From fa656308622fdaf54f2ff9ce8a70e4260f701b5d Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sat, 23 Feb 2013 12:06:34 -0800 Subject: Input: auo-pixcir-ts - set input direction for interrupt gpio Previously the gpio was not configured at all. Signed-off-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index c6e19a96348e..813413eebab7 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -504,6 +504,13 @@ static int auo_pixcir_probe(struct i2c_client *client, goto err_gpio_int; } + ret = gpio_direction_input(pdata->gpio_int); + if (ret) { + dev_err(&client->dev, "setting direction of gpio %d failed %d\n", + pdata->gpio_int, ret); + goto err_gpio_dir; + } + if (pdata->init_hw) pdata->init_hw(client); @@ -592,6 +599,7 @@ err_fw_vers: err_input_alloc: if (pdata->exit_hw) pdata->exit_hw(client); +err_gpio_dir: gpio_free(pdata->gpio_int); err_gpio_int: kfree(ts); -- cgit From 27cef8b47cfb27fa2955a8577637794f1f275db2 Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sat, 23 Feb 2013 12:06:44 -0800 Subject: Input: auo-pixcir-ts - handle reset gpio directly Devicetree based platforms don't handle device callbacks very well and until now no board has come along that needs more extended hwinit than pulling the rst gpio high. Therefore pull the reset handling directly into the driver and remove the callbacks from the driver. If extended device setup is needed at some later point, power-sequences would probably be the solution of choice. Signed-off-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 26 ++++++++++++++++++++------ include/linux/input/auo-pixcir-ts.h | 4 +--- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 813413eebab7..6317a9c7884c 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -511,8 +511,21 @@ static int auo_pixcir_probe(struct i2c_client *client, goto err_gpio_dir; } - if (pdata->init_hw) - pdata->init_hw(client); + ret = gpio_request(pdata->gpio_rst, "auo_pixcir_ts_rst"); + if (ret) { + dev_err(&client->dev, "request of gpio %d failed, %d\n", + pdata->gpio_rst, ret); + goto err_gpio_dir; + } + + ret = gpio_direction_output(pdata->gpio_rst, 1); + if (ret) { + dev_err(&client->dev, "setting direction of gpio %d failed %d\n", + pdata->gpio_rst, ret); + goto err_gpio_rst; + } + + msleep(200); ts->client = client; ts->touch_ind_mode = 0; @@ -597,8 +610,9 @@ err_input_register: err_fw_vers: input_free_device(input_dev); err_input_alloc: - if (pdata->exit_hw) - pdata->exit_hw(client); + gpio_set_value(pdata->gpio_rst, 0); +err_gpio_rst: + gpio_free(pdata->gpio_rst); err_gpio_dir: gpio_free(pdata->gpio_int); err_gpio_int: @@ -616,8 +630,8 @@ static int auo_pixcir_remove(struct i2c_client *client) input_unregister_device(ts->input); - if (pdata->exit_hw) - pdata->exit_hw(client); + gpio_set_value(pdata->gpio_rst, 0); + gpio_free(pdata->gpio_rst); gpio_free(pdata->gpio_int); diff --git a/include/linux/input/auo-pixcir-ts.h b/include/linux/input/auo-pixcir-ts.h index 75d4be717714..5049f21928e4 100644 --- a/include/linux/input/auo-pixcir-ts.h +++ b/include/linux/input/auo-pixcir-ts.h @@ -43,12 +43,10 @@ */ struct auo_pixcir_ts_platdata { int gpio_int; + int gpio_rst; int int_setting; - void (*init_hw)(struct i2c_client *); - void (*exit_hw)(struct i2c_client *); - unsigned int x_max; unsigned int y_max; }; -- cgit From 38e83f7f9169400047aa3033d643891da1b00441 Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sat, 23 Feb 2013 12:06:48 -0800 Subject: Input: auo_pixcir_ts - keep own pointer to platform_data When supporting devicetree the platformdata may not necessarily come from the dev but may be generated in the driver instead. Therefore keep the pointer in the driver struct instead of using dev.platform_data. Signed-off-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 6317a9c7884c..c0a2483b30cb 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -111,6 +111,7 @@ struct auo_pixcir_ts { struct i2c_client *client; struct input_dev *input; + const struct auo_pixcir_ts_platdata *pdata; char phys[32]; /* special handling for touch_indicate interupt mode */ @@ -132,7 +133,7 @@ static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, struct auo_point_t *point) { struct i2c_client *client = ts->client; - const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; + const struct auo_pixcir_ts_platdata *pdata = ts->pdata; uint8_t raw_coord[8]; uint8_t raw_area[4]; int i, ret; @@ -178,8 +179,7 @@ static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id) { struct auo_pixcir_ts *ts = dev_id; - struct i2c_client *client = ts->client; - const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; + const struct auo_pixcir_ts_platdata *pdata = ts->pdata; struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS]; int i; int ret; @@ -290,7 +290,7 @@ static int auo_pixcir_int_config(struct auo_pixcir_ts *ts, int int_setting) { struct i2c_client *client = ts->client; - struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; + const struct auo_pixcir_ts_platdata *pdata = ts->pdata; int ret; ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); @@ -527,6 +527,7 @@ static int auo_pixcir_probe(struct i2c_client *client, msleep(200); + ts->pdata = pdata; ts->client = client; ts->touch_ind_mode = 0; init_waitqueue_head(&ts->wait); @@ -624,7 +625,7 @@ err_gpio_int: static int auo_pixcir_remove(struct i2c_client *client) { struct auo_pixcir_ts *ts = i2c_get_clientdata(client); - const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; + const struct auo_pixcir_ts_platdata *pdata = ts->pdata; free_irq(client->irq, ts); -- cgit From 7241443f67bb352183bcfd7e3b807b87f2777b5d Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sat, 23 Feb 2013 12:08:55 -0800 Subject: Input: auo_pixcir_ts - add devicetree support Add the necessary code to create the needed platformdata from devicetree informations. The interrupt mode of the chip is not set via devicetree, as it is not a property of the hardware but instead only a preferred type of operation. This should probably be made settable via configfs in the future. The option set as default is the mode the datasheet mentions as default. Signed-off-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/auo_pixcir_ts.txt | 30 +++++++++ drivers/input/touchscreen/auo-pixcir-ts.c | 74 ++++++++++++++++++++-- 2 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt new file mode 100644 index 000000000000..f40f21c642b9 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt @@ -0,0 +1,30 @@ +* AUO in-cell touchscreen controller using Pixcir sensors + +Required properties: +- compatible: must be "auo,auo_pixcir_ts" +- reg: I2C address of the chip +- interrupts: interrupt to which the chip is connected +- gpios: gpios the chip is connected to + first one is the interrupt gpio and second one the reset gpio +- x-size: horizontal resolution of touchscreen +- y-size: vertical resolution of touchscreen + +Example: + + i2c@00000000 { + /* ... */ + + auo_pixcir_ts@5c { + compatible = "auo,auo_pixcir_ts"; + reg = <0x5c>; + interrupts = <2 0>; + + gpios = <&gpf 2 0 2>, /* INT */ + <&gpf 5 1 0>; /* RST */ + + x-size = <800>; + y-size = <600>; + }; + + /* ... */ + }; diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index c0a2483b30cb..dfa6d5463ef7 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* * Coordinate calculation: @@ -479,19 +481,72 @@ unlock: } #endif -static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, - auo_pixcir_resume); +static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, + auo_pixcir_suspend, auo_pixcir_resume); + +#ifdef CONFIG_OF +static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) +{ + struct auo_pixcir_ts_platdata *pdata; + struct device_node *np = dev->of_node; + + if (!np) + return ERR_PTR(-ENOENT); + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(dev, "failed to allocate platform data\n"); + return ERR_PTR(-ENOMEM); + } + + pdata->gpio_int = of_get_gpio(np, 0); + if (!gpio_is_valid(pdata->gpio_int)) { + dev_err(dev, "failed to get interrupt gpio\n"); + return ERR_PTR(-EINVAL); + } + + pdata->gpio_rst = of_get_gpio(np, 1); + if (!gpio_is_valid(pdata->gpio_rst)) { + dev_err(dev, "failed to get reset gpio\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(np, "x-size", &pdata->x_max)) { + dev_err(dev, "failed to get x-size property\n"); + return ERR_PTR(-EINVAL); + } + + if (of_property_read_u32(np, "y-size", &pdata->y_max)) { + dev_err(dev, "failed to get y-size property\n"); + return ERR_PTR(-EINVAL); + } + + /* default to asserting the interrupt when the screen is touched */ + pdata->int_setting = AUO_PIXCIR_INT_TOUCH_IND; + + return pdata; +} +#else +static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) +{ + return ERR_PTR(-EINVAL); +} +#endif static int auo_pixcir_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; + const struct auo_pixcir_ts_platdata *pdata; struct auo_pixcir_ts *ts; struct input_dev *input_dev; int ret; - if (!pdata) - return -EINVAL; + pdata = dev_get_platdata(&client->dev); + if (!pdata) { + pdata = auo_pixcir_parse_dt(&client->dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } ts = kzalloc(sizeof(struct auo_pixcir_ts), GFP_KERNEL); if (!ts) @@ -647,11 +702,20 @@ static const struct i2c_device_id auo_pixcir_idtable[] = { }; MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable); +#ifdef CONFIG_OF +static struct of_device_id auo_pixcir_ts_dt_idtable[] = { + { .compatible = "auo,auo_pixcir_ts" }, + {}, +}; +MODULE_DEVICE_TABLE(of, auo_pixcir_ts_dt_idtable); +#endif + static struct i2c_driver auo_pixcir_driver = { .driver = { .owner = THIS_MODULE, .name = "auo_pixcir_ts", .pm = &auo_pixcir_pm_ops, + .of_match_table = of_match_ptr(auo_pixcir_ts_dt_idtable), }, .probe = auo_pixcir_probe, .remove = auo_pixcir_remove, -- cgit From e90a6df80dc45ab53d2f4f4db297434e48c0208e Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 25 Feb 2013 11:31:43 +0100 Subject: HID: Extend the interface with report requests Some drivers send reports directly to underlying device, creating an unwanted dependency on the underlying transport layer. This patch adds hid_hw_request() to the interface, thereby removing usbhid from the lion share of the drivers. Signed-off-by: Henrik Rydberg Signed-off-by: Benjamin Tissoires Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 13 +++++++++++++ include/linux/hid.h | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 8e0c4bf94ebc..366fd09d257d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1243,6 +1243,18 @@ static int usbhid_power(struct hid_device *hid, int lvl) return r; } +static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int reqtype) +{ + switch (reqtype) { + case HID_REQ_GET_REPORT: + usbhid_submit_report(hid, rep, USB_DIR_IN); + break; + case HID_REQ_SET_REPORT: + usbhid_submit_report(hid, rep, USB_DIR_OUT); + break; + } +} + static struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, @@ -1251,6 +1263,7 @@ static struct hid_ll_driver usb_hid_driver = { .close = usbhid_close, .power = usbhid_power, .hidinput_input_event = usb_hidinput_input_event, + .request = usbhid_request, }; static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/include/linux/hid.h b/include/linux/hid.h index e14b465b1146..261c713d4842 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -662,6 +662,7 @@ struct hid_driver { * @hidinput_input_event: event input event (e.g. ff or leds) * @parse: this method is called only once to parse the device data, * shouldn't allocate anything to not leak memory + * @request: send report request to device (e.g. feature report) */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -676,6 +677,10 @@ struct hid_ll_driver { unsigned int code, int value); int (*parse)(struct hid_device *hdev); + + void (*request)(struct hid_device *hdev, + struct hid_report *report, int reqtype); + }; #define PM_HINT_FULLON 1<<5 @@ -883,6 +888,21 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; } + +/** + * hid_hw_request - send report request to device + * + * @hdev: hid device + * @report: report to send + * @reqtype: hid request type + */ +static inline void hid_hw_request(struct hid_device *hdev, + struct hid_report *report, int reqtype) +{ + if (hdev->ll_driver->request) + hdev->ll_driver->request(hdev, report, reqtype); +} + int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); -- cgit From 3373443befa73ee60e4275e7699b26058b01455a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 25 Feb 2013 11:31:44 +0100 Subject: HID: Extend the interface with wait io request Some drivers need to wait for an io from the underlying device, creating an unwanted dependency on the underlying transport layer. This patch adds wait() to the interface, thereby removing usbhid from the lion share of the drivers. Signed-off-by: Henrik Rydberg Signed-off-by: Benjamin Tissoires Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 1 + include/linux/hid.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 366fd09d257d..99d95d3368b5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1264,6 +1264,7 @@ static struct hid_ll_driver usb_hid_driver = { .power = usbhid_power, .hidinput_input_event = usb_hidinput_input_event, .request = usbhid_request, + .wait = usbhid_wait_io, }; static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/include/linux/hid.h b/include/linux/hid.h index 261c713d4842..7071eb3d36c7 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -663,6 +663,7 @@ struct hid_driver { * @parse: this method is called only once to parse the device data, * shouldn't allocate anything to not leak memory * @request: send report request to device (e.g. feature report) + * @wait: wait for buffered io to complete (send/recv reports) */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -681,6 +682,8 @@ struct hid_ll_driver { void (*request)(struct hid_device *hdev, struct hid_report *report, int reqtype); + int (*wait)(struct hid_device *hdev); + }; #define PM_HINT_FULLON 1<<5 @@ -903,6 +906,17 @@ static inline void hid_hw_request(struct hid_device *hdev, hdev->ll_driver->request(hdev, report, reqtype); } +/** + * hid_hw_wait - wait for buffered io to complete + * + * @hdev: hid device + */ +static inline void hid_hw_wait(struct hid_device *hdev) +{ + if (hdev->ll_driver->wait) + hdev->ll_driver->wait(hdev); +} + int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); -- cgit From f3757cea18fadce23c95a4c4bc3123af73a95e65 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:45 +0100 Subject: HID: Kconfig: Remove explicit transport layer dependencies Most HID drivers (rightfully) only depend on the HID bus, not the specific transport layer. Remove such dependencies where applicable. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 68 ++++++++++++++++++++++---------------------- drivers/hid/hid-apple.c | 1 - drivers/hid/hid-magicmouse.c | 1 - drivers/hid/hid-speedlink.c | 2 -- drivers/hid/hid-thingm.c | 1 - 5 files changed, 34 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5f07d85c4189..1b737b44c56e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -92,7 +92,7 @@ menu "Special HID drivers" config HID_A4TECH tristate "A4 tech mice" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for A4 tech X5 and WOP-35 / Trust 450L mice. @@ -113,7 +113,7 @@ config HID_ACRUX_FF config HID_APPLE tristate "Apple {i,Power,Mac}Books" if EXPERT - depends on (USB_HID || BT_HIDP) + depends on HID default !EXPERT ---help--- Support for some Apple devices which less or more break @@ -124,27 +124,27 @@ config HID_APPLE config HID_AUREAL tristate "Aureal" - depends on USB_HID + depends on HID ---help--- Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. config HID_BELKIN tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Belkin Flip KVM and Wireless keyboard. config HID_CHERRY tristate "Cherry Cymotion keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Cherry Cymotion keyboard. config HID_CHICONY tristate "Chicony Tactical pad" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Chicony Tactical pad. @@ -166,7 +166,7 @@ config HID_PRODIKEYS config HID_CYPRESS tristate "Cypress mouse and barcode readers" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for cypress mouse and barcode readers. @@ -202,13 +202,13 @@ config HID_EMS_FF config HID_ELECOM tristate "ELECOM BM084 bluetooth mouse" - depends on BT_HIDP + depends on HID ---help--- Support for the ELECOM BM084 (bluetooth mouse). config HID_EZKEY tristate "Ezkey BTC 8193 keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Ezkey BTC 8193 keyboard. @@ -231,7 +231,7 @@ config HOLTEK_FF config HID_KEYTOUCH tristate "Keytouch HID devices" - depends on USB_HID + depends on HID ---help--- Support for Keytouch HID devices not fully compliant with the specification. Currently supported: @@ -249,25 +249,25 @@ config HID_KYE config HID_UCLOGIC tristate "UC-Logic" - depends on USB_HID + depends on HID ---help--- Support for UC-Logic tablets. config HID_WALTOP tristate "Waltop" - depends on USB_HID + depends on HID ---help--- Support for Waltop tablets. config HID_GYRATION tristate "Gyration remote control" - depends on USB_HID + depends on HID ---help--- Support for Gyration remote control. config HID_ICADE tristate "ION iCade arcade controller" - depends on BT_HIDP + depends on HID ---help--- Support for the ION iCade arcade controller to work as a joystick. @@ -276,20 +276,20 @@ config HID_ICADE config HID_TWINHAN tristate "Twinhan IR remote control" - depends on USB_HID + depends on HID ---help--- Support for Twinhan IR remote control. config HID_KENSINGTON tristate "Kensington Slimblade Trackball" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Kensington Slimblade Trackball. config HID_LCPOWER tristate "LC-Power" - depends on USB_HID + depends on HID ---help--- Support for LC-Power RC1000MCE RF remote control. @@ -308,7 +308,7 @@ config HID_LENOVO_TPKBD config HID_LOGITECH tristate "Logitech devices" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -374,7 +374,7 @@ config LOGIWHEELS_FF config HID_MAGICMOUSE tristate "Apple MagicMouse multi-touch support" - depends on BT_HIDP + depends on HID ---help--- Support for the Apple Magic Mouse multi-touch. @@ -383,14 +383,14 @@ config HID_MAGICMOUSE config HID_MICROSOFT tristate "Microsoft non-fully HID-compliant devices" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Microsoft devices that are not fully compliant with HID standard. config HID_MONTEREY tristate "Monterey Genius KB29E keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Monterey Genius KB29E. @@ -445,7 +445,7 @@ config HID_NTRIG config HID_ORTEK tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad" - depends on USB_HID + depends on HID ---help--- There are certain devices which have LogicalMaximum wrong in the keyboard usage page of their report descriptor. The most prevailing ones so far @@ -473,7 +473,7 @@ config PANTHERLORD_FF config HID_PETALYNX tristate "Petalynx Maxter remote control" - depends on USB_HID + depends on HID ---help--- Support for Petalynx Maxter remote control. @@ -545,14 +545,14 @@ config HID_PICOLCD_CIR config HID_PRIMAX tristate "Primax non-fully HID-compliant devices" - depends on USB_HID + depends on HID ---help--- Support for Primax devices that are not fully compliant with the HID standard. config HID_PS3REMOTE tristate "Sony PS3 BD Remote Control" - depends on BT_HIDP + depends on HID ---help--- Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech Harmony Adapter for PS3, which connect over Bluetooth. @@ -569,7 +569,7 @@ config HID_ROCCAT config HID_SAITEK tristate "Saitek non-fully HID-compliant devices" - depends on USB_HID + depends on HID ---help--- Support for Saitek devices that are not fully compliant with the HID standard. @@ -578,7 +578,7 @@ config HID_SAITEK config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" - depends on USB_HID + depends on HID ---help--- Support for Samsung InfraRed remote control or keyboards. @@ -604,7 +604,7 @@ config HID_STEELSERIES config HID_SUNPLUS tristate "Sunplus wireless desktop" - depends on USB_HID + depends on HID ---help--- Support for Sunplus wireless desktop. @@ -650,20 +650,20 @@ config SMARTJOYPLUS_FF config HID_TIVO tristate "TiVo Slide Bluetooth remote control support" - depends on (USB_HID || BT_HIDP) + depends on HID ---help--- Say Y if you have a TiVo Slide Bluetooth remote control. config HID_TOPSEED tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" - depends on USB_HID + depends on HID ---help--- Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic CLLRCMCE remote control. config HID_THINGM tristate "ThingM blink(1) USB RGB LED" - depends on USB_HID + depends on HID depends on LEDS_CLASS ---help--- Support for the ThingM blink(1) USB RGB LED. This driver registers a @@ -689,7 +689,7 @@ config THRUSTMASTER_FF config HID_WACOM tristate "Wacom Bluetooth devices support" - depends on BT_HIDP + depends on HID depends on LEDS_CLASS select POWER_SUPPLY ---help--- @@ -697,7 +697,7 @@ config HID_WACOM config HID_WIIMOTE tristate "Nintendo Wii Remote support" - depends on BT_HIDP + depends on HID depends on LEDS_CLASS select POWER_SUPPLY select INPUT_FF_MEMLESS @@ -729,7 +729,7 @@ config ZEROPLUS_FF config HID_ZYDACRON tristate "Zydacron remote control support" - depends on USB_HID + depends on HID ---help--- Support for Zydacron remote control. diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 320a958d4139..9e0c4fbbb840 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "hid-ids.h" diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index f7f113ba083e..ef89573d65fc 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "hid-ids.h" diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c index e94371a059cb..a2f587d004e1 100644 --- a/drivers/hid/hid-speedlink.c +++ b/drivers/hid/hid-speedlink.c @@ -16,10 +16,8 @@ #include #include #include -#include #include "hid-ids.h" -#include "usbhid/usbhid.h" static const struct hid_device_id speedlink_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE)}, diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 2055a52e9a20..99342cfa0ea2 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "hid-ids.h" -- cgit From d881427253da011495f4193663d809d0e9dfa215 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:46 +0100 Subject: HID: use hid_hw_request() instead of direct call to usbhid This allows the hid drivers to be independent from the transport layer. The patch was constructed by replacing all occurences of usbhid_submit_report() by its hid_hw_request() counterpart. Then, drivers not requiring USB_HID anymore have their USB_HID dependency cleaned in the Kconfig file. Finally, few drivers still depends on USB_HID. Many of them are requiring the io wait callback. They are found in the next patch. Signed-off-by: Benjamin Tissoires Reviewed-by: Mika Westerberg For the sensor-hub part: Tested-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 30 ++++++++--------- drivers/hid/hid-axff.c | 6 ++-- drivers/hid/hid-dr.c | 8 ++--- drivers/hid/hid-emsff.c | 6 ++-- drivers/hid/hid-gaff.c | 10 +++--- drivers/hid/hid-holtekff.c | 4 +-- drivers/hid/hid-kye.c | 4 +-- drivers/hid/hid-lenovo-tpkbd.c | 4 +-- drivers/hid/hid-lg2ff.c | 6 ++-- drivers/hid/hid-lg3ff.c | 6 ++-- drivers/hid/hid-lg4ff.c | 18 +++++------ drivers/hid/hid-lgff.c | 8 ++--- drivers/hid/hid-logitech-dj.c | 3 +- drivers/hid/hid-multitouch.c | 4 +-- drivers/hid/hid-ntrig.c | 6 ++-- drivers/hid/hid-picolcd.h | 4 +-- drivers/hid/hid-picolcd_backlight.c | 4 +-- drivers/hid/hid-picolcd_cir.c | 2 -- drivers/hid/hid-picolcd_core.c | 8 ++--- drivers/hid/hid-picolcd_debugfs.c | 2 -- drivers/hid/hid-picolcd_fb.c | 7 ++-- drivers/hid/hid-picolcd_lcd.c | 4 +-- drivers/hid/hid-picolcd_leds.c | 4 +-- drivers/hid/hid-pl.c | 6 ++-- drivers/hid/hid-prodikeys.c | 3 +- drivers/hid/hid-sensor-hub.c | 7 ++-- drivers/hid/hid-sjoy.c | 6 ++-- drivers/hid/hid-steelseries.c | 3 +- drivers/hid/hid-tmff.c | 6 ++-- drivers/hid/hid-zpff.c | 6 ++-- drivers/hid/usbhid/hid-core.c | 3 +- drivers/hid/usbhid/hid-pidff.c | 64 ++++++++++++++++++------------------- drivers/hid/usbhid/hiddev.c | 4 +-- drivers/hid/usbhid/usbhid.h | 2 -- 34 files changed, 111 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1b737b44c56e..f0acf2754b69 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -99,7 +99,7 @@ config HID_A4TECH config HID_ACRUX tristate "ACRUX game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you want to enable support for ACRUX game controllers. @@ -151,7 +151,7 @@ config HID_CHICONY config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" - depends on USB_HID && SND + depends on HID && SND select SND_RAWMIDI ---help--- Support for Prodikeys PC-MIDI Keyboard device support. @@ -173,7 +173,7 @@ config HID_CYPRESS config HID_DRAGONRISE tristate "DragonRise Inc. game controller" - depends on USB_HID + depends on HID ---help--- Say Y here if you have DragonRise Inc. game controllers. These might be branded as: @@ -192,7 +192,7 @@ config DRAGONRISE_FF config HID_EMS_FF tristate "EMS Production Inc. force feedback support" - depends on USB_HID + depends on HID select INPUT_FF_MEMLESS ---help--- Say Y here if you want to enable force feedback support for devices by @@ -215,7 +215,7 @@ config HID_EZKEY config HID_HOLTEK tristate "Holtek HID devices" - depends on USB_HID + depends on HID ---help--- Support for Holtek based devices: - Holtek On Line Grip based game controller @@ -239,7 +239,7 @@ config HID_KEYTOUCH config HID_KYE tristate "KYE/Genius devices" - depends on USB_HID + depends on HID ---help--- Support for KYE/Genius devices not fully compliant with HID standard: - Ergo Mouse @@ -397,7 +397,7 @@ config HID_MONTEREY config HID_MULTITOUCH tristate "HID Multitouch panels" - depends on USB_HID + depends on HID ---help--- Generic support for HID multitouch panels. @@ -458,7 +458,7 @@ config HID_ORTEK config HID_PANTHERLORD tristate "Pantherlord/GreenAsia game controller" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a PantherLord/GreenAsia based game controller or adapter. @@ -592,13 +592,13 @@ config HID_SONY config HID_SPEEDLINK tristate "Speedlink VAD Cezanne mouse support" - depends on USB_HID + depends on HID ---help--- Support for Speedlink Vicious and Divine Cezanne mouse. config HID_STEELSERIES tristate "Steelseries SRW-S1 steering wheel support" - depends on USB_HID + depends on HID ---help--- Support for Steelseries SRW-S1 steering wheel @@ -610,7 +610,7 @@ config HID_SUNPLUS config HID_GREENASIA tristate "GreenAsia (Product ID 0x12) game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a GreenAsia (Product ID 0x12) based game controller or adapter. @@ -632,7 +632,7 @@ config HID_HYPERV_MOUSE config HID_SMARTJOYPLUS tristate "SmartJoy PLUS PS2/USB adapter support" - depends on USB_HID + depends on HID ---help--- Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box, Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro. @@ -673,7 +673,7 @@ config HID_THINGM config HID_THRUSTMASTER tristate "ThrustMaster devices support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or a THRUSTMASTER Ferrari GT Rumble Wheel. @@ -715,7 +715,7 @@ config HID_WIIMOTE_EXT config HID_ZEROPLUS tristate "Zeroplus based game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a Zeroplus based game controller. @@ -735,7 +735,7 @@ config HID_ZYDACRON config HID_SENSOR_HUB tristate "HID Sensors framework support" - depends on USB_HID && GENERIC_HARDIRQS + depends on HID && GENERIC_HARDIRQS select MFD_CORE default n -- help--- diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index 62f0cee032ba..64ab94a55aa7 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -29,14 +29,12 @@ #include #include -#include #include #include #include "hid-ids.h" #ifdef CONFIG_HID_ACRUX_FF -#include "usbhid/usbhid.h" struct axff_device { struct hid_report *report; @@ -68,7 +66,7 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect } dbg_hid("running with 0x%02x 0x%02x", left, right); - usbhid_submit_report(hid, axff->report, USB_DIR_OUT); + hid_hw_request(hid, axff->report, HID_REQ_SET_REPORT); return 0; } @@ -114,7 +112,7 @@ static int axff_init(struct hid_device *hid) goto err_free_mem; axff->report = report; - usbhid_submit_report(hid, axff->report, USB_DIR_OUT); + hid_hw_request(hid, axff->report, HID_REQ_SET_REPORT); hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun \n"); diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 0fe8f65ef01a..ce0644424f58 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c @@ -29,14 +29,12 @@ #include #include -#include #include #include #include "hid-ids.h" #ifdef CONFIG_DRAGONRISE_FF -#include "usbhid/usbhid.h" struct drff_device { struct hid_report *report; @@ -68,7 +66,7 @@ static int drff_play(struct input_dev *dev, void *data, drff->report->field[0]->value[1] = 0x00; drff->report->field[0]->value[2] = weak; drff->report->field[0]->value[4] = strong; - usbhid_submit_report(hid, drff->report, USB_DIR_OUT); + hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); drff->report->field[0]->value[0] = 0xfa; drff->report->field[0]->value[1] = 0xfe; @@ -80,7 +78,7 @@ static int drff_play(struct input_dev *dev, void *data, drff->report->field[0]->value[2] = 0x00; drff->report->field[0]->value[4] = 0x00; dbg_hid("running with 0x%02x 0x%02x", strong, weak); - usbhid_submit_report(hid, drff->report, USB_DIR_OUT); + hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); return 0; } @@ -132,7 +130,7 @@ static int drff_init(struct hid_device *hid) drff->report->field[0]->value[4] = 0x00; drff->report->field[0]->value[5] = 0x00; drff->report->field[0]->value[6] = 0x00; - usbhid_submit_report(hid, drff->report, USB_DIR_OUT); + hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); hid_info(hid, "Force Feedback for DragonRise Inc. " "game controllers by Richard Walmsley \n"); diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 2e093ab99b43..d82d75bb11f7 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -23,11 +23,9 @@ #include #include -#include #include #include "hid-ids.h" -#include "usbhid/usbhid.h" struct emsff_device { struct hid_report *report; @@ -52,7 +50,7 @@ static int emsff_play(struct input_dev *dev, void *data, emsff->report->field[0]->value[2] = strong; dbg_hid("running with 0x%02x 0x%02x\n", strong, weak); - usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); + hid_hw_request(hid, emsff->report, HID_REQ_SET_REPORT); return 0; } @@ -104,7 +102,7 @@ static int emsff_init(struct hid_device *hid) emsff->report->field[0]->value[4] = 0x00; emsff->report->field[0]->value[5] = 0x00; emsff->report->field[0]->value[6] = 0x00; - usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); + hid_hw_request(hid, emsff->report, HID_REQ_SET_REPORT); hid_info(hid, "force feedback for EMS based devices by Ignaz Forster \n"); diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index 04d2e6aca778..2d8cead3adca 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -29,13 +29,11 @@ #include #include -#include #include #include #include "hid-ids.h" #ifdef CONFIG_GREENASIA_FF -#include "usbhid/usbhid.h" struct gaff_device { struct hid_report *report; @@ -63,14 +61,14 @@ static int hid_gaff_play(struct input_dev *dev, void *data, gaff->report->field[0]->value[4] = left; gaff->report->field[0]->value[5] = 0; dbg_hid("running with 0x%02x 0x%02x", left, right); - usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); + hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); gaff->report->field[0]->value[0] = 0xfa; gaff->report->field[0]->value[1] = 0xfe; gaff->report->field[0]->value[2] = 0x0; gaff->report->field[0]->value[4] = 0x0; - usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); + hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); return 0; } @@ -122,12 +120,12 @@ static int gaff_init(struct hid_device *hid) gaff->report->field[0]->value[1] = 0x00; gaff->report->field[0]->value[2] = 0x00; gaff->report->field[0]->value[3] = 0x00; - usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); + hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); gaff->report->field[0]->value[0] = 0xfa; gaff->report->field[0]->value[1] = 0xfe; - usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); + hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski \n"); diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index f34d1186a3e1..9a8f05124525 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c @@ -27,12 +27,10 @@ #include #include #include -#include #include "hid-ids.h" #ifdef CONFIG_HOLTEK_FF -#include "usbhid/usbhid.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Anssi Hannula "); @@ -102,7 +100,7 @@ static void holtekff_send(struct holtekff_device *holtekff, dbg_hid("sending %*ph\n", 7, data); - usbhid_submit_report(hid, holtekff->field->report, USB_DIR_OUT); + hid_hw_request(hid, holtekff->field->report, HID_REQ_SET_REPORT); } static int holtekff_play(struct input_dev *dev, void *data, diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index ef72daecfa16..6af90dbdc3d4 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -16,8 +16,6 @@ #include #include #include -#include -#include "usbhid/usbhid.h" #include "hid-ids.h" @@ -361,7 +359,7 @@ static int kye_tablet_enable(struct hid_device *hdev) value[4] = 0x00; value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); return 0; } diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c index 956c3b135f64..a0535fd7a798 100644 --- a/drivers/hid/hid-lenovo-tpkbd.c +++ b/drivers/hid/hid-lenovo-tpkbd.c @@ -68,7 +68,7 @@ static int tpkbd_features_set(struct hid_device *hdev) report->field[2]->value[0] = data_pointer->sensitivity; report->field[3]->value[0] = data_pointer->press_speed; - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); return 0; } @@ -332,7 +332,7 @@ static void tpkbd_led_brightness_set(struct led_classdev *led_cdev, report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); } static int tpkbd_probe_tp(struct hid_device *hdev) diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index 3c31bc650e5d..b3cd1507dda2 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -23,10 +23,8 @@ #include #include -#include #include -#include "usbhid/usbhid.h" #include "hid-lg.h" struct lg2ff_device { @@ -56,7 +54,7 @@ static int play_effect(struct input_dev *dev, void *data, lg2ff->report->field[0]->value[4] = 0x00; } - usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT); + hid_hw_request(hid, lg2ff->report, HID_REQ_SET_REPORT); return 0; } @@ -108,7 +106,7 @@ int lg2ff_init(struct hid_device *hid) report->field[0]->value[5] = 0x00; report->field[0]->value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula \n"); diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c index f98644c26c1d..e52f181f6aa1 100644 --- a/drivers/hid/hid-lg3ff.c +++ b/drivers/hid/hid-lg3ff.c @@ -22,10 +22,8 @@ #include -#include #include -#include "usbhid/usbhid.h" #include "hid-lg.h" /* @@ -92,7 +90,7 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, report->field[0]->value[1] = (unsigned char)(-x); report->field[0]->value[31] = (unsigned char)(-y); - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); break; } return 0; @@ -118,7 +116,7 @@ static void hid_lg3ff_set_autocenter(struct input_dev *dev, u16 magnitude) report->field[0]->value[33] = 0x7F; report->field[0]->value[34] = 0x7F; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 65a6ec8d3742..7da40a1797cd 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -202,7 +202,7 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *e value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); break; } return 0; @@ -225,7 +225,7 @@ static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitud value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } /* Sends autocentering command compatible with Formula Force EX */ @@ -245,7 +245,7 @@ static void hid_lg4ff_set_autocenter_ffex(struct input_dev *dev, u16 magnitude) value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } /* Sends command to set range compatible with G25/G27/Driving Force GT */ @@ -265,7 +265,7 @@ static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range) value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } /* Sends commands to set range compatible with Driving Force Pro wheel */ @@ -294,7 +294,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) report->field[0]->value[1] = 0x02; full_range = 200; } - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); /* Prepare "fine" limit command */ value[0] = 0x81; @@ -306,7 +306,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) value[6] = 0x00; if (range == 200 || range == 900) { /* Do not apply any fine limit */ - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); return; } @@ -320,7 +320,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) value[5] = (start_right & 0xe) << 4 | (start_left & 0xe); value[6] = 0xff; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd) @@ -334,7 +334,7 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n for (i = 0; i < 7; i++) report->field[0]->value[i] = cmd->cmd[j++]; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } } @@ -410,7 +410,7 @@ static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) value[4] = 0x00; value[5] = 0x00; value[6] = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index 27bc54f92f44..d7ea8c845b40 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c @@ -30,10 +30,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include -#include "usbhid/usbhid.h" #include "hid-lg.h" struct dev_type { @@ -89,7 +87,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef report->field[0]->value[2] = x; report->field[0]->value[3] = y; dbg_hid("(x, y)=(%04x, %04x)\n", x, y); - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); break; case FF_RUMBLE: @@ -104,7 +102,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef report->field[0]->value[2] = left; report->field[0]->value[3] = right; dbg_hid("(left, right)=(%04x, %04x)\n", left, right); - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); break; } return 0; @@ -124,7 +122,7 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) *value++ = 0x80; *value++ = 0x00; *value = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); } int lgff_init(struct hid_device* hid) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9500f2f3f8fe..3cf62be2ca5d 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -27,7 +27,6 @@ #include #include #include -#include "usbhid/usbhid.h" #include "hid-ids.h" #include "hid-logitech-dj.h" @@ -638,7 +637,7 @@ static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS); hid_set_field(report->field[0], 2, data[1]); - usbhid_submit_report(dj_rcv_hiddev, report, USB_DIR_OUT); + hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT); return 0; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 7a1ebb867cf4..32258ba60056 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -736,7 +736,7 @@ static void mt_set_input_mode(struct hid_device *hdev) r = re->report_id_hash[td->inputmode]; if (r) { r->field[0]->value[td->inputmode_index] = 0x02; - usbhid_submit_report(hdev, r, USB_DIR_OUT); + hid_hw_request(hdev, r, HID_REQ_SET_REPORT); } } @@ -761,7 +761,7 @@ static void mt_set_maxcontacts(struct hid_device *hdev) max = min(fieldmax, max); if (r->field[0]->value[0] != max) { r->field[0]->value[0] = max; - usbhid_submit_report(hdev, r, USB_DIR_OUT); + hid_hw_request(hdev, r, HID_REQ_SET_REPORT); } } } diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 7757e82416e7..b926592e6c16 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -118,7 +118,7 @@ static inline int ntrig_get_mode(struct hid_device *hdev) if (!report) return -EINVAL; - usbhid_submit_report(hdev, report, USB_DIR_IN); + hid_hw_request(hdev, report, HID_REQ_GET_REPORT); usbhid_wait_io(hdev); return (int)report->field[0]->value[0]; } @@ -137,7 +137,7 @@ static inline void ntrig_set_mode(struct hid_device *hdev, const int mode) if (!report) return; - usbhid_submit_report(hdev, report, USB_DIR_IN); + hid_hw_request(hdev, report, HID_REQ_GET_REPORT); } static void ntrig_report_version(struct hid_device *hdev) @@ -938,7 +938,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) /* Let the device settle to ensure the wakeup message gets * through */ usbhid_wait_io(hdev); - usbhid_submit_report(hdev, report, USB_DIR_IN); + hid_hw_request(hdev, report, HID_REQ_GET_REPORT); /* * Sanity check: if the current mode is invalid reset it to diff --git a/drivers/hid/hid-picolcd.h b/drivers/hid/hid-picolcd.h index 020cef69f6a1..2941891ecac2 100644 --- a/drivers/hid/hid-picolcd.h +++ b/drivers/hid/hid-picolcd.h @@ -142,10 +142,10 @@ struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir); #ifdef CONFIG_DEBUG_FS void picolcd_debug_out_report(struct picolcd_data *data, struct hid_device *hdev, struct hid_report *report); -#define usbhid_submit_report(a, b, c) \ +#define hid_hw_request(a, b, c) \ do { \ picolcd_debug_out_report(hid_get_drvdata(a), a, b); \ - usbhid_submit_report(a, b, c); \ + hid_hw_request(a, b, c); \ } while (0) void picolcd_debug_raw_event(struct picolcd_data *data, diff --git a/drivers/hid/hid-picolcd_backlight.c b/drivers/hid/hid-picolcd_backlight.c index b91f30945f9c..a32c5f86b0b3 100644 --- a/drivers/hid/hid-picolcd_backlight.c +++ b/drivers/hid/hid-picolcd_backlight.c @@ -18,8 +18,6 @@ ***************************************************************************/ #include -#include "usbhid/usbhid.h" -#include #include #include @@ -46,7 +44,7 @@ static int picolcd_set_brightness(struct backlight_device *bdev) spin_lock_irqsave(&data->lock, flags); hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0); if (!(data->status & PICOLCD_FAILED)) - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); return 0; } diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index a79e95bb9fb6..e346038f0f11 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -21,8 +21,6 @@ #include #include #include "hid-ids.h" -#include "usbhid/usbhid.h" -#include #include #include diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index 31cd93fc3d4b..b48092d0e139 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c @@ -21,8 +21,6 @@ #include #include #include "hid-ids.h" -#include "usbhid/usbhid.h" -#include #include #include @@ -110,7 +108,7 @@ struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, work = NULL; } else { data->pending = work; - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); wait_for_completion_interruptible_timeout(&work->ready, HZ*2); spin_lock_irqsave(&data->lock, flags); @@ -244,7 +242,7 @@ int picolcd_reset(struct hid_device *hdev) spin_unlock_irqrestore(&data->lock, flags); return -ENODEV; } - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); error = picolcd_check_version(hdev); @@ -303,7 +301,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, spin_lock_irqsave(&data->lock, flags); hid_set_field(report->field[0], 0, timeout & 0xff); hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff); - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); return count; } diff --git a/drivers/hid/hid-picolcd_debugfs.c b/drivers/hid/hid-picolcd_debugfs.c index 4809aa1bdb9c..59ab8e157e6b 100644 --- a/drivers/hid/hid-picolcd_debugfs.c +++ b/drivers/hid/hid-picolcd_debugfs.c @@ -19,8 +19,6 @@ #include #include -#include "usbhid/usbhid.h" -#include #include #include diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c index eb003574b634..98f61de9a5e0 100644 --- a/drivers/hid/hid-picolcd_fb.c +++ b/drivers/hid/hid-picolcd_fb.c @@ -20,7 +20,6 @@ #include #include #include "usbhid/usbhid.h" -#include #include #include @@ -143,8 +142,8 @@ static int picolcd_fb_send_tile(struct picolcd_data *data, u8 *vbitmap, else hid_set_field(report2->field[0], 4 + i - 32, tdata[i]); - usbhid_submit_report(data->hdev, report1, USB_DIR_OUT); - usbhid_submit_report(data->hdev, report2, USB_DIR_OUT); + hid_hw_request(data->hdev, report1, HID_REQ_SET_REPORT); + hid_hw_request(data->hdev, report2, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); return 0; } @@ -214,7 +213,7 @@ int picolcd_fb_reset(struct picolcd_data *data, int clear) hid_set_field(report->field[0], j, mapcmd[j]); else hid_set_field(report->field[0], j, 0); - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); } spin_unlock_irqrestore(&data->lock, flags); diff --git a/drivers/hid/hid-picolcd_lcd.c b/drivers/hid/hid-picolcd_lcd.c index 2d0ddc5ac65f..89821c2da6d7 100644 --- a/drivers/hid/hid-picolcd_lcd.c +++ b/drivers/hid/hid-picolcd_lcd.c @@ -18,8 +18,6 @@ ***************************************************************************/ #include -#include "usbhid/usbhid.h" -#include #include #include @@ -48,7 +46,7 @@ static int picolcd_set_contrast(struct lcd_device *ldev, int contrast) spin_lock_irqsave(&data->lock, flags); hid_set_field(report->field[0], 0, data->lcd_contrast); if (!(data->status & PICOLCD_FAILED)) - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); return 0; } diff --git a/drivers/hid/hid-picolcd_leds.c b/drivers/hid/hid-picolcd_leds.c index 28cb6a4f9634..e994f9c29012 100644 --- a/drivers/hid/hid-picolcd_leds.c +++ b/drivers/hid/hid-picolcd_leds.c @@ -21,8 +21,6 @@ #include #include #include "hid-ids.h" -#include "usbhid/usbhid.h" -#include #include #include @@ -55,7 +53,7 @@ void picolcd_leds_set(struct picolcd_data *data) spin_lock_irqsave(&data->lock, flags); hid_set_field(report->field[0], 0, data->led_state); if (!(data->status & PICOLCD_FAILED)) - usbhid_submit_report(data->hdev, report, USB_DIR_OUT); + hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); spin_unlock_irqrestore(&data->lock, flags); } diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index b0199d27787b..d29112fa5cd5 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -43,13 +43,11 @@ #include #include #include -#include #include #include "hid-ids.h" #ifdef CONFIG_PANTHERLORD_FF -#include "usbhid/usbhid.h" struct plff_device { struct hid_report *report; @@ -75,7 +73,7 @@ static int hid_plff_play(struct input_dev *dev, void *data, *plff->strong = left; *plff->weak = right; debug("running with 0x%02x 0x%02x", left, right); - usbhid_submit_report(hid, plff->report, USB_DIR_OUT); + hid_hw_request(hid, plff->report, HID_REQ_SET_REPORT); return 0; } @@ -169,7 +167,7 @@ static int plff_init(struct hid_device *hid) *strong = 0x00; *weak = 0x00; - usbhid_submit_report(hid, plff->report, USB_DIR_OUT); + hid_hw_request(hid, plff->report, HID_REQ_SET_REPORT); } hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula \n"); diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 4e1c4bcbdc03..7ed828056414 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -26,7 +26,6 @@ #include #include #include -#include "usbhid/usbhid.h" #include "hid-ids.h" @@ -306,7 +305,7 @@ static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state) report->field[0]->value[0] = 0x01; report->field[0]->value[1] = state; - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); } static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data) diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 6679788bf75a..59d29f853ac0 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -18,7 +18,6 @@ */ #include #include -#include #include "usbhid/usbhid.h" #include #include @@ -204,7 +203,7 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, goto done_proc; } hid_set_field(report->field[field_index], 0, value); - usbhid_submit_report(hsdev->hdev, report, USB_DIR_OUT); + hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); usbhid_wait_io(hsdev->hdev); done_proc: @@ -227,7 +226,7 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, ret = -EINVAL; goto done_proc; } - usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); + hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); usbhid_wait_io(hsdev->hdev); *value = report->field[field_index]->value[0]; @@ -262,7 +261,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, spin_unlock_irqrestore(&data->lock, flags); goto err_free; } - usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); + hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); spin_unlock_irqrestore(&data->lock, flags); wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5); switch (data->pending.raw_size) { diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index 28f774003f03..37845eccddb5 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -28,13 +28,11 @@ #include #include -#include #include #include #include "hid-ids.h" #ifdef CONFIG_SMARTJOYPLUS_FF -#include "usbhid/usbhid.h" struct sjoyff_device { struct hid_report *report; @@ -57,7 +55,7 @@ static int hid_sjoyff_play(struct input_dev *dev, void *data, sjoyff->report->field[0]->value[1] = right; sjoyff->report->field[0]->value[2] = left; dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right); - usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); + hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT); return 0; } @@ -115,7 +113,7 @@ static int sjoyff_init(struct hid_device *hid) sjoyff->report->field[0]->value[0] = 0x01; sjoyff->report->field[0]->value[1] = 0x00; sjoyff->report->field[0]->value[2] = 0x00; - usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); + hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT); } hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c index 2ed995cda44a..98e66ac71842 100644 --- a/drivers/hid/hid-steelseries.c +++ b/drivers/hid/hid-steelseries.c @@ -16,7 +16,6 @@ #include #include -#include "usbhid/usbhid.h" #include "hid-ids.h" #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) @@ -132,7 +131,7 @@ static void steelseries_srws1_set_leds(struct hid_device *hdev, __u16 leds) value[14] = 0x00; value[15] = 0x00; - usbhid_submit_report(hdev, report, USB_DIR_OUT); + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); /* Note: LED change does not show on device until the device is read/polled */ } diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index e4fcf3f702a5..b83376077d72 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include "hid-ids.h" @@ -46,7 +45,6 @@ static const signed short ff_joystick[] = { }; #ifdef CONFIG_THRUSTMASTER_FF -#include "usbhid/usbhid.h" /* Usages for thrustmaster devices I know about */ #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) @@ -103,7 +101,7 @@ static int tmff_play(struct input_dev *dev, void *data, dbg_hid("(x, y)=(%04x, %04x)\n", x, y); ff_field->value[0] = x; ff_field->value[1] = y; - usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); + hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT); break; case FF_RUMBLE: @@ -117,7 +115,7 @@ static int tmff_play(struct input_dev *dev, void *data, dbg_hid("(left,right)=(%08x, %08x)\n", left, right); ff_field->value[0] = left; ff_field->value[1] = right; - usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); + hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT); break; } return 0; diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index af66452592e9..6ec28a37c146 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -24,13 +24,11 @@ #include #include #include -#include #include #include "hid-ids.h" #ifdef CONFIG_ZEROPLUS_FF -#include "usbhid/usbhid.h" struct zpff_device { struct hid_report *report; @@ -59,7 +57,7 @@ static int zpff_play(struct input_dev *dev, void *data, zpff->report->field[2]->value[0] = left; zpff->report->field[3]->value[0] = right; dbg_hid("running with 0x%02x 0x%02x\n", left, right); - usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); + hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); return 0; } @@ -104,7 +102,7 @@ static int zpff_init(struct hid_device *hid) zpff->report->field[1]->value[0] = 0x02; zpff->report->field[2]->value[0] = 0x00; zpff->report->field[3]->value[0] = 0x00; - usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); + hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula \n"); diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 99d95d3368b5..da68687d2c7c 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -639,7 +639,7 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re } } -void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) +static void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) { struct usbhid_device *usbhid = hid->driver_data; unsigned long flags; @@ -648,7 +648,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns __usbhid_submit_report(hid, report, dir); spin_unlock_irqrestore(&usbhid->lock, flags); } -EXPORT_SYMBOL_GPL(usbhid_submit_report); /* Workqueue routine to send requests to change LEDs */ static void hid_led(struct work_struct *work) diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index f91c136821f7..0f1efa39ec46 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -263,8 +263,8 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, envelope->attack_level, pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_ENVELOPE], + HID_REQ_SET_REPORT); } /* @@ -290,8 +290,8 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], effect->u.constant.level); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONSTANT], + HID_REQ_SET_REPORT); } /* @@ -325,8 +325,8 @@ static void pidff_set_effect_report(struct pidff_device *pidff, pidff->effect_direction); pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], + HID_REQ_SET_REPORT); } /* @@ -357,8 +357,8 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC], + HID_REQ_SET_REPORT); } @@ -399,8 +399,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff, effect->u.condition[i].left_saturation); pidff_set(&pidff->set_condition[PID_DEAD_BAND], effect->u.condition[i].deadband); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONDITION], + HID_REQ_SET_REPORT); } } @@ -440,8 +440,8 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff, effect->u.ramp.start_level); pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], effect->u.ramp.end_level); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_RAMP], + HID_REQ_SET_REPORT); } /* @@ -465,8 +465,8 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) int j; pidff->create_new_effect_type->value[0] = efnum; - usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], + HID_REQ_SET_REPORT); hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum); pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; @@ -475,8 +475,8 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) for (j = 0; j < 60; j++) { hid_dbg(pidff->hid, "pid_block_load requested\n"); - usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], - USB_DIR_IN); + hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_LOAD], + HID_REQ_GET_REPORT); usbhid_wait_io(pidff->hid); if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { @@ -513,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; } - usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], + HID_REQ_SET_REPORT); } /** @@ -535,8 +535,8 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value) static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) { pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; - usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE], + HID_REQ_SET_REPORT); } /* @@ -718,8 +718,8 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain) struct pidff_device *pidff = dev->ff->private; pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); - usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_GAIN], + HID_REQ_SET_REPORT); } static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) @@ -744,8 +744,8 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1; pidff->set_effect[PID_START_DELAY].value[0] = 0; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], - USB_DIR_OUT); + hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], + HID_REQ_SET_REPORT); } /* @@ -1158,18 +1158,18 @@ static void pidff_reset(struct pidff_device *pidff) pidff->device_control->value[0] = pidff->control_id[PID_RESET]; /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); + hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); usbhid_wait_io(hid); - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); + hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); usbhid_wait_io(hid); pidff->device_control->value[0] = pidff->control_id[PID_ENABLE_ACTUATORS]; - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); + hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); usbhid_wait_io(hid); /* pool report is sometimes messed up, refetch it */ - usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); + hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT); usbhid_wait_io(hid); if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { @@ -1181,8 +1181,8 @@ static void pidff_reset(struct pidff_device *pidff) break; } hid_dbg(pidff->hid, "pid_pool requested again\n"); - usbhid_submit_report(hid, pidff->reports[PID_POOL], - USB_DIR_IN); + hid_hw_request(hid, pidff->reports[PID_POOL], + HID_REQ_GET_REPORT); usbhid_wait_io(hid); } } @@ -1269,8 +1269,8 @@ int hid_pidff_init(struct hid_device *hid) if (test_bit(FF_GAIN, dev->ffbit)) { pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN], - USB_DIR_OUT); + hid_hw_request(hid, pidff->reports[PID_DEVICE_GAIN], + HID_REQ_SET_REPORT); } error = pidff_check_autocenter(pidff, dev); diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 87bd64959a91..430d2a9e4521 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -705,7 +705,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (report == NULL) break; - usbhid_submit_report(hid, report, USB_DIR_IN); + hid_hw_request(hid, report, HID_REQ_GET_REPORT); usbhid_wait_io(hid); r = 0; @@ -724,7 +724,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (report == NULL) break; - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_hw_request(hid, report, HID_REQ_SET_REPORT); usbhid_wait_io(hid); r = 0; diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index bd87a61e5303..aa1d5ff1208f 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -38,8 +38,6 @@ int usbhid_wait_io(struct hid_device* hid); void usbhid_close(struct hid_device *hid); int usbhid_open(struct hid_device *hid); void usbhid_init_reports(struct hid_device *hid); -void usbhid_submit_report -(struct hid_device *hid, struct hid_report *report, unsigned char dir); int usbhid_get_power(struct hid_device *hid); void usbhid_put_power(struct hid_device *hid); struct usb_interface *usbhid_find_interface(int minor); -- cgit From b7966a4d7be0a10329f03330390f4bdaf453d74a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:47 +0100 Subject: HID: use hid_hw_wait() instead of direct call to usbhid This removes most of the dependencies between hid drivers and usbhid. The patch was constructed by replacing all occurences of usbhid_wait_io() by its hid_hw_wait() counterpart. Then, drivers not requiring USB_HID anymore have their USB_HID dependency cleaned in the Kconfig file. As of today, few drivers are still requiring an explicit USB layer dependency: * ntrig (a patch is on its way) * multitouch (one patch following and another on its way) * lenovo tpkbd * roccat * sony The last three are two deeply using direct calls to the usb subsystem to be able to be cleaned right now. Signed-off-by: Benjamin Tissoires Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- drivers/hid/hid-ntrig.c | 4 ++-- drivers/hid/hid-picolcd_fb.c | 5 ++--- drivers/hid/hid-sensor-hub.c | 5 ++--- drivers/hid/usbhid/hid-core.c | 3 +-- drivers/hid/usbhid/hid-pidff.c | 16 ++++++++-------- drivers/hid/usbhid/hiddev.c | 4 ++-- drivers/hid/usbhid/usbhid.h | 1 - 8 files changed, 18 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index f0acf2754b69..c802b0716f48 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -479,7 +479,7 @@ config HID_PETALYNX config HID_PICOLCD tristate "PicoLCD (graphic version)" - depends on USB_HID + depends on HID ---help--- This provides support for Minibox PicoLCD devices, currently only the graphical ones are supported. diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index b926592e6c16..ef95102515e4 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -119,7 +119,7 @@ static inline int ntrig_get_mode(struct hid_device *hdev) return -EINVAL; hid_hw_request(hdev, report, HID_REQ_GET_REPORT); - usbhid_wait_io(hdev); + hid_hw_wait(hdev); return (int)report->field[0]->value[0]; } @@ -937,7 +937,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) if (report) { /* Let the device settle to ensure the wakeup message gets * through */ - usbhid_wait_io(hdev); + hid_hw_wait(hdev); hid_hw_request(hdev, report, HID_REQ_GET_REPORT); /* diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c index 98f61de9a5e0..591f6b22aa94 100644 --- a/drivers/hid/hid-picolcd_fb.c +++ b/drivers/hid/hid-picolcd_fb.c @@ -19,7 +19,6 @@ #include #include -#include "usbhid/usbhid.h" #include #include @@ -269,7 +268,7 @@ static void picolcd_fb_update(struct fb_info *info) mutex_unlock(&info->lock); if (!data) return; - usbhid_wait_io(data->hdev); + hid_hw_wait(data->hdev); mutex_lock(&info->lock); n = 0; } @@ -287,7 +286,7 @@ static void picolcd_fb_update(struct fb_info *info) spin_unlock_irqrestore(&fbdata->lock, flags); mutex_unlock(&info->lock); if (data) - usbhid_wait_io(data->hdev); + hid_hw_wait(data->hdev); return; } out: diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 59d29f853ac0..ca7498107327 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -18,7 +18,6 @@ */ #include #include -#include "usbhid/usbhid.h" #include #include #include @@ -204,7 +203,7 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, } hid_set_field(report->field[field_index], 0, value); hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); - usbhid_wait_io(hsdev->hdev); + hid_hw_wait(hsdev->hdev); done_proc: mutex_unlock(&data->mutex); @@ -227,7 +226,7 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, goto done_proc; } hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); - usbhid_wait_io(hsdev->hdev); + hid_hw_wait(hsdev->hdev); *value = report->field[field_index]->value[0]; done_proc: diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index da68687d2c7c..420466bc481a 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -705,7 +705,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un return 0; } -int usbhid_wait_io(struct hid_device *hid) +static int usbhid_wait_io(struct hid_device *hid) { struct usbhid_device *usbhid = hid->driver_data; @@ -719,7 +719,6 @@ int usbhid_wait_io(struct hid_device *hid) return 0; } -EXPORT_SYMBOL_GPL(usbhid_wait_io); static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) { diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 0f1efa39ec46..10b616702780 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -471,13 +471,13 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; pidff->block_load_status->value[0] = 0; - usbhid_wait_io(pidff->hid); + hid_hw_wait(pidff->hid); for (j = 0; j < 60; j++) { hid_dbg(pidff->hid, "pid_block_load requested\n"); hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_LOAD], HID_REQ_GET_REPORT); - usbhid_wait_io(pidff->hid); + hid_hw_wait(pidff->hid); if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { hid_dbg(pidff->hid, "device reported free memory: %d bytes\n", @@ -551,7 +551,7 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id) effect_id, pidff->pid_id[effect_id]); /* Wait for the queue to clear. We do not want a full fifo to prevent the effect removal. */ - usbhid_wait_io(pidff->hid); + hid_hw_wait(pidff->hid); pidff_playback_pid(pidff, pid_id, 0); pidff_erase_pid(pidff, pid_id); @@ -1159,18 +1159,18 @@ static void pidff_reset(struct pidff_device *pidff) pidff->device_control->value[0] = pidff->control_id[PID_RESET]; /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); pidff->device_control->value[0] = pidff->control_id[PID_ENABLE_ACTUATORS]; hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); /* pool report is sometimes messed up, refetch it */ hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) { @@ -1183,7 +1183,7 @@ static void pidff_reset(struct pidff_device *pidff) hid_dbg(pidff->hid, "pid_pool requested again\n"); hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); } } } diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 430d2a9e4521..2f1ddca6f2e0 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -706,7 +706,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; hid_hw_request(hid, report, HID_REQ_GET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); r = 0; break; @@ -725,7 +725,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; hid_hw_request(hid, report, HID_REQ_SET_REPORT); - usbhid_wait_io(hid); + hid_hw_wait(hid); r = 0; break; diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index aa1d5ff1208f..dbb6af699135 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -34,7 +34,6 @@ #include /* API provided by hid-core.c for USB HID drivers */ -int usbhid_wait_io(struct hid_device* hid); void usbhid_close(struct hid_device *hid); int usbhid_open(struct hid_device *hid); void usbhid_init_reports(struct hid_device *hid); -- cgit From 4ebc9b636cdc340196138f35ca0788b8da0e1779 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:48 +0100 Subject: HID: multitouch: remove explicit usbhid dependency This patch is part of the cleanup of the HID drivers against their low-level transport layer. With new touchscreens relying on I2C, it's better to handle now these dependencies before users get kernel oopses. Signed-off-by: Benjamin Tissoires Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 32258ba60056..184ac0a42121 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -32,7 +32,6 @@ #include #include #include -#include "usbhid/usbhid.h" MODULE_AUTHOR("Stephane Chatty "); @@ -907,7 +906,7 @@ static int mt_resume(struct hid_device *hdev) intf = to_usb_interface(hdev->dev.parent); interface = intf->cur_altsetting; - dev = hid_to_usb_dev(hdev); + dev = interface_to_usbdev(intf); /* Some Elan legacy devices require SET_IDLE to be set on resume. * It should be safe to send it to other devices too. -- cgit From b0a7868181be0a28fc35231d7435c1fb360eb675 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:49 +0100 Subject: HID: multitouch: Copyright and note on regression tests This reflects my new company and officialize the regression tests I'm conducting between each change. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Reviewed-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 184ac0a42121..3af9efdd13d9 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -2,8 +2,9 @@ * HID driver for multitouch panels * * Copyright (c) 2010-2012 Stephane Chatty - * Copyright (c) 2010-2012 Benjamin Tissoires + * Copyright (c) 2010-2013 Benjamin Tissoires * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France + * Copyright (c) 2012-2013 Red Hat, Inc * * This code is partly based on hid-egalax.c: * @@ -26,6 +27,17 @@ * any later version. */ +/* + * This driver is regularly tested thanks to the tool hid-test[1]. + * This tool relies on hid-replay[2] and a database of hid devices[3]. + * Please run these regression tests before patching this module so that + * your patch won't break existing known devices. + * + * [1] https://github.com/bentiss/hid-test + * [2] https://github.com/bentiss/hid-replay + * [3] https://github.com/bentiss/hid-devices + */ + #include #include #include -- cgit From 545bef681088cbf49c9c11d63872698b81eac7eb Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 25 Feb 2013 11:31:50 +0100 Subject: HID: i2c-hid: implement request() callback This allows HID drivers to also get/set reports through hid_hw_request(). Tested-by: Mika Westerberg Signed-off-by: Benjamin Tissoires Signed-off-by: Mika Westerberg Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index ec7930217a6d..935f387be95a 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -563,6 +563,37 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, return ret; } +static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, + int reqtype) +{ + struct i2c_client *client = hid->driver_data; + struct i2c_hid *ihid = i2c_get_clientdata(client); + char *buf; + int ret; + + buf = kzalloc(ihid->bufsize, GFP_KERNEL); + if (!buf) + return; + + switch (reqtype) { + case HID_REQ_GET_REPORT: + ret = i2c_hid_get_raw_report(hid, rep->id, buf, ihid->bufsize, + rep->type); + if (ret < 0) + dev_err(&client->dev, "%s: unable to get report: %d\n", + __func__, ret); + else + hid_input_report(hid, rep->type, buf, ret, 0); + break; + case HID_REQ_SET_REPORT: + hid_output_report(rep, buf); + i2c_hid_output_raw_report(hid, buf, ihid->bufsize, rep->type); + break; + } + + kfree(buf); +} + static int i2c_hid_parse(struct hid_device *hid) { struct i2c_client *client = hid->driver_data; @@ -742,6 +773,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .open = i2c_hid_open, .close = i2c_hid_close, .power = i2c_hid_power, + .request = i2c_hid_request, .hidinput_input_event = i2c_hid_hidinput_input_event, }; -- cgit From 6399f335c2c5fb9c244bbb2b8a437498d260bed7 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 19 Feb 2013 11:22:33 +0200 Subject: HID: make sensor autodetection independent of underlying bus Instead of limiting HID sensors to USB and I2C busses we can just make everything that has usage page of HID_UP_SENSOR to be included in HID_GROUP_SENSOR_HUB group. This allows the sensor-hub to work over bluetooth (and other transports) as well. Reported-by: Alexander Holler Signed-off-by: Mika Westerberg Reviewed-By: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ff75cabf7393..fea20c650f3f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -728,8 +728,7 @@ static int hid_scan_report(struct hid_device *hid) } else if (page == HID_UP_SENSOR && item.type == HID_ITEM_TYPE_MAIN && item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && - (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && - (hid->bus == BUS_USB || hid->bus == BUS_I2C)) + (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL) hid->group = HID_GROUP_SENSOR_HUB; } -- cgit From d6b0c58048d2c8c6f4955c37f670125b2792cd14 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 23 Feb 2013 13:11:14 -0800 Subject: devres: allow adding custom actions to the stack Sometimes drivers need to execute one-off actions in their error handling or device teardown paths. An example would be toggling a GPIO line to reset the controlled device into predefined state. To allow performing such actions when using managed resources let's allow adding them to stack/group of devres resources. Acked-by: Tejun Heo Acked-by: Greg Kroah-Hartman Signed-off-by: Dmitry Torokhov --- drivers/base/devres.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 4 +++ 2 files changed, 78 insertions(+) (limited to 'drivers') diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 8731979d668a..724957a13d48 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -670,6 +670,80 @@ int devres_release_group(struct device *dev, void *id) } EXPORT_SYMBOL_GPL(devres_release_group); +/* + * Custom devres actions allow inserting a simple function call + * into the teadown sequence. + */ + +struct action_devres { + void *data; + void (*action)(void *); +}; + +static int devm_action_match(struct device *dev, void *res, void *p) +{ + struct action_devres *devres = res; + struct action_devres *target = p; + + return devres->action == target->action && + devres->data == target->data; +} + +static void devm_action_release(struct device *dev, void *res) +{ + struct action_devres *devres = res; + + devres->action(devres->data); +} + +/** + * devm_add_action() - add a custom action to list of managed resources + * @dev: Device that owns the action + * @action: Function that should be called + * @data: Pointer to data passed to @action implementation + * + * This adds a custom action to the list of managed resources so that + * it gets executed as part of standard resource unwinding. + */ +int devm_add_action(struct device *dev, void (*action)(void *), void *data) +{ + struct action_devres *devres; + + devres = devres_alloc(devm_action_release, + sizeof(struct action_devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; + + devres->data = data; + devres->action = action; + + devres_add(dev, devres); + return 0; +} +EXPORT_SYMBOL_GPL(devm_add_action); + +/** + * devm_remove_action() - removes previously added custom action + * @dev: Device that owns the action + * @action: Function implementing the action + * @data: Pointer to data passed to @action implementation + * + * Removes instance of @action previously added by devm_add_action(). + * Both action and data should match one of the existing entries. + */ +void devm_remove_action(struct device *dev, void (*action)(void *), void *data) +{ + struct action_devres devres = { + .data = data, + .action = action, + }; + + WARN_ON(devres_destroy(dev, devm_action_release, devm_action_match, + &devres)); + +} +EXPORT_SYMBOL_GPL(devm_remove_action); + /* * Managed kzalloc/kfree */ diff --git a/include/linux/device.h b/include/linux/device.h index 86ef6ab553b1..854b247bf5f9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -567,6 +567,10 @@ extern void devm_kfree(struct device *dev, void *p); void __iomem *devm_request_and_ioremap(struct device *dev, struct resource *res); +/* allows to add/remove a custom action to devres stack */ +int devm_add_action(struct device *dev, void (*action)(void *), void *data); +void devm_remove_action(struct device *dev, void (*action)(void *), void *data); + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about -- cgit From bfc29e95950345dca0d64a79da46f6b8592c0b1e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 23 Feb 2013 12:18:14 -0800 Subject: Input: auo-pixcir-ts - switch to using managed resources This simplifies error unwinding and device teardown. Tested-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 163 +++++++++++++----------------- 1 file changed, 69 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index dfa6d5463ef7..d3f9f6b0f9b7 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -533,13 +533,21 @@ static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) } #endif +static void auo_pixcir_reset(void *data) +{ + struct auo_pixcir_ts *ts = data; + + gpio_set_value(ts->pdata->gpio_rst, 0); +} + static int auo_pixcir_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { const struct auo_pixcir_ts_platdata *pdata; struct auo_pixcir_ts *ts; struct input_dev *input_dev; - int ret; + int version; + int error; pdata = dev_get_platdata(&client->dev); if (!pdata) { @@ -548,60 +556,30 @@ static int auo_pixcir_probe(struct i2c_client *client, return PTR_ERR(pdata); } - ts = kzalloc(sizeof(struct auo_pixcir_ts), GFP_KERNEL); + ts = devm_kzalloc(&client->dev, + sizeof(struct auo_pixcir_ts), GFP_KERNEL); if (!ts) return -ENOMEM; - ret = gpio_request(pdata->gpio_int, "auo_pixcir_ts_int"); - if (ret) { - dev_err(&client->dev, "request of gpio %d failed, %d\n", - pdata->gpio_int, ret); - goto err_gpio_int; - } - - ret = gpio_direction_input(pdata->gpio_int); - if (ret) { - dev_err(&client->dev, "setting direction of gpio %d failed %d\n", - pdata->gpio_int, ret); - goto err_gpio_dir; - } - - ret = gpio_request(pdata->gpio_rst, "auo_pixcir_ts_rst"); - if (ret) { - dev_err(&client->dev, "request of gpio %d failed, %d\n", - pdata->gpio_rst, ret); - goto err_gpio_dir; - } - - ret = gpio_direction_output(pdata->gpio_rst, 1); - if (ret) { - dev_err(&client->dev, "setting direction of gpio %d failed %d\n", - pdata->gpio_rst, ret); - goto err_gpio_rst; + input_dev = devm_input_allocate_device(&client->dev); + if (!input_dev) { + dev_err(&client->dev, "could not allocate input device\n"); + return -ENOMEM; } - msleep(200); - ts->pdata = pdata; ts->client = client; + ts->input = input_dev; ts->touch_ind_mode = 0; + ts->stopped = true; init_waitqueue_head(&ts->wait); snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); - input_dev = input_allocate_device(); - if (!input_dev) { - dev_err(&client->dev, "could not allocate input device\n"); - goto err_input_alloc; - } - - ts->input = input_dev; - input_dev->name = "AUO-Pixcir touchscreen"; input_dev->phys = ts->phys; input_dev->id.bustype = BUS_I2C; - input_dev->dev.parent = &client->dev; input_dev->open = auo_pixcir_input_open; input_dev->close = auo_pixcir_input_close; @@ -626,72 +604,70 @@ static int auo_pixcir_probe(struct i2c_client *client, AUO_PIXCIR_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); - ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_VERSION); - if (ret < 0) - goto err_fw_vers; - dev_info(&client->dev, "firmware version 0x%X\n", ret); - - ret = auo_pixcir_int_config(ts, pdata->int_setting); - if (ret) - goto err_fw_vers; - input_set_drvdata(ts->input, ts); - ts->stopped = true; - ret = request_threaded_irq(client->irq, NULL, auo_pixcir_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - input_dev->name, ts); - if (ret) { - dev_err(&client->dev, "irq %d requested failed\n", client->irq); - goto err_fw_vers; + error = devm_gpio_request_one(&client->dev, pdata->gpio_int, + GPIOF_DIR_IN, "auo_pixcir_ts_int"); + if (error) { + dev_err(&client->dev, "request of gpio %d failed, %d\n", + pdata->gpio_int, error); + return error; } - /* stop device and put it into deep sleep until it is opened */ - ret = auo_pixcir_stop(ts); - if (ret < 0) - goto err_input_register; - - ret = input_register_device(input_dev); - if (ret) { - dev_err(&client->dev, "could not register input device\n"); - goto err_input_register; + error = devm_gpio_request_one(&client->dev, pdata->gpio_rst, + GPIOF_DIR_OUT | GPIOF_INIT_HIGH, + "auo_pixcir_ts_rst"); + if (error) { + dev_err(&client->dev, "request of gpio %d failed, %d\n", + pdata->gpio_rst, error); + return error; } - i2c_set_clientdata(client, ts); - - return 0; - -err_input_register: - free_irq(client->irq, ts); -err_fw_vers: - input_free_device(input_dev); -err_input_alloc: - gpio_set_value(pdata->gpio_rst, 0); -err_gpio_rst: - gpio_free(pdata->gpio_rst); -err_gpio_dir: - gpio_free(pdata->gpio_int); -err_gpio_int: - kfree(ts); + error = devm_add_action(&client->dev, auo_pixcir_reset, ts); + if (error) { + auo_pixcir_reset(ts); + dev_err(&client->dev, "failed to register reset action, %d\n", + error); + return error; + } - return ret; -} + msleep(200); -static int auo_pixcir_remove(struct i2c_client *client) -{ - struct auo_pixcir_ts *ts = i2c_get_clientdata(client); - const struct auo_pixcir_ts_platdata *pdata = ts->pdata; + version = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_VERSION); + if (version < 0) { + error = version; + return error; + } - free_irq(client->irq, ts); + dev_info(&client->dev, "firmware version 0x%X\n", version); - input_unregister_device(ts->input); + error = auo_pixcir_int_config(ts, pdata->int_setting); + if (error) + return error; - gpio_set_value(pdata->gpio_rst, 0); - gpio_free(pdata->gpio_rst); + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, auo_pixcir_interrupt, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + input_dev->name, ts); + if (error) { + dev_err(&client->dev, "irq %d requested failed, %d\n", + client->irq, error); + return error; + } - gpio_free(pdata->gpio_int); + /* stop device and put it into deep sleep until it is opened */ + error = auo_pixcir_stop(ts); + if (error) + return error; + + error = input_register_device(input_dev); + if (error) { + dev_err(&client->dev, "could not register input device, %d\n", + error); + return error; + } - kfree(ts); + i2c_set_clientdata(client, ts); return 0; } @@ -718,7 +694,6 @@ static struct i2c_driver auo_pixcir_driver = { .of_match_table = of_match_ptr(auo_pixcir_ts_dt_idtable), }, .probe = auo_pixcir_probe, - .remove = auo_pixcir_remove, .id_table = auo_pixcir_idtable, }; -- cgit From b3816d50439245d888798ee620da1e27cbf86c66 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 22 Dec 2012 13:31:19 +0800 Subject: regulator: twl: Convert twl[6030|4030]fixed_ops to regulator_list_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 74508cc62d67..b68df81b6f8f 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -616,18 +616,8 @@ static struct regulator_ops twl6030ldo_ops = { /*----------------------------------------------------------------------*/ -/* - * Fixed voltage LDOs don't have a VSEL field to update. - */ -static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index) -{ - struct twlreg_info *info = rdev_get_drvdata(rdev); - - return info->min_mV * 1000; -} - static struct regulator_ops twl4030fixed_ops = { - .list_voltage = twlfixed_list_voltage, + .list_voltage = regulator_list_voltage_linear, .enable = twl4030reg_enable, .disable = twl4030reg_disable, @@ -639,7 +629,7 @@ static struct regulator_ops twl4030fixed_ops = { }; static struct regulator_ops twl6030fixed_ops = { - .list_voltage = twlfixed_list_voltage, + .list_voltage = regulator_list_voltage_linear, .enable = twl6030reg_enable, .disable = twl6030reg_disable, @@ -945,6 +935,7 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \ .ops = &operations, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ + .min_uV = mVolts * 1000, \ .enable_time = turnon_delay, \ }, \ } -- cgit From 4813dd0efcfbf85bd79759fda50b9a6ad4e5ff9c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 15 Feb 2013 22:23:01 +0800 Subject: regulator: twl: Remove VDD1_VSEL_table and VDD2_VSEL_table Since commit ba305e31 "regulator: twl: fix twl4030 support for smps regulators", VDD1_VSEL_table and VDD2_VSEL_table are not used any more. Remove them. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index b68df81b6f8f..c9242988d010 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -441,12 +441,6 @@ static const u16 VSIM_VSEL_table[] = { static const u16 VDAC_VSEL_table[] = { 1200, 1300, 1800, 1800, }; -static const u16 VDD1_VSEL_table[] = { - 800, 1450, -}; -static const u16 VDD2_VSEL_table[] = { - 800, 1450, 1500, -}; static const u16 VIO_VSEL_table[] = { 1800, 1850, }; -- cgit From d1924519fe1dada0cfd9a228bf2ff1ea15840c84 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Feb 2013 10:53:49 +0800 Subject: regulator: twl: Remove TWL6030_FIXED_RESOURCE TWL6030_FIXED_RESOURCE is not used now, remove it. TWL6030_FIXED_RESOURCE is not used since commit e76ab829cc "regulator: twl: Remove references to the twl4030 regulator" twl6030_fixed_resource is removed by commit 029dd3cef "regulator: twl: Remove another unused variable warning". Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index c9242988d010..cb872bfd3442 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -934,19 +934,6 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \ }, \ } -#define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \ -static struct twlreg_info TWLRES_INFO_##label = { \ - .base = offset, \ - .desc = { \ - .name = #label, \ - .id = TWL6030_REG_##label, \ - .ops = &twl6030_fixed_resource, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .enable_time = turnon_delay, \ - }, \ - } - #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ static const struct twlreg_info TWLSMPS_INFO_##label = { \ .base = offset, \ -- cgit From c849a6143bec520aff2a6646518b0d041402428b Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Mon, 18 Feb 2013 09:20:21 -0800 Subject: HID: Separate struct hid_device's driver_lock into two locks. This patch separates struct hid_device's driver_lock into two. The goal is to allow hid device drivers to receive input during their probe() or remove() function calls. This is necessary because some drivers need to communicate with the device to determine parameters needed during probe (e.g., size of a multi-touch surface), and if possible, may perfer to communicate with a device on host-initiated disconnect (e.g., to put it into a low-power state). Historically, three functions used driver_lock: - hid_device_probe: blocks to acquire lock - hid_device_remove: blocks to acquire lock - hid_input_report: if locked returns -EBUSY, else acquires lock This patch adds another lock (driver_input_lock) which is used to block input from occurring. The lock behavior is now: - hid_device_probe: blocks to acq. driver_lock, then driver_input_lock - hid_device_remove: blocks to acq. driver_lock, then driver_input_lock - hid_input_report: if driver_input_lock locked returns -EBUSY, else acquires driver_input_lock This patch also adds two helper functions to be called during probe() or remove(): hid_device_io_start() and hid_device_io_stop(). These functions lock and unlock, respectively, driver_input_lock; they also make a note of whether they did so that hid-core knows if a driver has changed the lock state. This patch results in no behavior change for existing devices and drivers. However, during a probe() or remove() function call in a driver, that driver may now selectively call hid_device_io_start() to let input events come through, then optionally call hid_device_io_stop() to stop them. Signed-off-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 24 +++++++++++++++++++++--- include/linux/hid.h | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ff75cabf7393..680068c0c46a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1267,7 +1267,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i if (!hid) return -ENODEV; - if (down_trylock(&hid->driver_lock)) + if (down_trylock(&hid->driver_input_lock)) return -EBUSY; if (!hid->driver) { @@ -1324,7 +1324,7 @@ nomem: ret = hid_report_raw_event(hid, type, data, size, interrupt); unlock: - up(&hid->driver_lock); + up(&hid->driver_input_lock); return ret; } EXPORT_SYMBOL_GPL(hid_input_report); @@ -1845,6 +1845,11 @@ static int hid_device_probe(struct device *dev) if (down_interruptible(&hdev->driver_lock)) return -EINTR; + if (down_interruptible(&hdev->driver_input_lock)) { + ret = -EINTR; + goto unlock_driver_lock; + } + hdev->io_started = false; if (!hdev->driver) { id = hid_match_device(hdev, hdrv); @@ -1867,6 +1872,9 @@ static int hid_device_probe(struct device *dev) } } unlock: + if (!hdev->io_started) + up(&hdev->driver_input_lock); +unlock_driver_lock: up(&hdev->driver_lock); return ret; } @@ -1875,9 +1883,15 @@ static int hid_device_remove(struct device *dev) { struct hid_device *hdev = container_of(dev, struct hid_device, dev); struct hid_driver *hdrv; + int ret = 0; if (down_interruptible(&hdev->driver_lock)) return -EINTR; + if (down_interruptible(&hdev->driver_input_lock)) { + ret = -EINTR; + goto unlock_driver_lock; + } + hdev->io_started = false; hdrv = hdev->driver; if (hdrv) { @@ -1889,8 +1903,11 @@ static int hid_device_remove(struct device *dev) hdev->driver = NULL; } + if (!hdev->io_started) + up(&hdev->driver_input_lock); +unlock_driver_lock: up(&hdev->driver_lock); - return 0; + return ret; } static ssize_t modalias_show(struct device *dev, struct device_attribute *a, @@ -2329,6 +2346,7 @@ struct hid_device *hid_allocate_device(void) init_waitqueue_head(&hdev->debug_wait); INIT_LIST_HEAD(&hdev->debug_list); sema_init(&hdev->driver_lock, 1); + sema_init(&hdev->driver_input_lock, 1); return hdev; } diff --git a/include/linux/hid.h b/include/linux/hid.h index e14b465b1146..895b85639dec 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -456,7 +456,8 @@ struct hid_device { /* device report descriptor */ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; - struct semaphore driver_lock; /* protects the current driver */ + struct semaphore driver_lock; /* protects the current driver, except during input */ + struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; struct hid_ll_driver *ll_driver; @@ -477,6 +478,7 @@ struct hid_device { /* device report descriptor */ unsigned int status; /* see STAT flags above */ unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ + bool io_started; /* Protected by driver_lock. If IO has started */ struct list_head inputs; /* The list of inputs */ void *hiddev; /* The hiddev structure */ @@ -599,6 +601,10 @@ struct hid_usage_id { * @resume: invoked on resume if device was not reset (NULL means nop) * @reset_resume: invoked on resume if device was reset (NULL means nop) * + * probe should return -errno on error, or 0 on success. During probe, + * input will not be passed to raw_event unless hid_device_io_start is + * called. + * * raw_event and event should return 0 on no action performed, 1 when no * further processing should be done and negative on error * @@ -737,6 +743,44 @@ const struct hid_device_id *hid_match_id(struct hid_device *hdev, const struct hid_device_id *id); s32 hid_snto32(__u32 value, unsigned n); +/** + * hid_device_io_start - enable HID input during probe, remove + * + * @hid - the device + * + * This should only be called during probe or remove and only be + * called by the thread calling probe or remove. It will allow + * incoming packets to be delivered to the driver. + */ +static inline void hid_device_io_start(struct hid_device *hid) { + if (hid->io_started) { + dev_warn(&hid->dev, "io already started"); + return; + } + hid->io_started = true; + up(&hid->driver_input_lock); +} + +/** + * hid_device_io_stop - disable HID input during probe, remove + * + * @hid - the device + * + * Should only be called after hid_device_io_start. It will prevent + * incoming packets from going to the driver for the duration of + * probe, remove. If called during probe, packets will still go to the + * driver after probe is complete. This function should only be called + * by the thread calling probe or remove. + */ +static inline void hid_device_io_stop(struct hid_device *hid) { + if (!hid->io_started) { + dev_warn(&hid->dev, "io already stopped"); + return; + } + hid->io_started = false; + down(&hid->driver_input_lock); +} + /** * hid_map_usage - map usage input bits * -- cgit From a9dd22b73085734735cfa07398451b061626cc53 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Mon, 18 Feb 2013 09:20:22 -0800 Subject: HID: logitech-dj: Allow incoming packets during probe(). Historically, logitech-dj communicated with the device during probe() to query the list of devices attached. Later, a change was introduced to hid-core that prevented incoming packets for a device during probe(), as many drivers are unable to handle such input. That change broke the device enumeration in logitech-dj, so commit 596264082f10dd4a56 was introduced to workaround that by waiting for normal input before enumerating devices. Now that drivers can opt-in to receive input during probe, this patch changes logitech-dj to do that, so that it can successfully complete enumeration of devices during probe(). Signed-off-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9500f2f3f8fe..bf647ef18086 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -803,6 +803,9 @@ static int logi_dj_probe(struct hid_device *hdev, goto llopen_failed; } + /* Allow incoming packets to arrive: */ + hid_device_io_start(hdev); + retval = logi_dj_recv_query_paired_devices(djrcv_dev); if (retval < 0) { dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices " -- cgit From 8af6c08830b1ae114d1a8b548b1f8b056e068887 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Mon, 18 Feb 2013 09:20:23 -0800 Subject: Revert "HID: Fix logitech-dj: missing Unifying device issue" This reverts commit 596264082f10dd4a567c43d4526b2f54ac5520bc. The reverted commit was a workaround needed when drivers became unable to communicate with devices during probe(). Now that such communication is possible, the workaround is not needed. Signed-off-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 45 ------------------------------------------- drivers/hid/hid-logitech-dj.h | 1 - 2 files changed, 46 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index bf647ef18086..199b78c8a5f3 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -193,7 +193,6 @@ static struct hid_ll_driver logi_dj_ll_driver; static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, size_t count, unsigned char report_type); -static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, struct dj_report *dj_report) @@ -234,7 +233,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & SPFUNCTION_DEVICE_LIST_EMPTY) { dbg_hid("%s: device list is empty\n", __func__); - djrcv_dev->querying_devices = false; return; } @@ -245,12 +243,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, return; } - if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { - /* The device is already known. No need to reallocate it. */ - dbg_hid("%s: device is already known\n", __func__); - return; - } - dj_hiddev = hid_allocate_device(); if (IS_ERR(dj_hiddev)) { dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n", @@ -314,7 +306,6 @@ static void delayedwork_callback(struct work_struct *work) struct dj_report dj_report; unsigned long flags; int count; - int retval; dbg_hid("%s\n", __func__); @@ -347,25 +338,6 @@ static void delayedwork_callback(struct work_struct *work) logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); break; default: - /* A normal report (i. e. not belonging to a pair/unpair notification) - * arriving here, means that the report arrived but we did not have a - * paired dj_device associated to the report's device_index, this - * means that the original "device paired" notification corresponding - * to this dj_device never arrived to this driver. The reason is that - * hid-core discards all packets coming from a device while probe() is - * executing. */ - if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) { - /* ok, we don't know the device, just re-ask the - * receiver for the list of connected devices. */ - retval = logi_dj_recv_query_paired_devices(djrcv_dev); - if (!retval) { - /* everything went fine, so just leave */ - break; - } - dev_err(&djrcv_dev->hdev->dev, - "%s:logi_dj_recv_query_paired_devices " - "error:%d\n", __func__, retval); - } dbg_hid("%s: unexpected report type\n", __func__); } } @@ -396,12 +368,6 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev, if (!djdev) { dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" " is NULL, index %d\n", dj_report->device_index); - kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); - - if (schedule_work(&djrcv_dev->work) == 0) { - dbg_hid("%s: did not schedule the work item, was already " - "queued\n", __func__); - } return; } @@ -432,12 +398,6 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev, if (dj_device == NULL) { dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" " is NULL, index %d\n", dj_report->device_index); - kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); - - if (schedule_work(&djrcv_dev->work) == 0) { - dbg_hid("%s: did not schedule the work item, was already " - "queued\n", __func__); - } return; } @@ -479,10 +439,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) struct dj_report *dj_report; int retval; - /* no need to protect djrcv_dev->querying_devices */ - if (djrcv_dev->querying_devices) - return 0; - dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); if (!dj_report) return -ENOMEM; @@ -494,7 +450,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) return retval; } - static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h index 4a4000340ce1..fd28a5e0ca3b 100644 --- a/drivers/hid/hid-logitech-dj.h +++ b/drivers/hid/hid-logitech-dj.h @@ -101,7 +101,6 @@ struct dj_receiver_dev { struct work_struct work; struct kfifo notif_fifo; spinlock_t lock; - bool querying_devices; }; struct dj_device { -- cgit From 9ea49fff04917255ad3dbc2231587a8e8ec0a389 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 19 Dec 2012 16:42:29 +0000 Subject: clk: ux500: Ensure the FMSC clock is obtainable The FMSC clock is traditionally used for NAND flash devices when used on the ux500 series platforms. This patch makes it searchable during a clock-name search. Acked-by: Mike Turquette Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/clk/ux500/u8500_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 6b889a0e90b3..a60180228628 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -324,7 +324,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE, BIT(0), 0); - clk_register_clkdev(clk, NULL, "fsmc"); + clk_register_clkdev(clk, "fsmc", NULL); clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); -- cgit From 1e6b6801405ec578c8607e9dabcc4e946ea64f4c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 19 Dec 2012 16:48:02 +0000 Subject: clk: ux500: Provide an alias for the SMSC911x Ethernet chip In the case of some of the ux500 platforms, an Ethernet chip is placed on an extended bus which is traditionally used as a NAND flash chip placeholder. The p3_pclk0 clock is used to control it, so we are required to provide and easy way to access it from the SMSC911x driver. We do this using an alias provided by this patch. Acked-by: Mike Turquette Acked-by: Ulf Hansson Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/clk/ux500/u8500_clk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index a60180228628..9d9add1e816d 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -325,6 +325,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE, BIT(0), 0); clk_register_clkdev(clk, "fsmc", NULL); + clk_register_clkdev(clk, NULL, "smsc911x"); clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); -- cgit From b6c230196f07b9cdd23ceb899070076cdab0c467 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 19 Dec 2012 17:03:48 +0000 Subject: net/smsc911x: Provide common clock functionality Some platforms provide clocks which require enabling before the SMSC911x chip will power on. This patch uses the new common clk framework to do just that. If no clock is provided, it will just be ignored and the driver will continue to assume that no clock is required for the chip to run successfully. Acked-by: David S. Miller Reviewed-by: Linus Walleij Reviewed-by: Ulf Hansson Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/net/ethernet/smsc/smsc911x.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index da5cc9a3b34c..df77df16d991 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -33,6 +33,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -144,6 +145,9 @@ struct smsc911x_data { /* regulators */ struct regulator_bulk_data supplies[SMSC911X_NUM_SUPPLIES]; + + /* clock */ + struct clk *clk; }; /* Easy access to information */ @@ -369,7 +373,7 @@ out: } /* - * enable resources, currently just regulators. + * enable regulator and clock resources. */ static int smsc911x_enable_resources(struct platform_device *pdev) { @@ -382,6 +386,13 @@ static int smsc911x_enable_resources(struct platform_device *pdev) if (ret) netdev_err(ndev, "failed to enable regulators %d\n", ret); + + if (!IS_ERR(pdata->clk)) { + ret = clk_prepare_enable(pdata->clk); + if (ret < 0) + netdev_err(ndev, "failed to enable clock %d\n", ret); + } + return ret; } @@ -396,6 +407,10 @@ static int smsc911x_disable_resources(struct platform_device *pdev) ret = regulator_bulk_disable(ARRAY_SIZE(pdata->supplies), pdata->supplies); + + if (!IS_ERR(pdata->clk)) + clk_disable_unprepare(pdata->clk); + return ret; } @@ -421,6 +436,12 @@ static int smsc911x_request_resources(struct platform_device *pdev) if (ret) netdev_err(ndev, "couldn't get regulators %d\n", ret); + + /* Request clock */ + pdata->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(pdata->clk)) + netdev_warn(ndev, "couldn't get clock %li\n", PTR_ERR(pdata->clk)); + return ret; } @@ -436,6 +457,12 @@ static void smsc911x_free_resources(struct platform_device *pdev) /* Free regulators */ regulator_bulk_free(ARRAY_SIZE(pdata->supplies), pdata->supplies); + + /* Free clock */ + if (!IS_ERR(pdata->clk)) { + clk_put(pdata->clk); + pdata->clk = NULL; + } } /* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read -- cgit From 237fb5e675a312a84a602ad0fbdf0b4957c71073 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 31 Jan 2013 11:27:52 +0000 Subject: mmc: mmci: Move ios_handler functionality into the driver There are currently two instances of the ios_handler being used. Both of which mearly toy with some regulator settings. Now there is a GPIO regulator API, we can use that instead, and lessen the per platform burden. By doing this, we also become more Device Tree compatible. Acked-by: Chris Ball Signed-off-by: Lee Jones Signed-off-by: Ulf Hansson Signed-off-by: Russell King Signed-off-by: Linus Walleij --- drivers/mmc/host/mmci.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 372e921389c8..375c109607ff 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1141,6 +1141,11 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) case MMC_POWER_OFF: if (!IS_ERR(mmc->supply.vmmc)) mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + + if (!IS_ERR(mmc->supply.vqmmc) && + regulator_is_enabled(mmc->supply.vqmmc)) + regulator_disable(mmc->supply.vqmmc); + break; case MMC_POWER_UP: if (!IS_ERR(mmc->supply.vmmc)) @@ -1155,6 +1160,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; case MMC_POWER_ON: + if (!IS_ERR(mmc->supply.vqmmc) && + !regulator_is_enabled(mmc->supply.vqmmc)) + regulator_enable(mmc->supply.vqmmc); + pwr |= MCI_PWR_ON; break; } -- cgit From 165b6c2f33860e13d20cd7ac5993ea3acfb5ea34 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 14:54:48 -0700 Subject: gpio/tegra: assume CONFIG_OF Tegra only supports, and always enables, device tree. Remove all ifdefs and runtime checks for DT support from the driver. Signed-off-by: Stephen Warren Signed-off-by: Grant Likely --- drivers/gpio/gpio-tegra.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 414ad912232f..a78a81fbc2b0 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -398,10 +398,11 @@ static int tegra_gpio_probe(struct platform_device *pdev) int j; match = of_match_device(tegra_gpio_of_match, &pdev->dev); - if (match) - config = (struct tegra_gpio_soc_config *)match->data; - else - config = &tegra20_gpio_config; + if (!match) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; + } + config = (struct tegra_gpio_soc_config *)match->data; tegra_gpio_bank_stride = config->bank_stride; tegra_gpio_upper_offset = config->upper_offset; @@ -462,9 +463,7 @@ static int tegra_gpio_probe(struct platform_device *pdev) } } -#ifdef CONFIG_OF_GPIO tegra_gpio_chip.of_node = pdev->dev.of_node; -#endif gpiochip_add(&tegra_gpio_chip); -- cgit From fe7d4ccd1d7748bc9919c1bdee1e8286776f75ff Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Feb 2013 19:05:48 +0000 Subject: regmap: async: Add tracepoints for async I/O Trace when we start and complete async writes, and when we start and finish blocking for their completion. This is useful for performance analysis of the resulting I/O patterns. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 8 ++++++++ include/trace/events/regmap.h | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..7c6d3be137ba 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -999,6 +999,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, if (!async) return -ENOMEM; + trace_regmap_async_write_start(map->dev, reg, val_len); + async->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL | GFP_DMA); if (!async->work_buf) { @@ -1640,6 +1642,8 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret) struct regmap *map = async->map; bool wake; + trace_regmap_async_io_complete(map->dev); + spin_lock(&map->async_lock); list_del(&async->list); @@ -1686,6 +1690,8 @@ int regmap_async_complete(struct regmap *map) if (!map->bus->async_write) return 0; + trace_regmap_async_complete_start(map->dev); + wait_event(map->async_waitq, regmap_async_is_done(map)); spin_lock_irqsave(&map->async_lock, flags); @@ -1693,6 +1699,8 @@ int regmap_async_complete(struct regmap *map) map->async_ret = 0; spin_unlock_irqrestore(&map->async_lock, flags); + trace_regmap_async_complete_done(map->dev); + return ret; } EXPORT_SYMBOL_GPL(regmap_async_complete); diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h index 41a7dbd570e2..a43a2f67bd8e 100644 --- a/include/trace/events/regmap.h +++ b/include/trace/events/regmap.h @@ -175,6 +175,54 @@ DEFINE_EVENT(regmap_bool, regmap_cache_bypass, ); +DECLARE_EVENT_CLASS(regmap_async, + + TP_PROTO(struct device *dev), + + TP_ARGS(dev), + + TP_STRUCT__entry( + __string( name, dev_name(dev) ) + ), + + TP_fast_assign( + __assign_str(name, dev_name(dev)); + ), + + TP_printk("%s", __get_str(name)) +); + +DEFINE_EVENT(regmap_block, regmap_async_write_start, + + TP_PROTO(struct device *dev, unsigned int reg, int count), + + TP_ARGS(dev, reg, count) +); + +DEFINE_EVENT(regmap_async, regmap_async_io_complete, + + TP_PROTO(struct device *dev), + + TP_ARGS(dev) + +); + +DEFINE_EVENT(regmap_async, regmap_async_complete_start, + + TP_PROTO(struct device *dev), + + TP_ARGS(dev) + +); + +DEFINE_EVENT(regmap_async, regmap_async_complete_done, + + TP_PROTO(struct device *dev), + + TP_ARGS(dev) + +); + #endif /* _TRACE_REGMAP_H */ /* This part must be outside protection */ -- cgit From 66baf407571662f7e2a22dd0764cbe279559446c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Feb 2013 18:01:54 +0000 Subject: regmap: rbtree: Don't bother checking for noop updates If we're updating a value in place it's more work to read the value and compare the value with what we're about to set than it is to just write the value into the cache; there are no further operations after writing in the code even though there's an early return here. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache-rbtree.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index e6732cf7c06e..3f21c6ab296f 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -302,7 +302,6 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, struct regcache_rbtree_ctx *rbtree_ctx; struct regcache_rbtree_node *rbnode, *rbnode_tmp; struct rb_node *node; - unsigned int val; unsigned int reg_tmp; unsigned int pos; int i; @@ -315,10 +314,6 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, rbnode = regcache_rbtree_lookup(map, reg); if (rbnode) { reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; - val = regcache_rbtree_get_register(rbnode, reg_tmp, - map->cache_word_size); - if (val == value) - return 0; regcache_rbtree_set_register(rbnode, reg_tmp, value, map->cache_word_size); } else { -- cgit From 879082c9fe6e8fbddf787170eee605e4be138d0f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Feb 2013 18:03:13 +0000 Subject: regmap: cache: Pass the map rather than the word size when updating values It's more idiomatic to pass the map structure around and this means we can use other bits of information from the map. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 8 +++--- drivers/base/regmap/regcache-lzo.c | 6 ++--- drivers/base/regmap/regcache-rbtree.c | 51 +++++++++++++++++------------------ drivers/base/regmap/regcache.c | 18 ++++++------- 4 files changed, 39 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 5a22bd33ce3d..582d7fdf414b 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -188,10 +188,10 @@ int regcache_write(struct regmap *map, unsigned int reg, unsigned int value); int regcache_sync(struct regmap *map); -unsigned int regcache_get_val(const void *base, unsigned int idx, - unsigned int word_size); -bool regcache_set_val(void *base, unsigned int idx, - unsigned int val, unsigned int word_size); +unsigned int regcache_get_val(struct regmap *map, const void *base, + unsigned int idx); +bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, + unsigned int val); int regcache_lookup_reg(struct regmap *map, unsigned int reg); void regmap_async_complete_cb(struct regmap_async *async, int ret); diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index afd6aa91a0df..e210a6d1406a 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c @@ -260,8 +260,7 @@ static int regcache_lzo_read(struct regmap *map, ret = regcache_lzo_decompress_cache_block(map, lzo_block); if (ret >= 0) /* fetch the value from the cache */ - *value = regcache_get_val(lzo_block->dst, blkpos, - map->cache_word_size); + *value = regcache_get_val(map, lzo_block->dst, blkpos); kfree(lzo_block->dst); /* restore the pointer and length of the compressed block */ @@ -304,8 +303,7 @@ static int regcache_lzo_write(struct regmap *map, } /* write the new value to the cache */ - if (regcache_set_val(lzo_block->dst, blkpos, value, - map->cache_word_size)) { + if (regcache_set_val(map, lzo_block->dst, blkpos, value)) { kfree(lzo_block->dst); goto out; } diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 3f21c6ab296f..461cff888bb1 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -47,22 +47,21 @@ static inline void regcache_rbtree_get_base_top_reg( *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride); } -static unsigned int regcache_rbtree_get_register( - struct regcache_rbtree_node *rbnode, unsigned int idx, - unsigned int word_size) +static unsigned int regcache_rbtree_get_register(struct regmap *map, + struct regcache_rbtree_node *rbnode, unsigned int idx) { - return regcache_get_val(rbnode->block, idx, word_size); + return regcache_get_val(map, rbnode->block, idx); } -static void regcache_rbtree_set_register(struct regcache_rbtree_node *rbnode, - unsigned int idx, unsigned int val, - unsigned int word_size) +static void regcache_rbtree_set_register(struct regmap *map, + struct regcache_rbtree_node *rbnode, + unsigned int idx, unsigned int val) { - regcache_set_val(rbnode->block, idx, val, word_size); + regcache_set_val(map, rbnode->block, idx, val); } static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, - unsigned int reg) + unsigned int reg) { struct regcache_rbtree_ctx *rbtree_ctx = map->cache; struct rb_node *node; @@ -260,8 +259,7 @@ static int regcache_rbtree_read(struct regmap *map, rbnode = regcache_rbtree_lookup(map, reg); if (rbnode) { reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; - *value = regcache_rbtree_get_register(rbnode, reg_tmp, - map->cache_word_size); + *value = regcache_rbtree_get_register(map, rbnode, reg_tmp); } else { return -ENOENT; } @@ -270,21 +268,23 @@ static int regcache_rbtree_read(struct regmap *map, } -static int regcache_rbtree_insert_to_block(struct regcache_rbtree_node *rbnode, +static int regcache_rbtree_insert_to_block(struct regmap *map, + struct regcache_rbtree_node *rbnode, unsigned int pos, unsigned int reg, - unsigned int value, unsigned int word_size) + unsigned int value) { u8 *blk; blk = krealloc(rbnode->block, - (rbnode->blklen + 1) * word_size, GFP_KERNEL); + (rbnode->blklen + 1) * map->cache_word_size, + GFP_KERNEL); if (!blk) return -ENOMEM; /* insert the register value in the correct place in the rbnode block */ - memmove(blk + (pos + 1) * word_size, - blk + pos * word_size, - (rbnode->blklen - pos) * word_size); + memmove(blk + (pos + 1) * map->cache_word_size, + blk + pos * map->cache_word_size, + (rbnode->blklen - pos) * map->cache_word_size); /* update the rbnode block, its size and the base register */ rbnode->block = blk; @@ -292,7 +292,7 @@ static int regcache_rbtree_insert_to_block(struct regcache_rbtree_node *rbnode, if (!pos) rbnode->base_reg = reg; - regcache_rbtree_set_register(rbnode, pos, value, word_size); + regcache_rbtree_set_register(map, rbnode, pos, value); return 0; } @@ -314,8 +314,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, rbnode = regcache_rbtree_lookup(map, reg); if (rbnode) { reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; - regcache_rbtree_set_register(rbnode, reg_tmp, value, - map->cache_word_size); + regcache_rbtree_set_register(map, rbnode, reg_tmp, value); } else { /* look for an adjacent register to the one we are about to add */ for (node = rb_first(&rbtree_ctx->root); node; @@ -332,9 +331,10 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, pos = i + 1; else pos = i; - ret = regcache_rbtree_insert_to_block(rbnode_tmp, pos, - reg, value, - map->cache_word_size); + ret = regcache_rbtree_insert_to_block(map, + rbnode_tmp, + pos, reg, + value); if (ret) return ret; rbtree_ctx->cached_rbnode = rbnode_tmp; @@ -357,7 +357,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, kfree(rbnode); return -ENOMEM; } - regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size); + regcache_rbtree_set_register(map, rbnode, 0, value); regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); rbtree_ctx->cached_rbnode = rbnode; } @@ -399,8 +399,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, for (i = base; i < end; i++) { regtmp = rbnode->base_reg + (i * map->reg_stride); - val = regcache_rbtree_get_register(rbnode, i, - map->cache_word_size); + val = regcache_rbtree_get_register(map, rbnode, i); /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, regtmp); diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index e69ff3e4742c..f0a3db6ff9c2 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -58,8 +58,7 @@ static int regcache_hw_init(struct regmap *map) /* calculate the size of reg_defaults */ for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { - val = regcache_get_val(map->reg_defaults_raw, - i, map->cache_word_size); + val = regcache_get_val(map, map->reg_defaults_raw, i); if (regmap_volatile(map, i * map->reg_stride)) continue; count++; @@ -75,8 +74,7 @@ static int regcache_hw_init(struct regmap *map) /* fill the reg_defaults */ map->num_reg_defaults = count; for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { - val = regcache_get_val(map->reg_defaults_raw, - i, map->cache_word_size); + val = regcache_get_val(map, map->reg_defaults_raw, i); if (regmap_volatile(map, i * map->reg_stride)) continue; map->reg_defaults[j].reg = i * map->reg_stride; @@ -417,10 +415,10 @@ void regcache_cache_bypass(struct regmap *map, bool enable) } EXPORT_SYMBOL_GPL(regcache_cache_bypass); -bool regcache_set_val(void *base, unsigned int idx, - unsigned int val, unsigned int word_size) +bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, + unsigned int val) { - switch (word_size) { + switch (map->cache_word_size) { case 1: { u8 *cache = base; if (cache[idx] == val) @@ -448,13 +446,13 @@ bool regcache_set_val(void *base, unsigned int idx, return false; } -unsigned int regcache_get_val(const void *base, unsigned int idx, - unsigned int word_size) +unsigned int regcache_get_val(struct regmap *map, const void *base, + unsigned int idx) { if (!base) return -EINVAL; - switch (word_size) { + switch (map->cache_word_size) { case 1: { const u8 *cache = base; return cache[idx]; -- cgit From 325acab447f775bc2258b3a37a780893c203ab6c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Feb 2013 18:07:01 +0000 Subject: regmap: cache: Use regcache_get_value() to check if we updated Factor things out a little. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index f0a3db6ff9c2..6948996d2498 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -418,25 +418,22 @@ EXPORT_SYMBOL_GPL(regcache_cache_bypass); bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, unsigned int val) { + if (regcache_get_val(map, base, idx) == val) + return true; + switch (map->cache_word_size) { case 1: { u8 *cache = base; - if (cache[idx] == val) - return true; cache[idx] = val; break; } case 2: { u16 *cache = base; - if (cache[idx] == val) - return true; cache[idx] = val; break; } case 4: { u32 *cache = base; - if (cache[idx] == val) - return true; cache[idx] = val; break; } -- cgit From 8a819ff8abac9ad49f120c84cce01878b3d235c2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Mar 2013 09:04:51 +0800 Subject: regmap: core: Split out in place value parsing Currently the value parsing operations both return the parsed value and modify the passed buffer. This precludes their use in places like the cache code so split out the in place modification into a new parse_inplace() operation. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 3 ++- drivers/base/regmap/regmap.c | 52 +++++++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 582d7fdf414b..2b5851d42dbb 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -38,7 +38,8 @@ struct regmap_format { unsigned int reg, unsigned int val); void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); void (*format_val)(void *buf, unsigned int val, unsigned int shift); - unsigned int (*parse_val)(void *buf); + unsigned int (*parse_val)(const void *buf); + void (*parse_inplace)(void *buf); }; struct regmap_async { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..aff5a8b73947 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -228,30 +228,39 @@ static void regmap_format_32_native(void *buf, unsigned int val, *(u32 *)buf = val << shift; } -static unsigned int regmap_parse_8(void *buf) +static void regmap_parse_inplace_noop(void *buf) { - u8 *b = buf; +} + +static unsigned int regmap_parse_8(const void *buf) +{ + const u8 *b = buf; return b[0]; } -static unsigned int regmap_parse_16_be(void *buf) +static unsigned int regmap_parse_16_be(const void *buf) +{ + const __be16 *b = buf; + + return be16_to_cpu(b[0]); +} + +static void regmap_parse_16_be_inplace(void *buf) { __be16 *b = buf; b[0] = be16_to_cpu(b[0]); - - return b[0]; } -static unsigned int regmap_parse_16_native(void *buf) +static unsigned int regmap_parse_16_native(const void *buf) { return *(u16 *)buf; } -static unsigned int regmap_parse_24(void *buf) +static unsigned int regmap_parse_24(const void *buf) { - u8 *b = buf; + const u8 *b = buf; unsigned int ret = b[2]; ret |= ((unsigned int)b[1]) << 8; ret |= ((unsigned int)b[0]) << 16; @@ -259,16 +268,21 @@ static unsigned int regmap_parse_24(void *buf) return ret; } -static unsigned int regmap_parse_32_be(void *buf) +static unsigned int regmap_parse_32_be(const void *buf) +{ + const __be32 *b = buf; + + return be32_to_cpu(b[0]); +} + +static void regmap_parse_32_be_inplace(void *buf) { __be32 *b = buf; b[0] = be32_to_cpu(b[0]); - - return b[0]; } -static unsigned int regmap_parse_32_native(void *buf) +static unsigned int regmap_parse_32_native(const void *buf) { return *(u32 *)buf; } @@ -555,16 +569,21 @@ struct regmap *regmap_init(struct device *dev, goto err_map; } + if (val_endian == REGMAP_ENDIAN_NATIVE) + map->format.parse_inplace = regmap_parse_inplace_noop; + switch (config->val_bits) { case 8: map->format.format_val = regmap_format_8; map->format.parse_val = regmap_parse_8; + map->format.parse_inplace = regmap_parse_inplace_noop; break; case 16: switch (val_endian) { case REGMAP_ENDIAN_BIG: map->format.format_val = regmap_format_16_be; map->format.parse_val = regmap_parse_16_be; + map->format.parse_inplace = regmap_parse_16_be_inplace; break; case REGMAP_ENDIAN_NATIVE: map->format.format_val = regmap_format_16_native; @@ -585,6 +604,7 @@ struct regmap *regmap_init(struct device *dev, case REGMAP_ENDIAN_BIG: map->format.format_val = regmap_format_32_be; map->format.parse_val = regmap_parse_32_be; + map->format.parse_inplace = regmap_parse_32_be_inplace; break; case REGMAP_ENDIAN_NATIVE: map->format.format_val = regmap_format_32_native; @@ -1240,7 +1260,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, if (!map->bus) return -EINVAL; - if (!map->format.parse_val) + if (!map->format.parse_inplace) return -EINVAL; if (reg % map->reg_stride) return -EINVAL; @@ -1258,7 +1278,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, goto out; } for (i = 0; i < val_count * val_bytes; i += val_bytes) - map->format.parse_val(wval + i); + map->format.parse_inplace(wval + i); } /* * Some devices does not support bulk write, for @@ -1519,7 +1539,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, if (!map->bus) return -EINVAL; - if (!map->format.parse_val) + if (!map->format.parse_inplace) return -EINVAL; if (reg % map->reg_stride) return -EINVAL; @@ -1546,7 +1566,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, } for (i = 0; i < val_count * val_bytes; i += val_bytes) - map->format.parse_val(val + i); + map->format.parse_inplace(val + i); } else { for (i = 0; i < val_count; i++) { unsigned int ival; -- cgit From eb4cb76ff00e27858e5c80f69dbe8cc15364578c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 21 Feb 2013 18:39:47 +0000 Subject: regmap: cache: Store caches in native register format where possible This allows the cached data to be sent directly to the device when we sync it. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 6948996d2498..0f4fb8bc37e5 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -45,8 +45,8 @@ static int regcache_hw_init(struct regmap *map) tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); if (!tmp_buf) return -EINVAL; - ret = regmap_bulk_read(map, 0, tmp_buf, - map->num_reg_defaults_raw); + ret = regmap_raw_read(map, 0, tmp_buf, + map->num_reg_defaults_raw); map->cache_bypass = cache_bypass; if (ret < 0) { kfree(tmp_buf); @@ -421,6 +421,13 @@ bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, if (regcache_get_val(map, base, idx) == val) return true; + /* Use device native format if possible */ + if (map->format.format_val) { + map->format.format_val(base + (map->cache_word_size * idx), + val, 0); + return false; + } + switch (map->cache_word_size) { case 1: { u8 *cache = base; @@ -449,6 +456,11 @@ unsigned int regcache_get_val(struct regmap *map, const void *base, if (!base) return -EINVAL; + /* Use device native format if possible */ + if (map->format.parse_val) + return map->format.parse_val(base + + (map->cache_word_size * idx)); + switch (map->cache_word_size) { case 1: { const u8 *cache = base; -- cgit From 480738de0e076d759a973be623fac195cb901b82 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 20 Feb 2013 12:15:22 +0000 Subject: regmap: debugfs: Simplify calculation of `c->max_reg' We don't need to use any of the file position information to calculate the base and max register of each block. Just use the counter directly. Set `i = base' at the top to avoid GCC flow analysis bugs. The value of `i' can never be undefined or 0 in the if (c) { ... }. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-debugfs.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 81d6f605c92e..886b2f7682c2 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -88,16 +88,15 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, * If we don't have a cache build one so we don't have to do a * linear scan each time. */ + i = base; if (list_empty(&map->debugfs_off_cache)) { - for (i = base; i <= map->max_register; i += map->reg_stride) { + for (; i <= map->max_register; i += map->reg_stride) { /* Skip unprinted registers, closing off cache entry */ if (!regmap_readable(map, i) || regmap_precious(map, i)) { if (c) { c->max = p - 1; - fpos_offset = c->max - c->min; - reg_offset = fpos_offset / map->debugfs_tot_len; - c->max_reg = c->base_reg + reg_offset; + c->max_reg = i - map->reg_stride; list_add_tail(&c->list, &map->debugfs_off_cache); c = NULL; @@ -124,9 +123,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, /* Close the last entry off if we didn't scan beyond it */ if (c) { c->max = p - 1; - fpos_offset = c->max - c->min; - reg_offset = fpos_offset / map->debugfs_tot_len; - c->max_reg = c->base_reg + reg_offset; + c->max_reg = i - map->reg_stride; list_add_tail(&c->list, &map->debugfs_off_cache); } -- cgit From 065b4c587557dcd3dc8d3ff1ba2b9ecc6e0c6668 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 20 Feb 2013 12:15:23 +0000 Subject: regmap: debugfs: Add a registers `range' file This file lists the register ranges in the register map. The condition to split the range is based on whether the block is readable or not. Ensure that we lock the `debugfs_off_cache' list whenever we access and modify the list. There is a possible race otherwise between the read() operations of the `registers' file and the `range' file. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 1 + drivers/base/regmap/regmap-debugfs.c | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 5a22bd33ce3d..dc23508745fe 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -76,6 +76,7 @@ struct regmap { unsigned int debugfs_tot_len; struct list_head debugfs_off_cache; + struct mutex cache_lock; #endif unsigned int max_register; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 886b2f7682c2..23b701f5fd2f 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -88,6 +88,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, * If we don't have a cache build one so we don't have to do a * linear scan each time. */ + mutex_lock(&map->cache_lock); i = base; if (list_empty(&map->debugfs_off_cache)) { for (; i <= map->max_register; i += map->reg_stride) { @@ -110,6 +111,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) { regmap_debugfs_free_dump_cache(map); + mutex_unlock(&map->cache_lock); return base; } c->min = p; @@ -142,12 +144,14 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, fpos_offset = from - c->min; reg_offset = fpos_offset / map->debugfs_tot_len; *pos = c->min + (reg_offset * map->debugfs_tot_len); + mutex_unlock(&map->cache_lock); return c->base_reg + reg_offset; } *pos = c->max; ret = c->max_reg; } + mutex_unlock(&map->cache_lock); return ret; } @@ -308,6 +312,79 @@ static const struct file_operations regmap_range_fops = { .llseek = default_llseek, }; +static ssize_t regmap_reg_ranges_read_file(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct regmap *map = file->private_data; + struct regmap_debugfs_off_cache *c; + loff_t p = 0; + size_t buf_pos = 0; + char *buf; + char *entry; + int ret; + + if (*ppos < 0 || !count) + return -EINVAL; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + entry = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!entry) { + kfree(buf); + return -ENOMEM; + } + + /* While we are at it, build the register dump cache + * now so the read() operation on the `registers' file + * can benefit from using the cache. We do not care + * about the file position information that is contained + * in the cache, just about the actual register blocks */ + regmap_calc_tot_len(map, buf, count); + regmap_debugfs_get_dump_start(map, 0, *ppos, &p); + + /* Reset file pointer as the fixed-format of the `registers' + * file is not compatible with the `range' file */ + p = 0; + mutex_lock(&map->cache_lock); + list_for_each_entry(c, &map->debugfs_off_cache, list) { + snprintf(entry, PAGE_SIZE, "%x-%x", + c->base_reg, c->max_reg); + if (p >= *ppos) { + if (buf_pos + 1 + strlen(entry) > count) + break; + snprintf(buf + buf_pos, count - buf_pos, + "%s", entry); + buf_pos += strlen(entry); + buf[buf_pos] = '\n'; + buf_pos++; + } + p += strlen(entry) + 1; + } + mutex_unlock(&map->cache_lock); + + kfree(entry); + ret = buf_pos; + + if (copy_to_user(user_buf, buf, buf_pos)) { + ret = -EFAULT; + goto out_buf; + } + + *ppos += buf_pos; +out_buf: + kfree(buf); + return ret; +} + +static const struct file_operations regmap_reg_ranges_fops = { + .open = simple_open, + .read = regmap_reg_ranges_read_file, + .llseek = default_llseek, +}; + static ssize_t regmap_access_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -382,6 +459,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name) struct regmap_range_node *range_node; INIT_LIST_HEAD(&map->debugfs_off_cache); + mutex_init(&map->cache_lock); if (name) { map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", @@ -400,6 +478,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name) debugfs_create_file("name", 0400, map->debugfs, map, ®map_name_fops); + debugfs_create_file("range", 0400, map->debugfs, + map, ®map_reg_ranges_fops); + if (map->max_register) { debugfs_create_file("registers", 0400, map->debugfs, map, ®map_map_fops); @@ -432,7 +513,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name) void regmap_debugfs_exit(struct regmap *map) { debugfs_remove_recursive(map->debugfs); + mutex_lock(&map->cache_lock); regmap_debugfs_free_dump_cache(map); + mutex_unlock(&map->cache_lock); kfree(map->debugfs_name); } -- cgit From f19b00da8ed37db4e3891fe534fcf3a605a0e562 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 18 Feb 2013 06:50:39 +0000 Subject: regulator: core: support shared enable GPIO concept A Regulator can be enabled by external GPIO pin. This is configurable in the regulator_config. At this moment, the GPIO can be owned by only one regulator device. In some devices, multiple regulators are enabled by shared one GPIO pin. This patch extends this limitation, enabling shared enable GPIO of regulators. New list for enable GPIO: 'regulator_ena_gpio_list' This manages enable GPIO list. New structure for supporting shared enable GPIO: 'regulator_enable_gpio' The enable count is used for balancing GPIO control count. This count is incremented when GPIO is enabled. On the other hand, it's decremented when GPIO is disabled. Reference count: 'request_count' The reference count, 'request_count' is incremented/decremented on requesting/freeing the GPIO. This count makes sure only free the GPIO when it has no users. How it works If the GPIO is already used, skip requesting new GPIO usage. The GPIO is new one, request GPIO function and add it to the list of enable GPIO. This list is used for balancing enable GPIO count and pin control. Updating a GPIO and invert code moved 'ena_gpio' and 'ena_gpio_invert' of the regulator_config were moved to new function, regulator_ena_gpio_request(). Use regulator_enable_pin structure rather than regulator_dev. Signed-off-by: Milo(Woogyom) Kim Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 86 +++++++++++++++++++++++++++++++++++----- include/linux/regulator/driver.h | 2 + 2 files changed, 78 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index da9782bd27d0..71d6adc4eeab 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -51,6 +51,7 @@ static DEFINE_MUTEX(regulator_list_mutex); static LIST_HEAD(regulator_list); static LIST_HEAD(regulator_map_list); +static LIST_HEAD(regulator_ena_gpio_list); static bool has_full_constraints; static bool board_wants_dummy_regulator; @@ -68,6 +69,19 @@ struct regulator_map { struct regulator_dev *regulator; }; +/* + * struct regulator_enable_gpio + * + * Management for shared enable GPIO pin + */ +struct regulator_enable_gpio { + struct list_head list; + int gpio; + u32 enable_count; /* a number of enabled shared GPIO */ + u32 request_count; /* a number of requested shared GPIO */ + unsigned int ena_gpio_invert:1; +}; + /* * struct regulator * @@ -1456,6 +1470,65 @@ void devm_regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(devm_regulator_put); +/* Manage enable GPIO list. Same GPIO pin can be shared among regulators */ +static int regulator_ena_gpio_request(struct regulator_dev *rdev, + const struct regulator_config *config) +{ + struct regulator_enable_gpio *pin; + int ret; + + list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { + if (pin->gpio == config->ena_gpio) { + rdev_dbg(rdev, "GPIO %d is already used\n", + config->ena_gpio); + goto update_ena_gpio_to_rdev; + } + } + + ret = gpio_request_one(config->ena_gpio, + GPIOF_DIR_OUT | config->ena_gpio_flags, + rdev_get_name(rdev)); + if (ret) + return ret; + + pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); + if (pin == NULL) { + gpio_free(config->ena_gpio); + return -ENOMEM; + } + + pin->gpio = config->ena_gpio; + pin->ena_gpio_invert = config->ena_gpio_invert; + list_add(&pin->list, ®ulator_ena_gpio_list); + +update_ena_gpio_to_rdev: + pin->request_count++; + rdev->ena_pin = pin; + return 0; +} + +static void regulator_ena_gpio_free(struct regulator_dev *rdev) +{ + struct regulator_enable_gpio *pin, *n; + + if (!rdev->ena_pin) + return; + + /* Free the GPIO only in case of no use */ + list_for_each_entry_safe(pin, n, ®ulator_ena_gpio_list, list) { + if (pin->gpio == rdev->ena_pin->gpio) { + if (pin->request_count <= 1) { + pin->request_count = 0; + gpio_free(pin->gpio); + list_del(&pin->list); + kfree(pin); + } else { + pin->request_count--; + } + } + } +} + static int _regulator_do_enable(struct regulator_dev *rdev) { int ret, delay; @@ -3435,18 +3508,13 @@ regulator_register(const struct regulator_desc *regulator_desc, dev_set_drvdata(&rdev->dev, rdev); if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { - ret = gpio_request_one(config->ena_gpio, - GPIOF_DIR_OUT | config->ena_gpio_flags, - rdev_get_name(rdev)); + ret = regulator_ena_gpio_request(rdev, config); if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", config->ena_gpio, ret); goto wash; } - rdev->ena_gpio = config->ena_gpio; - rdev->ena_gpio_invert = config->ena_gpio_invert; - if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) rdev->ena_gpio_state = 1; @@ -3522,8 +3590,7 @@ unset_supplies: scrub: if (rdev->supply) _regulator_put(rdev->supply); - if (rdev->ena_gpio) - gpio_free(rdev->ena_gpio); + regulator_ena_gpio_free(rdev); kfree(rdev->constraints); wash: device_unregister(&rdev->dev); @@ -3558,8 +3625,7 @@ void regulator_unregister(struct regulator_dev *rdev) unset_regulator_supplies(rdev); list_del(&rdev->list); kfree(rdev->constraints); - if (rdev->ena_gpio) - gpio_free(rdev->ena_gpio); + regulator_ena_gpio_free(rdev); device_unregister(&rdev->dev); mutex_unlock(®ulator_list_mutex); } diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 23070fd83872..a467d11dd67d 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -22,6 +22,7 @@ struct regmap; struct regulator_dev; struct regulator_init_data; +struct regulator_enable_gpio; enum regulator_status { REGULATOR_STATUS_OFF, @@ -300,6 +301,7 @@ struct regulator_dev { struct dentry *debugfs; + struct regulator_enable_gpio *ena_pin; int ena_gpio; unsigned int ena_gpio_invert:1; unsigned int ena_gpio_state:1; -- cgit From 967cfb18c0e331b43a29ae7f60ec1ef0dcb02f6b Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 18 Feb 2013 06:50:48 +0000 Subject: regulator: core: manage enable GPIO list To support shared enable GPIO pin, replace GPIO code with new static functions Reference count: 'enable_count' Balance the reference count of each GPIO and actual pin control. The count is incremented with enabling GPIO. On the other hand, it is decremented on disabling GPIO. Actual GPIO pin is enabled at the initial use.(enable_count = 0) The pin is disabled if it is not used(shared) any more. (enable_count <=1) Regardless of the enable count, update GPIO state of the regulator. Signed-off-by: Milo(Woogyom) Kim Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 71d6adc4eeab..57d434d3145a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1529,6 +1529,42 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) } } +/** + * Balance enable_count of each GPIO and actual GPIO pin control. + * GPIO is enabled in case of initial use. (enable_count is 0) + * GPIO is disabled when it is not shared any more. (enable_count <= 1) + */ +static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) +{ + struct regulator_enable_gpio *pin = rdev->ena_pin; + + if (!pin) + return -EINVAL; + + if (enable) { + /* Enable GPIO at initial use */ + if (pin->enable_count == 0) + gpio_set_value_cansleep(pin->gpio, + !pin->ena_gpio_invert); + + pin->enable_count++; + } else { + if (pin->enable_count > 1) { + pin->enable_count--; + return 0; + } + + /* Disable GPIO if not used */ + if (pin->enable_count <= 1) { + gpio_set_value_cansleep(pin->gpio, + pin->ena_gpio_invert); + pin->enable_count = 0; + } + } + + return 0; +} + static int _regulator_do_enable(struct regulator_dev *rdev) { int ret, delay; @@ -1544,9 +1580,10 @@ static int _regulator_do_enable(struct regulator_dev *rdev) trace_regulator_enable(rdev_get_name(rdev)); - if (rdev->ena_gpio) { - gpio_set_value_cansleep(rdev->ena_gpio, - !rdev->ena_gpio_invert); + if (rdev->ena_pin) { + ret = regulator_ena_gpio_ctrl(rdev, true); + if (ret < 0) + return ret; rdev->ena_gpio_state = 1; } else if (rdev->desc->ops->enable) { ret = rdev->desc->ops->enable(rdev); @@ -1648,9 +1685,10 @@ static int _regulator_do_disable(struct regulator_dev *rdev) trace_regulator_disable(rdev_get_name(rdev)); - if (rdev->ena_gpio) { - gpio_set_value_cansleep(rdev->ena_gpio, - rdev->ena_gpio_invert); + if (rdev->ena_pin) { + ret = regulator_ena_gpio_ctrl(rdev, false); + if (ret < 0) + return ret; rdev->ena_gpio_state = 0; } else if (rdev->desc->ops->disable) { -- cgit From 7b74d149247c8972da1cec3e4c70b67049aaeb69 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 18 Feb 2013 06:50:55 +0000 Subject: regulator: core: use regulator_ena_pin member The regulator_dev has regulator_enable_gpio structure. 'ena_gpio' and 'ena_gpio_invert' were moved to in regulator_enable_gpio. regulator_dev ---> regulator_enable_gpio .ena_gpio .gpio .ena_gpio_invert .ena_gpio_invert Pointer, 'ena_pin' is used for checking valid enable GPIO pin. Signed-off-by: Milo(Woogyom) Kim Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 6 +++--- include/linux/regulator/driver.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 57d434d3145a..6c8c82406cd9 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1945,7 +1945,7 @@ EXPORT_SYMBOL_GPL(regulator_disable_regmap); static int _regulator_is_enabled(struct regulator_dev *rdev) { /* A GPIO control always takes precedence */ - if (rdev->ena_gpio) + if (rdev->ena_pin) return rdev->ena_gpio_state; /* If we don't know then assume that the regulator is always on */ @@ -3344,7 +3344,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev) if (status < 0) return status; } - if (rdev->ena_gpio || ops->is_enabled) { + if (rdev->ena_pin || ops->is_enabled) { status = device_create_file(dev, &dev_attr_state); if (status < 0) return status; @@ -3556,7 +3556,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) rdev->ena_gpio_state = 1; - if (rdev->ena_gpio_invert) + if (config->ena_gpio_invert) rdev->ena_gpio_state = !rdev->ena_gpio_state; } diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index a467d11dd67d..7b7aeec04f86 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -302,8 +302,6 @@ struct regulator_dev { struct dentry *debugfs; struct regulator_enable_gpio *ena_pin; - int ena_gpio; - unsigned int ena_gpio_invert:1; unsigned int ena_gpio_state:1; }; -- cgit From 407945fd78c3fddef83ba17bf2250112c07dc7c1 Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Mon, 18 Feb 2013 06:51:02 +0000 Subject: regulator: lp8788-ldo: use ena_pin of regulator-core for external control Regulator core driver provides enable GPIO control for enabling/disabling a regulator. Now, enable GPIO is shared among regulators. Use this internal working, so unnecessary code are removed. GPIO enable pin configurations are added in digital LDO and analog LDO drivers. Signed-off-by: Milo(Woogyom) Kim Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/lp8788-ldo.c | 98 ++++++++---------------------------------- 1 file changed, 17 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index cd5a14ad9263..fcba90a4c26c 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -184,40 +184,6 @@ static enum lp8788_ldo_id lp8788_aldo_id[] = { ALDO10, }; -static int lp8788_ldo_enable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - - if (ldo->en_pin) { - gpio_set_value(ldo->en_pin->gpio, ENABLE); - return 0; - } else { - return regulator_enable_regmap(rdev); - } -} - -static int lp8788_ldo_disable(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - - if (ldo->en_pin) { - gpio_set_value(ldo->en_pin->gpio, DISABLE); - return 0; - } else { - return regulator_disable_regmap(rdev); - } -} - -static int lp8788_ldo_is_enabled(struct regulator_dev *rdev) -{ - struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); - - if (ldo->en_pin) - return gpio_get_value(ldo->en_pin->gpio) ? 1 : 0; - else - return regulator_is_enabled_regmap(rdev); -} - static int lp8788_ldo_enable_time(struct regulator_dev *rdev) { struct lp8788_ldo *ldo = rdev_get_drvdata(rdev); @@ -253,17 +219,17 @@ static struct regulator_ops lp8788_ldo_voltage_table_ops = { .list_voltage = regulator_list_voltage_table, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .enable_time = lp8788_ldo_enable_time, }; static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { .get_voltage = lp8788_ldo_fixed_get_voltage, - .enable = lp8788_ldo_enable, - .disable = lp8788_ldo_disable, - .is_enabled = lp8788_ldo_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .enable_time = lp8788_ldo_enable_time, }; @@ -535,43 +501,10 @@ static struct regulator_desc lp8788_aldo_desc[] = { }, }; -static int lp8788_gpio_request_ldo_en(struct platform_device *pdev, - struct lp8788_ldo *ldo, - enum lp8788_ext_ldo_en_id id) -{ - struct device *dev = &pdev->dev; - struct lp8788_ldo_enable_pin *pin = ldo->en_pin; - int ret, gpio, pinstate; - char *name[] = { - [EN_ALDO1] = "LP8788_EN_ALDO1", - [EN_ALDO234] = "LP8788_EN_ALDO234", - [EN_ALDO5] = "LP8788_EN_ALDO5", - [EN_ALDO7] = "LP8788_EN_ALDO7", - [EN_DLDO7] = "LP8788_EN_DLDO7", - [EN_DLDO911] = "LP8788_EN_DLDO911", - }; - - gpio = pin->gpio; - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio: %d\n", gpio); - return -EINVAL; - } - - pinstate = pin->init_state; - ret = devm_gpio_request_one(dev, gpio, pinstate, name[id]); - if (ret == -EBUSY) { - dev_warn(dev, "gpio%d already used\n", gpio); - return 0; - } - - return ret; -} - static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, struct lp8788_ldo *ldo, enum lp8788_ldo_id id) { - int ret; struct lp8788 *lp = ldo->lp; struct lp8788_platform_data *pdata = lp->pdata; enum lp8788_ext_ldo_en_id enable_id; @@ -613,14 +546,7 @@ static int lp8788_config_ldo_enable_mode(struct platform_device *pdev, goto set_default_ldo_enable_mode; ldo->en_pin = pdata->ldo_pin[enable_id]; - - ret = lp8788_gpio_request_ldo_en(pdev, ldo, enable_id); - if (ret) { - ldo->en_pin = NULL; - goto set_default_ldo_enable_mode; - } - - return ret; + return 0; set_default_ldo_enable_mode: return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0); @@ -644,6 +570,11 @@ static int lp8788_dldo_probe(struct platform_device *pdev) if (ret) return ret; + if (ldo->en_pin) { + cfg.ena_gpio = ldo->en_pin->gpio; + cfg.ena_gpio_flags = ldo->en_pin->init_state; + } + cfg.dev = pdev->dev.parent; cfg.init_data = lp->pdata ? lp->pdata->dldo_data[id] : NULL; cfg.driver_data = ldo; @@ -700,6 +631,11 @@ static int lp8788_aldo_probe(struct platform_device *pdev) if (ret) return ret; + if (ldo->en_pin) { + cfg.ena_gpio = ldo->en_pin->gpio; + cfg.ena_gpio_flags = ldo->en_pin->init_state; + } + cfg.dev = pdev->dev.parent; cfg.init_data = lp->pdata ? lp->pdata->aldo_data[id] : NULL; cfg.driver_data = ldo; -- cgit From ad4928f1dc695ea822c4daaafa5e3b2db7b17964 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 15 Feb 2013 20:36:06 +0800 Subject: regulator: max8925: Remove unused parameter from max8925_regulator_dt_init The info parameter is not used at all, remove it. Signed-off-by: Axel Lin Acked-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/max8925-regulator.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 0d5f64a805a0..3597da8f0dca 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -246,7 +246,6 @@ static struct max8925_regulator_info max8925_regulator_info[] = { #ifdef CONFIG_OF static int max8925_regulator_dt_init(struct platform_device *pdev, - struct max8925_regulator_info *info, struct regulator_config *config, int ridx) { @@ -272,7 +271,7 @@ static int max8925_regulator_dt_init(struct platform_device *pdev, return 0; } #else -#define max8925_regulator_dt_init(w, x, y, z) (-1) +#define max8925_regulator_dt_init(x, y, z) (-1) #endif static int max8925_regulator_probe(struct platform_device *pdev) @@ -309,7 +308,7 @@ static int max8925_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.driver_data = ri; - if (max8925_regulator_dt_init(pdev, ri, &config, regulator_idx)) + if (max8925_regulator_dt_init(pdev, &config, regulator_idx)) if (pdata) config.init_data = pdata; -- cgit From 9df19a5597f70e8fd15c065035f5b6362fec91a5 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Sat, 23 Feb 2013 00:52:35 -0300 Subject: regulators: max8998.c: use dev_err() instead of printk() Fixes the following checkpatch warning: WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: Thiago Farina Signed-off-by: Mark Brown --- drivers/regulator/max8998.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index b588f07c7cad..a57a1b15cdba 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -665,14 +665,16 @@ static int max8998_pmic_probe(struct platform_device *pdev) gpio_is_valid(pdata->buck1_set2)) { /* Check if SET1 is not equal to 0 */ if (!pdata->buck1_set1) { - printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); + dev_err(&pdev->dev, + "MAX8998 SET1 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set1); ret = -EIO; goto err_out; } /* Check if SET2 is not equal to 0 */ if (!pdata->buck1_set2) { - printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); + dev_err(&pdev->dev, + "MAX8998 SET2 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set2); ret = -EIO; goto err_out; @@ -738,7 +740,8 @@ static int max8998_pmic_probe(struct platform_device *pdev) if (gpio_is_valid(pdata->buck2_set3)) { /* Check if SET3 is not equal to 0 */ if (!pdata->buck2_set3) { - printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); + dev_err(&pdev->dev, + "MAX8998 SET3 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck2_set3); ret = -EIO; goto err_out; -- cgit From 3c870e3f9d9d98f1ab98614b3b1fd5c79287d361 Mon Sep 17 00:00:00 2001 From: J Keerthy Date: Mon, 18 Feb 2013 10:44:20 +0530 Subject: regulator: palmas: Change the DT node property names to follow the convention DT node properties should not have "_". Replacing them by "-". Signed-off-by: J Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index cde13bb5a8fb..4f86f6cab620 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -553,17 +553,17 @@ static void palmas_dt_to_pdata(struct device *dev, sizeof(struct palmas_reg_init), GFP_KERNEL); ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,warm_reset", &prop); + "ti,warm-reset", &prop); if (!ret) pdata->reg_init[idx]->warm_reset = prop; ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,roof_floor", &prop); + "ti,roof-floor", &prop); if (!ret) pdata->reg_init[idx]->roof_floor = prop; ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,mode_sleep", &prop); + "ti,mode-sleep", &prop); if (!ret) pdata->reg_init[idx]->mode_sleep = prop; @@ -578,7 +578,7 @@ static void palmas_dt_to_pdata(struct device *dev, pdata->reg_init[idx]->vsel = prop; } - ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop); + ret = of_property_read_u32(node, "ti,ldo6-vibrator", &prop); if (!ret) pdata->ldo6_vibrator = prop; } -- cgit From 720a9717bcdad6fbfa22cde082c47fb969a22f6f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 24 Feb 2013 12:55:34 +0100 Subject: regulator: s5m8767: adjust duplicate test Delete successive tests to the same location. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @s exists@ local idexpression y; expression x,e; @@ *if ( \(x == NULL\|IS_ERR(x)\|y != 0\) ) { ... when forall return ...; } ... when != \(y = e\|y += e\|y -= e\|y |= e\|y &= e\|y++\|y--\|&y\) *if ( \(x == NULL\|IS_ERR(x)\|y != 0\) ) { ... when forall return ...; } // Signed-off-by: Julia Lawall Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 8a831947c351..8e56198167e8 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -549,7 +549,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * pdata->num_regulators, GFP_KERNEL); - if (!rdata) { + if (!rmode) { dev_err(iodev->dev, "could not allocate memory for regulator mode\n"); return -ENOMEM; -- cgit From 0a4cccaa314de37e6130a31e2092778e87c793ae Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 25 Feb 2013 12:34:09 +0100 Subject: regulator: tps6586x: (cosmetic) simplify a conditional of_node_put() is called on either branch of a conditional, simplify the code by only calling it once. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index e68382d0e1ea..4e3e4adb1dce 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -304,14 +304,12 @@ static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( } err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num); + of_node_put(regs); if (err < 0) { dev_err(&pdev->dev, "Regulator match failed, e %d\n", err); - of_node_put(regs); return NULL; } - of_node_put(regs); - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&pdev->dev, "Memory alloction failed\n"); -- cgit From 6673d66e5a772763f0e1b3b229474f261be37506 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 20 Feb 2013 10:23:46 +0800 Subject: regulator: tps6586x: Use dev_err rather than dev_warn for error message tps6586x_regulator_set_slew_rate() returns -EINVAL when having slew rate settings for other than SM0/1, thus use dev_err rather than dev_warn. Signed-off-by: Axel Lin Reviewed-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 4e3e4adb1dce..b813d213255b 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -245,7 +245,7 @@ static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev, reg = TPS6586X_SM1SL; break; default: - dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n"); + dev_err(&pdev->dev, "Only SM0/SM1 can set slew rate\n"); return -EINVAL; } -- cgit From 7ad530bf2499c702a6dcbb279cf78b76845ed584 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:42:57 -0800 Subject: staging: sync: Add synchronization framework Sync is a framework for synchronization between multiple drivers. Sync implementations can take advantage of hardware synchronization built into devices like GPUs. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message, moved to staging, squished minor fix in] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 9 + drivers/staging/android/Makefile | 1 + drivers/staging/android/sync.c | 525 +++++++++++++++++++++++++++++++++++++++ drivers/staging/android/sync.h | 314 +++++++++++++++++++++++ 4 files changed, 849 insertions(+) create mode 100644 drivers/staging/android/sync.c create mode 100644 drivers/staging/android/sync.h (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 465a28c08f20..c95aedeff3f4 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -72,6 +72,15 @@ config ANDROID_INTF_ALARM_DEV elapsed realtime, and a non-wakeup alarm on the monotonic clock. Also exports the alarm interface to user-space. +config SYNC + bool "Synchronization framework" + default n + select ANON_INODES + help + This option enables the framework for synchronization between multiple + drivers. Sync implementations can take advantage of hardware + synchronization built into devices like GPUs. + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index b35a631734d6..22c656c82c3f 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o +obj-$(CONFIG_SYNC) += sync.o diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c new file mode 100644 index 000000000000..4a9e63df83e9 --- /dev/null +++ b/drivers/staging/android/sync.c @@ -0,0 +1,525 @@ +/* + * drivers/base/sync.c + * + * Copyright (C) 2012 Google, Inc. + * + * 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 "sync.h" + +static void sync_fence_signal_pt(struct sync_pt *pt); +static int _sync_pt_has_signaled(struct sync_pt *pt); + +struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, + int size, const char *name) +{ + struct sync_timeline *obj; + + if (size < sizeof(struct sync_timeline)) + return NULL; + + obj = kzalloc(size, GFP_KERNEL); + if (obj == NULL) + return NULL; + + obj->ops = ops; + strlcpy(obj->name, name, sizeof(obj->name)); + + INIT_LIST_HEAD(&obj->child_list_head); + spin_lock_init(&obj->child_list_lock); + + INIT_LIST_HEAD(&obj->active_list_head); + spin_lock_init(&obj->active_list_lock); + + return obj; +} + +void sync_timeline_destroy(struct sync_timeline *obj) +{ + unsigned long flags; + bool needs_freeing; + + spin_lock_irqsave(&obj->child_list_lock, flags); + obj->destroyed = true; + needs_freeing = list_empty(&obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); + + if (needs_freeing) + kfree(obj); + else + sync_timeline_signal(obj); +} + +static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt) +{ + unsigned long flags; + + pt->parent = obj; + + spin_lock_irqsave(&obj->child_list_lock, flags); + list_add_tail(&pt->child_list, &obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); +} + +static void sync_timeline_remove_pt(struct sync_pt *pt) +{ + struct sync_timeline *obj = pt->parent; + unsigned long flags; + bool needs_freeing; + + spin_lock_irqsave(&obj->active_list_lock, flags); + if (!list_empty(&pt->active_list)) + list_del_init(&pt->active_list); + spin_unlock_irqrestore(&obj->active_list_lock, flags); + + spin_lock_irqsave(&obj->child_list_lock, flags); + list_del(&pt->child_list); + needs_freeing = obj->destroyed && list_empty(&obj->child_list_head); + spin_unlock_irqrestore(&obj->child_list_lock, flags); + + if (needs_freeing) + kfree(obj); +} + +void sync_timeline_signal(struct sync_timeline *obj) +{ + unsigned long flags; + LIST_HEAD(signaled_pts); + struct list_head *pos, *n; + + spin_lock_irqsave(&obj->active_list_lock, flags); + + list_for_each_safe(pos, n, &obj->active_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, active_list); + + if (_sync_pt_has_signaled(pt)) + list_move(pos, &signaled_pts); + } + + spin_unlock_irqrestore(&obj->active_list_lock, flags); + + list_for_each_safe(pos, n, &signaled_pts) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, active_list); + + list_del_init(pos); + sync_fence_signal_pt(pt); + } +} + +struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) +{ + struct sync_pt *pt; + + if (size < sizeof(struct sync_pt)) + return NULL; + + pt = kzalloc(size, GFP_KERNEL); + if (pt == NULL) + return NULL; + + INIT_LIST_HEAD(&pt->active_list); + sync_timeline_add_pt(parent, pt); + + return pt; +} + +void sync_pt_free(struct sync_pt *pt) +{ + if (pt->parent->ops->free_pt) + pt->parent->ops->free_pt(pt); + + sync_timeline_remove_pt(pt); + + kfree(pt); +} + +/* call with pt->parent->active_list_lock held */ +static int _sync_pt_has_signaled(struct sync_pt *pt) +{ + if (!pt->status) + pt->status = pt->parent->ops->has_signaled(pt); + + if (!pt->status && pt->parent->destroyed) + pt->status = -ENOENT; + + return pt->status; +} + +static struct sync_pt *sync_pt_dup(struct sync_pt *pt) +{ + return pt->parent->ops->dup(pt); +} + +/* Adds a sync pt to the active queue. Called when added to a fence */ +static void sync_pt_activate(struct sync_pt *pt) +{ + struct sync_timeline *obj = pt->parent; + unsigned long flags; + int err; + + spin_lock_irqsave(&obj->active_list_lock, flags); + + err = _sync_pt_has_signaled(pt); + if (err != 0) + goto out; + + list_add_tail(&pt->active_list, &obj->active_list_head); + +out: + spin_unlock_irqrestore(&obj->active_list_lock, flags); +} + +static int sync_fence_release(struct inode *inode, struct file *file); +static long sync_fence_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + + +static const struct file_operations sync_fence_fops = { + .release = sync_fence_release, + .unlocked_ioctl = sync_fence_ioctl, +}; + +static struct sync_fence *sync_fence_alloc(const char *name) +{ + struct sync_fence *fence; + + fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL); + if (fence == NULL) + return NULL; + + fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, + fence, 0); + if (fence->file == NULL) + goto err; + + strlcpy(fence->name, name, sizeof(fence->name)); + + INIT_LIST_HEAD(&fence->pt_list_head); + INIT_LIST_HEAD(&fence->waiter_list_head); + spin_lock_init(&fence->waiter_list_lock); + + init_waitqueue_head(&fence->wq); + return fence; + +err: + kfree(fence); + return NULL; +} + +/* TODO: implement a create which takes more that one sync_pt */ +struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) +{ + struct sync_fence *fence; + + if (pt->fence) + return NULL; + + fence = sync_fence_alloc(name); + if (fence == NULL) + return NULL; + + pt->fence = fence; + list_add(&pt->pt_list, &fence->pt_list_head); + sync_pt_activate(pt); + + return fence; +} + +static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) +{ + struct list_head *pos; + + list_for_each(pos, &src->pt_list_head) { + struct sync_pt *orig_pt = + container_of(pos, struct sync_pt, pt_list); + struct sync_pt *new_pt = sync_pt_dup(orig_pt); + + if (new_pt == NULL) + return -ENOMEM; + + new_pt->fence = dst; + list_add(&new_pt->pt_list, &dst->pt_list_head); + sync_pt_activate(new_pt); + } + + return 0; +} + +static void sync_fence_free_pts(struct sync_fence *fence) +{ + struct list_head *pos, *n; + + list_for_each_safe(pos, n, &fence->pt_list_head) { + struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); + sync_pt_free(pt); + } +} + +struct sync_fence *sync_fence_fdget(int fd) +{ + struct file *file = fget(fd); + + if (file == NULL) + return NULL; + + if (file->f_op != &sync_fence_fops) + goto err; + + return file->private_data; + +err: + fput(file); + return NULL; +} + +void sync_fence_put(struct sync_fence *fence) +{ + fput(fence->file); +} + +void sync_fence_install(struct sync_fence *fence, int fd) +{ + fd_install(fd, fence->file); +} + +static int sync_fence_get_status(struct sync_fence *fence) +{ + struct list_head *pos; + int status = 1; + + list_for_each(pos, &fence->pt_list_head) { + struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); + int pt_status = pt->status; + + if (pt_status < 0) { + status = pt_status; + break; + } else if (status == 1) { + status = pt_status; + } + } + + return status; +} + +struct sync_fence *sync_fence_merge(const char *name, + struct sync_fence *a, struct sync_fence *b) +{ + struct sync_fence *fence; + int err; + + fence = sync_fence_alloc(name); + if (fence == NULL) + return NULL; + + err = sync_fence_copy_pts(fence, a); + if (err < 0) + goto err; + + err = sync_fence_copy_pts(fence, b); + if (err < 0) + goto err; + + fence->status = sync_fence_get_status(fence); + + return fence; +err: + sync_fence_free_pts(fence); + kfree(fence); + return NULL; +} + +static void sync_fence_signal_pt(struct sync_pt *pt) +{ + LIST_HEAD(signaled_waiters); + struct sync_fence *fence = pt->fence; + struct list_head *pos; + struct list_head *n; + unsigned long flags; + int status; + + status = sync_fence_get_status(fence); + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + /* + * this should protect against two threads racing on the signaled + * false -> true transition + */ + if (status && !fence->status) { + list_for_each_safe(pos, n, &fence->waiter_list_head) + list_move(pos, &signaled_waiters); + + fence->status = status; + } else { + status = 0; + } + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); + + if (status) { + list_for_each_safe(pos, n, &signaled_waiters) { + struct sync_fence_waiter *waiter = + container_of(pos, struct sync_fence_waiter, + waiter_list); + + waiter->callback(fence, waiter->callback_data); + list_del(pos); + kfree(waiter); + } + wake_up(&fence->wq); + } +} + +int sync_fence_wait_async(struct sync_fence *fence, + void (*callback)(struct sync_fence *, void *data), + void *callback_data) +{ + struct sync_fence_waiter *waiter; + unsigned long flags; + int err = 0; + + waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL); + if (waiter == NULL) + return -ENOMEM; + + waiter->callback = callback; + waiter->callback_data = callback_data; + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + + if (fence->status) { + kfree(waiter); + err = fence->status; + goto out; + } + + list_add_tail(&waiter->waiter_list, &fence->waiter_list_head); +out: + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); + + return err; +} + +int sync_fence_wait(struct sync_fence *fence, long timeout) +{ + int err; + + if (timeout) { + timeout = msecs_to_jiffies(timeout); + err = wait_event_interruptible_timeout(fence->wq, + fence->status != 0, + timeout); + } else { + err = wait_event_interruptible(fence->wq, fence->status != 0); + } + + if (err < 0) + return err; + + if (fence->status < 0) + return fence->status; + + if (fence->status == 0) + return -ETIME; + + return 0; +} + +static int sync_fence_release(struct inode *inode, struct file *file) +{ + struct sync_fence *fence = file->private_data; + + sync_fence_free_pts(fence); + kfree(fence); + + return 0; +} + +static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) +{ + __s32 value; + + if (copy_from_user(&value, (void __user *)arg, sizeof(value))) + return -EFAULT; + + return sync_fence_wait(fence, value); +} + +static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) +{ + int fd = get_unused_fd(); + int err; + struct sync_fence *fence2, *fence3; + struct sync_merge_data data; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) + return -EFAULT; + + fence2 = sync_fence_fdget(data.fd2); + if (fence2 == NULL) { + err = -ENOENT; + goto err_put_fd; + } + + data.name[sizeof(data.name) - 1] = '\0'; + fence3 = sync_fence_merge(data.name, fence, fence2); + if (fence3 == NULL) { + err = -ENOMEM; + goto err_put_fence2; + } + + data.fence = fd; + if (copy_to_user((void __user *)arg, &data, sizeof(data))) { + err = -EFAULT; + goto err_put_fence3; + } + + sync_fence_install(fence3, fd); + sync_fence_put(fence2); + return 0; + +err_put_fence3: + sync_fence_put(fence3); + +err_put_fence2: + sync_fence_put(fence2); + +err_put_fd: + put_unused_fd(fd); + return err; +} + + +static long sync_fence_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct sync_fence *fence = file->private_data; + switch (cmd) { + case SYNC_IOC_WAIT: + return sync_fence_ioctl_wait(fence, arg); + + case SYNC_IOC_MERGE: + return sync_fence_ioctl_merge(fence, arg); + default: + return -ENOTTY; + } +} + diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h new file mode 100644 index 000000000000..388acd1ff412 --- /dev/null +++ b/drivers/staging/android/sync.h @@ -0,0 +1,314 @@ +/* + * include/linux/sync.h + * + * Copyright (C) 2012 Google, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT 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 _LINUX_SYNC_H +#define _LINUX_SYNC_H + +#include +#ifdef __KERNEL__ + +#include +#include +#include + +struct sync_timeline; +struct sync_pt; +struct sync_fence; + +/** + * struct sync_timeline_ops - sync object implementation ops + * @driver_name: name of the implentation + * @dup: duplicate a sync_pt + * @has_signaled: returns: + * 1 if pt has signaled + * 0 if pt has not signaled + * <0 on error + * @compare: returns: + * 1 if b will signal before a + * 0 if a and b will signal at the same time + * -1 if a will signabl before b + * @free_pt: called before sync_pt is freed + * @release_obj: called before sync_timeline is freed + */ +struct sync_timeline_ops { + const char *driver_name; + + /* required */ + struct sync_pt *(*dup)(struct sync_pt *pt); + + /* required */ + int (*has_signaled)(struct sync_pt *pt); + + /* required */ + int (*compare)(struct sync_pt *a, struct sync_pt *b); + + /* optional */ + void (*free_pt)(struct sync_pt *sync_pt); + + /* optional */ + void (*release_obj)(struct sync_timeline *sync_timeline); +}; + +/** + * struct sync_timeline - sync object + * @ops: ops that define the implementaiton of the sync_timeline + * @name: name of the sync_timeline. Useful for debugging + * @destoryed: set when sync_timeline is destroyed + * @child_list_head: list of children sync_pts for this sync_timeline + * @child_list_lock: lock protecting @child_list_head, destroyed, and + * sync_pt.status + * @active_list_head: list of active (unsignaled/errored) sync_pts + */ +struct sync_timeline { + const struct sync_timeline_ops *ops; + char name[32]; + + /* protected by child_list_lock */ + bool destroyed; + + struct list_head child_list_head; + spinlock_t child_list_lock; + + struct list_head active_list_head; + spinlock_t active_list_lock; +}; + +/** + * struct sync_pt - sync point + * @parent: sync_timeline to which this sync_pt belongs + * @child_list: membership in sync_timeline.child_list_head + * @active_list: membership in sync_timeline.active_list_head + * @fence: sync_fence to which the sync_pt belongs + * @pt_list: membership in sync_fence.pt_list_head + * @status: 1: signaled, 0:active, <0: error + */ +struct sync_pt { + struct sync_timeline *parent; + struct list_head child_list; + + struct list_head active_list; + + struct sync_fence *fence; + struct list_head pt_list; + + /* protected by parent->active_list_lock */ + int status; +}; + +/** + * struct sync_fence - sync fence + * @file: file representing this fence + * @name: name of sync_fence. Useful for debugging + * @pt_list_head: list of sync_pts in ths fence. immutable once fence + * is created + * @waiter_list_head: list of asynchronous waiters on this fence + * @waiter_list_lock: lock protecting @waiter_list_head and @status + * @status: 1: signaled, 0:active, <0: error + * + * @wq: wait queue for fence signaling + */ +struct sync_fence { + struct file *file; + char name[32]; + + /* this list is immutable once the fence is created */ + struct list_head pt_list_head; + + struct list_head waiter_list_head; + spinlock_t waiter_list_lock; /* also protects status */ + int status; + + wait_queue_head_t wq; +}; + +/** + * struct sync_fence_waiter - metadata for asynchronous waiter on a fence + * @waiter_list: membership in sync_fence.waiter_list_head + * @callback: function pointer to call when fence signals + * @callback_data: pointer to pass to @callback + */ +struct sync_fence_waiter { + struct list_head waiter_list; + + void (*callback)(struct sync_fence *fence, void *data); + void *callback_data; +}; + +/* + * API for sync_timeline implementers + */ + +/** + * sync_timeline_create() - creates a sync object + * @ops: specifies the implemention ops for the object + * @size: size to allocate for this obj + * @name: sync_timeline name + * + * Creates a new sync_timeline which will use the implemetation specified by + * @ops. @size bytes will be allocated allowing for implemntation specific + * data to be kept after the generic sync_timeline stuct. + */ +struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, + int size, const char *name); + +/** + * sync_timeline_destory() - destorys a sync object + * @obj: sync_timeline to destroy + * + * A sync implemntation should call this when the @obj is going away + * (i.e. module unload.) @obj won't actually be freed until all its childern + * sync_pts are freed. + */ +void sync_timeline_destroy(struct sync_timeline *obj); + +/** + * sync_timeline_signal() - signal a status change on a sync_timeline + * @obj: sync_timeline to signal + * + * A sync implemntation should call this any time one of it's sync_pts + * has signaled or has an error condition. + */ +void sync_timeline_signal(struct sync_timeline *obj); + +/** + * sync_pt_create() - creates a sync pt + * @parent: sync_pt's parent sync_timeline + * @size: size to allocate for this pt + * + * Creates a new sync_pt as a chiled of @parent. @size bytes will be + * allocated allowing for implemntation specific data to be kept after + * the generic sync_timeline struct. + */ +struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size); + +/** + * sync_pt_free() - frees a sync pt + * @pt: sync_pt to free + * + * This should only be called on sync_pts which have been created but + * not added to a fence. + */ +void sync_pt_free(struct sync_pt *pt); + +/** + * sync_fence_create() - creates a sync fence + * @name: name of fence to create + * @pt: sync_pt to add to the fence + * + * Creates a fence containg @pt. Once this is called, the fence takes + * ownership of @pt. + */ +struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt); + +/* + * API for sync_fence consumers + */ + +/** + * sync_fence_merge() - merge two fences + * @name: name of new fence + * @a: fence a + * @b: fence b + * + * Creates a new fence which contains copies of all the sync_pts in both + * @a and @b. @a and @b remain valid, independent fences. + */ +struct sync_fence *sync_fence_merge(const char *name, + struct sync_fence *a, struct sync_fence *b); + +/** + * sync_fence_fdget() - get a fence from an fd + * @fd: fd referencing a fence + * + * Ensures @fd references a valid fence, increments the refcount of the backing + * file, and returns the fence. + */ +struct sync_fence *sync_fence_fdget(int fd); + +/** + * sync_fence_put() - puts a refernnce of a sync fence + * @fence: fence to put + * + * Puts a reference on @fence. If this is the last reference, the fence and + * all it's sync_pts will be freed + */ +void sync_fence_put(struct sync_fence *fence); + +/** + * sync_fence_install() - installs a fence into a file descriptor + * @fence: fence to instal + * @fd: file descriptor in which to install the fence + * + * Installs @fence into @fd. @fd's should be acquired through get_unused_fd(). + */ +void sync_fence_install(struct sync_fence *fence, int fd); + +/** + * sync_fence_wait_async() - registers and async wait on the fence + * @fence: fence to wait on + * @callback: callback + * @callback_data data to pass to the callback + * + * Returns 1 if @fence has already signaled. + * + * Registers a callback to be called when @fence signals or has an error + */ +int sync_fence_wait_async(struct sync_fence *fence, + void (*callback)(struct sync_fence *, void *data), + void *callback_data); + +/** + * sync_fence_wait() - wait on fence + * @fence: fence to wait on + * @tiemout: timeout in ms + * + * Wait for @fence to be signaled or have an error. Waits indefintly + * if @timeout = 0 + */ +int sync_fence_wait(struct sync_fence *fence, long timeout); + +/* useful for sync driver's debug print handlers */ +const char *sync_status_str(int status); + +#endif /* __KERNEL__ */ + +/** + * struct sync_merge_data - data passed to merge ioctl + * @fd2: file descriptor of second fence + * @name: name of new fence + * @fence: returns the fd of the new fence to userspace + */ +struct sync_merge_data { + __s32 fd2; /* fd of second fence */ + char name[32]; /* name of new fence */ + __s32 fence; /* fd on newly created fence */ +}; + +#define SYNC_IOC_MAGIC '>' + +/** + * DOC: SYNC_IOC_WAIT - wait for a fence to signal + * + * pass timeout in milliseconds. + */ +#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __u32) + +/** + * DOC: SYNC_IOC_MERGE - merge two fences + * + * Takes a struct sync_merge_data. Creates a new fence containing copies of + * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the + * new fence's fd in sync_merge_data.fence + */ +#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) + +#endif /* _LINUX_SYNC_H */ -- cgit From 9d1906e61dda982070e3910a04d9cce050f7f1a4 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:42:58 -0800 Subject: staging: sw_sync: Add cpu based sync driver Adds a base sync driver that uses the cpu for serialization. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message, whitespace fixes and move to staging directory] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 18 +++ drivers/staging/android/Makefile | 1 + drivers/staging/android/sw_sync.c | 224 ++++++++++++++++++++++++++++++++++++++ drivers/staging/android/sw_sync.h | 58 ++++++++++ 4 files changed, 301 insertions(+) create mode 100644 drivers/staging/android/sw_sync.c create mode 100644 drivers/staging/android/sw_sync.h (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index c95aedeff3f4..cc406cc8b8d1 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -81,6 +81,24 @@ config SYNC drivers. Sync implementations can take advantage of hardware synchronization built into devices like GPUs. +config SW_SYNC + bool "Software synchronization objects" + default n + depends on SYNC + help + A sync object driver that uses a 32bit counter to coordinate + syncrhronization. Useful when there is no hardware primitive backing + the synchronization. + +config SW_SYNC_USER + bool "Userspace API for SW_SYNC" + default n + depends on SW_SYNC + help + Provides a user space API to the sw sync object. + *WARNING* improper use of this can result in deadlocking kernel + drivers from userspace. + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 22c656c82c3f..c136299e05af 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o obj-$(CONFIG_SYNC) += sync.o +obj-$(CONFIG_SW_SYNC) += sw_sync.o diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c new file mode 100644 index 000000000000..c27004c94cc6 --- /dev/null +++ b/drivers/staging/android/sw_sync.c @@ -0,0 +1,224 @@ +/* + * drivers/base/sw_sync.c + * + * Copyright (C) 2012 Google, Inc. + * + * 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 "sw_sync.h" + +static int sw_sync_cmp(u32 a, u32 b) +{ + if (a == b) + return 0; + + return ((s32)a - (s32)b) < 0 ? -1 : 1; +} + +struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) +{ + struct sw_sync_pt *pt; + + pt = (struct sw_sync_pt *) + sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt)); + + pt->value = value; + + return (struct sync_pt *)pt; +} + +static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt) +{ + struct sw_sync_pt *pt = (struct sw_sync_pt *) sync_pt; + struct sw_sync_timeline *obj = + (struct sw_sync_timeline *)sync_pt->parent; + + return (struct sync_pt *) sw_sync_pt_create(obj, pt->value); +} + +static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt) +{ + struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; + struct sw_sync_timeline *obj = + (struct sw_sync_timeline *)sync_pt->parent; + + return sw_sync_cmp(obj->value, pt->value) >= 0; +} + +static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) +{ + struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a; + struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b; + + return sw_sync_cmp(pt_a->value, pt_b->value); +} + +struct sync_timeline_ops sw_sync_timeline_ops = { + .driver_name = "sw_sync", + .dup = sw_sync_pt_dup, + .has_signaled = sw_sync_pt_has_signaled, + .compare = sw_sync_pt_compare, +}; + + +struct sw_sync_timeline *sw_sync_timeline_create(const char *name) +{ + struct sw_sync_timeline *obj = (struct sw_sync_timeline *) + sync_timeline_create(&sw_sync_timeline_ops, + sizeof(struct sw_sync_timeline), + name); + + return obj; +} + +void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) +{ + obj->value += inc; + + sync_timeline_signal(&obj->obj); +} + + +#ifdef CONFIG_SW_SYNC_USER +/* *WARNING* + * + * improper use of this can result in deadlocking kernel drivers from userspace. + */ + +/* opening sw_sync create a new sync obj */ +int sw_sync_open(struct inode *inode, struct file *file) +{ + struct sw_sync_timeline *obj; + char task_comm[TASK_COMM_LEN]; + + get_task_comm(task_comm, current); + + obj = sw_sync_timeline_create(task_comm); + if (obj == NULL) + return -ENOMEM; + + file->private_data = obj; + + return 0; +} + +int sw_sync_release(struct inode *inode, struct file *file) +{ + struct sw_sync_timeline *obj = file->private_data; + sync_timeline_destroy(&obj->obj); + return 0; +} + +long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) +{ + int fd = get_unused_fd(); + int err; + struct sync_pt *pt; + struct sync_fence *fence; + struct sw_sync_create_fence_data data; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) + return -EFAULT; + + pt = sw_sync_pt_create(obj, data.value); + if (pt == NULL) { + err = -ENOMEM; + goto err; + } + + data.name[sizeof(data.name) - 1] = '\0'; + fence = sync_fence_create(data.name, pt); + if (fence == NULL) { + sync_pt_free(pt); + err = -ENOMEM; + goto err; + } + + data.fence = fd; + if (copy_to_user((void __user *)arg, &data, sizeof(data))) { + sync_fence_put(fence); + err = -EFAULT; + goto err; + } + + sync_fence_install(fence, fd); + + return 0; + +err: + put_unused_fd(fd); + return err; +} + +long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) +{ + u32 value; + + if (copy_from_user(&value, (void __user *)arg, sizeof(value))) + return -EFAULT; + + sw_sync_timeline_inc(obj, value); + + return 0; +} + +long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct sw_sync_timeline *obj = file->private_data; + + switch (cmd) { + case SW_SYNC_IOC_CREATE_FENCE: + return sw_sync_ioctl_create_fence(obj, arg); + + case SW_SYNC_IOC_INC: + return sw_sync_ioctl_inc(obj, arg); + + default: + return -ENOTTY; + } +} + +static const struct file_operations sw_sync_fops = { + .owner = THIS_MODULE, + .open = sw_sync_open, + .release = sw_sync_release, + .unlocked_ioctl = sw_sync_ioctl, +}; + +static struct miscdevice sw_sync_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "sw_sync", + .fops = &sw_sync_fops, +}; + +int __init sw_sync_device_init(void) +{ + return misc_register(&sw_sync_dev); +} + +void __exit sw_sync_device_remove(void) +{ + misc_deregister(&sw_sync_dev); +} + +module_init(sw_sync_device_init); +module_exit(sw_sync_device_remove); + +#endif /* CONFIG_SW_SYNC_USER */ diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h new file mode 100644 index 000000000000..585040be5f18 --- /dev/null +++ b/drivers/staging/android/sw_sync.h @@ -0,0 +1,58 @@ +/* + * include/linux/sw_sync.h + * + * Copyright (C) 2012 Google, Inc. + * + * 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 _LINUX_SW_SYNC_H +#define _LINUX_SW_SYNC_H + +#include + +#ifdef __KERNEL__ + +#include "sync.h" + +struct sw_sync_timeline { + struct sync_timeline obj; + + u32 value; +}; + +struct sw_sync_pt { + struct sync_pt pt; + + u32 value; +}; + +struct sw_sync_timeline *sw_sync_timeline_create(const char *name); +void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); + +struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); + +#endif /* __KERNEL __ */ + +struct sw_sync_create_fence_data { + __u32 value; + char name[32]; + __s32 fence; /* fd of new fence */ +}; + +#define SW_SYNC_IOC_MAGIC 'W' + +#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ + struct sw_sync_create_fence_data) +#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) + + +#endif /* _LINUX_SW_SYNC_H */ -- cgit From 97a84843ac4a1b81c36ccf35ee26cd19c5b8d873 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:42:59 -0800 Subject: staging: sync: Add timestamps to sync_pts Add ktime timestamps to sync_pt structure and update them when signaled Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 5 +++++ drivers/staging/android/sync.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 4a9e63df83e9..88d7e6625868 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -155,12 +155,17 @@ void sync_pt_free(struct sync_pt *pt) /* call with pt->parent->active_list_lock held */ static int _sync_pt_has_signaled(struct sync_pt *pt) { + int old_status = pt->status; + if (!pt->status) pt->status = pt->parent->ops->has_signaled(pt); if (!pt->status && pt->parent->destroyed) pt->status = -ENOENT; + if (pt->status != old_status) + pt->timestamp = ktime_get(); + return pt->status; } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 388acd1ff412..a8e289d50ae0 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -16,6 +16,7 @@ #include #ifdef __KERNEL__ +#include #include #include #include @@ -90,6 +91,8 @@ struct sync_timeline { * @fence: sync_fence to which the sync_pt belongs * @pt_list: membership in sync_fence.pt_list_head * @status: 1: signaled, 0:active, <0: error + * @timestamp: time which sync_pt status transitioned from active to + * singaled or error. */ struct sync_pt { struct sync_timeline *parent; @@ -102,6 +105,8 @@ struct sync_pt { /* protected by parent->active_list_lock */ int status; + + ktime_t timestamp; }; /** -- cgit From af7582f293cdc29999d05f75b1ec835ffa43cb68 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:00 -0800 Subject: staging: sync: Add debugfs support Add support for debugfs Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 176 ++++++++++++++++++++++++++++++++++++++++- drivers/staging/android/sync.h | 20 ++++- 2 files changed, 191 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 88d7e6625868..4ab55a3a8ec5 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -14,10 +14,12 @@ * */ +#include #include #include #include #include +#include #include #include #include @@ -27,10 +29,17 @@ static void sync_fence_signal_pt(struct sync_pt *pt); static int _sync_pt_has_signaled(struct sync_pt *pt); +static LIST_HEAD(sync_timeline_list_head); +static DEFINE_SPINLOCK(sync_timeline_list_lock); + +static LIST_HEAD(sync_fence_list_head); +static DEFINE_SPINLOCK(sync_fence_list_lock); + struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, int size, const char *name) { struct sync_timeline *obj; + unsigned long flags; if (size < sizeof(struct sync_timeline)) return NULL; @@ -48,9 +57,27 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, INIT_LIST_HEAD(&obj->active_list_head); spin_lock_init(&obj->active_list_lock); + spin_lock_irqsave(&sync_timeline_list_lock, flags); + list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head); + spin_unlock_irqrestore(&sync_timeline_list_lock, flags); + return obj; } +static void sync_timeline_free(struct sync_timeline *obj) +{ + unsigned long flags; + + if (obj->ops->release_obj) + obj->ops->release_obj(obj); + + spin_lock_irqsave(&sync_timeline_list_lock, flags); + list_del(&obj->sync_timeline_list); + spin_unlock_irqrestore(&sync_timeline_list_lock, flags); + + kfree(obj); +} + void sync_timeline_destroy(struct sync_timeline *obj) { unsigned long flags; @@ -62,7 +89,7 @@ void sync_timeline_destroy(struct sync_timeline *obj) spin_unlock_irqrestore(&obj->child_list_lock, flags); if (needs_freeing) - kfree(obj); + sync_timeline_free(obj); else sync_timeline_signal(obj); } @@ -95,7 +122,7 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) spin_unlock_irqrestore(&obj->child_list_lock, flags); if (needs_freeing) - kfree(obj); + sync_timeline_free(obj); } void sync_timeline_signal(struct sync_timeline *obj) @@ -206,6 +233,7 @@ static const struct file_operations sync_fence_fops = { static struct sync_fence *sync_fence_alloc(const char *name) { struct sync_fence *fence; + unsigned long flags; fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL); if (fence == NULL) @@ -223,6 +251,11 @@ static struct sync_fence *sync_fence_alloc(const char *name) spin_lock_init(&fence->waiter_list_lock); init_waitqueue_head(&fence->wq); + + spin_lock_irqsave(&sync_fence_list_lock, flags); + list_add_tail(&fence->sync_fence_list, &sync_fence_list_head); + spin_unlock_irqrestore(&sync_fence_list_lock, flags); + return fence; err: @@ -451,8 +484,14 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) static int sync_fence_release(struct inode *inode, struct file *file) { struct sync_fence *fence = file->private_data; + unsigned long flags; sync_fence_free_pts(fence); + + spin_lock_irqsave(&sync_fence_list_lock, flags); + list_del(&fence->sync_fence_list); + spin_unlock_irqrestore(&sync_fence_list_lock, flags); + kfree(fence); return 0; @@ -523,8 +562,141 @@ static long sync_fence_ioctl(struct file *file, unsigned int cmd, case SYNC_IOC_MERGE: return sync_fence_ioctl_merge(fence, arg); + default: return -ENOTTY; } } +#ifdef CONFIG_DEBUG_FS +static const char *sync_status_str(int status) +{ + if (status > 0) + return "signaled"; + else if (status == 0) + return "active"; + else + return "error"; +} + +static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) +{ + int status = pt->status; + seq_printf(s, " %s%spt %s", + fence ? pt->parent->name : "", + fence ? "_" : "", + sync_status_str(status)); + if (pt->status) { + struct timeval tv = ktime_to_timeval(pt->timestamp); + seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec); + } + + if (pt->parent->ops->print_pt) { + seq_printf(s, ": "); + pt->parent->ops->print_pt(s, pt); + } + + seq_printf(s, "\n"); +} + +static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) +{ + struct list_head *pos; + unsigned long flags; + + seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); + + if (obj->ops->print_obj) { + seq_printf(s, ": "); + obj->ops->print_obj(s, obj); + } + + seq_printf(s, "\n"); + + spin_lock_irqsave(&obj->child_list_lock, flags); + list_for_each(pos, &obj->child_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, child_list); + sync_print_pt(s, pt, false); + } + spin_unlock_irqrestore(&obj->child_list_lock, flags); +} + +static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) +{ + struct list_head *pos; + unsigned long flags; + + seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status)); + + list_for_each(pos, &fence->pt_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, pt_list); + sync_print_pt(s, pt, true); + } + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + list_for_each(pos, &fence->waiter_list_head) { + struct sync_fence_waiter *waiter = + container_of(pos, struct sync_fence_waiter, + waiter_list); + + seq_printf(s, "waiter %pF %p\n", waiter->callback, + waiter->callback_data); + } + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); +} + +static int sync_debugfs_show(struct seq_file *s, void *unused) +{ + unsigned long flags; + struct list_head *pos; + + seq_printf(s, "objs:\n--------------\n"); + + spin_lock_irqsave(&sync_timeline_list_lock, flags); + list_for_each(pos, &sync_timeline_list_head) { + struct sync_timeline *obj = + container_of(pos, struct sync_timeline, + sync_timeline_list); + + sync_print_obj(s, obj); + seq_printf(s, "\n"); + } + spin_unlock_irqrestore(&sync_timeline_list_lock, flags); + + seq_printf(s, "fences:\n--------------\n"); + + spin_lock_irqsave(&sync_fence_list_lock, flags); + list_for_each(pos, &sync_fence_list_head) { + struct sync_fence *fence = + container_of(pos, struct sync_fence, sync_fence_list); + + sync_print_fence(s, fence); + seq_printf(s, "\n"); + } + spin_unlock_irqrestore(&sync_fence_list_lock, flags); + return 0; +} + +static int sync_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, sync_debugfs_show, inode->i_private); +} + +static const struct file_operations sync_debugfs_fops = { + .open = sync_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static __init int sync_debugfs_init(void) +{ + debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops); + return 0; +} + +late_initcall(sync_debugfs_init); + +#endif diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index a8e289d50ae0..d64271bd7a3c 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -39,6 +39,10 @@ struct sync_fence; * -1 if a will signabl before b * @free_pt: called before sync_pt is freed * @release_obj: called before sync_timeline is freed + * @print_obj: print aditional debug information about sync_timeline. + * should not print a newline + * @print_pt: print aditional debug information about sync_pt. + * should not print a newline */ struct sync_timeline_ops { const char *driver_name; @@ -57,6 +61,13 @@ struct sync_timeline_ops { /* optional */ void (*release_obj)(struct sync_timeline *sync_timeline); + + /* optional */ + void (*print_obj)(struct seq_file *s, + struct sync_timeline *sync_timeline); + + /* optional */ + void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt); }; /** @@ -68,6 +79,7 @@ struct sync_timeline_ops { * @child_list_lock: lock protecting @child_list_head, destroyed, and * sync_pt.status * @active_list_head: list of active (unsignaled/errored) sync_pts + * @sync_timeline_list: membership in global sync_timeline_list */ struct sync_timeline { const struct sync_timeline_ops *ops; @@ -81,6 +93,8 @@ struct sync_timeline { struct list_head active_list_head; spinlock_t active_list_lock; + + struct list_head sync_timeline_list; }; /** @@ -120,6 +134,7 @@ struct sync_pt { * @status: 1: signaled, 0:active, <0: error * * @wq: wait queue for fence signaling + * @sync_fence_list: membership in global fence list */ struct sync_fence { struct file *file; @@ -133,6 +148,8 @@ struct sync_fence { int status; wait_queue_head_t wq; + + struct list_head sync_fence_list; }; /** @@ -281,9 +298,6 @@ int sync_fence_wait_async(struct sync_fence *fence, */ int sync_fence_wait(struct sync_fence *fence, long timeout); -/* useful for sync driver's debug print handlers */ -const char *sync_status_str(int status); - #endif /* __KERNEL__ */ /** -- cgit From cebed3b1d7eaee7fb79e2c510a0da4296db043c8 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:01 -0800 Subject: staging: sw_sync: Add debug support Add debugfs support hooks. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index c27004c94cc6..64c5ebbbb1a0 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -70,11 +70,30 @@ static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) return sw_sync_cmp(pt_a->value, pt_b->value); } +static void sw_sync_print_obj(struct seq_file *s, + struct sync_timeline *sync_timeline) +{ + struct sw_sync_timeline *obj = (struct sw_sync_timeline *)sync_timeline; + + seq_printf(s, "%d", obj->value); +} + +static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt) +{ + struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; + struct sw_sync_timeline *obj = + (struct sw_sync_timeline *)sync_pt->parent; + + seq_printf(s, "%d / %d", pt->value, obj->value); +} + struct sync_timeline_ops sw_sync_timeline_ops = { .driver_name = "sw_sync", .dup = sw_sync_pt_dup, .has_signaled = sw_sync_pt_has_signaled, .compare = sw_sync_pt_compare, + .print_obj = sw_sync_print_obj, + .print_pt = sw_sync_print_pt, }; -- cgit From 79ba1525a91e99cdd7a3b6a57c7537d13ac0ac19 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:02 -0800 Subject: staging: sync: Add ioctl to get fence data Add ioctl to get fence data Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Commit message tweaks] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 81 ++++++++++++++++++++++++++++++++++++++++++ drivers/staging/android/sync.h | 57 +++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 4ab55a3a8ec5..f84caad35d68 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -551,6 +551,84 @@ err_put_fd: return err; } +static int sync_fill_pt_info(struct sync_pt *pt, void *data, int size) +{ + struct sync_pt_info *info = data; + int ret; + + if (size < sizeof(struct sync_pt_info)) + return -ENOMEM; + + info->len = sizeof(struct sync_pt_info); + + if (pt->parent->ops->fill_driver_data) { + ret = pt->parent->ops->fill_driver_data(pt, info->driver_data, + size - sizeof(*info)); + if (ret < 0) + return ret; + + info->len += ret; + } + + strlcpy(info->obj_name, pt->parent->name, sizeof(info->obj_name)); + strlcpy(info->driver_name, pt->parent->ops->driver_name, + sizeof(info->driver_name)); + info->status = pt->status; + info->timestamp_ns = ktime_to_ns(pt->timestamp); + + return info->len; +} + +static long sync_fence_ioctl_fence_info(struct sync_fence *fence, + unsigned long arg) +{ + struct sync_fence_info_data *data; + struct list_head *pos; + __u32 size; + __u32 len = 0; + int ret; + + if (copy_from_user(&size, (void __user *)arg, sizeof(size))) + return -EFAULT; + + if (size < sizeof(struct sync_fence_info_data)) + return -EINVAL; + + if (size > 4096) + size = 4096; + + data = kzalloc(size, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + strlcpy(data->name, fence->name, sizeof(data->name)); + data->status = fence->status; + len = sizeof(struct sync_fence_info_data); + + list_for_each(pos, &fence->pt_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, pt_list); + + ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); + + if (ret < 0) + goto out; + + len += ret; + } + + data->len = len; + + if (copy_to_user((void __user *)arg, data, len)) + ret = -EFAULT; + else + ret = 0; + +out: + kfree(data); + + return ret; +} static long sync_fence_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -563,6 +641,9 @@ static long sync_fence_ioctl(struct file *file, unsigned int cmd, case SYNC_IOC_MERGE: return sync_fence_ioctl_merge(fence, arg); + case SYNC_IOC_FENCE_INFO: + return sync_fence_ioctl_fence_info(fence, arg); + default: return -ENOTTY; } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index d64271bd7a3c..4f1993871467 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -43,6 +43,10 @@ struct sync_fence; * should not print a newline * @print_pt: print aditional debug information about sync_pt. * should not print a newline + * @fill_driver_data: write implmentation specific driver data to data. + * should return an error if there is not enough room + * as specified by size. This information is returned + * to userspace by SYNC_IOC_FENCE_INFO. */ struct sync_timeline_ops { const char *driver_name; @@ -68,6 +72,9 @@ struct sync_timeline_ops { /* optional */ void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt); + + /* optional */ + int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); }; /** @@ -312,6 +319,42 @@ struct sync_merge_data { __s32 fence; /* fd on newly created fence */ }; +/** + * struct sync_pt_info - detailed sync_pt information + * @len: length of sync_pt_info including any driver_data + * @obj_name: name of parent sync_timeline + * @driver_name: name of driver implmenting the parent + * @status: status of the sync_pt 0:active 1:signaled <0:error + * @timestamp_ns: timestamp of status change in nanoseconds + * @driver_data: any driver dependant data + */ +struct sync_pt_info { + __u32 len; + char obj_name[32]; + char driver_name[32]; + __s32 status; + __u64 timestamp_ns; + + __u8 driver_data[0]; +}; + +/** + * struct sync_fence_info_data - data returned from fence info ioctl + * @len: ioctl caller writes the size of the buffer its passing in. + * ioctl returns length of sync_fence_data reutnred to userspace + * including pt_info. + * @name: name of fence + * @status: status of fence. 1: signaled 0:active <0:error + * @pt_info: a sync_pt_info struct for every sync_pt in the fence + */ +struct sync_fence_info_data { + __u32 len; + char name[32]; + __s32 status; + + __u8 pt_info[0]; +}; + #define SYNC_IOC_MAGIC '>' /** @@ -330,4 +373,18 @@ struct sync_merge_data { */ #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) +/** + * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence + * + * Takes a struct sync_fence_info_data with extra space allocated for pt_info. + * Caller should write the size of the buffer into len. On return, len is + * updated to reflect the total size of the sync_fence_info_data including + * pt_info. + * + * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. + * To itterate over the sync_pt_infos, use the sync_pt_info.len field. + */ +#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ + struct sync_fence_info_data) + #endif /* _LINUX_SYNC_H */ -- cgit From b1489c2704b3db72ff37ecabe054926176e88e50 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:03 -0800 Subject: staging: sw_sync: Add fill_driver_data support Add fill_driver_data support to export fence data to ioctl Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index 64c5ebbbb1a0..081e4d188fe9 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -87,6 +87,19 @@ static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt) seq_printf(s, "%d / %d", pt->value, obj->value); } +static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, + void *data, int size) +{ + struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; + + if (size < sizeof(pt->value)) + return -ENOMEM; + + memcpy(data, &pt->value, sizeof(pt->value)); + + return sizeof(pt->value); +} + struct sync_timeline_ops sw_sync_timeline_ops = { .driver_name = "sw_sync", .dup = sw_sync_pt_dup, @@ -94,6 +107,7 @@ struct sync_timeline_ops sw_sync_timeline_ops = { .compare = sw_sync_pt_compare, .print_obj = sw_sync_print_obj, .print_pt = sw_sync_print_pt, + .fill_driver_data = sw_sync_fill_driver_data, }; -- cgit From 57b505bbe746dcc011152e79732bdaf96723c51a Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:04 -0800 Subject: staging: sync: Add poll support Support poll on sync fence Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index f84caad35d68..9e35ea3e73da 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -221,12 +222,14 @@ out: } static int sync_fence_release(struct inode *inode, struct file *file); +static unsigned int sync_fence_poll(struct file *file, poll_table *wait); static long sync_fence_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static const struct file_operations sync_fence_fops = { .release = sync_fence_release, + .poll = sync_fence_poll, .unlocked_ioctl = sync_fence_ioctl, }; @@ -497,6 +500,20 @@ static int sync_fence_release(struct inode *inode, struct file *file) return 0; } +static unsigned int sync_fence_poll(struct file *file, poll_table *wait) +{ + struct sync_fence *fence = file->private_data; + + poll_wait(file, &fence->wq, wait); + + if (fence->status == 1) + return POLLIN; + else if (fence->status < 0) + return POLLERR; + else + return 0; +} + static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) { __s32 value; -- cgit From c0f61a4e6145728153d0b94152b4dd5b06899b3b Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:05 -0800 Subject: staging: sync: Allow async waits to be canceled In order to allow drivers to cleanly handled teardown we need to allow them to cancel pending async waits. To do this cleanly, we move allocation of sync_fence_waiter to the driver calling sync_async_wait(). Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 46 ++++++++++++++++++++++++++++-------------- drivers/staging/android/sync.h | 36 ++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 9e35ea3e73da..54f84d926b9a 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -421,33 +421,22 @@ static void sync_fence_signal_pt(struct sync_pt *pt) container_of(pos, struct sync_fence_waiter, waiter_list); - waiter->callback(fence, waiter->callback_data); list_del(pos); - kfree(waiter); + waiter->callback(fence, waiter); } wake_up(&fence->wq); } } int sync_fence_wait_async(struct sync_fence *fence, - void (*callback)(struct sync_fence *, void *data), - void *callback_data) + struct sync_fence_waiter *waiter) { - struct sync_fence_waiter *waiter; unsigned long flags; int err = 0; - waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL); - if (waiter == NULL) - return -ENOMEM; - - waiter->callback = callback; - waiter->callback_data = callback_data; - spin_lock_irqsave(&fence->waiter_list_lock, flags); if (fence->status) { - kfree(waiter); err = fence->status; goto out; } @@ -459,6 +448,34 @@ out: return err; } +int sync_fence_cancel_async(struct sync_fence *fence, + struct sync_fence_waiter *waiter) +{ + struct list_head *pos; + struct list_head *n; + unsigned long flags; + int ret = -ENOENT; + + spin_lock_irqsave(&fence->waiter_list_lock, flags); + /* + * Make sure waiter is still in waiter_list because it is possible for + * the waiter to be removed from the list while the callback is still + * pending. + */ + list_for_each_safe(pos, n, &fence->waiter_list_head) { + struct sync_fence_waiter *list_waiter = + container_of(pos, struct sync_fence_waiter, + waiter_list); + if (list_waiter == waiter) { + list_del(pos); + ret = 0; + break; + } + } + spin_unlock_irqrestore(&fence->waiter_list_lock, flags); + return ret; +} + int sync_fence_wait(struct sync_fence *fence, long timeout) { int err; @@ -739,8 +756,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) container_of(pos, struct sync_fence_waiter, waiter_list); - seq_printf(s, "waiter %pF %p\n", waiter->callback, - waiter->callback_data); + seq_printf(s, "waiter %pF\n", waiter->callback); } spin_unlock_irqrestore(&fence->waiter_list_lock, flags); } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 4f1993871467..943f414b3f3b 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -159,6 +159,10 @@ struct sync_fence { struct list_head sync_fence_list; }; +struct sync_fence_waiter; +typedef void (*sync_callback_t)(struct sync_fence *fence, + struct sync_fence_waiter *waiter); + /** * struct sync_fence_waiter - metadata for asynchronous waiter on a fence * @waiter_list: membership in sync_fence.waiter_list_head @@ -168,10 +172,15 @@ struct sync_fence { struct sync_fence_waiter { struct list_head waiter_list; - void (*callback)(struct sync_fence *fence, void *data); - void *callback_data; + sync_callback_t callback; }; +static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, + sync_callback_t callback) +{ + waiter->callback = callback; +} + /* * API for sync_timeline implementers */ @@ -284,16 +293,29 @@ void sync_fence_install(struct sync_fence *fence, int fd); /** * sync_fence_wait_async() - registers and async wait on the fence * @fence: fence to wait on - * @callback: callback - * @callback_data data to pass to the callback + * @waiter: waiter callback struck * * Returns 1 if @fence has already signaled. * - * Registers a callback to be called when @fence signals or has an error + * Registers a callback to be called when @fence signals or has an error. + * @waiter should be initialized with sync_fence_waiter_init(). */ int sync_fence_wait_async(struct sync_fence *fence, - void (*callback)(struct sync_fence *, void *data), - void *callback_data); + struct sync_fence_waiter *waiter); + +/** + * sync_fence_cancel_async() - cancels an async wait + * @fence: fence to wait on + * @waiter: waiter callback struck + * + * returns 0 if waiter was removed from fence's async waiter list. + * returns -ENOENT if waiter was not found on fence's async waiter list. + * + * Cancels a previously registered async wait. Will fail gracefully if + * @waiter was never registered or if @fence has already signaled @waiter. + */ +int sync_fence_cancel_async(struct sync_fence *fence, + struct sync_fence_waiter *waiter); /** * sync_fence_wait() - wait on fence -- cgit From 8edb4ad9118befafe6e0a6b7456939b74a545e42 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:06 -0800 Subject: staging: sync: Export sync API symbols This is needed to allow modules to link against the sync subsystem Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 54f84d926b9a..6739a8440bfc 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -64,6 +65,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, return obj; } +EXPORT_SYMBOL(sync_timeline_create); static void sync_timeline_free(struct sync_timeline *obj) { @@ -94,6 +96,7 @@ void sync_timeline_destroy(struct sync_timeline *obj) else sync_timeline_signal(obj); } +EXPORT_SYMBOL(sync_timeline_destroy); static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt) { @@ -152,6 +155,7 @@ void sync_timeline_signal(struct sync_timeline *obj) sync_fence_signal_pt(pt); } } +EXPORT_SYMBOL(sync_timeline_signal); struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) { @@ -169,6 +173,7 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) return pt; } +EXPORT_SYMBOL(sync_pt_create); void sync_pt_free(struct sync_pt *pt) { @@ -179,6 +184,7 @@ void sync_pt_free(struct sync_pt *pt) kfree(pt); } +EXPORT_SYMBOL(sync_pt_free); /* call with pt->parent->active_list_lock held */ static int _sync_pt_has_signaled(struct sync_pt *pt) @@ -284,6 +290,7 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) return fence; } +EXPORT_SYMBOL(sync_fence_create); static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) { @@ -331,16 +338,19 @@ err: fput(file); return NULL; } +EXPORT_SYMBOL(sync_fence_fdget); void sync_fence_put(struct sync_fence *fence) { fput(fence->file); } +EXPORT_SYMBOL(sync_fence_put); void sync_fence_install(struct sync_fence *fence, int fd) { fd_install(fd, fence->file); } +EXPORT_SYMBOL(sync_fence_install); static int sync_fence_get_status(struct sync_fence *fence) { @@ -388,6 +398,7 @@ err: kfree(fence); return NULL; } +EXPORT_SYMBOL(sync_fence_merge); static void sync_fence_signal_pt(struct sync_pt *pt) { @@ -447,6 +458,7 @@ out: return err; } +EXPORT_SYMBOL(sync_fence_wait_async); int sync_fence_cancel_async(struct sync_fence *fence, struct sync_fence_waiter *waiter) @@ -475,6 +487,7 @@ int sync_fence_cancel_async(struct sync_fence *fence, spin_unlock_irqrestore(&fence->waiter_list_lock, flags); return ret; } +EXPORT_SYMBOL(sync_fence_cancel_async); int sync_fence_wait(struct sync_fence *fence, long timeout) { @@ -500,6 +513,7 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return 0; } +EXPORT_SYMBOL(sync_fence_wait); static int sync_fence_release(struct inode *inode, struct file *file) { -- cgit From 6e91f719865df97abf483b80b7778dc8a51011c4 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:07 -0800 Subject: staging: sw_sync: Export sw_sync API Needed to let modules link against sw_sync. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index 081e4d188fe9..d689760678c3 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -43,6 +44,7 @@ struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) return (struct sync_pt *)pt; } +EXPORT_SYMBOL(sw_sync_pt_create); static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt) { @@ -120,6 +122,7 @@ struct sw_sync_timeline *sw_sync_timeline_create(const char *name) return obj; } +EXPORT_SYMBOL(sw_sync_timeline_create); void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) { @@ -127,7 +130,7 @@ void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) sync_timeline_signal(&obj->obj); } - +EXPORT_SYMBOL(sw_sync_timeline_inc); #ifdef CONFIG_SW_SYNC_USER /* *WARNING* -- cgit From cc3c5cdc7bc16b78b6c59f0720542965a67d1c81 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:08 -0800 Subject: staging: sync: Reorder sync_fence_release Previously fence's pts were freed before the were the fence was removed from the global fence list. This led to a race with the debugfs support where it would iterate over sync_pts that had been freed. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 6739a8440bfc..2afbd69ab9f0 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -520,12 +520,12 @@ static int sync_fence_release(struct inode *inode, struct file *file) struct sync_fence *fence = file->private_data; unsigned long flags; - sync_fence_free_pts(fence); - spin_lock_irqsave(&sync_fence_list_lock, flags); list_del(&fence->sync_fence_list); spin_unlock_irqrestore(&sync_fence_list_lock, flags); + sync_fence_free_pts(fence); + kfree(fence); return 0; -- cgit From c6f668ce63943db48057b2e3ae8ef3ad5f9b29d2 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:09 -0800 Subject: staging: sync: Optimize fence merges If the two fences being merged contain sync_pts from the same timeline, those two pts will be collapsed into a single pt representing the latter of the two. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Whitespace fixes] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 52 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 2afbd69ab9f0..6cb7c883fad0 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -312,6 +312,56 @@ static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) return 0; } +static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src) +{ + struct list_head *src_pos, *dst_pos, *n; + + list_for_each(src_pos, &src->pt_list_head) { + struct sync_pt *src_pt = + container_of(src_pos, struct sync_pt, pt_list); + bool collapsed = false; + + list_for_each_safe(dst_pos, n, &dst->pt_list_head) { + struct sync_pt *dst_pt = + container_of(dst_pos, struct sync_pt, pt_list); + /* collapse two sync_pts on the same timeline + * to a single sync_pt that will signal at + * the later of the two + */ + if (dst_pt->parent == src_pt->parent) { + if (dst_pt->parent->ops->compare(dst_pt, src_pt) + == -1) { + struct sync_pt *new_pt = + sync_pt_dup(src_pt); + if (new_pt == NULL) + return -ENOMEM; + + new_pt->fence = dst; + list_replace(&dst_pt->pt_list, + &new_pt->pt_list); + sync_pt_activate(new_pt); + sync_pt_free(dst_pt); + } + collapsed = true; + break; + } + } + + if (!collapsed) { + struct sync_pt *new_pt = sync_pt_dup(src_pt); + + if (new_pt == NULL) + return -ENOMEM; + + new_pt->fence = dst; + list_add(&new_pt->pt_list, &dst->pt_list_head); + sync_pt_activate(new_pt); + } + } + + return 0; +} + static void sync_fence_free_pts(struct sync_fence *fence) { struct list_head *pos, *n; @@ -386,7 +436,7 @@ struct sync_fence *sync_fence_merge(const char *name, if (err < 0) goto err; - err = sync_fence_copy_pts(fence, b); + err = sync_fence_merge_pts(fence, b); if (err < 0) goto err; -- cgit From 01544170e1959dd261ceec6413674a528221669b Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:10 -0800 Subject: staging: sync: Add internal refcounting to fences If a fence is released while a timeline that one of it's pts is on is being signaled, it is possible for that fence to be deleted before it is signaled. This patch adds a refcount for internal references such as signaled pt processing. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 54 +++++++++++++++++++++++++++++++++++------- drivers/staging/android/sync.h | 5 ++++ 2 files changed, 51 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 6cb7c883fad0..7d4e9aaa5368 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -30,6 +30,7 @@ static void sync_fence_signal_pt(struct sync_pt *pt); static int _sync_pt_has_signaled(struct sync_pt *pt); +static void sync_fence_free(struct kref *kref); static LIST_HEAD(sync_timeline_list_head); static DEFINE_SPINLOCK(sync_timeline_list_lock); @@ -113,7 +114,7 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) { struct sync_timeline *obj = pt->parent; unsigned long flags; - bool needs_freeing; + bool needs_freeing = false; spin_lock_irqsave(&obj->active_list_lock, flags); if (!list_empty(&pt->active_list)) @@ -121,8 +122,11 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) spin_unlock_irqrestore(&obj->active_list_lock, flags); spin_lock_irqsave(&obj->child_list_lock, flags); - list_del(&pt->child_list); - needs_freeing = obj->destroyed && list_empty(&obj->child_list_head); + if (!list_empty(&pt->child_list)) { + list_del_init(&pt->child_list); + needs_freeing = obj->destroyed && + list_empty(&obj->child_list_head); + } spin_unlock_irqrestore(&obj->child_list_lock, flags); if (needs_freeing) @@ -141,18 +145,22 @@ void sync_timeline_signal(struct sync_timeline *obj) struct sync_pt *pt = container_of(pos, struct sync_pt, active_list); - if (_sync_pt_has_signaled(pt)) - list_move(pos, &signaled_pts); + if (_sync_pt_has_signaled(pt)) { + list_del_init(pos); + list_add(&pt->signaled_list, &signaled_pts); + kref_get(&pt->fence->kref); + } } spin_unlock_irqrestore(&obj->active_list_lock, flags); list_for_each_safe(pos, n, &signaled_pts) { struct sync_pt *pt = - container_of(pos, struct sync_pt, active_list); + container_of(pos, struct sync_pt, signaled_list); list_del_init(pos); sync_fence_signal_pt(pt); + kref_put(&pt->fence->kref, sync_fence_free); } } EXPORT_SYMBOL(sync_timeline_signal); @@ -253,6 +261,7 @@ static struct sync_fence *sync_fence_alloc(const char *name) if (fence->file == NULL) goto err; + kref_init(&fence->kref); strlcpy(fence->name, name, sizeof(fence->name)); INIT_LIST_HEAD(&fence->pt_list_head); @@ -362,6 +371,16 @@ static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src) return 0; } +static void sync_fence_detach_pts(struct sync_fence *fence) +{ + struct list_head *pos, *n; + + list_for_each_safe(pos, n, &fence->pt_list_head) { + struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); + sync_timeline_remove_pt(pt); + } +} + static void sync_fence_free_pts(struct sync_fence *fence) { struct list_head *pos, *n; @@ -565,18 +584,37 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) } EXPORT_SYMBOL(sync_fence_wait); +static void sync_fence_free(struct kref *kref) +{ + struct sync_fence *fence = container_of(kref, struct sync_fence, kref); + + sync_fence_free_pts(fence); + + kfree(fence); +} + static int sync_fence_release(struct inode *inode, struct file *file) { struct sync_fence *fence = file->private_data; unsigned long flags; + /* + * We need to remove all ways to access this fence before droping + * our ref. + * + * start with its membership in the global fence list + */ spin_lock_irqsave(&sync_fence_list_lock, flags); list_del(&fence->sync_fence_list); spin_unlock_irqrestore(&sync_fence_list_lock, flags); - sync_fence_free_pts(fence); + /* + * remove its pts from their parents so that sync_timeline_signal() + * can't reference the fence. + */ + sync_fence_detach_pts(fence); - kfree(fence); + kref_put(&fence->kref, sync_fence_free); return 0; } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 943f414b3f3b..00c9bae97065 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -16,6 +16,7 @@ #include #ifdef __KERNEL__ +#include #include #include #include @@ -109,6 +110,7 @@ struct sync_timeline { * @parent: sync_timeline to which this sync_pt belongs * @child_list: membership in sync_timeline.child_list_head * @active_list: membership in sync_timeline.active_list_head + * @signaled_list: membership in temorary signaled_list on stack * @fence: sync_fence to which the sync_pt belongs * @pt_list: membership in sync_fence.pt_list_head * @status: 1: signaled, 0:active, <0: error @@ -120,6 +122,7 @@ struct sync_pt { struct list_head child_list; struct list_head active_list; + struct list_head signaled_list; struct sync_fence *fence; struct list_head pt_list; @@ -133,6 +136,7 @@ struct sync_pt { /** * struct sync_fence - sync fence * @file: file representing this fence + * @kref: referenace count on fence. * @name: name of sync_fence. Useful for debugging * @pt_list_head: list of sync_pts in ths fence. immutable once fence * is created @@ -145,6 +149,7 @@ struct sync_pt { */ struct sync_fence { struct file *file; + struct kref kref; char name[32]; /* this list is immutable once the fence is created */ -- cgit From c5b86b7418f46220a623277718d6a909f520477b Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:11 -0800 Subject: staging: sync: Add reference counting to timelines If a timeline is destroyed while fences still hold pts on it, the reworked fence release handler can cause the timeline to be freed before all it's points are freed. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Squished in compiler warning fix] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 29 +++++++++++++---------------- drivers/staging/android/sync.h | 2 ++ 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 7d4e9aaa5368..61c27bdc5d0b 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -51,6 +51,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, if (obj == NULL) return NULL; + kref_init(&obj->kref); obj->ops = ops; strlcpy(obj->name, name, sizeof(obj->name)); @@ -68,8 +69,10 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, } EXPORT_SYMBOL(sync_timeline_create); -static void sync_timeline_free(struct sync_timeline *obj) +static void sync_timeline_free(struct kref *kref) { + struct sync_timeline *obj = + container_of(kref, struct sync_timeline, kref); unsigned long flags; if (obj->ops->release_obj) @@ -84,17 +87,14 @@ static void sync_timeline_free(struct sync_timeline *obj) void sync_timeline_destroy(struct sync_timeline *obj) { - unsigned long flags; - bool needs_freeing; - - spin_lock_irqsave(&obj->child_list_lock, flags); obj->destroyed = true; - needs_freeing = list_empty(&obj->child_list_head); - spin_unlock_irqrestore(&obj->child_list_lock, flags); - if (needs_freeing) - sync_timeline_free(obj); - else + /* + * If this is not the last reference, signal any children + * that their parent is going away. + */ + + if (!kref_put(&obj->kref, sync_timeline_free)) sync_timeline_signal(obj); } EXPORT_SYMBOL(sync_timeline_destroy); @@ -114,7 +114,6 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) { struct sync_timeline *obj = pt->parent; unsigned long flags; - bool needs_freeing = false; spin_lock_irqsave(&obj->active_list_lock, flags); if (!list_empty(&pt->active_list)) @@ -124,13 +123,8 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) spin_lock_irqsave(&obj->child_list_lock, flags); if (!list_empty(&pt->child_list)) { list_del_init(&pt->child_list); - needs_freeing = obj->destroyed && - list_empty(&obj->child_list_head); } spin_unlock_irqrestore(&obj->child_list_lock, flags); - - if (needs_freeing) - sync_timeline_free(obj); } void sync_timeline_signal(struct sync_timeline *obj) @@ -177,6 +171,7 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) return NULL; INIT_LIST_HEAD(&pt->active_list); + kref_get(&parent->kref); sync_timeline_add_pt(parent, pt); return pt; @@ -190,6 +185,8 @@ void sync_pt_free(struct sync_pt *pt) sync_timeline_remove_pt(pt); + kref_put(&pt->parent->kref, sync_timeline_free); + kfree(pt); } EXPORT_SYMBOL(sync_pt_free); diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 00c9bae97065..15863a6ebe51 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -80,6 +80,7 @@ struct sync_timeline_ops { /** * struct sync_timeline - sync object + * @kref: reference count on fence. * @ops: ops that define the implementaiton of the sync_timeline * @name: name of the sync_timeline. Useful for debugging * @destoryed: set when sync_timeline is destroyed @@ -90,6 +91,7 @@ struct sync_timeline_ops { * @sync_timeline_list: membership in global sync_timeline_list */ struct sync_timeline { + struct kref kref; const struct sync_timeline_ops *ops; char name[32]; -- cgit From 92ea915adb5565b522902a7b3f0a33ede16bb797 Mon Sep 17 00:00:00 2001 From: Rebecca Schultz Zavin Date: Thu, 28 Feb 2013 16:43:12 -0800 Subject: staging: sync: Fix error paths Check the return value of get_unused_fd to make sure a valid file descriptor is returned. Make sure to call put_unused_fd even if an error occurs before the fd can be used. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Rebecca Schultz Zavin Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 61c27bdc5d0b..c4a3c1d7946c 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -647,8 +647,13 @@ static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) struct sync_fence *fence2, *fence3; struct sync_merge_data data; - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; + if (fd < 0) + return fd; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { + err = -EFAULT; + goto err_put_fd; + } fence2 = sync_fence_fdget(data.fd2); if (fence2 == NULL) { -- cgit From 03e7a503561f6d0ef09c7ec73772a7a6f78417d3 Mon Sep 17 00:00:00 2001 From: Rebecca Schultz Zavin Date: Thu, 28 Feb 2013 16:43:13 -0800 Subject: staging: sw_sync: Fix error paths Check the return value of get_unused_fd to make sure a valid file descriptor is returned. Make sure to call put_unused_fd even if an error occurs before the fd can be used. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Rebecca Schultz Zavin Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index d689760678c3..d76889357e6c 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -170,8 +170,13 @@ long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) struct sync_fence *fence; struct sw_sync_create_fence_data data; - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; + if (fd < 0) + return fd; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { + err = -EFAULT; + goto err; + } pt = sw_sync_pt_create(obj, data.value); if (pt == NULL) { -- cgit From 3b640f5dd050f972439e5c67ba618a5377b61d34 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:14 -0800 Subject: staging: sync: Change wait timeout to mirror poll semantics Change wait timeout to act like poll Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message, squished typo-fix] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 6 +++--- drivers/staging/android/sync.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index c4a3c1d7946c..7fccfcdd9772 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -557,14 +557,14 @@ EXPORT_SYMBOL(sync_fence_cancel_async); int sync_fence_wait(struct sync_fence *fence, long timeout) { - int err; + int err = 0; - if (timeout) { + if (timeout > 0) { timeout = msecs_to_jiffies(timeout); err = wait_event_interruptible_timeout(fence->wq, fence->status != 0, timeout); - } else { + } else if (timeout < 0) { err = wait_event_interruptible(fence->wq, fence->status != 0); } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 15863a6ebe51..75ed5f1b75da 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -329,8 +329,8 @@ int sync_fence_cancel_async(struct sync_fence *fence, * @fence: fence to wait on * @tiemout: timeout in ms * - * Wait for @fence to be signaled or have an error. Waits indefintly - * if @timeout = 0 + * Wait for @fence to be signaled or have an error. Waits indefinitely + * if @timeout < 0 */ int sync_fence_wait(struct sync_fence *fence, long timeout); @@ -389,9 +389,9 @@ struct sync_fence_info_data { /** * DOC: SYNC_IOC_WAIT - wait for a fence to signal * - * pass timeout in milliseconds. + * pass timeout in milliseconds. Waits indefinitely timeout < 0. */ -#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __u32) +#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) /** * DOC: SYNC_IOC_MERGE - merge two fences -- cgit From f56388f3bd15a853d5718bf31c5d4dbc8f499cbe Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:15 -0800 Subject: staging: sync: Dump sync state to console on timeout If we hit a timeout, dump sync state to console Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message, whitespace fixups] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 7fccfcdd9772..d54fa8dd5341 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -31,6 +31,7 @@ static void sync_fence_signal_pt(struct sync_pt *pt); static int _sync_pt_has_signaled(struct sync_pt *pt); static void sync_fence_free(struct kref *kref); +static void sync_dump(void); static LIST_HEAD(sync_timeline_list_head); static DEFINE_SPINLOCK(sync_timeline_list_lock); @@ -574,8 +575,10 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) if (fence->status < 0) return fence->status; - if (fence->status == 0) + if (fence->status == 0) { + sync_dump(); return -ETIME; + } return 0; } @@ -914,7 +917,34 @@ static __init int sync_debugfs_init(void) debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops); return 0; } - late_initcall(sync_debugfs_init); +#define DUMP_CHUNK 256 +static char sync_dump_buf[64 * 1024]; +void sync_dump(void) +{ + struct seq_file s = { + .buf = sync_dump_buf, + .size = sizeof(sync_dump_buf) - 1, + }; + int i; + + sync_debugfs_show(&s, NULL); + + for (i = 0; i < s.count; i += DUMP_CHUNK) { + if ((s.count - i) > DUMP_CHUNK) { + char c = s.buf[i + DUMP_CHUNK]; + s.buf[i + DUMP_CHUNK] = 0; + pr_cont("%s", s.buf + i); + s.buf[i + DUMP_CHUNK] = c; + } else { + s.buf[s.count] = 0; + pr_cont("%s", s.buf + i); + } + } +} +#else +static void sync_dump(void) +{ +} #endif -- cgit From 1d5db2ce93089db91d7997927b4cfd92a88c5aad Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:16 -0800 Subject: staging: sync: Improve timeout dump messages Improve the output of the timeout dumps, including the fence pointer. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index d54fa8dd5341..92cdfe8031d1 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -576,6 +576,8 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return fence->status; if (fence->status == 0) { + pr_info("fence timeout on [%p] after %dms\n", fence, + jiffies_to_msecs(timeout)); sync_dump(); return -ETIME; } @@ -849,7 +851,8 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) struct list_head *pos; unsigned long flags; - seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status)); + seq_printf(s, "[%p] %s: %s\n", fence, fence->name, + sync_status_str(fence->status)); list_for_each(pos, &fence->pt_list_head) { struct sync_pt *pt = -- cgit From 7560645406b8341ab74644b505297e3e32fa6f3a Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:17 -0800 Subject: staging: sync: Dump sync state on fence errors When we get a bad status, dump sync state Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 92cdfe8031d1..36ffa2024875 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -572,8 +572,11 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) if (err < 0) return err; - if (fence->status < 0) + if (fence->status < 0) { + pr_info("fence error %d on [%p]\n", fence->status, fence); + sync_dump(); return fence->status; + } if (fence->status == 0) { pr_info("fence timeout on [%p] after %dms\n", fence, -- cgit From c679212dbfd060513e156133326122bf9f496579 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:18 -0800 Subject: staging: sync: Protect unlocked access to fence status Fence status is checked outside of locks in both sync_fence_wait and sync_fence_poll. This patch adds propper barrier protection in these cases to avoid seeing stale status. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 36ffa2024875..2394189c5958 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -556,6 +556,16 @@ int sync_fence_cancel_async(struct sync_fence *fence, } EXPORT_SYMBOL(sync_fence_cancel_async); +static bool sync_fence_check(struct sync_fence *fence) +{ + /* + * Make sure that reads to fence->status are ordered with the + * wait queue event triggering + */ + smp_rmb(); + return fence->status != 0; +} + int sync_fence_wait(struct sync_fence *fence, long timeout) { int err = 0; @@ -563,7 +573,7 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) if (timeout > 0) { timeout = msecs_to_jiffies(timeout); err = wait_event_interruptible_timeout(fence->wq, - fence->status != 0, + sync_fence_check(fence), timeout); } else if (timeout < 0) { err = wait_event_interruptible(fence->wq, fence->status != 0); @@ -630,6 +640,12 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait) poll_wait(file, &fence->wq, wait); + /* + * Make sure that reads to fence->status are ordered with the + * wait queue event triggering + */ + smp_rmb(); + if (fence->status == 1) return POLLIN; else if (fence->status < 0) -- cgit From eeb2f571639feedcfce3f1718b0c3fd85d796812 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:19 -0800 Subject: staging: sync: Update new fence status with sync_fence_signal_pt If a fence's pt is signaled before sync_fence_create is called, the fence will never transition into the signaled state. This also address a tiny race if a merged fence's pt after sync_fence_get_status checks it's status and before fence->status is updated. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 2394189c5958..889ca6eb9d42 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -295,6 +295,12 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt) list_add(&pt->pt_list, &fence->pt_list_head); sync_pt_activate(pt); + /* + * signal the fence in case pt was activated before + * sync_pt_activate(pt) was called + */ + sync_fence_signal_pt(pt); + return fence; } EXPORT_SYMBOL(sync_fence_create); @@ -457,7 +463,13 @@ struct sync_fence *sync_fence_merge(const char *name, if (err < 0) goto err; - fence->status = sync_fence_get_status(fence); + /* + * signal the fence in case one of it's pts were activated before + * they were activated + */ + sync_fence_signal_pt(list_first_entry(&fence->pt_list_head, + struct sync_pt, + pt_list)); return fence; err: -- cgit From 4b5de08a37e8189c039424c92ca76ff605cf1c7f Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:20 -0800 Subject: staging: sync: Use proper barriers when waiting indefinitely The previous fix only addressed waiting with a timeout. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 889ca6eb9d42..811cf65eb3eb 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -588,7 +588,8 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) sync_fence_check(fence), timeout); } else if (timeout < 0) { - err = wait_event_interruptible(fence->wq, fence->status != 0); + err = wait_event_interruptible(fence->wq, + sync_fence_check(fence)); } if (err < 0) -- cgit From dbd523905bac49da0643332e4eb0f2202e2acd06 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:21 -0800 Subject: staging: sync: Refactor sync debug printing Move driver callbacks to fill strings instead of using seq_files. This will allow those values to be used in a future tracepoint patch. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 18 ++++++++++++++++-- drivers/staging/android/sync.h | 19 +++++++++++++------ 2 files changed, 29 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 811cf65eb3eb..988f2339d70f 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -847,7 +847,17 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec); } - if (pt->parent->ops->print_pt) { + if (pt->parent->ops->timeline_value_str && + pt->parent->ops->pt_value_str) { + char value[64]; + pt->parent->ops->pt_value_str(pt, value, sizeof(value)); + seq_printf(s, ": %s", value); + if (fence) { + pt->parent->ops->timeline_value_str(pt->parent, value, + sizeof(value)); + seq_printf(s, " / %s", value); + } + } else if (pt->parent->ops->print_pt) { seq_printf(s, ": "); pt->parent->ops->print_pt(s, pt); } @@ -862,7 +872,11 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); - if (obj->ops->print_obj) { + if (obj->ops->timeline_value_str) { + char value[64]; + obj->ops->timeline_value_str(obj, value, sizeof(value)); + seq_printf(s, ": %s", value); + } else if (obj->ops->print_obj) { seq_printf(s, ": "); obj->ops->print_obj(s, obj); } diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 75ed5f1b75da..38ea986dc70f 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -40,14 +40,14 @@ struct sync_fence; * -1 if a will signabl before b * @free_pt: called before sync_pt is freed * @release_obj: called before sync_timeline is freed - * @print_obj: print aditional debug information about sync_timeline. - * should not print a newline - * @print_pt: print aditional debug information about sync_pt. - * should not print a newline + * @print_obj: deprecated + * @print_pt: deprecated * @fill_driver_data: write implmentation specific driver data to data. * should return an error if there is not enough room * as specified by size. This information is returned * to userspace by SYNC_IOC_FENCE_INFO. + * @timeline_value_str: fill str with the value of the sync_timeline's counter + * @pt_value_str: fill str with the value of the sync_pt */ struct sync_timeline_ops { const char *driver_name; @@ -67,15 +67,22 @@ struct sync_timeline_ops { /* optional */ void (*release_obj)(struct sync_timeline *sync_timeline); - /* optional */ + /* deprecated */ void (*print_obj)(struct seq_file *s, struct sync_timeline *sync_timeline); - /* optional */ + /* deprecated */ void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt); /* optional */ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); + + /* optional */ + void (*timeline_value_str)(struct sync_timeline *timeline, char *str, + int size); + + /* optional */ + void (*pt_value_str)(struct sync_pt *pt, char *str, int size); }; /** -- cgit From 135114a566c15dfe44fb8ca31e42dd215d627383 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:22 -0800 Subject: staging: sw_sync: Convert to use new value_str debug ops Switch from print_obj/print_pt to the new timeline_value_str and pt_value_str ops. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Add commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index d76889357e6c..68025a5401ae 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -72,23 +72,6 @@ static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) return sw_sync_cmp(pt_a->value, pt_b->value); } -static void sw_sync_print_obj(struct seq_file *s, - struct sync_timeline *sync_timeline) -{ - struct sw_sync_timeline *obj = (struct sw_sync_timeline *)sync_timeline; - - seq_printf(s, "%d", obj->value); -} - -static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt) -{ - struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; - struct sw_sync_timeline *obj = - (struct sw_sync_timeline *)sync_pt->parent; - - seq_printf(s, "%d / %d", pt->value, obj->value); -} - static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, void *data, int size) { @@ -102,14 +85,29 @@ static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, return sizeof(pt->value); } +static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline, + char *str, int size) +{ + struct sw_sync_timeline *timeline = + (struct sw_sync_timeline *)sync_timeline; + snprintf(str, size, "%d", timeline->value); +} + +static void sw_sync_pt_value_str(struct sync_pt *sync_pt, + char *str, int size) +{ + struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; + snprintf(str, size, "%d", pt->value); +} + struct sync_timeline_ops sw_sync_timeline_ops = { .driver_name = "sw_sync", .dup = sw_sync_pt_dup, .has_signaled = sw_sync_pt_has_signaled, .compare = sw_sync_pt_compare, - .print_obj = sw_sync_print_obj, - .print_pt = sw_sync_print_pt, .fill_driver_data = sw_sync_fill_driver_data, + .timeline_value_str = sw_sync_timeline_value_str, + .pt_value_str = sw_sync_pt_value_str, }; -- cgit From b699a644f82110e8e5a0f9b45ee1d3a3cd3e4586 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:23 -0800 Subject: staging: sync: Add tracepoint support Add support for tracepoints Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Whitespace changes, add commit message, move to staging] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 11 +++++ drivers/staging/android/trace/sync.h | 82 ++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 drivers/staging/android/trace/sync.h (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 988f2339d70f..1ddc40408167 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -28,6 +28,9 @@ #include "sync.h" +#define CREATE_TRACE_POINTS +#include "trace/sync.h" + static void sync_fence_signal_pt(struct sync_pt *pt); static int _sync_pt_has_signaled(struct sync_pt *pt); static void sync_fence_free(struct kref *kref); @@ -134,6 +137,8 @@ void sync_timeline_signal(struct sync_timeline *obj) LIST_HEAD(signaled_pts); struct list_head *pos, *n; + trace_sync_timeline(obj); + spin_lock_irqsave(&obj->active_list_lock, flags); list_for_each_safe(pos, n, &obj->active_list_head) { @@ -581,6 +586,11 @@ static bool sync_fence_check(struct sync_fence *fence) int sync_fence_wait(struct sync_fence *fence, long timeout) { int err = 0; + struct sync_pt *pt; + + trace_sync_wait(fence, 1); + list_for_each_entry(pt, &fence->pt_list_head, pt_list) + trace_sync_pt(pt); if (timeout > 0) { timeout = msecs_to_jiffies(timeout); @@ -591,6 +601,7 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) err = wait_event_interruptible(fence->wq, sync_fence_check(fence)); } + trace_sync_wait(fence, 0); if (err < 0) return err; diff --git a/drivers/staging/android/trace/sync.h b/drivers/staging/android/trace/sync.h new file mode 100644 index 000000000000..95462359ba57 --- /dev/null +++ b/drivers/staging/android/trace/sync.h @@ -0,0 +1,82 @@ +#undef TRACE_SYSTEM +#define TRACE_INCLUDE_PATH ../../drivers/staging/android/trace +#define TRACE_SYSTEM sync + +#if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYNC_H + +#include "../sync.h" +#include + +TRACE_EVENT(sync_timeline, + TP_PROTO(struct sync_timeline *timeline), + + TP_ARGS(timeline), + + TP_STRUCT__entry( + __string(name, timeline->name) + __array(char, value, 32) + ), + + TP_fast_assign( + __assign_str(name, timeline->name); + if (timeline->ops->timeline_value_str) { + timeline->ops->timeline_value_str(timeline, + __entry->value, + sizeof(__entry->value)); + } else { + __entry->value[0] = '\0'; + } + ), + + TP_printk("name=%s value=%s", __get_str(name), __entry->value) +); + +TRACE_EVENT(sync_wait, + TP_PROTO(struct sync_fence *fence, int begin), + + TP_ARGS(fence, begin), + + TP_STRUCT__entry( + __string(name, fence->name) + __field(s32, status) + __field(u32, begin) + ), + + TP_fast_assign( + __assign_str(name, fence->name); + __entry->status = fence->status; + __entry->begin = begin; + ), + + TP_printk("%s name=%s state=%d", __entry->begin ? "begin" : "end", + __get_str(name), __entry->status) +); + +TRACE_EVENT(sync_pt, + TP_PROTO(struct sync_pt *pt), + + TP_ARGS(pt), + + TP_STRUCT__entry( + __string(timeline, pt->parent->name) + __array(char, value, 32) + ), + + TP_fast_assign( + __assign_str(timeline, pt->parent->name); + if (pt->parent->ops->pt_value_str) { + pt->parent->ops->pt_value_str(pt, __entry->value, + sizeof(__entry->value)); + } else { + __entry->value[0] = '\0'; + } + ), + + TP_printk("name=%s value=%s", __get_str(timeline), __entry->value) +); + +#endif /* if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include -- cgit From 713648f0f137e149a1acade3278b621728291f37 Mon Sep 17 00:00:00 2001 From: Ørjan Eide Date: Thu, 28 Feb 2013 16:43:24 -0800 Subject: staging: sync: Fix race condition between merge and signal The copied sync_pt was activated immediately. If the sync_pt was signaled before the entire merge was completed, the new fence's pt_list could be iterated over while it is still in the process of being created. Moving the the sync_pt_activate call for all new sync_pts to after both the sync_fence_copy_pts and the sync_fence_merge_pts calls ensure that the pt_list is complete and immutable before it can be reached from the timeline's active list. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 1ddc40408167..bd18c755c779 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -324,7 +324,6 @@ static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src) new_pt->fence = dst; list_add(&new_pt->pt_list, &dst->pt_list_head); - sync_pt_activate(new_pt); } return 0; @@ -357,7 +356,6 @@ static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src) new_pt->fence = dst; list_replace(&dst_pt->pt_list, &new_pt->pt_list); - sync_pt_activate(new_pt); sync_pt_free(dst_pt); } collapsed = true; @@ -373,7 +371,6 @@ static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src) new_pt->fence = dst; list_add(&new_pt->pt_list, &dst->pt_list_head); - sync_pt_activate(new_pt); } } @@ -454,6 +451,7 @@ struct sync_fence *sync_fence_merge(const char *name, struct sync_fence *a, struct sync_fence *b) { struct sync_fence *fence; + struct list_head *pos; int err; fence = sync_fence_alloc(name); @@ -468,6 +466,12 @@ struct sync_fence *sync_fence_merge(const char *name, if (err < 0) goto err; + list_for_each(pos, &fence->pt_list_head) { + struct sync_pt *pt = + container_of(pos, struct sync_pt, pt_list); + sync_pt_activate(pt); + } + /* * signal the fence in case one of it's pts were activated before * they were activated -- cgit From 4c67d802119813f11fd7c71ca9e6d0f805ea414a Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Thu, 28 Feb 2013 16:43:25 -0800 Subject: staging: sync: Don't log wait timeouts when timeout = 0 If the timeout is zero, don't trip the timeout debugging Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Added commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index bd18c755c779..9b8b0e96b988 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -616,7 +616,7 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return fence->status; } - if (fence->status == 0) { + if (fence->status == 0 && timeout > 0) { pr_info("fence timeout on [%p] after %dms\n", fence, jiffies_to_msecs(timeout)); sync_dump(); -- cgit From 573632c2eaf87429a89490173f34682bb71f6883 Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Thu, 28 Feb 2013 16:43:26 -0800 Subject: staging: sync: Fix timeout = 0 wait behavior Fix wait behavior on timeout == 0 case Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Jamie Gennis [jstultz: Added commit message] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 9b8b0e96b988..b9bb974faacd 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -616,10 +616,12 @@ int sync_fence_wait(struct sync_fence *fence, long timeout) return fence->status; } - if (fence->status == 0 && timeout > 0) { - pr_info("fence timeout on [%p] after %dms\n", fence, - jiffies_to_msecs(timeout)); - sync_dump(); + if (fence->status == 0) { + if (timeout > 0) { + pr_info("fence timeout on [%p] after %dms\n", fence, + jiffies_to_msecs(timeout)); + sync_dump(); + } return -ETIME; } -- cgit From c56980744ed99994799850903627c4bbb5fed006 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:05:14 +0100 Subject: ACPI / scan: Introduce acpi_scan_match_handler() Introduce helper routine acpi_scan_match_handler() that will find the ACPI scan handler matching a given device ID, if there is one, and rework acpi_scan_attach_handler() to use the new routine (that routine will also be useful for other purposes going forward). Signed-off-by: Rafael J. Wysocki Acked-by: Yasuaki Ishimatsu Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/scan.c | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5e7e991717d7..cc1b0020478b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1536,6 +1536,25 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, return 0; } +static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, + const struct acpi_device_id **matchid) +{ + struct acpi_scan_handler *handler; + + list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) { + const struct acpi_device_id *devid; + + for (devid = handler->ids; devid->id[0]; devid++) + if (!strcmp((char *)devid->id, idstr)) { + if (matchid) + *matchid = devid; + + return handler; + } + } + return NULL; +} + static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, void *not_used, void **return_value) { @@ -1583,42 +1602,26 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } -static int acpi_scan_do_attach_handler(struct acpi_device *device, char *id) +static int acpi_scan_attach_handler(struct acpi_device *device) { - struct acpi_scan_handler *handler; + struct acpi_hardware_id *hwid; + int ret = 0; - list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) { + list_for_each_entry(hwid, &device->pnp.ids, list) { const struct acpi_device_id *devid; + struct acpi_scan_handler *handler; - for (devid = handler->ids; devid->id[0]; devid++) { - int ret; - - if (strcmp((char *)devid->id, id)) - continue; - + handler = acpi_scan_match_handler(hwid->id, &devid); + if (handler) { ret = handler->attach(device, devid); if (ret > 0) { device->handler = handler; - return ret; + break; } else if (ret < 0) { - return ret; + break; } } } - return 0; -} - -static int acpi_scan_attach_handler(struct acpi_device *device) -{ - struct acpi_hardware_id *hwid; - int ret = 0; - - list_for_each_entry(hwid, &device->pnp.ids, list) { - ret = acpi_scan_do_attach_handler(device, hwid->id); - if (ret) - break; - - } return ret; } -- cgit From a33ec399e9fc266ba20f9b71d693aa63658bf2aa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:05:29 +0100 Subject: ACPI / scan: Introduce common code for ACPI-based device hotplug Multiple drivers handling hotplug-capable ACPI device nodes install notify handlers covering the same types of events in a very similar way. Moreover, those handlers are installed in separate namespace walks, although that really should be done during namespace scans carried out by acpi_bus_scan(). This leads to substantial code duplication, unnecessary overhead and behavior that is hard to follow. For this reason, introduce common code in drivers/acpi/scan.c for handling hotplug-related notification and carrying out device insertion and eject operations in a generic fashion, such that it may be used by all of the relevant drivers in the future. To cover the existing differences between those drivers introduce struct acpi_hotplug_profile for representing collections of hotplug settings associated with different ACPI scan handlers that can be used by the drivers to make the common code reflect their current behavior. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/scan.c | 269 ++++++++++++++++++++++++++++++++++++++---------- include/acpi/acpi_bus.h | 12 +++ 2 files changed, 228 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index cc1b0020478b..de73fdf89598 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -107,32 +107,19 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); -/** - * acpi_bus_hot_remove_device: hot-remove a device and its children - * @context: struct acpi_eject_event pointer (freed in this func) - * - * Hot-remove a device and its children. This function frees up the - * memory space passed by arg context, so that the caller may call - * this function asynchronously through acpi_os_hotplug_execute(). - */ -void acpi_bus_hot_remove_device(void *context) +static int acpi_scan_hot_remove(struct acpi_device *device) { - struct acpi_eject_event *ej_event = context; - struct acpi_device *device = ej_event->device; acpi_handle handle = device->handle; - acpi_handle temp; + acpi_handle not_used; struct acpi_object_list arg_list; union acpi_object arg; - acpi_status status = AE_OK; - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ - - mutex_lock(&acpi_scan_lock); + acpi_status status; /* If there is no handle, the device node has been unregistered. */ - if (!device->handle) { + if (!handle) { dev_dbg(&device->dev, "ACPI handle missing\n"); put_device(&device->dev); - goto out; + return -EINVAL; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -143,7 +130,7 @@ void acpi_bus_hot_remove_device(void *context) put_device(&device->dev); device = NULL; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { + if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", ¬_used))) { arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; @@ -161,18 +148,158 @@ void acpi_bus_hot_remove_device(void *context) */ status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) + if (status == AE_NOT_FOUND) { + return -ENODEV; + } else { acpi_handle_warn(handle, "Eject failed\n"); + return -EIO; + } + } + return 0; +} - /* Tell the firmware the hot-remove operation has failed. */ - acpi_evaluate_hotplug_ost(handle, ej_event->event, - ost_code, NULL); +static void acpi_bus_device_eject(void *context) +{ + acpi_handle handle = context; + struct acpi_device *device = NULL; + struct acpi_scan_handler *handler; + u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; + + mutex_lock(&acpi_scan_lock); + + acpi_bus_get_device(handle, &device); + if (!device) + goto err_out; + + handler = device->handler; + if (!handler || !handler->hotplug.enabled) { + ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; + goto err_out; + } + acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, + ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); + if (handler->hotplug.mode == AHM_CONTAINER) { + device->flags.eject_pending = true; + kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); + } else { + int error; + + get_device(&device->dev); + error = acpi_scan_hot_remove(device); + if (error) + goto err_out; } out: mutex_unlock(&acpi_scan_lock); - kfree(context); return; + + err_out: + acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, ost_code, + NULL); + goto out; +} + +static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) +{ + struct acpi_device *device = NULL; + u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; + int error; + + mutex_lock(&acpi_scan_lock); + + acpi_bus_get_device(handle, &device); + if (device) { + dev_warn(&device->dev, "Attempt to re-insert\n"); + goto out; + } + acpi_evaluate_hotplug_ost(handle, ost_source, + ACPI_OST_SC_INSERT_IN_PROGRESS, NULL); + error = acpi_bus_scan(handle); + if (error) { + acpi_handle_warn(handle, "Namespace scan failure\n"); + goto out; + } + error = acpi_bus_get_device(handle, &device); + if (error) { + acpi_handle_warn(handle, "Missing device node object\n"); + goto out; + } + ost_code = ACPI_OST_SC_SUCCESS; + if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) + kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); + + out: + acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); + mutex_unlock(&acpi_scan_lock); +} + +static void acpi_scan_bus_check(void *context) +{ + acpi_scan_bus_device_check((acpi_handle)context, + ACPI_NOTIFY_BUS_CHECK); +} + +static void acpi_scan_device_check(void *context) +{ + acpi_scan_bus_device_check((acpi_handle)context, + ACPI_NOTIFY_DEVICE_CHECK); +} + +static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *not_used) +{ + acpi_osd_exec_callback callback; + acpi_status status; + + switch (type) { + case ACPI_NOTIFY_BUS_CHECK: + acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); + callback = acpi_scan_bus_check; + break; + case ACPI_NOTIFY_DEVICE_CHECK: + acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); + callback = acpi_scan_device_check; + break; + case ACPI_NOTIFY_EJECT_REQUEST: + acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); + callback = acpi_bus_device_eject; + break; + default: + /* non-hotplug event; possibly handled by other handler */ + return; + } + status = acpi_os_hotplug_execute(callback, handle); + if (ACPI_FAILURE(status)) + acpi_evaluate_hotplug_ost(handle, type, + ACPI_OST_SC_NON_SPECIFIC_FAILURE, + NULL); +} + +/** + * acpi_bus_hot_remove_device: hot-remove a device and its children + * @context: struct acpi_eject_event pointer (freed in this func) + * + * Hot-remove a device and its children. This function frees up the + * memory space passed by arg context, so that the caller may call + * this function asynchronously through acpi_os_hotplug_execute(). + */ +void acpi_bus_hot_remove_device(void *context) +{ + struct acpi_eject_event *ej_event = context; + struct acpi_device *device = ej_event->device; + acpi_handle handle = device->handle; + int error; + + mutex_lock(&acpi_scan_lock); + + error = acpi_scan_hot_remove(device); + if (error && handle) + acpi_evaluate_hotplug_ost(handle, ej_event->event, + ACPI_OST_SC_NON_SPECIFIC_FAILURE, + NULL); + + mutex_unlock(&acpi_scan_lock); + kfree(context); } EXPORT_SYMBOL(acpi_bus_hot_remove_device); @@ -206,51 +333,61 @@ static ssize_t acpi_eject_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - int ret = count; - acpi_status status; - acpi_object_type type = 0; struct acpi_device *acpi_device = to_acpi_device(d); struct acpi_eject_event *ej_event; + acpi_object_type not_used; + acpi_status status; + u32 ost_source; + int ret; - if ((!count) || (buf[0] != '1')) { + if (!count || buf[0] != '1') return -EINVAL; - } - if (!acpi_device->driver && !acpi_device->handler) { - ret = -ENODEV; - goto err; - } - status = acpi_get_type(acpi_device->handle, &type); - if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { - ret = -ENODEV; - goto err; - } - ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); - if (!ej_event) { - ret = -ENOMEM; - goto err; - } + if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) + && !acpi_device->driver) + return -ENODEV; + + status = acpi_get_type(acpi_device->handle, ¬_used); + if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) + return -ENODEV; + + mutex_lock(&acpi_scan_lock); - get_device(&acpi_device->dev); - ej_event->device = acpi_device; if (acpi_device->flags.eject_pending) { - /* event originated from ACPI eject notification */ - ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; + /* ACPI eject notification event. */ + ost_source = ACPI_NOTIFY_EJECT_REQUEST; acpi_device->flags.eject_pending = 0; } else { - /* event originated from user */ - ej_event->event = ACPI_OST_EC_OSPM_EJECT; - (void) acpi_evaluate_hotplug_ost(acpi_device->handle, - ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); + /* Eject initiated by user space. */ + ost_source = ACPI_OST_EC_OSPM_EJECT; } - + ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); + if (!ej_event) { + ret = -ENOMEM; + goto err_out; + } + acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, + ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); + ej_event->device = acpi_device; + ej_event->event = ost_source; + get_device(&acpi_device->dev); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); if (ACPI_FAILURE(status)) { put_device(&acpi_device->dev); kfree(ej_event); + ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; + goto err_out; } -err: + ret = count; + + out: + mutex_unlock(&acpi_scan_lock); return ret; + + err_out: + acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, + ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); + goto out; } static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); @@ -1555,6 +1692,30 @@ static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, return NULL; } +static void acpi_scan_init_hotplug(acpi_handle handle) +{ + struct acpi_device_info *info; + struct acpi_scan_handler *handler; + + if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) + return; + + if (!(info->valid & ACPI_VALID_HID)) { + kfree(info); + return; + } + + /* + * This relies on the fact that acpi_install_notify_handler() will not + * install the same notify handler routine twice for the same handle. + */ + handler = acpi_scan_match_handler(info->hardware_id.string, NULL); + kfree(info); + if (handler && handler->hotplug.enabled) + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + acpi_hotplug_notify_cb, NULL); +} + static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, void *not_used, void **return_value) { @@ -1577,6 +1738,8 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } + acpi_scan_init_hotplug(handle); + if (!(sta & ACPI_STA_DEVICE_PRESENT) && !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { struct acpi_device_wakeup wakeup; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e65278f560c4..f2c1d08a4798 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -88,11 +88,23 @@ struct acpi_device; * ----------------- */ +enum acpi_hotplug_mode { + AHM_GENERIC = 0, + AHM_CONTAINER, + AHM_COUNT +}; + +struct acpi_hotplug_profile { + bool enabled:1; + enum acpi_hotplug_mode mode; +}; + struct acpi_scan_handler { const struct acpi_device_id *ids; struct list_head list_node; int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id); void (*detach)(struct acpi_device *dev); + struct acpi_hotplug_profile hotplug; }; /* -- cgit From 68a67f6c78b80525d9b3c6672e7782de95e56a83 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:05:55 +0100 Subject: ACPI / container: Use common hotplug code Switch the ACPI container driver to using common device hotplug code introduced previously. This reduces the driver down to a trivial definition and registration of a struct acpi_scan_handler object. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/container.c | 146 ++++------------------------------------------- 1 file changed, 10 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5523ba7d764d..7f08dd68c524 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -1,12 +1,12 @@ /* - * acpi_container.c - ACPI Generic Container Driver - * ($Revision: ) + * container.c - ACPI Generic Container Driver * * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com) * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com) * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com) - * Copyright (C) 2004 Intel Corp. * Copyright (C) 2004 FUJITSU LIMITED + * Copyright (C) 2004, 2013 Intel Corp. + * Author: Rafael J. Wysocki * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -26,14 +26,9 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#include -#include -#include -#include -#include #include -#include -#include + +#include "internal.h" #define PREFIX "ACPI: " @@ -50,141 +45,20 @@ static const struct acpi_device_id container_device_ids[] = { static int container_device_attach(struct acpi_device *device, const struct acpi_device_id *not_used) { - /* - * FIXME: This is necessary, so that acpi_eject_store() doesn't return - * -ENODEV for containers. - */ + /* This is necessary for container hotplug to work. */ return 1; } static struct acpi_scan_handler container_device_handler = { .ids = container_device_ids, .attach = container_device_attach, + .hotplug = { + .enabled = true, + .mode = AHM_CONTAINER, + }, }; -static int is_device_present(acpi_handle handle) -{ - acpi_handle temp; - acpi_status status; - unsigned long long sta; - - - status = acpi_get_handle(handle, "_STA", &temp); - if (ACPI_FAILURE(status)) - return 1; /* _STA not found, assume device present */ - - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status)) - return 0; /* Firmware error */ - - return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); -} - -static void container_notify_cb(acpi_handle handle, u32 type, void *context) -{ - struct acpi_device *device = NULL; - int result; - int present; - acpi_status status; - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ - - acpi_scan_lock_acquire(); - - switch (type) { - case ACPI_NOTIFY_BUS_CHECK: - /* Fall through */ - case ACPI_NOTIFY_DEVICE_CHECK: - pr_debug("Container driver received %s event\n", - (type == ACPI_NOTIFY_BUS_CHECK) ? - "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); - - present = is_device_present(handle); - status = acpi_bus_get_device(handle, &device); - if (!present) { - if (ACPI_SUCCESS(status)) { - /* device exist and this is a remove request */ - device->flags.eject_pending = 1; - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - goto out; - } - break; - } - - if (!ACPI_FAILURE(status) || device) - break; - - result = acpi_bus_scan(handle); - if (result) { - acpi_handle_warn(handle, "Failed to add container\n"); - break; - } - result = acpi_bus_get_device(handle, &device); - if (result) { - acpi_handle_warn(handle, "Missing device object\n"); - break; - } - - kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); - ost_code = ACPI_OST_SC_SUCCESS; - break; - - case ACPI_NOTIFY_EJECT_REQUEST: - if (!acpi_bus_get_device(handle, &device) && device) { - device->flags.eject_pending = 1; - kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - goto out; - } - break; - - default: - /* non-hotplug event; possibly handled by other handler */ - goto out; - } - - /* Inform firmware that the hotplug operation has completed */ - (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); - - out: - acpi_scan_lock_release(); -} - -static bool is_container(acpi_handle handle) -{ - struct acpi_device_info *info; - bool ret = false; - - if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) - return false; - - if (info->valid & ACPI_VALID_HID) { - const struct acpi_device_id *id; - - for (id = container_device_ids; id->id[0]; id++) { - ret = !strcmp((char *)id->id, info->hardware_id.string); - if (ret) - break; - } - } - kfree(info); - return ret; -} - -static acpi_status acpi_container_register_notify_handler(acpi_handle handle, - u32 lvl, void *ctxt, - void **retv) -{ - if (is_container(handle)) - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - container_notify_cb, NULL); - - return AE_OK; -} - void __init acpi_container_init(void) { - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_container_register_notify_handler, NULL, - NULL, NULL); - acpi_scan_add_handler(&container_device_handler); } -- cgit From 4b59cc1fd6fd1dac1d4468b4f327ae9f59d1c0aa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:06:21 +0100 Subject: ACPI / scan: Introduce acpi_scan_handler_matching() Introduce new helper routine acpi_scan_handler_matching() for checking if the given ACPI scan handler matches a given device ID and rework acpi_scan_match_handler() to use the new routine (that routine will also be useful for other purposes in the future). Signed-off-by: Rafael J. Wysocki Acked-by: Yasuaki Ishimatsu Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/scan.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index de73fdf89598..45fbe95ba1f3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1673,22 +1673,32 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, return 0; } +static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, + char *idstr, + const struct acpi_device_id **matchid) +{ + const struct acpi_device_id *devid; + + for (devid = handler->ids; devid->id[0]; devid++) + if (!strcmp((char *)devid->id, idstr)) { + if (matchid) + *matchid = devid; + + return true; + } + + return false; +} + static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, const struct acpi_device_id **matchid) { struct acpi_scan_handler *handler; - list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) { - const struct acpi_device_id *devid; - - for (devid = handler->ids; devid->id[0]; devid++) - if (!strcmp((char *)devid->id, idstr)) { - if (matchid) - *matchid = devid; + list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) + if (acpi_scan_handler_matching(handler, idstr, matchid)) + return handler; - return handler; - } - } return NULL; } -- cgit From 3f8055c3583640ed3e4c81864dd76e06a7faa505 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:08:16 +0100 Subject: ACPI / hotplug: Introduce user space interface for hotplug profiles Introduce user space interface for manipulating hotplug profiles associated with ACPI scan handlers. The interface consists of sysfs directories under /sys/firmware/acpi/hotplug/, one for each hotplug profile, containing an attribute allowing user space to manipulate the enabled field of the corresponding profile. Namely, switching the enabled attribute from '0' to '1' will cause the common hotplug notify handler to be installed for all ACPI namespace objects representing devices matching the scan handler associated with the given hotplug profile (and analogously for the converse switch). Drivers willing to use the new user space interface should add their ACPI scan handlers with the help of new funtion acpi_scan_add_handler_with_hotplug(). Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Tested-by: Toshi Kani --- Documentation/ABI/testing/sysfs-firmware-acpi | 26 +++++++++++ drivers/acpi/internal.h | 6 +++ drivers/acpi/scan.c | 59 ++++++++++++++++++++++++ drivers/acpi/sysfs.c | 66 +++++++++++++++++++++++++++ include/acpi/acpi_bus.h | 7 +++ 5 files changed, 164 insertions(+) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi index dd930c8db41f..ce9bee98b43b 100644 --- a/Documentation/ABI/testing/sysfs-firmware-acpi +++ b/Documentation/ABI/testing/sysfs-firmware-acpi @@ -18,6 +18,32 @@ Description: yoffset: The number of pixels between the top of the screen and the top edge of the image. +What: /sys/firmware/acpi/hotplug/ +Date: February 2013 +Contact: Rafael J. Wysocki +Description: + There are separate hotplug profiles for different classes of + devices supported by ACPI, such as containers, memory modules, + processors, PCI root bridges etc. A hotplug profile for a given + class of devices is a collection of settings defining the way + that class of devices will be handled by the ACPI core hotplug + code. Those profiles are represented in sysfs as subdirectories + of /sys/firmware/acpi/hotplug/. + + The following setting is available to user space for each + hotplug profile: + + enabled: If set, the ACPI core will handle notifications of + hotplug events associated with the given class of + devices and will allow those devices to be ejected with + the help of the _EJ0 control method. Unsetting it + effectively disables hotplug for the correspoinding + class of devices. + + The value of the above attribute is an integer number: 1 (set) + or 0 (unset). Attempts to write any other values to it will + cause -EINVAL to be returned. + What: /sys/firmware/acpi/interrupts/ Date: February 2008 Contact: Len Brown diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 3c94a732b4b3..c708e4bad967 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -42,6 +42,12 @@ void acpi_container_init(void); static inline void acpi_container_init(void) {} #endif +void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, + const char *name); +int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, + const char *hotplug_profile_name); +void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val); + #ifdef CONFIG_DEBUG_FS extern struct dentry *acpi_debugfs_dir; int acpi_debugfs_init(void); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 45fbe95ba1f3..5458403c8249 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -63,6 +63,19 @@ int acpi_scan_add_handler(struct acpi_scan_handler *handler) return 0; } +int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, + const char *hotplug_profile_name) +{ + int error; + + error = acpi_scan_add_handler(handler); + if (error) + return error; + + acpi_sysfs_add_hotplug_profile(&handler->hotplug, hotplug_profile_name); + return 0; +} + /* * Creates hid/cid(s) string needed for modalias and uevent * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: @@ -1690,6 +1703,52 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, return false; } +static acpi_status acpi_scan_hotplug_modify(acpi_handle handle, + u32 lvl_not_used, void *data, + void **ret_not_used) +{ + struct acpi_scan_handler *handler = data; + struct acpi_device_info *info; + bool match = false; + + if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) + return AE_OK; + + if (info->valid & ACPI_VALID_HID) { + char *idstr = info->hardware_id.string; + match = acpi_scan_handler_matching(handler, idstr, NULL); + } + kfree(info); + if (!match) + return AE_OK; + + if (handler->hotplug.enabled) + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + acpi_hotplug_notify_cb, NULL); + else + acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + acpi_hotplug_notify_cb); + + return AE_OK; +} + +void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val) +{ + struct acpi_scan_handler *handler; + + if (!!hotplug->enabled == !!val) + return; + + mutex_lock(&acpi_scan_lock); + + hotplug->enabled = val; + handler = container_of(hotplug, struct acpi_scan_handler, hotplug); + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + acpi_scan_hotplug_modify, NULL, handler, NULL); + + mutex_unlock(&acpi_scan_lock); +} + static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, const struct acpi_device_id **matchid) { diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 41c0504470db..83db3a68a7ee 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -7,6 +7,8 @@ #include #include +#include "internal.h" + #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("sysfs"); @@ -249,6 +251,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); static LIST_HEAD(acpi_table_attr_list); static struct kobject *tables_kobj; static struct kobject *dynamic_tables_kobj; +static struct kobject *hotplug_kobj; struct acpi_table_attr { struct bin_attribute attr; @@ -716,6 +719,67 @@ acpi_show_profile(struct device *dev, struct device_attribute *attr, static const struct device_attribute pm_profile_attr = __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL); +static ssize_t hotplug_enabled_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj); + + return sprintf(buf, "%d\n", hotplug->enabled); +} + +static ssize_t hotplug_enabled_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t size) +{ + struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj); + unsigned int val; + + if (kstrtouint(buf, 10, &val) || val > 1) + return -EINVAL; + + acpi_scan_hotplug_enabled(hotplug, val); + return size; +} + +static struct kobj_attribute hotplug_enabled_attr = + __ATTR(enabled, S_IRUGO | S_IWUSR, hotplug_enabled_show, + hotplug_enabled_store); + +static struct attribute *hotplug_profile_attrs[] = { + &hotplug_enabled_attr.attr, + NULL +}; + +struct kobj_type acpi_hotplug_profile_ktype = { + .sysfs_ops = &kobj_sysfs_ops, + .default_attrs = hotplug_profile_attrs, +}; + +void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, + const char *name) +{ + int error; + + if (!hotplug_kobj) + goto err_out; + + kobject_init(&hotplug->kobj, &acpi_hotplug_profile_ktype); + error = kobject_set_name(&hotplug->kobj, "%s", name); + if (error) + goto err_out; + + hotplug->kobj.parent = hotplug_kobj; + error = kobject_add(&hotplug->kobj, hotplug_kobj, NULL); + if (error) + goto err_out; + + kobject_uevent(&hotplug->kobj, KOBJ_ADD); + return; + + err_out: + pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name); +} + int __init acpi_sysfs_init(void) { int result; @@ -723,6 +787,8 @@ int __init acpi_sysfs_init(void) result = acpi_tables_sysfs_init(); if (result) return result; + + hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj); result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr); return result; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f2c1d08a4798..533ef039c5e0 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -95,10 +95,17 @@ enum acpi_hotplug_mode { }; struct acpi_hotplug_profile { + struct kobject kobj; bool enabled:1; enum acpi_hotplug_mode mode; }; +static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile( + struct kobject *kobj) +{ + return container_of(kobj, struct acpi_hotplug_profile, kobj); +} + struct acpi_scan_handler { const struct acpi_device_id *ids; struct list_head list_node; -- cgit From 79917f34ac83140c20b06303b608ce6d740f0266 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:08:45 +0100 Subject: ACPI / container: Use hotplug profile user space interface Make the ACPI container driver register its ACPI scan handler object using acpi_scan_add_handler_with_hotplug() to allow user space to manipulate its hotplug profile attributes. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/container.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 7f08dd68c524..f9f8a08827fa 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -49,7 +49,7 @@ static int container_device_attach(struct acpi_device *device, return 1; } -static struct acpi_scan_handler container_device_handler = { +static struct acpi_scan_handler container_handler = { .ids = container_device_ids, .attach = container_device_attach, .hotplug = { @@ -60,5 +60,5 @@ static struct acpi_scan_handler container_device_handler = { void __init acpi_container_init(void) { - acpi_scan_add_handler(&container_device_handler); + acpi_scan_add_handler_with_hotplug(&container_handler, "container"); } -- cgit From 0a34764411aaab0114aa3f3656fda33a69a46d10 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 23:18:03 +0100 Subject: ACPI / scan: Make memory hotplug driver use struct acpi_scan_handler Make the ACPI memory hotplug driver use struct acpi_scan_handler for representing the object used to set up ACPI memory hotplug functionality and to remove hotplug memory ranges and data structures used by the driver before unregistering ACPI device nodes representing memory. Register the new struct acpi_scan_handler object with the help of acpi_scan_add_handler_with_hotplug() to allow user space to manipulate the attributes of the memory hotplug profile. This results in a significant reduction of the drvier's code size and removes some ACPI hotplug code duplication. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Tested-by: Toshi Kani --- drivers/acpi/Kconfig | 3 +- drivers/acpi/acpi_memhotplug.c | 309 +++++------------------------------------ drivers/acpi/internal.h | 5 + drivers/acpi/scan.c | 1 + 4 files changed, 45 insertions(+), 273 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 92ed9692c47e..da8082391f97 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -345,9 +345,8 @@ config ACPI_CONTAINER the module will be called container. config ACPI_HOTPLUG_MEMORY - tristate "Memory Hotplug" + bool "Memory Hotplug" depends on MEMORY_HOTPLUG - default n help This driver supports ACPI memory hotplug. The driver fields notifications on ACPI memory devices (PNP0C80), diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index da1f82b445e0..d4f2eb8a51ac 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -1,5 +1,7 @@ /* - * Copyright (C) 2004 Intel Corporation + * Copyright (C) 2004, 2013 Intel Corporation + * Author: Naveen B S + * Author: Rafael J. Wysocki * * All rights reserved. * @@ -25,14 +27,10 @@ * ranges. */ -#include -#include -#include -#include -#include -#include #include -#include +#include + +#include "internal.h" #define ACPI_MEMORY_DEVICE_CLASS "memory" #define ACPI_MEMORY_DEVICE_HID "PNP0C80" @@ -44,32 +42,28 @@ #define PREFIX "ACPI:memory_hp:" ACPI_MODULE_NAME("acpi_memhotplug"); -MODULE_AUTHOR("Naveen B S "); -MODULE_DESCRIPTION("Hotplug Mem Driver"); -MODULE_LICENSE("GPL"); /* Memory Device States */ #define MEMORY_INVALID_STATE 0 #define MEMORY_POWER_ON_STATE 1 #define MEMORY_POWER_OFF_STATE 2 -static int acpi_memory_device_add(struct acpi_device *device); -static int acpi_memory_device_remove(struct acpi_device *device); +static int acpi_memory_device_add(struct acpi_device *device, + const struct acpi_device_id *not_used); +static void acpi_memory_device_remove(struct acpi_device *device); static const struct acpi_device_id memory_device_ids[] = { {ACPI_MEMORY_DEVICE_HID, 0}, {"", 0}, }; -MODULE_DEVICE_TABLE(acpi, memory_device_ids); -static struct acpi_driver acpi_memory_device_driver = { - .name = "acpi_memhotplug", - .class = ACPI_MEMORY_DEVICE_CLASS, +static struct acpi_scan_handler memory_device_handler = { .ids = memory_device_ids, - .ops = { - .add = acpi_memory_device_add, - .remove = acpi_memory_device_remove, - }, + .attach = acpi_memory_device_add, + .detach = acpi_memory_device_remove, + .hotplug = { + .enabled = true, + }, }; struct acpi_memory_info { @@ -153,48 +147,6 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) return 0; } -static int acpi_memory_get_device(acpi_handle handle, - struct acpi_memory_device **mem_device) -{ - struct acpi_device *device = NULL; - int result = 0; - - acpi_scan_lock_acquire(); - - acpi_bus_get_device(handle, &device); - if (device) - goto end; - - /* - * Now add the notified device. This creates the acpi_device - * and invokes .add function - */ - result = acpi_bus_scan(handle); - if (result) { - acpi_handle_warn(handle, "ACPI namespace scan failed\n"); - result = -EINVAL; - goto out; - } - result = acpi_bus_get_device(handle, &device); - if (result) { - acpi_handle_warn(handle, "Missing device object\n"); - result = -EINVAL; - goto out; - } - - end: - *mem_device = acpi_driver_data(device); - if (!(*mem_device)) { - dev_err(&device->dev, "driver data not found\n"); - result = -ENODEV; - goto out; - } - - out: - acpi_scan_lock_release(); - return result; -} - static int acpi_memory_check_device(struct acpi_memory_device *mem_device) { unsigned long long current_status; @@ -310,95 +262,21 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) return result; } -static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) -{ - struct acpi_memory_device *mem_device; - struct acpi_device *device; - struct acpi_eject_event *ej_event = NULL; - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ - acpi_status status; - - switch (event) { - case ACPI_NOTIFY_BUS_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "\nReceived BUS CHECK notification for device\n")); - /* Fall Through */ - case ACPI_NOTIFY_DEVICE_CHECK: - if (event == ACPI_NOTIFY_DEVICE_CHECK) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "\nReceived DEVICE CHECK notification for device\n")); - if (acpi_memory_get_device(handle, &mem_device)) { - acpi_handle_err(handle, "Cannot find driver data\n"); - break; - } - - ost_code = ACPI_OST_SC_SUCCESS; - break; - - case ACPI_NOTIFY_EJECT_REQUEST: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "\nReceived EJECT REQUEST notification for device\n")); - - status = AE_ERROR; - acpi_scan_lock_acquire(); - - if (acpi_bus_get_device(handle, &device)) { - acpi_handle_err(handle, "Device doesn't exist\n"); - goto unlock; - } - mem_device = acpi_driver_data(device); - if (!mem_device) { - acpi_handle_err(handle, "Driver Data is NULL\n"); - goto unlock; - } - - ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); - if (!ej_event) { - pr_err(PREFIX "No memory, dropping EJECT\n"); - goto unlock; - } - - get_device(&device->dev); - ej_event->device = device; - ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; - /* The eject is carried out asynchronously. */ - status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, - ej_event); - if (ACPI_FAILURE(status)) { - put_device(&device->dev); - kfree(ej_event); - } - - unlock: - acpi_scan_lock_release(); - if (ACPI_SUCCESS(status)) - return; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - - /* non-hotplug event; possibly handled by other handler */ - return; - } - - /* Inform firmware that the hotplug operation has completed */ - (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); -} - static void acpi_memory_device_free(struct acpi_memory_device *mem_device) { if (!mem_device) return; acpi_memory_free_device_resources(mem_device); + mem_device->device->driver_data = NULL; kfree(mem_device); } -static int acpi_memory_device_add(struct acpi_device *device) +static int acpi_memory_device_add(struct acpi_device *device, + const struct acpi_device_id *not_used) { + struct acpi_memory_device *mem_device; int result; - struct acpi_memory_device *mem_device = NULL; - if (!device) return -EINVAL; @@ -423,147 +301,36 @@ static int acpi_memory_device_add(struct acpi_device *device) /* Set the device state */ mem_device->state = MEMORY_POWER_ON_STATE; - pr_debug("%s\n", acpi_device_name(device)); + result = acpi_memory_check_device(mem_device); + if (result) { + acpi_memory_device_free(mem_device); + return 0; + } - if (!acpi_memory_check_device(mem_device)) { - /* call add_memory func */ - result = acpi_memory_enable_device(mem_device); - if (result) { - dev_err(&device->dev, - "Error in acpi_memory_enable_device\n"); - acpi_memory_device_free(mem_device); - } + result = acpi_memory_enable_device(mem_device); + if (result) { + dev_err(&device->dev, "acpi_memory_enable_device() error\n"); + acpi_memory_device_free(mem_device); + return -ENODEV; } - return result; + + dev_dbg(&device->dev, "Memory device configured by ACPI\n"); + return 1; } -static int acpi_memory_device_remove(struct acpi_device *device) +static void acpi_memory_device_remove(struct acpi_device *device) { - struct acpi_memory_device *mem_device = NULL; - int result; + struct acpi_memory_device *mem_device; if (!device || !acpi_driver_data(device)) - return -EINVAL; + return; mem_device = acpi_driver_data(device); - - result = acpi_memory_remove_memory(mem_device); - if (result) - return result; - + acpi_memory_remove_memory(mem_device); acpi_memory_device_free(mem_device); - - return 0; -} - -/* - * Helper function to check for memory device - */ -static acpi_status is_memory_device(acpi_handle handle) -{ - char *hardware_id; - acpi_status status; - struct acpi_device_info *info; - - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) - return status; - - if (!(info->valid & ACPI_VALID_HID)) { - kfree(info); - return AE_ERROR; - } - - hardware_id = info->hardware_id.string; - if ((hardware_id == NULL) || - (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) - status = AE_ERROR; - - kfree(info); - return status; -} - -static acpi_status -acpi_memory_register_notify_handler(acpi_handle handle, - u32 level, void *ctxt, void **retv) -{ - acpi_status status; - - - status = is_memory_device(handle); - if (ACPI_FAILURE(status)) - return AE_OK; /* continue */ - - status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - acpi_memory_device_notify, NULL); - /* continue */ - return AE_OK; -} - -static acpi_status -acpi_memory_deregister_notify_handler(acpi_handle handle, - u32 level, void *ctxt, void **retv) -{ - acpi_status status; - - - status = is_memory_device(handle); - if (ACPI_FAILURE(status)) - return AE_OK; /* continue */ - - status = acpi_remove_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - acpi_memory_device_notify); - - return AE_OK; /* continue */ } -static int __init acpi_memory_device_init(void) +void __init acpi_memory_hotplug_init(void) { - int result; - acpi_status status; - - - result = acpi_bus_register_driver(&acpi_memory_device_driver); - - if (result < 0) - return -ENODEV; - - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - acpi_memory_register_notify_handler, NULL, - NULL, NULL); - - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed")); - acpi_bus_unregister_driver(&acpi_memory_device_driver); - return -ENODEV; - } - - return 0; -} - -static void __exit acpi_memory_device_exit(void) -{ - acpi_status status; - - - /* - * Adding this to un-install notification handlers for all the device - * handles. - */ - status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - acpi_memory_deregister_notify_handler, NULL, - NULL, NULL); - - if (ACPI_FAILURE(status)) - ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed")); - - acpi_bus_unregister_driver(&acpi_memory_device_driver); - - return; + acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); } - -module_init(acpi_memory_device_init); -module_exit(acpi_memory_device_exit); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index c708e4bad967..7215821ccb25 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -41,6 +41,11 @@ void acpi_container_init(void); #else static inline void acpi_container_init(void) {} #endif +#ifdef CONFIG_ACPI_HOTPLUG_MEMORY +void acpi_memory_hotplug_init(void); +#else +static inline void acpi_memory_hotplug_init(void) {} +#endif void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, const char *name); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5458403c8249..d69d77ab9c7e 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2026,6 +2026,7 @@ int __init acpi_scan_init(void) acpi_csrt_init(); acpi_container_init(); acpi_pci_slot_init(); + acpi_memory_hotplug_init(); mutex_lock(&acpi_scan_lock); /* -- cgit From 6e46daba562e44eee3009e4055a016a1c4bbb378 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:09 -0300 Subject: [media] em28xx: use v4l2_disable_ioctl() to disable ioctls VIDIOC_QUERYSTD, VIDIOC_G/S_STD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of checking the device type and returning -ENOTTY inside the ioctl functions, use v4l2_disable_ioctl() to disable the ioctls VIDIOC_QUERYSTD, VIDIOC_G_STD and VIDIOC_S_STD if the device is a camera. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 32bd7de5dec1..d1e6ba62e06c 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -959,8 +959,6 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) struct em28xx *dev = fh->dev; int rc; - if (dev->board.is_webcam) - return -ENOTTY; rc = check_dev(dev); if (rc < 0) return rc; @@ -976,8 +974,6 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) struct em28xx *dev = fh->dev; int rc; - if (dev->board.is_webcam) - return -ENOTTY; rc = check_dev(dev); if (rc < 0) return rc; @@ -994,8 +990,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) struct v4l2_format f; int rc; - if (dev->board.is_webcam) - return -ENOTTY; if (*norm == dev->norm) return 0; rc = check_dev(dev); @@ -1899,6 +1893,13 @@ int em28xx_register_analog_devices(struct em28xx *dev) dev->vdev->queue = &dev->vb_vidq; dev->vdev->queue->lock = &dev->vb_queue_lock; + /* disable inapplicable ioctls */ + if (dev->board.is_webcam) { + v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD); + v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD); + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD); + } + /* register v4l2 video video_device */ ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); -- cgit From 66df67b764f6013e557ac41aa9e9474c87a9a99b Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:10 -0300 Subject: [media] em28xx: disable tuner related ioctls for video and VBI devices without tuner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable the ioctls VIDIOC_G_TUNER, VIDIOC_S_TUNER, VIDIOC_G_FREQUENCY and VIDIOC_S_FREQUENCY for video and VBI devices without tuner. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index d1e6ba62e06c..a2216334d6f5 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1899,6 +1899,12 @@ int em28xx_register_analog_devices(struct em28xx *dev) v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD); v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD); } + if (dev->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER); + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER); + v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY); + } /* register v4l2 video video_device */ ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, @@ -1917,6 +1923,14 @@ int em28xx_register_analog_devices(struct em28xx *dev) dev->vbi_dev->queue = &dev->vb_vbiq; dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock; + /* disable inapplicable ioctls */ + if (dev->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER); + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER); + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY); + } + /* register v4l2 vbi video_device */ ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); -- cgit From c2dcef835e40f5a63b14f6eeada8b08b37da263f Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:11 -0300 Subject: [media] em28xx: use v4l2_disable_ioctl() to disable ioctls VIDIOC_G_AUDIO and VIDIOC_S_AUDIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of checking the device type and returning -EINVAL inside the ioctl functions, use v4l2_disable_ioctl() to disable the ioctls VIDIOC_G_AUDIO and VIDIOC_S_AUDIO if the device doesn't support audio. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index a2216334d6f5..346c92aca734 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1130,9 +1130,6 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - if (!dev->audio_mode.has_audio) - return -EINVAL; - switch (a->index) { case EM28XX_AMUX_VIDEO: strcpy(a->name, "Television"); @@ -1173,10 +1170,6 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - - if (!dev->audio_mode.has_audio) - return -EINVAL; - if (a->index >= MAX_EM28XX_INPUT) return -EINVAL; if (0 == INPUT(a->index)->type) @@ -1905,6 +1898,10 @@ int em28xx_register_analog_devices(struct em28xx *dev) v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY); v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY); } + if (!dev->audio_mode.has_audio) { + v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO); + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO); + } /* register v4l2 video video_device */ ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, @@ -1930,6 +1927,10 @@ int em28xx_register_analog_devices(struct em28xx *dev) v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY); v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY); } + if (!dev->audio_mode.has_audio) { + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO); + v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO); + } /* register v4l2 vbi video_device */ ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -- cgit From 3bc85cce365ca12f98aec150160ed0b84e1af732 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:12 -0300 Subject: [media] em28xx: use v4l2_disable_ioctl() to disable ioctl VIDIOC_S_PARM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of checking the device type and returning -ENOTTY inside the ioctl function, use v4l2_disable_ioctl() to disable the ioctl VIDIOC_S_PARM if the device is not a camera. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 346c92aca734..2f7c5abad75e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1044,9 +1044,6 @@ static int vidioc_s_parm(struct file *file, void *priv, struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - if (!dev->board.is_webcam) - return -ENOTTY; - if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1891,6 +1888,8 @@ int em28xx_register_analog_devices(struct em28xx *dev) v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD); v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD); v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD); + } else { + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM); } if (dev->tuner_type == TUNER_ABSENT) { v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER); -- cgit From 83c8bcce0629239ff9de6625ea74e16a10e8c1f0 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:13 -0300 Subject: [media] em28xx: disable ioctl VIDIOC_S_PARM for VBI devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VIDIOC_S_PARM doesn't make sense for VBI device nodes, because we don't support selecting the number of read buffers to use. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 2f7c5abad75e..c1f6c59f53aa 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1920,6 +1920,7 @@ int em28xx_register_analog_devices(struct em28xx *dev) dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock; /* disable inapplicable ioctls */ + v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM); if (dev->tuner_type == TUNER_ABSENT) { v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER); v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER); -- cgit From 1fe184a6accc781e814f15342513794266d73d06 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:14 -0300 Subject: [media] em28xx: make ioctls VIDIOC_G/S_PARM working for VBI devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the current code V4L2_BUF_TYPE_VIDEO_CAPTURE is accepted only, but for VBI devices only buffer type V4L2_BUF_TYPE_VBI_CAPTURE is used/valid. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index c1f6c59f53aa..e13b777d2cbf 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1024,9 +1024,6 @@ static int vidioc_g_parm(struct file *file, void *priv, struct em28xx *dev = fh->dev; int rc = 0; - if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - p->parm.capture.readbuffers = EM28XX_MIN_BUF; if (dev->board.is_webcam) rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, @@ -1044,9 +1041,6 @@ static int vidioc_s_parm(struct file *file, void *priv, struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - p->parm.capture.readbuffers = EM28XX_MIN_BUF; return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p); } -- cgit From 430101bd8b9184496c57a8bffe9fc9d1c2b7732f Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:15 -0300 Subject: [media] em28xx: remove ioctl VIDIOC_CROPCAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The em28xx driver doesn't support the VIDIOC_G_CROP and VIDIOC_S_CROP ioctls, so VIDIOC_CROPCAP is useless and has the potential to confuse applications, because it can be interpreted as indicator for cropping support. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index e13b777d2cbf..ea73dd4e428a 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1364,26 +1364,6 @@ static int vidioc_s_register(struct file *file, void *priv, #endif -static int vidioc_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cc) -{ - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh->dev; - - if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - cc->bounds.left = 0; - cc->bounds.top = 0; - cc->bounds.width = dev->width; - cc->bounds.height = dev->height; - cc->defrect = cc->bounds; - cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ - cc->pixelaspect.denominator = 59; - - return 0; -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1731,7 +1711,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, - .vidioc_cropcap = vidioc_cropcap, .vidioc_reqbufs = vb2_ioctl_reqbufs, .vidioc_create_bufs = vb2_ioctl_create_bufs, -- cgit From aab346187662b3f2a11b1120896f688299c8ba43 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:16 -0300 Subject: [media] em28xx: get rid of duplicate function vidioc_s_fmt_vbi_cap() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vidioc_s_fmt_vbi_cap() is a 100% duplicate of vidioc_g_fmt_vbi_cap() and therefore can be removed. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index ea73dd4e428a..8ddf3009c794 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1480,35 +1480,6 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, - struct v4l2_format *format) -{ - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh->dev; - - format->fmt.vbi.samples_per_line = dev->vbi_width; - format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - format->fmt.vbi.offset = 0; - format->fmt.vbi.flags = 0; - format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; - format->fmt.vbi.count[0] = dev->vbi_height; - format->fmt.vbi.count[1] = dev->vbi_height; - memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved)); - - /* Varies by video standard (NTSC, PAL, etc.) */ - if (dev->norm & V4L2_STD_525_60) { - /* NTSC */ - format->fmt.vbi.start[0] = 10; - format->fmt.vbi.start[1] = 273; - } else if (dev->norm & V4L2_STD_625_50) { - /* PAL */ - format->fmt.vbi.start[0] = 6; - format->fmt.vbi.start[1] = 318; - } - - return 0; -} - /* ----------------------------------------------------------- */ /* RADIO ESPECIFIC IOCTLS */ /* ----------------------------------------------------------- */ @@ -1707,7 +1678,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, - .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, + .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, -- cgit From 7a92de6a4c0c99c97df3f016860fe9597d4284b9 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:17 -0300 Subject: [media] em28xx: VIDIOC_G_TUNER: remove unneeded setting of tuner type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tuner type is set by the v4l2-core based on the device type. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 8ddf3009c794..e7f6f5745302 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1493,7 +1493,6 @@ static int radio_g_tuner(struct file *file, void *priv, return -EINVAL; strcpy(t->name, "Radio"); - t->type = V4L2_TUNER_RADIO; v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); -- cgit From eb17cee275ac5d0bcd31ed2d205051088140ce49 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:18 -0300 Subject: [media] em28xx: remove obsolete device state checks from the ioctl functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v4l2_device_disconnect() is called when the device is disconnected, so that the v4l2-core rejects all ioctl calls. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 43 --------------------------------- 1 file changed, 43 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index e7f6f5745302..c214305300db 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -799,15 +799,6 @@ const struct v4l2_ctrl_ops em28xx_ctrl_ops = { .s_ctrl = em28xx_s_ctrl, }; -static int check_dev(struct em28xx *dev) -{ - if (dev->disconnected) { - em28xx_errdev("v4l2 ioctl: device not present\n"); - return -ENODEV; - } - return 0; -} - static void get_scale(struct em28xx *dev, unsigned int width, unsigned int height, unsigned int *hscale, unsigned int *vscale) @@ -957,11 +948,6 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; *norm = dev->norm; @@ -972,11 +958,6 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm); @@ -988,13 +969,9 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; struct v4l2_format f; - int rc; if (*norm == dev->norm) return 0; - rc = check_dev(dev); - if (rc < 0) - return rc; if (dev->streaming_users > 0) return -EBUSY; @@ -1101,11 +1078,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; if (i >= MAX_EM28XX_INPUT) return -EINVAL; @@ -1180,11 +1152,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; if (0 != t->index) return -EINVAL; @@ -1200,11 +1167,6 @@ static int vidioc_s_tuner(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; if (0 != t->index) return -EINVAL; @@ -1231,11 +1193,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; if (0 != f->tuner) return -EINVAL; -- cgit From 35deba32e4bfd5fc16358f960ceb46be097ab3a2 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:19 -0300 Subject: [media] em28xx: make ioctl VIDIOC_DBG_G_CHIP_IDENT available without CONFIG_VIDEO_ADV_DEBUG selected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VIDIOC_DBG_G_CHIP_IDENT is a "normal" and not an "advanced" debug functionality. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index c214305300db..2ee2957db4bf 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1204,19 +1204,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, return 0; } -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int em28xx_reg_len(int reg) -{ - switch (reg) { - case EM28XX_R40_AC97LSB: - case EM28XX_R30_HSCALELOW: - case EM28XX_R32_VSCALELOW: - return 2; - default: - return 1; - } -} - static int vidioc_g_chip_ident(struct file *file, void *priv, struct v4l2_dbg_chip_ident *chip) { @@ -1239,6 +1226,18 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int em28xx_reg_len(int reg) +{ + switch (reg) { + case EM28XX_R40_AC97LSB: + case EM28XX_R30_HSCALELOW: + case EM28XX_R32_VSCALELOW: + return 2; + default: + return 1; + } +} static int vidioc_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) @@ -1662,10 +1661,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_frequency = vidioc_s_frequency, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, - .vidioc_g_chip_ident = vidioc_g_chip_ident, #endif }; -- cgit From fff459e36f70b96f9baf0e538d4bcf9ccddef72a Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:20 -0300 Subject: [media] em28xx: make ioctl VIDIOC_DBG_G_CHIP_IDENT available for radio devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 2ee2957db4bf..6d261232278c 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1691,6 +1691,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_s_frequency = vidioc_s_frequency, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, -- cgit From 84e902aa05b628b940c4a17ea2c92ec4fbcffc18 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Thu, 7 Feb 2013 13:39:21 -0300 Subject: [media] em28xx: do not claim VBI support if the device is a camera MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids registering a VBI device and streaming in VBI-mode if the device is a camera. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index aaedd11791f2..26d249971a01 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -681,6 +681,11 @@ int em28xx_vbi_supported(struct em28xx *dev) if (disable_vbi == 1) return 0; + if (dev->board.is_webcam) + return 0; + + /* FIXME: check subdevices for VBI support */ + if (dev->chip_id == CHIP_ID_EM2860 || dev->chip_id == CHIP_ID_EM2883) return 1; -- cgit From 8168532712fe0c662f22180755fb89103a2e6558 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 10 Feb 2013 16:05:11 -0300 Subject: [media] em28xx: introduce #define for maximum supported scaling values (register 0x30-0x33) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maximum supported scaling value for registers 0x30+0x31 (horizontal scaling) and 0x32+0x33 (vertical scaling) is 0x3fff, which corresponds to 20% of the input frame size. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-reg.h | 2 ++ drivers/media/usb/em28xx/em28xx-video.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 885089e22bcd..0a3cb04fbeae 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -152,6 +152,8 @@ #define EM28XX_R31_HSCALEHIGH 0x31 #define EM28XX_R32_VSCALELOW 0x32 #define EM28XX_R33_VSCALEHIGH 0x33 +#define EM28XX_HVSCALE_MAX 0x3fff /* => 20% */ + #define EM28XX_R34_VBI_START_H 0x34 #define EM28XX_R35_VBI_START_V 0x35 #define EM28XX_R36_VBI_WIDTH 0x36 diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 6d261232278c..9451e1ed0ec8 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -807,12 +807,12 @@ static void get_scale(struct em28xx *dev, unsigned int maxh = norm_maxh(dev); *hscale = (((unsigned long)maxw) << 12) / width - 4096L; - if (*hscale >= 0x4000) - *hscale = 0x3fff; + if (*hscale > EM28XX_HVSCALE_MAX) + *hscale = EM28XX_HVSCALE_MAX; *vscale = (((unsigned long)maxh) << 12) / height - 4096L; - if (*vscale >= 0x4000) - *vscale = 0x3fff; + if (*vscale > EM28XX_HVSCALE_MAX) + *vscale = EM28XX_HVSCALE_MAX; } /* ------------------------------------------------------------------ -- cgit From 6b09a21cbc01521dcc4855484e2c0ffe8aab2a78 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 10 Feb 2013 16:05:12 -0300 Subject: [media] em28xx: rename function get_scale() to size_to_scale() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 9451e1ed0ec8..197823cfd263 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -799,7 +799,7 @@ const struct v4l2_ctrl_ops em28xx_ctrl_ops = { .s_ctrl = em28xx_s_ctrl, }; -static void get_scale(struct em28xx *dev, +static void size_to_scale(struct em28xx *dev, unsigned int width, unsigned int height, unsigned int *hscale, unsigned int *vscale) { @@ -889,7 +889,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 1, 0); } - get_scale(dev, width, height, &hscale, &vscale); + size_to_scale(dev, width, height, &hscale, &vscale); width = (((unsigned long)maxw) << 12) / (hscale + 4096L); height = (((unsigned long)maxh) << 12) / (vscale + 4096L); @@ -923,7 +923,7 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, dev->height = height; /* set new image size */ - get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); + size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); em28xx_resolution_set(dev); @@ -986,7 +986,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) /* set new image size */ dev->width = f.fmt.pix.width; dev->height = f.fmt.pix.height; - get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); + size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); em28xx_resolution_set(dev); v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); -- cgit From b83741383565f675bd13861fc39cfacdd68d18c1 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 10 Feb 2013 16:05:13 -0300 Subject: [media] em28xx: add function scale_to_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 197823cfd263..f745617aeece 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -815,6 +815,17 @@ static void size_to_scale(struct em28xx *dev, *vscale = EM28XX_HVSCALE_MAX; } +static void scale_to_size(struct em28xx *dev, + unsigned int hscale, unsigned int vscale, + unsigned int *width, unsigned int *height) +{ + unsigned int maxw = norm_maxw(dev); + unsigned int maxh = norm_maxh(dev); + + *width = (((unsigned long)maxw) << 12) / (hscale + 4096L); + *height = (((unsigned long)maxh) << 12) / (vscale + 4096L); +} + /* ------------------------------------------------------------------ IOCTL vidioc handling ------------------------------------------------------------------*/ @@ -890,9 +901,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } size_to_scale(dev, width, height, &hscale, &vscale); - - width = (((unsigned long)maxw) << 12) / (hscale + 4096L); - height = (((unsigned long)maxh) << 12) / (vscale + 4096L); + scale_to_size(dev, hscale, hscale, &width, &height); f->fmt.pix.width = width; f->fmt.pix.height = height; -- cgit From 6c3598e641d447edbaaa05ff0d4cd6da152dc3f4 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 10 Feb 2013 16:05:14 -0300 Subject: [media] em28xx: VIDIOC_ENUM_FRAMESIZES: consider the scaler limits when calculating the minimum frame size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Output resolutions <=20% of the input resolution exceed the capabilities of the scaler. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index f745617aeece..86fd90727f56 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1405,8 +1405,12 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, /* Report a continuous range */ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fsize->stepwise.min_width = 48; - fsize->stepwise.min_height = 32; + scale_to_size(dev, EM28XX_HVSCALE_MAX, EM28XX_HVSCALE_MAX, + &fsize->stepwise.min_width, &fsize->stepwise.min_height); + if (fsize->stepwise.min_width < 48) + fsize->stepwise.min_width = 48; + if (fsize->stepwise.min_height < 38) + fsize->stepwise.min_height = 38; fsize->stepwise.max_width = maxw; fsize->stepwise.max_height = maxh; fsize->stepwise.step_width = 1; -- cgit From 511ffe920b483340d61bb707ee96e7d6a9e6b13b Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 15 Feb 2013 14:38:29 -0300 Subject: [media] em28xx: remove unused image quality control functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx.h | 66 --------------------------------------- 1 file changed, 66 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 5f0b2c59e846..6a9e3e1b9929 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -744,72 +744,6 @@ static inline int em28xx_compression_disable(struct em28xx *dev) return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); } -static inline int em28xx_contrast_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R20_YGAIN) & 0x1f; -} - -static inline int em28xx_brightness_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R21_YOFFSET); -} - -static inline int em28xx_saturation_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R22_UVGAIN) & 0x1f; -} - -static inline int em28xx_u_balance_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R23_UOFFSET); -} - -static inline int em28xx_v_balance_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R24_VOFFSET); -} - -static inline int em28xx_gamma_get(struct em28xx *dev) -{ - return em28xx_read_reg(dev, EM28XX_R14_GAMMA) & 0x3f; -} - -static inline int em28xx_contrast_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R20_YGAIN, &tmp, 1); -} - -static inline int em28xx_brightness_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R21_YOFFSET, &tmp, 1); -} - -static inline int em28xx_saturation_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R22_UVGAIN, &tmp, 1); -} - -static inline int em28xx_u_balance_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R23_UOFFSET, &tmp, 1); -} - -static inline int em28xx_v_balance_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R24_VOFFSET, &tmp, 1); -} - -static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) -{ - u8 tmp = (u8) val; - return em28xx_write_regs(dev, EM28XX_R14_GAMMA, &tmp, 1); -} - /*FIXME: maxw should be dependent of alt mode */ static inline unsigned int norm_maxw(struct em28xx *dev) { -- cgit From 7960205066632fea0245eda65278039d0f4f791c Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 15 Feb 2013 14:38:30 -0300 Subject: [media] em28xx: remove unused ac97 v4l2_ctrl_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 6a9e3e1b9929..7dc27b58a4d7 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -491,8 +491,6 @@ struct em28xx { struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; - /* provides ac97 mute and volume overrides */ - struct v4l2_ctrl_handler ac97_ctrl_handler; struct em28xx_board board; /* Webcam specific fields */ -- cgit From 43a5e08d0006b99308f0a1c9c14cf5551df35385 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 15 Feb 2013 14:38:31 -0300 Subject: [media] em28xx: introduce #defines for the image quality default settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image quality default values will be used in at least two different places and by using #defines we make sure that they are always consistent. Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-core.c | 12 ++++++------ drivers/media/usb/em28xx/em28xx-reg.h | 23 +++++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 26d249971a01..b2dcb3d1342d 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -607,12 +607,12 @@ EXPORT_SYMBOL_GPL(em28xx_audio_setup); int em28xx_colorlevels_set_default(struct em28xx *dev) { - em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */ - em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */ - em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */ - em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00); - em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00); - em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00); + em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT); + em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT); + em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT); + em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT); + em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT); + em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT); em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20); em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20); diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 0a3cb04fbeae..8fd3c7f80201 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -120,12 +120,23 @@ #define EM28XX_R1E_CWIDTH 0x1e #define EM28XX_R1F_CHEIGHT 0x1f -#define EM28XX_R20_YGAIN 0x20 -#define EM28XX_R21_YOFFSET 0x21 -#define EM28XX_R22_UVGAIN 0x22 -#define EM28XX_R23_UOFFSET 0x23 -#define EM28XX_R24_VOFFSET 0x24 -#define EM28XX_R25_SHARPNESS 0x25 +#define EM28XX_R20_YGAIN 0x20 /* contrast [0:4] */ +#define CONTRAST_DEFAULT 0x10 + +#define EM28XX_R21_YOFFSET 0x21 /* brightness */ /* signed */ +#define BRIGHTNESS_DEFAULT 0x00 + +#define EM28XX_R22_UVGAIN 0x22 /* saturation [0:4] */ +#define SATURATION_DEFAULT 0x10 + +#define EM28XX_R23_UOFFSET 0x23 /* blue balance */ /* signed */ +#define BLUE_BALANCE_DEFAULT 0x00 + +#define EM28XX_R24_VOFFSET 0x24 /* red balance */ /* signed */ +#define RED_BALANCE_DEFAULT 0x00 + +#define EM28XX_R25_SHARPNESS 0x25 /* sharpness [0:4] */ +#define SHARPNESS_DEFAULT 0x00 #define EM28XX_R26_COMPR 0x26 #define EM28XX_R27_OUTFMT 0x27 -- cgit From 8f8b113a030be7456dc5159bec879ff041a5a276 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 15 Feb 2013 14:38:32 -0300 Subject: [media] em28xx: add image quality bridge controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the image quality bridge controls contrast, brightness, saturation, blue balance, red balance and sharpness. These controls are enabled only if no subdevice provides them. Tested with the following devices: "Terratec Cinergy 200 USB" "Hauppauge HVR-900" "SilverCrest 1.3MPix webcam" "Hauppauge WinTV USB2" "Speedlink VAD Laplace webcam" Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 7 +--- drivers/media/usb/em28xx/em28xx-video.c | 58 +++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 54a03b20de6e..9332d051bde9 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3091,7 +3091,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, return retval; } - v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_handler_init(hdl, 8); dev->v4l2_dev.ctrl_handler = hdl; /* register i2c bus */ @@ -3160,11 +3160,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, msleep(3); } - v4l2_ctrl_handler_setup(&dev->ctrl_handler); - retval = dev->ctrl_handler.error; - if (retval) - goto fail; - retval = em28xx_register_analog_devices(dev); if (retval < 0) { goto fail; diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 86fd90727f56..48b937d1b063 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -782,17 +782,38 @@ void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl) { struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler); + int ret = -EINVAL; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: dev->mute = ctrl->val; + ret = em28xx_audio_analog_set(dev); break; case V4L2_CID_AUDIO_VOLUME: dev->volume = ctrl->val; + ret = em28xx_audio_analog_set(dev); + break; + case V4L2_CID_CONTRAST: + ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val); + break; + case V4L2_CID_BRIGHTNESS: + ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val); + break; + case V4L2_CID_SATURATION: + ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val); + break; + case V4L2_CID_BLUE_BALANCE: + ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val); + break; + case V4L2_CID_RED_BALANCE: + ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val); + break; + case V4L2_CID_SHARPNESS: + ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val); break; } - return em28xx_audio_analog_set(dev); + return (ret < 0) ? ret : 0; } const struct v4l2_ctrl_ops em28xx_ctrl_ops = { @@ -1784,9 +1805,42 @@ int em28xx_register_analog_devices(struct em28xx *dev) (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_set_outfmt(dev); - em28xx_colorlevels_set_default(dev); em28xx_compression_disable(dev); + /* Add image controls */ + /* NOTE: at this point, the subdevices are already registered, so bridge + * controls are only added/enabled when no subdevice provides them */ + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_CONTRAST, + 0, 0x1f, 1, CONTRAST_DEFAULT); + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_BRIGHTNESS, + -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_SATURATION, + 0, 0x1f, 1, SATURATION_DEFAULT); + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_BLUE_BALANCE, + -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_RED_BALANCE, + -0x30, 0x30, 1, RED_BALANCE_DEFAULT); + if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS)) + v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, + V4L2_CID_SHARPNESS, + 0, 0x0f, 1, SHARPNESS_DEFAULT); + + /* Reset image controls */ + em28xx_colorlevels_set_default(dev); + v4l2_ctrl_handler_setup(&dev->ctrl_handler); + if (dev->ctrl_handler.error) + return dev->ctrl_handler.error; + /* allocate and fill video video_device struct */ dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); if (!dev->vdev) { -- cgit From a062b291af64e94f603f7a231aa55e7d05f0feb9 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Mon, 11 Feb 2013 13:54:01 -0300 Subject: [media] em28xx: remove some obsolete function declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 7dc27b58a4d7..a3c08ae7ae8e 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -654,11 +654,6 @@ int em28xx_i2c_register(struct em28xx *dev); int em28xx_i2c_unregister(struct em28xx *dev); /* Provided by em28xx-core.c */ - -u32 em28xx_request_buffers(struct em28xx *dev, u32 count); -void em28xx_queue_unusedframes(struct em28xx *dev); -void em28xx_release_buffers(struct em28xx *dev); - int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg); @@ -691,7 +686,6 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, (struct em28xx *dev, struct urb *urb)); void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode); void em28xx_stop_urbs(struct em28xx *dev); -int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); void em28xx_wake_i2c(struct em28xx *dev); @@ -710,10 +704,8 @@ int em28xx_stop_vbi_streaming(struct vb2_queue *vq); extern const struct v4l2_ctrl_ops em28xx_ctrl_ops; /* Provided by em28xx-cards.c */ -extern int em2800_variant_detect(struct usb_device *udev, int model); extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; -extern const unsigned int em28xx_bcount; int em28xx_tuner_callback(void *ptr, int component, int command, int arg); void em28xx_release_resources(struct em28xx *dev); -- cgit From d5b6a7469127147797638b4c2b0c86d3049ad4ab Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Mon, 11 Feb 2013 14:01:20 -0300 Subject: [media] em28xx: fix spacing and some comments in em28xx.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx.h | 95 +++++++++++++++------------------------ 1 file changed, 37 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index a3c08ae7ae8e..4160a2ae1d84 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -42,28 +42,28 @@ #include "em28xx-reg.h" /* Boards supported by driver */ -#define EM2800_BOARD_UNKNOWN 0 -#define EM2820_BOARD_UNKNOWN 1 -#define EM2820_BOARD_TERRATEC_CINERGY_250 2 -#define EM2820_BOARD_PINNACLE_USB_2 3 -#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 -#define EM2820_BOARD_MSI_VOX_USB_2 5 -#define EM2800_BOARD_TERRATEC_CINERGY_200 6 -#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 -#define EM2800_BOARD_KWORLD_USB2800 8 -#define EM2820_BOARD_PINNACLE_DVC_90 9 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 -#define EM2880_BOARD_TERRATEC_HYBRID_XS 11 -#define EM2820_BOARD_KWORLD_PVRTV2800RF 12 -#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 -#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 -#define EM2800_BOARD_VGEAR_POCKETTV 15 -#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 -#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 -#define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19 -#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 -#define EM2800_BOARD_GRABBEEX_USB2800 21 +#define EM2800_BOARD_UNKNOWN 0 +#define EM2820_BOARD_UNKNOWN 1 +#define EM2820_BOARD_TERRATEC_CINERGY_250 2 +#define EM2820_BOARD_PINNACLE_USB_2 3 +#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 +#define EM2820_BOARD_MSI_VOX_USB_2 5 +#define EM2800_BOARD_TERRATEC_CINERGY_200 6 +#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 +#define EM2800_BOARD_KWORLD_USB2800 8 +#define EM2820_BOARD_PINNACLE_DVC_90 9 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 +#define EM2880_BOARD_TERRATEC_HYBRID_XS 11 +#define EM2820_BOARD_KWORLD_PVRTV2800RF 12 +#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 +#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 +#define EM2800_BOARD_VGEAR_POCKETTV 15 +#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 +#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 +#define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19 +#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 +#define EM2800_BOARD_GRABBEEX_USB2800 21 #define EM2750_BOARD_UNKNOWN 22 #define EM2750_BOARD_DLCW_130 23 #define EM2820_BOARD_DLINK_USB_TV 24 @@ -99,35 +99,35 @@ #define EM2882_BOARD_KWORLD_VS_DVBT 54 #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E 56 -#define EM2883_BOARD_KWORLD_HYBRID_330U 57 +#define EM2883_BOARD_KWORLD_HYBRID_330U 57 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 #define EM2820_BOARD_GADMEI_TVR200 62 -#define EM2860_BOARD_KAIOMY_TVNPC_U2 63 -#define EM2860_BOARD_EASYCAP 64 +#define EM2860_BOARD_KAIOMY_TVNPC_U2 63 +#define EM2860_BOARD_EASYCAP 64 #define EM2820_BOARD_IODATA_GVMVP_SZ 65 #define EM2880_BOARD_EMPIRE_DUAL_TV 66 #define EM2860_BOARD_TERRATEC_GRABBY 67 #define EM2860_BOARD_TERRATEC_AV350 68 #define EM2882_BOARD_KWORLD_ATSC_315U 69 #define EM2882_BOARD_EVGA_INDTUBE 70 -#define EM2820_BOARD_SILVERCREST_WEBCAM 71 -#define EM2861_BOARD_GADMEI_UTV330PLUS 72 -#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 +#define EM2820_BOARD_SILVERCREST_WEBCAM 71 +#define EM2861_BOARD_GADMEI_UTV330PLUS 72 +#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 #define EM2800_BOARD_VC211A 74 #define EM2882_BOARD_DIKOM_DK300 75 #define EM2870_BOARD_KWORLD_A340 76 #define EM2874_BOARD_LEADERSHIP_ISDBT 77 -#define EM28174_BOARD_PCTV_290E 78 +#define EM28174_BOARD_PCTV_290E 78 #define EM2884_BOARD_TERRATEC_H5 79 -#define EM28174_BOARD_PCTV_460E 80 +#define EM28174_BOARD_PCTV_460E 80 #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 #define EM2884_BOARD_CINERGY_HTC_STICK 82 -#define EM2860_BOARD_HT_VIDBOX_NW03 83 -#define EM2874_BOARD_MAXMEDIA_UB425_TC 84 -#define EM2884_BOARD_PCTV_510E 85 -#define EM2884_BOARD_PCTV_520E 86 +#define EM2860_BOARD_HT_VIDBOX_NW03 83 +#define EM2874_BOARD_MAXMEDIA_UB425_TC 84 +#define EM2884_BOARD_PCTV_510E 85 +#define EM2884_BOARD_PCTV_520E 86 #define EM2884_BOARD_TERRATEC_HTC_USB_XS 87 /* Limits minimum and default number of buffers */ @@ -172,27 +172,6 @@ #define EM28XX_INTERLACED_DEFAULT 1 -/* -#define (use usbview if you want to get the other alternate number infos) -#define -#define alternate number 2 -#define Endpoint Address: 82 - Direction: in - Attribute: 1 - Type: Isoc - Max Packet Size: 1448 - Interval: 125us - - alternate number 7 - - Endpoint Address: 82 - Direction: in - Attribute: 1 - Type: Isoc - Max Packet Size: 3072 - Interval: 125us -*/ - /* time in msecs to wait for i2c writes to finish */ #define EM2800_I2C_XFER_TIMEOUT 20 @@ -509,8 +488,8 @@ struct em28xx { unsigned int is_audio_only:1; /* Controls audio streaming */ - struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ - atomic_t stream_started; /* stream should be running if true */ + struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ + atomic_t stream_started; /* stream should be running if true */ struct em28xx_fmt *format; @@ -598,7 +577,7 @@ struct em28xx { u8 analog_ep_isoc; /* address of isoc endpoint for analog */ u8 analog_ep_bulk; /* address of bulk endpoint for analog */ u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */ - u8 dvb_ep_bulk; /* address of bulk endpoint for DVC */ + u8 dvb_ep_bulk; /* address of bulk endpoint for DVB */ int alt; /* alternate setting */ int max_pkt_size; /* max packet size of the selected ep at alt */ int packet_multiplier; /* multiplier for wMaxPacketSize, used for -- cgit From 43a20d791031d5bbc92e143ff077a9bd2a4d438c Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Mon, 11 Feb 2013 14:07:55 -0300 Subject: [media] em28xx: bump driver version to 0.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The em28xx driver has changed much, especially since kernel 3.8. So it's time to bump the driver version. Changes since kernel 3.8: - converted the driver to videobuf2 - converted the driver to the v4l2-ctrl framework - added USB bulk transfer support - use USB bulk transfers by default for webcams (allows streaming from multiple devices at the same time) - added image quality bridge controls: contrast, brightness, saturation, blue balance, red balance, sharpness - removed dependency from module ir-kbd-i2c - cleaned up the frame data processing code - removed some unused/obsolete code - made remote controls of devices with external (i2c) receiver/decoder work again - fixed audio over USB for device "Terratec Cinergy 250" - several v4l2 compliance fixes and improvements (including fixes for ioctls enabling/disabling) - lots of further bug fixes and code improvements Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 48b937d1b063..93fc6204df6c 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -52,7 +52,7 @@ #define DRIVER_DESC "Empia em28xx based USB video device driver" -#define EM28XX_VERSION "0.1.3" +#define EM28XX_VERSION "0.2.0" #define em28xx_videodbg(fmt, arg...) do {\ if (video_debug) \ -- cgit From d7a80eaa9a2adce908ad0707faea4f776199a48a Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:35 -0300 Subject: [media] em28xx-i2c: get rid of the dprintk2 macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is only a single place where the dprintk2 macro is used, so get rid of it. [mchehab@redhat.com: fix checkpathc.pl complain: ERROR: space prohibited before that close parenthesis ')'] Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 8532c1d4fd46..4ffcafb6ac9a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -41,14 +41,6 @@ static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); -#define dprintk2(lvl, fmt, args...) \ -do { \ - if (i2c_debug >= lvl) { \ - printk(KERN_DEBUG "%s at %s: " fmt, \ - dev->name, __func__ , ##args); \ - } \ -} while (0) - /* * em2800_i2c_send_bytes() * send up to 4 bytes to the em2800 i2c device @@ -295,9 +287,12 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, return 0; for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - dprintk2(2, "%s %s addr=%x len=%d:", - (msgs[i].flags & I2C_M_RD) ? "read" : "write", - i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); + if (i2c_debug >= 2) + printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", + dev->name, __func__ , + (msgs[i].flags & I2C_M_RD) ? "read" : "write", + i == num - 1 ? "stop" : "nonstop", + addr, msgs[i].len); if (!msgs[i].len) { /* no len: check only for device presence */ if (dev->board.is_em2800) rc = em2800_i2c_check_for_device(dev, addr); -- cgit From 12d7ce185a6d86758c8feecc91f3c029c39730c6 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:34 -0300 Subject: [media] em28xx-i2c: replace printk() with the corresponding em28xx macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduces the number of characters/lines, unifies the code and improves readability. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 55 +++++++++++++++-------------------- 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 4ffcafb6ac9a..ebe1ec626892 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -394,7 +394,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client, &buf, 0); if (err < 0) { - em28xx_errdev("board has no eeprom\n"); + em28xx_info("board has no eeprom\n"); memset(eedata, 0, len); return -ENODEV; } @@ -403,8 +403,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) err = i2c_master_send(&dev->i2c_client, &buf, 1); if (err != 1) { - printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", - dev->name, err); + em28xx_errdev("failed to read eeprom (err=%d)\n", err); return err; } @@ -421,9 +420,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) if (block != (err = i2c_master_recv(&dev->i2c_client, p, block))) { - printk(KERN_WARNING - "%s: i2c eeprom read error (err=%d)\n", - dev->name, err); + em28xx_errdev("i2c eeprom read error (err=%d)\n", err); return err; } size -= block; @@ -431,7 +428,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) } for (i = 0; i < len; i++) { if (0 == (i % 16)) - printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); + em28xx_info("i2c eeprom %02x:", i); printk(" %02x", eedata[i]); if (15 == (i % 16)) printk("\n"); @@ -440,55 +437,51 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) if (em_eeprom->id == 0x9567eb1a) dev->hash = em28xx_hash_mem(eedata, len, 32); - printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n", - dev->name, em_eeprom->id, dev->hash); + em28xx_info("EEPROM ID = 0x%08x, EEPROM hash = 0x%08lx\n", + em_eeprom->id, dev->hash); - printk(KERN_INFO "%s: EEPROM info:\n", dev->name); + em28xx_info("EEPROM info:\n"); switch (em_eeprom->chip_conf >> 4 & 0x3) { case 0: - printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name); + em28xx_info("\tNo audio on board.\n"); break; case 1: - printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n", - dev->name); + em28xx_info("\tAC97 audio (5 sample rates)\n"); break; case 2: - printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", - dev->name); + em28xx_info("\tI2S audio, sample rate=32k\n"); break; case 3: - printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", - dev->name); + em28xx_info("\tI2S audio, 3 sample rates\n"); break; } if (em_eeprom->chip_conf & 1 << 3) - printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name); + em28xx_info("\tUSB Remote wakeup capable\n"); if (em_eeprom->chip_conf & 1 << 2) - printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name); + em28xx_info("\tUSB Self power capable\n"); switch (em_eeprom->chip_conf & 0x3) { case 0: - printk(KERN_INFO "%s:\t500mA max power\n", dev->name); + em28xx_info("\t500mA max power\n"); break; case 1: - printk(KERN_INFO "%s:\t400mA max power\n", dev->name); + em28xx_info("\t400mA max power\n"); break; case 2: - printk(KERN_INFO "%s:\t300mA max power\n", dev->name); + em28xx_info("\t300mA max power\n"); break; case 3: - printk(KERN_INFO "%s:\t200mA max power\n", dev->name); + em28xx_info("\t200mA max power\n"); break; } - printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", - dev->name, - em_eeprom->string_idx_table, - em_eeprom->string1, - em_eeprom->string2, - em_eeprom->string3); + em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", + em_eeprom->string_idx_table, + em_eeprom->string1, + em_eeprom->string2, + em_eeprom->string3); return 0; } @@ -565,8 +558,8 @@ void em28xx_do_i2c_scan(struct em28xx *dev) if (rc < 0) continue; i2c_devicelist[i] = i; - printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", - dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + em28xx_info("found i2c device @ 0x%x [%s]\n", + i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, -- cgit From d90f067713091f010672ddbd023691675a7b33ea Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:36 -0300 Subject: [media] em28xx-i2c: also print debug messages at debug level 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code uses only a single debug level and all debug messages are printed for i2c_debug >= 2 only. So debug level 1 is actually the same as level 0, which is odd. Users expect debugging messages to become enabled for anything else than debug level 0. Fix it and simplify the code a bit by printing the debug messages also at debug level 1; Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index ebe1ec626892..b8e9946f8452 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -287,7 +287,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, return 0; for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - if (i2c_debug >= 2) + if (i2c_debug) printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", dev->name, __func__ , (msgs[i].flags & I2C_M_RD) ? "read" : "write", @@ -299,7 +299,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, else rc = em28xx_i2c_check_for_device(dev, addr); if (rc == -ENODEV) { - if (i2c_debug >= 2) + if (i2c_debug) printk(" no device\n"); return rc; } @@ -313,13 +313,13 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, rc = em28xx_i2c_recv_bytes(dev, addr, msgs[i].buf, msgs[i].len); - if (i2c_debug >= 2) { + if (i2c_debug) { for (byte = 0; byte < msgs[i].len; byte++) printk(" %02x", msgs[i].buf[byte]); } } else { /* write bytes */ - if (i2c_debug >= 2) { + if (i2c_debug) { for (byte = 0; byte < msgs[i].len; byte++) printk(" %02x", msgs[i].buf[byte]); } @@ -334,11 +334,11 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, i == num - 1); } if (rc < 0) { - if (i2c_debug >= 2) + if (i2c_debug) printk(" ERROR: %i\n", rc); return rc; } - if (i2c_debug >= 2) + if (i2c_debug) printk("\n"); } -- cgit From f55eacbe744f696fa5ff48fe4fdc0f00edc08619 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:37 -0300 Subject: [media] em28xx: do not interpret eeprom content if eeprom key is invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the eeprom key isn't valid, either a different (currently unknown) format is used or the eeprom is corrupted. In both cases it doesn't make sense to interpret the data. Also print an error message. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index b8e9946f8452..b8a9bee836fa 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -434,8 +434,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) printk("\n"); } - if (em_eeprom->id == 0x9567eb1a) - dev->hash = em28xx_hash_mem(eedata, len, 32); + if (em_eeprom->id != 0x9567eb1a) { + em28xx_errdev("Unknown eeprom type or eeprom corrupted !"); + return -ENODEV; + } + + dev->hash = em28xx_hash_mem(eedata, len, 32); em28xx_info("EEPROM ID = 0x%08x, EEPROM hash = 0x%08lx\n", em_eeprom->id, dev->hash); -- cgit From 0c28dcc054ecbcd16e197bd9bf9b394cc1f691c5 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:38 -0300 Subject: [media] em28xx: fix eeprom data endianess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data is stored as little endian in the eeprom. Hence the correct data types should be used and the data should be converted to the machine endianess before using it. The eeprom id (key) also isn't a 32 bit value but 4 separate bytes instead. [mchehab@redhat.com: Fix CodingStyle] Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 22 ++++++++++++---------- drivers/media/usb/em28xx/em28xx.h | 12 ++++++------ 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index b8a9bee836fa..1b90e7536aa5 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -434,19 +434,21 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) printk("\n"); } - if (em_eeprom->id != 0x9567eb1a) { + if (em_eeprom->id[0] != 0x1a || em_eeprom->id[1] != 0xeb || + em_eeprom->id[2] != 0x67 || em_eeprom->id[3] != 0x95) { em28xx_errdev("Unknown eeprom type or eeprom corrupted !"); return -ENODEV; } dev->hash = em28xx_hash_mem(eedata, len, 32); - em28xx_info("EEPROM ID = 0x%08x, EEPROM hash = 0x%08lx\n", - em_eeprom->id, dev->hash); + em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", + em_eeprom->id[0], em_eeprom->id[1], + em_eeprom->id[2], em_eeprom->id[3], dev->hash); em28xx_info("EEPROM info:\n"); - switch (em_eeprom->chip_conf >> 4 & 0x3) { + switch (le16_to_cpu(em_eeprom->chip_conf) >> 4 & 0x3) { case 0: em28xx_info("\tNo audio on board.\n"); break; @@ -461,13 +463,13 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) break; } - if (em_eeprom->chip_conf & 1 << 3) + if (le16_to_cpu(em_eeprom->chip_conf) & 1 << 3) em28xx_info("\tUSB Remote wakeup capable\n"); - if (em_eeprom->chip_conf & 1 << 2) + if (le16_to_cpu(em_eeprom->chip_conf) & 1 << 2) em28xx_info("\tUSB Self power capable\n"); - switch (em_eeprom->chip_conf & 0x3) { + switch (le16_to_cpu(em_eeprom->chip_conf) & 0x3) { case 0: em28xx_info("\t500mA max power\n"); break; @@ -483,9 +485,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) } em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", em_eeprom->string_idx_table, - em_eeprom->string1, - em_eeprom->string2, - em_eeprom->string3); + le16_to_cpu(em_eeprom->string1), + le16_to_cpu(em_eeprom->string2), + le16_to_cpu(em_eeprom->string3)); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 4160a2ae1d84..90266a1e7957 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -405,15 +405,15 @@ struct em28xx_board { }; struct em28xx_eeprom { - u32 id; /* 0x9567eb1a */ - u16 vendor_ID; - u16 product_ID; + u8 id[4]; /* 1a eb 67 95 */ + __le16 vendor_ID; + __le16 product_ID; - u16 chip_conf; + __le16 chip_conf; - u16 board_conf; + __le16 board_conf; - u16 string1, string2, string3; + __le16 string1, string2, string3; u8 string_idx_table; }; -- cgit From 87b52439cff4a8b745f419b9e99fa68a5533c342 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:40 -0300 Subject: [media] em28xx: add basic support for eeproms with 16 bit address width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer devices (em2874, em2884, em28174, em25xx, em27[6,7,8]x) use eeproms with 16 bit instead of 8 bit address width. The used eeprom type depends on the chip type, which makes sure eeproms can't be damaged. This patch adds basic support for 16 bit eeproms only, which includes - reading the content - calculating the eeprom hash - displaying the content The eeprom content uses a different format, for which support will be added with subsequent patches. Tested with the "Hauppauge HVR-930C" and the "Speedlink VAD Laplace webcam" (with additional experimental patches). Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 4 ++ drivers/media/usb/em28xx/em28xx-i2c.c | 69 +++++++++++++++++++++------------ drivers/media/usb/em28xx/em28xx.h | 1 + 3 files changed, 49 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 9332d051bde9..f371dbede27e 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2183,6 +2183,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT}, }; +/* NOTE: introduce a separate hash table for devices with 16 bit eeproms */ /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ static unsigned short saa711x_addrs[] = { @@ -3019,11 +3020,13 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, chip_name = "em2874"; dev->reg_gpio_num = EM2874_R80_GPIO; dev->wait_after_write = 0; + dev->eeprom_addrwidth_16bit = 1; break; case CHIP_ID_EM28174: chip_name = "em28174"; dev->reg_gpio_num = EM2874_R80_GPIO; dev->wait_after_write = 0; + dev->eeprom_addrwidth_16bit = 1; break; case CHIP_ID_EM2883: chip_name = "em2882/3"; @@ -3033,6 +3036,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, chip_name = "em2884"; dev->reg_gpio_num = EM2874_R80_GPIO; dev->wait_after_write = 0; + dev->eeprom_addrwidth_16bit = 1; break; default: printk(KERN_INFO DRIVER_NAME diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 1b90e7536aa5..3f0012c9cf25 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -372,46 +372,34 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) { - unsigned char buf, *p = eedata; + unsigned char buf[2], *p = eedata; struct em28xx_eeprom *em_eeprom = (void *)eedata; int i, err, size = len, block, block_max; - if (dev->chip_id == CHIP_ID_EM2874 || - dev->chip_id == CHIP_ID_EM28174 || - dev->chip_id == CHIP_ID_EM2884) { - /* Empia switched to a 16-bit addressable eeprom in newer - devices. While we could certainly write a routine to read - the eeprom, there is nothing of use in there that cannot be - accessed through registers, and there is the risk that we - could corrupt the eeprom (since a 16-bit read call is - interpreted as a write call by 8-bit eeproms). - */ - return 0; - } - dev->i2c_client.addr = 0xa0 >> 1; /* Check if board has eeprom */ - err = i2c_master_recv(&dev->i2c_client, &buf, 0); + err = i2c_master_recv(&dev->i2c_client, buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); memset(eedata, 0, len); return -ENODEV; } - buf = 0; - - err = i2c_master_send(&dev->i2c_client, &buf, 1); - if (err != 1) { + /* Select address memory address 0x00(00) */ + buf[0] = 0; + buf[1] = 0; + err = i2c_master_send(&dev->i2c_client, buf, 1 + dev->eeprom_addrwidth_16bit); + if (err != 1 + dev->eeprom_addrwidth_16bit) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); return err; } + /* Read eeprom content */ if (dev->board.is_em2800) block_max = 4; else block_max = 64; - while (size > 0) { if (size > block_max) block = block_max; @@ -426,17 +414,48 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) size -= block; p += block; } + + /* Display eeprom content */ for (i = 0; i < len; i++) { - if (0 == (i % 16)) - em28xx_info("i2c eeprom %02x:", i); + if (0 == (i % 16)) { + if (dev->eeprom_addrwidth_16bit) + em28xx_info("i2c eeprom %04x:", i); + else + em28xx_info("i2c eeprom %02x:", i); + } printk(" %02x", eedata[i]); if (15 == (i % 16)) printk("\n"); } - if (em_eeprom->id[0] != 0x1a || em_eeprom->id[1] != 0xeb || - em_eeprom->id[2] != 0x67 || em_eeprom->id[3] != 0x95) { - em28xx_errdev("Unknown eeprom type or eeprom corrupted !"); + if (dev->eeprom_addrwidth_16bit && + eedata[0] == 0x26 && eedata[3] == 0x00) { + /* new eeprom format; size 4-64kb */ + dev->hash = em28xx_hash_mem(eedata, len, 32); + em28xx_info("EEPROM hash = 0x%08lx\n", dev->hash); + em28xx_info("EEPROM info: boot page address = 0x%02x04, " + "boot configuration = 0x%02x\n", + eedata[1], eedata[2]); + /* boot configuration (address 0x0002): + * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz + * [1] always selects 12 kb RAM + * [2] USB device speed: 1 = force Full Speed; 0 = auto detect + * [4] 1 = force fast mode and no suspend for device testing + * [5:7] USB PHY tuning registers; determined by device + * characterization + */ + + /* FIXME: + * - read more than 256 bytes / addresses above 0x00ff + * - find offset for device config dataset and extract it + * - decrypt eeprom data for camera bridges (em25xx, em276x+) + * - use separate/different eeprom hashes (not yet used) + */ + + return 0; + } else if (em_eeprom->id[0] != 0x1a || em_eeprom->id[1] != 0xeb || + em_eeprom->id[2] != 0x67 || em_eeprom->id[3] != 0x95) { + em28xx_info("unknown eeprom format or eeprom corrupted !\n"); return -ENODEV; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 90266a1e7957..139dfe54a057 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -510,6 +510,7 @@ struct em28xx { /* i2c i/o */ struct i2c_adapter i2c_adap; struct i2c_client i2c_client; + unsigned char eeprom_addrwidth_16bit:1; /* video for linux */ int users; /* user count for exclusive use */ int streaming_users; /* Number of actively streaming users */ -- cgit From d832c5b28aff3c9aadfbde3002b640058eee6294 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:41 -0300 Subject: [media] em28xx: add helper function for reading data blocks from i2c clients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper function for reading data blocks from i2c devices with 8 or 16 bit address width and 8 bit register width. This allows us to reduce the size of new code added by the following patches. Works only for devices with activated register auto incrementation. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 74 ++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 3f0012c9cf25..438cfbcb9bf5 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -370,51 +370,69 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) return (hash >> (32 - bits)) & 0xffffffffUL; } +/* Helper function to read data blocks from i2c clients with 8 or 16 bit + * address width, 8 bit register width and auto incrementation been activated */ +static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, + u16 len, u8 *data) +{ + int remain = len, rsize, rsize_max, ret; + u8 buf[2]; + + /* Sanity check */ + if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1)) + return -EINVAL; + /* Select address */ + buf[0] = addr >> 8; + buf[1] = addr & 0xff; + ret = i2c_master_send(&dev->i2c_client, buf + !addr_w16, 1 + addr_w16); + if (ret < 0) + return ret; + /* Read data */ + if (dev->board.is_em2800) + rsize_max = 4; + else + rsize_max = 64; + while (remain > 0) { + if (remain > rsize_max) + rsize = rsize_max; + else + rsize = remain; + + ret = i2c_master_recv(&dev->i2c_client, data, rsize); + if (ret < 0) + return ret; + + remain -= rsize; + data += rsize; + } + + return len; +} + static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) { - unsigned char buf[2], *p = eedata; + unsigned char buf, *p = eedata; struct em28xx_eeprom *em_eeprom = (void *)eedata; - int i, err, size = len, block, block_max; + int i, err; dev->i2c_client.addr = 0xa0 >> 1; /* Check if board has eeprom */ - err = i2c_master_recv(&dev->i2c_client, buf, 0); + err = i2c_master_recv(&dev->i2c_client, &buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); memset(eedata, 0, len); return -ENODEV; } - /* Select address memory address 0x00(00) */ - buf[0] = 0; - buf[1] = 0; - err = i2c_master_send(&dev->i2c_client, buf, 1 + dev->eeprom_addrwidth_16bit); - if (err != 1 + dev->eeprom_addrwidth_16bit) { + /* Read EEPROM content */ + err = em28xx_i2c_read_block(dev, 0x0000, dev->eeprom_addrwidth_16bit, + len, p); + if (err != len) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); return err; } - /* Read eeprom content */ - if (dev->board.is_em2800) - block_max = 4; - else - block_max = 64; - while (size > 0) { - if (size > block_max) - block = block_max; - else - block = size; - - if (block != - (err = i2c_master_recv(&dev->i2c_client, p, block))) { - em28xx_errdev("i2c eeprom read error (err=%d)\n", err); - return err; - } - size -= block; - p += block; - } - /* Display eeprom content */ for (i = 0; i < len; i++) { if (0 == (i % 16)) { -- cgit From a217968f919b0574ef59054430d8908aebcf0a35 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:42 -0300 Subject: [media] em28xx: do not store eeprom content permanently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently reserve an array of 256 bytes for the eeprom content in the device struct. For eeproms with 16 bit address width it might even be necessary to increase the buffer size further. Having such a big chunk of memory reserved even if the device has no eeprom and keeping it after it has already been processed seems to be a waste of memory. Change the code to allocate + free the eeprom memory dynamically. This also makes it possible to handle different dataset sizes depending on what is stored/found in the eeprom. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 9 ++++++++- drivers/media/usb/em28xx/em28xx-i2c.c | 35 +++++++++++++++++++++------------ drivers/media/usb/em28xx/em28xx.h | 2 +- 3 files changed, 31 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index f371dbede27e..331d55034616 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2739,6 +2739,9 @@ static void em28xx_card_setup(struct em28xx *dev) case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; + + if (dev->eedata == NULL) + break; #if defined(CONFIG_MODULES) && defined(MODULE) request_module("tveeprom"); #endif @@ -2792,7 +2795,7 @@ static void em28xx_card_setup(struct em28xx *dev) em28xx_set_mode(dev, EM28XX_ANALOG_MODE); break; -/* + /* * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR. * * This occurs because they share identical USB vendor and @@ -2827,6 +2830,10 @@ static void em28xx_card_setup(struct em28xx *dev) "addresses)\n\n"); } + /* Free eeprom data memory */ + kfree(dev->eedata); + dev->eedata = NULL; + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 438cfbcb9bf5..8d4817747bf2 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -409,27 +409,33 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, return len; } -static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) +static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len) { - unsigned char buf, *p = eedata; - struct em28xx_eeprom *em_eeprom = (void *)eedata; + u8 buf, *data; + struct em28xx_eeprom *em_eeprom; int i, err; + *eedata = NULL; + dev->i2c_client.addr = 0xa0 >> 1; /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client, &buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); - memset(eedata, 0, len); return -ENODEV; } + data = kzalloc(len, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + /* Read EEPROM content */ err = em28xx_i2c_read_block(dev, 0x0000, dev->eeprom_addrwidth_16bit, - len, p); + len, data); if (err != len) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); + kfree(data); return err; } @@ -441,19 +447,19 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) else em28xx_info("i2c eeprom %02x:", i); } - printk(" %02x", eedata[i]); + printk(" %02x", data[i]); if (15 == (i % 16)) printk("\n"); } if (dev->eeprom_addrwidth_16bit && - eedata[0] == 0x26 && eedata[3] == 0x00) { + data[0] == 0x26 && data[3] == 0x00) { /* new eeprom format; size 4-64kb */ - dev->hash = em28xx_hash_mem(eedata, len, 32); + dev->hash = em28xx_hash_mem(data, len, 32); em28xx_info("EEPROM hash = 0x%08lx\n", dev->hash); em28xx_info("EEPROM info: boot page address = 0x%02x04, " "boot configuration = 0x%02x\n", - eedata[1], eedata[2]); + data[1], data[2]); /* boot configuration (address 0x0002): * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz * [1] always selects 12 kb RAM @@ -471,13 +477,16 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) */ return 0; - } else if (em_eeprom->id[0] != 0x1a || em_eeprom->id[1] != 0xeb || - em_eeprom->id[2] != 0x67 || em_eeprom->id[3] != 0x95) { + } else if (data[0] != 0x1a || data[1] != 0xeb || + data[2] != 0x67 || data[3] != 0x95) { em28xx_info("unknown eeprom format or eeprom corrupted !\n"); return -ENODEV; } - dev->hash = em28xx_hash_mem(eedata, len, 32); + *eedata = data; + em_eeprom = (void *)eedata; + + dev->hash = em28xx_hash_mem(data, len, 32); em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", em_eeprom->id[0], em_eeprom->id[1], @@ -635,7 +644,7 @@ int em28xx_i2c_register(struct em28xx *dev) dev->i2c_client = em28xx_client_template; dev->i2c_client.adapter = &dev->i2c_adap; - retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); + retval = em28xx_i2c_eeprom(dev, &dev->eedata, 256); if ((retval < 0) && (retval != -ENODEV)) { em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 139dfe54a057..77f600dc0067 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -562,7 +562,7 @@ struct em28xx { /* resources in use */ unsigned int resources; - unsigned char eedata[256]; + u8 *eedata; /* currently always 256 bytes */ /* Isoc control struct */ struct em28xx_dmaqueue vidq; -- cgit From 510e884c1abb86b060b895ffaf38ee1aac2e7fe4 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:43 -0300 Subject: [media] em28xx: extract the device configuration dataset from eeproms with 16 bit address width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new eeproms with 16 address width still have the the device config dataset (the content of the old 8 bit eeproms) embedded. Hauppauge also continues to include the tveeprom data structure inside this dataset in their devices. The start address of the dataset depends on the start address of the microcode and a variable additional offset. It should be mentioned that Camera devices seem to use a different dataset type, which is not yet supported. Tested with devices "Hauppauge HVR-930C". I've also checked the USB-log from the "MSI Digivox ATSC" and it works the same way. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 117 ++++++++++++++++++++++++---------- drivers/media/usb/em28xx/em28xx.h | 4 +- 2 files changed, 85 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 8d4817747bf2..6152423bef76 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -409,13 +409,18 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, return len; } -static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len) +static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) { - u8 buf, *data; - struct em28xx_eeprom *em_eeprom; + const u16 len = 256; + /* FIXME common length/size for bytes to read, to display, hash + * calculation and returned device dataset. Simplifies the code a lot, + * but we might have to deal with multiple sizes in the future ! */ int i, err; + struct em28xx_eeprom *dev_config; + u8 buf, *data; *eedata = NULL; + *eedata_len = 0; dev->i2c_client.addr = 0xa0 >> 1; @@ -435,8 +440,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len len, data); if (err != len) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); - kfree(data); - return err; + goto error; } /* Display eeprom content */ @@ -451,15 +455,25 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len if (15 == (i % 16)) printk("\n"); } + if (dev->eeprom_addrwidth_16bit) + em28xx_info("i2c eeprom %04x: ... (skipped)\n", i); if (dev->eeprom_addrwidth_16bit && data[0] == 0x26 && data[3] == 0x00) { /* new eeprom format; size 4-64kb */ + u16 mc_start; + u16 hwconf_offset; + dev->hash = em28xx_hash_mem(data, len, 32); - em28xx_info("EEPROM hash = 0x%08lx\n", dev->hash); - em28xx_info("EEPROM info: boot page address = 0x%02x04, " + mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ + + em28xx_info("EEPROM ID = %02x %02x %02x %02x, " + "EEPROM hash = 0x%08lx\n", + data[0], data[1], data[2], data[3], dev->hash); + em28xx_info("EEPROM info:\n"); + em28xx_info("\tmicrocode start address = 0x%04x, " "boot configuration = 0x%02x\n", - data[1], data[2]); + mc_start, data[2]); /* boot configuration (address 0x0002): * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz * [1] always selects 12 kb RAM @@ -469,32 +483,61 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len * characterization */ - /* FIXME: - * - read more than 256 bytes / addresses above 0x00ff - * - find offset for device config dataset and extract it - * - decrypt eeprom data for camera bridges (em25xx, em276x+) - * - use separate/different eeprom hashes (not yet used) + /* Read hardware config dataset offset from address + * (microcode start + 46) */ + err = em28xx_i2c_read_block(dev, mc_start + 46, 1, 2, data); + if (err != 2) { + em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", + err); + goto error; + } + + /* Calculate hardware config dataset start address */ + hwconf_offset = mc_start + data[0] + (data[1] << 8); + + /* Read hardware config dataset */ + /* NOTE: the microcode copy can be multiple pages long, but + * we assume the hardware config dataset is the same as in + * the old eeprom and not longer than 256 bytes. + * tveeprom is currently also limited to 256 bytes. */ + err = em28xx_i2c_read_block(dev, hwconf_offset, 1, len, data); + if (err != len) { + em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", + err); + goto error; + } - return 0; - } else if (data[0] != 0x1a || data[1] != 0xeb || - data[2] != 0x67 || data[3] != 0x95) { + /* Verify hardware config dataset */ + /* NOTE: not all devices provide this type of dataset */ + if (data[0] != 0x1a || data[1] != 0xeb || + data[2] != 0x67 || data[3] != 0x95) { + em28xx_info("\tno hardware configuration dataset found in eeprom\n"); + kfree(data); + return 0; + } + + /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ + + } else if (!dev->eeprom_addrwidth_16bit && + data[0] == 0x1a && data[1] == 0xeb && + data[2] == 0x67 && data[3] == 0x95) { + dev->hash = em28xx_hash_mem(data, len, 32); + em28xx_info("EEPROM ID = %02x %02x %02x %02x, " + "EEPROM hash = 0x%08lx\n", + data[0], data[1], data[2], data[3], dev->hash); + em28xx_info("EEPROM info:\n"); + } else { em28xx_info("unknown eeprom format or eeprom corrupted !\n"); - return -ENODEV; + err = -ENODEV; + goto error; } *eedata = data; - em_eeprom = (void *)eedata; + *eedata_len = len; + dev_config = (void *)eedata; - dev->hash = em28xx_hash_mem(data, len, 32); - - em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", - em_eeprom->id[0], em_eeprom->id[1], - em_eeprom->id[2], em_eeprom->id[3], dev->hash); - - em28xx_info("EEPROM info:\n"); - - switch (le16_to_cpu(em_eeprom->chip_conf) >> 4 & 0x3) { + switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { case 0: em28xx_info("\tNo audio on board.\n"); break; @@ -509,13 +552,13 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len break; } - if (le16_to_cpu(em_eeprom->chip_conf) & 1 << 3) + if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) em28xx_info("\tUSB Remote wakeup capable\n"); - if (le16_to_cpu(em_eeprom->chip_conf) & 1 << 2) + if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) em28xx_info("\tUSB Self power capable\n"); - switch (le16_to_cpu(em_eeprom->chip_conf) & 0x3) { + switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { case 0: em28xx_info("\t500mA max power\n"); break; @@ -530,12 +573,16 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char **eedata, int len break; } em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", - em_eeprom->string_idx_table, - le16_to_cpu(em_eeprom->string1), - le16_to_cpu(em_eeprom->string2), - le16_to_cpu(em_eeprom->string3)); + dev_config->string_idx_table, + le16_to_cpu(dev_config->string1), + le16_to_cpu(dev_config->string2), + le16_to_cpu(dev_config->string3)); return 0; + +error: + kfree(data); + return err; } /* ----------------------------------------------------------- */ @@ -644,7 +691,7 @@ int em28xx_i2c_register(struct em28xx *dev) dev->i2c_client = em28xx_client_template; dev->i2c_client.adapter = &dev->i2c_adap; - retval = em28xx_i2c_eeprom(dev, &dev->eedata, 256); + retval = em28xx_i2c_eeprom(dev, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", __func__, retval); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 77f600dc0067..2d6d31ace733 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -562,7 +562,9 @@ struct em28xx { /* resources in use */ unsigned int resources; - u8 *eedata; /* currently always 256 bytes */ + /* eeprom content */ + u8 *eedata; + u16 eedata_len; /* Isoc control struct */ struct em28xx_dmaqueue vidq; -- cgit From d56e326f7b7f409f0390517b0a29d65b4d60c14c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 09:05:42 -0300 Subject: [media] mb86a20s: don't pollute dmesg with debug messages There are a few debug tests that are shown with dev_err() or dev_info(). Replace them by dev_dbg(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index f19cd7367040..44bfb884ba11 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -1095,7 +1095,7 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe, if (rc < 0) return rc; *error |= rc; - dev_err(&state->i2c->dev, "%s: block error for layer %c: %d.\n", + dev_dbg(&state->i2c->dev, "%s: block error for layer %c: %d.\n", __func__, 'A' + layer, *error); /* Read Bit Count */ @@ -1386,7 +1386,7 @@ static int mb86a20s_get_main_CNR(struct dvb_frontend *fe) return rc; if (!(rc & 0x40)) { - dev_info(&state->i2c->dev, "%s: CNR is not available yet.\n", + dev_dbg(&state->i2c->dev, "%s: CNR is not available yet.\n", __func__); return -EBUSY; } @@ -1441,7 +1441,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe) /* Check if data is available */ if (!(rc & 0x01)) { - dev_info(&state->i2c->dev, + dev_dbg(&state->i2c->dev, "%s: MER measures aren't available yet.\n", __func__); return -EBUSY; } -- cgit From 768e6dadd748ecceee852def1f7f71aac4cd35a1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 28 Feb 2013 16:45:39 -0300 Subject: [media] mb86a20s: adjust IF based on what's set on the tuner Instead of hardcoding a fixed IF frequency of 3.3 MHz, use the IF frequency provided by the tuner driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 57 +++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 44bfb884ba11..daeee814e491 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -31,6 +31,8 @@ struct mb86a20s_state { struct dvb_frontend frontend; + u32 if_freq; + u32 estimated_rate[3]; bool need_init; @@ -47,7 +49,7 @@ struct regdata { * Initialization sequence: Use whatevere default values that PV SBTVD * does on its initialisation, obtained via USB snoop */ -static struct regdata mb86a20s_init[] = { +static struct regdata mb86a20s_init1[] = { { 0x70, 0x0f }, { 0x70, 0xff }, { 0x08, 0x01 }, @@ -56,7 +58,9 @@ static struct regdata mb86a20s_init[] = { { 0x39, 0x01 }, { 0x71, 0x00 }, { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, - { 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 }, +}; + +static struct regdata mb86a20s_init2[] = { { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, { 0x3b, 0x21 }, { 0x3c, 0x3a }, @@ -1737,6 +1741,7 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe) static int mb86a20s_initfe(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; + u64 pll; int rc; u8 regD5 = 1; @@ -1746,10 +1751,35 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) fe->ops.i2c_gate_ctrl(fe, 0); /* Initialize the frontend */ - rc = mb86a20s_writeregdata(state, mb86a20s_init); + rc = mb86a20s_writeregdata(state, mb86a20s_init1); if (rc < 0) goto err; + /* Adjust IF frequency to match tuner */ + if (fe->ops.tuner_ops.get_if_frequency) + fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq); + + if (!state->if_freq) + state->if_freq = 3300000; + + /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */ + pll = state->if_freq * 1677721600L; + do_div(pll, 1628571429L); + rc = mb86a20s_writereg(state, 0x28, 0x20); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x2b, pll & 0xff); + if (rc < 0) + goto err; + dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n", + __func__, state->if_freq, (long long)pll); + if (!state->config->is_serial) { regD5 &= ~1; @@ -1761,6 +1791,11 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) goto err; } + rc = mb86a20s_writeregdata(state, mb86a20s_init2); + if (rc < 0) + goto err; + + err: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -1779,7 +1814,7 @@ err: static int mb86a20s_set_frontend(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; - int rc; + int rc, if_freq; #if 0 /* * FIXME: Properly implement the set frontend properties @@ -1796,6 +1831,18 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.tuner_ops.set_params(fe); + if (fe->ops.tuner_ops.get_if_frequency) { + fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + + /* + * If the IF frequency changed, re-initialize the + * frontend. This is needed by some drivers like tda18271, + * that only sets the IF after receiving a set_params() call + */ + if (if_freq != state->if_freq) + state->need_init = true; + } + /* * Make it more reliable: if, for some reason, the initial * device initialization doesn't happen, initialize it when @@ -1805,6 +1852,8 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) * the agc callback logic is not called during DVB attach time, * causing mb86a20s to not be initialized with Kworld SBTVD. * So, this hack is needed, in order to make Kworld SBTVD to work. + * + * It is also needed to change the IF after the initial init. */ if (state->need_init) mb86a20s_initfe(fe); -- cgit From 15b1c5a068e710bd4d9c8d76e8ed8c63aa4bff2b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 09:06:17 -0300 Subject: [media] mb86a20s: provide CNR stats before FE_HAS_SYNC State 9 means TS started to be output, and it should be associated with FE_HAS_SYNC. The mb86a20scan get CNR statistics at state 7, when frame sync is obtained. As CNR may help to adjust the antenna, provide it earlier. A latter patch could eventually start outputing MER measures earlier, but that would require a bigger change, and probably won't be better than the current way, as the time between changing from state 8 to 9 is generally lower than the time to get the stats collected. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index daeee814e491..2720b828d89e 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -312,7 +312,7 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status) dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n", __func__, *status, val); - return 0; + return val; } static int mb86a20s_read_signal_strength(struct dvb_frontend *fe) @@ -1564,7 +1564,7 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe) } } -static int mb86a20s_get_stats(struct dvb_frontend *fe) +static int mb86a20s_get_stats(struct dvb_frontend *fe, int status_nr) { struct mb86a20s_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1584,6 +1584,14 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe) /* Get per-layer stats */ mb86a20s_get_blk_error_layer_CNR(fe); + /* + * At state 7, only CNR is available + * For BER measures, state=9 is required + * FIXME: we may get MER measures with state=8 + */ + if (status_nr < 9) + return 0; + for (i = 0; i < 3; i++) { if (c->isdbt_layer_enabled & (1 << i)) { /* Layer is active and has rc segments */ @@ -1875,7 +1883,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, { struct mb86a20s_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int rc; + int rc, status_nr; dev_dbg(&state->i2c->dev, "%s called.\n", __func__); @@ -1883,12 +1891,12 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 0); /* Get lock */ - rc = mb86a20s_read_status(fe, status); - if (!(*status & FE_HAS_LOCK)) { + status_nr = mb86a20s_read_status(fe, status); + if (status_nr < 7) { mb86a20s_stats_not_ready(fe); mb86a20s_reset_frontend_cache(fe); } - if (rc < 0) { + if (status_nr < 0) { dev_err(&state->i2c->dev, "%s: Can't read frontend lock status\n", __func__); goto error; @@ -1908,7 +1916,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, /* Fill signal strength */ c->strength.stat[0].uvalue = rc; - if (*status & FE_HAS_LOCK) { + if (status_nr >= 7) { /* Get TMCC info*/ rc = mb86a20s_get_frontend(fe); if (rc < 0) { @@ -1919,7 +1927,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, } /* Get statistics */ - rc = mb86a20s_get_stats(fe); + rc = mb86a20s_get_stats(fe, status_nr); if (rc < 0 && rc != -EBUSY) { dev_err(&state->i2c->dev, "%s: Can't get FE statistics.\n", __func__); -- cgit From dad78c56620d425eede52d74e8ba73ea136703dd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Mar 2013 16:15:16 -0300 Subject: [media] mb86a20s: Fix signal strength calculus A register typo made the calculation to not work. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 2720b828d89e..0fbfae23d904 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -335,7 +335,7 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe) rc = mb86a20s_writereg(state, 0x04, 0x20); if (rc < 0) return rc; - rc = mb86a20s_writereg(state, 0x04, rf); + rc = mb86a20s_writereg(state, 0x05, rf); if (rc < 0) return rc; -- cgit From 0921ecfdc2b93ebbe8f2371dac634d91e4fbdf60 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 10:15:30 -0300 Subject: [media] mb86a20s: don't allow updating signal strength too fast Getting signal strength requires some loop poking with I2C. Don't let it happen too fast. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 0fbfae23d904..9948fcbf1596 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -34,6 +34,7 @@ struct mb86a20s_state { u32 if_freq; u32 estimated_rate[3]; + unsigned long get_strength_time; bool need_init; }; @@ -318,9 +319,17 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status) static int mb86a20s_read_signal_strength(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int rc; unsigned rf_max, rf_min, rf; + if (state->get_strength_time && + (!time_after(jiffies, state->get_strength_time))) + return c->strength.stat[0].uvalue; + + /* Reset its value if an error happen */ + c->strength.stat[0].uvalue = 0; + /* Does a binary search to get RF strength */ rf_max = 0xfff; rf_min = 0; @@ -350,15 +359,19 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe) rf = (rf_max + rf_min) / 2; /* Rescale it from 2^12 (4096) to 2^16 */ - rf <<= (16 - 12); + rf = rf << (16 - 12); + if (rf) + rf |= (1 << 12) - 1; + dev_dbg(&state->i2c->dev, "%s: signal strength = %d (%d < RF=%d < %d)\n", __func__, rf, rf_min, rf >> 4, rf_max); - return rf; + c->strength.stat[0].uvalue = rf; + state->get_strength_time = jiffies + + msecs_to_jiffies(1000); + return 0; } } while (1); - - return 0; } static int mb86a20s_get_modulation(struct mb86a20s_state *state, @@ -1882,7 +1895,6 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, fe_status_t *status) { struct mb86a20s_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; int rc, status_nr; dev_dbg(&state->i2c->dev, "%s called.\n", __func__); @@ -1913,8 +1925,6 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, rc = 0; /* Status is OK */ goto error; } - /* Fill signal strength */ - c->strength.stat[0].uvalue = rc; if (status_nr >= 7) { /* Get TMCC info*/ -- cgit From 17e67d4c7fb7515ce98d3eb5de00c2575800818b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Mar 2013 15:20:25 -0300 Subject: [media] mb86a20s: change AGC tuning parameters Use the AGC settings present on a newer device. The initial settings were taken from one of the first devices with mb86a20s, and there are several reports that this is not working properly on some places. So, instead of keeping using it, get the parameters taken from a newer device. Tests are welcomed. Tested also with cx231xx PixelView SBTVD Hybrid with no regressions noticed so far. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 3 +- drivers/media/dvb-frontends/mb86a20s.c | 86 +++++++++++++++++----------------- 2 files changed, 46 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index d81dbb22aa81..8896993e631f 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -852,7 +852,8 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter, struct dmx_sct_filter_params *params) { - dprintk("function : %s\n", __func__); + dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n", + __func__, params->pid, params->flags, params->timeout); dvb_dmxdev_filter_stop(dmxdevfilter); diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 9948fcbf1596..68a88180b631 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -55,7 +55,7 @@ static struct regdata mb86a20s_init1[] = { { 0x70, 0xff }, { 0x08, 0x01 }, { 0x09, 0x3e }, - { 0x50, 0xd1 }, { 0x51, 0x22 }, + { 0x50, 0xd1 }, { 0x51, 0x20 }, { 0x39, 0x01 }, { 0x71, 0x00 }, { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, @@ -64,23 +64,23 @@ static struct regdata mb86a20s_init1[] = { static struct regdata mb86a20s_init2[] = { { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, { 0x3b, 0x21 }, - { 0x3c, 0x3a }, + { 0x3c, 0x38 }, { 0x01, 0x0d }, - { 0x04, 0x08 }, { 0x05, 0x05 }, + { 0x04, 0x08 }, { 0x05, 0x03 }, { 0x04, 0x0e }, { 0x05, 0x00 }, - { 0x04, 0x0f }, { 0x05, 0x14 }, - { 0x04, 0x0b }, { 0x05, 0x8c }, + { 0x04, 0x0f }, { 0x05, 0x37 }, + { 0x04, 0x0b }, { 0x05, 0x78 }, { 0x04, 0x00 }, { 0x05, 0x00 }, - { 0x04, 0x01 }, { 0x05, 0x07 }, - { 0x04, 0x02 }, { 0x05, 0x0f }, - { 0x04, 0x03 }, { 0x05, 0xa0 }, + { 0x04, 0x01 }, { 0x05, 0x1e }, + { 0x04, 0x02 }, { 0x05, 0x07 }, + { 0x04, 0x03 }, { 0x05, 0xd0 }, { 0x04, 0x09 }, { 0x05, 0x00 }, { 0x04, 0x0a }, { 0x05, 0xff }, - { 0x04, 0x27 }, { 0x05, 0x64 }, + { 0x04, 0x27 }, { 0x05, 0x00 }, { 0x04, 0x28 }, { 0x05, 0x00 }, - { 0x04, 0x1e }, { 0x05, 0xff }, - { 0x04, 0x29 }, { 0x05, 0x0a }, - { 0x04, 0x32 }, { 0x05, 0x0a }, + { 0x04, 0x1e }, { 0x05, 0x00 }, + { 0x04, 0x29 }, { 0x05, 0x64 }, + { 0x04, 0x32 }, { 0x05, 0x02 }, { 0x04, 0x14 }, { 0x05, 0x02 }, { 0x04, 0x04 }, { 0x05, 0x00 }, { 0x04, 0x05 }, { 0x05, 0x22 }, @@ -147,39 +147,39 @@ static struct regdata mb86a20s_init2[] = { { 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */ { 0x50, 0xd6 }, { 0x51, 0x1f }, { 0x50, 0xd2 }, { 0x51, 0x03 }, - { 0x50, 0xd7 }, { 0x51, 0x3f }, - { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x28, 0x74 }, { 0x29, 0x40 }, - { 0x28, 0x46 }, { 0x29, 0x2c }, { 0x28, 0x46 }, { 0x29, 0x0c }, + { 0x50, 0xd7 }, { 0x51, 0xbf }, + { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff }, + { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c }, { 0x04, 0x40 }, { 0x05, 0x00 }, - { 0x28, 0x00 }, { 0x29, 0x10 }, - { 0x28, 0x05 }, { 0x29, 0x02 }, + { 0x28, 0x00 }, { 0x2b, 0x08 }, + { 0x28, 0x05 }, { 0x2b, 0x00 }, { 0x1c, 0x01 }, - { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 }, - { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d }, - { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, - { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 }, - { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 }, - { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 }, - { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, - { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 }, - { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e }, - { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e }, - { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 }, - { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, - { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 }, - { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 }, - { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe }, - { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 }, - { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee }, - { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 }, - { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f }, - { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 }, - { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 }, - { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a }, - { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc }, - { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba }, - { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 }, + { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f }, + { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 }, + { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 }, + { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 }, + { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 }, + { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, + { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 }, + { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 }, + { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b }, + { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 }, + { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d }, + { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 }, + { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b }, + { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, + { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 }, + { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 }, + { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 }, + { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, + { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, + { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef }, + { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 }, + { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 }, + { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d }, + { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 }, + { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba }, { 0x50, 0x1e }, { 0x51, 0x5d }, { 0x50, 0x22 }, { 0x51, 0x00 }, { 0x50, 0x23 }, { 0x51, 0xc8 }, @@ -188,6 +188,8 @@ static struct regdata mb86a20s_init2[] = { { 0x50, 0x26 }, { 0x51, 0x00 }, { 0x50, 0x27 }, { 0x51, 0xc3 }, { 0x50, 0x39 }, { 0x51, 0x02 }, + { 0xec, 0x0f }, + { 0xeb, 0x1f }, { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, { 0xd0, 0x00 }, }; -- cgit From a78b41d5fd9a04037c7b29e59c7319035a54a150 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 13:45:31 -0300 Subject: [media] mb86a20s: Always reset the frontend with set_frontend Always init the frontend when set_frontend is called. The rationale is: it was noticed that, on some devices, it fails to lock with a different channel. It seems that some other registers need to be restored to its initial state, when the channel changes. As it is better to reset everything, even wasting a few more miliseconds than to loose channel lock, let's change the logic to always reset. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 68a88180b631..b6cdc444fb45 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -1854,18 +1854,9 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.tuner_ops.set_params(fe); - if (fe->ops.tuner_ops.get_if_frequency) { + if (fe->ops.tuner_ops.get_if_frequency) fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); - /* - * If the IF frequency changed, re-initialize the - * frontend. This is needed by some drivers like tda18271, - * that only sets the IF after receiving a set_params() call - */ - if (if_freq != state->if_freq) - state->need_init = true; - } - /* * Make it more reliable: if, for some reason, the initial * device initialization doesn't happen, initialize it when @@ -1877,9 +1868,13 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) * So, this hack is needed, in order to make Kworld SBTVD to work. * * It is also needed to change the IF after the initial init. + * + * HACK: Always init the frontend when set_frontend is called: + * it was noticed that, on some devices, it fails to lock on a + * different channel. So, it is better to reset everything, even + * wasting some time, than to loose channel lock. */ - if (state->need_init) - mb86a20s_initfe(fe); + mb86a20s_initfe(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- cgit From 8b8e444a271165bce923c98417334f9b989cca20 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 14:54:49 -0300 Subject: [media] mb86a20s: Don't reset strength with the other stats Signal strength is always available. There's no reason to reset it, as it has its own logic to reset it already. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index b6cdc444fb45..746adadfe8d5 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -754,7 +754,6 @@ static int mb86a20s_reset_counters(struct dvb_frontend *fe) /* Reset the counters, if the channel changed */ if (state->last_frequency != c->frequency) { - memset(&c->strength, 0, sizeof(c->strength)); memset(&c->cnr, 0, sizeof(c->cnr)); memset(&c->pre_bit_error, 0, sizeof(c->pre_bit_error)); memset(&c->pre_bit_count, 0, sizeof(c->pre_bit_count)); -- cgit From 3a2e47519ebbef9b1545cda0525e2fce64c437b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Mar 2013 15:02:23 -0300 Subject: [media] mb86a20s: cleanup the status at set_frontend() As the device got re-initialized, the stats should vanish until the device gets lock again. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 746adadfe8d5..1c135aa9df44 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -1880,6 +1880,7 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception); mb86a20s_reset_counters(fe); + mb86a20s_stats_not_ready(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); -- cgit From 84c09d723c30db7801433e1741b628e23cb3fecd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 3 Mar 2013 07:49:50 -0300 Subject: [media] cx231xx: Improve signal reception for PV SBTVD Instead of using 3.3 MHz IF, use 4MHz. That's the standard value for the demod, and, while it can be adjusted, 3.3 MHz is out of the recommended range. So, let's stick with the default. With regards to the IF voltage level, instead of using 0.5 V(p-p) for IF, use 2V, giving a 12dB gain. The rationale is that, on PixelView SBTVD Hybrid, even 2V(p-p) would be in the nominal range for IF, as the maximum range on this particular device is 3V. A higher gain here should help to improve reception under weak signals. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-dvb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 7c4e360ba9bc..14e26106fd72 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -89,8 +89,8 @@ static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { }; static struct tda18271_std_map mb86a20s_tda18271_config = { - .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, - .if_lvl = 7, .rfagc_top = 0x37, }, + .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4, + .if_lvl = 0, .rfagc_top = 0x37, }, }; static struct tda18271_config cnxt_rde253s_tunerconfig = { -- cgit From 385cd33c8dcac5a166c2d034169427e263bf4608 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 3 Mar 2013 09:34:41 -0300 Subject: [media] em28xx-dvb: Don't put device in suspend mode at feed stop Putting em28xx in suspend mode when a feed stops is just plain wrong. Every time a new PES filter is changed, the DVB demux code will stop the current feed, and then start a new one. If are there any code that switches off the frontend, via some GPIO setting, this would make the DVB fail. This condition was actually trigged with one device, during DVB scan, as, during scan, it is common that userspace apps to change the filter several times, in order to get all tables. Also, this is not needed at all, since the em28xx code already hooks into ops.ts_bus_ctrl(). This warrants that em28xx can check there if DVB frontend is in usage or not. The code there already puts the device on suspend mode, if the DVB frontend is not used (closed). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a81ec2e8cc9b..7200dfe59ef9 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -220,8 +220,6 @@ static int em28xx_stop_streaming(struct em28xx_dvb *dvb) em28xx_stop_urbs(dev); - em28xx_set_mode(dev, EM28XX_SUSPEND); - return 0; } -- cgit From 04fa725e7b1c22c583dd71a8cd85b8d997edfce3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Mar 2013 07:10:06 -0300 Subject: [media] mb86a20s: Implement set_frontend cache logic Up to now, the driver was simply assuming TV mode, 13 segs. Implement the logic to control the ISDB operational mode. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 74 +++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 1c135aa9df44..1859e9ddba6e 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -24,6 +24,18 @@ static int debug = 1; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); +enum mb86a20s_bandwidth { + MB86A20S_13SEG = 0, + MB86A20S_13SEG_PARTIAL = 1, + MB86A20S_1SEG = 2, + MB86A20S_3SEG = 3, +}; + +u8 mb86a20s_subchannel[] = { + 0xb0, 0xc0, 0xd0, 0xe0, + 0xf0, 0x00, 0x10, 0x20, +}; + struct mb86a20s_state { struct i2c_adapter *i2c; const struct mb86a20s_config *config; @@ -32,6 +44,9 @@ struct mb86a20s_state { struct dvb_frontend frontend; u32 if_freq; + enum mb86a20s_bandwidth bw; + bool inversion; + u32 subchannel; u32 estimated_rate[3]; unsigned long get_strength_time; @@ -54,10 +69,7 @@ static struct regdata mb86a20s_init1[] = { { 0x70, 0x0f }, { 0x70, 0xff }, { 0x08, 0x01 }, - { 0x09, 0x3e }, { 0x50, 0xd1 }, { 0x51, 0x20 }, - { 0x39, 0x01 }, - { 0x71, 0x00 }, { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, }; @@ -1765,7 +1777,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) struct mb86a20s_state *state = fe->demodulator_priv; u64 pll; int rc; - u8 regD5 = 1; + u8 regD5 = 1, reg71, reg09 = 0x3a; dev_dbg(&state->i2c->dev, "%s called.\n", __func__); @@ -1777,6 +1789,27 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) if (rc < 0) goto err; + if (!state->inversion) + reg09 |= 0x04; + rc = mb86a20s_writereg(state, 0x09, reg09); + if (rc < 0) + goto err; + if (!state->bw) + reg71 = 1; + else + reg71 = 0; + rc = mb86a20s_writereg(state, 0x39, reg71); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x71, state->bw); + if (rc < 0) + goto err; + if (state->subchannel) { + rc = mb86a20s_writereg(state, 0x44, state->subchannel); + if (rc < 0) + goto err; + } + /* Adjust IF frequency to match tuner */ if (fe->ops.tuner_ops.get_if_frequency) fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq); @@ -1836,15 +1869,34 @@ err: static int mb86a20s_set_frontend(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; - int rc, if_freq; -#if 0 - /* - * FIXME: Properly implement the set frontend properties - */ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -#endif + int rc, if_freq; dev_dbg(&state->i2c->dev, "%s called.\n", __func__); + if (!c->isdbt_layer_enabled) + c->isdbt_layer_enabled = 7; + + if (c->isdbt_layer_enabled == 1) + state->bw = MB86A20S_1SEG; + else if (c->isdbt_partial_reception) + state->bw = MB86A20S_13SEG_PARTIAL; + else + state->bw = MB86A20S_13SEG; + + if (c->inversion == INVERSION_ON) + state->inversion = true; + else + state->inversion = false; + + if (!c->isdbt_sb_mode) { + state->subchannel = 0; + } else { + if (c->isdbt_sb_subchannel > ARRAY_SIZE(mb86a20s_subchannel)) + c->isdbt_sb_subchannel = 0; + + state->subchannel = mb86a20s_subchannel[c->isdbt_sb_subchannel]; + } + /* * Gate should already be opened, but it doesn't hurt to * double-check @@ -2058,7 +2110,7 @@ static struct dvb_frontend_ops mb86a20s_ops = { /* Use dib8000 values per default */ .info = { .name = "Fujitsu mb86A20s", - .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER | + .caps = FE_CAN_RECOVER | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | -- cgit From 0e4bbedd638d6d13b0cfe2c95c75fc3736daec94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Mar 2013 08:15:49 -0300 Subject: [media] mb86a20s: Don't assume a 32.57142MHz clock Now that some devices initialize register 0x2a with different values, add the calculus formula, instead of hardcoding it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a20s.c | 26 ++++++++++++++++++++++++-- drivers/media/dvb-frontends/mb86a20s.h | 8 ++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 1859e9ddba6e..d04b52e3f4cc 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -70,7 +70,6 @@ static struct regdata mb86a20s_init1[] = { { 0x70, 0xff }, { 0x08, 0x01 }, { 0x50, 0xd1 }, { 0x51, 0x20 }, - { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, }; static struct regdata mb86a20s_init2[] = { @@ -1776,6 +1775,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) { struct mb86a20s_state *state = fe->demodulator_priv; u64 pll; + u32 fclk; int rc; u8 regD5 = 1, reg71, reg09 = 0x3a; @@ -1810,6 +1810,10 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) goto err; } + fclk = state->config->fclk; + if (!fclk) + fclk = 32571428; + /* Adjust IF frequency to match tuner */ if (fe->ops.tuner_ops.get_if_frequency) fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq); @@ -1817,6 +1821,24 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) if (!state->if_freq) state->if_freq = 3300000; + pll = (((u64)1) << 34) * state->if_freq; + do_div(pll, 63 * fclk); + pll = (1 << 25) - pll; + rc = mb86a20s_writereg(state, 0x28, 0x2a); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff); + if (rc < 0) + goto err; + rc = mb86a20s_writereg(state, 0x2b, pll & 0xff); + if (rc < 0) + goto err; + dev_dbg(&state->i2c->dev, "%s: fclk=%d, IF=%d, clock reg=0x%06llx\n", + __func__, fclk, state->if_freq, (long long)pll); + /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */ pll = state->if_freq * 1677721600L; do_div(pll, 1628571429L); @@ -1832,7 +1854,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) rc = mb86a20s_writereg(state, 0x2b, pll & 0xff); if (rc < 0) goto err; - dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n", + dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n", __func__, state->if_freq, (long long)pll); if (!state->config->is_serial) { diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h index bf22e77888b9..1a7dea2b237a 100644 --- a/drivers/media/dvb-frontends/mb86a20s.h +++ b/drivers/media/dvb-frontends/mb86a20s.h @@ -21,12 +21,16 @@ /** * struct mb86a20s_config - Define the per-device attributes of the frontend * + * @fclk: Clock frequency. If zero, assumes the default + * (32.57142 Mhz) * @demod_address: the demodulator's i2c address + * @is_serial: if true, TS is serial. Otherwise, TS is parallel */ struct mb86a20s_config { - u8 demod_address; - bool is_serial; + u32 fclk; + u8 demod_address; + bool is_serial; }; #if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \ -- cgit From a61660185b42fabd0b015ff2c26fabbc5e959ff7 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 3 Mar 2013 15:37:44 -0300 Subject: [media] em28xx: enable tveeprom for device Hauppauge HVR-930C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 331d55034616..4dcef9d6d561 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2737,6 +2737,7 @@ static void em28xx_card_setup(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: { struct tveeprom tv; -- cgit From 919729237f4f1a37bfe0e94a17e7a4bdfa9f5f8e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 09:31:33 -0300 Subject: [media] tlg2300: use correct device parent Set the correct parent for v4l2_device_register and don't set the name anymore (that's now deduced from the parent). Also remove an unnecessary forward reference and fix two weird looking log messages. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-main.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c index 7b1f6ebd0e2c..247d6ac99947 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/media/usb/tlg2300/pd-main.c @@ -55,7 +55,6 @@ MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose"); #define TLG2300_FIRMWARE "tlg2300_firmware.bin" static const char *firmware_name = TLG2300_FIRMWARE; -static struct usb_driver poseidon_driver; static LIST_HEAD(pd_device_list); /* @@ -316,7 +315,7 @@ static int poseidon_suspend(struct usb_interface *intf, pm_message_t msg) if (get_pm_count(pd) <= 0 && !in_hibernation(pd)) { pd->msg.event = PM_EVENT_AUTO_SUSPEND; pd->pm_resume = NULL; /* a good guard */ - printk(KERN_DEBUG "\n\t+ TLG2300 auto suspend +\n\n"); + printk(KERN_DEBUG "TLG2300 auto suspend\n"); } return 0; } @@ -331,7 +330,7 @@ static int poseidon_resume(struct usb_interface *intf) if (!pd) return 0; - printk(KERN_DEBUG "\n\t ++ TLG2300 resume ++\n\n"); + printk(KERN_DEBUG "TLG2300 resume\n"); if (!is_working(pd)) { if (PM_EVENT_AUTO_SUSPEND == pd->msg.event) @@ -431,15 +430,11 @@ static int poseidon_probe(struct usb_interface *interface, usb_set_intfdata(interface, pd); if (new_one) { - struct device *dev = &interface->dev; - logpm(pd); mutex_init(&pd->lock); /* register v4l2 device */ - snprintf(pd->v4l2_dev.name, sizeof(pd->v4l2_dev.name), "%s %s", - dev->driver->name, dev_name(dev)); - ret = v4l2_device_register(NULL, &pd->v4l2_dev); + ret = v4l2_device_register(&interface->dev, &pd->v4l2_dev); /* register devices in directory /dev */ ret = pd_video_init(pd); @@ -530,7 +525,7 @@ module_init(poseidon_init); module_exit(poseidon_exit); MODULE_AUTHOR("Telegent Systems"); -MODULE_DESCRIPTION("For tlg2300-based USB device "); +MODULE_DESCRIPTION("For tlg2300-based USB device"); MODULE_LICENSE("GPL"); MODULE_VERSION("0.0.2"); MODULE_FIRMWARE(TLG2300_FIRMWARE); -- cgit From 8bdfe557b8fa56cb9d9f6f036c0b2e6cb8abafb4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Jul 2012 12:33:41 -0300 Subject: [media] tlg2300: fix tuner and frequency handling of the radio device This driver now passes the tuner and frequency tests of v4l2-compliance. It's the usual bugs: frequency wasn't clamped to the valid frequency range, incorrect tuner capabilities and tuner fields not filled in, missing test for invalid tuner index, no initial frequency and incorrect error handling. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-radio.c | 37 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 25eeb166aa0b..90dc1d1fcecc 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -18,8 +18,8 @@ static int set_frequency(struct poseidon *p, __u32 frequency); static int poseidon_fm_close(struct file *filp); static int poseidon_fm_open(struct file *filp); -#define TUNER_FREQ_MIN_FM 76000000 -#define TUNER_FREQ_MAX_FM 108000000 +#define TUNER_FREQ_MIN_FM 76000000U +#define TUNER_FREQ_MAX_FM 108000000U #define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1) static int preemphasis[MAX_PREEMPHASIS] = { @@ -170,13 +170,14 @@ static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, return -EINVAL; vt->type = V4L2_TUNER_RADIO; - vt->capability = V4L2_TUNER_CAP_STEREO; - vt->rangelow = TUNER_FREQ_MIN_FM / 62500; - vt->rangehigh = TUNER_FREQ_MAX_FM / 62500; + vt->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW; + vt->rangelow = TUNER_FREQ_MIN_FM * 2 / 125; + vt->rangehigh = TUNER_FREQ_MAX_FM * 2 / 125; vt->rxsubchans = V4L2_TUNER_SUB_STEREO; vt->audmode = V4L2_TUNER_MODE_STEREO; vt->signal = 0; vt->afc = 0; + strlcpy(vt->name, "Radio", sizeof(vt->name)); mutex_lock(&p->lock); ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO, @@ -207,6 +208,8 @@ static int fm_get_freq(struct file *file, void *priv, { struct poseidon *p = file->private_data; + if (argp->tuner) + return -EINVAL; argp->frequency = p->radio_data.fm_freq; return 0; } @@ -221,11 +224,8 @@ static int set_frequency(struct poseidon *p, __u32 frequency) ret = send_set_req(p, TUNER_AUD_ANA_STD, p->radio_data.pre_emphasis, &status); - freq = (frequency * 125) * 500 / 1000;/* kHZ */ - if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) { - ret = -EINVAL; - goto error; - } + freq = (frequency * 125) / 2; /* Hz */ + freq = clamp(freq, TUNER_FREQ_MIN_FM, TUNER_FREQ_MAX_FM); ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status); if (ret < 0) @@ -240,7 +240,7 @@ static int set_frequency(struct poseidon *p, __u32 frequency) TLG_TUNE_PLAY_SVC_START, &status); p->radio_data.is_radio_streaming = 1; } - p->radio_data.fm_freq = frequency; + p->radio_data.fm_freq = freq * 2 / 125; error: mutex_unlock(&p->lock); return ret; @@ -251,7 +251,9 @@ static int fm_set_freq(struct file *file, void *priv, { struct poseidon *p = file->private_data; - p->file_for_stream = file; + if (argp->tuner) + return -EINVAL; + p->file_for_stream = file; #ifdef CONFIG_PM p->pm_suspend = pm_fm_suspend; p->pm_resume = pm_fm_resume; @@ -401,16 +403,19 @@ static struct video_device poseidon_fm_template = { int poseidon_fm_init(struct poseidon *p) { struct video_device *fm_dev; + int err; fm_dev = vdev_init(p, &poseidon_fm_template); if (fm_dev == NULL) - return -1; + return -ENOMEM; - if (video_register_device(fm_dev, VFL_TYPE_RADIO, -1) < 0) { + p->radio_data.fm_dev = fm_dev; + set_frequency(p, TUNER_FREQ_MIN_FM); + err = video_register_device(fm_dev, VFL_TYPE_RADIO, -1); + if (err < 0) { video_device_release(fm_dev); - return -1; + return err; } - p->radio_data.fm_dev = fm_dev; return 0; } -- cgit From 54dd0dde8561a935652f1b0d21e480ff8390d43f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Jul 2012 12:33:41 -0300 Subject: [media] tlg2300: switch to unlocked_ioctl The driver already does locking, so it is safe to switch to unlocked_ioctl. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-radio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 90dc1d1fcecc..c4feffbebeb6 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -156,7 +156,7 @@ static const struct v4l2_file_operations poseidon_fm_fops = { .owner = THIS_MODULE, .open = poseidon_fm_open, .release = poseidon_fm_close, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, -- cgit From 8f0829460507e68c4f41f4beedd6823411504a33 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:16:41 -0300 Subject: [media] tlg2300: remove ioctls that are invalid for radio devices The input and audio ioctls are only valid for video/vbi nodes. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-radio.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index c4feffbebeb6..4c76e0894d9e 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -350,36 +350,9 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) { return vt->index > 0 ? -EINVAL : 0; } -static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *va) -{ - return (va->index != 0) ? -EINVAL : 0; -} - -static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - a->index = 0; - a->mode = 0; - a->capability = V4L2_AUDCAP_STEREO; - strcpy(a->name, "Radio"); - return 0; -} - -static int vidioc_s_input(struct file *filp, void *priv, u32 i) -{ - return (i != 0) ? -EINVAL : 0; -} - -static int vidioc_g_input(struct file *filp, void *priv, u32 *i) -{ - return (*i != 0) ? -EINVAL : 0; -} static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = { .vidioc_querycap = vidioc_querycap, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, .vidioc_queryctrl = tlg_fm_vidioc_queryctrl, .vidioc_querymenu = tlg_fm_vidioc_querymenu, .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl, -- cgit From 6fef490706c327469fe5688ca65d5239b717960d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Jul 2012 12:39:58 -0300 Subject: [media] tlg2300: embed video_device instead of allocating it Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 2 +- drivers/media/usb/tlg2300/pd-radio.c | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 5dd73b7857d1..3a89128c3fc5 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -118,7 +118,7 @@ struct radio_data { int users; unsigned int is_radio_streaming; int pre_emphasis; - struct video_device *fm_dev; + struct video_device fm_dev; }; #define DVB_SBUF_NUM 4 diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 4c76e0894d9e..719c3da22193 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -369,31 +369,23 @@ static struct video_device poseidon_fm_template = { .name = "Telegent-Radio", .fops = &poseidon_fm_fops, .minor = -1, - .release = video_device_release, + .release = video_device_release_empty, .ioctl_ops = &poseidon_fm_ioctl_ops, }; int poseidon_fm_init(struct poseidon *p) { - struct video_device *fm_dev; - int err; + struct video_device *vfd = &p->radio_data.fm_dev; - fm_dev = vdev_init(p, &poseidon_fm_template); - if (fm_dev == NULL) - return -ENOMEM; + *vfd = poseidon_fm_template; + vfd->v4l2_dev = &p->v4l2_dev; + video_set_drvdata(vfd, p); - p->radio_data.fm_dev = fm_dev; set_frequency(p, TUNER_FREQ_MIN_FM); - err = video_register_device(fm_dev, VFL_TYPE_RADIO, -1); - if (err < 0) { - video_device_release(fm_dev); - return err; - } - return 0; + return video_register_device(vfd, VFL_TYPE_RADIO, -1); } int poseidon_fm_exit(struct poseidon *p) { - destroy_video_device(&p->radio_data.fm_dev); return 0; } -- cgit From 173fdb8aff63a4275fd5f51742b4e13bd7680ab8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 12 Jul 2012 12:56:47 -0300 Subject: [media] tlg2300: add control handler for radio device node Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 2 + drivers/media/usb/tlg2300/pd-radio.c | 112 ++++++++-------------------------- 2 files changed, 28 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 3a89128c3fc5..b26082af1b52 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "dvbdev.h" @@ -119,6 +120,7 @@ struct radio_data { unsigned int is_radio_streaming; int pre_emphasis; struct video_device fm_dev; + struct v4l2_ctrl_handler ctrl_handler; }; #define DVB_SBUF_NUM 4 diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 719c3da22193..45b3d7a769f9 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -261,104 +261,34 @@ static int fm_set_freq(struct file *file, void *priv, return set_frequency(p, argp->frequency); } -static int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *arg) +static int tlg_fm_s_ctrl(struct v4l2_ctrl *ctrl) { - return 0; -} - -static int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh, - struct v4l2_ext_controls *ctrls) -{ - struct poseidon *p = file->private_data; - int i; - - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) - return -EINVAL; - - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) - continue; - - if (i < MAX_PREEMPHASIS) - ctrl->value = p->radio_data.pre_emphasis; - } - return 0; -} - -static int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh, - struct v4l2_ext_controls *ctrls) -{ - int i; - - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) - return -EINVAL; - - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) - continue; - - if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) { - struct poseidon *p = file->private_data; - int pre_emphasis = preemphasis[ctrl->value]; - u32 status; - - send_set_req(p, TUNER_AUD_ANA_STD, - pre_emphasis, &status); - p->radio_data.pre_emphasis = pre_emphasis; - } - } - return 0; -} - -static int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - return 0; -} - -static int tlg_fm_vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *ctrl) -{ - if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) - return -EINVAL; + struct poseidon *p = container_of(ctrl->handler, struct poseidon, + radio_data.ctrl_handler); + int pre_emphasis; + u32 status; - ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL; - if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) { - /* return the next supported control */ - ctrl->id = V4L2_CID_TUNE_PREEMPHASIS; - v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED, - V4L2_PREEMPHASIS_75_uS, 1, - V4L2_PREEMPHASIS_50_uS); - ctrl->flags = V4L2_CTRL_FLAG_UPDATE; + switch (ctrl->id) { + case V4L2_CID_TUNE_PREEMPHASIS: + pre_emphasis = preemphasis[ctrl->val]; + send_set_req(p, TUNER_AUD_ANA_STD, pre_emphasis, &status); + p->radio_data.pre_emphasis = pre_emphasis; return 0; } return -EINVAL; } -static int tlg_fm_vidioc_querymenu(struct file *file, void *fh, - struct v4l2_querymenu *qmenu) -{ - return v4l2_ctrl_query_menu(qmenu, NULL, NULL); -} - static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) { return vt->index > 0 ? -EINVAL : 0; } +static const struct v4l2_ctrl_ops tlg_fm_ctrl_ops = { + .s_ctrl = tlg_fm_s_ctrl, +}; + static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = { .vidioc_querycap = vidioc_querycap, - .vidioc_queryctrl = tlg_fm_vidioc_queryctrl, - .vidioc_querymenu = tlg_fm_vidioc_querymenu, - .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl, - .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl, - .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl, - .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_tuner = tlg_fm_vidioc_g_tuner, .vidioc_g_frequency = fm_get_freq, @@ -376,16 +306,26 @@ static struct video_device poseidon_fm_template = { int poseidon_fm_init(struct poseidon *p) { struct video_device *vfd = &p->radio_data.fm_dev; + struct v4l2_ctrl_handler *hdl = &p->radio_data.ctrl_handler; *vfd = poseidon_fm_template; - vfd->v4l2_dev = &p->v4l2_dev; - video_set_drvdata(vfd, p); set_frequency(p, TUNER_FREQ_MIN_FM); + v4l2_ctrl_handler_init(hdl, 1); + v4l2_ctrl_new_std_menu(hdl, &tlg_fm_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS, + V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_50_uS); + if (hdl->error) { + v4l2_ctrl_handler_free(hdl); + return hdl->error; + } + vfd->v4l2_dev = &p->v4l2_dev; + vfd->ctrl_handler = hdl; + video_set_drvdata(vfd, p); return video_register_device(vfd, VFL_TYPE_RADIO, -1); } int poseidon_fm_exit(struct poseidon *p) { + v4l2_ctrl_handler_free(&p->radio_data.ctrl_handler); return 0; } -- cgit From 668cb00ed50688190417ae95cc2d2bf22ec285d2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 07:53:36 -0300 Subject: [media] tlg2300: switch to v4l2_fh This switch to v4l2_fh resolves the last v4l2_compliance issues with respect to control events and priority handling. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 1 - drivers/media/usb/tlg2300/pd-main.c | 3 ++- drivers/media/usb/tlg2300/pd-radio.c | 35 +++++++++++++++++++---------------- 3 files changed, 21 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index b26082af1b52..67ad065d2c3c 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -116,7 +116,6 @@ struct poseidon_audio { struct radio_data { __u32 fm_freq; - int users; unsigned int is_radio_streaming; int pre_emphasis; struct video_device fm_dev; diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c index 247d6ac99947..e07e4c699cc2 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/media/usb/tlg2300/pd-main.c @@ -267,7 +267,8 @@ static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev) static inline int get_autopm_ref(struct poseidon *pd) { return pd->video_data.users + pd->vbi_data.users + pd->audio.users - + atomic_read(&pd->dvb_data.users) + pd->radio_data.users; + + atomic_read(&pd->dvb_data.users) + + !list_empty(&pd->radio_data.fm_dev.fh_list); } /* fixup something for poseidon */ diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 45b3d7a769f9..854ffa007c1f 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include "pd-common.h" @@ -77,13 +79,9 @@ static int pm_fm_resume(struct poseidon *p) static int poseidon_fm_open(struct file *filp) { - struct video_device *vfd = video_devdata(filp); - struct poseidon *p = video_get_drvdata(vfd); + struct poseidon *p = video_drvdata(filp); int ret = 0; - if (!p) - return -1; - mutex_lock(&p->lock); if (p->state & POSEIDON_STATE_DISCONNECT) { ret = -ENODEV; @@ -94,9 +92,14 @@ static int poseidon_fm_open(struct file *filp) ret = -EBUSY; goto out; } + ret = v4l2_fh_open(filp); + if (ret) + goto out; usb_autopm_get_interface(p->interface); if (0 == p->state) { + struct video_device *vfd = &p->radio_data.fm_dev; + /* default pre-emphasis */ if (p->radio_data.pre_emphasis == 0) p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR; @@ -109,9 +112,7 @@ static int poseidon_fm_open(struct file *filp) } p->state |= POSEIDON_STATE_FM; } - p->radio_data.users++; kref_get(&p->kref); - filp->private_data = p; out: mutex_unlock(&p->lock); return ret; @@ -119,13 +120,12 @@ out: static int poseidon_fm_close(struct file *filp) { - struct poseidon *p = filp->private_data; + struct poseidon *p = video_drvdata(filp); struct radio_data *fm = &p->radio_data; uint32_t status; mutex_lock(&p->lock); - fm->users--; - if (0 == fm->users) + if (v4l2_fh_is_singular_file(filp)) p->state &= ~POSEIDON_STATE_FM; if (fm->is_radio_streaming && filp == p->file_for_stream) { @@ -136,14 +136,13 @@ static int poseidon_fm_close(struct file *filp) mutex_unlock(&p->lock); kref_put(&p->kref, poseidon_delete); - filp->private_data = NULL; - return 0; + return v4l2_fh_release(filp); } static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct poseidon *p = file->private_data; + struct poseidon *p = video_drvdata(file); strlcpy(v->driver, "tele-radio", sizeof(v->driver)); strlcpy(v->card, "Telegent Poseidon", sizeof(v->card)); @@ -156,15 +155,16 @@ static const struct v4l2_file_operations poseidon_fm_fops = { .owner = THIS_MODULE, .open = poseidon_fm_open, .release = poseidon_fm_close, + .poll = v4l2_ctrl_poll, .unlocked_ioctl = video_ioctl2, }; static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) { + struct poseidon *p = video_drvdata(file); struct tuner_fm_sig_stat_s fm_stat = {}; int ret, status, count = 5; - struct poseidon *p = file->private_data; if (vt->index != 0) return -EINVAL; @@ -206,7 +206,7 @@ static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, static int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp) { - struct poseidon *p = file->private_data; + struct poseidon *p = video_drvdata(file); if (argp->tuner) return -EINVAL; @@ -249,7 +249,7 @@ error: static int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp) { - struct poseidon *p = file->private_data; + struct poseidon *p = video_drvdata(file); if (argp->tuner) return -EINVAL; @@ -293,6 +293,8 @@ static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = { .vidioc_g_tuner = tlg_fm_vidioc_g_tuner, .vidioc_g_frequency = fm_get_freq, .vidioc_s_frequency = fm_set_freq, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device poseidon_fm_template = { @@ -320,6 +322,7 @@ int poseidon_fm_init(struct poseidon *p) } vfd->v4l2_dev = &p->v4l2_dev; vfd->ctrl_handler = hdl; + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); video_set_drvdata(vfd, p); return video_register_device(vfd, VFL_TYPE_RADIO, -1); } -- cgit From 6276a074c6519946c527f03e2ab69770a62652d9 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 4 Mar 2013 21:20:21 +0100 Subject: x86: Make Linux guest support optional Put all config options needed to run Linux as a guest behind a CONFIG_HYPERVISOR_GUEST menu so that they don't get built-in by default but be selectable by the user. Also, make all units which depend on x86_hyper, depend on this new symbol so that compilation doesn't fail when CONFIG_HYPERVISOR_GUEST is disabled but those units assume its presence. Sort options in the new HYPERVISOR_GUEST menu, adapt config text and drop redundant select. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1362428421-9244-3-git-send-email-bp@alien8.de Cc: Dmitry Torokhov Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 89 ++++++++++++++++++++------------------- arch/x86/include/asm/hypervisor.h | 16 ++++--- arch/x86/kernel/cpu/Makefile | 3 +- arch/x86/lguest/Kconfig | 3 +- arch/x86/xen/Kconfig | 2 +- drivers/hv/Kconfig | 2 +- drivers/misc/Kconfig | 2 +- 7 files changed, 62 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f922a9b9a319..e9e4623bd4da 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -389,7 +389,7 @@ config X86_NUMACHIP config X86_VSMP bool "ScaleMP vSMP" - select PARAVIRT_GUEST + select HYPERVISOR_GUEST select PARAVIRT depends on X86_64 && PCI depends on X86_EXTENDED_PLATFORM @@ -596,44 +596,17 @@ config SCHED_OMIT_FRAME_POINTER If in doubt, say "Y". -menuconfig PARAVIRT_GUEST - bool "Paravirtualized guest support" +menuconfig HYPERVISOR_GUEST + bool "Linux guest support" ---help--- - Say Y here to get to see options related to running Linux under - various hypervisors. This option alone does not add any kernel code. + Say Y here to enable options for running Linux under various hyper- + visors. This option enables basic hypervisor detection and platform + setup. - If you say N, all options in this submenu will be skipped and disabled. + If you say N, all options in this submenu will be skipped and + disabled, and Linux guest support won't be built in. -if PARAVIRT_GUEST - -config PARAVIRT_TIME_ACCOUNTING - bool "Paravirtual steal time accounting" - select PARAVIRT - default n - ---help--- - Select this option to enable fine granularity task steal time - accounting. Time spent executing other tasks in parallel with - the current vCPU is discounted from the vCPU power. To account for - that, there can be a small performance impact. - - If in doubt, say N here. - -source "arch/x86/xen/Kconfig" - -config KVM_GUEST - bool "KVM Guest support (including kvmclock)" - select PARAVIRT - select PARAVIRT - select PARAVIRT_CLOCK - default y if PARAVIRT_GUEST - ---help--- - This option enables various optimizations for running under the KVM - hypervisor. It includes a paravirtualized clock, so that instead - of relying on a PIT (or probably other) emulation by the - underlying device model, the host provides the guest with - timing infrastructure such as time of day, and system time - -source "arch/x86/lguest/Kconfig" +if HYPERVISOR_GUEST config PARAVIRT bool "Enable paravirtualization code" @@ -643,6 +616,13 @@ config PARAVIRT over full virtualization. However, when run without a hypervisor the kernel is theoretically slower and slightly larger. +config PARAVIRT_DEBUG + bool "paravirt-ops debugging" + depends on PARAVIRT && DEBUG_KERNEL + ---help--- + Enable to debug paravirt_ops internals. Specifically, BUG if + a paravirt_op is missing when it is called. + config PARAVIRT_SPINLOCKS bool "Paravirtualization layer for spinlocks" depends on PARAVIRT && SMP @@ -656,17 +636,38 @@ config PARAVIRT_SPINLOCKS If you are unsure how to answer this question, answer N. -config PARAVIRT_CLOCK - bool +source "arch/x86/xen/Kconfig" -config PARAVIRT_DEBUG - bool "paravirt-ops debugging" - depends on PARAVIRT && DEBUG_KERNEL +config KVM_GUEST + bool "KVM Guest support (including kvmclock)" + depends on PARAVIRT + select PARAVIRT_CLOCK + default y ---help--- - Enable to debug paravirt_ops internals. Specifically, BUG if - a paravirt_op is missing when it is called. + This option enables various optimizations for running under the KVM + hypervisor. It includes a paravirtualized clock, so that instead + of relying on a PIT (or probably other) emulation by the + underlying device model, the host provides the guest with + timing infrastructure such as time of day, and system time + +source "arch/x86/lguest/Kconfig" + +config PARAVIRT_TIME_ACCOUNTING + bool "Paravirtual steal time accounting" + depends on PARAVIRT + default n + ---help--- + Select this option to enable fine granularity task steal time + accounting. Time spent executing other tasks in parallel with + the current vCPU is discounted from the vCPU power. To account for + that, there can be a small performance impact. + + If in doubt, say N here. + +config PARAVIRT_CLOCK + bool -endif #PARAVIRT_GUEST +endif #HYPERVISOR_GUEST config NO_BOOTMEM def_bool y diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 86095ed14135..2d4b5e6107cd 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -20,13 +20,11 @@ #ifndef _ASM_X86_HYPERVISOR_H #define _ASM_X86_HYPERVISOR_H +#ifdef CONFIG_HYPERVISOR_GUEST + #include #include -extern void init_hypervisor(struct cpuinfo_x86 *c); -extern void init_hypervisor_platform(void); -extern bool hypervisor_x2apic_available(void); - /* * x86 hypervisor information */ @@ -55,4 +53,12 @@ extern const struct hypervisor_x86 x86_hyper_ms_hyperv; extern const struct hypervisor_x86 x86_hyper_xen_hvm; extern const struct hypervisor_x86 x86_hyper_kvm; -#endif +extern void init_hypervisor(struct cpuinfo_x86 *c); +extern void init_hypervisor_platform(void); +extern bool hypervisor_x2apic_available(void); +#else +static inline void init_hypervisor(struct cpuinfo_x86 *c) { } +static inline void init_hypervisor_platform(void) { } +static inline bool hypervisor_x2apic_available(void) { return false; } +#endif /* CONFIG_HYPERVISOR_GUEST */ +#endif /* _ASM_X86_HYPERVISOR_H */ diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index a0e067d3d96c..5f81bcefbe14 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -14,7 +14,6 @@ CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o -obj-y += vmware.o hypervisor.o mshyperv.o obj-y += rdrand.o obj-y += match.o @@ -42,6 +41,8 @@ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o +obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o + quiet_cmd_mkcapflags = MKCAP $@ cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@ diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 29043d2048a0..4a0890f815c4 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig @@ -1,7 +1,6 @@ config LGUEST_GUEST bool "Lguest guest support" - select PARAVIRT - depends on X86_32 + depends on X86_32 && PARAVIRT select TTY select VIRTUALIZATION select VIRTIO diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 131dacd2748a..1a3c76505649 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -4,7 +4,7 @@ config XEN bool "Xen guest support" - select PARAVIRT + depends on PARAVIRT select PARAVIRT_CLOCK select XEN_HAVE_PVMMU depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig index 64630f15f181..0403b51d20ba 100644 --- a/drivers/hv/Kconfig +++ b/drivers/hv/Kconfig @@ -2,7 +2,7 @@ menu "Microsoft Hyper-V guest support" config HYPERV tristate "Microsoft Hyper-V client drivers" - depends on X86 && ACPI && PCI && X86_LOCAL_APIC + depends on X86 && ACPI && PCI && X86_LOCAL_APIC && HYPERVISOR_GUEST help Select this option to run Linux as a Hyper-V client operating system. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e83fdfe0c8ca..891123e31932 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -418,7 +418,7 @@ config TI_DAC7512 config VMWARE_BALLOON tristate "VMware Balloon Driver" - depends on X86 + depends on X86 && HYPERVISOR_GUEST help This is VMware physical memory management driver which acts like a "balloon" that can be inflated to reclaim physical pages -- cgit From 24fae0fe2cf02eef941fd17a1e44b747483f4bef Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Fri, 1 Feb 2013 16:40:17 -0800 Subject: mmc: s3cmci: moved mach/regs-sdi.h into s3cmci device driver Since mach/regs-sdi.h is used only for s3cmci.c, so this moves the header file into the driver file, drivers/mmc/host/s3cmci.c file. Cc: Chris Ball Tested-by: Sylwester Nawrocki Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/dma-s3c2410.c | 1 - arch/arm/mach-s3c24xx/dma-s3c2412.c | 1 - arch/arm/mach-s3c24xx/dma-s3c2440.c | 1 - arch/arm/mach-s3c24xx/dma-s3c2443.c | 1 - arch/arm/mach-s3c24xx/include/mach/regs-sdi.h | 127 -------------------------- drivers/mmc/host/s3cmci.c | 83 ++++++++++++++++- 6 files changed, 81 insertions(+), 133 deletions(-) delete mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-sdi.h (limited to 'drivers') diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c index 25d085adc93c..a6c94b820954 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2410.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2410.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c index d2408ba372cb..c0e8c3f5057e 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2412.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2412.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c index 0b86e74d104f..1c08eccd9425 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2440.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2440.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c index 05536254a3f8..000e4c69fce9 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2443.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h deleted file mode 100644 index cbf2d8884e30..000000000000 --- a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h +++ /dev/null @@ -1,127 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h - * - * Copyright (c) 2004 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * 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. - * - * S3C2410 MMC/SDIO register definitions -*/ - -#ifndef __ASM_ARM_REGS_SDI -#define __ASM_ARM_REGS_SDI "regs-sdi.h" - -#define S3C2410_SDICON (0x00) -#define S3C2410_SDIPRE (0x04) -#define S3C2410_SDICMDARG (0x08) -#define S3C2410_SDICMDCON (0x0C) -#define S3C2410_SDICMDSTAT (0x10) -#define S3C2410_SDIRSP0 (0x14) -#define S3C2410_SDIRSP1 (0x18) -#define S3C2410_SDIRSP2 (0x1C) -#define S3C2410_SDIRSP3 (0x20) -#define S3C2410_SDITIMER (0x24) -#define S3C2410_SDIBSIZE (0x28) -#define S3C2410_SDIDCON (0x2C) -#define S3C2410_SDIDCNT (0x30) -#define S3C2410_SDIDSTA (0x34) -#define S3C2410_SDIFSTA (0x38) - -#define S3C2410_SDIDATA (0x3C) -#define S3C2410_SDIIMSK (0x40) - -#define S3C2440_SDIDATA (0x40) -#define S3C2440_SDIIMSK (0x3C) - -#define S3C2440_SDICON_SDRESET (1<<8) -#define S3C2440_SDICON_MMCCLOCK (1<<5) -#define S3C2410_SDICON_BYTEORDER (1<<4) -#define S3C2410_SDICON_SDIOIRQ (1<<3) -#define S3C2410_SDICON_RWAITEN (1<<2) -#define S3C2410_SDICON_FIFORESET (1<<1) -#define S3C2410_SDICON_CLOCKTYPE (1<<0) - -#define S3C2410_SDICMDCON_ABORT (1<<12) -#define S3C2410_SDICMDCON_WITHDATA (1<<11) -#define S3C2410_SDICMDCON_LONGRSP (1<<10) -#define S3C2410_SDICMDCON_WAITRSP (1<<9) -#define S3C2410_SDICMDCON_CMDSTART (1<<8) -#define S3C2410_SDICMDCON_SENDERHOST (1<<6) -#define S3C2410_SDICMDCON_INDEX (0x3f) - -#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12) -#define S3C2410_SDICMDSTAT_CMDSENT (1<<11) -#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10) -#define S3C2410_SDICMDSTAT_RSPFIN (1<<9) -#define S3C2410_SDICMDSTAT_XFERING (1<<8) -#define S3C2410_SDICMDSTAT_INDEX (0xff) - -#define S3C2440_SDIDCON_DS_BYTE (0<<22) -#define S3C2440_SDIDCON_DS_HALFWORD (1<<22) -#define S3C2440_SDIDCON_DS_WORD (2<<22) -#define S3C2410_SDIDCON_IRQPERIOD (1<<21) -#define S3C2410_SDIDCON_TXAFTERRESP (1<<20) -#define S3C2410_SDIDCON_RXAFTERCMD (1<<19) -#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18) -#define S3C2410_SDIDCON_BLOCKMODE (1<<17) -#define S3C2410_SDIDCON_WIDEBUS (1<<16) -#define S3C2410_SDIDCON_DMAEN (1<<15) -#define S3C2410_SDIDCON_STOP (1<<14) -#define S3C2440_SDIDCON_DATSTART (1<<14) -#define S3C2410_SDIDCON_DATMODE (3<<12) -#define S3C2410_SDIDCON_BLKNUM (0x7ff) - -/* constants for S3C2410_SDIDCON_DATMODE */ -#define S3C2410_SDIDCON_XFER_READY (0<<12) -#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12) -#define S3C2410_SDIDCON_XFER_RXSTART (2<<12) -#define S3C2410_SDIDCON_XFER_TXSTART (3<<12) - -#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) -#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12) - -#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10) -#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9) -#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */ -#define S3C2410_SDIDSTA_CRCFAIL (1<<7) -#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6) -#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5) -#define S3C2410_SDIDSTA_XFERFINISH (1<<4) -#define S3C2410_SDIDSTA_BUSYFINISH (1<<3) -#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */ -#define S3C2410_SDIDSTA_TXDATAON (1<<1) -#define S3C2410_SDIDSTA_RXDATAON (1<<0) - -#define S3C2440_SDIFSTA_FIFORESET (1<<16) -#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */ -#define S3C2410_SDIFSTA_TFDET (1<<13) -#define S3C2410_SDIFSTA_RFDET (1<<12) -#define S3C2410_SDIFSTA_TFHALF (1<<11) -#define S3C2410_SDIFSTA_TFEMPTY (1<<10) -#define S3C2410_SDIFSTA_RFLAST (1<<9) -#define S3C2410_SDIFSTA_RFFULL (1<<8) -#define S3C2410_SDIFSTA_RFHALF (1<<7) -#define S3C2410_SDIFSTA_COUNTMASK (0x7f) - -#define S3C2410_SDIIMSK_RESPONSECRC (1<<17) -#define S3C2410_SDIIMSK_CMDSENT (1<<16) -#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15) -#define S3C2410_SDIIMSK_RESPONSEND (1<<14) -#define S3C2410_SDIIMSK_READWAIT (1<<13) -#define S3C2410_SDIIMSK_SDIOIRQ (1<<12) -#define S3C2410_SDIIMSK_FIFOFAIL (1<<11) -#define S3C2410_SDIIMSK_CRCSTATUS (1<<10) -#define S3C2410_SDIIMSK_DATACRC (1<<9) -#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8) -#define S3C2410_SDIIMSK_DATAFINISH (1<<7) -#define S3C2410_SDIIMSK_BUSYFINISH (1<<6) -#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */ -#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4) -#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3) -#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2) -#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1) -#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0) - -#endif /* __ASM_ARM_REGS_SDI */ diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 63fb265e0da6..8d6794cdf899 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -25,14 +25,93 @@ #include -#include - #include #include "s3cmci.h" #define DRIVER_NAME "s3c-mci" +#define S3C2410_SDICON (0x00) +#define S3C2410_SDIPRE (0x04) +#define S3C2410_SDICMDARG (0x08) +#define S3C2410_SDICMDCON (0x0C) +#define S3C2410_SDICMDSTAT (0x10) +#define S3C2410_SDIRSP0 (0x14) +#define S3C2410_SDIRSP1 (0x18) +#define S3C2410_SDIRSP2 (0x1C) +#define S3C2410_SDIRSP3 (0x20) +#define S3C2410_SDITIMER (0x24) +#define S3C2410_SDIBSIZE (0x28) +#define S3C2410_SDIDCON (0x2C) +#define S3C2410_SDIDCNT (0x30) +#define S3C2410_SDIDSTA (0x34) +#define S3C2410_SDIFSTA (0x38) + +#define S3C2410_SDIDATA (0x3C) +#define S3C2410_SDIIMSK (0x40) + +#define S3C2440_SDIDATA (0x40) +#define S3C2440_SDIIMSK (0x3C) + +#define S3C2440_SDICON_SDRESET (1 << 8) +#define S3C2410_SDICON_SDIOIRQ (1 << 3) +#define S3C2410_SDICON_FIFORESET (1 << 1) +#define S3C2410_SDICON_CLOCKTYPE (1 << 0) + +#define S3C2410_SDICMDCON_LONGRSP (1 << 10) +#define S3C2410_SDICMDCON_WAITRSP (1 << 9) +#define S3C2410_SDICMDCON_CMDSTART (1 << 8) +#define S3C2410_SDICMDCON_SENDERHOST (1 << 6) +#define S3C2410_SDICMDCON_INDEX (0x3f) + +#define S3C2410_SDICMDSTAT_CRCFAIL (1 << 12) +#define S3C2410_SDICMDSTAT_CMDSENT (1 << 11) +#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1 << 10) +#define S3C2410_SDICMDSTAT_RSPFIN (1 << 9) + +#define S3C2440_SDIDCON_DS_WORD (2 << 22) +#define S3C2410_SDIDCON_TXAFTERRESP (1 << 20) +#define S3C2410_SDIDCON_RXAFTERCMD (1 << 19) +#define S3C2410_SDIDCON_BLOCKMODE (1 << 17) +#define S3C2410_SDIDCON_WIDEBUS (1 << 16) +#define S3C2410_SDIDCON_DMAEN (1 << 15) +#define S3C2410_SDIDCON_STOP (1 << 14) +#define S3C2440_SDIDCON_DATSTART (1 << 14) + +#define S3C2410_SDIDCON_XFER_RXSTART (2 << 12) +#define S3C2410_SDIDCON_XFER_TXSTART (3 << 12) + +#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) + +#define S3C2410_SDIDSTA_SDIOIRQDETECT (1 << 9) +#define S3C2410_SDIDSTA_FIFOFAIL (1 << 8) +#define S3C2410_SDIDSTA_CRCFAIL (1 << 7) +#define S3C2410_SDIDSTA_RXCRCFAIL (1 << 6) +#define S3C2410_SDIDSTA_DATATIMEOUT (1 << 5) +#define S3C2410_SDIDSTA_XFERFINISH (1 << 4) +#define S3C2410_SDIDSTA_TXDATAON (1 << 1) +#define S3C2410_SDIDSTA_RXDATAON (1 << 0) + +#define S3C2440_SDIFSTA_FIFORESET (1 << 16) +#define S3C2440_SDIFSTA_FIFOFAIL (3 << 14) +#define S3C2410_SDIFSTA_TFDET (1 << 13) +#define S3C2410_SDIFSTA_RFDET (1 << 12) +#define S3C2410_SDIFSTA_COUNTMASK (0x7f) + +#define S3C2410_SDIIMSK_RESPONSECRC (1 << 17) +#define S3C2410_SDIIMSK_CMDSENT (1 << 16) +#define S3C2410_SDIIMSK_CMDTIMEOUT (1 << 15) +#define S3C2410_SDIIMSK_RESPONSEND (1 << 14) +#define S3C2410_SDIIMSK_SDIOIRQ (1 << 12) +#define S3C2410_SDIIMSK_FIFOFAIL (1 << 11) +#define S3C2410_SDIIMSK_CRCSTATUS (1 << 10) +#define S3C2410_SDIIMSK_DATACRC (1 << 9) +#define S3C2410_SDIIMSK_DATATIMEOUT (1 << 8) +#define S3C2410_SDIIMSK_DATAFINISH (1 << 7) +#define S3C2410_SDIIMSK_TXFIFOHALF (1 << 4) +#define S3C2410_SDIIMSK_RXFIFOLAST (1 << 2) +#define S3C2410_SDIIMSK_RXFIFOHALF (1 << 0) + enum dbg_channels { dbg_err = (1 << 0), dbg_debug = (1 << 1), -- cgit From 0db96de6258ca3851c95c7c4349b7188ac524891 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 22 Feb 2013 20:19:55 +0530 Subject: ath6kl: Cosmetic change in checking for free vif slot A minor optimization is done in finding the free slot available for the new virtual interface in the firmware. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 752ffc4f4166..ad79880ebfaf 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -402,7 +402,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, if (type == NL80211_IFTYPE_STATION || type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) { for (i = 0; i < ar->vif_max; i++) { - if ((ar->avail_idx_map >> i) & BIT(0)) { + if ((ar->avail_idx_map) & BIT(i)) { *if_idx = i; return true; } @@ -412,7 +412,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) { for (i = ar->max_norm_iface; i < ar->vif_max; i++) { - if ((ar->avail_idx_map >> i) & BIT(0)) { + if ((ar->avail_idx_map) & BIT(i)) { *if_idx = i; return true; } -- cgit From bc52aab380c7beb49d20ea6e77e8239b9ffe74a9 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 22 Feb 2013 20:20:09 +0530 Subject: ath6kl: Protect ath6kl_cfg80211_vif_cleanup using rtnl_locks ath6kl_cfg80211_vif_cleanup calls 'unregister_netdevice' which inturn calls 'unregister_netdevice_queue' and it requires holding rtnl_lock semaphore protection. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index ad79880ebfaf..982dbf666a15 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1535,7 +1535,9 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag)); + rtnl_lock(); ath6kl_cfg80211_vif_cleanup(vif); + rtnl_unlock(); return 0; } -- cgit From bf9781454731c17085bc4708c09ada50f1b63120 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 22 Feb 2013 20:20:21 +0530 Subject: ath6kl: Return error from ath6kl_bmi_done() This addresses a FIXME in the driver. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 6 ++---- drivers/net/wireless/ath/ath6kl/sdio.c | 6 ++++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 5d434cf88f35..072a2295eff8 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1569,11 +1569,9 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) goto err_power_off; /* Do we need to finish the BMI phase */ - /* FIXME: return error from ath6kl_bmi_done() */ - if (ath6kl_bmi_done(ar)) { - ret = -EIO; + ret = ath6kl_bmi_done(ar); + if (ret) goto err_power_off; - } /* * The reason we have to wait for the target here is that the diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index d111980d44c0..0bd8ff69461a 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1123,10 +1123,12 @@ static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len, HIF_WR_SYNC_BYTE_INC); - if (ret) + if (ret) { ath6kl_err("unable to send the bmi data to the device\n"); + return ret; + } - return ret; + return 0; } static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) -- cgit From 4ce720b6f0302aae5c47fa4a6493fb86ec730c96 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 22 Feb 2013 20:20:33 +0530 Subject: ath6kl: Remove NETDEV_REGISTERED flag Currently its no where used. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 - drivers/net/wireless/ath/ath6kl/core.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 982dbf666a15..538c6a1cf8cc 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -3661,7 +3661,6 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, vif->sme_state = SME_DISCONNECTED; set_bit(WLAN_ENABLED, &vif->flags); ar->wlan_pwr_state = WLAN_POWER_STATE_ON; - set_bit(NETDEV_REGISTERED, &vif->flags); if (type == NL80211_IFTYPE_ADHOC) ar->ibss_if_active = true; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 61b2f98b4e77..1c9ed40358d8 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -560,7 +560,6 @@ enum ath6kl_vif_state { WMM_ENABLED, NETQ_STOPPED, DTIM_EXPIRED, - NETDEV_REGISTERED, CLEAR_BSSFILTER_ON_BEACON, DTIM_PERIOD_AVAIL, WLAN_ENABLED, -- cgit From 42af657feb3481b1dfc130619b5e0d56abc4e0fc Mon Sep 17 00:00:00 2001 From: Li Fei Date: Thu, 28 Feb 2013 15:51:32 +0800 Subject: wl1251: call pm_runtime_put_sync in pm_runtime_get_sync failed case Even in failed case of pm_runtime_get_sync, the usage_count is incremented. In order to keep the usage_count with correct value and runtime power management to behave correctly, call pm_runtime_put(_sync) in such case. Signed-off-by Liu Chuansheng Signed-off-by: Li Fei Signed-off-by: Luciano Coelho --- drivers/net/wireless/ti/wl1251/sdio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index e57ee48edff6..e2b3d9c541e8 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -186,8 +186,10 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) wl->set_power(true); ret = pm_runtime_get_sync(&func->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_sync(&func->dev); goto out; + } sdio_claim_host(func); sdio_enable_func(func); -- cgit From e5834d620d61d01444c41958f1816d688a96433c Mon Sep 17 00:00:00 2001 From: Shankar Brahadeeswaran Date: Wed, 20 Feb 2013 23:41:26 +0530 Subject: staging: android: ashmem: get_name,set_name not to hold ashmem_mutex Problem: There exists a path in ashmem driver that could lead to acquistion of mm->mmap_sem, ashmem_mutex in reverse order. This could lead to deadlock in the system. For Example, assume that mmap is called on a ashmem region in the context of a thread say T1. sys_mmap_pgoff (1. acquires mm->mmap_sem) | --> mmap_region | ----> ashmem_mmap (2. acquires asmem_mutex) Now if there is a context switch after 1 and before 2, and if another thread T2 (that shares the mm struct) invokes an ioctl say ASHMEM_GET_NAME, this can lead to the following path ashmem_ioctl | -->get_name (3. acquires ashmem_mutex) | ---> copy_to_user (4. acquires the mm->mmap_sem) Note that the copy_to_user could lead to a valid fault if no physical page is allocated yet for the user address passed. Now T1 has mmap_sem and is waiting for ashmem_mutex. and T2 has the ashmem_mutex and is waiting for mmap_sem Thus leading to deadlock. Solution: Do not call copy_to_user or copy_from_user while holding the ahsmem_mutex. Instead copy this to a local buffer that lives in the stack while holding this lock. This will maintain data integrity as well never reverse the lock order. Testing: Created a unit test case to reproduce the problem. Used the same to test this fix on kernel version 3.4.0 Ported the same patch to 3.8 Signed-off-by: Shankar Brahadeeswaran Reviewed-by: Dan Carpenter Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 45 ++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 634b9ae713e0..38a9135a2f6d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -414,20 +414,29 @@ out: static int set_name(struct ashmem_area *asma, void __user *name) { int ret = 0; + char local_name[ASHMEM_NAME_LEN]; - mutex_lock(&ashmem_mutex); + /* + * Holding the ashmem_mutex while doing a copy_from_user might cause + * an data abort which would try to access mmap_sem. If another + * thread has invoked ashmem_mmap then it will be holding the + * semaphore and will be waiting for ashmem_mutex, there by leading to + * deadlock. We'll release the mutex and take the name to a local + * variable that does not need protection and later copy the local + * variable to the structure member with lock held. + */ + if (copy_from_user(local_name, name, ASHMEM_NAME_LEN)) + return -EFAULT; + mutex_lock(&ashmem_mutex); /* cannot change an existing mapping's name */ if (unlikely(asma->file)) { ret = -EINVAL; goto out; } - - if (unlikely(copy_from_user(asma->name + ASHMEM_NAME_PREFIX_LEN, - name, ASHMEM_NAME_LEN))) - ret = -EFAULT; + memcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, + local_name, ASHMEM_NAME_LEN); asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0'; - out: mutex_unlock(&ashmem_mutex); @@ -437,26 +446,36 @@ out: static int get_name(struct ashmem_area *asma, void __user *name) { int ret = 0; + size_t len; + /* + * Have a local variable to which we'll copy the content + * from asma with the lock held. Later we can copy this to the user + * space safely without holding any locks. So even if we proceed to + * wait for mmap_sem, it won't lead to deadlock. + */ + char local_name[ASHMEM_NAME_LEN]; mutex_lock(&ashmem_mutex); if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') { - size_t len; /* * Copying only `len', instead of ASHMEM_NAME_LEN, bytes * prevents us from revealing one user's stack to another. */ len = strlen(asma->name + ASHMEM_NAME_PREFIX_LEN) + 1; - if (unlikely(copy_to_user(name, - asma->name + ASHMEM_NAME_PREFIX_LEN, len))) - ret = -EFAULT; + memcpy(local_name, asma->name + ASHMEM_NAME_PREFIX_LEN, len); } else { - if (unlikely(copy_to_user(name, ASHMEM_NAME_DEF, - sizeof(ASHMEM_NAME_DEF)))) - ret = -EFAULT; + len = sizeof(ASHMEM_NAME_DEF); + memcpy(local_name, ASHMEM_NAME_DEF, len); } mutex_unlock(&ashmem_mutex); + /* + * Now we are just copying from the stack variable to userland + * No lock held + */ + if (unlikely(copy_to_user(name, local_name, len))) + ret = -EFAULT; return ret; } -- cgit From eeb0f4f35fc1a4c0a5e30ec73e8e61916afa0399 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Tue, 26 Feb 2013 22:07:35 -0800 Subject: staging: android: lowmemorykiller: Don't count reserved free memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The amount of reserved memory varies between devices. Subtract it here to reduce the amount of devices specific tuning needed for the minfree values. Cc: Android Kernel Team Cc: Arve Hjønnevåg Signed-off-by: Arve Hjønnevåg Signed-off-by: John Stultz Acked-by: David Rientjes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 3b91b0fd4de3..18423d28414b 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) int selected_tasksize = 0; short selected_oom_score_adj; int array_size = ARRAY_SIZE(lowmem_adj); - int other_free = global_page_state(NR_FREE_PAGES); + int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages; int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); -- cgit From 99150f6a1a015de275a83ca95aa5f4054b409f40 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Tue, 26 Feb 2013 22:07:36 -0800 Subject: staging: android: lowmemorykiller: Change default debug_level to 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The select...to kill messages are not very useful when not debugging the lowmemorykiller itself. After the change to check TIF_MEMDIE instead of using a task notifer this message can also get very noisy. Cc: Android Kernel Team Cc: Arve Hjønnevåg Cc: Greg Kroah-Hartman Signed-off-by: Arve Hjønnevåg Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 18423d28414b..53d80c2650ec 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -40,7 +40,7 @@ #include #include -static uint32_t lowmem_debug_level = 2; +static uint32_t lowmem_debug_level = 1; static short lowmem_adj[6] = { 0, 1, -- cgit From 0441bcf4db64e9825937916fe64d539d12c3fead Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 26 Feb 2013 22:07:37 -0800 Subject: staging: android: logger: Allow a UID to read it's own log entries Modify the kernel logger to record the UID associated with the log entries. Always allow the same UID which generated a log message to read the log message. Allow anyone in the logs group, or anyone with CAP_SYSLOG, to read all log entries. In addition, allow the client to upgrade log formats, so they can get additional information from the kernel. Cc: Android Kernel Team Cc: Nick Kralevich Signed-off-by: Nick Kralevich Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 191 ++++++++++++++++++++++++++++++++++----- drivers/staging/android/logger.h | 40 +++++++- 2 files changed, 202 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index dbc63cbb4d3a..cfa606110cc2 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -68,6 +68,8 @@ static LIST_HEAD(log_list); * @log: The associated log * @list: The associated entry in @logger_log's list * @r_off: The current read head offset. + * @r_all: Reader can read all entries + * @r_ver: Reader ABI version * * This object lives from open to release, so we don't need additional * reference counting. The structure is protected by log->mutex. @@ -76,6 +78,8 @@ struct logger_reader { struct logger_log *log; struct list_head list; size_t r_off; + bool r_all; + int r_ver; }; /* logger_offset - returns index 'n' into the log via (optimized) modulus */ @@ -109,8 +113,29 @@ static inline struct logger_log *file_get_log(struct file *file) } /* - * get_entry_len - Grabs the length of the payload of the next entry starting - * from 'off'. + * get_entry_header - returns a pointer to the logger_entry header within + * 'log' starting at offset 'off'. A temporary logger_entry 'scratch' must + * be provided. Typically the return value will be a pointer within + * 'logger->buf'. However, a pointer to 'scratch' may be returned if + * the log entry spans the end and beginning of the circular buffer. + */ +static struct logger_entry *get_entry_header(struct logger_log *log, + size_t off, struct logger_entry *scratch) +{ + size_t len = min(sizeof(struct logger_entry), log->size - off); + if (len != sizeof(struct logger_entry)) { + memcpy(((void *) scratch), log->buffer + off, len); + memcpy(((void *) scratch) + len, log->buffer, + sizeof(struct logger_entry) - len); + return scratch; + } + + return (struct logger_entry *) (log->buffer + off); +} + +/* + * get_entry_msg_len - Grabs the length of the message of the entry + * starting from from 'off'. * * An entry length is 2 bytes (16 bits) in host endian order. * In the log, the length does not include the size of the log entry structure. @@ -118,20 +143,45 @@ static inline struct logger_log *file_get_log(struct file *file) * * Caller needs to hold log->mutex. */ -static __u32 get_entry_len(struct logger_log *log, size_t off) +static __u32 get_entry_msg_len(struct logger_log *log, size_t off) { - __u16 val; + struct logger_entry scratch; + struct logger_entry *entry; - /* copy 2 bytes from buffer, in memcpy order, */ - /* handling possible wrap at end of buffer */ + entry = get_entry_header(log, off, &scratch); + return entry->len; +} - ((__u8 *)&val)[0] = log->buffer[off]; - if (likely(off+1 < log->size)) - ((__u8 *)&val)[1] = log->buffer[off+1]; +static size_t get_user_hdr_len(int ver) +{ + if (ver < 2) + return sizeof(struct user_logger_entry_compat); else - ((__u8 *)&val)[1] = log->buffer[0]; + return sizeof(struct logger_entry); +} + +static ssize_t copy_header_to_user(int ver, struct logger_entry *entry, + char __user *buf) +{ + void *hdr; + size_t hdr_len; + struct user_logger_entry_compat v1; + + if (ver < 2) { + v1.len = entry->len; + v1.__pad = 0; + v1.pid = entry->pid; + v1.tid = entry->tid; + v1.sec = entry->sec; + v1.nsec = entry->nsec; + hdr = &v1; + hdr_len = sizeof(struct user_logger_entry_compat); + } else { + hdr = entry; + hdr_len = sizeof(struct logger_entry); + } - return sizeof(struct logger_entry) + val; + return copy_to_user(buf, hdr, hdr_len); } /* @@ -145,15 +195,31 @@ static ssize_t do_read_log_to_user(struct logger_log *log, char __user *buf, size_t count) { + struct logger_entry scratch; + struct logger_entry *entry; size_t len; + size_t msg_start; /* - * We read from the log in two disjoint operations. First, we read from - * the current read head offset up to 'count' bytes or to the end of + * First, copy the header to userspace, using the version of + * the header requested + */ + entry = get_entry_header(log, reader->r_off, &scratch); + if (copy_header_to_user(reader->r_ver, entry, buf)) + return -EFAULT; + + count -= get_user_hdr_len(reader->r_ver); + buf += get_user_hdr_len(reader->r_ver); + msg_start = logger_offset(log, + reader->r_off + sizeof(struct logger_entry)); + + /* + * We read from the msg in two disjoint operations. First, we read from + * the current msg head offset up to 'count' bytes or to the end of * the log, whichever comes first. */ - len = min(count, log->size - reader->r_off); - if (copy_to_user(buf, log->buffer + reader->r_off, len)) + len = min(count, log->size - msg_start); + if (copy_to_user(buf, log->buffer + msg_start, len)) return -EFAULT; /* @@ -164,9 +230,34 @@ static ssize_t do_read_log_to_user(struct logger_log *log, if (copy_to_user(buf + len, log->buffer, count - len)) return -EFAULT; - reader->r_off = logger_offset(log, reader->r_off + count); + reader->r_off = logger_offset(log, reader->r_off + + sizeof(struct logger_entry) + count); - return count; + return count + get_user_hdr_len(reader->r_ver); +} + +/* + * get_next_entry_by_uid - Starting at 'off', returns an offset into + * 'log->buffer' which contains the first entry readable by 'euid' + */ +static size_t get_next_entry_by_uid(struct logger_log *log, + size_t off, uid_t euid) +{ + while (off != log->w_off) { + struct logger_entry *entry; + struct logger_entry scratch; + size_t next_len; + + entry = get_entry_header(log, off, &scratch); + + if (entry->euid == euid) + return off; + + next_len = sizeof(struct logger_entry) + entry->len; + off = logger_offset(log, off + next_len); + } + + return off; } /* @@ -178,7 +269,7 @@ static ssize_t do_read_log_to_user(struct logger_log *log, * - If there are no log entries to read, blocks until log is written to * - Atomically reads exactly one log entry * - * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read + * Will set errno to EINVAL if read * buffer is insufficient to hold next entry. */ static ssize_t logger_read(struct file *file, char __user *buf, @@ -219,6 +310,10 @@ start: mutex_lock(&log->mutex); + if (!reader->r_all) + reader->r_off = get_next_entry_by_uid(log, + reader->r_off, current_euid()); + /* is there still something to read or did we race? */ if (unlikely(log->w_off == reader->r_off)) { mutex_unlock(&log->mutex); @@ -226,7 +321,8 @@ start: } /* get the size of the next entry */ - ret = get_entry_len(log, reader->r_off); + ret = get_user_hdr_len(reader->r_ver) + + get_entry_msg_len(log, reader->r_off); if (count < ret) { ret = -EINVAL; goto out; @@ -252,7 +348,8 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) size_t count = 0; do { - size_t nr = get_entry_len(log, off); + size_t nr = sizeof(struct logger_entry) + + get_entry_msg_len(log, off); off = logger_offset(log, off + nr); count += nr; } while (count < len); @@ -382,7 +479,9 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, header.tid = current->pid; header.sec = now.tv_sec; header.nsec = now.tv_nsec; + header.euid = current_euid(); header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); + header.hdr_size = sizeof(struct logger_entry); /* null writes succeed, return zero */ if (unlikely(!header.len)) @@ -463,6 +562,10 @@ static int logger_open(struct inode *inode, struct file *file) return -ENOMEM; reader->log = log; + reader->r_ver = 1; + reader->r_all = in_egroup_p(inode->i_gid) || + capable(CAP_SYSLOG); + INIT_LIST_HEAD(&reader->list); mutex_lock(&log->mutex); @@ -522,6 +625,10 @@ static unsigned int logger_poll(struct file *file, poll_table *wait) poll_wait(file, &log->wq, wait); mutex_lock(&log->mutex); + if (!reader->r_all) + reader->r_off = get_next_entry_by_uid(log, + reader->r_off, current_euid()); + if (log->w_off != reader->r_off) ret |= POLLIN | POLLRDNORM; mutex_unlock(&log->mutex); @@ -529,11 +636,25 @@ static unsigned int logger_poll(struct file *file, poll_table *wait) return ret; } +static long logger_set_version(struct logger_reader *reader, void __user *arg) +{ + int version; + if (copy_from_user(&version, arg, sizeof(int))) + return -EFAULT; + + if ((version < 1) || (version > 2)) + return -EINVAL; + + reader->r_ver = version; + return 0; +} + static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct logger_log *log = file_get_log(file); struct logger_reader *reader; - long ret = -ENOTTY; + long ret = -EINVAL; + void __user *argp = (void __user *) arg; mutex_lock(&log->mutex); @@ -558,8 +679,14 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } reader = file->private_data; + + if (!reader->r_all) + reader->r_off = get_next_entry_by_uid(log, + reader->r_off, current_euid()); + if (log->w_off != reader->r_off) - ret = get_entry_len(log, reader->r_off); + ret = get_user_hdr_len(reader->r_ver) + + get_entry_msg_len(log, reader->r_off); else ret = 0; break; @@ -573,6 +700,22 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) log->head = log->w_off; ret = 0; break; + case LOGGER_GET_VERSION: + if (!(file->f_mode & FMODE_READ)) { + ret = -EBADF; + break; + } + reader = file->private_data; + ret = reader->r_ver; + break; + case LOGGER_SET_VERSION: + if (!(file->f_mode & FMODE_READ)) { + ret = -EBADF; + break; + } + reader = file->private_data; + ret = logger_set_version(reader, argp); + break; } mutex_unlock(&log->mutex); @@ -592,8 +735,8 @@ static const struct file_operations logger_fops = { }; /* - * Log size must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, - * and less than LONG_MAX minus LOGGER_ENTRY_MAX_LEN. + * Log size must must be a power of two, and greater than + * (LOGGER_ENTRY_MAX_PAYLOAD + sizeof(struct logger_entry)). */ static int __init create_log(char *log_name, int size) { diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h index 9b929a8c7468..cc6bbd99c8e0 100644 --- a/drivers/staging/android/logger.h +++ b/drivers/staging/android/logger.h @@ -21,7 +21,7 @@ #include /** - * struct logger_entry - defines a single entry that is given to a logger + * struct user_logger_entry_compat - defines a single entry that is given to a logger * @len: The length of the payload * @__pad: Two bytes of padding that appear to be required * @pid: The generating process' process ID @@ -29,8 +29,12 @@ * @sec: The number of seconds that have elapsed since the Epoch * @nsec: The number of nanoseconds that have elapsed since @sec * @msg: The message that is to be logged + * + * The userspace structure for version 1 of the logger_entry ABI. + * This structure is returned to userspace unless the caller requests + * an upgrade to a newer ABI version. */ -struct logger_entry { +struct user_logger_entry_compat { __u16 len; __u16 __pad; __s32 pid; @@ -40,14 +44,38 @@ struct logger_entry { char msg[0]; }; +/** + * struct logger_entry - defines a single entry that is given to a logger + * @len: The length of the payload + * @hdr_size: sizeof(struct logger_entry_v2) + * @pid: The generating process' process ID + * @tid: The generating process' thread ID + * @sec: The number of seconds that have elapsed since the Epoch + * @nsec: The number of nanoseconds that have elapsed since @sec + * @euid: Effective UID of logger + * @msg: The message that is to be logged + * + * The structure for version 2 of the logger_entry ABI. + * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION) + * is called with version >= 2 + */ +struct logger_entry { + __u16 len; + __u16 hdr_size; + __s32 pid; + __s32 tid; + __s32 sec; + __s32 nsec; + uid_t euid; + char msg[0]; +}; + #define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ #define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ #define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */ #define LOGGER_LOG_MAIN "log_main" /* everything else */ -#define LOGGER_ENTRY_MAX_LEN (4*1024) -#define LOGGER_ENTRY_MAX_PAYLOAD \ - (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) +#define LOGGER_ENTRY_MAX_PAYLOAD 4076 #define __LOGGERIO 0xAE @@ -55,5 +83,7 @@ struct logger_entry { #define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ #define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ #define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ +#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */ +#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */ #endif /* _LINUX_LOGGER_H */ -- cgit From 1e70bd46a5a950b7ba319e50bdfed9d20ed9fd73 Mon Sep 17 00:00:00 2001 From: Charndeep Grewal Date: Tue, 26 Feb 2013 22:07:38 -0800 Subject: staging: android: logger: enforce GID and CAP check on log flush Restrict log flushing to those in the logs group, or anyone with CAP_SYSLOG. Cc: Android Kernel Team Cc: Charndeep Grewal Signed-off-by: Charndeep Grewal Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index cfa606110cc2..b14a55742559 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -695,6 +695,11 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = -EBADF; break; } + if (!(in_egroup_p(file->f_dentry->d_inode->i_gid) || + capable(CAP_SYSLOG))) { + ret = -EPERM; + break; + } list_for_each_entry(reader, &log->readers, list) reader->r_off = log->w_off; log->head = log->w_off; -- cgit From 7937d74aa26bd8415f301e916d70e2e91b53b8a9 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:11 -0500 Subject: zcache: s/int/bool/ on the various options. There are so many, but this allows us to at least have them right in as bool. Acked-by: Dan Magenheimer [v1: Rebase on ramster->zcache move] [v2: Rebase on staging/zcache: Fix/improve zcache writeback code, tie to a config option] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 328898ea76c3..d7dd02cbf80e 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -34,9 +34,9 @@ #include "zbud.h" #include "ramster.h" #ifdef CONFIG_RAMSTER -static int ramster_enabled; +static bool ramster_enabled __read_mostly; #else -#define ramster_enabled 0 +#define ramster_enabled false #endif #ifndef __PG_WAS_ACTIVE @@ -62,11 +62,11 @@ static inline void frontswap_tmem_exclusive_gets(bool b) /* enable (or fix code) when Seth's patches are accepted upstream */ #define zcache_writeback_enabled 0 -static int zcache_enabled __read_mostly; -static int disable_cleancache __read_mostly; -static int disable_frontswap __read_mostly; -static int disable_frontswap_ignore_nonactive __read_mostly; -static int disable_cleancache_ignore_nonactive __read_mostly; +static bool zcache_enabled __read_mostly; +static bool disable_cleancache __read_mostly; +static bool disable_frontswap __read_mostly; +static bool disable_frontswap_ignore_nonactive __read_mostly; +static bool disable_cleancache_ignore_nonactive __read_mostly; static char *namestr __read_mostly = "zcache"; #define ZCACHE_GFP_MASK \ @@ -1841,16 +1841,16 @@ struct frontswap_ops zcache_frontswap_register_ops(void) static int __init enable_zcache(char *s) { - zcache_enabled = 1; + zcache_enabled = true; return 1; } __setup("zcache", enable_zcache); static int __init enable_ramster(char *s) { - zcache_enabled = 1; + zcache_enabled = true; #ifdef CONFIG_RAMSTER - ramster_enabled = 1; + ramster_enabled = true; #endif return 1; } @@ -1860,7 +1860,7 @@ __setup("ramster", enable_ramster); static int __init no_cleancache(char *s) { - disable_cleancache = 1; + disable_cleancache = true; return 1; } @@ -1868,7 +1868,7 @@ __setup("nocleancache", no_cleancache); static int __init no_frontswap(char *s) { - disable_frontswap = 1; + disable_frontswap = true; return 1; } @@ -1884,7 +1884,7 @@ __setup("nofrontswapexclusivegets", no_frontswap_exclusive_gets); static int __init no_frontswap_ignore_nonactive(char *s) { - disable_frontswap_ignore_nonactive = 1; + disable_frontswap_ignore_nonactive = true; return 1; } @@ -1892,7 +1892,7 @@ __setup("nofrontswapignorenonactive", no_frontswap_ignore_nonactive); static int __init no_cleancache_ignore_nonactive(char *s) { - disable_cleancache_ignore_nonactive = 1; + disable_cleancache_ignore_nonactive = true; return 1; } @@ -1901,7 +1901,7 @@ __setup("nocleancacheignorenonactive", no_cleancache_ignore_nonactive); static int __init enable_zcache_compressor(char *s) { strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ); - zcache_enabled = 1; + zcache_enabled = true; return 1; } __setup("zcache=", enable_zcache_compressor); -- cgit From 3f007ca44935b5b4a773bb0bdbb8bb3045bbd6cb Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:12 -0500 Subject: zcache: Provide accessory functions for counter increase This is the first step in moving the debugfs code out of the main file in-to another file. And also allow the code to run without CONFIG_DEBUG_FS defined. Acked-by: Dan Magenheimer [v2: Rebase on top staging/zcache: Fix/improve zcache writeback code, tie to a config option] [v3: Rebase on top of zcache: Fix compile warnings due to usage of debugfs_create_size_t] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 109 +++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index d7dd02cbf80e..a3c5b7dae981 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -139,32 +139,87 @@ static ssize_t zcache_obj_count; static atomic_t zcache_obj_atomic = ATOMIC_INIT(0); static ssize_t zcache_obj_count_max; static ssize_t zcache_objnode_count; +static inline void inc_zcache_obj_count(void) +{ + zcache_obj_count = atomic_inc_return(&zcache_obj_atomic); + if (zcache_obj_count > zcache_obj_count_max) + zcache_obj_count_max = zcache_obj_count; +} + static atomic_t zcache_objnode_atomic = ATOMIC_INIT(0); static ssize_t zcache_objnode_count_max; +static inline void inc_zcache_objnode_count(void) +{ + zcache_objnode_count = atomic_inc_return(&zcache_objnode_atomic); + if (zcache_objnode_count > zcache_objnode_count_max) + zcache_objnode_count_max = zcache_objnode_count; +}; static u64 zcache_eph_zbytes; static atomic_long_t zcache_eph_zbytes_atomic = ATOMIC_INIT(0); static u64 zcache_eph_zbytes_max; +static inline void inc_zcache_eph_zbytes(unsigned clen) +{ + zcache_eph_zbytes = atomic_long_add_return(clen, &zcache_eph_zbytes_atomic); + if (zcache_eph_zbytes > zcache_eph_zbytes_max) + zcache_eph_zbytes_max = zcache_eph_zbytes; +}; static u64 zcache_pers_zbytes; static atomic_long_t zcache_pers_zbytes_atomic = ATOMIC_INIT(0); static u64 zcache_pers_zbytes_max; static ssize_t zcache_eph_pageframes; +static inline void inc_zcache_pers_zbytes(unsigned clen) +{ + zcache_pers_zbytes = atomic_long_add_return(clen, &zcache_pers_zbytes_atomic); + if (zcache_pers_zbytes > zcache_pers_zbytes_max) + zcache_pers_zbytes_max = zcache_pers_zbytes; +} static atomic_t zcache_eph_pageframes_atomic = ATOMIC_INIT(0); static ssize_t zcache_eph_pageframes_max; static ssize_t zcache_pers_pageframes; +static inline void inc_zcache_eph_pageframes(void) +{ + zcache_eph_pageframes = atomic_inc_return(&zcache_eph_pageframes_atomic); + if (zcache_eph_pageframes > zcache_eph_pageframes_max) + zcache_eph_pageframes_max = zcache_eph_pageframes; +}; static atomic_t zcache_pers_pageframes_atomic = ATOMIC_INIT(0); static ssize_t zcache_pers_pageframes_max; static ssize_t zcache_pageframes_alloced; +static inline void inc_zcache_pers_pageframes(void) +{ + zcache_pers_pageframes = atomic_inc_return(&zcache_pers_pageframes_atomic); + if (zcache_pers_pageframes > zcache_pers_pageframes_max) + zcache_pers_pageframes_max = zcache_pers_pageframes; +} static atomic_t zcache_pageframes_alloced_atomic = ATOMIC_INIT(0); static ssize_t zcache_pageframes_freed; +static inline void inc_zcache_pageframes_alloced(void) +{ + zcache_pageframes_alloced = atomic_inc_return(&zcache_pageframes_alloced_atomic); +}; static atomic_t zcache_pageframes_freed_atomic = ATOMIC_INIT(0); static ssize_t zcache_eph_zpages; -static ssize_t zcache_eph_zpages; +static inline void inc_zcache_pageframes_freed(void) +{ + zcache_pageframes_freed = atomic_inc_return(&zcache_pageframes_freed_atomic); +} static atomic_t zcache_eph_zpages_atomic = ATOMIC_INIT(0); static ssize_t zcache_eph_zpages_max; static ssize_t zcache_pers_zpages; +static inline void inc_zcache_eph_zpages(void) +{ + zcache_eph_zpages = atomic_inc_return(&zcache_eph_zpages_atomic); + if (zcache_eph_zpages > zcache_eph_zpages_max) + zcache_eph_zpages_max = zcache_eph_zpages; +} static atomic_t zcache_pers_zpages_atomic = ATOMIC_INIT(0); static ssize_t zcache_pers_zpages_max; - +static inline void inc_zcache_pers_zpages(void) +{ + zcache_pers_zpages = atomic_inc_return(&zcache_pers_zpages_atomic); + if (zcache_pers_zpages > zcache_pers_zpages_max) + zcache_pers_zpages_max = zcache_pers_zpages; +} /* but for the rest of these, counting races are ok */ static ssize_t zcache_flush_total; static ssize_t zcache_flush_found; @@ -422,9 +477,7 @@ static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) } } BUG_ON(objnode == NULL); - zcache_objnode_count = atomic_inc_return(&zcache_objnode_atomic); - if (zcache_objnode_count > zcache_objnode_count_max) - zcache_objnode_count_max = zcache_objnode_count; + inc_zcache_objnode_count(); return objnode; } @@ -446,9 +499,7 @@ static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) obj = kp->obj; BUG_ON(obj == NULL); kp->obj = NULL; - zcache_obj_count = atomic_inc_return(&zcache_obj_atomic); - if (zcache_obj_count > zcache_obj_count_max) - zcache_obj_count_max = zcache_obj_count; + inc_zcache_obj_count(); return obj; } @@ -472,8 +523,7 @@ static struct page *zcache_alloc_page(void) struct page *page = alloc_page(ZCACHE_GFP_MASK); if (page != NULL) - zcache_pageframes_alloced = - atomic_inc_return(&zcache_pageframes_alloced_atomic); + inc_zcache_pageframes_alloced(); return page; } @@ -485,8 +535,7 @@ static void zcache_free_page(struct page *page) if (page == NULL) BUG(); __free_page(page); - zcache_pageframes_freed = - atomic_inc_return(&zcache_pageframes_freed_atomic); + inc_zcache_pageframes_freed(); curr_pageframes = zcache_pageframes_alloced - atomic_read(&zcache_pageframes_freed_atomic) - atomic_read(&zcache_eph_pageframes_atomic) - @@ -551,19 +600,11 @@ static void *zcache_pampd_eph_create(char *data, size_t size, bool raw, create_in_new_page: pampd = (void *)zbud_create_prep(th, true, cdata, clen, newpage); BUG_ON(pampd == NULL); - zcache_eph_pageframes = - atomic_inc_return(&zcache_eph_pageframes_atomic); - if (zcache_eph_pageframes > zcache_eph_pageframes_max) - zcache_eph_pageframes_max = zcache_eph_pageframes; + inc_zcache_eph_pageframes(); got_pampd: - zcache_eph_zbytes = - atomic_long_add_return(clen, &zcache_eph_zbytes_atomic); - if (zcache_eph_zbytes > zcache_eph_zbytes_max) - zcache_eph_zbytes_max = zcache_eph_zbytes; - zcache_eph_zpages = atomic_inc_return(&zcache_eph_zpages_atomic); - if (zcache_eph_zpages > zcache_eph_zpages_max) - zcache_eph_zpages_max = zcache_eph_zpages; + inc_zcache_eph_zbytes(clen); + inc_zcache_eph_zpages(); if (ramster_enabled && raw) ramster_count_foreign_pages(true, 1); out: @@ -633,19 +674,11 @@ create_pampd: create_in_new_page: pampd = (void *)zbud_create_prep(th, false, cdata, clen, newpage); BUG_ON(pampd == NULL); - zcache_pers_pageframes = - atomic_inc_return(&zcache_pers_pageframes_atomic); - if (zcache_pers_pageframes > zcache_pers_pageframes_max) - zcache_pers_pageframes_max = zcache_pers_pageframes; + inc_zcache_pers_pageframes(); got_pampd: - zcache_pers_zpages = atomic_inc_return(&zcache_pers_zpages_atomic); - if (zcache_pers_zpages > zcache_pers_zpages_max) - zcache_pers_zpages_max = zcache_pers_zpages; - zcache_pers_zbytes = - atomic_long_add_return(clen, &zcache_pers_zbytes_atomic); - if (zcache_pers_zbytes > zcache_pers_zbytes_max) - zcache_pers_zbytes_max = zcache_pers_zbytes; + inc_zcache_pers_zpages(); + inc_zcache_pers_zbytes(clen); if (ramster_enabled && raw) ramster_count_foreign_pages(false, 1); out: @@ -991,6 +1024,11 @@ out: static atomic_t zcache_outstanding_writeback_pages_atomic = ATOMIC_INIT(0); +static inline void inc_zcache_outstanding_writeback_pages(void) +{ + zcache_outstanding_writeback_pages = + atomic_inc_return(&zcache_outstanding_writeback_pages_atomic); +} static void unswiz(struct tmem_oid oid, u32 index, unsigned *type, pgoff_t *offset); @@ -1120,8 +1158,7 @@ static int zcache_frontswap_writeback_zpage(int type, pgoff_t offset, */ (void)__swap_writepage(page, &wbc, zcache_end_swap_write); page_cache_release(page); - zcache_outstanding_writeback_pages = - atomic_inc_return(&zcache_outstanding_writeback_pages_atomic); + inc_zcache_outstanding_writeback_pages(); return 0; } -- cgit From 6f4336fbbe666490b1dccb39b3c0499a051da09b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:13 -0500 Subject: zcache: Provide accessory functions for counter decrease. This way we can have all wrapped with these functions and can disable/enable this with CONFIG_DEBUG_FS. Acked-by: Dan Magenheimer [v2: Rebase on top of staging/zcache: Fix/improve zcache writeback code, tie to a config option] [v3: Rebase on top of zcache: Fix compile warnings due to usage of debugfs_create_size_t] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 96 +++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index a3c5b7dae981..4272ab9c29ff 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -145,7 +145,11 @@ static inline void inc_zcache_obj_count(void) if (zcache_obj_count > zcache_obj_count_max) zcache_obj_count_max = zcache_obj_count; } - +static inline void dec_zcache_obj_count(void) +{ + zcache_obj_count = atomic_dec_return(&zcache_obj_atomic); + BUG_ON(zcache_obj_count < 0); +}; static atomic_t zcache_objnode_atomic = ATOMIC_INIT(0); static ssize_t zcache_objnode_count_max; static inline void inc_zcache_objnode_count(void) @@ -154,6 +158,11 @@ static inline void inc_zcache_objnode_count(void) if (zcache_objnode_count > zcache_objnode_count_max) zcache_objnode_count_max = zcache_objnode_count; }; +static inline void dec_zcache_objnode_count(void) +{ + zcache_objnode_count = atomic_dec_return(&zcache_objnode_atomic); + BUG_ON(zcache_objnode_count < 0); +}; static u64 zcache_eph_zbytes; static atomic_long_t zcache_eph_zbytes_atomic = ATOMIC_INIT(0); static u64 zcache_eph_zbytes_max; @@ -163,6 +172,10 @@ static inline void inc_zcache_eph_zbytes(unsigned clen) if (zcache_eph_zbytes > zcache_eph_zbytes_max) zcache_eph_zbytes_max = zcache_eph_zbytes; }; +static inline void dec_zcache_eph_zbytes(unsigned zsize) +{ + zcache_eph_zbytes = atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); +}; static u64 zcache_pers_zbytes; static atomic_long_t zcache_pers_zbytes_atomic = ATOMIC_INIT(0); static u64 zcache_pers_zbytes_max; @@ -173,6 +186,10 @@ static inline void inc_zcache_pers_zbytes(unsigned clen) if (zcache_pers_zbytes > zcache_pers_zbytes_max) zcache_pers_zbytes_max = zcache_pers_zbytes; } +static inline void dec_zcache_pers_zbytes(unsigned zsize) +{ + zcache_pers_zbytes = atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); +} static atomic_t zcache_eph_pageframes_atomic = ATOMIC_INIT(0); static ssize_t zcache_eph_pageframes_max; static ssize_t zcache_pers_pageframes; @@ -182,6 +199,10 @@ static inline void inc_zcache_eph_pageframes(void) if (zcache_eph_pageframes > zcache_eph_pageframes_max) zcache_eph_pageframes_max = zcache_eph_pageframes; }; +static inline void dec_zcache_eph_pageframes(void) +{ + zcache_eph_pageframes = atomic_dec_return(&zcache_eph_pageframes_atomic); +}; static atomic_t zcache_pers_pageframes_atomic = ATOMIC_INIT(0); static ssize_t zcache_pers_pageframes_max; static ssize_t zcache_pageframes_alloced; @@ -191,6 +212,10 @@ static inline void inc_zcache_pers_pageframes(void) if (zcache_pers_pageframes > zcache_pers_pageframes_max) zcache_pers_pageframes_max = zcache_pers_pageframes; } +static inline void dec_zcache_pers_pageframes(void) +{ + zcache_pers_pageframes = atomic_dec_return(&zcache_pers_pageframes_atomic); +} static atomic_t zcache_pageframes_alloced_atomic = ATOMIC_INIT(0); static ssize_t zcache_pageframes_freed; static inline void inc_zcache_pageframes_alloced(void) @@ -212,6 +237,10 @@ static inline void inc_zcache_eph_zpages(void) if (zcache_eph_zpages > zcache_eph_zpages_max) zcache_eph_zpages_max = zcache_eph_zpages; } +static inline void dec_zcache_eph_zpages(unsigned zpages) +{ + zcache_eph_zpages = atomic_sub_return(zpages, &zcache_eph_zpages_atomic); +} static atomic_t zcache_pers_zpages_atomic = ATOMIC_INIT(0); static ssize_t zcache_pers_zpages_max; static inline void inc_zcache_pers_zpages(void) @@ -220,6 +249,10 @@ static inline void inc_zcache_pers_zpages(void) if (zcache_pers_zpages > zcache_pers_zpages_max) zcache_pers_zpages_max = zcache_pers_zpages; } +static inline void dec_zcache_pers_zpages(unsigned zpages) +{ + zcache_pers_zpages = atomic_sub_return(zpages, &zcache_pers_zpages_atomic); +} /* but for the rest of these, counting races are ok */ static ssize_t zcache_flush_total; static ssize_t zcache_flush_found; @@ -484,9 +517,7 @@ static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) static void zcache_objnode_free(struct tmem_objnode *objnode, struct tmem_pool *pool) { - zcache_objnode_count = - atomic_dec_return(&zcache_objnode_atomic); - BUG_ON(zcache_objnode_count < 0); + dec_zcache_objnode_count(); kmem_cache_free(zcache_objnode_cache, objnode); } @@ -505,9 +536,7 @@ static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) { - zcache_obj_count = - atomic_dec_return(&zcache_obj_atomic); - BUG_ON(zcache_obj_count < 0); + dec_zcache_obj_count(); kmem_cache_free(zcache_obj_cache, obj); } @@ -827,20 +856,14 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *sizep, bool raw, &zsize, &zpages); if (eph) { if (page) - zcache_eph_pageframes = - atomic_dec_return(&zcache_eph_pageframes_atomic); - zcache_eph_zpages = - atomic_sub_return(zpages, &zcache_eph_zpages_atomic); - zcache_eph_zbytes = - atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); + dec_zcache_eph_pageframes(); + dec_zcache_eph_zpages(zpages); + dec_zcache_eph_zbytes(zsize); } else { if (page) - zcache_pers_pageframes = - atomic_dec_return(&zcache_pers_pageframes_atomic); - zcache_pers_zpages = - atomic_sub_return(zpages, &zcache_pers_zpages_atomic); - zcache_pers_zbytes = - atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); + dec_zcache_pers_pageframes(); + dec_zcache_pers_zpages(zpages); + dec_zcache_pers_zbytes(zsize); } if (!is_local_client(pool->client)) ramster_count_foreign_pages(eph, -1); @@ -870,23 +893,17 @@ static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, page = zbud_free_and_delist((struct zbudref *)pampd, true, &zsize, &zpages); if (page) - zcache_eph_pageframes = - atomic_dec_return(&zcache_eph_pageframes_atomic); - zcache_eph_zpages = - atomic_sub_return(zpages, &zcache_eph_zpages_atomic); - zcache_eph_zbytes = - atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); + dec_zcache_eph_pageframes(); + dec_zcache_eph_zpages(zpages); + dec_zcache_eph_zbytes(zsize); /* FIXME CONFIG_RAMSTER... check acct parameter? */ } else { page = zbud_free_and_delist((struct zbudref *)pampd, false, &zsize, &zpages); if (page) - zcache_pers_pageframes = - atomic_dec_return(&zcache_pers_pageframes_atomic); - zcache_pers_zpages = - atomic_sub_return(zpages, &zcache_pers_zpages_atomic); - zcache_pers_zbytes = - atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); + dec_zcache_pers_pageframes(); + dec_zcache_pers_zpages(zpages); + dec_zcache_pers_zbytes(zsize); } if (!is_local_client(pool->client)) ramster_count_foreign_pages(is_ephemeral(pool), -1); @@ -1008,13 +1025,10 @@ static struct page *zcache_evict_eph_pageframe(void) page = zbud_evict_pageframe_lru(&zsize, &zpages); if (page == NULL) goto out; - zcache_eph_zbytes = atomic_long_sub_return(zsize, - &zcache_eph_zbytes_atomic); - zcache_eph_zpages = atomic_sub_return(zpages, - &zcache_eph_zpages_atomic); + dec_zcache_eph_zbytes(zsize); + dec_zcache_eph_zpages(zpages); zcache_evicted_eph_zpages += zpages; - zcache_eph_pageframes = - atomic_dec_return(&zcache_eph_pageframes_atomic); + dec_zcache_eph_pageframes(); zcache_evicted_eph_pageframes++; out: return page; @@ -1029,6 +1043,11 @@ static inline void inc_zcache_outstanding_writeback_pages(void) zcache_outstanding_writeback_pages = atomic_inc_return(&zcache_outstanding_writeback_pages_atomic); } +static inline void dec_zcache_outstanding_writeback_pages(void) +{ + zcache_outstanding_writeback_pages = + atomic_dec_return(&zcache_outstanding_writeback_pages_atomic); +}; static void unswiz(struct tmem_oid oid, u32 index, unsigned *type, pgoff_t *offset); @@ -1042,8 +1061,7 @@ static void unswiz(struct tmem_oid oid, u32 index, static void zcache_end_swap_write(struct bio *bio, int err) { end_swap_bio_write(bio, err); - zcache_outstanding_writeback_pages = - atomic_dec_return(&zcache_outstanding_writeback_pages_atomic); + dec_zcache_outstanding_writeback_pages(); zcache_writtenback_pages++; } -- cgit From e0d11aed1966df0858564b58d2e355d36ff38e06 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:14 -0500 Subject: zcache: The last of the atomic reads has now an accessory function. And now we can move the code ([inc|dec]_zcache_[*]) to their own file with a header to make them nops or feed in debugfs. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 4272ab9c29ff..f455151377ab 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -253,6 +253,14 @@ static inline void dec_zcache_pers_zpages(unsigned zpages) { zcache_pers_zpages = atomic_sub_return(zpages, &zcache_pers_zpages_atomic); } + +static inline unsigned long curr_pageframes_count(void) +{ + return zcache_pageframes_alloced - + atomic_read(&zcache_pageframes_freed_atomic) - + atomic_read(&zcache_eph_pageframes_atomic) - + atomic_read(&zcache_pers_pageframes_atomic); +}; /* but for the rest of these, counting races are ok */ static ssize_t zcache_flush_total; static ssize_t zcache_flush_found; @@ -565,10 +573,7 @@ static void zcache_free_page(struct page *page) BUG(); __free_page(page); inc_zcache_pageframes_freed(); - curr_pageframes = zcache_pageframes_alloced - - atomic_read(&zcache_pageframes_freed_atomic) - - atomic_read(&zcache_eph_pageframes_atomic) - - atomic_read(&zcache_pers_pageframes_atomic); + curr_pageframes = curr_pageframes_count(); if (curr_pageframes > max_pageframes) max_pageframes = curr_pageframes; if (curr_pageframes < min_pageframes) -- cgit From a96138be77d1c7e44ff2d0b0366f3b0b240d3e39 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:15 -0500 Subject: zcache: Make the debug code use pr_debug as if you are debugging this driver you would be using 'debug' on the command line anyhow - and this would dump the debug data on the proper loglevel. While at it also remove the unconditional #define ZCACHE_DEBUG. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 85 +++++++++++++++++------------------- 1 file changed, 41 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index f455151377ab..366d457a6c7a 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -354,71 +354,68 @@ static int zcache_debugfs_init(void) #undef zdfs64 #endif -#define ZCACHE_DEBUG -#ifdef ZCACHE_DEBUG /* developers can call this in case of ooms, e.g. to find memory leaks */ void zcache_dump(void) { - pr_info("zcache: obj_count=%zd\n", zcache_obj_count); - pr_info("zcache: obj_count_max=%zd\n", zcache_obj_count_max); - pr_info("zcache: objnode_count=%zd\n", zcache_objnode_count); - pr_info("zcache: objnode_count_max=%zd\n", zcache_objnode_count_max); - pr_info("zcache: flush_total=%zd\n", zcache_flush_total); - pr_info("zcache: flush_found=%zd\n", zcache_flush_found); - pr_info("zcache: flobj_total=%zd\n", zcache_flobj_total); - pr_info("zcache: flobj_found=%zd\n", zcache_flobj_found); - pr_info("zcache: failed_eph_puts=%zd\n", zcache_failed_eph_puts); - pr_info("zcache: failed_pers_puts=%zd\n", zcache_failed_pers_puts); - pr_info("zcache: failed_get_free_pages=%zd\n", + pr_debug("zcache: obj_count=%zd\n", zcache_obj_count); + pr_debug("zcache: obj_count_max=%zd\n", zcache_obj_count_max); + pr_debug("zcache: objnode_count=%zd\n", zcache_objnode_count); + pr_debug("zcache: objnode_count_max=%zd\n", zcache_objnode_count_max); + pr_debug("zcache: flush_total=%zd\n", zcache_flush_total); + pr_debug("zcache: flush_found=%zd\n", zcache_flush_found); + pr_debug("zcache: flobj_total=%zd\n", zcache_flobj_total); + pr_debug("zcache: flobj_found=%zd\n", zcache_flobj_found); + pr_debug("zcache: failed_eph_puts=%zd\n", zcache_failed_eph_puts); + pr_debug("zcache: failed_pers_puts=%zd\n", zcache_failed_pers_puts); + pr_debug("zcache: failed_get_free_pages=%zd\n", zcache_failed_getfreepages); - pr_info("zcache: failed_alloc=%zd\n", zcache_failed_alloc); - pr_info("zcache: put_to_flush=%zd\n", zcache_put_to_flush); - pr_info("zcache: compress_poor=%zd\n", zcache_compress_poor); - pr_info("zcache: mean_compress_poor=%zd\n", + pr_debug("zcache: failed_alloc=%zd\n", zcache_failed_alloc); + pr_debug("zcache: put_to_flush=%zd\n", zcache_put_to_flush); + pr_debug("zcache: compress_poor=%zd\n", zcache_compress_poor); + pr_debug("zcache: mean_compress_poor=%zd\n", zcache_mean_compress_poor); - pr_info("zcache: eph_ate_tail=%zd\n", zcache_eph_ate_tail); - pr_info("zcache: eph_ate_tail_failed=%zd\n", + pr_debug("zcache: eph_ate_tail=%zd\n", zcache_eph_ate_tail); + pr_debug("zcache: eph_ate_tail_failed=%zd\n", zcache_eph_ate_tail_failed); - pr_info("zcache: pers_ate_eph=%zd\n", zcache_pers_ate_eph); - pr_info("zcache: pers_ate_eph_failed=%zd\n", + pr_debug("zcache: pers_ate_eph=%zd\n", zcache_pers_ate_eph); + pr_debug("zcache: pers_ate_eph_failed=%zd\n", zcache_pers_ate_eph_failed); - pr_info("zcache: evicted_eph_zpages=%zd\n", zcache_evicted_eph_zpages); - pr_info("zcache: evicted_eph_pageframes=%zd\n", + pr_debug("zcache: evicted_eph_zpages=%zd\n", zcache_evicted_eph_zpages); + pr_debug("zcache: evicted_eph_pageframes=%zd\n", zcache_evicted_eph_pageframes); - pr_info("zcache: eph_pageframes=%zd\n", zcache_eph_pageframes); - pr_info("zcache: eph_pageframes_max=%zd\n", zcache_eph_pageframes_max); - pr_info("zcache: pers_pageframes=%zd\n", zcache_pers_pageframes); - pr_info("zcache: pers_pageframes_max=%zd\n", + pr_debug("zcache: eph_pageframes=%zd\n", zcache_eph_pageframes); + pr_debug("zcache: eph_pageframes_max=%zd\n", zcache_eph_pageframes_max); + pr_debug("zcache: pers_pageframes=%zd\n", zcache_pers_pageframes); + pr_debug("zcache: pers_pageframes_max=%zd\n", zcache_pers_pageframes_max); - pr_info("zcache: eph_zpages=%zd\n", zcache_eph_zpages); - pr_info("zcache: eph_zpages_max=%zd\n", zcache_eph_zpages_max); - pr_info("zcache: pers_zpages=%zd\n", zcache_pers_zpages); - pr_info("zcache: pers_zpages_max=%zd\n", zcache_pers_zpages_max); - pr_info("zcache: last_active_file_pageframes=%zd\n", + pr_debug("zcache: eph_zpages=%zd\n", zcache_eph_zpages); + pr_debug("zcache: eph_zpages_max=%zd\n", zcache_eph_zpages_max); + pr_debug("zcache: pers_zpages=%zd\n", zcache_pers_zpages); + pr_debug("zcache: pers_zpages_max=%zd\n", zcache_pers_zpages_max); + pr_debug("zcache: last_active_file_pageframes=%zd\n", zcache_last_active_file_pageframes); - pr_info("zcache: last_inactive_file_pageframes=%zd\n", + pr_debug("zcache: last_inactive_file_pageframes=%zd\n", zcache_last_inactive_file_pageframes); - pr_info("zcache: last_active_anon_pageframes=%zd\n", + pr_debug("zcache: last_active_anon_pageframes=%zd\n", zcache_last_active_anon_pageframes); - pr_info("zcache: last_inactive_anon_pageframes=%zd\n", + pr_debug("zcache: last_inactive_anon_pageframes=%zd\n", zcache_last_inactive_anon_pageframes); - pr_info("zcache: eph_nonactive_puts_ignored=%zd\n", + pr_debug("zcache: eph_nonactive_puts_ignored=%zd\n", zcache_eph_nonactive_puts_ignored); - pr_info("zcache: pers_nonactive_puts_ignored=%zd\n", + pr_debug("zcache: pers_nonactive_puts_ignored=%zd\n", zcache_pers_nonactive_puts_ignored); - pr_info("zcache: eph_zbytes=%llu\n", + pr_debug("zcache: eph_zbytes=%llu\n", zcache_eph_zbytes); - pr_info("zcache: eph_zbytes_max=%llu\n", + pr_debug("zcache: eph_zbytes_max=%llu\n", zcache_eph_zbytes_max); - pr_info("zcache: pers_zbytes=%llu\n", + pr_debug("zcache: pers_zbytes=%llu\n", zcache_pers_zbytes); - pr_info("zcache: pers_zbytes_max=%llu\n", + pr_debug("zcache: pers_zbytes_max=%llu\n", zcache_pers_zbytes_max); - pr_info("zcache: outstanding_writeback_pages=%zd\n", + pr_debug("zcache: outstanding_writeback_pages=%zd\n", zcache_outstanding_writeback_pages); - pr_info("zcache: writtenback_pages=%zd\n", zcache_writtenback_pages); + pr_debug("zcache: writtenback_pages=%zd\n", zcache_writtenback_pages); } -#endif /* * zcache core code starts here -- cgit From 95bdaee2140ef60d31fff1de71f43448ae56cdbe Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:16 -0500 Subject: zcache: Move debugfs code out of zcache-main.c file. Note that at this point there is no CONFIG_ZCACHE_DEBUG option in the Kconfig. So in effect all of the counters are nop until that option gets re-introduced in: zcache/debug: Coalesce all debug under CONFIG_ZCACHE_DEBUG Acked-by: Dan Magenheimer [v1: Fixed conflicts due to rebase] Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Makefile | 1 + drivers/staging/zcache/debug.c | 132 ++++++++++++++++++ drivers/staging/zcache/debug.h | 187 +++++++++++++++++++++++++ drivers/staging/zcache/zcache-main.c | 264 ++--------------------------------- 4 files changed, 328 insertions(+), 256 deletions(-) create mode 100644 drivers/staging/zcache/debug.c create mode 100644 drivers/staging/zcache/debug.h (limited to 'drivers') diff --git a/drivers/staging/zcache/Makefile b/drivers/staging/zcache/Makefile index 471104957dad..24fd6aa23817 100644 --- a/drivers/staging/zcache/Makefile +++ b/drivers/staging/zcache/Makefile @@ -1,4 +1,5 @@ zcache-y := zcache-main.o tmem.o zbud.o +zcache-$(CONFIG_ZCACHE_DEBUG) += debug.o zcache-$(CONFIG_RAMSTER) += ramster/ramster.o ramster/r2net.o zcache-$(CONFIG_RAMSTER) += ramster/nodemanager.o ramster/tcp.o zcache-$(CONFIG_RAMSTER) += ramster/heartbeat.o ramster/masklog.o diff --git a/drivers/staging/zcache/debug.c b/drivers/staging/zcache/debug.c new file mode 100644 index 000000000000..622d5f371ff3 --- /dev/null +++ b/drivers/staging/zcache/debug.c @@ -0,0 +1,132 @@ +#include +#include "debug.h" + +#ifdef CONFIG_DEBUG_FS +#include +#define zdfs debugfs_create_size_t +#define zdfs64 debugfs_create_u64 +int zcache_debugfs_init(void) +{ + struct dentry *root = debugfs_create_dir("zcache", NULL); + if (root == NULL) + return -ENXIO; + + zdfs("obj_count", S_IRUGO, root, &zcache_obj_count); + zdfs("obj_count_max", S_IRUGO, root, &zcache_obj_count_max); + zdfs("objnode_count", S_IRUGO, root, &zcache_objnode_count); + zdfs("objnode_count_max", S_IRUGO, root, &zcache_objnode_count_max); + zdfs("flush_total", S_IRUGO, root, &zcache_flush_total); + zdfs("flush_found", S_IRUGO, root, &zcache_flush_found); + zdfs("flobj_total", S_IRUGO, root, &zcache_flobj_total); + zdfs("flobj_found", S_IRUGO, root, &zcache_flobj_found); + zdfs("failed_eph_puts", S_IRUGO, root, &zcache_failed_eph_puts); + zdfs("failed_pers_puts", S_IRUGO, root, &zcache_failed_pers_puts); + zdfs("failed_get_free_pages", S_IRUGO, root, + &zcache_failed_getfreepages); + zdfs("failed_alloc", S_IRUGO, root, &zcache_failed_alloc); + zdfs("put_to_flush", S_IRUGO, root, &zcache_put_to_flush); + zdfs("compress_poor", S_IRUGO, root, &zcache_compress_poor); + zdfs("mean_compress_poor", S_IRUGO, root, &zcache_mean_compress_poor); + zdfs("eph_ate_tail", S_IRUGO, root, &zcache_eph_ate_tail); + zdfs("eph_ate_tail_failed", S_IRUGO, root, &zcache_eph_ate_tail_failed); + zdfs("pers_ate_eph", S_IRUGO, root, &zcache_pers_ate_eph); + zdfs("pers_ate_eph_failed", S_IRUGO, root, &zcache_pers_ate_eph_failed); + zdfs("evicted_eph_zpages", S_IRUGO, root, &zcache_evicted_eph_zpages); + zdfs("evicted_eph_pageframes", S_IRUGO, root, + &zcache_evicted_eph_pageframes); + zdfs("eph_pageframes", S_IRUGO, root, &zcache_eph_pageframes); + zdfs("eph_pageframes_max", S_IRUGO, root, &zcache_eph_pageframes_max); + zdfs("pers_pageframes", S_IRUGO, root, &zcache_pers_pageframes); + zdfs("pers_pageframes_max", S_IRUGO, root, &zcache_pers_pageframes_max); + zdfs("eph_zpages", S_IRUGO, root, &zcache_eph_zpages); + zdfs("eph_zpages_max", S_IRUGO, root, &zcache_eph_zpages_max); + zdfs("pers_zpages", S_IRUGO, root, &zcache_pers_zpages); + zdfs("pers_zpages_max", S_IRUGO, root, &zcache_pers_zpages_max); + zdfs("last_active_file_pageframes", S_IRUGO, root, + &zcache_last_active_file_pageframes); + zdfs("last_inactive_file_pageframes", S_IRUGO, root, + &zcache_last_inactive_file_pageframes); + zdfs("last_active_anon_pageframes", S_IRUGO, root, + &zcache_last_active_anon_pageframes); + zdfs("last_inactive_anon_pageframes", S_IRUGO, root, + &zcache_last_inactive_anon_pageframes); + zdfs("eph_nonactive_puts_ignored", S_IRUGO, root, + &zcache_eph_nonactive_puts_ignored); + zdfs("pers_nonactive_puts_ignored", S_IRUGO, root, + &zcache_pers_nonactive_puts_ignored); + zdfs64("eph_zbytes", S_IRUGO, root, &zcache_eph_zbytes); + zdfs64("eph_zbytes_max", S_IRUGO, root, &zcache_eph_zbytes_max); + zdfs64("pers_zbytes", S_IRUGO, root, &zcache_pers_zbytes); + zdfs64("pers_zbytes_max", S_IRUGO, root, &zcache_pers_zbytes_max); + zdfs("outstanding_writeback_pages", S_IRUGO, root, + &zcache_outstanding_writeback_pages); + zdfs("writtenback_pages", S_IRUGO, root, &zcache_writtenback_pages); + + return 0; +} +#undef zdebugfs +#undef zdfs64 + +/* developers can call this in case of ooms, e.g. to find memory leaks */ +void zcache_dump(void) +{ + pr_debug("zcache: obj_count=%zd\n", zcache_obj_count); + pr_debug("zcache: obj_count_max=%zd\n", zcache_obj_count_max); + pr_debug("zcache: objnode_count=%zd\n", zcache_objnode_count); + pr_debug("zcache: objnode_count_max=%zd\n", zcache_objnode_count_max); + pr_debug("zcache: flush_total=%zd\n", zcache_flush_total); + pr_debug("zcache: flush_found=%zd\n", zcache_flush_found); + pr_debug("zcache: flobj_total=%zd\n", zcache_flobj_total); + pr_debug("zcache: flobj_found=%zd\n", zcache_flobj_found); + pr_debug("zcache: failed_eph_puts=%zd\n", zcache_failed_eph_puts); + pr_debug("zcache: failed_pers_puts=%zd\n", zcache_failed_pers_puts); + pr_debug("zcache: failed_get_free_pages=%zd\n", + zcache_failed_getfreepages); + pr_debug("zcache: failed_alloc=%zd\n", zcache_failed_alloc); + pr_debug("zcache: put_to_flush=%zd\n", zcache_put_to_flush); + pr_debug("zcache: compress_poor=%zd\n", zcache_compress_poor); + pr_debug("zcache: mean_compress_poor=%zd\n", + zcache_mean_compress_poor); + pr_debug("zcache: eph_ate_tail=%zd\n", zcache_eph_ate_tail); + pr_debug("zcache: eph_ate_tail_failed=%zd\n", + zcache_eph_ate_tail_failed); + pr_debug("zcache: pers_ate_eph=%zd\n", zcache_pers_ate_eph); + pr_debug("zcache: pers_ate_eph_failed=%zd\n", + zcache_pers_ate_eph_failed); + pr_debug("zcache: evicted_eph_zpages=%zd\n", zcache_evicted_eph_zpages); + pr_debug("zcache: evicted_eph_pageframes=%zd\n", + zcache_evicted_eph_pageframes); + pr_debug("zcache: eph_pageframes=%zd\n", zcache_eph_pageframes); + pr_debug("zcache: eph_pageframes_max=%zd\n", zcache_eph_pageframes_max); + pr_debug("zcache: pers_pageframes=%zd\n", zcache_pers_pageframes); + pr_debug("zcache: pers_pageframes_max=%zd\n", + zcache_pers_pageframes_max); + pr_debug("zcache: eph_zpages=%zd\n", zcache_eph_zpages); + pr_debug("zcache: eph_zpages_max=%zd\n", zcache_eph_zpages_max); + pr_debug("zcache: pers_zpages=%zd\n", zcache_pers_zpages); + pr_debug("zcache: pers_zpages_max=%zd\n", zcache_pers_zpages_max); + pr_debug("zcache: last_active_file_pageframes=%zd\n", + zcache_last_active_file_pageframes); + pr_debug("zcache: last_inactive_file_pageframes=%zd\n", + zcache_last_inactive_file_pageframes); + pr_debug("zcache: last_active_anon_pageframes=%zd\n", + zcache_last_active_anon_pageframes); + pr_debug("zcache: last_inactive_anon_pageframes=%zd\n", + zcache_last_inactive_anon_pageframes); + pr_debug("zcache: eph_nonactive_puts_ignored=%zd\n", + zcache_eph_nonactive_puts_ignored); + pr_debug("zcache: pers_nonactive_puts_ignored=%zd\n", + zcache_pers_nonactive_puts_ignored); + pr_debug("zcache: eph_zbytes=%llu\n", + zcache_eph_zbytes); + pr_debug("zcache: eph_zbytes_max=%llu\n", + zcache_eph_zbytes_max); + pr_debug("zcache: pers_zbytes=%llu\n", + zcache_pers_zbytes); + pr_debug("zcache: pers_zbytes_max=%llu\n", + zcache_pers_zbytes_max); + pr_debug("zcache: outstanding_writeback_pages=%zd\n", + zcache_outstanding_writeback_pages); + pr_debug("zcache: writtenback_pages=%zd\n", zcache_writtenback_pages); +} +#endif diff --git a/drivers/staging/zcache/debug.h b/drivers/staging/zcache/debug.h new file mode 100644 index 000000000000..98dc491021d0 --- /dev/null +++ b/drivers/staging/zcache/debug.h @@ -0,0 +1,187 @@ +#ifdef CONFIG_ZCACHE_DEBUG + +/* we try to keep these statistics SMP-consistent */ +static ssize_t zcache_obj_count; +static atomic_t zcache_obj_atomic = ATOMIC_INIT(0); +static ssize_t zcache_obj_count_max; +static inline void inc_zcache_obj_count(void) +{ + zcache_obj_count = atomic_inc_return(&zcache_obj_atomic); + if (zcache_obj_count > zcache_obj_count_max) + zcache_obj_count_max = zcache_obj_count; +} +static inline void dec_zcache_obj_count(void) +{ + zcache_obj_count = atomic_dec_return(&zcache_obj_atomic); + BUG_ON(zcache_obj_count < 0); +}; +static ssize_t zcache_objnode_count; +static atomic_t zcache_objnode_atomic = ATOMIC_INIT(0); +static ssize_t zcache_objnode_count_max; +static inline void inc_zcache_objnode_count(void) +{ + zcache_objnode_count = atomic_inc_return(&zcache_objnode_atomic); + if (zcache_objnode_count > zcache_objnode_count_max) + zcache_objnode_count_max = zcache_objnode_count; +}; +static inline void dec_zcache_objnode_count(void) +{ + zcache_objnode_count = atomic_dec_return(&zcache_objnode_atomic); + BUG_ON(zcache_objnode_count < 0); +}; +static u64 zcache_eph_zbytes; +static atomic_long_t zcache_eph_zbytes_atomic = ATOMIC_INIT(0); +static u64 zcache_eph_zbytes_max; +static inline void inc_zcache_eph_zbytes(unsigned clen) +{ + zcache_eph_zbytes = atomic_long_add_return(clen, &zcache_eph_zbytes_atomic); + if (zcache_eph_zbytes > zcache_eph_zbytes_max) + zcache_eph_zbytes_max = zcache_eph_zbytes; +}; +static inline void dec_zcache_eph_zbytes(unsigned zsize) +{ + zcache_eph_zbytes = atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); +}; +extern u64 zcache_pers_zbytes; +static atomic_long_t zcache_pers_zbytes_atomic = ATOMIC_INIT(0); +static u64 zcache_pers_zbytes_max; +static inline void inc_zcache_pers_zbytes(unsigned clen) +{ + zcache_pers_zbytes = atomic_long_add_return(clen, &zcache_pers_zbytes_atomic); + if (zcache_pers_zbytes > zcache_pers_zbytes_max) + zcache_pers_zbytes_max = zcache_pers_zbytes; +} +static inline void dec_zcache_pers_zbytes(unsigned zsize) +{ + zcache_pers_zbytes = atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); +} +extern ssize_t zcache_eph_pageframes; +static atomic_t zcache_eph_pageframes_atomic = ATOMIC_INIT(0); +static ssize_t zcache_eph_pageframes_max; +static inline void inc_zcache_eph_pageframes(void) +{ + zcache_eph_pageframes = atomic_inc_return(&zcache_eph_pageframes_atomic); + if (zcache_eph_pageframes > zcache_eph_pageframes_max) + zcache_eph_pageframes_max = zcache_eph_pageframes; +}; +static inline void dec_zcache_eph_pageframes(void) +{ + zcache_eph_pageframes = atomic_dec_return(&zcache_eph_pageframes_atomic); +}; +extern ssize_t zcache_pers_pageframes; +static atomic_t zcache_pers_pageframes_atomic = ATOMIC_INIT(0); +static ssize_t zcache_pers_pageframes_max; +static inline void inc_zcache_pers_pageframes(void) +{ + zcache_pers_pageframes = atomic_inc_return(&zcache_pers_pageframes_atomic); + if (zcache_pers_pageframes > zcache_pers_pageframes_max) + zcache_pers_pageframes_max = zcache_pers_pageframes; +} +static inline void dec_zcache_pers_pageframes(void) +{ + zcache_pers_pageframes = atomic_dec_return(&zcache_pers_pageframes_atomic); +} +static ssize_t zcache_pageframes_alloced; +static atomic_t zcache_pageframes_alloced_atomic = ATOMIC_INIT(0); +static inline void inc_zcache_pageframes_alloced(void) +{ + zcache_pageframes_alloced = atomic_inc_return(&zcache_pageframes_alloced_atomic); +}; +static ssize_t zcache_pageframes_freed; +static atomic_t zcache_pageframes_freed_atomic = ATOMIC_INIT(0); +static inline void inc_zcache_pageframes_freed(void) +{ + zcache_pageframes_freed = atomic_inc_return(&zcache_pageframes_freed_atomic); +} +static ssize_t zcache_eph_zpages; +static atomic_t zcache_eph_zpages_atomic = ATOMIC_INIT(0); +static ssize_t zcache_eph_zpages_max; +static inline void inc_zcache_eph_zpages(void) +{ + zcache_eph_zpages = atomic_inc_return(&zcache_eph_zpages_atomic); + if (zcache_eph_zpages > zcache_eph_zpages_max) + zcache_eph_zpages_max = zcache_eph_zpages; +} +static inline void dec_zcache_eph_zpages(unsigned zpages) +{ + zcache_eph_zpages = atomic_sub_return(zpages, &zcache_eph_zpages_atomic); +} +extern ssize_t zcache_pers_zpages; +static atomic_t zcache_pers_zpages_atomic = ATOMIC_INIT(0); +static ssize_t zcache_pers_zpages_max; +static inline void inc_zcache_pers_zpages(void) +{ + zcache_pers_zpages = atomic_inc_return(&zcache_pers_zpages_atomic); + if (zcache_pers_zpages > zcache_pers_zpages_max) + zcache_pers_zpages_max = zcache_pers_zpages; +} +static inline void dec_zcache_pers_zpages(unsigned zpages) +{ + zcache_pers_zpages = atomic_sub_return(zpages, &zcache_pers_zpages_atomic); +} + +static inline unsigned long curr_pageframes_count(void) +{ + return zcache_pageframes_alloced - + atomic_read(&zcache_pageframes_freed_atomic) - + atomic_read(&zcache_eph_pageframes_atomic) - + atomic_read(&zcache_pers_pageframes_atomic); +}; +/* but for the rest of these, counting races are ok */ +extern ssize_t zcache_flush_total; +extern ssize_t zcache_flush_found; +extern ssize_t zcache_flobj_total; +extern ssize_t zcache_flobj_found; +extern ssize_t zcache_failed_eph_puts; +extern ssize_t zcache_failed_pers_puts; +extern ssize_t zcache_failed_getfreepages; +extern ssize_t zcache_failed_alloc; +extern ssize_t zcache_put_to_flush; +extern ssize_t zcache_compress_poor; +extern ssize_t zcache_mean_compress_poor; +extern ssize_t zcache_eph_ate_tail; +extern ssize_t zcache_eph_ate_tail_failed; +extern ssize_t zcache_pers_ate_eph; +extern ssize_t zcache_pers_ate_eph_failed; +extern ssize_t zcache_evicted_eph_zpages; +extern ssize_t zcache_evicted_eph_pageframes; +extern ssize_t zcache_last_active_file_pageframes; +extern ssize_t zcache_last_inactive_file_pageframes; +extern ssize_t zcache_last_active_anon_pageframes; +extern ssize_t zcache_last_inactive_anon_pageframes; +extern ssize_t zcache_eph_nonactive_puts_ignored; +extern ssize_t zcache_pers_nonactive_puts_ignored; +#ifdef CONFIG_ZCACHE_WRITEBACK +extern ssize_t zcache_writtenback_pages; +extern ssize_t zcache_outstanding_writeback_pages; +#endif + +int zcache_debugfs_init(void); +#else +static inline void inc_zcache_obj_count(void) { }; +static inline void dec_zcache_obj_count(void) { }; +static inline void inc_zcache_objnode_count(void) { }; +static inline void dec_zcache_objnode_count(void) { }; +static inline void inc_zcache_eph_zbytes(unsigned clen) { }; +static inline void dec_zcache_eph_zbytes(unsigned zsize) { }; +static inline void inc_zcache_pers_zbytes(unsigned clen) { }; +static inline void dec_zcache_pers_zbytes(unsigned zsize) { }; +static inline void inc_zcache_eph_pageframes(void) { }; +static inline void dec_zcache_eph_pageframes(void) { }; +static inline void inc_zcache_pers_pageframes(void) { }; +static inline void dec_zcache_pers_pageframes(void) { }; +static inline void inc_zcache_pageframes_alloced(void) { }; +static inline void inc_zcache_pageframes_freed(void) { }; +static inline void inc_zcache_eph_zpages(void) { }; +static inline void dec_zcache_eph_zpages(unsigned zpages) { }; +static inline void inc_zcache_pers_zpages(void) { }; +static inline void dec_zcache_pers_zpages(unsigned zpages) { }; +static inline unsigned long curr_pageframes_count(void) +{ + return 0; +}; +static inline int zcache_debugfs_init(void) +{ + return 0; +}; +#endif diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 366d457a6c7a..9d6cf968513e 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -33,6 +33,7 @@ #include "zcache.h" #include "zbud.h" #include "ramster.h" +#include "debug.h" #ifdef CONFIG_RAMSTER static bool ramster_enabled __read_mostly; #else @@ -134,134 +135,13 @@ static struct kmem_cache *zcache_obj_cache; static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; -/* we try to keep these statistics SMP-consistent */ -static ssize_t zcache_obj_count; -static atomic_t zcache_obj_atomic = ATOMIC_INIT(0); -static ssize_t zcache_obj_count_max; -static ssize_t zcache_objnode_count; -static inline void inc_zcache_obj_count(void) -{ - zcache_obj_count = atomic_inc_return(&zcache_obj_atomic); - if (zcache_obj_count > zcache_obj_count_max) - zcache_obj_count_max = zcache_obj_count; -} -static inline void dec_zcache_obj_count(void) -{ - zcache_obj_count = atomic_dec_return(&zcache_obj_atomic); - BUG_ON(zcache_obj_count < 0); -}; -static atomic_t zcache_objnode_atomic = ATOMIC_INIT(0); -static ssize_t zcache_objnode_count_max; -static inline void inc_zcache_objnode_count(void) -{ - zcache_objnode_count = atomic_inc_return(&zcache_objnode_atomic); - if (zcache_objnode_count > zcache_objnode_count_max) - zcache_objnode_count_max = zcache_objnode_count; -}; -static inline void dec_zcache_objnode_count(void) -{ - zcache_objnode_count = atomic_dec_return(&zcache_objnode_atomic); - BUG_ON(zcache_objnode_count < 0); -}; -static u64 zcache_eph_zbytes; -static atomic_long_t zcache_eph_zbytes_atomic = ATOMIC_INIT(0); -static u64 zcache_eph_zbytes_max; -static inline void inc_zcache_eph_zbytes(unsigned clen) -{ - zcache_eph_zbytes = atomic_long_add_return(clen, &zcache_eph_zbytes_atomic); - if (zcache_eph_zbytes > zcache_eph_zbytes_max) - zcache_eph_zbytes_max = zcache_eph_zbytes; -}; -static inline void dec_zcache_eph_zbytes(unsigned zsize) -{ - zcache_eph_zbytes = atomic_long_sub_return(zsize, &zcache_eph_zbytes_atomic); -}; -static u64 zcache_pers_zbytes; -static atomic_long_t zcache_pers_zbytes_atomic = ATOMIC_INIT(0); -static u64 zcache_pers_zbytes_max; -static ssize_t zcache_eph_pageframes; -static inline void inc_zcache_pers_zbytes(unsigned clen) -{ - zcache_pers_zbytes = atomic_long_add_return(clen, &zcache_pers_zbytes_atomic); - if (zcache_pers_zbytes > zcache_pers_zbytes_max) - zcache_pers_zbytes_max = zcache_pers_zbytes; -} -static inline void dec_zcache_pers_zbytes(unsigned zsize) -{ - zcache_pers_zbytes = atomic_long_sub_return(zsize, &zcache_pers_zbytes_atomic); -} -static atomic_t zcache_eph_pageframes_atomic = ATOMIC_INIT(0); -static ssize_t zcache_eph_pageframes_max; -static ssize_t zcache_pers_pageframes; -static inline void inc_zcache_eph_pageframes(void) -{ - zcache_eph_pageframes = atomic_inc_return(&zcache_eph_pageframes_atomic); - if (zcache_eph_pageframes > zcache_eph_pageframes_max) - zcache_eph_pageframes_max = zcache_eph_pageframes; -}; -static inline void dec_zcache_eph_pageframes(void) -{ - zcache_eph_pageframes = atomic_dec_return(&zcache_eph_pageframes_atomic); -}; -static atomic_t zcache_pers_pageframes_atomic = ATOMIC_INIT(0); -static ssize_t zcache_pers_pageframes_max; -static ssize_t zcache_pageframes_alloced; -static inline void inc_zcache_pers_pageframes(void) -{ - zcache_pers_pageframes = atomic_inc_return(&zcache_pers_pageframes_atomic); - if (zcache_pers_pageframes > zcache_pers_pageframes_max) - zcache_pers_pageframes_max = zcache_pers_pageframes; -} -static inline void dec_zcache_pers_pageframes(void) -{ - zcache_pers_pageframes = atomic_dec_return(&zcache_pers_pageframes_atomic); -} -static atomic_t zcache_pageframes_alloced_atomic = ATOMIC_INIT(0); -static ssize_t zcache_pageframes_freed; -static inline void inc_zcache_pageframes_alloced(void) -{ - zcache_pageframes_alloced = atomic_inc_return(&zcache_pageframes_alloced_atomic); -}; -static atomic_t zcache_pageframes_freed_atomic = ATOMIC_INIT(0); -static ssize_t zcache_eph_zpages; -static inline void inc_zcache_pageframes_freed(void) -{ - zcache_pageframes_freed = atomic_inc_return(&zcache_pageframes_freed_atomic); -} -static atomic_t zcache_eph_zpages_atomic = ATOMIC_INIT(0); -static ssize_t zcache_eph_zpages_max; -static ssize_t zcache_pers_zpages; -static inline void inc_zcache_eph_zpages(void) -{ - zcache_eph_zpages = atomic_inc_return(&zcache_eph_zpages_atomic); - if (zcache_eph_zpages > zcache_eph_zpages_max) - zcache_eph_zpages_max = zcache_eph_zpages; -} -static inline void dec_zcache_eph_zpages(unsigned zpages) -{ - zcache_eph_zpages = atomic_sub_return(zpages, &zcache_eph_zpages_atomic); -} -static atomic_t zcache_pers_zpages_atomic = ATOMIC_INIT(0); -static ssize_t zcache_pers_zpages_max; -static inline void inc_zcache_pers_zpages(void) -{ - zcache_pers_zpages = atomic_inc_return(&zcache_pers_zpages_atomic); - if (zcache_pers_zpages > zcache_pers_zpages_max) - zcache_pers_zpages_max = zcache_pers_zpages; -} -static inline void dec_zcache_pers_zpages(unsigned zpages) -{ - zcache_pers_zpages = atomic_sub_return(zpages, &zcache_pers_zpages_atomic); -} +/* Used by debug.c */ +ssize_t zcache_pers_zpages; +u64 zcache_pers_zbytes; +ssize_t zcache_eph_pageframes; +ssize_t zcache_pers_pageframes; -static inline unsigned long curr_pageframes_count(void) -{ - return zcache_pageframes_alloced - - atomic_read(&zcache_pageframes_freed_atomic) - - atomic_read(&zcache_eph_pageframes_atomic) - - atomic_read(&zcache_pers_pageframes_atomic); -}; -/* but for the rest of these, counting races are ok */ +/* Used by this code. */ static ssize_t zcache_flush_total; static ssize_t zcache_flush_found; static ssize_t zcache_flobj_total; @@ -285,138 +165,10 @@ static ssize_t zcache_last_active_anon_pageframes; static ssize_t zcache_last_inactive_anon_pageframes; static ssize_t zcache_eph_nonactive_puts_ignored; static ssize_t zcache_pers_nonactive_puts_ignored; +#ifdef CONFIG_ZCACHE_WRITEBACK static ssize_t zcache_writtenback_pages; static ssize_t zcache_outstanding_writeback_pages; - -#ifdef CONFIG_DEBUG_FS -#include -#define zdfs debugfs_create_size_t -#define zdfs64 debugfs_create_u64 -static int zcache_debugfs_init(void) -{ - struct dentry *root = debugfs_create_dir("zcache", NULL); - if (root == NULL) - return -ENXIO; - - zdfs("obj_count", S_IRUGO, root, &zcache_obj_count); - zdfs("obj_count_max", S_IRUGO, root, &zcache_obj_count_max); - zdfs("objnode_count", S_IRUGO, root, &zcache_objnode_count); - zdfs("objnode_count_max", S_IRUGO, root, &zcache_objnode_count_max); - zdfs("flush_total", S_IRUGO, root, &zcache_flush_total); - zdfs("flush_found", S_IRUGO, root, &zcache_flush_found); - zdfs("flobj_total", S_IRUGO, root, &zcache_flobj_total); - zdfs("flobj_found", S_IRUGO, root, &zcache_flobj_found); - zdfs("failed_eph_puts", S_IRUGO, root, &zcache_failed_eph_puts); - zdfs("failed_pers_puts", S_IRUGO, root, &zcache_failed_pers_puts); - zdfs("failed_get_free_pages", S_IRUGO, root, - &zcache_failed_getfreepages); - zdfs("failed_alloc", S_IRUGO, root, &zcache_failed_alloc); - zdfs("put_to_flush", S_IRUGO, root, &zcache_put_to_flush); - zdfs("compress_poor", S_IRUGO, root, &zcache_compress_poor); - zdfs("mean_compress_poor", S_IRUGO, root, &zcache_mean_compress_poor); - zdfs("eph_ate_tail", S_IRUGO, root, &zcache_eph_ate_tail); - zdfs("eph_ate_tail_failed", S_IRUGO, root, &zcache_eph_ate_tail_failed); - zdfs("pers_ate_eph", S_IRUGO, root, &zcache_pers_ate_eph); - zdfs("pers_ate_eph_failed", S_IRUGO, root, &zcache_pers_ate_eph_failed); - zdfs("evicted_eph_zpages", S_IRUGO, root, &zcache_evicted_eph_zpages); - zdfs("evicted_eph_pageframes", S_IRUGO, root, - &zcache_evicted_eph_pageframes); - zdfs("eph_pageframes", S_IRUGO, root, &zcache_eph_pageframes); - zdfs("eph_pageframes_max", S_IRUGO, root, &zcache_eph_pageframes_max); - zdfs("pers_pageframes", S_IRUGO, root, &zcache_pers_pageframes); - zdfs("pers_pageframes_max", S_IRUGO, root, &zcache_pers_pageframes_max); - zdfs("eph_zpages", S_IRUGO, root, &zcache_eph_zpages); - zdfs("eph_zpages_max", S_IRUGO, root, &zcache_eph_zpages_max); - zdfs("pers_zpages", S_IRUGO, root, &zcache_pers_zpages); - zdfs("pers_zpages_max", S_IRUGO, root, &zcache_pers_zpages_max); - zdfs("last_active_file_pageframes", S_IRUGO, root, - &zcache_last_active_file_pageframes); - zdfs("last_inactive_file_pageframes", S_IRUGO, root, - &zcache_last_inactive_file_pageframes); - zdfs("last_active_anon_pageframes", S_IRUGO, root, - &zcache_last_active_anon_pageframes); - zdfs("last_inactive_anon_pageframes", S_IRUGO, root, - &zcache_last_inactive_anon_pageframes); - zdfs("eph_nonactive_puts_ignored", S_IRUGO, root, - &zcache_eph_nonactive_puts_ignored); - zdfs("pers_nonactive_puts_ignored", S_IRUGO, root, - &zcache_pers_nonactive_puts_ignored); - zdfs64("eph_zbytes", S_IRUGO, root, &zcache_eph_zbytes); - zdfs64("eph_zbytes_max", S_IRUGO, root, &zcache_eph_zbytes_max); - zdfs64("pers_zbytes", S_IRUGO, root, &zcache_pers_zbytes); - zdfs64("pers_zbytes_max", S_IRUGO, root, &zcache_pers_zbytes_max); - zdfs("outstanding_writeback_pages", S_IRUGO, root, - &zcache_outstanding_writeback_pages); - zdfs("writtenback_pages", S_IRUGO, root, &zcache_writtenback_pages); - return 0; -} -#undef zdebugfs -#undef zdfs64 #endif - -/* developers can call this in case of ooms, e.g. to find memory leaks */ -void zcache_dump(void) -{ - pr_debug("zcache: obj_count=%zd\n", zcache_obj_count); - pr_debug("zcache: obj_count_max=%zd\n", zcache_obj_count_max); - pr_debug("zcache: objnode_count=%zd\n", zcache_objnode_count); - pr_debug("zcache: objnode_count_max=%zd\n", zcache_objnode_count_max); - pr_debug("zcache: flush_total=%zd\n", zcache_flush_total); - pr_debug("zcache: flush_found=%zd\n", zcache_flush_found); - pr_debug("zcache: flobj_total=%zd\n", zcache_flobj_total); - pr_debug("zcache: flobj_found=%zd\n", zcache_flobj_found); - pr_debug("zcache: failed_eph_puts=%zd\n", zcache_failed_eph_puts); - pr_debug("zcache: failed_pers_puts=%zd\n", zcache_failed_pers_puts); - pr_debug("zcache: failed_get_free_pages=%zd\n", - zcache_failed_getfreepages); - pr_debug("zcache: failed_alloc=%zd\n", zcache_failed_alloc); - pr_debug("zcache: put_to_flush=%zd\n", zcache_put_to_flush); - pr_debug("zcache: compress_poor=%zd\n", zcache_compress_poor); - pr_debug("zcache: mean_compress_poor=%zd\n", - zcache_mean_compress_poor); - pr_debug("zcache: eph_ate_tail=%zd\n", zcache_eph_ate_tail); - pr_debug("zcache: eph_ate_tail_failed=%zd\n", - zcache_eph_ate_tail_failed); - pr_debug("zcache: pers_ate_eph=%zd\n", zcache_pers_ate_eph); - pr_debug("zcache: pers_ate_eph_failed=%zd\n", - zcache_pers_ate_eph_failed); - pr_debug("zcache: evicted_eph_zpages=%zd\n", zcache_evicted_eph_zpages); - pr_debug("zcache: evicted_eph_pageframes=%zd\n", - zcache_evicted_eph_pageframes); - pr_debug("zcache: eph_pageframes=%zd\n", zcache_eph_pageframes); - pr_debug("zcache: eph_pageframes_max=%zd\n", zcache_eph_pageframes_max); - pr_debug("zcache: pers_pageframes=%zd\n", zcache_pers_pageframes); - pr_debug("zcache: pers_pageframes_max=%zd\n", - zcache_pers_pageframes_max); - pr_debug("zcache: eph_zpages=%zd\n", zcache_eph_zpages); - pr_debug("zcache: eph_zpages_max=%zd\n", zcache_eph_zpages_max); - pr_debug("zcache: pers_zpages=%zd\n", zcache_pers_zpages); - pr_debug("zcache: pers_zpages_max=%zd\n", zcache_pers_zpages_max); - pr_debug("zcache: last_active_file_pageframes=%zd\n", - zcache_last_active_file_pageframes); - pr_debug("zcache: last_inactive_file_pageframes=%zd\n", - zcache_last_inactive_file_pageframes); - pr_debug("zcache: last_active_anon_pageframes=%zd\n", - zcache_last_active_anon_pageframes); - pr_debug("zcache: last_inactive_anon_pageframes=%zd\n", - zcache_last_inactive_anon_pageframes); - pr_debug("zcache: eph_nonactive_puts_ignored=%zd\n", - zcache_eph_nonactive_puts_ignored); - pr_debug("zcache: pers_nonactive_puts_ignored=%zd\n", - zcache_pers_nonactive_puts_ignored); - pr_debug("zcache: eph_zbytes=%llu\n", - zcache_eph_zbytes); - pr_debug("zcache: eph_zbytes_max=%llu\n", - zcache_eph_zbytes_max); - pr_debug("zcache: pers_zbytes=%llu\n", - zcache_pers_zbytes); - pr_debug("zcache: pers_zbytes_max=%llu\n", - zcache_pers_zbytes_max); - pr_debug("zcache: outstanding_writeback_pages=%zd\n", - zcache_outstanding_writeback_pages); - pr_debug("zcache: writtenback_pages=%zd\n", zcache_writtenback_pages); -} - /* * zcache core code starts here */ -- cgit From 9c0ad59ef4878f76779cc7261a3d7959c72699aa Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:17 -0500 Subject: zcache/debug: Use an array to initialize/use debugfs attributes. It makes it neater and also allows us to piggyback on that in the zcache_dump function. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/debug.c | 163 +++++++++++++---------------------------- 1 file changed, 51 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/debug.c b/drivers/staging/zcache/debug.c index 622d5f371ff3..cf19adc23323 100644 --- a/drivers/staging/zcache/debug.c +++ b/drivers/staging/zcache/debug.c @@ -3,130 +3,69 @@ #ifdef CONFIG_DEBUG_FS #include -#define zdfs debugfs_create_size_t -#define zdfs64 debugfs_create_u64 + +#define ATTR(x) { .name = #x, .val = &zcache_##x, } +static struct debug_entry { + const char *name; + ssize_t *val; +} attrs[] = { + ATTR(obj_count), ATTR(obj_count_max), + ATTR(objnode_count), ATTR(objnode_count_max), + ATTR(flush_total), ATTR(flush_found), + ATTR(flobj_total), ATTR(flobj_found), + ATTR(failed_eph_puts), ATTR(failed_pers_puts), + ATTR(failed_getfreepages), ATTR(failed_alloc), + ATTR(put_to_flush), + ATTR(compress_poor), ATTR(mean_compress_poor), + ATTR(eph_ate_tail), ATTR(eph_ate_tail_failed), + ATTR(pers_ate_eph), ATTR(pers_ate_eph_failed), + ATTR(evicted_eph_zpages), ATTR(evicted_eph_pageframes), + ATTR(eph_pageframes), ATTR(eph_pageframes_max), + ATTR(eph_zpages), ATTR(eph_zpages_max), + ATTR(pers_zpages), ATTR(pers_zpages_max), + ATTR(last_active_file_pageframes), + ATTR(last_inactive_file_pageframes), + ATTR(last_active_anon_pageframes), + ATTR(last_inactive_anon_pageframes), + ATTR(eph_nonactive_puts_ignored), + ATTR(pers_nonactive_puts_ignored), +#ifdef CONFIG_ZCACHE_WRITEBACK + ATTR(zcache_outstanding_writeback_pages), + ATTR(zcache_writtenback_pages), +#endif +}; +#undef ATTR int zcache_debugfs_init(void) { + unsigned int i; struct dentry *root = debugfs_create_dir("zcache", NULL); if (root == NULL) return -ENXIO; - zdfs("obj_count", S_IRUGO, root, &zcache_obj_count); - zdfs("obj_count_max", S_IRUGO, root, &zcache_obj_count_max); - zdfs("objnode_count", S_IRUGO, root, &zcache_objnode_count); - zdfs("objnode_count_max", S_IRUGO, root, &zcache_objnode_count_max); - zdfs("flush_total", S_IRUGO, root, &zcache_flush_total); - zdfs("flush_found", S_IRUGO, root, &zcache_flush_found); - zdfs("flobj_total", S_IRUGO, root, &zcache_flobj_total); - zdfs("flobj_found", S_IRUGO, root, &zcache_flobj_found); - zdfs("failed_eph_puts", S_IRUGO, root, &zcache_failed_eph_puts); - zdfs("failed_pers_puts", S_IRUGO, root, &zcache_failed_pers_puts); - zdfs("failed_get_free_pages", S_IRUGO, root, - &zcache_failed_getfreepages); - zdfs("failed_alloc", S_IRUGO, root, &zcache_failed_alloc); - zdfs("put_to_flush", S_IRUGO, root, &zcache_put_to_flush); - zdfs("compress_poor", S_IRUGO, root, &zcache_compress_poor); - zdfs("mean_compress_poor", S_IRUGO, root, &zcache_mean_compress_poor); - zdfs("eph_ate_tail", S_IRUGO, root, &zcache_eph_ate_tail); - zdfs("eph_ate_tail_failed", S_IRUGO, root, &zcache_eph_ate_tail_failed); - zdfs("pers_ate_eph", S_IRUGO, root, &zcache_pers_ate_eph); - zdfs("pers_ate_eph_failed", S_IRUGO, root, &zcache_pers_ate_eph_failed); - zdfs("evicted_eph_zpages", S_IRUGO, root, &zcache_evicted_eph_zpages); - zdfs("evicted_eph_pageframes", S_IRUGO, root, - &zcache_evicted_eph_pageframes); - zdfs("eph_pageframes", S_IRUGO, root, &zcache_eph_pageframes); - zdfs("eph_pageframes_max", S_IRUGO, root, &zcache_eph_pageframes_max); - zdfs("pers_pageframes", S_IRUGO, root, &zcache_pers_pageframes); - zdfs("pers_pageframes_max", S_IRUGO, root, &zcache_pers_pageframes_max); - zdfs("eph_zpages", S_IRUGO, root, &zcache_eph_zpages); - zdfs("eph_zpages_max", S_IRUGO, root, &zcache_eph_zpages_max); - zdfs("pers_zpages", S_IRUGO, root, &zcache_pers_zpages); - zdfs("pers_zpages_max", S_IRUGO, root, &zcache_pers_zpages_max); - zdfs("last_active_file_pageframes", S_IRUGO, root, - &zcache_last_active_file_pageframes); - zdfs("last_inactive_file_pageframes", S_IRUGO, root, - &zcache_last_inactive_file_pageframes); - zdfs("last_active_anon_pageframes", S_IRUGO, root, - &zcache_last_active_anon_pageframes); - zdfs("last_inactive_anon_pageframes", S_IRUGO, root, - &zcache_last_inactive_anon_pageframes); - zdfs("eph_nonactive_puts_ignored", S_IRUGO, root, - &zcache_eph_nonactive_puts_ignored); - zdfs("pers_nonactive_puts_ignored", S_IRUGO, root, - &zcache_pers_nonactive_puts_ignored); - zdfs64("eph_zbytes", S_IRUGO, root, &zcache_eph_zbytes); - zdfs64("eph_zbytes_max", S_IRUGO, root, &zcache_eph_zbytes_max); - zdfs64("pers_zbytes", S_IRUGO, root, &zcache_pers_zbytes); - zdfs64("pers_zbytes_max", S_IRUGO, root, &zcache_pers_zbytes_max); - zdfs("outstanding_writeback_pages", S_IRUGO, root, - &zcache_outstanding_writeback_pages); - zdfs("writtenback_pages", S_IRUGO, root, &zcache_writtenback_pages); + for (i = 0; i < ARRAY_SIZE(attrs); i++) + if (!debugfs_create_size_t(attrs[i].name, S_IRUGO, root, attrs[i].val)) + goto out; + + debugfs_create_u64("eph_zbytes", S_IRUGO, root, &zcache_eph_zbytes); + debugfs_create_u64("eph_zbytes_max", S_IRUGO, root, &zcache_eph_zbytes_max); + debugfs_create_u64("pers_zbytes", S_IRUGO, root, &zcache_pers_zbytes); + debugfs_create_u64("pers_zbytes_max", S_IRUGO, root, &zcache_pers_zbytes_max); return 0; +out: + return -ENODEV; } -#undef zdebugfs -#undef zdfs64 /* developers can call this in case of ooms, e.g. to find memory leaks */ void zcache_dump(void) { - pr_debug("zcache: obj_count=%zd\n", zcache_obj_count); - pr_debug("zcache: obj_count_max=%zd\n", zcache_obj_count_max); - pr_debug("zcache: objnode_count=%zd\n", zcache_objnode_count); - pr_debug("zcache: objnode_count_max=%zd\n", zcache_objnode_count_max); - pr_debug("zcache: flush_total=%zd\n", zcache_flush_total); - pr_debug("zcache: flush_found=%zd\n", zcache_flush_found); - pr_debug("zcache: flobj_total=%zd\n", zcache_flobj_total); - pr_debug("zcache: flobj_found=%zd\n", zcache_flobj_found); - pr_debug("zcache: failed_eph_puts=%zd\n", zcache_failed_eph_puts); - pr_debug("zcache: failed_pers_puts=%zd\n", zcache_failed_pers_puts); - pr_debug("zcache: failed_get_free_pages=%zd\n", - zcache_failed_getfreepages); - pr_debug("zcache: failed_alloc=%zd\n", zcache_failed_alloc); - pr_debug("zcache: put_to_flush=%zd\n", zcache_put_to_flush); - pr_debug("zcache: compress_poor=%zd\n", zcache_compress_poor); - pr_debug("zcache: mean_compress_poor=%zd\n", - zcache_mean_compress_poor); - pr_debug("zcache: eph_ate_tail=%zd\n", zcache_eph_ate_tail); - pr_debug("zcache: eph_ate_tail_failed=%zd\n", - zcache_eph_ate_tail_failed); - pr_debug("zcache: pers_ate_eph=%zd\n", zcache_pers_ate_eph); - pr_debug("zcache: pers_ate_eph_failed=%zd\n", - zcache_pers_ate_eph_failed); - pr_debug("zcache: evicted_eph_zpages=%zd\n", zcache_evicted_eph_zpages); - pr_debug("zcache: evicted_eph_pageframes=%zd\n", - zcache_evicted_eph_pageframes); - pr_debug("zcache: eph_pageframes=%zd\n", zcache_eph_pageframes); - pr_debug("zcache: eph_pageframes_max=%zd\n", zcache_eph_pageframes_max); - pr_debug("zcache: pers_pageframes=%zd\n", zcache_pers_pageframes); - pr_debug("zcache: pers_pageframes_max=%zd\n", - zcache_pers_pageframes_max); - pr_debug("zcache: eph_zpages=%zd\n", zcache_eph_zpages); - pr_debug("zcache: eph_zpages_max=%zd\n", zcache_eph_zpages_max); - pr_debug("zcache: pers_zpages=%zd\n", zcache_pers_zpages); - pr_debug("zcache: pers_zpages_max=%zd\n", zcache_pers_zpages_max); - pr_debug("zcache: last_active_file_pageframes=%zd\n", - zcache_last_active_file_pageframes); - pr_debug("zcache: last_inactive_file_pageframes=%zd\n", - zcache_last_inactive_file_pageframes); - pr_debug("zcache: last_active_anon_pageframes=%zd\n", - zcache_last_active_anon_pageframes); - pr_debug("zcache: last_inactive_anon_pageframes=%zd\n", - zcache_last_inactive_anon_pageframes); - pr_debug("zcache: eph_nonactive_puts_ignored=%zd\n", - zcache_eph_nonactive_puts_ignored); - pr_debug("zcache: pers_nonactive_puts_ignored=%zd\n", - zcache_pers_nonactive_puts_ignored); - pr_debug("zcache: eph_zbytes=%llu\n", - zcache_eph_zbytes); - pr_debug("zcache: eph_zbytes_max=%llu\n", - zcache_eph_zbytes_max); - pr_debug("zcache: pers_zbytes=%llu\n", - zcache_pers_zbytes); - pr_debug("zcache: pers_zbytes_max=%llu\n", - zcache_pers_zbytes_max); - pr_debug("zcache: outstanding_writeback_pages=%zd\n", - zcache_outstanding_writeback_pages); - pr_debug("zcache: writtenback_pages=%zd\n", zcache_writtenback_pages); + unsigned int i; + for (i = 0; i < ARRAY_SIZE(attrs); i++) + pr_debug("zcache: %s=%zu\n", attrs[i].name, *attrs[i].val); + + pr_debug("zcache: eph_zbytes=%llu\n", (unsigned long long)zcache_eph_zbytes); + pr_debug("zcache: eph_zbytes_max=%llu\n", (unsigned long long)zcache_eph_zbytes_max); + pr_debug("zcache: pers_zbytes=%llu\n", (unsigned long long)zcache_pers_zbytes); + pr_debug("zcache: pers_zbytes_max=%llu\n", (unsigned long long)zcache_pers_zbytes_max); } #endif -- cgit From 86d7de66dde2ca8a298575274eba260c8505471e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:18 -0500 Subject: zcache: Move the last of the debugfs counters out We now have in zcache-main only the counters that are are not debugfs related. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/debug.h | 80 +++++++++++++++++++++++++++--------- drivers/staging/zcache/zcache-main.c | 75 +++++++++++++-------------------- 2 files changed, 89 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/debug.h b/drivers/staging/zcache/debug.h index 98dc491021d0..eef67dbe78d8 100644 --- a/drivers/staging/zcache/debug.h +++ b/drivers/staging/zcache/debug.h @@ -128,34 +128,56 @@ static inline unsigned long curr_pageframes_count(void) atomic_read(&zcache_pers_pageframes_atomic); }; /* but for the rest of these, counting races are ok */ -extern ssize_t zcache_flush_total; -extern ssize_t zcache_flush_found; -extern ssize_t zcache_flobj_total; -extern ssize_t zcache_flobj_found; -extern ssize_t zcache_failed_eph_puts; -extern ssize_t zcache_failed_pers_puts; -extern ssize_t zcache_failed_getfreepages; -extern ssize_t zcache_failed_alloc; -extern ssize_t zcache_put_to_flush; -extern ssize_t zcache_compress_poor; -extern ssize_t zcache_mean_compress_poor; -extern ssize_t zcache_eph_ate_tail; -extern ssize_t zcache_eph_ate_tail_failed; -extern ssize_t zcache_pers_ate_eph; -extern ssize_t zcache_pers_ate_eph_failed; -extern ssize_t zcache_evicted_eph_zpages; -extern ssize_t zcache_evicted_eph_pageframes; +static ssize_t zcache_flush_total; +static ssize_t zcache_flush_found; +static ssize_t zcache_flobj_total; +static ssize_t zcache_flobj_found; +static ssize_t zcache_failed_eph_puts; +static ssize_t zcache_failed_pers_puts; +static ssize_t zcache_failed_getfreepages; +static ssize_t zcache_failed_alloc; +static ssize_t zcache_put_to_flush; +static ssize_t zcache_compress_poor; +static ssize_t zcache_mean_compress_poor; +static ssize_t zcache_eph_ate_tail; +static ssize_t zcache_eph_ate_tail_failed; +static ssize_t zcache_pers_ate_eph; +static ssize_t zcache_pers_ate_eph_failed; +static ssize_t zcache_evicted_eph_zpages; +static ssize_t zcache_evicted_eph_pageframes; + extern ssize_t zcache_last_active_file_pageframes; extern ssize_t zcache_last_inactive_file_pageframes; extern ssize_t zcache_last_active_anon_pageframes; extern ssize_t zcache_last_inactive_anon_pageframes; -extern ssize_t zcache_eph_nonactive_puts_ignored; -extern ssize_t zcache_pers_nonactive_puts_ignored; +static ssize_t zcache_eph_nonactive_puts_ignored; +static ssize_t zcache_pers_nonactive_puts_ignored; #ifdef CONFIG_ZCACHE_WRITEBACK extern ssize_t zcache_writtenback_pages; extern ssize_t zcache_outstanding_writeback_pages; #endif +static inline void inc_zcache_flush_total(void) { zcache_flush_total ++; }; +static inline void inc_zcache_flush_found(void) { zcache_flush_found ++; }; +static inline void inc_zcache_flobj_total(void) { zcache_flobj_total ++; }; +static inline void inc_zcache_flobj_found(void) { zcache_flobj_found ++; }; +static inline void inc_zcache_failed_eph_puts(void) { zcache_failed_eph_puts ++; }; +static inline void inc_zcache_failed_pers_puts(void) { zcache_failed_pers_puts ++; }; +static inline void inc_zcache_failed_getfreepages(void) { zcache_failed_getfreepages ++; }; +static inline void inc_zcache_failed_alloc(void) { zcache_failed_alloc ++; }; +static inline void inc_zcache_put_to_flush(void) { zcache_put_to_flush ++; }; +static inline void inc_zcache_compress_poor(void) { zcache_compress_poor ++; }; +static inline void inc_zcache_mean_compress_poor(void) { zcache_mean_compress_poor ++; }; +static inline void inc_zcache_eph_ate_tail(void) { zcache_eph_ate_tail ++; }; +static inline void inc_zcache_eph_ate_tail_failed(void) { zcache_eph_ate_tail_failed ++; }; +static inline void inc_zcache_pers_ate_eph(void) { zcache_pers_ate_eph ++; }; +static inline void inc_zcache_pers_ate_eph_failed(void) { zcache_pers_ate_eph_failed ++; }; +static inline void inc_zcache_evicted_eph_zpages(unsigned zpages) { zcache_evicted_eph_zpages += zpages; }; +static inline void inc_zcache_evicted_eph_pageframes(void) { zcache_evicted_eph_pageframes ++; }; + +static inline void inc_zcache_eph_nonactive_puts_ignored(void) { zcache_eph_nonactive_puts_ignored ++; }; +static inline void inc_zcache_pers_nonactive_puts_ignored(void) { zcache_pers_nonactive_puts_ignored ++; }; + int zcache_debugfs_init(void); #else static inline void inc_zcache_obj_count(void) { }; @@ -184,4 +206,24 @@ static inline int zcache_debugfs_init(void) { return 0; }; +static inline void inc_zcache_flush_total(void) { }; +static inline void inc_zcache_flush_found(void) { }; +static inline void inc_zcache_flobj_total(void) { }; +static inline void inc_zcache_flobj_found(void) { }; +static inline void inc_zcache_failed_eph_puts(void) { }; +static inline void inc_zcache_failed_pers_puts(void) { }; +static inline void inc_zcache_failed_getfreepages(void) { }; +static inline void inc_zcache_failed_alloc(void) { }; +static inline void inc_zcache_put_to_flush(void) { }; +static inline void inc_zcache_compress_poor(void) { }; +static inline void inc_zcache_mean_compress_poor(void) { }; +static inline void inc_zcache_eph_ate_tail(void) { }; +static inline void inc_zcache_eph_ate_tail_failed(void) { }; +static inline void inc_zcache_pers_ate_eph(void) { }; +static inline void inc_zcache_pers_ate_eph_failed(void) { }; +static inline void inc_zcache_evicted_eph_zpages(unsigned zpages) { }; +static inline void inc_zcache_evicted_eph_pageframes(void) { }; + +static inline void inc_zcache_eph_nonactive_puts_ignored(void) { }; +static inline void inc_zcache_pers_nonactive_puts_ignored(void) { }; #endif diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 9d6cf968513e..059c0f228423 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -142,32 +142,13 @@ ssize_t zcache_eph_pageframes; ssize_t zcache_pers_pageframes; /* Used by this code. */ -static ssize_t zcache_flush_total; -static ssize_t zcache_flush_found; -static ssize_t zcache_flobj_total; -static ssize_t zcache_flobj_found; -static ssize_t zcache_failed_eph_puts; -static ssize_t zcache_failed_pers_puts; -static ssize_t zcache_failed_getfreepages; -static ssize_t zcache_failed_alloc; -static ssize_t zcache_put_to_flush; -static ssize_t zcache_compress_poor; -static ssize_t zcache_mean_compress_poor; -static ssize_t zcache_eph_ate_tail; -static ssize_t zcache_eph_ate_tail_failed; -static ssize_t zcache_pers_ate_eph; -static ssize_t zcache_pers_ate_eph_failed; -static ssize_t zcache_evicted_eph_zpages; -static ssize_t zcache_evicted_eph_pageframes; -static ssize_t zcache_last_active_file_pageframes; -static ssize_t zcache_last_inactive_file_pageframes; -static ssize_t zcache_last_active_anon_pageframes; -static ssize_t zcache_last_inactive_anon_pageframes; -static ssize_t zcache_eph_nonactive_puts_ignored; -static ssize_t zcache_pers_nonactive_puts_ignored; +ssize_t zcache_last_active_file_pageframes; +ssize_t zcache_last_inactive_file_pageframes; +ssize_t zcache_last_active_anon_pageframes; +ssize_t zcache_last_inactive_anon_pageframes; #ifdef CONFIG_ZCACHE_WRITEBACK -static ssize_t zcache_writtenback_pages; -static ssize_t zcache_outstanding_writeback_pages; +ssize_t zcache_writtenback_pages; +ssize_t zcache_outstanding_writeback_pages; #endif /* * zcache core code starts here @@ -354,7 +335,7 @@ static void *zcache_pampd_eph_create(char *data, size_t size, bool raw, if (!raw) { zcache_compress(page, &cdata, &clen); if (clen > zbud_max_buddy_size()) { - zcache_compress_poor++; + inc_zcache_compress_poor(); goto out; } } else { @@ -371,14 +352,14 @@ static void *zcache_pampd_eph_create(char *data, size_t size, bool raw, if (newpage != NULL) goto create_in_new_page; - zcache_failed_getfreepages++; + inc_zcache_failed_getfreepages(); /* can't allocate a page, evict an ephemeral page via LRU */ newpage = zcache_evict_eph_pageframe(); if (newpage == NULL) { - zcache_eph_ate_tail_failed++; + inc_zcache_eph_ate_tail_failed(); goto out; } - zcache_eph_ate_tail++; + inc_zcache_eph_ate_tail(); create_in_new_page: pampd = (void *)zbud_create_prep(th, true, cdata, clen, newpage); @@ -413,7 +394,7 @@ static void *zcache_pampd_pers_create(char *data, size_t size, bool raw, zcache_compress(page, &cdata, &clen); /* reject if compression is too poor */ if (clen > zbud_max_zsize) { - zcache_compress_poor++; + inc_zcache_compress_poor(); goto out; } /* reject if mean compression is too poor */ @@ -424,7 +405,7 @@ static void *zcache_pampd_pers_create(char *data, size_t size, bool raw, zbud_mean_zsize = div_u64(total_zsize, curr_pers_zpages); if (zbud_mean_zsize > zbud_max_mean_zsize) { - zcache_mean_compress_poor++; + inc_zcache_mean_compress_poor(); goto out; } } @@ -445,14 +426,14 @@ create_pampd: * (global_page_state(NR_LRU_BASE + LRU_ACTIVE_FILE) + * global_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE))) */ - zcache_failed_getfreepages++; + inc_zcache_failed_getfreepages(); /* can't allocate a page, evict an ephemeral page via LRU */ newpage = zcache_evict_eph_pageframe(); if (newpage == NULL) { - zcache_pers_ate_eph_failed++; + inc_zcache_pers_ate_eph_failed(); goto out; } - zcache_pers_ate_eph++; + inc_zcache_pers_ate_eph(); create_in_new_page: pampd = (void *)zbud_create_prep(th, false, cdata, clen, newpage); @@ -492,7 +473,7 @@ void *zcache_pampd_create(char *data, unsigned int size, bool raw, objnode = kmem_cache_alloc(zcache_objnode_cache, ZCACHE_GFP_MASK); if (unlikely(objnode == NULL)) { - zcache_failed_alloc++; + inc_zcache_failed_alloc(); goto out; } kp->objnodes[i] = objnode; @@ -503,7 +484,7 @@ void *zcache_pampd_create(char *data, unsigned int size, bool raw, kp->obj = obj; } if (unlikely(kp->obj == NULL)) { - zcache_failed_alloc++; + inc_zcache_failed_alloc(); goto out; } /* @@ -781,9 +762,9 @@ static struct page *zcache_evict_eph_pageframe(void) goto out; dec_zcache_eph_zbytes(zsize); dec_zcache_eph_zpages(zpages); - zcache_evicted_eph_zpages += zpages; + inc_zcache_evicted_eph_zpages(zpages); dec_zcache_eph_pageframes(); - zcache_evicted_eph_pageframes++; + inc_zcache_evicted_eph_pageframes(); out: return page; } @@ -1166,9 +1147,9 @@ int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, if (pampd == NULL) { ret = -ENOMEM; if (ephemeral) - zcache_failed_eph_puts++; + inc_zcache_failed_eph_puts(); else - zcache_failed_pers_puts++; + inc_zcache_failed_pers_puts(); } else { if (ramster_enabled) ramster_do_preload_flnode(pool); @@ -1178,7 +1159,7 @@ int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, } zcache_put_pool(pool); } else { - zcache_put_to_flush++; + inc_zcache_put_to_flush(); if (ramster_enabled) ramster_do_preload_flnode(pool); if (atomic_read(&pool->obj_count) > 0) @@ -1228,7 +1209,7 @@ int zcache_flush_page(int cli_id, int pool_id, unsigned long flags; local_irq_save(flags); - zcache_flush_total++; + inc_zcache_flush_total(); pool = zcache_get_pool_by_id(cli_id, pool_id); if (ramster_enabled) ramster_do_preload_flnode(pool); @@ -1238,7 +1219,7 @@ int zcache_flush_page(int cli_id, int pool_id, zcache_put_pool(pool); } if (ret >= 0) - zcache_flush_found++; + inc_zcache_flush_found(); local_irq_restore(flags); return ret; } @@ -1251,7 +1232,7 @@ int zcache_flush_object(int cli_id, int pool_id, unsigned long flags; local_irq_save(flags); - zcache_flobj_total++; + inc_zcache_flobj_total(); pool = zcache_get_pool_by_id(cli_id, pool_id); if (ramster_enabled) ramster_do_preload_flnode(pool); @@ -1261,7 +1242,7 @@ int zcache_flush_object(int cli_id, int pool_id, zcache_put_pool(pool); } if (ret >= 0) - zcache_flobj_found++; + inc_zcache_flobj_found(); local_irq_restore(flags); return ret; } @@ -1424,7 +1405,7 @@ static void zcache_cleancache_put_page(int pool_id, struct tmem_oid oid = *(struct tmem_oid *)&key; if (!disable_cleancache_ignore_nonactive && !PageWasActive(page)) { - zcache_eph_nonactive_puts_ignored++; + inc_zcache_eph_nonactive_puts_ignored(); return; } if (likely(ind == index)) @@ -1553,7 +1534,7 @@ static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, BUG_ON(!PageLocked(page)); if (!disable_frontswap_ignore_nonactive && !PageWasActive(page)) { - zcache_pers_nonactive_puts_ignored++; + inc_zcache_pers_nonactive_puts_ignored(); ret = -ERANGE; goto out; } -- cgit From 1dba904ca9893c9780748e8bda1c2423828faf40 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:19 -0500 Subject: zcache: Module license is defined twice. The other (same license) is at the end of the file. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 059c0f228423..4b9ee7f0218f 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -73,8 +73,6 @@ static char *namestr __read_mostly = "zcache"; #define ZCACHE_GFP_MASK \ (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) -MODULE_LICENSE("GPL"); - /* crypto API for zcache */ #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly; -- cgit From 67e2cba459a3780c283113808a07adea92762f86 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 4 Mar 2013 13:18:20 -0500 Subject: zcache/debug: Coalesce all debug under CONFIG_ZCACHE_DEBUG and also define this extra attribute in the Kconfig entry. Acked-by: Dan Magenheimer Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 8 ++++++++ drivers/staging/zcache/debug.c | 2 +- drivers/staging/zcache/zcache-main.c | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 73582705e8c5..2da6cc444c7e 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -10,6 +10,14 @@ config ZCACHE memory to store clean page cache pages and swap in RAM, providing a noticeable reduction in disk I/O. +config ZCACHE_DEBUG + bool "Enable debug statistics" + depends on DEBUG_FS && ZCACHE + default n + help + This is used to provide an debugfs directory with counters of + how zcache is doing. You probably want to set this to 'N'. + config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y diff --git a/drivers/staging/zcache/debug.c b/drivers/staging/zcache/debug.c index cf19adc23323..e951c64a13dc 100644 --- a/drivers/staging/zcache/debug.c +++ b/drivers/staging/zcache/debug.c @@ -1,7 +1,7 @@ #include #include "debug.h" -#ifdef CONFIG_DEBUG_FS +#ifdef CONFIG_ZCACHE_DEBUG #include #define ATTR(x) { .name = #x, .val = &zcache_##x, } diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 4b9ee7f0218f..7c0fda4106a0 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -306,7 +306,7 @@ static void zcache_free_page(struct page *page) max_pageframes = curr_pageframes; if (curr_pageframes < min_pageframes) min_pageframes = curr_pageframes; -#ifdef ZCACHE_DEBUG +#ifdef CONFIG_ZCACHE_DEBUG if (curr_pageframes > 2L || curr_pageframes < -2L) { /* pr_info here */ } @@ -1774,7 +1774,7 @@ static int __init zcache_init(void) old_ops = zcache_cleancache_register_ops(); pr_info("%s: cleancache enabled using kernel transcendent " "memory and compression buddies\n", namestr); -#ifdef ZCACHE_DEBUG +#ifdef CONFIG_ZCACHE_DEBUG pr_info("%s: cleancache: ignorenonactive = %d\n", namestr, !disable_cleancache_ignore_nonactive); #endif @@ -1789,7 +1789,7 @@ static int __init zcache_init(void) frontswap_tmem_exclusive_gets(true); pr_info("%s: frontswap enabled using kernel transcendent " "memory and compression buddies\n", namestr); -#ifdef ZCACHE_DEBUG +#ifdef CONFIG_ZCACHE_DEBUG pr_info("%s: frontswap: excl gets = %d active only = %d\n", namestr, frontswap_has_exclusive_gets, !disable_frontswap_ignore_nonactive); -- cgit From fdc5663c1b686caaaeff01f1b0918489536f7d7d Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 5 Mar 2013 09:49:01 +0100 Subject: HID: Kconfig: fix "-- help---" Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5f07d85c4189..49e29391cb98 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -738,7 +738,7 @@ config HID_SENSOR_HUB depends on USB_HID && GENERIC_HARDIRQS select MFD_CORE default n - -- help--- + ---help--- Support for HID Sensor framework. This creates a MFD instance for a sensor hub and identifies all the sensors connected to it. Each sensor is registered as a MFD cell, so that sensor specific -- cgit From 51dcdafcb720a9d1fd73b597d0ccf48837abc59f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Mar 2013 14:16:00 +0800 Subject: regulator: core: Add enable_is_inverted flag to indicate set enable_mask bits to disable Add enable_is_inverted flag to indicate set enable_mask bits to disable when using regulator_enable_regmap and friends APIs. Signed-off-by: Axel Lin Reviewed-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/core.c | 24 ++++++++++++++++++++---- include/linux/regulator/driver.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 154bc8f0c1a0..d887b9f5b213 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1794,7 +1794,10 @@ int regulator_is_enabled_regmap(struct regulator_dev *rdev) if (ret != 0) return ret; - return (val & rdev->desc->enable_mask) != 0; + if (rdev->desc->enable_is_inverted) + return (val & rdev->desc->enable_mask) == 0; + else + return (val & rdev->desc->enable_mask) != 0; } EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); @@ -1809,9 +1812,15 @@ EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); */ int regulator_enable_regmap(struct regulator_dev *rdev) { + unsigned int val; + + if (rdev->desc->enable_is_inverted) + val = 0; + else + val = rdev->desc->enable_mask; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, - rdev->desc->enable_mask); + rdev->desc->enable_mask, val); } EXPORT_SYMBOL_GPL(regulator_enable_regmap); @@ -1826,8 +1835,15 @@ EXPORT_SYMBOL_GPL(regulator_enable_regmap); */ int regulator_disable_regmap(struct regulator_dev *rdev) { + unsigned int val; + + if (rdev->desc->enable_is_inverted) + val = rdev->desc->enable_mask; + else + val = 0; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, 0); + rdev->desc->enable_mask, val); } EXPORT_SYMBOL_GPL(regulator_disable_regmap); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7df93f52db08..07ea8f1a127e 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -199,6 +199,8 @@ enum regulator_type { * output when using regulator_set_voltage_sel_regmap * @enable_reg: Register for control when using regmap enable/disable ops * @enable_mask: Mask for control when using regmap enable/disable ops + * @enable_is_inverted: A flag to indicate set enable_mask bits to disable + * when using regulator_enable_regmap and friends APIs. * @bypass_reg: Register for control when using regmap set_bypass * @bypass_mask: Mask for control when using regmap set_bypass * @@ -228,6 +230,7 @@ struct regulator_desc { unsigned int apply_bit; unsigned int enable_reg; unsigned int enable_mask; + bool enable_is_inverted; unsigned int bypass_reg; unsigned int bypass_mask; -- cgit From 318c658b7c9da58c80aef417e8f51152c604e6bc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Mar 2013 14:16:58 +0800 Subject: regulator: 88pm8607: Use enable_is_inverted flag with regulator_enable_regmap and friends APIs Signed-off-by: Axel Lin Reviewed-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/88pm8607.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index c79ab843333e..493948a38fca 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -220,35 +220,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) return ret; } -static int pm8606_preg_enable(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - - return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, - 1 << rdev->desc->enable_mask, 0); -} - -static int pm8606_preg_disable(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - - return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, - 1 << rdev->desc->enable_mask, - 1 << rdev->desc->enable_mask); -} - -static int pm8606_preg_is_enabled(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - int ret; - - ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg); - if (ret < 0) - return ret; - - return !((unsigned char)ret & (1 << rdev->desc->enable_mask)); -} - static struct regulator_ops pm8607_regulator_ops = { .list_voltage = pm8607_list_voltage, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -259,9 +230,9 @@ static struct regulator_ops pm8607_regulator_ops = { }; static struct regulator_ops pm8606_preg_ops = { - .enable = pm8606_preg_enable, - .disable = pm8606_preg_disable, - .is_enabled = pm8606_preg_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, }; #define PM8606_PREG(ereg, ebit) \ @@ -274,6 +245,7 @@ static struct regulator_ops pm8606_preg_ops = { .owner = THIS_MODULE, \ .enable_reg = PM8606_##ereg, \ .enable_mask = (ebit), \ + .enable_is_inverted = true, \ }, \ } -- cgit From ea88b132acdf3270b812117f622b0df044e6b76f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Mar 2013 14:17:57 +0800 Subject: regulator: max8649: Use enable_is_inverted flag with regulator_enable_regmap and friends APIs Signed-off-by: Axel Lin Reviewed-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/max8649.c | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 3ca14380f22d..fdb67ff98129 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -60,36 +60,6 @@ struct max8649_regulator_info { unsigned ramp_down:1; }; -/* EN_PD means pulldown on EN input */ -static int max8649_enable(struct regulator_dev *rdev) -{ - struct max8649_regulator_info *info = rdev_get_drvdata(rdev); - return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 0); -} - -/* - * Applied internal pulldown resistor on EN input pin. - * If pulldown EN pin outside, it would be better. - */ -static int max8649_disable(struct regulator_dev *rdev) -{ - struct max8649_regulator_info *info = rdev_get_drvdata(rdev); - return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, - MAX8649_EN_PD); -} - -static int max8649_is_enabled(struct regulator_dev *rdev) -{ - struct max8649_regulator_info *info = rdev_get_drvdata(rdev); - unsigned int val; - int ret; - - ret = regmap_read(info->regmap, MAX8649_CONTROL, &val); - if (ret != 0) - return ret; - return !((unsigned char)val & MAX8649_EN_PD); -} - static int max8649_enable_time(struct regulator_dev *rdev) { struct max8649_regulator_info *info = rdev_get_drvdata(rdev); @@ -151,9 +121,9 @@ static struct regulator_ops max8649_dcdc_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, - .enable = max8649_enable, - .disable = max8649_disable, - .is_enabled = max8649_is_enabled, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, .enable_time = max8649_enable_time, .set_mode = max8649_set_mode, .get_mode = max8649_get_mode, @@ -169,6 +139,9 @@ static struct regulator_desc dcdc_desc = { .vsel_mask = MAX8649_VOL_MASK, .min_uV = MAX8649_DCDC_VMIN, .uV_step = MAX8649_DCDC_STEP, + .enable_reg = MAX8649_CONTROL, + .enable_mask = MAX8649_EN_PD, + .enable_is_inverted = true, }; static struct regmap_config max8649_regmap_config = { -- cgit From 1c8408e3137bcb78d9ab8af832111f455d11e99c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 12 Feb 2013 10:12:09 -0800 Subject: ARM: S3C24XX: handle s3c2412 eints using new infrastructure The s3c2412 handles the eints 0 to 3 different than all the other SoCs of the 24xx range. These eints must be acked and masked in the regular bits as well as the bits 0 to 3 of the eint registers, which are unused on the other SoCs. This of course can be realized using the new infrastructure with the eint bits in the main register being the parent interrupts of the same bits in the eint register. The s3c2412 therefore gets its own IRQ_EINT0 to 4 constants that reside in the newly created gap before IRQ_EINT4. gpio-samsung, as the only user of these is modified to return the correct values when handling gpio_to_irq requests on s3c2412 based machines. Due to lack of hardware this is compile tested only, but should hopefully work as intended. Signed-off-by: Heiko Stuebner Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c24xx/include/mach/irqs.h | 4 + arch/arm/mach-s3c24xx/irq.c | 118 +++++++++--------------------- drivers/gpio/gpio-samsung.c | 5 +- 3 files changed, 44 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index ea589e4f0d8b..43cada8019b4 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -59,6 +59,10 @@ #define IRQ_ADCPARENT S3C2410_IRQ(31) /* interrupts generated from the external interrupts sources */ +#define IRQ_EINT0_2412 S3C2410_IRQ(32) +#define IRQ_EINT1_2412 S3C2410_IRQ(33) +#define IRQ_EINT2_2412 S3C2410_IRQ(34) +#define IRQ_EINT3_2412 S3C2410_IRQ(35) #define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */ #define IRQ_EINT5 S3C2410_IRQ(37) #define IRQ_EINT6 S3C2410_IRQ(38) diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index c2205eb78dc1..3f3de7492094 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -342,7 +342,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, case S3C_IRQTYPE_NONE: return 0; case S3C_IRQTYPE_EINT: - if (irq_data->parent_irq) + /* On the S3C2412, the EINT0to3 have a parent irq + * but need the s3c_irq_eint0t4 chip + */ + if (irq_data->parent_irq && (!soc_is_s3c2412() || hw >= 4)) irq_set_chip_and_handler(virq, &s3c_irqext_chip, handle_edge_irq); else @@ -623,10 +626,10 @@ void __init s3c24xx_init_irq(void) #ifdef CONFIG_CPU_S3C2412 static struct s3c_irq_data init_s3c2412base[32] = { - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */ { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ { .type = S3C_IRQTYPE_NONE, }, /* reserved */ @@ -657,6 +660,33 @@ static struct s3c_irq_data init_s3c2412base[32] = { { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ }; +static struct s3c_irq_data init_s3c2412eint[32] = { + { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ +}; + static struct s3c_irq_data init_s3c2412subint[32] = { { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ @@ -675,77 +705,9 @@ static struct s3c_irq_data init_s3c2412subint[32] = { { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ }; -/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by - * having them turn up in both the INT* and the EINT* registers. Whilst - * both show the status, they both now need to be acked when the IRQs - * go off. -*/ - -static void -s3c2412_irq_mask(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask | bitval, S3C2410_INTMSK); - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask | bitval, S3C2412_EINTMASK); -} - -static inline void -s3c2412_irq_ack(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - - __raw_writel(bitval, S3C2412_EINTPEND); - __raw_writel(bitval, S3C2410_SRCPND); - __raw_writel(bitval, S3C2410_INTPND); -} - -static inline void -s3c2412_irq_maskack(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask|bitval, S3C2410_INTMSK); - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask | bitval, S3C2412_EINTMASK); - - __raw_writel(bitval, S3C2412_EINTPEND); - __raw_writel(bitval, S3C2410_SRCPND); - __raw_writel(bitval, S3C2410_INTPND); -} - -static void -s3c2412_irq_unmask(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); - unsigned long mask; - - mask = __raw_readl(S3C2412_EINTMASK); - __raw_writel(mask & ~bitval, S3C2412_EINTMASK); - - mask = __raw_readl(S3C2410_INTMSK); - __raw_writel(mask & ~bitval, S3C2410_INTMSK); -} - -static struct irq_chip s3c2412_irq_eint0t4 = { - .irq_ack = s3c2412_irq_ack, - .irq_mask = s3c2412_irq_mask, - .irq_unmask = s3c2412_irq_unmask, - .irq_set_wake = s3c_irq_wake, - .irq_set_type = s3c_irqext_type, -}; - void s3c2412_init_irq(void) { struct s3c_irq_intc *main_intc; - unsigned int irqno; pr_info("S3C2412: IRQ Support\n"); @@ -759,16 +721,8 @@ void s3c2412_init_irq(void) return; } - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4); + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4); s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018); - - /* special handling for eints 0 to 3 */ - - for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { - irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, - handle_edge_irq); - set_irq_flags(irqno, IRQF_VALID); - } } #endif diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b3643ff007e4..db098cea3a55 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -1123,7 +1123,10 @@ int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) { if (offset < 4) - return IRQ_EINT0 + offset; + if (soc_is_s3c2412()) + return IRQ_EINT0_2412 + offset; + else + return IRQ_EINT0 + offset; if (offset < 8) return IRQ_EINT4 + offset - 4; -- cgit From d97fedef912832611b668fa7ece8e8ff54a6a590 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 12 Feb 2013 21:01:38 -0800 Subject: gpio: samsung: fixes build warning with s3c2410_defconfig commit 7b45ed96 ("ARM: S3C24XX: handle s3c2412 eints using new infrastructure") introduced build warning and this patch fixes that: drivers/gpio/gpio-samsung.c: In function 's3c24xx_gpiolib_fbank_to_irq': drivers/gpio/gpio-samsung.c:1126:5: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses] Reported-by: kbuild test robot Cc: Heiko Stuebner Signed-off-by: Kukjin Kim --- drivers/gpio/gpio-samsung.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index db098cea3a55..58aa28fb5889 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -1122,11 +1122,12 @@ int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) #ifdef CONFIG_PLAT_S3C24XX static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) { - if (offset < 4) + if (offset < 4) { if (soc_is_s3c2412()) return IRQ_EINT0_2412 + offset; else return IRQ_EINT0 + offset; + } if (offset < 8) return IRQ_EINT4 + offset - 4; -- cgit From f67faf487fc182772ffa5521e94aa7f0816a309c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 28 Dec 2012 10:37:27 -0800 Subject: pinctrl: exynos: add exynos5250 SoC specific data Add Samsung Exynos5250 SoC specific data to enable pinctrl support for all platforms based on Exynos5250. Signed-off-by: Thomas Abraham Acked-by: Linus Walleij Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/pinctrl/pinctrl-exynos.c | 108 ++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-samsung.c | 2 + drivers/pinctrl/pinctrl-samsung.h | 1 + 3 files changed, 111 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 538b9ddaadf7..8738933a57d7 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -677,3 +677,111 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .label = "exynos4x12-gpio-ctrl3", }, }; + +/* pin banks of exynos5250 pin-controller 0 */ +static struct samsung_pin_bank exynos5250_pin_banks0[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), + EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), + EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c), + EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10), + EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14), + EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18), + EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c), + EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc1", 0x20), + EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc2", 0x24), + EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc3", 0x28), + EXYNOS_PIN_BANK_EINTG(4, 0x160, "gpd0", 0x2c), + EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x30), + EXYNOS_PIN_BANK_EINTG(7, 0x2E0, "gpc4", 0x34), + EXYNOS_PIN_BANK_EINTN(6, 0x1A0, "gpy0"), + EXYNOS_PIN_BANK_EINTN(4, 0x1C0, "gpy1"), + EXYNOS_PIN_BANK_EINTN(6, 0x1E0, "gpy2"), + EXYNOS_PIN_BANK_EINTN(8, 0x200, "gpy3"), + EXYNOS_PIN_BANK_EINTN(8, 0x220, "gpy4"), + EXYNOS_PIN_BANK_EINTN(8, 0x240, "gpy5"), + EXYNOS_PIN_BANK_EINTN(8, 0x260, "gpy6"), + EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), + EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), + EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), + EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), +}; + +/* pin banks of exynos5250 pin-controller 1 */ +static struct samsung_pin_bank exynos5250_pin_banks1[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), + EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), + EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08), + EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf1", 0x0c), + EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10), + EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14), + EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18), + EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gph0", 0x1c), + EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph1", 0x20), +}; + +/* pin banks of exynos5250 pin-controller 2 */ +static struct samsung_pin_bank exynos5250_pin_banks2[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), + EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08), + EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c), + EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10), +}; + +/* pin banks of exynos5250 pin-controller 3 */ +static struct samsung_pin_bank exynos5250_pin_banks3[] = { + EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), +}; + +/* + * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes + * four gpio/pin-mux/pinconfig controllers. + */ +struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { + { + /* pin-controller instance 0 data */ + .pin_banks = exynos5250_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks0), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .weint_con = EXYNOS_WKUP_ECON_OFFSET, + .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, + .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .eint_wkup_init = exynos_eint_wkup_init, + .label = "exynos5250-gpio-ctrl0", + }, { + /* pin-controller instance 1 data */ + .pin_banks = exynos5250_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks1), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl1", + }, { + /* pin-controller instance 2 data */ + .pin_banks = exynos5250_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks2), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl2", + }, { + /* pin-controller instance 3 data */ + .pin_banks = exynos5250_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos5250_pin_banks3), + .geint_con = EXYNOS_GPIO_ECON_OFFSET, + .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, + .svc = EXYNOS_SVC_OFFSET, + .eint_gpio_init = exynos_eint_gpio_init, + .label = "exynos5250-gpio-ctrl3", + }, +}; diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index f206df175656..3d5cf639aa46 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -948,6 +948,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = (void *)exynos4210_pin_ctrl }, { .compatible = "samsung,exynos4x12-pinctrl", .data = (void *)exynos4x12_pin_ctrl }, + { .compatible = "samsung,exynos5250-pinctrl", + .data = (void *)exynos5250_pin_ctrl }, {}, }; MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match); diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index e2d4e67f7e88..ee964aadce0c 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h @@ -237,5 +237,6 @@ struct samsung_pmx_func { /* list of all exported SoC specific data */ extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; +extern struct samsung_pin_ctrl exynos5250_pin_ctrl[]; #endif /* __PINCTRL_SAMSUNG_H */ -- cgit From 70850ad85370b2100ffe0e6a892c1d60569b476a Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 28 Dec 2012 10:37:27 -0800 Subject: gpio: samsung: skip gpiolib registration if pinctrl support is enabled for exynos5250 Skip exynos5250 gpiolib registration if pinctrl support for exynos5250 is enabled. Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/gpio/gpio-samsung.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b3643ff007e4..49b4292b2d6a 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -3024,6 +3024,7 @@ static __init int samsung_gpiolib_init(void) static const struct of_device_id exynos_pinctrl_ids[] = { { .compatible = "samsung,exynos4210-pinctrl", }, { .compatible = "samsung,exynos4x12-pinctrl", }, + { .compatible = "samsung,exynos5250-pinctrl", }, { .compatible = "samsung,exynos5440-pinctrl", }, }; for_each_matching_node(pctrl_np, exynos_pinctrl_ids) -- cgit From 42e509c6d3090fc890d2b30fc3c0be02300256a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:17:52 -0300 Subject: [media] tlg2300: fix radio querycap Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-radio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 854ffa007c1f..80307d3857f5 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -147,7 +147,12 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(v->driver, "tele-radio", sizeof(v->driver)); strlcpy(v->card, "Telegent Poseidon", sizeof(v->card)); usb_make_path(p->udev, v->bus_info, sizeof(v->bus_info)); - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + /* Report all capabilities of the USB device */ + v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | + V4L2_CAP_AUDIO | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; return 0; } -- cgit From 270ecca60e9a2b0e3f8e5a45238d8b9d4c953ebb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 08:17:34 -0300 Subject: [media] tlg2300: add missing video_unregister_device Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-radio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c index 80307d3857f5..0f958f74dbc4 100644 --- a/drivers/media/usb/tlg2300/pd-radio.c +++ b/drivers/media/usb/tlg2300/pd-radio.c @@ -334,6 +334,7 @@ int poseidon_fm_init(struct poseidon *p) int poseidon_fm_exit(struct poseidon *p) { + video_unregister_device(&p->radio_data.fm_dev); v4l2_ctrl_handler_free(&p->radio_data.ctrl_handler); return 0; } -- cgit From 1b952f17f3ecb1cf3c38cb0c99dfd794d32259b0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 08:17:58 -0300 Subject: [media] tlg2300: embed video_device Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 6 ++-- drivers/media/usb/tlg2300/pd-video.c | 55 +++++++---------------------------- 2 files changed, 13 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 67ad065d2c3c..052cb0c9530c 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -40,7 +40,7 @@ #define TUNER_FREQ_MAX (862000000) struct vbi_data { - struct video_device *v_dev; + struct video_device v_dev; struct video_data *video; struct front_face *front; @@ -63,7 +63,7 @@ struct running_context { struct video_data { /* v4l2 video device */ - struct video_device *v_dev; + struct video_device v_dev; /* the working context */ struct running_context context; @@ -234,7 +234,6 @@ void dvb_stop_streaming(struct pd_dvb_adapter *); /* FM */ int poseidon_fm_init(struct poseidon *); int poseidon_fm_exit(struct poseidon *); -struct video_device *vdev_init(struct poseidon *, struct video_device *); /* vendor command ops */ int send_set_req(struct poseidon*, u8, s32, s32*); @@ -250,7 +249,6 @@ void free_all_urb_generic(struct urb **urb_array, int num); /* misc */ void poseidon_delete(struct kref *kref); -void destroy_video_device(struct video_device **v_dev); extern int debug_mode; void set_debug_mode(struct video_device *vfd, int debug_mode); diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 21723378bb8f..312809a68b23 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -1590,48 +1590,18 @@ static struct video_device pd_video_template = { .name = "Telegent-Video", .fops = &pd_video_fops, .minor = -1, - .release = video_device_release, + .release = video_device_release_empty, .tvnorms = V4L2_STD_ALL, .ioctl_ops = &pd_video_ioctl_ops, }; -struct video_device *vdev_init(struct poseidon *pd, struct video_device *tmp) -{ - struct video_device *vfd; - - vfd = video_device_alloc(); - if (vfd == NULL) - return NULL; - *vfd = *tmp; - vfd->minor = -1; - vfd->v4l2_dev = &pd->v4l2_dev; - /*vfd->parent = &(pd->udev->dev); */ - vfd->release = video_device_release; - video_set_drvdata(vfd, pd); - return vfd; -} - -void destroy_video_device(struct video_device **v_dev) -{ - struct video_device *dev = *v_dev; - - if (dev == NULL) - return; - - if (video_is_registered(dev)) - video_unregister_device(dev); - else - video_device_release(dev); - *v_dev = NULL; -} - void pd_video_exit(struct poseidon *pd) { struct video_data *video = &pd->video_data; struct vbi_data *vbi = &pd->vbi_data; - destroy_video_device(&video->v_dev); - destroy_video_device(&vbi->v_dev); + video_unregister_device(&video->v_dev); + video_unregister_device(&vbi->v_dev); log(); } @@ -1641,21 +1611,19 @@ int pd_video_init(struct poseidon *pd) struct vbi_data *vbi = &pd->vbi_data; int ret = -ENOMEM; - video->v_dev = vdev_init(pd, &pd_video_template); - if (video->v_dev == NULL) - goto out; + video->v_dev = pd_video_template; + video->v_dev.v4l2_dev = &pd->v4l2_dev; + video_set_drvdata(&video->v_dev, pd); - ret = video_register_device(video->v_dev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(&video->v_dev, VFL_TYPE_GRABBER, -1); if (ret != 0) goto out; /* VBI uses the same template as video */ - vbi->v_dev = vdev_init(pd, &pd_video_template); - if (vbi->v_dev == NULL) { - ret = -ENOMEM; - goto out; - } - ret = video_register_device(vbi->v_dev, VFL_TYPE_VBI, -1); + vbi->v_dev = pd_video_template; + vbi->v_dev.v4l2_dev = &pd->v4l2_dev; + video_set_drvdata(&vbi->v_dev, pd); + ret = video_register_device(&vbi->v_dev, VFL_TYPE_VBI, -1); if (ret != 0) goto out; log("register VIDEO/VBI devices"); @@ -1665,4 +1633,3 @@ out: pd_video_exit(pd); return ret; } - -- cgit From c5d8907faa93757aa440fd2e584e4db4b8edc14a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:42:03 -0300 Subject: [media] tlg2300: fix querycap Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-video.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 312809a68b23..8ab28945a347 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -142,17 +142,23 @@ static int get_audio_std(v4l2_std_id v4l2_std) static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { + struct video_device *vdev = video_devdata(file); + struct poseidon *p = video_get_drvdata(vdev); struct front_face *front = fh; - struct poseidon *p = front->pd; logs(front); strcpy(cap->driver, "tele-video"); strcpy(cap->card, "Telegent Poseidon"); usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | - V4L2_CAP_AUDIO | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE; + cap->device_caps = V4L2_CAP_TUNER | V4L2_CAP_AUDIO | + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + if (vdev->vfl_type == VFL_TYPE_VBI) + cap->device_caps |= V4L2_CAP_VBI_CAPTURE; + else + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | + V4L2_CAP_RADIO | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE; return 0; } -- cgit From 7556ba9bfb2ef0f2709fba40e77c7cc488645c79 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:27:37 -0300 Subject: [media] tlg2300: fix frequency handling The usual set of problems: the frequency isn't clamped to the frequency range, no tuner index check and the frequency isn't initialized properly on module load. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 4 ++-- drivers/media/usb/tlg2300/pd-video.c | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 052cb0c9530c..55fe66e440e3 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -36,8 +36,8 @@ #define V4L_PAL_VBI_FRAMESIZE (V4L_PAL_VBI_LINES * 1440 * 2) #define V4L_NTSC_VBI_FRAMESIZE (V4L_NTSC_VBI_LINES * 1440 * 2) -#define TUNER_FREQ_MIN (45000000) -#define TUNER_FREQ_MAX (862000000) +#define TUNER_FREQ_MIN (45000000U) +#define TUNER_FREQ_MAX (862000000U) struct vbi_data { struct video_device v_dev; diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 8ab28945a347..da7cbd4c4477 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -940,7 +940,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i) return 0; } -static struct poseidon_control *check_control_id(__u32 id) +static struct poseidon_control *check_control_id(u32 id) { struct poseidon_control *control = &controls[0]; int array_size = ARRAY_SIZE(controls); @@ -1134,21 +1134,21 @@ static int vidioc_g_frequency(struct file *file, void *fh, return 0; } -static int set_frequency(struct poseidon *pd, __u32 frequency) +static int set_frequency(struct poseidon *pd, u32 *frequency) { s32 ret = 0, param, cmd_status; struct running_context *context = &pd->video_data.context; - param = frequency * 62500 / 1000; - if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000) - return -EINVAL; + *frequency = clamp(*frequency, + TUNER_FREQ_MIN / 62500, TUNER_FREQ_MAX / 62500); + param = (*frequency) * 62500 / 1000; mutex_lock(&pd->lock); ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status); ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); msleep(250); /* wait for a while until the hardware is ready. */ - context->freq = frequency; + context->freq = *frequency; mutex_unlock(&pd->lock); return ret; } @@ -1159,12 +1159,14 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct front_face *front = fh; struct poseidon *pd = front->pd; + if (freq->tuner) + return -EINVAL; logs(front); #ifdef CONFIG_PM pd->pm_suspend = pm_video_suspend; pd->pm_resume = pm_video_resume; #endif - return set_frequency(pd, freq->frequency); + return set_frequency(pd, &freq->frequency); } static int vidioc_reqbufs(struct file *file, void *fh, @@ -1351,7 +1353,7 @@ static int restore_v4l2_context(struct poseidon *pd, vidioc_s_input(NULL, front, context->sig_index); pd_vidioc_s_tuner(pd, context->audio_idx); pd_vidioc_s_fmt(pd, &context->pix); - set_frequency(pd, context->freq); + set_frequency(pd, &context->freq); return 0; } @@ -1615,8 +1617,10 @@ int pd_video_init(struct poseidon *pd) { struct video_data *video = &pd->video_data; struct vbi_data *vbi = &pd->vbi_data; + u32 freq = TUNER_FREQ_MIN / 62500; int ret = -ENOMEM; + set_frequency(pd, &freq); video->v_dev = pd_video_template; video->v_dev.v4l2_dev = &pd->v4l2_dev; video_set_drvdata(&video->v_dev, pd); -- cgit From 7cb23987503be7ae4ed17678cdca9ddb025c21b8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 10:03:34 -0300 Subject: [media] tlg2300: fix missing audioset Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index da7cbd4c4477..122f299b7102 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -903,7 +903,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in) * the audio input index mixed with this video input, * Poseidon only have one audio/video, set to "0" */ - in->audioset = 0; + in->audioset = 1; in->tuner = 0; in->std = V4L2_STD_ALL; in->status = 0; -- cgit From f29056ebd9f78cde41d506f985a9e6dd9a21aa65 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 10:22:48 -0300 Subject: [media] tlg2300: implement the control framework Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 1 + drivers/media/usb/tlg2300/pd-video.c | 128 +++++++++++----------------------- 2 files changed, 41 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 55fe66e440e3..cb5cb0f70062 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -64,6 +64,7 @@ struct running_context { struct video_data { /* v4l2 video device */ struct video_device v_dev; + struct v4l2_ctrl_handler ctrl_handler; /* the working context */ struct running_context context; diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 122f299b7102..849c4bb0e79f 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -8,6 +8,7 @@ #include #include +#include #include "pd-common.h" #include "vendorcmds.h" @@ -82,31 +83,6 @@ static const struct pd_input pd_inputs[] = { }; static const unsigned int POSEIDON_INPUTS = ARRAY_SIZE(pd_inputs); -struct poseidon_control { - struct v4l2_queryctrl v4l2_ctrl; - enum cmd_custom_param_id vc_id; -}; - -static struct poseidon_control controls[] = { - { - { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER, - "brightness", 0, 10000, 1, 100, 0, }, - CUST_PARM_ID_BRIGHTNESS_CTRL - }, { - { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER, - "contrast", 0, 10000, 1, 100, 0, }, - CUST_PARM_ID_CONTRAST_CTRL, - }, { - { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER, - "hue", 0, 10000, 1, 100, 0, }, - CUST_PARM_ID_HUE_CTRL, - }, { - { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER, - "saturation", 0, 10000, 1, 100, 0, }, - CUST_PARM_ID_SATURATION_CTRL, - }, -}; - struct video_std_to_audio_std { v4l2_std_id video_std; int audio_std; @@ -940,68 +916,28 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i) return 0; } -static struct poseidon_control *check_control_id(u32 id) -{ - struct poseidon_control *control = &controls[0]; - int array_size = ARRAY_SIZE(controls); - - for (; control < &controls[array_size]; control++) - if (control->v4l2_ctrl.id == id) - return control; - return NULL; -} - -static int vidioc_queryctrl(struct file *file, void *fh, - struct v4l2_queryctrl *a) -{ - struct poseidon_control *control = NULL; - - control = check_control_id(a->id); - if (!control) - return -EINVAL; - - *a = control->v4l2_ctrl; - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl) -{ - struct front_face *front = fh; - struct poseidon *pd = front->pd; - struct poseidon_control *control = NULL; - struct tuner_custom_parameter_s tuner_param; - s32 ret = 0, cmd_status; - - control = check_control_id(ctrl->id); - if (!control) - return -EINVAL; - - mutex_lock(&pd->lock); - ret = send_get_req(pd, TUNER_CUSTOM_PARAMETER, control->vc_id, - &tuner_param, &cmd_status, sizeof(tuner_param)); - mutex_unlock(&pd->lock); - - if (ret || cmd_status) - return -1; - - ctrl->value = tuner_param.param_value; - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a) +static int tlg_s_ctrl(struct v4l2_ctrl *c) { + struct poseidon *pd = container_of(c->handler, struct poseidon, + video_data.ctrl_handler); struct tuner_custom_parameter_s param = {0}; - struct poseidon_control *control = NULL; - struct front_face *front = fh; - struct poseidon *pd = front->pd; s32 ret = 0, cmd_status, params; - control = check_control_id(a->id); - if (!control) - return -EINVAL; - - param.param_value = a->value; - param.param_id = control->vc_id; + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + param.param_id = CUST_PARM_ID_BRIGHTNESS_CTRL; + break; + case V4L2_CID_CONTRAST: + param.param_id = CUST_PARM_ID_CONTRAST_CTRL; + break; + case V4L2_CID_HUE: + param.param_id = CUST_PARM_ID_HUE_CTRL; + break; + case V4L2_CID_SATURATION: + param.param_id = CUST_PARM_ID_SATURATION_CTRL; + break; + } + param.param_value = c->val; params = *(s32 *)¶m; /* temp code */ mutex_lock(&pd->lock); @@ -1587,11 +1523,6 @@ static const struct v4l2_ioctl_ops pd_video_ioctl_ops = { /* Stream on/off */ .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, - - /* Control handling */ - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, }; static struct video_device pd_video_template = { @@ -1603,6 +1534,10 @@ static struct video_device pd_video_template = { .ioctl_ops = &pd_video_ioctl_ops, }; +static const struct v4l2_ctrl_ops tlg_ctrl_ops = { + .s_ctrl = tlg_s_ctrl, +}; + void pd_video_exit(struct poseidon *pd) { struct video_data *video = &pd->video_data; @@ -1610,6 +1545,7 @@ void pd_video_exit(struct poseidon *pd) video_unregister_device(&video->v_dev); video_unregister_device(&vbi->v_dev); + v4l2_ctrl_handler_free(&video->ctrl_handler); log(); } @@ -1617,12 +1553,27 @@ int pd_video_init(struct poseidon *pd) { struct video_data *video = &pd->video_data; struct vbi_data *vbi = &pd->vbi_data; + struct v4l2_ctrl_handler *hdl = &video->ctrl_handler; u32 freq = TUNER_FREQ_MIN / 62500; int ret = -ENOMEM; + v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_new_std(hdl, &tlg_ctrl_ops, V4L2_CID_BRIGHTNESS, + 0, 10000, 1, 100); + v4l2_ctrl_new_std(hdl, &tlg_ctrl_ops, V4L2_CID_CONTRAST, + 0, 10000, 1, 100); + v4l2_ctrl_new_std(hdl, &tlg_ctrl_ops, V4L2_CID_HUE, + 0, 10000, 1, 100); + v4l2_ctrl_new_std(hdl, &tlg_ctrl_ops, V4L2_CID_SATURATION, + 0, 10000, 1, 100); + if (hdl->error) { + v4l2_ctrl_handler_free(hdl); + return hdl->error; + } set_frequency(pd, &freq); video->v_dev = pd_video_template; video->v_dev.v4l2_dev = &pd->v4l2_dev; + video->v_dev.ctrl_handler = hdl; video_set_drvdata(&video->v_dev, pd); ret = video_register_device(&video->v_dev, VFL_TYPE_GRABBER, -1); @@ -1632,6 +1583,7 @@ int pd_video_init(struct poseidon *pd) /* VBI uses the same template as video */ vbi->v_dev = pd_video_template; vbi->v_dev.v4l2_dev = &pd->v4l2_dev; + vbi->v_dev.ctrl_handler = hdl; video_set_drvdata(&vbi->v_dev, pd); ret = video_register_device(&vbi->v_dev, VFL_TYPE_VBI, -1); if (ret != 0) -- cgit From d4de6e406211028b9186e223b766bcd17579ec97 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:33:35 -0300 Subject: [media] tlg2300: remove empty vidioc_try_fmt_vid_cap, add missing g_std Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-video.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 849c4bb0e79f..4c045b3c1456 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -705,12 +705,6 @@ static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) return 0; } -static int vidioc_try_fmt(struct file *file, void *fh, - struct v4l2_format *f) -{ - return 0; -} - /* * VLC calls VIDIOC_S_STD before VIDIOC_S_FMT, while * Mplayer calls them in the reverse order. @@ -866,6 +860,14 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm) return set_std(front->pd, norm); } +static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) +{ + struct front_face *front = fh; + logs(front); + *norm = front->pd->video_data.context.tvnormid; + return 0; +} + static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in) { struct front_face *front = fh; @@ -1495,7 +1497,6 @@ static const struct v4l2_ioctl_ops pd_video_ioctl_ops = { .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, .vidioc_s_fmt_vid_cap = vidioc_s_fmt, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi, /* VBI */ - .vidioc_try_fmt_vid_cap = vidioc_try_fmt, /* Input */ .vidioc_g_input = vidioc_g_input, @@ -1510,6 +1511,7 @@ static const struct v4l2_ioctl_ops pd_video_ioctl_ops = { /* Tuner ioctls */ .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_std = vidioc_g_std, .vidioc_s_std = vidioc_s_std, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, -- cgit From 60c66b6f276ec2a1f76788f0833ad2bf366522b6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Jul 2012 11:52:41 -0300 Subject: [media] tlg2300: allow multiple opens Due to a poor administration of the driver state it wasn't possible to open a video or vbi device multiple times. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 1 - drivers/media/usb/tlg2300/pd-video.c | 40 +++++++++++++---------------------- 2 files changed, 15 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index cb5cb0f70062..3010496787ab 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -26,7 +26,6 @@ #define POSEIDON_STATE_ANALOG (0x0001) #define POSEIDON_STATE_FM (0x0002) #define POSEIDON_STATE_DVBT (0x0004) -#define POSEIDON_STATE_VBI (0x0008) #define POSEIDON_STATE_DISCONNECT (0x0080) #define PM_SUSPEND_DELAY 3 diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 4c045b3c1456..834428d90766 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -1352,12 +1352,14 @@ static int pd_video_open(struct file *file) mutex_lock(&pd->lock); usb_autopm_get_interface(pd->interface); - if (vfd->vfl_type == VFL_TYPE_GRABBER - && !(pd->state & POSEIDON_STATE_ANALOG)) { - front = kzalloc(sizeof(struct front_face), GFP_KERNEL); - if (!front) - goto out; - + if (pd->state && !(pd->state & POSEIDON_STATE_ANALOG)) { + ret = -EBUSY; + goto out; + } + front = kzalloc(sizeof(struct front_face), GFP_KERNEL); + if (!front) + goto out; + if (vfd->vfl_type == VFL_TYPE_GRABBER) { pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */ init_video_context(&pd->video_data.context); @@ -1368,7 +1370,6 @@ static int pd_video_open(struct file *file) goto out; } - pd->state |= POSEIDON_STATE_ANALOG; front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; pd->video_data.users++; set_debug_mode(vfd, debug_mode); @@ -1379,13 +1380,7 @@ static int pd_video_open(struct file *file) V4L2_FIELD_INTERLACED,/* video is interlacd */ sizeof(struct videobuf_buffer),/*it's enough*/ front, NULL); - } else if (vfd->vfl_type == VFL_TYPE_VBI - && !(pd->state & POSEIDON_STATE_VBI)) { - front = kzalloc(sizeof(struct front_face), GFP_KERNEL); - if (!front) - goto out; - - pd->state |= POSEIDON_STATE_VBI; + } else { front->type = V4L2_BUF_TYPE_VBI_CAPTURE; pd->vbi_data.front = front; pd->vbi_data.users++; @@ -1396,19 +1391,15 @@ static int pd_video_open(struct file *file) V4L2_FIELD_NONE, /* vbi is NONE mode */ sizeof(struct videobuf_buffer), front, NULL); - } else { - /* maybe add FM support here */ - log("other "); - ret = -EINVAL; - goto out; } - front->pd = pd; - front->curr_frame = NULL; + pd->state |= POSEIDON_STATE_ANALOG; + front->pd = pd; + front->curr_frame = NULL; INIT_LIST_HEAD(&front->active); spin_lock_init(&front->queue_lock); - file->private_data = front; + file->private_data = front; kref_get(&pd->kref); mutex_unlock(&pd->lock); @@ -1429,8 +1420,6 @@ static int pd_video_release(struct file *file) mutex_lock(&pd->lock); if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - pd->state &= ~POSEIDON_STATE_ANALOG; - /* stop the device, and free the URBs */ usb_transfer_stop(&pd->video_data); free_all_urb(&pd->video_data); @@ -1442,10 +1431,11 @@ static int pd_video_release(struct file *file) pd->file_for_stream = NULL; pd->video_data.users--; } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - pd->state &= ~POSEIDON_STATE_VBI; pd->vbi_data.front = NULL; pd->vbi_data.users--; } + if (!pd->vbi_data.users && !pd->video_data.users) + pd->state &= ~POSEIDON_STATE_ANALOG; videobuf_stop(&front->q); videobuf_mmap_free(&front->q); -- cgit From ca1178ed6a6304185d77dd16462de0590d9a7b28 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 06:39:09 -0300 Subject: [media] tlg2300: Remove logs() macro ioctl debugging can now be done through the debug parameter in sysfs. Signed-off-by: Hans Verkuil Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tlg2300/pd-common.h | 9 --------- drivers/media/usb/tlg2300/pd-video.c | 23 ++--------------------- 2 files changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index 3010496787ab..9e23ad32d2fe 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -268,13 +268,4 @@ void set_debug_mode(struct video_device *vfd, int debug_mode); log();\ } while (0) -#define logs(f) do { \ - if ((debug_mode & 0x4) && \ - (f)->type == V4L2_BUF_TYPE_VBI_CAPTURE) \ - log("type : VBI");\ - \ - if ((debug_mode & 0x8) && \ - (f)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) \ - log("type : VIDEO");\ - } while (0) #endif diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 834428d90766..dab0ca32d396 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -120,9 +120,6 @@ static int vidioc_querycap(struct file *file, void *fh, { struct video_device *vdev = video_devdata(file); struct poseidon *p = video_get_drvdata(vdev); - struct front_face *front = fh; - - logs(front); strcpy(cap->driver, "tele-video"); strcpy(cap->card, "Telegent Poseidon"); @@ -205,7 +202,6 @@ static void submit_frame(struct front_face *front) */ static void end_field(struct video_data *video) { - /* logs(video->front); */ if (1 == video->field_count) submit_frame(video->front); else @@ -700,7 +696,6 @@ static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) struct front_face *front = fh; struct poseidon *pd = front->pd; - logs(front); f->fmt.pix = pd->video_data.context.pix; return 0; } @@ -763,7 +758,6 @@ static int vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) struct front_face *front = fh; struct poseidon *pd = front->pd; - logs(front); /* stop VBI here */ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type) return -EINVAL; @@ -804,7 +798,6 @@ static int vidioc_g_fmt_vbi(struct file *file, void *fh, vbi_fmt->count[1] = V4L_PAL_VBI_LINES; } vbi_fmt->flags = V4L2_VBI_UNSYNC; - logs(front); return 0; } @@ -856,22 +849,20 @@ out: static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm) { struct front_face *front = fh; - logs(front); + return set_std(front->pd, norm); } static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) { struct front_face *front = fh; - logs(front); + *norm = front->pd->video_data.context.tvnormid; return 0; } static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in) { - struct front_face *front = fh; - if (in->index >= POSEIDON_INPUTS) return -EINVAL; strcpy(in->name, pd_inputs[in->index].name); @@ -885,7 +876,6 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in) in->tuner = 0; in->std = V4L2_STD_ALL; in->status = 0; - logs(front); return 0; } @@ -895,7 +885,6 @@ static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) struct poseidon *pd = front->pd; struct running_context *context = &pd->video_data.context; - logs(front); *i = context->sig_index; return 0; } @@ -1023,7 +1012,6 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *tuner) tuner->rxsubchans = pd_audio_modes[index].v4l2_audio_sub; tuner->audmode = pd_audio_modes[index].v4l2_audio_mode; tuner->afc = 0; - logs(front); return 0; } @@ -1051,7 +1039,6 @@ static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *a) if (0 != a->index) return -EINVAL; - logs(front); for (index = 0; index < POSEIDON_AUDIOMODS; index++) if (a->audmode == pd_audio_modes[index].v4l2_audio_mode) return pd_vidioc_s_tuner(pd, index); @@ -1099,7 +1086,6 @@ static int vidioc_s_frequency(struct file *file, void *fh, if (freq->tuner) return -EINVAL; - logs(front); #ifdef CONFIG_PM pd->pm_suspend = pm_video_suspend; pd->pm_resume = pm_video_resume; @@ -1111,14 +1097,12 @@ static int vidioc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b) { struct front_face *front = file->private_data; - logs(front); return videobuf_reqbufs(&front->q, b); } static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b) { struct front_face *front = file->private_data; - logs(front); return videobuf_querybuf(&front->q, b); } @@ -1207,7 +1191,6 @@ static int vidioc_streamon(struct file *file, void *fh, { struct front_face *front = fh; - logs(front); if (unlikely(type != front->type)) return -EINVAL; return videobuf_streamon(&front->q); @@ -1218,7 +1201,6 @@ static int vidioc_streamoff(struct file *file, void *fh, { struct front_face *front = file->private_data; - logs(front); if (unlikely(type != front->type)) return -EINVAL; return videobuf_streamoff(&front->q); @@ -1416,7 +1398,6 @@ static int pd_video_release(struct file *file) struct poseidon *pd = front->pd; s32 cmd_status = 0; - logs(front); mutex_lock(&pd->lock); if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { -- cgit From 78dea1aed44a6e3e16973e584b00825359d470bd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 Sep 2012 09:03:29 -0300 Subject: [media] bttv: fix querycap and radio v4l2-compliance issues The querycap ioctl didn't support V4L2_CAP_DEVICE_CAPS and the radio device implemented audio and video inputs and s_std, which are not part of the radio API. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 101 +++++++++------------------------- 1 file changed, 27 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index ccd18e4ee789..cc7f58f94cde 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2630,6 +2630,7 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, static int bttv_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + struct video_device *vdev = video_devdata(file); struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; @@ -2642,11 +2643,15 @@ static int bttv_querycap(struct file *file, void *priv, "PCI:%s", pci_name(btv->c.pci)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VBI_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; + V4L2_CAP_STREAMING | + V4L2_CAP_DEVICE_CAPS; if (no_overlay <= 0) cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; + if (btv->vbi_dev) + cap->capabilities |= V4L2_CAP_VBI_CAPTURE; + if (btv->radio_dev) + cap->capabilities |= V4L2_CAP_RADIO; /* * No need to lock here: those vars are initialized during board @@ -2656,6 +2661,25 @@ static int bttv_querycap(struct file *file, void *priv, cap->capabilities |= V4L2_CAP_RDS_CAPTURE; if (btv->tuner_type != TUNER_ABSENT) cap->capabilities |= V4L2_CAP_TUNER; + if (vdev->vfl_type == VFL_TYPE_GRABBER) + cap->device_caps = cap->capabilities & + (V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | + V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_TUNER); + else if (vdev->vfl_type == VFL_TYPE_VBI) + cap->device_caps = cap->capabilities & + (V4L2_CAP_VBI_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | + V4L2_CAP_TUNER); + else { + cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; + if (btv->has_saa6588) + cap->device_caps |= V4L2_CAP_READWRITE | + V4L2_CAP_RDS_CAPTURE; + } return 0; } @@ -3430,20 +3454,6 @@ static int radio_release(struct file *file) return 0; } -static int radio_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - strcpy(cap->driver, "bttv"); - strlcpy(cap->card, btv->radio_dev->name, sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(btv->c.pci)); - cap->capabilities = V4L2_CAP_TUNER; - - return 0; -} - static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct bttv_fh *fh = priv; @@ -3464,29 +3474,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return 0; } -static int radio_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - if (i->index != 0) - return -EINVAL; - - strcpy(i->name, "Radio"); - i->type = V4L2_INPUT_TYPE_TUNER; - - return 0; -} - -static int radio_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - strcpy(a->name, "Radio"); - - return 0; -} - static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { @@ -3500,28 +3487,6 @@ static int radio_s_tuner(struct file *file, void *priv, return 0; } -static int radio_s_audio(struct file *file, void *priv, - const struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - return 0; -} - -static int radio_s_input(struct file *filp, void *priv, unsigned int i) -{ - if (unlikely(i)) - return -EINVAL; - - return 0; -} - -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) -{ - return 0; -} - static int radio_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { @@ -3540,12 +3505,6 @@ static int radio_queryctrl(struct file *file, void *priv, return 0; } -static int radio_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - static ssize_t radio_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { @@ -3586,16 +3545,10 @@ static const struct v4l2_file_operations radio_fops = }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = radio_querycap, + .vidioc_querycap = bttv_querycap, .vidioc_g_tuner = radio_g_tuner, - .vidioc_enum_input = radio_enum_input, - .vidioc_g_audio = radio_g_audio, .vidioc_s_tuner = radio_s_tuner, - .vidioc_s_audio = radio_s_audio, - .vidioc_s_input = radio_s_input, - .vidioc_s_std = radio_s_std, .vidioc_queryctrl = radio_queryctrl, - .vidioc_g_input = radio_g_input, .vidioc_g_ctrl = bttv_g_ctrl, .vidioc_s_ctrl = bttv_s_ctrl, .vidioc_g_frequency = bttv_g_frequency, -- cgit From 1b9e94dc69959e963fe57ede46259f792641af4d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 Sep 2012 09:23:31 -0300 Subject: [media] bttv: add VIDIOC_DBG_G_CHIP_IDENT VIDIOC_DBG_G_CHIP_IDENT is a prerequisite for the G/S_REGISTER ioctls. In addition, add support to call G/S_REGISTER for supporting i2c devices. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 40 +++++++++++++++++++++++++++++++---- drivers/media/pci/bt8xx/bttv.h | 3 +++ include/media/v4l2-chip-ident.h | 8 +++++++ 3 files changed, 47 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index cc7f58f94cde..b36d67577535 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -49,6 +49,7 @@ #include "bttvp.h" #include #include +#include #include #include @@ -2059,6 +2060,28 @@ static int bttv_log_status(struct file *file, void *f) return 0; } +static int bttv_g_chip_ident(struct file *file, void *f, struct v4l2_dbg_chip_ident *chip) +{ + struct bttv_fh *fh = f; + struct bttv *btv = fh->btv; + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match.type == V4L2_CHIP_MATCH_HOST) { + if (v4l2_chip_match_host(&chip->match)) { + chip->ident = btv->id; + if (chip->ident == PCI_DEVICE_ID_FUSION879) + chip->ident = V4L2_IDENT_BT879; + } + return 0; + } + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + /* TODO: is this correct? */ + return bttv_call_all_err(btv, core, g_chip_ident, chip); +} + #ifdef CONFIG_VIDEO_ADV_DEBUG static int bttv_g_register(struct file *file, void *f, struct v4l2_dbg_register *reg) @@ -2069,8 +2092,12 @@ static int bttv_g_register(struct file *file, void *f, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; + if (!v4l2_chip_match_host(®->match)) { + /* TODO: subdev errors should not be ignored, this should become a + subdev helper function. */ + bttv_call_all(btv, core, g_register, reg); + return 0; + } /* bt848 has a 12-bit register space */ reg->reg &= 0xfff; @@ -2089,8 +2116,12 @@ static int bttv_s_register(struct file *file, void *f, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; + if (!v4l2_chip_match_host(®->match)) { + /* TODO: subdev errors should not be ignored, this should become a + subdev helper function. */ + bttv_call_all(btv, core, s_register, reg); + return 0; + } /* bt848 has a 12-bit register space */ reg->reg &= 0xfff; @@ -3394,6 +3425,7 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_s_frequency = bttv_s_frequency, .vidioc_log_status = bttv_log_status, .vidioc_querystd = bttv_querystd, + .vidioc_g_chip_ident = bttv_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = bttv_g_register, .vidioc_s_register = bttv_s_register, diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index 79a11240a590..6139ce26dc2c 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -359,6 +359,9 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); #define bttv_call_all(btv, o, f, args...) \ v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args) +#define bttv_call_all_err(btv, o, f, args...) \ + v4l2_device_call_until_err(&btv->c.v4l2_dev, 0, o, f, ##args) + extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, unsigned char b2, int both); diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 4ee125bae719..b5996f959a31 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -96,12 +96,20 @@ enum { /* module au0828 */ V4L2_IDENT_AU0828 = 828, + /* module bttv: ident 848 + 849 */ + V4L2_IDENT_BT848 = 848, + V4L2_IDENT_BT849 = 849, + /* module bt856: just ident 856 */ V4L2_IDENT_BT856 = 856, /* module bt866: just ident 866 */ V4L2_IDENT_BT866 = 866, + /* module bttv: ident 878 + 879 */ + V4L2_IDENT_BT878 = 878, + V4L2_IDENT_BT879 = 879, + /* module ks0127: reserved range 1120-1129 */ V4L2_IDENT_KS0122S = 1122, V4L2_IDENT_KS0127 = 1127, -- cgit From f74f89cb1cf2cccdc111bcab7de4fb8c41bb2a07 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Jan 2013 08:45:13 -0300 Subject: [media] bttv: fix ENUM_INPUT and S_INPUT - Fix ENUM_INPUT audioset. - Fix incorrect input check in s_input. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index b36d67577535..6e61dbdd95c3 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1923,7 +1923,7 @@ static int bttv_enum_input(struct file *file, void *priv, } i->type = V4L2_INPUT_TYPE_CAMERA; - i->audioset = 1; + i->audioset = 0; if (btv->tuner_type != TUNER_ABSENT && i->index == 0) { sprintf(i->name, "Television"); @@ -1964,21 +1964,16 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - int err; err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; + if (err) + return err; - if (i > bttv_tvcards[btv->c.type].video_inputs) { - err = -EINVAL; - goto err; - } + if (i >= bttv_tvcards[btv->c.type].video_inputs) + return -EINVAL; set_input(btv, i, btv->tvnorm); - -err: return 0; } -- cgit From d9b6707673b6590bb6b984af6c435c807335a459 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 11:43:07 -0300 Subject: [media] bttv: disable g/s_tuner and g/s_freq when no tuner present, fix return codes If no tuner is present, then disable the tuner and frequency ioctls. We can remove a number of checks from those ioctls testing for the presence of a tuner. Also remove some tuner type checks (now done by the core) and fix an error return when the prio check fails. Finally some 'unlikely' statements are removed since those only make sense in tightly often executed loops, otherwise they just clutter up the code. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 44 +++++++++++++---------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 6e61dbdd95c3..f6f2b009bb6f 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1984,25 +1984,17 @@ static int bttv_s_tuner(struct file *file, void *priv, struct bttv *btv = fh->btv; int err; - if (unlikely(0 != t->index)) + if (t->index) return -EINVAL; - if (unlikely(btv->tuner_type == TUNER_ABSENT)) { - err = -EINVAL; - goto err; - } - err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; + if (err) + return err; bttv_call_all(btv, tuner, s_tuner, t); if (btv->audio_mode_gpio) btv->audio_mode_gpio(btv, t, 1); - -err: - return 0; } @@ -2012,9 +2004,10 @@ static int bttv_g_frequency(struct file *file, void *priv, struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = btv->freq; + if (f->tuner) + return -EINVAL; + f->frequency = btv->freq; return 0; } @@ -2025,24 +2018,17 @@ static int bttv_s_frequency(struct file *file, void *priv, struct bttv *btv = fh->btv; int err; - if (unlikely(f->tuner != 0)) + if (f->tuner) return -EINVAL; err = v4l2_prio_check(&btv->prio, fh->prio); - if (unlikely(err)) - goto err; + if (err) + return err; - if (unlikely(f->type != (btv->radio_user - ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) { - err = -EINVAL; - goto err; - } btv->freq = f->frequency; bttv_call_all(btv, tuner, s_frequency, f); if (btv->has_matchbox && btv->radio_user) tea5757_set_freq(btv, btv->freq); -err: - return 0; } @@ -2983,8 +2969,6 @@ static int bttv_g_tuner(struct file *file, void *priv, struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (btv->tuner_type == TUNER_ABSENT) - return -EINVAL; if (0 != t->index) return -EINVAL; @@ -3486,8 +3470,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (btv->tuner_type == TUNER_ABSENT) - return -EINVAL; if (0 != t->index) return -EINVAL; strcpy(t->name, "Radio"); @@ -4131,7 +4113,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) /* ----------------------------------------------------------------------- */ -/* initialitation */ +/* initialization */ static struct video_device *vdev_init(struct bttv *btv, const struct video_device *template, @@ -4150,6 +4132,12 @@ static struct video_device *vdev_init(struct bttv *btv, snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", type_name, bttv_tvcards[btv->c.type].name); + if (btv->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); + v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); + } return vfd; } -- cgit From 76ea992a036c4a5d3bc606a79ef775dd32fd3daa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 11:49:14 -0300 Subject: [media] bttv: set initial tv/radio frequencies Set an initial frequencies when the driver is loaded. That way G_FREQUENCY will give a frequency that corresponds with reality. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 34 ++++++++++++++++++++++++++++------ drivers/media/pci/bt8xx/bttvp.h | 3 ++- 2 files changed, 30 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index f6f2b009bb6f..546a9f55b809 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2007,10 +2007,27 @@ static int bttv_g_frequency(struct file *file, void *priv, if (f->tuner) return -EINVAL; - f->frequency = btv->freq; + f->frequency = f->type == V4L2_TUNER_RADIO ? + btv->radio_freq : btv->tv_freq; + return 0; } +static void bttv_set_frequency(struct bttv *btv, struct v4l2_frequency *f) +{ + bttv_call_all(btv, tuner, s_frequency, f); + /* s_frequency may clamp the frequency, so get the actual + frequency before assigning radio/tv_freq. */ + bttv_call_all(btv, tuner, g_frequency, f); + if (f->type == V4L2_TUNER_RADIO) { + btv->radio_freq = f->frequency; + if (btv->has_matchbox) + tea5757_set_freq(btv, btv->radio_freq); + } else { + btv->tv_freq = f->frequency; + } +} + static int bttv_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { @@ -2024,11 +2041,7 @@ static int bttv_s_frequency(struct file *file, void *priv, err = v4l2_prio_check(&btv->prio, fh->prio); if (err) return err; - - btv->freq = f->frequency; - bttv_call_all(btv, tuner, s_frequency, f); - if (btv->has_matchbox && btv->radio_user) - tea5757_set_freq(btv, btv->freq); + bttv_set_frequency(btv, f); return 0; } @@ -4235,6 +4248,11 @@ static void pci_set_command(struct pci_dev *dev) static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { + struct v4l2_frequency init_freq = { + .tuner = 0, + .type = V4L2_TUNER_ANALOG_TV, + .frequency = 980, + }; int result; unsigned char lat; struct bttv *btv; @@ -4375,6 +4393,10 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) /* some card-specific stuff (needs working i2c) */ bttv_init_card2(btv); bttv_init_tuner(btv); + if (btv->tuner_type != TUNER_ABSENT) { + bttv_set_frequency(btv, &init_freq); + btv->radio_freq = 90500 * 16; /* 90.5Mhz default */ + } init_irqreg(btv); /* register video4linux + input */ diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 9ec0adba236c..528e03ec19e8 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -418,7 +418,7 @@ struct bttv { unsigned int input; unsigned int audio; unsigned int mute; - unsigned long freq; + unsigned long tv_freq; unsigned int tvnorm; int hue, contrast, bright, saturation; struct v4l2_framebuffer fbuf; @@ -442,6 +442,7 @@ struct bttv { int has_radio; int radio_user; int radio_uses_msp_demodulator; + unsigned long radio_freq; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ -- cgit From a652ef60952dd816bf84c7c52e0caf6e71ea5a49 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 Sep 2012 10:27:57 -0300 Subject: [media] bttv: G_PARM: set readbuffers Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 546a9f55b809..fb8ec0a67d14 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2970,6 +2970,9 @@ static int bttv_g_parm(struct file *file, void *f, struct bttv_fh *fh = f; struct bttv *btv = fh->btv; + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + parm->parm.capture.readbuffers = gbuffers; v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, &parm->parm.capture.timeperframe); -- cgit From f58648999347ff44194ff948637e465868acc1e6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 11:58:59 -0300 Subject: [media] bttv: fill in colorspace Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index fb8ec0a67d14..dbf1882147c7 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2506,6 +2506,7 @@ static int bttv_g_fmt_vid_cap(struct file *file, void *priv, fh->width, fh->height); f->fmt.pix.field = fh->cap.field; f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } @@ -2577,6 +2578,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, /* update data for the application */ f->fmt.pix.field = field; pix_format_set_size(&f->fmt.pix, fmt, width, height); + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } -- cgit From a12fd70e3b32a4de5e5dc6346a0f5bdfd164ed3d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:00:03 -0300 Subject: [media] bttv: fill in fb->flags for VIDIOC_G_FBUF Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index dbf1882147c7..cffa8b6683ea 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2769,6 +2769,7 @@ static int bttv_g_fbuf(struct file *file, void *f, *fb = btv->fbuf; fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + fb->flags = V4L2_FBUF_FLAG_PRIMARY; if (fh->ovfmt) fb->fmt.pixelformat = fh->ovfmt->fourcc; return 0; -- cgit From ee70e3d8039f16137d2e7e2e1a9cf8374b01be9b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:03:30 -0300 Subject: [media] bttv: fix field handling inside TRY_FMT - don't return -EINVAL for invalid field types, handle those as if it was FIELD_ANY. - the handling of FIELD_SEQ_BT/TB was wrong as well: if such field formats aren't supported, then fall back to FIELD_ANY instead of returning an error. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index cffa8b6683ea..73404b7a1396 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2530,6 +2530,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, struct bttv *btv = fh->btv; enum v4l2_field field; __s32 width, height; + __s32 height2; int rc; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -2538,30 +2539,25 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, field = f->fmt.pix.field; - if (V4L2_FIELD_ANY == field) { - __s32 height2; - - height2 = btv->crop[!!fh->do_crop].rect.height >> 1; - field = (f->fmt.pix.height > height2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - - if (V4L2_FIELD_SEQ_BT == field) - field = V4L2_FIELD_SEQ_TB; - switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_INTERLACED: break; + case V4L2_FIELD_SEQ_BT: case V4L2_FIELD_SEQ_TB: - if (fmt->flags & FORMAT_FLAGS_PLANAR) - return -EINVAL; + if (!(fmt->flags & FORMAT_FLAGS_PLANAR)) { + field = V4L2_FIELD_SEQ_TB; + break; + } + /* fall through */ + default: /* FIELD_ANY case */ + height2 = btv->crop[!!fh->do_crop].rect.height >> 1; + field = (f->fmt.pix.height > height2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_BOTTOM; break; - default: - return -EINVAL; } width = f->fmt.pix.width; -- cgit From 5d478e0de87113b9fa6b4021935e605b71e0ee28 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 5 Feb 2013 12:17:38 -0300 Subject: [media] tda7432: convert to the control framework Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tda7432.c | 276 ++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 166 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c index f7707e65761e..28b5121881f5 100644 --- a/drivers/media/i2c/tda7432.c +++ b/drivers/media/i2c/tda7432.c @@ -35,6 +35,7 @@ #include #include +#include #include #ifndef VIDEO_AUDIO_BALANCE @@ -60,13 +61,17 @@ MODULE_PARM_DESC(maxvol, "Set maximium volume to +20dB(0) else +0dB(1). Default struct tda7432 { struct v4l2_subdev sd; - int addr; - int input; - int volume; - int muted; - int bass, treble; - int lf, lr, rf, rr; - int loud; + struct v4l2_ctrl_handler hdl; + struct { + /* bass/treble cluster */ + struct v4l2_ctrl *bass; + struct v4l2_ctrl *treble; + }; + struct { + /* mute/balance cluster */ + struct v4l2_ctrl *mute; + struct v4l2_ctrl *balance; + }; }; static inline struct tda7432 *to_state(struct v4l2_subdev *sd) @@ -74,6 +79,11 @@ static inline struct tda7432 *to_state(struct v4l2_subdev *sd) return container_of(sd, struct tda7432, sd); } +static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) +{ + return &container_of(ctrl->handler, struct tda7432, hdl)->sd; +} + /* The TDA7432 is made by STS-Thompson * http://www.st.com * http://us.st.com/stonline/books/pdf/docs/4056.pdf @@ -227,24 +237,22 @@ static int tda7432_write(struct v4l2_subdev *sd, int subaddr, int val) static int tda7432_set(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct tda7432 *t = to_state(sd); unsigned char buf[16]; - v4l2_dbg(1, debug, sd, - "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", - t->input, t->volume, t->bass, t->treble, t->lf, t->lr, - t->rf, t->rr, t->loud); buf[0] = TDA7432_IN; - buf[1] = t->input; - buf[2] = t->volume; - buf[3] = t->bass; - buf[4] = t->treble; - buf[5] = t->lf; - buf[6] = t->lr; - buf[7] = t->rf; - buf[8] = t->rr; - buf[9] = t->loud; - if (10 != i2c_master_send(client, buf, 10)) { + buf[1] = TDA7432_STEREO_IN | /* Main (stereo) input */ + TDA7432_BASS_SYM | /* Symmetric bass cut */ + TDA7432_BASS_NORM; /* Normal bass range */ + buf[2] = 0x3b; + if (loudness) /* Turn loudness on? */ + buf[2] |= TDA7432_LD_ON; + buf[3] = TDA7432_TREBLE_0DB | (TDA7432_BASS_0DB << 4); + buf[4] = TDA7432_ATTEN_0DB; + buf[5] = TDA7432_ATTEN_0DB; + buf[6] = TDA7432_ATTEN_0DB; + buf[7] = TDA7432_ATTEN_0DB; + buf[8] = loudness; + if (9 != i2c_master_send(client, buf, 9)) { v4l2_err(sd, "I/O error, trying tda7432_set\n"); return -1; } @@ -252,174 +260,86 @@ static int tda7432_set(struct v4l2_subdev *sd) return 0; } -static void do_tda7432_init(struct v4l2_subdev *sd) -{ - struct tda7432 *t = to_state(sd); - - v4l2_dbg(2, debug, sd, "In tda7432_init\n"); - - t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ - TDA7432_BASS_SYM | /* Symmetric bass cut */ - TDA7432_BASS_NORM; /* Normal bass range */ - t->volume = 0x3b ; /* -27dB Volume */ - if (loudness) /* Turn loudness on? */ - t->volume |= TDA7432_LD_ON; - t->muted = 1; - t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */ - t->bass = TDA7432_BASS_0DB; /* 0dB Bass */ - t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ - t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */ - t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ - t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */ - t->loud = loudness; /* insmod parameter */ - - tda7432_set(sd); -} - -static int tda7432_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int tda7432_log_status(struct v4l2_subdev *sd) { - struct tda7432 *t = to_state(sd); + struct tda7432 *state = to_state(sd); - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value=t->muted; - return 0; - case V4L2_CID_AUDIO_VOLUME: - if (!maxvol){ /* max +20db */ - ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 630; - } else { /* max 0db */ - ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 829; - } - return 0; - case V4L2_CID_AUDIO_BALANCE: - { - if ( (t->lf) < (t->rf) ) - /* right is attenuated, balance shifted left */ - ctrl->value = (32768 - 1057*(t->rf)); - else - /* left is attenuated, balance shifted right */ - ctrl->value = (32768 + 1057*(t->lf)); - return 0; - } - case V4L2_CID_AUDIO_BASS: - { - /* Bass/treble 4 bits each */ - int bass=t->bass; - if(bass >= 0x8) - bass = ~(bass - 0x8) & 0xf; - ctrl->value = (bass << 12)+(bass << 8)+(bass << 4)+(bass); - return 0; - } - case V4L2_CID_AUDIO_TREBLE: - { - int treble=t->treble; - if(treble >= 0x8) - treble = ~(treble - 0x8) & 0xf; - ctrl->value = (treble << 12)+(treble << 8)+(treble << 4)+(treble); - return 0; - } - } - return -EINVAL; + v4l2_ctrl_handler_log_status(&state->hdl, sd->name); + return 0; } -static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int tda7432_s_ctrl(struct v4l2_ctrl *ctrl) { + struct v4l2_subdev *sd = to_sd(ctrl); struct tda7432 *t = to_state(sd); + u8 bass, treble, volume; + u8 lf, lr, rf, rr; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - t->muted=ctrl->value; - break; - case V4L2_CID_AUDIO_VOLUME: - if(!maxvol){ /* max +20db */ - t->volume = 0x6f - ((ctrl->value)/630); - } else { /* max 0db */ - t->volume = 0x6f - ((ctrl->value)/829); - } - if (loudness) /* Turn on the loudness bit */ - t->volume |= TDA7432_LD_ON; - - tda7432_write(sd, TDA7432_VL, t->volume); - return 0; - case V4L2_CID_AUDIO_BALANCE: - if (ctrl->value < 32768) { + if (t->balance->val < 0) { /* shifted to left, attenuate right */ - t->rr = (32768 - ctrl->value)/1057; - t->rf = t->rr; - t->lr = TDA7432_ATTEN_0DB; - t->lf = TDA7432_ATTEN_0DB; - } else if(ctrl->value > 32769) { + rr = rf = -t->balance->val; + lr = lf = TDA7432_ATTEN_0DB; + } else if (t->balance->val > 0) { /* shifted to right, attenuate left */ - t->lf = (ctrl->value - 32768)/1057; - t->lr = t->lf; - t->rr = TDA7432_ATTEN_0DB; - t->rf = TDA7432_ATTEN_0DB; + rr = rf = TDA7432_ATTEN_0DB; + lr = lf = t->balance->val; } else { /* centered */ - t->rr = TDA7432_ATTEN_0DB; - t->rf = TDA7432_ATTEN_0DB; - t->lf = TDA7432_ATTEN_0DB; - t->lr = TDA7432_ATTEN_0DB; + rr = rf = TDA7432_ATTEN_0DB; + lr = lf = TDA7432_ATTEN_0DB; } - break; - case V4L2_CID_AUDIO_BASS: - t->bass = ctrl->value >> 12; - if(t->bass>= 0x8) - t->bass = (~t->bass & 0xf) + 0x8 ; - - tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble); + if (t->mute->val) { + lf |= TDA7432_MUTE; + lr |= TDA7432_MUTE; + lf |= TDA7432_MUTE; + rr |= TDA7432_MUTE; + } + /* Mute & update balance*/ + tda7432_write(sd, TDA7432_LF, lf); + tda7432_write(sd, TDA7432_LR, lr); + tda7432_write(sd, TDA7432_RF, rf); + tda7432_write(sd, TDA7432_RR, rr); return 0; - case V4L2_CID_AUDIO_TREBLE: - t->treble= ctrl->value >> 12; - if(t->treble>= 0x8) - t->treble = (~t->treble & 0xf) + 0x8 ; + case V4L2_CID_AUDIO_VOLUME: + volume = 0x6f - ctrl->val; + if (loudness) /* Turn on the loudness bit */ + volume |= TDA7432_LD_ON; - tda7432_write(sd, TDA7432_TN, 0x10 | (t->bass << 4) | t->treble); + tda7432_write(sd, TDA7432_VL, volume); return 0; - default: - return -EINVAL; - } - - /* Used for both mute and balance changes */ - if (t->muted) - { - /* Mute & update balance*/ - tda7432_write(sd, TDA7432_LF, t->lf | TDA7432_MUTE); - tda7432_write(sd, TDA7432_LR, t->lr | TDA7432_MUTE); - tda7432_write(sd, TDA7432_RF, t->rf | TDA7432_MUTE); - tda7432_write(sd, TDA7432_RR, t->rr | TDA7432_MUTE); - } else { - tda7432_write(sd, TDA7432_LF, t->lf); - tda7432_write(sd, TDA7432_LR, t->lr); - tda7432_write(sd, TDA7432_RF, t->rf); - tda7432_write(sd, TDA7432_RR, t->rr); - } - return 0; -} - -static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + bass = t->bass->val; + treble = t->treble->val; + if (bass >= 0x8) + bass = 14 - (bass - 8); + if (treble >= 0x8) + treble = 14 - (treble - 8); + + tda7432_write(sd, TDA7432_TN, 0x10 | (bass << 4) | treble); + return 0; } return -EINVAL; } /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops tda7432_core_ops = { - .queryctrl = tda7432_queryctrl, - .g_ctrl = tda7432_g_ctrl, +static const struct v4l2_ctrl_ops tda7432_ctrl_ops = { .s_ctrl = tda7432_s_ctrl, }; +static const struct v4l2_subdev_core_ops tda7432_core_ops = { + .log_status = tda7432_log_status, + .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, + .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, + .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, + .g_ctrl = v4l2_subdev_g_ctrl, + .s_ctrl = v4l2_subdev_s_ctrl, + .queryctrl = v4l2_subdev_queryctrl, + .querymenu = v4l2_subdev_querymenu, +}; + static const struct v4l2_subdev_ops tda7432_ops = { .core = &tda7432_core_ops, }; @@ -444,6 +364,28 @@ static int tda7432_probe(struct i2c_client *client, return -ENOMEM; sd = &t->sd; v4l2_i2c_subdev_init(sd, client, &tda7432_ops); + v4l2_ctrl_handler_init(&t->hdl, 5); + v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops, + V4L2_CID_AUDIO_VOLUME, 0, maxvol ? 0x68 : 0x4f, 1, maxvol ? 0x5d : 0x47); + t->mute = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops, + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); + t->balance = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops, + V4L2_CID_AUDIO_BALANCE, -31, 31, 1, 0); + t->bass = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops, + V4L2_CID_AUDIO_BASS, 0, 14, 1, 7); + t->treble = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops, + V4L2_CID_AUDIO_TREBLE, 0, 14, 1, 7); + sd->ctrl_handler = &t->hdl; + if (t->hdl.error) { + int err = t->hdl.error; + + v4l2_ctrl_handler_free(&t->hdl); + kfree(t); + return err; + } + v4l2_ctrl_cluster(2, &t->bass); + v4l2_ctrl_cluster(2, &t->mute); + v4l2_ctrl_handler_setup(&t->hdl); if (loudness < 0 || loudness > 15) { v4l2_warn(sd, "loudness parameter must be between 0 and 15\n"); if (loudness < 0) @@ -452,17 +394,19 @@ static int tda7432_probe(struct i2c_client *client, loudness = 15; } - do_tda7432_init(sd); + tda7432_set(sd); return 0; } static int tda7432_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct tda7432 *t = to_state(sd); - do_tda7432_init(sd); + tda7432_set(sd); v4l2_device_unregister_subdev(sd); - kfree(to_state(sd)); + v4l2_ctrl_handler_free(&t->hdl); + kfree(t); return 0; } -- cgit From 01df530c2791610727e345b3dd97ef75943c7320 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:40:28 -0300 Subject: [media] bttv: convert to the control framework Note that the private chroma agc control has been replaced with the standard CHROMA_AGC control. Also fixes a mute/automute problem where closing the file handle would force mute on. That's not what you want since that would make the mute state out of sync with the mute control. Instead check against the user count. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-cards.c | 5 +- drivers/media/pci/bt8xx/bttv-driver.c | 682 +++++++++++++--------------------- drivers/media/pci/bt8xx/bttvp.h | 16 +- include/uapi/linux/v4l2-controls.h | 5 + 4 files changed, 271 insertions(+), 437 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index c4c59175e52c..682ed893d718 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -3554,8 +3554,9 @@ void bttv_init_card2(struct bttv *btv) I2C_CLIENT_END }; - if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tda7432", 0, addrs)) + btv->sd_tda7432 = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, + &btv->c.i2c_adap, "tda7432", 0, addrs); + if (btv->sd_tda7432) return; } diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 73404b7a1396..8e0a44d03fc4 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -94,7 +94,7 @@ static unsigned int combfilter; static unsigned int lumafilter; static unsigned int automute = 1; static unsigned int chroma_agc; -static unsigned int adc_crush = 1; +static unsigned int agc_crush = 1; static unsigned int whitecrush_upper = 0xCF; static unsigned int whitecrush_lower = 0x7F; static unsigned int vcr_hack; @@ -126,7 +126,7 @@ module_param(combfilter, int, 0444); module_param(lumafilter, int, 0444); module_param(automute, int, 0444); module_param(chroma_agc, int, 0444); -module_param(adc_crush, int, 0444); +module_param(agc_crush, int, 0444); module_param(whitecrush_upper, int, 0444); module_param(whitecrush_lower, int, 0444); module_param(vcr_hack, int, 0444); @@ -139,27 +139,27 @@ module_param_array(video_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); -MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)"); -MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian"); -MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)"); -MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)"); -MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); -MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); +MODULE_PARM_DESC(radio, "The TV card supports radio, default is 0 (no)"); +MODULE_PARM_DESC(bigendian, "byte order of the framebuffer, default is native endian"); +MODULE_PARM_DESC(bttv_verbose, "verbose startup messages, default is 1 (yes)"); +MODULE_PARM_DESC(bttv_gpio, "log gpio changes, default is 0 (no)"); +MODULE_PARM_DESC(bttv_debug, "debug messages, default is 0 (no)"); +MODULE_PARM_DESC(irq_debug, "irq handler debug messages, default is 0 (no)"); MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); -MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); -MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); -MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " +MODULE_PARM_DESC(gbuffers, "number of capture buffers. range 2-32, default 8"); +MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 0x208000"); +MODULE_PARM_DESC(reset_crop, "reset cropping parameters at open(), default " "is 1 (yes) for compatibility with older applications"); -MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)"); -MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); -MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); -MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207"); -MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); -MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); -MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); -MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); -MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); -MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); +MODULE_PARM_DESC(automute, "mute audio on bad/missing video signal, default is 1 (yes)"); +MODULE_PARM_DESC(chroma_agc, "enables the AGC of chroma signal, default is 0 (no)"); +MODULE_PARM_DESC(agc_crush, "enables the luminance AGC crush, default is 1 (yes)"); +MODULE_PARM_DESC(whitecrush_upper, "sets the white crush upper value, default is 207"); +MODULE_PARM_DESC(whitecrush_lower, "sets the white crush lower value, default is 127"); +MODULE_PARM_DESC(vcr_hack, "enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); +MODULE_PARM_DESC(irq_iswitch, "switch inputs in irq handler"); +MODULE_PARM_DESC(uv_ratio, "ratio between u and v gains, default is 50"); +MODULE_PARM_DESC(full_luma_range, "use the full luma range, default is 0 (no)"); +MODULE_PARM_DESC(coring, "set the luma coring level, default is 0 (no)"); MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); MODULE_PARM_DESC(radio_nr, "radio device numbers"); @@ -169,6 +169,17 @@ MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); MODULE_LICENSE("GPL"); MODULE_VERSION(BTTV_VERSION); +#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_USER_BTTV_BASE + 0) +#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_USER_BTTV_BASE + 1) +#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_USER_BTTV_BASE + 2) +#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_USER_BTTV_BASE + 3) +#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_USER_BTTV_BASE + 4) +#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_USER_BTTV_BASE + 5) +#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_USER_BTTV_BASE + 6) +#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_USER_BTTV_BASE + 7) +#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_USER_BTTV_BASE + 8) +#define V4L2_CID_PRIVATE_CORING (V4L2_CID_USER_BTTV_BASE + 9) + /* ----------------------------------------------------------------------- */ /* sysfs */ @@ -622,198 +633,6 @@ static const struct bttv_format formats[] = { }; static const unsigned int FORMATS = ARRAY_SIZE(formats); -/* ----------------------------------------------------------------------- */ - -#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0) -#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4) -#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) -#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) -#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8) -#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9) -#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10) -#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11) - -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; -static const struct v4l2_queryctrl bttv_ctls[] = { - /* --- video --- */ - { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0, - .maximum = 65535, - .step = 256, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 65535, - .step = 128, - .default_value = 27648, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 65535, - .step = 128, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_COLOR_KILLER, - .name = "Color killer", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 65535, - .step = 256, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - /* --- audio --- */ - { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 65535, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_BALANCE, - .name = "Balance", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_BASS, - .name = "Bass", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_TREBLE, - .name = "Treble", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - /* --- private --- */ - { - .id = V4L2_CID_PRIVATE_CHROMA_AGC, - .name = "chroma agc", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_COMBFILTER, - .name = "combfilter", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_AUTOMUTE, - .name = "automute", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_LUMAFILTER, - .name = "luma decimation filter", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_AGC_CRUSH, - .name = "agc crush", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_VCR_HACK, - .name = "vcr hack", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, - .name = "whitecrush upper", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0xCF, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, - .name = "whitecrush lower", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0x7F, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_UV_RATIO, - .name = "uv ratio", - .minimum = 0, - .maximum = 100, - .step = 1, - .default_value = 50, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, - .name = "full luma range", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - },{ - .id = V4L2_CID_PRIVATE_CORING, - .name = "coring", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - } - - - -}; - -static const struct v4l2_queryctrl *ctrl_by_id(int id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++) - if (bttv_ctls[i].id == id) - return bttv_ctls+i; - - return NULL; -} - /* ----------------------------------------------------------------------- */ /* resource management */ @@ -1173,7 +992,7 @@ static int audio_mux(struct bttv *btv, int input, int mute) { int gpio_val, signal; - struct v4l2_control ctrl; + struct v4l2_ctrl *ctrl; gpio_inout(bttv_tvcards[btv->c.type].gpiomask, bttv_tvcards[btv->c.type].gpiomask); @@ -1183,7 +1002,8 @@ audio_mux(struct bttv *btv, int input, int mute) btv->audio = input; /* automute */ - mute = mute || (btv->opt_automute && !signal && !btv->radio_user); + mute = mute || (btv->opt_automute && (!signal || !btv->users) + && !btv->radio_user); if (mute) gpio_val = bttv_tvcards[btv->c.type].gpiomute; @@ -1205,12 +1025,13 @@ audio_mux(struct bttv *btv, int input, int mute) if (in_interrupt()) return 0; - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = btv->mute; - bttv_call_all(btv, core, s_ctrl, &ctrl); if (btv->sd_msp34xx) { u32 in; + ctrl = v4l2_ctrl_find(btv->sd_msp34xx->ctrl_handler, V4L2_CID_AUDIO_MUTE); + if (ctrl) + v4l2_ctrl_s_ctrl(ctrl, btv->mute); + /* Note: the inputs tuner/radio/extern/intern are translated to msp routings. This assumes common behavior for all msp3400 based TV cards. When this assumption fails, then the @@ -1255,9 +1076,19 @@ audio_mux(struct bttv *btv, int input, int mute) in, MSP_OUTPUT_DEFAULT, 0); } if (btv->sd_tvaudio) { + ctrl = v4l2_ctrl_find(btv->sd_tvaudio->ctrl_handler, V4L2_CID_AUDIO_MUTE); + + if (ctrl) + v4l2_ctrl_s_ctrl(ctrl, btv->mute); v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, input, 0, 0); } + if (btv->sd_tda7432) { + ctrl = v4l2_ctrl_find(btv->sd_tda7432->ctrl_handler, V4L2_CID_AUDIO_MUTE); + + if (ctrl) + v4l2_ctrl_s_ctrl(ctrl, btv->mute); + } return 0; } @@ -1395,8 +1226,6 @@ static void init_irqreg(struct bttv *btv) static void init_bt848(struct bttv *btv) { - int val; - if (bttv_tvcards[btv->c.type].no_video) { /* very basic init only */ init_irqreg(btv); @@ -1416,30 +1245,10 @@ static void init_bt848(struct bttv *btv) BT848_GPIO_DMA_CTL_GPINTI, BT848_GPIO_DMA_CTL); - val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; - btwrite(val, BT848_E_SCLOOP); - btwrite(val, BT848_O_SCLOOP); - btwrite(0x20, BT848_E_VSCALE_HI); btwrite(0x20, BT848_O_VSCALE_HI); - btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), - BT848_ADC); - btwrite(whitecrush_upper, BT848_WC_UP); - btwrite(whitecrush_lower, BT848_WC_DOWN); - - if (btv->opt_lumafilter) { - btwrite(0, BT848_E_CONTROL); - btwrite(0, BT848_O_CONTROL); - } else { - btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL); - btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL); - } - - bt848_bright(btv, btv->bright); - bt848_hue(btv, btv->hue); - bt848_contrast(btv, btv->contrast); - bt848_sat(btv, btv->saturation); + v4l2_ctrl_handler_setup(&btv->ctrl_handler); /* interrupt */ init_irqreg(btv); @@ -1461,103 +1270,26 @@ static void bttv_reinit_bt848(struct bttv *btv) set_input(btv, btv->input, btv->tvnorm); } -static int bttv_g_ctrl(struct file *file, void *priv, - struct v4l2_control *c) +static int bttv_s_ctrl(struct v4l2_ctrl *c) { - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - c->value = btv->bright; - break; - case V4L2_CID_HUE: - c->value = btv->hue; - break; - case V4L2_CID_CONTRAST: - c->value = btv->contrast; - break; - case V4L2_CID_SATURATION: - c->value = btv->saturation; - break; - case V4L2_CID_COLOR_KILLER: - c->value = btv->opt_color_killer; - break; - - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, g_ctrl, c); - break; - - case V4L2_CID_PRIVATE_CHROMA_AGC: - c->value = btv->opt_chroma_agc; - break; - case V4L2_CID_PRIVATE_COMBFILTER: - c->value = btv->opt_combfilter; - break; - case V4L2_CID_PRIVATE_LUMAFILTER: - c->value = btv->opt_lumafilter; - break; - case V4L2_CID_PRIVATE_AUTOMUTE: - c->value = btv->opt_automute; - break; - case V4L2_CID_PRIVATE_AGC_CRUSH: - c->value = btv->opt_adc_crush; - break; - case V4L2_CID_PRIVATE_VCR_HACK: - c->value = btv->opt_vcr_hack; - break; - case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: - c->value = btv->opt_whitecrush_upper; - break; - case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: - c->value = btv->opt_whitecrush_lower; - break; - case V4L2_CID_PRIVATE_UV_RATIO: - c->value = btv->opt_uv_ratio; - break; - case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: - c->value = btv->opt_full_luma_range; - break; - case V4L2_CID_PRIVATE_CORING: - c->value = btv->opt_coring; - break; - default: - return -EINVAL; - } - return 0; -} - -static int bttv_s_ctrl(struct file *file, void *f, - struct v4l2_control *c) -{ - int err; - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (0 != err) - return err; + struct bttv *btv = container_of(c->handler, struct bttv, ctrl_handler); + int val; switch (c->id) { case V4L2_CID_BRIGHTNESS: - bt848_bright(btv, c->value); + bt848_bright(btv, c->val); break; case V4L2_CID_HUE: - bt848_hue(btv, c->value); + bt848_hue(btv, c->val); break; case V4L2_CID_CONTRAST: - bt848_contrast(btv, c->value); + bt848_contrast(btv, c->val); break; case V4L2_CID_SATURATION: - bt848_sat(btv, c->value); + bt848_sat(btv, c->val); break; case V4L2_CID_COLOR_KILLER: - btv->opt_color_killer = c->value; - if (btv->opt_color_killer) { + if (c->val) { btor(BT848_SCLOOP_CKILL, BT848_E_SCLOOP); btor(BT848_SCLOOP_CKILL, BT848_O_SCLOOP); } else { @@ -1566,36 +1298,22 @@ static int bttv_s_ctrl(struct file *file, void *f, } break; case V4L2_CID_AUDIO_MUTE: - audio_mute(btv, c->value); - /* fall through */ - case V4L2_CID_AUDIO_VOLUME: - if (btv->volume_gpio) - btv->volume_gpio(btv, c->value); - - bttv_call_all(btv, core, s_ctrl, c); + audio_mute(btv, c->val); break; - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, s_ctrl, c); + case V4L2_CID_AUDIO_VOLUME: + btv->volume_gpio(btv, c->val); break; - case V4L2_CID_PRIVATE_CHROMA_AGC: - btv->opt_chroma_agc = c->value; - if (btv->opt_chroma_agc) { - btor(BT848_SCLOOP_CAGC, BT848_E_SCLOOP); - btor(BT848_SCLOOP_CAGC, BT848_O_SCLOOP); - } else { - btand(~BT848_SCLOOP_CAGC, BT848_E_SCLOOP); - btand(~BT848_SCLOOP_CAGC, BT848_O_SCLOOP); - } + case V4L2_CID_CHROMA_AGC: + val = c->val ? BT848_SCLOOP_CAGC : 0; + btwrite(val, BT848_E_SCLOOP); + btwrite(val, BT848_O_SCLOOP); break; case V4L2_CID_PRIVATE_COMBFILTER: - btv->opt_combfilter = c->value; + btv->opt_combfilter = c->val; break; case V4L2_CID_PRIVATE_LUMAFILTER: - btv->opt_lumafilter = c->value; - if (btv->opt_lumafilter) { + if (c->val) { btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL); btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL); } else { @@ -1604,36 +1322,31 @@ static int bttv_s_ctrl(struct file *file, void *f, } break; case V4L2_CID_PRIVATE_AUTOMUTE: - btv->opt_automute = c->value; + btv->opt_automute = c->val; break; case V4L2_CID_PRIVATE_AGC_CRUSH: - btv->opt_adc_crush = c->value; btwrite(BT848_ADC_RESERVED | - (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), + (c->val ? BT848_ADC_CRUSH : 0), BT848_ADC); break; case V4L2_CID_PRIVATE_VCR_HACK: - btv->opt_vcr_hack = c->value; + btv->opt_vcr_hack = c->val; break; case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: - btv->opt_whitecrush_upper = c->value; - btwrite(c->value, BT848_WC_UP); + btwrite(c->val, BT848_WC_UP); break; case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: - btv->opt_whitecrush_lower = c->value; - btwrite(c->value, BT848_WC_DOWN); + btwrite(c->val, BT848_WC_DOWN); break; case V4L2_CID_PRIVATE_UV_RATIO: - btv->opt_uv_ratio = c->value; + btv->opt_uv_ratio = c->val; bt848_sat(btv, btv->saturation); break; case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: - btv->opt_full_luma_range = c->value; - btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); + btaor((c->val << 7), ~BT848_OFORM_RANGE, BT848_OFORM); break; case V4L2_CID_PRIVATE_CORING: - btv->opt_coring = c->value; - btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); + btaor((c->val << 5), ~BT848_OFORM_CORE32, BT848_OFORM); break; default: return -EINVAL; @@ -1641,6 +1354,121 @@ static int bttv_s_ctrl(struct file *file, void *f, return 0; } +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_ctrl_ops bttv_ctrl_ops = { + .s_ctrl = bttv_s_ctrl, +}; + +static struct v4l2_ctrl_config bttv_ctrl_combfilter = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_COMBFILTER, + .name = "Comb Filter", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_automute = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_AUTOMUTE, + .name = "Auto Mute", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_lumafilter = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_LUMAFILTER, + .name = "Luma Decimation Filter", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_agc_crush = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_AGC_CRUSH, + .name = "AGC Crush", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_vcr_hack = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_VCR_HACK, + .name = "VCR Hack", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_whitecrush_lower = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, + .name = "Whitecrush Lower", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 255, + .step = 1, + .def = 0x7f, +}; + +static struct v4l2_ctrl_config bttv_ctrl_whitecrush_upper = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, + .name = "Whitecrush Upper", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 255, + .step = 1, + .def = 0xcf, +}; + +static struct v4l2_ctrl_config bttv_ctrl_uv_ratio = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_UV_RATIO, + .name = "UV Ratio", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 100, + .step = 1, + .def = 50, +}; + +static struct v4l2_ctrl_config bttv_ctrl_full_luma = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, + .name = "Full Luma Range", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, +}; + +static struct v4l2_ctrl_config bttv_ctrl_coring = { + .ops = &bttv_ctrl_ops, + .id = V4L2_CID_PRIVATE_CORING, + .name = "Coring", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 3, + .step = 1, +}; + + /* ----------------------------------------------------------------------- */ void bttv_gpio_tracking(struct bttv *btv, char *comment) @@ -2047,9 +1875,11 @@ static int bttv_s_frequency(struct file *file, void *priv, static int bttv_log_status(struct file *file, void *f) { + struct video_device *vdev = video_devdata(file); struct bttv_fh *fh = f; struct bttv *btv = fh->btv; + v4l2_ctrl_handler_log_status(vdev->ctrl_handler, btv->c.v4l2_dev.name); bttv_call_all(btv, core, log_status); return 0; } @@ -2939,30 +2769,6 @@ static int bttv_streamoff(struct file *file, void *priv, return 0; } -static int bttv_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - const struct v4l2_queryctrl *ctrl; - - if ((c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) && - (c->id < V4L2_CID_PRIVATE_BASE || - c->id >= V4L2_CID_PRIVATE_LASTP1)) - return -EINVAL; - - if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) - *c = no_ctl; - else { - ctrl = ctrl_by_id(c->id); - - *c = (NULL != ctrl) ? *ctrl : no_ctl; - } - - return 0; -} - static int bttv_g_parm(struct file *file, void *f, struct v4l2_streamparm *parm) { @@ -3263,6 +3069,7 @@ static int bttv_open(struct file *file) fh = kmalloc(sizeof(*fh), GFP_KERNEL); if (unlikely(!fh)) return -ENOMEM; + btv->users++; file->private_data = fh; *fh = btv->init; @@ -3287,7 +3094,6 @@ static int bttv_open(struct file *file) set_tvnorm(btv,btv->tvnorm); set_input(btv, btv->input, btv->tvnorm); - btv->users++; /* The V4L2 spec requires one global set of cropping parameters which only change on request. These are stored in btv->crop[1]. @@ -3349,7 +3155,7 @@ static int bttv_release(struct file *file) bttv_field_count(btv); if (!btv->users) - audio_mute(btv, 1); + audio_mute(btv, btv->mute); return 0; } @@ -3400,9 +3206,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_enum_input = bttv_enum_input, .vidioc_g_input = bttv_g_input, .vidioc_s_input = bttv_s_input, - .vidioc_queryctrl = bttv_queryctrl, - .vidioc_g_ctrl = bttv_g_ctrl, - .vidioc_s_ctrl = bttv_s_ctrl, .vidioc_streamon = bttv_streamon, .vidioc_streamoff = bttv_streamoff, .vidioc_g_tuner = bttv_g_tuner, @@ -3511,24 +3314,6 @@ static int radio_s_tuner(struct file *file, void *priv, return 0; } -static int radio_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - const struct v4l2_queryctrl *ctrl; - - if (c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) - return -EINVAL; - - if (c->id == V4L2_CID_AUDIO_MUTE) { - ctrl = ctrl_by_id(c->id); - *c = *ctrl; - } else - *c = no_ctl; - - return 0; -} - static ssize_t radio_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { @@ -3570,11 +3355,9 @@ static const struct v4l2_file_operations radio_fops = static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = bttv_querycap, + .vidioc_log_status = bttv_log_status, .vidioc_g_tuner = radio_g_tuner, .vidioc_s_tuner = radio_s_tuner, - .vidioc_queryctrl = radio_queryctrl, - .vidioc_g_ctrl = bttv_g_ctrl, - .vidioc_s_ctrl = bttv_s_ctrl, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, }; @@ -4220,6 +4003,7 @@ static int bttv_register_video(struct bttv *btv) btv->radio_dev = vdev_init(btv, &radio_template, "radio"); if (NULL == btv->radio_dev) goto err; + btv->radio_dev->ctrl_handler = &btv->radio_ctrl_handler; if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, radio_nr[btv->c.nr]) < 0) goto err; @@ -4258,6 +4042,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) int result; unsigned char lat; struct bttv *btv; + struct v4l2_ctrl_handler *hdl; if (bttv_num == BTTV_MAX) return -ENOMEM; @@ -4317,6 +4102,10 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) pr_warn("%d: v4l2_device_register() failed\n", btv->c.nr); goto fail0; } + hdl = &btv->ctrl_handler; + v4l2_ctrl_handler_init(hdl, 20); + btv->c.v4l2_dev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(&btv->radio_ctrl_handler, 6); btv->revision = dev->revision; pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); @@ -4353,16 +4142,19 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) /* init options from insmod args */ btv->opt_combfilter = combfilter; - btv->opt_lumafilter = lumafilter; + bttv_ctrl_combfilter.def = combfilter; + bttv_ctrl_lumafilter.def = lumafilter; btv->opt_automute = automute; - btv->opt_chroma_agc = chroma_agc; - btv->opt_adc_crush = adc_crush; + bttv_ctrl_automute.def = automute; + bttv_ctrl_agc_crush.def = agc_crush; btv->opt_vcr_hack = vcr_hack; - btv->opt_whitecrush_upper = whitecrush_upper; - btv->opt_whitecrush_lower = whitecrush_lower; + bttv_ctrl_vcr_hack.def = vcr_hack; + bttv_ctrl_whitecrush_upper.def = whitecrush_upper; + bttv_ctrl_whitecrush_lower.def = whitecrush_lower; btv->opt_uv_ratio = uv_ratio; - btv->opt_full_luma_range = full_luma_range; - btv->opt_coring = coring; + bttv_ctrl_uv_ratio.def = uv_ratio; + bttv_ctrl_full_luma.def = full_luma_range; + bttv_ctrl_coring.def = coring; /* fill struct bttv with some useful defaults */ btv->init.btv = btv; @@ -4373,6 +4165,34 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btv->init.height = 240; btv->input = 0; + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 0xff00, 0x100, 32768); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_CONTRAST, 0, 0xff80, 0x80, 0x6c00); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_SATURATION, 0, 0xff80, 0x80, 32768); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_COLOR_KILLER, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_HUE, 0, 0xff00, 0x100, 32768); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_CHROMA_AGC, 0, 1, 1, !!chroma_agc); + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); + if (btv->volume_gpio) + v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, + V4L2_CID_AUDIO_VOLUME, 0, 0xff00, 0x100, 0xff00); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_combfilter, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_automute, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_lumafilter, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_agc_crush, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_vcr_hack, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_lower, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_upper, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_uv_ratio, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_full_luma, NULL); + v4l2_ctrl_new_custom(hdl, &bttv_ctrl_coring, NULL); + /* initialize hardware */ if (bttv_gpio) bttv_gpio_tracking(btv,"pre-init"); @@ -4400,20 +4220,26 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btv->radio_freq = 90500 * 16; /* 90.5Mhz default */ } init_irqreg(btv); + v4l2_ctrl_handler_setup(hdl); + if (hdl->error) { + result = hdl->error; + goto fail2; + } /* register video4linux + input */ if (!bttv_tvcards[btv->c.type].no_video) { - bttv_register_video(btv); - bt848_bright(btv,32768); - bt848_contrast(btv, 27648); - bt848_hue(btv,32768); - bt848_sat(btv,32768); - audio_mute(btv, 1); + v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl, + v4l2_ctrl_radio_filter); + if (btv->radio_ctrl_handler.error) { + result = btv->radio_ctrl_handler.error; + goto fail2; + } set_input(btv, 0, btv->tvnorm); bttv_crop_reset(&btv->crop[0], btv->tvnorm); btv->crop[1] = btv->crop[0]; /* current = default */ disclaim_vbi_lines(btv); disclaim_video_lines(btv); + bttv_register_video(btv); } /* add subdevices and autoload dvb-bt8xx if needed */ @@ -4435,6 +4261,8 @@ fail2: free_irq(btv->c.pci->irq,btv); fail1: + v4l2_ctrl_handler_free(&btv->ctrl_handler); + v4l2_ctrl_handler_free(&btv->radio_ctrl_handler); v4l2_device_unregister(&btv->c.v4l2_dev); fail0: @@ -4476,9 +4304,11 @@ static void bttv_remove(struct pci_dev *pci_dev) bttv_unregister_video(btv); /* free allocated memory */ + v4l2_ctrl_handler_free(&btv->ctrl_handler); + v4l2_ctrl_handler_free(&btv->radio_ctrl_handler); btcx_riscmem_free(btv->c.pci,&btv->main); - /* free ressources */ + /* free resources */ free_irq(btv->c.pci->irq,btv); iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 528e03ec19e8..c3882ef3c529 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -33,9 +33,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include @@ -393,12 +394,17 @@ struct bttv { wait_queue_head_t i2c_queue; struct v4l2_subdev *sd_msp34xx; struct v4l2_subdev *sd_tvaudio; + struct v4l2_subdev *sd_tda7432; /* video4linux (1) */ struct video_device *video_dev; struct video_device *radio_dev; struct video_device *vbi_dev; + /* controls */ + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl_handler radio_ctrl_handler; + /* infrared remote */ int has_remote; struct bttv_ir *remote; @@ -426,17 +432,9 @@ struct bttv { /* various options */ int opt_combfilter; - int opt_lumafilter; int opt_automute; - int opt_chroma_agc; - int opt_color_killer; - int opt_adc_crush; int opt_vcr_hack; - int opt_whitecrush_upper; - int opt_whitecrush_lower; int opt_uv_ratio; - int opt_full_luma_range; - int opt_coring; /* radio data/state */ int has_radio; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index dcd63745e83a..1d00ca9f0ba3 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -146,6 +146,11 @@ enum v4l2_colorfx { * of controls. We reserve 16 controls for this driver. */ #define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000) +/* The base for the bttv driver controls. + * We reserve 32 controls for this driver. */ +#define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010) + + /* MPEG-class control IDs */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit From ae50f0f83efce31c8d485b5de131a4fd3f13e24b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:42:13 -0300 Subject: [media] bttv: add support for control events Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 48 +++++++++++++++++++++++++---------- drivers/media/pci/bt8xx/bttvp.h | 4 +++ 2 files changed, 39 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 8e0a44d03fc4..d34d271c6100 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -49,6 +49,7 @@ #include "bttvp.h" #include #include +#include #include #include #include @@ -2999,34 +3000,43 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) struct bttv_fh *fh = file->private_data; struct bttv_buffer *buf; enum v4l2_field field; - unsigned int rc = POLLERR; + unsigned int rc = 0; + unsigned long req_events = poll_requested_events(wait); + + if (v4l2_event_pending(&fh->fh)) + rc = POLLPRI; + else if (req_events & POLLPRI) + poll_wait(file, &fh->fh.wait, wait); + + if (!(req_events & (POLLIN | POLLRDNORM))) + return rc; if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) - return POLLERR; - return videobuf_poll_stream(file, &fh->vbi, wait); + return rc | POLLERR; + return rc | videobuf_poll_stream(file, &fh->vbi, wait); } if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { /* streaming capture */ if (list_empty(&fh->cap.stream)) - goto err; + return rc | POLLERR; buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); } else { /* read() capture */ if (NULL == fh->cap.read_buf) { /* need to capture a new frame */ if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) - goto err; + return rc | POLLERR; fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize); if (NULL == fh->cap.read_buf) - goto err; + return rc | POLLERR; fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(&fh->cap); if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { kfree (fh->cap.read_buf); fh->cap.read_buf = NULL; - goto err; + return rc | POLLERR; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; @@ -3037,10 +3047,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) poll_wait(file, &buf->vb.done, wait); if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) - rc = POLLIN|POLLRDNORM; - else - rc = 0; -err: + rc = rc | POLLIN|POLLRDNORM; return rc; } @@ -3073,6 +3080,7 @@ static int bttv_open(struct file *file) file->private_data = fh; *fh = btv->init; + v4l2_fh_init(&fh->fh, vdev); fh->type = type; fh->ov.setup_ok = 0; @@ -3112,6 +3120,7 @@ static int bttv_open(struct file *file) bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); bttv_field_count(btv); + v4l2_fh_add(&fh->fh); return 0; } @@ -3149,7 +3158,6 @@ static int bttv_release(struct file *file) videobuf_mmap_free(&fh->vbi); v4l2_prio_close(&btv->prio, fh->prio); file->private_data = NULL; - kfree(fh); btv->users--; bttv_field_count(btv); @@ -3157,6 +3165,9 @@ static int bttv_release(struct file *file) if (!btv->users) audio_mute(btv, btv->mute); + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); + kfree(fh); return 0; } @@ -3222,6 +3233,8 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_s_frequency = bttv_s_frequency, .vidioc_log_status = bttv_log_status, .vidioc_querystd = bttv_querystd, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_g_chip_ident = bttv_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = bttv_g_register, @@ -3334,10 +3347,17 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; + unsigned long req_events = poll_requested_events(wait); struct saa6588_command cmd; + unsigned int res = 0; + + if (v4l2_event_pending(&fh->fh)) + res = POLLPRI; + else if (req_events & POLLPRI) + poll_wait(file, &fh->fh.wait, wait); cmd.instance = file; cmd.event_list = wait; - cmd.result = -ENODEV; + cmd.result = res; bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); return cmd.result; @@ -3360,6 +3380,8 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_s_tuner = radio_s_tuner, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device radio_template = { diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index c3882ef3c529..288cfd8bb560 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -215,6 +216,9 @@ struct bttv_crop { }; struct bttv_fh { + /* This must be the first field in this struct */ + struct v4l2_fh fh; + struct bttv *btv; int resources; #ifdef VIDIOC_G_PRIORITY -- cgit From 8c14cc1f0ade4e16d4d3384791807abb4f367731 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:42:40 -0300 Subject: [media] bttv: fix priority handling Replace the - incorrect - manual priority handling with the core priority implementation. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 61 ++++------------------------------- drivers/media/pci/bt8xx/bttvp.h | 6 ---- 2 files changed, 6 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index d34d271c6100..41de79ba5930 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1706,11 +1706,7 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; unsigned int i; - int err; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (err) - goto err; + int err = 0; for (i = 0; i < BTTV_TVNORMS; i++) if (*id & bttv_tvnorms[i].v4l2_id) @@ -1793,11 +1789,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - int err; - - err = v4l2_prio_check(&btv->prio, fh->prio); - if (err) - return err; if (i >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; @@ -1811,15 +1802,10 @@ static int bttv_s_tuner(struct file *file, void *priv, { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - int err; if (t->index) return -EINVAL; - err = v4l2_prio_check(&btv->prio, fh->prio); - if (err) - return err; - bttv_call_all(btv, tuner, s_tuner, t); if (btv->audio_mode_gpio) @@ -1862,14 +1848,10 @@ static int bttv_s_frequency(struct file *file, void *priv, { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - int err; if (f->tuner) return -EINVAL; - err = v4l2_prio_check(&btv->prio, fh->prio); - if (err) - return err; bttv_set_frequency(btv, f); return 0; } @@ -2808,28 +2790,6 @@ static int bttv_g_tuner(struct file *file, void *priv, return 0; } -static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - *p = v4l2_prio_max(&btv->prio); - - return 0; -} - -static int bttv_s_priority(struct file *file, void *f, - enum v4l2_priority prio) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - int rc; - - rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); - - return rc; -} - static int bttv_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap) { @@ -2882,11 +2842,6 @@ static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop) /* Make sure tvnorm, vbi_end and the current cropping parameters remain consistent until we're done. Note read() may change vbi_end in check_alloc_btres_lock(). */ - retval = v4l2_prio_check(&btv->prio, fh->prio); - if (0 != retval) { - return retval; - } - retval = -EBUSY; if (locked_btres(fh->btv, VIDEO_RESOURCES)) { @@ -3085,8 +3040,6 @@ static int bttv_open(struct file *file) fh->type = type; fh->ov.setup_ok = 0; - v4l2_prio_open(&btv->prio, &fh->prio); - videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, &btv->c.pci->dev, &btv->s_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, @@ -3156,7 +3109,6 @@ static int bttv_release(struct file *file) videobuf_mmap_free(&fh->cap); videobuf_mmap_free(&fh->vbi); - v4l2_prio_close(&btv->prio, fh->prio); file->private_data = NULL; btv->users--; @@ -3226,8 +3178,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_g_fbuf = bttv_g_fbuf, .vidioc_s_fbuf = bttv_s_fbuf, .vidioc_overlay = bttv_overlay, - .vidioc_g_priority = bttv_g_priority, - .vidioc_s_priority = bttv_s_priority, .vidioc_g_parm = bttv_g_parm, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, @@ -3268,13 +3218,13 @@ static int radio_open(struct file *file) return -ENOMEM; file->private_data = fh; *fh = btv->init; - - v4l2_prio_open(&btv->prio, &fh->prio); + v4l2_fh_init(&fh->fh, vdev); btv->radio_user++; bttv_call_all(btv, tuner, s_radio); audio_input(btv,TVAUDIO_INPUT_RADIO); + v4l2_fh_add(&fh->fh); return 0; } @@ -3285,8 +3235,9 @@ static int radio_release(struct file *file) struct bttv *btv = fh->btv; struct saa6588_command cmd; - v4l2_prio_close(&btv->prio, fh->prio); file->private_data = NULL; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); btv->radio_user--; @@ -3948,6 +3899,7 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->v4l2_dev = &btv->c.v4l2_dev; vfd->release = video_device_release; vfd->debug = bttv_debug; + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); video_set_drvdata(vfd, btv); snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", @@ -4086,7 +4038,6 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) INIT_LIST_HEAD(&btv->c.subs); INIT_LIST_HEAD(&btv->capture); INIT_LIST_HEAD(&btv->vcapture); - v4l2_prio_init(&btv->prio); init_timer(&btv->timeout); btv->timeout.function = bttv_irq_timeout; diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 288cfd8bb560..12cc4ebdc00f 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -221,9 +221,6 @@ struct bttv_fh { struct bttv *btv; int resources; -#ifdef VIDIOC_G_PRIORITY - enum v4l2_priority prio; -#endif enum v4l2_buf_type type; /* video capture */ @@ -420,9 +417,6 @@ struct bttv { spinlock_t s_lock; struct mutex lock; int resources; -#ifdef VIDIOC_G_PRIORITY - struct v4l2_prio_state prio; -#endif /* video state */ unsigned int input; -- cgit From 6795cc55506606988175c16aa0e17d9f349706ca Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:43:07 -0300 Subject: [media] bttv: use centralized std and implement g_std The 'current_norm' field cannot be used if multiple device nodes (video and vbi in this case) set the same std. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 13 ++++++++++++- drivers/media/pci/bt8xx/bttvp.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 41de79ba5930..46ead7d65af1 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1716,6 +1716,7 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) goto err; } + btv->std = *id; set_tvnorm(btv, i); err: @@ -1723,6 +1724,15 @@ err: return err; } +static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct bttv_fh *fh = priv; + struct bttv *btv = fh->btv; + + *id = btv->std; + return 0; +} + static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) { struct bttv_fh *fh = f; @@ -3166,6 +3176,7 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_qbuf = bttv_qbuf, .vidioc_dqbuf = bttv_dqbuf, .vidioc_s_std = bttv_s_std, + .vidioc_g_std = bttv_g_std, .vidioc_enum_input = bttv_enum_input, .vidioc_g_input = bttv_g_input, .vidioc_s_input = bttv_s_input, @@ -3196,7 +3207,6 @@ static struct video_device bttv_video_template = { .fops = &bttv_fops, .ioctl_ops = &bttv_ioctl_ops, .tvnorms = BTTV_NORMS, - .current_norm = V4L2_STD_PAL, }; /* ----------------------------------------------------------------------- */ @@ -4192,6 +4202,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) bttv_set_frequency(btv, &init_freq); btv->radio_freq = 90500 * 16; /* 90.5Mhz default */ } + btv->std = V4L2_STD_PAL; init_irqreg(btv); v4l2_ctrl_handler_setup(hdl); diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 12cc4ebdc00f..86d67bb5adec 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -424,6 +424,7 @@ struct bttv { unsigned int mute; unsigned long tv_freq; unsigned int tvnorm; + v4l2_std_id std; int hue, contrast, bright, saturation; struct v4l2_framebuffer fbuf; unsigned int field_count; -- cgit From fafdc26b8558838988f406abef27d6dcc5b3dd76 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:43:37 -0300 Subject: [media] bttv: there may be multiple tvaudio/tda7432 devices Probe for additional tvaudio devices, and allow tvaudio+tda7432 to co-exist. My STB TV PCI FM bttv card has a tda7432, a tda9850 and a tea6420 and with this patch it finally works again (probably for the first time in many years). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-cards.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index 682ed893d718..fa0faaa2a49a 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -3547,6 +3547,16 @@ void bttv_init_card2(struct bttv *btv) if (btv->sd_msp34xx) return; + /* Now see if we can find one of the tvaudio devices. */ + btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, + &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); + if (btv->sd_tvaudio) { + /* There may be two tvaudio chips on the card, so try to + find another. */ + v4l2_i2c_new_subdev(&btv->c.v4l2_dev, + &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); + } + /* it might also be a tda7432. */ if (!bttv_tvcards[btv->c.type].no_tda7432) { static const unsigned short addrs[] = { @@ -3559,10 +3569,6 @@ void bttv_init_card2(struct bttv *btv) if (btv->sd_tda7432) return; } - - /* Now see if we can find one of the tvaudio devices. */ - btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev, - &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); if (btv->sd_tvaudio) return; -- cgit From 3d4b8035050dbca905ab55ecc0a0de16f9ef11bf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 12:44:07 -0300 Subject: [media] bttv: fix g_tuner capabilities override The capability field of v4l2_tuner should be ORed by the various subdevs and by the main driver. In this case the stereo capability was dropped. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvaudio.c | 2 +- drivers/media/pci/bt8xx/bttv-driver.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index e3b33b78dd21..4c91b355b55a 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -1803,7 +1803,7 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) vt->audmode = chip->audmode; vt->rxsubchans = desc->getrxsubchans(chip); - vt->capability = V4L2_TUNER_CAP_STEREO | + vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; return 0; diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 46ead7d65af1..0fdaef225c9e 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2787,9 +2787,9 @@ static int bttv_g_tuner(struct file *file, void *priv, return -EINVAL; t->rxsubchans = V4L2_TUNER_SUB_MONO; + t->capability = V4L2_TUNER_CAP_NORM; bttv_call_all(btv, tuner, g_tuner, t); strcpy(t->name, "Television"); - t->capability = V4L2_TUNER_CAP_NORM; t->type = V4L2_TUNER_ANALOG_TV; if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) t->signal = 0xffff; -- cgit From c13eb7039f612cc666764d6685a3764f4e6c8821 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 07:56:11 -0300 Subject: [media] bttv: fix try_fmt_vid_overlay and setup initial overlay size try_fmt_vid_overlay should map incorrect sizes and fields to valid values. It also expects that an initial overlay size is defined so g_fmt_vid_overlay returns valid information. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 44 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 0fdaef225c9e..b5100da854c0 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2111,22 +2111,33 @@ limit_scaled_size_lock (struct bttv_fh * fh, may also adjust the current cropping parameters to get closer to the desired window size. */ static int -verify_window_lock (struct bttv_fh * fh, - struct v4l2_window * win, - int adjust_size, - int adjust_crop) +verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win, + int adjust_size, int adjust_crop) { enum v4l2_field field; unsigned int width_mask; int rc; - if (win->w.width < 48 || win->w.height < 32) - return -EINVAL; + if (win->w.width < 48) + win->w.width = 48; + if (win->w.height < 32) + win->w.height = 32; if (win->clipcount > 2048) - return -EINVAL; + win->clipcount = 2048; + win->chromakey = 0; + win->global_alpha = 0; field = win->field; + switch (field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_INTERLACED: + break; + default: + field = V4L2_FIELD_ANY; + break; + } if (V4L2_FIELD_ANY == field) { __s32 height2; @@ -2135,18 +2146,11 @@ verify_window_lock (struct bttv_fh * fh, ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } + win->field = field; - /* 4-byte alignment. */ if (NULL == fh->ovfmt) return -EINVAL; + /* 4-byte alignment. */ width_mask = ~0; switch (fh->ovfmt->depth) { case 8: @@ -2171,8 +2175,6 @@ verify_window_lock (struct bttv_fh * fh, adjust_size, adjust_crop); if (0 != rc) return rc; - - win->field = field; return 0; } @@ -2407,9 +2409,10 @@ static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, { struct bttv_fh *fh = priv; - return verify_window_lock(fh, &f->fmt.win, + verify_window_lock(fh, &f->fmt.win, /* adjust_size */ 1, /* adjust_crop */ 0); + return 0; } static int bttv_s_fmt_vid_cap(struct file *file, void *priv, @@ -4146,6 +4149,9 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); btv->init.width = 320; btv->init.height = 240; + btv->init.ov.w.width = 320; + btv->init.ov.w.height = 240; + btv->init.ov.field = V4L2_FIELD_INTERLACED; btv->input = 0; v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, -- cgit From b8e2a361ce4247118fe81224b43137821cda50f7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Feb 2013 09:24:14 -0300 Subject: [media] bttv: do not switch to the radio tuner unless it is accessed Just opening the radio tuner should not cause a switch to the radio tuner. Only after calling g/s_tuner or g/s_frequency should this happen. This prevents audio being unmuted as soon as the driver is loaded because some process opens /dev/radioX just to see what sort of node it is, which switches on the radio tuner and unmutes audio. This code can be improved further by actually keeping track of who owns the tuner and returning -EBUSY if switching tuner modes will cause problems. But for now just fix the annoying case where on boot the radio turns on automatically. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 23 ++++++++++++++++++++--- drivers/media/pci/bt8xx/bttvp.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index b5100da854c0..265263a47a13 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1004,7 +1004,7 @@ audio_mux(struct bttv *btv, int input, int mute) /* automute */ mute = mute || (btv->opt_automute && (!signal || !btv->users) - && !btv->radio_user); + && !btv->has_radio_tuner); if (mute) gpio_val = bttv_tvcards[btv->c.type].gpiomute; @@ -1701,6 +1701,16 @@ static struct videobuf_queue_ops bttv_video_qops = { .buf_release = buffer_release, }; +static void radio_enable(struct bttv *btv) +{ + /* Switch to the radio tuner */ + if (!btv->has_radio_tuner) { + btv->has_radio_tuner = 1; + bttv_call_all(btv, tuner, s_radio); + audio_input(btv, TVAUDIO_INPUT_RADIO); + } +} + static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) { struct bttv_fh *fh = priv; @@ -1832,6 +1842,8 @@ static int bttv_g_frequency(struct file *file, void *priv, if (f->tuner) return -EINVAL; + if (f->type == V4L2_TUNER_RADIO) + radio_enable(btv); f->frequency = f->type == V4L2_TUNER_RADIO ? btv->radio_freq : btv->tv_freq; @@ -1845,6 +1857,7 @@ static void bttv_set_frequency(struct bttv *btv, struct v4l2_frequency *f) frequency before assigning radio/tv_freq. */ bttv_call_all(btv, tuner, g_frequency, f); if (f->type == V4L2_TUNER_RADIO) { + radio_enable(btv); btv->radio_freq = f->frequency; if (btv->has_matchbox) tea5757_set_freq(btv, btv->radio_freq); @@ -3235,8 +3248,6 @@ static int radio_open(struct file *file) btv->radio_user++; - bttv_call_all(btv, tuner, s_radio); - audio_input(btv,TVAUDIO_INPUT_RADIO); v4l2_fh_add(&fh->fh); return 0; @@ -3257,6 +3268,8 @@ static int radio_release(struct file *file) bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + if (btv->radio_user == 0) + btv->has_radio_tuner = 0; return 0; } @@ -3269,6 +3282,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return -EINVAL; strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; + radio_enable(btv); bttv_call_all(btv, tuner, g_tuner, t); @@ -3287,6 +3301,7 @@ static int radio_s_tuner(struct file *file, void *priv, if (0 != t->index) return -EINVAL; + radio_enable(btv); bttv_call_all(btv, tuner, s_tuner, t); return 0; } @@ -3301,6 +3316,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.buffer = data; cmd.instance = file; cmd.result = -ENODEV; + radio_enable(btv); bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); @@ -3319,6 +3335,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) res = POLLPRI; else if (req_events & POLLPRI) poll_wait(file, &fh->fh.wait, wait); + radio_enable(btv); cmd.instance = file; cmd.event_list = wait; cmd.result = res; diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 86d67bb5adec..eb13be7ae3f4 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -437,6 +437,7 @@ struct bttv { /* radio data/state */ int has_radio; + int has_radio_tuner; int radio_user; int radio_uses_msp_demodulator; unsigned long radio_freq; -- cgit From e74d7e6d349099574107869463a940d987152215 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:56:48 -0300 Subject: [media] bttv: remove g/s_audio since there is only one audio input Note that the current driver does not implement enumaudio (so apps cannot tell that audio inputs are present), it does not set V4L2_CAP_AUDIO, nor does it set audioset when calling ENUM_INPUT. And G_AUDIO doesn't set the stereo flag either. So these g/s_audio ioctls are quite pointless and misleading. Especially since some surveillance boards do not have audio at all. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 265263a47a13..8610b6a8b8fb 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2925,23 +2925,6 @@ static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop) return 0; } -static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - strcpy(a->name, "audio"); - return 0; -} - -static int bttv_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; - - return 0; -} - static ssize_t bttv_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { @@ -3184,8 +3167,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, - .vidioc_g_audio = bttv_g_audio, - .vidioc_s_audio = bttv_s_audio, .vidioc_cropcap = bttv_cropcap, .vidioc_reqbufs = bttv_reqbufs, .vidioc_querybuf = bttv_querybuf, -- cgit From 4bc837d414c36676499220065143743d720bf40f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2012 05:29:12 -0300 Subject: [media] cx231xx: add device_caps support to QUERYCAP This fixes a v4l2_compliance failure. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 06376d904c9f..ffeedcd2448b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1854,6 +1854,7 @@ static int vidioc_streamoff(struct file *file, void *priv, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + struct video_device *vdev = video_devdata(file); struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; @@ -1861,17 +1862,20 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VBI_CAPTURE | -#if 0 - V4L2_CAP_SLICED_VBI_CAPTURE | -#endif - V4L2_CAP_VIDEO_CAPTURE | + cap->device_caps = V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + if (vdev->vfl_type == VFL_TYPE_VBI) + cap->device_caps |= V4L2_CAP_VBI_CAPTURE; + else + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; if (dev->tuner_type != TUNER_ABSENT) - cap->capabilities |= V4L2_CAP_TUNER; + cap->device_caps |= V4L2_CAP_TUNER; + cap->capabilities = cap->device_caps | + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit From fddd14c8f6ca2bb9bfdad1874c172002bc537527 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2012 05:37:11 -0300 Subject: [media] cx231xx: add required VIDIOC_DBG_G_CHIP_IDENT support This fixes a v4l2_compliance failure. [mchehab@redhat.com: CodingStyle fixes] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index ffeedcd2448b..1b29158bbbe2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1456,6 +1456,19 @@ static int vidioc_s_frequency(struct file *file, void *priv, return rc; } +static int vidioc_g_chip_ident(struct file *file, void *fh, + struct v4l2_dbg_chip_ident *chip) +{ + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match.type == V4L2_CHIP_MATCH_HOST) { + if (v4l2_chip_match_host(&chip->match)) + chip->ident = V4L2_IDENT_CX23100; + return 0; + } + return -EINVAL; +} + #ifdef CONFIG_VIDEO_ADV_DEBUG /* @@ -2514,6 +2527,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, -- cgit From 530e01e782c97076c58b6e474d31cc61caa4a9dd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 12:32:20 -0300 Subject: [media] cx231xx: clean up radio support Radio should not use video or audio inputs. In addition, fix a bug in radio_g_tuner where s_tuner was called in the tuner subdev instead of g_tuner. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 79 +++++++------------------------ 1 file changed, 18 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 1b29158bbbe2..2cd31129de86 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1875,20 +1875,24 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->device_caps = - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - - if (vdev->vfl_type == VFL_TYPE_VBI) - cap->device_caps |= V4L2_CAP_VBI_CAPTURE; - else - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + if (vdev->vfl_type == VFL_TYPE_RADIO) + cap->device_caps = V4L2_CAP_RADIO; + else { + cap->device_caps = V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + if (vdev->vfl_type == VFL_TYPE_VBI) + cap->device_caps |= V4L2_CAP_VBI_CAPTURE; + else + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + } if (dev->tuner_type != TUNER_ABSENT) cap->device_caps |= V4L2_CAP_TUNER; cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_DEVICE_CAPS; + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; + if (dev->radio_dev) + cap->capabilities |= V4L2_CAP_RADIO; return 0; } @@ -2055,53 +2059,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) /* RADIO ESPECIFIC IOCTLS */ /* ----------------------------------------------------------- */ -static int radio_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; - - strlcpy(cap->driver, "cx231xx", sizeof(cap->driver)); - strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - - cap->capabilities = V4L2_CAP_TUNER; - return 0; -} - static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; - if (unlikely(t->index > 0)) + if (t->index) return -EINVAL; strcpy(t->name, "Radio"); - t->type = V4L2_TUNER_RADIO; - - call_all(dev, tuner, s_tuner, t); - - return 0; -} -static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i) -{ - if (i->index != 0) - return -EINVAL; - strcpy(i->name, "Radio"); - i->type = V4L2_INPUT_TYPE_TUNER; - - return 0; -} - -static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - if (unlikely(a->index)) - return -EINVAL; + call_all(dev, tuner, g_tuner, t); - strcpy(a->name, "Radio"); return 0; } - static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; @@ -2114,16 +2084,6 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return 0; } -static int radio_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) -{ - return 0; -} - -static int radio_s_input(struct file *file, void *fh, unsigned int i) -{ - return 0; -} - static int radio_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { @@ -2552,18 +2512,15 @@ static const struct v4l2_file_operations radio_fops = { }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = radio_querycap, + .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = radio_g_tuner, - .vidioc_enum_input = radio_enum_input, - .vidioc_g_audio = radio_g_audio, .vidioc_s_tuner = radio_s_tuner, - .vidioc_s_audio = radio_s_audio, - .vidioc_s_input = radio_s_input, .vidioc_queryctrl = radio_queryctrl, .vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, -- cgit From 06c46003f7077cce7f87a75d327635e45c6d2b64 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2012 06:17:47 -0300 Subject: [media] cx231xx: remove broken audio input support from the driver The audio selection code is broken. Audio and video indices were mixed up and s_audio would reject changing the audio input to something else anyway, so what's the point? All the audio input code has been removed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 52 +++++-------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 2cd31129de86..a31f7daef3dd 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1231,44 +1231,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - - switch (a->index) { - case CX231XX_AMUX_VIDEO: - strcpy(a->name, "Television"); - break; - case CX231XX_AMUX_LINE_IN: - strcpy(a->name, "Line In"); - break; - default: - return -EINVAL; - } - - a->index = dev->ctl_ainput; - a->capability = V4L2_AUDCAP_STEREO; - - return 0; -} - -static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int status = 0; - - /* Doesn't allow manual routing */ - if (a->index != dev->ctl_ainput) - return -EINVAL; - - dev->ctl_ainput = INPUT(a->index)->amux; - status = cx231xx_set_audio_input(dev, dev->ctl_ainput); - - return status; -} - static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { @@ -1878,8 +1840,7 @@ static int vidioc_querycap(struct file *file, void *priv, if (vdev->vfl_type == VFL_TYPE_RADIO) cap->device_caps = V4L2_CAP_RADIO; else { - cap->device_caps = V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; if (vdev->vfl_type == VFL_TYPE_VBI) cap->device_caps |= V4L2_CAP_VBI_CAPTURE; else @@ -1887,9 +1848,8 @@ static int vidioc_querycap(struct file *file, void *priv, } if (dev->tuner_type != TUNER_ABSENT) cap->device_caps |= V4L2_CAP_TUNER; - cap->capabilities = cap->device_caps | + cap->capabilities = cap->device_caps | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; if (dev->radio_dev) cap->capabilities |= V4L2_CAP_RADIO; @@ -2464,8 +2424,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, .vidioc_cropcap = vidioc_cropcap, .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, @@ -2554,6 +2512,12 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); video_set_drvdata(vfd, dev); + if (dev->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); + v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); + } return vfd; } -- cgit From b251f95767e1b13b9b32b207b53f5be1c491899e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2012 12:54:36 -0300 Subject: [media] cx231xx: fix tuner compliance issues The g_tuner call wasn't passed on to the subdevices, g_frequency didn't check for invalid tuners and a low-level function that was expected to return 0 or a negative error returned a positive number instead, causing s_frequency to return bogus errors. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 722207913740..4706ed350293 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2133,7 +2133,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval); - return status; + return status == sizeof(dwval) ? 0 : -EIO; } /****************************************************************************** diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index a31f7daef3dd..2b7b0944b7b4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1322,6 +1322,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) t->capability = V4L2_TUNER_CAP_NORM; t->rangehigh = 0xffffffffUL; t->signal = 0xffff; /* LOCKED */ + call_all(dev, tuner, g_tuner, t); return 0; } @@ -1350,6 +1351,9 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; + if (f->tuner) + return -EINVAL; + f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = dev->ctl_freq; -- cgit From 8b735c130717cb0af7793e30bbb6e91709ef10f8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Feb 2013 06:35:02 -0300 Subject: [media] cx231xx: zero priv field and use right width in try_fmt The priv field of v4l2_pix_format must be zeroed. Also fix a bug in try_fmt where the current width was used instead of the width passed to try_fmt. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 2b7b0944b7b4..9593fd3cdc85 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1005,6 +1005,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.priv = 0; return 0; } @@ -1045,10 +1046,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.width = width; f->fmt.pix.height = height; f->fmt.pix.pixelformat = fmt->fourcc; - f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; + f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.priv = 0; return 0; } -- cgit From 0752d98e1a5619553d46a67590cdd94ee5827ff3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Feb 2013 06:40:33 -0300 Subject: [media] cx231xx: fix frequency clamping Let the tuner clamp the frequency and store that clamped value. This fixes a v4l2_compliance failure. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 9593fd3cdc85..f3104f008f46 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1356,11 +1356,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, if (f->tuner) return -EINVAL; - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = dev->ctl_freq; - call_all(dev, tuner, g_frequency, f); - return 0; } @@ -1383,16 +1380,12 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (0 != f->tuner) return -EINVAL; - if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) - return -EINVAL; - if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) - return -EINVAL; - /* set pre channel change settings in DIF first */ rc = cx231xx_tuner_pre_channel_change(dev); - dev->ctl_freq = f->frequency; call_all(dev, tuner, s_frequency, f); + call_all(dev, tuner, g_frequency, f); + dev->ctl_freq = f->frequency; /* set post channel change settings in DIF first */ rc = cx231xx_tuner_post_channel_change(dev); -- cgit From 6264722c1212e5455bfdb58cca4377161cf97d23 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Feb 2013 06:41:11 -0300 Subject: [media] cx231xx: fix vbi compliance issues Various v4l2-compliance fixes: remove unused sliced VBI functions, zero the reserved fields of struct v4l2_vbi_format and implement the missing s_fmt_vbi_cap. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 67 ++++++++----------------------- 1 file changed, 17 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index f3104f008f46..5389825995e7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1868,47 +1868,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, return 0; } -/* Sliced VBI ioctls */ -static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - f->fmt.sliced.service_set = 0; - - call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); - - if (f->fmt.sliced.service_set == 0) - rc = -EINVAL; - - return rc; -} - -static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced); - - if (f->fmt.sliced.service_set == 0) - return -EINVAL; - - return 0; -} - /* RAW VBI ioctls */ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, @@ -1916,6 +1875,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; + f->fmt.vbi.sampling_rate = 6750000 * 4; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -1927,6 +1887,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; + memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); return 0; @@ -1938,12 +1899,6 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; - if (dev->vbi_stream_on && !fh->stream_on) { - cx231xx_errdev("%s device in use by another fh\n", __func__); - return -EBUSY; - } - - f->type = V4L2_BUF_TYPE_VBI_CAPTURE; f->fmt.vbi.sampling_rate = 6750000 * 4; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -1956,11 +1911,25 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263; f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; + memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); return 0; } +static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx231xx_fh *fh = priv; + struct cx231xx *dev = fh->dev; + + if (dev->vbi_stream_on && !fh->stream_on) { + cx231xx_errdev("%s device in use by another fh\n", __func__); + return -EBUSY; + } + return vidioc_try_fmt_vbi_cap(file, priv, f); +} + static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb) { @@ -2422,10 +2391,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, - .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, + .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, .vidioc_cropcap = vidioc_cropcap, - .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, - .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, -- cgit From d2370f8eee263a0a0260b9df9798f242d4cb13bf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2012 07:22:09 -0300 Subject: [media] cx231xx: convert to the control framework This is needed to resolve the v4l2-compliance complaints about the control ioctls. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-audio.c | 4 - drivers/media/usb/cx231xx/cx231xx-cards.c | 2 - drivers/media/usb/cx231xx/cx231xx-video.c | 244 +++--------------------------- drivers/media/usb/cx231xx/cx231xx.h | 13 +- 4 files changed, 27 insertions(+), 236 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index b4c99c7270cf..b40360b8e89e 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -449,9 +449,6 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) return -ENODEV; } - /* Sets volume, mute, etc */ - dev->mute = 0; - /* set alternate setting for audio interface */ /* 1 - 48000 samples per sec */ mutex_lock(&dev->lock); @@ -503,7 +500,6 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) return ret; } - dev->mute = 1; dev->adev.users--; mutex_unlock(&dev->lock); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 8d529565f163..d6acb1ebff33 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -846,8 +846,6 @@ void cx231xx_card_setup(struct cx231xx *dev) int cx231xx_config(struct cx231xx *dev) { /* TBD need to add cx231xx specific code */ - dev->mute = 1; /* maybe not the right place... */ - dev->volume = 0x1f; return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 5389825995e7..7be2e7349ef7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -100,125 +100,6 @@ static struct cx231xx_fmt format[] = { }, }; -/* supported controls */ -/* Common to all boards */ - -/* ------------------------------------------------------------------- */ - -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; - -static struct cx231xx_ctrl cx231xx_ctls[] = { - /* --- video --- */ - { - .v = { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = LUMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - .v = { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = LUMA_CTRL, - .mask = 0xff00, - .shift = 8, - }, { - .v = { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = CHROMA_CTRL, - .mask = 0xff0000, - .shift = 16, - }, { - /* strictly, this only describes only U saturation. - * V saturation is handled specially through code. - */ - .v = { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = CHROMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - /* --- audio --- */ - .v = { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .default_value = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, - .reg = PATH1_CTL1, - .mask = (0x1f << 24), - .shift = 24, - }, { - .v = { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 0x3f, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .reg = PATH1_VOL_CTL, - .mask = 0xff, - .shift = 0, - } -}; -static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls); - -static const u32 cx231xx_user_ctrls[] = { - V4L2_CID_USER_CLASS, - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_AUDIO_VOLUME, -#if 0 - V4L2_CID_AUDIO_BALANCE, -#endif - V4L2_CID_AUDIO_MUTE, - 0 -}; - -static const u32 *ctrl_classes[] = { - cx231xx_user_ctrls, - NULL -}; /* ------------------------------------------------------------------ Video buffer and parser functions @@ -1233,78 +1114,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int id = qc->id; - int i; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - qc->id = v4l2_ctrl_next(ctrl_classes, qc->id); - if (unlikely(qc->id == 0)) - return -EINVAL; - - memset(qc, 0, sizeof(*qc)); - - qc->id = id; - - if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1) - return -EINVAL; - - for (i = 0; i < CX231XX_CTLS; i++) - if (cx231xx_ctls[i].v.id == qc->id) - break; - - if (i == CX231XX_CTLS) { - *qc = no_ctl; - return 0; - } - *qc = cx231xx_ctls[i].v; - - call_all(dev, core, queryctrl, qc); - - if (qc->type) - return 0; - else - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - call_all(dev, core, g_ctrl, ctrl); - return rc; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - call_all(dev, core, s_ctrl, ctrl); - return rc; -} - static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx_fh *fh = priv; @@ -2012,26 +1821,6 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return 0; } -static int radio_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - int i; - - if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1) - return -EINVAL; - if (c->id == V4L2_CID_AUDIO_MUTE) { - for (i = 0; i < CX231XX_CTLS; i++) { - if (cx231xx_ctls[i].v.id == c->id) - break; - } - if (i == CX231XX_CTLS) - return -EINVAL; - *c = cx231xx_ctls[i].v; - } else - *c = no_ctl; - return 0; -} - /* * cx231xx_v4l2_open() * inits the device and starts isoc transfer @@ -2180,6 +1969,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) video_device_release(dev->vdev); dev->vdev = NULL; } + v4l2_ctrl_handler_free(&dev->ctrl_handler); + v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); } /* @@ -2402,9 +2193,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_g_tuner = vidioc_g_tuner, @@ -2439,9 +2227,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_s_tuner = radio_s_tuner, - .vidioc_queryctrl = radio_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_g_chip_ident = vidioc_g_chip_ident, @@ -2506,9 +2291,21 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* Set the initial input */ video_mux(dev, dev->video_input); - /* Audio defaults */ - dev->mute = 1; - dev->volume = 0x1f; + v4l2_ctrl_handler_init(&dev->ctrl_handler, 10); + v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 5); + + if (dev->sd_cx25840) { + v4l2_ctrl_add_handler(&dev->ctrl_handler, + dev->sd_cx25840->ctrl_handler, NULL); + v4l2_ctrl_add_handler(&dev->radio_ctrl_handler, + dev->sd_cx25840->ctrl_handler, + v4l2_ctrl_radio_filter); + } + + if (dev->ctrl_handler.error) + return dev->ctrl_handler.error; + if (dev->radio_ctrl_handler.error) + return dev->radio_ctrl_handler.error; /* enable vbi capturing */ /* write code here... */ @@ -2520,6 +2317,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) return -ENODEV; } + dev->vdev->ctrl_handler = &dev->ctrl_handler; /* register v4l2 video video_device */ ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); @@ -2539,6 +2337,11 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* Allocate and fill vbi video_device struct */ dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); + if (!dev->vbi_dev) { + cx231xx_errdev("cannot allocate video_device.\n"); + return -ENODEV; + } + dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; /* register v4l2 vbi video_device */ ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); @@ -2557,6 +2360,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) cx231xx_errdev("cannot allocate video_device.\n"); return -ENODEV; } + dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 3e11462be0d0..53408ce598d1 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -516,14 +517,6 @@ struct cx231xx_tvnorm { u32 cxoformat; }; -struct cx231xx_ctrl { - struct v4l2_queryctrl v; - u32 off; - u32 reg; - u32 mask; - u32 shift; -}; - enum TRANSFER_TYPE { Raw_Video = 0, Audio, @@ -631,6 +624,8 @@ struct cx231xx { struct v4l2_device v4l2_dev; struct v4l2_subdev *sd_cx25840; struct v4l2_subdev *sd_tuner; + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl_handler radio_ctrl_handler; struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ atomic_t stream_started; /* stream should be running if true */ @@ -653,8 +648,6 @@ struct cx231xx { v4l2_std_id norm; /* selected tv norm */ int ctl_freq; /* selected frequency */ unsigned int ctl_ainput; /* selected audio input */ - int mute; - int volume; /* frame properties */ int width; /* current frame width */ -- cgit From 1d08a4fa75ad165ed06c12b48477c39741ac68e4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2012 07:31:04 -0300 Subject: [media] cx231xx: add struct v4l2_fh to get prio and event support Required to resolve v4l2-compliance failures. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 31 ++++++++++++++++++++++++++----- drivers/media/usb/cx231xx/cx231xx.h | 2 ++ 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 7be2e7349ef7..26d2a4fe74f1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1871,6 +1872,7 @@ static int cx231xx_v4l2_open(struct file *filp) fh->radio = radio; fh->type = fh_type; filp->private_data = fh; + v4l2_fh_init(&fh->fh, vdev); if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { dev->width = norm_maxw(dev); @@ -1926,6 +1928,7 @@ static int cx231xx_v4l2_open(struct file *filp) fh, &dev->lock); } mutex_unlock(&dev->lock); + v4l2_fh_add(&fh->fh); return errCode; } @@ -2020,12 +2023,15 @@ static int cx231xx_close(struct file *filp) else cx231xx_set_alt_setting(dev, INDEX_HANC, 0); + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); dev->users--; wake_up_interruptible_nr(&dev->open, 1); return 0; } + v4l2_fh_del(&fh->fh); dev->users--; if (!dev->users) { videobuf_stop(&fh->vb_vidq); @@ -2052,6 +2058,7 @@ static int cx231xx_close(struct file *filp) /* set alternate 0 */ cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); } + v4l2_fh_exit(&fh->fh); kfree(fh); wake_up_interruptible_nr(&dev->open, 1); return 0; @@ -2108,29 +2115,37 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, */ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait) { + unsigned long req_events = poll_requested_events(wait); struct cx231xx_fh *fh = filp->private_data; struct cx231xx *dev = fh->dev; + unsigned res = 0; int rc; rc = check_dev(dev); if (rc < 0) - return rc; + return POLLERR; rc = res_get(fh); if (unlikely(rc < 0)) return POLLERR; + if (v4l2_event_pending(&fh->fh)) + res |= POLLPRI; + else + poll_wait(filp, &fh->fh.wait, wait); + + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; + if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { - unsigned int res; - mutex_lock(&dev->lock); - res = videobuf_poll_stream(filp, &fh->vb_vidq, wait); + res |= videobuf_poll_stream(filp, &fh->vb_vidq, wait); mutex_unlock(&dev->lock); return res; } - return POLLERR; + return res | POLLERR; } /* @@ -2204,6 +2219,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device cx231xx_vbi_template; @@ -2220,6 +2237,7 @@ static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = cx231xx_v4l2_open, .release = cx231xx_v4l2_close, + .poll = v4l2_ctrl_poll, .ioctl = video_ioctl2, }; @@ -2234,6 +2252,8 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device cx231xx_radio_template = { @@ -2259,6 +2279,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, vfd->release = video_device_release; vfd->debug = video_debug; vfd->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 53408ce598d1..4c83ff54a0ff 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -429,6 +430,7 @@ struct cx231xx_audio { struct cx231xx; struct cx231xx_fh { + struct v4l2_fh fh; struct cx231xx *dev; unsigned int stream_on:1; /* Locks streams */ int radio; -- cgit From a25a7012ba65ef41fba809c605c4f7d0dc609a23 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2012 08:30:07 -0300 Subject: [media] cx231xx: remove current_norm usage The use of this field is deprecated since it will not work when multiple device nodes reference the same video input (the video and vbi nodes in this case). The norm field should be a device-global value. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 1 - drivers/media/usb/cx231xx/cx231xx-video.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 28688dbcb609..a4091dd75620 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -2115,7 +2115,6 @@ static struct video_device cx231xx_mpeg_template = { .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, .tvnorms = CX231xx_NORMS, - .current_norm = V4L2_STD_NTSC_M, }; void cx231xx_417_unregister(struct cx231xx *dev) diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 26d2a4fe74f1..ae27c8287d21 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -2230,7 +2230,6 @@ static const struct video_device cx231xx_video_template = { .release = video_device_release, .ioctl_ops = &video_ioctl_ops, .tvnorms = V4L2_STD_ALL, - .current_norm = V4L2_STD_PAL, }; static const struct v4l2_file_operations radio_fops = { @@ -2301,7 +2300,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev->name, CX231XX_VERSION); /* set default norm */ - /*dev->norm = cx231xx_video_template.current_norm; */ + dev->norm = V4L2_STD_PAL; dev->width = norm_maxw(dev); dev->height = norm_maxh(dev); dev->interlaced = 0; -- cgit From 1265f080d8f04ffe074bdf948bbec4cb9c420ee0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 17 Sep 2012 09:26:46 -0300 Subject: [media] cx231xx: replace ioctl by unlocked_ioctl There was already a core lock, so why wasn't ioctl already replaced by unlock_ioctl? This patch switches to unlocked_ioctl. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 15 ++++++--------- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index a4091dd75620..15dd334a93d3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1633,12 +1633,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) dprintk(3, "enter vidioc_s_input() i=%d\n", i); - mutex_lock(&dev->lock); - video_mux(dev, i); - mutex_unlock(&dev->lock); - if (i >= 4) return -EINVAL; dev->input = i; @@ -1932,7 +1928,8 @@ static int mpeg_open(struct file *file) if (dev == NULL) return -ENODEV; - mutex_lock(&dev->lock); + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); @@ -1948,14 +1945,14 @@ static int mpeg_open(struct file *file) videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops, NULL, &dev->video_mode.slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, - sizeof(struct cx231xx_buffer), fh, NULL); + sizeof(struct cx231xx_buffer), fh, &dev->lock); /* videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops, &dev->udev->dev, &dev->ts1.slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct cx231xx_buffer), - fh, NULL); + fh, &dev->lock); */ @@ -2069,7 +2066,7 @@ static struct v4l2_file_operations mpeg_fops = { .read = mpeg_read, .poll = mpeg_poll, .mmap = mpeg_mmap, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { @@ -2144,11 +2141,11 @@ static struct video_device *cx231xx_video_dev_alloc( if (NULL == vfd) return NULL; *vfd = *template; - vfd->minor = -1; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx231xx_boards[dev->model].name); vfd->v4l2_dev = &dev->v4l2_dev; + vfd->lock = &dev->lock; vfd->release = video_device_release; return vfd; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index ae27c8287d21..8d4964052036 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -2237,7 +2237,7 @@ static const struct v4l2_file_operations radio_fops = { .open = cx231xx_v4l2_open, .release = cx231xx_v4l2_close, .poll = v4l2_ctrl_poll, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { -- cgit From 71590765b81bdc22562fb54e1def0f78d9be8909 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 28 Jan 2013 12:57:47 -0300 Subject: [media] cx231xx: get rid of a bunch of unused cx231xx_fh fields Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 6 +----- drivers/media/usb/cx231xx/cx231xx.h | 18 +----------------- 2 files changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 8d4964052036..b0cd699aeda6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1621,9 +1621,6 @@ static int vidioc_streamoff(struct file *file, void *priv, if (rc < 0) return rc; - if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; if (type != fh->type) return -EINVAL; @@ -1869,7 +1866,6 @@ static int cx231xx_v4l2_open(struct file *filp) return -ERESTARTSYS; } fh->dev = dev; - fh->radio = radio; fh->type = fh_type; filp->private_data = fh; v4l2_fh_init(&fh->fh, vdev); @@ -1900,7 +1896,7 @@ static int cx231xx_v4l2_open(struct file *filp) dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; } - if (fh->radio) { + if (radio) { cx231xx_videodbg("video_open: setting radio device\n"); /* cx231xx_start_radio(dev); */ diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 4c83ff54a0ff..c17889d64e59 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -433,25 +433,9 @@ struct cx231xx_fh { struct v4l2_fh fh; struct cx231xx *dev; unsigned int stream_on:1; /* Locks streams */ - int radio; - - struct videobuf_queue vb_vidq; - enum v4l2_buf_type type; - - -/*following is copyed from cx23885.h*/ - u32 resources; - - /* video overlay */ - struct v4l2_window win; - struct v4l2_clip *clips; - unsigned int nclips; - - /* video capture */ - struct cx23417_fmt *fmt; - unsigned int width, height; + struct videobuf_queue vb_vidq; /* vbi capture */ struct videobuf_queue vidq; -- cgit From d61072a4975d0be5f0a858fba8d0304800b43fbf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 10:50:54 -0300 Subject: [media] cx231xx: improve std handling Set the initial standard of subdevices instead of leaving it undefined. Also update the width and height when a new standard is chosen and return -EBUSY when attempting to change the standard while videobuf is busy. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index b0cd699aeda6..b6cde46131c7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -992,34 +992,34 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; struct v4l2_mbus_framefmt mbus_fmt; - struct v4l2_format f; int rc; rc = check_dev(dev); if (rc < 0) return rc; - cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm); + if (dev->norm == *norm) + return 0; + + if (videobuf_queue_is_busy(&fh->vb_vidq)) + return -EBUSY; dev->norm = *norm; /* Adjusts width/height, if needed */ - f.fmt.pix.width = dev->width; - f.fmt.pix.height = dev->height; - vidioc_try_fmt_vid_cap(file, priv, &f); + dev->width = 720; + dev->height = (dev->norm & V4L2_STD_625_50) ? 576 : 480; call_all(dev, core, s_std, dev->norm); /* We need to reset basic properties in the decoder related to resolution (since a standard change effects things like the number of lines in VACT, etc) */ - v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED); + memset(&mbus_fmt, 0, sizeof(mbus_fmt)); + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.width = dev->width; + mbus_fmt.height = dev->height; call_all(dev, video, s_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt); - - /* set new image size */ - dev->width = f.fmt.pix.width; - dev->height = f.fmt.pix.height; /* do mode control overrides */ cx231xx_do_mode_ctrl_overrides(dev); @@ -2307,6 +2307,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* Set the initial input */ video_mux(dev, dev->video_input); + call_all(dev, core, s_std, dev->norm); + v4l2_ctrl_handler_init(&dev->ctrl_handler, 10); v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 5); -- cgit From 3f926e326d3c02b73898b7692f2b2306c521e2d3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 12:50:18 -0300 Subject: [media] cx231xx-417: remove empty functions Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 68 +-------------------------------- 1 file changed, 1 insertion(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 15dd334a93d3..ac15a55fe5d0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1551,33 +1551,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) dprintk(3, "exit vidioc_s_std() i=0x%x\n", i); return 0; } -static int vidioc_g_audio(struct file *file, void *fh, - struct v4l2_audio *a) -{ - struct v4l2_audio *vin = a; - - int ret = -EINVAL; - if (vin->index > 0) - return ret; - strncpy(vin->name, "VideoGrabber Audio", 14); - vin->capability = V4L2_AUDCAP_STEREO; -return 0; -} -static int vidioc_enumaudio(struct file *file, void *fh, - struct v4l2_audio *a) -{ - struct v4l2_audio *vin = a; - - int ret = -EINVAL; - - if (vin->index > 0) - return ret; - strncpy(vin->name, "VideoGrabber Audio", 14); - vin->capability = V4L2_AUDCAP_STEREO; - - -return 0; -} static const char *iname[] = { [CX231XX_VMUX_COMPOSITE1] = "Composite1", [CX231XX_VMUX_SVIDEO] = "S-Video", @@ -1642,32 +1615,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - - - return 0; -} - static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) { @@ -1748,13 +1695,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - - return 0; -} - static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { @@ -2073,20 +2013,14 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, .vidioc_enum_input = vidioc_enum_input, - .vidioc_enumaudio = vidioc_enumaudio, - .vidioc_g_audio = vidioc_g_audio, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, -- cgit From bc08734c825b710ffab93f79ca1ca2d0265dd321 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 12:52:33 -0300 Subject: [media] cx231xx-417: use one querycap for all device nodes Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 20 +------------------- drivers/media/usb/cx231xx/cx231xx-video.c | 6 +++--- drivers/media/usb/cx231xx/cx231xx.h | 2 ++ 3 files changed, 6 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index ac15a55fe5d0..be8f7481d7f2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1626,24 +1626,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, dprintk(3, "exit vidioc_s_ctrl()\n"); return 0; } -static struct v4l2_capability pvr_capability = { - .driver = "cx231xx", - .card = "VideoGrabber", - .bus_info = "usb", - .version = 1, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), -}; -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - - - - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); - return 0; -} static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) @@ -2016,7 +1998,7 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_querycap = vidioc_querycap, + .vidioc_querycap = cx231xx_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index b6cde46131c7..c199eae6bd3e 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1632,7 +1632,7 @@ static int vidioc_streamoff(struct file *file, void *priv, return 0; } -static int vidioc_querycap(struct file *file, void *priv, +int cx231xx_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); @@ -2186,7 +2186,7 @@ static const struct v4l2_file_operations cx231xx_v4l_fops = { }; static const struct v4l2_ioctl_ops video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, + .vidioc_querycap = cx231xx_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, @@ -2237,7 +2237,7 @@ static const struct v4l2_file_operations radio_fops = { }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, + .vidioc_querycap = cx231xx_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_s_tuner = radio_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index c17889d64e59..efc0d1cafd5d 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -934,6 +934,8 @@ int cx231xx_register_extension(struct cx231xx_ops *dev); void cx231xx_unregister_extension(struct cx231xx_ops *dev); void cx231xx_init_extension(struct cx231xx *dev); void cx231xx_close_extension(struct cx231xx *dev); +int cx231xx_querycap(struct file *file, void *priv, + struct v4l2_capability *cap); /* Provided by cx231xx-cards.c */ extern void cx231xx_pre_card_setup(struct cx231xx *dev); -- cgit From 5aa95991d7ff15ca965ef5abe91f90afeb262afd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 13:02:15 -0300 Subject: [media] cx231xx-417: fix g/try_fmt compliance problems Colorspace, field and priv were not set, and sizeimage was calculated using the wrong values (dev->ts1.ts_packet_size and dev->ts1.ts_packet_count can be 0 at module load). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index be8f7481d7f2..cbdc141fe9b2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1223,6 +1223,7 @@ static int bb_buf_setup(struct videobuf_queue *q, return 0; } + static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) { struct cx231xx_fh *fh = vq->priv_data; @@ -1645,17 +1646,18 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, { struct cx231xx_fh *fh = file->private_data; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_g_fmt_vid_cap()\n"); - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = dev->ts1.width; - f->fmt.pix.height = dev->ts1.height; - f->fmt.pix.field = fh->vidq.field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->vidq.field); + f->fmt.pix.sizeimage = mpeglines * mpeglinesize; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.width = dev->ts1.width; + f->fmt.pix.height = dev->ts1.height; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.priv = 0; + dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n", + dev->ts1.width, dev->ts1.height); dprintk(3, "exit vidioc_g_fmt_vid_cap()\n"); return 0; } @@ -1665,14 +1667,16 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { struct cx231xx_fh *fh = file->private_data; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_try_fmt_vid_cap()\n"); - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->vidq.field); + f->fmt.pix.sizeimage = mpeglines * mpeglinesize; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; + dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n", + dev->ts1.width, dev->ts1.height); dprintk(3, "exit vidioc_try_fmt_vid_cap()\n"); return 0; } -- cgit From 5b8acdc5e6d9ea73572478b59b6d3390b044f45a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 12:59:50 -0300 Subject: [media] cx231xx-417: checkpatch cleanups Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 732 ++++++++++++++++---------------- 1 file changed, 360 insertions(+), 372 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index cbdc141fe9b2..2c05c8f41527 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -38,7 +38,6 @@ #include #include "cx231xx.h" -/*#include "cx23885-ioctl.h"*/ #define CX231xx_FIRM_IMAGE_SIZE 376836 #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -75,9 +74,11 @@ static unsigned int mpegbufs = 8; module_param(mpegbufs, int, 0644); MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); + static unsigned int mpeglines = 128; module_param(mpeglines, int, 0644); MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); + static unsigned int mpeglinesize = 512; module_param(mpeglinesize, int, 0644); MODULE_PARM_DESC(mpeglinesize, @@ -86,10 +87,10 @@ MODULE_PARM_DESC(mpeglinesize, static unsigned int v4l_debug = 1; module_param(v4l_debug, int, 0644); MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); -struct cx231xx_dmaqueue *dma_qq; + #define dprintk(level, fmt, arg...)\ do { if (v4l_debug >= level) \ - printk(KERN_INFO "%s: " fmt, \ + pr_info("%s: " fmt, \ (dev) ? dev->name : "cx231xx[?]", ## arg); \ } while (0) @@ -131,11 +132,13 @@ static struct cx231xx_tvnorm cx231xx_tvnorms[] = { }; /* ------------------------------------------------------------------ */ + enum cx231xx_capture_type { CX231xx_MPEG_CAPTURE, CX231xx_RAW_CAPTURE, CX231xx_RAW_PASSTHRU_CAPTURE }; + enum cx231xx_capture_bits { CX231xx_RAW_BITS_NONE = 0x00, CX231xx_RAW_BITS_YUV_CAPTURE = 0x01, @@ -144,33 +147,40 @@ enum cx231xx_capture_bits { CX231xx_RAW_BITS_PASSTHRU_CAPTURE = 0x08, CX231xx_RAW_BITS_TO_HOST_CAPTURE = 0x10 }; + enum cx231xx_capture_end { CX231xx_END_AT_GOP, /* stop at the end of gop, generate irq */ CX231xx_END_NOW, /* stop immediately, no irq */ }; + enum cx231xx_framerate { CX231xx_FRAMERATE_NTSC_30, /* NTSC: 30fps */ CX231xx_FRAMERATE_PAL_25 /* PAL: 25fps */ }; + enum cx231xx_stream_port { CX231xx_OUTPUT_PORT_MEMORY, CX231xx_OUTPUT_PORT_STREAMING, CX231xx_OUTPUT_PORT_SERIAL }; + enum cx231xx_data_xfer_status { CX231xx_MORE_BUFFERS_FOLLOW, CX231xx_LAST_BUFFER, }; + enum cx231xx_picture_mask { CX231xx_PICTURE_MASK_NONE, CX231xx_PICTURE_MASK_I_FRAMES, CX231xx_PICTURE_MASK_I_P_FRAMES = 0x3, CX231xx_PICTURE_MASK_ALL_FRAMES = 0x7, }; + enum cx231xx_vbi_mode_bits { CX231xx_VBI_BITS_SLICED, CX231xx_VBI_BITS_RAW, }; + enum cx231xx_vbi_insertion_bits { CX231xx_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, CX231xx_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, @@ -178,56 +188,69 @@ enum cx231xx_vbi_insertion_bits { CX231xx_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, CX231xx_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, }; + enum cx231xx_dma_unit { CX231xx_DMA_BYTES, CX231xx_DMA_FRAMES, }; + enum cx231xx_dma_transfer_status_bits { CX231xx_DMA_TRANSFER_BITS_DONE = 0x01, CX231xx_DMA_TRANSFER_BITS_ERROR = 0x04, CX231xx_DMA_TRANSFER_BITS_LL_ERROR = 0x10, }; + enum cx231xx_pause { CX231xx_PAUSE_ENCODING, CX231xx_RESUME_ENCODING, }; + enum cx231xx_copyright { CX231xx_COPYRIGHT_OFF, CX231xx_COPYRIGHT_ON, }; + enum cx231xx_notification_type { CX231xx_NOTIFICATION_REFRESH, }; + enum cx231xx_notification_status { CX231xx_NOTIFICATION_OFF, CX231xx_NOTIFICATION_ON, }; + enum cx231xx_notification_mailbox { CX231xx_NOTIFICATION_NO_MAILBOX = -1, }; + enum cx231xx_field1_lines { CX231xx_FIELD1_SAA7114 = 0x00EF, /* 239 */ CX231xx_FIELD1_SAA7115 = 0x00F0, /* 240 */ CX231xx_FIELD1_MICRONAS = 0x0105, /* 261 */ }; + enum cx231xx_field2_lines { CX231xx_FIELD2_SAA7114 = 0x00EF, /* 239 */ CX231xx_FIELD2_SAA7115 = 0x00F0, /* 240 */ CX231xx_FIELD2_MICRONAS = 0x0106, /* 262 */ }; + enum cx231xx_custom_data_type { CX231xx_CUSTOM_EXTENSION_USR_DATA, CX231xx_CUSTOM_PRIVATE_PACKET, }; + enum cx231xx_mute { CX231xx_UNMUTE, CX231xx_MUTE, }; + enum cx231xx_mute_video_mask { CX231xx_MUTE_VIDEO_V_MASK = 0x0000FF00, CX231xx_MUTE_VIDEO_U_MASK = 0x00FF0000, CX231xx_MUTE_VIDEO_Y_MASK = 0xFF000000, }; + enum cx231xx_mute_video_shift { CX231xx_MUTE_VIDEO_V_SHIFT = 8, CX231xx_MUTE_VIDEO_U_SHIFT = 16, @@ -296,41 +319,43 @@ enum cx231xx_mute_video_shift { #define CX23417_GPIO_MASK 0xFC0003FF -static int setITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 value) + +static int set_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 value) { int status = 0; u32 _gpio_direction = 0; _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; - _gpio_direction = _gpio_direction|gpio_direction; + _gpio_direction = _gpio_direction | gpio_direction; status = cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); return status; } -static int getITVCReg(struct cx231xx *dev, u32 gpio_direction, u32 *pValue) + +static int get_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 *val_ptr) { int status = 0; u32 _gpio_direction = 0; _gpio_direction = _gpio_direction & CX23417_GPIO_MASK; - _gpio_direction = _gpio_direction|gpio_direction; + _gpio_direction = _gpio_direction | gpio_direction; status = cx231xx_send_gpio_cmd(dev, _gpio_direction, - (u8 *)pValue, 4, 0, 1); + (u8 *)val_ptr, 4, 0, 1); return status; } -static int waitForMciComplete(struct cx231xx *dev) +static int wait_for_mci_complete(struct cx231xx *dev) { u32 gpio; - u32 gpio_driection = 0; + u32 gpio_direction = 0; u8 count = 0; - getITVCReg(dev, gpio_driection, &gpio); + get_itvc_reg(dev, gpio_direction, &gpio); while (!(gpio&0x020000)) { msleep(10); - getITVCReg(dev, gpio_driection, &gpio); + get_itvc_reg(dev, gpio_direction, &gpio); if (count++ > 100) { dprintk(3, "ERROR: Timeout - gpio=%x\n", gpio); @@ -345,57 +370,57 @@ static int mc417_register_write(struct cx231xx *dev, u16 address, u32 value) u32 temp; int status = 0; - temp = 0x82|MCI_REGISTER_DATA_BYTE0|((value&0x000000FF)<<8); - temp = temp<<10; - status = setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_DATA_BYTE0 | ((value & 0x000000FF) << 8); + temp = temp << 10; + status = set_itvc_reg(dev, ITVC_WRITE_DIR, temp); if (status < 0) return status; - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 1;*/ - temp = 0x82|MCI_REGISTER_DATA_BYTE1|(value&0x0000FF00); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_DATA_BYTE1 | (value & 0x0000FF00); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 2;*/ - temp = 0x82|MCI_REGISTER_DATA_BYTE2|((value&0x00FF0000)>>8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 3;*/ - temp = 0x82|MCI_REGISTER_DATA_BYTE3|((value&0xFF000000)>>16); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_DATA_BYTE3 | ((value & 0xFF000000) >> 16); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write address byte 0;*/ - temp = 0x82|MCI_REGISTER_ADDRESS_BYTE0|((address&0x000000FF)<<8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x000000FF) << 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write address byte 1;*/ - temp = 0x82|MCI_REGISTER_ADDRESS_BYTE1|(address&0x0000FF00); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0x0000FF00); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*Write that the mode is write.*/ temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_WRITE; - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); - return waitForMciComplete(dev); + return wait_for_mci_complete(dev); } static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value) @@ -407,70 +432,68 @@ static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value) temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); temp = temp << 10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); temp = temp | ((0x05) << 10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write address byte 1;*/ temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0xFF00); temp = temp << 10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); temp = temp | ((0x05) << 10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write that the mode is read;*/ temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_READ; temp = temp << 10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); temp = temp | ((0x05) << 10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*wait for the MIRDY line to be asserted , signalling that the read is done;*/ - ret = waitForMciComplete(dev); + ret = wait_for_mci_complete(dev); /*switch the DATA- GPIO to input mode;*/ /*Read data byte 0;*/ temp = (0x82 | MCI_REGISTER_DATA_BYTE0) << 10; - setITVCReg(dev, ITVC_READ_DIR, temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); temp = ((0x81 | MCI_REGISTER_DATA_BYTE0) << 10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); return_value |= ((temp & 0x03FC0000) >> 18); - setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /* Read data byte 1;*/ temp = (0x82 | MCI_REGISTER_DATA_BYTE1) << 10; - setITVCReg(dev, ITVC_READ_DIR, temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); temp = ((0x81 | MCI_REGISTER_DATA_BYTE1) << 10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); return_value |= ((temp & 0x03FC0000) >> 10); - setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /*Read data byte 2;*/ temp = (0x82 | MCI_REGISTER_DATA_BYTE2) << 10; - setITVCReg(dev, ITVC_READ_DIR, temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); temp = ((0x81 | MCI_REGISTER_DATA_BYTE2) << 10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); return_value |= ((temp & 0x03FC0000) >> 2); - setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /*Read data byte 3;*/ temp = (0x82 | MCI_REGISTER_DATA_BYTE3) << 10; - setITVCReg(dev, ITVC_READ_DIR, temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); temp = ((0x81 | MCI_REGISTER_DATA_BYTE3) << 10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); return_value |= ((temp & 0x03FC0000) << 6); - setITVCReg(dev, ITVC_READ_DIR, (0x87 << 10)); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); *value = return_value; - - return ret; } @@ -481,59 +504,59 @@ static int mc417_memory_write(struct cx231xx *dev, u32 address, u32 value) u32 temp; int ret = 0; - temp = 0x82 | MCI_MEMORY_DATA_BYTE0|((value & 0x000000FF) << 8); + temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8); temp = temp << 10; - ret = setITVCReg(dev, ITVC_WRITE_DIR, temp); + ret = set_itvc_reg(dev, ITVC_WRITE_DIR, temp); if (ret < 0) return ret; - temp = temp | ((0x05) << 10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 1;*/ temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00); temp = temp << 10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp | ((0x05) << 10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 2;*/ - temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write data byte 3;*/ - temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /* write address byte 2;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | - ((address & 0x003F0000)>>8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | + ((address & 0x003F0000) >> 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /* write address byte 1;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /* write address byte 0;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*wait for MIRDY line;*/ - waitForMciComplete(dev); + wait_for_mci_complete(dev); return 0; } @@ -545,68 +568,68 @@ static int mc417_memory_read(struct cx231xx *dev, u32 address, u32 *value) int ret = 0; /*write address byte 2;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ | - ((address & 0x003F0000)>>8); - temp = temp<<10; - ret = setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ | + ((address & 0x003F0000) >> 8); + temp = temp << 10; + ret = set_itvc_reg(dev, ITVC_WRITE_DIR, temp); if (ret < 0) return ret; - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write address byte 1*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*write address byte 0*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF)<<8); - temp = temp<<10; - setITVCReg(dev, ITVC_WRITE_DIR, temp); - temp = temp|((0x05)<<10); - setITVCReg(dev, ITVC_WRITE_DIR, temp); + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); + temp = temp << 10; + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); + temp = temp | (0x05 << 10); + set_itvc_reg(dev, ITVC_WRITE_DIR, temp); /*Wait for MIRDY line*/ - ret = waitForMciComplete(dev); + ret = wait_for_mci_complete(dev); /*Read data byte 3;*/ - temp = (0x82|MCI_MEMORY_DATA_BYTE3)<<10; - setITVCReg(dev, ITVC_READ_DIR, temp); - temp = ((0x81|MCI_MEMORY_DATA_BYTE3)<<10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); - return_value |= ((temp&0x03FC0000)<<6); - setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); + temp = (0x82 | MCI_MEMORY_DATA_BYTE3) << 10; + set_itvc_reg(dev, ITVC_READ_DIR, temp); + temp = ((0x81 | MCI_MEMORY_DATA_BYTE3) << 10); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); + return_value |= ((temp & 0x03FC0000) << 6); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /*Read data byte 2;*/ - temp = (0x82|MCI_MEMORY_DATA_BYTE2)<<10; - setITVCReg(dev, ITVC_READ_DIR, temp); - temp = ((0x81|MCI_MEMORY_DATA_BYTE2)<<10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); - return_value |= ((temp&0x03FC0000)>>2); - setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); + temp = (0x82 | MCI_MEMORY_DATA_BYTE2) << 10; + set_itvc_reg(dev, ITVC_READ_DIR, temp); + temp = ((0x81 | MCI_MEMORY_DATA_BYTE2) << 10); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); + return_value |= ((temp & 0x03FC0000) >> 2); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /* Read data byte 1;*/ - temp = (0x82|MCI_MEMORY_DATA_BYTE1)<<10; - setITVCReg(dev, ITVC_READ_DIR, temp); - temp = ((0x81|MCI_MEMORY_DATA_BYTE1)<<10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); - return_value |= ((temp&0x03FC0000)>>10); - setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); + temp = (0x82 | MCI_MEMORY_DATA_BYTE1) << 10; + set_itvc_reg(dev, ITVC_READ_DIR, temp); + temp = ((0x81 | MCI_MEMORY_DATA_BYTE1) << 10); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); + return_value |= ((temp & 0x03FC0000) >> 10); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); /*Read data byte 0;*/ - temp = (0x82|MCI_MEMORY_DATA_BYTE0)<<10; - setITVCReg(dev, ITVC_READ_DIR, temp); - temp = ((0x81|MCI_MEMORY_DATA_BYTE0)<<10); - setITVCReg(dev, ITVC_READ_DIR, temp); - getITVCReg(dev, ITVC_READ_DIR, &temp); - return_value |= ((temp&0x03FC0000)>>18); - setITVCReg(dev, ITVC_READ_DIR, (0x87<<10)); + temp = (0x82 | MCI_MEMORY_DATA_BYTE0) << 10; + set_itvc_reg(dev, ITVC_READ_DIR, temp); + temp = ((0x81 | MCI_MEMORY_DATA_BYTE0) << 10); + set_itvc_reg(dev, ITVC_READ_DIR, temp); + get_itvc_reg(dev, ITVC_READ_DIR, &temp); + return_value |= ((temp & 0x03FC0000) >> 18); + set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10)); *value = return_value; return ret; @@ -619,94 +642,91 @@ static char *cmd_to_str(int cmd) { switch (cmd) { case CX2341X_ENC_PING_FW: - return "PING_FW"; + return "PING_FW"; case CX2341X_ENC_START_CAPTURE: - return "START_CAPTURE"; + return "START_CAPTURE"; case CX2341X_ENC_STOP_CAPTURE: - return "STOP_CAPTURE"; + return "STOP_CAPTURE"; case CX2341X_ENC_SET_AUDIO_ID: - return "SET_AUDIO_ID"; + return "SET_AUDIO_ID"; case CX2341X_ENC_SET_VIDEO_ID: - return "SET_VIDEO_ID"; + return "SET_VIDEO_ID"; case CX2341X_ENC_SET_PCR_ID: - return "SET_PCR_PID"; + return "SET_PCR_PID"; case CX2341X_ENC_SET_FRAME_RATE: - return "SET_FRAME_RATE"; + return "SET_FRAME_RATE"; case CX2341X_ENC_SET_FRAME_SIZE: - return "SET_FRAME_SIZE"; + return "SET_FRAME_SIZE"; case CX2341X_ENC_SET_BIT_RATE: - return "SET_BIT_RATE"; + return "SET_BIT_RATE"; case CX2341X_ENC_SET_GOP_PROPERTIES: - return "SET_GOP_PROPERTIES"; + return "SET_GOP_PROPERTIES"; case CX2341X_ENC_SET_ASPECT_RATIO: - return "SET_ASPECT_RATIO"; + return "SET_ASPECT_RATIO"; case CX2341X_ENC_SET_DNR_FILTER_MODE: - return "SET_DNR_FILTER_PROPS"; + return "SET_DNR_FILTER_PROPS"; case CX2341X_ENC_SET_DNR_FILTER_PROPS: - return "SET_DNR_FILTER_PROPS"; + return "SET_DNR_FILTER_PROPS"; case CX2341X_ENC_SET_CORING_LEVELS: - return "SET_CORING_LEVELS"; + return "SET_CORING_LEVELS"; case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: - return "SET_SPATIAL_FILTER_TYPE"; + return "SET_SPATIAL_FILTER_TYPE"; case CX2341X_ENC_SET_VBI_LINE: - return "SET_VBI_LINE"; + return "SET_VBI_LINE"; case CX2341X_ENC_SET_STREAM_TYPE: - return "SET_STREAM_TYPE"; + return "SET_STREAM_TYPE"; case CX2341X_ENC_SET_OUTPUT_PORT: - return "SET_OUTPUT_PORT"; + return "SET_OUTPUT_PORT"; case CX2341X_ENC_SET_AUDIO_PROPERTIES: - return "SET_AUDIO_PROPERTIES"; + return "SET_AUDIO_PROPERTIES"; case CX2341X_ENC_HALT_FW: - return "HALT_FW"; + return "HALT_FW"; case CX2341X_ENC_GET_VERSION: - return "GET_VERSION"; + return "GET_VERSION"; case CX2341X_ENC_SET_GOP_CLOSURE: - return "SET_GOP_CLOSURE"; + return "SET_GOP_CLOSURE"; case CX2341X_ENC_GET_SEQ_END: - return "GET_SEQ_END"; + return "GET_SEQ_END"; case CX2341X_ENC_SET_PGM_INDEX_INFO: - return "SET_PGM_INDEX_INFO"; + return "SET_PGM_INDEX_INFO"; case CX2341X_ENC_SET_VBI_CONFIG: - return "SET_VBI_CONFIG"; + return "SET_VBI_CONFIG"; case CX2341X_ENC_SET_DMA_BLOCK_SIZE: - return "SET_DMA_BLOCK_SIZE"; + return "SET_DMA_BLOCK_SIZE"; case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: - return "GET_PREV_DMA_INFO_MB_10"; + return "GET_PREV_DMA_INFO_MB_10"; case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: - return "GET_PREV_DMA_INFO_MB_9"; + return "GET_PREV_DMA_INFO_MB_9"; case CX2341X_ENC_SCHED_DMA_TO_HOST: - return "SCHED_DMA_TO_HOST"; + return "SCHED_DMA_TO_HOST"; case CX2341X_ENC_INITIALIZE_INPUT: - return "INITIALIZE_INPUT"; + return "INITIALIZE_INPUT"; case CX2341X_ENC_SET_FRAME_DROP_RATE: - return "SET_FRAME_DROP_RATE"; + return "SET_FRAME_DROP_RATE"; case CX2341X_ENC_PAUSE_ENCODER: - return "PAUSE_ENCODER"; + return "PAUSE_ENCODER"; case CX2341X_ENC_REFRESH_INPUT: - return "REFRESH_INPUT"; + return "REFRESH_INPUT"; case CX2341X_ENC_SET_COPYRIGHT: - return "SET_COPYRIGHT"; + return "SET_COPYRIGHT"; case CX2341X_ENC_SET_EVENT_NOTIFICATION: - return "SET_EVENT_NOTIFICATION"; + return "SET_EVENT_NOTIFICATION"; case CX2341X_ENC_SET_NUM_VSYNC_LINES: - return "SET_NUM_VSYNC_LINES"; + return "SET_NUM_VSYNC_LINES"; case CX2341X_ENC_SET_PLACEHOLDER: - return "SET_PLACEHOLDER"; + return "SET_PLACEHOLDER"; case CX2341X_ENC_MUTE_VIDEO: - return "MUTE_VIDEO"; + return "MUTE_VIDEO"; case CX2341X_ENC_MUTE_AUDIO: - return "MUTE_AUDIO"; + return "MUTE_AUDIO"; case CX2341X_ENC_MISC: - return "MISC"; + return "MISC"; default: return "UNKNOWN"; } } -static int cx231xx_mbox_func(void *priv, - u32 command, - int in, - int out, +static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) { struct cx231xx *dev = priv; @@ -721,10 +741,8 @@ static int cx231xx_mbox_func(void *priv, without side effects */ mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); if (value != 0x12345678) { - dprintk(3, - "Firmware and/or mailbox pointer not initialized " - "or corrupted, signature = 0x%x, cmd = %s\n", value, - cmd_to_str(command)); + dprintk(3, "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n", + value, cmd_to_str(command)); return -1; } @@ -733,8 +751,8 @@ static int cx231xx_mbox_func(void *priv, */ mc417_memory_read(dev, dev->cx23417_mailbox, &flag); if (flag) { - dprintk(3, "ERROR: Mailbox appears to be in use " - "(%x), cmd = %s\n", flag, cmd_to_str(command)); + dprintk(3, "ERROR: Mailbox appears to be in use (%x), cmd = %s\n", + flag, cmd_to_str(command)); return -1; } @@ -787,11 +805,8 @@ static int cx231xx_mbox_func(void *priv, /* We don't need to call the API often, so using just one * mailbox will probably suffice */ -static int cx231xx_api_cmd(struct cx231xx *dev, - u32 command, - u32 inputcnt, - u32 outputcnt, - ...) +static int cx231xx_api_cmd(struct cx231xx *dev, u32 command, + u32 inputcnt, u32 outputcnt, ...) { u32 data[CX2341X_MBOX_MAX_DATA]; va_list vargs; @@ -834,81 +849,80 @@ static int cx231xx_find_mailbox(struct cx231xx *dev) else signaturecnt = 0; if (4 == signaturecnt) { - dprintk(1, "Mailbox signature found at 0x%x\n", i+1); - return i+1; + dprintk(1, "Mailbox signature found at 0x%x\n", i + 1); + return i + 1; } } dprintk(3, "Mailbox signature values not found!\n"); return -1; } -static void mciWriteMemoryToGPIO(struct cx231xx *dev, u32 address, u32 value, +static void mci_write_memory_to_gpio(struct cx231xx *dev, u32 address, u32 value, u32 *p_fw_image) { - u32 temp = 0; int i = 0; - temp = 0x82|MCI_MEMORY_DATA_BYTE0|((value&0x000000FF)<<8); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /*write data byte 1;*/ - temp = 0x82|MCI_MEMORY_DATA_BYTE1|(value&0x0000FF00); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /*write data byte 2;*/ - temp = 0x82|MCI_MEMORY_DATA_BYTE2|((value&0x00FF0000)>>8); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /*write data byte 3;*/ - temp = 0x82|MCI_MEMORY_DATA_BYTE3|((value&0xFF000000)>>16); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /* write address byte 2;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | - ((address & 0x003F0000)>>8); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE | + ((address & 0x003F0000) >> 8); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /* write address byte 1;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; /* write address byte 0;*/ - temp = 0x82|MCI_MEMORY_ADDRESS_BYTE0|((address & 0x00FF)<<8); - temp = temp<<10; + temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8); + temp = temp << 10; *p_fw_image = temp; p_fw_image++; - temp = temp|((0x05)<<10); + temp = temp | (0x05 << 10); *p_fw_image = temp; p_fw_image++; @@ -971,8 +985,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) IVTV_REG_APU, 0); if (retval != 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", - __func__); + pr_err("%s: Error with mc417_register_write\n", __func__); return -1; } @@ -980,25 +993,21 @@ static int cx231xx_load_firmware(struct cx231xx *dev) &dev->udev->dev); if (retval != 0) { - printk(KERN_ERR - "ERROR: Hotplug firmware request failed (%s).\n", + pr_err("ERROR: Hotplug firmware request failed (%s).\n", CX231xx_FIRM_IMAGE_NAME); - printk(KERN_ERR "Please fix your hotplug setup, the board will " - "not work without firmware loaded!\n"); + pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { - printk(KERN_ERR "ERROR: Firmware size mismatch " - "(have %zd, expected %d)\n", + pr_err("ERROR: Firmware size mismatch (have %zd, expected %d)\n", firmware->size, CX231xx_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; } if (0 != memcmp(firmware->data, magic, 8)) { - printk(KERN_ERR - "ERROR: Firmware magic mismatch, wrong file?\n"); + pr_err("ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -1; } @@ -1013,7 +1022,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) transfer_size += 4) { fw_data = *p_fw_data; - mciWriteMemoryToGPIO(dev, address, fw_data, p_current_fw); + mci_write_memory_to_gpio(dev, address, fw_data, p_current_fw); address = address + 1; p_current_fw += 20; p_fw_data += 1; @@ -1045,7 +1054,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); if (retval < 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", + pr_err("%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1057,7 +1066,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); if (retval < 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", + pr_err("%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1105,27 +1114,25 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) dprintk(2, "%s() PING OK\n", __func__); retval = cx231xx_load_firmware(dev); if (retval < 0) { - printk(KERN_ERR "%s() f/w load failed\n", __func__); + pr_err("%s() f/w load failed\n", __func__); return retval; } retval = cx231xx_find_mailbox(dev); if (retval < 0) { - printk(KERN_ERR "%s() mailbox < 0, error\n", + pr_err("%s() mailbox < 0, error\n", __func__); return -1; } dev->cx23417_mailbox = retval; retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { - printk(KERN_ERR - "ERROR: cx23417 firmware ping failed!\n"); + pr_err("ERROR: cx23417 firmware ping failed!\n"); return -1; } retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" - "version failed!\n"); + pr_err("ERROR: cx23417 firmware get encoder: version failed!\n"); return -1; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); @@ -1134,7 +1141,7 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) for (i = 0; i < 1; i++) { retval = mc417_register_read(dev, 0x20f8, &val); - dprintk(3, "***before enable656() VIM Capture Lines =%d ***\n", + dprintk(3, "***before enable656() VIM Capture Lines = %d ***\n", val); if (retval < 0) return retval; @@ -1202,7 +1209,7 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) for (i = 0; i < 1; i++) { mc417_register_read(dev, 0x20f8, &val); - dprintk(3, "***VIM Capture Lines =%d ***\n", val); + dprintk(3, "***VIM Capture Lines =%d ***\n", val); } return 0; @@ -1250,91 +1257,85 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb, struct cx231xx_dmaqueue *dma_q) { - void *vbuf; - struct cx231xx_buffer *buf; - u32 tail_data = 0; - char *p_data; - - if (dma_q->mpeg_buffer_done == 0) { - if (list_empty(&dma_q->active)) - return; - - buf = list_entry(dma_q->active.next, - struct cx231xx_buffer, vb.queue); - dev->video_mode.isoc_ctl.buf = buf; - dma_q->mpeg_buffer_done = 1; - } - /* Fill buffer */ - buf = dev->video_mode.isoc_ctl.buf; - vbuf = videobuf_to_vmalloc(&buf->vb); - - if ((dma_q->mpeg_buffer_completed+len) < - mpeglines*mpeglinesize) { - if (dma_q->add_ps_package_head == - CX231XX_NEED_ADD_PS_PACKAGE_HEAD) { - memcpy(vbuf+dma_q->mpeg_buffer_completed, - dma_q->ps_head, 3); - dma_q->mpeg_buffer_completed = - dma_q->mpeg_buffer_completed + 3; - dma_q->add_ps_package_head = - CX231XX_NONEED_PS_PACKAGE_HEAD; - } - memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len); - dma_q->mpeg_buffer_completed = - dma_q->mpeg_buffer_completed + len; - } else { - dma_q->mpeg_buffer_done = 0; - - tail_data = - mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed; - memcpy(vbuf+dma_q->mpeg_buffer_completed, - data, tail_data); - - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - v4l2_get_timestamp(&buf->vb.ts); - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - dma_q->mpeg_buffer_completed = 0; - - if (len - tail_data > 0) { - p_data = data + tail_data; - dma_q->left_data_count = len - tail_data; - memcpy(dma_q->p_left_data, - p_data, len - tail_data); - } - - } - - return; -} - -static void buffer_filled(char *data, int len, struct urb *urb, - struct cx231xx_dmaqueue *dma_q) -{ - void *vbuf; - struct cx231xx_buffer *buf; + void *vbuf; + struct cx231xx_buffer *buf; + u32 tail_data = 0; + char *p_data; + if (dma_q->mpeg_buffer_done == 0) { if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, - struct cx231xx_buffer, vb.queue); + struct cx231xx_buffer, vb.queue); + dev->video_mode.isoc_ctl.buf = buf; + dma_q->mpeg_buffer_done = 1; + } + /* Fill buffer */ + buf = dev->video_mode.isoc_ctl.buf; + vbuf = videobuf_to_vmalloc(&buf->vb); + + if ((dma_q->mpeg_buffer_completed+len) < + mpeglines*mpeglinesize) { + if (dma_q->add_ps_package_head == + CX231XX_NEED_ADD_PS_PACKAGE_HEAD) { + memcpy(vbuf+dma_q->mpeg_buffer_completed, + dma_q->ps_head, 3); + dma_q->mpeg_buffer_completed = + dma_q->mpeg_buffer_completed + 3; + dma_q->add_ps_package_head = + CX231XX_NONEED_PS_PACKAGE_HEAD; + } + memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len); + dma_q->mpeg_buffer_completed = + dma_q->mpeg_buffer_completed + len; + } else { + dma_q->mpeg_buffer_done = 0; + tail_data = + mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed; + memcpy(vbuf+dma_q->mpeg_buffer_completed, + data, tail_data); - /* Fill buffer */ - vbuf = videobuf_to_vmalloc(&buf->vb); - memcpy(vbuf, data, len); buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; v4l2_get_timestamp(&buf->vb.ts); list_del(&buf->vb.queue); wake_up(&buf->vb.done); + dma_q->mpeg_buffer_completed = 0; + + if (len - tail_data > 0) { + p_data = data + tail_data; + dma_q->left_data_count = len - tail_data; + memcpy(dma_q->p_left_data, + p_data, len - tail_data); + } + } +} - return; +static void buffer_filled(char *data, int len, struct urb *urb, + struct cx231xx_dmaqueue *dma_q) +{ + void *vbuf; + struct cx231xx_buffer *buf; + + if (list_empty(&dma_q->active)) + return; + + buf = list_entry(dma_q->active.next, + struct cx231xx_buffer, vb.queue); + + /* Fill buffer */ + vbuf = videobuf_to_vmalloc(&buf->vb); + memcpy(vbuf, data, len); + buf->vb.state = VIDEOBUF_DONE; + buf->vb.field_count++; + v4l2_get_timestamp(&buf->vb.ts); + list_del(&buf->vb.queue); + wake_up(&buf->vb.done); } -static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) + +static int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) { struct cx231xx_dmaqueue *dma_q = urb->context; unsigned char *p_buffer; @@ -1359,11 +1360,9 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) return 0; } -static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) -{ - /*char *outp;*/ - /*struct cx231xx_buffer *buf;*/ +static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) +{ struct cx231xx_dmaqueue *dma_q = urb->context; unsigned char *p_buffer, *buffer; u32 buffer_size = 0; @@ -1394,8 +1393,6 @@ static int bb_buf_prepare(struct videobuf_queue *q, int rc = 0, urb_init = 0; int size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; - dma_qq = &dev->video_mode.vidq; - if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; buf->vb.width = fh->dev->ts1.ts_packet_size; @@ -1521,6 +1518,7 @@ static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) *norm = dev->encodernorm.id; return 0; } + static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) { struct cx231xx_fh *fh = file->private_data; @@ -1552,7 +1550,8 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) dprintk(3, "exit vidioc_s_std() i=0x%x\n", i); return 0; } -static const char *iname[] = { + +static const char * const iname[] = { [CX231XX_VMUX_COMPOSITE1] = "Composite1", [CX231XX_VMUX_SVIDEO] = "S-Video", [CX231XX_VMUX_TELEVISION] = "Television", @@ -1560,6 +1559,7 @@ static const char *iname[] = { [CX231XX_VMUX_DVB] = "DVB", [CX231XX_VMUX_DEBUG] = "for debug only", }; + static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { @@ -1572,7 +1572,6 @@ static int vidioc_enum_input(struct file *file, void *priv, if (i->index >= 4) return -EINVAL; - input = &cx231xx_boards[dev->model].input[i->index]; if (input->type == 0) @@ -1589,8 +1588,6 @@ static int vidioc_enum_input(struct file *file, void *priv, i->type = V4L2_INPUT_TYPE_TUNER; else i->type = V4L2_INPUT_TYPE_CAMERA; - - return 0; } @@ -1621,6 +1618,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, { struct cx231xx_fh *fh = file->private_data; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_s_ctrl()\n"); /* Update the A/V core */ call_all(dev, core, s_ctrl, ctl); @@ -1631,7 +1629,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - if (f->index != 0) return -EINVAL; @@ -1717,22 +1714,22 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_streamon()\n"); - cx231xx_set_alt_setting(dev, INDEX_TS1, 0); - cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - if (dev->USE_ISO) - cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, - CX231XX_NUM_BUFS, - dev->video_mode.max_pkt_size, - cx231xx_isoc_copy); - else { - cx231xx_init_bulk(dev, 320, - 5, - dev->ts1_mode.max_pkt_size, - cx231xx_bulk_copy); - } + cx231xx_set_alt_setting(dev, INDEX_TS1, 0); + cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); + if (dev->USE_ISO) + cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, + CX231XX_NUM_BUFS, + dev->video_mode.max_pkt_size, + cx231xx_isoc_copy); + else { + cx231xx_init_bulk(dev, 320, + 5, + dev->ts1_mode.max_pkt_size, + cx231xx_bulk_copy); + } dprintk(3, "exit vidioc_streamon()\n"); return videobuf_streamon(&fh->vidq); } @@ -1749,6 +1746,7 @@ static int vidioc_g_ext_ctrls(struct file *file, void *priv, { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_g_ext_ctrls()\n"); if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; @@ -1763,6 +1761,7 @@ static int vidioc_s_ext_ctrls(struct file *file, void *priv, struct cx231xx *dev = fh->dev; struct cx2341x_mpeg_params p; int err; + dprintk(3, "enter vidioc_s_ext_ctrls()\n"); if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; @@ -1776,9 +1775,6 @@ static int vidioc_s_ext_ctrls(struct file *file, void *priv, } return err; - - -return 0; } static int vidioc_try_ext_ctrls(struct file *file, void *priv, @@ -1788,6 +1784,7 @@ static int vidioc_try_ext_ctrls(struct file *file, void *priv, struct cx231xx *dev = fh->dev; struct cx2341x_mpeg_params p; int err; + dprintk(3, "enter vidioc_try_ext_ctrls()\n"); if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; @@ -1805,14 +1802,8 @@ static int vidioc_log_status(struct file *file, void *priv) char name[32 + 2]; snprintf(name, sizeof(name), "%s/2", dev->name); - dprintk(3, - "%s/2: ============ START LOG STATUS ============\n", - dev->name); call_all(dev, core, log_status); cx2341x_log_status(&dev->mpeg_params, name); - dprintk(3, - "%s/2: ============= END LOG STATUS =============\n", - dev->name); return 0; } @@ -1821,6 +1812,7 @@ static int vidioc_querymenu(struct file *file, void *priv, { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_querymenu()\n"); dprintk(3, "exit vidioc_querymenu()\n"); return cx231xx_querymenu(dev, a); @@ -1831,6 +1823,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; + dprintk(3, "enter vidioc_queryctrl()\n"); dprintk(3, "exit vidioc_queryctrl()\n"); return cx231xx_queryctrl(dev, c); @@ -1881,7 +1874,6 @@ static int mpeg_open(struct file *file) fh, &dev->lock); */ - cx231xx_set_alt_setting(dev, INDEX_VANC, 1); cx231xx_set_gpio_value(dev, 2, 0); @@ -1909,16 +1901,16 @@ static int mpeg_release(struct file *file) cx231xx_stop_TS1(dev); - /* do this before setting alternate! */ - if (dev->USE_ISO) - cx231xx_uninit_isoc(dev); - else - cx231xx_uninit_bulk(dev); - cx231xx_set_mode(dev, CX231XX_SUSPEND); + /* do this before setting alternate! */ + if (dev->USE_ISO) + cx231xx_uninit_isoc(dev); + else + cx231xx_uninit_bulk(dev); + cx231xx_set_mode(dev, CX231XX_SUSPEND); - cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, - CX231xx_RAW_BITS_NONE); + cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, + CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, + CX231xx_RAW_BITS_NONE); /* FIXME: Review this crap */ /* Shut device down on last close */ @@ -1950,7 +1942,6 @@ static ssize_t mpeg_read(struct file *file, char __user *data, struct cx231xx_fh *fh = file->private_data; struct cx231xx *dev = fh->dev; - /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ /* Start mpeg encoder on first read. */ if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { @@ -1968,9 +1959,6 @@ static unsigned int mpeg_poll(struct file *file, struct poll_table_struct *wait) { struct cx231xx_fh *fh = file->private_data; - /*struct cx231xx *dev = fh->dev;*/ - - /*dprintk(2, "%s\n", __func__);*/ return videobuf_poll_stream(file, &fh->vidq, wait); } -- cgit From b86d15440b683f8634c0cb26fc0861a5bc4913ac Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 13:16:06 -0300 Subject: [media] cx231xx-417: share ioctls with cx231xx-video Share tuner, frequency, debug and input ioctls with cx231xx-video. These are all shared resources, so no need to implement them again. [mchehab@redhat.com: Fix merge conflict and a checkpatch issue] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 113 +++++++----------------------- drivers/media/usb/cx231xx/cx231xx-video.c | 54 +++++++------- drivers/media/usb/cx231xx/cx231xx.h | 15 ++++ 3 files changed, 68 insertions(+), 114 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 2c05c8f41527..567d7ab1663d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "cx231xx.h" @@ -1551,68 +1552,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) return 0; } -static const char * const iname[] = { - [CX231XX_VMUX_COMPOSITE1] = "Composite1", - [CX231XX_VMUX_SVIDEO] = "S-Video", - [CX231XX_VMUX_TELEVISION] = "Television", - [CX231XX_VMUX_CABLE] = "Cable TV", - [CX231XX_VMUX_DVB] = "DVB", - [CX231XX_VMUX_DEBUG] = "for debug only", -}; - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - struct cx231xx_input *input; - int n; - dprintk(3, "enter vidioc_enum_input()i->index=%d\n", i->index); - - if (i->index >= 4) - return -EINVAL; - - input = &cx231xx_boards[dev->model].input[i->index]; - - if (input->type == 0) - return -EINVAL; - - /* FIXME - * strcpy(i->name, input->name); */ - - n = i->index; - strcpy(i->name, iname[INPUT(n)->type]); - - if (input->type == CX231XX_VMUX_TELEVISION || - input->type == CX231XX_VMUX_CABLE) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - - dprintk(3, "enter vidioc_s_input() i=%d\n", i); - - video_mux(dev, i); - - if (i >= 4) - return -EINVAL; - dev->input = i; - dprintk(3, "exit vidioc_s_input()\n"); - return 0; -} - static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) { @@ -1831,22 +1770,12 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int mpeg_open(struct file *file) { - int minor = video_devdata(file)->minor; - struct cx231xx *h, *dev = NULL; - /*struct list_head *list;*/ + struct video_device *vdev = video_devdata(file); + struct cx231xx *dev = video_drvdata(file); struct cx231xx_fh *fh; - /*u32 value = 0;*/ dprintk(2, "%s()\n", __func__); - list_for_each_entry(h, &cx231xx_devlist, devlist) { - if (h->v4l_device->minor == minor) - dev = h; - } - - if (dev == NULL) - return -ENODEV; - if (mutex_lock_interruptible(&dev->lock)) return -ERESTARTSYS; @@ -1858,7 +1787,8 @@ static int mpeg_open(struct file *file) } file->private_data = fh; - fh->dev = dev; + v4l2_fh_init(&fh->fh, vdev); + fh->dev = dev; videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops, @@ -1880,6 +1810,7 @@ static int mpeg_open(struct file *file) cx231xx_initialize_codec(dev); mutex_unlock(&dev->lock); + v4l2_fh_add(&fh->fh); cx231xx_start_TS1(dev); return 0; @@ -1892,11 +1823,6 @@ static int mpeg_release(struct file *file) dprintk(3, "mpeg_release()! dev=0x%p\n", dev); - if (!dev) { - dprintk(3, "abort!!!\n"); - return 0; - } - mutex_lock(&dev->lock); cx231xx_stop_TS1(dev); @@ -1930,7 +1856,8 @@ static int mpeg_release(struct file *file) videobuf_read_stop(&fh->vidq); videobuf_mmap_free(&fh->vidq); - file->private_data = NULL; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); mutex_unlock(&dev->lock); return 0; @@ -1986,9 +1913,13 @@ static struct v4l2_file_operations mpeg_fops = { static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, + .vidioc_g_tuner = cx231xx_g_tuner, + .vidioc_s_tuner = cx231xx_s_tuner, + .vidioc_g_frequency = cx231xx_g_frequency, + .vidioc_s_frequency = cx231xx_s_frequency, + .vidioc_enum_input = cx231xx_enum_input, + .vidioc_g_input = cx231xx_g_input, + .vidioc_s_input = cx231xx_s_input, .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_querycap = cx231xx_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, @@ -2007,10 +1938,10 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_log_status = vidioc_log_status, .vidioc_querymenu = vidioc_querymenu, .vidioc_queryctrl = vidioc_queryctrl, -/* .vidioc_g_chip_ident = cx231xx_g_chip_ident,*/ + .vidioc_g_chip_ident = cx231xx_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG -/* .vidioc_g_register = cx231xx_g_register,*/ -/* .vidioc_s_register = cx231xx_s_register,*/ + .vidioc_g_register = cx231xx_g_register, + .vidioc_s_register = cx231xx_s_register, #endif }; @@ -2055,6 +1986,14 @@ static struct video_device *cx231xx_video_dev_alloc( vfd->v4l2_dev = &dev->v4l2_dev; vfd->lock = &dev->lock; vfd->release = video_device_release; + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); + video_set_drvdata(vfd, dev); + if (dev->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); + v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); + v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); + } return vfd; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index c199eae6bd3e..bdaa5e01bb47 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1036,7 +1036,7 @@ static const char *iname[] = { [CX231XX_VMUX_DEBUG] = "for debug only", }; -static int vidioc_enum_input(struct file *file, void *priv, +int cx231xx_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct cx231xx_fh *fh = priv; @@ -1076,7 +1076,7 @@ static int vidioc_enum_input(struct file *file, void *priv, return 0; } -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +int cx231xx_g_input(struct file *file, void *priv, unsigned int *i) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; @@ -1086,7 +1086,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) return 0; } -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +int cx231xx_s_input(struct file *file, void *priv, unsigned int i) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; @@ -1115,7 +1115,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) +int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; @@ -1139,7 +1139,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return 0; } -static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) +int cx231xx_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; @@ -1157,7 +1157,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, +int cx231xx_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct cx231xx_fh *fh = priv; @@ -1171,7 +1171,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, +int cx231xx_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct cx231xx_fh *fh = priv; @@ -1227,8 +1227,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, return rc; } -static int vidioc_g_chip_ident(struct file *file, void *fh, - struct v4l2_dbg_chip_ident *chip) +int vidioc_g_chip_ident(struct file *file, void *fh, + struct v4l2_dbg_chip_ident *chip) { chip->ident = V4L2_IDENT_NONE; chip->revision = 0; @@ -1255,7 +1255,7 @@ static int vidioc_g_chip_ident(struct file *file, void *fh, if type == i2caddr, then is the 7-bit I2C address */ -static int vidioc_g_register(struct file *file, void *priv, +int cx231xx_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { struct cx231xx_fh *fh = priv; @@ -1402,7 +1402,7 @@ static int vidioc_g_register(struct file *file, void *priv, return ret; } -static int vidioc_s_register(struct file *file, void *priv, +int cx231xx_s_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { struct cx231xx_fh *fh = priv; @@ -1811,7 +1811,7 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; - if (0 != t->index) + if (t->index) return -EINVAL; call_all(dev, tuner, s_tuner, t); @@ -2201,19 +2201,19 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_dqbuf = vidioc_dqbuf, .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, + .vidioc_enum_input = cx231xx_enum_input, + .vidioc_g_input = cx231xx_g_input, + .vidioc_s_input = cx231xx_s_input, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_g_chip_ident = vidioc_g_chip_ident, + .vidioc_g_tuner = cx231xx_g_tuner, + .vidioc_s_tuner = cx231xx_s_tuner, + .vidioc_g_frequency = cx231xx_g_frequency, + .vidioc_s_frequency = cx231xx_s_frequency, + .vidioc_g_chip_ident = cx231xx_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, + .vidioc_g_register = cx231xx_g_register, + .vidioc_s_register = cx231xx_s_register, #endif .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, @@ -2240,12 +2240,12 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = cx231xx_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_s_tuner = radio_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_g_chip_ident = vidioc_g_chip_ident, + .vidioc_g_frequency = cx231xx_g_frequency, + .vidioc_s_frequency = cx231xx_s_frequency, + .vidioc_g_chip_ident = cx231xx_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, + .vidioc_g_register = cx231xx_g_register, + .vidioc_s_register = cx231xx_s_register, #endif .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index efc0d1cafd5d..6130e4f5924d 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -936,6 +936,21 @@ void cx231xx_init_extension(struct cx231xx *dev); void cx231xx_close_extension(struct cx231xx *dev); int cx231xx_querycap(struct file *file, void *priv, struct v4l2_capability *cap); +int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t); +int cx231xx_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t); +int cx231xx_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f); +int cx231xx_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f); +int cx231xx_enum_input(struct file *file, void *priv, + struct v4l2_input *i); +int cx231xx_g_input(struct file *file, void *priv, unsigned int *i); +int cx231xx_s_input(struct file *file, void *priv, unsigned int i); +int cx231xx_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip); +int cx231xx_g_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg); +int cx231xx_s_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg); /* Provided by cx231xx-cards.c */ extern void cx231xx_pre_card_setup(struct cx231xx *dev); -- cgit From 88b6ffedd90158173eb74c8f9169208277520cbc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 29 Jan 2013 13:18:09 -0300 Subject: [media] cx231xx-417: convert to the control framework Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 213 +++++++++++++------------------- drivers/media/usb/cx231xx/cx231xx.h | 2 +- 2 files changed, 86 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 567d7ab1663d..49c842aa1f70 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -744,7 +745,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, if (value != 0x12345678) { dprintk(3, "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n", value, cmd_to_str(command)); - return -1; + return -EIO; } /* This read looks at 32 bits, but flag is only 8 bits. @@ -754,7 +755,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, if (flag) { dprintk(3, "ERROR: Mailbox appears to be in use (%x), cmd = %s\n", flag, cmd_to_str(command)); - return -1; + return -EBUSY; } flag |= 1; /* tell 'em we're working on it */ @@ -783,7 +784,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, break; if (time_after(jiffies, timeout)) { dprintk(3, "ERROR: API Mailbox timeout\n"); - return -1; + return -EIO; } udelay(10); } @@ -800,7 +801,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out, flag = 0; mc417_memory_write(dev, dev->cx23417_mailbox, flag); - return retval; + return 0; } /* We don't need to call the API often, so using just one @@ -829,6 +830,7 @@ static int cx231xx_api_cmd(struct cx231xx *dev, u32 command, return err; } + static int cx231xx_find_mailbox(struct cx231xx *dev) { u32 signature[4] = { @@ -1092,10 +1094,10 @@ static void cx231xx_codec_settings(struct cx231xx *dev) cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, dev->ts1.height, dev->ts1.width); - dev->mpeg_params.width = dev->ts1.width; - dev->mpeg_params.height = dev->ts1.height; + dev->mpeg_ctrl_handler.width = dev->ts1.width; + dev->mpeg_ctrl_handler.height = dev->ts1.height; - cx2341x_update(dev, cx231xx_mbox_func, NULL, &dev->mpeg_params); + cx2341x_handler_setup(&dev->mpeg_ctrl_handler); cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1); cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1); @@ -1481,36 +1483,6 @@ static struct videobuf_queue_ops cx231xx_qops = { /* ------------------------------------------------------------------ */ -static const u32 *ctrl_classes[] = { - cx2341x_mpeg_ctrls, - NULL -}; - -static int cx231xx_queryctrl(struct cx231xx *dev, - struct v4l2_queryctrl *qctrl) -{ - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (qctrl->id == 0) - return -EINVAL; - - /* MPEG V4L2 controls */ - if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - - return 0; -} - -static int cx231xx_querymenu(struct cx231xx *dev, - struct v4l2_querymenu *qmenu) -{ - struct v4l2_queryctrl qctrl; - - qctrl.id = qmenu->id; - cx231xx_queryctrl(dev, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, - cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); -} - static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) { struct cx231xx_fh *fh = file->private_data; @@ -1537,12 +1509,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) dprintk(3, "encodernorm set to NTSC\n"); dev->norm = V4L2_STD_NTSC; dev->ts1.height = 480; - dev->mpeg_params.is_50hz = 0; + cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false); } else { dprintk(3, "encodernorm set to PAL\n"); dev->norm = V4L2_STD_PAL_B; dev->ts1.height = 576; - dev->mpeg_params.is_50hz = 1; + cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, true); } call_all(dev, core, s_std, dev->norm); /* do mode control overrides */ @@ -1680,92 +1652,13 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return videobuf_streamoff(&fh->vidq); } -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - - dprintk(3, "enter vidioc_g_ext_ctrls()\n"); - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - dprintk(3, "exit vidioc_g_ext_ctrls()\n"); - return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS); -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - dprintk(3, "enter vidioc_s_ext_ctrls()\n"); - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); - if (err == 0) { - err = cx2341x_update(dev, cx231xx_mbox_func, - &dev->mpeg_params, &p); - dev->mpeg_params = p; - } - - return err; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - dprintk(3, "enter vidioc_try_ext_ctrls()\n"); - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); - dprintk(3, "exit vidioc_try_ext_ctrls() err=%d\n", err); - return err; -} - static int vidioc_log_status(struct file *file, void *priv) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; - char name[32 + 2]; - snprintf(name, sizeof(name), "%s/2", dev->name); call_all(dev, core, log_status); - cx2341x_log_status(&dev->mpeg_params, name); - return 0; -} - -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *a) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - - dprintk(3, "enter vidioc_querymenu()\n"); - dprintk(3, "exit vidioc_querymenu()\n"); - return cx231xx_querymenu(dev, a); -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - - dprintk(3, "enter vidioc_queryctrl()\n"); - dprintk(3, "exit vidioc_queryctrl()\n"); - return cx231xx_queryctrl(dev, c); + return v4l2_ctrl_log_status(file, priv); } static int mpeg_open(struct file *file) @@ -1885,9 +1778,23 @@ static ssize_t mpeg_read(struct file *file, char __user *data, static unsigned int mpeg_poll(struct file *file, struct poll_table_struct *wait) { + unsigned long req_events = poll_requested_events(wait); struct cx231xx_fh *fh = file->private_data; + struct cx231xx *dev = fh->dev; + unsigned int res = 0; - return videobuf_poll_stream(file, &fh->vidq, wait); + if (v4l2_event_pending(&fh->fh)) + res |= POLLPRI; + else + poll_wait(file, &fh->fh.wait, wait); + + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; + + mutex_lock(&dev->lock); + res |= videobuf_poll_stream(file, &fh->vidq, wait); + mutex_unlock(&dev->lock); + return res; } static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) @@ -1932,17 +1839,14 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_dqbuf = vidioc_dqbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, .vidioc_log_status = vidioc_log_status, - .vidioc_querymenu = vidioc_querymenu, - .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_chip_ident = cx231xx_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = cx231xx_g_register, .vidioc_s_register = cx231xx_s_register, #endif + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device cx231xx_mpeg_template = { @@ -1950,7 +1854,7 @@ static struct video_device cx231xx_mpeg_template = { .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, - .tvnorms = CX231xx_NORMS, + .tvnorms = V4L2_STD_ALL, }; void cx231xx_417_unregister(struct cx231xx *dev) @@ -1963,10 +1867,44 @@ void cx231xx_417_unregister(struct cx231xx *dev) video_unregister_device(dev->v4l_device); else video_device_release(dev->v4l_device); + v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl); dev->v4l_device = NULL; } } +static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) +{ + struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler); + int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; + struct v4l2_mbus_framefmt fmt; + + /* fix videodecoder resolution */ + fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); + fmt.height = cxhdl->height; + fmt.code = V4L2_MBUS_FMT_FIXED; + v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt); + return 0; +} + +static int cx231xx_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx) +{ + static const u32 freqs[3] = { 44100, 48000, 32000 }; + struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler); + + /* The audio clock of the digitizer must match the codec sample + rate otherwise you get some very strange effects. */ + if (idx < ARRAY_SIZE(freqs)) + call_all(dev, audio, s_clock_freq, freqs[idx]); + return 0; +} + +static struct cx2341x_handler_ops cx231xx_ops = { + /* needed for the video clock freq */ + .s_audio_sampling_freq = cx231xx_s_audio_sampling_freq, + /* needed for setting up the video resolution */ + .s_video_encoding = cx231xx_s_video_encoding, +}; + static struct video_device *cx231xx_video_dev_alloc( struct cx231xx *dev, struct usb_device *usbdev, @@ -1987,6 +1925,7 @@ static struct video_device *cx231xx_video_dev_alloc( vfd->lock = &dev->lock; vfd->release = video_device_release; set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); + vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl; video_set_drvdata(vfd, dev); if (dev->tuner_type == TUNER_ABSENT) { v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); @@ -2016,10 +1955,27 @@ int cx231xx_417_register(struct cx231xx *dev) tsport->height = 576; tsport->width = 720; - cx2341x_fill_defaults(&dev->mpeg_params); + err = cx2341x_handler_init(&dev->mpeg_ctrl_handler, 50); + if (err) { + dprintk(3, "%s: can't init cx2341x controls\n", dev->name); + return err; + } + dev->mpeg_ctrl_handler.func = cx231xx_mbox_func; + dev->mpeg_ctrl_handler.priv = dev; + dev->mpeg_ctrl_handler.ops = &cx231xx_ops; + if (dev->sd_cx25840) + v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl, + dev->sd_cx25840->ctrl_handler, NULL); + if (dev->mpeg_ctrl_handler.hdl.error) { + err = dev->mpeg_ctrl_handler.hdl.error; + dprintk(3, "%s: can't add cx25840 controls\n", dev->name); + v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl); + return err; + } dev->norm = V4L2_STD_NTSC; - dev->mpeg_params.port = CX2341X_PORT_SERIAL; + dev->mpeg_ctrl_handler.port = CX2341X_PORT_SERIAL; + cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false); /* Allocate and initialize V4L video device */ dev->v4l_device = cx231xx_video_dev_alloc(dev, @@ -2028,6 +1984,7 @@ int cx231xx_417_register(struct cx231xx *dev) VFL_TYPE_GRABBER, -1); if (err < 0) { dprintk(3, "%s: can't register mpeg device\n", dev->name); + v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl); return err; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 6130e4f5924d..0f92fd1ea794 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -612,6 +612,7 @@ struct cx231xx { struct v4l2_subdev *sd_tuner; struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl_handler radio_ctrl_handler; + struct cx2341x_handler mpeg_ctrl_handler; struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ atomic_t stream_started; /* stream should be running if true */ @@ -715,7 +716,6 @@ struct cx231xx { u8 USE_ISO; struct cx231xx_tvnorm encodernorm; struct cx231xx_tsport ts1, ts2; - struct cx2341x_mpeg_params mpeg_params; struct video_device *v4l_device; atomic_t v4l_reader_count; u32 freq; -- cgit From 4485ea917b06c63087f369a7139c39b27ad14d10 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 11:07:40 -0300 Subject: [media] cx231xx: remove bogus driver prefix in log messages The prefix is generated automatically, so no need to provide it again. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-vbi.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 46e3892557c2..1340ff268817 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -70,10 +70,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status, + cx231xx_err("URB status %d [%s].\n", status, errmsg); } else { - cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n", + cx231xx_err("URB packet %d, status %d [%s].\n", packet, status, errmsg); } } @@ -317,7 +317,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - cx231xx_err(DRIVER_NAME "urb completition error %d.\n", + cx231xx_err("urb completition error %d.\n", urb->status); break; } @@ -332,7 +332,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { - cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n", + cx231xx_err("urb resubmit failed (error=%i)\n", urb->status); } } @@ -345,7 +345,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n"); + cx231xx_info("called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -394,7 +394,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_prepare_isoc\n"); + cx231xx_info("called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -442,8 +442,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - cx231xx_err(DRIVER_NAME - ": cannot alloc bulk_ctl.urb %i\n", i); + cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -453,8 +452,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - cx231xx_err(DRIVER_NAME - ": unable to allocate %i bytes for transfer" + cx231xx_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); cx231xx_uninit_vbi_isoc(dev); @@ -473,8 +471,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err(DRIVER_NAME - ": submit of urb %i failed (error=%i)\n", i, + cx231xx_err("submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; @@ -526,7 +523,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* cx231xx_info("[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; @@ -618,7 +615,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, char *outp; if (list_empty(&dma_q->active)) { - cx231xx_err(DRIVER_NAME ": No active queue to serve\n"); + cx231xx_err("No active queue to serve\n"); dev->vbi_mode.bulk_ctl.buf = NULL; *buf = NULL; return; -- cgit From b31077a88a1242541b1c9b191c238ac313609d9f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 13:22:06 -0300 Subject: [media] cx231xx: disable 417 support from the Conexant video grabber The 417 support doesn't work. Until someone can dig into this driver to figure out why it isn't working the 417 support is disabled. Sometimes you can actually stream a bit, but very soon the whole machine crashes, so something is seriously wrong. For the record, this was not introduced by my recent changes to this driver, it was broken before that. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index d6acb1ebff33..70944516125a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -263,7 +263,10 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_PAL, .no_alt_vanc = 1, .external_av = 1, - .has_417 = 1, + /* Actually, it has a 417, but it isn't working correctly. + * So set to 0 for now until someone can manage to get this + * to work reliably. */ + .has_417 = 0, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, -- cgit From 720b3dfad42af96e3c937df8e167aac6c2901295 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Feb 2013 11:48:41 -0300 Subject: [media] cx231xx: don't reset width/height on first open The last set width/height must be preserved as per the spec. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index bdaa5e01bb47..41c5c996ed2c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1871,9 +1871,6 @@ static int cx231xx_v4l2_open(struct file *filp) v4l2_fh_init(&fh->fh, vdev); if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { - dev->width = norm_maxw(dev); - dev->height = norm_maxh(dev); - /* Power up in Analog TV mode */ if (dev->board.external_av) cx231xx_set_power_mode(dev, -- cgit From fff9e818fb523804084cf8456f48ffbc56b70fbe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Feb 2013 12:43:25 -0300 Subject: [media] cx231xx: don't use port 3 on the Conexant video grabber It's not working reliably if port 3 is enabled. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 70944516125a..62d104b98390 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -263,6 +263,7 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_PAL, .no_alt_vanc = 1, .external_av = 1, + .dont_use_port_3 = 1, /* Actually, it has a 417, but it isn't working correctly. * So set to 0 for now until someone can manage to get this * to work reliably. */ -- cgit From 69a11a32643bda3e7f76af397cb6cd7b32c640f9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 15:28:53 -0300 Subject: [media] cx231xx: fix big-endian problems Tested on my big-endian ppc-based test machine. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-audio.c | 4 ++-- drivers/media/usb/cx231xx/cx231xx-avcore.c | 8 ++++---- drivers/media/usb/cx231xx/cx231xx-cards.c | 16 ++++++++-------- drivers/media/usb/cx231xx/cx231xx-core.c | 2 +- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index b40360b8e89e..81a1d971d797 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -704,8 +704,8 @@ static int cx231xx_audio_init(struct cx231xx *dev) audio_index + 1]; adev->end_point_addr = - le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc. - bEndpointAddress); + uif->altsetting[0].endpoint[isoc_pipe].desc. + bEndpointAddress; adev->num_alt = uif->num_altsetting; cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 4706ed350293..3f26f64d7bf4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2221,7 +2221,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (status < 0) return status; - tmp = *((u32 *) value); + tmp = le32_to_cpu(*((u32 *) value)); switch (mode) { case POLARIS_AVMODE_ENXTERNAL_AV: @@ -2442,7 +2442,7 @@ int cx231xx_power_suspend(struct cx231xx *dev) if (status > 0) return status; - tmp = *((u32 *) value); + tmp = le32_to_cpu(*((u32 *) value)); tmp &= (~PWR_MODE_MASK); value[0] = (u8) tmp; @@ -2470,7 +2470,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) if (status < 0) return status; - tmp = *((u32 *) value); + tmp = le32_to_cpu(*((u32 *) value)); tmp |= ep_mask; value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); @@ -2495,7 +2495,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) if (status < 0) return status; - tmp = *((u32 *) value); + tmp = le32_to_cpu(*((u32 *) value)); tmp &= (~ep_mask); value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 62d104b98390..b7b1acd7e7b0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1189,8 +1189,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, uif = udev->actconfig->interface[dev->current_pcb_config. hs_config_info[0].interface_info.video_index + 1]; - dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0]. - endpoint[isoc_pipe].desc.bEndpointAddress); + dev->video_mode.end_point_addr = uif->altsetting[0]. + endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", @@ -1223,8 +1223,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, vanc_index + 1]; dev->vbi_mode.end_point_addr = - le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc. - bEndpointAddress); + uif->altsetting[0].endpoint[isoc_pipe].desc. + bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", @@ -1258,8 +1258,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, hanc_index + 1]; dev->sliced_cc_mode.end_point_addr = - le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc. - bEndpointAddress); + uif->altsetting[0].endpoint[isoc_pipe].desc. + bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", @@ -1294,8 +1294,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ts1_index + 1]; dev->ts1_mode.end_point_addr = - le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe]. - desc.bEndpointAddress); + uif->altsetting[0].endpoint[isoc_pipe]. + desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 05358d486135..4ba3ce09b713 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1488,7 +1488,7 @@ int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode) if (status < 0) return status; - tmp = *((u32 *) value); + tmp = le32_to_cpu(*((u32 *) value)); tmp |= mode; value[0] = (u8) tmp; diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index 7473c33e823e..d7308ab7a90f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -672,7 +672,7 @@ u32 initialize_cx231xx(struct cx231xx *dev) pcb config it is related to */ cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4); - config_info = *((u32 *) data); + config_info = le32_to_cpu(*((u32 *) data)); usb_speed = (u8) (config_info & 0x1); /* Verify this device belongs to Bus power or Self power device */ -- cgit From 6b236a375d4764a6b7f7b83fb49bccacb7db4969 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Feb 2013 13:13:12 -0300 Subject: [media] cx231xx: fix gpio big-endian problems Tested on my big-endian ppc-based test machine. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 73 ++++++++++++++++-------------- drivers/media/usb/cx231xx/cx231xx.h | 2 - 2 files changed, 38 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 3f26f64d7bf4..2e51fb9fd21c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2638,20 +2638,23 @@ EXPORT_SYMBOL_GPL(cx231xx_capture_start); /***************************************************************************** * G P I O B I T control functions * ******************************************************************************/ -int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val) +static int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 gpio_val) { int status = 0; - status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0); + gpio_val = cpu_to_le32(gpio_val); + status = cx231xx_send_gpio_cmd(dev, gpio_bit, (u8 *)&gpio_val, 4, 0, 0); return status; } -int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val) +static int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 *gpio_val) { + u32 tmp; int status = 0; - status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1); + status = cx231xx_send_gpio_cmd(dev, gpio_bit, (u8 *)&tmp, 4, 0, 1); + *gpio_val = le32_to_cpu(tmp); return status; } @@ -2683,7 +2686,7 @@ int cx231xx_set_gpio_direction(struct cx231xx *dev, else value = dev->gpio_dir | (1 << pin_number); - status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, value, dev->gpio_val); /* cache the value for future */ dev->gpio_dir = value; @@ -2717,7 +2720,7 @@ int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value) value = dev->gpio_dir | (1 << pin_number); dev->gpio_dir = value; status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *) &dev->gpio_val); + dev->gpio_val); value = 0; } @@ -2730,7 +2733,7 @@ int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value) dev->gpio_val = value; /* toggle bit0 of GP_IO */ - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); return status; } @@ -2748,7 +2751,7 @@ int cx231xx_gpio_i2c_start(struct cx231xx *dev) dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; dev->gpio_val |= 1 << dev->board.tuner_sda_gpio; - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2756,7 +2759,7 @@ int cx231xx_gpio_i2c_start(struct cx231xx *dev) dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2764,7 +2767,7 @@ int cx231xx_gpio_i2c_start(struct cx231xx *dev) dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2782,7 +2785,7 @@ int cx231xx_gpio_i2c_end(struct cx231xx *dev) dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2790,7 +2793,7 @@ int cx231xx_gpio_i2c_end(struct cx231xx *dev) dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2800,7 +2803,7 @@ int cx231xx_gpio_i2c_end(struct cx231xx *dev) dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio); status = - cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); if (status < 0) return -EINVAL; @@ -2822,33 +2825,33 @@ int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data) dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* set SCL to output 1; set SDA to output 0 */ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* set SCL to output 0; set SDA to output 0 */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); } else { /* set SCL to output 0; set SDA to output 1 */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); dev->gpio_val |= 1 << dev->board.tuner_sda_gpio; status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* set SCL to output 1; set SDA to output 1 */ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* set SCL to output 0; set SDA to output 1 */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); } } return status; @@ -2867,17 +2870,17 @@ int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf) /* set SCL to output 0; set SDA to input */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* set SCL to output 1; set SDA to input */ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + dev->gpio_val); /* get SDA data bit */ gpio_logic_value = dev->gpio_val; status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + &dev->gpio_val); if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0) value |= (1 << (8 - i - 1)); @@ -2888,7 +2891,7 @@ int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf) !!!set SDA to input, never to modify SDA direction at the same times */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* store the value */ *buf = value & 0xff; @@ -2909,12 +2912,12 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio); gpio_logic_value = dev->gpio_val; - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); do { msleep(2); status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, - (u8 *)&dev->gpio_val); + &dev->gpio_val); nCnt--; } while (((dev->gpio_val & (1 << dev->board.tuner_scl_gpio)) == 0) && @@ -2929,7 +2932,7 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) * through clock stretch, slave has given a SCL signal, * so the SDA data can be directly read. */ - status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, &dev->gpio_val); if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) { dev->gpio_val = gpio_logic_value; @@ -2945,7 +2948,7 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) dev->gpio_val = gpio_logic_value; dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio); dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); return status; } @@ -2956,24 +2959,24 @@ int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev) /* set SDA to ouput */ dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio; - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set SCL = 0 (output); set SDA = 0 (output) */ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio); dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set SCL = 1 (output); set SDA = 0 (output) */ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set SCL = 0 (output); set SDA = 0 (output) */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set SDA to input,and then the slave will read data from SDA. */ dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); return status; } @@ -2985,15 +2988,15 @@ int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev) /* set scl to output ; set sda to input */ dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio; dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set scl to output 0; set sda to input */ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio); - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); /* set scl to output 1; set sda to input */ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio; - status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val); + status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); return status; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 0f92fd1ea794..a8e50d2d491c 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -845,8 +845,6 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* Gpio related functions */ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, u8 len, u8 request, u8 direction); -int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val); -int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val); int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value); int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number, int pin_value); -- cgit From 2aeb73e19dc3d17beebc1b9a678f4c60e1072e25 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 12 Feb 2013 05:25:38 -0300 Subject: [media] stk-webcam: add ASUS F3JC to upside-down list And add an extensive comment relating the history of the upside-down handling in this driver. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Thanks-to: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 4cbab085e348..b2a5ee453a6a 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -63,7 +63,39 @@ static struct usb_device_id stkwebcam_table[] = { }; MODULE_DEVICE_TABLE(usb, stkwebcam_table); -/* The stk webcam laptop module is mounted upside down in some laptops :( */ +/* + * The stk webcam laptop module is mounted upside down in some laptops :( + * + * Some background information (thanks to Hans de Goede for providing this): + * + * 1) Once upon a time the stkwebcam driver was written + * + * 2) The webcam in question was used mostly in Asus laptop models, including + * the laptop of the original author of the driver, and in these models, in + * typical Asus fashion (see the long long list for uvc cams inside v4l-utils), + * they mounted the webcam-module the wrong way up. So the hflip and vflip + * module options were given a default value of 1 (the correct value for + * upside down mounted models) + * + * 3) Years later I got a bug report from a user with a laptop with stkwebcam, + * where the module was actually mounted the right way up, and thus showed + * upside down under Linux. So now I was facing the choice of 2 options: + * + * a) Add a not-upside-down list to stkwebcam, which overrules the default. + * + * b) Do it like all the other drivers do, and make the default right for + * cams mounted the proper way and add an upside-down model list, with + * models where we need to flip-by-default. + * + * Despite knowing that going b) would cause a period of pain where we were + * building the table I opted to go for option b), since a) is just too ugly, + * and worse different from how every other driver does it leading to + * confusion in the long run. This change was made in kernel 3.6. + * + * So for any user report about upside-down images since kernel 3.6 ask them + * to provide the output of 'sudo dmidecode' so the laptop can be added in + * the table below. + */ static const struct dmi_system_id stk_upside_down_dmi_table[] = { { .ident = "ASUS G1", @@ -71,6 +103,12 @@ static const struct dmi_system_id stk_upside_down_dmi_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "G1") } + }, { + .ident = "ASUS F3JC", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "F3JC") + } }, {} }; -- cgit From e144760a33e3f09ccf6f3abb186920753f27a998 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 09:30:49 -0300 Subject: [media] stk-webcam: remove bogus STD support It's a webcam, the STD API is not applicable to webcams. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index b2a5ee453a6a..e9dbe23122c3 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -806,12 +806,6 @@ static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i) return 0; } -/* from vivi.c */ -static int stk_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a) -{ - return 0; -} - /* List of all V4Lv2 controls supported by the driver */ static struct v4l2_queryctrl stk_controls[] = { { @@ -1263,7 +1257,6 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { .vidioc_enum_input = stk_vidioc_enum_input, .vidioc_s_input = stk_vidioc_s_input, .vidioc_g_input = stk_vidioc_g_input, - .vidioc_s_std = stk_vidioc_s_std, .vidioc_reqbufs = stk_vidioc_reqbufs, .vidioc_querybuf = stk_vidioc_querybuf, .vidioc_qbuf = stk_vidioc_qbuf, @@ -1289,8 +1282,6 @@ static void stk_v4l_dev_release(struct video_device *vd) static struct video_device stk_v4l_data = { .name = "stkwebcam", - .tvnorms = V4L2_STD_UNKNOWN, - .current_norm = V4L2_STD_UNKNOWN, .fops = &v4l_stk_fops, .ioctl_ops = &v4l_stk_ioctl_ops, .release = stk_v4l_dev_release, -- cgit From 968c60f60376a573460b6ef4991435d09528d48c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 08:17:42 -0300 Subject: [media] stk-webcam: add support for struct v4l2_device Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 10 +++++++++- drivers/media/usb/stkwebcam/stk-webcam.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index e9dbe23122c3..eaf152c51ae2 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1294,7 +1294,7 @@ static int stk_register_video_device(struct stk_camera *dev) dev->vdev = stk_v4l_data; dev->vdev.debug = debug; - dev->vdev.parent = &dev->interface->dev; + dev->vdev.v4l2_dev = &dev->v4l2_dev; err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (err) STK_ERROR("v4l registration failed\n"); @@ -1323,6 +1323,12 @@ static int stk_camera_probe(struct usb_interface *interface, STK_ERROR("Out of memory !\n"); return -ENOMEM; } + err = v4l2_device_register(&interface->dev, &dev->v4l2_dev); + if (err < 0) { + dev_err(&udev->dev, "couldn't register v4l2_device\n"); + kfree(dev); + return err; + } spin_lock_init(&dev->spinlock); init_waitqueue_head(&dev->wait_frame); @@ -1383,6 +1389,7 @@ static int stk_camera_probe(struct usb_interface *interface, return 0; error: + v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); return err; } @@ -1400,6 +1407,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) video_device_node_name(&dev->vdev)); video_unregister_device(&dev->vdev); + v4l2_device_unregister(&dev->v4l2_dev); } #ifdef CONFIG_PM diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 9f6736637571..49ebe855cba6 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -23,6 +23,7 @@ #define STKWEBCAM_H #include +#include #include #define DRIVER_VERSION "v0.0.1" @@ -91,6 +92,7 @@ struct regval { }; struct stk_camera { + struct v4l2_device v4l2_dev; struct video_device vdev; struct usb_device *udev; struct usb_interface *interface; -- cgit From dc0fb28675e7ef7ac12a5532500b2f89e41f2174 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 08:53:11 -0300 Subject: [media] stk-webcam: convert to the control framework Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 119 ++++++++----------------------- drivers/media/usb/stkwebcam/stk-webcam.h | 3 +- 2 files changed, 33 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index eaf152c51ae2..f1cf9060ce71 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -806,99 +806,25 @@ static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i) return 0; } -/* List of all V4Lv2 controls supported by the driver */ -static struct v4l2_queryctrl stk_controls[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 0xffff, - .step = 0x0100, - .default_value = 0x6000, - }, - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Horizontal Flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vertical Flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, -}; - -static int stk_vidioc_queryctrl(struct file *filp, - void *priv, struct v4l2_queryctrl *c) +static int stk_s_ctrl(struct v4l2_ctrl *ctrl) { - int i; - int nbr; - nbr = ARRAY_SIZE(stk_controls); - - for (i = 0; i < nbr; i++) { - if (stk_controls[i].id == c->id) { - memcpy(c, &stk_controls[i], - sizeof(struct v4l2_queryctrl)); - return 0; - } - } - return -EINVAL; -} - -static int stk_vidioc_g_ctrl(struct file *filp, - void *priv, struct v4l2_control *c) -{ - struct stk_camera *dev = priv; - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - c->value = dev->vsettings.brightness; - break; - case V4L2_CID_HFLIP: - if (dmi_check_system(stk_upside_down_dmi_table)) - c->value = !dev->vsettings.hflip; - else - c->value = dev->vsettings.hflip; - break; - case V4L2_CID_VFLIP: - if (dmi_check_system(stk_upside_down_dmi_table)) - c->value = !dev->vsettings.vflip; - else - c->value = dev->vsettings.vflip; - break; - default: - return -EINVAL; - } - return 0; -} + struct stk_camera *dev = + container_of(ctrl->handler, struct stk_camera, hdl); -static int stk_vidioc_s_ctrl(struct file *filp, - void *priv, struct v4l2_control *c) -{ - struct stk_camera *dev = priv; - switch (c->id) { + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - dev->vsettings.brightness = c->value; - return stk_sensor_set_brightness(dev, c->value >> 8); + return stk_sensor_set_brightness(dev, ctrl->val); case V4L2_CID_HFLIP: if (dmi_check_system(stk_upside_down_dmi_table)) - dev->vsettings.hflip = !c->value; + dev->vsettings.hflip = !ctrl->val; else - dev->vsettings.hflip = c->value; + dev->vsettings.hflip = ctrl->val; return 0; case V4L2_CID_VFLIP: if (dmi_check_system(stk_upside_down_dmi_table)) - dev->vsettings.vflip = !c->value; + dev->vsettings.vflip = !ctrl->val; else - dev->vsettings.vflip = c->value; + dev->vsettings.vflip = ctrl->val; return 0; default: return -EINVAL; @@ -1238,6 +1164,10 @@ static int stk_vidioc_enum_framesizes(struct file *filp, } } +static const struct v4l2_ctrl_ops stk_ctrl_ops = { + .s_ctrl = stk_s_ctrl, +}; + static struct v4l2_file_operations v4l_stk_fops = { .owner = THIS_MODULE, .open = v4l_stk_open, @@ -1263,9 +1193,6 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { .vidioc_dqbuf = stk_vidioc_dqbuf, .vidioc_streamon = stk_vidioc_streamon, .vidioc_streamoff = stk_vidioc_streamoff, - .vidioc_queryctrl = stk_vidioc_queryctrl, - .vidioc_g_ctrl = stk_vidioc_g_ctrl, - .vidioc_s_ctrl = stk_vidioc_s_ctrl, .vidioc_g_parm = stk_vidioc_g_parm, .vidioc_enum_framesizes = stk_vidioc_enum_framesizes, }; @@ -1310,8 +1237,9 @@ static int stk_register_video_device(struct stk_camera *dev) static int stk_camera_probe(struct usb_interface *interface, const struct usb_device_id *id) { - int i; + struct v4l2_ctrl_handler *hdl; int err = 0; + int i; struct stk_camera *dev = NULL; struct usb_device *udev = interface_to_usbdev(interface); @@ -1329,6 +1257,20 @@ static int stk_camera_probe(struct usb_interface *interface, kfree(dev); return err; } + hdl = &dev->hdl; + v4l2_ctrl_handler_init(hdl, 3); + v4l2_ctrl_new_std(hdl, &stk_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 0xff, 0x1, 0x60); + v4l2_ctrl_new_std(hdl, &stk_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 1); + v4l2_ctrl_new_std(hdl, &stk_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 1); + if (hdl->error) { + err = hdl->error; + dev_err(&udev->dev, "couldn't register control\n"); + goto error; + } + dev->v4l2_dev.ctrl_handler = hdl; spin_lock_init(&dev->spinlock); init_waitqueue_head(&dev->wait_frame); @@ -1372,7 +1314,6 @@ static int stk_camera_probe(struct usb_interface *interface, err = -ENODEV; goto error; } - dev->vsettings.brightness = 0x7fff; dev->vsettings.palette = V4L2_PIX_FMT_RGB565; dev->vsettings.mode = MODE_VGA; dev->frame_size = 640 * 480 * 2; @@ -1389,6 +1330,7 @@ static int stk_camera_probe(struct usb_interface *interface, return 0; error: + v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); return err; @@ -1407,6 +1349,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) video_device_node_name(&dev->vdev)); video_unregister_device(&dev->vdev); + v4l2_ctrl_handler_free(&dev->hdl); v4l2_device_unregister(&dev->v4l2_dev); } diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 49ebe855cba6..901f0df21bc7 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -24,6 +24,7 @@ #include #include +#include #include #define DRIVER_VERSION "v0.0.1" @@ -60,7 +61,6 @@ enum stk_mode {MODE_VGA, MODE_SXGA, MODE_CIF, MODE_QVGA, MODE_QCIF}; struct stk_video { enum stk_mode mode; - int brightness; __u32 palette; int hflip; int vflip; @@ -93,6 +93,7 @@ struct regval { struct stk_camera { struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler hdl; struct video_device vdev; struct usb_device *udev; struct usb_interface *interface; -- cgit From 10351adc6ac9251863ec6d90436e3ad277d178e0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 09:00:48 -0300 Subject: [media] stk-webcam: don't use private_data, use video_drvdata file->private_data is needed to store the pointer to struct v4l2_fh. So use video_drvdata to get hold of the stk_camera struct. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index f1cf9060ce71..49a4dfd22bf2 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -604,11 +604,7 @@ static void stk_free_buffers(struct stk_camera *dev) static int v4l_stk_open(struct file *fp) { static int first_init = 1; /* webcam LED management */ - struct stk_camera *dev; - struct video_device *vdev; - - vdev = video_devdata(fp); - dev = vdev_to_camera(vdev); + struct stk_camera *dev = video_drvdata(fp); if (dev == NULL || !is_present(dev)) return -ENXIO; @@ -618,7 +614,6 @@ static int v4l_stk_open(struct file *fp) else first_init = 0; - fp->private_data = dev; usb_autopm_get_interface(dev->interface); return 0; @@ -626,7 +621,7 @@ static int v4l_stk_open(struct file *fp) static int v4l_stk_release(struct file *fp) { - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev = video_drvdata(fp); if (dev->owner == fp) { stk_stop_stream(dev); @@ -649,7 +644,7 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, int ret; unsigned long flags; struct stk_sio_buffer *sbuf; - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev = video_drvdata(fp); if (!is_present(dev)) return -EIO; @@ -705,7 +700,7 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) { - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev = video_drvdata(fp); poll_wait(fp, &dev->wait_frame, wait); @@ -741,7 +736,7 @@ static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma) unsigned int i; int ret; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev = video_drvdata(fp); struct stk_sio_buffer *sbuf = NULL; if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) @@ -879,7 +874,7 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *f) { struct v4l2_pix_format *pix_format = &f->fmt.pix; - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); int i; for (i = 0; i < ARRAY_SIZE(stk_sizes) && @@ -984,7 +979,7 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { int ret; - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); if (dev == NULL) return -ENODEV; @@ -1011,7 +1006,7 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, static int stk_vidioc_reqbufs(struct file *filp, void *priv, struct v4l2_requestbuffers *rb) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); if (dev == NULL) return -ENODEV; @@ -1037,7 +1032,7 @@ static int stk_vidioc_reqbufs(struct file *filp, static int stk_vidioc_querybuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); struct stk_sio_buffer *sbuf; if (buf->index >= dev->n_sbufs) @@ -1050,7 +1045,7 @@ static int stk_vidioc_querybuf(struct file *filp, static int stk_vidioc_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); struct stk_sio_buffer *sbuf; unsigned long flags; @@ -1074,7 +1069,7 @@ static int stk_vidioc_qbuf(struct file *filp, static int stk_vidioc_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); struct stk_sio_buffer *sbuf; unsigned long flags; int ret; @@ -1107,7 +1102,7 @@ static int stk_vidioc_dqbuf(struct file *filp, static int stk_vidioc_streamon(struct file *filp, void *priv, enum v4l2_buf_type type) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); if (is_streaming(dev)) return 0; if (dev->sio_bufs == NULL) @@ -1119,7 +1114,7 @@ static int stk_vidioc_streamon(struct file *filp, static int stk_vidioc_streamoff(struct file *filp, void *priv, enum v4l2_buf_type type) { - struct stk_camera *dev = priv; + struct stk_camera *dev = video_drvdata(filp); unsigned long flags; int i; stk_stop_stream(dev); @@ -1222,6 +1217,7 @@ static int stk_register_video_device(struct stk_camera *dev) dev->vdev = stk_v4l_data; dev->vdev.debug = debug; dev->vdev.v4l2_dev = &dev->v4l2_dev; + video_set_drvdata(&dev->vdev, dev); err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (err) STK_ERROR("v4l registration failed\n"); -- cgit From 89ea47069cc536f6ae6f428c89bcb960fea3eaff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 09:08:41 -0300 Subject: [media] stk-webcam: add support for control events and prio handling Also correct the first_init static: this should be part of the stk_camera struct. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 27 +++++++++++++++++---------- drivers/media/usb/stkwebcam/stk-webcam.h | 1 + 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 49a4dfd22bf2..c07366619227 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "stk-webcam.h" @@ -603,20 +604,21 @@ static void stk_free_buffers(struct stk_camera *dev) static int v4l_stk_open(struct file *fp) { - static int first_init = 1; /* webcam LED management */ struct stk_camera *dev = video_drvdata(fp); + int err; if (dev == NULL || !is_present(dev)) return -ENXIO; - if (!first_init) + if (!dev->first_init) stk_camera_write_reg(dev, 0x0, 0x24); else - first_init = 0; - - usb_autopm_get_interface(dev->interface); + dev->first_init = 0; - return 0; + err = v4l2_fh_open(fp); + if (!err) + usb_autopm_get_interface(dev->interface); + return err; } static int v4l_stk_release(struct file *fp) @@ -633,8 +635,7 @@ static int v4l_stk_release(struct file *fp) if (is_present(dev)) usb_autopm_put_interface(dev->interface); - - return 0; + return v4l2_fh_release(fp); } static ssize_t v4l_stk_read(struct file *fp, char __user *buf, @@ -701,6 +702,7 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) { struct stk_camera *dev = video_drvdata(fp); + unsigned res = v4l2_ctrl_poll(fp, wait); poll_wait(fp, &dev->wait_frame, wait); @@ -708,9 +710,9 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) return POLLERR; if (!list_empty(&dev->sio_full)) - return POLLIN | POLLRDNORM; + return res | POLLIN | POLLRDNORM; - return 0; + return res; } @@ -1190,6 +1192,9 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { .vidioc_streamoff = stk_vidioc_streamoff, .vidioc_g_parm = stk_vidioc_g_parm, .vidioc_enum_framesizes = stk_vidioc_enum_framesizes, + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static void stk_v4l_dev_release(struct video_device *vd) @@ -1217,6 +1222,7 @@ static int stk_register_video_device(struct stk_camera *dev) dev->vdev = stk_v4l_data; dev->vdev.debug = debug; dev->vdev.v4l2_dev = &dev->v4l2_dev; + set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags); video_set_drvdata(&dev->vdev, dev); err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (err) @@ -1270,6 +1276,7 @@ static int stk_camera_probe(struct usb_interface *interface, spin_lock_init(&dev->spinlock); init_waitqueue_head(&dev->wait_frame); + dev->first_init = 1; /* webcam LED management */ dev->udev = udev; dev->interface = interface; diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 901f0df21bc7..2156320487d8 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -99,6 +99,7 @@ struct stk_camera { struct usb_interface *interface; int webcam_model; struct file *owner; + int first_init; u8 isoc_ep; -- cgit From b27763f0faad374e215a474389ff5949e0b40764 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Feb 2013 14:32:52 -0300 Subject: [media] stk-webcam: fix querycap and simplify s_input Add device_caps support to querycap, fill in bus_info correctly and do not set the version field (let the core handle that). Also simplify the s_input ioctl. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index c07366619227..a00edf3de6bd 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -768,12 +768,15 @@ static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma) static int stk_vidioc_querycap(struct file *filp, void *priv, struct v4l2_capability *cap) { + struct stk_camera *dev = video_drvdata(filp); + strcpy(cap->driver, "stk"); strcpy(cap->card, "stk"); - cap->version = DRIVER_VERSION_NUM; + usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -797,10 +800,7 @@ static int stk_vidioc_g_input(struct file *filp, void *priv, unsigned int *i) static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - if (i != 0) - return -EINVAL; - else - return 0; + return i ? -EINVAL : 0; } static int stk_s_ctrl(struct v4l2_ctrl *ctrl) -- cgit From 8407653f5e2b9805958e0a392c0411ce027a3934 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 09:18:14 -0300 Subject: [media] stk-webcam: zero the priv field of v4l2_pix_format The priv field should be set to 0. In this case the driver abused the priv field for internal housekeeping. Modify the code so priv is no longer used for that purpose. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index a00edf3de6bd..bb524574c838 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -897,11 +897,12 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp, pix_format->bytesperline = 2 * pix_format->width; pix_format->sizeimage = pix_format->bytesperline * pix_format->height; + pix_format->priv = 0; return 0; } -static int stk_vidioc_try_fmt_vid_cap(struct file *filp, - void *priv, struct v4l2_format *fmtd) +static int stk_try_fmt_vid_cap(struct file *filp, + struct v4l2_format *fmtd, int *idx) { int i; switch (fmtd->fmt.pix.pixelformat) { @@ -923,11 +924,13 @@ static int stk_vidioc_try_fmt_vid_cap(struct file *filp, < abs(fmtd->fmt.pix.width - stk_sizes[i].w))) { fmtd->fmt.pix.height = stk_sizes[i-1].h; fmtd->fmt.pix.width = stk_sizes[i-1].w; - fmtd->fmt.pix.priv = i - 1; + if (idx) + *idx = i - 1; } else { fmtd->fmt.pix.height = stk_sizes[i].h; fmtd->fmt.pix.width = stk_sizes[i].w; - fmtd->fmt.pix.priv = i; + if (idx) + *idx = i; } fmtd->fmt.pix.field = V4L2_FIELD_NONE; @@ -938,9 +941,16 @@ static int stk_vidioc_try_fmt_vid_cap(struct file *filp, fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline * fmtd->fmt.pix.height; + fmtd->fmt.pix.priv = 0; return 0; } +static int stk_vidioc_try_fmt_vid_cap(struct file *filp, + void *priv, struct v4l2_format *fmtd) +{ + return stk_try_fmt_vid_cap(filp, fmtd, NULL); +} + static int stk_setup_format(struct stk_camera *dev) { int i = 0; @@ -981,6 +991,7 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { int ret; + int idx; struct stk_camera *dev = video_drvdata(filp); if (dev == NULL) @@ -991,7 +1002,7 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, return -EBUSY; if (dev->owner && dev->owner != filp) return -EBUSY; - ret = stk_vidioc_try_fmt_vid_cap(filp, priv, fmtd); + ret = stk_try_fmt_vid_cap(filp, fmtd, &idx); if (ret) return ret; dev->owner = filp; @@ -999,7 +1010,7 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, dev->vsettings.palette = fmtd->fmt.pix.pixelformat; stk_free_buffers(dev); dev->frame_size = fmtd->fmt.pix.sizeimage; - dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m; + dev->vsettings.mode = stk_sizes[idx].m; stk_initialise(dev); return stk_setup_format(dev); -- cgit From f80daa2d7d7725559908909254d240c433cafc93 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Feb 2013 09:27:32 -0300 Subject: [media] stk-webcam: enable core-locking This makes it possible to switch to unlocked_ioctl. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 24 ++++++++++++++++++++++-- drivers/media/usb/stkwebcam/stk-webcam.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index bb524574c838..2f1a09db1135 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -610,6 +610,8 @@ static int v4l_stk_open(struct file *fp) if (dev == NULL || !is_present(dev)) return -ENXIO; + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; if (!dev->first_init) stk_camera_write_reg(dev, 0x0, 0x24); else @@ -618,6 +620,7 @@ static int v4l_stk_open(struct file *fp) err = v4l2_fh_open(fp); if (!err) usb_autopm_get_interface(dev->interface); + mutex_unlock(&dev->lock); return err; } @@ -625,6 +628,7 @@ static int v4l_stk_release(struct file *fp) { struct stk_camera *dev = video_drvdata(fp); + mutex_lock(&dev->lock); if (dev->owner == fp) { stk_stop_stream(dev); stk_free_buffers(dev); @@ -635,10 +639,11 @@ static int v4l_stk_release(struct file *fp) if (is_present(dev)) usb_autopm_put_interface(dev->interface); + mutex_unlock(&dev->lock); return v4l2_fh_release(fp); } -static ssize_t v4l_stk_read(struct file *fp, char __user *buf, +static ssize_t stk_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos) { int i; @@ -699,6 +704,19 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, return count; } +static ssize_t v4l_stk_read(struct file *fp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct stk_camera *dev = video_drvdata(fp); + int ret; + + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + ret = stk_read(fp, buf, count, f_pos); + mutex_unlock(&dev->lock); + return ret; +} + static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) { struct stk_camera *dev = video_drvdata(fp); @@ -1183,7 +1201,7 @@ static struct v4l2_file_operations v4l_stk_fops = { .read = v4l_stk_read, .poll = v4l_stk_poll, .mmap = v4l_stk_mmap, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { @@ -1231,6 +1249,7 @@ static int stk_register_video_device(struct stk_camera *dev) int err; dev->vdev = stk_v4l_data; + dev->vdev.lock = &dev->lock; dev->vdev.debug = debug; dev->vdev.v4l2_dev = &dev->v4l2_dev; set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags); @@ -1286,6 +1305,7 @@ static int stk_camera_probe(struct usb_interface *interface, dev->v4l2_dev.ctrl_handler = hdl; spin_lock_init(&dev->spinlock); + mutex_init(&dev->lock); init_waitqueue_head(&dev->wait_frame); dev->first_init = 1; /* webcam LED management */ diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 2156320487d8..03550cf60dcd 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -99,6 +99,7 @@ struct stk_camera { struct usb_interface *interface; int webcam_model; struct file *owner; + struct mutex lock; int first_init; u8 isoc_ep; -- cgit From 1b499fe506257369fd6059422989e36c71b99897 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 6 Feb 2013 04:23:01 -0300 Subject: [media] stk-webcam: fix read() handling when reqbufs was already called Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 3 ++- drivers/media/usb/stkwebcam/stk-webcam.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 2f1a09db1135..a8fdbaf34720 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -654,7 +654,7 @@ static ssize_t stk_read(struct file *fp, char __user *buf, if (!is_present(dev)) return -EIO; - if (dev->owner && dev->owner != fp) + if (dev->owner && (!dev->reading || dev->owner != fp)) return -EBUSY; dev->owner = fp; if (!is_streaming(dev)) { @@ -662,6 +662,7 @@ static ssize_t stk_read(struct file *fp, char __user *buf, || stk_allocate_buffers(dev, 3) || stk_start_stream(dev)) return -ENOMEM; + dev->reading = 1; spin_lock_irqsave(&dev->spinlock, flags); for (i = 0; i < dev->n_sbufs; i++) { list_add_tail(&dev->sio_bufs[i].list, &dev->sio_avail); diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h index 03550cf60dcd..9bbfa3d9bfdd 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/media/usb/stkwebcam/stk-webcam.h @@ -118,6 +118,7 @@ struct stk_camera { int frame_size; /* Streaming buffers */ + int reading; unsigned int n_sbufs; struct stk_sio_buffer *sio_bufs; struct list_head sio_avail; -- cgit From f81e372a5d11694b86fc35ded379a441c209b920 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Feb 2013 14:36:41 -0300 Subject: [media] stk-webcam: s_fmt shouldn't grab ownership Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index a8fdbaf34720..45d73e2f3e57 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1019,12 +1019,11 @@ static int stk_vidioc_s_fmt_vid_cap(struct file *filp, return -ENODEV; if (is_streaming(dev)) return -EBUSY; - if (dev->owner && dev->owner != filp) + if (dev->owner) return -EBUSY; ret = stk_try_fmt_vid_cap(filp, fmtd, &idx); if (ret) return ret; - dev->owner = filp; dev->vsettings.palette = fmtd->fmt.pix.pixelformat; stk_free_buffers(dev); -- cgit From 9776e17189d33b0ac9235597460d6a22cf1bc6a7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Feb 2013 14:37:58 -0300 Subject: [media] stk-webcam: implement support for count == 0 when calling REQBUFS The spec specifies that setting count to 0 in v4l2_requestbuffers should result in releasing any streaming resources and the stream ownership. Implement this. Signed-off-by: Hans Verkuil Tested-by: Arvydas Sidorenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stkwebcam/stk-webcam.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 45d73e2f3e57..c43c8d32be40 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1046,6 +1046,13 @@ static int stk_vidioc_reqbufs(struct file *filp, if (is_streaming(dev) || (dev->owner && dev->owner != filp)) return -EBUSY; + stk_free_buffers(dev); + if (rb->count == 0) { + stk_camera_write_reg(dev, 0x0, 0x49); /* turn off the LED */ + unset_initialised(dev); + dev->owner = NULL; + return 0; + } dev->owner = filp; /*FIXME If they ask for zero, we must stop streaming and free */ -- cgit From 6aa69f99b2ecc7f9b387fcf22d30e6601b58819f Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Fri, 25 Jan 2013 06:29:57 -0300 Subject: [media] vb2: Add support for non monotonic timestamps Not all drivers use monotonic timestamps. This patch adds a way to set the timestamp type per every queue. In addition, set proper timestamp type in drivers that I am sure that use either MONOTONIC or COPY timestamps. Other drivers will correctly report UNKNOWN timestamp type instead of assuming that all drivers use monotonic timestamps. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Reviewed-by: Sylwester Nawrocki Acked-by: Hans Verkuil Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/bfin_capture.c | 1 + drivers/media/platform/davinci/vpbe_display.c | 1 + drivers/media/platform/davinci/vpif_capture.c | 1 + drivers/media/platform/davinci/vpif_display.c | 1 + drivers/media/platform/s3c-camif/camif-capture.c | 1 + drivers/media/platform/s5p-fimc/fimc-capture.c | 1 + drivers/media/platform/s5p-fimc/fimc-lite.c | 1 + drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 ++ drivers/media/platform/soc_camera/atmel-isi.c | 1 + drivers/media/platform/soc_camera/mx2_camera.c | 1 + drivers/media/platform/soc_camera/mx3_camera.c | 1 + drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 1 + drivers/media/platform/vivi.c | 1 + drivers/media/usb/pwc/pwc-if.c | 1 + drivers/media/usb/stk1160/stk1160-v4l.c | 1 + drivers/media/usb/uvc/uvc_queue.c | 1 + drivers/media/v4l2-core/videobuf2-core.c | 8 ++++++-- include/media/videobuf2-core.h | 1 + 18 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 5f209d5810dc..8ffe42aabd85 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -1029,6 +1029,7 @@ static int bcap_probe(struct platform_device *pdev) q->buf_struct_size = sizeof(struct bcap_buffer); q->ops = &bcap_video_qops; q->mem_ops = &vb2_dma_contig_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; vb2_queue_init(q); diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 5e6b0cab514b..9f9f2c1a073f 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1404,6 +1404,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, q->ops = &video_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct vpbe_disp_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) { diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 5892d2bc8eee..1943e41f3866 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1035,6 +1035,7 @@ static int vpif_reqbufs(struct file *file, void *priv, q->ops = &video_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct vpif_cap_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) { diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index dd249c96126d..5477c2cb8653 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1001,6 +1001,7 @@ static int vpif_reqbufs(struct file *file, void *priv, q->ops = &video_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct vpif_disp_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) { diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index a55793c3d811..e91f350929eb 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -1153,6 +1153,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct camif_buffer); q->drv_priv = vp; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index f553cc2a8ee8..87b68420f771 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1797,6 +1797,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q->ops = &fimc_capture_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct fimc_vid_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c index bfc4206935c8..47fbf7bcf608 100644 --- a/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -1325,6 +1325,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret < 0) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index e84703c314ce..92c6bf11af74 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -804,6 +804,7 @@ static int s5p_mfc_open(struct file *file) goto err_queue_init; } q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(q); if (ret) { mfc_err("Failed to initialize videobuf2 queue(capture)\n"); @@ -825,6 +826,7 @@ static int s5p_mfc_open(struct file *file) goto err_queue_init; } q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(q); if (ret) { mfc_err("Failed to initialize videobuf2 queue(output)\n"); diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 82dbf99d347c..c314ff9b98dc 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -514,6 +514,7 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, q->buf_struct_size = sizeof(struct frame_buffer); q->ops = &isi_video_qops; q->mem_ops = &vb2_dma_contig_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; return vb2_queue_init(q); } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ffba7d91f413..048c26a27c34 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -797,6 +797,7 @@ static int mx2_camera_init_videobuf(struct vb2_queue *q, q->ops = &mx2_videobuf_ops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct mx2_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; return vb2_queue_init(q); } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index f5cbb92db545..2c3bd69fb38c 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -455,6 +455,7 @@ static int mx3_camera_init_videobuf(struct vb2_queue *q, q->ops = &mx3_videobuf_ops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct mx3_camera_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; return vb2_queue_init(q); } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index bb08a46432f4..973e72b24fa8 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -2026,6 +2026,7 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q, q->ops = &sh_mobile_ceu_videobuf_ops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer); + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; return vb2_queue_init(q); } diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c index 8a33a712f480..c46d2e8677a5 100644 --- a/drivers/media/platform/vivi.c +++ b/drivers/media/platform/vivi.c @@ -1429,6 +1429,7 @@ static int __init vivi_create_instance(int inst) q->buf_struct_size = sizeof(struct vivi_buffer); q->ops = &vivi_video_qops; q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(q); if (ret) diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index 5ec15cb1ed26..77bbf7889659 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c @@ -1001,6 +1001,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf); pdev->vb_queue.ops = &pwc_vb_queue_ops; pdev->vb_queue.mem_ops = &vb2_vmalloc_memops; + pdev->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; rc = vb2_queue_init(&pdev->vb_queue); if (rc < 0) { PWC_ERROR("Oops, could not initialize vb2 queue.\n"); diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index 6694f9e2ca57..5307a63e378f 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -687,6 +687,7 @@ int stk1160_vb2_setup(struct stk1160 *dev) q->buf_struct_size = sizeof(struct stk1160_buffer); q->ops = &stk1160_video_qops; q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; rc = vb2_queue_init(q); if (rc < 0) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 6c233a54ce40..cd962be860ca 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -149,6 +149,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, queue->queue.buf_struct_size = sizeof(struct uvc_buffer); queue->queue.ops = &uvc_queue_qops; queue->queue.mem_ops = &vb2_vmalloc_memops; + queue->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ret = vb2_queue_init(&queue->queue); if (ret) return ret; diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index db1235dcb328..be0448161c60 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -403,7 +403,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) * Clear any buffer state related flags. */ b->flags &= ~V4L2_BUFFER_MASK_FLAGS; - b->flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + b->flags |= q->timestamp_type; switch (vb->state) { case VB2_BUF_STATE_QUEUED: @@ -2039,9 +2039,13 @@ int vb2_queue_init(struct vb2_queue *q) WARN_ON(!q->type) || WARN_ON(!q->io_modes) || WARN_ON(!q->ops->queue_setup) || - WARN_ON(!q->ops->buf_queue)) + WARN_ON(!q->ops->buf_queue) || + WARN_ON(q->timestamp_type & ~V4L2_BUF_FLAG_TIMESTAMP_MASK)) return -EINVAL; + /* Warn that the driver should choose an appropriate timestamp type */ + WARN_ON(q->timestamp_type == V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN); + INIT_LIST_HEAD(&q->queued_list); INIT_LIST_HEAD(&q->done_list); spin_lock_init(&q->done_lock); diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 9cfd4ee9e56f..a2d427450780 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -326,6 +326,7 @@ struct vb2_queue { const struct vb2_mem_ops *mem_ops; void *drv_priv; unsigned int buf_struct_size; + u32 timestamp_type; /* private: internal use only */ enum v4l2_memory memory; -- cgit From 69b95a3a80b44ebb71bf153e79bcb8580e1d3de5 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 7 Feb 2013 18:36:12 -0300 Subject: [media] s3c-camif: Fail on insufficient number of allocated buffers Ensure the driver gets always at least its minimum required number of buffers allocated by checking actual number of allocated buffers in vb2_reqbufs(). And free any partially allocated buffer queue with signaling an error to user space. Without this patch applications may wait forever to dequeue a filled buffer, because the hardware didn't even start after VIDIOC_STREAMON, VIDIOC_QBUF calls, due to insufficient number of empty buffers. Reported-by: Alexander Nestorov Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-capture.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index e91f350929eb..70438a0f62ae 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -934,12 +934,19 @@ static int s3c_camif_reqbufs(struct file *file, void *priv, vp->owner = NULL; ret = vb2_reqbufs(&vp->vb_queue, rb); - if (!ret) { - vp->reqbufs_count = rb->count; - if (vp->owner == NULL && rb->count > 0) - vp->owner = priv; + if (ret < 0) + return ret; + + if (rb->count && rb->count < CAMIF_REQ_BUFS_MIN) { + rb->count = 0; + vb2_reqbufs(&vp->vb_queue, rb); + ret = -ENOMEM; } + vp->reqbufs_count = rb->count; + if (vp->owner == NULL && rb->count > 0) + vp->owner = priv; + return ret; } -- cgit From 5ce60d790a246c4c32043ac9b142615466479728 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 6 Feb 2013 01:29:43 -0300 Subject: [media] s5p-g2d: Add DT based discovery support This patch adds device tree based discovery support to the G2D driver. Signed-off-by: Sachin Kamat Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-g2d/g2d.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index aaaf276a5a6c..14d663dacdbd 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -695,11 +696,14 @@ static struct v4l2_m2m_ops g2d_m2m_ops = { .unlock = g2d_unlock, }; +static const struct of_device_id exynos_g2d_match[]; + static int g2d_probe(struct platform_device *pdev) { struct g2d_dev *dev; struct video_device *vfd; struct resource *res; + const struct of_device_id *of_id; int ret = 0; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); @@ -794,7 +798,17 @@ static int g2d_probe(struct platform_device *pdev) } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; - dev->variant = g2d_get_drv_data(pdev); + + if (!pdev->dev.of_node) { + dev->variant = g2d_get_drv_data(pdev); + } else { + of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node); + if (!of_id) { + ret = -ENODEV; + goto unreg_video_dev; + } + dev->variant = (struct g2d_variant *)of_id->data; + } return 0; @@ -835,13 +849,25 @@ static int g2d_remove(struct platform_device *pdev) } static struct g2d_variant g2d_drvdata_v3x = { - .hw_rev = TYPE_G2D_3X, + .hw_rev = TYPE_G2D_3X, /* Revision 3.0 for S5PV210 and Exynos4210 */ }; static struct g2d_variant g2d_drvdata_v4x = { .hw_rev = TYPE_G2D_4X, /* Revision 4.1 for Exynos4X12 and Exynos5 */ }; +static const struct of_device_id exynos_g2d_match[] = { + { + .compatible = "samsung,s5pv210-g2d", + .data = &g2d_drvdata_v3x, + }, { + .compatible = "samsung,exynos4212-g2d", + .data = &g2d_drvdata_v4x, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, exynos_g2d_match); + static struct platform_device_id g2d_driver_ids[] = { { .name = "s5p-g2d", @@ -861,6 +887,7 @@ static struct platform_driver g2d_pdrv = { .driver = { .name = G2D_NAME, .owner = THIS_MODULE, + .of_match_table = exynos_g2d_match, }, }; -- cgit From c1f07ab2b3e7a1a0ec8152dc30ab5fec346bf367 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 11 Feb 2013 06:31:12 -0300 Subject: [media] gspca_sonixj: Convert to the control framework Signed-off-by: Hans Verkuil Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sonixj.c | 545 ++++++++++++--------------------------- 1 file changed, 164 insertions(+), 381 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index 671d0c6dece3..8246e1dc3e9d 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c @@ -31,32 +31,26 @@ MODULE_AUTHOR("Jean-François Moine "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); -/* controls */ -enum e_ctrl { - BRIGHTNESS, - CONTRAST, - COLORS, - BLUE, - RED, - GAMMA, - EXPOSURE, - AUTOGAIN, - GAIN, - HFLIP, - VFLIP, - SHARPNESS, - ILLUM, - FREQ, - NCTRLS /* number of controls */ -}; - /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - struct gspca_ctrl ctrls[NCTRLS]; - atomic_t avg_lum; + struct v4l2_ctrl *brightness; + struct v4l2_ctrl *contrast; + struct v4l2_ctrl *saturation; + struct { /* red/blue balance control cluster */ + struct v4l2_ctrl *red_bal; + struct v4l2_ctrl *blue_bal; + }; + struct { /* hflip/vflip control cluster */ + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *hflip; + }; + struct v4l2_ctrl *gamma; + struct v4l2_ctrl *illum; + struct v4l2_ctrl *sharpness; + struct v4l2_ctrl *freq; u32 exposure; struct work_struct work; @@ -127,283 +121,6 @@ static void qual_upd(struct work_struct *work); #define SEN_CLK_EN 0x20 /* enable sensor clock */ #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ -/* V4L2 controls supported by the driver */ -static void setbrightness(struct gspca_dev *gspca_dev); -static void setcontrast(struct gspca_dev *gspca_dev); -static void setcolors(struct gspca_dev *gspca_dev); -static void setredblue(struct gspca_dev *gspca_dev); -static void setgamma(struct gspca_dev *gspca_dev); -static void setexposure(struct gspca_dev *gspca_dev); -static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); -static void setgain(struct gspca_dev *gspca_dev); -static void sethvflip(struct gspca_dev *gspca_dev); -static void setsharpness(struct gspca_dev *gspca_dev); -static void setillum(struct gspca_dev *gspca_dev); -static void setfreq(struct gspca_dev *gspca_dev); - -static const struct ctrl sd_ctrls[NCTRLS] = { -[BRIGHTNESS] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x80, - }, - .set_control = setbrightness - }, -[CONTRAST] = { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, -#define CONTRAST_MAX 127 - .maximum = CONTRAST_MAX, - .step = 1, - .default_value = 20, - }, - .set_control = setcontrast - }, -[COLORS] = { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 40, - .step = 1, -#define COLORS_DEF 25 - .default_value = COLORS_DEF, - }, - .set_control = setcolors - }, -[BLUE] = { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Balance", - .minimum = 24, - .maximum = 40, - .step = 1, - .default_value = 32, - }, - .set_control = setredblue - }, -[RED] = { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Balance", - .minimum = 24, - .maximum = 40, - .step = 1, - .default_value = 32, - }, - .set_control = setredblue - }, -[GAMMA] = { - { - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0, - .maximum = 40, - .step = 1, -#define GAMMA_DEF 20 - .default_value = GAMMA_DEF, - }, - .set_control = setgamma - }, -[EXPOSURE] = { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 500, - .maximum = 1500, - .step = 1, - .default_value = 1024 - }, - .set_control = setexposure - }, -[AUTOGAIN] = { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Gain", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = sd_setautogain, - }, -[GAIN] = { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 4, - .maximum = 49, - .step = 1, - .default_value = 15 - }, - .set_control = setgain - }, -[HFLIP] = { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = sethvflip - }, -[VFLIP] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vflip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = sethvflip - }, -[SHARPNESS] = { - { - .id = V4L2_CID_SHARPNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Sharpness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 90, - }, - .set_control = setsharpness - }, -[ILLUM] = { - { - .id = V4L2_CID_ILLUMINATORS_1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Illuminator / infrared", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = setillum - }, -/* ov7630/ov7648/ov7660 only */ -[FREQ] = { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light frequency filter", - .minimum = 0, - .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ - .step = 1, - .default_value = 1, - }, - .set_control = setfreq - }, -}; - -/* table of the disabled controls */ -static const __u32 ctrl_dis[] = { -[SENSOR_ADCM1700] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_GC0307] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_HV7131R] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << FREQ), - -[SENSOR_MI0360] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MI0360B] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MO4000] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MT9V111] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_OM6802] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_OV7630] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP), - -[SENSOR_OV7648] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP), - -[SENSOR_OV7660] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP), - -[SENSOR_PO1030] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_PO2030N] = (1 << FREQ), - -[SENSOR_SOI768] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_SP80708] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), -}; - static const struct v4l2_pix_format cif_mode[] = { {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, @@ -1822,7 +1539,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_mode); } cam->npkt = 24; /* 24 packets per ISOC message */ - cam->ctrls = sd->ctrls; sd->ag_cnt = -1; sd->quality = QUALITY_DEF; @@ -1888,9 +1604,6 @@ static int sd_init(struct gspca_dev *gspca_dev) break; } - if (sd->sensor == SENSOR_OM6802) - sd->ctrls[SHARPNESS].def = 0x10; - /* Note we do not disable the sensor clock here (power saving mode), as that also disables the button on the cam. */ reg_w1(gspca_dev, 0xf1, 0x00); @@ -1899,13 +1612,92 @@ static int sd_init(struct gspca_dev *gspca_dev) sn9c1xx = sn_tb[sd->sensor]; sd->i2c_addr = sn9c1xx[9]; - gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; - if (!(sd->flags & F_ILLUM)) - gspca_dev->ctrl_dis |= (1 << ILLUM); - return gspca_dev->usb_err; } +static int sd_s_ctrl(struct v4l2_ctrl *ctrl); + +static const struct v4l2_ctrl_ops sd_ctrl_ops = { + .s_ctrl = sd_s_ctrl, +}; + +/* this function is called at probe time */ +static int sd_init_controls(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; + + gspca_dev->vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 14); + + sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); +#define CONTRAST_MAX 127 + sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20); +#define COLORS_DEF 25 + sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF); + sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_RED_BALANCE, 24, 40, 1, 32); + sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32); +#define GAMMA_DEF 20 + sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF); + + if (sd->sensor == SENSOR_OM6802) + sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_SHARPNESS, 0, 255, 1, 16); + else + sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_SHARPNESS, 0, 255, 1, 90); + + if (sd->flags & F_ILLUM) + sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); + + if (sd->sensor == SENSOR_PO2030N) { + gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_EXPOSURE, 500, 1500, 1, 1024); + gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_GAIN, 4, 49, 1, 15); + sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + } + + if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 && + sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 && + sd->sensor != SENSOR_SP80708) + gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + + if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 || + sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N) + sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + + if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || + sd->sensor == SENSOR_OV7660) + sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, + V4L2_CID_POWER_LINE_FREQUENCY, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(2, &sd->red_bal); + if (sd->sensor == SENSOR_PO2030N) { + v4l2_ctrl_cluster(2, &sd->vflip); + v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); + } + + return 0; +} + static u32 expo_adjust(struct gspca_dev *gspca_dev, u32 expo) { @@ -2014,10 +1806,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int expo; - int brightness; + int brightness = sd->brightness->val; u8 k2; - brightness = sd->ctrls[BRIGHTNESS].val; k2 = (brightness - 0x80) >> 2; switch (sd->sensor) { case SENSOR_ADCM1700: @@ -2064,7 +1855,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) u8 k2; u8 contrast[6]; - k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1) + k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1) + 37; /* 37..73 */ contrast[0] = (k2 + 1) / 2; /* red */ contrast[1] = 0; @@ -2090,7 +1881,7 @@ static void setcolors(struct gspca_dev *gspca_dev) 60, -51, -9 /* VR VG VB */ }; - colors = sd->ctrls[COLORS].val; + colors = sd->saturation->val; if (sd->sensor == SENSOR_MI0360B) uv = uv_mi0360b; else @@ -2112,14 +1903,14 @@ static void setredblue(struct gspca_dev *gspca_dev) {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; /* 0x40 = normal value = gain x 1 */ - rg1b[3] = sd->ctrls[RED].val * 2; - rg1b[5] = sd->ctrls[BLUE].val * 2; + rg1b[3] = sd->red_bal->val * 2; + rg1b[5] = sd->blue_bal->val * 2; i2c_w8(gspca_dev, rg1b); return; } - reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); + reg_w1(gspca_dev, 0x05, sd->red_bal->val); /* reg_w1(gspca_dev, 0x07, 32); */ - reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); + reg_w1(gspca_dev, 0x06, sd->blue_bal->val); } static void setgamma(struct gspca_dev *gspca_dev) @@ -2153,7 +1944,7 @@ static void setgamma(struct gspca_dev *gspca_dev) break; } - val = sd->ctrls[GAMMA].val; + val = sd->gamma->val; for (i = 0; i < sizeof gamma; i++) gamma[i] = gamma_base[i] + delta[i] * (val - GAMMA_DEF) / 32; @@ -2168,11 +1959,11 @@ static void setexposure(struct gspca_dev *gspca_dev) u8 rexpo[] = /* 1a: expo H, 1b: expo M */ {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; - rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; + rexpo[3] = gspca_dev->exposure->val >> 8; i2c_w8(gspca_dev, rexpo); msleep(6); rexpo[2] = 0x1b; - rexpo[3] = sd->ctrls[EXPOSURE].val; + rexpo[3] = gspca_dev->exposure->val; i2c_w8(gspca_dev, rexpo); } } @@ -2181,8 +1972,6 @@ static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) - return; switch (sd->sensor) { case SENSOR_OV7630: case SENSOR_OV7648: { @@ -2192,13 +1981,13 @@ static void setautogain(struct gspca_dev *gspca_dev) comb = 0xc0; else comb = 0xa0; - if (sd->ctrls[AUTOGAIN].val) + if (gspca_dev->autogain->val) comb |= 0x03; i2c_w1(&sd->gspca_dev, 0x13, comb); return; } } - if (sd->ctrls[AUTOGAIN].val) + if (gspca_dev->autogain->val) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; @@ -2212,7 +2001,7 @@ static void setgain(struct gspca_dev *gspca_dev) u8 rgain[] = /* 15: gain */ {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; - rgain[3] = sd->ctrls[GAIN].val; + rgain[3] = gspca_dev->gain->val; i2c_w8(gspca_dev, rgain); } } @@ -2225,19 +2014,19 @@ static void sethvflip(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_HV7131R: comn = 0x18; /* clkdiv = 1, ablcen = 1 */ - if (sd->ctrls[VFLIP].val) + if (sd->vflip->val) comn |= 0x01; i2c_w1(gspca_dev, 0x01, comn); /* sctra */ break; case SENSOR_OV7630: comn = 0x02; - if (!sd->ctrls[VFLIP].val) + if (!sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; case SENSOR_OV7648: comn = 0x06; - if (sd->ctrls[VFLIP].val) + if (sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; @@ -2251,9 +2040,9 @@ static void sethvflip(struct gspca_dev *gspca_dev) * bit3-0: X */ comn = 0x0a; - if (sd->ctrls[HFLIP].val) + if (sd->hflip->val) comn |= 0x80; - if (sd->ctrls[VFLIP].val) + if (sd->vflip->val) comn |= 0x40; i2c_w1(&sd->gspca_dev, 0x1e, comn); break; @@ -2264,23 +2053,21 @@ static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); + reg_w1(gspca_dev, 0x99, sd->sharpness->val); } static void setillum(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (gspca_dev->ctrl_dis & (1 << ILLUM)) - return; switch (sd->sensor) { case SENSOR_ADCM1700: reg_w1(gspca_dev, 0x02, /* gpio */ - sd->ctrls[ILLUM].val ? 0x64 : 0x60); + sd->illum->val ? 0x64 : 0x60); break; case SENSOR_MT9V111: reg_w1(gspca_dev, 0x02, - sd->ctrls[ILLUM].val ? 0x77 : 0x74); + sd->illum->val ? 0x77 : 0x74); /* should have been: */ /* 0x55 : 0x54); * 370i */ /* 0x66 : 0x64); * Clip */ @@ -2292,13 +2079,11 @@ static void setfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (gspca_dev->ctrl_dis & (1 << FREQ)) - return; if (sd->sensor == SENSOR_OV7660) { u8 com8; com8 = 0xdf; /* auto gain/wb/expo */ - switch (sd->ctrls[FREQ].val) { + switch (sd->freq->val) { case 0: /* Banding filter disabled */ i2c_w1(gspca_dev, 0x13, com8 | 0x20); break; @@ -2326,7 +2111,7 @@ static void setfreq(struct gspca_dev *gspca_dev) break; } - switch (sd->ctrls[FREQ].val) { + switch (sd->freq->val) { case 0: /* Banding filter disabled */ break; case 1: /* 50 hz (filter on and framerate adj) */ @@ -2698,17 +2483,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->reg01 = reg01; sd->reg17 = reg17; - sethvflip(gspca_dev); - setbrightness(gspca_dev); - setcontrast(gspca_dev); - setcolors(gspca_dev); - setautogain(gspca_dev); - if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { - setexposure(gspca_dev); - setgain(gspca_dev); - } - setfreq(gspca_dev); - sd->pktsz = sd->npkt = 0; sd->nchg = sd->short_mark = 0; sd->work_thread = create_singlethread_workqueue(MODULE_NAME); @@ -2803,9 +2577,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } } -#define WANT_REGULAR_AUTOGAIN -#include "autogain_functions.h" - static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -2825,7 +2596,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) PDEBUG(D_FRAM, "mean lum %d", delta); if (sd->sensor == SENSOR_PO2030N) { - auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, + gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta, 15, 1024); return; } @@ -3042,39 +2813,53 @@ marker_found: } } -static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +static int sd_s_ctrl(struct v4l2_ctrl *ctrl) { - struct sd *sd = (struct sd *) gspca_dev; + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - sd->ctrls[AUTOGAIN].val = val; - if (val) - gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); - else - gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); - if (gspca_dev->streaming) - setautogain(gspca_dev); - return gspca_dev->usb_err; -} + gspca_dev->usb_err = 0; -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - switch (menu->id) { + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + setbrightness(gspca_dev); + break; + case V4L2_CID_CONTRAST: + setcontrast(gspca_dev); + break; + case V4L2_CID_SATURATION: + setcolors(gspca_dev); + break; + case V4L2_CID_RED_BALANCE: + setredblue(gspca_dev); + break; + case V4L2_CID_GAMMA: + setgamma(gspca_dev); + break; + case V4L2_CID_AUTOGAIN: + setautogain(gspca_dev); + setexposure(gspca_dev); + setgain(gspca_dev); + break; + case V4L2_CID_VFLIP: + sethvflip(gspca_dev); + break; + case V4L2_CID_SHARPNESS: + setsharpness(gspca_dev); + break; + case V4L2_CID_ILLUMINATORS_1: + setillum(gspca_dev); + break; case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - } + setfreq(gspca_dev); break; + default: + return -EINVAL; } - return -EINVAL; + return gspca_dev->usb_err; } #if IS_ENABLED(CONFIG_INPUT) @@ -3099,16 +2884,14 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = NCTRLS, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, - .querymenu = sd_querymenu, #if IS_ENABLED(CONFIG_INPUT) .int_pkt_scan = sd_int_pkt_scan, #endif -- cgit From 676fdd856b22fa384b09bdad3c81d8117feadbe6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 19 Feb 2013 07:19:17 -0300 Subject: [media] gscpa_gl860: Convert to the control framework Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/gl860/gl860.c | 222 ++++++++++++++++++---------------- 1 file changed, 119 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c index ced3b71f14e5..96d9c28a748c 100644 --- a/drivers/media/usb/gspca/gl860/gl860.c +++ b/drivers/media/usb/gspca/gl860/gl860.c @@ -58,115 +58,135 @@ MODULE_PARM_DESC(sensor, /*============================ webcam controls =============================*/ -/* Functions to get and set a control value */ -#define SD_SETGET(thename) \ -static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\ -{\ - struct sd *sd = (struct sd *) gspca_dev;\ -\ - sd->vcur.thename = val;\ - if (gspca_dev->streaming)\ - sd->waitSet = 1;\ - return 0;\ -} \ -static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\ -{\ - struct sd *sd = (struct sd *) gspca_dev;\ -\ - *val = sd->vcur.thename;\ - return 0;\ -} +static int sd_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); + struct sd *sd = (struct sd *) gspca_dev; -SD_SETGET(mirror) -SD_SETGET(flip) -SD_SETGET(AC50Hz) -SD_SETGET(backlight) -SD_SETGET(brightness) -SD_SETGET(gamma) -SD_SETGET(hue) -SD_SETGET(saturation) -SD_SETGET(sharpness) -SD_SETGET(whitebal) -SD_SETGET(contrast) - -#define GL860_NCTRLS 11 - -/* control table */ -static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS]; -static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS]; -static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS]; -static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS]; - -#define SET_MY_CTRL(theid, \ - thetype, thelabel, thename) \ - if (sd->vmax.thename != 0) {\ - sd_ctrls[nCtrls].qctrl.id = theid;\ - sd_ctrls[nCtrls].qctrl.type = thetype;\ - strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\ - sd_ctrls[nCtrls].qctrl.minimum = 0;\ - sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\ - sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\ - sd_ctrls[nCtrls].qctrl.step = \ - (sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\ - sd_ctrls[nCtrls].set = sd_set_##thename;\ - sd_ctrls[nCtrls].get = sd_get_##thename;\ - nCtrls++;\ + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + sd->vcur.brightness = ctrl->val; + break; + case V4L2_CID_CONTRAST: + sd->vcur.contrast = ctrl->val; + break; + case V4L2_CID_SATURATION: + sd->vcur.saturation = ctrl->val; + break; + case V4L2_CID_HUE: + sd->vcur.hue = ctrl->val; + break; + case V4L2_CID_GAMMA: + sd->vcur.gamma = ctrl->val; + break; + case V4L2_CID_HFLIP: + sd->vcur.mirror = ctrl->val; + break; + case V4L2_CID_VFLIP: + sd->vcur.flip = ctrl->val; + break; + case V4L2_CID_POWER_LINE_FREQUENCY: + sd->vcur.AC50Hz = ctrl->val; + break; + case V4L2_CID_WHITE_BALANCE_TEMPERATURE: + sd->vcur.whitebal = ctrl->val; + break; + case V4L2_CID_SHARPNESS: + sd->vcur.sharpness = ctrl->val; + break; + case V4L2_CID_BACKLIGHT_COMPENSATION: + sd->vcur.backlight = ctrl->val; + break; + default: + return -EINVAL; } -static int gl860_build_control_table(struct gspca_dev *gspca_dev) + if (gspca_dev->streaming) + sd->waitSet = 1; + + return 0; +} + +static const struct v4l2_ctrl_ops sd_ctrl_ops = { + .s_ctrl = sd_s_ctrl, +}; + +static int sd_init_controls(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct ctrl *sd_ctrls; - int nCtrls = 0; - - if (_MI1320_) - sd_ctrls = sd_ctrls_mi1320; - else if (_MI2020_) - sd_ctrls = sd_ctrls_mi2020; - else if (_OV2640_) - sd_ctrls = sd_ctrls_ov2640; - else if (_OV9655_) - sd_ctrls = sd_ctrls_ov9655; - else - return 0; - - memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl)); - - SET_MY_CTRL(V4L2_CID_BRIGHTNESS, - V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness) - SET_MY_CTRL(V4L2_CID_SHARPNESS, - V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness) - SET_MY_CTRL(V4L2_CID_CONTRAST, - V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast) - SET_MY_CTRL(V4L2_CID_GAMMA, - V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma) - SET_MY_CTRL(V4L2_CID_HUE, - V4L2_CTRL_TYPE_INTEGER, "Palette", hue) - SET_MY_CTRL(V4L2_CID_SATURATION, - V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation) - SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE, - V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal) - SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION, - V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight) - - SET_MY_CTRL(V4L2_CID_HFLIP, - V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror) - SET_MY_CTRL(V4L2_CID_VFLIP, - V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip) - SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz) - - return nCtrls; + struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; + + gspca_dev->vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 11); + + if (sd->vmax.brightness) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS, + 0, sd->vmax.brightness, 1, + sd->vcur.brightness); + + if (sd->vmax.contrast) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, + 0, sd->vmax.contrast, 1, + sd->vcur.contrast); + + if (sd->vmax.saturation) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION, + 0, sd->vmax.saturation, 1, + sd->vcur.saturation); + + if (sd->vmax.hue) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE, + 0, sd->vmax.hue, 1, sd->vcur.hue); + + if (sd->vmax.gamma) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, + 0, sd->vmax.gamma, 1, sd->vcur.gamma); + + if (sd->vmax.mirror) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HFLIP, + 0, sd->vmax.mirror, 1, sd->vcur.mirror); + + if (sd->vmax.flip) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, + 0, sd->vmax.flip, 1, sd->vcur.flip); + + if (sd->vmax.AC50Hz) + v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, + V4L2_CID_POWER_LINE_FREQUENCY, + sd->vmax.AC50Hz, 0, sd->vcur.AC50Hz); + + if (sd->vmax.whitebal) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_WHITE_BALANCE_TEMPERATURE, + 0, sd->vmax.whitebal, 1, sd->vcur.whitebal); + + if (sd->vmax.sharpness) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS, + 0, sd->vmax.sharpness, 1, + sd->vcur.sharpness); + + if (sd->vmax.backlight) + v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_BACKLIGHT_COMPENSATION, + 0, sd->vmax.backlight, 1, + sd->vcur.backlight); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + return 0; } /*==================== sud-driver structure initialisation =================*/ static const struct sd_desc sd_desc_mi1320 = { .name = MODULE_NAME, - .ctrls = sd_ctrls_mi1320, - .nctrls = GL860_NCTRLS, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .isoc_init = sd_isoc_init, .start = sd_start, .stop0 = sd_stop0, @@ -176,10 +196,9 @@ static const struct sd_desc sd_desc_mi1320 = { static const struct sd_desc sd_desc_mi2020 = { .name = MODULE_NAME, - .ctrls = sd_ctrls_mi2020, - .nctrls = GL860_NCTRLS, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .isoc_init = sd_isoc_init, .start = sd_start, .stop0 = sd_stop0, @@ -189,10 +208,9 @@ static const struct sd_desc sd_desc_mi2020 = { static const struct sd_desc sd_desc_ov2640 = { .name = MODULE_NAME, - .ctrls = sd_ctrls_ov2640, - .nctrls = GL860_NCTRLS, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .isoc_init = sd_isoc_init, .start = sd_start, .stop0 = sd_stop0, @@ -202,10 +220,9 @@ static const struct sd_desc sd_desc_ov2640 = { static const struct sd_desc sd_desc_ov9655 = { .name = MODULE_NAME, - .ctrls = sd_ctrls_ov9655, - .nctrls = GL860_NCTRLS, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .isoc_init = sd_isoc_init, .start = sd_start, .stop0 = sd_stop0, @@ -371,7 +388,6 @@ static int sd_config(struct gspca_dev *gspca_dev, dev_init_settings(gspca_dev); if (AC50Hz != 0xff) ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz; - gl860_build_control_table(gspca_dev); return 0; } -- cgit From c84e412f6f3be6ba262b1b9691ce57593b576c90 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 19 Feb 2013 14:57:03 -0300 Subject: [media] gscpa_m5602: Convert to the control framework Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/m5602/m5602_bridge.h | 27 +- drivers/media/usb/gspca/m5602/m5602_core.c | 16 +- drivers/media/usb/gspca/m5602/m5602_mt9m111.c | 388 ++++++---------------- drivers/media/usb/gspca/m5602/m5602_mt9m111.h | 2 + drivers/media/usb/gspca/m5602/m5602_ov7660.c | 300 ++++------------- drivers/media/usb/gspca/m5602/m5602_ov7660.h | 3 + drivers/media/usb/gspca/m5602/m5602_ov9650.c | 445 ++++++------------------- drivers/media/usb/gspca/m5602/m5602_ov9650.h | 2 + drivers/media/usb/gspca/m5602/m5602_po1030.c | 452 ++++++-------------------- drivers/media/usb/gspca/m5602/m5602_po1030.h | 2 + drivers/media/usb/gspca/m5602/m5602_s5k4aa.c | 338 +++++-------------- drivers/media/usb/gspca/m5602/m5602_s5k4aa.h | 2 + drivers/media/usb/gspca/m5602/m5602_s5k83a.c | 290 ++++------------- drivers/media/usb/gspca/m5602/m5602_s5k83a.h | 9 +- drivers/media/usb/gspca/m5602/m5602_sensor.h | 3 + 15 files changed, 569 insertions(+), 1710 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/m5602/m5602_bridge.h b/drivers/media/usb/gspca/m5602/m5602_bridge.h index 51af3ee3ab85..19eb1a64f9d6 100644 --- a/drivers/media/usb/gspca/m5602/m5602_bridge.h +++ b/drivers/media/usb/gspca/m5602/m5602_bridge.h @@ -136,16 +136,33 @@ struct sd { /* A pointer to the currently connected sensor */ const struct m5602_sensor *sensor; - struct sd_desc *desc; - - /* Sensor private data */ - void *sensor_priv; - /* The current frame's id, used to detect frame boundaries */ u8 frame_id; /* The current frame count */ u32 frame_count; + + /* Camera rotation polling thread for "flipable" cams */ + struct task_struct *rotation_thread; + + struct { /* auto-white-bal + green/red/blue balance control cluster */ + struct v4l2_ctrl *auto_white_bal; + struct v4l2_ctrl *red_bal; + struct v4l2_ctrl *blue_bal; + struct v4l2_ctrl *green_bal; + }; + struct { /* autoexpo / expo cluster */ + struct v4l2_ctrl *autoexpo; + struct v4l2_ctrl *expo; + }; + struct { /* autogain / gain cluster */ + struct v4l2_ctrl *autogain; + struct v4l2_ctrl *gain; + }; + struct { /* hflip/vflip cluster */ + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + }; }; int m5602_read_bridge( diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c index ed22638978ce..907a968f474d 100644 --- a/drivers/media/usb/gspca/m5602/m5602_core.c +++ b/drivers/media/usb/gspca/m5602/m5602_core.c @@ -252,6 +252,16 @@ static int m5602_init(struct gspca_dev *gspca_dev) return err; } +static int m5602_init_controls(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (!sd->sensor->init_controls) + return 0; + + return sd->sensor->init_controls(sd); +} + static int m5602_start_transfer(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -336,11 +346,12 @@ static void m5602_stop_transfer(struct gspca_dev *gspca_dev) sd->sensor->stop(sd); } -/* sub-driver description, the ctrl and nctrl is filled at probe time */ -static struct sd_desc sd_desc = { +/* sub-driver description */ +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .config = m5602_configure, .init = m5602_init, + .init_controls = m5602_init_controls, .start = m5602_start_transfer, .stopN = m5602_stop_transfer, .pkt_scan = m5602_urb_complete @@ -355,7 +366,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev, int err; cam = &gspca_dev->cam; - sd->desc = &sd_desc; if (dump_bridge) m5602_dump_bridge(sd); diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c index 6268aa24ec5d..b5f66921b3eb 100644 --- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c @@ -20,22 +20,8 @@ #include "m5602_mt9m111.h" -static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); +static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl); +static void mt9m111_dump_registers(struct sd *sd); static struct v4l2_pix_format mt9m111_modes[] = { { @@ -50,118 +36,26 @@ static struct v4l2_pix_format mt9m111_modes[] = { } }; -static const struct ctrl mt9m111_ctrls[] = { -#define VFLIP_IDX 0 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_vflip, - .get = mt9m111_get_vflip - }, -#define HFLIP_IDX 1 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_hflip, - .get = mt9m111_get_hflip - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0, - .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, - .step = 1, - .default_value = MT9M111_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_gain, - .get = mt9m111_get_gain - }, -#define AUTO_WHITE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = mt9m111_set_auto_white_balance, - .get = mt9m111_get_auto_white_balance - }, -#define GREEN_BALANCE_IDX 4 - { - { - .id = M5602_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_GREEN_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_green_balance, - .get = mt9m111_get_green_balance - }, -#define BLUE_BALANCE_IDX 5 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_blue_balance, - .get = mt9m111_get_blue_balance - }, -#define RED_BALANCE_IDX 5 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_red_balance, - .get = mt9m111_get_red_balance - }, +static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = { + .s_ctrl = mt9m111_s_ctrl, }; -static void mt9m111_dump_registers(struct sd *sd); +static const struct v4l2_ctrl_config mt9m111_greenbal_cfg = { + .ops = &mt9m111_ctrl_ops, + .id = M5602_V4L2_CID_GREEN_BALANCE, + .name = "Green Balance", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 0x7ff, + .step = 1, + .def = MT9M111_GREEN_GAIN_DEFAULT, + .flags = V4L2_CTRL_FLAG_SLIDER, +}; int mt9m111_probe(struct sd *sd) { u8 data[2] = {0x00, 0x00}; int i; - s32 *sensor_settings; if (force_sensor) { if (force_sensor == MT9M111_SENSOR) { @@ -200,19 +94,8 @@ int mt9m111_probe(struct sd *sd) return -ENODEV; sensor_found: - sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), - GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - sd->gspca_dev.cam.cam_mode = mt9m111_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); - sd->desc->ctrls = mt9m111_ctrls; - sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); - - for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) - sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; return 0; } @@ -220,7 +103,6 @@ sensor_found: int mt9m111_init(struct sd *sd) { int i, err = 0; - s32 *sensor_settings = sd->sensor_priv; /* Init the sensor */ for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { @@ -241,30 +123,45 @@ int mt9m111_init(struct sd *sd) if (dump_sensor) mt9m111_dump_registers(sd); - err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_green_balance(&sd->gspca_dev, - sensor_settings[GREEN_BALANCE_IDX]); - if (err < 0) - return err; + return 0; +} - err = mt9m111_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; +int mt9m111_init_controls(struct sd *sd) +{ + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; + + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 7); + + sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 0); + sd->green_bal = v4l2_ctrl_new_custom(hdl, &mt9m111_greenbal_cfg, NULL); + sd->red_bal = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, + V4L2_CID_RED_BALANCE, 0, 0x7ff, 1, + MT9M111_RED_GAIN_DEFAULT); + sd->blue_bal = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, + V4L2_CID_BLUE_BALANCE, 0, 0x7ff, 1, + MT9M111_BLUE_GAIN_DEFAULT); + + v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, V4L2_CID_GAIN, 0, + (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, 1, + MT9M111_DEFAULT_GAIN); + + sd->hflip = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &mt9m111_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } - err = mt9m111_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; + v4l2_ctrl_auto_cluster(4, &sd->auto_white_bal, 0, false); + v4l2_ctrl_cluster(2, &sd->hflip); - return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); + return 0; } int mt9m111_start(struct sd *sd) @@ -272,7 +169,6 @@ int mt9m111_start(struct sd *sd) int i, err = 0; u8 data[2]; struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; @@ -334,25 +230,10 @@ int mt9m111_start(struct sd *sd) switch (width) { case 640: PDEBUG(D_V4L2, "Configuring camera for VGA mode"); - data[0] = MT9M111_RMB_OVER_SIZED; - data[1] = MT9M111_RMB_ROW_SKIP_2X | - MT9M111_RMB_COLUMN_SKIP_2X | - (sensor_settings[VFLIP_IDX] << 0) | - (sensor_settings[HFLIP_IDX] << 1); - - err = m5602_write_sensor(sd, - MT9M111_SC_R_MODE_CONTEXT_B, data, 2); break; case 320: PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); - data[0] = MT9M111_RMB_OVER_SIZED; - data[1] = MT9M111_RMB_ROW_SKIP_4X | - MT9M111_RMB_COLUMN_SKIP_4X | - (sensor_settings[VFLIP_IDX] << 0) | - (sensor_settings[HFLIP_IDX] << 1); - err = m5602_write_sensor(sd, - MT9M111_SC_R_MODE_CONTEXT_B, data, 2); break; } return err; @@ -361,105 +242,46 @@ int mt9m111_start(struct sd *sd) void mt9m111_disconnect(struct sd *sd) { sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - - sensor_settings[VFLIP_IDX] = val; - - /* The mt9m111 is flipped by default */ - val = !val; - - /* Set the correct page map */ - err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - return err; - - data[1] = (data[1] & 0xfe) | val; - err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - return err; -} - -static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - - return 0; } -static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) +static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev) { int err; u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; + int hflip; + int vflip; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - - sensor_settings[HFLIP_IDX] = val; + PDEBUG(D_V4L2, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val); /* The mt9m111 is flipped by default */ - val = !val; + hflip = !sd->hflip->val; + vflip = !sd->vflip->val; /* Set the correct page map */ err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); if (err < 0) return err; - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - return err; - - data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02); + data[0] = MT9M111_RMB_OVER_SIZED; + if (gspca_dev->width == 640) { + data[1] = MT9M111_RMB_ROW_SKIP_2X | + MT9M111_RMB_COLUMN_SKIP_2X | + (hflip << 1) | vflip; + } else { + data[1] = MT9M111_RMB_ROW_SKIP_4X | + MT9M111_RMB_COLUMN_SKIP_4X | + (hflip << 1) | vflip; + } err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); return err; } -static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - - return 0; -} - static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; int err; u8 data[2]; @@ -467,7 +289,6 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, if (err < 0) return err; - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); @@ -476,24 +297,11 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, return err; } -static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) { - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read auto white balance %d", *val); - return 0; -} - static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err, tmp; u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[GAIN_IDX] = val; /* Set the correct page map */ err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); @@ -532,9 +340,7 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) int err; u8 data[2]; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - sensor_settings[GREEN_BALANCE_IDX] = val; data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; @@ -548,23 +354,11 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) data, 2); } -static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GREEN_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read green balance %d", *val); - return 0; -} - static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) { u8 data[2]; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - sensor_settings[BLUE_BALANCE_IDX] = val; data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; @@ -574,23 +368,11 @@ static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) data, 2); } -static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue balance %d", *val); - return 0; -} - static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) { u8 data[2]; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - sensor_settings[RED_BALANCE_IDX] = val; data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; @@ -600,14 +382,40 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) data, 2); } -static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) +static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl) { + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; + int err; - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red balance %d", *val); - return 0; + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + err = mt9m111_set_auto_white_balance(gspca_dev, ctrl->val); + if (err || ctrl->val) + return err; + err = mt9m111_set_green_balance(gspca_dev, sd->green_bal->val); + if (err) + return err; + err = mt9m111_set_red_balance(gspca_dev, sd->red_bal->val); + if (err) + return err; + err = mt9m111_set_blue_balance(gspca_dev, sd->blue_bal->val); + break; + case V4L2_CID_GAIN: + err = mt9m111_set_gain(gspca_dev, ctrl->val); + break; + case V4L2_CID_HFLIP: + err = mt9m111_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; + } + + return err; } static void mt9m111_dump_registers(struct sd *sd) diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.h b/drivers/media/usb/gspca/m5602/m5602_mt9m111.h index 8c672b5c8c6a..07448d35e3cd 100644 --- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.h @@ -110,6 +110,7 @@ extern bool dump_sensor; int mt9m111_probe(struct sd *sd); int mt9m111_init(struct sd *sd); +int mt9m111_init_controls(struct sd *sd); int mt9m111_start(struct sd *sd); void mt9m111_disconnect(struct sd *sd); @@ -121,6 +122,7 @@ static const struct m5602_sensor mt9m111 = { .probe = mt9m111_probe, .init = mt9m111_init, + .init_controls = mt9m111_init_controls, .disconnect = mt9m111_disconnect, .start = mt9m111_start, }; diff --git a/drivers/media/usb/gspca/m5602/m5602_ov7660.c b/drivers/media/usb/gspca/m5602/m5602_ov7660.c index 9a14835c128f..3bbe3ad5d4a9 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov7660.c +++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.c @@ -20,111 +20,8 @@ #include "m5602_ov7660.h" -static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); - -static const struct ctrl ov7660_ctrls[] = { -#define GAIN_IDX 1 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = OV7660_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov7660_set_gain, - .get = ov7660_get_gain - }, -#define BLUE_BALANCE_IDX 2 -#define RED_BALANCE_IDX 3 -#define AUTO_WHITE_BALANCE_IDX 4 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_white_balance, - .get = ov7660_get_auto_white_balance - }, -#define AUTO_GAIN_CTRL_IDX 5 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto gain control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_gain, - .get = ov7660_get_auto_gain - }, -#define AUTO_EXPOSURE_IDX 6 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_exposure, - .get = ov7660_get_auto_exposure - }, -#define HFLIP_IDX 7 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov7660_set_hflip, - .get = ov7660_get_hflip - }, -#define VFLIP_IDX 8 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov7660_set_vflip, - .get = ov7660_get_vflip - }, - -}; +static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl); +static void ov7660_dump_registers(struct sd *sd); static struct v4l2_pix_format ov7660_modes[] = { { @@ -140,15 +37,15 @@ static struct v4l2_pix_format ov7660_modes[] = { } }; -static void ov7660_dump_registers(struct sd *sd); +static const struct v4l2_ctrl_ops ov7660_ctrl_ops = { + .s_ctrl = ov7660_s_ctrl, +}; int ov7660_probe(struct sd *sd) { int err = 0, i; u8 prod_id = 0, ver_id = 0; - s32 *sensor_settings; - if (force_sensor) { if (force_sensor == OV7660_SENSOR) { pr_info("Forcing an %s sensor\n", ov7660.name); @@ -191,19 +88,8 @@ int ov7660_probe(struct sd *sd) return -ENODEV; sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - sd->gspca_dev.cam.cam_mode = ov7660_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); - sd->desc->ctrls = ov7660_ctrls; - sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); - - for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) - sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; return 0; } @@ -211,7 +97,6 @@ sensor_found: int ov7660_init(struct sd *sd) { int i, err = 0; - s32 *sensor_settings = sd->sensor_priv; /* Init the sensor */ for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { @@ -231,33 +116,40 @@ int ov7660_init(struct sd *sd) if (dump_sensor) ov7660_dump_registers(sd); - err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; + return 0; +} - err = ov7660_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; +int ov7660_init_controls(struct sd *sd) +{ + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - err = ov7660_set_auto_gain(&sd->gspca_dev, - sensor_settings[AUTO_GAIN_CTRL_IDX]); - if (err < 0) - return err; + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 6); - err = ov7660_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - if (err < 0) - return err; - err = ov7660_set_hflip(&sd->gspca_dev, - sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; + v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 1); + v4l2_ctrl_new_std_menu(hdl, &ov7660_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); - err = ov7660_set_vflip(&sd->gspca_dev, - sensor_settings[VFLIP_IDX]); + sd->autogain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + sd->gain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_GAIN, 0, + 255, 1, OV7660_DEFAULT_GAIN); - return err; + sd->hflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); + v4l2_ctrl_cluster(2, &sd->hflip); + + return 0; } int ov7660_start(struct sd *sd) @@ -275,56 +167,29 @@ void ov7660_disconnect(struct sd *sd) ov7660_stop(sd); sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - return 0; } static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; - u8 i2c_data; + u8 i2c_data = val; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Setting gain to %d", val); - sensor_settings[GAIN_IDX] = val; - err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); return err; } - -static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - return 0; -} - static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto white balance to %d", val); - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) return err; @@ -335,26 +200,14 @@ static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, return err; } -static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; - PDEBUG(D_V4L2, "Read auto gain control %d", *val); - return 0; -} - static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto gain control to %d", val); - sensor_settings[AUTO_GAIN_CTRL_IDX] = val; err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) return err; @@ -364,94 +217,69 @@ static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); } -static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read auto exposure control %d", *val); - return 0; -} - static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto exposure control to %d", val); - sensor_settings[AUTO_EXPOSURE_IDX] = val; err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) return err; + val = (val == V4L2_EXPOSURE_AUTO); i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); } -static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return 0; -} - -static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val) +static int ov7660_set_hvflip(struct gspca_dev *gspca_dev) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); + PDEBUG(D_V4L2, "Set hvflip to %d, %d", sd->hflip->val, sd->vflip->val); - sensor_settings[HFLIP_IDX] = val; - - i2c_data = ((val & 0x01) << 5) | - (sensor_settings[VFLIP_IDX] << 4); + i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4); err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); return err; } -static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) +static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl) { + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - sensor_settings[VFLIP_IDX] = val; - i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); - err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); - if (err < 0) - return err; - - /* When vflip is toggled we need to readjust the bridge hsync/vsync */ - if (gspca_dev->streaming) - err = ov7660_start(sd); + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + err = ov7660_set_auto_white_balance(gspca_dev, ctrl->val); + break; + case V4L2_CID_EXPOSURE_AUTO: + err = ov7660_set_auto_exposure(gspca_dev, ctrl->val); + break; + case V4L2_CID_AUTOGAIN: + err = ov7660_set_auto_gain(gspca_dev, ctrl->val); + if (err || ctrl->val) + return err; + err = ov7660_set_gain(gspca_dev, sd->gain->val); + break; + case V4L2_CID_HFLIP: + err = ov7660_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; + } return err; } diff --git a/drivers/media/usb/gspca/m5602/m5602_ov7660.h b/drivers/media/usb/gspca/m5602/m5602_ov7660.h index 2b6a13b508f7..6fece1ce1232 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov7660.h +++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.h @@ -90,6 +90,8 @@ extern bool dump_sensor; int ov7660_probe(struct sd *sd); int ov7660_init(struct sd *sd); +int ov7660_init(struct sd *sd); +int ov7660_init_controls(struct sd *sd); int ov7660_start(struct sd *sd); int ov7660_stop(struct sd *sd); void ov7660_disconnect(struct sd *sd); @@ -100,6 +102,7 @@ static const struct m5602_sensor ov7660 = { .i2c_regW = 1, .probe = ov7660_probe, .init = ov7660_init, + .init_controls = ov7660_init_controls, .start = ov7660_start, .stop = ov7660_stop, .disconnect = ov7660_disconnect, diff --git a/drivers/media/usb/gspca/m5602/m5602_ov9650.c b/drivers/media/usb/gspca/m5602/m5602_ov9650.c index 2114a8b90ec9..e2fe2f942fe6 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.c @@ -20,26 +20,8 @@ #include "m5602_ov9650.h" -static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); +static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl); +static void ov9650_dump_registers(struct sd *sd); /* Vertically and horizontally flips the image if matched, needed for machines where the sensor is mounted upside down */ @@ -113,140 +95,6 @@ static {} }; -static const struct ctrl ov9650_ctrls[] = { -#define EXPOSURE_IDX 0 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0x1ff, - .step = 0x4, - .default_value = EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_exposure, - .get = ov9650_get_exposure - }, -#define GAIN_IDX 1 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0x3ff, - .step = 0x1, - .default_value = GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_gain, - .get = ov9650_get_gain - }, -#define RED_BALANCE_IDX 2 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_red_balance, - .get = ov9650_get_red_balance - }, -#define BLUE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_blue_balance, - .get = ov9650_get_blue_balance - }, -#define HFLIP_IDX 4 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_hflip, - .get = ov9650_get_hflip - }, -#define VFLIP_IDX 5 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_vflip, - .get = ov9650_get_vflip - }, -#define AUTO_WHITE_BALANCE_IDX 6 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_white_balance, - .get = ov9650_get_auto_white_balance - }, -#define AUTO_GAIN_CTRL_IDX 7 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto gain control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_gain, - .get = ov9650_get_auto_gain - }, -#define AUTO_EXPOSURE_IDX 8 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_exposure, - .get = ov9650_get_auto_exposure - } - -}; - static struct v4l2_pix_format ov9650_modes[] = { { 176, @@ -291,13 +139,14 @@ static struct v4l2_pix_format ov9650_modes[] = { } }; -static void ov9650_dump_registers(struct sd *sd); +static const struct v4l2_ctrl_ops ov9650_ctrl_ops = { + .s_ctrl = ov9650_s_ctrl, +}; int ov9650_probe(struct sd *sd) { int err = 0; u8 prod_id = 0, ver_id = 0, i; - s32 *sensor_settings; if (force_sensor) { if (force_sensor == OV9650_SENSOR) { @@ -338,19 +187,9 @@ int ov9650_probe(struct sd *sd) return -ENODEV; sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - sd->gspca_dev.cam.cam_mode = ov9650_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes); - sd->desc->ctrls = ov9650_ctrls; - sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls); - for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) - sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; return 0; } @@ -358,7 +197,6 @@ int ov9650_init(struct sd *sd) { int i, err = 0; u8 data; - s32 *sensor_settings = sd->sensor_priv; if (dump_sensor) ov9650_dump_registers(sd); @@ -372,46 +210,52 @@ int ov9650_init(struct sd *sd) err = m5602_write_bridge(sd, init_ov9650[i][1], data); } - err = ov9650_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = ov9650_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; + return 0; +} - err = ov9650_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - if (err < 0) - return err; +int ov9650_init_controls(struct sd *sd) +{ + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; + + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 9); + + sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 1); + sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, + V4L2_CID_RED_BALANCE, 0, 255, 1, + RED_GAIN_DEFAULT); + sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, + V4L2_CID_BLUE_BALANCE, 0, 255, 1, + BLUE_GAIN_DEFAULT); + + sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); + sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE, + 0, 0x1ff, 4, EXPOSURE_DEFAULT); + + sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0, + 0x3ff, 1, GAIN_DEFAULT); + + sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } - err = ov9650_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; + v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false); + v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false); + v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); + v4l2_ctrl_cluster(2, &sd->hflip); - err = ov9650_set_auto_gain(&sd->gspca_dev, - sensor_settings[AUTO_GAIN_CTRL_IDX]); - return err; + return 0; } int ov9650_start(struct sd *sd) @@ -419,7 +263,6 @@ int ov9650_start(struct sd *sd) u8 data; int i, err = 0; struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; @@ -427,9 +270,9 @@ int ov9650_start(struct sd *sd) int hor_offs = OV9650_LEFT_OFFSET; if ((!dmi_check_system(ov9650_flip_dmi_table) && - sensor_settings[VFLIP_IDX]) || + sd->vflip->val) || (dmi_check_system(ov9650_flip_dmi_table) && - !sensor_settings[VFLIP_IDX])) + !sd->vflip->val)) ver_offs--; if (width <= 320) @@ -553,29 +396,16 @@ void ov9650_disconnect(struct sd *sd) ov9650_stop(sd); sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read exposure %d", *val); - return 0; } static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; PDEBUG(D_V4L2, "Set exposure to %d", val); - sensor_settings[EXPOSURE_IDX] = val; /* The 6 MSBs */ i2c_data = (val >> 10) & 0x3f; err = m5602_write_sensor(sd, OV9650_AECHM, @@ -596,27 +426,14 @@ static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - return 0; -} - static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Setting gain to %d", val); - sensor_settings[GAIN_IDX] = val; - /* The 2 MSB */ /* Read the OV9650_VREF register first to avoid corrupting the VREF high and low bits */ @@ -637,117 +454,46 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red gain %d", *val); - return 0; -} - static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set red gain to %d", val); - sensor_settings[RED_BALANCE_IDX] = val; - i2c_data = val & 0xff; err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); return err; } -static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue gain %d", *val); - - return 0; -} - static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set blue gain to %d", val); - sensor_settings[BLUE_BALANCE_IDX] = val; - i2c_data = val & 0xff; err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); return err; } -static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return 0; -} - -static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) +static int ov9650_set_hvflip(struct gspca_dev *gspca_dev) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; + int hflip = sd->hflip->val; + int vflip = sd->vflip->val; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - - sensor_settings[HFLIP_IDX] = val; - - if (!dmi_check_system(ov9650_flip_dmi_table)) - i2c_data = ((val & 0x01) << 5) | - (sensor_settings[VFLIP_IDX] << 4); - else - i2c_data = ((val & 0x01) << 5) | - (!sensor_settings[VFLIP_IDX] << 4); - - err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); - - return err; -} - -static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - sensor_settings[VFLIP_IDX] = val; + PDEBUG(D_V4L2, "Set hvflip to %d %d", hflip, vflip); if (dmi_check_system(ov9650_flip_dmi_table)) - val = !val; + vflip = !vflip; - i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); + i2c_data = (hflip << 5) | (vflip << 4); err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); if (err < 0) return err; @@ -759,57 +505,34 @@ static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read auto exposure control %d", *val); - return 0; -} - static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto exposure control to %d", val); - sensor_settings[AUTO_EXPOSURE_IDX] = val; err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) return err; + val = (val == V4L2_EXPOSURE_AUTO); i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); } -static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - return 0; -} - static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto white balance to %d", val); - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) return err; @@ -820,26 +543,14 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, return err; } -static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; - PDEBUG(D_V4L2, "Read auto gain control %d", *val); - return 0; -} - static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set auto gain control to %d", val); - sensor_settings[AUTO_GAIN_CTRL_IDX] = val; err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) return err; @@ -849,6 +560,48 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); } +static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); + struct sd *sd = (struct sd *) gspca_dev; + int err; + + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val); + if (err || ctrl->val) + return err; + err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val); + if (err) + return err; + err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val); + break; + case V4L2_CID_EXPOSURE_AUTO: + err = ov9650_set_auto_exposure(gspca_dev, ctrl->val); + if (err || ctrl->val == V4L2_EXPOSURE_AUTO) + return err; + err = ov9650_set_exposure(gspca_dev, sd->expo->val); + break; + case V4L2_CID_AUTOGAIN: + err = ov9650_set_auto_gain(gspca_dev, ctrl->val); + if (err || ctrl->val) + return err; + err = ov9650_set_gain(gspca_dev, sd->gain->val); + break; + case V4L2_CID_HFLIP: + err = ov9650_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; + } + + return err; +} + static void ov9650_dump_registers(struct sd *sd) { int address; diff --git a/drivers/media/usb/gspca/m5602/m5602_ov9650.h b/drivers/media/usb/gspca/m5602/m5602_ov9650.h index f7aa5bf68983..f9f5870da60f 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.h @@ -139,6 +139,7 @@ extern bool dump_sensor; int ov9650_probe(struct sd *sd); int ov9650_init(struct sd *sd); +int ov9650_init_controls(struct sd *sd); int ov9650_start(struct sd *sd); int ov9650_stop(struct sd *sd); void ov9650_disconnect(struct sd *sd); @@ -149,6 +150,7 @@ static const struct m5602_sensor ov9650 = { .i2c_regW = 1, .probe = ov9650_probe, .init = ov9650_init, + .init_controls = ov9650_init_controls, .start = ov9650_start, .stop = ov9650_stop, .disconnect = ov9650_disconnect, diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c index b8771698cbcb..189086291303 100644 --- a/drivers/media/usb/gspca/m5602/m5602_po1030.c +++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c @@ -20,28 +20,8 @@ #include "m5602_po1030.h" -static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, - __s32 val); -static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, - __s32 *val); +static int po1030_s_ctrl(struct v4l2_ctrl *ctrl); +static void po1030_dump_registers(struct sd *sd); static struct v4l2_pix_format po1030_modes[] = { { @@ -56,146 +36,25 @@ static struct v4l2_pix_format po1030_modes[] = { } }; -static const struct ctrl po1030_ctrls[] = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0x4f, - .step = 0x1, - .default_value = PO1030_GLOBAL_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_gain, - .get = po1030_get_gain - }, -#define EXPOSURE_IDX 1 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0x02ff, - .step = 0x1, - .default_value = PO1030_EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_exposure, - .get = po1030_get_exposure - }, -#define RED_BALANCE_IDX 2 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_red_balance, - .get = po1030_get_red_balance - }, -#define BLUE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_blue_balance, - .get = po1030_get_blue_balance - }, -#define HFLIP_IDX 4 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_hflip, - .get = po1030_get_hflip - }, -#define VFLIP_IDX 5 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_vflip, - .get = po1030_get_vflip - }, -#define AUTO_WHITE_BALANCE_IDX 6 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_auto_white_balance, - .get = po1030_get_auto_white_balance - }, -#define AUTO_EXPOSURE_IDX 7 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_auto_exposure, - .get = po1030_get_auto_exposure - }, -#define GREEN_BALANCE_IDX 8 - { - { - .id = M5602_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_GREEN_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_green_balance, - .get = po1030_get_green_balance - }, +static const struct v4l2_ctrl_ops po1030_ctrl_ops = { + .s_ctrl = po1030_s_ctrl, }; -static void po1030_dump_registers(struct sd *sd); +static const struct v4l2_ctrl_config po1030_greenbal_cfg = { + .ops = &po1030_ctrl_ops, + .id = M5602_V4L2_CID_GREEN_BALANCE, + .name = "Green Balance", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = 255, + .step = 1, + .def = PO1030_GREEN_GAIN_DEFAULT, + .flags = V4L2_CTRL_FLAG_SLIDER, +}; int po1030_probe(struct sd *sd) { u8 dev_id_h = 0, i; - s32 *sensor_settings; if (force_sensor) { if (force_sensor == PO1030_SENSOR) { @@ -229,26 +88,14 @@ int po1030_probe(struct sd *sd) return -ENODEV; sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - sd->gspca_dev.cam.cam_mode = po1030_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); - sd->desc->ctrls = po1030_ctrls; - sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); - - for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) - sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; return 0; } int po1030_init(struct sd *sd) { - s32 *sensor_settings = sd->sensor_priv; int i, err = 0; /* Init the sensor */ @@ -279,46 +126,50 @@ int po1030_init(struct sd *sd) if (dump_sensor) po1030_dump_registers(sd); - err = po1030_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - err = po1030_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; - - err = po1030_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; + return 0; +} - err = po1030_set_green_balance(&sd->gspca_dev, - sensor_settings[GREEN_BALANCE_IDX]); - if (err < 0) - return err; +int po1030_init_controls(struct sd *sd) +{ + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; + + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 9); + + sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 0); + sd->green_bal = v4l2_ctrl_new_custom(hdl, &po1030_greenbal_cfg, NULL); + sd->red_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, + V4L2_CID_RED_BALANCE, 0, 255, 1, + PO1030_RED_GAIN_DEFAULT); + sd->blue_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, + V4L2_CID_BLUE_BALANCE, 0, 255, 1, + PO1030_BLUE_GAIN_DEFAULT); + + sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &po1030_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_MANUAL); + sd->expo = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_EXPOSURE, + 0, 0x2ff, 1, PO1030_EXPOSURE_DEFAULT); + + sd->gain = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_GAIN, 0, + 0x4f, 1, PO1030_GLOBAL_GAIN_DEFAULT); + + sd->hflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } - err = po1030_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; + v4l2_ctrl_auto_cluster(4, &sd->auto_white_bal, 0, false); + v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false); + v4l2_ctrl_cluster(2, &sd->hflip); - err = po1030_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - return err; + return 0; } int po1030_start(struct sd *sd) @@ -448,24 +299,12 @@ int po1030_start(struct sd *sd) return err; } -static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Exposure read as %d", *val); - return 0; -} - static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[EXPOSURE_IDX] = val; PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); i2c_data = ((val & 0xff00) >> 8); @@ -486,25 +325,12 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read global gain %d", *val); - return 0; -} - static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[GAIN_IDX] = val; - i2c_data = val & 0xff; PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, @@ -512,65 +338,19 @@ static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read hflip %d", *val); - - return 0; -} - -static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[HFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set hflip %d", val); - err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); - - err = m5602_write_sensor(sd, PO1030_CONTROL2, - &i2c_data, 1); - - return err; -} - -static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) +static int po1030_set_hvflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vflip %d", *val); - - return 0; -} - -static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[VFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set vflip %d", val); + PDEBUG(D_V4L2, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val); err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); if (err < 0) return err; - i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); + i2c_data = (0x3f & i2c_data) | (sd->hflip->val << 7) | + (sd->vflip->val << 6); err = m5602_write_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); @@ -578,25 +358,12 @@ static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red gain %d", *val); - return 0; -} - static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[RED_BALANCE_IDX] = val; - i2c_data = val & 0xff; PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_RED_GAIN, @@ -604,26 +371,12 @@ static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue gain %d", *val); - - return 0; -} - static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[BLUE_BALANCE_IDX] = val; - i2c_data = val & 0xff; PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, @@ -632,25 +385,12 @@ static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GREEN_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read green gain %d", *val); - - return 0; -} - static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[GREEN_BALANCE_IDX] = val; i2c_data = val & 0xff; PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); @@ -663,28 +403,13 @@ static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) &i2c_data, 1); } -static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Auto white balancing is %d", *val); - - return 0; -} - static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; - err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); if (err < 0) return err; @@ -695,31 +420,19 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, return err; } -static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Auto exposure is %d", *val); - return 0; -} - static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 i2c_data; int err; - sensor_settings[AUTO_EXPOSURE_IDX] = val; err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); if (err < 0) return err; PDEBUG(D_V4L2, "Set auto exposure to %d", val); + val = (val == V4L2_EXPOSURE_AUTO); i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); } @@ -727,7 +440,48 @@ static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, void po1030_disconnect(struct sd *sd) { sd->sensor = NULL; - kfree(sd->sensor_priv); +} + +static int po1030_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); + struct sd *sd = (struct sd *) gspca_dev; + int err; + + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + err = po1030_set_auto_white_balance(gspca_dev, ctrl->val); + if (err || ctrl->val) + return err; + err = po1030_set_green_balance(gspca_dev, sd->green_bal->val); + if (err) + return err; + err = po1030_set_red_balance(gspca_dev, sd->red_bal->val); + if (err) + return err; + err = po1030_set_blue_balance(gspca_dev, sd->blue_bal->val); + break; + case V4L2_CID_EXPOSURE_AUTO: + err = po1030_set_auto_exposure(gspca_dev, ctrl->val); + if (err || ctrl->val == V4L2_EXPOSURE_AUTO) + return err; + err = po1030_set_exposure(gspca_dev, sd->expo->val); + break; + case V4L2_CID_GAIN: + err = po1030_set_gain(gspca_dev, ctrl->val); + break; + case V4L2_CID_HFLIP: + err = po1030_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; + } + + return err; } static void po1030_dump_registers(struct sd *sd) diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.h b/drivers/media/usb/gspca/m5602/m5602_po1030.h index 81a2bcb88fe3..a6ab76149bd0 100644 --- a/drivers/media/usb/gspca/m5602/m5602_po1030.h +++ b/drivers/media/usb/gspca/m5602/m5602_po1030.h @@ -151,6 +151,7 @@ extern bool dump_sensor; int po1030_probe(struct sd *sd); int po1030_init(struct sd *sd); +int po1030_init_controls(struct sd *sd); int po1030_start(struct sd *sd); void po1030_disconnect(struct sd *sd); @@ -162,6 +163,7 @@ static const struct m5602_sensor po1030 = { .probe = po1030_probe, .init = po1030_init, + .init_controls = po1030_init_controls, .start = po1030_start, .disconnect = po1030_disconnect, }; diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c index c8e1572eb502..42ffaf04771c 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c @@ -20,18 +20,12 @@ #include "m5602_s5k4aa.h" -static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val); +static int s5k4aa_s_ctrl(struct v4l2_ctrl *ctrl); +static void s5k4aa_dump_registers(struct sd *sd); + +static const struct v4l2_ctrl_ops s5k4aa_ctrl_ops = { + .s_ctrl = s5k4aa_s_ctrl, +}; static const @@ -147,104 +141,11 @@ static struct v4l2_pix_format s5k4aa_modes[] = { } }; -static const struct ctrl s5k4aa_ctrls[] = { -#define VFLIP_IDX 0 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_vflip, - .get = s5k4aa_get_vflip - }, -#define HFLIP_IDX 1 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_hflip, - .get = s5k4aa_get_hflip - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = S5K4AA_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_gain, - .get = s5k4aa_get_gain - }, -#define EXPOSURE_IDX 3 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 13, - .maximum = 0xfff, - .step = 1, - .default_value = 0x100, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_exposure, - .get = s5k4aa_get_exposure - }, -#define NOISE_SUPP_IDX 4 - { - { - .id = V4L2_CID_PRIVATE_BASE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Noise suppression (smoothing)", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - .set = s5k4aa_set_noise, - .get = s5k4aa_get_noise - }, -#define BRIGHTNESS_IDX 5 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 0x1f, - .step = 1, - .default_value = S5K4AA_DEFAULT_BRIGHTNESS, - }, - .set = s5k4aa_set_brightness, - .get = s5k4aa_get_brightness - }, - -}; - -static void s5k4aa_dump_registers(struct sd *sd); - int s5k4aa_probe(struct sd *sd) { u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; int i, err = 0; - s32 *sensor_settings; if (force_sensor) { if (force_sensor == S5K4AA_SENSOR) { @@ -303,19 +204,8 @@ int s5k4aa_probe(struct sd *sd) pr_info("Detected a s5k4aa sensor\n"); sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - sd->gspca_dev.cam.cam_mode = s5k4aa_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); - sd->desc->ctrls = s5k4aa_ctrls; - sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); - - for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) - sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; return 0; } @@ -325,7 +215,6 @@ int s5k4aa_start(struct sd *sd) int i, err = 0; u8 data[2]; struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { case 1280: @@ -359,9 +248,6 @@ int s5k4aa_start(struct sd *sd) return -EINVAL; } } - err = s5k4aa_set_noise(&sd->gspca_dev, 0); - if (err < 0) - return err; break; case 640: @@ -395,37 +281,12 @@ int s5k4aa_start(struct sd *sd) return -EINVAL; } } - err = s5k4aa_set_noise(&sd->gspca_dev, 1); - if (err < 0) - return err; break; } if (err < 0) return err; - err = s5k4aa_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_brightness(&sd->gspca_dev, - sensor_settings[BRIGHTNESS_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); + return 0; } int s5k4aa_init(struct sd *sd) @@ -466,13 +327,36 @@ int s5k4aa_init(struct sd *sd) return err; } -static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) +int s5k4aa_init_controls(struct sd *sd) { - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; + + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 6); - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read exposure %d", *val); + v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_BRIGHTNESS, + 0, 0x1f, 1, S5K4AA_DEFAULT_BRIGHTNESS); + + v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_EXPOSURE, + 13, 0xfff, 1, 0x100); + + v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_GAIN, + 0, 127, 1, S5K4AA_DEFAULT_GAIN); + + v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_SHARPNESS, + 0, 1, 1, 1); + + sd->hflip = v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(2, &sd->hflip); return 0; } @@ -480,11 +364,9 @@ static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 data = S5K4AA_PAGE_MAP_2; int err; - sensor_settings[EXPOSURE_IDX] = val; PDEBUG(D_V4L2, "Set exposure to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) @@ -499,27 +381,15 @@ static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) +static int s5k4aa_set_hvflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 data = S5K4AA_PAGE_MAP_2; int err; + int hflip = sd->hflip->val; + int vflip = sd->vflip->val; - sensor_settings[VFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); + PDEBUG(D_V4L2, "Set hvflip %d %d", hflip, vflip); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; @@ -528,92 +398,47 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) if (err < 0) return err; - if (dmi_check_system(s5k4aa_vflip_dmi_table)) - val = !val; + if (dmi_check_system(s5k4aa_vflip_dmi_table)) { + hflip = !hflip; + vflip = !vflip; + } - data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7)); + data = (data & 0x7f) | (vflip << 7) | (hflip << 6); err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); if (err < 0) return err; - err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); + err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); if (err < 0) return err; - if (val) + if (hflip) data &= 0xfe; else data |= 0x01; - err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - return err; -} - -static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - - return 0; -} - -static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[HFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - return err; - - if (dmi_check_system(s5k4aa_vflip_dmi_table)) - val = !val; - - data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); - err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); + err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); if (err < 0) return err; - err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); + err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); if (err < 0) return err; - if (val) + if (vflip) data &= 0xfe; else data |= 0x01; - err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - return err; -} - -static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; + err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); + if (err < 0) + return err; - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); return 0; } static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 data = S5K4AA_PAGE_MAP_2; int err; - sensor_settings[GAIN_IDX] = val; - PDEBUG(D_V4L2, "Set gain to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) @@ -625,25 +450,12 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BRIGHTNESS_IDX]; - PDEBUG(D_V4L2, "Read brightness %d", *val); - return 0; -} - static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 data = S5K4AA_PAGE_MAP_2; int err; - sensor_settings[BRIGHTNESS_IDX] = val; - PDEBUG(D_V4L2, "Set brightness to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) @@ -653,25 +465,12 @@ static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1); } -static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[NOISE_SUPP_IDX]; - PDEBUG(D_V4L2, "Read noise %d", *val); - return 0; -} - static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; u8 data = S5K4AA_PAGE_MAP_2; int err; - sensor_settings[NOISE_SUPP_IDX] = val; - PDEBUG(D_V4L2, "Set noise to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) @@ -681,10 +480,41 @@ static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); } +static int s5k4aa_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); + int err; + + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + err = s5k4aa_set_brightness(gspca_dev, ctrl->val); + break; + case V4L2_CID_EXPOSURE: + err = s5k4aa_set_exposure(gspca_dev, ctrl->val); + break; + case V4L2_CID_GAIN: + err = s5k4aa_set_gain(gspca_dev, ctrl->val); + break; + case V4L2_CID_SHARPNESS: + err = s5k4aa_set_noise(gspca_dev, ctrl->val); + break; + case V4L2_CID_HFLIP: + err = s5k4aa_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; + } + + return err; +} + void s5k4aa_disconnect(struct sd *sd) { sd->sensor = NULL; - kfree(sd->sensor_priv); } static void s5k4aa_dump_registers(struct sd *sd) diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h index 8e0035e731c7..9953e9766954 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h @@ -69,6 +69,7 @@ extern bool dump_sensor; int s5k4aa_probe(struct sd *sd); int s5k4aa_init(struct sd *sd); +int s5k4aa_init_controls(struct sd *sd); int s5k4aa_start(struct sd *sd); void s5k4aa_disconnect(struct sd *sd); @@ -79,6 +80,7 @@ static const struct m5602_sensor s5k4aa = { .probe = s5k4aa_probe, .init = s5k4aa_init, + .init_controls = s5k4aa_init_controls, .start = s5k4aa_start, .disconnect = s5k4aa_disconnect, }; diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c index 1de743a02b02..69ee6e26b8ea 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c @@ -21,16 +21,11 @@ #include #include "m5602_s5k83a.h" -static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); +static int s5k83a_s_ctrl(struct v4l2_ctrl *ctrl); + +static const struct v4l2_ctrl_ops s5k83a_ctrl_ops = { + .s_ctrl = s5k83a_s_ctrl, +}; static struct v4l2_pix_format s5k83a_modes[] = { { @@ -46,83 +41,6 @@ static struct v4l2_pix_format s5k83a_modes[] = { } }; -static const struct ctrl s5k83a_ctrls[] = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_gain, - .get = s5k83a_get_gain - - }, -#define BRIGHTNESS_IDX 1 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_BRIGHTNESS, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_brightness, - .get = s5k83a_get_brightness, - }, -#define EXPOSURE_IDX 2 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = S5K83A_MAXIMUM_EXPOSURE, - .step = 0x01, - .default_value = S5K83A_DEFAULT_EXPOSURE, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_exposure, - .get = s5k83a_get_exposure - }, -#define HFLIP_IDX 3 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_hflip, - .get = s5k83a_get_hflip - }, -#define VFLIP_IDX 4 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_vflip, - .get = s5k83a_get_vflip - } -}; - static void s5k83a_dump_registers(struct sd *sd); static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); static int s5k83a_set_led_indication(struct sd *sd, u8 val); @@ -131,7 +49,6 @@ static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, int s5k83a_probe(struct sd *sd) { - struct s5k83a_priv *sens_priv; u8 prod_id = 0, ver_id = 0; int i, err = 0; @@ -173,38 +90,18 @@ int s5k83a_probe(struct sd *sd) pr_info("Detected a s5k83a sensor\n"); sensor_found: - sens_priv = kmalloc( - sizeof(struct s5k83a_priv), GFP_KERNEL); - if (!sens_priv) - return -ENOMEM; - - sens_priv->settings = - kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); - if (!sens_priv->settings) { - kfree(sens_priv); - return -ENOMEM; - } - sd->gspca_dev.cam.cam_mode = s5k83a_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); - sd->desc->ctrls = s5k83a_ctrls; - sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); /* null the pointer! thread is't running now */ - sens_priv->rotation_thread = NULL; - - for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) - sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; + sd->rotation_thread = NULL; - sd->sensor_priv = sens_priv; return 0; } int s5k83a_init(struct sd *sd) { int i, err = 0; - s32 *sensor_settings = - ((struct s5k83a_priv *) sd->sensor_priv)->settings; for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { u8 data[2] = {0x00, 0x00}; @@ -237,33 +134,44 @@ int s5k83a_init(struct sd *sd) if (dump_sensor) s5k83a_dump_registers(sd); - err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; + return err; +} - err = s5k83a_set_brightness(&sd->gspca_dev, - sensor_settings[BRIGHTNESS_IDX]); - if (err < 0) - return err; +int s5k83a_init_controls(struct sd *sd) +{ + struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - err = s5k83a_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; + sd->gspca_dev.vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 6); - err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; + v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_BRIGHTNESS, + 0, 255, 1, S5K83A_DEFAULT_BRIGHTNESS); - err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); + v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_EXPOSURE, + 0, S5K83A_MAXIMUM_EXPOSURE, 1, + S5K83A_DEFAULT_EXPOSURE); - return err; + v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_GAIN, + 0, 255, 1, S5K83A_DEFAULT_GAIN); + + sd->hflip = v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_HFLIP, + 0, 1, 1, 0); + sd->vflip = v4l2_ctrl_new_std(hdl, &s5k83a_ctrl_ops, V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(2, &sd->hflip); + + return 0; } static int rotation_thread_function(void *data) { struct sd *sd = (struct sd *) data; - struct s5k83a_priv *sens_priv = sd->sensor_priv; u8 reg, previous_rotation = 0; __s32 vflip, hflip; @@ -277,8 +185,8 @@ static int rotation_thread_function(void *data) previous_rotation = reg; pr_info("Camera was flipped\n"); - s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); - s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); + hflip = sd->hflip->val; + vflip = sd->vflip->val; if (reg) { vflip = !vflip; @@ -294,26 +202,25 @@ static int rotation_thread_function(void *data) /* return to "front" flip */ if (previous_rotation) { - s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); - s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); + hflip = sd->hflip->val; + vflip = sd->vflip->val; s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); } - sens_priv->rotation_thread = NULL; + sd->rotation_thread = NULL; return 0; } int s5k83a_start(struct sd *sd) { int i, err = 0; - struct s5k83a_priv *sens_priv = sd->sensor_priv; /* Create another thread, polling the GPIO ports of the camera to check if it got rotated. This is how the windows driver does it so we have to assume that there is no better way of accomplishing this */ - sens_priv->rotation_thread = kthread_create(rotation_thread_function, - sd, "rotation thread"); - wake_up_process(sens_priv->rotation_thread); + sd->rotation_thread = kthread_create(rotation_thread_function, + sd, "rotation thread"); + wake_up_process(sd->rotation_thread); /* Preinit the sensor */ for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { @@ -333,32 +240,17 @@ int s5k83a_start(struct sd *sd) int s5k83a_stop(struct sd *sd) { - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - if (sens_priv->rotation_thread) - kthread_stop(sens_priv->rotation_thread); + if (sd->rotation_thread) + kthread_stop(sd->rotation_thread); return s5k83a_set_led_indication(sd, 0); } void s5k83a_disconnect(struct sd *sd) { - struct s5k83a_priv *sens_priv = sd->sensor_priv; - s5k83a_stop(sd); sd->sensor = NULL; - kfree(sens_priv->settings); - kfree(sens_priv); -} - -static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[GAIN_IDX]; - return 0; } static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) @@ -366,9 +258,6 @@ static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) int err; u8 data[2]; struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[GAIN_IDX] = val; data[0] = 0x00; data[1] = 0x20; @@ -391,60 +280,29 @@ static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) return err; } -static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[BRIGHTNESS_IDX]; - return 0; -} - static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 data[1]; struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - sens_priv->settings[BRIGHTNESS_IDX] = val; data[0] = val; err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); return err; } -static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[EXPOSURE_IDX]; - return 0; -} - static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 data[2]; struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - sens_priv->settings[EXPOSURE_IDX] = val; data[0] = 0; data[1] = val; err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); return err; } -static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[VFLIP_IDX]; - return 0; -} - static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip) { @@ -476,60 +334,52 @@ static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, return err; } -static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) +static int s5k83a_set_hvflip(struct gspca_dev *gspca_dev) { int err; u8 reg; - __s32 hflip; struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[VFLIP_IDX] = val; - - s5k83a_get_hflip(gspca_dev, &hflip); + int hflip = sd->hflip->val; + int vflip = sd->vflip->val; err = s5k83a_get_rotation(sd, ®); if (err < 0) return err; if (reg) { - val = !val; hflip = !hflip; + vflip = !vflip; } - err = s5k83a_set_flip_real(gspca_dev, val, hflip); + err = s5k83a_set_flip_real(gspca_dev, vflip, hflip); return err; } -static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[HFLIP_IDX]; - return 0; -} - -static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) +static int s5k83a_s_ctrl(struct v4l2_ctrl *ctrl) { + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); int err; - u8 reg; - __s32 vflip; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[HFLIP_IDX] = val; - s5k83a_get_vflip(gspca_dev, &vflip); - - err = s5k83a_get_rotation(sd, ®); - if (err < 0) - return err; - if (reg) { - val = !val; - vflip = !vflip; + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + err = s5k83a_set_brightness(gspca_dev, ctrl->val); + break; + case V4L2_CID_EXPOSURE: + err = s5k83a_set_exposure(gspca_dev, ctrl->val); + break; + case V4L2_CID_GAIN: + err = s5k83a_set_gain(gspca_dev, ctrl->val); + break; + case V4L2_CID_HFLIP: + err = s5k83a_set_hvflip(gspca_dev); + break; + default: + return -EINVAL; } - err = s5k83a_set_flip_real(gspca_dev, vflip, val); return err; } diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.h b/drivers/media/usb/gspca/m5602/m5602_s5k83a.h index 79952247b534..d61b918228df 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.h @@ -45,6 +45,7 @@ extern bool dump_sensor; int s5k83a_probe(struct sd *sd); int s5k83a_init(struct sd *sd); +int s5k83a_init_controls(struct sd *sd); int s5k83a_start(struct sd *sd); int s5k83a_stop(struct sd *sd); void s5k83a_disconnect(struct sd *sd); @@ -53,6 +54,7 @@ static const struct m5602_sensor s5k83a = { .name = "S5K83A", .probe = s5k83a_probe, .init = s5k83a_init, + .init_controls = s5k83a_init_controls, .start = s5k83a_start, .stop = s5k83a_stop, .disconnect = s5k83a_disconnect, @@ -60,13 +62,6 @@ static const struct m5602_sensor s5k83a = { .i2c_regW = 2, }; -struct s5k83a_priv { - /* We use another thread periodically - probing the orientation of the camera */ - struct task_struct *rotation_thread; - s32 *settings; -}; - static const unsigned char preinit_s5k83a[][4] = { {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, diff --git a/drivers/media/usb/gspca/m5602/m5602_sensor.h b/drivers/media/usb/gspca/m5602/m5602_sensor.h index edff4f1f586f..48341b4d607b 100644 --- a/drivers/media/usb/gspca/m5602/m5602_sensor.h +++ b/drivers/media/usb/gspca/m5602/m5602_sensor.h @@ -57,6 +57,9 @@ struct m5602_sensor { /* Performs a initialization sequence */ int (*init)(struct sd *sd); + /* Controls initialization, maybe NULL */ + int (*init_controls)(struct sd *sd); + /* Executed when the camera starts to send data */ int (*start)(struct sd *sd); -- cgit From 9f8c734735f97fa36a1b4ce89a5f4126b321ff3b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 11 Feb 2013 06:31:55 -0300 Subject: [media] gspca_sonixb: Remove querymenu function (dead code) We forgot to remove that when sonixb was converted to the control framework. Signed-off-by: Hans Verkuil Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sonixb.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index 104ae25275b4..3fe207e038c7 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c @@ -1379,27 +1379,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - switch (menu->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - } - break; - } - return -EINVAL; -} - #if IS_ENABLED(CONFIG_INPUT) static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, /* interrupt packet data */ @@ -1428,7 +1407,6 @@ static const struct sd_desc sd_desc = { .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, - .querymenu = sd_querymenu, .dq_callback = do_autogain, #if IS_ENABLED(CONFIG_INPUT) .int_pkt_scan = sd_int_pkt_scan, -- cgit From 2effe6de386212fe721aae132ee4735cd37a9b13 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 17 Feb 2013 17:11:25 -0300 Subject: [media] gscpa: Remove autogain_functions.h Now that sonixj.c has been converted to the control framework it is no longer used. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/autogain_functions.h | 183 --------------------------- 1 file changed, 183 deletions(-) delete mode 100644 drivers/media/usb/gspca/autogain_functions.h (limited to 'drivers') diff --git a/drivers/media/usb/gspca/autogain_functions.h b/drivers/media/usb/gspca/autogain_functions.h deleted file mode 100644 index d625eafe63eb..000000000000 --- a/drivers/media/usb/gspca/autogain_functions.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Functions for auto gain. - * - * Copyright (C) 2010-2011 Hans de Goede - * - * 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 - */ - -#ifdef WANT_REGULAR_AUTOGAIN -/* auto gain and exposure algorithm based on the knee algorithm described here: - http://ytse.tricolour.net/docs/LowLightOptimization.html - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -static inline int auto_gain_n_exposure( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone, - int gain_knee, - int exposure_knee) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, steps, gain, orig_gain, exposure, orig_exposure; - int retval = 0; - - orig_gain = gain = sd->ctrls[GAIN].val; - orig_exposure = exposure = sd->ctrls[EXPOSURE].val; - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = abs(desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - for (i = 0; i < steps; i++) { - if (avg_lum > desired_avg_lum) { - if (gain > gain_knee) - gain--; - else if (exposure > exposure_knee) - exposure--; - else if (gain > sd->ctrls[GAIN].def) - gain--; - else if (exposure > sd->ctrls[EXPOSURE].min) - exposure--; - else if (gain > sd->ctrls[GAIN].min) - gain--; - else - break; - } else { - if (gain < sd->ctrls[GAIN].def) - gain++; - else if (exposure < exposure_knee) - exposure++; - else if (gain < gain_knee) - gain++; - else if (exposure < sd->ctrls[EXPOSURE].max) - exposure++; - else if (gain < sd->ctrls[GAIN].max) - gain++; - else - break; - } - } - - if (gain != orig_gain) { - sd->ctrls[GAIN].val = gain; - setgain(gspca_dev); - retval = 1; - } - if (exposure != orig_exposure) { - sd->ctrls[EXPOSURE].val = exposure; - setexposure(gspca_dev); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -#endif - -#ifdef WANT_COARSE_EXPO_AUTOGAIN -/* Autogain + exposure algorithm for cameras with a coarse exposure control - (usually this means we can only control the clockdiv to change exposure) - As changing the clockdiv so that the fps drops from 30 to 15 fps for - example, will lead to a huge exposure change (it effectively doubles), - this algorithm normally tries to only adjust the gain (between 40 and - 80 %) and if that does not help, only then changes exposure. This leads - to a much more stable image then using the knee algorithm which at - certain points of the knee graph will only try to adjust exposure, - which leads to oscilating as one exposure step is huge. - - Note this assumes that the sd struct for the cam in question has - exp_too_low_cnt and exp_too_high_cnt int members for use by this function. - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -static inline int coarse_grained_expo_autogain( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone) -{ - struct sd *sd = (struct sd *) gspca_dev; - int steps, gain, orig_gain, exposure, orig_exposure; - int gain_low, gain_high; - int retval = 0; - - orig_gain = gain = sd->ctrls[GAIN].val; - orig_exposure = exposure = sd->ctrls[EXPOSURE].val; - - gain_low = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 2; - gain_low += sd->ctrls[GAIN].min; - gain_high = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 4; - gain_high += sd->ctrls[GAIN].min; - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = (desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - if ((gain + steps) > gain_high && - exposure < sd->ctrls[EXPOSURE].max) { - gain = gain_high; - sd->exp_too_low_cnt++; - sd->exp_too_high_cnt = 0; - } else if ((gain + steps) < gain_low && - exposure > sd->ctrls[EXPOSURE].min) { - gain = gain_low; - sd->exp_too_high_cnt++; - sd->exp_too_low_cnt = 0; - } else { - gain += steps; - if (gain > sd->ctrls[GAIN].max) - gain = sd->ctrls[GAIN].max; - else if (gain < sd->ctrls[GAIN].min) - gain = sd->ctrls[GAIN].min; - sd->exp_too_high_cnt = 0; - sd->exp_too_low_cnt = 0; - } - - if (sd->exp_too_high_cnt > 3) { - exposure--; - sd->exp_too_high_cnt = 0; - } else if (sd->exp_too_low_cnt > 3) { - exposure++; - sd->exp_too_low_cnt = 0; - } - - if (gain != orig_gain) { - sd->ctrls[GAIN].val = gain; - setgain(gspca_dev); - retval = 1; - } - if (exposure != orig_exposure) { - sd->ctrls[EXPOSURE].val = exposure; - setexposure(gspca_dev); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -#endif -- cgit From 70c8ecf54bf735f300f86bde562420af90bf9db4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 16 Feb 2013 14:42:59 -0300 Subject: [media] gspca: Remove old control code now that all drivers are converted Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/gspca.c | 160 ---------------------------------------- drivers/media/usb/gspca/gspca.h | 24 ------ 2 files changed, 184 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 3564bdbb2ea3..5784ff4e1b2f 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -984,7 +984,6 @@ out: static void gspca_set_default_mode(struct gspca_dev *gspca_dev) { - struct gspca_ctrl *ctrl; int i; i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ @@ -993,17 +992,8 @@ static void gspca_set_default_mode(struct gspca_dev *gspca_dev) gspca_dev->height = gspca_dev->cam.cam_mode[i].height; gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; - /* set the current control values to their default values - * which may have changed in sd_init() */ /* does nothing if ctrl_handler == NULL */ v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); - ctrl = gspca_dev->cam.ctrls; - if (ctrl != NULL) { - for (i = 0; - i < gspca_dev->sd_desc->nctrls; - i++, ctrl++) - ctrl->val = ctrl->def; - } } static int wxh_to_mode(struct gspca_dev *gspca_dev, @@ -1357,134 +1347,6 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int get_ctrl(struct gspca_dev *gspca_dev, - int id) -{ - const struct ctrl *ctrls; - int i; - - for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; - i < gspca_dev->sd_desc->nctrls; - i++, ctrls++) { - if (gspca_dev->ctrl_dis & (1 << i)) - continue; - if (id == ctrls->qctrl.id) - return i; - } - return -1; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *q_ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - struct gspca_ctrl *gspca_ctrl; - int i, idx; - u32 id; - - id = q_ctrl->id; - if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { - id &= V4L2_CTRL_ID_MASK; - id++; - idx = -1; - for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { - if (gspca_dev->ctrl_dis & (1 << i)) - continue; - if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) - continue; - if (idx >= 0 - && gspca_dev->sd_desc->ctrls[i].qctrl.id - > gspca_dev->sd_desc->ctrls[idx].qctrl.id) - continue; - idx = i; - } - } else { - idx = get_ctrl(gspca_dev, id); - } - if (idx < 0) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl); - if (gspca_dev->cam.ctrls != NULL) { - gspca_ctrl = &gspca_dev->cam.ctrls[idx]; - q_ctrl->default_value = gspca_ctrl->def; - q_ctrl->minimum = gspca_ctrl->min; - q_ctrl->maximum = gspca_ctrl->max; - } - if (gspca_dev->ctrl_inac & (1 << idx)) - q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - struct gspca_ctrl *gspca_ctrl; - int idx; - - idx = get_ctrl(gspca_dev, ctrl->id); - if (idx < 0) - return -EINVAL; - if (gspca_dev->ctrl_inac & (1 << idx)) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - if (gspca_dev->cam.ctrls != NULL) { - gspca_ctrl = &gspca_dev->cam.ctrls[idx]; - if (ctrl->value < gspca_ctrl->min - || ctrl->value > gspca_ctrl->max) - return -ERANGE; - } else { - gspca_ctrl = NULL; - if (ctrl->value < ctrls->qctrl.minimum - || ctrl->value > ctrls->qctrl.maximum) - return -ERANGE; - } - PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); - gspca_dev->usb_err = 0; - if (ctrls->set != NULL) - return ctrls->set(gspca_dev, ctrl->value); - if (gspca_ctrl != NULL) { - gspca_ctrl->val = ctrl->value; - if (ctrls->set_control != NULL - && gspca_dev->streaming) - ctrls->set_control(gspca_dev); - } - return gspca_dev->usb_err; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - int idx; - - idx = get_ctrl(gspca_dev, ctrl->id); - if (idx < 0) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - - gspca_dev->usb_err = 0; - if (ctrls->get != NULL) - return ctrls->get(gspca_dev, &ctrl->value); - if (gspca_dev->cam.ctrls != NULL) - ctrl->value = gspca_dev->cam.ctrls[idx].val; - return 0; -} - -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *qmenu) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - if (!gspca_dev->sd_desc->querymenu) - return -ENOTTY; - return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu); -} - static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *input) { @@ -2125,10 +1987,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_streamon = vidioc_streamon, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_querymenu = vidioc_querymenu, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, @@ -2157,22 +2015,6 @@ static const struct video_device gspca_template = { .release = video_device_release_empty, /* We use v4l2_dev.release */ }; -/* initialize the controls */ -static void ctrls_init(struct gspca_dev *gspca_dev) -{ - struct gspca_ctrl *ctrl; - int i; - - for (i = 0, ctrl = gspca_dev->cam.ctrls; - i < gspca_dev->sd_desc->nctrls; - i++, ctrl++) { - ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value; - ctrl->val = ctrl->def; - ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum; - ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum; - } -} - /* * probe and create a new gspca device * @@ -2249,8 +2091,6 @@ int gspca_dev_probe2(struct usb_interface *intf, ret = sd_desc->config(gspca_dev, id); if (ret < 0) goto out; - if (gspca_dev->cam.ctrls != NULL) - ctrls_init(gspca_dev); ret = sd_desc->init(gspca_dev); if (ret < 0) goto out; diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index 5559932bf2f5..ac62cd3b590e 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h @@ -46,20 +46,11 @@ struct framerates { int nrates; }; -/* control definition */ -struct gspca_ctrl { - s16 val; /* current value */ - s16 def; /* default value */ - s16 min, max; /* minimum and maximum values */ -}; - /* device information - set at probe time */ struct cam { const struct v4l2_pix_format *cam_mode; /* size nmodes */ const struct framerates *mode_framerates; /* must have size nmodes, * just like cam_mode */ - struct gspca_ctrl *ctrls; /* control table - size nctrls */ - /* may be NULL */ u32 bulk_size; /* buffer size when image transfer by bulk */ u32 input_flags; /* value for ENUM_INPUT status flags */ u8 nmodes; /* size of cam_mode */ @@ -93,8 +84,6 @@ typedef int (*cam_ident_op) (struct gspca_dev *, struct v4l2_dbg_chip_ident *); typedef void (*cam_streamparm_op) (struct gspca_dev *, struct v4l2_streamparm *); -typedef int (*cam_qmnu_op) (struct gspca_dev *, - struct v4l2_querymenu *); typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, u8 *data, int len); @@ -102,20 +91,10 @@ typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev, u8 *data, int len); -struct ctrl { - struct v4l2_queryctrl qctrl; - int (*set)(struct gspca_dev *, __s32); - int (*get)(struct gspca_dev *, __s32 *); - cam_v_op set_control; -}; - /* subdriver description */ struct sd_desc { /* information */ const char *name; /* sub-driver name */ -/* controls */ - const struct ctrl *ctrls; /* static control definition */ - int nctrls; /* mandatory operations */ cam_cf_op config; /* called on probe */ cam_op init; /* called on probe and resume */ @@ -130,7 +109,6 @@ struct sd_desc { cam_v_op dq_callback; /* called when a frame has been dequeued */ cam_get_jpg_op get_jcomp; cam_set_jpg_op set_jcomp; - cam_qmnu_op querymenu; cam_streamparm_op get_streamparm; cam_streamparm_op set_streamparm; #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -174,8 +152,6 @@ struct gspca_dev { struct cam cam; /* device information */ const struct sd_desc *sd_desc; /* subdriver description */ - unsigned ctrl_dis; /* disabled controls (bit map) */ - unsigned ctrl_inac; /* inactive controls (bit map) */ struct v4l2_ctrl_handler ctrl_handler; /* autogain and exposure or gain control cluster, these are global as -- cgit From c93396e13576928a073154b5715761ff8a998368 Mon Sep 17 00:00:00 2001 From: Theodore Kilgore Date: Mon, 4 Feb 2013 13:17:55 -0300 Subject: [media] gspca: Remove gspca-specific debug magic Instead use v4l2_dbg and v4l2_err. Note that the PDEBUG macro is kept to make this patch-set less invasive, but it is simply a wrapper around v4l2_dbg now. Most of the other changes are there to make the dev parameter for the v4l2_xxx macros available everywhere we do logging. Signed-off-by: Theodore Kilgore Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/benq.c | 2 +- drivers/media/usb/gspca/conex.c | 12 ++-- drivers/media/usb/gspca/cpia1.c | 33 +++++----- drivers/media/usb/gspca/etoms.c | 10 ++- drivers/media/usb/gspca/gl860/gl860.c | 2 +- drivers/media/usb/gspca/gspca.c | 69 ++++++-------------- drivers/media/usb/gspca/gspca.h | 40 ++++++------ drivers/media/usb/gspca/jeilinj.c | 2 +- drivers/media/usb/gspca/konica.c | 28 ++++---- drivers/media/usb/gspca/m5602/m5602_core.c | 6 +- drivers/media/usb/gspca/m5602/m5602_mt9m111.c | 18 +++--- drivers/media/usb/gspca/m5602/m5602_ov7660.c | 10 +-- drivers/media/usb/gspca/m5602/m5602_ov9650.c | 26 ++++---- drivers/media/usb/gspca/m5602/m5602_po1030.c | 21 +++--- drivers/media/usb/gspca/m5602/m5602_s5k4aa.c | 16 +++-- drivers/media/usb/gspca/m5602/m5602_s5k83a.c | 1 + drivers/media/usb/gspca/mr97310a.c | 8 +-- drivers/media/usb/gspca/ov519.c | 81 ++++++++++++++++-------- drivers/media/usb/gspca/ov534.c | 2 +- drivers/media/usb/gspca/pac207.c | 2 +- drivers/media/usb/gspca/pac7302.c | 7 +- drivers/media/usb/gspca/pac7311.c | 5 +- drivers/media/usb/gspca/pac_common.h | 2 +- drivers/media/usb/gspca/sn9c2028.c | 4 +- drivers/media/usb/gspca/sonixj.c | 11 ++-- drivers/media/usb/gspca/spca1528.c | 4 +- drivers/media/usb/gspca/spca500.c | 36 +++++------ drivers/media/usb/gspca/spca501.c | 44 ++++++------- drivers/media/usb/gspca/spca505.c | 42 ++++++------ drivers/media/usb/gspca/spca508.c | 41 ++++++------ drivers/media/usb/gspca/spca561.c | 70 ++++++++++---------- drivers/media/usb/gspca/sq905.c | 2 +- drivers/media/usb/gspca/sq905c.c | 6 +- drivers/media/usb/gspca/sq930x.c | 4 +- drivers/media/usb/gspca/stv0680.c | 14 ++-- drivers/media/usb/gspca/stv06xx/stv06xx.c | 17 +++-- drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c | 8 ++- drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c | 14 ++-- drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c | 2 + drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c | 10 +-- drivers/media/usb/gspca/sunplus.c | 27 +++----- drivers/media/usb/gspca/vc032x.c | 9 +-- drivers/media/usb/gspca/w996Xcf.c | 5 +- drivers/media/usb/gspca/zc3xx.c | 3 +- 44 files changed, 373 insertions(+), 403 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c index 352f32190e68..05f406deae13 100644 --- a/drivers/media/usb/gspca/benq.c +++ b/drivers/media/usb/gspca/benq.c @@ -186,7 +186,7 @@ static void sd_isoc_irq(struct urb *urb) /* check the packet status and length */ if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) { - PDEBUG(D_ERR, "ISOC bad lengths %d / %d", + PERR("ISOC bad lengths %d / %d", urb0->iso_frame_desc[i].actual_length, urb->iso_frame_desc[i].actual_length); gspca_dev->last_packet_type = DISCARD_PACKET; diff --git a/drivers/media/usb/gspca/conex.c b/drivers/media/usb/gspca/conex.c index c9052f20435e..38714df31ac4 100644 --- a/drivers/media/usb/gspca/conex.c +++ b/drivers/media/usb/gspca/conex.c @@ -73,12 +73,11 @@ static void reg_r(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); + PERR("reg_r: buffer overflow\n"); return; } -#endif + usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0, @@ -113,13 +112,12 @@ static void reg_w(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - pr_err("reg_w: buffer overflow\n"); + PERR("reg_w: buffer overflow\n"); return; } PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); -#endif + memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -689,7 +687,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) reg_w_val(gspca_dev, 0x0053, 0x00); } while (--retry); if (retry == 0) - PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); + PERR("Damned Errors sending jpeg Table"); /* send the qtable now */ reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */ length = 8; diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c index 1dcdd9f95f1c..064b53043b15 100644 --- a/drivers/media/usb/gspca/cpia1.c +++ b/drivers/media/usb/gspca/cpia1.c @@ -421,8 +421,7 @@ static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command) pipe = usb_sndctrlpipe(gspca_dev->dev, 0); requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE; } else { - PDEBUG(D_ERR, "Unexpected first byte of command: %x", - command[0]); + PERR("Unexpected first byte of command: %x", command[0]); return -EINVAL; } @@ -701,7 +700,7 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) params->qx3.cradled = 0; } -static void printstatus(struct cam_params *params) +static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params) { PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x", params->status.systemState, params->status.grabState, @@ -725,10 +724,9 @@ static int goto_low_power(struct gspca_dev *gspca_dev) if (sd->params.status.systemState != LO_POWER_STATE) { if (sd->params.status.systemState != WARM_BOOT_STATE) { - PDEBUG(D_ERR, - "unexpected state after lo power cmd: %02x", - sd->params.status.systemState); - printstatus(&sd->params); + PERR("unexpected state after lo power cmd: %02x", + sd->params.status.systemState); + printstatus(gspca_dev, &sd->params); } return -EIO; } @@ -756,9 +754,9 @@ static int goto_high_power(struct gspca_dev *gspca_dev) return ret; if (sd->params.status.systemState != HI_POWER_STATE) { - PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x", - sd->params.status.systemState); - printstatus(&sd->params); + PERR("unexpected state after hi power cmd: %02x", + sd->params.status.systemState); + printstatus(gspca_dev, &sd->params); return -EIO; } @@ -1449,8 +1447,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); if (sd->params.version.firmwareVersion != 1) { - PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", - sd->params.version.firmwareVersion); + PERR("only firmware version 1 is supported (got: %d)", + sd->params.version.firmwareVersion); return -ENODEV; } @@ -1475,9 +1473,9 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Start the camera in low power mode */ if (goto_low_power(gspca_dev)) { if (sd->params.status.systemState != WARM_BOOT_STATE) { - PDEBUG(D_ERR, "unexpected systemstate: %02x", - sd->params.status.systemState); - printstatus(&sd->params); + PERR("unexpected systemstate: %02x", + sd->params.status.systemState); + printstatus(gspca_dev, &sd->params); return -ENODEV; } @@ -1523,9 +1521,8 @@ static int sd_start(struct gspca_dev *gspca_dev) return ret; if (sd->params.status.fatalError) { - PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x", - sd->params.status.fatalError, - sd->params.status.vpStatus); + PERR("fatal_error: %04x, vp_status: %04x", + sd->params.status.fatalError, sd->params.status.vpStatus); return -EIO; } diff --git a/drivers/media/usb/gspca/etoms.c b/drivers/media/usb/gspca/etoms.c index 38f68e11c3a2..948a6357573d 100644 --- a/drivers/media/usb/gspca/etoms.c +++ b/drivers/media/usb/gspca/etoms.c @@ -163,12 +163,11 @@ static void reg_r(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); + PERR("reg_r: buffer overflow\n"); return; } -#endif + usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0, @@ -201,13 +200,12 @@ static void reg_w(struct gspca_dev *gspca_dev, { struct usb_device *dev = gspca_dev->dev; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { pr_err("reg_w: buffer overflow\n"); return; } PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); -#endif + memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -274,7 +272,7 @@ static int et_video(struct gspca_dev *gspca_dev, : 0); /* stopvideo */ ret = Et_WaitStatus(gspca_dev); if (ret != 0) - PDEBUG(D_ERR, "timeout video on/off"); + PERR("timeout video on/off"); return ret; } diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c index 96d9c28a748c..cb1e64ca59c9 100644 --- a/drivers/media/usb/gspca/gl860/gl860.c +++ b/drivers/media/usb/gspca/gl860/gl860.c @@ -582,7 +582,7 @@ int gl860_RTx(struct gspca_dev *gspca_dev, pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n", r, pref, req, val, index, len); else if (len > 1 && r < len) - PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len); + PERR("short ctrl transfer %d/%d", r, len); msleep(1); diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 5784ff4e1b2f..5800d65f9144 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -60,14 +60,14 @@ MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(GSPCA_VERSION); -#ifdef GSPCA_DEBUG -int gspca_debug = D_ERR | D_PROBE; +int gspca_debug; EXPORT_SYMBOL(gspca_debug); -static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) +static void PDEBUG_MODE(struct gspca_dev *gspca_dev, int debug, char *txt, + __u32 pixfmt, int w, int h) { if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') { - PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d", + PDEBUG(debug, "%s %c%c%c%c %dx%d", txt, pixfmt & 0xff, (pixfmt >> 8) & 0xff, @@ -75,15 +75,12 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) pixfmt >> 24, w, h); } else { - PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d", + PDEBUG(debug, "%s 0x%08x %dx%d", txt, pixfmt, w, h); } } -#else -#define PDEBUG_MODE(txt, pixfmt, w, h) -#endif /* specific memory types - !! should be different from V4L2_MEMORY_xxx */ #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ @@ -129,7 +126,7 @@ static void int_irq(struct urb *urb) case 0: if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev, urb->transfer_buffer, urb->actual_length) < 0) { - PDEBUG(D_ERR, "Unknown packet received"); + PERR("Unknown packet received"); } break; @@ -143,7 +140,7 @@ static void int_irq(struct urb *urb) break; default: - PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status); + PERR("URB error %i, resubmitting", urb->status); urb->status = 0; ret = 0; } @@ -229,7 +226,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret < 0) { - PDEBUG(D_ERR, "submit int URB failed with error %i", ret); + PERR("submit int URB failed with error %i", ret); goto error_submit; } gspca_dev->int_urb = urb; @@ -315,7 +312,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, if (gspca_dev->frozen) return; #endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + PERR("urb status: %d", urb->status); urb->status = 0; goto resubmit; } @@ -388,7 +385,7 @@ static void bulk_irq(struct urb *urb) if (gspca_dev->frozen) return; #endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + PERR("urb status: %d", urb->status); urb->status = 0; goto resubmit; } @@ -460,7 +457,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, /* append the packet to the frame buffer */ if (len > 0) { if (gspca_dev->image_len + len > gspca_dev->frsz) { - PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", + PERR("frame overflow %d > %d", gspca_dev->image_len + len, gspca_dev->frsz); packet_type = DISCARD_PACKET; @@ -960,9 +957,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* the bandwidth is not wide enough * negotiate or try a lower alternate setting */ retry: - PDEBUG(D_ERR|D_STREAM, - "alt %d - bandwidth not wide enough - trying again", - alt); + PERR("alt %d - bandwidth not wide enough, trying again", alt); msleep(20); /* wait for kill complete */ if (gspca_dev->sd_desc->isoc_nego) { ret = gspca_dev->sd_desc->isoc_nego(gspca_dev); @@ -1127,10 +1122,9 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, w = fmt->fmt.pix.width; h = fmt->fmt.pix.height; -#ifdef GSPCA_DEBUG - if (gspca_debug & D_CONF) - PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); -#endif + PDEBUG_MODE(gspca_dev, D_CONF, "try fmt cap", + fmt->fmt.pix.pixelformat, w, h); + /* search the closest mode for width and height */ mode = wxh_to_mode(gspca_dev, w, h); @@ -1143,8 +1137,6 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, fmt->fmt.pix.pixelformat); if (mode2 >= 0) mode = mode2; -/* else - ; * no chance, return this mode */ } fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; /* some drivers use priv internally, zero it before giving it to @@ -1280,15 +1272,6 @@ static int dev_open(struct file *file) if (!try_module_get(gspca_dev->module)) return -ENODEV; -#ifdef GSPCA_DEBUG - /* activate the v4l2 debug */ - if (gspca_debug & D_V4L2) - gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG; - else - gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG); -#endif return v4l2_fh_open(file); } @@ -1483,14 +1466,8 @@ static int vidioc_streamon(struct file *file, void *priv, if (ret < 0) goto out; } -#ifdef GSPCA_DEBUG - if (gspca_debug & D_STREAM) { - PDEBUG_MODE("stream on OK", - gspca_dev->pixfmt, - gspca_dev->width, - gspca_dev->height); - } -#endif + PDEBUG_MODE(gspca_dev, D_STREAM, "stream on OK", gspca_dev->pixfmt, + gspca_dev->width, gspca_dev->height); ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); @@ -1741,8 +1718,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, frame->data, frame->v4l2_buf.bytesused)) { - PDEBUG(D_ERR|D_STREAM, - "dqbuf cp to user failed"); + PERR("dqbuf cp to user failed"); ret = -EFAULT; } } @@ -1954,8 +1930,7 @@ static ssize_t dev_read(struct file *file, char __user *data, count = frame->v4l2_buf.bytesused; ret = copy_to_user(data, frame->data, count); if (ret != 0) { - PDEBUG(D_ERR|D_STREAM, - "read cp to user lack %d / %zd", ret, count); + PERR("read cp to user lack %d / %zd", ret, count); ret = -EFAULT; goto out; } @@ -2290,10 +2265,6 @@ static void __exit gspca_exit(void) module_init(gspca_init); module_exit(gspca_exit); -#ifdef GSPCA_DEBUG module_param_named(debug, gspca_debug, int, 0644); MODULE_PARM_DESC(debug, - "Debug (bit) 0x01:error 0x02:probe 0x04:config" - " 0x08:stream 0x10:frame 0x20:packet" - " 0x0100: v4l2"); -#endif + "1:probe 2:config 3:stream 4:frame 5:packet 6:usbi 7:usbo"); diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index ac62cd3b590e..c3af3212d51e 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h @@ -10,30 +10,26 @@ #include #include -/* compilation option */ -/*#define GSPCA_DEBUG 1*/ -#ifdef GSPCA_DEBUG -/* GSPCA our debug messages */ + +/* GSPCA debug codes */ + +#define D_PROBE 1 +#define D_CONF 2 +#define D_STREAM 3 +#define D_FRAM 4 +#define D_PACK 5 +#define D_USBI 6 +#define D_USBO 7 + extern int gspca_debug; -#define PDEBUG(level, fmt, ...) \ -do { \ - if (gspca_debug & (level)) \ - pr_info(fmt, ##__VA_ARGS__); \ -} while (0) - -#define D_ERR 0x01 -#define D_PROBE 0x02 -#define D_CONF 0x04 -#define D_STREAM 0x08 -#define D_FRAM 0x10 -#define D_PACK 0x20 -#define D_USBI 0x00 -#define D_USBO 0x00 -#define D_V4L2 0x0100 -#else -#define PDEBUG(level, fmt, ...) do {} while(0) -#endif + + +#define PDEBUG(level, fmt, ...) \ + v4l2_dbg(level, gspca_debug, &gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__) + +#define PERR(fmt, ...) \ + v4l2_err(&gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__) #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ /* image transfers */ diff --git a/drivers/media/usb/gspca/jeilinj.c b/drivers/media/usb/gspca/jeilinj.c index 1ba29fe7fada..8da3dde38385 100644 --- a/drivers/media/usb/gspca/jeilinj.c +++ b/drivers/media/usb/gspca/jeilinj.c @@ -266,7 +266,7 @@ static int jlj_start(struct gspca_dev *gspca_dev) msleep(2); setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq)); if (gspca_dev->usb_err < 0) - PDEBUG(D_ERR, "Start streaming command failed"); + PERR("Start streaming command failed"); return gspca_dev->usb_err; } diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c index 61e25dbf2447..39c96bb4c985 100644 --- a/drivers/media/usb/gspca/konica.c +++ b/drivers/media/usb/gspca/konica.c @@ -277,7 +277,7 @@ static void sd_isoc_irq(struct urb *urb) if (gspca_dev->frozen) return; #endif - PDEBUG(D_ERR, "urb status: %d", urb->status); + PERR("urb status: %d", urb->status); st = usb_submit_urb(urb, GFP_ATOMIC); if (st < 0) pr_err("resubmit urb error %d\n", st); @@ -295,33 +295,30 @@ static void sd_isoc_irq(struct urb *urb) sd->last_data_urb = NULL; if (!data_urb || data_urb->start_frame != status_urb->start_frame) { - PDEBUG(D_ERR|D_PACK, "lost sync on frames"); + PERR("lost sync on frames"); goto resubmit; } if (data_urb->number_of_packets != status_urb->number_of_packets) { - PDEBUG(D_ERR|D_PACK, - "no packets does not match, data: %d, status: %d", - data_urb->number_of_packets, - status_urb->number_of_packets); + PERR("no packets does not match, data: %d, status: %d", + data_urb->number_of_packets, + status_urb->number_of_packets); goto resubmit; } for (i = 0; i < status_urb->number_of_packets; i++) { if (data_urb->iso_frame_desc[i].status || status_urb->iso_frame_desc[i].status) { - PDEBUG(D_ERR|D_PACK, - "pkt %d data-status %d, status-status %d", i, - data_urb->iso_frame_desc[i].status, - status_urb->iso_frame_desc[i].status); + PERR("pkt %d data-status %d, status-status %d", i, + data_urb->iso_frame_desc[i].status, + status_urb->iso_frame_desc[i].status); gspca_dev->last_packet_type = DISCARD_PACKET; continue; } if (status_urb->iso_frame_desc[i].actual_length != 1) { - PDEBUG(D_ERR|D_PACK, - "bad status packet length %d", - status_urb->iso_frame_desc[i].actual_length); + PERR("bad status packet length %d", + status_urb->iso_frame_desc[i].actual_length); gspca_dev->last_packet_type = DISCARD_PACKET; continue; } @@ -366,12 +363,11 @@ resubmit: if (data_urb) { st = usb_submit_urb(data_urb, GFP_ATOMIC); if (st < 0) - PDEBUG(D_ERR|D_PACK, - "usb_submit_urb(data_urb) ret %d", st); + PERR("usb_submit_urb(data_urb) ret %d", st); } st = usb_submit_urb(status_urb, GFP_ATOMIC); if (st < 0) - pr_err("usb_submit_urb(status_urb) ret %d\n", st); + PERR("usb_submit_urb(status_urb) ret %d\n", st); } static int sd_s_ctrl(struct v4l2_ctrl *ctrl) diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c index 907a968f474d..d926e62cb80b 100644 --- a/drivers/media/usb/gspca/m5602/m5602_core.c +++ b/drivers/media/usb/gspca/m5602/m5602_core.c @@ -41,6 +41,7 @@ MODULE_DEVICE_TABLE(usb, m5602_table); int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *) sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -62,6 +63,7 @@ int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *) sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -98,6 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address, u8 *i2c_data, const u8 len) { int err, i; + struct gspca_dev *gspca_dev = (struct gspca_dev *) sd; if (!len || len > sd->sensor->i2c_regW) return -EINVAL; @@ -147,6 +150,7 @@ int m5602_write_sensor(struct sd *sd, const u8 address, { int err, i; u8 *p; + struct gspca_dev *gspca_dev = (struct gspca_dev *) sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -378,7 +382,7 @@ static int m5602_configure(struct gspca_dev *gspca_dev, return 0; fail: - PDEBUG(D_ERR, "ALi m5602 webcam failed"); + PERR("ALi m5602 webcam failed"); cam->cam_mode = NULL; cam->nmodes = 0; diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c index b5f66921b3eb..cfa4663f8934 100644 --- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c @@ -56,6 +56,7 @@ int mt9m111_probe(struct sd *sd) { u8 data[2] = {0x00, 0x00}; int i; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { if (force_sensor == MT9M111_SENSOR) { @@ -169,6 +170,7 @@ int mt9m111_start(struct sd *sd) int i, err = 0; u8 data[2]; struct cam *cam = &sd->gspca_dev.cam; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; @@ -229,11 +231,11 @@ int mt9m111_start(struct sd *sd) switch (width) { case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); + PDEBUG(D_CONF, "Configuring camera for VGA mode"); break; case 320: - PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); + PDEBUG(D_CONF, "Configuring camera for QVGA mode"); break; } return err; @@ -252,7 +254,7 @@ static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev) int hflip; int vflip; - PDEBUG(D_V4L2, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val); + PDEBUG(D_CONF, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val); /* The mt9m111 is flipped by default */ hflip = !sd->hflip->val; @@ -293,7 +295,7 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); - PDEBUG(D_V4L2, "Set auto white balance %d", val); + PDEBUG(D_CONF, "Set auto white balance %d", val); return err; } @@ -326,7 +328,7 @@ static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) data[1] = (tmp & 0xff); data[0] = (tmp & 0xff00) >> 8; - PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, + PDEBUG(D_CONF, "tmp=%d, data[1]=%d, data[0]=%d", tmp, data[1], data[0]); err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, @@ -344,7 +346,7 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; - PDEBUG(D_V4L2, "Set green balance %d", val); + PDEBUG(D_CONF, "Set green balance %d", val); err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, data, 2); if (err < 0) @@ -362,7 +364,7 @@ static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; - PDEBUG(D_V4L2, "Set blue balance %d", val); + PDEBUG(D_CONF, "Set blue balance %d", val); return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, data, 2); @@ -376,7 +378,7 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) data[1] = (val & 0xff); data[0] = (val & 0xff00) >> 8; - PDEBUG(D_V4L2, "Set red balance %d", val); + PDEBUG(D_CONF, "Set red balance %d", val); return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, data, 2); diff --git a/drivers/media/usb/gspca/m5602/m5602_ov7660.c b/drivers/media/usb/gspca/m5602/m5602_ov7660.c index 3bbe3ad5d4a9..4ac78893cc5f 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov7660.c +++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.c @@ -175,7 +175,7 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data = val; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Setting gain to %d", val); + PDEBUG(D_CONF, "Setting gain to %d", val); err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); return err; @@ -188,7 +188,7 @@ static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto white balance to %d", val); + PDEBUG(D_CONF, "Set auto white balance to %d", val); err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) @@ -206,7 +206,7 @@ static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto gain control to %d", val); + PDEBUG(D_CONF, "Set auto gain control to %d", val); err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) @@ -224,7 +224,7 @@ static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto exposure control to %d", val); + PDEBUG(D_CONF, "Set auto exposure control to %d", val); err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); if (err < 0) @@ -242,7 +242,7 @@ static int ov7660_set_hvflip(struct gspca_dev *gspca_dev) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set hvflip to %d, %d", sd->hflip->val, sd->vflip->val); + PDEBUG(D_CONF, "Set hvflip to %d, %d", sd->hflip->val, sd->vflip->val); i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4); diff --git a/drivers/media/usb/gspca/m5602/m5602_ov9650.c b/drivers/media/usb/gspca/m5602/m5602_ov9650.c index e2fe2f942fe6..59bc62bfae26 100644 --- a/drivers/media/usb/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.c @@ -147,6 +147,7 @@ int ov9650_probe(struct sd *sd) { int err = 0; u8 prod_id = 0, ver_id = 0, i; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { if (force_sensor == OV9650_SENSOR) { @@ -268,6 +269,7 @@ int ov9650_start(struct sd *sd) int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; int hor_offs = OV9650_LEFT_OFFSET; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if ((!dmi_check_system(ov9650_flip_dmi_table) && sd->vflip->val) || @@ -351,7 +353,7 @@ int ov9650_start(struct sd *sd) switch (width) { case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); + PDEBUG(D_CONF, "Configuring camera for VGA mode"); data = OV9650_VGA_SELECT | OV9650_RGB_SELECT | OV9650_RAW_RGB_SELECT; @@ -359,7 +361,7 @@ int ov9650_start(struct sd *sd) break; case 352: - PDEBUG(D_V4L2, "Configuring camera for CIF mode"); + PDEBUG(D_CONF, "Configuring camera for CIF mode"); data = OV9650_CIF_SELECT | OV9650_RGB_SELECT | OV9650_RAW_RGB_SELECT; @@ -367,7 +369,7 @@ int ov9650_start(struct sd *sd) break; case 320: - PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); + PDEBUG(D_CONF, "Configuring camera for QVGA mode"); data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT | OV9650_RAW_RGB_SELECT; @@ -375,7 +377,7 @@ int ov9650_start(struct sd *sd) break; case 176: - PDEBUG(D_V4L2, "Configuring camera for QCIF mode"); + PDEBUG(D_CONF, "Configuring camera for QCIF mode"); data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT | OV9650_RAW_RGB_SELECT; @@ -404,7 +406,7 @@ static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; int err; - PDEBUG(D_V4L2, "Set exposure to %d", val); + PDEBUG(D_CONF, "Set exposure to %d", val); /* The 6 MSBs */ i2c_data = (val >> 10) & 0x3f; @@ -432,7 +434,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Setting gain to %d", val); + PDEBUG(D_CONF, "Setting gain to %d", val); /* The 2 MSB */ /* Read the OV9650_VREF register first to avoid @@ -460,7 +462,7 @@ static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set red gain to %d", val); + PDEBUG(D_CONF, "Set red gain to %d", val); i2c_data = val & 0xff; err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); @@ -473,7 +475,7 @@ static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set blue gain to %d", val); + PDEBUG(D_CONF, "Set blue gain to %d", val); i2c_data = val & 0xff; err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); @@ -488,7 +490,7 @@ static int ov9650_set_hvflip(struct gspca_dev *gspca_dev) int hflip = sd->hflip->val; int vflip = sd->vflip->val; - PDEBUG(D_V4L2, "Set hvflip to %d %d", hflip, vflip); + PDEBUG(D_CONF, "Set hvflip to %d %d", hflip, vflip); if (dmi_check_system(ov9650_flip_dmi_table)) vflip = !vflip; @@ -512,7 +514,7 @@ static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto exposure control to %d", val); + PDEBUG(D_CONF, "Set auto exposure control to %d", val); err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) @@ -531,7 +533,7 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto white balance to %d", val); + PDEBUG(D_CONF, "Set auto white balance to %d", val); err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) @@ -549,7 +551,7 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set auto gain control to %d", val); + PDEBUG(D_CONF, "Set auto gain control to %d", val); err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); if (err < 0) diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c index 189086291303..4bf5c43424b7 100644 --- a/drivers/media/usb/gspca/m5602/m5602_po1030.c +++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c @@ -55,6 +55,7 @@ static const struct v4l2_ctrl_config po1030_greenbal_cfg = { int po1030_probe(struct sd *sd) { u8 dev_id_h = 0, i; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { if (force_sensor == PO1030_SENSOR) { @@ -305,10 +306,10 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 i2c_data; int err; - PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); + PDEBUG(D_CONF, "Set exposure to %d", val & 0xffff); i2c_data = ((val & 0xff00) >> 8); - PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", + PDEBUG(D_CONF, "Set exposure to high byte to 0x%x", i2c_data); err = m5602_write_sensor(sd, PO1030_INTEGLINES_H, @@ -317,7 +318,7 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) return err; i2c_data = (val & 0xff); - PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", + PDEBUG(D_CONF, "Set exposure to low byte to 0x%x", i2c_data); err = m5602_write_sensor(sd, PO1030_INTEGLINES_M, &i2c_data, 1); @@ -332,7 +333,7 @@ static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); + PDEBUG(D_CONF, "Set global gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, &i2c_data, 1); return err; @@ -344,7 +345,7 @@ static int po1030_set_hvflip(struct gspca_dev *gspca_dev) u8 i2c_data; int err; - PDEBUG(D_V4L2, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val); + PDEBUG(D_CONF, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val); err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); if (err < 0) return err; @@ -365,7 +366,7 @@ static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); + PDEBUG(D_CONF, "Set red gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_RED_GAIN, &i2c_data, 1); return err; @@ -378,7 +379,7 @@ static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); + PDEBUG(D_CONF, "Set blue gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, &i2c_data, 1); @@ -392,7 +393,7 @@ static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) int err; i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); + PDEBUG(D_CONF, "Set green gain to %d", i2c_data); err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN, &i2c_data, 1); @@ -414,7 +415,7 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, if (err < 0) return err; - PDEBUG(D_V4L2, "Set auto white balance to %d", val); + PDEBUG(D_CONF, "Set auto white balance to %d", val); i2c_data = (i2c_data & 0xfe) | (val & 0x01); err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); return err; @@ -431,7 +432,7 @@ static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, if (err < 0) return err; - PDEBUG(D_V4L2, "Set auto exposure to %d", val); + PDEBUG(D_CONF, "Set auto exposure to %d", val); val = (val == V4L2_EXPOSURE_AUTO); i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c index 42ffaf04771c..7d12599458e2 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c @@ -145,6 +145,7 @@ int s5k4aa_probe(struct sd *sd) { u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int i, err = 0; if (force_sensor) { @@ -215,10 +216,11 @@ int s5k4aa_start(struct sd *sd) int i, err = 0; u8 data[2]; struct cam *cam = &sd->gspca_dev.cam; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { case 1280: - PDEBUG(D_V4L2, "Configuring camera for SXGA mode"); + PDEBUG(D_CONF, "Configuring camera for SXGA mode"); for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) { switch (SXGA_s5k4aa[i][0]) { @@ -251,7 +253,7 @@ int s5k4aa_start(struct sd *sd) break; case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); + PDEBUG(D_CONF, "Configuring camera for VGA mode"); for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) { switch (VGA_s5k4aa[i][0]) { @@ -367,7 +369,7 @@ static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set exposure to %d", val); + PDEBUG(D_CONF, "Set exposure to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; @@ -389,7 +391,7 @@ static int s5k4aa_set_hvflip(struct gspca_dev *gspca_dev) int hflip = sd->hflip->val; int vflip = sd->vflip->val; - PDEBUG(D_V4L2, "Set hvflip %d %d", hflip, vflip); + PDEBUG(D_CONF, "Set hvflip %d %d", hflip, vflip); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; @@ -439,7 +441,7 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set gain to %d", val); + PDEBUG(D_CONF, "Set gain to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; @@ -456,7 +458,7 @@ static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set brightness to %d", val); + PDEBUG(D_CONF, "Set brightness to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; @@ -471,7 +473,7 @@ static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) u8 data = S5K4AA_PAGE_MAP_2; int err; - PDEBUG(D_V4L2, "Set noise to %d", val); + PDEBUG(D_CONF, "Set noise to %d", val); err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); if (err < 0) return err; diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c index 69ee6e26b8ea..7cbc3a00bda8 100644 --- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c @@ -51,6 +51,7 @@ int s5k83a_probe(struct sd *sd) { u8 prod_id = 0, ver_id = 0; int i, err = 0; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { if (force_sensor == S5K83A_SENSOR) { diff --git a/drivers/media/usb/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c index 8f4714df5990..68bb2f359666 100644 --- a/drivers/media/usb/gspca/mr97310a.c +++ b/drivers/media/usb/gspca/mr97310a.c @@ -289,7 +289,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev) return err_code; } if (status != 0x0a) - PDEBUG(D_ERR, "status is %02x", status); + PERR("status is %02x", status); tries = 0; while (tries < 4) { @@ -330,7 +330,7 @@ static void stream_stop(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0] = 0x01; gspca_dev->usb_buf[1] = 0x00; if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "Stream Stop failed"); + PERR("Stream Stop failed"); } static void lcd_stop(struct gspca_dev *gspca_dev) @@ -338,7 +338,7 @@ static void lcd_stop(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0] = 0x19; gspca_dev->usb_buf[1] = 0x54; if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "LCD Stop failed"); + PERR("LCD Stop failed"); } static int isoc_enable(struct gspca_dev *gspca_dev) @@ -1026,7 +1026,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - sof = pac_find_sof(&sd->sof_read, data, len); + sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len); if (sof) { int n; diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index 9ad19a7ef81b..a3958ee86816 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c @@ -2034,6 +2034,7 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) /* Write a OV519 register */ static void reg_w(struct sd *sd, u16 index, u16 value) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret, req = 0; if (sd->gspca_dev.usb_err < 0) @@ -2071,7 +2072,7 @@ static void reg_w(struct sd *sd, u16 index, u16 value) sd->gspca_dev.usb_buf, 1, 500); leave: if (ret < 0) { - pr_err("reg_w %02x failed %d\n", index, ret); + PERR("reg_w %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; return; } @@ -2081,6 +2082,7 @@ leave: /* returns: negative is error, pos or zero is data */ static int reg_r(struct sd *sd, u16 index) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret; int req; @@ -2110,7 +2112,7 @@ static int reg_r(struct sd *sd, u16 index) PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index, ret); } else { - pr_err("reg_r %02x failed %d\n", index, ret); + PERR("reg_r %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; } @@ -2121,6 +2123,7 @@ static int reg_r(struct sd *sd, u16 index) static int reg_r8(struct sd *sd, u16 index) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret; if (sd->gspca_dev.usb_err < 0) @@ -2135,7 +2138,7 @@ static int reg_r8(struct sd *sd, if (ret >= 0) { ret = sd->gspca_dev.usb_buf[0]; } else { - pr_err("reg_r8 %02x failed %d\n", index, ret); + PERR("reg_r8 %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; } @@ -2174,6 +2177,7 @@ static void reg_w_mask(struct sd *sd, */ static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret; if (sd->gspca_dev.usb_err < 0) @@ -2188,13 +2192,14 @@ static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n) 0, index, sd->gspca_dev.usb_buf, n, 500); if (ret < 0) { - pr_err("reg_w32 %02x failed %d\n", index, ret); + PERR("reg_w32 %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; } } static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int rc, retries; PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value); @@ -2228,6 +2233,7 @@ static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value) static int ov511_i2c_r(struct sd *sd, u8 reg) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int rc, value, retries; /* Two byte write cycle */ @@ -2300,6 +2306,8 @@ static void ov518_i2c_w(struct sd *sd, u8 reg, u8 value) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value); /* Select camera register */ @@ -2325,6 +2333,7 @@ static void ov518_i2c_w(struct sd *sd, */ static int ov518_i2c_r(struct sd *sd, u8 reg) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int value; /* Select camera register */ @@ -2345,6 +2354,7 @@ static int ov518_i2c_r(struct sd *sd, u8 reg) static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret; if (sd->gspca_dev.usb_err < 0) @@ -2357,7 +2367,7 @@ static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) (u16) value, (u16) reg, NULL, 0, 500); if (ret < 0) { - pr_err("ovfx2_i2c_w %02x failed %d\n", reg, ret); + PERR("ovfx2_i2c_w %02x failed %d\n", reg, ret); sd->gspca_dev.usb_err = ret; } @@ -2366,6 +2376,7 @@ static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) static int ovfx2_i2c_r(struct sd *sd, u8 reg) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret; if (sd->gspca_dev.usb_err < 0) @@ -2381,7 +2392,7 @@ static int ovfx2_i2c_r(struct sd *sd, u8 reg) ret = sd->gspca_dev.usb_buf[0]; PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret); } else { - pr_err("ovfx2_i2c_r %02x failed %d\n", reg, ret); + PERR("ovfx2_i2c_r %02x failed %d\n", reg, ret); sd->gspca_dev.usb_err = ret; } @@ -2478,6 +2489,8 @@ static void i2c_w_mask(struct sd *sd, * registers while the camera is streaming */ static inline void ov51x_stop(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_STREAM, "stopping"); sd->stopped = 1; switch (sd->bridge) { @@ -2507,6 +2520,8 @@ static inline void ov51x_stop(struct sd *sd) * actually stopped (for performance). */ static inline void ov51x_restart(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_STREAM, "restarting"); if (!sd->stopped) return; @@ -2545,6 +2560,7 @@ static void ov51x_set_slave_ids(struct sd *sd, u8 slave); static int init_ov_sensor(struct sd *sd, u8 slave) { int i; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; ov51x_set_slave_ids(sd, slave); @@ -2624,10 +2640,11 @@ static void write_i2c_regvals(struct sd *sd, /* This initializes the OV2x10 / OV3610 / OV3620 / OV9600 */ static void ov_hires_configure(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int high, low; if (sd->bridge != BRIDGE_OVFX2) { - pr_err("error hires sensors only supported with ovfx2\n"); + PERR("error hires sensors only supported with ovfx2\n"); return; } @@ -2662,7 +2679,7 @@ static void ov_hires_configure(struct sd *sd) } break; } - pr_err("Error unknown sensor type: %02x%02x\n", high, low); + PERR("Error unknown sensor type: %02x%02x\n", high, low); } /* This initializes the OV8110, OV8610 sensor. The OV8110 uses @@ -2670,6 +2687,7 @@ static void ov_hires_configure(struct sd *sd) */ static void ov8xx0_configure(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int rc; PDEBUG(D_PROBE, "starting ov8xx0 configuration"); @@ -2677,13 +2695,13 @@ static void ov8xx0_configure(struct sd *sd) /* Detect sensor (sub)type */ rc = i2c_r(sd, OV7610_REG_COM_I); if (rc < 0) { - PDEBUG(D_ERR, "Error detecting sensor type"); + PERR("Error detecting sensor type"); return; } if ((rc & 3) == 1) sd->sensor = SEN_OV8610; else - pr_err("Unknown image sensor version: %d\n", rc & 3); + PERR("Unknown image sensor version: %d\n", rc & 3); } /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses @@ -2691,6 +2709,7 @@ static void ov8xx0_configure(struct sd *sd) */ static void ov7xx0_configure(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int rc, high, low; PDEBUG(D_PROBE, "starting OV7xx0 configuration"); @@ -2701,7 +2720,7 @@ static void ov7xx0_configure(struct sd *sd) /* add OV7670 here * it appears to be wrongly detected as a 7610 by default */ if (rc < 0) { - pr_err("Error detecting sensor type\n"); + PERR("Error detecting sensor type\n"); return; } if ((rc & 3) == 3) { @@ -2729,19 +2748,19 @@ static void ov7xx0_configure(struct sd *sd) /* try to read product id registers */ high = i2c_r(sd, 0x0a); if (high < 0) { - pr_err("Error detecting camera chip PID\n"); + PERR("Error detecting camera chip PID\n"); return; } low = i2c_r(sd, 0x0b); if (low < 0) { - pr_err("Error detecting camera chip VER\n"); + PERR("Error detecting camera chip VER\n"); return; } if (high == 0x76) { switch (low) { case 0x30: - pr_err("Sensor is an OV7630/OV7635\n"); - pr_err("7630 is not supported by this driver\n"); + PERR("Sensor is an OV7630/OV7635\n"); + PERR("7630 is not supported by this driver\n"); return; case 0x40: PDEBUG(D_PROBE, "Sensor is an OV7645"); @@ -2760,7 +2779,7 @@ static void ov7xx0_configure(struct sd *sd) sd->sensor = SEN_OV7660; break; default: - pr_err("Unknown sensor: 0x76%02x\n", low); + PERR("Unknown sensor: 0x76%02x\n", low); return; } } else { @@ -2768,20 +2787,22 @@ static void ov7xx0_configure(struct sd *sd) sd->sensor = SEN_OV7620; } } else { - pr_err("Unknown image sensor version: %d\n", rc & 3); + PERR("Unknown image sensor version: %d\n", rc & 3); } } /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ static void ov6xx0_configure(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int rc; + PDEBUG(D_PROBE, "starting OV6xx0 configuration"); /* Detect sensor (sub)type */ rc = i2c_r(sd, OV7610_REG_COM_I); if (rc < 0) { - pr_err("Error detecting sensor type\n"); + PERR("Error detecting sensor type\n"); return; } @@ -2810,7 +2831,7 @@ static void ov6xx0_configure(struct sd *sd) pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n"); break; default: - pr_err("FATAL: Unknown sensor version: 0x%02x\n", rc); + PERR("FATAL: Unknown sensor version: 0x%02x\n", rc); return; } @@ -2907,6 +2928,7 @@ static void ov51x_upload_quan_tables(struct sd *sd) 7, 7, 7, 7, 7, 7, 8, 8 }; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; const unsigned char *pYTable, *pUVTable; unsigned char val0, val1; int i, size, reg = R51x_COMP_LUT_BEGIN; @@ -3300,7 +3322,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { ov_hires_configure(sd); } else { - pr_err("Can't determine sensor slave IDs\n"); + PERR("Can't determine sensor slave IDs\n"); goto error; } @@ -3433,7 +3455,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } return gspca_dev->usb_err; error: - PDEBUG(D_ERR, "OV519 Config failed"); + PERR("OV519 Config failed"); return -EINVAL; } @@ -3459,6 +3481,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) */ static void ov511_mode_init_regs(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int hsegs, vsegs, packet_size, fps, needed; int interlaced = 0; struct usb_host_interface *alt; @@ -3467,7 +3490,7 @@ static void ov511_mode_init_regs(struct sd *sd) intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) { - pr_err("Couldn't get altsetting\n"); + PERR("Couldn't get altsetting\n"); sd->gspca_dev.usb_err = -EIO; return; } @@ -3583,6 +3606,7 @@ static void ov511_mode_init_regs(struct sd *sd) */ static void ov518_mode_init_regs(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int hsegs, vsegs, packet_size; struct usb_host_interface *alt; struct usb_interface *intf; @@ -3590,7 +3614,7 @@ static void ov518_mode_init_regs(struct sd *sd) intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) { - pr_err("Couldn't get altsetting\n"); + PERR("Couldn't get altsetting\n"); sd->gspca_dev.usb_err = -EIO; return; } @@ -3750,6 +3774,8 @@ static void ov519_mode_init_regs(struct sd *sd) /* windows reads 0x55 at this point, why? */ }; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + /******** Set the mode ********/ switch (sd->sensor) { default: @@ -3865,11 +3891,10 @@ static void ov519_mode_init_regs(struct sd *sd) static void mode_init_ov_sensor_regs(struct sd *sd) { - struct gspca_dev *gspca_dev; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int qvga, xstart, xend, ystart, yend; u8 v; - gspca_dev = &sd->gspca_dev; qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; /******** Mode (VGA/QVGA) and sensor specific regs ********/ @@ -4304,7 +4329,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, /* Frame end */ if ((in[9] + 1) * 8 != gspca_dev->width || (in[10] + 1) * 8 != gspca_dev->height) { - PDEBUG(D_ERR, "Invalid frame size, got: %dx%d," + PERR("Invalid frame size, got: %dx%d," " requested: %dx%d\n", (in[9] + 1) * 8, (in[10] + 1) * 8, gspca_dev->width, gspca_dev->height); @@ -4355,7 +4380,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, except that they may contain part of the footer), are numbered 0 */ else if (sd->packet_nr == 0 || data[len]) { - PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)", + PERR("Invalid packet nr: %d (expect: %d)", (int)data[len], (int)sd->packet_nr); gspca_dev->last_packet_type = DISCARD_PACKET; return; @@ -4898,7 +4923,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); if (hdl->error) { - pr_err("Could not initialize controls\n"); + PERR("Could not initialize controls\n"); return hdl->error; } if (gspca_dev->autogain) diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c index bb09d7884b89..2e28c81a03ab 100644 --- a/drivers/media/usb/gspca/ov534.c +++ b/drivers/media/usb/gspca/ov534.c @@ -690,7 +690,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) case 0x03: break; default: - PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", + PERR("sccb status 0x%02x, attempt %d/5", data, i + 1); } } diff --git a/drivers/media/usb/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c index 3b75097dd34e..83519be94e58 100644 --- a/drivers/media/usb/gspca/pac207.c +++ b/drivers/media/usb/gspca/pac207.c @@ -373,7 +373,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - sof = pac_find_sof(&sd->sof_read, data, len); + sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len); if (sof) { int n; diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c index add6f725ba50..682ef3340911 100644 --- a/drivers/media/usb/gspca/pac7302.c +++ b/drivers/media/usb/gspca/pac7302.c @@ -344,13 +344,10 @@ static void reg_w_var(struct gspca_dev *gspca_dev, reg_w_page(gspca_dev, page3, page3_len); break; default: -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - PDEBUG(D_ERR|D_STREAM, - "Incorrect variable sequence"); + PERR("Incorrect variable sequence"); return; } -#endif while (len > 0) { if (len < 8) { reg_w_buf(gspca_dev, @@ -795,7 +792,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *image; u8 *sof; - sof = pac_find_sof(&sd->sof_read, data, len); + sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; diff --git a/drivers/media/usb/gspca/pac7311.c b/drivers/media/usb/gspca/pac7311.c index a12dfbf6e051..1a5bdc853a80 100644 --- a/drivers/media/usb/gspca/pac7311.c +++ b/drivers/media/usb/gspca/pac7311.c @@ -262,8 +262,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev, break; default: if (len > USB_BUF_SZ) { - PDEBUG(D_ERR|D_STREAM, - "Incorrect variable sequence"); + PERR("Incorrect variable sequence"); return; } while (len > 0) { @@ -575,7 +574,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *image; unsigned char *sof; - sof = pac_find_sof(&sd->sof_read, data, len); + sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; diff --git a/drivers/media/usb/gspca/pac_common.h b/drivers/media/usb/gspca/pac_common.h index 8462a7c1a338..fbc5e226c3e4 100644 --- a/drivers/media/usb/gspca/pac_common.h +++ b/drivers/media/usb/gspca/pac_common.h @@ -71,7 +71,7 @@ static const unsigned char pac_sof_marker[5] = +----------+ */ -static unsigned char *pac_find_sof(u8 *sof_read, +static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, u8 *sof_read, unsigned char *m, int len) { int i; diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c index 03fa3fd940b4..39b6b2e02963 100644 --- a/drivers/media/usb/gspca/sn9c2028.c +++ b/drivers/media/usb/gspca/sn9c2028.c @@ -650,13 +650,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) result = sn9c2028_read1(gspca_dev); if (result < 0) - PDEBUG(D_ERR, "Camera Stop read failed"); + PERR("Camera Stop read failed"); memset(data, 0, 6); data[0] = 0x14; result = sn9c2028_command(gspca_dev, data); if (result < 0) - PDEBUG(D_ERR, "Camera Stop command failed"); + PERR("Camera Stop command failed"); } /* Include sn9c2028 sof detection functions */ diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index 8246e1dc3e9d..3b5ccb1c4cdf 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c @@ -1159,12 +1159,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (gspca_dev->usb_err < 0) return; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); + PERR("reg_r: buffer overflow\n"); return; } -#endif + ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), 0, @@ -1213,12 +1212,12 @@ static void reg_w(struct gspca_dev *gspca_dev, return; PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", value, buffer[0], buffer[1]); -#ifdef GSPCA_DEBUG + if (len > USB_BUF_SZ) { - pr_err("reg_w: buffer overflow\n"); + PERR("reg_w: buffer overflow\n"); return; } -#endif + memcpy(gspca_dev->usb_buf, buffer, len); ret = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c index 14d635277d71..688592b289ea 100644 --- a/drivers/media/usb/gspca/spca1528.c +++ b/drivers/media/usb/gspca/spca1528.c @@ -146,7 +146,7 @@ static void wait_status_0(struct gspca_dev *gspca_dev) w += 15; msleep(w); } while (--i > 0); - PDEBUG(D_ERR, "wait_status_0 timeout"); + PERR("wait_status_0 timeout"); gspca_dev->usb_err = -ETIME; } @@ -164,7 +164,7 @@ static void wait_status_1(struct gspca_dev *gspca_dev) return; } } while (--i > 0); - PDEBUG(D_ERR, "wait_status_1 timeout"); + PERR("wait_status_1 timeout"); gspca_dev->usb_err = -ETIME; } diff --git a/drivers/media/usb/gspca/spca500.c b/drivers/media/usb/gspca/spca500.c index 25cb68d0556d..9f8bf51fd64b 100644 --- a/drivers/media/usb/gspca/spca500.c +++ b/drivers/media/usb/gspca/spca500.c @@ -489,7 +489,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev) return err; err = reg_r_wait(gspca_dev, 0x06, 0, 0); if (err < 0) { - PDEBUG(D_ERR, "reg_r_wait() failed"); + PERR("reg_r_wait() failed"); return err; } /* all ok */ @@ -505,7 +505,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev) static int spca500_synch310(struct gspca_dev *gspca_dev) { if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { - PDEBUG(D_ERR, "Set packet size: set interface error"); + PERR("Set packet size: set interface error"); goto error; } spca500_ping310(gspca_dev); @@ -519,7 +519,7 @@ static int spca500_synch310(struct gspca_dev *gspca_dev) if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->alt) < 0) { - PDEBUG(D_ERR, "Set packet size: set interface error"); + PERR("Set packet size: set interface error"); goto error; } return 0; @@ -544,7 +544,7 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) - PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); + PERR("spca50x_setup_qtable failed on init"); /* set qtable index */ reg_w(gspca_dev, 0x00, 0x8880, 2); @@ -639,7 +639,7 @@ static int sd_start(struct gspca_dev *gspca_dev) 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); @@ -647,7 +647,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8000, 0x0004); msleep(500); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); + PERR("reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; @@ -660,13 +660,13 @@ static int sd_start(struct gspca_dev *gspca_dev) /* enable drop packet */ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); if (err < 0) - PDEBUG(D_ERR, "failed to enable drop packet"); + PERR("failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); @@ -675,7 +675,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); + PERR("reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; @@ -689,18 +689,18 @@ static int sd_start(struct gspca_dev *gspca_dev) /* do a full reset */ err = spca500_full_reset(gspca_dev); if (err < 0) - PDEBUG(D_ERR, "spca500_full_reset failed"); + PERR("spca500_full_reset failed"); /* enable drop packet */ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); if (err < 0) - PDEBUG(D_ERR, "failed to enable drop packet"); + PERR("failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); reg_w(gspca_dev, 0x20, 0x0001, 0x0004); @@ -709,7 +709,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); + PERR("reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; @@ -722,7 +722,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* do a full reset */ err = spca500_full_reset(gspca_dev); if (err < 0) - PDEBUG(D_ERR, "spca500_full_reset failed"); + PERR("spca500_full_reset failed"); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x8880, 0); @@ -730,7 +730,7 @@ static int sd_start(struct gspca_dev *gspca_dev) 0x00, 0x8800, 0x8840, qtable_kodak_ez200); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); reg_w(gspca_dev, 0x20, 0x0001, 0x0004); @@ -739,7 +739,7 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); + PERR("reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; @@ -765,7 +765,7 @@ static int sd_start(struct gspca_dev *gspca_dev) err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); reg_w(gspca_dev, 0x00, 0x8880, 2); /* familycam Quicksmart pocketDV stuff */ @@ -795,7 +795,7 @@ static int sd_start(struct gspca_dev *gspca_dev) 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + PERR("spca50x_setup_qtable failed"); reg_w(gspca_dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Init SDRAM - needed for SDRAM access */ diff --git a/drivers/media/usb/gspca/spca501.c b/drivers/media/usb/gspca/spca501.c index 3b7f777785b4..d92fd17d6701 100644 --- a/drivers/media/usb/gspca/spca501.c +++ b/drivers/media/usb/gspca/spca501.c @@ -1756,10 +1756,11 @@ static const __u16 spca501c_mysterious_init_data[][3] = { {} }; -static int reg_write(struct usb_device *dev, - __u16 req, __u16 index, __u16 value) +static int reg_write(struct gspca_dev *gspca_dev, + __u16 req, __u16 index, __u16 value) { int ret; + struct usb_device *dev = gspca_dev->dev; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -1774,17 +1775,15 @@ static int reg_write(struct usb_device *dev, } -static int write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][3]) +static int write_vector(struct gspca_dev *gspca_dev, const __u16 data[][3]) { - struct usb_device *dev = gspca_dev->dev; int ret, i = 0; while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + ret = reg_write(gspca_dev, data[i][0], data[i][2], + data[i][1]); if (ret < 0) { - PDEBUG(D_ERR, - "Reg write failed for 0x%02x,0x%02x,0x%02x", + PERR("Reg write failed for 0x%02x,0x%02x,0x%02x", data[i][0], data[i][1], data[i][2]); return ret; } @@ -1795,30 +1794,28 @@ static int write_vector(struct gspca_dev *gspca_dev, static void setbrightness(struct gspca_dev *gspca_dev, s32 val) { - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, val); + reg_write(gspca_dev, SPCA501_REG_CCDSP, 0x12, val); } static void setcontrast(struct gspca_dev *gspca_dev, s32 val) { - reg_write(gspca_dev->dev, 0x00, 0x00, - (val >> 8) & 0xff); - reg_write(gspca_dev->dev, 0x00, 0x01, - val & 0xff); + reg_write(gspca_dev, 0x00, 0x00, (val >> 8) & 0xff); + reg_write(gspca_dev, 0x00, 0x01, val & 0xff); } static void setcolors(struct gspca_dev *gspca_dev, s32 val) { - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, val); + reg_write(gspca_dev, SPCA501_REG_CCDSP, 0x0c, val); } static void setblue_balance(struct gspca_dev *gspca_dev, s32 val) { - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, val); + reg_write(gspca_dev, SPCA501_REG_CCDSP, 0x11, val); } static void setred_balance(struct gspca_dev *gspca_dev, s32 val) { - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, val); + reg_write(gspca_dev, SPCA501_REG_CCDSP, 0x13, val); } /* this function is called at probe time */ @@ -1868,7 +1865,6 @@ error: static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int mode; switch (sd->subtype) { @@ -1895,20 +1891,20 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Enable ISO packet machine CTRL reg=2, * index=1 bitmask=0x2 (bit ordinal 1) */ - reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94); + reg_write(gspca_dev, SPCA50X_REG_USB, 0x6, 0x94); switch (mode) { case 0: /* 640x480 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a); + reg_write(gspca_dev, SPCA50X_REG_USB, 0x07, 0x004a); break; case 1: /* 320x240 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a); + reg_write(gspca_dev, SPCA50X_REG_USB, 0x07, 0x104a); break; default: /* case 2: * 160x120 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a); + reg_write(gspca_dev, SPCA50X_REG_USB, 0x07, 0x204a); break; } - reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); + reg_write(gspca_dev, SPCA501_REG_CTLRL, 0x01, 0x02); return 0; } @@ -1917,7 +1913,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) { /* Disable ISO packet * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */ - reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); + reg_write(gspca_dev, SPCA501_REG_CTLRL, 0x01, 0x00); } /* called on streamoff with alt 0 and on disconnect */ @@ -1925,7 +1921,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) { if (!gspca_dev->present) return; - reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); + reg_write(gspca_dev, SPCA501_REG_CTLRL, 0x05, 0x00); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, diff --git a/drivers/media/usb/gspca/spca505.c b/drivers/media/usb/gspca/spca505.c index bc7d67c3cb04..232b330d2dd3 100644 --- a/drivers/media/usb/gspca/spca505.c +++ b/drivers/media/usb/gspca/spca505.c @@ -544,10 +544,11 @@ static const u8 spca505b_open_data_ccd[][3] = { {} }; -static int reg_write(struct usb_device *dev, +static int reg_write(struct gspca_dev *gspca_dev, u16 req, u16 index, u16 value) { int ret; + struct usb_device *dev = gspca_dev->dev; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -584,11 +585,11 @@ static int reg_read(struct gspca_dev *gspca_dev, static int write_vector(struct gspca_dev *gspca_dev, const u8 data[][3]) { - struct usb_device *dev = gspca_dev->dev; int ret, i = 0; while (data[i][0] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + ret = reg_write(gspca_dev, data[i][0], data[i][2], + data[i][1]); if (ret < 0) return ret; i++; @@ -629,14 +630,13 @@ static int sd_init(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) { - reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); - reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); + reg_write(gspca_dev, 0x05, 0x00, (255 - brightness) >> 6); + reg_write(gspca_dev, 0x05, 0x01, (255 - brightness) << 2); } static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int ret, mode; static u8 mode_tb[][3] = { /* r00 r06 r07 */ @@ -654,9 +654,7 @@ static int sd_start(struct gspca_dev *gspca_dev) ret = reg_read(gspca_dev, 0x06, 0x16); if (ret < 0) { - PDEBUG(D_ERR|D_CONF, - "register read failed err: %d", - ret); + PERR("register read failed err: %d", ret); return ret; } if (ret != 0x0101) { @@ -664,22 +662,22 @@ static int sd_start(struct gspca_dev *gspca_dev) ret); } - ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); + ret = reg_write(gspca_dev, 0x06, 0x16, 0x0a); if (ret < 0) return ret; - reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); + reg_write(gspca_dev, 0x05, 0xc2, 0x12); /* necessary because without it we can see stream * only once after loading module */ /* stopping usb registers Tomasz change */ - reg_write(dev, 0x02, 0x00, 0x00); + reg_write(gspca_dev, 0x02, 0x00, 0x00); mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); + reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); + reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); + reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); - return reg_write(dev, SPCA50X_REG_USB, + return reg_write(gspca_dev, SPCA50X_REG_USB, SPCA50X_USB_CTRL, SPCA50X_CUSB_ENABLE); } @@ -687,7 +685,7 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { /* Disable ISO packet machine */ - reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); + reg_write(gspca_dev, 0x02, 0x00, 0x00); } /* called on streamoff with alt 0 and on disconnect */ @@ -697,11 +695,11 @@ static void sd_stop0(struct gspca_dev *gspca_dev) return; /* This maybe reset or power control */ - reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); - reg_write(gspca_dev->dev, 0x03, 0x01, 0x00); - reg_write(gspca_dev->dev, 0x03, 0x00, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x10, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f); + reg_write(gspca_dev, 0x03, 0x03, 0x20); + reg_write(gspca_dev, 0x03, 0x01, 0x00); + reg_write(gspca_dev, 0x03, 0x00, 0x01); + reg_write(gspca_dev, 0x05, 0x10, 0x01); + reg_write(gspca_dev, 0x05, 0x11, 0x0f); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, diff --git a/drivers/media/usb/gspca/spca508.c b/drivers/media/usb/gspca/spca508.c index 1286b4170b88..75f2beb2ea5a 100644 --- a/drivers/media/usb/gspca/spca508.c +++ b/drivers/media/usb/gspca/spca508.c @@ -1241,10 +1241,10 @@ static const u16 spca508_vista_init_data[][2] = { {} }; -static int reg_write(struct usb_device *dev, - u16 index, u16 value) +static int reg_write(struct gspca_dev *gspca_dev, u16 index, u16 value) { int ret; + struct usb_device *dev = gspca_dev->dev; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -1286,22 +1286,21 @@ static int reg_read(struct gspca_dev *gspca_dev, static int ssi_w(struct gspca_dev *gspca_dev, u16 reg, u16 val) { - struct usb_device *dev = gspca_dev->dev; int ret, retry; - ret = reg_write(dev, 0x8802, reg >> 8); + ret = reg_write(gspca_dev, 0x8802, reg >> 8); if (ret < 0) goto out; - ret = reg_write(dev, 0x8801, reg & 0x00ff); + ret = reg_write(gspca_dev, 0x8801, reg & 0x00ff); if (ret < 0) goto out; if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */ - ret = reg_write(dev, 0x8805, val & 0x00ff); + ret = reg_write(gspca_dev, 0x8805, val & 0x00ff); if (ret < 0) goto out; val >>= 8; } - ret = reg_write(dev, 0x8800, val); + ret = reg_write(gspca_dev, 0x8800, val); if (ret < 0) goto out; @@ -1314,8 +1313,7 @@ static int ssi_w(struct gspca_dev *gspca_dev, if (gspca_dev->usb_buf[0] == 0) break; if (--retry <= 0) { - PDEBUG(D_ERR, "ssi_w busy %02x", - gspca_dev->usb_buf[0]); + PERR("ssi_w busy %02x", gspca_dev->usb_buf[0]); ret = -1; break; } @@ -1329,7 +1327,6 @@ out: static int write_vector(struct gspca_dev *gspca_dev, const u16 (*data)[2]) { - struct usb_device *dev = gspca_dev->dev; int ret = 0; while ((*data)[1] != 0) { @@ -1337,7 +1334,8 @@ static int write_vector(struct gspca_dev *gspca_dev, if ((*data)[1] == 0xdd00) /* delay */ msleep((*data)[0]); else - ret = reg_write(dev, (*data)[1], (*data)[0]); + ret = reg_write(gspca_dev, (*data)[1], + (*data)[0]); } else { ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]); } @@ -1363,8 +1361,6 @@ static int sd_config(struct gspca_dev *gspca_dev, spca508cs110_init_data, /* MicroInnovationIC200 4 */ spca508_init_data, /* ViewQuestVQ110 5 */ }; - -#ifdef GSPCA_DEBUG int data1, data2; /* Read from global register the USB product and vendor IDs, just to @@ -1381,7 +1377,6 @@ static int sd_config(struct gspca_dev *gspca_dev, data1 = reg_read(gspca_dev, 0x8621); PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); -#endif cam = &gspca_dev->cam; cam->cam_mode = sif_mode; @@ -1404,26 +1399,26 @@ static int sd_start(struct gspca_dev *gspca_dev) int mode; mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - reg_write(gspca_dev->dev, 0x8500, mode); + reg_write(gspca_dev, 0x8500, mode); switch (mode) { case 0: case 1: - reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */ + reg_write(gspca_dev, 0x8700, 0x28); /* clock */ break; default: /* case 2: */ /* case 3: */ - reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */ + reg_write(gspca_dev, 0x8700, 0x23); /* clock */ break; } - reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); + reg_write(gspca_dev, 0x8112, 0x10 | 0x20); return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) { /* Video ISO disable, Video Drop Packet enable: */ - reg_write(gspca_dev->dev, 0x8112, 0x20); + reg_write(gspca_dev, 0x8112, 0x20); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, @@ -1450,10 +1445,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) { /* MX seem contrast */ - reg_write(gspca_dev->dev, 0x8651, brightness); - reg_write(gspca_dev->dev, 0x8652, brightness); - reg_write(gspca_dev->dev, 0x8653, brightness); - reg_write(gspca_dev->dev, 0x8654, brightness); + reg_write(gspca_dev, 0x8651, brightness); + reg_write(gspca_dev, 0x8652, brightness); + reg_write(gspca_dev, 0x8653, brightness); + reg_write(gspca_dev, 0x8654, brightness); } static int sd_s_ctrl(struct v4l2_ctrl *ctrl) diff --git a/drivers/media/usb/gspca/spca561.c b/drivers/media/usb/gspca/spca561.c index d1db3d8f6522..403d71cd65d9 100644 --- a/drivers/media/usb/gspca/spca561.c +++ b/drivers/media/usb/gspca/spca561.c @@ -285,9 +285,10 @@ static const __u16 spca561_161rev12A_data2[][2] = { {} }; -static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) +static void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value) { int ret; + struct usb_device *dev = gspca_dev->dev; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, /* request */ @@ -301,12 +302,11 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) static void write_vector(struct gspca_dev *gspca_dev, const __u16 data[][2]) { - struct usb_device *dev = gspca_dev->dev; int i; i = 0; while (data[i][1] != 0) { - reg_w_val(dev, data[i][1], data[i][0]); + reg_w_val(gspca_dev, data[i][1], data[i][0]); i++; } } @@ -339,9 +339,9 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) { int retry = 60; - reg_w_val(gspca_dev->dev, 0x8801, reg); - reg_w_val(gspca_dev->dev, 0x8805, value); - reg_w_val(gspca_dev->dev, 0x8800, value >> 8); + reg_w_val(gspca_dev, 0x8801, reg); + reg_w_val(gspca_dev, 0x8805, value); + reg_w_val(gspca_dev, 0x8800, value >> 8); do { reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) @@ -355,9 +355,9 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) int retry = 60; __u8 value; - reg_w_val(gspca_dev->dev, 0x8804, 0x92); - reg_w_val(gspca_dev->dev, 0x8801, reg); - reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01); + reg_w_val(gspca_dev, 0x8804, 0x92); + reg_w_val(gspca_dev, 0x8801, reg); + reg_w_val(gspca_dev, 0x8802, mode | 0x01); do { reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) { @@ -459,14 +459,13 @@ static int sd_init_72a(struct gspca_dev *gspca_dev) write_sensor_72a(gspca_dev, rev72a_init_sensor1); write_vector(gspca_dev, rev72a_init_data2); write_sensor_72a(gspca_dev, rev72a_init_sensor2); - reg_w_val(gspca_dev->dev, 0x8112, 0x30); + reg_w_val(gspca_dev, 0x8112, 0x30); return 0; } static void setbrightness(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u16 reg; if (sd->chip_revision == Rev012A) @@ -474,16 +473,15 @@ static void setbrightness(struct gspca_dev *gspca_dev, s32 val) else reg = 0x8611; - reg_w_val(dev, reg + 0, val); /* R */ - reg_w_val(dev, reg + 1, val); /* Gr */ - reg_w_val(dev, reg + 2, val); /* B */ - reg_w_val(dev, reg + 3, val); /* Gb */ + reg_w_val(gspca_dev, reg + 0, val); /* R */ + reg_w_val(gspca_dev, reg + 1, val); /* Gr */ + reg_w_val(gspca_dev, reg + 2, val); /* B */ + reg_w_val(gspca_dev, reg + 3, val); /* Gb */ } static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 blue, red; __u16 reg; @@ -496,11 +494,11 @@ static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast) reg = 0x8651; red += contrast - 0x20; blue += contrast - 0x20; - reg_w_val(dev, 0x8652, contrast + 0x20); /* Gr */ - reg_w_val(dev, 0x8654, contrast + 0x20); /* Gb */ + reg_w_val(gspca_dev, 0x8652, contrast + 0x20); /* Gr */ + reg_w_val(gspca_dev, 0x8654, contrast + 0x20); /* Gb */ } - reg_w_val(dev, reg, red); - reg_w_val(dev, reg + 2, blue); + reg_w_val(gspca_dev, reg, red); + reg_w_val(gspca_dev, reg + 2, blue); } /* rev 12a only */ @@ -570,7 +568,6 @@ static void setautogain(struct gspca_dev *gspca_dev, s32 val) static int sd_start_12a(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; int mode; static const __u8 Reg8391[8] = {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00}; @@ -578,34 +575,33 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; if (mode <= 1) { /* Use compression on 320x240 and above */ - reg_w_val(dev, 0x8500, 0x10 | mode); + reg_w_val(gspca_dev, 0x8500, 0x10 | mode); } else { /* I couldn't get the compression to work below 320x240 * Fortunately at these resolutions the bandwidth * is sufficient to push raw frames at ~20fps */ - reg_w_val(dev, 0x8500, mode); + reg_w_val(gspca_dev, 0x8500, mode); } /* -- qq@kuku.eu.org */ gspca_dev->usb_buf[0] = 0xaa; gspca_dev->usb_buf[1] = 0x00; reg_w_buf(gspca_dev, 0x8307, 2); /* clock - lower 0x8X values lead to fps > 30 */ - reg_w_val(gspca_dev->dev, 0x8700, 0x8a); + reg_w_val(gspca_dev, 0x8700, 0x8a); /* 0x8f 0x85 0x27 clock */ - reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); - reg_w_val(gspca_dev->dev, 0x850b, 0x03); + reg_w_val(gspca_dev, 0x8112, 0x1e | 0x20); + reg_w_val(gspca_dev, 0x850b, 0x03); memcpy(gspca_dev->usb_buf, Reg8391, 8); reg_w_buf(gspca_dev, 0x8391, 8); reg_w_buf(gspca_dev, 0x8390, 8); /* Led ON (bit 3 -> 0 */ - reg_w_val(gspca_dev->dev, 0x8114, 0x00); + reg_w_val(gspca_dev, 0x8114, 0x00); return 0; } static int sd_start_72a(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int Clck; int mode; @@ -630,15 +626,15 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) Clck = 0x21; break; } - reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8702, 0x81); - reg_w_val(dev, 0x8500, mode); /* mode */ + reg_w_val(gspca_dev, 0x8700, Clck); /* 0x27 clock */ + reg_w_val(gspca_dev, 0x8702, 0x81); + reg_w_val(gspca_dev, 0x8500, mode); /* mode */ write_sensor_72a(gspca_dev, rev72a_init_sensor2); setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue), v4l2_ctrl_g_ctrl(sd->contrast)); /* setbrightness(gspca_dev); * fixme: bad values */ setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); - reg_w_val(dev, 0x8112, 0x10 | 0x20); + reg_w_val(gspca_dev, 0x8112, 0x10 | 0x20); return 0; } @@ -647,12 +643,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; if (sd->chip_revision == Rev012A) { - reg_w_val(gspca_dev->dev, 0x8112, 0x0e); + reg_w_val(gspca_dev, 0x8112, 0x0e); /* Led Off (bit 3 -> 1 */ - reg_w_val(gspca_dev->dev, 0x8114, 0x08); + reg_w_val(gspca_dev, 0x8114, 0x08); } else { - reg_w_val(gspca_dev->dev, 0x8112, 0x20); -/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */ + reg_w_val(gspca_dev, 0x8112, 0x20); +/* reg_w_val(gspca_dev, 0x8102, 0x00); ?? */ } } @@ -736,7 +732,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* This should never happen */ if (len < 2) { - PDEBUG(D_ERR, "Short SOF packet, ignoring"); + PERR("Short SOF packet, ignoring"); gspca_dev->last_packet_type = DISCARD_PACKET; return; } diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 1d99f10a3e19..a7ae0ec9fa91 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -387,7 +387,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); + PERR("Start streaming command failed"); return ret; } /* Start the workqueue function to do the streaming */ diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c index 410cdcbb55d4..acb19fb9a3df 100644 --- a/drivers/media/usb/gspca/sq905c.c +++ b/drivers/media/usb/gspca/sq905c.c @@ -215,13 +215,13 @@ static int sd_config(struct gspca_dev *gspca_dev, ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0); if (ret < 0) { - PDEBUG(D_ERR, "Get version command failed"); + PERR("Get version command failed"); return ret; } ret = sq905c_read(gspca_dev, 0xf5, 0, 20); if (ret < 0) { - PDEBUG(D_ERR, "Reading version command failed"); + PERR("Reading version command failed"); return ret; } /* Note we leave out the usb id and the manufacturing date */ @@ -286,7 +286,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); + PERR("Start streaming command failed"); return ret; } /* Start the workqueue function to do the streaming */ diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c index 7e8748b31e85..b10d0821111c 100644 --- a/drivers/media/usb/gspca/sq930x.c +++ b/drivers/media/usb/gspca/sq930x.c @@ -541,13 +541,11 @@ static void ucbus_write(struct gspca_dev *gspca_dev, if (gspca_dev->usb_err < 0) return; -#ifdef GSPCA_DEBUG if ((batchsize - 1) * 3 > USB_BUF_SZ) { - pr_err("Bug: usb_buf overflow\n"); + PERR("Bug: usb_buf overflow\n"); gspca_dev->usb_err = -ENOMEM; return; } -#endif for (;;) { len = ncmds; diff --git a/drivers/media/usb/gspca/stv0680.c b/drivers/media/usb/gspca/stv0680.c index 67605272aaa8..9c0827631b9c 100644 --- a/drivers/media/usb/gspca/stv0680.c +++ b/drivers/media/usb/gspca/stv0680.c @@ -86,7 +86,7 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret) { stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */ - PDEBUG(D_ERR, "last error: %i, command = 0x%x", + PERR("last error: %i, command = 0x%x", gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); return ret; } @@ -98,7 +98,7 @@ static int stv0680_get_video_mode(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0] = 0x0f; if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) { - PDEBUG(D_ERR, "Get_Camera_Mode failed"); + PERR("Get_Camera_Mode failed"); return stv0680_handle_error(gspca_dev, -EIO); } @@ -116,13 +116,13 @@ static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode) gspca_dev->usb_buf[0] = mode; if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) { - PDEBUG(D_ERR, "Set_Camera_Mode failed"); + PERR("Set_Camera_Mode failed"); return stv0680_handle_error(gspca_dev, -EIO); } /* Verify we got what we've asked for */ if (stv0680_get_video_mode(gspca_dev) != mode) { - PDEBUG(D_ERR, "Error setting camera video mode!"); + PERR("Error setting camera video mode!"); return -EIO; } @@ -146,7 +146,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* ping camera to be sure STV0680 is present */ if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { - PDEBUG(D_ERR, "STV(e): camera ping failed!!"); + PERR("STV(e): camera ping failed!!"); return stv0680_handle_error(gspca_dev, -ENODEV); } @@ -156,7 +156,7 @@ static int sd_config(struct gspca_dev *gspca_dev, if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 || gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) { - PDEBUG(D_ERR, "Could not get descriptor 0200."); + PERR("Could not get descriptor 0200."); return stv0680_handle_error(gspca_dev, -ENODEV); } if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02) @@ -167,7 +167,7 @@ static int sd_config(struct gspca_dev *gspca_dev, return stv0680_handle_error(gspca_dev, -ENODEV); if (!(gspca_dev->usb_buf[7] & 0x09)) { - PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode"); + PERR("Camera supports neither CIF nor QVGA mode"); return -ENODEV; } if (gspca_dev->usb_buf[7] & 0x01) diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 657160b4a1f7..55ee7a61c67f 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -42,8 +42,10 @@ static bool dump_sensor; int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; + u8 len = (i2c_data > 0xff) ? 2 : 1; buf[0] = i2c_data & 0xff; @@ -62,6 +64,7 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -110,6 +113,7 @@ static int stv06xx_write_sensor_finish(struct sd *sd) int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len) { int err, i, j; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -139,6 +143,7 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len) int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) { int err, i, j; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -170,6 +175,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; @@ -283,7 +289,7 @@ static int stv06xx_start(struct gspca_dev *gspca_dev) intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); + PERR("Couldn't get altsetting"); return -EIO; } @@ -341,7 +347,7 @@ static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); if (ret < 0) - PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); + PERR("set alt 1 err %d", ret); return ret; } @@ -406,7 +412,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, len -= 4; if (len < chunk_len) { - PDEBUG(D_ERR, "URB packet length is smaller" + PERR("URB packet length is smaller" " than the specified chunk length"); gspca_dev->last_packet_type = DISCARD_PACKET; return; @@ -449,7 +455,7 @@ frame_data: sd->to_skip = gspca_dev->width * 4; if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " + PERR("Chunk length is " "non-zero on a SOF"); break; @@ -463,7 +469,7 @@ frame_data: NULL, 0); if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " + PERR("Chunk length is " "non-zero on a EOF"); break; @@ -596,7 +602,6 @@ MODULE_DEVICE_TABLE(usb, device_table); static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - PDEBUG(D_PROBE, "Probing for a stv06xx device"); return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), THIS_MODULE); } diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c index 06fa54c5efb2..2220b70d47e6 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c @@ -255,7 +255,7 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) if (err < 0) return err; } - PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", + PDEBUG(D_CONF, "Writing exposure %d, rowexp %d, srowexp %d", val, rowexp, srowexp); return err; } @@ -280,7 +280,7 @@ static int hdcs_set_gains(struct sd *sd, u8 g) static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) { - PDEBUG(D_V4L2, "Writing gain %d", val); + PDEBUG(D_CONF, "Writing gain %d", val); return hdcs_set_gains((struct sd *) gspca_dev, val & 0xff); } @@ -467,6 +467,8 @@ static int hdcs_probe_1020(struct sd *sd) static int hdcs_start(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_STREAM, "Starting stream"); return hdcs_set_state(sd, HDCS_STATE_RUN); @@ -474,6 +476,8 @@ static int hdcs_start(struct sd *sd) static int hdcs_stop(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_STREAM, "Halting stream"); return hdcs_set_state(sd, HDCS_STATE_SLEEP); diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c index cdfc3d05ab6b..8206b7743300 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c @@ -190,6 +190,7 @@ static int pb0100_start(struct sd *sd) int err, packet_size, max_packet_size; struct usb_host_interface *alt; struct usb_interface *intf; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct cam *cam = &sd->gspca_dev.cam; u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; @@ -239,6 +240,7 @@ static int pb0100_start(struct sd *sd) static int pb0100_stop(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int err; err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1); @@ -334,7 +336,7 @@ static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val) err = stv06xx_write_sensor(sd, PB_G1GAIN, val); if (!err) err = stv06xx_write_sensor(sd, PB_G2GAIN, val); - PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err); + PDEBUG(D_CONF, "Set green gain to %d, status: %d", val, err); if (!err) err = pb0100_set_red_balance(gspca_dev, ctrls->red->val); @@ -357,7 +359,7 @@ static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) val = 255; err = stv06xx_write_sensor(sd, PB_RGAIN, val); - PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err); + PDEBUG(D_CONF, "Set red gain to %d, status: %d", val, err); return err; } @@ -375,7 +377,7 @@ static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) val = 255; err = stv06xx_write_sensor(sd, PB_BGAIN, val); - PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err); + PDEBUG(D_CONF, "Set blue gain to %d, status: %d", val, err); return err; } @@ -386,7 +388,7 @@ static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val) int err; err = stv06xx_write_sensor(sd, PB_RINTTIME, val); - PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err); + PDEBUG(D_CONF, "Set exposure to %d, status: %d", val, err); return err; } @@ -406,7 +408,7 @@ static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val) val = 0; err = stv06xx_write_sensor(sd, PB_EXPGAIN, val); - PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d", + PDEBUG(D_CONF, "Set autogain to %d (natural: %d), status: %d", val, ctrls->natural->val, err); return err; @@ -428,7 +430,7 @@ static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val) if (!err) err = stv06xx_write_sensor(sd, PB_R22, darkpixels); - PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err); + PDEBUG(D_CONF, "Set autogain target to %d, status: %d", val, err); return err; } diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c index 8a57990dfe0f..515a9e121653 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c @@ -279,6 +279,8 @@ static int st6422_start(struct sd *sd) static int st6422_stop(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + PDEBUG(D_STREAM, "Halting stream"); return 0; diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c index e95fa8997d22..bf3e5c317a26 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c @@ -131,6 +131,7 @@ static int vv6410_init(struct sd *sd) static int vv6410_start(struct sd *sd) { int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; struct cam *cam = &sd->gspca_dev.cam; u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv; @@ -163,6 +164,7 @@ static int vv6410_start(struct sd *sd) static int vv6410_stop(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int err; /* Turn off LED */ @@ -208,7 +210,7 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) else i2c_data &= ~VV6410_HFLIP; - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); + PDEBUG(D_CONF, "Set horizontal flip to %d", val); err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); return (err < 0) ? err : 0; @@ -229,7 +231,7 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) else i2c_data &= ~VV6410_VFLIP; - PDEBUG(D_V4L2, "Set vertical flip to %d", val); + PDEBUG(D_CONF, "Set vertical flip to %d", val); err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); return (err < 0) ? err : 0; @@ -240,7 +242,7 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) int err; struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_V4L2, "Set analog gain to %d", val); + PDEBUG(D_CONF, "Set analog gain to %d", val); err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); return (err < 0) ? err : 0; @@ -257,7 +259,7 @@ static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) fine = val % VV6410_CIF_LINELENGTH; coarse = min(512, val / VV6410_CIF_LINELENGTH); - PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", + PDEBUG(D_CONF, "Set coarse exposure to %d, fine expsure to %d", coarse, fine); err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index 9ccfcb1c6479..af8767a9bd4c 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -251,12 +251,10 @@ static void reg_r(struct gspca_dev *gspca_dev, { int ret; -#ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); + PERR("reg_r: buffer overflow\n"); return; } -#endif if (gspca_dev->usb_err < 0) return; ret = usb_control_msg(gspca_dev->dev, @@ -357,12 +355,14 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]); } -#ifdef GSPCA_DEBUG static void spca504_read_info(struct gspca_dev *gspca_dev) { int i; u8 info[6]; + if (gspca_debug < D_STREAM) + return; + for (i = 0; i < 6; i++) { reg_r(gspca_dev, 0, i, 1); info[i] = gspca_dev->usb_buf[0]; @@ -373,7 +373,6 @@ static void spca504_read_info(struct gspca_dev *gspca_dev) info[0], info[1], info[2], info[3], info[4], info[5]); } -#endif static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, u8 req, @@ -432,11 +431,13 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) } } -#ifdef GSPCA_DEBUG static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) { u8 *data; + if (gspca_debug < D_STREAM) + return; + data = gspca_dev->usb_buf; reg_r(gspca_dev, 0x20, 0, 5); PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d", @@ -444,7 +445,6 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) reg_r(gspca_dev, 0x23, 0, 64); reg_r(gspca_dev, 0x23, 1, 64); } -#endif static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) { @@ -457,9 +457,8 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) reg_w_riv(gspca_dev, 0x31, 0, 0); spca504B_WaitCmdStatus(gspca_dev); spca504B_PollingDataReady(gspca_dev); -#ifdef GSPCA_DEBUG spca50x_GetFirmware(gspca_dev); -#endif + reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ reg_r(gspca_dev, 0x24, 8, 1); @@ -645,14 +644,10 @@ static int sd_init(struct gspca_dev *gspca_dev) /* fall thru */ case BRIDGE_SPCA533: spca504B_PollingDataReady(gspca_dev); -#ifdef GSPCA_DEBUG spca50x_GetFirmware(gspca_dev); -#endif break; case BRIDGE_SPCA536: -#ifdef GSPCA_DEBUG spca50x_GetFirmware(gspca_dev); -#endif reg_r(gspca_dev, 0x00, 0x5002, 1); reg_w_1(gspca_dev, 0x24, 0, 0, 0); reg_r(gspca_dev, 0x24, 0, 1); @@ -678,9 +673,7 @@ static int sd_init(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504: */ PDEBUG(D_STREAM, "Opening SPCA504"); if (sd->subtype == AiptekMiniPenCam13) { -#ifdef GSPCA_DEBUG spca504_read_info(gspca_dev); -#endif /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ spca504A_acknowledged_command(gspca_dev, 0x24, @@ -752,9 +745,7 @@ static int sd_start(struct gspca_dev *gspca_dev) break; case BRIDGE_SPCA504: if (sd->subtype == AiptekMiniPenCam13) { -#ifdef GSPCA_DEBUG spca504_read_info(gspca_dev); -#endif /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ spca504A_acknowledged_command(gspca_dev, 0x24, @@ -766,9 +757,7 @@ static int sd_start(struct gspca_dev *gspca_dev) 0, 0, 0x9d, 1); } else { spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); -#ifdef GSPCA_DEBUG spca504_read_info(gspca_dev); -#endif spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); } diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c index e50079503d96..c00ac57de510 100644 --- a/drivers/media/usb/gspca/vc032x.c +++ b/drivers/media/usb/gspca/vc032x.c @@ -2927,7 +2927,6 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 len) { reg_r_i(gspca_dev, req, index, len); -#ifdef GSPCA_DEBUG if (gspca_dev->usb_err < 0) return; if (len == 1) @@ -2936,7 +2935,6 @@ static void reg_r(struct gspca_dev *gspca_dev, else PDEBUG(D_USBI, "GET %02x 0001 %04x %*ph", req, index, 3, gspca_dev->usb_buf); -#endif } static void reg_w_i(struct gspca_dev *gspca_dev, @@ -2964,11 +2962,9 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) { -#ifdef GSPCA_DEBUG if (gspca_dev->usb_err < 0) return; PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index); -#endif reg_w_i(gspca_dev, req, value, index); } @@ -3044,8 +3040,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) if (value == 0 && ptsensor_info->IdAdd == 0x82) value = read_sensor_register(gspca_dev, 0x83); if (value != 0) { - PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)", - value, i); + PDEBUG(D_PROBE, "Sensor ID %04x (%d)", value, i); if (value == ptsensor_info->VpId) return ptsensor_info->sensorId; @@ -3069,14 +3064,12 @@ static void i2c_write(struct gspca_dev *gspca_dev, { int retry; -#ifdef GSPCA_DEBUG if (gspca_dev->usb_err < 0) return; if (size == 1) PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val); else PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]); -#endif reg_r_i(gspca_dev, 0xa1, 0xb33f, 1); /*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/ reg_w_i(gspca_dev, 0xa0, size, 0xb334); diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c index 9e3a909e0a00..2165da0c7ce1 100644 --- a/drivers/media/usb/gspca/w996Xcf.c +++ b/drivers/media/usb/gspca/w996Xcf.c @@ -232,6 +232,7 @@ static void w9968cf_smbus_write_nack(struct sd *sd) static void w9968cf_smbus_read_ack(struct sd *sd) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int sda; /* Ensure SDA is high before raising clock to avoid a spurious stop */ @@ -248,6 +249,7 @@ static void w9968cf_smbus_read_ack(struct sd *sd) /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; u16* data = (u16 *)sd->gspca_dev.usb_buf; data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); @@ -297,6 +299,7 @@ static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ static int w9968cf_i2c_r(struct sd *sd, u8 reg) { + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret = 0; u8 value; @@ -326,7 +329,7 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg) ret = value; PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); } else - PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); + PERR("i2c read [0x%02x] failed", reg); return ret; } diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c index a8dc421f9f1f..cbfc2f921427 100644 --- a/drivers/media/usb/gspca/zc3xx.c +++ b/drivers/media/usb/gspca/zc3xx.c @@ -6259,12 +6259,11 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); if (retword == 0x2030) { -#ifdef GSPCA_DEBUG u8 retbyte; retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); -#endif + send_unknown(gspca_dev, SENSOR_PO2030); return retword; } -- cgit From 8b21eb17e749c9693eaea065f0eb95365006495c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 25 Feb 2013 07:58:41 -0300 Subject: [media] radio-isa: fix querycap capabilities code The device_caps and capabilities fields were swapped. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-isa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c index 84b7b9f4385e..fe0a4f85c422 100644 --- a/drivers/media/radio/radio-isa.c +++ b/drivers/media/radio/radio-isa.c @@ -51,8 +51,8 @@ static int radio_isa_querycap(struct file *file, void *priv, strlcpy(v->card, isa->drv->card, sizeof(v->card)); snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; - v->device_caps = v->capabilities | V4L2_CAP_DEVICE_CAPS; + v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit From 4ca286610f664acf3153634f3930acd2de993a9f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 25 Feb 2013 08:00:15 -0300 Subject: [media] radio-rtrack2: fix mute bug Setting the frequency would unmute the card. Fixed the mute handling in the s_frequency code. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-rtrack2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index b1f844c64fde..09cfbc373c92 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -8,6 +8,8 @@ * * Converted to the radio-isa framework by Hans Verkuil * Converted to V4L2 API by Mauro Carvalho Chehab + * + * Fully tested with actual hardware and the v4l2-compliance tool. */ #include /* Modules */ @@ -81,8 +83,7 @@ static int rtrack2_s_frequency(struct radio_isa_card *isa, u32 freq) zero(isa); outb_p(0xc8, isa->io); - if (!v4l2_ctrl_g_ctrl(isa->mute)) - outb_p(0, isa->io); + outb_p(v4l2_ctrl_g_ctrl(isa->mute), isa->io); return 0; } -- cgit From 192f1e78cb9cbc1a2cee866f5e03a52857e648b6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 05:51:21 -0300 Subject: [media] s2255: convert to the control framework Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 172 ++++++++++++------------------------- include/uapi/linux/v4l2-controls.h | 4 + 2 files changed, 59 insertions(+), 117 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 498c57ea5d32..2dcb29b647f0 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -217,6 +218,7 @@ struct s2255_dev; struct s2255_channel { struct video_device vdev; + struct v4l2_ctrl_handler hdl; int resources; struct s2255_dmaqueue vidq; struct s2255_bufferi buffer; @@ -336,7 +338,7 @@ struct s2255_fh { */ #define S2255_V4L2_YC_ON 1 #define S2255_V4L2_YC_OFF 0 -#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0) /* frame prefix size (sent once every frame) */ #define PREFIX_SIZE 512 @@ -810,28 +812,6 @@ static void res_free(struct s2255_fh *fh) dprintk(1, "res: put\n"); } -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *qmenu) -{ - static const char *colorfilter[] = { - "Off", - "On", - NULL - }; - if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) { - int i; - const char **menu_items = colorfilter; - for (i = 0; i < qmenu->index && menu_items[i]; i++) - ; /* do nothing (from v4l2-common.c) */ - if (menu_items[i] == NULL || menu_items[i][0] == '\0') - return -EINVAL; - strlcpy(qmenu->name, menu_items[qmenu->index], - sizeof(qmenu->name)); - return 0; - } - return v4l2_ctrl_query_menu(qmenu, NULL, NULL); -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1427,109 +1407,32 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -/* --- controls ---------------------------------------------- */ -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) +static int s2255_s_ctrl(struct v4l2_ctrl *ctrl) { - struct s2255_fh *fh = priv; - struct s2255_channel *channel = fh->channel; - struct s2255_dev *dev = fh->dev; - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT); - break; - case V4L2_CID_CONTRAST: - v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST); - break; - case V4L2_CID_SATURATION: - v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION); - break; - case V4L2_CID_HUE: - v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE); - break; - case V4L2_CID_PRIVATE_COLORFILTER: - if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) - return -EINVAL; - if ((dev->pid == 0x2257) && (channel->idx > 1)) - return -EINVAL; - strlcpy(qc->name, "Color Filter", sizeof(qc->name)); - qc->type = V4L2_CTRL_TYPE_MENU; - qc->minimum = 0; - qc->maximum = 1; - qc->step = 1; - qc->default_value = 1; - qc->flags = 0; - break; - default: - return -EINVAL; - } - dprintk(4, "%s, id %d\n", __func__, qc->id); - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct s2255_fh *fh = priv; - struct s2255_dev *dev = fh->dev; - struct s2255_channel *channel = fh->channel; - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = channel->mode.bright; - break; - case V4L2_CID_CONTRAST: - ctrl->value = channel->mode.contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = channel->mode.saturation; - break; - case V4L2_CID_HUE: - ctrl->value = channel->mode.hue; - break; - case V4L2_CID_PRIVATE_COLORFILTER: - if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) - return -EINVAL; - if ((dev->pid == 0x2257) && (channel->idx > 1)) - return -EINVAL; - ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16); - break; - default: - return -EINVAL; - } - dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value); - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct s2255_fh *fh = priv; - struct s2255_channel *channel = fh->channel; - struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); + struct s2255_channel *channel = + container_of(ctrl->handler, struct s2255_channel, hdl); struct s2255_mode mode; + mode = channel->mode; dprintk(4, "%s\n", __func__); + /* update the mode to the corresponding value */ switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - mode.bright = ctrl->value; + mode.bright = ctrl->val; break; case V4L2_CID_CONTRAST: - mode.contrast = ctrl->value; + mode.contrast = ctrl->val; break; case V4L2_CID_HUE: - mode.hue = ctrl->value; + mode.hue = ctrl->val; break; case V4L2_CID_SATURATION: - mode.saturation = ctrl->value; + mode.saturation = ctrl->val; break; - case V4L2_CID_PRIVATE_COLORFILTER: - if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) - return -EINVAL; - if ((dev->pid == 0x2257) && (channel->idx > 1)) - return -EINVAL; + case V4L2_CID_S2255_COLORFILTER: mode.color &= ~MASK_INPUT_TYPE; - mode.color |= ((ctrl->value ? 0 : 1) << 16); + mode.color |= !ctrl->val << 16; break; default: return -EINVAL; @@ -1539,7 +1442,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, some V4L programs restart stream unnecessarily after a s_crtl. */ - s2255_set_mode(fh->channel, &mode); + s2255_set_mode(channel, &mode); return 0; } @@ -1886,7 +1789,6 @@ static const struct v4l2_file_operations s2255_fops_v4l = { }; static const struct v4l2_ioctl_ops s2255_ioctl_ops = { - .vidioc_querymenu = vidioc_querymenu, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1900,9 +1802,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_s_jpegcomp = vidioc_s_jpegcomp, @@ -1915,8 +1814,13 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { static void s2255_video_device_release(struct video_device *vdev) { struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); - dprintk(4, "%s, chnls: %d \n", __func__, + struct s2255_channel *channel = + container_of(vdev, struct s2255_channel, vdev); + + v4l2_ctrl_handler_free(&channel->hdl); + dprintk(4, "%s, chnls: %d\n", __func__, atomic_read(&dev->num_channels)); + if (atomic_dec_and_test(&dev->num_channels)) s2255_destroy(dev); return; @@ -1931,6 +1835,20 @@ static struct video_device template = { .current_norm = V4L2_STD_NTSC_M, }; +static const struct v4l2_ctrl_ops s2255_ctrl_ops = { + .s_ctrl = s2255_s_ctrl, +}; + +static const struct v4l2_ctrl_config color_filter_ctrl = { + .ops = &s2255_ctrl_ops, + .name = "Color Filter", + .id = V4L2_CID_S2255_COLORFILTER, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .max = 1, + .step = 1, + .def = 1, +}; + static int s2255_probe_v4l(struct s2255_dev *dev) { int ret; @@ -1945,9 +1863,29 @@ static int s2255_probe_v4l(struct s2255_dev *dev) for (i = 0; i < MAX_CHANNELS; i++) { channel = &dev->channel[i]; INIT_LIST_HEAD(&channel->vidq.active); + + v4l2_ctrl_handler_init(&channel->hdl, 5); + v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, + V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT); + v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, + V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST); + v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, + V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION); + v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, + V4L2_CID_HUE, 0, 255, 1, DEF_HUE); + if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER && + (dev->pid != 0x2257 || channel->idx <= 1)) + v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl, NULL); + if (channel->hdl.error) { + ret = channel->hdl.error; + v4l2_ctrl_handler_free(&channel->hdl); + dev_err(&dev->udev->dev, "couldn't register control\n"); + break; + } channel->vidq.dev = dev; /* register 4 video devices */ channel->vdev = template; + channel->vdev.ctrl_handler = &channel->hdl; channel->vdev.lock = &dev->lock; channel->vdev.v4l2_dev = &dev->v4l2_dev; video_set_drvdata(&channel->vdev, channel); diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 1d00ca9f0ba3..7eab0b91827b 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -151,6 +151,10 @@ enum v4l2_colorfx { #define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010) +/* The base for the s2255 driver controls. + * We reserve 8 controls for this driver. */ +#define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1010) + /* MPEG-class control IDs */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit From 7041dec7a93039d1386ad0f5070dc2318d66a18d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 05:53:45 -0300 Subject: [media] s2255: add V4L2_CID_JPEG_COMPRESSION_QUALITY The use of the V4L2_CID_JPEG_COMPRESSION_QUALITY control is recommended over the G/S_JPEGCOMP ioctls. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 2dcb29b647f0..42c3afe215b2 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -219,12 +219,13 @@ struct s2255_dev; struct s2255_channel { struct video_device vdev; struct v4l2_ctrl_handler hdl; + struct v4l2_ctrl *jpegqual_ctrl; int resources; struct s2255_dmaqueue vidq; struct s2255_bufferi buffer; struct s2255_mode mode; /* jpeg compression */ - struct v4l2_jpegcompression jc; + unsigned jpegqual; /* capture parameters (for high quality mode full size) */ struct v4l2_captureparm cap_parm; int cur_frame; @@ -1015,7 +1016,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, case V4L2_PIX_FMT_MJPEG: mode.color &= ~MASK_COLOR; mode.color |= COLOR_JPG; - mode.color |= (channel->jc.quality << 8); + mode.color |= (channel->jpegqual << 8); break; case V4L2_PIX_FMT_YUV422P: mode.color &= ~MASK_COLOR; @@ -1185,7 +1186,7 @@ static int s2255_set_mode(struct s2255_channel *channel, mode->color &= ~MASK_COLOR; mode->color |= COLOR_JPG; mode->color &= ~MASK_JPG_QUALITY; - mode->color |= (channel->jc.quality << 8); + mode->color |= (channel->jpegqual << 8); } /* save the mode */ channel->mode = *mode; @@ -1434,6 +1435,9 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl) mode.color &= ~MASK_INPUT_TYPE; mode.color |= !ctrl->val << 16; break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + channel->jpegqual = ctrl->val; + return 0; default: return -EINVAL; } @@ -1451,7 +1455,9 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, { struct s2255_fh *fh = priv; struct s2255_channel *channel = fh->channel; - *jc = channel->jc; + + memset(jc, 0, sizeof(*jc)); + jc->quality = channel->jpegqual; dprintk(2, "%s: quality %d\n", __func__, jc->quality); return 0; } @@ -1463,7 +1469,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, struct s2255_channel *channel = fh->channel; if (jc->quality < 0 || jc->quality > 100) return -EINVAL; - channel->jc.quality = jc->quality; + v4l2_ctrl_s_ctrl(channel->jpegqual_ctrl, jc->quality); dprintk(2, "%s: quality %d\n", __func__, jc->quality); return 0; } @@ -1864,7 +1870,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) channel = &dev->channel[i]; INIT_LIST_HEAD(&channel->vidq.active); - v4l2_ctrl_handler_init(&channel->hdl, 5); + v4l2_ctrl_handler_init(&channel->hdl, 6); v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT); v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, @@ -1873,6 +1879,10 @@ static int s2255_probe_v4l(struct s2255_dev *dev) V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION); v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops, V4L2_CID_HUE, 0, 255, 1, DEF_HUE); + channel->jpegqual_ctrl = v4l2_ctrl_new_std(&channel->hdl, + &s2255_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, + 0, 100, 1, S2255_DEF_JPEG_QUAL); if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER && (dev->pid != 0x2257 || channel->idx <= 1)) v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl, NULL); @@ -2238,7 +2248,7 @@ static int s2255_board_init(struct s2255_dev *dev) channel->mode = mode_def; if (dev->pid == 0x2257 && j > 1) channel->mode.color |= (1 << 16); - channel->jc.quality = S2255_DEF_JPEG_QUAL; + channel->jpegqual = S2255_DEF_JPEG_QUAL; channel->width = LINE_SZ_4CIFS_NTSC; channel->height = NUM_LINES_4CIFS_NTSC * 2; channel->fmt = &formats[0]; -- cgit From 44d06d8273e032119c5ae0d0f90bb57ab8118a5b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 05:59:00 -0300 Subject: [media] s2255: add support for control events and prio handling Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 42c3afe215b2..55c972a0dbed 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -43,13 +43,14 @@ #include #include #include +#include +#include #include #include #include #include #include -#include -#include +#include #define S2255_VERSION "1.22.1" #define FIRMWARE_FILE_NAME "f2255usb.bin" @@ -295,6 +296,8 @@ struct s2255_buffer { }; struct s2255_fh { + /* this must be the first field in this struct */ + struct v4l2_fh fh; struct s2255_dev *dev; struct videobuf_queue vb_vidq; enum v4l2_buf_type type; @@ -1666,7 +1669,9 @@ static int __s2255_open(struct file *file) fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) return -ENOMEM; - file->private_data = fh; + v4l2_fh_init(&fh->fh, vdev); + v4l2_fh_add(&fh->fh); + file->private_data = &fh->fh; fh->dev = dev; fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fh->channel = channel; @@ -1709,12 +1714,13 @@ static unsigned int s2255_poll(struct file *file, { struct s2255_fh *fh = file->private_data; struct s2255_dev *dev = fh->dev; - int rc; + int rc = v4l2_ctrl_poll(file, wait); + dprintk(100, "%s\n", __func__); if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; mutex_lock(&dev->lock); - rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); + rc |= videobuf_poll_stream(file, &fh->vb_vidq, wait); mutex_unlock(&dev->lock); return rc; } @@ -1761,6 +1767,8 @@ static int s2255_release(struct file *file) videobuf_mmap_free(&fh->vb_vidq); mutex_unlock(&dev->lock); dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); return 0; } @@ -1815,6 +1823,9 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_s_parm = vidioc_s_parm, .vidioc_g_parm = vidioc_g_parm, .vidioc_enum_frameintervals = vidioc_enum_frameintervals, + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static void s2255_video_device_release(struct video_device *vdev) @@ -1898,6 +1909,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) channel->vdev.ctrl_handler = &channel->hdl; channel->vdev.lock = &dev->lock; channel->vdev.v4l2_dev = &dev->v4l2_dev; + set_bit(V4L2_FL_USE_FH_PRIO, &channel->vdev.flags); video_set_drvdata(&channel->vdev, channel); if (video_nr == -1) ret = video_register_device(&channel->vdev, -- cgit From 39696009d0d4472606b7fb90fc635a0d0fecba60 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 Feb 2013 07:06:21 -0300 Subject: [media] s2255: add device_caps support to querycap Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 55c972a0dbed..9cb832517040 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -821,10 +821,12 @@ static int vidioc_querycap(struct file *file, void *priv, { struct s2255_fh *fh = file->private_data; struct s2255_dev *dev = fh->dev; + strlcpy(cap->driver, "s2255", sizeof(cap->driver)); strlcpy(cap->card, "s2255", sizeof(cap->card)); usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit From 469af77a178510ed43d4d527b1b7a607c5c18bcb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:12:58 -0300 Subject: [media] s2255: fixes in the way standards are handled Instead of comparing against STD_NTSC and STD_PAL compare against 60 and 50 Hz formats. That's what you really want. When the standard is changed, make sure the width and height of the format are also updated to reflect the current standard. Also replace the deprecated current_norm by the g_std ioctl. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 61 ++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 9cb832517040..88f728d3b24f 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -225,6 +225,7 @@ struct s2255_channel { struct s2255_dmaqueue vidq; struct s2255_bufferi buffer; struct s2255_mode mode; + v4l2_std_id std; /* jpeg compression */ unsigned jpegqual; /* capture parameters (for high quality mode full size) */ @@ -312,7 +313,7 @@ struct s2255_fh { /* Need DSP version 5+ for video status feature */ #define S2255_MIN_DSP_STATUS 5 #define S2255_MIN_DSP_COLORFILTER 8 -#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) +#define S2255_NORMS (V4L2_STD_ALL) /* private V4L2 controls */ @@ -443,27 +444,27 @@ static const struct s2255_fmt formats[] = { } }; -static int norm_maxw(struct video_device *vdev) +static int norm_maxw(struct s2255_channel *channel) { - return (vdev->current_norm & V4L2_STD_NTSC) ? + return (channel->std & V4L2_STD_525_60) ? LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL; } -static int norm_maxh(struct video_device *vdev) +static int norm_maxh(struct s2255_channel *channel) { - return (vdev->current_norm & V4L2_STD_NTSC) ? + return (channel->std & V4L2_STD_525_60) ? (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2); } -static int norm_minw(struct video_device *vdev) +static int norm_minw(struct s2255_channel *channel) { - return (vdev->current_norm & V4L2_STD_NTSC) ? + return (channel->std & V4L2_STD_525_60) ? LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL; } -static int norm_minh(struct video_device *vdev) +static int norm_minh(struct s2255_channel *channel) { - return (vdev->current_norm & V4L2_STD_NTSC) ? + return (channel->std & V4L2_STD_525_60) ? (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL); } @@ -725,10 +726,10 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (channel->fmt == NULL) return -EINVAL; - if ((w < norm_minw(&channel->vdev)) || - (w > norm_maxw(&channel->vdev)) || - (h < norm_minh(&channel->vdev)) || - (h > norm_maxh(&channel->vdev))) { + if ((w < norm_minw(channel)) || + (w > norm_maxw(channel)) || + (h < norm_minh(channel)) || + (h > norm_maxh(channel))) { dprintk(4, "invalid buffer prepare\n"); return -EINVAL; } @@ -870,8 +871,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct s2255_fh *fh = priv; struct s2255_channel *channel = fh->channel; int is_ntsc; - is_ntsc = - (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0; + is_ntsc = (channel->std & V4L2_STD_525_60) ? 1 : 0; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -998,8 +998,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, channel->height = f->fmt.pix.height; fh->vb_vidq.field = f->fmt.pix.field; fh->type = f->type; - if (channel->width > norm_minw(&channel->vdev)) { - if (channel->height > norm_minh(&channel->vdev)) { + if (channel->width > norm_minw(channel)) { + if (channel->height > norm_minh(channel)) { if (channel->cap_parm.capturemode & V4L2_MODE_HIGHQUALITY) mode.scale = SCALE_4CIFSI; @@ -1323,7 +1323,9 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) struct s2255_fh *fh = priv; struct s2255_mode mode; struct videobuf_queue *q = &fh->vb_vidq; + struct s2255_channel *channel = fh->channel; int ret = 0; + mutex_lock(&q->vb_lock); if (videobuf_queue_is_busy(q)) { dprintk(1, "queue busy\n"); @@ -1336,24 +1338,30 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) goto out_s_std; } mode = fh->channel->mode; - if (*i & V4L2_STD_NTSC) { - dprintk(4, "%s NTSC\n", __func__); + if (*i & V4L2_STD_525_60) { + dprintk(4, "%s 60 Hz\n", __func__); /* if changing format, reset frame decimation/intervals */ if (mode.format != FORMAT_NTSC) { mode.restart = 1; mode.format = FORMAT_NTSC; mode.fdec = FDEC_1; + channel->width = LINE_SZ_4CIFS_NTSC; + channel->height = NUM_LINES_4CIFS_NTSC * 2; } - } else if (*i & V4L2_STD_PAL) { - dprintk(4, "%s PAL\n", __func__); + } else if (*i & V4L2_STD_625_50) { + dprintk(4, "%s 50 Hz\n", __func__); if (mode.format != FORMAT_PAL) { mode.restart = 1; mode.format = FORMAT_PAL; mode.fdec = FDEC_1; + channel->width = LINE_SZ_4CIFS_PAL; + channel->height = NUM_LINES_4CIFS_PAL * 2; } } else { ret = -EINVAL; + goto out_s_std; } + fh->channel->std = *i; if (mode.restart) s2255_set_mode(fh->channel, &mode); out_s_std: @@ -1361,6 +1369,14 @@ out_s_std: return ret; } +static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i) +{ + struct s2255_fh *fh = priv; + + *i = fh->channel->std; + return 0; +} + /* Sensoray 2255 is a multiple channel capture device. It does not have a "crossbar" of inputs. We use one V4L device per channel. The user must @@ -1815,6 +1831,7 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_s_std = vidioc_s_std, + .vidioc_g_std = vidioc_g_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, @@ -1851,7 +1868,6 @@ static struct video_device template = { .ioctl_ops = &s2255_ioctl_ops, .release = s2255_video_device_release, .tvnorms = S2255_NORMS, - .current_norm = V4L2_STD_NTSC_M, }; static const struct v4l2_ctrl_ops s2255_ctrl_ops = { @@ -2265,6 +2281,7 @@ static int s2255_board_init(struct s2255_dev *dev) channel->jpegqual = S2255_DEF_JPEG_QUAL; channel->width = LINE_SZ_4CIFS_NTSC; channel->height = NUM_LINES_4CIFS_NTSC * 2; + channel->std = V4L2_STD_NTSC_M; channel->fmt = &formats[0]; channel->mode.restart = 1; channel->req_image_size = get_transfer_size(&mode_def); -- cgit From 29ceb1101e9b39eaac2f20281a93c2afaf07aa10 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:03:26 -0300 Subject: [media] s2255: zero priv and set colorspace Set priv field of struct v4l2_pix_format to 0 and fill in colorspace. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 88f728d3b24f..a16bc6cdd007 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -859,6 +859,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.pixelformat = channel->fmt->fourcc; f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; return 0; } @@ -954,6 +956,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.field = field; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; dprintk(50, "%s: set width %d height %d field %d\n", __func__, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); return 0; -- cgit From 92513611fa5864b8aec216db5a93bafaa299d623 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:05:08 -0300 Subject: [media] s2255: fix field handling Just set the field value based on the chosen format. It's either INTERLACED or TOP. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 61 ++++++++++---------------------------- 1 file changed, 15 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index a16bc6cdd007..9693eb9d9e8d 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -852,10 +852,15 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, { struct s2255_fh *fh = priv; struct s2255_channel *channel = fh->channel; + int is_ntsc = channel->std & V4L2_STD_525_60; f->fmt.pix.width = channel->width; f->fmt.pix.height = channel->height; - f->fmt.pix.field = fh->vb_vidq.field; + if (f->fmt.pix.height >= + (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2) + f->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + f->fmt.pix.field = V4L2_FIELD_TOP; f->fmt.pix.pixelformat = channel->fmt->fourcc; f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; @@ -869,11 +874,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { const struct s2255_fmt *fmt; enum v4l2_field field; - int b_any_field = 0; struct s2255_fh *fh = priv; struct s2255_channel *channel = fh->channel; - int is_ntsc; - is_ntsc = (channel->std & V4L2_STD_525_60) ? 1 : 0; + int is_ntsc = channel->std & V4L2_STD_525_60; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -881,8 +884,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; field = f->fmt.pix.field; - if (field == V4L2_FIELD_ANY) - b_any_field = 1; dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n", __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height); @@ -890,24 +891,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, /* NTSC */ if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2; - if (b_any_field) { - field = V4L2_FIELD_SEQ_TB; - } else if (!((field == V4L2_FIELD_INTERLACED) || - (field == V4L2_FIELD_SEQ_TB) || - (field == V4L2_FIELD_INTERLACED_TB))) { - dprintk(1, "unsupported field setting\n"); - return -EINVAL; - } + field = V4L2_FIELD_INTERLACED; } else { f->fmt.pix.height = NUM_LINES_1CIFS_NTSC; - if (b_any_field) { - field = V4L2_FIELD_TOP; - } else if (!((field == V4L2_FIELD_TOP) || - (field == V4L2_FIELD_BOTTOM))) { - dprintk(1, "unsupported field setting\n"); - return -EINVAL; - } - + field = V4L2_FIELD_TOP; } if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; @@ -921,37 +908,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, /* PAL */ if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) { f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2; - if (b_any_field) { - field = V4L2_FIELD_SEQ_TB; - } else if (!((field == V4L2_FIELD_INTERLACED) || - (field == V4L2_FIELD_SEQ_TB) || - (field == V4L2_FIELD_INTERLACED_TB))) { - dprintk(1, "unsupported field setting\n"); - return -EINVAL; - } + field = V4L2_FIELD_INTERLACED; } else { f->fmt.pix.height = NUM_LINES_1CIFS_PAL; - if (b_any_field) { - field = V4L2_FIELD_TOP; - } else if (!((field == V4L2_FIELD_TOP) || - (field == V4L2_FIELD_BOTTOM))) { - dprintk(1, "unsupported field setting\n"); - return -EINVAL; - } + field = V4L2_FIELD_TOP; } - if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { + if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) f->fmt.pix.width = LINE_SZ_4CIFS_PAL; - field = V4L2_FIELD_SEQ_TB; - } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { + else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) f->fmt.pix.width = LINE_SZ_2CIFS_PAL; - field = V4L2_FIELD_TOP; - } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { + else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) f->fmt.pix.width = LINE_SZ_1CIFS_PAL; - field = V4L2_FIELD_TOP; - } else { + else f->fmt.pix.width = LINE_SZ_1CIFS_PAL; - field = V4L2_FIELD_TOP; - } } f->fmt.pix.field = field; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; -- cgit From 3c728118e00c42a177f9a5d0295b2a08591bddcb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:07:13 -0300 Subject: [media] s2255: don't zero struct v4l2_streamparm All fields after 'type' are already zeroed by the core framework. Clearing the full struct also clears 'type', which causes a wrong type value to be returned. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 9693eb9d9e8d..eaae9d167e76 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -1476,7 +1476,6 @@ static int vidioc_g_parm(struct file *file, void *priv, struct s2255_channel *channel = fh->channel; if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - memset(sp, 0, sizeof(struct v4l2_streamparm)); sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; sp->parm.capture.capturemode = channel->cap_parm.capturemode; def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000; -- cgit From 05e5d44b078fdd628a2b47c294dd78bbca524afc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 06:09:18 -0300 Subject: [media] s2255: Add ENUM_FRAMESIZES support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 73 ++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index eaae9d167e76..59d40e614e94 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -1545,36 +1545,64 @@ static int vidioc_s_parm(struct file *file, void *priv, return 0; } +#define NUM_SIZE_ENUMS 3 +static const struct v4l2_frmsize_discrete ntsc_sizes[] = { + { 640, 480 }, + { 640, 240 }, + { 320, 240 }, +}; +static const struct v4l2_frmsize_discrete pal_sizes[] = { + { 704, 576 }, + { 704, 288 }, + { 352, 288 }, +}; + +static int vidioc_enum_framesizes(struct file *file, void *priv, + struct v4l2_frmsizeenum *fe) +{ + struct s2255_fh *fh = priv; + struct s2255_channel *channel = fh->channel; + int is_ntsc = channel->std & V4L2_STD_525_60; + const struct s2255_fmt *fmt; + + if (fe->index >= NUM_SIZE_ENUMS) + return -EINVAL; + + fmt = format_by_fourcc(fe->pixel_format); + if (fmt == NULL) + return -EINVAL; + fe->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index]; + return 0; +} + static int vidioc_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fe) { - int is_ntsc = 0; + struct s2255_fh *fh = priv; + struct s2255_channel *channel = fh->channel; + const struct s2255_fmt *fmt; + const struct v4l2_frmsize_discrete *sizes; + int is_ntsc = channel->std & V4L2_STD_525_60; #define NUM_FRAME_ENUMS 4 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5}; + int i; + if (fe->index >= NUM_FRAME_ENUMS) return -EINVAL; - switch (fe->width) { - case 640: - if (fe->height != 240 && fe->height != 480) - return -EINVAL; - is_ntsc = 1; - break; - case 320: - if (fe->height != 240) - return -EINVAL; - is_ntsc = 1; - break; - case 704: - if (fe->height != 288 && fe->height != 576) - return -EINVAL; - break; - case 352: - if (fe->height != 288) - return -EINVAL; - break; - default: + + fmt = format_by_fourcc(fe->pixel_format); + if (fmt == NULL) return -EINVAL; - } + + sizes = is_ntsc ? ntsc_sizes : pal_sizes; + for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++) + if (fe->width == sizes->width && + fe->height == sizes->height) + break; + if (i == NUM_SIZE_ENUMS) + return -EINVAL; + fe->type = V4L2_FRMIVAL_TYPE_DISCRETE; fe->discrete.denominator = is_ntsc ? 30000 : 25000; fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index]; @@ -1813,6 +1841,7 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_g_jpegcomp = vidioc_g_jpegcomp, .vidioc_s_parm = vidioc_s_parm, .vidioc_g_parm = vidioc_g_parm, + .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_enum_frameintervals = vidioc_enum_frameintervals, .vidioc_log_status = v4l2_ctrl_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, -- cgit From 5c632b223a31fa6dd63598e2a250ccc193a8bb4e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 26 Feb 2013 14:29:04 -0300 Subject: [media] s2255: choose YUYV as the default format, not YUV422P The planar YUV422P is quite unusual and few if any applications support it. Instead choose the common YUYV format as the default. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 59d40e614e94..cd06f3cc4f98 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -416,11 +416,6 @@ MODULE_DEVICE_TABLE(usb, s2255_table); /* JPEG formats must be defined last to support jpeg_enable parameter */ static const struct s2255_fmt formats[] = { { - .name = "4:2:2, planar, YUV422P", - .fourcc = V4L2_PIX_FMT_YUV422P, - .depth = 16 - - }, { .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16 @@ -429,6 +424,11 @@ static const struct s2255_fmt formats[] = { .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16 + }, { + .name = "4:2:2, planar, YUV422P", + .fourcc = V4L2_PIX_FMT_YUV422P, + .depth = 16 + }, { .name = "8bpp GREY", .fourcc = V4L2_PIX_FMT_GREY, -- cgit From 0b84caab364f40fdbf85828c9309f0c1c4dc0014 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 26 Feb 2013 14:14:19 -0300 Subject: [media] s2255: fix big-endian support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index cd06f3cc4f98..2bd86132d3e3 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -522,7 +522,7 @@ static void s2255_timer(unsigned long user_data) /* this loads the firmware asynchronously. - Originally this was done synchroously in probe. + Originally this was done synchronously in probe. But it is better to load it asynchronously here than block inside the probe function. Blocking inside probe affects boot time. FW loading is triggered by the timer in the probe function @@ -1157,6 +1157,8 @@ static int s2255_set_mode(struct s2255_channel *channel, __le32 *buffer; unsigned long chn_rev; struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); + int i; + chn_rev = G_chnmap[channel->idx]; dprintk(3, "%s channel: %d\n", __func__, channel->idx); /* if JPEG, set the quality */ @@ -1179,7 +1181,8 @@ static int s2255_set_mode(struct s2255_channel *channel, buffer[0] = IN_DATA_TOKEN; buffer[1] = (__le32) cpu_to_le32(chn_rev); buffer[2] = CMD_SET_MODE; - memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode)); + for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++) + buffer[3 + i] = cpu_to_le32(((u32 *)&channel->mode)[i]); channel->setmode_ready = 0; res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); if (debug) @@ -2511,7 +2514,7 @@ static int s2255_probe(struct usb_interface *interface, return -ENOMEM; } atomic_set(&dev->num_channels, 0); - dev->pid = id->idProduct; + dev->pid = le16_to_cpu(id->idProduct); dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); if (!dev->fw_data) goto errorFWDATA1; @@ -2581,7 +2584,7 @@ static int s2255_probe(struct usb_interface *interface, /* make sure firmware is the latest */ __le32 *pRel; pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; - printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); + printk(KERN_INFO "s2255 dsp fw version %x\n", le32_to_cpu(*pRel)); dev->dsp_fw_ver = le32_to_cpu(*pRel); if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER) printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); -- cgit From e6a60d768bc7b767439c56e34e345eb2fe873b06 Mon Sep 17 00:00:00 2001 From: Fabrizio Gazzato Date: Fri, 15 Feb 2013 18:54:54 -0300 Subject: [media] rtl28xxu: Add USB ID for MaxMedia HU394-T Add USB ID for MaxMedia HU394-T USB DVB-T Multi (FM, DAB, DAB+) dongle (RTL2832U+FC0012) In Italy, is branded as "DIKOM USB-DVBT HD" lsusb: ID 1b80:d394 Afatech Signed-off-by: Fabrizio Gazzato Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index d98387a3c95e..3d128a5e4794 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1372,6 +1372,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = { &rtl2832u_props, "Digivox Micro Hd", NULL) }, { DVB_USB_DEVICE(USB_VID_COMPRO, 0x0620, &rtl2832u_props, "Compro VideoMate U620F", NULL) }, + { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394, + &rtl2832u_props, "MaxMedia HU394-T", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); -- cgit From 805b3e423567f67ba1e0fdf871763294a1f52cbd Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 4 Mar 2013 15:08:26 -0800 Subject: mmc: msm_sdcc: Remove unnecessary include This driver has no reason to include msm_iomap.h. Remove it so that we can remove msm_iomap.h from include/mach in the near future. Acked-by: Chris Ball Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- drivers/mmc/host/msm_sdcc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 7c0af0e80047..0ee4a57fe6b2 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -43,7 +43,6 @@ #include #include -#include #include #include -- cgit From 7bce696b07e3b6aafed58c211c7fa19cd734e4c1 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 4 Mar 2013 15:08:27 -0800 Subject: gpio: Make gpio-msm-v1 into a platform driver Doing this removes the dependence of this driver on the msm_iomap.h and cpu.h mach include headers provied by MSM. This is necessary to support single zImage work in the future and allows us to remove cpu.h entirely and brings us closer to removing msm_iomap.h. Cc: Grant Likely Acked-by: Linus Walleij Tested-by: Rohit Vaswani Acked-by: Rohit Vaswani Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/board-halibut.c | 1 + arch/arm/mach-msm/board-msm7x30.c | 1 + arch/arm/mach-msm/board-qsd8x50.c | 1 + arch/arm/mach-msm/board-trout.c | 1 + arch/arm/mach-msm/devices-msm7x00.c | 31 +++++ arch/arm/mach-msm/devices-msm7x30.c | 31 +++++ arch/arm/mach-msm/devices-qsd8x50.c | 31 +++++ arch/arm/mach-msm/devices.h | 4 + drivers/gpio/gpio-msm-v1.c | 220 ++++++++++++++++++++++++------------ 9 files changed, 250 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 84d720af34ab..82eaf88d2026 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -59,6 +59,7 @@ static struct platform_device smc91x_device = { }; static struct platform_device *devices[] __initdata = { + &msm_device_gpio_7201, &msm_device_uart3, &msm_device_smd, &msm_device_nand, diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 7bc3f82e3ec9..520c141acd03 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -89,6 +89,7 @@ struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { }; static struct platform_device *devices[] __initdata = { + &msm_device_gpio_7x30, #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart2, #endif diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 686e7949a73a..38a532d6937c 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -89,6 +89,7 @@ static struct msm_otg_platform_data msm_otg_pdata = { }; static struct platform_device *devices[] __initdata = { + &msm_device_gpio_8x50, &msm_device_uart3, &msm_device_smd, &msm_device_otg, diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 919bfa32871a..80fe1c5ff5c1 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -36,6 +36,7 @@ extern int trout_init_mmc(unsigned int); static struct platform_device *devices[] __initdata = { + &msm_device_gpio_7201, &msm_device_uart3, &msm_device_smd, &msm_device_nand, diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index f66ee6ea8720..1a0a2306b115 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c @@ -29,6 +29,37 @@ #include "clock-pcom.h" #include +static struct resource msm_gpio_resources[] = { + { + .start = 32 + 0, + .end = 32 + 0, + .flags = IORESOURCE_IRQ, + }, + { + .start = 32 + 1, + .end = 32 + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = 0xa9200800, + .end = 0xa9200800 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio1" + }, + { + .start = 0xa9300C00, + .end = 0xa9300C00 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio2" + }, +}; + +struct platform_device msm_device_gpio_7201 = { + .name = "gpio-msm-7201", + .num_resources = ARRAY_SIZE(msm_gpio_resources), + .resource = msm_gpio_resources, +}; + static struct resource resources_uart1[] = { { .start = INT_UART1, diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c index e90ab5938c5f..12f482c07740 100644 --- a/arch/arm/mach-msm/devices-msm7x30.c +++ b/arch/arm/mach-msm/devices-msm7x30.c @@ -33,6 +33,37 @@ #include +static struct resource msm_gpio_resources[] = { + { + .start = 32 + 18, + .end = 32 + 18, + .flags = IORESOURCE_IRQ, + }, + { + .start = 32 + 19, + .end = 32 + 19, + .flags = IORESOURCE_IRQ, + }, + { + .start = 0xac001000, + .end = 0xac001000 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio1" + }, + { + .start = 0xac101400, + .end = 0xac101400 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio2" + }, +}; + +struct platform_device msm_device_gpio_7x30 = { + .name = "gpio-msm-7x30", + .num_resources = ARRAY_SIZE(msm_gpio_resources), + .resource = msm_gpio_resources, +}; + static struct resource resources_uart2[] = { { .start = INT_UART2, diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c index 4db61d5fe317..2e1b3ec9dfc7 100644 --- a/arch/arm/mach-msm/devices-qsd8x50.c +++ b/arch/arm/mach-msm/devices-qsd8x50.c @@ -30,6 +30,37 @@ #include #include "clock-pcom.h" +static struct resource msm_gpio_resources[] = { + { + .start = 64 + 165 + 9, + .end = 64 + 165 + 9, + .flags = IORESOURCE_IRQ, + }, + { + .start = 64 + 165 + 10, + .end = 64 + 165 + 10, + .flags = IORESOURCE_IRQ, + }, + { + .start = 0xa9000800, + .end = 0xa9000800 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio1" + }, + { + .start = 0xa9100C00, + .end = 0xa9100C00 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + .name = "gpio2" + }, +}; + +struct platform_device msm_device_gpio_8x50 = { + .name = "gpio-msm-8x50", + .num_resources = ARRAY_SIZE(msm_gpio_resources), + .resource = msm_gpio_resources, +}; + static struct resource resources_uart3[] = { { .start = INT_UART3, diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 9545c196c6e8..da902cf51161 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h @@ -20,6 +20,10 @@ #include "clock.h" +extern struct platform_device msm_device_gpio_7201; +extern struct platform_device msm_device_gpio_7x30; +extern struct platform_device msm_device_gpio_8x50; + extern struct platform_device msm_device_uart1; extern struct platform_device msm_device_uart2; extern struct platform_device msm_device_uart3; diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index 52a4d4286eba..c798585a3fe5 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2009-2012, The Linux Foundation. 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 @@ -19,9 +19,10 @@ #include #include #include -#include +#include +#include + #include -#include /* see 80-VA736-2 Rev C pp 695-751 ** @@ -34,10 +35,10 @@ ** macros. */ -#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off)) -#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off)) -#define MSM_GPIO1_SHADOW_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) -#define MSM_GPIO2_SHADOW_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) +#define MSM_GPIO1_REG(off) (off) +#define MSM_GPIO2_REG(off) (off) +#define MSM_GPIO1_SHADOW_REG(off) (off) +#define MSM_GPIO2_SHADOW_REG(off) (off) /* * MSM7X00 registers @@ -276,16 +277,14 @@ #define MSM_GPIO_BANK(soc, bank, first, last) \ { \ - .regs = { \ - .out = soc##_GPIO_OUT_##bank, \ - .in = soc##_GPIO_IN_##bank, \ - .int_status = soc##_GPIO_INT_STATUS_##bank, \ - .int_clear = soc##_GPIO_INT_CLEAR_##bank, \ - .int_en = soc##_GPIO_INT_EN_##bank, \ - .int_edge = soc##_GPIO_INT_EDGE_##bank, \ - .int_pos = soc##_GPIO_INT_POS_##bank, \ - .oe = soc##_GPIO_OE_##bank, \ - }, \ + .regs[MSM_GPIO_OUT] = soc##_GPIO_OUT_##bank, \ + .regs[MSM_GPIO_IN] = soc##_GPIO_IN_##bank, \ + .regs[MSM_GPIO_INT_STATUS] = soc##_GPIO_INT_STATUS_##bank, \ + .regs[MSM_GPIO_INT_CLEAR] = soc##_GPIO_INT_CLEAR_##bank, \ + .regs[MSM_GPIO_INT_EN] = soc##_GPIO_INT_EN_##bank, \ + .regs[MSM_GPIO_INT_EDGE] = soc##_GPIO_INT_EDGE_##bank, \ + .regs[MSM_GPIO_INT_POS] = soc##_GPIO_INT_POS_##bank, \ + .regs[MSM_GPIO_OE] = soc##_GPIO_OE_##bank, \ .chip = { \ .base = (first), \ .ngpio = (last) - (first) + 1, \ @@ -301,39 +300,57 @@ #define MSM_GPIO_BROKEN_INT_CLEAR 1 -struct msm_gpio_regs { - void __iomem *out; - void __iomem *in; - void __iomem *int_status; - void __iomem *int_clear; - void __iomem *int_en; - void __iomem *int_edge; - void __iomem *int_pos; - void __iomem *oe; +enum msm_gpio_reg { + MSM_GPIO_IN, + MSM_GPIO_OUT, + MSM_GPIO_INT_STATUS, + MSM_GPIO_INT_CLEAR, + MSM_GPIO_INT_EN, + MSM_GPIO_INT_EDGE, + MSM_GPIO_INT_POS, + MSM_GPIO_OE, + MSM_GPIO_REG_NR }; struct msm_gpio_chip { spinlock_t lock; struct gpio_chip chip; - struct msm_gpio_regs regs; + unsigned long regs[MSM_GPIO_REG_NR]; #if MSM_GPIO_BROKEN_INT_CLEAR unsigned int_status_copy; #endif unsigned int both_edge_detect; unsigned int int_enable[2]; /* 0: awake, 1: sleep */ + void __iomem *base; +}; + +struct msm_gpio_initdata { + struct msm_gpio_chip *chips; + int count; }; +static void msm_gpio_writel(struct msm_gpio_chip *chip, u32 val, + enum msm_gpio_reg reg) +{ + writel(val, chip->base + chip->regs[reg]); +} + +static u32 msm_gpio_readl(struct msm_gpio_chip *chip, enum msm_gpio_reg reg) +{ + return readl(chip->base + chip->regs[reg]); +} + static int msm_gpio_write(struct msm_gpio_chip *msm_chip, unsigned offset, unsigned on) { unsigned mask = BIT(offset); unsigned val; - val = readl(msm_chip->regs.out); + val = msm_gpio_readl(msm_chip, MSM_GPIO_OUT); if (on) - writel(val | mask, msm_chip->regs.out); + msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_OUT); else - writel(val & ~mask, msm_chip->regs.out); + msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_OUT); return 0; } @@ -342,13 +359,13 @@ static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip) int loop_limit = 100; unsigned pol, val, val2, intstat; do { - val = readl(msm_chip->regs.in); - pol = readl(msm_chip->regs.int_pos); + val = msm_gpio_readl(msm_chip, MSM_GPIO_IN); + pol = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS); pol = (pol & ~msm_chip->both_edge_detect) | (~val & msm_chip->both_edge_detect); - writel(pol, msm_chip->regs.int_pos); - intstat = readl(msm_chip->regs.int_status); - val2 = readl(msm_chip->regs.in); + msm_gpio_writel(msm_chip, pol, MSM_GPIO_INT_POS); + intstat = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); + val2 = msm_gpio_readl(msm_chip, MSM_GPIO_IN); if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0) return; } while (loop_limit-- > 0); @@ -365,10 +382,11 @@ static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip, /* Save interrupts that already triggered before we loose them. */ /* Any interrupt that triggers between the read of int_status */ /* and the write to int_clear will still be lost though. */ - msm_chip->int_status_copy |= readl(msm_chip->regs.int_status); + msm_chip->int_status_copy |= + msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); msm_chip->int_status_copy &= ~bit; #endif - writel(bit, msm_chip->regs.int_clear); + msm_gpio_writel(msm_chip, bit, MSM_GPIO_INT_CLEAR); msm_gpio_update_both_edge_detect(msm_chip); return 0; } @@ -377,10 +395,12 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct msm_gpio_chip *msm_chip; unsigned long irq_flags; + u32 val; msm_chip = container_of(chip, struct msm_gpio_chip, chip); spin_lock_irqsave(&msm_chip->lock, irq_flags); - writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe); + val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) & ~BIT(offset); + msm_gpio_writel(msm_chip, val, MSM_GPIO_OE); spin_unlock_irqrestore(&msm_chip->lock, irq_flags); return 0; } @@ -390,11 +410,13 @@ msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { struct msm_gpio_chip *msm_chip; unsigned long irq_flags; + u32 val; msm_chip = container_of(chip, struct msm_gpio_chip, chip); spin_lock_irqsave(&msm_chip->lock, irq_flags); msm_gpio_write(msm_chip, offset, value); - writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe); + val = msm_gpio_readl(msm_chip, MSM_GPIO_OE) | BIT(offset); + msm_gpio_writel(msm_chip, val, MSM_GPIO_OE); spin_unlock_irqrestore(&msm_chip->lock, irq_flags); return 0; } @@ -404,7 +426,7 @@ static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) struct msm_gpio_chip *msm_chip; msm_chip = container_of(chip, struct msm_gpio_chip, chip); - return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0; + return (msm_gpio_readl(msm_chip, MSM_GPIO_IN) & (1U << offset)) ? 1 : 0; } static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) @@ -450,6 +472,11 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x01[] = { MSM_GPIO_BANK(MSM7X00, 5, 107, 121), }; +static struct msm_gpio_initdata msm_gpio_7x01_init = { + .chips = msm_gpio_chips_msm7x01, + .count = ARRAY_SIZE(msm_gpio_chips_msm7x01), +}; + static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = { MSM_GPIO_BANK(MSM7X30, 0, 0, 15), MSM_GPIO_BANK(MSM7X30, 1, 16, 43), @@ -461,6 +488,11 @@ static struct msm_gpio_chip msm_gpio_chips_msm7x30[] = { MSM_GPIO_BANK(MSM7X30, 7, 151, 181), }; +static struct msm_gpio_initdata msm_gpio_7x30_init = { + .chips = msm_gpio_chips_msm7x30, + .count = ARRAY_SIZE(msm_gpio_chips_msm7x30), +}; + static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = { MSM_GPIO_BANK(QSD8X50, 0, 0, 15), MSM_GPIO_BANK(QSD8X50, 1, 16, 42), @@ -472,6 +504,11 @@ static struct msm_gpio_chip msm_gpio_chips_qsd8x50[] = { MSM_GPIO_BANK(QSD8X50, 7, 153, 164), }; +static struct msm_gpio_initdata msm_gpio_8x50_init = { + .chips = msm_gpio_chips_qsd8x50, + .count = ARRAY_SIZE(msm_gpio_chips_qsd8x50), +}; + static void msm_gpio_irq_ack(struct irq_data *d) { unsigned long irq_flags; @@ -490,10 +527,10 @@ static void msm_gpio_irq_mask(struct irq_data *d) spin_lock_irqsave(&msm_chip->lock, irq_flags); /* level triggered interrupts are also latched */ - if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) + if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset))) msm_gpio_clear_detect_status(msm_chip, offset); msm_chip->int_enable[0] &= ~BIT(offset); - writel(msm_chip->int_enable[0], msm_chip->regs.int_en); + msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN); spin_unlock_irqrestore(&msm_chip->lock, irq_flags); } @@ -505,10 +542,10 @@ static void msm_gpio_irq_unmask(struct irq_data *d) spin_lock_irqsave(&msm_chip->lock, irq_flags); /* level triggered interrupts are also latched */ - if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) + if (!(msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE) & BIT(offset))) msm_gpio_clear_detect_status(msm_chip, offset); msm_chip->int_enable[0] |= BIT(offset); - writel(msm_chip->int_enable[0], msm_chip->regs.int_en); + msm_gpio_writel(msm_chip, msm_chip->int_enable[0], MSM_GPIO_INT_EN); spin_unlock_irqrestore(&msm_chip->lock, irq_flags); } @@ -537,12 +574,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) unsigned val, mask = BIT(offset); spin_lock_irqsave(&msm_chip->lock, irq_flags); - val = readl(msm_chip->regs.int_edge); + val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_EDGE); if (flow_type & IRQ_TYPE_EDGE_BOTH) { - writel(val | mask, msm_chip->regs.int_edge); + msm_gpio_writel(msm_chip, val | mask, MSM_GPIO_INT_EDGE); __irq_set_handler_locked(d->irq, handle_edge_irq); } else { - writel(val & ~mask, msm_chip->regs.int_edge); + msm_gpio_writel(msm_chip, val & ~mask, MSM_GPIO_INT_EDGE); __irq_set_handler_locked(d->irq, handle_level_irq); } if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { @@ -550,11 +587,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) msm_gpio_update_both_edge_detect(msm_chip); } else { msm_chip->both_edge_detect &= ~mask; - val = readl(msm_chip->regs.int_pos); + val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_POS); if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) - writel(val | mask, msm_chip->regs.int_pos); + val |= mask; else - writel(val & ~mask, msm_chip->regs.int_pos); + val &= ~mask; + msm_gpio_writel(msm_chip, val, MSM_GPIO_INT_POS); } spin_unlock_irqrestore(&msm_chip->lock, irq_flags); return 0; @@ -567,7 +605,7 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) for (i = 0; i < msm_gpio_count; i++) { struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i]; - val = readl(msm_chip->regs.int_status); + val = msm_gpio_readl(msm_chip, MSM_GPIO_INT_STATUS); val &= msm_chip->int_enable[0]; while (val) { mask = val & -val; @@ -592,22 +630,36 @@ static struct irq_chip msm_gpio_irq_chip = { .irq_set_type = msm_gpio_irq_set_type, }; -static int __init msm_init_gpio(void) +static int __devinit gpio_msm_v1_probe(struct platform_device *pdev) { int i, j = 0; - - if (cpu_is_msm7x01()) { - msm_gpio_chips = msm_gpio_chips_msm7x01; - msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_msm7x01); - } else if (cpu_is_msm7x30()) { - msm_gpio_chips = msm_gpio_chips_msm7x30; - msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_msm7x30); - } else if (cpu_is_qsd8x50()) { - msm_gpio_chips = msm_gpio_chips_qsd8x50; - msm_gpio_count = ARRAY_SIZE(msm_gpio_chips_qsd8x50); - } else { - return 0; - } + const struct platform_device_id *dev_id = platform_get_device_id(pdev); + struct msm_gpio_initdata *data; + int irq1, irq2; + struct resource *res; + void __iomem *base1, __iomem *base2; + + data = (struct msm_gpio_initdata *)dev_id->driver_data; + msm_gpio_chips = data->chips; + msm_gpio_count = data->count; + + irq1 = platform_get_irq(pdev, 0); + if (irq1 < 0) + return irq1; + + irq2 = platform_get_irq(pdev, 1); + if (irq2 < 0) + return irq2; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base1 = devm_request_and_ioremap(&pdev->dev, res); + if (!base1) + return -EADDRNOTAVAIL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + base2 = devm_request_and_ioremap(&pdev->dev, res); + if (!base2) + return -EADDRNOTAVAIL; for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) { if (i - FIRST_GPIO_IRQ >= @@ -621,16 +673,42 @@ static int __init msm_init_gpio(void) } for (i = 0; i < msm_gpio_count; i++) { + if (i == 1) + msm_gpio_chips[i].base = base2; + else + msm_gpio_chips[i].base = base1; spin_lock_init(&msm_gpio_chips[i].lock); - writel(0, msm_gpio_chips[i].regs.int_en); + msm_gpio_writel(&msm_gpio_chips[i], 0, MSM_GPIO_INT_EN); gpiochip_add(&msm_gpio_chips[i].chip); } - irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); - irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); - irq_set_irq_wake(INT_GPIO_GROUP1, 1); - irq_set_irq_wake(INT_GPIO_GROUP2, 2); + irq_set_chained_handler(irq1, msm_gpio_irq_handler); + irq_set_chained_handler(irq2, msm_gpio_irq_handler); + irq_set_irq_wake(irq1, 1); + irq_set_irq_wake(irq2, 2); return 0; } -postcore_initcall(msm_init_gpio); +static struct platform_device_id gpio_msm_v1_device_ids[] = { + { "gpio-msm-7201", (unsigned long)&msm_gpio_7x01_init }, + { "gpio-msm-7x30", (unsigned long)&msm_gpio_7x30_init }, + { "gpio-msm-8x50", (unsigned long)&msm_gpio_8x50_init }, + { } +}; +MODULE_DEVICE_TABLE(platform, gpio_msm_v1_device_ids); + +static struct platform_driver gpio_msm_v1_driver = { + .driver = { + .name = "gpio-msm-v1", + .owner = THIS_MODULE, + }, + .probe = gpio_msm_v1_probe, + .id_table = gpio_msm_v1_device_ids, +}; + +static int __init gpio_msm_v1_init(void) +{ + return platform_driver_register(&gpio_msm_v1_driver); +} +postcore_initcall(gpio_msm_v1_init); +MODULE_LICENSE("GPL v2"); -- cgit From fa563073281d7be6c685a0bb8ca6b2737e00f368 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 17 Feb 2013 09:40:05 -0300 Subject: [media] bttv: make remote controls of devices with i2c ir decoder working MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Request module ir-kbd-i2c if an i2c ir decoder is detected. Tested with device "Hauppauge WinTV Theatre" (model 37284 rev B421). Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-input.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 04207a799055..01c71214f9ec 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -375,6 +375,7 @@ void init_bttv_i2c_ir(struct bttv *btv) I2C_CLIENT_END }; struct i2c_board_info info; + struct i2c_client *i2c_dev; if (0 != btv->i2c_rc) return; @@ -390,7 +391,12 @@ void init_bttv_i2c_ir(struct bttv *btv) btv->init_data.ir_codes = RC_MAP_PV951; info.addr = 0x4b; break; - default: + } + + if (btv->init_data.name) { + info.platform_data = &btv->init_data; + i2c_dev = i2c_new_device(&btv->c.i2c_adap, &info); + } else { /* * The external IR receiver is at i2c address 0x34 (0x35 for * reads). Future Hauppauge cards will have an internal @@ -399,16 +405,14 @@ void init_bttv_i2c_ir(struct bttv *btv) * internal. * That's why we probe 0x1a (~0x34) first. CB */ - - i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); - return; + i2c_dev = i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); } + if (NULL == i2c_dev) + return; - if (btv->init_data.name) - info.platform_data = &btv->init_data; - i2c_new_device(&btv->c.i2c_adap, &info); - - return; +#if defined(CONFIG_MODULES) && defined(MODULE) + request_module("ir-kbd-i2c"); +#endif } int fini_bttv_i2c(struct bttv *btv) -- cgit From 457ba4ce4f435d0b4dd82a0acc6c796e541a2ea7 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 17 Feb 2013 09:41:29 -0300 Subject: [media] bttv: move fini_bttv_i2c() from bttv-input.c to bttv-i2c.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like init_bttv_i2c(), fini_bttv_i2c() belongs to bttv-i2c.c. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-i2c.c | 8 ++++++++ drivers/media/pci/bt8xx/bttv-input.c | 8 -------- drivers/media/pci/bt8xx/bttvp.h | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c index c63c643ed1f8..b7c52dc8999c 100644 --- a/drivers/media/pci/bt8xx/bttv-i2c.c +++ b/drivers/media/pci/bt8xx/bttv-i2c.c @@ -394,3 +394,11 @@ int init_bttv_i2c(struct bttv *btv) return btv->i2c_rc; } + +int fini_bttv_i2c(struct bttv *btv) +{ + if (0 != btv->i2c_rc) + return 0; + + return i2c_del_adapter(&btv->c.i2c_adap); +} diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 01c71214f9ec..f36821367d8d 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -415,14 +415,6 @@ void init_bttv_i2c_ir(struct bttv *btv) #endif } -int fini_bttv_i2c(struct bttv *btv) -{ - if (0 != btv->i2c_rc) - return 0; - - return i2c_del_adapter(&btv->c.i2c_adap); -} - int bttv_input_init(struct bttv *btv) { struct bttv_ir *ir; diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index eb13be7ae3f4..e7910e0ffa05 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -300,6 +300,10 @@ extern int no_overlay; /* bttv-input.c */ extern void init_bttv_i2c_ir(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* bttv-i2c.c */ +extern int init_bttv_i2c(struct bttv *btv); extern int fini_bttv_i2c(struct bttv *btv); /* ---------------------------------------------------------- */ @@ -310,7 +314,6 @@ extern unsigned int bttv_verbose; extern unsigned int bttv_debug; extern unsigned int bttv_gpio; extern void bttv_gpio_tracking(struct bttv *btv, char *comment); -extern int init_bttv_i2c(struct bttv *btv); #define dprintk(fmt, ...) \ do { \ -- cgit From 07e169335ff0570c6e67b5ccf74d793f00ab0834 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 28 Feb 2013 12:33:16 +0100 Subject: virtio_ccw: pass a cookie value to kvm hypercall Lookups by channel/vq pair on host during virtio notifications might be expensive. Interpret hypercall return value as a cookie which host can use to do device lookups for the next notification more efficiently. [CH: Fix line > 80 chars] Tested-by: Christian Borntraeger Reviewed-by: Christian Borntraeger Signed-off-by: Michael S. Tsirkin Signed-off-by: Cornelia Huck Signed-off-by: Marcelo Tosatti --- drivers/s390/kvm/virtio_ccw.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 2029b6caa595..3d657522b3e2 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { void *queue; struct vq_info_block *info_block; struct list_head node; + long cookie; }; #define KVM_VIRTIO_CCW_RING_ALIGN 4096 @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, } static inline long do_kvm_notify(struct subchannel_id schid, - unsigned long queue_index) + unsigned long queue_index, + long cookie) { register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; register struct subchannel_id __schid asm("2") = schid; register unsigned long __index asm("3") = queue_index; register long __rc asm("2"); + register long __cookie asm("4") = cookie; asm volatile ("diag 2,4,0x500\n" - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), + "d"(__cookie) : "memory", "cc"); return __rc; } @@ -166,7 +170,8 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) vcdev = to_vc_device(info->vq->vdev); ccw_device_get_schid(vcdev->cdev, &schid); - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), + info->cookie); } static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, -- cgit From 6a773cb825afb74a600a08fe87fab55ee98ec2ac Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 28 Feb 2013 12:33:17 +0100 Subject: KVM: s390: Export virtio-ccw api. Export the virtio-ccw api in a header for usage by other code. Signed-off-by: Cornelia Huck Signed-off-by: Marcelo Tosatti --- arch/s390/include/uapi/asm/Kbuild | 1 + arch/s390/include/uapi/asm/virtio-ccw.h | 21 +++++++++++++++++++++ drivers/s390/kvm/virtio_ccw.c | 5 +---- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 arch/s390/include/uapi/asm/virtio-ccw.h (limited to 'drivers') diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild index 7bf68fff7c5d..9ccd1905bdad 100644 --- a/arch/s390/include/uapi/asm/Kbuild +++ b/arch/s390/include/uapi/asm/Kbuild @@ -44,5 +44,6 @@ header-y += termios.h header-y += types.h header-y += ucontext.h header-y += unistd.h +header-y += virtio-ccw.h header-y += vtoc.h header-y += zcrypt.h diff --git a/arch/s390/include/uapi/asm/virtio-ccw.h b/arch/s390/include/uapi/asm/virtio-ccw.h new file mode 100644 index 000000000000..a9a4ebf79fa7 --- /dev/null +++ b/arch/s390/include/uapi/asm/virtio-ccw.h @@ -0,0 +1,21 @@ +/* + * Definitions for virtio-ccw devices. + * + * Copyright IBM Corp. 2013 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Cornelia Huck + */ +#ifndef __KVM_VIRTIO_CCW_H +#define __KVM_VIRTIO_CCW_H + +/* Alignment of vring buffers. */ +#define KVM_VIRTIO_CCW_RING_ALIGN 4096 + +/* Subcode for diagnose 500 (virtio hypercall). */ +#define KVM_S390_VIRTIO_CCW_NOTIFY 3 + +#endif diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 3d657522b3e2..42d507c4e06b 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * virtio related functions @@ -80,10 +81,6 @@ struct virtio_ccw_vq_info { long cookie; }; -#define KVM_VIRTIO_CCW_RING_ALIGN 4096 - -#define KVM_S390_VIRTIO_CCW_NOTIFY 3 - #define CCW_CMD_SET_VQ 0x13 #define CCW_CMD_VDEV_RESET 0x33 #define CCW_CMD_SET_IND 0x43 -- cgit From 5db5a20a50cfd078c78b13a988f237cca81aedc5 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 6 Mar 2013 11:31:06 +1100 Subject: staging: zcache: disable ZCACHE_DEBUG due to build error In file included from drivers/staging/zcache/debug.c:2:0: drivers/staging/zcache/debug.h: In function 'dec_zcache_obj_count': drivers/staging/zcache/debug.h:16:2: error: implicit declaration of function 'BUG_ON' [-Werror=implicit-function-declaration] Signed-off-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 2da6cc444c7e..ad47b4b8f04b 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -13,6 +13,7 @@ config ZCACHE config ZCACHE_DEBUG bool "Enable debug statistics" depends on DEBUG_FS && ZCACHE + depends on BROKEN default n help This is used to provide an debugfs directory with counters of -- cgit From e9f5b8145af9a0ee34e98cf01dcd3afb87225538 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Tue, 5 Mar 2013 15:27:38 +0000 Subject: staging: android: ashmem: Add support for 32bit ashmem calls in a 64bit kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Android's shared memory subsystem, Ashmem, does not support calls from a 32bit userspace in a 64 bit kernel. This patch adds support for syscalls coming from a 32bit userspace in a 64bit kernel. The patch has been successfully tested on ARMv8 AEM(64bit platform model) and Versatile Express A9(32bit platform). v2: Fix missing compat.h include. Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Acked-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 21 ++++++++++++++++++++- drivers/staging/android/ashmem.h | 7 +++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 38a9135a2f6d..e681bdd9aa5f 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -702,6 +702,23 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } +/* support of 32bit userspace on 64bit platforms */ +#ifdef CONFIG_COMPAT +static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + + switch (cmd) { + case COMPAT_ASHMEM_SET_SIZE: + cmd = ASHMEM_SET_SIZE; + break; + case COMPAT_ASHMEM_SET_PROT_MASK: + cmd = ASHMEM_SET_PROT_MASK; + break; + } + return ashmem_ioctl(file, cmd, arg); +} +#endif + static const struct file_operations ashmem_fops = { .owner = THIS_MODULE, .open = ashmem_open, @@ -710,7 +727,9 @@ static const struct file_operations ashmem_fops = { .llseek = ashmem_llseek, .mmap = ashmem_mmap, .unlocked_ioctl = ashmem_ioctl, - .compat_ioctl = ashmem_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_ashmem_ioctl, +#endif }; static struct miscdevice ashmem_misc = { diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h index 1976b10ef93e..8dc0f0d3adf3 100644 --- a/drivers/staging/android/ashmem.h +++ b/drivers/staging/android/ashmem.h @@ -14,6 +14,7 @@ #include #include +#include #define ASHMEM_NAME_LEN 256 @@ -45,4 +46,10 @@ struct ashmem_pin { #define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) #define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) +/* support of 32bit userspace on 64bit platforms */ +#ifdef CONFIG_COMPAT +#define COMPAT_ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, compat_size_t) +#define COMPAT_ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned int) +#endif + #endif /* _LINUX_ASHMEM_H */ -- cgit From ede4d7a5b9835510fd1f724367f68d2fa4128453 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 1 Mar 2013 11:22:47 -0600 Subject: gpio/omap: convert gpio irq domain to linear mapping Currently the OMAP GPIO driver uses a legacy mapping for the GPIO IRQ domain. This is not necessary because we do not need to assign a specific interrupt number to the GPIO IRQ domain. Therefore, convert the OMAP GPIO driver to use a linear mapping instead. Please note that this also allows to simplify the logic in the OMAP gpio_irq_handler() routine, by using irq_find_mapping() to obtain the virtual irq number from the GPIO bank and bank index. Reported-by: Linus Walleij Signed-off-by: Jon Hunter Reviewed-by: Felipe Balbi Acked-by: Santosh Shilimkar Acked-by: Kevin Hilman Tested-by: Javier Martinez Canillas Signed-off-by: Grant Likely --- drivers/gpio/gpio-omap.c | 72 +++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 159f5c57eb45..c3598d143aa9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -53,7 +53,6 @@ struct gpio_bank { struct list_head node; void __iomem *base; u16 irq; - int irq_base; struct irq_domain *domain; u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; @@ -89,7 +88,14 @@ struct gpio_bank { static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) { - return gpio_irq - bank->irq_base + bank->chip.base; + return bank->chip.base + gpio_irq; +} + +static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); + + return irq_find_mapping(bank->domain, offset); } static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) @@ -427,7 +433,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) #endif if (!gpio) - gpio = irq_to_gpio(bank, d->irq); + gpio = irq_to_gpio(bank, d->hwirq); if (type & ~IRQ_TYPE_SENSE_MASK) return -EINVAL; @@ -580,7 +586,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) static int gpio_wake_enable(struct irq_data *d, unsigned int enable) { struct gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = irq_to_gpio(bank, d->irq); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); return _set_gpio_wakeup(bank, gpio, enable); } @@ -680,7 +686,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *isr_reg = NULL; u32 isr; - unsigned int gpio_irq, gpio_index; + unsigned int i; struct gpio_bank *bank; int unmasked = 0; struct irq_chip *chip = irq_desc_get_chip(desc); @@ -721,15 +727,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (!isr) break; - gpio_irq = bank->irq_base; - for (; isr != 0; isr >>= 1, gpio_irq++) { - int gpio = irq_to_gpio(bank, gpio_irq); - + for (i = 0; isr != 0; isr >>= 1, i++) { if (!(isr & 1)) continue; - gpio_index = GPIO_INDEX(bank, gpio); - /* * Some chips can't respond to both rising and falling * at the same time. If this irq was requested with @@ -737,10 +738,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) * to respond to the IRQ for the opposite direction. * This will be indicated in the bank toggle_mask. */ - if (bank->toggle_mask & (1 << gpio_index)) - _toggle_gpio_edge_triggering(bank, gpio_index); + if (bank->toggle_mask & (1 << i)) + _toggle_gpio_edge_triggering(bank, i); - generic_handle_irq(gpio_irq); + generic_handle_irq(irq_find_mapping(bank->domain, i)); } } /* if bank has any level sensitive GPIO pin interrupt @@ -756,7 +757,7 @@ exit: static void gpio_irq_shutdown(struct irq_data *d) { struct gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = irq_to_gpio(bank, d->irq); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; spin_lock_irqsave(&bank->lock, flags); @@ -767,7 +768,7 @@ static void gpio_irq_shutdown(struct irq_data *d) static void gpio_ack_irq(struct irq_data *d) { struct gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = irq_to_gpio(bank, d->irq); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); _clear_gpio_irqstatus(bank, gpio); } @@ -775,7 +776,7 @@ static void gpio_ack_irq(struct irq_data *d) static void gpio_mask_irq(struct irq_data *d) { struct gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = irq_to_gpio(bank, d->irq); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; spin_lock_irqsave(&bank->lock, flags); @@ -787,7 +788,7 @@ static void gpio_mask_irq(struct irq_data *d) static void gpio_unmask_irq(struct irq_data *d) { struct gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = irq_to_gpio(bank, d->irq); + unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned int irq_mask = GPIO_BIT(bank, gpio); u32 trigger = irqd_get_trigger_type(d); unsigned long flags; @@ -953,14 +954,6 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) spin_unlock_irqrestore(&bank->lock, flags); } -static int gpio_2irq(struct gpio_chip *chip, unsigned offset) -{ - struct gpio_bank *bank; - - bank = container_of(chip, struct gpio_bank, chip); - return bank->irq_base + offset; -} - /*---------------------------------------------------------------------*/ static void __init omap_gpio_show_rev(struct gpio_bank *bank) @@ -1057,7 +1050,7 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) bank->chip.direction_output = gpio_output; bank->chip.set_debounce = gpio_debounce; bank->chip.set = gpio_set; - bank->chip.to_irq = gpio_2irq; + bank->chip.to_irq = omap_gpio_to_irq; if (bank->is_mpuio) { bank->chip.label = "mpuio"; if (bank->regs->wkup_en) @@ -1072,15 +1065,16 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) gpiochip_add(&bank->chip); - for (j = bank->irq_base; j < bank->irq_base + bank->width; j++) { - irq_set_lockdep_class(j, &gpio_lock_class); - irq_set_chip_data(j, bank); + for (j = 0; j < bank->width; j++) { + int irq = irq_create_mapping(bank->domain, j); + irq_set_lockdep_class(irq, &gpio_lock_class); + irq_set_chip_data(irq, bank); if (bank->is_mpuio) { - omap_mpuio_alloc_gc(bank, j, bank->width); + omap_mpuio_alloc_gc(bank, irq, bank->width); } else { - irq_set_chip(j, &gpio_irq_chip); - irq_set_handler(j, handle_simple_irq); - set_irq_flags(j, IRQF_VALID); + irq_set_chip_and_handler(irq, &gpio_irq_chip, + handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); } } irq_set_chained_handler(bank->irq, gpio_irq_handler); @@ -1130,14 +1124,10 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->chip.of_node = of_node_get(node); #endif - bank->irq_base = irq_alloc_descs(-1, 0, bank->width, 0); - if (bank->irq_base < 0) { - dev_err(dev, "Couldn't allocate IRQ numbers\n"); + bank->domain = irq_domain_add_linear(node, bank->width, + &irq_domain_simple_ops, NULL); + if (!bank->domain) return -ENODEV; - } - - bank->domain = irq_domain_add_legacy(node, bank->width, bank->irq_base, - 0, &irq_domain_simple_ops, NULL); if (bank->regs->set_dataout && bank->regs->clr_dataout) bank->set_dataout = _set_gpio_dataout_reg; -- cgit From 8d4c277e185c31359cf70573d8b0351fb7dd0dfe Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Fri, 1 Mar 2013 11:22:48 -0600 Subject: gpio/omap: warn if bank is not enabled on setting irq type For OMAP devices, if a gpio is being used as an interrupt source but has not been requested by calling gpio_request(), a call to request_irq() may cause the kernel hang because the gpio bank may be disabled and hence the register access will fail. To prevent such hangs, test for this case and warn if this is detected. Signed-off-by: Jon Hunter Reviewed-by: Felipe Balbi Acked-by: Santosh Shilimkar Acked-by: Kevin Hilman Tested-by: Javier Martinez Canillas Signed-off-by: Grant Likely --- drivers/gpio/gpio-omap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c3598d143aa9..0d30c7acf0c7 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -427,6 +427,9 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) int retval; unsigned long flags; + if (WARN_ON(!bank->mod_usage)) + return -EINVAL; + #ifdef CONFIG_ARCH_OMAP1 if (d->irq > IH_MPUIO_BASE) gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); -- cgit From 753c5983ddd38022a680a36f5d66b23b185c9b62 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 22:26:23 +0900 Subject: gpio/em: Add Device Tree support Update the Emma Mobile GPIO driver to add DT support. The patch simply adds a two-cell xlate function and updates the probe code to allow configuration via DT using the "ngpios" property plus OF id in the same style as gpio-mvebu.c. The code is also adjusted to use postcore_initcall() to force early setup. Signed-off-by: Magnus Damm Signed-off-by: Grant Likely --- drivers/gpio/gpio-em.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index deca78f99316..d05369735857 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -231,10 +231,12 @@ static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, static struct irq_domain_ops em_gio_irq_domain_ops = { .map = em_gio_irq_domain_map, + .xlate = irq_domain_xlate_twocell, }; static int em_gio_probe(struct platform_device *pdev) { + struct gpio_em_config pdata_dt; struct gpio_em_config *pdata = pdev->dev.platform_data; struct em_gio_priv *p; struct resource *io[2], *irq[2]; @@ -259,8 +261,8 @@ static int em_gio_probe(struct platform_device *pdev) irq[0] = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1); - if (!io[0] || !io[1] || !irq[0] || !irq[1] || !pdata) { - dev_err(&pdev->dev, "missing IRQ, IOMEM or configuration\n"); + if (!io[0] || !io[1] || !irq[0] || !irq[1]) { + dev_err(&pdev->dev, "missing IRQ or IOMEM\n"); ret = -EINVAL; goto err1; } @@ -279,6 +281,25 @@ static int em_gio_probe(struct platform_device *pdev) goto err2; } + if (!pdata) { + memset(&pdata_dt, 0, sizeof(pdata_dt)); + pdata = &pdata_dt; + + if (of_property_read_u32(pdev->dev.of_node, "ngpios", + &pdata->number_of_pins)) { + dev_err(&pdev->dev, "Missing ngpios OF property\n"); + ret = -EINVAL; + goto err3; + } + + ret = of_alias_get_id(pdev->dev.of_node, "gpio"); + if (ret < 0) { + dev_err(&pdev->dev, "Couldn't get OF id\n"); + goto err3; + } + pdata->gpio_base = ret * 32; /* 32 GPIOs per instance */ + } + gpio_chip = &p->gpio_chip; gpio_chip->direction_input = em_gio_direction_input; gpio_chip->get = em_gio_get; @@ -366,15 +387,33 @@ static int em_gio_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id em_gio_dt_ids[] = { + { .compatible = "renesas,em-gio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, em_gio_dt_ids); + static struct platform_driver em_gio_device_driver = { .probe = em_gio_probe, .remove = em_gio_remove, .driver = { .name = "em_gio", + .of_match_table = em_gio_dt_ids, + .owner = THIS_MODULE, } }; -module_platform_driver(em_gio_device_driver); +static int __init em_gio_init(void) +{ + return platform_driver_register(&em_gio_device_driver); +} +postcore_initcall(em_gio_init); + +static void __exit em_gio_exit(void) +{ + platform_driver_unregister(&em_gio_device_driver); +} +module_exit(em_gio_exit); MODULE_AUTHOR("Magnus Damm"); MODULE_DESCRIPTION("Renesas Emma Mobile GIO Driver"); -- cgit From ecad0a684c30c8f28c332c12f0746a22189be4f0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 4 Mar 2013 16:42:03 +0000 Subject: net: at91_ether: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/at91_ether.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 3becdb2deb46..1a57e16ada7c 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -519,18 +519,7 @@ static struct platform_driver at91ether_driver = { }, }; -static int __init at91ether_init(void) -{ - return platform_driver_probe(&at91ether_driver, at91ether_probe); -} - -static void __exit at91ether_exit(void) -{ - platform_driver_unregister(&at91ether_driver); -} - -module_init(at91ether_init) -module_exit(at91ether_exit) +module_platform_driver_probe(at91ether_driver, at91ether_probe); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); -- cgit From b543a8d813e979821d97a58b1509df4fdfcfa637 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 4 Mar 2013 16:43:18 +0000 Subject: net: macb: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 79039439bfdc..3a5d680ff8f9 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1737,18 +1737,7 @@ static struct platform_driver macb_driver = { }, }; -static int __init macb_init(void) -{ - return platform_driver_probe(&macb_driver, macb_probe); -} - -static void __exit macb_exit(void) -{ - platform_driver_unregister(&macb_driver); -} - -module_init(macb_init); -module_exit(macb_exit); +module_platform_driver_probe(macb_driver, macb_probe); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cadence MACB/GEM Ethernet driver"); -- cgit From fae4f3cf49ac9d91b83c705809d71fdeb0dc9284 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 4 Mar 2013 16:43:50 +0000 Subject: net: cs89x0: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Signed-off-by: David S. Miller --- drivers/net/ethernet/cirrus/cs89x0.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 138446957786..73c1c8c33dd1 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1978,18 +1978,6 @@ static struct platform_driver cs89x0_driver = { .remove = cs89x0_platform_remove, }; -static int __init cs89x0_init(void) -{ - return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe); -} - -module_init(cs89x0_init); - -static void __exit cs89x0_cleanup(void) -{ - platform_driver_unregister(&cs89x0_driver); -} - -module_exit(cs89x0_cleanup); +module_platform_driver_probe(cs89x0_driver, cs89x0_platform_probe); #endif /* CONFIG_CS89x0_PLATFORM */ -- cgit From 6fac41157252220678b210fcb13e2c3dad7a912a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Mar 2013 15:57:47 +0000 Subject: bnx2x: use the default NAPI weight BQL (Byte Queue Limits) proper operation needs TX completion being serviced in a timely fashion. bnx2x uses a non standard NAPI poll weight, and thats not fair to other napi poll handlers, and even not reasonable. Use the default value instead. Signed-off-by: Eric Dumazet Cc: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index e4605a965084..9577cceafac4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -492,7 +492,6 @@ enum bnx2x_tpa_mode_t { struct bnx2x_fastpath { struct bnx2x *bp; /* parent */ -#define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; union host_hc_status_block status_blk; /* chip independed shortcuts into sb structure */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index aee7671ff4c1..8d158d8240a2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -834,7 +834,7 @@ static inline void bnx2x_add_all_napi_cnic(struct bnx2x *bp) /* Add NAPI objects */ for_each_rx_queue_cnic(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, BNX2X_NAPI_WEIGHT); + bnx2x_poll, NAPI_POLL_WEIGHT); } static inline void bnx2x_add_all_napi(struct bnx2x *bp) @@ -844,7 +844,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) /* Add NAPI objects */ for_each_eth_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, BNX2X_NAPI_WEIGHT); + bnx2x_poll, NAPI_POLL_WEIGHT); } static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp) -- cgit From 9a412cdb1ab0ad984b76debfe562cb7a2c815371 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Mar 2013 11:53:09 +0800 Subject: mfd: wm5102: Map in additional FLL control registers Signed-off-by: Mark Brown --- drivers/mfd/wm5102-tables.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index a433f580aa4c..8a6ce8c12505 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c @@ -290,12 +290,14 @@ static const struct reg_default wm5102_reg_default[] = { { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */ { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */ + { 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */ { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ { 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */ { 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */ { 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */ + { 0x00000187, 0x0001 }, /* R391 - FLL1 Synchroniser 7 */ { 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */ { 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */ { 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */ @@ -306,12 +308,14 @@ static const struct reg_default wm5102_reg_default[] = { { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */ + { 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */ { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ { 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */ { 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */ { 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */ + { 0x000001A7, 0x0001 }, /* R423 - FLL2 Synchroniser 7 */ { 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */ { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */ { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ @@ -1051,12 +1055,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) case ARIZONA_FLL1_CONTROL_6: case ARIZONA_FLL1_LOOP_FILTER_TEST_1: case ARIZONA_FLL1_NCO_TEST_0: + case ARIZONA_FLL1_CONTROL_7: case ARIZONA_FLL1_SYNCHRONISER_1: case ARIZONA_FLL1_SYNCHRONISER_2: case ARIZONA_FLL1_SYNCHRONISER_3: case ARIZONA_FLL1_SYNCHRONISER_4: case ARIZONA_FLL1_SYNCHRONISER_5: case ARIZONA_FLL1_SYNCHRONISER_6: + case ARIZONA_FLL1_SYNCHRONISER_7: case ARIZONA_FLL1_SPREAD_SPECTRUM: case ARIZONA_FLL1_GPIO_CLOCK: case ARIZONA_FLL2_CONTROL_1: @@ -1067,12 +1073,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) case ARIZONA_FLL2_CONTROL_6: case ARIZONA_FLL2_LOOP_FILTER_TEST_1: case ARIZONA_FLL2_NCO_TEST_0: + case ARIZONA_FLL2_CONTROL_7: case ARIZONA_FLL2_SYNCHRONISER_1: case ARIZONA_FLL2_SYNCHRONISER_2: case ARIZONA_FLL2_SYNCHRONISER_3: case ARIZONA_FLL2_SYNCHRONISER_4: case ARIZONA_FLL2_SYNCHRONISER_5: case ARIZONA_FLL2_SYNCHRONISER_6: + case ARIZONA_FLL2_SYNCHRONISER_7: case ARIZONA_FLL2_SPREAD_SPECTRUM: case ARIZONA_FLL2_GPIO_CLOCK: case ARIZONA_MIC_CHARGE_PUMP_1: -- cgit From 77ee7c891a04c3d254711ddf1bde5d7381339fb3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Feb 2013 00:48:33 +0100 Subject: cfg80211: comprehensively check station changes The station change API isn't being checked properly before drivers are called, and as a result it is difficult to see what should be allowed and what not. In order to comprehensively check the API parameters parse everything first, and then have the driver call a function (cfg80211_check_station_change()) with the additionally information about the kind of station that is being changed; this allows the function to make better decisions than the old code could. While at it, also add a few checks, particularly in mesh and clarify the TDLS station lifetime in documentation. To be able to reduce a few checks, ignore any flag set bits when the mask isn't set, they shouldn't be applied then. Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 +- include/net/cfg80211.h | 48 ++++- include/uapi/linux/nl80211.h | 16 +- net/mac80211/cfg.c | 125 ++++++++----- net/wireless/nl80211.c | 288 +++++++++++++++++------------ 5 files changed, 311 insertions(+), 174 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 752ffc4f4166..28c413f861a2 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2990,13 +2990,15 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); + int err; if (vif->nw_type != AP_NETWORK) return -EOPNOTSUPP; - /* Use this only for authorizing/unauthorizing a station */ - if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) - return -EOPNOTSUPP; + err = cfg80211_check_station_change(wiphy, params, + CFG80211_STA_AP_MLME_CLIENT); + if (err) + return err; if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7ca321d2b599..ed2b08da3b93 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -677,6 +677,49 @@ struct station_parameters { u8 ext_capab_len; }; +/** + * enum cfg80211_station_type - the type of station being modified + * @CFG80211_STA_AP_CLIENT: client of an AP interface + * @CFG80211_STA_AP_MLME_CLIENT: client of an AP interface that has + * the AP MLME in the device + * @CFG80211_STA_AP_STA: AP station on managed interface + * @CFG80211_STA_IBSS: IBSS station + * @CFG80211_STA_TDLS_PEER_SETUP: TDLS peer on managed interface (dummy entry + * while TDLS setup is in progress, it moves out of this state when + * being marked authorized; use this only if TDLS with external setup is + * supported/used) + * @CFG80211_STA_TDLS_PEER_ACTIVE: TDLS peer on managed interface (active + * entry that is operating, has been marked authorized by userspace) + * @CFG80211_STA_MESH_PEER_NONSEC: peer on mesh interface (non-secured) + * @CFG80211_STA_MESH_PEER_SECURE: peer on mesh interface (secured) + */ +enum cfg80211_station_type { + CFG80211_STA_AP_CLIENT, + CFG80211_STA_AP_MLME_CLIENT, + CFG80211_STA_AP_STA, + CFG80211_STA_IBSS, + CFG80211_STA_TDLS_PEER_SETUP, + CFG80211_STA_TDLS_PEER_ACTIVE, + CFG80211_STA_MESH_PEER_NONSEC, + CFG80211_STA_MESH_PEER_SECURE, +}; + +/** + * cfg80211_check_station_change - validate parameter changes + * @wiphy: the wiphy this operates on + * @params: the new parameters for a station + * @statype: the type of station being modified + * + * Utility function for the @change_station driver method. Call this function + * with the appropriate station type looking up the station (and checking that + * it exists). It will verify whether the station change is acceptable, and if + * not will return an error code. Note that it may modify the parameters for + * backward compatibility reasons, so don't use them before calling this. + */ +int cfg80211_check_station_change(struct wiphy *wiphy, + struct station_parameters *params, + enum cfg80211_station_type statype); + /** * enum station_info_flags - station information flags * @@ -1770,9 +1813,8 @@ struct cfg80211_gtk_rekey_data { * @change_station: Modify a given station. Note that flags changes are not much * validated in cfg80211, in particular the auth/assoc/authorized flags * might come to the driver in invalid combinations -- make sure to check - * them, also against the existing state! Also, supported_rates changes are - * not checked in station mode -- drivers need to reject (or ignore) them - * for anything but TDLS peers. + * them, also against the existing state! Drivers must call + * cfg80211_check_station_change() to validate the information. * @get_station: get station information for the station identified by @mac * @dump_station: dump station callback -- resume dump at index @idx * diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 7dcc69f73d2c..523ed3d65b41 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -36,7 +36,21 @@ * The station is still assumed to belong to the AP interface it was added * to. * - * TODO: need more info? + * Station handling varies per interface type and depending on the driver's + * capabilities. + * + * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS + * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows: + * - a setup station entry is added, not yet authorized, without any rate + * or capability information, this just exists to avoid race conditions + * - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid + * to add rate and capability information to the station and at the same + * time mark it authorized. + * - %NL80211_TDLS_ENABLE_LINK is then used + * - after this, the only valid operation is to remove it by tearing down + * the TDLS link (%NL80211_TDLS_DISABLE_LINK) + * + * TODO: need more info for other interface types */ /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ca28405d5f65..c115f82c037c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1177,6 +1177,18 @@ static int sta_apply_parameters(struct ieee80211_local *local, mask |= BIT(NL80211_STA_FLAG_ASSOCIATED); if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) set |= BIT(NL80211_STA_FLAG_ASSOCIATED); + } else if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { + /* + * TDLS -- everything follows authorized, but + * only becoming authorized is possible, not + * going back + */ + if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) { + set |= BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_ASSOCIATED); + mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_ASSOCIATED); + } } ret = sta_apply_auth_flags(local, sta, mask, set); @@ -1261,9 +1273,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH u32 changed = 0; - if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED && - (params->sta_modify_mask & - STATION_PARAM_APPLY_PLINK_STATE)) { + + if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) { switch (params->plink_state) { case NL80211_PLINK_ESTAB: if (sta->plink_state != NL80211_PLINK_ESTAB) @@ -1294,21 +1305,18 @@ static int sta_apply_parameters(struct ieee80211_local *local, /* nothing */ break; } - } else if (params->sta_modify_mask & - STATION_PARAM_APPLY_PLINK_STATE) { - return -EINVAL; - } else { - switch (params->plink_action) { - case NL80211_PLINK_ACTION_NO_ACTION: - /* nothing */ - break; - case NL80211_PLINK_ACTION_OPEN: - changed |= mesh_plink_open(sta); - break; - case NL80211_PLINK_ACTION_BLOCK: - changed |= mesh_plink_block(sta); - break; - } + } + + switch (params->plink_action) { + case NL80211_PLINK_ACTION_NO_ACTION: + /* nothing */ + break; + case NL80211_PLINK_ACTION_OPEN: + changed |= mesh_plink_open(sta); + break; + case NL80211_PLINK_ACTION_BLOCK: + changed |= mesh_plink_block(sta); + break; } if (params->local_pm) @@ -1354,8 +1362,10 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, * defaults -- if userspace wants something else we'll * change it accordingly in sta_apply_parameters() */ - sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); - sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); + if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) { + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); + sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); + } err = sta_apply_parameters(local, sta, params); if (err) { @@ -1364,8 +1374,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, } /* - * for TDLS, rate control should be initialized only when supported - * rates are known. + * for TDLS, rate control should be initialized only when + * rates are known and station is marked authorized */ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) rate_control_rate_init(sta); @@ -1402,50 +1412,67 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_change_station(struct wiphy *wiphy, - struct net_device *dev, - u8 *mac, + struct net_device *dev, u8 *mac, struct station_parameters *params) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = wiphy_priv(wiphy); struct sta_info *sta; struct ieee80211_sub_if_data *vlansdata; + enum cfg80211_station_type statype; int err; mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, mac); if (!sta) { - mutex_unlock(&local->sta_mtx); - return -ENOENT; + err = -ENOENT; + goto out_err; } - /* in station mode, some updates are only valid with TDLS */ - if (sdata->vif.type == NL80211_IFTYPE_STATION && - (params->supported_rates || params->ht_capa || params->vht_capa || - params->sta_modify_mask || - (params->sta_flags_mask & BIT(NL80211_STA_FLAG_WME))) && - !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { - mutex_unlock(&local->sta_mtx); - return -EINVAL; + switch (sdata->vif.type) { + case NL80211_IFTYPE_MESH_POINT: + if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) + statype = CFG80211_STA_MESH_PEER_SECURE; + else + statype = CFG80211_STA_MESH_PEER_NONSEC; + break; + case NL80211_IFTYPE_ADHOC: + statype = CFG80211_STA_IBSS; + break; + case NL80211_IFTYPE_STATION: + if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { + statype = CFG80211_STA_AP_STA; + break; + } + if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) + statype = CFG80211_STA_TDLS_PEER_ACTIVE; + else + statype = CFG80211_STA_TDLS_PEER_SETUP; + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + statype = CFG80211_STA_AP_CLIENT; + break; + default: + err = -EOPNOTSUPP; + goto out_err; } + err = cfg80211_check_station_change(wiphy, params, statype); + if (err) + goto out_err; + if (params->vlan && params->vlan != sta->sdata->dev) { bool prev_4addr = false; bool new_4addr = false; vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); - if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN && - vlansdata->vif.type != NL80211_IFTYPE_AP) { - mutex_unlock(&local->sta_mtx); - return -EINVAL; - } - if (params->vlan->ieee80211_ptr->use_4addr) { if (vlansdata->u.vlan.sta) { - mutex_unlock(&local->sta_mtx); - return -EBUSY; + err = -EBUSY; + goto out_err; } rcu_assign_pointer(vlansdata->u.vlan.sta, sta); @@ -1472,12 +1499,12 @@ static int ieee80211_change_station(struct wiphy *wiphy, } err = sta_apply_parameters(local, sta, params); - if (err) { - mutex_unlock(&local->sta_mtx); - return err; - } + if (err) + goto out_err; - if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates) + /* When peer becomes authorized, init rate control as well */ + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && + test_sta_flag(sta, WLAN_STA_AUTHORIZED)) rate_control_rate_init(sta); mutex_unlock(&local->sta_mtx); @@ -1487,7 +1514,11 @@ static int ieee80211_change_station(struct wiphy *wiphy, ieee80211_recalc_ps(local, -1); ieee80211_recalc_ps_vif(sdata); } + return 0; +out_err: + mutex_unlock(&local->sta_mtx); + return err; } #ifdef CONFIG_MAC80211_MESH diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9e7c10420da8..83151a50e5ad 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2967,6 +2967,7 @@ static int parse_station_flags(struct genl_info *info, sta_flags = nla_data(nla); params->sta_flags_mask = sta_flags->mask; params->sta_flags_set = sta_flags->set; + params->sta_flags_set &= params->sta_flags_mask; if ((params->sta_flags_mask | params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID)) return -EINVAL; @@ -3320,6 +3321,136 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) return genlmsg_reply(msg, info); } +int cfg80211_check_station_change(struct wiphy *wiphy, + struct station_parameters *params, + enum cfg80211_station_type statype) +{ + if (params->listen_interval != -1) + return -EINVAL; + if (params->aid) + return -EINVAL; + + /* When you run into this, adjust the code below for the new flag */ + BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); + + switch (statype) { + case CFG80211_STA_MESH_PEER_NONSEC: + case CFG80211_STA_MESH_PEER_SECURE: + /* + * No ignoring the TDLS flag here -- the userspace mesh + * code doesn't have the bug of including TDLS in the + * mask everywhere. + */ + if (params->sta_flags_mask & + ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_MFP) | + BIT(NL80211_STA_FLAG_AUTHORIZED))) + return -EINVAL; + break; + case CFG80211_STA_TDLS_PEER_SETUP: + case CFG80211_STA_TDLS_PEER_ACTIVE: + if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) + return -EINVAL; + /* ignore since it can't change */ + params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); + break; + default: + /* disallow mesh-specific things */ + if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION) + return -EINVAL; + if (params->local_pm) + return -EINVAL; + if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) + return -EINVAL; + } + + if (statype != CFG80211_STA_TDLS_PEER_SETUP && + statype != CFG80211_STA_TDLS_PEER_ACTIVE) { + /* TDLS can't be set, ... */ + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + return -EINVAL; + /* + * ... but don't bother the driver with it. This works around + * a hostapd/wpa_supplicant issue -- it always includes the + * TLDS_PEER flag in the mask even for AP mode. + */ + params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); + } + + if (statype != CFG80211_STA_TDLS_PEER_SETUP) { + /* reject other things that can't change */ + if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) + return -EINVAL; + if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY) + return -EINVAL; + if (params->supported_rates) + return -EINVAL; + if (params->ext_capab || params->ht_capa || params->vht_capa) + return -EINVAL; + } + + if (statype != CFG80211_STA_AP_CLIENT) { + if (params->vlan) + return -EINVAL; + } + + switch (statype) { + case CFG80211_STA_AP_MLME_CLIENT: + /* Use this only for authorizing/unauthorizing a station */ + if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) + return -EOPNOTSUPP; + break; + case CFG80211_STA_AP_CLIENT: + /* accept only the listed bits */ + if (params->sta_flags_mask & + ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | + BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_ASSOCIATED) | + BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | + BIT(NL80211_STA_FLAG_WME) | + BIT(NL80211_STA_FLAG_MFP))) + return -EINVAL; + + /* but authenticated/associated only if driver handles it */ + if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) && + params->sta_flags_mask & + (BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_ASSOCIATED))) + return -EINVAL; + break; + case CFG80211_STA_IBSS: + case CFG80211_STA_AP_STA: + /* reject any changes other than AUTHORIZED */ + if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) + return -EINVAL; + break; + case CFG80211_STA_TDLS_PEER_SETUP: + /* reject any changes other than AUTHORIZED or WME */ + if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | + BIT(NL80211_STA_FLAG_WME))) + return -EINVAL; + /* force (at least) rates when authorizing */ + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) && + !params->supported_rates) + return -EINVAL; + break; + case CFG80211_STA_TDLS_PEER_ACTIVE: + /* reject any changes */ + return -EINVAL; + case CFG80211_STA_MESH_PEER_NONSEC: + if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) + return -EINVAL; + break; + case CFG80211_STA_MESH_PEER_SECURE: + if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION) + return -EINVAL; + break; + } + + return 0; +} +EXPORT_SYMBOL(cfg80211_check_station_change); + /* * Get vlan interface making sure it is running and on the right wiphy. */ @@ -3342,6 +3473,13 @@ static struct net_device *get_vlan(struct genl_info *info, goto error; } + if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { + ret = -EINVAL; + goto error; + } + if (!netif_running(v)) { ret = -ENETDOWN; goto error; @@ -3410,15 +3548,18 @@ static int nl80211_set_station_tdls(struct genl_info *info, static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; - int err; struct net_device *dev = info->user_ptr[1]; struct station_parameters params; - u8 *mac_addr = NULL; + u8 *mac_addr; + int err; memset(¶ms, 0, sizeof(params)); params.listen_interval = -1; + if (!rdev->ops->change_station) + return -EOPNOTSUPP; + if (info->attrs[NL80211_ATTR_STA_AID]) return -EINVAL; @@ -3450,9 +3591,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) return -EINVAL; - if (!rdev->ops->change_station) - return -EOPNOTSUPP; - if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) return -EINVAL; @@ -3482,133 +3620,33 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) params.local_pm = pm; } + /* Include parameters for TDLS peer (will check later) */ + err = nl80211_set_station_tdls(info, ¶ms); + if (err) + return err; + + params.vlan = get_vlan(info, rdev); + if (IS_ERR(params.vlan)) + return PTR_ERR(params.vlan); + switch (dev->ieee80211_ptr->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_GO: - /* disallow mesh-specific things */ - if (params.plink_action) - return -EINVAL; - if (params.local_pm) - return -EINVAL; - if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - return -EINVAL; - - /* TDLS can't be set, ... */ - if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) - return -EINVAL; - /* - * ... but don't bother the driver with it. This works around - * a hostapd/wpa_supplicant issue -- it always includes the - * TLDS_PEER flag in the mask even for AP mode. - */ - params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); - - /* accept only the listed bits */ - if (params.sta_flags_mask & - ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | - BIT(NL80211_STA_FLAG_AUTHENTICATED) | - BIT(NL80211_STA_FLAG_ASSOCIATED) | - BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | - BIT(NL80211_STA_FLAG_WME) | - BIT(NL80211_STA_FLAG_MFP))) - return -EINVAL; - - /* but authenticated/associated only if driver handles it */ - if (!(rdev->wiphy.features & - NL80211_FEATURE_FULL_AP_CLIENT_STATE) && - params.sta_flags_mask & - (BIT(NL80211_STA_FLAG_AUTHENTICATED) | - BIT(NL80211_STA_FLAG_ASSOCIATED))) - return -EINVAL; - - /* reject other things that can't change */ - if (params.supported_rates) - return -EINVAL; - if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) - return -EINVAL; - if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) - return -EINVAL; - if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || - info->attrs[NL80211_ATTR_VHT_CAPABILITY]) - return -EINVAL; - - /* must be last in here for error handling */ - params.vlan = get_vlan(info, rdev); - if (IS_ERR(params.vlan)) - return PTR_ERR(params.vlan); - break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: - /* - * Don't allow userspace to change the TDLS_PEER flag, - * but silently ignore attempts to change it since we - * don't have state here to verify that it doesn't try - * to change the flag. - */ - params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); - /* Include parameters for TDLS peer (driver will check) */ - err = nl80211_set_station_tdls(info, ¶ms); - if (err) - return err; - /* disallow things sta doesn't support */ - if (params.plink_action) - return -EINVAL; - if (params.local_pm) - return -EINVAL; - if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - return -EINVAL; - /* reject any changes other than AUTHORIZED or WME (for TDLS) */ - if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | - BIT(NL80211_STA_FLAG_WME))) - return -EINVAL; - break; case NL80211_IFTYPE_ADHOC: - /* disallow things sta doesn't support */ - if (params.plink_action) - return -EINVAL; - if (params.local_pm) - return -EINVAL; - if (params.sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE) - return -EINVAL; - if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || - info->attrs[NL80211_ATTR_VHT_CAPABILITY]) - return -EINVAL; - /* reject any changes other than AUTHORIZED */ - if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) - return -EINVAL; - break; case NL80211_IFTYPE_MESH_POINT: - /* disallow things mesh doesn't support */ - if (params.vlan) - return -EINVAL; - if (params.supported_rates) - return -EINVAL; - if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) - return -EINVAL; - if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) - return -EINVAL; - if (info->attrs[NL80211_ATTR_HT_CAPABILITY] || - info->attrs[NL80211_ATTR_VHT_CAPABILITY]) - return -EINVAL; - /* - * No special handling for TDLS here -- the userspace - * mesh code doesn't have this bug. - */ - if (params.sta_flags_mask & - ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | - BIT(NL80211_STA_FLAG_MFP) | - BIT(NL80211_STA_FLAG_AUTHORIZED))) - return -EINVAL; break; default: - return -EOPNOTSUPP; + err = -EOPNOTSUPP; + goto out_put_vlan; } - /* be aware of params.vlan when changing code here */ - + /* driver will call cfg80211_check_station_change() */ err = rdev_change_station(rdev, dev, mac_addr, ¶ms); + out_put_vlan: if (params.vlan) dev_put(params.vlan); @@ -3687,6 +3725,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) return -EINVAL; + /* When you run into this, adjust the code below for the new flag */ + BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); + switch (dev->ieee80211_ptr->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: @@ -3730,8 +3771,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) /* ignore uAPSD data */ params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD; - /* associated is disallowed */ - if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) + /* these are disallowed */ + if (params.sta_flags_mask & + (BIT(NL80211_STA_FLAG_ASSOCIATED) | + BIT(NL80211_STA_FLAG_AUTHENTICATED))) return -EINVAL; /* Only TDLS peers can be added */ if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) @@ -3742,6 +3785,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) /* ... with external setup is supported */ if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)) return -EOPNOTSUPP; + /* + * Older wpa_supplicant versions always mark the TDLS peer + * as authorized, but it shouldn't yet be. + */ + params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED); break; default: return -EOPNOTSUPP; -- cgit From 9a886586c82aa02cb49f8c85e961595716884545 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 15 Feb 2013 19:25:00 +0100 Subject: wireless: move sequence number arithmetic to ieee80211.h Move the sequence number arithmetic code from mac80211 to ieee80211.h so others can use it. Also rename the functions from _seq to _sn, they operate on the sequence number, not the sequence_control field. Also move macros to convert the sequence control to/from the sequence number value from various drivers. Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlegacy/3945.h | 4 --- drivers/net/wireless/iwlegacy/4965-mac.c | 13 ++++---- drivers/net/wireless/iwlegacy/common.h | 4 --- drivers/net/wireless/iwlwifi/dvm/tx.c | 11 ++++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 3 -- drivers/net/wireless/iwlwifi/mvm/sta.c | 4 +-- drivers/net/wireless/iwlwifi/mvm/tx.c | 2 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 3 -- include/linux/ieee80211.h | 28 +++++++++++++++++ net/mac80211/rx.c | 53 +++++++++++++------------------- 11 files changed, 66 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 1d45075e0d5b..9a8703def0ba 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -150,10 +150,6 @@ struct il3945_frame { struct list_head list; }; -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 7941eb3a0166..c092fcbbe965 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2258,7 +2258,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, spin_lock_irqsave(&il->sta_lock, flags); tid_data = &il->stations[sta_id].tid[tid]; - *ssn = SEQ_TO_SN(tid_data->seq_number); + *ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; il_set_swq_id(&il->txq[txq_id], il4965_get_ac_from_tid(tid), txq_id); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -2408,7 +2408,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) /* aggregated HW queue */ if (txq_id == tid_data->agg.txq_id && q->read_ptr == q->write_ptr) { - u16 ssn = SEQ_TO_SN(tid_data->seq_number); + u16 ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); int tx_fifo = il4965_get_fifo_from_tid(tid); D_HT("HW queue empty: continue DELBA flow\n"); il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo); @@ -2627,7 +2627,8 @@ il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr) static inline u32 il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp) { - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; + return le32_to_cpup(&tx_resp->u.status + + tx_resp->frame_count) & IEEE80211_MAX_SN; } static inline u32 @@ -2717,15 +2718,15 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, hdr = (struct ieee80211_hdr *) skb->data; sc = le16_to_cpu(hdr->seq_ctrl); - if (idx != (SEQ_TO_SN(sc) & 0xff)) { + if (idx != (IEEE80211_SEQ_TO_SN(sc) & 0xff)) { IL_ERR("BUG_ON idx doesn't match seq control" " idx=%d, seq_idx=%d, seq=%d\n", idx, - SEQ_TO_SN(sc), hdr->seq_ctrl); + IEEE80211_SEQ_TO_SN(sc), hdr->seq_ctrl); return -1; } D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx, - SEQ_TO_SN(sc)); + IEEE80211_SEQ_TO_SN(sc)); sh = idx - start; if (sh > 64) { diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 96f2025d936e..73bd3ef316c8 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -541,10 +541,6 @@ struct il_frame { struct list_head list; }; -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - enum { CMD_SYNC = 0, CMD_SIZE_NORMAL = 0, diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 6aec2df3bb27..d499a0366fa6 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -418,7 +418,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, " Tx flags = 0x%08x, agg.state = %d", info->flags, tid_data->agg.state); IWL_ERR(priv, "sta_id = %d, tid = %d seq_num = %d", - sta_id, tid, SEQ_TO_SN(tid_data->seq_number)); + sta_id, tid, + IEEE80211_SEQ_TO_SN(tid_data->seq_number)); goto drop_unlock_sta; } @@ -569,7 +570,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, return 0; } - tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); + tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); /* There are still packets for this RA / TID in the HW */ if (!test_bit(txq_id, priv->agg_q_alloc)) { @@ -651,7 +652,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; - tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); + tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; *ssn = tid_data->agg.ssn; @@ -911,7 +912,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp) { return le32_to_cpup((__le32 *)&tx_resp->status + - tx_resp->frame_count) & MAX_SN; + tx_resp->frame_count) & IEEE80211_MAX_SN; } static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, @@ -1148,7 +1149,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, if (tx_resp->frame_count == 1) { u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); - next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); + next_reclaimed = IEEE80211_SEQ_TO_SN(next_reclaimed + 0x10); if (is_agg) { /* If this is an aggregation queue, we can rely on the diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 8c7bec6b9a0b..00bdc5b00af3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -114,9 +114,6 @@ * completely agnostic to these differences. * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode), */ -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) #define SEQ_TO_INDEX(s) ((s) & 0xff) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 861a7f9f8e7f..52aecf20d0df 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -686,7 +686,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, spin_lock_bh(&mvmsta->lock); tid_data = &mvmsta->tid_data[tid]; - tid_data->ssn = SEQ_TO_SN(tid_data->seq_number); + tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); tid_data->txq_id = txq_id; *ssn = tid_data->ssn; @@ -779,7 +779,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, switch (tid_data->state) { case IWL_AGG_ON: - tid_data->ssn = SEQ_TO_SN(tid_data->seq_number); + tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number); IWL_DEBUG_TX_QUEUES(mvm, "ssn = %d, next_recl = %d\n", diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 6b67ce3f679c..56df249b215e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -641,7 +641,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, next_reclaimed = ssn; } else { /* The next packet to be reclaimed is the one after this one */ - next_reclaimed = SEQ_TO_SN(seq_ctl + 0x10); + next_reclaimed = IEEE80211_SEQ_TO_SN(seq_ctl + 0x10); } IWL_DEBUG_TX_REPLY(mvm, diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8e9e3212fe78..ad7441dfa6fb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1581,7 +1581,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, * Check here that the packets are in the right place on the ring. */ #ifdef CONFIG_IWLWIFI_DEBUG - wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && ((wifi_seq & 0xff) != q->write_ptr), "Q: %d WiFi Seq %d tfdNum %d", diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index f13258a8d995..c3eff32acf6c 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -2127,9 +2127,6 @@ value to host byte ordering.*/ #define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) #define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) #define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) #define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ #define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 7e24fe0cfbcd..a0c550fb65a6 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -113,6 +113,34 @@ #define IEEE80211_CTL_EXT_SSW_FBACK 0x9000 #define IEEE80211_CTL_EXT_SSW_ACK 0xa000 + +#define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4) +#define IEEE80211_MAX_SN IEEE80211_SN_MASK +#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1) + +static inline int ieee80211_sn_less(u16 sn1, u16 sn2) +{ + return ((sn1 - sn2) & IEEE80211_SN_MASK) > (IEEE80211_SN_MODULO >> 1); +} + +static inline u16 ieee80211_sn_add(u16 sn1, u16 sn2) +{ + return (sn1 + sn2) & IEEE80211_SN_MASK; +} + +static inline u16 ieee80211_sn_inc(u16 sn) +{ + return ieee80211_sn_add(sn, 1); +} + +static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2) +{ + return (sn1 - sn2) & IEEE80211_SN_MASK; +} + +#define IEEE80211_SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define IEEE80211_SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) + /* miscellaneous IEEE 802.11 constants */ #define IEEE80211_MAX_FRAG_THRESHOLD 2352 #define IEEE80211_MAX_RTS_THRESHOLD 2353 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index acf006f2d61a..1f940e2b6f27 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -648,24 +648,6 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) return RX_CONTINUE; } -#define SEQ_MODULO 0x1000 -#define SEQ_MASK 0xfff - -static inline int seq_less(u16 sq1, u16 sq2) -{ - return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); -} - -static inline u16 seq_inc(u16 sq) -{ - return (sq + 1) & SEQ_MASK; -} - -static inline u16 seq_sub(u16 sq1, u16 sq2) -{ - return (sq1 - sq2) & SEQ_MASK; -} - static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, int index, @@ -687,7 +669,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, __skb_queue_tail(frames, skb); no_frame: - tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); + tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num); } static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, @@ -699,8 +681,9 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata lockdep_assert_held(&tid_agg_rx->reorder_lock); - while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) { + index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, frames); @@ -727,8 +710,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&tid_agg_rx->reorder_lock); /* release the buffer until next missing frame */ - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % - tid_agg_rx->buf_size; + index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; if (!tid_agg_rx->reorder_buf[index] && tid_agg_rx->stored_mpdu_num) { /* @@ -756,19 +739,22 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, * Increment the head seq# also for the skipped slots. */ tid_agg_rx->head_seq_num = - (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; + (tid_agg_rx->head_seq_num + + skipped) & IEEE80211_SN_MASK; skipped = 0; } } else while (tid_agg_rx->reorder_buf[index]) { ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, frames); - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; } if (tid_agg_rx->stored_mpdu_num) { - j = index = seq_sub(tid_agg_rx->head_seq_num, - tid_agg_rx->ssn) % tid_agg_rx->buf_size; + j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % + tid_agg_rx->buf_size; for (; j != (index - 1) % tid_agg_rx->buf_size; j = (j + 1) % tid_agg_rx->buf_size) { @@ -809,7 +795,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata head_seq_num = tid_agg_rx->head_seq_num; /* frame with out of date sequence number */ - if (seq_less(mpdu_seq_num, head_seq_num)) { + if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) { dev_kfree_skb(skb); goto out; } @@ -818,8 +804,9 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata * If frame the sequence number exceeds our buffering window * size release some previous frames to make room for this one. */ - if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { - head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); + if (!ieee80211_sn_less(mpdu_seq_num, head_seq_num + buf_size)) { + head_seq_num = ieee80211_sn_inc( + ieee80211_sn_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */ ieee80211_release_reorder_frames(sdata, tid_agg_rx, head_seq_num, frames); @@ -827,7 +814,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata /* Now the new frame is always in the range of the reordering buffer */ - index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; + index = ieee80211_sn_sub(mpdu_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; /* check if we already stored this frame */ if (tid_agg_rx->reorder_buf[index]) { @@ -843,7 +831,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata */ if (mpdu_seq_num == tid_agg_rx->head_seq_num && tid_agg_rx->stored_mpdu_num == 0) { - tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); + tid_agg_rx->head_seq_num = + ieee80211_sn_inc(tid_agg_rx->head_seq_num); ret = false; goto out; } -- cgit From d339d5ca8eee34f3c70386cf2545edc53e546a13 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Tue, 12 Feb 2013 09:34:13 +0200 Subject: mac80211: Allow drivers to differentiate between ROC types Some devices can handle remain on channel requests differently based on the request type/priority. Add support to differentiate between different ROC types, i.e., indicate that the ROC is required for sending managment frames. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 7 ++++--- drivers/net/wireless/mac80211_hwsim.c | 3 ++- drivers/net/wireless/ti/wlcore/main.c | 3 ++- include/net/mac80211.h | 21 ++++++++++++++++++++- net/mac80211/cfg.c | 21 +++++++++++++++------ net/mac80211/driver-ops.h | 7 ++++--- net/mac80211/ieee80211_i.h | 1 + net/mac80211/offchannel.c | 2 +- net/mac80211/trace.h | 11 +++++++---- 10 files changed, 58 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 323e4a33fcac..c7cd2dffa5cd 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1137,7 +1137,8 @@ done: static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *channel, - int duration) + int duration, + enum ieee80211_roc_type type) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e8264e11b12d..23460f4a4c75 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1081,7 +1081,8 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw, static int iwl_mvm_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *channel, - int duration) + int duration, + enum ieee80211_roc_type type) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct cfg80211_chan_def chandef; @@ -1092,8 +1093,8 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, return -EINVAL; } - IWL_DEBUG_MAC80211(mvm, "enter (%d, %d)\n", channel->hw_value, - duration); + IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, + duration, type); mutex_lock(&mvm->mutex); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index cffdf4fbf161..7490c4fc7177 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1535,7 +1535,8 @@ static void hw_roc_done(struct work_struct *work) static int mac80211_hwsim_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *chan, - int duration) + int duration, + enum ieee80211_roc_type type) { struct mac80211_hwsim_data *hwsim = hw->priv; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 2c2ff3e1f849..d7e306333f6c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4956,7 +4956,8 @@ static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop) static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *chan, - int duration) + int duration, + enum ieee80211_roc_type type) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271 *wl = hw->priv; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f7eba1300d82..9b0d342c0675 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2134,6 +2134,24 @@ enum ieee80211_rate_control_changed { IEEE80211_RC_NSS_CHANGED = BIT(3), }; +/** + * enum ieee80211_roc_type - remain on channel type + * + * With the support for multi channel contexts and multi channel operations, + * remain on channel operations might be limited/deferred/aborted by other + * flows/operations which have higher priority (and vise versa). + * Specifying the ROC type can be used by devices to prioritize the ROC + * operations compared to other operations/flows. + * + * @IEEE80211_ROC_TYPE_NORMAL: There are no special requirements for this ROC. + * @IEEE80211_ROC_TYPE_MGMT_TX: The remain on channel request is required + * for sending managment frames offchannel. + */ +enum ieee80211_roc_type { + IEEE80211_ROC_TYPE_NORMAL = 0, + IEEE80211_ROC_TYPE_MGMT_TX, +}; + /** * struct ieee80211_ops - callbacks from mac80211 to the driver * @@ -2687,7 +2705,8 @@ struct ieee80211_ops { int (*remain_on_channel)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *chan, - int duration); + int duration, + enum ieee80211_roc_type type); int (*cancel_remain_on_channel)(struct ieee80211_hw *hw); int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); void (*get_ringparam)(struct ieee80211_hw *hw, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c115f82c037c..f9cbdc29946d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2410,7 +2410,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_channel *channel, unsigned int duration, u64 *cookie, - struct sk_buff *txskb) + struct sk_buff *txskb, + enum ieee80211_roc_type type) { struct ieee80211_roc_work *roc, *tmp; bool queued = false; @@ -2429,6 +2430,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, roc->duration = duration; roc->req_duration = duration; roc->frame = txskb; + roc->type = type; roc->mgmt_tx_cookie = (unsigned long)txskb; roc->sdata = sdata; INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); @@ -2459,7 +2461,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, if (!duration) duration = 10; - ret = drv_remain_on_channel(local, sdata, channel, duration); + ret = drv_remain_on_channel(local, sdata, channel, duration, type); if (ret) { kfree(roc); return ret; @@ -2478,10 +2480,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, * * If it hasn't started yet, just increase the duration * and add the new one to the list of dependents. + * If the type of the new ROC has higher priority, modify the + * type of the previous one to match that of the new one. */ if (!tmp->started) { list_add_tail(&roc->list, &tmp->dependents); tmp->duration = max(tmp->duration, roc->duration); + tmp->type = max(tmp->type, roc->type); queued = true; break; } @@ -2493,16 +2498,18 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, /* * In the offloaded ROC case, if it hasn't begun, add * this new one to the dependent list to be handled - * when the the master one begins. If it has begun, + * when the master one begins. If it has begun, * check that there's still a minimum time left and * if so, start this one, transmitting the frame, but - * add it to the list directly after this one with a + * add it to the list directly after this one with * a reduced time so we'll ask the driver to execute * it right after finishing the previous one, in the * hope that it'll also be executed right afterwards, * effectively extending the old one. * If there's no minimum time left, just add it to the * normal list. + * TODO: the ROC type is ignored here, assuming that it + * is better to immediately use the current ROC. */ if (!tmp->hw_begun) { list_add_tail(&roc->list, &tmp->dependents); @@ -2596,7 +2603,8 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy, mutex_lock(&local->mtx); ret = ieee80211_start_roc_work(local, sdata, chan, - duration, cookie, NULL); + duration, cookie, NULL, + IEEE80211_ROC_TYPE_NORMAL); mutex_unlock(&local->mtx); return ret; @@ -2829,7 +2837,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, /* This will handle all kinds of coalescing and immediate TX */ ret = ieee80211_start_roc_work(local, sdata, chan, - wait, cookie, skb); + wait, cookie, skb, + IEEE80211_ROC_TYPE_MGMT_TX); if (ret) kfree_skb(skb); out_unlock: diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ee56d0779d8b..832acea4a5cb 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -787,15 +787,16 @@ static inline int drv_get_antenna(struct ieee80211_local *local, static inline int drv_remain_on_channel(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_channel *chan, - unsigned int duration) + unsigned int duration, + enum ieee80211_roc_type type) { int ret; might_sleep(); - trace_drv_remain_on_channel(local, sdata, chan, duration); + trace_drv_remain_on_channel(local, sdata, chan, duration, type); ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, - chan, duration); + chan, duration, type); trace_drv_return_int(local, ret); return ret; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8da53a067306..2518f0429b87 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -315,6 +315,7 @@ struct ieee80211_roc_work { u32 duration, req_duration; struct sk_buff *frame; u64 cookie, mgmt_tx_cookie; + enum ieee80211_roc_type type; }; /* flags used in struct ieee80211_if_managed.flags */ diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index cc79b4a2e821..db547fceaeb9 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -277,7 +277,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) duration = 10; ret = drv_remain_on_channel(local, roc->sdata, roc->chan, - duration); + duration, roc->type); roc->started = true; diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 3d7cd2a0582f..e7db2b804e0c 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1042,15 +1042,17 @@ TRACE_EVENT(drv_remain_on_channel, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_channel *chan, - unsigned int duration), + unsigned int duration, + enum ieee80211_roc_type type), - TP_ARGS(local, sdata, chan, duration), + TP_ARGS(local, sdata, chan, duration, type), TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY __field(int, center_freq) __field(unsigned int, duration) + __field(u32, type) ), TP_fast_assign( @@ -1058,12 +1060,13 @@ TRACE_EVENT(drv_remain_on_channel, VIF_ASSIGN; __entry->center_freq = chan->center_freq; __entry->duration = duration; + __entry->type = type; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms", + LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms type=%d", LOCAL_PR_ARG, VIF_PR_ARG, - __entry->center_freq, __entry->duration + __entry->center_freq, __entry->duration, __entry->type ) ); -- cgit From 410dc5aa5906ed49e2733b451a5287884e8a16dc Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 18 Feb 2013 09:22:28 +0200 Subject: iwlwifi: a few fixes in license 7000.c was released as GPL only by mistake: it should be dual licensed - GPL / BSD. The file that contains the license in the kernel is COPYING and not LICENSE.GPL. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/agn.h | 2 +- drivers/net/wireless/iwlwifi/dvm/calib.c | 2 +- drivers/net/wireless/iwlwifi/dvm/calib.h | 2 +- drivers/net/wireless/iwlwifi/dvm/commands.h | 2 +- drivers/net/wireless/iwlwifi/dvm/debugfs.c | 2 +- drivers/net/wireless/iwlwifi/dvm/lib.c | 2 +- drivers/net/wireless/iwlwifi/dvm/scan.c | 2 +- drivers/net/wireless/iwlwifi/dvm/testmode.c | 2 +- drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +- drivers/net/wireless/iwlwifi/dvm/ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/iwlwifi/iwl-csr.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debug.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 2 +- drivers/net/wireless/iwlwifi/iwl-notif-wait.h | 2 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 2 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | 2 +- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 2 +- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 2 +- drivers/net/wireless/iwlwifi/iwl-phy-db.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 2 +- drivers/net/wireless/iwlwifi/iwl-test.c | 2 +- drivers/net/wireless/iwlwifi/iwl-test.h | 2 +- drivers/net/wireless/iwlwifi/iwl-testmode.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 +- drivers/net/wireless/iwlwifi/mvm/binding.c | 2 +- drivers/net/wireless/iwlwifi/mvm/d3.c | 2 +- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/iwlwifi/mvm/led.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 2 +- drivers/net/wireless/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/power.c | 2 +- drivers/net/wireless/iwlwifi/mvm/quota.c | 2 +- drivers/net/wireless/iwlwifi/mvm/rx.c | 2 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 2 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 2 +- drivers/net/wireless/iwlwifi/mvm/sta.h | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.c | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.h | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 2 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 2 +- drivers/net/wireless/iwlwifi/pcie/7000.c | 61 ++++++++++++++++++++----- drivers/net/wireless/iwlwifi/pcie/cfg.h | 2 +- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- 69 files changed, 117 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 41ec27cb6efe..019d433900ef 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 6468de8634b0..d6c4cf2ad7c5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index 65e920cab2b7..cfddde194940 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 84e2c0fcfef6..22100c2a56ea 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 20806cae11b7..9d3b7e3165f4 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 86ea5f4c3939..cddf77c36b36 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 3a4aa5239c45..d69b55866714 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index dc6f965a123a..b89b9d9b9969 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 6aec2df3bb27..303403b86b75 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 736fe9bb140e..166019afc2d0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index e9975c54c276..6d73f943cefa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 743b48343358..8ba293b2396b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index df3463a38704..20e845d4da04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 87535a67de76..88df574e33de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index fbfd2d137117..8620de406f64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 594a5c71b272..4c96472ac3ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 034f2ff4f43d..28c33512aed5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index 683fe6a8c58f..37f115390b19 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index ef4806f27cf8..92e7245ced8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h index b2588c5cbf93..8e941f8bd7d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index f5592fb3b1ed..484d318245fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 90873eca35f7..8b6c6fd95ed0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index b545178e46e3..54848d59df0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 2c2a729092f5..a2cefe2c3e1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index c3affbc62cdf..721fc64dd44b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index c2ce764463a3..2e2f1c8c99f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index a70213bdb83c..2ab4bd67ba92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index b2692bd287fa..e57fb989661e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 4a680019e117..98c7aa7346da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 3392011a8768..31c05487a688 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h index d0e43d96ab38..ce983af79644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index f76e9cad7757..386f2a7c87cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index ce0c67b425ee..a7cbf7906200 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h index 7fbf4d717caa..8fbd21704840 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.h +++ b/drivers/net/wireless/iwlwifi/iwl-test.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index a963f45c6849..98f48a9afc98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0cac2b7af78b..205aab851e5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c index 73d24aacb90a..93fd1457954b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/binding.c +++ b/drivers/net/wireless/iwlwifi/mvm/binding.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 994c8c263dc0..376a5776db90 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index c1bdb5582126..9e5313776a26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index cf6f9a02fb74..a442ee11a062 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index ae39b7dfda7b..d68640ea41d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index be36b7604b7f..127051891e9b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index aa3474d08231..fdd33bc0a594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 670ac8f95e26..b60d14151721 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 0acb53dda22d..a30691a8a85b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h index 2677914bf0a6..6d53850c5448 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 2adb61f103f4..92cd982f6b27 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 500f818dba04..0f45fa583aa1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c index 011906e73a05..2269a9e5cc67 100644 --- a/drivers/net/wireless/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/iwlwifi/mvm/led.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 341dbc0237ea..147e925d6474 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7e169b085afe..5939af8523c2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index bdae700c769e..23c39eab4d97 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 20016bcbdeab..555095cf4afc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index d0f9c1e0475e..473864733aab 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index b428448f8ddf..0d537e035ef0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5a92a4978795..efb9a6f3faac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 925628468146..df85c49dc599 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index b0b190d0ec23..4dfc21a3e83e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 9b21b92aa8d1..0d3c76b29242 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 274f44e2ef60..1970001bf96d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 896f88ac8145..119de72c6d18 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index e437e02c7149..c2c7f5176027 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 64fb57a5ab43..b36424eda361 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 6645efe5c03e..a65acf09f913 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 000e842c2edd..e308ad93aa9e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c index 6e35b2b72332..d1d3b3074b9e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ b/drivers/net/wireless/iwlwifi/pcie/7000.c @@ -1,27 +1,64 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * + * BSD LICENSE + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * *****************************************************************************/ #include diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h index c6f8e83c3551..f4318fb192df 100644 --- a/drivers/net/wireless/iwlwifi/pcie/cfg.h +++ b/drivers/net/wireless/iwlwifi/pcie/cfg.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 7bc0fb9128dd..49b254326d9c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 17bedc50e753..d90cbf5041f5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless -- cgit From 5d158efa5577f3851d36f2bdf42ea7af66668b9c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 14:39:58 +0200 Subject: iwlwifi: mvm: respect disable Tx AGG parameter We didn't check that we allowed to start Tx AGG. This can possibly be avoided by a module parameter. Fix that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5939af8523c2..65fc5531f7ba 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -273,6 +273,10 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); break; case IEEE80211_AMPDU_TX_START: + if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { + ret = -EINVAL; + break; + } ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP_CONT: -- cgit From 80d8565557747854d6ff7fc0a756cc71a9fa2372 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 15:32:42 +0200 Subject: iwlwifi: mvm: free AGG queue when we STA is removed When we stop an AGG session, we need to look at the sequence numbers in in the private area of the ieee80211_sta struct. This allows us to know is the queue is empty. To get access to this private area, we use fw_id_to_mac_id that maps sta_id (index of the STA in fw table) to ieee80211_sta. When the STA exists in fw, but not in mac80211, we set an ERR ptr in fw_id_to_mac_id. But if we first set an ERR ptr to fw_id_to_mac_id, and only then flush the queues, then we won't be able to access the sequence numbers in ieee80211_sta from the reclaim flow. This means that we will never be able to release an AGG queue when a station is deleted. So first, flush the queue. That will let the reclaim flow call iwl_mvm_check_ratid_empty which will disable the AGG queue as needed, and only then, remove the mapping in fw_id_to_mac_id. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 1970001bf96d..ca7aba404502 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -340,6 +340,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, if (vif->type == NL80211_IFTYPE_STATION && mvmvif->ap_sta_id == mvm_sta->sta_id) { + /* flush its queues here since we are freeing mvm_sta */ + ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); + /* * Put a non-NULL since the fw station isn't removed. * It will be removed after the MAC will be set as @@ -348,9 +351,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], ERR_PTR(-EINVAL)); - /* flush its queues here since we are freeing mvm_sta */ - ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); - /* if we are associated - we can't remove the AP STA now */ if (vif->bss_conf.assoc) return ret; -- cgit From cc7ee2bab3d90b0a09651dcfa2d0c9ec1a115bc8 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Mon, 18 Feb 2013 13:51:36 +0200 Subject: iwlwifi: mvm: don't use cts to self The current fw doesn't currently support cts to self. There is a bug in the fw that prevents us from using cts to self. Use full protection (including RTS) for now. Signed-off-by: Dor Shaish Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 147e925d6474..3a136c1d3a5d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, if (vif->bss_conf.qos) cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); + /* Don't use cts to self as the fw doesn't support it currently. */ if (vif->bss_conf.use_cts_prot) - cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | - MAC_PROT_FLG_SELF_CTS_EN); + cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); /* * I think that we should enable these 2 flags regardless the HT PROT -- cgit From 1dcd15eed073d5c7b37b43eff645e6c1dae342d9 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 14 Feb 2013 14:25:24 +0200 Subject: iwlwifi: mvm: Update MAC context filter flags 1. For P2P Device filter in only probe requests. 2. For station mode filter in all group cast frames, and in addition beacons as long as we are not associated. 3. For AP/GO filter in all group cast and in addition probe requests. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 3a136c1d3a5d..a993f6c7dac0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm, /* Fill the common data for all mac context types */ iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); + /* Allow beacons to pass through as long as we are not associated,or we + * do not have dtim period information */ + if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period) + cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON); + else + cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); + /* Fill the data specific for station mode */ iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); @@ -714,7 +721,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); - cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); + + /* Override the filter flags to accept only probe requests */ + cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); /* * This flag should be set to true when the P2P Device is @@ -881,6 +890,9 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, /* Fill the common data for all mac context types */ iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); + /* Also enable probe requests to pass */ + cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); + /* Fill the data specific for ap mode */ iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); -- cgit From f4a7dfa3f21afc1b2362f19cebc79d3d7d5a9aee Mon Sep 17 00:00:00 2001 From: Beni Lev Date: Tue, 19 Feb 2013 14:30:16 +0200 Subject: iwlwifi: 7000: disable HT greenfield support The 7000 series devices don't support HT greenfield mode so don't advertise or use it. Signed-off-by: Beni Lev Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/7000.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c index d1d3b3074b9e..a5e9cfe3e746 100644 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ b/drivers/net/wireless/iwlwifi/pcie/7000.c @@ -107,7 +107,6 @@ static const struct iwl_base_params iwl7000_base_params = { }; static const struct iwl_ht_params iwl7000_ht_params = { - .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; -- cgit From 6e6cc9f319bf81b292ceb281228ab1d261172cac Mon Sep 17 00:00:00 2001 From: Beni Lev Date: Tue, 19 Feb 2013 14:40:11 +0200 Subject: iwlwifi: disable greenfield transmissions as a workaround There's a bug that causes the rate scaling to get stuck when it has to use single-stream rates with a peer that can do GF and SGI; the two are incompatible so we can't use them together, but that causes the algorithm to not work at all, it always rejects updates. Disable greenfield for now to prevent that problem. The MVM driver currently only works on devices that don't support greenfield anyway, but better be safe and not allow us to forget about this. Signed-off-by: Beni Lev Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/rs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 56b636d9ab30..a01a6612677e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, */ static bool rs_use_green(struct ieee80211_sta *sta) { - struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; - - bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & - IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; + /* + * There's a bug somewhere in this code that causes the + * scaling to get stuck because GF+SGI can't be combined + * in SISO rates. Until we find that bug, disable GF, it + * has only limited benefit and we still interoperate with + * GF APs since we can always receive GF transmissions. + */ + return false; } /** -- cgit From 831e85f3fe078297ba452e12c0dba96008c59438 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 7 Feb 2013 17:09:09 +0200 Subject: iwlwifi: mvm: Add support for additional addresses Use the number of addresses (max 5) from the NVM instead of limiting to 2 artificially. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 14 +++++++++----- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 65fc5531f7ba..d08ae2604d7b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -105,7 +105,7 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) { struct ieee80211_hw *hw = mvm->hw; - int num_mac, ret; + int num_mac, ret, i; /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | @@ -156,11 +156,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); hw->wiphy->addresses = mvm->addresses; hw->wiphy->n_addresses = 1; - num_mac = mvm->nvm_data->n_hw_addrs; - if (num_mac > 1) { - memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, + + /* Extract additional MAC addresses if available */ + num_mac = (mvm->nvm_data->n_hw_addrs > 1) ? + min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1; + + for (i = 1; i < num_mac; i++) { + memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr, ETH_ALEN); - mvm->addresses[1].addr[5]++; + mvm->addresses[i].addr[5]++; hw->wiphy->n_addresses++; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 23c39eab4d97..efe5da992897 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -79,7 +79,7 @@ #include "fw-api.h" #define IWL_INVALID_MAC80211_QUEUE 0xff -#define IWL_MVM_MAX_ADDRESSES 2 +#define IWL_MVM_MAX_ADDRESSES 5 /* RSSI offset for WkP */ #define IWL_RSSI_OFFSET 50 -- cgit From e3d9e7ce4cd8ea7299cad568b21d50873a29f011 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 16:13:53 +0200 Subject: iwlwifi: mvm: support IEEE80211_AMPDU_TX_STOP_FLUSH mac80211 tells us when we need to dump the frames from the AGG queue instead of releasing them as single MPDUs. Being able to differentiate between the different cases (IEEE80211_AMPDU_TX_STOP_*) allows us to handle races better. When the station is removed, mac80211 asks to flush and removes the station right away. This allows to avoid a case where we still have frames in AGG queues, but the station has been remove already. Note that we can have frames on the shared queues, but this is not a problem: the station in the fw will be kept until all the frames on the shared queues have been drained. AGG queues are a special case since they are dynamically allocated. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 +++- drivers/net/wireless/iwlwifi/mvm/sta.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/sta.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index d08ae2604d7b..924cabf88b26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -284,9 +284,11 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP_CONT: + ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); + break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); + ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ca7aba404502..8b8629317e9c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -834,6 +834,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return err; } +int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid) +{ + struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; + struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; + u16 txq_id; + + /* + * First set the agg state to OFF to avoid calling + * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty. + */ + spin_lock_bh(&mvmsta->lock); + txq_id = tid_data->txq_id; + IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", + mvmsta->sta_id, tid, txq_id, tid_data->state); + tid_data->state = IWL_AGG_OFF; + spin_unlock_bh(&mvmsta->lock); + + if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) + IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); + + iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); + mvm->queue_to_mac80211[tid_data->txq_id] = + IWL_INVALID_MAC80211_QUEUE; + + return 0; +} + static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) { int i; diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 119de72c6d18..b0352df981e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -348,6 +348,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u8 buf_size); int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); +int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid); int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, -- cgit From f7546c76f756f7fbd8d7ec6f26f32cefe7778f9e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 11 Feb 2013 18:55:58 +0100 Subject: iwlwifi: support DSSS/CCK mode in 40 MHz All hardware after 4965 supports this. It's likely that it wasn't set because for 4965 it was irrelevant (HT is only supported on 5 GHz there) and then never updated. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 28c33512aed5..e170f5e6ee7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -749,7 +749,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, } ht_info->ht_supported = true; - ht_info->cap = 0; + ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; if (iwlwifi_mod_params.amsdu_size_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; -- cgit From 9047e4ad435711e67f57b73b76b1235405118c0e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2013 16:29:37 +0100 Subject: iwlwifi: use __get_str in tracing Instead of using (char *)__get_dynamic_array use __get_str. The latter is actually a macro that expands to the former in the code, but trace-cmd in userspace can parse __get_str only. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 81aa91fab5aa..4491c1c72cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -298,7 +298,7 @@ TRACE_EVENT(iwlwifi_dbg, MAX_MSG_LEN, vaf->fmt, *vaf->va) >= MAX_MSG_LEN); ), - TP_printk("%s", (char *)__get_dynamic_array(msg)) + TP_printk("%s", __get_str(msg)) ); #undef TRACE_SYSTEM -- cgit From ba5295f8b2c789275cc6ffb0a45e50a8aa3a5c84 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 25 Feb 2013 21:24:11 +0800 Subject: iwlwifi: convert to use simple_open() This removes an open coded simple_open() function and replaces file operations references to the function with simple_open() instead. Signed-off-by: Wei Yongjun Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 9e5313776a26..2ad301164bd9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx { struct ieee80211_vif *vif; }; -static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -309,7 +303,7 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -317,14 +311,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ }; #define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ }; -- cgit From f0c2646af4f7432f7414e1162377cada06c3c747 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 Jan 2013 20:41:58 +0100 Subject: iwlwifi: mvm: implement remote wake With remote wake, the firmware creates a TCP connection and sends some configurable data on it, until a special TCP data packet from the server is received that triggers a wakeup. The configuration is a bit tricky because it is based on packet pattern matching but this is hidden in the driver and the exposed API in cfg80211 is just based on the required TCP connection parameters. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/d3.c | 258 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 51 +++++- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 26 +++ 3 files changed, 334 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 376a5776db90..d4578cefe445 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -62,8 +62,10 @@ *****************************************************************************/ #include +#include #include #include +#include #include "iwl-modparams.h" #include "fw-api.h" #include "mvm.h" @@ -402,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, sizeof(cmd), &cmd); } +enum iwl_mvm_tcp_packet_type { + MVM_TCP_TX_SYN, + MVM_TCP_RX_SYNACK, + MVM_TCP_TX_DATA, + MVM_TCP_RX_ACK, + MVM_TCP_RX_WAKE, + MVM_TCP_TX_FIN, +}; + +static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr) +{ + __sum16 check = tcp_v4_check(len, saddr, daddr, 0); + return cpu_to_le16(be16_to_cpu((__force __be16)check)); +} + +static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_wowlan_tcp *tcp, + void *_pkt, u8 *mask, + __le16 *pseudo_hdr_csum, + enum iwl_mvm_tcp_packet_type ptype) +{ + struct { + struct ethhdr eth; + struct iphdr ip; + struct tcphdr tcp; + u8 data[]; + } __packed *pkt = _pkt; + u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); + int i; + + pkt->eth.h_proto = cpu_to_be16(ETH_P_IP), + pkt->ip.version = 4; + pkt->ip.ihl = 5; + pkt->ip.protocol = IPPROTO_TCP; + + switch (ptype) { + case MVM_TCP_TX_SYN: + case MVM_TCP_TX_DATA: + case MVM_TCP_TX_FIN: + memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN); + memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN); + pkt->ip.ttl = 128; + pkt->ip.saddr = tcp->src; + pkt->ip.daddr = tcp->dst; + pkt->tcp.source = cpu_to_be16(tcp->src_port); + pkt->tcp.dest = cpu_to_be16(tcp->dst_port); + /* overwritten for TX SYN later */ + pkt->tcp.doff = sizeof(struct tcphdr) / 4; + pkt->tcp.window = cpu_to_be16(65000); + break; + case MVM_TCP_RX_SYNACK: + case MVM_TCP_RX_ACK: + case MVM_TCP_RX_WAKE: + memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN); + memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN); + pkt->ip.saddr = tcp->dst; + pkt->ip.daddr = tcp->src; + pkt->tcp.source = cpu_to_be16(tcp->dst_port); + pkt->tcp.dest = cpu_to_be16(tcp->src_port); + break; + default: + WARN_ON(1); + return; + } + + switch (ptype) { + case MVM_TCP_TX_SYN: + /* firmware assumes 8 option bytes - 8 NOPs for now */ + memset(pkt->data, 0x01, 8); + ip_tot_len += 8; + pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4; + pkt->tcp.syn = 1; + break; + case MVM_TCP_TX_DATA: + ip_tot_len += tcp->payload_len; + memcpy(pkt->data, tcp->payload, tcp->payload_len); + pkt->tcp.psh = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_TX_FIN: + pkt->tcp.fin = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_SYNACK: + pkt->tcp.syn = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_ACK: + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_WAKE: + ip_tot_len += tcp->wake_len; + pkt->tcp.psh = 1; + pkt->tcp.ack = 1; + memcpy(pkt->data, tcp->wake_data, tcp->wake_len); + break; + } + + switch (ptype) { + case MVM_TCP_TX_SYN: + case MVM_TCP_TX_DATA: + case MVM_TCP_TX_FIN: + pkt->ip.tot_len = cpu_to_be16(ip_tot_len); + pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl); + break; + case MVM_TCP_RX_WAKE: + for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) { + u8 tmp = tcp->wake_mask[i]; + mask[i + 6] |= tmp << 6; + if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8)) + mask[i + 7] = tmp >> 2; + } + /* fall through for ethernet/IP/TCP headers mask */ + case MVM_TCP_RX_SYNACK: + case MVM_TCP_RX_ACK: + mask[0] = 0xff; /* match ethernet */ + /* + * match ethernet, ip.version, ip.ihl + * the ip.ihl half byte is really masked out by firmware + */ + mask[1] = 0x7f; + mask[2] = 0x80; /* match ip.protocol */ + mask[3] = 0xfc; /* match ip.saddr, ip.daddr */ + mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */ + mask[5] = 0x80; /* match tcp flags */ + /* leave rest (0 or set for MVM_TCP_RX_WAKE) */ + break; + }; + + *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr), + pkt->ip.saddr, pkt->ip.daddr); +} + +static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_wowlan_tcp *tcp) +{ + struct iwl_wowlan_remote_wake_config *cfg; + struct iwl_host_cmd cmd = { + .id = REMOTE_WAKE_CONFIG_CMD, + .len = { sizeof(*cfg), }, + .dataflags = { IWL_HCMD_DFL_NOCOPY, }, + .flags = CMD_SYNC, + }; + int ret; + + if (!tcp) + return 0; + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + cmd.data[0] = cfg; + + cfg->max_syn_retries = 10; + cfg->max_data_retries = 10; + cfg->tcp_syn_ack_timeout = 1; /* seconds */ + cfg->tcp_ack_timeout = 1; /* seconds */ + + /* SYN (TX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->syn_tx.data, NULL, + &cfg->syn_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_SYN); + cfg->syn_tx.info.tcp_payload_length = 0; + + /* SYN/ACK (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask, + &cfg->synack_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_SYNACK); + cfg->synack_rx.info.tcp_payload_length = 0; + + /* KEEPALIVE/ACK (TX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->keepalive_tx.data, NULL, + &cfg->keepalive_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_DATA); + cfg->keepalive_tx.info.tcp_payload_length = + cpu_to_le16(tcp->payload_len); + cfg->sequence_number_offset = tcp->payload_seq.offset; + /* length must be 0..4, the field is little endian */ + cfg->sequence_number_length = tcp->payload_seq.len; + cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start); + cfg->keepalive_interval = cpu_to_le16(tcp->data_interval); + if (tcp->payload_tok.len) { + cfg->token_offset = tcp->payload_tok.offset; + cfg->token_length = tcp->payload_tok.len; + cfg->num_tokens = + cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len); + memcpy(cfg->tokens, tcp->payload_tok.token_stream, + tcp->tokens_size); + } else { + /* set tokens to max value to almost never run out */ + cfg->num_tokens = cpu_to_le16(65535); + } + + /* ACK (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->keepalive_ack_rx.data, + cfg->keepalive_ack_rx.rx_mask, + &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_ACK); + cfg->keepalive_ack_rx.info.tcp_payload_length = 0; + + /* WAKEUP (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask, + &cfg->wake_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_WAKE); + cfg->wake_rx.info.tcp_payload_length = + cpu_to_le16(tcp->wake_len); + + /* FIN */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->fin_tx.data, NULL, + &cfg->fin_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_FIN); + cfg->fin_tx.info.tcp_payload_length = 0; + + ret = iwl_mvm_send_cmd(mvm, &cmd); + kfree(cfg); + + return ret; +} + struct iwl_d3_iter_data { struct iwl_mvm *mvm; struct ieee80211_vif *vif; @@ -640,6 +869,22 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) d3_cfg_cmd.wakeup_flags |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); + if (wowlan->tcp) { + /* + * The firmware currently doesn't really look at these, only + * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that + * reason bit since losing the connection to the AP implies + * losing the TCP connection. + * Set the flags anyway as long as they exist, in case this + * will be changed in the firmware. + */ + wowlan_config_cmd.wakeup_filter |= + cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | + IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | + IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | + IWL_WOWLAN_WAKEUP_LINK_CHANGE); + } + iwl_mvm_cancel_scan(mvm); iwl_trans_stop_device(mvm->trans); @@ -755,6 +1000,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (ret) goto out; + ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); + if (ret) + goto out; + /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, sizeof(d3_cfg_cmd), &d3_cfg_cmd); @@ -874,6 +1123,15 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) wakeup.four_way_handshake = true; + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) + wakeup.tcp_connlost = true; + + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) + wakeup.tcp_nomoretokens = true; + + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) + wakeup.tcp_match = true; + if (status->wake_packet_bufsize) { int pktsize = le32_to_cpu(status->wake_packet_bufsize); int pktlen = le32_to_cpu(status->wake_packet_length); diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index a442ee11a062..51e015d1dfb2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason { IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), - IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), + /* BIT(11) reserved */ IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ @@ -277,6 +277,55 @@ struct iwl_wowlan_status { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ +#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 +#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 +#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 + +struct iwl_tcp_packet_info { + __le16 tcp_pseudo_header_checksum; + __le16 tcp_payload_length; +} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */ + +struct iwl_tcp_packet { + struct iwl_tcp_packet_info info; + u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; + u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN]; +} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ + +struct iwl_remote_wake_packet { + struct iwl_tcp_packet_info info; + u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; + u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN]; +} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ + +struct iwl_wowlan_remote_wake_config { + __le32 connection_max_time; /* unused */ + /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */ + u8 max_syn_retries; + u8 max_data_retries; + u8 tcp_syn_ack_timeout; + u8 tcp_ack_timeout; + + struct iwl_tcp_packet syn_tx; + struct iwl_tcp_packet synack_rx; + struct iwl_tcp_packet keepalive_ack_rx; + struct iwl_tcp_packet fin_tx; + + struct iwl_remote_wake_packet keepalive_tx; + struct iwl_remote_wake_packet wake_rx; + + /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */ + u8 sequence_number_offset; + u8 sequence_number_length; + u8 token_offset; + u8 token_length; + /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */ + __le32 initial_sequence_number; + __le16 keepalive_interval; + __le16 num_tokens; + u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS]; +} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */ + /* TODO: NetDetect API */ #endif /* __fw_api_d3_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 924cabf88b26..ed2d8754c82b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -65,7 +65,9 @@ #include #include #include +#include #include +#include #include "iwl-op-mode.h" #include "iwl-io.h" @@ -102,6 +104,29 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { }, }; +#ifdef CONFIG_PM_SLEEP +static const struct nl80211_wowlan_tcp_data_token_feature +iwl_mvm_wowlan_tcp_token_feature = { + .min_len = 0, + .max_len = 255, + .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS, +}; + +static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = { + .tok = &iwl_mvm_wowlan_tcp_token_feature, + .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN - + sizeof(struct ethhdr) - + sizeof(struct iphdr) - + sizeof(struct tcphdr), + .data_interval_max = 65535, /* __le16 in API */ + .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN - + sizeof(struct ethhdr) - + sizeof(struct iphdr) - + sizeof(struct tcphdr), + .seq = true, +}; +#endif + int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) { struct ieee80211_hw *hw = mvm->hw; @@ -210,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; + hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; } #endif -- cgit From 5bc5aaad407ccc49262d9fd3456d6ab332286395 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 12 Feb 2013 14:35:36 +0100 Subject: iwlwifi: mvm: set up initial SMPS/NSS station info When a station is added, we need to tell the firmware what the SMPS settings and number of streams are. After having the initial data, the firmware will track future changes by itself. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 8b8629317e9c..4872ec23b371 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, } add_sta_cmd.add_modify = update ? 1 : 0; - /* STA_FLG_FAT_EN_MSK ? */ - /* STA_FLG_MIMO_EN_MSK ? */ + add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK | + STA_FLG_MIMO_EN_MSK); + + switch (sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_80: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_40: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_20: + if (sta->ht_cap.ht_supported) + add_sta_cmd.station_flags |= + cpu_to_le32(STA_FLG_FAT_EN_20MHZ); + break; + } + + switch (sta->rx_nss) { + case 1: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); + break; + case 2: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2); + break; + case 3 ... 8: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3); + break; + } + + switch (sta->smps_mode) { + case IEEE80211_SMPS_AUTOMATIC: + case IEEE80211_SMPS_NUM_MODES: + WARN_ON(1); + break; + case IEEE80211_SMPS_STATIC: + /* override NSS */ + add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK); + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); + break; + case IEEE80211_SMPS_DYNAMIC: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT); + break; + case IEEE80211_SMPS_OFF: + /* nothing */ + break; + } if (sta->ht_cap.ht_supported) { add_sta_cmd.station_flags_msk |= -- cgit From 33158fefc88e58fa17a46fdd90ba5231c3c8c89a Mon Sep 17 00:00:00 2001 From: Eytan Lifshitz Date: Wed, 20 Feb 2013 11:01:13 +0200 Subject: iwlwifi: mvm: advertise VHT capabilities Update the NVM parsing functions to add VHT capabilities; they are only added for 5 GHz, of course. This assumes that all devices with NVM reading (rather than EEPROM) that support 5 GHz have VHT, which is true right now. Signed-off-by: Eytan Lifshitz Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 2ab4bd67ba92..1ae6f2c1558d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -149,6 +149,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { * @NVM_CHANNEL_DFS: dynamic freq selection candidate * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) + * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) + * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) */ enum iwl_nvm_channel_flags { NVM_CHANNEL_VALID = BIT(0), @@ -158,6 +160,8 @@ enum iwl_nvm_channel_flags { NVM_CHANNEL_DFS = BIT(7), NVM_CHANNEL_WIDE = BIT(8), NVM_CHANNEL_40MHZ = BIT(9), + NVM_CHANNEL_80MHZ = BIT(10), + NVM_CHANNEL_160MHZ = BIT(11), }; #define CHECK_AND_PRINT_I(x) \ @@ -210,6 +214,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, else channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; } + if (!(ch_flags & NVM_CHANNEL_80MHZ)) + channel->flags |= IEEE80211_CHAN_NO_80MHZ; + if (!(ch_flags & NVM_CHANNEL_160MHZ)) + channel->flags |= IEEE80211_CHAN_NO_160MHZ; if (!(ch_flags & NVM_CHANNEL_IBSS)) channel->flags |= IEEE80211_CHAN_NO_IBSS; @@ -245,6 +253,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, return n_channels; } +static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, + struct iwl_nvm_data *data, + struct ieee80211_sta_vht_cap *vht_cap) +{ + /* For now, assume new devices with NVM are VHT capable */ + + vht_cap->vht_supported = true; + + vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + + if (iwlwifi_mod_params.amsdu_size_8K) + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; + + vht_cap->vht_mcs.rx_mcs_map = + cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); + + if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { + vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; + /* this works because NOT_SUPPORTED == 3 */ + vht_cap->vht_mcs.rx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2); + } + + vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; +} + static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, struct iwl_nvm_data *data, const __le16 *nvm_sw) { @@ -268,6 +313,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, n_used += iwl_init_sband_channels(data, sband, n_channels, IEEE80211_BAND_5GHZ); iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); + iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); if (n_channels != n_used) IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", -- cgit From 5e4fbe4cc05767fe7e1bbc269376e0e48f365327 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 27 Feb 2013 11:21:07 +0200 Subject: iwlwifi: dvm: pad iwl_compressed_ba_resp All the data coming from the fw must have a length that is multiple of 4. This doesn't change anything to the way we handle the notification. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/commands.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 22100c2a56ea..95ca026ecc9d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp { __le16 scd_ssn; u8 txed; /* number of frames sent */ u8 txed_2_done; /* number of frames acked */ + __le16 reserved1; } __packed; /* -- cgit From b1f553c7484b983aac20c107b9766804b69cf73f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 20 Feb 2013 12:41:58 +0200 Subject: iwlwifi: make device configuration bus agnostic Newer devices can work on different buses. This means that their configuration can be shared between different buses. Hence the configuration structures should exported to all the buses and not only to PCIE. Change this. Note that this requires all the fields to be the same amongst the buses. If differences will appear, we can always define a part that is bus dependent. Today, this is not needed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 3 +- drivers/net/wireless/iwlwifi/iwl-1000.c | 140 +++++++++++ drivers/net/wireless/iwlwifi/iwl-2000.c | 242 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-5000.c | 179 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-6000.c | 402 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-7000.c | 146 +++++++++++ drivers/net/wireless/iwlwifi/iwl-config.h | 47 ++++ drivers/net/wireless/iwlwifi/pcie/1000.c | 141 ----------- drivers/net/wireless/iwlwifi/pcie/2000.c | 243 ------------------ drivers/net/wireless/iwlwifi/pcie/5000.c | 180 ------------- drivers/net/wireless/iwlwifi/pcie/6000.c | 403 ------------------------------ drivers/net/wireless/iwlwifi/pcie/7000.c | 147 ----------- drivers/net/wireless/iwlwifi/pcie/cfg.h | 115 --------- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 - 14 files changed, 1157 insertions(+), 1233 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-1000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-2000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-5000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-6000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-7000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/1000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/2000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/5000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/6000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/7000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/cfg.h (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 6c7800044a04..3b5613ea458b 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o -iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o -iwlwifi-objs += pcie/7000.o +iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c new file mode 100644 index 000000000000..c080ae3070b2 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-csr.h" +#include "iwl-agn-hw.h" + +/* Highest firmware API version supported */ +#define IWL1000_UCODE_API_MAX 5 +#define IWL100_UCODE_API_MAX 5 + +/* Oldest version we won't warn about */ +#define IWL1000_UCODE_API_OK 5 +#define IWL100_UCODE_API_OK 5 + +/* Lowest firmware API version supported */ +#define IWL1000_UCODE_API_MIN 1 +#define IWL100_UCODE_API_MIN 5 + +/* EEPROM version */ +#define EEPROM_1000_TX_POWER_VERSION (4) +#define EEPROM_1000_EEPROM_VERSION (0x15C) + +#define IWL1000_FW_PRE "iwlwifi-1000-" +#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" + +#define IWL100_FW_PRE "iwlwifi-100-" +#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" + + +static const struct iwl_base_params iwl1000_base_params = { + .num_of_queues = IWLAGN_NUM_QUEUES, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .max_ll_items = OTP_MAX_LL_ITEMS_1000, + .shadow_ram_support = false, + .led_compensation = 51, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_WATCHDOG_DISABLED, + .max_event_log_size = 128, +}; + +static const struct iwl_ht_params iwl1000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), +}; + +static const struct iwl_eeprom_params iwl1000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + } +}; + +#define IWL_DEVICE_1000 \ + .fw_name_pre = IWL1000_FW_PRE, \ + .ucode_api_max = IWL1000_UCODE_API_MAX, \ + .ucode_api_ok = IWL1000_UCODE_API_OK, \ + .ucode_api_min = IWL1000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_1000, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl1000_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", + IWL_DEVICE_1000, + .ht_params = &iwl1000_ht_params, +}; + +const struct iwl_cfg iwl1000_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", + IWL_DEVICE_1000, +}; + +#define IWL_DEVICE_100 \ + .fw_name_pre = IWL100_FW_PRE, \ + .ucode_api_max = IWL100_UCODE_API_MAX, \ + .ucode_api_ok = IWL100_UCODE_API_OK, \ + .ucode_api_min = IWL100_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_100, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ + .led_mode = IWL_LED_RF_STATE, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl100_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", + IWL_DEVICE_100, + .ht_params = &iwl1000_ht_params, +}; + +const struct iwl_cfg iwl100_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 100 BG", + IWL_DEVICE_100, +}; + +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c new file mode 100644 index 000000000000..a6ddd2f9fba0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -0,0 +1,242 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "dvm/commands.h" /* needed for BT for now */ + +/* Highest firmware API version supported */ +#define IWL2030_UCODE_API_MAX 6 +#define IWL2000_UCODE_API_MAX 6 +#define IWL105_UCODE_API_MAX 6 +#define IWL135_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL2030_UCODE_API_OK 6 +#define IWL2000_UCODE_API_OK 6 +#define IWL105_UCODE_API_OK 6 +#define IWL135_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL2030_UCODE_API_MIN 5 +#define IWL2000_UCODE_API_MIN 5 +#define IWL105_UCODE_API_MIN 5 +#define IWL135_UCODE_API_MIN 5 + +/* EEPROM version */ +#define EEPROM_2000_TX_POWER_VERSION (6) +#define EEPROM_2000_EEPROM_VERSION (0x805) + + +#define IWL2030_FW_PRE "iwlwifi-2030-" +#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" + +#define IWL2000_FW_PRE "iwlwifi-2000-" +#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode" + +#define IWL105_FW_PRE "iwlwifi-105-" +#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" + +#define IWL135_FW_PRE "iwlwifi-135-" +#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl2000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .hd_v2 = true, +}; + + +static const struct iwl_base_params iwl2030_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .hd_v2 = true, +}; + +static const struct iwl_ht_params iwl2000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), +}; + +static const struct iwl_bt_params iwl2030_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, + .bt_sco_disable = true, + .bt_session_2 = true, +}; + +static const struct iwl_eeprom_params iwl20x0_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .enhanced_txpower = true, +}; + +#define IWL_DEVICE_2000 \ + .fw_name_pre = IWL2000_FW_PRE, \ + .ucode_api_max = IWL2000_UCODE_API_MAX, \ + .ucode_api_ok = IWL2000_UCODE_API_OK, \ + .ucode_api_min = IWL2000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_2000, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE + +const struct iwl_cfg iwl2000_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +const struct iwl_cfg iwl2000_2bgn_d_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_2030 \ + .fw_name_pre = IWL2030_FW_PRE, \ + .ucode_api_max = IWL2030_UCODE_API_MAX, \ + .ucode_api_ok = IWL2030_UCODE_API_OK, \ + .ucode_api_min = IWL2030_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_2030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + +const struct iwl_cfg iwl2030_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", + IWL_DEVICE_2030, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_105 \ + .fw_name_pre = IWL105_FW_PRE, \ + .ucode_api_max = IWL105_UCODE_API_MAX, \ + .ucode_api_ok = IWL105_UCODE_API_OK, \ + .ucode_api_min = IWL105_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_105, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl105_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", + IWL_DEVICE_105, + .ht_params = &iwl2000_ht_params, +}; + +const struct iwl_cfg iwl105_bgn_d_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", + IWL_DEVICE_105, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_135 \ + .fw_name_pre = IWL135_FW_PRE, \ + .ucode_api_max = IWL135_UCODE_API_MAX, \ + .ucode_api_ok = IWL135_UCODE_API_OK, \ + .ucode_api_min = IWL135_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_135, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl135_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", + IWL_DEVICE_135, + .ht_params = &iwl2000_ht_params, +}; + +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c new file mode 100644 index 000000000000..403f3f224bf6 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "iwl-csr.h" + +/* Highest firmware API version supported */ +#define IWL5000_UCODE_API_MAX 5 +#define IWL5150_UCODE_API_MAX 2 + +/* Oldest version we won't warn about */ +#define IWL5000_UCODE_API_OK 5 +#define IWL5150_UCODE_API_OK 2 + +/* Lowest firmware API version supported */ +#define IWL5000_UCODE_API_MIN 1 +#define IWL5150_UCODE_API_MIN 1 + +/* EEPROM versions */ +#define EEPROM_5000_TX_POWER_VERSION (4) +#define EEPROM_5000_EEPROM_VERSION (0x11A) +#define EEPROM_5050_TX_POWER_VERSION (4) +#define EEPROM_5050_EEPROM_VERSION (0x21E) + +#define IWL5000_FW_PRE "iwlwifi-5000-" +#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" + +#define IWL5150_FW_PRE "iwlwifi-5150-" +#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl5000_base_params = { + .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .led_compensation = 51, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_WATCHDOG_DISABLED, + .max_event_log_size = 512, + .no_idle_support = true, +}; + +static const struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +static const struct iwl_eeprom_params iwl5000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, +}; + +#define IWL_DEVICE_5000 \ + .fw_name_pre = IWL5000_FW_PRE, \ + .ucode_api_max = IWL5000_UCODE_API_MAX, \ + .ucode_api_ok = IWL5000_UCODE_API_OK, \ + .ucode_api_min = IWL5000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_5000, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ + .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl5300_agn_cfg = { + .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", + IWL_DEVICE_5000, + /* at least EEPROM 0x11A has wrong info */ + .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ + .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5100_bgn_cfg = { + .name = "Intel(R) WiFi Link 5100 BGN", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5100_abg_cfg = { + .name = "Intel(R) WiFi Link 5100 ABG", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ +}; + +const struct iwl_cfg iwl5100_agn_cfg = { + .name = "Intel(R) WiFi Link 5100 AGN", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5350_agn_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", + .fw_name_pre = IWL5000_FW_PRE, + .ucode_api_max = IWL5000_UCODE_API_MAX, + .ucode_api_ok = IWL5000_UCODE_API_OK, + .ucode_api_min = IWL5000_UCODE_API_MIN, + .device_family = IWL_DEVICE_FAMILY_5000, + .max_inst_size = IWLAGN_RTC_INST_SIZE, + .max_data_size = IWLAGN_RTC_DATA_SIZE, + .nvm_ver = EEPROM_5050_EEPROM_VERSION, + .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, + .base_params = &iwl5000_base_params, + .eeprom_params = &iwl5000_eeprom_params, + .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, +}; + +#define IWL_DEVICE_5150 \ + .fw_name_pre = IWL5150_FW_PRE, \ + .ucode_api_max = IWL5150_UCODE_API_MAX, \ + .ucode_api_ok = IWL5150_UCODE_API_OK, \ + .ucode_api_min = IWL5150_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_5150, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ + .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ + .no_xtal_calib = true, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl5150_agn_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", + IWL_DEVICE_5150, + .ht_params = &iwl5000_ht_params, + +}; + +const struct iwl_cfg iwl5150_abg_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", + IWL_DEVICE_5150, +}; + +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c new file mode 100644 index 000000000000..b5ab8d1bcac0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -0,0 +1,402 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "dvm/commands.h" /* needed for BT for now */ + +/* Highest firmware API version supported */ +#define IWL6000_UCODE_API_MAX 6 +#define IWL6050_UCODE_API_MAX 5 +#define IWL6000G2_UCODE_API_MAX 6 +#define IWL6035_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL6000_UCODE_API_OK 4 +#define IWL6000G2_UCODE_API_OK 5 +#define IWL6050_UCODE_API_OK 5 +#define IWL6000G2B_UCODE_API_OK 6 +#define IWL6035_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL6000_UCODE_API_MIN 4 +#define IWL6050_UCODE_API_MIN 4 +#define IWL6000G2_UCODE_API_MIN 5 +#define IWL6035_UCODE_API_MIN 6 + +/* EEPROM versions */ +#define EEPROM_6000_TX_POWER_VERSION (4) +#define EEPROM_6000_EEPROM_VERSION (0x423) +#define EEPROM_6050_TX_POWER_VERSION (4) +#define EEPROM_6050_EEPROM_VERSION (0x532) +#define EEPROM_6150_TX_POWER_VERSION (6) +#define EEPROM_6150_EEPROM_VERSION (0x553) +#define EEPROM_6005_TX_POWER_VERSION (6) +#define EEPROM_6005_EEPROM_VERSION (0x709) +#define EEPROM_6030_TX_POWER_VERSION (6) +#define EEPROM_6030_EEPROM_VERSION (0x709) +#define EEPROM_6035_TX_POWER_VERSION (6) +#define EEPROM_6035_EEPROM_VERSION (0x753) + +#define IWL6000_FW_PRE "iwlwifi-6000-" +#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" + +#define IWL6050_FW_PRE "iwlwifi-6050-" +#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode" + +#define IWL6005_FW_PRE "iwlwifi-6000g2a-" +#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode" + +#define IWL6030_FW_PRE "iwlwifi-6000g2b-" +#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl6000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_base_params iwl6050_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x50, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1500, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 1024, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_base_params iwl6000_g2_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_ht_params iwl6000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +static const struct iwl_bt_params iwl6000_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, + .bt_sco_disable = true, +}; + +static const struct iwl_eeprom_params iwl6000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .enhanced_txpower = true, +}; + +#define IWL_DEVICE_6005 \ + .fw_name_pre = IWL6005_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6005, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE + +const struct iwl_cfg iwl6005_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", + IWL_DEVICE_6005, +}; + +const struct iwl_cfg iwl6005_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", + IWL_DEVICE_6005, +}; + +const struct iwl_cfg iwl6005_2agn_sff_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_d_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_mow1_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_mow2_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +#define IWL_DEVICE_6030 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + +const struct iwl_cfg iwl6030_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6030_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", + IWL_DEVICE_6030, +}; + +const struct iwl_cfg iwl6030_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6030_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", + IWL_DEVICE_6030, +}; + +#define IWL_DEVICE_6035 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6035_UCODE_API_MAX, \ + .ucode_api_ok = IWL6035_UCODE_API_OK, \ + .ucode_api_min = IWL6035_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + +const struct iwl_cfg iwl6035_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", + IWL_DEVICE_6035, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl1030_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl1030_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", + IWL_DEVICE_6030, +}; + +const struct iwl_cfg iwl130_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, + .rx_with_siso_diversity = true, +}; + +const struct iwl_cfg iwl130_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BG", + IWL_DEVICE_6030, + .rx_with_siso_diversity = true, +}; + +/* + * "i": Internal configuration, use internal Power Amplifier + */ +#define IWL_DEVICE_6000i \ + .fw_name_pre = IWL6000_FW_PRE, \ + .ucode_api_max = IWL6000_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000_UCODE_API_OK, \ + .ucode_api_min = IWL6000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6000i, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ + .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ + .base_params = &iwl6000_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl6000i_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", + IWL_DEVICE_6000i, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6000i_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", + IWL_DEVICE_6000i, +}; + +const struct iwl_cfg iwl6000i_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", + IWL_DEVICE_6000i, +}; + +#define IWL_DEVICE_6050 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6050, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ + .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ + .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl6050_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", + IWL_DEVICE_6050, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6050_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", + IWL_DEVICE_6050, +}; + +#define IWL_DEVICE_6150 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6150, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ + .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl6150_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", + IWL_DEVICE_6150, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6150_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", + IWL_DEVICE_6150, +}; + +const struct iwl_cfg iwl6000_3agn_cfg = { + .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", + .fw_name_pre = IWL6000_FW_PRE, + .ucode_api_max = IWL6000_UCODE_API_MAX, + .ucode_api_ok = IWL6000_UCODE_API_OK, + .ucode_api_min = IWL6000_UCODE_API_MIN, + .device_family = IWL_DEVICE_FAMILY_6000, + .max_inst_size = IWL60_RTC_INST_SIZE, + .max_data_size = IWL60_RTC_DATA_SIZE, + .nvm_ver = EEPROM_6000_EEPROM_VERSION, + .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, + .base_params = &iwl6000_base_params, + .eeprom_params = &iwl6000_eeprom_params, + .ht_params = &iwl6000_ht_params, + .led_mode = IWL_LED_BLINK, +}; + +MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c new file mode 100644 index 000000000000..50263e87fe15 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -0,0 +1,146 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" + +/* Highest firmware API version supported */ +#define IWL7260_UCODE_API_MAX 6 +#define IWL3160_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL7260_UCODE_API_OK 6 +#define IWL3160_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL7260_UCODE_API_MIN 6 +#define IWL3160_UCODE_API_MIN 6 + +/* NVM versions */ +#define IWL7260_NVM_VERSION 0x0a1d +#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ +#define IWL3160_NVM_VERSION 0x709 +#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ + +#define IWL7260_FW_PRE "iwlwifi-7260-" +#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" + +#define IWL3160_FW_PRE "iwlwifi-3160-" +#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl7000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_ht_params iwl7000_ht_params = { + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +#define IWL_DEVICE_7000 \ + .ucode_api_max = IWL7260_UCODE_API_MAX, \ + .ucode_api_ok = IWL7260_UCODE_API_OK, \ + .ucode_api_min = IWL7260_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_7000, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .base_params = &iwl7000_base_params, \ + /* TODO: .bt_params? */ \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + + +const struct iwl_cfg iwl7260_2ac_cfg = { + .name = "Intel(R) Dual Band Wireless AC7260", + .fw_name_pre = IWL7260_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, +}; + +const struct iwl_cfg iwl3160_ac_cfg = { + .name = "Intel(R) Dual Band Wireless AC3160", + .fw_name_pre = IWL3160_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL3160_NVM_VERSION, + .nvm_calib_ver = IWL3160_TX_POWER_VERSION, +}; + +MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); +MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 8ba293b2396b..c38aa8f77554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -275,4 +275,51 @@ struct iwl_cfg { const bool temp_offset_v2; }; +/* + * This list declares the config structures for all devices. + */ +extern const struct iwl_cfg iwl5300_agn_cfg; +extern const struct iwl_cfg iwl5100_agn_cfg; +extern const struct iwl_cfg iwl5350_agn_cfg; +extern const struct iwl_cfg iwl5100_bgn_cfg; +extern const struct iwl_cfg iwl5100_abg_cfg; +extern const struct iwl_cfg iwl5150_agn_cfg; +extern const struct iwl_cfg iwl5150_abg_cfg; +extern const struct iwl_cfg iwl6005_2agn_cfg; +extern const struct iwl_cfg iwl6005_2abg_cfg; +extern const struct iwl_cfg iwl6005_2bg_cfg; +extern const struct iwl_cfg iwl6005_2agn_sff_cfg; +extern const struct iwl_cfg iwl6005_2agn_d_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; +extern const struct iwl_cfg iwl1030_bgn_cfg; +extern const struct iwl_cfg iwl1030_bg_cfg; +extern const struct iwl_cfg iwl6030_2agn_cfg; +extern const struct iwl_cfg iwl6030_2abg_cfg; +extern const struct iwl_cfg iwl6030_2bgn_cfg; +extern const struct iwl_cfg iwl6030_2bg_cfg; +extern const struct iwl_cfg iwl6000i_2agn_cfg; +extern const struct iwl_cfg iwl6000i_2abg_cfg; +extern const struct iwl_cfg iwl6000i_2bg_cfg; +extern const struct iwl_cfg iwl6000_3agn_cfg; +extern const struct iwl_cfg iwl6050_2agn_cfg; +extern const struct iwl_cfg iwl6050_2abg_cfg; +extern const struct iwl_cfg iwl6150_bgn_cfg; +extern const struct iwl_cfg iwl6150_bg_cfg; +extern const struct iwl_cfg iwl1000_bgn_cfg; +extern const struct iwl_cfg iwl1000_bg_cfg; +extern const struct iwl_cfg iwl100_bgn_cfg; +extern const struct iwl_cfg iwl100_bg_cfg; +extern const struct iwl_cfg iwl130_bgn_cfg; +extern const struct iwl_cfg iwl130_bg_cfg; +extern const struct iwl_cfg iwl2000_2bgn_cfg; +extern const struct iwl_cfg iwl2000_2bgn_d_cfg; +extern const struct iwl_cfg iwl2030_2bgn_cfg; +extern const struct iwl_cfg iwl6035_2agn_cfg; +extern const struct iwl_cfg iwl105_bgn_cfg; +extern const struct iwl_cfg iwl105_bgn_d_cfg; +extern const struct iwl_cfg iwl135_bgn_cfg; +extern const struct iwl_cfg iwl7260_2ac_cfg; +extern const struct iwl_cfg iwl3160_ac_cfg; + #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c deleted file mode 100644 index ff3389757281..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-csr.h" -#include "iwl-agn-hw.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 5 -#define IWL100_UCODE_API_MAX 5 - -/* Oldest version we won't warn about */ -#define IWL1000_UCODE_API_OK 5 -#define IWL100_UCODE_API_OK 5 - -/* Lowest firmware API version supported */ -#define IWL1000_UCODE_API_MIN 1 -#define IWL100_UCODE_API_MIN 5 - -/* EEPROM version */ -#define EEPROM_1000_TX_POWER_VERSION (4) -#define EEPROM_1000_EEPROM_VERSION (0x15C) - -#define IWL1000_FW_PRE "iwlwifi-1000-" -#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" - -#define IWL100_FW_PRE "iwlwifi-100-" -#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" - - -static const struct iwl_base_params iwl1000_base_params = { - .num_of_queues = IWLAGN_NUM_QUEUES, - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .led_compensation = 51, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHDOG_DISABLED, - .max_event_log_size = 128, -}; - -static const struct iwl_ht_params iwl1000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ), -}; - -static const struct iwl_eeprom_params iwl1000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - } -}; - -#define IWL_DEVICE_1000 \ - .fw_name_pre = IWL1000_FW_PRE, \ - .ucode_api_max = IWL1000_UCODE_API_MAX, \ - .ucode_api_ok = IWL1000_UCODE_API_OK, \ - .ucode_api_min = IWL1000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_1000, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_params, \ - .eeprom_params = &iwl1000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl1000_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", - IWL_DEVICE_1000, - .ht_params = &iwl1000_ht_params, -}; - -const struct iwl_cfg iwl1000_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", - IWL_DEVICE_1000, -}; - -#define IWL_DEVICE_100 \ - .fw_name_pre = IWL100_FW_PRE, \ - .ucode_api_max = IWL100_UCODE_API_MAX, \ - .ucode_api_ok = IWL100_UCODE_API_OK, \ - .ucode_api_min = IWL100_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_100, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_params, \ - .eeprom_params = &iwl1000_eeprom_params, \ - .led_mode = IWL_LED_RF_STATE, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl100_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", - IWL_DEVICE_100, - .ht_params = &iwl1000_ht_params, -}; - -const struct iwl_cfg iwl100_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BG", - IWL_DEVICE_100, -}; - -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c deleted file mode 100644 index e7de33128b16..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ /dev/null @@ -1,243 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" -#include "dvm/commands.h" /* needed for BT for now */ - -/* Highest firmware API version supported */ -#define IWL2030_UCODE_API_MAX 6 -#define IWL2000_UCODE_API_MAX 6 -#define IWL105_UCODE_API_MAX 6 -#define IWL135_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 6 -#define IWL2000_UCODE_API_OK 6 -#define IWL105_UCODE_API_OK 6 -#define IWL135_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL2030_UCODE_API_MIN 5 -#define IWL2000_UCODE_API_MIN 5 -#define IWL105_UCODE_API_MIN 5 -#define IWL135_UCODE_API_MIN 5 - -/* EEPROM version */ -#define EEPROM_2000_TX_POWER_VERSION (6) -#define EEPROM_2000_EEPROM_VERSION (0x805) - - -#define IWL2030_FW_PRE "iwlwifi-2030-" -#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" - -#define IWL2000_FW_PRE "iwlwifi-2000-" -#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode" - -#define IWL105_FW_PRE "iwlwifi-105-" -#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" - -#define IWL135_FW_PRE "iwlwifi-135-" -#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl2000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_2x00, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ - .hd_v2 = true, -}; - - -static const struct iwl_base_params iwl2030_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_2x00, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ - .hd_v2 = true, -}; - -static const struct iwl_ht_params iwl2000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ), -}; - -static const struct iwl_bt_params iwl2030_bt_params = { - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .advanced_bt_coexist = true, - .agg_time_limit = BT_AGG_THRESHOLD_DEF, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, - .bt_sco_disable = true, - .bt_session_2 = true, -}; - -static const struct iwl_eeprom_params iwl20x0_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .enhanced_txpower = true, -}; - -#define IWL_DEVICE_2000 \ - .fw_name_pre = IWL2000_FW_PRE, \ - .ucode_api_max = IWL2000_UCODE_API_MAX, \ - .ucode_api_ok = IWL2000_UCODE_API_OK, \ - .ucode_api_min = IWL2000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2000, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE - -const struct iwl_cfg iwl2000_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", - IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, -}; - -const struct iwl_cfg iwl2000_2bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", - IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_2030 \ - .fw_name_pre = IWL2030_FW_PRE, \ - .ucode_api_max = IWL2030_UCODE_API_MAX, \ - .ucode_api_ok = IWL2030_UCODE_API_OK, \ - .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true - -const struct iwl_cfg iwl2030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", - IWL_DEVICE_2030, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_105 \ - .fw_name_pre = IWL105_FW_PRE, \ - .ucode_api_max = IWL105_UCODE_API_MAX, \ - .ucode_api_ok = IWL105_UCODE_API_OK, \ - .ucode_api_min = IWL105_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_105, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl105_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", - IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, -}; - -const struct iwl_cfg iwl105_bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", - IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_135 \ - .fw_name_pre = IWL135_FW_PRE, \ - .ucode_api_max = IWL135_UCODE_API_MAX, \ - .ucode_api_ok = IWL135_UCODE_API_OK, \ - .ucode_api_min = IWL135_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_135, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl135_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", - IWL_DEVICE_135, - .ht_params = &iwl2000_ht_params, -}; - -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c deleted file mode 100644 index 5096f7c96ab6..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ /dev/null @@ -1,180 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "iwl-csr.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 5 -#define IWL5150_UCODE_API_MAX 2 - -/* Oldest version we won't warn about */ -#define IWL5000_UCODE_API_OK 5 -#define IWL5150_UCODE_API_OK 2 - -/* Lowest firmware API version supported */ -#define IWL5000_UCODE_API_MIN 1 -#define IWL5150_UCODE_API_MIN 1 - -/* EEPROM versions */ -#define EEPROM_5000_TX_POWER_VERSION (4) -#define EEPROM_5000_EEPROM_VERSION (0x11A) -#define EEPROM_5050_TX_POWER_VERSION (4) -#define EEPROM_5050_EEPROM_VERSION (0x21E) - -#define IWL5000_FW_PRE "iwlwifi-5000-" -#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" - -#define IWL5150_FW_PRE "iwlwifi-5150-" -#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl5000_base_params = { - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .led_compensation = 51, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHDOG_DISABLED, - .max_event_log_size = 512, - .no_idle_support = true, -}; - -static const struct iwl_ht_params iwl5000_ht_params = { - .ht_greenfield_support = true, - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -static const struct iwl_eeprom_params iwl5000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, -}; - -#define IWL_DEVICE_5000 \ - .fw_name_pre = IWL5000_FW_PRE, \ - .ucode_api_max = IWL5000_UCODE_API_MAX, \ - .ucode_api_ok = IWL5000_UCODE_API_OK, \ - .ucode_api_min = IWL5000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5000, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_params, \ - .eeprom_params = &iwl5000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl5300_agn_cfg = { - .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", - IWL_DEVICE_5000, - /* at least EEPROM 0x11A has wrong info */ - .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ - .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5100_bgn_cfg = { - .name = "Intel(R) WiFi Link 5100 BGN", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5100_abg_cfg = { - .name = "Intel(R) WiFi Link 5100 ABG", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ -}; - -const struct iwl_cfg iwl5100_agn_cfg = { - .name = "Intel(R) WiFi Link 5100 AGN", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5350_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_ok = IWL5000_UCODE_API_OK, - .ucode_api_min = IWL5000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_5000, - .max_inst_size = IWLAGN_RTC_INST_SIZE, - .max_data_size = IWLAGN_RTC_DATA_SIZE, - .nvm_ver = EEPROM_5050_EEPROM_VERSION, - .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .base_params = &iwl5000_base_params, - .eeprom_params = &iwl5000_eeprom_params, - .ht_params = &iwl5000_ht_params, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, -}; - -#define IWL_DEVICE_5150 \ - .fw_name_pre = IWL5150_FW_PRE, \ - .ucode_api_max = IWL5150_UCODE_API_MAX, \ - .ucode_api_ok = IWL5150_UCODE_API_OK, \ - .ucode_api_min = IWL5150_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5150, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_params, \ - .eeprom_params = &iwl5000_eeprom_params, \ - .no_xtal_calib = true, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl5150_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", - IWL_DEVICE_5150, - .ht_params = &iwl5000_ht_params, - -}; - -const struct iwl_cfg iwl5150_abg_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", - IWL_DEVICE_5150, -}; - -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c deleted file mode 100644 index 801ff49796dd..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ /dev/null @@ -1,403 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" -#include "dvm/commands.h" /* needed for BT for now */ - -/* Highest firmware API version supported */ -#define IWL6000_UCODE_API_MAX 6 -#define IWL6050_UCODE_API_MAX 5 -#define IWL6000G2_UCODE_API_MAX 6 -#define IWL6035_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL6000_UCODE_API_OK 4 -#define IWL6000G2_UCODE_API_OK 5 -#define IWL6050_UCODE_API_OK 5 -#define IWL6000G2B_UCODE_API_OK 6 -#define IWL6035_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL6000_UCODE_API_MIN 4 -#define IWL6050_UCODE_API_MIN 4 -#define IWL6000G2_UCODE_API_MIN 5 -#define IWL6035_UCODE_API_MIN 6 - -/* EEPROM versions */ -#define EEPROM_6000_TX_POWER_VERSION (4) -#define EEPROM_6000_EEPROM_VERSION (0x423) -#define EEPROM_6050_TX_POWER_VERSION (4) -#define EEPROM_6050_EEPROM_VERSION (0x532) -#define EEPROM_6150_TX_POWER_VERSION (6) -#define EEPROM_6150_EEPROM_VERSION (0x553) -#define EEPROM_6005_TX_POWER_VERSION (6) -#define EEPROM_6005_EEPROM_VERSION (0x709) -#define EEPROM_6030_TX_POWER_VERSION (6) -#define EEPROM_6030_EEPROM_VERSION (0x709) -#define EEPROM_6035_TX_POWER_VERSION (6) -#define EEPROM_6035_EEPROM_VERSION (0x753) - -#define IWL6000_FW_PRE "iwlwifi-6000-" -#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" - -#define IWL6050_FW_PRE "iwlwifi-6050-" -#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode" - -#define IWL6005_FW_PRE "iwlwifi-6000g2a-" -#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode" - -#define IWL6030_FW_PRE "iwlwifi-6000g2b-" -#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl6000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_base_params iwl6050_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 1024, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_base_params iwl6000_g2_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_ht_params iwl6000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -static const struct iwl_bt_params iwl6000_bt_params = { - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .advanced_bt_coexist = true, - .agg_time_limit = BT_AGG_THRESHOLD_DEF, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, - .bt_sco_disable = true, -}; - -static const struct iwl_eeprom_params iwl6000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - .enhanced_txpower = true, -}; - -#define IWL_DEVICE_6005 \ - .fw_name_pre = IWL6005_FW_PRE, \ - .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ - .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6005, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE - -const struct iwl_cfg iwl6005_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", - IWL_DEVICE_6005, -}; - -const struct iwl_cfg iwl6005_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", - IWL_DEVICE_6005, -}; - -const struct iwl_cfg iwl6005_2agn_sff_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_d_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_mow1_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_mow2_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -#define IWL_DEVICE_6030 \ - .fw_name_pre = IWL6030_FW_PRE, \ - .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ - .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .bt_params = &iwl6000_bt_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - -const struct iwl_cfg iwl6030_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6030_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", - IWL_DEVICE_6030, -}; - -const struct iwl_cfg iwl6030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6030_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", - IWL_DEVICE_6030, -}; - -#define IWL_DEVICE_6035 \ - .fw_name_pre = IWL6030_FW_PRE, \ - .ucode_api_max = IWL6035_UCODE_API_MAX, \ - .ucode_api_ok = IWL6035_UCODE_API_OK, \ - .ucode_api_min = IWL6035_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .bt_params = &iwl6000_bt_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true - -const struct iwl_cfg iwl6035_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", - IWL_DEVICE_6035, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl1030_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl1030_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", - IWL_DEVICE_6030, -}; - -const struct iwl_cfg iwl130_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, - .rx_with_siso_diversity = true, -}; - -const struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BG", - IWL_DEVICE_6030, - .rx_with_siso_diversity = true, -}; - -/* - * "i": Internal configuration, use internal Power Amplifier - */ -#define IWL_DEVICE_6000i \ - .fw_name_pre = IWL6000_FW_PRE, \ - .ucode_api_max = IWL6000_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000_UCODE_API_OK, \ - .ucode_api_min = IWL6000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6000i, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ - .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ - .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ - .base_params = &iwl6000_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl6000i_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", - IWL_DEVICE_6000i, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6000i_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", - IWL_DEVICE_6000i, -}; - -const struct iwl_cfg iwl6000i_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", - IWL_DEVICE_6000i, -}; - -#define IWL_DEVICE_6050 \ - .fw_name_pre = IWL6050_FW_PRE, \ - .ucode_api_max = IWL6050_UCODE_API_MAX, \ - .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6050, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ - .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl6050_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", - IWL_DEVICE_6050, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6050_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", - IWL_DEVICE_6050, -}; - -#define IWL_DEVICE_6150 \ - .fw_name_pre = IWL6050_FW_PRE, \ - .ucode_api_max = IWL6050_UCODE_API_MAX, \ - .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6150, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl6150_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", - IWL_DEVICE_6150, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6150_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", - IWL_DEVICE_6150, -}; - -const struct iwl_cfg iwl6000_3agn_cfg = { - .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", - .fw_name_pre = IWL6000_FW_PRE, - .ucode_api_max = IWL6000_UCODE_API_MAX, - .ucode_api_ok = IWL6000_UCODE_API_OK, - .ucode_api_min = IWL6000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_6000, - .max_inst_size = IWL60_RTC_INST_SIZE, - .max_data_size = IWL60_RTC_DATA_SIZE, - .nvm_ver = EEPROM_6000_EEPROM_VERSION, - .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .base_params = &iwl6000_base_params, - .eeprom_params = &iwl6000_eeprom_params, - .ht_params = &iwl6000_ht_params, - .led_mode = IWL_LED_BLINK, -}; - -MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c deleted file mode 100644 index a5e9cfe3e746..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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. - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL7260_UCODE_API_MAX 6 -#define IWL3160_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL7260_UCODE_API_OK 6 -#define IWL3160_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL7260_UCODE_API_MIN 6 -#define IWL3160_UCODE_API_MIN 6 - -/* NVM versions */ -#define IWL7260_NVM_VERSION 0x0a1d -#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ -#define IWL3160_NVM_VERSION 0x709 -#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ - -#define IWL7260_FW_PRE "iwlwifi-7260-" -#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" - -#define IWL3160_FW_PRE "iwlwifi-3160-" -#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl7000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_ht_params iwl7000_ht_params = { - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -#define IWL_DEVICE_7000 \ - .ucode_api_max = IWL7260_UCODE_API_MAX, \ - .ucode_api_ok = IWL7260_UCODE_API_OK, \ - .ucode_api_min = IWL7260_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_7000, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .base_params = &iwl7000_base_params, \ - /* TODO: .bt_params? */ \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - - -const struct iwl_cfg iwl7260_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC7260", - .fw_name_pre = IWL7260_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL7260_NVM_VERSION, - .nvm_calib_ver = IWL7260_TX_POWER_VERSION, -}; - -const struct iwl_cfg iwl3160_ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC3160", - .fw_name_pre = IWL3160_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL3160_NVM_VERSION, - .nvm_calib_ver = IWL3160_TX_POWER_VERSION, -}; - -MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); -MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h deleted file mode 100644 index f4318fb192df..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/cfg.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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. - * - *****************************************************************************/ -#ifndef __iwl_pci_h__ -#define __iwl_pci_h__ - - -/* - * This file declares the config structures for all devices. - */ - -extern const struct iwl_cfg iwl5300_agn_cfg; -extern const struct iwl_cfg iwl5100_agn_cfg; -extern const struct iwl_cfg iwl5350_agn_cfg; -extern const struct iwl_cfg iwl5100_bgn_cfg; -extern const struct iwl_cfg iwl5100_abg_cfg; -extern const struct iwl_cfg iwl5150_agn_cfg; -extern const struct iwl_cfg iwl5150_abg_cfg; -extern const struct iwl_cfg iwl6005_2agn_cfg; -extern const struct iwl_cfg iwl6005_2abg_cfg; -extern const struct iwl_cfg iwl6005_2bg_cfg; -extern const struct iwl_cfg iwl6005_2agn_sff_cfg; -extern const struct iwl_cfg iwl6005_2agn_d_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; -extern const struct iwl_cfg iwl1030_bgn_cfg; -extern const struct iwl_cfg iwl1030_bg_cfg; -extern const struct iwl_cfg iwl6030_2agn_cfg; -extern const struct iwl_cfg iwl6030_2abg_cfg; -extern const struct iwl_cfg iwl6030_2bgn_cfg; -extern const struct iwl_cfg iwl6030_2bg_cfg; -extern const struct iwl_cfg iwl6000i_2agn_cfg; -extern const struct iwl_cfg iwl6000i_2abg_cfg; -extern const struct iwl_cfg iwl6000i_2bg_cfg; -extern const struct iwl_cfg iwl6000_3agn_cfg; -extern const struct iwl_cfg iwl6050_2agn_cfg; -extern const struct iwl_cfg iwl6050_2abg_cfg; -extern const struct iwl_cfg iwl6150_bgn_cfg; -extern const struct iwl_cfg iwl6150_bg_cfg; -extern const struct iwl_cfg iwl1000_bgn_cfg; -extern const struct iwl_cfg iwl1000_bg_cfg; -extern const struct iwl_cfg iwl100_bgn_cfg; -extern const struct iwl_cfg iwl100_bg_cfg; -extern const struct iwl_cfg iwl130_bgn_cfg; -extern const struct iwl_cfg iwl130_bg_cfg; -extern const struct iwl_cfg iwl2000_2bgn_cfg; -extern const struct iwl_cfg iwl2000_2bgn_d_cfg; -extern const struct iwl_cfg iwl2030_2bgn_cfg; -extern const struct iwl_cfg iwl6035_2agn_cfg; -extern const struct iwl_cfg iwl105_bgn_cfg; -extern const struct iwl_cfg iwl105_bgn_d_cfg; -extern const struct iwl_cfg iwl135_bgn_cfg; -extern const struct iwl_cfg iwl7260_2ac_cfg; -extern const struct iwl_cfg iwl3160_ac_cfg; - -#endif /* __iwl_pci_h__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 49b254326d9c..46ca91f77c9c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -69,8 +69,6 @@ #include "iwl-trans.h" #include "iwl-drv.h" - -#include "cfg.h" #include "internal.h" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ -- cgit From 506a81e6ba1148a4435dec95651cd93874c2b7cf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 28 Feb 2013 14:05:14 +0100 Subject: iwlwifi: mvm: don't read system time when modifying AP/GO MAC When modifying a MAC, we update its beacon system time which is taken as a base to calculate TBTT. The firmware doesn't use the new timestamp because the time is never used after the MAC and broadcast station were added, but it is safer to not rely on this and avoids the overhead of reading the register every time the MAC is updated. Reviewed-by: Emmanuel Grumbach Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 25 ++++++++++++++++++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index a993f6c7dac0..2779235daa35 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -855,10 +855,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, */ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_data_ap *ctxt_ap) + struct iwl_mac_data_ap *ctxt_ap, + bool add) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - u32 curr_dev_time; ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); ctxt_ap->bi_reciprocal = @@ -870,10 +870,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, vif->bss_conf.dtim_period)); ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); - curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); - ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time); - ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); + /* + * Only read the system time when the MAC is being added, when we + * just modify the MAC then we should keep the time -- the firmware + * can otherwise have a "jumping" TBTT. + */ + if (add) + mvmvif->ap_beacon_time = + iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); + + ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); + + ctxt_ap->beacon_tsf = 0; /* unused */ /* TODO: Assume that the beacon id == mac context id */ ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); @@ -894,7 +903,8 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); /* Fill the data specific for ap mode */ - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, + action == FW_CTXT_ACTION_ADD); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } @@ -911,7 +921,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); /* Fill the data specific for GO mode */ - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, + action == FW_CTXT_ACTION_ADD); cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index efe5da992897..234c5726d196 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -174,6 +174,8 @@ struct iwl_mvm_vif { bool uploaded; bool ap_active; + u32 ap_beacon_time; + enum iwl_tsf_id tsf_id; /* -- cgit From 1fd4afe2d13588f935d9f8642a696f84aa1f03d1 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 10:18:07 +0200 Subject: iwlwifi: mvm: Change NVM default section read size Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/nvm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 555095cf4afc..93e3d0f174cc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -74,6 +74,9 @@ static const int nvm_to_read[] = { NVM_SECTION_TYPE_PRODUCTION, }; +/* Default NVM size to read */ +#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); + /* used to simplify the shared operations on NCM_ACCESS_CMD versions */ union iwl_nvm_access_cmd { struct iwl_nvm_access_cmd_ver1 ver1; @@ -193,9 +196,9 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, int ret; bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; - length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) - - sizeof(union iwl_nvm_access_cmd) - - sizeof(struct iwl_rx_packet); + /* Set nvm section read length */ + length = IWL_NVM_DEFAULT_CHUNK_SIZE; + /* * if length is greater than EEPROM size, truncate it because uCode * doesn't check it by itself, and exit the loop when reached. -- cgit From 1218206e9d642f63801417156be46d8d0175164a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Mar 2013 00:05:26 +0100 Subject: iwlwifi: allow selecting only MVM driver Now that we have two drivers (DVM and MVM) stop selecting the DVM one (but make it default) and allow enabling only the MVM driver if so desired. Add a warning for the case of having neither DVM nor MVM enabled -- that's useless. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ba319cba3f1e..615ed10825b8 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -6,7 +6,6 @@ config IWLWIFI select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS - select IWLDVM ---help--- Select to build the driver supporting the: @@ -45,6 +44,7 @@ config IWLWIFI config IWLDVM tristate "Intel Wireless WiFi DVM Firmware support" depends on IWLWIFI + default IWLWIFI help This is the driver supporting the DVM firmware which is currently the only firmware available for existing devices. @@ -58,6 +58,9 @@ config IWLMVM Say yes if you have such a device. +comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" + depends on IWLWIFI && IWLDVM=n && IWLMVM=n + menu "Debugging Options" depends on IWLWIFI -- cgit From 48e29340d54104ab0d8f995f32485e28ff00e59e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Mar 2013 00:13:33 +0100 Subject: iwlwifi: export symbols only conditionally If all the pieces of iwlwifi are built into the kernel then there's no need for it to export its symbols to other modules, so prevent that. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Kconfig | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-debug.c | 11 ++++++----- drivers/net/wireless/iwlwifi/iwl-drv.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-drv.h | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-io.c | 19 ++++++++++--------- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 13 +++++++------ drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-test.c | 9 +++++---- 11 files changed, 64 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 615ed10825b8..56c2040a955b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -58,6 +58,12 @@ config IWLMVM Say yes if you have such a device. +# don't call it _MODULE -- will confuse Kconfig/fixdep/... +config IWLWIFI_OPMODE_MODULAR + bool + default y if IWLDVM=m + default y if IWLMVM=m + comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" depends on IWLWIFI && IWLDVM=n && IWLMVM=n diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 88df574e33de..8a44f594528d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -66,6 +66,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-debug.h" #include "iwl-devtrace.h" @@ -85,11 +86,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ } __iwl_fn(warn) -EXPORT_SYMBOL_GPL(__iwl_warn); +IWL_EXPORT_SYMBOL(__iwl_warn); __iwl_fn(info) -EXPORT_SYMBOL_GPL(__iwl_info); +IWL_EXPORT_SYMBOL(__iwl_info); __iwl_fn(crit) -EXPORT_SYMBOL_GPL(__iwl_crit); +IWL_EXPORT_SYMBOL(__iwl_crit); void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, const char *fmt, ...) @@ -110,7 +111,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, trace_iwlwifi_err(&vaf); va_end(args); } -EXPORT_SYMBOL_GPL(__iwl_err); +IWL_EXPORT_SYMBOL(__iwl_err); #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) void __iwl_dbg(struct device *dev, @@ -133,5 +134,5 @@ void __iwl_dbg(struct device *dev, trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); va_end(args); } -EXPORT_SYMBOL_GPL(__iwl_dbg); +IWL_EXPORT_SYMBOL(__iwl_dbg); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 8620de406f64..15ac54baa833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1111,7 +1111,7 @@ struct iwl_mod_params iwlwifi_mod_params = { .wd_disable = true, /* the rest are 0 by default */ }; -EXPORT_SYMBOL_GPL(iwlwifi_mod_params); +IWL_EXPORT_SYMBOL(iwlwifi_mod_params); int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) { @@ -1135,7 +1135,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) mutex_unlock(&iwlwifi_opmode_table_mtx); return -EIO; } -EXPORT_SYMBOL_GPL(iwl_opmode_register); +IWL_EXPORT_SYMBOL(iwl_opmode_register); void iwl_opmode_deregister(const char *name) { @@ -1157,7 +1157,7 @@ void iwl_opmode_deregister(const char *name) } mutex_unlock(&iwlwifi_opmode_table_mtx); } -EXPORT_SYMBOL_GPL(iwl_opmode_deregister); +IWL_EXPORT_SYMBOL(iwl_opmode_deregister); static int __init iwl_drv_init(void) { diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 4c96472ac3ea..7d1450916308 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -63,6 +63,8 @@ #ifndef __iwl_drv_h__ #define __iwl_drv_h__ +#include + /* for all modules */ #define DRV_NAME "iwlwifi" #define IWLWIFI_VERSION "in-tree:" @@ -123,4 +125,17 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, */ void iwl_drv_stop(struct iwl_drv *drv); +/* + * exported symbol management + * + * The driver can be split into multiple modules, in which case some symbols + * must be exported for the sub-modules. However, if it's not split and + * everything is built-in, then we can avoid that. + */ +#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR +#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym) +#else +#define IWL_EXPORT_SYMBOL(sym) +#endif + #endif /* __iwl_drv_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index e170f5e6ee7a..600c9fdd7f71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -62,6 +62,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-modparams.h" #include "iwl-eeprom-parse.h" @@ -909,7 +910,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, kfree(data); return NULL; } -EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); +IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data); /* helper functions */ int iwl_nvm_check_version(struct iwl_nvm_data *data, @@ -928,4 +929,4 @@ int iwl_nvm_check_version(struct iwl_nvm_data *data, data->calib_version, trans->cfg->nvm_calib_ver); return -EINVAL; } -EXPORT_SYMBOL_GPL(iwl_nvm_check_version); +IWL_EXPORT_SYMBOL(iwl_nvm_check_version); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index 92e7245ced8d..e5f2e362ab0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -63,6 +63,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-debug.h" #include "iwl-eeprom-read.h" #include "iwl-io.h" @@ -460,4 +461,4 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) return ret; } -EXPORT_SYMBOL_GPL(iwl_read_eeprom); +IWL_EXPORT_SYMBOL(iwl_read_eeprom); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 276410d82de4..305c81f2c2b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -29,6 +29,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-io.h" #include "iwl-csr.h" #include "iwl-debug.h" @@ -49,7 +50,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, return -ETIMEDOUT; } -EXPORT_SYMBOL_GPL(iwl_poll_bit); +IWL_EXPORT_SYMBOL(iwl_poll_bit); u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { @@ -62,7 +63,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) return value; } -EXPORT_SYMBOL_GPL(iwl_read_direct32); +IWL_EXPORT_SYMBOL(iwl_read_direct32); void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { @@ -73,7 +74,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_write_direct32); +IWL_EXPORT_SYMBOL(iwl_write_direct32); int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) @@ -89,7 +90,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, return -ETIMEDOUT; } -EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); +IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) { @@ -115,7 +116,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) } return val; } -EXPORT_SYMBOL_GPL(iwl_read_prph); +IWL_EXPORT_SYMBOL(iwl_read_prph); void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) { @@ -126,7 +127,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_write_prph); +IWL_EXPORT_SYMBOL(iwl_write_prph); void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) { @@ -138,7 +139,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_set_bits_prph); +IWL_EXPORT_SYMBOL(iwl_set_bits_prph); void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, u32 bits, u32 mask) @@ -151,7 +152,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); +IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) { @@ -164,4 +165,4 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); +IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 721fc64dd44b..940b8a9d5285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -63,6 +63,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-notif-wait.h" @@ -72,7 +73,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) INIT_LIST_HEAD(¬if_wait->notif_waits); init_waitqueue_head(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_notification_wait_init); +IWL_EXPORT_SYMBOL(iwl_notification_wait_init); void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt) @@ -117,7 +118,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, if (triggered) wake_up_all(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); +IWL_EXPORT_SYMBOL(iwl_notification_wait_notify); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) { @@ -130,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) wake_up_all(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); +IWL_EXPORT_SYMBOL(iwl_abort_notification_waits); void iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, @@ -154,7 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, list_add(&wait_entry->list, ¬if_wait->notif_waits); spin_unlock_bh(¬if_wait->notif_wait_lock); } -EXPORT_SYMBOL_GPL(iwl_init_notification_wait); +IWL_EXPORT_SYMBOL(iwl_init_notification_wait); int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry, @@ -178,7 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, return -ETIMEDOUT; return 0; } -EXPORT_SYMBOL_GPL(iwl_wait_notification); +IWL_EXPORT_SYMBOL(iwl_wait_notification); void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry) @@ -187,4 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, list_del(&wait_entry->list); spin_unlock_bh(¬if_wait->notif_wait_lock); } -EXPORT_SYMBOL_GPL(iwl_remove_notification); +IWL_EXPORT_SYMBOL(iwl_remove_notification); diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 1ae6f2c1558d..6199a0a597a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -62,6 +62,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-modparams.h" #include "iwl-nvm-parse.h" @@ -389,4 +390,4 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, return data; } -EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); +IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 31c05487a688..25745daa0d5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -65,6 +65,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-phy-db.h" #include "iwl-debug.h" #include "iwl-op-mode.h" @@ -149,7 +150,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) /* TODO: add default values of the phy db. */ return phy_db; } -EXPORT_SYMBOL(iwl_phy_db_init); +IWL_EXPORT_SYMBOL(iwl_phy_db_init); /* * get phy db section: returns a pointer to a phy db section specified by @@ -215,7 +216,7 @@ void iwl_phy_db_free(struct iwl_phy_db *phy_db) kfree(phy_db); } -EXPORT_SYMBOL(iwl_phy_db_free); +IWL_EXPORT_SYMBOL(iwl_phy_db_free); int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, gfp_t alloc_ctx) @@ -260,7 +261,7 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, return 0; } -EXPORT_SYMBOL(iwl_phy_db_set_section); +IWL_EXPORT_SYMBOL(iwl_phy_db_set_section); static int is_valid_channel(u16 ch_id) { @@ -495,4 +496,4 @@ int iwl_send_phy_db_data(struct iwl_phy_db *phy_db) "Finished sending phy db non channel data\n"); return 0; } -EXPORT_SYMBOL(iwl_send_phy_db_data); +IWL_EXPORT_SYMBOL(iwl_send_phy_db_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index a7cbf7906200..efff2986b5b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -64,6 +64,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-io.h" #include "iwl-fh.h" #include "iwl-prph.h" @@ -653,7 +654,7 @@ int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, } return 0; } -EXPORT_SYMBOL_GPL(iwl_test_parse); +IWL_EXPORT_SYMBOL(iwl_test_parse); /* * Handle test commands. @@ -715,7 +716,7 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb) } return result; } -EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); +IWL_EXPORT_SYMBOL(iwl_test_handle_cmd); static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, struct netlink_callback *cb) @@ -803,7 +804,7 @@ int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, } return result; } -EXPORT_SYMBOL_GPL(iwl_test_dump); +IWL_EXPORT_SYMBOL(iwl_test_dump); /* * Multicast a spontaneous messages from the device to the user space. @@ -849,4 +850,4 @@ void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) if (tst->notify) iwl_test_send_rx(tst, rxb); } -EXPORT_SYMBOL_GPL(iwl_test_rx); +IWL_EXPORT_SYMBOL(iwl_test_rx); -- cgit From 3b4612fbd3a571b4f37e87fcd66c9b4d213341f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 09:14:51 +0200 Subject: iwlwifi: mvm: add CARD_STATE_NOTIFICATION to the cmd strings Then the transport can print it nicely in its debug prints. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 473864733aab..dda699e1c996 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -293,6 +293,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(NET_DETECT_PROFILES_CMD), CMD(NET_DETECT_HOTSPOTS_CMD), CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), + CMD(CARD_STATE_NOTIFICATION), }; #undef CMD -- cgit From fb3ceb817503f3d89e3beb4f48a2f4d608a6697f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 14 Jan 2013 15:04:01 +0200 Subject: iwlwifi: mvm: add BT Coex FW API This is the API to tell the fw to handle the BT Coexistence. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h | 319 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw-api.h | 7 + drivers/net/wireless/iwlwifi/mvm/ops.c | 4 + 3 files changed, 330 insertions(+) create mode 100644 drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h new file mode 100644 index 000000000000..05c61d6f384e --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h @@ -0,0 +1,319 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + *****************************************************************************/ + +#ifndef __fw_api_bt_coex_h__ +#define __fw_api_bt_coex_h__ + +#include +#include + +#define BITS(nb) (BIT(nb) - 1) + +/** + * enum iwl_bt_coex_flags - flags for BT_COEX command + * @BT_CH_PRIMARY_EN: + * @BT_CH_SECONDARY_EN: + * @BT_NOTIF_COEX_OFF: + * @BT_COEX_MODE_POS: + * @BT_COEX_MODE_MSK: + * @BT_COEX_DISABLE: + * @BT_COEX_2W: + * @BT_COEX_3W: + * @BT_COEX_NW: + * @BT_USE_DEFAULTS: + * @BT_SYNC_2_BT_DISABLE: + * @BT_COEX_CORUNNING_TBL_EN: + */ +enum iwl_bt_coex_flags { + BT_CH_PRIMARY_EN = BIT(0), + BT_CH_SECONDARY_EN = BIT(1), + BT_NOTIF_COEX_OFF = BIT(2), + BT_COEX_MODE_POS = 3, + BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS, + BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS, + BT_COEX_2W = 0x1 << BT_COEX_MODE_POS, + BT_COEX_3W = 0x2 << BT_COEX_MODE_POS, + BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, + BT_USE_DEFAULTS = BIT(6), + BT_SYNC_2_BT_DISABLE = BIT(7), + /* + * For future use - when the flags will be enlarged + * BT_COEX_CORUNNING_TBL_EN = BIT(8), + */ +}; + +/* + * indicates what has changed in the BT_COEX command. + */ +enum iwl_bt_coex_valid_bit_msk { + BT_VALID_ENABLE = BIT(0), + BT_VALID_BT_PRIO_BOOST = BIT(1), + BT_VALID_MAX_KILL = BIT(2), + BT_VALID_3W_TMRS = BIT(3), + BT_VALID_KILL_ACK = BIT(4), + BT_VALID_KILL_CTS = BIT(5), + BT_VALID_REDUCED_TX_POWER = BIT(6), + BT_VALID_LUT = BIT(7), + BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8), + BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9), + BT_VALID_MULTI_PRIO_LUT = BIT(10), + BT_VALID_TRM_KICK_FILTER = BIT(11), + BT_VALID_CORUN_LUT_20 = BIT(12), + BT_VALID_CORUN_LUT_40 = BIT(13), + BT_VALID_ANT_ISOLATION = BIT(14), + BT_VALID_ANT_ISOLATION_THRS = BIT(15), + /* + * For future use - when the valid flags will be enlarged + * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), + * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), + */ +}; + +/** + * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames. + * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames + * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames + * + * This mechanism allows to have BT and WiFi run concurrently. Since WiFi + * reduces its Tx power, it can work along with BT, hence reducing the amount + * of WiFi frames being killed by BT. + */ +enum iwl_bt_reduced_tx_power { + BT_REDUCED_TX_POWER_CTL = BIT(0), + BT_REDUCED_TX_POWER_DATA = BIT(1), +}; + +#define BT_COEX_LUT_SIZE (12) + +/** + * struct iwl_bt_coex_cmd - bt coex configuration command + * @flags:&enum iwl_bt_coex_flags + * @lead_time: + * @max_kill: + * @bt3_time_t7_value: + * @kill_ack_msk: + * @kill_cts_msk: + * @bt3_prio_sample_time: + * @bt3_timer_t2_value: + * @bt4_reaction_time: + * @decision_lut[12]: + * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power + * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk + * @bt_prio_boost: values for PTA boost register + * @wifi_tx_prio_boost: SW boost of wifi tx priority + * @wifi_rx_prio_boost: SW boost of wifi rx priority + * + * The structure is used for the BT_COEX command. + */ +struct iwl_bt_coex_cmd { + u8 flags; + u8 lead_time; + u8 max_kill; + u8 bt3_time_t7_value; + __le32 kill_ack_msk; + __le32 kill_cts_msk; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; + __le32 decision_lut[BT_COEX_LUT_SIZE]; + u8 bt_reduced_tx_power; + u8 reserved; + __le16 valid_bit_msk; + __le32 bt_prio_boost; + u8 reserved2; + u8 wifi_tx_prio_boost; + __le16 wifi_rx_prio_boost; +} __packed; /* BT_COEX_CMD_API_S_VER_3 */ + +#define BT_MBOX(n_dw, _msg, _pos, _nbits) \ + BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ + BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS + +enum iwl_bt_mxbox_dw0 { + BT_MBOX(0, LE_SLAVE_LAT, 0, 3), + BT_MBOX(0, LE_PROF1, 3, 1), + BT_MBOX(0, LE_PROF2, 4, 1), + BT_MBOX(0, LE_PROF_OTHER, 5, 1), + BT_MBOX(0, CHL_SEQ_N, 8, 4), + BT_MBOX(0, INBAND_S, 13, 1), + BT_MBOX(0, LE_MIN_RSSI, 16, 4), + BT_MBOX(0, LE_SCAN, 20, 1), + BT_MBOX(0, LE_ADV, 21, 1), + BT_MBOX(0, LE_MAX_TX_POWER, 24, 4), + BT_MBOX(0, OPEN_CON_1, 28, 2), +}; + +enum iwl_bt_mxbox_dw1 { + BT_MBOX(1, BR_MAX_TX_POWER, 0, 4), + BT_MBOX(1, IP_SR, 4, 1), + BT_MBOX(1, LE_MSTR, 5, 1), + BT_MBOX(1, AGGR_TRFC_LD, 8, 6), + BT_MBOX(1, MSG_TYPE, 16, 3), + BT_MBOX(1, SSN, 19, 2), +}; + +enum iwl_bt_mxbox_dw2 { + BT_MBOX(2, SNIFF_ACT, 0, 3), + BT_MBOX(2, PAG, 3, 1), + BT_MBOX(2, INQUIRY, 4, 1), + BT_MBOX(2, CONN, 5, 1), + BT_MBOX(2, SNIFF_INTERVAL, 8, 5), + BT_MBOX(2, DISC, 13, 1), + BT_MBOX(2, SCO_TX_ACT, 16, 2), + BT_MBOX(2, SCO_RX_ACT, 18, 2), + BT_MBOX(2, ESCO_RE_TX, 20, 2), + BT_MBOX(2, SCO_DURATION, 24, 6), +}; + +enum iwl_bt_mxbox_dw3 { + BT_MBOX(3, SCO_STATE, 0, 1), + BT_MBOX(3, SNIFF_STATE, 1, 1), + BT_MBOX(3, A2DP_STATE, 2, 1), + BT_MBOX(3, ACL_STATE, 3, 1), + BT_MBOX(3, MSTR_STATE, 4, 1), + BT_MBOX(3, OBX_STATE, 5, 1), + BT_MBOX(3, OPEN_CON_2, 8, 2), + BT_MBOX(3, TRAFFIC_LOAD, 10, 2), + BT_MBOX(3, CHL_SEQN_LSB, 12, 1), + BT_MBOX(3, INBAND_P, 13, 1), + BT_MBOX(3, MSG_TYPE_2, 16, 3), + BT_MBOX(3, SSN_2, 19, 2), + BT_MBOX(3, UPDATE_REQUEST, 21, 1), +}; + +#define BT_MBOX_MSG(_notif, _num, _field) \ + ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ + >> BT_MBOX##_num##_##_field##_POS) + +/** + * struct iwl_bt_coex_profile_notif - notification about BT coex + * @mbox_msg: message from BT to WiFi + * @:bt_status: 0 - off, 1 - on + * @:bt_open_conn: number of BT connections open + * @:bt_traffic_load: load of BT traffic + * @:bt_agg_traffic_load: aggregated load of BT traffic + * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant + */ +struct iwl_bt_coex_profile_notif { + __le32 mbox_msg[4]; + u8 bt_status; + u8 bt_open_conn; + u8 bt_traffic_load; + u8 bt_agg_traffic_load; + u8 bt_ci_compliance; + u8 reserved[3]; +} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ + +enum iwl_bt_coex_prio_table_event { + BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, + BT_COEX_PRIO_TBL_EVT_DTIM = 6, + BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, + BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, + BT_COEX_PRIO_TBL_EVT_IDLE = 9, + BT_COEX_PRIO_TBL_EVT_MAX = 16, +}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */ + +enum iwl_bt_coex_prio_table_prio { + BT_COEX_PRIO_TBL_DISABLED = 0, + BT_COEX_PRIO_TBL_PRIO_LOW = 1, + BT_COEX_PRIO_TBL_PRIO_HIGH = 2, + BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, + BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, + BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6, + BT_COEX_PRIO_TBL_MAX = 8, +}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */ + +#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0) +#define BT_COEX_PRIO_TBL_PRIO_POS (1) +#define BT_COEX_PRIO_TBL_RESERVED_POS (4) + +/** + * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex + * @prio_tbl: + */ +struct iwl_bt_coex_prio_tbl_cmd { + u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; +} __packed; + +enum iwl_bt_coex_env_action { + BT_COEX_ENV_CLOSE = 0, + BT_COEX_ENV_OPEN = 1, +}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */ + +/** + * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope + * @action: enum %iwl_bt_coex_env_action + * @type: enum %iwl_bt_coex_prio_table_event + */ +struct iwl_bt_coex_prot_env_cmd { + u8 action; /* 0 = closed, 1 = open */ + u8 type; /* 0 .. 15 */ + u8 reserved[2]; +} __packed; + +#endif /* __fw_api_bt_coex_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 92cd982f6b27..da9ee3fe3379 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -70,6 +70,7 @@ #include "fw-api-mac.h" #include "fw-api-power.h" #include "fw-api-d3.h" +#include "fw-api-bt-coex.h" /* queue and FIFO numbers by usage */ enum { @@ -152,6 +153,7 @@ enum { BEACON_TEMPLATE_CMD = 0x91, TX_ANT_CONFIGURATION_CMD = 0x98, + BT_CONFIG = 0x9b, STATISTICS_NOTIFICATION = 0x9d, /* RF-KILL commands and notifications */ @@ -162,6 +164,11 @@ enum { REPLY_RX_MPDU_CMD = 0xc1, BA_NOTIF = 0xc5, + /* BT Coex */ + BT_COEX_PRIO_TABLE = 0xcc, + BT_COEX_PROT_ENV = 0xcd, + BT_PROFILE_NOTIFICATION = 0xce, + REPLY_DEBUG_CMD = 0xf0, DEBUG_LOG_MSG = 0xf7, diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index dda699e1c996..2003daa0cf76 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -294,6 +294,10 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(NET_DETECT_HOTSPOTS_CMD), CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), CMD(CARD_STATE_NOTIFICATION), + CMD(BT_COEX_PRIO_TABLE), + CMD(BT_COEX_PROT_ENV), + CMD(BT_PROFILE_NOTIFICATION), + CMD(BT_CONFIG), }; #undef CMD -- cgit From 931d416049cdb6e8382792231317f76be0d922ce Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 17 Jan 2013 09:42:25 +0200 Subject: iwlwifi: mvm: begin basic BT-Coex implementation Send the PRIO table before the calibrations. This table tells the fw what priority to give to what (WiFi / BT) according to events. Send a hardcoded BT_COEX command to the fw to enable basic BT coexistence. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/Makefile | 2 +- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 242 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw.c | 12 ++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 + 4 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/bt-coex.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile index 807b250ec396..2acc44b40986 100644 --- a/drivers/net/wireless/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/iwlwifi/mvm/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o iwlmvm-y += scan.o time-event.o rs.o -iwlmvm-y += power.o +iwlmvm-y += power.o bt-coex.o iwlmvm-y += led.o iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o iwlmvm-$(CONFIG_PM_SLEEP) += d3.o diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c new file mode 100644 index 000000000000..d37865af3254 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -0,0 +1,242 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * + *****************************************************************************/ + +#include "fw-api-bt-coex.h" +#include "iwl-modparams.h" +#include "mvm.h" + +#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ + [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ + ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS)) + +static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1, + BT_COEX_PRIO_TBL_PRIO_BYPASS, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2, + BT_COEX_PRIO_TBL_PRIO_BYPASS, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1, + BT_COEX_PRIO_TBL_PRIO_LOW, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2, + BT_COEX_PRIO_TBL_PRIO_LOW, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1, + BT_COEX_PRIO_TBL_PRIO_HIGH, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2, + BT_COEX_PRIO_TBL_PRIO_HIGH, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM, + BT_COEX_PRIO_TBL_DISABLED, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24, + BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE, + BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0), + 0, 0, 0, 0, 0, 0, +}; + +#undef EVENT_PRIO_ANT + +int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) +{ + return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, + sizeof(struct iwl_bt_coex_prio_tbl_cmd), + &iwl_bt_prio_tbl); +} + +static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type) +{ + struct iwl_bt_coex_prot_env_cmd env_cmd; + int ret; + + env_cmd.action = action; + env_cmd.type = type; + ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC, + sizeof(env_cmd), &env_cmd); + if (ret) + IWL_ERR(mvm, "failed to send BT env command\n"); + return ret; +} + +enum iwl_bt_kill_msk { + BT_KILL_MSK_DEFAULT, + BT_KILL_MSK_SCO_HID_A2DP, + BT_KILL_MSK_REDUCED_TXPOW, + BT_KILL_MSK_MAX, +}; + +static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { + 0xffffffff, + 0xfffffc00, + 0, +}; + +static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { + 0xffffffff, + 0xfffffc00, + 0, +}; + +#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) + +/* Tight Coex */ +static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), +}; + +/* Loose Coex */ +static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), +}; + +/* Full concurrency */ +static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) + +int iwl_send_bt_init_conf(struct iwl_mvm *mvm) +{ + struct iwl_bt_coex_cmd cmd = { + .max_kill = 5, + .bt3_time_t7_value = 1, + .bt3_prio_sample_time = 2, + .bt3_timer_t2_value = 0xc, + }; + int ret; + + cmd.flags = iwlwifi_mod_params.bt_coex_active ? + BT_COEX_NW : BT_COEX_DISABLE; + cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? + BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0; + cmd.flags |= BT_SYNC_2_BT_DISABLE; + + cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | + BT_VALID_BT_PRIO_BOOST | + BT_VALID_MAX_KILL | + BT_VALID_3W_TMRS | + BT_VALID_KILL_ACK | + BT_VALID_KILL_CTS | + BT_VALID_REDUCED_TX_POWER | + BT_VALID_LUT); + + if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) + memcpy(&cmd.decision_lut, iwl_loose_lookup, + sizeof(iwl_tight_lookup)); + else + memcpy(&cmd.decision_lut, iwl_tight_lookup, + sizeof(iwl_tight_lookup)); + + cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); + cmd.kill_ack_msk = + cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); + cmd.kill_cts_msk = + cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); + + /* go to CALIB state in internal BT-Coex state machine */ + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; + + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; + + return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, + sizeof(cmd), &cmd); +} diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 0f45fa583aa1..1006b3204e7b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -309,6 +309,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto error; } + ret = iwl_send_bt_prio_tbl(mvm); + if (ret) + goto error; + if (read_nvm) { /* Read nvm */ ret = iwl_nvm_init(mvm); @@ -414,6 +418,14 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; + ret = iwl_send_bt_prio_tbl(mvm); + if (ret) + goto error; + + ret = iwl_send_bt_init_conf(mvm); + if (ret) + goto error; + /* Send phy db control command and then phy db calibration*/ ret = iwl_send_phy_db_data(mvm->phy_db); if (ret) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 234c5726d196..b7f27d59fc24 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -504,4 +504,8 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); +/* BT Coex */ +int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); +int iwl_send_bt_init_conf(struct iwl_mvm *mvm); + #endif /* __IWL_MVM_H__ */ -- cgit From f421f9c3b2dc77e2be1b9400a4420b6d2cdfb847 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 17 Jan 2013 14:20:29 +0200 Subject: iwlwifi: mvm: handle BT-coex notification The BT-Coex notification is sent by the fw when there are updates wrt. BT activity. Driver action might be taken based on the info in this notification. For now, update the Ack/Cts_kill_msk if HID / SCO / A2DP profiles are active. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 50 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 6 ++++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 ++ 3 files changed, 58 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index d37865af3254..61159f8abe78 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -64,6 +64,7 @@ #include "fw-api-bt-coex.h" #include "iwl-modparams.h" #include "mvm.h" +#include "iwl-debug.h" #define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ @@ -240,3 +241,52 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd); } + +int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *dev_cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; + struct iwl_bt_coex_cmd cmd = {}; + enum iwl_bt_kill_msk bt_kill_msk; + + IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); + IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); + IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn); + IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load); + IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n", + notif->bt_agg_traffic_load); + IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + + /* Low latency BT profile is active: give higher prio to BT */ + if (BT_MBOX_MSG(notif, 3, SCO_STATE) || + BT_MBOX_MSG(notif, 3, A2DP_STATE) || + BT_MBOX_MSG(notif, 3, SNIFF_STATE)) + bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; + else + bt_kill_msk = BT_KILL_MSK_DEFAULT; + + /* Don't send HCMD if there is no update */ + if (bt_kill_msk == mvm->bt_kill_msk) + return 0; + + IWL_DEBUG_COEX(mvm, + "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n", + bt_kill_msk, + BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); + + mvm->bt_kill_msk = bt_kill_msk; + cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); + cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); + + cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); + + if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) + IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); + + /* This handler is ASYNC */ + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index b7f27d59fc24..a1f1a86643e5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -334,6 +334,9 @@ struct iwl_mvm { #ifdef CONFIG_PM_SLEEP int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; #endif + + /* BT-Coex */ + u8 bt_kill_msk; }; /* Extract MVM priv from op_mode and _hw */ @@ -507,5 +510,8 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, /* BT Coex */ int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); int iwl_send_bt_init_conf(struct iwl_mvm *mvm); +int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 2003daa0cf76..54595eb7b92a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -230,6 +230,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), + RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), + RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), -- cgit From 7da052b818371b6b29909d871bf803192aa40b84 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Feb 2013 17:06:17 +0200 Subject: iwlwifi: mvm: update SMPS when BT gets active When BT traffic load gets higher, we want to avoid using the shared antenna. In order to do so, we need to tell the AP that we don't support MIMO any more, or at least not all the time: in short, use the SMPS to achieve this. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 61159f8abe78..fa054b364e52 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -242,12 +242,60 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) sizeof(cmd), &cmd); } +struct iwl_bt_notif_iterator_data { + struct iwl_mvm *mvm; + struct iwl_bt_coex_profile_notif *notif; +}; + +static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_bt_notif_iterator_data *data = _data; + struct ieee80211_chanctx_conf *chanctx_conf; + enum ieee80211_smps_mode smps_mode; + enum ieee80211_band band; + + if (vif->type != NL80211_IFTYPE_STATION) + return; + + rcu_read_lock(); + chanctx_conf = rcu_dereference(vif->chanctx_conf); + if (chanctx_conf && chanctx_conf->def.chan) + band = chanctx_conf->def.chan->band; + else + band = -1; + rcu_read_unlock(); + + if (band != IEEE80211_BAND_2GHZ) + return; + + smps_mode = IEEE80211_SMPS_AUTOMATIC; + + if (data->notif->bt_status) + smps_mode = IEEE80211_SMPS_DYNAMIC; + + if (data->notif->bt_traffic_load) + smps_mode = IEEE80211_SMPS_STATIC; + + IWL_DEBUG_COEX(data->mvm, + "mac %d: bt_status %d traffic_load %d smps_req %d\n", + mvmvif->id, data->notif->bt_status, + data->notif->bt_traffic_load, smps_mode); + + ieee80211_request_smps(vif, smps_mode); +} + int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *dev_cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; + struct iwl_bt_notif_iterator_data data = { + .mvm = mvm, + .notif = notif, + }; struct iwl_bt_coex_cmd cmd = {}; enum iwl_bt_kill_msk bt_kill_msk; @@ -259,6 +307,10 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, notif->bt_agg_traffic_load); IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_bt_notif_iterator, &data); + /* Low latency BT profile is active: give higher prio to BT */ if (BT_MBOX_MSG(notif, 3, SCO_STATE) || BT_MBOX_MSG(notif, 3, A2DP_STATE) || -- cgit From 1094234284a2afe46202773ebd9ae55416092d9c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 11:02:36 +0200 Subject: iwlwifi: mvm: export last bt_notif through debugfs This will allow to track how BT core updates the driver. This is required to debug the BT Coexistence mechanism. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 3 + drivers/net/wireless/iwlwifi/mvm/debugfs.c | 100 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 3 files changed, 104 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index fa054b364e52..47954deb6493 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -307,6 +307,9 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, notif->bt_agg_traffic_load); IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + /* remember this notification for future use: rssi fluctuations */ + memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); + ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_bt_notif_iterator, &data); diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 2ad301164bd9..56bf601f8991 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -300,6 +300,104 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, return count; } +#define BT_MBOX_MSG(_notif, _num, _field) \ + ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ + >> BT_MBOX##_num##_##_field##_POS) + + +#define BT_MBOX_PRINT(_num, _field, _end) \ + pos += scnprintf(buf + pos, bufsz - pos, \ + "\t%s: %d%s", \ + #_field, \ + BT_MBOX_MSG(notif, _num, _field), \ + true ? "\n" : ", "); + +static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; + char *buf; + int ret, pos = 0, bufsz = sizeof(char) * 1024; + + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + mutex_lock(&mvm->mutex); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); + + BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); + BT_MBOX_PRINT(0, LE_PROF1, false); + BT_MBOX_PRINT(0, LE_PROF2, false); + BT_MBOX_PRINT(0, LE_PROF_OTHER, false); + BT_MBOX_PRINT(0, CHL_SEQ_N, false); + BT_MBOX_PRINT(0, INBAND_S, false); + BT_MBOX_PRINT(0, LE_MIN_RSSI, false); + BT_MBOX_PRINT(0, LE_SCAN, false); + BT_MBOX_PRINT(0, LE_ADV, false); + BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false); + BT_MBOX_PRINT(0, OPEN_CON_1, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n"); + + BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false); + BT_MBOX_PRINT(1, IP_SR, false); + BT_MBOX_PRINT(1, LE_MSTR, false); + BT_MBOX_PRINT(1, AGGR_TRFC_LD, false); + BT_MBOX_PRINT(1, MSG_TYPE, false); + BT_MBOX_PRINT(1, SSN, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n"); + + BT_MBOX_PRINT(2, SNIFF_ACT, false); + BT_MBOX_PRINT(2, PAG, false); + BT_MBOX_PRINT(2, INQUIRY, false); + BT_MBOX_PRINT(2, CONN, false); + BT_MBOX_PRINT(2, SNIFF_INTERVAL, false); + BT_MBOX_PRINT(2, DISC, false); + BT_MBOX_PRINT(2, SCO_TX_ACT, false); + BT_MBOX_PRINT(2, SCO_RX_ACT, false); + BT_MBOX_PRINT(2, ESCO_RE_TX, false); + BT_MBOX_PRINT(2, SCO_DURATION, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n"); + + BT_MBOX_PRINT(3, SCO_STATE, false); + BT_MBOX_PRINT(3, SNIFF_STATE, false); + BT_MBOX_PRINT(3, A2DP_STATE, false); + BT_MBOX_PRINT(3, ACL_STATE, false); + BT_MBOX_PRINT(3, MSTR_STATE, false); + BT_MBOX_PRINT(3, OBX_STATE, false); + BT_MBOX_PRINT(3, OPEN_CON_2, false); + BT_MBOX_PRINT(3, TRAFFIC_LOAD, false); + BT_MBOX_PRINT(3, CHL_SEQN_LSB, false); + BT_MBOX_PRINT(3, INBAND_P, false); + BT_MBOX_PRINT(3, MSG_TYPE_2, false); + BT_MBOX_PRINT(3, SSN_2, false); + BT_MBOX_PRINT(3, UPDATE_REQUEST, true); + + pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", + notif->bt_status); + pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", + notif->bt_open_conn); + pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", + notif->bt_traffic_load); + pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", + notif->bt_agg_traffic_load); + pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", + notif->bt_ci_compliance); + + mutex_unlock(&mvm->mutex); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + + return ret; +} +#undef BT_MBOX_PRINT + #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ @@ -339,6 +437,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); MVM_DEBUGFS_READ_FILE_OPS(stations); +MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); @@ -352,6 +451,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); + MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index a1f1a86643e5..203eb85e03d3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -337,6 +337,7 @@ struct iwl_mvm { /* BT-Coex */ u8 bt_kill_msk; + struct iwl_bt_coex_profile_notif last_bt_notif; }; /* Extract MVM priv from op_mode and _hw */ -- cgit From 6bfcb7e88cbb45782664caeb9bfe1a1c1b83a10e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 10:19:45 +0200 Subject: iwlwifi: mvm: update firmware API - MAC ID in RX The firmware tells the driver to what MACs the received frame belongs (based on the time slot in which it was received). Note that there can be several MACs if they share the same binding. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index da9ee3fe3379..f8d7e88234e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -801,6 +801,7 @@ struct iwl_phy_context_cmd { * @byte_count: frame's byte-count * @frame_time: frame's time on the air, based on byte count and frame rate * calculation + * @mac_active_msk: what MACs were active when the frame was received * * Before each Rx, the device sends this data. It contains PHY information * about the reception of the packet. @@ -818,7 +819,7 @@ struct iwl_rx_phy_info { __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; __le32 rate_n_flags; __le32 byte_count; - __le16 reserved2; + __le16 mac_active_msk; __le16 frame_time; } __packed; -- cgit From 490953ac344725f56746d16ef8480842f4087fc4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 4 Mar 2013 08:53:07 +0200 Subject: iwlwifi: move firmware restart debugfs hook to op_mode This allows to test fw restart flow. The hook in transport layer doesn't really make the fw assert. Moving this hook to the op_mode allows to use the fw API to actually send a host command that will make the fw assert. Change the restart_fw module parameter to be a boolean on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/debugfs.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-drv.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/pcie/trans.c | 18 ------------------ 5 files changed, 52 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 9d3b7e3165f4..7b8178be119f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + bool restart_fw = iwlwifi_mod_params.restart_fw; + int ret; + + iwlwifi_mod_params.restart_fw = true; + + mutex_lock(&priv->mutex); + + /* take the return value to make compiler happy - it will fail anyway */ + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL); + + mutex_unlock(&priv->mutex); + + iwlwifi_mod_params.restart_fw = restart_fw; + + return count; +} + DEBUGFS_READ_FILE_OPS(ucode_rx_stats); DEBUGFS_READ_FILE_OPS(ucode_tx_stats); DEBUGFS_READ_FILE_OPS(ucode_general_stats); @@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); +DEBUGFS_WRITE_FILE_OPS(fw_restart); #ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); #endif @@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR); #ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 15ac54baa833..3ce4e9d5082d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,7 +1102,7 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { - .restart_fw = 1, + .restart_fw = true, .plcp_check = true, .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, @@ -1207,8 +1207,8 @@ MODULE_PARM_DESC(11n_disable, module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, int, S_IRUGO); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); -module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); +module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO); +MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index a2cefe2c3e1d..3cc39ffe8ba5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -109,7 +109,7 @@ struct iwl_mod_params { int sw_crypto; unsigned int disable_11n; int amsdu_size_8K; - int restart_fw; + bool restart_fw; bool plcp_check; int wd_disable; bool bt_coex_active; diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 56bf601f8991..b080b4ba5458 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -398,6 +398,28 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, } #undef BT_MBOX_PRINT +static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + bool restart_fw = iwlwifi_mod_params.restart_fw; + int ret; + + iwlwifi_mod_params.restart_fw = true; + + mutex_lock(&mvm->mutex); + + /* take the return value to make compiler happy - it will fail anyway */ + ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL); + + mutex_unlock(&mvm->mutex); + + iwlwifi_mod_params.restart_fw = restart_fw; + + return count; +} + #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ @@ -440,6 +462,7 @@ MVM_DEBUGFS_READ_FILE_OPS(stations); MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); +MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) { @@ -454,6 +477,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); + MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); /* * Create a symlink with mac80211. It will be removed when mac80211 diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d90cbf5041f5..d17fb4bd3efb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1370,28 +1370,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, return ret; } -static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_trans *trans = file->private_data; - - if (!trans->op_mode) - return -EAGAIN; - - local_bh_disable(); - iwl_op_mode_nic_error(trans->op_mode); - local_bh_enable(); - - return count; -} - DEBUGFS_READ_WRITE_FILE_OPS(interrupt); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_FILE_OPS(rx_queue); DEBUGFS_READ_FILE_OPS(tx_queue); DEBUGFS_WRITE_FILE_OPS(csr); -DEBUGFS_WRITE_FILE_OPS(fw_restart); /* * Create the debugfs files and directories @@ -1405,7 +1388,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); - DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); return 0; err: -- cgit From f9477c17c2ce59f64462635c3e5d43c98c0ad67f Mon Sep 17 00:00:00 2001 From: Amnon Paz Date: Wed, 27 Feb 2013 11:28:16 +0200 Subject: iwlwifi: fix indirect write bug Fix a bug in writing to indirect (periphery) registers; although writes seem successful the data is not written to the desired address). Also fix address mask for HBUS_TARG_PRPH_RADDR and HBUS_TARG_PRPH_WADDR registers. Signed-off-by: Amnon Paz Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d17fb4bd3efb..6649e377e9cd 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -715,7 +715,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) { - iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, + ((reg & 0x000FFFFF) | (3 << 24))); return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); } @@ -723,7 +724,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, - ((addr & 0x0000FFFF) | (3 << 24))); + ((addr & 0x000FFFFF) | (3 << 24))); iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -- cgit From 25b9ea5c797b5d78f8ceced9ad9c7a7daf0db19c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Mar 2013 11:53:38 +0200 Subject: iwlwifi: mvm: the SCD byte count is a TLV flag The SCD byte count layout is decided by the configuration done in fw, it is then logical to export it as a TLV flag and not per HW SKU. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 54848d59df0e..435618574240 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -73,12 +73,14 @@ * treats good CRC threshold as a boolean * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS */ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_PAN = BIT(0), IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), IWL_UCODE_TLV_FLAGS_MFP = BIT(2), IWL_UCODE_TLV_FLAGS_P2P = BIT(3), + IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), }; /* The default calibrate table size if not specified by firmware file */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 54595eb7b92a..828bdddd07e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -370,8 +370,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; - /* TODO: this should really be a TLV */ - if (cfg->device_family == IWL_DEVICE_FAMILY_7000) + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) trans_cfg.bc_table_dword = true; if (!iwlwifi_mod_params.wd_disable) -- cgit From acbba0d0f88e2577b9d92b61b136d13f65831a52 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 6 Mar 2013 01:31:12 +0000 Subject: team: introduce two default team_modeop functions and use them in modes No need to duplicate code for this. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 19 ++++++++++++++++--- drivers/net/team/team_mode_broadcast.c | 14 ++------------ drivers/net/team/team_mode_roundrobin.c | 14 ++------------ include/linux/if_team.h | 5 ++++- 4 files changed, 24 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 05c5efe84591..ece70a4abbb1 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -73,11 +73,24 @@ static int team_port_set_orig_dev_addr(struct team_port *port) return __set_port_dev_addr(port->dev, port->orig.dev_addr); } -int team_port_set_team_dev_addr(struct team_port *port) +static int team_port_set_team_dev_addr(struct team *team, + struct team_port *port) +{ + return __set_port_dev_addr(port->dev, team->dev->dev_addr); +} + +int team_modeop_port_enter(struct team *team, struct team_port *port) +{ + return team_port_set_team_dev_addr(team, port); +} +EXPORT_SYMBOL(team_modeop_port_enter); + +void team_modeop_port_change_dev_addr(struct team *team, + struct team_port *port) { - return __set_port_dev_addr(port->dev, port->team->dev->dev_addr); + team_port_set_team_dev_addr(team, port); } -EXPORT_SYMBOL(team_port_set_team_dev_addr); +EXPORT_SYMBOL(team_modeop_port_change_dev_addr); static void team_refresh_port_linkup(struct team_port *port) { diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c index c5db428e73fa..c366cd299c06 100644 --- a/drivers/net/team/team_mode_broadcast.c +++ b/drivers/net/team/team_mode_broadcast.c @@ -46,20 +46,10 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) return sum_ret; } -static int bc_port_enter(struct team *team, struct team_port *port) -{ - return team_port_set_team_dev_addr(port); -} - -static void bc_port_change_dev_addr(struct team *team, struct team_port *port) -{ - team_port_set_team_dev_addr(port); -} - static const struct team_mode_ops bc_mode_ops = { .transmit = bc_transmit, - .port_enter = bc_port_enter, - .port_change_dev_addr = bc_port_change_dev_addr, + .port_enter = team_modeop_port_enter, + .port_change_dev_addr = team_modeop_port_change_dev_addr, }; static const struct team_mode bc_mode = { diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c index 105135aa8f05..ed63a6bc66ce 100644 --- a/drivers/net/team/team_mode_roundrobin.c +++ b/drivers/net/team/team_mode_roundrobin.c @@ -64,20 +64,10 @@ drop: return false; } -static int rr_port_enter(struct team *team, struct team_port *port) -{ - return team_port_set_team_dev_addr(port); -} - -static void rr_port_change_dev_addr(struct team *team, struct team_port *port) -{ - team_port_set_team_dev_addr(port); -} - static const struct team_mode_ops rr_mode_ops = { .transmit = rr_transmit, - .port_enter = rr_port_enter, - .port_change_dev_addr = rr_port_change_dev_addr, + .port_enter = team_modeop_port_enter, + .port_change_dev_addr = team_modeop_port_change_dev_addr, }; static const struct team_mode rr_mode = { diff --git a/include/linux/if_team.h b/include/linux/if_team.h index cfd21e3d5506..3283def74483 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -112,6 +112,10 @@ struct team_mode_ops { void (*port_disabled)(struct team *team, struct team_port *port); }; +extern int team_modeop_port_enter(struct team *team, struct team_port *port); +extern void team_modeop_port_change_dev_addr(struct team *team, + struct team_port *port); + enum team_option_type { TEAM_OPTION_TYPE_U32, TEAM_OPTION_TYPE_STRING, @@ -236,7 +240,6 @@ static inline struct team_port *team_get_port_by_index_rcu(struct team *team, return NULL; } -extern int team_port_set_team_dev_addr(struct team_port *port); extern int team_options_register(struct team *team, const struct team_option *option, size_t option_count); -- cgit From 753f993911b32e479b4fab5d228dc07c11d1e7e7 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 6 Mar 2013 01:31:13 +0000 Subject: team: introduce random mode As suggested by Eric Dumazet, allow user to select mode which chooses TX port randomly. Functionality should be more of less similar to round-robin mode with even lower overhead. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/Kconfig | 12 ++++++ drivers/net/team/Makefile | 1 + drivers/net/team/team_mode_random.c | 71 +++++++++++++++++++++++++++++++++ drivers/net/team/team_mode_roundrobin.c | 22 +--------- include/linux/if_team.h | 20 ++++++++++ 5 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 drivers/net/team/team_mode_random.c (limited to 'drivers') diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig index c3011af68e91..c853d84fd99f 100644 --- a/drivers/net/team/Kconfig +++ b/drivers/net/team/Kconfig @@ -37,6 +37,18 @@ config NET_TEAM_MODE_ROUNDROBIN To compile this team mode as a module, choose M here: the module will be called team_mode_roundrobin. +config NET_TEAM_MODE_RANDOM + tristate "Random mode support" + depends on NET_TEAM + ---help--- + Basic mode where port used for transmitting packets is selected + randomly. + + All added ports are setup to have team's device address. + + To compile this team mode as a module, choose M here: the module + will be called team_mode_random. + config NET_TEAM_MODE_ACTIVEBACKUP tristate "Active-backup mode support" depends on NET_TEAM diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile index 975763014e5a..c57e85889751 100644 --- a/drivers/net/team/Makefile +++ b/drivers/net/team/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_NET_TEAM) += team.o obj-$(CONFIG_NET_TEAM_MODE_BROADCAST) += team_mode_broadcast.o obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o +obj-$(CONFIG_NET_TEAM_MODE_RANDOM) += team_mode_random.o obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c new file mode 100644 index 000000000000..9eabfaa22f3e --- /dev/null +++ b/drivers/net/team/team_mode_random.c @@ -0,0 +1,71 @@ +/* + * drivers/net/team/team_mode_random.c - Random mode for team + * Copyright (c) 2013 Jiri Pirko + * + * 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 + +static u32 random_N(unsigned int N) +{ + return reciprocal_divide(random32(), N); +} + +static bool rnd_transmit(struct team *team, struct sk_buff *skb) +{ + struct team_port *port; + int port_index; + + port_index = random_N(team->en_port_count); + port = team_get_port_by_index_rcu(team, port_index); + port = team_get_first_port_txable_rcu(team, port); + if (unlikely(!port)) + goto drop; + if (team_dev_queue_xmit(team, port, skb)) + return false; + return true; + +drop: + dev_kfree_skb_any(skb); + return false; +} + +static const struct team_mode_ops rnd_mode_ops = { + .transmit = rnd_transmit, + .port_enter = team_modeop_port_enter, + .port_change_dev_addr = team_modeop_port_change_dev_addr, +}; + +static const struct team_mode rnd_mode = { + .kind = "random", + .owner = THIS_MODULE, + .ops = &rnd_mode_ops, +}; + +static int __init rnd_init_module(void) +{ + return team_mode_register(&rnd_mode); +} + +static void __exit rnd_cleanup_module(void) +{ + team_mode_unregister(&rnd_mode); +} + +module_init(rnd_init_module); +module_exit(rnd_cleanup_module); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Jiri Pirko "); +MODULE_DESCRIPTION("Random mode for team"); +MODULE_ALIAS("team-mode-random"); diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c index ed63a6bc66ce..d268e4de781b 100644 --- a/drivers/net/team/team_mode_roundrobin.c +++ b/drivers/net/team/team_mode_roundrobin.c @@ -25,26 +25,6 @@ static struct rr_priv *rr_priv(struct team *team) return (struct rr_priv *) &team->mode_priv; } -static struct team_port *__get_first_port_up(struct team *team, - struct team_port *port) -{ - struct team_port *cur; - - if (team_port_txable(port)) - return port; - cur = port; - list_for_each_entry_continue_rcu(cur, &team->port_list, list) - if (team_port_txable(port)) - return cur; - list_for_each_entry_rcu(cur, &team->port_list, list) { - if (cur == port) - break; - if (team_port_txable(port)) - return cur; - } - return NULL; -} - static bool rr_transmit(struct team *team, struct sk_buff *skb) { struct team_port *port; @@ -52,7 +32,7 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb) port_index = rr_priv(team)->sent_packets++ % team->en_port_count; port = team_get_port_by_index_rcu(team, port_index); - port = __get_first_port_up(team, port); + port = team_get_first_port_txable_rcu(team, port); if (unlikely(!port)) goto drop; if (team_dev_queue_xmit(team, port, skb)) diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 3283def74483..4474557904f6 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -240,6 +240,26 @@ static inline struct team_port *team_get_port_by_index_rcu(struct team *team, return NULL; } +static inline struct team_port * +team_get_first_port_txable_rcu(struct team *team, struct team_port *port) +{ + struct team_port *cur; + + if (likely(team_port_txable(port))) + return port; + cur = port; + list_for_each_entry_continue_rcu(cur, &team->port_list, list) + if (team_port_txable(port)) + return cur; + list_for_each_entry_rcu(cur, &team->port_list, list) { + if (cur == port) + break; + if (team_port_txable(port)) + return cur; + } + return NULL; +} + extern int team_options_register(struct team *team, const struct team_option *option, size_t option_count); -- cgit From 09e7fae97702f9fcc875b56f3b687e88408b32e5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 6 Mar 2013 00:41:32 +0000 Subject: r6040: check MDIO register busy waiting result We are currently busy waiting for MDIO registers to complete their operation but we did not propagate the result back to the caller. Update r6040_phy_{read,write} to report the busy waiting result accordingly. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/rdc/r6040.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 5b4103db70f5..d5622ab5a1da 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -224,11 +224,14 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg) break; } + if (limit < 0) + return -ETIMEDOUT; + return ioread16(ioaddr + MMRD); } /* Write a word data from PHY Chip */ -static void r6040_phy_write(void __iomem *ioaddr, +static int r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) { int limit = MAC_DEF_TIMEOUT; @@ -243,6 +246,8 @@ static void r6040_phy_write(void __iomem *ioaddr, if (!(cmd & MDIO_WRITE)) break; } + + return (limit < 0) ? -ETIMEDOUT : 0; } static int r6040_mdiobus_read(struct mii_bus *bus, int phy_addr, int reg) @@ -261,9 +266,7 @@ static int r6040_mdiobus_write(struct mii_bus *bus, int phy_addr, struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - r6040_phy_write(ioaddr, phy_addr, reg, value); - - return 0; + return r6040_phy_write(ioaddr, phy_addr, reg, value); } static int r6040_mdiobus_reset(struct mii_bus *bus) -- cgit From e5652756ff36ed9e1283121f788e6a17117efcab Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 20 Feb 2013 12:11:05 -0800 Subject: ssb: pci: Standardize a function to get mac address Don't require alignment of mac addresses to u16. Signed-off-by: Joe Perches Tested-by: Larry Finger Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index e9d94968f394..4ec0bdbf25ed 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -231,6 +231,15 @@ static inline u8 ssb_crc8(u8 crc, u8 data) return t[crc ^ data]; } +static void sprom_get_mac(char *mac, const u16 *in) +{ + int i; + for (i = 0; i < 3; i++) { + *mac++ = in[i]; + *mac++ = in[i] >> 8; + } +} + static u8 ssb_sprom_crc(const u16 *sprom, u16 size) { int word; @@ -341,8 +350,6 @@ static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in, static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) { - int i; - u16 v; u16 loc[3]; if (out->revision == 3) /* rev 3 moved MAC */ @@ -352,19 +359,10 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) loc[1] = SSB_SPROM1_ET0MAC; loc[2] = SSB_SPROM1_ET1MAC; } - for (i = 0; i < 3; i++) { - v = in[SPOFF(loc[0]) + i]; - *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); - } + sprom_get_mac(out->il0mac, &in[SPOFF(loc[0])]); if (out->revision < 3) { /* only rev 1-2 have et0, et1 */ - for (i = 0; i < 3; i++) { - v = in[SPOFF(loc[1]) + i]; - *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); - } - for (i = 0; i < 3; i++) { - v = in[SPOFF(loc[2]) + i]; - *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); - } + sprom_get_mac(out->et0mac, &in[SPOFF(loc[1])]); + sprom_get_mac(out->et1mac, &in[SPOFF(loc[2])]); } SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, @@ -454,19 +452,15 @@ static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in) static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) { - int i; - u16 v; u16 il0mac_offset; if (out->revision == 4) il0mac_offset = SSB_SPROM4_IL0MAC; else il0mac_offset = SSB_SPROM5_IL0MAC; - /* extract the MAC address */ - for (i = 0; i < 3; i++) { - v = in[SPOFF(il0mac_offset) + i]; - *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); - } + + sprom_get_mac(out->il0mac, &in[SPOFF(il0mac_offset)]); + SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, SSB_SPROM4_ETHPHY_ET1A_SHIFT); @@ -530,7 +524,7 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) { int i; - u16 v, o; + u16 o; u16 pwr_info_offset[] = { SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 @@ -539,10 +533,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) ARRAY_SIZE(out->core_pwr_info)); /* extract the MAC address */ - for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; - *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); - } + sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]); + SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); -- cgit From 33a606ac8020b47292bcfda30c7888c1ab5233e2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 20 Feb 2013 12:16:13 -0800 Subject: ssb: Convert ssb_printk to ssb_ Use a more current logging style. Convert ssb_dbprint to ssb_dbg too. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 2 +- drivers/ssb/driver_chipcommon_pmu.c | 41 +++++++++++++--------------- drivers/ssb/driver_mipscore.c | 25 ++++++++--------- drivers/ssb/driver_pcicore.c | 15 +++++------ drivers/ssb/embedded.c | 5 ++-- drivers/ssb/main.c | 51 +++++++++++++++-------------------- drivers/ssb/pci.c | 53 +++++++++++++++++-------------------- drivers/ssb/pcmcia.c | 46 ++++++++++++++------------------ drivers/ssb/scan.c | 31 ++++++++-------------- drivers/ssb/sprom.c | 4 +-- drivers/ssb/ssb_private.h | 19 ++++++++++--- 11 files changed, 135 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 71098a7b5fed..7cb7d2c8fd86 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -354,7 +354,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) if (cc->dev->id.revision >= 11) cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); - ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); + ssb_dbg("chipcommon status is 0x%x\n", cc->status); if (cc->dev->id.revision >= 20) { chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0); diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 4c0f6d883dd3..791da2c0d8f6 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c @@ -110,8 +110,8 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc, return; } - ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", - (crystalfreq / 1000), (crystalfreq % 1000)); + ssb_info("Programming PLL to %u.%03u MHz\n", + crystalfreq / 1000, crystalfreq % 1000); /* First turn the PLL off. */ switch (bus->chip_id) { @@ -138,7 +138,7 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc, } tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) - ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); + ssb_emerg("Failed to turn the PLL off!\n"); /* Set PDIV in PLL control 0. */ pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL0); @@ -249,8 +249,8 @@ static void ssb_pmu1_pllinit_r0(struct ssb_chipcommon *cc, return; } - ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", - (crystalfreq / 1000), (crystalfreq % 1000)); + ssb_info("Programming PLL to %u.%03u MHz\n", + crystalfreq / 1000, crystalfreq % 1000); /* First turn the PLL off. */ switch (bus->chip_id) { @@ -275,7 +275,7 @@ static void ssb_pmu1_pllinit_r0(struct ssb_chipcommon *cc, } tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) - ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); + ssb_emerg("Failed to turn the PLL off!\n"); /* Set p1div and p2div. */ pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL0); @@ -349,9 +349,8 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) case 43222: break; default: - ssb_printk(KERN_ERR PFX - "ERROR: PLL init unknown for device %04X\n", - bus->chip_id); + ssb_err("ERROR: PLL init unknown for device %04X\n", + bus->chip_id); } } @@ -472,9 +471,8 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) max_msk = 0xFFFFF; break; default: - ssb_printk(KERN_ERR PFX - "ERROR: PMU resource config unknown for device %04X\n", - bus->chip_id); + ssb_err("ERROR: PMU resource config unknown for device %04X\n", + bus->chip_id); } if (updown_tab) { @@ -526,8 +524,8 @@ void ssb_pmu_init(struct ssb_chipcommon *cc) pmucap = chipco_read32(cc, SSB_CHIPCO_PMU_CAP); cc->pmu.rev = (pmucap & SSB_CHIPCO_PMU_CAP_REVISION); - ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", - cc->pmu.rev, pmucap); + ssb_dbg("Found rev %u PMU (capabilities 0x%08X)\n", + cc->pmu.rev, pmucap); if (cc->pmu.rev == 1) chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, @@ -638,9 +636,8 @@ u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc) case 0x5354: ssb_pmu_get_alp_clock_clk0(cc); default: - ssb_printk(KERN_ERR PFX - "ERROR: PMU alp clock unknown for device %04X\n", - bus->chip_id); + ssb_err("ERROR: PMU alp clock unknown for device %04X\n", + bus->chip_id); return 0; } } @@ -654,9 +651,8 @@ u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) /* 5354 chip uses a non programmable PLL of frequency 240MHz */ return 240000000; default: - ssb_printk(KERN_ERR PFX - "ERROR: PMU cpu clock unknown for device %04X\n", - bus->chip_id); + ssb_err("ERROR: PMU cpu clock unknown for device %04X\n", + bus->chip_id); return 0; } } @@ -669,9 +665,8 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) case 0x5354: return 120000000; default: - ssb_printk(KERN_ERR PFX - "ERROR: PMU controlclock unknown for device %04X\n", - bus->chip_id); + ssb_err("ERROR: PMU controlclock unknown for device %04X\n", + bus->chip_id); return 0; } } diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 33b37dac40bd..fa385a368a56 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c @@ -167,21 +167,22 @@ static void set_irq(struct ssb_device *dev, unsigned int irq) irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); ssb_write32(mdev, SSB_IPSFLAG, irqflag); } - ssb_dprintk(KERN_INFO PFX - "set_irq: core 0x%04x, irq %d => %d\n", - dev->id.coreid, oldirq+2, irq+2); + ssb_dbg("set_irq: core 0x%04x, irq %d => %d\n", + dev->id.coreid, oldirq+2, irq+2); } static void print_irq(struct ssb_device *dev, unsigned int irq) { - int i; static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; - ssb_dprintk(KERN_INFO PFX - "core 0x%04x, irq :", dev->id.coreid); - for (i = 0; i <= 6; i++) { - ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); - } - ssb_dprintk("\n"); + ssb_dbg("core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n", + dev->id.coreid, + irq_name[0], irq == 0 ? "*" : " ", + irq_name[1], irq == 1 ? "*" : " ", + irq_name[2], irq == 2 ? "*" : " ", + irq_name[3], irq == 3 ? "*" : " ", + irq_name[4], irq == 4 ? "*" : " ", + irq_name[5], irq == 5 ? "*" : " ", + irq_name[6], irq == 6 ? "*" : " "); } static void dump_irq(struct ssb_bus *bus) @@ -286,7 +287,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) if (!mcore->dev) return; /* We don't have a MIPS core */ - ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); + ssb_dbg("Initializing MIPS core...\n"); bus = mcore->dev->bus; hz = ssb_clockspeed(bus); @@ -334,7 +335,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) break; } } - ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); + ssb_dbg("after irq reconfiguration\n"); dump_irq(bus); ssb_mips_serial_init(mcore); diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 59801d23d7ec..d75b72ba2672 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -263,8 +263,7 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d) return -ENODEV; } - ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", - pci_name(d)); + ssb_info("PCI: Fixing up device %s\n", pci_name(d)); /* Fix up interrupt lines */ d->irq = ssb_mips_irq(extpci_core->dev) + 2; @@ -285,12 +284,12 @@ static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev) if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) return; - ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); + ssb_info("PCI: Fixing up bridge %s\n", pci_name(dev)); /* Enable PCI bridge bus mastering and memory space */ pci_set_master(dev); if (pcibios_enable_device(dev, ~0) < 0) { - ssb_printk(KERN_ERR "PCI: SSB bridge enable failed\n"); + ssb_err("PCI: SSB bridge enable failed\n"); return; } @@ -299,8 +298,8 @@ static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev) /* Make sure our latency is high enough to handle the devices behind us */ lat = 168; - ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", - pci_name(dev), lat); + ssb_info("PCI: Fixing latency timer of device %s to %u\n", + pci_name(dev), lat); pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge); @@ -323,7 +322,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) return; extpci_core = pc; - ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); + ssb_dbg("PCIcore in host mode found\n"); /* Reset devices on the external PCI bus */ val = SSB_PCICORE_CTL_RST_OE; val |= SSB_PCICORE_CTL_CLK_OE; @@ -338,7 +337,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) udelay(1); /* Assertion time demanded by the PCI standard */ if (pc->dev->bus->has_cardbus_slot) { - ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); + ssb_dbg("CardBus slot detected\n"); pc->cardbusmode = 1; /* GPIO 1 resets the bridge */ ssb_gpio_out(pc->dev->bus, 1, 1); diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c index bb18d76f9f2c..55e101115038 100644 --- a/drivers/ssb/embedded.c +++ b/drivers/ssb/embedded.c @@ -57,9 +57,8 @@ int ssb_watchdog_register(struct ssb_bus *bus) bus->busnumber, &wdt, sizeof(wdt)); if (IS_ERR(pdev)) { - ssb_dprintk(KERN_INFO PFX - "can not register watchdog device, err: %li\n", - PTR_ERR(pdev)); + ssb_dbg("can not register watchdog device, err: %li\n", + PTR_ERR(pdev)); return PTR_ERR(pdev); } diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 3b645b8a261f..812775a4bfb6 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -275,8 +275,8 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx) err = sdrv->probe(sdev, &sdev->id); if (err) { - ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n", - dev_name(sdev->dev)); + ssb_err("Failed to thaw device %s\n", + dev_name(sdev->dev)); result = err; } ssb_device_put(sdev); @@ -447,10 +447,9 @@ void ssb_bus_unregister(struct ssb_bus *bus) err = ssb_gpio_unregister(bus); if (err == -EBUSY) - ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n"); + ssb_dbg("Some GPIOs are still in use\n"); else if (err) - ssb_dprintk(KERN_ERR PFX - "Can not unregister GPIO driver: %i\n", err); + ssb_dbg("Can not unregister GPIO driver: %i\n", err); ssb_buses_lock(); ssb_devices_unregister(bus); @@ -497,8 +496,7 @@ static int ssb_devices_register(struct ssb_bus *bus) devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL); if (!devwrap) { - ssb_printk(KERN_ERR PFX - "Could not allocate device\n"); + ssb_err("Could not allocate device\n"); err = -ENOMEM; goto error; } @@ -537,9 +535,7 @@ static int ssb_devices_register(struct ssb_bus *bus) sdev->dev = dev; err = device_register(dev); if (err) { - ssb_printk(KERN_ERR PFX - "Could not register %s\n", - dev_name(dev)); + ssb_err("Could not register %s\n", dev_name(dev)); /* Set dev to NULL to not unregister * dev on error unwinding. */ sdev->dev = NULL; @@ -825,10 +821,9 @@ static int ssb_bus_register(struct ssb_bus *bus, ssb_mipscore_init(&bus->mipscore); err = ssb_gpio_init(bus); if (err == -ENOTSUPP) - ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n"); + ssb_dbg("GPIO driver not activated\n"); else if (err) - ssb_dprintk(KERN_ERR PFX - "Error registering GPIO driver: %i\n", err); + ssb_dbg("Error registering GPIO driver: %i\n", err); err = ssb_fetch_invariants(bus, get_invariants); if (err) { ssb_bus_may_powerdown(bus); @@ -878,11 +873,11 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus, struct pci_dev *host_pci) err = ssb_bus_register(bus, ssb_pci_get_invariants, 0); if (!err) { - ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " - "PCI device %s\n", dev_name(&host_pci->dev)); + ssb_info("Sonics Silicon Backplane found on PCI device %s\n", + dev_name(&host_pci->dev)); } else { - ssb_printk(KERN_ERR PFX "Failed to register PCI version" - " of SSB with error %d\n", err); + ssb_err("Failed to register PCI version of SSB with error %d\n", + err); } return err; @@ -903,8 +898,8 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus, err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr); if (!err) { - ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " - "PCMCIA device %s\n", pcmcia_dev->devname); + ssb_info("Sonics Silicon Backplane found on PCMCIA device %s\n", + pcmcia_dev->devname); } return err; @@ -925,8 +920,8 @@ int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0); if (!err) { - ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " - "SDIO device %s\n", sdio_func_id(func)); + ssb_info("Sonics Silicon Backplane found on SDIO device %s\n", + sdio_func_id(func)); } return err; @@ -944,8 +939,8 @@ int ssb_bus_ssbbus_register(struct ssb_bus *bus, unsigned long baseaddr, err = ssb_bus_register(bus, get_invariants, baseaddr); if (!err) { - ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at " - "address 0x%08lX\n", baseaddr); + ssb_info("Sonics Silicon Backplane found at address 0x%08lX\n", + baseaddr); } return err; @@ -1339,7 +1334,7 @@ out: #endif return err; error: - ssb_printk(KERN_ERR PFX "Bus powerdown failed\n"); + ssb_err("Bus powerdown failed\n"); goto out; } EXPORT_SYMBOL(ssb_bus_may_powerdown); @@ -1362,7 +1357,7 @@ int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl) return 0; error: - ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); + ssb_err("Bus powerup failed\n"); return err; } EXPORT_SYMBOL(ssb_bus_powerup); @@ -1470,15 +1465,13 @@ static int __init ssb_modinit(void) err = b43_pci_ssb_bridge_init(); if (err) { - ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " - "initialization failed\n"); + ssb_err("Broadcom 43xx PCI-SSB-bridge initialization failed\n"); /* don't fail SSB init because of this */ err = 0; } err = ssb_gige_init(); if (err) { - ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet " - "driver initialization failed\n"); + ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n"); /* don't fail SSB init because of this */ err = 0; } diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 4ec0bdbf25ed..6d6e7b926aa5 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -56,7 +56,7 @@ int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx) } return 0; error: - ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); + ssb_err("Failed to switch to core %u\n", coreidx); return -ENODEV; } @@ -67,10 +67,9 @@ int ssb_pci_switch_core(struct ssb_bus *bus, unsigned long flags; #if SSB_VERBOSE_PCICORESWITCH_DEBUG - ssb_printk(KERN_INFO PFX - "Switching to %s core, index %d\n", - ssb_core_name(dev->id.coreid), - dev->core_index); + ssb_info("Switching to %s core, index %d\n", + ssb_core_name(dev->id.coreid), + dev->core_index); #endif spin_lock_irqsave(&bus->bar_lock, flags); @@ -287,7 +286,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) u32 spromctl; u16 size = bus->sprom_size; - ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); + ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); if (err) goto err_ctlreg; @@ -295,17 +294,17 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); if (err) goto err_ctlreg; - ssb_printk(KERN_NOTICE PFX "[ 0%%"); + ssb_notice("[ 0%%"); msleep(500); for (i = 0; i < size; i++) { if (i == size / 4) - ssb_printk("25%%"); + ssb_cont("25%%"); else if (i == size / 2) - ssb_printk("50%%"); + ssb_cont("50%%"); else if (i == (size * 3) / 4) - ssb_printk("75%%"); + ssb_cont("75%%"); else if (i % 2) - ssb_printk("."); + ssb_cont("."); writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); mmiowb(); msleep(20); @@ -318,12 +317,12 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) if (err) goto err_ctlreg; msleep(500); - ssb_printk("100%% ]\n"); - ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); + ssb_cont("100%% ]\n"); + ssb_notice("SPROM written\n"); return 0; err_ctlreg: - ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n"); + ssb_err("Could not access SPROM control register.\n"); return err; } @@ -735,7 +734,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, memset(out, 0, sizeof(*out)); out->revision = in[size - 1] & 0x00FF; - ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); + ssb_dbg("SPROM revision %d detected\n", out->revision); memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ memset(out->et1mac, 0xFF, 6); @@ -744,7 +743,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, * number stored in the SPROM. * Always extract r1. */ out->revision = 1; - ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); + ssb_dbg("SPROM treated as revision %d\n", out->revision); } switch (out->revision) { @@ -761,9 +760,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, sprom_extract_r8(out, in); break; default: - ssb_printk(KERN_WARNING PFX "Unsupported SPROM" - " revision %d detected. Will extract" - " v1\n", out->revision); + ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n", + out->revision); out->revision = 1; sprom_extract_r123(out, in); } @@ -783,7 +781,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, u16 *buf; if (!ssb_is_sprom_available(bus)) { - ssb_printk(KERN_ERR PFX "No SPROM available!\n"); + ssb_err("No SPROM available!\n"); return -ENODEV; } if (bus->chipco.dev) { /* can be unavailable! */ @@ -802,7 +800,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, } else { bus->sprom_offset = SSB_SPROM_BASE1; } - ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); + ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset); buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) @@ -827,18 +825,15 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, * available for this device in some other storage */ err = ssb_fill_sprom_with_fallback(bus, sprom); if (err) { - ssb_printk(KERN_WARNING PFX "WARNING: Using" - " fallback SPROM failed (err %d)\n", - err); + ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n", + err); } else { - ssb_dprintk(KERN_DEBUG PFX "Using SPROM" - " revision %d provided by" - " platform.\n", sprom->revision); + ssb_dbg("Using SPROM revision %d provided by platform\n", + sprom->revision); err = 0; goto out_free; } - ssb_printk(KERN_WARNING PFX "WARNING: Invalid" - " SPROM CRC (corrupt SPROM)\n"); + ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); } } err = sprom_extract(bus, sprom, buf, bus->sprom_size); diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index fbafed5b729b..b413e0187087 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c @@ -143,7 +143,7 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, return 0; error: - ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); + ssb_err("Failed to switch to core %u\n", coreidx); return err; } @@ -153,10 +153,9 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus, int err; #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG - ssb_printk(KERN_INFO PFX - "Switching to %s core, index %d\n", - ssb_core_name(dev->id.coreid), - dev->core_index); + ssb_info("Switching to %s core, index %d\n", + ssb_core_name(dev->id.coreid), + dev->core_index); #endif err = ssb_pcmcia_switch_coreidx(bus, dev->core_index); @@ -192,7 +191,7 @@ int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg) return 0; error: - ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n"); + ssb_err("Failed to switch pcmcia segment\n"); return err; } @@ -549,44 +548,39 @@ static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom) bool failed = 0; size_t size = SSB_PCMCIA_SPROM_SIZE; - ssb_printk(KERN_NOTICE PFX - "Writing SPROM. Do NOT turn off the power! " - "Please stand by...\n"); + ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN); if (err) { - ssb_printk(KERN_NOTICE PFX - "Could not enable SPROM write access.\n"); + ssb_notice("Could not enable SPROM write access\n"); return -EBUSY; } - ssb_printk(KERN_NOTICE PFX "[ 0%%"); + ssb_notice("[ 0%%"); msleep(500); for (i = 0; i < size; i++) { if (i == size / 4) - ssb_printk("25%%"); + ssb_cont("25%%"); else if (i == size / 2) - ssb_printk("50%%"); + ssb_cont("50%%"); else if (i == (size * 3) / 4) - ssb_printk("75%%"); + ssb_cont("75%%"); else if (i % 2) - ssb_printk("."); + ssb_cont("."); err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); if (err) { - ssb_printk(KERN_NOTICE PFX - "Failed to write to SPROM.\n"); + ssb_notice("Failed to write to SPROM\n"); failed = 1; break; } } err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); if (err) { - ssb_printk(KERN_NOTICE PFX - "Could not disable SPROM write access.\n"); + ssb_notice("Could not disable SPROM write access\n"); failed = 1; } msleep(500); if (!failed) { - ssb_printk("100%% ]\n"); - ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); + ssb_cont("100%% ]\n"); + ssb_notice("SPROM written\n"); } return failed ? -EBUSY : 0; @@ -700,7 +694,7 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev, return -ENOSPC; /* continue with next entry */ error: - ssb_printk(KERN_ERR PFX + ssb_err( "PCMCIA: Failed to fetch device invariants: %s\n", error_description); return -ENODEV; @@ -722,7 +716,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE, ssb_pcmcia_get_mac, sprom); if (res != 0) { - ssb_printk(KERN_ERR PFX + ssb_err( "PCMCIA: Failed to fetch MAC address\n"); return -ENODEV; } @@ -733,7 +727,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, if ((res == 0) || (res == -ENOSPC)) return 0; - ssb_printk(KERN_ERR PFX + ssb_err( "PCMCIA: Failed to fetch device invariants\n"); return -ENODEV; } @@ -843,6 +837,6 @@ int ssb_pcmcia_init(struct ssb_bus *bus) return 0; error: - ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n"); + ssb_err("Failed to initialize PCMCIA host device\n"); return err; } diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index ab4627cf1114..b9429df583eb 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -125,8 +125,7 @@ static u16 pcidev_to_chipid(struct pci_dev *pci_dev) chipid_fallback = 0x4401; break; default: - ssb_printk(KERN_ERR PFX - "PCI-ID not in fallback list\n"); + ssb_err("PCI-ID not in fallback list\n"); } return chipid_fallback; @@ -152,8 +151,7 @@ static u8 chipid_to_nrcores(u16 chipid) case 0x4704: return 9; default: - ssb_printk(KERN_ERR PFX - "CHIPID not in nrcores fallback list\n"); + ssb_err("CHIPID not in nrcores fallback list\n"); } return 1; @@ -320,15 +318,13 @@ int ssb_bus_scan(struct ssb_bus *bus, bus->chip_package = 0; } } - ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and " - "package 0x%02X\n", bus->chip_id, bus->chip_rev, - bus->chip_package); + ssb_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n", + bus->chip_id, bus->chip_rev, bus->chip_package); if (!bus->nr_devices) bus->nr_devices = chipid_to_nrcores(bus->chip_id); if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { - ssb_printk(KERN_ERR PFX - "More than %d ssb cores found (%d)\n", - SSB_MAX_NR_CORES, bus->nr_devices); + ssb_err("More than %d ssb cores found (%d)\n", + SSB_MAX_NR_CORES, bus->nr_devices); goto err_unmap; } if (bus->bustype == SSB_BUSTYPE_SSB) { @@ -370,8 +366,7 @@ int ssb_bus_scan(struct ssb_bus *bus, nr_80211_cores++; if (nr_80211_cores > 1) { if (!we_support_multiple_80211_cores(bus)) { - ssb_dprintk(KERN_INFO PFX "Ignoring additional " - "802.11 core\n"); + ssb_dbg("Ignoring additional 802.11 core\n"); continue; } } @@ -379,8 +374,7 @@ int ssb_bus_scan(struct ssb_bus *bus, case SSB_DEV_EXTIF: #ifdef CONFIG_SSB_DRIVER_EXTIF if (bus->extif.dev) { - ssb_printk(KERN_WARNING PFX - "WARNING: Multiple EXTIFs found\n"); + ssb_warn("WARNING: Multiple EXTIFs found\n"); break; } bus->extif.dev = dev; @@ -388,8 +382,7 @@ int ssb_bus_scan(struct ssb_bus *bus, break; case SSB_DEV_CHIPCOMMON: if (bus->chipco.dev) { - ssb_printk(KERN_WARNING PFX - "WARNING: Multiple ChipCommon found\n"); + ssb_warn("WARNING: Multiple ChipCommon found\n"); break; } bus->chipco.dev = dev; @@ -398,8 +391,7 @@ int ssb_bus_scan(struct ssb_bus *bus, case SSB_DEV_MIPS_3302: #ifdef CONFIG_SSB_DRIVER_MIPS if (bus->mipscore.dev) { - ssb_printk(KERN_WARNING PFX - "WARNING: Multiple MIPS cores found\n"); + ssb_warn("WARNING: Multiple MIPS cores found\n"); break; } bus->mipscore.dev = dev; @@ -420,8 +412,7 @@ int ssb_bus_scan(struct ssb_bus *bus, } } if (bus->pcicore.dev) { - ssb_printk(KERN_WARNING PFX - "WARNING: Multiple PCI(E) cores found\n"); + ssb_warn("WARNING: Multiple PCI(E) cores found\n"); break; } bus->pcicore.dev = dev; diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 80d366fcf8d3..a3b23644b0fb 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -127,13 +127,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus, goto out_kfree; err = ssb_devices_freeze(bus, &freeze); if (err) { - ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n"); + ssb_err("SPROM write: Could not freeze all devices\n"); goto out_unlock; } res = sprom_write(bus, sprom); err = ssb_devices_thaw(&freeze); if (err) - ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n"); + ssb_err("SPROM write: Could not thaw all devices\n"); out_unlock: mutex_unlock(&bus->sprom_mutex); out_kfree: diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 466171b77f68..4671f17f09af 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -9,16 +9,27 @@ #define PFX "ssb: " #ifdef CONFIG_SSB_SILENT -# define ssb_printk(fmt, x...) do { /* nothing */ } while (0) +# define ssb_printk(fmt, ...) \ + do { if (0) printk(fmt, ##__VA_ARGS__); } while (0) #else -# define ssb_printk printk +# define ssb_printk(fmt, ...) \ + printk(fmt, ##__VA_ARGS__) #endif /* CONFIG_SSB_SILENT */ +#define ssb_emerg(fmt, ...) ssb_printk(KERN_EMERG PFX fmt, ##__VA_ARGS__) +#define ssb_err(fmt, ...) ssb_printk(KERN_ERR PFX fmt, ##__VA_ARGS__) +#define ssb_warn(fmt, ...) ssb_printk(KERN_WARNING PFX fmt, ##__VA_ARGS__) +#define ssb_notice(fmt, ...) ssb_printk(KERN_NOTICE PFX fmt, ##__VA_ARGS__) +#define ssb_info(fmt, ...) ssb_printk(KERN_INFO PFX fmt, ##__VA_ARGS__) +#define ssb_cont(fmt, ...) ssb_printk(KERN_CONT fmt, ##__VA_ARGS__) + /* dprintk: Debugging printk; vanishes for non-debug compilation */ #ifdef CONFIG_SSB_DEBUG -# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x) +# define ssb_dbg(fmt, ...) \ + ssb_printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__) #else -# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0) +# define ssb_dbg(fmt, ...) \ + do { if (0) printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__); } while (0) #endif #ifdef CONFIG_SSB_DEBUG -- cgit From 3a703ab5fba5b00292c1e7e964783c304f43fef7 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Mon, 18 Feb 2013 12:56:28 -0700 Subject: rt2x00: rt2x00pci_regbusy_read() - only print register access failure once BugLink: http://bugs.launchpad.net/bugs/1128840 It appears that when this register read fails it never recovers, so I think there is no need to repeat the same error message ad infinitum. Cc: Ivo van Doorn Cc: Gertjan van Wingerde Cc: Helmut Schaa Cc: "John W. Linville" Cc: linux-wireless@vger.kernel.org Cc: users@rt2x00.serialmonkey.com Cc: netdev@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Tim Gardner Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index a0c8caef3b0a..b1c673ecada1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + printk_once(KERN_ERR "%s() Indirect register access failed: " + "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg); *reg = ~0; return 0; -- cgit From 10419d08b96e58e140ca44293ee941973396adee Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 19 Feb 2013 19:41:42 +0100 Subject: bcma: ignore extra GMAC cores on BCM4706 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 9a6188add590..f72f52b4b1dd 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -120,6 +120,11 @@ static int bcma_register_cores(struct bcma_bus *bus) continue; } + /* Only first GMAC core on BCM4706 is connected and working */ + if (core->id.id == BCMA_CORE_4706_MAC_GBIT && + core->core_unit > 0) + continue; + core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id); -- cgit From a829148435618174a08154a478e4e64fa44eb4d4 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 21 Feb 2013 07:34:42 -0500 Subject: b43: Fix 'me' -> 'be' typo in Kconfig Also add a missing 'the' before 'runtime performance'. Signed-off-by: W. Trevor King Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 287c6b670a36..c3024ecea38a 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -166,8 +166,8 @@ config B43_DEBUG Broadcom 43xx debugging. This adds additional runtime sanity checks and statistics to the driver. - These checks and statistics might me expensive and hurt runtime performance - of your system. + These checks and statistics might be expensive and hurt the runtime + performance of your system. This also adds the b43 debugfs interface. Do not enable this, unless you are debugging the driver. -- cgit From 5f34608fa2acbfef5a06d0072a978c9943c28a2d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 22 Feb 2013 01:30:44 +0100 Subject: carl9170: fix frame drop and WARN due to minstrel_ht change With "mac80211/minstrel_ht: add support for using CCK rates" minstrel_ht selects legacy CCK rates as viable rates for outgoing frames which might be sent as part of an A-MPDU [IEEE80211_TX_CTL_AMPDU is set]. This behavior triggered the following WARN_ON in the driver: > WARNING: at carl9170/tx.c:995 carl9170_op_tx+0x1dd/0x6fd The driver assumed that the rate control algorithm made a mistake and dropped the frame. This patch removes the noisy warning altogether and allows said A-MPDU frames with CCK sample and/or fallback rates to be transmitted seamlessly. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 69 ++++++++++++++-------------------- 1 file changed, 28 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 9c0b150d5b8e..c61cafa2665b 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -387,8 +387,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, u8 tid; if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || - txinfo->flags & IEEE80211_TX_CTL_INJECTED || - (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) + txinfo->flags & IEEE80211_TX_CTL_INJECTED) return; rcu_read_lock(); @@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar9170 *ar, SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, txc->s.ampdu_settings, factor); - - for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { - txrate = &info->control.rates[i]; - if (txrate->idx >= 0) { - txc->s.ri[i] = - CARL9170_TX_SUPER_RI_AMPDU; - - if (WARN_ON(!(txrate->flags & - IEEE80211_TX_RC_MCS))) { - /* - * Not sure if it's even possible - * to aggregate non-ht rates with - * this HW. - */ - goto err_out; - } - continue; - } - - txrate->idx = 0; - txrate->count = ar->hw->max_rate_tries; - } - - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); } /* @@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar9170 *ar, * taken from mac_control. For all fallback rate, the firmware * updates the mac_control flags from the rate info field. */ - for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { + __le32 phy_set; txrate = &info->control.rates[i]; if (txrate->idx < 0) break; + phy_set = carl9170_tx_physet(ar, info, txrate); + if (i == 0) { + /* first rate - part of the hw's frame header */ + txc->f.phy_control = phy_set; + + if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); + else if (carl9170_tx_cts_check(ar, txrate)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); + + } else { + /* fallback rates are stored in the firmware's + * retry rate set array. + */ + txc->s.rr[i - 1] = phy_set; + } + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], txrate->count); @@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar9170 *ar, txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << CARL9170_TX_SUPER_RI_ERP_PROT_S); - txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); + if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS)) + txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU; } - txrate = &info->control.rates[0]; - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); - - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - else if (carl9170_tx_cts_check(ar, txrate)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); - txc->s.len = cpu_to_le16(skb->len); txc->f.length = cpu_to_le16(len + FCS_LEN); txc->f.mac_control = mac_tmp; - txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); arinfo = (void *)info->rate_driver_data; arinfo->timeout = jiffies; @@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *ar) } static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, - struct ieee80211_sta *sta, struct sk_buff *skb) + struct ieee80211_sta *sta, struct sk_buff *skb, + struct ieee80211_tx_info *txinfo) { - struct _carl9170_tx_superframe *super = (void *) skb->data; struct carl9170_sta_info *sta_info; struct carl9170_sta_tid *agg; struct sk_buff *iter; @@ -1450,7 +1437,7 @@ err_unlock: err_unlock_rcu: rcu_read_unlock(); - super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); + txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU; carl9170_tx_status(ar, skb, false); ar->tx_dropped++; return false; @@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw *hw, * sta == NULL checks are redundant in this * special case. */ - run = carl9170_tx_ampdu_queue(ar, sta, skb); + run = carl9170_tx_ampdu_queue(ar, sta, skb, info); if (run) carl9170_tx_ampdu(ar); -- cgit From 7626cf19713464dbad96abba3f375771447925e6 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 24 Feb 2013 16:41:34 +0100 Subject: brcmsmac: export firmware version to ethtool This exports the firmware version in use to userspace through ethtool. root@OpenWrt:/# ethtool -i wlan0 firmware-version: 610.812 Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 8ef02dca8f8c..0c8e998bfb1e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -7810,9 +7810,14 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) /* read the ucode version if we have not yet done so */ if (wlc->ucode_rev == 0) { - wlc->ucode_rev = - brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16); - wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR); + u16 rev; + u16 patch; + + rev = brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR); + patch = brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR); + wlc->ucode_rev = (rev << NBITS(u16)) | patch; + snprintf(wlc->wiphy->fw_version, + sizeof(wlc->wiphy->fw_version), "%u.%u", rev, patch); } /* ..now really unleash hell (allow the MAC out of suspend) */ -- cgit From cd3d03d596a4d8b31fcec40120472ea518d8232e Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 03:35:43 +0530 Subject: rndis_wlan: Remove redundant NULL check before kfree kfree on a NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 525fd7521dff..5f66b4eac298 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2839,8 +2839,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); - if (info != NULL) - kfree(info); + kfree(info); priv->connected = true; memcpy(priv->bssid, bssid, ETH_ALEN); -- cgit From 188741731ce1148c0f8ab63ff41c81ce56ac1e74 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 25 Feb 2013 15:36:48 +0100 Subject: ath5k: cleanup channel to eprom_mode function Stop returning negative values from ath5k_eeprom_mode_from_channel. Yell loudly about that case in that function instead and return the default/zero/mode A. This cleans up the callers, but needs to pass ah down to ath5k_eeprom_mode_from_channel for ATH5K_WARN. For that purpose we also need the declaration to be moved to ath5k.h. Signed-off-by: Jiri Slaby Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 ++- drivers/net/wireless/ath/ath5k/eeprom.c | 6 ++++-- drivers/net/wireless/ath/ath5k/eeprom.h | 3 --- drivers/net/wireless/ath/ath5k/phy.c | 20 +++----------------- drivers/net/wireless/ath/ath5k/reset.c | 4 +--- 5 files changed, 10 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 3150def17193..2d691b8b95b9 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1523,7 +1523,8 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah); /* EEPROM access functions */ int ath5k_eeprom_init(struct ath5k_hw *ah); void ath5k_eeprom_detach(struct ath5k_hw *ah); - +int ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah, + struct ieee80211_channel *channel); /* Protocol Control Unit Functions */ /* Helpers */ diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index b7e0258887e7..94d34ee02265 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1779,7 +1779,8 @@ ath5k_eeprom_detach(struct ath5k_hw *ah) } int -ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) +ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah, + struct ieee80211_channel *channel) { switch (channel->hw_value) { case AR5K_MODE_11A: @@ -1789,6 +1790,7 @@ ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) case AR5K_MODE_11B: return AR5K_EEPROM_MODE_11B; default: - return -1; + ATH5K_WARN(ah, "channel is not A/B/G!"); + return AR5K_EEPROM_MODE_11A; } } diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 94a9bbea6874..693296ee9693 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -493,6 +493,3 @@ struct ath5k_eeprom_info { /* Antenna raw switch tables */ u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; }; - -int -ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel); diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index a78afa98c650..d6bc7cb61bfb 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1612,11 +1612,7 @@ ath5k_hw_update_noise_floor(struct ath5k_hw *ah) ah->ah_cal_mask |= AR5K_CALIBRATION_NF; - ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); - if (WARN_ON(ee_mode < 0)) { - ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF; - return; - } + ee_mode = ath5k_eeprom_mode_from_channel(ah, ah->ah_current_channel); /* completed NF calibration, test threshold */ nf = ath5k_hw_read_measured_noise_floor(ah); @@ -2317,12 +2313,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) def_ant = ah->ah_def_ant; - ee_mode = ath5k_eeprom_mode_from_channel(channel); - if (ee_mode < 0) { - ATH5K_ERR(ah, - "invalid channel: %d\n", channel->center_freq); - return; - } + ee_mode = ath5k_eeprom_mode_from_channel(ah, channel); switch (ant_mode) { case AR5K_ANTMODE_DEFAULT: @@ -3622,12 +3613,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - ee_mode = ath5k_eeprom_mode_from_channel(channel); - if (ee_mode < 0) { - ATH5K_ERR(ah, - "invalid channel: %d\n", channel->center_freq); - return -EINVAL; - } + ee_mode = ath5k_eeprom_mode_from_channel(ah, channel); /* Initialize TX power table */ switch (ah->ah_radio) { diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index e2d8b2cf19eb..a3399c4f13a9 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -984,9 +984,7 @@ ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, if (ah->ah_version == AR5K_AR5210) return; - ee_mode = ath5k_eeprom_mode_from_channel(channel); - if (WARN_ON(ee_mode < 0)) - return; + ee_mode = ath5k_eeprom_mode_from_channel(ah, channel); /* Adjust power delta for channel 14 */ if (channel->center_freq == 2484) -- cgit From 93ecbd64effe18389d219f26bdcf148fb0979889 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 26 Feb 2013 10:29:34 +0800 Subject: wil6210: convert to use simple_open() This removes an open coded simple_open() function and replaces file operations references to the function with simple_open() instead. Signed-off-by: Wei Yongjun Acked-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/debugfs.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 65fc9683bfd8..1e709bfb63a3 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -312,14 +312,6 @@ static const struct file_operations fops_memread = { .llseek = seq_lseek, }; -static int wil_default_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - - return 0; -} - static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -361,7 +353,7 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, static const struct file_operations fops_ioblob = { .read = wil_read_file_ioblob, - .open = wil_default_open, + .open = simple_open, .llseek = default_llseek, }; @@ -396,7 +388,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, static const struct file_operations fops_reset = { .write = wil_write_file_reset, - .open = wil_default_open, + .open = simple_open, }; /*---------Tx descriptor------------*/ @@ -526,7 +518,7 @@ static ssize_t wil_write_file_ssid(struct file *file, const char __user *buf, static const struct file_operations fops_ssid = { .read = wil_read_file_ssid, .write = wil_write_file_ssid, - .open = wil_default_open, + .open = simple_open, }; /*----------------*/ -- cgit From c722839cc856cee5f7f1bb833a0f36c86d0bbe8f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 26 Feb 2013 10:02:23 +0100 Subject: bcma: implement disabling PLLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c index 03bbe104338f..17b26ce7e051 100644 --- a/drivers/bcma/core.c +++ b/drivers/bcma/core.c @@ -104,7 +104,13 @@ void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on) if (i) bcma_err(core->bus, "PLL enable timeout\n"); } else { - bcma_warn(core->bus, "Disabling PLL not supported yet!\n"); + /* + * Mask the PLL but don't wait for it to be disabled. PLL may be + * shared between cores and will be still up if there is another + * core using it. + */ + bcma_mask32(core, BCMA_CLKCTLST, ~req); + bcma_read32(core, BCMA_CLKCTLST); } } EXPORT_SYMBOL_GPL(bcma_core_pll_ctl); -- cgit From 88cceab541f066b7f5d56a6d2da9ae2be4c3bb6c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 26 Feb 2013 10:07:57 +0100 Subject: b43: define BCMA wireless specific PLLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 6 ++++++ drivers/net/wireless/b43/main.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 10e288d470e7..fe4a77ee05c9 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -473,6 +473,12 @@ enum { #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ +/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */ +#define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100 +#define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200 +#define B43_BCMA_CLKCTLST_80211_PLL_ST 0x01000000 +#define B43_BCMA_CLKCTLST_PHY_PLL_ST 0x02000000 + /* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */ #define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */ #define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 05682736e466..c4d0cc582555 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1189,10 +1189,15 @@ static void b43_bcma_phy_reset(struct b43_wldev *dev) static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) { + u32 req = B43_BCMA_CLKCTLST_80211_PLL_REQ | + B43_BCMA_CLKCTLST_PHY_PLL_REQ; + u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST | + B43_BCMA_CLKCTLST_PHY_PLL_ST; + b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN); bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); b43_bcma_phy_reset(dev); - bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true); + bcma_core_pll_ctl(dev->dev->bdev, req, status, true); } #endif -- cgit From 2dcc26e37c55b9db2f3a0ea6e4b931e37ca286d2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 26 Feb 2013 13:04:51 +0300 Subject: ray_cs: read past the end of the array "translate" should either be set or disabled. We also use it an offset into the framing[] array when we're generating the proc file. Framing looks like this: static const char *framing[] = { "Encapsulation", "Translation" } So when we're setting translate we need to restrict the values to either 1 or 0 or it can an out of bounds read. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ray_cs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 3109c0db66e1..4775b5d172d5 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -144,7 +144,7 @@ static int psm; static char *essid; /* Default to encapsulation unless translation requested */ -static int translate = 1; +static bool translate = 1; static int country = USA; @@ -178,7 +178,7 @@ module_param(hop_dwell, int, 0); module_param(beacon_period, int, 0); module_param(psm, int, 0); module_param(essid, charp, 0); -module_param(translate, int, 0); +module_param(translate, bool, 0); module_param(country, int, 0); module_param(sniffer, int, 0); module_param(bc, int, 0); @@ -1353,7 +1353,7 @@ static int ray_get_range(struct net_device *dev, struct iw_request_info *info, static int ray_set_framing(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - translate = *(extra); /* Set framing mode */ + translate = !!*(extra); /* Set framing mode */ return 0; } -- cgit From 4ba910db199779470685dd962d626e1ffc657f7e Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Tue, 26 Feb 2013 13:41:52 -0500 Subject: ath9k: simplify ATH_EP_RND Remove the embedded branch to make the ATH_EP_RND macro a little clearer. The new version also generates better code, saving 24 bytes of text: text data bss dec hex filename 87858 1641 24 89523 15db3 ath9k_orig.ko 87834 1641 24 89499 15d9b ath9k_new.ko Although neither version handles negative values particularly well, the lone caller clamps all negative values to zero anyway. I have verified that the results are the same for the range of possible positive rssi values. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 5f845beeb18b..eca95a0c3890 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -40,7 +40,7 @@ x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ } while (0) #define ATH_EP_RND(x, mul) \ - ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) + (((x) + ((mul)/2)) / (mul)) int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); -- cgit From 6f56b06e74e2805577bf7940dc0fb17b3310d6b6 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 27 Feb 2013 14:55:06 +0800 Subject: drivers/net/wireless/ath/wil6210: Makefile, only -Werror when no -W* in EXTRA_CFLAGS When make with EXTRA_CFLAGS=-W, it will report error. so give a check in Makefile. Signed-off-by: Chen Gang Acked-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile index 9396dc9fe3c5..d288eea0a26a 100644 --- a/drivers/net/wireless/ath/wil6210/Makefile +++ b/drivers/net/wireless/ath/wil6210/Makefile @@ -9,5 +9,7 @@ wil6210-objs += wmi.o wil6210-objs += interrupt.o wil6210-objs += txrx.o -subdir-ccflags-y += -Werror +ifeq (, $(findstring -W,$(EXTRA_CFLAGS))) + subdir-ccflags-y += -Werror +endif subdir-ccflags-y += -D__CHECK_ENDIAN__ -- cgit From f6baf153eec3cd195589b7cfe32b4ea62d8ec9d1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Feb 2013 07:45:47 +0300 Subject: ath6kl: small cleanup in ath6kl_htc_pipe_rx_complete() It's harmless, but Smatch complains if we use "htc_hdr->eid" before doing the bounds check. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index 281390178e3d..9adb56741bc3 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -988,8 +988,6 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, htc_hdr = (struct htc_frame_hdr *) netdata; - ep = &target->endpoint[htc_hdr->eid]; - if (htc_hdr->eid >= ENDPOINT_MAX) { ath6kl_dbg(ATH6KL_DBG_HTC, "HTC Rx: invalid EndpointID=%d\n", @@ -997,6 +995,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, status = -EINVAL; goto free_skb; } + ep = &target->endpoint[htc_hdr->eid]; payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len)); -- cgit From d926dc7de89ca3caa550a393b2a00715acb744ea Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Fri, 1 Mar 2013 17:12:45 +0530 Subject: mwl8k: Adding support for 8764 4x4 AP The patch does the following:- a Add entry in the PCIe table b Add firmware support with API versioning c Reuse most of the 8366 code d Make 8764 specific changes where 8764 differs from 8366 e.g. structure definitions. Signed-off-by: Nishant Sarmukadam Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 78 +++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 091d9a64080a..e86a31bac45f 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -908,9 +908,9 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv, } /* - * Packet reception for 88w8366 AP firmware. + * Packet reception for 88w8366/88w8764 AP firmware. */ -struct mwl8k_rxd_8366_ap { +struct mwl8k_rxd_ap { __le16 pkt_len; __u8 sq2; __u8 rate; @@ -928,30 +928,30 @@ struct mwl8k_rxd_8366_ap { __u8 rx_ctrl; } __packed; -#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80 -#define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40 -#define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f) +#define MWL8K_AP_RATE_INFO_MCS_FORMAT 0x80 +#define MWL8K_AP_RATE_INFO_40MHZ 0x40 +#define MWL8K_AP_RATE_INFO_RATEID(x) ((x) & 0x3f) -#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80 +#define MWL8K_AP_RX_CTRL_OWNED_BY_HOST 0x80 -/* 8366 AP rx_status bits */ -#define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK 0x80 -#define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF -#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02 -#define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04 -#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08 +/* 8366/8764 AP rx_status bits */ +#define MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK 0x80 +#define MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF +#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02 +#define MWL8K_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04 +#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08 -static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr) +static void mwl8k_rxd_ap_init(void *_rxd, dma_addr_t next_dma_addr) { - struct mwl8k_rxd_8366_ap *rxd = _rxd; + struct mwl8k_rxd_ap *rxd = _rxd; rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); - rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST; + rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST; } -static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) +static void mwl8k_rxd_ap_refill(void *_rxd, dma_addr_t addr, int len) { - struct mwl8k_rxd_8366_ap *rxd = _rxd; + struct mwl8k_rxd_ap *rxd = _rxd; rxd->pkt_len = cpu_to_le16(len); rxd->pkt_phys_addr = cpu_to_le32(addr); @@ -960,12 +960,12 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) } static int -mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, - __le16 *qos, s8 *noise) +mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status, + __le16 *qos, s8 *noise) { - struct mwl8k_rxd_8366_ap *rxd = _rxd; + struct mwl8k_rxd_ap *rxd = _rxd; - if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST)) + if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST)) return -1; rmb(); @@ -974,11 +974,11 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, status->signal = -rxd->rssi; *noise = -rxd->noise_floor; - if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { + if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) { status->flag |= RX_FLAG_HT; - if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ) + if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ) status->flag |= RX_FLAG_40MHZ; - status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate); + status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate); } else { int i; @@ -1002,19 +1002,19 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, *qos = rxd->qos_control; - if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) && - (rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) && - (rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) + if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) && + (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) && + (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) status->flag |= RX_FLAG_MMIC_ERROR; return le16_to_cpu(rxd->pkt_len); } -static struct rxd_ops rxd_8366_ap_ops = { - .rxd_size = sizeof(struct mwl8k_rxd_8366_ap), - .rxd_init = mwl8k_rxd_8366_ap_init, - .rxd_refill = mwl8k_rxd_8366_ap_refill, - .rxd_process = mwl8k_rxd_8366_ap_process, +static struct rxd_ops rxd_ap_ops = { + .rxd_size = sizeof(struct mwl8k_rxd_ap), + .rxd_init = mwl8k_rxd_ap_init, + .rxd_refill = mwl8k_rxd_ap_refill, + .rxd_process = mwl8k_rxd_ap_process, }; /* @@ -5429,12 +5429,17 @@ enum { MWL8363 = 0, MWL8687, MWL8366, + MWL8764, }; #define MWL8K_8366_AP_FW_API 3 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) +#define MWL8K_8764_AP_FW_API 1 +#define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw" +#define MWL8K_8764_AP_FW(api) _MWL8K_8764_AP_FW(api) + static struct mwl8k_device_info mwl8k_info_tbl[] = { [MWL8363] = { .part_name = "88w8363", @@ -5452,7 +5457,13 @@ static struct mwl8k_device_info mwl8k_info_tbl[] = { .fw_image_sta = "mwl8k/fmimage_8366.fw", .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API), .fw_api_ap = MWL8K_8366_AP_FW_API, - .ap_rxd_ops = &rxd_8366_ap_ops, + .ap_rxd_ops = &rxd_ap_ops, + }, + [MWL8764] = { + .part_name = "88w8764", + .fw_image_ap = MWL8K_8764_AP_FW(MWL8K_8764_AP_FW_API), + .fw_api_ap = MWL8K_8764_AP_FW_API, + .ap_rxd_ops = &rxd_ap_ops, }, }; @@ -5474,6 +5485,7 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { { PCI_VDEVICE(MARVELL, 0x2a41), .driver_data = MWL8366, }, { PCI_VDEVICE(MARVELL, 0x2a42), .driver_data = MWL8366, }, { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, }, + { PCI_VDEVICE(MARVELL, 0x2b36), .driver_data = MWL8764, }, { }, }; MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); -- cgit From 98929824eec490984e42ac9dc3b96f7f12033996 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Fri, 1 Mar 2013 17:13:01 +0530 Subject: mwl8k: Load 8764 firmware image This differs from legacy chips i.e. a 8764 loads firmware image without a helper image b Check interrupt status register for download complete indication. Signed-off-by: Nishant Sarmukadam Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index e86a31bac45f..aaaf10d48f7d 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -284,6 +284,7 @@ struct mwl8k_priv { unsigned fw_state; char *fw_pref; char *fw_alt; + bool is_8764; struct completion firmware_loading_complete; /* bitmap of running BSSes */ @@ -600,13 +601,18 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length) loops = 1000; do { u32 int_code; - - int_code = ioread32(regs + MWL8K_HIU_INT_CODE); - if (int_code == MWL8K_INT_CODE_CMD_FINISHED) { - iowrite32(0, regs + MWL8K_HIU_INT_CODE); - break; + if (priv->is_8764) { + int_code = ioread32(regs + + MWL8K_HIU_H2A_INTERRUPT_STATUS); + if (int_code == 0) + break; + } else { + int_code = ioread32(regs + MWL8K_HIU_INT_CODE); + if (int_code == MWL8K_INT_CODE_CMD_FINISHED) { + iowrite32(0, regs + MWL8K_HIU_INT_CODE); + break; + } } - cond_resched(); udelay(1); } while (--loops); @@ -724,7 +730,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) int rc; int loops; - if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) { + if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) { const struct firmware *helper = priv->fw_helper; if (helper == NULL) { @@ -743,7 +749,10 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); } else { - rc = mwl8k_load_fw_image(priv, fw->data, fw->size); + if (priv->is_8764) + rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); + else + rc = mwl8k_load_fw_image(priv, fw->data, fw->size); } if (rc) { @@ -6007,6 +6016,8 @@ static int mwl8k_probe(struct pci_dev *pdev, priv->pdev = pdev; priv->device_info = &mwl8k_info_tbl[id->driver_data]; + if (id->driver_data == MWL8764) + priv->is_8764 = true; priv->sram = pci_iomap(pdev, 0, 0x10000); if (priv->sram == NULL) { -- cgit From cd864522b349cfe88903cf6f3415293c39856b6c Mon Sep 17 00:00:00 2001 From: Piotr Haber Date: Sun, 3 Mar 2013 12:45:20 +0100 Subject: brcmsmac: radio on led support Add support for radio on led indicator. Control led via BCMA gpio driver. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Reviewed-by: Arend van Spriel Signed-off-by: Piotr Haber [arend@broadcom.com: modify Makefile for conditional compile led.c] Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/Kconfig | 5 +- drivers/net/wireless/brcm80211/brcmsmac/Makefile | 4 + drivers/net/wireless/brcm80211/brcmsmac/led.c | 126 +++++++++++++++++++++ drivers/net/wireless/brcm80211/brcmsmac/led.h | 36 ++++++ .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 4 + .../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 4 + 6 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/led.c create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/led.h (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index 1d92d874ebb6..747e9317dabd 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig @@ -12,8 +12,9 @@ config BRCMSMAC select CORDIC ---help--- This module adds support for PCIe wireless adapters based on Broadcom - IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll - be called brcmsmac.ko. + IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will + be available if you select BCMA_DRIVER_GPIO. If you choose to build a + module, the driver will be called brcmsmac.ko. config BRCMFMAC tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile index d3d4151c3eda..cba19d839b77 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile @@ -43,6 +43,10 @@ BRCMSMAC_OFILES := \ brcms_trace_events.o \ debug.o +ifdef CONFIG_BCMA_DRIVER_GPIO +BRCMSMAC_OFILES += led.o +endif + MODULEPFX := brcmsmac obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.c b/drivers/net/wireless/brcm80211/brcmsmac/led.c new file mode 100644 index 000000000000..74b17cecb189 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/led.c @@ -0,0 +1,126 @@ +#include +#include +#include + +#include "mac80211_if.h" +#include "pub.h" +#include "main.h" +#include "led.h" + + /* number of leds */ +#define BRCMS_LED_NO 4 + /* behavior mask */ +#define BRCMS_LED_BEH_MASK 0x7f + /* activelow (polarity) bit */ +#define BRCMS_LED_AL_MASK 0x80 + /* radio enabled */ +#define BRCMS_LED_RADIO 3 + +static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state) +{ + if (wl->radio_led.gpio == -1) + return; + + if (wl->radio_led.active_low) + state = !state; + + if (state) + gpio_set_value(wl->radio_led.gpio, 1); + else + gpio_set_value(wl->radio_led.gpio, 0); +} + + +/* Callback from the LED subsystem. */ +static void brcms_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct brcms_info *wl = container_of(led_dev, + struct brcms_info, led_dev); + brcms_radio_led_ctrl(wl, brightness); +} + +void brcms_led_unregister(struct brcms_info *wl) +{ + if (wl->led_dev.dev) + led_classdev_unregister(&wl->led_dev); + if (wl->radio_led.gpio != -1) + gpio_free(wl->radio_led.gpio); +} + +int brcms_led_register(struct brcms_info *wl) +{ + int i, err; + struct brcms_led *radio_led = &wl->radio_led; + /* get CC core */ + struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc; + struct gpio_chip *bcma_gpio = &cc_drv->gpio; + struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom; + u8 *leds[] = { &sprom->gpio0, + &sprom->gpio1, + &sprom->gpio2, + &sprom->gpio3 }; + unsigned gpio = -1; + bool active_low = false; + + /* none by default */ + radio_led->gpio = -1; + radio_led->active_low = false; + + if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base)) + return -ENODEV; + + /* find radio enabled LED */ + for (i = 0; i < BRCMS_LED_NO; i++) { + u8 led = *leds[i]; + if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) { + gpio = bcma_gpio->base + i; + if (led & BRCMS_LED_AL_MASK) + active_low = true; + break; + } + } + + if (gpio == -1 || !gpio_is_valid(gpio)) + return -ENODEV; + + /* request and configure LED gpio */ + err = gpio_request_one(gpio, + active_low ? GPIOF_OUT_INIT_HIGH + : GPIOF_OUT_INIT_LOW, + "radio on"); + if (err) { + wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n", + gpio, err); + return err; + } + err = gpio_direction_output(gpio, 1); + if (err) { + wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n", + gpio, err); + return err; + } + + snprintf(wl->radio_led.name, sizeof(wl->radio_led.name), + "brcmsmac-%s:radio", wiphy_name(wl->wiphy)); + + wl->led_dev.name = wl->radio_led.name; + wl->led_dev.default_trigger = + ieee80211_get_radio_led_name(wl->pub->ieee_hw); + wl->led_dev.brightness_set = brcms_led_brightness_set; + err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev); + + if (err) { + wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n", + wl->radio_led.name, err); + return err; + } + + wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n", + wl->radio_led.name, + gpio); + radio_led->gpio = gpio; + radio_led->active_low = active_low; + + return 0; +} diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.h b/drivers/net/wireless/brcm80211/brcmsmac/led.h new file mode 100644 index 000000000000..17a0b1f5dbcf --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/led.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012 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_LED_H_ +#define _BRCM_LED_H_ +struct brcms_led { + char name[32]; + unsigned gpio; + bool active_low; +}; + +#ifdef CONFIG_BCMA_DRIVER_GPIO +void brcms_led_unregister(struct brcms_info *wl); +int brcms_led_register(struct brcms_info *wl); +#else +static inline void brcms_led_unregister(struct brcms_info *wl) {}; +static inline int brcms_led_register(struct brcms_info *wl) +{ + return -ENOTSUPP; +}; +#endif + +#endif /* _BRCM_LED_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c6451c61407a..c70cf7b654cd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -34,6 +34,7 @@ #include "mac80211_if.h" #include "main.h" #include "debug.h" +#include "led.h" #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ #define BRCMS_FLUSH_TIMEOUT 500 /* msec */ @@ -904,6 +905,7 @@ static void brcms_remove(struct bcma_device *pdev) struct brcms_info *wl = hw->priv; if (wl->wlc) { + brcms_led_unregister(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); ieee80211_unregister_hw(hw); @@ -1151,6 +1153,8 @@ static int brcms_bcma_probe(struct bcma_device *pdev) pr_err("%s: brcms_attach failed!\n", __func__); return -ENODEV; } + brcms_led_register(wl); + return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 947ccacf43e6..4090032e81a2 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -20,8 +20,10 @@ #include #include #include +#include #include "ucode_loader.h" +#include "led.h" /* * Starting index for 5G rates in the * legacy rate table. @@ -81,6 +83,8 @@ struct brcms_info { struct wiphy *wiphy; struct brcms_ucode ucode; bool mute_tx; + struct brcms_led radio_led; + struct led_classdev led_dev; }; /* misc callbacks */ -- cgit From e5483576f04476de8f277feb313248b348d56ad8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:21 +0100 Subject: brcmfmac: introduce tracepoints for message logging Inspired by tracing functionality added by Seth Forshee in the brcmsmac driver, this patch adds similar functionality to brcmfmac. Reviewed-by: Piotr Haber Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 + .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 33 ++++++++ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 21 ++++-- .../net/wireless/brcm80211/brcmfmac/tracepoint.c | 22 ++++++ .../net/wireless/brcm80211/brcmfmac/tracepoint.h | 87 ++++++++++++++++++++++ 6 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 756e19fc2795..74282739350d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -39,3 +39,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o brcmfmac-$(CONFIG_BRCMDBG) += \ dhd_dbg.o +brcmfmac-$(CONFIG_BRCM_TRACING) += \ + tracepoint.o diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 4544342a0428..be0787cab24f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -24,6 +24,7 @@ #include "dhd_proto.h" #include "dhd_dbg.h" #include "fwil.h" +#include "tracepoint.h" #define PKTFILTER_BUF_SIZE 128 #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ @@ -373,3 +374,35 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) done: return err; } + +#ifdef CONFIG_BRCM_TRACING +void __brcmf_err(const char *func, const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + pr_err("%s: %pV", func, &vaf); + trace_brcmf_err(func, &vaf); + va_end(args); +} +#endif +#if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG) +void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + if (brcmf_msg_level & level) + pr_debug("%s %pV", func, &vaf); + trace_brcmf_dbg(level, func, &vaf); + va_end(args); +} +#endif diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 57671eddf79d..50f293851982 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -22,6 +22,7 @@ #include "dhd.h" #include "dhd_bus.h" #include "dhd_dbg.h" +#include "tracepoint.h" static struct dentry *root_folder; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index bc013cbe06f6..0a1806f58676 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -43,6 +43,7 @@ * debugging is not selected. When debugging the driver error * messages are as important as other tracing or even more so. */ +#ifndef CONFIG_BRCM_TRACING #ifdef CONFIG_BRCMDBG #define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__) #else @@ -52,15 +53,21 @@ pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \ } while (0) #endif +#else +__printf(2, 3) +void __brcmf_err(const char *func, const char *fmt, ...); +#define brcmf_err(fmt, ...) \ + __brcmf_err(__func__, fmt, ##__VA_ARGS__) +#endif -#if defined(DEBUG) - +#if defined(DEBUG) || defined(CONFIG_BRCM_TRACING) +__printf(3, 4) +void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...); #define brcmf_dbg(level, fmt, ...) \ do { \ - if (brcmf_msg_level & BRCMF_##level##_VAL) \ - pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ + __brcmf_dbg(BRCMF_##level##_VAL, __func__, \ + fmt, ##__VA_ARGS__); \ } while (0) - #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) @@ -69,7 +76,7 @@ do { \ #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) #define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) -#else /* (defined DEBUG) || (defined DEBUG) */ +#else /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */ #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) @@ -81,7 +88,7 @@ do { \ #define BRCMF_EVENT_ON() 0 #define BRCMF_FIL_ON() 0 -#endif /* defined(DEBUG) */ +#endif /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */ #define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ do { \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c new file mode 100644 index 000000000000..b505db48c60d --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2012 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 /* bug in tracepoint.h, it should include this */ + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "tracepoint.h" +#endif diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h new file mode 100644 index 000000000000..35efc7a67644 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 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. + */ +#if !defined(BRCMF_TRACEPOINT_H_) || defined(TRACE_HEADER_MULTI_READ) +#define BRCMF_TRACEPOINT_H_ + +#include +#include + +#ifndef CONFIG_BRCM_TRACING + +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, ...) \ +static inline void trace_ ## name(proto) {} + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(...) + +#undef DEFINE_EVENT +#define DEFINE_EVENT(evt_class, name, proto, ...) \ +static inline void trace_ ## name(proto) {} + +#endif /* CONFIG_BRCM_TRACING */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmfmac + +#define MAX_MSG_LEN 100 + +TRACE_EVENT(brcmf_err, + TP_PROTO(const char *func, struct va_format *vaf), + TP_ARGS(func, vaf), + TP_STRUCT__entry( + __string(func, func) + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + __assign_str(func, func); + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s: %s", __get_str(func), __get_str(msg)) +); + +TRACE_EVENT(brcmf_dbg, + TP_PROTO(u32 level, const char *func, struct va_format *vaf), + TP_ARGS(level, func, vaf), + TP_STRUCT__entry( + __field(u32, level) + __string(func, func) + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + __entry->level = level; + __assign_str(func, func); + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s: %s", __get_str(func), __get_str(msg)) +); + +#ifdef CONFIG_BRCM_TRACING + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE tracepoint + +#include + +#endif /* CONFIG_BRCM_TRACING */ + +#endif /* BRCMF_TRACEPOINT_H_ */ -- cgit From 1b255c92536a3f0e5dd00d291759350c834cd669 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:22 +0100 Subject: brcmfmac: make debug module parameter more clear The module parameter definition for brcmf_msg_level has been reworked to a named module parameter with description so modinfo is a bit more informative: parm: debug:level of debug output (int) Reviewed-by: Hante Meuleman Reviewed-by: Piotr Haber Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c06cea88df0d..3a8fd51ad6ad 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -40,7 +40,8 @@ MODULE_LICENSE("Dual BSD/GPL"); /* Error bits */ int brcmf_msg_level; -module_param(brcmf_msg_level, int, 0); +module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(debug, "level of debug output"); /* P2P0 enable */ static int brcmf_p2p_enable; -- cgit From 5cfd6e88da8a02f287b4e6e3582573906e673042 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:23 +0100 Subject: brcmfmac: cleanup module information macros The output of modinfo shows a bit of strangeness because module information macros are used in multiple source files: license: Dual BSD/GPL description: Broadcom 802.11 wireless LAN fullmac driver. author: Broadcom Corporation firmware: brcm/brcmfmac-sdio.txt firmware: brcm/brcmfmac-sdio.bin firmware: brcm/brcmfmac43236b.bin license: Dual BSD/GPL description: Broadcom 802.11n wireless LAN fullmac usb driver. author: Broadcom Corporation This patch cleans it up. Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 1 - drivers/net/wireless/brcm80211/brcmfmac/usb.c | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 3a8fd51ad6ad..9d0faebda8af 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -33,7 +33,6 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); #define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 42289e9ea886..156db2adcace 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -112,11 +112,6 @@ struct brcmf_usbdev_info { static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, struct brcmf_usbreq *req); -MODULE_AUTHOR("Broadcom Corporation"); -MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards"); -MODULE_LICENSE("Dual BSD/GPL"); - static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -1485,6 +1480,7 @@ static struct usb_device_id brcmf_usb_devid_table[] = { { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, { } }; + MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); -- cgit From dc7bdbf1ae939d74485569db285971274f4d8fea Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:25 +0100 Subject: brcmfmac: remove null-pointer check in .sched_scan_start() callback In brcmf_cfg80211_sched_scan_start() the request parameter was checked for being non-null. However, it never is so remove the check which gets rid of following smatch warning: drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c:2904 brcmf_cfg80211_sched_scan_start() warn: variable dereferenced before check 'request' (see line 2897) Reported-by: Dan Carpenter Reviewed-by: Hante Meuleman Reviewed-by: Piotr Haber Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 2af9c0f0798d..804473fc5c5e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3052,16 +3052,16 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, int i; int ret = 0; - brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", + brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", request->n_match_sets, request->n_ssids); if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); return -EAGAIN; } - if (!request || !request->n_ssids || !request->n_match_sets) { + if (!request->n_ssids || !request->n_match_sets) { brcmf_err("Invalid sched scan req!! n_ssids:%d\n", - request ? request->n_ssids : 0); + request->n_ssids); return -EINVAL; } -- cgit From bee1b848877b9e4512bdda480f73cda12b593e2f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:26 +0100 Subject: brcmfmac: increase required skbuff headroom for firmware signalling In preparation of firmware signalling feature additional headroom is needed to accommodate signalling protocol data between host and firmware. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index a2354d951dd7..81e1be7051ca 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -71,13 +71,26 @@ struct brcmf_proto_cdc_dcmd { ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ ((idx) << BDC_FLAG2_IF_SHIFT))) +/** + * struct brcmf_proto_bdc_header - BDC header format + * + * @flags: flags contain protocol and checksum info. + * @priority: 802.1d priority and USB flow control info (bit 4:7). + * @flags2: additional flags containing dongle interface index. + * @data_offset: start of packet data. header is following by firmware signals. + */ struct brcmf_proto_bdc_header { u8 flags; - u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */ + u8 priority; u8 flags2; u8 data_offset; }; +/* + * maximum length of firmware signal data between + * the BDC header and packet data in the tx path. + */ +#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 #define RETRIES 2 /* # of retries to retrieve matching dcmd response */ #define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE @@ -350,7 +363,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) } drvr->prot = cdc; - drvr->hdrlen += BDC_HEADER_LEN; + drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; return 0; -- cgit From edee1668bb1b7d977f39c34f63916b82647f024a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:27 +0100 Subject: brcmutil: add macros for setting bitfields using mask/shift operations Added inline functions to set bitfields in an unsigned integer variable. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/include/brcmu_utils.h | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 477b92ad3d62..82fcfe8c9bc1 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -173,6 +173,29 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir, /* ip address */ struct ipv4_addr; +/* + * bitfield macros using masking and shift + * + * remark: the mask parameter should be a shifted mask. + */ +static inline void brcmu_maskset32(u32 *var, u32 mask, u8 shift, u32 value) +{ + value = (value << shift) & mask; + *var = (*var & ~mask) | value; +} +static inline u32 brcmu_maskget32(u32 var, u32 mask, u8 shift) +{ + return (var & mask) >> shift; +} +static inline void brcmu_maskset16(u16 *var, u16 mask, u8 shift, u16 value) +{ + value = (value << shift) & mask; + *var = (*var & ~mask) | value; +} +static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift) +{ + return (var & mask) >> shift; +} /* externs */ /* format/print */ -- cgit From 349e7104ff662eeacca1fffbb480c287562c45a1 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:28 +0100 Subject: brcmfmac: add support for TLV based firmware signalling The firmware and host can exchange signals which are carried within the data packets. These are TLV based signals that are inserted before the actual data, ie. ethernet frame. This commit adds the new source module for this feature and enables RSSI signals from firmware. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 7 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 8 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 41 +++ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 13 + .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 28 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 14 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 382 +++++++++++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h | 25 ++ 9 files changed, 501 insertions(+), 18 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 74282739350d..598c8e2f8d2b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -26,6 +26,7 @@ brcmfmac-objs += \ wl_cfg80211.o \ fwil.o \ fweh.o \ + fwsignal.o \ p2p.o \ dhd_cdc.o \ dhd_common.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index ef6f23be6d32..c7fa20846b32 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -501,6 +501,7 @@ struct brcmf_dcmd { /* Forward decls for struct brcmf_pub (see below) */ struct brcmf_proto; /* device communication protocol info */ struct brcmf_cfg80211_dev; /* cfg80211 device info */ +struct brcmf_fws_info; /* firmware signalling info */ /* Common structure for module and instance linkage */ struct brcmf_pub { @@ -527,6 +528,10 @@ struct brcmf_pub { unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; struct brcmf_fweh_info fweh; + + bool fw_signals; + struct brcmf_fws_info *fws; + spinlock_t fws_spinlock; #ifdef DEBUG struct dentry *dbgfs_dir; #endif @@ -582,7 +587,7 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); /* Remove any protocol-specific data header. */ -extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, +extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, struct sk_buff *rxp); extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index 81e1be7051ca..8212d4384b1b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -28,6 +28,7 @@ #include "dhd.h" #include "dhd_proto.h" #include "dhd_bus.h" +#include "fwsignal.h" #include "dhd_dbg.h" struct brcmf_proto_cdc_dcmd { @@ -294,7 +295,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, BDC_SET_IF_IDX(h, ifidx); } -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, struct sk_buff *pktbuf) { struct brcmf_proto_bdc_header *h; @@ -341,7 +342,10 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, pktbuf->priority = h->priority & BDC_PRIORITY_MASK; skb_pull(pktbuf, BDC_HEADER_LEN); - skb_pull(pktbuf, h->data_offset << 2); + if (do_fws) + brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); + else + skb_pull(pktbuf, h->data_offset << 2); if (pktbuf->len == 0) return -ENODATA; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 50f293851982..ac792499b46a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -124,3 +124,44 @@ void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, debugfs_create_file("counters", S_IRUGO, dentry, sdcnt, &brcmf_debugfs_sdio_counter_ops); } + +static +ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data, + size_t count, loff_t *ppos) +{ + struct brcmf_fws_stats *fwstats = f->private_data; + char buf[100]; + int res; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), + "header_pulls: %u\n" + "header_only_pkt: %u\n" + "tlv_parse_failed: %u\n" + "tlv_invalid_type: %u\n", + fwstats->header_pulls, + fwstats->header_only_pkt, + fwstats->tlv_parse_failed, + fwstats->tlv_invalid_type); + + return simple_read_from_buffer(data, count, ppos, buf, res); +} + +static const struct file_operations brcmf_debugfs_fws_stats_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = brcmf_debugfs_fws_stats_read +}; + +void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, + struct brcmf_fws_stats *stats) +{ + struct dentry *dentry = drvr->dbgfs_dir; + + if (!IS_ERR_OR_NULL(dentry)) + debugfs_create_file("fws_stats", S_IRUGO, dentry, + stats, &brcmf_debugfs_fws_stats_ops); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 0a1806f58676..4bc646bde16f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -132,6 +132,13 @@ struct brcmf_sdio_count { ulong rx_readahead_cnt; /* packets where header read-ahead was used */ }; +struct brcmf_fws_stats { + u32 tlv_parse_failed; + u32 tlv_invalid_type; + u32 header_only_pkt; + u32 header_pulls; +}; + struct brcmf_pub; #ifdef DEBUG void brcmf_debugfs_init(void); @@ -141,6 +148,8 @@ void brcmf_debugfs_detach(struct brcmf_pub *drvr); struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, struct brcmf_sdio_count *sdcnt); +void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, + struct brcmf_fws_stats *stats); #else static inline void brcmf_debugfs_init(void) { @@ -155,6 +164,10 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr) static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) { } +static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, + struct brcmf_fws_stats *stats) +{ +} #endif #endif /* _BRCMF_DBG_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 9d0faebda8af..172d39cdb4ea 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -30,6 +30,7 @@ #include "p2p.h" #include "wl_cfg80211.h" #include "fwil.h" +#include "fwsignal.h" MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); @@ -283,7 +284,7 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) skb_unlink(skb, skb_list); /* process and remove protocol-specific header */ - ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); + ret = brcmf_proto_hdrpull(drvr, drvr->fw_signals, &ifidx, skb); ifp = drvr->iflist[ifidx]; if (ret || !ifp || !ifp->ndev) { @@ -357,20 +358,23 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; struct brcmf_if *ifp; + int res; - brcmf_proto_hdrpull(drvr, &ifidx, txp); + res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp); ifp = drvr->iflist[ifidx]; if (!ifp) return; - eh = (struct ethhdr *)(txp->data); - type = ntohs(eh->h_proto); + if (res == 0) { + eh = (struct ethhdr *)(txp->data); + type = ntohs(eh->h_proto); - if (type == ETH_P_PAE) { - atomic_dec(&ifp->pend_8021x_cnt); - if (waitqueue_active(&ifp->pend_8021x_wait)) - wake_up(&ifp->pend_8021x_wait); + if (type == ETH_P_PAE) { + atomic_dec(&ifp->pend_8021x_cnt); + if (waitqueue_active(&ifp->pend_8021x_wait)) + wake_up(&ifp->pend_8021x_wait); + } } if (!success) ifp->stats.tx_errors++; @@ -873,6 +877,9 @@ int brcmf_bus_start(struct device *dev) if (ret < 0) goto fail; + drvr->fw_signals = true; + (void)brcmf_fws_init(drvr); + drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); if (drvr->config == NULL) { ret = -ENOMEM; @@ -889,6 +896,8 @@ fail: brcmf_err("failed: %d\n", ret); if (drvr->config) brcmf_cfg80211_detach(drvr->config); + if (drvr->fws) + brcmf_fws_deinit(drvr); free_netdev(ifp->ndev); drvr->iflist[0] = NULL; if (p2p_ifp) { @@ -952,6 +961,9 @@ void brcmf_detach(struct device *dev) if (drvr->prot) brcmf_proto_detach(drvr); + if (drvr->fws) + brcmf_fws_deinit(drvr); + brcmf_debugfs_detach(drvr); bus_if->drvr = NULL; kfree(drvr); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4469321c0eb3..bf6ab41b7b1e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1546,7 +1546,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) struct sk_buff_head pktlist; /* needed for bus interface */ u16 pad; /* Number of pad bytes to read */ uint rxleft = 0; /* Remaining number of frames allowed */ - int sdret; /* Return code from calls */ + int ret; /* Return code from calls */ uint rxcount = 0; /* Total frames read */ struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; u8 head_read = 0; @@ -1577,15 +1577,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) /* read header first for unknow frame length */ sdio_claim_host(bus->sdiodev->func[1]); if (!rd->len) { - sdret = brcmf_sdcard_recv_buf(bus->sdiodev, + ret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, bus->rxhdr, BRCMF_FIRSTREAD); bus->sdcnt.f2rxhdrs++; - if (sdret < 0) { + if (ret < 0) { brcmf_err("RXHEADER FAILED: %d\n", - sdret); + ret); bus->sdcnt.rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); sdio_release_host(bus->sdiodev->func[1]); @@ -1637,14 +1637,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) skb_pull(pkt, head_read); pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); - sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, + ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2rxdata++; sdio_release_host(bus->sdiodev->func[1]); - if (sdret < 0) { + if (ret < 0) { brcmf_err("read %d bytes from channel %d failed: %d\n", - rd->len, rd->channel, sdret); + rd->len, rd->channel, ret); brcmu_pkt_buf_free_skb(pkt); sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, true, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c new file mode 100644 index 000000000000..071d55f9cd4d --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -0,0 +1,382 @@ +/* + * 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 "dhd.h" +#include "dhd_dbg.h" +#include "fwil.h" +#include "fweh.h" +#include "fwsignal.h" + +/** + * DOC: Firmware Signalling + * + * Firmware can send signals to host and vice versa, which are passed in the + * data packets using TLV based header. This signalling layer is on top of the + * BDC bus protocol layer. + */ + +/* + * single definition for firmware-driver flow control tlv's. + * + * each tlv is specified by BRCMF_FWS_TLV_DEF(name, ID, length). + * A length value 0 indicates variable length tlv. + */ +#define BRCMF_FWS_TLV_DEFLIST \ + BRCMF_FWS_TLV_DEF(MAC_OPEN, 1, 1) \ + BRCMF_FWS_TLV_DEF(MAC_CLOSE, 2, 1) \ + BRCMF_FWS_TLV_DEF(MAC_REQUEST_CREDIT, 3, 2) \ + BRCMF_FWS_TLV_DEF(TXSTATUS, 4, 4) \ + BRCMF_FWS_TLV_DEF(PKTTAG, 5, 4) \ + BRCMF_FWS_TLV_DEF(MACDESC_ADD, 6, 8) \ + BRCMF_FWS_TLV_DEF(MACDESC_DEL, 7, 8) \ + BRCMF_FWS_TLV_DEF(RSSI, 8, 1) \ + BRCMF_FWS_TLV_DEF(INTERFACE_OPEN, 9, 1) \ + BRCMF_FWS_TLV_DEF(INTERFACE_CLOSE, 10, 1) \ + BRCMF_FWS_TLV_DEF(FIFO_CREDITBACK, 11, 8) \ + BRCMF_FWS_TLV_DEF(PENDING_TRAFFIC_BMP, 12, 2) \ + BRCMF_FWS_TLV_DEF(MAC_REQUEST_PACKET, 13, 3) \ + BRCMF_FWS_TLV_DEF(HOST_REORDER_RXPKTS, 14, 10) \ + BRCMF_FWS_TLV_DEF(TRANS_ID, 18, 6) \ + BRCMF_FWS_TLV_DEF(COMP_TXSTATUS, 19, 1) \ + BRCMF_FWS_TLV_DEF(FILLER, 255, 0) + +/** + * enum brcmf_fws_tlv_type - definition of tlv identifiers. + */ +#define BRCMF_FWS_TLV_DEF(name, id, len) \ + BRCMF_FWS_TYPE_ ## name = id, +enum brcmf_fws_tlv_type { + BRCMF_FWS_TLV_DEFLIST + BRCMF_FWS_TYPE_INVALID +}; +#undef BRCMF_FWS_TLV_DEF + +/** + * enum brcmf_fws_tlv_len - length values for tlvs. + */ +#define BRCMF_FWS_TLV_DEF(name, id, len) \ + BRCMF_FWS_TYPE_ ## name ## _LEN = len, +enum brcmf_fws_tlv_len { + BRCMF_FWS_TLV_DEFLIST +}; +#undef BRCMF_FWS_TLV_DEF + +#ifdef DEBUG +/** + * brcmf_fws_tlv_names - array of tlv names. + */ +#define BRCMF_FWS_TLV_DEF(name, id, len) \ + { id, #name }, +static struct { + enum brcmf_fws_tlv_type id; + const char *name; +} brcmf_fws_tlv_names[] = { + BRCMF_FWS_TLV_DEFLIST +}; +#undef BRCMF_FWS_TLV_DEF + +static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(brcmf_fws_tlv_names); i++) + if (brcmf_fws_tlv_names[i].id == id) + return brcmf_fws_tlv_names[i].name; + + return "INVALID"; +} +#else +static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) +{ + return "NODEBUG"; +} +#endif /* DEBUG */ + +/** + * flags used to enable tlv signalling from firmware. + */ +#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001 +#define BRCMF_FWS_FLAGS_XONXOFF_SIGNALS 0x0002 +#define BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS 0x0004 +#define BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008 +#define BRCMF_FWS_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010 +#define BRCMF_FWS_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020 +#define BRCMF_FWS_FLAGS_HOST_RXREORDER_ACTIVE 0x0040 + +#define BRCMF_FWS_HANGER_MAXITEMS 1024 +#define BRCMF_FWS_HANGER_ITEM_STATE_FREE 1 +#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE 2 +#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3 + +#define BRCMF_FWS_STATE_OPEN 1 +#define BRCMF_FWS_STATE_CLOSE 2 + +#define BRCMF_FWS_FCMODE_NONE 0 +#define BRCMF_FWS_FCMODE_IMPLIED_CREDIT 1 +#define BRCMF_FWS_FCMODE_EXPLICIT_CREDIT 2 + +#define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32 +#define BRCMF_FWS_MAX_IFNUM 16 +#define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff + +#define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0 +#define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1 + +/** + * FWFC packet identifier + * + * 32-bit packet identifier used in PKTTAG tlv from host to dongle. + * + * - Generated at the host (e.g. dhd) + * - Seen as a generic sequence number by wlc except the flags field + * + * Generation : b[31] => generation number for this packet [host->fw] + * OR, current generation number [fw->host] + * Flags : b[30:27] => command, status flags + * FIFO-AC : b[26:24] => AC-FIFO id + * h-slot : b[23:8] => hanger-slot + * freerun : b[7:0] => A free running counter + */ +#define BRCMF_FWS_PKTTAG_GENERATION_MASK 0x80000000 +#define BRCMF_FWS_PKTTAG_GENERATION_SHIFT 31 +#define BRCMF_FWS_PKTTAG_FLAGS_MASK 0x78000000 +#define BRCMF_FWS_PKTTAG_FLAGS_SHIFT 27 +#define BRCMF_FWS_PKTTAG_FIFO_MASK 0x07000000 +#define BRCMF_FWS_PKTTAG_FIFO_SHIFT 24 +#define BRCMF_FWS_PKTTAG_HSLOT_MASK 0x00ffff00 +#define BRCMF_FWS_PKTTAG_HSLOT_SHIFT 8 +#define BRCMF_FWS_PKTTAG_FREERUN_MASK 0x000000ff +#define BRCMF_FWS_PKTTAG_FREERUN_SHIFT 0 + +#define brcmf_fws_pkttag_set_field(var, field, value) \ + brcmu_maskset32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \ + BRCMF_FWS_PKTTAG_ ## field ## _SHIFT, (value)) +#define brcmf_fws_pkttag_get_field(var, field) \ + brcmu_maskget32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \ + BRCMF_FWS_PKTTAG_ ## field ## _SHIFT) + +struct brcmf_fws_info { + struct brcmf_pub *drvr; + struct brcmf_fws_stats stats; +}; + +static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi) +{ + brcmf_dbg(CTL, "rssi %d\n", rssi); + return 0; +} + +static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) +{ + __le32 timestamp; + + memcpy(×tamp, &data[2], sizeof(timestamp)); + brcmf_dbg(INFO, "received: seq %d, timestamp %d\n", data[1], + le32_to_cpu(timestamp)); + return 0; +} + +/* using macro so sparse checking does not complain + * about locking imbalance. + */ +#define brcmf_fws_lock(drvr, flags) \ +do { \ + flags = 0; \ + spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \ +} while (0) + +/* using macro so sparse checking does not complain + * about locking imbalance. + */ +#define brcmf_fws_unlock(drvr, flags) \ + spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags)) + +int brcmf_fws_init(struct brcmf_pub *drvr) +{ + u32 tlv; + int rc; + + /* enable rssi signals */ + tlv = drvr->fw_signals ? BRCMF_FWS_FLAGS_RSSI_SIGNALS : 0; + + spin_lock_init(&drvr->fws_spinlock); + + drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); + if (!drvr->fws) { + rc = -ENOMEM; + goto fail; + } + + /* enable proptxtstatus signaling by default */ + rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); + if (rc < 0) { + brcmf_err("failed to set bdcv2 tlv signaling\n"); + goto fail; + } + /* set linkage back */ + drvr->fws->drvr = drvr; + + /* create debugfs file for statistics */ + brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats); + + /* TODO: remove upon feature delivery */ + brcmf_err("%s bdcv2 tlv signaling [%x]\n", + drvr->fw_signals ? "enabled" : "disabled", tlv); + return 0; + +fail: + /* disable flow control entirely */ + drvr->fw_signals = false; + brcmf_fws_deinit(drvr); + return rc; +} + +void brcmf_fws_deinit(struct brcmf_pub *drvr) +{ + /* free top structure */ + kfree(drvr->fws); + drvr->fws = NULL; +} + +int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, + struct sk_buff *skb) +{ + struct brcmf_fws_info *fws = drvr->fws; + ulong flags; + u8 *signal_data; + s16 data_len; + u8 type; + u8 len; + u8 *data; + + brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n", + ifidx, skb->len, signal_len); + + WARN_ON(signal_len > skb->len); + + /* if flow control disabled, skip to packet data and leave */ + if (!signal_len || !drvr->fw_signals) { + skb_pull(skb, signal_len); + return 0; + } + + /* lock during tlv parsing */ + brcmf_fws_lock(drvr, flags); + + fws->stats.header_pulls++; + data_len = signal_len; + signal_data = skb->data; + + while (data_len > 0) { + /* extract tlv info */ + type = signal_data[0]; + + /* FILLER type is actually not a TLV, but + * a single byte that can be skipped. + */ + if (type == BRCMF_FWS_TYPE_FILLER) { + signal_data += 1; + data_len -= 1; + continue; + } + len = signal_data[1]; + data = signal_data + 2; + + /* abort parsing when length invalid */ + if (data_len < len + 2) + break; + + brcmf_dbg(INFO, "tlv type=%d (%s), len=%d\n", type, + brcmf_fws_get_tlv_name(type), len); + switch (type) { + case BRCMF_FWS_TYPE_MAC_OPEN: + case BRCMF_FWS_TYPE_MAC_CLOSE: + WARN_ON(len != BRCMF_FWS_TYPE_MAC_OPEN_LEN); + break; + case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: + WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT_LEN); + break; + case BRCMF_FWS_TYPE_TXSTATUS: + WARN_ON(len != BRCMF_FWS_TYPE_TXSTATUS_LEN); + break; + case BRCMF_FWS_TYPE_PKTTAG: + WARN_ON(len != BRCMF_FWS_TYPE_PKTTAG_LEN); + break; + case BRCMF_FWS_TYPE_MACDESC_ADD: + case BRCMF_FWS_TYPE_MACDESC_DEL: + WARN_ON(len != BRCMF_FWS_TYPE_MACDESC_ADD_LEN); + break; + case BRCMF_FWS_TYPE_RSSI: + WARN_ON(len != BRCMF_FWS_TYPE_RSSI_LEN); + brcmf_fws_rssi_indicate(fws, *(s8 *)data); + break; + case BRCMF_FWS_TYPE_INTERFACE_OPEN: + case BRCMF_FWS_TYPE_INTERFACE_CLOSE: + WARN_ON(len != BRCMF_FWS_TYPE_INTERFACE_OPEN_LEN); + break; + case BRCMF_FWS_TYPE_FIFO_CREDITBACK: + WARN_ON(len != BRCMF_FWS_TYPE_FIFO_CREDITBACK_LEN); + break; + case BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP: + WARN_ON(len != BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN); + break; + case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: + WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_PACKET_LEN); + break; + case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: + WARN_ON(len != BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS_LEN); + break; + case BRCMF_FWS_TYPE_TRANS_ID: + WARN_ON(len != BRCMF_FWS_TYPE_TRANS_ID_LEN); + brcmf_fws_dbg_seqnum_check(fws, data); + break; + case BRCMF_FWS_TYPE_COMP_TXSTATUS: + WARN_ON(len != BRCMF_FWS_TYPE_COMP_TXSTATUS_LEN); + break; + default: + fws->stats.tlv_invalid_type++; + break; + } + + signal_data += len + 2; + data_len -= len + 2; + } + + if (data_len != 0) + fws->stats.tlv_parse_failed++; + + /* signalling processing result does + * not affect the actual ethernet packet. + */ + skb_pull(skb, signal_len); + + /* this may be a signal-only packet + */ + if (skb->len == 0) + fws->stats.header_only_pkt++; + + brcmf_fws_unlock(drvr, flags); + return 0; +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h new file mode 100644 index 000000000000..e728eea72bb4 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2012 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 FWSIGNAL_H_ +#define FWSIGNAL_H_ + +int brcmf_fws_init(struct brcmf_pub *drvr); +void brcmf_fws_deinit(struct brcmf_pub *drvr); +int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, + struct sk_buff *skb); +#endif /* FWSIGNAL_H_ */ -- cgit From 7f4bceecf0b4fb3190af47a775e48782952196a2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:29 +0100 Subject: brcmfmac: release transmit packet in brcmf_txcomplete() In the bus-specific driver code each call to brcmf_txcomplete() is following by a free of that packet. This patch moves that free to the brcmf_txcomplete() function. Reviewed-by: Hante Meuleman Reviewed-by: Piotr Haber Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 5 ++++- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 14 +++----------- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 2 -- 4 files changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index ad25c3408b59..883ef9063e8a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -134,7 +134,7 @@ extern void brcmf_dev_reset(struct device *dev); /* Indication from bus module to change flow-control state */ extern void brcmf_txflowblock(struct device *dev, bool state); -/* Notify tx completion */ +/* Notify the bus has transferred the tx packet to firmware */ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 172d39cdb4ea..faf209236975 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -364,7 +364,7 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) ifp = drvr->iflist[ifidx]; if (!ifp) - return; + goto done; if (res == 0) { eh = (struct ethhdr *)(txp->data); @@ -378,6 +378,9 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) } if (!success) ifp->stats.tx_errors++; + +done: + brcmu_pkt_buf_free_skb(txp); } static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index bf6ab41b7b1e..9a2edd3f0a5c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1775,7 +1775,7 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, - uint chan, bool free_pkt) + uint chan) { int ret; u8 *frame; @@ -1805,10 +1805,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, pkt_align(new, pkt->len, BRCMF_SDALIGN); memcpy(new->data, pkt->data, pkt->len); - if (free_pkt) - brcmu_pkt_buf_free_skb(pkt); - /* free the pkt if canned one is not used */ - free_pkt = true; + brcmu_pkt_buf_free_skb(pkt); pkt = new; frame = (u8 *) (pkt->data); /* precondition: (frame % BRCMF_SDALIGN) == 0) */ @@ -1901,10 +1898,6 @@ done: /* restore pkt buffer pointer before calling tx complete routine */ skb_pull(pkt, SDPCM_HDRLEN + pad); brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); - - if (free_pkt) - brcmu_pkt_buf_free_skb(pkt); - return ret; } @@ -1932,7 +1925,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) spin_unlock_bh(&bus->txqlock); datalen = pkt->len - SDPCM_HDRLEN; - ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); + ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL); /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { @@ -2343,7 +2336,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { skb_pull(pkt, SDPCM_HDRLEN); brcmf_txcomplete(bus->sdiodev->dev, pkt, false); - brcmu_pkt_buf_free_skb(pkt); brcmf_err("out of bus->txq !!!\n"); ret = -ENOSR; } else { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 156db2adcace..bf5bb8768e7b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -417,8 +417,6 @@ static void brcmf_usb_tx_complete(struct urb *urb) brcmf_usb_del_fromq(devinfo, req); brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); - - brcmu_pkt_buf_free_skb(req->skb); req->skb = NULL; brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount); if (devinfo->tx_freecount > devinfo->tx_high_watermark && -- cgit From 6fc9ca138515880cc038b9588bd3637e66743343 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:30 +0100 Subject: brcmfmac: assure brcmf_txcomplete() is called in failure paths For transmit packets the function brcmf_txcomplete() must be called. This should be done as well when for some reason the transmit fails to assure proper tx post processing. This patch fixes the code paths in brcmf_usb_tx() that forgot to do so. Reviewed-by: Piotr Haber Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 29 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index bf5bb8768e7b..01aed7ad6bec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -570,15 +570,17 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) int ret; brcmf_dbg(USB, "Enter, skb=%p\n", skb); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) - return -EIO; + if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { + ret = -EIO; + goto fail; + } req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, &devinfo->tx_freecount); if (!req) { - brcmu_pkt_buf_free_skb(skb); brcmf_err("no req to send\n"); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } req->skb = skb; @@ -591,18 +593,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) if (ret) { brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n"); brcmf_usb_del_fromq(devinfo, req); - brcmu_pkt_buf_free_skb(req->skb); req->skb = NULL; brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, - &devinfo->tx_freecount); - } else { - if (devinfo->tx_freecount < devinfo->tx_low_watermark && - !devinfo->tx_flowblock) { - brcmf_txflowblock(dev, true); - devinfo->tx_flowblock = true; - } + &devinfo->tx_freecount); + goto fail; } + if (devinfo->tx_freecount < devinfo->tx_low_watermark && + !devinfo->tx_flowblock) { + brcmf_txflowblock(dev, true); + devinfo->tx_flowblock = true; + } + return 0; + +fail: + brcmf_txcomplete(dev, skb, false); return ret; } -- cgit From 17f14d7c1f306ad6a6d1cd253d7447a574785f07 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:31 +0100 Subject: brcmutil: add dequeue function with filtering Adding a packet dequeue function that will return packets that pass the provided match function. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Reviewed-by: Piotr Haber Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmutil/utils.c | 25 ++++++++++++++++++++++ .../net/wireless/brcm80211/include/brcmu_utils.h | 4 ++++ 2 files changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index 3e6405e06ac0..bf5e50fc21ba 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -116,6 +116,31 @@ struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) } EXPORT_SYMBOL(brcmu_pktq_pdeq); +/* + * precedence based dequeue with match function. Passing a NULL pointer + * for the match function parameter is considered to be a wildcard so + * any packet on the queue is returned. In that case it is no different + * from brcmu_pktq_pdeq() above. + */ +struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, + bool (*match_fn)(struct sk_buff *skb, + void *arg), void *arg) +{ + struct sk_buff_head *q; + struct sk_buff *p, *next; + + q = &pq->q[prec].skblist; + skb_queue_walk_safe(q, p, next) { + if (match_fn == NULL || match_fn(p, arg)) { + skb_unlink(p, q); + pq->len--; + return p; + } + } + return NULL; +} +EXPORT_SYMBOL(brcmu_pktq_pdeq_match); + struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) { struct sk_buff_head *q; diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 82fcfe8c9bc1..898cacb8d01d 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -120,6 +120,10 @@ 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); +extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, + bool (*match_fn)(struct sk_buff *p, + void *arg), + void *arg); /* packet primitives */ extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); -- cgit From 8f0c3b6d44e09f497f57ca2997d903c5602336a1 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 3 Mar 2013 12:45:32 +0100 Subject: brcmfmac: add parameter to brcmf_proto_hdrpush() for data offset The function brcmf_proto_hdrpush() increases the header space and fills in the protocol header fields. One field is the data offset which is currently fixed to zero meaning the data follows right after the header. The parameter is added to determine the actual start of data. This will be used for firmware signalling. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Reviewed-by: Piotr Haber Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 5 ++--- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index 8212d4384b1b..e224bcb90024 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -272,7 +272,7 @@ static void pkt_set_sum_good(struct sk_buff *skb, bool x) skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); } -void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, +void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, struct sk_buff *pktbuf) { struct brcmf_proto_bdc_header *h; @@ -280,7 +280,6 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, brcmf_dbg(CDC, "Enter\n"); /* Push BDC header used to convey priority for buses that don't */ - skb_push(pktbuf, BDC_HEADER_LEN); h = (struct brcmf_proto_bdc_header *)(pktbuf->data); @@ -291,7 +290,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); h->flags2 = 0; - h->data_offset = 0; + h->data_offset = offset; BDC_SET_IF_IDX(h, ifidx); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index faf209236975..fa5a2af04d46 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -231,7 +231,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, atomic_inc(&ifp->pend_8021x_cnt); /* If the protocol uses a data header, apply it */ - brcmf_proto_hdrpush(drvr, ifp->ifidx, skb); + brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb); /* Use bus module to send data frame */ ret = brcmf_bus_txdata(drvr->bus_if, skb); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 48fa70302192..ef9179883748 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -33,7 +33,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, +extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, struct sk_buff *txp); /* Sets dongle media info (drv_version, mac address). */ -- cgit From fcb9a3de1e72cb271343aa9484a20c066b6c4eee Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Mar 2013 12:42:52 +0530 Subject: ath9k_hw: Remove CHANNEL_CW_INT This flag is used for indicating channel interference and we currently do nothing with it, so remove it. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 4 +--- drivers/net/wireless/ath/ath9k/hw.c | 6 ++---- drivers/net/wireless/ath/ath9k/hw.h | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 1e8508530e98..7bdd726c7a8f 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -369,7 +369,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) struct ieee80211_channel *c = chan->chan; struct ath9k_hw_cal_data *caldata = ah->caldata; - chan->channelFlags &= (~CHANNEL_CW_INT); if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { ath_dbg(common, CALIBRATE, "NF did not complete in calibration window\n"); @@ -384,7 +383,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) ath_dbg(common, CALIBRATE, "noise floor failed detected; detected %d, threshold %d\n", nf, nfThresh); - chan->channelFlags |= CHANNEL_CW_INT; } if (!caldata) { @@ -410,7 +408,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, int i, j; ah->caldata->channel = chan->channel; - ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; + ah->caldata->channelFlags = chan->channelFlags; ah->caldata->chanmode = chan->chanmode; h = ah->caldata->nfCalHist; default_nf = ath9k_hw_get_default_nf(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2a2ae403e0e5..e80b563d9468 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1761,10 +1761,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_getnf(ah, ah->curchan); ah->caldata = caldata; - if (caldata && - (chan->channel != caldata->channel || - (chan->channelFlags & ~CHANNEL_CW_INT) != - (caldata->channelFlags & ~CHANNEL_CW_INT))) { + if (caldata && (chan->channel != caldata->channel || + chan->channelFlags != caldata->channelFlags)) { /* Operating channel changed, reset channel calibration data */ memset(caldata, 0, sizeof(*caldata)); ath9k_init_nfcal_hist_buffer(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 784e81ccb903..30e62d92d46d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -363,7 +363,6 @@ enum ath9k_int { ATH9K_INT_NOCARD = 0xffffffff }; -#define CHANNEL_CW_INT 0x00002 #define CHANNEL_CCK 0x00020 #define CHANNEL_OFDM 0x00040 #define CHANNEL_2GHZ 0x00080 -- cgit From 15d2b58577ac6ef580160069911a237aeaf955db Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Mar 2013 12:42:53 +0530 Subject: ath9k_hw: Use helper functions to simplify HW reset Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 182 ++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index e80b563d9468..767222f2ba5c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1667,6 +1667,104 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_check_alive); +static void ath9k_hw_init_mfp(struct ath_hw *ah) +{ + /* Setup MFP options for CCMP */ + if (AR_SREV_9280_20_OR_LATER(ah)) { + /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt + * frames when constructing CCMP AAD. */ + REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, + 0xc7ff); + ah->sw_mgmt_crypto = false; + } else if (AR_SREV_9160_10_OR_LATER(ah)) { + /* Disable hardware crypto for management frames */ + REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); + REG_SET_BIT(ah, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); + ah->sw_mgmt_crypto = true; + } else { + ah->sw_mgmt_crypto = true; + } +} + +static void ath9k_hw_reset_opmode(struct ath_hw *ah, + u32 macStaId1, u32 saveDefAntenna) +{ + struct ath_common *common = ath9k_hw_common(ah); + + ENABLE_REGWRITE_BUFFER(ah); + + REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); + REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) + | macStaId1 + | AR_STA_ID1_RTS_USE_DEF + | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) + | ah->sta_id1_defaults); + ath_hw_setbssidmask(common); + REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); + ath9k_hw_write_associd(ah); + REG_WRITE(ah, AR_ISR, ~0); + REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); + + REGWRITE_BUFFER_FLUSH(ah); + + ath9k_hw_set_operating_mode(ah, ah->opmode); +} + +static void ath9k_hw_init_queues(struct ath_hw *ah) +{ + int i; + + ENABLE_REGWRITE_BUFFER(ah); + + for (i = 0; i < AR_NUM_DCU; i++) + REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); + + REGWRITE_BUFFER_FLUSH(ah); + + ah->intr_txqs = 0; + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + ath9k_hw_resettxqueue(ah, i); +} + +/* + * For big endian systems turn on swapping for descriptors + */ +static void ath9k_hw_init_desc(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + if (AR_SREV_9100(ah)) { + u32 mask; + mask = REG_READ(ah, AR_CFG); + if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { + ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n", + mask); + } else { + mask = INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; + REG_WRITE(ah, AR_CFG, mask); + ath_dbg(common, RESET, "Setting CFG 0x%x\n", + REG_READ(ah, AR_CFG)); + } + } else { + if (common->bus_ops->ath_bus_type == ATH_USB) { + /* Configure AR9271 target WLAN */ + if (AR_SREV_9271(ah)) + REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); + else + REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); + } +#ifdef __BIG_ENDIAN + else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || + AR_SREV_9550(ah)) + REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); + else + REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); +#endif + } +} + /* * Fast channel change: * (Change synthesizer based on channel freq without resetting chip) @@ -1744,7 +1842,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, u32 saveDefAntenna; u32 macStaId1; u64 tsf = 0; - int i, r; + int r; bool start_mci_reset = false; bool save_fullsleep = ah->chip_fullsleep; @@ -1849,22 +1947,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_settsf64(ah, tsf); } - /* Setup MFP options for CCMP */ - if (AR_SREV_9280_20_OR_LATER(ah)) { - /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt - * frames when constructing CCMP AAD. */ - REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, - 0xc7ff); - ah->sw_mgmt_crypto = false; - } else if (AR_SREV_9160_10_OR_LATER(ah)) { - /* Disable hardware crypto for management frames */ - REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, - AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); - REG_SET_BIT(ah, AR_PCU_MISC_MODE2, - AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); - ah->sw_mgmt_crypto = true; - } else - ah->sw_mgmt_crypto = true; + ath9k_hw_init_mfp(ah); if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) ath9k_hw_set_delta_slope(ah, chan); @@ -1872,24 +1955,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_spur_mitigate_freq(ah, chan); ah->eep_ops->set_board_values(ah, chan); - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); - REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) - | macStaId1 - | AR_STA_ID1_RTS_USE_DEF - | (ah->config. - ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) - | ah->sta_id1_defaults); - ath_hw_setbssidmask(common); - REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); - ath9k_hw_write_associd(ah); - REG_WRITE(ah, AR_ISR, ~0); - REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); - - REGWRITE_BUFFER_FLUSH(ah); - - ath9k_hw_set_operating_mode(ah, ah->opmode); + ath9k_hw_reset_opmode(ah, macStaId1, saveDefAntenna); r = ath9k_hw_rf_set_freq(ah, chan); if (r) @@ -1897,17 +1963,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_set_clockrate(ah); - ENABLE_REGWRITE_BUFFER(ah); - - for (i = 0; i < AR_NUM_DCU; i++) - REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); - - REGWRITE_BUFFER_FLUSH(ah); - - ah->intr_txqs = 0; - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) - ath9k_hw_resettxqueue(ah, i); - + ath9k_hw_init_queues(ah); ath9k_hw_init_interrupt_masks(ah, ah->opmode); ath9k_hw_ani_cache_ini_regs(ah); ath9k_hw_init_qos(ah); @@ -1962,38 +2018,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REGWRITE_BUFFER_FLUSH(ah); - /* - * For big endian systems turn on swapping for descriptors - */ - if (AR_SREV_9100(ah)) { - u32 mask; - mask = REG_READ(ah, AR_CFG); - if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { - ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n", - mask); - } else { - mask = - INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; - REG_WRITE(ah, AR_CFG, mask); - ath_dbg(common, RESET, "Setting CFG 0x%x\n", - REG_READ(ah, AR_CFG)); - } - } else { - if (common->bus_ops->ath_bus_type == ATH_USB) { - /* Configure AR9271 target WLAN */ - if (AR_SREV_9271(ah)) - REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); - else - REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); - } -#ifdef __BIG_ENDIAN - else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || - AR_SREV_9550(ah)) - REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); - else - REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); -#endif - } + ath9k_hw_init_desc(ah); if (ath9k_hw_btcoex_is_enabled(ah)) ath9k_hw_btcoex_enable(ah); @@ -2006,7 +2031,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (AR_SREV_9300_20_OR_LATER(ah)) { ar9003_hw_bb_watchdog_config(ah); - ar9003_hw_disable_phy_restart(ah); } -- cgit From 16329ff029b799c66876fc71ef0f63bf10756f15 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Mar 2013 12:42:54 +0530 Subject: ath9k_hw: Update initvals for AR9462 Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 49 +++++++++++----------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index ccc42a71b436..999ab08c34e6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -37,28 +37,28 @@ static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = { /* Addr allmodes */ {0x00018c00, 0x18253ede}, {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0003580c}, + {0x00018c08, 0x0003780c}, }; static const u32 ar9462_2p0_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, - {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, + {0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81}, {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, - {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, + {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2}, {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e3c, 0xcf946222, 0xcf946222, 0xcfd5c782, 0xcfd5c282}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, @@ -82,9 +82,9 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a3a4, 0x00000010, 0x00000010, 0x00000000, 0x00000000}, + {0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000}, {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}, - {0x0000a3ac, 0xaaaaaa00, 0xaaaaaa30, 0xaaaaaa00, 0xaaaaaa00}, + {0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00}, {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, @@ -363,14 +363,14 @@ static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = { /* Addr allmodes */ {0x00018c00, 0x18213ede}, {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0003580c}, + {0x00018c08, 0x0003780c}, }; static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { /* Addr allmodes */ {0x00018c00, 0x18212ede}, {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0003580c}, + {0x00018c08, 0x0003780c}, }; static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { @@ -775,7 +775,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = { {0x00009fc0, 0x803e4788}, {0x00009fc4, 0x0001efb5}, {0x00009fcc, 0x40000014}, - {0x00009fd0, 0x01193b93}, + {0x00009fd0, 0x0a193b93}, {0x0000a20c, 0x00000000}, {0x0000a220, 0x00000000}, {0x0000a224, 0x00000000}, @@ -850,7 +850,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = { {0x0000a7cc, 0x00000000}, {0x0000a7d0, 0x00000000}, {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000001}, + {0x0000a7dc, 0x00000000}, {0x0000a7f0, 0x80000000}, {0x0000a8d0, 0x004b6a8e}, {0x0000a8d4, 0x00000820}, @@ -886,7 +886,7 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, @@ -906,20 +906,20 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, + {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84}, {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0}, + {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4}, + {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, + {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, + {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, + {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -1053,7 +1053,6 @@ static const u32 ar9462_2p0_mac_core[][2] = { {0x00008044, 0x00000000}, {0x00008048, 0x00000000}, {0x0000804c, 0xffffffff}, - {0x00008050, 0xffffffff}, {0x00008054, 0x00000000}, {0x00008058, 0x00000000}, {0x0000805c, 0x000fc78f}, @@ -1117,9 +1116,9 @@ static const u32 ar9462_2p0_mac_core[][2] = { {0x000081f8, 0x00000000}, {0x000081fc, 0x00000000}, {0x00008240, 0x00100000}, - {0x00008244, 0x0010f424}, + {0x00008244, 0x0010f400}, {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e848}, + {0x0000824c, 0x0001e800}, {0x00008250, 0x00000000}, {0x00008254, 0x00000000}, {0x00008258, 0x00000000}, -- cgit From ef95e58deffef56076890383cc8a4b199612e758 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 4 Mar 2013 12:42:55 +0530 Subject: ath9k_hw: Fix fixed antenna for AR9462 When the RX chainmask is set to 0x2 for AR9462, certain values from chain1 have to be programmed for chain0 also. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 881e989ea470..e6b92ff265fd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3606,6 +3606,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); + if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) { + value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); + REG_RMW_FIELD(ah, switch_chain_reg[0], + AR_SWITCH_TABLE_ALL, value); + } + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { if ((ah->rxchainmask & BIT(chain)) || (ah->txchainmask & BIT(chain))) { @@ -3772,6 +3778,17 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) AR_PHY_EXT_ATTEN_CTL_2, }; + if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) { + value = ar9003_hw_atten_chain_get(ah, 1, chan); + REG_RMW_FIELD(ah, ext_atten_reg[0], + AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); + + value = ar9003_hw_atten_chain_get_margin(ah, 1, chan); + REG_RMW_FIELD(ah, ext_atten_reg[0], + AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, + value); + } + /* Test value. if 0 then attenuation is unused. Don't load anything. */ for (i = 0; i < 3; i++) { if (ah->txchainmask & BIT(i)) { -- cgit From 7c2332b8061b7d4d7cd539ced1277e78d976f3da Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 4 Mar 2013 16:39:10 +0100 Subject: b43: HT-PHY: make it BCMA-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HT-PHY was found only on BCM4331 which is a BCMA-based chipset. This is reallly unlikely we will ever see HT-PHY on SSB thus make the whole code BCMA specific. This will allow us to call various BCMA-specific functions directly (without extra checks). Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 2 +- drivers/net/wireless/b43/phy_ht.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index c3024ecea38a..078e6f3477a9 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -131,7 +131,7 @@ config B43_PHY_LP config B43_PHY_HT bool "Support for HT-PHY (high throughput) devices" - depends on B43 + depends on B43 && B43_BCMA ---help--- Support for the HT-PHY. diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 7416c5e9154d..3719a8884c1e 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -346,6 +346,11 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) u16 tmp; u16 clip_state[3]; + if (dev->dev->bus_type != B43_BUS_BCMA) { + b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n"); + return -EOPNOTSUPP; + } + b43_phy_ht_tables_init(dev); b43_phy_mask(dev, 0x0be, ~0x2); -- cgit From 4d900389048921a703160b009b7e015005e0b007 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 4 Mar 2013 15:31:16 -0800 Subject: ath9k: Report txerr-filtered errors in debugfs. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 3 +++ drivers/net/wireless/ath/ath9k/debug.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 3714b971d18e..daae4d09a80a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -537,6 +537,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("AMPDUs Completed:", a_completed); PR("AMPDUs Retried: ", a_retries); PR("AMPDUs XRetried: ", a_xretries); + PR("TXERR Filtered: ", txerr_filtered); PR("FIFO Underrun: ", fifo_underrun); PR("TXOP Exceeded: ", xtxop); PR("TXTIMER Expiry: ", timer_exp); @@ -756,6 +757,8 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, TX_STAT_INC(qnum, completed); } + if (ts->ts_status & ATH9K_TXERR_FILT) + TX_STAT_INC(qnum, txerr_filtered); if (ts->ts_status & ATH9K_TXERR_FIFO) TX_STAT_INC(qnum, fifo_underrun); if (ts->ts_status & ATH9K_TXERR_XTXOP) diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 410d6d8f1aa7..794a7ec83a24 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -142,6 +142,7 @@ struct ath_interrupt_stats { * @a_completed: Total AMPDUs completed * @a_retries: No. of AMPDUs retried (SW) * @a_xretries: No. of AMPDUs dropped due to xretries + * @txerr_filtered: No. of frames with TXERR_FILT flag set. * @fifo_underrun: FIFO underrun occurrences Valid only for: - non-aggregate condition. @@ -168,6 +169,7 @@ struct ath_tx_stats { u32 a_completed; u32 a_retries; u32 a_xretries; + u32 txerr_filtered; u32 fifo_underrun; u32 xtxop; u32 timer_exp; -- cgit From 18c45b108c6f5027d49000b9fe700aea76a3f04e Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 4 Mar 2013 15:31:17 -0800 Subject: ath9k: Report rx-crc-errors in ethtool stats. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index daae4d09a80a..67a2a4b3b883 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1912,6 +1912,7 @@ static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { AMKSTR(d_tx_desc_cfg_err), AMKSTR(d_tx_data_underrun), AMKSTR(d_tx_delim_underrun), + "d_rx_crc_err", "d_rx_decrypt_crc_err", "d_rx_phy_err", "d_rx_mic_err", @@ -1992,6 +1993,7 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, AWDATA(data_underrun); AWDATA(delim_underrun); + AWDATA_RX(crc_err); AWDATA_RX(decrypt_crc_err); AWDATA_RX(phy_err); AWDATA_RX(mic_err); -- cgit From fcca8d5ae5991a3ef18d9eceeb6e22caad36ab7d Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 4 Mar 2013 16:27:53 -0800 Subject: mwifiex: remove static forward declarations in pcie.c move functions up just to avoid static forward declaration for mwifiex_pcie_resume. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 150 ++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 35c79722c361..f7e8c73f1bc6 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -36,8 +36,6 @@ static u8 user_rmmod; static struct mwifiex_if_ops pcie_ops; static struct semaphore add_remove_card_sem; -static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter); -static int mwifiex_pcie_resume(struct pci_dev *pdev); static int mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, @@ -78,6 +76,80 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) return false; } +/* + * Kernel needs to suspend all functions separately. Therefore all + * registered functions must have drivers with suspend and resume + * methods. Failing that the kernel simply removes the whole card. + * + * If already not suspended, this function allocates and sends a host + * sleep activate request to the firmware and turns off the traffic. + */ +static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct mwifiex_adapter *adapter; + struct pcie_service_card *card; + int hs_actived; + + if (pdev) { + card = (struct pcie_service_card *) pci_get_drvdata(pdev); + if (!card || !card->adapter) { + pr_err("Card or adapter structure is not valid\n"); + return 0; + } + } else { + pr_err("PCIE device is not specified\n"); + return 0; + } + + adapter = card->adapter; + + hs_actived = mwifiex_enable_hs(adapter); + + /* Indicate device suspended */ + adapter->is_suspended = true; + + return 0; +} + +/* + * Kernel needs to suspend all functions separately. Therefore all + * registered functions must have drivers with suspend and resume + * methods. Failing that the kernel simply removes the whole card. + * + * If already not resumed, this function turns on the traffic and + * sends a host sleep cancel request to the firmware. + */ +static int mwifiex_pcie_resume(struct pci_dev *pdev) +{ + struct mwifiex_adapter *adapter; + struct pcie_service_card *card; + + if (pdev) { + card = (struct pcie_service_card *) pci_get_drvdata(pdev); + if (!card || !card->adapter) { + pr_err("Card or adapter structure is not valid\n"); + return 0; + } + } else { + pr_err("PCIE device is not specified\n"); + return 0; + } + + adapter = card->adapter; + + if (!adapter->is_suspended) { + dev_warn(adapter->dev, "Device already resumed\n"); + return 0; + } + + adapter->is_suspended = false; + + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), + MWIFIEX_ASYNC_CMD); + + return 0; +} + /* * This function probes an mwifiex device and registers it. It allocates * the card structure, enables PCIE function number and initiates the @@ -159,80 +231,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) kfree(card); } -/* - * Kernel needs to suspend all functions separately. Therefore all - * registered functions must have drivers with suspend and resume - * methods. Failing that the kernel simply removes the whole card. - * - * If already not suspended, this function allocates and sends a host - * sleep activate request to the firmware and turns off the traffic. - */ -static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct mwifiex_adapter *adapter; - struct pcie_service_card *card; - int hs_actived; - - if (pdev) { - card = (struct pcie_service_card *) pci_get_drvdata(pdev); - if (!card || !card->adapter) { - pr_err("Card or adapter structure is not valid\n"); - return 0; - } - } else { - pr_err("PCIE device is not specified\n"); - return 0; - } - - adapter = card->adapter; - - hs_actived = mwifiex_enable_hs(adapter); - - /* Indicate device suspended */ - adapter->is_suspended = true; - - return 0; -} - -/* - * Kernel needs to suspend all functions separately. Therefore all - * registered functions must have drivers with suspend and resume - * methods. Failing that the kernel simply removes the whole card. - * - * If already not resumed, this function turns on the traffic and - * sends a host sleep cancel request to the firmware. - */ -static int mwifiex_pcie_resume(struct pci_dev *pdev) -{ - struct mwifiex_adapter *adapter; - struct pcie_service_card *card; - - if (pdev) { - card = (struct pcie_service_card *) pci_get_drvdata(pdev); - if (!card || !card->adapter) { - pr_err("Card or adapter structure is not valid\n"); - return 0; - } - } else { - pr_err("PCIE device is not specified\n"); - return 0; - } - - adapter = card->adapter; - - if (!adapter->is_suspended) { - dev_warn(adapter->dev, "Device already resumed\n"); - return 0; - } - - adapter->is_suspended = false; - - mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_ASYNC_CMD); - - return 0; -} - static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { { PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, -- cgit From 8509e82064319d175192837355a92653e1517798 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 4 Mar 2013 16:27:54 -0800 Subject: mwifiex: fix [-Wunused-function] warnings on pcie suspend/resume drivers/net/wireless/mwifiex/pcie.c:204:12: warning: 'mwifiex_pcie_resume' defined but not used [-Wunused-function] drivers/net/wireless/mwifiex/pcie.c:166:12: warning: 'mwifiex_pcie_suspend' defined but not used [-Wunused-function] The suspend/resume handlers ought to be under CONFIG_PM directive. Reported-by: kbuild test robot Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index f7e8c73f1bc6..cf7bdf424d05 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -76,6 +76,7 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) return false; } +#ifdef CONFIG_PM /* * Kernel needs to suspend all functions separately. Therefore all * registered functions must have drivers with suspend and resume @@ -149,6 +150,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) return 0; } +#endif /* * This function probes an mwifiex device and registers it. It allocates -- cgit From 9931078e36bd2caa3d5364cab31a893d50a8b5de Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 4 Mar 2013 16:27:55 -0800 Subject: mwifiex: avoid [-Wmaybe-uninitialized] warnings in pcie.c drivers/net/wireless/mwifiex/pcie.c:1157:9: warning: 'desc2' may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/net/wireless/mwifiex/pcie.c:1048:31: note: 'desc2' was declared here drivers/net/wireless/mwifiex/pcie.c:1159:9: warning: 'desc' may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/net/wireless/mwifiex/pcie.c:1047:32: note: 'desc' was declared here Reported-by: kbuild test robot Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index cf7bdf424d05..b813a27ee613 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -1030,8 +1030,8 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, u32 wrindx, num_tx_buffs, rx_val; int ret; dma_addr_t buf_pa; - struct mwifiex_pcie_buf_desc *desc; - struct mwifiex_pfu_buf_desc *desc2; + struct mwifiex_pcie_buf_desc *desc = NULL; + struct mwifiex_pfu_buf_desc *desc2 = NULL; __le16 *tmp; if (!(skb->data && skb->len)) { -- cgit From f553e1aad797540afddd1a99753a348e1c426ffe Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 4 Mar 2013 16:27:56 -0800 Subject: mwifiex: modify skb->truesize for PCIE Rx We allocate SKB buffers of 4K size to make sure that we process RX AMSDU of 4K. So when skb->len is lesser than 4K; we should modify skb->truesize. This resolves an issue where kernel has allocated packets with 2K assumption and starts dropping packets for large size data transfer. This fix is already present for USB; extend it to PCIE. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 21553976b550..54667e65ca47 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -195,7 +195,7 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) skb->protocol = eth_type_trans(skb, priv->netdev); skb->ip_summed = CHECKSUM_NONE; - /* This is required only in case of 11n and USB as we alloc + /* This is required only in case of 11n and USB/PCIE as we alloc * a buffer of 4K only if its 11N (to be able to receive 4K * AMSDU packets). In case of SD we allocate buffers based * on the size of packet and hence this is not needed. @@ -212,7 +212,8 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) * fragments. Currently we fail the Filesndl-ht.scr script * for UDP, hence this fix */ - if ((priv->adapter->iface_type == MWIFIEX_USB) && + if ((priv->adapter->iface_type == MWIFIEX_USB || + priv->adapter->iface_type == MWIFIEX_PCIE) && (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); -- cgit From cc0b5a64b8e79b7fb73b8dfd4f71ac86d3ac94c7 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 4 Mar 2013 16:27:57 -0800 Subject: mwifiex: shorten the host sleep configuration macro names As we are adding a few more macros in this category in next patch, this cleanup work is required. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 2 +- drivers/net/wireless/mwifiex/fw.h | 8 ++++---- drivers/net/wireless/mwifiex/init.c | 6 +++--- drivers/net/wireless/mwifiex/sta_cmd.c | 2 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 20a6c5555873..d19a88c47a4d 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1139,7 +1139,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap); } - if (conditions != HOST_SLEEP_CFG_CANCEL) { + if (conditions != HS_CFG_CANCEL) { adapter->is_hs_configured = true; if (adapter->iface_type == MWIFIEX_USB || adapter->iface_type == MWIFIEX_PCIE) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 25acb0682c56..270685ed53dc 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -376,10 +376,10 @@ enum P2P_MODES { #define HostCmd_SCAN_RADIO_TYPE_BG 0 #define HostCmd_SCAN_RADIO_TYPE_A 1 -#define HOST_SLEEP_CFG_CANCEL 0xffffffff -#define HOST_SLEEP_CFG_COND_DEF 0x00000000 -#define HOST_SLEEP_CFG_GPIO_DEF 0xff -#define HOST_SLEEP_CFG_GAP_DEF 0 +#define HS_CFG_CANCEL 0xffffffff +#define HS_CFG_COND_DEF 0x00000000 +#define HS_CFG_GPIO_DEF 0xff +#define HS_CFG_GAP_DEF 0 #define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc #define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e38aa9b3663d..cab3434d0d52 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -318,9 +318,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; adapter->is_hs_configured = false; - adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF); - adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF; - adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF; + adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF); + adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF; + adapter->hs_cfg.gap = HS_CFG_GAP_DEF; adapter->hs_activated = false; memset(adapter->event_body, 0, sizeof(adapter->event_body)); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index c55c5bb93134..3d51721af2eb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -334,7 +334,7 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && + (hscfg_param->conditions != cpu_to_le32(HS_CFG_CANCEL)) && ((adapter->arp_filter_size > 0) && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { dev_dbg(adapter->dev, diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 9f33c92c90f5..76d31deb7b1b 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -388,7 +388,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, break; } if (hs_cfg->is_invoke_hostcmd) { - if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) { + if (hs_cfg->conditions == HS_CFG_CANCEL) { if (!adapter->is_hs_configured) /* Already cancelled */ break; @@ -403,8 +403,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; if (hs_cfg->gap) adapter->hs_cfg.gap = (u8)hs_cfg->gap; - } else if (adapter->hs_cfg.conditions - == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { + } else if (adapter->hs_cfg.conditions == + cpu_to_le32(HS_CFG_CANCEL)) { /* Return failure if no parameters for HS enable */ status = -1; @@ -420,7 +420,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, HostCmd_CMD_802_11_HS_CFG_ENH, HostCmd_ACT_GEN_SET, 0, &adapter->hs_cfg); - if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) + if (hs_cfg->conditions == HS_CFG_CANCEL) /* Restore previous condition */ adapter->hs_cfg.conditions = cpu_to_le32(prev_cond); @@ -454,7 +454,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) { struct mwifiex_ds_hs_cfg hscfg; - hscfg.conditions = HOST_SLEEP_CFG_CANCEL; + hscfg.conditions = HS_CFG_CANCEL; hscfg.is_invoke_hostcmd = true; return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, -- cgit From 0d7f53e34d3f5f82c0f4941356a02285a78807a4 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 4 Mar 2013 16:27:58 -0800 Subject: mwifiex: add "ethtool wol" command support Host sleep wakeup condition is configured using this command. Supports Wake-on: pumb For examples: wake-on any unicast packets: ethtool -s mlan0 wol u wake-on multicast/broadcast packet: ethtool -s mlan0 wol mb wake-on unicast packets and MAC events: ethtool -s mlan0 wol pu wake-on unicast/multicast/broadcast packets and MAC events: ethtool -s mlan0 wol pmbu disable all wake-on options: ethtool -s mlan0 wol d Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/Makefile | 1 + drivers/net/wireless/mwifiex/cfg80211.c | 1 + drivers/net/wireless/mwifiex/ethtool.c | 70 +++++++++++++++++++++++++++++++++ drivers/net/wireless/mwifiex/fw.h | 4 ++ drivers/net/wireless/mwifiex/main.h | 2 + 5 files changed, 78 insertions(+) create mode 100644 drivers/net/wireless/mwifiex/ethtool.c (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile index 97b245cbafd8..ecf28464367f 100644 --- a/drivers/net/wireless/mwifiex/Makefile +++ b/drivers/net/wireless/mwifiex/Makefile @@ -39,6 +39,7 @@ mwifiex-y += sta_tx.o mwifiex-y += sta_rx.o mwifiex-y += uap_txrx.o mwifiex-y += cfg80211.o +mwifiex-y += ethtool.o mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o obj-$(CONFIG_MWIFIEX) += mwifiex.o diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a44023a7bd57..45790faf6ebb 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2235,6 +2235,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; + dev->ethtool_ops = &mwifiex_ethtool_ops; mdev_priv = netdev_priv(dev); *((unsigned long *) mdev_priv) = (unsigned long) priv; diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c new file mode 100644 index 000000000000..bfb39908b2c6 --- /dev/null +++ b/drivers/net/wireless/mwifiex/ethtool.c @@ -0,0 +1,70 @@ +/* + * Marvell Wireless LAN device driver: ethtool + * + * Copyright (C) 2013, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "main.h" + +static void mwifiex_ethtool_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + u32 conditions = le32_to_cpu(priv->adapter->hs_cfg.conditions); + + wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY; + + if (conditions == HS_CFG_COND_DEF) + return; + + if (conditions & HS_CFG_COND_UNICAST_DATA) + wol->wolopts |= WAKE_UCAST; + if (conditions & HS_CFG_COND_MULTICAST_DATA) + wol->wolopts |= WAKE_MCAST; + if (conditions & HS_CFG_COND_BROADCAST_DATA) + wol->wolopts |= WAKE_BCAST; + if (conditions & HS_CFG_COND_MAC_EVENT) + wol->wolopts |= WAKE_PHY; +} + +static int mwifiex_ethtool_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + u32 conditions = 0; + + if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) + return -EOPNOTSUPP; + + if (wol->wolopts & WAKE_UCAST) + conditions |= HS_CFG_COND_UNICAST_DATA; + if (wol->wolopts & WAKE_MCAST) + conditions |= HS_CFG_COND_MULTICAST_DATA; + if (wol->wolopts & WAKE_BCAST) + conditions |= HS_CFG_COND_BROADCAST_DATA; + if (wol->wolopts & WAKE_PHY) + conditions |= HS_CFG_COND_MAC_EVENT; + if (wol->wolopts == 0) + conditions |= HS_CFG_COND_DEF; + priv->adapter->hs_cfg.conditions = cpu_to_le32(conditions); + + return 0; +} + +const struct ethtool_ops mwifiex_ethtool_ops = { + .get_wol = mwifiex_ethtool_get_wol, + .set_wol = mwifiex_ethtool_set_wol, +}; diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 270685ed53dc..5a5d06659d57 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -380,6 +380,10 @@ enum P2P_MODES { #define HS_CFG_COND_DEF 0x00000000 #define HS_CFG_GPIO_DEF 0xff #define HS_CFG_GAP_DEF 0 +#define HS_CFG_COND_BROADCAST_DATA 0x00000001 +#define HS_CFG_COND_UNICAST_DATA 0x00000002 +#define HS_CFG_COND_MAC_EVENT 0x00000004 +#define HS_CFG_COND_MULTICAST_DATA 0x00000008 #define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc #define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 553adfb0aa81..989e05e3d81c 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1103,6 +1103,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); u8 *mwifiex_11d_code_2_region(u8 code); +extern const struct ethtool_ops mwifiex_ethtool_ops; + #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); void mwifiex_debugfs_remove(void); -- cgit From 7da060c1c01b103d181dba39bce9bd141a945f99 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 4 Mar 2013 16:27:59 -0800 Subject: mwifiex: add WOWLAN support Currently 'magic-packet' and 'patterns' options in 'iw wowlan' command are supported. Appropriate packet filters for wowlan are configured in firmware based on provided patterns and/or magic-packet option. For examples, wake-on ARP request for 192.168.0.100: iw phy0 wowlan enable patterns ff:ff:ff:ff:ff:ff 20+08:06 46+c0:a8:00:64 wake-on RX packets sent from IP address 192.168.0.88: iw phy0 wowlan enable patterns 34+c0:a8:00:58 wake-on RX packets with TCP destination port 80 iw phy0 wowlan enable patterns 44+50 wake-on MagicPacket: iw phy0 wowlan enable magic-packet wake-on MagicPacket or patterns: iw phy0 wowlan enable magic-packet patterns 12+00:11:22:33:44:55 18+00:50:43:21 wake-on IPv4 multicast packets: iw phy0 wowlan enable patterns 01:00:5e wake-on IPv6 multicast packets: iw phy0 wowlan enable patterns 33:33 disable all wowlan options iw phy0 wowlan disable Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 156 +++++++++++++++++++++++++++++ drivers/net/wireless/mwifiex/fw.h | 32 ++++++ drivers/net/wireless/mwifiex/ioctl.h | 23 +++++ drivers/net/wireless/mwifiex/main.h | 2 + drivers/net/wireless/mwifiex/sta_cmd.c | 77 ++++++++++++++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 + 6 files changed, 292 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 45790faf6ebb..df30107225f8 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2294,6 +2294,149 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) } EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf); +#ifdef CONFIG_PM +static bool +mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat, + s8 *byte_seq) +{ + int j, k, valid_byte_cnt = 0; + bool dont_care_byte = false; + + for (j = 0; j < DIV_ROUND_UP(pat->pattern_len, 8); j++) { + for (k = 0; k < 8; k++) { + if (pat->mask[j] & 1 << k) { + memcpy(byte_seq + valid_byte_cnt, + &pat->pattern[j * 8 + k], 1); + valid_byte_cnt++; + if (dont_care_byte) + return false; + } else { + if (valid_byte_cnt) + dont_care_byte = true; + } + + if (valid_byte_cnt > MAX_BYTESEQ) + return false; + } + } + + byte_seq[MAX_BYTESEQ] = valid_byte_cnt; + + return true; +} + +static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wowlan) +{ + struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); + struct mwifiex_ds_mef_cfg mef_cfg; + struct mwifiex_mef_entry *mef_entry; + int i, filt_num = 0, ret; + bool first_pat = true; + u8 byte_seq[MAX_BYTESEQ + 1]; + const u8 ipv4_mc_mac[] = {0x33, 0x33}; + const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e}; + struct mwifiex_private *priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); + + if (!wowlan) { + dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n"); + return 0; + } + + if (!priv->media_connected) { + dev_warn(adapter->dev, + "Can not configure WOWLAN in disconnected state\n"); + return 0; + } + + memset(&mef_cfg, 0, sizeof(mef_cfg)); + mef_cfg.num_entries = 1; + mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL); + mef_cfg.mef_entry = mef_entry; + mef_entry->mode = MEF_MODE_HOST_SLEEP; + mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST; + + for (i = 0; i < wowlan->n_patterns; i++) { + memset(byte_seq, 0, sizeof(byte_seq)); + if (!mwifiex_is_pattern_supported(&wowlan->patterns[i], + byte_seq)) { + wiphy_err(wiphy, "Pattern not supported\n"); + kfree(mef_entry); + return -EOPNOTSUPP; + } + + if (!wowlan->patterns[i].pkt_offset) { + if (!(byte_seq[0] & 0x01) && + (byte_seq[MAX_BYTESEQ] == 1)) { + mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; + continue; + } else if (is_broadcast_ether_addr(byte_seq)) { + mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST; + continue; + } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) && + (byte_seq[MAX_BYTESEQ] == 2)) || + (!memcmp(byte_seq, ipv6_mc_mac, 3) && + (byte_seq[MAX_BYTESEQ] == 3))) { + mef_cfg.criteria |= MWIFIEX_CRITERIA_MULTICAST; + continue; + } + } + + mef_entry->filter[filt_num].repeat = 1; + mef_entry->filter[filt_num].offset = + wowlan->patterns[i].pkt_offset; + memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq, + sizeof(byte_seq)); + mef_entry->filter[filt_num].filt_type = TYPE_EQ; + + if (first_pat) + first_pat = false; + else + mef_entry->filter[filt_num].filt_action = TYPE_AND; + + filt_num++; + } + + if (wowlan->magic_pkt) { + mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; + mef_entry->filter[filt_num].repeat = 16; + memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, + ETH_ALEN); + mef_entry->filter[filt_num].byte_seq[MAX_BYTESEQ] = ETH_ALEN; + mef_entry->filter[filt_num].offset = 14; + mef_entry->filter[filt_num].filt_type = TYPE_EQ; + if (filt_num) + mef_entry->filter[filt_num].filt_action = TYPE_OR; + } + + if (!mef_cfg.criteria) + mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST | + MWIFIEX_CRITERIA_UNICAST | + MWIFIEX_CRITERIA_MULTICAST; + + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MEF_CFG, + HostCmd_ACT_GEN_SET, 0, + &mef_cfg); + + kfree(mef_entry); + return ret; +} + +static int mwifiex_cfg80211_resume(struct wiphy *wiphy) +{ + return 0; +} + +static void mwifiex_cfg80211_set_wakeup(struct wiphy *wiphy, + bool enabled) +{ + struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); + + device_set_wakeup_enable(adapter->dev, enabled); +} +#endif + /* station cfg80211 operations */ static struct cfg80211_ops mwifiex_cfg80211_ops = { .add_virtual_intf = mwifiex_add_virtual_intf, @@ -2322,6 +2465,11 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .change_beacon = mwifiex_cfg80211_change_beacon, .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, .set_antenna = mwifiex_cfg80211_set_antenna, +#ifdef CONFIG_PM + .suspend = mwifiex_cfg80211_suspend, + .resume = mwifiex_cfg80211_resume, + .set_wakeup = mwifiex_cfg80211_set_wakeup, +#endif }; /* @@ -2380,6 +2528,14 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); +#ifdef CONFIG_PM + wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT; + wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS; + wiphy->wowlan.pattern_min_len = 1; + wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN; + wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN; +#endif + wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 5a5d06659d57..6d6e5ae71eaa 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -300,6 +300,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f #define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 #define HostCmd_CMD_VERSION_EXT 0x0097 +#define HostCmd_CMD_MEF_CFG 0x009a #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa @@ -473,6 +474,23 @@ enum P2P_MODES { #define EVENT_GET_BSS_TYPE(event_cause) \ (((event_cause) >> 24) & 0x00ff) +#define MWIFIEX_MAX_PATTERN_LEN 20 +#define MWIFIEX_MAX_OFFSET_LEN 50 +#define STACK_NBYTES 100 +#define TYPE_DNUM 1 +#define TYPE_BYTESEQ 2 +#define MAX_OPERAND 0x40 +#define TYPE_EQ (MAX_OPERAND+1) +#define TYPE_EQ_DNUM (MAX_OPERAND+2) +#define TYPE_EQ_BIT (MAX_OPERAND+3) +#define TYPE_AND (MAX_OPERAND+4) +#define TYPE_OR (MAX_OPERAND+5) +#define MEF_MODE_HOST_SLEEP 1 +#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3 +#define MWIFIEX_CRITERIA_BROADCAST BIT(0) +#define MWIFIEX_CRITERIA_UNICAST BIT(1) +#define MWIFIEX_CRITERIA_MULTICAST BIT(3) + struct mwifiex_ie_types_header { __le16 type; __le16 len; @@ -1503,6 +1521,19 @@ struct host_cmd_ds_802_11_ibss_status { __le16 use_g_rate_protect; } __packed; +struct mwifiex_fw_mef_entry { + u8 mode; + u8 action; + __le16 exprsize; + u8 expr[0]; +} __packed; + +struct host_cmd_ds_mef_cfg { + __le32 criteria; + __le16 num_entries; + struct mwifiex_fw_mef_entry mef_entry[0]; +} __packed; + #define CONNECTION_TYPE_INFRA 0 #define CONNECTION_TYPE_ADHOC 1 #define CONNECTION_TYPE_AP 2 @@ -1607,6 +1638,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_remain_on_chan roc_cfg; struct host_cmd_ds_p2p_mode_cfg mode_cfg; struct host_cmd_ds_802_11_ibss_status ibss_coalescing; + struct host_cmd_ds_mef_cfg mef_cfg; struct host_cmd_ds_mac_reg_access mac_reg; struct host_cmd_ds_bbp_reg_access bbp_reg; struct host_cmd_ds_rf_reg_access rf_reg; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d85e6eb1f58a..91d522c746ed 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -354,6 +354,29 @@ struct mwifiex_ds_misc_subsc_evt { struct subsc_evt_cfg bcn_h_rssi_cfg; }; +#define MAX_BYTESEQ 6 /* non-adjustable */ +#define MWIFIEX_MAX_FILTERS 10 + +struct mwifiex_mef_filter { + u16 repeat; + u16 offset; + s8 byte_seq[MAX_BYTESEQ + 1]; + u8 filt_type; + u8 filt_action; +}; + +struct mwifiex_mef_entry { + u8 mode; + u8 action; + struct mwifiex_mef_filter filter[MWIFIEX_MAX_FILTERS]; +}; + +struct mwifiex_ds_mef_cfg { + u32 criteria; + u16 num_entries; + struct mwifiex_mef_entry *mef_entry; +}; + #define MWIFIEX_MAX_VSIE_LEN (256) #define MWIFIEX_MAX_VSIE_NUM (8) #define MWIFIEX_VSIE_MASK_CLEAR 0x00 diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 989e05e3d81c..560cf7312d08 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1098,6 +1098,8 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev); void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); +int mwifiex_add_wowlan_magic_pkt_filter(struct mwifiex_adapter *adapter); + int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, struct cfg80211_beacon_data *data); int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 3d51721af2eb..a2ae690a0a67 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1059,6 +1059,80 @@ mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv, return 0; } +static int +mwifiex_cmd_append_rpn_expression(struct mwifiex_private *priv, + struct mwifiex_mef_entry *mef_entry, + u8 **buffer) +{ + struct mwifiex_mef_filter *filter = mef_entry->filter; + int i, byte_len; + u8 *stack_ptr = *buffer; + + for (i = 0; i < MWIFIEX_MAX_FILTERS; i++) { + filter = &mef_entry->filter[i]; + if (!filter->filt_type) + break; + *(__le32 *)stack_ptr = cpu_to_le32((u32)filter->repeat); + stack_ptr += 4; + *stack_ptr = TYPE_DNUM; + stack_ptr += 1; + + byte_len = filter->byte_seq[MAX_BYTESEQ]; + memcpy(stack_ptr, filter->byte_seq, byte_len); + stack_ptr += byte_len; + *stack_ptr = byte_len; + stack_ptr += 1; + *stack_ptr = TYPE_BYTESEQ; + stack_ptr += 1; + + *(__le32 *)stack_ptr = cpu_to_le32((u32)filter->offset); + stack_ptr += 4; + *stack_ptr = TYPE_DNUM; + stack_ptr += 1; + + *stack_ptr = filter->filt_type; + stack_ptr += 1; + + if (filter->filt_action) { + *stack_ptr = filter->filt_action; + stack_ptr += 1; + } + + if (stack_ptr - *buffer > STACK_NBYTES) + return -1; + } + + *buffer = stack_ptr; + return 0; +} + +static int +mwifiex_cmd_mef_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + struct mwifiex_ds_mef_cfg *mef) +{ + struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg; + u8 *pos = (u8 *)mef_cfg; + + cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG); + + mef_cfg->criteria = cpu_to_le32(mef->criteria); + mef_cfg->num_entries = cpu_to_le16(mef->num_entries); + pos += sizeof(*mef_cfg); + mef_cfg->mef_entry->mode = mef->mef_entry->mode; + mef_cfg->mef_entry->action = mef->mef_entry->action; + pos += sizeof(*(mef_cfg->mef_entry)); + + if (mwifiex_cmd_append_rpn_expression(priv, mef->mef_entry, &pos)) + return -1; + + mef_cfg->mef_entry->exprsize = + cpu_to_le16(pos - mef_cfg->mef_entry->expr); + cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN); + + return 0; +} + /* * This function prepares the commands before sending them to the firmware. * @@ -1273,6 +1347,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: ret = mwifiex_cmd_802_11_subsc_evt(priv, cmd_ptr, data_buf); break; + case HostCmd_CMD_MEF_CFG: + ret = mwifiex_cmd_mef_cfg(priv, cmd_ptr, data_buf); + break; default: dev_err(priv->adapter->dev, "PREP_CMD: unknown cmd- %#x\n", cmd_no); diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 4669f8d9389f..80b9f2238001 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -976,6 +976,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_UAP_BSS_STOP: priv->bss_started = 0; break; + case HostCmd_CMD_MEF_CFG: + break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", resp->command); -- cgit From 289d1054e972b445fe8f7bbcbebf40b1bec37384 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Thu, 7 Mar 2013 08:53:00 +1100 Subject: lguest: fix paths in comments After commit 07fe997, lguest tool has already moved from Documentation/virtual/lguest/ to tools/lguest/. Signed-off-by: Wanlong Gao Signed-off-by: Rusty Russell --- drivers/lguest/Kconfig | 5 ++--- tools/lguest/lguest.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 89875ea19ade..ee035ec4526b 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -5,10 +5,9 @@ config LGUEST ---help--- This is a very simple module which allows you to run multiple instances of the same Linux kernel, using the - "lguest" command found in the Documentation/virtual/lguest - directory. + "lguest" command found in the tools/lguest directory. Note that "lguest" is pronounced to rhyme with "fell quest", - not "rustyvisor". See Documentation/virtual/lguest/lguest.txt. + not "rustyvisor". See tools/lguest/lguest.txt. If unsure, say N. If curious, say M. If masochistic, say Y. diff --git a/tools/lguest/lguest.txt b/tools/lguest/lguest.txt index 7203ace65e83..06e1f4649511 100644 --- a/tools/lguest/lguest.txt +++ b/tools/lguest/lguest.txt @@ -70,7 +70,7 @@ Running Lguest: - Run an lguest as root: - Documentation/virtual/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 \ + tools/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 \ --block=rootfile root=/dev/vda Explanation: -- cgit From 76f3ae125f3ca777cc831d475d17184641d5bc46 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Wed, 20 Feb 2013 13:35:16 -0500 Subject: mmc: sdhci-tegra: cleanup ifdefs The structs wrapped with the SOC ifdefs are small enough where having them always there shouldn't be a big overhead. Removing the ifdefs also makes the code a little cleaner. Signed-off-by: Rhyland Klein Acked-by: Stephen Warren Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-tegra.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 08b06e9a3a21..73009713640e 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -173,7 +173,6 @@ static struct sdhci_ops tegra_sdhci_ops = { .platform_reset_exit = tegra_sdhci_reset_exit, }; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC static struct sdhci_pltfm_data sdhci_tegra20_pdata = { .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_SINGLE_POWER_WRITE | @@ -187,9 +186,7 @@ static struct sdhci_tegra_soc_data soc_data_tegra20 = { .nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 | NVQUIRK_ENABLE_BLOCK_GAP_DET, }; -#endif -#ifdef CONFIG_ARCH_TEGRA_3x_SOC static struct sdhci_pltfm_data sdhci_tegra30_pdata = { .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | @@ -203,15 +200,10 @@ static struct sdhci_tegra_soc_data soc_data_tegra30 = { .pdata = &sdhci_tegra30_pdata, .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300, }; -#endif static const struct of_device_id sdhci_tegra_dt_match[] = { -#ifdef CONFIG_ARCH_TEGRA_3x_SOC { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 }, -#endif -#ifdef CONFIG_ARCH_TEGRA_2x_SOC { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 }, -#endif {} }; MODULE_DEVICE_TABLE(of, sdhci_dt_ids); -- cgit From 5ebf2552493228ec875ea45f6ba8a816cca3744a Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Wed, 20 Feb 2013 13:35:17 -0500 Subject: mmc: sdhci-tegra: add basic support for Tegra114 The mmc controller on Tegra114 platforms is basically compatible with the settings used for Tegra30. However there is a difference where we don't need the extra ENABLE_SDHCI_SPEC_300 quirk as Tegra114 hardware advertises v3.0 support already. Signed-off-by: Rhyland Klein Acked-by: Stephen Warren Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-tegra.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 73009713640e..ff99b632808d 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -201,7 +201,21 @@ static struct sdhci_tegra_soc_data soc_data_tegra30 = { .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300, }; +static struct sdhci_pltfm_data sdhci_tegra114_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_NO_HISPD_BIT | + SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, + .ops = &tegra_sdhci_ops, +}; + +static struct sdhci_tegra_soc_data soc_data_tegra114 = { + .pdata = &sdhci_tegra114_pdata, +}; + static const struct of_device_id sdhci_tegra_dt_match[] = { + { .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 }, { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 }, { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 }, {} -- cgit From f04a9d8adf766c480353c0f2427e641251c9b059 Mon Sep 17 00:00:00 2001 From: Rajkumar Kasirajan Date: Wed, 30 May 2012 16:32:37 +0530 Subject: mfd: ab8500-sysctrl: Update correct turn on status In L9540, turn_on_status register is not updated correctly if the device is rebooted with AC/USB charger connected. Due to this, the device boots android instead of entering into charge only mode. Read the AC/USB status register to detect the charger presence and update the turn on status manually. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Per Forlin Signed-off-by: Lee Jones Reviewed-by: Rupesh KUMAR Reviewed-by: Philippe LANGLAIS Tested-by: Rupesh KUMAR Tested-by: Philippe LANGLAIS Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 39 +++++++++++++++++++++++++++++++++++++++ drivers/mfd/ab8500-sysctrl.c | 2 +- include/linux/mfd/abx500/ab8500.h | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 7c84ced2e01b..50e6f1e29727 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -111,6 +111,13 @@ #define AB8500_TURN_ON_STATUS 0x00 +#define AB8500_CH_USBCH_STAT1_REG 0x02 +#define VBUS_DET_DBNC100 0x02 +#define VBUS_DET_DBNC1 0x01 + +static DEFINE_SPINLOCK(on_stat_lock); +static u8 turn_on_stat_mask = 0xFF; +static u8 turn_on_stat_set; static bool no_bm; /* No battery management */ module_param(no_bm, bool, S_IRUGO); @@ -1171,6 +1178,15 @@ static ssize_t show_switch_off_status(struct device *dev, return sprintf(buf, "%#x\n", value); } +/* use mask and set to override the register turn_on_stat value */ +void ab8500_override_turn_on_stat(u8 mask, u8 set) +{ + spin_lock(&on_stat_lock); + turn_on_stat_mask = mask; + turn_on_stat_set = set; + spin_unlock(&on_stat_lock); +} + /* * ab8500 has turned on due to (TURN_ON_STATUS): * 0x01 PORnVbat @@ -1194,6 +1210,20 @@ static ssize_t show_turn_on_status(struct device *dev, AB8500_TURN_ON_STATUS, &value); if (ret < 0) return ret; + + /* + * In L9540, turn_on_status register is not updated correctly if + * the device is rebooted with AC/USB charger connected. Due to + * this, the device boots android instead of entering into charge + * only mode. Read the AC/USB status register to detect the charger + * presence and update the turn on status manually. + */ + if (is_ab9540(ab8500)) { + spin_lock(&on_stat_lock); + value = (value & turn_on_stat_mask) | turn_on_stat_set; + spin_unlock(&on_stat_lock); + } + return sprintf(buf, "%#x\n", value); } @@ -1399,6 +1429,15 @@ static int ab8500_probe(struct platform_device *pdev) if (plat && plat->init) plat->init(ab8500); + if (is_ab9540(ab8500)) { + ret = get_register_interruptible(ab8500, AB8500_CHARGER, + AB8500_CH_USBCH_STAT1_REG, &value); + if (ret < 0) + return ret; + if ((value & VBUS_DET_DBNC1) && (value & VBUS_DET_DBNC100)) + ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, + AB8500_VBUS_DET); + } /* Clear and mask all interrupts */ for (i = 0; i < ab8500->mask_size; i++) { diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 108fd86552f0..7c773797d267 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -21,7 +21,7 @@ void ab8500_power_off(void) { sigset_t old; sigset_t all; - static char *pss[] = {"ab8500_ac", "ab8500_usb"}; + static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"}; int i; bool charger_present = false; union power_supply_propval val; diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 9db0bda446a0..fdd8be64feeb 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h @@ -512,6 +512,8 @@ static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab) return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0)); } +void ab8500_override_turn_on_stat(u8 mask, u8 set); + #ifdef CONFIG_AB8500_DEBUG void ab8500_dump_all_banks(struct device *dev); void ab8500_debug_register_interrupt(int line); -- cgit From 774c50abae2456af492728aee8d282ba5079b744 Mon Sep 17 00:00:00 2001 From: Daniel WILLERUD Date: Thu, 12 Apr 2012 08:15:05 +0200 Subject: mfd: ab8500-gpadc: Implemented suspend/resume suspend/resume methods implemented to prevent suspend while the gpadc driver is busy. Signed-off-by: Daniel WILLERUD Signed-off-by: Lee Jones Reviewed-by: Jonas ABERG Reviewed-by: Ulf HANSSON Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-gpadc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index b1f3561b023f..9ed3afc31d11 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -605,6 +605,31 @@ static int ab8500_gpadc_runtime_idle(struct device *dev) return 0; } +static int ab8500_gpadc_suspend(struct device *dev) +{ + struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); + + mutex_lock(&gpadc->ab8500_gpadc_lock); + + pm_runtime_get_sync(dev); + + regulator_disable(gpadc->regu); + return 0; +} + +static int ab8500_gpadc_resume(struct device *dev) +{ + struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); + + regulator_enable(gpadc->regu); + + pm_runtime_mark_last_busy(gpadc->dev); + pm_runtime_put_autosuspend(gpadc->dev); + + mutex_unlock(&gpadc->ab8500_gpadc_lock); + return 0; +} + static int ab8500_gpadc_probe(struct platform_device *pdev) { int ret = 0; @@ -698,6 +723,9 @@ static const struct dev_pm_ops ab8500_gpadc_pm_ops = { SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend, ab8500_gpadc_runtime_resume, ab8500_gpadc_runtime_idle) + SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend, + ab8500_gpadc_resume) + }; static struct platform_driver ab8500_gpadc_driver = { -- cgit From d89cc5aad109d20d10d228ba52d86e0adca62461 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Tue, 17 Apr 2012 16:10:46 +0200 Subject: mfd: ab8500-gpadc: Reread on failure Reread the gpadc once upon failure. Signed-off-by: Jonas Aaberg Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-gpadc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 9ed3afc31d11..7f39479c1afc 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -256,6 +256,11 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) int voltage; ad_value = ab8500_gpadc_read_raw(gpadc, channel); + + /* On failure retry a second time */ + if (ad_value < 0) + ad_value = ab8500_gpadc_read_raw(gpadc, channel); + if (ad_value < 0) { dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel); return ad_value; -- cgit From 734823462590335cbf5c6a1fa5cae84a881dcb43 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 10:06:55 +0000 Subject: mfd: ab8500-gpadc: Add gpadc hw conversion Add the support of gpacd hw conversion and make the number of sample configurable. Signed-off-by: M'boumba Cedric Madianga Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Tested-by: Michel JAOUEN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 292 +++++++++++++++++++++++++++++--- drivers/mfd/ab8500-gpadc.c | 282 ++++++++++++++++++++++-------- include/linux/mfd/abx500/ab8500-gpadc.h | 30 +++- 3 files changed, 499 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 45fe3c50eb03..59ecd8c680ed 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -101,6 +101,11 @@ static int num_irqs; static struct device_attribute **dev_attr; static char **event_name; +static u8 avg_sample = SAMPLE_16; +static u8 trig_edge = RISING_EDGE; +static u8 conv_type = ADC_SW; +static u8 trig_timer; + /** * struct ab8500_reg_range * @first: the first address of the range @@ -808,9 +813,10 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL); + bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL, + avg_sample, trig_edge, trig_timer, conv_type); bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, - BAT_CTRL, bat_ctrl_raw); + BAT_CTRL, bat_ctrl_raw); return seq_printf(s, "%d,0x%X\n", bat_ctrl_convert, bat_ctrl_raw); @@ -836,9 +842,10 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL); + btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL, + avg_sample, trig_edge, trig_timer, conv_type); btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL, - btemp_ball_raw); + btemp_ball_raw); return seq_printf(s, "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw); @@ -865,9 +872,10 @@ static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V); + main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V, + avg_sample, trig_edge, trig_timer, conv_type); main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, - MAIN_CHARGER_V, main_charger_v_raw); + MAIN_CHARGER_V, main_charger_v_raw); return seq_printf(s, "%d,0x%X\n", main_charger_v_convert, main_charger_v_raw); @@ -895,9 +903,10 @@ static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1); + acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1, + avg_sample, trig_edge, trig_timer, conv_type); acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1, - acc_detect1_raw); + acc_detect1_raw); return seq_printf(s, "%d,0x%X\n", acc_detect1_convert, acc_detect1_raw); @@ -925,9 +934,10 @@ static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2); + acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2, + avg_sample, trig_edge, trig_timer, conv_type); acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc, - ACC_DETECT2, acc_detect2_raw); + ACC_DETECT2, acc_detect2_raw); return seq_printf(s, "%d,0x%X\n", acc_detect2_convert, acc_detect2_raw); @@ -955,9 +965,10 @@ static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1); + aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1, + avg_sample, trig_edge, trig_timer, conv_type); aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1, - aux1_raw); + aux1_raw); return seq_printf(s, "%d,0x%X\n", aux1_convert, aux1_raw); @@ -983,9 +994,10 @@ static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2); + aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2, + avg_sample, trig_edge, trig_timer, conv_type); aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2, - aux2_raw); + aux2_raw); return seq_printf(s, "%d,0x%X\n", aux2_convert, aux2_raw); @@ -1011,9 +1023,10 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V); + main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V, + avg_sample, trig_edge, trig_timer, conv_type); main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V, - main_bat_v_raw); + main_bat_v_raw); return seq_printf(s, "%d,0x%X\n", main_bat_v_convert, main_bat_v_raw); @@ -1040,9 +1053,10 @@ static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V); + vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V, + avg_sample, trig_edge, trig_timer, conv_type); vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V, - vbus_v_raw); + vbus_v_raw); return seq_printf(s, "%d,0x%X\n", vbus_v_convert, vbus_v_raw); @@ -1068,9 +1082,10 @@ static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C); + main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C, + avg_sample, trig_edge, trig_timer, conv_type); main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc, - MAIN_CHARGER_C, main_charger_c_raw); + MAIN_CHARGER_C, main_charger_c_raw); return seq_printf(s, "%d,0x%X\n", main_charger_c_convert, main_charger_c_raw); @@ -1098,9 +1113,10 @@ static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C); + usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C, + avg_sample, trig_edge, trig_timer, conv_type); usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc, - USB_CHARGER_C, usb_charger_c_raw); + USB_CHARGER_C, usb_charger_c_raw); return seq_printf(s, "%d,0x%X\n", usb_charger_c_convert, usb_charger_c_raw); @@ -1128,9 +1144,10 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V); + bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V, + avg_sample, trig_edge, trig_timer, conv_type); bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, - BK_BAT_V, bk_bat_v_raw); + BK_BAT_V, bk_bat_v_raw); return seq_printf(s, "%d,0x%X\n", bk_bat_v_convert, bk_bat_v_raw); @@ -1156,9 +1173,10 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p) struct ab8500_gpadc *gpadc; gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP); + die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP, + avg_sample, trig_edge, trig_timer, conv_type); die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP, - die_temp_raw); + die_temp_raw); return seq_printf(s, "%d,0x%X\n", die_temp_convert, die_temp_raw); @@ -1177,6 +1195,208 @@ static const struct file_operations ab8500_gpadc_die_temp_fops = { .owner = THIS_MODULE, }; +static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p) +{ + return seq_printf(s, "%d\n", avg_sample); +} + +static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_gpadc_avg_sample_print, + inode->i_private); +} + +static ssize_t ab8500_gpadc_avg_sample_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_avg_sample; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_avg_sample); + if (err) + return -EINVAL; + if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4) + || (user_avg_sample == SAMPLE_8) + || (user_avg_sample == SAMPLE_16)) { + avg_sample = (u8) user_avg_sample; + } else { + dev_err(dev, "debugfs error input: " + "should be egal to 1, 4, 8 or 16\n"); + return -EINVAL; + } + return buf_size; +} + +static const struct file_operations ab8500_gpadc_avg_sample_fops = { + .open = ab8500_gpadc_avg_sample_open, + .read = seq_read, + .write = ab8500_gpadc_avg_sample_write, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p) +{ + return seq_printf(s, "%d\n", trig_edge); +} + +static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_gpadc_trig_edge_print, + inode->i_private); +} + +static ssize_t ab8500_gpadc_trig_edge_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_trig_edge; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_trig_edge); + if (err) + return -EINVAL; + if ((user_trig_edge == RISING_EDGE) + || (user_trig_edge == FALLING_EDGE)) { + trig_edge = (u8) user_trig_edge; + } else { + dev_err(dev, "Wrong input:\n" + "Enter 0. Rising edge\n" + "Enter 1. Falling edge\n"); + return -EINVAL; + } + return buf_size; +} + +static const struct file_operations ab8500_gpadc_trig_edge_fops = { + .open = ab8500_gpadc_trig_edge_open, + .read = seq_read, + .write = ab8500_gpadc_trig_edge_write, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p) +{ + return seq_printf(s, "%d\n", trig_timer); +} + +static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_gpadc_trig_timer_print, + inode->i_private); +} + +static ssize_t ab8500_gpadc_trig_timer_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_trig_timer; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_trig_timer); + if (err) + return -EINVAL; + if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) { + trig_timer = (u8) user_trig_timer; + } else { + dev_err(dev, "debugfs error input: " + "should be beetween 0 to 255\n"); + return -EINVAL; + } + return buf_size; +} + +static const struct file_operations ab8500_gpadc_trig_timer_fops = { + .open = ab8500_gpadc_trig_timer_open, + .read = seq_read, + .write = ab8500_gpadc_trig_timer_write, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p) +{ + return seq_printf(s, "%d\n", conv_type); +} + +static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_gpadc_conv_type_print, + inode->i_private); +} + +static ssize_t ab8500_gpadc_conv_type_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_conv_type; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_conv_type); + if (err) + return -EINVAL; + if ((user_conv_type == ADC_SW) + || (user_conv_type == ADC_HW)) { + conv_type = (u8) user_conv_type; + } else { + dev_err(dev, "Wrong input:\n" + "Enter 0. ADC SW conversion\n" + "Enter 1. ADC HW conversion\n"); + return -EINVAL; + } + return buf_size; +} + +static const struct file_operations ab8500_gpadc_conv_type_fops = { + .open = ab8500_gpadc_conv_type_open, + .read = seq_read, + .write = ab8500_gpadc_conv_type_write, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + /* * return length of an ASCII numerical value, 0 is string is not a * numerical value. @@ -1722,6 +1942,26 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; + file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops); + if (!file) + goto err; + + file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops); + if (!file) + goto err; + + file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops); + if (!file) + goto err; + + file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops); + if (!file) + goto err; + return 0; err: diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 7f39479c1afc..8673bf66f7d7 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -55,13 +55,18 @@ #define EN_VTVOUT 0x02 #define EN_GPADC 0x01 #define DIS_GPADC 0x00 -#define SW_AVG_16 0x60 +#define AVG_1 0x00 +#define AVG_4 0x20 +#define AVG_8 0x40 +#define AVG_16 0x60 #define ADC_SW_CONV 0x04 #define EN_ICHAR 0x80 #define BTEMP_PULL_UP 0x08 #define EN_BUF 0x40 #define DIS_ZERO 0x00 #define GPADC_BUSY 0x01 +#define EN_FALLING 0x10 +#define EN_TRIG_EDGE 0x02 /* GPADC constants from AB8500 spec, UM0836 */ #define ADC_RESOLUTION 1024 @@ -116,7 +121,10 @@ struct adc_cal_data { * the completion of gpadc conversion * @ab8500_gpadc_lock: structure of type mutex * @regu: pointer to the struct regulator - * @irq: interrupt number that is used by gpadc + * @irq_sw: interrupt number that is used by gpadc for Sw + * conversion + * @irq_hw: interrupt number that is used by gpadc for Hw + * conversion * @cal_data array of ADC calibration data structs */ struct ab8500_gpadc { @@ -126,7 +134,8 @@ struct ab8500_gpadc { struct completion ab8500_gpadc_complete; struct mutex ab8500_gpadc_lock; struct regulator *regu; - int irq; + int irq_sw; + int irq_hw; struct adc_cal_data cal_data[NBR_CAL_INPUTS]; }; @@ -244,30 +253,35 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage); /** - * ab8500_gpadc_convert() - gpadc conversion + * ab8500_gpadc_sw_hw_convert() - gpadc conversion * @channel: analog channel to be converted to digital data + * @avg_sample: number of ADC sample to average + * @trig_egde: selected ADC trig edge + * @trig_timer: selected ADC trigger delay timer + * @conv_type: selected conversion type (HW or SW conversion) * * This function converts the selected analog i/p to digital * data. */ -int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) +int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) { int ad_value; int voltage; - ad_value = ab8500_gpadc_read_raw(gpadc, channel); - - /* On failure retry a second time */ + ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, + trig_edge, trig_timer, conv_type); +/* On failure retry a second time */ if (ad_value < 0) - ad_value = ab8500_gpadc_read_raw(gpadc, channel); - - if (ad_value < 0) { - dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel); + ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, + trig_edge, trig_timer, conv_type); +if (ad_value < 0) { + dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", + channel); return ad_value; } voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value); - if (voltage < 0) dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" " %d AD: 0x%x\n", channel, ad_value); @@ -279,11 +293,16 @@ EXPORT_SYMBOL(ab8500_gpadc_convert); /** * ab8500_gpadc_read_raw() - gpadc read * @channel: analog channel to be read + * @avg_sample: number of ADC sample to average + * @trig_edge: selected trig edge + * @trig_timer: selected ADC trigger delay timer + * @conv_type: selected conversion type (HW or SW conversion) * - * This function obtains the raw ADC value, this then needs - * to be converted by calling ab8500_gpadc_ad_to_voltage() + * This function obtains the raw ADC value for an hardware conversion, + * this then needs to be converted by calling ab8500_gpadc_ad_to_voltage() */ -int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) +int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) { int ret; int looplimit = 0; @@ -293,7 +312,6 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) return -ENODEV; mutex_lock(&gpadc->ab8500_gpadc_lock); - /* Enable VTVout LDO this is required for GPADC */ pm_runtime_get_sync(gpadc->dev); @@ -321,9 +339,29 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) goto out; } - /* Select the channel source and set average samples to 16 */ - ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16)); + /* Select the channel source and set average samples */ + switch (avg_sample) { + case SAMPLE_1: + val = channel | AVG_1; + break; + case SAMPLE_4: + val = channel | AVG_4; + break; + case SAMPLE_8: + val = channel | AVG_8; + break; + default: + val = channel | AVG_16; + break; + + } + + if (conv_type == ADC_HW) + ret = abx500_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val); + else + ret = abx500_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val); if (ret < 0) { dev_err(gpadc->dev, "gpadc_conversion: set avg samples failed\n"); @@ -335,22 +373,43 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) * charging current sense if it needed, ABB 3.0 needs some special * treatment too. */ + if ((conv_type == ADC_HW) && (trig_edge)) { + ret = abx500_mask_and_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_FALLING, EN_FALLING); + + } switch (channel) { case MAIN_CHARGER_C: case USB_CHARGER_C: - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_ICHAR, - EN_BUF | EN_ICHAR); - break; - case BTEMP_BALL: - if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { - /* Turn on btemp pull-up on ABB 3.0 */ + if (conv_type == ADC_HW) ret = abx500_mask_and_set_register_interruptible( gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | BTEMP_PULL_UP, - EN_BUF | BTEMP_PULL_UP); + EN_BUF | EN_ICHAR | EN_TRIG_EDGE, + EN_BUF | EN_ICHAR | EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | EN_ICHAR, + EN_BUF | EN_ICHAR); + break; + case BTEMP_BALL: + if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { + if (conv_type == ADC_HW) + /* Turn on btemp pull-up on ABB 3.0 */ + ret = abx500_mask_and_set_register_interruptible + (gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE, + EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible + (gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | BTEMP_PULL_UP, + EN_BUF | BTEMP_PULL_UP); /* * Delay might be needed for ABB8500 cut 3.0, if not, remove @@ -361,8 +420,17 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) } /* Intentional fallthrough */ default: - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF); + if (conv_type == ADC_HW) + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | EN_TRIG_EDGE, + EN_BUF | EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, + AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF); break; } if (ret < 0) { @@ -371,36 +439,83 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) goto out; } - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: start s/w conversion failed\n"); - goto out; + /* Set trigger delay timer */ + if (conv_type == ADC_HW) { + ret = abx500_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: trig timer failed\n"); + goto out; + } + } + + /* Start SW conversion */ + if (conv_type == ADC_SW) { + ret = abx500_mask_and_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + ADC_SW_CONV, ADC_SW_CONV); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: start s/w conv failed\n"); + goto out; + } } + /* wait for completion of conversion */ - if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, - msecs_to_jiffies(CONVERSION_TIME))) { - dev_err(gpadc->dev, - "timeout: didn't receive GPADC conversion interrupt\n"); - ret = -EINVAL; - goto out; + if (conv_type == ADC_HW) { + if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, + 2*HZ)) { + dev_err(gpadc->dev, + "timeout didn't receive" + " hw GPADC conv interrupt\n"); + ret = -EINVAL; + goto out; + } + } else { + if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, + msecs_to_jiffies(CONVERSION_TIME))) { + dev_err(gpadc->dev, + "timeout didn't receive" + " sw GPADC conv interrupt\n"); + ret = -EINVAL; + goto out; + } } /* Read the converted RAW data */ - ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_MANDATAL_REG, &low_data); - if (ret < 0) { - dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n"); - goto out; - } + if (conv_type == ADC_HW) { + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_AUTODATAL_REG, &low_data); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read hw low data failed\n"); + goto out; + } - ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, - AB8500_GPADC_MANDATAH_REG, &high_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read high data failed\n"); - goto out; + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_AUTODATAH_REG, &high_data); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read hw high data failed\n"); + goto out; + } + } else { + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_MANDATAL_REG, &low_data); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read sw low data failed\n"); + goto out; + } + + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_MANDATAH_REG, &high_data); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read sw high data failed\n"); + goto out; + } } /* Disable GPADC */ @@ -411,6 +526,7 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) goto out; } + /* Disable VTVout LDO this is required for GPADC */ pm_runtime_mark_last_busy(gpadc->dev); pm_runtime_put_autosuspend(gpadc->dev); @@ -427,9 +543,7 @@ out: */ (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL1_REG, DIS_GPADC); - pm_runtime_put(gpadc->dev); - mutex_unlock(&gpadc->ab8500_gpadc_lock); dev_err(gpadc->dev, "gpadc_conversion: Failed to AD convert channel %d\n", channel); @@ -438,16 +552,16 @@ out: EXPORT_SYMBOL(ab8500_gpadc_read_raw); /** - * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion + * ab8500_bm_gpadcconvend_handler() - isr for gpadc conversion completion * @irq: irq number * @data: pointer to the data passed during request irq * - * This is a interrupt service routine for s/w gpadc conversion completion. + * This is a interrupt service routine for gpadc conversion completion. * Notifies the gpadc completion is completed and the converted raw value * can be read from the registers. * Returns IRQ status(IRQ_HANDLED) */ -static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc) +static irqreturn_t ab8500_bm_gpadcconvend_handler(int irq, void *_gpadc) { struct ab8500_gpadc *gpadc = _gpadc; @@ -646,11 +760,19 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) return -ENOMEM; } - gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); - if (gpadc->irq < 0) { - dev_err(&pdev->dev, "failed to get platform irq-%d\n", - gpadc->irq); - ret = gpadc->irq; + gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); + if (gpadc->irq_sw < 0) { + dev_err(gpadc->dev, "failed to get platform irq-%d\n", + gpadc->irq_sw); + ret = gpadc->irq_sw; + goto fail; + } + + gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); + if (gpadc->irq_hw < 0) { + dev_err(gpadc->dev, "failed to get platform irq-%d\n", + gpadc->irq_hw); + ret = gpadc->irq_hw; goto fail; } @@ -661,14 +783,21 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) /* Initialize completion used to notify completion of conversion */ init_completion(&gpadc->ab8500_gpadc_complete); - /* Register interrupt - SwAdcComplete */ - ret = request_threaded_irq(gpadc->irq, NULL, - ab8500_bm_gpswadcconvend_handler, - IRQF_ONESHOT | IRQF_NO_SUSPEND | IRQF_SHARED, - "ab8500-gpadc", gpadc); + /* Register interrupts */ + ret = request_threaded_irq(gpadc->irq_sw, NULL, + ab8500_bm_gpadcconvend_handler, + IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", gpadc); + if (ret < 0) { + dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", + gpadc->irq_sw); + goto fail; + } + ret = request_threaded_irq(gpadc->irq_hw, NULL, + ab8500_bm_gpadcconvend_handler, + IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", gpadc); if (ret < 0) { dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", - gpadc->irq); + gpadc->irq_hw); goto fail; } @@ -694,7 +823,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) dev_dbg(gpadc->dev, "probe success\n"); return 0; fail_irq: - free_irq(gpadc->irq, gpadc); + free_irq(gpadc->irq_sw, gpadc); + free_irq(gpadc->irq_hw, gpadc); fail: kfree(gpadc); gpadc = NULL; @@ -708,7 +838,8 @@ static int ab8500_gpadc_remove(struct platform_device *pdev) /* remove this gpadc entry from the list */ list_del(&gpadc->node); /* remove interrupt - completion of Sw ADC conversion */ - free_irq(gpadc->irq, gpadc); + free_irq(gpadc->irq_sw, gpadc); + free_irq(gpadc->irq_hw, gpadc); pm_runtime_get_sync(gpadc->dev); pm_runtime_disable(gpadc->dev); @@ -757,6 +888,7 @@ subsys_initcall_sync(ab8500_gpadc_init); module_exit(ab8500_gpadc_exit); MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson"); +MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson," + "M'boumba Cedric Madianga"); MODULE_ALIAS("platform:ab8500_gpadc"); MODULE_DESCRIPTION("AB8500 GPADC driver"); diff --git a/include/linux/mfd/abx500/ab8500-gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h index 252966769d93..7694e7ab1880 100644 --- a/include/linux/mfd/abx500/ab8500-gpadc.h +++ b/include/linux/mfd/abx500/ab8500-gpadc.h @@ -4,12 +4,14 @@ * * Author: Arun R Murthy * Author: Daniel Willerud + * Author: M'boumba Cedric Madianga */ #ifndef _AB8500_GPADC_H #define _AB8500_GPADC_H -/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */ +/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2 + * and ADCHwSel[4:0] in GPADCCtrl3 ) */ #define BAT_CTRL 0x01 #define BTEMP_BALL 0x02 #define MAIN_CHARGER_V 0x03 @@ -24,12 +26,32 @@ #define BK_BAT_V 0x0C #define DIE_TEMP 0x0D +#define SAMPLE_1 1 +#define SAMPLE_4 4 +#define SAMPLE_8 8 +#define SAMPLE_16 16 +#define RISING_EDGE 0 +#define FALLING_EDGE 1 + +/* Arbitrary ADC conversion type constants */ +#define ADC_SW 0 +#define ADC_HW 1 + + struct ab8500_gpadc; struct ab8500_gpadc *ab8500_gpadc_get(char *name); -int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel); -int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel); +int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type); +static inline int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) +{ + return ab8500_gpadc_sw_hw_convert(gpadc, channel, + SAMPLE_16, 0, 0, ADC_SW); +} + +int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type); int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, - u8 channel, int ad_value); + u8 channel, int ad_value); #endif /* _AB8500_GPADC_H */ -- cgit From a29264b68a93556a09005b9f18cbd3f61f6fd355 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:34:26 +0000 Subject: mfd: ab8500-core: APE Interrupts are not cleared There are missing register descriptions from the AB8505 user manual and these need to be masked so that the APEINT line can toggle. This patch also affects the behaviour of AB9540. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Maxime COQUELIN Reviewed-by: Alexandre TORGUE Reviewed-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 50e6f1e29727..baaf2ed8095b 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -95,6 +95,7 @@ #define AB8500_IT_MASK22_REG 0x55 #define AB8500_IT_MASK23_REG 0x56 #define AB8500_IT_MASK24_REG 0x57 +#define AB8500_IT_MASK25_REG 0x58 /* * latch hierarchy registers @@ -137,9 +138,9 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, }; -/* AB9540 support */ +/* AB9540 / AB8505 support */ static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, + 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23 }; static const char ab8500_version_str[][7] = { -- cgit From cfc0849c66099dc62ed6d879d8128977bd087aa7 Mon Sep 17 00:00:00 2001 From: Mattias Wallin Date: Mon, 28 May 2012 15:53:58 +0200 Subject: mfd: ab8500-debug: Print banks in hex This patch changes bank prints to use hex value. Signed-off-by: Mattias Wallin Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Daniel WILLERUD Tested-by: Jonas ABERG Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 59ecd8c680ed..75366b55f16c 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -525,19 +525,19 @@ static int ab8500_registers_print(struct device *dev, u32 bank, } if (s) { - err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", + err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value); if (err < 0) { dev_err(dev, - "seq_printf overflow bank=%d reg=%d\n", + "seq_printf overflow bank=0x%02X reg=0x%02X\n", bank, reg); /* Error is not returned here since * the output is wanted in any case */ return 0; } } else { - printk(KERN_INFO" [%u/0x%02X]: 0x%02X\n", bank, - reg, value); + printk(KERN_INFO" [0x%02X/0x%02X]: 0x%02X\n", + bank, reg, value); } } } @@ -551,7 +551,7 @@ static int ab8500_print_bank_registers(struct seq_file *s, void *p) seq_printf(s, AB8500_NAME_STRING " register values:\n"); - seq_printf(s, " bank %u:\n", bank); + seq_printf(s, " bank 0x%02X:\n", bank); ab8500_registers_print(dev, bank, s); return 0; @@ -579,9 +579,9 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p) seq_printf(s, AB8500_NAME_STRING " register values:\n"); for (i = 1; i < AB8500_NUM_BANKS; i++) { - err = seq_printf(s, " bank %u:\n", i); + err = seq_printf(s, " bank 0x%02X:\n", i); if (err < 0) - dev_err(dev, "seq_printf overflow, bank=%d\n", i); + dev_err(dev, "seq_printf overflow, bank=0x%02X\n", i); ab8500_registers_print(dev, i, s); } @@ -596,7 +596,7 @@ void ab8500_dump_all_banks(struct device *dev) printk(KERN_INFO"ab8500 register values:\n"); for (i = 1; i < AB8500_NUM_BANKS; i++) { - printk(KERN_INFO" bank %u:\n", i); + printk(KERN_INFO" bank 0x%02X:\n", i); ab8500_registers_print(dev, i, NULL); } } @@ -630,7 +630,7 @@ static const struct file_operations ab8500_all_banks_fops = { static int ab8500_bank_print(struct seq_file *s, void *p) { - return seq_printf(s, "%d\n", debug_bank); + return seq_printf(s, "0x%02X\n", debug_bank); } static int ab8500_bank_open(struct inode *inode, struct file *file) -- cgit From a72149e82b65b76d2dae5428a6b211eb43933529 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 26 Feb 2013 11:34:07 +0900 Subject: pinctrl: core: use devres_release() instead of devres_destroy() devres_release() can simplify the code, because devres_release() will call the destructor for the resource as well as freeing the devres data. Signed-off-by: Jingoo Han Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index b0de6e7f1fdb..e2d214c5c58f 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -979,9 +979,8 @@ static int devm_pinctrl_match(struct device *dev, void *res, void *data) */ void devm_pinctrl_put(struct pinctrl *p) { - WARN_ON(devres_destroy(p->dev, devm_pinctrl_release, + WARN_ON(devres_release(p->dev, devm_pinctrl_release, devm_pinctrl_match, p)); - pinctrl_put(p); } EXPORT_SYMBOL_GPL(devm_pinctrl_put); -- cgit From 022ab148d28e8466e45d28552224e3029f1cccd8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 16 Feb 2013 10:25:07 +0100 Subject: pinctrl: Declare operation structures as const The pinconf, pinctrl and pinmux operation structures hold function pointers that are never modified. Declare them as const. Signed-off-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/devicetree.c | 4 ++-- drivers/pinctrl/mvebu/pinctrl-mvebu.c | 6 +++--- drivers/pinctrl/pinconf.c | 2 +- drivers/pinctrl/pinctrl-abx500.c | 6 +++--- drivers/pinctrl/pinctrl-at91.c | 6 +++--- drivers/pinctrl/pinctrl-bcm2835.c | 6 +++--- drivers/pinctrl/pinctrl-exynos5440.c | 6 +++--- drivers/pinctrl/pinctrl-falcon.c | 2 +- drivers/pinctrl/pinctrl-imx.c | 6 +++--- drivers/pinctrl/pinctrl-lantiq.c | 4 ++-- drivers/pinctrl/pinctrl-mxs.c | 6 +++--- drivers/pinctrl/pinctrl-nomadik.c | 6 +++--- drivers/pinctrl/pinctrl-pxa3xx.c | 4 ++-- drivers/pinctrl/pinctrl-samsung.c | 6 +++--- drivers/pinctrl/pinctrl-single.c | 6 +++--- drivers/pinctrl/pinctrl-sirf.c | 4 ++-- drivers/pinctrl/pinctrl-sunxi.c | 6 +++--- drivers/pinctrl/pinctrl-tegra.c | 6 +++--- drivers/pinctrl/pinctrl-u300.c | 6 +++--- drivers/pinctrl/pinctrl-xway.c | 2 +- drivers/pinctrl/spear/pinctrl-spear.c | 4 ++-- include/linux/pinctrl/pinctrl.h | 6 +++--- 22 files changed, 55 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index fd40a11ad645..c7b7cb477129 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -41,7 +41,7 @@ static void dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { if (pctldev) { - struct pinctrl_ops *ops = pctldev->desc->pctlops; + const struct pinctrl_ops *ops = pctldev->desc->pctlops; ops->dt_free_map(pctldev, map, num_maps); } else { /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ @@ -122,7 +122,7 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename, { struct device_node *np_pctldev; struct pinctrl_dev *pctldev; - struct pinctrl_ops *ops; + const struct pinctrl_ops *ops; int ret; struct pinctrl_map *map; unsigned num_maps; diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index c689c04a4f52..61149914882d 100644 --- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -263,7 +263,7 @@ static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, return; } -static struct pinconf_ops mvebu_pinconf_ops = { +static const struct pinconf_ops mvebu_pinconf_ops = { .pin_config_group_get = mvebu_pinconf_group_get, .pin_config_group_set = mvebu_pinconf_group_set, .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show, @@ -369,7 +369,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, return -ENOTSUPP; } -static struct pinmux_ops mvebu_pinmux_ops = { +static const struct pinmux_ops mvebu_pinmux_ops = { .get_functions_count = mvebu_pinmux_get_funcs_count, .get_function_name = mvebu_pinmux_get_func_name, .get_function_groups = mvebu_pinmux_get_groups, @@ -470,7 +470,7 @@ static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops mvebu_pinctrl_ops = { +static const struct pinctrl_ops mvebu_pinctrl_ops = { .get_groups_count = mvebu_pinctrl_get_groups_count, .get_group_name = mvebu_pinctrl_get_group_name, .get_group_pins = mvebu_pinctrl_get_group_pins, diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index ac8d382a79bb..8aefd28c797e 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -670,7 +670,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d) struct pinctrl_maps *maps_node; struct pinctrl_map const *map; struct pinctrl_dev *pctldev = NULL; - struct pinconf_ops *confops = NULL; + const struct pinconf_ops *confops = NULL; int i, j; bool found = false; diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index caecdd373061..169d72c59a7b 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -656,7 +656,7 @@ static void abx500_gpio_disable_free(struct pinctrl_dev *pctldev, { } -static struct pinmux_ops abx500_pinmux_ops = { +static const struct pinmux_ops abx500_pinmux_ops = { .get_functions_count = abx500_pmx_get_funcs_cnt, .get_function_name = abx500_pmx_get_func_name, .get_function_groups = abx500_pmx_get_func_groups, @@ -704,7 +704,7 @@ static void abx500_pin_dbg_show(struct pinctrl_dev *pctldev, chip->base + offset - 1); } -static struct pinctrl_ops abx500_pinctrl_ops = { +static const struct pinctrl_ops abx500_pinctrl_ops = { .get_groups_count = abx500_get_groups_cnt, .get_group_name = abx500_get_group_name, .get_group_pins = abx500_get_group_pins, @@ -778,7 +778,7 @@ int abx500_pin_config_set(struct pinctrl_dev *pctldev, return ret; } -static struct pinconf_ops abx500_pinconf_ops = { +static const struct pinconf_ops abx500_pinconf_ops = { .pin_config_get = abx500_pin_config_get, .pin_config_set = abx500_pin_config_set, }; diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 75933a6aa828..e50fa5f863e1 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -294,7 +294,7 @@ static void at91_dt_free_map(struct pinctrl_dev *pctldev, { } -static struct pinctrl_ops at91_pctrl_ops = { +static const struct pinctrl_ops at91_pctrl_ops = { .get_groups_count = at91_get_groups_count, .get_group_name = at91_get_group_name, .get_group_pins = at91_get_group_pins, @@ -696,7 +696,7 @@ static void at91_gpio_disable_free(struct pinctrl_dev *pctldev, /* Set the pin to some default state, GPIO is usually default */ } -static struct pinmux_ops at91_pmx_ops = { +static const struct pinmux_ops at91_pmx_ops = { .get_functions_count = at91_pmx_get_funcs_count, .get_function_name = at91_pmx_get_func_name, .get_function_groups = at91_pmx_get_groups, @@ -776,7 +776,7 @@ static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } -static struct pinconf_ops at91_pinconf_ops = { +static const struct pinconf_ops at91_pinconf_ops = { .pin_config_get = at91_pinconf_get, .pin_config_set = at91_pinconf_set, .pin_config_dbg_show = at91_pinconf_dbg_show, diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index 4eb6d2c4e4df..f28d4b08771a 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c @@ -795,7 +795,7 @@ out: return err; } -static struct pinctrl_ops bcm2835_pctl_ops = { +static const struct pinctrl_ops bcm2835_pctl_ops = { .get_groups_count = bcm2835_pctl_get_groups_count, .get_group_name = bcm2835_pctl_get_group_name, .get_group_pins = bcm2835_pctl_get_group_pins, @@ -872,7 +872,7 @@ static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, return 0; } -static struct pinmux_ops bcm2835_pmx_ops = { +static const struct pinmux_ops bcm2835_pmx_ops = { .get_functions_count = bcm2835_pmx_get_functions_count, .get_function_name = bcm2835_pmx_get_function_name, .get_function_groups = bcm2835_pmx_get_function_groups, @@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -static struct pinconf_ops bcm2835_pinconf_ops = { +static const struct pinconf_ops bcm2835_pinconf_ops = { .pin_config_get = bcm2835_pinconf_get, .pin_config_set = bcm2835_pinconf_set, }; diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c index 1376eb7305db..169ea3e5f777 100644 --- a/drivers/pinctrl/pinctrl-exynos5440.c +++ b/drivers/pinctrl/pinctrl-exynos5440.c @@ -286,7 +286,7 @@ static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev, } /* list of pinctrl callbacks for the pinctrl core */ -static struct pinctrl_ops exynos5440_pctrl_ops = { +static const struct pinctrl_ops exynos5440_pctrl_ops = { .get_groups_count = exynos5440_get_group_count, .get_group_name = exynos5440_get_group_name, .get_group_pins = exynos5440_get_group_pins, @@ -374,7 +374,7 @@ static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, } /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ -static struct pinmux_ops exynos5440_pinmux_ops = { +static const struct pinmux_ops exynos5440_pinmux_ops = { .get_functions_count = exynos5440_get_functions_count, .get_function_name = exynos5440_pinmux_get_fname, .get_function_groups = exynos5440_pinmux_get_groups, @@ -523,7 +523,7 @@ static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev, } /* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */ -static struct pinconf_ops exynos5440_pinconf_ops = { +static const struct pinconf_ops exynos5440_pinconf_ops = { .pin_config_get = exynos5440_pinconf_get, .pin_config_set = exynos5440_pinconf_set, .pin_config_group_get = exynos5440_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c index af97a1f90007..f9b2a1d4854f 100644 --- a/drivers/pinctrl/pinctrl-falcon.c +++ b/drivers/pinctrl/pinctrl-falcon.c @@ -353,7 +353,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, { } -static struct pinconf_ops falcon_pinconf_ops = { +static const struct pinconf_ops falcon_pinconf_ops = { .pin_config_get = falcon_pinconf_get, .pin_config_set = falcon_pinconf_set, .pin_config_group_get = falcon_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 4cebb9c6c5c5..0ef190449eab 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -207,7 +207,7 @@ static void imx_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops imx_pctrl_ops = { +static const struct pinctrl_ops imx_pctrl_ops = { .get_groups_count = imx_get_groups_count, .get_group_name = imx_get_group_name, .get_group_pins = imx_get_group_pins, @@ -299,7 +299,7 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static struct pinmux_ops imx_pmx_ops = { +static const struct pinmux_ops imx_pmx_ops = { .get_functions_count = imx_pmx_get_funcs_count, .get_function_name = imx_pmx_get_func_name, .get_function_groups = imx_pmx_get_groups, @@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, } } -static struct pinconf_ops imx_pinconf_ops = { +static const struct pinconf_ops imx_pinconf_ops = { .pin_config_get = imx_pinconf_get, .pin_config_set = imx_pinconf_set, .pin_config_dbg_show = imx_pinconf_dbg_show, diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index a70384611351..615c5002b757 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c @@ -169,7 +169,7 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static struct pinctrl_ops ltq_pctrl_ops = { +static const struct pinctrl_ops ltq_pctrl_ops = { .get_groups_count = ltq_get_group_count, .get_group_name = ltq_get_group_name, .get_group_pins = ltq_get_group_pins, @@ -311,7 +311,7 @@ static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, return info->apply_mux(pctrldev, mfp, pin_func); } -static struct pinmux_ops ltq_pmx_ops = { +static const struct pinmux_ops ltq_pmx_ops = { .get_functions_count = ltq_pmx_func_count, .get_function_name = ltq_pmx_func_name, .get_function_groups = ltq_pmx_get_groups, diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 23af9f1f9c35..b45c4eb35798 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -158,7 +158,7 @@ static void mxs_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops mxs_pinctrl_ops = { +static const struct pinctrl_ops mxs_pinctrl_ops = { .get_groups_count = mxs_get_groups_count, .get_group_name = mxs_get_group_name, .get_group_pins = mxs_get_group_pins, @@ -219,7 +219,7 @@ static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static struct pinmux_ops mxs_pinmux_ops = { +static const struct pinmux_ops mxs_pinmux_ops = { .get_functions_count = mxs_pinctrl_get_funcs_count, .get_function_name = mxs_pinctrl_get_func_name, .get_function_groups = mxs_pinctrl_get_func_groups, @@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, "0x%lx", config); } -static struct pinconf_ops mxs_pinconf_ops = { +static const struct pinconf_ops mxs_pinconf_ops = { .pin_config_get = mxs_pinconf_get, .pin_config_set = mxs_pinconf_set, .pin_config_group_get = mxs_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 36d20293de5c..2328baaa86bf 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1764,7 +1764,7 @@ int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static struct pinctrl_ops nmk_pinctrl_ops = { +static const struct pinctrl_ops nmk_pinctrl_ops = { .get_groups_count = nmk_get_groups_cnt, .get_group_name = nmk_get_group_name, .get_group_pins = nmk_get_group_pins, @@ -1975,7 +1975,7 @@ static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, /* Set the pin to some default state, GPIO is usually default */ } -static struct pinmux_ops nmk_pinmux_ops = { +static const struct pinmux_ops nmk_pinmux_ops = { .get_functions_count = nmk_pmx_get_funcs_cnt, .get_function_name = nmk_pmx_get_func_name, .get_function_groups = nmk_pmx_get_func_groups, @@ -2089,7 +2089,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, return 0; } -static struct pinconf_ops nmk_pinconf_ops = { +static const struct pinconf_ops nmk_pinconf_ops = { .pin_config_get = nmk_pin_config_get, .pin_config_set = nmk_pin_config_set, }; diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c index 1f49bb02a6af..05e11de1d144 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -53,7 +53,7 @@ static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } -static struct pinctrl_ops pxa3xx_pctrl_ops = { +static const struct pinctrl_ops pxa3xx_pctrl_ops = { .get_groups_count = pxa3xx_get_groups_count, .get_group_name = pxa3xx_get_group_name, .get_group_pins = pxa3xx_get_group_pins, @@ -161,7 +161,7 @@ static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, return 0; } -static struct pinmux_ops pxa3xx_pmx_ops = { +static const struct pinmux_ops pxa3xx_pmx_ops = { .get_functions_count = pxa3xx_pmx_get_funcs_count, .get_function_name = pxa3xx_pmx_get_func_name, .get_function_groups = pxa3xx_pmx_get_groups, diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index f206df175656..3475b92b24a4 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -214,7 +214,7 @@ static void samsung_dt_free_map(struct pinctrl_dev *pctldev, } /* list of pinctrl callbacks for the pinctrl core */ -static struct pinctrl_ops samsung_pctrl_ops = { +static const struct pinctrl_ops samsung_pctrl_ops = { .get_groups_count = samsung_get_group_count, .get_group_name = samsung_get_group_name, .get_group_pins = samsung_get_group_pins, @@ -357,7 +357,7 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, } /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ -static struct pinmux_ops samsung_pinmux_ops = { +static const struct pinmux_ops samsung_pinmux_ops = { .get_functions_count = samsung_get_functions_count, .get_function_name = samsung_pinmux_get_fname, .get_function_groups = samsung_pinmux_get_groups, @@ -468,7 +468,7 @@ static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev, } /* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */ -static struct pinconf_ops samsung_pinconf_ops = { +static const struct pinconf_ops samsung_pinconf_ops = { .pin_config_get = samsung_pinconf_get, .pin_config_set = samsung_pinconf_set, .pin_config_group_get = samsung_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 5c32e880bcb2..0c0e2da9d880 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -270,7 +270,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, struct pinctrl_map **map, unsigned *num_maps); -static struct pinctrl_ops pcs_pinctrl_ops = { +static const struct pinctrl_ops pcs_pinctrl_ops = { .get_groups_count = pcs_get_groups_count, .get_group_name = pcs_get_group_name, .get_group_pins = pcs_get_group_pins, @@ -408,7 +408,7 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev, return -ENOTSUPP; } -static struct pinmux_ops pcs_pinmux_ops = { +static const struct pinmux_ops pcs_pinmux_ops = { .get_functions_count = pcs_get_functions_count, .get_function_name = pcs_get_function_name, .get_function_groups = pcs_get_function_groups, @@ -451,7 +451,7 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } -static struct pinconf_ops pcs_pinconf_ops = { +static const struct pinconf_ops pcs_pinconf_ops = { .pin_config_get = pcs_pinconf_get, .pin_config_set = pcs_pinconf_set, .pin_config_group_get = pcs_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index d02498b30c6e..0990a721758e 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -979,7 +979,7 @@ static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops sirfsoc_pctrl_ops = { +static const struct pinctrl_ops sirfsoc_pctrl_ops = { .get_groups_count = sirfsoc_get_groups_count, .get_group_name = sirfsoc_get_group_name, .get_group_pins = sirfsoc_get_group_pins, @@ -1181,7 +1181,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, return 0; } -static struct pinmux_ops sirfsoc_pinmux_ops = { +static const struct pinmux_ops sirfsoc_pinmux_ops = { .enable = sirfsoc_pinmux_enable, .disable = sirfsoc_pinmux_disable, .get_functions_count = sirfsoc_pinmux_get_funcs_count, diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index 80b11e3415bc..46b8f2d4f0a5 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c @@ -1029,7 +1029,7 @@ static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops sunxi_pctrl_ops = { +static const struct pinctrl_ops sunxi_pctrl_ops = { .dt_node_to_map = sunxi_pctrl_dt_node_to_map, .dt_free_map = sunxi_pctrl_dt_free_map, .get_groups_count = sunxi_pctrl_get_groups_count, @@ -1098,7 +1098,7 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, return 0; } -static struct pinconf_ops sunxi_pconf_ops = { +static const struct pinconf_ops sunxi_pconf_ops = { .pin_config_group_get = sunxi_pconf_group_get, .pin_config_group_set = sunxi_pconf_group_set, }; @@ -1204,7 +1204,7 @@ error: return ret; } -static struct pinmux_ops sunxi_pmx_ops = { +static const struct pinmux_ops sunxi_pmx_ops = { .get_functions_count = sunxi_pmx_get_funcs_cnt, .get_function_name = sunxi_pmx_get_func_name, .get_function_groups = sunxi_pmx_get_func_groups, diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index f195d77a3572..2fa9bc6cd7ab 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -316,7 +316,7 @@ static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -static struct pinctrl_ops tegra_pinctrl_ops = { +static const struct pinctrl_ops tegra_pinctrl_ops = { .get_groups_count = tegra_pinctrl_get_groups_count, .get_group_name = tegra_pinctrl_get_group_name, .get_group_pins = tegra_pinctrl_get_group_pins, @@ -401,7 +401,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, pmx_writel(pmx, val, g->mux_bank, g->mux_reg); } -static struct pinmux_ops tegra_pinmux_ops = { +static const struct pinmux_ops tegra_pinmux_ops = { .get_functions_count = tegra_pinctrl_get_funcs_count, .get_function_name = tegra_pinctrl_get_func_name, .get_function_groups = tegra_pinctrl_get_func_groups, @@ -676,7 +676,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, } #endif -static struct pinconf_ops tegra_pinconf_ops = { +static const struct pinconf_ops tegra_pinconf_ops = { .pin_config_get = tegra_pinconf_get, .pin_config_set = tegra_pinconf_set, .pin_config_group_get = tegra_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 2b5772550836..6a3a7503e6a0 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -860,7 +860,7 @@ static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, seq_printf(s, " " DRIVER_NAME); } -static struct pinctrl_ops u300_pctrl_ops = { +static const struct pinctrl_ops u300_pctrl_ops = { .get_groups_count = u300_get_groups_count, .get_group_name = u300_get_group_name, .get_group_pins = u300_get_group_pins, @@ -1003,7 +1003,7 @@ static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static struct pinmux_ops u300_pmx_ops = { +static const struct pinmux_ops u300_pmx_ops = { .get_functions_count = u300_pmx_get_funcs_count, .get_function_name = u300_pmx_get_func_name, .get_function_groups = u300_pmx_get_groups, @@ -1046,7 +1046,7 @@ static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, return 0; } -static struct pinconf_ops u300_pconf_ops = { +static const struct pinconf_ops u300_pconf_ops = { .is_generic = true, .pin_config_get = u300_pin_config_get, .pin_config_set = u300_pin_config_set, diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index 068224efa6fa..f2977cff8366 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -553,7 +553,7 @@ int xway_pinconf_group_set(struct pinctrl_dev *pctldev, return ret; } -static struct pinconf_ops xway_pinconf_ops = { +static const struct pinconf_ops xway_pinconf_ops = { .pin_config_get = xway_pinconf_get, .pin_config_set = xway_pinconf_set, .pin_config_group_set = xway_pinconf_group_set, diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 6a7dae70db08..116da0412c4b 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -198,7 +198,7 @@ static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, kfree(map); } -static struct pinctrl_ops spear_pinctrl_ops = { +static const struct pinctrl_ops spear_pinctrl_ops = { .get_groups_count = spear_pinctrl_get_groups_cnt, .get_group_name = spear_pinctrl_get_group_name, .get_group_pins = spear_pinctrl_get_group_pins, @@ -340,7 +340,7 @@ static void gpio_disable_free(struct pinctrl_dev *pctldev, gpio_request_endisable(pctldev, range, offset, false); } -static struct pinmux_ops spear_pinmux_ops = { +static const struct pinmux_ops spear_pinmux_ops = { .get_functions_count = spear_pinctrl_get_funcs_count, .get_function_name = spear_pinctrl_get_func_name, .get_function_groups = spear_pinctrl_get_func_groups, diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 778804df293f..2c2a9e8d8578 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -118,9 +118,9 @@ struct pinctrl_desc { const char *name; struct pinctrl_pin_desc const *pins; unsigned int npins; - struct pinctrl_ops *pctlops; - struct pinmux_ops *pmxops; - struct pinconf_ops *confops; + const struct pinctrl_ops *pctlops; + const struct pinmux_ops *pmxops; + const struct pinconf_ops *confops; struct module *owner; }; -- cgit From e3929714942b242ecb55657e70d51e0eb4c77726 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 17 Feb 2013 21:58:47 +0800 Subject: pinctrl: abx500: Add terminating entry for of_device_id table The of_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-abx500.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index 169d72c59a7b..e8abc3cf3033 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -834,6 +834,7 @@ static const struct of_device_id abx500_gpio_match[] = { { .compatible = "stericsson,ab8505-gpio", .data = (void *)PINCTRL_AB8505, }, { .compatible = "stericsson,ab8540-gpio", .data = (void *)PINCTRL_AB8540, }, { .compatible = "stericsson,ab9540-gpio", .data = (void *)PINCTRL_AB9540, }, + { } }; static int abx500_gpio_probe(struct platform_device *pdev) -- cgit From 86853c83e33738397564e9377ceeff94d4bc041c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:47 +0800 Subject: gpio: add gpio offset in gpio range cells property Add gpio offset into "gpio-range-cells" property. It's used to support sparse pinctrl range in gpio chip. Signed-off-by: Haojian Zhuang Acked-by: Viresh Kumar Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/gpio.txt | 6 +++--- arch/arm/boot/dts/spear1310.dtsi | 4 ++-- arch/arm/boot/dts/spear1340.dtsi | 4 ++-- arch/arm/boot/dts/spear310.dtsi | 4 ++-- arch/arm/boot/dts/spear320.dtsi | 4 ++-- drivers/gpio/gpiolib-of.c | 15 ++------------- 6 files changed, 13 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index a33628759d36..d933af370697 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt @@ -98,7 +98,7 @@ announce the pinrange to the pin ctrl subsystem. For example, compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; reg = <0x1460 0x18>; gpio-controller; - gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>; + gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>; } @@ -107,8 +107,8 @@ where, Next values specify the base pin and number of pins for the range handled by 'qe_pio_e' gpio. In the given example from base pin 20 to - pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled - by this gpio controller. + pin 29 under pinctrl1 with gpio offset 0 and pin 50 to pin 69 under + pinctrl2 with gpio offset 10 is handled by this gpio controller. The pinctrl node must have "#gpio-range-cells" property to show number of arguments to pass with phandle from gpio controllers node. diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 1513c1927cc8..122ae94076c8 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -89,7 +89,7 @@ pinmux: pinmux@e0700000 { compatible = "st,spear1310-pinmux"; reg = <0xe0700000 0x1000>; - #gpio-range-cells = <2>; + #gpio-range-cells = <3>; }; apb { @@ -212,7 +212,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 246>; + gpio-ranges = <&pinmux 0 0 246>; status = "disabled"; st-plgpio,ngpio = <246>; diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index 34da11aa6795..c511c4772efd 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -63,7 +63,7 @@ pinmux: pinmux@e0700000 { compatible = "st,spear1340-pinmux"; reg = <0xe0700000 0x1000>; - #gpio-range-cells = <2>; + #gpio-range-cells = <3>; }; pwm: pwm@e0180000 { @@ -127,7 +127,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 252>; + gpio-ranges = <&pinmux 0 0 252>; status = "disabled"; st-plgpio,ngpio = <250>; diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index ab45b8c81982..95372080eea6 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi @@ -25,7 +25,7 @@ pinmux: pinmux@b4000000 { compatible = "st,spear310-pinmux"; reg = <0xb4000000 0x1000>; - #gpio-range-cells = <2>; + #gpio-range-cells = <3>; }; fsmc: flash@44000000 { @@ -102,7 +102,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 102>; + gpio-ranges = <&pinmux 0 0 102>; status = "disabled"; st-plgpio,ngpio = <102>; diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index caa5520b1fd4..ffea342aeec9 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi @@ -24,7 +24,7 @@ pinmux: pinmux@b3000000 { compatible = "st,spear320-pinmux"; reg = <0xb3000000 0x1000>; - #gpio-range-cells = <2>; + #gpio-range-cells = <3>; }; clcd@90000000 { @@ -130,7 +130,7 @@ interrupt-controller; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pinmux 0 102>; + gpio-ranges = <&pinmux 0 0 102>; status = "disabled"; st-plgpio,ngpio = <102>; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a71a54a3e3f7..892040ad0095 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -203,22 +203,11 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!pctldev) break; - /* - * This assumes that the n GPIO pins are consecutive in the - * GPIO number space, and that the pins are also consecutive - * in their local number space. Currently it is not possible - * to add different ranges for one and the same GPIO chip, - * as the code assumes that we have one consecutive range - * on both, mapping 1-to-1. - * - * TODO: make the OF bindings handle multiple sparse ranges - * on the same GPIO chip. - */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_devname(pctldev), - 0, /* offset in gpiochip */ pinspec.args[0], - pinspec.args[1]); + pinspec.args[1], + pinspec.args[2]); if (ret) break; -- cgit From f1f70479e999217ecbf619d71837fc5d77c680fb Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:49 +0800 Subject: gpio: pl061: support irqdomain Drop the support of irq generic chip. Now support irqdomain instead. Although set_wake() is defined in irq generic chip & it is not really used in pl061 gpio driver. Drop it at the same time. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 104 +++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b820869ca93c..d1d603585a93 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -51,8 +52,7 @@ struct pl061_gpio { spinlock_t lock; void __iomem *base; - int irq_base; - struct irq_chip_generic *irq_gc; + struct irq_domain *domain; struct gpio_chip gc; #ifdef CONFIG_PM @@ -122,24 +122,20 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - if (chip->irq_base <= 0) - return -EINVAL; - - return chip->irq_base + offset; + return irq_create_mapping(chip->domain, offset); } static int pl061_irq_type(struct irq_data *d, unsigned trigger) { - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct pl061_gpio *chip = gc->private; - int offset = d->irq - chip->irq_base; + struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); + int offset = irqd_to_hwirq(d); unsigned long flags; u8 gpiois, gpioibe, gpioiev; if (offset < 0 || offset >= PL061_GPIO_NR) return -EINVAL; - raw_spin_lock_irqsave(&gc->lock, flags); + spin_lock_irqsave(&chip->lock, flags); gpioiev = readb(chip->base + GPIOIEV); @@ -168,7 +164,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger) writeb(gpioiev, chip->base + GPIOIEV); - raw_spin_unlock_irqrestore(&gc->lock, flags); + spin_unlock_irqrestore(&chip->lock, flags); return 0; } @@ -192,31 +188,61 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) chained_irq_exit(irqchip, desc); } -static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) +static void pl061_irq_mask(struct irq_data *d) { - struct irq_chip_type *ct; + struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); + u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); + u8 gpioie; + + spin_lock(&chip->lock); + gpioie = readb(chip->base + GPIOIE) & ~mask; + writeb(gpioie, chip->base + GPIOIE); + spin_unlock(&chip->lock); +} - chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base, - chip->base, handle_simple_irq); - chip->irq_gc->private = chip; +static void pl061_irq_unmask(struct irq_data *d) +{ + struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); + u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); + u8 gpioie; + + spin_lock(&chip->lock); + gpioie = readb(chip->base + GPIOIE) | mask; + writeb(gpioie, chip->base + GPIOIE); + spin_unlock(&chip->lock); +} + +static struct irq_chip pl061_irqchip = { + .name = "pl061 gpio", + .irq_mask = pl061_irq_mask, + .irq_unmask = pl061_irq_unmask, + .irq_set_type = pl061_irq_type, +}; + +static int pl061_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + struct pl061_gpio *chip = d->host_data; - ct = chip->irq_gc->chip_types; - ct->chip.irq_mask = irq_gc_mask_clr_bit; - ct->chip.irq_unmask = irq_gc_mask_set_bit; - ct->chip.irq_set_type = pl061_irq_type; - ct->chip.irq_set_wake = irq_gc_set_wake; - ct->regs.mask = GPIOIE; + irq_set_chip_and_handler_name(virq, &pl061_irqchip, handle_simple_irq, + "pl061"); + irq_set_chip_data(virq, chip); + irq_set_irq_type(virq, IRQ_TYPE_NONE); - irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR), - IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); + return 0; } +static const struct irq_domain_ops pl061_domain_ops = { + .map = pl061_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + static int pl061_probe(struct amba_device *adev, const struct amba_id *id) { struct device *dev = &adev->dev; struct pl061_platform_data *pdata = dev->platform_data; struct pl061_gpio *chip; - int ret, irq, i; + int ret, irq, i, irq_base; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) @@ -224,22 +250,28 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) if (pdata) { chip->gc.base = pdata->gpio_base; - chip->irq_base = pdata->irq_base; - } else if (adev->dev.of_node) { + irq_base = pdata->irq_base; + if (irq_base <= 0) + return -ENODEV; + } else { chip->gc.base = -1; - chip->irq_base = 0; - } else - return -ENODEV; + irq_base = 0; + } if (!devm_request_mem_region(dev, adev->res.start, - resource_size(&adev->res), "pl061")) + resource_size(&adev->res), "pl061")) return -EBUSY; chip->base = devm_ioremap(dev, adev->res.start, - resource_size(&adev->res)); - if (chip->base == NULL) + resource_size(&adev->res)); + if (!chip->base) return -ENOMEM; + chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR, + irq_base, &pl061_domain_ops, chip); + if (!chip->domain) + return -ENODEV; + spin_lock_init(&chip->lock); chip->gc.direction_input = pl061_direction_input; @@ -259,12 +291,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) /* * irq_chip support */ - - if (chip->irq_base <= 0) - return 0; - - pl061_init_gc(chip, chip->irq_base); - writeb(0, chip->base + GPIOIE); /* disable irqs */ irq = adev->irq[0]; if (irq < 0) -- cgit From 51e13c2475913d45a3ec546dee647538a9341d6a Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:50 +0800 Subject: pinctrl: check pinctrl ready for gpio range pinctrl_get_device_gpio_range() only checks whether a certain GPIO pin is in gpio range. But maybe some GPIO pins don't have back-end pinctrl interface, it means that these pins are always configured as GPIO function. For example, gpio159 isn't related to back-end pinctrl device in Hi3620 while other GPIO pins are related to back-end pinctrl device. Append pinctrl_ready_for_gpio_range() that is used to check whether pinctrl device with GPIO range is ready. This function will be called after pinctrl_get_device_gpio_range() fails. If pinctrl device with GPIO range is found, it means that pinctrl device is already launched and a certain GPIO pin just don't have back-end pinctrl interface. Then pinctrl_request_gpio() shouldn't return -EPROBE_DEFER in this case. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e2d214c5c58f..f8a632dc877b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "core.h" #include "devicetree.h" #include "pinmux.h" @@ -276,6 +277,39 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) return NULL; } +/** + * pinctrl_ready_for_gpio_range() - check if other GPIO pins of + * the same GPIO chip are in range + * @gpio: gpio pin to check taken from the global GPIO pin space + * + * This function is complement of pinctrl_match_gpio_range(). If the return + * value of pinctrl_match_gpio_range() is NULL, this function could be used + * to check whether pinctrl device is ready or not. Maybe some GPIO pins + * of the same GPIO chip don't have back-end pinctrl interface. + * If the return value is true, it means that pinctrl device is ready & the + * certain GPIO pin doesn't have back-end pinctrl device. If the return value + * is false, it means that pinctrl device may not be ready. + */ +static bool pinctrl_ready_for_gpio_range(unsigned gpio) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range = NULL; + struct gpio_chip *chip = gpio_to_chip(gpio); + + /* Loop over the pin controllers */ + list_for_each_entry(pctldev, &pinctrldev_list, node) { + /* Loop over the ranges */ + list_for_each_entry(range, &pctldev->gpio_ranges, node) { + /* Check if any gpio range overlapped with gpio chip */ + if (range->base + range->npins - 1 < chip->base || + range->base > chip->base + chip->ngpio - 1) + continue; + return true; + } + } + return false; +} + /** * pinctrl_get_device_gpio_range() - find device for GPIO range * @gpio: the pin to locate the pin controller for @@ -443,6 +477,8 @@ int pinctrl_request_gpio(unsigned gpio) ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); if (ret) { + if (pinctrl_ready_for_gpio_range(gpio)) + ret = 0; mutex_unlock(&pinctrl_mutex); return ret; } -- cgit From 39b70ee05199f9bea50641df104aee4dbd913d1d Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:51 +0800 Subject: gpio: pl061: bind pinctrl by gpio request Add the pl061_gpio_request() to request pinctrl. Create the logic between pl061 gpio driver and pinctrl (pinctrl-single) driver. While a gpio pin is requested, it will request pinctrl driver to set that pin with gpio function mode. So pinctrl driver should append .gpio_request_enable() in pinmux_ops. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index d1d603585a93..06ed257c5d31 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,17 @@ struct pl061_gpio { #endif }; +static int pl061_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + /* + * Map back to global GPIO space and request muxing, the direction + * parameter does not matter for this controller. + */ + int gpio = chip->base + offset; + + return pinctrl_request_gpio(gpio); +} + static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); @@ -274,6 +286,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&chip->lock); + chip->gc.request = pl061_gpio_request; chip->gc.direction_input = pl061_direction_input; chip->gc.direction_output = pl061_direction_output; chip->gc.get = pl061_get_value; -- cgit From a1a277eb76b3507df7c41774048a644aa4dfd096 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:52 +0800 Subject: pinctrl: single: create new gpio function range Since gpio driver could create gpio range in DTS, it could invoke pinctrl_request_gpio(). In the pinctrl-single driver, it needs to configure pins with gpio function mode. A new gpio function range should be created in DTS file in below. pinctrl-single,gpio-range = ; range: gpio-range { #pinctrl-single,gpio-range-cells = <3>; }; The gpio-ranges property is used in gpio driver and the pinctrl-single,gpio-range property is used in pinctrl-single driver. 1. gpio-ranges is used for gpio driver in below. gpio-ranges = gpio-ranges = < &pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1 &pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>; 2. gpio driver could get pin offset from gpio-ranges property. pinctrl-single driver could get gpio function mode from gpio_func that is stored in @gpiofuncs list in struct pcs_device. This new pinctrl-single,gpio-range is used as complement for gpio-ranges property in gpio driver. Signed-off-by: Haojian Zhuang Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 73 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 0c0e2da9d880..f4bc602cdb08 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -76,6 +76,20 @@ struct pcs_function { struct list_head node; }; +/** + * struct pcs_gpiofunc_range - pin ranges with same mux value of gpio function + * @offset: offset base of pins + * @npins: number pins with the same mux value of gpio function + * @gpiofunc: mux value of gpio function + * @node: list node + */ +struct pcs_gpiofunc_range { + unsigned offset; + unsigned npins; + unsigned gpiofunc; + struct list_head node; +}; + /** * struct pcs_data - wrapper for data needed by pinctrl framework * @pa: pindesc array @@ -123,6 +137,7 @@ struct pcs_name { * @ftree: function index radix tree * @pingroups: list of pingroups * @functions: list of functions + * @gpiofuncs: list of gpio functions * @ngroups: number of pingroups * @nfuncs: number of functions * @desc: pin controller descriptor @@ -148,6 +163,7 @@ struct pcs_device { struct radix_tree_root ftree; struct list_head pingroups; struct list_head functions; + struct list_head gpiofuncs; unsigned ngroups; unsigned nfuncs; struct pinctrl_desc desc; @@ -403,9 +419,26 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) + struct pinctrl_gpio_range *range, unsigned pin) { - return -ENOTSUPP; + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_gpiofunc_range *frange = NULL; + struct list_head *pos, *tmp; + int mux_bytes = 0; + unsigned data; + + list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { + frange = list_entry(pos, struct pcs_gpiofunc_range, node); + if (pin >= frange->offset + frange->npins + || pin < frange->offset) + continue; + mux_bytes = pcs->width / BITS_PER_BYTE; + data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; + data |= frange->gpiofunc; + pcs->write(data, pcs->base + pin * mux_bytes); + break; + } + return 0; } static const struct pinmux_ops pcs_pinmux_ops = { @@ -879,6 +912,37 @@ static void pcs_free_resources(struct pcs_device *pcs) static struct of_device_id pcs_of_match[]; +static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) +{ + const char *propname = "pinctrl-single,gpio-range"; + const char *cellname = "#pinctrl-single,gpio-range-cells"; + struct of_phandle_args gpiospec; + struct pcs_gpiofunc_range *range; + int ret, i; + + for (i = 0; ; i++) { + ret = of_parse_phandle_with_args(node, propname, cellname, + i, &gpiospec); + /* Do not treat it as error. Only treat it as end condition. */ + if (ret) { + ret = 0; + break; + } + range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL); + if (!range) { + ret = -ENOMEM; + break; + } + range->offset = gpiospec.args[0]; + range->npins = gpiospec.args[1]; + range->gpiofunc = gpiospec.args[2]; + mutex_lock(&pcs->mutex); + list_add_tail(&range->node, &pcs->gpiofuncs); + mutex_unlock(&pcs->mutex); + } + return ret; +} + static int pcs_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -900,6 +964,7 @@ static int pcs_probe(struct platform_device *pdev) mutex_init(&pcs->mutex); INIT_LIST_HEAD(&pcs->pingroups); INIT_LIST_HEAD(&pcs->functions); + INIT_LIST_HEAD(&pcs->gpiofuncs); PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width, "register width not specified\n"); @@ -975,6 +1040,10 @@ static int pcs_probe(struct platform_device *pdev) goto free; } + ret = pcs_add_gpio_func(np, pcs); + if (ret < 0) + goto free; + dev_info(pcs->dev, "%i pins at pa %p size %u\n", pcs->desc.npins, pcs->base, pcs->size); -- cgit From 9cfd1724f070ffce27861cb7dcfca6808fd722b8 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:53 +0800 Subject: pinctrl: generic: dump pin configuration Add the support of dumping pin configuration. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 14 ++++++++++++++ drivers/pinctrl/pinconf.h | 8 ++++++++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 06c304ac6f7d..9c436858812c 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) "generic pinconfig core: " fmt #include +#include #include #include #include @@ -120,4 +121,17 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, } } +void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned long config) +{ + int i; + + for(i = 0; i < ARRAY_SIZE(conf_items); i++) { + if (pinconf_to_config_param(config) != conf_items[i].param) + continue; + seq_printf(s, "%s: 0x%x", conf_items[i].display, + pinconf_to_config_argument(config)); + } +} +EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); #endif diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index e3ed8cb072a5..1f7113e40078 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -98,6 +98,8 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, struct seq_file *s, const char *gname); +void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned long config); #else static inline void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, @@ -114,4 +116,10 @@ static inline void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, return; } +static inline void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned long config) +{ + return; +} #endif -- cgit From 477ac771dd25d1cacfb832394f5207343508bdb4 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:54 +0800 Subject: pinctrl: single: set function mask as optional Since Hisilicon's pin controller is divided into two parts. One is the function mux, and the other is pin configuration. These two parts are in the different memory regions. So make pinctrl-single,function-mask as optional property. Then we can define pingroups without valid function mux that is only used for pin configuration. Signed-off-by: Haojian Zhuang Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index f4bc602cdb08..f9596fe26394 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -350,6 +350,9 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, int i; pcs = pinctrl_dev_get_drvdata(pctldev); + /* If function mask is null, needn't enable it. */ + if (!pcs->fmask) + return 0; func = radix_tree_lookup(&pcs->ftree, fselector); if (!func) return -EINVAL; @@ -384,6 +387,10 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, int i; pcs = pinctrl_dev_get_drvdata(pctldev); + /* If function mask is null, needn't disable it. */ + if (!pcs->fmask) + return; + func = radix_tree_lookup(&pcs->ftree, fselector); if (!func) { dev_err(pcs->dev, "%s could not find function%i\n", @@ -427,6 +434,10 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev, int mux_bytes = 0; unsigned data; + /* If function mask is null, return directly. */ + if (!pcs->fmask) + return -ENOTSUPP; + list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { frange = list_entry(pos, struct pcs_gpiofunc_range, node); if (pin >= frange->offset + frange->npins @@ -969,10 +980,17 @@ static int pcs_probe(struct platform_device *pdev) PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width, "register width not specified\n"); - PCS_GET_PROP_U32("pinctrl-single,function-mask", &pcs->fmask, - "function register mask not specified\n"); - pcs->fshift = ffs(pcs->fmask) - 1; - pcs->fmax = pcs->fmask >> pcs->fshift; + ret = of_property_read_u32(np, "pinctrl-single,function-mask", + &pcs->fmask); + if (!ret) { + pcs->fshift = ffs(pcs->fmask) - 1; + pcs->fmax = pcs->fmask >> pcs->fshift; + } else { + /* If mask property doesn't exist, function mux is invalid. */ + pcs->fmask = 0; + pcs->fshift = 0; + pcs->fmax = 0; + } ret = of_property_read_u32(np, "pinctrl-single,function-off", &pcs->foff); -- cgit From 9dddb4df90d136429b6d6ddefceb49a9b93f6cd1 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:55 +0800 Subject: pinctrl: single: support generic pinconf Support the operation of generic pinconf. The supported config arguments are INPUT_SCHMITT, INPUT_SCHMITT_ENABLE, DRIVE_STRENGHT, BIAS_DISABLE, BIAS_PULLUP, BIAS_PULLDOWN, SLEW_RATE. Signed-off-by: Haojian Zhuang Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/pinctrl-single.c | 408 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 402 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 34f51d2d90d2..5a690ce6d60d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -166,6 +166,7 @@ config PINCTRL_SINGLE depends on OF select PINMUX select PINCONF + select GENERIC_PINCONF help This selects the device tree based generic pinctrl driver. diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index f9596fe26394..4cdcf8582764 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -22,8 +22,10 @@ #include #include +#include #include "core.h" +#include "pinconf.h" #define DRIVER_NAME "pinctrl-single" #define PCS_MUX_PINS_NAME "pinctrl-single,pins" @@ -58,6 +60,33 @@ struct pcs_func_vals { unsigned mask; }; +/** + * struct pcs_conf_vals - pinconf parameter, pinconf register offset + * and value, enable, disable, mask + * @param: config parameter + * @val: user input bits in the pinconf register + * @enable: enable bits in the pinconf register + * @disable: disable bits in the pinconf register + * @mask: mask bits in the register value + */ +struct pcs_conf_vals { + enum pin_config_param param; + unsigned val; + unsigned enable; + unsigned disable; + unsigned mask; +}; + +/** + * struct pcs_conf_type - pinconf property name, pinconf param pair + * @name: property name in DTS file + * @param: config parameter + */ +struct pcs_conf_type { + const char *name; + enum pin_config_param param; +}; + /** * struct pcs_function - pinctrl function * @name: pinctrl function name @@ -73,6 +102,8 @@ struct pcs_function { unsigned nvals; const char **pgnames; int npgnames; + struct pcs_conf_vals *conf; + int nconfs; struct list_head node; }; @@ -131,6 +162,7 @@ struct pcs_name { * @fshift: function register shift * @foff: value to turn mux off * @fmax: max number of functions in fmask + * @is_pinconf: whether supports pinconf * @names: array of register names for pins * @pins: physical pins on the SoC * @pgtree: pingroup index radix tree @@ -157,6 +189,7 @@ struct pcs_device { unsigned foff; unsigned fmax; bool bits_per_mux; + bool is_pinconf; struct pcs_name *names; struct pcs_data pins; struct radix_tree_root pgtree; @@ -171,6 +204,16 @@ struct pcs_device { void (*write)(unsigned val, void __iomem *reg); }; +static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config); +static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long config); + +static enum pin_config_param pcs_bias[] = { + PIN_CONFIG_BIAS_PULL_DOWN, + PIN_CONFIG_BIAS_PULL_UP, +}; + /* * REVISIT: Reads and writes could eventually use regmap or something * generic. But at least on omaps, some mux registers are performance @@ -342,6 +385,28 @@ static int pcs_get_function_groups(struct pinctrl_dev *pctldev, return 0; } +static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin, + struct pcs_function **func) +{ + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pin_desc *pdesc = pin_desc_get(pctldev, pin); + const struct pinctrl_setting_mux *setting; + unsigned fselector; + + /* If pin is not described in DTS & enabled, mux_setting is NULL. */ + setting = pdesc->mux_setting; + if (!setting) + return -ENOTSUPP; + fselector = setting->func; + *func = radix_tree_lookup(&pcs->ftree, fselector); + if (!(*func)) { + dev_err(pcs->dev, "%s could not find function%i\n", + __func__, fselector); + return -ENOTSUPP; + } + return 0; +} + static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, unsigned group) { @@ -461,32 +526,191 @@ static const struct pinmux_ops pcs_pinmux_ops = { .gpio_request_enable = pcs_request_gpio, }; +/* Clear BIAS value */ +static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin) +{ + unsigned long config; + int i; + for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { + config = pinconf_to_config_packed(pcs_bias[i], 0); + pcs_pinconf_set(pctldev, pin, config); + } +} + +/* + * Check whether PIN_CONFIG_BIAS_DISABLE is valid. + * It's depend on that PULL_DOWN & PULL_UP configs are all invalid. + */ +static bool pcs_pinconf_bias_disable(struct pinctrl_dev *pctldev, unsigned pin) +{ + unsigned long config; + int i; + + for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { + config = pinconf_to_config_packed(pcs_bias[i], 0); + if (!pcs_pinconf_get(pctldev, pin, &config)) + goto out; + } + return true; +out: + return false; +} + static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; + unsigned offset = 0, data = 0, i, j, ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (i = 0; i < func->nconfs; i++) { + param = pinconf_to_config_param(*config); + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (pcs_pinconf_bias_disable(pctldev, pin)) { + *config = 0; + return 0; + } else { + return -ENOTSUPP; + } + } else if (param != func->conf[i].param) { + continue; + } + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset) & func->conf[i].mask; + switch (func->conf[i].param) { + /* 4 parameters */ + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if ((data != func->conf[i].enable) || + (data == func->conf[i].disable)) + return -ENOTSUPP; + *config = 0; + break; + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + for (j = 0; j < func->nconfs; j++) { + switch (func->conf[j].param) { + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (data != func->conf[j].enable) + return -ENOTSUPP; + break; + default: + break; + } + } + *config = data; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + case PIN_CONFIG_SLEW_RATE: + default: + *config = data; + break; + } + return 0; + } return -ENOTSUPP; } static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + unsigned offset = 0, shift = 0, arg = 0, i, data, ret; + u16 argument; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (i = 0; i < func->nconfs; i++) { + if (pinconf_to_config_param(config) == func->conf[i].param) { + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset); + argument = pinconf_to_config_argument(config); + switch (func->conf[i].param) { + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_DRIVE_STRENGTH: + case PIN_CONFIG_SLEW_RATE: + shift = ffs(func->conf[i].mask) - 1; + arg = pinconf_to_config_argument(config); + data &= ~func->conf[i].mask; + data |= (arg << shift) & func->conf[i].mask; + break; + /* 4 parameters */ + case PIN_CONFIG_BIAS_DISABLE: + pcs_pinconf_clear_bias(pctldev, pin); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (argument) + pcs_pinconf_clear_bias(pctldev, pin); + /* fall through */ + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + data &= ~func->conf[i].mask; + if (argument) + data |= func->conf[i].enable; + else + data |= func->conf[i].disable; + break; + default: + return -ENOTSUPP; + } + pcs->write(data, pcs->base + offset); + return 0; + } + } return -ENOTSUPP; } static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev, unsigned group, unsigned long *config) { - return -ENOTSUPP; + const unsigned *pins; + unsigned npins, old = 0; + int i, ret; + + ret = pcs_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + for (i = 0; i < npins; i++) { + if (pcs_pinconf_get(pctldev, pins[i], config)) + return -ENOTSUPP; + /* configs do not match between two pins */ + if (i && (old != *config)) + return -ENOTSUPP; + old = *config; + } + return 0; } static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, unsigned long config) { - return -ENOTSUPP; + const unsigned *pins; + unsigned npins; + int i, ret; + + ret = pcs_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + for (i = 0; i < npins; i++) { + if (pcs_pinconf_set(pctldev, pins[i], config)) + return -ENOTSUPP; + } + return 0; } static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned offset) + struct seq_file *s, unsigned pin) { } @@ -495,6 +719,13 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } +static void pcs_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned long config) +{ + pinconf_generic_dump_config(pctldev, s, config); +} + static const struct pinconf_ops pcs_pinconf_ops = { .pin_config_get = pcs_pinconf_get, .pin_config_set = pcs_pinconf_set, @@ -502,6 +733,7 @@ static const struct pinconf_ops pcs_pinconf_ops = { .pin_config_group_set = pcs_pinconf_group_set, .pin_config_dbg_show = pcs_pinconf_dbg_show, .pin_config_group_dbg_show = pcs_pinconf_group_dbg_show, + .pin_config_config_dbg_show = pcs_pinconf_config_dbg_show, }; /** @@ -692,11 +924,157 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset) return index; } +/* + * check whether data matches enable bits or disable bits + * Return value: 1 for matching enable bits, 0 for matching disable bits, + * and negative value for matching failure. + */ +static int pcs_config_match(unsigned data, unsigned enable, unsigned disable) +{ + int ret = -EINVAL; + + if (data == enable) + ret = 1; + else if (data == disable) + ret = 0; + return ret; +} + +static void add_config(struct pcs_conf_vals **conf, enum pin_config_param param, + unsigned value, unsigned enable, unsigned disable, + unsigned mask) +{ + (*conf)->param = param; + (*conf)->val = value; + (*conf)->enable = enable; + (*conf)->disable = disable; + (*conf)->mask = mask; + (*conf)++; +} + +static void add_setting(unsigned long **setting, enum pin_config_param param, + unsigned arg) +{ + **setting = pinconf_to_config_packed(param, arg); + (*setting)++; +} + +/* add pinconf setting with 2 parameters */ +static void pcs_add_conf2(struct pcs_device *pcs, struct device_node *np, + const char *name, enum pin_config_param param, + struct pcs_conf_vals **conf, unsigned long **settings) +{ + unsigned value[2]; + int ret; + + ret = of_property_read_u32_array(np, name, value, 2); + if (ret) + return; + /* set value & mask */ + value[0] &= value[1]; + /* skip enable & disable */ + add_config(conf, param, value[0], 0, 0, value[1]); + add_setting(settings, param, value[0]); +} + +/* add pinconf setting with 4 parameters */ +static void pcs_add_conf4(struct pcs_device *pcs, struct device_node *np, + const char *name, enum pin_config_param param, + struct pcs_conf_vals **conf, unsigned long **settings) +{ + unsigned value[4]; + int ret; + + /* value to set, enable, disable, mask */ + ret = of_property_read_u32_array(np, name, value, 4); + if (ret) + return; + if (!value[3]) { + dev_err(pcs->dev, "mask field of the property can't be 0\n"); + return; + } + value[0] &= value[3]; + value[1] &= value[3]; + value[2] &= value[3]; + ret = pcs_config_match(value[0], value[1], value[2]); + if (ret < 0) + dev_dbg(pcs->dev, "failed to match enable or disable bits\n"); + add_config(conf, param, value[0], value[1], value[2], value[3]); + add_setting(settings, param, ret); +} + +static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, + struct pcs_function *func, + struct pinctrl_map **map) + +{ + struct pinctrl_map *m = *map; + int i = 0, nconfs = 0; + unsigned long *settings = NULL, *s = NULL; + struct pcs_conf_vals *conf = NULL; + struct pcs_conf_type prop2[] = { + { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, }, + { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, }, + { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, }, + }; + struct pcs_conf_type prop4[] = { + { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, }, + { "pinctrl-single,bias-pulldown", PIN_CONFIG_BIAS_PULL_DOWN, }, + { "pinctrl-single,input-schmitt-enable", + PIN_CONFIG_INPUT_SCHMITT_ENABLE, }, + }; + + /* If pinconf isn't supported, don't parse properties in below. */ + if (!pcs->is_pinconf) + return 0; + + /* cacluate how much properties are supported in current node */ + for (i = 0; i < ARRAY_SIZE(prop2); i++) { + if (of_find_property(np, prop2[i].name, NULL)) + nconfs++; + } + for (i = 0; i < ARRAY_SIZE(prop4); i++) { + if (of_find_property(np, prop4[i].name, NULL)) + nconfs++; + } + if (!nconfs) + return 0; + + func->conf = devm_kzalloc(pcs->dev, + sizeof(struct pcs_conf_vals) * nconfs, + GFP_KERNEL); + if (!func->conf) + return -ENOMEM; + func->nconfs = nconfs; + conf = &(func->conf[0]); + m++; + settings = devm_kzalloc(pcs->dev, sizeof(unsigned long) * nconfs, + GFP_KERNEL); + if (!settings) + return -ENOMEM; + s = &settings[0]; + + for (i = 0; i < ARRAY_SIZE(prop2); i++) + pcs_add_conf2(pcs, np, prop2[i].name, prop2[i].param, + &conf, &s); + for (i = 0; i < ARRAY_SIZE(prop4); i++) + pcs_add_conf4(pcs, np, prop4[i].name, prop4[i].param, + &conf, &s); + m->type = PIN_MAP_TYPE_CONFIGS_GROUP; + m->data.configs.group_or_pin = np->name; + m->data.configs.configs = settings; + m->data.configs.num_configs = nconfs; + return 0; +} + +static void pcs_free_pingroups(struct pcs_device *pcs); + /** * smux_parse_one_pinctrl_entry() - parses a device tree mux entry * @pcs: pinctrl driver instance * @np: device node of the mux entry * @map: map entry + * @num_maps: number of map * @pgnames: pingroup names * * Note that this binding currently supports only sets of one register + value. @@ -713,6 +1091,7 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset) static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, struct device_node *np, struct pinctrl_map **map, + unsigned *num_maps, const char **pgnames) { struct pcs_func_vals *vals; @@ -785,8 +1164,18 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, (*map)->data.mux.group = np->name; (*map)->data.mux.function = np->name; + if (pcs->is_pinconf) { + if (pcs_parse_pinconf(pcs, np, function, map)) + goto free_pingroups; + *num_maps = 2; + } else { + *num_maps = 1; + } return 0; +free_pingroups: + pcs_free_pingroups(pcs); + *num_maps = 1; free_function: pcs_remove_function(pcs, function); @@ -815,7 +1204,8 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, pcs = pinctrl_dev_get_drvdata(pctldev); - *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL); + /* create 2 maps. One is for pinmux, and the other is for pinconf. */ + *map = devm_kzalloc(pcs->dev, sizeof(**map) * 2, GFP_KERNEL); if (!*map) return -ENOMEM; @@ -827,13 +1217,13 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, goto free_map; } - ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames); + ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, num_maps, + pgnames); if (ret < 0) { dev_err(pcs->dev, "no pins entries for %s\n", np_config->name); goto free_pgnames; } - *num_maps = 1; return 0; @@ -976,6 +1366,7 @@ static int pcs_probe(struct platform_device *pdev) INIT_LIST_HEAD(&pcs->pingroups); INIT_LIST_HEAD(&pcs->functions); INIT_LIST_HEAD(&pcs->gpiofuncs); + pcs->is_pinconf = match->data; PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width, "register width not specified\n"); @@ -1046,6 +1437,8 @@ static int pcs_probe(struct platform_device *pdev) pcs->desc.pmxops = &pcs_pinmux_ops; pcs->desc.confops = &pcs_pinconf_ops; pcs->desc.owner = THIS_MODULE; + if (match->data) + pcs_pinconf_ops.is_generic = true; ret = pcs_allocate_pin_table(pcs); if (ret < 0) @@ -1086,7 +1479,8 @@ static int pcs_remove(struct platform_device *pdev) } static struct of_device_id pcs_of_match[] = { - { .compatible = DRIVER_NAME, }, + { .compatible = "pinctrl-single", .data = (void *)false }, + { .compatible = "pinconf-single", .data = (void *)true }, { }, }; MODULE_DEVICE_TABLE(of, pcs_of_match); -- cgit From 5ff9090f3de360578a2a4f53812fcfce761bfaaa Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Feb 2013 14:35:28 +0000 Subject: mfd: ab8500-debug: Function to save all ABB registers to mem Dump function that stores all readable ABB registers to a memory areas where they can be accessed from dump file. Signed-off-by: Jonas Aaberg Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 75366b55f16c..7febf171e755 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -601,6 +601,56 @@ void ab8500_dump_all_banks(struct device *dev) } } +/* Space for 500 registers. */ +#define DUMP_MAX_REGS 700 +struct ab8500_register_dump +{ + u8 bank; + u8 reg; + u8 value; + int ret; +} ab8500_complete_register_dump[DUMP_MAX_REGS]; + +extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); + +/* This shall only be called upon kernel panic! */ +void ab8500_dump_all_banks_to_mem(void) +{ + int i, r = 0; + u8 bank; + + pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" " + "for crash analyze.\n"); + + for (bank = 1; bank < AB8500_NUM_BANKS; bank++) { + for (i = 0; i < debug_ranges[bank].num_ranges; i++) { + u8 reg; + + for (reg = debug_ranges[bank].range[i].first; + reg <= debug_ranges[bank].range[i].last; + reg++) { + u8 value; + int err; + + err = prcmu_abb_read(bank, reg, &value, 1); + + ab8500_complete_register_dump[r].ret = err; + ab8500_complete_register_dump[r].bank = bank; + ab8500_complete_register_dump[r].reg = reg; + ab8500_complete_register_dump[r].value = value; + + r++; + + if (r >= DUMP_MAX_REGS) { + pr_err("%s: too many register to dump!\n", + __func__); + return; + } + } + } + } +} + static int ab8500_all_banks_open(struct inode *inode, struct file *file) { struct seq_file *s; -- cgit From a7bbdd7f8065b97108830662b31c18fc67449c87 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 4 Mar 2013 13:47:39 +0800 Subject: pinctrl: single: Fix build error If pcs->is_pinconf is false, it means does not support pinconf. If pcs->is_pinconf is true, is_generic flag is always true. This patch fixes below build error: CC [M] drivers/pinctrl/pinctrl-single.o drivers/pinctrl/pinctrl-single.c: In function 'pcs_probe': drivers/pinctrl/pinctrl-single.c:1441:3: error: assignment of member 'is_generic' in read-only object make[2]: *** [drivers/pinctrl/pinctrl-single.o] Error 1 make[1]: *** [drivers/pinctrl] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Reviewed-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 4cdcf8582764..e35dabd3135d 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -734,6 +734,7 @@ static const struct pinconf_ops pcs_pinconf_ops = { .pin_config_dbg_show = pcs_pinconf_dbg_show, .pin_config_group_dbg_show = pcs_pinconf_group_dbg_show, .pin_config_config_dbg_show = pcs_pinconf_config_dbg_show, + .is_generic = true, }; /** @@ -1435,10 +1436,9 @@ static int pcs_probe(struct platform_device *pdev) pcs->desc.name = DRIVER_NAME; pcs->desc.pctlops = &pcs_pinctrl_ops; pcs->desc.pmxops = &pcs_pinmux_ops; - pcs->desc.confops = &pcs_pinconf_ops; + if (pcs->is_pinconf) + pcs->desc.confops = &pcs_pinconf_ops; pcs->desc.owner = THIS_MODULE; - if (match->data) - pcs_pinconf_ops.is_generic = true; ret = pcs_allocate_pin_table(pcs); if (ret < 0) -- cgit From c0eda9aef1c0ef7bb2812b739ddf400405568bef Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Feb 2013 15:04:09 +0000 Subject: mfd: ab8500-core: Add ADC support for ab8540 Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 74 ++++++++++++++++++++++++++++++++++++---------- drivers/mfd/ab8500-gpadc.c | 67 +++++++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index baaf2ed8095b..cdf6c1e59bc3 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -658,6 +658,15 @@ static struct resource ab8500_gpadc_resources[] = { }, }; +static struct resource ab8540_gpadc_resources[] = { + { + .name = "SW_CONV_END", + .start = AB8500_INT_GP_SW_ADC_CONV_END, + .end = AB8500_INT_GP_SW_ADC_CONV_END, + .flags = IORESOURCE_IRQ, + }, +}; + static struct resource ab8500_rtc_resources[] = { { .name = "60S", @@ -1013,12 +1022,6 @@ static struct mfd_cell abx500_common_devs[] = { .name = "abx500-clk", .of_compatible = "stericsson,abx500-clk", }, - { - .name = "ab8500-gpadc", - .of_compatible = "stericsson,ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), - .resources = ab8500_gpadc_resources, - }, { .name = "ab8500-rtc", .of_compatible = "stericsson,ab8500-rtc", @@ -1118,6 +1121,12 @@ static struct mfd_cell ab8500_devs[] = { .name = "ab8500-codec", .of_compatible = "stericsson,ab8500-codec", }, + { + .name = "ab8500-gpadc", + .of_compatible = "stericsson,ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), + .resources = ab8500_gpadc_resources, + }, }; static struct mfd_cell ab9540_devs[] = { @@ -1133,10 +1142,44 @@ static struct mfd_cell ab9540_devs[] = { { .name = "ab9540-codec", }, + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), + .resources = ab8500_gpadc_resources, + }, + { + .name = "ab-iddet", + .num_resources = ARRAY_SIZE(ab8505_iddet_resources), + .resources = ab8505_iddet_resources, + }, }; -/* Device list common to ab9540 and ab8505 */ -static struct mfd_cell ab9540_ab8505_devs[] = { +/* Device list for ab8505 */ +static struct mfd_cell ab8505_devs[] = { + { + .name = "ab-iddet", + .num_resources = ARRAY_SIZE(ab8505_iddet_resources), + .resources = ab8505_iddet_resources, + }, +}; + +static struct mfd_cell ab8540_devs[] = { + { + .name = "ab8500-gpio", + }, + { + .name = "ab8540-usb", + .num_resources = ARRAY_SIZE(ab8500_usb_resources), + .resources = ab8500_usb_resources, + }, + { + .name = "ab8540-codec", + }, + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8540_gpadc_resources), + .resources = ab8540_gpadc_resources, + }, { .name = "ab-iddet", .num_resources = ARRAY_SIZE(ab8505_iddet_resources), @@ -1495,6 +1538,14 @@ static int ab8500_probe(struct platform_device *pdev) ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, ARRAY_SIZE(ab9540_devs), NULL, ab8500->irq_base, ab8500->domain); + else if (is_ab8540(ab8500)) + ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs, + ARRAY_SIZE(ab8540_devs), NULL, + ab8500->irq_base, ab8500->domain); + else if (is_ab8505(ab8500)) + ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs, + ARRAY_SIZE(ab8505_devs), NULL, + ab8500->irq_base, ab8500->domain); else ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, ARRAY_SIZE(ab8500_devs), NULL, @@ -1502,13 +1553,6 @@ static int ab8500_probe(struct platform_device *pdev) if (ret) return ret; - if (is_ab9540(ab8500) || is_ab8505(ab8500)) - ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, - ARRAY_SIZE(ab9540_ab8505_devs), NULL, - ab8500->irq_base, ab8500->domain); - if (ret) - return ret; - if (!no_bm) { /* Add battery management devices */ ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 8673bf66f7d7..fc8da4496e84 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -311,6 +311,12 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, if (!gpadc) return -ENODEV; + /* check if convertion is supported */ + if ((gpadc->irq_sw < 0) && (conv_type == ADC_SW)) + return -ENOTSUPP; + if ((gpadc->irq_hw < 0) && (conv_type == ADC_HW)) + return -ENOTSUPP; + mutex_lock(&gpadc->ab8500_gpadc_lock); /* Enable VTVout LDO this is required for GPADC */ pm_runtime_get_sync(gpadc->dev); @@ -761,20 +767,12 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) } gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); - if (gpadc->irq_sw < 0) { - dev_err(gpadc->dev, "failed to get platform irq-%d\n", - gpadc->irq_sw); - ret = gpadc->irq_sw; - goto fail; - } + if (gpadc->irq_sw < 0) + dev_err(gpadc->dev, "failed to get platform sw_conv_end irq\n"); gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); - if (gpadc->irq_hw < 0) { - dev_err(gpadc->dev, "failed to get platform irq-%d\n", - gpadc->irq_hw); - ret = gpadc->irq_hw; - goto fail; - } + if (gpadc->irq_hw < 0) + dev_err(gpadc->dev, "failed to get platform hw_conv_end irq\n"); gpadc->dev = &pdev->dev; gpadc->parent = dev_get_drvdata(pdev->dev.parent); @@ -784,21 +782,30 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) init_completion(&gpadc->ab8500_gpadc_complete); /* Register interrupts */ - ret = request_threaded_irq(gpadc->irq_sw, NULL, - ab8500_bm_gpadcconvend_handler, - IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", gpadc); - if (ret < 0) { - dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", - gpadc->irq_sw); - goto fail; + if (gpadc->irq_sw >= 0) { + ret = request_threaded_irq(gpadc->irq_sw, NULL, + ab8500_bm_gpadcconvend_handler, + IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", + gpadc); + if (ret < 0) { + dev_err(gpadc->dev, + "Failed to register interrupt irq: %d\n", + gpadc->irq_sw); + goto fail; + } } - ret = request_threaded_irq(gpadc->irq_hw, NULL, - ab8500_bm_gpadcconvend_handler, - IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", gpadc); - if (ret < 0) { - dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", - gpadc->irq_hw); - goto fail; + + if (gpadc->irq_hw >= 0) { + ret = request_threaded_irq(gpadc->irq_hw, NULL, + ab8500_bm_gpadcconvend_handler, + IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", + gpadc); + if (ret < 0) { + dev_err(gpadc->dev, + "Failed to register interrupt irq: %d\n", + gpadc->irq_hw); + goto fail_irq; + } } /* VTVout LDO used to power up ab8500-GPADC */ @@ -821,7 +828,9 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) ab8500_gpadc_read_calibration_data(gpadc); list_add_tail(&gpadc->node, &ab8500_gpadc_list); dev_dbg(gpadc->dev, "probe success\n"); + return 0; + fail_irq: free_irq(gpadc->irq_sw, gpadc); free_irq(gpadc->irq_hw, gpadc); @@ -838,8 +847,10 @@ static int ab8500_gpadc_remove(struct platform_device *pdev) /* remove this gpadc entry from the list */ list_del(&gpadc->node); /* remove interrupt - completion of Sw ADC conversion */ - free_irq(gpadc->irq_sw, gpadc); - free_irq(gpadc->irq_hw, gpadc); + if (gpadc->irq_sw >= 0) + free_irq(gpadc->irq_sw, gpadc); + if (gpadc->irq_hw >= 0) + free_irq(gpadc->irq_hw, gpadc); pm_runtime_get_sync(gpadc->dev); pm_runtime_disable(gpadc->dev); -- cgit From 4b106fb9895c7edba2acd41c152e8f6edf724651 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:42:00 +0000 Subject: mfd: ab8500-core: Rework MFD sub-device initialisation structures Here we're separating Battery Management devices into their own structure, removing the common device structure & redistribute them amongst the individual platform structs and completing the population of them. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 243 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 182 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index cdf6c1e59bc3..23db4fcea496 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -658,7 +658,7 @@ static struct resource ab8500_gpadc_resources[] = { }, }; -static struct resource ab8540_gpadc_resources[] = { +static struct resource ab8505_gpadc_resources[] = { { .name = "SW_CONV_END", .start = AB8500_INT_GP_SW_ADC_CONV_END, @@ -1001,7 +1001,42 @@ static struct resource ab8500_temp_resources[] = { }, }; -static struct mfd_cell abx500_common_devs[] = { +static struct mfd_cell ab8500_bm_devs[] = { + { + .name = "ab8500-charger", + .of_compatible = "stericsson,ab8500-charger", + .num_resources = ARRAY_SIZE(ab8500_charger_resources), + .resources = ab8500_charger_resources, + .platform_data = &ab8500_bm_data, + .pdata_size = sizeof(ab8500_bm_data), + }, + { + .name = "ab8500-btemp", + .of_compatible = "stericsson,ab8500-btemp", + .num_resources = ARRAY_SIZE(ab8500_btemp_resources), + .resources = ab8500_btemp_resources, + .platform_data = &ab8500_bm_data, + .pdata_size = sizeof(ab8500_bm_data), + }, + { + .name = "ab8500-fg", + .of_compatible = "stericsson,ab8500-fg", + .num_resources = ARRAY_SIZE(ab8500_fg_resources), + .resources = ab8500_fg_resources, + .platform_data = &ab8500_bm_data, + .pdata_size = sizeof(ab8500_bm_data), + }, + { + .name = "ab8500-chargalg", + .of_compatible = "stericsson,ab8500-chargalg", + .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), + .resources = ab8500_chargalg_resources, + .platform_data = &ab8500_bm_data, + .pdata_size = sizeof(ab8500_bm_data), + }, +}; + +static struct mfd_cell ab8500_devs[] = { #ifdef CONFIG_DEBUG_FS { .name = "ab8500-debug", @@ -1022,6 +1057,11 @@ static struct mfd_cell abx500_common_devs[] = { .name = "abx500-clk", .of_compatible = "stericsson,abx500-clk", }, + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), + .resources = ab8500_gpadc_resources, + }, { .name = "ab8500-rtc", .of_compatible = "stericsson,ab8500-rtc", @@ -1035,6 +1075,7 @@ static struct mfd_cell abx500_common_devs[] = { .resources = ab8500_av_acc_detect_resources, }, { + .name = "ab8500-poweron-key", .of_compatible = "stericsson,ab8500-poweron-key", .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), @@ -1063,63 +1104,39 @@ static struct mfd_cell abx500_common_devs[] = { .name = "ab8500-denc", .of_compatible = "stericsson,ab8500-denc", }, + { + .name = "ab8500-gpio", + .of_compatible = "stericsson,ab8500-gpio", + }, { .name = "abx500-temp", .of_compatible = "stericsson,abx500-temp", .num_resources = ARRAY_SIZE(ab8500_temp_resources), .resources = ab8500_temp_resources, }, -}; - -static struct mfd_cell ab8500_bm_devs[] = { - { - .name = "ab8500-charger", - .of_compatible = "stericsson,ab8500-charger", - .num_resources = ARRAY_SIZE(ab8500_charger_resources), - .resources = ab8500_charger_resources, - .platform_data = &ab8500_bm_data, - .pdata_size = sizeof(ab8500_bm_data), - }, { - .name = "ab8500-btemp", - .of_compatible = "stericsson,ab8500-btemp", - .num_resources = ARRAY_SIZE(ab8500_btemp_resources), - .resources = ab8500_btemp_resources, - .platform_data = &ab8500_bm_data, - .pdata_size = sizeof(ab8500_bm_data), - }, - { - .name = "ab8500-fg", - .of_compatible = "stericsson,ab8500-fg", - .num_resources = ARRAY_SIZE(ab8500_fg_resources), - .resources = ab8500_fg_resources, - .platform_data = &ab8500_bm_data, - .pdata_size = sizeof(ab8500_bm_data), + .name = "ab8500-usb", + .num_resources = ARRAY_SIZE(ab8500_usb_resources), + .resources = ab8500_usb_resources, }, { - .name = "ab8500-chargalg", - .of_compatible = "stericsson,ab8500-chargalg", - .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), - .resources = ab8500_chargalg_resources, - .platform_data = &ab8500_bm_data, - .pdata_size = sizeof(ab8500_bm_data), + .name = "ab8500-codec", }, }; -static struct mfd_cell ab8500_devs[] = { +static struct mfd_cell ab9540_devs[] = { +#ifdef CONFIG_DEBUG_FS { - .name = "pinctrl-ab8500", - .of_compatible = "stericsson,ab8500-gpio", + .name = "ab8500-debug", + .num_resources = ARRAY_SIZE(ab8500_debug_resources), + .resources = ab8500_debug_resources, }, +#endif { - .name = "ab8500-usb", - .of_compatible = "stericsson,ab8500-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, + .name = "ab8500-sysctrl", }, { - .name = "ab8500-codec", - .of_compatible = "stericsson,ab8500-codec", + .name = "ab8500-regulator", }, { .name = "ab8500-gpadc", @@ -1127,9 +1144,33 @@ static struct mfd_cell ab8500_devs[] = { .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), .resources = ab8500_gpadc_resources, }, -}; - -static struct mfd_cell ab9540_devs[] = { + { + .name = "ab8500-rtc", + .num_resources = ARRAY_SIZE(ab8500_rtc_resources), + .resources = ab8500_rtc_resources, + }, + { + .name = "ab8500-acc-det", + .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), + .resources = ab8500_av_acc_detect_resources, + }, + { + .name = "ab8500-poweron-key", + .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), + .resources = ab8500_poweronkey_db_resources, + }, + { + .name = "ab8500-pwm", + .id = 1, + }, + { + .name = "ab8500-leds", + }, + { + .name = "abx500-temp", + .num_resources = ARRAY_SIZE(ab8500_temp_resources), + .resources = ab8500_temp_resources, + }, { .name = "pinctrl-ab9540", .of_compatible = "stericsson,ab9540-gpio", @@ -1142,11 +1183,6 @@ static struct mfd_cell ab9540_devs[] = { { .name = "ab9540-codec", }, - { - .name = "ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), - .resources = ab8500_gpadc_resources, - }, { .name = "ab-iddet", .num_resources = ARRAY_SIZE(ab8505_iddet_resources), @@ -1156,6 +1192,57 @@ static struct mfd_cell ab9540_devs[] = { /* Device list for ab8505 */ static struct mfd_cell ab8505_devs[] = { +#ifdef CONFIG_DEBUG_FS + { + .name = "ab8500-debug", + .num_resources = ARRAY_SIZE(ab8500_debug_resources), + .resources = ab8500_debug_resources, + }, +#endif + { + .name = "ab8500-sysctrl", + }, + { + .name = "ab8500-regulator", + }, + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), + .resources = ab8505_gpadc_resources, + }, + { + .name = "ab8500-rtc", + .num_resources = ARRAY_SIZE(ab8500_rtc_resources), + .resources = ab8500_rtc_resources, + }, + { + .name = "ab8500-acc-det", + .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), + .resources = ab8500_av_acc_detect_resources, + }, + { + .name = "ab8500-poweron-key", + .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), + .resources = ab8500_poweronkey_db_resources, + }, + { + .name = "ab8500-pwm", + .id = 1, + }, + { + .name = "ab8500-leds", + }, + { + .name = "ab8500-gpio", + }, + { + .name = "ab8500-usb", + .num_resources = ARRAY_SIZE(ab8500_usb_resources), + .resources = ab8500_usb_resources, + }, + { + .name = "ab8500-codec", + }, { .name = "ab-iddet", .num_resources = ARRAY_SIZE(ab8505_iddet_resources), @@ -1164,6 +1251,51 @@ static struct mfd_cell ab8505_devs[] = { }; static struct mfd_cell ab8540_devs[] = { +#ifdef CONFIG_DEBUG_FS + { + .name = "ab8500-debug", + .num_resources = ARRAY_SIZE(ab8500_debug_resources), + .resources = ab8500_debug_resources, + }, +#endif + { + .name = "ab8500-sysctrl", + }, + { + .name = "ab8500-regulator", + }, + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), + .resources = ab8505_gpadc_resources, + }, + { + .name = "ab8500-rtc", + .num_resources = ARRAY_SIZE(ab8500_rtc_resources), + .resources = ab8500_rtc_resources, + }, + { + .name = "ab8500-acc-det", + .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), + .resources = ab8500_av_acc_detect_resources, + }, + { + .name = "ab8500-poweron-key", + .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), + .resources = ab8500_poweronkey_db_resources, + }, + { + .name = "ab8500-pwm", + .id = 1, + }, + { + .name = "ab8500-leds", + }, + { + .name = "abx500-temp", + .num_resources = ARRAY_SIZE(ab8500_temp_resources), + .resources = ab8500_temp_resources, + }, { .name = "ab8500-gpio", }, @@ -1175,11 +1307,6 @@ static struct mfd_cell ab8540_devs[] = { { .name = "ab8540-codec", }, - { - .name = "ab8500-gpadc", - .num_resources = ARRAY_SIZE(ab8540_gpadc_resources), - .resources = ab8540_gpadc_resources, - }, { .name = "ab-iddet", .num_resources = ARRAY_SIZE(ab8505_iddet_resources), @@ -1528,12 +1655,6 @@ static int ab8500_probe(struct platform_device *pdev) return ret; } - ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, - ARRAY_SIZE(abx500_common_devs), NULL, - ab8500->irq_base, ab8500->domain); - if (ret) - return ret; - if (is_ab9540(ab8500)) ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, ARRAY_SIZE(ab9540_devs), NULL, -- cgit From 3e1a498f2728476535571d270081a17fdfceaf26 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:57:35 +0000 Subject: mfd: ab8500-core: Add Interrupt support for ab8540 ITSource/ITLatch 7, 8, 9 and 10 don't exist on AB8540. This patch replaces them with '-1' in the interrupt list, and handles the '-1' in the code accordingly. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 50 +++++++++++++++++++++++++++++++++------ include/linux/mfd/abx500/ab8500.h | 1 + 2 files changed, 44 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 23db4fcea496..0ba08a26cf73 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -103,8 +103,10 @@ #define AB8500_IT_LATCHHIER1_REG 0x60 #define AB8500_IT_LATCHHIER2_REG 0x61 #define AB8500_IT_LATCHHIER3_REG 0x62 +#define AB8540_IT_LATCHHIER4_REG 0x63 #define AB8500_IT_LATCHHIER_NUM 3 +#define AB8540_IT_LATCHHIER_NUM 4 #define AB8500_REV_REG 0x80 #define AB8500_IC_NAME_REG 0x82 @@ -143,6 +145,12 @@ static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23 }; +/* AB8540 support */ +static const int ab8540_irq_regoffset[AB8540_NUM_IRQ_REGS] = { + 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23, + 25, 26, 27, 28, 29, 30, 31, +}; + static const char ab8500_version_str[][7] = { [AB8500_VERSION_AB8500] = "AB8500", [AB8500_VERSION_AB8505] = "AB8505", @@ -360,6 +368,9 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) is_ab8500_1p1_or_earlier(ab8500)) continue; + if (ab8500->irq_reg_offset[i] < 0) + continue; + ab8500->oldmask[i] = new; reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i]; @@ -431,6 +442,18 @@ static struct irq_chip ab8500_irq_chip = { .irq_set_type = ab8500_irq_set_type, }; +static void update_latch_offset(u8 *offset, int i) +{ + /* Fix inconsistent ITFromLatch25 bit mapping... */ + if (unlikely(*offset == 17)) + *offset = 24; + /* Fix inconsistent ab8540 bit mapping... */ + if (unlikely(*offset == 16)) + *offset = 25; + if ((i==3) && (*offset >= 24)) + *offset += 2; +} + static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, int latch_offset, u8 latch_val) { @@ -482,9 +505,7 @@ static int ab8500_handle_hierarchical_latch(struct ab8500 *ab8500, latch_bit = __ffs(hier_val); latch_offset = (hier_offset << 3) + latch_bit; - /* Fix inconsistent ITFromLatch25 bit mapping... */ - if (unlikely(latch_offset == 17)) - latch_offset = 24; + update_latch_offset(&latch_offset, hier_offset); status = get_register_interruptible(ab8500, AB8500_INTERRUPT, @@ -512,7 +533,7 @@ static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev) dev_vdbg(ab8500->dev, "interrupt\n"); /* Hierarchical interrupt version */ - for (i = 0; i < AB8500_IT_LATCHHIER_NUM; i++) { + for (i = 0; i < (ab8500->it_latchhier_num); i++) { int status; u8 hier_val; @@ -565,6 +586,9 @@ static irqreturn_t ab8500_irq(int irq, void *dev) if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500)) continue; + if (regoffset < 0) + continue; + status = get_register_interruptible(ab8500, AB8500_INTERRUPT, AB8500_IT_LATCH1_REG + regoffset, &value); if (status < 0 || value == 0) @@ -615,7 +639,9 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np) { int num_irqs; - if (is_ab9540(ab8500)) + if (is_ab8540(ab8500)) + num_irqs = AB8540_NR_IRQS; + else if (is_ab9540(ab8500)) num_irqs = AB9540_NR_IRQS; else if (is_ab8505(ab8500)) num_irqs = AB8505_NR_IRQS; @@ -1552,13 +1578,20 @@ static int ab8500_probe(struct platform_device *pdev) ab8500->chip_id >> 4, ab8500->chip_id & 0x0F); - /* Configure AB8500 or AB9540 IRQ */ - if (is_ab9540(ab8500) || is_ab8505(ab8500)) { + /* Configure AB8540 */ + if (is_ab8540(ab8500)) { + ab8500->mask_size = AB8540_NUM_IRQ_REGS; + ab8500->irq_reg_offset = ab8540_irq_regoffset; + ab8500->it_latchhier_num = AB8540_IT_LATCHHIER_NUM; + }/* Configure AB8500 or AB9540 IRQ */ + else if (is_ab9540(ab8500) || is_ab8505(ab8500)) { ab8500->mask_size = AB9540_NUM_IRQ_REGS; ab8500->irq_reg_offset = ab9540_irq_regoffset; + ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM; } else { ab8500->mask_size = AB8500_NUM_IRQ_REGS; ab8500->irq_reg_offset = ab8500_irq_regoffset; + ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM; } ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL); if (!ab8500->mask) @@ -1620,6 +1653,9 @@ static int ab8500_probe(struct platform_device *pdev) is_ab8500_1p1_or_earlier(ab8500)) continue; + if (ab8500->irq_reg_offset[i] < 0) + continue; + get_register_interruptible(ab8500, AB8500_INTERRUPT, AB8500_IT_LATCH1_REG + ab8500->irq_reg_offset[i], &value); diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index fdd8be64feeb..b5780fd40fe4 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h @@ -362,6 +362,7 @@ struct ab8500 { u8 *oldmask; int mask_size; const int *irq_reg_offset; + int it_latchhier_num; }; struct regulator_reg_init; -- cgit From 222460cb4b2fe1c1e84f3302a8d8dbc4a94f6837 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Mon, 18 Jun 2012 10:35:28 +0200 Subject: mfd: ab8500-debug: Better error handling on crash Stop trying to read i2c registers if one fail. Signed-off-by: Jonas Aaberg Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 7febf171e755..1e76a2f35066 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -608,7 +608,6 @@ struct ab8500_register_dump u8 bank; u8 reg; u8 value; - int ret; } ab8500_complete_register_dump[DUMP_MAX_REGS]; extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); @@ -618,6 +617,7 @@ void ab8500_dump_all_banks_to_mem(void) { int i, r = 0; u8 bank; + int err = 0; pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" " "for crash analyze.\n"); @@ -630,11 +630,12 @@ void ab8500_dump_all_banks_to_mem(void) reg <= debug_ranges[bank].range[i].last; reg++) { u8 value; - int err; err = prcmu_abb_read(bank, reg, &value, 1); - ab8500_complete_register_dump[r].ret = err; + if (err < 0) + goto out; + ab8500_complete_register_dump[r].bank = bank; ab8500_complete_register_dump[r].reg = reg; ab8500_complete_register_dump[r].value = value; @@ -644,11 +645,17 @@ void ab8500_dump_all_banks_to_mem(void) if (r >= DUMP_MAX_REGS) { pr_err("%s: too many register to dump!\n", __func__); - return; + err = -EINVAL; + goto out; } } } } +out: + if (err >= 0) + pr_info("Saved all ABB registers.\n"); + else + pr_info("Failed to save all ABB registers.\n"); } static int ab8500_all_banks_open(struct inode *inode, struct file *file) -- cgit From 2cf64e264828aa0be841751d41fcd7f13a98d778 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Thu, 31 May 2012 07:57:07 +0200 Subject: mfd: ab8500-debug: Add wake-up info Add information regarding what ab interrupt that caused a wake-up from suspend in /ab8500/interrupts. Also print the name of the interrupts, not just the numbers. Signed-off-by: Jonas Aaberg Signed-off-by: Lee Jones Reviewed-by: Per FORLIN Tested-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 1e76a2f35066..55d0ff4f5b23 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -803,22 +804,46 @@ static ssize_t ab8500_val_write(struct file *file, * Interrupt status */ static u32 num_interrupts[AB8500_MAX_NR_IRQS]; +static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS]; static int num_interrupt_lines; +bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int) +{ + return false; +} + void ab8500_debug_register_interrupt(int line) { - if (line < num_interrupt_lines) + if (line < num_interrupt_lines) { num_interrupts[line]++; + if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500)) + num_wake_interrupts[line]++; + } } static int ab8500_interrupts_print(struct seq_file *s, void *p) { int line; - seq_printf(s, "irq: number of\n"); + seq_printf(s, "name: number: number of: wake:\n"); + + for (line = 0; line < num_interrupt_lines; line++) { + struct irq_desc *desc = irq_to_desc(line + irq_first); + struct irqaction *action = desc->action; - for (line = 0; line < num_interrupt_lines; line++) - seq_printf(s, "%3i: %6i\n", line, num_interrupts[line]); + seq_printf(s, "%3i: %6i %4i", line, + num_interrupts[line], + num_wake_interrupts[line]); + + if (desc && desc->name) + seq_printf(s, "-%-8s", desc->name); + if (action) { + seq_printf(s, " %s", action->name); + while ((action = action->next) != NULL) + seq_printf(s, ", %s", action->name); + } + seq_putc(s, '\n'); + } return 0; } @@ -1870,7 +1895,7 @@ static int ab8500_debug_probe(struct platform_device *plf) dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last); ret = irq_last; - goto out_freeevent_name; + goto out_freeevent_name; } ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); -- cgit From 2377e52f7ca8ebe6ba9ad0e6173915538ee4808b Mon Sep 17 00:00:00 2001 From: Marcus Danielsson Date: Mon, 18 Jun 2012 15:00:40 +0200 Subject: mfd: ab8500-sysctrl: Error check clean up Add error checks to see if sysctrl was probed as it should. If the sysctrl_dev is not set the return value is -EINVAL. Signed-off-by: Marcus Danielsson Signed-off-by: Lee Jones Reviewed-by: Mattias WALLIN Tested-by: Per FORLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-sysctrl.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 7c773797d267..6ac63a05893c 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -28,6 +28,11 @@ void ab8500_power_off(void) struct power_supply *psy; int ret; + if (sysctrl_dev == NULL) { + pr_err("%s: sysctrl not initialized\n", __func__); + return; + } + /* * If we have a charger connected and we're powering off, * reboot into charge-only mode. @@ -85,7 +90,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value) u8 bank; if (sysctrl_dev == NULL) - return -EAGAIN; + return -EINVAL; bank = (reg >> 8); if (!valid_bank(bank)) @@ -101,7 +106,7 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) u8 bank; if (sysctrl_dev == NULL) - return -EAGAIN; + return -EINVAL; bank = (reg >> 8); if (!valid_bank(bank)) @@ -116,31 +121,32 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev) { struct ab8500_platform_data *plat; struct ab8500_sysctrl_platform_data *pdata; + int ret, i, j; - sysctrl_dev = &pdev->dev; plat = dev_get_platdata(pdev->dev.parent); + + if (!(plat && plat->sysctrl)) + return -EINVAL; + if (plat->pm_power_off) pm_power_off = ab8500_power_off; pdata = plat->sysctrl; - if (pdata) { - int ret, i, j; - for (i = AB8500_SYSCLKREQ1RFCLKBUF; - i <= AB8500_SYSCLKREQ8RFCLKBUF; i++) { - j = i - AB8500_SYSCLKREQ1RFCLKBUF; - ret = ab8500_sysctrl_write(i, 0xff, - pdata->initial_req_buf_config[j]); - dev_dbg(&pdev->dev, + for (i = AB8500_SYSCLKREQ1RFCLKBUF; + i <= AB8500_SYSCLKREQ8RFCLKBUF; i++) { + j = i - AB8500_SYSCLKREQ1RFCLKBUF; + ret = ab8500_sysctrl_write(i, 0xff, + pdata->initial_req_buf_config[j]); + dev_dbg(&pdev->dev, "Setting SysClkReq%dRfClkBuf 0x%X\n", j + 1, pdata->initial_req_buf_config[j]); - if (ret < 0) { - dev_err(&pdev->dev, - "unable to set sysClkReq%dRfClkBuf: " - "%d\n", j + 1, ret); - } + if (ret < 0) { + dev_err(&pdev->dev, + "unable to set sysClkReq%dRfClkBuf: " + "%d\n", j + 1, ret); } } -- cgit From e436ddff5748c459853bb3fb97550a9b8b647b8d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 10:09:41 +0000 Subject: mfd: ab8500-debugfs: Add tests for ab8540 based platform initialisations Signed-off-by: Alexandre Torgue Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Mattias WALLIN Tested-by: Maxime COQUELIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 9 ++++++--- drivers/mfd/ab8500-debugfs.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 0ba08a26cf73..0fc18e91310c 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1346,6 +1346,7 @@ static ssize_t show_chip_id(struct device *dev, struct ab8500 *ab8500; ab8500 = dev_get_drvdata(dev); + return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); } @@ -1676,7 +1677,7 @@ static int ab8500_probe(struct platform_device *pdev) /* Activate this feature only in ab9540 */ /* till tests are done on ab8500 1p2 or later*/ - if (is_ab9540(ab8500)) { + if (is_ab9540(ab8500) || is_ab8540(ab8500)) ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL, ab8500_hierarchical_irq, IRQF_ONESHOT | IRQF_NO_SUSPEND, @@ -1719,7 +1720,8 @@ static int ab8500_probe(struct platform_device *pdev) dev_err(ab8500->dev, "error adding bm devices\n"); } - if (is_ab9540(ab8500)) + if (((is_ab8505(ab8500) || is_ab9540(ab8500)) && + ab8500->chip_id >= AB8500_CUT2P0) || is_ab8540(ab8500)) ret = sysfs_create_group(&ab8500->dev->kobj, &ab9540_attr_group); else @@ -1735,7 +1737,8 @@ static int ab8500_remove(struct platform_device *pdev) { struct ab8500 *ab8500 = platform_get_drvdata(pdev); - if (is_ab9540(ab8500)) + if (((is_ab8505(ab8500) || is_ab9540(ab8500)) && + ab8500->chip_id >= AB8500_CUT2P0) || is_ab8540(ab8500)) sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group); else sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 55d0ff4f5b23..969e43db8485 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1943,6 +1943,8 @@ static int ab8500_debug_probe(struct platform_device *plf) num_interrupt_lines = AB8505_NR_IRQS; else if (is_ab9540(ab8500)) num_interrupt_lines = AB9540_NR_IRQS; + else if (is_ab8540(ab8500)) + num_interrupt_lines = AB8540_NR_IRQS; file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev, &ab8500_interrupts_fops); -- cgit From 9581ae39de8833a7affaef24caadef2830603fef Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 6 Jul 2012 16:11:50 +0200 Subject: mfd: ab8500-debug: Add support for ab8505 and ab9540 Make it possible to dump all registers in ab8505 and ab9540. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 383 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 372 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 969e43db8485..074eea9e4bfd 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -156,7 +156,9 @@ static struct hwreg_cfg hwreg_cfg = { #define AB8500_REV_REG 0x80 -static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = { +static struct ab8500_prcmu_ranges *debug_ranges; + +struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { [0x0] = { .num_ranges = 0, .range = NULL, @@ -360,7 +362,7 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = { }, { .first = 0xf5, - .last = 0xf6, + .last = 0xf6, }, }, }, @@ -485,6 +487,365 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = { }, }; +struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = { + [0x0] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_SYS_CTRL1_BLOCK] = { + .num_ranges = 5, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x04, + }, + { + .first = 0x42, + .last = 0x42, + }, + { + .first = 0x52, + .last = 0x52, + }, + { + .first = 0x54, + .last = 0x57, + }, + { + .first = 0x80, + .last = 0x83, + }, + }, + }, + [AB8500_SYS_CTRL2_BLOCK] = { + .num_ranges = 5, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x0D, + }, + { + .first = 0x0F, + .last = 0x17, + }, + { + .first = 0x20, + .last = 0x20, + }, + { + .first = 0x30, + .last = 0x30, + }, + { + .first = 0x32, + .last = 0x3A, + }, + }, + }, + [AB8500_REGU_CTRL1] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x03, + .last = 0x11, + }, + { + .first = 0x80, + .last = 0x86, + }, + }, + }, + [AB8500_REGU_CTRL2] = { + .num_ranges = 6, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x06, + }, + { + .first = 0x08, + .last = 0x15, + }, + { + .first = 0x17, + .last = 0x19, + }, + { + .first = 0x1B, + .last = 0x1D, + }, + { + .first = 0x1F, + .last = 0x30, + }, + { + .first = 0x40, + .last = 0x48, + }, + /* 0x80-0x8B is SIM registers and should + * not be accessed from here */ + }, + }, + [AB8500_USB] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x80, + .last = 0x83, + }, + { + .first = 0x87, + .last = 0x8A, + }, + { + .first = 0x91, + .last = 0x94, + }, + }, + }, + [AB8500_TVOUT] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_DBI] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_ECI_AV_ACC] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x80, + .last = 0x82, + }, + }, + }, + [AB8500_RESERVED] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_GPADC] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x08, + }, + }, + }, + [AB8500_CHARGER] = { + .num_ranges = 9, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x02, + .last = 0x03, + }, + { + .first = 0x05, + .last = 0x05, + }, + { + .first = 0x40, + .last = 0x44, + }, + { + .first = 0x50, + .last = 0x57, + }, + { + .first = 0x60, + .last = 0x60, + }, + { + .first = 0xA0, + .last = 0xA7, + }, + { + .first = 0xAF, + .last = 0xB2, + }, + { + .first = 0xC0, + .last = 0xC2, + }, + { + .first = 0xF5, + .last = 0xF5, + }, + }, + }, + [AB8500_GAS_GAUGE] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x07, + .last = 0x0A, + }, + { + .first = 0x10, + .last = 0x14, + }, + }, + }, + [AB8500_AUDIO] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x83, + }, + }, + }, + [AB8500_INTERRUPT] = { + .num_ranges = 11, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x04, + }, + { + .first = 0x06, + .last = 0x07, + }, + { + .first = 0x09, + .last = 0x09, + }, + { + .first = 0x0B, + .last = 0x0C, + }, + { + .first = 0x12, + .last = 0x15, + }, + { + .first = 0x18, + .last = 0x18, + }, + /* Latch registers should not be read here */ + { + .first = 0x40, + .last = 0x44, + }, + { + .first = 0x46, + .last = 0x49, + }, + { + .first = 0x4B, + .last = 0x4D, + }, + { + .first = 0x52, + .last = 0x55, + }, + { + .first = 0x58, + .last = 0x58, + }, + /* LatchHier registers should not be read here */ + }, + }, + [AB8500_RTC] = { + .num_ranges = 2, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x14, + }, + { + .first = 0x16, + .last = 0x17, + }, + }, + }, + [AB8500_MISC] = { + .num_ranges = 8, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x06, + }, + { + .first = 0x10, + .last = 0x16, + }, + { + .first = 0x20, + .last = 0x26, + }, + { + .first = 0x30, + .last = 0x36, + }, + { + .first = 0x40, + .last = 0x46, + }, + { + .first = 0x50, + .last = 0x50, + }, + { + .first = 0x60, + .last = 0x6B, + }, + { + .first = 0x80, + .last = 0x82, + }, + }, + }, + [AB8500_DEVELOPMENT] = { + .num_ranges = 2, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x05, + .last = 0x05, + }, + }, + }, + [AB8500_DEBUG] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x05, + .last = 0x07, + }, + }, + }, + [AB8500_PROD_TEST] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_STE_TEST] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_OTP_EMUL] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x01, + .last = 0x15, + }, + }, + }, +}; + static irqreturn_t ab8500_debug_handler(int irq, void *data) { char buf[16]; @@ -529,9 +890,6 @@ static int ab8500_registers_print(struct device *dev, u32 bank, err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value); if (err < 0) { - dev_err(dev, - "seq_printf overflow bank=0x%02X reg=0x%02X\n", - bank, reg); /* Error is not returned here since * the output is wanted in any case */ return 0; @@ -581,8 +939,6 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p) for (i = 1; i < AB8500_NUM_BANKS; i++) { err = seq_printf(s, " bank 0x%02X:\n", i); - if (err < 0) - dev_err(dev, "seq_printf overflow, bank=0x%02X\n", i); ab8500_registers_print(dev, i, s); } @@ -1937,14 +2293,19 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; - if (is_ab8500(ab8500)) + if (is_ab8500(ab8500)) { + debug_ranges = ab8500_debug_ranges; num_interrupt_lines = AB8500_NR_IRQS; - else if (is_ab8505(ab8500)) + } else if (is_ab8505(ab8500)) { + debug_ranges = ab8505_debug_ranges; num_interrupt_lines = AB8505_NR_IRQS; - else if (is_ab9540(ab8500)) + } else if (is_ab9540(ab8500)) { + debug_ranges = ab8505_debug_ranges; num_interrupt_lines = AB9540_NR_IRQS; - else if (is_ab8540(ab8500)) + } else if (is_ab8540(ab8500)) { + debug_ranges = ab8505_debug_ranges; num_interrupt_lines = AB8540_NR_IRQS; + } file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev, &ab8500_interrupts_fops); -- cgit From 75932094601b404fc9ef28f7b6c0aa83dd619af0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 12 Feb 2013 15:11:19 +0000 Subject: mfd: ab8500-sysctrl: Add new reset function Add a new reset function which uses the AB WD with 0 timeout. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-sysctrl.c | 63 +++++++++++++++++++++++++++++++ include/linux/mfd/abx500/ab8500-sysctrl.h | 6 +++ 2 files changed, 69 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 6ac63a05893c..f43c42b9f32c 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -15,6 +15,12 @@ #include #include +/* RtcCtrl bits */ +#define AB8500_ALARM_MIN_LOW 0x08 +#define AB8500_ALARM_MIN_MID 0x09 +#define RTC_CTRL 0x0B +#define RTC_ALARM_ENABLE 0x4 + static struct device *sysctrl_dev; void ab8500_power_off(void) @@ -79,6 +85,63 @@ shutdown: } } +/* + * Use the AB WD to reset the platform. It will perform a hard + * reset instead of a soft reset. Write the reset reason to + * the AB before reset, which can be read upon restart. + */ +void ab8500_restart(char mode, const char *cmd) +{ + struct ab8500_platform_data *plat; + struct ab8500_sysctrl_platform_data *pdata; + u16 reason = 0; + u8 val; + + if (sysctrl_dev == NULL) { + pr_err("%s: sysctrl not initialized\n", __func__); + return; + } + + plat = dev_get_platdata(sysctrl_dev->parent); + pdata = plat->sysctrl; + if (pdata->reboot_reason_code) + reason = pdata->reboot_reason_code(cmd); + else + pr_warn("[%s] No reboot reason set. Default reason %d\n", + __func__, reason); + + /* + * Disable RTC alarm, just a precaution so that no alarm + * is running when WD reset is executed. + */ + abx500_get_register_interruptible(sysctrl_dev, AB8500_RTC, + RTC_CTRL , &val); + abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, + RTC_CTRL , (val & ~RTC_ALARM_ENABLE)); + + /* + * Android is not using the RTC alarm registers during reboot + * so we borrow them for writing the reason of reset + */ + + /* reason[8 LSB] */ + val = reason & 0xFF; + abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, + AB8500_ALARM_MIN_LOW , val); + + /* reason[8 MSB] */ + val = (reason>>8) & 0xFF; + abx500_set_register_interruptible(sysctrl_dev, AB8500_RTC, + AB8500_ALARM_MIN_MID , val); + + /* Setting WD timeout to 0 */ + ab8500_sysctrl_write(AB8500_MAINWDOGTIMER, 0xFF, 0x0); + + /* Setting the parameters to AB8500 WD*/ + ab8500_sysctrl_write(AB8500_MAINWDOGCTRL, 0xFF, (AB8500_ENABLE_WD | + AB8500_WD_RESTART_ON_EXPIRE | AB8500_KICK_WD)); +} + static inline bool valid_bank(u8 bank) { return ((bank == AB8500_SYS_CTRL1_BLOCK) || diff --git a/include/linux/mfd/abx500/ab8500-sysctrl.h b/include/linux/mfd/abx500/ab8500-sysctrl.h index ebf12e793db9..990bc93f46e1 100644 --- a/include/linux/mfd/abx500/ab8500-sysctrl.h +++ b/include/linux/mfd/abx500/ab8500-sysctrl.h @@ -12,6 +12,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value); int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value); +void ab8500_restart(char mode, const char *cmd); #else @@ -40,6 +41,7 @@ static inline int ab8500_sysctrl_clear(u16 reg, u8 bits) /* Configuration data for SysClkReq1RfClkBuf - SysClkReq8RfClkBuf */ struct ab8500_sysctrl_platform_data { u8 initial_req_buf_config[8]; + u16 (*reboot_reason_code)(const char *cmd); }; /* Registers */ @@ -299,4 +301,8 @@ struct ab8500_sysctrl_platform_data { #define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_MASK 0xFF #define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_SHIFT 0 +#define AB8500_ENABLE_WD 0x1 +#define AB8500_KICK_WD 0x2 +#define AB8500_WD_RESTART_ON_EXPIRE 0x10 + #endif /* __AB8500_SYSCTRL_H */ -- cgit From e4bffe8d8ad9856143b6e941a17870aee37413d7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 11 Feb 2013 10:38:00 +0000 Subject: mfd: ab8500-gpadc: Add support for the AB8540 This patch enables the GPADC to work on AB8540 based platforms. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-gpadc.c | 316 ++++++++++++++++++++++++++++---- include/linux/mfd/abx500/ab8500-gpadc.h | 43 +++-- 2 files changed, 305 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index fc8da4496e84..c985b90577f6 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -37,6 +37,13 @@ #define AB8500_GPADC_AUTODATAL_REG 0x07 #define AB8500_GPADC_AUTODATAH_REG 0x08 #define AB8500_GPADC_MUX_CTRL_REG 0x09 +#define AB8540_GPADC_MANDATA2L_REG 0x09 +#define AB8540_GPADC_MANDATA2H_REG 0x0A +#define AB8540_GPADC_APEAAX_REG 0x10 +#define AB8540_GPADC_APEAAT_REG 0x11 +#define AB8540_GPADC_APEAAM_REG 0x12 +#define AB8540_GPADC_APEAAH_REG 0x13 +#define AB8540_GPADC_APEAAL_REG 0x14 /* * OTP register offsets @@ -49,6 +56,10 @@ #define AB8500_GPADC_CAL_5 0x13 #define AB8500_GPADC_CAL_6 0x14 #define AB8500_GPADC_CAL_7 0x15 +/* New calibration for 8540 */ +#define AB8540_GPADC_OTP4_REG_7 0x38 +#define AB8540_GPADC_OTP4_REG_6 0x39 +#define AB8540_GPADC_OTP4_REG_5 0x3A /* gpadc constants */ #define EN_VINTCORE12 0x04 @@ -67,6 +78,7 @@ #define GPADC_BUSY 0x01 #define EN_FALLING 0x10 #define EN_TRIG_EDGE 0x02 +#define EN_VBIAS_XTAL_TEMP 0x02 /* GPADC constants from AB8500 spec, UM0836 */ #define ADC_RESOLUTION 1024 @@ -85,8 +97,21 @@ #define ADC_CH_BKBAT_MIN 0 #define ADC_CH_BKBAT_MAX 3200 +/* GPADC constants from AB8540 spec */ +#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/ +#define ADC_CH_IBAT_MAX 6000 +#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/ +#define ADC_CH_IBAT_MAX_V 60 +#define IBAT_VDROP_L (-56) /* mV */ +#define IBAT_VDROP_H 56 + /* This is used to not lose precision when dividing to get gain and offset */ -#define CALIB_SCALE 1000 +#define CALIB_SCALE 1000 +/* + * Number of bits shift used to not lose precision + * when dividing to get ibat gain. + */ +#define CALIB_SHIFT_IBAT 20 /* Time in ms before disabling regulator */ #define GPADC_AUDOSUSPEND_DELAY 1 @@ -97,6 +122,7 @@ enum cal_channels { ADC_INPUT_VMAIN = 0, ADC_INPUT_BTEMP, ADC_INPUT_VBAT, + ADC_INPUT_IBAT, NBR_CAL_INPUTS, }; @@ -107,8 +133,8 @@ enum cal_channels { * @offset: Offset of the ADC channel */ struct adc_cal_data { - u64 gain; - u64 offset; + s64 gain; + s64 offset; }; /** @@ -180,6 +206,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE; break; + case XTAL_TEMP: case BAT_CTRL: case BTEMP_BALL: case ACC_DETECT1: @@ -198,6 +225,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, break; case MAIN_BAT_V: + case VBAT_TRUE_MEAS: /* For some reason we don't have calibrated data */ if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) { res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX - @@ -241,6 +269,20 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, ADC_RESOLUTION; break; + case IBAT_VIRTUAL_CHANNEL: + /* For some reason we don't have calibrated data */ + if (!gpadc->cal_data[ADC_INPUT_IBAT].gain) { + res = ADC_CH_IBAT_MIN + (ADC_CH_IBAT_MAX - + ADC_CH_IBAT_MIN) * ad_value / + ADC_RESOLUTION; + break; + } + /* Here we can use the calibrated data */ + res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_IBAT].gain + + gpadc->cal_data[ADC_INPUT_IBAT].offset) + >> CALIB_SHIFT_IBAT; + break; + default: dev_err(gpadc->dev, "unknown channel, not possible to convert\n"); @@ -303,10 +345,20 @@ EXPORT_SYMBOL(ab8500_gpadc_convert); */ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) +{ + int raw_data; + raw_data = ab8500_gpadc_double_read_raw(gpadc, channel, + avg_sample, trig_edge, trig_timer, conv_type, NULL); + return raw_data; +} + +int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type, + int *ibat) { int ret; int looplimit = 0; - u8 val, low_data, high_data; + u8 val, low_data, high_data, low_data2, high_data2; if (!gpadc) return -ENODEV; @@ -359,7 +411,6 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, default: val = channel | AVG_16; break; - } if (conv_type == ADC_HW) @@ -383,8 +434,8 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, ret = abx500_mask_and_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_FALLING, EN_FALLING); - } + switch (channel) { case MAIN_CHARGER_C: case USB_CHARGER_C: @@ -401,6 +452,55 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, EN_BUF | EN_ICHAR, EN_BUF | EN_ICHAR); break; + + case XTAL_TEMP: + if (conv_type == ADC_HW) + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | EN_TRIG_EDGE, + EN_BUF | EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF , + EN_BUF); + break; + + case VBAT_TRUE_MEAS: + if (conv_type == ADC_HW) + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF | EN_TRIG_EDGE, + EN_BUF | EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF , + EN_BUF); + break; + + case BAT_CTRL_AND_IBAT: + case VBAT_MEAS_AND_IBAT: + case VBAT_TRUE_MEAS_AND_IBAT: + case BAT_TEMP_AND_IBAT: + if (conv_type == ADC_HW) + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_TRIG_EDGE, + EN_TRIG_EDGE); + else + ret = abx500_mask_and_set_register_interruptible( + gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, + EN_BUF, + 0); + break; + case BTEMP_BALL: if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { if (conv_type == ADC_HW) @@ -471,21 +571,19 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, /* wait for completion of conversion */ if (conv_type == ADC_HW) { if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, - 2*HZ)) { - dev_err(gpadc->dev, - "timeout didn't receive" - " hw GPADC conv interrupt\n"); - ret = -EINVAL; - goto out; + 2 * HZ)) { + dev_err(gpadc->dev, + "timeout didn't receive hw GPADC conv interrupt\n"); + ret = -EINVAL; + goto out; } } else { if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, - msecs_to_jiffies(CONVERSION_TIME))) { - dev_err(gpadc->dev, - "timeout didn't receive" - " sw GPADC conv interrupt\n"); - ret = -EINVAL; - goto out; + msecs_to_jiffies(CONVERSION_TIME))) { + dev_err(gpadc->dev, + "timeout didn't receive sw GPADC conv interrupt\n"); + ret = -EINVAL; + goto out; } } @@ -523,6 +621,46 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, goto out; } } + /* Check if double convertion is required */ + if ((channel == BAT_CTRL_AND_IBAT) || + (channel == VBAT_MEAS_AND_IBAT) || + (channel == VBAT_TRUE_MEAS_AND_IBAT) || + (channel == BAT_TEMP_AND_IBAT)) { + + if (conv_type == ADC_HW) { + /* not supported */ + ret = -ENOTSUPP; + dev_err(gpadc->dev, + "gpadc_conversion: only SW double conversion supported\n"); + goto out; + } else { + /* Read the converted RAW data 2 */ + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8540_GPADC_MANDATA2L_REG, + &low_data2); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read sw low data 2 failed\n"); + goto out; + } + + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8540_GPADC_MANDATA2H_REG, + &high_data2); + if (ret < 0) { + dev_err(gpadc->dev, + "gpadc_conversion: read sw high data 2 failed\n"); + goto out; + } + if (ibat != NULL) { + *ibat = (high_data2 << 8) | low_data2; + } else { + dev_warn(gpadc->dev, + "gpadc_conversion: ibat not stored\n"); + } + + } + } /* Disable GPADC */ ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, @@ -586,15 +724,27 @@ static int otp_cal_regs[] = { AB8500_GPADC_CAL_7, }; +static int otp4_cal_regs[] = { + AB8540_GPADC_OTP4_REG_7, + AB8540_GPADC_OTP4_REG_6, + AB8540_GPADC_OTP4_REG_5, +}; + static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) { int i; int ret[ARRAY_SIZE(otp_cal_regs)]; u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)]; - + int ret_otp4[ARRAY_SIZE(otp4_cal_regs)]; + u8 gpadc_otp4[ARRAY_SIZE(otp4_cal_regs)]; int vmain_high, vmain_low; int btemp_high, btemp_low; int vbat_high, vbat_low; + int ibat_high, ibat_low; + s64 V_gain, V_offset, V2A_gain, V2A_offset; + struct ab8500 *ab8500; + + ab8500 = gpadc->parent; /* First we read all OTP registers and store the error code */ for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) { @@ -614,7 +764,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) * bt_h/l = btemp_high/low * vb_h/l = vbat_high/low * - * Data bits: + * Data bits 8500/9540: * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 * |.......|.......|.......|.......|.......|.......|.......|....... * | | vm_h9 | vm_h8 @@ -632,6 +782,35 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | * |.......|.......|.......|.......|.......|.......|.......|....... * + * Data bits 8540: + * OTP2 + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | + * |.......|.......|.......|.......|.......|.......|.......|....... + * | vm_h9 | vm_h8 | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | + * |.......|.......|.......|.......|.......|.......|.......|....... + * + * Data bits 8540: + * OTP4 + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | | ib_h9 | ib_h8 | ib_h7 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | ib_h6 | ib_h5 | ib_h4 | ib_h3 | ib_h2 | ib_h1 | ib_h0 | ib_l5 + * |.......|.......|.......|.......|.......|.......|.......|....... + * | ib_l4 | ib_l3 | ib_l2 | ib_l1 | ib_l0 | + * * * Ideal output ADC codes corresponding to injected input voltages * during manufacturing is: @@ -644,38 +823,96 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) * vbat_low: Vin = 2380mV / ADC ideal code = 33 */ - /* Calculate gain and offset for VMAIN if all reads succeeded */ - if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { - vmain_high = (((gpadc_cal[0] & 0x03) << 8) | - ((gpadc_cal[1] & 0x3F) << 2) | - ((gpadc_cal[2] & 0xC0) >> 6)); + if (is_ab8540(ab8500)) { + /* Calculate gain and offset for VMAIN if all reads succeeded*/ + if (!(ret[1] < 0 || ret[2] < 0)) { + vmain_high = (((gpadc_cal[1] & 0xFF) << 2) | + ((gpadc_cal[2] & 0xC0) >> 6)); + vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); + gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * + (19500 - 315) / (vmain_high - vmain_low); + gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * + 19500 - (CALIB_SCALE * (19500 - 315) / + (vmain_high - vmain_low)) * vmain_high; + } else { + gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; + } - vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); + /* Read IBAT calibration Data */ + for (i = 0; i < ARRAY_SIZE(otp4_cal_regs); i++) { + ret_otp4[i] = abx500_get_register_interruptible( + gpadc->dev, AB8500_OTP_EMUL, + otp4_cal_regs[i], &gpadc_otp4[i]); + if (ret_otp4[i] < 0) + dev_err(gpadc->dev, + "%s: read otp4 reg 0x%02x failed\n", + __func__, otp4_cal_regs[i]); + } - gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * - (19500 - 315) / (vmain_high - vmain_low); + /* Calculate gain and offset for IBAT if all reads succeeded */ + if (!(ret_otp4[0] < 0 || ret_otp4[1] < 0 || ret_otp4[2] < 0)) { + ibat_high = (((gpadc_otp4[0] & 0x07) << 7) | + ((gpadc_otp4[1] & 0xFE) >> 1)); + ibat_low = (((gpadc_otp4[1] & 0x01) << 5) | + ((gpadc_otp4[2] & 0xF8) >> 3)); + + V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L) + << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low); + + V_offset = (IBAT_VDROP_H << CALIB_SHIFT_IBAT) - + (((IBAT_VDROP_H - IBAT_VDROP_L) << + CALIB_SHIFT_IBAT) / (ibat_high - ibat_low)) + * ibat_high; + /* + * Result obtained is in mV (at a scale factor), + * we need to calculate gain and offset to get mA + */ + V2A_gain = (ADC_CH_IBAT_MAX - ADC_CH_IBAT_MIN)/ + (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V); + V2A_offset = ((ADC_CH_IBAT_MAX_V * ADC_CH_IBAT_MIN - + ADC_CH_IBAT_MAX * ADC_CH_IBAT_MIN_V) + << CALIB_SHIFT_IBAT) + / (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V); + + gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain; + gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset * + V2A_gain + V2A_offset; + } else { + gpadc->cal_data[ADC_INPUT_IBAT].gain = 0; + } - gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 - - (CALIB_SCALE * (19500 - 315) / - (vmain_high - vmain_low)) * vmain_high; + dev_dbg(gpadc->dev, "IBAT gain %llu offset %llu\n", + gpadc->cal_data[ADC_INPUT_IBAT].gain, + gpadc->cal_data[ADC_INPUT_IBAT].offset); } else { - gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; + /* Calculate gain and offset for VMAIN if all reads succeeded */ + if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { + vmain_high = (((gpadc_cal[0] & 0x03) << 8) | + ((gpadc_cal[1] & 0x3F) << 2) | + ((gpadc_cal[2] & 0xC0) >> 6)); + vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); + + gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * + (19500 - 315) / (vmain_high - vmain_low); + + gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * + 19500 - (CALIB_SCALE * (19500 - 315) / + (vmain_high - vmain_low)) * vmain_high; + } else { + gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; + } } - /* Calculate gain and offset for BTEMP if all reads succeeded */ if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { btemp_high = (((gpadc_cal[2] & 0x01) << 9) | - (gpadc_cal[3] << 1) | - ((gpadc_cal[4] & 0x80) >> 7)); - + (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7)); btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); gpadc->cal_data[ADC_INPUT_BTEMP].gain = CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); - gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - - (CALIB_SCALE * (1300 - 21) / - (btemp_high - btemp_low)) * btemp_high; + (CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low)) + * btemp_high; } else { gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0; } @@ -687,7 +924,6 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * (4700 - 2380) / (vbat_high - vbat_low); - gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - (CALIB_SCALE * (4700 - 2380) / (vbat_high - vbat_low)) * vbat_high; diff --git a/include/linux/mfd/abx500/ab8500-gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h index 7694e7ab1880..4131437ace4b 100644 --- a/include/linux/mfd/abx500/ab8500-gpadc.h +++ b/include/linux/mfd/abx500/ab8500-gpadc.h @@ -12,19 +12,32 @@ /* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2 * and ADCHwSel[4:0] in GPADCCtrl3 ) */ -#define BAT_CTRL 0x01 -#define BTEMP_BALL 0x02 -#define MAIN_CHARGER_V 0x03 -#define ACC_DETECT1 0x04 -#define ACC_DETECT2 0x05 -#define ADC_AUX1 0x06 -#define ADC_AUX2 0x07 -#define MAIN_BAT_V 0x08 -#define VBUS_V 0x09 -#define MAIN_CHARGER_C 0x0A -#define USB_CHARGER_C 0x0B -#define BK_BAT_V 0x0C -#define DIE_TEMP 0x0D +#define BAT_CTRL 0x01 +#define BTEMP_BALL 0x02 +#define MAIN_CHARGER_V 0x03 +#define ACC_DETECT1 0x04 +#define ACC_DETECT2 0x05 +#define ADC_AUX1 0x06 +#define ADC_AUX2 0x07 +#define MAIN_BAT_V 0x08 +#define VBUS_V 0x09 +#define MAIN_CHARGER_C 0x0A +#define USB_CHARGER_C 0x0B +#define BK_BAT_V 0x0C +#define DIE_TEMP 0x0D +#define USB_ID 0x0E +#define XTAL_TEMP 0x12 +#define VBAT_TRUE_MEAS 0x13 +#define BAT_CTRL_AND_IBAT 0x1C +#define VBAT_MEAS_AND_IBAT 0x1D +#define VBAT_TRUE_MEAS_AND_IBAT 0x1E +#define BAT_TEMP_AND_IBAT 0x1F + +/* Virtual channel used only for ibat convertion to ampere + * Battery current conversion (ibat) cannot be requested as a single conversion + * but it is always in combination with other input requests + */ +#define IBAT_VIRTUAL_CHANNEL 0xFF #define SAMPLE_1 1 #define SAMPLE_4 4 @@ -37,7 +50,6 @@ #define ADC_SW 0 #define ADC_HW 1 - struct ab8500_gpadc; struct ab8500_gpadc *ab8500_gpadc_get(char *name); @@ -51,6 +63,9 @@ static inline int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type); +int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type, + int *ibat); int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, int ad_value); -- cgit From bc6b4132bcae4b8e59766ba2dae8f377009b26d0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 14:02:31 +0000 Subject: mfd: ab8500-debug: Add support for the AB8540 Allow GPADC debug information to be shown when executing on an AB8540 based platform. Signed-off-by: Alexandre Bourdiol Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 286 +++++++++++++++++++++++++++++++- drivers/mfd/ab8500-gpadc.c | 44 +++++ include/linux/mfd/abx500/ab8500-gpadc.h | 3 + 3 files changed, 332 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 074eea9e4bfd..1e44d65e1771 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1633,6 +1633,254 @@ static const struct file_operations ab8500_gpadc_die_temp_fops = { .owner = THIS_MODULE, }; +static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p) +{ + int xtal_temp_raw; + int xtal_temp_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + xtal_temp_raw = ab8500_gpadc_read_raw(gpadc, XTAL_TEMP, + avg_sample, trig_edge, trig_timer, conv_type); + xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP, + xtal_temp_raw); + + return seq_printf(s, "%d,0x%X\n", + xtal_temp_convert, xtal_temp_raw); +} + +static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8540_gpadc_xtal_temp_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_xtal_temp_fops = { + .open = ab8540_gpadc_xtal_temp_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p) +{ + int vbat_true_meas_raw; + int vbat_true_meas_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS, + avg_sample, trig_edge, trig_timer, conv_type); + vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS, + vbat_true_meas_raw); + + return seq_printf(s, "%d,0x%X\n", + vbat_true_meas_convert, vbat_true_meas_raw); +} + +static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ab8540_gpadc_vbat_true_meas_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = { + .open = ab8540_gpadc_vbat_true_meas_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p) +{ + int bat_ctrl_raw; + int bat_ctrl_convert; + int ibat_raw; + int ibat_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + bat_ctrl_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_CTRL_AND_IBAT, + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); + + bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, BAT_CTRL, + bat_ctrl_raw); + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, + ibat_raw); + + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", + bat_ctrl_convert, bat_ctrl_raw, + ibat_convert, ibat_raw); +} + +static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = { + .open = ab8540_gpadc_bat_ctrl_and_ibat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p) +{ + int vbat_meas_raw; + int vbat_meas_convert; + int ibat_raw; + int ibat_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + vbat_meas_raw = ab8500_gpadc_double_read_raw(gpadc, VBAT_MEAS_AND_IBAT, + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); + vbat_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V, + vbat_meas_raw); + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, + ibat_raw); + + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", + vbat_meas_convert, vbat_meas_raw, + ibat_convert, ibat_raw); +} + +static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = { + .open = ab8540_gpadc_vbat_meas_and_ibat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p) +{ + int vbat_true_meas_raw; + int vbat_true_meas_convert; + int ibat_raw; + int ibat_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + vbat_true_meas_raw = ab8500_gpadc_double_read_raw(gpadc, + VBAT_TRUE_MEAS_AND_IBAT, avg_sample, trig_edge, + trig_timer, conv_type, &ibat_raw); + vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, + VBAT_TRUE_MEAS, vbat_true_meas_raw); + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, + ibat_raw); + + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", + vbat_true_meas_convert, vbat_true_meas_raw, + ibat_convert, ibat_raw); +} + +static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = { + .open = ab8540_gpadc_vbat_true_meas_and_ibat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p) +{ + int bat_temp_raw; + int bat_temp_convert; + int ibat_raw; + int ibat_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + bat_temp_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_TEMP_AND_IBAT, + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); + bat_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL, + bat_temp_raw); + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, + ibat_raw); + + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", + bat_temp_convert, bat_temp_raw, + ibat_convert, ibat_raw); +} + +static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print, + inode->i_private); +} + +static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = { + .open = ab8540_gpadc_bat_temp_and_ibat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p) +{ + struct ab8500_gpadc *gpadc; + u16 vmain_l, vmain_h, btemp_l, btemp_h; + u16 vbat_l, vbat_h, ibat_l, ibat_h; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h, + &vbat_l, &vbat_h, &ibat_l, &ibat_h); + return seq_printf(s, "VMAIN_L:0x%X\n" + "VMAIN_H:0x%X\n" + "BTEMP_L:0x%X\n" + "BTEMP_H:0x%X\n" + "VBAT_L:0x%X\n" + "VBAT_H:0x%X\n" + "IBAT_L:0x%X\n" + "IBAT_H:0x%X\n" + , + vmain_l, + vmain_h, + btemp_l, + btemp_h, + vbat_l, + vbat_h, + ibat_l, + ibat_h); +} + +static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private); +} + +static const struct file_operations ab8540_gpadc_otp_calib_fops = { + .open = ab8540_gpadc_otp_cal_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p) { return seq_printf(s, "%d\n", avg_sample); @@ -2386,7 +2634,43 @@ static int ab8500_debug_probe(struct platform_device *plf) ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); if (!file) goto err; - + if (is_ab8540(ab8500)) { + file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops); + if (!file) + goto err; + file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, + &ab8540_gpadc_vbat_true_meas_fops); + if (!file) + goto err; + file = debugfs_create_file("batctrl_and_ibat", + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops); + if (!file) + goto err; + file = debugfs_create_file("vbatmeas_and_ibat", + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, + &ab8540_gpadc_vbat_meas_and_ibat_fops); + if (!file) + goto err; + file = debugfs_create_file("vbattruemeas_and_ibat", + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, + &ab8540_gpadc_vbat_true_meas_and_ibat_fops); + if (!file) + goto err; + file = debugfs_create_file("battemp_and_ibat", + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); + if (!file) + goto err; + file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops); + if (!file) + goto err; + } file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops); if (!file) diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index c985b90577f6..e3535c74d5fe 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -135,6 +135,8 @@ enum cal_channels { struct adc_cal_data { s64 gain; s64 offset; + u16 otp_calib_hi; + u16 otp_calib_lo; }; /** @@ -829,6 +831,12 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) vmain_high = (((gpadc_cal[1] & 0xFF) << 2) | ((gpadc_cal[2] & 0xC0) >> 6)); vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); + + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = + (u16)vmain_high; + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = + (u16)vmain_low; + gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * (19500 - 315) / (vmain_high - vmain_low); gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * @@ -856,6 +864,11 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) ibat_low = (((gpadc_otp4[1] & 0x01) << 5) | ((gpadc_otp4[2] & 0xF8) >> 3)); + gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi = + (u16)ibat_high; + gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo = + (u16)ibat_low; + V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L) << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low); @@ -892,6 +905,11 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) ((gpadc_cal[2] & 0xC0) >> 6)); vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = + (u16)vmain_high; + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = + (u16)vmain_low; + gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * (19500 - 315) / (vmain_high - vmain_low); @@ -902,12 +920,16 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; } } + /* Calculate gain and offset for BTEMP if all reads succeeded */ if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { btemp_high = (((gpadc_cal[2] & 0x01) << 9) | (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7)); btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); + gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi = (u16)btemp_high; + gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo = (u16)btemp_low; + gpadc->cal_data[ADC_INPUT_BTEMP].gain = CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - @@ -922,6 +944,9 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]); vbat_low = ((gpadc_cal[6] & 0xFC) >> 2); + gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi = (u16)vbat_high; + gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo = (u16)vbat_low; + gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * (4700 - 2380) / (vbat_high - vbat_low); gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - @@ -1131,6 +1156,25 @@ static void __exit ab8500_gpadc_exit(void) platform_driver_unregister(&ab8500_gpadc_driver); } +/** + * ab8540_gpadc_get_otp() - returns OTP values + * + */ +void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, + u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, + u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h) +{ + *vmain_l = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo; + *vmain_h = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi; + *btemp_l = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo; + *btemp_h = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi; + *vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo; + *vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi; + *ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo; + *ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi; + return ; +} + subsys_initcall_sync(ab8500_gpadc_init); module_exit(ab8500_gpadc_exit); diff --git a/include/linux/mfd/abx500/ab8500-gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h index 4131437ace4b..49ded001049b 100644 --- a/include/linux/mfd/abx500/ab8500-gpadc.h +++ b/include/linux/mfd/abx500/ab8500-gpadc.h @@ -68,5 +68,8 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, int *ibat); int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, int ad_value); +void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, + u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, + u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h); #endif /* _AB8500_GPADC_H */ -- cgit From 7c8f023616f89c3796331cece68b7efdc5a0b1ca Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 11 Feb 2013 10:49:41 +0000 Subject: mfd: ab8500-gpadc: Optimise GPADC driver Optimise GPADC driver: * for code readability and maintenance by grouping similar cheking * for performance by grouping several writing to control register Signed-off-by: Alexandre Bourdiol Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-gpadc.c | 212 ++++++++++++--------------------------------- 1 file changed, 55 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index e3535c74d5fe..af1db2a45e86 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -360,7 +360,12 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, { int ret; int looplimit = 0; + unsigned long completion_timeout; u8 val, low_data, high_data, low_data2, high_data2; + u8 val_reg1 = 0; + unsigned int delay_min = 0; + unsigned int delay_max = 0; + u8 data_low_addr, data_high_addr; if (!gpadc) return -ENODEV; @@ -392,12 +397,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, } /* Enable GPADC */ - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC); - if (ret < 0) { - dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n"); - goto out; - } + val_reg1 |= EN_GPADC; /* Select the channel source and set average samples */ switch (avg_sample) { @@ -415,9 +415,13 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, break; } - if (conv_type == ADC_HW) + if (conv_type == ADC_HW) { ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val); + val_reg1 |= EN_TRIG_EDGE; + if (trig_edge) + val_reg1 |= EN_FALLING; + } else ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val); @@ -432,123 +436,42 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, * charging current sense if it needed, ABB 3.0 needs some special * treatment too. */ - if ((conv_type == ADC_HW) && (trig_edge)) { - ret = abx500_mask_and_set_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_FALLING, EN_FALLING); - } - switch (channel) { case MAIN_CHARGER_C: case USB_CHARGER_C: - if (conv_type == ADC_HW) - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_ICHAR | EN_TRIG_EDGE, - EN_BUF | EN_ICHAR | EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_ICHAR, - EN_BUF | EN_ICHAR); - break; - - case XTAL_TEMP: - if (conv_type == ADC_HW) - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_TRIG_EDGE, - EN_BUF | EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF , - EN_BUF); - break; - - case VBAT_TRUE_MEAS: - if (conv_type == ADC_HW) - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_TRIG_EDGE, - EN_BUF | EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF , - EN_BUF); - break; - - case BAT_CTRL_AND_IBAT: - case VBAT_MEAS_AND_IBAT: - case VBAT_TRUE_MEAS_AND_IBAT: - case BAT_TEMP_AND_IBAT: - if (conv_type == ADC_HW) - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_TRIG_EDGE, - EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF, - 0); + val_reg1 |= EN_BUF | EN_ICHAR; break; - case BTEMP_BALL: if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { - if (conv_type == ADC_HW) - /* Turn on btemp pull-up on ABB 3.0 */ - ret = abx500_mask_and_set_register_interruptible - (gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE, - EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible - (gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | BTEMP_PULL_UP, - EN_BUF | BTEMP_PULL_UP); - - /* - * Delay might be needed for ABB8500 cut 3.0, if not, remove - * when hardware will be available - */ - usleep_range(1000, 1000); + val_reg1 |= EN_BUF | BTEMP_PULL_UP; + /* + * Delay might be needed for ABB8500 cut 3.0, if not, + * remove when hardware will be availible + */ + delay_min = 1000; /* Delay in micro seconds */ + delay_max = 10000; /* large range to optimise sleep mode */ break; } /* Intentional fallthrough */ default: - if (conv_type == ADC_HW) - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, AB8500_GPADC_CTRL1_REG, - EN_BUF | EN_TRIG_EDGE, - EN_BUF | EN_TRIG_EDGE); - else - ret = abx500_mask_and_set_register_interruptible( - gpadc->dev, - AB8500_GPADC, - AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF); + val_reg1 |= EN_BUF; break; } + + /* Write configuration to register */ + ret = abx500_set_register_interruptible(gpadc->dev, + AB8500_GPADC, AB8500_GPADC_CTRL1_REG, val_reg1); if (ret < 0) { dev_err(gpadc->dev, - "gpadc_conversion: select falling edge failed\n"); + "gpadc_conversion: set Control register failed\n"); goto out; } - /* Set trigger delay timer */ + if (delay_min != 0) + usleep_range(delay_min, delay_max); + if (conv_type == ADC_HW) { + /* Set trigger delay timer */ ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer); if (ret < 0) { @@ -556,10 +479,11 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, "gpadc_conversion: trig timer failed\n"); goto out; } - } - - /* Start SW conversion */ - if (conv_type == ADC_SW) { + completion_timeout = 2 * HZ; + data_low_addr = AB8500_GPADC_AUTODATAL_REG; + data_high_addr = AB8500_GPADC_AUTODATAH_REG; + } else { + /* Start SW conversion */ ret = abx500_mask_and_set_register_interruptible(gpadc->dev, AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV); @@ -568,61 +492,35 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, "gpadc_conversion: start s/w conv failed\n"); goto out; } + completion_timeout = msecs_to_jiffies(CONVERSION_TIME); + data_low_addr = AB8500_GPADC_MANDATAL_REG; + data_high_addr = AB8500_GPADC_MANDATAH_REG; } /* wait for completion of conversion */ - if (conv_type == ADC_HW) { - if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, - 2 * HZ)) { - dev_err(gpadc->dev, - "timeout didn't receive hw GPADC conv interrupt\n"); - ret = -EINVAL; - goto out; - } - } else { - if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, - msecs_to_jiffies(CONVERSION_TIME))) { - dev_err(gpadc->dev, - "timeout didn't receive sw GPADC conv interrupt\n"); - ret = -EINVAL; - goto out; - } + if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, + completion_timeout)) { + dev_err(gpadc->dev, + "timeout didn't receive GPADC conv interrupt\n"); + ret = -EINVAL; + goto out; } /* Read the converted RAW data */ - if (conv_type == ADC_HW) { - ret = abx500_get_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_AUTODATAL_REG, &low_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read hw low data failed\n"); - goto out; - } - - ret = abx500_get_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_AUTODATAH_REG, &high_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read hw high data failed\n"); - goto out; - } - } else { - ret = abx500_get_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_MANDATAL_REG, &low_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read sw low data failed\n"); - goto out; - } + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, data_low_addr, &low_data); + if (ret < 0) { + dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n"); + goto out; + } - ret = abx500_get_register_interruptible(gpadc->dev, - AB8500_GPADC, AB8500_GPADC_MANDATAH_REG, &high_data); - if (ret < 0) { - dev_err(gpadc->dev, - "gpadc_conversion: read sw high data failed\n"); - goto out; - } + ret = abx500_get_register_interruptible(gpadc->dev, + AB8500_GPADC, data_high_addr, &high_data); + if (ret < 0) { + dev_err(gpadc->dev, "gpadc_conversion: read high data failed\n"); + goto out; } + /* Check if double convertion is required */ if ((channel == BAT_CTRL_AND_IBAT) || (channel == VBAT_MEAS_AND_IBAT) || -- cgit From 492390c8fd4a90b1e4ca371c8f8a23c63b04d7f9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 15:06:18 +0000 Subject: mfd: ab8500-core: Add additional resources to ab8505_iddet_resources Add VBUS_DET_R, VBUS_DET_F IRQ, ID_DET_PLUGR and ID_DET_PLUGF IRQ information to ab8505_iddet_resources. These are required to get interrupts for AB8505 cut-2. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 0fc18e91310c..141572c6c392 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1016,6 +1016,30 @@ static struct resource ab8505_iddet_resources[] = { .end = AB8505_INT_KEYSTUCK, .flags = IORESOURCE_IRQ, }, + { + .name = "VBUS_DET_R", + .start = AB8500_INT_VBUS_DET_R, + .end = AB8500_INT_VBUS_DET_R, + .flags = IORESOURCE_IRQ, + }, + { + .name = "VBUS_DET_F", + .start = AB8500_INT_VBUS_DET_F, + .end = AB8500_INT_VBUS_DET_F, + .flags = IORESOURCE_IRQ, + }, + { + .name = "ID_DET_PLUGR", + .start = AB8500_INT_ID_DET_PLUGR, + .end = AB8500_INT_ID_DET_PLUGR, + .flags = IORESOURCE_IRQ, + }, + { + .name = "ID_DET_PLUGF", + .start = AB8500_INT_ID_DET_PLUGF, + .end = AB8500_INT_ID_DET_PLUGF, + .flags = IORESOURCE_IRQ, + }, }; static struct resource ab8500_temp_resources[] = { -- cgit From c55355221e259bc4d6c1dc3ebe0852afce644a40 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 22 Aug 2012 13:08:11 +0200 Subject: mfd: ab8500-sysctrl: AB8505 doesn't have SYSCLKREQ5..8 So we're removing support for it. Signed-off-by: Rabin Vincent Signed-off-by: Lee Jones Tested-by: Marcus COOPER Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-sysctrl.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index f43c42b9f32c..272479cdb107 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -182,9 +182,9 @@ EXPORT_SYMBOL(ab8500_sysctrl_write); static int ab8500_sysctrl_probe(struct platform_device *pdev) { + struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_platform_data *plat; struct ab8500_sysctrl_platform_data *pdata; - int ret, i, j; plat = dev_get_platdata(pdev->dev.parent); @@ -196,20 +196,27 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev) pdata = plat->sysctrl; - - for (i = AB8500_SYSCLKREQ1RFCLKBUF; - i <= AB8500_SYSCLKREQ8RFCLKBUF; i++) { - j = i - AB8500_SYSCLKREQ1RFCLKBUF; - ret = ab8500_sysctrl_write(i, 0xff, - pdata->initial_req_buf_config[j]); - dev_dbg(&pdev->dev, - "Setting SysClkReq%dRfClkBuf 0x%X\n", - j + 1, - pdata->initial_req_buf_config[j]); - if (ret < 0) { - dev_err(&pdev->dev, - "unable to set sysClkReq%dRfClkBuf: " - "%d\n", j + 1, ret); + if (pdata) { + int last, ret, i, j; + + if (is_ab8505(ab8500)) + last = AB8500_SYSCLKREQ4RFCLKBUF; + else + last = AB8500_SYSCLKREQ8RFCLKBUF; + + for (i = AB8500_SYSCLKREQ1RFCLKBUF; i <= last; i++) { + j = i - AB8500_SYSCLKREQ1RFCLKBUF; + ret = ab8500_sysctrl_write(i, 0xff, + pdata->initial_req_buf_config[j]); + dev_dbg(&pdev->dev, + "Setting SysClkReq%dRfClkBuf 0x%X\n", + j + 1, + pdata->initial_req_buf_config[j]); + if (ret < 0) { + dev_err(&pdev->dev, + "unable to set sysClkReq%dRfClkBuf: " + "%d\n", j + 1, ret); + } } } -- cgit From c7ebaee292fb0f935752d50ef9bad1db74efde6e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 14:03:33 +0000 Subject: mfd: ab8500-debugfs: Dump sim registers This patch allows to dump the SIM registers from debugfs. It will temporary change the config to allow APE side to read the SIM registers. Note that this read can cause problem on modem side since the modem can't read these registers while the operation is ongoing. Signed-off-by: Mattias Wallin Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Jonas ABERG Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 1e44d65e1771..a653a0747b31 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1244,6 +1244,79 @@ static int ab8500_hwreg_open(struct inode *inode, struct file *file) return single_open(file, ab8500_hwreg_print, inode->i_private); } +#define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01 +#define AB8500_SUPPLY_CONTROL_REG 0x00 +#define AB8500_FIRST_SIM_REG 0x80 +#define AB8500_LAST_SIM_REG 0x8B +#define AB8505_LAST_SIM_REG 0x8C + +static int ab8500_print_modem_registers(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + struct ab8500 *ab8500; + int err; + u8 value; + u8 orig_value; + u32 bank = AB8500_REGU_CTRL2; + u32 last_sim_reg = AB8500_LAST_SIM_REG; + u32 reg; + + ab8500 = dev_get_drvdata(dev->parent); + dev_warn(dev, "WARNING! This operation can interfer with modem side\n" + "and should only be done with care\n"); + + err = abx500_get_register_interruptible(dev, + AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value); + if (err < 0) { + dev_err(dev, "ab->read fail %d\n", err); + return err; + } + /* Config 1 will allow APE side to read SIM registers */ + err = abx500_set_register_interruptible(dev, + AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, + AB8500_SUPPLY_CONTROL_CONFIG_1); + if (err < 0) { + dev_err(dev, "ab->write fail %d\n", err); + return err; + } + + seq_printf(s, " bank 0x%02X:\n", bank); + + if (is_ab9540(ab8500) || is_ab8505(ab8500)) + last_sim_reg = AB8505_LAST_SIM_REG; + + for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) { + err = abx500_get_register_interruptible(dev, + bank, reg, &value); + if (err < 0) { + dev_err(dev, "ab->read fail %d\n", err); + return err; + } + err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", + bank, reg, value); + } + err = abx500_set_register_interruptible(dev, + AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value); + if (err < 0) { + dev_err(dev, "ab->write fail %d\n", err); + return err; + } + return 0; +} + +static int ab8500_modem_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_print_modem_registers, inode->i_private); +} + +static const struct file_operations ab8500_modem_fops = { + .open = ab8500_modem_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p) { int bat_ctrl_raw; @@ -2570,6 +2643,11 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; + file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUGO), + ab8500_dir, &plf->dev, &ab8500_modem_fops); + if (!file) + goto err; + file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops); if (!file) -- cgit From 127629d74efff202372fbd6097e607fcb2c8a7af Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 14:04:37 +0000 Subject: mfd: ab8500-debug: Add ADC input channel usb_id in debugfs Signed-off-by: Yang QU Signed-off-by: Lee Jones Reviewed-by: Alexandre BOURDIOL Reviewed-by: Philippe LANGLAIS Reviewed-by: Mattias WALLIN Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index a653a0747b31..44c9bc1f2544 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1706,6 +1706,35 @@ static const struct file_operations ab8500_gpadc_die_temp_fops = { .owner = THIS_MODULE, }; +static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p) +{ + int usb_id_raw; + int usb_id_convert; + struct ab8500_gpadc *gpadc; + + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); + usb_id_raw = ab8500_gpadc_read_raw(gpadc, USB_ID, + avg_sample, trig_edge, trig_timer, conv_type); + usb_id_convert = ab8500_gpadc_ad_to_voltage(gpadc, USB_ID, + usb_id_raw); + + return seq_printf(s, "%d,0x%X\n", + usb_id_convert, usb_id_raw); +} + +static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab8500_gpadc_usb_id_print, inode->i_private); +} + +static const struct file_operations ab8500_gpadc_usb_id_fops = { + .open = ab8500_gpadc_usb_id_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p) { int xtal_temp_raw; @@ -2712,6 +2741,12 @@ static int ab8500_debug_probe(struct platform_device *plf) ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); if (!file) goto err; + + file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUGO), + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_id_fops); + if (!file) + goto err; + if (is_ab8540(ab8500)) { file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops); -- cgit From abee26cdb685fa47d3d17ec9cf39f6149ce67083 Mon Sep 17 00:00:00 2001 From: Mattias Wallin Date: Fri, 28 Sep 2012 09:34:24 +0200 Subject: mfd: ab8500-core: Show turn on status at boot Several states can be detected when a device is initially turned on. This patch displays these states in the log. If none of the states are true, then we report that too. Signed-off-by: Mattias Wallin Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Jonas ABERG Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 141572c6c392..a4120edbccf2 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1542,6 +1542,15 @@ static int ab8500_probe(struct platform_device *pdev) "Battery level lower than power on reset threshold", "Power on key 1 pressed longer than 10 seconds", "DB8500 thermal shutdown"}; + static char *turn_on_status[] = { + "Battery rising (Vbat)", + "Power On Key 1 dbF", + "Power On Key 2 dbF", + "RTC Alarm", + "Main Charger Detect", + "Vbus Detect (USB)", + "USB ID Detect", + "UART Factory Mode Detect"}; struct ab8500_platform_data *plat = dev_get_platdata(&pdev->dev); const struct platform_device_id *platid = platform_get_device_id(pdev); enum ab8500_version version = AB8500_VERSION_UNDEFINED; @@ -1655,9 +1664,26 @@ static int ab8500_probe(struct platform_device *pdev) } else { printk(KERN_CONT " None\n"); } + ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK, + AB8500_TURN_ON_STATUS, &value); + if (ret < 0) + return ret; + dev_info(ab8500->dev, "turn on reason(s) (%#x): ", value); + + if (value) { + for (i = 0; i < ARRAY_SIZE(turn_on_status); i++) { + if (value & 1) + printk("\"%s\" ", turn_on_status[i]); + value = value >> 1; + } + printk("\n"); + } else { + printk("None\n"); + } if (plat && plat->init) plat->init(ab8500); + if (is_ab9540(ab8500)) { ret = get_register_interruptible(ab8500, AB8500_CHARGER, AB8500_CH_USBCH_STAT1_REG, &value); -- cgit From f38487f22dee6eaca8d06cac99377693803cda8f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 14:09:08 +0000 Subject: mfd: ab8500-debugfs: Change AB8500 debug permissions Enable group write permissions for ab8500 debug MFD driver. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 44c9bc1f2544..4779e2f834b4 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -2623,22 +2623,22 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; - file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_bank_fops); if (!file) goto err; - file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_address_fops); if (!file) goto err; - file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_val_fops); if (!file) goto err; - file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_subscribe_fops); if (!file) goto err; @@ -2662,97 +2662,97 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; - file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); if (!file) goto err; - file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_hwreg_fops); if (!file) goto err; - file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, &plf->dev, &ab8500_modem_fops); if (!file) goto err; - file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops); if (!file) goto err; - file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops); if (!file) goto err; - file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops); if (!file) goto err; - file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops); if (!file) goto err; - file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops); if (!file) goto err; - file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops); if (!file) goto err; - file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops); if (!file) goto err; - file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops); if (!file) goto err; - file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops); if (!file) goto err; - file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops); if (!file) goto err; - file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops); if (!file) goto err; - file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops); if (!file) goto err; - file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR), + file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); if (!file) goto err; - file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_id_fops); if (!file) goto err; if (is_ab8540(ab8500)) { - file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops); if (!file) goto err; - file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_vbat_true_meas_fops); if (!file) @@ -2779,27 +2779,27 @@ static int ab8500_debug_probe(struct platform_device *plf) &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); if (!file) goto err; - file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops); if (!file) goto err; } - file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops); if (!file) goto err; - file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops); if (!file) goto err; - file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops); if (!file) goto err; - file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUGO), + file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops); if (!file) goto err; -- cgit From 971480f520a5ed9e54443a9b2b5711eedf51c77a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 19 Nov 2012 12:20:03 +0100 Subject: mfd: ab8500-debug: Add register map for ab8540. Required to read out correct debug information from the AB chip. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 422 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 419 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 4779e2f834b4..862dbfeb619e 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -846,6 +846,422 @@ struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = { }, }; +struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = { + [AB8500_M_FSM_RANK] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x0B, + }, + }, + }, + [AB8500_SYS_CTRL1_BLOCK] = { + .num_ranges = 6, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x04, + }, + { + .first = 0x42, + .last = 0x42, + }, + { + .first = 0x50, + .last = 0x54, + }, + { + .first = 0x57, + .last = 0x57, + }, + { + .first = 0x80, + .last = 0x83, + }, + { + .first = 0x90, + .last = 0x90, + }, + }, + }, + [AB8500_SYS_CTRL2_BLOCK] = { + .num_ranges = 5, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x0D, + }, + { + .first = 0x0F, + .last = 0x10, + }, + { + .first = 0x20, + .last = 0x21, + }, + { + .first = 0x32, + .last = 0x3C, + }, + { + .first = 0x40, + .last = 0x42, + }, + }, + }, + [AB8500_REGU_CTRL1] = { + .num_ranges = 4, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x03, + .last = 0x15, + }, + { + .first = 0x20, + .last = 0x20, + }, + { + .first = 0x80, + .last = 0x85, + }, + { + .first = 0x87, + .last = 0x88, + }, + }, + }, + [AB8500_REGU_CTRL2] = { + .num_ranges = 8, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x06, + }, + { + .first = 0x08, + .last = 0x15, + }, + { + .first = 0x17, + .last = 0x19, + }, + { + .first = 0x1B, + .last = 0x1D, + }, + { + .first = 0x1F, + .last = 0x2F, + }, + { + .first = 0x31, + .last = 0x3A, + }, + { + .first = 0x43, + .last = 0x44, + }, + { + .first = 0x48, + .last = 0x49, + }, + }, + }, + [AB8500_USB] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x80, + .last = 0x83, + }, + { + .first = 0x87, + .last = 0x8A, + }, + { + .first = 0x91, + .last = 0x94, + }, + }, + }, + [AB8500_TVOUT] = { + .num_ranges = 0, + .range = NULL + }, + [AB8500_DBI] = { + .num_ranges = 4, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x07, + }, + { + .first = 0x10, + .last = 0x11, + }, + { + .first = 0x20, + .last = 0x21, + }, + { + .first = 0x30, + .last = 0x43, + }, + }, + }, + [AB8500_ECI_AV_ACC] = { + .num_ranges = 2, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x03, + }, + { + .first = 0x80, + .last = 0x82, + }, + }, + }, + [AB8500_RESERVED] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_GPADC] = { + .num_ranges = 4, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x01, + }, + { + .first = 0x04, + .last = 0x06, + }, + { + .first = 0x09, + .last = 0x0A, + }, + { + .first = 0x10, + .last = 0x14, + }, + }, + }, + [AB8500_CHARGER] = { + .num_ranges = 10, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x02, + .last = 0x05, + }, + { + .first = 0x40, + .last = 0x44, + }, + { + .first = 0x50, + .last = 0x57, + }, + { + .first = 0x60, + .last = 0x60, + }, + { + .first = 0x70, + .last = 0x70, + }, + { + .first = 0xA0, + .last = 0xA9, + }, + { + .first = 0xAF, + .last = 0xB2, + }, + { + .first = 0xC0, + .last = 0xC6, + }, + { + .first = 0xF5, + .last = 0xF5, + }, + }, + }, + [AB8500_GAS_GAUGE] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x07, + .last = 0x0A, + }, + { + .first = 0x10, + .last = 0x14, + }, + }, + }, + [AB8500_AUDIO] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x9f, + }, + }, + }, + [AB8500_INTERRUPT] = { + .num_ranges = 6, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x05, + }, + { + .first = 0x0B, + .last = 0x0D, + }, + { + .first = 0x12, + .last = 0x20, + }, + /* Latch registers should not be read here */ + { + .first = 0x40, + .last = 0x45, + }, + { + .first = 0x4B, + .last = 0x4D, + }, + { + .first = 0x52, + .last = 0x60, + }, + /* LatchHier registers should not be read here */ + }, + }, + [AB8500_RTC] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x07, + }, + { + .first = 0x0B, + .last = 0x18, + }, + { + .first = 0x20, + .last = 0x25, + }, + }, + }, + [AB8500_MISC] = { + .num_ranges = 9, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x06, + }, + { + .first = 0x10, + .last = 0x16, + }, + { + .first = 0x20, + .last = 0x26, + }, + { + .first = 0x30, + .last = 0x36, + }, + { + .first = 0x40, + .last = 0x49, + }, + { + .first = 0x50, + .last = 0x50, + }, + { + .first = 0x60, + .last = 0x6B, + }, + { + .first = 0x70, + .last = 0x74, + }, + { + .first = 0x80, + .last = 0x82, + }, + }, + }, + [AB8500_DEVELOPMENT] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x01, + }, + { + .first = 0x06, + .last = 0x06, + }, + { + .first = 0x10, + .last = 0x21, + }, + }, + }, + [AB8500_DEBUG] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x01, + .last = 0x0C, + }, + { + .first = 0x0E, + .last = 0x11, + }, + { + .first = 0x80, + .last = 0x81, + }, + }, + }, + [AB8500_PROD_TEST] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_STE_TEST] = { + .num_ranges = 0, + .range = NULL, + }, + [AB8500_OTP_EMUL] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x3F, + }, + }, + }, +}; + + static irqreturn_t ab8500_debug_handler(int irq, void *data) { char buf[16]; @@ -937,7 +1353,7 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p) seq_printf(s, AB8500_NAME_STRING " register values:\n"); - for (i = 1; i < AB8500_NUM_BANKS; i++) { + for (i = 0; i < AB8500_NUM_BANKS; i++) { err = seq_printf(s, " bank 0x%02X:\n", i); ab8500_registers_print(dev, i, s); @@ -979,7 +1395,7 @@ void ab8500_dump_all_banks_to_mem(void) pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" " "for crash analyze.\n"); - for (bank = 1; bank < AB8500_NUM_BANKS; bank++) { + for (bank = 0; bank < AB8500_NUM_BANKS; bank++) { for (i = 0; i < debug_ranges[bank].num_ranges; i++) { u8 reg; @@ -2653,7 +3069,7 @@ static int ab8500_debug_probe(struct platform_device *plf) debug_ranges = ab8505_debug_ranges; num_interrupt_lines = AB9540_NR_IRQS; } else if (is_ab8540(ab8500)) { - debug_ranges = ab8505_debug_ranges; + debug_ranges = ab8540_debug_ranges; num_interrupt_lines = AB8540_NR_IRQS; } -- cgit From 9ee17676a5a36621db020c596e766fec24aae959 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 20 Nov 2012 14:57:25 +0100 Subject: mfd: ab8500-core: Add abx500-clk as an mfd child device Hierarchically, the abx500-clk shall be considered as a child of the ab8500 core. The abx500-clk is intiated at arch init and thus the clks will be available when clients needs them. Signed-off-by: Ulf Hansson Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Reviewed-by: Patrice CHOTARD Reviewed-by: Gabriel FERNANDEZ Reviewed-by: Philippe BEGNIC Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index a4120edbccf2..caab1fd3a03f 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1188,6 +1188,10 @@ static struct mfd_cell ab9540_devs[] = { { .name = "ab8500-regulator", }, + { + .name = "abx500-clk", + .of_compatible = "stericsson,abx500-clk", + }, { .name = "ab8500-gpadc", .of_compatible = "stericsson,ab8500-gpadc", @@ -1255,6 +1259,10 @@ static struct mfd_cell ab8505_devs[] = { { .name = "ab8500-regulator", }, + { + .name = "abx500-clk", + .of_compatible = "stericsson,abx500-clk", + }, { .name = "ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), @@ -1314,6 +1322,10 @@ static struct mfd_cell ab8540_devs[] = { { .name = "ab8500-regulator", }, + { + .name = "abx500-clk", + .of_compatible = "stericsson,abx500-clk", + }, { .name = "ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), -- cgit From eb1f95872a053c5aed3e3d13234f8f68e3b2a55a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 22 Nov 2012 18:50:06 +0100 Subject: mfd: ab8500-debug: Add explicit dependencies As I am working on SPARSE_IRQ a number of implicit resource grabs in the kernel become evident. For example, some includes like would implicitly include and then from there . In many cases it is masking the fact that drivers do not properly use resources to pass their dependencies, base addresses etc. So write explicit #include statements with TODO items to have this fixed the proper way to all drivers doing this. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 862dbfeb619e..810ac6faabba 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -91,6 +91,9 @@ #include #endif +/* TODO: this file should not reference IRQ_DB8500_AB8500! */ +#include + static u32 debug_bank; static u32 debug_address; -- cgit From 7b830ae4e538cf04d3b57432bb08f58b828dbafa Mon Sep 17 00:00:00 2001 From: srinidhi kasagar Date: Fri, 23 Nov 2012 15:11:00 +0530 Subject: mfd: ab8500-debug: Convert to kstrtoul_from_user Use kstrtoul_from_user for getting an unsigned long from userspace which is less error prone. Signed-off-by: srinidhi kasagar Signed-off-by: Linus Walleij Signed-off-by: Lee Jones Reviewed-by: Jonas ABERG Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 100 +++++++++++++------------------------------ 1 file changed, 30 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 810ac6faabba..e33c1628c65b 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1479,7 +1479,6 @@ static ssize_t ab8500_bank_write(struct file *file, unsigned long user_bank; int err; - /* Get userspace string and assure termination */ err = kstrtoul_from_user(user_buf, count, 0, &user_bank); if (err) return err; @@ -1512,7 +1511,6 @@ static ssize_t ab8500_address_write(struct file *file, unsigned long user_address; int err; - /* Get userspace string and assure termination */ err = kstrtoul_from_user(user_buf, count, 0, &user_address); if (err) return err; @@ -1522,6 +1520,7 @@ static ssize_t ab8500_address_write(struct file *file, return -EINVAL; } debug_address = user_address; + return count; } @@ -1556,7 +1555,6 @@ static ssize_t ab8500_val_write(struct file *file, unsigned long user_val; int err; - /* Get userspace string and assure termination */ err = kstrtoul_from_user(user_buf, count, 0, &user_val); if (err) return err; @@ -2418,20 +2416,13 @@ static ssize_t ab8500_gpadc_avg_sample_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_avg_sample; int err; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_avg_sample); + err = kstrtoul_from_user(user_buf, count, 0, &user_avg_sample); if (err) - return -EINVAL; + return err; + if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4) || (user_avg_sample == SAMPLE_8) || (user_avg_sample == SAMPLE_16)) { @@ -2441,7 +2432,8 @@ static ssize_t ab8500_gpadc_avg_sample_write(struct file *file, "should be egal to 1, 4, 8 or 16\n"); return -EINVAL; } - return buf_size; + + return count; } static const struct file_operations ab8500_gpadc_avg_sample_fops = { @@ -2469,20 +2461,13 @@ static ssize_t ab8500_gpadc_trig_edge_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_trig_edge; int err; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_trig_edge); + err = kstrtoul_from_user(user_buf, count, 0, &user_trig_edge); if (err) - return -EINVAL; + return err; + if ((user_trig_edge == RISING_EDGE) || (user_trig_edge == FALLING_EDGE)) { trig_edge = (u8) user_trig_edge; @@ -2492,7 +2477,8 @@ static ssize_t ab8500_gpadc_trig_edge_write(struct file *file, "Enter 1. Falling edge\n"); return -EINVAL; } - return buf_size; + + return count; } static const struct file_operations ab8500_gpadc_trig_edge_fops = { @@ -2520,20 +2506,13 @@ static ssize_t ab8500_gpadc_trig_timer_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_trig_timer; int err; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_trig_timer); + err = kstrtoul_from_user(user_buf, count, 0, &user_trig_timer); if (err) - return -EINVAL; + return err; + if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) { trig_timer = (u8) user_trig_timer; } else { @@ -2541,7 +2520,8 @@ static ssize_t ab8500_gpadc_trig_timer_write(struct file *file, "should be beetween 0 to 255\n"); return -EINVAL; } - return buf_size; + + return count; } static const struct file_operations ab8500_gpadc_trig_timer_fops = { @@ -2569,20 +2549,13 @@ static ssize_t ab8500_gpadc_conv_type_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_conv_type; int err; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_conv_type); + err = kstrtoul_from_user(user_buf, count, 0, &user_conv_type); if (err) - return -EINVAL; + return err; + if ((user_conv_type == ADC_SW) || (user_conv_type == ADC_HW)) { conv_type = (u8) user_conv_type; @@ -2592,7 +2565,8 @@ static ssize_t ab8500_gpadc_conv_type_write(struct file *file, "Enter 1. ADC HW conversion\n"); return -EINVAL; } - return buf_size; + + return count; } static const struct file_operations ab8500_gpadc_conv_type_fops = { @@ -2809,21 +2783,14 @@ static ssize_t ab8500_subscribe_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_val; int err; unsigned int irq_index; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_val); + err = kstrtoul_from_user(user_buf, count, 0, &user_val); if (err) - return -EINVAL; + return err; + if (user_val < irq_first) { dev_err(dev, "debugfs error input < %d\n", irq_first); return -EINVAL; @@ -2843,7 +2810,7 @@ static ssize_t ab8500_subscribe_write(struct file *file, */ dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute), GFP_KERNEL); - event_name[irq_index] = kmalloc(buf_size, GFP_KERNEL); + event_name[irq_index] = kmalloc(count, GFP_KERNEL); sprintf(event_name[irq_index], "%lu", user_val); dev_attr[irq_index]->show = show_irq; dev_attr[irq_index]->store = NULL; @@ -2865,7 +2832,7 @@ static ssize_t ab8500_subscribe_write(struct file *file, return err; } - return buf_size; + return count; } static ssize_t ab8500_unsubscribe_write(struct file *file, @@ -2873,21 +2840,14 @@ static ssize_t ab8500_unsubscribe_write(struct file *file, size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; unsigned long user_val; int err; unsigned int irq_index; - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_val); + err = kstrtoul_from_user(user_buf, count, 0, &user_val); if (err) - return -EINVAL; + return err; + if (user_val < irq_first) { dev_err(dev, "debugfs error input < %d\n", irq_first); return -EINVAL; @@ -2912,7 +2872,7 @@ static ssize_t ab8500_unsubscribe_write(struct file *file, kfree(event_name[irq_index]); kfree(dev_attr[irq_index]); - return buf_size; + return count; } /* -- cgit From f348fefd2a227122eb2d723e255c60cf491d0557 Mon Sep 17 00:00:00 2001 From: Dariusz Szymczak Date: Mon, 26 Nov 2012 13:31:26 +0100 Subject: mfd: ab8500-core: Hierarchical interrupt registers Make use of the hierarchical interrupt rergister called ITLatchHier1 - 3 also for the 8500 platform (currently the hierarchical interrupt registers are used only for the 8540 and 9540 platforms). This will make the interrupt routing go faster since fewer i2c reads need to made in the most common cases. Signed-off-by: Dariusz Szymczak Signed-off-by: Lee Jones Reviewed-by: Mian Yousaf KAUKAB Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 82 ++++------------------------------------------- 1 file changed, 6 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index caab1fd3a03f..c7ff55753a8f 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -549,66 +549,6 @@ static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev) return IRQ_HANDLED; } -/** - * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ - * - * @ab8500: ab8500_irq controller to operate on. - * @irq: index of the interrupt requested in the chip IRQs - * - * Useful for drivers to request their own IRQs. - */ -static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq) -{ - if (!ab8500) - return -EINVAL; - - return irq_create_mapping(ab8500->domain, irq); -} - -static irqreturn_t ab8500_irq(int irq, void *dev) -{ - struct ab8500 *ab8500 = dev; - int i; - - dev_vdbg(ab8500->dev, "interrupt\n"); - - atomic_inc(&ab8500->transfer_ongoing); - - for (i = 0; i < ab8500->mask_size; i++) { - int regoffset = ab8500->irq_reg_offset[i]; - int status; - u8 value; - - /* - * Interrupt register 12 doesn't exist prior to AB8500 version - * 2.0 - */ - if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500)) - continue; - - if (regoffset < 0) - continue; - - status = get_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_LATCH1_REG + regoffset, &value); - if (status < 0 || value == 0) - continue; - - do { - int bit = __ffs(value); - int line = i * 8 + bit; - int virq = ab8500_irq_get_virq(ab8500, line); - - handle_nested_irq(virq); - ab8500_debug_register_interrupt(line); - value &= ~(1 << bit); - - } while (value); - } - atomic_dec(&ab8500->transfer_ongoing); - return IRQ_HANDLED; -} - static int ab8500_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) { @@ -1737,22 +1677,12 @@ static int ab8500_probe(struct platform_device *pdev) if (ret) return ret; - /* Activate this feature only in ab9540 */ - /* till tests are done on ab8500 1p2 or later*/ - if (is_ab9540(ab8500) || is_ab8540(ab8500)) - ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL, - ab8500_hierarchical_irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - "ab8500", ab8500); - } - else { - ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL, - ab8500_irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - "ab8500", ab8500); - if (ret) - return ret; - } + ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL, + ab8500_hierarchical_irq, + IRQF_ONESHOT | IRQF_NO_SUSPEND, + "ab8500", ab8500); + if (ret) + return ret; if (is_ab9540(ab8500)) ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, -- cgit From 9f9ba15f74cec390ad4a58f9e73fed591e46ddab Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Feb 2013 12:05:15 +0000 Subject: mfd: ab8500-debugfs: Trivially beautify the debugfs driver Just lots of white space corrections, changing some of the 4 space tabs to 8 and pulling back some of the double tabbing back into singles, such as the remaining of the driver. Signed-off-by: Lee Jones Acked-by: Samuel Ortiz --- drivers/mfd/ab8500-debugfs.c | 186 +++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 97 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index e33c1628c65b..b88bbbc15f1e 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -1504,8 +1504,8 @@ static int ab8500_address_open(struct inode *inode, struct file *file) } static ssize_t ab8500_address_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; unsigned long user_address; @@ -1548,8 +1548,8 @@ static int ab8500_val_open(struct inode *inode, struct file *file) } static ssize_t ab8500_val_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct device *dev = ((struct seq_file *)(file->private_data))->private; unsigned long user_val; @@ -1747,7 +1747,7 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p) BAT_CTRL, bat_ctrl_raw); return seq_printf(s, "%d,0x%X\n", - bat_ctrl_convert, bat_ctrl_raw); + bat_ctrl_convert, bat_ctrl_raw); } static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file) @@ -1776,11 +1776,11 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p) btemp_ball_raw); return seq_printf(s, - "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw); + "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw); } static int ab8500_gpadc_btemp_ball_open(struct inode *inode, - struct file *file) + struct file *file) { return single_open(file, ab8500_gpadc_btemp_ball_print, inode->i_private); } @@ -1810,10 +1810,10 @@ static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p) } static int ab8500_gpadc_main_charger_v_open(struct inode *inode, - struct file *file) + struct file *file) { return single_open(file, ab8500_gpadc_main_charger_v_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8500_gpadc_main_charger_v_fops = { @@ -1837,14 +1837,14 @@ static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p) acc_detect1_raw); return seq_printf(s, "%d,0x%X\n", - acc_detect1_convert, acc_detect1_raw); + acc_detect1_convert, acc_detect1_raw); } static int ab8500_gpadc_acc_detect1_open(struct inode *inode, - struct file *file) + struct file *file) { return single_open(file, ab8500_gpadc_acc_detect1_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8500_gpadc_acc_detect1_fops = { @@ -1868,14 +1868,14 @@ static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p) ACC_DETECT2, acc_detect2_raw); return seq_printf(s, "%d,0x%X\n", - acc_detect2_convert, acc_detect2_raw); + acc_detect2_convert, acc_detect2_raw); } static int ab8500_gpadc_acc_detect2_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_acc_detect2_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8500_gpadc_acc_detect2_fops = { @@ -1899,7 +1899,7 @@ static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p) aux1_raw); return seq_printf(s, "%d,0x%X\n", - aux1_convert, aux1_raw); + aux1_convert, aux1_raw); } static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file) @@ -1957,11 +1957,11 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p) main_bat_v_raw); return seq_printf(s, "%d,0x%X\n", - main_bat_v_convert, main_bat_v_raw); + main_bat_v_convert, main_bat_v_raw); } static int ab8500_gpadc_main_bat_v_open(struct inode *inode, - struct file *file) + struct file *file) { return single_open(file, ab8500_gpadc_main_bat_v_print, inode->i_private); } @@ -1987,7 +1987,7 @@ static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p) vbus_v_raw); return seq_printf(s, "%d,0x%X\n", - vbus_v_convert, vbus_v_raw); + vbus_v_convert, vbus_v_raw); } static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file) @@ -2016,14 +2016,14 @@ static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p) MAIN_CHARGER_C, main_charger_c_raw); return seq_printf(s, "%d,0x%X\n", - main_charger_c_convert, main_charger_c_raw); + main_charger_c_convert, main_charger_c_raw); } static int ab8500_gpadc_main_charger_c_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_main_charger_c_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8500_gpadc_main_charger_c_fops = { @@ -2047,14 +2047,14 @@ static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p) USB_CHARGER_C, usb_charger_c_raw); return seq_printf(s, "%d,0x%X\n", - usb_charger_c_convert, usb_charger_c_raw); + usb_charger_c_convert, usb_charger_c_raw); } static int ab8500_gpadc_usb_charger_c_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_usb_charger_c_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8500_gpadc_usb_charger_c_fops = { @@ -2078,7 +2078,7 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p) BK_BAT_V, bk_bat_v_raw); return seq_printf(s, "%d,0x%X\n", - bk_bat_v_convert, bk_bat_v_raw); + bk_bat_v_convert, bk_bat_v_raw); } static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file) @@ -2107,7 +2107,7 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p) die_temp_raw); return seq_printf(s, "%d,0x%X\n", - die_temp_convert, die_temp_raw); + die_temp_convert, die_temp_raw); } static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file) @@ -2136,7 +2136,7 @@ static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p) usb_id_raw); return seq_printf(s, "%d,0x%X\n", - usb_id_convert, usb_id_raw); + usb_id_convert, usb_id_raw); } static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file) @@ -2165,13 +2165,13 @@ static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p) xtal_temp_raw); return seq_printf(s, "%d,0x%X\n", - xtal_temp_convert, xtal_temp_raw); + xtal_temp_convert, xtal_temp_raw); } static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_xtal_temp_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_xtal_temp_fops = { @@ -2195,14 +2195,14 @@ static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p) vbat_true_meas_raw); return seq_printf(s, "%d,0x%X\n", - vbat_true_meas_convert, vbat_true_meas_raw); + vbat_true_meas_convert, vbat_true_meas_raw); } static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_vbat_true_meas_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = { @@ -2231,15 +2231,15 @@ static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p) ibat_raw); return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", - bat_ctrl_convert, bat_ctrl_raw, - ibat_convert, ibat_raw); + bat_ctrl_convert, bat_ctrl_raw, + ibat_convert, ibat_raw); } static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = { @@ -2267,15 +2267,15 @@ static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p) ibat_raw); return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", - vbat_meas_convert, vbat_meas_raw, - ibat_convert, ibat_raw); + vbat_meas_convert, vbat_meas_raw, + ibat_convert, ibat_raw); } static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = { @@ -2304,15 +2304,15 @@ static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void * ibat_raw); return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", - vbat_true_meas_convert, vbat_true_meas_raw, - ibat_convert, ibat_raw); + vbat_true_meas_convert, vbat_true_meas_raw, + ibat_convert, ibat_raw); } static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = { @@ -2340,15 +2340,15 @@ static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p) ibat_raw); return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", - bat_temp_convert, bat_temp_raw, - ibat_convert, ibat_raw); + bat_temp_convert, bat_temp_raw, + ibat_convert, ibat_raw); } static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode, struct file *file) { return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print, - inode->i_private); + inode->i_private); } static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = { @@ -2369,22 +2369,14 @@ static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p) ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h, &vbat_l, &vbat_h, &ibat_l, &ibat_h); return seq_printf(s, "VMAIN_L:0x%X\n" - "VMAIN_H:0x%X\n" - "BTEMP_L:0x%X\n" - "BTEMP_H:0x%X\n" - "VBAT_L:0x%X\n" - "VBAT_H:0x%X\n" - "IBAT_L:0x%X\n" - "IBAT_H:0x%X\n" - , - vmain_l, - vmain_h, - btemp_l, - btemp_h, - vbat_l, - vbat_h, - ibat_l, - ibat_h); + "VMAIN_H:0x%X\n" + "BTEMP_L:0x%X\n" + "BTEMP_H:0x%X\n" + "VBAT_L:0x%X\n" + "VBAT_H:0x%X\n" + "IBAT_L:0x%X\n" + "IBAT_H:0x%X\n", + vmain_l, vmain_h, btemp_l, btemp_h, vbat_l, vbat_h, ibat_l, ibat_h); } static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file) @@ -2408,7 +2400,7 @@ static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p) static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_avg_sample_print, - inode->i_private); + inode->i_private); } static ssize_t ab8500_gpadc_avg_sample_write(struct file *file, @@ -2453,7 +2445,7 @@ static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p) static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_trig_edge_print, - inode->i_private); + inode->i_private); } static ssize_t ab8500_gpadc_trig_edge_write(struct file *file, @@ -2498,7 +2490,7 @@ static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p) static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_trig_timer_print, - inode->i_private); + inode->i_private); } static ssize_t ab8500_gpadc_trig_timer_write(struct file *file, @@ -2541,7 +2533,7 @@ static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p) static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_gpadc_conv_type_print, - inode->i_private); + inode->i_private); } static ssize_t ab8500_gpadc_conv_type_write(struct file *file, @@ -2753,7 +2745,7 @@ static int ab8500_subscribe_unsubscribe_open(struct inode *inode, struct file *file) { return single_open(file, ab8500_subscribe_unsubscribe_print, - inode->i_private); + inode->i_private); } /* @@ -2970,7 +2962,7 @@ static int ab8500_debug_probe(struct platform_device *plf) irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); if (irq_first < 0) { dev_err(&plf->dev, "First irq not found, err %d\n", - irq_first); + irq_first); ret = irq_first; goto out_freeevent_name; } @@ -2978,7 +2970,7 @@ static int ab8500_debug_probe(struct platform_device *plf) irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); if (irq_last < 0) { dev_err(&plf->dev, "Last irq not found, err %d\n", - irq_last); + irq_last); ret = irq_last; goto out_freeevent_name; } @@ -2988,37 +2980,37 @@ static int ab8500_debug_probe(struct platform_device *plf) goto err; ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING, - ab8500_dir); + ab8500_dir); if (!ab8500_gpadc_dir) goto err; file = debugfs_create_file("all-bank-registers", S_IRUGO, - ab8500_dir, &plf->dev, &ab8500_registers_fops); + ab8500_dir, &plf->dev, &ab8500_registers_fops); if (!file) goto err; file = debugfs_create_file("all-banks", S_IRUGO, - ab8500_dir, &plf->dev, &ab8500_all_banks_fops); + ab8500_dir, &plf->dev, &ab8500_all_banks_fops); if (!file) goto err; file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_bank_fops); + ab8500_dir, &plf->dev, &ab8500_bank_fops); if (!file) goto err; file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_address_fops); + ab8500_dir, &plf->dev, &ab8500_address_fops); if (!file) goto err; file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_val_fops); + ab8500_dir, &plf->dev, &ab8500_val_fops); if (!file) goto err; file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_subscribe_fops); + ab8500_dir, &plf->dev, &ab8500_subscribe_fops); if (!file) goto err; @@ -3037,17 +3029,17 @@ static int ab8500_debug_probe(struct platform_device *plf) } file = debugfs_create_file("interrupts", (S_IRUGO), - ab8500_dir, &plf->dev, &ab8500_interrupts_fops); + ab8500_dir, &plf->dev, &ab8500_interrupts_fops); if (!file) goto err; file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); + ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); if (!file) goto err; file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_dir, &plf->dev, &ab8500_hwreg_fops); + ab8500_dir, &plf->dev, &ab8500_hwreg_fops); if (!file) goto err; @@ -3057,67 +3049,67 @@ static int ab8500_debug_probe(struct platform_device *plf) goto err; file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops); if (!file) goto err; file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops); if (!file) goto err; file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops); if (!file) goto err; file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops); if (!file) goto err; file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops); if (!file) goto err; file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops); if (!file) goto err; file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops); if (!file) goto err; file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops); if (!file) goto err; file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops); if (!file) goto err; file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops); if (!file) goto err; file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops); if (!file) goto err; file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops); if (!file) goto err; file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP), - ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); + ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); if (!file) goto err; @@ -3137,25 +3129,25 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!file) goto err; file = debugfs_create_file("batctrl_and_ibat", - (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, - &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops); + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops); if (!file) goto err; file = debugfs_create_file("vbatmeas_and_ibat", - (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, - &plf->dev, - &ab8540_gpadc_vbat_meas_and_ibat_fops); + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, + &ab8540_gpadc_vbat_meas_and_ibat_fops); if (!file) goto err; file = debugfs_create_file("vbattruemeas_and_ibat", - (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, - &plf->dev, - &ab8540_gpadc_vbat_true_meas_and_ibat_fops); + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, + &ab8540_gpadc_vbat_true_meas_and_ibat_fops); if (!file) goto err; file = debugfs_create_file("battemp_and_ibat", - (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, - &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, + &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); if (!file) goto err; file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP), -- cgit From 116c326e74494806f2524ea07dc256f12b245652 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:26:52 +0000 Subject: pm2301_charger: Remove __exit, __init and __devexit_p() Signed-off-by: Lee Jones --- drivers/power/pm2301_charger.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ed48d75bb786..ca424b844b21 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -851,7 +851,7 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, return 0; } -static int __devinit pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, +static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; @@ -1021,7 +1021,7 @@ free_device_info: return ret; } -static int __devexit pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) +static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) { struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); @@ -1058,7 +1058,7 @@ MODULE_DEVICE_TABLE(i2c, pm2xxx_id); static struct i2c_driver pm2xxx_charger_driver = { .probe = pm2xxx_wall_charger_probe, - .remove = __devexit_p(pm2xxx_wall_charger_remove), + .remove = pm2xxx_wall_charger_remove, .suspend = pm2xxx_wall_charger_suspend, .resume = pm2xxx_wall_charger_resume, .driver = { -- cgit From 584f970339bb259d4ac7dd82b355f283550193b2 Mon Sep 17 00:00:00 2001 From: Rajkumar Kasirajan Date: Tue, 5 Jun 2012 12:31:25 +0530 Subject: pm2301-charger: Enable SW EOC control on the ab9540 End of charging is managed by SW. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Lee Jones Reviewed-by: Jonas ABERG Tested-by: Jonas ABERG --- drivers/power/pm2301_charger.c | 48 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ca424b844b21..b2f2d4188da9 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -192,11 +192,22 @@ static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2) { int ret; + /* Disable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, PM2XXX_SWCTRL_HW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } + /* Disable charging */ ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, (PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS)); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } - return ret; + return 0; } static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val) @@ -245,13 +256,29 @@ static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val) { + int ret; + switch (val) { case PM2XXX_INT1_ITVBATLOWR: dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n"); + /* Enable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, + PM2XXX_SWCTRL_SW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } break; case PM2XXX_INT1_ITVBATLOWF: dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n"); + /* Disable SW EOC ctrl */ + ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, + PM2XXX_SWCTRL_HW); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); + return ret; + } break; default: @@ -322,16 +349,27 @@ static int pm2_int_reg0(void *pm2_data, int val) struct pm2xxx_charger *pm2 = pm2_data; int ret = 0; - if (val & (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)) { - ret = pm2xxx_charger_vbat_lsig_mngt(pm2, val & - (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)); + if (val & PM2XXX_INT1_ITVBATLOWR) { + ret = pm2xxx_charger_vbat_lsig_mngt(pm2, + PM2XXX_INT1_ITVBATLOWR); + if (ret < 0) + goto out; + } + + if (val & PM2XXX_INT1_ITVBATLOWF) { + ret = pm2xxx_charger_vbat_lsig_mngt(pm2, + PM2XXX_INT1_ITVBATLOWF); + if (ret < 0) + goto out; } if (val & PM2XXX_INT1_ITVBATDISCONNECT) { ret = pm2xxx_charger_bat_disc_mngt(pm2, PM2XXX_INT1_ITVBATDISCONNECT); + if (ret < 0) + goto out; } - +out: return ret; } -- cgit From 330b7ebfa59d70ea5b814a04a28b8c7d8e462a81 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 15 Feb 2013 10:53:57 +0000 Subject: abx500-chargalg: Store the AB8500 MFD parent device for platform differentiation Any platform can be dynamically probed for model and version number provided the AB8500 MFD parent device pointer is available. This patch obtains that pointer and stores it in a locally controlled struct for later use. Signed-off-by: Lee Jones --- drivers/power/abx500_chargalg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index f043c0851a76..31507bfe549c 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -204,6 +204,7 @@ enum maxim_ret { * @batt_data: data of the battery * @susp_status: current charger suspension status * @bm: Platform specific battery management information + * @parent: pointer to the struct abx500 * @chargalg_psy: structure that holds the battery properties exposed by * the charging algorithm * @events: structure for information about events triggered @@ -227,6 +228,7 @@ struct abx500_chargalg { struct abx500_chargalg_charger_info chg_info; struct abx500_chargalg_battery_data batt_data; struct abx500_chargalg_suspension_status susp_status; + struct ab8500 *parent; struct abx500_bm_data *bm; struct power_supply chargalg_psy; struct ux500_charger *ac_chg; @@ -1873,8 +1875,9 @@ static int abx500_chargalg_probe(struct platform_device *pdev) } } - /* get device struct */ + /* get device struct and parent */ di->dev = &pdev->dev; + di->parent = dev_get_drvdata(pdev->dev.parent); /* chargalg supply */ di->chargalg_psy.name = "abx500_chargalg"; -- cgit From 93ff722e88530b9719cbf53be4f3197722461394 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 31 May 2012 16:16:36 +0200 Subject: ab8500-fg: Add power cut feature for ab8505 and ab8540 Add support for a power cut feature which allows user to configure when ab8505 and ab8540 based platforms should shut down system due to low battery. Signed-off-by: Lee Jones --- drivers/mfd/ab8500-core.c | 36 +++ drivers/power/ab8500_bmdata.c | 5 + drivers/power/ab8500_fg.c | 474 +++++++++++++++++++++++++++++++++++ include/linux/mfd/abx500.h | 10 + include/linux/mfd/abx500/ab8500-bm.h | 18 ++ 5 files changed, 543 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index c7ff55753a8f..f276352cc9ef 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -113,6 +113,7 @@ #define AB8500_SWITCH_OFF_STATUS 0x00 #define AB8500_TURN_ON_STATUS 0x00 +#define AB8505_TURN_ON_STATUS_2 0x04 #define AB8500_CH_USBCH_STAT1_REG 0x02 #define VBUS_DET_DBNC100 0x02 @@ -1401,6 +1402,21 @@ static ssize_t show_turn_on_status(struct device *dev, return sprintf(buf, "%#x\n", value); } +static ssize_t show_turn_on_status_2(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + u8 value; + struct ab8500 *ab8500; + + ab8500 = dev_get_drvdata(dev); + ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK, + AB8505_TURN_ON_STATUS_2, &value); + if (ret < 0) + return ret; + return sprintf(buf, "%#x\n", (value & 0x1)); +} + static ssize_t show_ab9540_dbbrstn(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1457,6 +1473,7 @@ exit: static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL); +static DEVICE_ATTR(turn_on_status_2, S_IRUGO, show_turn_on_status_2, NULL); static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR, show_ab9540_dbbrstn, store_ab9540_dbbrstn); @@ -1467,6 +1484,11 @@ static struct attribute *ab8500_sysfs_entries[] = { NULL, }; +static struct attribute *ab8505_sysfs_entries[] = { + &dev_attr_turn_on_status_2.attr, + NULL, +}; + static struct attribute *ab9540_sysfs_entries[] = { &dev_attr_chip_id.attr, &dev_attr_switch_off_status.attr, @@ -1479,6 +1501,10 @@ static struct attribute_group ab8500_attr_group = { .attrs = ab8500_sysfs_entries, }; +static struct attribute_group ab8505_attr_group = { + .attrs = ab8505_sysfs_entries, +}; + static struct attribute_group ab9540_attr_group = { .attrs = ab9540_sysfs_entries, }; @@ -1719,6 +1745,12 @@ static int ab8500_probe(struct platform_device *pdev) else ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group); + + if ((is_ab8505(ab8500) || is_ab9540(ab8500)) && + ab8500->chip_id >= AB8500_CUT2P0) + ret = sysfs_create_group(&ab8500->dev->kobj, + &ab8505_attr_group); + if (ret) dev_err(ab8500->dev, "error creating sysfs entries\n"); @@ -1735,6 +1767,10 @@ static int ab8500_remove(struct platform_device *pdev) else sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); + if ((is_ab8505(ab8500) || is_ab9540(ab8500)) && + ab8500->chip_id >= AB8500_CUT2P0) + sysfs_remove_group(&ab8500->dev->kobj, &ab8505_attr_group); + mfd_remove_devices(ab8500->dev); return 0; diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c index 7a96c0650fbb..e8759763fbe0 100644 --- a/drivers/power/ab8500_bmdata.c +++ b/drivers/power/ab8500_bmdata.c @@ -407,6 +407,11 @@ static const struct abx500_fg_parameters fg = { .battok_raising_th_sel1 = 2860, .maint_thres = 95, .user_cap_limit = 15, + .pcut_enable = 1, + .pcut_max_time = 127, + .pcut_flag_time = 112, + .pcut_max_restart = 15, + .pcut_debounce_time = 2, }; static const struct abx500_maxim_parameters maxi_params = { diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 25dae4c4b0ef..92f342bcf188 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -2344,6 +2344,50 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di) dev_err(di->dev, "BattOk init write failed.\n"); goto out; } + + if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && + abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) + || is_ab8540(di->parent)) { + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_MAX_TIME_REG, di->bm->fg_params->pcut_max_time); + + if (ret) { + dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_MAX_TIME_REG\n", __func__); + goto out; + }; + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_FLAG_TIME_REG, di->bm->fg_params->pcut_flag_time); + + if (ret) { + dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_FLAG_TIME_REG\n", __func__); + goto out; + }; + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_RESTART_REG, di->bm->fg_params->pcut_max_restart); + + if (ret) { + dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_RESTART_REG\n", __func__); + goto out; + }; + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_DEBOUNCE_REG, di->bm->fg_params->pcut_debounce_time); + + if (ret) { + dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_DEBOUNCE_REG\n", __func__); + goto out; + }; + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_CTL_STATUS_REG, di->bm->fg_params->pcut_enable); + + if (ret) { + dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_CTL_STATUS_REG\n", __func__); + goto out; + }; + } out: return ret; } @@ -2546,6 +2590,428 @@ static int ab8500_fg_sysfs_init(struct ab8500_fg *di) return ret; } + +static ssize_t ab8505_powercut_flagtime_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_FLAG_TIME_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_FLAG_TIME_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0x7F)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_flagtime_write(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + long unsigned reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + reg_value = simple_strtoul(buf, NULL, 10); + + if (reg_value > 0x7F) { + dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n"); + goto fail; + } + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_FLAG_TIME_REG, (u8)reg_value); + + if (ret < 0) + dev_err(dev, "Failed to set AB8505_RTC_PCUT_FLAG_TIME_REG\n"); + +fail: + return count; +} + +static ssize_t ab8505_powercut_maxtime_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_MAX_TIME_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_MAX_TIME_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0x7F)); + +fail: + return ret; + +} + +static ssize_t ab8505_powercut_maxtime_write(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + reg_value = simple_strtoul(buf, NULL, 10); + if (reg_value > 0x7F) { + dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n"); + goto fail; + } + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_MAX_TIME_REG, (u8)reg_value); + + if (ret < 0) + dev_err(dev, "Failed to set AB8505_RTC_PCUT_MAX_TIME_REG\n"); + +fail: + return count; +} + +static ssize_t ab8505_powercut_restart_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_RESTART_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_RESTART_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0xF)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_restart_write(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + reg_value = simple_strtoul(buf, NULL, 10); + if (reg_value > 0xF) { + dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n"); + goto fail; + } + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_RESTART_REG, (u8)reg_value); + + if (ret < 0) + dev_err(dev, "Failed to set AB8505_RTC_PCUT_RESTART_REG\n"); + +fail: + return count; + +} + +static ssize_t ab8505_powercut_timer_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_TIME_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_TIME_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0x7F)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_restart_counter_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_RESTART_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_RESTART_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0xF0) >> 4); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); + + if (ret < 0) + goto fail; + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0x1)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_write(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + reg_value = simple_strtoul(buf, NULL, 10); + if (reg_value > 0x1) { + dev_err(dev, "Incorrect parameter, echo 0/1 to disable/enable Pcut feature\n"); + goto fail; + } + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_CTL_STATUS_REG, (u8)reg_value); + + if (ret < 0) + dev_err(dev, "Failed to set AB8505_RTC_PCUT_CTL_STATUS_REG\n"); + +fail: + return count; +} + +static ssize_t ab8505_powercut_flag_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_CTL_STATUS_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", ((reg_value & 0x10) >> 4)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_debounce_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_DEBOUNCE_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_DEBOUNCE_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", (reg_value & 0x7)); + +fail: + return ret; +} + +static ssize_t ab8505_powercut_debounce_write(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + reg_value = simple_strtoul(buf, NULL, 10); + if (reg_value > 0x7) { + dev_err(dev, "Incorrect parameter, echo 0 to 7 for debounce setting\n"); + goto fail; + } + + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_DEBOUNCE_REG, (u8)reg_value); + + if (ret < 0) + dev_err(dev, "Failed to set AB8505_RTC_PCUT_DEBOUNCE_REG\n"); + +fail: + return count; +} + +static ssize_t ab8505_powercut_enable_status_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 reg_value; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, + AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); + + if (ret < 0) { + dev_err(dev, "Failed to read AB8505_RTC_PCUT_CTL_STATUS_REG\n"); + goto fail; + } + + return scnprintf(buf, PAGE_SIZE, "%d\n", ((reg_value & 0x20) >> 5)); + +fail: + return ret; +} + +static struct device_attribute ab8505_fg_sysfs_psy_attrs[] = { + __ATTR(powercut_flagtime, (S_IRUGO | S_IWUSR | S_IWGRP), + ab8505_powercut_flagtime_read, ab8505_powercut_flagtime_write), + __ATTR(powercut_maxtime, (S_IRUGO | S_IWUSR | S_IWGRP), + ab8505_powercut_maxtime_read, ab8505_powercut_maxtime_write), + __ATTR(powercut_restart_max, (S_IRUGO | S_IWUSR | S_IWGRP), + ab8505_powercut_restart_read, ab8505_powercut_restart_write), + __ATTR(powercut_timer, S_IRUGO, ab8505_powercut_timer_read, NULL), + __ATTR(powercut_restart_counter, S_IRUGO, + ab8505_powercut_restart_counter_read, NULL), + __ATTR(powercut_enable, (S_IRUGO | S_IWUSR | S_IWGRP), + ab8505_powercut_read, ab8505_powercut_write), + __ATTR(powercut_flag, S_IRUGO, ab8505_powercut_flag_read, NULL), + __ATTR(powercut_debounce_time, (S_IRUGO | S_IWUSR | S_IWGRP), + ab8505_powercut_debounce_read, ab8505_powercut_debounce_write), + __ATTR(powercut_enable_status, S_IRUGO, + ab8505_powercut_enable_status_read, NULL), +}; + +static int ab8500_fg_sysfs_psy_create_attrs(struct device *dev) +{ + unsigned int i, j; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && + abx500_get_chip_id(dev->parent) >= AB8500_CUT2P0) + || is_ab8540(di->parent)) { + for (j = 0; j < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); j++) + if (device_create_file(dev, &ab8505_fg_sysfs_psy_attrs[j])) + goto sysfs_psy_create_attrs_failed_ab8505; + } + return 0; +sysfs_psy_create_attrs_failed_ab8505: + dev_err(dev, "Failed creating sysfs psy attrs for ab8505.\n"); + while (j--) + device_remove_file(dev, &ab8505_fg_sysfs_psy_attrs[i]); + + return -EIO; +} + +static void ab8500_fg_sysfs_psy_remove_attrs(struct device *dev) +{ + unsigned int i; + struct power_supply *psy = dev_get_drvdata(dev); + struct ab8500_fg *di; + + di = to_ab8500_fg_device_info(psy); + + if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && + abx500_get_chip_id(dev->parent) >= AB8500_CUT2P0) + || is_ab8540(di->parent)) { + for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) + (void)device_remove_file(dev, &ab8505_fg_sysfs_psy_attrs[i]); + } +} + /* Exposure to the sysfs interface <> */ #if defined(CONFIG_PM) @@ -2607,6 +3073,7 @@ static int ab8500_fg_remove(struct platform_device *pdev) ab8500_fg_sysfs_exit(di); flush_scheduled_work(); + ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev); power_supply_unregister(&di->fg_psy); platform_set_drvdata(pdev, NULL); return ret; @@ -2772,6 +3239,13 @@ static int ab8500_fg_probe(struct platform_device *pdev) goto free_irq; } + ret = ab8500_fg_sysfs_psy_create_attrs(di->fg_psy.dev); + if (ret) { + dev_err(di->dev, "failed to create FG psy\n"); + ab8500_fg_sysfs_exit(di); + goto free_irq; + } + /* Calibrate the fg first time */ di->flags.calibrate = true; di->calib_state = AB8500_FG_CALIB_INIT; diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 9ead60bc66b7..188aedc322c2 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -89,6 +89,11 @@ struct abx500_fg; * points. * @maint_thres This is the threshold where we stop reporting * battery full while in maintenance, in per cent + * @pcut_enable: Enable power cut feature in ab8505 + * @pcut_max_time: Max time threshold + * @pcut_flag_time: Flagtime threshold + * @pcut_max_restart: Max number of restarts + * @pcut_debounce_time: Sets battery debounce time */ struct abx500_fg_parameters { int recovery_sleep_timer; @@ -106,6 +111,11 @@ struct abx500_fg_parameters { int battok_raising_th_sel1; int user_cap_limit; int maint_thres; + bool pcut_enable; + u8 pcut_max_time; + u8 pcut_flag_time; + u8 pcut_max_restart; + u8 pcut_debounce_time; }; /** diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index 8d35bfe164c8..0efbe0efee7f 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -235,6 +235,14 @@ /* Battery type */ #define BATTERY_UNKNOWN 00 +/* Registers for pcut feature in ab8505 and ab9540 */ +#define AB8505_RTC_PCUT_CTL_STATUS_REG 0x12 +#define AB8505_RTC_PCUT_TIME_REG 0x13 +#define AB8505_RTC_PCUT_MAX_TIME_REG 0x14 +#define AB8505_RTC_PCUT_FLAG_TIME_REG 0x15 +#define AB8505_RTC_PCUT_RESTART_REG 0x16 +#define AB8505_RTC_PCUT_DEBOUNCE_REG 0x17 + /** * struct res_to_temp - defines one point in a temp to res curve. To * be used in battery packs that combines the identification resistor with a @@ -283,6 +291,11 @@ struct ab8500_fg; * points. * @maint_thres This is the threshold where we stop reporting * battery full while in maintenance, in per cent + * @pcut_enable: Enable power cut feature in ab8505 + * @pcut_max_time: Max time threshold + * @pcut_flag_time: Flagtime threshold + * @pcut_max_restart: Max number of restarts + * @pcut_debunce_time: Sets battery debounce time */ struct ab8500_fg_parameters { int recovery_sleep_timer; @@ -299,6 +312,11 @@ struct ab8500_fg_parameters { int battok_raising_th_sel1; int user_cap_limit; int maint_thres; + bool pcut_enable; + u8 pcut_max_time; + u8 pcut_flag_time; + u8 pcut_max_restart; + u8 pcut_debunce_time; }; /** -- cgit From e82c5bdbf3aa26d22e9eab3626213795d8338da1 Mon Sep 17 00:00:00 2001 From: Martin Bergstrom Date: Fri, 8 Jun 2012 16:21:48 +0200 Subject: ab8500-fg: Report unscaled capacity Unscaled capacity should be reported for POWER_SUPPLY_PROP_CAPACITY. Signed-off-by: Martin Bergstrom Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Tested-by: Jonas ABERG --- drivers/power/ab8500_fg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 92f342bcf188..a747c5ce3b27 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -2153,9 +2153,7 @@ static int ab8500_fg_get_property(struct power_supply *psy, val->intval = di->bat_cap.prev_mah; break; case POWER_SUPPLY_PROP_CAPACITY: - if (di->bm->capacity_scaling) - val->intval = di->bat_cap.cap_scale.scaled_cap; - else if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && + if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && di->flags.batt_id_received) val->intval = 100; else -- cgit From 0f4aa401853e07885707aedfc68c608051b0d6e4 Mon Sep 17 00:00:00 2001 From: Yang QU Date: Tue, 26 Jun 2012 19:25:52 +0800 Subject: ab8500-charger: Add backup battery charge voltages on the ab8540 Add 2.7v, 2.9v, 3.0v, 3.2v and 3.3v charging voltages for backup battery. Before that only 2.5v, 2.6v, 2.8v, 3.1v were available. Signed-off-by: Yang QU Signed-off-by: Lee Jones Reviewed-by: Maxime COQUELIN Reviewed-by: Marcus COOPER Tested-by: Xiao Mei ZHANG --- drivers/power/ab8500_charger.c | 19 +++++++++++++++++-- include/linux/mfd/abx500/ab8500-bm.h | 24 ++++++++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 24b30b7ea5ca..fd3fa2beca2b 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2836,6 +2836,7 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) { int ret = 0; + u8 bup_vch_range = 0, vbup33_vrtcn = 0; /* Setup maximum charger current and voltage for ABB cut2.0 */ if (!is_ab8500_1p1_or_earlier(di->parent)) { @@ -2945,15 +2946,29 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) } /* Backup battery voltage and current */ + if (di->bm->bkup_bat_v > BUP_VCH_SEL_3P1V) + bup_vch_range = BUP_VCH_RANGE; + if (di->bm->bkup_bat_v == BUP_VCH_SEL_3P3V) + vbup33_vrtcn = VBUP33_VRTCN; + ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, AB8500_RTC_BACKUP_CHG_REG, - di->bm->bkup_bat_v | - di->bm->bkup_bat_i); + (di->bm->bkup_bat_v & 0x3) | di->bm->bkup_bat_i); if (ret) { dev_err(di->dev, "failed to setup backup battery charging\n"); goto out; } + if (is_ab8540(di->parent)) { + ret = abx500_set_register_interruptible(di->dev, + AB8500_RTC, + AB8500_RTC_CTRL1_REG, + bup_vch_range | vbup33_vrtcn); + if (ret) { + dev_err(di->dev, "failed to setup backup battery charging\n"); + goto out; + } + } /* Enable backup battery charging */ abx500_mask_and_set_register_interruptible(di->dev, diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index 0efbe0efee7f..a73e05a0441b 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -105,6 +105,7 @@ #define AB8500_RTC_BACKUP_CHG_REG 0x0C #define AB8500_RTC_CC_CONF_REG 0x01 #define AB8500_RTC_CTRL_REG 0x0B +#define AB8500_RTC_CTRL1_REG 0x11 /* * OTP register offsets @@ -179,10 +180,25 @@ #define BUP_ICH_SEL_300UA 0x08 #define BUP_ICH_SEL_700UA 0x0C -#define BUP_VCH_SEL_2P5V 0x00 -#define BUP_VCH_SEL_2P6V 0x01 -#define BUP_VCH_SEL_2P8V 0x02 -#define BUP_VCH_SEL_3P1V 0x03 +enum bup_vch_sel { + BUP_VCH_SEL_2P5V, + BUP_VCH_SEL_2P6V, + BUP_VCH_SEL_2P8V, + BUP_VCH_SEL_3P1V, + /* + * Note that the following 5 values 2.7v, 2.9v, 3.0v, 3.2v, 3.3v + * are only available on ab8540. You can't choose these 5 + * voltage on ab8500/ab8505/ab9540. + */ + BUP_VCH_SEL_2P7V, + BUP_VCH_SEL_2P9V, + BUP_VCH_SEL_3P0V, + BUP_VCH_SEL_3P2V, + BUP_VCH_SEL_3P3V, +}; + +#define BUP_VCH_RANGE 0x02 +#define VBUP33_VRTCN 0x01 /* Battery OVV constants */ #define BATT_OVV_ENA 0x02 -- cgit From 72a90ddbc3d89a63b769ae1b8538c612cf01e675 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 14 Feb 2013 09:22:48 +0000 Subject: ab8500-charger: Trivial coding style changes Enforce the white space character after 'if'. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index fd3fa2beca2b..dcd3c6feca97 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -3152,10 +3152,10 @@ static int ab8500_charger_remove(struct platform_device *pdev) destroy_workqueue(di->charger_wq); flush_scheduled_work(); - if(di->usb_chg.enabled) + if (di->usb_chg.enabled) power_supply_unregister(&di->usb_chg.psy); #if !defined(CONFIG_CHARGER_PM2301) - if(di->ac_chg.enabled) + if (di->ac_chg.enabled) power_supply_unregister(&di->ac_chg.psy); #endif platform_set_drvdata(pdev, NULL); @@ -3331,7 +3331,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) } /* Register AC charger class */ - if(di->ac_chg.enabled) { + if (di->ac_chg.enabled) { ret = power_supply_register(di->dev, &di->ac_chg.psy); if (ret) { dev_err(di->dev, "failed to register AC charger\n"); @@ -3340,7 +3340,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) } /* Register USB charger class */ - if(di->usb_chg.enabled) { + if (di->usb_chg.enabled) { ret = power_supply_register(di->dev, &di->usb_chg.psy); if (ret) { dev_err(di->dev, "failed to register USB charger\n"); @@ -3425,10 +3425,10 @@ free_irq: put_usb_phy: usb_put_phy(di->usb_phy); free_usb: - if(di->usb_chg.enabled) + if (di->usb_chg.enabled) power_supply_unregister(&di->usb_chg.psy); free_ac: - if(di->ac_chg.enabled) + if (di->ac_chg.enabled) power_supply_unregister(&di->ac_chg.psy); free_charger_wq: destroy_workqueue(di->charger_wq); -- cgit From 4dcdf57773fd45b483fc7613b9e51b89a57d655c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 14 Feb 2013 09:24:10 +0000 Subject: ab8500-bm: Quick re-attach charging behaviour Due to a bug in some AB8500 ASICs charger removal cannot always be detected if the removal and reinsertion is done to close in time. This patch detects above described case and handles the situation so that charging will be kept turned on. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 105 +++++++++++++++++++++++++++++- drivers/power/abx500_chargalg.c | 33 ++++++++++ include/linux/mfd/abx500/ux500_chargalg.h | 1 + 3 files changed, 137 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index dcd3c6feca97..3eb23cf9ff47 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -52,6 +52,7 @@ #define VBUS_DET_DBNC100 0x02 #define VBUS_DET_DBNC1 0x01 #define OTP_ENABLE_WD 0x01 +#define DROP_COUNT_RESET 0x01 #define MAIN_CH_INPUT_CURR_SHIFT 4 #define VBUS_IN_CURR_LIM_SHIFT 4 @@ -1677,6 +1678,105 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, return ret; } +/** + * ab8500_charger_usb_check_enable() - enable usb charging + * @charger: pointer to the ux500_charger structure + * @vset: charging voltage + * @iset: charger output current + * + * Check if the VBUS charger has been disconnected and reconnected without + * AB8500 rising an interrupt. Returns 0 on success. + */ +static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, + int vset, int iset) +{ + u8 usbch_ctrl1 = 0; + int ret = 0; + + struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger); + + if (!di->usb.charger_connected) + return ret; + + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8500_USBCH_CTRL1_REG, &usbch_ctrl1); + if (ret < 0) { + dev_err(di->dev, "ab8500 read failed %d\n", __LINE__); + return ret; + } + dev_dbg(di->dev, "USB charger ctrl: 0x%02x\n", usbch_ctrl1); + + if (!(usbch_ctrl1 & USB_CH_ENA)) { + dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n"); + + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_CHARGER_CTRL, + DROP_COUNT_RESET, DROP_COUNT_RESET); + if (ret < 0) { + dev_err(di->dev, "ab8500 write failed %d\n", __LINE__); + return ret; + } + + ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset); + if (ret < 0) { + dev_err(di->dev, "Failed to enable VBUS charger %d\n", + __LINE__); + return ret; + } + } + return ret; +} + +/** + * ab8500_charger_ac_check_enable() - enable usb charging + * @charger: pointer to the ux500_charger structure + * @vset: charging voltage + * @iset: charger output current + * + * Check if the AC charger has been disconnected and reconnected without + * AB8500 rising an interrupt. Returns 0 on success. + */ +static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, + int vset, int iset) +{ + u8 mainch_ctrl1 = 0; + int ret = 0; + + struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger); + + if (!di->ac.charger_connected) + return ret; + + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8500_MCH_CTRL1, &mainch_ctrl1); + if (ret < 0) { + dev_err(di->dev, "ab8500 read failed %d\n", __LINE__); + return ret; + } + dev_dbg(di->dev, "AC charger ctrl: 0x%02x\n", mainch_ctrl1); + + if (!(mainch_ctrl1 & MAIN_CH_ENA)) { + dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n"); + + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_CHARGER_CTRL, + DROP_COUNT_RESET, DROP_COUNT_RESET); + + if (ret < 0) { + dev_err(di->dev, "ab8500 write failed %d\n", __LINE__); + return ret; + } + + ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset); + if (ret < 0) { + dev_err(di->dev, "failed to enable AC charger %d\n", + __LINE__); + return ret; + } + } + return ret; +} + /** * ab8500_charger_watchdog_kick() - kick charger watchdog * @di: pointer to the ab8500_charger structure @@ -1734,8 +1834,7 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, /* Reset the main and usb drop input current measurement counter */ ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CHARGER_CTRL, - 0x1); + AB8500_CHARGER_CTRL, DROP_COUNT_RESET); if (ret) { dev_err(di->dev, "%s write failed\n", __func__); return ret; @@ -3221,6 +3320,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), /* ux500_charger sub-class */ di->ac_chg.ops.enable = &ab8500_charger_ac_en; + di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable; di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ @@ -3242,6 +3342,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), /* ux500_charger sub-class */ di->usb_chg.ops.enable = &ab8500_charger_usb_en; + di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 31507bfe549c..8ab65a3a8190 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -305,6 +305,30 @@ static void abx500_chargalg_state_to(struct abx500_chargalg *di, di->charge_state = state; } +static int abx500_chargalg_check_charger_enable(struct abx500_chargalg *di) +{ + switch (di->charge_state) { + case STATE_NORMAL: + case STATE_MAINTENANCE_A: + case STATE_MAINTENANCE_B: + break; + default: + return 0; + } + + if (di->chg_info.charger_type & USB_CHG) { + return di->usb_chg->ops.check_enable(di->usb_chg, + di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, + di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + } else if ((di->chg_info.charger_type & AC_CHG) && + !(di->ac_chg->external)) { + return di->ac_chg->ops.check_enable(di->ac_chg, + di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, + di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + } + return 0; +} + /** * abx500_chargalg_check_charger_connection() - Check charger connection change * @di: pointer to the abx500_chargalg structure @@ -1219,6 +1243,7 @@ static void abx500_chargalg_external_power_changed(struct power_supply *psy) static void abx500_chargalg_algorithm(struct abx500_chargalg *di) { int charger_status; + int ret; /* Collect data from all power_supply class devices */ class_for_each_device(power_supply_class, NULL, @@ -1229,6 +1254,14 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) abx500_chargalg_check_charger_voltage(di); charger_status = abx500_chargalg_check_charger_connection(di); + + if (is_ab8500(di->parent)) { + ret = abx500_chargalg_check_charger_enable(di); + if (ret < 0) + dev_err(di->dev, "Checking charger is enabled error" + ": Returned Value %d\n", ret); + } + /* * First check if we have a charger connected. * Also we don't allow charging of unknown batteries if configured diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index d43ac0f35526..110d12f09548 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -17,6 +17,7 @@ struct ux500_charger; struct ux500_charger_ops { int (*enable) (struct ux500_charger *, int, int, int); + int (*check_enable) (struct ux500_charger *, int, int); int (*kick_wd) (struct ux500_charger *); int (*update_curr) (struct ux500_charger *, int); }; -- cgit From 789ca7b46877f29b2aaa94401319c50be35b184f Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Tue, 19 Jun 2012 10:21:24 +0530 Subject: pm2301-charger: Support for over voltage protection on the ab9540 Added support for main charger over voltage protection. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Tested-by: Michel JAOUEN --- drivers/power/pm2301_charger.c | 50 ++++++++++++++++++++++++++++++------------ drivers/power/pm2301_charger.h | 1 + 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b2f2d4188da9..b560fa5ac4e7 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -227,21 +227,14 @@ int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val) static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) { - int ret = 0; + dev_err(pm2->dev, "Overvoltage detected\n"); + pm2->flags.ovv = true; + power_supply_changed(&pm2->ac_chg.psy); - pm2->failure_input_ovv++; - if (pm2->failure_input_ovv < 4) { - ret = pm2xxx_charging_enable_mngt(pm2); - goto out; - } else { - pm2->failure_input_ovv = 0; - dev_err(pm2->dev, "Overvoltage detected\n"); - pm2->flags.ovv = true; - power_supply_changed(&pm2->ac_chg.psy); - } + /* Schedule a new HW failure check */ + queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0); -out: - return ret; + return 0; } static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) @@ -630,6 +623,8 @@ static int pm2xxx_charger_ac_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_HEALTH_DEAD; else if (pm2->flags.main_thermal_prot) val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + else if (pm2->flags.ovv) + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; else val->intval = POWER_SUPPLY_HEALTH_GOOD; break; @@ -860,6 +855,30 @@ static void pm2xxx_charger_ac_work(struct work_struct *work) sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); }; +static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) +{ + u8 reg_value; + + struct pm2xxx_charger *pm2 = container_of(work, + struct pm2xxx_charger, check_hw_failure_work.work); + + if (pm2->flags.ovv) { + pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, ®_value); + + if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV | + PM2XXX_INT4_S_ITVPWR2OVV))) { + pm2->flags.ovv = false; + power_supply_changed(&pm2->ac_chg.psy); + } + } + + /* If we still have a failure, schedule a new check */ + if (pm2->flags.ovv) { + queue_delayed_work(pm2->charger_wq, + &pm2->check_hw_failure_work, round_jiffies(HZ)); + } +} + static void pm2xxx_charger_check_main_thermal_prot_work( struct work_struct *work) { @@ -983,6 +1002,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, INIT_WORK(&pm2->check_main_thermal_prot_work, pm2xxx_charger_check_main_thermal_prot_work); + /* Init work for HW failure check */ + INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work, + pm2xxx_charger_check_hw_failure_work); + /* * VDD ADC supply needs to be enabled from this driver when there * is a charger connected to avoid erroneous BTEMP_HIGH/LOW @@ -1123,4 +1146,3 @@ MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); MODULE_ALIAS("platform:pm2xxx-charger"); MODULE_DESCRIPTION("PM2xxx charger management driver"); - diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h index e6319cdbc94f..fad1f387f8f4 100644 --- a/drivers/power/pm2301_charger.h +++ b/drivers/power/pm2301_charger.h @@ -506,6 +506,7 @@ struct pm2xxx_charger { struct delayed_work check_vbat_work; struct work_struct ac_work; struct work_struct check_main_thermal_prot_work; + struct delayed_work check_hw_failure_work; struct ux500_charger ac_chg; struct pm2xxx_charger_event_flags flags; }; -- cgit From 8891716e24d7b0f4b1c3b4fdff641bcb1fb282c4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 13 Feb 2013 11:39:19 +0000 Subject: ab8500-bm: Charge only mode fixes for the ab9540 Fix for charging not getting enabled in charge only mode by external charger. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 42 +++++++++++++++++++++++++++++++ drivers/power/abx500_chargalg.c | 14 +++++++++++ drivers/power/pm2301_charger.c | 7 ++++++ include/linux/mfd/abx500/ux500_chargalg.h | 2 ++ 4 files changed, 65 insertions(+) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 3eb23cf9ff47..f1d712308b02 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,10 @@ #define AB8500_SW_CONTROL_FALLBACK 0x03 /* Wait for enumeration before charing in us */ #define WAIT_ACA_RID_ENUMERATION (5 * 1000) +/*External charger control*/ +#define AB8500_SYS_CHARGER_CONTROL_REG 0x52 +#define EXTERNAL_CHARGER_DISABLE_REG_VAL 0x03 +#define EXTERNAL_CHARGER_ENABLE_REG_VAL 0x07 /* UsbLineStatus register - usb types */ enum ab8500_charger_link_status { @@ -1678,6 +1683,29 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, return ret; } +static int ab8500_external_charger_prepare(struct notifier_block *charger_nb, + unsigned long event, void *data) +{ + int ret; + struct device *dev = data; + /*Toggle External charger control pin*/ + ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, + AB8500_SYS_CHARGER_CONTROL_REG, + EXTERNAL_CHARGER_DISABLE_REG_VAL); + if (ret < 0) { + dev_err(dev, "write reg failed %d\n", ret); + goto out; + } + ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, + AB8500_SYS_CHARGER_CONTROL_REG, + EXTERNAL_CHARGER_ENABLE_REG_VAL); + if (ret < 0) + dev_err(dev, "Write reg failed %d\n", ret); + +out: + return ret; +} + /** * ab8500_charger_usb_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure @@ -3221,6 +3249,10 @@ static int ab8500_charger_suspend(struct platform_device *pdev, #define ab8500_charger_resume NULL #endif +static struct notifier_block charger_nb = { + .notifier_call = ab8500_external_charger_prepare, +}; + static int ab8500_charger_remove(struct platform_device *pdev) { struct ab8500_charger *di = platform_get_drvdata(pdev); @@ -3250,6 +3282,11 @@ static int ab8500_charger_remove(struct platform_device *pdev) /* Delete the work queue */ destroy_workqueue(di->charger_wq); + /* Unregister external charger enable notifier */ + if (!di->ac_chg.enabled) + blocking_notifier_chain_unregister( + &charger_notifier_list, &charger_nb); + flush_scheduled_work(); if (di->usb_chg.enabled) power_supply_unregister(&di->usb_chg.psy); @@ -3331,6 +3368,11 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.enabled = di->bm->ac_enabled; di->ac_chg.external = false; + /*notifier for external charger enabling*/ + if (!di->ac_chg.enabled) + blocking_notifier_chain_register( + &charger_notifier_list, &charger_nb); + /* USB supply */ /* power_supply base class */ di->usb_chg.psy.name = "ab8500_usb"; diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 8ab65a3a8190..a876976678ab 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Watchdog kick interval */ #define CHG_WD_INTERVAL (6 * HZ) @@ -243,6 +244,9 @@ struct abx500_chargalg { struct kobject chargalg_kobject; }; +/*External charger prepare notifier*/ +BLOCKING_NOTIFIER_HEAD(charger_notifier_list); + /* Main battery properties */ static enum power_supply_property abx500_chargalg_props[] = { POWER_SUPPLY_PROP_STATUS, @@ -503,6 +507,8 @@ static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di) static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable, int vset, int iset) { + static int abx500_chargalg_ex_ac_enable_toggle; + if (!di->ac_chg || !di->ac_chg->ops.enable) return -ENXIO; @@ -515,6 +521,14 @@ static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable, di->chg_info.ac_iset = iset; di->chg_info.ac_vset = vset; + /* Enable external charger */ + if (enable && di->ac_chg->external && + !abx500_chargalg_ex_ac_enable_toggle) { + blocking_notifier_call_chain(&charger_notifier_list, + 0, di->dev); + abx500_chargalg_ex_ac_enable_toggle++; + } + return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset); } diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b560fa5ac4e7..45ef3b9de6b9 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1059,6 +1059,13 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { + /* + * When boot is due to AC charger plug-in, + * read interrupt registers + */ + pm2xxx_reg_read(pm2, PM2XXX_REG_INT1, &val); + pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); + pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; pm2->ac_conn = true; power_supply_changed(&pm2->ac_chg.psy); diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index 110d12f09548..fa831f1e8cf8 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -41,4 +41,6 @@ struct ux500_charger { bool external; }; +extern struct blocking_notifier_head charger_notifier_list; + #endif -- cgit From 54fbbb6242247d06d21e21bbcf4ae8339bd75592 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Thu, 5 Jul 2012 16:52:55 +0200 Subject: pm2301-charger: Force main charger detect Force main charger detect in turn on status. Signed-off-by: Rajkumar Kasirajan Signed-off-by: Per Forlin Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS Tested-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 45ef3b9de6b9..3f02636c48a5 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1067,6 +1067,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; + ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, + AB8500_MAIN_CH_DET); pm2->ac_conn = true; power_supply_changed(&pm2->ac_chg.psy); sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); -- cgit From 49fddeec9fbb0dd58507185104812fde77c38def Mon Sep 17 00:00:00 2001 From: Mustapha Ben Zoubeir Date: Wed, 27 Jun 2012 15:40:58 +0200 Subject: pm2301-charger: Resolve I2C detection problem on ab9540 Signed-off-by: Mustapha Ben Zoubeir Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS Tested-by: Olivier CLERGEAUD --- drivers/power/pm2301_charger.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 3f02636c48a5..a95edae925f8 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -34,6 +34,8 @@ #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ struct pm2xxx_charger, ac_chg) +#define SLEEP_MIN 50 +#define SLEEP_MAX 100 static int pm2xxx_interrupt_registers[] = { PM2XXX_REG_INT1, @@ -113,17 +115,14 @@ static const struct i2c_device_id pm2xxx_ident[] = { static void set_lpn_pin(struct pm2xxx_charger *pm2) { - if (pm2->ac.charger_connected) - return; gpio_set_value(pm2->lpn_pin, 1); + usleep_range(SLEEP_MIN, SLEEP_MAX); return; } static void clear_lpn_pin(struct pm2xxx_charger *pm2) { - if (pm2->ac.charger_connected) - return; gpio_set_value(pm2->lpn_pin, 0); return; @@ -139,7 +138,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) * and receive I2C "acknowledge" from PM2301. */ mutex_lock(&pm2->lock); - set_lpn_pin(pm2); ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, val); @@ -147,7 +145,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); else ret = 0; - clear_lpn_pin(pm2); mutex_unlock(&pm2->lock); return ret; @@ -163,7 +160,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) * and receive I2C "acknowledge" from PM2301. */ mutex_lock(&pm2->lock); - set_lpn_pin(pm2); ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, &val); @@ -171,7 +167,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); else ret = 0; - clear_lpn_pin(pm2); mutex_unlock(&pm2->lock); return ret; @@ -478,7 +473,6 @@ static int pm2_int_reg5(void *pm2_data, int val) struct pm2xxx_charger *pm2 = pm2_data; int ret = 0; - if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); } @@ -899,12 +893,34 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = { static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) { + struct pm2xxx_charger *pm2; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); + set_lpn_pin(pm2); + + /* If we still have a HW failure, schedule a new check */ + if (pm2->flags.ovv) + queue_delayed_work(pm2->charger_wq, + &pm2->check_hw_failure_work, 0); + return 0; } static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, pm_message_t state) { + struct pm2xxx_charger *pm2; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); + clear_lpn_pin(pm2); + + /* Cancel any pending HW failure check */ + if (delayed_work_pending(&pm2->check_hw_failure_work)) + cancel_delayed_work(&pm2->check_hw_failure_work); + + flush_work(&pm2->ac_work); + flush_work(&pm2->check_main_thermal_prot_work); + return 0; } @@ -1056,6 +1072,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, goto free_gpio; } + set_lpn_pin(pm2); ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { -- cgit From f7470b5d246294761892f4bafc0eeedaa4369d92 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 14 Feb 2013 12:37:29 +0000 Subject: ab8500_charger: Prevent auto drop of VBUS Do not set higher current in stepping functionality if VBUS is dropping. After VBUS has dropped try to set current once again. If dropping again then we have found the maximum capability of the charger. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 169 +++++++++++++++++++++++++++++------------ 1 file changed, 120 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index f1d712308b02..547f6ea1b695 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -58,6 +58,7 @@ #define MAIN_CH_INPUT_CURR_SHIFT 4 #define VBUS_IN_CURR_LIM_SHIFT 4 #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 +#define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ #define LED_INDICATOR_PWM_ENA 0x01 #define LED_INDICATOR_PWM_DIS 0x00 @@ -202,10 +203,15 @@ struct ab8500_charger_usb_state { spinlock_t usb_lock; }; +struct ab8500_charger_max_usb_in_curr { + int usb_type_max; + int set_max; + int calculated_max; +}; + /** * struct ab8500_charger - ab8500 Charger device information * @dev: Pointer to the structure device - * @max_usb_in_curr: Max USB charger input current * @vbus_detected: VBUS detected * @vbus_detected_start: * VBUS detected during startup @@ -220,7 +226,6 @@ struct ab8500_charger_usb_state { * @autopower Indicate if we should have automatic pwron after pwrloss * @autopower_cfg platform specific power config support for "pwron after pwrloss" * @invalid_charger_detect_state State when forcing AB to use invalid charger - * @is_usb_host: Indicate if last detected USB type is host * @is_aca_rid: Incicate if accessory is ACA type * @current_stepping_sessions: * Counter for current stepping sessions @@ -229,6 +234,7 @@ struct ab8500_charger_usb_state { * @bm: Platform specific battery management information * @flags: Structure for information about events triggered * @usb_state: Structure for usb stack information + * @max_usb_in_curr: Max USB charger input current * @ac_chg: AC charger power supply * @usb_chg: USB charger power supply * @ac: Structure that holds the AC charger properties @@ -260,7 +266,6 @@ struct ab8500_charger_usb_state { */ struct ab8500_charger { struct device *dev; - int max_usb_in_curr; bool vbus_detected; bool vbus_detected_start; bool ac_conn; @@ -272,7 +277,6 @@ struct ab8500_charger { bool autopower; bool autopower_cfg; int invalid_charger_detect_state; - bool is_usb_host; int is_aca_rid; atomic_t current_stepping_sessions; struct ab8500 *parent; @@ -280,6 +284,7 @@ struct ab8500_charger { struct abx500_bm_data *bm; struct ab8500_charger_event_flags flags; struct ab8500_charger_usb_state usb_state; + struct ab8500_charger_max_usb_in_curr max_usb_in_curr; struct ux500_charger ac_chg; struct ux500_charger usb_chg; struct ab8500_charger_info ac; @@ -421,6 +426,10 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, if (connected != di->usb.charger_connected) { dev_dbg(di->dev, "USB connected:%i\n", connected); di->usb.charger_connected = connected; + + if (!connected) + di->flags.vbus_drop_end = false; + sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); if (connected) { @@ -674,23 +683,19 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, case USB_STAT_STD_HOST_C_S: dev_dbg(di->dev, "USB Type - Standard host is " "detected through USB driver\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - di->is_usb_host = true; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_HOST_CHG_HS_CHIRP: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - di->is_usb_host = true; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_HOST_CHG_HS: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - di->is_usb_host = true; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_C_HS: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; - di->is_usb_host = false; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_A: @@ -699,8 +704,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, * can consume (900mA). Closest level is 500mA */ dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - di->is_usb_host = false; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 1; break; case USB_STAT_ACA_RID_B: @@ -708,38 +712,35 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, * Dedicated charger level minus 120mA (20mA for ACA and * 100mA for potential accessory). Closest level is 1300mA */ - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P3; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, - di->max_usb_in_curr); - di->is_usb_host = false; + di->max_usb_in_curr.usb_type_max); di->is_aca_rid = 1; break; case USB_STAT_HOST_CHG_NM: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - di->is_usb_host = true; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_DEDICATED_CHG: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; - di->is_usb_host = false; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_C_HS_CHIRP: case USB_STAT_ACA_RID_C_NM: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; - di->is_usb_host = false; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; di->is_aca_rid = 1; break; case USB_STAT_NOT_CONFIGURED: if (di->vbus_detected) { di->usb_device_is_unrecognised = true; dev_dbg(di->dev, "USB Type - Legacy charger.\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; + di->max_usb_in_curr.usb_type_max = + USB_CH_IP_CUR_LVL_1P5; break; } case USB_STAT_HM_IDGND: dev_err(di->dev, "USB Type - Charging not allowed\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; ret = -ENXIO; break; case USB_STAT_RESERVED: @@ -752,9 +753,11 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, } if (is_ab9540(di->parent) || is_ab8505(di->parent)) { dev_dbg(di->dev, "USB Type - Charging not allowed\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max = + USB_CH_IP_CUR_LVL_0P05; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", - link_status, di->max_usb_in_curr); + link_status, + di->max_usb_in_curr.usb_type_max); ret = -ENXIO; break; } @@ -763,23 +766,24 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, case USB_STAT_CARKIT_2: case USB_STAT_ACA_DOCK_CHARGER: case USB_STAT_CHARGER_LINE_1: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, - di->max_usb_in_curr); + di->max_usb_in_curr.usb_type_max); case USB_STAT_NOT_VALID_LINK: dev_err(di->dev, "USB Type invalid - try charging anyway\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; break; default: dev_err(di->dev, "USB Type - Unknown\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; ret = -ENXIO; break; }; + di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", - link_status, di->max_usb_in_curr); + link_status, di->max_usb_in_curr.set_max); return ret; } @@ -1083,28 +1087,48 @@ static int ab8500_vbus_in_curr_to_regval(int curr) */ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) { + int ret = 0; switch (di->usb_state.usb_current) { case 100: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P09; break; case 200: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P19; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P19; break; case 300: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P29; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P29; break; case 400: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P38; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P38; break; case 500: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; break; default: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; - return -1; + di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; + ret = -EPERM; break; }; - return 0; + di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; + return ret; +} + +/** + * ab8500_charger_check_continue_stepping() - Check to allow stepping + * @di: pointer to the ab8500_charger structure + * @reg: select what charger register to check + * + * Check if current stepping should be allowed to continue. + * Checks if charger source has not collapsed. If it has, further stepping + * is not allowed. + */ +static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di, + int reg) +{ + if (reg == AB8500_USBCH_IPT_CRNTLVL_REG) + return !di->flags.vbus_drop_end; + else + return true; } /** @@ -1225,7 +1249,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, usleep_range(step_udelay, step_udelay * 2); } } else { - for (i = prev_curr_index + 1; i <= curr_index; i++) { + bool allow = true; + for (i = prev_curr_index + 1; i <= curr_index && allow; i++) { dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", (u8)i << shift_value, reg); ret = abx500_set_register_interruptible(di->dev, @@ -1236,6 +1261,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, } if (i != curr_index) usleep_range(step_udelay, step_udelay * 2); + + allow = ab8500_charger_check_continue_stepping(di, reg); } } @@ -1261,6 +1288,11 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, /* We should always use to lowest current limit */ min_value = min(di->bm->chg_params->usb_curr_max, ich_in); + if (di->max_usb_in_curr.set_max > 0) + min_value = min(di->max_usb_in_curr.set_max, min_value); + + if (di->usb_state.usb_current >= 0) + min_value = min(di->usb_state.usb_current, min_value); switch (min_value) { case 100: @@ -1615,7 +1647,8 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, di->usb.charger_online = 1; /* USBChInputCurr: current that can be drawn from the usb */ - ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); + ret = ab8500_charger_set_vbus_in_curr(di, + di->max_usb_in_curr.usb_type_max); if (ret) { dev_err(di->dev, "setting USBChInputCurr failed\n"); return ret; @@ -1950,9 +1983,10 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) di->vbat > VBAT_TRESH_IP_CUR_RED))) { dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," - " old: %d\n", di->max_usb_in_curr, di->vbat, - di->old_vbat); - ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); + " old: %d\n", di->max_usb_in_curr.usb_type_max, + di->vbat, di->old_vbat); + ab8500_charger_set_vbus_in_curr(di, + di->max_usb_in_curr.usb_type_max); power_supply_changed(&di->usb_chg.psy); } @@ -2232,7 +2266,8 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) /* Update maximum input current if USB enumeration is not detected */ if (!di->usb.charger_online) { - ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); + ret = ab8500_charger_set_vbus_in_curr(di, + di->max_usb_in_curr.usb_type_max); if (ret) return; } @@ -2400,7 +2435,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) if (!ab8500_charger_get_usb_cur(di)) { /* Update maximum input current */ ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr); + di->max_usb_in_curr.usb_type_max); if (ret) return; @@ -2618,15 +2653,45 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) { struct ab8500_charger *di = container_of(work, struct ab8500_charger, vbus_drop_end_work.work); + int ret; + u8 reg_value; di->flags.vbus_drop_end = false; /* Reset the drop counter */ abx500_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8500_CH_USBCH_STAT2_REG, + ®_value); + if (ret < 0) { + dev_err(di->dev, "%s ab8500 read failed\n", __func__); + } else { + int curr = ab8500_charger_vbus_in_curr_map[ + reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; + if (di->max_usb_in_curr.calculated_max != curr) { + /* USB source is collapsing */ + di->max_usb_in_curr.calculated_max = curr; + dev_dbg(di->dev, + "VBUS input current limiting to %d mA\n", + di->max_usb_in_curr.calculated_max); + } else { + /* + * USB source can not give more than this amount. + * Taking more will collapse the source. + */ + di->max_usb_in_curr.set_max = + di->max_usb_in_curr.calculated_max; + dev_dbg(di->dev, + "VBUS input current limited to %d mA\n", + di->max_usb_in_curr.set_max); + return; + } + } if (di->usb.charger_connected) - ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); + ab8500_charger_set_vbus_in_curr(di, + di->max_usb_in_curr.usb_type_max); } /** @@ -2781,8 +2846,13 @@ static irqreturn_t ab8500_charger_vbuschdropend_handler(int irq, void *_di) dev_dbg(di->dev, "VBUS charger drop ended\n"); di->flags.vbus_drop_end = true; + + /* + * VBUS might have dropped due to bad connection. + * Schedule a new input limit set to the value SW requests. + */ queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, - round_jiffies(30 * HZ)); + round_jiffies(VBUS_IN_CURR_LIM_RETRY_SET_TIME * HZ)); return IRQ_HANDLED; } @@ -3394,6 +3464,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.enabled = di->bm->usb_enabled; di->usb_chg.external = false; + di->usb_state.usb_current = -1; /* Create a work queue for the charger */ di->charger_wq = -- cgit From da9e83d496039458fe9863540cf52b3f9b450675 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Mon, 16 Jul 2012 12:45:19 +0530 Subject: pm2301-charger: Die temp thermal protection This patch adds support for die temperature thermal protection in pm2301 driver. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Hakan BERG Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a95edae925f8..ae647c41c535 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -876,7 +876,27 @@ static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) static void pm2xxx_charger_check_main_thermal_prot_work( struct work_struct *work) { -}; + int ret; + u8 val; + + struct pm2xxx_charger *pm2 = container_of(work, struct pm2xxx_charger, + check_main_thermal_prot_work); + + /* Check if die temp warning is still active */ + ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT5, &val); + if (ret < 0) { + dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); + return; + } + if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGRISE + | PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE)) + pm2->flags.main_thermal_prot = true; + else if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGFALL + | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL)) + pm2->flags.main_thermal_prot = false; + + power_supply_changed(&pm2->ac_chg.psy); +} static struct pm2xxx_interrupts pm2xxx_int = { .handler[0] = pm2_int_reg0, -- cgit From d4f510f6c3f579bac0dbeaa8dc7c2dc768c31786 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Thu, 28 Jun 2012 18:31:19 +0530 Subject: pm2301-charger: Wake system when ext charger is plugged-in When in suspend state, upon plug-in of external AC charger the device needs to wake-up and charging operation started. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ae647c41c535..b8eafc3850d0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1072,6 +1072,12 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); goto unregister_pm2xxx_charger; } + /* pm interrupt can wake up system */ + ret = enable_irq_wake(pm2->pdata->irq_number); + if (ret) { + dev_err(pm2->dev, "failed to set irq wake\n"); + goto unregister_pm2xxx_interrupt; + } /*Initialize lock*/ mutex_init(&pm2->lock); @@ -1084,7 +1090,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); if (ret < 0) { dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); - goto unregister_pm2xxx_charger; + goto disable_pm2_irq_wake; } ret = gpio_direction_output(pm2->lpn_pin, 0); if (ret < 0) { @@ -1115,6 +1121,11 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, free_gpio: gpio_free(pm2->lpn_pin); +disable_pm2_irq_wake: + disable_irq_wake(pm2->pdata->irq_number); +unregister_pm2xxx_interrupt: + /* disable interrupt */ + free_irq(pm2->pdata->irq_number, pm2); unregister_pm2xxx_charger: /* unregister power supply */ power_supply_unregister(&pm2->ac_chg.psy); @@ -1125,6 +1136,7 @@ free_charger_wq: destroy_workqueue(pm2->charger_wq); free_device_info: kfree(pm2); + return ret; } @@ -1135,6 +1147,9 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) /* Disable AC charging */ pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); + /* Disable wake by pm interrupt */ + disable_irq_wake(pm2->pdata->irq_number); + /* Disable interrupts */ free_irq(pm2->pdata->irq_number, pm2); -- cgit From 908fe8d6a575e2bdf349ba8635b862eeb91f7ade Mon Sep 17 00:00:00 2001 From: Hakan Berg Date: Tue, 17 Jul 2012 14:17:16 +0200 Subject: ab8500-btemp: Filter btemp readings Battery tempreature readings sometimes fail and results in a value far from recent values. This patch adds a software filter that disposes such readings, by allowing direct updates on temperature only if two samples result in the same temperature. Else only allow 1 degree change from previous reported value in the direction of the new measurement. Signed-off-by: Hakan Berg Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Martin SJOBLOM Reviewed-by: Rabin VINCENT --- drivers/power/ab8500_btemp.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 07689064996e..fa60e3ac33a3 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -76,8 +76,8 @@ struct ab8500_btemp_ranges { * @dev: Pointer to the structure device * @node: List of AB8500 BTEMPs, hence prepared for reentrance * @curr_source: What current source we use, in uA - * @bat_temp: Battery temperature in degree Celcius - * @prev_bat_temp Last dispatched battery temperature + * @bat_temp: Dispatched battery temperature in degree Celcius + * @prev_bat_temp Last measured battery temperature in degree Celcius * @parent: Pointer to the struct ab8500 * @gpadc: Pointer to the struct gpadc * @fg: Pointer to the struct fg @@ -604,6 +604,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) static void ab8500_btemp_periodic_work(struct work_struct *work) { int interval; + int bat_temp; struct ab8500_btemp *di = container_of(work, struct ab8500_btemp, btemp_periodic_work.work); @@ -614,12 +615,26 @@ static void ab8500_btemp_periodic_work(struct work_struct *work) dev_warn(di->dev, "failed to identify the battery\n"); } - di->bat_temp = ab8500_btemp_measure_temp(di); - - if (di->bat_temp != di->prev_bat_temp) { - di->prev_bat_temp = di->bat_temp; + bat_temp = ab8500_btemp_measure_temp(di); + /* + * Filter battery temperature. + * Allow direct updates on temperature only if two samples result in + * same temperature. Else only allow 1 degree change from previous + * reported value in the direction of the new measurement. + */ + if (bat_temp == di->prev_bat_temp || !di->initialized) { + if (di->bat_temp != di->prev_bat_temp || !di->initialized) { + di->bat_temp = bat_temp; + power_supply_changed(&di->btemp_psy); + } + } else if (bat_temp < di->prev_bat_temp) { + di->bat_temp--; + power_supply_changed(&di->btemp_psy); + } else if (bat_temp > di->prev_bat_temp) { + di->bat_temp++; power_supply_changed(&di->btemp_psy); } + di->prev_bat_temp = bat_temp; if (di->events.ac_conn || di->events.usb_conn) interval = di->bm->temp_interval_chg; -- cgit From 642776182c2412739f433d84da0ab8872a0509a8 Mon Sep 17 00:00:00 2001 From: Hakan Berg Date: Mon, 23 Jul 2012 14:00:50 +0200 Subject: ab8500-fg: Allow capacity to raise from 1% when charging When battery capacity was going below 1% fg is not supposed to report 0% unless we've got the LOW_BAT IRQ, no matter what the FG-algorithm says. This made fg get stuck at 1% if charger is connected when capacity is 1%. Signed-off-by: Hakan BERG Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Srinidhi KASAGAR --- drivers/power/ab8500_fg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index a747c5ce3b27..d1f93098a412 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -1354,9 +1354,6 @@ static void ab8500_fg_check_capacity_limits(struct ab8500_fg *di, bool init) * algorithm says. */ di->bat_cap.prev_percent = 1; - di->bat_cap.permille = 1; - di->bat_cap.prev_mah = 1; - di->bat_cap.mah = 1; percent = 1; changed = true; @@ -1768,9 +1765,10 @@ static void ab8500_fg_algorithm(struct ab8500_fg *di) ab8500_fg_algorithm_discharging(di); } - dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d " + dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d %d " "%d %d %d %d %d %d %d\n", di->bat_cap.max_mah_design, + di->bat_cap.max_mah, di->bat_cap.mah, di->bat_cap.permille, di->bat_cap.level, -- cgit From d4337660d06945c9772182b5b8e72443ae3e475d Mon Sep 17 00:00:00 2001 From: Hakan Berg Date: Thu, 26 Jul 2012 11:10:35 +0200 Subject: ab8500-charger: Add AB8505_USB_LINK_STATUS The AB8505 does not have the same address for USB link-status as has ab8500. Add AB8505_USB_LINK_STATUS and code to switch to correct constant. Signed-off-by: Hakan Berg Signed-off-by: Lee Jones Reviewed-by: Mian Yousaf KAUKAB Reviewed-by: Marcus COOPER Reviewed-by: Rabin VINCENT --- drivers/power/ab8500_charger.c | 43 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 547f6ea1b695..b5c7a3975024 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -80,6 +80,7 @@ /* UsbLineStatus register bit masks */ #define AB8500_USB_LINK_STATUS 0x78 +#define AB8505_USB_LINK_STATUS 0xF8 #define AB8500_STD_HOST_SUSP 0x18 /* Watchdog timeout constant */ @@ -809,10 +810,12 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) if (is_ab8500(di->parent)) { ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); - } else { - if (is_ab9540(di->parent) || is_ab8505(di->parent)) + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; } if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); @@ -820,7 +823,14 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) } /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; + if (is_ab8500(di->parent)) { + val = (val & AB8500_USB_LINK_STATUS) >> 3; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + val = (val & AB8505_USB_LINK_STATUS) >> 3; + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } ret = ab8500_charger_max_usb_curr(di, (enum ab8500_charger_link_status) val); @@ -856,12 +866,16 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) return ret; } - if (is_ab8500(di->parent)) + if (is_ab8500(di->parent)) { ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); - else + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); return ret; @@ -875,7 +889,14 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) */ /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; + if (is_ab8500(di->parent)) { + val = (val & AB8500_USB_LINK_STATUS) >> 3; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + val = (val & AB8505_USB_LINK_STATUS) >> 3; + } else { + dev_err(di->dev, "%s unsupported analog baseband\n", __func__); + return -ENXIO; + } if (val) break; } @@ -2287,6 +2308,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) int detected_chargers; int ret; u8 val; + u8 link_status; struct ab8500_charger *di = container_of(work, struct ab8500_charger, usb_link_status_work); @@ -2313,8 +2335,13 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) else dev_dbg(di->dev, "Error reading USB link status\n"); + if (is_ab9540(di->parent) || is_ab8505(di->parent)) + link_status = AB8505_USB_LINK_STATUS; + else + link_status = AB8500_USB_LINK_STATUS; + if (detected_chargers & USB_PW_CONN) { - if (((val & AB8500_USB_LINK_STATUS) >> 3) == USB_STAT_NOT_VALID_LINK && + if (((val & link_status) >> 3) == USB_STAT_NOT_VALID_LINK && di->invalid_charger_detect_state == 0) { dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); /*Enable charger*/ @@ -2337,7 +2364,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); dev_dbg(di->dev, "USB link status= 0x%02x\n", - (val & AB8500_USB_LINK_STATUS) >> 3); + (val & link_status) >> 3); di->invalid_charger_detect_state = 2; } } else { -- cgit From 405fea1c6691eb8259f2ca879c9348a4cf5d898d Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Fri, 10 Aug 2012 12:59:06 +0200 Subject: pm2301-charger: Always compile the PM2301 Charger driver with AB8500 Battery Mgnt The PM2301 Charger should always be available when using the AB8500 Battery Management system, we're ensuring this will be the case. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Hakan BERG Reviewed-by: Mian Yousaf KAUKAB --- drivers/power/Kconfig | 7 ------- drivers/power/Makefile | 3 +-- drivers/power/ab8500_charger.c | 6 +++--- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 9e00c389e777..07e1a8f8d03e 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -353,13 +353,6 @@ config BATTERY_GOLDFISH Say Y to enable support for the battery and AC power in the Goldfish emulator. -config CHARGER_PM2301 - bool "PM2301 Battery Charger Driver" - depends on AB8500_BM - help - Say Y to include support for PM2301 charger driver. - Depends on AB8500 battery management core. - source "drivers/power/reset/Kconfig" endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 3f66436af45c..eb520ea74970 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o -obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o +obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o @@ -47,7 +47,6 @@ obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o -obj-$(CONFIG_CHARGER_PM2301) += pm2301_charger.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index b5c7a3975024..6fea4fdf8701 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -3387,10 +3387,10 @@ static int ab8500_charger_remove(struct platform_device *pdev) flush_scheduled_work(); if (di->usb_chg.enabled) power_supply_unregister(&di->usb_chg.psy); -#if !defined(CONFIG_CHARGER_PM2301) - if (di->ac_chg.enabled) + + if (di->ac_chg.enabled && !di->ac_chg.external) power_supply_unregister(&di->ac_chg.psy); -#endif + platform_set_drvdata(pdev, NULL); return 0; -- cgit From db43e6c473b57d4e7a55c4bd6edef71f40f13eae Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 14 Feb 2013 12:39:15 +0000 Subject: ab8500-bm: Add usb power path support AB8540 supports power path function in USB charging mode for fast power up with dead and weak battery, and it could extend the battery age. When USB charging starts, if the Vbattrue is below than SW cut off voltage, power path and pre-charge should be enabled. If Vbattrue is higher than SW cut off voltage, power path and pre-charge should be disabled. This is to make sure full current to battery charge. At the end of charge, power path should be enable again to reduce charging the battery again. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 81 +++++++++++++++++++++++++++++++ drivers/power/abx500_chargalg.c | 62 +++++++++++++++++++++++ include/linux/mfd/abx500.h | 1 + include/linux/mfd/abx500/ab8500-bm.h | 12 +++++ include/linux/mfd/abx500/ux500_chargalg.h | 4 ++ 5 files changed, 160 insertions(+) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 6fea4fdf8701..f249a65b02e1 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -1925,6 +1925,67 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, return ret; } +/** + * ab8540_charger_power_path_enable() - enable usb power path mode + * @charger: pointer to the ux500_charger structure + * @enable: enable/disable flag + * + * Enable or disable the power path for usb mode + * Returns error code in case of failure else 0(on success) + */ +static int ab8540_charger_power_path_enable(struct ux500_charger *charger, + bool enable) +{ + int ret; + struct ab8500_charger *di; + + if (charger->psy.type == POWER_SUPPLY_TYPE_USB) + di = to_ab8500_charger_usb_device_info(charger); + else + return -ENXIO; + + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8540_USB_PP_MODE_REG, + BUS_POWER_PATH_MODE_ENA, enable); + if (ret) { + dev_err(di->dev, "%s write failed\n", __func__); + return ret; + } + + return ret; +} + + +/** + * ab8540_charger_usb_pre_chg_enable() - enable usb pre change + * @charger: pointer to the ux500_charger structure + * @enable: enable/disable flag + * + * Enable or disable the pre-chage for usb mode + * Returns error code in case of failure else 0(on success) + */ +static int ab8540_charger_usb_pre_chg_enable(struct ux500_charger *charger, + bool enable) +{ + int ret; + struct ab8500_charger *di; + + if (charger->psy.type == POWER_SUPPLY_TYPE_USB) + di = to_ab8500_charger_usb_device_info(charger); + else + return -ENXIO; + + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8540_USB_PP_CHR_REG, + BUS_POWER_PATH_PRECHG_ENA, enable); + if (ret) { + dev_err(di->dev, "%s write failed\n", __func__); + return ret; + } + + return ret; +} + static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) { struct power_supply *psy; @@ -3201,6 +3262,23 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) if (ret < 0) dev_err(di->dev, "%s mask and set failed\n", __func__); + if (is_ab8540(di->parent)) { + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8540_USB_PP_MODE_REG, + BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); + if (ret) { + dev_err(di->dev, "failed to setup usb power path vsys voltage\n"); + goto out; + } + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8540_USB_PP_CHR_REG, + BUS_PP_PRECHG_CURRENT_MASK, 0); + if (ret) { + dev_err(di->dev, "failed to setup usb power path prechage current\n"); + goto out; + } + } + out: return ret; } @@ -3484,6 +3562,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; + di->usb_chg.ops.pp_enable = &ab8540_charger_power_path_enable; + di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->usb_chg.max_out_curr = ab8500_charger_current_map[ @@ -3491,6 +3571,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.enabled = di->bm->usb_enabled; di->usb_chg.external = false; + di->usb_chg.power_path = di->bm->usb_power_path; di->usb_state.usb_current = -1; /* Create a work queue for the charger */ diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index a876976678ab..a9b8efdafb8f 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -34,6 +34,9 @@ /* End-of-charge criteria counter */ #define EOC_COND_CNT 10 +/* Plus margin for the low battery threshold */ +#define BAT_PLUS_MARGIN (100) + #define to_abx500_chargalg_device_info(x) container_of((x), \ struct abx500_chargalg, chargalg_psy); @@ -83,6 +86,7 @@ enum abx500_chargalg_states { STATE_HW_TEMP_PROTECT_INIT, STATE_HW_TEMP_PROTECT, STATE_NORMAL_INIT, + STATE_USB_PP_PRE_CHARGE, STATE_NORMAL, STATE_WAIT_FOR_RECHARGE_INIT, STATE_WAIT_FOR_RECHARGE, @@ -114,6 +118,7 @@ static const char *states[] = { "HW_TEMP_PROTECT_INIT", "HW_TEMP_PROTECT", "NORMAL_INIT", + "USB_PP_PRE_CHARGE", "NORMAL", "WAIT_FOR_RECHARGE_INIT", "WAIT_FOR_RECHARGE", @@ -560,6 +565,37 @@ static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable, return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset); } + /** + * ab8540_chargalg_usb_pp_en() - Enable/ disable USB power path + * @di: pointer to the abx500_chargalg structure + * @enable: power path enable/disable + * + * The USB power path will be enable/ disable + */ +static int ab8540_chargalg_usb_pp_en(struct abx500_chargalg *di, bool enable) +{ + if (!di->usb_chg || !di->usb_chg->ops.pp_enable) + return -ENXIO; + + return di->usb_chg->ops.pp_enable(di->usb_chg, enable); +} + +/** + * ab8540_chargalg_usb_pre_chg_en() - Enable/ disable USB pre-charge + * @di: pointer to the abx500_chargalg structure + * @enable: USB pre-charge enable/disable + * + * The USB USB pre-charge will be enable/ disable + */ +static int ab8540_chargalg_usb_pre_chg_en(struct abx500_chargalg *di, + bool enable) +{ + if (!di->usb_chg || !di->usb_chg->ops.pre_chg_enable) + return -ENXIO; + + return di->usb_chg->ops.pre_chg_enable(di->usb_chg, enable); +} + /** * abx500_chargalg_update_chg_curr() - Update charger current * @di: pointer to the abx500_chargalg structure @@ -765,6 +801,9 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di) di->batt_data.avg_curr > 0) { if (++di->eoc_cnt >= EOC_COND_CNT) { di->eoc_cnt = 0; + if ((di->chg_info.charger_type & USB_CHG) && + (di->usb_chg->power_path)) + ab8540_chargalg_usb_pp_en(di, true); di->charge_status = POWER_SUPPLY_STATUS_FULL; di->maintenance_chg = true; dev_dbg(di->dev, "EOC reached!\n"); @@ -1465,6 +1504,22 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) break; case STATE_NORMAL_INIT: + if ((di->chg_info.charger_type & USB_CHG) && + di->usb_chg->power_path) { + if (di->batt_data.volt > + (di->bm->fg_params->lowbat_threshold + + BAT_PLUS_MARGIN)) { + ab8540_chargalg_usb_pre_chg_en(di, false); + ab8540_chargalg_usb_pp_en(di, false); + } else { + ab8540_chargalg_usb_pp_en(di, true); + ab8540_chargalg_usb_pre_chg_en(di, true); + abx500_chargalg_state_to(di, + STATE_USB_PP_PRE_CHARGE); + break; + } + } + abx500_chargalg_start_charging(di, di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); @@ -1479,6 +1534,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) break; + case STATE_USB_PP_PRE_CHARGE: + if (di->batt_data.volt > + (di->bm->fg_params->lowbat_threshold + + BAT_PLUS_MARGIN)) + abx500_chargalg_state_to(di, STATE_NORMAL_INIT); + break; + case STATE_NORMAL: handle_maxim_chg_curr(di); if (di->charge_status == POWER_SUPPLY_STATUS_FULL && diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 188aedc322c2..cd71d8eadf50 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -267,6 +267,7 @@ struct abx500_bm_data { bool autopower_cfg; bool ac_enabled; bool usb_enabled; + bool usb_power_path; bool no_maintenance; bool capacity_scaling; bool chg_unknown_bat; diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index a73e05a0441b..0ebf0c5d1f88 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -69,6 +69,8 @@ #define AB8500_USBCH_CTRL1_REG 0xC0 #define AB8500_USBCH_CTRL2_REG 0xC1 #define AB8500_USBCH_IPT_CRNTLVL_REG 0xC2 +#define AB8540_USB_PP_MODE_REG 0xC5 +#define AB8540_USB_PP_CHR_REG 0xC6 /* * Gas Gauge register offsets @@ -259,6 +261,16 @@ enum bup_vch_sel { #define AB8505_RTC_PCUT_RESTART_REG 0x16 #define AB8505_RTC_PCUT_DEBOUNCE_REG 0x17 +/* USB Power Path constants for ab8540 */ +#define BUS_VSYS_VOL_SELECT_MASK 0x06 +#define BUS_VSYS_VOL_SELECT_3P6V 0x00 +#define BUS_VSYS_VOL_SELECT_3P325V 0x02 +#define BUS_VSYS_VOL_SELECT_3P9V 0x04 +#define BUS_VSYS_VOL_SELECT_4P3V 0x06 +#define BUS_POWER_PATH_MODE_ENA 0x01 +#define BUS_PP_PRECHG_CURRENT_MASK 0x0E +#define BUS_POWER_PATH_PRECHG_ENA 0x01 + /** * struct res_to_temp - defines one point in a temp to res curve. To * be used in battery packs that combines the identification resistor with a diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index fa831f1e8cf8..234c99143bf7 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -20,6 +20,8 @@ struct ux500_charger_ops { int (*check_enable) (struct ux500_charger *, int, int); int (*kick_wd) (struct ux500_charger *); int (*update_curr) (struct ux500_charger *, int); + int (*pp_enable) (struct ux500_charger *, bool); + int (*pre_chg_enable) (struct ux500_charger *, bool); }; /** @@ -30,6 +32,7 @@ struct ux500_charger_ops { * @max_out_curr maximum output charger current in mA * @enabled indicates if this charger is used or not * @external external charger unit (pm2xxx) + * @power_path USB power path support */ struct ux500_charger { struct power_supply psy; @@ -39,6 +42,7 @@ struct ux500_charger { int wdt_refresh; bool enabled; bool external; + bool power_path; }; extern struct blocking_notifier_head charger_notifier_list; -- cgit From 2c4c40ac0052eaf9b14009635ab475362e88c6e0 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 22 Aug 2012 15:14:22 +0530 Subject: ab8500-btemp: Defer btemp filtering while initialising Due to btemp filtering enabled during init, temp values reported to charge algorithm driver started from 0. As a result,charge algorithm was going into wrong state and charging was stopped. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Martin SJOBLOM Reviewed-by: Philippe LANGLAIS --- drivers/power/ab8500_btemp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index fa60e3ac33a3..91ad3edf6197 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -609,7 +609,6 @@ static void ab8500_btemp_periodic_work(struct work_struct *work) struct ab8500_btemp, btemp_periodic_work.work); if (!di->initialized) { - di->initialized = true; /* Identify the battery */ if (ab8500_btemp_id(di) < 0) dev_warn(di->dev, "failed to identify the battery\n"); @@ -622,8 +621,9 @@ static void ab8500_btemp_periodic_work(struct work_struct *work) * same temperature. Else only allow 1 degree change from previous * reported value in the direction of the new measurement. */ - if (bat_temp == di->prev_bat_temp || !di->initialized) { - if (di->bat_temp != di->prev_bat_temp || !di->initialized) { + if ((bat_temp == di->prev_bat_temp) || !di->initialized) { + if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { + di->initialized = true; di->bat_temp = bat_temp; power_supply_changed(&di->btemp_psy); } -- cgit From 861a30da53e2c5b9823b5390c1757baaf8f6e356 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 29 Aug 2012 20:36:51 +0800 Subject: ab8500-bm: Add support for the new ab8540 platform Provide AB8540 platform specific information required to run the Battery Management subsystem on AB8540 based devices. For this to happen we see the introduction of separate platform specific data structures and a means in which to process them. Signed-off-by: Lee Jones --- drivers/power/ab8500_bmdata.c | 91 +++++++++++- drivers/power/ab8500_btemp.c | 42 +++++- drivers/power/ab8500_charger.c | 270 +++++++++++++++-------------------- include/linux/mfd/abx500.h | 10 +- include/linux/mfd/abx500/ab8500-bm.h | 5 +- 5 files changed, 248 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c index e8759763fbe0..85742a6d29ff 100644 --- a/drivers/power/ab8500_bmdata.c +++ b/drivers/power/ab8500_bmdata.c @@ -414,13 +414,20 @@ static const struct abx500_fg_parameters fg = { .pcut_debounce_time = 2, }; -static const struct abx500_maxim_parameters maxi_params = { +static const struct abx500_maxim_parameters ab8500_maxi_params = { .ena_maxi = true, .chg_curr = 910, .wait_cycles = 10, .charger_curr_step = 100, }; +static const struct abx500_maxim_parameters abx540_maxi_params = { + .ena_maxi = true, + .chg_curr = 3000, + .wait_cycles = 10, + .charger_curr_step = 200, +}; + static const struct abx500_bm_charger_parameters chg = { .usb_volt_max = 5500, .usb_curr_max = 1500, @@ -428,6 +435,46 @@ static const struct abx500_bm_charger_parameters chg = { .ac_curr_max = 1500, }; +/* + * This array maps the raw hex value to charger output current used by the + * AB8500 values + */ +static int ab8500_charge_output_curr_map[] = { + 100, 200, 300, 400, 500, 600, 700, 800, + 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, +}; + +static int ab8540_charge_output_curr_map[] = { + 0, 0, 0, 75, 100, 125, 150, 175, + 200, 225, 250, 275, 300, 325, 350, 375, + 400, 425, 450, 475, 500, 525, 550, 575, + 600, 625, 650, 675, 700, 725, 750, 775, + 800, 825, 850, 875, 900, 925, 950, 975, + 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, + 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, + 1400, 1425, 1450, 1500, 1600, 1700, 1900, 2000, +}; + +/* + * This array maps the raw hex value to charger input current used by the + * AB8500 values + */ +static int ab8500_charge_input_curr_map[] = { + 50, 98, 193, 290, 380, 450, 500, 600, + 700, 800, 900, 1000, 1100, 1300, 1400, 1500, +}; + +static int ab8540_charge_input_curr_map[] = { + 25, 50, 75, 100, 125, 150, 175, 200, + 225, 250, 275, 300, 325, 350, 375, 400, + 425, 450, 475, 500, 525, 550, 575, 600, + 625, 650, 675, 700, 725, 750, 775, 800, + 825, 850, 875, 900, 925, 950, 975, 1000, + 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, + 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, + 1425, 1450, 1475, 1500, 1500, 1500, 1500, 1500, +}; + struct abx500_bm_data ab8500_bm_data = { .temp_under = 3, .temp_low = 8, @@ -447,15 +494,53 @@ struct abx500_bm_data ab8500_bm_data = { .fg_res = 100, .cap_levels = &cap_levels, .bat_type = bat_type_thermistor, - .n_btypes = 3, + .n_btypes = ARRAY_SIZE(bat_type_thermistor), .batt_id = 0, .interval_charging = 5, .interval_not_charging = 120, .temp_hysteresis = 3, .gnd_lift_resistance = 34, - .maxi = &maxi_params, + .chg_output_curr = ab8500_charge_output_curr_map, + .n_chg_out_curr = ARRAY_SIZE(ab8500_charge_output_curr_map), + .maxi = &ab8500_maxi_params, .chg_params = &chg, .fg_params = &fg, + .chg_input_curr = ab8500_charge_input_curr_map, + .n_chg_in_curr = ARRAY_SIZE(ab8500_charge_input_curr_map), +}; + +struct abx500_bm_data ab8540_bm_data = { + .temp_under = 3, + .temp_low = 8, + .temp_high = 43, + .temp_over = 48, + .main_safety_tmr_h = 4, + .temp_interval_chg = 20, + .temp_interval_nochg = 120, + .usb_safety_tmr_h = 4, + .bkup_bat_v = BUP_VCH_SEL_2P6V, + .bkup_bat_i = BUP_ICH_SEL_150UA, + .no_maintenance = false, + .capacity_scaling = false, + .adc_therm = ABx500_ADC_THERM_BATCTRL, + .chg_unknown_bat = false, + .enable_overshoot = false, + .fg_res = 100, + .cap_levels = &cap_levels, + .bat_type = bat_type_thermistor, + .n_btypes = ARRAY_SIZE(bat_type_thermistor), + .batt_id = 0, + .interval_charging = 5, + .interval_not_charging = 120, + .temp_hysteresis = 3, + .gnd_lift_resistance = 0, + .maxi = &abx540_maxi_params, + .chg_params = &chg, + .fg_params = &fg, + .chg_output_curr = ab8540_charge_output_curr_map, + .n_chg_out_curr = ARRAY_SIZE(ab8540_charge_output_curr_map), + .chg_input_curr = ab8540_charge_input_curr_map, + .n_chg_in_curr = ARRAY_SIZE(ab8540_charge_input_curr_map), }; int ab8500_bm_of_probe(struct device *dev, diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 91ad3edf6197..7336dcf45f7e 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -42,6 +42,9 @@ #define BTEMP_BATCTRL_CURR_SRC_16UA 16 #define BTEMP_BATCTRL_CURR_SRC_18UA 18 +#define BTEMP_BATCTRL_CURR_SRC_60UA 60 +#define BTEMP_BATCTRL_CURR_SRC_120UA 120 + #define to_ab8500_btemp_device_info(x) container_of((x), \ struct ab8500_btemp, btemp_psy); @@ -216,7 +219,12 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, /* Only do this for batteries with internal NTC */ if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { - if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + if (is_ab8540(di->parent)) { + if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_60UA) + curr = BAT_CTRL_60U_ENA; + else + curr = BAT_CTRL_120U_ENA; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) curr = BAT_CTRL_16U_ENA; else @@ -257,7 +265,14 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { dev_dbg(di->dev, "Disable BATCTRL curr source\n"); - if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + if (is_ab8540(di->parent)) { + /* Write 0 to the curr bits */ + ret = abx500_mask_and_set_register_interruptible( + di->dev, + AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, + BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, + ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { /* Write 0 to the curr bits */ ret = abx500_mask_and_set_register_interruptible( di->dev, @@ -314,7 +329,13 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, * if we got an error above */ disable_curr_source: - if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + if (is_ab8540(di->parent)) { + /* Write 0 to the curr bits */ + ret = abx500_mask_and_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, + BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA, + ~(BAT_CTRL_60U_ENA | BAT_CTRL_120U_ENA)); + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { /* Write 0 to the curr bits */ ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, @@ -541,7 +562,9 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) { int res; u8 i; - if (is_ab9540(di->parent) || is_ab8505(di->parent)) + if (is_ab8540(di->parent)) + di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; + else if (is_ab9540(di->parent) || is_ab8505(di->parent)) di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; else di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; @@ -582,9 +605,14 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) * detected type is Type 1, else we use the 7uA source */ if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && - di->bm->batt_id == 1) { - if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - dev_dbg(di->dev, "Set BATCTRL current source to 16uA\n"); + di->bm->batt_id == 1) { + if (is_ab8540(di->parent)) { + dev_dbg(di->dev, + "Set BATCTRL current source to 60uA\n"); + di->curr_source = BTEMP_BATCTRL_CURR_SRC_60UA; + } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + dev_dbg(di->dev, + "Set BATCTRL current source to 16uA\n"); di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; } else { dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index f249a65b02e1..6089ee7bc609 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -57,7 +57,9 @@ #define MAIN_CH_INPUT_CURR_SHIFT 4 #define VBUS_IN_CURR_LIM_SHIFT 4 +#define AB8540_VBUS_IN_CURR_LIM_SHIFT 2 #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 +#define AB8540_AUTO_VBUS_IN_CURR_MASK 0x3F #define VBUS_IN_CURR_LIM_RETRY_SET_TIME 30 /* seconds */ #define LED_INDICATOR_PWM_ENA 0x01 @@ -82,6 +84,7 @@ #define AB8500_USB_LINK_STATUS 0x78 #define AB8505_USB_LINK_STATUS 0xF8 #define AB8500_STD_HOST_SUSP 0x18 +#define USB_LINK_STATUS_SHIFT 3 /* Watchdog timeout constant */ #define WD_TIMER 0x30 /* 4min */ @@ -751,8 +754,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, "VBUS has collapsed\n"); ret = -ENXIO; break; - } - if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + } else { dev_dbg(di->dev, "USB Type - Charging not allowed\n"); di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; @@ -807,30 +809,22 @@ static int ab8500_charger_read_usb_type(struct ab8500_charger *di) dev_err(di->dev, "%s ab8500 read failed\n", __func__); return ret; } - if (is_ab8500(di->parent)) { + if (is_ab8500(di->parent)) ret = abx500_get_register_interruptible(di->dev, AB8500_USB, - AB8500_USB_LINE_STAT_REG, &val); - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - ret = abx500_get_register_interruptible(di->dev, - AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); - } else { - dev_err(di->dev, "%s unsupported analog baseband\n", __func__); - return -ENXIO; - } + AB8500_USB_LINE_STAT_REG, &val); + else + ret = abx500_get_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); return ret; } /* get the USB type */ - if (is_ab8500(di->parent)) { - val = (val & AB8500_USB_LINK_STATUS) >> 3; - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - val = (val & AB8505_USB_LINK_STATUS) >> 3; - } else { - dev_err(di->dev, "%s unsupported analog baseband\n", __func__); - return -ENXIO; - } + if (is_ab8500(di->parent)) + val = (val & AB8500_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; + else + val = (val & AB8505_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT; ret = ab8500_charger_max_usb_curr(di, (enum ab8500_charger_link_status) val); @@ -866,16 +860,12 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) return ret; } - if (is_ab8500(di->parent)) { + if (is_ab8500(di->parent)) ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { + else ret = abx500_get_register_interruptible(di->dev, AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val); - } else { - dev_err(di->dev, "%s unsupported analog baseband\n", __func__); - return -ENXIO; - } if (ret < 0) { dev_err(di->dev, "%s ab8500 read failed\n", __func__); return ret; @@ -889,14 +879,12 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) */ /* get the USB type */ - if (is_ab8500(di->parent)) { - val = (val & AB8500_USB_LINK_STATUS) >> 3; - } else if (is_ab9540(di->parent) || is_ab8505(di->parent)) { - val = (val & AB8505_USB_LINK_STATUS) >> 3; - } else { - dev_err(di->dev, "%s unsupported analog baseband\n", __func__); - return -ENXIO; - } + if (is_ab8500(di->parent)) + val = (val & AB8500_USB_LINK_STATUS) >> + USB_LINK_STATUS_SHIFT; + else + val = (val & AB8505_USB_LINK_STATUS) >> + USB_LINK_STATUS_SHIFT; if (val) break; } @@ -991,51 +979,6 @@ static int ab8500_charger_voltage_map[] = { 4600 , }; -/* - * This array maps the raw hex value to charger current used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_charger_current_map[] = { - 100 , - 200 , - 300 , - 400 , - 500 , - 600 , - 700 , - 800 , - 900 , - 1000 , - 1100 , - 1200 , - 1300 , - 1400 , - 1500 , -}; - -/* - * This array maps the raw hex value to VBUS input current used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_charger_vbus_in_curr_map[] = { - USB_CH_IP_CUR_LVL_0P05, - USB_CH_IP_CUR_LVL_0P09, - USB_CH_IP_CUR_LVL_0P19, - USB_CH_IP_CUR_LVL_0P29, - USB_CH_IP_CUR_LVL_0P38, - USB_CH_IP_CUR_LVL_0P45, - USB_CH_IP_CUR_LVL_0P5, - USB_CH_IP_CUR_LVL_0P6, - USB_CH_IP_CUR_LVL_0P7, - USB_CH_IP_CUR_LVL_0P8, - USB_CH_IP_CUR_LVL_0P9, - USB_CH_IP_CUR_LVL_1P0, - USB_CH_IP_CUR_LVL_1P1, - USB_CH_IP_CUR_LVL_1P3, - USB_CH_IP_CUR_LVL_1P4, - USB_CH_IP_CUR_LVL_1P5, -}; - static int ab8500_voltage_to_regval(int voltage) { int i; @@ -1057,41 +1000,41 @@ static int ab8500_voltage_to_regval(int voltage) return -1; } -static int ab8500_current_to_regval(int curr) +static int ab8500_current_to_regval(struct ab8500_charger *di, int curr) { int i; - if (curr < ab8500_charger_current_map[0]) + if (curr < di->bm->chg_output_curr[0]) return 0; - for (i = 0; i < ARRAY_SIZE(ab8500_charger_current_map); i++) { - if (curr < ab8500_charger_current_map[i]) + for (i = 0; i < di->bm->n_chg_out_curr; i++) { + if (curr < di->bm->chg_output_curr[i]) return i - 1; } /* If not last element, return error */ - i = ARRAY_SIZE(ab8500_charger_current_map) - 1; - if (curr == ab8500_charger_current_map[i]) + i = di->bm->n_chg_out_curr - 1; + if (curr == di->bm->chg_output_curr[i]) return i; else return -1; } -static int ab8500_vbus_in_curr_to_regval(int curr) +static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) { int i; - if (curr < ab8500_charger_vbus_in_curr_map[0]) + if (curr < di->bm->chg_input_curr[0]) return 0; - for (i = 0; i < ARRAY_SIZE(ab8500_charger_vbus_in_curr_map); i++) { - if (curr < ab8500_charger_vbus_in_curr_map[i]) + for (i = 0; i < di->bm->n_chg_in_curr; i++) { + if (curr < di->bm->chg_input_curr[i]) return i - 1; } /* If not last element, return error */ - i = ARRAY_SIZE(ab8500_charger_vbus_in_curr_map) - 1; - if (curr == ab8500_charger_vbus_in_curr_map[i]) + i = di->bm->n_chg_in_curr - 1; + if (curr == di->bm->chg_input_curr[i]) return i; else return -1; @@ -1169,7 +1112,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, int ich, int reg) { int ret = 0; - int auto_curr_index, curr_index, prev_curr_index, shift_value, i; + int curr_index, prev_curr_index, shift_value, i; u8 reg_value; u32 step_udelay; bool no_stepping = false; @@ -1187,39 +1130,27 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, case AB8500_MCH_IPT_CURLVL_REG: shift_value = MAIN_CH_INPUT_CURR_SHIFT; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_current_to_regval(ich); + curr_index = ab8500_current_to_regval(di, ich); step_udelay = STEP_UDELAY; if (!di->ac.charger_connected) no_stepping = true; break; case AB8500_USBCH_IPT_CRNTLVL_REG: - shift_value = VBUS_IN_CURR_LIM_SHIFT; + if (is_ab8540(di->parent)) + shift_value = AB8540_VBUS_IN_CURR_LIM_SHIFT; + else + shift_value = VBUS_IN_CURR_LIM_SHIFT; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_vbus_in_curr_to_regval(ich); + curr_index = ab8500_vbus_in_curr_to_regval(di, ich); step_udelay = STEP_UDELAY * 100; - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_USBCH_STAT2_REG, ®_value); - if (ret < 0) { - dev_err(di->dev, "%s read failed\n", __func__); - goto exit_set_current; - } - auto_curr_index = - reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT; - - dev_dbg(di->dev, "%s Auto VBUS curr is %d mA\n", - __func__, - ab8500_charger_vbus_in_curr_map[auto_curr_index]); - - prev_curr_index = min(prev_curr_index, auto_curr_index); - if (!di->usb.charger_connected) no_stepping = true; break; case AB8500_CH_OPT_CRNTLVL_REG: shift_value = 0; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_current_to_regval(ich); + curr_index = ab8500_current_to_regval(di, ich); step_udelay = STEP_UDELAY; if (curr_index && (curr_index - prev_curr_index) > 1) step_udelay *= 100; @@ -1459,8 +1390,8 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, /* Check if the requested voltage or current is valid */ volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(iset); - input_curr_index = ab8500_current_to_regval( + curr_index = ab8500_current_to_regval(di, iset); + input_curr_index = ab8500_current_to_regval(di, di->bm->chg_params->ac_curr_max); if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { dev_err(di->dev, @@ -1631,7 +1562,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, /* Check if the requested voltage or current is valid */ volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(ich_out); + curr_index = ab8500_current_to_regval(di, ich_out); if (volt_index < 0 || curr_index < 0) { dev_err(di->dev, "Charger voltage or current too high, " @@ -2396,18 +2327,21 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) else dev_dbg(di->dev, "Error reading USB link status\n"); - if (is_ab9540(di->parent) || is_ab8505(di->parent)) - link_status = AB8505_USB_LINK_STATUS; - else + if (is_ab8500(di->parent)) link_status = AB8500_USB_LINK_STATUS; + else + link_status = AB8505_USB_LINK_STATUS; if (detected_chargers & USB_PW_CONN) { - if (((val & link_status) >> 3) == USB_STAT_NOT_VALID_LINK && + if (((val & link_status) >> USB_LINK_STATUS_SHIFT) == + USB_STAT_NOT_VALID_LINK && di->invalid_charger_detect_state == 0) { - dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); + dev_dbg(di->dev, + "Invalid charger detected, state= 0\n"); /*Enable charger*/ abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, 0x01, 0x01); + AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, + USB_CH_ENA, USB_CH_ENA); /*Enable charger detection*/ abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); @@ -2417,15 +2351,17 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) } if (di->invalid_charger_detect_state == 1) { - dev_dbg(di->dev, "Invalid charger detected, state= 1\n"); + dev_dbg(di->dev, + "Invalid charger detected, state= 1\n"); /*Stop charger detection*/ abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); /*Check link status*/ - ret = abx500_get_register_interruptible(di->dev, AB8500_USB, + ret = abx500_get_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); dev_dbg(di->dev, "USB link status= 0x%02x\n", - (val & link_status) >> 3); + (val & link_status) >> USB_LINK_STATUS_SHIFT); di->invalid_charger_detect_state = 2; } } else { @@ -2741,7 +2677,7 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) { struct ab8500_charger *di = container_of(work, struct ab8500_charger, vbus_drop_end_work.work); - int ret; + int ret, curr; u8 reg_value; di->flags.vbus_drop_end = false; @@ -2749,32 +2685,41 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) /* Reset the drop counter */ abx500_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_USBCH_STAT2_REG, - ®_value); + + if (is_ab8540(di->parent)) + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8540_CH_USBCH_STAT3_REG, ®_value); + else + ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, + AB8500_CH_USBCH_STAT2_REG, ®_value); if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - } else { - int curr = ab8500_charger_vbus_in_curr_map[ + dev_err(di->dev, "%s read failed\n", __func__); + return; + } + + if (is_ab8540(di->parent)) + curr = di->bm->chg_input_curr[ + reg_value & AB8540_AUTO_VBUS_IN_CURR_MASK]; + else + curr = di->bm->chg_input_curr[ reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; - if (di->max_usb_in_curr.calculated_max != curr) { - /* USB source is collapsing */ - di->max_usb_in_curr.calculated_max = curr; - dev_dbg(di->dev, - "VBUS input current limiting to %d mA\n", - di->max_usb_in_curr.calculated_max); - } else { - /* - * USB source can not give more than this amount. - * Taking more will collapse the source. - */ - di->max_usb_in_curr.set_max = - di->max_usb_in_curr.calculated_max; - dev_dbg(di->dev, - "VBUS input current limited to %d mA\n", - di->max_usb_in_curr.set_max); - return; - } + + if (di->max_usb_in_curr.calculated_max != curr) { + /* USB source is collapsing */ + di->max_usb_in_curr.calculated_max = curr; + dev_dbg(di->dev, + "VBUS input current limiting to %d mA\n", + di->max_usb_in_curr.calculated_max); + } else { + /* + * USB source can not give more than this amount. + * Taking more will collapse the source. + */ + di->max_usb_in_curr.set_max = + di->max_usb_in_curr.calculated_max; + dev_dbg(di->dev, + "VBUS input current limited to %d mA\n", + di->max_usb_in_curr.set_max); } if (di->usb.charger_connected) @@ -3134,9 +3079,14 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) goto out; } - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_MAX_REG, CH_OP_CUR_LVL_1P6); + if (is_ab8540(di->parent)) + ret = abx500_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, + CH_OP_CUR_LVL_2P); + else + ret = abx500_set_register_interruptible(di->dev, + AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG, + CH_OP_CUR_LVL_1P6); if (ret) { dev_err(di->dev, "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); @@ -3144,7 +3094,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) } } - if (is_ab9540_2p0(di->parent) || is_ab8505_2p0(di->parent)) + if (is_ab9540_2p0(di->parent) || is_ab9540_3p0(di->parent) + || is_ab8505_2p0(di->parent) || is_ab8540(di->parent)) ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_CHARGER, AB8500_USBCH_CTRL2_REG, @@ -3250,7 +3201,8 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) AB8500_RTC_CTRL1_REG, bup_vch_range | vbup33_vrtcn); if (ret) { - dev_err(di->dev, "failed to setup backup battery charging\n"); + dev_err(di->dev, + "failed to setup backup battery charging\n"); goto out; } } @@ -3267,14 +3219,16 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) AB8500_CHARGER, AB8540_USB_PP_MODE_REG, BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V); if (ret) { - dev_err(di->dev, "failed to setup usb power path vsys voltage\n"); + dev_err(di->dev, + "failed to setup usb power path vsys voltage\n"); goto out; } ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_CHARGER, AB8540_USB_PP_CHR_REG, BUS_PP_PRECHG_CURRENT_MASK, 0); if (ret) { - dev_err(di->dev, "failed to setup usb power path prechage current\n"); + dev_err(di->dev, + "failed to setup usb power path prechage current\n"); goto out; } } @@ -3537,8 +3491,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->ac_chg.max_out_curr = ab8500_charger_current_map[ - ARRAY_SIZE(ab8500_charger_current_map) - 1]; + di->ac_chg.max_out_curr = + di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; di->ac_chg.enabled = di->bm->ac_enabled; di->ac_chg.external = false; @@ -3566,8 +3520,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable; di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->usb_chg.max_out_curr = ab8500_charger_current_map[ - ARRAY_SIZE(ab8500_charger_current_map) - 1]; + di->usb_chg.max_out_curr = + di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.enabled = di->bm->usb_enabled; di->usb_chg.external = false; diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index cd71d8eadf50..33b0253569a3 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -246,7 +246,11 @@ struct abx500_bm_charger_parameters { * @interval_not_charging charge alg cycle period time when not charging (sec) * @temp_hysteresis temperature hysteresis * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) - * @maxi: maximization parameters + * @n_chg_out_curr number of elements in array chg_output_curr + * @n_chg_in_curr number of elements in array chg_input_curr + * @chg_output_curr charger output current level map + * @chg_input_curr charger input current level map + * @maxi maximization parameters * @cap_levels capacity in percent for the different capacity levels * @bat_type table of supported battery types * @chg_params charger parameters @@ -281,6 +285,10 @@ struct abx500_bm_data { int interval_not_charging; int temp_hysteresis; int gnd_lift_resistance; + int n_chg_out_curr; + int n_chg_in_curr; + int *chg_output_curr; + int *chg_input_curr; const struct abx500_maxim_parameters *maxi; const struct abx500_bm_capacity_levels *cap_levels; struct abx500_battery_type *bat_type; diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index 0ebf0c5d1f88..ee1c1626c886 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -33,7 +33,7 @@ #define AB8500_CH_STATUS2_REG 0x01 #define AB8500_CH_USBCH_STAT1_REG 0x02 #define AB8500_CH_USBCH_STAT2_REG 0x03 -#define AB8500_CH_FSM_STAT_REG 0x04 +#define AB8540_CH_USBCH_STAT3_REG 0x04 #define AB8500_CH_STAT_REG 0x05 /* @@ -157,6 +157,7 @@ #define CH_OP_CUR_LVL_1P4 0x0D #define CH_OP_CUR_LVL_1P5 0x0E #define CH_OP_CUR_LVL_1P6 0x0F +#define CH_OP_CUR_LVL_2P 0x3F /* BTEMP High thermal limits */ #define BTEMP_HIGH_TH_57_0 0x00 @@ -246,6 +247,8 @@ enum bup_vch_sel { #define BAT_CTRL_20U_ENA 0x02 #define BAT_CTRL_18U_ENA 0x01 #define BAT_CTRL_16U_ENA 0x02 +#define BAT_CTRL_60U_ENA 0x01 +#define BAT_CTRL_120U_ENA 0x02 #define BAT_CTRL_CMP_ENA 0x04 #define FORCE_BAT_CTRL_CMP_HIGH 0x08 #define BAT_CTRL_PULL_UP_ENA 0x10 -- cgit From 88efdb8022f13c198fe4459e6e278f9b559cff3b Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Thu, 30 Aug 2012 14:12:53 +0200 Subject: ab8500-charger: Use USBLink1Status Register The newer AB's such as the AB8505, AB9540 etc include a USBLink1 Status register which detects a larger range of external devices. This should be used instead of the USBLine Status register. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Hakan BERG Reviewed-by: Jonas ABERG Tested-by: Yang QU --- drivers/power/ab8500_charger.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 6089ee7bc609..bf8b479914cd 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2320,8 +2320,13 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) * to start the charging process. but by jumping * thru a few hoops it can be forced to start. */ - ret = abx500_get_register_interruptible(di->dev, AB8500_USB, - AB8500_USB_LINE_STAT_REG, &val); + if (is_ab8500(di->parent)) + ret = abx500_get_register_interruptible(di->dev, AB8500_USB, + AB8500_USB_LINE_STAT_REG, &val); + else + ret = abx500_get_register_interruptible(di->dev, AB8500_USB, + AB8500_USB_LINK1_STAT_REG, &val); + if (ret >= 0) dev_dbg(di->dev, "UsbLineStatus register = 0x%02x\n", val); else @@ -2357,9 +2362,15 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); /*Check link status*/ - ret = abx500_get_register_interruptible(di->dev, - AB8500_USB, - AB8500_USB_LINE_STAT_REG, &val); + if (is_ab8500(di->parent)) + ret = abx500_get_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINE_STAT_REG, + &val); + else + ret = abx500_get_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINK1_STAT_REG, + &val); + dev_dbg(di->dev, "USB link status= 0x%02x\n", (val & link_status) >> USB_LINK_STATUS_SHIFT); di->invalid_charger_detect_state = 2; -- cgit From eaded808c9f9f36d95b5b7fe195ab1839e9e486c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 13 Feb 2013 13:38:00 +0000 Subject: abx500-chargalg: Prevent the watchdog from being kicked twice Charging watchdog kicker work-thread gets started twice causing 'failed to kick watchdog' message after removing charger and when re-inserting charger. This patch removes the superfluous start of watchdog kicker-thread. Signed-off-by: Lee Jones --- drivers/power/abx500_chargalg.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index a9b8efdafb8f..e23b92a5332e 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -689,8 +689,6 @@ static void abx500_chargalg_hold_charging(struct abx500_chargalg *di) static void abx500_chargalg_start_charging(struct abx500_chargalg *di, int vset, int iset) { - bool start_chargalg_wd = true; - switch (di->chg_info.charger_type) { case AC_CHG: dev_dbg(di->dev, @@ -708,12 +706,8 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di, default: dev_err(di->dev, "Unknown charger to charge from\n"); - start_chargalg_wd = false; break; } - - if (start_chargalg_wd && !delayed_work_pending(&di->chargalg_wd_work)) - queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0); } /** -- cgit From 257107ae6b9ba1f3822a8b079acef57a752dcc4c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 13 Feb 2013 15:15:03 +0000 Subject: ab8500-chargalg: Use hrtimer Timers used for charging safety and maintenance must work even when CPU power has collapsed. By using hrtimers with the realtime clock the system is able to trigger an alarm that wakes-up the CPU and makes it possible to handle events. Allow a little slack time of 5 minutes for the hrtimers to allow CPU to be woken-up in a more optimal power saving way. A 5 minute delay to time-out timers relative to hours does not impact on safety. Signed-off-by: Lee Jones --- drivers/power/abx500_chargalg.c | 91 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index e23b92a5332e..55c9d2ea5dff 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -1,5 +1,6 @@ /* * Copyright (C) ST-Ericsson SA 2012 + * Copyright (c) 2012 Sony Mobile Communications AB * * Charging algorithm driver for abx500 variants * @@ -8,11 +9,13 @@ * Johan Palsson * Karl Komierowski * Arun R Murthy + * Author: Imre Sunyi */ #include #include #include +#include #include #include #include @@ -24,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +38,12 @@ /* End-of-charge criteria counter */ #define EOC_COND_CNT 10 +/* One hour expressed in seconds */ +#define ONE_HOUR_IN_SECONDS 3600 + +/* Five minutes expressed in seconds */ +#define FIVE_MINUTES_IN_SECONDS 300 + /* Plus margin for the low battery threshold */ #define BAT_PLUS_MARGIN (100) @@ -244,8 +254,8 @@ struct abx500_chargalg { struct delayed_work chargalg_periodic_work; struct delayed_work chargalg_wd_work; struct work_struct chargalg_work; - struct timer_list safety_timer; - struct timer_list maintenance_timer; + struct hrtimer safety_timer; + struct hrtimer maintenance_timer; struct kobject chargalg_kobject; }; @@ -260,38 +270,47 @@ static enum power_supply_property abx500_chargalg_props[] = { /** * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer - * @data: pointer to the abx500_chargalg structure + * @timer: pointer to the hrtimer structure * * This function gets called when the safety timer for the charger * expires */ -static void abx500_chargalg_safety_timer_expired(unsigned long data) +static enum hrtimer_restart +abx500_chargalg_safety_timer_expired(struct hrtimer *timer) { - struct abx500_chargalg *di = (struct abx500_chargalg *) data; + struct abx500_chargalg *di = container_of(timer, struct abx500_chargalg, + safety_timer); dev_err(di->dev, "Safety timer expired\n"); di->events.safety_timer_expired = true; /* Trigger execution of the algorithm instantly */ queue_work(di->chargalg_wq, &di->chargalg_work); + + return HRTIMER_NORESTART; } /** * abx500_chargalg_maintenance_timer_expired() - Expiration of * the maintenance timer - * @i: pointer to the abx500_chargalg structure + * @timer: pointer to the timer structure * * This function gets called when the maintenence timer * expires */ -static void abx500_chargalg_maintenance_timer_expired(unsigned long data) +static enum hrtimer_restart +abx500_chargalg_maintenance_timer_expired(struct hrtimer *timer) { - struct abx500_chargalg *di = (struct abx500_chargalg *) data; + struct abx500_chargalg *di = container_of(timer, struct abx500_chargalg, + maintenance_timer); + dev_dbg(di->dev, "Maintenance timer expired\n"); di->events.maintenance_timer_expired = true; /* Trigger execution of the algorithm instantly */ queue_work(di->chargalg_wq, &di->chargalg_work); + + return HRTIMER_NORESTART; } /** @@ -391,19 +410,16 @@ static int abx500_chargalg_check_charger_connection(struct abx500_chargalg *di) */ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di) { - unsigned long timer_expiration = 0; + /* Charger-dependent expiration time in hours*/ + int timer_expiration = 0; switch (di->chg_info.charger_type) { case AC_CHG: - timer_expiration = - round_jiffies(jiffies + - (di->bm->main_safety_tmr_h * 3600 * HZ)); + timer_expiration = di->bm->main_safety_tmr_h; break; case USB_CHG: - timer_expiration = - round_jiffies(jiffies + - (di->bm->usb_safety_tmr_h * 3600 * HZ)); + timer_expiration = di->bm->usb_safety_tmr_h; break; default: @@ -412,11 +428,10 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di) } di->events.safety_timer_expired = false; - di->safety_timer.expires = timer_expiration; - if (!timer_pending(&di->safety_timer)) - add_timer(&di->safety_timer); - else - mod_timer(&di->safety_timer, timer_expiration); + hrtimer_set_expires_range(&di->safety_timer, + ktime_set(timer_expiration * ONE_HOUR_IN_SECONDS, 0), + ktime_set(FIVE_MINUTES_IN_SECONDS, 0)); + hrtimer_start_expires(&di->safety_timer, HRTIMER_MODE_REL); } /** @@ -427,8 +442,8 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di) */ static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg *di) { - di->events.safety_timer_expired = false; - del_timer(&di->safety_timer); + if (hrtimer_try_to_cancel(&di->safety_timer) >= 0) + di->events.safety_timer_expired = false; } /** @@ -443,17 +458,11 @@ static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg *di) static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg *di, int duration) { - unsigned long timer_expiration; - - /* Convert from hours to jiffies */ - timer_expiration = round_jiffies(jiffies + (duration * 3600 * HZ)); - + hrtimer_set_expires_range(&di->maintenance_timer, + ktime_set(duration * ONE_HOUR_IN_SECONDS, 0), + ktime_set(FIVE_MINUTES_IN_SECONDS, 0)); di->events.maintenance_timer_expired = false; - di->maintenance_timer.expires = timer_expiration; - if (!timer_pending(&di->maintenance_timer)) - add_timer(&di->maintenance_timer); - else - mod_timer(&di->maintenance_timer, timer_expiration); + hrtimer_start_expires(&di->maintenance_timer, HRTIMER_MODE_REL); } /** @@ -465,8 +474,8 @@ static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg *di, */ static void abx500_chargalg_stop_maintenance_timer(struct abx500_chargalg *di) { - di->events.maintenance_timer_expired = false; - del_timer(&di->maintenance_timer); + if (hrtimer_try_to_cancel(&di->maintenance_timer) >= 0) + di->events.maintenance_timer_expired = false; } /** @@ -1937,10 +1946,16 @@ static int abx500_chargalg_remove(struct platform_device *pdev) /* sysfs interface to enable/disbale charging from user space */ abx500_chargalg_sysfs_exit(di); + hrtimer_cancel(&di->safety_timer); + hrtimer_cancel(&di->maintenance_timer); + + cancel_delayed_work_sync(&di->chargalg_periodic_work); + cancel_delayed_work_sync(&di->chargalg_wd_work); + cancel_work_sync(&di->chargalg_work); + /* Delete the work queue */ destroy_workqueue(di->chargalg_wq); - flush_scheduled_work(); power_supply_unregister(&di->chargalg_psy); platform_set_drvdata(pdev, NULL); @@ -1994,15 +2009,13 @@ static int abx500_chargalg_probe(struct platform_device *pdev) abx500_chargalg_external_power_changed; /* Initilialize safety timer */ - init_timer(&di->safety_timer); + hrtimer_init(&di->safety_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); di->safety_timer.function = abx500_chargalg_safety_timer_expired; - di->safety_timer.data = (unsigned long) di; /* Initilialize maintenance timer */ - init_timer(&di->maintenance_timer); + hrtimer_init(&di->maintenance_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); di->maintenance_timer.function = abx500_chargalg_maintenance_timer_expired; - di->maintenance_timer.data = (unsigned long) di; /* Create a work queue for the chargalg */ di->chargalg_wq = -- cgit From b3ea5f451e4e435b650e34142f8552002dc21297 Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Wed, 29 Aug 2012 17:56:19 +0200 Subject: ab8500-charger: Add UsbLineCtrl2 reference When the state of USB Charge detection is changed then the calls use a define for another register in other bank. This change creates a new define for the correct register and removes the magic numbers that are present. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Hakan BERG Reviewed-by: Jonas ABERG --- drivers/power/ab8500_charger.c | 11 +++++++---- include/linux/mfd/abx500/ab8500-bm.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index bf8b479914cd..64accb235d2c 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -54,6 +54,7 @@ #define VBUS_DET_DBNC1 0x01 #define OTP_ENABLE_WD 0x01 #define DROP_COUNT_RESET 0x01 +#define USB_CH_DET 0x01 #define MAIN_CH_INPUT_CURR_SHIFT 4 #define VBUS_IN_CURR_LIM_SHIFT 4 @@ -2348,8 +2349,9 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, USB_CH_ENA, USB_CH_ENA); /*Enable charger detection*/ - abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, - AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); + abx500_mask_and_set_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINE_CTRL2_REG, + USB_CH_DET, USB_CH_DET); di->invalid_charger_detect_state = 1; /*exit and wait for new link status interrupt.*/ return; @@ -2359,8 +2361,9 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) dev_dbg(di->dev, "Invalid charger detected, state= 1\n"); /*Stop charger detection*/ - abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, - AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); + abx500_mask_and_set_register_interruptible(di->dev, + AB8500_USB, AB8500_USB_LINE_CTRL2_REG, + USB_CH_DET, 0x00); /*Check link status*/ if (is_ab8500(di->parent)) ret = abx500_get_register_interruptible(di->dev, diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index ee1c1626c886..f5214dc651f9 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -23,6 +23,7 @@ * Bank : 0x5 */ #define AB8500_USB_LINE_STAT_REG 0x80 +#define AB8500_USB_LINE_CTRL2_REG 0x82 #define AB8500_USB_LINK1_STAT_REG 0x94 /* -- cgit From f4095a0f06476e5914f2c58b4e96258b2e2ba6b7 Mon Sep 17 00:00:00 2001 From: M BenZoubeir Date: Thu, 13 Sep 2012 10:34:18 +0200 Subject: pm2301-charger: Adjust interrupt handler behavior Signed-off-by: M BenZoubeir Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 45 ++++++++++++++++++++++-------------------- include/linux/pm2301_charger.h | 2 +- 2 files changed, 25 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index b8eafc3850d0..eed8a89ba4f0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -493,14 +493,16 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) struct pm2xxx_interrupts *interrupt = pm2->pm2_int; int i; - for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { - pm2xxx_reg_read(pm2, + do { + for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { + pm2xxx_reg_read(pm2, pm2xxx_interrupt_registers[i], &(interrupt->reg[i])); - if (interrupt->reg[i] > 0) - interrupt->handler[i](pm2, interrupt->reg[i]); - } + if (interrupt->reg[i] > 0) + interrupt->handler[i](pm2, interrupt->reg[i]); + } + } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); return IRQ_HANDLED; } @@ -951,6 +953,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, struct pm2xxx_charger *pm2; int ret = 0; u8 val; + int i; pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); if (!pm2) { @@ -1062,24 +1065,25 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, } /* Register interrupts */ - ret = request_threaded_irq(pm2->pdata->irq_number, NULL, + ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), + NULL, pm2xxx_charger_irq[0].isr, pm2->pdata->irq_type, pm2xxx_charger_irq[0].name, pm2); if (ret != 0) { dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", - pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); + pm2xxx_charger_irq[0].name, + gpio_to_irq(pm2->pdata->gpio_irq_number), ret); goto unregister_pm2xxx_charger; } /* pm interrupt can wake up system */ - ret = enable_irq_wake(pm2->pdata->irq_number); + ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); if (ret) { dev_err(pm2->dev, "failed to set irq wake\n"); goto unregister_pm2xxx_interrupt; } - /*Initialize lock*/ mutex_init(&pm2->lock); /* @@ -1099,16 +1103,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, } set_lpn_pin(pm2); + + /* read interrupt registers */ + for (i = 0; i < PM2XXX_NUM_INT_REG; i++) + pm2xxx_reg_read(pm2, + pm2xxx_interrupt_registers[i], + &val); + ret = pm2xxx_charger_detection(pm2, &val); if ((ret == 0) && val) { - /* - * When boot is due to AC charger plug-in, - * read interrupt registers - */ - pm2xxx_reg_read(pm2, PM2XXX_REG_INT1, &val); - pm2xxx_reg_read(pm2, PM2XXX_REG_INT2, &val); - pm2xxx_reg_read(pm2, PM2XXX_REG_INT4, &val); pm2->ac.charger_connected = 1; ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, AB8500_MAIN_CH_DET); @@ -1122,10 +1126,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, free_gpio: gpio_free(pm2->lpn_pin); disable_pm2_irq_wake: - disable_irq_wake(pm2->pdata->irq_number); + disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); unregister_pm2xxx_interrupt: /* disable interrupt */ - free_irq(pm2->pdata->irq_number, pm2); + free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); unregister_pm2xxx_charger: /* unregister power supply */ power_supply_unregister(&pm2->ac_chg.psy); @@ -1148,10 +1152,10 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); /* Disable wake by pm interrupt */ - disable_irq_wake(pm2->pdata->irq_number); + disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); /* Disable interrupts */ - free_irq(pm2->pdata->irq_number, pm2); + free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); /* Delete the work queue */ destroy_workqueue(pm2->charger_wq); @@ -1163,7 +1167,6 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) power_supply_unregister(&pm2->ac_chg.psy); - /*Free GPIO60*/ gpio_free(pm2->lpn_pin); kfree(pm2); diff --git a/include/linux/pm2301_charger.h b/include/linux/pm2301_charger.h index fc3f026922ae..85c16defe11a 100644 --- a/include/linux/pm2301_charger.h +++ b/include/linux/pm2301_charger.h @@ -48,7 +48,7 @@ struct pm2xxx_charger_platform_data { size_t num_supplicants; int i2c_bus; const char *label; - int irq_number; + int gpio_irq_number; unsigned int lpn_gpio; int irq_type; }; -- cgit From aee2b8468caf3d1eed6e329e828bc09eaa61063a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 25 Feb 2013 14:28:59 +0000 Subject: pm2301-charger: Add pm_runtime_resume & pm_runtime_suspend To optimize the current consumption we use pm_runtime autosuspend functions which execute the pm_runtime_suspend after a delay of inactivity on the other hand we use pm_runtime_resume every time we receive an interruption to wake up the pm2301. Signed-off-by: M BenZoubeir Signed-off-by: Lee Jones Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index eed8a89ba4f0..fde5805fdab0 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "pm2301_charger.h" @@ -36,6 +37,7 @@ struct pm2xxx_charger, ac_chg) #define SLEEP_MIN 50 #define SLEEP_MAX 100 +#define PM2XXX_AUTOSUSPEND_DELAY 500 static int pm2xxx_interrupt_registers[] = { PM2XXX_REG_INT1, @@ -493,6 +495,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) struct pm2xxx_interrupts *interrupt = pm2->pm2_int; int i; + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); + do { for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { pm2xxx_reg_read(pm2, @@ -504,6 +509,9 @@ static irqreturn_t pm2xxx_irq_int(int irq, void *data) } } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); + pm_runtime_mark_last_busy(pm2->dev); + pm_runtime_put_autosuspend(pm2->dev); + return IRQ_HANDLED; } @@ -946,6 +954,53 @@ static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, return 0; } +#ifdef CONFIG_PM +static int pm2xxx_runtime_suspend(struct device *dev) +{ + struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); + struct pm2xxx_charger *pm2; + int ret = 0; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); + if (!pm2) { + dev_err(pm2->dev, "no pm2xxx_charger data supplied\n"); + ret = -EINVAL; + return ret; + } + + clear_lpn_pin(pm2); + + return ret; +} + +static int pm2xxx_runtime_resume(struct device *dev) +{ + struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); + struct pm2xxx_charger *pm2; + int ret = 0; + + pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); + if (!pm2) { + dev_err(pm2->dev, "no pm2xxx_charger data supplied\n"); + ret = -EINVAL; + return ret; + } + + if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0) + set_lpn_pin(pm2); + + return ret; +} + +static const struct dev_pm_ops pm2xxx_pm_ops = { + .runtime_suspend = pm2xxx_runtime_suspend, + .runtime_resume = pm2xxx_runtime_resume, +}; +#define PM2XXX_PM_OPS (&pm2xxx_pm_ops) +#else +#define PM2XXX_PM_OPS NULL +#endif + static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { @@ -1077,6 +1132,16 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, gpio_to_irq(pm2->pdata->gpio_irq_number), ret); goto unregister_pm2xxx_charger; } + + ret = pm_runtime_set_active(pm2->dev); + if (ret) + dev_err(pm2->dev, "set active Error\n"); + + pm_runtime_enable(pm2->dev); + pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(pm2->dev); + pm_runtime_resume(pm2->dev); + /* pm interrupt can wake up system */ ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); if (ret) { @@ -1148,6 +1213,8 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) { struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); + /* Disable pm_runtime */ + pm_runtime_disable(pm2->dev); /* Disable AC charging */ pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); @@ -1189,6 +1256,7 @@ static struct i2c_driver pm2xxx_charger_driver = { .driver = { .name = "pm2xxx-wall_charger", .owner = THIS_MODULE, + .pm = PM2XXX_PM_OPS, }, .id_table = pm2xxx_id, }; -- cgit From 261c5136fa988008387e31cf5381dc5b088e2a17 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 26 Sep 2012 13:36:38 +0200 Subject: ab8500-charger: Run detect workaround only on AB8500 Only AB8500 has this hardware bug, so these works only need to be run there. Signed-off-by: Rabin Vincent Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Martin SJOBLOM Reviewed-by: Jonas ABERG --- drivers/power/ab8500_charger.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 64accb235d2c..853002843984 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -441,7 +441,8 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, mutex_lock(&di->charger_attached_mutex); mutex_unlock(&di->charger_attached_mutex); - queue_delayed_work(di->charger_wq, + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, &di->usb_charger_attached_work, HZ); } else { @@ -2622,7 +2623,9 @@ static irqreturn_t ab8500_charger_mainchplugdet_handler(int irq, void *_di) mutex_lock(&di->charger_attached_mutex); mutex_unlock(&di->charger_attached_mutex); - queue_delayed_work(di->charger_wq, + + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, &di->ac_charger_attached_work, HZ); return IRQ_HANDLED; @@ -3690,14 +3693,16 @@ static int ab8500_charger_probe(struct platform_device *pdev) ch_stat = ab8500_charger_detect_chargers(di, false); if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { - queue_delayed_work(di->charger_wq, - &di->ac_charger_attached_work, - HZ); + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, + &di->ac_charger_attached_work, + HZ); } if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) { - queue_delayed_work(di->charger_wq, - &di->usb_charger_attached_work, - HZ); + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, + &di->usb_charger_attached_work, + HZ); } mutex_unlock(&di->charger_attached_mutex); -- cgit From f70dfdec99877fa716f71633a67d7ba3dfab1c5f Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 10 Oct 2012 14:56:41 +0530 Subject: pm2301-charger: Removed unused code from PM2301 driver Some of the headers and defines accrued over time are no longer in use. Let's take the opportunity to remove a few of them. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 5 ----- drivers/power/pm2301_charger.h | 22 ---------------------- 2 files changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index fde5805fdab0..87ddc658413f 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -16,16 +16,12 @@ #include #include #include -#include #include #include #include #include -#include -#include #include #include -#include #include #include #include @@ -1018,7 +1014,6 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, /* get parent data */ pm2->dev = &i2c_client->dev; - pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); pm2->pm2_int = &pm2xxx_int; diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h index fad1f387f8f4..8ce3cc0195df 100644 --- a/drivers/power/pm2301_charger.h +++ b/drivers/power/pm2301_charger.h @@ -9,27 +9,6 @@ #ifndef PM2301_CHARGER_H #define PM2301_CHARGER_H -#define MAIN_WDOG_ENA 0x01 -#define MAIN_WDOG_KICK 0x02 -#define MAIN_WDOG_DIS 0x00 -#define CHARG_WD_KICK 0x01 -#define MAIN_CH_ENA 0x01 -#define MAIN_CH_NO_OVERSHOOT_ENA_N 0x02 -#define MAIN_CH_DET 0x01 -#define MAIN_CH_CV_ON 0x04 -#define OTP_ENABLE_WD 0x01 - -#define MAIN_CH_INPUT_CURR_SHIFT 4 - -#define LED_INDICATOR_PWM_ENA 0x01 -#define LED_INDICATOR_PWM_DIS 0x00 -#define LED_IND_CUR_5MA 0x04 -#define LED_INDICATOR_PWM_DUTY_252_256 0xBF - -/* HW failure constants */ -#define MAIN_CH_TH_PROT 0x02 -#define MAIN_CH_NOK 0x01 - /* Watchdog timeout constant */ #define WD_TIMER 0x30 /* 4min */ #define WD_KICK_INTERVAL (30 * HZ) @@ -495,7 +474,6 @@ struct pm2xxx_charger { int failure_input_ovv; unsigned int lpn_pin; struct pm2xxx_interrupts *pm2_int; - struct ab8500_gpadc *gpadc; struct regulator *regu; struct pm2xxx_bm_data *bat; struct mutex lock; -- cgit From 1ee26af028a46cf911f844c062b3c810bac34366 Mon Sep 17 00:00:00 2001 From: srinidhi kasagar Date: Thu, 11 Oct 2012 14:38:28 +0530 Subject: abx500-chargalg: Use module_platform_driver() rather deprecate some boilerplate code by using module_platform_driver helper macro. No functional changes. Signed-off-by: srinidhi kasagar Signed-off-by: Lee Jones --- drivers/power/abx500_chargalg.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 55c9d2ea5dff..7e4bc011dd8f 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -2083,18 +2083,7 @@ static struct platform_driver abx500_chargalg_driver = { }, }; -static int __init abx500_chargalg_init(void) -{ - return platform_driver_register(&abx500_chargalg_driver); -} - -static void __exit abx500_chargalg_exit(void) -{ - platform_driver_unregister(&abx500_chargalg_driver); -} - -module_init(abx500_chargalg_init); -module_exit(abx500_chargalg_exit); +module_platform_driver(abx500_chargalg_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); -- cgit From 3c01b3676f3fa3813b02742a1816c9d2eff1b27e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 24 Oct 2012 11:06:07 +0200 Subject: ab8500-charger: Remove duplicate code Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 8 -------- drivers/power/ab8500_fg.c | 1 - 2 files changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 853002843984..81c9615fd726 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -3184,14 +3184,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) goto out; } - /* Set charger watchdog timeout */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_WD_TIMER_REG, WD_TIMER); - if (ret) { - dev_err(di->dev, "failed to set charger watchdog timeout\n"); - goto out; - } - ret = ab8500_charger_led_en(di, false); if (ret < 0) { dev_err(di->dev, "failed to disable LED\n"); diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index d1f93098a412..466ec6292d73 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -1680,7 +1680,6 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di) break; case AB8500_FG_DISCHARGE_WAKEUP: - ab8500_fg_coulomb_counter(di, true); ab8500_fg_calc_cap_discharge_voltage(di, true); di->fg_samples = SEC_TO_SAMPLE( -- cgit From a21e22f2f36c65c8453575ffd0cc8267134bb30a Mon Sep 17 00:00:00 2001 From: lme00437 Date: Tue, 13 Nov 2012 14:43:48 +0100 Subject: pm2301-charger: lpn pin used only in C2C boards This patch restricts use of LPN pin to C2C boards to avoid conflict on HSI for GPIO 60 use. Signed-off-by: Benoit GAUTHIER Signed-off-by: Lee Jones Reviewed-by: Mustapha BEN-ZOUBEIR Reviewed-by: Philippe LANGLAIS Tested-by: Benoit GAUTHIER --- drivers/power/pm2301_charger.c | 66 ++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 87ddc658413f..12aeed34bd4f 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -113,17 +113,16 @@ static const struct i2c_device_id pm2xxx_ident[] = { static void set_lpn_pin(struct pm2xxx_charger *pm2) { - gpio_set_value(pm2->lpn_pin, 1); - usleep_range(SLEEP_MIN, SLEEP_MAX); - - return; + if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) { + gpio_set_value(pm2->lpn_pin, 1); + usleep_range(SLEEP_MIN, SLEEP_MAX); + } } static void clear_lpn_pin(struct pm2xxx_charger *pm2) { - gpio_set_value(pm2->lpn_pin, 0); - - return; + if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) + gpio_set_value(pm2->lpn_pin, 0); } static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) @@ -1035,14 +1034,6 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2->bat = pl_data->battery; - /*get lpn GPIO from platform data*/ - if (!pm2->pdata->lpn_gpio) { - dev_err(pm2->dev, "no lpn gpio data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - pm2->lpn_pin = pm2->pdata->lpn_gpio; - if (!i2c_check_functionality(i2c_client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA)) { @@ -1146,23 +1137,28 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, mutex_init(&pm2->lock); - /* - * Charger detection mechanism requires pulling up the LPN pin - * while i2c communication if Charger is not connected - * LPN pin of PM2301 is GPIO60 of AB9540 - */ - ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); - if (ret < 0) { - dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); - goto disable_pm2_irq_wake; - } - ret = gpio_direction_output(pm2->lpn_pin, 0); - if (ret < 0) { - dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); - goto free_gpio; - } + if (gpio_is_valid(pm2->pdata->lpn_gpio)) { + /* get lpn GPIO from platform data */ + pm2->lpn_pin = pm2->pdata->lpn_gpio; - set_lpn_pin(pm2); + /* + * Charger detection mechanism requires pulling up the LPN pin + * while i2c communication if Charger is not connected + * LPN pin of PM2301 is GPIO60 of AB9540 + */ + ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); + + if (ret < 0) { + dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); + goto disable_pm2_irq_wake; + } + ret = gpio_direction_output(pm2->lpn_pin, 0); + if (ret < 0) { + dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); + goto free_gpio; + } + set_lpn_pin(pm2); + } /* read interrupt registers */ for (i = 0; i < PM2XXX_NUM_INT_REG; i++) @@ -1184,7 +1180,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, return 0; free_gpio: - gpio_free(pm2->lpn_pin); + if (gpio_is_valid(pm2->lpn_pin)) + gpio_free(pm2->lpn_pin); disable_pm2_irq_wake: disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); unregister_pm2xxx_interrupt: @@ -1229,7 +1226,8 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) power_supply_unregister(&pm2->ac_chg.psy); - gpio_free(pm2->lpn_pin); + if (gpio_is_valid(pm2->lpn_pin)) + gpio_free(pm2->lpn_pin); kfree(pm2); @@ -1266,7 +1264,7 @@ static void __exit pm2xxx_charger_exit(void) i2c_del_driver(&pm2xxx_charger_driver); } -subsys_initcall_sync(pm2xxx_charger_init); +device_initcall_sync(pm2xxx_charger_init); module_exit(pm2xxx_charger_exit); MODULE_LICENSE("GPL v2"); -- cgit From 0f80ba63187439ef4ad3810ccd97633af9522be8 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Tue, 20 Nov 2012 11:51:56 +0530 Subject: pm2301-charger: Charging LED control for pm2301 The LED Indicator feature allows indicating through a led when the PM2301 battery charging is active. SW shall not disable this LED. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 12aeed34bd4f..ac03f9e247d1 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -706,10 +706,6 @@ static int pm2xxx_charging_init(struct pm2xxx_charger *pm2) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG, PM2XXX_VBAT_LOW_MONITORING_ENA); - /* Disable LED */ - ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, - PM2XXX_LED_SELECT_DIS); - return ret; } -- cgit From 7a2cf9bacf6c5f3119a9100f103dc46a1f648fbb Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Wed, 28 Nov 2012 14:42:59 +0100 Subject: ab8500-bm: Trivially fix up some incorrect and out-of-date comments Some of the comments in the ab8500 drivers reflect the behaviour of the original device. As this driver now supports newer devices then these comments are now redundant. Also some IRQ comments are incorrect. Signed-off-by: Marcus Cooper Signed-off-by: Lee Jones Reviewed-by: Rabin VINCENT Tested-by: Rabin VINCENT --- drivers/power/ab8500_btemp.c | 4 ++-- drivers/power/ab8500_fg.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 7336dcf45f7e..a9486f1a1b5b 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -158,7 +158,7 @@ static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di, if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL) { /* * If the battery has internal NTC, we use the current - * source to calculate the resistance, 7uA or 20uA + * source to calculate the resistance. */ rbs = (v_batctrl * 1000 - di->bm->gnd_lift_resistance * inst_curr) @@ -602,7 +602,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) /* * We only have to change current source if the - * detected type is Type 1, else we use the 7uA source + * detected type is Type 1. */ if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && di->bm->batt_id == 1) { diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 466ec6292d73..adc02004e7a3 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -1979,7 +1979,7 @@ static void ab8500_fg_instant_work(struct work_struct *work) } /** - * ab8500_fg_cc_data_end_handler() - isr to get battery avg current. + * ab8500_fg_cc_data_end_handler() - end of data conversion isr. * @irq: interrupt number * @_di: pointer to the ab8500_fg structure * @@ -1999,7 +1999,7 @@ static irqreturn_t ab8500_fg_cc_data_end_handler(int irq, void *_di) } /** - * ab8500_fg_cc_convend_handler() - isr to get battery avg current. + * ab8500_fg_cc_int_calib_handler () - end of calibration isr. * @irq: interrupt number * @_di: pointer to the ab8500_fg structure * -- cgit From b64f51c4adde8972afac778a63a19a30c6d5f4b0 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 5 Dec 2012 14:14:13 +0530 Subject: pm2301-charger: Wake device on register access When USB Dedicated or Standard host chargers are plugged into the device, chargealg attempts to disable the PM2301 AC charger, However, disabling PM2301 was failing because of it being in runtime suepend mode & LPN pin being low. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ac03f9e247d1..a1fc37eca334 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -128,13 +128,9 @@ static void clear_lpn_pin(struct pm2xxx_charger *pm2) static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) { int ret; - /* - * When AC adaptor is unplugged, the host - * must put LPN high to be able to - * communicate by I2C with PM2301 - * and receive I2C "acknowledge" from PM2301. - */ - mutex_lock(&pm2->lock); + + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, val); @@ -142,7 +138,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); else ret = 0; - mutex_unlock(&pm2->lock); return ret; } @@ -150,13 +145,9 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) { int ret; - /* - * When AC adaptor is unplugged, the host - * must put LPN high to be able to - * communicate by I2C with PM2301 - * and receive I2C "acknowledge" from PM2301. - */ - mutex_lock(&pm2->lock); + + /* wake up the device */ + pm_runtime_get_sync(pm2->dev); ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 1, &val); @@ -164,7 +155,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); else ret = 0; - mutex_unlock(&pm2->lock); return ret; } -- cgit From 9b7f50e3ea9a98f518fc4077f8bebc96717acff5 Mon Sep 17 00:00:00 2001 From: Rupesh Kumar Date: Wed, 5 Dec 2012 16:13:31 +0530 Subject: pm2301-charger: Reference put missing after access Added missing pm_runtime_put_sync in read & write. Signed-off-by: Rupesh Kumar Signed-off-by: Lee Jones Reviewed-by: Sandeep TRIPATHY Reviewed-by: Philippe LANGLAIS --- drivers/power/pm2301_charger.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a1fc37eca334..618c46d25a3b 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -139,6 +139,8 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) else ret = 0; + pm_runtime_put_sync(pm2->dev); + return ret; } @@ -156,6 +158,8 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) else ret = 0; + pm_runtime_put_sync(pm2->dev); + return ret; } -- cgit From 4d3b4aa58ac9e18029c4d0259630414cffd3ba76 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 15 Feb 2013 10:58:58 +0000 Subject: abx500-chargalg: Add charging current step interface To prevent overheating, provide differnt steps of charging current interface to allow thermal mitigation. This will provide possibility to reduce gradually the charging current. Signed-off-by: Lee Jones --- drivers/power/abx500_chargalg.c | 231 +++++++++++++++++++++++++++------------- 1 file changed, 155 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 7e4bc011dd8f..9863e423602c 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -47,6 +47,9 @@ /* Plus margin for the low battery threshold */ #define BAT_PLUS_MARGIN (100) +#define CHARGALG_CURR_STEP_LOW 0 +#define CHARGALG_CURR_STEP_HIGH 100 + #define to_abx500_chargalg_device_info(x) container_of((x), \ struct abx500_chargalg, chargalg_psy); @@ -80,6 +83,11 @@ struct abx500_chargalg_suspension_status { bool usb_suspended; }; +struct abx500_chargalg_current_step_status { + bool curr_step_change; + int curr_step; +}; + struct abx500_chargalg_battery_data { int temp; int volt; @@ -220,6 +228,7 @@ enum maxim_ret { * @batt_data: data of the battery * @susp_status: current charger suspension status * @bm: Platform specific battery management information + * @curr_status: Current step status for over-current protection * @parent: pointer to the struct abx500 * @chargalg_psy: structure that holds the battery properties exposed by * the charging algorithm @@ -245,6 +254,7 @@ struct abx500_chargalg { struct abx500_chargalg_battery_data batt_data; struct abx500_chargalg_suspension_status susp_status; struct ab8500 *parent; + struct abx500_chargalg_current_step_status curr_status; struct abx500_bm_data *bm; struct power_supply chargalg_psy; struct ux500_charger *ac_chg; @@ -268,6 +278,12 @@ static enum power_supply_property abx500_chargalg_props[] = { POWER_SUPPLY_PROP_HEALTH, }; +struct abx500_chargalg_sysfs_entry { + struct attribute attr; + ssize_t (*show)(struct abx500_chargalg *, char *); + ssize_t (*store)(struct abx500_chargalg *, const char *, size_t); +}; + /** * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer * @timer: pointer to the hrtimer structure @@ -401,6 +417,22 @@ static int abx500_chargalg_check_charger_connection(struct abx500_chargalg *di) return di->chg_info.conn_chg; } +/** + * abx500_chargalg_check_current_step_status() - Check charging current + * step status. + * @di: pointer to the abx500_chargalg structure + * + * This function will check if there is a change in the charging current step + * and change charge state accordingly. + */ +static void abx500_chargalg_check_current_step_status + (struct abx500_chargalg *di) +{ + if (di->curr_status.curr_step_change) + abx500_chargalg_state_to(di, STATE_NORMAL_INIT); + di->curr_status.curr_step_change = false; +} + /** * abx500_chargalg_start_safety_timer() - Start charging safety timer * @di: pointer to the abx500_chargalg structure @@ -1300,6 +1332,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) { int charger_status; int ret; + int curr_step_lvl; /* Collect data from all power_supply class devices */ class_for_each_device(power_supply_class, NULL, @@ -1310,6 +1343,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) abx500_chargalg_check_charger_voltage(di); charger_status = abx500_chargalg_check_charger_connection(di); + abx500_chargalg_check_current_step_status(di); if (is_ab8500(di->parent)) { ret = abx500_chargalg_check_charger_enable(di); @@ -1523,9 +1557,18 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) } } - abx500_chargalg_start_charging(di, - di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + if (di->curr_status.curr_step == CHARGALG_CURR_STEP_LOW) + abx500_chargalg_stop_charging(di); + else { + curr_step_lvl = di->bm->bat_type[ + di->bm->batt_id].normal_cur_lvl + * di->curr_status.curr_step + / CHARGALG_CURR_STEP_HIGH; + abx500_chargalg_start_charging(di, + di->bm->bat_type[di->bm->batt_id] + .normal_vol_lvl, curr_step_lvl); + } + abx500_chargalg_state_to(di, STATE_NORMAL); abx500_chargalg_start_safety_timer(di); abx500_chargalg_stop_maintenance_timer(di); @@ -1767,99 +1810,134 @@ static int abx500_chargalg_get_property(struct power_supply *psy, /* Exposure to the sysfs interface */ -/** - * abx500_chargalg_sysfs_show() - sysfs show operations - * @kobj: pointer to the struct kobject - * @attr: pointer to the struct attribute - * @buf: buffer that holds the parameter to send to userspace - * - * Returns a buffer to be displayed in user space - */ -static ssize_t abx500_chargalg_sysfs_show(struct kobject *kobj, - struct attribute *attr, char *buf) +static ssize_t abx500_chargalg_curr_step_show(struct abx500_chargalg *di, + char *buf) { - struct abx500_chargalg *di = container_of(kobj, - struct abx500_chargalg, chargalg_kobject); + return sprintf(buf, "%d\n", di->curr_status.curr_step); +} + +static ssize_t abx500_chargalg_curr_step_store(struct abx500_chargalg *di, + const char *buf, size_t length) +{ + long int param; + int ret; + + ret = kstrtol(buf, 10, ¶m); + if (ret < 0) + return ret; + di->curr_status.curr_step = param; + if (di->curr_status.curr_step >= CHARGALG_CURR_STEP_LOW && + di->curr_status.curr_step <= CHARGALG_CURR_STEP_HIGH) { + di->curr_status.curr_step_change = true; + queue_work(di->chargalg_wq, &di->chargalg_work); + } else + dev_info(di->dev, "Wrong current step\n" + "Enter 0. Disable AC/USB Charging\n" + "1--100. Set AC/USB charging current step\n" + "100. Enable AC/USB Charging\n"); + + return strlen(buf); +} + + +static ssize_t abx500_chargalg_en_show(struct abx500_chargalg *di, + char *buf) +{ return sprintf(buf, "%d\n", di->susp_status.ac_suspended && di->susp_status.usb_suspended); } -/** - * abx500_chargalg_sysfs_charger() - sysfs store operations - * @kobj: pointer to the struct kobject - * @attr: pointer to the struct attribute - * @buf: buffer that holds the parameter passed from userspace - * @length: length of the parameter passed - * - * Returns length of the buffer(input taken from user space) on success - * else error code on failure - * The operation to be performed on passing the parameters from the user space. - */ -static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t length) +static ssize_t abx500_chargalg_en_store(struct abx500_chargalg *di, + const char *buf, size_t length) { - struct abx500_chargalg *di = container_of(kobj, - struct abx500_chargalg, chargalg_kobject); long int param; int ac_usb; int ret; - char entry = *attr->name; - switch (entry) { - case 'c': - ret = strict_strtol(buf, 10, ¶m); - if (ret < 0) - return ret; - - ac_usb = param; - switch (ac_usb) { - case 0: - /* Disable charging */ - di->susp_status.ac_suspended = true; - di->susp_status.usb_suspended = true; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - case 1: - /* Enable AC Charging */ - di->susp_status.ac_suspended = false; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - case 2: - /* Enable USB charging */ - di->susp_status.usb_suspended = false; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - default: - dev_info(di->dev, "Wrong input\n" - "Enter 0. Disable AC/USB Charging\n" - "1. Enable AC charging\n" - "2. Enable USB Charging\n"); - }; + ret = kstrtol(buf, 10, ¶m); + if (ret < 0) + return ret; + + ac_usb = param; + switch (ac_usb) { + case 0: + /* Disable charging */ + di->susp_status.ac_suspended = true; + di->susp_status.usb_suspended = true; + di->susp_status.suspended_change = true; + /* Trigger a state change */ + queue_work(di->chargalg_wq, + &di->chargalg_work); + break; + case 1: + /* Enable AC Charging */ + di->susp_status.ac_suspended = false; + di->susp_status.suspended_change = true; + /* Trigger a state change */ + queue_work(di->chargalg_wq, + &di->chargalg_work); break; + case 2: + /* Enable USB charging */ + di->susp_status.usb_suspended = false; + di->susp_status.suspended_change = true; + /* Trigger a state change */ + queue_work(di->chargalg_wq, + &di->chargalg_work); + break; + default: + dev_info(di->dev, "Wrong input\n" + "Enter 0. Disable AC/USB Charging\n" + "1. Enable AC charging\n" + "2. Enable USB Charging\n"); }; return strlen(buf); } -static struct attribute abx500_chargalg_en_charger = \ +static struct abx500_chargalg_sysfs_entry abx500_chargalg_en_charger = + __ATTR(chargalg, 0644, abx500_chargalg_en_show, + abx500_chargalg_en_store); + +static struct abx500_chargalg_sysfs_entry abx500_chargalg_curr_step = + __ATTR(chargalg_curr_step, 0644, abx500_chargalg_curr_step_show, + abx500_chargalg_curr_step_store); + +static ssize_t abx500_chargalg_sysfs_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct abx500_chargalg_sysfs_entry *entry = container_of(attr, + struct abx500_chargalg_sysfs_entry, attr); + + struct abx500_chargalg *di = container_of(kobj, + struct abx500_chargalg, chargalg_kobject); + + if (!entry->show) + return -EIO; + + return entry->show(di, buf); +} + +static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t length) { - .name = "chargalg", - .mode = S_IRUGO | S_IWUSR, -}; + struct abx500_chargalg_sysfs_entry *entry = container_of(attr, + struct abx500_chargalg_sysfs_entry, attr); + + struct abx500_chargalg *di = container_of(kobj, + struct abx500_chargalg, chargalg_kobject); + + if (!entry->store) + return -EIO; + + return entry->store(di, buf, length); +} static struct attribute *abx500_chargalg_chg[] = { - &abx500_chargalg_en_charger, - NULL + &abx500_chargalg_en_charger.attr, + &abx500_chargalg_curr_step.attr, + NULL, }; static const struct sysfs_ops abx500_chargalg_sysfs_ops = { @@ -2052,6 +2130,7 @@ static int abx500_chargalg_probe(struct platform_device *pdev) dev_err(di->dev, "failed to create sysfs entry\n"); goto free_psy; } + di->curr_status.curr_step = CHARGALG_CURR_STEP_HIGH; /* Run the charging algorithm */ queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0); -- cgit From 0577610e0e6b431a1503cc5d78e8178e0dd59948 Mon Sep 17 00:00:00 2001 From: lme00437 Date: Wed, 12 Dec 2012 10:07:50 +0100 Subject: ab8500-fg: Change current calculation This patch updates the gas gauge constant for electric current calculation according to hardware specification. Signed-off-by: Benoit GAUTHIER Signed-off-by: Lee Jones Reviewed-by: Marcus COOPER Reviewed-by: Philippe LANGLAIS Tested-by: Benoit GAUTHIER --- drivers/power/ab8500_fg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index adc02004e7a3..1601d27ce5d4 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -36,7 +36,7 @@ #define MILLI_TO_MICRO 1000 #define FG_LSB_IN_MA 1627 -#define QLSB_NANO_AMP_HOURS_X10 1129 +#define QLSB_NANO_AMP_HOURS_X10 1071 #define INS_CURR_TIMEOUT (3 * HZ) #define SEC_TO_SAMPLE(S) (S * 4) @@ -672,11 +672,11 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) /* * Convert to unit value in mA * Full scale input voltage is - * 66.660mV => LSB = 66.660mV/(4096*res) = 1.627mA + * 63.160mV => LSB = 63.160mV/(4096*res) = 1.542mA * Given a 250ms conversion cycle time the LSB corresponds - * to 112.9 nAh. Convert to current by dividing by the conversion + * to 107.1 nAh. Convert to current by dividing by the conversion * time in hours (250ms = 1 / (3600 * 4)h) - * 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm + * 107.1nAh assumes 10mOhm, but fg_res is in 0.1mOhm */ val = (val * QLSB_NANO_AMP_HOURS_X10 * 36 * 4) / (1000 * di->bm->fg_res); -- cgit From b09f86dbfc20d9420dac43dba016cb65b582c983 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 21 Dec 2012 17:56:52 -0800 Subject: ab8500-charger: Do not use [delayed_]work_pending() There's no need to test whether a (delayed) work item is pending before queueing, flushing or cancelling it. Most uses are unnecessary and quite a few of them are buggy. Signed-off-by: Lee Jones --- drivers/power/ab8500_charger.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 81c9615fd726..a558318b169c 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -1661,8 +1661,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, dev_dbg(di->dev, "%s Disabled USB charging\n", __func__); /* Cancel any pending Vbat check work */ - if (delayed_work_pending(&di->check_vbat_work)) - cancel_delayed_work(&di->check_vbat_work); + cancel_delayed_work(&di->check_vbat_work); } ab8500_power_supply_changed(di, &di->usb_chg.psy); @@ -3335,11 +3334,8 @@ static int ab8500_charger_resume(struct platform_device *pdev) dev_err(di->dev, "Failed to kick WD!\n"); /* If not already pending start a new timer */ - if (!delayed_work_pending( - &di->kick_wd_work)) { - queue_delayed_work(di->charger_wq, &di->kick_wd_work, - round_jiffies(WD_KICK_INTERVAL)); - } + queue_delayed_work(di->charger_wq, &di->kick_wd_work, + round_jiffies(WD_KICK_INTERVAL)); } /* If we still have a HW failure, schedule a new check */ @@ -3359,12 +3355,9 @@ static int ab8500_charger_suspend(struct platform_device *pdev, { struct ab8500_charger *di = platform_get_drvdata(pdev); - /* Cancel any pending HW failure check */ - if (delayed_work_pending(&di->check_hw_failure_work)) - cancel_delayed_work(&di->check_hw_failure_work); - - if (delayed_work_pending(&di->vbus_drop_end_work)) - cancel_delayed_work(&di->vbus_drop_end_work); + /* Cancel any pending jobs */ + cancel_delayed_work(&di->check_hw_failure_work); + cancel_delayed_work(&di->vbus_drop_end_work); flush_delayed_work(&di->attach_work); flush_delayed_work(&di->usb_charger_attached_work); -- cgit From b5f50bf923edfb1ab1dc3620db90989d5a9dafa5 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 6 Mar 2013 16:12:44 +0100 Subject: pinctrl: sunxi: Add Allwinner A10 pin functions The initial driver contained only a limited set of pins functions because we lacked of documentation on it. Now that we have such documentation, finish to fill the array. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-sunxi.c | 733 +++++++++++++++++++++++++++++++--------- 1 file changed, 571 insertions(+), 162 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index 46b8f2d4f0a5..74f6d59790fe 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c @@ -30,482 +30,856 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXD3 */ + SUNXI_FUNCTION(0x3, "spi1"), /* CS0 */ + SUNXI_FUNCTION(0x4, "uart2")), /* RTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXD2 */ + SUNXI_FUNCTION(0x3, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x4, "uart2")), /* CTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXD1 */ + SUNXI_FUNCTION(0x3, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x4, "uart2")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXD0 */ + SUNXI_FUNCTION(0x3, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x4, "uart2")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXD3 */ + SUNXI_FUNCTION(0x3, "spi1")), /* CS1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXD2 */ + SUNXI_FUNCTION(0x3, "spi3")), /* CS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXD1 */ + SUNXI_FUNCTION(0x3, "spi3")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXD0 */ + SUNXI_FUNCTION(0x3, "spi3")), /* MOSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXCK */ + SUNXI_FUNCTION(0x3, "spi3")), /* MISO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXERR */ + SUNXI_FUNCTION(0x3, "spi3")), /* CS1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ERXDV */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* EMDC */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* EMDIO */ + SUNXI_FUNCTION(0x3, "uart6"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* RTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXEN */ + SUNXI_FUNCTION(0x3, "uart6"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* CTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXCK */ + SUNXI_FUNCTION(0x3, "uart7"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* DTR */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ECRS */ + SUNXI_FUNCTION(0x3, "uart7"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* DSR */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ECOL */ + SUNXI_FUNCTION(0x3, "can"), /* TX */ SUNXI_FUNCTION(0x4, "uart1")), /* DCD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "wemac"), /* ETXERR */ + SUNXI_FUNCTION(0x3, "can"), /* RX */ SUNXI_FUNCTION(0x4, "uart1")), /* RING */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm")), /* PWM0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ir0")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ir0")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s"), /* MCLK */ + SUNXI_FUNCTION(0x3, "ac97")), /* MCLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s"), /* BCLK */ + SUNXI_FUNCTION(0x3, "ac97")), /* BCLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s"), /* LRCK */ + SUNXI_FUNCTION(0x3, "ac97")), /* SYNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s"), /* DO0 */ + SUNXI_FUNCTION(0x3, "ac97")), /* DO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s")), /* DO1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s")), /* DO2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s")), /* DO3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s"), /* DI */ + SUNXI_FUNCTION(0x3, "ac97")), /* DI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2")), /* CS1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2"), /* CS0 */ + SUNXI_FUNCTION(0x3, "jtag")), /* MS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2"), /* CLK */ + SUNXI_FUNCTION(0x3, "jtag")), /* CK0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2"), /* MOSI */ + SUNXI_FUNCTION(0x3, "jtag")), /* DO0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2"), /* MISO */ + SUNXI_FUNCTION(0x3, "jtag")), /* DI0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB22, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart0")), /* TX */ + SUNXI_FUNCTION(0x2, "uart0"), /* TX */ + SUNXI_FUNCTION(0x3, "ir1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB23, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart0")), /* RX */ + SUNXI_FUNCTION(0x2, "uart0"), /* RX */ + SUNXI_FUNCTION(0x3, "ir1")), /* RX */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NWE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NALE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */ + SUNXI_FUNCTION(0x3, "spi0")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NRE# */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NRB0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NRB1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ2 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ3 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NDQ4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NDQ5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NDQ6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NDQ7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NWP */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE4 */ + SUNXI_FUNCTION(0x3, "spi2")), /* CS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE5 */ + SUNXI_FUNCTION(0x3, "spi2")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE6 */ + SUNXI_FUNCTION(0x3, "spi2")), /* MOSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE7 */ + SUNXI_FUNCTION(0x3, "spi2")), /* MISO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NDQS */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D0 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D1 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VM3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VPC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */ + SUNXI_FUNCTION(0x3, "csi1")), /* MCLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */ + SUNXI_FUNCTION(0x3, "sim")), /* VPPEN */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */ + SUNXI_FUNCTION(0x3, "sim")), /* VPPPP */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */ + SUNXI_FUNCTION(0x3, "sim")), /* DET */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */ + SUNXI_FUNCTION(0x3, "sim")), /* VCCEN */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* DE */ + SUNXI_FUNCTION(0x3, "sim")), /* RST */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */ + SUNXI_FUNCTION(0x3, "sim")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */ + SUNXI_FUNCTION(0x3, "sim")), /* SDA */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* CLK */ + SUNXI_FUNCTION(0x3, "csi0")), /* PCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* ERR */ + SUNXI_FUNCTION(0x3, "csi0")), /* CK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* SYNC */ + SUNXI_FUNCTION(0x3, "csi0")), /* HSYNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* DVLD */ + SUNXI_FUNCTION(0x3, "csi0")), /* VSYNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D0 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D1 */ + SUNXI_FUNCTION(0x3, "csi0"), /* D1 */ + SUNXI_FUNCTION(0x4, "sim")), /* VPPEN */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D2 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D3 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D4 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D5 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D6 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts0"), /* D7 */ + SUNXI_FUNCTION(0x3, "csi0")), /* D7 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */ + SUNXI_FUNCTION(0x4, "jtag")), /* MSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */ + SUNXI_FUNCTION(0x4, "jtag")), /* DI1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ SUNXI_FUNCTION(0x4, "uart0")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */ + SUNXI_FUNCTION(0x4, "jtag")), /* DO1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ SUNXI_FUNCTION(0x4, "uart0")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */ + SUNXI_FUNCTION(0x4, "jtag")), /* CK1 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* CLK */ + SUNXI_FUNCTION(0x3, "csi1"), /* PCK */ + SUNXI_FUNCTION(0x4, "mmc1")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* ERR */ + SUNXI_FUNCTION(0x3, "csi1"), /* CK */ + SUNXI_FUNCTION(0x4, "mmc1")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* SYNC */ + SUNXI_FUNCTION(0x3, "csi1"), /* HSYNC */ + SUNXI_FUNCTION(0x4, "mmc1")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* DVLD */ + SUNXI_FUNCTION(0x3, "csi1"), /* VSYNC */ + SUNXI_FUNCTION(0x4, "mmc1")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D0 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D0 */ + SUNXI_FUNCTION(0x4, "mmc1"), /* D2 */ + SUNXI_FUNCTION(0x5, "csi0")), /* D8 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D1 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D1 */ + SUNXI_FUNCTION(0x4, "mmc1"), /* D3 */ + SUNXI_FUNCTION(0x5, "csi0")), /* D9 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D2 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D2 */ + SUNXI_FUNCTION(0x4, "uart3"), /* TX */ + SUNXI_FUNCTION(0x5, "csi0")), /* D10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D3 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D3 */ + SUNXI_FUNCTION(0x4, "uart3"), /* RX */ + SUNXI_FUNCTION(0x5, "csi0")), /* D11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D4 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D4 */ + SUNXI_FUNCTION(0x4, "uart3"), /* RTS */ + SUNXI_FUNCTION(0x5, "csi0")), /* D12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D5 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D5 */ + SUNXI_FUNCTION(0x4, "uart3"), /* CTS */ + SUNXI_FUNCTION(0x5, "csi0")), /* D13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D6 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D6 */ + SUNXI_FUNCTION(0x4, "uart4"), /* TX */ + SUNXI_FUNCTION(0x5, "csi0")), /* D14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ts1"), /* D7 */ + SUNXI_FUNCTION(0x3, "csi1"), /* D7 */ + SUNXI_FUNCTION(0x4, "uart4"), /* RX */ + SUNXI_FUNCTION(0x5, "csi0")), /* D15 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D0 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAA0 */ + SUNXI_FUNCTION(0x4, "uart3"), /* TX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D1 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAA1 */ + SUNXI_FUNCTION(0x4, "uart3"), /* RX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D2 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAA2 */ + SUNXI_FUNCTION(0x4, "uart3"), /* RTS */ + SUNXI_FUNCTION(0x7, "csi1")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D3 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAIRQ */ + SUNXI_FUNCTION(0x4, "uart3"), /* CTS */ + SUNXI_FUNCTION(0x7, "csi1")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D4 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD0 */ + SUNXI_FUNCTION(0x4, "uart4"), /* TX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D5 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD1 */ + SUNXI_FUNCTION(0x4, "uart4"), /* RX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D6 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD2 */ + SUNXI_FUNCTION(0x4, "uart5"), /* TX */ + SUNXI_FUNCTION(0x5, "ms"), /* BS */ + SUNXI_FUNCTION(0x7, "csi1")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D7 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD3 */ + SUNXI_FUNCTION(0x4, "uart5"), /* RX */ + SUNXI_FUNCTION(0x5, "ms"), /* CLK */ + SUNXI_FUNCTION(0x7, "csi1")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D8 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD4 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN0 */ + SUNXI_FUNCTION(0x5, "ms"), /* D0 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D8 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D9 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD5 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN1 */ + SUNXI_FUNCTION(0x5, "ms"), /* D1 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D9 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D10 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD6 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN2 */ + SUNXI_FUNCTION(0x5, "ms"), /* D2 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D11 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD7 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN3 */ + SUNXI_FUNCTION(0x5, "ms"), /* D3 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D12 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD8 */ + SUNXI_FUNCTION(0x4, "ps2"), /* SCK1 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D13 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD9 */ + SUNXI_FUNCTION(0x4, "ps2"), /* SDA1 */ + SUNXI_FUNCTION(0x5, "sim"), /* RST */ + SUNXI_FUNCTION(0x7, "csi1")), /* D13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D14 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD10 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN4 */ + SUNXI_FUNCTION(0x5, "sim"), /* VPPEN */ + SUNXI_FUNCTION(0x7, "csi1")), /* D14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D15 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD11 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN5 */ + SUNXI_FUNCTION(0x5, "sim"), /* VPPPP */ + SUNXI_FUNCTION(0x7, "csi1")), /* D15 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D16 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD12 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN6 */ + SUNXI_FUNCTION(0x7, "csi1")), /* D16 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D17 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD13 */ + SUNXI_FUNCTION(0x4, "keypad"), /* IN7 */ + SUNXI_FUNCTION(0x5, "sim"), /* VCCEN */ + SUNXI_FUNCTION(0x7, "csi1")), /* D17 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D18 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD14 */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT0 */ + SUNXI_FUNCTION(0x5, "sim"), /* SCK */ + SUNXI_FUNCTION(0x7, "csi1")), /* D18 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D19 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAD15 */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT1 */ + SUNXI_FUNCTION(0x5, "sim"), /* SDA */ + SUNXI_FUNCTION(0x7, "csi1")), /* D19 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D20 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAOE */ + SUNXI_FUNCTION(0x4, "can"), /* TX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D20 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D21 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATADREQ */ + SUNXI_FUNCTION(0x4, "can"), /* RX */ + SUNXI_FUNCTION(0x7, "csi1")), /* D21 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D22 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATADACK */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT2 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* CMD */ + SUNXI_FUNCTION(0x7, "csi1")), /* D22 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* D23 */ + SUNXI_FUNCTION(0x3, "pata"), /* ATACS0 */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT3 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* CLK */ + SUNXI_FUNCTION(0x7, "csi1")), /* D23 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* CLK */ + SUNXI_FUNCTION(0x3, "pata"), /* ATACS1 */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT4 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* D0 */ + SUNXI_FUNCTION(0x7, "csi1")), /* PCLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* DE */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAIORDY */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT5 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* D1 */ + SUNXI_FUNCTION(0x7, "csi1")), /* FIELD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* HSYNC */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAIOR */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT6 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* D2 */ + SUNXI_FUNCTION(0x7, "csi1")), /* HSYNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PH27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd1"), /* VSYNC */ + SUNXI_FUNCTION(0x3, "pata"), /* ATAIOW */ + SUNXI_FUNCTION(0x4, "keypad"), /* OUT7 */ + SUNXI_FUNCTION(0x5, "mmc1"), /* D3 */ + SUNXI_FUNCTION(0x7, "csi1")), /* VSYNC */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI0, SUNXI_FUNCTION(0x0, "gpio_in"), @@ -518,61 +892,96 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { SUNXI_FUNCTION(0x1, "gpio_out")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PI3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm")), /* PWM1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc3")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* CS0 */ + SUNXI_FUNCTION(0x3, "uart5")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart5")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* MOSI */ + SUNXI_FUNCTION(0x3, "uart6")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* MISO */ + SUNXI_FUNCTION(0x3, "uart6")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* CS1 */ + SUNXI_FUNCTION(0x3, "ps2"), /* SCK1 */ + SUNXI_FUNCTION(0x4, "timer4")), /* TCLKIN0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */ + SUNXI_FUNCTION(0x3, "ps2"), /* SDA1 */ + SUNXI_FUNCTION(0x4, "timer5")), /* TCLKIN1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ + SUNXI_FUNCTION(0x3, "uart2")), /* RTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart2")), /* CTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x3, "uart2")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x3, "uart2")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ps2"), /* SCK0 */ + SUNXI_FUNCTION(0x3, "uart7"), /* TX */ + SUNXI_FUNCTION(0x4, "hdmi")), /* HSCL */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PI21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ps2"), /* SDA0 */ + SUNXI_FUNCTION(0x3, "uart7"), /* RX */ + SUNXI_FUNCTION(0x4, "hdmi")), /* HSDA */ }; static const struct sunxi_desc_pin sun5i_a13_pins[] = { -- cgit From ee341a99de7386434a0d5cf4bc4329c3ab972a13 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 6 Mar 2013 16:12:45 +0100 Subject: pinctrl: sunxi: Add Allwinner A13 pin functions The initial driver contained only a limited set of pins functions because we lacked of documentation on it. Now that we have such documentation, finish to fill the array. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-sunxi.c | 239 ++++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index 74f6d59790fe..cb491d6ba601 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c @@ -988,216 +988,305 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm")), SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ir0")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "ir0")), /* RX */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi2")), /* CS1 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NWE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NALE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCLE */ + SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NCE1 */ + SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NCE0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* NRE */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NRB0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NRB1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ2 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ3 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ4 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ5 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ6 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQ7 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* NDQS */ + SUNXI_FUNCTION(0x4, "uart3")), /* RTS */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D7 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D15 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D18 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D19 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D20 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D21 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D22 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D23 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* DE */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* HSYNC */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* VSYNC */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x3, "csi0"), /* PCLK */ + SUNXI_FUNCTION(0x4, "spi2")), /* CS0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x3, "csi0"), /* MCLK */ + SUNXI_FUNCTION(0x4, "spi2")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x3, "csi0"), /* HSYNC */ + SUNXI_FUNCTION(0x4, "spi2")), /* MOSI */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* VSYNC */ + SUNXI_FUNCTION(0x4, "spi2")), /* MISO */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D0 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D1 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D2 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* D2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D3 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D4 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D5 */ + SUNXI_FUNCTION(0x4, "mmc2")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D6 */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "csi0"), /* D7 */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* D1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* D0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* CLK */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* CMD */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* D3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x4, "mmc0")), /* D2 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0, SUNXI_FUNCTION(0x0, "gpio_in"), @@ -1211,24 +1300,34 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ SUNXI_FUNCTION(0x4, "uart1")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4, SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ SUNXI_FUNCTION(0x4, "uart1")), /* RX */ - /* Hole */ +/* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ + SUNXI_FUNCTION(0x3, "uart3")), /* TX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart3")), /* RX */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x3, "uart3")), /* CTS */ SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12, SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x3, "uart3")), /* RTS */ }; static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = { -- cgit From 5b62efd8250d6a751c31d1972e96bfccd19c4679 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 27 Feb 2013 16:23:15 +0100 Subject: HID: multitouch: remove useless last_field_index field The aim of last_field_index was to detect the end of the report. With the introduction of .report(), it is not required anymore to detect it on the fly as we can put it in the right place during the .report(). The resulting code path is simpler to read because the terminating condition is not evaluated after each field. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 7a1ebb867cf4..3f6849ddd29c 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -86,7 +86,6 @@ struct mt_device { multitouch fields */ int cc_index; /* contact count field index in the report */ int cc_value_index; /* contact count value index in the field */ - unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ unsigned mt_report_id; /* the report ID of the multitouch device */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ @@ -405,7 +404,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, } mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_GD_Y: if (prev_usage && (prev_usage->hid == usage->hid)) { @@ -421,7 +419,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, } mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; } return 0; @@ -436,21 +433,17 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, ABS_MT_DISTANCE, 0, 1, 0, 0); } mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_CONFIDENCE: mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_TIPSWITCH: hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH); mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_CONTACTID: mt_store_field(usage, td, hi); - td->last_field_index = field->index; td->touches_by_report++; td->mt_report_id = field->report->id; return 1; @@ -461,7 +454,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, cls->sn_width); mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, @@ -473,7 +465,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, ABS_MT_ORIENTATION, 0, 1, 0, 0); } mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_TIPPRESSURE: hid_map_usage(hi, usage, bit, max, @@ -481,17 +472,14 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, set_abs(hi->input, ABS_MT_PRESSURE, field, cls->sn_pressure); mt_store_field(usage, td, hi); - td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: td->cc_index = field->index; td->cc_value_index = usage->usage_index; - td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ - td->last_field_index = field->index; return -1; case HID_DG_TOUCH: /* Legacy devices use TIPSWITCH and not TOUCH. @@ -677,10 +665,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, /* we only take into account the last report. */ if (usage->hid == td->last_slot_field) mt_complete_slot(td, field->hidinput->input); - - if (field->index == td->last_field_index - && td->num_received >= td->num_expected) - mt_sync_frame(td, field->hidinput->input); } } @@ -721,6 +705,9 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) mt_process_mt_event(hid, field, &field->usage[n], field->value[n]); } + + if (td->num_received >= td->num_expected) + mt_sync_frame(td, report->field[0]->hidinput->input); } static void mt_set_input_mode(struct hid_device *hdev) -- cgit From 777d4bb39a585ff54817815544941c2da70a0bb9 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 7 Mar 2013 10:48:29 +0100 Subject: HID: holtek: Holtek devices depends on USB_HID In the HID drivers tranport cleanup series, I removed the dependency between hid-holtek and usbhid. This was wrong as hid-holtek.c relies extensively on usb calls. This fixes compilation error when CONFIG_USB_SUPPORT is not enabled. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index c802b0716f48..d1dcfc78bed2 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -215,7 +215,7 @@ config HID_EZKEY config HID_HOLTEK tristate "Holtek HID devices" - depends on HID + depends on USB_HID ---help--- Support for Holtek based devices: - Holtek On Line Grip based game controller -- cgit From 9684819b5a29e62acd8265a92d8f3454de9bb71e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 27 Feb 2013 16:38:17 +0100 Subject: HID: ll_driver: Extend the interface with idle requests Some drivers send the idle command directly to underlying device, creating an unwanted dependency on the underlying transport layer. This patch adds hid_hw_idle() to the interface, thereby removing usbhid from the lion share of the drivers. Signed-off-by: Benjamin Tissoires Reviewed-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 15 +++++++++++++++ include/linux/hid.h | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 420466bc481a..effcd3d6f5cf 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1253,6 +1253,20 @@ static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int r } } +static int usbhid_idle(struct hid_device *hid, int report, int idle, + int reqtype) +{ + struct usb_device *dev = hid_to_usb_dev(hid); + struct usb_interface *intf = to_usb_interface(hid->dev.parent); + struct usb_host_interface *interface = intf->cur_altsetting; + int ifnum = interface->desc.bInterfaceNumber; + + if (reqtype != HID_REQ_SET_IDLE) + return -EINVAL; + + return hid_set_idle(dev, ifnum, report, idle); +} + static struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, @@ -1263,6 +1277,7 @@ static struct hid_ll_driver usb_hid_driver = { .hidinput_input_event = usb_hidinput_input_event, .request = usbhid_request, .wait = usbhid_wait_io, + .idle = usbhid_idle, }; static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/include/linux/hid.h b/include/linux/hid.h index 7071eb3d36c7..863744c38ddc 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -664,6 +664,7 @@ struct hid_driver { * shouldn't allocate anything to not leak memory * @request: send report request to device (e.g. feature report) * @wait: wait for buffered io to complete (send/recv reports) + * @idle: send idle request to device */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -683,6 +684,7 @@ struct hid_ll_driver { struct hid_report *report, int reqtype); int (*wait)(struct hid_device *hdev); + int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); }; @@ -906,6 +908,23 @@ static inline void hid_hw_request(struct hid_device *hdev, hdev->ll_driver->request(hdev, report, reqtype); } +/** + * hid_hw_idle - send idle request to device + * + * @hdev: hid device + * @report: report to control + * @idle: idle state + * @reqtype: hid request type + */ +static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle, + int reqtype) +{ + if (hdev->ll_driver->idle) + return hdev->ll_driver->idle(hdev, report, idle, reqtype); + + return 0; +} + /** * hid_hw_wait - wait for buffered io to complete * -- cgit From 4ba25d3f87fe3ed6634f61da2a6904e2dfd09192 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 27 Feb 2013 16:38:18 +0100 Subject: HID: multitouch: remove last usb dependency hid-multitouch used to direclty call for a set_idle in the .resume() callback. With the new hid_hw_idle(), this can be dropped and hid-multitouch is now freed from its transport layer. Signed-off-by: Benjamin Tissoires Reviewed-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3af9efdd13d9..f712772437cb 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -909,26 +909,11 @@ static int mt_reset_resume(struct hid_device *hdev) static int mt_resume(struct hid_device *hdev) { - struct usb_interface *intf; - struct usb_host_interface *interface; - struct usb_device *dev; - - if (hdev->bus != BUS_USB) - return 0; - - intf = to_usb_interface(hdev->dev.parent); - interface = intf->cur_altsetting; - dev = interface_to_usbdev(intf); - /* Some Elan legacy devices require SET_IDLE to be set on resume. * It should be safe to send it to other devices too. * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ - usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_IDLE, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, interface->desc.bInterfaceNumber, - NULL, 0, USB_CTRL_SET_TIMEOUT); + hid_hw_idle(hdev, 0, 0, HID_REQ_SET_IDLE); return 0; } -- cgit From 4a74dc65e3ad825a66dfbcb256f98c550f96445b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Mar 2013 20:13:54 +0000 Subject: sfc: Allow efx_channel_type::receive_skb() to reject a packet Instead of having efx_ptp_rx() call netif_receive_skb() for an invalid PTP packet, make it return false for rejected packets and have efx_rx_deliver() pass them up. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 2 +- drivers/net/ethernet/sfc/ptp.c | 16 +++++++--------- drivers/net/ethernet/sfc/rx.c | 10 ++++++---- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 0a90abd2421b..cdcf510311c3 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -410,7 +410,7 @@ struct efx_channel_type { void (*post_remove)(struct efx_channel *); void (*get_name)(struct efx_channel *, char *buf, size_t len); struct efx_channel *(*copy)(const struct efx_channel *); - void (*receive_skb)(struct efx_channel *, struct sk_buff *); + bool (*receive_skb)(struct efx_channel *, struct sk_buff *); bool keep_eventq; }; diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 3f93624fc273..faf4baf36861 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1006,7 +1006,7 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) * the receive timestamp from the MC - this will probably occur after the * packet arrival because of the processing in the MC. */ -static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) +static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) { struct efx_nic *efx = channel->efx; struct efx_ptp_data *ptp = efx->ptp_data; @@ -1019,18 +1019,15 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) /* Correct version? */ if (ptp->mode == MC_CMD_PTP_MODE_V1) { if (skb->len < PTP_V1_MIN_LENGTH) { - netif_receive_skb(skb); - return; + return false; } version = ntohs(*(__be16 *)&skb->data[PTP_V1_VERSION_OFFSET]); if (version != PTP_VERSION_V1) { - netif_receive_skb(skb); - return; + return false; } } else { if (skb->len < PTP_V2_MIN_LENGTH) { - netif_receive_skb(skb); - return; + return false; } version = skb->data[PTP_V2_VERSION_OFFSET]; @@ -1041,8 +1038,7 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH); if ((version & PTP_VERSION_V2_MASK) != PTP_VERSION_V2) { - netif_receive_skb(skb); - return; + return false; } } @@ -1073,6 +1069,8 @@ static void efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) skb_queue_tail(&ptp->rxq, skb); queue_work(ptp->workwq, &ptp->work); + + return true; } /* Transmit a PTP packet. This has to be transmitted by the MC diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index bb579a6128c8..f31c23ea2a07 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -575,12 +575,14 @@ static void efx_rx_deliver(struct efx_channel *channel, /* Record the rx_queue */ skb_record_rx_queue(skb, channel->rx_queue.core_index); - /* Pass the packet up */ if (channel->type->receive_skb) - channel->type->receive_skb(channel, skb); - else - netif_receive_skb(skb); + if (channel->type->receive_skb(channel, skb)) + goto handled; + + /* Pass the packet up */ + netif_receive_skb(skb); +handled: /* Update allocation strategy method */ channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; } -- cgit From c939a316459783e5cd6c6bd9dc90ea11b18ecd7f Mon Sep 17 00:00:00 2001 From: Laurence Evans Date: Thu, 15 Nov 2012 10:56:07 +0000 Subject: sfc: PTP changes to support improved UUID filtering mode There is a long-standing problem with the packet-timestamp matching in the driver. When a PTP packet is received by the MC, the FPGA timestamps the packet and the MC sends the timestamp and 6 bytes of the UUID to the driver. The driver then matches the timestamp against received packets using the same 6 bytes of UUID. The problem comes from the choice of which 6 bytes to use. The PTP spec is slightly contradictory and misleading in one of the two places where the UUIDs are discussed. From section 7.2.2.2 of the spec, a PTPD2 UUID can be either a EUI-64 or a EUI-64 constructed from a EUI-48. The typical ethernet based implementation uses a EUI-64 constructed from a EUI-48. This works by taking the first 3 bytes of the MAC address of the NIC being used for PTP (the OUI), then inserting 0xFF, 0xFE, then taking the last 3 bytes of the MAC address giving MAC[0], MAC[1], MAC[2], 0xFF, 0xFE, MAC[3], MAC[4], MAC[5] The current MC firmware and driver discard the first two bytes of this UUID and packets are matched against timestamps using bytes 2 to 7 so there is a small risk that in a deployment of Solarflare PTP NICs used with other vendors NICs, that a PTP packet could be matched against the wrong timestamp. This applies to all other organisations whose third byte of the OUI is 0x53. It's a long list but I notice that it includes Cisco. The necessary modifications to use bytes 0-2 and 5-7 of the UUID to match against are quite small but introduce incompatibility between older version of the firmware and driver. When PTP is enabled via SO_TIMESTAMPING specifying PTP V2, the driver will try to enable PTP in the firmware using the enhanced mode (above). If the firmware returns an error, the driver will enable PTP in the firmware using the old mode. [bwh: Fix some style errors; remove private ioctl bits] Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi_pcol.h | 1 + drivers/net/ethernet/sfc/ptp.c | 61 ++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index 9d426d0457bd..c5c9747861ba 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -553,6 +553,7 @@ #define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */ #define MC_CMD_PTP_MODE_V2 0x2 /* enum */ #define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */ +#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4 /* enum */ /* MC_CMD_PTP_IN_DISABLE msgrequest */ #define MC_CMD_PTP_IN_DISABLE_LEN 8 diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index faf4baf36861..2b40cbd6667b 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -99,6 +99,9 @@ #define PTP_V2_VERSION_LENGTH 1 #define PTP_V2_VERSION_OFFSET 29 +#define PTP_V2_UUID_LENGTH 8 +#define PTP_V2_UUID_OFFSET 48 + /* Although PTP V2 UUIDs are comprised a ClockIdentity (8) and PortNumber (2), * the MC only captures the last six bytes of the clock identity. These values * reflect those, not the ones used in the standard. The standard permits @@ -1011,7 +1014,7 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) struct efx_nic *efx = channel->efx; struct efx_ptp_data *ptp = efx->ptp_data; struct efx_ptp_match *match = (struct efx_ptp_match *)skb->cb; - u8 *data; + u8 *match_data_012, *match_data_345; unsigned int version; match->expiry = jiffies + msecs_to_jiffies(PKT_EVENT_LIFETIME_MS); @@ -1025,21 +1028,35 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) if (version != PTP_VERSION_V1) { return false; } + + /* PTP V1 uses all six bytes of the UUID to match the packet + * to the timestamp + */ + match_data_012 = skb->data + PTP_V1_UUID_OFFSET; + match_data_345 = skb->data + PTP_V1_UUID_OFFSET + 3; } else { if (skb->len < PTP_V2_MIN_LENGTH) { return false; } version = skb->data[PTP_V2_VERSION_OFFSET]; - - BUG_ON(ptp->mode != MC_CMD_PTP_MODE_V2); - BUILD_BUG_ON(PTP_V1_UUID_OFFSET != PTP_V2_MC_UUID_OFFSET); - BUILD_BUG_ON(PTP_V1_UUID_LENGTH != PTP_V2_MC_UUID_LENGTH); - BUILD_BUG_ON(PTP_V1_SEQUENCE_OFFSET != PTP_V2_SEQUENCE_OFFSET); - BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH); - if ((version & PTP_VERSION_V2_MASK) != PTP_VERSION_V2) { return false; } + + /* The original V2 implementation uses bytes 2-7 of + * the UUID to match the packet to the timestamp. This + * discards two of the bytes of the MAC address used + * to create the UUID (SF bug 33070). The PTP V2 + * enhanced mode fixes this issue and uses bytes 0-2 + * and byte 5-7 of the UUID. + */ + match_data_345 = skb->data + PTP_V2_UUID_OFFSET + 5; + if (ptp->mode == MC_CMD_PTP_MODE_V2) { + match_data_012 = skb->data + PTP_V2_UUID_OFFSET + 2; + } else { + match_data_012 = skb->data + PTP_V2_UUID_OFFSET + 0; + BUG_ON(ptp->mode != MC_CMD_PTP_MODE_V2_ENHANCED); + } } /* Does this packet require timestamping? */ @@ -1052,14 +1069,19 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) timestamps = skb_hwtstamps(skb); memset(timestamps, 0, sizeof(*timestamps)); + /* We expect the sequence number to be in the same position in + * the packet for PTP V1 and V2 + */ + BUILD_BUG_ON(PTP_V1_SEQUENCE_OFFSET != PTP_V2_SEQUENCE_OFFSET); + BUILD_BUG_ON(PTP_V1_SEQUENCE_LENGTH != PTP_V2_SEQUENCE_LENGTH); + /* Extract UUID/Sequence information */ - data = skb->data + PTP_V1_UUID_OFFSET; - match->words[0] = (data[0] | - (data[1] << 8) | - (data[2] << 16) | - (data[3] << 24)); - match->words[1] = (data[4] | - (data[5] << 8) | + match->words[0] = (match_data_012[0] | + (match_data_012[1] << 8) | + (match_data_012[2] << 16) | + (match_data_345[0] << 24)); + match->words[1] = (match_data_345[1] | + (match_data_345[2] << 8) | (skb->data[PTP_V1_SEQUENCE_OFFSET + PTP_V1_SEQUENCE_LENGTH - 1] << 16)); @@ -1165,7 +1187,7 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) * timestamped */ init->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; - new_mode = MC_CMD_PTP_MODE_V2; + new_mode = MC_CMD_PTP_MODE_V2_ENHANCED; enable_wanted = true; break; case HWTSTAMP_FILTER_PTP_V2_EVENT: @@ -1184,7 +1206,14 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) if (init->tx_type != HWTSTAMP_TX_OFF) enable_wanted = true; + /* Old versions of the firmware do not support the improved + * UUID filtering option (SF bug 33070). If the firmware does + * not accept the enhanced mode, fall back to the standard PTP + * v2 UUID filtering. + */ rc = efx_ptp_change_mode(efx, enable_wanted, new_mode); + if ((rc != 0) && (new_mode == MC_CMD_PTP_MODE_V2_ENHANCED)) + rc = efx_ptp_change_mode(efx, enable_wanted, MC_CMD_PTP_MODE_V2); if (rc != 0) return rc; -- cgit From 9230451af9efcf5e3d60ce7f4fec2468e8ce54b1 Mon Sep 17 00:00:00 2001 From: Laurence Evans Date: Mon, 11 Feb 2013 13:55:08 +0000 Subject: sfc: tidy up PTP synchronize function efx_ptp_process_times() Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/ptp.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 2b40cbd6667b..d1858c0e0827 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -432,13 +432,10 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, unsigned number_readings = (response_length / MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN); unsigned i; - unsigned min; - unsigned min_set = 0; unsigned total; unsigned ngood = 0; unsigned last_good = 0; struct efx_ptp_data *ptp = efx->ptp_data; - bool min_valid = false; u32 last_sec; u32 start_sec; struct timespec delta; @@ -446,35 +443,17 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, if (number_readings == 0) return -EAGAIN; - /* Find minimum value in this set of results, discarding clearly - * erroneous results. + /* Read the set of results and increment stats for any results that + * appera to be erroneous. */ for (i = 0; i < number_readings; i++) { efx_ptp_read_timeset(synch_buf, &ptp->timeset[i]); synch_buf += MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN; - if (ptp->timeset[i].window > SYNCHRONISATION_GRANULARITY_NS) { - if (min_valid) { - if (ptp->timeset[i].window < min_set) - min_set = ptp->timeset[i].window; - } else { - min_valid = true; - min_set = ptp->timeset[i].window; - } - } - } - - if (min_valid) { - if (ptp->base_sync_valid && (min_set > ptp->base_sync_ns)) - min = ptp->base_sync_ns; - else - min = min_set; - } else { - min = SYNCHRONISATION_GRANULARITY_NS; } - /* Discard excessively long synchronise durations. The MC times - * when it finishes reading the host time so the corrected window - * time should be fairly constant for a given platform. + /* Find the last good host-MC synchronization result. The MC times + * when it finishes reading the host time so the corrected window time + * should be fairly constant for a given platform. */ total = 0; for (i = 0; i < number_readings; i++) @@ -492,8 +471,8 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf, if (ngood == 0) { netif_warn(efx, drv, efx->net_dev, - "PTP no suitable synchronisations %dns %dns\n", - ptp->base_sync_ns, min_set); + "PTP no suitable synchronisations %dns\n", + ptp->base_sync_ns); return -EAGAIN; } -- cgit From 97d48a10c670f87bba9e5b2241e32f2eccd3fef0 Mon Sep 17 00:00:00 2001 From: Alexandre Rames Date: Fri, 11 Jan 2013 12:26:21 +0000 Subject: sfc: Remove rx_alloc_method SKB [bwh: Remove more dead code, and make efx_ptp_rx() pull the data it needs into the header area.] Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 8 +- drivers/net/ethernet/sfc/efx.h | 1 - drivers/net/ethernet/sfc/net_driver.h | 23 +-- drivers/net/ethernet/sfc/ptp.c | 4 +- drivers/net/ethernet/sfc/rx.c | 330 ++++++++++------------------------ 5 files changed, 101 insertions(+), 265 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 0bc00991d310..11a81084bec4 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -247,10 +247,8 @@ static int efx_process_channel(struct efx_channel *channel, int budget) __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = NULL; } - if (rx_queue->enabled) { - efx_rx_strategy(channel); + if (rx_queue->enabled) efx_fast_push_rx_descriptors(rx_queue); - } } return spent; @@ -655,16 +653,12 @@ static void efx_start_datapath(struct efx_nic *efx) efx_for_each_channel_tx_queue(tx_queue, channel) efx_init_tx_queue(tx_queue); - /* The rx buffer allocation strategy is MTU dependent */ - efx_rx_strategy(channel); - efx_for_each_channel_rx_queue(rx_queue, channel) { efx_init_rx_queue(rx_queue); efx_nic_generate_fill_event(rx_queue); } WARN_ON(channel->rx_pkt != NULL); - efx_rx_strategy(channel); } if (netif_device_present(efx->net_dev)) diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index d2f790df6dcb..64c555e493be 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -37,7 +37,6 @@ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); -extern void efx_rx_strategy(struct efx_channel *channel); extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); extern void efx_rx_slow_fill(unsigned long context); extern void __efx_rx_packet(struct efx_channel *channel, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index cdcf510311c3..c83fe090406d 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -206,25 +206,19 @@ struct efx_tx_queue { /** * struct efx_rx_buffer - An Efx RX data buffer * @dma_addr: DMA base address of the buffer - * @skb: The associated socket buffer. Valid iff !(@flags & %EFX_RX_BUF_PAGE). + * @page: The associated page buffer. * Will be %NULL if the buffer slot is currently free. - * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE. - * Will be %NULL if the buffer slot is currently free. - * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE. + * @page_offset: Offset within page * @len: Buffer length, in bytes. * @flags: Flags for buffer and packet state. */ struct efx_rx_buffer { dma_addr_t dma_addr; - union { - struct sk_buff *skb; - struct page *page; - } u; + struct page *page; u16 page_offset; u16 len; u16 flags; }; -#define EFX_RX_BUF_PAGE 0x0001 #define EFX_RX_PKT_CSUMMED 0x0002 #define EFX_RX_PKT_DISCARD 0x0004 @@ -266,8 +260,6 @@ struct efx_rx_page_state { * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. - * @alloc_page_count: RX allocation strategy counter. - * @alloc_skb_count: RX allocation strategy counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). */ struct efx_rx_queue { @@ -286,8 +278,6 @@ struct efx_rx_queue { unsigned int fast_fill_trigger; unsigned int min_fill; unsigned int min_overfill; - unsigned int alloc_page_count; - unsigned int alloc_skb_count; struct timer_list slow_fill; unsigned int slow_fill_count; }; @@ -336,10 +326,6 @@ enum efx_rx_alloc_method { * @event_test_cpu: Last CPU to handle interrupt or test event for this channel * @irq_count: Number of IRQs since last adaptive moderation decision * @irq_mod_score: IRQ moderation score - * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors - * and diagnostic counters - * @rx_alloc_push_pages: RX allocation method currently in use for pushing - * descriptors * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors * @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors * @n_rx_tcp_udp_chksum_err: Count of RX TCP and UDP checksum errors @@ -371,9 +357,6 @@ struct efx_channel { unsigned int rfs_filters_added; #endif - int rx_alloc_level; - int rx_alloc_push_pages; - unsigned n_rx_tobe_disc; unsigned n_rx_ip_hdr_chksum_err; unsigned n_rx_tcp_udp_chksum_err; diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index d1858c0e0827..07f6baa15c0c 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1000,7 +1000,7 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) /* Correct version? */ if (ptp->mode == MC_CMD_PTP_MODE_V1) { - if (skb->len < PTP_V1_MIN_LENGTH) { + if (!pskb_may_pull(skb, PTP_V1_MIN_LENGTH)) { return false; } version = ntohs(*(__be16 *)&skb->data[PTP_V1_VERSION_OFFSET]); @@ -1014,7 +1014,7 @@ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) match_data_012 = skb->data + PTP_V1_UUID_OFFSET; match_data_345 = skb->data + PTP_V1_UUID_OFFSET + 3; } else { - if (skb->len < PTP_V2_MIN_LENGTH) { + if (!pskb_may_pull(skb, PTP_V2_MIN_LENGTH)) { return false; } version = skb->data[PTP_V2_VERSION_OFFSET]; diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index f31c23ea2a07..e7aa28eb9327 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -33,46 +33,6 @@ /* Size of buffer allocated for skb header area. */ #define EFX_SKB_HEADERS 64u -/* - * rx_alloc_method - RX buffer allocation method - * - * This driver supports two methods for allocating and using RX buffers: - * each RX buffer may be backed by an skb or by an order-n page. - * - * When GRO is in use then the second method has a lower overhead, - * since we don't have to allocate then free skbs on reassembled frames. - * - * Values: - * - RX_ALLOC_METHOD_AUTO = 0 - * - RX_ALLOC_METHOD_SKB = 1 - * - RX_ALLOC_METHOD_PAGE = 2 - * - * The heuristic for %RX_ALLOC_METHOD_AUTO is a simple hysteresis count - * controlled by the parameters below. - * - * - Since pushing and popping descriptors are separated by the rx_queue - * size, so the watermarks should be ~rxd_size. - * - The performance win by using page-based allocation for GRO is less - * than the performance hit of using page-based allocation of non-GRO, - * so the watermarks should reflect this. - * - * Per channel we maintain a single variable, updated by each channel: - * - * rx_alloc_level += (gro_performed ? RX_ALLOC_FACTOR_GRO : - * RX_ALLOC_FACTOR_SKB) - * Per NAPI poll interval, we constrain rx_alloc_level to 0..MAX (which - * limits the hysteresis), and update the allocation strategy: - * - * rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_GRO ? - * RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB) - */ -static int rx_alloc_method = RX_ALLOC_METHOD_AUTO; - -#define RX_ALLOC_LEVEL_GRO 0x2000 -#define RX_ALLOC_LEVEL_MAX 0x3000 -#define RX_ALLOC_FACTOR_GRO 1 -#define RX_ALLOC_FACTOR_SKB (-2) - /* This is the percentage fill level below which new RX descriptors * will be added to the RX descriptor ring. */ @@ -99,10 +59,7 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) { - if (buf->flags & EFX_RX_BUF_PAGE) - return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); - else - return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size; + return page_address(buf->page) + efx_rx_buf_offset(efx, buf); } static inline u32 efx_rx_buf_hash(const u8 *eh) @@ -120,56 +77,7 @@ static inline u32 efx_rx_buf_hash(const u8 *eh) } /** - * efx_init_rx_buffers_skb - create EFX_RX_BATCH skb-based RX buffers - * - * @rx_queue: Efx RX queue - * - * This allocates EFX_RX_BATCH skbs, maps them for DMA, and populates a - * struct efx_rx_buffer for each one. Return a negative error code or 0 - * on success. May fail having only inserted fewer than EFX_RX_BATCH - * buffers. - */ -static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) -{ - struct efx_nic *efx = rx_queue->efx; - struct net_device *net_dev = efx->net_dev; - struct efx_rx_buffer *rx_buf; - struct sk_buff *skb; - int skb_len = efx->rx_buffer_len; - unsigned index, count; - - for (count = 0; count < EFX_RX_BATCH; ++count) { - index = rx_queue->added_count & rx_queue->ptr_mask; - rx_buf = efx_rx_buffer(rx_queue, index); - - rx_buf->u.skb = skb = netdev_alloc_skb(net_dev, skb_len); - if (unlikely(!skb)) - return -ENOMEM; - - /* Adjust the SKB for padding */ - skb_reserve(skb, NET_IP_ALIGN); - rx_buf->len = skb_len - NET_IP_ALIGN; - rx_buf->flags = 0; - - rx_buf->dma_addr = dma_map_single(&efx->pci_dev->dev, - skb->data, rx_buf->len, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(&efx->pci_dev->dev, - rx_buf->dma_addr))) { - dev_kfree_skb_any(skb); - rx_buf->u.skb = NULL; - return -EIO; - } - - ++rx_queue->added_count; - ++rx_queue->alloc_skb_count; - } - - return 0; -} - -/** - * efx_init_rx_buffers_page - create EFX_RX_BATCH page-based RX buffers + * efx_init_rx_buffers - create EFX_RX_BATCH page-based RX buffers * * @rx_queue: Efx RX queue * @@ -178,7 +86,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) * code or 0 on success. If a single page can be split between two buffers, * then the page will either be inserted fully, or not at at all. */ -static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) +static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; struct efx_rx_buffer *rx_buf; @@ -214,12 +122,11 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; - rx_buf->u.page = page; + rx_buf->page = page; rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; - rx_buf->flags = EFX_RX_BUF_PAGE; + rx_buf->flags = 0; ++rx_queue->added_count; - ++rx_queue->alloc_page_count; ++state->refcnt; if ((~count & 1) && (efx->rx_buffer_len <= EFX_RX_HALF_PAGE)) { @@ -239,10 +146,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf, unsigned int used_len) { - if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { + if (rx_buf->page) { struct efx_rx_page_state *state; - state = page_address(rx_buf->u.page); + state = page_address(rx_buf->page); if (--state->refcnt == 0) { dma_unmap_page(&efx->pci_dev->dev, state->dma_addr, @@ -253,21 +160,15 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, rx_buf->dma_addr, used_len, DMA_FROM_DEVICE); } - } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { - dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr, - rx_buf->len, DMA_FROM_DEVICE); } } static void efx_free_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { - __free_pages(rx_buf->u.page, efx->rx_buffer_order); - rx_buf->u.page = NULL; - } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { - dev_kfree_skb_any(rx_buf->u.skb); - rx_buf->u.skb = NULL; + if (rx_buf->page) { + __free_pages(rx_buf->page, efx->rx_buffer_order); + rx_buf->page = NULL; } } @@ -283,7 +184,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - struct efx_rx_page_state *state = page_address(rx_buf->u.page); + struct efx_rx_page_state *state = page_address(rx_buf->page); struct efx_rx_buffer *new_buf; unsigned fill_level, index; @@ -298,14 +199,13 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, } ++state->refcnt; - get_page(rx_buf->u.page); + get_page(rx_buf->page); index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); - new_buf->u.page = rx_buf->u.page; + new_buf->page = rx_buf->page; new_buf->len = rx_buf->len; - new_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; } @@ -319,18 +219,17 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *new_buf; unsigned index; - rx_buf->flags &= EFX_RX_BUF_PAGE; + rx_buf->flags = 0; - if ((rx_buf->flags & EFX_RX_BUF_PAGE) && - efx->rx_buffer_len <= EFX_RX_HALF_PAGE && - page_count(rx_buf->u.page) == 1) + if (efx->rx_buffer_len <= EFX_RX_HALF_PAGE && + page_count(rx_buf->page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); memcpy(new_buf, rx_buf, sizeof(*new_buf)); - rx_buf->u.page = NULL; + rx_buf->page = NULL; ++rx_queue->added_count; } @@ -348,7 +247,6 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, */ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) { - struct efx_channel *channel = efx_rx_queue_channel(rx_queue); unsigned fill_level; int space, rc = 0; @@ -369,16 +267,13 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" - " level %d to level %d using %s allocation\n", + " level %d to level %d\n", efx_rx_queue_index(rx_queue), fill_level, - rx_queue->max_fill, - channel->rx_alloc_push_pages ? "page" : "skb"); + rx_queue->max_fill); + do { - if (channel->rx_alloc_push_pages) - rc = efx_init_rx_buffers_page(rx_queue); - else - rc = efx_init_rx_buffers_skb(rx_queue); + rc = efx_init_rx_buffers(rx_queue); if (unlikely(rc)) { /* Ensure that we don't leave the rx queue empty */ if (rx_queue->added_count == rx_queue->removed_count) @@ -408,7 +303,7 @@ void efx_rx_slow_fill(unsigned long context) static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf, - int len, bool *leak_packet) + int len) { struct efx_nic *efx = rx_queue->efx; unsigned max_len = rx_buf->len - efx->type->rx_buffer_padding; @@ -428,11 +323,6 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, "RX event (0x%x > 0x%x+0x%x). Leaking\n", efx_rx_queue_index(rx_queue), len, max_len, efx->type->rx_buffer_padding); - /* If this buffer was skb-allocated, then the meta - * data at the end of the skb will be trashed. So - * we have no choice but to leak the fragment. - */ - *leak_packet = !(rx_buf->flags & EFX_RX_BUF_PAGE); efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY); } else { if (net_ratelimit()) @@ -454,51 +344,78 @@ static void efx_rx_packet_gro(struct efx_channel *channel, { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; + struct efx_nic *efx = channel->efx; + struct page *page = rx_buf->page; + struct sk_buff *skb; - if (rx_buf->flags & EFX_RX_BUF_PAGE) { - struct efx_nic *efx = channel->efx; - struct page *page = rx_buf->u.page; - struct sk_buff *skb; - - rx_buf->u.page = NULL; + rx_buf->page = NULL; - skb = napi_get_frags(napi); - if (!skb) { - put_page(page); - return; - } + skb = napi_get_frags(napi); + if (!skb) { + put_page(page); + return; + } - if (efx->net_dev->features & NETIF_F_RXHASH) - skb->rxhash = efx_rx_buf_hash(eh); + if (efx->net_dev->features & NETIF_F_RXHASH) + skb->rxhash = efx_rx_buf_hash(eh); - skb_fill_page_desc(skb, 0, page, - efx_rx_buf_offset(efx, rx_buf), rx_buf->len); + skb_fill_page_desc(skb, 0, page, + efx_rx_buf_offset(efx, rx_buf), rx_buf->len); - skb->len = rx_buf->len; - skb->data_len = rx_buf->len; - skb->truesize += rx_buf->len; - skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? - CHECKSUM_UNNECESSARY : CHECKSUM_NONE); + skb->len = rx_buf->len; + skb->data_len = rx_buf->len; + skb->truesize += rx_buf->len; + skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE); - skb_record_rx_queue(skb, channel->rx_queue.core_index); + skb_record_rx_queue(skb, channel->rx_queue.core_index); gro_result = napi_gro_frags(napi); - } else { - struct sk_buff *skb = rx_buf->u.skb; - EFX_BUG_ON_PARANOID(!(rx_buf->flags & EFX_RX_PKT_CSUMMED)); - rx_buf->u.skb = NULL; - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (gro_result != GRO_DROP) + channel->irq_mod_score += 2; +} - gro_result = napi_gro_receive(napi, skb); - } +/* Allocate and construct an SKB around a struct page.*/ +static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, + struct efx_rx_buffer *rx_buf, + u8 *eh, int hdr_len) +{ + struct efx_nic *efx = channel->efx; + struct sk_buff *skb; - if (gro_result == GRO_NORMAL) { - channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; - } else if (gro_result != GRO_DROP) { - channel->rx_alloc_level += RX_ALLOC_FACTOR_GRO; - channel->irq_mod_score += 2; + /* Allocate an SKB to store the headers */ + skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN); + if (unlikely(skb == NULL)) + return NULL; + + EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len); + + skb_reserve(skb, EFX_PAGE_SKB_ALIGN); + + skb->len = rx_buf->len; + skb->truesize = rx_buf->len + sizeof(struct sk_buff); + memcpy(skb->data, eh, hdr_len); + skb->tail += hdr_len; + + /* Append the remaining page onto the frag list */ + if (rx_buf->len > hdr_len) { + skb->data_len = skb->len - hdr_len; + skb_fill_page_desc(skb, 0, rx_buf->page, + efx_rx_buf_offset(efx, rx_buf) + hdr_len, + skb->data_len); + } else { + __free_pages(rx_buf->page, efx->rx_buffer_order); + skb->data_len = 0; } + + /* Ownership has transferred from the rx_buf to skb */ + rx_buf->page = NULL; + + /* Move past the ethernet header */ + skb->protocol = eth_type_trans(skb, efx->net_dev); + + return skb; } void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, @@ -507,7 +424,6 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, struct efx_nic *efx = rx_queue->efx; struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_rx_buffer *rx_buf; - bool leak_packet = false; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->flags |= flags; @@ -519,7 +435,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_queue->removed_count++; /* Validate the length encoded in the event vs the descriptor pushed */ - efx_rx_packet__check_len(rx_queue, rx_buf, len, &leak_packet); + efx_rx_packet__check_len(rx_queue, rx_buf, len); netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", @@ -530,10 +446,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, /* Discard packet, if instructed to do so */ if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) { - if (unlikely(leak_packet)) - channel->n_skbuff_leaks++; - else - efx_recycle_rx_buffer(channel, rx_buf); + efx_recycle_rx_buffer(channel, rx_buf); /* Don't hold off the previous receive */ rx_buf = NULL; @@ -560,31 +473,28 @@ out: channel->rx_pkt = rx_buf; } -static void efx_rx_deliver(struct efx_channel *channel, +static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, struct efx_rx_buffer *rx_buf) { struct sk_buff *skb; + u16 hdr_len = min_t(u16, rx_buf->len, EFX_SKB_HEADERS); - /* We now own the SKB */ - skb = rx_buf->u.skb; - rx_buf->u.skb = NULL; + skb = efx_rx_mk_skb(channel, rx_buf, eh, hdr_len); + if (unlikely(skb == NULL)) { + efx_free_rx_buffer(channel->efx, rx_buf); + return; + } + skb_record_rx_queue(skb, channel->rx_queue.core_index); /* Set the SKB flags */ skb_checksum_none_assert(skb); - /* Record the rx_queue */ - skb_record_rx_queue(skb, channel->rx_queue.core_index); - if (channel->type->receive_skb) if (channel->type->receive_skb(channel, skb)) - goto handled; + return; /* Pass the packet up */ netif_receive_skb(skb); - -handled: - /* Update allocation strategy method */ - channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; } /* Handle a received packet. Second half: Touches packet payload. */ @@ -602,60 +512,13 @@ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) return; } - if (!(rx_buf->flags & EFX_RX_BUF_PAGE)) { - struct sk_buff *skb = rx_buf->u.skb; - - prefetch(skb_shinfo(skb)); - - skb_reserve(skb, efx->type->rx_buffer_hash_size); - skb_put(skb, rx_buf->len); - - if (efx->net_dev->features & NETIF_F_RXHASH) - skb->rxhash = efx_rx_buf_hash(eh); - - /* Move past the ethernet header. rx_buf->data still points - * at the ethernet header */ - skb->protocol = eth_type_trans(skb, efx->net_dev); - - skb_record_rx_queue(skb, channel->rx_queue.core_index); - } - if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) rx_buf->flags &= ~EFX_RX_PKT_CSUMMED; - if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED)) && - !channel->type->receive_skb) + if (!channel->type->receive_skb) efx_rx_packet_gro(channel, rx_buf, eh); else - efx_rx_deliver(channel, rx_buf); -} - -void efx_rx_strategy(struct efx_channel *channel) -{ - enum efx_rx_alloc_method method = rx_alloc_method; - - if (channel->type->receive_skb) { - channel->rx_alloc_push_pages = false; - return; - } - - /* Only makes sense to use page based allocation if GRO is enabled */ - if (!(channel->efx->net_dev->features & NETIF_F_GRO)) { - method = RX_ALLOC_METHOD_SKB; - } else if (method == RX_ALLOC_METHOD_AUTO) { - /* Constrain the rx_alloc_level */ - if (channel->rx_alloc_level < 0) - channel->rx_alloc_level = 0; - else if (channel->rx_alloc_level > RX_ALLOC_LEVEL_MAX) - channel->rx_alloc_level = RX_ALLOC_LEVEL_MAX; - - /* Decide on the allocation method */ - method = ((channel->rx_alloc_level > RX_ALLOC_LEVEL_GRO) ? - RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB); - } - - /* Push the option */ - channel->rx_alloc_push_pages = (method == RX_ALLOC_METHOD_PAGE); + efx_rx_deliver(channel, eh, rx_buf); } int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) @@ -756,9 +619,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) } -module_param(rx_alloc_method, int, 0644); -MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers"); - module_param(rx_refill_threshold, uint, 0444); MODULE_PARM_DESC(rx_refill_threshold, "RX descriptor ring refill threshold (%)"); -- cgit From 7de07a4deb8e7707892b952daa59eff67701f0c3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Jan 2013 17:43:15 +0000 Subject: sfc: More sensible semantics for efx_filter_insert_filter() replace flag The 'replace' flag to efx_filter_insert_filter() controls whether the new filter may replace *any* filter, and is checked even before priority comparison. But lower-priority filters should never block insertion of higher-priority filters. Change the priority checking so that lower-priority filters are replaced regardless of the value of the flag, and rename the flag to 'replace_equal'. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 8af42cd1feda..2fdd3a5f21c4 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -650,14 +650,22 @@ u32 efx_filter_get_rx_id_limit(struct efx_nic *efx) * efx_filter_insert_filter - add or replace a filter * @efx: NIC in which to insert the filter * @spec: Specification for the filter - * @replace: Flag for whether the specified filter may replace a filter - * with an identical match expression and equal or lower priority + * @replace_equal: Flag for whether the specified filter may replace an + * existing filter with equal priority * * On success, return the filter ID. * On failure, return a negative error code. + * + * If an existing filter has equal match values to the new filter + * spec, then the new filter might replace it, depending on the + * relative priorities. If the existing filter has lower priority, or + * if @replace_equal is set and it has equal priority, then it is + * replaced. Otherwise the function fails, returning -%EPERM if + * the existing filter has higher priority or -%EEXIST if it has + * equal priority. */ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, - bool replace) + bool replace_equal) { struct efx_filter_state *state = efx->filter_state; struct efx_filter_table *table = efx_filter_spec_table(state, spec); @@ -687,7 +695,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, if (test_bit(filter_idx, table->used_bitmap)) { /* Should we replace the existing filter? */ - if (!replace) { + if (spec->priority == saved_spec->priority && !replace_equal) { rc = -EEXIST; goto out; } -- cgit From e3a699fab34a724fa8693c1274d3ddb3e213a134 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Jan 2013 21:23:14 +0000 Subject: sfc: Remove redundant parameter to efx_filter_search() The 'for_insert' parameter is redundant since there are no longer any other operations that need to search based on a filter spec. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 2fdd3a5f21c4..3d94ed73c65e 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -522,7 +522,7 @@ static bool efx_filter_equal(const struct efx_filter_spec *left, static int efx_filter_search(struct efx_filter_table *table, struct efx_filter_spec *spec, u32 key, - bool for_insert, unsigned int *depth_required) + unsigned int *depth_required) { unsigned hash, incr, filter_idx, depth, depth_max; @@ -531,25 +531,20 @@ static int efx_filter_search(struct efx_filter_table *table, filter_idx = hash & (table->size - 1); depth = 1; - depth_max = (for_insert ? - (spec->priority <= EFX_FILTER_PRI_HINT ? - FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX) : - table->search_depth[spec->type]); + depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ? + FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX); for (;;) { - /* Return success if entry is used and matches this spec - * or entry is unused and we are trying to insert. - */ - if (test_bit(filter_idx, table->used_bitmap) ? - efx_filter_equal(spec, &table->spec[filter_idx]) : - for_insert) { + /* Return success if entry is unused or matches this spec */ + if (!test_bit(filter_idx, table->used_bitmap) || + efx_filter_equal(spec, &table->spec[filter_idx])) { *depth_required = depth; return filter_idx; } /* Return failure if we reached the maximum search depth */ if (depth == depth_max) - return for_insert ? -EBUSY : -ENOENT; + return -EBUSY; filter_idx = (filter_idx + incr) & (table->size - 1); ++depth; @@ -686,7 +681,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, spin_lock_bh(&state->lock); - rc = efx_filter_search(table, spec, key, true, &depth); + rc = efx_filter_search(table, spec, key, &depth); if (rc < 0) goto out; filter_idx = rc; -- cgit From 385904f819e31fcf5a5aa53fa91f3352bffa6d19 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Jan 2013 21:23:15 +0000 Subject: sfc: Don't use efx_filter_{build,hash,increment}() for default MAC filters These functions happen to work for default MAC filters: they generate an initial index of 1/0 for unicast/multicast respectively and an increment of 1 for either, so a search succeeds at depth 2. But this is a matter of luck rather than design, and it really won't work well with the bug fix we're about to do. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 3d94ed73c65e..8d83d9832b21 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -463,13 +463,6 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) break; } - case EFX_FILTER_TABLE_RX_DEF: - /* One filter spec per type */ - BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); - BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != - EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); - return spec->type - EFX_FILTER_UC_DEF; - case EFX_FILTER_TABLE_RX_MAC: { bool is_wild = spec->type == EFX_FILTER_MAC_WILD; EFX_POPULATE_OWORD_7( @@ -667,25 +660,35 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, struct efx_filter_spec *saved_spec; efx_oword_t filter; unsigned int filter_idx, depth = 0; - u32 key; int rc; if (!table || table->size == 0) return -EINVAL; - key = efx_filter_build(&filter, spec); - netif_vdbg(efx, hw, efx->net_dev, "%s: type %d search_depth=%d", __func__, spec->type, table->search_depth[spec->type]); - spin_lock_bh(&state->lock); + if (table->id == EFX_FILTER_TABLE_RX_DEF) { + /* One filter spec per type */ + BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); + BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != + EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); + filter_idx = spec->type - EFX_FILTER_INDEX_UC_DEF; + + spin_lock_bh(&state->lock); + } else { + u32 key = efx_filter_build(&filter, spec); + + spin_lock_bh(&state->lock); + + rc = efx_filter_search(table, spec, key, &depth); + if (rc < 0) + goto out; + filter_idx = rc; + BUG_ON(filter_idx >= table->size); + } - rc = efx_filter_search(table, spec, key, &depth); - if (rc < 0) - goto out; - filter_idx = rc; - BUG_ON(filter_idx >= table->size); saved_spec = &table->spec[filter_idx]; if (test_bit(filter_idx, table->used_bitmap)) { -- cgit From 297891cecc23b85c6b788b0ec6f2f7e71d89003e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Jan 2013 21:23:16 +0000 Subject: sfc: Merge efx_filter_search() into efx_filter_insert() efx_filter_search() is only called from efx_filter_insert(), and neither function is very long. The following bug fix requires a more sophisticated search with a third result, which is going to be easier to implement as part of the same function. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 60 ++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 8d83d9832b21..769560a2cb34 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -513,37 +513,6 @@ static bool efx_filter_equal(const struct efx_filter_spec *left, return true; } -static int efx_filter_search(struct efx_filter_table *table, - struct efx_filter_spec *spec, u32 key, - unsigned int *depth_required) -{ - unsigned hash, incr, filter_idx, depth, depth_max; - - hash = efx_filter_hash(key); - incr = efx_filter_increment(key); - - filter_idx = hash & (table->size - 1); - depth = 1; - depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ? - FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX); - - for (;;) { - /* Return success if entry is unused or matches this spec */ - if (!test_bit(filter_idx, table->used_bitmap) || - efx_filter_equal(spec, &table->spec[filter_idx])) { - *depth_required = depth; - return filter_idx; - } - - /* Return failure if we reached the maximum search depth */ - if (depth == depth_max) - return -EBUSY; - - filter_idx = (filter_idx + incr) & (table->size - 1); - ++depth; - } -} - /* * Construct/deconstruct external filter IDs. At least the RX filter * IDs must be ordered by matching priority, for RX NFC semantics. @@ -679,14 +648,33 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, spin_lock_bh(&state->lock); } else { u32 key = efx_filter_build(&filter, spec); + unsigned int hash = efx_filter_hash(key); + unsigned int incr = efx_filter_increment(key); + unsigned int depth_max = + spec->priority <= EFX_FILTER_PRI_HINT ? + FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX; + + filter_idx = hash & (table->size - 1); + depth = 1; spin_lock_bh(&state->lock); - rc = efx_filter_search(table, spec, key, &depth); - if (rc < 0) - goto out; - filter_idx = rc; - BUG_ON(filter_idx >= table->size); + for (;;) { + if (!test_bit(filter_idx, table->used_bitmap) || + efx_filter_equal(spec, &table->spec[filter_idx])) + break; + + /* Return failure if we reached the maximum search + * depth + */ + if (depth == depth_max) { + rc = -EBUSY; + goto out; + } + + filter_idx = (filter_idx + incr) & (table->size - 1); + ++depth; + } } saved_spec = &table->spec[filter_idx]; -- cgit From d9ccfdd4b3b675750518e035549f5c778d4027f2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 14 Jan 2013 21:23:17 +0000 Subject: sfc: Fix replacement detection in efx_filter_insert_filter() efx_filter_insert_filter() uses the first table entry in the hash chain that either has the same match values or is empty. This means that replacement doesn't always work correctly: 1. Insert filter F1 with match values M1, hashing to H1, at first possible entry E1. 2. Insert filter F2 with match values M2, hashing to H1, at second possible entry E2. 3. Remove filter F1. 4. Insert filter F3 with match values M2, hashing to H1, at first possible entry E1. F3 should have either replaced F2 or been rejected (depending on priority and the replace_equal parameter). Instead, search for both a matching filter that the inserted filter would replace, and an available insertion point, up to the applicable maximum search depths. If we insert at lower depth than a replaced filter, clear the replaced filter. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 89 +++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 769560a2cb34..0de8daf01c01 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -66,6 +66,10 @@ struct efx_filter_state { #endif }; +static void efx_filter_table_clear_entry(struct efx_nic *efx, + struct efx_filter_table *table, + unsigned int filter_idx); + /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit * key derived from the n-tuple. The initial LFSR state is 0xffff. */ static u16 efx_filter_hash(u32 key) @@ -626,9 +630,9 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, { struct efx_filter_state *state = efx->filter_state; struct efx_filter_table *table = efx_filter_spec_table(state, spec); - struct efx_filter_spec *saved_spec; efx_oword_t filter; - unsigned int filter_idx, depth = 0; + int rep_index, ins_index; + unsigned int depth = 0; int rc; if (!table || table->size == 0) @@ -643,44 +647,74 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); - filter_idx = spec->type - EFX_FILTER_INDEX_UC_DEF; + rep_index = spec->type - EFX_FILTER_INDEX_UC_DEF; + ins_index = rep_index; spin_lock_bh(&state->lock); } else { + /* Search concurrently for + * (1) a filter to be replaced (rep_index): any filter + * with the same match values, up to the current + * search depth for this type, and + * (2) the insertion point (ins_index): (1) or any + * free slot before it or up to the maximum search + * depth for this priority + * We fail if we cannot find (2). + * + * We can stop once either + * (a) we find (1), in which case we have definitely + * found (2) as well; or + * (b) we have searched exhaustively for (1), and have + * either found (2) or searched exhaustively for it + */ u32 key = efx_filter_build(&filter, spec); unsigned int hash = efx_filter_hash(key); unsigned int incr = efx_filter_increment(key); - unsigned int depth_max = + unsigned int max_rep_depth = table->search_depth[spec->type]; + unsigned int max_ins_depth = spec->priority <= EFX_FILTER_PRI_HINT ? FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX; + unsigned int i = hash & (table->size - 1); - filter_idx = hash & (table->size - 1); + ins_index = -1; depth = 1; spin_lock_bh(&state->lock); for (;;) { - if (!test_bit(filter_idx, table->used_bitmap) || - efx_filter_equal(spec, &table->spec[filter_idx])) + if (!test_bit(i, table->used_bitmap)) { + if (ins_index < 0) + ins_index = i; + } else if (efx_filter_equal(spec, &table->spec[i])) { + /* Case (a) */ + if (ins_index < 0) + ins_index = i; + rep_index = i; break; + } - /* Return failure if we reached the maximum search - * depth - */ - if (depth == depth_max) { - rc = -EBUSY; - goto out; + if (depth >= max_rep_depth && + (ins_index >= 0 || depth >= max_ins_depth)) { + /* Case (b) */ + if (ins_index < 0) { + rc = -EBUSY; + goto out; + } + rep_index = -1; + break; } - filter_idx = (filter_idx + incr) & (table->size - 1); + i = (i + incr) & (table->size - 1); ++depth; } } - saved_spec = &table->spec[filter_idx]; + /* If we found a filter to be replaced, check whether we + * should do so + */ + if (rep_index >= 0) { + struct efx_filter_spec *saved_spec = &table->spec[rep_index]; - if (test_bit(filter_idx, table->used_bitmap)) { - /* Should we replace the existing filter? */ if (spec->priority == saved_spec->priority && !replace_equal) { rc = -EEXIST; goto out; @@ -689,11 +723,14 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, rc = -EPERM; goto out; } - } else { - __set_bit(filter_idx, table->used_bitmap); + } + + /* Insert the filter */ + if (ins_index != rep_index) { + __set_bit(ins_index, table->used_bitmap); ++table->used; } - *saved_spec = *spec; + table->spec[ins_index] = *spec; if (table->id == EFX_FILTER_TABLE_RX_DEF) { efx_filter_push_rx_config(efx); @@ -707,13 +744,19 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, } efx_writeo(efx, &filter, - table->offset + table->step * filter_idx); + table->offset + table->step * ins_index); + + /* If we were able to replace a filter by inserting + * at a lower depth, clear the replaced filter + */ + if (ins_index != rep_index && rep_index >= 0) + efx_filter_table_clear_entry(efx, table, rep_index); } netif_vdbg(efx, hw, efx->net_dev, "%s: filter type %d index %d rxq %u set", - __func__, spec->type, filter_idx, spec->dmaq_id); - rc = efx_filter_make_id(spec, filter_idx); + __func__, spec->type, ins_index, spec->dmaq_id); + rc = efx_filter_make_id(spec, ins_index); out: spin_unlock_bh(&state->lock); -- cgit From 634ab72c39b3df78ac7d6ccd4a50133059bae14f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 6 Mar 2013 19:39:20 +0000 Subject: sfc: Disable RSS when using SR-IOV and only 1 RX queue on the PF On Siena, VFs share RSS configuration with the PF. We attempted to support configurations where the PF only uses 1 RX queue and VFs use multiple RX queues, by (1) setting up RSS for the number of RX queues per VF (2) disabling RSS in the PF's RX default filters. Unfortunately commit cd2d5b529cdb ('sfc: Add SR-IOV back-end support for SFC9000 family') only included (1). This is (2). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/filter.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 0de8daf01c01..61b4408bbdb8 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -414,8 +414,12 @@ static void efx_filter_reset_rx_def(struct efx_nic *efx, unsigned filter_idx) struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_DEF]; struct efx_filter_spec *spec = &table->spec[filter_idx]; + /* If there's only one channel then disable RSS for non VF + * traffic, thereby allowing VFs to use RSS when the PF can't. + */ efx_filter_init_rx(spec, EFX_FILTER_PRI_MANUAL, - EFX_FILTER_FLAG_RX_RSS, 0); + efx->n_rx_channels > 1 ? EFX_FILTER_FLAG_RX_RSS : 0, + 0); spec->type = EFX_FILTER_UC_DEF + filter_idx; table->used_bitmap[0] |= 1 << filter_idx; } -- cgit From 626950db84c065925ee10c2e833da265cbda8800 Mon Sep 17 00:00:00 2001 From: Alexandre Rames Date: Mon, 14 Jan 2013 17:20:22 +0000 Subject: sfc: Add AER and EEH support for Siena The Linux side of EEH is triggered by MMIO reads, but this driver's data path does not issue any MMIO reads (except in legacy interrupt mode). Therefore add a monitor function to poll EEH periodically. When preparing to reset the device based on our own error detection, also poll EEH and defer to its recovery mechanism if appropriate. [bwh: Use a separate condition for the initial link poll; fix some style errors] Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 207 ++++++++++++++++++++++++++++++---- drivers/net/ethernet/sfc/enum.h | 12 +- drivers/net/ethernet/sfc/net_driver.h | 1 + drivers/net/ethernet/sfc/siena.c | 22 +++- 4 files changed, 216 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 11a81084bec4..5e1ddc559b4f 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include "net_driver.h" #include "efx.h" #include "nic.h" @@ -71,17 +73,19 @@ const char *const efx_loopback_mode_names[] = { const unsigned int efx_reset_type_max = RESET_TYPE_MAX; const char *const efx_reset_type_names[] = { - [RESET_TYPE_INVISIBLE] = "INVISIBLE", - [RESET_TYPE_ALL] = "ALL", - [RESET_TYPE_WORLD] = "WORLD", - [RESET_TYPE_DISABLE] = "DISABLE", - [RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG", - [RESET_TYPE_INT_ERROR] = "INT_ERROR", - [RESET_TYPE_RX_RECOVERY] = "RX_RECOVERY", - [RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH", - [RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH", - [RESET_TYPE_TX_SKIP] = "TX_SKIP", - [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", + [RESET_TYPE_INVISIBLE] = "INVISIBLE", + [RESET_TYPE_ALL] = "ALL", + [RESET_TYPE_RECOVER_OR_ALL] = "RECOVER_OR_ALL", + [RESET_TYPE_WORLD] = "WORLD", + [RESET_TYPE_RECOVER_OR_DISABLE] = "RECOVER_OR_DISABLE", + [RESET_TYPE_DISABLE] = "DISABLE", + [RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG", + [RESET_TYPE_INT_ERROR] = "INT_ERROR", + [RESET_TYPE_RX_RECOVERY] = "RX_RECOVERY", + [RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH", + [RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH", + [RESET_TYPE_TX_SKIP] = "TX_SKIP", + [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", }; #define EFX_MAX_MTU (9 * 1024) @@ -117,9 +121,12 @@ MODULE_PARM_DESC(separate_tx_channels, static int napi_weight = 64; /* This is the time (in jiffies) between invocations of the hardware - * monitor. On Falcon-based NICs, this will: + * monitor. + * On Falcon-based NICs, this will: * - Check the on-board hardware monitor; * - Poll the link state and reconfigure the hardware as necessary. + * On Siena-based NICs for power systems with EEH support, this will give EEH a + * chance to start. */ static unsigned int efx_monitor_interval = 1 * HZ; @@ -203,13 +210,14 @@ static void efx_stop_all(struct efx_nic *efx); #define EFX_ASSERT_RESET_SERIALISED(efx) \ do { \ if ((efx->state == STATE_READY) || \ + (efx->state == STATE_RECOVERY) || \ (efx->state == STATE_DISABLED)) \ ASSERT_RTNL(); \ } while (0) static int efx_check_disabled(struct efx_nic *efx) { - if (efx->state == STATE_DISABLED) { + if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) { netif_err(efx, drv, efx->net_dev, "device is disabled due to earlier errors\n"); return -EIO; @@ -677,7 +685,7 @@ static void efx_stop_datapath(struct efx_nic *efx) BUG_ON(efx->port_enabled); /* Only perform flush if dma is enabled */ - if (dev->is_busmaster) { + if (dev->is_busmaster && efx->state != STATE_RECOVERY) { rc = efx_nic_flush_queues(efx); if (rc && EFX_WORKAROUND_7803(efx)) { @@ -1590,13 +1598,15 @@ static void efx_start_all(struct efx_nic *efx) efx_start_port(efx); efx_start_datapath(efx); - /* Start the hardware monitor if there is one. Otherwise (we're link - * event driven), we have to poll the PHY because after an event queue - * flush, we could have a missed a link state change */ - if (efx->type->monitor != NULL) { + /* Start the hardware monitor if there is one */ + if (efx->type->monitor != NULL) queue_delayed_work(efx->workqueue, &efx->monitor_work, efx_monitor_interval); - } else { + + /* If link state detection is normally event-driven, we have + * to poll now because we could have missed a change + */ + if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) { mutex_lock(&efx->mac_lock); if (efx->phy_op->poll(efx)) efx_link_status_changed(efx); @@ -2303,7 +2313,9 @@ int efx_reset(struct efx_nic *efx, enum reset_type method) out: /* Leave device stopped if necessary */ - disabled = rc || method == RESET_TYPE_DISABLE; + disabled = rc || + method == RESET_TYPE_DISABLE || + method == RESET_TYPE_RECOVER_OR_DISABLE; rc2 = efx_reset_up(efx, method, !disabled); if (rc2) { disabled = true; @@ -2322,13 +2334,48 @@ out: return rc; } +/* Try recovery mechanisms. + * For now only EEH is supported. + * Returns 0 if the recovery mechanisms are unsuccessful. + * Returns a non-zero value otherwise. + */ +static int efx_try_recovery(struct efx_nic *efx) +{ +#ifdef CONFIG_EEH + /* A PCI error can occur and not be seen by EEH because nothing + * happens on the PCI bus. In this case the driver may fail and + * schedule a 'recover or reset', leading to this recovery handler. + * Manually call the eeh failure check function. + */ + struct eeh_dev *eehdev = + of_node_to_eeh_dev(pci_device_to_OF_node(efx->pci_dev)); + + if (eeh_dev_check_failure(eehdev)) { + /* The EEH mechanisms will handle the error and reset the + * device if necessary. + */ + return 1; + } +#endif + return 0; +} + /* The worker thread exists so that code that cannot sleep can * schedule a reset for later. */ static void efx_reset_work(struct work_struct *data) { struct efx_nic *efx = container_of(data, struct efx_nic, reset_work); - unsigned long pending = ACCESS_ONCE(efx->reset_pending); + unsigned long pending; + enum reset_type method; + + pending = ACCESS_ONCE(efx->reset_pending); + method = fls(pending) - 1; + + if ((method == RESET_TYPE_RECOVER_OR_DISABLE || + method == RESET_TYPE_RECOVER_OR_ALL) && + efx_try_recovery(efx)) + return; if (!pending) return; @@ -2340,7 +2387,7 @@ static void efx_reset_work(struct work_struct *data) * it cannot change again. */ if (efx->state == STATE_READY) - (void)efx_reset(efx, fls(pending) - 1); + (void)efx_reset(efx, method); rtnl_unlock(); } @@ -2349,11 +2396,20 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) { enum reset_type method; + if (efx->state == STATE_RECOVERY) { + netif_dbg(efx, drv, efx->net_dev, + "recovering: skip scheduling %s reset\n", + RESET_TYPE(type)); + return; + } + switch (type) { case RESET_TYPE_INVISIBLE: case RESET_TYPE_ALL: + case RESET_TYPE_RECOVER_OR_ALL: case RESET_TYPE_WORLD: case RESET_TYPE_DISABLE: + case RESET_TYPE_RECOVER_OR_DISABLE: method = type; netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", RESET_TYPE(method)); @@ -2563,6 +2619,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev) efx_fini_struct(efx); pci_set_drvdata(pci_dev, NULL); free_netdev(efx->net_dev); + + pci_disable_pcie_error_reporting(pci_dev); }; /* NIC VPD information @@ -2735,6 +2793,11 @@ static int efx_pci_probe(struct pci_dev *pci_dev, netif_warn(efx, probe, efx->net_dev, "failed to create MTDs (%d)\n", rc); + rc = pci_enable_pcie_error_reporting(pci_dev); + if (rc && rc != -EINVAL) + netif_warn(efx, probe, efx->net_dev, + "pci_enable_pcie_error_reporting failed (%d)\n", rc); + return 0; fail4: @@ -2859,12 +2922,112 @@ static const struct dev_pm_ops efx_pm_ops = { .restore = efx_pm_resume, }; +/* A PCI error affecting this device was detected. + * At this point MMIO and DMA may be disabled. + * Stop the software path and request a slot reset. + */ +pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, + enum pci_channel_state state) +{ + pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + struct efx_nic *efx = pci_get_drvdata(pdev); + + if (state == pci_channel_io_perm_failure) + return PCI_ERS_RESULT_DISCONNECT; + + rtnl_lock(); + + if (efx->state != STATE_DISABLED) { + efx->state = STATE_RECOVERY; + efx->reset_pending = 0; + + efx_device_detach_sync(efx); + + efx_stop_all(efx); + efx_stop_interrupts(efx, false); + + status = PCI_ERS_RESULT_NEED_RESET; + } else { + /* If the interface is disabled we don't want to do anything + * with it. + */ + status = PCI_ERS_RESULT_RECOVERED; + } + + rtnl_unlock(); + + pci_disable_device(pdev); + + return status; +} + +/* Fake a successfull reset, which will be performed later in efx_io_resume. */ +pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev) +{ + struct efx_nic *efx = pci_get_drvdata(pdev); + pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + int rc; + + if (pci_enable_device(pdev)) { + netif_err(efx, hw, efx->net_dev, + "Cannot re-enable PCI device after reset.\n"); + status = PCI_ERS_RESULT_DISCONNECT; + } + + rc = pci_cleanup_aer_uncorrect_error_status(pdev); + if (rc) { + netif_err(efx, hw, efx->net_dev, + "pci_cleanup_aer_uncorrect_error_status failed (%d)\n", rc); + /* Non-fatal error. Continue. */ + } + + return status; +} + +/* Perform the actual reset and resume I/O operations. */ +static void efx_io_resume(struct pci_dev *pdev) +{ + struct efx_nic *efx = pci_get_drvdata(pdev); + int rc; + + rtnl_lock(); + + if (efx->state == STATE_DISABLED) + goto out; + + rc = efx_reset(efx, RESET_TYPE_ALL); + if (rc) { + netif_err(efx, hw, efx->net_dev, + "efx_reset failed after PCI error (%d)\n", rc); + } else { + efx->state = STATE_READY; + netif_dbg(efx, hw, efx->net_dev, + "Done resetting and resuming IO after PCI error.\n"); + } + +out: + rtnl_unlock(); +} + +/* For simplicity and reliability, we always require a slot reset and try to + * reset the hardware when a pci error affecting the device is detected. + * We leave both the link_reset and mmio_enabled callback unimplemented: + * with our request for slot reset the mmio_enabled callback will never be + * called, and the link_reset callback is not used by AER or EEH mechanisms. + */ +static struct pci_error_handlers efx_err_handlers = { + .error_detected = efx_io_error_detected, + .slot_reset = efx_io_slot_reset, + .resume = efx_io_resume, +}; + static struct pci_driver efx_pci_driver = { .name = KBUILD_MODNAME, .id_table = efx_pci_table, .probe = efx_pci_probe, .remove = efx_pci_remove, .driver.pm = &efx_pm_ops, + .err_handler = &efx_err_handlers, }; /************************************************************************** diff --git a/drivers/net/ethernet/sfc/enum.h b/drivers/net/ethernet/sfc/enum.h index 182dbe2cc6e4..ab8fb5889e55 100644 --- a/drivers/net/ethernet/sfc/enum.h +++ b/drivers/net/ethernet/sfc/enum.h @@ -137,8 +137,12 @@ enum efx_loopback_mode { * Reset methods are numbered in order of increasing scope. * * @RESET_TYPE_INVISIBLE: Reset datapath and MAC (Falcon only) + * @RESET_TYPE_RECOVER_OR_ALL: Try to recover. Apply RESET_TYPE_ALL + * if unsuccessful. * @RESET_TYPE_ALL: Reset datapath, MAC and PHY * @RESET_TYPE_WORLD: Reset as much as possible + * @RESET_TYPE_RECOVER_OR_DISABLE: Try to recover. Apply RESET_TYPE_DISABLE if + * unsuccessful. * @RESET_TYPE_DISABLE: Reset datapath, MAC and PHY; leave NIC disabled * @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog * @RESET_TYPE_INT_ERROR: reset due to internal error @@ -150,9 +154,11 @@ enum efx_loopback_mode { */ enum reset_type { RESET_TYPE_INVISIBLE = 0, - RESET_TYPE_ALL = 1, - RESET_TYPE_WORLD = 2, - RESET_TYPE_DISABLE = 3, + RESET_TYPE_RECOVER_OR_ALL = 1, + RESET_TYPE_ALL = 2, + RESET_TYPE_WORLD = 3, + RESET_TYPE_RECOVER_OR_DISABLE = 4, + RESET_TYPE_DISABLE = 5, RESET_TYPE_MAX_METHOD, RESET_TYPE_TX_WATCHDOG, RESET_TYPE_INT_ERROR, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c83fe090406d..9e900817d2ab 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -429,6 +429,7 @@ enum nic_state { STATE_UNINIT = 0, /* device being probed/removed or is frozen */ STATE_READY = 1, /* hardware ready and netdev registered */ STATE_DISABLED = 2, /* device disabled due to hardware errors */ + STATE_RECOVERY = 3, /* device recovering from PCI error */ }; /* diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index ba40f67e4f05..e07ff0d3f26b 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -202,7 +202,7 @@ out: static enum reset_type siena_map_reset_reason(enum reset_type reason) { - return RESET_TYPE_ALL; + return RESET_TYPE_RECOVER_OR_ALL; } static int siena_map_reset_flags(u32 *flags) @@ -245,6 +245,22 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) return efx_mcdi_reset_port(efx); } +#ifdef CONFIG_EEH +/* When a PCI device is isolated from the bus, a subsequent MMIO read is + * required for the kernel EEH mechanisms to notice. As the Solarflare driver + * was written to minimise MMIO read (for latency) then a periodic call to check + * the EEH status of the device is required so that device recovery can happen + * in a timely fashion. + */ +static void siena_monitor(struct efx_nic *efx) +{ + struct eeh_dev *eehdev = + of_node_to_eeh_dev(pci_device_to_OF_node(efx->pci_dev)); + + eeh_dev_check_failure(eehdev); +} +#endif + static int siena_probe_nvconfig(struct efx_nic *efx) { u32 caps = 0; @@ -665,7 +681,11 @@ const struct efx_nic_type siena_a0_nic_type = { .init = siena_init_nic, .dimension_resources = siena_dimension_resources, .fini = efx_port_dummy_op_void, +#ifdef CONFIG_EEH + .monitor = siena_monitor, +#else .monitor = NULL, +#endif .map_reset_reason = siena_map_reset_reason, .map_reset_flags = siena_map_reset_flags, .reset = siena_reset_hw, -- cgit From 80c2e716d555912168f93853f96a24d0de75897b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Jan 2013 21:52:13 +0000 Subject: sfc: Document current usage of efx_rx_buffer::len and efx_nic::rx_buffer_len Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 9e900817d2ab..f74411fc000c 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -209,7 +209,8 @@ struct efx_tx_queue { * @page: The associated page buffer. * Will be %NULL if the buffer slot is currently free. * @page_offset: Offset within page - * @len: Buffer length, in bytes. + * @len: If pending: length for DMA descriptor. + * If completed: received length, excluding hash prefix. * @flags: Flags for buffer and packet state. */ struct efx_rx_buffer { @@ -668,7 +669,8 @@ struct vfdi_status; * @n_channels: Number of channels in use * @n_rx_channels: Number of channels used for RX (= number of RX queues) * @n_tx_channels: Number of channels used for TX - * @rx_buffer_len: RX buffer length + * @rx_buffer_len: RX buffer length, including start alignment but excluding + * any metadata * @rx_buffer_order: Order (log2) of number of pages for each RX buffer * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS -- cgit From 272baeeb6a98f5f746c2eeab4973c2df89e9d7ea Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:14 +0000 Subject: sfc: Properly distinguish RX buffer and DMA lengths Replace efx_nic::rx_buffer_len with efx_nic::rx_dma_len, the maximum RX DMA length. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 11 +++++------ drivers/net/ethernet/sfc/net_driver.h | 5 ++--- drivers/net/ethernet/sfc/rx.c | 19 ++++++++----------- 3 files changed, 15 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 5e1ddc559b4f..34b56ec87fba 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -639,12 +639,11 @@ static void efx_start_datapath(struct efx_nic *efx) * support the current MTU, including padding for header * alignment and overruns. */ - efx->rx_buffer_len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + - EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + - efx->type->rx_buffer_hash_size + - efx->type->rx_buffer_padding); - efx->rx_buffer_order = get_order(efx->rx_buffer_len + - sizeof(struct efx_rx_page_state)); + efx->rx_dma_len = (efx->type->rx_buffer_hash_size + + EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + + efx->type->rx_buffer_padding); + efx->rx_buffer_order = get_order(sizeof(struct efx_rx_page_state) + + EFX_PAGE_IP_ALIGN + efx->rx_dma_len); /* We must keep at least one descriptor in a TX ring empty. * We could avoid this when the queue size does not exactly diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index f74411fc000c..fc6770e07d5a 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -669,8 +669,7 @@ struct vfdi_status; * @n_channels: Number of channels in use * @n_rx_channels: Number of channels used for RX (= number of RX queues) * @n_tx_channels: Number of channels used for TX - * @rx_buffer_len: RX buffer length, including start alignment but excluding - * any metadata + * @rx_dma_len: Current maximum RX DMA length * @rx_buffer_order: Order (log2) of number of pages for each RX buffer * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS @@ -786,7 +785,7 @@ struct efx_nic { unsigned rss_spread; unsigned tx_channel_offset; unsigned n_tx_channels; - unsigned int rx_buffer_len; + unsigned int rx_dma_len; unsigned int rx_buffer_order; u8 rx_hash_key[40]; u32 rx_indir_table[128]; diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index e7aa28eb9327..31361db28f91 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -27,8 +27,9 @@ /* Number of RX descriptors pushed at once. */ #define EFX_RX_BATCH 8 -/* Maximum size of a buffer sharing a page */ -#define EFX_RX_HALF_PAGE ((PAGE_SIZE >> 1) - sizeof(struct efx_rx_page_state)) +/* Maximum length for an RX descriptor sharing a page */ +#define EFX_RX_HALF_PAGE ((PAGE_SIZE >> 1) - sizeof(struct efx_rx_page_state) \ + - EFX_PAGE_IP_ALIGN) /* Size of buffer allocated for skb header area. */ #define EFX_SKB_HEADERS 64u @@ -52,10 +53,6 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, { return buf->page_offset + efx->type->rx_buffer_hash_size; } -static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) -{ - return PAGE_SIZE << efx->rx_buffer_order; -} static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) { @@ -105,7 +102,7 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) if (unlikely(page == NULL)) return -ENOMEM; dma_addr = dma_map_page(&efx->pci_dev->dev, page, 0, - efx_rx_buf_size(efx), + PAGE_SIZE << efx->rx_buffer_order, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(&efx->pci_dev->dev, dma_addr))) { __free_pages(page, efx->rx_buffer_order); @@ -124,12 +121,12 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->page = page; rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; - rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; + rx_buf->len = efx->rx_dma_len; rx_buf->flags = 0; ++rx_queue->added_count; ++state->refcnt; - if ((~count & 1) && (efx->rx_buffer_len <= EFX_RX_HALF_PAGE)) { + if ((~count & 1) && (efx->rx_dma_len <= EFX_RX_HALF_PAGE)) { /* Use the second half of the page */ get_page(page); dma_addr += (PAGE_SIZE >> 1); @@ -153,7 +150,7 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, if (--state->refcnt == 0) { dma_unmap_page(&efx->pci_dev->dev, state->dma_addr, - efx_rx_buf_size(efx), + PAGE_SIZE << efx->rx_buffer_order, DMA_FROM_DEVICE); } else if (used_len) { dma_sync_single_for_cpu(&efx->pci_dev->dev, @@ -221,7 +218,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, rx_buf->flags = 0; - if (efx->rx_buffer_len <= EFX_RX_HALF_PAGE && + if (efx->rx_dma_len <= EFX_RX_HALF_PAGE && page_count(rx_buf->page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); -- cgit From 9bc2fc9b5272cc888fb10d5839f7188fa0bfdc90 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:14 +0000 Subject: sfc: Make RX queue descriptor counts unsigned for consistency Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index fc6770e07d5a..3fd6dbe5e3dd 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -272,9 +272,9 @@ struct efx_rx_queue { bool enabled; bool flush_pending; - int added_count; - int notified_count; - int removed_count; + unsigned int added_count; + unsigned int notified_count; + unsigned int removed_count; unsigned int max_fill; unsigned int fast_fill_trigger; unsigned int min_fill; -- cgit From ff734ef4bca05fd5cd51b83d2e2a9f008b64f9a3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:14 +0000 Subject: sfc: Wrap __efx_rx_packet() with efx_rx_flush_packet() The pipeline mechanism will need to change a bit for scattered packets. Add a wrapper to insulate efx_process_channel() from this. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 +----- drivers/net/ethernet/sfc/efx.h | 7 +++++++ drivers/net/ethernet/sfc/rx.c | 3 +-- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 34b56ec87fba..f8013c3ea37c 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -250,11 +250,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); - /* Deliver last RX packet. */ - if (channel->rx_pkt) { - __efx_rx_packet(channel, channel->rx_pkt); - channel->rx_pkt = NULL; - } + efx_rx_flush_packet(channel); if (rx_queue->enabled) efx_fast_push_rx_descriptors(rx_queue); } diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 64c555e493be..00e7077fa1d8 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -43,6 +43,13 @@ extern void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf); extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, u16 flags); +static inline void efx_rx_flush_packet(struct efx_channel *channel) +{ + if (channel->rx_pkt) { + __efx_rx_packet(channel, channel->rx_pkt); + channel->rx_pkt = NULL; + } +} extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_DMAQ_SIZE 4096UL diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 31361db28f91..60f4eb7cebc6 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -465,8 +465,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ rx_buf->len = len - efx->type->rx_buffer_hash_size; out: - if (channel->rx_pkt) - __efx_rx_packet(channel, channel->rx_pkt); + efx_rx_flush_packet(channel); channel->rx_pkt = rx_buf; } -- cgit From b184f16b7feb9ede7d658ee6f2c77434d580d764 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:15 +0000 Subject: sfc: Replace efx_rx_buf_eh() with simpler efx_rx_buf_va() efx_rx_buf_va() returns the virtual address of the current start of the buffer. The callers must add the hash prefix size themselves. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 60f4eb7cebc6..23d67d1f136f 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -54,9 +54,9 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, return buf->page_offset + efx->type->rx_buffer_hash_size; } -static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) +static inline u8 *efx_rx_buf_va(struct efx_rx_buffer *buf) { - return page_address(buf->page) + efx_rx_buf_offset(efx, buf); + return page_address(buf->page) + buf->page_offset; } static inline u32 efx_rx_buf_hash(const u8 *eh) @@ -458,7 +458,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. */ - prefetch(efx_rx_buf_eh(efx, rx_buf)); + prefetch(efx_rx_buf_va(rx_buf) + efx->type->rx_buffer_hash_size); /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. @@ -497,7 +497,7 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; - u8 *eh = efx_rx_buf_eh(efx, rx_buf); + u8 *eh = efx_rx_buf_va(rx_buf) + efx->type->rx_buffer_hash_size; /* If we're in loopback test, then pass the packet directly to the * loopback layer, and free the rx_buf here -- cgit From 5036b7c7b9137bd084f28438396432348f20e0bc Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:15 +0000 Subject: sfc: Explicitly prefetch RX hash prefix, not just Ethernet heade Currently we prefetch from the Ethernet header, but we will also read the hash prefix. In practice they should be in the same cache line and this won't hurt, but it is still pointless to add on the hash prefix size. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 23d67d1f136f..8e78a2fe7364 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -458,7 +458,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. */ - prefetch(efx_rx_buf_va(rx_buf) + efx->type->rx_buffer_hash_size); + prefetch(efx_rx_buf_va(rx_buf)); /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. -- cgit From b74e3e8cd6f952faf8797fca81a5a2ceace6b9aa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:15 +0000 Subject: sfc: Update RX buffer address together with length Adjust rx_buf->page_offset when we eat the RX hash prefix. Remove efx_rx_buf_offset(), which is now redundant. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 3 ++- drivers/net/ethernet/sfc/rx.c | 18 ++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 3fd6dbe5e3dd..1bc911f980b5 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -208,7 +208,8 @@ struct efx_tx_queue { * @dma_addr: DMA base address of the buffer * @page: The associated page buffer. * Will be %NULL if the buffer slot is currently free. - * @page_offset: Offset within page + * @page_offset: If pending: offset in @page of DMA base address. + * If completed: offset in @page of Ethernet header. * @len: If pending: length for DMA descriptor. * If completed: received length, excluding hash prefix. * @flags: Flags for buffer and packet state. diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 8e78a2fe7364..04518722ac1d 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -47,13 +47,6 @@ static unsigned int rx_refill_threshold; */ #define EFX_RXD_HEAD_ROOM 2 -/* Offset of ethernet header within page */ -static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, - struct efx_rx_buffer *buf) -{ - return buf->page_offset + efx->type->rx_buffer_hash_size; -} - static inline u8 *efx_rx_buf_va(struct efx_rx_buffer *buf) { return page_address(buf->page) + buf->page_offset; @@ -356,8 +349,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, if (efx->net_dev->features & NETIF_F_RXHASH) skb->rxhash = efx_rx_buf_hash(eh); - skb_fill_page_desc(skb, 0, page, - efx_rx_buf_offset(efx, rx_buf), rx_buf->len); + skb_fill_page_desc(skb, 0, page, rx_buf->page_offset, rx_buf->len); skb->len = rx_buf->len; skb->data_len = rx_buf->len; @@ -399,7 +391,7 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, if (rx_buf->len > hdr_len) { skb->data_len = skb->len - hdr_len; skb_fill_page_desc(skb, 0, rx_buf->page, - efx_rx_buf_offset(efx, rx_buf) + hdr_len, + rx_buf->page_offset + hdr_len, skb->data_len); } else { __free_pages(rx_buf->page, efx->rx_buffer_order); @@ -460,10 +452,12 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ prefetch(efx_rx_buf_va(rx_buf)); + rx_buf->page_offset += efx->type->rx_buffer_hash_size; + rx_buf->len = len - efx->type->rx_buffer_hash_size; + /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. */ - rx_buf->len = len - efx->type->rx_buffer_hash_size; out: efx_rx_flush_packet(channel); channel->rx_pkt = rx_buf; @@ -497,7 +491,7 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; - u8 *eh = efx_rx_buf_va(rx_buf) + efx->type->rx_buffer_hash_size; + u8 *eh = efx_rx_buf_va(rx_buf); /* If we're in loopback test, then pass the packet directly to the * loopback layer, and free the rx_buf here -- cgit From 85740cdf0b84224a9fce62dc9150008ef8d6ab4e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 29 Jan 2013 23:33:15 +0000 Subject: sfc: Enable RX DMA scattering where possible Enable RX DMA scattering iff an RX buffer large enough for the current MTU will not fit into a single page and the NIC supports DMA scattering for kernel-mode RX queues. On Falcon and Siena, the RX_USR_BUF_SIZE field is used as the DMA limit for both all RX queues with scatter enabled. Set it to 1824, matching what Onload uses now. Maintain a statistic for frames truncated due to lack of descriptors (rx_nodesc_trunc). This is distinct from rx_frm_trunc which may be incremented when scattering is disabled and implies an over-length frame. Whenever an MTU change causes scattering to be turned on or off, update filters that point to the PF queues, but leave others unchanged, as VF drivers assume scattering is off. Add n_frags parameters to various functions, and make them iterate: - efx_rx_packet() - efx_recycle_rx_buffers() - efx_rx_mk_skb() - efx_rx_deliver() Make efx_handle_rx_event() responsible for updating efx_rx_queue::removed_count. Change the RX pipeline state to a starting ring index and number of fragments, and make __efx_rx_packet() responsible for clearing it. Based on earlier versions by David Riddoch and Jon Cooper. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 34 +++++- drivers/net/ethernet/sfc/efx.h | 13 +-- drivers/net/ethernet/sfc/ethtool.c | 4 +- drivers/net/ethernet/sfc/falcon.c | 17 +-- drivers/net/ethernet/sfc/filter.c | 74 +++++++++++- drivers/net/ethernet/sfc/net_driver.h | 35 ++++-- drivers/net/ethernet/sfc/nic.c | 90 ++++++++++++--- drivers/net/ethernet/sfc/rx.c | 211 ++++++++++++++++++++++------------ drivers/net/ethernet/sfc/siena.c | 3 + 9 files changed, 363 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index f8013c3ea37c..1213af5024d1 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -88,8 +88,6 @@ const char *const efx_reset_type_names[] = { [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", }; -#define EFX_MAX_MTU (9 * 1024) - /* Reset workqueue. If any NIC has a hardware failure then a reset will be * queued onto this work queue. This is not a per-nic work queue, because * efx_reset_work() acquires the rtnl lock, so resets are naturally serialised. @@ -627,9 +625,11 @@ fail: */ static void efx_start_datapath(struct efx_nic *efx) { + bool old_rx_scatter = efx->rx_scatter; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; struct efx_channel *channel; + size_t rx_buf_len; /* Calculate the rx buffer allocation parameters required to * support the current MTU, including padding for header @@ -638,8 +638,32 @@ static void efx_start_datapath(struct efx_nic *efx) efx->rx_dma_len = (efx->type->rx_buffer_hash_size + EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + efx->type->rx_buffer_padding); - efx->rx_buffer_order = get_order(sizeof(struct efx_rx_page_state) + - EFX_PAGE_IP_ALIGN + efx->rx_dma_len); + rx_buf_len = (sizeof(struct efx_rx_page_state) + + EFX_PAGE_IP_ALIGN + efx->rx_dma_len); + if (rx_buf_len <= PAGE_SIZE) { + efx->rx_scatter = false; + efx->rx_buffer_order = 0; + if (rx_buf_len <= PAGE_SIZE / 2) + efx->rx_buffer_truesize = PAGE_SIZE / 2; + else + efx->rx_buffer_truesize = PAGE_SIZE; + } else if (efx->type->can_rx_scatter) { + BUILD_BUG_ON(sizeof(struct efx_rx_page_state) + + EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE > + PAGE_SIZE / 2); + efx->rx_scatter = true; + efx->rx_dma_len = EFX_RX_USR_BUF_SIZE; + efx->rx_buffer_order = 0; + efx->rx_buffer_truesize = PAGE_SIZE / 2; + } else { + efx->rx_scatter = false; + efx->rx_buffer_order = get_order(rx_buf_len); + efx->rx_buffer_truesize = PAGE_SIZE << efx->rx_buffer_order; + } + + /* RX filters also have scatter-enabled flags */ + if (efx->rx_scatter != old_rx_scatter) + efx_filter_update_rx_scatter(efx); /* We must keep at least one descriptor in a TX ring empty. * We could avoid this when the queue size does not exactly @@ -661,7 +685,7 @@ static void efx_start_datapath(struct efx_nic *efx) efx_nic_generate_fill_event(rx_queue); } - WARN_ON(channel->rx_pkt != NULL); + WARN_ON(channel->rx_pkt_n_frags); } if (netif_device_present(efx->net_dev)) diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 00e7077fa1d8..211da79a65e8 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -39,16 +39,14 @@ extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_fini_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); extern void efx_rx_slow_fill(unsigned long context); -extern void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf); -extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, +extern void __efx_rx_packet(struct efx_channel *channel); +extern void efx_rx_packet(struct efx_rx_queue *rx_queue, + unsigned int index, unsigned int n_frags, unsigned int len, u16 flags); static inline void efx_rx_flush_packet(struct efx_channel *channel) { - if (channel->rx_pkt) { - __efx_rx_packet(channel, channel->rx_pkt); - channel->rx_pkt = NULL; - } + if (channel->rx_pkt_n_frags) + __efx_rx_packet(channel); } extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); @@ -73,6 +71,7 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); extern int efx_probe_filters(struct efx_nic *efx); extern void efx_restore_filters(struct efx_nic *efx); extern void efx_remove_filters(struct efx_nic *efx); +extern void efx_filter_update_rx_scatter(struct efx_nic *efx); extern s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, bool replace); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 8e61cd06f66a..6e768175e7e0 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -154,6 +154,7 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc), + EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_nodesc_trunc), }; /* Number of ethtool statistics */ @@ -978,7 +979,8 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, rule->m_ext.data[1])) return -EINVAL; - efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, 0, + efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, + efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, (rule->ring_cookie == RX_CLS_FLOW_DISC) ? 0xfff : rule->ring_cookie); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 49bcd196e10d..4486102fa9b3 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -1546,10 +1546,6 @@ static int falcon_probe_nic(struct efx_nic *efx) static void falcon_init_rx_cfg(struct efx_nic *efx) { - /* Prior to Siena the RX DMA engine will split each frame at - * intervals of RX_USR_BUF_SIZE (32-byte units). We set it to - * be so large that that never happens. */ - const unsigned huge_buf_size = (3 * 4096) >> 5; /* RX control FIFO thresholds (32 entries) */ const unsigned ctrl_xon_thr = 20; const unsigned ctrl_xoff_thr = 25; @@ -1557,10 +1553,15 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) efx_reado(efx, ®, FR_AZ_RX_CFG); if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { - /* Data FIFO size is 5.5K */ + /* Data FIFO size is 5.5K. The RX DMA engine only + * supports scattering for user-mode queues, but will + * split DMA writes at intervals of RX_USR_BUF_SIZE + * (32-byte units) even for kernel-mode queues. We + * set it to be so large that that never happens. + */ EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_USR_BUF_SIZE, - huge_buf_size); + (3 * 4096) >> 5); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, 512 >> 8); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, 2048 >> 8); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_TX_TH, ctrl_xon_thr); @@ -1569,7 +1570,7 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) /* Data FIFO size is 80K; register fields moved */ EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_USR_BUF_SIZE, - huge_buf_size); + EFX_RX_USR_BUF_SIZE >> 5); /* Send XON and XOFF at ~3 * max MTU away from empty/full */ EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, 27648 >> 8); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, 54272 >> 8); @@ -1815,6 +1816,7 @@ const struct efx_nic_type falcon_a1_nic_type = { .evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER, .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .rx_buffer_padding = 0x24, + .can_rx_scatter = false, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, @@ -1865,6 +1867,7 @@ const struct efx_nic_type falcon_b0_nic_type = { .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .rx_buffer_hash_size = 0x10, .rx_buffer_padding = 0, + .can_rx_scatter = true, .max_interrupt_mode = EFX_INT_MODE_MSIX, .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 61b4408bbdb8..2397f0e8d3eb 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c @@ -172,6 +172,25 @@ static void efx_filter_push_rx_config(struct efx_nic *efx) filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED, !!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags & EFX_FILTER_FLAG_RX_RSS)); + + /* There is a single bit to enable RX scatter for all + * unmatched packets. Only set it if scatter is + * enabled in both filter specs. + */ + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, + !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags & + table->spec[EFX_FILTER_INDEX_MC_DEF].flags & + EFX_FILTER_FLAG_RX_SCATTER)); + } else if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + /* We don't expose 'default' filters because unmatched + * packets always go to the queue number found in the + * RSS table. But we still need to set the RX scatter + * bit here. + */ + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, + efx->rx_scatter); } efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); @@ -413,13 +432,18 @@ static void efx_filter_reset_rx_def(struct efx_nic *efx, unsigned filter_idx) struct efx_filter_state *state = efx->filter_state; struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_DEF]; struct efx_filter_spec *spec = &table->spec[filter_idx]; + enum efx_filter_flags flags = 0; /* If there's only one channel then disable RSS for non VF * traffic, thereby allowing VFs to use RSS when the PF can't. */ - efx_filter_init_rx(spec, EFX_FILTER_PRI_MANUAL, - efx->n_rx_channels > 1 ? EFX_FILTER_FLAG_RX_RSS : 0, - 0); + if (efx->n_rx_channels > 1) + flags |= EFX_FILTER_FLAG_RX_RSS; + + if (efx->rx_scatter) + flags |= EFX_FILTER_FLAG_RX_SCATTER; + + efx_filter_init_rx(spec, EFX_FILTER_PRI_MANUAL, flags, 0); spec->type = EFX_FILTER_UC_DEF + filter_idx; table->used_bitmap[0] |= 1 << filter_idx; } @@ -1101,6 +1125,50 @@ void efx_remove_filters(struct efx_nic *efx) kfree(state); } +/* Update scatter enable flags for filters pointing to our own RX queues */ +void efx_filter_update_rx_scatter(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id; + struct efx_filter_table *table; + efx_oword_t filter; + unsigned int filter_idx; + + spin_lock_bh(&state->lock); + + for (table_id = EFX_FILTER_TABLE_RX_IP; + table_id <= EFX_FILTER_TABLE_RX_DEF; + table_id++) { + table = &state->table[table_id]; + + for (filter_idx = 0; filter_idx < table->size; filter_idx++) { + if (!test_bit(filter_idx, table->used_bitmap) || + table->spec[filter_idx].dmaq_id >= + efx->n_rx_channels) + continue; + + if (efx->rx_scatter) + table->spec[filter_idx].flags |= + EFX_FILTER_FLAG_RX_SCATTER; + else + table->spec[filter_idx].flags &= + ~EFX_FILTER_FLAG_RX_SCATTER; + + if (table_id == EFX_FILTER_TABLE_RX_DEF) + /* Pushed by efx_filter_push_rx_config() */ + continue; + + efx_filter_build(&filter, &table->spec[filter_idx]); + efx_writeo(efx, &filter, + table->offset + table->step * filter_idx); + } + } + + efx_filter_push_rx_config(efx); + + spin_unlock_bh(&state->lock); +} + #ifdef CONFIG_RFS_ACCEL int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 1bc911f980b5..e41b54bada7c 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -69,6 +69,12 @@ #define EFX_TXQ_TYPES 4 #define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS) +/* Maximum possible MTU the driver supports */ +#define EFX_MAX_MTU (9 * 1024) + +/* Size of an RX scatter buffer. Small enough to pack 2 into a 4K page. */ +#define EFX_RX_USR_BUF_SIZE 1824 + /* Forward declare Precision Time Protocol (PTP) support structure. */ struct efx_ptp_data; @@ -212,7 +218,8 @@ struct efx_tx_queue { * If completed: offset in @page of Ethernet header. * @len: If pending: length for DMA descriptor. * If completed: received length, excluding hash prefix. - * @flags: Flags for buffer and packet state. + * @flags: Flags for buffer and packet state. These are only set on the + * first buffer of a scattered packet. */ struct efx_rx_buffer { dma_addr_t dma_addr; @@ -256,6 +263,7 @@ struct efx_rx_page_state { * @added_count: Number of buffers added to the receive queue. * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. + * @scatter_n: Number of buffers used by current packet * @max_fill: RX descriptor maximum fill level (<= ring size) * @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill * (<= @max_fill) @@ -276,6 +284,7 @@ struct efx_rx_queue { unsigned int added_count; unsigned int notified_count; unsigned int removed_count; + unsigned int scatter_n; unsigned int max_fill; unsigned int fast_fill_trigger; unsigned int min_fill; @@ -335,6 +344,12 @@ enum efx_rx_alloc_method { * @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun + * @n_rx_nodesc_trunc: Number of RX packets truncated and then dropped due to + * lack of descriptors + * @rx_pkt_n_frags: Number of fragments in next packet to be delivered by + * __efx_rx_packet(), or zero if there is none + * @rx_pkt_index: Ring index of first buffer for next packet to be delivered + * by __efx_rx_packet(), if @rx_pkt_n_frags != 0 * @rx_queue: RX queue for this channel * @tx_queue: TX queues for this channel */ @@ -366,11 +381,10 @@ struct efx_channel { unsigned n_rx_frm_trunc; unsigned n_rx_overlength; unsigned n_skbuff_leaks; + unsigned int n_rx_nodesc_trunc; - /* Used to pipeline received packets in order to optimise memory - * access with prefetches. - */ - struct efx_rx_buffer *rx_pkt; + unsigned int rx_pkt_n_frags; + unsigned int rx_pkt_index; struct efx_rx_queue rx_queue; struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; @@ -672,8 +686,11 @@ struct vfdi_status; * @n_tx_channels: Number of channels used for TX * @rx_dma_len: Current maximum RX DMA length * @rx_buffer_order: Order (log2) of number of pages for each RX buffer + * @rx_buffer_truesize: Amortised allocation size of an RX buffer, + * for use in sk_buff::truesize * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS + * @rx_scatter: Scatter mode enabled for receives * @int_error_count: Number of internal errors seen recently * @int_error_expire: Time at which error count will be expired * @irq_status: Interrupt status buffer @@ -788,8 +805,10 @@ struct efx_nic { unsigned n_tx_channels; unsigned int rx_dma_len; unsigned int rx_buffer_order; + unsigned int rx_buffer_truesize; u8 rx_hash_key[40]; u32 rx_indir_table[128]; + bool rx_scatter; unsigned int_error_count; unsigned long int_error_expire; @@ -920,8 +939,9 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @evq_ptr_tbl_base: Event queue pointer table base address * @evq_rptr_tbl_base: Event queue read-pointer table base address * @max_dma_mask: Maximum possible DMA mask - * @rx_buffer_hash_size: Size of hash at start of RX buffer - * @rx_buffer_padding: Size of padding at end of RX buffer + * @rx_buffer_hash_size: Size of hash at start of RX packet + * @rx_buffer_padding: Size of padding at end of RX packet + * @can_rx_scatter: NIC is able to scatter packet to multiple buffers * @max_interrupt_mode: Highest capability interrupt mode supported * from &enum efx_init_mode. * @phys_addr_channels: Number of channels with physically addressed @@ -969,6 +989,7 @@ struct efx_nic_type { u64 max_dma_mask; unsigned int rx_buffer_hash_size; unsigned int rx_buffer_padding; + bool can_rx_scatter; unsigned int max_interrupt_mode; unsigned int phys_addr_channels; unsigned int timer_period_max; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 0ad790cc473c..f9f5df8b51fe 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -591,12 +591,22 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; bool is_b0 = efx_nic_rev(efx) >= EFX_REV_FALCON_B0; bool iscsi_digest_en = is_b0; + bool jumbo_en; + + /* For kernel-mode queues in Falcon A1, the JUMBO flag enables + * DMA to continue after a PCIe page boundary (and scattering + * is not possible). In Falcon B0 and Siena, it enables + * scatter. + */ + jumbo_en = !is_b0 || efx->rx_scatter; netif_dbg(efx, hw, efx->net_dev, "RX queue %d ring in special buffers %d-%d\n", efx_rx_queue_index(rx_queue), rx_queue->rxd.index, rx_queue->rxd.index + rx_queue->rxd.entries - 1); + rx_queue->scatter_n = 0; + /* Pin RX descriptor ring */ efx_init_special_buffer(efx, &rx_queue->rxd); @@ -613,8 +623,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) FRF_AZ_RX_DESCQ_SIZE, __ffs(rx_queue->rxd.entries), FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , - /* For >=B0 this is scatter so disable */ - FRF_AZ_RX_DESCQ_JUMBO, !is_b0, + FRF_AZ_RX_DESCQ_JUMBO, jumbo_en, FRF_AZ_RX_DESCQ_EN, 1); efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, efx_rx_queue_index(rx_queue)); @@ -968,13 +977,24 @@ static u16 efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, EFX_RX_PKT_DISCARD : 0; } -/* Handle receive events that are not in-order. */ -static void +/* Handle receive events that are not in-order. Return true if this + * can be handled as a partial packet discard, false if it's more + * serious. + */ +static bool efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) { + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; unsigned expected, dropped; + if (rx_queue->scatter_n && + index == ((rx_queue->removed_count + rx_queue->scatter_n - 1) & + rx_queue->ptr_mask)) { + ++channel->n_rx_nodesc_trunc; + return true; + } + expected = rx_queue->removed_count & rx_queue->ptr_mask; dropped = (index - expected) & rx_queue->ptr_mask; netif_info(efx, rx_err, efx->net_dev, @@ -983,6 +1003,7 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) efx_schedule_reset(efx, EFX_WORKAROUND_5676(efx) ? RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); + return false; } /* Handle a packet received event @@ -998,7 +1019,7 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt; unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; unsigned expected_ptr; - bool rx_ev_pkt_ok; + bool rx_ev_pkt_ok, rx_ev_sop, rx_ev_cont; u16 flags; struct efx_rx_queue *rx_queue; struct efx_nic *efx = channel->efx; @@ -1006,21 +1027,56 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) if (unlikely(ACCESS_ONCE(efx->reset_pending))) return; - /* Basic packet information */ - rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT); - rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_OK); - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); - WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_JUMBO_CONT)); - WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_SOP) != 1); + rx_ev_cont = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_JUMBO_CONT); + rx_ev_sop = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_SOP); WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) != channel->channel); rx_queue = efx_channel_get_rx_queue(channel); rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); - expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask; - if (unlikely(rx_ev_desc_ptr != expected_ptr)) - efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); + expected_ptr = ((rx_queue->removed_count + rx_queue->scatter_n) & + rx_queue->ptr_mask); + + /* Check for partial drops and other errors */ + if (unlikely(rx_ev_desc_ptr != expected_ptr) || + unlikely(rx_ev_sop != (rx_queue->scatter_n == 0))) { + if (rx_ev_desc_ptr != expected_ptr && + !efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr)) + return; + + /* Discard all pending fragments */ + if (rx_queue->scatter_n) { + efx_rx_packet( + rx_queue, + rx_queue->removed_count & rx_queue->ptr_mask, + rx_queue->scatter_n, 0, EFX_RX_PKT_DISCARD); + rx_queue->removed_count += rx_queue->scatter_n; + rx_queue->scatter_n = 0; + } + + /* Return if there is no new fragment */ + if (rx_ev_desc_ptr != expected_ptr) + return; + + /* Discard new fragment if not SOP */ + if (!rx_ev_sop) { + efx_rx_packet( + rx_queue, + rx_queue->removed_count & rx_queue->ptr_mask, + 1, 0, EFX_RX_PKT_DISCARD); + ++rx_queue->removed_count; + return; + } + } + + ++rx_queue->scatter_n; + if (rx_ev_cont) + return; + + rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT); + rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_OK); + rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); if (likely(rx_ev_pkt_ok)) { /* If packet is marked as OK and packet type is TCP/IP or @@ -1048,7 +1104,11 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) channel->irq_mod_score += 2; /* Handle received packet */ - efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, flags); + efx_rx_packet(rx_queue, + rx_queue->removed_count & rx_queue->ptr_mask, + rx_queue->scatter_n, rx_ev_byte_cnt, flags); + rx_queue->removed_count += rx_queue->scatter_n; + rx_queue->scatter_n = 0; } /* If this flush done event corresponds to a &struct efx_tx_queue, then diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 04518722ac1d..88aa1ff01e3f 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -39,13 +39,17 @@ */ static unsigned int rx_refill_threshold; +/* Each packet can consume up to ceil(max_frame_len / buffer_size) buffers */ +#define EFX_RX_MAX_FRAGS DIV_ROUND_UP(EFX_MAX_FRAME_LEN(EFX_MAX_MTU), \ + EFX_RX_USR_BUF_SIZE) + /* * RX maximum head room required. * - * This must be at least 1 to prevent overflow and at least 2 to allow - * pipelined receives. + * This must be at least 1 to prevent overflow, plus one packet-worth + * to allow pipelined receives. */ -#define EFX_RXD_HEAD_ROOM 2 +#define EFX_RXD_HEAD_ROOM (1 + EFX_RX_MAX_FRAGS) static inline u8 *efx_rx_buf_va(struct efx_rx_buffer *buf) { @@ -66,6 +70,15 @@ static inline u32 efx_rx_buf_hash(const u8 *eh) #endif } +static inline struct efx_rx_buffer * +efx_rx_buf_next(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) +{ + if (unlikely(rx_buf == efx_rx_buffer(rx_queue, rx_queue->ptr_mask))) + return efx_rx_buffer(rx_queue, 0); + else + return rx_buf + 1; +} + /** * efx_init_rx_buffers - create EFX_RX_BATCH page-based RX buffers * @@ -199,28 +212,34 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, ++rx_queue->added_count; } -/* Recycle the given rx buffer directly back into the rx_queue. There is - * always room to add this buffer, because we've just popped a buffer. */ -static void efx_recycle_rx_buffer(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf) +/* Recycle buffers directly back into the rx_queue. There is always + * room to add these buffer, because we've just popped them. + */ +static void efx_recycle_rx_buffers(struct efx_channel *channel, + struct efx_rx_buffer *rx_buf, + unsigned int n_frags) { struct efx_nic *efx = channel->efx; struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); struct efx_rx_buffer *new_buf; unsigned index; - rx_buf->flags = 0; + do { + rx_buf->flags = 0; - if (efx->rx_dma_len <= EFX_RX_HALF_PAGE && - page_count(rx_buf->page) == 1) - efx_resurrect_rx_buffer(rx_queue, rx_buf); + if (efx->rx_dma_len <= EFX_RX_HALF_PAGE && + page_count(rx_buf->page) == 1) + efx_resurrect_rx_buffer(rx_queue, rx_buf); - index = rx_queue->added_count & rx_queue->ptr_mask; - new_buf = efx_rx_buffer(rx_queue, index); + index = rx_queue->added_count & rx_queue->ptr_mask; + new_buf = efx_rx_buffer(rx_queue, index); - memcpy(new_buf, rx_buf, sizeof(*new_buf)); - rx_buf->page = NULL; - ++rx_queue->added_count; + memcpy(new_buf, rx_buf, sizeof(*new_buf)); + rx_buf->page = NULL; + ++rx_queue->added_count; + + rx_buf = efx_rx_buf_next(rx_queue, rx_buf); + } while (--n_frags); } /** @@ -328,46 +347,56 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, /* Pass a received packet up through GRO. GRO can handle pages * regardless of checksum state and skbs with a good checksum. */ -static void efx_rx_packet_gro(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, - const u8 *eh) +static void +efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, + unsigned int n_frags, u8 *eh) { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; struct efx_nic *efx = channel->efx; - struct page *page = rx_buf->page; struct sk_buff *skb; - rx_buf->page = NULL; - skb = napi_get_frags(napi); - if (!skb) { - put_page(page); + if (unlikely(!skb)) { + while (n_frags--) { + put_page(rx_buf->page); + rx_buf->page = NULL; + rx_buf = efx_rx_buf_next(&channel->rx_queue, rx_buf); + } return; } if (efx->net_dev->features & NETIF_F_RXHASH) skb->rxhash = efx_rx_buf_hash(eh); - - skb_fill_page_desc(skb, 0, page, rx_buf->page_offset, rx_buf->len); - - skb->len = rx_buf->len; - skb->data_len = rx_buf->len; - skb->truesize += rx_buf->len; skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); - skb_record_rx_queue(skb, channel->rx_queue.core_index); + for (;;) { + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, + rx_buf->page, rx_buf->page_offset, + rx_buf->len); + rx_buf->page = NULL; + skb->len += rx_buf->len; + if (skb_shinfo(skb)->nr_frags == n_frags) + break; - gro_result = napi_gro_frags(napi); + rx_buf = efx_rx_buf_next(&channel->rx_queue, rx_buf); + } + + skb->data_len = skb->len; + skb->truesize += n_frags * efx->rx_buffer_truesize; + + skb_record_rx_queue(skb, channel->rx_queue.core_index); + gro_result = napi_gro_frags(napi); if (gro_result != GRO_DROP) channel->irq_mod_score += 2; } -/* Allocate and construct an SKB around a struct page.*/ +/* Allocate and construct an SKB around page fragments */ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, + unsigned int n_frags, u8 *eh, int hdr_len) { struct efx_nic *efx = channel->efx; @@ -381,25 +410,32 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len); skb_reserve(skb, EFX_PAGE_SKB_ALIGN); + memcpy(__skb_put(skb, hdr_len), eh, hdr_len); - skb->len = rx_buf->len; - skb->truesize = rx_buf->len + sizeof(struct sk_buff); - memcpy(skb->data, eh, hdr_len); - skb->tail += hdr_len; - - /* Append the remaining page onto the frag list */ + /* Append the remaining page(s) onto the frag list */ if (rx_buf->len > hdr_len) { - skb->data_len = skb->len - hdr_len; - skb_fill_page_desc(skb, 0, rx_buf->page, - rx_buf->page_offset + hdr_len, - skb->data_len); + rx_buf->page_offset += hdr_len; + rx_buf->len -= hdr_len; + + for (;;) { + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, + rx_buf->page, rx_buf->page_offset, + rx_buf->len); + rx_buf->page = NULL; + skb->len += rx_buf->len; + skb->data_len += rx_buf->len; + if (skb_shinfo(skb)->nr_frags == n_frags) + break; + + rx_buf = efx_rx_buf_next(&channel->rx_queue, rx_buf); + } } else { __free_pages(rx_buf->page, efx->rx_buffer_order); - skb->data_len = 0; + rx_buf->page = NULL; + n_frags = 0; } - /* Ownership has transferred from the rx_buf to skb */ - rx_buf->page = NULL; + skb->truesize += n_frags * efx->rx_buffer_truesize; /* Move past the ethernet header */ skb->protocol = eth_type_trans(skb, efx->net_dev); @@ -408,7 +444,7 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, } void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, u16 flags) + unsigned int n_frags, unsigned int len, u16 flags) { struct efx_nic *efx = rx_queue->efx; struct efx_channel *channel = efx_rx_queue_channel(rx_queue); @@ -417,35 +453,43 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->flags |= flags; - /* This allows the refill path to post another buffer. - * EFX_RXD_HEAD_ROOM ensures that the slot we are using - * isn't overwritten yet. - */ - rx_queue->removed_count++; - - /* Validate the length encoded in the event vs the descriptor pushed */ - efx_rx_packet__check_len(rx_queue, rx_buf, len); + /* Validate the number of fragments and completed length */ + if (n_frags == 1) { + efx_rx_packet__check_len(rx_queue, rx_buf, len); + } else if (unlikely(n_frags > EFX_RX_MAX_FRAGS) || + unlikely(len <= (n_frags - 1) * EFX_RX_USR_BUF_SIZE) || + unlikely(len > n_frags * EFX_RX_USR_BUF_SIZE) || + unlikely(!efx->rx_scatter)) { + /* If this isn't an explicit discard request, either + * the hardware or the driver is broken. + */ + WARN_ON(!(len == 0 && rx_buf->flags & EFX_RX_PKT_DISCARD)); + rx_buf->flags |= EFX_RX_PKT_DISCARD; + } netif_vdbg(efx, rx_status, efx->net_dev, - "RX queue %d received id %x at %llx+%x %s%s\n", + "RX queue %d received ids %x-%x len %d %s%s\n", efx_rx_queue_index(rx_queue), index, - (unsigned long long)rx_buf->dma_addr, len, + (index + n_frags - 1) & rx_queue->ptr_mask, len, (rx_buf->flags & EFX_RX_PKT_CSUMMED) ? " [SUMMED]" : "", (rx_buf->flags & EFX_RX_PKT_DISCARD) ? " [DISCARD]" : ""); - /* Discard packet, if instructed to do so */ + /* Discard packet, if instructed to do so. Process the + * previous receive first. + */ if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) { - efx_recycle_rx_buffer(channel, rx_buf); - - /* Don't hold off the previous receive */ - rx_buf = NULL; - goto out; + efx_rx_flush_packet(channel); + efx_recycle_rx_buffers(channel, rx_buf, n_frags); + return; } + if (n_frags == 1) + rx_buf->len = len; + /* Release and/or sync DMA mapping - assumes all RX buffers * consumed in-order per RX queue */ - efx_unmap_rx_buffer(efx, rx_buf, len); + efx_unmap_rx_buffer(efx, rx_buf, rx_buf->len); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. @@ -453,23 +497,40 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, prefetch(efx_rx_buf_va(rx_buf)); rx_buf->page_offset += efx->type->rx_buffer_hash_size; - rx_buf->len = len - efx->type->rx_buffer_hash_size; + rx_buf->len -= efx->type->rx_buffer_hash_size; + + if (n_frags > 1) { + /* Release/sync DMA mapping for additional fragments. + * Fix length for last fragment. + */ + unsigned int tail_frags = n_frags - 1; + + for (;;) { + rx_buf = efx_rx_buf_next(rx_queue, rx_buf); + if (--tail_frags == 0) + break; + efx_unmap_rx_buffer(efx, rx_buf, EFX_RX_USR_BUF_SIZE); + } + rx_buf->len = len - (n_frags - 1) * EFX_RX_USR_BUF_SIZE; + efx_unmap_rx_buffer(efx, rx_buf, rx_buf->len); + } /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. */ -out: efx_rx_flush_packet(channel); - channel->rx_pkt = rx_buf; + channel->rx_pkt_n_frags = n_frags; + channel->rx_pkt_index = index; } static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, - struct efx_rx_buffer *rx_buf) + struct efx_rx_buffer *rx_buf, + unsigned int n_frags) { struct sk_buff *skb; u16 hdr_len = min_t(u16, rx_buf->len, EFX_SKB_HEADERS); - skb = efx_rx_mk_skb(channel, rx_buf, eh, hdr_len); + skb = efx_rx_mk_skb(channel, rx_buf, n_frags, eh, hdr_len); if (unlikely(skb == NULL)) { efx_free_rx_buffer(channel->efx, rx_buf); return; @@ -488,9 +549,11 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, } /* Handle a received packet. Second half: Touches packet payload. */ -void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) +void __efx_rx_packet(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + struct efx_rx_buffer *rx_buf = + efx_rx_buffer(&channel->rx_queue, channel->rx_pkt_index); u8 *eh = efx_rx_buf_va(rx_buf); /* If we're in loopback test, then pass the packet directly to the @@ -499,16 +562,18 @@ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) if (unlikely(efx->loopback_selftest)) { efx_loopback_rx_packet(efx, eh, rx_buf->len); efx_free_rx_buffer(efx, rx_buf); - return; + goto out; } if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) rx_buf->flags &= ~EFX_RX_PKT_CSUMMED; if (!channel->type->receive_skb) - efx_rx_packet_gro(channel, rx_buf, eh); + efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh); else - efx_rx_deliver(channel, eh, rx_buf); + efx_rx_deliver(channel, eh, rx_buf, channel->rx_pkt_n_frags); +out: + channel->rx_pkt_n_frags = 0; } int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index e07ff0d3f26b..51669244d154 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -414,6 +414,8 @@ static int siena_init_nic(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_INSRT_HDR, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_HASH_ALG, 1); EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_IP_HASH, 1); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_USR_BUF_SIZE, + EFX_RX_USR_BUF_SIZE >> 5); efx_writeo(efx, &temp, FR_AZ_RX_CFG); /* Set hash key for IPv4 */ @@ -718,6 +720,7 @@ const struct efx_nic_type siena_a0_nic_type = { .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .rx_buffer_hash_size = 0x10, .rx_buffer_padding = 0, + .can_rx_scatter = true, .max_interrupt_mode = EFX_INT_MODE_MSIX, .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 -- cgit From 2768935a46603bb9bdd121864b1f2b2e8a71cccc Mon Sep 17 00:00:00 2001 From: Daniel Pieczko Date: Wed, 13 Feb 2013 10:54:41 +0000 Subject: sfc: reuse pages to avoid DMA mapping/unmapping costs On POWER systems, DMA mapping/unmapping operations are very expensive. These changes reduce these costs by trying to reuse DMA mapped pages. After all the buffers associated with a page have been processed and passed up, the page is placed into a ring (if there is room). For each page that is required for a refill operation, a page in the ring is examined to determine if its page count has fallen to 1, ie. the kernel has released its reference to these packets. If this is the case, the page can be immediately added back into the RX descriptor ring, without having to re-map it for DMA. If the kernel is still holding a reference to this page, it is removed from the ring and unmapped for DMA. Then a new page, which can immediately be used by RX buffers in the descriptor ring, is allocated and DMA mapped. The time a page needs to spend in the recycle ring before the kernel has released its page references is based on the number of buffers that use this page. As large pages can hold more RX buffers, the RX recycle ring can be shorter. This reduces memory usage on POWER systems, while maintaining the performance gain achieved by recycling pages, following the driver change to pack more than two RX buffers into large pages. When an IOMMU is not present, the recycle ring can be small to reduce memory usage, since DMA mapping operations are inexpensive. With a small recycle ring, attempting to refill the descriptor queue with more buffers than the equivalent size of the recycle ring could ultimately lead to memory leaks if page entries in the recycle ring were overwritten. To prevent this, the check to see if the recycle ring is full is changed to check if the next entry to be written is NULL. [bwh: Combine and rebase several commits so this is complete before the following buffer-packing changes. Remove module parameter.] Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 2 + drivers/net/ethernet/sfc/net_driver.h | 19 +++ drivers/net/ethernet/sfc/rx.c | 299 +++++++++++++++++++++++----------- 3 files changed, 226 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 1213af5024d1..a70c458f3cef 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -661,6 +661,8 @@ static void efx_start_datapath(struct efx_nic *efx) efx->rx_buffer_truesize = PAGE_SIZE << efx->rx_buffer_order; } + efx->rx_bufs_per_page = (rx_buf_len <= PAGE_SIZE / 2) ? 2 : 1; + /* RX filters also have scatter-enabled flags */ if (efx->rx_scatter != old_rx_scatter) efx_filter_update_rx_scatter(efx); diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index e41b54bada7c..370c5bcebad9 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -264,12 +264,22 @@ struct efx_rx_page_state { * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. * @scatter_n: Number of buffers used by current packet + * @page_ring: The ring to store DMA mapped pages for reuse. + * @page_add: Counter to calculate the write pointer for the recycle ring. + * @page_remove: Counter to calculate the read pointer for the recycle ring. + * @page_recycle_count: The number of pages that have been recycled. + * @page_recycle_failed: The number of pages that couldn't be recycled because + * the kernel still held a reference to them. + * @page_recycle_full: The number of pages that were released because the + * recycle ring was full. + * @page_ptr_mask: The number of pages in the RX recycle ring minus 1. * @max_fill: RX descriptor maximum fill level (<= ring size) * @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill * (<= @max_fill) * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. + * @recycle_count: RX buffer recycle counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). */ struct efx_rx_queue { @@ -285,10 +295,18 @@ struct efx_rx_queue { unsigned int notified_count; unsigned int removed_count; unsigned int scatter_n; + struct page **page_ring; + unsigned int page_add; + unsigned int page_remove; + unsigned int page_recycle_count; + unsigned int page_recycle_failed; + unsigned int page_recycle_full; + unsigned int page_ptr_mask; unsigned int max_fill; unsigned int fast_fill_trigger; unsigned int min_fill; unsigned int min_overfill; + unsigned int recycle_count; struct timer_list slow_fill; unsigned int slow_fill_count; }; @@ -806,6 +824,7 @@ struct efx_nic { unsigned int rx_dma_len; unsigned int rx_buffer_order; unsigned int rx_buffer_truesize; + unsigned int rx_bufs_per_page; u8 rx_hash_key[40]; u32 rx_indir_table[128]; bool rx_scatter; diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 88aa1ff01e3f..eea56f3ec81c 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include "net_driver.h" @@ -27,6 +28,13 @@ /* Number of RX descriptors pushed at once. */ #define EFX_RX_BATCH 8 +/* Number of RX buffers to recycle pages for. When creating the RX page recycle + * ring, this number is divided by the number of buffers per page to calculate + * the number of pages to store in the RX page recycle ring. + */ +#define EFX_RECYCLE_RING_SIZE_IOMMU 4096 +#define EFX_RECYCLE_RING_SIZE_NOIOMMU (2 * EFX_RX_BATCH) + /* Maximum length for an RX descriptor sharing a page */ #define EFX_RX_HALF_PAGE ((PAGE_SIZE >> 1) - sizeof(struct efx_rx_page_state) \ - EFX_PAGE_IP_ALIGN) @@ -79,6 +87,56 @@ efx_rx_buf_next(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) return rx_buf + 1; } +static inline void efx_sync_rx_buffer(struct efx_nic *efx, + struct efx_rx_buffer *rx_buf, + unsigned int len) +{ + dma_sync_single_for_cpu(&efx->pci_dev->dev, rx_buf->dma_addr, len, + DMA_FROM_DEVICE); +} + +/* Return true if this is the last RX buffer using a page. */ +static inline bool efx_rx_is_last_buffer(struct efx_nic *efx, + struct efx_rx_buffer *rx_buf) +{ + return (rx_buf->page_offset >= (PAGE_SIZE >> 1) || + efx->rx_dma_len > EFX_RX_HALF_PAGE); +} + +/* Check the RX page recycle ring for a page that can be reused. */ +static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) +{ + struct efx_nic *efx = rx_queue->efx; + struct page *page; + struct efx_rx_page_state *state; + unsigned index; + + index = rx_queue->page_remove & rx_queue->page_ptr_mask; + page = rx_queue->page_ring[index]; + if (page == NULL) + return NULL; + + rx_queue->page_ring[index] = NULL; + /* page_remove cannot exceed page_add. */ + if (rx_queue->page_remove != rx_queue->page_add) + ++rx_queue->page_remove; + + /* If page_count is 1 then we hold the only reference to this page. */ + if (page_count(page) == 1) { + ++rx_queue->page_recycle_count; + return page; + } else { + state = page_address(page); + dma_unmap_page(&efx->pci_dev->dev, state->dma_addr, + PAGE_SIZE << efx->rx_buffer_order, + DMA_FROM_DEVICE); + put_page(page); + ++rx_queue->page_recycle_failed; + } + + return NULL; +} + /** * efx_init_rx_buffers - create EFX_RX_BATCH page-based RX buffers * @@ -103,20 +161,28 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) BUILD_BUG_ON(EFX_RX_BATCH & 1); for (count = 0; count < EFX_RX_BATCH; ++count) { - page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC, - efx->rx_buffer_order); - if (unlikely(page == NULL)) - return -ENOMEM; - dma_addr = dma_map_page(&efx->pci_dev->dev, page, 0, - PAGE_SIZE << efx->rx_buffer_order, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(&efx->pci_dev->dev, dma_addr))) { - __free_pages(page, efx->rx_buffer_order); - return -EIO; + page = efx_reuse_page(rx_queue); + if (page == NULL) { + page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC, + efx->rx_buffer_order); + if (unlikely(page == NULL)) + return -ENOMEM; + dma_addr = + dma_map_page(&efx->pci_dev->dev, page, 0, + PAGE_SIZE << efx->rx_buffer_order, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(&efx->pci_dev->dev, + dma_addr))) { + __free_pages(page, efx->rx_buffer_order); + return -EIO; + } + state = page_address(page); + state->dma_addr = dma_addr; + } else { + state = page_address(page); + dma_addr = state->dma_addr; } - state = page_address(page); - state->refcnt = 0; - state->dma_addr = dma_addr; + get_page(page); dma_addr += sizeof(struct efx_rx_page_state); page_offset = sizeof(struct efx_rx_page_state); @@ -128,9 +194,7 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) rx_buf->page = page; rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_dma_len; - rx_buf->flags = 0; ++rx_queue->added_count; - ++state->refcnt; if ((~count & 1) && (efx->rx_dma_len <= EFX_RX_HALF_PAGE)) { /* Use the second half of the page */ @@ -145,99 +209,91 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) return 0; } +/* Unmap a DMA-mapped page. This function is only called for the final RX + * buffer in a page. + */ static void efx_unmap_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf, - unsigned int used_len) + struct efx_rx_buffer *rx_buf) { - if (rx_buf->page) { - struct efx_rx_page_state *state; - - state = page_address(rx_buf->page); - if (--state->refcnt == 0) { - dma_unmap_page(&efx->pci_dev->dev, - state->dma_addr, - PAGE_SIZE << efx->rx_buffer_order, - DMA_FROM_DEVICE); - } else if (used_len) { - dma_sync_single_for_cpu(&efx->pci_dev->dev, - rx_buf->dma_addr, used_len, - DMA_FROM_DEVICE); - } + struct page *page = rx_buf->page; + + if (page) { + struct efx_rx_page_state *state = page_address(page); + dma_unmap_page(&efx->pci_dev->dev, + state->dma_addr, + PAGE_SIZE << efx->rx_buffer_order, + DMA_FROM_DEVICE); } } -static void efx_free_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf) +static void efx_free_rx_buffer(struct efx_rx_buffer *rx_buf) { if (rx_buf->page) { - __free_pages(rx_buf->page, efx->rx_buffer_order); + put_page(rx_buf->page); rx_buf->page = NULL; } } -static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, - struct efx_rx_buffer *rx_buf) +/* Attempt to recycle the page if there is an RX recycle ring; the page can + * only be added if this is the final RX buffer, to prevent pages being used in + * the descriptor ring and appearing in the recycle ring simultaneously. + */ +static void efx_recycle_rx_page(struct efx_channel *channel, + struct efx_rx_buffer *rx_buf) { - efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0); - efx_free_rx_buffer(rx_queue->efx, rx_buf); -} + struct page *page = rx_buf->page; + struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); + struct efx_nic *efx = rx_queue->efx; + unsigned index; -/* Attempt to resurrect the other receive buffer that used to share this page, - * which had previously been passed up to the kernel and freed. */ -static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, - struct efx_rx_buffer *rx_buf) -{ - struct efx_rx_page_state *state = page_address(rx_buf->page); - struct efx_rx_buffer *new_buf; - unsigned fill_level, index; - - /* +1 because efx_rx_packet() incremented removed_count. +1 because - * we'd like to insert an additional descriptor whilst leaving - * EFX_RXD_HEAD_ROOM for the non-recycle path */ - fill_level = (rx_queue->added_count - rx_queue->removed_count + 2); - if (unlikely(fill_level > rx_queue->max_fill)) { - /* We could place "state" on a list, and drain the list in - * efx_fast_push_rx_descriptors(). For now, this will do. */ + /* Only recycle the page after processing the final buffer. */ + if (!efx_rx_is_last_buffer(efx, rx_buf)) return; - } - ++state->refcnt; - get_page(rx_buf->page); + index = rx_queue->page_add & rx_queue->page_ptr_mask; + if (rx_queue->page_ring[index] == NULL) { + unsigned read_index = rx_queue->page_remove & + rx_queue->page_ptr_mask; - index = rx_queue->added_count & rx_queue->ptr_mask; - new_buf = efx_rx_buffer(rx_queue, index); - new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); - new_buf->page = rx_buf->page; - new_buf->len = rx_buf->len; - ++rx_queue->added_count; + /* The next slot in the recycle ring is available, but + * increment page_remove if the read pointer currently + * points here. + */ + if (read_index == index) + ++rx_queue->page_remove; + rx_queue->page_ring[index] = page; + ++rx_queue->page_add; + return; + } + ++rx_queue->page_recycle_full; + efx_unmap_rx_buffer(efx, rx_buf); + put_page(rx_buf->page); } -/* Recycle buffers directly back into the rx_queue. There is always - * room to add these buffer, because we've just popped them. - */ +static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, + struct efx_rx_buffer *rx_buf) +{ + /* Release the page reference we hold for the buffer. */ + if (rx_buf->page) + put_page(rx_buf->page); + + /* If this is the last buffer in a page, unmap and free it. */ + if (efx_rx_is_last_buffer(rx_queue->efx, rx_buf)) { + efx_unmap_rx_buffer(rx_queue->efx, rx_buf); + efx_free_rx_buffer(rx_buf); + } + rx_buf->page = NULL; +} + +/* Recycle the pages that are used by buffers that have just been received. */ static void efx_recycle_rx_buffers(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, unsigned int n_frags) { - struct efx_nic *efx = channel->efx; struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); - struct efx_rx_buffer *new_buf; - unsigned index; do { - rx_buf->flags = 0; - - if (efx->rx_dma_len <= EFX_RX_HALF_PAGE && - page_count(rx_buf->page) == 1) - efx_resurrect_rx_buffer(rx_queue, rx_buf); - - index = rx_queue->added_count & rx_queue->ptr_mask; - new_buf = efx_rx_buffer(rx_queue, index); - - memcpy(new_buf, rx_buf, sizeof(*new_buf)); - rx_buf->page = NULL; - ++rx_queue->added_count; - + efx_recycle_rx_page(channel, rx_buf); rx_buf = efx_rx_buf_next(rx_queue, rx_buf); } while (--n_frags); } @@ -451,7 +507,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, struct efx_rx_buffer *rx_buf; rx_buf = efx_rx_buffer(rx_queue, index); - rx_buf->flags |= flags; + rx_buf->flags = flags; /* Validate the number of fragments and completed length */ if (n_frags == 1) { @@ -479,6 +535,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) { efx_rx_flush_packet(channel); + put_page(rx_buf->page); efx_recycle_rx_buffers(channel, rx_buf, n_frags); return; } @@ -486,10 +543,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, if (n_frags == 1) rx_buf->len = len; - /* Release and/or sync DMA mapping - assumes all RX buffers - * consumed in-order per RX queue + /* Release and/or sync the DMA mapping - assumes all RX buffers + * consumed in-order per RX queue. */ - efx_unmap_rx_buffer(efx, rx_buf, rx_buf->len); + efx_sync_rx_buffer(efx, rx_buf, rx_buf->len); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. @@ -509,12 +566,16 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf = efx_rx_buf_next(rx_queue, rx_buf); if (--tail_frags == 0) break; - efx_unmap_rx_buffer(efx, rx_buf, EFX_RX_USR_BUF_SIZE); + efx_sync_rx_buffer(efx, rx_buf, EFX_RX_USR_BUF_SIZE); } rx_buf->len = len - (n_frags - 1) * EFX_RX_USR_BUF_SIZE; - efx_unmap_rx_buffer(efx, rx_buf, rx_buf->len); + efx_sync_rx_buffer(efx, rx_buf, rx_buf->len); } + /* All fragments have been DMA-synced, so recycle buffers and pages. */ + rx_buf = efx_rx_buffer(rx_queue, index); + efx_recycle_rx_buffers(channel, rx_buf, n_frags); + /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. */ @@ -532,7 +593,7 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, skb = efx_rx_mk_skb(channel, rx_buf, n_frags, eh, hdr_len); if (unlikely(skb == NULL)) { - efx_free_rx_buffer(channel->efx, rx_buf); + efx_free_rx_buffer(rx_buf); return; } skb_record_rx_queue(skb, channel->rx_queue.core_index); @@ -561,7 +622,7 @@ void __efx_rx_packet(struct efx_channel *channel) */ if (unlikely(efx->loopback_selftest)) { efx_loopback_rx_packet(efx, eh, rx_buf->len); - efx_free_rx_buffer(efx, rx_buf); + efx_free_rx_buffer(rx_buf); goto out; } @@ -603,9 +664,32 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) kfree(rx_queue->buffer); rx_queue->buffer = NULL; } + return rc; } +void efx_init_rx_recycle_ring(struct efx_nic *efx, + struct efx_rx_queue *rx_queue) +{ + unsigned int bufs_in_recycle_ring, page_ring_size; + + /* Set the RX recycle ring size */ +#ifdef CONFIG_PPC64 + bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU; +#else + if (efx->pci_dev->dev.iommu_group) + bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU; + else + bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_NOIOMMU; +#endif /* CONFIG_PPC64 */ + + page_ring_size = roundup_pow_of_two(bufs_in_recycle_ring / + efx->rx_bufs_per_page); + rx_queue->page_ring = kcalloc(page_ring_size, + sizeof(*rx_queue->page_ring), GFP_KERNEL); + rx_queue->page_ptr_mask = page_ring_size - 1; +} + void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; @@ -619,6 +703,13 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) rx_queue->notified_count = 0; rx_queue->removed_count = 0; rx_queue->min_fill = -1U; + efx_init_rx_recycle_ring(efx, rx_queue); + + rx_queue->page_remove = 0; + rx_queue->page_add = rx_queue->page_ptr_mask + 1; + rx_queue->page_recycle_count = 0; + rx_queue->page_recycle_failed = 0; + rx_queue->page_recycle_full = 0; /* Initialise limit fields */ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; @@ -642,6 +733,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) { int i; + struct efx_nic *efx = rx_queue->efx; struct efx_rx_buffer *rx_buf; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, @@ -653,13 +745,32 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) del_timer_sync(&rx_queue->slow_fill); efx_nic_fini_rx(rx_queue); - /* Release RX buffers NB start at index 0 not current HW ptr */ + /* Release RX buffers from the current read ptr to the write ptr */ if (rx_queue->buffer) { - for (i = 0; i <= rx_queue->ptr_mask; i++) { - rx_buf = efx_rx_buffer(rx_queue, i); + for (i = rx_queue->removed_count; i < rx_queue->added_count; + i++) { + unsigned index = i & rx_queue->ptr_mask; + rx_buf = efx_rx_buffer(rx_queue, index); efx_fini_rx_buffer(rx_queue, rx_buf); } } + + /* Unmap and release the pages in the recycle ring. Remove the ring. */ + for (i = 0; i <= rx_queue->page_ptr_mask; i++) { + struct page *page = rx_queue->page_ring[i]; + struct efx_rx_page_state *state; + + if (page == NULL) + continue; + + state = page_address(page); + dma_unmap_page(&efx->pci_dev->dev, state->dma_addr, + PAGE_SIZE << efx->rx_buffer_order, + DMA_FROM_DEVICE); + put_page(page); + } + kfree(rx_queue->page_ring); + rx_queue->page_ring = NULL; } void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) -- cgit From 179ea7f039f68ae4247a340bfb59fd861e7def12 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 7 Mar 2013 16:31:17 +0000 Subject: sfc: Replace efx_rx_is_last_buffer() with a flag This condition is brittle and we have lots of flags to spare. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 1 + drivers/net/ethernet/sfc/rx.c | 17 ++++++----------- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 370c5bcebad9..e22e75c8f635 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -228,6 +228,7 @@ struct efx_rx_buffer { u16 len; u16 flags; }; +#define EFX_RX_BUF_LAST_IN_PAGE 0x0001 #define EFX_RX_PKT_CSUMMED 0x0002 #define EFX_RX_PKT_DISCARD 0x0004 diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index eea56f3ec81c..4cc2ba48a912 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -95,14 +95,6 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, DMA_FROM_DEVICE); } -/* Return true if this is the last RX buffer using a page. */ -static inline bool efx_rx_is_last_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf) -{ - return (rx_buf->page_offset >= (PAGE_SIZE >> 1) || - efx->rx_dma_len > EFX_RX_HALF_PAGE); -} - /* Check the RX page recycle ring for a page that can be reused. */ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) { @@ -199,11 +191,14 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) if ((~count & 1) && (efx->rx_dma_len <= EFX_RX_HALF_PAGE)) { /* Use the second half of the page */ get_page(page); + rx_buf->flags = 0; dma_addr += (PAGE_SIZE >> 1); page_offset += (PAGE_SIZE >> 1); ++count; goto split; } + + rx_buf->flags = EFX_RX_BUF_LAST_IN_PAGE; } return 0; @@ -247,7 +242,7 @@ static void efx_recycle_rx_page(struct efx_channel *channel, unsigned index; /* Only recycle the page after processing the final buffer. */ - if (!efx_rx_is_last_buffer(efx, rx_buf)) + if (!(rx_buf->flags & EFX_RX_BUF_LAST_IN_PAGE)) return; index = rx_queue->page_add & rx_queue->page_ptr_mask; @@ -278,7 +273,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, put_page(rx_buf->page); /* If this is the last buffer in a page, unmap and free it. */ - if (efx_rx_is_last_buffer(rx_queue->efx, rx_buf)) { + if (rx_buf->flags & EFX_RX_BUF_LAST_IN_PAGE) { efx_unmap_rx_buffer(rx_queue->efx, rx_buf); efx_free_rx_buffer(rx_buf); } @@ -507,7 +502,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, struct efx_rx_buffer *rx_buf; rx_buf = efx_rx_buffer(rx_queue, index); - rx_buf->flags = flags; + rx_buf->flags |= flags; /* Validate the number of fragments and completed length */ if (n_frags == 1) { -- cgit From 1648a23fa159e5c433aac06dc5e0d9db36146016 Mon Sep 17 00:00:00 2001 From: Daniel Pieczko Date: Wed, 13 Feb 2013 10:54:41 +0000 Subject: sfc: allocate more RX buffers per page Allocating 2 buffers per page is insanely inefficient when MTU is 1500 and PAGE_SIZE is 64K (as it usually is on POWER). Allocate as many as we can fit, and choose the refill batch size at run-time so that we still always use a whole page at once. [bwh: Fix loop condition to allow for compound pages; rebase] Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 18 +++++--- drivers/net/ethernet/sfc/efx.h | 1 + drivers/net/ethernet/sfc/net_driver.h | 2 + drivers/net/ethernet/sfc/rx.c | 80 ++++++++++++++++++----------------- 4 files changed, 56 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index a70c458f3cef..f050248e9fba 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -643,10 +643,6 @@ static void efx_start_datapath(struct efx_nic *efx) if (rx_buf_len <= PAGE_SIZE) { efx->rx_scatter = false; efx->rx_buffer_order = 0; - if (rx_buf_len <= PAGE_SIZE / 2) - efx->rx_buffer_truesize = PAGE_SIZE / 2; - else - efx->rx_buffer_truesize = PAGE_SIZE; } else if (efx->type->can_rx_scatter) { BUILD_BUG_ON(sizeof(struct efx_rx_page_state) + EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE > @@ -654,14 +650,22 @@ static void efx_start_datapath(struct efx_nic *efx) efx->rx_scatter = true; efx->rx_dma_len = EFX_RX_USR_BUF_SIZE; efx->rx_buffer_order = 0; - efx->rx_buffer_truesize = PAGE_SIZE / 2; } else { efx->rx_scatter = false; efx->rx_buffer_order = get_order(rx_buf_len); - efx->rx_buffer_truesize = PAGE_SIZE << efx->rx_buffer_order; } - efx->rx_bufs_per_page = (rx_buf_len <= PAGE_SIZE / 2) ? 2 : 1; + efx_rx_config_page_split(efx); + if (efx->rx_buffer_order) + netif_dbg(efx, drv, efx->net_dev, + "RX buf len=%u; page order=%u batch=%u\n", + efx->rx_dma_len, efx->rx_buffer_order, + efx->rx_pages_per_batch); + else + netif_dbg(efx, drv, efx->net_dev, + "RX buf len=%u step=%u bpp=%u; page batch=%u\n", + efx->rx_dma_len, efx->rx_page_buf_step, + efx->rx_bufs_per_page, efx->rx_pages_per_batch); /* RX filters also have scatter-enabled flags */ if (efx->rx_scatter != old_rx_scatter) diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 211da79a65e8..8372da239b43 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -33,6 +33,7 @@ extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); /* RX */ +extern void efx_rx_config_page_split(struct efx_nic *efx); extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue); diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index e22e75c8f635..9bd433a095c5 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -825,7 +825,9 @@ struct efx_nic { unsigned int rx_dma_len; unsigned int rx_buffer_order; unsigned int rx_buffer_truesize; + unsigned int rx_page_buf_step; unsigned int rx_bufs_per_page; + unsigned int rx_pages_per_batch; u8 rx_hash_key[40]; u32 rx_indir_table[128]; bool rx_scatter; diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 4cc2ba48a912..a948b36c1910 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -25,19 +25,15 @@ #include "selftest.h" #include "workarounds.h" -/* Number of RX descriptors pushed at once. */ -#define EFX_RX_BATCH 8 +/* Preferred number of descriptors to fill at once */ +#define EFX_RX_PREFERRED_BATCH 8U /* Number of RX buffers to recycle pages for. When creating the RX page recycle * ring, this number is divided by the number of buffers per page to calculate * the number of pages to store in the RX page recycle ring. */ #define EFX_RECYCLE_RING_SIZE_IOMMU 4096 -#define EFX_RECYCLE_RING_SIZE_NOIOMMU (2 * EFX_RX_BATCH) - -/* Maximum length for an RX descriptor sharing a page */ -#define EFX_RX_HALF_PAGE ((PAGE_SIZE >> 1) - sizeof(struct efx_rx_page_state) \ - - EFX_PAGE_IP_ALIGN) +#define EFX_RECYCLE_RING_SIZE_NOIOMMU (2 * EFX_RX_PREFERRED_BATCH) /* Size of buffer allocated for skb header area. */ #define EFX_SKB_HEADERS 64u @@ -95,6 +91,19 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, DMA_FROM_DEVICE); } +void efx_rx_config_page_split(struct efx_nic *efx) +{ + efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + EFX_PAGE_IP_ALIGN, + L1_CACHE_BYTES); + efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : + ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / + efx->rx_page_buf_step); + efx->rx_buffer_truesize = (PAGE_SIZE << efx->rx_buffer_order) / + efx->rx_bufs_per_page; + efx->rx_pages_per_batch = DIV_ROUND_UP(EFX_RX_PREFERRED_BATCH, + efx->rx_bufs_per_page); +} + /* Check the RX page recycle ring for a page that can be reused. */ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) { @@ -134,10 +143,10 @@ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) * * @rx_queue: Efx RX queue * - * This allocates memory for EFX_RX_BATCH receive buffers, maps them for DMA, - * and populates struct efx_rx_buffers for each one. Return a negative error - * code or 0 on success. If a single page can be split between two buffers, - * then the page will either be inserted fully, or not at at all. + * This allocates a batch of pages, maps them for DMA, and populates + * struct efx_rx_buffers for each one. Return a negative error code or + * 0 on success. If a single page can be used for multiple buffers, + * then the page will either be inserted fully, or not at all. */ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) { @@ -149,10 +158,8 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) dma_addr_t dma_addr; unsigned index, count; - /* We can split a page between two buffers */ - BUILD_BUG_ON(EFX_RX_BATCH & 1); - - for (count = 0; count < EFX_RX_BATCH; ++count) { + count = 0; + do { page = efx_reuse_page(rx_queue); if (page == NULL) { page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC, @@ -174,32 +181,26 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) state = page_address(page); dma_addr = state->dma_addr; } - get_page(page); dma_addr += sizeof(struct efx_rx_page_state); page_offset = sizeof(struct efx_rx_page_state); - split: - index = rx_queue->added_count & rx_queue->ptr_mask; - rx_buf = efx_rx_buffer(rx_queue, index); - rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; - rx_buf->page = page; - rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; - rx_buf->len = efx->rx_dma_len; - ++rx_queue->added_count; - - if ((~count & 1) && (efx->rx_dma_len <= EFX_RX_HALF_PAGE)) { - /* Use the second half of the page */ - get_page(page); + do { + index = rx_queue->added_count & rx_queue->ptr_mask; + rx_buf = efx_rx_buffer(rx_queue, index); + rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; + rx_buf->page = page; + rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; + rx_buf->len = efx->rx_dma_len; rx_buf->flags = 0; - dma_addr += (PAGE_SIZE >> 1); - page_offset += (PAGE_SIZE >> 1); - ++count; - goto split; - } + ++rx_queue->added_count; + get_page(page); + dma_addr += efx->rx_page_buf_step; + page_offset += efx->rx_page_buf_step; + } while (page_offset + efx->rx_page_buf_step <= PAGE_SIZE); rx_buf->flags = EFX_RX_BUF_LAST_IN_PAGE; - } + } while (++count < efx->rx_pages_per_batch); return 0; } @@ -307,7 +308,8 @@ static void efx_recycle_rx_buffers(struct efx_channel *channel, */ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) { - unsigned fill_level; + struct efx_nic *efx = rx_queue->efx; + unsigned int fill_level, batch_size; int space, rc = 0; /* Calculate current fill level, and exit if we don't need to fill */ @@ -322,8 +324,9 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) rx_queue->min_fill = fill_level; } + batch_size = efx->rx_pages_per_batch * efx->rx_bufs_per_page; space = rx_queue->max_fill - fill_level; - EFX_BUG_ON_PARANOID(space < EFX_RX_BATCH); + EFX_BUG_ON_PARANOID(space < batch_size); netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" @@ -340,7 +343,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) efx_schedule_slow_fill(rx_queue); goto out; } - } while ((space -= EFX_RX_BATCH) >= EFX_RX_BATCH); + } while ((space -= batch_size) >= batch_size); netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filled descriptor ring " @@ -708,7 +711,8 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) /* Initialise limit fields */ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; - max_trigger = max_fill - EFX_RX_BATCH; + max_trigger = + max_fill - efx->rx_pages_per_batch * efx->rx_bufs_per_page; if (rx_refill_threshold != 0) { trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; if (trigger > max_trigger) -- cgit From faaf02d24ce393032e9b60128cce529d09f7190e Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 6 Mar 2013 15:39:43 +0000 Subject: ixgbe: Make use of the default fdb handlers. For fdb_add, use the default handler in the non-SRIOV case. For the other fdb handlers, just remove them and use the default ones. CC: John Fastabend Acked-By: John Fastabend CC: CC: Gregory Rose Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 42 +-------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index db5611ae407e..e56a3d169e30 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7007,7 +7007,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], int err; if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) - return -EOPNOTSUPP; + return ndo_dflt_fdb_add(ndm, tb, dev, addr, flags); /* Hardware does not support aging addresses so if a * ndm_state is given only allow permanent addresses @@ -7038,44 +7038,6 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], return err; } -static int ixgbe_ndo_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr) -{ - struct ixgbe_adapter *adapter = netdev_priv(dev); - int err = -EOPNOTSUPP; - - if (ndm->ndm_state & NUD_PERMANENT) { - pr_info("%s: FDB only supports static addresses\n", - ixgbe_driver_name); - return -EINVAL; - } - - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - if (is_unicast_ether_addr(addr)) - err = dev_uc_del(dev, addr); - else if (is_multicast_ether_addr(addr)) - err = dev_mc_del(dev, addr); - else - err = -EINVAL; - } - - return err; -} - -static int ixgbe_ndo_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, - int idx) -{ - struct ixgbe_adapter *adapter = netdev_priv(dev); - - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) - idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); - - return idx; -} - static int ixgbe_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh) { @@ -7171,8 +7133,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_features = ixgbe_set_features, .ndo_fix_features = ixgbe_fix_features, .ndo_fdb_add = ixgbe_ndo_fdb_add, - .ndo_fdb_del = ixgbe_ndo_fdb_del, - .ndo_fdb_dump = ixgbe_ndo_fdb_dump, .ndo_bridge_setlink = ixgbe_ndo_bridge_setlink, .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, }; -- cgit From 75a75ee46bab6f580bde5514a08f75f4db1f0a2d Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 6 Mar 2013 15:39:44 +0000 Subject: mlx4: Remove driver specific fdb handlers. Remove driver specific fdb hadlers since they are the same as the default ones. CC: Amir Vadai CC: Yan Burman Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 76 -------------------------- 1 file changed, 76 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index bb4d8d99f36d..4c37d487bb03 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1924,79 +1924,6 @@ static int mlx4_en_set_features(struct net_device *netdev, } -static int mlx4_en_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr, u16 flags) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_dev *mdev = priv->mdev->dev; - int err; - - if (!mlx4_is_mfunc(mdev)) - return -EOPNOTSUPP; - - /* Hardware does not support aging addresses, allow only - * permanent addresses if ndm_state is given - */ - if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) { - en_info(priv, "Add FDB only supports static addresses\n"); - return -EINVAL; - } - - if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) - err = dev_uc_add_excl(dev, addr); - else if (is_multicast_ether_addr(addr)) - err = dev_mc_add_excl(dev, addr); - else - err = -EINVAL; - - /* Only return duplicate errors if NLM_F_EXCL is set */ - if (err == -EEXIST && !(flags & NLM_F_EXCL)) - err = 0; - - return err; -} - -static int mlx4_en_fdb_del(struct ndmsg *ndm, - struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_dev *mdev = priv->mdev->dev; - int err; - - if (!mlx4_is_mfunc(mdev)) - return -EOPNOTSUPP; - - if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) { - en_info(priv, "Del FDB only supports static addresses\n"); - return -EINVAL; - } - - if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) - err = dev_uc_del(dev, addr); - else if (is_multicast_ether_addr(addr)) - err = dev_mc_del(dev, addr); - else - err = -EINVAL; - - return err; -} - -static int mlx4_en_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, int idx) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_dev *mdev = priv->mdev->dev; - - if (mlx4_is_mfunc(mdev)) - idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); - - return idx; -} - static const struct net_device_ops mlx4_netdev_ops = { .ndo_open = mlx4_en_open, .ndo_stop = mlx4_en_close, @@ -2018,9 +1945,6 @@ static const struct net_device_ops mlx4_netdev_ops = { #ifdef CONFIG_RFS_ACCEL .ndo_rx_flow_steer = mlx4_en_filter_rfs, #endif - .ndo_fdb_add = mlx4_en_fdb_add, - .ndo_fdb_del = mlx4_en_fdb_del, - .ndo_fdb_dump = mlx4_en_fdb_dump, }; int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, -- cgit From 3e5c112f5f3a09e7b5a899ef87ce38de83f99f1a Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 6 Mar 2013 15:39:45 +0000 Subject: qlcnic: Use generic fdb handler when driver options are not enabled. Allow qlcnic to use the generic fdb handler when the driver options are not enabled. Untill the driver is fully fixed, this allows the use of the FDB interface with qlogic driver, but simply puts the driver into promisc mode since the driver currently does not support IFF_UNICAST_FLT. CC: Jitendra Kalsaria Acked-by: Jitendra Kalsaria CC: Sony Chacko CC: linux-driver@qlogic.com Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 28a6d4838364..c6f9d5eb7d50 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -253,11 +253,8 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct qlcnic_adapter *adapter = netdev_priv(netdev); int err = -EOPNOTSUPP; - if (!adapter->fdb_mac_learn) { - pr_info("%s: Driver mac learn is enabled, FDB operation not allowed\n", - __func__); - return err; - } + if (!adapter->fdb_mac_learn) + return ndo_dflt_fdb_del(ndm, tb, netdev, addr); if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { if (is_unicast_ether_addr(addr)) @@ -277,11 +274,8 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct qlcnic_adapter *adapter = netdev_priv(netdev); int err = 0; - if (!adapter->fdb_mac_learn) { - pr_info("%s: Driver mac learn is enabled, FDB operation not allowed\n", - __func__); - return -EOPNOTSUPP; - } + if (!adapter->fdb_mac_learn) + return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags); if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { pr_info("%s: FDB e-switch is not enabled\n", __func__); @@ -306,11 +300,8 @@ static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, { struct qlcnic_adapter *adapter = netdev_priv(netdev); - if (!adapter->fdb_mac_learn) { - pr_info("%s: Driver mac learn is enabled, FDB operation not allowed\n", - __func__); - return -EOPNOTSUPP; - } + if (!adapter->fdb_mac_learn) + return ndo_dflt_fdb_dump(skb, ncb, netdev, idx); if (adapter->flags & QLCNIC_ESWITCH_ENABLED) idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); -- cgit From 1caf13ebc8c0809ad6203c0836391ba593b13530 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 6 Mar 2013 17:02:29 +0000 Subject: tg3: Add new FW_TSO flag tg3 used the fw_needed member loosely as a synonym for firmware TSO. Now that the 57766 needs firmware download support, fw_needed can no longer be used like this. This patch creates a new FW_TSO flag and changes the code to use it. Also rearrange all the TSO flags together in the enum. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 11 +++++------ drivers/net/ethernet/broadcom/tg3.h | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index fdb9b5655414..f6ebcaa75b0f 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3618,9 +3618,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err, i; - if (tg3_flag(tp, HW_TSO_1) || - tg3_flag(tp, HW_TSO_2) || - tg3_flag(tp, HW_TSO_3)) + if (!tg3_flag(tp, FW_TSO)) return 0; fw_data = (void *)tp->fw->data; @@ -15293,7 +15291,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) } else if (tg3_asic_rev(tp) != ASIC_REV_5700 && tg3_asic_rev(tp) != ASIC_REV_5701 && tg3_chip_rev_id(tp) != CHIPREV_ID_5705_A0) { - tg3_flag_set(tp, TSO_BUG); + tg3_flag_set(tp, FW_TSO); + tg3_flag_set(tp, TSO_BUG); if (tg3_asic_rev(tp) == ASIC_REV_5705) tp->fw_needed = FIRMWARE_TG3TSO5; else @@ -15304,7 +15303,7 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) if (tg3_flag(tp, HW_TSO_1) || tg3_flag(tp, HW_TSO_2) || tg3_flag(tp, HW_TSO_3) || - tp->fw_needed) { + tg3_flag(tp, FW_TSO)) { /* For firmware TSO, assume ASF is disabled. * We'll disable TSO later if we discover ASF * is enabled in tg3_get_eeprom_hw_cfg(). @@ -15591,7 +15590,7 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) */ tg3_get_eeprom_hw_cfg(tp); - if (tp->fw_needed && tg3_flag(tp, ENABLE_ASF)) { + if (tg3_flag(tp, FW_TSO) && tg3_flag(tp, ENABLE_ASF)) { tg3_flag_clear(tp, TSO_CAPABLE); tg3_flag_clear(tp, TSO_BUG); tp->fw_needed = NULL; diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 8d7d4c2ab5d6..eb41b6f517a1 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -3009,17 +3009,18 @@ enum TG3_FLAGS { TG3_FLAG_JUMBO_CAPABLE, TG3_FLAG_CHIP_RESETTING, TG3_FLAG_INIT_COMPLETE, - TG3_FLAG_TSO_BUG, TG3_FLAG_MAX_RXPEND_64, - TG3_FLAG_TSO_CAPABLE, TG3_FLAG_PCI_EXPRESS, /* BCM5785 + pci_is_pcie() */ TG3_FLAG_ASF_NEW_HANDSHAKE, TG3_FLAG_HW_AUTONEG, TG3_FLAG_IS_NIC, TG3_FLAG_FLASH, + TG3_FLAG_FW_TSO, TG3_FLAG_HW_TSO_1, TG3_FLAG_HW_TSO_2, TG3_FLAG_HW_TSO_3, + TG3_FLAG_TSO_CAPABLE, + TG3_FLAG_TSO_BUG, TG3_FLAG_ICH_WORKAROUND, TG3_FLAG_1SHOT_MSI, TG3_FLAG_NO_FWARE_REPORTED, -- cgit From 837c45bb4eaf367ac738c8d746990da33b3402ee Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 6 Mar 2013 17:02:30 +0000 Subject: tg3: Refactor cpu pause/resume code The 57766 rxcpu needs to be paused/resumed when we download the firmware just like we do for existing firmware. Refactor the pause/resume code to be reusable. This patch also renames the "offset" argument of tg3_halt_cpu to "cpu_base" since that's what it really is. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 83 ++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index f6ebcaa75b0f..35a99f76cb1d 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3452,11 +3452,58 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) #define TX_CPU_SCRATCH_SIZE 0x04000 /* tp->lock is held. */ -static int tg3_halt_cpu(struct tg3 *tp, u32 offset) +static int tg3_pause_cpu(struct tg3 *tp, u32 cpu_base) { int i; + const int iters = 10000; - BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)); + for (i = 0; i < iters; i++) { + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); + if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT) + break; + } + + return (i == iters) ? -EBUSY : 0; +} + +/* tp->lock is held. */ +static int tg3_rxcpu_pause(struct tg3 *tp) +{ + int rc = tg3_pause_cpu(tp, RX_CPU_BASE); + + tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); + tw32_f(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); + udelay(10); + + return rc; +} + +/* tp->lock is held. */ +static int tg3_txcpu_pause(struct tg3 *tp) +{ + return tg3_pause_cpu(tp, TX_CPU_BASE); +} + +/* tp->lock is held. */ +static void tg3_resume_cpu(struct tg3 *tp, u32 cpu_base) +{ + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32_f(cpu_base + CPU_MODE, 0x00000000); +} + +/* tp->lock is held. */ +static void tg3_rxcpu_resume(struct tg3 *tp) +{ + tg3_resume_cpu(tp, RX_CPU_BASE); +} + +/* tp->lock is held. */ +static int tg3_halt_cpu(struct tg3 *tp, u32 cpu_base) +{ + int rc; + + BUG_ON(cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)); if (tg3_asic_rev(tp) == ASIC_REV_5906) { u32 val = tr32(GRC_VCPU_EXT_CTRL); @@ -3464,17 +3511,8 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU); return 0; } - if (offset == RX_CPU_BASE) { - for (i = 0; i < 10000; i++) { - tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_HALT); - if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) - break; - } - - tw32(offset + CPU_STATE, 0xffffffff); - tw32_f(offset + CPU_MODE, CPU_MODE_HALT); - udelay(10); + if (cpu_base == RX_CPU_BASE) { + rc = tg3_rxcpu_pause(tp); } else { /* * There is only an Rx CPU for the 5750 derivative in the @@ -3483,17 +3521,12 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) if (tg3_flag(tp, IS_SSB_CORE)) return 0; - for (i = 0; i < 10000; i++) { - tw32(offset + CPU_STATE, 0xffffffff); - tw32(offset + CPU_MODE, CPU_MODE_HALT); - if (tr32(offset + CPU_MODE) & CPU_MODE_HALT) - break; - } + rc = tg3_txcpu_pause(tp); } - if (i >= 10000) { + if (rc) { netdev_err(tp->dev, "%s timed out, %s CPU\n", - __func__, offset == RX_CPU_BASE ? "RX" : "TX"); + __func__, cpu_base == RX_CPU_BASE ? "RX" : "TX"); return -ENODEV; } @@ -3604,8 +3637,8 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) tr32(RX_CPU_BASE + CPU_PC), info.fw_base); return -ENODEV; } - tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32_f(RX_CPU_BASE + CPU_MODE, 0x00000000); + + tg3_rxcpu_resume(tp); return 0; } @@ -3667,8 +3700,8 @@ static int tg3_load_tso_firmware(struct tg3 *tp) __func__, tr32(cpu_base + CPU_PC), info.fw_base); return -ENODEV; } - tw32(cpu_base + CPU_STATE, 0xffffffff); - tw32_f(cpu_base + CPU_MODE, 0x00000000); + + tg3_resume_cpu(tp, cpu_base); return 0; } -- cgit From f4bffb28d66c735a11859024fa0cae60711d313e Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 6 Mar 2013 17:02:31 +0000 Subject: tg3: Refactor the 2nd type of cpu pause For completeness and consistency, add common function tg3_pause_cpu_and_set_pc(). This is only for existing fw and not used for the 57766. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 35a99f76cb1d..470516918248 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3588,12 +3588,33 @@ out: return err; } +/* tp->lock is held. */ +static int tg3_pause_cpu_and_set_pc(struct tg3 *tp, u32 cpu_base, u32 pc) +{ + int i; + const int iters = 5; + + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32_f(cpu_base + CPU_PC, pc); + + for (i = 0; i < iters; i++) { + if (tr32(cpu_base + CPU_PC) == pc) + break; + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); + tw32_f(cpu_base + CPU_PC, pc); + udelay(1000); + } + + return (i == iters) ? -EBUSY : 0; +} + /* tp->lock is held. */ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) { struct fw_info info; const __be32 *fw_data; - int err, i; + int err; fw_data = (void *)tp->fw->data; @@ -3620,18 +3641,8 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) return err; /* Now startup only the RX cpu. */ - tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base); - - for (i = 0; i < 5; i++) { - if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base) - break; - tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); - tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base); - udelay(1000); - } - if (i >= 5) { + err = tg3_pause_cpu_and_set_pc(tp, RX_CPU_BASE, info.fw_base); + if (err) { netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x " "should be %08x\n", __func__, tr32(RX_CPU_BASE + CPU_PC), info.fw_base); @@ -3649,7 +3660,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) struct fw_info info; const __be32 *fw_data; unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; - int err, i; + int err; if (!tg3_flag(tp, FW_TSO)) return 0; @@ -3683,18 +3694,8 @@ static int tg3_load_tso_firmware(struct tg3 *tp) return err; /* Now startup the cpu. */ - tw32(cpu_base + CPU_STATE, 0xffffffff); - tw32_f(cpu_base + CPU_PC, info.fw_base); - - for (i = 0; i < 5; i++) { - if (tr32(cpu_base + CPU_PC) == info.fw_base) - break; - tw32(cpu_base + CPU_STATE, 0xffffffff); - tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); - tw32_f(cpu_base + CPU_PC, info.fw_base); - udelay(1000); - } - if (i >= 5) { + err = tg3_pause_cpu_and_set_pc(tp, cpu_base, info.fw_base); + if (err) { netdev_err(tp->dev, "%s fails to set CPU PC, is %08x should be %08x\n", __func__, tr32(cpu_base + CPU_PC), info.fw_base); -- cgit From 77997ea3f4ac84e6275bc3d6051956eee54f901a Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 6 Mar 2013 17:02:32 +0000 Subject: tg3: Cleanup firmware parsing code The current firmware header parsing is complicated due to interpreting it as a u32 array and accessing header members via array offsets. Add tg3_firmware_hdr structure to access the firmware fields instead of hardcoding offsets. The same header format will be used for individual firmware fragments in the 57766. The fw_hdr and tg3 structures have all the information required for loading the fw. Remove the redundant fw_info structure and pass fw_hdr instead. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 63 ++++++++++++++++--------------------- drivers/net/ethernet/broadcom/tg3.h | 7 +++++ 2 files changed, 34 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 470516918248..87bd0e3cea7d 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3536,19 +3536,14 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 cpu_base) return 0; } -struct fw_info { - unsigned int fw_base; - unsigned int fw_len; - const __be32 *fw_data; -}; - /* tp->lock is held. */ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, int cpu_scratch_size, - struct fw_info *info) + const struct tg3_firmware_hdr *fw_hdr) { int err, lock_err, i; void (*write_op)(struct tg3 *, u32, u32); + u32 *fw_data = (u32 *)(fw_hdr + 1); if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) { netdev_err(tp->dev, @@ -3576,11 +3571,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, write_op(tp, cpu_scratch_base + i, 0); tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); - for (i = 0; i < (info->fw_len / sizeof(u32)); i++) - write_op(tp, (cpu_scratch_base + - (info->fw_base & 0xffff) + - (i * sizeof(u32))), - be32_to_cpu(info->fw_data[i])); + for (i = 0; i < (tp->fw->size - TG3_FW_HDR_LEN) / sizeof(u32); i++) + write_op(tp, cpu_scratch_base + + (be32_to_cpu(fw_hdr->base_addr) & 0xffff) + + (i * sizeof(u32)), + be32_to_cpu(fw_data[i])); + err = 0; @@ -3612,11 +3608,10 @@ static int tg3_pause_cpu_and_set_pc(struct tg3 *tp, u32 cpu_base, u32 pc) /* tp->lock is held. */ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) { - struct fw_info info; - const __be32 *fw_data; + const struct tg3_firmware_hdr *fw_hdr; int err; - fw_data = (void *)tp->fw->data; + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; /* Firmware blob starts with version numbers, followed by start address and length. We are setting complete length. @@ -3624,28 +3619,26 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) Remainder is the blob to be loaded contiguously from start address. */ - info.fw_base = be32_to_cpu(fw_data[1]); - info.fw_len = tp->fw->size - 12; - info.fw_data = &fw_data[3]; - err = tg3_load_firmware_cpu(tp, RX_CPU_BASE, RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE, - &info); + fw_hdr); if (err) return err; err = tg3_load_firmware_cpu(tp, TX_CPU_BASE, TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE, - &info); + fw_hdr); if (err) return err; /* Now startup only the RX cpu. */ - err = tg3_pause_cpu_and_set_pc(tp, RX_CPU_BASE, info.fw_base); + err = tg3_pause_cpu_and_set_pc(tp, RX_CPU_BASE, + be32_to_cpu(fw_hdr->base_addr)); if (err) { netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x " "should be %08x\n", __func__, - tr32(RX_CPU_BASE + CPU_PC), info.fw_base); + tr32(RX_CPU_BASE + CPU_PC), + be32_to_cpu(fw_hdr->base_addr)); return -ENODEV; } @@ -3657,15 +3650,14 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) /* tp->lock is held. */ static int tg3_load_tso_firmware(struct tg3 *tp) { - struct fw_info info; - const __be32 *fw_data; + const struct tg3_firmware_hdr *fw_hdr; unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err; if (!tg3_flag(tp, FW_TSO)) return 0; - fw_data = (void *)tp->fw->data; + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; /* Firmware blob starts with version numbers, followed by start address and length. We are setting complete length. @@ -3673,10 +3665,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) Remainder is the blob to be loaded contiguously from start address. */ - info.fw_base = be32_to_cpu(fw_data[1]); cpu_scratch_size = tp->fw_len; - info.fw_len = tp->fw->size - 12; - info.fw_data = &fw_data[3]; if (tg3_asic_rev(tp) == ASIC_REV_5705) { cpu_base = RX_CPU_BASE; @@ -3689,16 +3678,18 @@ static int tg3_load_tso_firmware(struct tg3 *tp) err = tg3_load_firmware_cpu(tp, cpu_base, cpu_scratch_base, cpu_scratch_size, - &info); + fw_hdr); if (err) return err; /* Now startup the cpu. */ - err = tg3_pause_cpu_and_set_pc(tp, cpu_base, info.fw_base); + err = tg3_pause_cpu_and_set_pc(tp, cpu_base, + be32_to_cpu(fw_hdr->base_addr)); if (err) { netdev_err(tp->dev, "%s fails to set CPU PC, is %08x should be %08x\n", - __func__, tr32(cpu_base + CPU_PC), info.fw_base); + __func__, tr32(cpu_base + CPU_PC), + be32_to_cpu(fw_hdr->base_addr)); return -ENODEV; } @@ -10598,7 +10589,7 @@ static int tg3_test_msi(struct tg3 *tp) static int tg3_request_firmware(struct tg3 *tp) { - const __be32 *fw_data; + const struct tg3_firmware_hdr *fw_hdr; if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", @@ -10606,15 +10597,15 @@ static int tg3_request_firmware(struct tg3 *tp) return -ENOENT; } - fw_data = (void *)tp->fw->data; + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; /* Firmware blob starts with version numbers, followed by * start address and _full_ length including BSS sections * (which must be longer than the actual data, of course */ - tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ - if (tp->fw_len < (tp->fw->size - 12)) { + tp->fw_len = be32_to_cpu(fw_hdr->len); /* includes bss */ + if (tp->fw_len < (tp->fw->size - TG3_FW_HDR_LEN)) { netdev_err(tp->dev, "bogus length %d in \"%s\"\n", tp->fw_len, tp->fw_needed); release_firmware(tp->fw); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index eb41b6f517a1..b5098f0d0e8f 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -3065,6 +3065,13 @@ enum TG3_FLAGS { TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */ }; +struct tg3_firmware_hdr { + __be32 version; /* unused for fragments */ + __be32 base_addr; + __be32 len; +}; +#define TG3_FW_HDR_LEN (sizeof(struct tg3_firmware_hdr)) + struct tg3 { /* begin "general, frequently-used members" cacheline section */ -- cgit From 31f11a951f1b5d262186e741ca019e572a3fafe4 Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 6 Mar 2013 17:02:33 +0000 Subject: tg3: Enhance firmware download code to support fragmented firmware This lays the ground work to download the 57766 fragmented firmware. We loop until we've written data equal to tp->fw->size minus headers. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 48 ++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 87bd0e3cea7d..54f604bbaeac 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -3536,6 +3536,33 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 cpu_base) return 0; } +static int tg3_fw_data_len(struct tg3 *tp, + const struct tg3_firmware_hdr *fw_hdr) +{ + int fw_len; + + /* Non fragmented firmware have one firmware header followed by a + * contiguous chunk of data to be written. The length field in that + * header is not the length of data to be written but the complete + * length of the bss. The data length is determined based on + * tp->fw->size minus headers. + * + * Fragmented firmware have a main header followed by multiple + * fragments. Each fragment is identical to non fragmented firmware + * with a firmware header followed by a contiguous chunk of data. In + * the main header, the length field is unused and set to 0xffffffff. + * In each fragment header the length is the entire size of that + * fragment i.e. fragment data + header length. Data length is + * therefore length field in the header minus TG3_FW_HDR_LEN. + */ + if (tp->fw_len == 0xffffffff) + fw_len = be32_to_cpu(fw_hdr->len); + else + fw_len = tp->fw->size; + + return (fw_len - TG3_FW_HDR_LEN) / sizeof(u32); +} + /* tp->lock is held. */ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, int cpu_scratch_size, @@ -3543,7 +3570,7 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, { int err, lock_err, i; void (*write_op)(struct tg3 *, u32, u32); - u32 *fw_data = (u32 *)(fw_hdr + 1); + int total_len = tp->fw->size; if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) { netdev_err(tp->dev, @@ -3571,12 +3598,21 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, write_op(tp, cpu_scratch_base + i, 0); tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); - for (i = 0; i < (tp->fw->size - TG3_FW_HDR_LEN) / sizeof(u32); i++) - write_op(tp, cpu_scratch_base + - (be32_to_cpu(fw_hdr->base_addr) & 0xffff) + - (i * sizeof(u32)), - be32_to_cpu(fw_data[i])); + do { + u32 *fw_data = (u32 *)(fw_hdr + 1); + for (i = 0; i < tg3_fw_data_len(tp, fw_hdr); i++) + write_op(tp, cpu_scratch_base + + (be32_to_cpu(fw_hdr->base_addr) & 0xffff) + + (i * sizeof(u32)), + be32_to_cpu(fw_data[i])); + + total_len -= be32_to_cpu(fw_hdr->len); + + /* Advance to next fragment */ + fw_hdr = (struct tg3_firmware_hdr *) + ((void *)fw_hdr + be32_to_cpu(fw_hdr->len)); + } while (total_len > 0); err = 0; -- cgit From c4dab50697ff220e35f7b4464418c5893de4e699 Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 6 Mar 2013 17:02:34 +0000 Subject: tg3: Download 57766 EEE service patch firmware This patch downloads the EEE service patch firmware and enables the necessary EEE flags. Reviewed-by: Benjamin Li Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 138 +++++++++++++++++++++++++++++++----- drivers/net/ethernet/broadcom/tg3.h | 6 ++ 2 files changed, 128 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 54f604bbaeac..2b2bee61ddd7 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -212,6 +212,7 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define TG3_FW_UPDATE_FREQ_SEC (TG3_FW_UPDATE_TIMEOUT_SEC / 2) #define FIRMWARE_TG3 "tigon/tg3.bin" +#define FIRMWARE_TG357766 "tigon/tg357766.bin" #define FIRMWARE_TG3TSO "tigon/tg3_tso.bin" #define FIRMWARE_TG3TSO5 "tigon/tg3_tso5.bin" @@ -3568,7 +3569,7 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, int cpu_scratch_size, const struct tg3_firmware_hdr *fw_hdr) { - int err, lock_err, i; + int err, i; void (*write_op)(struct tg3 *, u32, u32); int total_len = tp->fw->size; @@ -3579,25 +3580,34 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, return -EINVAL; } - if (tg3_flag(tp, 5705_PLUS)) + if (tg3_flag(tp, 5705_PLUS) && tg3_asic_rev(tp) != ASIC_REV_57766) write_op = tg3_write_mem; else write_op = tg3_write_indirect_reg32; - /* It is possible that bootcode is still loading at this point. - * Get the nvram lock first before halting the cpu. - */ - lock_err = tg3_nvram_lock(tp); - err = tg3_halt_cpu(tp, cpu_base); - if (!lock_err) - tg3_nvram_unlock(tp); - if (err) - goto out; + if (tg3_asic_rev(tp) != ASIC_REV_57766) { + /* It is possible that bootcode is still loading at this point. + * Get the nvram lock first before halting the cpu. + */ + int lock_err = tg3_nvram_lock(tp); + err = tg3_halt_cpu(tp, cpu_base); + if (!lock_err) + tg3_nvram_unlock(tp); + if (err) + goto out; - for (i = 0; i < cpu_scratch_size; i += sizeof(u32)) - write_op(tp, cpu_scratch_base + i, 0); - tw32(cpu_base + CPU_STATE, 0xffffffff); - tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); + for (i = 0; i < cpu_scratch_size; i += sizeof(u32)) + write_op(tp, cpu_scratch_base + i, 0); + tw32(cpu_base + CPU_STATE, 0xffffffff); + tw32(cpu_base + CPU_MODE, + tr32(cpu_base + CPU_MODE) | CPU_MODE_HALT); + } else { + /* Subtract additional main header for fragmented firmware and + * advance to the first fragment + */ + total_len -= TG3_FW_HDR_LEN; + fw_hdr++; + } do { u32 *fw_data = (u32 *)(fw_hdr + 1); @@ -3683,6 +3693,78 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) return 0; } +static int tg3_validate_rxcpu_state(struct tg3 *tp) +{ + const int iters = 1000; + int i; + u32 val; + + /* Wait for boot code to complete initialization and enter service + * loop. It is then safe to download service patches + */ + for (i = 0; i < iters; i++) { + if (tr32(RX_CPU_HWBKPT) == TG3_SBROM_IN_SERVICE_LOOP) + break; + + udelay(10); + } + + if (i == iters) { + netdev_err(tp->dev, "Boot code not ready for service patches\n"); + return -EBUSY; + } + + val = tg3_read_indirect_reg32(tp, TG3_57766_FW_HANDSHAKE); + if (val & 0xff) { + netdev_warn(tp->dev, + "Other patches exist. Not downloading EEE patch\n"); + return -EEXIST; + } + + return 0; +} + +/* tp->lock is held. */ +static void tg3_load_57766_firmware(struct tg3 *tp) +{ + struct tg3_firmware_hdr *fw_hdr; + + if (!tg3_flag(tp, NO_NVRAM)) + return; + + if (tg3_validate_rxcpu_state(tp)) + return; + + if (!tp->fw) + return; + + /* This firmware blob has a different format than older firmware + * releases as given below. The main difference is we have fragmented + * data to be written to non-contiguous locations. + * + * In the beginning we have a firmware header identical to other + * firmware which consists of version, base addr and length. The length + * here is unused and set to 0xffffffff. + * + * This is followed by a series of firmware fragments which are + * individually identical to previous firmware. i.e. they have the + * firmware header and followed by data for that fragment. The version + * field of the individual fragment header is unused. + */ + + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; + if (be32_to_cpu(fw_hdr->base_addr) != TG3_57766_FW_BASE_ADDR) + return; + + if (tg3_rxcpu_pause(tp)) + return; + + /* tg3_load_firmware_cpu() will always succeed for the 57766 */ + tg3_load_firmware_cpu(tp, 0, TG3_57766_FW_BASE_ADDR, 0, fw_hdr); + + tg3_rxcpu_resume(tp); +} + /* tp->lock is held. */ static int tg3_load_tso_firmware(struct tg3 *tp) { @@ -9836,6 +9918,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) return err; } + if (tg3_asic_rev(tp) == ASIC_REV_57766) { + /* Ignore any errors for the firmware download. If download + * fails, the device will operate with EEE disabled + */ + tg3_load_57766_firmware(tp); + } + if (tg3_flag(tp, TSO_CAPABLE)) { err = tg3_load_tso_firmware(tp); if (err) @@ -10940,7 +11029,15 @@ static int tg3_open(struct net_device *dev) if (tp->fw_needed) { err = tg3_request_firmware(tp); - if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) { + if (tg3_asic_rev(tp) == ASIC_REV_57766) { + if (err) { + netdev_warn(tp->dev, "EEE capability disabled\n"); + tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP; + } else if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) { + netdev_warn(tp->dev, "EEE capability restored\n"); + tp->phy_flags |= TG3_PHYFLG_EEE_CAP; + } + } else if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) { if (err) return err; } else if (err) { @@ -14570,6 +14667,7 @@ static int tg3_phy_probe(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && (tg3_asic_rev(tp) == ASIC_REV_5719 || tg3_asic_rev(tp) == ASIC_REV_5720 || + tg3_asic_rev(tp) == ASIC_REV_57766 || tg3_asic_rev(tp) == ASIC_REV_5762 || (tg3_asic_rev(tp) == ASIC_REV_5717 && tg3_chip_rev_id(tp) != CHIPREV_ID_5717_A0) || @@ -15379,6 +15477,9 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) if (tg3_chip_rev_id(tp) == CHIPREV_ID_5701_A0) tp->fw_needed = FIRMWARE_TG3; + if (tg3_asic_rev(tp) == ASIC_REV_57766) + tp->fw_needed = FIRMWARE_TG357766; + tp->irq_max = 1; if (tg3_flag(tp, 5750_PLUS)) { @@ -15839,6 +15940,11 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) udelay(50); tg3_nvram_init(tp); + /* If the device has an NVRAM, no need to load patch firmware */ + if (tg3_asic_rev(tp) == ASIC_REV_57766 && + !tg3_flag(tp, NO_NVRAM)) + tp->fw_needed = NULL; + grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index b5098f0d0e8f..1cdc1b641c77 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -2222,6 +2222,12 @@ #define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000 #define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000 +#define TG3_SRAM_RXCPU_SCRATCH_BASE_57766 0x00030000 +#define TG3_SRAM_RXCPU_SCRATCH_SIZE_57766 0x00010000 +#define TG3_57766_FW_BASE_ADDR 0x00030000 +#define TG3_57766_FW_HANDSHAKE 0x0003fccc +#define TG3_SBROM_IN_SERVICE_LOOP 0x51 + #define TG3_SRAM_RX_STD_BDCACHE_SIZE_5700 128 #define TG3_SRAM_RX_STD_BDCACHE_SIZE_5755 64 #define TG3_SRAM_RX_STD_BDCACHE_SIZE_5906 32 -- cgit From c7bb15a66cfd144ceaa32dea5c287118d5bdb9b5 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 6 Mar 2013 20:05:05 +0000 Subject: be2net: Update copyright year Signed-off-by: Vasundhara Volam Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 2 +- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +- drivers/net/ethernet/emulex/benet/be_ethtool.c | 2 +- drivers/net/ethernet/emulex/benet/be_hw.h | 2 +- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- drivers/net/ethernet/emulex/benet/be_roce.c | 2 +- drivers/net/ethernet/emulex/benet/be_roce.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 28ceb8414185..ff1efe55ceee 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 071aea79d218..4512e42596d4 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 96970860c915..6ef4575ce1c8 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 76b302f30c87..053f00d006c0 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 541d4530d5bf..c515eeaaa5d6 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3860888ac711..1f8103c0afbf 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c index 55d32aa0a093..f3d126dcc104 100644 --- a/drivers/net/ethernet/emulex/benet/be_roce.c +++ b/drivers/net/ethernet/emulex/benet/be_roce.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h index db4ea8081c07..276572998463 100644 --- a/drivers/net/ethernet/emulex/benet/be_roce.h +++ b/drivers/net/ethernet/emulex/benet/be_roce.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2011 Emulex + * Copyright (C) 2005 - 2013 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or -- cgit From 11e5e76eb4c8fc9763caf4e52e30499bfb4dcf77 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 01:53:28 +0000 Subject: bgmac: register MII bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 80 ++++++++++++++++++++++++++++++++++- drivers/net/ethernet/broadcom/bgmac.h | 1 + 2 files changed, 80 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index da5f4397f87c..d6cb376b71e6 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1312,6 +1313,73 @@ static const struct ethtool_ops bgmac_ethtool_ops = { .get_drvinfo = bgmac_get_drvinfo, }; +/************************************************** + * MII + **************************************************/ + +static int bgmac_mii_read(struct mii_bus *bus, int mii_id, int regnum) +{ + return bgmac_phy_read(bus->priv, mii_id, regnum); +} + +static int bgmac_mii_write(struct mii_bus *bus, int mii_id, int regnum, + u16 value) +{ + return bgmac_phy_write(bus->priv, mii_id, regnum, value); +} + +static int bgmac_mii_register(struct bgmac *bgmac) +{ + struct mii_bus *mii_bus; + int i, err = 0; + + mii_bus = mdiobus_alloc(); + if (!mii_bus) + return -ENOMEM; + + mii_bus->name = "bgmac mii bus"; + sprintf(mii_bus->id, "%s-%d-%d", "bgmac", bgmac->core->bus->num, + bgmac->core->core_unit); + mii_bus->priv = bgmac; + mii_bus->read = bgmac_mii_read; + mii_bus->write = bgmac_mii_write; + mii_bus->parent = &bgmac->core->dev; + mii_bus->phy_mask = ~(1 << bgmac->phyaddr); + + mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); + if (!mii_bus->irq) { + err = -ENOMEM; + goto err_free_bus; + } + for (i = 0; i < PHY_MAX_ADDR; i++) + mii_bus->irq[i] = PHY_POLL; + + err = mdiobus_register(mii_bus); + if (err) { + bgmac_err(bgmac, "Registration of mii bus failed\n"); + goto err_free_irq; + } + + bgmac->mii_bus = mii_bus; + + return err; + +err_free_irq: + kfree(mii_bus->irq); +err_free_bus: + mdiobus_free(mii_bus); + return err; +} + +static void bgmac_mii_unregister(struct bgmac *bgmac) +{ + struct mii_bus *mii_bus = bgmac->mii_bus; + + mdiobus_unregister(mii_bus); + kfree(mii_bus->irq); + mdiobus_free(mii_bus); +} + /************************************************** * BCMA bus ops **************************************************/ @@ -1404,11 +1472,18 @@ static int bgmac_probe(struct bcma_device *core) if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); + err = bgmac_mii_register(bgmac); + if (err) { + bgmac_err(bgmac, "Cannot register MDIO\n"); + err = -ENOTSUPP; + goto err_dma_free; + } + err = register_netdev(bgmac->net_dev); if (err) { bgmac_err(bgmac, "Cannot register net device\n"); err = -ENOTSUPP; - goto err_dma_free; + goto err_mii_unregister; } netif_carrier_off(net_dev); @@ -1417,6 +1492,8 @@ static int bgmac_probe(struct bcma_device *core) return 0; +err_mii_unregister: + bgmac_mii_unregister(bgmac); err_dma_free: bgmac_dma_free(bgmac); @@ -1433,6 +1510,7 @@ static void bgmac_remove(struct bcma_device *core) netif_napi_del(&bgmac->napi); unregister_netdev(bgmac->net_dev); + bgmac_mii_unregister(bgmac); bgmac_dma_free(bgmac); bcma_set_drvdata(core, NULL); free_netdev(bgmac->net_dev); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 4ede614c81f8..98d4b5fcc070 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -399,6 +399,7 @@ struct bgmac { struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */ struct net_device *net_dev; struct napi_struct napi; + struct mii_bus *mii_bus; /* DMA */ struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS]; -- cgit From 7791c623b3826ab9dac6fe0bca770776a5e6c4ce Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 7 Mar 2013 13:50:47 -0500 Subject: staging: zcache/debug: compiler failure on PPC64 and revert commit. On PPC64 we get this: In file included from drivers/staging/zcache/debug.c:2: drivers/staging/zcache/debug.h: In function 'dec_zcache_obj_count': drivers/staging/zcache/debug.h:16: error: implicit declaration of function 'BUG_ON' This simple patch adds the appropiate header file to finish the compile and reverts "staging: zcache: disable ZCACHE_DEBUG due to build error" (5db5a20a50cfd078c78b13a988f237cca81aedc5) Reported-by: Stephen Rothwell Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 1 - drivers/staging/zcache/debug.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index ad47b4b8f04b..2da6cc444c7e 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -13,7 +13,6 @@ config ZCACHE config ZCACHE_DEBUG bool "Enable debug statistics" depends on DEBUG_FS && ZCACHE - depends on BROKEN default n help This is used to provide an debugfs directory with counters of diff --git a/drivers/staging/zcache/debug.h b/drivers/staging/zcache/debug.h index eef67dbe78d8..4bbe49b73d49 100644 --- a/drivers/staging/zcache/debug.h +++ b/drivers/staging/zcache/debug.h @@ -1,3 +1,5 @@ +#include + #ifdef CONFIG_ZCACHE_DEBUG /* we try to keep these statistics SMP-consistent */ -- cgit From c791126b93e800c68557483235321b201c082910 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 25 Feb 2013 17:15:47 +0900 Subject: pwm_backlight: remove unnecessary ifdefs When the macro such as SIMPLE_DEV_PM_OPS is used, there is no need to use '#ifdef CONFIG_PM' to prevent build error. Thus, this patch removes unnecessary ifdefs. Signed-off-by: Jingoo Han Cc: Thierry Reding Signed-off-by: Thierry Reding --- drivers/video/backlight/pwm_bl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index fa00304a63d8..1fea627394d7 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -274,7 +274,7 @@ static int pwm_backlight_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int pwm_backlight_suspend(struct device *dev) { struct backlight_device *bl = dev_get_drvdata(dev); @@ -296,19 +296,16 @@ static int pwm_backlight_resume(struct device *dev) backlight_update_status(bl); return 0; } +#endif static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend, pwm_backlight_resume); -#endif - static struct platform_driver pwm_backlight_driver = { .driver = { .name = "pwm-backlight", .owner = THIS_MODULE, -#ifdef CONFIG_PM .pm = &pwm_backlight_pm_ops, -#endif .of_match_table = of_match_ptr(pwm_backlight_of_match), }, .probe = pwm_backlight_probe, -- cgit From 482467ad97b633b28f57c347440d97c108dc4bfb Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 8 Mar 2013 12:45:58 +0900 Subject: pwm: ab8500: use devm_kzalloc() Use devm_kzalloc() to make cleanup paths more simple. Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-ab8500.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index 4248d0418273..93af1bbf88ce 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c @@ -99,7 +99,7 @@ static int ab8500_pwm_probe(struct platform_device *pdev) * Nothing to be done in probe, this is required to get the * device which is required for ab8500 read and write */ - ab8500 = kzalloc(sizeof(*ab8500), GFP_KERNEL); + ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); if (ab8500 == NULL) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; @@ -111,10 +111,8 @@ static int ab8500_pwm_probe(struct platform_device *pdev) ab8500->chip.npwm = 1; err = pwmchip_add(&ab8500->chip); - if (err < 0) { - kfree(ab8500); + if (err < 0) return err; - } dev_dbg(&pdev->dev, "pwm probe successful\n"); platform_set_drvdata(pdev, ab8500); @@ -132,7 +130,6 @@ static int ab8500_pwm_remove(struct platform_device *pdev) return err; dev_dbg(&pdev->dev, "pwm driver removed\n"); - kfree(ab8500); return 0; } -- cgit From c509a8e521939ca1fd4ba31feca4718328044230 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 8 Mar 2013 13:03:31 +0900 Subject: pwm: samsung: convert s3c_pwm to dev_pm_ops Instead of using legacy suspend/resume methods, using newer dev_pm_ops structure allows better control over power management. Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-samsung.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index 5207e6cd8648..a0ece50d70bb 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -289,10 +289,10 @@ static int s3c_pwm_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int s3c_pwm_suspend(struct device *dev) { - struct s3c_chip *s3c = platform_get_drvdata(pdev); + struct s3c_chip *s3c = dev_get_drvdata(dev); /* No one preserve these values during suspend so reset them * Otherwise driver leaves PWM unconfigured if same values @@ -304,9 +304,9 @@ static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int s3c_pwm_resume(struct platform_device *pdev) +static int s3c_pwm_resume(struct device *dev) { - struct s3c_chip *s3c = platform_get_drvdata(pdev); + struct s3c_chip *s3c = dev_get_drvdata(dev); unsigned long tcon; /* Restore invertion */ @@ -316,21 +316,19 @@ static int s3c_pwm_resume(struct platform_device *pdev) return 0; } - -#else -#define s3c_pwm_suspend NULL -#define s3c_pwm_resume NULL #endif +static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend, + s3c_pwm_resume); + static struct platform_driver s3c_pwm_driver = { .driver = { .name = "s3c24xx-pwm", .owner = THIS_MODULE, + .pm = &s3c_pwm_pm_ops, }, .probe = s3c_pwm_probe, .remove = s3c_pwm_remove, - .suspend = s3c_pwm_suspend, - .resume = s3c_pwm_resume, }; static int __init pwm_init(void) -- cgit From e757e3e198795bfc56a28b41c494bcb27c0ee2ab Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 31 Jan 2013 07:43:22 +0000 Subject: ixgbevf: Make next_to_watch a pointer and adjust memory barriers to avoid races This change is meant to address several race issues that become possible because next_to_watch could possibly be set to a value that shows that the descriptor is done when it is not. In order to correct that we instead make next_to_watch a pointer that is set to NULL during cleanup, and set to the eop_desc after the descriptor rings have been written. To enforce proper ordering the next_to_watch pointer is not set until after a wmb writing the values to the last descriptor in a transmit. In order to guarantee that the descriptor is not read until after the eop_desc we use the read_barrier_depends which is only really necessary on the alpha architecture. Signed-off-by: Alexander Duyck Acked-by: Greg Rose Tested-by: Sibai Li Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 2 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 71 +++++++++++++---------- 2 files changed, 40 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index fc0af9a3bb35..fff0d9867529 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -44,8 +44,8 @@ struct ixgbevf_tx_buffer { struct sk_buff *skb; dma_addr_t dma; unsigned long time_stamp; + union ixgbe_adv_tx_desc *next_to_watch; u16 length; - u16 next_to_watch; u16 mapped_as_page; }; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index c3db6cd69b68..20736eb567d8 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -190,28 +190,37 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_adapter *adapter = q_vector->adapter; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbevf_tx_buffer *tx_buffer_info; - unsigned int i, eop, count = 0; + unsigned int i, count = 0; unsigned int total_bytes = 0, total_packets = 0; if (test_bit(__IXGBEVF_DOWN, &adapter->state)) return true; i = tx_ring->next_to_clean; - eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBEVF_TX_DESC(tx_ring, eop); + tx_buffer_info = &tx_ring->tx_buffer_info[i]; + eop_desc = tx_buffer_info->next_to_watch; - while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && - (count < tx_ring->count)) { + do { bool cleaned = false; - rmb(); /* read buffer_info after eop_desc */ - /* eop could change between read and DD-check */ - if (unlikely(eop != tx_ring->tx_buffer_info[i].next_to_watch)) - goto cont_loop; + + /* if next_to_watch is not set then there is no work pending */ + if (!eop_desc) + break; + + /* prevent any other reads prior to eop_desc */ + read_barrier_depends(); + + /* if DD is not set pending work has not been completed */ + if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) + break; + + /* clear next_to_watch to prevent false hangs */ + tx_buffer_info->next_to_watch = NULL; + for ( ; !cleaned; count++) { struct sk_buff *skb; tx_desc = IXGBEVF_TX_DESC(tx_ring, i); - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - cleaned = (i == eop); + cleaned = (tx_desc == eop_desc); skb = tx_buffer_info->skb; if (cleaned && skb) { @@ -234,12 +243,12 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, i++; if (i == tx_ring->count) i = 0; + + tx_buffer_info = &tx_ring->tx_buffer_info[i]; } -cont_loop: - eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBEVF_TX_DESC(tx_ring, eop); - } + eop_desc = tx_buffer_info->next_to_watch; + } while (count < tx_ring->count); tx_ring->next_to_clean = i; @@ -2806,8 +2815,7 @@ static bool ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring, } static int ixgbevf_tx_map(struct ixgbevf_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - unsigned int first) + struct sk_buff *skb, u32 tx_flags) { struct ixgbevf_tx_buffer *tx_buffer_info; unsigned int len; @@ -2832,7 +2840,6 @@ static int ixgbevf_tx_map(struct ixgbevf_ring *tx_ring, size, DMA_TO_DEVICE); if (dma_mapping_error(tx_ring->dev, tx_buffer_info->dma)) goto dma_error; - tx_buffer_info->next_to_watch = i; len -= size; total -= size; @@ -2862,7 +2869,6 @@ static int ixgbevf_tx_map(struct ixgbevf_ring *tx_ring, tx_buffer_info->dma)) goto dma_error; tx_buffer_info->mapped_as_page = true; - tx_buffer_info->next_to_watch = i; len -= size; total -= size; @@ -2881,8 +2887,6 @@ static int ixgbevf_tx_map(struct ixgbevf_ring *tx_ring, else i = i - 1; tx_ring->tx_buffer_info[i].skb = skb; - tx_ring->tx_buffer_info[first].next_to_watch = i; - tx_ring->tx_buffer_info[first].time_stamp = jiffies; return count; @@ -2891,7 +2895,6 @@ dma_error: /* clear timestamp and dma mappings for failed tx_buffer_info map */ tx_buffer_info->dma = 0; - tx_buffer_info->next_to_watch = 0; count--; /* clear timestamp and dma mappings for remaining portion of packet */ @@ -2908,7 +2911,8 @@ dma_error: } static void ixgbevf_tx_queue(struct ixgbevf_ring *tx_ring, int tx_flags, - int count, u32 paylen, u8 hdr_len) + int count, unsigned int first, u32 paylen, + u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; struct ixgbevf_tx_buffer *tx_buffer_info; @@ -2959,6 +2963,16 @@ static void ixgbevf_tx_queue(struct ixgbevf_ring *tx_ring, int tx_flags, tx_desc->read.cmd_type_len |= cpu_to_le32(txd_cmd); + tx_ring->tx_buffer_info[first].time_stamp = jiffies; + + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + + tx_ring->tx_buffer_info[first].next_to_watch = tx_desc; tx_ring->next_to_use = i; } @@ -3050,15 +3064,8 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_flags |= IXGBE_TX_FLAGS_CSUM; ixgbevf_tx_queue(tx_ring, tx_flags, - ixgbevf_tx_map(tx_ring, skb, tx_flags, first), - skb->len, hdr_len); - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); + ixgbevf_tx_map(tx_ring, skb, tx_flags), + first, skb->len, hdr_len); writel(tx_ring->next_to_use, adapter->hw.hw_addr + tx_ring->tail); -- cgit From 39ba22b413723e1e3981d915a542ad6c24e3c919 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 6 Feb 2013 02:37:04 +0000 Subject: ixgbevf: use PCI_DEVICE_TABLE macro Makes PCI id table const. Reformat to match table in ixgbe_main.c Signed-off-by: Stephen Hemminger Acked-by: Greg Rose Tested-by: Sibai Li Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 20736eb567d8..2635b8303515 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -76,12 +76,9 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = { * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, * Class, Class Mask, private data (not used) } */ -static struct pci_device_id ixgbevf_pci_tbl[] = { - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), - board_82599_vf}, - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), - board_X540_vf}, - +static DEFINE_PCI_DEVICE_TABLE(ixgbevf_pci_tbl) = { + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf }, /* required last entry */ {0, } }; -- cgit From f0ff439872e1eab81940d736a5683e93b44865e3 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:05:39 +0000 Subject: e1000e: cleanup CODE_INDENT checkpatch errors ERROR:CODE_INDENT: code indent should use tabs where possible Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 73 +++++++++++----------- drivers/net/ethernet/intel/e1000e/82571.c | 18 +++--- drivers/net/ethernet/intel/e1000e/ethtool.c | 37 ++++++----- drivers/net/ethernet/intel/e1000e/hw.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 74 +++++++++++----------- drivers/net/ethernet/intel/e1000e/netdev.c | 80 +++++++++++------------- drivers/net/ethernet/intel/e1000e/phy.c | 81 ++++++++++++------------- 7 files changed, 178 insertions(+), 187 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index e0991388664c..c4bc569997b0 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -116,7 +116,7 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); + E1000_EECD_SIZE_EX_SHIFT); /* Added to a constant, "size" becomes the left-shift value * for setting word_size. @@ -406,14 +406,14 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, udelay(200); ret_val = e1000e_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); udelay(200); } else { ret_val = e1000e_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); } e1000_release_phy_80003es2lan(hw); @@ -475,14 +475,14 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, udelay(200); ret_val = e1000e_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & + offset, data); udelay(200); } else { ret_val = e1000e_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & + offset, data); } e1000_release_phy_80003es2lan(hw); @@ -784,14 +784,14 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy */ reg_data = er32(TXDCTL(0)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); ew32(TXDCTL(0), reg_data); /* ...for both queues. */ reg_data = er32(TXDCTL(1)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); ew32(TXDCTL(1), reg_data); /* Enable retransmit on late collisions */ @@ -818,10 +818,9 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* default to true to enable the MDIC W/A */ hw->dev_spec.e80003es2lan.mdic_wa_enable = true; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET >> - E1000_KMRNCTRLSTA_OFFSET_SHIFT, - &i); + ret_val = + e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET >> + E1000_KMRNCTRLSTA_OFFSET_SHIFT, &i); if (!ret_val) { if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) @@ -1049,27 +1048,29 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) * polling the phy; this fixes erroneous timeouts at 10Mbps. */ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), - 0xFFFF); + 0xFFFF); if (ret_val) return ret_val; ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), - ®_data); + ®_data); if (ret_val) return ret_val; reg_data |= 0x3F; ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), - reg_data); + reg_data); if (ret_val) return ret_val; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, - ®_data); + ret_val = + e1000_read_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, + ®_data); if (ret_val) return ret_val; reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, - reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, + reg_data); if (ret_val) return ret_val; @@ -1096,7 +1097,7 @@ static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) if (hw->phy.media_type == e1000_media_type_copper) { ret_val = e1000e_get_speed_and_duplex_copper(hw, &speed, - &duplex); + &duplex); if (ret_val) return ret_val; @@ -1125,9 +1126,10 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) u16 reg_data, reg_data2; reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, - reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, + reg_data); if (ret_val) return ret_val; @@ -1171,9 +1173,10 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) u32 i = 0; reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, - reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, + reg_data); if (ret_val) return ret_val; @@ -1220,7 +1223,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, return ret_val; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; + E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; ew32(KMRNCTRLSTA, kmrnctrlsta); e1e_flush(); @@ -1255,7 +1258,7 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, return ret_val; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | data; + E1000_KMRNCTRLSTA_OFFSET) | data; ew32(KMRNCTRLSTA, kmrnctrlsta); e1e_flush(); diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 2faffbde179e..e63ddc6d77f4 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -846,9 +846,9 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, } for (i = 0; i < words; i++) { - eewr = (data[i] << E1000_NVM_RW_REG_DATA) | - ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | - E1000_NVM_RW_REG_START; + eewr = ((data[i] << E1000_NVM_RW_REG_DATA) | + ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | + E1000_NVM_RW_REG_START); ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); if (ret_val) @@ -1122,9 +1122,9 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy */ reg_data = er32(TXDCTL(0)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | - E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | + E1000_TXDCTL_COUNT_DESC); ew32(TXDCTL(0), reg_data); /* ...for both queues. */ @@ -1140,9 +1140,9 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) break; default: reg_data = er32(TXDCTL(1)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | - E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | + E1000_TXDCTL_COUNT_DESC); ew32(TXDCTL(1), reg_data); break; } diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 2c1813737f6d..fa375dd4da12 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -196,8 +196,7 @@ static int e1000_get_settings(struct net_device *netdev, /* MDI-X => 2; MDI =>1; Invalid =>0 */ if ((hw->phy.media_type == e1000_media_type_copper) && netif_carrier_ok(netdev)) - ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : - ETH_TP_MDI; + ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : ETH_TP_MDI; else ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; @@ -297,12 +296,10 @@ static int e1000_set_settings(struct net_device *netdev, hw->mac.autoneg = 1; if (hw->phy.media_type == e1000_media_type_fiber) hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full | - ADVERTISED_FIBRE | - ADVERTISED_Autoneg; + ADVERTISED_FIBRE | ADVERTISED_Autoneg; else hw->phy.autoneg_advertised = ecmd->advertising | - ADVERTISED_TP | - ADVERTISED_Autoneg; + ADVERTISED_TP | ADVERTISED_Autoneg; ecmd->advertising = hw->phy.autoneg_advertised; if (adapter->fc_autoneg) hw->fc.requested_mode = e1000_fc_default; @@ -345,7 +342,7 @@ static void e1000_get_pauseparam(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; pause->autoneg = - (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); + (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); if (hw->fc.current_mode == e1000_fc_rx_pause) { pause->rx_pause = 1; @@ -434,7 +431,7 @@ static void e1000_get_regs(struct net_device *netdev, memset(p, 0, E1000_REGS_LEN * sizeof(u32)); regs->version = (1 << 24) | (adapter->pdev->revision << 16) | - adapter->pdev->device; + adapter->pdev->device; regs_buff[0] = er32(CTRL); regs_buff[1] = er32(STATUS); @@ -821,7 +818,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) case e1000_80003es2lan: toggle = 0x7FFFF3FF; break; - default: + default: toggle = 0x7FFFF033; break; } @@ -1178,8 +1175,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[i].length = skb->len; tx_ring->buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, skb->len, - DMA_TO_DEVICE); + dma_map_single(&pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, tx_ring->buffer_info[i].dma)) { ret_val = 4; @@ -1225,10 +1222,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) ew32(RDH(0), 0); ew32(RDT(0), 0); rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | - E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE | - E1000_RCTL_SBP | E1000_RCTL_SECRC | - E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | - (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE | + E1000_RCTL_SBP | E1000_RCTL_SECRC | + E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | + (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); ew32(RCTL, rctl); for (i = 0; i < rx_ring->count; i++) { @@ -1243,8 +1240,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) skb_reserve(skb, NET_IP_ALIGN); rx_ring->buffer_info[i].skb = skb; rx_ring->buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, 2048, - DMA_FROM_DEVICE); + dma_map_single(&pdev->dev, skb->data, 2048, + DMA_FROM_DEVICE); if (dma_mapping_error(&pdev->dev, rx_ring->buffer_info[i].dma)) { ret_val = 8; @@ -1980,11 +1977,11 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, switch (e1000_gstrings_stats[i].type) { case NETDEV_STATS: p = (char *) &net_stats + - e1000_gstrings_stats[i].stat_offset; + e1000_gstrings_stats[i].stat_offset; break; case E1000_STATS: p = (char *) adapter + - e1000_gstrings_stats[i].stat_offset; + e1000_gstrings_stats[i].stat_offset; break; default: data[i] = 0; @@ -1992,7 +1989,7 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, } data[i] = (e1000_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } } diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 1e6b889aee87..649bfb67bc05 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -545,7 +545,7 @@ struct e1000_mac_info { u16 mta_reg_count; /* Maximum size of the MTA register table in all supported adapters */ - #define MAX_MTA_REG 128 +#define MAX_MTA_REG 128 u32 mta_shadow[MAX_MTA_REG]; u16 rar_entry_count; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index dff7bff8b8e0..37b2003bcc9c 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -548,8 +548,8 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) /* find total size of the NVM, then cut in half since the total * size represents two separate NVM banks. */ - nvm->flash_bank_size = (sector_end_addr - sector_base_addr) - << FLASH_SECTOR_ADDR_SHIFT; + nvm->flash_bank_size = ((sector_end_addr - sector_base_addr) + << FLASH_SECTOR_ADDR_SHIFT); nvm->flash_bank_size /= 2; /* Adjust to word count */ nvm->flash_bank_size /= sizeof(u16); @@ -1073,9 +1073,9 @@ static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) u32 fwsm; fwsm = er32(FWSM); - return (fwsm & E1000_ICH_FWSM_FW_VALID) && - ((fwsm & E1000_FWSM_MODE_MASK) == - (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); + return ((fwsm & E1000_ICH_FWSM_FW_VALID) && + ((fwsm & E1000_FWSM_MODE_MASK) == + (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))); } /** @@ -1092,7 +1092,7 @@ static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw) fwsm = er32(FWSM); return (fwsm & E1000_ICH_FWSM_FW_VALID) && - (fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); + (fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); } /** @@ -1440,13 +1440,13 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) if (ret_val) goto release; - status_reg &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + status_reg &= (BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK); if (status_reg == (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_1000)) k1_enable = false; } @@ -1455,13 +1455,13 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) if (ret_val) goto release; - status_reg &= HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_MASK; + status_reg &= (HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_MASK); if (status_reg == (HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_1000)) + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_1000)) k1_enable = false; } @@ -2384,7 +2384,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) /* Check bank 0 */ ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset, - &sig_byte); + &sig_byte); if (ret_val) return ret_val; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == @@ -2395,8 +2395,8 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) /* Check bank 1 */ ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset + - bank1_offset, - &sig_byte); + bank1_offset, + &sig_byte); if (ret_val) return ret_val; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == @@ -2635,8 +2635,8 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) return -E1000_ERR_NVM; - flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + + hw->nvm.flash_base_addr); do { udelay(1); @@ -2783,8 +2783,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) data = dev_spec->shadow_ram[i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, i + - old_bank_offset, - &data); + old_bank_offset, + &data); if (ret_val) break; } @@ -2812,8 +2812,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) udelay(100); ret_val = e1000_retry_write_flash_byte_ich8lan(hw, - act_offset + 1, - (u8)(data >> 8)); + act_offset + 1, + (u8)(data >> 8)); if (ret_val) break; } @@ -2989,8 +2989,8 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, offset > ICH_FLASH_LINEAR_ADDR_MASK) return -E1000_ERR_NVM; - flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + + hw->nvm.flash_base_addr); do { udelay(1); @@ -3480,16 +3480,16 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy for both queues */ txdctl = er32(TXDCTL(0)); - txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; - txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB); + txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | + E1000_TXDCTL_MAX_TX_DESC_PREFETCH); ew32(TXDCTL(0), txdctl); txdctl = er32(TXDCTL(1)); - txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; - txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB); + txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | + E1000_TXDCTL_MAX_TX_DESC_PREFETCH); ew32(TXDCTL(1), txdctl); /* ICH8 has opposite polarity of no_snoop bits. @@ -3676,12 +3676,12 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) return ret_val; ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, - ®_data); + ®_data); if (ret_val) return ret_val; reg_data |= 0x3F; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, - reg_data); + reg_data); if (ret_val) return ret_val; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a177b8b65c44..e8192d3f7eb4 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -850,8 +850,8 @@ check_page: if (!buffer_info->dma) buffer_info->dma = dma_map_page(&pdev->dev, - buffer_info->page, 0, - PAGE_SIZE, + buffer_info->page, 0, + PAGE_SIZE, DMA_FROM_DEVICE); rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); @@ -1068,8 +1068,8 @@ static void e1000_put_txbuf(struct e1000_ring *tx_ring, static void e1000_print_hw_hang(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, - struct e1000_adapter, - print_hang_task); + struct e1000_adapter, + print_hang_task); struct net_device *netdev = adapter->netdev; struct e1000_ring *tx_ring = adapter->tx_ring; unsigned int i = tx_ring->next_to_clean; @@ -1549,7 +1549,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, /* this is the beginning of a chain */ rxtop = skb; skb_fill_page_desc(rxtop, 0, buffer_info->page, - 0, length); + 0, length); } else { /* this is the middle of a chain */ skb_fill_page_desc(rxtop, @@ -1590,10 +1590,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); } else { skb_fill_page_desc(skb, 0, - buffer_info->page, 0, - length); + buffer_info->page, 0, + length); e1000_consume_page(buffer_info, skb, - length); + length); } } } @@ -1666,8 +1666,7 @@ static void e1000_clean_rx_ring(struct e1000_ring *rx_ring) DMA_FROM_DEVICE); else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) dma_unmap_page(&pdev->dev, buffer_info->dma, - PAGE_SIZE, - DMA_FROM_DEVICE); + PAGE_SIZE, DMA_FROM_DEVICE); else if (adapter->clean_rx == e1000_clean_rx_irq_ps) dma_unmap_single(&pdev->dev, buffer_info->dma, adapter->rx_ps_bsize0, @@ -2578,8 +2577,7 @@ set_itr_now: * increasing */ new_itr = new_itr > adapter->itr ? - min(adapter->itr + (new_itr >> 2), new_itr) : - new_itr; + min(adapter->itr + (new_itr >> 2), new_itr) : new_itr; adapter->itr = new_itr; adapter->rx_ring->itr_val = new_itr; if (adapter->msix_entries) @@ -2827,7 +2825,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter) e1000_vlan_rx_add_vid(adapter->netdev, 0); for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) - e1000_vlan_rx_add_vid(adapter->netdev, vid); + e1000_vlan_rx_add_vid(adapter->netdev, vid); } static void e1000_init_manageability_pt(struct e1000_adapter *adapter) @@ -3002,8 +3000,8 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) rctl = er32(RCTL); rctl &= ~(3 << E1000_RCTL_MO_SHIFT); rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | - E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | - (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | + (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); /* Do not Store bad packets */ rctl &= ~E1000_RCTL_SBP; @@ -3275,7 +3273,7 @@ static int e1000e_write_mc_addr_list(struct net_device *netdev) /* update_mc_addr_list expects a packed array of only addresses. */ i = 0; netdev_for_each_mc_addr(ha, netdev) - memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); + memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); hw->mac.ops.update_mc_addr_list(hw, mta_list, i); kfree(mta_list); @@ -4615,18 +4613,16 @@ static void e1000e_update_stats(struct e1000_adapter *adapter) * our own version based on RUC and ROC */ netdev->stats.rx_errors = adapter->stats.rxerrc + - adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.ruc + adapter->stats.roc + - adapter->stats.cexterr; + adapter->stats.crcerrs + adapter->stats.algnerrc + + adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr; netdev->stats.rx_length_errors = adapter->stats.ruc + - adapter->stats.roc; + adapter->stats.roc; netdev->stats.rx_crc_errors = adapter->stats.crcerrs; netdev->stats.rx_frame_errors = adapter->stats.algnerrc; netdev->stats.rx_missed_errors = adapter->stats.mpc; /* Tx Errors */ - netdev->stats.tx_errors = adapter->stats.ecol + - adapter->stats.latecol; + netdev->stats.tx_errors = adapter->stats.ecol + adapter->stats.latecol; netdev->stats.tx_aborted_errors = adapter->stats.ecol; netdev->stats.tx_window_errors = adapter->stats.latecol; netdev->stats.tx_carrier_errors = adapter->stats.tncrs; @@ -5056,14 +5052,14 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) iph->tot_len = 0; iph->check = 0; tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, - 0, IPPROTO_TCP, 0); + 0, IPPROTO_TCP, 0); cmd_length = E1000_TXD_CMD_IP; ipcse = skb_transport_offset(skb) - 1; } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); ipcse = 0; } ipcss = skb_network_offset(skb); @@ -5072,7 +5068,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | - E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); + E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); i = tx_ring->next_to_use; context_desc = E1000_CONTEXT_DESC(*tx_ring, i); @@ -5142,8 +5138,7 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) context_desc->lower_setup.ip_config = 0; context_desc->upper_setup.tcp_fields.tucss = css; - context_desc->upper_setup.tcp_fields.tucso = - css + skb->csum_offset; + context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset; context_desc->upper_setup.tcp_fields.tucse = 0; context_desc->tcp_seg_setup.data = 0; context_desc->cmd_and_length = cpu_to_le32(cmd_len); @@ -5265,7 +5260,7 @@ static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count) if (tx_flags & E1000_TX_FLAGS_TSO) { txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D | - E1000_TXD_CMD_TSE; + E1000_TXD_CMD_TSE; txd_upper |= E1000_TXD_POPTS_TXSM << 8; if (tx_flags & E1000_TX_FLAGS_IPV4) @@ -5296,8 +5291,8 @@ static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count) buffer_info = &tx_ring->buffer_info[i]; tx_desc = E1000_TX_DESC(*tx_ring, i); tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); - tx_desc->lower.data = - cpu_to_le32(txd_lower | buffer_info->length); + tx_desc->lower.data = cpu_to_le32(txd_lower | + buffer_info->length); tx_desc->upper.data = cpu_to_le32(txd_upper); i++; @@ -5597,18 +5592,15 @@ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, * our own version based on RUC and ROC */ stats->rx_errors = adapter->stats.rxerrc + - adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.ruc + adapter->stats.roc + - adapter->stats.cexterr; - stats->rx_length_errors = adapter->stats.ruc + - adapter->stats.roc; + adapter->stats.crcerrs + adapter->stats.algnerrc + + adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr; + stats->rx_length_errors = adapter->stats.ruc + adapter->stats.roc; stats->rx_crc_errors = adapter->stats.crcerrs; stats->rx_frame_errors = adapter->stats.algnerrc; stats->rx_missed_errors = adapter->stats.mpc; /* Tx Errors */ - stats->tx_errors = adapter->stats.ecol + - adapter->stats.latecol; + stats->tx_errors = adapter->stats.ecol + adapter->stats.latecol; stats->tx_aborted_errors = adapter->stats.ecol; stats->tx_window_errors = adapter->stats.latecol; stats->tx_carrier_errors = adapter->stats.tncrs; @@ -6002,8 +5994,7 @@ static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) pci_set_power_state(pdev, PCI_D3hot); } -static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, - bool wake) +static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, bool wake) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -6413,7 +6404,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) e_info("(PCI Express:2.5GT/s:%s) %pM\n", /* bus width */ ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : - "Width x1"), + "Width x1"), /* MAC address */ netdev->dev_addr); e_info("Intel(R) PRO/%s Network Connection\n", @@ -6550,7 +6541,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { - dev_err(&pdev->dev, "No usable DMA configuration, aborting\n"); + dev_err(&pdev->dev, + "No usable DMA configuration, aborting\n"); goto err_dma; } } @@ -6835,7 +6827,7 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: pci_release_selected_regions(pdev, - pci_select_bars(pdev, IORESOURCE_MEM)); + pci_select_bars(pdev, IORESOURCE_MEM)); err_pci_reg: err_dma: pci_disable_device(pdev); @@ -6905,7 +6897,7 @@ static void e1000_remove(struct pci_dev *pdev) if (adapter->hw.flash_address) iounmap(adapter->hw.flash_address); pci_release_selected_regions(pdev, - pci_select_bars(pdev, IORESOURCE_MEM)); + pci_select_bars(pdev, IORESOURCE_MEM)); free_netdev(netdev); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 0930c136aa31..c39a65e293fa 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1609,9 +1609,9 @@ s32 e1000_check_polarity_m88(struct e1000_hw *hw) ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data); if (!ret_val) - phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -1653,9 +1653,9 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw) ret_val = e1e_rphy(hw, offset, &data); if (!ret_val) - phy->cable_polarity = (data & mask) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & mask) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -1685,9 +1685,9 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw) ret_val = e1e_rphy(hw, offset, &phy_data); if (!ret_val) - phy->cable_polarity = (phy_data & mask) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((phy_data & mask) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -1791,8 +1791,8 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw) if (ret_val) return ret_val; - index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT; + index = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT); if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) return -E1000_ERR_PHY; @@ -1824,10 +1824,10 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) u16 cur_agc_index, max_agc_index = 0; u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = { - IGP02E1000_PHY_AGC_A, - IGP02E1000_PHY_AGC_B, - IGP02E1000_PHY_AGC_C, - IGP02E1000_PHY_AGC_D + IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D }; /* Read the AGC registers for all channels */ @@ -1841,8 +1841,8 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) * that can be put into the lookup table to obtain the * approximate cable length. */ - cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & - IGP02E1000_AGC_LENGTH_MASK; + cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & + IGP02E1000_AGC_LENGTH_MASK); /* Array index bound check. */ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) || @@ -1865,8 +1865,8 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2); /* Calculate cable length with the error range of +/- 10 meters. */ - phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? - (agc_value - IGP02E1000_AGC_RANGE) : 0; + phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ? + (agc_value - IGP02E1000_AGC_RANGE) : 0); phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; @@ -2040,9 +2040,9 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw) return ret_val; } else { /* Polarity is forced */ - phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); } ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data); @@ -2375,13 +2375,13 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000e_write_phy_reg_mdic(hw, page_select, - (page << page_shift)); + (page << page_shift)); if (ret_val) goto release; } ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); release: hw->phy.ops.release(hw); @@ -2433,13 +2433,13 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000e_write_phy_reg_mdic(hw, page_select, - (page << page_shift)); + (page << page_shift)); if (ret_val) goto release; } ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); release: hw->phy.ops.release(hw); return ret_val; @@ -2674,7 +2674,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, if (read) { /* Read the Wakeup register page value using opcode 0x12 */ ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, - data); + data); } else { /* Write the Wakeup register page value using opcode 0x12 */ ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, @@ -2763,7 +2763,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, if (page > 0 && page < HV_INTC_FC_PAGE_START) { ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - data, true); + data, true); goto out; } @@ -2786,8 +2786,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, e_dbg("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page, page << IGP_PAGE_SHIFT, reg); - ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); out: if (!locked) hw->phy.ops.release(hw); @@ -2871,7 +2870,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, if (page > 0 && page < HV_INTC_FC_PAGE_START) { ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - &data, false); + &data, false); goto out; } @@ -2910,7 +2909,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, page << IGP_PAGE_SHIFT, reg); ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); + data); out: if (!locked) @@ -2995,8 +2994,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u32 data_reg; /* This takes care of the difference with desktop vs mobile phy */ - addr_reg = (hw->phy.type == e1000_phy_82578) ? - I82578_ADDR_REG : I82577_ADDR_REG; + addr_reg = ((hw->phy.type == e1000_phy_82578) ? + I82578_ADDR_REG : I82577_ADDR_REG); data_reg = addr_reg + 1; /* All operations in this function are phy address 2 */ @@ -3050,8 +3049,8 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) if (ret_val) return ret_val; - data &= BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + data &= (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK); if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | BM_CS_STATUS_SPEED_1000)) @@ -3086,9 +3085,9 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw) ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data); if (!ret_val) - phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -3215,8 +3214,8 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw) if (ret_val) return ret_val; - length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >> - I82577_DSTATUS_CABLE_LENGTH_SHIFT; + length = ((phy_data & I82577_DSTATUS_CABLE_LENGTH) >> + I82577_DSTATUS_CABLE_LENGTH_SHIFT); if (length == E1000_CABLE_LENGTH_UNDEFINED) return -E1000_ERR_PHY; -- cgit From 362e20caee2ca2184c887484fca8182289f7e0a2 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:05:45 +0000 Subject: e1000e: cleanup SPACING checkpatch errors and warnings ERROR:SPACING: spaces prohibited around that ':' (ctx:WxV) ERROR:SPACING: need consistent spacing around '-' (ctx:WxV) ERROR:SPACING: space required after that ',' (ctx:VxV) ERROR:SPACING: spaces required around that '=' (ctx:VxV) WARNING:SPACING: missing space after enum definition and some similar spacing issues not reported by checkpatch. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 +- drivers/net/ethernet/intel/e1000e/hw.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 48 ++++++++++++++--------------- drivers/net/ethernet/intel/e1000e/netdev.c | 12 ++++---- drivers/net/ethernet/intel/e1000e/phy.c | 2 +- 6 files changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index e63ddc6d77f4..2a4ae28e6587 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -847,7 +847,7 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, for (i = 0; i < words; i++) { eewr = ((data[i] << E1000_NVM_RW_REG_DATA) | - ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | + ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) | E1000_NVM_RW_REG_START); ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index fa375dd4da12..bbd4b1b3319d 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -39,7 +39,7 @@ #include "e1000.h" -enum {NETDEV_STATS, E1000_STATS}; +enum { NETDEV_STATS, E1000_STATS }; struct e1000_stats { char stat_string[ETH_GSTRING_LEN]; diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 649bfb67bc05..84850f7a23e4 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -167,7 +167,7 @@ enum e1000_1000t_rx_status { e1000_1000t_rx_status_undefined = 0xFF }; -enum e1000_rev_polarity{ +enum e1000_rev_polarity { e1000_rev_polarity_normal = 0, e1000_rev_polarity_reversed, e1000_rev_polarity_undefined = 0xFF diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 37b2003bcc9c..705e74f8c1d1 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -61,15 +61,15 @@ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { struct ich8_hsfsts { - u16 flcdone :1; /* bit 0 Flash Cycle Done */ - u16 flcerr :1; /* bit 1 Flash Cycle Error */ - u16 dael :1; /* bit 2 Direct Access error Log */ - u16 berasesz :2; /* bit 4:3 Sector Erase Size */ - u16 flcinprog :1; /* bit 5 flash cycle in Progress */ - u16 reserved1 :2; /* bit 13:6 Reserved */ - u16 reserved2 :6; /* bit 13:6 Reserved */ - u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */ - u16 flockdn :1; /* bit 15 Flash Config Lock-Down */ + u16 flcdone:1; /* bit 0 Flash Cycle Done */ + u16 flcerr:1; /* bit 1 Flash Cycle Error */ + u16 dael:1; /* bit 2 Direct Access error Log */ + u16 berasesz:2; /* bit 4:3 Sector Erase Size */ + u16 flcinprog:1; /* bit 5 flash cycle in Progress */ + u16 reserved1:2; /* bit 13:6 Reserved */ + u16 reserved2:6; /* bit 13:6 Reserved */ + u16 fldesvalid:1; /* bit 14 Flash Descriptor Valid */ + u16 flockdn:1; /* bit 15 Flash Config Lock-Down */ } hsf_status; u16 regval; }; @@ -78,11 +78,11 @@ union ich8_hws_flash_status { /* Offset 06h FLCTL */ union ich8_hws_flash_ctrl { struct ich8_hsflctl { - u16 flcgo :1; /* 0 Flash Cycle Go */ - u16 flcycle :2; /* 2:1 Flash Cycle */ - u16 reserved :5; /* 7:3 Reserved */ - u16 fldbcount :2; /* 9:8 Flash Data Byte Count */ - u16 flockdn :6; /* 15:10 Reserved */ + u16 flcgo:1; /* 0 Flash Cycle Go */ + u16 flcycle:2; /* 2:1 Flash Cycle */ + u16 reserved:5; /* 7:3 Reserved */ + u16 fldbcount:2; /* 9:8 Flash Data Byte Count */ + u16 flockdn:6; /* 15:10 Reserved */ } hsf_ctrl; u16 regval; }; @@ -90,10 +90,10 @@ union ich8_hws_flash_ctrl { /* ICH Flash Region Access Permissions */ union ich8_hws_flash_regacc { struct ich8_flracc { - u32 grra :8; /* 0:7 GbE region Read Access */ - u32 grwa :8; /* 8:15 GbE region Write Access */ - u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */ - u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */ + u32 grra:8; /* 0:7 GbE region Read Access */ + u32 grwa:8; /* 8:15 GbE region Write Access */ + u32 gmrag:8; /* 23:16 GbE Master Read Access Grant */ + u32 gmwag:8; /* 31:24 GbE Master Write Access Grant */ } hsf_flregacc; u16 regval; }; @@ -1773,7 +1773,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) * SHRAL/H) and initial CRC values to the MAC */ for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) { - u8 mac_addr[ETH_ALEN] = {0}; + u8 mac_addr[ETH_ALEN] = { 0 }; u32 addr_high, addr_low; addr_high = er32(RAH(i)); @@ -2449,8 +2449,8 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, ret_val = 0; for (i = 0; i < words; i++) { - if (dev_spec->shadow_ram[offset+i].modified) { - data[i] = dev_spec->shadow_ram[offset+i].value; + if (dev_spec->shadow_ram[offset + i].modified) { + data[i] = dev_spec->shadow_ram[offset + i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, act_offset + i, @@ -2713,8 +2713,8 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, nvm->ops.acquire(hw); for (i = 0; i < words; i++) { - dev_spec->shadow_ram[offset+i].modified = true; - dev_spec->shadow_ram[offset+i].value = data[i]; + dev_spec->shadow_ram[offset + i].modified = true; + dev_spec->shadow_ram[offset + i].value = data[i]; } nvm->ops.release(hw); @@ -3001,7 +3001,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ - hsflctl.hsf_ctrl.fldbcount = size -1; + hsflctl.hsf_ctrl.fldbcount = size - 1; hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index e8192d3f7eb4..247f61f77e5d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1495,7 +1495,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, unsigned int i; int cleaned_count = 0; bool cleaned = false; - unsigned int total_rx_bytes=0, total_rx_packets=0; + unsigned int total_rx_bytes = 0, total_rx_packets = 0; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); @@ -2489,7 +2489,7 @@ static unsigned int e1000_update_itr(u16 itr_setting, int packets, int bytes) switch (itr_setting) { case lowest_latency: /* handle TSO and jumbo frames */ - if (bytes/packets > 8000) + if (bytes / packets > 8000) retval = bulk_latency; else if ((packets < 5) && (bytes > 512)) retval = low_latency; @@ -2497,13 +2497,13 @@ static unsigned int e1000_update_itr(u16 itr_setting, int packets, int bytes) case low_latency: /* 50 usec aka 20000 ints/s */ if (bytes > 10000) { /* this if handles the TSO accounting */ - if (bytes/packets > 8000) + if (bytes / packets > 8000) retval = bulk_latency; - else if ((packets < 10) || ((bytes/packets) > 1200)) + else if ((packets < 10) || ((bytes / packets) > 1200)) retval = bulk_latency; else if ((packets > 35)) retval = lowest_latency; - } else if (bytes/packets > 2000) { + } else if (bytes / packets > 2000) { retval = bulk_latency; } else if (packets <= 2 && bytes < 512) { retval = lowest_latency; @@ -5346,7 +5346,7 @@ static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, return 0; { - const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); + const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data + 14); struct udphdr *udp; if (ip->protocol != IPPROTO_UDP) diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index c39a65e293fa..e46b65f11894 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1756,7 +1756,7 @@ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, if (phy_status & BMSR_LSTATUS) break; if (usec_interval >= 1000) - mdelay(usec_interval/1000); + mdelay(usec_interval / 1000); else udelay(usec_interval); } -- cgit From c29c3ba55fbfb96e68c62f3ceff8a0ee7e66288f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:05:50 +0000 Subject: e1000e: cleanup LONG_LINE checkpatch warnings WARNING:LONG_LINE: line over 80 characters Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/defines.h | 21 +++++++++++---------- drivers/net/ethernet/intel/e1000e/e1000.h | 6 ++++-- drivers/net/ethernet/intel/e1000e/ethtool.c | 3 ++- drivers/net/ethernet/intel/e1000e/netdev.c | 3 ++- drivers/net/ethernet/intel/e1000e/param.c | 6 ++++-- 5 files changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index fc3a4fe1ac71..5af602af40d5 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -66,7 +66,7 @@ #define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 #define E1000_CTRL_EXT_EIAME 0x01000000 #define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ -#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ +#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ #define E1000_CTRL_EXT_LSECCK 0x00001000 #define E1000_CTRL_EXT_PHYPDEN 0x00100000 @@ -239,7 +239,7 @@ #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ #define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ -#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master Req status */ #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 @@ -400,7 +400,8 @@ #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ -#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ +/* If this bit asserted, the driver should claim the interrupt */ +#define E1000_ICR_INT_ASSERTED 0x80000000 #define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ #define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ @@ -583,13 +584,13 @@ #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ #define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES) -#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */ -#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ -#define E1000_NVM_RW_REG_START 1 /* Start operation */ -#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ -#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ -#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ -#define E1000_FLASH_UPDATES 2000 +#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM r/w regs */ +#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ +#define E1000_NVM_RW_REG_START 1 /* Start operation */ +#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define E1000_NVM_POLL_WRITE 1 /* Flag for polling write complete */ +#define E1000_NVM_POLL_READ 0 /* Flag for polling read complete */ +#define E1000_FLASH_UPDATES 2000 /* NVM Word Offsets */ #define NVM_COMPAT 0x0003 diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index fcc758138b8a..9b6a568da702 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -558,12 +558,14 @@ static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw) return hw->nvm.ops.update(hw); } -static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { return hw->nvm.ops.read(hw, offset, words, data); } -static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { return hw->nvm.ops.write(hw, offset, words, data); } diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index bbd4b1b3319d..6e9d433f122b 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -549,7 +549,8 @@ static int e1000_set_eeprom(struct net_device *netdev, if (eeprom->len == 0) return -EOPNOTSUPP; - if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) + if (eeprom->magic != + (adapter->pdev->vendor | (adapter->pdev->device << 16))) return -EFAULT; if (adapter->flags & FLAG_READ_ONLY_NVM) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 247f61f77e5d..1fa61ca4a388 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6918,7 +6918,8 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), + board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 }, diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 98da75dff936..a0117436826d 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -143,7 +143,8 @@ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); * * Default Value: 1 (enabled) */ -E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); +E1000_PARAM(WriteProtectNVM, + "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); /* Enable CRC Stripping * @@ -500,7 +501,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) if (adapter->flags & FLAG_IS_ICH) { if (num_WriteProtectNVM > bd) { - unsigned int write_protect_nvm = WriteProtectNVM[bd]; + unsigned int write_protect_nvm = + WriteProtectNVM[bd]; e1000_validate_option(&write_protect_nvm, &opt, adapter); if (write_protect_nvm) -- cgit From 66501f567d79e50d41931247cfc64b1b5914cdcc Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:05:55 +0000 Subject: e1000e: cleanup LEADING_SPACE checkpatch warnings WARNING:LEADING_SPACE: please, no spaces at the start of a line Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 4 ++-- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- drivers/net/ethernet/intel/e1000e/phy.c | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 9b6a568da702..6ce64ae3e5dd 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -487,8 +487,8 @@ extern int e1000e_setup_tx_resources(struct e1000_ring *ring); extern void e1000e_free_rx_resources(struct e1000_ring *ring); extern void e1000e_free_tx_resources(struct e1000_ring *ring); extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 - *stats); + struct rtnl_link_stats64 + *stats); extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_get_hw_control(struct e1000_adapter *adapter); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 1fa61ca4a388..87fa1c9d5ff6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1468,7 +1468,7 @@ next_desc: * e1000_consume_page - helper function **/ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, - u16 length) + u16 length) { bi->page = NULL; skb->len += length; @@ -5571,7 +5571,7 @@ static void e1000_reset_task(struct work_struct *work) * Returns the address of the device statistics structure. **/ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *stats) + struct rtnl_link_stats64 *stats) { struct e1000_adapter *adapter = netdev_priv(netdev); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index e46b65f11894..643353f4e670 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -324,7 +324,7 @@ s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page) * semaphores before exiting. **/ static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked) { s32 ret_val = 0; @@ -391,7 +391,7 @@ s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data) * at the offset. Release any acquired semaphores before exiting. **/ static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked) { s32 ret_val = 0; @@ -458,7 +458,7 @@ s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data) * Release any acquired semaphores before exiting. **/ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked) { u32 kmrnctrlsta; @@ -531,7 +531,7 @@ s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) * before exiting. **/ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked) { u32 kmrnctrlsta; @@ -2987,7 +2987,7 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page) * These accesses done with PHY address 2 and without using pages. **/ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, - u16 *data, bool read) + u16 *data, bool read) { s32 ret_val; u32 addr_reg; -- cgit From 17e813ec8c8cd0b08b80437f436d1d78f70b8403 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:01 +0000 Subject: e1000e: cleanup PARENTHESIS_ALIGNMENT checkpatch checks CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 39 +++++------ drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 71 ++++++++++--------- drivers/net/ethernet/intel/e1000e/ich8lan.c | 40 +++++------ drivers/net/ethernet/intel/e1000e/netdev.c | 90 ++++++++++++++----------- drivers/net/ethernet/intel/e1000e/param.c | 15 ++--- drivers/net/ethernet/intel/e1000e/phy.c | 9 ++- 7 files changed, 139 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index c4bc569997b0..6c0d96b9889d 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -580,7 +580,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) e_dbg("Waiting for forced speed/duplex link on GG82563 phy.\n"); ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) return ret_val; @@ -595,7 +595,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) /* Try once more */ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) return ret_val; } @@ -666,14 +666,12 @@ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, s32 ret_val; if (hw->phy.media_type == e1000_media_type_copper) { - ret_val = e1000e_get_speed_and_duplex_copper(hw, - speed, - duplex); + ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex); hw->phy.ops.cfg_on_link_up(hw); } else { ret_val = e1000e_get_speed_and_duplex_fiber_serdes(hw, - speed, - duplex); + speed, + duplex); } return ret_val; @@ -823,7 +821,7 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) E1000_KMRNCTRLSTA_OFFSET_SHIFT, &i); if (!ret_val) { if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == - E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) + E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) hw->dev_spec.e80003es2lan.mdic_wa_enable = false; } @@ -890,7 +888,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; - u32 ctrl_ext; + u32 reg; u16 data; ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); @@ -953,22 +951,19 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) } /* Bypass Rx and Tx FIFO's */ - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, - E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | - E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); + reg = E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL; + data = (E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | + E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); if (ret_val) return ret_val; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, - &data); + reg = E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE; + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, reg, &data); if (ret_val) return ret_val; data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, - data); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); if (ret_val) return ret_val; @@ -981,9 +976,9 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) return ret_val; - ctrl_ext = er32(CTRL_EXT); - ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); - ew32(CTRL_EXT, ctrl_ext); + reg = er32(CTRL_EXT); + reg &= ~E1000_CTRL_EXT_LINK_MODE_MASK; + ew32(CTRL_EXT, reg); ret_val = e1e_rphy(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); if (ret_val) diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 2a4ae28e6587..64fc15bd35a6 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -184,7 +184,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) default: nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); + E1000_EECD_SIZE_EX_SHIFT); /* Added to a constant, "size" becomes the left-shift value * for setting word_size. */ diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 6e9d433f122b..b328943ae003 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -499,8 +499,8 @@ static int e1000_get_eeprom(struct net_device *netdev, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * - (last_word - first_word + 1), GFP_KERNEL); + eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; @@ -511,7 +511,7 @@ static int e1000_get_eeprom(struct net_device *netdev, } else { for (i = 0; i < last_word - first_word + 1; i++) { ret_val = e1000_read_nvm(hw, first_word + i, 1, - &eeprom_buff[i]); + &eeprom_buff[i]); if (ret_val) break; } @@ -576,7 +576,7 @@ static int e1000_set_eeprom(struct net_device *netdev, /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ ret_val = e1000_read_nvm(hw, last_word, 1, - &eeprom_buff[last_word - first_word]); + &eeprom_buff[last_word - first_word]); if (ret_val) goto out; @@ -624,10 +624,10 @@ static void e1000_get_drvinfo(struct net_device *netdev, * PCI-E controllers */ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d-%d", - (adapter->eeprom_vers & 0xF000) >> 12, - (adapter->eeprom_vers & 0x0FF0) >> 4, - (adapter->eeprom_vers & 0x000F)); + "%d.%d-%d", + (adapter->eeprom_vers & 0xF000) >> 12, + (adapter->eeprom_vers & 0x0FF0) >> 4, + (adapter->eeprom_vers & 0x000F)); strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), sizeof(drvinfo->bus_info)); @@ -966,8 +966,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, netdev)) { shared_int = 0; - } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, - netdev->name, netdev)) { + } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, netdev->name, + netdev)) { *data = 1; ret_val = -1; goto out; @@ -1077,28 +1077,33 @@ static void e1000_free_desc_rings(struct e1000_adapter *adapter) struct e1000_ring *tx_ring = &adapter->test_tx_ring; struct e1000_ring *rx_ring = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; + struct e1000_buffer *buffer_info; int i; if (tx_ring->desc && tx_ring->buffer_info) { for (i = 0; i < tx_ring->count; i++) { - if (tx_ring->buffer_info[i].dma) + buffer_info = &tx_ring->buffer_info[i]; + + if (buffer_info->dma) dma_unmap_single(&pdev->dev, - tx_ring->buffer_info[i].dma, - tx_ring->buffer_info[i].length, - DMA_TO_DEVICE); - if (tx_ring->buffer_info[i].skb) - dev_kfree_skb(tx_ring->buffer_info[i].skb); + buffer_info->dma, + buffer_info->length, + DMA_TO_DEVICE); + if (buffer_info->skb) + dev_kfree_skb(buffer_info->skb); } } if (rx_ring->desc && rx_ring->buffer_info) { for (i = 0; i < rx_ring->count; i++) { - if (rx_ring->buffer_info[i].dma) + buffer_info = &rx_ring->buffer_info[i]; + + if (buffer_info->dma) dma_unmap_single(&pdev->dev, - rx_ring->buffer_info[i].dma, - 2048, DMA_FROM_DEVICE); - if (rx_ring->buffer_info[i].skb) - dev_kfree_skb(rx_ring->buffer_info[i].skb); + buffer_info->dma, + 2048, DMA_FROM_DEVICE); + if (buffer_info->skb) + dev_kfree_skb(buffer_info->skb); } } @@ -1561,7 +1566,7 @@ static int e1000_check_lbtest_frame(struct sk_buff *skb, frame_size &= ~1; if (*(skb->data + 3) == 0xFF) if ((*(skb->data + frame_size / 2 + 10) == 0xBE) && - (*(skb->data + frame_size / 2 + 12) == 0xAF)) + (*(skb->data + frame_size / 2 + 12) == 0xAF)) return 0; return 13; } @@ -1572,6 +1577,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) struct e1000_ring *rx_ring = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; + struct e1000_buffer *buffer_info; int i, j, k, l; int lc; int good_cnt; @@ -1594,12 +1600,13 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) l = 0; for (j = 0; j <= lc; j++) { /* loop count loop */ for (i = 0; i < 64; i++) { /* send the packets */ - e1000_create_lbtest_frame(tx_ring->buffer_info[k].skb, - 1024); + buffer_info = &tx_ring->buffer_info[k]; + + e1000_create_lbtest_frame(buffer_info->skb, 1024); dma_sync_single_for_device(&pdev->dev, - tx_ring->buffer_info[k].dma, - tx_ring->buffer_info[k].length, - DMA_TO_DEVICE); + buffer_info->dma, + buffer_info->length, + DMA_TO_DEVICE); k++; if (k == tx_ring->count) k = 0; @@ -1610,12 +1617,14 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) time = jiffies; /* set the start time for the receive */ good_cnt = 0; do { /* receive the sent packets */ + buffer_info = &rx_ring->buffer_info[l]; + dma_sync_single_for_cpu(&pdev->dev, - rx_ring->buffer_info[l].dma, 2048, - DMA_FROM_DEVICE); + buffer_info->dma, 2048, + DMA_FROM_DEVICE); - ret_val = e1000_check_lbtest_frame( - rx_ring->buffer_info[l].skb, 1024); + ret_val = e1000_check_lbtest_frame(buffer_info->skb, + 1024); if (!ret_val) good_cnt++; l++; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 705e74f8c1d1..a18dd1ca22d9 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1804,8 +1804,8 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) ew32(RCTL, mac_reg); ret_val = e1000e_read_kmrn_reg(hw, - E1000_KMRNCTRLSTA_CTRL_OFFSET, - &data); + E1000_KMRNCTRLSTA_CTRL_OFFSET, + &data); if (ret_val) return ret_val; ret_val = e1000e_write_kmrn_reg(hw, @@ -1814,8 +1814,8 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) if (ret_val) return ret_val; ret_val = e1000e_read_kmrn_reg(hw, - E1000_KMRNCTRLSTA_HD_CTRL, - &data); + E1000_KMRNCTRLSTA_HD_CTRL, + &data); if (ret_val) return ret_val; data &= ~(0xF << 8); @@ -1862,8 +1862,8 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) ew32(RCTL, mac_reg); ret_val = e1000e_read_kmrn_reg(hw, - E1000_KMRNCTRLSTA_CTRL_OFFSET, - &data); + E1000_KMRNCTRLSTA_CTRL_OFFSET, + &data); if (ret_val) return ret_val; ret_val = e1000e_write_kmrn_reg(hw, @@ -1872,8 +1872,8 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) if (ret_val) return ret_val; ret_val = e1000e_read_kmrn_reg(hw, - E1000_KMRNCTRLSTA_HD_CTRL, - &data); + E1000_KMRNCTRLSTA_HD_CTRL, + &data); if (ret_val) return ret_val; data &= ~(0xF << 8); @@ -2653,8 +2653,9 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ew32flash(ICH_FLASH_FADDR, flash_linear_addr); - ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_READ_COMMAND_TIMEOUT); + ret_val = + e1000_flash_cycle_ich8lan(hw, + ICH_FLASH_READ_COMMAND_TIMEOUT); /* Check if FCERR is set to 1, if set to 1, clear it * and try the whole sequence a few more times, else @@ -3017,8 +3018,9 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* check if FCERR is set to 1 , if set to 1, clear it * and try the whole sequence a few more times else done */ - ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_WRITE_COMMAND_TIMEOUT); + ret_val = + e1000_flash_cycle_ich8lan(hw, + ICH_FLASH_WRITE_COMMAND_TIMEOUT); if (!ret_val) break; @@ -3150,6 +3152,8 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) for (j = 0; j < iteration ; j++) { do { + u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT; + /* Steps */ ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) @@ -3169,8 +3173,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) flash_linear_addr += (j * sector_size); ew32flash(ICH_FLASH_FADDR, flash_linear_addr); - ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_ERASE_COMMAND_TIMEOUT); + ret_val = e1000_flash_cycle_ich8lan(hw, timeout); if (!ret_val) break; @@ -3625,8 +3628,7 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) */ hw->fc.current_mode = hw->fc.requested_mode; - e_dbg("After fix-ups FlowControl is now = %x\n", - hw->fc.current_mode); + e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode); /* Continue to configure the copper link. */ ret_val = hw->mac.ops.setup_physical_interface(hw); @@ -3838,7 +3840,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) * /disabled - false). **/ void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, - bool state) + bool state) { struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; @@ -3920,12 +3922,12 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) return; ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, - ®_data); + ®_data); if (ret_val) return; reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, - reg_data); + reg_data); if (ret_val) return; reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 87fa1c9d5ff6..9d76edcca62d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1430,7 +1430,7 @@ copydone: e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); if (rx_desc->wb.upper.header_status & - cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) + cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) adapter->rx_hdr_split++; e1000_receive_skb(adapter, netdev, skb, staterr, @@ -1496,6 +1496,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, int cleaned_count = 0; bool cleaned = false; unsigned int total_rx_bytes = 0, total_rx_packets = 0; + struct skb_shared_info *shinfo; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); @@ -1552,9 +1553,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, 0, length); } else { /* this is the middle of a chain */ - skb_fill_page_desc(rxtop, - skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, length); + shinfo = skb_shinfo(rxtop); + skb_fill_page_desc(rxtop, shinfo->nr_frags, + buffer_info->page, 0, + length); /* re-use the skb, only consumed the page */ buffer_info->skb = skb; } @@ -1563,9 +1565,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, } else { if (rxtop) { /* end of the chain */ - skb_fill_page_desc(rxtop, - skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, length); + shinfo = skb_shinfo(rxtop); + skb_fill_page_desc(rxtop, shinfo->nr_frags, + buffer_info->page, 0, + length); /* re-use the current skb, we only consumed the * page */ @@ -1719,7 +1722,8 @@ static void e1000_clean_rx_ring(struct e1000_ring *rx_ring) static void e1000e_downshift_workaround(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, - struct e1000_adapter, downshift_task); + struct e1000_adapter, + downshift_task); if (test_bit(__E1000_DOWN, &adapter->state)) return; @@ -2044,8 +2048,9 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) if (adapter->flags & FLAG_HAS_MSIX) { adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */ adapter->msix_entries = kcalloc(adapter->num_vectors, - sizeof(struct msix_entry), - GFP_KERNEL); + sizeof(struct + msix_entry), + GFP_KERNEL); if (adapter->msix_entries) { for (i = 0; i < adapter->num_vectors; i++) adapter->msix_entries[i].entry = i; @@ -3854,13 +3859,13 @@ void e1000e_reset(struct e1000_adapter *adapter) if ((adapter->max_frame_size * 2) > (pba << 10)) { if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) { dev_info(&adapter->pdev->dev, - "Interrupt Throttle Rate turned off\n"); + "Interrupt Throttle Rate off\n"); adapter->flags2 |= FLAG2_DISABLE_AIM; e1000e_write_itr(adapter, 0); } } else if (adapter->flags2 & FLAG2_DISABLE_AIM) { dev_info(&adapter->pdev->dev, - "Interrupt Throttle Rate turned on\n"); + "Interrupt Throttle Rate on\n"); adapter->flags2 &= ~FLAG2_DISABLE_AIM; adapter->itr = 20000; e1000e_write_itr(adapter, adapter->itr); @@ -4429,7 +4434,8 @@ static int e1000_set_mac(struct net_device *netdev, void *p) static void e1000e_update_phy_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, - struct e1000_adapter, update_phy_task); + struct e1000_adapter, + update_phy_task); if (test_bit(__E1000_DOWN, &adapter->state)) return; @@ -4789,7 +4795,8 @@ static void e1000_watchdog(unsigned long data) static void e1000_watchdog_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, - struct e1000_adapter, watchdog_task); + struct e1000_adapter, + watchdog_task); struct net_device *netdev = adapter->netdev; struct e1000_mac_info *mac = &adapter->hw.mac; struct e1000_phy_info *phy = &adapter->hw.phy; @@ -4823,8 +4830,8 @@ static void e1000_watchdog_task(struct work_struct *work) /* update snapshot of PHY registers on LSC */ e1000_phy_read_status(adapter); mac->ops.get_link_up_info(&adapter->hw, - &adapter->link_speed, - &adapter->link_duplex); + &adapter->link_speed, + &adapter->link_duplex); e1000_print_link_info(adapter); /* check if SmartSpeed worked */ @@ -4937,7 +4944,7 @@ static void e1000_watchdog_task(struct work_struct *work) adapter->flags |= FLAG_RESTART_NOW; else pm_schedule_suspend(netdev->dev.parent, - LINK_TIMEOUT); + LINK_TIMEOUT); } } @@ -4972,8 +4979,8 @@ link_up: */ u32 goc = (adapter->gotc + adapter->gorc) / 10000; u32 dif = (adapter->gotc > adapter->gorc ? - adapter->gotc - adapter->gorc : - adapter->gorc - adapter->gotc) / 10000; + adapter->gotc - adapter->gorc : + adapter->gorc - adapter->gotc) / 10000; u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000; e1000e_write_itr(adapter, itr); @@ -5211,7 +5218,8 @@ static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag, - offset, size, DMA_TO_DEVICE); + offset, size, + DMA_TO_DEVICE); buffer_info->mapped_as_page = true; if (dma_mapping_error(&pdev->dev, buffer_info->dma)) goto dma_error; @@ -5669,9 +5677,9 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) /* adjust allocation if LPE protects us, and we aren't using SBP */ if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) || - (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)) + (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)) adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN - + ETH_FCS_LEN; + + ETH_FCS_LEN; if (netif_running(netdev)) e1000e_up(adapter); @@ -5850,7 +5858,7 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) phy_reg &= ~(BM_RCTL_MO_MASK); if (mac_reg & E1000_RCTL_MO_3) phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT) - << BM_RCTL_MO_SHIFT); + << BM_RCTL_MO_SHIFT); if (mac_reg & E1000_RCTL_BAM) phy_reg |= BM_RCTL_BAM; if (mac_reg & E1000_RCTL_PMCF) @@ -6098,24 +6106,24 @@ static int __e1000_resume(struct pci_dev *pdev) e1e_rphy(&adapter->hw, BM_WUS, &phy_data); if (phy_data) { e_info("PHY Wakeup cause - %s\n", - phy_data & E1000_WUS_EX ? "Unicast Packet" : - phy_data & E1000_WUS_MC ? "Multicast Packet" : - phy_data & E1000_WUS_BC ? "Broadcast Packet" : - phy_data & E1000_WUS_MAG ? "Magic Packet" : - phy_data & E1000_WUS_LNKC ? - "Link Status Change" : "other"); + phy_data & E1000_WUS_EX ? "Unicast Packet" : + phy_data & E1000_WUS_MC ? "Multicast Packet" : + phy_data & E1000_WUS_BC ? "Broadcast Packet" : + phy_data & E1000_WUS_MAG ? "Magic Packet" : + phy_data & E1000_WUS_LNKC ? + "Link Status Change" : "other"); } e1e_wphy(&adapter->hw, BM_WUS, ~0); } else { u32 wus = er32(WUS); if (wus) { e_info("MAC Wakeup cause - %s\n", - wus & E1000_WUS_EX ? "Unicast Packet" : - wus & E1000_WUS_MC ? "Multicast Packet" : - wus & E1000_WUS_BC ? "Broadcast Packet" : - wus & E1000_WUS_MAG ? "Magic Packet" : - wus & E1000_WUS_LNKC ? "Link Status Change" : - "other"); + wus & E1000_WUS_EX ? "Unicast Packet" : + wus & E1000_WUS_MC ? "Multicast Packet" : + wus & E1000_WUS_BC ? "Broadcast Packet" : + wus & E1000_WUS_MAG ? "Magic Packet" : + wus & E1000_WUS_LNKC ? "Link Status Change" : + "other"); } ew32(WUS, ~0); } @@ -6514,7 +6522,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) resource_size_t flash_start, flash_len; static int cards_found; u16 aspm_disable_flag = 0; - int i, err, pci_using_dac; + int bars, i, err, pci_using_dac; u16 eeprom_data = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; @@ -6548,9 +6556,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } - err = pci_request_selected_regions_exclusive(pdev, - pci_select_bars(pdev, IORESOURCE_MEM), - e1000e_driver_name); + bars = pci_select_bars(pdev, IORESOURCE_MEM); + err = pci_request_selected_regions_exclusive(pdev, bars, + e1000e_driver_name); if (err) goto err_pci_reg; @@ -6995,8 +7003,8 @@ MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); #ifdef CONFIG_PM static const struct dev_pm_ops e1000_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume) - SET_RUNTIME_PM_OPS(e1000_runtime_suspend, - e1000_runtime_resume, e1000_idle) + SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume, + e1000_idle) }; #endif diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index a0117436826d..39fb5072128e 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -45,7 +45,7 @@ unsigned int copybreak = COPYBREAK_DEFAULT; module_param(copybreak, uint, 0644); MODULE_PARM_DESC(copybreak, - "Maximum size of packet that is copied to a new buffer on receive"); + "Maximum size of packet that is copied to a new buffer on receive"); /* All parameters are treated the same, as an integer array of values. * This macro just reduces the need to repeat the same declaration code @@ -478,18 +478,17 @@ void e1000e_check_options(struct e1000_adapter *adapter) .err = "defaulting to Enabled", .def = OPTION_ENABLED }; + bool enabled = opt.def; if (num_KumeranLockLoss > bd) { unsigned int kmrn_lock_loss = KumeranLockLoss[bd]; e1000_validate_option(&kmrn_lock_loss, &opt, adapter); - if (hw->mac.type == e1000_ich8lan) - e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, - kmrn_lock_loss); - } else { - if (hw->mac.type == e1000_ich8lan) - e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, - opt.def); + enabled = kmrn_lock_loss; } + + if (hw->mac.type == e1000_ich8lan) + e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, + enabled); } { /* Write-protect NVM */ static const struct e1000_option opt = { diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 643353f4e670..8ff0060e0ed6 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -410,8 +410,7 @@ static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, (u16)offset); if (!ret_val) ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & - offset, - data); + offset, data); if (!locked) hw->phy.ops.release(hw); @@ -1296,7 +1295,7 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw) e_dbg("Waiting for forced speed/duplex link on M88 phy.\n"); ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) return ret_val; @@ -1319,7 +1318,7 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw) /* Try once more */ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) return ret_val; } @@ -1733,7 +1732,7 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw) * Polls the PHY status register for link, 'iterations' number of times. **/ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, bool *success) + u32 usec_interval, bool *success) { s32 ret_val = 0; u16 i, phy_status; -- cgit From 53aa82da090222a0eec2956cf9d8409326adca40 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:06 +0000 Subject: e1000e: cleanup SPACING checkpatch checks CHECK:SPACING: No space is necessary after a cast CHECK:SPACING: space prohibited before semicolon Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 16 ++++++++-------- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 ++-- drivers/net/ethernet/intel/e1000e/netdev.c | 10 +++++----- drivers/net/ethernet/intel/e1000e/phy.c | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index b328943ae003..07ef74e7144d 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -925,7 +925,7 @@ static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) } /* If Checksum is not Correct return error else test passed */ - if ((checksum != (u16) NVM_SUM) && !(*data)) + if ((checksum != (u16)NVM_SUM) && !(*data)) *data = 2; return *data; @@ -933,7 +933,7 @@ static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) static irqreturn_t e1000_test_intr(int __always_unused irq, void *data) { - struct net_device *netdev = (struct net_device *) data; + struct net_device *netdev = (struct net_device *)data; struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; @@ -1158,8 +1158,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - ew32(TDBAL(0), ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); - ew32(TDBAH(0), ((u64) tx_ring->dma >> 32)); + ew32(TDBAL(0), ((u64)tx_ring->dma & 0x00000000FFFFFFFF)); + ew32(TDBAH(0), ((u64)tx_ring->dma >> 32)); ew32(TDLEN(0), tx_ring->count * sizeof(struct e1000_tx_desc)); ew32(TDH(0), 0); ew32(TDT(0), 0); @@ -1222,8 +1222,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rctl = er32(RCTL); if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) ew32(RCTL, rctl & ~E1000_RCTL_EN); - ew32(RDBAL(0), ((u64) rx_ring->dma & 0xFFFFFFFF)); - ew32(RDBAH(0), ((u64) rx_ring->dma >> 32)); + ew32(RDBAL(0), ((u64)rx_ring->dma & 0xFFFFFFFF)); + ew32(RDBAH(0), ((u64)rx_ring->dma >> 32)); ew32(RDLEN(0), rx_ring->size); ew32(RDH(0), 0); ew32(RDT(0), 0); @@ -1986,11 +1986,11 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { switch (e1000_gstrings_stats[i].type) { case NETDEV_STATS: - p = (char *) &net_stats + + p = (char *)&net_stats + e1000_gstrings_stats[i].stat_offset; break; case E1000_STATS: - p = (char *) adapter + + p = (char *)adapter + e1000_gstrings_stats[i].stat_offset; break; default: diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index a18dd1ca22d9..dd67cb6dd3a8 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -3150,7 +3150,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) flash_linear_addr = hw->nvm.flash_base_addr; flash_linear_addr += (bank) ? flash_bank_size : 0; - for (j = 0; j < iteration ; j++) { + for (j = 0; j < iteration; j++) { do { u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT; @@ -3501,7 +3501,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) if (mac->type == e1000_ich8lan) snoop = PCIE_ICH8_SNOOP_ALL; else - snoop = (u32) ~(PCIE_NO_SNOOP_ALL); + snoop = (u32)~(PCIE_NO_SNOOP_ALL); e1000e_set_pcie_no_snoop(hw, snoop); ctrl_ext = er32(CTRL_EXT); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 9d76edcca62d..ca1c10e5f69b 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4452,7 +4452,7 @@ static void e1000e_update_phy_task(struct work_struct *work) **/ static void e1000_update_phy_info(unsigned long data) { - struct e1000_adapter *adapter = (struct e1000_adapter *) data; + struct e1000_adapter *adapter = (struct e1000_adapter *)data; if (test_bit(__E1000_DOWN, &adapter->state)) return; @@ -4784,7 +4784,7 @@ static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter) **/ static void e1000_watchdog(unsigned long data) { - struct e1000_adapter *adapter = (struct e1000_adapter *) data; + struct e1000_adapter *adapter = (struct e1000_adapter *)data; /* Do the rest outside of interrupt context */ schedule_work(&adapter->watchdog_task); @@ -5350,7 +5350,7 @@ static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, if (skb->len <= MINIMUM_DHCP_PACKET_SIZE) return 0; - if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP)) + if (((struct ethhdr *)skb->data)->h_proto != htons(ETH_P_IP)) return 0; { @@ -6727,11 +6727,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) init_timer(&adapter->watchdog_timer); adapter->watchdog_timer.function = e1000_watchdog; - adapter->watchdog_timer.data = (unsigned long) adapter; + adapter->watchdog_timer.data = (unsigned long)adapter; init_timer(&adapter->phy_info_timer); adapter->phy_info_timer.function = e1000_update_phy_info; - adapter->phy_info_timer.data = (unsigned long) adapter; + adapter->phy_info_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, e1000_reset_task); INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 8ff0060e0ed6..50e84ed3dc86 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -175,7 +175,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) e_dbg("MDI Error\n"); return -E1000_ERR_PHY; } - *data = (u16) mdic; + *data = (u16)mdic; /* Allow some time after each MDIC transaction to avoid * reading duplicate data in the next MDIC transaction. -- cgit From fc830b785b08cd8c6974850f78fa9cf221c311a8 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:11 +0000 Subject: e1000e: cleanup (add/remove) blank lines where appropriate Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 2 +- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/defines.h | 1 - drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/ethtool.c | 2 ++ drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 3 +-- drivers/net/ethernet/intel/e1000e/phy.c | 2 ++ 8 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 6c0d96b9889d..d75ace9c9651 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -38,6 +38,7 @@ */ static const u16 e1000_gg82563_cable_length_table[] = { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; + #define GG82563_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_gg82563_cable_length_table) @@ -1417,4 +1418,3 @@ const struct e1000_info e1000_es2_info = { .phy_ops = &es2_phy_ops, .nvm_ops = &es2_nvm_ops, }; - diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 64fc15bd35a6..49341c0eeace 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -526,6 +526,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); ew32(SWSM, swsm); } + /** * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore * @hw: pointer to the HW structure @@ -2066,4 +2067,3 @@ const struct e1000_info e1000_82583_info = { .phy_ops = &e82_phy_ops_bm, .nvm_ops = &e82571_nvm_ops, }; - diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 5af602af40d5..e6fe09096c34 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -244,7 +244,6 @@ #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 - #define ADVERTISE_10_HALF 0x0001 #define ADVERTISE_10_FULL 0x0002 #define ADVERTISE_100_HALF 0x0004 diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 6ce64ae3e5dd..3ecc9881353f 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -61,7 +61,6 @@ struct e1000_info; #define e_notice(format, arg...) \ netdev_notice(adapter->netdev, format, ## arg) - /* Interrupt modes, as used by the IntMode parameter */ #define E1000E_INT_MODE_LEGACY 0 #define E1000E_INT_MODE_MSI 1 diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 07ef74e7144d..c47dee6be8eb 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -120,6 +120,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = { "Interrupt test (offline)", "Loopback test (offline)", "Link test (on/offline)" }; + #define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test) static int e1000_get_settings(struct net_device *netdev, @@ -783,6 +784,7 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, } return 0; } + #define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write) \ do { \ if (reg_pattern_test(adapter, data, reg, offset, mask, write)) \ diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index dd67cb6dd3a8..6ff7ff5f2c76 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1606,7 +1606,6 @@ release: return ret_val; } - /** * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode * @hw: pointer to the HW structure @@ -3517,6 +3516,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) return ret_val; } + /** * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits * @hw: pointer to the HW structure diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index ca1c10e5f69b..172d2e32af32 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1542,7 +1542,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, rx_ring->rx_skb_top = NULL; goto next_desc; } - #define rxtop (rx_ring->rx_skb_top) if (!(staterr & E1000_RXD_STAT_EOP)) { /* this descriptor is only the beginning (or middle) */ @@ -1916,7 +1915,6 @@ static irqreturn_t e1000_intr_msix_tx(int __always_unused irq, void *data) struct e1000_hw *hw = &adapter->hw; struct e1000_ring *tx_ring = adapter->tx_ring; - adapter->total_tx_bytes = 0; adapter->total_tx_packets = 0; @@ -4384,6 +4382,7 @@ static int e1000_close(struct net_device *netdev) return 0; } + /** * e1000_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 50e84ed3dc86..0a81d1437feb 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -38,6 +38,7 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; + #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_m88_cable_length_table) @@ -50,6 +51,7 @@ static const u16 e1000_igp_2_cable_length_table[] = { 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, 124}; + #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_igp_2_cable_length_table) -- cgit From 33550cecf5d22a216d497a9e1d7681537e8ffb68 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:16 +0000 Subject: e1000e: cleanup unusually placed comments Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 2 +- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/e1000.h | 5 ++-- drivers/net/ethernet/intel/e1000e/ethtool.c | 15 ++++++----- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- drivers/net/ethernet/intel/e1000e/param.c | 36 ++++++++++++++++--------- 7 files changed, 39 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index d75ace9c9651..303aa8a73d80 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -753,9 +753,9 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); + /* An error is not fatal and we should not stop init due to this */ if (ret_val) e_dbg("Error initializing identification LED\n"); - /* This is not fatal and we should not stop init due to this */ /* Disabling VLAN filtering */ e_dbg("Initializing the IEEE VLAN\n"); diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 49341c0eeace..49bce4ebacc3 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1096,9 +1096,9 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); + /* An error is not fatal and we should not stop init due to this */ if (ret_val) e_dbg("Error initializing identification LED\n"); - /* This is not fatal and we should not stop init due to this */ /* Disabling VLAN filtering */ e_dbg("Initializing the IEEE VLAN\n"); diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 3ecc9881353f..6ba114938ff9 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -238,9 +238,8 @@ struct e1000_adapter { u16 tx_itr; u16 rx_itr; - /* Tx */ - struct e1000_ring *tx_ring /* One per active queue */ - ____cacheline_aligned_in_smp; + /* Tx - one ring per active queue */ + struct e1000_ring *tx_ring ____cacheline_aligned_in_smp; u32 tx_fifo_limit; struct napi_struct napi; diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index c47dee6be8eb..9dbf5d0f575e 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -812,10 +812,10 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) u32 wlock_mac = 0; /* The status register is Read Only, so a write should fail. - * Some bits that get toggled are ignored. + * Some bits that get toggled are ignored. There are several bits + * on newer hardware that are r/w. */ switch (mac->type) { - /* there are several bits on newer hardware that are r/w */ case e1000_82571: case e1000_82572: case e1000_80003es2lan: @@ -1600,8 +1600,10 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) k = 0; l = 0; - for (j = 0; j <= lc; j++) { /* loop count loop */ - for (i = 0; i < 64; i++) { /* send the packets */ + /* loop count loop */ + for (j = 0; j <= lc; j++) { + /* send the packets */ + for (i = 0; i < 64; i++) { buffer_info = &tx_ring->buffer_info[k]; e1000_create_lbtest_frame(buffer_info->skb, 1024); @@ -1618,7 +1620,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) msleep(200); time = jiffies; /* set the start time for the receive */ good_cnt = 0; - do { /* receive the sent packets */ + /* receive the sent packets */ + do { buffer_info = &rx_ring->buffer_info[l]; dma_sync_single_for_cpu(&pdev->dev, @@ -1645,7 +1648,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) ret_val = 14; /* error code for time out error */ break; } - } /* end loop count loop */ + } return ret_val; } diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 6ff7ff5f2c76..d249db9e44e0 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -3452,9 +3452,9 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); + /* An error is not fatal and we should not stop init due to this */ if (ret_val) e_dbg("Error initializing identification LED\n"); - /* This is not fatal and we should not stop init due to this */ /* Setup the receive address. */ e1000e_init_rx_addrs(hw, mac->rar_entry_count); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 172d2e32af32..533713740c58 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2558,8 +2558,8 @@ static void e1000_set_itr(struct e1000_adapter *adapter) current_itr = max(adapter->rx_itr, adapter->tx_itr); - switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ + switch (current_itr) { case lowest_latency: new_itr = 70000; break; diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 39fb5072128e..36bf39d54d79 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -161,11 +161,13 @@ struct e1000_option { const char *err; int def; union { - struct { /* range_option info */ + /* range_option info */ + struct { int min; int max; } r; - struct { /* list_option info */ + /* list_option info */ + struct { int nr; struct e1000_opt_list { int i; char *str; } *p; } l; @@ -247,7 +249,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) "Using defaults for all values\n"); } - { /* Transmit Interrupt Delay */ + /* Transmit Interrupt Delay */ + { static const struct e1000_option opt = { .type = range_option, .name = "Transmit Interrupt Delay", @@ -266,7 +269,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->tx_int_delay = opt.def; } } - { /* Transmit Absolute Interrupt Delay */ + /* Transmit Absolute Interrupt Delay */ + { static const struct e1000_option opt = { .type = range_option, .name = "Transmit Absolute Interrupt Delay", @@ -285,7 +289,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->tx_abs_int_delay = opt.def; } } - { /* Receive Interrupt Delay */ + /* Receive Interrupt Delay */ + { static struct e1000_option opt = { .type = range_option, .name = "Receive Interrupt Delay", @@ -304,7 +309,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->rx_int_delay = opt.def; } } - { /* Receive Absolute Interrupt Delay */ + /* Receive Absolute Interrupt Delay */ + { static const struct e1000_option opt = { .type = range_option, .name = "Receive Absolute Interrupt Delay", @@ -323,7 +329,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->rx_abs_int_delay = opt.def; } } - { /* Interrupt Throttling Rate */ + /* Interrupt Throttling Rate */ + { static const struct e1000_option opt = { .type = range_option, .name = "Interrupt Throttling Rate (ints/sec)", @@ -393,7 +400,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) break; } } - { /* Interrupt Mode */ + /* Interrupt Mode */ + { static struct e1000_option opt = { .type = range_option, .name = "Interrupt Mode", @@ -436,7 +444,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) kfree(opt.err); #endif } - { /* Smart Power Down */ + /* Smart Power Down */ + { static const struct e1000_option opt = { .type = enable_option, .name = "PHY Smart Power Down", @@ -451,7 +460,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->flags |= FLAG_SMART_POWER_DOWN; } } - { /* CRC Stripping */ + /* CRC Stripping */ + { static const struct e1000_option opt = { .type = enable_option, .name = "CRC Stripping", @@ -471,7 +481,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING; } } - { /* Kumeran Lock Loss Workaround */ + /* Kumeran Lock Loss Workaround */ + { static const struct e1000_option opt = { .type = enable_option, .name = "Kumeran Lock Loss Workaround", @@ -490,7 +501,8 @@ void e1000e_check_options(struct e1000_adapter *adapter) e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, enabled); } - { /* Write-protect NVM */ + /* Write-protect NVM */ + { static const struct e1000_option opt = { .type = enable_option, .name = "Write-protect NVM", -- cgit From 04e115cfc5d3e3b0bec3115de423f9e582d3f1f4 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:22 +0000 Subject: e1000e: cleanup formatting of static structs Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 3 ++- drivers/net/ethernet/intel/e1000e/ethtool.c | 3 ++- drivers/net/ethernet/intel/e1000e/phy.c | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 303aa8a73d80..30cf42cbeca2 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -37,7 +37,8 @@ * "index + 5". */ static const u16 e1000_gg82563_cable_length_table[] = { - 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; + 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF +}; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_gg82563_cable_length_table) diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 9dbf5d0f575e..a63cb598babf 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -754,7 +754,8 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, { u32 pat, val; static const u32 test[] = { - 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF + }; for (pat = 0; pat < ARRAY_SIZE(test); pat++) { E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, (test[pat] & write)); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 0a81d1437feb..e071ef772380 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -37,7 +37,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = { - 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; + 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED +}; #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_m88_cable_length_table) @@ -50,7 +51,8 @@ static const u16 e1000_igp_2_cable_length_table[] = { 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, - 124}; + 124 +}; #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_igp_2_cable_length_table) -- cgit From e5fe2541b5e67c2f5b37c58f0148956b1014c2a7 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:27 +0000 Subject: e1000e: cleanup unnecessary line breaks Cuddle broken lines where appropriate. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 6 +-- drivers/net/ethernet/intel/e1000e/ethtool.c | 12 ++---- drivers/net/ethernet/intel/e1000e/ich8lan.c | 9 ++--- drivers/net/ethernet/intel/e1000e/netdev.c | 60 ++++++++++------------------- drivers/net/ethernet/intel/e1000e/phy.c | 6 +-- 5 files changed, 31 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 49bce4ebacc3..c0477fbe6eb3 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -876,8 +876,7 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) s32 timeout = PHY_CFG_TIMEOUT; while (timeout) { - if (er32(EEMNGCTL) & - E1000_NVM_CFG_DONE_PORT_0) + if (er32(EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) break; usleep_range(1000, 2000); timeout--; @@ -1124,8 +1123,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy */ reg_data = er32(TXDCTL(0)); reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | - E1000_TXDCTL_COUNT_DESC); + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); ew32(TXDCTL(0), reg_data); /* ...for both queues. */ diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index a63cb598babf..e43c9440a127 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -223,8 +223,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx) /* Fiber NICs only allow 1000 gbps Full duplex */ if ((adapter->hw.phy.media_type == e1000_media_type_fiber) && - spd != SPEED_1000 && - dplx != DUPLEX_FULL) { + (spd != SPEED_1000) && (dplx != DUPLEX_FULL)) { goto err_inval; } @@ -616,8 +615,7 @@ static void e1000_get_drvinfo(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); - strlcpy(drvinfo->driver, e1000e_driver_name, - sizeof(drvinfo->driver)); + strlcpy(drvinfo->driver, e1000e_driver_name, sizeof(drvinfo->driver)); strlcpy(drvinfo->version, e1000e_driver_version, sizeof(drvinfo->version)); @@ -1143,8 +1141,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->count = E1000_DEFAULT_TXD; tx_ring->buffer_info = kcalloc(tx_ring->count, - sizeof(struct e1000_buffer), - GFP_KERNEL); + sizeof(struct e1000_buffer), GFP_KERNEL); if (!tx_ring->buffer_info) { ret_val = 1; goto err_nomem; @@ -1205,8 +1202,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->count = E1000_DEFAULT_RXD; rx_ring->buffer_info = kcalloc(rx_ring->count, - sizeof(struct e1000_buffer), - GFP_KERNEL); + sizeof(struct e1000_buffer), GFP_KERNEL); if (!rx_ring->buffer_info) { ret_val = 5; goto err_nomem; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index d249db9e44e0..0ed04fcae187 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1379,8 +1379,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) word_addr = (u16)(cnf_base_addr << 1); for (i = 0; i < cnf_size; i++) { - ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, - ®_data); + ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1, ®_data); if (ret_val) goto release; @@ -3211,8 +3210,7 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) return ret_val; } - if (*data == ID_LED_RESERVED_0000 || - *data == ID_LED_RESERVED_FFFF) + if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) *data = ID_LED_DEFAULT_ICH8LAN; return 0; @@ -3756,8 +3754,7 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, return ret_val; if ((hw->mac.type == e1000_ich8lan) && - (hw->phy.type == e1000_phy_igp_3) && - (*speed == SPEED_1000)) { + (hw->phy.type == e1000_phy_igp_3) && (*speed == SPEED_1000)) { ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw); } diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 533713740c58..b085ce1d4546 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -219,9 +219,8 @@ static void e1000e_dump(struct e1000_adapter *adapter) if (netdev) { dev_info(&adapter->pdev->dev, "Net device Info\n"); pr_info("Device Name state trans_start last_rx\n"); - pr_info("%-15s %016lX %016lX %016lX\n", - netdev->name, netdev->state, netdev->trans_start, - netdev->last_rx); + pr_info("%-15s %016lX %016lX %016lX\n", netdev->name, + netdev->state, netdev->trans_start, netdev->last_rx); } /* Print Registers */ @@ -755,8 +754,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring, cpu_to_le64(ps_page->dma); } - skb = __netdev_alloc_skb_ip_align(netdev, - adapter->rx_ps_bsize0, + skb = __netdev_alloc_skb_ip_align(netdev, adapter->rx_ps_bsize0, gfp); if (!skb) { @@ -937,10 +935,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, cleaned = true; cleaned_count++; - dma_unmap_single(&pdev->dev, - buffer_info->dma, - adapter->rx_buffer_len, - DMA_FROM_DEVICE); + dma_unmap_single(&pdev->dev, buffer_info->dma, + adapter->rx_buffer_len, DMA_FROM_DEVICE); buffer_info->dma = 0; length = le16_to_cpu(rx_desc->wb.upper.length); @@ -1082,8 +1078,7 @@ static void e1000_print_hw_hang(struct work_struct *work) if (test_bit(__E1000_DOWN, &adapter->state)) return; - if (!adapter->tx_hang_recheck && - (adapter->flags2 & FLAG2_DMA_BURST)) { + if (!adapter->tx_hang_recheck && (adapter->flags2 & FLAG2_DMA_BURST)) { /* May be block on write-back, flush and detect again * flush pending descriptor writebacks to memory */ @@ -1125,19 +1120,10 @@ static void e1000_print_hw_hang(struct work_struct *work) "PHY 1000BASE-T Status <%x>\n" "PHY Extended Status <%x>\n" "PCI Status <%x>\n", - readl(tx_ring->head), - readl(tx_ring->tail), - tx_ring->next_to_use, - tx_ring->next_to_clean, - tx_ring->buffer_info[eop].time_stamp, - eop, - jiffies, - eop_desc->upper.fields.status, - er32(STATUS), - phy_status, - phy_1000t_status, - phy_ext_status, - pci_status); + readl(tx_ring->head), readl(tx_ring->tail), tx_ring->next_to_use, + tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp, + eop, jiffies, eop_desc->upper.fields.status, er32(STATUS), + phy_status, phy_1000t_status, phy_ext_status, pci_status); /* Suggest workaround for known h/w issue */ if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE)) @@ -2811,8 +2797,7 @@ static void e1000_update_mng_vlan(struct e1000_adapter *adapter) u16 vid = adapter->hw.mng_cookie.vlan_id; u16 old_vid = adapter->mng_vlan_id; - if (adapter->hw.mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { + if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { e1000_vlan_rx_add_vid(netdev, vid); adapter->mng_vlan_id = vid; } @@ -3090,19 +3075,17 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) /* Enable Packet split descriptors */ rctl |= E1000_RCTL_DTYP_PS; - psrctl |= adapter->rx_ps_bsize0 >> - E1000_PSRCTL_BSIZE0_SHIFT; + psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT; switch (adapter->rx_ps_pages) { case 3: - psrctl |= PAGE_SIZE << - E1000_PSRCTL_BSIZE3_SHIFT; + psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE3_SHIFT; + /* fall-through */ case 2: - psrctl |= PAGE_SIZE << - E1000_PSRCTL_BSIZE2_SHIFT; + psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE2_SHIFT; + /* fall-through */ case 1: - psrctl |= PAGE_SIZE >> - E1000_PSRCTL_BSIZE1_SHIFT; + psrctl |= PAGE_SIZE >> E1000_PSRCTL_BSIZE1_SHIFT; break; } @@ -3753,8 +3736,7 @@ void e1000e_reset(struct e1000_adapter *adapter) * but don't include ethernet FCS because hardware appends it */ min_tx_space = (adapter->max_frame_size + - sizeof(struct e1000_tx_desc) - - ETH_FCS_LEN) * 2; + sizeof(struct e1000_tx_desc) - ETH_FCS_LEN) * 2; min_tx_space = ALIGN(min_tx_space, 1024); min_tx_space >>= 10; /* software strips receive CRC, so leave room for it */ @@ -4262,8 +4244,7 @@ static int e1000_open(struct net_device *netdev) e1000e_power_up_phy(adapter); adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - if ((adapter->hw.mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) + if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) e1000_update_mng_vlan(adapter); /* DMA latency requirement to workaround jumbo issue */ @@ -4365,8 +4346,7 @@ static int e1000_close(struct net_device *netdev) /* kill manageability vlan ID if supported, but not if a vlan with * the same ID is registered on the host OS (let 8021q kill it) */ - if (adapter->hw.mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN) + if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); /* If AMT is enabled, let the firmware know that the network diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index e071ef772380..9b3d16729660 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -71,8 +71,7 @@ s32 e1000e_check_reset_block_generic(struct e1000_hw *hw) manc = er32(MANC); - return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? - E1000_BLK_PHY_RESET : 0; + return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? E1000_BLK_PHY_RESET : 0; } /** @@ -775,8 +774,7 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) phy_data |= M88E1000_EPSCR_TX_CLK_25; - if ((phy->revision == 2) && - (phy->id == M88E1111_I_PHY_ID)) { + if ((phy->revision == 2) && (phy->id == M88E1111_I_PHY_ID)) { /* 82573L PHY - set the downshift counter to 5x. */ phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK; phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X; -- cgit From ce43a2168c59bc47b5f0c1825fd5f9a2a9e3b447 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:32 +0000 Subject: e1000e: cleanup USLEEP_RANGE checkpatch checks Resolve strict checkpatch USLEEP_RANGE checks by converting delays and sleeps as described in ./Documentation/timers/timers-howto.txt. Three other violations of the text have also been fixed. CHECK:USLEEP_RANGE: usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 12 ++++++------ drivers/net/ethernet/intel/e1000e/82571.c | 12 ++++++------ drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 10 +++++----- drivers/net/ethernet/intel/e1000e/ich8lan.c | 16 ++++++++-------- drivers/net/ethernet/intel/e1000e/mac.c | 10 +++++----- drivers/net/ethernet/intel/e1000e/nvm.c | 2 +- drivers/net/ethernet/intel/e1000e/phy.c | 12 ++++++------ 8 files changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 30cf42cbeca2..b71c8502a2b3 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -395,7 +395,7 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ - udelay(200); + usleep_range(200, 400); /* ...and verify the command was successful. */ ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); @@ -405,13 +405,13 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, return -E1000_ERR_PHY; } - udelay(200); + usleep_range(200, 400); ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - udelay(200); + usleep_range(200, 400); } else { ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, @@ -464,7 +464,7 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ - udelay(200); + usleep_range(200, 400); /* ...and verify the command was successful. */ ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); @@ -474,13 +474,13 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, return -E1000_ERR_PHY; } - udelay(200); + usleep_range(200, 400); ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - udelay(200); + usleep_range(200, 400); } else { ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index c0477fbe6eb3..7380442a3829 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -437,7 +437,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) return ret_val; phy->id = (u32)(phy_id << 16); - udelay(20); + usleep_range(20, 40); ret_val = e1e_rphy(hw, MII_PHYSID2, &phy_id); if (ret_val) return ret_val; @@ -482,7 +482,7 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) if (!(swsm & E1000_SWSM_SMBI)) break; - udelay(50); + usleep_range(50, 100); i++; } @@ -499,7 +499,7 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) if (er32(SWSM) & E1000_SWSM_SWESMBI) break; - udelay(50); + usleep_range(50, 100); } if (i == fw_timeout) { @@ -1022,7 +1022,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) } if (hw->nvm.type == e1000_nvm_flash_hw) { - udelay(10); + usleep_range(10, 20); ctrl_ext = er32(CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_EE_RST; ew32(CTRL_EXT, ctrl_ext); @@ -1529,7 +1529,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) status = er32(STATUS); er32(RXCW); /* SYNCH bit and IV bit are sticky */ - udelay(10); + usleep_range(10, 20); rxcw = er32(RXCW); if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { @@ -1632,7 +1632,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * the IV bit and restart Autoneg */ for (i = 0; i < AN_RETRY_COUNT; i++) { - udelay(10); + usleep_range(10, 20); rxcw = er32(RXCW); if ((rxcw & E1000_RXCW_SYNCH) && (rxcw & E1000_RXCW_C)) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 6ba114938ff9..e371f771cf8b 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -597,7 +597,7 @@ static inline s32 __ew32_prepare(struct e1000_hw *hw) s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT; while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i) - udelay(50); + usleep_range(50, 100); return i; } diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index e43c9440a127..23d5d9051113 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1297,7 +1297,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) ew32(CTRL, ctrl_reg); e1e_flush(); - udelay(500); + usleep_range(500, 1000); return 0; } @@ -1323,7 +1323,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) e1e_wphy(hw, PHY_REG(2, 21), phy_reg); /* Assert SW reset for above settings to take effect */ hw->phy.ops.commit(hw); - mdelay(1); + usleep_range(1000, 2000); /* Force Full Duplex */ e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C); @@ -1364,7 +1364,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) /* force 1000, set loopback */ e1e_wphy(hw, MII_BMCR, 0x4140); - mdelay(250); + msleep(250); /* Now set up the MAC to the same speed/duplex as the PHY. */ ctrl_reg = er32(CTRL); @@ -1396,7 +1396,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) if (hw->phy.type == e1000_phy_m88) e1000_phy_disable_receiver(adapter); - udelay(500); + usleep_range(500, 1000); return 0; } @@ -1704,7 +1704,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) /* On some Phy/switch combinations, link establishment * can take a few seconds more than expected. */ - msleep(5000); + msleep_interruptible(5000); if (!(er32(STATUS) & E1000_STATUS_LU)) *data = 1; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 0ed04fcae187..382813dfc7a8 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -312,7 +312,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; ew32(CTRL, mac_reg); e1e_flush(); - udelay(10); + usleep_range(10, 20); mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; ew32(CTRL, mac_reg); e1e_flush(); @@ -1517,7 +1517,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) if (ret_val) return ret_val; - udelay(20); + usleep_range(20, 40); ctrl_ext = er32(CTRL_EXT); ctrl_reg = er32(CTRL); @@ -1527,11 +1527,11 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); e1e_flush(); - udelay(20); + usleep_range(20, 40); ew32(CTRL, ctrl_reg); ew32(CTRL_EXT, ctrl_ext); e1e_flush(); - udelay(20); + usleep_range(20, 40); return 0; } @@ -2037,7 +2037,7 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw) do { data = er32(STATUS); data &= E1000_STATUS_LAN_INIT_DONE; - udelay(100); + usleep_range(100, 200); } while ((!data) && --loop); /* If basic configuration is incomplete before the above loop @@ -2801,7 +2801,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) /* Convert offset to bytes. */ act_offset = (i + new_bank_offset) << 1; - udelay(100); + usleep_range(100, 200); /* Write the bytes to the new bank. */ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, @@ -2809,7 +2809,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (ret_val) break; - udelay(100); + usleep_range(100, 200); ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset + 1, (u8)(data >> 8)); @@ -3077,7 +3077,7 @@ static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, for (program_retries = 0; program_retries < 100; program_retries++) { e_dbg("Retrying Byte %2.2X at offset %u\n", byte, offset); - udelay(100); + usleep_range(100, 200); ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); if (!ret_val) break; diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index b78e02174601..b25cc4300de7 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -596,7 +596,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) * serdes media type. */ /* SYNCH bit and IV bit are sticky. */ - udelay(10); + usleep_range(10, 20); rxcw = er32(RXCW); if (rxcw & E1000_RXCW_SYNCH) { if (!(rxcw & E1000_RXCW_IV)) { @@ -613,7 +613,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) status = er32(STATUS); if (status & E1000_STATUS_LU) { /* SYNCH bit and IV bit are sticky, so reread rxcw. */ - udelay(10); + usleep_range(10, 20); rxcw = er32(RXCW); if (rxcw & E1000_RXCW_SYNCH) { if (!(rxcw & E1000_RXCW_IV)) { @@ -1382,7 +1382,7 @@ s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) if (!(swsm & E1000_SWSM_SMBI)) break; - udelay(50); + usleep_range(50, 100); i++; } @@ -1400,7 +1400,7 @@ s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) if (er32(SWSM) & E1000_SWSM_SWESMBI) break; - udelay(50); + usleep_range(50, 100); } if (i == timeout) { @@ -1712,7 +1712,7 @@ s32 e1000e_disable_pcie_master(struct e1000_hw *hw) while (timeout) { if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) break; - udelay(100); + usleep_range(100, 200); timeout--; } diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c index 84fecc268162..44ddc0a0ee0e 100644 --- a/drivers/net/ethernet/intel/e1000e/nvm.c +++ b/drivers/net/ethernet/intel/e1000e/nvm.c @@ -630,7 +630,7 @@ void e1000e_reload_nvm_generic(struct e1000_hw *hw) { u32 ctrl_ext; - udelay(10); + usleep_range(10, 20); ctrl_ext = er32(CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_EE_RST; ew32(CTRL_EXT, ctrl_ext); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 9b3d16729660..60dbf022e986 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -97,7 +97,7 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) return ret_val; phy->id = (u32)(phy_id << 16); - udelay(20); + usleep_range(20, 40); ret_val = e1e_rphy(hw, MII_PHYSID2, &phy_id); if (ret_val) return ret_val; @@ -165,7 +165,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * the lower time out */ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { - udelay(50); + usleep_range(50, 100); mdic = er32(MDIC); if (mdic & E1000_MDIC_READY) break; @@ -184,7 +184,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * reading duplicate data in the next MDIC transaction. */ if (hw->mac.type == e1000_pch2lan) - udelay(100); + usleep_range(100, 200); return 0; } @@ -223,7 +223,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) * the lower time out */ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { - udelay(50); + usleep_range(50, 100); mdic = er32(MDIC); if (mdic & E1000_MDIC_READY) break; @@ -241,7 +241,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) * reading duplicate data in the next MDIC transaction. */ if (hw->mac.type == e1000_pch2lan) - udelay(100); + usleep_range(100, 200); return 0; } @@ -2120,7 +2120,7 @@ s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) ew32(CTRL, ctrl); e1e_flush(); - udelay(150); + usleep_range(150, 300); phy->ops.release(hw); -- cgit From 7be859f74ce232361c39d92d29da207ce6ee72bb Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Thu, 7 Mar 2013 13:17:48 +0000 Subject: regulator: palmas correct dt parsing Fix the DT parsing to agree with the bindings document. Some small changes to the value names and also fix the handling of boolean values. They were previously using prop = 1/0, now just use of_property_read_bool calls. Signed-off-by: Graeme Gregory Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 4f86f6cab620..c25c2ff48305 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -1,7 +1,7 @@ /* * Driver for Regulator part of Palmas PMIC Chips * - * Copyright 2011-2012 Texas Instruments Inc. + * Copyright 2011-2013 Texas Instruments Inc. * * Author: Graeme Gregory * @@ -552,15 +552,13 @@ static void palmas_dt_to_pdata(struct device *dev, pdata->reg_init[idx] = devm_kzalloc(dev, sizeof(struct palmas_reg_init), GFP_KERNEL); - ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,warm-reset", &prop); - if (!ret) - pdata->reg_init[idx]->warm_reset = prop; + pdata->reg_init[idx]->warm_reset = + of_property_read_u32(palmas_matches[idx].of_node, + "ti,warm-reset", &prop); - ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,roof-floor", &prop); - if (!ret) - pdata->reg_init[idx]->roof_floor = prop; + pdata->reg_init[idx]->roof_floor = + of_property_read_bool(palmas_matches[idx].of_node, + "ti,roof-floor"); ret = of_property_read_u32(palmas_matches[idx].of_node, "ti,mode-sleep", &prop); @@ -572,15 +570,14 @@ static void palmas_dt_to_pdata(struct device *dev, if (!ret) pdata->reg_init[idx]->tstep = prop; - ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,vsel", &prop); - if (!ret) - pdata->reg_init[idx]->vsel = prop; + ret = of_property_read_bool(palmas_matches[idx].of_node, + "ti,smps-range"); + if (ret) + pdata->reg_init[idx]->vsel = + PALMAS_SMPS12_VOLTAGE_RANGE; } - ret = of_property_read_u32(node, "ti,ldo6-vibrator", &prop); - if (!ret) - pdata->ldo6_vibrator = prop; + pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator"); } @@ -805,6 +802,13 @@ static int palmas_remove(struct platform_device *pdev) static struct of_device_id of_palmas_match_tbl[] = { { .compatible = "ti,palmas-pmic", }, + { .compatible = "ti,palmas-charger-pmic", }, + { .compatible = "ti,twl6035-pmic", }, + { .compatible = "ti,twl6036-pmic", }, + { .compatible = "ti,twl6037-pmic", }, + { .compatible = "ti,tps65913-pmic", }, + { .compatible = "ti,tps65914-pmic", }, + { .compatible = "ti,tps80036-pmic", }, { /* end */ } }; -- cgit From bbf441271b3c0e631f3687fef398c8a47fe0e3cd Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:37 +0000 Subject: e1000e: cleanup format of struct e1000_opt_list struct Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/param.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 36bf39d54d79..c16bd75b6caa 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -169,7 +169,10 @@ struct e1000_option { /* list_option info */ struct { int nr; - struct e1000_opt_list { int i; char *str; } *p; + struct e1000_opt_list { + int i; + char *str; + } *p; } l; } arg; }; -- cgit From 3ffcf2cb1e1b68eb48011158a023ee1d0bb4b1fc Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 04:06:43 +0000 Subject: e1000e: cleanup - move defines to appropriate header file Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.h | 2 ++ drivers/net/ethernet/intel/e1000e/defines.h | 3 +++ drivers/net/ethernet/intel/e1000e/ethtool.c | 6 ++---- drivers/net/ethernet/intel/e1000e/netdev.c | 5 ----- 4 files changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.h b/drivers/net/ethernet/intel/e1000e/82571.h index 85cb1a3b7cd4..08e24dc3dc0e 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.h +++ b/drivers/net/ethernet/intel/e1000e/82571.h @@ -44,6 +44,8 @@ #define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */ #define E1000_EIAC_MASK_82574 0x01F00000 +#define E1000_IVAR_INT_ALLOC_VALID 0x8 + /* Manageability Operation Mode mask */ #define E1000_NVM_INIT_CTRL2_MNGM 0x6000 diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index e6fe09096c34..b7c664f2a95f 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -216,6 +216,8 @@ #define E1000_CTRL_MEHE 0x00080000 /* Memory Error Handling Enable */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ +#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 /* PHY PM enable */ #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ #define E1000_CTRL_RST 0x04000000 /* Global reset */ #define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ @@ -310,6 +312,7 @@ /* SerDes Control */ #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 +#define E1000_SCTL_ENABLE_SERDES_LOOPBACK 0x0410 /* Receive Checksum Control */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 23d5d9051113..8f5832c606e1 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1432,8 +1432,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) /* special write to serdes control register to enable SerDes analog * loopback */ -#define E1000_SERDES_LB_ON 0x410 - ew32(SCTL, E1000_SERDES_LB_ON); + ew32(SCTL, E1000_SCTL_ENABLE_SERDES_LOOPBACK); e1e_flush(); usleep_range(10000, 20000); @@ -1527,8 +1526,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter) case e1000_82572: if (hw->phy.media_type == e1000_media_type_fiber || hw->phy.media_type == e1000_media_type_internal_serdes) { -#define E1000_SERDES_LB_OFF 0x400 - ew32(SCTL, E1000_SERDES_LB_OFF); + ew32(SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); e1e_flush(); usleep_range(10000, 20000); break; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index b085ce1d4546..b4eab18e1c16 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1957,7 +1957,6 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) ew32(RFCTL, rfctl); } -#define E1000_IVAR_INT_ALLOC_VALID 0x8 /* Configure Rx vector */ rx_ring->ims_val = E1000_IMS_RXQ0; adapter->eiac_mask |= rx_ring->ims_val; @@ -5911,10 +5910,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, } ctrl = er32(CTRL); - /* advertise wake from D3Cold */ - #define E1000_CTRL_ADVD3WUC 0x00100000 - /* phy power management enable */ - #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 ctrl |= E1000_CTRL_ADVD3WUC; if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)) ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT; -- cgit From e6146c5cefedefe69676ab6b2c28a40c2d749ec2 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 7 Mar 2013 22:33:38 +0200 Subject: rndis_wlan: update email address Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- drivers/net/wireless/rndis_wlan.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index e95b1e944eb7..7f68b5e0ce6b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8504,7 +8504,7 @@ F: drivers/usb/gadget/*uvc*.c F: drivers/usb/gadget/webcam.c USB WIRELESS RNDIS DRIVER (rndis_wlan) -M: Jussi Kivilinna +M: Jussi Kivilinna L: linux-wireless@vger.kernel.org S: Maintained F: drivers/net/wireless/rndis_wlan.c diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 5f66b4eac298..8169a85c4498 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2,7 +2,7 @@ * Driver for RNDIS based wireless USB devices. * * Copyright (C) 2007 by Bjorge Dijkstra - * Copyright (C) 2008-2009 by Jussi Kivilinna + * Copyright (C) 2008-2009 by Jussi Kivilinna * * 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 -- cgit From 8908c7d5392671610a2d80107845d4aeee92d9c1 Mon Sep 17 00:00:00 2001 From: Ashok Nagarajan Date: Fri, 8 Mar 2013 10:58:45 -0800 Subject: mwifiex: Trigger a card reset on reaching tx_timeout threshold tx_timeout doesn't always lead to a cmd_timeout. There are occurrences where cmd_timeout never gets triggered for a long time and we encounter a kernel crash. In this patch, we track the consecutive timeouts (tx_timeout_cnt). When tx_timeout_cnt exceeds the threshold, trigger a card reset thereby avoiding a kernel crash. Signed-off-by: Ashok Nagarajan Signed-off-by: Paul Stewart Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 15 ++++++++++++--- drivers/net/wireless/mwifiex/main.h | 5 +++++ drivers/net/wireless/mwifiex/txrx.c | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 9c802ede9c3b..121443a0f2a1 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -588,10 +588,19 @@ mwifiex_tx_timeout(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", - jiffies, priv->bss_type, priv->bss_num); - mwifiex_set_trans_start(dev); priv->num_tx_timeout++; + priv->tx_timeout_cnt++; + dev_err(priv->adapter->dev, + "%lu : Tx timeout(#%d), bss_type-num = %d-%d\n", + jiffies, priv->tx_timeout_cnt, priv->bss_type, priv->bss_num); + mwifiex_set_trans_start(dev); + + if (priv->tx_timeout_cnt > TX_TIMEOUT_THRESHOLD && + priv->adapter->if_ops.card_reset) { + dev_err(priv->adapter->dev, + "tx_timeout_cnt exceeds threshold. Triggering card reset!\n"); + priv->adapter->if_ops.card_reset(priv->adapter); + } } /* diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 560cf7312d08..920657587fff 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -130,6 +130,9 @@ enum { #define MWIFIEX_USB_TYPE_DATA 0xBEADC0DE #define MWIFIEX_USB_TYPE_EVENT 0xBEEFFACE +/* Threshold for tx_timeout_cnt before we trigger a card reset */ +#define TX_TIMEOUT_THRESHOLD 6 + struct mwifiex_dbg { u32 num_cmd_host_to_card_failure; u32 num_cmd_sleep_cfm_host_to_card_failure; @@ -394,6 +397,8 @@ struct mwifiex_private { u8 curr_addr[ETH_ALEN]; u8 media_connected; u32 num_tx_timeout; + /* track consecutive timeout */ + u8 tx_timeout_cnt; struct net_device *netdev; struct net_device_stats stats; u16 curr_pkt_filter; diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 296faec14365..8f923d0d2ba6 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -169,6 +169,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, if (!status) { priv->stats.tx_packets++; priv->stats.tx_bytes += skb->len; + if (priv->tx_timeout_cnt) + priv->tx_timeout_cnt = 0; } else { priv->stats.tx_errors++; } -- cgit From c678fb2a915b71f8faa78d9ab6d409b8ff3276cc Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 6 Mar 2013 16:44:26 -0800 Subject: mwifiex: fix potential null dereference 'mef_entry' drivers/net/wireless/mwifiex/cfg80211.c:2357 mwifiex_cfg80211_suspend() error: potential null dereference 'mef_entry' (kzalloc returns null) Reported-by: kbuild test robot Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index df30107225f8..c9bc5f5ba6e1 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2350,9 +2350,12 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, return 0; } + mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL); + if (!mef_entry) + return -ENOMEM; + memset(&mef_cfg, 0, sizeof(mef_cfg)); mef_cfg.num_entries = 1; - mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL); mef_cfg.mef_entry = mef_entry; mef_entry->mode = MEF_MODE_HOST_SLEEP; mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST; -- cgit From 6938d75a8c1a1752f9fa7ef14a0c570036c7b73b Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 16:16:13 +0900 Subject: ARM: EXYNOS: move mct driver to drivers/clocksource Move the multi core timer (mct) driver to from mach-exynos to drivers/clocksource and update the Kconfig and makefiles. Cc: Changhwan Youn Signed-off-by: Thomas Abraham Reviewed-by: Stephen Warren Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 2 +- arch/arm/mach-exynos/Kconfig | 6 - arch/arm/mach-exynos/Makefile | 2 - arch/arm/mach-exynos/mct.c | 550 --------------------------------------- drivers/clocksource/Kconfig | 5 + drivers/clocksource/Makefile | 1 + drivers/clocksource/exynos_mct.c | 550 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 557 insertions(+), 559 deletions(-) delete mode 100644 arch/arm/mach-exynos/mct.c create mode 100644 drivers/clocksource/exynos_mct.c (limited to 'drivers') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b714695b01b..94a062894a10 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1650,7 +1650,7 @@ config LOCAL_TIMERS bool "Use local timer interrupts" depends on SMP default y - select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT) + select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !CLKSRC_EXYNOS_MCT) help Enable support for local timers on SMP platforms, rather then the legacy IPI broadcast method. Local timers allows the system diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 52f51e7b4a0c..b0802eb24d40 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -79,12 +79,6 @@ config SOC_EXYNOS5440 help Enable EXYNOS5440 SoC support -config EXYNOS4_MCT - bool - default y - help - Use MCT (Multi Core Timer) as kernel timers - config EXYNOS_DEV_DMA bool help diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 435757e57bb4..daf289b21486 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -26,8 +26,6 @@ obj-$(CONFIG_ARCH_EXYNOS) += pmu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o -obj-$(CONFIG_EXYNOS4_MCT) += mct.o - obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o # machine support diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c deleted file mode 100644 index 545c98976e93..000000000000 --- a/arch/arm/mach-exynos/mct.c +++ /dev/null @@ -1,550 +0,0 @@ -/* linux/arch/arm/mach-exynos4/mct.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 MCT(Multi-Core Timer) support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#define EXYNOS4_MCTREG(x) (x) -#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) -#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) -#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110) -#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200) -#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204) -#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208) -#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240) -#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244) -#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) -#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) -#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) -#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) -#define EXYNOS4_MCT_L_MASK (0xffffff00) - -#define MCT_L_TCNTB_OFFSET (0x00) -#define MCT_L_ICNTB_OFFSET (0x08) -#define MCT_L_TCON_OFFSET (0x20) -#define MCT_L_INT_CSTAT_OFFSET (0x30) -#define MCT_L_INT_ENB_OFFSET (0x34) -#define MCT_L_WSTAT_OFFSET (0x40) -#define MCT_G_TCON_START (1 << 8) -#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1) -#define MCT_G_TCON_COMP0_ENABLE (1 << 0) -#define MCT_L_TCON_INTERVAL_MODE (1 << 2) -#define MCT_L_TCON_INT_START (1 << 1) -#define MCT_L_TCON_TIMER_START (1 << 0) - -#define TICK_BASE_CNT 1 - -enum { - MCT_INT_SPI, - MCT_INT_PPI -}; - -enum { - MCT_G0_IRQ, - MCT_G1_IRQ, - MCT_G2_IRQ, - MCT_G3_IRQ, - MCT_L0_IRQ, - MCT_L1_IRQ, - MCT_L2_IRQ, - MCT_L3_IRQ, - MCT_NR_IRQS, -}; - -static void __iomem *reg_base; -static unsigned long clk_rate; -static unsigned int mct_int_type; -static int mct_irqs[MCT_NR_IRQS]; - -struct mct_clock_event_device { - struct clock_event_device *evt; - unsigned long base; - char name[10]; -}; - -static void exynos4_mct_write(unsigned int value, unsigned long offset) -{ - unsigned long stat_addr; - u32 mask; - u32 i; - - __raw_writel(value, reg_base + offset); - - if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { - stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; - switch (offset & EXYNOS4_MCT_L_MASK) { - case MCT_L_TCON_OFFSET: - mask = 1 << 3; /* L_TCON write status */ - break; - case MCT_L_ICNTB_OFFSET: - mask = 1 << 1; /* L_ICNTB write status */ - break; - case MCT_L_TCNTB_OFFSET: - mask = 1 << 0; /* L_TCNTB write status */ - break; - default: - return; - } - } else { - switch (offset) { - case EXYNOS4_MCT_G_TCON: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 16; /* G_TCON write status */ - break; - case EXYNOS4_MCT_G_COMP0_L: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 0; /* G_COMP0_L write status */ - break; - case EXYNOS4_MCT_G_COMP0_U: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 1; /* G_COMP0_U write status */ - break; - case EXYNOS4_MCT_G_COMP0_ADD_INCR: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 2; /* G_COMP0_ADD_INCR w status */ - break; - case EXYNOS4_MCT_G_CNT_L: - stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; - mask = 1 << 0; /* G_CNT_L write status */ - break; - case EXYNOS4_MCT_G_CNT_U: - stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; - mask = 1 << 1; /* G_CNT_U write status */ - break; - default: - return; - } - } - - /* Wait maximum 1 ms until written values are applied */ - for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++) - if (__raw_readl(reg_base + stat_addr) & mask) { - __raw_writel(mask, reg_base + stat_addr); - return; - } - - panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset); -} - -/* Clocksource handling */ -static void exynos4_mct_frc_start(u32 hi, u32 lo) -{ - u32 reg; - - exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L); - exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U); - - reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); - reg |= MCT_G_TCON_START; - exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); -} - -static cycle_t exynos4_frc_read(struct clocksource *cs) -{ - unsigned int lo, hi; - u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U); - - do { - hi = hi2; - lo = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L); - hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U); - } while (hi != hi2); - - return ((cycle_t)hi << 32) | lo; -} - -static void exynos4_frc_resume(struct clocksource *cs) -{ - exynos4_mct_frc_start(0, 0); -} - -struct clocksource mct_frc = { - .name = "mct-frc", - .rating = 400, - .read = exynos4_frc_read, - .mask = CLOCKSOURCE_MASK(64), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .resume = exynos4_frc_resume, -}; - -static void __init exynos4_clocksource_init(void) -{ - exynos4_mct_frc_start(0, 0); - - if (clocksource_register_hz(&mct_frc, clk_rate)) - panic("%s: can't register clocksource\n", mct_frc.name); -} - -static void exynos4_mct_comp0_stop(void) -{ - unsigned int tcon; - - tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); - tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC); - - exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON); - exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); -} - -static void exynos4_mct_comp0_start(enum clock_event_mode mode, - unsigned long cycles) -{ - unsigned int tcon; - cycle_t comp_cycle; - - tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); - - if (mode == CLOCK_EVT_MODE_PERIODIC) { - tcon |= MCT_G_TCON_COMP0_AUTO_INC; - exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); - } - - comp_cycle = exynos4_frc_read(&mct_frc) + cycles; - exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L); - exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U); - - exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB); - - tcon |= MCT_G_TCON_COMP0_ENABLE; - exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON); -} - -static int exynos4_comp_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - exynos4_mct_comp0_start(evt->mode, cycles); - - return 0; -} - -static void exynos4_comp_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long cycles_per_jiffy; - exynos4_mct_comp0_stop(); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - cycles_per_jiffy = - (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); - exynos4_mct_comp0_start(mode, cycles_per_jiffy); - break; - - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_RESUME: - break; - } -} - -static struct clock_event_device mct_comp_device = { - .name = "mct-comp", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .rating = 250, - .set_next_event = exynos4_comp_set_next_event, - .set_mode = exynos4_comp_set_mode, -}; - -static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) -{ - struct clock_event_device *evt = dev_id; - - exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction mct_comp_event_irq = { - .name = "mct_comp_irq", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = exynos4_mct_comp_isr, - .dev_id = &mct_comp_device, -}; - -static void exynos4_clockevent_init(void) -{ - mct_comp_device.cpumask = cpumask_of(0); - clockevents_config_and_register(&mct_comp_device, clk_rate, - 0xf, 0xffffffff); - setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); -} - -#ifdef CONFIG_LOCAL_TIMERS - -static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); - -/* Clock event handling */ -static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt) -{ - unsigned long tmp; - unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START; - unsigned long offset = mevt->base + MCT_L_TCON_OFFSET; - - tmp = __raw_readl(reg_base + offset); - if (tmp & mask) { - tmp &= ~mask; - exynos4_mct_write(tmp, offset); - } -} - -static void exynos4_mct_tick_start(unsigned long cycles, - struct mct_clock_event_device *mevt) -{ - unsigned long tmp; - - exynos4_mct_tick_stop(mevt); - - tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */ - - /* update interrupt count buffer */ - exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET); - - /* enable MCT tick interrupt */ - exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET); - - tmp = __raw_readl(reg_base + mevt->base + MCT_L_TCON_OFFSET); - tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START | - MCT_L_TCON_INTERVAL_MODE; - exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); -} - -static int exynos4_tick_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); - - exynos4_mct_tick_start(cycles, mevt); - - return 0; -} - -static inline void exynos4_tick_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); - unsigned long cycles_per_jiffy; - - exynos4_mct_tick_stop(mevt); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - cycles_per_jiffy = - (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); - exynos4_mct_tick_start(cycles_per_jiffy, mevt); - break; - - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_RESUME: - break; - } -} - -static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) -{ - struct clock_event_device *evt = mevt->evt; - - /* - * This is for supporting oneshot mode. - * Mct would generate interrupt periodically - * without explicit stopping. - */ - if (evt->mode != CLOCK_EVT_MODE_PERIODIC) - exynos4_mct_tick_stop(mevt); - - /* Clear the MCT tick interrupt */ - if (__raw_readl(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) { - exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); - return 1; - } else { - return 0; - } -} - -static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) -{ - struct mct_clock_event_device *mevt = dev_id; - struct clock_event_device *evt = mevt->evt; - - exynos4_mct_tick_clear(mevt); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction mct_tick0_event_irq = { - .name = "mct_tick0_irq", - .flags = IRQF_TIMER | IRQF_NOBALANCING, - .handler = exynos4_mct_tick_isr, -}; - -static struct irqaction mct_tick1_event_irq = { - .name = "mct_tick1_irq", - .flags = IRQF_TIMER | IRQF_NOBALANCING, - .handler = exynos4_mct_tick_isr, -}; - -static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) -{ - struct mct_clock_event_device *mevt; - unsigned int cpu = smp_processor_id(); - - mevt = this_cpu_ptr(&percpu_mct_tick); - mevt->evt = evt; - - mevt->base = EXYNOS4_MCT_L_BASE(cpu); - sprintf(mevt->name, "mct_tick%d", cpu); - - evt->name = mevt->name; - evt->cpumask = cpumask_of(cpu); - evt->set_next_event = exynos4_tick_set_next_event; - evt->set_mode = exynos4_tick_set_mode; - evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - evt->rating = 450; - clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), - 0xf, 0x7fffffff); - - exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); - - if (mct_int_type == MCT_INT_SPI) { - if (cpu == 0) { - mct_tick0_event_irq.dev_id = mevt; - evt->irq = mct_irqs[MCT_L0_IRQ]; - setup_irq(evt->irq, &mct_tick0_event_irq); - } else { - mct_tick1_event_irq.dev_id = mevt; - evt->irq = mct_irqs[MCT_L1_IRQ]; - setup_irq(evt->irq, &mct_tick1_event_irq); - irq_set_affinity(evt->irq, cpumask_of(1)); - } - } else { - enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); - } - - return 0; -} - -static void exynos4_local_timer_stop(struct clock_event_device *evt) -{ - unsigned int cpu = smp_processor_id(); - evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); - if (mct_int_type == MCT_INT_SPI) - if (cpu == 0) - remove_irq(evt->irq, &mct_tick0_event_irq); - else - remove_irq(evt->irq, &mct_tick1_event_irq); - else - disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); -} - -static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { - .setup = exynos4_local_timer_setup, - .stop = exynos4_local_timer_stop, -}; -#endif /* CONFIG_LOCAL_TIMERS */ - -static void __init exynos4_timer_resources(struct device_node *np) -{ - struct clk *mct_clk; - mct_clk = clk_get(NULL, "xtal"); - - clk_rate = clk_get_rate(mct_clk); - - reg_base = np ? of_iomap(np, 0) : S5P_VA_SYSTIMER; - if (!reg_base) - panic("%s: unable to ioremap mct address space\n", __func__); - -#ifdef CONFIG_LOCAL_TIMERS - if (mct_int_type == MCT_INT_PPI) { - int err; - - err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], - exynos4_mct_tick_isr, "MCT", - &percpu_mct_tick); - WARN(err, "MCT: can't request IRQ %d (%d)\n", - mct_irqs[MCT_L0_IRQ], err); - } - - local_timer_register(&exynos4_mct_tick_ops); -#endif /* CONFIG_LOCAL_TIMERS */ -} - -static const struct of_device_id exynos_mct_ids[] = { - { .compatible = "samsung,exynos4210-mct", .data = (void *)MCT_INT_SPI }, - { .compatible = "samsung,exynos4412-mct", .data = (void *)MCT_INT_PPI }, -}; - -void __init mct_init(void) -{ - struct device_node *np = NULL; - const struct of_device_id *match; - u32 nr_irqs, i; - -#ifdef CONFIG_OF - np = of_find_matching_node_and_match(NULL, exynos_mct_ids, &match); -#endif - if (np) { - mct_int_type = (u32)(match->data); - - /* This driver uses only one global timer interrupt */ - mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); - - /* - * Find out the number of local irqs specified. The local - * timer irqs are specified after the four global timer - * irqs are specified. - */ -#ifdef CONFIG_OF - nr_irqs = of_irq_count(np); -#endif - for (i = MCT_L0_IRQ; i < nr_irqs; i++) - mct_irqs[i] = irq_of_parse_and_map(np, i); - } else if (soc_is_exynos4210()) { - mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0; - mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0; - mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1; - mct_int_type = MCT_INT_SPI; - } else { - panic("unable to determine mct controller type\n"); - } - - exynos4_timer_resources(np); - exynos4_clocksource_init(); - exynos4_clockevent_init(); -} -CLOCKSOURCE_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init) -CLOCKSOURCE_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index e507ab7df60b..e8c453285151 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -67,3 +67,8 @@ config CLKSRC_METAG_GENERIC def_bool y if METAG help This option enables support for the Meta per-thread timers. + +config CLKSRC_EXYNOS_MCT + def_bool y if ARCH_EXYNOS + help + Support for Multi Core Timer controller on Exynos SoCs. diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 4d8283aec5b5..1c1b15db7c4d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o +obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c new file mode 100644 index 000000000000..545c98976e93 --- /dev/null +++ b/drivers/clocksource/exynos_mct.c @@ -0,0 +1,550 @@ +/* linux/arch/arm/mach-exynos4/mct.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS4 MCT(Multi-Core Timer) support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#define EXYNOS4_MCTREG(x) (x) +#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) +#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) +#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110) +#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200) +#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204) +#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208) +#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240) +#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244) +#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) +#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) +#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) +#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) +#define EXYNOS4_MCT_L_MASK (0xffffff00) + +#define MCT_L_TCNTB_OFFSET (0x00) +#define MCT_L_ICNTB_OFFSET (0x08) +#define MCT_L_TCON_OFFSET (0x20) +#define MCT_L_INT_CSTAT_OFFSET (0x30) +#define MCT_L_INT_ENB_OFFSET (0x34) +#define MCT_L_WSTAT_OFFSET (0x40) +#define MCT_G_TCON_START (1 << 8) +#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1) +#define MCT_G_TCON_COMP0_ENABLE (1 << 0) +#define MCT_L_TCON_INTERVAL_MODE (1 << 2) +#define MCT_L_TCON_INT_START (1 << 1) +#define MCT_L_TCON_TIMER_START (1 << 0) + +#define TICK_BASE_CNT 1 + +enum { + MCT_INT_SPI, + MCT_INT_PPI +}; + +enum { + MCT_G0_IRQ, + MCT_G1_IRQ, + MCT_G2_IRQ, + MCT_G3_IRQ, + MCT_L0_IRQ, + MCT_L1_IRQ, + MCT_L2_IRQ, + MCT_L3_IRQ, + MCT_NR_IRQS, +}; + +static void __iomem *reg_base; +static unsigned long clk_rate; +static unsigned int mct_int_type; +static int mct_irqs[MCT_NR_IRQS]; + +struct mct_clock_event_device { + struct clock_event_device *evt; + unsigned long base; + char name[10]; +}; + +static void exynos4_mct_write(unsigned int value, unsigned long offset) +{ + unsigned long stat_addr; + u32 mask; + u32 i; + + __raw_writel(value, reg_base + offset); + + if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { + stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; + switch (offset & EXYNOS4_MCT_L_MASK) { + case MCT_L_TCON_OFFSET: + mask = 1 << 3; /* L_TCON write status */ + break; + case MCT_L_ICNTB_OFFSET: + mask = 1 << 1; /* L_ICNTB write status */ + break; + case MCT_L_TCNTB_OFFSET: + mask = 1 << 0; /* L_TCNTB write status */ + break; + default: + return; + } + } else { + switch (offset) { + case EXYNOS4_MCT_G_TCON: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 16; /* G_TCON write status */ + break; + case EXYNOS4_MCT_G_COMP0_L: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 0; /* G_COMP0_L write status */ + break; + case EXYNOS4_MCT_G_COMP0_U: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 1; /* G_COMP0_U write status */ + break; + case EXYNOS4_MCT_G_COMP0_ADD_INCR: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 2; /* G_COMP0_ADD_INCR w status */ + break; + case EXYNOS4_MCT_G_CNT_L: + stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; + mask = 1 << 0; /* G_CNT_L write status */ + break; + case EXYNOS4_MCT_G_CNT_U: + stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; + mask = 1 << 1; /* G_CNT_U write status */ + break; + default: + return; + } + } + + /* Wait maximum 1 ms until written values are applied */ + for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++) + if (__raw_readl(reg_base + stat_addr) & mask) { + __raw_writel(mask, reg_base + stat_addr); + return; + } + + panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset); +} + +/* Clocksource handling */ +static void exynos4_mct_frc_start(u32 hi, u32 lo) +{ + u32 reg; + + exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L); + exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U); + + reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); + reg |= MCT_G_TCON_START; + exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); +} + +static cycle_t exynos4_frc_read(struct clocksource *cs) +{ + unsigned int lo, hi; + u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U); + + do { + hi = hi2; + lo = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L); + hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U); + } while (hi != hi2); + + return ((cycle_t)hi << 32) | lo; +} + +static void exynos4_frc_resume(struct clocksource *cs) +{ + exynos4_mct_frc_start(0, 0); +} + +struct clocksource mct_frc = { + .name = "mct-frc", + .rating = 400, + .read = exynos4_frc_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .resume = exynos4_frc_resume, +}; + +static void __init exynos4_clocksource_init(void) +{ + exynos4_mct_frc_start(0, 0); + + if (clocksource_register_hz(&mct_frc, clk_rate)) + panic("%s: can't register clocksource\n", mct_frc.name); +} + +static void exynos4_mct_comp0_stop(void) +{ + unsigned int tcon; + + tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); + tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC); + + exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON); + exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB); +} + +static void exynos4_mct_comp0_start(enum clock_event_mode mode, + unsigned long cycles) +{ + unsigned int tcon; + cycle_t comp_cycle; + + tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + tcon |= MCT_G_TCON_COMP0_AUTO_INC; + exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR); + } + + comp_cycle = exynos4_frc_read(&mct_frc) + cycles; + exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L); + exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U); + + exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB); + + tcon |= MCT_G_TCON_COMP0_ENABLE; + exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON); +} + +static int exynos4_comp_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + exynos4_mct_comp0_start(evt->mode, cycles); + + return 0; +} + +static void exynos4_comp_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long cycles_per_jiffy; + exynos4_mct_comp0_stop(); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_comp0_start(mode, cycles_per_jiffy); + break; + + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device mct_comp_device = { + .name = "mct-comp", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = 250, + .set_next_event = exynos4_comp_set_next_event, + .set_mode = exynos4_comp_set_mode, +}; + +static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction mct_comp_event_irq = { + .name = "mct_comp_irq", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = exynos4_mct_comp_isr, + .dev_id = &mct_comp_device, +}; + +static void exynos4_clockevent_init(void) +{ + mct_comp_device.cpumask = cpumask_of(0); + clockevents_config_and_register(&mct_comp_device, clk_rate, + 0xf, 0xffffffff); + setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); +} + +#ifdef CONFIG_LOCAL_TIMERS + +static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); + +/* Clock event handling */ +static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt) +{ + unsigned long tmp; + unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START; + unsigned long offset = mevt->base + MCT_L_TCON_OFFSET; + + tmp = __raw_readl(reg_base + offset); + if (tmp & mask) { + tmp &= ~mask; + exynos4_mct_write(tmp, offset); + } +} + +static void exynos4_mct_tick_start(unsigned long cycles, + struct mct_clock_event_device *mevt) +{ + unsigned long tmp; + + exynos4_mct_tick_stop(mevt); + + tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */ + + /* update interrupt count buffer */ + exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET); + + /* enable MCT tick interrupt */ + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET); + + tmp = __raw_readl(reg_base + mevt->base + MCT_L_TCON_OFFSET); + tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START | + MCT_L_TCON_INTERVAL_MODE; + exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); +} + +static int exynos4_tick_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + + exynos4_mct_tick_start(cycles, mevt); + + return 0; +} + +static inline void exynos4_tick_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + unsigned long cycles_per_jiffy; + + exynos4_mct_tick_stop(mevt); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_tick_start(cycles_per_jiffy, mevt); + break; + + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) +{ + struct clock_event_device *evt = mevt->evt; + + /* + * This is for supporting oneshot mode. + * Mct would generate interrupt periodically + * without explicit stopping. + */ + if (evt->mode != CLOCK_EVT_MODE_PERIODIC) + exynos4_mct_tick_stop(mevt); + + /* Clear the MCT tick interrupt */ + if (__raw_readl(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) { + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); + return 1; + } else { + return 0; + } +} + +static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) +{ + struct mct_clock_event_device *mevt = dev_id; + struct clock_event_device *evt = mevt->evt; + + exynos4_mct_tick_clear(mevt); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction mct_tick0_event_irq = { + .name = "mct_tick0_irq", + .flags = IRQF_TIMER | IRQF_NOBALANCING, + .handler = exynos4_mct_tick_isr, +}; + +static struct irqaction mct_tick1_event_irq = { + .name = "mct_tick1_irq", + .flags = IRQF_TIMER | IRQF_NOBALANCING, + .handler = exynos4_mct_tick_isr, +}; + +static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) +{ + struct mct_clock_event_device *mevt; + unsigned int cpu = smp_processor_id(); + + mevt = this_cpu_ptr(&percpu_mct_tick); + mevt->evt = evt; + + mevt->base = EXYNOS4_MCT_L_BASE(cpu); + sprintf(mevt->name, "mct_tick%d", cpu); + + evt->name = mevt->name; + evt->cpumask = cpumask_of(cpu); + evt->set_next_event = exynos4_tick_set_next_event; + evt->set_mode = exynos4_tick_set_mode; + evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + evt->rating = 450; + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), + 0xf, 0x7fffffff); + + exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); + + if (mct_int_type == MCT_INT_SPI) { + if (cpu == 0) { + mct_tick0_event_irq.dev_id = mevt; + evt->irq = mct_irqs[MCT_L0_IRQ]; + setup_irq(evt->irq, &mct_tick0_event_irq); + } else { + mct_tick1_event_irq.dev_id = mevt; + evt->irq = mct_irqs[MCT_L1_IRQ]; + setup_irq(evt->irq, &mct_tick1_event_irq); + irq_set_affinity(evt->irq, cpumask_of(1)); + } + } else { + enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); + } + + return 0; +} + +static void exynos4_local_timer_stop(struct clock_event_device *evt) +{ + unsigned int cpu = smp_processor_id(); + evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); + if (mct_int_type == MCT_INT_SPI) + if (cpu == 0) + remove_irq(evt->irq, &mct_tick0_event_irq); + else + remove_irq(evt->irq, &mct_tick1_event_irq); + else + disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); +} + +static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { + .setup = exynos4_local_timer_setup, + .stop = exynos4_local_timer_stop, +}; +#endif /* CONFIG_LOCAL_TIMERS */ + +static void __init exynos4_timer_resources(struct device_node *np) +{ + struct clk *mct_clk; + mct_clk = clk_get(NULL, "xtal"); + + clk_rate = clk_get_rate(mct_clk); + + reg_base = np ? of_iomap(np, 0) : S5P_VA_SYSTIMER; + if (!reg_base) + panic("%s: unable to ioremap mct address space\n", __func__); + +#ifdef CONFIG_LOCAL_TIMERS + if (mct_int_type == MCT_INT_PPI) { + int err; + + err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], + exynos4_mct_tick_isr, "MCT", + &percpu_mct_tick); + WARN(err, "MCT: can't request IRQ %d (%d)\n", + mct_irqs[MCT_L0_IRQ], err); + } + + local_timer_register(&exynos4_mct_tick_ops); +#endif /* CONFIG_LOCAL_TIMERS */ +} + +static const struct of_device_id exynos_mct_ids[] = { + { .compatible = "samsung,exynos4210-mct", .data = (void *)MCT_INT_SPI }, + { .compatible = "samsung,exynos4412-mct", .data = (void *)MCT_INT_PPI }, +}; + +void __init mct_init(void) +{ + struct device_node *np = NULL; + const struct of_device_id *match; + u32 nr_irqs, i; + +#ifdef CONFIG_OF + np = of_find_matching_node_and_match(NULL, exynos_mct_ids, &match); +#endif + if (np) { + mct_int_type = (u32)(match->data); + + /* This driver uses only one global timer interrupt */ + mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); + + /* + * Find out the number of local irqs specified. The local + * timer irqs are specified after the four global timer + * irqs are specified. + */ +#ifdef CONFIG_OF + nr_irqs = of_irq_count(np); +#endif + for (i = MCT_L0_IRQ; i < nr_irqs; i++) + mct_irqs[i] = irq_of_parse_and_map(np, i); + } else if (soc_is_exynos4210()) { + mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0; + mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0; + mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1; + mct_int_type = MCT_INT_SPI; + } else { + panic("unable to determine mct controller type\n"); + } + + exynos4_timer_resources(np); + exynos4_clocksource_init(); + exynos4_clockevent_init(); +} +CLOCKSOURCE_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init) +CLOCKSOURCE_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init) -- cgit From 1fdc7fe18e396d02f9c2dfec3de6975dc8314b60 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Feb 2013 07:45:47 +0300 Subject: ath6kl: small cleanup in ath6kl_htc_pipe_rx_complete() It's harmless, but Smatch complains if we use "htc_hdr->eid" before doing the bounds check. Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index 281390178e3d..9adb56741bc3 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -988,8 +988,6 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, htc_hdr = (struct htc_frame_hdr *) netdata; - ep = &target->endpoint[htc_hdr->eid]; - if (htc_hdr->eid >= ENDPOINT_MAX) { ath6kl_dbg(ATH6KL_DBG_HTC, "HTC Rx: invalid EndpointID=%d\n", @@ -997,6 +995,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, status = -EINVAL; goto free_skb; } + ep = &target->endpoint[htc_hdr->eid]; payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len)); -- cgit From 05c0db08abb82a11e50c1a66392b21bb15aee9cd Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 7 Mar 2013 13:22:36 +0000 Subject: VXLAN: Use UDP Tunnel segmention. Enable TSO for VXLAN devices and use UDP_TUNNEL to offload vxlan segmentation. Signed-off-by: Pravin B Shelar Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index f10e58ac9c1b..f057ec00bba3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -820,6 +820,20 @@ static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb) return (((u64) hash * range) >> 32) + vxlan->port_min; } +static int handle_offloads(struct sk_buff *skb) +{ + if (skb_is_gso(skb)) { + int err = skb_unclone(skb, GFP_ATOMIC); + if (unlikely(err)) + return err; + + skb_shinfo(skb)->gso_type |= (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP); + } else if (skb->ip_summed != CHECKSUM_PARTIAL) + skb->ip_summed = CHECKSUM_NONE; + + return 0; +} + /* Transmit local packets over Vxlan * * Outer IP header inherits ECN and DF from inner header. @@ -963,9 +977,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) vxlan_set_owner(dev, skb); - /* See iptunnel_xmit() */ - if (skb->ip_summed != CHECKSUM_PARTIAL) - skb->ip_summed = CHECKSUM_NONE; + if (handle_offloads(skb)) + goto drop; err = ip_local_out(skb); if (likely(net_xmit_eval(err) == 0)) { @@ -1187,8 +1200,10 @@ static void vxlan_setup(struct net_device *dev) dev->features |= NETIF_F_NETNS_LOCAL; dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; dev->features |= NETIF_F_RXCSUM; + dev->features |= NETIF_F_GSO_SOFTWARE; dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + dev->hw_features |= NETIF_F_GSO_SOFTWARE; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; -- cgit From 7068a67581dced3408d9906afacdeea732c61961 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 8 Mar 2013 09:07:40 +0000 Subject: bna: fix declaration mismatch The function is declared to take u32 but definition uses enum. Signed-off-by: Stephen Hemminger Acked-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/ethernet/brocade/bna/bfa_ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 3227fdde521b..f2b73ffa9122 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -76,7 +76,7 @@ static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc); static void bfa_ioc_pf_failed(struct bfa_ioc *ioc); static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc); static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc); -static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, +static void bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, u32 boot_param); static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, -- cgit From 199453339d7bc0d9bdb548854eb7e62ac33b9296 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 8 Mar 2013 09:07:41 +0000 Subject: Supject: phy: make local function static Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/phy/lxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index ec40ba882f61..ff2e45e9cb54 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -159,7 +159,7 @@ static int lxt973a2_update_link(struct phy_device *phydev) return 0; } -int lxt973a2_read_status(struct phy_device *phydev) +static int lxt973a2_read_status(struct phy_device *phydev) { int adv; int err; -- cgit From baec126cf6a864e0191cf51ac1940f3c4c211617 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 8 Mar 2013 09:07:42 +0000 Subject: phy: vitesse make vsc824x_add_skew static Function is only used in this file, should be static and not an exported symbol. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/phy/vitesse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 2585c383e623..3492b5391273 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -61,7 +61,7 @@ MODULE_DESCRIPTION("Vitesse PHY driver"); MODULE_AUTHOR("Kriston Carson"); MODULE_LICENSE("GPL"); -int vsc824x_add_skew(struct phy_device *phydev) +static int vsc824x_add_skew(struct phy_device *phydev) { int err; int extcon; @@ -81,7 +81,6 @@ int vsc824x_add_skew(struct phy_device *phydev) return err; } -EXPORT_SYMBOL(vsc824x_add_skew); static int vsc824x_config_init(struct phy_device *phydev) { -- cgit From 2ea46599436d4efdd48b626b08ee2113f06bf3a1 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 8 Mar 2013 09:07:43 +0000 Subject: team: make local function static Signed-off-by: Stephen Hemminger Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index ece70a4abbb1..6ba0883b9c36 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -503,9 +503,9 @@ static bool team_dummy_transmit(struct team *team, struct sk_buff *skb) return false; } -rx_handler_result_t team_dummy_receive(struct team *team, - struct team_port *port, - struct sk_buff *skb) +static rx_handler_result_t team_dummy_receive(struct team *team, + struct team_port *port, + struct sk_buff *skb) { return RX_HANDLER_ANOTHER; } -- cgit From a96227e66f0a0361d96885042629bf60eb6a4b39 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 8 Mar 2013 09:53:49 +0000 Subject: qlcnic: Fix endian issues in 83xx driver o Split mailbox structure elements on boundary of adapter register size i.e. 32bit. o Shuffle the position of structure elements based on CPU endianness. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 106 +++++++++++++++++---- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 17 +++- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 33 ++++++- 3 files changed, 130 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index cd5ae8813cb3..41c02ba7648c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -15,36 +15,57 @@ #define RSS_HASHTYPE_IP_TCP 0x3 /* status descriptor mailbox data - * @phy_addr: physical address of buffer + * @phy_addr_{low|high}: physical address of buffer * @sds_ring_size: buffer size * @intrpt_id: interrupt id * @intrpt_val: source of interrupt */ struct qlcnic_sds_mbx { - u64 phy_addr; - u8 rsvd1[16]; + u32 phy_addr_low; + u32 phy_addr_high; + u32 rsvd1[4]; +#if defined(__LITTLE_ENDIAN) u16 sds_ring_size; - u16 rsvd2[3]; + u16 rsvd2; + u16 rsvd3[2]; u16 intrpt_id; u8 intrpt_val; - u8 rsvd3[5]; + u8 rsvd4; +#elif defined(__BIG_ENDIAN) + u16 rsvd2; + u16 sds_ring_size; + u16 rsvd3[2]; + u8 rsvd4; + u8 intrpt_val; + u16 intrpt_id; +#endif + u32 rsvd5; } __packed; /* receive descriptor buffer data - * phy_addr_reg: physical address of regular buffer - * phy_addr_jmb: physical address of jumbo buffer + * phy_addr_reg_{low|high}: physical address of regular buffer + * phy_addr_jmb_{low|high}: physical address of jumbo buffer * reg_ring_sz: size of regular buffer * reg_ring_len: no. of entries in regular buffer * jmb_ring_len: no. of entries in jumbo buffer * jmb_ring_sz: size of jumbo buffer */ struct qlcnic_rds_mbx { - u64 phy_addr_reg; - u64 phy_addr_jmb; + u32 phy_addr_reg_low; + u32 phy_addr_reg_high; + u32 phy_addr_jmb_low; + u32 phy_addr_jmb_high; +#if defined(__LITTLE_ENDIAN) u16 reg_ring_sz; u16 reg_ring_len; u16 jmb_ring_sz; u16 jmb_ring_len; +#elif defined(__BIG_ENDIAN) + u16 reg_ring_len; + u16 reg_ring_sz; + u16 jmb_ring_len; + u16 jmb_ring_sz; +#endif } __packed; /* host producers for regular and jumbo rings */ @@ -61,6 +82,7 @@ struct __host_producer_mbx { * @phy_port: physical port id */ struct qlcnic_rcv_mbx_out { +#if defined(__LITTLE_ENDIAN) u8 rcv_num; u8 sts_num; u16 ctx_id; @@ -68,32 +90,56 @@ struct qlcnic_rcv_mbx_out { u8 num_pci_func; u8 phy_port; u8 vport_id; +#elif defined(__BIG_ENDIAN) + u16 ctx_id; + u8 sts_num; + u8 rcv_num; + u8 vport_id; + u8 phy_port; + u8 num_pci_func; + u8 state; +#endif u32 host_csmr[QLCNIC_MAX_RING_SETS]; struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS]; } __packed; struct qlcnic_add_rings_mbx_out { +#if defined(__LITTLE_ENDIAN) u8 rcv_num; u8 sts_num; - u16 ctx_id; + u16 ctx_id; +#elif defined(__BIG_ENDIAN) + u16 ctx_id; + u8 sts_num; + u8 rcv_num; +#endif u32 host_csmr[QLCNIC_MAX_RING_SETS]; struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS]; } __packed; /* Transmit context mailbox inbox registers - * @phys_addr: DMA address of the transmit buffer - * @cnsmr_index: host consumer index + * @phys_addr_{low|high}: DMA address of the transmit buffer + * @cnsmr_index_{low|high}: host consumer index * @size: legth of transmit buffer ring * @intr_id: interrput id * @src: src of interrupt */ struct qlcnic_tx_mbx { - u64 phys_addr; - u64 cnsmr_index; + u32 phys_addr_low; + u32 phys_addr_high; + u32 cnsmr_index_low; + u32 cnsmr_index_high; +#if defined(__LITTLE_ENDIAN) u16 size; u16 intr_id; u8 src; u8 rsvd[3]; +#elif defined(__BIG_ENDIAN) + u16 intr_id; + u16 size; + u8 rsvd[3]; + u8 src; +#endif } __packed; /* Transmit context mailbox outbox registers @@ -101,11 +147,18 @@ struct qlcnic_tx_mbx { * @ctx_id: transmit context id * @state: state of the transmit context */ + struct qlcnic_tx_mbx_out { u32 host_prod; +#if defined(__LITTLE_ENDIAN) u16 ctx_id; u8 state; u8 rsvd; +#elif defined(__BIG_ENDIAN) + u8 rsvd; + u8 state; + u16 ctx_id; +#endif } __packed; static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { @@ -1004,7 +1057,8 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) sds = &recv_ctx->sds_rings[i]; sds->consumer = 0; memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds)); - sds_mbx.phy_addr = sds->phys_addr; + sds_mbx.phy_addr_low = LSD(sds->phys_addr); + sds_mbx.phy_addr_high = MSD(sds->phys_addr); sds_mbx.sds_ring_size = sds->num_desc; if (adapter->flags & QLCNIC_MSIX_ENABLED) @@ -1090,7 +1144,8 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter) sds = &recv_ctx->sds_rings[i]; sds->consumer = 0; memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds)); - sds_mbx.phy_addr = sds->phys_addr; + sds_mbx.phy_addr_low = LSD(sds->phys_addr); + sds_mbx.phy_addr_high = MSD(sds->phys_addr); sds_mbx.sds_ring_size = sds->num_desc; if (adapter->flags & QLCNIC_MSIX_ENABLED) intrpt_id = ahw->intr_tbl[i].id; @@ -1110,13 +1165,15 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter) rds = &recv_ctx->rds_rings[0]; rds->producer = 0; memset(&rds_mbx, 0, rds_mbx_size); - rds_mbx.phy_addr_reg = rds->phys_addr; + rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr); + rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr); rds_mbx.reg_ring_sz = rds->dma_size; rds_mbx.reg_ring_len = rds->num_desc; /* Jumbo ring */ rds = &recv_ctx->rds_rings[1]; rds->producer = 0; - rds_mbx.phy_addr_jmb = rds->phys_addr; + rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr); + rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr); rds_mbx.jmb_ring_sz = rds->dma_size; rds_mbx.jmb_ring_len = rds->num_desc; buf = &cmd.req.arg[index]; @@ -1182,8 +1239,10 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx)); /* setup mailbox inbox registerss */ - mbx.phys_addr = tx->phys_addr; - mbx.cnsmr_index = tx->hw_cons_phys_addr; + mbx.phys_addr_low = LSD(tx->phys_addr); + mbx.phys_addr_high = MSD(tx->phys_addr); + mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr); + mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr); mbx.size = tx->num_desc; if (adapter->flags & QLCNIC_MSIX_ENABLED) msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id; @@ -1713,7 +1772,12 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, (adapter->recv_ctx->context_id << 16); mv.vlan = le16_to_cpu(vlan_id); - memcpy(&mv.mac, addr, ETH_ALEN); + mv.mac_addr0 = addr[0]; + mv.mac_addr1 = addr[1]; + mv.mac_addr2 = addr[2]; + mv.mac_addr3 = addr[3]; + mv.mac_addr4 = addr[4]; + mv.mac_addr5 = addr[5]; buf = &cmd.req.arg[2]; memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); err = qlcnic_issue_cmd(adapter, &cmd); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 61f81f6c84a9..94e3ee0a7aa6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -94,8 +94,23 @@ struct qlcnic_intrpt_config { }; struct qlcnic_macvlan_mbx { - u8 mac[ETH_ALEN]; +#if defined(__LITTLE_ENDIAN) + u8 mac_addr0; + u8 mac_addr1; + u8 mac_addr2; + u8 mac_addr3; + u8 mac_addr4; + u8 mac_addr5; u16 vlan; +#elif defined(__BIG_ENDIAN) + u8 mac_addr3; + u8 mac_addr2; + u8 mac_addr1; + u8 mac_addr0; + u16 vlan; + u8 mac_addr5; + u8 mac_addr4; +#endif }; struct qlc_83xx_fw_info { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 5c033f268ca5..ba5ac69bf48e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -31,6 +31,7 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter); /* Template header */ struct qlc_83xx_reset_hdr { +#if defined(__LITTLE_ENDIAN) u16 version; u16 signature; u16 size; @@ -39,14 +40,31 @@ struct qlc_83xx_reset_hdr { u16 checksum; u16 init_offset; u16 start_offset; +#elif defined(__BIG_ENDIAN) + u16 signature; + u16 version; + u16 entries; + u16 size; + u16 checksum; + u16 hdr_size; + u16 start_offset; + u16 init_offset; +#endif } __packed; /* Command entry header. */ struct qlc_83xx_entry_hdr { - u16 cmd; - u16 size; - u16 count; - u16 delay; +#if defined(__LITTLE_ENDIAN) + u16 cmd; + u16 size; + u16 count; + u16 delay; +#elif defined(__BIG_ENDIAN) + u16 size; + u16 cmd; + u16 delay; + u16 count; +#endif } __packed; /* Generic poll command */ @@ -60,10 +78,17 @@ struct qlc_83xx_rmw { u32 mask; u32 xor_value; u32 or_value; +#if defined(__LITTLE_ENDIAN) u8 shl; u8 shr; u8 index_a; u8 rsvd; +#elif defined(__BIG_ENDIAN) + u8 rsvd; + u8 index_a; + u8 shr; + u8 shl; +#endif } __packed; /* Generic command with 2 DWORD */ -- cgit From d16951d94aabb72245319679036125b8d7efead9 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Fri, 8 Mar 2013 09:53:50 +0000 Subject: qlcnic: Enable LED test support for 83xx adapter o Add support for LED test on 83xx series adapters Signed-off-by: Himanshu Madhani Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 45 ++++++++++++++++++++++ .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 1 + .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 3 +- 3 files changed, 48 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 41c02ba7648c..c08fa20dd5f0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -1432,6 +1432,51 @@ mbx_err: } } +int qlcnic_83xx_set_led(struct net_device *netdev, + enum ethtool_phys_id_state state) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + int err = -EIO, active = 1; + + if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { + netdev_warn(netdev, + "LED test is not supported in non-privileged mode\n"); + return -EOPNOTSUPP; + } + + switch (state) { + case ETHTOOL_ID_ACTIVE: + if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) + return -EBUSY; + + if (test_bit(__QLCNIC_RESETTING, &adapter->state)) + break; + + err = qlcnic_83xx_config_led(adapter, active, 0); + if (err) + netdev_err(netdev, "Failed to set LED blink state\n"); + break; + case ETHTOOL_ID_INACTIVE: + active = 0; + + if (test_bit(__QLCNIC_RESETTING, &adapter->state)) + break; + + err = qlcnic_83xx_config_led(adapter, active, 0); + if (err) + netdev_err(netdev, "Failed to reset LED blink state\n"); + break; + + default: + return -EINVAL; + } + + if (!active || err) + clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); + + return err; +} + void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, int enable) { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 94e3ee0a7aa6..648a73f904ee 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -449,5 +449,6 @@ int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *); int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *); int qlcnic_83xx_loopback_test(struct net_device *, u8); int qlcnic_83xx_interrupt_test(struct net_device *); +int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state); int qlcnic_83xx_flash_test(struct qlcnic_adapter *); #endif diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 5641f8ec49ab..ba1502acc84a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1176,7 +1176,8 @@ static int qlcnic_set_led(struct net_device *dev, int err = -EIO, active = 1; if (qlcnic_83xx_check(adapter)) - return -EOPNOTSUPP; + return qlcnic_83xx_set_led(dev, state); + if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { netdev_warn(dev, "LED test not supported for non " "privilege function\n"); -- cgit From 1075822c871b56eb1e77cff82fae7bc9d7876d0a Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 8 Mar 2013 09:53:51 +0000 Subject: qlcnic: Fix ethtool statistics for 82xx adapter o Fix miscalculation of statistics length Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index ba1502acc84a..f687a6354e4a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -149,7 +149,8 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { static inline int qlcnic_82xx_statistics(void) { - return QLCNIC_STATS_LEN + ARRAY_SIZE(qlcnic_83xx_mac_stats_strings); + return ARRAY_SIZE(qlcnic_device_gstrings_stats) + + ARRAY_SIZE(qlcnic_83xx_mac_stats_strings); } static inline int qlcnic_83xx_statistics(void) -- cgit From 9434dbfe54518ca65fc80a4c8d3ee581fa6ee8be Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 8 Mar 2013 09:53:52 +0000 Subject: qlcnic: Fix ethtool statistics collection o Properly fill statistics data into buffer. Update buffer pointer properly after filling statistics data into buffer. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index f687a6354e4a..f4f279d5cba4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1071,8 +1071,7 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) } } -static void -qlcnic_fill_stats(u64 *data, void *stats, int type) +static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type) { if (type == QLCNIC_MAC_STATS) { struct qlcnic_mac_statistics *mac_stats = @@ -1121,6 +1120,7 @@ qlcnic_fill_stats(u64 *data, void *stats, int type) *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames); *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes); } + return data; } static void qlcnic_get_ethtool_stats(struct net_device *dev, @@ -1148,7 +1148,7 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev, /* Retrieve MAC statistics from firmware */ memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics)); qlcnic_get_mac_stats(adapter, &mac_stats); - qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS); + data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS); } if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) @@ -1160,7 +1160,7 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev, if (ret) return; - qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS); + data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS); ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func, QLCNIC_QUERY_TX_COUNTER, &port_stats.tx); if (ret) -- cgit From e8f83e5ec7450b85b101a774e165e70a18e9c3ab Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Fri, 8 Mar 2013 09:53:53 +0000 Subject: qlcnic: Bump up the version to 5.1.36 Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index ba3c72fce1f2..c8b489516008 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -38,8 +38,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 1 -#define _QLCNIC_LINUX_SUBVERSION 35 -#define QLCNIC_LINUX_VERSIONID "5.1.35" +#define _QLCNIC_LINUX_SUBVERSION 36 +#define QLCNIC_LINUX_VERSIONID "5.1.36" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit From 720a43efd30f04a0a492c85fb997361c44fbae05 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 8 Mar 2013 15:03:25 +0000 Subject: drivers:net: Remove unnecessary OOM messages after netdev_alloc_skb Emitting netdev_alloc_skb and netdev_alloc_skb_ip_align OOM messages is unnecessary as there is already a dump_stack after allocation failures. Other trivial changes around these removals: Convert a few comparisons of pointer to 0 to !pointer. Change flow to remove unnecessary label. Remove now unused variable. Hoist assignment from if. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/caif/caif_shmcore.c | 5 +---- drivers/net/ethernet/adi/bfin_mac.c | 6 ++---- drivers/net/ethernet/amd/7990.c | 2 -- drivers/net/ethernet/amd/a2065.c | 1 - drivers/net/ethernet/amd/am79c961a.c | 1 - drivers/net/ethernet/amd/ariadne.c | 1 - drivers/net/ethernet/amd/atarilance.c | 2 -- drivers/net/ethernet/amd/au1000_eth.c | 1 - drivers/net/ethernet/amd/declance.c | 2 -- drivers/net/ethernet/amd/pcnet32.c | 1 - drivers/net/ethernet/amd/sun3lance.c | 3 --- drivers/net/ethernet/amd/sunlance.c | 4 ---- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 6 ++---- drivers/net/ethernet/atheros/atlx/atl2.c | 3 --- drivers/net/ethernet/broadcom/bgmac.c | 4 +--- drivers/net/ethernet/broadcom/sb1250-mac.c | 5 +---- drivers/net/ethernet/cadence/at91_ether.c | 1 - drivers/net/ethernet/cirrus/cs89x0.c | 6 ------ drivers/net/ethernet/dlink/dl2k.c | 7 ++----- drivers/net/ethernet/freescale/fec.c | 2 -- .../net/ethernet/freescale/fs_enet/fs_enet-main.c | 17 +++-------------- drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 2 -- drivers/net/ethernet/i825xx/82596.c | 8 +++----- drivers/net/ethernet/i825xx/lib82596.c | 6 ++---- drivers/net/ethernet/ibm/ehea/ehea_main.c | 9 ++------- drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 5 ++--- drivers/net/ethernet/natsemi/sonic.c | 1 - drivers/net/ethernet/netx-eth.c | 2 -- drivers/net/ethernet/nuvoton/w90p910_ether.c | 1 - drivers/net/ethernet/nvidia/forcedeth.c | 1 - drivers/net/ethernet/qlogic/qla3xxx.c | 1 - drivers/net/ethernet/qlogic/qlge/qlge_main.c | 6 ------ drivers/net/ethernet/rdc/r6040.c | 1 - drivers/net/ethernet/realtek/8139too.c | 2 -- drivers/net/ethernet/realtek/atp.c | 2 -- drivers/net/ethernet/seeq/ether3.c | 22 +++++----------------- drivers/net/ethernet/seeq/sgiseeq.c | 2 -- drivers/net/ethernet/sis/sis900.c | 7 ++----- drivers/net/ethernet/smsc/smc9194.c | 2 -- drivers/net/ethernet/smsc/smc91x.c | 2 -- drivers/net/ethernet/smsc/smsc9420.c | 4 +--- drivers/net/ethernet/sun/sunqe.c | 5 +---- drivers/net/ethernet/tehuti/tehuti.c | 5 ++--- drivers/net/ethernet/ti/tlan.c | 4 +--- drivers/net/ethernet/xilinx/ll_temac_main.c | 10 +++------- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 9 +++------ drivers/net/ethernet/xircom/xirc2ps_cs.c | 1 - 47 files changed, 39 insertions(+), 161 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index bce8bac311c9..cca2afc945af 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -338,11 +338,8 @@ static void shm_rx_work_func(struct work_struct *rx_work) /* Get a suitable CAIF packet and copy in data. */ skb = netdev_alloc_skb(pshm_drv->pshm_dev->pshm_netdev, frm_pck_len + 1); - - if (skb == NULL) { - pr_info("OOM: Try next frame in descriptor\n"); + if (skb == NULL) break; - } p = skb_put(skb, frm_pck_len); memcpy(p, pbuf->desc_vptr + frm_pck_ofs, frm_pck_len); diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index a175d0be1ae1..ee705771bd2c 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -188,10 +188,9 @@ static int desc_list_init(struct net_device *dev) /* allocate a new skb for next time receive */ new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN); - if (!new_skb) { - pr_notice("init: low on mem - packet dropped\n"); + if (!new_skb) goto init_error; - } + skb_reserve(new_skb, NET_IP_ALIGN); /* Invidate the data cache of skb->data range when it is write back * cache. It will prevent overwritting the new data from DMA @@ -1236,7 +1235,6 @@ static void bfin_mac_rx(struct net_device *dev) new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN); if (!new_skb) { - netdev_notice(dev, "rx: low on mem - packet dropped\n"); dev->stats.rx_dropped++; goto out; } diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c index 6e722dc37db7..65926a956575 100644 --- a/drivers/net/ethernet/amd/7990.c +++ b/drivers/net/ethernet/amd/7990.c @@ -318,8 +318,6 @@ static int lance_rx (struct net_device *dev) struct sk_buff *skb = netdev_alloc_skb(dev, len + 2); if (!skb) { - printk ("%s: Memory squeeze, deferring packet.\n", - dev->name); dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c index 3789affbc0e5..0866e7627433 100644 --- a/drivers/net/ethernet/amd/a2065.c +++ b/drivers/net/ethernet/amd/a2065.c @@ -293,7 +293,6 @@ static int lance_rx(struct net_device *dev) struct sk_buff *skb = netdev_alloc_skb(dev, len + 2); if (!skb) { - netdev_warn(dev, "Memory squeeze, deferring packet\n"); dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c index 60e2b701afe7..9793767996a2 100644 --- a/drivers/net/ethernet/amd/am79c961a.c +++ b/drivers/net/ethernet/amd/am79c961a.c @@ -528,7 +528,6 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) dev->stats.rx_packets++; } else { am_writeword (dev, hdraddr + 2, RMD_OWN); - printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; break; } diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c index 98f4522fd17b..c178eb4c8166 100644 --- a/drivers/net/ethernet/amd/ariadne.c +++ b/drivers/net/ethernet/amd/ariadne.c @@ -193,7 +193,6 @@ static int ariadne_rx(struct net_device *dev) skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { - netdev_warn(dev, "Memory squeeze, deferring packet\n"); for (i = 0; i < RX_RING_SIZE; i++) if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN) break; diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index 84219df72f51..ab9bedb8d276 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -996,8 +996,6 @@ static int lance_rx( struct net_device *dev ) else { skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { - DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", - dev->name )); for( i = 0; i < RX_RING_SIZE; i++ ) if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag & RMD1_OWN_CHIP) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index de774d419144..688aede742c7 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -727,7 +727,6 @@ static int au1000_rx(struct net_device *dev) frmlen -= 4; /* Remove FCS */ skb = netdev_alloc_skb(dev, frmlen + 2); if (skb == NULL) { - netdev_err(dev, "Memory squeeze, dropping packet.\n"); dev->stats.rx_dropped++; continue; } diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index baca0bd1b393..3d86ffeb4e15 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -607,8 +607,6 @@ static int lance_rx(struct net_device *dev) skb = netdev_alloc_skb(dev, len + 2); if (skb == 0) { - printk("%s: Memory squeeze, deferring packet.\n", - dev->name); dev->stats.rx_dropped++; *rds_ptr(rd, mblength, lp->type) = 0; *rds_ptr(rd, rmd1, lp->type) = diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 797f847edf13..ed2130727643 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1166,7 +1166,6 @@ static void pcnet32_rx_entry(struct net_device *dev, skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN); if (skb == NULL) { - netif_err(lp, drv, dev, "Memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; return; } diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c index 74b3891b6483..de412d331a72 100644 --- a/drivers/net/ethernet/amd/sun3lance.c +++ b/drivers/net/ethernet/amd/sun3lance.c @@ -812,9 +812,6 @@ static int lance_rx( struct net_device *dev ) else { skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { - DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", - dev->name )); - dev->stats.rx_dropped++; head->msg_length = 0; head->flag |= RMD1_OWN_CHIP; diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 6a40290d3727..70d543063993 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -536,8 +536,6 @@ static void lance_rx_dvma(struct net_device *dev) skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { - printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", - dev->name); dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; @@ -708,8 +706,6 @@ static void lance_rx_pio(struct net_device *dev) skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { - printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", - dev->name); dev->stats.rx_dropped++; sbus_writew(0, &rd->mblength); sbus_writeb(LE_R1_OWN, &rd->rmd1_bits); diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 92f4734f860d..e1f1b2a0673a 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1420,11 +1420,9 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) & RRS_PKT_SIZE_MASK) - 4; /* CRC */ skb = netdev_alloc_skb_ip_align(netdev, packet_size); - if (skb == NULL) { - netdev_warn(netdev, - "Memory squeeze, deferring packet\n"); + if (skb == NULL) goto skip_pkt; - } + memcpy(skb->data, (u8 *)(prrs + 1), packet_size); skb_put(skb, packet_size); skb->protocol = eth_type_trans(skb, netdev); diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index 1278b47022e0..a046b6ff847c 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c @@ -437,9 +437,6 @@ static void atl2_intr_rx(struct atl2_adapter *adapter) /* alloc new buffer */ skb = netdev_alloc_skb_ip_align(netdev, rx_size); if (NULL == skb) { - printk(KERN_WARNING - "%s: Mem squeeze, deferring packet.\n", - netdev->name); /* * Check that some rx space is free. If not, * free one and mark stats->rx_dropped++. diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index d6cb376b71e6..eec0af45b859 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -245,10 +245,8 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, /* Alloc skb */ slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); - if (!slot->skb) { - bgmac_err(bgmac, "Allocation of skb failed!\n"); + if (!slot->skb) return -ENOMEM; - } /* Poison - if everything goes fine, hardware will overwrite it */ rx = (struct bgmac_rx_header *)slot->skb->data; diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index e9b35da375cb..e80bfb60c3ef 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -831,11 +831,8 @@ static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + NET_IP_ALIGN); - if (sb_new == NULL) { - pr_info("%s: sk_buff allocation failed\n", - d->sbdma_eth->sbm_dev->name); + if (sb_new == NULL) return -ENOBUFS; - } sbdma_align_skb(sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN); } diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 1a57e16ada7c..5bd7786e8413 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -209,7 +209,6 @@ static void at91ether_rx(struct net_device *dev) netif_rx(skb); } else { lp->stats.rx_dropped++; - netdev_notice(dev, "Memory squeeze, dropping packet.\n"); } if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH)) diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 73c1c8c33dd1..aaa0499aa19c 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -478,9 +478,6 @@ dma_rx(struct net_device *dev) /* Malloc up new buffer. */ skb = netdev_alloc_skb(dev, length + 2); if (skb == NULL) { - /* I don't think we want to do this to a stressed system */ - cs89_dbg(0, err, "%s: Memory squeeze, dropping packet\n", - dev->name); dev->stats.rx_dropped++; /* AKPM: advance bp to the next frame */ @@ -731,9 +728,6 @@ net_rx(struct net_device *dev) /* Malloc up new buffer. */ skb = netdev_alloc_skb(dev, length + 2); if (skb == NULL) { -#if 0 /* Again, this seems a cruel thing to do */ - pr_warn("%s: Memory squeeze, dropping packet\n", dev->name); -#endif dev->stats.rx_dropped++; return; } diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index 110d26f4c602..afa8e3af2c4d 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -580,12 +580,9 @@ alloc_list (struct net_device *dev) skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz); np->rx_skbuff[i] = skb; - if (skb == NULL) { - printk (KERN_ERR - "%s: alloc_list: allocate Rx buffer error! ", - dev->name); + if (skb == NULL) break; - } + /* Rubicon now supports 40 bits of addressing space. */ np->rx_ring[i].fraginfo = cpu_to_le64 ( pci_map_single ( diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 069a155d16ed..f97c60f78089 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -743,8 +743,6 @@ fec_enet_rx(struct net_device *ndev, int budget) skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN); if (unlikely(!skb)) { - printk("%s: Memory squeeze, dropping packet.\n", - ndev->name); ndev->stats.rx_dropped++; } else { skb_reserve(skb, NET_IP_ALIGN); diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 46df28893c10..edc120094c34 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -177,8 +177,6 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) received++; netif_receive_skb(skb); } else { - dev_warn(fep->dev, - "Memory squeeze, dropping packet.\n"); fep->stats.rx_dropped++; skbn = skb; } @@ -309,8 +307,6 @@ static int fs_enet_rx_non_napi(struct net_device *dev) received++; netif_rx(skb); } else { - dev_warn(fep->dev, - "Memory squeeze, dropping packet.\n"); fep->stats.rx_dropped++; skbn = skb; } @@ -505,11 +501,9 @@ void fs_init_bds(struct net_device *dev) */ for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE); - if (skb == NULL) { - dev_warn(fep->dev, - "Memory squeeze, unable to allocate skb\n"); + if (skb == NULL) break; - } + skb_align(skb, ENET_RX_ALIGN); fep->rx_skbuff[i] = skb; CBDW_BUFADDR(bdp, @@ -593,13 +587,8 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev, /* Alloc new skb */ new_skb = netdev_alloc_skb(dev, skb->len + 4); - if (!new_skb) { - if (net_ratelimit()) { - dev_warn(fep->dev, - "Memory squeeze, dropping tx packet.\n"); - } + if (!new_skb) return NULL; - } /* Make sure new skb is properly aligned */ skb_align(new_skb, 4); diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index 2418faf2251a..84125707f321 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -1003,8 +1003,6 @@ static void fjn_rx(struct net_device *dev) } skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { - netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n", - pkt_len); outb(F_SKP_PKT, ioaddr + RX_SKIP); dev->stats.rx_dropped++; break; diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c index 1c54e229e3cc..e38816145395 100644 --- a/drivers/net/ethernet/i825xx/82596.c +++ b/drivers/net/ethernet/i825xx/82596.c @@ -798,16 +798,14 @@ static inline int i596_rx(struct net_device *dev) #ifdef __mc68000__ cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ); #endif - } - else + } else { skb = netdev_alloc_skb(dev, pkt_len + 2); + } memory_squeeze: if (skb == NULL) { /* XXX tulip.c can defer packets here!! */ - printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; - } - else { + } else { if (!rx_in_place) { /* 16 byte align the data fields */ skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c index f045ea4dc514..d653bac4cfc4 100644 --- a/drivers/net/ethernet/i825xx/lib82596.c +++ b/drivers/net/ethernet/i825xx/lib82596.c @@ -715,14 +715,12 @@ static inline int i596_rx(struct net_device *dev) rbd->v_data = newskb->data; rbd->b_data = SWAP32(dma_addr); DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd)); - } else + } else { skb = netdev_alloc_skb_ip_align(dev, pkt_len); + } memory_squeeze: if (skb == NULL) { /* XXX tulip.c can defer packets here!! */ - printk(KERN_ERR - "%s: i596_rx Memory squeeze, dropping packet.\n", - dev->name); dev->stats.rx_dropped++; } else { if (!rx_in_place) { diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 328f47c92e26..029633434474 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -402,7 +402,6 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) skb_arr_rq1[index] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); if (!skb_arr_rq1[index]) { - netdev_info(dev, "Unable to allocate enough skb in the array\n"); pr->rq1_skba.os_skbs = fill_wqes - i; break; } @@ -432,10 +431,8 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a) for (i = 0; i < nr_rq1a; i++) { skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); - if (!skb_arr_rq1[i]) { - netdev_info(dev, "Not enough memory to allocate skb array\n"); + if (!skb_arr_rq1[i]) break; - } } /* Ring doorbell */ ehea_update_rq1a(pr->qp, i - 1); @@ -695,10 +692,8 @@ static int ehea_proc_rwqes(struct net_device *dev, skb = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); - if (!skb) { - netdev_err(dev, "Not enough memory to allocate skb\n"); + if (!skb) break; - } } skb_copy_to_linear_data(skb, ((char *)cqe) + 64, cqe->num_bytes_transfered - 4); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c index 3488c6d9e6b5..2448f0d669e6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c @@ -58,10 +58,9 @@ static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv) /* build the pkt before xmit */ skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN); - if (!skb) { - en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n"); + if (!skb) return -ENOMEM; - } + skb_reserve(skb, NET_IP_ALIGN); ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr)); diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index 46795e403467..1bd419dbda6d 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -424,7 +424,6 @@ static void sonic_rx(struct net_device *dev) /* Malloc up new buffer. */ new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); if (new_skb == NULL) { - printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; break; } diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 63e7af44366f..cb9e63831500 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -152,8 +152,6 @@ static void netx_eth_receive(struct net_device *ndev) skb = netdev_alloc_skb(ndev, len); if (unlikely(skb == NULL)) { - printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", - ndev->name); ndev->stats.rx_dropped++; return; } diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c index 162da8975b05..539d2028e456 100644 --- a/drivers/net/ethernet/nuvoton/w90p910_ether.c +++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c @@ -737,7 +737,6 @@ static void netdev_rx(struct net_device *dev) data = ether->rdesc->recv_buf[ether->cur_rx]; skb = netdev_alloc_skb(dev, length + 2); if (!skb) { - dev_err(&pdev->dev, "get skb buffer error\n"); ether->stats.rx_dropped++; return; } diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 0b8de12bcbca..b62262cfe4d9 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -5025,7 +5025,6 @@ static int nv_loopback_test(struct net_device *dev) pkt_len = ETH_DATA_LEN; tx_skb = netdev_alloc_skb(dev, pkt_len); if (!tx_skb) { - netdev_err(dev, "netdev_alloc_skb() failed during loopback test\n"); ret = 0; goto out; } diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 8fd38cb6d26a..91a8fcd6c246 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -312,7 +312,6 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, lrg_buf_cb->skb = netdev_alloc_skb(qdev->ndev, qdev->lrg_buffer_len); if (unlikely(!lrg_buf_cb->skb)) { - netdev_err(qdev->ndev, "failed netdev_alloc_skb()\n"); qdev->lrg_buf_skb_check++; } else { /* diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index b13ab544a7eb..1dd778a6f01e 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1211,8 +1211,6 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) netdev_alloc_skb(qdev->ndev, SMALL_BUFFER_SIZE); if (sbq_desc->p.skb == NULL) { - netif_err(qdev, probe, qdev->ndev, - "Couldn't get an skb.\n"); rx_ring->sbq_clean_idx = clean_idx; return; } @@ -1519,8 +1517,6 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, skb = netdev_alloc_skb(ndev, length); if (!skb) { - netif_err(qdev, drv, qdev->ndev, - "Couldn't get an skb, need to unwind!.\n"); rx_ring->rx_dropped++; put_page(lbq_desc->p.pg_chunk.page); return; @@ -1605,8 +1601,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, /* Allocate new_skb and copy */ new_skb = netdev_alloc_skb(qdev->ndev, length + NET_IP_ALIGN); if (new_skb == NULL) { - netif_err(qdev, probe, qdev->ndev, - "No skb available, drop the packet.\n"); rx_ring->rx_dropped++; return; } diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index d5622ab5a1da..e9dc84943cfc 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -350,7 +350,6 @@ static int r6040_alloc_rxbufs(struct net_device *dev) do { skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); if (!skb) { - netdev_err(dev, "failed to alloc skb for rx\n"); rc = -ENOMEM; goto err_exit; } diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 1276ac71353a..3ccedeb8aba0 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -2041,8 +2041,6 @@ keep_pkt: netif_receive_skb (skb); } else { - if (net_ratelimit()) - netdev_warn(dev, "Memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; } received++; diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c index 9f2d416de750..d77d60ea8202 100644 --- a/drivers/net/ethernet/realtek/atp.c +++ b/drivers/net/ethernet/realtek/atp.c @@ -782,8 +782,6 @@ static void net_rx(struct net_device *dev) skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { - printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", - dev->name); dev->stats.rx_dropped++; goto done; } diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c index 3aca57853ed4..bdac936a68bc 100644 --- a/drivers/net/ethernet/seeq/ether3.c +++ b/drivers/net/ethernet/seeq/ether3.c @@ -651,8 +651,11 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); received ++; - } else - goto dropping; + } else { + ether3_outw(next_ptr >> 8, REG_RECVEND); + dev->stats.rx_dropped++; + goto done; + } } else { struct net_device_stats *stats = &dev->stats; ether3_outw(next_ptr >> 8, REG_RECVEND); @@ -679,21 +682,6 @@ done: } return maxcnt; - -dropping:{ - static unsigned long last_warned; - - ether3_outw(next_ptr >> 8, REG_RECVEND); - /* - * Don't print this message too many times... - */ - if (time_after(jiffies, last_warned + 10 * HZ)) { - last_warned = jiffies; - printk("%s: memory squeeze, dropping packet.\n", dev->name); - } - dev->stats.rx_dropped++; - goto done; - } } /* diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index 0fde9ca28269..0ad5694b41f8 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -381,8 +381,6 @@ memory_squeeze: dev->stats.rx_packets++; dev->stats.rx_bytes += len; } else { - printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", - dev->name); dev->stats.rx_dropped++; } } else { diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index efca14eaefa9..e45829628d5f 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -1841,15 +1841,12 @@ refill_rx_ring: entry = sis_priv->dirty_rx % NUM_RX_DESC; if (sis_priv->rx_skbuff[entry] == NULL) { - if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) { + skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE); + if (skb == NULL) { /* not enough memory for skbuff, this makes a * "hole" on the buffer ring, it is not clear * how the hardware will react to this kind * of degenerated buffer */ - if (netif_msg_rx_err(sis_priv)) - printk(KERN_INFO "%s: Memory squeeze, " - "deferring packet.\n", - net_dev->name); net_dev->stats.rx_dropped++; break; } diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c index 50823da9dc1e..e85c2e7e8246 100644 --- a/drivers/net/ethernet/smsc/smc9194.c +++ b/drivers/net/ethernet/smsc/smc9194.c @@ -1223,9 +1223,7 @@ static void smc_rcv(struct net_device *dev) dev->stats.multicast++; skb = netdev_alloc_skb(dev, packet_length + 5); - if ( skb == NULL ) { - printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n"); dev->stats.rx_dropped++; goto done; } diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 591650a8de38..dfbf978315df 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -465,8 +465,6 @@ static inline void smc_rcv(struct net_device *dev) */ skb = netdev_alloc_skb(dev, packet_len); if (unlikely(skb == NULL)) { - printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", - dev->name); SMC_WAIT_MMU_BUSY(lp); SMC_SET_MMU_CMD(lp, MC_RELEASE); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index d457fa2d7509..ffa5c4ad1210 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -848,10 +848,8 @@ static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index) BUG_ON(pd->rx_buffers[index].skb); BUG_ON(pd->rx_buffers[index].mapping); - if (unlikely(!skb)) { - smsc_warn(RX_ERR, "Failed to allocate new skb!"); + if (unlikely(!skb)) return -ENOMEM; - } mapping = pci_map_single(pd->pdev, skb_tail_pointer(skb), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 49bf3e2eb652..8182591bc187 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -414,7 +414,7 @@ static void qe_rx(struct sunqe *qep) struct qe_rxd *this; struct sunqe_buffers *qbufs = qep->buffers; __u32 qbufs_dvma = qep->buffers_dvma; - int elem = qep->rx_new, drops = 0; + int elem = qep->rx_new; u32 flags; this = &rxbase[elem]; @@ -436,7 +436,6 @@ static void qe_rx(struct sunqe *qep) } else { skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { - drops++; dev->stats.rx_dropped++; } else { skb_reserve(skb, 2); @@ -456,8 +455,6 @@ static void qe_rx(struct sunqe *qep) this = &rxbase[elem]; } qep->rx_new = elem; - if (drops) - printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", qep->dev->name); } static void qe_tx_reclaim(struct sunqe *qep); diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index e15cc71b826d..e8824cea093b 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1102,10 +1102,9 @@ static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f) dno = bdx_rxdb_available(db) - 1; while (dno > 0) { skb = netdev_alloc_skb(priv->ndev, f->m.pktsz + NET_IP_ALIGN); - if (!skb) { - pr_err("NO MEM: netdev_alloc_skb failed\n"); + if (!skb) break; - } + skb_reserve(skb, NET_IP_ALIGN); idx = bdx_rxdb_alloc_elem(db); diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 22725386c5de..bdda36f8e541 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -1911,10 +1911,8 @@ static void tlan_reset_lists(struct net_device *dev) list->frame_size = TLAN_MAX_FRAME_SIZE; list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5); - if (!skb) { - netdev_err(dev, "Out of memory for received data\n"); + if (!skb) break; - } list->buffer[0].address = pci_map_single(priv->pci_dev, skb->data, diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 9fc2ada4c3c2..5ac43e4ace25 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -273,11 +273,9 @@ static int temac_dma_bd_init(struct net_device *ndev) skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); - - if (skb == 0) { - dev_err(&ndev->dev, "alloc_skb error %d\n", i); + if (!skb) goto out; - } + lp->rx_skb[i] = skb; /* returns physical address of skb->data */ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, @@ -789,9 +787,7 @@ static void ll_temac_recv(struct net_device *ndev) new_skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); - - if (new_skb == 0) { - dev_err(&ndev->dev, "no memory for new sk_buff\n"); + if (!new_skb) { spin_unlock_irqrestore(&lp->rx_lock, flags); return; } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 278c9db3b5b8..397d4a6a1f30 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -235,10 +235,8 @@ static int axienet_dma_bd_init(struct net_device *ndev) ((i + 1) % RX_BD_NUM); skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); - if (!skb) { - dev_err(&ndev->dev, "alloc_skb error %d\n", i); + if (!skb) goto out; - } lp->rx_bd_v[i].sw_id_offset = (u32) skb; lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, @@ -777,10 +775,9 @@ static void axienet_recv(struct net_device *ndev) packets++; new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); - if (!new_skb) { - dev_err(&ndev->dev, "no memory for new sk_buff\n"); + if (!new_skb) return; - } + cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, lp->max_frm_size, DMA_FROM_DEVICE); diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index 98e09d0d3ce2..76210abf2e9b 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -1041,7 +1041,6 @@ xirc2ps_interrupt(int irq, void *dev_id) /* 1 extra so we can use insw */ skb = netdev_alloc_skb(dev, pktlen + 3); if (!skb) { - pr_notice("low memory, packet dropped (size=%u)\n", pktlen); dev->stats.rx_dropped++; } else { /* okay get the packet */ skb_reserve(skb, 2); -- cgit From 6aed0c8bf7d2f389b472834053eb6e3bd6926999 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Sat, 9 Mar 2013 16:38:39 +0000 Subject: tunnel: use iptunnel_xmit() again With recent patches from Pravin, most tunnels can't use iptunnel_xmit() any more, due to ip_select_ident() and skb->ip_summed. But we can just move these operations out of iptunnel_xmit(), so that tunnels can use it again. This by the way fixes a bug in vxlan (missing nf_reset()) for net-next. Cc: Pravin B Shelar Cc: Stephen Hemminger Cc: "David S. Miller" Signed-off-by: Cong Wang Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 14 +------------- include/net/ipip.h | 3 --- net/ipv4/ip_gre.c | 16 +--------------- net/ipv4/ipip.c | 18 +----------------- net/ipv6/sit.c | 2 ++ 5 files changed, 5 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index f057ec00bba3..f3a135cb50a9 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -855,7 +855,6 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) __u16 src_port; __be16 df = 0; __u8 tos, ttl; - int err; bool did_rsc = false; const struct vxlan_fdb *f; @@ -980,18 +979,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) if (handle_offloads(skb)) goto drop; - err = ip_local_out(skb); - if (likely(net_xmit_eval(err) == 0)) { - struct vxlan_stats *stats = this_cpu_ptr(vxlan->stats); - - u64_stats_update_begin(&stats->syncp); - stats->tx_packets++; - stats->tx_bytes += pkt_len; - u64_stats_update_end(&stats->syncp); - } else { - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - } + iptunnel_xmit(skb, dev); return NETDEV_TX_OK; drop: diff --git a/include/net/ipip.h b/include/net/ipip.h index fd19625ff99d..0c046e3bca05 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -51,13 +51,10 @@ struct ip_tunnel_prl_entry { static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev) { int err; - struct iphdr *iph = ip_hdr(skb); int pkt_len = skb->len - skb_transport_offset(skb); struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats); nf_reset(skb); - skb->ip_summed = CHECKSUM_NONE; - ip_select_ident(iph, skb_dst(skb), NULL); err = ip_local_out(skb); if (likely(net_xmit_eval(err) == 0)) { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d0ef0e674ec5..a13a0972a57f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -762,7 +762,6 @@ error: static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { - struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats); struct ip_tunnel *tunnel = netdev_priv(dev); const struct iphdr *old_iph; const struct iphdr *tiph; @@ -778,7 +777,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev int mtu; u8 ttl; int err; - int pkt_len; skb = handle_offloads(tunnel, skb); if (IS_ERR(skb)) { @@ -1022,19 +1020,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } } - nf_reset(skb); - - pkt_len = skb->len - skb_transport_offset(skb); - err = ip_local_out(skb); - if (likely(net_xmit_eval(err) == 0)) { - u64_stats_update_begin(&tstats->syncp); - tstats->tx_bytes += pkt_len; - tstats->tx_packets++; - u64_stats_update_end(&tstats->syncp); - } else { - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - } + iptunnel_xmit(skb, dev); return NETDEV_TX_OK; #if IS_ENABLED(CONFIG_IPV6) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index b50435ba0ce5..34e006fe2d87 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -478,8 +478,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) __be32 dst = tiph->daddr; struct flowi4 fl4; int mtu; - int err; - int pkt_len; if (skb->protocol != htons(ETH_P_IP)) goto tx_error; @@ -600,21 +598,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if ((iph->ttl = tiph->ttl) == 0) iph->ttl = old_iph->ttl; - nf_reset(skb); - - pkt_len = skb->len - skb_transport_offset(skb); - err = ip_local_out(skb); - if (likely(net_xmit_eval(err) == 0)) { - struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats); - - u64_stats_update_begin(&tstats->syncp); - tstats->tx_bytes += pkt_len; - tstats->tx_packets++; - u64_stats_update_end(&tstats->syncp); - } else { - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - } + iptunnel_xmit(skb, dev); return NETDEV_TX_OK; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 02f96dcbcf02..898e671a526b 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -899,6 +899,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, if ((iph->ttl = tiph->ttl) == 0) iph->ttl = iph6->hop_limit; + skb->ip_summed = CHECKSUM_NONE; + ip_select_ident(iph, skb_dst(skb), NULL); iptunnel_xmit(skb, dev); return NETDEV_TX_OK; -- cgit From cadc4ab8f6f73719ef0e124320cdd210d1c9ff3e Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Wed, 20 Feb 2013 17:10:24 +0100 Subject: crypto: atmel-aes - add support for latest release of the IP (0x130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates from previous IP release (0x120): - add cfb64 support - add DMA double input buffer support Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Signed-off-by: Herbert Xu --- drivers/crypto/atmel-aes.c | 471 +++++++++++++++++++++++++++++++++------------ 1 file changed, 353 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index 6f22ba51f969..c1efd910d97b 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include "atmel-aes-regs.h" #define CFB8_BLOCK_SIZE 1 @@ -47,7 +47,7 @@ #define CFB64_BLOCK_SIZE 8 /* AES flags */ -#define AES_FLAGS_MODE_MASK 0x01ff +#define AES_FLAGS_MODE_MASK 0x03ff #define AES_FLAGS_ENCRYPT BIT(0) #define AES_FLAGS_CBC BIT(1) #define AES_FLAGS_CFB BIT(2) @@ -55,21 +55,26 @@ #define AES_FLAGS_CFB16 BIT(4) #define AES_FLAGS_CFB32 BIT(5) #define AES_FLAGS_CFB64 BIT(6) -#define AES_FLAGS_OFB BIT(7) -#define AES_FLAGS_CTR BIT(8) +#define AES_FLAGS_CFB128 BIT(7) +#define AES_FLAGS_OFB BIT(8) +#define AES_FLAGS_CTR BIT(9) #define AES_FLAGS_INIT BIT(16) #define AES_FLAGS_DMA BIT(17) #define AES_FLAGS_BUSY BIT(18) +#define AES_FLAGS_FAST BIT(19) -#define AES_FLAGS_DUALBUFF BIT(24) - -#define ATMEL_AES_QUEUE_LENGTH 1 -#define ATMEL_AES_CACHE_SIZE 0 +#define ATMEL_AES_QUEUE_LENGTH 50 #define ATMEL_AES_DMA_THRESHOLD 16 +struct atmel_aes_caps { + bool has_dualbuff; + bool has_cfb64; + u32 max_burst_size; +}; + struct atmel_aes_dev; struct atmel_aes_ctx { @@ -77,6 +82,8 @@ struct atmel_aes_ctx { int keylen; u32 key[AES_KEYSIZE_256 / sizeof(u32)]; + + u16 block_size; }; struct atmel_aes_reqctx { @@ -112,20 +119,27 @@ struct atmel_aes_dev { struct scatterlist *in_sg; unsigned int nb_in_sg; - + size_t in_offset; struct scatterlist *out_sg; unsigned int nb_out_sg; + size_t out_offset; size_t bufcnt; + size_t buflen; + size_t dma_size; - u8 buf_in[ATMEL_AES_DMA_THRESHOLD] __aligned(sizeof(u32)); - int dma_in; + void *buf_in; + int dma_in; + dma_addr_t dma_addr_in; struct atmel_aes_dma dma_lch_in; - u8 buf_out[ATMEL_AES_DMA_THRESHOLD] __aligned(sizeof(u32)); - int dma_out; + void *buf_out; + int dma_out; + dma_addr_t dma_addr_out; struct atmel_aes_dma dma_lch_out; + struct atmel_aes_caps caps; + u32 hw_version; }; @@ -165,6 +179,37 @@ static int atmel_aes_sg_length(struct ablkcipher_request *req, return sg_nb; } +static int atmel_aes_sg_copy(struct scatterlist **sg, size_t *offset, + void *buf, size_t buflen, size_t total, int out) +{ + unsigned int count, off = 0; + + while (buflen && total) { + count = min((*sg)->length - *offset, total); + count = min(count, buflen); + + if (!count) + return off; + + scatterwalk_map_and_copy(buf + off, *sg, *offset, count, out); + + off += count; + buflen -= count; + *offset += count; + total -= count; + + if (*offset == (*sg)->length) { + *sg = sg_next(*sg); + if (*sg) + *offset = 0; + else + total = 0; + } + } + + return off; +} + static inline u32 atmel_aes_read(struct atmel_aes_dev *dd, u32 offset) { return readl_relaxed(dd->io_base + offset); @@ -190,14 +235,6 @@ static void atmel_aes_write_n(struct atmel_aes_dev *dd, u32 offset, atmel_aes_write(dd, offset, *value); } -static void atmel_aes_dualbuff_test(struct atmel_aes_dev *dd) -{ - atmel_aes_write(dd, AES_MR, AES_MR_DUALBUFF); - - if (atmel_aes_read(dd, AES_MR) & AES_MR_DUALBUFF) - dd->flags |= AES_FLAGS_DUALBUFF; -} - static struct atmel_aes_dev *atmel_aes_find_dev(struct atmel_aes_ctx *ctx) { struct atmel_aes_dev *aes_dd = NULL; @@ -225,7 +262,7 @@ static int atmel_aes_hw_init(struct atmel_aes_dev *dd) if (!(dd->flags & AES_FLAGS_INIT)) { atmel_aes_write(dd, AES_CR, AES_CR_SWRST); - atmel_aes_dualbuff_test(dd); + atmel_aes_write(dd, AES_MR, 0xE << AES_MR_CKEY_OFFSET); dd->flags |= AES_FLAGS_INIT; dd->err = 0; } @@ -233,11 +270,19 @@ static int atmel_aes_hw_init(struct atmel_aes_dev *dd) return 0; } +static inline unsigned int atmel_aes_get_version(struct atmel_aes_dev *dd) +{ + return atmel_aes_read(dd, AES_HW_VERSION) & 0x00000fff; +} + static void atmel_aes_hw_version_init(struct atmel_aes_dev *dd) { atmel_aes_hw_init(dd); - dd->hw_version = atmel_aes_read(dd, AES_HW_VERSION); + dd->hw_version = atmel_aes_get_version(dd); + + dev_info(dd->dev, + "version: 0x%x\n", dd->hw_version); clk_disable_unprepare(dd->iclk); } @@ -260,50 +305,77 @@ static void atmel_aes_dma_callback(void *data) tasklet_schedule(&dd->done_task); } -static int atmel_aes_crypt_dma(struct atmel_aes_dev *dd) +static int atmel_aes_crypt_dma(struct atmel_aes_dev *dd, + dma_addr_t dma_addr_in, dma_addr_t dma_addr_out, int length) { + struct scatterlist sg[2]; struct dma_async_tx_descriptor *in_desc, *out_desc; - int nb_dma_sg_in, nb_dma_sg_out; - dd->nb_in_sg = atmel_aes_sg_length(dd->req, dd->in_sg); - if (!dd->nb_in_sg) - goto exit_err; + dd->dma_size = length; - nb_dma_sg_in = dma_map_sg(dd->dev, dd->in_sg, dd->nb_in_sg, - DMA_TO_DEVICE); - if (!nb_dma_sg_in) - goto exit_err; + if (!(dd->flags & AES_FLAGS_FAST)) { + dma_sync_single_for_device(dd->dev, dma_addr_in, length, + DMA_TO_DEVICE); + } - in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, dd->in_sg, - nb_dma_sg_in, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (dd->flags & AES_FLAGS_CFB8) { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_1_BYTE; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_1_BYTE; + } else if (dd->flags & AES_FLAGS_CFB16) { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_2_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_2_BYTES; + } else { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + } - if (!in_desc) - goto unmap_in; + if (dd->flags & (AES_FLAGS_CFB8 | AES_FLAGS_CFB16 | + AES_FLAGS_CFB32 | AES_FLAGS_CFB64)) { + dd->dma_lch_in.dma_conf.src_maxburst = 1; + dd->dma_lch_in.dma_conf.dst_maxburst = 1; + dd->dma_lch_out.dma_conf.src_maxburst = 1; + dd->dma_lch_out.dma_conf.dst_maxburst = 1; + } else { + dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; + dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; + dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; + dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; + } - /* callback not needed */ + dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); + dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); - dd->nb_out_sg = atmel_aes_sg_length(dd->req, dd->out_sg); - if (!dd->nb_out_sg) - goto unmap_in; + dd->flags |= AES_FLAGS_DMA; - nb_dma_sg_out = dma_map_sg(dd->dev, dd->out_sg, dd->nb_out_sg, - DMA_FROM_DEVICE); - if (!nb_dma_sg_out) - goto unmap_out; + sg_init_table(&sg[0], 1); + sg_dma_address(&sg[0]) = dma_addr_in; + sg_dma_len(&sg[0]) = length; - out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, dd->out_sg, - nb_dma_sg_out, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + sg_init_table(&sg[1], 1); + sg_dma_address(&sg[1]) = dma_addr_out; + sg_dma_len(&sg[1]) = length; + + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0], + 1, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!in_desc) + return -EINVAL; + out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1], + 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!out_desc) - goto unmap_out; + return -EINVAL; out_desc->callback = atmel_aes_dma_callback; out_desc->callback_param = dd; - dd->total -= dd->req->nbytes; - dmaengine_submit(out_desc); dma_async_issue_pending(dd->dma_lch_out.chan); @@ -311,15 +383,6 @@ static int atmel_aes_crypt_dma(struct atmel_aes_dev *dd) dma_async_issue_pending(dd->dma_lch_in.chan); return 0; - -unmap_out: - dma_unmap_sg(dd->dev, dd->out_sg, dd->nb_out_sg, - DMA_FROM_DEVICE); -unmap_in: - dma_unmap_sg(dd->dev, dd->in_sg, dd->nb_in_sg, - DMA_TO_DEVICE); -exit_err: - return -EINVAL; } static int atmel_aes_crypt_cpu_start(struct atmel_aes_dev *dd) @@ -352,30 +415,66 @@ static int atmel_aes_crypt_cpu_start(struct atmel_aes_dev *dd) static int atmel_aes_crypt_dma_start(struct atmel_aes_dev *dd) { - int err; + int err, fast = 0, in, out; + size_t count; + dma_addr_t addr_in, addr_out; + + if ((!dd->in_offset) && (!dd->out_offset)) { + /* check for alignment */ + in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)) && + IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size); + out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)) && + IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size); + fast = in && out; + + if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg)) + fast = 0; + } + + + if (fast) { + count = min(dd->total, sg_dma_len(dd->in_sg)); + count = min(count, sg_dma_len(dd->out_sg)); + + err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); + if (!err) { + dev_err(dd->dev, "dma_map_sg() error\n"); + return -EINVAL; + } + + err = dma_map_sg(dd->dev, dd->out_sg, 1, + DMA_FROM_DEVICE); + if (!err) { + dev_err(dd->dev, "dma_map_sg() error\n"); + dma_unmap_sg(dd->dev, dd->in_sg, 1, + DMA_TO_DEVICE); + return -EINVAL; + } + + addr_in = sg_dma_address(dd->in_sg); + addr_out = sg_dma_address(dd->out_sg); + + dd->flags |= AES_FLAGS_FAST; - if (dd->flags & AES_FLAGS_CFB8) { - dd->dma_lch_in.dma_conf.dst_addr_width = - DMA_SLAVE_BUSWIDTH_1_BYTE; - dd->dma_lch_out.dma_conf.src_addr_width = - DMA_SLAVE_BUSWIDTH_1_BYTE; - } else if (dd->flags & AES_FLAGS_CFB16) { - dd->dma_lch_in.dma_conf.dst_addr_width = - DMA_SLAVE_BUSWIDTH_2_BYTES; - dd->dma_lch_out.dma_conf.src_addr_width = - DMA_SLAVE_BUSWIDTH_2_BYTES; } else { - dd->dma_lch_in.dma_conf.dst_addr_width = - DMA_SLAVE_BUSWIDTH_4_BYTES; - dd->dma_lch_out.dma_conf.src_addr_width = - DMA_SLAVE_BUSWIDTH_4_BYTES; + /* use cache buffers */ + count = atmel_aes_sg_copy(&dd->in_sg, &dd->in_offset, + dd->buf_in, dd->buflen, dd->total, 0); + + addr_in = dd->dma_addr_in; + addr_out = dd->dma_addr_out; + + dd->flags &= ~AES_FLAGS_FAST; } - dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); - dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); + dd->total -= count; - dd->flags |= AES_FLAGS_DMA; - err = atmel_aes_crypt_dma(dd); + err = atmel_aes_crypt_dma(dd, addr_in, addr_out, count); + + if (err && (dd->flags & AES_FLAGS_FAST)) { + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); + } return err; } @@ -410,6 +509,8 @@ static int atmel_aes_write_ctrl(struct atmel_aes_dev *dd) valmr |= AES_MR_CFBS_32b; else if (dd->flags & AES_FLAGS_CFB64) valmr |= AES_MR_CFBS_64b; + else if (dd->flags & AES_FLAGS_CFB128) + valmr |= AES_MR_CFBS_128b; } else if (dd->flags & AES_FLAGS_OFB) { valmr |= AES_MR_OPMOD_OFB; } else if (dd->flags & AES_FLAGS_CTR) { @@ -423,7 +524,7 @@ static int atmel_aes_write_ctrl(struct atmel_aes_dev *dd) if (dd->total > ATMEL_AES_DMA_THRESHOLD) { valmr |= AES_MR_SMOD_IDATAR0; - if (dd->flags & AES_FLAGS_DUALBUFF) + if (dd->caps.has_dualbuff) valmr |= AES_MR_DUALBUFF; } else { valmr |= AES_MR_SMOD_AUTO; @@ -477,7 +578,9 @@ static int atmel_aes_handle_queue(struct atmel_aes_dev *dd, /* assign new request to device */ dd->req = req; dd->total = req->nbytes; + dd->in_offset = 0; dd->in_sg = req->src; + dd->out_offset = 0; dd->out_sg = req->dst; rctx = ablkcipher_request_ctx(req); @@ -506,18 +609,86 @@ static int atmel_aes_handle_queue(struct atmel_aes_dev *dd, static int atmel_aes_crypt_dma_stop(struct atmel_aes_dev *dd) { int err = -EINVAL; + size_t count; if (dd->flags & AES_FLAGS_DMA) { - dma_unmap_sg(dd->dev, dd->out_sg, - dd->nb_out_sg, DMA_FROM_DEVICE); - dma_unmap_sg(dd->dev, dd->in_sg, - dd->nb_in_sg, DMA_TO_DEVICE); err = 0; + if (dd->flags & AES_FLAGS_FAST) { + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); + } else { + dma_sync_single_for_device(dd->dev, dd->dma_addr_out, + dd->dma_size, DMA_FROM_DEVICE); + + /* copy data */ + count = atmel_aes_sg_copy(&dd->out_sg, &dd->out_offset, + dd->buf_out, dd->buflen, dd->dma_size, 1); + if (count != dd->dma_size) { + err = -EINVAL; + pr_err("not all data converted: %u\n", count); + } + } } return err; } + +static int atmel_aes_buff_init(struct atmel_aes_dev *dd) +{ + int err = -ENOMEM; + + dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, 0); + dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, 0); + dd->buflen = PAGE_SIZE; + dd->buflen &= ~(AES_BLOCK_SIZE - 1); + + if (!dd->buf_in || !dd->buf_out) { + dev_err(dd->dev, "unable to alloc pages.\n"); + goto err_alloc; + } + + /* MAP here */ + dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, + dd->buflen, DMA_TO_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_in)) { + dev_err(dd->dev, "dma %d bytes error\n", dd->buflen); + err = -EINVAL; + goto err_map_in; + } + + dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, + dd->buflen, DMA_FROM_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_out)) { + dev_err(dd->dev, "dma %d bytes error\n", dd->buflen); + err = -EINVAL; + goto err_map_out; + } + + return 0; + +err_map_out: + dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, + DMA_TO_DEVICE); +err_map_in: + free_page((unsigned long)dd->buf_out); + free_page((unsigned long)dd->buf_in); +err_alloc: + if (err) + pr_err("error: %d\n", err); + return err; +} + +static void atmel_aes_buff_cleanup(struct atmel_aes_dev *dd) +{ + dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, + DMA_FROM_DEVICE); + dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, + DMA_TO_DEVICE); + free_page((unsigned long)dd->buf_out); + free_page((unsigned long)dd->buf_in); +} + static int atmel_aes_crypt(struct ablkcipher_request *req, unsigned long mode) { struct atmel_aes_ctx *ctx = crypto_ablkcipher_ctx( @@ -525,9 +696,30 @@ static int atmel_aes_crypt(struct ablkcipher_request *req, unsigned long mode) struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req); struct atmel_aes_dev *dd; - if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { - pr_err("request size is not exact amount of AES blocks\n"); - return -EINVAL; + if (mode & AES_FLAGS_CFB8) { + if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) { + pr_err("request size is not exact amount of CFB8 blocks\n"); + return -EINVAL; + } + ctx->block_size = CFB8_BLOCK_SIZE; + } else if (mode & AES_FLAGS_CFB16) { + if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) { + pr_err("request size is not exact amount of CFB16 blocks\n"); + return -EINVAL; + } + ctx->block_size = CFB16_BLOCK_SIZE; + } else if (mode & AES_FLAGS_CFB32) { + if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) { + pr_err("request size is not exact amount of CFB32 blocks\n"); + return -EINVAL; + } + ctx->block_size = CFB32_BLOCK_SIZE; + } else { + if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { + pr_err("request size is not exact amount of AES blocks\n"); + return -EINVAL; + } + ctx->block_size = AES_BLOCK_SIZE; } dd = atmel_aes_find_dev(ctx); @@ -551,14 +743,12 @@ static bool atmel_aes_filter(struct dma_chan *chan, void *slave) } } -static int atmel_aes_dma_init(struct atmel_aes_dev *dd) +static int atmel_aes_dma_init(struct atmel_aes_dev *dd, + struct crypto_platform_data *pdata) { int err = -ENOMEM; - struct aes_platform_data *pdata; dma_cap_mask_t mask_in, mask_out; - pdata = dd->dev->platform_data; - if (pdata && pdata->dma_slave->txdata.dma_dev && pdata->dma_slave->rxdata.dma_dev) { @@ -568,28 +758,38 @@ static int atmel_aes_dma_init(struct atmel_aes_dev *dd) dd->dma_lch_in.chan = dma_request_channel(mask_in, atmel_aes_filter, &pdata->dma_slave->rxdata); + if (!dd->dma_lch_in.chan) goto err_dma_in; dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + AES_IDATAR(0); - dd->dma_lch_in.dma_conf.src_maxburst = 1; - dd->dma_lch_in.dma_conf.dst_maxburst = 1; + dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; + dd->dma_lch_in.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; dd->dma_lch_in.dma_conf.device_fc = false; dma_cap_zero(mask_out); dma_cap_set(DMA_SLAVE, mask_out); dd->dma_lch_out.chan = dma_request_channel(mask_out, atmel_aes_filter, &pdata->dma_slave->txdata); + if (!dd->dma_lch_out.chan) goto err_dma_out; dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + AES_ODATAR(0); - dd->dma_lch_out.dma_conf.src_maxburst = 1; - dd->dma_lch_out.dma_conf.dst_maxburst = 1; + dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; + dd->dma_lch_out.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; dd->dma_lch_out.dma_conf.device_fc = false; return 0; @@ -665,13 +865,13 @@ static int atmel_aes_ofb_decrypt(struct ablkcipher_request *req) static int atmel_aes_cfb_encrypt(struct ablkcipher_request *req) { return atmel_aes_crypt(req, - AES_FLAGS_ENCRYPT | AES_FLAGS_CFB); + AES_FLAGS_ENCRYPT | AES_FLAGS_CFB | AES_FLAGS_CFB128); } static int atmel_aes_cfb_decrypt(struct ablkcipher_request *req) { return atmel_aes_crypt(req, - AES_FLAGS_CFB); + AES_FLAGS_CFB | AES_FLAGS_CFB128); } static int atmel_aes_cfb64_encrypt(struct ablkcipher_request *req) @@ -753,7 +953,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0xf, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -773,7 +973,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0xf, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -794,7 +994,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0xf, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -815,7 +1015,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0xf, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -836,7 +1036,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB32_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0x3, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -857,7 +1057,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB16_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0x1, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -899,7 +1099,7 @@ static struct crypto_alg aes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0xf, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -915,15 +1115,14 @@ static struct crypto_alg aes_algs[] = { }, }; -static struct crypto_alg aes_cfb64_alg[] = { -{ +static struct crypto_alg aes_cfb64_alg = { .cra_name = "cfb64(aes)", .cra_driver_name = "atmel-cfb64-aes", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB64_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_aes_ctx), - .cra_alignmask = 0x0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_aes_cra_init, @@ -936,7 +1135,6 @@ static struct crypto_alg aes_cfb64_alg[] = { .encrypt = atmel_aes_cfb64_encrypt, .decrypt = atmel_aes_cfb64_decrypt, } -}, }; static void atmel_aes_queue_task(unsigned long data) @@ -969,7 +1167,14 @@ static void atmel_aes_done_task(unsigned long data) err = dd->err ? : err; if (dd->total && !err) { - err = atmel_aes_crypt_dma_start(dd); + if (dd->flags & AES_FLAGS_FAST) { + dd->in_sg = sg_next(dd->in_sg); + dd->out_sg = sg_next(dd->out_sg); + if (!dd->in_sg || !dd->out_sg) + err = -EINVAL; + } + if (!err) + err = atmel_aes_crypt_dma_start(dd); if (!err) return; /* DMA started. Not fininishing. */ } @@ -1003,8 +1208,8 @@ static void atmel_aes_unregister_algs(struct atmel_aes_dev *dd) for (i = 0; i < ARRAY_SIZE(aes_algs); i++) crypto_unregister_alg(&aes_algs[i]); - if (dd->hw_version >= 0x130) - crypto_unregister_alg(&aes_cfb64_alg[0]); + if (dd->caps.has_cfb64) + crypto_unregister_alg(&aes_cfb64_alg); } static int atmel_aes_register_algs(struct atmel_aes_dev *dd) @@ -1017,10 +1222,8 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd) goto err_aes_algs; } - atmel_aes_hw_version_init(dd); - - if (dd->hw_version >= 0x130) { - err = crypto_register_alg(&aes_cfb64_alg[0]); + if (dd->caps.has_cfb64) { + err = crypto_register_alg(&aes_cfb64_alg); if (err) goto err_aes_cfb64_alg; } @@ -1036,10 +1239,32 @@ err_aes_algs: return err; } +static void atmel_aes_get_cap(struct atmel_aes_dev *dd) +{ + dd->caps.has_dualbuff = 0; + dd->caps.has_cfb64 = 0; + dd->caps.max_burst_size = 1; + + /* keep only major version number */ + switch (dd->hw_version & 0xff0) { + case 0x130: + dd->caps.has_dualbuff = 1; + dd->caps.has_cfb64 = 1; + dd->caps.max_burst_size = 4; + break; + case 0x120: + break; + default: + dev_warn(dd->dev, + "Unmanaged aes version, set minimum capabilities\n"); + break; + } +} + static int atmel_aes_probe(struct platform_device *pdev) { struct atmel_aes_dev *aes_dd; - struct aes_platform_data *pdata; + struct crypto_platform_data *pdata; struct device *dev = &pdev->dev; struct resource *aes_res; unsigned long aes_phys_size; @@ -1099,7 +1324,7 @@ static int atmel_aes_probe(struct platform_device *pdev) } /* Initializing the clock */ - aes_dd->iclk = clk_get(&pdev->dev, NULL); + aes_dd->iclk = clk_get(&pdev->dev, "aes_clk"); if (IS_ERR(aes_dd->iclk)) { dev_err(dev, "clock intialization failed.\n"); err = PTR_ERR(aes_dd->iclk); @@ -1113,7 +1338,15 @@ static int atmel_aes_probe(struct platform_device *pdev) goto aes_io_err; } - err = atmel_aes_dma_init(aes_dd); + atmel_aes_hw_version_init(aes_dd); + + atmel_aes_get_cap(aes_dd); + + err = atmel_aes_buff_init(aes_dd); + if (err) + goto err_aes_buff; + + err = atmel_aes_dma_init(aes_dd, pdata); if (err) goto err_aes_dma; @@ -1135,6 +1368,8 @@ err_algs: spin_unlock(&atmel_aes.lock); atmel_aes_dma_cleanup(aes_dd); err_aes_dma: + atmel_aes_buff_cleanup(aes_dd); +err_aes_buff: iounmap(aes_dd->io_base); aes_io_err: clk_put(aes_dd->iclk); -- cgit From 1f858040c2f78013fd2b10ddeb9dc157c3362b04 Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Wed, 20 Feb 2013 17:10:25 +0100 Subject: crypto: atmel-tdes - add support for latest release of the IP (0x700) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update from previous IP release (0x600): - add DMA support (previous IP release use PDC) Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Signed-off-by: Herbert Xu --- drivers/crypto/atmel-tdes-regs.h | 2 + drivers/crypto/atmel-tdes.c | 394 +++++++++++++++++++++++++++++++++------ 2 files changed, 343 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/atmel-tdes-regs.h b/drivers/crypto/atmel-tdes-regs.h index 5ac2a900d80c..f86734d0fda4 100644 --- a/drivers/crypto/atmel-tdes-regs.h +++ b/drivers/crypto/atmel-tdes-regs.h @@ -69,6 +69,8 @@ #define TDES_XTEARNDR_XTEA_RNDS_MASK (0x3F << 0) #define TDES_XTEARNDR_XTEA_RNDS_OFFSET 0 +#define TDES_HW_VERSION 0xFC + #define TDES_RPR 0x100 #define TDES_RCR 0x104 #define TDES_TPR 0x108 diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 7c73fbb17538..4a99564a08e6 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c @@ -38,29 +38,35 @@ #include #include #include +#include #include "atmel-tdes-regs.h" /* TDES flags */ -#define TDES_FLAGS_MODE_MASK 0x007f +#define TDES_FLAGS_MODE_MASK 0x00ff #define TDES_FLAGS_ENCRYPT BIT(0) #define TDES_FLAGS_CBC BIT(1) #define TDES_FLAGS_CFB BIT(2) #define TDES_FLAGS_CFB8 BIT(3) #define TDES_FLAGS_CFB16 BIT(4) #define TDES_FLAGS_CFB32 BIT(5) -#define TDES_FLAGS_OFB BIT(6) +#define TDES_FLAGS_CFB64 BIT(6) +#define TDES_FLAGS_OFB BIT(7) #define TDES_FLAGS_INIT BIT(16) #define TDES_FLAGS_FAST BIT(17) #define TDES_FLAGS_BUSY BIT(18) +#define TDES_FLAGS_DMA BIT(19) -#define ATMEL_TDES_QUEUE_LENGTH 1 +#define ATMEL_TDES_QUEUE_LENGTH 50 #define CFB8_BLOCK_SIZE 1 #define CFB16_BLOCK_SIZE 2 #define CFB32_BLOCK_SIZE 4 -#define CFB64_BLOCK_SIZE 8 +struct atmel_tdes_caps { + bool has_dma; + u32 has_cfb_3keys; +}; struct atmel_tdes_dev; @@ -70,12 +76,19 @@ struct atmel_tdes_ctx { int keylen; u32 key[3*DES_KEY_SIZE / sizeof(u32)]; unsigned long flags; + + u16 block_size; }; struct atmel_tdes_reqctx { unsigned long mode; }; +struct atmel_tdes_dma { + struct dma_chan *chan; + struct dma_slave_config dma_conf; +}; + struct atmel_tdes_dev { struct list_head list; unsigned long phys_base; @@ -99,8 +112,10 @@ struct atmel_tdes_dev { size_t total; struct scatterlist *in_sg; + unsigned int nb_in_sg; size_t in_offset; struct scatterlist *out_sg; + unsigned int nb_out_sg; size_t out_offset; size_t buflen; @@ -109,10 +124,16 @@ struct atmel_tdes_dev { void *buf_in; int dma_in; dma_addr_t dma_addr_in; + struct atmel_tdes_dma dma_lch_in; void *buf_out; int dma_out; dma_addr_t dma_addr_out; + struct atmel_tdes_dma dma_lch_out; + + struct atmel_tdes_caps caps; + + u32 hw_version; }; struct atmel_tdes_drv { @@ -207,6 +228,31 @@ static int atmel_tdes_hw_init(struct atmel_tdes_dev *dd) return 0; } +static inline unsigned int atmel_tdes_get_version(struct atmel_tdes_dev *dd) +{ + return atmel_tdes_read(dd, TDES_HW_VERSION) & 0x00000fff; +} + +static void atmel_tdes_hw_version_init(struct atmel_tdes_dev *dd) +{ + atmel_tdes_hw_init(dd); + + dd->hw_version = atmel_tdes_get_version(dd); + + dev_info(dd->dev, + "version: 0x%x\n", dd->hw_version); + + clk_disable_unprepare(dd->iclk); +} + +static void atmel_tdes_dma_callback(void *data) +{ + struct atmel_tdes_dev *dd = data; + + /* dma_lch_out - completed */ + tasklet_schedule(&dd->done_task); +} + static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) { int err; @@ -217,7 +263,9 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) if (err) return err; - atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS); + if (!dd->caps.has_dma) + atmel_tdes_write(dd, TDES_PTCR, + TDES_PTCR_TXTDIS | TDES_PTCR_RXTDIS); /* MR register must be set before IV registers */ if (dd->ctx->keylen > (DES_KEY_SIZE << 1)) { @@ -241,6 +289,8 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) valmr |= TDES_MR_CFBS_16b; else if (dd->flags & TDES_FLAGS_CFB32) valmr |= TDES_MR_CFBS_32b; + else if (dd->flags & TDES_FLAGS_CFB64) + valmr |= TDES_MR_CFBS_64b; } else if (dd->flags & TDES_FLAGS_OFB) { valmr |= TDES_MR_OPMOD_OFB; } @@ -262,7 +312,7 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) return 0; } -static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) +static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd) { int err = 0; size_t count; @@ -288,7 +338,7 @@ static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) return err; } -static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) +static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd) { int err = -ENOMEM; @@ -333,7 +383,7 @@ err_alloc: return err; } -static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) +static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) { dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, DMA_FROM_DEVICE); @@ -343,7 +393,7 @@ static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) free_page((unsigned long)dd->buf_in); } -static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, +static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, dma_addr_t dma_addr_out, int length) { struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); @@ -379,7 +429,76 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, return 0; } -static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) +static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, + dma_addr_t dma_addr_out, int length) +{ + struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); + struct atmel_tdes_dev *dd = ctx->dd; + struct scatterlist sg[2]; + struct dma_async_tx_descriptor *in_desc, *out_desc; + + dd->dma_size = length; + + if (!(dd->flags & TDES_FLAGS_FAST)) { + dma_sync_single_for_device(dd->dev, dma_addr_in, length, + DMA_TO_DEVICE); + } + + if (dd->flags & TDES_FLAGS_CFB8) { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_1_BYTE; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_1_BYTE; + } else if (dd->flags & TDES_FLAGS_CFB16) { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_2_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_2_BYTES; + } else { + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + } + + dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); + dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); + + dd->flags |= TDES_FLAGS_DMA; + + sg_init_table(&sg[0], 1); + sg_dma_address(&sg[0]) = dma_addr_in; + sg_dma_len(&sg[0]) = length; + + sg_init_table(&sg[1], 1); + sg_dma_address(&sg[1]) = dma_addr_out; + sg_dma_len(&sg[1]) = length; + + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0], + 1, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!in_desc) + return -EINVAL; + + out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1], + 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!out_desc) + return -EINVAL; + + out_desc->callback = atmel_tdes_dma_callback; + out_desc->callback_param = dd; + + dmaengine_submit(out_desc); + dma_async_issue_pending(dd->dma_lch_out.chan); + + dmaengine_submit(in_desc); + dma_async_issue_pending(dd->dma_lch_in.chan); + + return 0; +} + +static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd) { struct crypto_tfm *tfm = crypto_ablkcipher_tfm( crypto_ablkcipher_reqtfm(dd->req)); @@ -387,23 +506,23 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) size_t count; dma_addr_t addr_in, addr_out; - if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) { + if ((!dd->in_offset) && (!dd->out_offset)) { /* check for alignment */ - in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)); - out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)); - + in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)) && + IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size); + out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)) && + IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size); fast = in && out; + + if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg)) + fast = 0; } + if (fast) { count = min(dd->total, sg_dma_len(dd->in_sg)); count = min(count, sg_dma_len(dd->out_sg)); - if (count != dd->total) { - pr_err("request length != buffer length\n"); - return -EINVAL; - } - err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); if (!err) { dev_err(dd->dev, "dma_map_sg() error\n"); @@ -433,13 +552,16 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) addr_out = dd->dma_addr_out; dd->flags &= ~TDES_FLAGS_FAST; - } dd->total -= count; - err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count); - if (err) { + if (dd->caps.has_dma) + err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count); + else + err = atmel_tdes_crypt_pdc(tfm, addr_in, addr_out, count); + + if (err && (dd->flags & TDES_FLAGS_FAST)) { dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); } @@ -447,7 +569,6 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) return err; } - static void atmel_tdes_finish_req(struct atmel_tdes_dev *dd, int err) { struct ablkcipher_request *req = dd->req; @@ -506,7 +627,7 @@ static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd, err = atmel_tdes_write_ctrl(dd); if (!err) - err = atmel_tdes_crypt_dma_start(dd); + err = atmel_tdes_crypt_start(dd); if (err) { /* des_task will not finish it, so do it here */ atmel_tdes_finish_req(dd, err); @@ -516,41 +637,145 @@ static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd, return ret; } +static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) +{ + int err = -EINVAL; + size_t count; + + if (dd->flags & TDES_FLAGS_DMA) { + err = 0; + if (dd->flags & TDES_FLAGS_FAST) { + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); + } else { + dma_sync_single_for_device(dd->dev, dd->dma_addr_out, + dd->dma_size, DMA_FROM_DEVICE); + + /* copy data */ + count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset, + dd->buf_out, dd->buflen, dd->dma_size, 1); + if (count != dd->dma_size) { + err = -EINVAL; + pr_err("not all data converted: %u\n", count); + } + } + } + return err; +} static int atmel_tdes_crypt(struct ablkcipher_request *req, unsigned long mode) { struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx( crypto_ablkcipher_reqtfm(req)); struct atmel_tdes_reqctx *rctx = ablkcipher_request_ctx(req); - struct atmel_tdes_dev *dd; if (mode & TDES_FLAGS_CFB8) { if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) { pr_err("request size is not exact amount of CFB8 blocks\n"); return -EINVAL; } + ctx->block_size = CFB8_BLOCK_SIZE; } else if (mode & TDES_FLAGS_CFB16) { if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) { pr_err("request size is not exact amount of CFB16 blocks\n"); return -EINVAL; } + ctx->block_size = CFB16_BLOCK_SIZE; } else if (mode & TDES_FLAGS_CFB32) { if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) { pr_err("request size is not exact amount of CFB32 blocks\n"); return -EINVAL; } - } else if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { - pr_err("request size is not exact amount of DES blocks\n"); - return -EINVAL; + ctx->block_size = CFB32_BLOCK_SIZE; + } else { + if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { + pr_err("request size is not exact amount of DES blocks\n"); + return -EINVAL; + } + ctx->block_size = DES_BLOCK_SIZE; } - dd = atmel_tdes_find_dev(ctx); - if (!dd) + rctx->mode = mode; + + return atmel_tdes_handle_queue(ctx->dd, req); +} + +static bool atmel_tdes_filter(struct dma_chan *chan, void *slave) +{ + struct at_dma_slave *sl = slave; + + if (sl && sl->dma_dev == chan->device->dev) { + chan->private = sl; + return true; + } else { + return false; + } +} + +static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd, + struct crypto_platform_data *pdata) +{ + int err = -ENOMEM; + dma_cap_mask_t mask_in, mask_out; + + if (pdata && pdata->dma_slave->txdata.dma_dev && + pdata->dma_slave->rxdata.dma_dev) { + + /* Try to grab 2 DMA channels */ + dma_cap_zero(mask_in); + dma_cap_set(DMA_SLAVE, mask_in); + + dd->dma_lch_in.chan = dma_request_channel(mask_in, + atmel_tdes_filter, &pdata->dma_slave->rxdata); + + if (!dd->dma_lch_in.chan) + goto err_dma_in; + + dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; + dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + + TDES_IDATA1R; + dd->dma_lch_in.dma_conf.src_maxburst = 1; + dd->dma_lch_in.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_in.dma_conf.dst_maxburst = 1; + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_in.dma_conf.device_fc = false; + + dma_cap_zero(mask_out); + dma_cap_set(DMA_SLAVE, mask_out); + dd->dma_lch_out.chan = dma_request_channel(mask_out, + atmel_tdes_filter, &pdata->dma_slave->txdata); + + if (!dd->dma_lch_out.chan) + goto err_dma_out; + + dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; + dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + + TDES_ODATA1R; + dd->dma_lch_out.dma_conf.src_maxburst = 1; + dd->dma_lch_out.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.dst_maxburst = 1; + dd->dma_lch_out.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.device_fc = false; + + return 0; + } else { return -ENODEV; + } - rctx->mode = mode; +err_dma_out: + dma_release_channel(dd->dma_lch_in.chan); +err_dma_in: + return err; +} - return atmel_tdes_handle_queue(dd, req); +static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) +{ + dma_release_channel(dd->dma_lch_in.chan); + dma_release_channel(dd->dma_lch_out.chan); } static int atmel_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, @@ -590,7 +815,8 @@ static int atmel_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, /* * HW bug in cfb 3-keys mode. */ - if (strstr(alg_name, "cfb") && (keylen != 2*DES_KEY_SIZE)) { + if (!ctx->dd->caps.has_cfb_3keys && strstr(alg_name, "cfb") + && (keylen != 2*DES_KEY_SIZE)) { crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } else if ((keylen != 2*DES_KEY_SIZE) && (keylen != 3*DES_KEY_SIZE)) { @@ -678,8 +904,15 @@ static int atmel_tdes_ofb_decrypt(struct ablkcipher_request *req) static int atmel_tdes_cra_init(struct crypto_tfm *tfm) { + struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); + struct atmel_tdes_dev *dd; + tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_tdes_reqctx); + dd = atmel_tdes_find_dev(ctx); + if (!dd) + return -ENODEV; + return 0; } @@ -695,7 +928,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -715,7 +948,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -736,7 +969,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -778,7 +1011,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB16_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x1, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -799,7 +1032,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB32_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x3, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -820,7 +1053,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -841,7 +1074,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -861,7 +1094,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -882,7 +1115,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -924,7 +1157,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB16_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x1, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -945,7 +1178,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = CFB32_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x3, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -966,7 +1199,7 @@ static struct crypto_alg tdes_algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct atmel_tdes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0x7, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = atmel_tdes_cra_init, @@ -994,14 +1227,24 @@ static void atmel_tdes_done_task(unsigned long data) struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *) data; int err; - err = atmel_tdes_crypt_dma_stop(dd); + if (!(dd->flags & TDES_FLAGS_DMA)) + err = atmel_tdes_crypt_pdc_stop(dd); + else + err = atmel_tdes_crypt_dma_stop(dd); err = dd->err ? : err; if (dd->total && !err) { - err = atmel_tdes_crypt_dma_start(dd); + if (dd->flags & TDES_FLAGS_FAST) { + dd->in_sg = sg_next(dd->in_sg); + dd->out_sg = sg_next(dd->out_sg); + if (!dd->in_sg || !dd->out_sg) + err = -EINVAL; + } if (!err) - return; + err = atmel_tdes_crypt_start(dd); + if (!err) + return; /* DMA started. Not fininishing. */ } atmel_tdes_finish_req(dd, err); @@ -1053,9 +1296,31 @@ err_tdes_algs: return err; } +static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd) +{ + + dd->caps.has_dma = 0; + dd->caps.has_cfb_3keys = 0; + + /* keep only major version number */ + switch (dd->hw_version & 0xf00) { + case 0x700: + dd->caps.has_dma = 1; + dd->caps.has_cfb_3keys = 1; + break; + case 0x600: + break; + default: + dev_warn(dd->dev, + "Unmanaged tdes version, set minimum capabilities\n"); + break; + } +} + static int atmel_tdes_probe(struct platform_device *pdev) { struct atmel_tdes_dev *tdes_dd; + struct crypto_platform_data *pdata; struct device *dev = &pdev->dev; struct resource *tdes_res; unsigned long tdes_phys_size; @@ -1109,7 +1374,7 @@ static int atmel_tdes_probe(struct platform_device *pdev) } /* Initializing the clock */ - tdes_dd->iclk = clk_get(&pdev->dev, NULL); + tdes_dd->iclk = clk_get(&pdev->dev, "tdes_clk"); if (IS_ERR(tdes_dd->iclk)) { dev_err(dev, "clock intialization failed.\n"); err = PTR_ERR(tdes_dd->iclk); @@ -1123,9 +1388,25 @@ static int atmel_tdes_probe(struct platform_device *pdev) goto tdes_io_err; } - err = atmel_tdes_dma_init(tdes_dd); + atmel_tdes_hw_version_init(tdes_dd); + + atmel_tdes_get_cap(tdes_dd); + + err = atmel_tdes_buff_init(tdes_dd); if (err) - goto err_tdes_dma; + goto err_tdes_buff; + + if (tdes_dd->caps.has_dma) { + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "platform data not available\n"); + err = -ENXIO; + goto err_pdata; + } + err = atmel_tdes_dma_init(tdes_dd, pdata); + if (err) + goto err_tdes_dma; + } spin_lock(&atmel_tdes.lock); list_add_tail(&tdes_dd->list, &atmel_tdes.dev_list); @@ -1143,8 +1424,12 @@ err_algs: spin_lock(&atmel_tdes.lock); list_del(&tdes_dd->list); spin_unlock(&atmel_tdes.lock); - atmel_tdes_dma_cleanup(tdes_dd); + if (tdes_dd->caps.has_dma) + atmel_tdes_dma_cleanup(tdes_dd); err_tdes_dma: +err_pdata: + atmel_tdes_buff_cleanup(tdes_dd); +err_tdes_buff: iounmap(tdes_dd->io_base); tdes_io_err: clk_put(tdes_dd->iclk); @@ -1178,7 +1463,10 @@ static int atmel_tdes_remove(struct platform_device *pdev) tasklet_kill(&tdes_dd->done_task); tasklet_kill(&tdes_dd->queue_task); - atmel_tdes_dma_cleanup(tdes_dd); + if (tdes_dd->caps.has_dma) + atmel_tdes_dma_cleanup(tdes_dd); + + atmel_tdes_buff_cleanup(tdes_dd); iounmap(tdes_dd->io_base); -- cgit From d4905b38d1f6b60761a6fd16f45ebd1fac8b6e1f Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Wed, 20 Feb 2013 17:10:26 +0100 Subject: crypto: atmel-sha - add support for latest release of the IP (0x410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates from IP release 0x320 to 0x400: - add DMA support (previous IP revision use PDC) - add DMA double input buffer support - add SHA224 support Update from IP release 0x400 to 0x410: - add SHA384 and SHA512 support Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 8 +- drivers/crypto/atmel-sha-regs.h | 7 +- drivers/crypto/atmel-sha.c | 586 +++++++++++++++++++++++++++++++++------- 3 files changed, 497 insertions(+), 104 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 87ec4d027c25..e66fb0a332d4 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -361,15 +361,17 @@ config CRYPTO_DEV_ATMEL_TDES will be called atmel-tdes. config CRYPTO_DEV_ATMEL_SHA - tristate "Support for Atmel SHA1/SHA256 hw accelerator" + tristate "Support for Atmel SHA hw accelerator" depends on ARCH_AT91 select CRYPTO_SHA1 select CRYPTO_SHA256 + select CRYPTO_SHA512 select CRYPTO_ALGAPI help - Some Atmel processors have SHA1/SHA256 hw accelerator. + Some Atmel processors have SHA1/SHA224/SHA256/SHA384/SHA512 + hw accelerator. Select this if you want to use the Atmel module for - SHA1/SHA256 algorithms. + SHA1/SHA224/SHA256/SHA384/SHA512 algorithms. To compile this driver as a module, choose M here: the module will be called atmel-sha. diff --git a/drivers/crypto/atmel-sha-regs.h b/drivers/crypto/atmel-sha-regs.h index dc53a20d7da1..83b2d7425666 100644 --- a/drivers/crypto/atmel-sha-regs.h +++ b/drivers/crypto/atmel-sha-regs.h @@ -14,10 +14,13 @@ #define SHA_MR_MODE_MANUAL 0x0 #define SHA_MR_MODE_AUTO 0x1 #define SHA_MR_MODE_PDC 0x2 -#define SHA_MR_DUALBUFF (1 << 3) #define SHA_MR_PROCDLY (1 << 4) #define SHA_MR_ALGO_SHA1 (0 << 8) #define SHA_MR_ALGO_SHA256 (1 << 8) +#define SHA_MR_ALGO_SHA384 (2 << 8) +#define SHA_MR_ALGO_SHA512 (3 << 8) +#define SHA_MR_ALGO_SHA224 (4 << 8) +#define SHA_MR_DUALBUFF (1 << 16) #define SHA_IER 0x10 #define SHA_IDR 0x14 @@ -33,6 +36,8 @@ #define SHA_ISR_URAT_MR (0x2 << 12) #define SHA_ISR_URAT_WO (0x5 << 12) +#define SHA_HW_VERSION 0xFC + #define SHA_TPR 0x108 #define SHA_TCR 0x10C #define SHA_TNPR 0x118 diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 4918e9424d31..eaed8bf183bc 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "atmel-sha-regs.h" /* SHA flags */ @@ -52,11 +53,12 @@ #define SHA_FLAGS_FINUP BIT(16) #define SHA_FLAGS_SG BIT(17) #define SHA_FLAGS_SHA1 BIT(18) -#define SHA_FLAGS_SHA256 BIT(19) -#define SHA_FLAGS_ERROR BIT(20) -#define SHA_FLAGS_PAD BIT(21) - -#define SHA_FLAGS_DUALBUFF BIT(24) +#define SHA_FLAGS_SHA224 BIT(19) +#define SHA_FLAGS_SHA256 BIT(20) +#define SHA_FLAGS_SHA384 BIT(21) +#define SHA_FLAGS_SHA512 BIT(22) +#define SHA_FLAGS_ERROR BIT(23) +#define SHA_FLAGS_PAD BIT(24) #define SHA_OP_UPDATE 1 #define SHA_OP_FINAL 2 @@ -65,6 +67,12 @@ #define ATMEL_SHA_DMA_THRESHOLD 56 +struct atmel_sha_caps { + bool has_dma; + bool has_dualbuff; + bool has_sha224; + bool has_sha_384_512; +}; struct atmel_sha_dev; @@ -73,8 +81,8 @@ struct atmel_sha_reqctx { unsigned long flags; unsigned long op; - u8 digest[SHA256_DIGEST_SIZE] __aligned(sizeof(u32)); - size_t digcnt; + u8 digest[SHA512_DIGEST_SIZE] __aligned(sizeof(u32)); + u64 digcnt[2]; size_t bufcnt; size_t buflen; dma_addr_t dma_addr; @@ -84,6 +92,8 @@ struct atmel_sha_reqctx { unsigned int offset; /* offset in current sg */ unsigned int total; /* total request */ + size_t block_size; + u8 buffer[0] __aligned(sizeof(u32)); }; @@ -97,7 +107,12 @@ struct atmel_sha_ctx { }; -#define ATMEL_SHA_QUEUE_LENGTH 1 +#define ATMEL_SHA_QUEUE_LENGTH 50 + +struct atmel_sha_dma { + struct dma_chan *chan; + struct dma_slave_config dma_conf; +}; struct atmel_sha_dev { struct list_head list; @@ -114,6 +129,12 @@ struct atmel_sha_dev { unsigned long flags; struct crypto_queue queue; struct ahash_request *req; + + struct atmel_sha_dma dma_lch_in; + + struct atmel_sha_caps caps; + + u32 hw_version; }; struct atmel_sha_drv { @@ -137,14 +158,6 @@ static inline void atmel_sha_write(struct atmel_sha_dev *dd, writel_relaxed(value, dd->io_base + offset); } -static void atmel_sha_dualbuff_test(struct atmel_sha_dev *dd) -{ - atmel_sha_write(dd, SHA_MR, SHA_MR_DUALBUFF); - - if (atmel_sha_read(dd, SHA_MR) & SHA_MR_DUALBUFF) - dd->flags |= SHA_FLAGS_DUALBUFF; -} - static size_t atmel_sha_append_sg(struct atmel_sha_reqctx *ctx) { size_t count; @@ -176,31 +189,58 @@ static size_t atmel_sha_append_sg(struct atmel_sha_reqctx *ctx) } /* - * The purpose of this padding is to ensure that the padded message - * is a multiple of 512 bits. The bit "1" is appended at the end of - * the message followed by "padlen-1" zero bits. Then a 64 bits block - * equals to the message length in bits is appended. + * The purpose of this padding is to ensure that the padded message is a + * multiple of 512 bits (SHA1/SHA224/SHA256) or 1024 bits (SHA384/SHA512). + * The bit "1" is appended at the end of the message followed by + * "padlen-1" zero bits. Then a 64 bits block (SHA1/SHA224/SHA256) or + * 128 bits block (SHA384/SHA512) equals to the message length in bits + * is appended. * - * padlen is calculated as followed: + * For SHA1/SHA224/SHA256, padlen is calculated as followed: * - if message length < 56 bytes then padlen = 56 - message length * - else padlen = 64 + 56 - message length + * + * For SHA384/SHA512, padlen is calculated as followed: + * - if message length < 112 bytes then padlen = 112 - message length + * - else padlen = 128 + 112 - message length */ static void atmel_sha_fill_padding(struct atmel_sha_reqctx *ctx, int length) { unsigned int index, padlen; - u64 bits; - u64 size; - - bits = (ctx->bufcnt + ctx->digcnt + length) << 3; - size = cpu_to_be64(bits); - - index = ctx->bufcnt & 0x3f; - padlen = (index < 56) ? (56 - index) : ((64+56) - index); - *(ctx->buffer + ctx->bufcnt) = 0x80; - memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen-1); - memcpy(ctx->buffer + ctx->bufcnt + padlen, &size, 8); - ctx->bufcnt += padlen + 8; - ctx->flags |= SHA_FLAGS_PAD; + u64 bits[2]; + u64 size[2]; + + size[0] = ctx->digcnt[0]; + size[1] = ctx->digcnt[1]; + + size[0] += ctx->bufcnt; + if (size[0] < ctx->bufcnt) + size[1]++; + + size[0] += length; + if (size[0] < length) + size[1]++; + + bits[1] = cpu_to_be64(size[0] << 3); + bits[0] = cpu_to_be64(size[1] << 3 | size[0] >> 61); + + if (ctx->flags & (SHA_FLAGS_SHA384 | SHA_FLAGS_SHA512)) { + index = ctx->bufcnt & 0x7f; + padlen = (index < 112) ? (112 - index) : ((128+112) - index); + *(ctx->buffer + ctx->bufcnt) = 0x80; + memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen-1); + memcpy(ctx->buffer + ctx->bufcnt + padlen, bits, 16); + ctx->bufcnt += padlen + 16; + ctx->flags |= SHA_FLAGS_PAD; + } else { + index = ctx->bufcnt & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + *(ctx->buffer + ctx->bufcnt) = 0x80; + memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen-1); + memcpy(ctx->buffer + ctx->bufcnt + padlen, &bits[1], 8); + ctx->bufcnt += padlen + 8; + ctx->flags |= SHA_FLAGS_PAD; + } } static int atmel_sha_init(struct ahash_request *req) @@ -231,13 +271,35 @@ static int atmel_sha_init(struct ahash_request *req) dev_dbg(dd->dev, "init: digest size: %d\n", crypto_ahash_digestsize(tfm)); - if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE) + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: ctx->flags |= SHA_FLAGS_SHA1; - else if (crypto_ahash_digestsize(tfm) == SHA256_DIGEST_SIZE) + ctx->block_size = SHA1_BLOCK_SIZE; + break; + case SHA224_DIGEST_SIZE: + ctx->flags |= SHA_FLAGS_SHA224; + ctx->block_size = SHA224_BLOCK_SIZE; + break; + case SHA256_DIGEST_SIZE: ctx->flags |= SHA_FLAGS_SHA256; + ctx->block_size = SHA256_BLOCK_SIZE; + break; + case SHA384_DIGEST_SIZE: + ctx->flags |= SHA_FLAGS_SHA384; + ctx->block_size = SHA384_BLOCK_SIZE; + break; + case SHA512_DIGEST_SIZE: + ctx->flags |= SHA_FLAGS_SHA512; + ctx->block_size = SHA512_BLOCK_SIZE; + break; + default: + return -EINVAL; + break; + } ctx->bufcnt = 0; - ctx->digcnt = 0; + ctx->digcnt[0] = 0; + ctx->digcnt[1] = 0; ctx->buflen = SHA_BUFFER_LEN; return 0; @@ -249,19 +311,28 @@ static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma) u32 valcr = 0, valmr = SHA_MR_MODE_AUTO; if (likely(dma)) { - atmel_sha_write(dd, SHA_IER, SHA_INT_TXBUFE); + if (!dd->caps.has_dma) + atmel_sha_write(dd, SHA_IER, SHA_INT_TXBUFE); valmr = SHA_MR_MODE_PDC; - if (dd->flags & SHA_FLAGS_DUALBUFF) - valmr = SHA_MR_DUALBUFF; + if (dd->caps.has_dualbuff) + valmr |= SHA_MR_DUALBUFF; } else { atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY); } - if (ctx->flags & SHA_FLAGS_SHA256) + if (ctx->flags & SHA_FLAGS_SHA1) + valmr |= SHA_MR_ALGO_SHA1; + else if (ctx->flags & SHA_FLAGS_SHA224) + valmr |= SHA_MR_ALGO_SHA224; + else if (ctx->flags & SHA_FLAGS_SHA256) valmr |= SHA_MR_ALGO_SHA256; + else if (ctx->flags & SHA_FLAGS_SHA384) + valmr |= SHA_MR_ALGO_SHA384; + else if (ctx->flags & SHA_FLAGS_SHA512) + valmr |= SHA_MR_ALGO_SHA512; /* Setting CR_FIRST only for the first iteration */ - if (!ctx->digcnt) + if (!(ctx->digcnt[0] || ctx->digcnt[1])) valcr = SHA_CR_FIRST; atmel_sha_write(dd, SHA_CR, valcr); @@ -275,13 +346,15 @@ static int atmel_sha_xmit_cpu(struct atmel_sha_dev *dd, const u8 *buf, int count, len32; const u32 *buffer = (const u32 *)buf; - dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", - ctx->digcnt, length, final); + dev_dbg(dd->dev, "xmit_cpu: digcnt: 0x%llx 0x%llx, length: %d, final: %d\n", + ctx->digcnt[1], ctx->digcnt[0], length, final); atmel_sha_write_ctrl(dd, 0); /* should be non-zero before next lines to disable clocks later */ - ctx->digcnt += length; + ctx->digcnt[0] += length; + if (ctx->digcnt[0] < length) + ctx->digcnt[1]++; if (final) dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */ @@ -302,8 +375,8 @@ static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1, struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req); int len32; - dev_dbg(dd->dev, "xmit_pdc: digcnt: %d, length: %d, final: %d\n", - ctx->digcnt, length1, final); + dev_dbg(dd->dev, "xmit_pdc: digcnt: 0x%llx 0x%llx, length: %d, final: %d\n", + ctx->digcnt[1], ctx->digcnt[0], length1, final); len32 = DIV_ROUND_UP(length1, sizeof(u32)); atmel_sha_write(dd, SHA_PTCR, SHA_PTCR_TXTDIS); @@ -317,7 +390,9 @@ static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1, atmel_sha_write_ctrl(dd, 1); /* should be non-zero before next lines to disable clocks later */ - ctx->digcnt += length1; + ctx->digcnt[0] += length1; + if (ctx->digcnt[0] < length1) + ctx->digcnt[1]++; if (final) dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */ @@ -330,6 +405,86 @@ static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1, return -EINPROGRESS; } +static void atmel_sha_dma_callback(void *data) +{ + struct atmel_sha_dev *dd = data; + + /* dma_lch_in - completed - wait DATRDY */ + atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY); +} + +static int atmel_sha_xmit_dma(struct atmel_sha_dev *dd, dma_addr_t dma_addr1, + size_t length1, dma_addr_t dma_addr2, size_t length2, int final) +{ + struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req); + struct dma_async_tx_descriptor *in_desc; + struct scatterlist sg[2]; + + dev_dbg(dd->dev, "xmit_dma: digcnt: 0x%llx 0x%llx, length: %d, final: %d\n", + ctx->digcnt[1], ctx->digcnt[0], length1, final); + + if (ctx->flags & (SHA_FLAGS_SHA1 | SHA_FLAGS_SHA224 | + SHA_FLAGS_SHA256)) { + dd->dma_lch_in.dma_conf.src_maxburst = 16; + dd->dma_lch_in.dma_conf.dst_maxburst = 16; + } else { + dd->dma_lch_in.dma_conf.src_maxburst = 32; + dd->dma_lch_in.dma_conf.dst_maxburst = 32; + } + + dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); + + if (length2) { + sg_init_table(sg, 2); + sg_dma_address(&sg[0]) = dma_addr1; + sg_dma_len(&sg[0]) = length1; + sg_dma_address(&sg[1]) = dma_addr2; + sg_dma_len(&sg[1]) = length2; + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, sg, 2, + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + } else { + sg_init_table(sg, 1); + sg_dma_address(&sg[0]) = dma_addr1; + sg_dma_len(&sg[0]) = length1; + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, sg, 1, + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + } + if (!in_desc) + return -EINVAL; + + in_desc->callback = atmel_sha_dma_callback; + in_desc->callback_param = dd; + + atmel_sha_write_ctrl(dd, 1); + + /* should be non-zero before next lines to disable clocks later */ + ctx->digcnt[0] += length1; + if (ctx->digcnt[0] < length1) + ctx->digcnt[1]++; + + if (final) + dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */ + + dd->flags |= SHA_FLAGS_DMA_ACTIVE; + + /* Start DMA transfer */ + dmaengine_submit(in_desc); + dma_async_issue_pending(dd->dma_lch_in.chan); + + return -EINPROGRESS; +} + +static int atmel_sha_xmit_start(struct atmel_sha_dev *dd, dma_addr_t dma_addr1, + size_t length1, dma_addr_t dma_addr2, size_t length2, int final) +{ + if (dd->caps.has_dma) + return atmel_sha_xmit_dma(dd, dma_addr1, length1, + dma_addr2, length2, final); + else + return atmel_sha_xmit_pdc(dd, dma_addr1, length1, + dma_addr2, length2, final); +} + static int atmel_sha_update_cpu(struct atmel_sha_dev *dd) { struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req); @@ -337,7 +492,6 @@ static int atmel_sha_update_cpu(struct atmel_sha_dev *dd) atmel_sha_append_sg(ctx); atmel_sha_fill_padding(ctx, 0); - bufcnt = ctx->bufcnt; ctx->bufcnt = 0; @@ -349,17 +503,17 @@ static int atmel_sha_xmit_dma_map(struct atmel_sha_dev *dd, size_t length, int final) { ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, - ctx->buflen + SHA1_BLOCK_SIZE, DMA_TO_DEVICE); + ctx->buflen + ctx->block_size, DMA_TO_DEVICE); if (dma_mapping_error(dd->dev, ctx->dma_addr)) { dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen + - SHA1_BLOCK_SIZE); + ctx->block_size); return -EINVAL; } ctx->flags &= ~SHA_FLAGS_SG; /* next call does not fail... so no unmap in the case of error */ - return atmel_sha_xmit_pdc(dd, ctx->dma_addr, length, 0, 0, final); + return atmel_sha_xmit_start(dd, ctx->dma_addr, length, 0, 0, final); } static int atmel_sha_update_dma_slow(struct atmel_sha_dev *dd) @@ -372,8 +526,8 @@ static int atmel_sha_update_dma_slow(struct atmel_sha_dev *dd) final = (ctx->flags & SHA_FLAGS_FINUP) && !ctx->total; - dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n", - ctx->bufcnt, ctx->digcnt, final); + dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: 0x%llx 0x%llx, final: %d\n", + ctx->bufcnt, ctx->digcnt[1], ctx->digcnt[0], final); if (final) atmel_sha_fill_padding(ctx, 0); @@ -400,30 +554,25 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) if (ctx->bufcnt || ctx->offset) return atmel_sha_update_dma_slow(dd); - dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n", - ctx->digcnt, ctx->bufcnt, ctx->total); + dev_dbg(dd->dev, "fast: digcnt: 0x%llx 0x%llx, bufcnt: %u, total: %u\n", + ctx->digcnt[1], ctx->digcnt[0], ctx->bufcnt, ctx->total); sg = ctx->sg; if (!IS_ALIGNED(sg->offset, sizeof(u32))) return atmel_sha_update_dma_slow(dd); - if (!sg_is_last(sg) && !IS_ALIGNED(sg->length, SHA1_BLOCK_SIZE)) - /* size is not SHA1_BLOCK_SIZE aligned */ + if (!sg_is_last(sg) && !IS_ALIGNED(sg->length, ctx->block_size)) + /* size is not ctx->block_size aligned */ return atmel_sha_update_dma_slow(dd); length = min(ctx->total, sg->length); if (sg_is_last(sg)) { if (!(ctx->flags & SHA_FLAGS_FINUP)) { - /* not last sg must be SHA1_BLOCK_SIZE aligned */ - tail = length & (SHA1_BLOCK_SIZE - 1); + /* not last sg must be ctx->block_size aligned */ + tail = length & (ctx->block_size - 1); length -= tail; - if (length == 0) { - /* offset where to start slow */ - ctx->offset = length; - return atmel_sha_update_dma_slow(dd); - } } } @@ -434,7 +583,7 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) /* Add padding */ if (final) { - tail = length & (SHA1_BLOCK_SIZE - 1); + tail = length & (ctx->block_size - 1); length -= tail; ctx->total += tail; ctx->offset = length; /* offset where to start slow */ @@ -445,10 +594,10 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) atmel_sha_fill_padding(ctx, length); ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, - ctx->buflen + SHA1_BLOCK_SIZE, DMA_TO_DEVICE); + ctx->buflen + ctx->block_size, DMA_TO_DEVICE); if (dma_mapping_error(dd->dev, ctx->dma_addr)) { dev_err(dd->dev, "dma %u bytes error\n", - ctx->buflen + SHA1_BLOCK_SIZE); + ctx->buflen + ctx->block_size); return -EINVAL; } @@ -456,7 +605,7 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) ctx->flags &= ~SHA_FLAGS_SG; count = ctx->bufcnt; ctx->bufcnt = 0; - return atmel_sha_xmit_pdc(dd, ctx->dma_addr, count, 0, + return atmel_sha_xmit_start(dd, ctx->dma_addr, count, 0, 0, final); } else { ctx->sg = sg; @@ -470,7 +619,7 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) count = ctx->bufcnt; ctx->bufcnt = 0; - return atmel_sha_xmit_pdc(dd, sg_dma_address(ctx->sg), + return atmel_sha_xmit_start(dd, sg_dma_address(ctx->sg), length, ctx->dma_addr, count, final); } } @@ -483,7 +632,7 @@ static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd) ctx->flags |= SHA_FLAGS_SG; /* next call does not fail... so no unmap in the case of error */ - return atmel_sha_xmit_pdc(dd, sg_dma_address(ctx->sg), length, 0, + return atmel_sha_xmit_start(dd, sg_dma_address(ctx->sg), length, 0, 0, final); } @@ -498,12 +647,13 @@ static int atmel_sha_update_dma_stop(struct atmel_sha_dev *dd) if (ctx->sg) ctx->offset = 0; } - if (ctx->flags & SHA_FLAGS_PAD) + if (ctx->flags & SHA_FLAGS_PAD) { dma_unmap_single(dd->dev, ctx->dma_addr, - ctx->buflen + SHA1_BLOCK_SIZE, DMA_TO_DEVICE); + ctx->buflen + ctx->block_size, DMA_TO_DEVICE); + } } else { dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen + - SHA1_BLOCK_SIZE, DMA_TO_DEVICE); + ctx->block_size, DMA_TO_DEVICE); } return 0; @@ -515,8 +665,8 @@ static int atmel_sha_update_req(struct atmel_sha_dev *dd) struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); int err; - dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n", - ctx->total, ctx->digcnt, (ctx->flags & SHA_FLAGS_FINUP) != 0); + dev_dbg(dd->dev, "update_req: total: %u, digcnt: 0x%llx 0x%llx\n", + ctx->total, ctx->digcnt[1], ctx->digcnt[0]); if (ctx->flags & SHA_FLAGS_CPU) err = atmel_sha_update_cpu(dd); @@ -524,8 +674,8 @@ static int atmel_sha_update_req(struct atmel_sha_dev *dd) err = atmel_sha_update_dma_start(dd); /* wait for dma completion before can take more data */ - dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", - err, ctx->digcnt); + dev_dbg(dd->dev, "update: err: %d, digcnt: 0x%llx 0%llx\n", + err, ctx->digcnt[1], ctx->digcnt[0]); return err; } @@ -562,12 +712,21 @@ static void atmel_sha_copy_hash(struct ahash_request *req) u32 *hash = (u32 *)ctx->digest; int i; - if (likely(ctx->flags & SHA_FLAGS_SHA1)) + if (ctx->flags & SHA_FLAGS_SHA1) for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); - else + else if (ctx->flags & SHA_FLAGS_SHA224) + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(u32); i++) + hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); + else if (ctx->flags & SHA_FLAGS_SHA256) for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); + else if (ctx->flags & SHA_FLAGS_SHA384) + for (i = 0; i < SHA384_DIGEST_SIZE / sizeof(u32); i++) + hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); + else + for (i = 0; i < SHA512_DIGEST_SIZE / sizeof(u32); i++) + hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i)); } static void atmel_sha_copy_ready_hash(struct ahash_request *req) @@ -577,10 +736,16 @@ static void atmel_sha_copy_ready_hash(struct ahash_request *req) if (!req->result) return; - if (likely(ctx->flags & SHA_FLAGS_SHA1)) + if (ctx->flags & SHA_FLAGS_SHA1) memcpy(req->result, ctx->digest, SHA1_DIGEST_SIZE); - else + else if (ctx->flags & SHA_FLAGS_SHA224) + memcpy(req->result, ctx->digest, SHA224_DIGEST_SIZE); + else if (ctx->flags & SHA_FLAGS_SHA256) memcpy(req->result, ctx->digest, SHA256_DIGEST_SIZE); + else if (ctx->flags & SHA_FLAGS_SHA384) + memcpy(req->result, ctx->digest, SHA384_DIGEST_SIZE); + else + memcpy(req->result, ctx->digest, SHA512_DIGEST_SIZE); } static int atmel_sha_finish(struct ahash_request *req) @@ -589,11 +754,11 @@ static int atmel_sha_finish(struct ahash_request *req) struct atmel_sha_dev *dd = ctx->dd; int err = 0; - if (ctx->digcnt) + if (ctx->digcnt[0] || ctx->digcnt[1]) atmel_sha_copy_ready_hash(req); - dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, - ctx->bufcnt); + dev_dbg(dd->dev, "digcnt: 0x%llx 0x%llx, bufcnt: %d\n", ctx->digcnt[1], + ctx->digcnt[0], ctx->bufcnt); return err; } @@ -628,9 +793,8 @@ static int atmel_sha_hw_init(struct atmel_sha_dev *dd) { clk_prepare_enable(dd->iclk); - if (SHA_FLAGS_INIT & dd->flags) { + if (!(SHA_FLAGS_INIT & dd->flags)) { atmel_sha_write(dd, SHA_CR, SHA_CR_SWRST); - atmel_sha_dualbuff_test(dd); dd->flags |= SHA_FLAGS_INIT; dd->err = 0; } @@ -638,6 +802,23 @@ static int atmel_sha_hw_init(struct atmel_sha_dev *dd) return 0; } +static inline unsigned int atmel_sha_get_version(struct atmel_sha_dev *dd) +{ + return atmel_sha_read(dd, SHA_HW_VERSION) & 0x00000fff; +} + +static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd) +{ + atmel_sha_hw_init(dd); + + dd->hw_version = atmel_sha_get_version(dd); + + dev_info(dd->dev, + "version: 0x%x\n", dd->hw_version); + + clk_disable_unprepare(dd->iclk); +} + static int atmel_sha_handle_queue(struct atmel_sha_dev *dd, struct ahash_request *req) { @@ -682,10 +863,9 @@ static int atmel_sha_handle_queue(struct atmel_sha_dev *dd, if (ctx->op == SHA_OP_UPDATE) { err = atmel_sha_update_req(dd); - if (err != -EINPROGRESS && (ctx->flags & SHA_FLAGS_FINUP)) { + if (err != -EINPROGRESS && (ctx->flags & SHA_FLAGS_FINUP)) /* no final() after finup() */ err = atmel_sha_final_req(dd); - } } else if (ctx->op == SHA_OP_FINAL) { err = atmel_sha_final_req(dd); } @@ -808,7 +988,7 @@ static int atmel_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) } crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct atmel_sha_reqctx) + - SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); + SHA_BUFFER_LEN + SHA512_BLOCK_SIZE); return 0; } @@ -826,7 +1006,7 @@ static void atmel_sha_cra_exit(struct crypto_tfm *tfm) tctx->fallback = NULL; } -static struct ahash_alg sha_algs[] = { +static struct ahash_alg sha_1_256_algs[] = { { .init = atmel_sha_init, .update = atmel_sha_update, @@ -875,6 +1055,79 @@ static struct ahash_alg sha_algs[] = { }, }; +static struct ahash_alg sha_224_alg = { + .init = atmel_sha_init, + .update = atmel_sha_update, + .final = atmel_sha_final, + .finup = atmel_sha_finup, + .digest = atmel_sha_digest, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .base = { + .cra_name = "sha224", + .cra_driver_name = "atmel-sha224", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct atmel_sha_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = atmel_sha_cra_init, + .cra_exit = atmel_sha_cra_exit, + } + } +}; + +static struct ahash_alg sha_384_512_algs[] = { +{ + .init = atmel_sha_init, + .update = atmel_sha_update, + .final = atmel_sha_final, + .finup = atmel_sha_finup, + .digest = atmel_sha_digest, + .halg = { + .digestsize = SHA384_DIGEST_SIZE, + .base = { + .cra_name = "sha384", + .cra_driver_name = "atmel-sha384", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct atmel_sha_ctx), + .cra_alignmask = 0x3, + .cra_module = THIS_MODULE, + .cra_init = atmel_sha_cra_init, + .cra_exit = atmel_sha_cra_exit, + } + } +}, +{ + .init = atmel_sha_init, + .update = atmel_sha_update, + .final = atmel_sha_final, + .finup = atmel_sha_finup, + .digest = atmel_sha_digest, + .halg = { + .digestsize = SHA512_DIGEST_SIZE, + .base = { + .cra_name = "sha512", + .cra_driver_name = "atmel-sha512", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct atmel_sha_ctx), + .cra_alignmask = 0x3, + .cra_module = THIS_MODULE, + .cra_init = atmel_sha_cra_init, + .cra_exit = atmel_sha_cra_exit, + } + } +}, +}; + static void atmel_sha_done_task(unsigned long data) { struct atmel_sha_dev *dd = (struct atmel_sha_dev *)data; @@ -941,32 +1194,142 @@ static void atmel_sha_unregister_algs(struct atmel_sha_dev *dd) { int i; - for (i = 0; i < ARRAY_SIZE(sha_algs); i++) - crypto_unregister_ahash(&sha_algs[i]); + for (i = 0; i < ARRAY_SIZE(sha_1_256_algs); i++) + crypto_unregister_ahash(&sha_1_256_algs[i]); + + if (dd->caps.has_sha224) + crypto_unregister_ahash(&sha_224_alg); + + if (dd->caps.has_sha_384_512) { + for (i = 0; i < ARRAY_SIZE(sha_384_512_algs); i++) + crypto_unregister_ahash(&sha_384_512_algs[i]); + } } static int atmel_sha_register_algs(struct atmel_sha_dev *dd) { int err, i, j; - for (i = 0; i < ARRAY_SIZE(sha_algs); i++) { - err = crypto_register_ahash(&sha_algs[i]); + for (i = 0; i < ARRAY_SIZE(sha_1_256_algs); i++) { + err = crypto_register_ahash(&sha_1_256_algs[i]); if (err) - goto err_sha_algs; + goto err_sha_1_256_algs; + } + + if (dd->caps.has_sha224) { + err = crypto_register_ahash(&sha_224_alg); + if (err) + goto err_sha_224_algs; + } + + if (dd->caps.has_sha_384_512) { + for (i = 0; i < ARRAY_SIZE(sha_384_512_algs); i++) { + err = crypto_register_ahash(&sha_384_512_algs[i]); + if (err) + goto err_sha_384_512_algs; + } } return 0; -err_sha_algs: +err_sha_384_512_algs: + for (j = 0; j < i; j++) + crypto_unregister_ahash(&sha_384_512_algs[j]); + crypto_unregister_ahash(&sha_224_alg); +err_sha_224_algs: + i = ARRAY_SIZE(sha_1_256_algs); +err_sha_1_256_algs: for (j = 0; j < i; j++) - crypto_unregister_ahash(&sha_algs[j]); + crypto_unregister_ahash(&sha_1_256_algs[j]); return err; } +static bool atmel_sha_filter(struct dma_chan *chan, void *slave) +{ + struct at_dma_slave *sl = slave; + + if (sl && sl->dma_dev == chan->device->dev) { + chan->private = sl; + return true; + } else { + return false; + } +} + +static int atmel_sha_dma_init(struct atmel_sha_dev *dd, + struct crypto_platform_data *pdata) +{ + int err = -ENOMEM; + dma_cap_mask_t mask_in; + + if (pdata && pdata->dma_slave->rxdata.dma_dev) { + /* Try to grab DMA channel */ + dma_cap_zero(mask_in); + dma_cap_set(DMA_SLAVE, mask_in); + + dd->dma_lch_in.chan = dma_request_channel(mask_in, + atmel_sha_filter, &pdata->dma_slave->rxdata); + + if (!dd->dma_lch_in.chan) + return err; + + dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; + dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + + SHA_REG_DIN(0); + dd->dma_lch_in.dma_conf.src_maxburst = 1; + dd->dma_lch_in.dma_conf.src_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_in.dma_conf.dst_maxburst = 1; + dd->dma_lch_in.dma_conf.dst_addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_in.dma_conf.device_fc = false; + + return 0; + } + + return -ENODEV; +} + +static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) +{ + dma_release_channel(dd->dma_lch_in.chan); +} + +static void atmel_sha_get_cap(struct atmel_sha_dev *dd) +{ + + dd->caps.has_dma = 0; + dd->caps.has_dualbuff = 0; + dd->caps.has_sha224 = 0; + dd->caps.has_sha_384_512 = 0; + + /* keep only major version number */ + switch (dd->hw_version & 0xff0) { + case 0x410: + dd->caps.has_dma = 1; + dd->caps.has_dualbuff = 1; + dd->caps.has_sha224 = 1; + dd->caps.has_sha_384_512 = 1; + break; + case 0x400: + dd->caps.has_dma = 1; + dd->caps.has_dualbuff = 1; + dd->caps.has_sha224 = 1; + break; + case 0x320: + break; + default: + dev_warn(dd->dev, + "Unmanaged sha version, set minimum capabilities\n"); + break; + } +} + static int atmel_sha_probe(struct platform_device *pdev) { struct atmel_sha_dev *sha_dd; + struct crypto_platform_data *pdata; struct device *dev = &pdev->dev; struct resource *sha_res; unsigned long sha_phys_size; @@ -1018,7 +1381,7 @@ static int atmel_sha_probe(struct platform_device *pdev) } /* Initializing the clock */ - sha_dd->iclk = clk_get(&pdev->dev, NULL); + sha_dd->iclk = clk_get(&pdev->dev, "sha_clk"); if (IS_ERR(sha_dd->iclk)) { dev_err(dev, "clock intialization failed.\n"); err = PTR_ERR(sha_dd->iclk); @@ -1032,6 +1395,22 @@ static int atmel_sha_probe(struct platform_device *pdev) goto sha_io_err; } + atmel_sha_hw_version_init(sha_dd); + + atmel_sha_get_cap(sha_dd); + + if (sha_dd->caps.has_dma) { + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "platform data not available\n"); + err = -ENXIO; + goto err_pdata; + } + err = atmel_sha_dma_init(sha_dd, pdata); + if (err) + goto err_sha_dma; + } + spin_lock(&atmel_sha.lock); list_add_tail(&sha_dd->list, &atmel_sha.dev_list); spin_unlock(&atmel_sha.lock); @@ -1048,6 +1427,10 @@ err_algs: spin_lock(&atmel_sha.lock); list_del(&sha_dd->list); spin_unlock(&atmel_sha.lock); + if (sha_dd->caps.has_dma) + atmel_sha_dma_cleanup(sha_dd); +err_sha_dma: +err_pdata: iounmap(sha_dd->io_base); sha_io_err: clk_put(sha_dd->iclk); @@ -1078,6 +1461,9 @@ static int atmel_sha_remove(struct platform_device *pdev) tasklet_kill(&sha_dd->done_task); + if (sha_dd->caps.has_dma) + atmel_sha_dma_cleanup(sha_dd); + iounmap(sha_dd->io_base); clk_put(sha_dd->iclk); @@ -1102,6 +1488,6 @@ static struct platform_driver atmel_sha_driver = { module_platform_driver(atmel_sha_driver); -MODULE_DESCRIPTION("Atmel SHA1/SHA256 hw acceleration support."); +MODULE_DESCRIPTION("Atmel SHA (1/256/224/384/512) hw acceleration support."); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Nicolas Royer - Eukréa Electromatique"); -- cgit From fb1dd794802022f4413d36e47bd40f8c7bacd456 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 03:57:39 +0530 Subject: crypto: bfin_crc - Fix possible NULL pointer dereference If we define dev_dbg(), then there is a possible NULL pointer dereference. Signed-off-by: Syam Sidhardhan Signed-off-by: Herbert Xu --- drivers/crypto/bfin_crc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/bfin_crc.c b/drivers/crypto/bfin_crc.c index 827913d7d33a..d797f31f5d85 100644 --- a/drivers/crypto/bfin_crc.c +++ b/drivers/crypto/bfin_crc.c @@ -151,7 +151,7 @@ static int bfin_crypto_crc_init(struct ahash_request *req) struct bfin_crypto_crc_reqctx *ctx = ahash_request_ctx(req); struct bfin_crypto_crc *crc; - dev_dbg(crc->dev, "crc_init\n"); + dev_dbg(ctx->crc->dev, "crc_init\n"); spin_lock_bh(&crc_list.lock); list_for_each_entry(crc, &crc_list.dev_list, list) { crc_ctx->crc = crc; @@ -160,7 +160,7 @@ static int bfin_crypto_crc_init(struct ahash_request *req) spin_unlock_bh(&crc_list.lock); if (sg_count(req->src) > CRC_MAX_DMA_DESC) { - dev_dbg(crc->dev, "init: requested sg list is too big > %d\n", + dev_dbg(ctx->crc->dev, "init: requested sg list is too big > %d\n", CRC_MAX_DMA_DESC); return -EINVAL; } @@ -175,7 +175,7 @@ static int bfin_crypto_crc_init(struct ahash_request *req) /* init crc results */ put_unaligned_le32(crc_ctx->key, req->result); - dev_dbg(crc->dev, "init: digest size: %d\n", + dev_dbg(ctx->crc->dev, "init: digest size: %d\n", crypto_ahash_digestsize(tfm)); return bfin_crypto_crc_init_hw(crc, crc_ctx->key); -- cgit From e68af48251ffb2a8aad4664ea68e0363893dda26 Mon Sep 17 00:00:00 2001 From: Joel A Fernandes Date: Tue, 26 Feb 2013 10:04:31 -0600 Subject: crypto: omap-sham - Use pm_runtime_put instead of pm_runtime_put_sync in tasklet After DMA is complete, the omap_sham_finish_req function is called as a part of the done_task tasklet. During this its atomic and any calls to pm functions should not assume they wont sleep. The patch replaces a call to pm_runtime_put_sync (which can sleep) with pm_runtime_put thus fixing a kernel panic observed on AM33xx SoC during SHA operation. Tested on an AM33xx SoC device (beaglebone board). To reproduce the problem, used the tcrypt kernel module as: modprobe tcrypt sec=2 mode=403 Signed-off-by: Joel A Fernandes Cc: David S. Miller Acked-by: Mark A. Greer Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 3d1611f5aecf..1cfdea142b6b 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -923,7 +923,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) | BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY)); - pm_runtime_put_sync(dd->dev); + pm_runtime_put(dd->dev); if (req->base.complete) req->base.complete(&req->base, err); -- cgit From bbbaa37428abac025fe11b83933473888ddf6fc1 Mon Sep 17 00:00:00 2001 From: Joel A Fernandes Date: Tue, 26 Feb 2013 10:04:32 -0600 Subject: crypto: omap-aes - Use pm_runtime_put instead of pm_runtime_put_sync in tasklet After DMA is complete, the omap_aes_finish_req function is called as a part of the done_task tasklet. During this its atomic and any calls to pm functions should not assume they wont sleep. The patch replaces a call to pm_runtime_put_sync (which can sleep) with pm_runtime_put thus fixing a kernel panic observed on AM33xx SoC during AES operation. Tested on an AM33xx SoC device (beaglebone board). To reproduce the problem, I used the tcrypt kernel module as: modprobe tcrypt sec=2 mode=500 Signed-off-by: Joel A Fernandes Cc: David S. Miller Acked-by: Mark A. Greer Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 6aa425fe0ed5..1e5a17adefe4 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -636,7 +636,7 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) pr_debug("err: %d\n", err); - pm_runtime_put_sync(dd->dev); + pm_runtime_put(dd->dev); dd->flags &= ~FLAGS_BUSY; req->base.complete(&req->base, err); -- cgit From 94e51df9d60c818a7974f545fd32f6690a9605d9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 15:09:42 +0530 Subject: crypto: omap-aes - Use module_platform_driver macro module_platform_driver() makes the code simpler by eliminating boilerplate code. Signed-off-by: Sachin Kamat Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 1e5a17adefe4..ee15b0f7849a 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -1248,18 +1248,7 @@ static struct platform_driver omap_aes_driver = { }, }; -static int __init omap_aes_mod_init(void) -{ - return platform_driver_register(&omap_aes_driver); -} - -static void __exit omap_aes_mod_exit(void) -{ - platform_driver_unregister(&omap_aes_driver); -} - -module_init(omap_aes_mod_init); -module_exit(omap_aes_mod_exit); +module_platform_driver(omap_aes_driver); MODULE_DESCRIPTION("OMAP AES hw acceleration support."); MODULE_LICENSE("GPL v2"); -- cgit From 0261370268193755c5ff1bef3d9d6339f314052c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 15:09:43 +0530 Subject: crypto: omap-sham - Use module_platform_driver macro module_platform_driver() makes the code simpler by eliminating boilerplate code. Signed-off-by: Sachin Kamat Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 1cfdea142b6b..a1e1b4756ee5 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -1813,18 +1813,7 @@ static struct platform_driver omap_sham_driver = { }, }; -static int __init omap_sham_mod_init(void) -{ - return platform_driver_register(&omap_sham_driver); -} - -static void __exit omap_sham_mod_exit(void) -{ - platform_driver_unregister(&omap_sham_driver); -} - -module_init(omap_sham_mod_init); -module_exit(omap_sham_mod_exit); +module_platform_driver(omap_sham_driver); MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support."); MODULE_LICENSE("GPL v2"); -- cgit From ae8488a507357fd4fd2c825ac423b39ea1041353 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 5 Mar 2013 14:33:16 +0100 Subject: crypto: caam - fix typo "CRYPTO_AHASH" The Kconfig entry for CAAM's hash algorithm implementations has always selected CRYPTO_AHASH. But there's no corresponding Kconfig symbol. It seems it was intended to select CRYPTO_HASH, like other crypto drivers do. That would apparently (indirectly) select CRYPTO_HASH2, which would enable the ahash functionality this driver uses. Signed-off-by: Paul Bolle Reviewed-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 65c7668614ab..b44091c47f75 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -78,7 +78,7 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API tristate "Register hash algorithm implementations with Crypto API" depends on CRYPTO_DEV_FSL_CAAM default y - select CRYPTO_AHASH + select CRYPTO_HASH help Selecting this will offload ahash for users of the scatterlist crypto API to the SEC4 via job ring. -- cgit From e41eef8f317a4cfe43ec4de2527703a2e6f16087 Mon Sep 17 00:00:00 2001 From: Andreea Hodea Date: Sun, 10 Mar 2013 02:34:36 +0000 Subject: eicon: Fixed checkpatch warning drivers/isdn/hardware/eicon/diva_didd.c:32:6: warning: symbol 'DRIVERRELEASE_DIDD' was not declared. Should it be static? Signed-off-by: Andreea Hodea Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/diva_didd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c index fab6ccfb00d5..21468be0f3d5 100644 --- a/drivers/isdn/hardware/eicon/diva_didd.c +++ b/drivers/isdn/hardware/eicon/diva_didd.c @@ -29,7 +29,7 @@ static char *main_revision = "$Revision: 1.13.6.4 $"; static char *DRIVERNAME = "Eicon DIVA - DIDD table (http://www.melware.net)"; static char *DRIVERLNAME = "divadidd"; -char *DRIVERRELEASE_DIDD = "2.0"; +static char *DRIVERRELEASE_DIDD = "2.0"; MODULE_DESCRIPTION("DIDD table driver for diva drivers"); MODULE_AUTHOR("Cytronics & Melware, Eicon Networks"); -- cgit From 1c03da0522e91617fcadeb7dd596ee41f2b116b9 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 10 Mar 2013 03:57:47 +0000 Subject: bcm63xx_enet: use managed io memory allocations Signed-off-by: Jonas Gorski Acked-by: Kevin Cernekee Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 43 +++++----------------------- 1 file changed, 7 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 7d81e059e811..8256b55883e2 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1619,7 +1619,6 @@ static int bcm_enet_probe(struct platform_device *pdev) struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx; struct mii_bus *bus; const char *clk_name; - unsigned int iomem_size; int i, ret; /* stop if shared driver failed, assume driver->probe will be @@ -1644,17 +1643,12 @@ static int bcm_enet_probe(struct platform_device *pdev) if (ret) goto out; - iomem_size = resource_size(res_mem); - if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) { - ret = -EBUSY; - goto out; - } - - priv->base = ioremap(res_mem->start, iomem_size); + priv->base = devm_request_and_ioremap(&pdev->dev, res_mem); if (priv->base == NULL) { ret = -ENOMEM; - goto out_release_mem; + goto out; } + dev->irq = priv->irq = res_irq->start; priv->irq_rx = res_irq_rx->start; priv->irq_tx = res_irq_tx->start; @@ -1674,7 +1668,7 @@ static int bcm_enet_probe(struct platform_device *pdev) priv->mac_clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(priv->mac_clk)) { ret = PTR_ERR(priv->mac_clk); - goto out_unmap; + goto out; } clk_enable(priv->mac_clk); @@ -1814,12 +1808,6 @@ out_uninit_hw: out_put_clk_mac: clk_disable(priv->mac_clk); clk_put(priv->mac_clk); - -out_unmap: - iounmap(priv->base); - -out_release_mem: - release_mem_region(res_mem->start, iomem_size); out: free_netdev(dev); return ret; @@ -1833,7 +1821,6 @@ static int bcm_enet_remove(struct platform_device *pdev) { struct bcm_enet_priv *priv; struct net_device *dev; - struct resource *res; /* stop netdevice */ dev = platform_get_drvdata(pdev); @@ -1856,11 +1843,6 @@ static int bcm_enet_remove(struct platform_device *pdev) bcm_enet_mdio_write_mii); } - /* release device resources */ - iounmap(priv->base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - /* disable hw block clocks */ if (priv->phy_clk) { clk_disable(priv->phy_clk); @@ -1889,31 +1871,20 @@ struct platform_driver bcm63xx_enet_driver = { static int bcm_enet_shared_probe(struct platform_device *pdev) { struct resource *res; - unsigned int iomem_size; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - iomem_size = resource_size(res); - if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma")) - return -EBUSY; - - bcm_enet_shared_base = ioremap(res->start, iomem_size); - if (!bcm_enet_shared_base) { - release_mem_region(res->start, iomem_size); + bcm_enet_shared_base = devm_request_and_ioremap(&pdev->dev, res); + if (!bcm_enet_shared_base) return -ENOMEM; - } + return 0; } static int bcm_enet_shared_remove(struct platform_device *pdev) { - struct resource *res; - - iounmap(bcm_enet_shared_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); return 0; } -- cgit From 2a80b5e1580cf6b2c534674080dc3fdf788b06b8 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 10 Mar 2013 03:57:48 +0000 Subject: bcm63xx_enet: use managed memory allocations Signed-off-by: Jonas Gorski Acked-by: Kevin Cernekee Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 8256b55883e2..b45e5fd46df6 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1727,7 +1727,8 @@ static int bcm_enet_probe(struct platform_device *pdev) * if a slave is not present on hw */ bus->phy_mask = ~(1 << priv->phy_id); - bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR, + GFP_KERNEL); if (!bus->irq) { ret = -ENOMEM; goto out_free_mdio; @@ -1788,10 +1789,8 @@ static int bcm_enet_probe(struct platform_device *pdev) return 0; out_unregister_mdio: - if (priv->mii_bus) { + if (priv->mii_bus) mdiobus_unregister(priv->mii_bus); - kfree(priv->mii_bus->irq); - } out_free_mdio: if (priv->mii_bus) @@ -1832,7 +1831,6 @@ static int bcm_enet_remove(struct platform_device *pdev) if (priv->has_phy) { mdiobus_unregister(priv->mii_bus); - kfree(priv->mii_bus->irq); mdiobus_free(priv->mii_bus); } else { struct bcm63xx_enet_platform_data *pd; -- cgit From 624e2d21356a40ad7200cb30c4f966741d805a79 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 10 Mar 2013 03:57:49 +0000 Subject: bcm63xx_enet: properly prepare/unprepare clocks before/after usage Use clk_prepare_enable/disable_unprepare calls in preparation for switching to the generic clock framework. Signed-off-by: Jonas Gorski Acked-by: Kevin Cernekee Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index b45e5fd46df6..db343a1d0835 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1670,7 +1670,7 @@ static int bcm_enet_probe(struct platform_device *pdev) ret = PTR_ERR(priv->mac_clk); goto out; } - clk_enable(priv->mac_clk); + clk_prepare_enable(priv->mac_clk); /* initialize default and fetch platform data */ priv->rx_ring_size = BCMENET_DEF_RX_DESC; @@ -1699,7 +1699,7 @@ static int bcm_enet_probe(struct platform_device *pdev) priv->phy_clk = NULL; goto out_put_clk_mac; } - clk_enable(priv->phy_clk); + clk_prepare_enable(priv->phy_clk); } /* do minimal hardware init to be able to probe mii bus */ @@ -1800,12 +1800,12 @@ out_uninit_hw: /* turn off mdc clock */ enet_writel(priv, 0, ENET_MIISC_REG); if (priv->phy_clk) { - clk_disable(priv->phy_clk); + clk_disable_unprepare(priv->phy_clk); clk_put(priv->phy_clk); } out_put_clk_mac: - clk_disable(priv->mac_clk); + clk_disable_unprepare(priv->mac_clk); clk_put(priv->mac_clk); out: free_netdev(dev); @@ -1843,10 +1843,10 @@ static int bcm_enet_remove(struct platform_device *pdev) /* disable hw block clocks */ if (priv->phy_clk) { - clk_disable(priv->phy_clk); + clk_disable_unprepare(priv->phy_clk); clk_put(priv->phy_clk); } - clk_disable(priv->mac_clk); + clk_disable_unprepare(priv->mac_clk); clk_put(priv->mac_clk); platform_set_drvdata(pdev, NULL); -- cgit From 63cd353c34a08af2d1935f8d0c2b6b091714ff79 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 13 Feb 2013 10:45:46 +0100 Subject: NFC: microread: Fix MEI build failure The mei_device field should be called device, not mei_device. Signed-off-by: Samuel Ortiz --- drivers/nfc/microread/mei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c index eef38cfd812e..13bde92b1e29 100644 --- a/drivers/nfc/microread/mei.c +++ b/drivers/nfc/microread/mei.c @@ -48,7 +48,7 @@ struct mei_nfc_hdr { #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) struct microread_mei_phy { - struct mei_device *mei_device; + struct mei_device *device; struct nfc_hci_dev *hdev; int powered; -- cgit From 73e046839925920eff2085e9238c81f051d9619b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Mar 2013 17:48:26 -0400 Subject: Revert "eicon: Fixed checkpatch warning" This reverts commit e41eef8f317a4cfe43ec4de2527703a2e6f16087. It breaks the build, this symbol is refernced by debugging macros in diddfunc.c Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/diva_didd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c index 21468be0f3d5..fab6ccfb00d5 100644 --- a/drivers/isdn/hardware/eicon/diva_didd.c +++ b/drivers/isdn/hardware/eicon/diva_didd.c @@ -29,7 +29,7 @@ static char *main_revision = "$Revision: 1.13.6.4 $"; static char *DRIVERNAME = "Eicon DIVA - DIDD table (http://www.melware.net)"; static char *DRIVERLNAME = "divadidd"; -static char *DRIVERRELEASE_DIDD = "2.0"; +char *DRIVERRELEASE_DIDD = "2.0"; MODULE_DESCRIPTION("DIDD table driver for diva drivers"); MODULE_AUTHOR("Cytronics & Melware, Eicon Networks"); -- cgit From b78f5fc92a836259b69d49129c6c1cad9b03c322 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Mar 2013 11:12:58 +0900 Subject: pwm: pwm-tiecap: add CONFIG_PM_SLEEP to suspend/resume functions This patch adds CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. drivers/pwm/pwm-tiecap.c:314:12: warning: 'ecap_pwm_suspend' defined but not used [-Wunused-function] drivers/pwm/pwm-tiecap.c:328:12: warning: 'ecap_pwm_resume' defined but not used [-Wunused-function] Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiecap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 22e96e2bffd3..f024db06e6c4 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -311,6 +311,7 @@ void ecap_pwm_restore_context(struct ecap_pwm_chip *pc) writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2); } +#ifdef CONFIG_PM_SLEEP static int ecap_pwm_suspend(struct device *dev) { struct ecap_pwm_chip *pc = dev_get_drvdata(dev); @@ -337,6 +338,7 @@ static int ecap_pwm_resume(struct device *dev) ecap_pwm_restore_context(pc); return 0; } +#endif static SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume); -- cgit From c26e9bb4ac72312386dc8ffa4dc8c1b560d9b29b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Mar 2013 11:14:16 +0900 Subject: pwm: pwm-tipwmss: add CONFIG_PM_SLEEP to suspend/resume functions This patch adds CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. drivers/pwm/pwm-tipwmss.c:104:12: warning: 'pwmss_suspend' defined but not used [-Wunused-function] drivers/pwm/pwm-tipwmss.c:113:12: warning: 'pwmss_resume' defined but not used [-Wunused-function] Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tipwmss.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c index 17cbc59660ec..c9c3d3a1e0eb 100644 --- a/drivers/pwm/pwm-tipwmss.c +++ b/drivers/pwm/pwm-tipwmss.c @@ -101,6 +101,7 @@ static int pwmss_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP static int pwmss_suspend(struct device *dev) { struct pwmss_info *info = dev_get_drvdata(dev); @@ -118,6 +119,7 @@ static int pwmss_resume(struct device *dev) writew(info->pwmss_clkconfig, info->mmio_base + PWMSS_CLKCONFIG); return 0; } +#endif static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume); -- cgit From 29258b215af83dbb4ad143cefe7a1e5d0384a605 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Mar 2013 11:14:41 +0900 Subject: pwm: pwm-tiehrpwm: add CONFIG_PM_SLEEP to suspend/resume functions This patch adds CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. drivers/pwm/pwm-tiehrpwm.c:562:12: warning: 'ehrpwm_pwm_suspend' defined but not used [-Wunused-function] drivers/pwm/pwm-tiehrpwm.c:580:12: warning: 'ehrpwm_pwm_resume' defined but not used [-Wunused-function Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiehrpwm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 8b4c86fa99c8..d058ba90845b 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -559,6 +559,7 @@ void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc) ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl); } +#ifdef CONFIG_PM_SLEEP static int ehrpwm_pwm_suspend(struct device *dev) { struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); @@ -594,6 +595,7 @@ static int ehrpwm_pwm_resume(struct device *dev) ehrpwm_pwm_restore_context(pc); return 0; } +#endif static SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend, ehrpwm_pwm_resume); -- cgit From effbfdd7baf7babc73154b87a5ff940969cf6559 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 6 Feb 2013 14:40:22 -0600 Subject: clocksource: pass DT node pointer to init functions In cases where we have multiple nodes of the same type, we may need the node pointer to know which node was matched. Passing the node pointer also keeps the init function from having to match the node a 2nd time. Update bcm2835, vt8500, and tegra20 init functions for the new function prototype. Further tegra20 clean-ups are in follow-up commit. Signed-off-by: Rob Herring Cc: John Stultz Cc: Thomas Gleixner Reviewed-by: Stephen Warren Tested-by: Stephen Warren Acked-by: Arnd Bergmann Acked-by: Tony Prisk Tested-by: Michal Simek --- drivers/clocksource/bcm2835_timer.c | 12 +----------- drivers/clocksource/clksrc-of.c | 4 ++-- drivers/clocksource/tegra20_timer.c | 3 +-- drivers/clocksource/vt8500_timer.c | 14 +------------- 4 files changed, 5 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c index 50c68fef944b..766611d29945 100644 --- a/drivers/clocksource/bcm2835_timer.c +++ b/drivers/clocksource/bcm2835_timer.c @@ -95,23 +95,13 @@ static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id) } } -static struct of_device_id bcm2835_time_match[] __initconst = { - { .compatible = "brcm,bcm2835-system-timer" }, - {} -}; - -static void __init bcm2835_timer_init(void) +static void __init bcm2835_timer_init(struct device_node *node) { - struct device_node *node; void __iomem *base; u32 freq; int irq; struct bcm2835_timer *timer; - node = of_find_matching_node(NULL, bcm2835_time_match); - if (!node) - panic("No bcm2835 timer node"); - base = of_iomap(node, 0); if (!base) panic("Can't remap registers"); diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index bdabdaa8d00f..3ef11fba781c 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c @@ -26,10 +26,10 @@ void __init clocksource_of_init(void) { struct device_node *np; const struct of_device_id *match; - void (*init_func)(void); + void (*init_func)(struct device_node *); for_each_matching_node_and_match(np, __clksrc_of_table, &match) { init_func = match->data; - init_func(); + init_func(np); } } diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index 0bde03feb095..b3396ab15f63 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c @@ -164,9 +164,8 @@ static const struct of_device_id rtc_match[] __initconst = { {} }; -static void __init tegra20_init_timer(void) +static void __init tegra20_init_timer(struct device_node *np) { - struct device_node *np; struct clk *clk; unsigned long rate; int ret; diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index 8efc86b5b5dd..242255285597 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c @@ -129,22 +129,10 @@ static struct irqaction irq = { .dev_id = &clockevent, }; -static struct of_device_id vt8500_timer_ids[] = { - { .compatible = "via,vt8500-timer" }, - { } -}; - -static void __init vt8500_timer_init(void) +static void __init vt8500_timer_init(struct device_node *np) { - struct device_node *np; int timer_irq; - np = of_find_matching_node(NULL, vt8500_timer_ids); - if (!np) { - pr_err("%s: Timer description missing from Device Tree\n", - __func__); - return; - } regbase = of_iomap(np, 0); if (!regbase) { pr_err("%s: Missing iobase description in Device Tree\n", -- cgit From 1d16cfb3aeba71bc6ecf2d19ccbabed0426e5c22 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 7 Feb 2013 11:36:23 -0600 Subject: clocksource: tegra20: use the device_node pointer passed to init We've already matched the node, so use the node pointer passed in. The rtc init was intermingled with the timer init, so split this out to a separate init function. Signed-off-by: Rob Herring Cc: John Stultz Cc: Thomas Gleixner Reviewed-by: Stephen Warren Tested-by: Stephen Warren --- drivers/clocksource/tegra20_timer.c | 67 ++++++++++++++----------------------- 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index b3396ab15f63..15cc723f699f 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c @@ -154,28 +154,12 @@ static struct irqaction tegra_timer_irq = { .dev_id = &tegra_clockevent, }; -static const struct of_device_id timer_match[] __initconst = { - { .compatible = "nvidia,tegra20-timer" }, - {} -}; - -static const struct of_device_id rtc_match[] __initconst = { - { .compatible = "nvidia,tegra20-rtc" }, - {} -}; - static void __init tegra20_init_timer(struct device_node *np) { struct clk *clk; unsigned long rate; int ret; - np = of_find_matching_node(NULL, timer_match); - if (!np) { - pr_err("Failed to find timer DT node\n"); - BUG(); - } - timer_reg_base = of_iomap(np, 0); if (!timer_reg_base) { pr_err("Can't map timer registers\n"); @@ -199,30 +183,6 @@ static void __init tegra20_init_timer(struct device_node *np) of_node_put(np); - np = of_find_matching_node(NULL, rtc_match); - if (!np) { - pr_err("Failed to find RTC DT node\n"); - BUG(); - } - - rtc_base = of_iomap(np, 0); - if (!rtc_base) { - pr_err("Can't map RTC registers"); - BUG(); - } - - /* - * rtc registers are used by read_persistent_clock, keep the rtc clock - * enabled - */ - clk = clk_get_sys("rtc-tegra", NULL); - if (IS_ERR(clk)) - pr_warn("Unable to get rtc-tegra clock\n"); - else - clk_prepare_enable(clk); - - of_node_put(np); - switch (rate) { case 12000000: timer_writel(0x000b, TIMERUS_USEC_CFG); @@ -261,9 +221,34 @@ static void __init tegra20_init_timer(struct device_node *np) #ifdef CONFIG_HAVE_ARM_TWD twd_local_timer_of_register(); #endif +} +CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); + +static void __init tegra20_init_rtc(struct device_node *np) +{ + struct clk *clk; + + rtc_base = of_iomap(np, 0); + if (!rtc_base) { + pr_err("Can't map RTC registers"); + BUG(); + } + + /* + * rtc registers are used by read_persistent_clock, keep the rtc clock + * enabled + */ + clk = clk_get_sys("rtc-tegra", NULL); + if (IS_ERR(clk)) + pr_warn("Unable to get rtc-tegra clock\n"); + else + clk_prepare_enable(clk); + + of_node_put(np); + register_persistent_clock(NULL, tegra_read_persistent_clock); } -CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer); +CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); #ifdef CONFIG_PM static u32 usec_config; -- cgit From da4a686a2cfb077a8bfc1697f597e7f86235b822 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 6 Feb 2013 21:17:47 -0600 Subject: ARM: smp_twd: convert to use CLKSRC_OF init Now that we have OF based init with CLKSRC_OF, convert smp_twd init function to use it and covert all callers of twd_local_timer_of_register. Signed-off-by: Rob Herring Cc: Shawn Guo Cc: Sascha Hauer Cc: Russell King Cc: Viresh Kumar Cc: Shiraz Hashim Cc: Srinidhi Kasagar Cc: John Stultz Cc: Thomas Gleixner Cc: linux-omap@vger.kernel.org Cc: spear-devel@list.st.com Reviewed-by: Stephen Warren Acked-by: Santosh Shilimkar Acked-by: Tony Lindgren Acked-by: Linus Walleij --- arch/arm/Kconfig | 1 + arch/arm/include/asm/smp_twd.h | 8 -------- arch/arm/kernel/smp_twd.c | 17 ++++------------- arch/arm/mach-highbank/highbank.c | 5 ++--- arch/arm/mach-imx/mach-imx6q.c | 5 ++--- arch/arm/mach-omap2/timer.c | 2 +- arch/arm/mach-spear13xx/spear13xx.c | 4 ++-- arch/arm/mach-ux500/timer.c | 3 ++- arch/arm/mach-vexpress/v2m.c | 6 +++--- drivers/clocksource/tegra20_timer.c | 3 --- 10 files changed, 17 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b714695b01b..5bfd584929c8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1597,6 +1597,7 @@ config HAVE_ARM_ARCH_TIMER config HAVE_ARM_TWD bool depends on SMP + select CLKSRC_OF if OF help This options enables support for the ARM timer and watchdog unit diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index 0f01f4677bd2..7b2899c2f7fc 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -34,12 +34,4 @@ struct twd_local_timer name __initdata = { \ int twd_local_timer_register(struct twd_local_timer *); -#ifdef CONFIG_HAVE_ARM_TWD -void twd_local_timer_of_register(void); -#else -static inline void twd_local_timer_of_register(void) -{ -} -#endif - #endif diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 3f2565037480..90525d9d290b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -362,25 +362,13 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt) } #ifdef CONFIG_OF -const static struct of_device_id twd_of_match[] __initconst = { - { .compatible = "arm,cortex-a9-twd-timer", }, - { .compatible = "arm,cortex-a5-twd-timer", }, - { .compatible = "arm,arm11mp-twd-timer", }, - { }, -}; - -void __init twd_local_timer_of_register(void) +static void __init twd_local_timer_of_register(struct device_node *np) { - struct device_node *np; int err; if (!is_smp() || !setup_max_cpus) return; - np = of_find_matching_node(NULL, twd_of_match); - if (!np) - return; - twd_ppi = irq_of_parse_and_map(np, 0); if (!twd_ppi) { err = -EINVAL; @@ -398,4 +386,7 @@ void __init twd_local_timer_of_register(void) out: WARN(err, "twd_local_timer_of_register failed (%d)\n", err); } +CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register); +CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register); +CLOCKSOURCE_OF_DECLARE(arm_twd_11mp, "arm,arm11mp-twd-timer", twd_local_timer_of_register); #endif diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index a4f9f50247d4..76c1170b3528 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -119,10 +118,10 @@ static void __init highbank_timer_init(void) sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); sp804_clockevents_init(timer_base, irq, "timer0"); - twd_local_timer_of_register(); - arch_timer_of_register(); arch_timer_sched_clock_init(); + + clocksource_of_init(); } static void highbank_power_off(void) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 9ffd103b27e4..b59ddcb57c78 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -28,11 +29,9 @@ #include #include #include -#include #include #include #include -#include #include #include "common.h" @@ -292,7 +291,7 @@ static void __init imx6q_init_irq(void) static void __init imx6q_timer_init(void) { mx6q_clocks_init(); - twd_local_timer_of_register(); + clocksource_of_init(); imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2bdd4cf17a8f..4fd80257c73e 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -597,7 +597,7 @@ void __init omap4_local_timer_init(void) int err; if (of_have_populated_dt()) { - twd_local_timer_of_register(); + clocksource_of_init(); return; } diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index c7d2b4a8d8cc..25a10191b021 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c @@ -15,12 +15,12 @@ #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -179,5 +179,5 @@ void __init spear13xx_timer_init(void) clk_put(pclk); spear_setup_of_timer(); - twd_local_timer_of_register(); + clocksource_of_init(); } diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index a6af0b8732ba..d07bbe7f04a6 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,7 @@ static void __init ux500_twd_init(void) twd_local_timer = &u8500_twd_local_timer; if (of_have_populated_dt()) - twd_local_timer_of_register(); + clocksource_of_init(); else { err = twd_local_timer_register(twd_local_timer); if (err) diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 915683cb67d6..d0ad78998cb6 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -435,6 +435,7 @@ static void __init v2m_dt_timer_init(void) vexpress_clk_of_init(); + clocksource_of_init(); do { node = of_find_compatible_node(node, NULL, "arm,sp804"); } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB); @@ -445,8 +446,7 @@ static void __init v2m_dt_timer_init(void) irq_of_parse_and_map(node, 0)); } - if (arch_timer_of_register() != 0) - twd_local_timer_of_register(); + arch_timer_of_register(); if (arch_timer_sched_clock_init() != 0) versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index 15cc723f699f..2e4d8a666c36 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c @@ -218,9 +218,6 @@ static void __init tegra20_init_timer(struct device_node *np) tegra_clockevent.irq = tegra_timer_irq.irq; clockevents_config_and_register(&tegra_clockevent, 1000000, 0x1, 0x1fffffff); -#ifdef CONFIG_HAVE_ARM_TWD - twd_local_timer_of_register(); -#endif } CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); -- cgit From 44f507163d9e51238458ee6904b4d71fb0723723 Mon Sep 17 00:00:00 2001 From: Vijay Mohan Pandarathil Date: Mon, 11 Mar 2013 09:28:44 -0600 Subject: VFIO: Wrapper for getting reference to vfio_device - Added vfio_device_get_from_dev() as wrapper to get reference to vfio_device from struct device. - Added vfio_device_data() as a wrapper to get device_data from vfio_device. Signed-off-by: Vijay Mohan Pandarathil Signed-off-by: Alex Williamson --- drivers/vfio/vfio.c | 30 +++++++++++++++++++++++++++++- include/linux/vfio.h | 3 +++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index fcc12f3e60a3..21eddd9e0f26 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -392,12 +392,13 @@ static void vfio_device_release(struct kref *kref) } /* Device reference always implies a group reference */ -static void vfio_device_put(struct vfio_device *device) +void vfio_device_put(struct vfio_device *device) { struct vfio_group *group = device->group; kref_put_mutex(&device->kref, vfio_device_release, &group->device_lock); vfio_group_put(group); } +EXPORT_SYMBOL_GPL(vfio_device_put); static void vfio_device_get(struct vfio_device *device) { @@ -627,6 +628,33 @@ int vfio_add_group_dev(struct device *dev, } EXPORT_SYMBOL_GPL(vfio_add_group_dev); +/** + * Get a reference to the vfio_device for a device that is known to + * be bound to a vfio driver. The driver implicitly holds a + * vfio_device reference between vfio_add_group_dev and + * vfio_del_group_dev. We can therefore use drvdata to increment + * that reference from the struct device. This additional + * reference must be released by calling vfio_device_put. + */ +struct vfio_device *vfio_device_get_from_dev(struct device *dev) +{ + struct vfio_device *device = dev_get_drvdata(dev); + + vfio_device_get(device); + + return device; +} +EXPORT_SYMBOL_GPL(vfio_device_get_from_dev); + +/* + * Caller must hold a reference to the vfio_device + */ +void *vfio_device_data(struct vfio_device *device) +{ + return device->device_data; +} +EXPORT_SYMBOL_GPL(vfio_device_data); + /* Given a referenced group, check if it contains the device */ static bool vfio_dev_present(struct vfio_group *group, struct device *dev) { diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ab9e86224c54..ac8d488e4372 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -45,6 +45,9 @@ extern int vfio_add_group_dev(struct device *dev, void *device_data); extern void *vfio_del_group_dev(struct device *dev); +extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); +extern void vfio_device_put(struct vfio_device *device); +extern void *vfio_device_data(struct vfio_device *device); /** * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks -- cgit From dad9f8972e04cd081a028d8fb1249d746d97fc03 Mon Sep 17 00:00:00 2001 From: Vijay Mohan Pandarathil Date: Mon, 11 Mar 2013 09:31:22 -0600 Subject: VFIO-AER: Vfio-pci driver changes for supporting AER - New VFIO_SET_IRQ ioctl option to pass the eventfd that is signaled when an error occurs in the vfio_pci_device - Register pci_error_handler for the vfio_pci driver - When the device encounters an error, the error handler registered by the vfio_pci driver gets invoked by the AER infrastructure - In the error handler, signal the eventfd registered for the device. - This results in the qemu eventfd handler getting invoked and appropriate action taken for the guest. Signed-off-by: Vijay Mohan Pandarathil Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 44 ++++++++++++++++++++++++- drivers/vfio/pci/vfio_pci_intrs.c | 64 +++++++++++++++++++++++++++++++++++++ drivers/vfio/pci/vfio_pci_private.h | 1 + include/uapi/linux/vfio.h | 1 + 4 files changed, 109 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 8189cb6a86af..acfcb1ae77bc 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -201,7 +201,9 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) return (flags & PCI_MSIX_FLAGS_QSIZE) + 1; } - } + } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX) + if (pci_is_pcie(vdev->pdev)) + return 1; return 0; } @@ -317,6 +319,17 @@ static long vfio_pci_ioctl(void *device_data, if (info.argsz < minsz || info.index >= VFIO_PCI_NUM_IRQS) return -EINVAL; + switch (info.index) { + case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX: + break; + case VFIO_PCI_ERR_IRQ_INDEX: + if (pci_is_pcie(vdev->pdev)) + break; + /* pass thru to return error */ + default: + return -EINVAL; + } + info.flags = VFIO_IRQ_INFO_EVENTFD; info.count = vfio_pci_get_irq_count(vdev, info.index); @@ -551,11 +564,40 @@ static void vfio_pci_remove(struct pci_dev *pdev) kfree(vdev); } +static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct vfio_pci_device *vdev; + struct vfio_device *device; + + device = vfio_device_get_from_dev(&pdev->dev); + if (device == NULL) + return PCI_ERS_RESULT_DISCONNECT; + + vdev = vfio_device_data(device); + if (vdev == NULL) { + vfio_device_put(device); + return PCI_ERS_RESULT_DISCONNECT; + } + + if (vdev->err_trigger) + eventfd_signal(vdev->err_trigger, 1); + + vfio_device_put(device); + + return PCI_ERS_RESULT_CAN_RECOVER; +} + +static struct pci_error_handlers vfio_err_handlers = { + .error_detected = vfio_pci_aer_err_detected, +}; + static struct pci_driver vfio_pci_driver = { .name = "vfio-pci", .id_table = NULL, /* only dynamic ids */ .probe = vfio_pci_probe, .remove = vfio_pci_remove, + .err_handler = &vfio_err_handlers, }; static void __exit vfio_pci_cleanup(void) diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 3639371fa697..b84bf2210a91 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -745,6 +745,63 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev, return 0; } +static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev, + unsigned index, unsigned start, + unsigned count, uint32_t flags, void *data) +{ + int32_t fd = *(int32_t *)data; + struct pci_dev *pdev = vdev->pdev; + + if ((index != VFIO_PCI_ERR_IRQ_INDEX) || + !(flags & VFIO_IRQ_SET_DATA_TYPE_MASK)) + return -EINVAL; + + /* + * device_lock synchronizes setting and checking of + * err_trigger. The vfio_pci_aer_err_detected() is also + * called with device_lock held. + */ + + /* DATA_NONE/DATA_BOOL enables loopback testing */ + + if (flags & VFIO_IRQ_SET_DATA_NONE) { + device_lock(&pdev->dev); + if (vdev->err_trigger) + eventfd_signal(vdev->err_trigger, 1); + device_unlock(&pdev->dev); + return 0; + } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { + uint8_t trigger = *(uint8_t *)data; + device_lock(&pdev->dev); + if (trigger && vdev->err_trigger) + eventfd_signal(vdev->err_trigger, 1); + device_unlock(&pdev->dev); + return 0; + } + + /* Handle SET_DATA_EVENTFD */ + + if (fd == -1) { + device_lock(&pdev->dev); + if (vdev->err_trigger) + eventfd_ctx_put(vdev->err_trigger); + vdev->err_trigger = NULL; + device_unlock(&pdev->dev); + return 0; + } else if (fd >= 0) { + struct eventfd_ctx *efdctx; + efdctx = eventfd_ctx_fdget(fd); + if (IS_ERR(efdctx)) + return PTR_ERR(efdctx); + device_lock(&pdev->dev); + if (vdev->err_trigger) + eventfd_ctx_put(vdev->err_trigger); + vdev->err_trigger = efdctx; + device_unlock(&pdev->dev); + return 0; + } else + return -EINVAL; +} int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, unsigned index, unsigned start, unsigned count, void *data) @@ -779,6 +836,13 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, break; } break; + case VFIO_PCI_ERR_IRQ_INDEX: + switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) { + case VFIO_IRQ_SET_ACTION_TRIGGER: + if (pci_is_pcie(vdev->pdev)) + func = vfio_pci_set_err_trigger; + break; + } } if (!func) diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h index d7e55d03f49e..9c6d5d0f3b02 100644 --- a/drivers/vfio/pci/vfio_pci_private.h +++ b/drivers/vfio/pci/vfio_pci_private.h @@ -56,6 +56,7 @@ struct vfio_pci_device { bool has_vga; struct pci_saved_state *pci_saved_state; atomic_t refcnt; + struct eventfd_ctx *err_trigger; }; #define is_intx(vdev) (vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX) diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 4f41f309911e..284ff2436829 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -319,6 +319,7 @@ enum { VFIO_PCI_INTX_IRQ_INDEX, VFIO_PCI_MSI_IRQ_INDEX, VFIO_PCI_MSIX_IRQ_INDEX, + VFIO_PCI_ERR_IRQ_INDEX, VFIO_PCI_NUM_IRQS }; -- cgit From c37aeab62514cd623afa1b952ca86d53dd21a745 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 13:07:27 +0100 Subject: staging/sep: Fix smatch false positive about potential NULL dereference in sep_main.c Smatch complains about a potential NULL pointer dereference: sep_main.c:2312 sep_construct_dma_tables_from_lli() error: potential NULL dereference 'info_out_entry_ptr'. info_out_entry_ptr is initialized with NULL and if info_in_entry_ptr is not NULL it gets derefenced. However info_out_entry_ptr is only NULL in the first iteration of the while loop and in this case info_in_entry_ptr is also NULL (as indicated by the comment /* If info entry is null - this is the first table built */ -> this is a false positive. Nevertheless we add a check for info_out_entry_ptr to silence this warning and make it more robust in regard to code changes. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 30e8d25113e4..366d56b9a255 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -2276,7 +2276,7 @@ static int sep_construct_dma_tables_from_lli( table_data_size); /* If info entry is null - this is the first table built */ - if (info_in_entry_ptr == NULL) { + if (info_in_entry_ptr == NULL || info_out_entry_ptr == NULL) { /* Set the output parameters to physical addresses */ *lli_table_in_ptr = sep_shared_area_virt_to_bus(sep, dma_in_lli_table_ptr); -- cgit From eb1bd49c50880df667905b4cfb472064f62c05d1 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 13:07:28 +0100 Subject: staging/sep: Check pointers before dereferencing (fix smatch warning) smatch complains about two dereferenced before check issues: sep_main.c:2898 sep_free_dma_tables_and_dcb() warn: variable dereferenced before check 'dma_ctx' (see line 2885) sep_main.c:2898 sep_free_dma_tables_and_dcb() warn: variable dereferenced before check '*dma_ctx' (see line 2885) -> Move the checks to the top, but keep the semantics. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 366d56b9a255..f5b73419eebc 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -2880,6 +2880,8 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n", current->pid); + if (!dma_ctx || !*dma_ctx) /* nothing to be done here*/ + return 0; if (((*dma_ctx)->secure_dma == false) && (isapplet == true)) { dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n", @@ -2895,8 +2897,7 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, * Go over each DCB and see if * tail pointer must be updated */ - for (i = 0; dma_ctx && *dma_ctx && - i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { + for (i = 0; i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { if (dcb_table_ptr->out_vr_tail_pt) { pt_hold = (unsigned long)dcb_table_ptr-> out_vr_tail_pt; -- cgit From 075dd9b83da5bc54b53b23f6e315c19b54f2d800 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Wed, 6 Mar 2013 16:32:25 -0500 Subject: Staging: bcm: avoid use-after-free in bcm_char_ioctl() Free pBulkBuffer (pvBuffer) after pBulkBuffer->Register. Signed-off-by: Xi Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 491e2bfbc464..35641e529396 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -1148,8 +1148,8 @@ cntrlEnd: if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || ((ULONG)pBulkBuffer->Register & 0x3)) { - kfree(pvBuffer); BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)pBulkBuffer->Register); + kfree(pvBuffer); Status = -EINVAL; break; } -- cgit From 2c5270ac807e46889fb08c3cf3c65902d0c35bb2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 1 Mar 2013 23:28:06 +0300 Subject: Staging: bcm: potential forever loop verifying firmware There is an ioctl() to write data to the firmware. After the data is written, it reads the databack from the firmware and compares against what the user wanted to write and prints an error message if it doesn't match. The problem is that verify process has a forever loop if the firmware size is not a multiple of 4. I've fixed it by replacing the bcm compare function with memcmp(). I have chopped out some debugging code in the process. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceDld.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 64ea6edb9dc2..348ad75b340d 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -205,30 +205,6 @@ static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm return retval; } -static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len) -{ - int retval = STATUS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - if ((len-sizeof(unsigned int)) < 4) { - if (memcmp(readbackbuff , buff, len)) - retval = -EINVAL; - } else { - len -= 4; - - while (len) { - if (*(unsigned int *)&readbackbuff[len] != *(unsigned int *)&buff[len]) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); - retval = -EINVAL; - break; - } - len -= 4; - } - } - return retval; -} - int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; @@ -321,9 +297,11 @@ static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, break; } - retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len); - if (STATUS_SUCCESS != retval) - break; + if (memcmp(readbackbuff, mappedbuffer, len) != 0) { + pr_err("%s() failed. The firmware doesn't match what was written", + __func__); + retval = -EIO; + } u32StartingAddress += len; u32FirmwareLength -= len; -- cgit From acb84e9ec213a51578a00cdf14650610c174ef9b Mon Sep 17 00:00:00 2001 From: Mihnea Dobrescu-Balaur Date: Sun, 10 Mar 2013 14:48:27 +0200 Subject: staging: bcm: don't cast kzalloc() return value Signed-off-by: Mihnea Dobrescu-Balaur Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/nvm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index e6152f4df14b..bea1330f7ea6 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -2228,20 +2228,20 @@ int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); return -EINVAL; } - psAdapter->psFlashCSInfo = (struct bcm_flash_cs_info *)kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL); + psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL); if (psAdapter->psFlashCSInfo == NULL) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); return -ENOMEM; } - psAdapter->psFlash2xCSInfo = (struct bcm_flash2x_cs_info *)kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL); + psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL); if (!psAdapter->psFlash2xCSInfo) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); return -ENOMEM; } - psAdapter->psFlash2xVendorInfo = (struct bcm_flash2x_vendor_info *)kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL); + psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL); if (!psAdapter->psFlash2xVendorInfo) { BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); kfree(psAdapter->psFlashCSInfo); @@ -4074,7 +4074,7 @@ int BcmCopySection(struct bcm_mini_adapter *Adapter, else BuffSize = numOfBytes; - pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL); + pBuff = kzalloc(BuffSize, GFP_KERNEL); if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); return -ENOMEM; @@ -4154,7 +4154,7 @@ int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned } /* If Header is present overwrite passed buffer with this */ if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { - pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL); + pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL); if (!pTempBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); return -ENOMEM; @@ -4563,7 +4563,7 @@ static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sect } } - pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); + pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; @@ -4622,7 +4622,7 @@ static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_sect return SECTOR_IS_NOT_WRITABLE; } - pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL); + pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); if (!pBuff) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); return -ENOMEM; -- cgit From 6d8a94e67f0448f11279eee27d3b0ede06ba07d7 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 17 Feb 2013 11:53:15 +0800 Subject: staging: sep: using strlcpy instead of strncpy set '\0' at tail for NUL terminated string, or TP_printk may cause issue. Signed-off-by: Chen Gang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_trace_events.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_trace_events.h b/drivers/staging/sep/sep_trace_events.h index 2b053a93afe6..74f4c9a2b5be 100644 --- a/drivers/staging/sep/sep_trace_events.h +++ b/drivers/staging/sep/sep_trace_events.h @@ -52,6 +52,11 @@ */ #include +/* + * Since use str*cpy in header file, better to include string.h, directly. + */ +#include + /* * The TRACE_EVENT macro is broken up into 5 parts. * @@ -97,7 +102,7 @@ TRACE_EVENT(sep_func_start, ), TP_fast_assign( - strncpy(__entry->name, name, 20); + strlcpy(__entry->name, name, 20); __entry->branch = branch; ), @@ -116,7 +121,7 @@ TRACE_EVENT(sep_func_end, ), TP_fast_assign( - strncpy(__entry->name, name, 20); + strlcpy(__entry->name, name, 20); __entry->branch = branch; ), @@ -135,7 +140,7 @@ TRACE_EVENT(sep_misc_event, ), TP_fast_assign( - strncpy(__entry->name, name, 20); + strlcpy(__entry->name, name, 20); __entry->branch = branch; ), -- cgit From 6c259f4f9346fb6a2ad0c98764ea6b4a5ea08f24 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 20 Feb 2013 23:25:27 -0500 Subject: Staging: bcm: Fix all white space issues in PHSModule.c This patch fixes all white space issues in PHSModule.c as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 1184 +++++++++++++++++++-------------------- 1 file changed, 588 insertions(+), 596 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 7028bc95b4f9..3fecbc88111c 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -1,118 +1,107 @@ #include "headers.h" -static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId, struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); +static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); -static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId, struct bcm_phs_entry *pstServiceFlowEntry, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); +static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_entry *pstServiceFlowEntry, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); -static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, enum bcm_phs_classifier_context eClsContext,B_UINT8 u8AssociatedPHSI); +static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, enum bcm_phs_classifier_context eClsContext, B_UINT8 u8AssociatedPHSI); -static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); +static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI); static BOOLEAN ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule); -static BOOLEAN DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule); +static BOOLEAN DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule); -static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable,B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry); +static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry); -static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable,B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_rule **ppstPhsRule); +static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_rule **ppstPhsRule); static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable); static int phs_compress(struct bcm_phs_rule *phs_members, unsigned char *in_buf, - unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size ); + unsigned char *out_buf, unsigned int *header_size, UINT *new_header_size); +static int verify_suppress_phsf(unsigned char *in_buffer, unsigned char *out_buffer, + unsigned char *phsf, unsigned char *phsm, unsigned int phss, unsigned int phsv, UINT *new_header_size); -static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, - unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size ); - -static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\ - struct bcm_phs_rule *phs_rules, UINT *header_size); - - -static ULONG PhsCompress(void* pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pOldHeaderSize, - UINT *pNewHeaderSize ); - -static ULONG PhsDeCompress(void* pvContext, - B_UINT16 uiVcid, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pInHeaderSize, - UINT *pOutHeaderSize); +static int phs_decompress(unsigned char *in_buf, unsigned char *out_buf, + struct bcm_phs_rule *phs_rules, UINT *header_size); +static ULONG PhsCompress(void *pvContext, + B_UINT16 uiVcid, + B_UINT16 uiClsId, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pOldHeaderSize, + UINT *pNewHeaderSize); +static ULONG PhsDeCompress(void *pvContext, + B_UINT16 uiVcid, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pInHeaderSize, + UINT *pOutHeaderSize); #define IN #define OUT /* -Function: PHSTransmit - -Description: This routine handle PHS(Payload Header Suppression for Tx path. - It extracts a fragment of the NDIS_PACKET containing the header - to be suppressed. It then suppresses the header by invoking PHS exported compress routine. - The header data after suppression is copied back to the NDIS_PACKET. - +Function: PHSTransmit +Description: This routine handle PHS(Payload Header Suppression for Tx path. + It extracts a fragment of the NDIS_PACKET containing the header + to be suppressed. It then suppresses the header by invoking PHS exported compress routine. + The header data after suppression is copied back to the NDIS_PACKET. Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - IN Packet - NDIS packet containing data to be transmitted - IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to - identify PHS rule to be applied. - B_UINT16 uiClassifierRuleID - Classifier Rule ID - BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. - -Return: STATUS_SUCCESS - If the send was successful. - Other - If an error occurred. + IN Packet - NDIS packet containing data to be transmitted + IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to + identify PHS rule to be applied. + B_UINT16 uiClassifierRuleID - Classifier Rule ID + BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. + +Return: STATUS_SUCCESS - If the send was successful. + Other - If an error occurred. */ int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - BOOLEAN bHeaderSuppressionEnabled, - UINT *PacketLen, - UCHAR bEthCSSupport) + struct sk_buff **pPacket, + USHORT Vcid, + B_UINT16 uiClassifierRuleID, + BOOLEAN bHeaderSuppressionEnabled, + UINT *PacketLen, + UCHAR bEthCSSupport) { - //PHS Sepcific - UINT unPHSPktHdrBytesCopied = 0; - UINT unPhsOldHdrSize = 0; - UINT unPHSNewPktHeaderLen = 0; + UINT unPHSPktHdrBytesCopied = 0; + UINT unPhsOldHdrSize = 0; + UINT unPHSNewPktHeaderLen = 0; /* Pointer to PHS IN Hdr Buffer */ - PUCHAR pucPHSPktHdrInBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; + PUCHAR pucPHSPktHdrInBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; /* Pointer to PHS OUT Hdr Buffer */ - PUCHAR pucPHSPktHdrOutBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; - UINT usPacketType; - UINT BytesToRemove=0; - BOOLEAN bPHSI = 0; + PUCHAR pucPHSPktHdrOutBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; + UINT usPacketType; + UINT BytesToRemove = 0; + BOOLEAN bPHSI = 0; LONG ulPhsStatus = 0; - UINT numBytesCompressed = 0; + UINT numBytesCompressed = 0; struct sk_buff *newPacket = NULL; struct sk_buff *Packet = *pPacket; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit"); - if(!bEthCSSupport) - BytesToRemove=ETH_HLEN; + if (!bEthCSSupport) + BytesToRemove = ETH_HLEN; /* - Accumulate the header upto the size we support suppression - from NDIS packet + Accumulate the header upto the size we support suppression + from NDIS packet */ - usPacketType=((struct ethhdr *)(Packet->data))->h_proto; - + usPacketType = ((struct ethhdr *)(Packet->data))->h_proto; pucPHSPktHdrInBuf = Packet->data + BytesToRemove; //considering data after ethernet header - if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) + if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) { - unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); } else @@ -120,85 +109,81 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; } - if( (unPHSPktHdrBytesCopied > 0 ) && + if ((unPHSPktHdrBytesCopied > 0) && (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { - - // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. - // Suppress only if IP Header and PHS Enabled For the Service Flow - if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) || - (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && + // Suppress only if IP Header and PHS Enabled For the Service Flow + if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || + (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && (bHeaderSuppressionEnabled)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nTrying to PHS Compress Using Classifier rule 0x%X", uiClassifierRuleID); + unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; + ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, + Vcid, + uiClassifierRuleID, + pucPHSPktHdrInBuf, + pucPHSPktHdrOutBuf, + &unPhsOldHdrSize, + &unPHSNewPktHeaderLen); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nPHS Old header Size : %d New Header Size %d\n", unPhsOldHdrSize, unPHSNewPktHeaderLen); + + if (unPHSNewPktHeaderLen == unPhsOldHdrSize) + { + if (ulPhsStatus == STATUS_PHS_COMPRESSED) + bPHSI = *pucPHSPktHdrOutBuf; - unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; - ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, - Vcid, - uiClassifierRuleID, - pucPHSPktHdrInBuf, - pucPHSPktHdrOutBuf, - &unPhsOldHdrSize, - &unPHSNewPktHeaderLen); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen); + ulPhsStatus = STATUS_PHS_NOCOMPRESSION; + } - if(unPHSNewPktHeaderLen == unPhsOldHdrSize) - { - if( ulPhsStatus == STATUS_PHS_COMPRESSED) - bPHSI = *pucPHSPktHdrOutBuf; - ulPhsStatus = STATUS_PHS_NOCOMPRESSION; - } + if (ulPhsStatus == STATUS_PHS_COMPRESSED) + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "PHS Sending packet Compressed"); - if( ulPhsStatus == STATUS_PHS_COMPRESSED) + if (skb_cloned(Packet)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed"); - - if(skb_cloned(Packet)) - { - newPacket = skb_copy(Packet, GFP_ATOMIC); + newPacket = skb_copy(Packet, GFP_ATOMIC); - if(newPacket == NULL) - return STATUS_FAILURE; + if (newPacket == NULL) + return STATUS_FAILURE; - dev_kfree_skb(Packet); - *pPacket = Packet = newPacket; - pucPHSPktHdrInBuf = Packet->data + BytesToRemove; - } + dev_kfree_skb(Packet); + *pPacket = Packet = newPacket; + pucPHSPktHdrInBuf = Packet->data + BytesToRemove; + } - numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN); + numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen + PHSI_LEN); - memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); - memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); - skb_pull(Packet, numBytesCompressed); + memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); + memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); + skb_pull(Packet, numBytesCompressed); - return STATUS_SUCCESS; - } - - else + return STATUS_SUCCESS; + } + else + { + //if one byte headroom is not available, increase it through skb_cow + if (!(skb_headroom(Packet) > 0)) { - //if one byte headroom is not available, increase it through skb_cow - if(!(skb_headroom(Packet) > 0)) + if (skb_cow(Packet, 1)) { - if(skb_cow(Packet, 1)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n"); - return STATUS_FAILURE; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n"); + return STATUS_FAILURE; } - skb_push(Packet, 1); + } + skb_push(Packet, 1); - // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it. - *(Packet->data + BytesToRemove) = bPHSI; - return STATUS_SUCCESS; + // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it. + *(Packet->data + BytesToRemove) = bPHSI; + return STATUS_SUCCESS; } } else { - if(!bHeaderSuppressionEnabled) + if (!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nHeader Suppression Disabled For SF: No PHS\n"); } return STATUS_SUCCESS; @@ -210,20 +195,21 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, } int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT bHeaderSuppressionEnabled) + USHORT usVcid, + struct sk_buff *packet, + UINT *punPacketLen, + UCHAR *pucEthernetHdr, + UINT bHeaderSuppressionEnabled) { - u32 nStandardPktHdrLen = 0; - u32 nTotalsuppressedPktHdrBytes = 0; - int ulPhsStatus = 0; - PUCHAR pucInBuff = NULL ; + u32 nStandardPktHdrLen = 0; + u32 nTotalsuppressedPktHdrBytes = 0; + int ulPhsStatus = 0; + PUCHAR pucInBuff = NULL; UINT TotalBytesAdded = 0; - if(!bHeaderSuppressionEnabled) + + if (!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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; } @@ -232,16 +218,16 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, //Restore PHS suppressed header nStandardPktHdrLen = packet->len; ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, - usVcid, - pucInBuff, - Adapter->ucaPHSPktRestoreBuf, - &nTotalsuppressedPktHdrBytes, - &nStandardPktHdrLen); + usVcid, + pucInBuff, + Adapter->ucaPHSPktRestoreBuf, + &nTotalsuppressedPktHdrBytes, + &nStandardPktHdrLen); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", - nTotalsuppressedPktHdrBytes,nStandardPktHdrLen); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", + nTotalsuppressedPktHdrBytes, nStandardPktHdrLen); - if(ulPhsStatus != STATUS_PHS_COMPRESSED) + if (ulPhsStatus != STATUS_PHS_COMPRESSED) { skb_pull(packet, 1); return STATUS_SUCCESS; @@ -249,15 +235,15 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, else { TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN; - if(TotalBytesAdded) + if (TotalBytesAdded) { - if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) + if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) skb_push(packet, TotalBytesAdded); else { - if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) + if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n"); return STATUS_FAILURE; } @@ -271,11 +257,12 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) +void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet"); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dumping Data Packet"); + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, pBuf, nPktLen); } //----------------------------------------------------------------------------- @@ -295,65 +282,60 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap { int i; struct bcm_phs_table *pstServiceFlowTable; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function "); - if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function"); + + if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable) return -EINVAL; - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = - kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); + pPhsdeviceExtension->pstServiceFlowPhsRulesTable = kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); - if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) + if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); return -ENOMEM; } pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; - for(i=0;istSFList[i]; sServiceFlow.pstClassifierTable = kzalloc(sizeof(struct bcm_phs_classifier_table), GFP_KERNEL); - if(!sServiceFlow.pstClassifierTable) + if (!sServiceFlow.pstClassifierTable) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension-> - pstServiceFlowPhsRulesTable); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; return -ENOMEM; } } pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - - if(pPhsdeviceExtension->CompressedTxBuffer == NULL) + if (pPhsdeviceExtension->CompressedTxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; return -ENOMEM; } - pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL) + pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); + if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); kfree(pPhsdeviceExtension->CompressedTxBuffer); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; return -ENOMEM; } - - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful"); return STATUS_SUCCESS; } - int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) { - if(pPHSDeviceExt->pstServiceFlowPhsRulesTable) + if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) { free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; @@ -368,8 +350,6 @@ int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) return 0; } - - //PHS functions /*++ PhsUpdateClassifierRule @@ -389,53 +369,48 @@ Return Value: >0 Error. --*/ -ULONG PhsUpdateClassifierRule(IN void* pvContext, - IN B_UINT16 uiVcid , - IN B_UINT16 uiClsId , - IN struct bcm_phs_rule *psPhsRule, - IN B_UINT8 u8AssociatedPHSI) +ULONG PhsUpdateClassifierRule(IN void *pvContext, + IN B_UINT16 uiVcid , + IN B_UINT16 uiClsId , + IN struct bcm_phs_rule *psPhsRule, + IN B_UINT8 u8AssociatedPHSI) { - ULONG lStatus =0; - UINT nSFIndex =0 ; + ULONG lStatus = 0; + UINT nSFIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS With Corr2 Changes\n"); - - struct bcm_phs_extension *pDeviceExtension= (struct bcm_phs_extension *)pvContext; - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n"); - - if(pDeviceExtension == NULL) + if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } - - if(u8AssociatedPHSI == 0) + if (u8AssociatedPHSI == 0) { return ERR_PHS_INVALID_PHS_RULE; } /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid,&pstServiceFlowEntry); + uiVcid, &pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { /* This is a new SF. Create a mapping entry for this */ lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, - pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); + pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); return lStatus; } /* SF already Exists Add PHS Rule to existing SF */ - lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, - pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); + lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, + pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI); - return lStatus; + return lStatus; } /*++ @@ -456,51 +431,49 @@ Return Value: --*/ -ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) +ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI) { - ULONG lStatus =0; - UINT nSFIndex =0, nClsidIndex =0 ; + ULONG lStatus = 0; + UINT nSFIndex = 0, nClsidIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); - struct bcm_phs_extension *pDeviceExtension= (struct bcm_phs_extension *)pvContext; - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); - - if(pDeviceExtension) + if (pDeviceExtension) { - //Retrieve the SFID Entry Index for requested Service Flow - nSFIndex = GetServiceFlowEntry(pDeviceExtension - ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry); + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } - pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; - if(pstClassifierRulesTable) + pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; + if (pstClassifierRulesTable) { - for(nClsidIndex=0;nClsidIndexstActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { - if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { - if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) + { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; - if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + + if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); + memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry)); } } } } - } return lStatus; } @@ -522,45 +495,44 @@ Return Value: >0 Error. --*/ -ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId) +ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId) { - ULONG lStatus =0; - UINT nSFIndex =0, nClsidIndex =0 ; + ULONG lStatus = 0; + UINT nSFIndex = 0, nClsidIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension= (struct bcm_phs_extension *)pvContext; + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - if(pDeviceExtension) + if (pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow - nSFIndex = GetServiceFlowEntry(pDeviceExtension - ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); - if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) + uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); + if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { - if(pstClassifierEntry->pstPhsRule) + if (pstClassifierEntry->pstPhsRule) { - if(pstClassifierEntry->pstPhsRule->u8RefCnt) - pstClassifierEntry->pstPhsRule->u8RefCnt--; - if(0==pstClassifierEntry->pstPhsRule->u8RefCnt) - kfree(pstClassifierEntry->pstPhsRule); + if (pstClassifierEntry->pstPhsRule->u8RefCnt) + pstClassifierEntry->pstPhsRule->u8RefCnt--; + if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt) + kfree(pstClassifierEntry->pstPhsRule); } memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry)); } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId,eOldClassifierRuleContext,&pstClassifierEntry); + uiClsId, eOldClassifierRuleContext, &pstClassifierEntry); - if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) + if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { kfree(pstClassifierEntry->pstPhsRule); memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry)); @@ -585,71 +557,64 @@ Return Value: >0 Error. --*/ -ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) +ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) { - - ULONG lStatus =0; - UINT nSFIndex =0, nClsidIndex =0 ; + ULONG lStatus = 0; + UINT nSFIndex = 0, nClsidIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension= (struct bcm_phs_extension *)pvContext; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n"); + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n"); - if(pDeviceExtension) + if (pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid,&pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + uiVcid, &pstServiceFlowEntry); + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } - pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable; - if(pstClassifierRulesTable) + pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; + if (pstClassifierRulesTable) { - for(nClsidIndex=0;nClsidIndexstActivePhsRulesList[nClsidIndex].pstPhsRule) + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { - if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt) - pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt--; - if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt) + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; + + if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); - pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule = NULL; + + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule = NULL; } memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry)); - if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) + if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) { - if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt) - pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt--; - if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt) - kfree(pstClassifierRulesTable - ->stOldPhsRulesList[nClsidIndex].pstPhsRule); - pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] - .pstPhsRule = NULL; + if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; + + if (0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + kfree(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule); + + pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule = NULL; } memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry)); } } pstServiceFlowEntry->bUsed = FALSE; pstServiceFlowEntry->uiVcid = 0; - } return lStatus; } - /*++ PhsCompress @@ -671,73 +636,65 @@ Return Value: >0 Error. --*/ -ULONG PhsCompress(IN void* pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pOldHeaderSize, - OUT UINT *pNewHeaderSize ) +ULONG PhsCompress(IN void *pvContext, + IN B_UINT16 uiVcid, + IN B_UINT16 uiClsId, + IN void *pvInputBuffer, + OUT void *pvOutputBuffer, + OUT UINT *pOldHeaderSize, + OUT UINT *pNewHeaderSize) { - UINT nSFIndex =0, nClsidIndex =0 ; + UINT nSFIndex = 0, nClsidIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; struct bcm_phs_rule *pstPhsRule = NULL; - ULONG lStatus =0; + ULONG lStatus = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - - - struct bcm_phs_extension *pDeviceExtension= (struct bcm_phs_extension *)pvContext; - - - if(pDeviceExtension == NULL) + if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n"); - lStatus = STATUS_PHS_NOCOMPRESSION ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Invalid Device Extension\n"); + lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n"); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Suppressing header\n"); //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid,&pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + uiVcid, &pstServiceFlowEntry); + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n"); - lStatus = STATUS_PHS_NOCOMPRESSION ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "SFID Match Failed\n"); + lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry); + uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); - if(nClsidIndex == PHS_INVALID_TABLE_INDEX) + if (nClsidIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n"); - lStatus = STATUS_PHS_NOCOMPRESSION ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "No PHS Rule Defined For Classifier\n"); + lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; } - //get rule from SF id,Cls ID pair and proceed - pstPhsRule = pstClassifierEntry->pstPhsRule; - - if(!ValidatePHSRuleComplete(pstPhsRule)) + pstPhsRule = pstClassifierEntry->pstPhsRule; + if (!ValidatePHSRuleComplete(pstPhsRule)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n"); - lStatus = STATUS_PHS_NOCOMPRESSION ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n"); + lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; } //Compress Packet - lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize); + lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer, + (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize); - if(lStatus == STATUS_PHS_COMPRESSED) + if (lStatus == STATUS_PHS_COMPRESSED) { pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1; pstPhsRule->PHSModifiedNumPackets++; @@ -767,63 +724,60 @@ Return Value: >0 Error. --*/ -ULONG PhsDeCompress(IN void* pvContext, - IN B_UINT16 uiVcid, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pInHeaderSize, - OUT UINT *pOutHeaderSize ) +ULONG PhsDeCompress(IN void *pvContext, + IN B_UINT16 uiVcid, + IN void *pvInputBuffer, + OUT void *pvOutputBuffer, + OUT UINT *pInHeaderSize, + OUT UINT *pOutHeaderSize) { - UINT nSFIndex =0, nPhsRuleIndex =0 ; + UINT nSFIndex = 0, nPhsRuleIndex = 0; struct bcm_phs_entry *pstServiceFlowEntry = NULL; struct bcm_phs_rule *pstPhsRule = NULL; UINT phsi; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension= - (struct bcm_phs_extension *)pvContext; + struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; *pInHeaderSize = 0; - - if(pDeviceExtension == NULL) + if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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_RECEIVE,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_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi); - if(phsi == UNCOMPRESSED_PACKET ) + 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; } //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid,&pstServiceFlowEntry); - if(nSFIndex == PHS_INVALID_TABLE_INDEX) + uiVcid, &pstServiceFlowEntry); + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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; } - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi, - eActiveClassifierRuleContext,&pstPhsRule); - if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) + nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi, + eActiveClassifierRuleContext, &pstPhsRule); + if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { //Phs Rule does not exist in active rules table. Lets try in the old rules table. nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi,eOldClassifierRuleContext,&pstPhsRule); - if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) + phsi, eOldClassifierRuleContext, &pstPhsRule); + if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { return ERR_PHSRULE_MATCH_FAIL; } - } *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize); + (PUCHAR)pvOutputBuffer, pstPhsRule, pOutHeaderSize); pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; @@ -831,7 +785,6 @@ ULONG PhsDeCompress(IN void* pvContext, return STATUS_PHS_COMPRESSED; } - //----------------------------------------------------------------------------- // Procedure: free_phs_serviceflow_rules // @@ -846,79 +799,76 @@ ULONG PhsDeCompress(IN void* pvContext, static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable) { - int i,j; + int i, j; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); - if(psServiceFlowRulesTable) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); + + if (psServiceFlowRulesTable) { - for(i=0;istSFList[i]; - struct bcm_phs_classifier_table *pstClassifierRulesTable = - stServiceFlowEntry.pstClassifierTable; + struct bcm_phs_entry stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i]; + struct bcm_phs_classifier_table *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable; - if(pstClassifierRulesTable) + if (pstClassifierRulesTable) { - for(j=0;jstActivePhsRulesList[j].pstPhsRule) + if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) { - if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule - ->u8RefCnt) - pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule - ->u8RefCnt--; - if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule - ->u8RefCnt) + if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt--; + + if (0 == pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule); + pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; } - if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) + + if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) { - if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule - ->u8RefCnt) - pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule - ->u8RefCnt--; - if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule - ->u8RefCnt) + if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt--; + + if (0 == pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt) kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule); + pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL; } } kfree(pstClassifierRulesTable); - stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; + stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; } } } - kfree(psServiceFlowRulesTable); - psServiceFlowRulesTable = NULL; + kfree(psServiceFlowRulesTable); + psServiceFlowRulesTable = NULL; } - - static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule) { - if(psPhsRule) + if (psPhsRule) { - if(!psPhsRule->u8PHSI) + if (!psPhsRule->u8PHSI) { // PHSI is not valid return FALSE; } - if(!psPhsRule->u8PHSS) + if (!psPhsRule->u8PHSS) { //PHSS Is Undefined return FALSE; } //Check if PHSF is defines for the PHS Rule - if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF + if (!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF { return FALSE; } + return TRUE; } else @@ -928,14 +878,16 @@ static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule) } UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, - IN B_UINT16 uiVcid, struct bcm_phs_entry **ppstServiceFlowEntry) + IN B_UINT16 uiVcid, + struct bcm_phs_entry **ppstServiceFlowEntry) { - int i; - for(i=0;istSFList[i].bUsed) + if (psServiceFlowTable->stSFList[i].bUsed) { - if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid) + if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid) { *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i]; return i; @@ -947,17 +899,16 @@ UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, return PHS_INVALID_TABLE_INDEX; } - UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_classifier_entry **ppstClassifierEntry) + IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, + OUT struct bcm_phs_classifier_entry **ppstClassifierEntry) { int i; struct bcm_phs_classifier_entry *psClassifierRules = NULL; - for(i=0;istActivePhsRulesList[i]; } @@ -966,15 +917,14 @@ UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i]; } - if(psClassifierRules->bUsed) + if (psClassifierRules->bUsed) { - if(psClassifierRules->uiClassifierRuleId == uiClsid) + if (psClassifierRules->uiClassifierRuleId == uiClsid) { *ppstClassifierEntry = psClassifierRules; return i; } } - } *ppstClassifierEntry = NULL; @@ -982,14 +932,15 @@ UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, } static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_rule **ppstPhsRule) + IN B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, + OUT struct bcm_phs_rule **ppstPhsRule) { int i; struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - for(i=0;istActivePhsRulesList[i]; } @@ -997,48 +948,48 @@ static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTab { pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i]; } - if(pstClassifierRule->bUsed) + + if (pstClassifierRule->bUsed) { - if(pstClassifierRule->u8PHSI == uiPHSI) + if (pstClassifierRule->u8PHSI == uiPHSI) { *ppstPhsRule = pstClassifierRule->pstPhsRule; return i; } } - } *ppstPhsRule = NULL; return PHS_INVALID_TABLE_INDEX; } -UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId, - IN struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) +UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, + IN struct bcm_phs_table *psServiceFlowTable, + struct bcm_phs_rule *psPhsRule, + B_UINT8 u8AssociatedPHSI) { - struct bcm_phs_classifier_table *psaClassifiertable = NULL; UINT uiStatus = 0; int iSfIndex; - BOOLEAN bFreeEntryFound =FALSE; + BOOLEAN bFreeEntryFound = FALSE; + //Check for a free entry in SFID table - for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++) + for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { - if(!psServiceFlowTable->stSFList[iSfIndex].bUsed) + if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) { bFreeEntryFound = TRUE; break; } } - if(!bFreeEntryFound) + if (!bFreeEntryFound) return ERR_SFTABLE_FULL; - psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable; - uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule, - eActiveClassifierRuleContext,u8AssociatedPHSI); - if(uiStatus == PHS_SUCCESS) + uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule, + eActiveClassifierRuleContext, u8AssociatedPHSI); + if (uiStatus == PHS_SUCCESS) { //Add entry at free index to the SF psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE; @@ -1046,77 +997,88 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId, } return uiStatus; - } UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId,IN struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI) + IN B_UINT16 uiClsId, + IN struct bcm_phs_entry *pstServiceFlowEntry, + struct bcm_phs_rule *psPhsRule, + B_UINT8 u8AssociatedPHSI) { struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - UINT uiStatus =PHS_SUCCESS; + UINT uiStatus = PHS_SUCCESS; UINT nClassifierIndex = 0; struct bcm_phs_classifier_table *psaClassifiertable = NULL; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>"); + psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>"); /* Check if the supplied Classifier already exists */ - nClassifierIndex =GetClassifierEntry( - pstServiceFlowEntry->pstClassifierTable,uiClsId, - eActiveClassifierRuleContext,&pstClassifierEntry); - if(nClassifierIndex == PHS_INVALID_TABLE_INDEX) + nClassifierIndex = GetClassifierEntry( + pstServiceFlowEntry->pstClassifierTable, + uiClsId, + eActiveClassifierRuleContext, + &pstClassifierEntry); + + if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { /* - The Classifier doesn't exist. So its a new classifier being added. - Add new entry to associate PHS Rule to the Classifier + The Classifier doesn't exist. So its a new classifier being added. + Add new entry to associate PHS Rule to the Classifier */ - uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable, - psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI); + uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, + psPhsRule, + eActiveClassifierRuleContext, + u8AssociatedPHSI); return uiStatus; } /* The Classifier exists.The PHS Rule for this classifier is being modified - */ - if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) + */ + + if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { - if(pstClassifierEntry->pstPhsRule == NULL) + if (pstClassifierEntry->pstPhsRule == NULL) return ERR_PHS_INVALID_PHS_RULE; /* - This rule already exists if any fields are changed for this PHS - rule update them. - */ - /* If any part of PHSF is valid then we update PHSF */ - if(psPhsRule->u8PHSFLength) + This rule already exists if any fields are changed for this PHS + rule update them. + */ + /* If any part of PHSF is valid then we update PHSF */ + if (psPhsRule->u8PHSFLength) { //update PHSF memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, - psPhsRule->u8PHSF , MAX_PHS_LENGTHS); + psPhsRule->u8PHSF, MAX_PHS_LENGTHS); } - if(psPhsRule->u8PHSFLength) + + if (psPhsRule->u8PHSFLength) { //update PHSFLen - pstClassifierEntry->pstPhsRule->u8PHSFLength = - psPhsRule->u8PHSFLength; + pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength; } - if(psPhsRule->u8PHSMLength) + + if (psPhsRule->u8PHSMLength) { //update PHSM memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, - psPhsRule->u8PHSM, MAX_PHS_LENGTHS); + psPhsRule->u8PHSM, MAX_PHS_LENGTHS); } - if(psPhsRule->u8PHSMLength) + + if (psPhsRule->u8PHSMLength) { //update PHSM Len pstClassifierEntry->pstPhsRule->u8PHSMLength = - psPhsRule->u8PHSMLength; + psPhsRule->u8PHSMLength; } - if(psPhsRule->u8PHSS) + + if (psPhsRule->u8PHSS) { //update PHSS pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS; @@ -1124,75 +1086,75 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, //update PHSV pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; - } else { /* A new rule is being set for this classifier. */ - uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry, - psaClassifiertable, psPhsRule, u8AssociatedPHSI); + uiStatus = UpdateClassifierPHSRule(uiClsId, pstClassifierEntry, + psaClassifiertable, psPhsRule, u8AssociatedPHSI); } - - return uiStatus; } static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext,B_UINT8 u8AssociatedPHSI) + struct bcm_phs_classifier_table *psaClassifiertable, + struct bcm_phs_rule *psPhsRule, + enum bcm_phs_classifier_context eClsContext, + B_UINT8 u8AssociatedPHSI) { UINT iClassifierIndex = 0; BOOLEAN bFreeEntryFound = FALSE; struct bcm_phs_classifier_entry *psClassifierRules = NULL; UINT nStatus = PHS_SUCCESS; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule"); - if(psaClassifiertable == NULL) + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Inside CreateClassifierPHSRule"); + + if (psaClassifiertable == NULL) { return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; } - if(eClsContext == eOldClassifierRuleContext) + if (eClsContext == eOldClassifierRuleContext) { /* If An Old Entry for this classifier ID already exists in the - old rules table replace it. */ + old rules table replace it. */ iClassifierIndex = - GetClassifierEntry(psaClassifiertable, uiClsId, - eClsContext,&psClassifierRules); - if(iClassifierIndex != PHS_INVALID_TABLE_INDEX) + GetClassifierEntry(psaClassifiertable, uiClsId, + eClsContext, &psClassifierRules); + + if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { /* - The Classifier already exists in the old rules table - Lets replace the old classifier with the new one. + The Classifier already exists in the old rules table + Lets replace the old classifier with the new one. */ bFreeEntryFound = TRUE; } } - if(!bFreeEntryFound) + if (!bFreeEntryFound) { /* Continue to search for a free location to add the rule */ - for(iClassifierIndex = 0; iClassifierIndex < - MAX_PHSRULE_PER_SF; iClassifierIndex++) + for (iClassifierIndex = 0; iClassifierIndex < + MAX_PHSRULE_PER_SF; iClassifierIndex++) { - if(eClsContext == eActiveClassifierRuleContext) + if (eClsContext == eActiveClassifierRuleContext) { - psClassifierRules = - &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; + psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; } else { - psClassifierRules = - &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; } - if(!psClassifierRules->bUsed) + if (!psClassifierRules->bUsed) { bFreeEntryFound = TRUE; break; @@ -1200,36 +1162,34 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, } } - if(!bFreeEntryFound) + if (!bFreeEntryFound) { - if(eClsContext == eActiveClassifierRuleContext) + if (eClsContext == eActiveClassifierRuleContext) { return ERR_CLSASSIFIER_TABLE_FULL; } else { //Lets replace the oldest rule if we are looking in old Rule table - if(psaClassifiertable->uiOldestPhsRuleIndex >= - MAX_PHSRULE_PER_SF) + if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) { - psaClassifiertable->uiOldestPhsRuleIndex =0; + psaClassifiertable->uiOldestPhsRuleIndex = 0; } iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; - psClassifierRules = - &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - (psaClassifiertable->uiOldestPhsRuleIndex)++; + (psaClassifiertable->uiOldestPhsRuleIndex)++; } } - if(eClsContext == eOldClassifierRuleContext) + if (eClsContext == eOldClassifierRuleContext) { - if(psClassifierRules->pstPhsRule == NULL) + if (psClassifierRules->pstPhsRule == NULL) { - psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule),GFP_KERNEL); + psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL); - if(NULL == psClassifierRules->pstPhsRule) + if (NULL == psClassifierRules->pstPhsRule) return ERR_PHSRULE_MEMALLOC_FAIL; } @@ -1238,70 +1198,71 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, psClassifierRules->u8PHSI = psPhsRule->u8PHSI; psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule; - /* Update The PHS rule */ - memcpy(psClassifierRules->pstPhsRule, - psPhsRule, sizeof(struct bcm_phs_rule)); + /* Update The PHS rule */ + memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule)); } else { - nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules, - psaClassifiertable,psPhsRule,u8AssociatedPHSI); + nStatus = UpdateClassifierPHSRule(uiClsId, psClassifierRules, + psaClassifiertable, psPhsRule, u8AssociatedPHSI); } + return nStatus; } - static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, - IN struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) + IN struct bcm_phs_classifier_entry *pstClassifierEntry, + struct bcm_phs_classifier_table *psaClassifiertable, + struct bcm_phs_rule *psPhsRule, + B_UINT8 u8AssociatedPHSI) { struct bcm_phs_rule *pstAddPhsRule = NULL; - UINT nPhsRuleIndex = 0; - BOOLEAN bPHSRuleOrphaned = FALSE; + UINT nPhsRuleIndex = 0; + BOOLEAN bPHSRuleOrphaned = FALSE; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - psPhsRule->u8RefCnt =0; + + psPhsRule->u8RefCnt = 0; /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ - bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable, - pstClassifierEntry->pstPhsRule); + bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable, + pstClassifierEntry->pstPhsRule); //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF - nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI, - eActiveClassifierRuleContext, &pstAddPhsRule); - if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) + nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, + eActiveClassifierRuleContext, &pstAddPhsRule); + if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); - if(psPhsRule->u8PHSI == 0) + if (psPhsRule->u8PHSI == 0) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); return ERR_PHS_INVALID_PHS_RULE; } + //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId - if(FALSE == bPHSRuleOrphaned) + if (FALSE == bPHSRuleOrphaned) { pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL); - if(NULL == pstClassifierEntry->pstPhsRule) + if (NULL == pstClassifierEntry->pstPhsRule) { return ERR_PHSRULE_MEMALLOC_FAIL; } } memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule)); - } else { //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); - if(bPHSRuleOrphaned) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); + if (bPHSRuleOrphaned) { kfree(pstClassifierEntry->pstPhsRule); pstClassifierEntry->pstPhsRule = NULL; } pstClassifierEntry->pstPhsRule = pstAddPhsRule; - } + pstClassifierEntry->bUsed = TRUE; pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; pstClassifierEntry->uiClassifierRuleId = uiClsId; @@ -1309,16 +1270,17 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; return PHS_SUCCESS; - } static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule) { - if(pstPhsRule==NULL) + if (pstPhsRule == NULL) return FALSE; - if(pstPhsRule->u8RefCnt) + + if (pstPhsRule->u8RefCnt) pstPhsRule->u8RefCnt--; - if(0==pstPhsRule->u8RefCnt) + + if (0 == pstPhsRule->u8RefCnt) { /*if(pstPhsRule->u8PHSI) //Store the currently active rule into the old rules list @@ -1333,55 +1295,59 @@ static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_tabl void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) { - int i,j,k,l; + int i, j, k, l; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n"); - for(i=0;ipstServiceFlowPhsRulesTable->stSFList[i]; - if(stServFlowEntry.bUsed) + pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; + if (stServFlowEntry.bUsed) { - for(j=0;jstActivePhsRulesList[j]; - if(stClsEntry.bUsed) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n"); + if (stClsEntry.bUsed) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule :\n"); } else { stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j]; - if(stClsEntry.bUsed) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n"); + if (stClsEntry.bUsed) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule :\n"); } - if(stClsEntry.bUsed) + if (stClsEntry.bUsed) { - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); - for(k=0;ku8PHSFLength;k++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", stServFlowEntry.uiVcid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", stClsEntry.uiClassifierRuleId); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", stClsEntry.u8PHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", stClsEntry.pstPhsRule->u8PHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", stClsEntry.pstPhsRule->u8PHSFLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); + + for (k = 0 ; k < stClsEntry.pstPhsRule->u8PHSFLength; k++) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSF[k]); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); - for(k=0;ku8PHSMLength;k++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", stClsEntry.pstPhsRule->u8PHSMLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); + + for (k = 0; k < stClsEntry.pstPhsRule->u8PHSMLength; k++) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSM[k]); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", stClsEntry.pstPhsRule->u8PHSS); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", stClsEntry.pstPhsRule->u8PHSV); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); } } } @@ -1389,7 +1355,6 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) } } - //----------------------------------------------------------------------------- // Procedure: phs_decompress // @@ -1407,48 +1372,52 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) // 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed. //----------------------------------------------------------------------------- -int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, - struct bcm_phs_rule *decomp_phs_rules, UINT *header_size) +int phs_decompress(unsigned char *in_buf, + unsigned char *out_buf, + struct bcm_phs_rule *decomp_phs_rules, + UINT *header_size) { - int phss,size=0; + int phss, size = 0; struct bcm_phs_rule *tmp_memb; - int bit,i=0; - unsigned char *phsf,*phsm; - int in_buf_len = *header_size-1; + int bit, i = 0; + unsigned char *phsf, *phsm; + int in_buf_len = *header_size - 1; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); + in_buf++; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,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 )) + if ((decomp_phs_rules == NULL)) return 0; - tmp_memb = decomp_phs_rules; //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; - phsm = tmp_memb->u8PHSM; + phss = tmp_memb->u8PHSS; + phsf = tmp_memb->u8PHSF; + phsm = tmp_memb->u8PHSM; - if(phss > MAX_PHS_LENGTHS) + if (phss > MAX_PHS_LENGTHS) phss = MAX_PHS_LENGTHS; + //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)) + while ((phss > 0) && (size < in_buf_len)) { - bit = ((*phsm << i)& SUPPRESS); + bit = ((*phsm << i) & SUPPRESS); - if(bit == SUPPRESS) + if (bit == SUPPRESS) { *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", - phss,*phsf,*out_buf); + 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_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", - phss,*in_buf,*out_buf); + 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++; } @@ -1456,20 +1425,18 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, phsf++; phss--; i++; - *header_size=*header_size + 1; + *header_size = *header_size + 1; - if(i > MAX_NO_BIT) + if (i > MAX_NO_BIT) { - i=0; + i = 0; phsm++; } } + return size; } - - - //----------------------------------------------------------------------------- // Procedure: phs_compress // @@ -1490,21 +1457,24 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, // size-The number of bytes copied into the output buffer i.e dynamic fields // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. //----------------------------------------------------------------------------- -static int phs_compress(struct bcm_phs_rule *phs_rule, unsigned char *in_buf - ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) +static int phs_compress(struct bcm_phs_rule *phs_rule, + unsigned char *in_buf, + unsigned char *out_buf, + UINT *header_size, + UINT *new_header_size) { unsigned char *old_addr = out_buf; int suppress = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - if(phs_rule == NULL) + + if (phs_rule == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nphs_compress(): phs_rule null!"); *out_buf = ZERO_PHSI; return STATUS_PHS_NOCOMPRESSION; } - - if(phs_rule->u8PHSS <= *new_header_size) + if (phs_rule->u8PHSS <= *new_header_size) { *header_size = phs_rule->u8PHSS; } @@ -1512,25 +1482,27 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, unsigned char *in_buf { *header_size = *new_header_size; } + //To copy PHSI out_buf++; - suppress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF, - phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size); + suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF, + phs_rule->u8PHSM, phs_rule->u8PHSS, + phs_rule->u8PHSV, new_header_size); - if(suppress == STATUS_PHS_COMPRESSED) + if (suppress == STATUS_PHS_COMPRESSED) { *old_addr = (unsigned char)phs_rule->u8PHSI; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress phsi %d", phs_rule->u8PHSI); } else { *old_addr = ZERO_PHSI; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress PHSV Verification failed"); } + return suppress; } - //----------------------------------------------------------------------------- // Procedure: verify_suppress_phsf // @@ -1551,61 +1523,81 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, unsigned char *in_buf // 0 -Packet has failed the verification. //----------------------------------------------------------------------------- -static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, - unsigned char *phsf,unsigned char *phsm,unsigned int phss, - unsigned int phsv,UINT* new_header_size) +static int verify_suppress_phsf(unsigned char *in_buffer, + unsigned char *out_buffer, + unsigned char *phsf, + unsigned char *phsm, + unsigned int phss, + unsigned int phsv, + UINT *new_header_size) { - unsigned int size=0; - int bit,i=0; + unsigned int size = 0; + int bit, i = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm); - if(phss>(*new_header_size)) + if (phss > (*new_header_size)) { - phss=*new_header_size; + phss = *new_header_size; } - while(phss > 0) + + while (phss > 0) { - bit = ((*phsm << i)& SUPPRESS); - if(bit == SUPPRESS) + bit = ((*phsm << i) & SUPPRESS); + if (bit == SUPPRESS) { - - if(*in_buffer != *phsf) + if (*in_buffer != *phsf) { - if(phsv == VERIFY) + if (phsv == VERIFY) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf); + BCM_DEBUG_PRINT(Adapter, + DBG_TYPE_OTHERS, + PHS_SEND, + DBG_LVL_ALL, + "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d", + phss, + *in_buffer, + *phsf); return STATUS_PHS_NOCOMPRESSION; } } else - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf); + BCM_DEBUG_PRINT(Adapter, + DBG_TYPE_OTHERS, + PHS_SEND, + DBG_LVL_ALL, + "\nCOMP:In verify_phsf success for field %d buf %d phsf %d", + phss, + *in_buffer, + *phsf); } else { *out_buffer = *in_buffer; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer); + BCM_DEBUG_PRINT(Adapter, + DBG_TYPE_OTHERS, + PHS_SEND, + DBG_LVL_ALL, + "\nCOMP:In copying_header input %d out %d", + *in_buffer, + *out_buffer); out_buffer++; size++; } + in_buffer++; phsf++; phss--; i++; - if(i > MAX_NO_BIT) + + if (i > MAX_NO_BIT) { - i=0; + i = 0; phsm++; } } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf success"); *new_header_size = size; return STATUS_PHS_COMPRESSED; } - - - - - - -- cgit From 6949387e1a9073eefb431d902e324482b15ab15c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 20 Feb 2013 23:25:28 -0500 Subject: Staging: bcm: Properly format braces in PHSModule.c This patch formats braces in PHSModule.c as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 433 +++++++++++++--------------------------- 1 file changed, 140 insertions(+), 293 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 3fecbc88111c..17318003998d 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -101,23 +101,19 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, pucPHSPktHdrInBuf = Packet->data + BytesToRemove; //considering data after ethernet header if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) - { unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); - } else - { unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; - } if ((unPHSPktHdrBytesCopied > 0) && - (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) - { + (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { + // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. // Suppress only if IP Header and PHS Enabled For the Service Flow if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && - (bHeaderSuppressionEnabled)) - { + (bHeaderSuppressionEnabled)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nTrying to PHS Compress Using Classifier rule 0x%X", uiClassifierRuleID); unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, @@ -129,20 +125,19 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, &unPHSNewPktHeaderLen); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nPHS Old header Size : %d New Header Size %d\n", unPhsOldHdrSize, unPHSNewPktHeaderLen); - if (unPHSNewPktHeaderLen == unPhsOldHdrSize) - { + if (unPHSNewPktHeaderLen == unPhsOldHdrSize) { + if (ulPhsStatus == STATUS_PHS_COMPRESSED) bPHSI = *pucPHSPktHdrOutBuf; ulPhsStatus = STATUS_PHS_NOCOMPRESSION; } - if (ulPhsStatus == STATUS_PHS_COMPRESSED) - { + if (ulPhsStatus == STATUS_PHS_COMPRESSED) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "PHS Sending packet Compressed"); - if (skb_cloned(Packet)) - { + if (skb_cloned(Packet)) { newPacket = skb_copy(Packet, GFP_ATOMIC); if (newPacket == NULL) @@ -160,14 +155,11 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, skb_pull(Packet, numBytesCompressed); return STATUS_SUCCESS; - } - else - { + } else { //if one byte headroom is not available, increase it through skb_cow - if (!(skb_headroom(Packet) > 0)) - { - if (skb_cow(Packet, 1)) - { + if (!(skb_headroom(Packet) > 0)) { + + if (skb_cow(Packet, 1)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n"); return STATUS_FAILURE; } @@ -178,13 +170,10 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, *(Packet->data + BytesToRemove) = bPHSI; return STATUS_SUCCESS; } - } - else - { + } else { + if (!bHeaderSuppressionEnabled) - { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nHeader Suppression Disabled For SF: No PHS\n"); - } return STATUS_SUCCESS; } @@ -207,8 +196,7 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, PUCHAR pucInBuff = NULL; UINT TotalBytesAdded = 0; - if (!bHeaderSuppressionEnabled) - { + if (!bHeaderSuppressionEnabled) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nPhs Disabled for incoming packet"); return ulPhsStatus; } @@ -227,22 +215,17 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", nTotalsuppressedPktHdrBytes, nStandardPktHdrLen); - if (ulPhsStatus != STATUS_PHS_COMPRESSED) - { + if (ulPhsStatus != STATUS_PHS_COMPRESSED) { skb_pull(packet, 1); return STATUS_SUCCESS; - } - else - { + } else { TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN; - if (TotalBytesAdded) - { + + if (TotalBytesAdded) { if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) skb_push(packet, TotalBytesAdded); - else - { - if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) - { + else { + if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n"); return STATUS_FAILURE; } @@ -290,19 +273,16 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap pPhsdeviceExtension->pstServiceFlowPhsRulesTable = kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); - if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) - { + if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); return -ENOMEM; } pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; - for (i = 0; i < MAX_SERVICEFLOWS; i++) - { + for (i = 0; i < MAX_SERVICEFLOWS; i++) { struct bcm_phs_entry sServiceFlow = pstServiceFlowTable->stSFList[i]; sServiceFlow.pstClassifierTable = kzalloc(sizeof(struct bcm_phs_classifier_table), GFP_KERNEL); - if (!sServiceFlow.pstClassifierTable) - { + if (!sServiceFlow.pstClassifierTable) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; @@ -311,8 +291,7 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap } pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->CompressedTxBuffer == NULL) - { + if (pPhsdeviceExtension->CompressedTxBuffer == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; @@ -320,8 +299,7 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap } pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) - { + if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); kfree(pPhsdeviceExtension->CompressedTxBuffer); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); @@ -335,8 +313,7 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) { - if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) - { + if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) { free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; } @@ -383,23 +360,19 @@ ULONG PhsUpdateClassifierRule(IN void *pvContext, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS With Corr2 Changes\n"); - if (pDeviceExtension == NULL) - { + if (pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } if (u8AssociatedPHSI == 0) - { return ERR_PHS_INVALID_PHS_RULE; - } /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { /* This is a new SF. Create a mapping entry for this */ lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI); @@ -442,26 +415,21 @@ ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); - if (pDeviceExtension) - { + if (pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) - { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) - { - if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) - { - if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) - { + if (pstClassifierRulesTable) { + for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; @@ -504,22 +472,19 @@ ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT1 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - if (pDeviceExtension) - { + if (pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) - { - if (pstClassifierEntry->pstPhsRule) - { + + if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { + if (pstClassifierEntry->pstPhsRule) { if (pstClassifierEntry->pstPhsRule->u8RefCnt) pstClassifierEntry->pstPhsRule->u8RefCnt--; @@ -532,8 +497,7 @@ ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT1 nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId, eOldClassifierRuleContext, &pstClassifierEntry); - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) - { + if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { kfree(pstClassifierEntry->pstPhsRule); memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry)); } @@ -568,24 +532,20 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n"); - if (pDeviceExtension) - { + if (pDeviceExtension) { //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); return ERR_SF_MATCH_FAIL; } pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) - { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) - { - if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) - { + if (pstClassifierRulesTable) { + for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { + if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; @@ -595,8 +555,8 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule = NULL; } memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry)); - if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) - { + if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) { + if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; @@ -652,8 +612,7 @@ ULONG PhsCompress(IN void *pvContext, struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - if (pDeviceExtension == NULL) - { + if (pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Invalid Device Extension\n"); lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; @@ -664,8 +623,7 @@ ULONG PhsCompress(IN void *pvContext, //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "SFID Match Failed\n"); lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; @@ -674,8 +632,7 @@ ULONG PhsCompress(IN void *pvContext, nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry); - if (nClsidIndex == PHS_INVALID_TABLE_INDEX) - { + if (nClsidIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "No PHS Rule Defined For Classifier\n"); lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; @@ -683,8 +640,7 @@ ULONG PhsCompress(IN void *pvContext, //get rule from SF id,Cls ID pair and proceed pstPhsRule = pstClassifierEntry->pstPhsRule; - if (!ValidatePHSRuleComplete(pstPhsRule)) - { + if (!ValidatePHSRuleComplete(pstPhsRule)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n"); lStatus = STATUS_PHS_NOCOMPRESSION; return lStatus; @@ -694,12 +650,10 @@ ULONG PhsCompress(IN void *pvContext, lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer, (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize); - if (lStatus == STATUS_PHS_COMPRESSED) - { + if (lStatus == STATUS_PHS_COMPRESSED) { pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1; pstPhsRule->PHSModifiedNumPackets++; - } - else + } else pstPhsRule->PHSErrorNumPackets++; return lStatus; @@ -739,8 +693,7 @@ ULONG PhsDeCompress(IN void *pvContext, struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; *pInHeaderSize = 0; - if (pDeviceExtension == NULL) - { + if (pDeviceExtension == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } @@ -750,30 +703,24 @@ ULONG PhsDeCompress(IN void *pvContext, phsi = *((unsigned char *)(pvInputBuffer)); 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; - } //Retrieve the SFID Entry Index for requested Service Flow nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) - { + if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "SFID Match Failed During Lookup\n"); return ERR_SF_MATCH_FAIL; } nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi, eActiveClassifierRuleContext, &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) - { + if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { //Phs Rule does not exist in active rules table. Lets try in the old rules table. nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi, eOldClassifierRuleContext, &pstPhsRule); if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) - { return ERR_PHSRULE_MATCH_FAIL; - } } *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, @@ -804,19 +751,15 @@ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesT BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n"); - if (psServiceFlowRulesTable) - { - for (i = 0; i < MAX_SERVICEFLOWS; i++) - { + if (psServiceFlowRulesTable) { + for (i = 0; i < MAX_SERVICEFLOWS; i++) { struct bcm_phs_entry stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i]; struct bcm_phs_classifier_table *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable; - if (pstClassifierRulesTable) - { - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) - { - if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) - { + if (pstClassifierRulesTable) { + for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { + if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) { + if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt--; @@ -826,8 +769,8 @@ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesT pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; } - if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) - { + if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) { + if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt) pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt--; @@ -849,32 +792,24 @@ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesT static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule) { - if (psPhsRule) - { - if (!psPhsRule->u8PHSI) - { + if (psPhsRule) { + if (!psPhsRule->u8PHSI) { // PHSI is not valid return FALSE; } - if (!psPhsRule->u8PHSS) - { + if (!psPhsRule->u8PHSS) { //PHSS Is Undefined return FALSE; } //Check if PHSF is defines for the PHS Rule if (!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF - { return FALSE; - } return TRUE; - } - else - { + } else return FALSE; - } } UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, @@ -883,12 +818,9 @@ UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, { int i; - for (i = 0; i < MAX_SERVICEFLOWS; i++) - { - if (psServiceFlowTable->stSFList[i].bUsed) - { - if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid) - { + for (i = 0; i < MAX_SERVICEFLOWS; i++) { + if (psServiceFlowTable->stSFList[i].bUsed) { + if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid) { *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i]; return i; } @@ -906,21 +838,15 @@ UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, int i; struct bcm_phs_classifier_entry *psClassifierRules = NULL; - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) - { + for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { + if (eClsContext == eActiveClassifierRuleContext) - { psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i]; - } else - { psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i]; - } - if (psClassifierRules->bUsed) - { - if (psClassifierRules->uiClassifierRuleId == uiClsid) - { + if (psClassifierRules->bUsed) { + if (psClassifierRules->uiClassifierRuleId == uiClsid) { *ppstClassifierEntry = psClassifierRules; return i; } @@ -938,21 +864,14 @@ static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTab int i; struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) - { + for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { if (eClsContext == eActiveClassifierRuleContext) - { pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i]; - } else - { pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i]; - } - if (pstClassifierRule->bUsed) - { - if (pstClassifierRule->u8PHSI == uiPHSI) - { + if (pstClassifierRule->bUsed) { + if (pstClassifierRule->u8PHSI == uiPHSI) { *ppstPhsRule = pstClassifierRule->pstPhsRule; return i; } @@ -974,10 +893,8 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, BOOLEAN bFreeEntryFound = FALSE; //Check for a free entry in SFID table - for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) - { - if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) - { + for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { + if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) { bFreeEntryFound = TRUE; break; } @@ -989,8 +906,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable; uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule, eActiveClassifierRuleContext, u8AssociatedPHSI); - if (uiStatus == PHS_SUCCESS) - { + if (uiStatus == PHS_SUCCESS) { //Add entry at free index to the SF psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE; psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid; @@ -1022,8 +938,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, eActiveClassifierRuleContext, &pstClassifierEntry); - if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) - { + if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { /* The Classifier doesn't exist. So its a new classifier being added. Add new entry to associate PHS Rule to the Classifier @@ -1041,8 +956,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, is being modified */ - if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) - { + if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { if (pstClassifierEntry->pstPhsRule == NULL) return ERR_PHS_INVALID_PHS_RULE; @@ -1051,44 +965,37 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, rule update them. */ /* If any part of PHSF is valid then we update PHSF */ - if (psPhsRule->u8PHSFLength) - { + if (psPhsRule->u8PHSFLength) { //update PHSF memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, psPhsRule->u8PHSF, MAX_PHS_LENGTHS); } - if (psPhsRule->u8PHSFLength) - { + if (psPhsRule->u8PHSFLength) { //update PHSFLen pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength; } - if (psPhsRule->u8PHSMLength) - { + if (psPhsRule->u8PHSMLength) { //update PHSM memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, psPhsRule->u8PHSM, MAX_PHS_LENGTHS); } - if (psPhsRule->u8PHSMLength) - { + if (psPhsRule->u8PHSMLength) { //update PHSM Len pstClassifierEntry->pstPhsRule->u8PHSMLength = psPhsRule->u8PHSMLength; } - if (psPhsRule->u8PHSS) - { + if (psPhsRule->u8PHSS) { //update PHSS pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS; } //update PHSV pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; - } - else - { + } else { /* A new rule is being set for this classifier. */ @@ -1114,12 +1021,9 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Inside CreateClassifierPHSRule"); if (psaClassifiertable == NULL) - { return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; - } - if (eClsContext == eOldClassifierRuleContext) - { + if (eClsContext == eOldClassifierRuleContext) { /* If An Old Entry for this classifier ID already exists in the old rules table replace it. */ @@ -1127,8 +1031,7 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, GetClassifierEntry(psaClassifiertable, uiClsId, eClsContext, &psClassifierRules); - if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) - { + if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { /* The Classifier already exists in the old rules table Lets replace the old classifier with the new one. @@ -1137,44 +1040,32 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, } } - if (!bFreeEntryFound) - { + if (!bFreeEntryFound) { /* Continue to search for a free location to add the rule */ for (iClassifierIndex = 0; iClassifierIndex < - MAX_PHSRULE_PER_SF; iClassifierIndex++) - { + MAX_PHSRULE_PER_SF; iClassifierIndex++) { if (eClsContext == eActiveClassifierRuleContext) - { psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; - } else - { psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - } - if (!psClassifierRules->bUsed) - { + if (!psClassifierRules->bUsed) { bFreeEntryFound = TRUE; break; } } } - if (!bFreeEntryFound) - { + if (!bFreeEntryFound) { + if (eClsContext == eActiveClassifierRuleContext) - { return ERR_CLSASSIFIER_TABLE_FULL; - } - else - { + else { //Lets replace the oldest rule if we are looking in old Rule table if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) - { psaClassifiertable->uiOldestPhsRuleIndex = 0; - } iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; @@ -1183,10 +1074,10 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, } } - if (eClsContext == eOldClassifierRuleContext) - { - if (psClassifierRules->pstPhsRule == NULL) - { + if (eClsContext == eOldClassifierRuleContext) { + + if (psClassifierRules->pstPhsRule == NULL) { + psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL); if (NULL == psClassifierRules->pstPhsRule) @@ -1200,12 +1091,9 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, /* Update The PHS rule */ memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule)); - } - else - { + } else nStatus = UpdateClassifierPHSRule(uiClsId, psClassifierRules, psaClassifiertable, psPhsRule, u8AssociatedPHSI); - } return nStatus; } @@ -1230,33 +1118,27 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, eActiveClassifierRuleContext, &pstAddPhsRule); - if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) - { + if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier"); - if (psPhsRule->u8PHSI == 0) - { + if (psPhsRule->u8PHSI == 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n"); return ERR_PHS_INVALID_PHS_RULE; } //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId - if (FALSE == bPHSRuleOrphaned) - { + if (FALSE == bPHSRuleOrphaned) { + pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL); if (NULL == pstClassifierEntry->pstPhsRule) - { return ERR_PHSRULE_MEMALLOC_FAIL; - } } memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule)); - } - else - { + } else { //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); - if (bPHSRuleOrphaned) - { + if (bPHSRuleOrphaned) { kfree(pstClassifierEntry->pstPhsRule); pstClassifierEntry->pstPhsRule = NULL; } @@ -1280,17 +1162,13 @@ static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_tabl if (pstPhsRule->u8RefCnt) pstPhsRule->u8RefCnt--; - if (0 == pstPhsRule->u8RefCnt) - { + if (0 == pstPhsRule->u8RefCnt) { /*if(pstPhsRule->u8PHSI) //Store the currently active rule into the old rules list CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/ return TRUE; - } - else - { + } else return FALSE; - } } void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) @@ -1300,32 +1178,28 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules :\n"); - for (i = 0; i < MAX_SERVICEFLOWS; i++) - { + for (i = 0; i < MAX_SERVICEFLOWS; i++) { + struct bcm_phs_entry stServFlowEntry = pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; - if (stServFlowEntry.bUsed) - { - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) - { - for (l = 0; l < 2; l++) - { + if (stServFlowEntry.bUsed) { + + for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { + + for (l = 0; l < 2; l++) { struct bcm_phs_classifier_entry stClsEntry; - if (l == 0) - { + if (l == 0) { stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j]; if (stClsEntry.bUsed) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule :\n"); - } - else - { + } else { stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j]; if (stClsEntry.bUsed) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule :\n"); } - if (stClsEntry.bUsed) - { + + if (stClsEntry.bUsed) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", stServFlowEntry.uiVcid); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", stClsEntry.uiClassifierRuleId); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", stClsEntry.u8PHSI); @@ -1335,16 +1209,12 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); for (k = 0 ; k < stClsEntry.pstPhsRule->u8PHSFLength; k++) - { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSF[k]); - } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", stClsEntry.pstPhsRule->u8PHSMLength); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); for (k = 0; k < stClsEntry.pstPhsRule->u8PHSMLength; k++) - { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSM[k]); - } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", stClsEntry.pstPhsRule->u8PHSS); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", stClsEntry.pstPhsRule->u8PHSV); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); @@ -1403,18 +1273,14 @@ int phs_decompress(unsigned char *in_buf, phss = MAX_PHS_LENGTHS; //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)) - { + while ((phss > 0) && (size < in_buf_len)) { bit = ((*phsm << i) & SUPPRESS); - if (bit == SUPPRESS) - { + if (bit == SUPPRESS) { *out_buf = *phsf; 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 - { + } else { *out_buf = *in_buf; 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); @@ -1427,8 +1293,7 @@ int phs_decompress(unsigned char *in_buf, i++; *header_size = *header_size + 1; - if (i > MAX_NO_BIT) - { + if (i > MAX_NO_BIT) { i = 0; phsm++; } @@ -1467,21 +1332,16 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, int suppress = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - if (phs_rule == NULL) - { + if (phs_rule == NULL) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nphs_compress(): phs_rule null!"); *out_buf = ZERO_PHSI; return STATUS_PHS_NOCOMPRESSION; } if (phs_rule->u8PHSS <= *new_header_size) - { *header_size = phs_rule->u8PHSS; - } else - { *header_size = *new_header_size; - } //To copy PHSI out_buf++; @@ -1489,13 +1349,10 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV, new_header_size); - if (suppress == STATUS_PHS_COMPRESSED) - { + if (suppress == STATUS_PHS_COMPRESSED) { *old_addr = (unsigned char)phs_rule->u8PHSI; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress phsi %d", phs_rule->u8PHSI); - } - else - { + } else { *old_addr = ZERO_PHSI; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress PHSV Verification failed"); } @@ -1538,19 +1395,13 @@ static int verify_suppress_phsf(unsigned char *in_buffer, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm); if (phss > (*new_header_size)) - { phss = *new_header_size; - } - while (phss > 0) - { + while (phss > 0) { bit = ((*phsm << i) & SUPPRESS); - if (bit == SUPPRESS) - { - if (*in_buffer != *phsf) - { - if (phsv == VERIFY) - { + if (bit == SUPPRESS) { + if (*in_buffer != *phsf) { + if (phsv == VERIFY) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, @@ -1561,8 +1412,7 @@ static int verify_suppress_phsf(unsigned char *in_buffer, *phsf); return STATUS_PHS_NOCOMPRESSION; } - } - else + } else BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, @@ -1571,9 +1421,7 @@ static int verify_suppress_phsf(unsigned char *in_buffer, phss, *in_buffer, *phsf); - } - else - { + } else { *out_buffer = *in_buffer; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, @@ -1591,8 +1439,7 @@ static int verify_suppress_phsf(unsigned char *in_buffer, phss--; i++; - if (i > MAX_NO_BIT) - { + if (i > MAX_NO_BIT) { i = 0; phsm++; } -- cgit From 14b3a406783371610985b84357223c237f33ade9 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 20 Feb 2013 23:25:29 -0500 Subject: Staging: bcm: Properly format comments in PHSModule.c This patch properly formats comments, and removes them as needed in PHSModule.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 543 ++++++++++++++++++++-------------------- 1 file changed, 272 insertions(+), 271 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 17318003998d..48377839dc08 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -46,22 +46,22 @@ static ULONG PhsDeCompress(void *pvContext, #define OUT /* -Function: PHSTransmit -Description: This routine handle PHS(Payload Header Suppression for Tx path. - It extracts a fragment of the NDIS_PACKET containing the header - to be suppressed. It then suppresses the header by invoking PHS exported compress routine. - The header data after suppression is copied back to the NDIS_PACKET. - -Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - IN Packet - NDIS packet containing data to be transmitted - IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to - identify PHS rule to be applied. - B_UINT16 uiClassifierRuleID - Classifier Rule ID - BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. - -Return: STATUS_SUCCESS - If the send was successful. - Other - If an error occurred. -*/ + * Function: PHSTransmit + * Description: This routine handle PHS(Payload Header Suppression for Tx path. + * It extracts a fragment of the NDIS_PACKET containing the header + * to be suppressed. It then suppresses the header by invoking PHS exported compress routine. + * The header data after suppression is copied back to the NDIS_PACKET. + * + * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context + * IN Packet - NDIS packet containing data to be transmitted + * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to + * identify PHS rule to be applied. + * B_UINT16 uiClassifierRuleID - Classifier Rule ID + * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. + * + * Return: STATUS_SUCCESS - If the send was successful. + * Other - If an error occurred. + */ int PHSTransmit(struct bcm_mini_adapter *Adapter, struct sk_buff **pPacket, @@ -71,7 +71,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, UINT *PacketLen, UCHAR bEthCSSupport) { - //PHS Sepcific + /* PHS Sepcific */ UINT unPHSPktHdrBytesCopied = 0; UINT unPhsOldHdrSize = 0; UINT unPHSNewPktHeaderLen = 0; @@ -92,14 +92,14 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, if (!bEthCSSupport) BytesToRemove = ETH_HLEN; /* - Accumulate the header upto the size we support suppression - from NDIS packet - */ + * Accumulate the header upto the size we support suppression + * from NDIS packet + */ usPacketType = ((struct ethhdr *)(Packet->data))->h_proto; pucPHSPktHdrInBuf = Packet->data + BytesToRemove; - //considering data after ethernet header + /* considering data after ethernet header */ if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); else @@ -108,8 +108,10 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, if ((unPHSPktHdrBytesCopied > 0) && (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { - // Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. - // Suppress only if IP Header and PHS Enabled For the Service Flow + /* + * Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. + * Suppress only if IP Header and PHS Enabled For the Service Flow + */ if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && (bHeaderSuppressionEnabled)) { @@ -156,7 +158,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } else { - //if one byte headroom is not available, increase it through skb_cow + /* if one byte headroom is not available, increase it through skb_cow */ if (!(skb_headroom(Packet) > 0)) { if (skb_cow(Packet, 1)) { @@ -166,7 +168,11 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, } skb_push(Packet, 1); - // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it. + /* + * CAUTION: The MAC Header is getting corrupted + * here for IP CS - can be saved by copying 14 + * Bytes. not needed .... hence corrupting it. + */ *(Packet->data + BytesToRemove) = bPHSI; return STATUS_SUCCESS; } @@ -179,7 +185,7 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter, } } - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); */ return STATUS_SUCCESS; } @@ -203,7 +209,7 @@ int PHSReceive(struct bcm_mini_adapter *Adapter, pucInBuff = packet->data; - //Restore PHS suppressed header + /* Restore PHS suppressed header */ nStandardPktHdrLen = packet->len; ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, usVcid, @@ -248,19 +254,19 @@ void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, pBuf, nPktLen); } -//----------------------------------------------------------------------------- -// Procedure: phs_init -// -// Description: This routine is responsible for allocating memory for classifier and -// PHS rules. -// -// Arguments: -// pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc -// -// Returns: -// TRUE(1) -If allocation of memory was success full. -// FALSE -If allocation of memory fails. -//----------------------------------------------------------------------------- +/* + * Procedure: phs_init + * + * Description: This routine is responsible for allocating memory for classifier and + * PHS rules. + * + * Arguments: + * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc + * + * Returns: + * TRUE(1) -If allocation of memory was success full. + * FALSE -If allocation of memory fails. + */ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adapter *Adapter) { int i; @@ -327,25 +333,24 @@ int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) return 0; } -//PHS functions -/*++ -PhsUpdateClassifierRule - -Routine Description: - Exported function to add or modify a PHS Rule. - -Arguments: - IN void* pvContext - PHS Driver Specific Context - IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. - -Return Value: - - 0 if successful, - >0 Error. - ---*/ +/* + * PHS functions + * PhsUpdateClassifierRule + * + * Routine Description: + * Exported function to add or modify a PHS Rule. + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context + * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. + * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsUpdateClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid , IN B_UINT16 uiClsId , @@ -386,24 +391,22 @@ ULONG PhsUpdateClassifierRule(IN void *pvContext, return lStatus; } -/*++ -PhsDeletePHSRule - -Routine Description: - Deletes the specified phs Rule within Vcid - -Arguments: - IN void* pvContext - PHS Driver Specific Context - IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. - -Return Value: - - 0 if successful, - >0 Error. - ---*/ - +/* + * PhsDeletePHSRule + * + * Routine Description: + * Deletes the specified phs Rule within Vcid + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context + * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI) { ULONG lStatus = 0; @@ -416,7 +419,7 @@ ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n"); if (pDeviceExtension) { - //Retrieve the SFID Entry Index for requested Service Flow + /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if (nSFIndex == PHS_INVALID_TABLE_INDEX) { @@ -446,23 +449,22 @@ ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI return lStatus; } -/*++ -PhsDeleteClassifierRule - -Routine Description: - Exported function to Delete a PHS Rule for the SFID,CLSID Pair. - -Arguments: - IN void* pvContext - PHS Driver Specific Context - IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - -Return Value: - - 0 if successful, - >0 Error. - ---*/ +/* + * PhsDeleteClassifierRule + * + * Routine Description: + * Exported function to Delete a PHS Rule for the SFID,CLSID Pair. + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context + * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies + * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId) { ULONG lStatus = 0; @@ -473,7 +475,7 @@ ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT1 struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; if (pDeviceExtension) { - //Retrieve the SFID Entry Index for requested Service Flow + /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if (nSFIndex == PHS_INVALID_TABLE_INDEX) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n"); @@ -505,22 +507,21 @@ ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT1 return lStatus; } -/*++ -PhsDeleteSFRules - -Routine Description: - Exported function to Delete a all PHS Rules for the SFID. - -Arguments: - IN void* pvContext - PHS Driver Specific Context - IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted - -Return Value: - - 0 if successful, - >0 Error. - ---*/ +/* + * PhsDeleteSFRules + * + * Routine Description: + * Exported function to Delete a all PHS Rules for the SFID. + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context + * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) { ULONG lStatus = 0; @@ -533,7 +534,7 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n"); if (pDeviceExtension) { - //Retrieve the SFID Entry Index for requested Service Flow + /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if (nSFIndex == PHS_INVALID_TABLE_INDEX) { @@ -575,27 +576,26 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) return lStatus; } -/*++ -PhsCompress - -Routine Description: - Exported function to compress the data using PHS. - -Arguments: - IN void* pvContext - PHS Driver Specific Context. - IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies. - IN UINT uiClsId - The Classifier ID to which current packet header compression applies. - IN void *pvInputBuffer - The Input buffer containg packet header data - IN void *pvOutputBuffer - The output buffer returned by this function after PHS - IN UINT *pOldHeaderSize - The actual size of the header before PHS - IN UINT *pNewHeaderSize - The new size of the header after applying PHS - -Return Value: - - 0 if successful, - >0 Error. - ---*/ +/* + * PhsCompress + * + * Routine Description: + * Exported function to compress the data using PHS. + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context. + * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies. + * IN UINT uiClsId - The Classifier ID to which current packet header compression applies. + * IN void *pvInputBuffer - The Input buffer containg packet header data + * IN void *pvOutputBuffer - The output buffer returned by this function after PHS + * IN UINT *pOldHeaderSize - The actual size of the header before PHS + * IN UINT *pNewHeaderSize - The new size of the header after applying PHS + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsCompress(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, @@ -620,7 +620,7 @@ ULONG PhsCompress(IN void *pvContext, BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Suppressing header\n"); - //Retrieve the SFID Entry Index for requested Service Flow + /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if (nSFIndex == PHS_INVALID_TABLE_INDEX) { @@ -638,7 +638,7 @@ ULONG PhsCompress(IN void *pvContext, return lStatus; } - //get rule from SF id,Cls ID pair and proceed + /* get rule from SF id,Cls ID pair and proceed */ pstPhsRule = pstClassifierEntry->pstPhsRule; if (!ValidatePHSRuleComplete(pstPhsRule)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n"); @@ -646,7 +646,7 @@ ULONG PhsCompress(IN void *pvContext, return lStatus; } - //Compress Packet + /* Compress Packet */ lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer, (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize); @@ -659,25 +659,24 @@ ULONG PhsCompress(IN void *pvContext, return lStatus; } -/*++ -PhsDeCompress - -Routine Description: - Exported function to restore the packet header in Rx path. - -Arguments: - IN void* pvContext - PHS Driver Specific Context. - IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies. - IN void *pvInputBuffer - The Input buffer containg suppressed packet header data - OUT void *pvOutputBuffer - The output buffer returned by this function after restoration - OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter. - -Return Value: - - 0 if successful, - >0 Error. - ---*/ +/* + * PhsDeCompress + * + * Routine Description: + * Exported function to restore the packet header in Rx path. + * + * Arguments: + * IN void* pvContext - PHS Driver Specific Context. + * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies. + * IN void *pvInputBuffer - The Input buffer containg suppressed packet header data + * OUT void *pvOutputBuffer - The output buffer returned by this function after restoration + * OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter. + * + * Return Value: + * + * 0 if successful, + * >0 Error. + */ ULONG PhsDeCompress(IN void *pvContext, IN B_UINT16 uiVcid, IN void *pvInputBuffer, @@ -705,7 +704,7 @@ ULONG PhsDeCompress(IN void *pvContext, if (phsi == UNCOMPRESSED_PACKET) return STATUS_PHS_NOCOMPRESSION; - //Retrieve the SFID Entry Index for requested Service Flow + /* Retrieve the SFID Entry Index for requested Service Flow */ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry); if (nSFIndex == PHS_INVALID_TABLE_INDEX) { @@ -716,7 +715,7 @@ ULONG PhsDeCompress(IN void *pvContext, nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi, eActiveClassifierRuleContext, &pstPhsRule); if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { - //Phs Rule does not exist in active rules table. Lets try in the old rules table. + /* Phs Rule does not exist in active rules table. Lets try in the old rules table. */ nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi, eOldClassifierRuleContext, &pstPhsRule); if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) @@ -732,18 +731,17 @@ ULONG PhsDeCompress(IN void *pvContext, return STATUS_PHS_COMPRESSED; } -//----------------------------------------------------------------------------- -// Procedure: free_phs_serviceflow_rules -// -// Description: This routine is responsible for freeing memory allocated for PHS rules. -// -// Arguments: -// rules - ptr to S_SERVICEFLOW_TABLE structure. -// -// Returns: -// Does not return any value. -//----------------------------------------------------------------------------- - +/* + * Procedure: free_phs_serviceflow_rules + * + * Description: This routine is responsible for freeing memory allocated for PHS rules. + * + * Arguments: + * rules - ptr to S_SERVICEFLOW_TABLE structure. + * + * Returns: + * Does not return any value. + */ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable) { int i, j; @@ -794,17 +792,17 @@ static BOOLEAN ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule) { if (psPhsRule) { if (!psPhsRule->u8PHSI) { - // PHSI is not valid + /* PHSI is not valid */ return FALSE; } if (!psPhsRule->u8PHSS) { - //PHSS Is Undefined + /* PHSS Is Undefined */ return FALSE; } - //Check if PHSF is defines for the PHS Rule - if (!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF + /* Check if PHSF is defines for the PHS Rule */ + if (!psPhsRule->u8PHSFLength) /* If any part of PHSF is valid then Rule contains valid PHSF */ return FALSE; return TRUE; @@ -892,7 +890,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, int iSfIndex; BOOLEAN bFreeEntryFound = FALSE; - //Check for a free entry in SFID table + /* Check for a free entry in SFID table */ for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) { bFreeEntryFound = TRUE; @@ -907,7 +905,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId, uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule, eActiveClassifierRuleContext, u8AssociatedPHSI); if (uiStatus == PHS_SUCCESS) { - //Add entry at free index to the SF + /* Add entry at free index to the SF */ psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE; psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid; } @@ -940,9 +938,9 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { /* - The Classifier doesn't exist. So its a new classifier being added. - Add new entry to associate PHS Rule to the Classifier - */ + * The Classifier doesn't exist. So its a new classifier being added. + * Add new entry to associate PHS Rule to the Classifier + */ uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule, @@ -952,53 +950,51 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, } /* - The Classifier exists.The PHS Rule for this classifier - is being modified - */ + * The Classifier exists.The PHS Rule for this classifier + * is being modified + */ if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { if (pstClassifierEntry->pstPhsRule == NULL) return ERR_PHS_INVALID_PHS_RULE; /* - This rule already exists if any fields are changed for this PHS - rule update them. - */ + * This rule already exists if any fields are changed for this PHS + * rule update them. + */ /* If any part of PHSF is valid then we update PHSF */ if (psPhsRule->u8PHSFLength) { - //update PHSF + /* update PHSF */ memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, psPhsRule->u8PHSF, MAX_PHS_LENGTHS); } if (psPhsRule->u8PHSFLength) { - //update PHSFLen + /* update PHSFLen */ pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength; } if (psPhsRule->u8PHSMLength) { - //update PHSM + /* update PHSM */ memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, psPhsRule->u8PHSM, MAX_PHS_LENGTHS); } if (psPhsRule->u8PHSMLength) { - //update PHSM Len + /* update PHSM Len */ pstClassifierEntry->pstPhsRule->u8PHSMLength = psPhsRule->u8PHSMLength; } if (psPhsRule->u8PHSS) { - //update PHSS + /* update PHSS */ pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS; } - //update PHSV + /* update PHSV */ pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; } else { - /* - A new rule is being set for this classifier. - */ + /* A new rule is being set for this classifier. */ uiStatus = UpdateClassifierPHSRule(uiClsId, pstClassifierEntry, psaClassifiertable, psPhsRule, u8AssociatedPHSI); } @@ -1024,8 +1020,10 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; if (eClsContext == eOldClassifierRuleContext) { - /* If An Old Entry for this classifier ID already exists in the - old rules table replace it. */ + /* + * If An Old Entry for this classifier ID already exists in the + * old rules table replace it. + */ iClassifierIndex = GetClassifierEntry(psaClassifiertable, uiClsId, @@ -1033,17 +1031,15 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { /* - The Classifier already exists in the old rules table - Lets replace the old classifier with the new one. - */ + * The Classifier already exists in the old rules table + * Lets replace the old classifier with the new one. + */ bFreeEntryFound = TRUE; } } if (!bFreeEntryFound) { - /* - Continue to search for a free location to add the rule - */ + /* Continue to search for a free location to add the rule */ for (iClassifierIndex = 0; iClassifierIndex < MAX_PHSRULE_PER_SF; iClassifierIndex++) { if (eClsContext == eActiveClassifierRuleContext) @@ -1063,7 +1059,7 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, if (eClsContext == eActiveClassifierRuleContext) return ERR_CLSASSIFIER_TABLE_FULL; else { - //Lets replace the oldest rule if we are looking in old Rule table + /* Lets replace the oldest rule if we are looking in old Rule table */ if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) psaClassifiertable->uiOldestPhsRuleIndex = 0; @@ -1111,11 +1107,11 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, psPhsRule->u8RefCnt = 0; - /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/ + /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */ bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable, pstClassifierEntry->pstPhsRule); - //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF + /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF */ nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, eActiveClassifierRuleContext, &pstAddPhsRule); if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { @@ -1127,7 +1123,7 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, return ERR_PHS_INVALID_PHS_RULE; } - //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId + /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId */ if (FALSE == bPHSRuleOrphaned) { pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL); @@ -1136,7 +1132,7 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, } memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule)); } else { - //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule + /* Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); if (bPHSRuleOrphaned) { kfree(pstClassifierEntry->pstPhsRule); @@ -1163,9 +1159,11 @@ static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_tabl pstPhsRule->u8RefCnt--; if (0 == pstPhsRule->u8RefCnt) { - /*if(pstPhsRule->u8PHSI) - //Store the currently active rule into the old rules list - CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/ + /* + * if(pstPhsRule->u8PHSI) + * Store the currently active rule into the old rules list + * CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI); + */ return TRUE; } else return FALSE; @@ -1225,23 +1223,22 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) } } -//----------------------------------------------------------------------------- -// Procedure: phs_decompress -// -// Description: This routine restores the static fields within the packet. -// -// Arguments: -// in_buf - ptr to incoming packet buffer. -// out_buf - ptr to output buffer where the suppressed header is copied. -// decomp_phs_rules - ptr to PHS rule. -// header_size - ptr to field which holds the phss or phsf_length. -// -// Returns: -// size -The number of bytes of dynamic fields present with in the incoming packet -// header. -// 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed. -//----------------------------------------------------------------------------- - +/* + * Procedure: phs_decompress + * + * Description: This routine restores the static fields within the packet. + * + * Arguments: + * in_buf - ptr to incoming packet buffer. + * out_buf - ptr to output buffer where the suppressed header is copied. + * decomp_phs_rules - ptr to PHS rule. + * header_size - ptr to field which holds the phss or phsf_length. + * + * Returns: + * size -The number of bytes of dynamic fields present with in the incoming packet + * header. + * 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed. + */ int phs_decompress(unsigned char *in_buf, unsigned char *out_buf, struct bcm_phs_rule *decomp_phs_rules, @@ -1263,8 +1260,10 @@ int phs_decompress(unsigned char *in_buf, return 0; tmp_memb = decomp_phs_rules; - //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; + /* + * 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; phsm = tmp_memb->u8PHSM; @@ -1272,7 +1271,10 @@ int phs_decompress(unsigned char *in_buf, if (phss > MAX_PHS_LENGTHS) phss = MAX_PHS_LENGTHS; - //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)); + /* + * 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); @@ -1302,26 +1304,26 @@ int phs_decompress(unsigned char *in_buf, return size; } -//----------------------------------------------------------------------------- -// Procedure: phs_compress -// -// Description: This routine suppresses the static fields within the packet.Before -// that it will verify the fields to be suppressed with the corresponding fields in the -// phsf. For verification it checks the phsv field of PHS rule. If set and verification -// succeeds it suppresses the field.If any one static field is found different none of -// the static fields are suppressed then the packet is sent as uncompressed packet with -// phsi=0. -// -// Arguments: -// phs_rule - ptr to PHS rule. -// in_buf - ptr to incoming packet buffer. -// out_buf - ptr to output buffer where the suppressed header is copied. -// header_size - ptr to field which holds the phss. -// -// Returns: -// size-The number of bytes copied into the output buffer i.e dynamic fields -// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. -//----------------------------------------------------------------------------- +/* + * Procedure: phs_compress + * + * Description: This routine suppresses the static fields within the packet.Before + * that it will verify the fields to be suppressed with the corresponding fields in the + * phsf. For verification it checks the phsv field of PHS rule. If set and verification + * succeeds it suppresses the field.If any one static field is found different none of + * the static fields are suppressed then the packet is sent as uncompressed packet with + * phsi=0. + * + * Arguments: + * phs_rule - ptr to PHS rule. + * in_buf - ptr to incoming packet buffer. + * out_buf - ptr to output buffer where the suppressed header is copied. + * header_size - ptr to field which holds the phss. + * + * Returns: + * size-The number of bytes copied into the output buffer i.e dynamic fields + * 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. + */ static int phs_compress(struct bcm_phs_rule *phs_rule, unsigned char *in_buf, unsigned char *out_buf, @@ -1343,7 +1345,7 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, else *header_size = *new_header_size; - //To copy PHSI + /* To copy PHSI */ out_buf++; suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF, phs_rule->u8PHSM, phs_rule->u8PHSS, @@ -1360,26 +1362,25 @@ static int phs_compress(struct bcm_phs_rule *phs_rule, return suppress; } -//----------------------------------------------------------------------------- -// Procedure: verify_suppress_phsf -// -// Description: This routine verifies the fields of the packet and if all the -// static fields are equal it adds the phsi of that PHS rule.If any static -// field differs it woun't suppress any field. -// -// Arguments: -// rules_set - ptr to classifier_rules. -// in_buffer - ptr to incoming packet buffer. -// out_buffer - ptr to output buffer where the suppressed header is copied. -// phsf - ptr to phsf. -// phsm - ptr to phsm. -// phss - variable holding phss. -// -// Returns: -// size-The number of bytes copied into the output buffer i.e dynamic fields. -// 0 -Packet has failed the verification. -//----------------------------------------------------------------------------- - +/* + * Procedure: verify_suppress_phsf + * + * Description: This routine verifies the fields of the packet and if all the + * static fields are equal it adds the phsi of that PHS rule.If any static + * field differs it woun't suppress any field. + * + * Arguments: + * rules_set - ptr to classifier_rules. + * in_buffer - ptr to incoming packet buffer. + * out_buffer - ptr to output buffer where the suppressed header is copied. + * phsf - ptr to phsf. + * phsm - ptr to phsm. + * phss - variable holding phss. + * + * Returns: + * size-The number of bytes copied into the output buffer i.e dynamic fields. + * 0 -Packet has failed the verification. + */ static int verify_suppress_phsf(unsigned char *in_buffer, unsigned char *out_buffer, unsigned char *phsf, -- cgit From 175c51259cbb56e03e620f8ddfd95b8b62427eea Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 20 Feb 2013 23:25:30 -0500 Subject: Staging: bcm: Fix spelling error in PHSModule.c This patch fixes a spelling error in PHSModule.c Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 48377839dc08..af5d22faa7f0 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -264,7 +264,7 @@ void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc * * Returns: - * TRUE(1) -If allocation of memory was success full. + * TRUE(1) -If allocation of memory was successful. * FALSE -If allocation of memory fails. */ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adapter *Adapter) -- cgit From b902fbfebf2c80c3782e41eda24b487964a47fd1 Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 25 Feb 2013 20:32:51 -0500 Subject: staging: vt6656: replaced custom BYTE definition with u8 Checkpatch findings were not resolved, only direct replacement. sed -i 's/\bBYTE\b/u8/g' drivers/staging/vt6656/*.[ch] sed -i 's/\bPBYTE\b/u8 */g' drivers/staging/vt6656/*.[ch] Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211hdr.h | 24 ++-- drivers/staging/vt6656/80211mgr.c | 32 ++--- drivers/staging/vt6656/80211mgr.h | 254 +++++++++++++++++++------------------- drivers/staging/vt6656/aes_ccmp.c | 82 ++++++------ drivers/staging/vt6656/aes_ccmp.h | 2 +- drivers/staging/vt6656/baseband.c | 34 ++--- drivers/staging/vt6656/baseband.h | 4 +- drivers/staging/vt6656/bssdb.c | 18 +-- drivers/staging/vt6656/bssdb.h | 62 +++++----- drivers/staging/vt6656/card.c | 44 +++---- drivers/staging/vt6656/card.h | 2 +- drivers/staging/vt6656/channel.c | 14 +-- drivers/staging/vt6656/channel.h | 6 +- drivers/staging/vt6656/datarate.c | 28 ++--- drivers/staging/vt6656/datarate.h | 8 +- drivers/staging/vt6656/desc.h | 68 +++++----- drivers/staging/vt6656/device.h | 10 +- drivers/staging/vt6656/dpc.c | 56 ++++----- drivers/staging/vt6656/firmware.c | 2 +- drivers/staging/vt6656/hostap.c | 8 +- drivers/staging/vt6656/int.c | 16 +-- drivers/staging/vt6656/int.h | 30 ++--- drivers/staging/vt6656/iwctl.c | 24 ++-- drivers/staging/vt6656/key.c | 6 +- drivers/staging/vt6656/key.h | 12 +- drivers/staging/vt6656/mac.c | 46 +++---- drivers/staging/vt6656/main_usb.c | 16 +-- drivers/staging/vt6656/mib.c | 36 +++--- drivers/staging/vt6656/mib.h | 34 ++--- drivers/staging/vt6656/michael.c | 24 ++-- drivers/staging/vt6656/michael.h | 2 +- drivers/staging/vt6656/rc4.c | 22 ++-- drivers/staging/vt6656/rc4.h | 6 +- drivers/staging/vt6656/rndis.h | 62 +++++----- drivers/staging/vt6656/rxtx.c | 192 ++++++++++++++-------------- drivers/staging/vt6656/rxtx.h | 186 ++++++++++++++-------------- drivers/staging/vt6656/srom.h | 42 +++---- drivers/staging/vt6656/tcrc.c | 8 +- drivers/staging/vt6656/tcrc.h | 6 +- drivers/staging/vt6656/tether.c | 10 +- drivers/staging/vt6656/tether.h | 22 ++-- drivers/staging/vt6656/tkip.c | 10 +- drivers/staging/vt6656/tkip.h | 6 +- drivers/staging/vt6656/tmacro.h | 6 +- drivers/staging/vt6656/ttype.h | 3 - drivers/staging/vt6656/wcmd.c | 4 +- drivers/staging/vt6656/wcmd.h | 2 +- drivers/staging/vt6656/wctl.c | 6 +- drivers/staging/vt6656/wmgr.c | 86 ++++++------- drivers/staging/vt6656/wpa.c | 22 ++-- drivers/staging/vt6656/wpa.h | 4 +- drivers/staging/vt6656/wpa2.c | 22 ++-- drivers/staging/vt6656/wpa2.h | 4 +- drivers/staging/vt6656/wpactl.c | 16 +-- 54 files changed, 874 insertions(+), 877 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h index b87d5434077a..6d181bbc6871 100644 --- a/drivers/staging/vt6656/80211hdr.h +++ b/drivers/staging/vt6656/80211hdr.h @@ -269,15 +269,15 @@ #define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1) /* 3-Addr & 4-Addr */ -#define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN) -#define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN) +#define WLAN_HDR_A3_DATA_PTR(p) (((u8 *)(p)) + WLAN_HDR_ADDR3_LEN) +#define WLAN_HDR_A4_DATA_PTR(p) (((u8 *)(p)) + WLAN_HDR_ADDR4_LEN) /* IEEE ADDR */ #define IEEE_ADDR_UNIVERSAL 0x02 #define IEEE_ADDR_GROUP 0x01 typedef struct { - BYTE abyAddr[6]; + u8 abyAddr[6]; } IEEE_ADDR, *PIEEE_ADDR; /* 802.11 Header Format */ @@ -286,8 +286,8 @@ typedef struct tagWLAN_80211HDR_A2 { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[WLAN_ADDR_LEN]; - BYTE abyAddr2[WLAN_ADDR_LEN]; + u8 abyAddr1[WLAN_ADDR_LEN]; + u8 abyAddr2[WLAN_ADDR_LEN]; } __attribute__ ((__packed__)) WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; @@ -296,9 +296,9 @@ typedef struct tagWLAN_80211HDR_A3 { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[WLAN_ADDR_LEN]; - BYTE abyAddr2[WLAN_ADDR_LEN]; - BYTE abyAddr3[WLAN_ADDR_LEN]; + u8 abyAddr1[WLAN_ADDR_LEN]; + u8 abyAddr2[WLAN_ADDR_LEN]; + u8 abyAddr3[WLAN_ADDR_LEN]; WORD wSeqCtl; } __attribute__ ((__packed__)) @@ -308,11 +308,11 @@ typedef struct tagWLAN_80211HDR_A4 { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[WLAN_ADDR_LEN]; - BYTE abyAddr2[WLAN_ADDR_LEN]; - BYTE abyAddr3[WLAN_ADDR_LEN]; + u8 abyAddr1[WLAN_ADDR_LEN]; + u8 abyAddr2[WLAN_ADDR_LEN]; + u8 abyAddr3[WLAN_ADDR_LEN]; WORD wSeqCtl; - BYTE abyAddr4[WLAN_ADDR_LEN]; + u8 abyAddr4[WLAN_ADDR_LEN]; } __attribute__ ((__packed__)) WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c index 534d490539b6..b494453c0b0c 100644 --- a/drivers/staging/vt6656/80211mgr.c +++ b/drivers/staging/vt6656/80211mgr.c @@ -141,9 +141,9 @@ vMgrDecodeBeacon( + WLAN_BEACON_OFF_CAPINFO); /* Information elements */ - pItem = (PWLAN_IE)((PBYTE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) + pItem = (PWLAN_IE)((u8 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) + WLAN_BEACON_OFF_SSID); - while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) { + while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) { switch (pItem->byElementID) { case WLAN_EID_SSID: @@ -224,7 +224,7 @@ vMgrDecodeBeacon( break; } - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); } } @@ -376,7 +376,7 @@ vMgrDecodeAssocRequest( pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCREQ_OFF_SSID); - while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) { + while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) { switch (pItem->byElementID) { case WLAN_EID_SSID: if (pFrame->pSSID == NULL) @@ -407,7 +407,7 @@ vMgrDecodeAssocRequest( pItem->byElementID); break; } - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); } } @@ -474,9 +474,9 @@ vMgrDecodeAssocResponse( + WLAN_ASSOCRESP_OFF_SUPP_RATES); pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); - if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { + if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem); } else @@ -545,7 +545,7 @@ vMgrDecodeReassocRequest( pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_SSID); - while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) { + while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) { switch (pItem->byElementID) { case WLAN_EID_SSID: @@ -576,7 +576,7 @@ vMgrDecodeReassocRequest( pItem->byElementID); break; } - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); } } @@ -626,7 +626,7 @@ vMgrDecodeProbeRequest( /* Information elements */ pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))); - while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) { + while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) { switch (pItem->byElementID) { case WLAN_EID_SSID: @@ -649,7 +649,7 @@ vMgrDecodeProbeRequest( break; } - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); } } @@ -722,7 +722,7 @@ vMgrDecodeProbeResponse( pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_SSID); - while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) { + while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) { switch (pItem->byElementID) { case WLAN_EID_SSID: if (pFrame->pSSID == NULL) @@ -796,7 +796,7 @@ vMgrDecodeProbeResponse( break; } - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); } } @@ -862,7 +862,7 @@ vMgrDecodeAuthen( pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_CHALLENGE); - if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) + if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem; } @@ -980,8 +980,8 @@ vMgrDecodeReassocResponse( + WLAN_REASSOCRESP_OFF_SUPP_RATES); pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len); + pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len); - if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) + if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; } diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index f8e16d8989ea..2a88f0c2c7c7 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -223,56 +223,56 @@ #pragma pack(1) typedef struct tagWLAN_IE { - BYTE byElementID; - BYTE len; + u8 byElementID; + u8 len; } __attribute__ ((__packed__)) WLAN_IE, *PWLAN_IE; /* Service Set IDentity (SSID) */ #pragma pack(1) typedef struct tagWLAN_IE_SSID { - BYTE byElementID; - BYTE len; - BYTE abySSID[1]; + u8 byElementID; + u8 len; + u8 abySSID[1]; } __attribute__ ((__packed__)) WLAN_IE_SSID, *PWLAN_IE_SSID; /* Supported Rates */ #pragma pack(1) typedef struct tagWLAN_IE_SUPP_RATES { - BYTE byElementID; - BYTE len; - BYTE abyRates[1]; + u8 byElementID; + u8 len; + u8 abyRates[1]; } __attribute__ ((__packed__)) WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; /* FH Parameter Set */ #pragma pack(1) typedef struct _WLAN_IE_FH_PARMS { - BYTE byElementID; - BYTE len; + u8 byElementID; + u8 len; WORD wDwellTime; - BYTE byHopSet; - BYTE byHopPattern; - BYTE byHopIndex; + u8 byHopSet; + u8 byHopPattern; + u8 byHopIndex; } WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS; /* DS Parameter Set */ #pragma pack(1) typedef struct tagWLAN_IE_DS_PARMS { - BYTE byElementID; - BYTE len; - BYTE byCurrChannel; + u8 byElementID; + u8 len; + u8 byCurrChannel; } __attribute__ ((__packed__)) WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS; /* CF Parameter Set */ #pragma pack(1) typedef struct tagWLAN_IE_CF_PARMS { - BYTE byElementID; - BYTE len; - BYTE byCFPCount; - BYTE byCFPPeriod; + u8 byElementID; + u8 len; + u8 byCFPCount; + u8 byCFPPeriod; WORD wCFPMaxDuration; WORD wCFPDurRemaining; } __attribute__ ((__packed__)) @@ -281,20 +281,20 @@ WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS; /* TIM */ #pragma pack(1) typedef struct tagWLAN_IE_TIM { - BYTE byElementID; - BYTE len; - BYTE byDTIMCount; - BYTE byDTIMPeriod; - BYTE byBitMapCtl; - BYTE byVirtBitMap[1]; + u8 byElementID; + u8 len; + u8 byDTIMCount; + u8 byDTIMPeriod; + u8 byBitMapCtl; + u8 byVirtBitMap[1]; } __attribute__ ((__packed__)) WLAN_IE_TIM, *PWLAN_IE_TIM; /* IBSS Parameter Set */ #pragma pack(1) typedef struct tagWLAN_IE_IBSS_PARMS { - BYTE byElementID; - BYTE len; + u8 byElementID; + u8 len; WORD wATIMWindow; } __attribute__ ((__packed__)) WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; @@ -302,22 +302,22 @@ WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; /* Challenge Text */ #pragma pack(1) typedef struct tagWLAN_IE_CHALLENGE { - BYTE byElementID; - BYTE len; - BYTE abyChallenge[1]; + u8 byElementID; + u8 len; + u8 abyChallenge[1]; } __attribute__ ((__packed__)) WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE; #pragma pack(1) typedef struct tagWLAN_IE_RSN_EXT { - BYTE byElementID; - BYTE len; - BYTE abyOUI[4]; + u8 byElementID; + u8 len; + u8 abyOUI[4]; WORD wVersion; - BYTE abyMulticast[4]; + u8 abyMulticast[4]; WORD wPKCount; struct { - BYTE abyOUI[4]; + u8 abyOUI[4]; } PKSList[1]; /* the rest is variable so need to overlay ieauth structure */ } WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT; @@ -326,79 +326,79 @@ typedef struct tagWLAN_IE_RSN_EXT { typedef struct tagWLAN_IE_RSN_AUTH { WORD wAuthCount; struct { - BYTE abyOUI[4]; + u8 abyOUI[4]; } AuthKSList[1]; } WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH; /* RSN Identity */ #pragma pack(1) typedef struct tagWLAN_IE_RSN { - BYTE byElementID; - BYTE len; + u8 byElementID; + u8 len; WORD wVersion; - BYTE abyRSN[WLAN_MIN_ARRAY]; + u8 abyRSN[WLAN_MIN_ARRAY]; } WLAN_IE_RSN, *PWLAN_IE_RSN; /* CCX Identity DavidWang */ #pragma pack(1) typedef struct tagWLAN_IE_CCX { -BYTE byElementID; -BYTE len; -BYTE abyCCX[30]; +u8 byElementID; +u8 len; +u8 abyCCX[30]; } WLAN_IE_CCX, *PWLAN_IE_CCX; #pragma pack(1) typedef struct tagWLAN_IE_CCX_IP { -BYTE byElementID; -BYTE len; -BYTE abyCCXOUI[4]; -BYTE abyCCXIP[4]; -BYTE abyCCXREV[2]; +u8 byElementID; +u8 len; +u8 abyCCXOUI[4]; +u8 abyCCXIP[4]; +u8 abyCCXREV[2]; } WLAN_IE_CCX_IP, *PWLAN_IE_CCX_IP; #pragma pack(1) typedef struct tagWLAN_IE_CCX_Ver { -BYTE byElementID; -BYTE len; -BYTE abyCCXVer[5]; +u8 byElementID; +u8 len; +u8 abyCCXVer[5]; } WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver; /* ERP */ #pragma pack(1) typedef struct tagWLAN_IE_ERP { - BYTE byElementID; - BYTE len; - BYTE byContext; + u8 byElementID; + u8 len; + u8 byContext; } __attribute__ ((__packed__)) WLAN_IE_ERP, *PWLAN_IE_ERP; #pragma pack(1) typedef struct _MEASEURE_REQ { - BYTE byChannel; - BYTE abyStartTime[8]; - BYTE abyDuration[2]; + u8 byChannel; + u8 abyStartTime[8]; + u8 abyDuration[2]; } MEASEURE_REQ, *PMEASEURE_REQ, MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC, MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA, MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI; typedef struct _MEASEURE_REP_BASIC { - BYTE byChannel; - BYTE abyStartTime[8]; - BYTE abyDuration[2]; - BYTE byMap; + u8 byChannel; + u8 abyStartTime[8]; + u8 abyDuration[2]; + u8 byMap; } MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC; typedef struct _MEASEURE_REP_CCA { - BYTE byChannel; - BYTE abyStartTime[8]; - BYTE abyDuration[2]; - BYTE byCCABusyFraction; + u8 byChannel; + u8 abyStartTime[8]; + u8 abyDuration[2]; + u8 byCCABusyFraction; } MEASEURE_REP_CCA, *PMEASEURE_REP_CCA; typedef struct _MEASEURE_REP_RPI { - BYTE byChannel; - BYTE abyStartTime[8]; - BYTE abyDuration[2]; - BYTE abyRPIdensity[8]; + u8 byChannel; + u8 abyStartTime[8]; + u8 abyDuration[2]; + u8 abyRPIdensity[8]; } MEASEURE_REP_RPI, *PMEASEURE_REP_RPI; typedef union _MEASEURE_REP { @@ -410,85 +410,85 @@ typedef union _MEASEURE_REP { } MEASEURE_REP, *PMEASEURE_REP; typedef struct _WLAN_IE_MEASURE_REQ { - BYTE byElementID; - BYTE len; - BYTE byToken; - BYTE byMode; - BYTE byType; + u8 byElementID; + u8 len; + u8 byToken; + u8 byMode; + u8 byType; MEASEURE_REQ sReq; } WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ; typedef struct _WLAN_IE_MEASURE_REP { - BYTE byElementID; - BYTE len; - BYTE byToken; - BYTE byMode; - BYTE byType; + u8 byElementID; + u8 len; + u8 byToken; + u8 byMode; + u8 byType; MEASEURE_REP sRep; } WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP; typedef struct _WLAN_IE_CH_SW { - BYTE byElementID; - BYTE len; - BYTE byMode; - BYTE byChannel; - BYTE byCount; + u8 byElementID; + u8 len; + u8 byMode; + u8 byChannel; + u8 byCount; } WLAN_IE_CH_SW, *PWLAN_IE_CH_SW; typedef struct _WLAN_IE_QUIET { - BYTE byElementID; - BYTE len; - BYTE byQuietCount; - BYTE byQuietPeriod; - BYTE abyQuietDuration[2]; - BYTE abyQuietOffset[2]; + u8 byElementID; + u8 len; + u8 byQuietCount; + u8 byQuietPeriod; + u8 abyQuietDuration[2]; + u8 abyQuietOffset[2]; } WLAN_IE_QUIET, *PWLAN_IE_QUIET; typedef struct _WLAN_IE_COUNTRY { - BYTE byElementID; - BYTE len; - BYTE abyCountryString[3]; - BYTE abyCountryInfo[3]; + u8 byElementID; + u8 len; + u8 abyCountryString[3]; + u8 abyCountryInfo[3]; } WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY; typedef struct _WLAN_IE_PW_CONST { - BYTE byElementID; - BYTE len; - BYTE byPower; + u8 byElementID; + u8 len; + u8 byPower; } WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST; typedef struct _WLAN_IE_PW_CAP { - BYTE byElementID; - BYTE len; - BYTE byMinPower; - BYTE byMaxPower; + u8 byElementID; + u8 len; + u8 byMinPower; + u8 byMaxPower; } WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP; typedef struct _WLAN_IE_SUPP_CH { - BYTE byElementID; - BYTE len; - BYTE abyChannelTuple[2]; + u8 byElementID; + u8 len; + u8 abyChannelTuple[2]; } WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH; typedef struct _WLAN_IE_TPC_REQ { - BYTE byElementID; - BYTE len; + u8 byElementID; + u8 len; } WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ; typedef struct _WLAN_IE_TPC_REP { - BYTE byElementID; - BYTE len; - BYTE byTxPower; - BYTE byLinkMargin; + u8 byElementID; + u8 len; + u8 byTxPower; + u8 byLinkMargin; } WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP; typedef struct _WLAN_IE_IBSS_DFS { - BYTE byElementID; - BYTE len; - BYTE abyDFSOwner[6]; - BYTE byDFSRecovery; - BYTE abyChannelMap[2]; + u8 byElementID; + u8 len; + u8 abyDFSOwner[6]; + u8 byDFSRecovery; + u8 abyChannelMap[2]; } WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS; #pragma pack() @@ -500,7 +500,7 @@ typedef struct tagWLAN_FR_MGMT { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; } WLAN_FR_MGMT, *PWLAN_FR_MGMT; @@ -510,7 +510,7 @@ typedef struct tagWLAN_FR_BEACON { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ u64 *pqwTimestamp; @@ -541,7 +541,7 @@ typedef struct tagWLAN_FR_IBSSATIM { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ @@ -555,7 +555,7 @@ typedef struct tagWLAN_FR_DISASSOC { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwReason; @@ -568,7 +568,7 @@ typedef struct tagWLAN_FR_ASSOCREQ { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwCapInfo; @@ -592,7 +592,7 @@ typedef struct tagWLAN_FR_ASSOCRESP { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwCapInfo; @@ -609,7 +609,7 @@ typedef struct tagWLAN_FR_REASSOCREQ { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ @@ -634,7 +634,7 @@ typedef struct tagWLAN_FR_REASSOCRESP { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwCapInfo; @@ -651,7 +651,7 @@ typedef struct tagWLAN_FR_PROBEREQ { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ /* info elements */ @@ -666,7 +666,7 @@ typedef struct tagWLAN_FR_PROBERESP { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ u64 *pqwTimestamp; @@ -695,7 +695,7 @@ typedef struct tagWLAN_FR_AUTHEN { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwAuthAlgorithm; @@ -711,7 +711,7 @@ typedef struct tagWLAN_FR_DEAUTHEN { unsigned int uType; unsigned int len; - PBYTE pBuf; + u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ PWORD pwReason; diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index fb6124d9082a..688e6138d810 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -43,7 +43,7 @@ * SBOX Table */ -BYTE sbox_table[256] = { +u8 sbox_table[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, @@ -62,7 +62,7 @@ BYTE sbox_table[256] = { 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; -BYTE dot2_table[256] = { +u8 dot2_table[256] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, @@ -81,7 +81,7 @@ BYTE dot2_table[256] = { 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 }; -BYTE dot3_table[256] = { +u8 dot3_table[256] = { 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, @@ -106,7 +106,7 @@ BYTE dot3_table[256] = { /*--------------------- Export Functions --------------------------*/ -static void xor_128(BYTE *a, BYTE *b, BYTE *out) +static void xor_128(u8 *a, u8 *b, u8 *out) { PDWORD dwPtrA = (PDWORD) a; PDWORD dwPtrB = (PDWORD) b; @@ -119,7 +119,7 @@ static void xor_128(BYTE *a, BYTE *b, BYTE *out) } -static void xor_32(BYTE *a, BYTE *b, BYTE *out) +static void xor_32(u8 *a, u8 *b, u8 *out) { PDWORD dwPtrA = (PDWORD) a; PDWORD dwPtrB = (PDWORD) b; @@ -128,10 +128,10 @@ static void xor_32(BYTE *a, BYTE *b, BYTE *out) (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } -void AddRoundKey(BYTE *key, int round) +void AddRoundKey(u8 *key, int round) { - BYTE sbox_key[4]; - BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + u8 sbox_key[4]; + u8 rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; sbox_key[0] = sbox_table[key[13]]; sbox_key[1] = sbox_table[key[14]]; @@ -146,7 +146,7 @@ void AddRoundKey(BYTE *key, int round) xor_32(&key[12], &key[8], &key[12]); } -void SubBytes(BYTE *in, BYTE *out) +void SubBytes(u8 *in, u8 *out) { int i; @@ -154,7 +154,7 @@ void SubBytes(BYTE *in, BYTE *out) out[i] = sbox_table[in[i]]; } -void ShiftRows(BYTE *in, BYTE *out) +void ShiftRows(u8 *in, u8 *out) { out[0] = in[0]; out[1] = in[5]; @@ -174,7 +174,7 @@ void ShiftRows(BYTE *in, BYTE *out) out[15] = in[11]; } -void MixColumns(BYTE *in, BYTE *out) +void MixColumns(u8 *in, u8 *out) { out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; @@ -183,13 +183,13 @@ void MixColumns(BYTE *in, BYTE *out) out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; } -void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext) +void AESv128(u8 *key, u8 *data, u8 *ciphertext) { int i; int round; - BYTE TmpdataA[16]; - BYTE TmpdataB[16]; - BYTE abyRoundKey[16]; + u8 TmpdataA[16]; + u8 TmpdataB[16]; + u8 abyRoundKey[16]; for (i = 0; i < 16; i++) abyRoundKey[i] = key[i]; @@ -231,26 +231,26 @@ void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext) * */ -bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) +bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, WORD wFrameSize) { - BYTE abyNonce[13]; - BYTE MIC_IV[16]; - BYTE MIC_HDR1[16]; - BYTE MIC_HDR2[16]; - BYTE abyMIC[16]; - BYTE abyCTRPLD[16]; - BYTE abyTmp[16]; - BYTE abyPlainText[16]; - BYTE abyLastCipher[16]; + u8 abyNonce[13]; + u8 MIC_IV[16]; + u8 MIC_HDR1[16]; + u8 MIC_HDR2[16]; + u8 abyMIC[16]; + u8 abyCTRPLD[16]; + u8 abyTmp[16]; + u8 abyPlainText[16]; + u8 abyLastCipher[16]; PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; - PBYTE pbyIV; - PBYTE pbyPayload; + u8 * pbyIV; + u8 * pbyPayload; WORD wHLen = 22; /* 8 is IV, 8 is MIC, 4 is CRC */ WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN; bool bA4 = false; - BYTE byTmp; + u8 byTmp; WORD wCnt; int ii, jj, kk; @@ -276,15 +276,15 @@ bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) /* MIC_IV */ MIC_IV[0] = 0x59; memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); - MIC_IV[14] = (BYTE)(wPayloadSize >> 8); - MIC_IV[15] = (BYTE)(wPayloadSize & 0xff); + MIC_IV[14] = (u8)(wPayloadSize >> 8); + MIC_IV[15] = (u8)(wPayloadSize & 0xff); /* MIC_HDR1 */ - MIC_HDR1[0] = (BYTE)(wHLen >> 8); - MIC_HDR1[1] = (BYTE)(wHLen & 0xff); - byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff); + MIC_HDR1[0] = (u8)(wHLen >> 8); + MIC_HDR1[1] = (u8)(wHLen & 0xff); + byTmp = (u8)(pMACHeader->wFrameCtl & 0xff); MIC_HDR1[2] = byTmp & 0x8f; - byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8); + byTmp = (u8)(pMACHeader->wFrameCtl >> 8); byTmp &= 0x87; MIC_HDR1[3] = byTmp | 0x40; memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); @@ -292,7 +292,7 @@ bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) /* MIC_HDR2 */ memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); - byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff); + byTmp = (u8)(pMACHeader->wSeqCtl & 0xff); MIC_HDR2[6] = byTmp & 0x0f; MIC_HDR2[7] = 0; @@ -326,8 +326,8 @@ bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) for (jj = wPayloadSize; jj > 16; jj = jj-16) { - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + abyCTRPLD[14] = (u8) (wCnt >> 8); + abyCTRPLD[15] = (u8) (wCnt & 0xff); AESv128(pbyRxKey, abyCTRPLD, abyTmp); @@ -349,8 +349,8 @@ bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) for (ii = jj; ii < 16; ii++) abyLastCipher[ii] = 0x00; - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + abyCTRPLD[14] = (u8) (wCnt >> 8); + abyCTRPLD[15] = (u8) (wCnt & 0xff); AESv128(pbyRxKey, abyCTRPLD, abyTmp); for (kk = 0; kk < 16; kk++) @@ -370,8 +370,8 @@ bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) /* => above is the calculated MIC */ wCnt = 0; - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + abyCTRPLD[14] = (u8) (wCnt >> 8); + abyCTRPLD[15] = (u8) (wCnt & 0xff); AESv128(pbyRxKey, abyCTRPLD, abyTmp); for (kk = 0; kk < 8; kk++) diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h index a2e2c4e9a5c9..f5ea0f164774 100644 --- a/drivers/staging/vt6656/aes_ccmp.h +++ b/drivers/staging/vt6656/aes_ccmp.h @@ -41,6 +41,6 @@ /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ -bool AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize); +bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, WORD wFrameSize); #endif /* __AES_CCMP_H__ */ diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index a9f525e9d16e..ac33206715b3 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -66,7 +66,7 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ -BYTE abyVT3184_AGC[] = { +u8 abyVT3184_AGC[] = { 0x00, //0 0x00, //1 0x02, //2 @@ -134,7 +134,7 @@ BYTE abyVT3184_AGC[] = { }; -BYTE abyVT3184_AL2230[] = { +u8 abyVT3184_AL2230[] = { 0x31,//00 0x00, 0x00, @@ -396,7 +396,7 @@ BYTE abyVT3184_AL2230[] = { //{{RobertYu:20060515, new BB setting for VT3226D0 -BYTE abyVT3184_VT3226D0[] = { +u8 abyVT3184_VT3226D0[] = { 0x31,//00 0x00, 0x00, @@ -691,8 +691,8 @@ s_vClearSQ3Value(PSDevice pDevice); */ unsigned int BBuGetFrameTime( - BYTE byPreambleType, - BYTE byPktType, + u8 byPreambleType, + u8 byPktType, unsigned int cbFrameLength, WORD wRate ) @@ -964,10 +964,10 @@ int BBbVT3184Init(struct vnt_private *pDevice) { int ntStatus; WORD wLength; - PBYTE pbyAddr; - PBYTE pbyAgc; + u8 * pbyAddr; + u8 * pbyAgc; WORD wLengthAgc; - BYTE abyArray[256]; + u8 abyArray[256]; ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, @@ -1155,7 +1155,7 @@ else { */ void BBvLoopbackOn(struct vnt_private *pDevice) { - BYTE byData; + u8 byData; //CR C9 = 0x00 ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xC9, &pDevice->byBBCRc9);//CR201 @@ -1169,7 +1169,7 @@ void BBvLoopbackOn(struct vnt_private *pDevice) if (pDevice->wCurrentRate <= RATE_11M) { //CCK // Enable internal digital loopback: CR33 |= 0000 0001 ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33 - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData | 0x01));//CR33 + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (u8)(byData | 0x01));//CR33 // CR154 = 0x00 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, 0); //CR154 @@ -1178,7 +1178,7 @@ void BBvLoopbackOn(struct vnt_private *pDevice) else { //OFDM // Enable internal digital loopback:CR154 |= 0000 0001 ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154 - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData | 0x01));//CR154 + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (u8)(byData | 0x01));//CR154 // CR33 = 0x00 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, 0); //CR33 @@ -1190,7 +1190,7 @@ void BBvLoopbackOn(struct vnt_private *pDevice) // Disable TX_IQUN ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x09, &pDevice->byBBCR09); - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, (BYTE)(pDevice->byBBCR09 & 0xDE)); + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, (u8)(pDevice->byBBCR09 & 0xDE)); } /* @@ -1218,13 +1218,13 @@ void BBvLoopbackOff(struct vnt_private *pDevice) if (pDevice->wCurrentRate <= RATE_11M) { // CCK // Set the CR33 Bit2 to disable internal Loopback. ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33 - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData & 0xFE));//CR33 + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (u8)(byData & 0xFE));//CR33 } else { /* OFDM */ ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154 - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData & 0xFE));//CR154 + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (u8)(byData & 0xFE));//CR154 } ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x0E, &byData);//CR14 - ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, (BYTE)(byData | 0x80));//CR14 + ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, (u8)(byData | 0x80));//CR14 } @@ -1243,7 +1243,7 @@ void BBvLoopbackOff(struct vnt_private *pDevice) */ void BBvSetShortSlotTime(struct vnt_private *pDevice) { - BYTE byBBVGA=0; + u8 byBBVGA=0; if (pDevice->bShortSlotTime) pDevice->byBBRxConf &= 0xDF;//1101 1111 @@ -1258,7 +1258,7 @@ void BBvSetShortSlotTime(struct vnt_private *pDevice) } -void BBvSetVGAGainOffset(struct vnt_private *pDevice, BYTE byData) +void BBvSetVGAGainOffset(struct vnt_private *pDevice, u8 byData) { ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData); diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index fba61605a692..935b19f792e8 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -97,8 +97,8 @@ unsigned int BBuGetFrameTime( - BYTE byPreambleType, - BYTE byFreqType, + u8 byPreambleType, + u8 byFreqType, unsigned int cbFrameLength, WORD wRate ); diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index e214fcf83868..e08f719709a8 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -430,7 +430,7 @@ int BSSbInsertToBSSList(struct vnt_private *pDevice, unsigned int uLen = pRSNWPA->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((PBYTE) pRSNWPA - pbyIEs))) { + (unsigned int) (ULONG_PTR) ((u8 *) pRSNWPA - pbyIEs))) { pBSSList->wWPALen = uLen; memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); WPA_ParseRSN(pBSSList, pRSNWPA); @@ -443,7 +443,7 @@ int BSSbInsertToBSSList(struct vnt_private *pDevice, unsigned int uLen = pRSN->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((PBYTE) pRSN - pbyIEs))) { + (unsigned int) (ULONG_PTR) ((u8 *) pRSN - pbyIEs))) { pBSSList->wRSNLen = uLen; memcpy(pBSSList->byRSNIE, pRSN, uLen); WPA2vParseRSN(pBSSList, pRSN); @@ -483,7 +483,7 @@ int BSSbInsertToBSSList(struct vnt_private *pDevice, if (pDevice->bUpdateBBVGA) { // Monitor if RSSI is too strong. pBSSList->byRSSIStatCnt = 0; - RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); + RFvRSSITodBm(pDevice, (u8)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; pBSSList->ldBmAverRange = pBSSList->ldBmMAX; for (ii = 1; ii < RSSI_STAT_COUNT; ii++) @@ -592,7 +592,7 @@ int BSSbUpdateToBSSList(struct vnt_private *pDevice, if (pRSNWPA != NULL) { unsigned int uLen = pRSNWPA->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((PBYTE) pRSNWPA - pbyIEs))) { + (unsigned int) (ULONG_PTR) ((u8 *) pRSNWPA - pbyIEs))) { pBSSList->wWPALen = uLen; memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); WPA_ParseRSN(pBSSList, pRSNWPA); @@ -604,7 +604,7 @@ int BSSbUpdateToBSSList(struct vnt_private *pDevice, if (pRSN != NULL) { unsigned int uLen = pRSN->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((PBYTE) pRSN - pbyIEs))) { + (unsigned int) (ULONG_PTR) ((u8 *) pRSN - pbyIEs))) { pBSSList->wRSNLen = uLen; memcpy(pBSSList->byRSNIE, pRSN, uLen); WPA2vParseRSN(pBSSList, pRSN); @@ -612,7 +612,7 @@ int BSSbUpdateToBSSList(struct vnt_private *pDevice, } if (pRxPacket->uRSSI != 0) { - RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &ldBm); + RFvRSSITodBm(pDevice, (u8)(pRxPacket->uRSSI), &ldBm); // Monitor if RSSI is too strong. pBSSList->byRSSIStatCnt++; pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; @@ -1207,7 +1207,7 @@ void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, byTxRetry = (byTSR & 0xF0) >> 4; wRate = (WORD) (byPktNO & 0xF0) >> 4; wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl; - pbyDestAddr = (PBYTE) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]); + pbyDestAddr = (u8 *) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]); if (wFIFOCtl & FIFOCTL_AUTO_FB_0) { byFallBack = AUTO_FB_0; @@ -1433,7 +1433,7 @@ if(pDevice->bLinkPass !=true) } else { - RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); + RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); if(-ldBm < 50) { RssiRatio = 4000; } @@ -1473,7 +1473,7 @@ static void s_vCheckPreEDThreshold(struct vnt_private *pDevice) ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); if (pBSSList != NULL) { - pDevice->byBBPreEDRSSI = (BYTE) (~(pBSSList->ldBmAverRange) + 1); + pDevice->byBBPreEDRSSI = (u8) (~(pBSSList->ldBmAverRange) + 1); BBvUpdatePreEDThreshold(pDevice, false); } } diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 08091a0a7c40..d329f4bbe6e7 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -80,7 +80,7 @@ typedef struct tagSERPObject { bool bERPExist; - BYTE byERP; + u8 byERP; } ERPObject, *PERPObject; @@ -93,19 +93,19 @@ typedef struct tagSRSNCapObject { typedef struct tagKnownBSS { // BSS info bool bActive; - BYTE abyBSSID[WLAN_BSSID_LEN]; + u8 abyBSSID[WLAN_BSSID_LEN]; unsigned int uChannel; - BYTE abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - BYTE abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + u8 abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + u8 abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; unsigned int uRSSI; - BYTE bySQ; + u8 bySQ; WORD wBeaconInterval; WORD wCapInfo; - BYTE abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - BYTE byRxRate; + u8 abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + u8 byRxRate; // WORD wATIMWindow; - BYTE byRSSIStatCnt; + u8 byRSSIStatCnt; signed long ldBmMAX; signed long ldBmAverage[RSSI_STAT_COUNT]; signed long ldBmAverRange; @@ -114,32 +114,32 @@ typedef struct tagKnownBSS { //++ WPA informations bool bWPAValid; - BYTE byGKType; - BYTE abyPKType[4]; + u8 byGKType; + u8 abyPKType[4]; WORD wPKCount; - BYTE abyAuthType[4]; + u8 abyAuthType[4]; WORD wAuthCount; - BYTE byDefaultK_as_PK; - BYTE byReplayIdx; + u8 byDefaultK_as_PK; + u8 byReplayIdx; //-- //++ WPA2 informations bool bWPA2Valid; - BYTE byCSSGK; + u8 byCSSGK; WORD wCSSPKCount; - BYTE abyCSSPK[4]; + u8 abyCSSPK[4]; WORD wAKMSSAuthCount; - BYTE abyAKMSSAuthType[4]; + u8 abyAKMSSAuthType[4]; //++ wpactl - BYTE byWPAIE[MAX_WPA_IE_LEN]; - BYTE byRSNIE[MAX_WPA_IE_LEN]; + u8 byWPAIE[MAX_WPA_IE_LEN]; + u8 byRSNIE[MAX_WPA_IE_LEN]; WORD wWPALen; WORD wRSNLen; // Clear count unsigned int uClearCount; -// BYTE abyIEs[WLAN_BEACON_FR_MAXLEN]; +// u8 abyIEs[WLAN_BEACON_FR_MAXLEN]; unsigned int uIELength; u64 qwBSSTimestamp; u64 qwLocalTSF;/* local TSF timer */ @@ -148,7 +148,7 @@ typedef struct tagKnownBSS { ERPObject sERP; SRSNCapObject sRSNCapObj; - BYTE abyIEs[1024]; // don't move this field !! + u8 abyIEs[1024]; // don't move this field !! } __attribute__ ((__packed__)) KnownBSS , *PKnownBSS; @@ -168,9 +168,9 @@ typedef enum tagNODE_STATE { typedef struct tagKnownNodeDB { // STA info bool bActive; - BYTE abyMACAddr[WLAN_ADDR_LEN]; - BYTE abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - BYTE abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; + u8 abyMACAddr[WLAN_ADDR_LEN]; + u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; + u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; WORD wTxDataRate; bool bShortPreamble; bool bERPExist; @@ -179,8 +179,8 @@ typedef struct tagKnownNodeDB { WORD wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. WORD wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. WORD wSuppRate; - BYTE byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode - BYTE byTopCCKBasicRate; //Records the highest basic rate in CCK mode + u8 byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode + u8 byTopCCKBasicRate; //Records the highest basic rate in CCK mode // For AP mode struct sk_buff_head sTxPSQueue; @@ -190,21 +190,21 @@ typedef struct tagKnownNodeDB { NODE_STATE eNodeState; bool bPSEnable; bool bRxPSPoll; - BYTE byAuthSequence; + u8 byAuthSequence; unsigned long ulLastRxJiffer; - BYTE bySuppRate; + u8 bySuppRate; DWORD dwFlags; WORD wEnQueueCnt; bool bOnFly; unsigned long long KeyRSC; - BYTE byKeyIndex; + u8 byKeyIndex; DWORD dwKeyIndex; - BYTE byCipherSuite; + u8 byCipherSuite; DWORD dwTSC47_16; WORD wTSC15_0; unsigned int uWepKeyLength; - BYTE abyWepKey[WLAN_WEPMAX_KEYLEN]; + u8 abyWepKey[WLAN_WEPMAX_KEYLEN]; // // Auto rate fallback vars bool bIsInFallback; @@ -270,7 +270,7 @@ int BSSbUpdateToBSSList(struct vnt_private *, u8 *pbyIEs, void *pRxPacketContext); -int BSSbIsSTAInNodeDB(struct vnt_private *, PBYTE abyDstAddr, +int BSSbIsSTAInNodeDB(struct vnt_private *, u8 * abyDstAddr, u32 *puNodeIndex); void BSSvCreateOneNode(struct vnt_private *, u32 *puNodeIndex); diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 22918a106d73..2cd120ba4576 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -133,7 +133,7 @@ void CARDbSetMediaChannel(struct vnt_private *pDevice, u32 uConnectionChannel) pDevice->byCurPwr = 0xFF; RFbRawSetPower(pDevice, pDevice->abyCCKPwrTbl[uConnectionChannel-1], RATE_1M); } - ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(BYTE)(uConnectionChannel|0x80)); + ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(u8)(uConnectionChannel|0x80)); } /* @@ -221,9 +221,9 @@ static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx) void CARDvCalculateOFDMRParameter ( WORD wRate, - BYTE byBBType, - PBYTE pbyTxRate, - PBYTE pbyRsvTime + u8 byBBType, + u8 * pbyTxRate, + u8 * pbyRsvTime ) { switch (wRate) { @@ -434,23 +434,23 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 byBBType) &abyTxRate[8], &abyRsvTime[8]); - abyData[0] = (BYTE)(awLen[0]&0xFF); - abyData[1] = (BYTE)(awLen[0]>>8); + abyData[0] = (u8)(awLen[0]&0xFF); + abyData[1] = (u8)(awLen[0]>>8); abyData[2] = abySignal[0]; abyData[3] = abyServ[0]; - abyData[4] = (BYTE)(awLen[1]&0xFF); - abyData[5] = (BYTE)(awLen[1]>>8); + abyData[4] = (u8)(awLen[1]&0xFF); + abyData[5] = (u8)(awLen[1]>>8); abyData[6] = abySignal[1]; abyData[7] = abyServ[1]; - abyData[8] = (BYTE)(awLen[2]&0xFF); - abyData[9] = (BYTE)(awLen[2]>>8); + abyData[8] = (u8)(awLen[2]&0xFF); + abyData[9] = (u8)(awLen[2]>>8); abyData[10] = abySignal[2]; abyData[11] = abyServ[2]; - abyData[12] = (BYTE)(awLen[3]&0xFF); - abyData[13] = (BYTE)(awLen[3]>>8); + abyData[12] = (u8)(awLen[3]&0xFF); + abyData[13] = (u8)(awLen[3]>>8); abyData[14] = abySignal[3]; abyData[15] = abyServ[3]; @@ -500,7 +500,7 @@ void vUpdateIFS(struct vnt_private *pDevice) byMaxMin = 5; } else {// PK_TYPE_11GA & PK_TYPE_11GB - BYTE byRate = 0; + u8 byRate = 0; bool bOFDMRate = false; unsigned int ii = 0; PWLAN_IE_SUPP_RATES pItemRates = NULL; @@ -515,7 +515,7 @@ void vUpdateIFS(struct vnt_private *pDevice) pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt.abyCurrSuppRates; for (ii = 0; ii < pItemRates->len; ii++) { - byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F); + byRate = (u8)(pItemRates->abyRates[ii]&0x7F); if (RATEwGetRateIdx(byRate) > RATE_11M) { bOFDMRate = true; break; @@ -525,7 +525,7 @@ void vUpdateIFS(struct vnt_private *pDevice) pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt .abyCurrExtSuppRates; for (ii = 0; ii < pItemRates->len; ii++) { - byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F); + byRate = (u8)(pItemRates->abyRates[ii]&0x7F); if (RATEwGetRateIdx(byRate) > RATE_11M) { bOFDMRate = true; break; @@ -544,10 +544,10 @@ void vUpdateIFS(struct vnt_private *pDevice) pDevice->uCwMax = C_CWMAX; pDevice->uEIFS = C_EIFS; - byData[0] = (BYTE)pDevice->uSIFS; - byData[1] = (BYTE)pDevice->uDIFS; - byData[2] = (BYTE)pDevice->uEIFS; - byData[3] = (BYTE)pDevice->uSlot; + byData[0] = (u8)pDevice->uSIFS; + byData[1] = (u8)pDevice->uDIFS; + byData[2] = (u8)pDevice->uEIFS; + byData[3] = (u8)pDevice->uSlot; CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, @@ -627,7 +627,7 @@ u8 CARDbyGetPktType(struct vnt_private *pDevice) { if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) { - return (BYTE)pDevice->byBBType; + return (u8)pDevice->byBBType; } else if (CARDbIsOFDMinBasicRate(pDevice)) { return PK_TYPE_11GA; @@ -653,7 +653,7 @@ u8 CARDbyGetPktType(struct vnt_private *pDevice) * Return Value: TSF Offset value * */ -u64 CARDqGetTSFOffset(BYTE byRxRate, u64 qwTSF1, u64 qwTSF2) +u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2) { u64 qwTSFOffset = 0; WORD wRxBcnTSFOffst = 0; @@ -996,7 +996,7 @@ void CARDvSetBSSMode(struct vnt_private *pDevice) } vUpdateIFS(pDevice); - CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); + CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType); if ( pDevice->byBBType == BB_TYPE_11A ) { //request by Jack 2005-04-26 diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 5123bc7d0dcd..146b51b59ec0 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -74,7 +74,7 @@ void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, WORD wBeaconInterval); void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF, WORD wBeaconInterval); u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval); -u64 CARDqGetTSFOffset(BYTE byRxRate, u64 qwTSF1, u64 qwTSF2); +u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2); int CARDbRadioPowerOff(struct vnt_private *pDevice); int CARDbRadioPowerOn(struct vnt_private *pDevice); u8 CARDbyGetPktType(struct vnt_private *pDevice); diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index 4181e3e12ea9..9421c5dc60a6 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -116,10 +116,10 @@ static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] = ************************************************************************/ static struct { - BYTE byChannelCountryCode; /* The country code */ + u8 byChannelCountryCode; /* The country code */ char chCountryCode[2]; - BYTE bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */ - BYTE byPower[CB_MAX_CHANNEL]; + u8 bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */ + u8 byPower[CB_MAX_CHANNEL]; } ChannelRuleTab[] = { /************************************************************************ @@ -425,7 +425,7 @@ exit: bool CHvChannelGetList ( unsigned int uCountryCodeIdx, - PBYTE pbyChannelTable + u8 * pbyChannelTable ) { if (uCountryCodeIdx >= CCODE_MAX) { @@ -508,10 +508,10 @@ void CHvInitChannelTable(struct vnt_private *pDevice) } } -BYTE CHbyGetChannelMapping(BYTE byChannelNumber) +u8 CHbyGetChannelMapping(u8 byChannelNumber) { -BYTE ii; -BYTE byCHMapping = 0; +u8 ii; +u8 byCHMapping = 0; for (ii = 1; ii <= CB_MAX_CHANNEL; ii++) { if (sChannelTbl[ii].byChannelNumber == byChannelNumber) diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 9914dba0ba0c..30cd46dcb2b1 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -38,7 +38,7 @@ /*--------------------- Export Classes ----------------------------*/ typedef struct tagSChannelTblElement { - BYTE byChannelNumber; + u8 byChannelNumber; unsigned int uFrequency; bool bValid; } SChannelTblElement, *PSChannelTblElement; @@ -49,8 +49,8 @@ typedef struct tagSChannelTblElement { bool ChannelValid(unsigned int CountryCode, unsigned int ChannelNum); void CHvInitChannelTable(struct vnt_private *pDevice); -BYTE CHbyGetChannelMapping(BYTE byChannelNumber); +u8 CHbyGetChannelMapping(u8 byChannelNumber); -bool CHvChannelGetList(unsigned int uCountryCodeIdx, PBYTE pbyChannelTable); +bool CHvChannelGetList(unsigned int uCountryCodeIdx, u8 * pbyChannelTable); #endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index 77464e819f6d..7314f2bc2504 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -57,7 +57,7 @@ /* static int msglevel = MSG_LEVEL_DEBUG; */ static int msglevel =MSG_LEVEL_INFO; -const BYTE acbyIERate[MAX_RATE] = +const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; #define AUTORATE_TXOK_CNT 0x0400 @@ -70,7 +70,7 @@ void s_vResetCounter(PKnownNodeDB psNodeDBTable); void s_vResetCounter(PKnownNodeDB psNodeDBTable) { - BYTE ii; + u8 ii; /* clear statistics counter for auto_rate */ for (ii = 0; ii <= MAX_RATE; ii++) { @@ -92,19 +92,19 @@ void s_vResetCounter(PKnownNodeDB psNodeDBTable) * * Parameters: * In: - * BYTE - Rate value in SuppRates IE or ExtSuppRates IE + * u8 - Rate value in SuppRates IE or ExtSuppRates IE * Out: * none * * Return Value: RateIdx * -*/ -BYTE +u8 DATARATEbyGetRateIdx ( - BYTE byRate + u8 byRate ) { - BYTE ii; + u8 ii; /* erase BasicRate flag */ byRate = byRate & 0x7F; @@ -146,7 +146,7 @@ DATARATEbyGetRateIdx ( * * Parameters: * In: - * BYTE - Rate value in SuppRates IE or ExtSuppRates IE + * u8 - Rate value in SuppRates IE or ExtSuppRates IE * Out: * none * @@ -155,7 +155,7 @@ DATARATEbyGetRateIdx ( -*/ WORD RATEwGetRateIdx( - BYTE byRate + u8 byRate ) { WORD ii; @@ -216,7 +216,7 @@ void RATEvParseMaxRate(struct vnt_private *pDevice, } for (ii = 0; ii < uRateLen; ii++) { - byRate = (BYTE)(pItemRates->abyRates[ii]); + byRate = (u8)(pItemRates->abyRates[ii]); if (WLAN_MGMT_IS_BASICRATE(byRate) && (bUpdateBasicRate == true)) { /* @@ -226,7 +226,7 @@ void RATEvParseMaxRate(struct vnt_private *pDevice, CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate)); } - byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F); + byRate = (u8)(pItemRates->abyRates[ii]&0x7F); if (byHighSuppRate == 0) byHighSuppRate = byRate; if (byRate > byHighSuppRate) @@ -242,7 +242,7 @@ void RATEvParseMaxRate(struct vnt_private *pDevice, uExtRateLen = WLAN_RATES_MAXLEN; for (ii = 0; ii < uExtRateLen ; ii++) { - byRate = (BYTE)(pItemExtRates->abyRates[ii]); + byRate = (u8)(pItemExtRates->abyRates[ii]); /* select highest basic rate */ if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { /* @@ -252,7 +252,7 @@ void RATEvParseMaxRate(struct vnt_private *pDevice, CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate)); } - byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F); + byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F); if (byHighSuppRate == 0) byHighSuppRate = byRate; if (byRate > byHighSuppRate) @@ -400,7 +400,7 @@ void RATEvTxRateFallBack(struct vnt_private *pDevice, * Return Value: None * -*/ -BYTE +u8 RATEuSetIE ( PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates, @@ -423,6 +423,6 @@ RATEuSetIE ( } } } - return (BYTE)uRateCnt; + return (u8)uRateCnt; } diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 8dc55bd61669..355e51f3ff16 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -77,7 +77,7 @@ void RATEvParseMaxRate(struct vnt_private *, PWLAN_IE_SUPP_RATES pItemRates, void RATEvTxRateFallBack(struct vnt_private *pDevice, PKnownNodeDB psNodeDBTable); -BYTE +u8 RATEuSetIE( PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates, @@ -86,13 +86,13 @@ RATEuSetIE( WORD RATEwGetRateIdx( - BYTE byRate + u8 byRate ); -BYTE +u8 DATARATEbyGetRateIdx( - BYTE byRate + u8 byRate ); #endif /* __DATARATE_H__ */ diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index 0c0b614aaa11..bfbaccd63012 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -190,19 +190,19 @@ typedef const SRrvTime_atim *PCSRrvTime_atim; typedef struct tagSRTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[ETH_ALEN]; - BYTE abyTA[ETH_ALEN]; + u8 abyRA[ETH_ALEN]; + u8 abyTA[ETH_ALEN]; } __attribute__ ((__packed__)) SRTSData, *PSRTSData; typedef const SRTSData *PCSRTSData; typedef struct tagSRTS_g { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_ba; WORD wDuration_aa; @@ -214,11 +214,11 @@ SRTS_g, *PSRTS_g; typedef const SRTS_g *PCSRTS_g; typedef struct tagSRTS_g_FB { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_ba; WORD wDuration_aa; @@ -235,8 +235,8 @@ SRTS_g_FB, *PSRTS_g_FB; typedef const SRTS_g_FB *PCSRTS_g_FB; typedef struct tagSRTS_ab { - BYTE bySignalField; - BYTE byServiceField; + u8 bySignalField; + u8 byServiceField; WORD wTransmitLength; WORD wDuration; WORD wReserved; @@ -247,8 +247,8 @@ SRTS_ab, *PSRTS_ab; typedef const SRTS_ab *PCSRTS_ab; typedef struct tagSRTS_a_FB { - BYTE bySignalField; - BYTE byServiceField; + u8 bySignalField; + u8 byServiceField; WORD wTransmitLength; WORD wDuration; WORD wReserved; @@ -266,14 +266,14 @@ typedef const SRTS_a_FB *PCSRTS_a_FB; typedef struct tagSCTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[ETH_ALEN]; + u8 abyRA[ETH_ALEN]; WORD wReserved; } __attribute__ ((__packed__)) SCTSData, *PSCTSData; typedef struct tagSCTS { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; WORD wDuration_ba; WORD wReserved; @@ -284,8 +284,8 @@ SCTS, *PSCTS; typedef const SCTS *PCSCTS; typedef struct tagSCTS_FB { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; WORD wDuration_ba; WORD wReserved; @@ -321,11 +321,11 @@ typedef const STxShortBufHead *PCSTxShortBufHead; * TX data header */ typedef struct tagSTxDataHead_g { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -337,11 +337,11 @@ STxDataHead_g, *PSTxDataHead_g; typedef const STxDataHead_g *PCSTxDataHead_g; typedef struct tagSTxDataHead_g_FB { - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -354,8 +354,8 @@ STxDataHead_g_FB, *PSTxDataHead_g_FB; typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB; typedef struct tagSTxDataHead_ab { - BYTE bySignalField; - BYTE byServiceField; + u8 bySignalField; + u8 byServiceField; WORD wTransmitLength; WORD wDuration; WORD wTimeStampOff; @@ -364,8 +364,8 @@ STxDataHead_ab, *PSTxDataHead_ab; typedef const STxDataHead_ab *PCSTxDataHead_ab; typedef struct tagSTxDataHead_a_FB { - BYTE bySignalField; - BYTE byServiceField; + u8 bySignalField; + u8 byServiceField; WORD wTransmitLength; WORD wDuration; WORD wTimeStampOff; @@ -397,14 +397,14 @@ SBEACONCtl; typedef struct tagSSecretKey { u32 dwLowDword; - BYTE byHighByte; + u8 byHighByte; } __attribute__ ((__packed__)) SSecretKey; typedef struct tagSKeyEntry { - BYTE abyAddrHi[2]; + u8 abyAddrHi[2]; WORD wKCTL; - BYTE abyAddrLo[4]; + u8 abyAddrLo[4]; u32 dwKey0[4]; u32 dwKey1[4]; u32 dwKey2[4]; diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 6bba2e06fa64..486de1e25a58 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -212,7 +212,7 @@ typedef struct _DEFAULT_CONFIG { */ typedef struct { unsigned int uDataLen; - PBYTE pDataBuf; + u8 * pDataBuf; /* struct urb *pUrb; */ bool bInUse; } INT_BUFFER, *PINT_BUFFER; @@ -310,14 +310,14 @@ typedef struct tagSPMKIDCandidateEvent { typedef struct tagSQuietControl { bool bEnable; DWORD dwStartTime; - BYTE byPeriod; + u8 byPeriod; WORD wDuration; } SQuietControl, *PSQuietControl; /* The receive duplicate detection cache entry */ typedef struct tagSCacheEntry{ WORD wFmSequence; - BYTE abyAddr2[ETH_ALEN]; + u8 abyAddr2[ETH_ALEN]; WORD wFrameCtl; } SCacheEntry, *PSCacheEntry; @@ -337,10 +337,10 @@ typedef struct tagSDeFragControlBlock { WORD wSequence; WORD wFragNum; - BYTE abyAddr2[ETH_ALEN]; + u8 abyAddr2[ETH_ALEN]; unsigned int uLifetime; struct sk_buff* skb; - PBYTE pbyRxBuffer; + u8 * pbyRxBuffer; unsigned int cbFrameLength; bool bInUse; } SDeFragControlBlock, *PSDeFragControlBlock; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e83f95e1d9a8..e53b77b393a9 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -64,7 +64,7 @@ //static int msglevel =MSG_LEVEL_DEBUG; static int msglevel =MSG_LEVEL_INFO; -const BYTE acbyRxRate[MAX_RATE] = +const u8 acbyRxRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; @@ -74,12 +74,12 @@ const BYTE acbyRxRate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ -static BYTE s_byGetRateIdx(BYTE byRate); +static u8 s_byGetRateIdx(u8 byRate); static void s_vGetDASA( - PBYTE pbyRxBufferAddr, + u8 * pbyRxBufferAddr, unsigned int *pcbHeaderSize, PSEthernetHeader psEthHeader ); @@ -135,7 +135,7 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - s_vGetDASA((PBYTE)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); + s_vGetDASA((u8 *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); if (bIsWEP) { if (bExtIV) { @@ -150,7 +150,7 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, cbHeaderSize += WLAN_HDR_ADDR3_LEN; }; - pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize); + pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize); if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) { cbHeaderSize += 6; } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { @@ -188,7 +188,7 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, } cbHeaderSize -= (ETH_ALEN * 2); - pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize); + pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize); for (ii = 0; ii < ETH_ALEN; ii++) *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii]; for (ii = 0; ii < ETH_ALEN; ii++) @@ -200,9 +200,9 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, -static BYTE s_byGetRateIdx(BYTE byRate) +static u8 s_byGetRateIdx(u8 byRate) { - BYTE byRateIdx; + u8 byRateIdx; for (byRateIdx = 0; byRateIdx data); + pbyDAddress = (u8 *)(skb->data); pbyRxSts = pbyDAddress+4; pbyRxRate = pbyDAddress+5; @@ -407,7 +407,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, // Use for TKIP MIC s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader); - if (!compare_ether_addr((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), + if (!compare_ether_addr((u8 *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr)) return false; @@ -415,7 +415,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (PS802_11Header) (pbyFrame); // get SA NodeIndex - if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) { + if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->abyAddr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; } @@ -529,8 +529,8 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, // Handle Control & Manage Frame if (IS_TYPE_MGMT((pbyFrame))) { - PBYTE pbyData1; - PBYTE pbyData2; + u8 * pbyData1; + u8 * pbyData2; pRxPacket = &(pRCB->sMngPacket); pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame); @@ -622,9 +622,9 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, } //mike add:station mode check eapol-key challenge---> { - BYTE Protocol_Version; //802.1x Authentication - BYTE Packet_Type; //802.1x Authentication - BYTE Descriptor_type; + u8 Protocol_Version; //802.1x Authentication + u8 Packet_Type; //802.1x Authentication + u8 Descriptor_type; WORD Key_info; if (bIsWEP) cbIVOffset = 8; @@ -703,7 +703,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, // ----------------------------------------------- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)){ - BYTE abyMacHdr[24]; + u8 abyMacHdr[24]; // Only 802.1x packet incoming allowed if (bIsWEP) @@ -776,11 +776,11 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, } MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((PBYTE)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); + MIC_vAppend((u8 *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; - MIC_vAppend((PBYTE)&dwMIC_Priority, 4); + MIC_vAppend((u8 *)&dwMIC_Priority, 4); // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. - MIC_vAppend((PBYTE)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8), + MIC_vAppend((u8 *)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8), FrameSize - WLAN_HDR_ADDR3_LEN - 8); MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); MIC_vUnInit(); @@ -877,7 +877,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, } // ----- End of Reply Counter Check -------------------------- - s_vProcessRxMACHeader(pDevice, (PBYTE)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); + s_vProcessRxMACHeader(pDevice, (u8 *)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); FrameSize -= cbHeaderOffset; cbHeaderOffset += 8; // 8 is Rcv buffer header @@ -946,7 +946,7 @@ static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame, // reason = (6) class 2 received from nonauth sta vMgrDeAuthenBeginSta(pDevice, pMgmt, - (PBYTE)(p802_11Header->abyAddr2), + (u8 *)(p802_11Header->abyAddr2), (WLAN_MGMT_REASON_CLASS2_NONAUTH), &Status ); @@ -958,7 +958,7 @@ static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame, // reason = (7) class 3 received from nonassoc sta vMgrDisassocBeginSta(pDevice, pMgmt, - (PBYTE)(p802_11Header->abyAddr2), + (u8 *)(p802_11Header->abyAddr2), (WLAN_MGMT_REASON_CLASS3_NONASSOC), &Status ); @@ -1011,7 +1011,7 @@ static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame, else { vMgrDeAuthenBeginSta(pDevice, pMgmt, - (PBYTE)(p802_11Header->abyAddr2), + (u8 *)(p802_11Header->abyAddr2), (WLAN_MGMT_REASON_CLASS2_NONAUTH), &Status ); @@ -1301,7 +1301,7 @@ static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb, if (FrameSize > CB_MAX_BUF_SIZE) return false; // check DA - if (is_multicast_ether_addr((PBYTE)(skb->data+cbHeaderOffset))) { + if (is_multicast_ether_addr((u8 *)(skb->data+cbHeaderOffset))) { if (pMgmt->sNodeDBTable[0].bPSEnable) { skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); @@ -1326,7 +1326,7 @@ static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb, } else { // check if relay - if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data+cbHeaderOffset), &iDANodeIndex)) { + if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { // queue this skb until next PS tx, and then release. @@ -1356,7 +1356,7 @@ static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb, iDANodeIndex = 0; if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) { - bRelayPacketSend(pDevice, (PBYTE) (skb->data + cbHeaderOffset), + bRelayPacketSend(pDevice, (u8 *) (skb->data + cbHeaderOffset), FrameSize, (unsigned int) iDANodeIndex); } diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 4371a77e9adc..d5d99fbaf9a3 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -142,7 +142,7 @@ int FIRMWAREbCheckVersion(struct vnt_private *pDevice) 0, MESSAGE_REQUEST_VERSION, 2, - (PBYTE) &(pDevice->wFirmwareVersion)); + (u8 *) &(pDevice->wFirmwareVersion)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion); if (ntStatus != STATUS_SUCCESS) { diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index bc5e9da47586..ab828b58dde7 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -491,7 +491,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, dwKeyIndex = (DWORD)(param->u.crypt.idx); if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { - pDevice->byKeyIndex = (BYTE)dwKeyIndex; + pDevice->byKeyIndex = (u8)dwKeyIndex; pDevice->bTransmitKey = true; dwKeyIndex |= (1 << 31); } @@ -515,7 +515,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, ¶m->sta_addr[0], dwKeyIndex & ~(USE_KEYRSC), param->u.crypt.key_len, - &KeyRSC, (PBYTE)abyKey, + &KeyRSC, (u8 *)abyKey, KEY_CTL_WEP ) == true) { @@ -585,7 +585,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, dwKeyIndex, param->u.crypt.key_len, &KeyRSC, - (PBYTE)abyKey, + (u8 *)abyKey, byKeyDecMode ) == true) { @@ -670,7 +670,7 @@ static int hostap_get_encryption(struct vnt_private *pDevice, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); memset(param->u.crypt.seq, 0, 8); for (ii = 0 ; ii < 8 ; ii++) { - param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); + param->u.crypt.seq[ii] = (u8)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); } return ret; diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 51990bd3dd45..ed2222fd43b1 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -98,8 +98,8 @@ void INTnsProcessData(struct vnt_private *pDevice) pINTData = (PSINTData) pDevice->intBuf.pDataBuf; if (pINTData->byTSR0 & TSR_VALID) { STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (BYTE)(pINTData->byPkt0 & 0x0F), - (BYTE)(pINTData->byPkt0>>4), + (u8)(pINTData->byPkt0 & 0x0F), + (u8)(pINTData->byPkt0>>4), pINTData->byTSR0); BSSvUpdateNodeTxCounter(pDevice, &(pDevice->scStatistic), @@ -109,8 +109,8 @@ void INTnsProcessData(struct vnt_private *pDevice) } if (pINTData->byTSR1 & TSR_VALID) { STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (BYTE)(pINTData->byPkt1 & 0x0F), - (BYTE)(pINTData->byPkt1>>4), + (u8)(pINTData->byPkt1 & 0x0F), + (u8)(pINTData->byPkt1>>4), pINTData->byTSR1); BSSvUpdateNodeTxCounter(pDevice, &(pDevice->scStatistic), @@ -120,8 +120,8 @@ void INTnsProcessData(struct vnt_private *pDevice) } if (pINTData->byTSR2 & TSR_VALID) { STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (BYTE)(pINTData->byPkt2 & 0x0F), - (BYTE)(pINTData->byPkt2>>4), + (u8)(pINTData->byPkt2 & 0x0F), + (u8)(pINTData->byPkt2>>4), pINTData->byTSR2); BSSvUpdateNodeTxCounter(pDevice, &(pDevice->scStatistic), @@ -131,8 +131,8 @@ void INTnsProcessData(struct vnt_private *pDevice) } if (pINTData->byTSR3 & TSR_VALID) { STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (BYTE)(pINTData->byPkt3 & 0x0F), - (BYTE)(pINTData->byPkt3>>4), + (u8)(pINTData->byPkt3 & 0x0F), + (u8)(pINTData->byPkt3>>4), pINTData->byTSR3); BSSvUpdateNodeTxCounter(pDevice, &(pDevice->scStatistic), diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 27c725f1ce11..b8a79433d4d2 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -35,26 +35,26 @@ /*--------------------- Export Definitions -------------------------*/ typedef struct tagSINTData { - BYTE byTSR0; - BYTE byPkt0; + u8 byTSR0; + u8 byPkt0; WORD wTime0; - BYTE byTSR1; - BYTE byPkt1; + u8 byTSR1; + u8 byPkt1; WORD wTime1; - BYTE byTSR2; - BYTE byPkt2; + u8 byTSR2; + u8 byPkt2; WORD wTime2; - BYTE byTSR3; - BYTE byPkt3; + u8 byTSR3; + u8 byPkt3; WORD wTime3; u64 qwTSF; - BYTE byISR0; - BYTE byISR1; - BYTE byRTSSuccess; - BYTE byRTSFail; - BYTE byACKFail; - BYTE byFCSErr; - BYTE abySW[2]; + u8 byISR0; + u8 byISR1; + u8 byRTSSuccess; + u8 byRTSFail; + u8 byACKFail; + u8 byFCSErr; + u8 abySW[2]; } __attribute__ ((__packed__)) SINTData, *PSINTData; diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 69971f35e490..598c1386c0e2 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -61,8 +61,8 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) pDevice->wstats.status = pDevice->eOPMode; if (pDevice->scStatistic.LinkQuality > 100) pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual =(BYTE)pDevice->scStatistic.LinkQuality; - RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); + pDevice->wstats.qual.qual =(u8)pDevice->scStatistic.LinkQuality; + RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; pDevice->wstats.qual.noise = 0; pDevice->wstats.qual.updated = 1; @@ -95,7 +95,7 @@ int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq = &wrqu->data; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; struct iw_scan_req *req = (struct iw_scan_req *)extra; - BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; PWLAN_IE_SSID pItemSSID = NULL; if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) @@ -238,7 +238,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, // ADD quality memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; - RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); + RFvRSSITodBm(pDevice, (u8)(pBSS->uRSSI), &ldBm); iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; @@ -532,7 +532,7 @@ int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_range *range = (struct iw_range *)extra; int i; int k; - BYTE abySupportedRates[13] = { + u8 abySupportedRates[13] = { 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90 }; @@ -635,7 +635,7 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq = &wrqu->ap_addr; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; int rc = 0; - BYTE ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PRINT_K(" SIOCSIWAP\n"); @@ -819,7 +819,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, if (pDevice->bWPASuppWextEnabled == true) { /*******search if in hidden ssid mode ****/ PKnownBSS pCurr = NULL; - BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + u8 abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; unsigned ii; unsigned uSameBssidNum = 0; @@ -913,7 +913,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, int rc = 0; u8 brate = 0; int i; - BYTE abySupportedRates[13] = { + u8 abySupportedRates[13] = { 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90 }; @@ -996,7 +996,7 @@ int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, return -EFAULT; { - BYTE abySupportedRates[13] = { + u8 abySupportedRates[13] = { 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90 }; @@ -1227,7 +1227,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, KEY_CTL_WEP); spin_unlock_irq(&pDevice->lock); } - pDevice->byKeyIndex = (BYTE)dwKeyIndex; + pDevice->byKeyIndex = (u8)dwKeyIndex; pDevice->uKeyLength = wrq->length; pDevice->bTransmitKey = true; pDevice->bEncryptionEnable = true; @@ -1317,7 +1317,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } - } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index, &pKey)) { + } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (u8)index, &pKey)) { wrq->length = pKey->uKeyLength; memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); @@ -1424,7 +1424,7 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n"); if (pDevice->bLinkPass == true) { - RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); + RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); wrq->value = ldBm; } else { wrq->value = 0; diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 416175e8ba53..5e369673a04f 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -79,7 +79,7 @@ static void s_vCheckKeyTableValid(struct vnt_private *pDevice, pTable->KeyTable[i].bInUse = false; pTable->KeyTable[i].wKeyCtl = 0; pTable->KeyTable[i].bSoftWEP = false; - pbyData[wLength++] = (BYTE) i; + pbyData[wLength++] = (u8) i; //MACvDisableKeyEntry(pDevice, i); } } @@ -130,9 +130,9 @@ void KeyvInitTable(struct vnt_private *pDevice, PSKeyManagement pTable) pTable->KeyTable[i].wKeyCtl = 0; pTable->KeyTable[i].dwGTKeyIndex = 0; pTable->KeyTable[i].bSoftWEP = false; - pbyData[i] = (BYTE) i; + pbyData[i] = (u8) i; } - pbyData[i] = (BYTE) i; + pbyData[i] = (u8) i; CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_CLRKEYENTRY, 0, diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 7ecddcd6bcfa..d5ff9c755212 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -59,27 +59,27 @@ typedef struct tagSKeyItem { bool bKeyValid; u32 uKeyLength; - BYTE abyKey[MAX_KEY_LEN]; + u8 abyKey[MAX_KEY_LEN]; u64 KeyRSC; DWORD dwTSC47_16; WORD wTSC15_0; - BYTE byCipherSuite; - BYTE byReserved0; + u8 byCipherSuite; + u8 byReserved0; DWORD dwKeyIndex; void *pvKeyTable; } SKeyItem, *PSKeyItem; //64 typedef struct tagSKeyTable { - BYTE abyBSSID[ETH_ALEN]; /* 6 */ - BYTE byReserved0[2]; //8 + u8 abyBSSID[ETH_ALEN]; /* 6 */ + u8 byReserved0[2]; //8 SKeyItem PairwiseKey; SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 DWORD dwGTKeyIndex; // GroupTransmitKey Index bool bInUse; WORD wKeyCtl; bool bSoftWEP; - BYTE byReserved1[6]; + u8 byReserved1[6]; } SKeyTable, *PSKeyTable; //352 typedef struct tagSKeyManagement diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 76d307b58d52..eccba6a6dbf0 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -169,10 +169,10 @@ void MACvSetMISCFifo(struct vnt_private *pDevice, u16 wOffset, u32 dwData) if (wOffset > 273) return; - pbyData[0] = (BYTE)dwData; - pbyData[1] = (BYTE)(dwData>>8); - pbyData[2] = (BYTE)(dwData>>16); - pbyData[3] = (BYTE)(dwData>>24); + pbyData[0] = (u8)dwData; + pbyData[1] = (u8)(dwData>>8); + pbyData[2] = (u8)(dwData>>16); + pbyData[3] = (u8)(dwData>>24); CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE_MISCFF, @@ -203,7 +203,7 @@ void MACvDisableKeyEntry(struct vnt_private *pDevice, u32 uEntryIdx) u8 byData; - byData = (BYTE) uEntryIdx; + byData = (u8) uEntryIdx; wOffset = MISCFIFO_KEYETRY0; wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); @@ -294,16 +294,16 @@ void MACvSetKeyEntry(struct vnt_private *pDevice, u16 wKeyCtl, u32 uEntryIdx, VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } */ - pbyKey = (PBYTE)pdwKey; - - pbyData[0] = (BYTE)dwData1; - pbyData[1] = (BYTE)(dwData1>>8); - pbyData[2] = (BYTE)(dwData1>>16); - pbyData[3] = (BYTE)(dwData1>>24); - pbyData[4] = (BYTE)dwData2; - pbyData[5] = (BYTE)(dwData2>>8); - pbyData[6] = (BYTE)(dwData2>>16); - pbyData[7] = (BYTE)(dwData2>>24); + pbyKey = (u8 *)pdwKey; + + pbyData[0] = (u8)dwData1; + pbyData[1] = (u8)(dwData1>>8); + pbyData[2] = (u8)(dwData1>>16); + pbyData[3] = (u8)(dwData1>>24); + pbyData[4] = (u8)dwData2; + pbyData[5] = (u8)(dwData2>>8); + pbyData[6] = (u8)(dwData2>>16); + pbyData[7] = (u8)(dwData2>>24); for (ii = 8; ii < 24; ii++) pbyData[ii] = *pbyKey++; @@ -358,8 +358,8 @@ void MACvWriteWord(struct vnt_private *pDevice, u8 byRegOfs, u16 wData) u8 pbyData[2]; - pbyData[0] = (BYTE)(wData & 0xff); - pbyData[1] = (BYTE)(wData >> 8); + pbyData[0] = (u8)(wData & 0xff); + pbyData[1] = (u8)(wData >> 8); CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, @@ -376,12 +376,12 @@ void MACvWriteBSSIDAddress(struct vnt_private *pDevice, u8 *pbyEtherAddr) u8 pbyData[6]; - pbyData[0] = *((PBYTE)pbyEtherAddr); - pbyData[1] = *((PBYTE)pbyEtherAddr+1); - pbyData[2] = *((PBYTE)pbyEtherAddr+2); - pbyData[3] = *((PBYTE)pbyEtherAddr+3); - pbyData[4] = *((PBYTE)pbyEtherAddr+4); - pbyData[5] = *((PBYTE)pbyEtherAddr+5); + pbyData[0] = *((u8 *)pbyEtherAddr); + pbyData[1] = *((u8 *)pbyEtherAddr+1); + pbyData[2] = *((u8 *)pbyEtherAddr+2); + pbyData[3] = *((u8 *)pbyEtherAddr+3); + pbyData[4] = *((u8 *)pbyEtherAddr+4); + pbyData[5] = *((u8 *)pbyEtherAddr+5); CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index d5f53e1a74a2..a38d2cb9d979 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -258,8 +258,8 @@ static void usb_device_reset(struct vnt_private *pDevice); static void device_set_options(struct vnt_private *pDevice) { - BYTE abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); @@ -366,8 +366,8 @@ static int device_init_registers(struct vnt_private *pDevice, } } - sInitCmd.byInitClass = (BYTE)InitType; - sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr; + sInitCmd.byInitClass = (u8)InitType; + sInitCmd.bExistSWNetAddr = (u8) pDevice->bExistSWNetAddr; for (ii = 0; ii < 6; ii++) sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii]; sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit; @@ -379,7 +379,7 @@ static int device_init_registers(struct vnt_private *pDevice, 0, 0, sizeof(CMD_CARD_INIT), - (PBYTE) &(sInitCmd)); + (u8 *) &(sInitCmd)); if ( ntStatus != STATUS_SUCCESS ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n"); @@ -388,7 +388,7 @@ static int device_init_registers(struct vnt_private *pDevice, } if (InitType == DEVICE_INIT_COLD) { - ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (PBYTE) &(sInitRsp)); + ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (u8 *) &(sInitRsp)); if (ntStatus != STATUS_SUCCESS) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n"); @@ -1470,8 +1470,8 @@ static void device_set_multi(struct net_device *dev) mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); } for (ii = 0; ii < 4; ii++) { - MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii)); - MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii)); + MACvWriteMultiAddr(pDevice, ii, *((u8 *)&mc_filter[0] + ii)); + MACvWriteMultiAddr(pDevice, ii+ 4, *((u8 *)&mc_filter[1] + ii)); } pDevice->byRxMode &= ~(RCR_UNICAST); pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index d4c7b0cc7ecd..fd4202c14eab 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -89,7 +89,7 @@ void STAvClearAllCounter (PSStatCounter pStatistic) * Return Value: none * */ -void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1) +void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, u8 byIsr0, u8 byIsr1) { /**********************/ /* ABNORMAL interrupt */ @@ -152,9 +152,9 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr * */ void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, - BYTE byRxSts, BYTE byRxRate, - PBYTE pbyBuffer, unsigned int cbFrameLength) + u8 byRSR, u8 byNewRSR, + u8 byRxSts, u8 byRxRate, + u8 * pbyBuffer, unsigned int cbFrameLength) { /* need change */ PS802_11Header pHeader = (PS802_11Header)pbyBuffer; @@ -390,11 +390,11 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic, void STAvUpdateRDStatCounterEx ( PSStatCounter pStatistic, - BYTE byRSR, - BYTE byNewRSR, - BYTE byRxSts, - BYTE byRxRate, - PBYTE pbyBuffer, + u8 byRSR, + u8 byNewRSR, + u8 byRxSts, + u8 byRxRate, + u8 * pbyBuffer, unsigned int cbFrameLength ) { @@ -411,7 +411,7 @@ STAvUpdateRDStatCounterEx ( // rx length pStatistic->dwCntRxFrmLength = cbFrameLength; // rx pattern, we just see 10 bytes for sample - memcpy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10); + memcpy(pStatistic->abyCntRxPattern, (u8 *)pbyBuffer, 10); } @@ -435,12 +435,12 @@ STAvUpdateRDStatCounterEx ( void STAvUpdateTDStatCounter ( PSStatCounter pStatistic, - BYTE byPktNum, - BYTE byRate, - BYTE byTSR + u8 byPktNum, + u8 byRate, + u8 byTSR ) { - BYTE byRetyCnt; + u8 byRetyCnt; // increase tx packet count pStatistic->dwTsrTxPacket++; @@ -524,10 +524,10 @@ void STAvUpdate802_11Counter( PSDot11Counters p802_11Counter, PSStatCounter pStatistic, - BYTE byRTSSuccess, - BYTE byRTSFail, - BYTE byACKFail, - BYTE byFCSErr + u8 byRTSSuccess, + u8 byRTSFail, + u8 byACKFail, + u8 byFCSErr ) { //p802_11Counter->TransmittedFragmentCount diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 85c28e923663..967486554312 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -92,7 +92,7 @@ typedef struct tagSMib2Counter { signed long ifType; signed long ifMtu; DWORD ifSpeed; - BYTE ifPhysAddress[ETH_ALEN]; + u8 ifPhysAddress[ETH_ALEN]; signed long ifAdminStatus; signed long ifOperStatus; DWORD ifLastChange; @@ -228,10 +228,10 @@ typedef struct tagSISRCounters { // Tx packet information // typedef struct tagSTxPktInfo { - BYTE byBroadMultiUni; + u8 byBroadMultiUni; WORD wLength; WORD wFIFOCtl; - BYTE abyDestAddr[ETH_ALEN]; + u8 abyDestAddr[ETH_ALEN]; } STxPktInfo, *PSTxPktInfo; @@ -318,8 +318,8 @@ typedef struct tagSStatCounter { DWORD dwCntRxFrmLength; DWORD dwCntTxBufLength; - BYTE abyCntRxPattern[16]; - BYTE abyCntTxPattern[16]; + u8 abyCntRxPattern[16]; + u8 abyCntTxPattern[16]; @@ -376,30 +376,30 @@ typedef struct tagSStatCounter { void STAvClearAllCounter(PSStatCounter pStatistic); void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, - BYTE byIsr0, - BYTE byIsr1); + u8 byIsr0, + u8 byIsr1); void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, - BYTE byRxRate, PBYTE pbyBuffer, + u8 byRSR, u8 byNewRSR, u8 byRxSts, + u8 byRxRate, u8 * pbyBuffer, unsigned int cbFrameLength); void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, - BYTE byRxRate, PBYTE pbyBuffer, + u8 byRSR, u8 byNewRSR, u8 byRxSts, + u8 byRxRate, u8 * pbyBuffer, unsigned int cbFrameLength); -void STAvUpdateTDStatCounter(PSStatCounter pStatistic, BYTE byPktNum, - BYTE byRate, BYTE byTSR); +void STAvUpdateTDStatCounter(PSStatCounter pStatistic, u8 byPktNum, + u8 byRate, u8 byTSR); void STAvUpdate802_11Counter( PSDot11Counters p802_11Counter, PSStatCounter pStatistic, - BYTE byRTSSuccess, - BYTE byRTSFail, - BYTE byACKFail, - BYTE byFCSErr + u8 byRTSSuccess, + u8 byRTSFail, + u8 byACKFail, + u8 byFCSErr ); void STAvClear802_11Counter(PSDot11Counters p802_11Counter); diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c index 4d419814f27f..1fb88e6d73fb 100644 --- a/drivers/staging/vt6656/michael.c +++ b/drivers/staging/vt6656/michael.c @@ -26,8 +26,8 @@ * Date: Sep 4, 2002 * * Functions: - * s_dwGetUINT32 - Convert from BYTE[] to DWORD in a portable way - * s_vPutUINT32 - Convert from DWORD to BYTE[] in a portable way + * s_dwGetUINT32 - Convert from u8[] to DWORD in a portable way + * s_vPutUINT32 - Convert from DWORD to u8[] in a portable way * s_vClear - Reset the state to the empty message. * s_vSetKey - Set the key. * MIC_vInit - Set the key. @@ -48,16 +48,16 @@ /*--------------------- Static Functions --------------------------*/ /* - * static DWORD s_dwGetUINT32(BYTE * p); Get DWORD from + * static DWORD s_dwGetUINT32(u8 * p); Get DWORD from * 4 bytes LSByte first - * static void s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into + * static void s_vPutUINT32(u8* p, DWORD val); Put DWORD into * 4 bytes LSByte first */ static void s_vClear(void); /* Clear the internal message, * resets the object to the * state just after construction. */ static void s_vSetKey(DWORD dwK0, DWORD dwK1); -static void s_vAppendByte(BYTE b); /* Add a single byte to the internal +static void s_vAppendByte(u8 b); /* Add a single byte to the internal * message */ /*--------------------- Export Variables --------------------------*/ @@ -69,8 +69,8 @@ static unsigned int nBytesInM; /* # bytes in M */ /*--------------------- Export Functions --------------------------*/ /* -static DWORD s_dwGetUINT32 (BYTE * p) -// Convert from BYTE[] to DWORD in a portable way +static DWORD s_dwGetUINT32 (u8 * p) +// Convert from u8[] to DWORD in a portable way { DWORD res = 0; unsigned int i; @@ -79,12 +79,12 @@ static DWORD s_dwGetUINT32 (BYTE * p) return res; } -static void s_vPutUINT32(BYTE *p, DWORD val) -// Convert from DWORD to BYTE[] in a portable way +static void s_vPutUINT32(u8 *p, DWORD val) +// Convert from DWORD to u8[] in a portable way { unsigned int i; for (i = 0; i < 4; i++) { - *p++ = (BYTE) (val & 0xff); + *p++ = (u8) (val & 0xff); val >>= 8; } } @@ -108,7 +108,7 @@ static void s_vSetKey(DWORD dwK0, DWORD dwK1) s_vClear(); } -static void s_vAppendByte(BYTE b) +static void s_vAppendByte(u8 b) { /* Append the byte to our word-sized buffer */ M |= b << (8*nBytesInM); @@ -148,7 +148,7 @@ void MIC_vUnInit(void) s_vClear(); } -void MIC_vAppend(PBYTE src, unsigned int nBytes) +void MIC_vAppend(u8 * src, unsigned int nBytes) { /* This is simple */ while (nBytes > 0) { diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 81351f506232..074023221b43 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -40,7 +40,7 @@ void MIC_vInit(DWORD dwK0, DWORD dwK1); void MIC_vUnInit(void); // Append bytes to the message to be MICed -void MIC_vAppend(PBYTE src, unsigned int nBytes); +void MIC_vAppend(u8 * src, unsigned int nBytes); // Get the MIC result. Destination should accept 8 bytes of result. // This also resets the message to empty. diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c index 5c3c2d0552b4..2fd836f07536 100644 --- a/drivers/staging/vt6656/rc4.c +++ b/drivers/staging/vt6656/rc4.c @@ -32,27 +32,27 @@ #include "rc4.h" -void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, unsigned int cbKey_len) +void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len) { unsigned int ust1, ust2; unsigned int keyindex; unsigned int stateindex; - PBYTE pbyst; + u8 * pbyst; unsigned int idx; pbyst = pRC4->abystate; pRC4->ux = 0; pRC4->uy = 0; for (idx = 0; idx < 256; idx++) - pbyst[idx] = (BYTE)idx; + pbyst[idx] = (u8)idx; keyindex = 0; stateindex = 0; for (idx = 0; idx < 256; idx++) { ust1 = pbyst[idx]; stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; ust2 = pbyst[stateindex]; - pbyst[stateindex] = (BYTE)ust1; - pbyst[idx] = (BYTE)ust2; + pbyst[stateindex] = (u8)ust1; + pbyst[idx] = (u8)ust2; if (++keyindex >= cbKey_len) keyindex = 0; } @@ -63,7 +63,7 @@ unsigned int rc4_byte(PRC4Ext pRC4) unsigned int ux; unsigned int uy; unsigned int ustx, usty; - PBYTE pbyst; + u8 * pbyst; pbyst = pRC4->abystate; ux = (pRC4->ux + 1) & 0xff; @@ -72,16 +72,16 @@ unsigned int rc4_byte(PRC4Ext pRC4) usty = pbyst[uy]; pRC4->ux = ux; pRC4->uy = uy; - pbyst[uy] = (BYTE)ustx; - pbyst[ux] = (BYTE)usty; + pbyst[uy] = (u8)ustx; + pbyst[ux] = (u8)usty; return pbyst[(ustx + usty) & 0xff]; } -void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, - PBYTE pbySrc, unsigned int cbData_len) +void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest, + u8 * pbySrc, unsigned int cbData_len) { unsigned int ii; for (ii = 0; ii < cbData_len; ii++) - pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4)); + pbyDest[ii] = (u8)(pbySrc[ii] ^ rc4_byte(pRC4)); } diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h index d447879c8f99..2751d06bb9cf 100644 --- a/drivers/staging/vt6656/rc4.h +++ b/drivers/staging/vt6656/rc4.h @@ -37,12 +37,12 @@ typedef struct { unsigned int ux; unsigned int uy; - BYTE abystate[256]; + u8 abystate[256]; } RC4Ext, *PRC4Ext; -void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, unsigned int cbKey_len); +void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len); unsigned int rc4_byte(PRC4Ext pRC4); -void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, +void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest, u8 * pbySrc, unsigned int cbData_len); #endif /* __RC4_H__ */ diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h index fccf7e98eb68..e14b4f71aec8 100644 --- a/drivers/staging/vt6656/rndis.h +++ b/drivers/staging/vt6656/rndis.h @@ -74,43 +74,43 @@ typedef struct _CMD_MESSAGE { - BYTE byData[256]; + u8 byData[256]; } CMD_MESSAGE, *PCMD_MESSAGE; typedef struct _CMD_WRITE_MASK { - BYTE byData; - BYTE byMask; + u8 byData; + u8 byMask; } CMD_WRITE_MASK, *PCMD_WRITE_MASK; typedef struct _CMD_CARD_INIT { - BYTE byInitClass; - BYTE bExistSWNetAddr; - BYTE bySWNetAddr[6]; - BYTE byShortRetryLimit; - BYTE byLongRetryLimit; + u8 byInitClass; + u8 bExistSWNetAddr; + u8 bySWNetAddr[6]; + u8 byShortRetryLimit; + u8 byLongRetryLimit; } CMD_CARD_INIT, *PCMD_CARD_INIT; typedef struct _RSP_CARD_INIT { - BYTE byStatus; - BYTE byNetAddr[6]; - BYTE byRFType; - BYTE byMinChannel; - BYTE byMaxChannel; + u8 byStatus; + u8 byNetAddr[6]; + u8 byRFType; + u8 byMinChannel; + u8 byMaxChannel; } RSP_CARD_INIT, *PRSP_CARD_INIT; typedef struct _CMD_SET_KEY { WORD wKCTL; - BYTE abyMacAddr[6]; - BYTE abyKey[16]; + u8 abyMacAddr[6]; + u8 abyKey[16]; } CMD_SET_KEY, *PCMD_SET_KEY; typedef struct _CMD_CLRKEY_ENTRY { - BYTE abyKeyEntry[11]; + u8 abyKeyEntry[11]; } CMD_CLRKEY_ENTRY, *PCMD_CLRKEY_ENTRY; typedef struct _CMD_WRITE_MISCFF @@ -120,29 +120,29 @@ typedef struct _CMD_WRITE_MISCFF typedef struct _CMD_SET_TSFTBTT { - BYTE abyTSF_TBTT[8]; + u8 abyTSF_TBTT[8]; } CMD_SET_TSFTBTT, *PCMD_SET_TSFTBTT; typedef struct _CMD_SET_SSTIFS { - BYTE bySIFS; - BYTE byDIFS; - BYTE byEIFS; - BYTE bySlotTime; - BYTE byCwMax_Min; - BYTE byBBCR10; + u8 bySIFS; + u8 byDIFS; + u8 byEIFS; + u8 bySlotTime; + u8 byCwMax_Min; + u8 byBBCR10; } CMD_SET_SSTIFS, *PCMD_SET_SSTIFS; typedef struct _CMD_CHANGE_BBTYPE { - BYTE bySIFS; - BYTE byDIFS; - BYTE byEIFS; - BYTE bySlotTime; - BYTE byCwMax_Min; - BYTE byBBCR10; - BYTE byBB_BBType; //CR88 - BYTE byMAC_BBType; + u8 bySIFS; + u8 byDIFS; + u8 byEIFS; + u8 bySlotTime; + u8 byCwMax_Min; + u8 byBBCR10; + u8 byBB_BBType; //CR88 + u8 byMAC_BBType; DWORD dwRSPINF_b_1; DWORD dwRSPINF_b_2; DWORD dwRSPINF_b_55; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index b939dcf689d6..d019b44bdc50 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -222,13 +222,13 @@ static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf, if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){ - memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3); + memcpy(pDevice->abyPRNG, (u8 *)&(dwRevIVCounter), 3); memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); } else { - memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3); + memcpy(pbyBuf, (u8 *)&(dwRevIVCounter), 3); memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3); + memcpy(pbyBuf+8, (u8 *)&(dwRevIVCounter), 3); memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); } memcpy(pDevice->abyPRNG, pbyBuf, 16); @@ -252,7 +252,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf, // Make IV memcpy(pdwIV, pDevice->abyPRNG, 3); - *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV + *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV // Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n", @@ -267,33 +267,33 @@ static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf, // Make IV *pdwIV = 0; - *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV + *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0)); //Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); //Fill MICHDR0 *pMICHDR = 0x59; - *((PBYTE)(pMICHDR+1)) = 0; // TxPriority + *((u8 *)(pMICHDR+1)) = 0; // TxPriority memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6); - *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); - *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); - *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen); - *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen); + *((u8 *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); + *((u8 *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); + *((u8 *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); + *((u8 *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); + *((u8 *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); + *((u8 *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); + *((u8 *)(pMICHDR+14)) = HIBYTE(wPayloadLen); + *((u8 *)(pMICHDR+15)) = LOBYTE(wPayloadLen); //Fill MICHDR1 - *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8] + *((u8 *)(pMICHDR+16)) = 0; // HLEN[15:8] if (pDevice->bLongHeader) { - *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0] + *((u8 *)(pMICHDR+17)) = 28; // HLEN[7:0] } else { - *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0] + *((u8 *)(pMICHDR+17)) = 22; // HLEN[7:0] } wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F); - memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL + memcpy(pMICHDR+18, (u8 *)&wValue, 2); // MSKFRACTL memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6); memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6); @@ -302,7 +302,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf, wValue = pMACHeader->wSeqCtl; wValue &= 0x000F; wValue = cpu_to_le16(wValue); - memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL + memcpy(pMICHDR+38, (u8 *)&wValue, 2); // MSKSEQCTL if (pDevice->bLongHeader) { memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6); } @@ -671,7 +671,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, @@ -688,10 +688,10 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) + (PWORD)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, @@ -711,10 +711,10 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) + (PWORD)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, @@ -737,7 +737,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, @@ -754,7 +754,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, @@ -772,7 +772,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, @@ -810,11 +810,11 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_g pBuf = (PSRTS_g)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); //Get Duration @@ -852,11 +852,11 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); //Get Duration @@ -901,7 +901,7 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration @@ -936,7 +936,7 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration @@ -972,7 +972,7 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration @@ -1028,7 +1028,7 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx, PSCTS_FB pBuf = (PSCTS_FB)pvCTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data @@ -1053,7 +1053,7 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx, PSCTS pBuf = (PSCTS)pvCTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b) + (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); //Get CTSDuration_ba @@ -1195,7 +1195,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n"); } /* - PBYTE pbyBuffer,//point to pTxBufHead + u8 * pbyBuffer,//point to pTxBufHead WORD wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last unsigned int cbFragmentSize,//Hdr+payoad+FCS */ @@ -1358,7 +1358,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); } - pbyTxBufferAddr = (PBYTE) &(pTxBufHead->adwTxKey[0]); + pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]); wTxBufSize = sizeof(STxBufHead); if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet if (byFBOption == AUTO_FB_NONE) { @@ -1437,9 +1437,9 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, } // Auto Fall Back } - pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength); - pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding); - pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); + pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength); + pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding); + pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); //========================= @@ -1464,8 +1464,8 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, if (bNeedEncryption == true) { //Fill TXKEY - s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR); + s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (WORD)cbFrameBodySize, (u8 *)pMICHDR); if (pDevice->bEnableHostWEP) { pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; @@ -1478,15 +1478,15 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, if (pDevice->dwDiagRefCount == 0) { if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) || (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((PBYTE) (pbyPayloadHead), + memcpy((u8 *) (pbyPayloadHead), abySNAP_Bridgetunnel, 6); } else { - memcpy((PBYTE) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); + memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); } - pbyType = (PBYTE) (pbyPayloadHead + 6); + pbyType = (u8 *) (pbyPayloadHead + 6); memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD)); } else { - memcpy((PBYTE) (pbyPayloadHead), &(psEthHeader->wType), sizeof(WORD)); + memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->wType), sizeof(WORD)); } @@ -1502,7 +1502,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, } else { // while bRelayPacketSend psEthHeader is point to header+payload - memcpy((pbyPayloadHead + cb802_1_H_len), ((PBYTE)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN); + memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN); } ASSERT(uLength == cbNdisBodySize); @@ -1525,9 +1525,9 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, } // DO Software Michael MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12); + MIC_vAppend((u8 *)&(psEthHeader->abyDstAddr[0]), 12); dwMIC_Priority = 0; - MIC_vAppend((PBYTE)&dwMIC_Priority, 4); + MIC_vAppend((u8 *)&dwMIC_Priority, 4); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); @@ -1535,7 +1535,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength)); //for (ii = 0; ii < cbFrameBodySize; ii++) { - // DBG_PRN_GRP12(("%02x ", *((PBYTE)((pbyPayloadHead + cb802_1_H_len) + ii)))); + // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii)))); //} //DBG_PRN_GRP12(("\n\n\n")); @@ -1740,7 +1740,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, } pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]); - pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->adwTxKey[0]); + pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]); cbFrameBodySize = pPacket->cbPayloadLen; pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; wTxBufSize = sizeof(STxBufHead); @@ -1902,13 +1902,13 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - PBYTE pbyIVHead; - PBYTE pbyPayloadHead; - PBYTE pbyBSSID; + u8 * pbyIVHead; + u8 * pbyPayloadHead; + u8 * pbyBSSID; PSKeyItem pTransmitKey = NULL; - pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); + pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); + pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); do { if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && (pDevice->bLinkPass == true)) { @@ -1935,11 +1935,11 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, } } while(false); //Fill TXKEY - s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL); + s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, + (u8 *)pMACHeader, (WORD)cbFrameBodySize, NULL); memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen), + memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen), cbFrameBodySize); } else { @@ -1968,7 +1968,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount)); - pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); + pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x00; pContext->pPacket = NULL; @@ -1976,10 +1976,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, pContext->uBufLen = (WORD)cbReqCount + 4; //USB header if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) { - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); } else { - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); } PIPEnsSendBulkOut(pDevice,pContext); @@ -2012,7 +2012,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, return status ; } pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]); - pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->wFIFOCtl); + pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl); cbFrameBodySize = pPacket->cbPayloadLen; @@ -2025,7 +2025,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A, - (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField) + (PWORD)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A, @@ -2038,7 +2038,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B, - (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField) + (PWORD)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B, @@ -2060,7 +2060,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize; pTX_Buffer->wTxByteCount = (WORD)cbReqCount; - pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); + pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x01; pContext->pPacket = NULL; @@ -2126,7 +2126,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]); - pbyTxBufferAddr = (PBYTE)(&pTX_Buffer->adwTxKey[0]); + pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]); pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; wTxBufSize = sizeof(STxBufHead); memset(pTxBufHead, 0, wTxBufSize); @@ -2177,7 +2177,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } else { if (pDevice->bEnableHostWEP) { - if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex)) + if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex)) bNodeExist = true; } bNeedACK = true; @@ -2314,9 +2314,9 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; - pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize); - pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); - pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding); + pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize); + pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); + pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding); // Copy the Packet into a tx Buffer memcpy(pbyMacHdr, skb->data, cbMacHdLen); @@ -2364,9 +2364,9 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) // DO Software Michael MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12); + MIC_vAppend((u8 *)&(sEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; - MIC_vAppend((PBYTE)&dwMIC_Priority, 4); + MIC_vAppend((u8 *)&dwMIC_Priority, 4); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\ " %X, %X\n", dwMICKey0, dwMICKey1); @@ -2393,8 +2393,8 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } - s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR); + s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (WORD)cbFrameBodySize, (u8 *)pMICHDR); if (pDevice->bEnableHostWEP) { pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; @@ -2427,7 +2427,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount)); - pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); + pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x00; pContext->pPacket = skb; @@ -2435,10 +2435,10 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) pContext->uBufLen = (WORD)cbReqCount + 4; //USB header if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) { - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); } else { - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); } PIPEnsSendBulkOut(pDevice,pContext); return ; @@ -2496,7 +2496,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, return 0; } - if (is_multicast_ether_addr((PBYTE)(skb->data))) { + if (is_multicast_ether_addr((u8 *)(skb->data))) { uNodeIndex = 0; bNodeExist = true; if (pMgmt->sNodeDBTable[0].bPSEnable) { @@ -2518,7 +2518,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, }else { - if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data), &uNodeIndex)) { + if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) { if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { @@ -2562,13 +2562,13 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, return STATUS_RESOURCES; } - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN); + memcpy(pDevice->sTxEthHeader.abyDstAddr, (u8 *)(skb->data), ETH_HLEN); //mike add:station mode check eapol-key challenge---> { - BYTE Protocol_Version; //802.1x Authentication - BYTE Packet_Type; //802.1x Authentication - BYTE Descriptor_type; + u8 Protocol_Version; //802.1x Authentication + u8 Packet_Type; //802.1x Authentication + u8 Descriptor_type; WORD Key_info; Protocol_Version = skb->data[ETH_HLEN]; @@ -2665,7 +2665,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, } } - byPktType = (BYTE)pDevice->byPacketType; + byPktType = (u8)pDevice->byPacketType; if (pDevice->bFixRate) { if (pDevice->byBBType == BB_TYPE_11B) { @@ -2793,9 +2793,9 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, } fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType, - (PBYTE)(&pContext->Data[0]), bNeedEncryption, + (u8 *)(&pContext->Data[0]), bNeedEncryption, skb->len, uDMAIdx, &pDevice->sTxEthHeader, - (PBYTE)skb->data, pTransmitKey, uNodeIndex, + (u8 *)skb->data, pTransmitKey, uNodeIndex, pDevice->wCurrentRate, &uHeaderLen, &BytesToWrite ); @@ -2816,21 +2816,21 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, } pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]); - pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); + pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->wTxByteCount = (WORD)BytesToWrite; pContext->pPacket = skb; pContext->Type = CONTEXT_DATA_PACKET; pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); status = PIPEnsSendBulkOut(pDevice,pContext); if (bNeedDeAuth == true) { WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE; - bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (PBYTE) &wReason); + bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason); } if(status!=STATUS_PENDING) { @@ -2885,7 +2885,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, return false; } - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, ETH_HLEN); + memcpy(pDevice->sTxEthHeader.abyDstAddr, (u8 *)pbySkbData, ETH_HLEN); if (pDevice->bEncryptionEnable == true) { bNeedEncryption = true; @@ -2919,7 +2919,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, return false; } - byPktTyp = (BYTE)pDevice->byPacketType; + byPktTyp = (u8)pDevice->byPacketType; if (pDevice->bFixRate) { if (pDevice->byBBType == BB_TYPE_11B) { @@ -2957,7 +2957,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, // and send the irp. fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType, - (PBYTE)(&pContext->Data[0]), bNeedEncryption, + (u8 *)(&pContext->Data[0]), bNeedEncryption, uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex, pDevice->wCurrentRate, @@ -2970,14 +2970,14 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, } pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]); - pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); + pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->wTxByteCount = (WORD)BytesToWrite; pContext->pPacket = NULL; pContext->Type = CONTEXT_DATA_PACKET; pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header - s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); status = PIPEnsSendBulkOut(pDevice,pContext); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 9f537022cdd1..7ca185e4437e 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -43,8 +43,8 @@ typedef struct tagSRTSDataF { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[ETH_ALEN]; - BYTE abyTA[ETH_ALEN]; + u8 abyRA[ETH_ALEN]; + u8 abyTA[ETH_ALEN]; } SRTSDataF, *PSRTSDataF; // @@ -53,7 +53,7 @@ typedef struct tagSRTSDataF { typedef struct tagSCTSDataF { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[ETH_ALEN]; + u8 abyRA[ETH_ALEN]; WORD wReserved; } SCTSDataF, *PSCTSDataF; @@ -78,11 +78,11 @@ typedef struct tagSTX_NAF_G_RTS WORD wTxRrvTime_a; //RTS - BYTE byRTSSignalField_b; - BYTE byRTSServiceField_b; + u8 byRTSSignalField_b; + u8 byRTSServiceField_b; WORD wRTSTransmitLength_b; - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_ba; WORD wRTSDuration_aa; @@ -91,11 +91,11 @@ typedef struct tagSTX_NAF_G_RTS SRTSDataF sRTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -117,11 +117,11 @@ typedef struct tagSTX_NAF_G_RTS_MIC SMICHDR sMICHDR; //RTS - BYTE byRTSSignalField_b; - BYTE byRTSServiceField_b; + u8 byRTSSignalField_b; + u8 byRTSServiceField_b; WORD wRTSTransmitLength_b; - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_ba; WORD wRTSDuration_aa; @@ -130,11 +130,11 @@ typedef struct tagSTX_NAF_G_RTS_MIC SRTSDataF sRTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -152,19 +152,19 @@ typedef struct tagSTX_NAF_G_CTS WORD wTxRrvTime_a; //CTS - BYTE byCTSSignalField_b; - BYTE byCTSServiceField_b; + u8 byCTSSignalField_b; + u8 byCTSServiceField_b; WORD wCTSTransmitLength_b; WORD wCTSDuration_ba; WORD wReserved3; SCTSDataF sCTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -186,19 +186,19 @@ typedef struct tagSTX_NAF_G_CTS_MIC SMICHDR sMICHDR; //CTS - BYTE byCTSSignalField_b; - BYTE byCTSServiceField_b; + u8 byCTSSignalField_b; + u8 byCTSServiceField_b; WORD wCTSTransmitLength_b; WORD wCTSDuration_ba; WORD wReserved3; SCTSDataF sCTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -214,16 +214,16 @@ typedef struct tagSTX_NAF_G_BEACON WORD wTimeStamp; //CTS - BYTE byCTSSignalField_b; - BYTE byCTSServiceField_b; + u8 byCTSSignalField_b; + u8 byCTSServiceField_b; WORD wCTSTransmitLength_b; WORD wCTSDuration_ba; WORD wReserved1; SCTSDataF sCTS; //Data - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_a; WORD wTimeStampOff_a; @@ -239,16 +239,16 @@ typedef struct tagSTX_NAF_AB_RTS WORD wTxRrvTime_ab; //RTS - BYTE byRTSSignalField_ab; - BYTE byRTSServiceField_ab; + u8 byRTSSignalField_ab; + u8 byRTSServiceField_ab; WORD wRTSTransmitLength_ab; WORD wRTSDuration_ab; WORD wReserved2; SRTSDataF sRTS; //Data - BYTE bySignalField_ab; - BYTE byServiceField_ab; + u8 bySignalField_ab; + u8 byServiceField_ab; WORD wTransmitLength_ab; WORD wDuration_ab; WORD wTimeStampOff_ab; @@ -266,16 +266,16 @@ typedef struct tagSTX_NAF_AB_RTS_MIC SMICHDR sMICHDR; //RTS - BYTE byRTSSignalField_ab; - BYTE byRTSServiceField_ab; + u8 byRTSSignalField_ab; + u8 byRTSServiceField_ab; WORD wRTSTransmitLength_ab; WORD wRTSDuration_ab; WORD wReserved2; SRTSDataF sRTS; //Data - BYTE bySignalField_ab; - BYTE byServiceField_ab; + u8 bySignalField_ab; + u8 byServiceField_ab; WORD wTransmitLength_ab; WORD wDuration_ab; WORD wTimeStampOff_ab; @@ -292,8 +292,8 @@ typedef struct tagSTX_NAF_AB_CTS WORD wTxRrvTime_ab; //Data - BYTE bySignalField_ab; - BYTE byServiceField_ab; + u8 bySignalField_ab; + u8 byServiceField_ab; WORD wTransmitLength_ab; WORD wDuration_ab; WORD wTimeStampOff_ab; @@ -309,8 +309,8 @@ typedef struct tagSTX_NAF_AB_CTS_MIC SMICHDR sMICHDR; //Data - BYTE bySignalField_ab; - BYTE byServiceField_ab; + u8 bySignalField_ab; + u8 byServiceField_ab; WORD wTransmitLength_ab; WORD wDuration_ab; WORD wTimeStampOff_ab; @@ -324,8 +324,8 @@ typedef struct tagSTX_NAF_AB_BEACON WORD wTimeStamp; //Data - BYTE bySignalField_ab; - BYTE byServiceField_ab; + u8 bySignalField_ab; + u8 byServiceField_ab; WORD wTransmitLength_ab; WORD wDuration_ab; WORD wTimeStampOff_ab; @@ -343,11 +343,11 @@ typedef struct tagSTX_AF_G_RTS WORD wTxRrvTime_a; //RTS - BYTE byRTSSignalField_b; - BYTE byRTSServiceField_b; + u8 byRTSSignalField_b; + u8 byRTSServiceField_b; WORD wRTSTransmitLength_b; - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_ba; WORD wRTSDuration_aa; @@ -360,11 +360,11 @@ typedef struct tagSTX_AF_G_RTS SRTSDataF sRTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -389,11 +389,11 @@ typedef struct tagSTX_AF_G_RTS_MIC SMICHDR sMICHDR; //RTS - BYTE byRTSSignalField_b; - BYTE byRTSServiceField_b; + u8 byRTSSignalField_b; + u8 byRTSServiceField_b; WORD wRTSTransmitLength_b; - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_ba; WORD wRTSDuration_aa; @@ -406,11 +406,11 @@ typedef struct tagSTX_AF_G_RTS_MIC SRTSDataF sRTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -432,8 +432,8 @@ typedef struct tagSTX_AF_G_CTS WORD wTxRrvTime_a; //CTS - BYTE byCTSSignalField_b; - BYTE byCTSServiceField_b; + u8 byCTSSignalField_b; + u8 byCTSServiceField_b; WORD wCTSTransmitLength_b; WORD wCTSDuration_ba; WORD wReserved3; @@ -442,11 +442,11 @@ typedef struct tagSTX_AF_G_CTS SCTSDataF sCTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -470,8 +470,8 @@ typedef struct tagSTX_AF_G_CTS_MIC SMICHDR sMICHDR; //CTS - BYTE byCTSSignalField_b; - BYTE byCTSServiceField_b; + u8 byCTSSignalField_b; + u8 byCTSServiceField_b; WORD wCTSTransmitLength_b; WORD wCTSDuration_ba; WORD wReserved3; @@ -480,11 +480,11 @@ typedef struct tagSTX_AF_G_CTS_MIC SCTSDataF sCTS; //Data - BYTE bySignalField_b; - BYTE byServiceField_b; + u8 bySignalField_b; + u8 byServiceField_b; WORD wTransmitLength_b; - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_b; WORD wDuration_a; @@ -504,8 +504,8 @@ typedef struct tagSTX_AF_A_RTS WORD wTxRrvTime_a; //RTS - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_a; WORD wReserved2; @@ -514,8 +514,8 @@ typedef struct tagSTX_AF_A_RTS SRTSDataF sRTS; //Data - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_a; WORD wTimeStampOff_a; @@ -534,8 +534,8 @@ typedef struct tagSTX_AF_A_RTS_MIC SMICHDR sMICHDR; //RTS - BYTE byRTSSignalField_a; - BYTE byRTSServiceField_a; + u8 byRTSSignalField_a; + u8 byRTSServiceField_a; WORD wRTSTransmitLength_a; WORD wRTSDuration_a; WORD wReserved2; @@ -544,8 +544,8 @@ typedef struct tagSTX_AF_A_RTS_MIC SRTSDataF sRTS; //Data - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_a; WORD wTimeStampOff_a; @@ -563,8 +563,8 @@ typedef struct tagSTX_AF_A_CTS WORD wTxRrvTime_a; //Data - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_a; WORD wTimeStampOff_a; @@ -583,8 +583,8 @@ typedef struct tagSTX_AF_A_CTS_MIC SMICHDR sMICHDR; //Data - BYTE bySignalField_a; - BYTE byServiceField_a; + u8 bySignalField_a; + u8 byServiceField_a; WORD wTransmitLength_a; WORD wDuration_a; WORD wTimeStampOff_a; @@ -626,8 +626,8 @@ typedef union tagUTX_BUFFER_CONTAINER // typedef struct tagSTX_BUFFER { - BYTE byType; - BYTE byPKTNO; + u8 byType; + u8 byPKTNO; WORD wTxByteCount; u32 adwTxKey[4]; @@ -648,8 +648,8 @@ typedef struct tagSTX_BUFFER // typedef struct tagSBEACON_BUFFER { - BYTE byType; - BYTE byPKTNO; + u8 byType; + u8 byPKTNO; WORD wTxByteCount; WORD wFIFOCtl; diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h index dba21a54414b..c681789136c1 100644 --- a/drivers/staging/vt6656/srom.h +++ b/drivers/staging/vt6656/srom.h @@ -86,34 +86,34 @@ // 2048 bits = 256 bytes = 128 words // typedef struct tagSSromReg { - BYTE abyPAR[6]; // 0x00 (WORD) + u8 abyPAR[6]; // 0x00 (WORD) WORD wSUB_VID; // 0x03 (WORD) WORD wSUB_SID; - BYTE byBCFG0; // 0x05 (WORD) - BYTE byBCFG1; - - BYTE byFCR0; // 0x06 (WORD) - BYTE byFCR1; - BYTE byPMC0; // 0x07 (WORD) - BYTE byPMC1; - BYTE byMAXLAT; // 0x08 (WORD) - BYTE byMINGNT; - BYTE byCFG0; // 0x09 (WORD) - BYTE byCFG1; + u8 byBCFG0; // 0x05 (WORD) + u8 byBCFG1; + + u8 byFCR0; // 0x06 (WORD) + u8 byFCR1; + u8 byPMC0; // 0x07 (WORD) + u8 byPMC1; + u8 byMAXLAT; // 0x08 (WORD) + u8 byMINGNT; + u8 byCFG0; // 0x09 (WORD) + u8 byCFG1; WORD wCISPTR; // 0x0A (WORD) WORD wRsv0; // 0x0B (WORD) WORD wRsv1; // 0x0C (WORD) - BYTE byBBPAIR; // 0x0D (WORD) - BYTE byRFTYPE; - BYTE byMinChannel; // 0x0E (WORD) - BYTE byMaxChannel; - BYTE bySignature; // 0x0F (WORD) - BYTE byCheckSum; - - BYTE abyReserved0[96]; // 0x10 (WORD) - BYTE abyCIS[128]; // 0x80 (WORD) + u8 byBBPAIR; // 0x0D (WORD) + u8 byRFTYPE; + u8 byMinChannel; // 0x0E (WORD) + u8 byMaxChannel; + u8 bySignature; // 0x0F (WORD) + u8 byCheckSum; + + u8 abyReserved0[96]; // 0x10 (WORD) + u8 abyCIS[128]; // 0x80 (WORD) } SSromReg, *PSSromReg; /*--------------------- Export Macros ------------------------------*/ diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c index 2237eeb5ec5b..d4db71302a43 100644 --- a/drivers/staging/vt6656/tcrc.c +++ b/drivers/staging/vt6656/tcrc.c @@ -132,13 +132,13 @@ static const DWORD s_adwCrc32Table[256] = { * Return Value: CRC-32 * -*/ -DWORD CRCdwCrc32(PBYTE pbyData, unsigned int cbByte, DWORD dwCrcSeed) +DWORD CRCdwCrc32(u8 * pbyData, unsigned int cbByte, DWORD dwCrcSeed) { DWORD dwCrc; dwCrc = dwCrcSeed; while (cbByte--) { - dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ + dwCrc = s_adwCrc32Table[(u8)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); pbyData++; } @@ -165,7 +165,7 @@ DWORD CRCdwCrc32(PBYTE pbyData, unsigned int cbByte, DWORD dwCrcSeed) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32(PBYTE pbyData, unsigned int cbByte) +DWORD CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte) { return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); } @@ -191,7 +191,7 @@ DWORD CRCdwGetCrc32(PBYTE pbyData, unsigned int cbByte) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32Ex(PBYTE pbyData, unsigned int cbByte, DWORD dwPreCRC) +DWORD CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, DWORD dwPreCRC) { return CRCdwCrc32(pbyData, cbByte, dwPreCRC); } diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index dc54bd8fc4fc..342061dc9bb4 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -43,8 +43,8 @@ /*--------------------- Export Functions --------------------------*/ -DWORD CRCdwCrc32(PBYTE pbyData, unsigned int cbByte, DWORD dwCrcSeed); -DWORD CRCdwGetCrc32(PBYTE pbyData, unsigned int cbByte); -DWORD CRCdwGetCrc32Ex(PBYTE pbyData, unsigned int cbByte, DWORD dwPreCRC); +DWORD CRCdwCrc32(u8 * pbyData, unsigned int cbByte, DWORD dwCrcSeed); +DWORD CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte); +DWORD CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, DWORD dwPreCRC); #endif /* __TCRC_H__ */ diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index 95286c4d5572..c92efdaf4088 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -61,14 +61,14 @@ * Return Value: Hash value * */ -BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr) +u8 ETHbyGetHashIndexByCrc32(u8 * pbyMultiAddr) { int ii; - BYTE byTmpHash; - BYTE byHash = 0; + u8 byTmpHash; + u8 byHash = 0; /* get the least 6-bits from CRC generator */ - byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, + byTmpHash = (u8)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, 0xFFFFFFFFL) & 0x3F); /* reverse most bit to least bit */ for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { @@ -96,7 +96,7 @@ BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr) * Return Value: true if ok; false if error. * */ -bool ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, unsigned int cbFrameLength) +bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength) { DWORD dwCRC; diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index 2f8f4853fd9d..0b8a40f05b96 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -120,8 +120,8 @@ // Ethernet packet // typedef struct tagSEthernetHeader { - BYTE abyDstAddr[ETH_ALEN]; - BYTE abySrcAddr[ETH_ALEN]; + u8 abyDstAddr[ETH_ALEN]; + u8 abySrcAddr[ETH_ALEN]; WORD wType; } __attribute__ ((__packed__)) SEthernetHeader, *PSEthernetHeader; @@ -131,8 +131,8 @@ SEthernetHeader, *PSEthernetHeader; // 802_3 packet // typedef struct tagS802_3Header { - BYTE abyDstAddr[ETH_ALEN]; - BYTE abySrcAddr[ETH_ALEN]; + u8 abyDstAddr[ETH_ALEN]; + u8 abySrcAddr[ETH_ALEN]; WORD wLen; } __attribute__ ((__packed__)) S802_3Header, *PS802_3Header; @@ -143,11 +143,11 @@ S802_3Header, *PS802_3Header; typedef struct tagS802_11Header { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[ETH_ALEN]; - BYTE abyAddr2[ETH_ALEN]; - BYTE abyAddr3[ETH_ALEN]; + u8 abyAddr1[ETH_ALEN]; + u8 abyAddr2[ETH_ALEN]; + u8 abyAddr3[ETH_ALEN]; WORD wSeqCtl; - BYTE abyAddr4[ETH_ALEN]; + u8 abyAddr4[ETH_ALEN]; } __attribute__ ((__packed__)) S802_11Header, *PS802_11Header; @@ -159,8 +159,8 @@ S802_11Header, *PS802_11Header; /*--------------------- Export Functions --------------------------*/ -BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr); -//BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr); -bool ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, unsigned int cbFrameLength); +u8 ETHbyGetHashIndexByCrc32(u8 * pbyMultiAddr); +//u8 ETHbyGetHashIndexByCrc(u8 * pbyMultiAddr); +bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength); #endif /* __TETHER_H__ */ diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index 282c08d65761..c6d3a83bd890 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -55,7 +55,7 @@ /* The 2nd table is the same as the 1st but with the upper and lower */ /* bytes swapped. To allow an endian tolerant implementation, the byte */ /* halves have been expressed independently here. */ -const BYTE TKIP_Sbox_Lower[256] = { +const u8 TKIP_Sbox_Lower[256] = { 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, @@ -90,7 +90,7 @@ const BYTE TKIP_Sbox_Lower[256] = { 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A }; -const BYTE TKIP_Sbox_Upper[256] = { +const u8 TKIP_Sbox_Upper[256] = { 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, @@ -182,11 +182,11 @@ static unsigned int rotr1(unsigned int a) * */ void TKIPvMixKey( - PBYTE pbyTKey, - PBYTE pbyTA, + u8 * pbyTKey, + u8 * pbyTA, WORD wTSC15_0, DWORD dwTSC47_16, - PBYTE pbyRC4Key + u8 * pbyRC4Key ) { u32 p1k[5]; diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index 47c3a853b92a..b8e5d442ac0f 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -47,11 +47,11 @@ /*--------------------- Export Functions --------------------------*/ void TKIPvMixKey( - PBYTE pbyTKey, - PBYTE pbyTA, + u8 * pbyTKey, + u8 * pbyTA, WORD wTSC15_0, DWORD dwTSC47_16, - PBYTE pbyRC4Key + u8 * pbyRC4Key ); #endif /* __TKIP_H__ */ diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h index 3c81e2b0791d..4ad4f051266e 100644 --- a/drivers/staging/vt6656/tmacro.h +++ b/drivers/staging/vt6656/tmacro.h @@ -34,10 +34,10 @@ /****** Common helper macros ***********************************************/ #if !defined(LOBYTE) -#define LOBYTE(w) ((BYTE)(w)) +#define LOBYTE(w) ((u8)(w)) #endif #if !defined(HIBYTE) -#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) +#define HIBYTE(w) ((u8)(((WORD)(w) >> 8) & 0xFF)) #endif #if !defined(LOWORD) @@ -51,7 +51,7 @@ #define HIDWORD(q) ((q).u.dwHighDword) #if !defined(MAKEWORD) -#define MAKEWORD(lb, hb) ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8))) +#define MAKEWORD(lb, hb) ((WORD)(((u8)(lb)) | (((WORD)((u8)(hb))) << 8))) #endif #if !defined(MAKEDWORD) #define MAKEDWORD(lw, hw) ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16))) diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index d7b648945316..a4cafc643c35 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -35,7 +35,6 @@ /****** Simple typedefs ***************************************************/ -typedef u8 BYTE; typedef u16 WORD; typedef u32 DWORD; @@ -46,8 +45,6 @@ typedef u32 DWORD_PTR; // boolean pointer -typedef BYTE * PBYTE; - typedef WORD * PWORD; typedef DWORD * PDWORD; diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 4bb652bf7cf6..904b5dae5d2a 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -260,7 +260,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice, + WLAN_PROBEREQ_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; vMgrEncodeProbeRequest(&sFrame); sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( @@ -845,7 +845,7 @@ void vRunCommand(struct vnt_private *pDevice) { int ntStatus = STATUS_SUCCESS; - BYTE byTmp; + u8 byTmp; ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index c40e6baa0b5d..5763509b0af0 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -73,7 +73,7 @@ typedef enum tagCMD_STATUS { typedef struct tagCMD_ITEM { CMD_CODE eCmd; - BYTE abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + u8 abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; bool bNeedRadioOFF; bool bRadioCmd; bool bForceSCAN; diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c index baa48a1f0d36..a02ea0328db5 100644 --- a/drivers/staging/vt6656/wctl.c +++ b/drivers/staging/vt6656/wctl.c @@ -213,8 +213,8 @@ bool WCTLbHandleFragment(struct vnt_private *pDevice, PS802_11Header pMACHeader, } } // reserve 8 byte to match MAC RX Buffer - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8); -// pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8); +// pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; @@ -229,7 +229,7 @@ bool WCTLbHandleFragment(struct vnt_private *pDevice, PS802_11Header pMACHeader, (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) && ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((PBYTE) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); + memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((u8 *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 5dced0a43797..c9ad7cacc6e3 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -191,8 +191,8 @@ static bool s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - PBYTE pbyCCSPK, - PBYTE pbyCCSGK + u8 * pbyCCSPK, + u8 * pbyCCSGK ); static void Encyption_Rebuild(struct vnt_private *, PKnownBSS pCurr); @@ -426,7 +426,7 @@ void vMgrDisassocBeginSta(struct vnt_private *pDevice, + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_DISASSOC_FR_MAXLEN; // format fixed field frame structure @@ -496,7 +496,7 @@ static void s_vMgrRxAssocRequest(struct vnt_private *pDevice, memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeAssocRequest(&sFrame); @@ -643,7 +643,7 @@ static void s_vMgrRxReAssocRequest(struct vnt_private *pDevice, //decode the frame memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ)); sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeReassocRequest(&sFrame); if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { @@ -777,7 +777,7 @@ static void s_vMgrRxAssocResponse(struct vnt_private *pDevice, pMgmt->eCurrState == WMAC_STATE_ASSOC) { sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; // decode the frame vMgrDecodeAssocResponse(&sFrame); if ((sFrame.pwCapInfo == NULL) @@ -820,7 +820,7 @@ static void s_vMgrRxAssocResponse(struct vnt_private *pDevice, //if(pDevice->bWPASuppWextEnabled == true) { - BYTE buf[512]; + u8 buf[512]; size_t len; union iwreq_data wrqu; int we_event; @@ -906,7 +906,7 @@ void vMgrAuthenBeginSta(struct vnt_private *pDevice, + WLAN_AUTHEN_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_AUTHEN_FR_MAXLEN; vMgrEncodeAuthen(&sFrame); /* insert values */ @@ -960,7 +960,7 @@ void vMgrDeAuthenBeginSta(struct vnt_private *pDevice, + WLAN_DEAUTHEN_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN; vMgrEncodeDeauthen(&sFrame); /* insert values */ @@ -1012,7 +1012,7 @@ static void s_vMgrRxAuthentication(struct vnt_private *pDevice, // decode the frame sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeAuthen(&sFrame); switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){ case 1: @@ -1082,7 +1082,7 @@ static void s_vMgrRxAuthenSequence_1(struct vnt_private *pDevice, + WLAN_AUTHEN_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_AUTHEN_FR_MAXLEN; // format buffer structure vMgrEncodeAuthen(&sFrame); @@ -1193,7 +1193,7 @@ static void s_vMgrRxAuthenSequence_2(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_AUTHEN_FR_MAXLEN; // format buffer structure vMgrEncodeAuthen(&sFrame); @@ -1297,7 +1297,7 @@ reply: + WLAN_AUTHEN_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_AUTHEN_FR_MAXLEN; // format buffer structure vMgrEncodeAuthen(&sFrame); @@ -1385,7 +1385,7 @@ static void s_vMgrRxDisassociation(struct vnt_private *pDevice, // if is acting an AP.. // a STA is leaving this BSS.. sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { BSSvRemoveOneNode(pDevice, uNodeIndex); } @@ -1395,7 +1395,7 @@ static void s_vMgrRxDisassociation(struct vnt_private *pDevice, } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){ sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeDisassociation(&sFrame); DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason))); @@ -1454,7 +1454,7 @@ static void s_vMgrRxDeauthentication(struct vnt_private *pDevice, // if is acting an AP.. // a STA is leaving this BSS.. sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { BSSvRemoveOneNode(pDevice, uNodeIndex); } @@ -1465,7 +1465,7 @@ static void s_vMgrRxDeauthentication(struct vnt_private *pDevice, else { if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) { sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeDeauthen(&sFrame); pDevice->fWPA_Authened = false; DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason)))); @@ -1576,7 +1576,7 @@ static void s_vMgrRxBeacon(struct vnt_private *pDevice, memset(&sFrame, 0, sizeof(WLAN_FR_BEACON)); sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; // decode the beacon frame vMgrDecodeBeacon(&sFrame); @@ -1672,7 +1672,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) return; } - if(byCurrChannel == (BYTE)pMgmt->uCurrChannel) + if(byCurrChannel == (u8)pMgmt->uCurrChannel) bIsChannelEqual = true; if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { @@ -1785,7 +1785,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) pDevice->byPreambleType = 0; } if (pDevice->byPreambleType != byOldPreambleType) - CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); + CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType); // // Basic Rate Set may change dynamically // @@ -2009,7 +2009,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) pDevice->byPreambleType = 0; } if (pDevice->byPreambleType != byOldPreambleType) - CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); + CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType); // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); @@ -2411,9 +2411,9 @@ void vMgrJoinBSSBegin(struct vnt_private *pDevice, PCMD_STATUS pStatus) if (pItemExtRates->len <= ii) break; } - pItemRates->len += (BYTE)ii; + pItemRates->len += (u8)ii; if (pItemExtRates->len - ii > 0) { - pItemExtRates->len -= (BYTE)ii; + pItemExtRates->len -= (u8)ii; for (uu = 0; uu < pItemExtRates->len; uu ++) { pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii]; } @@ -2466,7 +2466,7 @@ void vMgrJoinBSSBegin(struct vnt_private *pDevice, PCMD_STATUS pStatus) pDevice->byPreambleType = 0; } // Change PreambleType must set RSPINF again - CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); + CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n"); @@ -2597,7 +2597,7 @@ void vMgrJoinBSSBegin(struct vnt_private *pDevice, PCMD_STATUS pStatus) pDevice->byPreambleType = 0; } // Change PreambleType must set RSPINF again - CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); + CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType); // Prepare beacon bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); @@ -2906,7 +2906,7 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure. - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_BEACON_FR_MAXLEN; vMgrEncodeBeacon(&sFrame); // Setup the header @@ -2945,7 +2945,7 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice, sFrame.len += (1) + WLAN_IEHDR_LEN; sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel; + sFrame.pDSParms->byCurrChannel = (u8)uCurrChannel; } // TIM field if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { @@ -3073,7 +3073,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure. - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_PROBERESP_FR_MAXLEN; vMgrEncodeProbeResponse(&sFrame); // Setup the header @@ -3114,7 +3114,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, sFrame.len += (1) + WLAN_IEHDR_LEN; sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel; + sFrame.pDSParms->byCurrChannel = (u8)uCurrChannel; } if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { @@ -3199,7 +3199,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure. - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN; // format fixed field frame structure vMgrEncodeAssocRequest(&sFrame); @@ -3287,7 +3287,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; } // Auth Key Management Suite - pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); + pbyRSN = (u8 *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); *pbyRSN++=0x01; *pbyRSN++=0x00; *pbyRSN++=0x00; @@ -3457,7 +3457,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); /* Setup the sFrame structure. */ - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN; // format fixed field frame structure @@ -3546,7 +3546,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; } // Auth Key Management Suite - pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); + pbyRSN = (u8 *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); *pbyRSN++=0x01; *pbyRSN++=0x00; *pbyRSN++=0x00; @@ -3704,7 +3704,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; vMgrEncodeAssocResponse(&sFrame); // Setup the header @@ -3773,7 +3773,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice, pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); // Setup the sFrame structure - sFrame.pBuf = (PBYTE)pTxPacket->p80211Header; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; vMgrEncodeReassocResponse(&sFrame); // Setup the header @@ -3839,7 +3839,7 @@ static void s_vMgrRxProbeResponse(struct vnt_private *pDevice, memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP)); // decode the frame sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeProbeResponse(&sFrame); if ((sFrame.pqwTimestamp == NULL) @@ -3969,7 +3969,7 @@ static void s_vMgrRxProbeRequest(struct vnt_private *pDevice, memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ)); // decode the frame sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; + sFrame.pBuf = (u8 *)pRxPacket->p80211Header; vMgrDecodeProbeRequest(&sFrame); /* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n", @@ -4000,7 +4000,7 @@ static void s_vMgrRxProbeRequest(struct vnt_private *pDevice, 0, sFrame.pHdr->sA3.abyAddr2, (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PBYTE)pMgmt->abyCurrBSSID, + (u8 *)pMgmt->abyCurrBSSID, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, byPHYType @@ -4199,7 +4199,7 @@ int bMgrPrepareBeaconToSend(struct vnt_private *pDevice, pMgmt->uCurrChannel, pMgmt->wCurrATIMWindow, //0, (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PBYTE)pMgmt->abyCurrBSSID, + (u8 *)pMgmt->abyCurrBSSID, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates ); @@ -4368,12 +4368,12 @@ static bool s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - PBYTE pbyCCSPK, - PBYTE pbyCCSGK + u8 * pbyCCSPK, + u8 * pbyCCSGK ) { - BYTE byMulticastCipher = KEY_CTL_INVALID; - BYTE byCipherMask = 0x00; + u8 byMulticastCipher = KEY_CTL_INVALID; + u8 byCipherMask = 0x00; int i; if (pBSSNode == NULL) diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index f037be3aa164..619ce3c69641 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -45,12 +45,12 @@ /*--------------------- Static Variables --------------------------*/ static int msglevel =MSG_LEVEL_INFO; -const BYTE abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; -const BYTE abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; -const BYTE abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; -const BYTE abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; -const BYTE abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; -const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; +const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; +const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; +const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; +const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; +const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; +const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; /*+ @@ -112,7 +112,7 @@ WPA_ParseRSN( { PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; int i, j, m, n = 0; - PBYTE pbyCaps; + u8 * pbyCaps; WPA_ClearRSN(pBSSList); @@ -209,7 +209,7 @@ WPA_ParseRSN( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2) - pbyCaps = (PBYTE)pIE_RSN_Auth->AuthKSList[n].abyOUI; + pbyCaps = (u8 *)pIE_RSN_Auth->AuthKSList[n].abyOUI; pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); pBSSList->sRSNCapObj.bRSNCapExist = true; @@ -241,13 +241,13 @@ WPA_ParseRSN( -*/ bool WPA_SearchRSN( - BYTE byCmd, - BYTE byEncrypt, + u8 byCmd, + u8 byEncrypt, PKnownBSS pBSSList ) { int ii; - BYTE byPKType = WPA_NONE; + u8 byPKType = WPA_NONE; if (pBSSList->bWPAValid == false) return false; diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h index 0369cbf32c49..2e35856c50f3 100644 --- a/drivers/staging/vt6656/wpa.h +++ b/drivers/staging/vt6656/wpa.h @@ -71,8 +71,8 @@ WPA_ParseRSN( bool WPA_SearchRSN( - BYTE byCmd, - BYTE byEncrypt, + u8 byCmd, + u8 byEncrypt, PKnownBSS pBSSList ); diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index a89456a9137a..71a6fa5a4b54 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -41,14 +41,14 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ -const BYTE abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; -const BYTE abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const BYTE abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; -const BYTE abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -const BYTE abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; +const u8 abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; +const u8 abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +const u8 abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; +const u8 abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +const u8 abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; -const BYTE abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const BYTE abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +const u8 abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +const u8 abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; /*--------------------- Static Functions --------------------------*/ @@ -114,7 +114,7 @@ WPA2vParseRSN ( { int i, j; WORD m = 0, n = 0; - PBYTE pbyOUI; + u8 * pbyOUI; bool bUseGK = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len); @@ -167,7 +167,7 @@ WPA2vParseRSN ( j = 0; pbyOUI = &(pRSN->abyRSN[6]); - for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(BYTE)); i++) { + for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(u8)); i++) { if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i) if ( !memcmp(pbyOUI, abyOUIGK, 4)) { @@ -218,7 +218,7 @@ WPA2vParseRSN ( pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m])); j = 0; pbyOUI = &(pRSN->abyRSN[8+4*m]); - for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) { + for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(u8)); i++) { if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i) if ( !memcmp(pbyOUI, abyOUI8021X, 4)) pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X; @@ -274,7 +274,7 @@ unsigned int WPA2uSetIEs(void *pMgmtHandle, PWLAN_IE_RSN pRSNIEs) (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && (pMgmt->pCurrBSS != NULL)) { /* WPA2 IE */ - pbyBuffer = (PBYTE) pRSNIEs; + pbyBuffer = (u8 *) pRSNIEs; pRSNIEs->byElementID = WLAN_EID_RSN; pRSNIEs->len = 6; //Version(2)+GK(4) pRSNIEs->wVersion = 1; diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index c359252a6b0e..03b14c72d204 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -40,8 +40,8 @@ #define MAX_PMKID_CACHE 16 typedef struct tagsPMKIDInfo { - BYTE abyBSSID[6]; - BYTE abyPMKID[16]; + u8 abyBSSID[6]; + u8 abyPMKID[16]; } PMKIDInfo, *PPMKIDInfo; typedef struct tagSPMKIDCache { diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 53629b26f24d..c0886c161639 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -72,10 +72,10 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) struct viawget_wpa_param *param = ctx; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; DWORD dwKeyIndex = 0; - BYTE abyKey[MAX_KEY_LEN]; - BYTE abySeq[MAX_KEY_LEN]; + u8 abyKey[MAX_KEY_LEN]; + u8 abySeq[MAX_KEY_LEN]; u64 KeyRSC; - BYTE byKeyDecMode = KEY_CTL_WEP; + u8 byKeyDecMode = KEY_CTL_WEP; int ret = 0; int uu; int ii; @@ -108,7 +108,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) return -EINVAL; } else { if (param->u.wpa_key.set_tx) { - pDevice->byKeyIndex = (BYTE)dwKeyIndex; + pDevice->byKeyIndex = (u8)dwKeyIndex; pDevice->bTransmitKey = true; dwKeyIndex |= (1 << 31); } @@ -204,7 +204,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, &KeyRSC, - (PBYTE)abyKey, + (u8 *)abyKey, byKeyDecMode ) == true) && (KeybSetDefaultKey(pDevice, @@ -212,7 +212,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) dwKeyIndex, param->u.wpa_key.key_len, &KeyRSC, - (PBYTE)abyKey, + (u8 *)abyKey, byKeyDecMode ) == true) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); @@ -234,7 +234,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) } if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->addr[0], dwKeyIndex, param->u.wpa_key.key_len, - &KeyRSC, (PBYTE)abyKey, byKeyDecMode + &KeyRSC, (u8 *)abyKey, byKeyDecMode ) == true) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); } else { @@ -250,7 +250,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) } } // BSSID not 0xffffffffffff if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { - pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index; + pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index; pDevice->bTransmitKey = true; } pDevice->bEncryptionEnable = true; -- cgit From 3eaca0d2f5a4137d4a5ecf63cf34cdf13b499bee Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 25 Feb 2013 20:32:52 -0500 Subject: staging: vt6656: replaced custom WORD definition with u16 Checkpatch findings were not resolved. sed -i 's/\bWORD\b/u16/g' drivers/staging/vt6656/*.[ch] sed -i 's/\bPWORD\b/u16 */g' drivers/staging/vt6656/*.[ch] Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211hdr.h | 96 ++++---- drivers/staging/vt6656/80211mgr.c | 76 +++---- drivers/staging/vt6656/80211mgr.h | 54 ++--- drivers/staging/vt6656/aes_ccmp.c | 12 +- drivers/staging/vt6656/aes_ccmp.h | 2 +- drivers/staging/vt6656/baseband.c | 14 +- drivers/staging/vt6656/baseband.h | 2 +- drivers/staging/vt6656/bssdb.c | 6 +- drivers/staging/vt6656/bssdb.h | 38 ++-- drivers/staging/vt6656/card.c | 20 +- drivers/staging/vt6656/card.h | 6 +- drivers/staging/vt6656/datarate.c | 8 +- drivers/staging/vt6656/datarate.h | 2 +- drivers/staging/vt6656/desc.h | 160 ++++++------- drivers/staging/vt6656/device.h | 10 +- drivers/staging/vt6656/dpc.c | 26 +-- drivers/staging/vt6656/hostap.c | 2 +- drivers/staging/vt6656/int.h | 8 +- drivers/staging/vt6656/key.h | 4 +- drivers/staging/vt6656/mac.c | 6 +- drivers/staging/vt6656/main_usb.c | 2 +- drivers/staging/vt6656/mib.h | 4 +- drivers/staging/vt6656/power.c | 2 +- drivers/staging/vt6656/rndis.h | 6 +- drivers/staging/vt6656/rxtx.c | 224 +++++++++--------- drivers/staging/vt6656/rxtx.h | 468 +++++++++++++++++++------------------- drivers/staging/vt6656/srom.h | 32 +-- drivers/staging/vt6656/tether.h | 10 +- drivers/staging/vt6656/tkip.c | 2 +- drivers/staging/vt6656/tkip.h | 2 +- drivers/staging/vt6656/tmacro.h | 10 +- drivers/staging/vt6656/ttype.h | 3 - drivers/staging/vt6656/wcmd.c | 2 +- drivers/staging/vt6656/wcmd.h | 2 +- drivers/staging/vt6656/wmgr.c | 32 +-- drivers/staging/vt6656/wpa.c | 6 +- drivers/staging/vt6656/wpa2.c | 18 +- 37 files changed, 687 insertions(+), 690 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h index 6d181bbc6871..0ce12e9e858f 100644 --- a/drivers/staging/vt6656/80211hdr.h +++ b/drivers/staging/vt6656/80211hdr.h @@ -155,22 +155,22 @@ #ifdef __BIG_ENDIAN /* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) ((((WORD)(n) >> 8) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n) >> 8) \ +#define WLAN_GET_FC_PRVER(n) ((((u16)(n) >> 8) & (BIT0 | BIT1)) +#define WLAN_GET_FC_FTYPE(n) ((((u16)(n) >> 8) & (BIT2 | BIT3)) >> 2) +#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n) >> 8) \ & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((WORD)(n) << 8) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((WORD)(n) << 8) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n) << 8) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((WORD)(n) << 8) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((WORD)(n) << 8) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n) << 8) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((WORD)(n) << 8) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((WORD)(n) << 8) & (BIT15)) >> 15) +#define WLAN_GET_FC_TODS(n) ((((u16)(n) << 8) & (BIT8)) >> 8) +#define WLAN_GET_FC_FROMDS(n) ((((u16)(n) << 8) & (BIT9)) >> 9) +#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n) << 8) & (BIT10)) >> 10) +#define WLAN_GET_FC_RETRY(n) ((((u16)(n) << 8) & (BIT11)) >> 11) +#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n) << 8) & (BIT12)) >> 12) +#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n) << 8) & (BIT13)) >> 13) +#define WLAN_GET_FC_ISWEP(n) ((((u16)(n) << 8) & (BIT14)) >> 14) +#define WLAN_GET_FC_ORDER(n) ((((u16)(n) << 8) & (BIT15)) >> 15) /* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) \ +#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) +#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n) >> 8) \ & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) /* Capability Field bit */ @@ -190,21 +190,21 @@ #else /* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) (((WORD)(n)) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((WORD)(n)) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((WORD)(n)) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((WORD)(n)) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n)) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((WORD)(n)) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((WORD)(n)) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n)) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((WORD)(n)) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((WORD)(n)) & (BIT15)) >> 15) +#define WLAN_GET_FC_PRVER(n) (((u16)(n)) & (BIT0 | BIT1)) +#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT2 | BIT3)) >> 2) +#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) +#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT8)) >> 8) +#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT9)) >> 9) +#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10) +#define WLAN_GET_FC_RETRY(n) ((((u16)(n)) & (BIT11)) >> 11) +#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n)) & (BIT12)) >> 12) +#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13) +#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT14)) >> 14) +#define WLAN_GET_FC_ORDER(n) ((((u16)(n)) & (BIT15)) >> 15) /* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) +#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3)) +#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) /* Capability Field bit */ #define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0) @@ -235,20 +235,20 @@ #define WLAN_SET_CAP_INFO_DSSSOFDM(n) ((n) << 13) #define WLAN_SET_CAP_INFO_GRPACK(n) ((n) << 14) -#define WLAN_SET_FC_PRVER(n) ((WORD)(n)) -#define WLAN_SET_FC_FTYPE(n) (((WORD)(n)) << 2) -#define WLAN_SET_FC_FSTYPE(n) (((WORD)(n)) << 4) -#define WLAN_SET_FC_TODS(n) (((WORD)(n)) << 8) -#define WLAN_SET_FC_FROMDS(n) (((WORD)(n)) << 9) -#define WLAN_SET_FC_MOREFRAG(n) (((WORD)(n)) << 10) -#define WLAN_SET_FC_RETRY(n) (((WORD)(n)) << 11) -#define WLAN_SET_FC_PWRMGT(n) (((WORD)(n)) << 12) -#define WLAN_SET_FC_MOREDATA(n) (((WORD)(n)) << 13) -#define WLAN_SET_FC_ISWEP(n) (((WORD)(n)) << 14) -#define WLAN_SET_FC_ORDER(n) (((WORD)(n)) << 15) - -#define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n)) -#define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4) +#define WLAN_SET_FC_PRVER(n) ((u16)(n)) +#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2) +#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4) +#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8) +#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9) +#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10) +#define WLAN_SET_FC_RETRY(n) (((u16)(n)) << 11) +#define WLAN_SET_FC_PWRMGT(n) (((u16)(n)) << 12) +#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13) +#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14) +#define WLAN_SET_FC_ORDER(n) (((u16)(n)) << 15) + +#define WLAN_SET_SEQ_FRGNUM(n) ((u16)(n)) +#define WLAN_SET_SEQ_SEQNUM(n) (((u16)(n)) << 4) /* ERP Field bit */ @@ -284,8 +284,8 @@ typedef struct { typedef struct tagWLAN_80211HDR_A2 { - WORD wFrameCtl; - WORD wDurationID; + u16 wFrameCtl; + u16 wDurationID; u8 abyAddr1[WLAN_ADDR_LEN]; u8 abyAddr2[WLAN_ADDR_LEN]; @@ -294,24 +294,24 @@ WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; typedef struct tagWLAN_80211HDR_A3 { - WORD wFrameCtl; - WORD wDurationID; + u16 wFrameCtl; + u16 wDurationID; u8 abyAddr1[WLAN_ADDR_LEN]; u8 abyAddr2[WLAN_ADDR_LEN]; u8 abyAddr3[WLAN_ADDR_LEN]; - WORD wSeqCtl; + u16 wSeqCtl; } __attribute__ ((__packed__)) WLAN_80211HDR_A3, *PWLAN_80211HDR_A3; typedef struct tagWLAN_80211HDR_A4 { - WORD wFrameCtl; - WORD wDurationID; + u16 wFrameCtl; + u16 wDurationID; u8 abyAddr1[WLAN_ADDR_LEN]; u8 abyAddr2[WLAN_ADDR_LEN]; u8 abyAddr3[WLAN_ADDR_LEN]; - WORD wSeqCtl; + u16 wSeqCtl; u8 abyAddr4[WLAN_ADDR_LEN]; } __attribute__ ((__packed__)) diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c index b494453c0b0c..6a74c15c95db 100644 --- a/drivers/staging/vt6656/80211mgr.c +++ b/drivers/staging/vt6656/80211mgr.c @@ -100,9 +100,9 @@ vMgrEncodeBeacon( pFrame->pqwTimestamp = (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_CAPINFO); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID; @@ -135,9 +135,9 @@ vMgrDecodeBeacon( pFrame->pqwTimestamp = (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_CAPINFO); /* Information elements */ @@ -291,7 +291,7 @@ vMgrEncodeDisassociation( /* Fixed Fields */ - pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_DISASSOC_OFF_REASON); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason)); } @@ -316,7 +316,7 @@ vMgrDecodeDisassociation( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_DISASSOC_OFF_REASON); } @@ -339,9 +339,9 @@ vMgrEncodeAssocRequest( { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCREQ_OFF_LISTEN_INT); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval)); } @@ -367,9 +367,9 @@ vMgrDecodeAssocRequest( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCREQ_OFF_LISTEN_INT); /* Information elements */ @@ -430,11 +430,11 @@ vMgrEncodeAssocResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_AID); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid)); @@ -462,11 +462,11 @@ vMgrDecodeAssocResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_ASSOCRESP_OFF_AID); /* Information elements */ @@ -503,9 +503,9 @@ vMgrEncodeReassocRequest( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_LISTEN_INT); pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_CURR_AP); @@ -534,9 +534,9 @@ vMgrDecodeReassocRequest( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_LISTEN_INT); pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCREQ_OFF_CURR_AP); @@ -677,9 +677,9 @@ vMgrEncodeProbeResponse( pFrame->pqwTimestamp = (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_CAP_INFO); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO + @@ -713,9 +713,9 @@ vMgrDecodeProbeResponse( pFrame->pqwTimestamp = (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_CAP_INFO); /* Information elements */ @@ -820,11 +820,11 @@ vMgrEncodeAuthen( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_STATUS); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus)); } @@ -851,11 +851,11 @@ vMgrDecodeAuthen( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_AUTHEN_OFF_STATUS); /* Information elements */ @@ -886,7 +886,7 @@ vMgrEncodeDeauthen( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_DEAUTHEN_OFF_REASON); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason)); } @@ -911,7 +911,7 @@ vMgrDecodeDeauthen( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_DEAUTHEN_OFF_REASON); } @@ -935,11 +935,11 @@ vMgrEncodeReassocResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_AID); pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid)); @@ -968,11 +968,11 @@ vMgrDecodeReassocResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_REASSOCRESP_OFF_AID); /* Information elements */ diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index 2a88f0c2c7c7..990d44784aa0 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -251,7 +251,7 @@ WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; typedef struct _WLAN_IE_FH_PARMS { u8 byElementID; u8 len; - WORD wDwellTime; + u16 wDwellTime; u8 byHopSet; u8 byHopPattern; u8 byHopIndex; @@ -273,8 +273,8 @@ typedef struct tagWLAN_IE_CF_PARMS { u8 len; u8 byCFPCount; u8 byCFPPeriod; - WORD wCFPMaxDuration; - WORD wCFPDurRemaining; + u16 wCFPMaxDuration; + u16 wCFPDurRemaining; } __attribute__ ((__packed__)) WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS; @@ -295,7 +295,7 @@ WLAN_IE_TIM, *PWLAN_IE_TIM; typedef struct tagWLAN_IE_IBSS_PARMS { u8 byElementID; u8 len; - WORD wATIMWindow; + u16 wATIMWindow; } __attribute__ ((__packed__)) WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; @@ -313,9 +313,9 @@ typedef struct tagWLAN_IE_RSN_EXT { u8 byElementID; u8 len; u8 abyOUI[4]; - WORD wVersion; + u16 wVersion; u8 abyMulticast[4]; - WORD wPKCount; + u16 wPKCount; struct { u8 abyOUI[4]; } PKSList[1]; @@ -324,7 +324,7 @@ typedef struct tagWLAN_IE_RSN_EXT { #pragma pack(1) typedef struct tagWLAN_IE_RSN_AUTH { - WORD wAuthCount; + u16 wAuthCount; struct { u8 abyOUI[4]; } AuthKSList[1]; @@ -335,7 +335,7 @@ typedef struct tagWLAN_IE_RSN_AUTH { typedef struct tagWLAN_IE_RSN { u8 byElementID; u8 len; - WORD wVersion; + u16 wVersion; u8 abyRSN[WLAN_MIN_ARRAY]; } WLAN_IE_RSN, *PWLAN_IE_RSN; @@ -514,8 +514,8 @@ typedef struct tagWLAN_FR_BEACON { PUWLAN_80211HDR pHdr; /* fixed fields */ u64 *pqwTimestamp; - PWORD pwBeaconInterval; - PWORD pwCapInfo; + u16 * pwBeaconInterval; + u16 * pwCapInfo; /* info elements */ PWLAN_IE_SSID pSSID; PWLAN_IE_SUPP_RATES pSuppRates; @@ -558,7 +558,7 @@ typedef struct tagWLAN_FR_DISASSOC { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwReason; + u16 * pwReason; /* info elements */ } WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC; @@ -571,8 +571,8 @@ typedef struct tagWLAN_FR_ASSOCREQ { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwCapInfo; - PWORD pwListenInterval; + u16 * pwCapInfo; + u16 * pwListenInterval; /* info elements */ PWLAN_IE_SSID pSSID; PWLAN_IE_SUPP_RATES pSuppRates; @@ -595,9 +595,9 @@ typedef struct tagWLAN_FR_ASSOCRESP { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwCapInfo; - PWORD pwStatus; - PWORD pwAid; + u16 * pwCapInfo; + u16 * pwStatus; + u16 * pwAid; /* info elements */ PWLAN_IE_SUPP_RATES pSuppRates; PWLAN_IE_SUPP_RATES pExtSuppRates; @@ -613,8 +613,8 @@ typedef struct tagWLAN_FR_REASSOCREQ { PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwCapInfo; - PWORD pwListenInterval; + u16 * pwCapInfo; + u16 * pwListenInterval; PIEEE_ADDR pAddrCurrAP; /* info elements */ @@ -637,9 +637,9 @@ typedef struct tagWLAN_FR_REASSOCRESP { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwCapInfo; - PWORD pwStatus; - PWORD pwAid; + u16 * pwCapInfo; + u16 * pwStatus; + u16 * pwAid; /* info elements */ PWLAN_IE_SUPP_RATES pSuppRates; PWLAN_IE_SUPP_RATES pExtSuppRates; @@ -670,8 +670,8 @@ typedef struct tagWLAN_FR_PROBERESP { PUWLAN_80211HDR pHdr; /* fixed fields */ u64 *pqwTimestamp; - PWORD pwBeaconInterval; - PWORD pwCapInfo; + u16 * pwBeaconInterval; + u16 * pwCapInfo; /* info elements */ PWLAN_IE_SSID pSSID; PWLAN_IE_SUPP_RATES pSuppRates; @@ -698,9 +698,9 @@ typedef struct tagWLAN_FR_AUTHEN { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwAuthAlgorithm; - PWORD pwAuthSequence; - PWORD pwStatus; + u16 * pwAuthAlgorithm; + u16 * pwAuthSequence; + u16 * pwStatus; /* info elements */ PWLAN_IE_CHALLENGE pChallenge; @@ -714,7 +714,7 @@ typedef struct tagWLAN_FR_DEAUTHEN { u8 * pBuf; PUWLAN_80211HDR pHdr; /* fixed fields */ - PWORD pwReason; + u16 * pwReason; /* info elements */ diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index 688e6138d810..0186cee0d6fb 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -231,7 +231,7 @@ void AESv128(u8 *key, u8 *data, u8 *ciphertext) * */ -bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, WORD wFrameSize) +bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize) { u8 abyNonce[13]; u8 MIC_IV[16]; @@ -246,17 +246,17 @@ bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, WORD wFrameSize) PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; u8 * pbyIV; u8 * pbyPayload; - WORD wHLen = 22; + u16 wHLen = 22; /* 8 is IV, 8 is MIC, 4 is CRC */ - WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN; + u16 wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN; bool bA4 = false; u8 byTmp; - WORD wCnt; + u16 wCnt; int ii, jj, kk; pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(PWORD) pbyFrame) && - WLAN_GET_FC_FROMDS(*(PWORD) pbyFrame)) { + if (WLAN_GET_FC_TODS(*(u16 *) pbyFrame) && + WLAN_GET_FC_FROMDS(*(u16 *) pbyFrame)) { bA4 = true; pbyIV += 6; /* 6 is 802.11 address4 */ wHLen += 6; diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h index f5ea0f164774..349fe9effa3e 100644 --- a/drivers/staging/vt6656/aes_ccmp.h +++ b/drivers/staging/vt6656/aes_ccmp.h @@ -41,6 +41,6 @@ /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ -bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, WORD wFrameSize); +bool AESbGenCCMP(u8 * pbyRxKey, u8 * pbyFrame, u16 wFrameSize); #endif /* __AES_CCMP_H__ */ diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index ac33206715b3..93e297841f8d 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -655,7 +655,7 @@ u8 abyVT3184_VT3226D0[] = { 0x00, }; -const WORD awcFrameTime[MAX_RATE] = +const u16 awcFrameTime[MAX_RATE] = {10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216}; /*--------------------- Static Functions --------------------------*/ @@ -694,7 +694,7 @@ BBuGetFrameTime( u8 byPreambleType, u8 byPktType, unsigned int cbFrameLength, - WORD wRate + u16 wRate ) { unsigned int uFrameTime; @@ -900,11 +900,11 @@ void BBvCalculateParameter(struct vnt_private *pDevice, u32 cbFrameLength, *pbyPhySrv = 0x00; if (bExtBit) *pbyPhySrv = *pbyPhySrv | 0x80; - *pwPhyLen = (WORD) cbUsCount; + *pwPhyLen = (u16) cbUsCount; } else { *pbyPhySrv = 0x00; - *pwPhyLen = (WORD)cbFrameLength; + *pwPhyLen = (u16)cbFrameLength; } } @@ -940,7 +940,7 @@ void BBvSetAntennaMode(struct vnt_private *pDevice, u8 byAntennaMode) CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_SET_ANTMD, - (WORD) byAntennaMode, + (u16) byAntennaMode, 0, 0, NULL); @@ -963,10 +963,10 @@ void BBvSetAntennaMode(struct vnt_private *pDevice, u8 byAntennaMode) int BBbVT3184Init(struct vnt_private *pDevice) { int ntStatus; - WORD wLength; + u16 wLength; u8 * pbyAddr; u8 * pbyAgc; - WORD wLengthAgc; + u16 wLengthAgc; u8 abyArray[256]; ntStatus = CONTROLnsRequestIn(pDevice, diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index 935b19f792e8..a6c3448e77ee 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -100,7 +100,7 @@ BBuGetFrameTime( u8 byPreambleType, u8 byFreqType, unsigned int cbFrameLength, - WORD wRate + u16 wRate ); void BBvCalculateParameter(struct vnt_private *, u32 cbFrameLength, diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index e08f719709a8..bbe348e98b9a 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -72,14 +72,14 @@ static int msglevel =MSG_LEVEL_INFO; -const WORD awHWRetry0[5][5] = { +const u16 awHWRetry0[5][5] = { {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} }; -const WORD awHWRetry1[5][5] = { +const u16 awHWRetry1[5][5] = { {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, @@ -1205,7 +1205,7 @@ void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, byPktNum = (byPktNO & 0x0F) >> 4; byTxRetry = (byTSR & 0xF0) >> 4; - wRate = (WORD) (byPktNO & 0xF0) >> 4; + wRate = (u16) (byPktNO & 0xF0) >> 4; wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl; pbyDestAddr = (u8 *) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]); diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index d329f4bbe6e7..6f72539e4cca 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -86,7 +86,7 @@ typedef struct tagSERPObject { typedef struct tagSRSNCapObject { bool bRSNCapExist; - WORD wRSNCap; + u16 wRSNCap; } SRSNCapObject, *PSRSNCapObject; // BSS info(AP) @@ -99,12 +99,12 @@ typedef struct tagKnownBSS { u8 abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; unsigned int uRSSI; u8 bySQ; - WORD wBeaconInterval; - WORD wCapInfo; + u16 wBeaconInterval; + u16 wCapInfo; u8 abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; u8 byRxRate; -// WORD wATIMWindow; +// u16 wATIMWindow; u8 byRSSIStatCnt; signed long ldBmMAX; signed long ldBmAverage[RSSI_STAT_COUNT]; @@ -116,9 +116,9 @@ typedef struct tagKnownBSS { bool bWPAValid; u8 byGKType; u8 abyPKType[4]; - WORD wPKCount; + u16 wPKCount; u8 abyAuthType[4]; - WORD wAuthCount; + u16 wAuthCount; u8 byDefaultK_as_PK; u8 byReplayIdx; //-- @@ -126,16 +126,16 @@ typedef struct tagKnownBSS { //++ WPA2 informations bool bWPA2Valid; u8 byCSSGK; - WORD wCSSPKCount; + u16 wCSSPKCount; u8 abyCSSPK[4]; - WORD wAKMSSAuthCount; + u16 wAKMSSAuthCount; u8 abyAKMSSAuthType[4]; //++ wpactl u8 byWPAIE[MAX_WPA_IE_LEN]; u8 byRSNIE[MAX_WPA_IE_LEN]; - WORD wWPALen; - WORD wRSNLen; + u16 wWPALen; + u16 wRSNLen; // Clear count unsigned int uClearCount; @@ -171,22 +171,22 @@ typedef struct tagKnownNodeDB { u8 abyMACAddr[WLAN_ADDR_LEN]; u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - WORD wTxDataRate; + u16 wTxDataRate; bool bShortPreamble; bool bERPExist; bool bShortSlotTime; unsigned int uInActiveCount; - WORD wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. - WORD wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. - WORD wSuppRate; + u16 wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. + u16 wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. + u16 wSuppRate; u8 byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode u8 byTopCCKBasicRate; //Records the highest basic rate in CCK mode // For AP mode struct sk_buff_head sTxPSQueue; - WORD wCapInfo; - WORD wListenInterval; - WORD wAID; + u16 wCapInfo; + u16 wListenInterval; + u16 wAID; NODE_STATE eNodeState; bool bPSEnable; bool bRxPSPoll; @@ -194,7 +194,7 @@ typedef struct tagKnownNodeDB { unsigned long ulLastRxJiffer; u8 bySuppRate; DWORD dwFlags; - WORD wEnQueueCnt; + u16 wEnQueueCnt; bool bOnFly; unsigned long long KeyRSC; @@ -202,7 +202,7 @@ typedef struct tagKnownNodeDB { DWORD dwKeyIndex; u8 byCipherSuite; DWORD dwTSC47_16; - WORD wTSC15_0; + u16 wTSC15_0; unsigned int uWepKeyLength; u8 abyWepKey[WLAN_WEPMAX_KEYLEN]; // diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 2cd120ba4576..40f58d085e1e 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -71,10 +71,10 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -//const WORD cwRXBCNTSFOff[MAX_RATE] = +//const u16 cwRXBCNTSFOff[MAX_RATE] = //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; -const WORD cwRXBCNTSFOff[MAX_RATE] = +const u16 cwRXBCNTSFOff[MAX_RATE] = {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3}; /*--------------------- Static Functions --------------------------*/ @@ -114,7 +114,7 @@ void CARDbSetMediaChannel(struct vnt_private *pDevice, u32 uConnectionChannel) CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_SELECT_CHANNLE, - (WORD) uConnectionChannel, + (u16) uConnectionChannel, 0, 0, NULL @@ -220,7 +220,7 @@ static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx) */ void CARDvCalculateOFDMRParameter ( - WORD wRate, + u16 wRate, u8 byBBType, u8 * pbyTxRate, u8 * pbyRsvTime @@ -571,7 +571,7 @@ void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) //Determines the highest basic rate. for (ii = RATE_54M; ii >= RATE_6M; ii --) { - if ( (pDevice->wBasicRate) & ((WORD)(1<wBasicRate) & ((u16)(1<byTopOFDMBasicRate = byTopOFDM; for (ii = RATE_11M;; ii --) { - if ( (pDevice->wBasicRate) & ((WORD)(1<wBasicRate) & ((u16)(1<= RATE_6M; ii --) { - if ((pDevice->wBasicRate) & ((WORD)(1<wBasicRate) & ((u16)(1<wSuppRate & (0x0001< dwThroughput) && (bAutoRate[ii]==true) ) { dwThroughput = dwThroughputTbl[ii]; - wIdxDownRate = (WORD) ii; + wIdxDownRate = (u16) ii; } } psNodeDBTable->wTxDataRate = wIdxDownRate; diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 355e51f3ff16..d86e537176d0 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -84,7 +84,7 @@ RATEuSetIE( unsigned int uRateLen ); -WORD +u16 RATEwGetRateIdx( u8 byRate ); diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index bfbaccd63012..a93eb5fa92c9 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -147,38 +147,38 @@ * RsvTime buffer header */ typedef struct tagSRrvTime_gRTS { - WORD wRTSTxRrvTime_ba; - WORD wRTSTxRrvTime_aa; - WORD wRTSTxRrvTime_bb; - WORD wReserved; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_ba; + u16 wRTSTxRrvTime_aa; + u16 wRTSTxRrvTime_bb; + u16 wReserved; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; } __attribute__ ((__packed__)) SRrvTime_gRTS, *PSRrvTime_gRTS; typedef const SRrvTime_gRTS *PCSRrvTime_gRTS; typedef struct tagSRrvTime_gCTS { - WORD wCTSTxRrvTime_ba; - WORD wReserved; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wReserved; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; } __attribute__ ((__packed__)) SRrvTime_gCTS, *PSRrvTime_gCTS; typedef const SRrvTime_gCTS *PCSRrvTime_gCTS; typedef struct tagSRrvTime_ab { - WORD wRTSTxRrvTime; - WORD wTxRrvTime; + u16 wRTSTxRrvTime; + u16 wTxRrvTime; } __attribute__ ((__packed__)) SRrvTime_ab, *PSRrvTime_ab; typedef const SRrvTime_ab *PCSRrvTime_ab; typedef struct tagSRrvTime_atim { - WORD wCTSTxRrvTime_ba; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wTxRrvTime_a; } __attribute__ ((__packed__)) SRrvTime_atim, *PSRrvTime_atim; @@ -188,8 +188,8 @@ typedef const SRrvTime_atim *PCSRrvTime_atim; * RTS buffer header */ typedef struct tagSRTSData { - WORD wFrameControl; - WORD wDurationID; + u16 wFrameControl; + u16 wDurationID; u8 abyRA[ETH_ALEN]; u8 abyTA[ETH_ALEN]; } __attribute__ ((__packed__)) @@ -200,14 +200,14 @@ typedef const SRTSData *PCSRTSData; typedef struct tagSRTS_g { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_ba; - WORD wDuration_aa; - WORD wDuration_bb; - WORD wReserved; + u16 wTransmitLength_a; + u16 wDuration_ba; + u16 wDuration_aa; + u16 wDuration_bb; + u16 wReserved; SRTSData Data; } __attribute__ ((__packed__)) SRTS_g, *PSRTS_g; @@ -216,18 +216,18 @@ typedef const SRTS_g *PCSRTS_g; typedef struct tagSRTS_g_FB { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_ba; - WORD wDuration_aa; - WORD wDuration_bb; - WORD wReserved; - WORD wRTSDuration_ba_f0; - WORD wRTSDuration_aa_f0; - WORD wRTSDuration_ba_f1; - WORD wRTSDuration_aa_f1; + u16 wTransmitLength_a; + u16 wDuration_ba; + u16 wDuration_aa; + u16 wDuration_bb; + u16 wReserved; + u16 wRTSDuration_ba_f0; + u16 wRTSDuration_aa_f0; + u16 wRTSDuration_ba_f1; + u16 wRTSDuration_aa_f1; SRTSData Data; } __attribute__ ((__packed__)) SRTS_g_FB, *PSRTS_g_FB; @@ -237,9 +237,9 @@ typedef const SRTS_g_FB *PCSRTS_g_FB; typedef struct tagSRTS_ab { u8 bySignalField; u8 byServiceField; - WORD wTransmitLength; - WORD wDuration; - WORD wReserved; + u16 wTransmitLength; + u16 wDuration; + u16 wReserved; SRTSData Data; } __attribute__ ((__packed__)) SRTS_ab, *PSRTS_ab; @@ -249,11 +249,11 @@ typedef const SRTS_ab *PCSRTS_ab; typedef struct tagSRTS_a_FB { u8 bySignalField; u8 byServiceField; - WORD wTransmitLength; - WORD wDuration; - WORD wReserved; - WORD wRTSDuration_f0; - WORD wRTSDuration_f1; + u16 wTransmitLength; + u16 wDuration; + u16 wReserved; + u16 wRTSDuration_f0; + u16 wRTSDuration_f1; SRTSData Data; } __attribute__ ((__packed__)) SRTS_a_FB, *PSRTS_a_FB; @@ -264,19 +264,19 @@ typedef const SRTS_a_FB *PCSRTS_a_FB; * CTS buffer header */ typedef struct tagSCTSData { - WORD wFrameControl; - WORD wDurationID; + u16 wFrameControl; + u16 wDurationID; u8 abyRA[ETH_ALEN]; - WORD wReserved; + u16 wReserved; } __attribute__ ((__packed__)) SCTSData, *PSCTSData; typedef struct tagSCTS { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; - WORD wDuration_ba; - WORD wReserved; + u16 wTransmitLength_b; + u16 wDuration_ba; + u16 wReserved; SCTSData Data; } __attribute__ ((__packed__)) SCTS, *PSCTS; @@ -286,11 +286,11 @@ typedef const SCTS *PCSCTS; typedef struct tagSCTS_FB { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; - WORD wDuration_ba; - WORD wReserved; - WORD wCTSDuration_ba_f0; - WORD wCTSDuration_ba_f1; + u16 wTransmitLength_b; + u16 wDuration_ba; + u16 wReserved; + u16 wCTSDuration_ba_f0; + u16 wCTSDuration_ba_f1; SCTSData Data; } __attribute__ ((__packed__)) SCTS_FB, *PSCTS_FB; @@ -302,17 +302,17 @@ typedef const SCTS_FB *PCSCTS_FB; */ typedef struct tagSTxBufHead { u32 adwTxKey[4]; - WORD wFIFOCtl; - WORD wTimeStamp; - WORD wFragCtl; - WORD wReserved; + u16 wFIFOCtl; + u16 wTimeStamp; + u16 wFragCtl; + u16 wReserved; } __attribute__ ((__packed__)) STxBufHead, *PSTxBufHead; typedef const STxBufHead *PCSTxBufHead; typedef struct tagSTxShortBufHead { - WORD wFIFOCtl; - WORD wTimeStamp; + u16 wFIFOCtl; + u16 wTimeStamp; } __attribute__ ((__packed__)) STxShortBufHead, *PSTxShortBufHead; typedef const STxShortBufHead *PCSTxShortBufHead; @@ -323,14 +323,14 @@ typedef const STxShortBufHead *PCSTxShortBufHead; typedef struct tagSTxDataHead_g { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } __attribute__ ((__packed__)) STxDataHead_g, *PSTxDataHead_g; @@ -339,16 +339,16 @@ typedef const STxDataHead_g *PCSTxDataHead_g; typedef struct tagSTxDataHead_g_FB { u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } __attribute__ ((__packed__)) STxDataHead_g_FB, *PSTxDataHead_g_FB; typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB; @@ -356,9 +356,9 @@ typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB; typedef struct tagSTxDataHead_ab { u8 bySignalField; u8 byServiceField; - WORD wTransmitLength; - WORD wDuration; - WORD wTimeStampOff; + u16 wTransmitLength; + u16 wDuration; + u16 wTimeStampOff; } __attribute__ ((__packed__)) STxDataHead_ab, *PSTxDataHead_ab; typedef const STxDataHead_ab *PCSTxDataHead_ab; @@ -366,11 +366,11 @@ typedef const STxDataHead_ab *PCSTxDataHead_ab; typedef struct tagSTxDataHead_a_FB { u8 bySignalField; u8 byServiceField; - WORD wTransmitLength; - WORD wDuration; - WORD wTimeStampOff; - WORD wDuration_f0; - WORD wDuration_f1; + u16 wTransmitLength; + u16 wDuration; + u16 wTimeStampOff; + u16 wDuration_f0; + u16 wDuration_f1; } __attribute__ ((__packed__)) STxDataHead_a_FB, *PSTxDataHead_a_FB; typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB; @@ -403,7 +403,7 @@ SSecretKey; typedef struct tagSKeyEntry { u8 abyAddrHi[2]; - WORD wKCTL; + u16 wKCTL; u8 abyAddrLo[4]; u32 dwKey0[4]; u32 dwKey1[4]; diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 486de1e25a58..f16428df359a 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -311,14 +311,14 @@ typedef struct tagSQuietControl { bool bEnable; DWORD dwStartTime; u8 byPeriod; - WORD wDuration; + u16 wDuration; } SQuietControl, *PSQuietControl; /* The receive duplicate detection cache entry */ typedef struct tagSCacheEntry{ - WORD wFmSequence; + u16 wFmSequence; u8 abyAddr2[ETH_ALEN]; - WORD wFrameCtl; + u16 wFrameCtl; } SCacheEntry, *PSCacheEntry; typedef struct tagSCache{ @@ -335,8 +335,8 @@ typedef struct tagSCache{ */ typedef struct tagSDeFragControlBlock { - WORD wSequence; - WORD wFragNum; + u16 wSequence; + u16 wFragNum; u8 abyAddr2[ETH_ALEN]; unsigned int uLifetime; struct sk_buff* skb; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e53b77b393a9..d63a946b2ac9 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -155,11 +155,11 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, cbHeaderSize += 6; } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { cbHeaderSize += 6; - pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); + pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize); if ((*pwType == cpu_to_be16(ETH_P_IPX)) || (*pwType == cpu_to_le16(0xF380))) { cbHeaderSize -= 8; - pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); + pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize); if (bIsWEP) { if (bExtIV) { *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV @@ -174,7 +174,7 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice, } else { cbHeaderSize -= 2; - pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); + pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize); if (bIsWEP) { if (bExtIV) { *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV @@ -328,7 +328,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding //if SQ3 the range is 24~27, if no SQ3 the range is 20~23 //real Frame size in PLCPLength field. - pwPLCP_Length = (PWORD) (pbyDAddress + 6); + pwPLCP_Length = (u16 *) (pbyDAddress + 6); //Fix hardware bug => PLCP_Length error if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) || ((BytesToIndicate - (*pwPLCP_Length)) < 24) || @@ -625,7 +625,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, u8 Protocol_Version; //802.1x Authentication u8 Packet_Type; //802.1x Authentication u8 Descriptor_type; - WORD Key_info; + u16 Key_info; if (bIsWEP) cbIVOffset = 8; else @@ -837,12 +837,12 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || (pKey->byCipherSuite == KEY_CTL_CCMP))) { if (bIsWEP) { - WORD wLocalTSC15_0 = 0; + u16 wLocalTSC15_0 = 0; DWORD dwLocalTSC47_16 = 0; unsigned long long RSC = 0; // endian issues RSC = *((unsigned long long *) &(pKey->KeyRSC)); - wLocalTSC15_0 = (WORD) RSC; + wLocalTSC15_0 = (u16) RSC; dwLocalTSC47_16 = (DWORD) (RSC>>16); RSC = dwRxTSC47_16; @@ -1047,8 +1047,8 @@ static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, *pdwRxTSC47_16 = 0; pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) && - WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) { + if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) && + WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) { pbyIV += 6; // 6 is 802.11 address4 PayloadLen -= 6; } @@ -1141,7 +1141,7 @@ static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); } else { - *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV); + *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); @@ -1183,8 +1183,8 @@ static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, *pdwRxTSC47_16 = 0; pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) && - WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) { + if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) && + WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) { pbyIV += 6; // 6 is 802.11 address4 PayloadLen -= 6; } @@ -1241,7 +1241,7 @@ static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); } else { - *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV); + *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index ab828b58dde7..0319f928c1fd 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -242,7 +242,7 @@ static int hostap_add_sta(struct vnt_private *pDevice, pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid; + pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)param->u.add_sta.aid; pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index b8a79433d4d2..180ea57f9888 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -37,16 +37,16 @@ typedef struct tagSINTData { u8 byTSR0; u8 byPkt0; - WORD wTime0; + u16 wTime0; u8 byTSR1; u8 byPkt1; - WORD wTime1; + u16 wTime1; u8 byTSR2; u8 byPkt2; - WORD wTime2; + u16 wTime2; u8 byTSR3; u8 byPkt3; - WORD wTime3; + u16 wTime3; u64 qwTSF; u8 byISR0; u8 byISR1; diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index d5ff9c755212..217decd33fce 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -62,7 +62,7 @@ typedef struct tagSKeyItem u8 abyKey[MAX_KEY_LEN]; u64 KeyRSC; DWORD dwTSC47_16; - WORD wTSC15_0; + u16 wTSC15_0; u8 byCipherSuite; u8 byReserved0; DWORD dwKeyIndex; @@ -77,7 +77,7 @@ typedef struct tagSKeyTable SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 DWORD dwGTKeyIndex; // GroupTransmitKey Index bool bInUse; - WORD wKeyCtl; + u16 wKeyCtl; bool bSoftWEP; u8 byReserved1[6]; } SKeyTable, *PSKeyTable; //352 diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index eccba6a6dbf0..30dcdcc68d2e 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -88,7 +88,7 @@ void MACvSetMultiAddrByHash(struct vnt_private *pDevice, u8 byHashIdx) CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE_MASK, - (WORD) (MAC_REG_MAR0 + uByteIdx), + (u16) (MAC_REG_MAR0 + uByteIdx), MESSAGE_REQUEST_MACREG, 2, pbyData); @@ -117,7 +117,7 @@ void MACvWriteMultiAddr(struct vnt_private *pDevice, u32 uByteIdx, u8 byData) byData1 = byData; CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, - (WORD) (MAC_REG_MAR0 + uByteIdx), + (u16) (MAC_REG_MAR0 + uByteIdx), MESSAGE_REQUEST_MACREG, 1, &byData1); @@ -310,7 +310,7 @@ void MACvSetKeyEntry(struct vnt_private *pDevice, u16 wKeyCtl, u32 uEntryIdx, CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_SETKEY, wOffset, - (WORD)uKeyIdx, + (u16)uKeyIdx, 24, pbyData ); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index a38d2cb9d979..ba8948a14027 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -418,7 +418,7 @@ static int device_init_registers(struct vnt_private *pDevice, pDevice->bNonERPPresent = false; pDevice->bBarkerPreambleMd = false; if ( pDevice->bFixRate ) { - pDevice->wCurrentRate = (WORD) pDevice->uConnectionRate; + pDevice->wCurrentRate = (u16) pDevice->uConnectionRate; } else { if ( pDevice->byBBType == BB_TYPE_11B ) pDevice->wCurrentRate = RATE_11M; diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 967486554312..7ec4f02d17ec 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -229,8 +229,8 @@ typedef struct tagSISRCounters { // typedef struct tagSTxPktInfo { u8 byBroadMultiUni; - WORD wLength; - WORD wFIFOCtl; + u16 wLength; + u16 wFIFOCtl; u8 abyDestAddr[ETH_ALEN]; } STxPktInfo, *PSTxPktInfo; diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 527c259f6758..f3445109eeaf 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -290,7 +290,7 @@ int PSbSendNullPacket(struct vnt_private *pDevice) pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(flags); if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) - pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); + pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((u16)WLAN_SET_FC_TODS(1)); memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h index e14b4f71aec8..8dd611c18036 100644 --- a/drivers/staging/vt6656/rndis.h +++ b/drivers/staging/vt6656/rndis.h @@ -103,7 +103,7 @@ typedef struct _RSP_CARD_INIT typedef struct _CMD_SET_KEY { - WORD wKCTL; + u16 wKCTL; u8 abyMacAddr[6]; u8 abyKey[16]; } CMD_SET_KEY, *PCMD_SET_KEY; @@ -147,12 +147,12 @@ typedef struct _CMD_CHANGE_BBTYPE DWORD dwRSPINF_b_2; DWORD dwRSPINF_b_55; DWORD dwRSPINF_b_11; - WORD wRSPINF_a[9]; + u16 wRSPINF_a[9]; } CMD_CHANGE_BBTYPE, *PCMD_CHANGE_BBTYPE; /*--------------------- Export Macros -------------------------*/ -#define EXCH_WORD(w) ((WORD)((WORD)(w)<<8) | (WORD)((WORD)(w)>>8)) +#define EXCH_WORD(w) ((u16)((u16)(w)<<8) | (u16)((u16)(w)>>8)) /*--------------------- Export Variables --------------------------*/ diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index d019b44bdc50..b542ec3fdc96 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -74,16 +74,16 @@ static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Definitions -------------------------*/ -const WORD wTimeStampOff[2][MAX_RATE] = { +const u16 wTimeStampOff[2][MAX_RATE] = { {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble }; -const WORD wFB_Opt0[2][5] = { +const u16 wFB_Opt0[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 }; -const WORD wFB_Opt1[2][5] = { +const u16 wFB_Opt1[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 }; @@ -268,7 +268,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf, // Make IV *pdwIV = 0; *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0)); + *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0)); //Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); @@ -360,9 +360,9 @@ static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType, uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate); if (byPktType == PK_TYPE_11B) {//llb,CCK mode - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate); + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate); } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate); + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate); } if (bNeedAck) { @@ -671,10 +671,10 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff - pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz @@ -688,17 +688,17 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) + (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp - pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, + pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz - pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, + pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz @@ -711,19 +711,19 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) + (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); //Get Duration and TimeStamp - pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz - pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, + pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz - pBuf->wDuration_a_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, + pBuf->wDuration_a_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz - pBuf->wDuration_a_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, + pBuf->wDuration_a_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]; pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]; @@ -737,14 +737,14 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff - pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz - pBuf->wDuration_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, + pBuf->wDuration_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz - pBuf->wDuration_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, + pBuf->wDuration_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz if(uDMAIdx!=TYPE_ATIMDMA) { pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]; @@ -754,10 +754,10 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff - pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); @@ -772,10 +772,10 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice, PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (PWORD)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); //Get Duration and TimeStampOff - pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, + pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); @@ -810,17 +810,17 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_g pBuf = (PSRTS_g)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); //Get Duration - pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData - pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData - pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wDuration_bb = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->wDuration_aa = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData + pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data pBuf->Data.wDurationID = pBuf->wDuration_aa; //Get RTS Frame body @@ -852,21 +852,21 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a) ); pBuf->wTransmitLength_a = cpu_to_le16(wLen); //Get Duration - pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData - pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData - pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData - pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData + pBuf->wDuration_bb = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->wDuration_aa = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData + pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData + pBuf->wRTSDuration_ba_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_aa_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_ba_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_aa_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData pBuf->Data.wDurationID = pBuf->wDuration_aa; //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 @@ -901,11 +901,11 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration - pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData + pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData pBuf->Data.wDurationID = pBuf->wDuration; //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 @@ -936,13 +936,13 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration - pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData - pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData - pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0: + pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData + pBuf->wRTSDuration_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData + pBuf->wRTSDuration_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0: pBuf->Data.wDurationID = pBuf->wDuration; //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 @@ -972,11 +972,11 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType, PSRTS_ab pBuf = (PSRTS_ab)pvRTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField) ); pBuf->wTransmitLength = cpu_to_le16(wLen); //Get Duration - pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData pBuf->Data.wDurationID = pBuf->wDuration; //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 @@ -1028,18 +1028,18 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx, PSCTS_FB pBuf = (PSCTS_FB)pvCTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); - pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wDuration_ba = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data pBuf->wDuration_ba += pDevice->wCTSDuration; pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); //Get CTSDuration_ba_f0 - pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wCTSDuration_ba_f0 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration; pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0); //Get CTSDuration_ba_f1 - pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wCTSDuration_ba_f1 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration; pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1); //Get CTS Frame body @@ -1053,11 +1053,11 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx, PSCTS pBuf = (PSCTS)pvCTS; //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (PWORD)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) + (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b) ); pBuf->wTransmitLength_b = cpu_to_le16(wLen); //Get CTSDuration_ba - pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data pBuf->wDuration_ba += pDevice->wCTSDuration; pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); @@ -1130,11 +1130,11 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime; - pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz - pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz - pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz - pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM - pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK + pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz + pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz + pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz + pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM + pBuf->wTxRrvTime_b = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK } //Fill RTS s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); @@ -1144,9 +1144,9 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime; - pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM - pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK - pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz + pBuf->wTxRrvTime_a = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM + pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK + pBuf->wCTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz } //Fill CTS s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption); @@ -1158,8 +1158,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz - pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM + pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz + pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM } //Fill RTS s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); @@ -1168,7 +1168,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM + pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM } } } @@ -1178,8 +1178,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz - pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK + pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz + pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK } //Fill RTS s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); @@ -1188,7 +1188,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, //Fill RsvTime if (pvRrvTime) { PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK + pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK } } } @@ -1196,7 +1196,7 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice, } /* u8 * pbyBuffer,//point to pTxBufHead - WORD wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last + u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last unsigned int cbFragmentSize,//Hdr+payoad+FCS */ @@ -1253,7 +1253,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len; //Set packet type - pTxBufHead->wFIFOCtl |= (WORD)(byPktType<<8); + pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8); if (pDevice->dwDiagRefCount != 0) { bNeedACK = false; @@ -1293,7 +1293,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, } else { cbMACHdLen = WLAN_HDR_ADDR3_LEN; } - pTxBufHead->wFragCtl |= (WORD)(cbMACHdLen << 10); + pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10); //Set FIFOCTL_GrpAckPolicy if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 @@ -1459,13 +1459,13 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, 0, 0, 1/*uMACfragNum*/, byFBOption); // Generate TX MAC Header - s_vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncryption, + s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption, byFragType, uDMAIdx, 0); if (bNeedEncryption == true) { //Fill TXKEY s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (WORD)cbFrameBodySize, (u8 *)pMICHDR); + pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR); if (pDevice->bEnableHostWEP) { pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; @@ -1484,9 +1484,9 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); } pbyType = (u8 *) (pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD)); + memcpy(pbyType, &(psEthHeader->wType), sizeof(u16)); } else { - memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->wType), sizeof(WORD)); + memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->wType), sizeof(u16)); } @@ -1560,7 +1560,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, if (bSoftWEP == true) { - s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (WORD)(cbFrameBodySize + cbMIClen)); + s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen)); } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) || ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) || @@ -1590,7 +1590,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, //Set FragCtl in TxBufferHead - pTxBufHead->wFragCtl |= (WORD)byFragType; + pTxBufHead->wFragCtl |= (u16)byFragType; return true; @@ -1666,7 +1666,7 @@ static void s_vGenerateMACHeader(struct vnt_private *pDevice, } if (bNeedEncrypt) - pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1)); + pMACHeader->wFrameCtl |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1)); pMACHeader->wDurationID = cpu_to_le16(wDuration); @@ -1678,7 +1678,7 @@ static void s_vGenerateMACHeader(struct vnt_private *pDevice, pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); //Set FragNumber in Sequence Control - pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx); + pMACHeader->wSeqCtl |= cpu_to_le16((u16)uFragIdx); if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { pDevice->wSeqCounter++; @@ -1814,7 +1814,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, } //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10)); + pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10)); // Notes: // Although spec says MMPDU can be fragmented; In most case, @@ -1886,7 +1886,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, //========================= // No Fragmentation //========================= - pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG; + pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG; //Fill FIFO,RrvTime,RTS,and CTS @@ -1936,7 +1936,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, } while(false); //Fill TXKEY s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (u8 *)pMACHeader, (WORD)cbFrameBodySize, NULL); + (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL); memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen), @@ -1967,19 +1967,19 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, } - pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount)); + pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount)); pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x00; pContext->pPacket = NULL; pContext->Type = CONTEXT_MGMT_PACKET; - pContext->uBufLen = (WORD)cbReqCount + 4; //USB header + pContext->uBufLen = (u16)cbReqCount + 4; //USB header if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) { - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(u16)cbFrameSize,pTX_Buffer->wFIFOCtl); } else { - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(u16)cbFrameSize,pTX_Buffer->wFIFOCtl); } PIPEnsSendBulkOut(pDevice,pContext); @@ -2025,10 +2025,10 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A, - (PWORD)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) + (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff - pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A, + pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A, wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]; cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab); @@ -2038,10 +2038,10 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize); //Get SignalField,ServiceField,Length BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B, - (PWORD)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) + (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField) ); //Get Duration and TimeStampOff - pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B, + pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B, wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]; cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab); @@ -2059,13 +2059,13 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize; - pTX_Buffer->wTxByteCount = (WORD)cbReqCount; + pTX_Buffer->wTxByteCount = (u16)cbReqCount; pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x01; pContext->pPacket = NULL; pContext->Type = CONTEXT_MGMT_PACKET; - pContext->uBufLen = (WORD)cbReqCount + 4; //USB header + pContext->uBufLen = (u16)cbReqCount + 4; //USB header PIPEnsSendBulkOut(pDevice,pContext); return CMD_STATUS_PENDING; @@ -2225,7 +2225,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10); + pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10); // Notes: // Although spec says MMPDU can be fragmented; In most case, @@ -2299,7 +2299,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) //========================= // No Fragmentation //========================= - pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG; + pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG; //Fill FIFO,RrvTime,RTS,and CTS @@ -2394,7 +2394,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (WORD)cbFrameBodySize, (u8 *)pMICHDR); + pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR); if (pDevice->bEnableHostWEP) { pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; @@ -2402,7 +2402,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen)); + s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen)); } } @@ -2426,19 +2426,19 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } } - pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount)); + pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount)); pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); pTX_Buffer->byType = 0x00; pContext->pPacket = skb; pContext->Type = CONTEXT_MGMT_PACKET; - pContext->uBufLen = (WORD)cbReqCount + 4; //USB header + pContext->uBufLen = (u16)cbReqCount + 4; //USB header if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) { - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(u16)cbFrameSize,pTX_Buffer->wFIFOCtl); } else { - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(u16)cbFrameSize,pTX_Buffer->wFIFOCtl); } PIPEnsSendBulkOut(pDevice,pContext); return ; @@ -2569,7 +2569,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, u8 Protocol_Version; //802.1x Authentication u8 Packet_Type; //802.1x Authentication u8 Descriptor_type; - WORD Key_info; + u16 Key_info; Protocol_Version = skb->data[ETH_HLEN]; Packet_Type = skb->data[ETH_HLEN+1]; @@ -2672,7 +2672,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, if (pDevice->uConnectionRate >= RATE_11M) { pDevice->wCurrentRate = RATE_11M; } else { - pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate; + pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; } } else { if ((pDevice->byBBType == BB_TYPE_11A) && @@ -2682,7 +2682,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, if (pDevice->uConnectionRate >= RATE_54M) pDevice->wCurrentRate = RATE_54M; else - pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate; + pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; } } } @@ -2817,18 +2817,18 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]); pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); - pTX_Buffer->wTxByteCount = (WORD)BytesToWrite; + pTX_Buffer->wTxByteCount = (u16)BytesToWrite; pContext->pPacket = skb; pContext->Type = CONTEXT_DATA_PACKET; - pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header + pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(u16) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); status = PIPEnsSendBulkOut(pDevice,pContext); if (bNeedDeAuth == true) { - WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE; + u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE; bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason); } @@ -2926,7 +2926,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, if (pDevice->uConnectionRate >= RATE_11M) { pDevice->wCurrentRate = RATE_11M; } else { - pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate; + pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; } } else { if ((pDevice->byBBType == BB_TYPE_11A) && @@ -2936,7 +2936,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, if (pDevice->uConnectionRate >= RATE_54M) pDevice->wCurrentRate = RATE_54M; else - pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate; + pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; } } } @@ -2971,13 +2971,13 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]); pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F)); - pTX_Buffer->wTxByteCount = (WORD)BytesToWrite; + pTX_Buffer->wTxByteCount = (u16)BytesToWrite; pContext->pPacket = NULL; pContext->Type = CONTEXT_DATA_PACKET; - pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header + pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header - s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); + s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(u16) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl); status = PIPEnsSendBulkOut(pDevice,pContext); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 7ca185e4437e..57706acf3acc 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -41,8 +41,8 @@ // RTS buffer header // typedef struct tagSRTSDataF { - WORD wFrameControl; - WORD wDurationID; + u16 wFrameControl; + u16 wDurationID; u8 abyRA[ETH_ALEN]; u8 abyTA[ETH_ALEN]; } SRTSDataF, *PSRTSDataF; @@ -51,10 +51,10 @@ typedef struct tagSRTSDataF { // CTS buffer header // typedef struct tagSCTSDataF { - WORD wFrameControl; - WORD wDurationID; + u16 wFrameControl; + u16 wDurationID; u8 abyRA[ETH_ALEN]; - WORD wReserved; + u16 wReserved; } SCTSDataF, *PSCTSDataF; // @@ -70,106 +70,106 @@ typedef struct tagSMICHDR { typedef struct tagSTX_NAF_G_RTS { //RsvTime - WORD wRTSTxRrvTime_ba; - WORD wRTSTxRrvTime_aa; - WORD wRTSTxRrvTime_bb; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_ba; + u16 wRTSTxRrvTime_aa; + u16 wRTSTxRrvTime_bb; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; //RTS u8 byRTSSignalField_b; u8 byRTSServiceField_b; - WORD wRTSTransmitLength_b; + u16 wRTSTransmitLength_b; u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_ba; - WORD wRTSDuration_aa; - WORD wRTSDuration_bb; - WORD wReserved3; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_ba; + u16 wRTSDuration_aa; + u16 wRTSDuration_bb; + u16 wReserved3; SRTSDataF sRTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_NAF_G_RTS, *PTX_NAF_G_RTS; typedef struct tagSTX_NAF_G_RTS_MIC { //RsvTime - WORD wRTSTxRrvTime_ba; - WORD wRTSTxRrvTime_aa; - WORD wRTSTxRrvTime_bb; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_ba; + u16 wRTSTxRrvTime_aa; + u16 wRTSTxRrvTime_bb; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; SMICHDR sMICHDR; //RTS u8 byRTSSignalField_b; u8 byRTSServiceField_b; - WORD wRTSTransmitLength_b; + u16 wRTSTransmitLength_b; u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_ba; - WORD wRTSDuration_aa; - WORD wRTSDuration_bb; - WORD wReserved3; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_ba; + u16 wRTSDuration_aa; + u16 wRTSDuration_bb; + u16 wReserved3; SRTSDataF sRTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_NAF_G_RTS_MIC, *PTX_NAF_G_RTS_MIC; typedef struct tagSTX_NAF_G_CTS { //RsvTime - WORD wCTSTxRrvTime_ba; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; //CTS u8 byCTSSignalField_b; u8 byCTSServiceField_b; - WORD wCTSTransmitLength_b; - WORD wCTSDuration_ba; - WORD wReserved3; + u16 wCTSTransmitLength_b; + u16 wCTSDuration_ba; + u16 wReserved3; SCTSDataF sCTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_NAF_G_CTS, *PTX_NAF_G_CTS; @@ -177,10 +177,10 @@ typedef struct tagSTX_NAF_G_CTS typedef struct tagSTX_NAF_G_CTS_MIC { //RsvTime - WORD wCTSTxRrvTime_ba; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; SMICHDR sMICHDR; @@ -188,45 +188,45 @@ typedef struct tagSTX_NAF_G_CTS_MIC //CTS u8 byCTSSignalField_b; u8 byCTSServiceField_b; - WORD wCTSTransmitLength_b; - WORD wCTSDuration_ba; - WORD wReserved3; + u16 wCTSTransmitLength_b; + u16 wCTSDuration_ba; + u16 wReserved3; SCTSDataF sCTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_NAF_G_CTS_MIC, *PTX_NAF_G_CTS_MIC; typedef struct tagSTX_NAF_G_BEACON { - WORD wFIFOCtl; - WORD wTimeStamp; + u16 wFIFOCtl; + u16 wTimeStamp; //CTS u8 byCTSSignalField_b; u8 byCTSServiceField_b; - WORD wCTSTransmitLength_b; - WORD wCTSDuration_ba; - WORD wReserved1; + u16 wCTSTransmitLength_b; + u16 wCTSDuration_ba; + u16 wReserved1; SCTSDataF sCTS; //Data u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_a; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_a; + u16 wTimeStampOff_a; } TX_NAF_G_BEACON, *PTX_NAF_G_BEACON; @@ -235,23 +235,23 @@ typedef struct tagSTX_NAF_G_BEACON typedef struct tagSTX_NAF_AB_RTS { //RsvTime - WORD wRTSTxRrvTime_ab; - WORD wTxRrvTime_ab; + u16 wRTSTxRrvTime_ab; + u16 wTxRrvTime_ab; //RTS u8 byRTSSignalField_ab; u8 byRTSServiceField_ab; - WORD wRTSTransmitLength_ab; - WORD wRTSDuration_ab; - WORD wReserved2; + u16 wRTSTransmitLength_ab; + u16 wRTSDuration_ab; + u16 wReserved2; SRTSDataF sRTS; //Data u8 bySignalField_ab; u8 byServiceField_ab; - WORD wTransmitLength_ab; - WORD wDuration_ab; - WORD wTimeStampOff_ab; + u16 wTransmitLength_ab; + u16 wDuration_ab; + u16 wTimeStampOff_ab; } TX_NAF_AB_RTS, *PTX_NAF_AB_RTS; @@ -260,25 +260,25 @@ typedef struct tagSTX_NAF_AB_RTS typedef struct tagSTX_NAF_AB_RTS_MIC { //RsvTime - WORD wRTSTxRrvTime_ab; - WORD wTxRrvTime_ab; + u16 wRTSTxRrvTime_ab; + u16 wTxRrvTime_ab; SMICHDR sMICHDR; //RTS u8 byRTSSignalField_ab; u8 byRTSServiceField_ab; - WORD wRTSTransmitLength_ab; - WORD wRTSDuration_ab; - WORD wReserved2; + u16 wRTSTransmitLength_ab; + u16 wRTSDuration_ab; + u16 wReserved2; SRTSDataF sRTS; //Data u8 bySignalField_ab; u8 byServiceField_ab; - WORD wTransmitLength_ab; - WORD wDuration_ab; - WORD wTimeStampOff_ab; + u16 wTransmitLength_ab; + u16 wDuration_ab; + u16 wTimeStampOff_ab; } TX_NAF_AB_RTS_MIC, *PTX_NAF_AB_RTS_MIC; @@ -288,90 +288,90 @@ typedef struct tagSTX_NAF_AB_RTS_MIC typedef struct tagSTX_NAF_AB_CTS { //RsvTime - WORD wReserved2; - WORD wTxRrvTime_ab; + u16 wReserved2; + u16 wTxRrvTime_ab; //Data u8 bySignalField_ab; u8 byServiceField_ab; - WORD wTransmitLength_ab; - WORD wDuration_ab; - WORD wTimeStampOff_ab; + u16 wTransmitLength_ab; + u16 wDuration_ab; + u16 wTimeStampOff_ab; } TX_NAF_AB_CTS, *PTX_NAF_AB_CTS; typedef struct tagSTX_NAF_AB_CTS_MIC { //RsvTime - WORD wReserved2; - WORD wTxRrvTime_ab; + u16 wReserved2; + u16 wTxRrvTime_ab; SMICHDR sMICHDR; //Data u8 bySignalField_ab; u8 byServiceField_ab; - WORD wTransmitLength_ab; - WORD wDuration_ab; - WORD wTimeStampOff_ab; + u16 wTransmitLength_ab; + u16 wDuration_ab; + u16 wTimeStampOff_ab; } TX_NAF_AB_CTS_MIC, *PTX_NAF_AB_CTS_MIC; typedef struct tagSTX_NAF_AB_BEACON { - WORD wFIFOCtl; - WORD wTimeStamp; + u16 wFIFOCtl; + u16 wTimeStamp; //Data u8 bySignalField_ab; u8 byServiceField_ab; - WORD wTransmitLength_ab; - WORD wDuration_ab; - WORD wTimeStampOff_ab; + u16 wTransmitLength_ab; + u16 wDuration_ab; + u16 wTimeStampOff_ab; } TX_NAF_AB_BEACON, *PTX_NAF_AB_BEACON; typedef struct tagSTX_AF_G_RTS { //RsvTime - WORD wRTSTxRrvTime_ba; - WORD wRTSTxRrvTime_aa; - WORD wRTSTxRrvTime_bb; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_ba; + u16 wRTSTxRrvTime_aa; + u16 wRTSTxRrvTime_bb; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; //RTS u8 byRTSSignalField_b; u8 byRTSServiceField_b; - WORD wRTSTransmitLength_b; + u16 wRTSTransmitLength_b; u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_ba; - WORD wRTSDuration_aa; - WORD wRTSDuration_bb; - WORD wReserved3; - WORD wRTSDuration_ba_f0; - WORD wRTSDuration_aa_f0; - WORD wRTSDuration_ba_f1; - WORD wRTSDuration_aa_f1; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_ba; + u16 wRTSDuration_aa; + u16 wRTSDuration_bb; + u16 wReserved3; + u16 wRTSDuration_ba_f0; + u16 wRTSDuration_aa_f0; + u16 wRTSDuration_ba_f1; + u16 wRTSDuration_aa_f1; SRTSDataF sRTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_AF_G_RTS, *PTX_AF_G_RTS; @@ -379,45 +379,45 @@ typedef struct tagSTX_AF_G_RTS typedef struct tagSTX_AF_G_RTS_MIC { //RsvTime - WORD wRTSTxRrvTime_ba; - WORD wRTSTxRrvTime_aa; - WORD wRTSTxRrvTime_bb; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_ba; + u16 wRTSTxRrvTime_aa; + u16 wRTSTxRrvTime_bb; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; SMICHDR sMICHDR; //RTS u8 byRTSSignalField_b; u8 byRTSServiceField_b; - WORD wRTSTransmitLength_b; + u16 wRTSTransmitLength_b; u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_ba; - WORD wRTSDuration_aa; - WORD wRTSDuration_bb; - WORD wReserved3; - WORD wRTSDuration_ba_f0; - WORD wRTSDuration_aa_f0; - WORD wRTSDuration_ba_f1; - WORD wRTSDuration_aa_f1; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_ba; + u16 wRTSDuration_aa; + u16 wRTSDuration_bb; + u16 wReserved3; + u16 wRTSDuration_ba_f0; + u16 wRTSDuration_aa_f0; + u16 wRTSDuration_ba_f1; + u16 wRTSDuration_aa_f1; SRTSDataF sRTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_AF_G_RTS_MIC, *PTX_AF_G_RTS_MIC; @@ -426,34 +426,34 @@ typedef struct tagSTX_AF_G_RTS_MIC typedef struct tagSTX_AF_G_CTS { //RsvTime - WORD wCTSTxRrvTime_ba; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; //CTS u8 byCTSSignalField_b; u8 byCTSServiceField_b; - WORD wCTSTransmitLength_b; - WORD wCTSDuration_ba; - WORD wReserved3; - WORD wCTSDuration_ba_f0; - WORD wCTSDuration_ba_f1; + u16 wCTSTransmitLength_b; + u16 wCTSDuration_ba; + u16 wReserved3; + u16 wCTSDuration_ba_f0; + u16 wCTSDuration_ba_f1; SCTSDataF sCTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_AF_G_CTS, *PTX_AF_G_CTS; @@ -461,10 +461,10 @@ typedef struct tagSTX_AF_G_CTS typedef struct tagSTX_AF_G_CTS_MIC { //RsvTime - WORD wCTSTxRrvTime_ba; - WORD wReserved2; - WORD wTxRrvTime_b; - WORD wTxRrvTime_a; + u16 wCTSTxRrvTime_ba; + u16 wReserved2; + u16 wTxRrvTime_b; + u16 wTxRrvTime_a; SMICHDR sMICHDR; @@ -472,26 +472,26 @@ typedef struct tagSTX_AF_G_CTS_MIC //CTS u8 byCTSSignalField_b; u8 byCTSServiceField_b; - WORD wCTSTransmitLength_b; - WORD wCTSDuration_ba; - WORD wReserved3; - WORD wCTSDuration_ba_f0; - WORD wCTSDuration_ba_f1; + u16 wCTSTransmitLength_b; + u16 wCTSDuration_ba; + u16 wReserved3; + u16 wCTSDuration_ba_f0; + u16 wCTSDuration_ba_f1; SCTSDataF sCTS; //Data u8 bySignalField_b; u8 byServiceField_b; - WORD wTransmitLength_b; + u16 wTransmitLength_b; u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_b; - WORD wDuration_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; - WORD wTimeStampOff_b; - WORD wTimeStampOff_a; + u16 wTransmitLength_a; + u16 wDuration_b; + u16 wDuration_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; + u16 wTimeStampOff_b; + u16 wTimeStampOff_a; } TX_AF_G_CTS_MIC, *PTX_AF_G_CTS_MIC; @@ -500,27 +500,27 @@ typedef struct tagSTX_AF_G_CTS_MIC typedef struct tagSTX_AF_A_RTS { //RsvTime - WORD wRTSTxRrvTime_a; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_a; + u16 wTxRrvTime_a; //RTS u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_a; - WORD wReserved2; - WORD wRTSDuration_a_f0; - WORD wRTSDuration_a_f1; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_a; + u16 wReserved2; + u16 wRTSDuration_a_f0; + u16 wRTSDuration_a_f1; SRTSDataF sRTS; //Data u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_a; - WORD wTimeStampOff_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; + u16 wTransmitLength_a; + u16 wDuration_a; + u16 wTimeStampOff_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; } TX_AF_A_RTS, *PTX_AF_A_RTS; @@ -528,29 +528,29 @@ typedef struct tagSTX_AF_A_RTS typedef struct tagSTX_AF_A_RTS_MIC { //RsvTime - WORD wRTSTxRrvTime_a; - WORD wTxRrvTime_a; + u16 wRTSTxRrvTime_a; + u16 wTxRrvTime_a; SMICHDR sMICHDR; //RTS u8 byRTSSignalField_a; u8 byRTSServiceField_a; - WORD wRTSTransmitLength_a; - WORD wRTSDuration_a; - WORD wReserved2; - WORD wRTSDuration_a_f0; - WORD wRTSDuration_a_f1; + u16 wRTSTransmitLength_a; + u16 wRTSDuration_a; + u16 wReserved2; + u16 wRTSDuration_a_f0; + u16 wRTSDuration_a_f1; SRTSDataF sRTS; //Data u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_a; - WORD wTimeStampOff_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; + u16 wTransmitLength_a; + u16 wDuration_a; + u16 wTimeStampOff_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; } TX_AF_A_RTS_MIC, *PTX_AF_A_RTS_MIC; @@ -559,17 +559,17 @@ typedef struct tagSTX_AF_A_RTS_MIC typedef struct tagSTX_AF_A_CTS { //RsvTime - WORD wReserved2; - WORD wTxRrvTime_a; + u16 wReserved2; + u16 wTxRrvTime_a; //Data u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_a; - WORD wTimeStampOff_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; + u16 wTransmitLength_a; + u16 wDuration_a; + u16 wTimeStampOff_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; } TX_AF_A_CTS, *PTX_AF_A_CTS; @@ -577,19 +577,19 @@ typedef struct tagSTX_AF_A_CTS typedef struct tagSTX_AF_A_CTS_MIC { //RsvTime - WORD wReserved2; - WORD wTxRrvTime_a; + u16 wReserved2; + u16 wTxRrvTime_a; SMICHDR sMICHDR; //Data u8 bySignalField_a; u8 byServiceField_a; - WORD wTransmitLength_a; - WORD wDuration_a; - WORD wTimeStampOff_a; - WORD wDuration_a_f0; - WORD wDuration_a_f1; + u16 wTransmitLength_a; + u16 wDuration_a; + u16 wTimeStampOff_a; + u16 wDuration_a_f0; + u16 wDuration_a_f1; } TX_AF_A_CTS_MIC, *PTX_AF_A_CTS_MIC; @@ -628,13 +628,13 @@ typedef struct tagSTX_BUFFER { u8 byType; u8 byPKTNO; - WORD wTxByteCount; + u16 wTxByteCount; u32 adwTxKey[4]; - WORD wFIFOCtl; - WORD wTimeStamp; - WORD wFragCtl; - WORD wReserved; + u16 wFIFOCtl; + u16 wTimeStamp; + u16 wFragCtl; + u16 wReserved; // Actual message @@ -650,10 +650,10 @@ typedef struct tagSBEACON_BUFFER { u8 byType; u8 byPKTNO; - WORD wTxByteCount; + u16 wTxByteCount; - WORD wFIFOCtl; - WORD wTimeStamp; + u16 wFIFOCtl; + u16 wTimeStamp; // Actual message TX_BUFFER_CONTAINER BufferHeader; diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h index c681789136c1..9f1af6746ccb 100644 --- a/drivers/staging/vt6656/srom.h +++ b/drivers/staging/vt6656/srom.h @@ -86,34 +86,34 @@ // 2048 bits = 256 bytes = 128 words // typedef struct tagSSromReg { - u8 abyPAR[6]; // 0x00 (WORD) + u8 abyPAR[6]; // 0x00 (u16) - WORD wSUB_VID; // 0x03 (WORD) - WORD wSUB_SID; + u16 wSUB_VID; // 0x03 (u16) + u16 wSUB_SID; - u8 byBCFG0; // 0x05 (WORD) + u8 byBCFG0; // 0x05 (u16) u8 byBCFG1; - u8 byFCR0; // 0x06 (WORD) + u8 byFCR0; // 0x06 (u16) u8 byFCR1; - u8 byPMC0; // 0x07 (WORD) + u8 byPMC0; // 0x07 (u16) u8 byPMC1; - u8 byMAXLAT; // 0x08 (WORD) + u8 byMAXLAT; // 0x08 (u16) u8 byMINGNT; - u8 byCFG0; // 0x09 (WORD) + u8 byCFG0; // 0x09 (u16) u8 byCFG1; - WORD wCISPTR; // 0x0A (WORD) - WORD wRsv0; // 0x0B (WORD) - WORD wRsv1; // 0x0C (WORD) - u8 byBBPAIR; // 0x0D (WORD) + u16 wCISPTR; // 0x0A (u16) + u16 wRsv0; // 0x0B (u16) + u16 wRsv1; // 0x0C (u16) + u8 byBBPAIR; // 0x0D (u16) u8 byRFTYPE; - u8 byMinChannel; // 0x0E (WORD) + u8 byMinChannel; // 0x0E (u16) u8 byMaxChannel; - u8 bySignature; // 0x0F (WORD) + u8 bySignature; // 0x0F (u16) u8 byCheckSum; - u8 abyReserved0[96]; // 0x10 (WORD) - u8 abyCIS[128]; // 0x80 (WORD) + u8 abyReserved0[96]; // 0x10 (u16) + u8 abyCIS[128]; // 0x80 (u16) } SSromReg, *PSSromReg; /*--------------------- Export Macros ------------------------------*/ diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index 0b8a40f05b96..d3ef6b59d503 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -122,7 +122,7 @@ typedef struct tagSEthernetHeader { u8 abyDstAddr[ETH_ALEN]; u8 abySrcAddr[ETH_ALEN]; - WORD wType; + u16 wType; } __attribute__ ((__packed__)) SEthernetHeader, *PSEthernetHeader; @@ -133,7 +133,7 @@ SEthernetHeader, *PSEthernetHeader; typedef struct tagS802_3Header { u8 abyDstAddr[ETH_ALEN]; u8 abySrcAddr[ETH_ALEN]; - WORD wLen; + u16 wLen; } __attribute__ ((__packed__)) S802_3Header, *PS802_3Header; @@ -141,12 +141,12 @@ S802_3Header, *PS802_3Header; // 802_11 packet // typedef struct tagS802_11Header { - WORD wFrameCtl; - WORD wDurationID; + u16 wFrameCtl; + u16 wDurationID; u8 abyAddr1[ETH_ALEN]; u8 abyAddr2[ETH_ALEN]; u8 abyAddr3[ETH_ALEN]; - WORD wSeqCtl; + u16 wSeqCtl; u8 abyAddr4[ETH_ALEN]; } __attribute__ ((__packed__)) S802_11Header, *PS802_11Header; diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index c6d3a83bd890..f5aeb5e53396 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -184,7 +184,7 @@ static unsigned int rotr1(unsigned int a) void TKIPvMixKey( u8 * pbyTKey, u8 * pbyTA, - WORD wTSC15_0, + u16 wTSC15_0, DWORD dwTSC47_16, u8 * pbyRC4Key ) diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index b8e5d442ac0f..7662423e2479 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -49,7 +49,7 @@ void TKIPvMixKey( u8 * pbyTKey, u8 * pbyTA, - WORD wTSC15_0, + u16 wTSC15_0, DWORD dwTSC47_16, u8 * pbyRC4Key ); diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h index 4ad4f051266e..b4e6cb2e4c9f 100644 --- a/drivers/staging/vt6656/tmacro.h +++ b/drivers/staging/vt6656/tmacro.h @@ -37,24 +37,24 @@ #define LOBYTE(w) ((u8)(w)) #endif #if !defined(HIBYTE) -#define HIBYTE(w) ((u8)(((WORD)(w) >> 8) & 0xFF)) +#define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF)) #endif #if !defined(LOWORD) -#define LOWORD(d) ((WORD)(d)) +#define LOWORD(d) ((u16)(d)) #endif #if !defined(HIWORD) -#define HIWORD(d) ((WORD)((((DWORD)(d)) >> 16) & 0xFFFF)) +#define HIWORD(d) ((u16)((((DWORD)(d)) >> 16) & 0xFFFF)) #endif #define LODWORD(q) ((q).u.dwLowDword) #define HIDWORD(q) ((q).u.dwHighDword) #if !defined(MAKEWORD) -#define MAKEWORD(lb, hb) ((WORD)(((u8)(lb)) | (((WORD)((u8)(hb))) << 8))) +#define MAKEWORD(lb, hb) ((u16)(((u8)(lb)) | (((u16)((u8)(hb))) << 8))) #endif #if !defined(MAKEDWORD) -#define MAKEDWORD(lw, hw) ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16))) +#define MAKEDWORD(lw, hw) ((DWORD)(((u16)(lw)) | (((DWORD)((u16)(hw))) << 16))) #endif #endif /* __TMACRO_H__ */ diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index a4cafc643c35..ee1201d4a8e8 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -35,7 +35,6 @@ /****** Simple typedefs ***************************************************/ -typedef u16 WORD; typedef u32 DWORD; /****** Common pointer types ***********************************************/ @@ -45,8 +44,6 @@ typedef u32 DWORD_PTR; // boolean pointer -typedef WORD * PWORD; - typedef DWORD * PDWORD; #endif /* __TTYPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 904b5dae5d2a..4d9e1456a35d 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -1147,7 +1147,7 @@ int bScheduleCommand(struct vnt_private *pDevice, break; /* case WLAN_CMD_DEAUTH: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((PWORD)pbyItem0); + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0); break; */ diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 5763509b0af0..398414b2b431 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -77,7 +77,7 @@ typedef struct tagCMD_ITEM { bool bNeedRadioOFF; bool bRadioCmd; bool bForceSCAN; - WORD wDeAuthenReason; + u16 wDeAuthenReason; } CMD_ITEM, *PCMD_ITEM; // Command state diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index c9ad7cacc6e3..f36cb112682a 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -543,9 +543,9 @@ static void s_vMgrRxAssocRequest(struct vnt_private *pDevice, WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex; + pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)uNodeIndex; wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (WORD)uNodeIndex; + wAssocAID = (u16)uNodeIndex; // check if ERP support if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; @@ -691,9 +691,9 @@ static void s_vMgrRxReAssocRequest(struct vnt_private *pDevice, WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex; + pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)uNodeIndex; wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (WORD)uNodeIndex; + wAssocAID = (u16)uNodeIndex; // if suppurt ERP if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) @@ -2843,9 +2843,9 @@ static void s_vMgrFormatTIM(struct vnt_manager *pMgmt, PWLAN_IE_TIM pTIM) if (byMap) { if (!bStartFound) { bStartFound = true; - wStartIndex = (WORD)ii; + wStartIndex = (u16)ii; } - wEndIndex = (WORD)ii; + wEndIndex = (u16)ii; } } @@ -2917,7 +2917,7 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice, )); if (pDevice->bEnablePSMode) { - sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_PWRMGT(1)); + sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((u16)WLAN_SET_FC_PWRMGT(1)); } memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN); @@ -2988,11 +2988,11 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice, // Pairwise Key Cipher Suite sFrame.pRSNWPA->wPKCount = 0; // Auth Key Management Suite - *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; + *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; sFrame.pRSNWPA->len +=2; // RSN Capabilites - *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; + *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; sFrame.pRSNWPA->len +=2; sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; } @@ -3089,7 +3089,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); if (byPHYType == BB_TYPE_11B) { - *sFrame.pwCapInfo &= cpu_to_le16((WORD)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); + *sFrame.pwCapInfo &= cpu_to_le16((u16)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); } // Copy SSID @@ -3322,7 +3322,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && (pMgmt->pCurrBSS != NULL)) { unsigned int ii; - PWORD pwPMKID; + u16 * pwPMKID; // WPA IE sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); @@ -3387,7 +3387,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { // RSN PMKID pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (PWORD)pbyRSN; // Point to PMKID count + pwPMKID = (u16 *)pbyRSN; // Point to PMKID count *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { @@ -3578,7 +3578,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && (pMgmt->pCurrBSS != NULL)) { unsigned int ii; - PWORD pwPMKID; + u16 * pwPMKID; /* WPA IE */ sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); @@ -3643,7 +3643,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { // RSN PMKID pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (PWORD)pbyRSN; // Point to PMKID count + pwPMKID = (u16 *)pbyRSN; // Point to PMKID count *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { @@ -3719,7 +3719,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice, *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15)); + *sFrame.pwAid = cpu_to_le16((u16)(wAssocAID | BIT14 | BIT15)); // Copy the rate set sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); @@ -3788,7 +3788,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice, *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15)); + *sFrame.pwAid = cpu_to_le16((u16)(wAssocAID | BIT14 | BIT15)); // Copy the rate set sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 619ce3c69641..e370b39821c6 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -167,7 +167,7 @@ WPA_ParseRSN( break; //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1])); } //for - pBSSList->wPKCount = (WORD)j; + pBSSList->wPKCount = (u16)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount); } @@ -197,7 +197,7 @@ WPA_ParseRSN( //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1])); } if(j > 0) - pBSSList->wAuthCount = (WORD)j; + pBSSList->wAuthCount = (u16)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount); } @@ -213,7 +213,7 @@ WPA_ParseRSN( pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); pBSSList->sRSNCapObj.bRSNCapExist = true; - pBSSList->sRSNCapObj.wRSNCap = *(PWORD)pbyCaps; + pBSSList->sRSNCapObj.wRSNCap = *(u16 *)pbyCaps; //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps)); //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK)); //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx)); diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index 71a6fa5a4b54..004869ab221e 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -113,7 +113,7 @@ WPA2vParseRSN ( ) { int i, j; - WORD m = 0, n = 0; + u16 m = 0, n = 0; u8 * pbyOUI; bool bUseGK = false; @@ -163,7 +163,7 @@ WPA2vParseRSN ( } if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2) - pBSSNode->wCSSPKCount = *((PWORD) &(pRSN->abyRSN[4])); + pBSSNode->wCSSPKCount = *((u16 *) &(pRSN->abyRSN[4])); j = 0; pbyOUI = &(pRSN->abyRSN[6]); @@ -208,14 +208,14 @@ WPA2vParseRSN ( // invalid CSS, No valid PK. return; } - pBSSNode->wCSSPKCount = (WORD)j; + pBSSNode->wCSSPKCount = (u16)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); } - m = *((PWORD) &(pRSN->abyRSN[4])); + m = *((u16 *) &(pRSN->abyRSN[4])); if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m])); + pBSSNode->wAKMSSAuthCount = *((u16 *) &(pRSN->abyRSN[6+4*m])); j = 0; pbyOUI = &(pRSN->abyRSN[8+4*m]); for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(u8)); i++) { @@ -231,13 +231,13 @@ WPA2vParseRSN ( } else break; } - pBSSNode->wAKMSSAuthCount = (WORD)j; + pBSSNode->wAKMSSAuthCount = (u16)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); - n = *((PWORD) &(pRSN->abyRSN[6+4*m])); + n = *((u16 *) &(pRSN->abyRSN[6+4*m])); if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) pBSSNode->sRSNCapObj.bRSNCapExist = true; - pBSSNode->sRSNCapObj.wRSNCap = *((PWORD) &(pRSN->abyRSN[8+4*m+4*n])); + pBSSNode->sRSNCapObj.wRSNCap = *((u16 *) &(pRSN->abyRSN[8+4*m+4*n])); } } //ignore PMKID lists bcs only (Re)Assocrequest has this field @@ -337,7 +337,7 @@ unsigned int WPA2uSetIEs(void *pMgmtHandle, PWLAN_IE_RSN pRSNIEs) (pMgmt->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { /* RSN PMKID, pointer to PMKID count */ - pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]); + pwPMKID = (u16 *)(&pRSNIEs->abyRSN[18]); *pwPMKID = 0; /* Initialize PMKID count */ pbyBuffer = &pRSNIEs->abyRSN[20]; /* Point to PMKID list */ for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { -- cgit From 52a7e64b06f70404c2539e4462063a8df9e4ee13 Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 25 Feb 2013 20:32:53 -0500 Subject: staging: vt6656: replaced custom DWORD definition with u32 Checkpatch findings were not resolved. sed -i 's/\bDWORD\b/u32/g' drivers/staging/vt6656/*.[ch] sed -i 's/\bPDWORD\b/u32 */g' drivers/staging/vt6656/*.[ch] Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/aes_ccmp.c | 12 +- drivers/staging/vt6656/bssdb.h | 6 +- drivers/staging/vt6656/device.h | 2 +- drivers/staging/vt6656/dpc.c | 40 +++---- drivers/staging/vt6656/hostap.c | 2 +- drivers/staging/vt6656/key.c | 8 +- drivers/staging/vt6656/key.h | 6 +- drivers/staging/vt6656/mib.h | 230 +++++++++++++++++++------------------- drivers/staging/vt6656/michael.c | 32 +++--- drivers/staging/vt6656/michael.h | 4 +- drivers/staging/vt6656/rf.c | 8 +- drivers/staging/vt6656/rndis.h | 10 +- drivers/staging/vt6656/rxtx.c | 28 ++--- drivers/staging/vt6656/tcrc.c | 10 +- drivers/staging/vt6656/tcrc.h | 6 +- drivers/staging/vt6656/tether.c | 4 +- drivers/staging/vt6656/tkip.c | 2 +- drivers/staging/vt6656/tkip.h | 2 +- drivers/staging/vt6656/tmacro.h | 4 +- drivers/staging/vt6656/ttype.h | 4 - drivers/staging/vt6656/wpactl.c | 4 +- 21 files changed, 210 insertions(+), 214 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index 0186cee0d6fb..0cf425e28eb3 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -108,9 +108,9 @@ u8 dot3_table[256] = { static void xor_128(u8 *a, u8 *b, u8 *out) { - PDWORD dwPtrA = (PDWORD) a; - PDWORD dwPtrB = (PDWORD) b; - PDWORD dwPtrOut = (PDWORD) out; + u32 * dwPtrA = (u32 *) a; + u32 * dwPtrB = (u32 *) b; + u32 * dwPtrOut = (u32 *) out; (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); @@ -121,9 +121,9 @@ static void xor_128(u8 *a, u8 *b, u8 *out) static void xor_32(u8 *a, u8 *b, u8 *out) { - PDWORD dwPtrA = (PDWORD) a; - PDWORD dwPtrB = (PDWORD) b; - PDWORD dwPtrOut = (PDWORD) out; + u32 * dwPtrA = (u32 *) a; + u32 * dwPtrB = (u32 *) b; + u32 * dwPtrOut = (u32 *) out; (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 6f72539e4cca..f003fbebb7a6 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -193,15 +193,15 @@ typedef struct tagKnownNodeDB { u8 byAuthSequence; unsigned long ulLastRxJiffer; u8 bySuppRate; - DWORD dwFlags; + u32 dwFlags; u16 wEnQueueCnt; bool bOnFly; unsigned long long KeyRSC; u8 byKeyIndex; - DWORD dwKeyIndex; + u32 dwKeyIndex; u8 byCipherSuite; - DWORD dwTSC47_16; + u32 dwTSC47_16; u16 wTSC15_0; unsigned int uWepKeyLength; u8 abyWepKey[WLAN_WEPMAX_KEYLEN]; diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index f16428df359a..c0522aa04185 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -309,7 +309,7 @@ typedef struct tagSPMKIDCandidateEvent { typedef struct tagSQuietControl { bool bEnable; - DWORD dwStartTime; + u32 dwStartTime; u8 byPeriod; u16 wDuration; } SQuietControl, *PSQuietControl; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index d63a946b2ac9..66ce1952c6bd 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -750,28 +750,28 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, // Soft MIC if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { if (bIsWEP) { - PDWORD pdwMIC_L; - PDWORD pdwMIC_R; - DWORD dwMIC_Priority; - DWORD dwMICKey0 = 0, dwMICKey1 = 0; - DWORD dwLocalMIC_L = 0; - DWORD dwLocalMIC_R = 0; + u32 * pdwMIC_L; + u32 * pdwMIC_R; + u32 dwMIC_Priority; + u32 dwMICKey0 = 0, dwMICKey1 = 0; + u32 dwLocalMIC_L = 0; + u32 dwLocalMIC_R = 0; if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28])); + dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); + dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); } else { if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20])); + dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); + dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); } else if ((pKey->dwKeyIndex & BIT28) == 0) { - dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20])); + dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); + dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); } else { - dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28])); + dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); + dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); } } @@ -785,8 +785,8 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); MIC_vUnInit(); - pdwMIC_L = (PDWORD)(skb->data + 8 + FrameSize); - pdwMIC_R = (PDWORD)(skb->data + 8 + FrameSize + 4); + pdwMIC_L = (u32 *)(skb->data + 8 + FrameSize); + pdwMIC_R = (u32 *)(skb->data + 8 + FrameSize + 4); if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || @@ -838,12 +838,12 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, PRCB pRCB, (pKey->byCipherSuite == KEY_CTL_CCMP))) { if (bIsWEP) { u16 wLocalTSC15_0 = 0; - DWORD dwLocalTSC47_16 = 0; + u32 dwLocalTSC47_16 = 0; unsigned long long RSC = 0; // endian issues RSC = *((unsigned long long *) &(pKey->KeyRSC)); wLocalTSC15_0 = (u16) RSC; - dwLocalTSC47_16 = (DWORD) (RSC>>16); + dwLocalTSC47_16 = (u32) (RSC>>16); RSC = dwRxTSC47_16; RSC <<= 16; @@ -1136,7 +1136,7 @@ static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, // TKIP/AES PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); + *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); @@ -1235,7 +1235,7 @@ static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, // TKIP/AES PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); + *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 0319f928c1fd..94cee3d5f059 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -489,7 +489,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, param->u.crypt.key_len ); - dwKeyIndex = (DWORD)(param->u.crypt.idx); + dwKeyIndex = (u32)(param->u.crypt.idx); if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { pDevice->byKeyIndex = (u8)dwKeyIndex; pDevice->bTransmitKey = true; diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 5e369673a04f..18305192cfa7 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -272,7 +272,7 @@ int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable, if (uKeyLength == WLAN_WEP104_KEYLEN) pKey->abyKey[15] |= 0x80; } - MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey); + MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey); if ((dwKeyIndex & USE_KEYRSC) == 0) pKey->KeyRSC = 0; /* RSC set by NIC */ @@ -340,7 +340,7 @@ int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable, if (uKeyLength == WLAN_WEP104_KEYLEN) pKey->abyKey[15] |= 0x80; } - MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey); + MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey); if ((dwKeyIndex & USE_KEYRSC) == 0) pKey->KeyRSC = 0; /* RSC set by NIC */ @@ -707,7 +707,7 @@ int KeybSetDefaultKey(struct vnt_private *pDevice, PSKeyManagement pTable, pKey->abyKey[15] |= 0x80; } - MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (PDWORD) pKey->abyKey); + MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (u32 *) pKey->abyKey); if ((dwKeyIndex & USE_KEYRSC) == 0) pKey->KeyRSC = 0; /* RSC set by NIC */ @@ -805,7 +805,7 @@ int KeybSetAllGroupKey(struct vnt_private *pDevice, PSKeyManagement pTable, pKey->abyKey[15] |= 0x80; } - MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (PDWORD) pKey->abyKey); + MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (u32 *) pKey->abyKey); if ((dwKeyIndex & USE_KEYRSC) == 0) pKey->KeyRSC = 0; /* RSC set by NIC */ diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 217decd33fce..56799cf71004 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -61,11 +61,11 @@ typedef struct tagSKeyItem u32 uKeyLength; u8 abyKey[MAX_KEY_LEN]; u64 KeyRSC; - DWORD dwTSC47_16; + u32 dwTSC47_16; u16 wTSC15_0; u8 byCipherSuite; u8 byReserved0; - DWORD dwKeyIndex; + u32 dwKeyIndex; void *pvKeyTable; } SKeyItem, *PSKeyItem; //64 @@ -75,7 +75,7 @@ typedef struct tagSKeyTable u8 byReserved0[2]; //8 SKeyItem PairwiseKey; SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 - DWORD dwGTKeyIndex; // GroupTransmitKey Index + u32 dwGTKeyIndex; // GroupTransmitKey Index bool bInUse; u16 wKeyCtl; bool bSoftWEP; diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 7ec4f02d17ec..ced7d567027f 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -40,7 +40,7 @@ // USB counter // typedef struct tagSUSBCounter { - DWORD dwCrc; + u32 dwCrc; } SUSBCounter, *PSUSBCounter; @@ -91,24 +91,24 @@ typedef struct tagSMib2Counter { // e.g. "interface 1" signed long ifType; signed long ifMtu; - DWORD ifSpeed; + u32 ifSpeed; u8 ifPhysAddress[ETH_ALEN]; signed long ifAdminStatus; signed long ifOperStatus; - DWORD ifLastChange; - DWORD ifInOctets; - DWORD ifInUcastPkts; - DWORD ifInNUcastPkts; - DWORD ifInDiscards; - DWORD ifInErrors; - DWORD ifInUnknownProtos; - DWORD ifOutOctets; - DWORD ifOutUcastPkts; - DWORD ifOutNUcastPkts; - DWORD ifOutDiscards; - DWORD ifOutErrors; - DWORD ifOutQLen; - DWORD ifSpecific; + u32 ifLastChange; + u32 ifInOctets; + u32 ifInUcastPkts; + u32 ifInNUcastPkts; + u32 ifInDiscards; + u32 ifInErrors; + u32 ifInUnknownProtos; + u32 ifOutOctets; + u32 ifOutUcastPkts; + u32 ifOutNUcastPkts; + u32 ifOutDiscards; + u32 ifOutErrors; + u32 ifOutQLen; + u32 ifSpecific; } SMib2Counter, *PSMib2Counter; // Value in the ifType entry @@ -125,26 +125,26 @@ typedef struct tagSMib2Counter { // typedef struct tagSRmonCounter { signed long etherStatsIndex; - DWORD etherStatsDataSource; - DWORD etherStatsDropEvents; - DWORD etherStatsOctets; - DWORD etherStatsPkts; - DWORD etherStatsBroadcastPkts; - DWORD etherStatsMulticastPkts; - DWORD etherStatsCRCAlignErrors; - DWORD etherStatsUndersizePkts; - DWORD etherStatsOversizePkts; - DWORD etherStatsFragments; - DWORD etherStatsJabbers; - DWORD etherStatsCollisions; - DWORD etherStatsPkt64Octets; - DWORD etherStatsPkt65to127Octets; - DWORD etherStatsPkt128to255Octets; - DWORD etherStatsPkt256to511Octets; - DWORD etherStatsPkt512to1023Octets; - DWORD etherStatsPkt1024to1518Octets; - DWORD etherStatsOwners; - DWORD etherStatsStatus; + u32 etherStatsDataSource; + u32 etherStatsDropEvents; + u32 etherStatsOctets; + u32 etherStatsPkts; + u32 etherStatsBroadcastPkts; + u32 etherStatsMulticastPkts; + u32 etherStatsCRCAlignErrors; + u32 etherStatsUndersizePkts; + u32 etherStatsOversizePkts; + u32 etherStatsFragments; + u32 etherStatsJabbers; + u32 etherStatsCollisions; + u32 etherStatsPkt64Octets; + u32 etherStatsPkt65to127Octets; + u32 etherStatsPkt128to255Octets; + u32 etherStatsPkt256to511Octets; + u32 etherStatsPkt512to1023Octets; + u32 etherStatsPkt1024to1518Octets; + u32 etherStatsOwners; + u32 etherStatsStatus; } SRmonCounter, *PSRmonCounter; // @@ -192,27 +192,27 @@ typedef struct tagSCustomCounters { typedef struct tagSISRCounters { unsigned long Length; - DWORD dwIsrTx0OK; - DWORD dwIsrAC0TxOK; - DWORD dwIsrBeaconTxOK; - DWORD dwIsrRx0OK; - DWORD dwIsrTBTTInt; - DWORD dwIsrSTIMERInt; - DWORD dwIsrWatchDog; - DWORD dwIsrUnrecoverableError; - DWORD dwIsrSoftInterrupt; - DWORD dwIsrMIBNearfull; - DWORD dwIsrRxNoBuf; - - DWORD dwIsrUnknown; // unknown interrupt count - - DWORD dwIsrRx1OK; - DWORD dwIsrATIMTxOK; - DWORD dwIsrSYNCTxOK; - DWORD dwIsrCFPEnd; - DWORD dwIsrATIMEnd; - DWORD dwIsrSYNCFlushOK; - DWORD dwIsrSTIMER1Int; + u32 dwIsrTx0OK; + u32 dwIsrAC0TxOK; + u32 dwIsrBeaconTxOK; + u32 dwIsrRx0OK; + u32 dwIsrTBTTInt; + u32 dwIsrSTIMERInt; + u32 dwIsrWatchDog; + u32 dwIsrUnrecoverableError; + u32 dwIsrSoftInterrupt; + u32 dwIsrMIBNearfull; + u32 dwIsrRxNoBuf; + + u32 dwIsrUnknown; // unknown interrupt count + + u32 dwIsrRx1OK; + u32 dwIsrATIMTxOK; + u32 dwIsrSYNCTxOK; + u32 dwIsrCFPEnd; + u32 dwIsrATIMEnd; + u32 dwIsrSYNCFlushOK; + u32 dwIsrSTIMER1Int; ///////////////////////////////////// } SISRCounters, *PSISRCounters; @@ -248,34 +248,34 @@ typedef struct tagSStatCounter { // RSR status count // - DWORD dwRsrFrmAlgnErr; - DWORD dwRsrErr; - DWORD dwRsrCRCErr; - DWORD dwRsrCRCOk; - DWORD dwRsrBSSIDOk; - DWORD dwRsrADDROk; - DWORD dwRsrBCNSSIDOk; - DWORD dwRsrLENErr; - DWORD dwRsrTYPErr; - - DWORD dwNewRsrDECRYPTOK; - DWORD dwNewRsrCFP; - DWORD dwNewRsrUTSF; - DWORD dwNewRsrHITAID; - DWORD dwNewRsrHITAID0; - - DWORD dwRsrLong; - DWORD dwRsrRunt; - - DWORD dwRsrRxControl; - DWORD dwRsrRxData; - DWORD dwRsrRxManage; - - DWORD dwRsrRxPacket; - DWORD dwRsrRxOctet; - DWORD dwRsrBroadcast; - DWORD dwRsrMulticast; - DWORD dwRsrDirected; + u32 dwRsrFrmAlgnErr; + u32 dwRsrErr; + u32 dwRsrCRCErr; + u32 dwRsrCRCOk; + u32 dwRsrBSSIDOk; + u32 dwRsrADDROk; + u32 dwRsrBCNSSIDOk; + u32 dwRsrLENErr; + u32 dwRsrTYPErr; + + u32 dwNewRsrDECRYPTOK; + u32 dwNewRsrCFP; + u32 dwNewRsrUTSF; + u32 dwNewRsrHITAID; + u32 dwNewRsrHITAID0; + + u32 dwRsrLong; + u32 dwRsrRunt; + + u32 dwRsrRxControl; + u32 dwRsrRxData; + u32 dwRsrRxManage; + + u32 dwRsrRxPacket; + u32 dwRsrRxOctet; + u32 dwRsrBroadcast; + u32 dwRsrMulticast; + u32 dwRsrDirected; // 64-bit OID unsigned long long ullRsrOK; @@ -287,36 +287,36 @@ typedef struct tagSStatCounter { unsigned long long ullRxMulticastFrames; unsigned long long ullRxDirectedFrames; - DWORD dwRsrRxFragment; - DWORD dwRsrRxFrmLen64; - DWORD dwRsrRxFrmLen65_127; - DWORD dwRsrRxFrmLen128_255; - DWORD dwRsrRxFrmLen256_511; - DWORD dwRsrRxFrmLen512_1023; - DWORD dwRsrRxFrmLen1024_1518; + u32 dwRsrRxFragment; + u32 dwRsrRxFrmLen64; + u32 dwRsrRxFrmLen65_127; + u32 dwRsrRxFrmLen128_255; + u32 dwRsrRxFrmLen256_511; + u32 dwRsrRxFrmLen512_1023; + u32 dwRsrRxFrmLen1024_1518; // TSR status count // - DWORD dwTsrTotalRetry; // total collision retry count - DWORD dwTsrOnceRetry; // this packet only occur one collision - DWORD dwTsrMoreThanOnceRetry; // this packet occur more than one collision - DWORD dwTsrRetry; // this packet has ever occur collision, + u32 dwTsrTotalRetry; // total collision retry count + u32 dwTsrOnceRetry; // this packet only occur one collision + u32 dwTsrMoreThanOnceRetry; // this packet occur more than one collision + u32 dwTsrRetry; // this packet has ever occur collision, // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - DWORD dwTsrACKData; - DWORD dwTsrErr; - DWORD dwAllTsrOK; - DWORD dwTsrRetryTimeout; - DWORD dwTsrTransmitTimeout; - - DWORD dwTsrTxPacket; - DWORD dwTsrTxOctet; - DWORD dwTsrBroadcast; - DWORD dwTsrMulticast; - DWORD dwTsrDirected; + u32 dwTsrACKData; + u32 dwTsrErr; + u32 dwAllTsrOK; + u32 dwTsrRetryTimeout; + u32 dwTsrTransmitTimeout; + + u32 dwTsrTxPacket; + u32 dwTsrTxOctet; + u32 dwTsrBroadcast; + u32 dwTsrMulticast; + u32 dwTsrDirected; // RD/TD count - DWORD dwCntRxFrmLength; - DWORD dwCntTxBufLength; + u32 dwCntRxFrmLength; + u32 dwCntTxBufLength; u8 abyCntRxPattern[16]; u8 abyCntTxPattern[16]; @@ -324,9 +324,9 @@ typedef struct tagSStatCounter { // Software check.... - DWORD dwCntRxDataErr; // rx buffer data software compare CRC err count - DWORD dwCntDecryptErr; // rx buffer data software compare CRC err count - DWORD dwCntRxICVErr; // rx buffer data software compare CRC err count + u32 dwCntRxDataErr; // rx buffer data software compare CRC err count + u32 dwCntDecryptErr; // rx buffer data software compare CRC err count + u32 dwCntRxICVErr; // rx buffer data software compare CRC err count // 64-bit OID @@ -341,9 +341,9 @@ typedef struct tagSStatCounter { unsigned long long ullTxDirectedBytes; // for autorate - DWORD dwTxOk[MAX_RATE+1]; - DWORD dwTxFail[MAX_RATE+1]; - DWORD dwTxRetryCount[8]; + u32 dwTxOk[MAX_RATE+1]; + u32 dwTxFail[MAX_RATE+1]; + u32 dwTxRetryCount[8]; STxPktInfo abyTxPktInfo[16]; diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c index 1fb88e6d73fb..1a8ae920f1e7 100644 --- a/drivers/staging/vt6656/michael.c +++ b/drivers/staging/vt6656/michael.c @@ -26,8 +26,8 @@ * Date: Sep 4, 2002 * * Functions: - * s_dwGetUINT32 - Convert from u8[] to DWORD in a portable way - * s_vPutUINT32 - Convert from DWORD to u8[] in a portable way + * s_dwGetUINT32 - Convert from u8[] to u32 in a portable way + * s_vPutUINT32 - Convert from u32 to u8[] in a portable way * s_vClear - Reset the state to the empty message. * s_vSetKey - Set the key. * MIC_vInit - Set the key. @@ -48,39 +48,39 @@ /*--------------------- Static Functions --------------------------*/ /* - * static DWORD s_dwGetUINT32(u8 * p); Get DWORD from + * static u32 s_dwGetUINT32(u8 * p); Get u32 from * 4 bytes LSByte first - * static void s_vPutUINT32(u8* p, DWORD val); Put DWORD into + * static void s_vPutUINT32(u8* p, u32 val); Put u32 into * 4 bytes LSByte first */ static void s_vClear(void); /* Clear the internal message, * resets the object to the * state just after construction. */ -static void s_vSetKey(DWORD dwK0, DWORD dwK1); +static void s_vSetKey(u32 dwK0, u32 dwK1); static void s_vAppendByte(u8 b); /* Add a single byte to the internal * message */ /*--------------------- Export Variables --------------------------*/ -static DWORD L, R; /* Current state */ -static DWORD K0, K1; /* Key */ -static DWORD M; /* Message accumulator (single word) */ +static u32 L, R; /* Current state */ +static u32 K0, K1; /* Key */ +static u32 M; /* Message accumulator (single word) */ static unsigned int nBytesInM; /* # bytes in M */ /*--------------------- Export Functions --------------------------*/ /* -static DWORD s_dwGetUINT32 (u8 * p) -// Convert from u8[] to DWORD in a portable way +static u32 s_dwGetUINT32 (u8 * p) +// Convert from u8[] to u32 in a portable way { - DWORD res = 0; + u32 res = 0; unsigned int i; for (i = 0; i < 4; i++) res |= (*p++) << (8*i); return res; } -static void s_vPutUINT32(u8 *p, DWORD val) -// Convert from DWORD to u8[] in a portable way +static void s_vPutUINT32(u8 *p, u32 val) +// Convert from u32 to u8[] in a portable way { unsigned int i; for (i = 0; i < 4; i++) { @@ -99,7 +99,7 @@ static void s_vClear(void) M = 0; } -static void s_vSetKey(DWORD dwK0, DWORD dwK1) +static void s_vSetKey(u32 dwK0, u32 dwK1) { /* Set the key */ K0 = dwK0; @@ -130,7 +130,7 @@ static void s_vAppendByte(u8 b) } } -void MIC_vInit(DWORD dwK0, DWORD dwK1) +void MIC_vInit(u32 dwK0, u32 dwK1) { /* Set the key */ s_vSetKey(dwK0, dwK1); @@ -157,7 +157,7 @@ void MIC_vAppend(u8 * src, unsigned int nBytes) } } -void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR) +void MIC_vGetMIC(u32 * pdwL, u32 * pdwR) { /* Append the minimum padding */ s_vAppendByte(0x5a); diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 074023221b43..2cdb07ed53ad 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -35,7 +35,7 @@ /*--------------------- Export Types ------------------------------*/ -void MIC_vInit(DWORD dwK0, DWORD dwK1); +void MIC_vInit(u32 dwK0, u32 dwK1); void MIC_vUnInit(void); @@ -44,7 +44,7 @@ void MIC_vAppend(u8 * src, unsigned int nBytes); // Get the MIC result. Destination should accept 8 bytes of result. // This also resets the message to empty. -void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); +void MIC_vGetMIC(u32 * pdwL, u32 * pdwR); /*--------------------- Export Macros ------------------------------*/ diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index a415705297b2..114217a6c747 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -842,7 +842,7 @@ int RFbRawSetPower(struct vnt_private *pDevice, u8 byPwr, u32 uRATE) case RF_AIROHA7230: { - DWORD dwMax7230Pwr; + u32 dwMax7230Pwr; if (uRATE <= RATE_11M) { //RobertYu:20060426, for better 11b mask bResult &= IFRFbWriteEmbedded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); @@ -864,7 +864,7 @@ int RFbRawSetPower(struct vnt_private *pDevice, u8 byPwr, u32 uRATE) case RF_VT3226: //RobertYu:20051111, VT3226C0 and before { - DWORD dwVT3226Pwr; + u32 dwVT3226Pwr; if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN) return false; @@ -876,7 +876,7 @@ int RFbRawSetPower(struct vnt_private *pDevice, u8 byPwr, u32 uRATE) case RF_VT3226D0: //RobertYu:20051228 { - DWORD dwVT3226Pwr; + u32 dwVT3226Pwr; if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN) return false; @@ -921,7 +921,7 @@ int RFbRawSetPower(struct vnt_private *pDevice, u8 byPwr, u32 uRATE) //{{RobertYu:20060609 case RF_VT3342A0: { - DWORD dwVT3342Pwr; + u32 dwVT3342Pwr; if (pDevice->byCurPwr >= VT3342_PWR_IDX_LEN) return false; diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h index 8dd611c18036..2c67583cfef9 100644 --- a/drivers/staging/vt6656/rndis.h +++ b/drivers/staging/vt6656/rndis.h @@ -115,7 +115,7 @@ typedef struct _CMD_CLRKEY_ENTRY typedef struct _CMD_WRITE_MISCFF { - DWORD adwMiscFFData[22][4]; //a key entry has only 22 dwords + u32 adwMiscFFData[22][4]; //a key entry has only 22 dwords } CMD_WRITE_MISCFF, *PCMD_WRITE_MISCFF; typedef struct _CMD_SET_TSFTBTT @@ -143,10 +143,10 @@ typedef struct _CMD_CHANGE_BBTYPE u8 byBBCR10; u8 byBB_BBType; //CR88 u8 byMAC_BBType; - DWORD dwRSPINF_b_1; - DWORD dwRSPINF_b_2; - DWORD dwRSPINF_b_55; - DWORD dwRSPINF_b_11; + u32 dwRSPINF_b_1; + u32 dwRSPINF_b_2; + u32 dwRSPINF_b_55; + u32 dwRSPINF_b_11; u16 wRSPINF_a[9]; } CMD_CHANGE_BBTYPE, *PCMD_CHANGE_BBTYPE; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index b542ec3fdc96..024b29c3bfd3 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -324,7 +324,7 @@ static void s_vSWencryption(struct vnt_private *pDevice, //======================================================================= // Append ICV after payload dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize); + pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize); // finally, we must invert dwCRC to get the correct answer *pdwICV = cpu_to_le32(~dwICV); // RC4 encryption @@ -335,7 +335,7 @@ static void s_vSWencryption(struct vnt_private *pDevice, //======================================================================= //Append ICV after payload dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize); + pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize); // finally, we must invert dwCRC to get the correct answer *pdwICV = cpu_to_le32(~dwICV); // RC4 encryption @@ -1516,12 +1516,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]); + dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); + dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); } else { - dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]); + dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]); + dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]); } // DO Software Michael MIC_vInit(dwMICKey0, dwMICKey1); @@ -1541,8 +1541,8 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, MIC_vAppend(pbyPayloadHead, cbFrameBodySize); - pdwMIC_L = (PDWORD)(pbyPayloadHead + cbFrameBodySize); - pdwMIC_R = (PDWORD)(pbyPayloadHead + cbFrameBodySize + 4); + pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize); + pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4); MIC_vGetMIC(pdwMIC_L, pdwMIC_R); MIC_vUnInit(); @@ -1570,13 +1570,13 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, if (pDevice->bSoftwareGenCrcErr == true) { unsigned int cbLen; - PDWORD pdwCRC; + u32 * pdwCRC; dwCRC = 0xFFFFFFFFL; cbLen = cbFrameSize - cbFCSlen; // calculate CRC, and wrtie CRC value to end of TD dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC); - pdwCRC = (PDWORD)(pbyMacHdr + cbLen); + pdwCRC = (u32 *)(pbyMacHdr + cbLen); // finally, we must invert dwCRC to get the correct answer *pdwCRC = ~dwCRC; // Force Error @@ -2359,8 +2359,8 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]); + dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); + dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); // DO Software Michael MIC_vInit(dwMICKey0, dwMICKey1); @@ -2374,8 +2374,8 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); - pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize); - pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); + pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize); + pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); MIC_vGetMIC(pdwMIC_L, pdwMIC_R); MIC_vUnInit(); diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c index d4db71302a43..1fe043c402ff 100644 --- a/drivers/staging/vt6656/tcrc.c +++ b/drivers/staging/vt6656/tcrc.c @@ -42,7 +42,7 @@ /*--------------------- Static Variables --------------------------*/ /* 32-bit CRC table */ -static const DWORD s_adwCrc32Table[256] = { +static const u32 s_adwCrc32Table[256] = { 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, @@ -132,9 +132,9 @@ static const DWORD s_adwCrc32Table[256] = { * Return Value: CRC-32 * -*/ -DWORD CRCdwCrc32(u8 * pbyData, unsigned int cbByte, DWORD dwCrcSeed) +u32 CRCdwCrc32(u8 * pbyData, unsigned int cbByte, u32 dwCrcSeed) { - DWORD dwCrc; + u32 dwCrc; dwCrc = dwCrcSeed; while (cbByte--) { @@ -165,7 +165,7 @@ DWORD CRCdwCrc32(u8 * pbyData, unsigned int cbByte, DWORD dwCrcSeed) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte) +u32 CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte) { return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); } @@ -191,7 +191,7 @@ DWORD CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, DWORD dwPreCRC) +u32 CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, u32 dwPreCRC) { return CRCdwCrc32(pbyData, cbByte, dwPreCRC); } diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index 342061dc9bb4..4eb923b94ceb 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -43,8 +43,8 @@ /*--------------------- Export Functions --------------------------*/ -DWORD CRCdwCrc32(u8 * pbyData, unsigned int cbByte, DWORD dwCrcSeed); -DWORD CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte); -DWORD CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, DWORD dwPreCRC); +u32 CRCdwCrc32(u8 * pbyData, unsigned int cbByte, u32 dwCrcSeed); +u32 CRCdwGetCrc32(u8 * pbyData, unsigned int cbByte); +u32 CRCdwGetCrc32Ex(u8 * pbyData, unsigned int cbByte, u32 dwPreCRC); #endif /* __TCRC_H__ */ diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index c92efdaf4088..ed99289940ea 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -98,10 +98,10 @@ u8 ETHbyGetHashIndexByCrc32(u8 * pbyMultiAddr) */ bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength) { - DWORD dwCRC; + u32 dwCRC; dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); - if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) + if (cpu_to_le32(*((u32 *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) return false; return true; } diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index f5aeb5e53396..0389e888195c 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -185,7 +185,7 @@ void TKIPvMixKey( u8 * pbyTKey, u8 * pbyTA, u16 wTSC15_0, - DWORD dwTSC47_16, + u32 dwTSC47_16, u8 * pbyRC4Key ) { diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index 7662423e2479..a5a09be60a1a 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -50,7 +50,7 @@ void TKIPvMixKey( u8 * pbyTKey, u8 * pbyTA, u16 wTSC15_0, - DWORD dwTSC47_16, + u32 dwTSC47_16, u8 * pbyRC4Key ); diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h index b4e6cb2e4c9f..3a5ee0622f20 100644 --- a/drivers/staging/vt6656/tmacro.h +++ b/drivers/staging/vt6656/tmacro.h @@ -44,7 +44,7 @@ #define LOWORD(d) ((u16)(d)) #endif #if !defined(HIWORD) -#define HIWORD(d) ((u16)((((DWORD)(d)) >> 16) & 0xFFFF)) +#define HIWORD(d) ((u16)((((u32)(d)) >> 16) & 0xFFFF)) #endif #define LODWORD(q) ((q).u.dwLowDword) @@ -54,7 +54,7 @@ #define MAKEWORD(lb, hb) ((u16)(((u8)(lb)) | (((u16)((u8)(hb))) << 8))) #endif #if !defined(MAKEDWORD) -#define MAKEDWORD(lw, hw) ((DWORD)(((u16)(lw)) | (((DWORD)((u16)(hw))) << 16))) +#define MAKEDWORD(lw, hw) ((u32)(((u16)(lw)) | (((u32)((u16)(hw))) << 16))) #endif #endif /* __TMACRO_H__ */ diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index ee1201d4a8e8..b22cf91b1e3c 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -35,8 +35,6 @@ /****** Simple typedefs ***************************************************/ -typedef u32 DWORD; - /****** Common pointer types ***********************************************/ typedef u32 ULONG_PTR; @@ -44,6 +42,4 @@ typedef u32 DWORD_PTR; // boolean pointer -typedef DWORD * PDWORD; - #endif /* __TTYPE_H__ */ diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index c0886c161639..669fb1654adb 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -71,7 +71,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) { struct viawget_wpa_param *param = ctx; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; - DWORD dwKeyIndex = 0; + u32 dwKeyIndex = 0; u8 abyKey[MAX_KEY_LEN]; u8 abySeq[MAX_KEY_LEN]; u64 KeyRSC; @@ -101,7 +101,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx) memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); - dwKeyIndex = (DWORD)(param->u.wpa_key.key_index); + dwKeyIndex = (u32)(param->u.wpa_key.key_index); if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { if (dwKeyIndex > 3) { -- cgit From 1f9eedc2ad7ea89175ead78a175944e7152f3688 Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 25 Feb 2013 20:32:54 -0500 Subject: staging: vt6656: removed custom pointer definitions No checkpatch findings were resolved. sed -i 's/\bULONG_PTR\b/u32/g' drivers/staging/vt6656/*.[ch] sed -i 's/\bDWORD_PTR\b/u32/g' drivers/staging/vt6656/*.[ch] Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/bssdb.c | 8 ++++---- drivers/staging/vt6656/ttype.h | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index bbe348e98b9a..759404d57e11 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -430,7 +430,7 @@ int BSSbInsertToBSSList(struct vnt_private *pDevice, unsigned int uLen = pRSNWPA->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((u8 *) pRSNWPA - pbyIEs))) { + (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) { pBSSList->wWPALen = uLen; memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); WPA_ParseRSN(pBSSList, pRSNWPA); @@ -443,7 +443,7 @@ int BSSbInsertToBSSList(struct vnt_private *pDevice, unsigned int uLen = pRSN->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((u8 *) pRSN - pbyIEs))) { + (unsigned int) (u32) ((u8 *) pRSN - pbyIEs))) { pBSSList->wRSNLen = uLen; memcpy(pBSSList->byRSNIE, pRSN, uLen); WPA2vParseRSN(pBSSList, pRSN); @@ -592,7 +592,7 @@ int BSSbUpdateToBSSList(struct vnt_private *pDevice, if (pRSNWPA != NULL) { unsigned int uLen = pRSNWPA->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((u8 *) pRSNWPA - pbyIEs))) { + (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) { pBSSList->wWPALen = uLen; memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); WPA_ParseRSN(pBSSList, pRSNWPA); @@ -604,7 +604,7 @@ int BSSbUpdateToBSSList(struct vnt_private *pDevice, if (pRSN != NULL) { unsigned int uLen = pRSN->len + 2; if (uLen <= (uIELength - - (unsigned int) (ULONG_PTR) ((u8 *) pRSN - pbyIEs))) { + (unsigned int) (u32) ((u8 *) pRSN - pbyIEs))) { pBSSList->wRSNLen = uLen; memcpy(pBSSList->byRSNIE, pRSN, uLen); WPA2vParseRSN(pBSSList, pRSN); diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index b22cf91b1e3c..d1ba96ea7010 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -37,9 +37,6 @@ /****** Common pointer types ***********************************************/ -typedef u32 ULONG_PTR; -typedef u32 DWORD_PTR; - // boolean pointer #endif /* __TTYPE_H__ */ -- cgit From 4fcf94980c994ed992d8efd1424bd842225f1cc6 Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 25 Feb 2013 20:32:55 -0500 Subject: staging: vt6656: removed no longer useful ttype.h file Removed includes and added linux/types.h instead when needed. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211hdr.h | 2 -- drivers/staging/vt6656/80211mgr.h | 1 - drivers/staging/vt6656/TODO | 2 +- drivers/staging/vt6656/aes_ccmp.h | 2 -- drivers/staging/vt6656/baseband.h | 1 - drivers/staging/vt6656/bssdb.c | 1 - drivers/staging/vt6656/card.h | 1 - drivers/staging/vt6656/channel.h | 1 - drivers/staging/vt6656/control.h | 1 - drivers/staging/vt6656/datarate.c | 1 - drivers/staging/vt6656/desc.h | 2 +- drivers/staging/vt6656/device.h | 1 - drivers/staging/vt6656/device_cfg.h | 2 -- drivers/staging/vt6656/dpc.h | 1 - drivers/staging/vt6656/firmware.h | 1 - drivers/staging/vt6656/int.h | 1 - drivers/staging/vt6656/iocmd.h | 2 -- drivers/staging/vt6656/key.h | 1 - drivers/staging/vt6656/mac.h | 1 - drivers/staging/vt6656/mib.h | 1 - drivers/staging/vt6656/michael.h | 2 ++ drivers/staging/vt6656/power.c | 1 - drivers/staging/vt6656/rc4.h | 2 +- drivers/staging/vt6656/rf.h | 1 - drivers/staging/vt6656/rxtx.h | 1 - drivers/staging/vt6656/srom.h | 2 -- drivers/staging/vt6656/tcrc.h | 2 +- drivers/staging/vt6656/tether.h | 1 - drivers/staging/vt6656/tkip.h | 1 - drivers/staging/vt6656/tmacro.h | 2 -- drivers/staging/vt6656/ttype.h | 42 ------------------------------------- drivers/staging/vt6656/usbpipe.h | 1 - drivers/staging/vt6656/wcmd.c | 1 - drivers/staging/vt6656/wcmd.h | 2 +- drivers/staging/vt6656/wctl.h | 1 - drivers/staging/vt6656/wmgr.h | 1 - drivers/staging/vt6656/wpa.c | 1 - drivers/staging/vt6656/wpa.h | 1 - drivers/staging/vt6656/wpa2.h | 1 - 39 files changed, 7 insertions(+), 85 deletions(-) delete mode 100644 drivers/staging/vt6656/ttype.h (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h index 0ce12e9e858f..198fc954930a 100644 --- a/drivers/staging/vt6656/80211hdr.h +++ b/drivers/staging/vt6656/80211hdr.h @@ -28,8 +28,6 @@ #ifndef __80211HDR_H__ #define __80211HDR_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ /* bit type */ diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index 990d44784aa0..c8cc1d124f54 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -31,7 +31,6 @@ #ifndef __80211MGR_H__ #define __80211MGR_H__ -#include "ttype.h" #include "80211hdr.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO index a318995ba07f..e154b2f3b247 100644 --- a/drivers/staging/vt6656/TODO +++ b/drivers/staging/vt6656/TODO @@ -7,7 +7,7 @@ TODO: - split rf.c - abstract VT3184 chipset specific code - add common vt665x infrastructure -- kill ttype.h +- kill ttype.h -- done - switch to use LIB80211 - switch to use MAC80211 - use kernel coding style diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h index 349fe9effa3e..d4192526484f 100644 --- a/drivers/staging/vt6656/aes_ccmp.h +++ b/drivers/staging/vt6656/aes_ccmp.h @@ -30,8 +30,6 @@ #ifndef __AES_H__ #define __AES_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Types ------------------------------*/ diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index a6c3448e77ee..f3f58b56a211 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -33,7 +33,6 @@ #ifndef __BASEBAND_H__ #define __BASEBAND_H__ -#include "ttype.h" #include "tether.h" #include "device.h" diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 759404d57e11..f47cd3e0b1ee 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -39,7 +39,6 @@ * */ -#include "ttype.h" #include "tmacro.h" #include "tether.h" #include "device.h" diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 9905e35fe83b..25d5aa2930cd 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -29,7 +29,6 @@ #ifndef __CARD_H__ #define __CARD_H__ #include "device.h" -#include "ttype.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 30cd46dcb2b1..aceb29aeb18b 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -31,7 +31,6 @@ #define _CHANNEL_H_ #include "device.h" -#include "ttype.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h index 76ce0244e100..2a4e283613c8 100644 --- a/drivers/staging/vt6656/control.h +++ b/drivers/staging/vt6656/control.h @@ -30,7 +30,6 @@ #ifndef __CONTROL_H__ #define __CONTROL_H__ -#include "ttype.h" #include "device.h" #include "usbpipe.h" diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index 7ce332c65850..e11821319219 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -33,7 +33,6 @@ * */ -#include "ttype.h" #include "tmacro.h" #include "mac.h" #include "80211mgr.h" diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index a93eb5fa92c9..64cb046fe988 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -33,7 +33,7 @@ #include #include -#include "ttype.h" + #include "tether.h" /* max transmit or receive buffer size */ diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index c0522aa04185..9bb4397f1a72 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -66,7 +66,6 @@ */ #include "device_cfg.h" -#include "ttype.h" #include "80211hdr.h" #include "tether.h" #include "wmgr.h" diff --git a/drivers/staging/vt6656/device_cfg.h b/drivers/staging/vt6656/device_cfg.h index 62290d0ac195..ea66b975fa5b 100644 --- a/drivers/staging/vt6656/device_cfg.h +++ b/drivers/staging/vt6656/device_cfg.h @@ -29,8 +29,6 @@ #include -#include "ttype.h" - typedef struct _version { unsigned char major; diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 786c523f5479..933df02f6dd0 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -29,7 +29,6 @@ #ifndef __DPC_H__ #define __DPC_H__ -#include "ttype.h" #include "device.h" #include "wcmd.h" diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index ebab3a6351b3..dff516281b41 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -30,7 +30,6 @@ #ifndef __FIRMWARE_H__ #define __FIRMWARE_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 180ea57f9888..13e1a6a6158b 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -30,7 +30,6 @@ #ifndef __INT_H__ #define __INT_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index c354a77964d8..dab089ac5cc9 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -29,8 +29,6 @@ #ifndef __IOCMD_H__ #define __IOCMD_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ // ioctl Command code diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 56799cf71004..a7101d7e6424 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -30,7 +30,6 @@ #ifndef __KEY_H__ #define __KEY_H__ -#include "ttype.h" #include "tether.h" #include "80211mgr.h" diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 6e28500ae5f8..32ac58793f19 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -34,7 +34,6 @@ #ifndef __MAC_H__ #define __MAC_H__ -#include "ttype.h" #include "device.h" #include "tmacro.h" diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index ced7d567027f..cc8089ec0350 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -29,7 +29,6 @@ #ifndef __MIB_H__ #define __MIB_H__ -#include "ttype.h" #include "tether.h" #include "desc.h" diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 2cdb07ed53ad..56331ccfc1db 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -31,6 +31,8 @@ #ifndef __MICHAEL_H__ #define __MICHAEL_H__ +#include + /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Types ------------------------------*/ diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index f3445109eeaf..94c2acde268c 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -37,7 +37,6 @@ * */ -#include "ttype.h" #include "mac.h" #include "device.h" #include "wmgr.h" diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h index 2751d06bb9cf..fe613f819aef 100644 --- a/drivers/staging/vt6656/rc4.h +++ b/drivers/staging/vt6656/rc4.h @@ -30,7 +30,7 @@ #ifndef __RC4_H__ #define __RC4_H__ -#include "ttype.h" +#include /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Types ------------------------------*/ diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 9f70cf740bae..aa0b007a4e9b 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -30,7 +30,6 @@ #ifndef __RF_H__ #define __RF_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 57706acf3acc..e27640cda90c 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -29,7 +29,6 @@ #ifndef __RXTX_H__ #define __RXTX_H__ -#include "ttype.h" #include "device.h" #include "wcmd.h" diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h index 9f1af6746ccb..48e10c45a182 100644 --- a/drivers/staging/vt6656/srom.h +++ b/drivers/staging/vt6656/srom.h @@ -30,8 +30,6 @@ #ifndef __SROM_H__ #define __SROM_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ #define EEP_MAX_CONTEXT_SIZE 256 diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index 4eb923b94ceb..c45a63af1902 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -29,7 +29,7 @@ #ifndef __TCRC_H__ #define __TCRC_H__ -#include "ttype.h" +#include /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index d3ef6b59d503..4812659c13b6 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -30,7 +30,6 @@ #define __TETHER_H__ #include -#include "ttype.h" /*--------------------- Export Definitions -------------------------*/ // diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index a5a09be60a1a..2b247d225de1 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -30,7 +30,6 @@ #ifndef __TKIP_H__ #define __TKIP_H__ -#include "ttype.h" #include "tether.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h index 3a5ee0622f20..15cd5abb8004 100644 --- a/drivers/staging/vt6656/tmacro.h +++ b/drivers/staging/vt6656/tmacro.h @@ -29,8 +29,6 @@ #ifndef __TMACRO_H__ #define __TMACRO_H__ -#include "ttype.h" - /****** Common helper macros ***********************************************/ #if !defined(LOBYTE) diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h deleted file mode 100644 index d1ba96ea7010..000000000000 --- a/drivers/staging/vt6656/ttype.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: ttype.h - * - * Purpose: define basic common types and macros - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __TTYPE_H__ -#define __TTYPE_H__ - -#include - -/******* Common definitions and typedefs ***********************************/ - -/****** Simple typedefs ***************************************************/ - -/****** Common pointer types ***********************************************/ - -// boolean pointer - -#endif /* __TTYPE_H__ */ diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index b3023559c15b..e277bb4f0386 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -30,7 +30,6 @@ #ifndef __USBPIPE_H__ #define __USBPIPE_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 4d9e1456a35d..18e1d5bf5f60 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -38,7 +38,6 @@ * */ -#include "ttype.h" #include "tmacro.h" #include "device.h" #include "mac.h" diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 398414b2b431..22878b9cedd6 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -28,7 +28,7 @@ #ifndef __WCMD_H__ #define __WCMD_H__ -#include "ttype.h" + #include "80211hdr.h" #include "80211mgr.h" diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h index 1b21e32e99e5..4436108250f6 100644 --- a/drivers/staging/vt6656/wctl.h +++ b/drivers/staging/vt6656/wctl.h @@ -29,7 +29,6 @@ #ifndef __WCTL_H__ #define __WCTL_H__ -#include "ttype.h" #include "tether.h" #include "device.h" diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index 83aed45f68a3..11cbcc07c6b8 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -34,7 +34,6 @@ #ifndef __WMGR_H__ #define __WMGR_H__ -#include "ttype.h" #include "80211mgr.h" #include "80211hdr.h" #include "wcmd.h" diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index e370b39821c6..919d969ae8f8 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -32,7 +32,6 @@ * */ -#include "ttype.h" #include "tmacro.h" #include "tether.h" #include "device.h" diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h index 2e35856c50f3..21b34567bbe7 100644 --- a/drivers/staging/vt6656/wpa.h +++ b/drivers/staging/vt6656/wpa.h @@ -31,7 +31,6 @@ #ifndef __WPA_H__ #define __WPA_H__ -#include "ttype.h" #include "80211hdr.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 03b14c72d204..5b3b9ff5a466 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -31,7 +31,6 @@ #ifndef __WPA2_H__ #define __WPA2_H__ -#include "ttype.h" #include "80211mgr.h" #include "80211hdr.h" #include "bssdb.h" -- cgit From 81372118c6fc12d41b6e978b915cc010fe6e5700 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 05:13:50 +0100 Subject: staging/slicoss: Check pointer before dereferencing Smatch complains that the variable adapter is dereferenced before it is checked: slicoss.c:906 slic_timer_load_check() warn: variable dereferenced before check 'adapter' (see line 904) -> move the assignment after the check. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 76fc2e554f35..753993c867fa 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -901,10 +901,9 @@ static void slic_timer_load_check(ulong cardaddr) u32 load = card->events; u32 level = 0; - intagg = &adapter->slic_regs->slic_intagg; - if ((adapter) && (adapter->state == ADAPT_UP) && (card->state == CARD_UP) && (slic_global.dynamic_intagg)) { + intagg = &adapter->slic_regs->slic_intagg; if (adapter->devid == SLIC_1GB_DEVICE_ID) { if (adapter->linkspeed == LINK_1000MB) level = 100; -- cgit From cbb0920b9b5090c7006404d8c6533f8ca03cf2ed Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 05:18:49 +0100 Subject: staging/slicoss: Remove always true if statement skbtype is assigned once to NORMAL_ETHFRAME and then checked if it is NORMAL_ETHFRAME -> remove the checks. This also gets rid of the (false positive) smatch warning: slicoss.c:2829 slic_xmit_start() error: potential NULL dereference 'hcmd'. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 753993c867fa..048a3419a2fd 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -2786,7 +2786,6 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) struct adapter *adapter = netdev_priv(dev); struct slic_hostcmd *hcmd = NULL; u32 status = 0; - u32 skbtype = NORMAL_ETHFRAME; void *offloadcmd = NULL; card = adapter->card; @@ -2800,19 +2799,16 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) goto xmit_fail; } - if (skbtype == NORMAL_ETHFRAME) { - hcmd = slic_cmdq_getfree(adapter); - if (!hcmd) { - adapter->xmitq_full = 1; - status = XMIT_FAIL_HOSTCMD_FAIL; - goto xmit_fail; - } - hcmd->skb = skb; - hcmd->busy = 1; - hcmd->type = SLIC_CMD_DUMB; - if (skbtype == NORMAL_ETHFRAME) - slic_xmit_build_request(adapter, hcmd, skb); + hcmd = slic_cmdq_getfree(adapter); + if (!hcmd) { + adapter->xmitq_full = 1; + status = XMIT_FAIL_HOSTCMD_FAIL; + goto xmit_fail; } + hcmd->skb = skb; + hcmd->busy = 1; + hcmd->type = SLIC_CMD_DUMB; + slic_xmit_build_request(adapter, hcmd, skb); dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; @@ -2838,7 +2834,7 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) xmit_done: return NETDEV_TX_OK; xmit_fail: - slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status); + slic_xmit_fail(adapter, skb, offloadcmd, NORMAL_ETHFRAME, status); goto xmit_done; } -- cgit From 6d1b80fd886937ad4d6169ffa78cb0075eebce53 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 05:18:50 +0100 Subject: staging/slicoss: Fix operation may be undefined warning gcc complains about an undefined operation: slicoss.c:1417:19: warning: operation on 'rspq->pageindex' may be undefined [-Wsequence-point] The intended operation was (probably) to retrieve the pageindex + 1 and let it wrap around if it reaches the num_pages. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 048a3419a2fd..fc085856c027 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1414,7 +1414,7 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter) slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64, (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE), &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH); - rspq->pageindex = (++rspq->pageindex) % rspq->num_pages; + rspq->pageindex = (rspq->pageindex + 1) % rspq->num_pages; rspq->offset = 0; rspq->rspbuf = (struct slic_rspbuf *) rspq->vaddr[rspq->pageindex]; -- cgit From 20d403e801272b84e033b8f17d3e45c4f66507c7 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 05:18:51 +0100 Subject: staging/slicoss: Fix buffer possible overflow in slic_card_locate smatch complains about a possible buffer overflow slicoss.c:3651 slic_card_locate() error: buffer overflow 'physcard->adapter' 4 <= 4 If the for loop is not exited prematurely i++ is executed after the last iteration and thus i can be 4, which is out of bounds for physcard->adapter. -> Add check for this condition and simplify the if statement by inverting the condition. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index fc085856c027..48056bf910b3 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3643,11 +3643,12 @@ static u32 slic_card_locate(struct adapter *adapter) while (physcard) { for (i = 0; i < SLIC_MAX_PORTS; i++) { - if (!physcard->adapter[i]) - continue; - else + if (physcard->adapter[i]) break; } + if (i == SLIC_MAX_PORTS) + break; + if (physcard->adapter[i]->slotnumber == adapter->slotnumber) break; physcard = physcard->next; -- cgit From 97b3e0ed1df6cf577be12b96cf80e5f7d90c8323 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 05:18:52 +0100 Subject: staging/slicoss: Use ether_crc for mac hash calculation Instead of performing the hash calculation for the mac address by ourself, we can simply reuse ether_crc and shift only the result according to our needs. The code was tested against the previous implementation by verifying both implementations against each other in userspace for 16200000000 different mac addresses, changing the vendor bits of the mac address first. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 69 +++------------------------------------ 1 file changed, 4 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 48056bf910b3..58a00c2db33b 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -189,76 +190,14 @@ static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg, adapter->bit64reglock.flags); } -/* - * Functions to obtain the CRC corresponding to the destination mac address. - * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using - * the polynomial: - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + - * x^4 + x^2 + x^1. - * - * After the CRC for the 6 bytes is generated (but before the value is - * complemented), - * we must then transpose the value and return bits 30-23. - * - */ -static u32 slic_crc_table[256]; /* Table of CRCs for all possible byte values */ -static u32 slic_crc_init; /* Is table initialized */ - -/* - * Contruct the CRC32 table - */ -static void slic_mcast_init_crc32(void) -{ - u32 c; /* CRC reg */ - u32 e = 0; /* Poly X-or pattern */ - int i; /* counter */ - int k; /* byte being shifted into crc */ - - static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 }; - - for (i = 0; i < ARRAY_SIZE(p); i++) - e |= 1L << (31 - p[i]); - - for (i = 1; i < 256; i++) { - c = i; - for (k = 8; k; k--) - c = c & 1 ? (c >> 1) ^ e : c >> 1; - slic_crc_table[i] = c; - } -} - -/* - * Return the MAC hast as described above. - */ -static unsigned char slic_mcast_get_mac_hash(char *macaddr) -{ - u32 crc; - char *p; - int i; - unsigned char machash = 0; - - if (!slic_crc_init) { - slic_mcast_init_crc32(); - slic_crc_init = 1; - } - - crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */ - for (i = 0, p = macaddr; i < 6; ++p, ++i) - crc = (crc >> 8) ^ slic_crc_table[(crc ^ *p) & 0xFF]; - - /* Return bits 1-8, transposed */ - for (i = 1; i < 9; i++) - machash |= (((crc >> i) & 1) << (8 - i)); - - return machash; -} - static void slic_mcast_set_bit(struct adapter *adapter, char *address) { unsigned char crcpoly; /* Get the CRC polynomial for the mac address */ - crcpoly = slic_mcast_get_mac_hash(address); + /* we use bits 1-8 (lsb), bitwise reversed, + * msb (= lsb bit 0 before bitrev) is automatically discarded */ + crcpoly = (ether_crc(ETH_ALEN, address)>>23); /* We only have space on the SLIC for 64 entries. Lop * off the top two bits. (2^6 = 64) -- cgit From 0f1bf4baf61ca426a210bf3c98263957fa474158 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 00:12:48 +0100 Subject: staging/sm7xxfb: Convert to SIMPLE_DEV_PM_OPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of assigning the pm_ops fields individually we can simply use SIMPLE_DEV_PM_OPS. Signed-off-by: Peter Huewe Acked-by: Javier Muñoz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xxfb/sm7xxfb.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index 0764bbbfd497..8add64b1cb09 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -1006,15 +1006,7 @@ static int smtcfb_pci_resume(struct device *device) return 0; } -static const struct dev_pm_ops sm7xx_pm_ops = { - .suspend = smtcfb_pci_suspend, - .resume = smtcfb_pci_resume, - .freeze = smtcfb_pci_suspend, - .thaw = smtcfb_pci_resume, - .poweroff = smtcfb_pci_suspend, - .restore = smtcfb_pci_resume, -}; - +static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume); #define SM7XX_PM_OPS (&sm7xx_pm_ops) #else /* !CONFIG_PM */ -- cgit From 01d0a9b474661831cd1ee5d88d5ee3fb80b55a7a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Feb 2013 16:33:11 -0800 Subject: staging: slicoss: Remove dma_addr_t cast compilation warnings Eliminate some warnings by casting to unsigned long before casting a dma_addr_t value to a pointer. btw: Does slicoss always work on x86-32? Is a pshmem guaranteed to be accessible by a 32 bit address? Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 58a00c2db33b..c8375a26816b 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -999,7 +999,8 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr) if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) { struct slic_shmem *pshmem; - pshmem = (struct slic_shmem *)adapter->phys_shmem; + pshmem = (struct slic_shmem *)(unsigned long) + adapter->phys_shmem; #if BITS_PER_LONG == 64 slic_upr_queue_request(adapter, SLIC_UPR_RLSR, @@ -1631,10 +1632,11 @@ retry_rcvqfill: #endif skb = alloc_skb(SLIC_RCVQ_RCVBUFSIZE, GFP_ATOMIC); if (skb) { - paddr = (void *)pci_map_single(adapter->pcidev, - skb->data, - SLIC_RCVQ_RCVBUFSIZE, - PCI_DMA_FROMDEVICE); + paddr = (void *)(unsigned long) + pci_map_single(adapter->pcidev, + skb->data, + SLIC_RCVQ_RCVBUFSIZE, + PCI_DMA_FROMDEVICE); paddrl = SLIC_GET_ADDR_LOW(paddr); paddrh = SLIC_GET_ADDR_HIGH(paddr); @@ -1781,8 +1783,9 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb) struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head; struct device *dev; - paddr = (void *)pci_map_single(adapter->pcidev, skb->head, - SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE); + paddr = (void *)(unsigned long) + pci_map_single(adapter->pcidev, skb->head, + SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE); rcvbuf->status = 0; skb->next = NULL; @@ -2279,7 +2282,7 @@ static void slic_link_event_handler(struct adapter *adapter) return; } - pshmem = (struct slic_shmem *)adapter->phys_shmem; + pshmem = (struct slic_shmem *)(unsigned long)adapter->phys_shmem; #if BITS_PER_LONG == 64 status = slic_upr_request(adapter, @@ -2306,7 +2309,7 @@ static void slic_init_cleanup(struct adapter *adapter) sizeof(struct slic_shmem), adapter->pshmem, adapter->phys_shmem); adapter->pshmem = NULL; - adapter->phys_shmem = (dma_addr_t) NULL; + adapter->phys_shmem = (dma_addr_t)(unsigned long)NULL; } if (adapter->pingtimerset) { @@ -2880,7 +2883,8 @@ static int slic_if_init(struct adapter *adapter) mdelay(1); if (!adapter->isp_initialized) { - pshmem = (struct slic_shmem *)adapter->phys_shmem; + pshmem = (struct slic_shmem *)(unsigned long) + adapter->phys_shmem; spin_lock_irqsave(&adapter->bit64reglock.lock, adapter->bit64reglock.flags); @@ -3282,7 +3286,8 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter) } slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH); mdelay(1); - pshmem = (struct slic_shmem *)adapter->phys_shmem; + pshmem = (struct slic_shmem *)(unsigned long) + adapter->phys_shmem; spin_lock_irqsave(&adapter->bit64reglock.lock, adapter->bit64reglock.flags); -- cgit From a6000538e402ef2479a16ff789059c78a152be9d Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 18:50:18 +0100 Subject: staging/gdm72xx: Include corresponding header file (fix sparse warning) sdio_boot.c and netlink_k.c both have a corresponding header file with their function prototypes but fail to include them, which leads to the following sparse warnings: sdio_boot.c:135:5: warning: symbol 'sdio_boot' was not declared. Should it be static? netlink_k.c:89:13: warning: symbol 'netlink_init' was not declared. Should it be static? netlink_k.c:109:6: warning: symbol 'netlink_exit' was not declared. Should it be static? netlink_k.c:114:5: warning: symbol 'netlink_send' was not declared. Should it be static? -> Add the include files and silence the warning Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/netlink_k.c | 1 + drivers/staging/gdm72xx/sdio_boot.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 52c25ba5831d..8a92605adbff 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -18,6 +18,7 @@ #include #include #include +#include "netlink_k.h" #if !defined(NLMSG_HDRLEN) #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c index 93046dda78f0..4302fcbdfdc3 100644 --- a/drivers/staging/gdm72xx/sdio_boot.c +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -27,6 +27,7 @@ #include #include "gdm_sdio.h" +#include "sdio_boot.h" #define TYPE_A_HEADER_SIZE 4 #define TYPE_A_LOOKAHEAD_SIZE 16 -- cgit From eb986df15c86b66a51f6e82f4706bc825444670b Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 18:50:19 +0100 Subject: staging/gdm72xx: Remove unused variable in gdm_qos.c len is never read after assignment, thus can be removed. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 1e6303123722..d48994befebd 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -337,7 +337,6 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) struct nic *nic = nic_ptr; u32 i, SFID, index, pos; u8 subCmdEvt; - u8 len; struct qos_cb_s *qcb = &nic->qos; struct qos_entry_s *entry, *n; struct list_head send_list; @@ -347,8 +346,6 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) subCmdEvt = (u8)buf[4]; if (subCmdEvt == QOS_REPORT) { - len = (u8)buf[5]; - spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < qcb->qos_list_cnt; i++) { SFID = ((buf[(i*5)+6]<<24)&0xff000000); @@ -369,8 +366,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) send_qos_list(nic, &send_list); return; } else if (subCmdEvt == QOS_ADD) { - pos = 5; - len = (u8)buf[pos++]; + pos = 6; SFID = ((buf[pos++]<<24)&0xff000000); SFID += ((buf[pos++]<<16)&0xff0000); @@ -424,8 +420,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) qcb->qos_limit_size = 254/qcb->qos_list_cnt; spin_unlock_irqrestore(&qcb->qos_lock, flags); } else if (subCmdEvt == QOS_CHANGE_DEL) { - pos = 5; - len = (u8)buf[pos++]; + pos = 6; SFID = ((buf[pos++]<<24)&0xff000000); SFID += ((buf[pos++]<<16)&0xff0000); SFID += ((buf[pos++]<<8)&0xff00); -- cgit From d38529100d0f2e844df5f06d67dae8dd32086ec1 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 19 Feb 2013 18:50:20 +0100 Subject: staging/gdm72xx: Remove duplicated code in gdm_qos.c The first branch of the if statement is ended with a return thus there is no need for an else if, and thus we can move the duplicated code to the top and use it for the other two branches. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 42 ++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index d48994befebd..b795353e8348 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -365,20 +365,24 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_unlock_irqrestore(&qcb->qos_lock, flags); send_qos_list(nic, &send_list); return; - } else if (subCmdEvt == QOS_ADD) { - pos = 6; - - SFID = ((buf[pos++]<<24)&0xff000000); - SFID += ((buf[pos++]<<16)&0xff0000); - SFID += ((buf[pos++]<<8)&0xff00); - SFID += (buf[pos++]); - - index = get_csr(qcb, SFID, 1); - if (index == -1) { - netdev_err(nic->netdev, "QoS ERROR: csr Update Error\n"); - return; - } + } + /* subCmdEvt == QOS_ADD || subCmdEvt == QOS_CHANG_DEL */ + pos = 6; + SFID = ((buf[pos++]<<24)&0xff000000); + SFID += ((buf[pos++]<<16)&0xff0000); + SFID += ((buf[pos++]<<8)&0xff00); + SFID += (buf[pos++]); + + index = get_csr(qcb, SFID, 1); + if (index == -1) { + netdev_err(nic->netdev, + "QoS ERROR: csr Update Error / Wrong index (%d) \n", + index); + return; + } + + if (subCmdEvt == QOS_ADD) { netdev_dbg(nic->netdev, "QOS_ADD SFID = 0x%x, index=%d\n", SFID, index); @@ -420,18 +424,6 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) qcb->qos_limit_size = 254/qcb->qos_list_cnt; spin_unlock_irqrestore(&qcb->qos_lock, flags); } else if (subCmdEvt == QOS_CHANGE_DEL) { - pos = 6; - SFID = ((buf[pos++]<<24)&0xff000000); - SFID += ((buf[pos++]<<16)&0xff0000); - SFID += ((buf[pos++]<<8)&0xff00); - SFID += (buf[pos++]); - index = get_csr(qcb, SFID, 1); - if (index == -1) { - netdev_err(nic->netdev, "QoS ERROR: Wrong index(%d)\n", - index); - return; - } - netdev_dbg(nic->netdev, "QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", SFID, index); -- cgit From 90a08fdcd440ab6c6e6e2775c673c7b58871a4c0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Feb 2013 18:32:28 -0800 Subject: staging: fix all sparse warnings in silicom/bypasslib/ Fix all sparse warning in drivers/staging/silicom/bypasslib/, e.g.: drivers/staging/silicom/bypasslib/bypass.c:471:21: warning: non-ANSI function declaration of function 'init_lib_module' drivers/staging/silicom/bypasslib/bypass.c:478:25: warning: non-ANSI function declaration of function 'cleanup_lib_module' drivers/staging/silicom/bypasslib/bypass.c:137:5: warning: symbol 'is_bypass_dev' was not declared. Should it be static? drivers/staging/silicom/bypasslib/bypass.c:182:5: warning: symbol 'is_bypass' was not declared. Should it be static? drivers/staging/silicom/bypasslib/bypass.c:192:5: warning: symbol 'get_bypass_slave' was not declared. Should it be static? drivers/staging/silicom/bypasslib/bypass.c:197:5: warning: symbol 'get_bypass_caps' was not declared. Should it be static? drivers/staging/silicom/bypasslib/bypass.c:202:5: warning: symbol 'get_wd_set_caps' was not declared. Should it be static? etc. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bypasslib/bypass.c | 94 +++++++++++++++--------------- 1 file changed, 47 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c index 95a1f1815d90..9ed250848e81 100644 --- a/drivers/staging/silicom/bypasslib/bypass.c +++ b/drivers/staging/silicom/bypasslib/bypass.c @@ -134,7 +134,7 @@ static int is_dev_sd(int if_index) return (ret >= 0 ? 1 : 0); } -int is_bypass_dev(int if_index) +static int is_bypass_dev(int if_index) { struct pci_dev *pdev = NULL; struct net_device *dev = NULL; @@ -179,7 +179,7 @@ int is_bypass_dev(int if_index) return (ret < 0 ? -1 : ret); } -int is_bypass(int if_index) +static int is_bypass(int if_index) { int ret = 0; SET_BPLIB_INT_FN(is_bypass, int, if_index, ret); @@ -189,70 +189,70 @@ int is_bypass(int if_index) return ret; } -int get_bypass_slave(int if_index) +static int get_bypass_slave(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass_slave, GET_BYPASS_SLAVE, if_index); } -int get_bypass_caps(int if_index) +static int get_bypass_caps(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass_caps, GET_BYPASS_CAPS, if_index); } -int get_wd_set_caps(int if_index) +static int get_wd_set_caps(int if_index) { DO_BPLIB_GET_ARG_FN(get_wd_set_caps, GET_WD_SET_CAPS, if_index); } -int set_bypass(int if_index, int bypass_mode) +static int set_bypass(int if_index, int bypass_mode) { DO_BPLIB_SET_ARG_FN(set_bypass, SET_BYPASS, if_index, bypass_mode); } -int get_bypass(int if_index) +static int get_bypass(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass, GET_BYPASS, if_index); } -int get_bypass_change(int if_index) +static int get_bypass_change(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass_change, GET_BYPASS_CHANGE, if_index); } -int set_dis_bypass(int if_index, int dis_bypass) +static int set_dis_bypass(int if_index, int dis_bypass) { DO_BPLIB_SET_ARG_FN(set_dis_bypass, SET_DIS_BYPASS, if_index, dis_bypass); } -int get_dis_bypass(int if_index) +static int get_dis_bypass(int if_index) { DO_BPLIB_GET_ARG_FN(get_dis_bypass, GET_DIS_BYPASS, if_index); } -int set_bypass_pwoff(int if_index, int bypass_mode) +static int set_bypass_pwoff(int if_index, int bypass_mode) { DO_BPLIB_SET_ARG_FN(set_bypass_pwoff, SET_BYPASS_PWOFF, if_index, bypass_mode); } -int get_bypass_pwoff(int if_index) +static int get_bypass_pwoff(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass_pwoff, GET_BYPASS_PWOFF, if_index); } -int set_bypass_pwup(int if_index, int bypass_mode) +static int set_bypass_pwup(int if_index, int bypass_mode) { DO_BPLIB_SET_ARG_FN(set_bypass_pwup, SET_BYPASS_PWUP, if_index, bypass_mode); } -int get_bypass_pwup(int if_index) +static int get_bypass_pwup(int if_index) { DO_BPLIB_GET_ARG_FN(get_bypass_pwup, GET_BYPASS_PWUP, if_index); } -int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set) +static int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set) { int data = ms_timeout, ret = 0; if (is_dev_sd(if_index)) @@ -268,7 +268,7 @@ int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set) return ret; } -int get_bypass_wd(int if_index, int *ms_timeout_set) +static int get_bypass_wd(int if_index, int *ms_timeout_set) { int *data = ms_timeout_set, ret = 0; if (is_dev_sd(if_index)) @@ -279,7 +279,7 @@ int get_bypass_wd(int if_index, int *ms_timeout_set) return ret; } -int get_wd_expire_time(int if_index, int *ms_time_left) +static int get_wd_expire_time(int if_index, int *ms_time_left) { int *data = ms_time_left, ret = 0; if (is_dev_sd(if_index)) @@ -293,144 +293,144 @@ int get_wd_expire_time(int if_index, int *ms_time_left) return ret; } -int reset_bypass_wd_timer(int if_index) +static int reset_bypass_wd_timer(int if_index) { DO_BPLIB_GET_ARG_FN(reset_bypass_wd_timer, RESET_BYPASS_WD_TIMER, if_index); } -int set_std_nic(int if_index, int bypass_mode) +static int set_std_nic(int if_index, int bypass_mode) { DO_BPLIB_SET_ARG_FN(set_std_nic, SET_STD_NIC, if_index, bypass_mode); } -int get_std_nic(int if_index) +static int get_std_nic(int if_index) { DO_BPLIB_GET_ARG_FN(get_std_nic, GET_STD_NIC, if_index); } -int set_tx(int if_index, int tx_state) +static int set_tx(int if_index, int tx_state) { DO_BPLIB_SET_ARG_FN(set_tx, SET_TX, if_index, tx_state); } -int get_tx(int if_index) +static int get_tx(int if_index) { DO_BPLIB_GET_ARG_FN(get_tx, GET_TX, if_index); } -int set_tap(int if_index, int tap_mode) +static int set_tap(int if_index, int tap_mode) { DO_BPLIB_SET_ARG_FN(set_tap, SET_TAP, if_index, tap_mode); } -int get_tap(int if_index) +static int get_tap(int if_index) { DO_BPLIB_GET_ARG_FN(get_tap, GET_TAP, if_index); } -int get_tap_change(int if_index) +static int get_tap_change(int if_index) { DO_BPLIB_GET_ARG_FN(get_tap_change, GET_TAP_CHANGE, if_index); } -int set_dis_tap(int if_index, int dis_tap) +static int set_dis_tap(int if_index, int dis_tap) { DO_BPLIB_SET_ARG_FN(set_dis_tap, SET_DIS_TAP, if_index, dis_tap); } -int get_dis_tap(int if_index) +static int get_dis_tap(int if_index) { DO_BPLIB_GET_ARG_FN(get_dis_tap, GET_DIS_TAP, if_index); } -int set_tap_pwup(int if_index, int tap_mode) +static int set_tap_pwup(int if_index, int tap_mode) { DO_BPLIB_SET_ARG_FN(set_tap_pwup, SET_TAP_PWUP, if_index, tap_mode); } -int get_tap_pwup(int if_index) +static int get_tap_pwup(int if_index) { DO_BPLIB_GET_ARG_FN(get_tap_pwup, GET_TAP_PWUP, if_index); } -int set_bp_disc(int if_index, int disc_mode) +static int set_bp_disc(int if_index, int disc_mode) { DO_BPLIB_SET_ARG_FN(set_bp_disc, SET_DISC, if_index, disc_mode); } -int get_bp_disc(int if_index) +static int get_bp_disc(int if_index) { DO_BPLIB_GET_ARG_FN(get_bp_disc, GET_DISC, if_index); } -int get_bp_disc_change(int if_index) +static int get_bp_disc_change(int if_index) { DO_BPLIB_GET_ARG_FN(get_bp_disc_change, GET_DISC_CHANGE, if_index); } -int set_bp_dis_disc(int if_index, int dis_disc) +static int set_bp_dis_disc(int if_index, int dis_disc) { DO_BPLIB_SET_ARG_FN(set_bp_dis_disc, SET_DIS_DISC, if_index, dis_disc); } -int get_bp_dis_disc(int if_index) +static int get_bp_dis_disc(int if_index) { DO_BPLIB_GET_ARG_FN(get_bp_dis_disc, GET_DIS_DISC, if_index); } -int set_bp_disc_pwup(int if_index, int disc_mode) +static int set_bp_disc_pwup(int if_index, int disc_mode) { DO_BPLIB_SET_ARG_FN(set_bp_disc_pwup, SET_DISC_PWUP, if_index, disc_mode); } -int get_bp_disc_pwup(int if_index) +static int get_bp_disc_pwup(int if_index) { DO_BPLIB_GET_ARG_FN(get_bp_disc_pwup, GET_DISC_PWUP, if_index); } -int set_wd_exp_mode(int if_index, int mode) +static int set_wd_exp_mode(int if_index, int mode) { DO_BPLIB_SET_ARG_FN(set_wd_exp_mode, SET_WD_EXP_MODE, if_index, mode); } -int get_wd_exp_mode(int if_index) +static int get_wd_exp_mode(int if_index) { DO_BPLIB_GET_ARG_FN(get_wd_exp_mode, GET_WD_EXP_MODE, if_index); } -int set_wd_autoreset(int if_index, int time) +static int set_wd_autoreset(int if_index, int time) { DO_BPLIB_SET_ARG_FN(set_wd_autoreset, SET_WD_AUTORESET, if_index, time); } -int get_wd_autoreset(int if_index) +static int get_wd_autoreset(int if_index) { DO_BPLIB_GET_ARG_FN(get_wd_autoreset, GET_WD_AUTORESET, if_index); } -int set_tpl(int if_index, int tpl_mode) +static int set_tpl(int if_index, int tpl_mode) { DO_BPLIB_SET_ARG_FN(set_tpl, SET_TPL, if_index, tpl_mode); } -int get_tpl(int if_index) +static int get_tpl(int if_index) { DO_BPLIB_GET_ARG_FN(get_tpl, GET_TPL, if_index); } -int set_bp_hw_reset(int if_index, int mode) +static int set_bp_hw_reset(int if_index, int mode) { DO_BPLIB_SET_ARG_FN(set_tpl, SET_BP_HW_RESET, if_index, mode); } -int get_bp_hw_reset(int if_index) +static int get_bp_hw_reset(int if_index) { DO_BPLIB_GET_ARG_FN(get_tpl, GET_BP_HW_RESET, if_index); } -int get_bypass_info(int if_index, struct bp_info *bp_info) +static int get_bypass_info(int if_index, struct bp_info *bp_info) { int ret = 0; if (is_dev_sd(if_index)) { @@ -468,14 +468,14 @@ int get_bypass_info(int if_index, struct bp_info *bp_info) return ret; } -int init_lib_module() +int init_lib_module(void) { printk(VERSION); return 0; } -void cleanup_lib_module() +void cleanup_lib_module(void) { } -- cgit From f54ab7d916ee4504e91b552c38cfa2f82df3718d Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghiu Date: Tue, 26 Feb 2013 16:53:16 +0200 Subject: Staging: silicom: bp_mod: Removed trailing whitespaces Fixed coding style issue. Signed-off-by: Alexandru Gheorghiu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_mod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 58c5f5cf4cec..61a912debb96 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -6983,7 +6983,7 @@ static void __exit bypass_cleanup_module(void) /* spin_lock_irqsave(&bpvm_lock, flags); rcu_read_lock(); */ bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); -/* spin_unlock_irqrestore(&bpvm_lock, flags); +/* spin_unlock_irqrestore(&bpvm_lock, flags); rcu_read_unlock(); */ #endif remove_bypass_wd_auto(&bpctl_dev_arr[i]); @@ -7006,7 +7006,7 @@ static void __exit bypass_cleanup_module(void) kfree(bpctl_dev_arr); /* -* Unregister the device +* Unregister the device */ unregister_chrdev(major_num, DEVICE_NAME); } -- cgit From d39625c4eb3349569f0959a4488e71faa927ec4a Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Thu, 7 Mar 2013 01:44:54 +0530 Subject: staging: silicom: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_mod.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 61a912debb96..45a222723207 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -6995,15 +6995,13 @@ static void __exit bypass_cleanup_module(void) /* unmap all devices */ for (i = 0; i < device_num; i++) { #ifdef BP_SELF_TEST - if (bpctl_dev_arr[i].bp_tx_data) - kfree(bpctl_dev_arr[i].bp_tx_data); + kfree(bpctl_dev_arr[i].bp_tx_data); #endif iounmap((void *)(bpctl_dev_arr[i].mem_map)); } /* free all devices space */ - if (bpctl_dev_arr) - kfree(bpctl_dev_arr); + kfree(bpctl_dev_arr); /* * Unregister the device -- cgit From cbb86718ac50eaf56e98a14760d717e6c73b345e Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:25 +0100 Subject: staging: usbip: userspace: libsrc: fix indention This patch fixes the following checkpatch warning: -ERROR: code indent should use tabs where possible -WARNING: suspect code indent for conditional statements Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/names.c | 380 ++++++++++----------- .../staging/usbip/userspace/libsrc/vhci_driver.c | 20 +- 2 files changed, 200 insertions(+), 200 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index b4de18b4bb9c..448d09d1d821 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c @@ -22,8 +22,8 @@ */ /* - * Copyright (C) 2005 Takahiro Hirofuchi - * - names_deinit() is added. + * Copyright (C) 2005 Takahiro Hirofuchi + * - names_deinit() is added. */ /*****************************************************************************/ @@ -82,9 +82,9 @@ struct audioterminal { }; struct genericstrtable { - struct genericstrtable *next; - unsigned int num; - char name[1]; + struct genericstrtable *next; + unsigned int num; + char name[1]; }; /* ---------------------------------------------------------------------- */ @@ -124,12 +124,12 @@ static struct genericstrtable *countrycodes[HASHSZ] = { NULL, }; static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index) { - struct genericstrtable *h; + struct genericstrtable *h; - for (h = t[hashnum(index)]; h; h = h->next) - if (h->num == index) - return h->name; - return NULL; + for (h = t[hashnum(index)]; h; h = h->next) + if (h->num == index) + return h->name; + return NULL; } const char *names_hid(u_int8_t hidd) @@ -409,20 +409,20 @@ static int new_audioterminal(const char *name, u_int16_t termt) static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index) { - struct genericstrtable *g; + struct genericstrtable *g; unsigned int h = hashnum(index); - for (g = t[h]; g; g = g->next) - if (g->num == index) - return -1; - g = my_malloc(sizeof(struct genericstrtable) + strlen(name)); - if (!g) - return -1; - strcpy(g->name, name); - g->num = index; - g->next = t[h]; - t[h] = g; - return 0; + for (g = t[h]; g; g = g->next) + if (g->num == index) + return -1; + g = my_malloc(sizeof(struct genericstrtable) + strlen(name)); + if (!g) + return -1; + strcpy(g->name, name); + g->num = index; + g->next = t[h]; + t[h] = g; + return 0; } static int new_hid(const char *name, u_int8_t hidd) @@ -485,92 +485,92 @@ static void parse(FILE *f) if (buf[0] == '#' || !buf[0]) continue; cp = buf; - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' && - buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') { - cp = buf + 8; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); - continue; - } - if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { - cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); - continue; - } - if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { - cp = buf + 5; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); - continue; - } - if (new_bias(cp, u)) - fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') { - cp = buf+2; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); - continue; - } - if (new_langid(cp, u)) - fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp); - DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp)); - lasthut = lastclass = lastvendor = lastsubclass = -1; - lastlang = u; - continue; - } + if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' && + buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') { + cp = buf + 8; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); + continue; + } + if (new_physdes(cp, u)) + fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp); + DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp)); + continue; + + } + if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { + cp = buf + 4; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid PHY type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid PHY type at line %u\n", linectr); + continue; + } + if (new_physdes(cp, u)) + fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp); + DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp)); + continue; + + } + if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { + cp = buf + 5; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); + continue; + } + if (new_bias(cp, u)) + fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp); + DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp)); + continue; + + } + if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') { + cp = buf+2; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); + continue; + } + if (new_langid(cp, u)) + fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp); + DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp)); + lasthut = lastclass = lastvendor = lastsubclass = -1; + lastlang = u; + continue; + } if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') { /* class spec */ cp = buf+2; @@ -617,24 +617,24 @@ static void parse(FILE *f) } if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) { /* HID Descriptor bCountryCode */ - cp = buf+3; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 10); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); - continue; - } - if (new_countrycode(cp, u)) - fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp); - DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp)); - continue; + cp = buf+3; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid HID country code at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 10); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid HID country code at line %u\n", linectr); + continue; + } + if (new_countrycode(cp, u)) + fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp); + DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp)); + continue; } if (isxdigit(*cp)) { /* vendor */ @@ -680,10 +680,10 @@ static void parse(FILE *f) continue; } if (lastlang != -1) { - if (new_langid(cp, lastlang+(u<<10))) - fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr); - continue; - } + if (new_langid(cp, lastlang+(u<<10))) + fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr); + continue; + } fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr); continue; } @@ -707,70 +707,70 @@ static void parse(FILE *f) } if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') { cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); - continue; - } - if (new_hid(cp, u)) - fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp)); - continue; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid HID type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid HID type at line %u\n", linectr); + continue; + } + if (new_hid(cp, u)) + fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp); + DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp)); + continue; } - if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { - cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); - continue; - } - if (new_huts(cp, u)) - fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp); + if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { + cp = buf + 4; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid HUT type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid HUT type at line %u\n", linectr); + continue; + } + if (new_huts(cp, u)) + fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp); lastlang = lastclass = lastvendor = lastsubclass = -1; lasthut = u; - DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'R' && buf[1] == ' ') { - cp = buf + 2; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); - continue; - } - if (new_reporttag(cp, u)) - fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'V' && buf[1] == 'T') { + DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp)); + continue; + + } + if (buf[0] == 'R' && buf[1] == ' ') { + cp = buf + 2; + while (isspace(*cp)) + cp++; + if (!isxdigit(*cp)) { + fprintf(stderr, "Invalid Report type at line %u\n", linectr); + continue; + } + u = strtoul(cp, &cp, 16); + while (isspace(*cp)) + cp++; + if (!*cp) { + fprintf(stderr, "Invalid Report type at line %u\n", linectr); + continue; + } + if (new_reporttag(cp, u)) + fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp); + DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp)); + continue; + + } + if (buf[0] == 'V' && buf[1] == 'T') { /* add here */ continue; } diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index 0958ba53e94a..7a5da58f72dd 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -289,25 +289,25 @@ static int get_nports(void) static int get_hc_busid(char *sysfs_mntpath, char *hc_busid) { - struct sysfs_driver *sdriver; - char sdriver_path[SYSFS_PATH_MAX]; + struct sysfs_driver *sdriver; + char sdriver_path[SYSFS_PATH_MAX]; struct sysfs_device *hc_dev; struct dlist *hc_devs; int found = 0; - 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); + 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) { + sdriver = sysfs_open_driver_path(sdriver_path); + if (!sdriver) { dbg("sysfs_open_driver_path failed: %s", sdriver_path); - dbg("make sure " USBIP_CORE_MOD_NAME ".ko and " + dbg("make sure " USBIP_CORE_MOD_NAME ".ko and " USBIP_VHCI_DRV_NAME ".ko are loaded!"); - return -1; - } + return -1; + } hc_devs = sysfs_get_driver_devices(sdriver); if (!hc_devs) { -- cgit From 5af7746f47cef58e1d2499e7a79fe3306c129269 Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:26 +0100 Subject: staging: usbip: userspace: libsrc: do not init static/globals to 0 This patch fixes the following checkpatch errors: -ERROR: do not initialise statics to 0 or NULL -ERROR: do not initialise globals to 0 or NULL Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/names.c | 2 +- drivers/staging/usbip/userspace/libsrc/usbip_common.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index 448d09d1d821..8fe932d996be 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c @@ -246,7 +246,7 @@ struct pool { void *mem; }; -static struct pool *pool_head = NULL; +static struct pool *pool_head; static void *my_malloc(size_t size) { diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c index 154b4b1103ec..98dc3df5e1a6 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c @@ -8,9 +8,9 @@ #undef PROGNAME #define PROGNAME "libusbip" -int usbip_use_syslog = 0; -int usbip_use_stderr = 0; -int usbip_use_debug = 0; +int usbip_use_syslog; +int usbip_use_stderr; +int usbip_use_debug; struct speed_string { int num; -- cgit From b8ab0f2beeb9e0fc500078aa60c93131a0f2ffbf Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:27 +0100 Subject: staging: usbip: userspace: libsrc: spaces required around that '=' This patch fixes the following checkpatch error: -ERROR: spaces required around that '=' Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/names.c | 2 +- drivers/staging/usbip/userspace/libsrc/usbip_common.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index 8fe932d996be..8ee370bb9b90 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c @@ -472,7 +472,7 @@ static void parse(FILE *f) { char buf[512], *cp; unsigned int linectr = 0; - int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut=-1, lastlang=-1; + int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut = -1, lastlang = -1; unsigned int u; while (fgets(buf, sizeof(buf), f)) { diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c index 98dc3df5e1a6..b55df81a24f5 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c @@ -44,7 +44,7 @@ static struct portst_string portst_strings[] = { const char *usbip_status_string(int32_t status) { - for (int i=0; portst_strings[i].desc != NULL; i++) + for (int i = 0; portst_strings[i].desc != NULL; i++) if (portst_strings[i].num == status) return portst_strings[i].desc; @@ -53,7 +53,7 @@ const char *usbip_status_string(int32_t status) const char *usbip_speed_string(int num) { - for (int i=0; speed_strings[i].speed != NULL; i++) + for (int i = 0; speed_strings[i].speed != NULL; i++) if (speed_strings[i].num == num) return speed_strings[i].desc; @@ -172,7 +172,7 @@ int read_attr_speed(struct sysfs_device *dev) err: sysfs_close_attribute(attr); - for (int i=0; speed_strings[i].speed != NULL; i++) { + for (int i = 0; speed_strings[i].speed != NULL; i++) { if (!strcmp(speed, speed_strings[i].speed)) return speed_strings[i].num; } -- cgit From 71bd5b76720493b60e9ba61e1aa4146f2edc22cd Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:28 +0100 Subject: staging: usbip: userspace: libsrc: (foo*) should be (foo *) This patch fixes the following checkpatch error: -ERROR: "(foo*)" should be "(foo *)" Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/vhci_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index 7a5da58f72dd..b9c6e2abb466 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -36,7 +36,7 @@ static struct usbip_imported_device *imported_device_init(struct usbip_imported_ goto err; memcpy(new_cdev, cdev, sizeof(*new_cdev)); - dlist_unshift(idev->cdev_list, (void*) new_cdev); + dlist_unshift(idev->cdev_list, (void *) new_cdev); } } -- cgit From 9db91e1b4cdf23c28f7f932376bcdeafbd1aee28 Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:29 +0100 Subject: staging: usbip: userspace: libsrc: replaced lines over 80 characters This patch fixes some of the following checkpatch warnings: -WARNING: line over 80 characters We did not split format strings for readability. Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/names.c | 215 ++++++++++++++------- drivers/staging/usbip/userspace/libsrc/names.h | 3 +- .../staging/usbip/userspace/libsrc/usbip_common.c | 16 +- .../staging/usbip/userspace/libsrc/usbip_common.h | 9 +- .../staging/usbip/userspace/libsrc/vhci_driver.c | 18 +- 5 files changed, 175 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index 8ee370bb9b90..a66f5391e5dc 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c @@ -122,7 +122,8 @@ static struct genericstrtable *countrycodes[HASHSZ] = { NULL, }; /* ---------------------------------------------------------------------- */ -static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index) +static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], + unsigned int index) { struct genericstrtable *h; @@ -216,13 +217,16 @@ const char *names_subclass(u_int8_t classid, u_int8_t subclassid) return NULL; } -const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) +const char *names_protocol(u_int8_t classid, u_int8_t subclassid, + u_int8_t protocolid) { struct protocol *p; - p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)]; + p = protocols[hashnum((classid << 16) | (subclassid << 8) + | protocolid)]; for (; p; p = p->next) - if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid) + if (p->classid == classid && p->subclassid == subclassid && + p->protocolid == protocolid) return p->name; return NULL; } @@ -308,7 +312,8 @@ static int new_vendor(const char *name, u_int16_t vendorid) return 0; } -static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid) +static int new_product(const char *name, u_int16_t vendorid, + u_int16_t productid) { struct product *p; unsigned int h = hashnum((vendorid << 16) | productid); @@ -367,14 +372,17 @@ static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid) return 0; } -static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) +static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, + u_int8_t protocolid) { struct protocol *p; - unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid); + unsigned int h = hashnum((classid << 16) | (subclassid << 8) + | protocolid); p = protocols[h]; for (; p; p = p->next) - if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid) + if (p->classid == classid && p->subclassid == subclassid + && p->protocolid == protocolid) return -1; p = my_malloc(sizeof(struct protocol) + strlen(name)); if (!p) @@ -407,7 +415,8 @@ static int new_audioterminal(const char *name, u_int16_t termt) return 0; } -static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index) +static int new_genericstrtable(struct genericstrtable *t[HASHSZ], + const char *name, unsigned int index) { struct genericstrtable *g; unsigned int h = hashnum(index); @@ -472,7 +481,11 @@ static void parse(FILE *f) { char buf[512], *cp; unsigned int linectr = 0; - int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut = -1, lastlang = -1; + int lastvendor = -1; + int lastclass = -1; + int lastsubclass = -1; + int lasthut = -1; + int lastlang = -1; unsigned int u; while (fgets(buf, sizeof(buf), f)) { @@ -485,67 +498,82 @@ static void parse(FILE *f) if (buf[0] == '#' || !buf[0]) continue; cp = buf; - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' && - buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') { + if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' + && buf[3] == 'S' && buf[4] == 'D' && buf[5] == 'E' + && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') { cp = buf + 8; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); + fprintf(stderr, "Invalid Physdes type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); + fprintf(stderr, "Invalid Physdes type at line %u\n", + linectr); continue; } if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u physdes type %02x %s\n", linectr, + u, cp)); continue; } - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { + if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' + && /*isspace(buf[3])*/ buf[3] == ' ') { cp = buf + 4; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); + fprintf(stderr, "Invalid PHY type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); + fprintf(stderr, "Invalid PHY type at line %u\n", + linectr); continue; } if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u PHY type %02x %s\n", linectr, u, + cp)); continue; } - if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { + if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' + && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { cp = buf + 5; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); + fprintf(stderr, "Invalid BIAS type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); + fprintf(stderr, "Invalid BIAS type at line %u\n", + linectr); continue; } if (new_bias(cp, u)) - fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, + cp)); continue; } @@ -554,19 +582,23 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); + fprintf(stderr, "Invalid LANGID spec at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); + fprintf(stderr, "Invalid LANGID spec at line %u\n", + linectr); continue; } if (new_langid(cp, u)) - fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp); - DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u LANGID %02x %s\n", linectr, u, + cp)); lasthut = lastclass = lastvendor = lastsubclass = -1; lastlang = u; continue; @@ -577,18 +609,21 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid class spec at line %u\n", linectr); + fprintf(stderr, "Invalid class spec at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid class spec at line %u\n", linectr); + fprintf(stderr, "Invalid class spec at line %u\n", + linectr); continue; } if (new_class(cp, u)) - fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp); + fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", + linectr, u, cp); DBG(printf("line %5u class %02x %s\n", linectr, u, cp)); lasthut = lastlang = lastvendor = lastsubclass = -1; lastclass = u; @@ -600,40 +635,49 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr); + fprintf(stderr, "Invalid audio terminal type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr); + fprintf(stderr, "Invalid audio terminal type at line %u\n", + linectr); continue; } if (new_audioterminal(cp, u)) - fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u audio terminal type %02x %s\n", + linectr, u, cp)); continue; } - if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) { + if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' + && isspace(buf[3])) { /* HID Descriptor bCountryCode */ cp = buf+3; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); + fprintf(stderr, "Invalid HID country code at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 10); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); + fprintf(stderr, "Invalid HID country code at line %u\n", + linectr); continue; } if (new_countrycode(cp, u)) - fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp); - DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", + linectr, u, cp); + DBG(printf("line %5u keyboard country code %02u %s\n", + linectr, u, cp)); continue; } if (isxdigit(*cp)) { @@ -642,12 +686,15 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid vendor spec at line %u\n", linectr); + fprintf(stderr, "Invalid vendor spec at line %u\n", + linectr); continue; } if (new_vendor(cp, u)) - fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp); - DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u vendor %04x %s\n", linectr, u, + cp)); lastvendor = u; lasthut = lastlang = lastclass = lastsubclass = -1; continue; @@ -658,33 +705,41 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr); + fprintf(stderr, "Invalid product/subclass spec at line %u\n", + linectr); continue; } if (lastvendor != -1) { if (new_product(cp, lastvendor, u)) - fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp); - DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp)); + fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", + linectr, lastvendor, u, cp); + DBG(printf("line %5u product %04x:%04x %s\n", + linectr, lastvendor, u, cp)); continue; } if (lastclass != -1) { if (new_subclass(cp, lastclass, u)) - fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp); - DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp)); + fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", + linectr, lastclass, u, cp); + DBG(printf("line %5u subclass %02x:%02x %s\n", + linectr, lastclass, u, cp)); lastsubclass = u; continue; } if (lasthut != -1) { if (new_hutus(cp, (lasthut << 16)+u)) - fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr); + fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", + linectr); continue; } if (lastlang != -1) { if (new_langid(cp, lastlang+(u<<10))) - fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr); + fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", + linectr); continue; } - fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr); + fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", + linectr); continue; } if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) { @@ -693,59 +748,73 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid protocol spec at line %u\n", linectr); + fprintf(stderr, "Invalid protocol spec at line %u\n", + linectr); continue; } if (lastclass != -1 && lastsubclass != -1) { if (new_protocol(cp, lastclass, lastsubclass, u)) - fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp); - DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp)); + fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", + linectr, lastclass, lastsubclass, u, cp); + DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", + linectr, lastclass, lastsubclass, u, cp)); continue; } - fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr); + fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", + linectr); continue; } - if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') { + if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' + && /*isspace(buf[3])*/ buf[3] == ' ') { cp = buf + 4; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); + fprintf(stderr, "Invalid HID type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); + fprintf(stderr, "Invalid HID type at line %u\n", + linectr); continue; } if (new_hid(cp, u)) - fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u HID type %02x %s\n", linectr, u, + cp)); continue; } - if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { + if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' + && /*isspace(buf[3])*/ buf[3] == ' ') { cp = buf + 4; while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); + fprintf(stderr, "Invalid HUT type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); + fprintf(stderr, "Invalid HUT type at line %u\n", + linectr); continue; } if (new_huts(cp, u)) - fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp); + fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", + linectr, u, cp); lastlang = lastclass = lastvendor = lastsubclass = -1; lasthut = u; - DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp)); + DBG(printf("line %5u HUT type %02x %s\n", linectr, u, + cp)); continue; } @@ -754,19 +823,23 @@ static void parse(FILE *f) while (isspace(*cp)) cp++; if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); + fprintf(stderr, "Invalid Report type at line %u\n", + linectr); continue; } u = strtoul(cp, &cp, 16); while (isspace(*cp)) cp++; if (!*cp) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); + fprintf(stderr, "Invalid Report type at line %u\n", + linectr); continue; } if (new_reporttag(cp, u)) - fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp)); + fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", + linectr, u, cp); + DBG(printf("line %5u Report type %02x %s\n", linectr, + u, cp)); continue; } diff --git a/drivers/staging/usbip/userspace/libsrc/names.h b/drivers/staging/usbip/userspace/libsrc/names.h index 3a269fecc02a..28dafc59f5b0 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.h +++ b/drivers/staging/usbip/userspace/libsrc/names.h @@ -40,7 +40,8 @@ extern const char *names_vendor(u_int16_t vendorid); extern const char *names_product(u_int16_t vendorid, u_int16_t productid); extern const char *names_class(u_int8_t classid); extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid); -extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid); +extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, + u_int8_t protocolid); extern const char *names_audioterminal(u_int16_t termt); extern const char *names_hid(u_int8_t hidd); extern const char *names_reporttag(u_int8_t rt); diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c index b55df81a24f5..17e08e022c00 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c @@ -109,7 +109,8 @@ void dump_usb_device(struct usbip_usb_device *udev) } -int read_attr_value(struct sysfs_device *dev, const char *name, const char *format) +int read_attr_value(struct sysfs_device *dev, const char *name, + const char *format) { char attrpath[SYSFS_PATH_MAX]; struct sysfs_attribute *attr; @@ -180,8 +181,11 @@ err: return USB_SPEED_UNKNOWN; } -#define READ_ATTR(object, type, dev, name, format)\ - do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0) +#define READ_ATTR(object, type, dev, name, format) \ + do { \ + (object)->name = (type) read_attr_value(dev, to_string(name), \ + format); \ + } while (0) int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev) @@ -245,7 +249,8 @@ void usbip_names_free() names_free(); } -void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product) +void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, + uint16_t product) { const char *prod, *vend; @@ -261,7 +266,8 @@ void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product); } -void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol) +void usbip_names_get_class(char *buff, size_t size, uint8_t class, + uint8_t subclass, uint8_t protocol) { const char *c, *s, *p; diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h index eedefbd12ea6..0b2f3705ff6f 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h @@ -132,7 +132,8 @@ struct usbip_usb_device { 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_attr_value(struct sysfs_device *dev, const char *name, + const char *format); int read_usb_interface(struct usbip_usb_device *udev, int i, struct usbip_usb_interface *uinf); @@ -141,7 +142,9 @@ const char *usbip_status_string(int32_t status); int usbip_names_init(char *); 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); +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 /* __USBIP_COMMON_H */ diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index b9c6e2abb466..25e62e9f0a33 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -10,7 +10,8 @@ struct usbip_vhci_driver *vhci_driver; -static struct usbip_imported_device *imported_device_init(struct usbip_imported_device *idev, char *busid) +static struct usbip_imported_device * +imported_device_init(struct usbip_imported_device *idev, char *busid) { struct sysfs_device *sudev; @@ -29,8 +30,10 @@ static struct usbip_imported_device *imported_device_init(struct usbip_imported_ 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 */ + /* + * alloc and copy because dlist is linked + * from only one list + */ new_cdev = calloc(1, sizeof(*new_cdev)); if (!new_cdev) goto err; @@ -101,7 +104,8 @@ static int parse_status(char *value) return -1; } - if (idev->status != VDEV_ST_NULL && idev->status != VDEV_ST_NOTASSIGNED) { + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { idev = imported_device_init(idev, lbusid); if (!idev) { dbg("imported_device_init failed"); @@ -126,8 +130,10 @@ static int parse_status(char *value) static int check_usbip_device(struct sysfs_class_device *cdev) { - 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 */ + /* /sys/class/video4linux/video0/device */ + char class_path[SYSFS_PATH_MAX]; + /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */ + char dev_path[SYSFS_PATH_MAX]; int ret; struct usbip_class_device *usbip_cdev; -- cgit From 6f19a2b1c386d6ef75bcfebf5c1a68d28658d62e Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:30 +0100 Subject: staging: usbip: userspace: libsrc: removed assignments in if conditions This patch fixes the following checkpatch error: -ERROR: do not use assignment in if condition Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/names.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index a66f5391e5dc..3b151dff85a6 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c @@ -491,9 +491,11 @@ static void parse(FILE *f) while (fgets(buf, sizeof(buf), f)) { linectr++; /* remove line ends */ - if ((cp = strchr(buf, 13))) + cp = strchr(buf, 13); + if (cp) *cp = 0; - if ((cp = strchr(buf, 10))) + cp = strchr(buf, 10); + if (cp) *cp = 0; if (buf[0] == '#' || !buf[0]) continue; @@ -857,9 +859,10 @@ int names_init(char *n) { FILE *f; - if (!(f = fopen(n, "r"))) { + f = fopen(n, "r"); + if (!f) return errno; - } + parse(f); fclose(f); return 0; -- cgit From ba0edc23df90332e4360d5116bcf3ea333e5de73 Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:31 +0100 Subject: staging: usbip: userspace: libsrc: added missing space This patch fixes the following checkpatch warning: -WARNING: missing space after enum definition Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/usbip_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h index 0b2f3705ff6f..938ad1c36947 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h @@ -84,7 +84,7 @@ enum usb_device_speed { }; /* FIXME: how to sync with drivers/usbip_common.h ? */ -enum usbip_device_status{ +enum usbip_device_status { /* sdev is available. */ SDEV_ST_AVAILABLE = 0x01, /* sdev is now used. */ -- cgit From c46cb54db3a01223bdd457ead25d4a3582c0babe Mon Sep 17 00:00:00 2001 From: Stefan Reif Date: Fri, 22 Feb 2013 12:13:32 +0100 Subject: staging: usbip: remove unnecessary braces This patch fixes the following checkpatch warning: -WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Stefan Reif Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index f1ca08478da8..d7974cb2cc6f 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -956,11 +956,10 @@ static int vhci_bus_resume(struct usb_hcd *hcd) dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock(&vhci->lock); - if (!HCD_HW_ACCESSIBLE(hcd)) { + if (!HCD_HW_ACCESSIBLE(hcd)) rc = -ESHUTDOWN; - } else { + else hcd->state = HC_STATE_RUNNING; - } spin_unlock(&vhci->lock); return rc; -- cgit From 5037307d51636e7c784ceef8aa23e0c074d429a7 Mon Sep 17 00:00:00 2001 From: Stefan Reif Date: Fri, 22 Feb 2013 12:13:33 +0100 Subject: staging: usbip: userspace: fix whitespace errors This patch fixes the following checkpatch errors: -ERROR: space required after that ',' -ERROR: spaces required around that '=' -ERROR: space prohibited before that close parenthesis -WARNING: please, no space before tabs Signed-off-by: Stefan Reif Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/src/usbip_detach.c | 2 +- drivers/staging/usbip/userspace/src/usbip_network.c | 2 +- drivers/staging/usbip/userspace/src/usbip_network.h | 4 ++-- drivers/staging/usbip/userspace/src/usbipd.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c index dac5f065755a..13308df613a2 100644 --- a/drivers/staging/usbip/userspace/src/usbip_detach.c +++ b/drivers/staging/usbip/userspace/src/usbip_detach.c @@ -49,7 +49,7 @@ static int detach_port(char *port) uint8_t portnum; char path[PATH_MAX+1]; - for (unsigned int i=0; i < strlen(port); i++) + for (unsigned int i = 0; i < strlen(port); i++) if (!isdigit(port[i])) { err("invalid port %s", port); return -1; diff --git a/drivers/staging/usbip/userspace/src/usbip_network.c b/drivers/staging/usbip/userspace/src/usbip_network.c index 1a84dd37e125..4cb76e5d71c8 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.c +++ b/drivers/staging/usbip/userspace/src/usbip_network.c @@ -56,7 +56,7 @@ void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev) { usbip_net_pack_uint32_t(pack, &udev->busnum); usbip_net_pack_uint32_t(pack, &udev->devnum); - usbip_net_pack_uint32_t(pack, &udev->speed ); + usbip_net_pack_uint32_t(pack, &udev->speed); usbip_net_pack_uint16_t(pack, &udev->idVendor); usbip_net_pack_uint16_t(pack, &udev->idProduct); diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/drivers/staging/usbip/userspace/src/usbip_network.h index 2d1e070fb7b8..1bbefc993fb1 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.h +++ b/drivers/staging/usbip/userspace/src/usbip_network.h @@ -35,8 +35,8 @@ struct op_common { #define PACK_OP_COMMON(pack, op_common) do {\ 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 );\ + usbip_net_pack_uint16_t(pack, &(op_common)->code);\ + usbip_net_pack_uint32_t(pack, &(op_common)->status);\ } while (0) /* ---------------------------------------------------------------------- */ diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c index 34760cc1d10e..cc3be17b9e24 100644 --- a/drivers/staging/usbip/userspace/src/usbipd.c +++ b/drivers/staging/usbip/userspace/src/usbipd.c @@ -60,7 +60,7 @@ static const char usbipd_help_string[] = " -d, --debug \n" " Print debugging information. \n" " \n" - " -h, --help \n" + " -h, --help \n" " Print this help. \n" " \n" " -v, --version \n" @@ -446,7 +446,7 @@ static int do_standalone_mode(int daemonize) } if (daemonize) { - if (daemon(0,0) < 0) { + if (daemon(0, 0) < 0) { err("daemonizing failed: %s", strerror(errno)); return -1; } -- cgit From 8c4e58348b79d826076b7062ead4b9d828773a7f Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Fri, 22 Feb 2013 12:13:34 +0100 Subject: staging: usbip: removed lines over 80 characters This patch fixes the following checkpatch warning: -WARNING: line over 80 characters Signed-off-by: Kurt Kanzenbach Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_dev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 67556acd1514..0a70b8ea9209 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -114,8 +114,10 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, spin_unlock_irq(&sdev->ud.lock); - sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, "stub_rx"); - sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, "stub_tx"); + sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, + "stub_rx"); + sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, + "stub_tx"); spin_lock_irq(&sdev->ud.lock); sdev->ud.status = SDEV_ST_USED; -- cgit From c19e94613eda688c11973858d11597179842f4c2 Mon Sep 17 00:00:00 2001 From: Laurent Navet Date: Mon, 25 Feb 2013 14:08:49 +0100 Subject: staging: line6: pod.c: fix checkpatch warning - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Laurent Navet Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pod.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 74898c3c9f90..699b21725062 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -148,9 +148,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod) buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) { return; } - if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0) { + if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0) return; - } if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) { short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | -- cgit From a0cdd2e4a96a253c83e8d7856e39b9807805c6c4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 27 Feb 2013 08:12:06 +0300 Subject: wlan-ng: clean up prism2sta_inf_chinforesults() This function is ugly because it hits against the 80 character limit. This patch does several things to clean it up. 1) Introduces "result" instead of inf->info.chinforesult.result[n]. 2) Reverses the ".scanchannels & (1 << i)" so everthing can be pulled in one indent level. 3) Use "chan" instead of "channel". 4) Tweaks the line breaks to the call to pr_debug(). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2sta.c | 48 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 8d2277bb898f..dc221f2ad227 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1160,30 +1160,30 @@ static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, le16_to_cpu(inf->info.chinforesult.scanchannels); for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { - if (hw->channel_info.results.scanchannels & (1 << i)) { - int channel = - le16_to_cpu(inf->info.chinforesult.result[n].chid) - - 1; - hfa384x_ChInfoResultSub_t *chinforesult = - &hw->channel_info.results.result[channel]; - chinforesult->chid = channel; - chinforesult->anl = - le16_to_cpu(inf->info.chinforesult.result[n].anl); - chinforesult->pnl = - le16_to_cpu(inf->info.chinforesult.result[n].pnl); - chinforesult->active = - le16_to_cpu(inf->info.chinforesult.result[n]. - active); - pr_debug - ("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", - channel + 1, - chinforesult-> - active & HFA384x_CHINFORESULT_BSSACTIVE ? "signal" - : "noise", chinforesult->anl, chinforesult->pnl, - chinforesult-> - active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0); - n++; - } + hfa384x_ChInfoResultSub_t *result; + hfa384x_ChInfoResultSub_t *chinforesult; + int chan; + + if (!(hw->channel_info.results.scanchannels & (1 << i))) + continue; + + result = &inf->info.chinforesult.result[n]; + chan = le16_to_cpu(result->chid) - 1; + + chinforesult = &hw->channel_info.results.result[chan]; + chinforesult->chid = chan; + chinforesult->anl = le16_to_cpu(result->anl); + chinforesult->pnl = le16_to_cpu(result->pnl); + chinforesult->active = le16_to_cpu(result->active); + + pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", + chan + 1, + (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) + ? "signal" : "noise", + chinforesult->anl, chinforesult->pnl, + (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) + ? 1 : 0); + n++; } atomic_set(&hw->channel_info.done, 2); -- cgit From 72c1c06d91c54beee35613434a5efdd7e8909302 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 27 Feb 2013 08:13:45 +0300 Subject: wlan-ng: add a bounds check I'm not sure where these results come from, but it can't hurt to add a sanity check the array offset. The .results[] array on the next line has HFA384x_CHINFORESULT_MAX (16) elements. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2sta.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index dc221f2ad227..428a9be25010 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1170,6 +1170,9 @@ static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, result = &inf->info.chinforesult.result[n]; chan = le16_to_cpu(result->chid) - 1; + if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) + continue; + chinforesult = &hw->channel_info.results.result[chan]; chinforesult->chid = chan; chinforesult->anl = le16_to_cpu(result->anl); -- cgit From b3bf0e90f05f1addf86ec7237e59b8a096e64e49 Mon Sep 17 00:00:00 2001 From: Ruslan Ruslichenko Date: Tue, 26 Feb 2013 18:53:24 -0400 Subject: staging: omap-thermal: Add print when TSHUT temperature reached To indicate that board was shut down due to TSHUT temperature reached it is good to print some information message before shutting down. Signed-off-by: Ruslan Ruslichenko Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index dcc1448dbf8e..35b99158f989 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -133,6 +133,9 @@ static irqreturn_t talert_irq_handler(int irq, void *data) /* This is the Tshut handler. Call it only if HAS(TSHUT) is set */ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) { + pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n", + __func__); + orderly_poweroff(true); return IRQ_HANDLED; -- cgit From 6c9c1d66e44e84a0c2a3d543479c74c8b8a44cea Mon Sep 17 00:00:00 2001 From: Radhesh Fadnis Date: Tue, 26 Feb 2013 18:53:25 -0400 Subject: staging: omap-thermal: introduce clock feature flag The clock to Bandgap module is SW controlled on some version of OMAP silicon (OMAP44xx). But on OMAP54xx ES2.0 onwards this is HW-Auto controlled. Hence introduce a feature flag to use/not-to-use SW enable/disable of BG clock. Signed-off-by: Radhesh Fadnis Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 18 +++++++++++++----- drivers/staging/omap-thermal/omap-bandgap.h | 1 + drivers/staging/omap-thermal/omap4-thermal.c | 3 +++ drivers/staging/omap-thermal/omap5-thermal.c | 3 ++- 4 files changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 35b99158f989..80384edfd762 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -914,7 +914,9 @@ int omap_bandgap_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n"); bg_ptr->clk_rate = clk_rate; - clk_enable(bg_ptr->fclock); + if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) + clk_enable(bg_ptr->fclock); + mutex_init(&bg_ptr->bg_mutex); bg_ptr->dev = &pdev->dev; @@ -982,7 +984,8 @@ int omap_bandgap_probe(struct platform_device *pdev) return 0; disable_clk: - clk_disable(bg_ptr->fclock); + if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) + clk_disable(bg_ptr->fclock); put_clks: clk_put(bg_ptr->fclock); clk_put(bg_ptr->div_clk); @@ -1012,7 +1015,8 @@ int omap_bandgap_remove(struct platform_device *pdev) omap_bandgap_power(bg_ptr, false); - clk_disable(bg_ptr->fclock); + if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) + clk_disable(bg_ptr->fclock); clk_put(bg_ptr->fclock); clk_put(bg_ptr->div_clk); @@ -1109,7 +1113,9 @@ static int omap_bandgap_suspend(struct device *dev) err = omap_bandgap_save_ctxt(bg_ptr); omap_bandgap_power(bg_ptr, false); - clk_disable(bg_ptr->fclock); + + if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) + clk_disable(bg_ptr->fclock); return err; } @@ -1118,7 +1124,9 @@ static int omap_bandgap_resume(struct device *dev) { struct omap_bandgap *bg_ptr = dev_get_drvdata(dev); - clk_enable(bg_ptr->fclock); + if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) + clk_enable(bg_ptr->fclock); + omap_bandgap_power(bg_ptr, true); return omap_bandgap_restore_ctxt(bg_ptr); diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 2bb14bd7c6d9..85e1a2f4b4e5 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -384,6 +384,7 @@ struct omap_bandgap_data { #define OMAP_BANDGAP_FEATURE_MODE_CONFIG (1 << 3) #define OMAP_BANDGAP_FEATURE_COUNTER (1 << 4) #define OMAP_BANDGAP_FEATURE_POWER_SWITCH (1 << 5) +#define OMAP_BANDGAP_FEATURE_CLK_CTRL (1 << 6) #define OMAP_BANDGAP_HAS(b, f) \ ((b)->conf->features & OMAP_BANDGAP_FEATURE_ ## f) unsigned int features; diff --git a/drivers/staging/omap-thermal/omap4-thermal.c b/drivers/staging/omap-thermal/omap4-thermal.c index 04c02b6c0077..732c853174a2 100644 --- a/drivers/staging/omap-thermal/omap4-thermal.c +++ b/drivers/staging/omap-thermal/omap4-thermal.c @@ -69,6 +69,7 @@ omap4430_adc_to_temp[OMAP4430_ADC_END_VALUE - OMAP4430_ADC_START_VALUE + 1] = { /* OMAP4430 data */ const struct omap_bandgap_data omap4430_data = { .features = OMAP_BANDGAP_FEATURE_MODE_CONFIG | + OMAP_BANDGAP_FEATURE_CLK_CTRL | OMAP_BANDGAP_FEATURE_POWER_SWITCH, .fclock_name = "bandgap_fclk", .div_ck_name = "bandgap_fclk", @@ -207,6 +208,7 @@ const struct omap_bandgap_data omap4460_data = { OMAP_BANDGAP_FEATURE_TALERT | OMAP_BANDGAP_FEATURE_MODE_CONFIG | OMAP_BANDGAP_FEATURE_POWER_SWITCH | + OMAP_BANDGAP_FEATURE_CLK_CTRL | OMAP_BANDGAP_FEATURE_COUNTER, .fclock_name = "bandgap_ts_fclk", .div_ck_name = "div_ts_ck", @@ -236,6 +238,7 @@ const struct omap_bandgap_data omap4470_data = { OMAP_BANDGAP_FEATURE_TALERT | OMAP_BANDGAP_FEATURE_MODE_CONFIG | OMAP_BANDGAP_FEATURE_POWER_SWITCH | + OMAP_BANDGAP_FEATURE_CLK_CTRL | OMAP_BANDGAP_FEATURE_COUNTER, .fclock_name = "bandgap_ts_fclk", .div_ck_name = "div_ts_ck", diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 2f3a498dacd1..8fca21b88efd 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -260,7 +260,8 @@ const struct omap_bandgap_data omap5430_data = { .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | OMAP_BANDGAP_FEATURE_TALERT | OMAP_BANDGAP_FEATURE_MODE_CONFIG | - OMAP_BANDGAP_FEATURE_COUNTER, + OMAP_BANDGAP_FEATURE_COUNTER | + OMAP_BANDGAP_FEATURE_CLK_CTRL, .fclock_name = "ts_clk_div_ck", .div_ck_name = "ts_clk_div_ck", .conv_table = omap5430_adc_to_temp, -- cgit From 2cb4093ce2f6918f129c8820715612abe647bdd8 Mon Sep 17 00:00:00 2001 From: Radhesh Fadnis Date: Tue, 26 Feb 2013 18:53:26 -0400 Subject: staging: omap-thermal: update OMAP54xx conv_table This patch updates the ADC conversion table for OMAP5430 ES2.0 devices. Signed-off-by: Radhesh Fadnis Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 5 +- drivers/staging/omap-thermal/omap5-thermal.c | 170 ++++++++++++++++----------- 2 files changed, 105 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 85e1a2f4b4e5..a13e43adfcaa 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -210,9 +210,8 @@ #define OMAP5430_MPU_MIN_TEMP -40000 #define OMAP5430_MPU_MAX_TEMP 125000 #define OMAP5430_MPU_HYST_VAL 5000 -#define OMAP5430_ADC_START_VALUE 532 -#define OMAP5430_ADC_END_VALUE 934 - +#define OMAP5430_ADC_START_VALUE 540 +#define OMAP5430_ADC_END_VALUE 945 #define OMAP5430_GPU_TSHUT_HOT 915 #define OMAP5430_GPU_TSHUT_COLD 900 diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 8fca21b88efd..dfa0350f0432 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -187,73 +187,109 @@ static struct temp_sensor_data omap5430_core_temp_sensor_data = { .update_int2 = 2000, }; -static const int -omap5430_adc_to_temp[OMAP5430_ADC_END_VALUE - OMAP5430_ADC_START_VALUE + 1] = { - -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, - -38200, -37800, -37300, -36800, - -36400, -36000, -35600, -35200, -34800, -34300, -33800, -33400, -33000, - -32600, - -32200, -31800, -31300, -30800, -30400, -30000, -29600, -29200, -28700, - -28200, -27800, -27400, -27000, -26600, -26200, -25700, -25200, -24800, - -24400, -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000, - -20600, -20200, -19700, -19200, -9300, -18400, -18000, -17600, -17200, - -16700, -16200, -15800, -15400, -15000, -14600, -14200, -13700, -13200, - -12800, -12400, -12000, -11600, -11200, -10700, -10200, -9800, -9400, - -9000, - -8600, -8200, -7700, -7200, -6800, -6400, -6000, -5600, -5200, -4800, - -4300, - -3800, -3400, -3000, -2600, -2200, -1800, -1300, -800, -400, 0, 400, - 800, - 1200, 1600, 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, - 6400, 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10800, - 11100, - 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800, 15300, - 15800, - 16200, 16600, 17000, 17400, 17800, 18200, 18700, 19200, 19600, 20000, - 20400, - 20800, 21200, 21600, 22100, 22600, 23000, 23400, 23800, 24200, 24600, - 25000, - 25400, 25900, 26400, 26800, 27200, 27600, 28000, 28400, 28800, 29300, - 29800, - 30200, 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000, - 34400, - 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800, 38200, 38600, - 39000, - 39400, 39800, 40200, 40600, 41100, 41600, 42000, 42400, 42800, 43200, - 43600, - 44000, 44400, 44800, 45300, 45800, 46200, 46600, 47000, 47400, 47800, - 48200, - 48600, 49000, 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, - 52800, - 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600, 57000, - 57400, - 57800, 58200, 58700, 59200, 59600, 60000, 60400, 60800, 61200, 61600, - 62000, - 62400, 62800, 63300, 63800, 64200, 64600, 65000, 65400, 65800, 66200, - 66600, - 67000, 67400, 67800, 68200, 68700, 69200, 69600, 70000, 70400, 70800, - 71200, - 71600, 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400, - 75800, - 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, 79400, 79800, - 80300, - 80800, 81200, 81600, 82000, 82400, 82800, 83200, 83600, 84000, 84400, - 84800, - 85200, 85600, 86000, 86400, 86800, 87300, 87800, 88200, 88600, 89000, - 89400, - 89800, 90200, 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, - 93800, - 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600, 98000, - 98400, - 98800, 99200, 99600, 100000, 100400, 100800, 101200, 101600, 102000, - 102400, - 102800, 103200, 103600, 104000, 104400, 104800, 105200, 105600, 106100, - 106600, 107000, 107400, 107800, 108200, 108600, 109000, 109400, 109800, - 110200, 110600, 111000, 111400, 111800, 112200, 112600, 113000, 113400, - 113800, 114200, 114600, 115000, 115400, 115800, 116200, 116600, 117000, - 117400, 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600, - 121000, 121400, 121800, 122200, 122600, 123000, 123400, 123800, 124200, - 124600, 124900, 125000, 125000, 125000, 125000, +/* + * OMAP54xx ES2.0 : Temperature values in milli degree celsius + * ADC code values from 540 to 945 + */ +static int +omap5430_adc_to_temp[ + OMAP5430_ADC_END_VALUE - OMAP5430_ADC_START_VALUE + 1] = { + /* Index 540 - 549 */ + -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, + -37800, + /* Index 550 - 559 */ + -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800, + -33400, + /* Index 560 - 569 */ + -33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800, + -29400, + /* Index 570 - 579 */ + -29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400, + -25000, + /* Index 580 - 589 */ + -24600, -24200, -23800, -23400, -23000, -22600, -22200, -21600, -21400, + -21000, + /* Index 590 - 599 */ + -20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000, + -16600, + /* Index 600 - 609 */ + -16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000, + -12500, + /* Index 610 - 619 */ + -11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600, + -8200, + /* Index 620 - 629 */ + -7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, + /* Index 630 - 639 */ + -3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200, 200, + /* Index 640 - 649 */ + 600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900, 4500, + /* Index 650 - 659 */ + 5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200, 8600, + /* Index 660 - 669 */ + 9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200, 12700, + /* Index 670 - 679 */ + 13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600, 17000, + /* Index 680 - 689 */ + 17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600, 21100, + /* Index 690 - 699 */ + 21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000, 25400, + /* Index 700 - 709 */ + 25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000, 29400, + /* Index 710 - 719 */ + 29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400, 33800, + /* Index 720 - 729 */ + 34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400, 37800, + /* Index 730 - 739 */ + 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400, 41800, + /* Index 740 - 749 */ + 42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800, 46200, + /* Index 750 - 759 */ + 46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800, 50200, + /* Index 760 - 769 */ + 50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800, 54200, + /* Index 770 - 779 */ + 54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200, 58600, + /* Index 780 - 789 */ + 59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200, 62600, + /* Index 790 - 799 */ + 63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200, 66600, + /* Index 800 - 809 */ + 67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200, 70600, + /* Index 810 - 819 */ + 71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600, 75000, + /* Index 820 - 829 */ + 75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, + /* Index 830 - 839 */ + 79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600, 83000, + /* Index 840 - 849 */ + 83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600, 87000, + /* Index 850 - 859 */ + 87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600, 91000, + /* Index 860 - 869 */ + 91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600, 95000, + /* Index 870 - 879 */ + 95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000, 99400, + /* Index 880 - 889 */ + 99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000, + 103400, + /* Index 890 - 899 */ + 103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000, + 107400, + /* Index 900 - 909 */ + 107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, + 111400, + /* Index 910 - 919 */ + 111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000, + 115400, + /* Index 920 - 929 */ + 115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, + 119400, + /* Index 930 - 939 */ + 119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000, + 123400, + /* Index 940 - 945 */ + 123800, 1242000, 124600, 124900, 125000, 125000, }; const struct omap_bandgap_data omap5430_data = { -- cgit From f49302de52eb9112a746c5d218214c320c5714d6 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:27 -0400 Subject: staging: omap-thermal: standardize register nomenclature to use 'GPU' In order to keep same nomenclature across the register definition, this change will make all 'MM' suffixes to be named 'GPU'. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 16 ++++++++-------- drivers/staging/omap-thermal/omap5-thermal.c | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index a13e43adfcaa..ef342d8352c1 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -110,10 +110,10 @@ #define OMAP5430_MASK_HOT_CORE_MASK (1 << 5) #define OMAP5430_MASK_COLD_CORE_SHIFT 4 #define OMAP5430_MASK_COLD_CORE_MASK (1 << 4) -#define OMAP5430_MASK_HOT_MM_SHIFT 3 -#define OMAP5430_MASK_HOT_MM_MASK (1 << 3) -#define OMAP5430_MASK_COLD_MM_SHIFT 2 -#define OMAP5430_MASK_COLD_MM_MASK (1 << 2) +#define OMAP5430_MASK_HOT_GPU_SHIFT 3 +#define OMAP5430_MASK_HOT_GPU_MASK (1 << 3) +#define OMAP5430_MASK_COLD_GPU_SHIFT 2 +#define OMAP5430_MASK_COLD_GPU_MASK (1 << 2) #define OMAP5430_MASK_HOT_MPU_SHIFT 1 #define OMAP5430_MASK_HOT_MPU_MASK (1 << 1) #define OMAP5430_MASK_COLD_MPU_SHIFT 0 @@ -144,10 +144,10 @@ #define OMAP5430_HOT_CORE_FLAG_MASK (1 << 5) #define OMAP5430_COLD_CORE_FLAG_SHIFT 4 #define OMAP5430_COLD_CORE_FLAG_MASK (1 << 4) -#define OMAP5430_HOT_MM_FLAG_SHIFT 3 -#define OMAP5430_HOT_MM_FLAG_MASK (1 << 3) -#define OMAP5430_COLD_MM_FLAG_SHIFT 2 -#define OMAP5430_COLD_MM_FLAG_MASK (1 << 2) +#define OMAP5430_HOT_GPU_FLAG_SHIFT 3 +#define OMAP5430_HOT_GPU_FLAG_MASK (1 << 3) +#define OMAP5430_COLD_GPU_FLAG_SHIFT 2 +#define OMAP5430_COLD_GPU_FLAG_MASK (1 << 2) #define OMAP5430_HOT_MPU_FLAG_SHIFT 1 #define OMAP5430_HOT_MPU_FLAG_MASK (1 << 1) #define OMAP5430_COLD_MPU_FLAG_SHIFT 0 diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index dfa0350f0432..496555685241 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -71,8 +71,8 @@ omap5430_gpu_temp_sensor_registers = { .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, - .mask_hot_mask = OMAP5430_MASK_HOT_MM_MASK, - .mask_cold_mask = OMAP5430_MASK_COLD_MM_MASK, + .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK, + .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK, .bgap_mode_ctrl = OMAP5430_BGAP_COUNTER_GPU_OFFSET, .mode_ctrl_mask = OMAP5430_REPEAT_MODE_MASK, @@ -91,8 +91,8 @@ omap5430_gpu_temp_sensor_registers = { .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, .status_clean_stop_mask = 0x0, .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, - .status_hot_mask = OMAP5430_HOT_MM_FLAG_MASK, - .status_cold_mask = OMAP5430_COLD_MM_FLAG_MASK, + .status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK, .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, }; -- cgit From 9345640a6b381a704c3e953965eb836470390007 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:28 -0400 Subject: staging: omap-thermal: remove from register map soc and mode on OMAP5 On OMAP54xx ES2.0 there is no single read and only one mode: continuous mode. For this reason, there is no point in defining register fields for these operations. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap5-thermal.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 496555685241..32d3f878da12 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -27,7 +27,6 @@ static struct temp_sensor_registers omap5430_mpu_temp_sensor_registers = { .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_MPU_OFFSET, .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_soc_mask = OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK, .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, @@ -35,8 +34,6 @@ omap5430_mpu_temp_sensor_registers = { .mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK, - .bgap_mode_ctrl = OMAP5430_BGAP_COUNTER_MPU_OFFSET, - .mode_ctrl_mask = OMAP5430_REPEAT_MODE_MASK, .bgap_counter = OMAP5430_BGAP_COUNTER_MPU_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, @@ -66,7 +63,6 @@ static struct temp_sensor_registers omap5430_gpu_temp_sensor_registers = { .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_GPU_OFFSET, .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_soc_mask = OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK, .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, @@ -74,9 +70,6 @@ omap5430_gpu_temp_sensor_registers = { .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK, - .bgap_mode_ctrl = OMAP5430_BGAP_COUNTER_GPU_OFFSET, - .mode_ctrl_mask = OMAP5430_REPEAT_MODE_MASK, - .bgap_counter = OMAP5430_BGAP_COUNTER_GPU_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, @@ -105,7 +98,6 @@ static struct temp_sensor_registers omap5430_core_temp_sensor_registers = { .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_CORE_OFFSET, .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_soc_mask = OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK, .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, @@ -113,9 +105,6 @@ omap5430_core_temp_sensor_registers = { .mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK, - .bgap_mode_ctrl = OMAP5430_BGAP_COUNTER_CORE_OFFSET, - .mode_ctrl_mask = OMAP5430_REPEAT_MODE_MASK, - .bgap_counter = OMAP5430_BGAP_COUNTER_CORE_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, -- cgit From 1aa556ace337f7079990ec43f902c1d51b60d42a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:29 -0400 Subject: staging: omap-thermal: introduce new features of OMAP54xx On OMAP54xx ES2.0 there are new features inside the bandgap device. This patch introduces the registers definition to access these features and adapts the data structures to map these new registers. The new features are: . SIDLE mode . Cumulative register . History buffer. . Buffer freeze bit . Buffer clear bit Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 65 +++++++++++++++++++++++++++- drivers/staging/omap-thermal/omap5-thermal.c | 48 +++++++++++++++++--- 2 files changed, 106 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index ef342d8352c1..5994ebb3a4d8 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -118,6 +118,26 @@ #define OMAP5430_MASK_HOT_MPU_MASK (1 << 1) #define OMAP5430_MASK_COLD_MPU_SHIFT 0 #define OMAP5430_MASK_COLD_MPU_MASK (1 << 0) +#define OMAP5430_MASK_SIDLEMODE_SHIFT 30 +#define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30) +#define OMAP5430_MASK_FREEZE_CORE_SHIFT 23 +#define OMAP5430_MASK_FREEZE_CORE_MASK (1 << 23) +#define OMAP5430_MASK_FREEZE_GPU_SHIFT 22 +#define OMAP5430_MASK_FREEZE_GPU_MASK (1 << 22) +#define OMAP5430_MASK_FREEZE_MPU_SHIFT 21 +#define OMAP5430_MASK_FREEZE_MPU_MASK (1 << 21) +#define OMAP5430_MASK_CLEAR_CORE_SHIFT 20 +#define OMAP5430_MASK_CLEAR_CORE_MASK (1 << 20) +#define OMAP5430_MASK_CLEAR_GPU_SHIFT 19 +#define OMAP5430_MASK_CLEAR_GPU_MASK (1 << 19) +#define OMAP5430_MASK_CLEAR_MPU_SHIFT 18 +#define OMAP5430_MASK_CLEAR_MPU_MASK (1 << 18) +#define OMAP5430_MASK_CLEAR_ACCUM_CORE_SHIFT 17 +#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK (1 << 17) +#define OMAP5430_MASK_CLEAR_ACCUM_GPU_SHIFT 16 +#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK (1 << 16) +#define OMAP5430_MASK_CLEAR_ACCUM_MPU_SHIFT 15 +#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK (1 << 15) /* BANDGAP_COUNTER */ #define OMAP5430_REPEAT_MODE_SHIFT 31 @@ -137,6 +157,18 @@ #define OMAP5430_TSHUT_COLD_SHIFT 0 #define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0) +/* BANDGAP_CUMUL_DTEMP_MPU */ +#define OMAP5430_CUMUL_DTEMP_MPU_SHIFT 0 +#define OMAP5430_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0) + +/* BANDGAP_CUMUL_DTEMP_GPU */ +#define OMAP5430_CUMUL_DTEMP_GPU_SHIFT 0 +#define OMAP5430_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0) + +/* BANDGAP_CUMUL_DTEMP_CORE */ +#define OMAP5430_CUMUL_DTEMP_CORE_SHIFT 0 +#define OMAP5430_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0) + /* BANDGAP_STATUS */ #define OMAP5430_BGAP_ALERT_SHIFT 31 #define OMAP5430_BGAP_ALERT_MASK (1 << 31) @@ -174,6 +206,12 @@ #define OMAP5430_BGAP_COUNTER_GPU_OFFSET 0x1C0 #define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x1A8 #define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x1B4 +#define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET 0x1C0 +#define OMAP5430_BGAP_DTEMP_GPU_0_OFFSET 0x1F4 +#define OMAP5430_BGAP_DTEMP_GPU_1_OFFSET 0x1F8 +#define OMAP5430_BGAP_DTEMP_GPU_2_OFFSET 0x1FC +#define OMAP5430_BGAP_DTEMP_GPU_3_OFFSET 0x200 +#define OMAP5430_BGAP_DTEMP_GPU_4_OFFSET 0x204 #define OMAP5430_FUSE_OPP_BGAP_MPU 0x4 #define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x14C @@ -181,13 +219,26 @@ #define OMAP5430_BGAP_COUNTER_MPU_OFFSET 0x1BC #define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x1A4 #define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x1B0 -#define OMAP5430_BGAP_STATUS_OFFSET 0x1C8 +#define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET 0x1BC +#define OMAP5430_BGAP_DTEMP_MPU_0_OFFSET 0x1E0 +#define OMAP5430_BGAP_DTEMP_MPU_1_OFFSET 0x1E4 +#define OMAP5430_BGAP_DTEMP_MPU_2_OFFSET 0x1E8 +#define OMAP5430_BGAP_DTEMP_MPU_3_OFFSET 0x1EC +#define OMAP5430_BGAP_DTEMP_MPU_4_OFFSET 0x1F0 #define OMAP5430_FUSE_OPP_BGAP_CORE 0x8 #define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x154 #define OMAP5430_BGAP_COUNTER_CORE_OFFSET 0x1C4 #define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x1AC #define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x1B8 +#define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET 0x1C4 +#define OMAP5430_BGAP_DTEMP_CORE_0_OFFSET 0x208 +#define OMAP5430_BGAP_DTEMP_CORE_1_OFFSET 0x20C +#define OMAP5430_BGAP_DTEMP_CORE_2_OFFSET 0x210 +#define OMAP5430_BGAP_DTEMP_CORE_3_OFFSET 0x214 +#define OMAP5430_BGAP_DTEMP_CORE_4_OFFSET 0x218 + +#define OMAP5430_BGAP_STATUS_OFFSET 0x1C8 #define OMAP4460_TSHUT_HOT 900 /* 122 deg C */ #define OMAP4460_TSHUT_COLD 895 /* 100 deg C */ @@ -248,6 +299,10 @@ struct temp_sensor_registers { u32 bgap_mask_ctrl; u32 mask_hot_mask; u32 mask_cold_mask; + u32 mask_sidlemode_mask; + u32 mask_freeze_mask; + u32 mask_clear_mask; + u32 mask_clear_accum_mask; u32 bgap_mode_ctrl; u32 mode_ctrl_mask; @@ -260,6 +315,8 @@ struct temp_sensor_registers { u32 threshold_tcold_mask; u32 tshut_threshold; + u32 tshut_efuse_mask; + u32 tshut_efuse_shift; u32 tshut_hot_mask; u32 tshut_cold_mask; @@ -269,6 +326,12 @@ struct temp_sensor_registers { u32 status_hot_mask; u32 status_cold_mask; + u32 bgap_cumul_dtemp; + u32 ctrl_dtemp_0; + u32 ctrl_dtemp_1; + u32 ctrl_dtemp_2; + u32 ctrl_dtemp_3; + u32 ctrl_dtemp_4; u32 bgap_efuse; }; diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 32d3f878da12..91618fd75b0b 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -20,8 +20,12 @@ #include "omap-thermal.h" /* - * omap5430 has one instance of thermal sensor for MPU - * need to describe the individual bit fields + * OMAP5430 has three instances of thermal sensor for MPU, GPU & CORE, + * need to describe the individual registers and bit fields. + */ + +/* + * OMAP5430 MPU thermal sensor register offset and bit-fields */ static struct temp_sensor_registers omap5430_mpu_temp_sensor_registers = { @@ -33,6 +37,10 @@ omap5430_mpu_temp_sensor_registers = { .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, .mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_MPU_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_MPU_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK, .bgap_counter = OMAP5430_BGAP_COUNTER_MPU_OFFSET, @@ -52,12 +60,17 @@ omap5430_mpu_temp_sensor_registers = { .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK, .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK, + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_MPU_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_MPU_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_MPU_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_MPU_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_MPU_4_OFFSET, .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU, }; /* - * omap5430 has one instance of thermal sensor for GPU - * need to describe the individual bit fields + * OMAP5430 GPU thermal sensor register offset and bit-fields */ static struct temp_sensor_registers omap5430_gpu_temp_sensor_registers = { @@ -69,6 +82,10 @@ omap5430_gpu_temp_sensor_registers = { .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_GPU_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK, .bgap_counter = OMAP5430_BGAP_COUNTER_GPU_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, @@ -87,12 +104,18 @@ omap5430_gpu_temp_sensor_registers = { .status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK, .status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK, + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_GPU_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_GPU_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_GPU_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_GPU_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_GPU_4_OFFSET, + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, }; /* - * omap5430 has one instance of thermal sensor for CORE - * need to describe the individual bit fields + * OMAP5430 CORE thermal sensor register offset and bit-fields */ static struct temp_sensor_registers omap5430_core_temp_sensor_registers = { @@ -104,6 +127,10 @@ omap5430_core_temp_sensor_registers = { .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, .mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK, .mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_CORE_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK, .bgap_counter = OMAP5430_BGAP_COUNTER_CORE_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, @@ -122,6 +149,13 @@ omap5430_core_temp_sensor_registers = { .status_hot_mask = OMAP5430_HOT_CORE_FLAG_MASK, .status_cold_mask = OMAP5430_COLD_CORE_FLAG_MASK, + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_CORE_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_CORE_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_CORE_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_CORE_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_CORE_4_OFFSET, + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_CORE, }; @@ -281,6 +315,8 @@ omap5430_adc_to_temp[ 123800, 1242000, 124600, 124900, 125000, 125000, }; +/* OMAP54xx ES2.0 data */ +/* TODO : Need to update the slope/constant for ES2.0 silicon */ const struct omap_bandgap_data omap5430_data = { .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | OMAP_BANDGAP_FEATURE_TALERT | -- cgit From ac5c3e47a27e1ceecbed2b6809dcd78105cb3df5 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:30 -0400 Subject: staging: omap-thermal: update OMAP54xx clock sources This patch updates the OMAP54xx data structure to use the right clock source name for ES2.0. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap5-thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 91618fd75b0b..c8c3e6e735e3 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -323,8 +323,8 @@ const struct omap_bandgap_data omap5430_data = { OMAP_BANDGAP_FEATURE_MODE_CONFIG | OMAP_BANDGAP_FEATURE_COUNTER | OMAP_BANDGAP_FEATURE_CLK_CTRL, - .fclock_name = "ts_clk_div_ck", - .div_ck_name = "ts_clk_div_ck", + .fclock_name = "l3instr_ts_gclk_div", + .div_ck_name = "l3instr_ts_gclk_div", .conv_table = omap5430_adc_to_temp, .expose_sensor = omap_thermal_expose_sensor, .remove_sensor = omap_thermal_remove_sensor, -- cgit From c1989bec03f7a6b41377efca88aa44b966c318f4 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:31 -0400 Subject: staging: omap-thermal: update feature bitfield for OMAP54xx This patch removes from OMAP54xx the features: . CLK_CTRL . COUNTER . MODE_CONFIG Because these features are not present in OMAP54xx ES2.0 Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap5-thermal.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index c8c3e6e735e3..63063600f058 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -319,10 +319,7 @@ omap5430_adc_to_temp[ /* TODO : Need to update the slope/constant for ES2.0 silicon */ const struct omap_bandgap_data omap5430_data = { .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | - OMAP_BANDGAP_FEATURE_TALERT | - OMAP_BANDGAP_FEATURE_MODE_CONFIG | - OMAP_BANDGAP_FEATURE_COUNTER | - OMAP_BANDGAP_FEATURE_CLK_CTRL, + OMAP_BANDGAP_FEATURE_TALERT, .fclock_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div", .conv_table = omap5430_adc_to_temp, -- cgit From 8c9e642fc87128d87cc773d042e2fdcd38a1a9e7 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:32 -0400 Subject: staging: omap-thermal: remove dedicated counter register for OMAP5 On OMAP54xx there is only one counter register. For this reason, each domain must use the same counter register. This patch changes the data definition to coupe with this. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 5 ----- drivers/staging/omap-thermal/omap5-thermal.c | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 5994ebb3a4d8..ef5503d11177 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -140,8 +140,6 @@ #define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK (1 << 15) /* BANDGAP_COUNTER */ -#define OMAP5430_REPEAT_MODE_SHIFT 31 -#define OMAP5430_REPEAT_MODE_MASK (1 << 31) #define OMAP5430_COUNTER_SHIFT 0 #define OMAP5430_COUNTER_MASK (0xffffff << 0) @@ -203,7 +201,6 @@ /* 5430 - All goes relative to OPP_BGAP_GPU */ #define OMAP5430_FUSE_OPP_BGAP_GPU 0x0 #define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x150 -#define OMAP5430_BGAP_COUNTER_GPU_OFFSET 0x1C0 #define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x1A8 #define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x1B4 #define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET 0x1C0 @@ -216,7 +213,6 @@ #define OMAP5430_FUSE_OPP_BGAP_MPU 0x4 #define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x14C #define OMAP5430_BGAP_CTRL_OFFSET 0x1A0 -#define OMAP5430_BGAP_COUNTER_MPU_OFFSET 0x1BC #define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x1A4 #define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x1B0 #define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET 0x1BC @@ -228,7 +224,6 @@ #define OMAP5430_FUSE_OPP_BGAP_CORE 0x8 #define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x154 -#define OMAP5430_BGAP_COUNTER_CORE_OFFSET 0x1C4 #define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x1AC #define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x1B8 #define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET 0x1C4 diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index 63063600f058..c2bfc65f5d97 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -43,7 +43,7 @@ omap5430_mpu_temp_sensor_registers = { .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK, - .bgap_counter = OMAP5430_BGAP_COUNTER_MPU_OFFSET, + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, .bgap_threshold = OMAP5430_BGAP_THRESHOLD_MPU_OFFSET, @@ -87,7 +87,7 @@ omap5430_gpu_temp_sensor_registers = { .mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK, .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK, - .bgap_counter = OMAP5430_BGAP_COUNTER_GPU_OFFSET, + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, .bgap_threshold = OMAP5430_BGAP_THRESHOLD_GPU_OFFSET, @@ -132,7 +132,7 @@ omap5430_core_temp_sensor_registers = { .mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK, .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK, - .bgap_counter = OMAP5430_BGAP_COUNTER_CORE_OFFSET, + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, .counter_mask = OMAP5430_COUNTER_MASK, .bgap_threshold = OMAP5430_BGAP_THRESHOLD_CORE_OFFSET, -- cgit From 194a54f0bd0adef2e6e61fea49ba4b9db81598f8 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:33 -0400 Subject: staging: omap-thermal: introduze FREEZE_BIT feature For ES2.0 devices, it is not guaranteed that current DTEMP or DTEMP0 from the history buffer are going to contain correct values, due to desynchronization between BG clk and OCP clk. For this reason, this patch changes the driver to first: a. consider a feature flag, FREEZE_BIT, in order to check it is possible to freeze the history buffer or not. b. whenever reading the temperature, it will fetch from DTEMP1 instead of DTEMP or DTEMP0. This WA is applicable only for OMAP5430 ES2.0. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 60 ++++++++++++++++++++-------- drivers/staging/omap-thermal/omap-bandgap.h | 1 + drivers/staging/omap-thermal/omap5-thermal.c | 1 + 3 files changed, 46 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 80384edfd762..82ad5dbd7adf 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -75,12 +75,44 @@ static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) return 0; } +static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) +{ + struct temp_sensor_registers *tsr; + u32 temp, ctrl, reg; + + tsr = bg_ptr->conf->sensors[id].registers; + reg = tsr->temp_sensor_ctrl; + + if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) { + ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); + ctrl |= tsr->mask_freeze_mask; + omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl); + /* + * In case we cannot read from cur_dtemp / dtemp_0, + * then we read from the last valid temp read + */ + reg = tsr->ctrl_dtemp_1; + } + + /* read temperature */ + temp = omap_bandgap_readl(bg_ptr, reg); + temp &= tsr->bgap_dtemp_mask; + + if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) { + ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); + ctrl &= ~tsr->mask_freeze_mask; + omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl); + } + + return temp; +} + /* This is the Talert handler. Call it only if HAS(TALERT) is set */ static irqreturn_t talert_irq_handler(int irq, void *data) { struct omap_bandgap *bg_ptr = data; struct temp_sensor_registers *tsr; - u32 t_hot = 0, t_cold = 0, temp, ctrl; + u32 t_hot = 0, t_cold = 0, ctrl; int i; bg_ptr = data; @@ -118,10 +150,6 @@ static irqreturn_t talert_irq_handler(int irq, void *data) __func__, bg_ptr->conf->sensors[i].domain, t_hot, t_cold); - /* read temperature */ - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= tsr->bgap_dtemp_mask; - /* report temperature to whom may concern */ if (bg_ptr->conf->report_temperature) bg_ptr->conf->report_temperature(bg_ptr, i); @@ -190,11 +218,11 @@ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, u32 temp, reg_val; /* Read the current on die temperature */ - tsr = bg_ptr->conf->sensors[id].registers; - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= tsr->bgap_dtemp_mask; + temp = omap_bandgap_read_temp(bg_ptr, id); + tsr = bg_ptr->conf->sensors[id].registers; reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); + if (temp < t_hot) reg_val |= tsr->mask_hot_mask; else @@ -625,8 +653,9 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, return ret; tsr = bg_ptr->conf->sensors[id].registers; - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= tsr->bgap_dtemp_mask; + mutex_lock(&bg_ptr->bg_mutex); + temp = omap_bandgap_read_temp(bg_ptr, id); + mutex_unlock(&bg_ptr->bg_mutex); ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp); if (ret) @@ -694,12 +723,11 @@ omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) temp |= 1 << __ffs(tsr->bgap_soc_mask); omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl); /* Wait until DTEMP is updated */ - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= (tsr->bgap_dtemp_mask); - while ((temp == 0) && --counter) { - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= (tsr->bgap_dtemp_mask); - } + temp = omap_bandgap_read_temp(bg_ptr, id); + + while ((temp == 0) && --counter) + temp = omap_bandgap_read_temp(bg_ptr, id); + /* Start of Conversion = 0 */ temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); temp &= ~(1 << __ffs(tsr->bgap_soc_mask)); diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index ef5503d11177..59c9ba20c153 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -442,6 +442,7 @@ struct omap_bandgap_data { #define OMAP_BANDGAP_FEATURE_COUNTER (1 << 4) #define OMAP_BANDGAP_FEATURE_POWER_SWITCH (1 << 5) #define OMAP_BANDGAP_FEATURE_CLK_CTRL (1 << 6) +#define OMAP_BANDGAP_FEATURE_FREEZE_BIT (1 << 7) #define OMAP_BANDGAP_HAS(b, f) \ ((b)->conf->features & OMAP_BANDGAP_FEATURE_ ## f) unsigned int features; diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c index c2bfc65f5d97..b20db0c65318 100644 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ b/drivers/staging/omap-thermal/omap5-thermal.c @@ -319,6 +319,7 @@ omap5430_adc_to_temp[ /* TODO : Need to update the slope/constant for ES2.0 silicon */ const struct omap_bandgap_data omap5430_data = { .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | + OMAP_BANDGAP_FEATURE_FREEZE_BIT | OMAP_BANDGAP_FEATURE_TALERT, .fclock_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div", -- cgit From 18da6351d0af2cd2b4d913cd4bc28f5abb6f7e43 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:34 -0400 Subject: staging: omap-thermal: update DT entry documentation Simple update on documentation file for DT. This patch also adds an example for OMAP4430 and 0MAP4470, and also updated OMAP4460's example. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap_bandgap.txt | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap_bandgap.txt b/drivers/staging/omap-thermal/omap_bandgap.txt index 6008a1452fde..e30dc1c017c1 100644 --- a/drivers/staging/omap-thermal/omap_bandgap.txt +++ b/drivers/staging/omap-thermal/omap_bandgap.txt @@ -10,21 +10,42 @@ to the silicon temperature. Required properties: - compatible : Should be: - - "ti,omap4460-control-bandgap" : for OMAP4460 bandgap - - "ti,omap5430-control-bandgap" : for OMAP5430 bandgap + - "ti,omap4430-bandgap" : for OMAP4430 bandgap + - "ti,omap4460-bandgap" : for OMAP4460 bandgap + - "ti,omap4470-bandgap" : for OMAP4470 bandgap + - "ti,omap5430-bandgap" : for OMAP5430 bandgap - interrupts : this entry should indicate which interrupt line the talert signal is routed to; Specific: - ti,tshut-gpio : this entry should be used to inform which GPIO line the tshut signal is routed to; +- regs : this entry must also be specified and it is specific +to each bandgap version, because the mapping may change from +soc to soc, apart of depending on available features. Example: +OMAP4430: +bandgap { + reg = <0x4a002260 0x4 0x4a00232C 0x4>; + compatible = "ti,omap4430-bandgap"; +}; + +OMAP4460: +bandgap { + reg = <0x4a002260 0x4 + 0x4a00232C 0x4 + 0x4a002378 0x18>; + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; +}; +OMAP4470: bandgap { reg = <0x4a002260 0x4 0x4a00232C 0x4 0x4a002378 0x18>; - compatible = "ti,omap4460-control-bandgap"; + compatible = "ti,omap4470-bandgap"; interrupts = <0 126 4>; /* talert */ ti,tshut-gpio = <86>; }; -- cgit From efba11940a28eaf529af912f078087931e4dbaaa Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:35 -0400 Subject: staging: omap-thermal: add DT example for OMAP54xx devices Update documentation with DT example for OMAP54xx devices. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap_bandgap.txt | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap_bandgap.txt b/drivers/staging/omap-thermal/omap_bandgap.txt index e30dc1c017c1..a4a33d1a0746 100644 --- a/drivers/staging/omap-thermal/omap_bandgap.txt +++ b/drivers/staging/omap-thermal/omap_bandgap.txt @@ -49,3 +49,12 @@ bandgap { interrupts = <0 126 4>; /* talert */ ti,tshut-gpio = <86>; }; + +OMAP5430: +bandgap { + reg = <0x4a0021e0 0xc + 0x4a00232c 0xc + 0x4a002380 0x2c + 0x4a0023C0 0x3c>; + compatible = "ti,omap5430-bandgap"; +}; -- cgit From c8a8f847cc3762f07851e377c7b9515634372bb2 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:36 -0400 Subject: staging: omap-thermal: Remove double conv_table reference This patch removes from data structure the double reference of the conversion table. It keeps the reference coming from bandgap data definition. The patch also adapts the code accordingly. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 8 ++++---- drivers/staging/omap-thermal/omap-bandgap.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 82ad5dbd7adf..83f74f496017 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -179,7 +179,7 @@ int adc_to_temp_conversion(struct omap_bandgap *bg_ptr, int id, int adc_val, if (adc_val < ts_data->adc_start_val || adc_val > ts_data->adc_end_val) return -ERANGE; - *t = bg_ptr->conv_table[adc_val - ts_data->adc_start_val]; + *t = bg_ptr->conf->conv_table[adc_val - ts_data->adc_start_val]; return 0; } @@ -188,17 +188,18 @@ static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i, int *adc) { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[i].ts_data; + const int *conv_table = bg_ptr->conf->conv_table; int high, low, mid; low = 0; high = ts_data->adc_end_val - ts_data->adc_start_val; mid = (high + low) / 2; - if (temp < bg_ptr->conv_table[low] || temp > bg_ptr->conv_table[high]) + if (temp < conv_table[low] || temp > conv_table[high]) return -EINVAL; while (low < high) { - if (temp < bg_ptr->conv_table[mid]) + if (temp < conv_table[mid]) high = mid - 1; else low = mid + 1; @@ -911,7 +912,6 @@ int omap_bandgap_probe(struct platform_device *pdev) goto free_irqs; } - bg_ptr->conv_table = bg_ptr->conf->conv_table; for (i = 0; i < bg_ptr->conf->sensor_count; i++) { struct temp_sensor_registers *tsr; u32 val; diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 59c9ba20c153..3e9072c8c6bd 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -369,7 +369,6 @@ struct omap_bandgap { struct omap_bandgap_data *conf; struct clk *fclock; struct clk *div_clk; - const int *conv_table; struct mutex bg_mutex; /* Mutex for irq and PM */ int irq; int tshut_gpio; -- cgit From 687ad31ca3debfbc6803a323018f3bfc00a03b98 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:37 -0400 Subject: staging: omap-thermal: name data files accordingly This patch simply changes the name of files containing data structure definition. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/Makefile | 4 +- drivers/staging/omap-thermal/omap4-thermal-data.c | 262 ++++++++++++++++ drivers/staging/omap-thermal/omap4-thermal.c | 262 ---------------- drivers/staging/omap-thermal/omap5-thermal-data.c | 357 ++++++++++++++++++++++ drivers/staging/omap-thermal/omap5-thermal.c | 357 ---------------------- 5 files changed, 621 insertions(+), 621 deletions(-) create mode 100644 drivers/staging/omap-thermal/omap4-thermal-data.c delete mode 100644 drivers/staging/omap-thermal/omap4-thermal.c create mode 100644 drivers/staging/omap-thermal/omap5-thermal-data.c delete mode 100644 drivers/staging/omap-thermal/omap5-thermal.c (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/Makefile b/drivers/staging/omap-thermal/Makefile index 091c4d20b14d..fbd14d1365db 100644 --- a/drivers/staging/omap-thermal/Makefile +++ b/drivers/staging/omap-thermal/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o omap-thermal-y := omap-bandgap.o omap-thermal-$(CONFIG_OMAP_THERMAL) += omap-thermal-common.o -omap-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal.o -omap-thermal-$(CONFIG_OMAP5_THERMAL) += omap5-thermal.o +omap-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal-data.o +omap-thermal-$(CONFIG_OMAP5_THERMAL) += omap5-thermal-data.o diff --git a/drivers/staging/omap-thermal/omap4-thermal-data.c b/drivers/staging/omap-thermal/omap4-thermal-data.c new file mode 100644 index 000000000000..732c853174a2 --- /dev/null +++ b/drivers/staging/omap-thermal/omap4-thermal-data.c @@ -0,0 +1,262 @@ +/* + * OMAP4 thermal driver. + * + * Copyright (C) 2011-2012 Texas Instruments Inc. + * Contact: + * Eduardo Valentin + * + * 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 "omap-thermal.h" +#include "omap-bandgap.h" + +/* + * OMAP4430 has one instance of thermal sensor for MPU + * need to describe the individual bit fields + */ +static struct temp_sensor_registers +omap4430_mpu_temp_sensor_registers = { + .temp_sensor_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET, + .bgap_tempsoff_mask = OMAP4430_BGAP_TEMPSOFF_MASK, + .bgap_soc_mask = OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK, + .bgap_eocz_mask = OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK, + .bgap_dtemp_mask = OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK, + + .bgap_mode_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET, + .mode_ctrl_mask = OMAP4430_SINGLE_MODE_MASK, + + .bgap_efuse = OMAP4430_FUSE_OPP_BGAP, +}; + +/* Thresholds and limits for OMAP4430 MPU temperature sensor */ +static struct temp_sensor_data omap4430_mpu_temp_sensor_data = { + .min_freq = OMAP4430_MIN_FREQ, + .max_freq = OMAP4430_MAX_FREQ, + .max_temp = OMAP4430_MAX_TEMP, + .min_temp = OMAP4430_MIN_TEMP, + .hyst_val = OMAP4430_HYST_VAL, + .adc_start_val = OMAP4430_ADC_START_VALUE, + .adc_end_val = OMAP4430_ADC_END_VALUE, +}; + +/* + * Temperature values in milli degree celsius + * ADC code values from 530 to 923 + */ +static const int +omap4430_adc_to_temp[OMAP4430_ADC_END_VALUE - OMAP4430_ADC_START_VALUE + 1] = { + -38000, -35000, -34000, -32000, -30000, -28000, -26000, -24000, -22000, + -20000, -18000, -17000, -15000, -13000, -12000, -10000, -8000, -6000, + -5000, -3000, -1000, 0, 2000, 3000, 5000, 6000, 8000, 10000, 12000, + 13000, 15000, 17000, 19000, 21000, 23000, 25000, 27000, 28000, 30000, + 32000, 33000, 35000, 37000, 38000, 40000, 42000, 43000, 45000, 47000, + 48000, 50000, 52000, 53000, 55000, 57000, 58000, 60000, 62000, 64000, + 66000, 68000, 70000, 71000, 73000, 75000, 77000, 78000, 80000, 82000, + 83000, 85000, 87000, 88000, 90000, 92000, 93000, 95000, 97000, 98000, + 100000, 102000, 103000, 105000, 107000, 109000, 111000, 113000, 115000, + 117000, 118000, 120000, 122000, 123000, +}; + +/* OMAP4430 data */ +const struct omap_bandgap_data omap4430_data = { + .features = OMAP_BANDGAP_FEATURE_MODE_CONFIG | + OMAP_BANDGAP_FEATURE_CLK_CTRL | + OMAP_BANDGAP_FEATURE_POWER_SWITCH, + .fclock_name = "bandgap_fclk", + .div_ck_name = "bandgap_fclk", + .conv_table = omap4430_adc_to_temp, + .expose_sensor = omap_thermal_expose_sensor, + .remove_sensor = omap_thermal_remove_sensor, + .sensors = { + { + .registers = &omap4430_mpu_temp_sensor_registers, + .ts_data = &omap4430_mpu_temp_sensor_data, + .domain = "cpu", + .slope = 0, + .constant = 20000, + .slope_pcb = 0, + .constant_pcb = 20000, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, + }, + }, + .sensor_count = 1, +}; +/* + * OMAP4460 has one instance of thermal sensor for MPU + * need to describe the individual bit fields + */ +static struct temp_sensor_registers +omap4460_mpu_temp_sensor_registers = { + .temp_sensor_ctrl = OMAP4460_TEMP_SENSOR_CTRL_OFFSET, + .bgap_tempsoff_mask = OMAP4460_BGAP_TEMPSOFF_MASK, + .bgap_soc_mask = OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK, + .bgap_eocz_mask = OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK, + .bgap_dtemp_mask = OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK, + + .bgap_mask_ctrl = OMAP4460_BGAP_CTRL_OFFSET, + .mask_hot_mask = OMAP4460_MASK_HOT_MASK, + .mask_cold_mask = OMAP4460_MASK_COLD_MASK, + + .bgap_mode_ctrl = OMAP4460_BGAP_CTRL_OFFSET, + .mode_ctrl_mask = OMAP4460_SINGLE_MODE_MASK, + + .bgap_counter = OMAP4460_BGAP_COUNTER_OFFSET, + .counter_mask = OMAP4460_COUNTER_MASK, + + .bgap_threshold = OMAP4460_BGAP_THRESHOLD_OFFSET, + .threshold_thot_mask = OMAP4460_T_HOT_MASK, + .threshold_tcold_mask = OMAP4460_T_COLD_MASK, + + .tshut_threshold = OMAP4460_BGAP_TSHUT_OFFSET, + .tshut_hot_mask = OMAP4460_TSHUT_HOT_MASK, + .tshut_cold_mask = OMAP4460_TSHUT_COLD_MASK, + + .bgap_status = OMAP4460_BGAP_STATUS_OFFSET, + .status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK, + .status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK, + .status_hot_mask = OMAP4460_HOT_FLAG_MASK, + .status_cold_mask = OMAP4460_COLD_FLAG_MASK, + + .bgap_efuse = OMAP4460_FUSE_OPP_BGAP, +}; + +/* Thresholds and limits for OMAP4460 MPU temperature sensor */ +static struct temp_sensor_data omap4460_mpu_temp_sensor_data = { + .tshut_hot = OMAP4460_TSHUT_HOT, + .tshut_cold = OMAP4460_TSHUT_COLD, + .t_hot = OMAP4460_T_HOT, + .t_cold = OMAP4460_T_COLD, + .min_freq = OMAP4460_MIN_FREQ, + .max_freq = OMAP4460_MAX_FREQ, + .max_temp = OMAP4460_MAX_TEMP, + .min_temp = OMAP4460_MIN_TEMP, + .hyst_val = OMAP4460_HYST_VAL, + .adc_start_val = OMAP4460_ADC_START_VALUE, + .adc_end_val = OMAP4460_ADC_END_VALUE, + .update_int1 = 1000, + .update_int2 = 2000, +}; + +/* + * Temperature values in milli degree celsius + * ADC code values from 530 to 923 + */ +static const int +omap4460_adc_to_temp[OMAP4460_ADC_END_VALUE - OMAP4460_ADC_START_VALUE + 1] = { + -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, + -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800, + -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300, + -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800, + -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400, + -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000, + -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600, + -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200, + -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700, + -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800, + -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000, + -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600, + 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400, + 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000, + 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800, + 15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700, + 19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600, + 23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400, + 26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200, + 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000, + 34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800, + 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600, + 42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300, + 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000, + 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800, + 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600, + 57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400, + 60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200, + 64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800, + 68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600, + 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400, + 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, + 79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800, + 83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400, + 86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200, + 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800, + 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600, + 98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200, + 101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400, + 104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800, + 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, + 111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200, + 114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400, + 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600, + 121000, 121400, 121800, 122200, 122600, 123000, 123400, 123800, 124200, + 124600, 124900, 125000, 125000, 125000, 125000 +}; + +/* OMAP4460 data */ +const struct omap_bandgap_data omap4460_data = { + .features = OMAP_BANDGAP_FEATURE_TSHUT | + OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | + OMAP_BANDGAP_FEATURE_TALERT | + OMAP_BANDGAP_FEATURE_MODE_CONFIG | + OMAP_BANDGAP_FEATURE_POWER_SWITCH | + OMAP_BANDGAP_FEATURE_CLK_CTRL | + OMAP_BANDGAP_FEATURE_COUNTER, + .fclock_name = "bandgap_ts_fclk", + .div_ck_name = "div_ts_ck", + .conv_table = omap4460_adc_to_temp, + .expose_sensor = omap_thermal_expose_sensor, + .remove_sensor = omap_thermal_remove_sensor, + .sensors = { + { + .registers = &omap4460_mpu_temp_sensor_registers, + .ts_data = &omap4460_mpu_temp_sensor_data, + .domain = "cpu", + .slope = OMAP_GRADIENT_SLOPE_4460, + .constant = OMAP_GRADIENT_CONST_4460, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, + }, + }, + .sensor_count = 1, +}; + +/* OMAP4470 data */ +const struct omap_bandgap_data omap4470_data = { + .features = OMAP_BANDGAP_FEATURE_TSHUT | + OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | + OMAP_BANDGAP_FEATURE_TALERT | + OMAP_BANDGAP_FEATURE_MODE_CONFIG | + OMAP_BANDGAP_FEATURE_POWER_SWITCH | + OMAP_BANDGAP_FEATURE_CLK_CTRL | + OMAP_BANDGAP_FEATURE_COUNTER, + .fclock_name = "bandgap_ts_fclk", + .div_ck_name = "div_ts_ck", + .conv_table = omap4460_adc_to_temp, + .expose_sensor = omap_thermal_expose_sensor, + .remove_sensor = omap_thermal_remove_sensor, + .sensors = { + { + .registers = &omap4460_mpu_temp_sensor_registers, + .ts_data = &omap4460_mpu_temp_sensor_data, + .domain = "cpu", + .slope = OMAP_GRADIENT_SLOPE_4470, + .constant = OMAP_GRADIENT_CONST_4470, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470, + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, + }, + }, + .sensor_count = 1, +}; diff --git a/drivers/staging/omap-thermal/omap4-thermal.c b/drivers/staging/omap-thermal/omap4-thermal.c deleted file mode 100644 index 732c853174a2..000000000000 --- a/drivers/staging/omap-thermal/omap4-thermal.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * OMAP4 thermal driver. - * - * Copyright (C) 2011-2012 Texas Instruments Inc. - * Contact: - * Eduardo Valentin - * - * 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 "omap-thermal.h" -#include "omap-bandgap.h" - -/* - * OMAP4430 has one instance of thermal sensor for MPU - * need to describe the individual bit fields - */ -static struct temp_sensor_registers -omap4430_mpu_temp_sensor_registers = { - .temp_sensor_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET, - .bgap_tempsoff_mask = OMAP4430_BGAP_TEMPSOFF_MASK, - .bgap_soc_mask = OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK, - .bgap_eocz_mask = OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK, - .bgap_dtemp_mask = OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK, - - .bgap_mode_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET, - .mode_ctrl_mask = OMAP4430_SINGLE_MODE_MASK, - - .bgap_efuse = OMAP4430_FUSE_OPP_BGAP, -}; - -/* Thresholds and limits for OMAP4430 MPU temperature sensor */ -static struct temp_sensor_data omap4430_mpu_temp_sensor_data = { - .min_freq = OMAP4430_MIN_FREQ, - .max_freq = OMAP4430_MAX_FREQ, - .max_temp = OMAP4430_MAX_TEMP, - .min_temp = OMAP4430_MIN_TEMP, - .hyst_val = OMAP4430_HYST_VAL, - .adc_start_val = OMAP4430_ADC_START_VALUE, - .adc_end_val = OMAP4430_ADC_END_VALUE, -}; - -/* - * Temperature values in milli degree celsius - * ADC code values from 530 to 923 - */ -static const int -omap4430_adc_to_temp[OMAP4430_ADC_END_VALUE - OMAP4430_ADC_START_VALUE + 1] = { - -38000, -35000, -34000, -32000, -30000, -28000, -26000, -24000, -22000, - -20000, -18000, -17000, -15000, -13000, -12000, -10000, -8000, -6000, - -5000, -3000, -1000, 0, 2000, 3000, 5000, 6000, 8000, 10000, 12000, - 13000, 15000, 17000, 19000, 21000, 23000, 25000, 27000, 28000, 30000, - 32000, 33000, 35000, 37000, 38000, 40000, 42000, 43000, 45000, 47000, - 48000, 50000, 52000, 53000, 55000, 57000, 58000, 60000, 62000, 64000, - 66000, 68000, 70000, 71000, 73000, 75000, 77000, 78000, 80000, 82000, - 83000, 85000, 87000, 88000, 90000, 92000, 93000, 95000, 97000, 98000, - 100000, 102000, 103000, 105000, 107000, 109000, 111000, 113000, 115000, - 117000, 118000, 120000, 122000, 123000, -}; - -/* OMAP4430 data */ -const struct omap_bandgap_data omap4430_data = { - .features = OMAP_BANDGAP_FEATURE_MODE_CONFIG | - OMAP_BANDGAP_FEATURE_CLK_CTRL | - OMAP_BANDGAP_FEATURE_POWER_SWITCH, - .fclock_name = "bandgap_fclk", - .div_ck_name = "bandgap_fclk", - .conv_table = omap4430_adc_to_temp, - .expose_sensor = omap_thermal_expose_sensor, - .remove_sensor = omap_thermal_remove_sensor, - .sensors = { - { - .registers = &omap4430_mpu_temp_sensor_registers, - .ts_data = &omap4430_mpu_temp_sensor_data, - .domain = "cpu", - .slope = 0, - .constant = 20000, - .slope_pcb = 0, - .constant_pcb = 20000, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, - }, - }, - .sensor_count = 1, -}; -/* - * OMAP4460 has one instance of thermal sensor for MPU - * need to describe the individual bit fields - */ -static struct temp_sensor_registers -omap4460_mpu_temp_sensor_registers = { - .temp_sensor_ctrl = OMAP4460_TEMP_SENSOR_CTRL_OFFSET, - .bgap_tempsoff_mask = OMAP4460_BGAP_TEMPSOFF_MASK, - .bgap_soc_mask = OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK, - .bgap_eocz_mask = OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK, - .bgap_dtemp_mask = OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK, - - .bgap_mask_ctrl = OMAP4460_BGAP_CTRL_OFFSET, - .mask_hot_mask = OMAP4460_MASK_HOT_MASK, - .mask_cold_mask = OMAP4460_MASK_COLD_MASK, - - .bgap_mode_ctrl = OMAP4460_BGAP_CTRL_OFFSET, - .mode_ctrl_mask = OMAP4460_SINGLE_MODE_MASK, - - .bgap_counter = OMAP4460_BGAP_COUNTER_OFFSET, - .counter_mask = OMAP4460_COUNTER_MASK, - - .bgap_threshold = OMAP4460_BGAP_THRESHOLD_OFFSET, - .threshold_thot_mask = OMAP4460_T_HOT_MASK, - .threshold_tcold_mask = OMAP4460_T_COLD_MASK, - - .tshut_threshold = OMAP4460_BGAP_TSHUT_OFFSET, - .tshut_hot_mask = OMAP4460_TSHUT_HOT_MASK, - .tshut_cold_mask = OMAP4460_TSHUT_COLD_MASK, - - .bgap_status = OMAP4460_BGAP_STATUS_OFFSET, - .status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK, - .status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK, - .status_hot_mask = OMAP4460_HOT_FLAG_MASK, - .status_cold_mask = OMAP4460_COLD_FLAG_MASK, - - .bgap_efuse = OMAP4460_FUSE_OPP_BGAP, -}; - -/* Thresholds and limits for OMAP4460 MPU temperature sensor */ -static struct temp_sensor_data omap4460_mpu_temp_sensor_data = { - .tshut_hot = OMAP4460_TSHUT_HOT, - .tshut_cold = OMAP4460_TSHUT_COLD, - .t_hot = OMAP4460_T_HOT, - .t_cold = OMAP4460_T_COLD, - .min_freq = OMAP4460_MIN_FREQ, - .max_freq = OMAP4460_MAX_FREQ, - .max_temp = OMAP4460_MAX_TEMP, - .min_temp = OMAP4460_MIN_TEMP, - .hyst_val = OMAP4460_HYST_VAL, - .adc_start_val = OMAP4460_ADC_START_VALUE, - .adc_end_val = OMAP4460_ADC_END_VALUE, - .update_int1 = 1000, - .update_int2 = 2000, -}; - -/* - * Temperature values in milli degree celsius - * ADC code values from 530 to 923 - */ -static const int -omap4460_adc_to_temp[OMAP4460_ADC_END_VALUE - OMAP4460_ADC_START_VALUE + 1] = { - -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, - -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800, - -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300, - -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800, - -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400, - -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000, - -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600, - -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200, - -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700, - -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800, - -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000, - -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600, - 2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400, - 6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000, - 11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800, - 15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700, - 19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600, - 23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400, - 26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200, - 30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000, - 34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800, - 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600, - 42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300, - 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000, - 49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800, - 53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600, - 57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400, - 60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200, - 64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800, - 68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600, - 72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400, - 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, - 79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800, - 83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400, - 86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200, - 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800, - 94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600, - 98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200, - 101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400, - 104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800, - 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, - 111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200, - 114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400, - 117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600, - 121000, 121400, 121800, 122200, 122600, 123000, 123400, 123800, 124200, - 124600, 124900, 125000, 125000, 125000, 125000 -}; - -/* OMAP4460 data */ -const struct omap_bandgap_data omap4460_data = { - .features = OMAP_BANDGAP_FEATURE_TSHUT | - OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | - OMAP_BANDGAP_FEATURE_TALERT | - OMAP_BANDGAP_FEATURE_MODE_CONFIG | - OMAP_BANDGAP_FEATURE_POWER_SWITCH | - OMAP_BANDGAP_FEATURE_CLK_CTRL | - OMAP_BANDGAP_FEATURE_COUNTER, - .fclock_name = "bandgap_ts_fclk", - .div_ck_name = "div_ts_ck", - .conv_table = omap4460_adc_to_temp, - .expose_sensor = omap_thermal_expose_sensor, - .remove_sensor = omap_thermal_remove_sensor, - .sensors = { - { - .registers = &omap4460_mpu_temp_sensor_registers, - .ts_data = &omap4460_mpu_temp_sensor_data, - .domain = "cpu", - .slope = OMAP_GRADIENT_SLOPE_4460, - .constant = OMAP_GRADIENT_CONST_4460, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, - }, - }, - .sensor_count = 1, -}; - -/* OMAP4470 data */ -const struct omap_bandgap_data omap4470_data = { - .features = OMAP_BANDGAP_FEATURE_TSHUT | - OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | - OMAP_BANDGAP_FEATURE_TALERT | - OMAP_BANDGAP_FEATURE_MODE_CONFIG | - OMAP_BANDGAP_FEATURE_POWER_SWITCH | - OMAP_BANDGAP_FEATURE_CLK_CTRL | - OMAP_BANDGAP_FEATURE_COUNTER, - .fclock_name = "bandgap_ts_fclk", - .div_ck_name = "div_ts_ck", - .conv_table = omap4460_adc_to_temp, - .expose_sensor = omap_thermal_expose_sensor, - .remove_sensor = omap_thermal_remove_sensor, - .sensors = { - { - .registers = &omap4460_mpu_temp_sensor_registers, - .ts_data = &omap4460_mpu_temp_sensor_data, - .domain = "cpu", - .slope = OMAP_GRADIENT_SLOPE_4470, - .constant = OMAP_GRADIENT_CONST_4470, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470, - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, - }, - }, - .sensor_count = 1, -}; diff --git a/drivers/staging/omap-thermal/omap5-thermal-data.c b/drivers/staging/omap-thermal/omap5-thermal-data.c new file mode 100644 index 000000000000..b20db0c65318 --- /dev/null +++ b/drivers/staging/omap-thermal/omap5-thermal-data.c @@ -0,0 +1,357 @@ +/* + * OMAP5 thermal driver. + * + * Copyright (C) 2011-2012 Texas Instruments Inc. + * Contact: + * Eduardo Valentin + * + * 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 "omap-bandgap.h" +#include "omap-thermal.h" + +/* + * OMAP5430 has three instances of thermal sensor for MPU, GPU & CORE, + * need to describe the individual registers and bit fields. + */ + +/* + * OMAP5430 MPU thermal sensor register offset and bit-fields + */ +static struct temp_sensor_registers +omap5430_mpu_temp_sensor_registers = { + .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_MPU_OFFSET, + .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, + .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, + .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, + + .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, + .mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK, + .mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_MPU_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_MPU_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK, + + + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, + .counter_mask = OMAP5430_COUNTER_MASK, + + .bgap_threshold = OMAP5430_BGAP_THRESHOLD_MPU_OFFSET, + .threshold_thot_mask = OMAP5430_T_HOT_MASK, + .threshold_tcold_mask = OMAP5430_T_COLD_MASK, + + .tshut_threshold = OMAP5430_BGAP_TSHUT_MPU_OFFSET, + .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, + .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, + + .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, + .status_clean_stop_mask = 0x0, + .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, + .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK, + + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_MPU_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_MPU_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_MPU_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_MPU_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_MPU_4_OFFSET, + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU, +}; + +/* + * OMAP5430 GPU thermal sensor register offset and bit-fields + */ +static struct temp_sensor_registers +omap5430_gpu_temp_sensor_registers = { + .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_GPU_OFFSET, + .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, + .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, + .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, + + .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, + .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK, + .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_GPU_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK, + + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, + .counter_mask = OMAP5430_COUNTER_MASK, + + .bgap_threshold = OMAP5430_BGAP_THRESHOLD_GPU_OFFSET, + .threshold_thot_mask = OMAP5430_T_HOT_MASK, + .threshold_tcold_mask = OMAP5430_T_COLD_MASK, + + .tshut_threshold = OMAP5430_BGAP_TSHUT_GPU_OFFSET, + .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, + .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, + + .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, + .status_clean_stop_mask = 0x0, + .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, + .status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK, + + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_GPU_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_GPU_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_GPU_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_GPU_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_GPU_4_OFFSET, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, +}; + +/* + * OMAP5430 CORE thermal sensor register offset and bit-fields + */ +static struct temp_sensor_registers +omap5430_core_temp_sensor_registers = { + .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_CORE_OFFSET, + .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, + .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, + .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, + + .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, + .mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK, + .mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK, + .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, + .mask_freeze_mask = OMAP5430_MASK_FREEZE_CORE_MASK, + .mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK, + .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK, + + .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, + .counter_mask = OMAP5430_COUNTER_MASK, + + .bgap_threshold = OMAP5430_BGAP_THRESHOLD_CORE_OFFSET, + .threshold_thot_mask = OMAP5430_T_HOT_MASK, + .threshold_tcold_mask = OMAP5430_T_COLD_MASK, + + .tshut_threshold = OMAP5430_BGAP_TSHUT_CORE_OFFSET, + .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, + .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, + + .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, + .status_clean_stop_mask = 0x0, + .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, + .status_hot_mask = OMAP5430_HOT_CORE_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_CORE_FLAG_MASK, + + .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET, + .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_CORE_0_OFFSET, + .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_CORE_1_OFFSET, + .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_CORE_2_OFFSET, + .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_CORE_3_OFFSET, + .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_CORE_4_OFFSET, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_CORE, +}; + +/* Thresholds and limits for OMAP5430 MPU temperature sensor */ +static struct temp_sensor_data omap5430_mpu_temp_sensor_data = { + .tshut_hot = OMAP5430_MPU_TSHUT_HOT, + .tshut_cold = OMAP5430_MPU_TSHUT_COLD, + .t_hot = OMAP5430_MPU_T_HOT, + .t_cold = OMAP5430_MPU_T_COLD, + .min_freq = OMAP5430_MPU_MIN_FREQ, + .max_freq = OMAP5430_MPU_MAX_FREQ, + .max_temp = OMAP5430_MPU_MAX_TEMP, + .min_temp = OMAP5430_MPU_MIN_TEMP, + .hyst_val = OMAP5430_MPU_HYST_VAL, + .adc_start_val = OMAP5430_ADC_START_VALUE, + .adc_end_val = OMAP5430_ADC_END_VALUE, + .update_int1 = 1000, + .update_int2 = 2000, +}; + +/* Thresholds and limits for OMAP5430 GPU temperature sensor */ +static struct temp_sensor_data omap5430_gpu_temp_sensor_data = { + .tshut_hot = OMAP5430_GPU_TSHUT_HOT, + .tshut_cold = OMAP5430_GPU_TSHUT_COLD, + .t_hot = OMAP5430_GPU_T_HOT, + .t_cold = OMAP5430_GPU_T_COLD, + .min_freq = OMAP5430_GPU_MIN_FREQ, + .max_freq = OMAP5430_GPU_MAX_FREQ, + .max_temp = OMAP5430_GPU_MAX_TEMP, + .min_temp = OMAP5430_GPU_MIN_TEMP, + .hyst_val = OMAP5430_GPU_HYST_VAL, + .adc_start_val = OMAP5430_ADC_START_VALUE, + .adc_end_val = OMAP5430_ADC_END_VALUE, + .update_int1 = 1000, + .update_int2 = 2000, +}; + +/* Thresholds and limits for OMAP5430 CORE temperature sensor */ +static struct temp_sensor_data omap5430_core_temp_sensor_data = { + .tshut_hot = OMAP5430_CORE_TSHUT_HOT, + .tshut_cold = OMAP5430_CORE_TSHUT_COLD, + .t_hot = OMAP5430_CORE_T_HOT, + .t_cold = OMAP5430_CORE_T_COLD, + .min_freq = OMAP5430_CORE_MIN_FREQ, + .max_freq = OMAP5430_CORE_MAX_FREQ, + .max_temp = OMAP5430_CORE_MAX_TEMP, + .min_temp = OMAP5430_CORE_MIN_TEMP, + .hyst_val = OMAP5430_CORE_HYST_VAL, + .adc_start_val = OMAP5430_ADC_START_VALUE, + .adc_end_val = OMAP5430_ADC_END_VALUE, + .update_int1 = 1000, + .update_int2 = 2000, +}; + +/* + * OMAP54xx ES2.0 : Temperature values in milli degree celsius + * ADC code values from 540 to 945 + */ +static int +omap5430_adc_to_temp[ + OMAP5430_ADC_END_VALUE - OMAP5430_ADC_START_VALUE + 1] = { + /* Index 540 - 549 */ + -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, + -37800, + /* Index 550 - 559 */ + -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800, + -33400, + /* Index 560 - 569 */ + -33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800, + -29400, + /* Index 570 - 579 */ + -29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400, + -25000, + /* Index 580 - 589 */ + -24600, -24200, -23800, -23400, -23000, -22600, -22200, -21600, -21400, + -21000, + /* Index 590 - 599 */ + -20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000, + -16600, + /* Index 600 - 609 */ + -16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000, + -12500, + /* Index 610 - 619 */ + -11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600, + -8200, + /* Index 620 - 629 */ + -7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, + /* Index 630 - 639 */ + -3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200, 200, + /* Index 640 - 649 */ + 600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900, 4500, + /* Index 650 - 659 */ + 5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200, 8600, + /* Index 660 - 669 */ + 9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200, 12700, + /* Index 670 - 679 */ + 13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600, 17000, + /* Index 680 - 689 */ + 17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600, 21100, + /* Index 690 - 699 */ + 21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000, 25400, + /* Index 700 - 709 */ + 25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000, 29400, + /* Index 710 - 719 */ + 29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400, 33800, + /* Index 720 - 729 */ + 34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400, 37800, + /* Index 730 - 739 */ + 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400, 41800, + /* Index 740 - 749 */ + 42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800, 46200, + /* Index 750 - 759 */ + 46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800, 50200, + /* Index 760 - 769 */ + 50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800, 54200, + /* Index 770 - 779 */ + 54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200, 58600, + /* Index 780 - 789 */ + 59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200, 62600, + /* Index 790 - 799 */ + 63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200, 66600, + /* Index 800 - 809 */ + 67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200, 70600, + /* Index 810 - 819 */ + 71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600, 75000, + /* Index 820 - 829 */ + 75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, + /* Index 830 - 839 */ + 79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600, 83000, + /* Index 840 - 849 */ + 83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600, 87000, + /* Index 850 - 859 */ + 87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600, 91000, + /* Index 860 - 869 */ + 91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600, 95000, + /* Index 870 - 879 */ + 95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000, 99400, + /* Index 880 - 889 */ + 99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000, + 103400, + /* Index 890 - 899 */ + 103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000, + 107400, + /* Index 900 - 909 */ + 107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, + 111400, + /* Index 910 - 919 */ + 111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000, + 115400, + /* Index 920 - 929 */ + 115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, + 119400, + /* Index 930 - 939 */ + 119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000, + 123400, + /* Index 940 - 945 */ + 123800, 1242000, 124600, 124900, 125000, 125000, +}; + +/* OMAP54xx ES2.0 data */ +/* TODO : Need to update the slope/constant for ES2.0 silicon */ +const struct omap_bandgap_data omap5430_data = { + .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | + OMAP_BANDGAP_FEATURE_FREEZE_BIT | + OMAP_BANDGAP_FEATURE_TALERT, + .fclock_name = "l3instr_ts_gclk_div", + .div_ck_name = "l3instr_ts_gclk_div", + .conv_table = omap5430_adc_to_temp, + .expose_sensor = omap_thermal_expose_sensor, + .remove_sensor = omap_thermal_remove_sensor, + .sensors = { + { + .registers = &omap5430_mpu_temp_sensor_registers, + .ts_data = &omap5430_mpu_temp_sensor_data, + .domain = "cpu", + .register_cooling = omap_thermal_register_cpu_cooling, + .unregister_cooling = omap_thermal_unregister_cpu_cooling, + .slope = OMAP_GRADIENT_SLOPE_5430_CPU, + .constant = OMAP_GRADIENT_CONST_5430_CPU, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU, + }, + { + .registers = &omap5430_gpu_temp_sensor_registers, + .ts_data = &omap5430_gpu_temp_sensor_data, + .domain = "gpu", + .slope = OMAP_GRADIENT_SLOPE_5430_GPU, + .constant = OMAP_GRADIENT_CONST_5430_GPU, + .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU, + .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU, + }, + { + .registers = &omap5430_core_temp_sensor_registers, + .ts_data = &omap5430_core_temp_sensor_data, + .domain = "core", + }, + }, + .sensor_count = 3, +}; diff --git a/drivers/staging/omap-thermal/omap5-thermal.c b/drivers/staging/omap-thermal/omap5-thermal.c deleted file mode 100644 index b20db0c65318..000000000000 --- a/drivers/staging/omap-thermal/omap5-thermal.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * OMAP5 thermal driver. - * - * Copyright (C) 2011-2012 Texas Instruments Inc. - * Contact: - * Eduardo Valentin - * - * 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 "omap-bandgap.h" -#include "omap-thermal.h" - -/* - * OMAP5430 has three instances of thermal sensor for MPU, GPU & CORE, - * need to describe the individual registers and bit fields. - */ - -/* - * OMAP5430 MPU thermal sensor register offset and bit-fields - */ -static struct temp_sensor_registers -omap5430_mpu_temp_sensor_registers = { - .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_MPU_OFFSET, - .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, - .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, - - .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, - .mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK, - .mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK, - .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, - .mask_freeze_mask = OMAP5430_MASK_FREEZE_MPU_MASK, - .mask_clear_mask = OMAP5430_MASK_CLEAR_MPU_MASK, - .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK, - - - .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, - .counter_mask = OMAP5430_COUNTER_MASK, - - .bgap_threshold = OMAP5430_BGAP_THRESHOLD_MPU_OFFSET, - .threshold_thot_mask = OMAP5430_T_HOT_MASK, - .threshold_tcold_mask = OMAP5430_T_COLD_MASK, - - .tshut_threshold = OMAP5430_BGAP_TSHUT_MPU_OFFSET, - .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, - .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, - - .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, - .status_clean_stop_mask = 0x0, - .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, - .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK, - .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK, - - .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET, - .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_MPU_0_OFFSET, - .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_MPU_1_OFFSET, - .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_MPU_2_OFFSET, - .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_MPU_3_OFFSET, - .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_MPU_4_OFFSET, - .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU, -}; - -/* - * OMAP5430 GPU thermal sensor register offset and bit-fields - */ -static struct temp_sensor_registers -omap5430_gpu_temp_sensor_registers = { - .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_GPU_OFFSET, - .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, - .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, - - .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, - .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK, - .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK, - .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, - .mask_freeze_mask = OMAP5430_MASK_FREEZE_GPU_MASK, - .mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK, - .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK, - - .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, - .counter_mask = OMAP5430_COUNTER_MASK, - - .bgap_threshold = OMAP5430_BGAP_THRESHOLD_GPU_OFFSET, - .threshold_thot_mask = OMAP5430_T_HOT_MASK, - .threshold_tcold_mask = OMAP5430_T_COLD_MASK, - - .tshut_threshold = OMAP5430_BGAP_TSHUT_GPU_OFFSET, - .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, - .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, - - .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, - .status_clean_stop_mask = 0x0, - .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, - .status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK, - .status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK, - - .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET, - .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_GPU_0_OFFSET, - .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_GPU_1_OFFSET, - .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_GPU_2_OFFSET, - .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_GPU_3_OFFSET, - .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_GPU_4_OFFSET, - - .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, -}; - -/* - * OMAP5430 CORE thermal sensor register offset and bit-fields - */ -static struct temp_sensor_registers -omap5430_core_temp_sensor_registers = { - .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_CORE_OFFSET, - .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK, - .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK, - .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK, - - .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET, - .mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK, - .mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK, - .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK, - .mask_freeze_mask = OMAP5430_MASK_FREEZE_CORE_MASK, - .mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK, - .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK, - - .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET, - .counter_mask = OMAP5430_COUNTER_MASK, - - .bgap_threshold = OMAP5430_BGAP_THRESHOLD_CORE_OFFSET, - .threshold_thot_mask = OMAP5430_T_HOT_MASK, - .threshold_tcold_mask = OMAP5430_T_COLD_MASK, - - .tshut_threshold = OMAP5430_BGAP_TSHUT_CORE_OFFSET, - .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK, - .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK, - - .bgap_status = OMAP5430_BGAP_STATUS_OFFSET, - .status_clean_stop_mask = 0x0, - .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK, - .status_hot_mask = OMAP5430_HOT_CORE_FLAG_MASK, - .status_cold_mask = OMAP5430_COLD_CORE_FLAG_MASK, - - .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET, - .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_CORE_0_OFFSET, - .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_CORE_1_OFFSET, - .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_CORE_2_OFFSET, - .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_CORE_3_OFFSET, - .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_CORE_4_OFFSET, - - .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_CORE, -}; - -/* Thresholds and limits for OMAP5430 MPU temperature sensor */ -static struct temp_sensor_data omap5430_mpu_temp_sensor_data = { - .tshut_hot = OMAP5430_MPU_TSHUT_HOT, - .tshut_cold = OMAP5430_MPU_TSHUT_COLD, - .t_hot = OMAP5430_MPU_T_HOT, - .t_cold = OMAP5430_MPU_T_COLD, - .min_freq = OMAP5430_MPU_MIN_FREQ, - .max_freq = OMAP5430_MPU_MAX_FREQ, - .max_temp = OMAP5430_MPU_MAX_TEMP, - .min_temp = OMAP5430_MPU_MIN_TEMP, - .hyst_val = OMAP5430_MPU_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, - .update_int1 = 1000, - .update_int2 = 2000, -}; - -/* Thresholds and limits for OMAP5430 GPU temperature sensor */ -static struct temp_sensor_data omap5430_gpu_temp_sensor_data = { - .tshut_hot = OMAP5430_GPU_TSHUT_HOT, - .tshut_cold = OMAP5430_GPU_TSHUT_COLD, - .t_hot = OMAP5430_GPU_T_HOT, - .t_cold = OMAP5430_GPU_T_COLD, - .min_freq = OMAP5430_GPU_MIN_FREQ, - .max_freq = OMAP5430_GPU_MAX_FREQ, - .max_temp = OMAP5430_GPU_MAX_TEMP, - .min_temp = OMAP5430_GPU_MIN_TEMP, - .hyst_val = OMAP5430_GPU_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, - .update_int1 = 1000, - .update_int2 = 2000, -}; - -/* Thresholds and limits for OMAP5430 CORE temperature sensor */ -static struct temp_sensor_data omap5430_core_temp_sensor_data = { - .tshut_hot = OMAP5430_CORE_TSHUT_HOT, - .tshut_cold = OMAP5430_CORE_TSHUT_COLD, - .t_hot = OMAP5430_CORE_T_HOT, - .t_cold = OMAP5430_CORE_T_COLD, - .min_freq = OMAP5430_CORE_MIN_FREQ, - .max_freq = OMAP5430_CORE_MAX_FREQ, - .max_temp = OMAP5430_CORE_MAX_TEMP, - .min_temp = OMAP5430_CORE_MIN_TEMP, - .hyst_val = OMAP5430_CORE_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, - .update_int1 = 1000, - .update_int2 = 2000, -}; - -/* - * OMAP54xx ES2.0 : Temperature values in milli degree celsius - * ADC code values from 540 to 945 - */ -static int -omap5430_adc_to_temp[ - OMAP5430_ADC_END_VALUE - OMAP5430_ADC_START_VALUE + 1] = { - /* Index 540 - 549 */ - -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200, - -37800, - /* Index 550 - 559 */ - -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800, - -33400, - /* Index 560 - 569 */ - -33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800, - -29400, - /* Index 570 - 579 */ - -29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400, - -25000, - /* Index 580 - 589 */ - -24600, -24200, -23800, -23400, -23000, -22600, -22200, -21600, -21400, - -21000, - /* Index 590 - 599 */ - -20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000, - -16600, - /* Index 600 - 609 */ - -16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000, - -12500, - /* Index 610 - 619 */ - -11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600, - -8200, - /* Index 620 - 629 */ - -7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, - /* Index 630 - 639 */ - -3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200, 200, - /* Index 640 - 649 */ - 600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900, 4500, - /* Index 650 - 659 */ - 5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200, 8600, - /* Index 660 - 669 */ - 9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200, 12700, - /* Index 670 - 679 */ - 13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600, 17000, - /* Index 680 - 689 */ - 17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600, 21100, - /* Index 690 - 699 */ - 21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000, 25400, - /* Index 700 - 709 */ - 25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000, 29400, - /* Index 710 - 719 */ - 29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400, 33800, - /* Index 720 - 729 */ - 34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400, 37800, - /* Index 730 - 739 */ - 38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400, 41800, - /* Index 740 - 749 */ - 42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800, 46200, - /* Index 750 - 759 */ - 46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800, 50200, - /* Index 760 - 769 */ - 50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800, 54200, - /* Index 770 - 779 */ - 54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200, 58600, - /* Index 780 - 789 */ - 59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200, 62600, - /* Index 790 - 799 */ - 63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200, 66600, - /* Index 800 - 809 */ - 67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200, 70600, - /* Index 810 - 819 */ - 71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600, 75000, - /* Index 820 - 829 */ - 75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000, - /* Index 830 - 839 */ - 79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600, 83000, - /* Index 840 - 849 */ - 83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600, 87000, - /* Index 850 - 859 */ - 87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600, 91000, - /* Index 860 - 869 */ - 91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600, 95000, - /* Index 870 - 879 */ - 95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000, 99400, - /* Index 880 - 889 */ - 99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000, - 103400, - /* Index 890 - 899 */ - 103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000, - 107400, - /* Index 900 - 909 */ - 107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000, - 111400, - /* Index 910 - 919 */ - 111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000, - 115400, - /* Index 920 - 929 */ - 115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, - 119400, - /* Index 930 - 939 */ - 119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000, - 123400, - /* Index 940 - 945 */ - 123800, 1242000, 124600, 124900, 125000, 125000, -}; - -/* OMAP54xx ES2.0 data */ -/* TODO : Need to update the slope/constant for ES2.0 silicon */ -const struct omap_bandgap_data omap5430_data = { - .features = OMAP_BANDGAP_FEATURE_TSHUT_CONFIG | - OMAP_BANDGAP_FEATURE_FREEZE_BIT | - OMAP_BANDGAP_FEATURE_TALERT, - .fclock_name = "l3instr_ts_gclk_div", - .div_ck_name = "l3instr_ts_gclk_div", - .conv_table = omap5430_adc_to_temp, - .expose_sensor = omap_thermal_expose_sensor, - .remove_sensor = omap_thermal_remove_sensor, - .sensors = { - { - .registers = &omap5430_mpu_temp_sensor_registers, - .ts_data = &omap5430_mpu_temp_sensor_data, - .domain = "cpu", - .register_cooling = omap_thermal_register_cpu_cooling, - .unregister_cooling = omap_thermal_unregister_cpu_cooling, - .slope = OMAP_GRADIENT_SLOPE_5430_CPU, - .constant = OMAP_GRADIENT_CONST_5430_CPU, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU, - }, - { - .registers = &omap5430_gpu_temp_sensor_registers, - .ts_data = &omap5430_gpu_temp_sensor_data, - .domain = "gpu", - .slope = OMAP_GRADIENT_SLOPE_5430_GPU, - .constant = OMAP_GRADIENT_CONST_5430_GPU, - .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU, - .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU, - }, - { - .registers = &omap5430_core_temp_sensor_registers, - .ts_data = &omap5430_core_temp_sensor_data, - .domain = "core", - }, - }, - .sensor_count = 3, -}; -- cgit From f1d07f33321d10d92ab74fdab0340c1f14c106a4 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 26 Feb 2013 18:53:38 -0400 Subject: staging: omap-thermal: update clock prepare count This patch changes the clock management code to also update the clock prepare counter, this way we won't skip the enable/disable operation due to prepare dependencies. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 83f74f496017..d4a37880f1de 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -943,7 +943,7 @@ int omap_bandgap_probe(struct platform_device *pdev) bg_ptr->clk_rate = clk_rate; if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) - clk_enable(bg_ptr->fclock); + clk_prepare_enable(bg_ptr->fclock); mutex_init(&bg_ptr->bg_mutex); @@ -1013,7 +1013,7 @@ int omap_bandgap_probe(struct platform_device *pdev) disable_clk: if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) - clk_disable(bg_ptr->fclock); + clk_disable_unprepare(bg_ptr->fclock); put_clks: clk_put(bg_ptr->fclock); clk_put(bg_ptr->div_clk); @@ -1044,7 +1044,7 @@ int omap_bandgap_remove(struct platform_device *pdev) omap_bandgap_power(bg_ptr, false); if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) - clk_disable(bg_ptr->fclock); + clk_disable_unprepare(bg_ptr->fclock); clk_put(bg_ptr->fclock); clk_put(bg_ptr->div_clk); @@ -1143,7 +1143,7 @@ static int omap_bandgap_suspend(struct device *dev) omap_bandgap_power(bg_ptr, false); if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) - clk_disable(bg_ptr->fclock); + clk_disable_unprepare(bg_ptr->fclock); return err; } @@ -1153,7 +1153,7 @@ static int omap_bandgap_resume(struct device *dev) struct omap_bandgap *bg_ptr = dev_get_drvdata(dev); if (OMAP_BANDGAP_HAS(bg_ptr, CLK_CTRL)) - clk_enable(bg_ptr->fclock); + clk_prepare_enable(bg_ptr->fclock); omap_bandgap_power(bg_ptr, true); -- cgit From 3009891c9f19d4e9d75941f7400656782e452baf Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Thu, 28 Feb 2013 20:04:01 +0100 Subject: rtl8712: remove unused functions from rtl871x_recv.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niklas Söderlund Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_recv.h | 74 ---------------------------------- 1 file changed, 74 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index e42e6f0a15e6..2d24b1a3ce65 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -150,11 +150,6 @@ static inline u8 *get_rxmem(union recv_frame *precvframe) return precvframe->u.hdr.rx_head; } -static inline u8 *get_rx_status(union recv_frame *precvframe) -{ - return get_rxmem(precvframe); -} - static inline u8 *get_recvframe_data(union recv_frame *precvframe) { /* always return rx_data */ @@ -163,28 +158,6 @@ static inline u8 *get_recvframe_data(union recv_frame *precvframe) return precvframe->u.hdr.rx_data; } -static inline u8 *recvframe_push(union recv_frame *precvframe, sint sz) -{ - /* append data before rx_data */ - - /* add data to the start of recv_frame - * - * This function extends the used data area of the recv_frame at the - * buffer start. rx_data must be still larger than rx_head, after - * pushing. - */ - - if (precvframe == NULL) - return NULL; - precvframe->u.hdr.rx_data -= sz ; - if (precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head) { - precvframe->u.hdr.rx_data += sz ; - return NULL; - } - precvframe->u.hdr.len += sz; - return precvframe->u.hdr.rx_data; -} - static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz) { /* used for extract sz bytes from rx_data, update rx_data and return @@ -236,53 +209,6 @@ static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) return precvframe->u.hdr.rx_tail; } -static inline _buffer *get_rxbuf_desc(union recv_frame *precvframe) -{ - _buffer *buf_desc; - if (precvframe == NULL) - return NULL; - return buf_desc; -} - -static inline union recv_frame *rxmem_to_recvframe(u8 *rxmem) -{ - /* due to the design of 2048 bytes alignment of recv_frame, we can - * reference the union recv_frame from any given member of recv_frame. - * rxmem indicates the any member/address in recv_frame */ - return (union recv_frame *)(((addr_t)rxmem >> RXFRAME_ALIGN) << - RXFRAME_ALIGN); -} - -static inline union recv_frame *pkt_to_recvframe(_pkt *pkt) -{ - u8 *buf_star; - union recv_frame *precv_frame; - - precv_frame = rxmem_to_recvframe((unsigned char *)buf_star); - return precv_frame; -} - -static inline u8 *pkt_to_recvmem(_pkt *pkt) -{ - /* return the rx_head */ - union recv_frame *precv_frame = pkt_to_recvframe(pkt); - - return precv_frame->u.hdr.rx_head; -} - -static inline u8 *pkt_to_recvdata(_pkt *pkt) -{ - /* return the rx_data */ - union recv_frame *precv_frame = pkt_to_recvframe(pkt); - - return precv_frame->u.hdr.rx_data; -} - -static inline sint get_recvframe_len(union recv_frame *precvframe) -{ - return precvframe->u.hdr.len; -} - struct sta_info; void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); -- cgit From d3bb3c1b25e1ef79f22da62f12df02ba6c50a778 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Thu, 28 Feb 2013 20:04:02 +0100 Subject: rtl8712: remove dead function prototypes from rtl871x_recv.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no implementation of these functions anywhere in the code. Signed-off-by: Niklas Söderlund Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_recv.h | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index 2d24b1a3ce65..ad0a28f49bd4 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -130,15 +130,10 @@ struct sta_recv_priv { /* get a free recv_frame from pfree_recv_queue */ union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue); -union recv_frame *r8712_dequeue_recvframe(struct __queue *queue); -int r8712_enqueue_recvframe(union recv_frame *precvframe, - struct __queue *queue); int r8712_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue); void r8712_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue); -void r8712_init_recvframe(union recv_frame *precvframe, - struct recv_priv *precvpriv); int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe); int recv_func(struct _adapter *padapter, void *pcontext); @@ -218,36 +213,10 @@ union recv_frame *r8712_decryptor(struct _adapter *adapter, union recv_frame *precv_frame); union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter, union recv_frame *precv_frame); -union recv_frame *r8712_recvframe_defrag(struct _adapter *adapter, - struct __queue *defrag_q); -union recv_frame *r8712_recvframe_chk_defrag_new(struct _adapter *adapter, - union recv_frame *precv_frame); -union recv_frame *r8712_recvframe_defrag_new(struct _adapter *adapter, - struct __queue *defrag_q, - union recv_frame *precv_frame); -int r8712_recv_decache(union recv_frame *precv_frame, u8 bretry, - struct stainfo_rxcache *prxcache); -int r8712_sta2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta); -int r8712_ap2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta); -int r8712_sta2ap_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta); -int r8712_validate_recv_ctrl_frame(struct _adapter *adapter, - union recv_frame *precv_frame); -int r8712_validate_recv_mgnt_frame(struct _adapter *adapter, - union recv_frame *precv_frame); -int r8712_validate_recv_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame); int r8712_validate_recv_frame(struct _adapter *adapter, union recv_frame *precv_frame); union recv_frame *r8712_portctrl(struct _adapter *adapter, union recv_frame *precv_frame); -void r8712_mgt_dispatcher(struct _adapter *padapter, u8 *pframe, uint len); -int r8712_amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe); #endif -- cgit From eb79b3e1f05193dcbd5aadf1b669b9ff367fd109 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Thu, 28 Feb 2013 20:04:03 +0100 Subject: rtl8712: remove unused definitions from rtl871x_recv.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niklas Söderlund Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_recv.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index ad0a28f49bd4..92ca8997e5bc 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -9,9 +9,6 @@ #define RXFRAME_ALIGN 8 #define RXFRAME_ALIGN_SZ (1 << RXFRAME_ALIGN) -#define MAX_RXFRAME_CNT 512 -#define MAX_RX_NUMBLKS (32) -#define RECVFRAME_HDR_ALIGN 128 #define MAX_SUBFRAME_COUNT 64 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) -- cgit From e85b315e2c2a2196ca15f85fa5501f55bb0a46fb Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Wed, 27 Feb 2013 20:40:06 +0100 Subject: rtl8712: remove redundant if statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same result no matter what path is taken. Signed-off-by: Niklas Söderlund Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_led.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index c9eb4b74799b..6cb1a0af5177 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -267,12 +267,8 @@ static void SwLedBlink(struct LED_871x *pLed) LED_BLINK_SLOWLY_INTERVAL); break; case LED_BLINK_WPS: - if (pLed->BlinkingLedState == LED_ON) - _set_timer(&(pLed->BlinkTimer), - LED_BLINK_LONG_INTERVAL); - else - _set_timer(&(pLed->BlinkTimer), - LED_BLINK_LONG_INTERVAL); + _set_timer(&(pLed->BlinkTimer), + LED_BLINK_LONG_INTERVAL); break; default: _set_timer(&(pLed->BlinkTimer), -- cgit From c9cf272b928c3e92c41d9987ddaac1398ba631ef Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 28 Feb 2013 11:46:57 -0800 Subject: staging: dgrp: Drop unnecessary typecast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An unnecessary typecast in dgrp_net_ops.c causes the following build error if compiled with W=1. In function ‘copy_from_user’, inlined from ‘dgrp_net_ioctl’ at drivers/staging/dgrp/dgrp_net_ops.c:3408:21: arch/x86/include/asm/uaccess_32.h:211:26: error: call to ‘copy_from_user_overflow’ declared with attribute error: copy_from_user() buffer size is not provably correct Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_net_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index e6018823b9de..f364e8e1722d 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -3405,7 +3405,7 @@ static long dgrp_net_ioctl(struct file *file, unsigned int cmd, if (size != sizeof(struct link_struct)) return -EINVAL; - if (copy_from_user((void *)(&link), (void __user *) arg, size)) + if (copy_from_user(&link, (void __user *)arg, size)) return -EFAULT; if (link.lk_fast_rate < 9600) -- cgit From b6dd012efc8c785f8dc2441ae21ae48561788821 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sat, 2 Mar 2013 10:45:17 +0900 Subject: staging: csr: csr_time.c: Fix coding style Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_time.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c index f3f4a9c9c67a..01179e46f47d 100644 --- a/drivers/staging/csr/csr_time.c +++ b/drivers/staging/csr/csr_time.c @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ -- cgit From aeac64aac538fde7c11038fc6dd2ef4bec4c39a7 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Fri, 8 Mar 2013 08:47:50 +0800 Subject: staging: zcache: using strlcpy instead of strncpy for NUL terminated string, need alway set '\0' in the end. Signed-off-by: Chen Gang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 7c0fda4106a0..7a6dd966931b 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1688,7 +1689,7 @@ __setup("nocleancacheignorenonactive", no_cleancache_ignore_nonactive); static int __init enable_zcache_compressor(char *s) { - strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ); + strlcpy(zcache_comp_name, s, sizeof(zcache_comp_name)); zcache_enabled = true; return 1; } -- cgit From 451fb7664a590e74122061d3ac773eddb3c73674 Mon Sep 17 00:00:00 2001 From: Changlong Xie Date: Tue, 5 Mar 2013 13:39:39 +0800 Subject: staging: sw_sync: sw_sync_timeline_ops can be static Reported-by: Fengguang Wu Signed-off-by: Changlong Xie Acked-by: Erik Gilling Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index 68025a5401ae..ec7de30ac33e 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -100,7 +100,7 @@ static void sw_sync_pt_value_str(struct sync_pt *sync_pt, snprintf(str, size, "%d", pt->value); } -struct sync_timeline_ops sw_sync_timeline_ops = { +static struct sync_timeline_ops sw_sync_timeline_ops = { .driver_name = "sw_sync", .dup = sw_sync_pt_dup, .has_signaled = sw_sync_pt_has_signaled, @@ -137,7 +137,7 @@ EXPORT_SYMBOL(sw_sync_timeline_inc); */ /* opening sw_sync create a new sync obj */ -int sw_sync_open(struct inode *inode, struct file *file) +static int sw_sync_open(struct inode *inode, struct file *file) { struct sw_sync_timeline *obj; char task_comm[TASK_COMM_LEN]; @@ -153,14 +153,14 @@ int sw_sync_open(struct inode *inode, struct file *file) return 0; } -int sw_sync_release(struct inode *inode, struct file *file) +static int sw_sync_release(struct inode *inode, struct file *file) { struct sw_sync_timeline *obj = file->private_data; sync_timeline_destroy(&obj->obj); return 0; } -long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) +static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg) { int fd = get_unused_fd(); int err; @@ -206,7 +206,7 @@ err: return err; } -long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) +static long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) { u32 value; @@ -218,7 +218,7 @@ long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) return 0; } -long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct sw_sync_timeline *obj = file->private_data; @@ -247,12 +247,12 @@ static struct miscdevice sw_sync_dev = { .fops = &sw_sync_fops, }; -int __init sw_sync_device_init(void) +static int __init sw_sync_device_init(void) { return misc_register(&sw_sync_dev); } -void __exit sw_sync_device_remove(void) +static void __exit sw_sync_device_remove(void) { misc_deregister(&sw_sync_dev); } -- cgit From b8f4ac237e382accd4b30c75043939f7ed9e79a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:53:41 -0700 Subject: staging: comedi: comedi_pci: change the comedi_pci_auto_config() 'context' The comedi_pci_auto_config() function is used to allow the PCI driver (*probe) function to automatically call the comedi driver (*auto_attach). This allows the comedi driver to be part of the PnP process when the PCI device is detected. Currently the comedi_pci_auto_config() always passes a 'context' of '0' to comedi_auto_config(). This makes the 'context' a bit useless. Modify comedi_pci_auto_config() to allow the comedi pci drivers to pass a 'context' from the PCI driver. Make all the comedi pci drivers pass the pci_device_id 'driver_data' as the 'context'. Since none of the comedi pci drivers currently set the 'driver_data' the 'context' will still be '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_pci.c | 6 ++++-- drivers/staging/comedi/comedidev.h | 3 ++- drivers/staging/comedi/drivers/8255_pci.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_035.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1032.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1500.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1516.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1564.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_16xx.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1710.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_2032.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_2200.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3200.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3501.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci6208.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci7x3x.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci8164.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci9111.c | 5 +++-- drivers/staging/comedi/drivers/adl_pci9118.c | 5 +++-- drivers/staging/comedi/drivers/adv_pci1710.c | 5 +++-- drivers/staging/comedi/drivers/adv_pci1723.c | 5 +++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 5 +++-- drivers/staging/comedi/drivers/amplc_dio200.c | 6 +++--- drivers/staging/comedi/drivers/amplc_pc236.c | 5 +++-- drivers/staging/comedi/drivers/amplc_pc263.c | 6 +++--- drivers/staging/comedi/drivers/amplc_pci224.c | 6 +++--- drivers/staging/comedi/drivers/amplc_pci230.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcidas.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcidas64.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcidda.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcimdas.c | 5 +++-- drivers/staging/comedi/drivers/cb_pcimdda.c | 5 +++-- drivers/staging/comedi/drivers/contec_pci_dio.c | 5 +++-- drivers/staging/comedi/drivers/daqboard2000.c | 5 +++-- drivers/staging/comedi/drivers/das08_pci.c | 5 +++-- drivers/staging/comedi/drivers/dt3000.c | 4 ++-- drivers/staging/comedi/drivers/dyna_pci10xx.c | 5 +++-- drivers/staging/comedi/drivers/gsc_hpdi.c | 4 ++-- drivers/staging/comedi/drivers/icp_multi.c | 4 ++-- drivers/staging/comedi/drivers/jr3_pci.c | 4 ++-- drivers/staging/comedi/drivers/ke_counter.c | 5 +++-- drivers/staging/comedi/drivers/me4000.c | 4 ++-- drivers/staging/comedi/drivers/me_daq.c | 4 ++-- drivers/staging/comedi/drivers/ni_6527.c | 4 ++-- drivers/staging/comedi/drivers/ni_65xx.c | 4 ++-- drivers/staging/comedi/drivers/ni_660x.c | 4 ++-- drivers/staging/comedi/drivers/ni_670x.c | 4 ++-- drivers/staging/comedi/drivers/ni_labpc.c | 4 ++-- drivers/staging/comedi/drivers/ni_pcidio.c | 4 ++-- drivers/staging/comedi/drivers/ni_pcimio.c | 4 ++-- drivers/staging/comedi/drivers/rtd520.c | 4 ++-- drivers/staging/comedi/drivers/s626.c | 4 ++-- drivers/staging/comedi/drivers/skel.c | 4 ++-- 55 files changed, 135 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index 37d2e4677360..bf5095601e00 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -72,13 +72,15 @@ EXPORT_SYMBOL_GPL(comedi_pci_disable); * comedi_pci_auto_config() - Configure/probe a comedi PCI driver. * @pcidev: pci_dev struct * @driver: comedi_driver struct + * @context: driver specific data, passed to comedi_auto_config() * * Typically called from the pci_driver (*probe) function. */ int comedi_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver) + struct comedi_driver *driver, + unsigned long context) { - return comedi_auto_config(&pcidev->dev, driver, 0); + return comedi_auto_config(&pcidev->dev, driver, context); } EXPORT_SYMBOL_GPL(comedi_pci_auto_config); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index f3a990b45df5..b8e5d091fff8 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -387,7 +387,8 @@ struct pci_dev *comedi_to_pci_dev(struct comedi_device *); int comedi_pci_enable(struct pci_dev *, const char *); void comedi_pci_disable(struct pci_dev *); -int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *); +int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *, + unsigned long context); void comedi_pci_auto_unconfig(struct pci_dev *); int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 0ae356ae56ea..fa144e304f06 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -311,9 +311,9 @@ static struct comedi_driver pci_8255_driver = { }; static int pci_8255_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &pci_8255_driver); + return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 5a53e58258a0..ea6ddb3d06a3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -50,9 +50,9 @@ static struct comedi_driver apci035_driver = { }; static int apci035_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci035_driver); + return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index c0d0429c35c8..fdd053c61a63 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -373,9 +373,9 @@ static struct comedi_driver apci1032_driver = { }; static int apci1032_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci1032_driver); + return comedi_pci_auto_config(dev, &apci1032_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 9c2f8eeb7977..c945a2aef9e3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -50,9 +50,9 @@ static struct comedi_driver apci1500_driver = { }; static int apci1500_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci1500_driver); + return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 69e399638419..df8f8ea243ff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -235,9 +235,9 @@ static struct comedi_driver apci1516_driver = { }; static int apci1516_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci1516_driver); + return comedi_pci_auto_config(dev, &apci1516_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index ddea64df9180..b2b3bdbb9f30 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -47,9 +47,9 @@ static struct comedi_driver apci1564_driver = { }; static int apci1564_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci1564_driver); + return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index e51f80001363..12ff76a73d8a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -225,9 +225,9 @@ static struct comedi_driver apci16xx_driver = { }; static int apci16xx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci16xx_driver); + return comedi_pci_auto_config(dev, &apci16xx_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index e83e829831b0..f32a79a2afca 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -125,9 +125,9 @@ static struct comedi_driver apci1710_driver = { }; static int apci1710_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci1710_driver); + return comedi_pci_auto_config(dev, &apci1710_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 9ce1d26aff2f..4a33b3502f40 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -374,9 +374,9 @@ static struct comedi_driver apci2032_driver = { }; static int apci2032_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci2032_driver); + return comedi_pci_auto_config(dev, &apci2032_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index b1c4226902e1..48afa2316497 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -150,9 +150,9 @@ static struct comedi_driver apci2200_driver = { }; static int apci2200_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci2200_driver); + return comedi_pci_auto_config(dev, &apci2200_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 917234d24e99..6ecdaab77585 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -248,9 +248,9 @@ static struct comedi_driver apci3120_driver = { }; static int apci3120_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci3120_driver); + return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 90ee4f844f91..a28bcbdffe07 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -103,9 +103,9 @@ static struct comedi_driver apci3200_driver = { }; static int apci3200_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci3200_driver); + return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); } static struct pci_driver apci3200_pci_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 786fcaf82c32..ecd54ea6f8de 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -443,9 +443,9 @@ static struct comedi_driver apci3501_driver = { }; static int apci3501_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci3501_driver); + return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 09d4b21fce23..96ec65b2678e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -748,9 +748,9 @@ static struct comedi_driver apci3xxx_driver = { }; static int apci3xxx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &apci3xxx_driver); + return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 7b3e331616ed..b8f0efcec0f7 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -267,9 +267,10 @@ static struct comedi_driver adl_pci6208_driver = { }; static int adl_pci6208_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adl_pci6208_driver); + return comedi_pci_auto_config(dev, &adl_pci6208_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index f27f48e6e702..b8dd161136aa 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -293,9 +293,10 @@ static struct comedi_driver adl_pci7x3x_driver = { }; static int adl_pci7x3x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adl_pci7x3x_driver); + return comedi_pci_auto_config(dev, &adl_pci7x3x_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index d06b83f38653..4126f733d34d 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -295,9 +295,10 @@ static struct comedi_driver adl_pci8164_driver = { }; static int adl_pci8164_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adl_pci8164_driver); + return comedi_pci_auto_config(dev, &adl_pci8164_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index eeb10ec7f178..8680cf18b7de 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -959,9 +959,10 @@ static struct comedi_driver adl_pci9111_driver = { }; static int pci9111_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adl_pci9111_driver); + return comedi_pci_auto_config(dev, &adl_pci9111_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4dbac7459a48..a0277a83115d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2222,9 +2222,10 @@ static struct comedi_driver adl_pci9118_driver = { }; static int adl_pci9118_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adl_pci9118_driver); + return comedi_pci_auto_config(dev, &adl_pci9118_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 3d788c76d648..7f04f8bae987 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1398,9 +1398,10 @@ static struct comedi_driver adv_pci1710_driver = { }; static int adv_pci1710_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adv_pci1710_driver); + return comedi_pci_auto_config(dev, &adv_pci1710_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 02ce55a01d2a..bd95b1d4338a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -324,9 +324,10 @@ static struct comedi_driver adv_pci1723_driver = { }; static int adv_pci1723_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adv_pci1723_driver); + return comedi_pci_auto_config(dev, &adv_pci1723_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adv_pci1723_pci_table) = { diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 338c43e716ba..45e0b3719b8e 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1202,9 +1202,10 @@ static struct comedi_driver adv_pci_dio_driver = { }; static int adv_pci_dio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adv_pci_dio_driver); + return comedi_pci_auto_config(dev, &adv_pci_dio_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 7c53dea12c76..82f80d563fbe 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -2070,10 +2070,10 @@ static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { MODULE_DEVICE_TABLE(pci, dio200_pci_table); static int amplc_dio200_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &lc_dio200_driver); + return comedi_pci_auto_config(dev, &lc_dio200_driver, + id->driver_data); } static struct pci_driver amplc_dio200_pci_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 479e10fddd22..b6bba4d15a5a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -610,9 +610,10 @@ static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { MODULE_DEVICE_TABLE(pci, pc236_pci_table); static int amplc_pc236_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &lc_pc236_driver); + return comedi_pci_auto_config(dev, &lc_pc236_driver, + id->driver_data); } static struct pci_driver amplc_pc236_pci_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 11c1f4764eac..e61d55679a77 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -368,10 +368,10 @@ static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { MODULE_DEVICE_TABLE(pci, pc263_pci_table); static int amplc_pc263_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &lc_pc263_driver); + return comedi_pci_auto_config(dev, &lc_pc263_driver, + id->driver_data); } static struct pci_driver amplc_pc263_pci_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index c9da4cd74baa..4a56468cb7ba 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1507,10 +1507,10 @@ static struct comedi_driver amplc_pci224_driver = { }; static int amplc_pci224_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &lc_pci224_driver); + return comedi_pci_auto_config(dev, &lc_pci224_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = { diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index e2244c6e536b..70074b512130 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2859,9 +2859,10 @@ static struct comedi_driver amplc_pci230_driver = { }; static int amplc_pci230_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &lc_pci230_driver); + return comedi_pci_auto_config(dev, &lc_pci230_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = { diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 79c72118a090..425a5a18a787 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1629,9 +1629,10 @@ static struct comedi_driver cb_pcidas_driver = { }; static int cb_pcidas_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &cb_pcidas_driver); + return comedi_pci_auto_config(dev, &cb_pcidas_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 9f3112cb7a21..c085e1d80d46 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4216,9 +4216,10 @@ static struct comedi_driver cb_pcidas64_driver = { }; static int cb_pcidas64_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &cb_pcidas64_driver); + return comedi_pci_auto_config(dev, &cb_pcidas64_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index e2cadc728455..f00d85732d0d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -435,9 +435,10 @@ static struct comedi_driver cb_pcidda_driver = { }; static int cb_pcidda_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &cb_pcidda_driver); + return comedi_pci_auto_config(dev, &cb_pcidda_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index aae063ca85a0..7d456ad2aad4 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -295,9 +295,10 @@ static struct comedi_driver cb_pcimdas_driver = { }; static int cb_pcimdas_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &cb_pcimdas_driver); + return comedi_pci_auto_config(dev, &cb_pcimdas_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 63cfbaf3a3fe..5db4f4ada463 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -219,9 +219,10 @@ static struct comedi_driver cb_pcimdda_driver = { }; static int cb_pcimdda_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &cb_pcimdda_driver); + return comedi_pci_auto_config(dev, &cb_pcimdda_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 182dea669ef2..d6597445aae8 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -127,9 +127,10 @@ static struct comedi_driver contec_pci_dio_driver = { }; static int contec_pci_dio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &contec_pci_dio_driver); + return comedi_pci_auto_config(dev, &contec_pci_dio_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 50b450f09c65..42e13e30d502 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -795,9 +795,10 @@ static struct comedi_driver daqboard2000_driver = { }; static int daqboard2000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &daqboard2000_driver); + return comedi_pci_auto_config(dev, &daqboard2000_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index c405876ddcf7..ecab0c4f70f2 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -97,9 +97,10 @@ static struct comedi_driver das08_pci_comedi_driver = { }; static int das08_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &das08_pci_comedi_driver); + return comedi_pci_auto_config(dev, &das08_pci_comedi_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 3ce499fa5dbf..6862e7f8ed04 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -853,9 +853,9 @@ static struct comedi_driver dt3000_driver = { }; static int dt3000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &dt3000_driver); + return comedi_pci_auto_config(dev, &dt3000_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index decc17f1867e..58ff129a8339 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -273,9 +273,10 @@ static struct comedi_driver dyna_pci10xx_driver = { }; static int dyna_pci10xx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &dyna_pci10xx_driver); + return comedi_pci_auto_config(dev, &dyna_pci10xx_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index b60c97562676..a18d897606f8 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -943,9 +943,9 @@ static struct comedi_driver gsc_hpdi_driver = { }; static int gsc_hpdi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &gsc_hpdi_driver); + return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(gsc_hpdi_pci_table) = { diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 1e08f9141fad..8722defde22f 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -618,9 +618,9 @@ static struct comedi_driver icp_multi_driver = { }; static int icp_multi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &icp_multi_driver); + return comedi_pci_auto_config(dev, &icp_multi_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(icp_multi_pci_table) = { diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 17ba75e0ab89..aea940121c58 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -841,9 +841,9 @@ static struct comedi_driver jr3_pci_driver = { }; static int jr3_pci_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &jr3_pci_driver); + return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 8c09c026508a..ac40e355dff2 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -149,9 +149,10 @@ static struct comedi_driver ke_counter_driver = { }; static int ke_counter_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ke_counter_driver); + return comedi_pci_auto_config(dev, &ke_counter_driver, + id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ke_counter_pci_table) = { diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b766bb93efd6..9f09e1969911 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1730,9 +1730,9 @@ static struct comedi_driver me4000_driver = { }; static int me4000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &me4000_driver); + return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 06490ebc8cc8..58ba9e322624 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -616,9 +616,9 @@ static struct comedi_driver me_daq_driver = { }; static int me_daq_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &me_daq_driver); + return comedi_pci_auto_config(dev, &me_daq_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = { diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index bcd4df290ec4..507c1216461b 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -449,9 +449,9 @@ static struct comedi_driver ni6527_driver = { }; static int ni6527_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni6527_driver); + return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data); } static struct pci_driver ni6527_pci_driver = { diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index bfa790ecf41d..ded8d9e5d9ba 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -785,9 +785,9 @@ static struct comedi_driver ni_65xx_driver = { }; static int ni_65xx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_65xx_driver); + return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data); } static struct pci_driver ni_65xx_pci_driver = { diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index e46dd7a1a724..cf05d665ba9e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1325,9 +1325,9 @@ static struct comedi_driver ni_660x_driver = { }; static int ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_660x_driver); + return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 2faf86c83dc5..e60e1ba358d6 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -306,9 +306,9 @@ static struct comedi_driver ni_670x_driver = { }; static int ni_670x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_670x_driver); + return comedi_pci_auto_config(dev, &ni_670x_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index f957b8859b3d..d386c3e2b976 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -2113,9 +2113,9 @@ static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { MODULE_DEVICE_TABLE(pci, labpc_pci_table); static int labpc_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &labpc_driver); + return comedi_pci_auto_config(dev, &labpc_driver, id->driver_data); } static struct pci_driver labpc_pci_driver = { diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 0a00260d11f3..f4d3fab6f2d5 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1221,9 +1221,9 @@ static struct comedi_driver ni_pcidio_driver = { }; static int ni_pcidio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_pcidio_driver); + return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 98b43f2fc65d..e626ac046b7f 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1788,9 +1788,9 @@ static struct comedi_driver ni_pcimio_driver = { }; static int ni_pcimio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_pcimio_driver); + return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = { diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 6a5c914fa501..8b72edf3cad1 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1416,9 +1416,9 @@ static struct comedi_driver rtd520_driver = { }; static int rtd520_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &rtd520_driver); + return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 81a1fe661579..4fec6d6a04ab 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2832,9 +2832,9 @@ static struct comedi_driver s626_driver = { }; static int s626_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &s626_driver); + return comedi_pci_auto_config(dev, &s626_driver, id->driver_data); } /* diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index cb83f6ae48b9..8cedc4cf020c 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -702,9 +702,9 @@ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { MODULE_DEVICE_TABLE(pci, skel_pci_table); static int skel_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &skel_driver); + return comedi_pci_auto_config(dev, &skel_driver, id->driver_data); } static struct pci_driver skel_pci_driver = { -- cgit From af48bd8ccece2c2605ea8cc4e4b69a916ec277f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:54:58 -0700 Subject: staging: comedi: 8255_pci: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'vendor' and 'device' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 156 ++++++++++++------------------ 1 file changed, 61 insertions(+), 95 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index fa144e304f06..7e25500cd996 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -60,124 +60,104 @@ Configuration Options: not applicable, uses PCI auto config #include "8255.h" -/* - * PCI Device ID's supported by this driver - */ -#define PCI_DEVICE_ID_ADLINK_PCI7224 0x7224 -#define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248 -#define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296 - -#define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b -#define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014 -#define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017 -#define PCI_DEVICE_ID_CB_PCIDIO24 0x0028 - -#define PCI_DEVICE_ID_NI_PCIDIO96 0x0160 -#define PCI_DEVICE_ID_NI_PCI6503 0x0400 -#define PCI_DEVICE_ID_NI_PCI6503B 0x1250 -#define PCI_DEVICE_ID_NI_PXI6508 0x13c0 -#define PCI_DEVICE_ID_NI_PCIDIO96B 0x1630 -#define PCI_DEVICE_ID_NI_PCI6503X 0x17d0 -#define PCI_DEVICE_ID_NI_PXI_6503 0x1800 +enum pci_8255_boardid { + BOARD_ADLINK_PCI7224, + BOARD_ADLINK_PCI7248, + BOARD_ADLINK_PCI7296, + BOARD_CB_PCIDIO24, + BOARD_CB_PCIDIO24H, + BOARD_CB_PCIDIO48H, + BOARD_CB_PCIDIO96H, + BOARD_NI_PCIDIO96, + BOARD_NI_PCIDIO96B, + BOARD_NI_PXI6508, + BOARD_NI_PCI6503, + BOARD_NI_PCI6503B, + BOARD_NI_PCI6503X, + BOARD_NI_PXI_6503, +}; struct pci_8255_boardinfo { const char *name; - unsigned short vendor; - unsigned short device; int dio_badr; int is_mmio; int n_8255; }; static const struct pci_8255_boardinfo pci_8255_boards[] = { - { + [BOARD_ADLINK_PCI7224] = { .name = "adl_pci-7224", - .vendor = PCI_VENDOR_ID_ADLINK, - .device = PCI_DEVICE_ID_ADLINK_PCI7224, .dio_badr = 2, .n_8255 = 1, - }, { + }, + [BOARD_ADLINK_PCI7248] = { .name = "adl_pci-7248", - .vendor = PCI_VENDOR_ID_ADLINK, - .device = PCI_DEVICE_ID_ADLINK_PCI7248, .dio_badr = 2, .n_8255 = 2, - }, { + }, + [BOARD_ADLINK_PCI7296] = { .name = "adl_pci-7296", - .vendor = PCI_VENDOR_ID_ADLINK, - .device = PCI_DEVICE_ID_ADLINK_PCI7296, .dio_badr = 2, .n_8255 = 4, - }, { + }, + [BOARD_CB_PCIDIO24] = { .name = "cb_pci-dio24", - .vendor = PCI_VENDOR_ID_CB, - .device = PCI_DEVICE_ID_CB_PCIDIO24, .dio_badr = 2, .n_8255 = 1, - }, { + }, + [BOARD_CB_PCIDIO24H] = { .name = "cb_pci-dio24h", - .vendor = PCI_VENDOR_ID_CB, - .device = PCI_DEVICE_ID_CB_PCIDIO24H, .dio_badr = 2, .n_8255 = 1, - }, { + }, + [BOARD_CB_PCIDIO48H] = { .name = "cb_pci-dio48h", - .vendor = PCI_VENDOR_ID_CB, - .device = PCI_DEVICE_ID_CB_PCIDIO48H, .dio_badr = 1, .n_8255 = 2, - }, { + }, + [BOARD_CB_PCIDIO96H] = { .name = "cb_pci-dio96h", - .vendor = PCI_VENDOR_ID_CB, - .device = PCI_DEVICE_ID_CB_PCIDIO96H, .dio_badr = 2, .n_8255 = 4, - }, { + }, + [BOARD_NI_PCIDIO96] = { .name = "ni_pci-dio-96", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PCIDIO96, .dio_badr = 1, .is_mmio = 1, .n_8255 = 4, - }, { + }, + [BOARD_NI_PCIDIO96B] = { .name = "ni_pci-dio-96b", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PCIDIO96B, .dio_badr = 1, .is_mmio = 1, .n_8255 = 4, - }, { + }, + [BOARD_NI_PXI6508] = { .name = "ni_pxi-6508", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PXI6508, .dio_badr = 1, .is_mmio = 1, .n_8255 = 4, - }, { + }, + [BOARD_NI_PCI6503] = { .name = "ni_pci-6503", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PCI6503, .dio_badr = 1, .is_mmio = 1, .n_8255 = 1, - }, { + }, + [BOARD_NI_PCI6503B] = { .name = "ni_pci-6503b", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PCI6503B, .dio_badr = 1, .is_mmio = 1, .n_8255 = 1, - }, { + }, + [BOARD_NI_PCI6503X] = { .name = "ni_pci-6503x", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PCI6503X, .dio_badr = 1, .is_mmio = 1, .n_8255 = 1, - }, { + }, + [BOARD_NI_PXI_6503] = { .name = "ni_pxi-6503", - .vendor = PCI_VENDOR_ID_NI, - .device = PCI_DEVICE_ID_NI_PXI_6503, .dio_badr = 1, .is_mmio = 1, .n_8255 = 1, @@ -200,26 +180,11 @@ static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase) } } -static const void *pci_8255_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct pci_8255_boardinfo *board; - int i; - - for (i = 0; i < ARRAY_SIZE(pci_8255_boards); i++) { - board = &pci_8255_boards[i]; - if (pcidev->vendor == board->vendor && - pcidev->device == board->device) - return board; - } - return NULL; -} - static int pci_8255_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct pci_8255_boardinfo *board; + const struct pci_8255_boardinfo *board = NULL; struct pci_8255_private *devpriv; struct comedi_subdevice *s; resource_size_t iobase; @@ -227,7 +192,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev, int ret; int i; - board = pci_8255_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(pci_8255_boards)) + board = &pci_8255_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; @@ -317,20 +283,20 @@ static int pci_8255_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7224) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7248) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7296) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO96H) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96B) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI6508) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503B) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503X) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI_6503) }, + { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 }, + { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 }, + { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 }, + { PCI_VDEVICE(CB, 0x0028), BOARD_CB_PCIDIO24 }, + { PCI_VDEVICE(CB, 0x0014), BOARD_CB_PCIDIO24H }, + { PCI_VDEVICE(CB, 0x000b), BOARD_CB_PCIDIO48H }, + { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H }, + { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 }, + { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B }, + { PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 }, + { PCI_VDEVICE(NI, 0x0400), BOARD_NI_PCI6503 }, + { PCI_VDEVICE(NI, 0x1250), BOARD_NI_PCI6503B }, + { PCI_VDEVICE(NI, 0x17d0), BOARD_NI_PCI6503X }, + { PCI_VDEVICE(NI, 0x1800), BOARD_NI_PXI_6503 }, { 0 } }; MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); -- cgit From 852f3378497265783e8a629cf3aa985f30be213d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:56:06 -0700 Subject: staging: comedi: addi_apci_1516: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 52 +++++++++---------------- 1 file changed, 18 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index df8f8ea243ff..0319315ba9bd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -35,13 +35,6 @@ #include "addi_watchdog.h" #include "comedi_fc.h" -/* - * PCI device ids supported by this driver - */ -#define PCI_DEVICE_ID_APCI1016 0x1000 -#define PCI_DEVICE_ID_APCI1516 0x1001 -#define PCI_DEVICE_ID_APCI2016 0x1002 - /* * PCI bar 1 I/O Register map - Digital input/output */ @@ -53,28 +46,32 @@ */ #define APCI1516_WDOG_REG 0x00 +enum apci1516_boardid { + BOARD_APCI1016, + BOARD_APCI1516, + BOARD_APCI2016, +}; + struct apci1516_boardinfo { const char *name; - unsigned short device; int di_nchan; int do_nchan; int has_wdog; }; static const struct apci1516_boardinfo apci1516_boardtypes[] = { - { + [BOARD_APCI1016] = { .name = "apci1016", - .device = PCI_DEVICE_ID_APCI1016, .di_nchan = 16, - }, { + }, + [BOARD_APCI1516] = { .name = "apci1516", - .device = PCI_DEVICE_ID_APCI1516, .di_nchan = 8, .do_nchan = 8, .has_wdog = 1, - }, { + }, + [BOARD_APCI2016] = { .name = "apci2016", - .device = PCI_DEVICE_ID_APCI2016, .do_nchan = 16, .has_wdog = 1, }, @@ -130,30 +127,17 @@ static int apci1516_reset(struct comedi_device *dev) return 0; } -static const void *apci1516_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct apci1516_boardinfo *this_board; - int i; - - for (i = 0; i < dev->driver->num_names; i++) { - this_board = &apci1516_boardtypes[i]; - if (this_board->device == pcidev->device) - return this_board; - } - return NULL; -} - static int apci1516_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct apci1516_boardinfo *this_board; + const struct apci1516_boardinfo *this_board = NULL; struct apci1516_private *devpriv; struct comedi_subdevice *s; int ret; - this_board = apci1516_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(apci1516_boardtypes)) + this_board = &apci1516_boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -241,9 +225,9 @@ static int apci1516_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1016) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1516) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI2016) }, + { PCI_VDEVICE(ADDIDATA, 0x1000), BOARD_APCI1016 }, + { PCI_VDEVICE(ADDIDATA, 0x1001), BOARD_APCI1516 }, + { PCI_VDEVICE(ADDIDATA, 0x1002), BOARD_APCI2016 }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci1516_pci_table); -- cgit From a4732f354487ba42ad3dc22dbdab33a3137e6041 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:56:51 -0700 Subject: staging: comedi: addi_apci_16xx: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'vendor' and 'device' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_16xx.c | 48 ++++++++----------------- 1 file changed, 14 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 12ff76a73d8a..4117de96994f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -33,12 +33,6 @@ #include "../comedidev.h" -/* - * PCI device ids supported by this driver - */ -#define PCI_DEVICE_ID_APCI1648 0x1009 -#define PCI_DEVICE_ID_APCI1696 0x100a - /* * Register I/O map */ @@ -46,23 +40,23 @@ #define APCI16XX_OUT_REG(x) (((x) * 4) + 0x14) #define APCI16XX_DIR_REG(x) (((x) * 4) + 0x20) +enum apci16xx_boardid { + BOARD_APCI1648, + BOARD_APCI1696, +}; + struct apci16xx_boardinfo { const char *name; - unsigned short vendor; - unsigned short device; int n_chan; }; static const struct apci16xx_boardinfo apci16xx_boardtypes[] = { - { + [BOARD_APCI1648] = { .name = "apci1648", - .vendor = PCI_VENDOR_ID_ADDIDATA, - .device = PCI_DEVICE_ID_APCI1648, .n_chan = 48, /* 2 subdevices */ - }, { + }, + [BOARD_APCI1696] = { .name = "apci1696", - .vendor = PCI_VENDOR_ID_ADDIDATA, - .device = PCI_DEVICE_ID_APCI1696, .n_chan = 96, /* 3 subdevices */ }, }; @@ -130,33 +124,19 @@ static int apci16xx_dio_insn_bits(struct comedi_device *dev, return insn->n; } -static const void *apci16xx_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct apci16xx_boardinfo *board; - int i; - - for (i = 0; i < ARRAY_SIZE(apci16xx_boardtypes); i++) { - board = &apci16xx_boardtypes[i]; - if (board->vendor == pcidev->vendor && - board->device == pcidev->device) - return board; - } - return NULL; -} - static int apci16xx_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct apci16xx_boardinfo *board; + const struct apci16xx_boardinfo *board = NULL; struct comedi_subdevice *s; unsigned int n_subdevs; unsigned int last; int i; int ret; - board = apci16xx_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(apci16xx_boardtypes)) + board = &apci16xx_boardtypes[context]; if (!board) return -ENODEV; dev->board_ptr = board; @@ -231,8 +211,8 @@ static int apci16xx_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1648) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1696) }, + { PCI_VDEVICE(ADDIDATA, 0x1009), BOARD_APCI1648 }, + { PCI_VDEVICE(ADDIDATA, 0x100a), BOARD_APCI1696 }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci16xx_pci_table); -- cgit From 5e7479f1d88024669b2ab909a5bb4a74fb9df8e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:57:26 -0700 Subject: staging: comedi: addi_apci_16xx: remove the boardinfo from the comedi_driver This driver uses the comedi auto attach mechanism and does not need to supply the 'num_names', 'board_name', and 'offset' fields so that the comedi core can search the boardinfo. These fields are only used for the legacy attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_16xx.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 4117de96994f..8aca57f8590a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -199,9 +199,6 @@ static struct comedi_driver apci16xx_driver = { .module = THIS_MODULE, .auto_attach = apci16xx_auto_attach, .detach = apci16xx_detach, - .num_names = ARRAY_SIZE(apci16xx_boardtypes), - .board_name = &apci16xx_boardtypes[0].name, - .offset = sizeof(struct apci16xx_boardinfo), }; static int apci16xx_pci_probe(struct pci_dev *dev, -- cgit From 1df0e5b0ca97e2aeaa2be8241ea840f06b4dabfa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:58:01 -0700 Subject: staging: comedi: addi_apci_3120: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'i_VendorId' and 'i_DeviceId' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 40 +++++++++---------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6ecdaab77585..07bcb388fc5f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -8,11 +8,14 @@ #include "addi-data/hwdrv_apci3120.c" +enum apci3120_boardid { + BOARD_APCI3120, + BOARD_APCI3001, +}; + static const struct addi_board apci3120_boardtypes[] = { - { + [BOARD_APCI3120] = { .pc_DriverName = "apci3120", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x818D, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -23,10 +26,9 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .interrupt = v_APCI3120_Interrupt, - }, { + }, + [BOARD_APCI3001] = { .pc_DriverName = "apci3001", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x828D, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -47,31 +49,17 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static const void *apci3120_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct addi_board *this_board; - int i; - - for (i = 0; i < ARRAY_SIZE(apci3120_boardtypes); i++) { - this_board = &apci3120_boardtypes[i]; - if (this_board->i_VendorId == pcidev->vendor && - this_board->i_DeviceId == pcidev->device) - return this_board; - } - return NULL; -} - static int apci3120_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board; + const struct addi_board *this_board = NULL; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i; - this_board = apci3120_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(apci3120_boardtypes)) + this_board = &apci3120_boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -254,8 +242,8 @@ static int apci3120_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, + { PCI_VDEVICE(ADDIDATA_OLD, 0x818d), BOARD_APCI3120 }, + { PCI_VDEVICE(ADDIDATA_OLD, 0x828d), BOARD_APCI3001 }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci3120_pci_table); -- cgit From 5e42525df0a7a1262069d433b1015d0cf2107cb1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:58:25 -0700 Subject: staging: comedi: adl_pci6208: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci6208.c | 44 +++++++++------------------- 1 file changed, 14 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index b8f0efcec0f7..49f82f48bf09 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -46,12 +46,6 @@ References: #include "../comedidev.h" -/* - * ADLINK PCI Device ID's supported by this driver - */ -#define PCI_DEVICE_ID_PCI6208 0x6208 -#define PCI_DEVICE_ID_PCI6216 0x6216 - /* * PCI-6208/6216-GL register map */ @@ -66,20 +60,23 @@ References: #define PCI6208_MAX_AO_CHANNELS 16 +enum pci6208_boardid { + BOARD_PCI6208, + BOARD_PCI6216, +}; + struct pci6208_board { const char *name; - unsigned short dev_id; int ao_chans; }; static const struct pci6208_board pci6208_boards[] = { - { + [BOARD_PCI6208] = { .name = "adl_pci6208", - .dev_id = PCI_DEVICE_ID_PCI6208, .ao_chans = 8, - }, { + }, + [BOARD_PCI6216] = { .name = "adl_pci6216", - .dev_id = PCI_DEVICE_ID_PCI6216, .ao_chans = 16, }, }; @@ -162,31 +159,18 @@ static int pci6208_do_insn_bits(struct comedi_device *dev, return insn->n; } -static const void *pci6208_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct pci6208_board *boardinfo; - int i; - - for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) { - boardinfo = &pci6208_boards[i]; - if (boardinfo->dev_id == pcidev->device) - return boardinfo; - } - return NULL; -} - static int pci6208_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct pci6208_board *boardinfo; + const struct pci6208_board *boardinfo = NULL; struct pci6208_private *devpriv; struct comedi_subdevice *s; unsigned int val; int ret; - boardinfo = pci6208_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(pci6208_boards)) + boardinfo = &pci6208_boards[context]; if (!boardinfo) return -ENODEV; dev->board_ptr = boardinfo; @@ -274,8 +258,8 @@ static int adl_pci6208_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6208) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6216) }, + { PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 }, + { PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 }, { 0 } }; MODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table); -- cgit From b5357e6111b6400852ce1d47c11cc9325d68bd02 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:59:07 -0700 Subject: staging: comedi: adl_pci7x3x: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci7x3x.c | 76 +++++++++++----------------- 1 file changed, 30 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index b8dd161136aa..70f8c93ef7ad 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -52,61 +52,58 @@ Configuration Options: not applicable, uses comedi PCI auto config #include "../comedidev.h" -/* - * PCI Device ID's supported by this driver - */ -#define PCI_DEVICE_ID_PCI7230 0x7230 -#define PCI_DEVICE_ID_PCI7233 0x7233 -#define PCI_DEVICE_ID_PCI7234 0x7234 -#define PCI_DEVICE_ID_PCI7432 0x7432 -#define PCI_DEVICE_ID_PCI7433 0x7433 -#define PCI_DEVICE_ID_PCI7434 0x7434 - /* * Register I/O map (32-bit access only) */ #define PCI7X3X_DIO_REG 0x00 #define PCI743X_DIO_REG 0x04 +enum apci1516_boardid { + BOARD_PCI7230, + BOARD_PCI7233, + BOARD_PCI7234, + BOARD_PCI7432, + BOARD_PCI7433, + BOARD_PCI7434, +}; + struct adl_pci7x3x_boardinfo { const char *name; - unsigned short device; int nsubdevs; int di_nchan; int do_nchan; }; static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = { - { + [BOARD_PCI7230] = { .name = "adl_pci7230", - .device = PCI_DEVICE_ID_PCI7230, .nsubdevs = 2, .di_nchan = 16, .do_nchan = 16, - }, { + }, + [BOARD_PCI7233] = { .name = "adl_pci7233", - .device = PCI_DEVICE_ID_PCI7233, .nsubdevs = 1, .di_nchan = 32, - }, { + }, + [BOARD_PCI7234] = { .name = "adl_pci7234", - .device = PCI_DEVICE_ID_PCI7234, .nsubdevs = 1, .do_nchan = 32, - }, { + }, + [BOARD_PCI7432] = { .name = "adl_pci7432", - .device = PCI_DEVICE_ID_PCI7432, .nsubdevs = 2, .di_nchan = 32, .do_nchan = 32, - }, { + }, + [BOARD_PCI7433] = { .name = "adl_pci7433", - .device = PCI_DEVICE_ID_PCI7433, .nsubdevs = 2, .di_nchan = 64, - }, { + }, + [BOARD_PCI7434] = { .name = "adl_pci7434", - .device = PCI_DEVICE_ID_PCI7434, .nsubdevs = 2, .do_nchan = 64, } @@ -150,31 +147,18 @@ static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev, return insn->n; } -static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct adl_pci7x3x_boardinfo *board; - int i; - - for (i = 0; i < ARRAY_SIZE(adl_pci7x3x_boards); i++) { - board = &adl_pci7x3x_boards[i]; - if (pcidev->device == board->device) - return board; - } - return NULL; -} - static int adl_pci7x3x_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct adl_pci7x3x_boardinfo *board; + const struct adl_pci7x3x_boardinfo *board = NULL; struct comedi_subdevice *s; int subdev; int nchan; int ret; - board = adl_pci7x3x_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(adl_pci7x3x_boards)) + board = &adl_pci7x3x_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; @@ -300,12 +284,12 @@ static int adl_pci7x3x_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7233) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7234) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7433) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7434) }, + { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 }, + { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 }, + { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 }, + { PCI_VDEVICE(ADLINK, 0x7432), BOARD_PCI7432 }, + { PCI_VDEVICE(ADLINK, 0x7433), BOARD_PCI7433 }, + { PCI_VDEVICE(ADLINK, 0x7434), BOARD_PCI7434 }, { 0 } }; MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table); -- cgit From 0005fbedc83e7bfb4f8e41aab5530f9a13e9dfc4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:59:29 -0700 Subject: staging: comedi: adv_pci1710: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. The pci1710 and pci1710hg boards have the same vendor/device id so it is impossible to determine which board is actually detected. The boardinfo for the pci1710hg is identical to the pci1710 other than the analog input range information. Remove the pci1710hg information and #if out the range tables for that device with the define USE_PCI1710HG_RANGE. Modify the pci1710 boardinfo accordingly to use the same define to determine which range table to use. Until a better solution is worked out, this will allow the driver to be compiled to support the pci1710 (default) or pci1710hg. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 92 +++++++++++++--------------- 1 file changed, 42 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 7f04f8bae987..e4e78c99af02 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -50,6 +50,17 @@ Configuration options: #include "8253.h" #include "amcc_s5933.h" +/* + * The pci1710 and pci1710hg boards have the same device id! + * + * The only difference between these boards is in the + * supported analog input ranges. + * + * #define this if your card is a pci1710hg and you need the + * correct ranges reported to user space. + */ +#undef USE_PCI1710HG_RANGE + #define PCI171x_PARANOIDCHECK /* if defined, then is used code which control * correct channel number on every 12 bit * sample */ @@ -133,6 +144,7 @@ static const struct comedi_lrange range_pci1710_3 = { 9, { static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 }; +#ifdef USE_PCI1710HG_RANGE static const struct comedi_lrange range_pci1710hg = { 12, { BIP_RANGE(5), BIP_RANGE(0.5), @@ -152,6 +164,7 @@ static const struct comedi_lrange range_pci1710hg = { 12, { static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13 }; +#endif /* USE_PCI1710HG_RANGE */ static const struct comedi_lrange range_pci17x1 = { 5, { BIP_RANGE(10), @@ -178,9 +191,16 @@ static const struct comedi_lrange range_pci171x_da = { 2, { } }; +enum pci1710_boardid { + BOARD_PCI1710, + BOARD_PCI1711, + BOARD_PCI1713, + BOARD_PCI1720, + BOARD_PCI1731, +}; + struct boardtype { const char *name; /* board name */ - int device_id; int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=1710& co. 2=1713, ... */ @@ -200,9 +220,8 @@ struct boardtype { }; static const struct boardtype boardtypes[] = { - { + [BOARD_PCI1710] = { .name = "pci1710", - .device_id = 0x1710, .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, @@ -214,33 +233,19 @@ static const struct boardtype boardtypes[] = { .n_counter = 1, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, +#ifndef USE_PCI1710HG_RANGE .rangelist_ai = &range_pci1710_3, .rangecode_ai = range_codes_pci1710_3, - .rangelist_ao = &range_pci171x_da, - .ai_ns_min = 10000, - .fifo_half_size = 2048, - }, { - .name = "pci1710hg", - .device_id = 0x1710, - .iorange = IORANGE_171x, - .have_irq = 1, - .cardtype = TYPE_PCI171X, - .n_aichan = 16, - .n_aichand = 8, - .n_aochan = 2, - .n_dichan = 16, - .n_dochan = 16, - .n_counter = 1, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, +#else .rangelist_ai = &range_pci1710hg, .rangecode_ai = range_codes_pci1710hg, +#endif .rangelist_ao = &range_pci171x_da, .ai_ns_min = 10000, .fifo_half_size = 2048, - }, { + }, + [BOARD_PCI1711] = { .name = "pci1711", - .device_id = 0x1711, .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, @@ -256,9 +261,9 @@ static const struct boardtype boardtypes[] = { .rangelist_ao = &range_pci171x_da, .ai_ns_min = 10000, .fifo_half_size = 512, - }, { + }, + [BOARD_PCI1713] = { .name = "pci1713", - .device_id = 0x1713, .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI1713, @@ -269,17 +274,17 @@ static const struct boardtype boardtypes[] = { .rangecode_ai = range_codes_pci1710_3, .ai_ns_min = 10000, .fifo_half_size = 2048, - }, { + }, + [BOARD_PCI1720] = { .name = "pci1720", - .device_id = 0x1720, .iorange = IORANGE_1720, .cardtype = TYPE_PCI1720, .n_aochan = 4, .ao_maxdata = 0x0fff, .rangelist_ao = &range_pci1720, - }, { + }, + [BOARD_PCI1731] = { .name = "pci1731", - .device_id = 0x1731, .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, @@ -1220,30 +1225,17 @@ static int pci1710_reset(struct comedi_device *dev) } } -static const void *pci1710_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct boardtype *this_board; - int i; - - for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { - this_board = &boardtypes[i]; - if (pcidev->device == this_board->device_id) - return this_board; - } - return NULL; -} - static int pci1710_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct boardtype *this_board; + const struct boardtype *this_board = NULL; struct pci1710_private *devpriv; struct comedi_subdevice *s; int ret, subdev, n_subdevices; - this_board = pci1710_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(boardtypes)) + this_board = &boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -1405,11 +1397,11 @@ static int adv_pci1710_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) }, + { PCI_VDEVICE(ADVANTECH, 0x1710), BOARD_PCI1710 }, + { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 }, + { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 }, + { PCI_VDEVICE(ADVANTECH, 0x1720), BOARD_PCI1720 }, + { PCI_VDEVICE(ADVANTECH, 0x1731), BOARD_PCI1731 }, { 0 } }; MODULE_DEVICE_TABLE(pci, adv_pci1710_pci_table); -- cgit From c0a0e0ca9523bc9ae14f7153e792885459df640e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 09:59:52 -0700 Subject: staging: comedi: adv_pci_dio: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'vendor_id' and 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. The pci1753 and pci1753e boards have the same vendor/device id so it is impossible to determine which board is actually detected. The boardinfo for the boards is quite different. Group them in the same enum index in the boardinfo table and #if out the information with USE_PCI1753E_BOARDINFO. Until a better solution is worked out, this will allow the driver to be compiled to support the pci1753 (default) or pci1752e. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 151 +++++++++++++-------------- 1 file changed, 72 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 45e0b3719b8e..52b6d0264d34 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -37,6 +37,13 @@ Configuration options: #include "8255.h" #include "8253.h" +/* + * The pci1753 and pci1753e have the same vendor/device id! + * + * These boards are quite different. #define this if your card is a pci1753e. + */ +#undef USE_PCI1753E_BOARDINFO + /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, @@ -226,6 +233,23 @@ enum hw_io_access { #define OMBCMD_RETRY 0x03 /* 3 times try request before error */ +enum dio_boardid { + BOARD_PCI1730, + BOARD_PCI1733, + BOARD_PCI1734, + BOARD_PCI1735, + BOARD_PCI1736, + BOARD_PCI1739, + BOARD_PCI1750, + BOARD_PCI1751, + BOARD_PCI1752, + BOARD_PCI1753, + BOARD_PCI1754, + BOARD_PCI1756, + BOARD_PCI1760, + BOARD_PCI1762, +}; + struct diosubd_data { int chans; /* num of chans */ int addr; /* PCI address ofset */ @@ -236,8 +260,6 @@ struct diosubd_data { struct dio_boardtype { const char *name; /* board name */ - int vendor_id; /* vendor/device PCI ID */ - int device_id; int main_pci_region; /* main I/O PCI region */ enum hw_cards_id cardtype; int nsubdevs; @@ -250,10 +272,8 @@ struct dio_boardtype { }; static const struct dio_boardtype boardtypes[] = { - { + [BOARD_PCI1730] = { .name = "pci1730", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1730, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1730, .nsubdevs = 5, @@ -263,30 +283,27 @@ static const struct dio_boardtype boardtypes[] = { .sdo[1] = { 16, PCI1730_IDO, 2, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1733] = { .name = "pci1733", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1733, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1733, .nsubdevs = 2, .sdi[1] = { 32, PCI1733_IDI, 4, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1734] = { .name = "pci1734", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1734, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1734, .nsubdevs = 2, .sdo[1] = { 32, PCI1734_IDO, 4, 0, }, .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1735] = { .name = "pci1735", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1735, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1735, .nsubdevs = 4, @@ -295,10 +312,9 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, }, .s8254[0] = { 3, PCI1735_C8254, 1, 0, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1736] = { .name = "pci1736", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1736, .main_pci_region = PCI1736_MAINREG, .cardtype = TYPE_PCI1736, .nsubdevs = 3, @@ -306,39 +322,35 @@ static const struct dio_boardtype boardtypes[] = { .sdo[1] = { 16, PCI1736_IDO, 2, 0, }, .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1739] = { .name = "pci1739", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1739, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1739, .nsubdevs = 2, .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1750] = { .name = "pci1750", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1750, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1750, .nsubdevs = 2, .sdi[1] = { 16, PCI1750_IDI, 2, 0, }, .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1751] = { .name = "pci1751", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1751, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1751, .nsubdevs = 3, .sdio[0] = { 48, PCI1751_DIO, 2, 0, }, .s8254[0] = { 3, PCI1751_CNT, 1, 0, }, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1752] = { .name = "pci1752", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1752, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1752, .nsubdevs = 3, @@ -346,29 +358,27 @@ static const struct dio_boardtype boardtypes[] = { .sdo[1] = { 32, PCI1752_IDO2, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, - }, { + }, + [BOARD_PCI1753] = { +#ifndef USE_PCI1753E_BOARDINFO .name = "pci1753", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753, .nsubdevs = 4, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .io_access = IO_8b, - }, { +#else .name = "pci1753e", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1753, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753E, .nsubdevs = 8, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, .io_access = IO_8b, - }, { +#endif + }, + [BOARD_PCI1754] = { .name = "pci1754", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1754, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1754, .nsubdevs = 3, @@ -376,10 +386,9 @@ static const struct dio_boardtype boardtypes[] = { .sdi[1] = { 32, PCI1754_IDI2, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, - }, { + }, + [BOARD_PCI1756] = { .name = "pci1756", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1756, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1756, .nsubdevs = 3, @@ -387,19 +396,17 @@ static const struct dio_boardtype boardtypes[] = { .sdo[1] = { 32, PCI1756_IDO, 2, 0, }, .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, - }, { + }, + [BOARD_PCI1760] = { /* This card has its own 'attach' */ .name = "pci1760", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1760, .main_pci_region = 0, .cardtype = TYPE_PCI1760, .nsubdevs = 4, .io_access = IO_8b, - }, { + }, + [BOARD_PCI1762] = { .name = "pci1762", - .vendor_id = PCI_VENDOR_ID_ADVANTECH, - .device_id = 0x1762, .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1762, .nsubdevs = 3, @@ -1076,31 +1083,17 @@ static int pci_dio_add_8254(struct comedi_device *dev, return 0; } -static const void *pci_dio_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct dio_boardtype *this_board; - int i; - - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - this_board = &boardtypes[i]; - if (this_board->vendor_id == pcidev->vendor && - this_board->device_id == pcidev->device) - return this_board; - } - return NULL; -} - static int pci_dio_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct dio_boardtype *this_board; + const struct dio_boardtype *this_board = NULL; struct pci_dio_private *devpriv; struct comedi_subdevice *s; int ret, subdev, i, j; - this_board = pci_dio_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(boardtypes)) + this_board = &boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -1209,20 +1202,20 @@ static int adv_pci_dio_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1730) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1733) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1753) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1754) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1756) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1762) }, + { PCI_VDEVICE(ADVANTECH, 0x1730), BOARD_PCI1730 }, + { PCI_VDEVICE(ADVANTECH, 0x1733), BOARD_PCI1733 }, + { PCI_VDEVICE(ADVANTECH, 0x1734), BOARD_PCI1734 }, + { PCI_VDEVICE(ADVANTECH, 0x1735), BOARD_PCI1735 }, + { PCI_VDEVICE(ADVANTECH, 0x1736), BOARD_PCI1736 }, + { PCI_VDEVICE(ADVANTECH, 0x1739), BOARD_PCI1739 }, + { PCI_VDEVICE(ADVANTECH, 0x1750), BOARD_PCI1750 }, + { PCI_VDEVICE(ADVANTECH, 0x1751), BOARD_PCI1751 }, + { PCI_VDEVICE(ADVANTECH, 0x1752), BOARD_PCI1752 }, + { PCI_VDEVICE(ADVANTECH, 0x1753), BOARD_PCI1753 }, + { PCI_VDEVICE(ADVANTECH, 0x1754), BOARD_PCI1754 }, + { PCI_VDEVICE(ADVANTECH, 0x1756), BOARD_PCI1756 }, + { PCI_VDEVICE(ADVANTECH, 0x1760), BOARD_PCI1760 }, + { PCI_VDEVICE(ADVANTECH, 0x1762), BOARD_PCI1762 }, { 0 } }; MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table); -- cgit From 9b315bcb6f1d45938658dec82ee356546745b217 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:00:15 -0700 Subject: staging: comedi: cb_pcidas: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 80 ++++++++++++++---------------- 1 file changed, 38 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 425a5a18a787..1f9316996951 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -231,9 +231,19 @@ enum trimpot_model { AD8402, }; +enum cb_pcidas_boardid { + BOARD_PCIDAS1602_16, + BOARD_PCIDAS1200, + BOARD_PCIDAS1602_12, + BOARD_PCIDAS1200_JR, + BOARD_PCIDAS1602_16_JR, + BOARD_PCIDAS1000, + BOARD_PCIDAS1001, + BOARD_PCIDAS1002, +}; + struct cb_pcidas_board { const char *name; - unsigned short device_id; int ai_nchan; /* Inputs in single-ended mode */ int ai_bits; /* analog input resolution */ int ai_speed; /* fastest conversion period in ns */ @@ -248,9 +258,8 @@ struct cb_pcidas_board { }; static const struct cb_pcidas_board cb_pcidas_boards[] = { - { + [BOARD_PCIDAS1602_16] = { .name = "pci-das1602/16", - .device_id = 0x1, .ai_nchan = 16, .ai_bits = 16, .ai_speed = 5000, @@ -262,9 +271,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .trimpot = AD8402, .has_dac08 = 1, .is_1602 = 1, - }, { + }, + [BOARD_PCIDAS1200] = { .name = "pci-das1200", - .device_id = 0xF, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 3200, @@ -272,9 +281,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .fifo_size = 1024, .ranges = &cb_pcidas_ranges, .trimpot = AD7376, - }, { + }, + [BOARD_PCIDAS1602_12] = { .name = "pci-das1602/12", - .device_id = 0x10, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 3200, @@ -285,18 +294,18 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .is_1602 = 1, - }, { + }, + [BOARD_PCIDAS1200_JR] = { .name = "pci-das1200/jr", - .device_id = 0x19, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 3200, .fifo_size = 1024, .ranges = &cb_pcidas_ranges, .trimpot = AD7376, - }, { + }, + [BOARD_PCIDAS1602_16_JR] = { .name = "pci-das1602/16/jr", - .device_id = 0x1C, .ai_nchan = 16, .ai_bits = 16, .ai_speed = 5000, @@ -305,18 +314,18 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .trimpot = AD8402, .has_dac08 = 1, .is_1602 = 1, - }, { + }, + [BOARD_PCIDAS1000] = { .name = "pci-das1000", - .device_id = 0x4C, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 4000, .fifo_size = 1024, .ranges = &cb_pcidas_ranges, .trimpot = AD7376, - }, { + }, + [BOARD_PCIDAS1001] = { .name = "pci-das1001", - .device_id = 0x1a, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 6800, @@ -324,9 +333,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .fifo_size = 1024, .ranges = &cb_pcidas_alt_ranges, .trimpot = AD7376, - }, { + }, + [BOARD_PCIDAS1002] = { .name = "pci-das1002", - .device_id = 0x1b, .ai_nchan = 16, .ai_bits = 12, .ai_speed = 6800, @@ -1424,31 +1433,18 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) return IRQ_HANDLED; } -static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cb_pcidas_board *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) { - thisboard = &cb_pcidas_boards[i]; - if (thisboard->device_id == pcidev->device) - return thisboard; - } - return NULL; -} - static int cb_pcidas_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct cb_pcidas_board *thisboard; + const struct cb_pcidas_board *thisboard = NULL; struct cb_pcidas_private *devpriv; struct comedi_subdevice *s; int i; int ret; - thisboard = cb_pcidas_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(cb_pcidas_boards)) + thisboard = &cb_pcidas_boards[context]; if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; @@ -1636,14 +1632,14 @@ static int cb_pcidas_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, + { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 }, + { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 }, + { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 }, + { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR }, + { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR }, + { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 }, + { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 }, + { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); -- cgit From 463740d48fe9804a7181b25bcbdab1c887e36173 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:00:39 -0700 Subject: staging: comedi: cb_pcidas64: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 190 +++++++++++++-------------- 1 file changed, 92 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index c085e1d80d46..d0d6ed402474 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -593,9 +593,39 @@ struct hw_fifo_info { uint16_t fifo_size_reg_mask; }; +enum pcidas64_boardid { + BOARD_PCIDAS6402_16, + BOARD_PCIDAS6402_12, + BOARD_PCIDAS64_M1_16, + BOARD_PCIDAS64_M2_16, + BOARD_PCIDAS64_M3_16, + BOARD_PCIDAS6013, + BOARD_PCIDAS6014, + BOARD_PCIDAS6023, + BOARD_PCIDAS6025, + BOARD_PCIDAS6030, + BOARD_PCIDAS6031, + BOARD_PCIDAS6032, + BOARD_PCIDAS6033, + BOARD_PCIDAS6034, + BOARD_PCIDAS6035, + BOARD_PCIDAS6036, + BOARD_PCIDAS6040, + BOARD_PCIDAS6052, + BOARD_PCIDAS6070, + BOARD_PCIDAS6071, + BOARD_PCIDAS4020_12, + BOARD_PCIDAS6402_16_JR, + BOARD_PCIDAS64_M1_16_JR, + BOARD_PCIDAS64_M2_16_JR, + BOARD_PCIDAS64_M3_16_JR, + BOARD_PCIDAS64_M1_14, + BOARD_PCIDAS64_M2_14, + BOARD_PCIDAS64_M3_14, +}; + struct pcidas64_board { const char *name; - int device_id; /* pci device id */ int ai_se_chans; /* number of ai inputs in single-ended mode */ int ai_bits; /* analog input resolution */ int ai_speed; /* fastest conversion period in ns */ @@ -648,9 +678,8 @@ static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board) static const int bytes_in_sample = 2; static const struct pcidas64_board pcidas64_boards[] = { - { + [BOARD_PCIDAS6402_16] = { .name = "pci-das6402/16", - .device_id = 0x1d, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 5000, @@ -664,9 +693,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS6402_12] = { .name = "pci-das6402/12", /* XXX check */ - .device_id = 0x1e, .ai_se_chans = 64, .ai_bits = 12, .ai_speed = 5000, @@ -680,9 +708,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M1_16] = { .name = "pci-das64/m1/16", - .device_id = 0x35, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 1000, @@ -696,9 +723,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M2_16] = { .name = "pci-das64/m2/16", - .device_id = 0x36, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 500, @@ -712,9 +738,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M3_16] = { .name = "pci-das64/m3/16", - .device_id = 0x37, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 333, @@ -728,9 +753,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS6013] = { .name = "pci-das6013", - .device_id = 0x78, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 5000, @@ -743,9 +767,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6014] = { .name = "pci-das6014", - .device_id = 0x79, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 5000, @@ -759,9 +782,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6023] = { .name = "pci-das6023", - .device_id = 0x5d, .ai_se_chans = 16, .ai_bits = 12, .ai_speed = 5000, @@ -774,9 +796,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS6025] = { .name = "pci-das6025", - .device_id = 0x5e, .ai_se_chans = 16, .ai_bits = 12, .ai_speed = 5000, @@ -790,9 +811,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS6030] = { .name = "pci-das6030", - .device_id = 0x5f, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 10000, @@ -806,9 +826,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6031] = { .name = "pci-das6031", - .device_id = 0x60, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 10000, @@ -822,9 +841,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6032] = { .name = "pci-das6032", - .device_id = 0x61, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 10000, @@ -834,9 +852,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6033] = { .name = "pci-das6033", - .device_id = 0x62, .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 10000, @@ -846,9 +863,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6034] = { .name = "pci-das6034", - .device_id = 0x63, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 5000, @@ -859,9 +875,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6035] = { .name = "pci-das6035", - .device_id = 0x64, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 5000, @@ -875,9 +890,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6036] = { .name = "pci-das6036", - .device_id = 0x6f, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 5000, @@ -891,9 +905,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6040] = { .name = "pci-das6040", - .device_id = 0x65, .ai_se_chans = 16, .ai_bits = 12, .ai_speed = 2000, @@ -907,9 +920,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6052] = { .name = "pci-das6052", - .device_id = 0x66, .ai_se_chans = 16, .ai_bits = 16, .ai_speed = 3333, @@ -923,9 +935,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6070] = { .name = "pci-das6070", - .device_id = 0x67, .ai_se_chans = 16, .ai_bits = 12, .ai_speed = 800, @@ -939,9 +950,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS6071] = { .name = "pci-das6071", - .device_id = 0x68, .ai_se_chans = 64, .ai_bits = 12, .ai_speed = 800, @@ -955,9 +965,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = &ai_fifo_60xx, .has_8255 = 0, }, - { + [BOARD_PCIDAS4020_12] = { .name = "pci-das4020/12", - .device_id = 0x52, .ai_se_chans = 4, .ai_bits = 12, .ai_speed = 50, @@ -972,9 +981,12 @@ static const struct pcidas64_board pcidas64_boards[] = { .has_8255 = 1, }, #if 0 - { + /* + * The device id for these boards is unknown + */ + + [BOARD_PCIDAS6402_16_JR] = { .name = "pci-das6402/16/jr", - .device_id = 0 /* XXX, */ .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 5000, @@ -985,9 +997,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M1_16_JR] = { .name = "pci-das64/m1/16/jr", - .device_id = 0 /* XXX, */ .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 1000, @@ -998,9 +1009,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M2_16_JR] = { .name = "pci-das64/m2/16/jr", - .device_id = 0 /* XXX, */ .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 500, @@ -1011,9 +1021,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M3_16_JR] = { .name = "pci-das64/m3/16/jr", - .device_id = 0 /* XXX, */ .ai_se_chans = 64, .ai_bits = 16, .ai_speed = 333, @@ -1024,9 +1033,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M1_14] = { .name = "pci-das64/m1/14", - .device_id = 0, /* XXX */ .ai_se_chans = 64, .ai_bits = 14, .ai_speed = 1000, @@ -1037,9 +1045,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M2_14] = { .name = "pci-das64/m2/14", - .device_id = 0, /* XXX */ .ai_se_chans = 64, .ai_bits = 14, .ai_speed = 500, @@ -1050,9 +1057,8 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo = ai_fifo_64xx, .has_8255 = 1, }, - { + [BOARD_PCIDAS64_M3_14] = { .name = "pci-das64/m3/14", - .device_id = 0, /* XXX */ .ai_se_chans = 64, .ai_bits = 14, .ai_speed = 333, @@ -4033,34 +4039,20 @@ static int setup_subdevices(struct comedi_device *dev) return 0; } -static const struct pcidas64_board -*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) - if (pcidev->device == pcidas64_boards[i].device_id) - return &pcidas64_boards[i]; - return NULL; -} - static int auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { - const struct pcidas64_board *thisboard; - struct pcidas64_private *devpriv; struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct pcidas64_board *thisboard = NULL; + struct pcidas64_private *devpriv; uint32_t local_range, local_decode; int retval; - dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); - if (!dev->board_ptr) { - dev_err(dev->class_dev, - "cb_pcidas64: does not support pci %s\n", - pci_name(pcidev)); - return -EINVAL; - } - thisboard = comedi_board(dev); + if (context < ARRAY_SIZE(pcidas64_boards)) + thisboard = &pcidas64_boards[context]; + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -4223,25 +4215,27 @@ static int cb_pcidas64_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001d) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001e) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0035) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0036) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0037) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0052) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005d) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005e) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005f) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0061) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0062) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0063) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0064) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0066) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0067) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0068) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x006f) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0078) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0079) }, + { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 }, + { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 }, + { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 }, + { PCI_VDEVICE(CB, 0x0036), BOARD_PCIDAS64_M2_16 }, + { PCI_VDEVICE(CB, 0x0037), BOARD_PCIDAS64_M3_16 }, + { PCI_VDEVICE(CB, 0x0052), BOARD_PCIDAS4020_12 }, + { PCI_VDEVICE(CB, 0x005d), BOARD_PCIDAS6023 }, + { PCI_VDEVICE(CB, 0x005e), BOARD_PCIDAS6025 }, + { PCI_VDEVICE(CB, 0x005f), BOARD_PCIDAS6030 }, + { PCI_VDEVICE(CB, 0x0060), BOARD_PCIDAS6031 }, + { PCI_VDEVICE(CB, 0x0061), BOARD_PCIDAS6032 }, + { PCI_VDEVICE(CB, 0x0062), BOARD_PCIDAS6033 }, + { PCI_VDEVICE(CB, 0x0063), BOARD_PCIDAS6034 }, + { PCI_VDEVICE(CB, 0x0064), BOARD_PCIDAS6035 }, + { PCI_VDEVICE(CB, 0x0065), BOARD_PCIDAS6040 }, + { PCI_VDEVICE(CB, 0x0066), BOARD_PCIDAS6052 }, + { PCI_VDEVICE(CB, 0x0067), BOARD_PCIDAS6070 }, + { PCI_VDEVICE(CB, 0x0068), BOARD_PCIDAS6071 }, + { PCI_VDEVICE(CB, 0x006f), BOARD_PCIDAS6036 }, + { PCI_VDEVICE(CB, 0x0078), BOARD_PCIDAS6013 }, + { PCI_VDEVICE(CB, 0x0079), BOARD_PCIDAS6014 }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table); -- cgit From 2ccdb96442fb94342eedb9dbc7a7a180e05dbde7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:00:59 -0700 Subject: staging: comedi: cb_pcidas64: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 716 +++++++++++++-------------- 1 file changed, 358 insertions(+), 358 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index d0d6ed402474..fe58c9c6fb33 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -679,396 +679,396 @@ static const int bytes_in_sample = 2; static const struct pcidas64_board pcidas64_boards[] = { [BOARD_PCIDAS6402_16] = { - .name = "pci-das6402/16", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ao_range_table = &ao_ranges_64xx, - .ao_range_code = ao_range_code_64xx, - .ai_fifo = &ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das6402/16", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS6402_12] = { - .name = "pci-das6402/12", /* XXX check */ - .ai_se_chans = 64, - .ai_bits = 12, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ao_range_table = &ao_ranges_64xx, - .ao_range_code = ao_range_code_64xx, - .ai_fifo = &ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das6402/12", /* XXX check */ + .ai_se_chans = 64, + .ai_bits = 12, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M1_16] = { - .name = "pci-das64/m1/16", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 1000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ao_range_table = &ao_ranges_64xx, - .ao_range_code = ao_range_code_64xx, - .ai_fifo = &ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m1/16", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 1000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M2_16] = { - .name = "pci-das64/m2/16", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 500, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ao_range_table = &ao_ranges_64xx, - .ao_range_code = ao_range_code_64xx, - .ai_fifo = &ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m2/16", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 500, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M3_16] = { - .name = "pci-das64/m3/16", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 333, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ao_range_table = &ao_ranges_64xx, - .ao_range_code = ao_range_code_64xx, - .ai_fifo = &ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m3/16", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 333, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS6013] = { - .name = "pci-das6013", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 0, - .ao_bits = 16, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6013", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 0, + .ao_bits = 16, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6014] = { - .name = "pci-das6014", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 100000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6014", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6023] = { - .name = "pci-das6023", - .ai_se_chans = 16, - .ai_bits = 12, - .ai_speed = 5000, - .ao_nchan = 0, - .ao_scan_speed = 100000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 1, - }, + .name = "pci-das6023", + .ai_se_chans = 16, + .ai_bits = 12, + .ai_speed = 5000, + .ao_nchan = 0, + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 1, + }, [BOARD_PCIDAS6025] = { - .name = "pci-das6025", - .ai_se_chans = 16, - .ai_bits = 12, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 100000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 1, - }, + .name = "pci-das6025", + .ai_se_chans = 16, + .ai_bits = 12, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 1, + }, [BOARD_PCIDAS6030] = { - .name = "pci-das6030", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 10000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6030, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6030", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 10000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6031] = { - .name = "pci-das6031", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 10000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 10000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6030, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6031", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 10000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6032] = { - .name = "pci-das6032", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 10000, - .ao_nchan = 0, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6032", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 10000, + .ao_nchan = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6033] = { - .name = "pci-das6033", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 10000, - .ao_nchan = 0, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6033", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 10000, + .ao_nchan = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6034] = { - .name = "pci-das6034", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 0, - .ao_scan_speed = 0, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6034", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 0, + .ao_scan_speed = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6035] = { - .name = "pci-das6035", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 100000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6035", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6036] = { - .name = "pci-das6036", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 100000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_60xx, - .ao_range_table = &ao_ranges_60xx, - .ao_range_code = ao_range_code_60xx, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6036", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6040] = { - .name = "pci-das6040", - .ai_se_chans = 16, - .ai_bits = 12, - .ai_speed = 2000, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 1000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6052, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6040", + .ai_se_chans = 16, + .ai_bits = 12, + .ai_speed = 2000, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6052] = { - .name = "pci-das6052", - .ai_se_chans = 16, - .ai_bits = 16, - .ai_speed = 3333, - .ao_nchan = 2, - .ao_bits = 16, - .ao_scan_speed = 3333, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6052, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6052", + .ai_se_chans = 16, + .ai_bits = 16, + .ai_speed = 3333, + .ao_nchan = 2, + .ao_bits = 16, + .ao_scan_speed = 3333, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6070] = { - .name = "pci-das6070", - .ai_se_chans = 16, - .ai_bits = 12, - .ai_speed = 800, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 1000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6052, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6070", + .ai_se_chans = 16, + .ai_bits = 12, + .ai_speed = 800, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS6071] = { - .name = "pci-das6071", - .ai_se_chans = 64, - .ai_bits = 12, - .ai_speed = 800, - .ao_nchan = 2, - .ao_bits = 12, - .ao_scan_speed = 1000, - .layout = LAYOUT_60XX, - .ai_range_table = &ai_ranges_6052, - .ao_range_table = &ao_ranges_6030, - .ao_range_code = ao_range_code_6030, - .ai_fifo = &ai_fifo_60xx, - .has_8255 = 0, - }, + .name = "pci-das6071", + .ai_se_chans = 64, + .ai_bits = 12, + .ai_speed = 800, + .ao_nchan = 2, + .ao_bits = 12, + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, [BOARD_PCIDAS4020_12] = { - .name = "pci-das4020/12", - .ai_se_chans = 4, - .ai_bits = 12, - .ai_speed = 50, - .ao_bits = 12, - .ao_nchan = 2, - .ao_scan_speed = 0, /* no hardware pacing on ao */ - .layout = LAYOUT_4020, - .ai_range_table = &ai_ranges_4020, - .ao_range_table = &ao_ranges_4020, - .ao_range_code = ao_range_code_4020, - .ai_fifo = &ai_fifo_4020, - .has_8255 = 1, - }, + .name = "pci-das4020/12", + .ai_se_chans = 4, + .ai_bits = 12, + .ai_speed = 50, + .ao_bits = 12, + .ao_nchan = 2, + .ao_scan_speed = 0, /* no hardware pacing on ao */ + .layout = LAYOUT_4020, + .ai_range_table = &ai_ranges_4020, + .ao_range_table = &ao_ranges_4020, + .ao_range_code = ao_range_code_4020, + .ai_fifo = &ai_fifo_4020, + .has_8255 = 1, + }, #if 0 /* * The device id for these boards is unknown */ [BOARD_PCIDAS6402_16_JR] = { - .name = "pci-das6402/16/jr", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 5000, - .ao_nchan = 0, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das6402/16/jr", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 5000, + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M1_16_JR] = { - .name = "pci-das64/m1/16/jr", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 1000, - .ao_nchan = 0, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m1/16/jr", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 1000, + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M2_16_JR] = { - .name = "pci-das64/m2/16/jr", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 500, - .ao_nchan = 0, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m2/16/jr", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 500, + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M3_16_JR] = { - .name = "pci-das64/m3/16/jr", - .ai_se_chans = 64, - .ai_bits = 16, - .ai_speed = 333, - .ao_nchan = 0, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m3/16/jr", + .ai_se_chans = 64, + .ai_bits = 16, + .ai_speed = 333, + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M1_14] = { - .name = "pci-das64/m1/14", - .ai_se_chans = 64, - .ai_bits = 14, - .ai_speed = 1000, - .ao_nchan = 2, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m1/14", + .ai_se_chans = 64, + .ai_bits = 14, + .ai_speed = 1000, + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M2_14] = { - .name = "pci-das64/m2/14", - .ai_se_chans = 64, - .ai_bits = 14, - .ai_speed = 500, - .ao_nchan = 2, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m2/14", + .ai_se_chans = 64, + .ai_bits = 14, + .ai_speed = 500, + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, [BOARD_PCIDAS64_M3_14] = { - .name = "pci-das64/m3/14", - .ai_se_chans = 64, - .ai_bits = 14, - .ai_speed = 333, - .ao_nchan = 2, - .ao_scan_speed = 10000, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_fifo = ai_fifo_64xx, - .has_8255 = 1, - }, + .name = "pci-das64/m3/14", + .ai_se_chans = 64, + .ai_bits = 14, + .ai_speed = 333, + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, #endif }; -- cgit From e125f75374830aa004ba24ce5375e850856a2731 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:01:28 -0700 Subject: staging: comedi: cb_pcidda: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 76 ++++++++++++------------------ 1 file changed, 30 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index f00d85732d0d..54cdb2728a81 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -48,16 +48,6 @@ #include "comedi_fc.h" #include "8255.h" -/* - * ComputerBoards PCI Device ID's supported by this driver - */ -#define PCI_DEVICE_ID_DDA02_12 0x0020 -#define PCI_DEVICE_ID_DDA04_12 0x0021 -#define PCI_DEVICE_ID_DDA08_12 0x0022 -#define PCI_DEVICE_ID_DDA02_16 0x0023 -#define PCI_DEVICE_ID_DDA04_16 0x0024 -#define PCI_DEVICE_ID_DDA08_16 0x0025 - #define EEPROM_SIZE 128 /* number of entries in eeprom */ /* maximum number of ao channels for supported boards */ #define MAX_AO_CHANNELS 8 @@ -118,42 +108,49 @@ static const struct comedi_lrange cb_pcidda_ranges = { } }; +enum cb_pcidda_boardid { + BOARD_DDA02_12, + BOARD_DDA04_12, + BOARD_DDA08_12, + BOARD_DDA02_16, + BOARD_DDA04_16, + BOARD_DDA08_16, +}; + struct cb_pcidda_board { const char *name; - unsigned short device_id; int ao_chans; int ao_bits; }; static const struct cb_pcidda_board cb_pcidda_boards[] = { - { + [BOARD_DDA02_12] = { .name = "pci-dda02/12", - .device_id = PCI_DEVICE_ID_DDA02_12, .ao_chans = 2, .ao_bits = 12, - }, { + }, + [BOARD_DDA04_12] = { .name = "pci-dda04/12", - .device_id = PCI_DEVICE_ID_DDA04_12, .ao_chans = 4, .ao_bits = 12, - }, { + }, + [BOARD_DDA08_12] = { .name = "pci-dda08/12", - .device_id = PCI_DEVICE_ID_DDA08_12, .ao_chans = 8, .ao_bits = 12, - }, { + }, + [BOARD_DDA02_16] = { .name = "pci-dda02/16", - .device_id = PCI_DEVICE_ID_DDA02_16, .ao_chans = 2, .ao_bits = 16, - }, { + }, + [BOARD_DDA04_16] = { .name = "pci-dda04/16", - .device_id = PCI_DEVICE_ID_DDA04_16, .ao_chans = 4, .ao_bits = 16, - }, { + }, + [BOARD_DDA08_16] = { .name = "pci-dda08/16", - .device_id = PCI_DEVICE_ID_DDA08_16, .ao_chans = 8, .ao_bits = 16, }, @@ -337,32 +334,19 @@ static int cb_pcidda_ao_insn_write(struct comedi_device *dev, return insn->n; } -static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cb_pcidda_board *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) { - thisboard = &cb_pcidda_boards[i]; - if (thisboard->device_id != pcidev->device) - return thisboard; - } - return NULL; -} - static int cb_pcidda_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct cb_pcidda_board *thisboard; + const struct cb_pcidda_board *thisboard = NULL; struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; unsigned long iobase_8255; int i; int ret; - thisboard = cb_pcidda_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(cb_pcidda_boards)) + thisboard = &cb_pcidda_boards[context]; if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; @@ -442,12 +426,12 @@ static int cb_pcidda_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) }, + { PCI_VDEVICE(CB, 0x0020), BOARD_DDA02_12 }, + { PCI_VDEVICE(CB, 0x0021), BOARD_DDA04_12 }, + { PCI_VDEVICE(CB, 0x0022), BOARD_DDA08_12 }, + { PCI_VDEVICE(CB, 0x0023), BOARD_DDA02_16 }, + { PCI_VDEVICE(CB, 0x0024), BOARD_DDA04_16 }, + { PCI_VDEVICE(CB, 0x0025), BOARD_DDA08_16 }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); -- cgit From cf7df5864aaac1af20ddc99f3d7b2ce94c5e27e1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:01:59 -0700 Subject: staging: comedi: dt3000: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 84 +++++++++++++-------------------- 1 file changed, 34 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 6862e7f8ed04..5726d56346c8 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -63,17 +63,6 @@ AO commands are not supported. #include "comedi_fc.h" -/* - * PCI device id's supported by this driver - */ -#define PCI_DEVICE_ID_DT3001 0x0022 -#define PCI_DEVICE_ID_DT3002 0x0023 -#define PCI_DEVICE_ID_DT3003 0x0024 -#define PCI_DEVICE_ID_DT3004 0x0025 -#define PCI_DEVICE_ID_DT3005 0x0026 -#define PCI_DEVICE_ID_DT3001_PGL 0x0027 -#define PCI_DEVICE_ID_DT3003_PGL 0x0028 - static const struct comedi_lrange range_dt3000_ai = { 4, { BIP_RANGE(10), @@ -92,9 +81,18 @@ static const struct comedi_lrange range_dt3000_ai_pgl = { } }; +enum dt3k_boardid { + BOARD_DT3001, + BOARD_DT3001_PGL, + BOARD_DT3002, + BOARD_DT3003, + BOARD_DT3003_PGL, + BOARD_DT3004, + BOARD_DT3005, +}; + struct dt3k_boardtype { const char *name; - unsigned int device_id; int adchan; int adbits; int ai_speed; @@ -104,61 +102,60 @@ struct dt3k_boardtype { }; static const struct dt3k_boardtype dt3k_boardtypes[] = { - { + [BOARD_DT3001] = { .name = "dt3001", - .device_id = PCI_DEVICE_ID_DT3001, .adchan = 16, .adbits = 12, .adrange = &range_dt3000_ai, .ai_speed = 3000, .dachan = 2, .dabits = 12, - }, { + }, + [BOARD_DT3001_PGL] = { .name = "dt3001-pgl", - .device_id = PCI_DEVICE_ID_DT3001_PGL, .adchan = 16, .adbits = 12, .adrange = &range_dt3000_ai_pgl, .ai_speed = 3000, .dachan = 2, .dabits = 12, - }, { + }, + [BOARD_DT3002] = { .name = "dt3002", - .device_id = PCI_DEVICE_ID_DT3002, .adchan = 32, .adbits = 12, .adrange = &range_dt3000_ai, .ai_speed = 3000, - }, { + }, + [BOARD_DT3003] = { .name = "dt3003", - .device_id = PCI_DEVICE_ID_DT3003, .adchan = 64, .adbits = 12, .adrange = &range_dt3000_ai, .ai_speed = 3000, .dachan = 2, .dabits = 12, - }, { + }, + [BOARD_DT3003_PGL] = { .name = "dt3003-pgl", - .device_id = PCI_DEVICE_ID_DT3003_PGL, .adchan = 64, .adbits = 12, .adrange = &range_dt3000_ai_pgl, .ai_speed = 3000, .dachan = 2, .dabits = 12, - }, { + }, + [BOARD_DT3004] = { .name = "dt3004", - .device_id = PCI_DEVICE_ID_DT3004, .adchan = 16, .adbits = 16, .adrange = &range_dt3000_ai, .ai_speed = 10000, .dachan = 2, .dabits = 12, - }, { + }, + [BOARD_DT3005] = { .name = "dt3005", /* a.k.a. 3004-200 */ - .device_id = PCI_DEVICE_ID_DT3005, .adchan = 16, .adbits = 16, .adrange = &range_dt3000_ai, @@ -716,31 +713,18 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, return i; } -static const void *dt3000_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct dt3k_boardtype *this_board; - int i; - - for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) { - this_board = &dt3k_boardtypes[i]; - if (this_board->device_id == pcidev->device) - return this_board; - } - return NULL; -} - static int dt3000_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct dt3k_boardtype *this_board; + const struct dt3k_boardtype *this_board = NULL; struct dt3k_private *devpriv; struct comedi_subdevice *s; resource_size_t pci_base; int ret = 0; - this_board = dt3000_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(dt3k_boardtypes)) + this_board = &dt3k_boardtypes[context]; if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -859,13 +843,13 @@ static int dt3000_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001_PGL) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3002) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003_PGL) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3004) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3005) }, + { PCI_VDEVICE(DT, 0x0022), BOARD_DT3001 }, + { PCI_VDEVICE(DT, 0x0023), BOARD_DT3002 }, + { PCI_VDEVICE(DT, 0x0024), BOARD_DT3003 }, + { PCI_VDEVICE(DT, 0x0025), BOARD_DT3004 }, + { PCI_VDEVICE(DT, 0x0026), BOARD_DT3005 }, + { PCI_VDEVICE(DT, 0x0027), BOARD_DT3001_PGL }, + { PCI_VDEVICE(DT, 0x0028), BOARD_DT3003_PGL }, { 0 } }; MODULE_DEVICE_TABLE(pci, dt3000_pci_table); -- cgit From 8c35550969445590b312c568103bd02ff3546166 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:02:47 -0700 Subject: staging: comedi: me4000: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 131 ++++++++++++++------------------ 1 file changed, 59 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 9f09e1969911..141a3f7bbf15 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -61,20 +61,6 @@ broken. #include "me4000_fw.h" #endif -#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 -#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 -#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 -#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 -#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 -#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 -#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 -#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 -#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 -#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 -#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 -#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 -#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 - /* * ME4000 Register map and bit defines */ @@ -220,9 +206,24 @@ struct me4000_info { unsigned int ao_readback[4]; }; +enum me4000_boardid { + BOARD_ME4650, + BOARD_ME4660, + BOARD_ME4660I, + BOARD_ME4660S, + BOARD_ME4660IS, + BOARD_ME4670, + BOARD_ME4670I, + BOARD_ME4670S, + BOARD_ME4670IS, + BOARD_ME4680, + BOARD_ME4680I, + BOARD_ME4680S, + BOARD_ME4680IS, +}; + struct me4000_board { const char *name; - unsigned short device_id; int ao_nchan; int ao_fifo; int ai_nchan; @@ -234,62 +235,61 @@ struct me4000_board { }; static const struct me4000_board me4000_boards[] = { - { + [BOARD_ME4650] = { .name = "ME-4650", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4650, .ai_nchan = 16, .dio_nchan = 32, - }, { + }, + [BOARD_ME4660] = { .name = "ME-4660", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4660I] = { .name = "ME-4660i", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660I, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4660S] = { .name = "ME-4660s", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660S, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4660IS] = { .name = "ME-4660is", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660IS, .ai_nchan = 32, .ai_diff_nchan = 16, .ai_sh_nchan = 8, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4670] = { .name = "ME-4670", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4670I] = { .name = "ME-4670i", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670I, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4670S] = { .name = "ME-4670s", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670S, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -297,9 +297,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4670IS] = { .name = "ME-4670is", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670IS, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -307,9 +307,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680] = { .name = "ME-4680", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -317,9 +317,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680I] = { .name = "ME-4680i", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680I, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -327,9 +327,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680S] = { .name = "ME-4680s", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680S, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -338,9 +338,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680IS] = { .name = "ME-4680is", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680IS, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -1550,30 +1550,17 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } -static const void *me4000_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct me4000_board *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { - thisboard = &me4000_boards[i]; - if (thisboard->device_id == pcidev->device) - return thisboard; - } - return NULL; -} - static int me4000_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct me4000_board *thisboard; + const struct me4000_board *thisboard = NULL; struct me4000_info *info; struct comedi_subdevice *s; int result; - thisboard = me4000_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(me4000_boards)) + thisboard = &me4000_boards[context]; if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; @@ -1736,20 +1723,20 @@ static int me4000_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660S)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660IS)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S)}, - {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS)}, - {0} + { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 }, + { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 }, + { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I }, + { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S }, + { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS }, + { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 }, + { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I }, + { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S }, + { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS }, + { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 }, + { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I }, + { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S }, + { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS }, + { 0 } }; MODULE_DEVICE_TABLE(pci, me4000_pci_table); -- cgit From a4493f07c67bb774519189044ae90034466748a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:03:09 -0700 Subject: staging: comedi: me_daq: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since the PCI device ids are now only used in the id_table, remove the defines and open code the device ids. The me-2600i needs to have firmware uploaded to the board. Add a new field to the boardinfo, 'needs_firmware', to indicate this. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 47 +++++++++++++-------------------- 1 file changed, 18 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 58ba9e322624..3637828727c8 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -43,9 +43,6 @@ #define ME2600_FIRMWARE "me2600_firmware.bin" -#define ME2000_DEVICE_ID 0x2000 -#define ME2600_DEVICE_ID 0x2600 - #define PLX_INTCSR 0x4C /* PLX interrupt status register */ #define XILINX_DOWNLOAD_RESET 0x42 /* Xilinx registers */ @@ -149,21 +146,26 @@ static const struct comedi_lrange me_ao_range = { } }; +enum me_boardid { + BOARD_ME2600, + BOARD_ME2000, +}; + struct me_board { const char *name; - int device_id; + int needs_firmware; int has_ao; }; static const struct me_board me_boards[] = { - { + [BOARD_ME2600] = { .name = "me-2600i", - .device_id = ME2600_DEVICE_ID, + .needs_firmware = 1, .has_ao = 1, - }, { + }, + [BOARD_ME2000] = { .name = "me-2000i", - .device_id = ME2000_DEVICE_ID, - } + }, }; struct me_private_data { @@ -488,30 +490,17 @@ static int me_reset(struct comedi_device *dev) return 0; } -static const void *me_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct me_board *board; - int i; - - for (i = 0; i < ARRAY_SIZE(me_boards); i++) { - board = &me_boards[i]; - if (board->device_id == pcidev->device) - return board; - } - return NULL; -} - static int me_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct me_board *board; + const struct me_board *board = NULL; struct me_private_data *dev_private; struct comedi_subdevice *s; int ret; - board = me_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(me_boards)) + board = &me_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; @@ -538,7 +527,7 @@ static int me_auto_attach(struct comedi_device *dev, return -ENOMEM; /* Download firmware and reset card */ - if (board->device_id == ME2600_DEVICE_ID) { + if (board->needs_firmware) { ret = me2600_upload_firmware(dev); if (ret < 0) return ret; @@ -622,8 +611,8 @@ static int me_daq_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) }, + { PCI_VDEVICE(MEILHAUS, 0x2600), BOARD_ME2600 }, + { PCI_VDEVICE(MEILHAUS, 0x2000), BOARD_ME2000 }, { 0 } }; MODULE_DEVICE_TABLE(pci, me_daq_pci_table); -- cgit From dcf9cfd3b1807a28fd46ca73489bc401827fd933 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:03:34 -0700 Subject: staging: comedi: ni_6527: cleanup pci_driver declaration For aesthetic reasons, add some whitespace to the pci_driver declaration. Also, move the pci device table near the pci_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 507c1216461b..41945df67e4d 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -100,14 +100,6 @@ static const struct ni6527_board ni6527_boards[] = { #define this_board ((const struct ni6527_board *)dev->board_ptr) -static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni6527_pci_table); - struct ni6527_private { struct mite_struct *mite; unsigned int filter_interval; @@ -454,10 +446,17 @@ static int ni6527_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data); } +static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ni6527_pci_table); + static struct pci_driver ni6527_pci_driver = { - .name = DRIVER_NAME, - .id_table = ni6527_pci_table, - .probe = ni6527_pci_probe, + .name = DRIVER_NAME, + .id_table = ni6527_pci_table, + .probe = ni6527_pci_probe, .remove = comedi_pci_auto_unconfig, }; module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver); -- cgit From 1787b7c170a59f93a17f340b8956152a9aad8f37 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:03:55 -0700 Subject: staging: comedi: ni_6527: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. For aesthetic reasons, add some whitespace to the boardinfo. Remove the now unnecessary 'this_board' macro. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 56 +++++++++++++------------------- 1 file changed, 22 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 41945df67e4d..514d5db92028 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -81,25 +81,24 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 #define Rising_Edge_Detection_Enable(x) (0x018+(x)) #define Falling_Edge_Detection_Enable(x) (0x020+(x)) -struct ni6527_board { +enum ni6527_boardid { + BOARD_PCI6527, + BOARD_PXI6527, +}; - int dev_id; +struct ni6527_board { const char *name; }; static const struct ni6527_board ni6527_boards[] = { - { - .dev_id = 0x2b20, - .name = "pci-6527", - }, - { - .dev_id = 0x2b10, - .name = "pxi-6527", - }, + [BOARD_PCI6527] = { + .name = "pci-6527", + }, + [BOARD_PXI6527] = { + .name = "pxi-6527", + }, }; -#define this_board ((const struct ni6527_board *)dev->board_ptr) - struct ni6527_private { struct mite_struct *mite; unsigned int filter_interval; @@ -321,37 +320,27 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, return 2; } -static const struct ni6527_board * -ni6527_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni6527_boards); n++) { - const struct ni6527_board *board = &ni6527_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int ni6527_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct ni6527_board *board = NULL; struct ni6527_private *devpriv; struct comedi_subdevice *s; int ret; + if (context < ARRAY_SIZE(ni6527_boards)) + board = &ni6527_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - dev->board_ptr = ni6527_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; @@ -362,7 +351,6 @@ static int ni6527_auto_attach(struct comedi_device *dev, return ret; } - dev->board_name = this_board->name; dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name, readb(devpriv->mite->daq_io_addr + ID_Register)); @@ -447,8 +435,8 @@ static int ni6527_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20) }, + { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 }, + { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni6527_pci_table); -- cgit From a2fa439d9a183a7c5096b1c8f87078b728f22897 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:04:22 -0700 Subject: staging: comedi: ni_65xx: cleanup pci_driver declaration For aesthetic reasons, add some whitespace to the pci_driver declaration. Also, move the pci device table near the pci_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 61 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index ded8d9e5d9ba..cd29eaa83d20 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -257,34 +257,6 @@ static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board return board->num_dio_ports + board->num_di_ports + board->num_do_ports; } -static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1710)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7085)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7086)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7087)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7088)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70a9)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c3)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c8)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c9)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70cc)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70CD)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d1)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d2)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d3)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7124)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7125)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7126)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7127)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7128)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718b)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718c)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71c5)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table); - struct ni_65xx_private { struct mite_struct *mite; unsigned int filter_interval; @@ -790,10 +762,37 @@ static int ni_65xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data); } +static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1710) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7085) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7086) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7087) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7088) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70a9) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c3) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c8) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c9) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70cc) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70CD) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d1) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d2) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d3) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7124) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7125) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7126) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7127) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7128) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718b) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718c) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71c5) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table); + static struct pci_driver ni_65xx_pci_driver = { - .name = "ni_65xx", - .id_table = ni_65xx_pci_table, - .probe = ni_65xx_pci_probe, + .name = "ni_65xx", + .id_table = ni_65xx_pci_table, + .probe = ni_65xx_pci_probe, .remove = comedi_pci_auto_unconfig, }; module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver); -- cgit From b4a69035fb7ed12f0e869d7c7e448d1bf0bccf4f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:04:52 -0700 Subject: staging: comedi: ni_65xx: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Since we now have a local variable in the attach that has the boardinfo pointer, use that instead of calling the local board() helper function each time the boardinfo is accessed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 185 +++++++++++++++---------------- 1 file changed, 88 insertions(+), 97 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index cd29eaa83d20..34b93d2083be 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -112,8 +112,32 @@ static inline unsigned Filter_Enable(unsigned port) #define OverflowIntEnable 0x02 #define EdgeIntEnable 0x01 +enum ni_65xx_boardid { + BOARD_PCI6509, + BOARD_PXI6509, + BOARD_PCI6510, + BOARD_PCI6511, + BOARD_PXI6511, + BOARD_PCI6512, + BOARD_PXI6512, + BOARD_PCI6513, + BOARD_PXI6513, + BOARD_PCI6514, + BOARD_PXI6514, + BOARD_PCI6515, + BOARD_PXI6515, + BOARD_PCI6516, + BOARD_PCI6517, + BOARD_PCI6518, + BOARD_PCI6519, + BOARD_PCI6520, + BOARD_PCI6521, + BOARD_PXI6521, + BOARD_PCI6528, + BOARD_PXI6528, +}; + struct ni_65xx_board { - int dev_id; const char *name; unsigned num_dio_ports; unsigned num_di_ports; @@ -122,118 +146,96 @@ struct ni_65xx_board { }; static const struct ni_65xx_board ni_65xx_boards[] = { - { - .dev_id = 0x7085, + [BOARD_PCI6509] = { .name = "pci-6509", .num_dio_ports = 12, .invert_outputs = 0}, - { - .dev_id = 0x1710, + [BOARD_PXI6509] = { .name = "pxi-6509", .num_dio_ports = 12, .invert_outputs = 0}, - { - .dev_id = 0x7124, + [BOARD_PCI6510] = { .name = "pci-6510", .num_di_ports = 4}, - { - .dev_id = 0x70c3, + [BOARD_PCI6511] = { .name = "pci-6511", .num_di_ports = 8}, - { - .dev_id = 0x70d3, + [BOARD_PXI6511] = { .name = "pxi-6511", .num_di_ports = 8}, - { - .dev_id = 0x70cc, + [BOARD_PCI6512] = { .name = "pci-6512", .num_do_ports = 8}, - { - .dev_id = 0x70d2, + [BOARD_PXI6512] = { .name = "pxi-6512", .num_do_ports = 8}, - { - .dev_id = 0x70c8, + [BOARD_PCI6513] = { .name = "pci-6513", .num_do_ports = 8, .invert_outputs = 1}, - { - .dev_id = 0x70d1, + [BOARD_PXI6513] = { .name = "pxi-6513", .num_do_ports = 8, .invert_outputs = 1}, - { - .dev_id = 0x7088, + [BOARD_PCI6514] = { .name = "pci-6514", .num_di_ports = 4, .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x70CD, + [BOARD_PXI6514] = { .name = "pxi-6514", .num_di_ports = 4, .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x7087, + [BOARD_PCI6515] = { .name = "pci-6515", .num_di_ports = 4, .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x70c9, + [BOARD_PXI6515] = { .name = "pxi-6515", .num_di_ports = 4, .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x7125, + [BOARD_PCI6516] = { .name = "pci-6516", .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x7126, + [BOARD_PCI6517] = { .name = "pci-6517", .num_do_ports = 4, .invert_outputs = 1}, - { - .dev_id = 0x7127, + [BOARD_PCI6518] = { .name = "pci-6518", .num_di_ports = 2, .num_do_ports = 2, .invert_outputs = 1}, - { - .dev_id = 0x7128, + [BOARD_PCI6519] = { .name = "pci-6519", .num_di_ports = 2, .num_do_ports = 2, .invert_outputs = 1}, - { - .dev_id = 0x71c5, + [BOARD_PCI6520] = { .name = "pci-6520", .num_di_ports = 1, .num_do_ports = 1, }, - { - .dev_id = 0x718b, + [BOARD_PCI6521] = { .name = "pci-6521", .num_di_ports = 1, .num_do_ports = 1, }, - { - .dev_id = 0x718c, + [BOARD_PXI6521] = { .name = "pxi-6521", .num_di_ports = 1, .num_do_ports = 1, }, - { - .dev_id = 0x70a9, + [BOARD_PCI6528] = { .name = "pci-6528", .num_di_ports = 3, .num_do_ports = 3, }, - { - .dev_id = 0x7086, + [BOARD_PXI6528] = { .name = "pxi-6528", .num_di_ports = 3, .num_do_ports = 3, @@ -571,38 +573,28 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, return 2; } -static const struct ni_65xx_board * -ni_65xx_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni_65xx_boards); n++) { - const struct ni_65xx_board *board = &ni_65xx_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int ni_65xx_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct ni_65xx_board *board = NULL; struct ni_65xx_private *devpriv; struct comedi_subdevice *s; unsigned i; int ret; + if (context < ARRAY_SIZE(ni_65xx_boards)) + board = &ni_65xx_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - dev->board_ptr = ni_65xx_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; @@ -613,7 +605,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, return ret; } - dev->board_name = board(dev)->name; dev->irq = mite_irq(devpriv->mite); dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, readb(devpriv->mite->daq_io_addr + ID_Register)); @@ -623,11 +614,11 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - if (board(dev)->num_di_ports) { + if (board->num_di_ports) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = - board(dev)->num_di_ports * ni_65xx_channels_per_port; + board->num_di_ports * ni_65xx_channels_per_port; s->range_table = &range_digital; s->maxdata = 1; s->insn_config = ni_65xx_dio_insn_config; @@ -641,28 +632,28 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, } s = &dev->subdevices[1]; - if (board(dev)->num_do_ports) { + if (board->num_do_ports) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = - board(dev)->num_do_ports * ni_65xx_channels_per_port; + board->num_do_ports * ni_65xx_channels_per_port; s->range_table = &range_digital; s->maxdata = 1; s->insn_bits = ni_65xx_dio_insn_bits; s->private = ni_65xx_alloc_subdevice_private(); if (s->private == NULL) return -ENOMEM; - sprivate(s)->base_port = board(dev)->num_di_ports; + sprivate(s)->base_port = board->num_di_ports; } else { s->type = COMEDI_SUBD_UNUSED; } s = &dev->subdevices[2]; - if (board(dev)->num_dio_ports) { + if (board->num_dio_ports) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = - board(dev)->num_dio_ports * ni_65xx_channels_per_port; + board->num_dio_ports * ni_65xx_channels_per_port; s->range_table = &range_digital; s->maxdata = 1; s->insn_config = ni_65xx_dio_insn_config; @@ -671,7 +662,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, if (s->private == NULL) return -ENOMEM; sprivate(s)->base_port = 0; - for (i = 0; i < board(dev)->num_dio_ports; ++i) { + for (i = 0; i < board->num_dio_ports; ++i) { /* configure all ports for input */ writeb(0x1, devpriv->mite->daq_io_addr + @@ -694,10 +685,10 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, s->insn_bits = ni_65xx_intr_insn_bits; s->insn_config = ni_65xx_intr_insn_config; - for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) { + for (i = 0; i < ni_65xx_total_num_ports(board); ++i) { writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(i)); - if (board(dev)->invert_outputs) + if (board->invert_outputs) writeb(0x01, devpriv->mite->daq_io_addr + Port_Data(i)); else @@ -763,28 +754,28 @@ static int ni_65xx_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1710) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7085) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7086) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7087) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7088) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70a9) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c3) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c8) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c9) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70cc) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70CD) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d1) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d2) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d3) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7124) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7125) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7126) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7127) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7128) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718b) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718c) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71c5) }, + { PCI_VDEVICE(NI, 0x1710), BOARD_PXI6509 }, + { PCI_VDEVICE(NI, 0x7085), BOARD_PCI6509 }, + { PCI_VDEVICE(NI, 0x7086), BOARD_PXI6528 }, + { PCI_VDEVICE(NI, 0x7087), BOARD_PCI6515 }, + { PCI_VDEVICE(NI, 0x7088), BOARD_PCI6514 }, + { PCI_VDEVICE(NI, 0x70a9), BOARD_PCI6528 }, + { PCI_VDEVICE(NI, 0x70c3), BOARD_PCI6511 }, + { PCI_VDEVICE(NI, 0x70c8), BOARD_PCI6513 }, + { PCI_VDEVICE(NI, 0x70c9), BOARD_PXI6515 }, + { PCI_VDEVICE(NI, 0x70cc), BOARD_PCI6512 }, + { PCI_VDEVICE(NI, 0x70cd), BOARD_PXI6514 }, + { PCI_VDEVICE(NI, 0x70d1), BOARD_PXI6513 }, + { PCI_VDEVICE(NI, 0x70d2), BOARD_PXI6512 }, + { PCI_VDEVICE(NI, 0x70d3), BOARD_PXI6511 }, + { PCI_VDEVICE(NI, 0x7124), BOARD_PCI6510 }, + { PCI_VDEVICE(NI, 0x7125), BOARD_PCI6516 }, + { PCI_VDEVICE(NI, 0x7126), BOARD_PCI6517 }, + { PCI_VDEVICE(NI, 0x7127), BOARD_PCI6518 }, + { PCI_VDEVICE(NI, 0x7128), BOARD_PCI6519 }, + { PCI_VDEVICE(NI, 0x718b), BOARD_PCI6521 }, + { PCI_VDEVICE(NI, 0x718c), BOARD_PXI6521 }, + { PCI_VDEVICE(NI, 0x71c5), BOARD_PCI6520 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table); -- cgit From 7fd80eb0aa4183a2f950f5d34dfcc47812f83371 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:05:20 -0700 Subject: staging: comedi: ni_65xx: remove board() helper function This local helper function is a duplicate of the comedi core privided comedi_board() helper. Use that function instead and use a local variable to hold the boardinfo pointer instead of calling the helper each time the boardinfo is accessed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 34b93d2083be..747f7700875b 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -243,10 +243,6 @@ static const struct ni_65xx_board ni_65xx_boards[] = { }; #define n_ni_65xx_boards ARRAY_SIZE(ni_65xx_boards) -static inline const struct ni_65xx_board *board(struct comedi_device *dev) -{ - return dev->board_ptr; -} static inline unsigned ni_65xx_port_by_channel(unsigned channel) { @@ -372,6 +368,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_65xx_board *board = comedi_board(dev); struct ni_65xx_private *devpriv = dev->private; unsigned base_bitfield_channel; const unsigned max_ports_per_bitfield = 5; @@ -387,7 +384,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, unsigned base_port_channel; unsigned port_mask, port_data, port_read_bits; int bitshift; - if (port >= ni_65xx_total_num_ports(board(dev))) + if (port >= ni_65xx_total_num_ports(board)) break; base_port_channel = port_offset * ni_65xx_channels_per_port; port_mask = data[0]; @@ -410,7 +407,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, devpriv->output_bits[port] |= port_data & port_mask; bits = devpriv->output_bits[port]; - if (board(dev)->invert_outputs) + if (board->invert_outputs) bits = ~bits; writeb(bits, devpriv->mite->daq_io_addr + @@ -418,7 +415,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, } port_read_bits = readb(devpriv->mite->daq_io_addr + Port_Data(port)); - if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) { + if (s->type == COMEDI_SUBD_DO && board->invert_outputs) { /* Outputs inverted, so invert value read back from * DO subdevice. (Does not apply to boards with DIO * subdevice.) */ -- cgit From 8f5d4e0385c160a7442b9288f4ac2fbc8d44fe6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:15:15 -0700 Subject: staging: comedi: ni_65xx: remove n_ni_65xx_boards macro This macro is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 747f7700875b..9d824c59123a 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -242,8 +242,6 @@ static const struct ni_65xx_board ni_65xx_boards[] = { }, }; -#define n_ni_65xx_boards ARRAY_SIZE(ni_65xx_boards) - static inline unsigned ni_65xx_port_by_channel(unsigned channel) { return channel / ni_65xx_channels_per_port; -- cgit From e4f0e1302908488fd2761a76d2d8cbddc1d291a7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:15:40 -0700 Subject: staging: comedi: ni_65xx: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 159 +++++++++++++++++-------------- 1 file changed, 87 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 9d824c59123a..74a1e65010cf 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -147,99 +147,114 @@ struct ni_65xx_board { static const struct ni_65xx_board ni_65xx_boards[] = { [BOARD_PCI6509] = { - .name = "pci-6509", - .num_dio_ports = 12, - .invert_outputs = 0}, + .name = "pci-6509", + .num_dio_ports = 12, + }, [BOARD_PXI6509] = { - .name = "pxi-6509", - .num_dio_ports = 12, - .invert_outputs = 0}, + .name = "pxi-6509", + .num_dio_ports = 12, + }, [BOARD_PCI6510] = { - .name = "pci-6510", - .num_di_ports = 4}, + .name = "pci-6510", + .num_di_ports = 4, + }, [BOARD_PCI6511] = { - .name = "pci-6511", - .num_di_ports = 8}, + .name = "pci-6511", + .num_di_ports = 8, + }, [BOARD_PXI6511] = { - .name = "pxi-6511", - .num_di_ports = 8}, + .name = "pxi-6511", + .num_di_ports = 8, + }, [BOARD_PCI6512] = { - .name = "pci-6512", - .num_do_ports = 8}, + .name = "pci-6512", + .num_do_ports = 8, + }, [BOARD_PXI6512] = { - .name = "pxi-6512", - .num_do_ports = 8}, + .name = "pxi-6512", + .num_do_ports = 8, + }, [BOARD_PCI6513] = { - .name = "pci-6513", - .num_do_ports = 8, - .invert_outputs = 1}, + .name = "pci-6513", + .num_do_ports = 8, + .invert_outputs = 1, + }, [BOARD_PXI6513] = { - .name = "pxi-6513", - .num_do_ports = 8, - .invert_outputs = 1}, + .name = "pxi-6513", + .num_do_ports = 8, + .invert_outputs = 1, + }, [BOARD_PCI6514] = { - .name = "pci-6514", - .num_di_ports = 4, - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pci-6514", + .num_di_ports = 4, + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PXI6514] = { - .name = "pxi-6514", - .num_di_ports = 4, - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pxi-6514", + .num_di_ports = 4, + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PCI6515] = { - .name = "pci-6515", - .num_di_ports = 4, - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pci-6515", + .num_di_ports = 4, + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PXI6515] = { - .name = "pxi-6515", - .num_di_ports = 4, - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pxi-6515", + .num_di_ports = 4, + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PCI6516] = { - .name = "pci-6516", - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pci-6516", + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PCI6517] = { - .name = "pci-6517", - .num_do_ports = 4, - .invert_outputs = 1}, + .name = "pci-6517", + .num_do_ports = 4, + .invert_outputs = 1, + }, [BOARD_PCI6518] = { - .name = "pci-6518", - .num_di_ports = 2, - .num_do_ports = 2, - .invert_outputs = 1}, + .name = "pci-6518", + .num_di_ports = 2, + .num_do_ports = 2, + .invert_outputs = 1, + }, [BOARD_PCI6519] = { - .name = "pci-6519", - .num_di_ports = 2, - .num_do_ports = 2, - .invert_outputs = 1}, + .name = "pci-6519", + .num_di_ports = 2, + .num_do_ports = 2, + .invert_outputs = 1, + }, [BOARD_PCI6520] = { - .name = "pci-6520", - .num_di_ports = 1, - .num_do_ports = 1, - }, + .name = "pci-6520", + .num_di_ports = 1, + .num_do_ports = 1, + }, [BOARD_PCI6521] = { - .name = "pci-6521", - .num_di_ports = 1, - .num_do_ports = 1, - }, + .name = "pci-6521", + .num_di_ports = 1, + .num_do_ports = 1, + }, [BOARD_PXI6521] = { - .name = "pxi-6521", - .num_di_ports = 1, - .num_do_ports = 1, - }, + .name = "pxi-6521", + .num_di_ports = 1, + .num_do_ports = 1, + }, [BOARD_PCI6528] = { - .name = "pci-6528", - .num_di_ports = 3, - .num_do_ports = 3, - }, + .name = "pci-6528", + .num_di_ports = 3, + .num_do_ports = 3, + }, [BOARD_PXI6528] = { - .name = "pxi-6528", - .num_di_ports = 3, - .num_do_ports = 3, - }, + .name = "pxi-6528", + .num_di_ports = 3, + .num_do_ports = 3, + }, }; static inline unsigned ni_65xx_port_by_channel(unsigned channel) -- cgit From 97bcce5a4cf420986670c43923aa4bc5efa9bc2e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:16:16 -0700 Subject: staging: comedi: ni_660x: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 63 +++++++++++++------------------- 1 file changed, 25 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index cf05d665ba9e..eae0e4acc053 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -389,31 +389,32 @@ enum global_interrupt_config_register_bits { /* First chip is at base-address + 0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; -/* Board description*/ +enum ni_660x_boardid { + BOARD_PCI6601, + BOARD_PCI6602, + BOARD_PXI6602, + BOARD_PXI6608, +}; + struct ni_660x_board { - unsigned short dev_id; /* `lspci` will show you this */ const char *name; unsigned n_chips; /* total number of TIO chips */ }; static const struct ni_660x_board ni_660x_boards[] = { - { - .dev_id = 0x2c60, + [BOARD_PCI6601] = { .name = "PCI-6601", .n_chips = 1, }, - { - .dev_id = 0x1310, + [BOARD_PCI6602] = { .name = "PCI-6602", .n_chips = 2, }, - { - .dev_id = 0x1360, + [BOARD_PXI6602] = { .name = "PXI-6602", .n_chips = 2, }, - { - .dev_id = 0x2cc0, + [BOARD_PXI6608] = { .name = "PXI-6608", .n_chips = 2, }, @@ -974,20 +975,6 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -static const struct ni_660x_board * -ni_660x_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni_660x_boards); n++) { - const struct ni_660x_board *board = &ni_660x_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1170,32 +1157,32 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, } static int ni_660x_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct ni_660x_board *board; + const struct ni_660x_board *board = NULL; struct ni_660x_private *devpriv; struct comedi_subdevice *s; int ret; unsigned i; unsigned global_interrupt_config_bits; + if (context < ARRAY_SIZE(ni_660x_boards)) + board = &ni_660x_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; devpriv = dev->private; - dev->board_ptr = ni_660x_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - board = comedi_board(dev); - devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; - dev->board_name = board->name; - ret = mite_setup2(devpriv->mite, 1); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); @@ -1331,11 +1318,11 @@ static int ni_660x_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, - {0} + { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 }, + { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, + { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, + { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 }, + { 0 } }; MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); -- cgit From e2b8360fd13cd5e211e2bd2ba0f04d97bf6e409b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:16:42 -0700 Subject: staging: comedi: ni_660x: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index eae0e4acc053..d2e061a195d0 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -403,21 +403,21 @@ struct ni_660x_board { static const struct ni_660x_board ni_660x_boards[] = { [BOARD_PCI6601] = { - .name = "PCI-6601", - .n_chips = 1, - }, + .name = "PCI-6601", + .n_chips = 1, + }, [BOARD_PCI6602] = { - .name = "PCI-6602", - .n_chips = 2, - }, + .name = "PCI-6602", + .n_chips = 2, + }, [BOARD_PXI6602] = { - .name = "PXI-6602", - .n_chips = 2, - }, + .name = "PXI-6602", + .n_chips = 2, + }, [BOARD_PXI6608] = { - .name = "PXI-6608", - .n_chips = 2, - }, + .name = "PXI-6608", + .n_chips = 2, + }, }; #define NI_660X_MAX_NUM_CHIPS 2 -- cgit From 3bac78caf1f70fb93d3021d86cca83ee783e35c0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:17:07 -0700 Subject: staging: comedi: ni_670x: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_670x.c | 53 +++++++++++++------------------- 1 file changed, 22 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index e60e1ba358d6..0e7b957afbe4 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -60,26 +60,28 @@ Commands are not supported. #define MISC_STATUS_OFFSET 0x14 #define MISC_CONTROL_OFFSET 0x14 -/* Board description*/ +enum ni_670x_boardid { + BOARD_PCI6703, + BOARD_PXI6704, + BOARD_PCI6704, +}; struct ni_670x_board { const char *name; - unsigned short dev_id; unsigned short ao_chans; }; static const struct ni_670x_board ni_670x_boards[] = { - { + [BOARD_PCI6703] = { .name = "PCI-6703", - .dev_id = 0x2c90, .ao_chans = 16, - }, { + }, + [BOARD_PXI6704] = { .name = "PXI-6704", - .dev_id = 0x1920, .ao_chans = 32, - }, { + }, + [BOARD_PCI6704] = { .name = "PCI-6704", - .dev_id = 0x1290, .ao_chans = 32, }, }; @@ -189,49 +191,37 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, return insn->n; } -static const struct ni_670x_board * -ni_670x_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni_670x_boards); n++) { - const struct ni_670x_board *board = &ni_670x_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int ni_670x_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct ni_670x_board *thisboard; + const struct ni_670x_board *thisboard = NULL; struct ni_670x_private *devpriv; struct comedi_subdevice *s; int ret; int i; + if (context < ARRAY_SIZE(ni_670x_boards)) + thisboard = &ni_670x_boards[context]; + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - dev->board_ptr = ni_670x_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; - thisboard = comedi_board(dev); ret = mite_setup(devpriv->mite); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 2); if (ret) @@ -312,8 +302,9 @@ static int ni_670x_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c90) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1920) }, + { PCI_VDEVICE(NI, 0x1290), BOARD_PCI6704 }, + { PCI_VDEVICE(NI, 0x1920), BOARD_PXI6704 }, + { PCI_VDEVICE(NI, 0x2c90), BOARD_PCI6703 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_670x_pci_table); -- cgit From 6d6d443cb29671c5bb1d67cbbaacbfc503409581 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:17:31 -0700 Subject: staging: comedi: ni_pcidio: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'dev_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 52 +++++++++++++----------------- 1 file changed, 23 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index f4d3fab6f2d5..2c7538bae238 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -280,21 +280,25 @@ enum FPGA_Control_Bits { static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); +enum nidio_boardid { + BOARD_PCIDIO_32HS, + BOARD_PXI6533, + BOARD_PCI6534, +}; + struct nidio_board { - int dev_id; const char *name; unsigned int uses_firmware:1; }; static const struct nidio_board nidio_boards[] = { - { - .dev_id = 0x1150, + [BOARD_PCIDIO_32HS] = { .name = "pci-dio-32hs", - }, { - .dev_id = 0x1320, + }, + [BOARD_PXI6533] = { .name = "pxi-6533", - }, { - .dev_id = 0x12b0, + }, + [BOARD_PCI6534] = { .name = "pci-6534", .uses_firmware = 1, }, @@ -1094,29 +1098,23 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) return ret; } -static const struct nidio_board * -nidio_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(nidio_boards); n++) { - const struct nidio_board *board = &nidio_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int nidio_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct nidio_board *board = NULL; struct nidio96_private *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; + if (context < ARRAY_SIZE(nidio_boards)) + board = &nidio_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = this_board->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -1124,9 +1122,6 @@ static int nidio_auto_attach(struct comedi_device *dev, spin_lock_init(&devpriv->mite_channel_lock); - dev->board_ptr = nidio_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; @@ -1141,7 +1136,6 @@ static int nidio_auto_attach(struct comedi_device *dev, if (devpriv->di_mite_ring == NULL) return -ENOMEM; - dev->board_name = this_board->name; irq = mite_irq(devpriv->mite); if (this_board->uses_firmware) { ret = pci_6534_upload_firmware(dev); @@ -1227,9 +1221,9 @@ static int ni_pcidio_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0) }, + { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS }, + { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 }, + { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); -- cgit From e69e860ef2f05df0f8f31854f8b353b9a52e85e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:18:04 -0700 Subject: staging: comedi: ni_pcidio: remove n_ndio_boards macro This macro is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 2c7538bae238..01da281e32e6 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -304,7 +304,6 @@ static const struct nidio_board nidio_boards[] = { }, }; -#define n_nidio_boards ARRAY_SIZE(nidio_boards) #define this_board ((const struct nidio_board *)dev->board_ptr) struct nidio96_private { -- cgit From 715988871f82a00b8bb36b7f2fdbd865c09b170e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:19:36 -0700 Subject: staging: comedi: ni_pcidio: remove this_board macro This macro relies on a local variable having a specific name and derives a pointer from that local variable. It's only used in the attach and we already have the local variable 'board' that has the same information. Use that instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 01da281e32e6..50e025b07780 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -304,8 +304,6 @@ static const struct nidio_board nidio_boards[] = { }, }; -#define this_board ((const struct nidio_board *)dev->board_ptr) - struct nidio96_private { struct mite_struct *mite; int boardtype; @@ -1112,7 +1110,7 @@ static int nidio_auto_attach(struct comedi_device *dev, if (!board) return -ENODEV; dev->board_ptr = board; - dev->board_name = this_board->name; + dev->board_name = board->name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -1136,7 +1134,7 @@ static int nidio_auto_attach(struct comedi_device *dev, return -ENOMEM; irq = mite_irq(devpriv->mite); - if (this_board->uses_firmware) { + if (board->uses_firmware) { ret = pci_6534_upload_firmware(dev); if (ret < 0) return ret; -- cgit From a25a701afa508f58f622b8121cb2dcfdfaf6e9d2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:20:06 -0700 Subject: staging: comedi: ni_pcimio: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. A couple of the entries in the boardinfo are #if 0'ed out due to unknown device ids. Add the enums for them also but comment them out. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Remove the dev_info function trace noise in the attach. Use the boardinfo 'board' pointer instead of accessing the data directly with the 'boardtype' macro in the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 378 ++++++++++++++--------------- 1 file changed, 183 insertions(+), 195 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index e626ac046b7f..175770a8b95c 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -163,9 +163,68 @@ static const struct comedi_lrange range_ni_M_622x_ao = { 1, { } }; +enum ni_pcimio_boardid { + BOARD_PCIMIO_16XE_50, + BOARD_PCIMIO_16XE_10, + BOARD_PCI6014, + BOARD_PXI6030E, + BOARD_PCIMIO_16E_1, + BOARD_PCIMIO_16E_4, + BOARD_PXI6040E, + BOARD_PCI6031E, + BOARD_PCI6032E, + BOARD_PCI6033E, + BOARD_PCI6071E, + BOARD_PCI6023E, + BOARD_PCI6024E, + BOARD_PCI6025E, + BOARD_PXI6025E, + BOARD_PCI6034E, + BOARD_PCI6035E, + BOARD_PCI6052E, + BOARD_PCI6110, + BOARD_PCI6111, + /* BOARD_PCI6115, */ + /* BOARD_PXI6115, */ + BOARD_PCI6711, + BOARD_PXI6711, + BOARD_PCI6713, + BOARD_PXI6713, + BOARD_PCI6731, + /* BOARD_PXI6731, */ + BOARD_PCI6733, + BOARD_PXI6733, + BOARD_PXI6071E, + BOARD_PXI6070E, + BOARD_PXI6052E, + BOARD_PXI6031E, + BOARD_PCI6036E, + BOARD_PCI6220, + BOARD_PCI6221, + BOARD_PCI6221_37PIN, + BOARD_PCI6224, + BOARD_PXI6224, + BOARD_PCI6225, + BOARD_PXI6225, + BOARD_PCI6229, + BOARD_PCI6250, + BOARD_PCI6251, + BOARD_PCIE6251, + BOARD_PXIE6251, + BOARD_PCI6254, + BOARD_PCI6259, + BOARD_PCIE6259, + BOARD_PCI6280, + BOARD_PCI6281, + BOARD_PXI6281, + BOARD_PCI6284, + BOARD_PCI6289, + BOARD_PCI6143, + BOARD_PXI6143, +}; + static const struct ni_board_struct ni_boards[] = { - { - .device_id = 0x0162, /* NI also says 0x1620. typo? */ + [BOARD_PCIMIO_16XE_50] = { .name = "pci-mio-16xe-50", .n_adchan = 16, .adbits = 16, @@ -183,8 +242,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043}, .has_8255 = 0, }, - { - .device_id = 0x1170, + [BOARD_PCIMIO_16XE_10] = { .name = "pci-mio-16xe-10", /* aka pci-6030E */ .n_adchan = 16, .adbits = 16, @@ -202,8 +260,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043, ad8522}, .has_8255 = 0, }, - { - .device_id = 0x28c0, + [BOARD_PCI6014] = { .name = "pci-6014", .n_adchan = 16, .adbits = 16, @@ -221,8 +278,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x11d0, + [BOARD_PXI6030E] = { .name = "pxi-6030e", .n_adchan = 16, .adbits = 16, @@ -240,8 +296,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043, ad8522}, .has_8255 = 0, }, - { - .device_id = 0x1180, + [BOARD_PCIMIO_16E_1] = { .name = "pci-mio-16e-1", /* aka pci-6070e */ .n_adchan = 16, .adbits = 12, @@ -259,8 +314,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {mb88341}, .has_8255 = 0, }, - { - .device_id = 0x1190, + [BOARD_PCIMIO_16E_4] = { .name = "pci-mio-16e-4", /* aka pci-6040e */ .n_adchan = 16, .adbits = 12, @@ -280,8 +334,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, /* doc says mb88341 */ .has_8255 = 0, }, - { - .device_id = 0x11c0, + [BOARD_PXI6040E] = { .name = "pxi-6040e", .n_adchan = 16, .adbits = 12, @@ -299,9 +352,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {mb88341}, .has_8255 = 0, }, - - { - .device_id = 0x1330, + [BOARD_PCI6031E] = { .name = "pci-6031e", .n_adchan = 64, .adbits = 16, @@ -319,8 +370,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043, ad8522}, .has_8255 = 0, }, - { - .device_id = 0x1270, + [BOARD_PCI6032E] = { .name = "pci-6032e", .n_adchan = 16, .adbits = 16, @@ -336,8 +386,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043, ad8522}, .has_8255 = 0, }, - { - .device_id = 0x1340, + [BOARD_PCI6033E] = { .name = "pci-6033e", .n_adchan = 64, .adbits = 16, @@ -353,8 +402,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {dac8800, dac8043, ad8522}, .has_8255 = 0, }, - { - .device_id = 0x1350, + [BOARD_PCI6071E] = { .name = "pci-6071e", .n_adchan = 64, .adbits = 12, @@ -372,8 +420,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x2a60, + [BOARD_PCI6023E] = { .name = "pci-6023e", .n_adchan = 16, .adbits = 12, @@ -388,8 +435,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, /* manual is wrong */ .has_8255 = 0, }, - { - .device_id = 0x2a70, + [BOARD_PCI6024E] = { .name = "pci-6024e", .n_adchan = 16, .adbits = 12, @@ -407,8 +453,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, /* manual is wrong */ .has_8255 = 0, }, - { - .device_id = 0x2a80, + [BOARD_PCI6025E] = { .name = "pci-6025e", .n_adchan = 16, .adbits = 12, @@ -426,8 +471,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, /* manual is wrong */ .has_8255 = 1, }, - { - .device_id = 0x2ab0, + [BOARD_PXI6025E] = { .name = "pxi-6025e", .n_adchan = 16, .adbits = 12, @@ -445,9 +489,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, /* manual is wrong */ .has_8255 = 1, }, - - { - .device_id = 0x2ca0, + [BOARD_PCI6034E] = { .name = "pci-6034e", .n_adchan = 16, .adbits = 16, @@ -463,8 +505,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x2c80, + [BOARD_PCI6035E] = { .name = "pci-6035e", .n_adchan = 16, .adbits = 16, @@ -482,8 +523,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x18b0, + [BOARD_PCI6052E] = { .name = "pci-6052e", .n_adchan = 16, .adbits = 16, @@ -500,7 +540,7 @@ static const struct ni_board_struct ni_boards[] = { .num_p0_dio_channels = 8, .caldac = {ad8804_debug, ad8804_debug, ad8522}, /* manual is wrong */ }, - {.device_id = 0x14e0, + [BOARD_PCI6110] = { .name = "pci-6110", .n_adchan = 4, .adbits = 12, @@ -518,8 +558,7 @@ static const struct ni_board_struct ni_boards[] = { .num_p0_dio_channels = 8, .caldac = {ad8804, ad8804}, }, - { - .device_id = 0x14f0, + [BOARD_PCI6111] = { .name = "pci-6111", .n_adchan = 2, .adbits = 12, @@ -539,8 +578,7 @@ static const struct ni_board_struct ni_boards[] = { }, #if 0 /* The 6115 boards probably need their own driver */ - { - .device_id = 0x2ed0, + [BOARD_PCI6115] = { /* .device_id = 0x2ed0, */ .name = "pci-6115", .n_adchan = 4, .adbits = 12, @@ -560,8 +598,7 @@ static const struct ni_board_struct ni_boards[] = { }, #endif #if 0 - { - .device_id = 0x0000, + [BOARD_PXI6115] = { /* .device_id = ????, */ .name = "pxi-6115", .n_adchan = 4, .adbits = 12, @@ -580,8 +617,7 @@ static const struct ni_board_struct ni_boards[] = { caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */ }, #endif - { - .device_id = 0x1880, + [BOARD_PCI6711] = { .name = "pci-6711", .n_adchan = 0, /* no analog input */ .n_aochan = 4, @@ -595,8 +631,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6711, .caldac = {ad8804_debug}, }, - { - .device_id = 0x2b90, + [BOARD_PXI6711] = { .name = "pxi-6711", .n_adchan = 0, /* no analog input */ .n_aochan = 4, @@ -609,8 +644,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6711, .caldac = {ad8804_debug}, }, - { - .device_id = 0x1870, + [BOARD_PCI6713] = { .name = "pci-6713", .n_adchan = 0, /* no analog input */ .n_aochan = 8, @@ -623,8 +657,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6713, .caldac = {ad8804_debug, ad8804_debug}, }, - { - .device_id = 0x2b80, + [BOARD_PXI6713] = { .name = "pxi-6713", .n_adchan = 0, /* no analog input */ .n_aochan = 8, @@ -637,8 +670,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6713, .caldac = {ad8804_debug, ad8804_debug}, }, - { - .device_id = 0x2430, + [BOARD_PCI6731] = { .name = "pci-6731", .n_adchan = 0, /* no analog input */ .n_aochan = 4, @@ -651,9 +683,8 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6711, .caldac = {ad8804_debug}, }, -#if 0 /* need device ids */ - { - .device_id = 0x0, +#if 0 + [BOARD_PXI6731] = { /* .device_id = ????, */ .name = "pxi-6731", .n_adchan = 0, /* no analog input */ .n_aochan = 4, @@ -666,8 +697,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, }, #endif - { - .device_id = 0x2410, + [BOARD_PCI6733] = { .name = "pci-6733", .n_adchan = 0, /* no analog input */ .n_aochan = 8, @@ -680,8 +710,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6713, .caldac = {ad8804_debug, ad8804_debug}, }, - { - .device_id = 0x2420, + [BOARD_PXI6733] = { .name = "pxi-6733", .n_adchan = 0, /* no analog input */ .n_aochan = 8, @@ -694,8 +723,7 @@ static const struct ni_board_struct ni_boards[] = { .reg_type = ni_reg_6713, .caldac = {ad8804_debug, ad8804_debug}, }, - { - .device_id = 0x15b0, + [BOARD_PXI6071E] = { .name = "pxi-6071e", .n_adchan = 64, .adbits = 12, @@ -713,8 +741,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x11b0, + [BOARD_PXI6070E] = { .name = "pxi-6070e", .n_adchan = 16, .adbits = 12, @@ -732,8 +759,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x18c0, + [BOARD_PXI6052E] = { .name = "pxi-6052e", .n_adchan = 16, .adbits = 16, @@ -750,8 +776,7 @@ static const struct ni_board_struct ni_boards[] = { .num_p0_dio_channels = 8, .caldac = {mb88341, mb88341, ad8522}, }, - { - .device_id = 0x1580, + [BOARD_PXI6031E] = { .name = "pxi-6031e", .n_adchan = 64, .adbits = 16, @@ -768,8 +793,7 @@ static const struct ni_board_struct ni_boards[] = { .num_p0_dio_channels = 8, .caldac = {dac8800, dac8043, ad8522}, }, - { - .device_id = 0x2890, + [BOARD_PCI6036E] = { .name = "pci-6036e", .n_adchan = 16, .adbits = 16, @@ -787,8 +811,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {ad8804_debug}, .has_8255 = 0, }, - { - .device_id = 0x70b0, + [BOARD_PCI6220] = { .name = "pci-6220", .n_adchan = 16, .adbits = 16, @@ -805,8 +828,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70af, + [BOARD_PCI6221] = { .name = "pci-6221", .n_adchan = 16, .adbits = 16, @@ -824,8 +846,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x71bc, + [BOARD_PCI6221_37PIN] = { .name = "pci-6221_37pin", .n_adchan = 16, .adbits = 16, @@ -843,8 +864,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70f2, + [BOARD_PCI6224] = { .name = "pci-6224", .n_adchan = 32, .adbits = 16, @@ -860,8 +880,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70f3, + [BOARD_PXI6224] = { .name = "pxi-6224", .n_adchan = 32, .adbits = 16, @@ -877,8 +896,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x716c, + [BOARD_PCI6225] = { .name = "pci-6225", .n_adchan = 80, .adbits = 16, @@ -896,8 +914,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x716d, + [BOARD_PXI6225] = { .name = "pxi-6225", .n_adchan = 80, .adbits = 16, @@ -915,8 +932,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70aa, + [BOARD_PCI6229] = { .name = "pci-6229", .n_adchan = 32, .adbits = 16, @@ -934,8 +950,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70b4, + [BOARD_PCI6250] = { .name = "pci-6250", .n_adchan = 16, .adbits = 16, @@ -951,8 +966,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70b8, + [BOARD_PCI6251] = { .name = "pci-6251", .n_adchan = 16, .adbits = 16, @@ -970,8 +984,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x717d, + [BOARD_PCIE6251] = { .name = "pcie-6251", .n_adchan = 16, .adbits = 16, @@ -989,8 +1002,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x72e8, + [BOARD_PXIE6251] = { .name = "pxie-6251", .n_adchan = 16, .adbits = 16, @@ -1008,8 +1020,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70b7, + [BOARD_PCI6254] = { .name = "pci-6254", .n_adchan = 32, .adbits = 16, @@ -1025,8 +1036,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70ab, + [BOARD_PCI6259] = { .name = "pci-6259", .n_adchan = 32, .adbits = 16, @@ -1044,8 +1054,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x717f, + [BOARD_PCIE6259] = { .name = "pcie-6259", .n_adchan = 32, .adbits = 16, @@ -1063,8 +1072,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70b6, + [BOARD_PCI6280] = { .name = "pci-6280", .n_adchan = 16, .adbits = 18, @@ -1080,8 +1088,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70bd, + [BOARD_PCI6281] = { .name = "pci-6281", .n_adchan = 16, .adbits = 18, @@ -1099,8 +1106,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70bf, + [BOARD_PXI6281] = { .name = "pxi-6281", .n_adchan = 16, .adbits = 18, @@ -1118,8 +1124,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70bc, + [BOARD_PCI6284] = { .name = "pci-6284", .n_adchan = 32, .adbits = 18, @@ -1135,8 +1140,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70ac, + [BOARD_PCI6289] = { .name = "pci-6289", .n_adchan = 32, .adbits = 18, @@ -1154,8 +1158,7 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, - { - .device_id = 0x70C0, + [BOARD_PCI6143] = { .name = "pci-6143", .n_adchan = 8, .adbits = 16, @@ -1171,8 +1174,7 @@ static const struct ni_board_struct ni_boards[] = { .num_p0_dio_channels = 8, .caldac = {ad8804_debug, ad8804_debug}, }, - { - .device_id = 0x710D, + [BOARD_PXI6143] = { .name = "pxi-6143", .n_adchan = 8, .adbits = 16, @@ -1608,46 +1610,31 @@ static void pcimio_detach(struct comedi_device *dev) } } -static const struct ni_board_struct * -pcimio_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int device_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni_boards); n++) { - const struct ni_board_struct *board = &ni_boards[n]; - if (board->device_id == device_id) - return board; - } - return NULL; -} - static int pcimio_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct ni_board_struct *board = NULL; struct ni_private *devpriv; int ret; - dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev)); + if (context < ARRAY_SIZE(ni_boards)) + board = &ni_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; ret = ni_alloc_private(dev); if (ret) return ret; devpriv = dev->private; - dev->board_ptr = pcimio_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; - dev_dbg(dev->class_dev, "%s\n", boardtype.name); - dev->board_name = boardtype.name; - - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { devpriv->stc_writew = &m_series_stc_writew; devpriv->stc_readw = &m_series_stc_readw; devpriv->stc_writel = &m_series_stc_writel; @@ -1681,9 +1668,9 @@ static int pcimio_auto_attach(struct comedi_device *dev, if (devpriv->gpct_mite_ring[1] == NULL) return -ENOMEM; - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) m_series_init_eeprom_buffer(dev); - if (boardtype.reg_type == ni_reg_6143) + if (board->reg_type == ni_reg_6143) init_6143(dev); dev->irq = mite_irq(devpriv->mite); @@ -1794,59 +1781,60 @@ static int ni_pcimio_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0162) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1170) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1180) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1190) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11b0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11c0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11d0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1270) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1330) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1340) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1350) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14e0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14f0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1580) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x15b0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1880) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1870) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18b0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18c0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2410) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2420) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2430) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2890) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x28c0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a60) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a70) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a80) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ab0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b80) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b90) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c80) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ca0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70aa) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ab) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ac) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70af) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b4) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b6) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b7) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b8) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bc) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bd) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bf) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c0) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70f2) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x710d) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716c) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716d) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d) }, - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8) }, + { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */ + { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 }, + { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 }, + { PCI_VDEVICE(NI, 0x1190), BOARD_PCIMIO_16E_4 }, + { PCI_VDEVICE(NI, 0x11b0), BOARD_PXI6070E }, + { PCI_VDEVICE(NI, 0x11c0), BOARD_PXI6040E }, + { PCI_VDEVICE(NI, 0x11d0), BOARD_PXI6030E }, + { PCI_VDEVICE(NI, 0x1270), BOARD_PCI6032E }, + { PCI_VDEVICE(NI, 0x1330), BOARD_PCI6031E }, + { PCI_VDEVICE(NI, 0x1340), BOARD_PCI6033E }, + { PCI_VDEVICE(NI, 0x1350), BOARD_PCI6071E }, + { PCI_VDEVICE(NI, 0x14e0), BOARD_PCI6110 }, + { PCI_VDEVICE(NI, 0x14f0), BOARD_PCI6111 }, + { PCI_VDEVICE(NI, 0x1580), BOARD_PXI6031E }, + { PCI_VDEVICE(NI, 0x15b0), BOARD_PXI6071E }, + { PCI_VDEVICE(NI, 0x1880), BOARD_PCI6711 }, + { PCI_VDEVICE(NI, 0x1870), BOARD_PCI6713 }, + { PCI_VDEVICE(NI, 0x18b0), BOARD_PCI6052E }, + { PCI_VDEVICE(NI, 0x18c0), BOARD_PXI6052E }, + { PCI_VDEVICE(NI, 0x2410), BOARD_PCI6733 }, + { PCI_VDEVICE(NI, 0x2420), BOARD_PXI6733 }, + { PCI_VDEVICE(NI, 0x2430), BOARD_PCI6731 }, + { PCI_VDEVICE(NI, 0x2890), BOARD_PCI6036E }, + { PCI_VDEVICE(NI, 0x28c0), BOARD_PCI6014 }, + { PCI_VDEVICE(NI, 0x2a60), BOARD_PCI6023E }, + { PCI_VDEVICE(NI, 0x2a70), BOARD_PCI6024E }, + { PCI_VDEVICE(NI, 0x2a80), BOARD_PCI6025E }, + { PCI_VDEVICE(NI, 0x2ab0), BOARD_PXI6025E }, + { PCI_VDEVICE(NI, 0x2b80), BOARD_PXI6713 }, + { PCI_VDEVICE(NI, 0x2b90), BOARD_PXI6711 }, + { PCI_VDEVICE(NI, 0x2c80), BOARD_PCI6035E }, + { PCI_VDEVICE(NI, 0x2ca0), BOARD_PCI6034E }, + { PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 }, + { PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 }, + { PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 }, + { PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 }, + { PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 }, + { PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 }, + { PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 }, + { PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 }, + { PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 }, + { PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 }, + { PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 }, + { PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 }, + { PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 }, + { PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 }, + { PCI_VDEVICE(NI, 0x70f3), BOARD_PXI6224 }, + { PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 }, + { PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 }, + { PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 }, + { PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 }, + { PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN }, + { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 }, + { PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table); -- cgit From 6293e35742550320b1720044f9969d9544a5deaa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:20:41 -0700 Subject: staging: comedi: ni_stc.h: remove boardtype macro This macro relies on a local variable having a specific name and returns an object that variable points to. This object is the boardinfo used by the driver. The comedi core provides the comedi_board() helper to return a const pointer to the boardinfo. Remove the 'boardtype' macro and fix all the users of the 'boardtype' macro to use the comedi_board() helper to get the const boardinfo pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 343 ++++++++++++++----------- drivers/staging/comedi/drivers/ni_pcimio.c | 4 +- drivers/staging/comedi/drivers/ni_stc.h | 2 - 3 files changed, 198 insertions(+), 151 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index b7403597e905..208fa24295ae 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -696,9 +696,10 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev) static void ni_e_series_enable_second_irq(struct comedi_device *dev, unsigned gpct_index, short enable) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) return; switch (gpct_index) { case 0: @@ -728,16 +729,17 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev, static void ni_clear_ai_fifo(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; - if (boardtype.reg_type == ni_reg_6143) { + if (board->reg_type == ni_reg_6143) { /* Flush the 6143 data FIFO */ ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */ ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */ while (ni_readl(AIFIFO_Status_6143) & 0x10) ; /* Wait for complete */ } else { devpriv->stc_writew(dev, 1, ADC_FIFO_Clear); - if (boardtype.reg_type == ni_reg_625x) { + if (board->reg_type == ni_reg_625x) { ni_writeb(0, M_Offset_Static_AI_Control(0)); ni_writeb(1, M_Offset_Static_AI_Control(0)); #if 0 @@ -1292,6 +1294,7 @@ static void ni_mio_print_status_b(int status) static void ni_ao_fifo_load(struct comedi_device *dev, struct comedi_subdevice *s, int n) { + const struct ni_board_struct *board = comedi_board(dev); struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; int chan; @@ -1309,10 +1312,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev, range = CR_RANGE(cmd->chanlist[chan]); - if (boardtype.reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) { packed_data = d & 0xffff; /* 6711 only has 16 bit wide ao fifo */ - if (boardtype.reg_type != ni_reg_6711) { + if (board->reg_type != ni_reg_6711) { err &= comedi_buf_get(async, &d); if (err == 0) break; @@ -1352,6 +1355,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev, static int ni_ao_fifo_half_empty(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); int n; n = comedi_buf_read_n_available(s->async); @@ -1361,8 +1365,8 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, } n /= sizeof(short); - if (n > boardtype.ao_fifo_depth / 2) - n = boardtype.ao_fifo_depth / 2; + if (n > board->ao_fifo_depth / 2) + n = board->ao_fifo_depth / 2; ni_ao_fifo_load(dev, s, n); @@ -1374,12 +1378,13 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, static int ni_ao_prep_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; int n; /* reset fifo */ devpriv->stc_writew(dev, 1, DAC_FIFO_Clear); - if (boardtype.reg_type & ni_reg_6xxx_mask) + if (board->reg_type & ni_reg_6xxx_mask) ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); /* load some data */ @@ -1388,8 +1393,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, return 0; n /= sizeof(short); - if (n > boardtype.ao_fifo_depth) - n = boardtype.ao_fifo_depth; + if (n > board->ao_fifo_depth) + n = board->ao_fifo_depth; ni_ao_fifo_load(dev, s, n); @@ -1399,11 +1404,12 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, static void ni_ai_fifo_read(struct comedi_device *dev, struct comedi_subdevice *s, int n) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; int i; - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { short data[2]; u32 dl; @@ -1420,7 +1426,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, data[0] = dl & 0xffff; cfc_write_to_buffer(s, data[0]); } - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { short data[2]; u32 dl; @@ -1458,10 +1464,11 @@ static void ni_ai_fifo_read(struct comedi_device *dev, static void ni_handle_fifo_half_full(struct comedi_device *dev) { - int n; + const struct ni_board_struct *board = comedi_board(dev); struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; + int n; - n = boardtype.ai_fifo_depth / 2; + n = board->ai_fifo_depth / 2; ni_ai_fifo_read(dev, s, n); } @@ -1508,6 +1515,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) */ static void ni_handle_fifo_dregs(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data[2]; @@ -1515,7 +1523,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) short fifo_empty; int i; - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { while ((devpriv->stc_readw(dev, AI_Status_1_Register) & AI_FIFO_Empty_St) == 0) { @@ -1526,7 +1534,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) data[1] = (dl & 0xffff); cfc_write_array_to_buffer(s, data, sizeof(data)); } - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { i = 0; while (ni_readl(AIFIFO_Status_6143) & 0x04) { dl = ni_readl(AIFIFO_Data_6143); @@ -1573,12 +1581,13 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) static void get_last_sample_611x(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; - if (boardtype.reg_type != ni_reg_611x) + if (board->reg_type != ni_reg_611x) return; /* Check if there's a single sample stuck in the FIFO */ @@ -1591,12 +1600,13 @@ static void get_last_sample_611x(struct comedi_device *dev) static void get_last_sample_6143(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; - if (boardtype.reg_type != ni_reg_6143) + if (board->reg_type != ni_reg_6143) return; /* Check if there's a single sample stuck in the FIFO */ @@ -1641,6 +1651,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_setup_MITE_dma(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; int retval; @@ -1660,7 +1671,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) return -EIO; } - switch (boardtype.reg_type) { + switch (board->reg_type) { case ni_reg_611x: case ni_reg_6143: mite_prep_dma(devpriv->ai_mite_chan, 32, 16); @@ -1681,6 +1692,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) static int ni_ao_setup_MITE_dma(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; int retval; @@ -1695,7 +1707,7 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->ao_mite_chan) { - if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) { + if (board->reg_type & (ni_reg_611x | ni_reg_6713)) { mite_prep_dma(devpriv->ao_mite_chan, 32, 32); } else { /* doing 32 instead of 16 bit wide transfers from memory @@ -1720,6 +1732,7 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; ni_release_ai_mite_channel(dev); @@ -1735,7 +1748,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) ni_clear_ai_fifo(dev); - if (boardtype.reg_type != ni_reg_6143) + if (board->reg_type != ni_reg_6143) ni_writeb(0, Misc_Command); devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */ @@ -1746,7 +1759,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register); /* generate FIFO interrupts on non-empty */ devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register); - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width | AI_SOC_Polarity | AI_LOCALMUX_CLK_Pulse_Width, @@ -1759,7 +1772,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) AI_CONVERT_Output_Select (AI_CONVERT_Output_Enable_High), AI_Output_Control_Register); - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width | AI_SOC_Polarity | AI_LOCALMUX_CLK_Pulse_Width, @@ -1784,7 +1797,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) AI_EXTMUX_CLK_Output_Select(0) | AI_LOCALMUX_CLK_Output_Select(2) | AI_SC_TC_Output_Select(3); - if (boardtype.reg_type == ni_reg_622x) + if (board->reg_type == ni_reg_622x) ai_output_control_bits |= AI_CONVERT_Output_Select (AI_CONVERT_Output_Enable_High); @@ -1832,9 +1845,10 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; int i, n; - const unsigned int mask = (1 << boardtype.adbits) - 1; + const unsigned int mask = (1 << board->adbits) - 1; unsigned signbits; unsigned short d; unsigned long dl; @@ -1844,7 +1858,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, ni_clear_ai_fifo(dev); signbits = devpriv->ai_offset[0]; - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { for (n = 0; n < num_adc_stages_611x; n++) { devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); @@ -1877,7 +1891,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, d += signbits; data[n] = d; } - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { for (n = 0; n < insn->n; n++) { devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); @@ -1913,7 +1927,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, ("ni_mio_common: timeout in ni_ai_insn_read\n"); return -ETIME; } - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { data[n] = ni_readl(M_Offset_AI_FIFO_Data) & mask; } else { @@ -1948,6 +1962,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; @@ -1957,12 +1972,12 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, devpriv->stc_writew(dev, 1, Configuration_Memory_Clear); -/* offset = 1 << (boardtype.adbits - 1); */ +/* offset = 1 << (board->adbits - 1); */ if ((list[0] & CR_ALT_SOURCE)) { unsigned bypass_bits; chan = CR_CHAN(list[0]); range = CR_RANGE(list[0]); - range_code = ni_gainlkup[boardtype.gainlkup][range]; + range_code = ni_gainlkup[board->gainlkup][range]; dither = ((list[0] & CR_ALT_FILTER) != 0); bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit; bypass_bits |= chan; @@ -1989,7 +2004,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, range = CR_RANGE(list[i]); dither = ((list[i] & CR_ALT_FILTER) != 0); - range_code = ni_gainlkup[boardtype.gainlkup][range]; + range_code = ni_gainlkup[board->gainlkup][range]; devpriv->ai_offset[i] = offset; switch (aref) { case AREF_DIFF: @@ -2009,7 +2024,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, } config_bits |= MSeries_AI_Config_Channel_Bits(chan); config_bits |= - MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan); + MSeries_AI_Config_Bank_Bits(board->reg_type, chan); config_bits |= MSeries_AI_Config_Gain_Bits(range_code); if (i == n_chan - 1) config_bits |= MSeries_AI_Config_Last_Channel_Bit; @@ -2054,6 +2069,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; @@ -2061,12 +2077,12 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned offset; unsigned int dither; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { ni_m_series_load_channelgain_list(dev, n_chan, list); return; } - if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x) - && (boardtype.reg_type != ni_reg_6143)) { + if (n_chan == 1 && (board->reg_type != ni_reg_611x) + && (board->reg_type != ni_reg_6143)) { if (devpriv->changain_state && devpriv->changain_spec == list[0]) { /* ready to go. */ @@ -2081,7 +2097,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, devpriv->stc_writew(dev, 1, Configuration_Memory_Clear); /* Set up Calibration mode if required */ - if (boardtype.reg_type == ni_reg_6143) { + if (board->reg_type == ni_reg_6143) { if ((list[0] & CR_ALT_SOURCE) && !devpriv->ai_calib_source_enabled) { /* Strobe Relay enable bit */ @@ -2105,9 +2121,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev, } } - offset = 1 << (boardtype.adbits - 1); + offset = 1 << (board->adbits - 1); for (i = 0; i < n_chan; i++) { - if ((boardtype.reg_type != ni_reg_6143) + if ((board->reg_type != ni_reg_6143) && (list[i] & CR_ALT_SOURCE)) { chan = devpriv->ai_calib_source; } else { @@ -2118,21 +2134,21 @@ static void ni_load_channelgain_list(struct comedi_device *dev, dither = ((list[i] & CR_ALT_FILTER) != 0); /* fix the external/internal range differences */ - range = ni_gainlkup[boardtype.gainlkup][range]; - if (boardtype.reg_type == ni_reg_611x) + range = ni_gainlkup[board->gainlkup][range]; + if (board->reg_type == ni_reg_611x) devpriv->ai_offset[i] = offset; else devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset; hi = 0; if ((list[i] & CR_ALT_SOURCE)) { - if (boardtype.reg_type == ni_reg_611x) + if (board->reg_type == ni_reg_611x) ni_writew(CR_CHAN(list[i]) & 0x0003, Calibration_Channel_Select_611x); } else { - if (boardtype.reg_type == ni_reg_611x) + if (board->reg_type == ni_reg_611x) aref = AREF_DIFF; - else if (boardtype.reg_type == ni_reg_6143) + else if (board->reg_type == ni_reg_6143) aref = AREF_OTHER; switch (aref) { case AREF_DIFF: @@ -2152,7 +2168,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, ni_writew(hi, Configuration_Memory_High); - if (boardtype.reg_type != ni_reg_6143) { + if (board->reg_type != ni_reg_6143) { lo = range; if (i == n_chan - 1) lo |= AI_LAST_CHANNEL; @@ -2164,8 +2180,8 @@ static void ni_load_channelgain_list(struct comedi_device *dev, } /* prime the channel/gain list */ - if ((boardtype.reg_type != ni_reg_611x) - && (boardtype.reg_type != ni_reg_6143)) { + if ((board->reg_type != ni_reg_611x) + && (board->reg_type != ni_reg_6143)) { ni_prime_channelgain_list(dev); } } @@ -2201,22 +2217,25 @@ static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer) static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev, unsigned num_channels) { - switch (boardtype.reg_type) { + const struct ni_board_struct *board = comedi_board(dev); + + switch (board->reg_type) { case ni_reg_611x: case ni_reg_6143: /* simultaneously-sampled inputs */ - return boardtype.ai_speed; + return board->ai_speed; break; default: /* multiplexed inputs */ break; } - return boardtype.ai_speed * num_channels; + return board->ai_speed * num_channels; } static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; int err = 0; int tmp; @@ -2233,8 +2252,8 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, TRIG_TIMER | TRIG_EXT); sources = TRIG_TIMER | TRIG_EXT; - if (boardtype.reg_type == ni_reg_611x || - boardtype.reg_type == ni_reg_6143) + if (board->reg_type == ni_reg_611x || + board->reg_type == ni_reg_6143) sources |= TRIG_NOW; err |= cfc_check_trigger_src(&cmd->convert_src, sources); @@ -2289,12 +2308,12 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } if (cmd->convert_src == TRIG_TIMER) { - if ((boardtype.reg_type == ni_reg_611x) - || (boardtype.reg_type == ni_reg_6143)) { + if ((board->reg_type == ni_reg_611x) + || (board->reg_type == ni_reg_6143)) { err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } else { err |= cfc_check_trigger_arg_min(&cmd->convert_arg, - boardtype.ai_speed); + board->ai_speed); err |= cfc_check_trigger_arg_max(&cmd->convert_arg, devpriv->clock_ns * 0xffff); } @@ -2315,7 +2334,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (cmd->stop_src == TRIG_COUNT) { unsigned int max_count = 0x01000000; - if (boardtype.reg_type == ni_reg_611x) + if (board->reg_type == ni_reg_611x) max_count -= num_adc_stages_611x; err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count); err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); @@ -2341,8 +2360,8 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err++; } if (cmd->convert_src == TRIG_TIMER) { - if ((boardtype.reg_type != ni_reg_611x) - && (boardtype.reg_type != ni_reg_6143)) { + if ((board->reg_type != ni_reg_611x) + && (board->reg_type != ni_reg_6143)) { tmp = cmd->convert_arg; cmd->convert_arg = ni_timer_to_ns(dev, ni_ns_to_timer(dev, @@ -2370,6 +2389,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; int timer; @@ -2426,8 +2446,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) mode2 &= ~AI_SC_Reload_Mode; devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); - if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x) - || (boardtype.reg_type == ni_reg_6143)) { + if (cmd->chanlist_len == 1 || (board->reg_type == ni_reg_611x) + || (board->reg_type == ni_reg_6143)) { start_stop_select |= AI_STOP_Polarity; start_stop_select |= AI_STOP_Select(31); /* logic low */ start_stop_select |= AI_STOP_Sync; @@ -2442,7 +2462,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_COUNT: stop_count = cmd->stop_arg - 1; - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { /* have to take 3 stage adc pipeline into account */ stop_count += num_adc_stages_611x; } @@ -2698,6 +2718,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; if (insn->n < 1) @@ -2707,7 +2728,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, case INSN_CONFIG_ANALOG_TRIG: return ni_ai_config_analog_trig(dev, s, insn, data); case INSN_CONFIG_ALT_SOURCE: - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask | MSeries_AI_Bypass_Cal_Sel_Neg_Mask | MSeries_AI_Bypass_Mode_Mux_Mask | @@ -2715,7 +2736,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, return -EINVAL; } devpriv->ai_calib_source = data[1]; - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { unsigned int calib_source; calib_source = data[1] & 0xf; @@ -2735,7 +2756,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, if (calib_source >= 8) return -EINVAL; devpriv->ai_calib_source = calib_source; - if (boardtype.reg_type == ni_reg_611x) { + if (board->reg_type == ni_reg_611x) { ni_writeb(calib_source_adjust, Cal_Gain_Select_611x); } @@ -2753,6 +2774,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int a, b, modebits; int err = 0; @@ -2761,14 +2783,14 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, * data[2] is analog line * data[3] is set level * data[4] is reset level */ - if (!boardtype.has_analog_trig) + if (!board->has_analog_trig) return -EINVAL; if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) { data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff); err++; } - if (data[2] >= boardtype.n_adchan) { - data[2] = boardtype.n_adchan - 1; + if (data[2] >= board->n_adchan) { + data[2] = board->n_adchan - 1; err++; } if (data[3] > 255) { /* a */ @@ -2852,6 +2874,7 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, unsigned int chan_index) { + const struct ni_board_struct *board = comedi_board(dev); struct comedi_async *async = s->async; unsigned int range; unsigned int i; @@ -2859,10 +2882,10 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int length = num_bytes / sizeof(short); short *array = data; - offset = 1 << (boardtype.aobits - 1); + offset = 1 << (board->aobits - 1); for (i = 0; i < length; i++) { range = CR_RANGE(async->cmd.chanlist[chan_index]); - if (boardtype.ao_unipolar == 0 || (range & 1) == 0) + if (board->ao_unipolar == 0 || (range & 1) == 0) array[i] -= offset; #ifdef PCIDMA array[i] = cpu_to_le16(array[i]); @@ -2877,6 +2900,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans, int timed) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; @@ -2885,7 +2909,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, int invert = 0; if (timed) { - for (i = 0; i < boardtype.n_aochan; ++i) { + for (i = 0; i < board->n_aochan; ++i) { devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit; ni_writeb(devpriv->ao_conf[i], M_Offset_AO_Config_Bank(i)); @@ -2949,6 +2973,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; @@ -2961,10 +2986,10 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, range = CR_RANGE(chanspec[i]); conf = AO_Channel(chan); - if (boardtype.ao_unipolar) { + if (board->ao_unipolar) { if ((range & 1) == 0) { conf |= AO_Bipolar; - invert = (1 << (boardtype.aobits - 1)); + invert = (1 << (board->aobits - 1)); } else { invert = 0; } @@ -2972,7 +2997,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, conf |= AO_Ext_Ref; } else { conf |= AO_Bipolar; - invert = (1 << (boardtype.aobits - 1)); + invert = (1 << (board->aobits - 1)); } /* not all boards can deglitch, but this shouldn't hurt */ @@ -2995,7 +3020,9 @@ static int ni_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans, int timed) { - if (boardtype.reg_type & ni_reg_m_series_mask) + const struct ni_board_struct *board = comedi_board(dev); + + if (board->reg_type & ni_reg_m_series_mask) return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans, timed); else @@ -3017,6 +3044,7 @@ static int ni_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int invert; @@ -3025,7 +3053,7 @@ static int ni_ao_insn_write(struct comedi_device *dev, devpriv->ao[chan] = data[0]; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { ni_writew(data[0], M_Offset_DAC_Direct_Data(chan)); } else ni_writew(data[0] ^ invert, @@ -3038,12 +3066,13 @@ static int ni_ao_insn_write_671x(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int invert; ao_win_out(1 << chan, AO_Immediate_671x); - invert = 1 << (boardtype.aobits - 1); + invert = 1 << (board->aobits - 1); ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0); @@ -3057,13 +3086,14 @@ static int ni_ao_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; switch (data[0]) { case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE: switch (data[1]) { case COMEDI_OUTPUT: - data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short); + data[2] = 1 + board->ao_fifo_depth * sizeof(short); if (devpriv->mite) data[2] += devpriv->mite->fifo_size; break; @@ -3085,6 +3115,7 @@ static int ni_ao_insn_config(struct comedi_device *dev, static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + const struct ni_board_struct *board __maybe_unused = comedi_board(dev); struct ni_private *devpriv = dev->private; int ret; int interrupt_b_bits; @@ -3104,7 +3135,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, interrupt_b_bits = AO_Error_Interrupt_Enable; #ifdef PCIDMA devpriv->stc_writew(dev, 1, DAC_FIFO_Clear); - if (boardtype.reg_type & ni_reg_6xxx_mask) + if (board->reg_type & ni_reg_6xxx_mask) ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); ret = ni_ao_setup_MITE_dma(dev); if (ret) @@ -3155,6 +3186,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; int bits; @@ -3170,7 +3202,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register); - if (boardtype.reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) { ao_win_out(CLEAR_WG, AO_Misc_611x); bits = 0; @@ -3233,7 +3265,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); switch (cmd->stop_src) { case TRIG_COUNT: - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { /* this is how the NI example code does it for m-series boards, verified correct with 6259 */ devpriv->stc_writel(dev, cmd->stop_arg - 1, AO_UC_Load_A_Register); @@ -3301,8 +3333,8 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned bits; devpriv->ao_mode1 &= ~AO_Multiple_Channels; bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z); - if (boardtype. - reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) { + if (board->reg_type & + (ni_reg_m_series_mask | ni_reg_6xxx_mask)) { bits |= AO_Number_Of_Channels(0); } else { bits |= @@ -3329,14 +3361,14 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width | AO_TMRDACWR_Pulse_Width; - if (boardtype.ao_fifo_depth) + if (board->ao_fifo_depth) bits |= AO_FIFO_Enable; else bits |= AO_DMA_PIO_Control; #if 0 /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281, verified with bus analyzer. */ - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) bits |= AO_Number_Of_DAC_Packages; #endif devpriv->stc_writew(dev, bits, AO_Personal_Register); @@ -3360,6 +3392,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; int err = 0; int tmp; @@ -3407,7 +3440,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (cmd->scan_begin_src == TRIG_TIMER) { err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, - boardtype.ao_speed); + board->ao_speed); err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, devpriv->clock_ns * 0xffffff); } @@ -3448,6 +3481,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; /* devpriv->ao0p=0x0000; */ @@ -3475,7 +3509,7 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); devpriv->ao_mode2 = 0; devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) devpriv->ao_mode3 = AO_Last_Gate_Disable; else devpriv->ao_mode3 = 0; @@ -3483,7 +3517,7 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ao_trigger_select = 0; devpriv->stc_writew(dev, devpriv->ao_trigger_select, AO_Trigger_Select_Register); - if (boardtype.reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) { unsigned immediate_bits = 0; unsigned i; for (i = 0; i < s->n_chan; ++i) { @@ -3784,6 +3818,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void handle_cdio_interrupt(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv __maybe_unused = dev->private; unsigned cdio_status; struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV]; @@ -3791,7 +3826,7 @@ static void handle_cdio_interrupt(struct comedi_device *dev) unsigned long flags; #endif - if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { + if ((board->reg_type & ni_reg_m_series_mask) == 0) { return; } #ifdef PCIDMA @@ -4038,6 +4073,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, static void mio_common_detach(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; @@ -4046,7 +4082,7 @@ static void mio_common_detach(struct comedi_device *dev) ni_gpct_device_destroy(devpriv->counter_dev); } } - if (dev->subdevices && boardtype.has_8255) { + if (dev->subdevices && board->has_8255) { s = &dev->subdevices[NI_8255_DIO_SUBDEV]; subdev_8255_cleanup(dev, s); } @@ -4355,14 +4391,15 @@ static int ni_alloc_private(struct comedi_device *dev) static int ni_E_init(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned j; enum ni_gpct_variant counter_variant; int ret; - if (boardtype.n_aochan > MAX_N_AO_CHAN) { - printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n"); + if (board->n_aochan > MAX_N_AO_CHAN) { + printk("bug! n_aochan > MAX_N_AO_CHAN\n"); return -EINVAL; } @@ -4374,20 +4411,20 @@ static int ni_E_init(struct comedi_device *dev) s = &dev->subdevices[NI_AI_SUBDEV]; dev->read_subdev = s; - if (boardtype.n_adchan) { + if (board->n_adchan) { s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ; - if (boardtype.reg_type != ni_reg_611x) + if (board->reg_type != ni_reg_611x) s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER; - if (boardtype.adbits > 16) + if (board->adbits > 16) s->subdev_flags |= SDF_LSAMPL; - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) s->subdev_flags |= SDF_SOFT_CALIBRATED; - s->n_chan = boardtype.n_adchan; + s->n_chan = board->n_adchan; s->len_chanlist = 512; - s->maxdata = (1 << boardtype.adbits) - 1; - s->range_table = ni_range_lkup[boardtype.gainlkup]; + s->maxdata = (1 << board->adbits) - 1; + s->range_table = ni_range_lkup[board->gainlkup]; s->insn_read = &ni_ai_insn_read; s->insn_config = &ni_ai_insn_config; s->do_cmdtest = &ni_ai_cmdtest; @@ -4405,40 +4442,40 @@ static int ni_E_init(struct comedi_device *dev) /* analog output subdevice */ s = &dev->subdevices[NI_AO_SUBDEV]; - if (boardtype.n_aochan) { + if (board->n_aochan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND; - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) s->subdev_flags |= SDF_SOFT_CALIBRATED; - s->n_chan = boardtype.n_aochan; - s->maxdata = (1 << boardtype.aobits) - 1; - s->range_table = boardtype.ao_range_table; + s->n_chan = board->n_aochan; + s->maxdata = (1 << board->aobits) - 1; + s->range_table = board->ao_range_table; s->insn_read = &ni_ao_insn_read; - if (boardtype.reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) { s->insn_write = &ni_ao_insn_write_671x; } else { s->insn_write = &ni_ao_insn_write; } s->insn_config = &ni_ao_insn_config; #ifdef PCIDMA - if (boardtype.n_aochan) { + if (board->n_aochan) { s->async_dma_dir = DMA_TO_DEVICE; #else - if (boardtype.ao_fifo_depth) { + if (board->ao_fifo_depth) { #endif dev->write_subdev = s; s->subdev_flags |= SDF_CMD_WRITE; s->do_cmd = &ni_ao_cmd; s->do_cmdtest = &ni_ao_cmdtest; - s->len_chanlist = boardtype.n_aochan; - if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) + s->len_chanlist = board->n_aochan; + if ((board->reg_type & ni_reg_m_series_mask) == 0) s->munge = ni_ao_munge; } s->cancel = &ni_ao_reset; } else { s->type = COMEDI_SUBD_UNUSED; } - if ((boardtype.reg_type & ni_reg_67xx_mask)) + if ((board->reg_type & ni_reg_67xx_mask)) init_ao_67xx(dev, s); /* digital i/o subdevice */ @@ -4449,8 +4486,8 @@ static int ni_E_init(struct comedi_device *dev) s->maxdata = 1; s->io_bits = 0; /* all bits input */ s->range_table = &range_digital; - s->n_chan = boardtype.num_p0_dio_channels; - if (boardtype.reg_type & ni_reg_m_series_mask) { + s->n_chan = board->num_p0_dio_channels; + if (board->reg_type & ni_reg_m_series_mask) { s->subdev_flags |= SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ; s->insn_bits = &ni_m_series_dio_insn_bits; @@ -4472,7 +4509,7 @@ static int ni_E_init(struct comedi_device *dev) /* 8255 device */ s = &dev->subdevices[NI_8255_DIO_SUBDEV]; - if (boardtype.has_8255) { + if (board->has_8255) { subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev); } else { s->type = COMEDI_SUBD_UNUSED; @@ -4485,14 +4522,14 @@ static int ni_E_init(struct comedi_device *dev) /* calibration subdevice -- ai and ao */ s = &dev->subdevices[NI_CALIBRATION_SUBDEV]; s->type = COMEDI_SUBD_CALIB; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { /* internal PWM analog output used for AI nonlinearity calibration */ s->subdev_flags = SDF_INTERNAL; s->insn_config = &ni_m_series_pwm_config; s->n_chan = 1; s->maxdata = 0; ni_writel(0x0, M_Offset_Cal_PWM); - } else if (boardtype.reg_type == ni_reg_6143) { + } else if (board->reg_type == ni_reg_6143) { /* internal PWM analog output used for AI nonlinearity calibration */ s->subdev_flags = SDF_INTERNAL; s->insn_config = &ni_6143_pwm_config; @@ -4510,7 +4547,7 @@ static int ni_E_init(struct comedi_device *dev) s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; s->maxdata = 0xff; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { s->n_chan = M_SERIES_EEPROM_SIZE; s->insn_read = &ni_m_series_eeprom_insn_read; } else { @@ -4522,7 +4559,7 @@ static int ni_E_init(struct comedi_device *dev) s = &dev->subdevices[NI_PFI_DIO_SUBDEV]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { unsigned i; s->n_chan = 16; ni_writew(s->state, M_Offset_PFI_DO); @@ -4534,7 +4571,7 @@ static int ni_E_init(struct comedi_device *dev) s->n_chan = 10; } s->maxdata = 1; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { s->insn_bits = &ni_pfi_insn_bits; } s->insn_config = &ni_pfi_insn_config; @@ -4542,11 +4579,11 @@ static int ni_E_init(struct comedi_device *dev) /* cs5529 calibration adc */ s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV]; - if (boardtype.reg_type & ni_reg_67xx_mask) { + if (board->reg_type & ni_reg_67xx_mask) { s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL; /* one channel for each analog output channel */ - s->n_chan = boardtype.n_aochan; + s->n_chan = board->n_aochan; s->maxdata = (1 << 16) - 1; s->range_table = &range_unknown; /* XXX */ s->insn_read = cs5529_ai_insn_read; @@ -4576,7 +4613,7 @@ static int ni_E_init(struct comedi_device *dev) s->insn_config = ni_rtsi_insn_config; ni_rtsi_init(dev); - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { counter_variant = ni_gpct_variant_m_series; } else { counter_variant = ni_gpct_variant_e_series; @@ -4594,7 +4631,7 @@ static int ni_E_init(struct comedi_device *dev) SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ /* | SDF_CMD_WRITE */ ; s->n_chan = 3; - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) s->maxdata = 0xffffffff; else s->maxdata = 0xffffff; @@ -4626,7 +4663,7 @@ static int ni_E_init(struct comedi_device *dev) /* ai configuration */ s = &dev->subdevices[NI_AI_SUBDEV]; ni_ai_reset(dev, s); - if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) { + if ((board->reg_type & ni_reg_6xxx_mask) == 0) { /* BEAM is this needed for PCI-6143 ?? */ devpriv->clock_and_fout = Slow_Internal_Time_Divide_By_2 | @@ -4663,11 +4700,11 @@ static int ni_E_init(struct comedi_device *dev) ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select); ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select); - if (boardtype.reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) { ni_writeb(0, Magic_611x); - } else if (boardtype.reg_type & ni_reg_m_series_mask) { + } else if (board->reg_type & ni_reg_m_series_mask) { int channel; - for (channel = 0; channel < boardtype.n_aochan; ++channel) { + for (channel = 0; channel < board->n_aochan; ++channel) { ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel)); ni_writeb(0x0, M_Offset_AO_Reference_Attenuation(channel)); @@ -4938,6 +4975,7 @@ static struct caldac_struct caldacs[] = { static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; int i, j; int n_dacs; @@ -4947,12 +4985,12 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) int type; int chan; - type = boardtype.caldac[0]; + type = board->caldac[0]; if (type == caldac_none) return; n_bits = caldacs[type].n_bits; for (i = 0; i < 3; i++) { - type = boardtype.caldac[i]; + type = board->caldac[i]; if (type == caldac_none) break; if (caldacs[type].n_bits != n_bits) @@ -4971,7 +5009,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list; chan = 0; for (i = 0; i < n_dacs; i++) { - type = boardtype.caldac[i]; + type = board->caldac[i]; for (j = 0; j < caldacs[type].n_chans; j++) { maxdata_list[chan] = (1 << caldacs[type].n_bits) - 1; @@ -4982,7 +5020,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) for (chan = 0; chan < s->n_chan; chan++) ni_write_caldac(dev, i, s->maxdata_list[i] / 2); } else { - type = boardtype.caldac[0]; + type = board->caldac[0]; s->maxdata = (1 << caldacs[type].n_bits) - 1; for (chan = 0; chan < s->n_chan; chan++) @@ -4992,6 +5030,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) static void ni_write_caldac(struct comedi_device *dev, int addr, int val) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int loadbit = 0, bits = 0, bit, bitstring = 0; int i; @@ -5003,7 +5042,7 @@ static void ni_write_caldac(struct comedi_device *dev, int addr, int val) devpriv->caldacs[addr] = val; for (i = 0; i < 3; i++) { - type = boardtype.caldac[i]; + type = board->caldac[i]; if (type == caldac_none) break; if (addr < caldacs[type].n_chans) { @@ -5275,7 +5314,9 @@ static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan, static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { - if (boardtype.reg_type & ni_reg_m_series_mask) + const struct ni_board_struct *board = comedi_board(dev); + + if (board->reg_type & ni_reg_m_series_mask) return ni_m_series_set_pfi_routing(dev, chan, source); else return ni_old_set_pfi_routing(dev, chan, source); @@ -5336,7 +5377,9 @@ static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan) static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan) { - if (boardtype.reg_type & ni_reg_m_series_mask) + const struct ni_board_struct *board = comedi_board(dev); + + if (board->reg_type & ni_reg_m_series_mask) return ni_m_series_get_pfi_routing(dev, chan); else return ni_old_get_pfi_routing(dev, chan); @@ -5345,10 +5388,11 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan) static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel, enum ni_pfi_filter_select filter) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv __maybe_unused = dev->private; unsigned bits; - if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { + if ((board->reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } bits = ni_readl(M_Offset_PFI_Filter); @@ -5362,9 +5406,10 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv __maybe_unused = dev->private; - if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { + if ((board->reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } if (data[0]) { @@ -5423,6 +5468,7 @@ static int ni_pfi_insn_config(struct comedi_device *dev, */ static void ni_rtsi_init(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; /* Initialises the RTSI bus signal switch to a default state */ @@ -5449,7 +5495,7 @@ static void ni_rtsi_init(struct comedi_device *dev) RTSI_Trig_Output_Bits(5, NI_RTSI_OUTPUT_G_SRC0) | RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0); - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) devpriv->rtsi_trig_b_output_reg |= RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC); devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg, @@ -5517,7 +5563,9 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns, static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev) { - if (boardtype.reg_type & ni_reg_m_series_mask) + const struct ni_board_struct *board = comedi_board(dev); + + if (board->reg_type & ni_reg_m_series_mask) return 8; else return 7; @@ -5629,6 +5677,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, static int ni_set_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; if (source == NI_MIO_INTERNAL_CLOCK) { @@ -5636,7 +5685,7 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source, devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, RTSI_Trig_Direction_Register); devpriv->clock_ns = TIMEBASE_1_NS; - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { devpriv->clock_and_fout2 &= ~(MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit); @@ -5646,7 +5695,7 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source, } devpriv->clock_source = source; } else { - if (boardtype.reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) { return ni_mseries_set_pll_master_clock(dev, source, period_ns); } else { @@ -5676,6 +5725,8 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source, static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan, unsigned source) { + const struct ni_board_struct *board = comedi_board(dev); + if (chan >= num_configurable_rtsi_channels(dev)) { if (chan == old_RTSI_clock_channel) { if (source == NI_RTSI_OUTPUT_RTSI_OSC) @@ -5702,7 +5753,7 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan, return 1; break; case NI_RTSI_OUTPUT_RTSI_OSC: - if (boardtype.reg_type & ni_reg_m_series_mask) + if (board->reg_type & ni_reg_m_series_mask) return 1; else return 0; @@ -5758,6 +5809,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); @@ -5766,9 +5818,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, if (chan < num_configurable_rtsi_channels(dev)) { devpriv->rtsi_trig_direction_reg |= RTSI_Output_Bit(chan, - (boardtype. - reg_type & ni_reg_m_series_mask) != - 0); + (board->reg_type & ni_reg_m_series_mask) != 0); } else if (chan == old_RTSI_clock_channel) { devpriv->rtsi_trig_direction_reg |= Drive_RTSI_Clock_Bit; @@ -5780,9 +5830,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, if (chan < num_configurable_rtsi_channels(dev)) { devpriv->rtsi_trig_direction_reg &= ~RTSI_Output_Bit(chan, - (boardtype. - reg_type & ni_reg_m_series_mask) - != 0); + (board->reg_type & ni_reg_m_series_mask) != 0); } else if (chan == old_RTSI_clock_channel) { devpriv->rtsi_trig_direction_reg &= ~Drive_RTSI_Clock_Bit; @@ -5795,10 +5843,9 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, data[1] = (devpriv->rtsi_trig_direction_reg & RTSI_Output_Bit(chan, - (boardtype.reg_type & - ni_reg_m_series_mask) - != 0)) ? INSN_CONFIG_DIO_OUTPUT : - INSN_CONFIG_DIO_INPUT; + (board->reg_type & ni_reg_m_series_mask) != 0)) + ? INSN_CONFIG_DIO_OUTPUT + : INSN_CONFIG_DIO_INPUT; } else if (chan == old_RTSI_clock_channel) { data[1] = (devpriv->rtsi_trig_direction_reg & diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 175770a8b95c..4bcf8eaa55c9 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1571,6 +1571,7 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev) static void init_6143(struct comedi_device *dev) { + const struct ni_board_struct *board = comedi_board(dev); struct ni_private *devpriv = dev->private; /* Disable interrupts */ @@ -1581,7 +1582,8 @@ static void init_6143(struct comedi_device *dev) ni_writeb(0x80, PipelineDelay_6143); /* Set EOCMode, ADCMode and pipelinedelay */ ni_writeb(0x00, EOC_Set_6143); /* Set EOC Delay */ - ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143); /* Set the FIFO half full level */ + /* Set the FIFO half full level */ + ni_writel(board->ai_fifo_depth / 2, AIFIFO_Flag_6143); /* Strobe Relay disable bit */ devpriv->ai_calib_source_enabled = 0; diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index 504ea7155334..368d46831c13 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -1423,8 +1423,6 @@ struct ni_board_struct { #define n_ni_boards (sizeof(ni_boards)/sizeof(struct ni_board_struct)) -#define boardtype (*(struct ni_board_struct *)dev->board_ptr) - #define MAX_N_AO_CHAN 8 #define NUM_GPCT 2 -- cgit From f5a1d92bf6f4fa063d5ea43613f43494896e333f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:21:03 -0700 Subject: staging: comedi: ni_stc.h: remove n_ni_boards macro This macro is not used, remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_stc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index 368d46831c13..0a613c077608 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -1421,8 +1421,6 @@ struct ni_board_struct { enum caldac_enum caldac[3]; }; -#define n_ni_boards (sizeof(ni_boards)/sizeof(struct ni_board_struct)) - #define MAX_N_AO_CHAN 8 #define NUM_GPCT 2 -- cgit From 68278f100a88390baf07602f3900d98a6b5c6167 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:21:24 -0700 Subject: staging: comedi: ni_pcimio: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 1663 +++++++++++++--------------- 1 file changed, 762 insertions(+), 901 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 4bcf8eaa55c9..c8e0127783c7 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -225,971 +225,832 @@ enum ni_pcimio_boardid { static const struct ni_board_struct ni_boards[] = { [BOARD_PCIMIO_16XE_50] = { - .name = "pci-mio-16xe-50", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 2048, - .alwaysdither = 1, - .gainlkup = ai_gain_8, - .ai_speed = 50000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 50000, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043}, - .has_8255 = 0, - }, + .name = "pci-mio-16xe-50", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 2048, + .alwaysdither = 1, + .gainlkup = ai_gain_8, + .ai_speed = 50000, + .n_aochan = 2, + .aobits = 12, + .ao_range_table = &range_bipolar10, + .ao_speed = 50000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043 }, + }, [BOARD_PCIMIO_16XE_10] = { - .name = "pci-mio-16xe-10", /* aka pci-6030E */ - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 10000, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - .has_8255 = 0, - }, + .name = "pci-mio-16xe-10", /* aka pci-6030E */ + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCI6014] = { - .name = "pci-6014", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pci-6014", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 16, + .ao_range_table = &range_bipolar10, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PXI6030E] = { - .name = "pxi-6030e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 10000, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - .has_8255 = 0, - }, + .name = "pxi-6030e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCIMIO_16E_1] = { - .name = "pci-mio-16e-1", /* aka pci-6070e */ - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_16, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {mb88341}, - .has_8255 = 0, - }, + .name = "pci-mio-16e-1", /* aka pci-6070e */ + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_16, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { mb88341 }, + }, [BOARD_PCIMIO_16E_4] = { - .name = "pci-mio-16e-4", /* aka pci-6040e */ - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_16, - /* .Note = there have been reported problems with full speed - * on this board */ - .ai_speed = 2000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 512, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, /* doc says mb88341 */ - .has_8255 = 0, - }, + .name = "pci-mio-16e-4", /* aka pci-6040e */ + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_16, + /* + * there have been reported problems with + * full speed on this board + */ + .ai_speed = 2000, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 512, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, /* doc says mb88341 */ + }, [BOARD_PXI6040E] = { - .name = "pxi-6040e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_16, - .ai_speed = 2000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 512, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {mb88341}, - .has_8255 = 0, - }, + .name = "pxi-6040e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_16, + .ai_speed = 2000, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 512, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { mb88341 }, + }, [BOARD_PCI6031E] = { - .name = "pci-6031e", - .n_adchan = 64, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 10000, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - .has_8255 = 0, - }, + .name = "pci-6031e", + .n_adchan = 64, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCI6032E] = { - .name = "pci-6032e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - .has_8255 = 0, - }, + .name = "pci-6032e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCI6033E] = { - .name = "pci-6033e", - .n_adchan = 64, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - .has_8255 = 0, - }, + .name = "pci-6033e", + .n_adchan = 64, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCI6071E] = { - .name = "pci-6071e", - .n_adchan = 64, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_16, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pci-6071e", + .n_adchan = 64, + .adbits = 12, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_16, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PCI6023E] = { - .name = "pci-6023e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 0, - .aobits = 0, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, /* manual is wrong */ - .has_8255 = 0, - }, + .name = "pci-6023e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, /* manual is wrong */ + }, [BOARD_PCI6024E] = { - .name = "pci-6024e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, /* manual is wrong */ - .has_8255 = 0, - }, + .name = "pci-6024e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 12, + .ao_range_table = &range_bipolar10, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, /* manual is wrong */ + }, [BOARD_PCI6025E] = { - .name = "pci-6025e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, /* manual is wrong */ - .has_8255 = 1, - }, + .name = "pci-6025e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 12, + .ao_range_table = &range_bipolar10, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, /* manual is wrong */ + .has_8255 = 1, + }, [BOARD_PXI6025E] = { - .name = "pxi-6025e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 0, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 0, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, /* manual is wrong */ - .has_8255 = 1, - }, + .name = "pxi-6025e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 12, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, /* manual is wrong */ + .has_8255 = 1, + }, [BOARD_PCI6034E] = { - .name = "pci-6034e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pci-6034e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PCI6035E] = { - .name = "pci-6035e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pci-6035e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 12, + .ao_range_table = &range_bipolar10, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PCI6052E] = { - .name = "pci-6052e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_16, - .ai_speed = 3000, - .n_aochan = 2, - .aobits = 16, - .ao_unipolar = 1, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_speed = 3000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug, ad8804_debug, ad8522}, /* manual is wrong */ - }, + .name = "pci-6052e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_16, + .ai_speed = 3000, + .n_aochan = 2, + .aobits = 16, + .ao_unipolar = 1, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_speed = 3000, + .num_p0_dio_channels = 8, + /* manual is wrong */ + .caldac = { ad8804_debug, ad8804_debug, ad8522 }, + }, [BOARD_PCI6110] = { - .name = "pci-6110", - .n_adchan = 4, - .adbits = 12, - .ai_fifo_depth = 8192, - .alwaysdither = 0, - .gainlkup = ai_gain_611x, - .ai_speed = 200, - .n_aochan = 2, - .aobits = 16, - .reg_type = ni_reg_611x, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_fifo_depth = 2048, - .ao_speed = 250, - .num_p0_dio_channels = 8, - .caldac = {ad8804, ad8804}, - }, + .name = "pci-6110", + .n_adchan = 4, + .adbits = 12, + .ai_fifo_depth = 8192, + .alwaysdither = 0, + .gainlkup = ai_gain_611x, + .ai_speed = 200, + .n_aochan = 2, + .aobits = 16, + .reg_type = ni_reg_611x, + .ao_range_table = &range_bipolar10, + .ao_fifo_depth = 2048, + .ao_speed = 250, + .num_p0_dio_channels = 8, + .caldac = { ad8804, ad8804 }, + }, [BOARD_PCI6111] = { - .name = "pci-6111", - .n_adchan = 2, - .adbits = 12, - .ai_fifo_depth = 8192, - .alwaysdither = 0, - .gainlkup = ai_gain_611x, - .ai_speed = 200, - .n_aochan = 2, - .aobits = 16, - .reg_type = ni_reg_611x, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_fifo_depth = 2048, - .ao_speed = 250, - .num_p0_dio_channels = 8, - .caldac = {ad8804, ad8804}, - }, + .name = "pci-6111", + .n_adchan = 2, + .adbits = 12, + .ai_fifo_depth = 8192, + .gainlkup = ai_gain_611x, + .ai_speed = 200, + .n_aochan = 2, + .aobits = 16, + .reg_type = ni_reg_611x, + .ao_range_table = &range_bipolar10, + .ao_fifo_depth = 2048, + .ao_speed = 250, + .num_p0_dio_channels = 8, + .caldac = { ad8804, ad8804 }, + }, #if 0 /* The 6115 boards probably need their own driver */ [BOARD_PCI6115] = { /* .device_id = 0x2ed0, */ - .name = "pci-6115", - .n_adchan = 4, - .adbits = 12, - .ai_fifo_depth = 8192, - .alwaysdither = 0, - .gainlkup = ai_gain_611x, - .ai_speed = 100, - .n_aochan = 2, - .aobits = 16, - .ao_671x = 1, - .ao_unipolar = 0, - .ao_fifo_depth = 2048, - .ao_speed = 250, - .num_p0_dio_channels = 8, - .reg_611x = 1, - .caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */ - }, + .name = "pci-6115", + .n_adchan = 4, + .adbits = 12, + .ai_fifo_depth = 8192, + .gainlkup = ai_gain_611x, + .ai_speed = 100, + .n_aochan = 2, + .aobits = 16, + .ao_671x = 1, + .ao_fifo_depth = 2048, + .ao_speed = 250, + .num_p0_dio_channels = 8, + .reg_611x = 1, + /* XXX */ + .caldac = { ad8804_debug, ad8804_debug, ad8804_debug }, + }, #endif #if 0 [BOARD_PXI6115] = { /* .device_id = ????, */ - .name = "pxi-6115", - .n_adchan = 4, - .adbits = 12, - .ai_fifo_depth = 8192, - .alwaysdither = 0, - .gainlkup = ai_gain_611x, - .ai_speed = 100, - .n_aochan = 2, - .aobits = 16, - .ao_671x = 1, - .ao_unipolar = 0, - .ao_fifo_depth = 2048, - .ao_speed = 250, - .reg_611x = 1, - .num_p0_dio_channels = 8, - caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */ - }, + .name = "pxi-6115", + .n_adchan = 4, + .adbits = 12, + .ai_fifo_depth = 8192, + .gainlkup = ai_gain_611x, + .ai_speed = 100, + .n_aochan = 2, + .aobits = 16, + .ao_671x = 1, + .ao_fifo_depth = 2048, + .ao_speed = 250, + .reg_611x = 1, + .num_p0_dio_channels = 8, + /* XXX */ + .caldac = { ad8804_debug, ad8804_debug, ad8804_debug }, + }, #endif [BOARD_PCI6711] = { - .name = "pci-6711", - .n_adchan = 0, /* no analog input */ - .n_aochan = 4, - .aobits = 12, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - /* data sheet says 8192, but fifo really holds 16384 samples */ - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6711, - .caldac = {ad8804_debug}, - }, + .name = "pci-6711", + .n_aochan = 4, + .aobits = 12, + /* data sheet says 8192, but fifo really holds 16384 samples */ + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6711, + .caldac = { ad8804_debug }, + }, [BOARD_PXI6711] = { - .name = "pxi-6711", - .n_adchan = 0, /* no analog input */ - .n_aochan = 4, - .aobits = 12, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6711, - .caldac = {ad8804_debug}, - }, + .name = "pxi-6711", + .n_aochan = 4, + .aobits = 12, + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6711, + .caldac = { ad8804_debug }, + }, [BOARD_PCI6713] = { - .name = "pci-6713", - .n_adchan = 0, /* no analog input */ - .n_aochan = 8, - .aobits = 12, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6713, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pci-6713", + .n_aochan = 8, + .aobits = 12, + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6713, + .caldac = { ad8804_debug, ad8804_debug }, + }, [BOARD_PXI6713] = { - .name = "pxi-6713", - .n_adchan = 0, /* no analog input */ - .n_aochan = 8, - .aobits = 12, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6713, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pxi-6713", + .n_aochan = 8, + .aobits = 12, + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6713, + .caldac = { ad8804_debug, ad8804_debug }, + }, [BOARD_PCI6731] = { - .name = "pci-6731", - .n_adchan = 0, /* no analog input */ - .n_aochan = 4, - .aobits = 16, - .ao_unipolar = 0, - .ao_fifo_depth = 8192, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6711, - .caldac = {ad8804_debug}, - }, + .name = "pci-6731", + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8192, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6711, + .caldac = { ad8804_debug }, + }, #if 0 [BOARD_PXI6731] = { /* .device_id = ????, */ - .name = "pxi-6731", - .n_adchan = 0, /* no analog input */ - .n_aochan = 4, - .aobits = 16, - .ao_unipolar = 0, - .ao_fifo_depth = 8192, - .ao_range_table = &range_bipolar10, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6711, - .caldac = {ad8804_debug}, - }, + .name = "pxi-6731", + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8192, + .ao_range_table = &range_bipolar10, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6711, + .caldac = { ad8804_debug }, + }, #endif [BOARD_PCI6733] = { - .name = "pci-6733", - .n_adchan = 0, /* no analog input */ - .n_aochan = 8, - .aobits = 16, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6713, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pci-6733", + .n_aochan = 8, + .aobits = 16, + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6713, + .caldac = { ad8804_debug, ad8804_debug }, + }, [BOARD_PXI6733] = { - .name = "pxi-6733", - .n_adchan = 0, /* no analog input */ - .n_aochan = 8, - .aobits = 16, - .ao_unipolar = 0, - .ao_fifo_depth = 16384, - .ao_range_table = &range_bipolar10, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_6713, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pxi-6733", + .n_aochan = 8, + .aobits = 16, + .ao_fifo_depth = 16384, + .ao_range_table = &range_bipolar10, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_6713, + .caldac = { ad8804_debug, ad8804_debug }, + }, [BOARD_PXI6071E] = { - .name = "pxi-6071e", - .n_adchan = 64, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_16, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pxi-6071e", + .n_adchan = 64, + .adbits = 12, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_16, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PXI6070E] = { - .name = "pxi-6070e", - .n_adchan = 16, - .adbits = 12, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_16, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 12, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 1000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pxi-6070e", + .n_adchan = 16, + .adbits = 12, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_16, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 12, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 1000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PXI6052E] = { - .name = "pxi-6052e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_16, - .ai_speed = 3000, - .n_aochan = 2, - .aobits = 16, - .ao_unipolar = 1, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_speed = 3000, - .num_p0_dio_channels = 8, - .caldac = {mb88341, mb88341, ad8522}, - }, + .name = "pxi-6052e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_16, + .ai_speed = 3000, + .n_aochan = 2, + .aobits = 16, + .ao_unipolar = 1, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_speed = 3000, + .num_p0_dio_channels = 8, + .caldac = { mb88341, mb88341, ad8522 }, + }, [BOARD_PXI6031E] = { - .name = "pxi-6031e", - .n_adchan = 64, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_14, - .ai_speed = 10000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 2048, - .ao_range_table = &range_ni_E_ao_ext, - .ao_unipolar = 1, - .ao_speed = 10000, - .num_p0_dio_channels = 8, - .caldac = {dac8800, dac8043, ad8522}, - }, + .name = "pxi-6031e", + .n_adchan = 64, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_14, + .ai_speed = 10000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 2048, + .ao_range_table = &range_ni_E_ao_ext, + .ao_unipolar = 1, + .ao_speed = 10000, + .num_p0_dio_channels = 8, + .caldac = { dac8800, dac8043, ad8522 }, + }, [BOARD_PCI6036E] = { - .name = "pci-6036e", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - .alwaysdither = 1, - .gainlkup = ai_gain_4, - .ai_speed = 5000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 0, - .ao_range_table = &range_bipolar10, - .ao_unipolar = 0, - .ao_speed = 100000, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug}, - .has_8255 = 0, - }, + .name = "pci-6036e", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, + .alwaysdither = 1, + .gainlkup = ai_gain_4, + .ai_speed = 5000, + .n_aochan = 2, + .aobits = 16, + .ao_range_table = &range_bipolar10, + .ao_speed = 100000, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug }, + }, [BOARD_PCI6220] = { - .name = "pci-6220", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 512, - /* .FIXME = guess */ - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .num_p0_dio_channels = 8, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6220", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 512, /* FIXME: guess */ + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .num_p0_dio_channels = 8, + .reg_type = ni_reg_622x, + .caldac = { caldac_none }, + }, [BOARD_PCI6221] = { - .name = "pci-6221", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_622x_ao, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .ao_speed = 1200, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6221", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_622x_ao, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6221_37PIN] = { - .name = "pci-6221_37pin", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_622x_ao, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .ao_speed = 1200, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6221_37pin", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_622x_ao, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6224] = { - .name = "pci-6224", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6224", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .reg_type = ni_reg_622x, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PXI6224] = { - .name = "pxi-6224", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pxi-6224", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .reg_type = ni_reg_622x, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6225] = { - .name = "pci-6225", - .n_adchan = 80, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_622x_ao, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .ao_speed = 1200, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6225", + .n_adchan = 80, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_622x_ao, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PXI6225] = { - .name = "pxi-6225", - .n_adchan = 80, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_622x_ao, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .ao_speed = 1200, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, + .name = "pxi-6225", + .n_adchan = 80, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_622x_ao, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, }, [BOARD_PCI6229] = { - .name = "pci-6229", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_622x, - .ai_speed = 4000, - .n_aochan = 4, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_622x_ao, - .reg_type = ni_reg_622x, - .ao_unipolar = 0, - .ao_speed = 1200, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6229", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_622x, + .ai_speed = 4000, + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_622x_ao, + .reg_type = ni_reg_622x, + .ao_speed = 1200, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6250] = { - .name = "pci-6250", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6250", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .reg_type = ni_reg_625x, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6251] = { - .name = "pci-6251", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_625x_ao, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .ao_speed = 350, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6251", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCIE6251] = { - .name = "pcie-6251", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_625x_ao, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .ao_speed = 350, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pcie-6251", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PXIE6251] = { - .name = "pxie-6251", - .n_adchan = 16, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_625x_ao, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .ao_speed = 350, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pxie-6251", + .n_adchan = 16, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6254] = { - .name = "pci-6254", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6254", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .reg_type = ni_reg_625x, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6259] = { - .name = "pci-6259", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 4, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_625x_ao, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .ao_speed = 350, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6259", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCIE6259] = { - .name = "pcie-6259", - .n_adchan = 32, - .adbits = 16, - .ai_fifo_depth = 4095, - .gainlkup = ai_gain_628x, - .ai_speed = 800, - .n_aochan = 4, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_625x_ao, - .reg_type = ni_reg_625x, - .ao_unipolar = 0, - .ao_speed = 350, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pcie-6259", + .n_adchan = 32, + .adbits = 16, + .ai_fifo_depth = 4095, + .gainlkup = ai_gain_628x, + .ai_speed = 800, + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_625x_ao, + .reg_type = ni_reg_625x, + .ao_speed = 350, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6280] = { - .name = "pci-6280", - .n_adchan = 16, - .adbits = 18, - .ai_fifo_depth = 2047, - .gainlkup = ai_gain_628x, - .ai_speed = 1600, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 8191, - .reg_type = ni_reg_628x, - .ao_unipolar = 0, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6280", + .n_adchan = 16, + .adbits = 18, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .ao_fifo_depth = 8191, + .reg_type = ni_reg_628x, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6281] = { - .name = "pci-6281", - .n_adchan = 16, - .adbits = 18, - .ai_fifo_depth = 2047, - .gainlkup = ai_gain_628x, - .ai_speed = 1600, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_628x_ao, - .reg_type = ni_reg_628x, - .ao_unipolar = 1, - .ao_speed = 350, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6281", + .n_adchan = 16, + .adbits = 18, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_628x_ao, + .reg_type = ni_reg_628x, + .ao_unipolar = 1, + .ao_speed = 350, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PXI6281] = { - .name = "pxi-6281", - .n_adchan = 16, - .adbits = 18, - .ai_fifo_depth = 2047, - .gainlkup = ai_gain_628x, - .ai_speed = 1600, - .n_aochan = 2, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_628x_ao, - .reg_type = ni_reg_628x, - .ao_unipolar = 1, - .ao_speed = 350, - .num_p0_dio_channels = 8, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pxi-6281", + .n_adchan = 16, + .adbits = 18, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .n_aochan = 2, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_628x_ao, + .reg_type = ni_reg_628x, + .ao_unipolar = 1, + .ao_speed = 350, + .num_p0_dio_channels = 8, + .caldac = { caldac_none }, + }, [BOARD_PCI6284] = { - .name = "pci-6284", - .n_adchan = 32, - .adbits = 18, - .ai_fifo_depth = 2047, - .gainlkup = ai_gain_628x, - .ai_speed = 1600, - .n_aochan = 0, - .aobits = 0, - .ao_fifo_depth = 0, - .reg_type = ni_reg_628x, - .ao_unipolar = 0, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6284", + .n_adchan = 32, + .adbits = 18, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .reg_type = ni_reg_628x, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6289] = { - .name = "pci-6289", - .n_adchan = 32, - .adbits = 18, - .ai_fifo_depth = 2047, - .gainlkup = ai_gain_628x, - .ai_speed = 1600, - .n_aochan = 4, - .aobits = 16, - .ao_fifo_depth = 8191, - .ao_range_table = &range_ni_M_628x_ao, - .reg_type = ni_reg_628x, - .ao_unipolar = 1, - .ao_speed = 350, - .num_p0_dio_channels = 32, - .caldac = {caldac_none}, - .has_8255 = 0, - }, + .name = "pci-6289", + .n_adchan = 32, + .adbits = 18, + .ai_fifo_depth = 2047, + .gainlkup = ai_gain_628x, + .ai_speed = 1600, + .n_aochan = 4, + .aobits = 16, + .ao_fifo_depth = 8191, + .ao_range_table = &range_ni_M_628x_ao, + .reg_type = ni_reg_628x, + .ao_unipolar = 1, + .ao_speed = 350, + .num_p0_dio_channels = 32, + .caldac = { caldac_none }, + }, [BOARD_PCI6143] = { - .name = "pci-6143", - .n_adchan = 8, - .adbits = 16, - .ai_fifo_depth = 1024, - .alwaysdither = 0, - .gainlkup = ai_gain_6143, - .ai_speed = 4000, - .n_aochan = 0, - .aobits = 0, - .reg_type = ni_reg_6143, - .ao_unipolar = 0, - .ao_fifo_depth = 0, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pci-6143", + .n_adchan = 8, + .adbits = 16, + .ai_fifo_depth = 1024, + .gainlkup = ai_gain_6143, + .ai_speed = 4000, + .reg_type = ni_reg_6143, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug, ad8804_debug }, + }, [BOARD_PXI6143] = { - .name = "pxi-6143", - .n_adchan = 8, - .adbits = 16, - .ai_fifo_depth = 1024, - .alwaysdither = 0, - .gainlkup = ai_gain_6143, - .ai_speed = 4000, - .n_aochan = 0, - .aobits = 0, - .reg_type = ni_reg_6143, - .ao_unipolar = 0, - .ao_fifo_depth = 0, - .num_p0_dio_channels = 8, - .caldac = {ad8804_debug, ad8804_debug}, - }, + .name = "pxi-6143", + .n_adchan = 8, + .adbits = 16, + .ai_fifo_depth = 1024, + .gainlkup = ai_gain_6143, + .ai_speed = 4000, + .reg_type = ni_reg_6143, + .num_p0_dio_channels = 8, + .caldac = { ad8804_debug, ad8804_debug }, + }, }; struct ni_private { -- cgit From b3322d422e65bcfd0a70444c9a0f240aaa8d0b07 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:21:47 -0700 Subject: staging: comedi: rtd520: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'device_id' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 38 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 8b72edf3cad1..5ee38b149b51 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -249,24 +249,27 @@ static const struct comedi_lrange rtd_ao_range = { } }; +enum rtd_boardid { + BOARD_DM7520, + BOARD_PCI4520, +}; + struct rtdBoard { const char *name; - int device_id; int range10Start; /* start of +-10V range */ int rangeUniStart; /* start of +10V range */ const struct comedi_lrange *ai_range; }; static const struct rtdBoard rtd520Boards[] = { - { + [BOARD_DM7520] = { .name = "DM7520", - .device_id = 0x7520, .range10Start = 6, .rangeUniStart = 12, .ai_range = &rtd_ai_7520_range, - }, { + }, + [BOARD_PCI4520] = { .name = "PCI4520", - .device_id = 0x4520, .range10Start = 8, .rangeUniStart = 16, .ai_range = &rtd_ai_4520_range, @@ -1259,30 +1262,17 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, } } -static const void *rtd_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct rtdBoard *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) { - thisboard = &rtd520Boards[i]; - if (pcidev->device == thisboard->device_id) - return thisboard; - } - return NULL; -} - static int rtd_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct rtdBoard *thisboard; + const struct rtdBoard *thisboard = NULL; struct rtdPrivate *devpriv; struct comedi_subdevice *s; int ret; - thisboard = rtd_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(rtd520Boards)) + thisboard = &rtd520Boards[context]; if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; @@ -1422,8 +1412,8 @@ static int rtd520_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) }, - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) }, + { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 }, + { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 }, { 0 } }; MODULE_DEVICE_TABLE(pci, rtd520_pci_table); -- cgit From 151df466b681181bc1b0543df79620d4e805e531 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:22:06 -0700 Subject: staging: comedi: skel: cleanup pci_driver declaration For aesthetic reasons, add some whitespace to the pci_driver declaration. Also, move the pci device table near the pci_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 8cedc4cf020c..53bbe9e5f98b 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -689,11 +689,22 @@ static struct comedi_driver skel_driver = { #ifdef CONFIG_COMEDI_PCI_DRIVERS -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded - * upstream. */ -#define PCI_VENDOR_ID_SKEL 0xdafe +static int skel_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &skel_driver, id->driver_data); +} + +/* + * Please add your PCI vendor ID to comedidev.h, and it will + * be forwarded upstream. + */ +#define PCI_VENDOR_ID_SKEL 0xdafe + +/* + * This is used by modprobe to translate PCI IDs to drivers. + * Should only be used for PCI and ISA-PnP devices + */ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, @@ -701,16 +712,10 @@ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { }; MODULE_DEVICE_TABLE(pci, skel_pci_table); -static int skel_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return comedi_pci_auto_config(dev, &skel_driver, id->driver_data); -} - static struct pci_driver skel_pci_driver = { - .name = "dummy", - .id_table = skel_pci_table, - .probe = &skel_pci_probe, + .name = "dummy", + .id_table = skel_pci_table, + .probe = skel_pci_probe, .remove = comedi_pci_auto_unconfig, }; module_comedi_pci_driver(skel_driver, skel_pci_driver); -- cgit From 2fdecdbedbe08957155e68946b1eb87848364d8d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:22:31 -0700 Subject: staging: comedi: skel: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. This allows removing the 'devid' data from the boardinfo as well the search function that was used to locate the boardinfo for the PCI device. Cleanup some of the comments to describe the usage of the 'context' in the (*auto_attach). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 59 ++++++++++++++--------------------- 1 file changed, 24 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 53bbe9e5f98b..9d914b21e5c0 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -90,25 +90,27 @@ Configuration Options: * boards in this way is optional, and completely driver-dependent. * Some drivers use arrays such as this, other do not. */ +enum skel_boardid { + BOARD_SKEL100, + BOARD_SKEL200, +}; + struct skel_board { const char *name; - unsigned int devid; int ai_chans; int ai_bits; int have_dio; }; static const struct skel_board skel_boards[] = { - { + [BOARD_SKEL100] = { .name = "skel-100", - .devid = 0x100, .ai_chans = 16, .ai_bits = 12, .have_dio = 1, }, - { + [BOARD_SKEL200] = { .name = "skel-200", - .devid = 0x200, .ai_chans = 8, .ai_bits = 16, .have_dio = 0, @@ -394,22 +396,6 @@ static int skel_dio_insn_config(struct comedi_device *dev, return insn->n; } -static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev) -{ - unsigned int i; - -/* - * This example code assumes all the entries in skel_boards[] are PCI boards - * and all use the same PCI vendor ID. If skel_boards[] contains a mixture - * of PCI and non-PCI boards, this loop should skip over the non-PCI boards. - */ - for (i = 0; i < ARRAY_SIZE(skel_boards); i++) - if (/* skel_boards[i].bustype == pci_bustype && */ - pcidev->device == skel_boards[i].devid) - return &skel_boards[i]; - return NULL; -} - /* * Handle common part of skel_attach() and skel_auto_attach(). */ @@ -541,16 +527,13 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) * comedi_usb_auto_config(), etc.) to handle devices that can be attached * to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl. * - * The context parameter is usually unused, but if the driver called - * comedi_auto_config() directly instead of the comedi_pci_auto_config() - * wrapper function, this will be a copy of the context passed to - * comedi_auto_config(). + * The context parameter is driver dependent. */ static int skel_auto_attach(struct comedi_device *dev, - unsigned long context) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct skel_board *thisboard; + const struct skel_board *thisboard = NULL; struct skel_private *devpriv; int ret; @@ -558,12 +541,18 @@ static int skel_auto_attach(struct comedi_device *dev, if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) return -EINVAL; - /* Find a matching board in skel_boards[]. */ - thisboard = skel_find_pci_board(pcidev); - if (!thisboard) { - dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); - return -EINVAL; - } + /* + * In this example, the _auto_attach is for a PCI device. + * + * The 'context' passed to this function is the id->driver_data + * associated with the PCI device found in the id_table during + * the modprobe. This 'context' is the index of the entry in + * skel_boards[i] that contains the boardinfo for the PCI device. + */ + if (context < ARRAY_SIZE(skel_boards)) + thisboard = &skel_boards[context]; + if (!thisboard) + return -ENODEV; /* * Point the struct comedi_device to the matching board info @@ -706,8 +695,8 @@ static int skel_pci_probe(struct pci_dev *dev, * Should only be used for PCI and ISA-PnP devices */ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, + { PCI_VDEVICE(SKEL, 0x0100), BOARD_SKEL100 }, + { PCI_VDEVICE(SKEL, 0x0200), BOARD_SKEL200 }, { 0 } }; MODULE_DEVICE_TABLE(pci, skel_pci_table); -- cgit From 3dd98ebe532beb8d6a7ed22e16b8791e455f4e13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:22:48 -0700 Subject: staging: comedi: skel: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 9d914b21e5c0..1737c2a06ae3 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -104,17 +104,16 @@ struct skel_board { static const struct skel_board skel_boards[] = { [BOARD_SKEL100] = { - .name = "skel-100", - .ai_chans = 16, - .ai_bits = 12, - .have_dio = 1, - }, + .name = "skel-100", + .ai_chans = 16, + .ai_bits = 12, + .have_dio = 1, + }, [BOARD_SKEL200] = { - .name = "skel-200", - .ai_chans = 8, - .ai_bits = 16, - .have_dio = 0, - }, + .name = "skel-200", + .ai_chans = 8, + .ai_bits = 16, + }, }; /* this structure is for data unique to this hardware driver. If -- cgit From 1f388811b54f9f1b78d52237edda1eaea109e900 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:23:10 -0700 Subject: staging: comedi: addi_common: allow driver to set the board_ptr The addi_apci_035, addi_apci_1500, addi_apci_1564, and addi_apci_3xxx drivers still use the addi_common code. Allow those drivers to set the dev->board_ptr before calling addi_auto_attach(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 1051fa5ce8f7..e9a4b43fda71 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -105,16 +105,19 @@ static int addi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board; + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv; struct comedi_subdevice *s; int ret, n_subdevices; unsigned int dw_Dummy; - this_board = addi_find_boardinfo(dev, pcidev); - if (!this_board) - return -ENODEV; - dev->board_ptr = this_board; + if (!this_board) { + /* The driver did not set the board_ptr, try finding it. */ + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + } dev->board_name = this_board->pc_DriverName; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); -- cgit From fb0cdeefc8f67ef069bb59b52af6a6188e55b963 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:23:30 -0700 Subject: staging: comedi: addi_apci_035: set board_ptr before calling addi_auto_attach() This driver only supports a single PCI device. If we set the dev->board_ptr before calling addi_auto_attach() we remove the need for the common code to search for the boardinfo. Since the search is not done we can remove the unnecessary board information from the comedi_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_035.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index ea6ddb3d06a3..f296cb387b7c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -39,14 +39,19 @@ static const struct addi_board apci035_boardtypes[] = { }, }; +static int apci035_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + dev->board_ptr = &apci035_boardtypes[0]; + + return addi_auto_attach(dev, context); +} + static struct comedi_driver apci035_driver = { .driver_name = "addi_apci_035", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, + .auto_attach = apci035_auto_attach, .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci035_boardtypes), - .board_name = &apci035_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int apci035_pci_probe(struct pci_dev *dev, -- cgit From a80cb91aa63412385e8e8088d33cf364308b25e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:24:00 -0700 Subject: staging: comedi: addi_apci_1500: set board_ptr before calling addi_auto_attach() This driver only supports a single PCI device. If we set the dev->board_ptr before calling addi_auto_attach() we remove the need for the common code to search for the boardinfo. Since the search is not done we can remove the unnecessary board information from the comedi_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1500.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index c945a2aef9e3..24c859088bc1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -39,14 +39,19 @@ static const struct addi_board apci1500_boardtypes[] = { }, }; +static int apci1500_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + dev->board_ptr = &apci1500_boardtypes[0]; + + return addi_auto_attach(dev, context); +} + static struct comedi_driver apci1500_driver = { .driver_name = "addi_apci_1500", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, + .auto_attach = apci1500_auto_attach, .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci1500_boardtypes), - .board_name = &apci1500_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int apci1500_pci_probe(struct pci_dev *dev, -- cgit From 43ba213156dba3afb4c8367da16c3d90aa87d2f8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:24:21 -0700 Subject: staging: comedi: addi_apci_1564: set board_ptr before calling addi_auto_attach() This driver only supports a single PCI device. If we set the dev->board_ptr before calling addi_auto_attach() we remove the need for the common code to search for the boardinfo. Since the search is not done we can remove the unnecessary board information from the comedi_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1564.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index b2b3bdbb9f30..97e389f4e5c6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -36,14 +36,19 @@ static const struct addi_board apci1564_boardtypes[] = { }, }; +static int apci1564_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + dev->board_ptr = &apci1564_boardtypes[0]; + + return addi_auto_attach(dev, context); +} + static struct comedi_driver apci1564_driver = { .driver_name = "addi_apci_1564", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, + .auto_attach = apci1564_auto_attach, .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci1564_boardtypes), - .board_name = &apci1564_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int apci1564_pci_probe(struct pci_dev *dev, -- cgit From f7c929b7fb3afde17997b997d17fa7846777c69d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:24:43 -0700 Subject: staging: comedi: addi_apci_3200: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. Set the dev->board_ptr before calling addi_auto_attach(). This removes the need for the common code to search for the boardinfo. Since the search is not done we can remove the unnecessary board information from the comedi_driver. For aesthetic reasons, move the pci device table near the pci_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3200.c | 41 +++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index a28bcbdffe07..e23831bcec4d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -22,8 +22,13 @@ static void fpu_end(void) #include "addi-data/hwdrv_apci3200.c" #include "addi-data/addi_common.c" +enum apci3200_boardid { + BOARD_APCI3200, + BOARD_APCI3300, +}; + static const struct addi_board apci3200_boardtypes[] = { - { + [BOARD_APCI3200] = { .pc_DriverName = "apci3200", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3000, @@ -53,7 +58,8 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cancel = i_APCI3200_StopCyclicAcquisition, .di_bits = apci3200_di_insn_bits, .do_bits = apci3200_do_insn_bits, - }, { + }, + [BOARD_APCI3300] = { .pc_DriverName = "apci3300", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3007, @@ -85,21 +91,25 @@ static const struct addi_board apci3200_boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci3200_pci_table); +static int apci3200_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + const struct addi_board *board = NULL; + + if (context < ARRAY_SIZE(apci3200_boardtypes)) + board = &apci3200_boardtypes[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + + return addi_auto_attach(dev, context); +} static struct comedi_driver apci3200_driver = { .driver_name = "addi_apci_3200", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, + .auto_attach = apci3200_auto_attach, .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci3200_boardtypes), - .board_name = &apci3200_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int apci3200_pci_probe(struct pci_dev *dev, @@ -108,6 +118,13 @@ static int apci3200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); } +static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { + { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 }, + { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, apci3200_pci_table); + static struct pci_driver apci3200_pci_driver = { .name = "addi_apci_3200", .id_table = apci3200_pci_table, -- cgit From dbae4575661da840353f12dd76499ad587c92519 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:25:04 -0700 Subject: staging: comedi: addi_apci_3xxx: use the pci id_table 'driver_data' Create an enum to the boardinfo and pass that enum in the pci_driver id_table as the driver_data. Change the macro used to fill in the device table from PCI_DEVICE() to PCI_VDEVICE(). This allows passing the enum as the next field. Set the dev->board_ptr before calling addi_auto_attach(). This removes the need for the common code to search for the boardinfo. Since the search is not done we can remove the unnecessary board information from the comedi_driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 171 ++++++++++++++++-------- 1 file changed, 117 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 96ec65b2678e..5069fbdb27c3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -10,8 +10,36 @@ #include "addi-data/hwdrv_apci3xxx.c" #include "addi-data/addi_common.c" +enum apci3xxx_boardid { + BOARD_APCI3000_16, + BOARD_APCI3000_8, + BOARD_APCI3000_4, + BOARD_APCI3006_16, + BOARD_APCI3006_8, + BOARD_APCI3006_4, + BOARD_APCI3010_16, + BOARD_APCI3010_8, + BOARD_APCI3010_4, + BOARD_APCI3016_16, + BOARD_APCI3016_8, + BOARD_APCI3016_4, + BOARD_APCI3100_16_4, + BOARD_APCI3100_8_4, + BOARD_APCI3106_16_4, + BOARD_APCI3106_8_4, + BOARD_APCI3110_16_4, + BOARD_APCI3110_8_4, + BOARD_APCI3116_16_4, + BOARD_APCI3116_8_4, + BOARD_APCI3003, + BOARD_APCI3002_16, + BOARD_APCI3002_8, + BOARD_APCI3002_4, + BOARD_APCI3500, +}; + static const struct addi_board apci3xxx_boardtypes[] = { - { + [BOARD_APCI3000_16] = { .pc_DriverName = "apci3000-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3010, @@ -37,7 +65,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3000_8] = { .pc_DriverName = "apci3000-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x300F, @@ -63,7 +92,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3000_4] = { .pc_DriverName = "apci3000-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x300E, @@ -89,7 +119,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3006_16] = { .pc_DriverName = "apci3006-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3013, @@ -115,7 +146,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3006_8] = { .pc_DriverName = "apci3006-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3014, @@ -141,7 +173,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3006_4] = { .pc_DriverName = "apci3006-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3015, @@ -167,7 +200,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3010_16] = { .pc_DriverName = "apci3010-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3016, @@ -198,7 +232,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3010_8] = { .pc_DriverName = "apci3010-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3017, @@ -229,7 +264,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3010_4] = { .pc_DriverName = "apci3010-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3018, @@ -260,7 +296,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3016_16] = { .pc_DriverName = "apci3016-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3019, @@ -291,7 +328,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3016_8] = { .pc_DriverName = "apci3016-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301A, @@ -322,7 +360,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3016_4] = { .pc_DriverName = "apci3016-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301B, @@ -353,7 +392,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3100_16_4] = { .pc_DriverName = "apci3100-16-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301C, @@ -383,7 +423,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3100_8_4] = { .pc_DriverName = "apci3100-8-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301D, @@ -413,7 +454,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3106_16_4] = { .pc_DriverName = "apci3106-16-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301E, @@ -443,7 +485,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3106_8_4] = { .pc_DriverName = "apci3106-8-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x301F, @@ -473,7 +516,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3110_16_4] = { .pc_DriverName = "apci3110-16-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3020, @@ -508,7 +552,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3110_8_4] = { .pc_DriverName = "apci3110-8-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3021, @@ -543,7 +588,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3116_16_4] = { .pc_DriverName = "apci3116-16-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3022, @@ -578,7 +624,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3116_8_4] = { .pc_DriverName = "apci3116-8-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3023, @@ -613,7 +660,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { + }, + [BOARD_APCI3003] = { .pc_DriverName = "apci3003", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x300B, @@ -638,7 +686,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, .do_bits = apci3xxx_do_insn_bits, - }, { + }, + [BOARD_APCI3002_16] = { .pc_DriverName = "apci3002-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3002, @@ -663,7 +712,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, .do_bits = apci3xxx_do_insn_bits, - }, { + }, + [BOARD_APCI3002_8] = { .pc_DriverName = "apci3002-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3003, @@ -688,7 +738,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, .do_bits = apci3xxx_do_insn_bits, - }, { + }, + [BOARD_APCI3002_4] = { .pc_DriverName = "apci3002-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3004, @@ -713,7 +764,8 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, .do_bits = apci3xxx_do_insn_bits, - }, { + }, + [BOARD_APCI3500] = { .pc_DriverName = "apci3500", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3024, @@ -737,14 +789,25 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, }; +static int apci3xxx_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + const struct addi_board *board = NULL; + + if (context < ARRAY_SIZE(apci3xxx_boardtypes)) + board = &apci3xxx_boardtypes[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + + return addi_auto_attach(dev, context); +} + static struct comedi_driver apci3xxx_driver = { .driver_name = "addi_apci_3xxx", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, + .auto_attach = apci3xxx_auto_attach, .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci3xxx_boardtypes), - .board_name = &apci3xxx_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int apci3xxx_pci_probe(struct pci_dev *dev, @@ -754,31 +817,31 @@ static int apci3xxx_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301a) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301b) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301c) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301d) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301e) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301f) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) }, + { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 }, + { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 }, + { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 }, + { PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 }, + { PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 }, + { PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 }, + { PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 }, + { PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 }, + { PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 }, + { PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 }, + { PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 }, + { PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 }, + { PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 }, + { PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 }, + { PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 }, + { PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 }, + { PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 }, + { PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table); -- cgit From bfcded4656c09a60c836c6be566ae501adf15a50 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:25:32 -0700 Subject: staging: comedi: addi_common: remove addi_find_boardinfo() All the users of the addi_common code now set the dev->board_ptr before calling addi_auto_attach(). Remove the unnecessary function that searches for the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 24 ---------------------- 1 file changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index e9a4b43fda71..3140880948e1 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -84,23 +84,6 @@ static int i_ADDI_Reset(struct comedi_device *dev) return 0; } -static const void *addi_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const void *p = dev->driver->board_name; - const struct addi_board *this_board; - int i; - - for (i = 0; i < dev->driver->num_names; i++) { - this_board = p; - if (this_board->i_VendorId == pcidev->vendor && - this_board->i_DeviceId == pcidev->device) - return this_board; - p += dev->driver->offset; - } - return NULL; -} - static int addi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { @@ -111,13 +94,6 @@ static int addi_auto_attach(struct comedi_device *dev, int ret, n_subdevices; unsigned int dw_Dummy; - if (!this_board) { - /* The driver did not set the board_ptr, try finding it. */ - this_board = addi_find_boardinfo(dev, pcidev); - if (!this_board) - return -ENODEV; - dev->board_ptr = this_board; - } dev->board_name = this_board->pc_DriverName; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); -- cgit From cf55a71e43685b39ea6a2cf568a54d05b12b97d5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:26:02 -0700 Subject: staging: comedi: addi_apci_1710: remove 'interrupt' from boardinfo Only one board type is supported by this driver. Remove the 'interrupt' field from the boardinfo and just call the function directly in v_ADDI_Interrupt(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index f32a79a2afca..068b0169f4c7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -26,16 +26,12 @@ static const struct addi_board apci1710_boardtypes[] = { .pc_DriverName = "apci1710", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = APCI1710_BOARD_DEVICE_ID, - .interrupt = v_APCI1710_Interrupt, }, }; static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { - struct comedi_device *dev = d; - const struct addi_board *this_board = comedi_board(dev); - - this_board->interrupt(irq, d); + v_APCI1710_Interrupt(irq, d); return IRQ_RETVAL(1); } -- cgit From 2667079167fcb7300fe7c215b6ca07b1bceb8717 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:26:23 -0700 Subject: staging: comedi: addi_apci_1710: remove boardinfo This driver only uses the boardinfo to get the dev->board_name. Just use the dev->driver->driver_name and remove the unnecessary boardinfo completely. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 30 +------------------------ 1 file changed, 1 insertion(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 068b0169f4c7..f654eb03473a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -21,49 +21,21 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" -static const struct addi_board apci1710_boardtypes[] = { - { - .pc_DriverName = "apci1710", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = APCI1710_BOARD_DEVICE_ID, - }, -}; - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { v_APCI1710_Interrupt(irq, d); return IRQ_RETVAL(1); } -static const void *apci1710_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct addi_board *this_board; - int i; - - for (i = 0; i < ARRAY_SIZE(apci1710_boardtypes); i++) { - this_board = &apci1710_boardtypes[i]; - if (this_board->i_VendorId == pcidev->vendor && - this_board->i_DeviceId == pcidev->device) - return this_board; - } - return NULL; -} - static int apci1710_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; int ret; - this_board = apci1710_find_boardinfo(dev, pcidev); - if (!this_board) - return -ENODEV; - dev->board_ptr = this_board; - dev->board_name = this_board->pc_DriverName; + dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) -- cgit From b9beb6c7e76a2ab4153b4c6eb675fe3c481300cf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:26:44 -0700 Subject: staging: comedi: addi_common: remove 'i_VendorId' and 'i_Device Id' The vendor/device ids in the boardinfo are not longer needed. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.h | 2 - drivers/staging/comedi/drivers/addi_apci_035.c | 2 - drivers/staging/comedi/drivers/addi_apci_1500.c | 2 - drivers/staging/comedi/drivers/addi_apci_1564.c | 2 - drivers/staging/comedi/drivers/addi_apci_3200.c | 4 -- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 50 ---------------------- 6 files changed, 62 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 6d8b29f945d5..19da977fef82 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -45,8 +45,6 @@ /* structure for the boardtype */ struct addi_board { const char *pc_DriverName; /* driver name */ - int i_VendorId; /* PCI vendor a device ID of card */ - int i_DeviceId; int i_IorangeBase0; int i_IorangeBase1; int i_IorangeBase2; /* base 2 range */ diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index f296cb387b7c..2f4e2948a9f2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -15,8 +15,6 @@ static const struct addi_board apci035_boardtypes[] = { { .pc_DriverName = "apci035", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x0300, .i_IorangeBase0 = 127, .i_IorangeBase1 = APCI035_ADDRESS_RANGE, .i_PCIEeprom = 1, diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 24c859088bc1..1170e7688f39 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -13,8 +13,6 @@ static const struct addi_board apci1500_boardtypes[] = { { .pc_DriverName = "apci1500", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x80fc, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, .i_IorangeBase2 = 4, diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 97e389f4e5c6..8de7b4875b0d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -13,8 +13,6 @@ static const struct addi_board apci1564_boardtypes[] = { { .pc_DriverName = "apci1564", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1006, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, .i_PCIEeprom = ADDIDATA_EEPROM, diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index e23831bcec4d..4b492a0897b8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -30,8 +30,6 @@ enum apci3200_boardid { static const struct addi_board apci3200_boardtypes[] = { [BOARD_APCI3200] = { .pc_DriverName = "apci3200", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3000, .i_IorangeBase0 = 128, .i_IorangeBase1 = 256, .i_IorangeBase2 = 4, @@ -61,8 +59,6 @@ static const struct addi_board apci3200_boardtypes[] = { }, [BOARD_APCI3300] = { .pc_DriverName = "apci3300", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3007, .i_IorangeBase0 = 128, .i_IorangeBase1 = 256, .i_IorangeBase2 = 4, diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 5069fbdb27c3..1afc62cb07c5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -41,8 +41,6 @@ enum apci3xxx_boardid { static const struct addi_board apci3xxx_boardtypes[] = { [BOARD_APCI3000_16] = { .pc_DriverName = "apci3000-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3010, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -68,8 +66,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3000_8] = { .pc_DriverName = "apci3000-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300F, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -95,8 +91,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3000_4] = { .pc_DriverName = "apci3000-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300E, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -122,8 +116,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3006_16] = { .pc_DriverName = "apci3006-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3013, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -149,8 +141,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3006_8] = { .pc_DriverName = "apci3006-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3014, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -176,8 +166,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3006_4] = { .pc_DriverName = "apci3006-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3015, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -203,8 +191,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3010_16] = { .pc_DriverName = "apci3010-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3016, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -235,8 +221,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3010_8] = { .pc_DriverName = "apci3010-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3017, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -267,8 +251,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3010_4] = { .pc_DriverName = "apci3010-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3018, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -299,8 +281,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3016_16] = { .pc_DriverName = "apci3016-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3019, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -331,8 +311,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3016_8] = { .pc_DriverName = "apci3016-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301A, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -363,8 +341,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3016_4] = { .pc_DriverName = "apci3016-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301B, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -395,8 +371,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3100_16_4] = { .pc_DriverName = "apci3100-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301C, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -426,8 +400,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3100_8_4] = { .pc_DriverName = "apci3100-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301D, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -457,8 +429,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3106_16_4] = { .pc_DriverName = "apci3106-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301E, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -488,8 +458,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3106_8_4] = { .pc_DriverName = "apci3106-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301F, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -519,8 +487,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3110_16_4] = { .pc_DriverName = "apci3110-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3020, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -555,8 +521,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3110_8_4] = { .pc_DriverName = "apci3110-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3021, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -591,8 +555,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3116_16_4] = { .pc_DriverName = "apci3116-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3022, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -627,8 +589,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3116_8_4] = { .pc_DriverName = "apci3116-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3023, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -663,8 +623,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3003] = { .pc_DriverName = "apci3003", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300B, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -689,8 +647,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3002_16] = { .pc_DriverName = "apci3002-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3002, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -715,8 +671,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3002_8] = { .pc_DriverName = "apci3002-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3003, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -741,8 +695,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3002_4] = { .pc_DriverName = "apci3002-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3004, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, @@ -767,8 +719,6 @@ static const struct addi_board apci3xxx_boardtypes[] = { }, [BOARD_APCI3500] = { .pc_DriverName = "apci3500", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3024, .i_IorangeBase0 = 256, .i_IorangeBase1 = 256, .i_IorangeBase2 = 256, -- cgit From 42169e2d8a536c4d6a24298078e0b06add77f502 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Mar 2013 10:27:07 -0700 Subject: staging: comedi: das08: remove 'id' from boardinfo With the bus specific code split out, the device id in the boardinfo is no longer needed. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.h | 1 - drivers/staging/comedi/drivers/das08_cs.c | 1 - drivers/staging/comedi/drivers/das08_pci.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index b102ad4918c4..89bb8d6fdfc6 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -32,7 +32,6 @@ enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl, struct das08_board_struct { const char *name; - unsigned int id; /* id for pci/pcmcia boards */ bool is_jr; /* true for 'JR' boards */ unsigned int ai_nbits; enum das08_lrange ai_pg; diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index cfeebe4d1ddd..d9f3e92317d3 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -59,7 +59,6 @@ Command support does not exist, but could be added for this board. static const struct das08_board_struct das08_cs_boards[] = { { .name = "pcm-das08", - .id = 0x0, /* XXX */ .ai_nbits = 12, .ai_pg = das08_bipolar5, .ai_encoding = das08_pcm_encode12, diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index ecab0c4f70f2..a56cee7f86dd 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -46,7 +46,6 @@ static const struct das08_board_struct das08_pci_boards[] = { { .name = "pci-das08", - .id = PCI_DEVICE_ID_PCIDAS08, .ai_nbits = 12, .ai_pg = das08_bipolar5, .ai_encoding = das08_encode12, -- cgit From fff7a2cc99726f3994b9709782bd3e251ceb1023 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 15:57:24 -0700 Subject: staging: comedi: adl_pci8164: remove buggy dev_dbg() The dev_dbg() messages in the adl_pci8164_insn_{read,out} functions output the 'data' that was read/write to the device. Two 'data' values are always printed, data[0] and data[1]. The 'data' pointer points to an array of unsigned int values. The number of values in the array is indicated by insn->n. The number of data elements is never checked so the dev_dbg() could be trying to access a 'data' element that is invalid. Instead of fixing the dev_dbg() just remove them. They are really just added noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 4126f733d34d..86d4fb6af142 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -64,36 +64,27 @@ static void adl_pci8164_insn_read(struct comedi_device *dev, char *action, unsigned short offset) { int axis, axis_reg; - char axisname; axis = CR_CHAN(insn->chanspec); switch (axis) { case 0: axis_reg = PCI8164_AXIS_X; - axisname = 'X'; break; case 1: axis_reg = PCI8164_AXIS_Y; - axisname = 'Y'; break; case 2: axis_reg = PCI8164_AXIS_Z; - axisname = 'Z'; break; case 3: axis_reg = PCI8164_AXIS_U; - axisname = 'U'; break; default: axis_reg = PCI8164_AXIS_X; - axisname = 'X'; } data[0] = inw(dev->iobase + axis_reg + offset); - dev_dbg(dev->class_dev, - "pci8164 %s read -> %04X:%04X on axis %c\n", - action, data[0], data[1], axisname); } static int adl_pci8164_insn_read_msts(struct comedi_device *dev, @@ -144,38 +135,26 @@ static void adl_pci8164_insn_out(struct comedi_device *dev, { unsigned int axis, axis_reg; - char axisname; - axis = CR_CHAN(insn->chanspec); switch (axis) { case 0: axis_reg = PCI8164_AXIS_X; - axisname = 'X'; break; case 1: axis_reg = PCI8164_AXIS_Y; - axisname = 'Y'; break; case 2: axis_reg = PCI8164_AXIS_Z; - axisname = 'Z'; break; case 3: axis_reg = PCI8164_AXIS_U; - axisname = 'U'; break; default: axis_reg = PCI8164_AXIS_X; - axisname = 'X'; } outw(data[0], dev->iobase + axis_reg + offset); - - dev_dbg(dev->class_dev, - "pci8164 %s write -> %04X:%04X on axis %c\n", - action, data[0], data[1], axisname); - } static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, -- cgit From d99fc2c3723e50c020bc1ca20107ecbf74d02e1f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 15:57:51 -0700 Subject: staging: comedi: adl_pci8164: simplify axis register determination The low-level i/o functions in this driver simply read/write a register based on the channel in insn->chanspec and an offset. Create a macro, PCI8164_AXIS(), that takes the channel number as a parameter and returns the register value. Remove the switch() statements used to figure out the 'axis_reg' and use the new macro instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 51 +++------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 86d4fb6af142..57e21cf5edee 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -38,10 +38,7 @@ Configuration Options: not applicable, uses PCI auto config #include "comedi_fc.h" #include "8253.h" -#define PCI8164_AXIS_X 0x00 -#define PCI8164_AXIS_Y 0x08 -#define PCI8164_AXIS_Z 0x10 -#define PCI8164_AXIS_U 0x18 +#define PCI8164_AXIS(x) ((x) * 0x08) #define PCI8164_MSTS 0x00 #define PCI8164_SSTS 0x02 @@ -63,28 +60,9 @@ static void adl_pci8164_insn_read(struct comedi_device *dev, unsigned int *data, char *action, unsigned short offset) { - int axis, axis_reg; - - axis = CR_CHAN(insn->chanspec); - - switch (axis) { - case 0: - axis_reg = PCI8164_AXIS_X; - break; - case 1: - axis_reg = PCI8164_AXIS_Y; - break; - case 2: - axis_reg = PCI8164_AXIS_Z; - break; - case 3: - axis_reg = PCI8164_AXIS_U; - break; - default: - axis_reg = PCI8164_AXIS_X; - } + unsigned int chan = CR_CHAN(insn->chanspec); - data[0] = inw(dev->iobase + axis_reg + offset); + data[0] = inw(dev->iobase + PCI8164_AXIS(chan) + offset); } static int adl_pci8164_insn_read_msts(struct comedi_device *dev, @@ -133,28 +111,9 @@ static void adl_pci8164_insn_out(struct comedi_device *dev, unsigned int *data, char *action, unsigned short offset) { - unsigned int axis, axis_reg; - - axis = CR_CHAN(insn->chanspec); - - switch (axis) { - case 0: - axis_reg = PCI8164_AXIS_X; - break; - case 1: - axis_reg = PCI8164_AXIS_Y; - break; - case 2: - axis_reg = PCI8164_AXIS_Z; - break; - case 3: - axis_reg = PCI8164_AXIS_U; - break; - default: - axis_reg = PCI8164_AXIS_X; - } + unsigned int chan = CR_CHAN(insn->chanspec); - outw(data[0], dev->iobase + axis_reg + offset); + outw(data[0], dev->iobase + PCI8164_AXIS(chan) + offset); } static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, -- cgit From a6c57d2ed7ac6224ef70cc5d8adaf9ab8996736c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 15:58:28 -0700 Subject: staging: comedi: adl_pci8164: simplify (*insn_{read,write}) The (*insn_read) and (*insn_write) functions for all the subdevices in this driver are the same except for the 'offset' that is added to the iobase and channel to read/write a register on the board. Pass the 'offset' in s->private so we can use the same (*insn_read) and (*insn->write) functions for all the subdevices. Also, fix the (*insn_read) and (*insn_write) functions so they work correctly. The comedi core expects them to read/write insn->n data values and then return the number of values used. For aesthetic reasons, add some whitespace to the subdevice init. Remove the dev_info() noise at the end of the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 194 +++++++++------------------ 1 file changed, 60 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 57e21cf5edee..f5570582e35a 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -39,117 +39,41 @@ Configuration Options: not applicable, uses PCI auto config #include "8253.h" #define PCI8164_AXIS(x) ((x) * 0x08) - -#define PCI8164_MSTS 0x00 -#define PCI8164_SSTS 0x02 -#define PCI8164_BUF0 0x04 -#define PCI8164_BUF1 0x06 - -#define PCI8164_CMD 0x00 -#define PCI8164_OTP 0x02 +#define PCI8164_CMD_MSTS_REG 0x00 +#define PCI8164_OTP_SSTS_REG 0x02 +#define PCI8164_BUF0_REG 0x04 +#define PCI8164_BUF1_REG 0x06 #define PCI_DEVICE_ID_PCI8164 0x8164 -/* - all the read commands are the same except for the addition a constant - * const to the data for inw() - */ -static void adl_pci8164_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data, - char *action, unsigned short offset) -{ - unsigned int chan = CR_CHAN(insn->chanspec); - - data[0] = inw(dev->iobase + PCI8164_AXIS(chan) + offset); -} - -static int adl_pci8164_insn_read_msts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_read(dev, s, insn, data, "MSTS", PCI8164_MSTS); - return 2; -} - -static int adl_pci8164_insn_read_ssts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_read(dev, s, insn, data, "SSTS", PCI8164_SSTS); - return 2; -} - -static int adl_pci8164_insn_read_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_read(dev, s, insn, data, "BUF0", PCI8164_BUF0); - return 2; -} - -static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_read(dev, s, insn, data, "BUF1", PCI8164_BUF1); - return 2; -} - -/* - all the write commands are the same except for the addition a constant - * const to the data for outw() - */ -static void adl_pci8164_insn_out(struct comedi_device *dev, +static int adl_pci8164_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data, - char *action, unsigned short offset) + unsigned int *data) { + unsigned long offset = (unsigned long)s->private; unsigned int chan = CR_CHAN(insn->chanspec); + int i; - outw(data[0], dev->iobase + PCI8164_AXIS(chan) + offset); -} + for (i = 0; i < insn->n; i++) + data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset); -static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_out(dev, s, insn, data, "CMD", PCI8164_CMD); - return 2; + return insn->n; } -static int adl_pci8164_insn_write_otp(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int adl_pci8164_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - adl_pci8164_insn_out(dev, s, insn, data, "OTP", PCI8164_OTP); - return 2; -} + unsigned long offset = (unsigned long)s->private; + unsigned int chan = CR_CHAN(insn->chanspec); + int i; -static int adl_pci8164_insn_write_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_out(dev, s, insn, data, "BUF0", PCI8164_BUF0); - return 2; -} + for (i = 0; i < insn->n; i++) + outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset); -static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - adl_pci8164_insn_out(dev, s, insn, data, "BUF1", PCI8164_BUF1); - return 2; + return insn->n; } static int adl_pci8164_auto_attach(struct comedi_device *dev, @@ -170,47 +94,49 @@ static int adl_pci8164_auto_attach(struct comedi_device *dev, if (ret) return ret; + /* read MSTS register / write CMD register for each axis (channel) */ s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_msts; - s->insn_write = adl_pci8164_insn_write_cmd; - + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + s->insn_read = adl_pci8164_insn_read; + s->insn_write = adl_pci8164_insn_write; + s->private = (void *)PCI8164_CMD_MSTS_REG; + + /* read SSTS register / write OTP register for each axis (channel) */ s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_ssts; - s->insn_write = adl_pci8164_insn_write_otp; - + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + s->insn_read = adl_pci8164_insn_read; + s->insn_write = adl_pci8164_insn_write; + s->private = (void *)PCI8164_OTP_SSTS_REG; + + /* read/write BUF0 register for each axis (channel) */ s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf0; - s->insn_write = adl_pci8164_insn_write_buf0; - + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + s->insn_read = adl_pci8164_insn_read; + s->insn_write = adl_pci8164_insn_write; + s->private = (void *)PCI8164_BUF0_REG; + + /* read/write BUF1 register for each axis (channel) */ s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf1; - s->insn_write = adl_pci8164_insn_write_buf1; - - dev_info(dev->class_dev, "%s attached\n", dev->board_name); + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + s->insn_read = adl_pci8164_insn_read; + s->insn_write = adl_pci8164_insn_write; + s->private = (void *)PCI8164_BUF1_REG; return 0; } -- cgit From 83dcad479d8b71c9046abfd38d83fcaa55e14f5c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 15:59:20 -0700 Subject: staging: comedi: adl_pci8164: remove PCI_DEVICE_ID_* define The PCI device id is only used in the device table. Remove the define and just open code the device id. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index f5570582e35a..e9ff701d5d91 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -44,8 +44,6 @@ Configuration Options: not applicable, uses PCI auto config #define PCI8164_BUF0_REG 0x04 #define PCI8164_BUF1_REG 0x06 -#define PCI_DEVICE_ID_PCI8164 0x8164 - static int adl_pci8164_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -166,8 +164,8 @@ static int adl_pci8164_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) }, - {0} + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) }, + { 0 } }; MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); -- cgit From d2607ad1d3777d052217a7c6e54e58da02ae21f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 16:00:14 -0700 Subject: staging: comedi: adl_pci8164: remove unnecessary includes Remove all the unnecessary includes. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index e9ff701d5d91..dce44e378a89 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -32,11 +32,8 @@ Configuration Options: not applicable, uses PCI auto config #include #include -#include #include "../comedidev.h" -#include "comedi_fc.h" -#include "8253.h" #define PCI8164_AXIS(x) ((x) * 0x08) #define PCI8164_CMD_MSTS_REG 0x00 -- cgit From 92d7323b8ff2057a86072fbccca57833b845fc28 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 16:00:38 -0700 Subject: staging: comedi: adl_pci8164: cleanup multi-line comments Format the multi-line comments in the kernel CodingStyle. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index dce44e378a89..de5cac052888 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -1,34 +1,34 @@ /* - comedi/drivers/adl_pci8164.c + * comedi/drivers/adl_pci8164.c + * + * Hardware comedi driver for PCI-8164 Adlink card + * Copyright (C) 2004 Michel Lachine + * + * 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. + */ - Hardware comedi driver fot PCI-8164 Adlink card - Copyright (C) 2004 Michel Lachine - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ /* -Driver: adl_pci8164 -Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board -Devices: [ADLink] PCI-8164 (adl_pci8164) -Author: Michel Lachaine -Status: experimental -Updated: Mon, 14 Apr 2008 15:10:32 +0100 - -Configuration Options: not applicable, uses PCI auto config -*/ + * Driver: adl_pci8164 + * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board + * Devices: (ADLink) PCI-8164 [adl_pci8164] + * Author: Michel Lachaine + * Status: experimental + * Updated: Mon, 14 Apr 2008 15:10:32 +0100 + * + * Configuration Options: not applicable, uses PCI auto config + */ #include #include -- cgit From 20ce161d2f53af092fe8dabfef6fb0d7af846c43 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 7 Mar 2013 23:48:40 +0900 Subject: staging: comedi: Fix typo in comedi Correct spelling typos in staging/comedi Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/pcl816.c | 2 +- drivers/staging/comedi/drivers/usbdux.c | 2 +- drivers/staging/comedi/drivers/usbduxsigma.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index 1e05732e9f3d..97e7eec343d7 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -704,9 +704,9 @@ static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, | unsigned char *_ pb_ChannelStatus) | +----------------------------------------------------------------------------+ | Task : - (0) Set the digital output from selected SSI moule | + (0) Set the digital output from selected SSI module | | (b_ModuleNbr) ON - (1) Set the digital output from selected SSI moule | + (1) Set the digital output from selected SSI module | | (b_ModuleNbr) OFF (2)Read the status from selected SSI digital input | | (b_InputChannel) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index e4e78c99af02..8683e2564618 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -312,7 +312,7 @@ struct pci1710_private { unsigned int ai_et_CntrlReg; unsigned int ai_et_MuxVal; unsigned int ai_et_div1, ai_et_div2; - unsigned int act_chanlist[32]; /* list of scaned channel */ + unsigned int act_chanlist[32]; /* list of scanned channel */ unsigned char act_chanlist_len; /* len of scanlist */ unsigned char act_chanlist_pos; /* actual position in MUX list */ unsigned char da_ranges; /* copy of D/A outpit range register */ @@ -339,7 +339,7 @@ static const unsigned int muxonechan[] = { /* ============================================================================== - Check if channel list from user is builded correctly + Check if channel list from user is built correctly If it's ok, then program scan/gain logic. This works for all cards. */ diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index fe58c9c6fb33..e61cf71d46ef 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1529,7 +1529,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) struct pcidas64_private *devpriv = dev->private; int i; - /* alocate pci dma buffers */ + /* allocate pci dma buffers */ for (i = 0; i < ai_dma_ring_count(thisboard); i++) { devpriv->ai_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 8722defde22f..9a466879e493 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -120,7 +120,7 @@ struct icp_multi_private { unsigned int DacCmdStatus; /* DAC Command/Status register */ unsigned int IntEnable; /* Interrupt Enable register */ unsigned int IntStatus; /* Interrupt Status register */ - unsigned int act_chanlist[32]; /* list of scaned channel */ + unsigned int act_chanlist[32]; /* list of scanned channel */ unsigned char act_chanlist_len; /* len of scanlist */ unsigned char act_chanlist_pos; /* actual position in MUX list */ unsigned int *ai_chanlist; /* actaul chanlist */ diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 3637828727c8..55d66d0295e0 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -428,7 +428,7 @@ static int me2600_xilinx_download(struct comedi_device *dev, /* * Loop for writing firmware byte by byte to xilinx - * Firmware data start at offfset 16 + * Firmware data start at offset 16 */ for (i = 0; i < file_length; i++) writeb((data[16 + i] & 0xff), diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index f625fdab335c..ebd9e4706050 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -837,7 +837,7 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, /* ============================================================================== - Check if channel list from user is builded correctly + Check if channel list from user is built correctly If it's ok, then return non-zero length of repeated segment of channel list */ static int diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1a0062a04456..6f2e42972289 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -56,7 +56,7 @@ sampling rate. If you sample two channels you get 4kHz and so on. * functions firmware upload is by fxload and no longer by comedi (due to * enumeration) * 0.97: USB IDs received, adjusted table - * 0.98: SMP, locking, memroy alloc: moved all usb memory alloc + * 0.98: SMP, locking, memory alloc: moved all usb memory alloc * to the usb subsystem and moved all comedi related memory * alloc to comedi. * | kernel | registration | usbdux-usb | usbdux-comedi | comedi | diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index d066351a71b2..cfbfeeb40ffe 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1369,7 +1369,7 @@ static int usbdux_getstatusinfo(struct comedi_device *dev, int chan) /* 32 bits big endian from the A/D converter */ one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1))); - /* mask out the staus byte */ + /* mask out the status byte */ one = one & 0x00ffffff; one = one ^ 0x00800000; -- cgit From 70c1e91f5b43327eca9941205c529ba43ddc7923 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 22:22:42 +0800 Subject: staging: comedi: remove duplicated include from ni_pcimio.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index c8e0127783c7..4d1a431edee0 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -110,7 +110,6 @@ Bugs: */ -#include #include #include "../comedidev.h" -- cgit From 59691367be00806a3ab1c6a125ced6ed87e91356 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 21:45:34 +0800 Subject: staging: sync: fix return value check in sync_fence_alloc() In case of error, the function anon_inode_getfile() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index b9bb974faacd..bf66c199a833 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -261,7 +261,7 @@ static struct sync_fence *sync_fence_alloc(const char *name) fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, fence, 0); - if (fence->file == NULL) + if (IS_ERR(fence->file)) goto err; kref_init(&fence->kref); -- cgit From 6f98b1a250cb6055ab5dde41a181b2c9cf026bc9 Mon Sep 17 00:00:00 2001 From: Ganesan Ramalingam Date: Wed, 6 Mar 2013 19:42:22 +0530 Subject: Staging: Netlogic XLR/XLS GMAC driver Add support for the Network Accelerator Engine on Netlogic XLR/XLS MIPS SoCs. The XLR/XLS NAE blocks can be configured as one 10G interface or four 1G interfaces. This driver supports blocks with 1G ports. Signed-off-by: Ganesan Ramalingam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/netlogic/Kconfig | 7 + drivers/staging/netlogic/Makefile | 1 + drivers/staging/netlogic/TODO | 12 + drivers/staging/netlogic/platform_net.c | 223 ++++++ drivers/staging/netlogic/platform_net.h | 46 ++ drivers/staging/netlogic/xlr_net.c | 1116 +++++++++++++++++++++++++++++++ drivers/staging/netlogic/xlr_net.h | 1099 ++++++++++++++++++++++++++++++ 9 files changed, 2507 insertions(+) create mode 100644 drivers/staging/netlogic/Kconfig create mode 100644 drivers/staging/netlogic/Makefile create mode 100644 drivers/staging/netlogic/TODO create mode 100644 drivers/staging/netlogic/platform_net.c create mode 100644 drivers/staging/netlogic/platform_net.h create mode 100644 drivers/staging/netlogic/xlr_net.c create mode 100644 drivers/staging/netlogic/xlr_net.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 093f10c88cce..daeeec17ac9b 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -140,4 +140,6 @@ source "drivers/staging/zcache/Kconfig" source "drivers/staging/goldfish/Kconfig" +source "drivers/staging/netlogic/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fa41b04cf4cb..d3040d7bdded 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_RTS5139) += rts5139/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ +obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ diff --git a/drivers/staging/netlogic/Kconfig b/drivers/staging/netlogic/Kconfig new file mode 100644 index 000000000000..d660de51b541 --- /dev/null +++ b/drivers/staging/netlogic/Kconfig @@ -0,0 +1,7 @@ +config NETLOGIC_XLR_NET + tristate "Netlogic XLR/XLS network device" + depends on CPU_XLR + select PHYLIB + ---help--- + This driver support Netlogic XLR/XLS on chip gigabit + Ethernet. diff --git a/drivers/staging/netlogic/Makefile b/drivers/staging/netlogic/Makefile new file mode 100644 index 000000000000..f7355e3e9c4c --- /dev/null +++ b/drivers/staging/netlogic/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_NETLOGIC_XLR_NET) += xlr_net.o platform_net.o diff --git a/drivers/staging/netlogic/TODO b/drivers/staging/netlogic/TODO new file mode 100644 index 000000000000..08e6d5218b3b --- /dev/null +++ b/drivers/staging/netlogic/TODO @@ -0,0 +1,12 @@ +* Implementing 64bit stat counter in software +* All memory allocation should be changed to DMA allocations +* All the netdev should be linked to single pdev as parent +* Changing comments in to linux standred format + +Please send patches +To: +Ganesan Ramalingam +Greg Kroah-Hartman +Cc: +Jayachandran Chandrashekaran Nair + diff --git a/drivers/staging/netlogic/platform_net.c b/drivers/staging/netlogic/platform_net.c new file mode 100644 index 000000000000..61f20e10d636 --- /dev/null +++ b/drivers/staging/netlogic/platform_net.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * 1. Redistributions of source code must retain the above copyright + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * 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, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "platform_net.h" + +/* Linux Net */ +#define MAX_NUM_GMAC 8 +#define MAX_NUM_XLS_GMAC 8 +#define MAX_NUM_XLR_GMAC 4 + + +static u32 xlr_gmac_offsets[] = { + NETLOGIC_IO_GMAC_0_OFFSET, NETLOGIC_IO_GMAC_1_OFFSET, + NETLOGIC_IO_GMAC_2_OFFSET, NETLOGIC_IO_GMAC_3_OFFSET, + NETLOGIC_IO_GMAC_4_OFFSET, NETLOGIC_IO_GMAC_5_OFFSET, + NETLOGIC_IO_GMAC_6_OFFSET, NETLOGIC_IO_GMAC_7_OFFSET +}; + +static u32 xlr_gmac_irqs[] = { PIC_GMAC_0_IRQ, PIC_GMAC_1_IRQ, + PIC_GMAC_2_IRQ, PIC_GMAC_3_IRQ, + PIC_GMAC_4_IRQ, PIC_GMAC_5_IRQ, + PIC_GMAC_6_IRQ, PIC_GMAC_7_IRQ +}; + +static struct xlr_net_data ndata[MAX_NUM_GMAC]; +static struct resource xlr_net_res[8][2]; +static struct platform_device xlr_net_dev[8]; +static u32 __iomem *gmac0_addr; +static u32 __iomem *gmac4_addr; +static u32 __iomem *gpio_addr; + +static void config_mac(struct xlr_net_data *nd, int phy, u32 __iomem *serdes, + u32 __iomem *pcs, int rfr, int tx, int *bkt_size, + struct xlr_fmn_info *gmac_fmn_info, int phy_addr) +{ + nd->cpu_mask = nlm_current_node()->coremask; + nd->phy_interface = phy; + nd->rfr_station = rfr; + nd->tx_stnid = tx; + nd->mii_addr = gmac0_addr; + nd->serdes_addr = serdes; + nd->pcs_addr = pcs; + nd->gpio_addr = gpio_addr; + + nd->bucket_size = bkt_size; + nd->gmac_fmn_info = gmac_fmn_info; + nd->phy_addr = phy_addr; +} + +static void net_device_init(int id, struct resource *res, int offset, int irq) +{ + res[0].name = "gmac"; + res[0].start = CPHYSADDR(nlm_mmio_base(offset)); + res[0].end = res[0].start + 0xfff; + res[0].flags = IORESOURCE_MEM; + + res[1].name = "gmac"; + res[1].start = irq; + res[1].end = irq; + res[1].flags = IORESOURCE_IRQ; + + xlr_net_dev[id].name = "xlr-net"; + xlr_net_dev[id].id = id; + xlr_net_dev[id].num_resources = 2; + xlr_net_dev[id].resource = res; + xlr_net_dev[id].dev.platform_data = &ndata[id]; +} + +static void xls_gmac_init(void) +{ + int mac; + + gmac4_addr = ioremap(CPHYSADDR( + nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), 0xfff); + /* Passing GPIO base for serdes init. Only needed on sgmii ports*/ + gpio_addr = ioremap(CPHYSADDR( + nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), 0xfff); + + switch (nlm_prom_info.board_major_version) { + case 12: + /* first block RGMII or XAUI, use RGMII */ + config_mac(&ndata[0], + PHY_INTERFACE_MODE_RGMII, + gmac0_addr, /* serdes */ + gmac0_addr, /* pcs */ + FMN_STNID_GMACRFR_0, + FMN_STNID_GMAC0_TX0, + xlr_board_fmn_config.bucket_size, + &xlr_board_fmn_config.gmac[0], + 0); + + net_device_init(0, xlr_net_res[0], xlr_gmac_offsets[0], + xlr_gmac_irqs[0]); + platform_device_register(&xlr_net_dev[0]); + + /* second block is XAUI, not supported yet */ + break; + default: + /* default XLS config, all ports SGMII */ + for (mac = 0; mac < 4; mac++) { + config_mac(&ndata[mac], + PHY_INTERFACE_MODE_SGMII, + gmac0_addr, /* serdes */ + gmac0_addr, /* pcs */ + FMN_STNID_GMACRFR_0, + FMN_STNID_GMAC0_TX0 + mac, + xlr_board_fmn_config.bucket_size, + &xlr_board_fmn_config.gmac[0], + /* PHY address according to chip/board */ + mac + 0x10); + + net_device_init(mac, xlr_net_res[mac], + xlr_gmac_offsets[mac], + xlr_gmac_irqs[mac]); + platform_device_register(&xlr_net_dev[mac]); + } + + for (mac = 4; mac < MAX_NUM_XLS_GMAC; mac++) { + config_mac(&ndata[mac], + PHY_INTERFACE_MODE_SGMII, + gmac4_addr, /* serdes */ + gmac4_addr, /* pcs */ + FMN_STNID_GMAC1_FR_0, + FMN_STNID_GMAC1_TX0 + mac - 4, + xlr_board_fmn_config.bucket_size, + &xlr_board_fmn_config.gmac[1], + /* PHY address according to chip/board */ + mac + 0x10); + + net_device_init(mac, xlr_net_res[mac], + xlr_gmac_offsets[mac], + xlr_gmac_irqs[mac]); + platform_device_register(&xlr_net_dev[mac]); + } + } +} + +static void xlr_gmac_init(void) +{ + int mac; + + /* assume all GMACs for now */ + for (mac = 0; mac < MAX_NUM_XLR_GMAC; mac++) { + config_mac(&ndata[mac], + PHY_INTERFACE_MODE_RGMII, + 0, + 0, + FMN_STNID_GMACRFR_0, + FMN_STNID_GMAC0_TX0, + xlr_board_fmn_config.bucket_size, + &xlr_board_fmn_config.gmac[0], + mac); + + net_device_init(mac, xlr_net_res[mac], xlr_gmac_offsets[mac], + xlr_gmac_irqs[mac]); + platform_device_register(&xlr_net_dev[mac]); + } +} + +static int __init xlr_net_init(void) +{ + gmac0_addr = ioremap(CPHYSADDR( + nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff); + + if (nlm_chip_is_xls()) + xls_gmac_init(); + else + xlr_gmac_init(); + + return 0; +} + +arch_initcall(xlr_net_init); diff --git a/drivers/staging/netlogic/platform_net.h b/drivers/staging/netlogic/platform_net.h new file mode 100644 index 000000000000..29deeea72ca1 --- /dev/null +++ b/drivers/staging/netlogic/platform_net.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * 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, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ +struct xlr_net_data { + int cpu_mask; + u32 __iomem *mii_addr; + u32 __iomem *serdes_addr; + u32 __iomem *pcs_addr; + u32 __iomem *gpio_addr; + int phy_interface; + int rfr_station; + int tx_stnid; + int *bucket_size; + int phy_addr; + struct xlr_fmn_info *gmac_fmn_info; +}; diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c new file mode 100644 index 000000000000..efc6172b73b6 --- /dev/null +++ b/drivers/staging/netlogic/xlr_net.c @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * 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, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* fmn.h - For FMN credit configuration and registering fmn_handler. + * FMN is communication mechanism that allows processing agents within + * XLR/XLS to communicate each other. + */ +#include + +#include "platform_net.h" +#include "xlr_net.h" + +/* + * The readl/writel implementation byteswaps on XLR/XLS, so + * we need to use __raw_ IO to read the NAE registers + * because they are in the big-endian MMIO area on the SoC. + */ +static inline void xlr_nae_wreg(u32 __iomem *base, unsigned int reg, u32 val) +{ + __raw_writel(val, base + reg); +} + +static inline u32 xlr_nae_rdreg(u32 __iomem *base, unsigned int reg) +{ + return __raw_readl(base + reg); +} + +static inline void xlr_reg_update(u32 *base_addr, + u32 off, u32 val, u32 mask) +{ + u32 tmp; + + tmp = xlr_nae_rdreg(base_addr, off); + xlr_nae_wreg(base_addr, off, (tmp & ~mask) | (val & mask)); +} + +/* + * Table of net_device pointers indexed by port, this will be used to + * lookup the net_device corresponding to a port by the message ring handler. + * + * Maximum ports in XLR/XLS is 8(8 GMAC on XLS, 4 GMAC + 2 XGMAC on XLR) + */ +static struct net_device *mac_to_ndev[8]; + +static inline struct sk_buff *mac_get_skb_back_ptr(void *addr) +{ + struct sk_buff **back_ptr; + + /* this function should be used only for newly allocated packets. + * It assumes the first cacheline is for the back pointer related + * book keeping info. + */ + back_ptr = (struct sk_buff **)(addr - MAC_SKB_BACK_PTR_SIZE); + return *back_ptr; +} + +static inline void mac_put_skb_back_ptr(struct sk_buff *skb) +{ + struct sk_buff **back_ptr = (struct sk_buff **)skb->data; + + /* this function should be used only for newly allocated packets. + * It assumes the first cacheline is for the back pointer related + * book keeping info. + */ + skb_reserve(skb, MAC_SKB_BACK_PTR_SIZE); + *back_ptr = skb; +} + +static int send_to_rfr_fifo(struct xlr_net_priv *priv, void *addr) +{ + struct nlm_fmn_msg msg; + int ret = 0, num_try = 0, stnid; + unsigned long paddr, mflags; + + paddr = virt_to_bus(addr); + msg.msg0 = (u64)paddr & 0xffffffffe0ULL; + msg.msg1 = 0; + msg.msg2 = 0; + msg.msg3 = 0; + stnid = priv->nd->rfr_station; + do { + mflags = nlm_cop2_enable(); + ret = nlm_fmn_send(1, 0, stnid, &msg); + nlm_cop2_restore(mflags); + if (ret == 0) + return 0; + } while (++num_try < 10000); + + pr_err("Send to RFR failed in RX path\n"); + return ret; +} + +static inline struct sk_buff *xlr_alloc_skb(void) +{ + struct sk_buff *skb; + + /* skb->data is cache aligned */ + skb = alloc_skb(XLR_RX_BUF_SIZE, GFP_ATOMIC); + if (!skb) { + pr_err("SKB allocation failed\n"); + return NULL; + } + mac_put_skb_back_ptr(skb); + return skb; +} + +static void xlr_net_fmn_handler(int bkt, int src_stnid, int size, + int code, struct nlm_fmn_msg *msg, void *arg) +{ + struct sk_buff *skb, *skb_new = NULL; + struct net_device *ndev; + struct xlr_net_priv *priv; + u64 length, port; + void *addr; + + length = (msg->msg0 >> 40) & 0x3fff; + if (length == 0) { + addr = bus_to_virt(msg->msg0 & 0xffffffffffULL); + dev_kfree_skb_any(addr); + } else if (length) { + addr = bus_to_virt(msg->msg0 & 0xffffffffe0ULL); + length = length - BYTE_OFFSET - MAC_CRC_LEN; + port = msg->msg0 & 0x0f; + if (src_stnid == FMN_STNID_GMAC1) + port = port + 4; + skb = mac_get_skb_back_ptr(addr); + skb->dev = mac_to_ndev[port]; + ndev = skb->dev; + priv = netdev_priv(ndev); + + /* 16 byte IP header align */ + skb_reserve(skb, BYTE_OFFSET); + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, skb->dev); + skb->dev->last_rx = jiffies; + netif_rx(skb); + /* Fill rx ring */ + skb_new = xlr_alloc_skb(); + if (skb_new) + send_to_rfr_fifo(priv, skb_new->data); + } + return; +} + +/* Ethtool operation */ +static int xlr_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + if (!phydev) + return -ENODEV; + return phy_ethtool_gset(phydev, ecmd); +} + +static int xlr_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + if (!phydev) + return -ENODEV; + return phy_ethtool_sset(phydev, ecmd); +} + +static struct ethtool_ops xlr_ethtool_ops = { + .get_settings = xlr_get_settings, + .set_settings = xlr_set_settings, +}; + +/* Net operations */ +static int xlr_net_fill_rx_ring(struct net_device *ndev) +{ + struct sk_buff *skb; + struct xlr_net_priv *priv = netdev_priv(ndev); + int i; + + for (i = 0; i < MAX_FRIN_SPILL/2; i++) { + skb = xlr_alloc_skb(); + if (!skb) + return -ENOMEM; + send_to_rfr_fifo(priv, skb->data); + } + pr_info("Rx ring setup done\n"); + return 0; +} + +static int xlr_net_open(struct net_device *ndev) +{ + u32 err; + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + /* schedule a link state check */ + phy_start(phydev); + + err = phy_start_aneg(phydev); + if (err) { + pr_err("Autoneg failed\n"); + return err; + } + + /* Setup the speed from PHY to internal reg*/ + xlr_set_gmac_speed(priv); + netif_tx_start_all_queues(ndev); + return 0; +} + +static int xlr_net_stop(struct net_device *ndev) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + phy_stop(phydev); + netif_tx_stop_all_queues(ndev); + return 0; +} + +static void xlr_make_tx_desc(struct nlm_fmn_msg *msg, unsigned long addr, + struct sk_buff *skb) +{ + unsigned long physkb = virt_to_phys(skb); + int cpu_core = nlm_core_id(); + int fr_stn_id = cpu_core * 8 + XLR_FB_STN; /* FB to 6th bucket */ + msg->msg0 = (((u64)1 << 63) | /* End of packet descriptor */ + ((u64)127 << 54) | /* No Free back */ + (u64)skb->len << 40 | /* Length of data */ + ((u64)addr)); + msg->msg1 = (((u64)1 << 63) | + ((u64)fr_stn_id << 54) | /* Free back id */ + (u64)0 << 40 | /* Set len to 0 */ + ((u64)physkb & 0xffffffff)); /* 32bit address */ + msg->msg2 = msg->msg3 = 0; +} + +static void __maybe_unused xlr_wakeup_queue(unsigned long dev) +{ + struct net_device *ndev = (struct net_device *) dev; + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + if (phydev->link) + netif_tx_wake_queue(netdev_get_tx_queue(ndev, priv->wakeup_q)); +} + +static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb, + struct net_device *ndev) +{ + struct nlm_fmn_msg msg; + struct xlr_net_priv *priv = netdev_priv(ndev); + int ret; + u16 qmap; + u32 flags; + + qmap = skb->queue_mapping; + xlr_make_tx_desc(&msg, virt_to_phys(skb->data), skb); + flags = nlm_cop2_enable(); + ret = nlm_fmn_send(2, 0, priv->nd->tx_stnid, &msg); + nlm_cop2_restore(flags); + if (ret) + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +static u16 xlr_net_select_queue(struct net_device *ndev, struct sk_buff *skb) +{ + return (u16)smp_processor_id(); +} + +static void xlr_hw_set_mac_addr(struct net_device *ndev) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + + /* set mac station address */ + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0, + ((ndev->dev_addr[5] << 24) | (ndev->dev_addr[4] << 16) | + (ndev->dev_addr[3] << 8) | (ndev->dev_addr[2]))); + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0 + 1, + ((ndev->dev_addr[1] << 24) | (ndev->dev_addr[0] << 16))); + + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2 + 1, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3 + 1, 0xffffffff); + + xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG, + (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID)); + + if (priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII || + priv->nd->phy_interface == PHY_INTERFACE_MODE_SGMII) + xlr_reg_update(priv->base_addr, R_IPG_IFG, MAC_B2B_IPG, 0x7f); +} + +static int xlr_net_set_mac_addr(struct net_device *ndev, void *data) +{ + int err; + + err = eth_mac_addr(ndev, data); + if (err) + return err; + xlr_hw_set_mac_addr(ndev); + return 0; +} + +static void xlr_set_rx_mode(struct net_device *ndev) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + u32 regval; + + regval = xlr_nae_rdreg(priv->base_addr, R_MAC_FILTER_CONFIG); + + if (ndev->flags & IFF_PROMISC) { + regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); + } else { + regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); + } + + xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG, regval); +} + +static void xlr_stats(struct net_device *ndev, struct rtnl_link_stats64 *stats) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + + stats->rx_packets = xlr_nae_rdreg(priv->base_addr, RX_PACKET_COUNTER); + stats->tx_packets = xlr_nae_rdreg(priv->base_addr, TX_PACKET_COUNTER); + stats->rx_bytes = xlr_nae_rdreg(priv->base_addr, RX_BYTE_COUNTER); + stats->tx_bytes = xlr_nae_rdreg(priv->base_addr, TX_BYTE_COUNTER); + stats->tx_errors = xlr_nae_rdreg(priv->base_addr, TX_FCS_ERROR_COUNTER); + stats->rx_dropped = xlr_nae_rdreg(priv->base_addr, + RX_DROP_PACKET_COUNTER); + stats->tx_dropped = xlr_nae_rdreg(priv->base_addr, + TX_DROP_FRAME_COUNTER); + + stats->multicast = xlr_nae_rdreg(priv->base_addr, + RX_MULTICAST_PACKET_COUNTER); + stats->collisions = xlr_nae_rdreg(priv->base_addr, + TX_TOTAL_COLLISION_COUNTER); + + stats->rx_length_errors = xlr_nae_rdreg(priv->base_addr, + RX_FRAME_LENGTH_ERROR_COUNTER); + stats->rx_over_errors = xlr_nae_rdreg(priv->base_addr, + RX_DROP_PACKET_COUNTER); + stats->rx_crc_errors = xlr_nae_rdreg(priv->base_addr, + RX_FCS_ERROR_COUNTER); + stats->rx_frame_errors = xlr_nae_rdreg(priv->base_addr, + RX_ALIGNMENT_ERROR_COUNTER); + + stats->rx_fifo_errors = xlr_nae_rdreg(priv->base_addr, + RX_DROP_PACKET_COUNTER); + stats->rx_missed_errors = xlr_nae_rdreg(priv->base_addr, + RX_CARRIER_SENSE_ERROR_COUNTER); + + stats->rx_errors = (stats->rx_over_errors + stats->rx_crc_errors + + stats->rx_frame_errors + stats->rx_fifo_errors + + stats->rx_missed_errors); + + stats->tx_aborted_errors = xlr_nae_rdreg(priv->base_addr, + TX_EXCESSIVE_COLLISION_PACKET_COUNTER); + stats->tx_carrier_errors = xlr_nae_rdreg(priv->base_addr, + TX_DROP_FRAME_COUNTER); + stats->tx_fifo_errors = xlr_nae_rdreg(priv->base_addr, + TX_DROP_FRAME_COUNTER); +} + +static struct rtnl_link_stats64 *xlr_get_stats64(struct net_device *ndev, + struct rtnl_link_stats64 *stats) +{ + xlr_stats(ndev, stats); + return stats; +} + +static struct net_device_ops xlr_netdev_ops = { + .ndo_open = xlr_net_open, + .ndo_stop = xlr_net_stop, + .ndo_start_xmit = xlr_net_start_xmit, + .ndo_select_queue = xlr_net_select_queue, + .ndo_set_mac_address = xlr_net_set_mac_addr, + .ndo_set_rx_mode = xlr_set_rx_mode, + .ndo_get_stats64 = xlr_get_stats64, +}; + +/* Gmac init */ +static void *xlr_config_spill(struct xlr_net_priv *priv, int reg_start_0, + int reg_start_1, int reg_size, int size) +{ + void *spill; + u32 *base; + unsigned long phys_addr; + u32 spill_size; + + base = priv->base_addr; + spill_size = size; + spill = kmalloc(spill_size + SMP_CACHE_BYTES, GFP_ATOMIC); + if (!spill) + pr_err("Unable to allocate memory for spill area!\n"); + + spill = PTR_ALIGN(spill, SMP_CACHE_BYTES); + phys_addr = virt_to_phys(spill); + dev_dbg(&priv->ndev->dev, "Allocated spill %d bytes at %lx\n", + size, phys_addr); + xlr_nae_wreg(base, reg_start_0, (phys_addr >> 5) & 0xffffffff); + xlr_nae_wreg(base, reg_start_1, ((u64)phys_addr >> 37) & 0x07); + xlr_nae_wreg(base, reg_size, spill_size); + + return spill; +} + +/* + * Configure the 6 FIFO's that are used by the network accelarator to + * communicate with the rest of the XLx device. 4 of the FIFO's are for + * packets from NA --> cpu (called Class FIFO's) and 2 are for feeding + * the NA with free descriptors. + */ +static void xlr_config_fifo_spill_area(struct xlr_net_priv *priv) +{ + priv->frin_spill = xlr_config_spill(priv, + R_REG_FRIN_SPILL_MEM_START_0, + R_REG_FRIN_SPILL_MEM_START_1, + R_REG_FRIN_SPILL_MEM_SIZE, + MAX_FRIN_SPILL * + sizeof(u64)); + priv->frout_spill = xlr_config_spill(priv, + R_FROUT_SPILL_MEM_START_0, + R_FROUT_SPILL_MEM_START_1, + R_FROUT_SPILL_MEM_SIZE, + MAX_FROUT_SPILL * + sizeof(u64)); + priv->class_0_spill = xlr_config_spill(priv, + R_CLASS0_SPILL_MEM_START_0, + R_CLASS0_SPILL_MEM_START_1, + R_CLASS0_SPILL_MEM_SIZE, + MAX_CLASS_0_SPILL * + sizeof(u64)); + priv->class_1_spill = xlr_config_spill(priv, + R_CLASS1_SPILL_MEM_START_0, + R_CLASS1_SPILL_MEM_START_1, + R_CLASS1_SPILL_MEM_SIZE, + MAX_CLASS_1_SPILL * + sizeof(u64)); + priv->class_2_spill = xlr_config_spill(priv, + R_CLASS2_SPILL_MEM_START_0, + R_CLASS2_SPILL_MEM_START_1, + R_CLASS2_SPILL_MEM_SIZE, + MAX_CLASS_2_SPILL * + sizeof(u64)); + priv->class_3_spill = xlr_config_spill(priv, + R_CLASS3_SPILL_MEM_START_0, + R_CLASS3_SPILL_MEM_START_1, + R_CLASS3_SPILL_MEM_SIZE, + MAX_CLASS_3_SPILL * + sizeof(u64)); +} + +/* Configure PDE to Round-Robin distribution of packets to the + * available cpu */ +static void xlr_config_pde(struct xlr_net_priv *priv) +{ + int i = 0; + u64 bkt_map = 0; + + /* Each core has 8 buckets(station) */ + for (i = 0; i < hweight32(priv->nd->cpu_mask); i++) + bkt_map |= (0xff << (i * 8)); + + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0, (bkt_map & 0xffffffff)); + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0 + 1, + ((bkt_map >> 32) & 0xffffffff)); + + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1, (bkt_map & 0xffffffff)); + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1 + 1, + ((bkt_map >> 32) & 0xffffffff)); + + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2, (bkt_map & 0xffffffff)); + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2 + 1, + ((bkt_map >> 32) & 0xffffffff)); + + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3, (bkt_map & 0xffffffff)); + xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3 + 1, + ((bkt_map >> 32) & 0xffffffff)); +} + +/* Setup the Message ring credits, bucket size and other + * common configuration */ +static void xlr_config_common(struct xlr_net_priv *priv) +{ + struct xlr_fmn_info *gmac = priv->nd->gmac_fmn_info; + int start_stn_id = gmac->start_stn_id; + int end_stn_id = gmac->end_stn_id; + int *bucket_size = priv->nd->bucket_size; + int i, j; + + /* Setting non-core MsgBktSize(0x321 - 0x325) */ + for (i = start_stn_id; i <= end_stn_id; i++) { + xlr_nae_wreg(priv->base_addr, + R_GMAC_RFR0_BUCKET_SIZE + i - start_stn_id, + bucket_size[i]); + } + + /* Setting non-core Credit counter register + * Distributing Gmac's credit to CPU's*/ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) + xlr_nae_wreg(priv->base_addr, + (R_CC_CPU0_0 + (i * 8)) + j, + gmac->credit_config[(i * 8) + j]); + } + + xlr_nae_wreg(priv->base_addr, R_MSG_TX_THRESHOLD, 3); + xlr_nae_wreg(priv->base_addr, R_DMACR0, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_DMACR1, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_DMACR2, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_DMACR3, 0xffffffff); + xlr_nae_wreg(priv->base_addr, R_FREEQCARVE, 0); + + xlr_net_fill_rx_ring(priv->ndev); + nlm_register_fmn_handler(start_stn_id, end_stn_id, xlr_net_fmn_handler, + NULL); +} + +static void xlr_config_translate_table(struct xlr_net_priv *priv) +{ + u32 cpu_mask; + u32 val; + int bkts[32]; /* one bucket is assumed for each cpu */ + int b1, b2, c1, c2, i, j, k; + int use_bkt; + + use_bkt = 0; + cpu_mask = priv->nd->cpu_mask; + + pr_info("Using %s-based distribution\n", + (use_bkt) ? "bucket" : "class"); + j = 0; + for (i = 0; i < 32; i++) { + if ((1 << i) & cpu_mask) { + /* for each cpu, mark the 4+threadid bucket */ + bkts[j] = ((i / 4) * 8) + (i % 4); + j++; + } + } + + /*configure the 128 * 9 Translation table to send to available buckets*/ + k = 0; + c1 = 3; + c2 = 0; + for (i = 0; i < 64; i++) { + /* On use_bkt set the b0, b1 are used, else + * the 4 classes are used, here implemented + * a logic to distribute the packets to the + * buckets equally or based on the class + */ + c1 = (c1 + 1) & 3; + c2 = (c1 + 1) & 3; + b1 = bkts[k]; + k = (k + 1) % j; + b2 = bkts[k]; + k = (k + 1) % j; + val = ((c1 << 23) | (b1 << 17) | (use_bkt << 16) | + (c2 << 7) | (b2 << 1) | (use_bkt << 0)); + + val = ((c1 << 23) | (b1 << 17) | (use_bkt << 16) | + (c2 << 7) | (b2 << 1) | (use_bkt << 0)); + dev_dbg(&priv->ndev->dev, "Table[%d] b1=%d b2=%d c1=%d c2=%d\n", + i, b1, b2, c1, c2); + xlr_nae_wreg(priv->base_addr, R_TRANSLATETABLE + i, val); + c1 = c2; + } +} + +static void xlr_config_parser(struct xlr_net_priv *priv) +{ + u32 val; + + /* Mark it as ETHERNET type */ + xlr_nae_wreg(priv->base_addr, R_L2TYPE_0, 0x01); + + /* Use 7bit CRChash for flow classification with 127 as CRC polynomial*/ + xlr_nae_wreg(priv->base_addr, R_PARSERCONFIGREG, + ((0x7f << 8) | (1 << 1))); + + /* configure the parser : L2 Type is configured in the bootloader */ + /* extract IP: src, dest protocol */ + xlr_nae_wreg(priv->base_addr, R_L3CTABLE, + (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | + (0x0800 << 0)); + xlr_nae_wreg(priv->base_addr, R_L3CTABLE + 1, + (9 << 25) | (1 << 21) | (12 << 14) | (4 << 10) | + (16 << 4) | 4); + + /* Configure to extract SRC port and Dest port for TCP and UDP pkts */ + xlr_nae_wreg(priv->base_addr, R_L4CTABLE, 6); + xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 2, 17); + val = ((0 << 21) | (2 << 17) | (2 << 11) | (2 << 7)); + xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 1, val); + xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 3, val); + + xlr_config_translate_table(priv); +} + +static int xlr_phy_write(u32 *base_addr, int phy_addr, int regnum, u16 val) +{ + unsigned long timeout, stoptime, checktime; + int timedout; + + /* 100ms timeout*/ + timeout = msecs_to_jiffies(100); + stoptime = jiffies + timeout; + timedout = 0; + + xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS, (phy_addr << 8) | regnum); + + /* Write the data which starts the write cycle */ + xlr_nae_wreg(base_addr, R_MII_MGMT_WRITE_DATA, (u32) val); + + /* poll for the read cycle to complete */ + while (!timedout) { + checktime = jiffies; + if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0) + break; + timedout = time_after(checktime, stoptime); + } + if (timedout) { + pr_info("Phy device write err: device busy"); + return -EBUSY; + } + + return 0; +} + +static int xlr_phy_read(u32 *base_addr, int phy_addr, int regnum) +{ + unsigned long timeout, stoptime, checktime; + int timedout; + + /* 100ms timeout*/ + timeout = msecs_to_jiffies(100); + stoptime = jiffies + timeout; + timedout = 0; + + /* setup the phy reg to be used */ + xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS, + (phy_addr << 8) | (regnum << 0)); + + /* Issue the read command */ + xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND, + (1 << O_MII_MGMT_COMMAND__rstat)); + + + /* poll for the read cycle to complete */ + while (!timedout) { + checktime = jiffies; + if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0) + break; + timedout = time_after(checktime, stoptime); + } + if (timedout) { + pr_info("Phy device read err: device busy"); + return -EBUSY; + } + + /* clear the read cycle */ + xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND, 0); + + /* Read the data */ + return xlr_nae_rdreg(base_addr, R_MII_MGMT_STATUS); +} + +static int xlr_mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 val) +{ + struct xlr_net_priv *priv = bus->priv; + int ret; + + ret = xlr_phy_write(priv->mii_addr, phy_addr, regnum, val); + dev_dbg(&priv->ndev->dev, "mii_write phy %d : %d <- %x [%x]\n", + phy_addr, regnum, val, ret); + return ret; +} + +static int xlr_mii_read(struct mii_bus *bus, int phy_addr, int regnum) +{ + struct xlr_net_priv *priv = bus->priv; + int ret; + + ret = xlr_phy_read(priv->mii_addr, phy_addr, regnum); + dev_dbg(&priv->ndev->dev, "mii_read phy %d : %d [%x]\n", + phy_addr, regnum, ret); + return ret; +} + +/* XLR ports are RGMII. XLS ports are SGMII mostly except the port0, + * which can be configured either SGMII or RGMII, considered SGMII + * by default, if board setup to RGMII the port_type need to set + * accordingly.Serdes and PCS layer need to configured for SGMII + */ +static void xlr_sgmii_init(struct xlr_net_priv *priv) +{ + int phy; + + xlr_phy_write(priv->serdes_addr, 26, 0, 0x6DB0); + xlr_phy_write(priv->serdes_addr, 26, 1, 0xFFFF); + xlr_phy_write(priv->serdes_addr, 26, 2, 0xB6D0); + xlr_phy_write(priv->serdes_addr, 26, 3, 0x00FF); + xlr_phy_write(priv->serdes_addr, 26, 4, 0x0000); + xlr_phy_write(priv->serdes_addr, 26, 5, 0x0000); + xlr_phy_write(priv->serdes_addr, 26, 6, 0x0005); + xlr_phy_write(priv->serdes_addr, 26, 7, 0x0001); + xlr_phy_write(priv->serdes_addr, 26, 8, 0x0000); + xlr_phy_write(priv->serdes_addr, 26, 9, 0x0000); + xlr_phy_write(priv->serdes_addr, 26, 10, 0x0000); + + /* program GPIO values for serdes init parameters */ + xlr_nae_wreg(priv->gpio_addr, 0x20, 0x7e6802); + xlr_nae_wreg(priv->gpio_addr, 0x10, 0x7104); + + xlr_nae_wreg(priv->gpio_addr, 0x22, 0x7e6802); + xlr_nae_wreg(priv->gpio_addr, 0x21, 0x7104); + + /* enable autoneg - more magic */ + phy = priv->port_id % 4 + 27; + xlr_phy_write(priv->pcs_addr, phy, 0, 0x1000); + xlr_phy_write(priv->pcs_addr, phy, 0, 0x0200); +} + +void xlr_set_gmac_speed(struct xlr_net_priv *priv) +{ + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + int speed; + + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) + xlr_sgmii_init(priv); + + if (phydev->speed != priv->phy_speed) { + pr_info("change %d to %d\n", priv->phy_speed, phydev->speed); + speed = phydev->speed; + if (speed == SPEED_1000) { + /* Set interface to Byte mode */ + xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217); + priv->phy_speed = speed; + } else if (speed == SPEED_100 || speed == SPEED_10) { + /* Set interface to Nibble mode */ + xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117); + priv->phy_speed = speed; + } + /* Set SGMII speed in Interface controll reg */ + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + if (speed == SPEED_10) + xlr_nae_wreg(priv->base_addr, + R_INTERFACE_CONTROL, SGMII_SPEED_10); + if (speed == SPEED_100) + xlr_nae_wreg(priv->base_addr, + R_INTERFACE_CONTROL, SGMII_SPEED_100); + if (speed == SPEED_1000) + xlr_nae_wreg(priv->base_addr, + R_INTERFACE_CONTROL, SGMII_SPEED_1000); + } + if (speed == SPEED_10) + xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x2); + if (speed == SPEED_100) + xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x1); + if (speed == SPEED_1000) + xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x0); + } + pr_info("gmac%d : %dMbps\n", priv->port_id, priv->phy_speed); +} + +static void xlr_gmac_link_adjust(struct net_device *ndev) +{ + struct xlr_net_priv *priv = netdev_priv(ndev); + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + u32 intreg; + + intreg = xlr_nae_rdreg(priv->base_addr, R_INTREG); + if (phydev->link) { + if (phydev->speed != priv->phy_speed) { + pr_info("gmac%d : Link up\n", priv->port_id); + xlr_set_gmac_speed(priv); + } + } else { + pr_info("gmac%d : Link down\n", priv->port_id); + xlr_set_gmac_speed(priv); + } +} + +static int xlr_mii_probe(struct xlr_net_priv *priv) +{ + struct phy_device *phydev = priv->mii_bus->phy_map[priv->phy_addr]; + + if (!phydev) { + pr_err("no PHY found on phy_addr %d\n", priv->phy_addr); + return -ENODEV; + } + + /* Attach MAC to PHY */ + phydev = phy_connect(priv->ndev, dev_name(&phydev->dev), + &xlr_gmac_link_adjust, priv->nd->phy_interface); + + if (IS_ERR(phydev)) { + pr_err("could not attach PHY\n"); + return PTR_ERR(phydev); + } + phydev->supported &= (ADVERTISED_10baseT_Full + | ADVERTISED_10baseT_Half + | ADVERTISED_100baseT_Full + | ADVERTISED_100baseT_Half + | ADVERTISED_1000baseT_Full + | ADVERTISED_Autoneg + | ADVERTISED_MII); + + phydev->advertising = phydev->supported; + pr_info("attached PHY driver [%s] (mii_bus:phy_addr=%s\n", + phydev->drv->name, dev_name(&phydev->dev)); + return 0; +} + +static int xlr_setup_mdio(struct xlr_net_priv *priv, + struct platform_device *pdev) +{ + int err; + + priv->phy_addr = priv->nd->phy_addr; + priv->mii_bus = mdiobus_alloc(); + if (!priv->mii_bus) { + pr_err("mdiobus alloc failed\n"); + return -ENOMEM; + } + + priv->mii_bus->priv = priv; + priv->mii_bus->name = "xlr-mdio"; + snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d", + priv->mii_bus->name, priv->port_id); + priv->mii_bus->read = xlr_mii_read; + priv->mii_bus->write = xlr_mii_write; + priv->mii_bus->parent = &pdev->dev; + priv->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); + priv->mii_bus->irq[priv->phy_addr] = priv->ndev->irq; + + /* Scan only the enabled address */ + priv->mii_bus->phy_mask = ~(1 << priv->phy_addr); + + /* setting clock divisor to 54 */ + xlr_nae_wreg(priv->base_addr, R_MII_MGMT_CONFIG, 0x7); + + err = mdiobus_register(priv->mii_bus); + if (err) { + mdiobus_free(priv->mii_bus); + pr_err("mdio bus registration failed\n"); + return err; + } + + pr_info("Registerd mdio bus id : %s\n", priv->mii_bus->id); + err = xlr_mii_probe(priv); + if (err) { + mdiobus_free(priv->mii_bus); + return err; + } + return 0; +} + +static void xlr_port_enable(struct xlr_net_priv *priv) +{ + u32 prid = (read_c0_prid() & 0xf000); + + /* Setup MAC_CONFIG reg if (xls & rgmii) */ + if ((prid == 0x8000 || prid == 0x4000 || prid == 0xc000) && + priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII) + xlr_reg_update(priv->base_addr, R_RX_CONTROL, + (1 << O_RX_CONTROL__RGMII), (1 << O_RX_CONTROL__RGMII)); + + /* Rx Tx enable */ + xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1, + ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen) | + (1 << O_MAC_CONFIG_1__rxfc) | (1 << O_MAC_CONFIG_1__txfc)), + ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen) | + (1 << O_MAC_CONFIG_1__rxfc) | (1 << O_MAC_CONFIG_1__txfc))); + + /* Setup tx control reg */ + xlr_reg_update(priv->base_addr, R_TX_CONTROL, + ((1 << O_TX_CONTROL__TxEnable) | + (512 << O_TX_CONTROL__TxThreshold)), 0x3fff); + + /* Setup rx control reg */ + xlr_reg_update(priv->base_addr, R_RX_CONTROL, + 1 << O_RX_CONTROL__RxEnable, 1 << O_RX_CONTROL__RxEnable); +} + +static void xlr_port_disable(struct xlr_net_priv *priv) +{ + /* Setup MAC_CONFIG reg */ + /* Rx Tx disable*/ + xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1, + ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen) | + (1 << O_MAC_CONFIG_1__rxfc) | (1 << O_MAC_CONFIG_1__txfc)), + 0x0); + + /* Setup tx control reg */ + xlr_reg_update(priv->base_addr, R_TX_CONTROL, + ((1 << O_TX_CONTROL__TxEnable) | + (512 << O_TX_CONTROL__TxThreshold)), 0); + + /* Setup rx control reg */ + xlr_reg_update(priv->base_addr, R_RX_CONTROL, + 1 << O_RX_CONTROL__RxEnable, 0); +} + +/* Initialization of gmac */ +static int xlr_gmac_init(struct xlr_net_priv *priv, + struct platform_device *pdev) +{ + int ret; + + pr_info("Initializing the gmac%d\n", priv->port_id); + + xlr_port_disable(priv); + xlr_nae_wreg(priv->base_addr, R_DESC_PACK_CTRL, + (1 << O_DESC_PACK_CTRL__MaxEntry) + | (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset) + | (1600 << O_DESC_PACK_CTRL__RegularSize)); + + ret = xlr_setup_mdio(priv, pdev); + if (ret) + return ret; + xlr_port_enable(priv); + + /* Enable Full-duplex/1000Mbps/CRC */ + xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217); + /* speed 2.5Mhz */ + xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x02); + /* Setup Interrupt mask reg */ + xlr_nae_wreg(priv->base_addr, R_INTMASK, + (1 << O_INTMASK__TxIllegal) | + (1 << O_INTMASK__MDInt) | + (1 << O_INTMASK__TxFetchError) | + (1 << O_INTMASK__P2PSpillEcc) | + (1 << O_INTMASK__TagFull) | + (1 << O_INTMASK__Underrun) | + (1 << O_INTMASK__Abort) + ); + + /* Clear all stats */ + xlr_reg_update(priv->base_addr, R_STATCTRL, + 0, 1 << O_STATCTRL__ClrCnt); + xlr_reg_update(priv->base_addr, R_STATCTRL, + 1 << O_STATCTRL__ClrCnt, 1 << O_STATCTRL__ClrCnt); + return 0; +} + +static int xlr_net_probe(struct platform_device *pdev) +{ + struct xlr_net_priv *priv = NULL; + struct net_device *ndev; + struct resource *res; + int mac, err; + + mac = pdev->id; + ndev = alloc_etherdev_mq(sizeof(struct xlr_net_priv), 32); + if (!ndev) { + pr_err("Allocation of Ethernet device failed\n"); + return -ENOMEM; + } + + priv = netdev_priv(ndev); + priv->pdev = pdev; + priv->ndev = ndev; + priv->port_id = mac; + priv->nd = (struct xlr_net_data *)pdev->dev.platform_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + pr_err("No memory resource for MAC %d\n", mac); + err = -ENODEV; + goto err_gmac; + } + + ndev->base_addr = (unsigned long) devm_request_and_ioremap + (&pdev->dev, res); + if (!ndev->base_addr) { + dev_err(&pdev->dev, + "devm_request_and_ioremap failed\n"); + return -EBUSY; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res == NULL) { + pr_err("No irq resource for MAC %d\n", mac); + err = -ENODEV; + goto err_gmac; + } + ndev->irq = res->start; + + priv->mii_addr = priv->nd->mii_addr; + priv->serdes_addr = priv->nd->serdes_addr; + priv->pcs_addr = priv->nd->pcs_addr; + priv->gpio_addr = priv->nd->gpio_addr; + priv->base_addr = (u32 *) ndev->base_addr; + + mac_to_ndev[mac] = ndev; + ndev->netdev_ops = &xlr_netdev_ops; + ndev->watchdog_timeo = HZ; + + /* Setup Mac address and Rx mode */ + eth_hw_addr_random(ndev); + xlr_hw_set_mac_addr(ndev); + xlr_set_rx_mode(ndev); + + priv->num_rx_desc += MAX_NUM_DESC_SPILL; + SET_ETHTOOL_OPS(ndev, &xlr_ethtool_ops); + SET_NETDEV_DEV(ndev, &pdev->dev); + + /* Common registers, do one time initialization */ + if (mac == 0 || mac == 4) { + xlr_config_fifo_spill_area(priv); + /* Configure PDE to Round-Robin pkt distribution */ + xlr_config_pde(priv); + xlr_config_parser(priv); + } + /* Call init with respect to port */ + if (strcmp(res->name, "gmac") == 0) { + err = xlr_gmac_init(priv, pdev); + if (err) { + pr_err("gmac%d init failed\n", mac); + goto err_gmac; + } + } + + if (mac == 0 || mac == 4) + xlr_config_common(priv); + + err = register_netdev(ndev); + if (err) + goto err_netdev; + platform_set_drvdata(pdev, priv); + return 0; + +err_netdev: + mdiobus_free(priv->mii_bus); +err_gmac: + free_netdev(ndev); + return err; +} + +static int xlr_net_remove(struct platform_device *pdev) +{ + struct xlr_net_priv *priv = platform_get_drvdata(pdev); + unregister_netdev(priv->ndev); + mdiobus_unregister(priv->mii_bus); + mdiobus_free(priv->mii_bus); + free_netdev(priv->ndev); + return 0; +} + +static struct platform_driver xlr_net_driver = { + .probe = xlr_net_probe, + .remove = xlr_net_remove, + .driver = { + .name = "xlr-net", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(xlr_net_driver); + +MODULE_AUTHOR("Ganesan Ramalingam "); +MODULE_DESCRIPTION("Ethernet driver for Netlogic XLR/XLS"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("platform:xlr-net"); diff --git a/drivers/staging/netlogic/xlr_net.h b/drivers/staging/netlogic/xlr_net.h new file mode 100644 index 000000000000..f91d27e9d7c4 --- /dev/null +++ b/drivers/staging/netlogic/xlr_net.h @@ -0,0 +1,1099 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * 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, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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. + */ +/* #define MAC_SPLIT_MODE */ + +#define MAC_SPACING 0x400 +#define XGMAC_SPACING 0x400 + +/* PE-MCXMAC register and bit field definitions */ +#define R_MAC_CONFIG_1 0x00 +#define O_MAC_CONFIG_1__srst 31 +#define O_MAC_CONFIG_1__simr 30 +#define O_MAC_CONFIG_1__hrrmc 18 +#define W_MAC_CONFIG_1__hrtmc 2 +#define O_MAC_CONFIG_1__hrrfn 16 +#define W_MAC_CONFIG_1__hrtfn 2 +#define O_MAC_CONFIG_1__intlb 8 +#define O_MAC_CONFIG_1__rxfc 5 +#define O_MAC_CONFIG_1__txfc 4 +#define O_MAC_CONFIG_1__srxen 3 +#define O_MAC_CONFIG_1__rxen 2 +#define O_MAC_CONFIG_1__stxen 1 +#define O_MAC_CONFIG_1__txen 0 +#define R_MAC_CONFIG_2 0x01 +#define O_MAC_CONFIG_2__prlen 12 +#define W_MAC_CONFIG_2__prlen 4 +#define O_MAC_CONFIG_2__speed 8 +#define W_MAC_CONFIG_2__speed 2 +#define O_MAC_CONFIG_2__hugen 5 +#define O_MAC_CONFIG_2__flchk 4 +#define O_MAC_CONFIG_2__crce 1 +#define O_MAC_CONFIG_2__fulld 0 +#define R_IPG_IFG 0x02 +#define O_IPG_IFG__ipgr1 24 +#define W_IPG_IFG__ipgr1 7 +#define O_IPG_IFG__ipgr2 16 +#define W_IPG_IFG__ipgr2 7 +#define O_IPG_IFG__mifg 8 +#define W_IPG_IFG__mifg 8 +#define O_IPG_IFG__ipgt 0 +#define W_IPG_IFG__ipgt 7 +#define R_HALF_DUPLEX 0x03 +#define O_HALF_DUPLEX__abebt 24 +#define W_HALF_DUPLEX__abebt 4 +#define O_HALF_DUPLEX__abebe 19 +#define O_HALF_DUPLEX__bpnb 18 +#define O_HALF_DUPLEX__nobo 17 +#define O_HALF_DUPLEX__edxsdfr 16 +#define O_HALF_DUPLEX__retry 12 +#define W_HALF_DUPLEX__retry 4 +#define O_HALF_DUPLEX__lcol 0 +#define W_HALF_DUPLEX__lcol 10 +#define R_MAXIMUM_FRAME_LENGTH 0x04 +#define O_MAXIMUM_FRAME_LENGTH__maxf 0 +#define W_MAXIMUM_FRAME_LENGTH__maxf 16 +#define R_TEST 0x07 +#define O_TEST__mbof 3 +#define O_TEST__rthdf 2 +#define O_TEST__tpause 1 +#define O_TEST__sstct 0 +#define R_MII_MGMT_CONFIG 0x08 +#define O_MII_MGMT_CONFIG__scinc 5 +#define O_MII_MGMT_CONFIG__spre 4 +#define O_MII_MGMT_CONFIG__clks 3 +#define W_MII_MGMT_CONFIG__clks 3 +#define R_MII_MGMT_COMMAND 0x09 +#define O_MII_MGMT_COMMAND__scan 1 +#define O_MII_MGMT_COMMAND__rstat 0 +#define R_MII_MGMT_ADDRESS 0x0A +#define O_MII_MGMT_ADDRESS__fiad 8 +#define W_MII_MGMT_ADDRESS__fiad 5 +#define O_MII_MGMT_ADDRESS__fgad 5 +#define W_MII_MGMT_ADDRESS__fgad 0 +#define R_MII_MGMT_WRITE_DATA 0x0B +#define O_MII_MGMT_WRITE_DATA__ctld 0 +#define W_MII_MGMT_WRITE_DATA__ctld 16 +#define R_MII_MGMT_STATUS 0x0C +#define R_MII_MGMT_INDICATORS 0x0D +#define O_MII_MGMT_INDICATORS__nvalid 2 +#define O_MII_MGMT_INDICATORS__scan 1 +#define O_MII_MGMT_INDICATORS__busy 0 +#define R_INTERFACE_CONTROL 0x0E +#define O_INTERFACE_CONTROL__hrstint 31 +#define O_INTERFACE_CONTROL__tbimode 27 +#define O_INTERFACE_CONTROL__ghdmode 26 +#define O_INTERFACE_CONTROL__lhdmode 25 +#define O_INTERFACE_CONTROL__phymod 24 +#define O_INTERFACE_CONTROL__hrrmi 23 +#define O_INTERFACE_CONTROL__rspd 16 +#define O_INTERFACE_CONTROL__hr100 15 +#define O_INTERFACE_CONTROL__frcq 10 +#define O_INTERFACE_CONTROL__nocfr 9 +#define O_INTERFACE_CONTROL__dlfct 8 +#define O_INTERFACE_CONTROL__enjab 0 +#define R_INTERFACE_STATUS 0x0F +#define O_INTERFACE_STATUS__xsdfr 9 +#define O_INTERFACE_STATUS__ssrr 8 +#define W_INTERFACE_STATUS__ssrr 5 +#define O_INTERFACE_STATUS__miilf 3 +#define O_INTERFACE_STATUS__locar 2 +#define O_INTERFACE_STATUS__sqerr 1 +#define O_INTERFACE_STATUS__jabber 0 +#define R_STATION_ADDRESS_LS 0x10 +#define R_STATION_ADDRESS_MS 0x11 + +/* A-XGMAC register and bit field definitions */ +#define R_XGMAC_CONFIG_0 0x00 +#define O_XGMAC_CONFIG_0__hstmacrst 31 +#define O_XGMAC_CONFIG_0__hstrstrctl 23 +#define O_XGMAC_CONFIG_0__hstrstrfn 22 +#define O_XGMAC_CONFIG_0__hstrsttctl 18 +#define O_XGMAC_CONFIG_0__hstrsttfn 17 +#define O_XGMAC_CONFIG_0__hstrstmiim 16 +#define O_XGMAC_CONFIG_0__hstloopback 8 +#define R_XGMAC_CONFIG_1 0x01 +#define O_XGMAC_CONFIG_1__hsttctlen 31 +#define O_XGMAC_CONFIG_1__hsttfen 30 +#define O_XGMAC_CONFIG_1__hstrctlen 29 +#define O_XGMAC_CONFIG_1__hstrfen 28 +#define O_XGMAC_CONFIG_1__tfen 26 +#define O_XGMAC_CONFIG_1__rfen 24 +#define O_XGMAC_CONFIG_1__hstrctlshrtp 12 +#define O_XGMAC_CONFIG_1__hstdlyfcstx 10 +#define W_XGMAC_CONFIG_1__hstdlyfcstx 2 +#define O_XGMAC_CONFIG_1__hstdlyfcsrx 8 +#define W_XGMAC_CONFIG_1__hstdlyfcsrx 2 +#define O_XGMAC_CONFIG_1__hstppen 7 +#define O_XGMAC_CONFIG_1__hstbytswp 6 +#define O_XGMAC_CONFIG_1__hstdrplt64 5 +#define O_XGMAC_CONFIG_1__hstprmscrx 4 +#define O_XGMAC_CONFIG_1__hstlenchk 3 +#define O_XGMAC_CONFIG_1__hstgenfcs 2 +#define O_XGMAC_CONFIG_1__hstpadmode 0 +#define W_XGMAC_CONFIG_1__hstpadmode 2 +#define R_XGMAC_CONFIG_2 0x02 +#define O_XGMAC_CONFIG_2__hsttctlfrcp 31 +#define O_XGMAC_CONFIG_2__hstmlnkflth 27 +#define O_XGMAC_CONFIG_2__hstalnkflth 26 +#define O_XGMAC_CONFIG_2__rflnkflt 24 +#define W_XGMAC_CONFIG_2__rflnkflt 2 +#define O_XGMAC_CONFIG_2__hstipgextmod 16 +#define W_XGMAC_CONFIG_2__hstipgextmod 5 +#define O_XGMAC_CONFIG_2__hstrctlfrcp 15 +#define O_XGMAC_CONFIG_2__hstipgexten 5 +#define O_XGMAC_CONFIG_2__hstmipgext 0 +#define W_XGMAC_CONFIG_2__hstmipgext 5 +#define R_XGMAC_CONFIG_3 0x03 +#define O_XGMAC_CONFIG_3__hstfltrfrm 31 +#define W_XGMAC_CONFIG_3__hstfltrfrm 16 +#define O_XGMAC_CONFIG_3__hstfltrfrmdc 15 +#define W_XGMAC_CONFIG_3__hstfltrfrmdc 16 +#define R_XGMAC_STATION_ADDRESS_LS 0x04 +#define O_XGMAC_STATION_ADDRESS_LS__hstmacadr0 0 +#define W_XGMAC_STATION_ADDRESS_LS__hstmacadr0 32 +#define R_XGMAC_STATION_ADDRESS_MS 0x05 +#define R_XGMAC_MAX_FRAME_LEN 0x08 +#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 16 +#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 14 +#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 0 +#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 16 +#define R_XGMAC_REV_LEVEL 0x0B +#define O_XGMAC_REV_LEVEL__revlvl 0 +#define W_XGMAC_REV_LEVEL__revlvl 15 +#define R_XGMAC_MIIM_COMMAND 0x10 +#define O_XGMAC_MIIM_COMMAND__hstldcmd 3 +#define O_XGMAC_MIIM_COMMAND__hstmiimcmd 0 +#define W_XGMAC_MIIM_COMMAND__hstmiimcmd 3 +#define R_XGMAC_MIIM_FILED 0x11 +#define O_XGMAC_MIIM_FILED__hststfield 30 +#define W_XGMAC_MIIM_FILED__hststfield 2 +#define O_XGMAC_MIIM_FILED__hstopfield 28 +#define W_XGMAC_MIIM_FILED__hstopfield 2 +#define O_XGMAC_MIIM_FILED__hstphyadx 23 +#define W_XGMAC_MIIM_FILED__hstphyadx 5 +#define O_XGMAC_MIIM_FILED__hstregadx 18 +#define W_XGMAC_MIIM_FILED__hstregadx 5 +#define O_XGMAC_MIIM_FILED__hsttafield 16 +#define W_XGMAC_MIIM_FILED__hsttafield 2 +#define O_XGMAC_MIIM_FILED__miimrddat 0 +#define W_XGMAC_MIIM_FILED__miimrddat 16 +#define R_XGMAC_MIIM_CONFIG 0x12 +#define O_XGMAC_MIIM_CONFIG__hstnopram 7 +#define O_XGMAC_MIIM_CONFIG__hstclkdiv 0 +#define W_XGMAC_MIIM_CONFIG__hstclkdiv 7 +#define R_XGMAC_MIIM_LINK_FAIL_VECTOR 0x13 +#define O_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 0 +#define W_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 32 +#define R_XGMAC_MIIM_INDICATOR 0x14 +#define O_XGMAC_MIIM_INDICATOR__miimphylf 4 +#define O_XGMAC_MIIM_INDICATOR__miimmoncplt 3 +#define O_XGMAC_MIIM_INDICATOR__miimmonvld 2 +#define O_XGMAC_MIIM_INDICATOR__miimmon 1 +#define O_XGMAC_MIIM_INDICATOR__miimbusy 0 + +/* GMAC stats registers */ +#define R_RBYT 0x27 +#define R_RPKT 0x28 +#define R_RFCS 0x29 +#define R_RMCA 0x2A +#define R_RBCA 0x2B +#define R_RXCF 0x2C +#define R_RXPF 0x2D +#define R_RXUO 0x2E +#define R_RALN 0x2F +#define R_RFLR 0x30 +#define R_RCDE 0x31 +#define R_RCSE 0x32 +#define R_RUND 0x33 +#define R_ROVR 0x34 +#define R_TBYT 0x38 +#define R_TPKT 0x39 +#define R_TMCA 0x3A +#define R_TBCA 0x3B +#define R_TXPF 0x3C +#define R_TDFR 0x3D +#define R_TEDF 0x3E +#define R_TSCL 0x3F +#define R_TMCL 0x40 +#define R_TLCL 0x41 +#define R_TXCL 0x42 +#define R_TNCL 0x43 +#define R_TJBR 0x46 +#define R_TFCS 0x47 +#define R_TXCF 0x48 +#define R_TOVR 0x49 +#define R_TUND 0x4A +#define R_TFRG 0x4B + +/* Glue logic register and bit field definitions */ +#define R_MAC_ADDR0 0x50 +#define R_MAC_ADDR1 0x52 +#define R_MAC_ADDR2 0x54 +#define R_MAC_ADDR3 0x56 +#define R_MAC_ADDR_MASK2 0x58 +#define R_MAC_ADDR_MASK3 0x5A +#define R_MAC_FILTER_CONFIG 0x5C +#define O_MAC_FILTER_CONFIG__BROADCAST_EN 10 +#define O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN 9 +#define O_MAC_FILTER_CONFIG__ALL_MCAST_EN 8 +#define O_MAC_FILTER_CONFIG__ALL_UCAST_EN 7 +#define O_MAC_FILTER_CONFIG__HASH_MCAST_EN 6 +#define O_MAC_FILTER_CONFIG__HASH_UCAST_EN 5 +#define O_MAC_FILTER_CONFIG__ADDR_MATCH_DISC 4 +#define O_MAC_FILTER_CONFIG__MAC_ADDR3_VALID 3 +#define O_MAC_FILTER_CONFIG__MAC_ADDR2_VALID 2 +#define O_MAC_FILTER_CONFIG__MAC_ADDR1_VALID 1 +#define O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID 0 +#define R_HASH_TABLE_VECTOR 0x30 +#define R_TX_CONTROL 0x0A0 +#define O_TX_CONTROL__Tx15Halt 31 +#define O_TX_CONTROL__Tx14Halt 30 +#define O_TX_CONTROL__Tx13Halt 29 +#define O_TX_CONTROL__Tx12Halt 28 +#define O_TX_CONTROL__Tx11Halt 27 +#define O_TX_CONTROL__Tx10Halt 26 +#define O_TX_CONTROL__Tx9Halt 25 +#define O_TX_CONTROL__Tx8Halt 24 +#define O_TX_CONTROL__Tx7Halt 23 +#define O_TX_CONTROL__Tx6Halt 22 +#define O_TX_CONTROL__Tx5Halt 21 +#define O_TX_CONTROL__Tx4Halt 20 +#define O_TX_CONTROL__Tx3Halt 19 +#define O_TX_CONTROL__Tx2Halt 18 +#define O_TX_CONTROL__Tx1Halt 17 +#define O_TX_CONTROL__Tx0Halt 16 +#define O_TX_CONTROL__TxIdle 15 +#define O_TX_CONTROL__TxEnable 14 +#define O_TX_CONTROL__TxThreshold 0 +#define W_TX_CONTROL__TxThreshold 14 +#define R_RX_CONTROL 0x0A1 +#define O_RX_CONTROL__RGMII 10 +#define O_RX_CONTROL__SoftReset 2 +#define O_RX_CONTROL__RxHalt 1 +#define O_RX_CONTROL__RxEnable 0 +#define R_DESC_PACK_CTRL 0x0A2 +#define O_DESC_PACK_CTRL__ByteOffset 17 +#define W_DESC_PACK_CTRL__ByteOffset 3 +#define O_DESC_PACK_CTRL__PrePadEnable 16 +#define O_DESC_PACK_CTRL__MaxEntry 14 +#define W_DESC_PACK_CTRL__MaxEntry 2 +#define O_DESC_PACK_CTRL__RegularSize 0 +#define W_DESC_PACK_CTRL__RegularSize 14 +#define R_STATCTRL 0x0A3 +#define O_STATCTRL__OverFlowEn 4 +#define O_STATCTRL__GIG 3 +#define O_STATCTRL__Sten 2 +#define O_STATCTRL__ClrCnt 1 +#define O_STATCTRL__AutoZ 0 +#define R_L2ALLOCCTRL 0x0A4 +#define O_L2ALLOCCTRL__TxL2Allocate 9 +#define W_L2ALLOCCTRL__TxL2Allocate 9 +#define O_L2ALLOCCTRL__RxL2Allocate 0 +#define W_L2ALLOCCTRL__RxL2Allocate 9 +#define R_INTMASK 0x0A5 +#define O_INTMASK__Spi4TxError 28 +#define O_INTMASK__Spi4RxError 27 +#define O_INTMASK__RGMIIHalfDupCollision 27 +#define O_INTMASK__Abort 26 +#define O_INTMASK__Underrun 25 +#define O_INTMASK__DiscardPacket 24 +#define O_INTMASK__AsyncFifoFull 23 +#define O_INTMASK__TagFull 22 +#define O_INTMASK__Class3Full 21 +#define O_INTMASK__C3EarlyFull 20 +#define O_INTMASK__Class2Full 19 +#define O_INTMASK__C2EarlyFull 18 +#define O_INTMASK__Class1Full 17 +#define O_INTMASK__C1EarlyFull 16 +#define O_INTMASK__Class0Full 15 +#define O_INTMASK__C0EarlyFull 14 +#define O_INTMASK__RxDataFull 13 +#define O_INTMASK__RxEarlyFull 12 +#define O_INTMASK__RFreeEmpty 9 +#define O_INTMASK__RFEarlyEmpty 8 +#define O_INTMASK__P2PSpillEcc 7 +#define O_INTMASK__FreeDescFull 5 +#define O_INTMASK__FreeEarlyFull 4 +#define O_INTMASK__TxFetchError 3 +#define O_INTMASK__StatCarry 2 +#define O_INTMASK__MDInt 1 +#define O_INTMASK__TxIllegal 0 +#define R_INTREG 0x0A6 +#define O_INTREG__Spi4TxError 28 +#define O_INTREG__Spi4RxError 27 +#define O_INTREG__RGMIIHalfDupCollision 27 +#define O_INTREG__Abort 26 +#define O_INTREG__Underrun 25 +#define O_INTREG__DiscardPacket 24 +#define O_INTREG__AsyncFifoFull 23 +#define O_INTREG__TagFull 22 +#define O_INTREG__Class3Full 21 +#define O_INTREG__C3EarlyFull 20 +#define O_INTREG__Class2Full 19 +#define O_INTREG__C2EarlyFull 18 +#define O_INTREG__Class1Full 17 +#define O_INTREG__C1EarlyFull 16 +#define O_INTREG__Class0Full 15 +#define O_INTREG__C0EarlyFull 14 +#define O_INTREG__RxDataFull 13 +#define O_INTREG__RxEarlyFull 12 +#define O_INTREG__RFreeEmpty 9 +#define O_INTREG__RFEarlyEmpty 8 +#define O_INTREG__P2PSpillEcc 7 +#define O_INTREG__FreeDescFull 5 +#define O_INTREG__FreeEarlyFull 4 +#define O_INTREG__TxFetchError 3 +#define O_INTREG__StatCarry 2 +#define O_INTREG__MDInt 1 +#define O_INTREG__TxIllegal 0 +#define R_TXRETRY 0x0A7 +#define O_TXRETRY__CollisionRetry 6 +#define O_TXRETRY__BusErrorRetry 5 +#define O_TXRETRY__UnderRunRetry 4 +#define O_TXRETRY__Retries 0 +#define W_TXRETRY__Retries 4 +#define R_CORECONTROL 0x0A8 +#define O_CORECONTROL__ErrorThread 4 +#define W_CORECONTROL__ErrorThread 7 +#define O_CORECONTROL__Shutdown 2 +#define O_CORECONTROL__Speed 0 +#define W_CORECONTROL__Speed 2 +#define R_BYTEOFFSET0 0x0A9 +#define R_BYTEOFFSET1 0x0AA +#define R_L2TYPE_0 0x0F0 +#define O_L2TYPE__ExtraHdrProtoSize 26 +#define W_L2TYPE__ExtraHdrProtoSize 5 +#define O_L2TYPE__ExtraHdrProtoOffset 20 +#define W_L2TYPE__ExtraHdrProtoOffset 6 +#define O_L2TYPE__ExtraHeaderSize 14 +#define W_L2TYPE__ExtraHeaderSize 6 +#define O_L2TYPE__ProtoOffset 8 +#define W_L2TYPE__ProtoOffset 6 +#define O_L2TYPE__L2HdrOffset 2 +#define W_L2TYPE__L2HdrOffset 6 +#define O_L2TYPE__L2Proto 0 +#define W_L2TYPE__L2Proto 2 +#define R_L2TYPE_1 0xF0 +#define R_L2TYPE_2 0xF0 +#define R_L2TYPE_3 0xF0 +#define R_PARSERCONFIGREG 0x100 +#define O_PARSERCONFIGREG__CRCHashPoly 8 +#define W_PARSERCONFIGREG__CRCHashPoly 7 +#define O_PARSERCONFIGREG__PrePadOffset 4 +#define W_PARSERCONFIGREG__PrePadOffset 4 +#define O_PARSERCONFIGREG__UseCAM 2 +#define O_PARSERCONFIGREG__UseHASH 1 +#define O_PARSERCONFIGREG__UseProto 0 +#define R_L3CTABLE 0x140 +#define O_L3CTABLE__Offset0 25 +#define W_L3CTABLE__Offset0 7 +#define O_L3CTABLE__Len0 21 +#define W_L3CTABLE__Len0 4 +#define O_L3CTABLE__Offset1 14 +#define W_L3CTABLE__Offset1 7 +#define O_L3CTABLE__Len1 10 +#define W_L3CTABLE__Len1 4 +#define O_L3CTABLE__Offset2 4 +#define W_L3CTABLE__Offset2 6 +#define O_L3CTABLE__Len2 0 +#define W_L3CTABLE__Len2 4 +#define O_L3CTABLE__L3HdrOffset 26 +#define W_L3CTABLE__L3HdrOffset 6 +#define O_L3CTABLE__L4ProtoOffset 20 +#define W_L3CTABLE__L4ProtoOffset 6 +#define O_L3CTABLE__IPChksumCompute 19 +#define O_L3CTABLE__L4Classify 18 +#define O_L3CTABLE__L2Proto 16 +#define W_L3CTABLE__L2Proto 2 +#define O_L3CTABLE__L3ProtoKey 0 +#define W_L3CTABLE__L3ProtoKey 16 +#define R_L4CTABLE 0x160 +#define O_L4CTABLE__Offset0 21 +#define W_L4CTABLE__Offset0 6 +#define O_L4CTABLE__Len0 17 +#define W_L4CTABLE__Len0 4 +#define O_L4CTABLE__Offset1 11 +#define W_L4CTABLE__Offset1 6 +#define O_L4CTABLE__Len1 7 +#define W_L4CTABLE__Len1 4 +#define O_L4CTABLE__TCPChksumEnable 0 +#define R_CAM4X128TABLE 0x172 +#define O_CAM4X128TABLE__ClassId 7 +#define W_CAM4X128TABLE__ClassId 2 +#define O_CAM4X128TABLE__BucketId 1 +#define W_CAM4X128TABLE__BucketId 6 +#define O_CAM4X128TABLE__UseBucket 0 +#define R_CAM4X128KEY 0x180 +#define R_TRANSLATETABLE 0x1A0 +#define R_DMACR0 0x200 +#define O_DMACR0__Data0WrMaxCr 27 +#define W_DMACR0__Data0WrMaxCr 3 +#define O_DMACR0__Data0RdMaxCr 24 +#define W_DMACR0__Data0RdMaxCr 3 +#define O_DMACR0__Data1WrMaxCr 21 +#define W_DMACR0__Data1WrMaxCr 3 +#define O_DMACR0__Data1RdMaxCr 18 +#define W_DMACR0__Data1RdMaxCr 3 +#define O_DMACR0__Data2WrMaxCr 15 +#define W_DMACR0__Data2WrMaxCr 3 +#define O_DMACR0__Data2RdMaxCr 12 +#define W_DMACR0__Data2RdMaxCr 3 +#define O_DMACR0__Data3WrMaxCr 9 +#define W_DMACR0__Data3WrMaxCr 3 +#define O_DMACR0__Data3RdMaxCr 6 +#define W_DMACR0__Data3RdMaxCr 3 +#define O_DMACR0__Data4WrMaxCr 3 +#define W_DMACR0__Data4WrMaxCr 3 +#define O_DMACR0__Data4RdMaxCr 0 +#define W_DMACR0__Data4RdMaxCr 3 +#define R_DMACR1 0x201 +#define O_DMACR1__Data5WrMaxCr 27 +#define W_DMACR1__Data5WrMaxCr 3 +#define O_DMACR1__Data5RdMaxCr 24 +#define W_DMACR1__Data5RdMaxCr 3 +#define O_DMACR1__Data6WrMaxCr 21 +#define W_DMACR1__Data6WrMaxCr 3 +#define O_DMACR1__Data6RdMaxCr 18 +#define W_DMACR1__Data6RdMaxCr 3 +#define O_DMACR1__Data7WrMaxCr 15 +#define W_DMACR1__Data7WrMaxCr 3 +#define O_DMACR1__Data7RdMaxCr 12 +#define W_DMACR1__Data7RdMaxCr 3 +#define O_DMACR1__Data8WrMaxCr 9 +#define W_DMACR1__Data8WrMaxCr 3 +#define O_DMACR1__Data8RdMaxCr 6 +#define W_DMACR1__Data8RdMaxCr 3 +#define O_DMACR1__Data9WrMaxCr 3 +#define W_DMACR1__Data9WrMaxCr 3 +#define O_DMACR1__Data9RdMaxCr 0 +#define W_DMACR1__Data9RdMaxCr 3 +#define R_DMACR2 0x202 +#define O_DMACR2__Data10WrMaxCr 27 +#define W_DMACR2__Data10WrMaxCr 3 +#define O_DMACR2__Data10RdMaxCr 24 +#define W_DMACR2__Data10RdMaxCr 3 +#define O_DMACR2__Data11WrMaxCr 21 +#define W_DMACR2__Data11WrMaxCr 3 +#define O_DMACR2__Data11RdMaxCr 18 +#define W_DMACR2__Data11RdMaxCr 3 +#define O_DMACR2__Data12WrMaxCr 15 +#define W_DMACR2__Data12WrMaxCr 3 +#define O_DMACR2__Data12RdMaxCr 12 +#define W_DMACR2__Data12RdMaxCr 3 +#define O_DMACR2__Data13WrMaxCr 9 +#define W_DMACR2__Data13WrMaxCr 3 +#define O_DMACR2__Data13RdMaxCr 6 +#define W_DMACR2__Data13RdMaxCr 3 +#define O_DMACR2__Data14WrMaxCr 3 +#define W_DMACR2__Data14WrMaxCr 3 +#define O_DMACR2__Data14RdMaxCr 0 +#define W_DMACR2__Data14RdMaxCr 3 +#define R_DMACR3 0x203 +#define O_DMACR3__Data15WrMaxCr 27 +#define W_DMACR3__Data15WrMaxCr 3 +#define O_DMACR3__Data15RdMaxCr 24 +#define W_DMACR3__Data15RdMaxCr 3 +#define O_DMACR3__SpClassWrMaxCr 21 +#define W_DMACR3__SpClassWrMaxCr 3 +#define O_DMACR3__SpClassRdMaxCr 18 +#define W_DMACR3__SpClassRdMaxCr 3 +#define O_DMACR3__JumFrInWrMaxCr 15 +#define W_DMACR3__JumFrInWrMaxCr 3 +#define O_DMACR3__JumFrInRdMaxCr 12 +#define W_DMACR3__JumFrInRdMaxCr 3 +#define O_DMACR3__RegFrInWrMaxCr 9 +#define W_DMACR3__RegFrInWrMaxCr 3 +#define O_DMACR3__RegFrInRdMaxCr 6 +#define W_DMACR3__RegFrInRdMaxCr 3 +#define O_DMACR3__FrOutWrMaxCr 3 +#define W_DMACR3__FrOutWrMaxCr 3 +#define O_DMACR3__FrOutRdMaxCr 0 +#define W_DMACR3__FrOutRdMaxCr 3 +#define R_REG_FRIN_SPILL_MEM_START_0 0x204 +#define O_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 0 +#define W_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 32 +#define R_REG_FRIN_SPILL_MEM_START_1 0x205 +#define O_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 0 +#define W_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 3 +#define R_REG_FRIN_SPILL_MEM_SIZE 0x206 +#define O_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 0 +#define W_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 32 +#define R_FROUT_SPILL_MEM_START_0 0x207 +#define O_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 0 +#define W_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 32 +#define R_FROUT_SPILL_MEM_START_1 0x208 +#define O_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 0 +#define W_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 3 +#define R_FROUT_SPILL_MEM_SIZE 0x209 +#define O_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 0 +#define W_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 32 +#define R_CLASS0_SPILL_MEM_START_0 0x20A +#define O_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 0 +#define W_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 32 +#define R_CLASS0_SPILL_MEM_START_1 0x20B +#define O_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 0 +#define W_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 3 +#define R_CLASS0_SPILL_MEM_SIZE 0x20C +#define O_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 0 +#define W_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 32 +#define R_JUMFRIN_SPILL_MEM_START_0 0x20D +#define O_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 0 +#define W_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 32 +#define R_JUMFRIN_SPILL_MEM_START_1 0x20E +#define O_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 0 +#define W_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 3 +#define R_JUMFRIN_SPILL_MEM_SIZE 0x20F +#define O_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 0 +#define W_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 32 +#define R_CLASS1_SPILL_MEM_START_0 0x210 +#define O_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 0 +#define W_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 32 +#define R_CLASS1_SPILL_MEM_START_1 0x211 +#define O_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 0 +#define W_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 3 +#define R_CLASS1_SPILL_MEM_SIZE 0x212 +#define O_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 0 +#define W_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 32 +#define R_CLASS2_SPILL_MEM_START_0 0x213 +#define O_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 0 +#define W_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 32 +#define R_CLASS2_SPILL_MEM_START_1 0x214 +#define O_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 0 +#define W_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 3 +#define R_CLASS2_SPILL_MEM_SIZE 0x215 +#define O_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 0 +#define W_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 32 +#define R_CLASS3_SPILL_MEM_START_0 0x216 +#define O_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 0 +#define W_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 32 +#define R_CLASS3_SPILL_MEM_START_1 0x217 +#define O_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 0 +#define W_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 3 +#define R_CLASS3_SPILL_MEM_SIZE 0x218 +#define O_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 0 +#define W_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 32 +#define R_REG_FRIN1_SPILL_MEM_START_0 0x219 +#define R_REG_FRIN1_SPILL_MEM_START_1 0x21a +#define R_REG_FRIN1_SPILL_MEM_SIZE 0x21b +#define R_SPIHNGY0 0x219 +#define O_SPIHNGY0__EG_HNGY_THRESH_0 24 +#define W_SPIHNGY0__EG_HNGY_THRESH_0 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_1 16 +#define W_SPIHNGY0__EG_HNGY_THRESH_1 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_2 8 +#define W_SPIHNGY0__EG_HNGY_THRESH_2 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_3 0 +#define W_SPIHNGY0__EG_HNGY_THRESH_3 7 +#define R_SPIHNGY1 0x21A +#define O_SPIHNGY1__EG_HNGY_THRESH_4 24 +#define W_SPIHNGY1__EG_HNGY_THRESH_4 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_5 16 +#define W_SPIHNGY1__EG_HNGY_THRESH_5 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_6 8 +#define W_SPIHNGY1__EG_HNGY_THRESH_6 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_7 0 +#define W_SPIHNGY1__EG_HNGY_THRESH_7 7 +#define R_SPIHNGY2 0x21B +#define O_SPIHNGY2__EG_HNGY_THRESH_8 24 +#define W_SPIHNGY2__EG_HNGY_THRESH_8 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_9 16 +#define W_SPIHNGY2__EG_HNGY_THRESH_9 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_10 8 +#define W_SPIHNGY2__EG_HNGY_THRESH_10 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_11 0 +#define W_SPIHNGY2__EG_HNGY_THRESH_11 7 +#define R_SPIHNGY3 0x21C +#define O_SPIHNGY3__EG_HNGY_THRESH_12 24 +#define W_SPIHNGY3__EG_HNGY_THRESH_12 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_13 16 +#define W_SPIHNGY3__EG_HNGY_THRESH_13 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_14 8 +#define W_SPIHNGY3__EG_HNGY_THRESH_14 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_15 0 +#define W_SPIHNGY3__EG_HNGY_THRESH_15 7 +#define R_SPISTRV0 0x21D +#define O_SPISTRV0__EG_STRV_THRESH_0 24 +#define W_SPISTRV0__EG_STRV_THRESH_0 7 +#define O_SPISTRV0__EG_STRV_THRESH_1 16 +#define W_SPISTRV0__EG_STRV_THRESH_1 7 +#define O_SPISTRV0__EG_STRV_THRESH_2 8 +#define W_SPISTRV0__EG_STRV_THRESH_2 7 +#define O_SPISTRV0__EG_STRV_THRESH_3 0 +#define W_SPISTRV0__EG_STRV_THRESH_3 7 +#define R_SPISTRV1 0x21E +#define O_SPISTRV1__EG_STRV_THRESH_4 24 +#define W_SPISTRV1__EG_STRV_THRESH_4 7 +#define O_SPISTRV1__EG_STRV_THRESH_5 16 +#define W_SPISTRV1__EG_STRV_THRESH_5 7 +#define O_SPISTRV1__EG_STRV_THRESH_6 8 +#define W_SPISTRV1__EG_STRV_THRESH_6 7 +#define O_SPISTRV1__EG_STRV_THRESH_7 0 +#define W_SPISTRV1__EG_STRV_THRESH_7 7 +#define R_SPISTRV2 0x21F +#define O_SPISTRV2__EG_STRV_THRESH_8 24 +#define W_SPISTRV2__EG_STRV_THRESH_8 7 +#define O_SPISTRV2__EG_STRV_THRESH_9 16 +#define W_SPISTRV2__EG_STRV_THRESH_9 7 +#define O_SPISTRV2__EG_STRV_THRESH_10 8 +#define W_SPISTRV2__EG_STRV_THRESH_10 7 +#define O_SPISTRV2__EG_STRV_THRESH_11 0 +#define W_SPISTRV2__EG_STRV_THRESH_11 7 +#define R_SPISTRV3 0x220 +#define O_SPISTRV3__EG_STRV_THRESH_12 24 +#define W_SPISTRV3__EG_STRV_THRESH_12 7 +#define O_SPISTRV3__EG_STRV_THRESH_13 16 +#define W_SPISTRV3__EG_STRV_THRESH_13 7 +#define O_SPISTRV3__EG_STRV_THRESH_14 8 +#define W_SPISTRV3__EG_STRV_THRESH_14 7 +#define O_SPISTRV3__EG_STRV_THRESH_15 0 +#define W_SPISTRV3__EG_STRV_THRESH_15 7 +#define R_TXDATAFIFO0 0x221 +#define O_TXDATAFIFO0__Tx0DataFifoStart 24 +#define W_TXDATAFIFO0__Tx0DataFifoStart 7 +#define O_TXDATAFIFO0__Tx0DataFifoSize 16 +#define W_TXDATAFIFO0__Tx0DataFifoSize 7 +#define O_TXDATAFIFO0__Tx1DataFifoStart 8 +#define W_TXDATAFIFO0__Tx1DataFifoStart 7 +#define O_TXDATAFIFO0__Tx1DataFifoSize 0 +#define W_TXDATAFIFO0__Tx1DataFifoSize 7 +#define R_TXDATAFIFO1 0x222 +#define O_TXDATAFIFO1__Tx2DataFifoStart 24 +#define W_TXDATAFIFO1__Tx2DataFifoStart 7 +#define O_TXDATAFIFO1__Tx2DataFifoSize 16 +#define W_TXDATAFIFO1__Tx2DataFifoSize 7 +#define O_TXDATAFIFO1__Tx3DataFifoStart 8 +#define W_TXDATAFIFO1__Tx3DataFifoStart 7 +#define O_TXDATAFIFO1__Tx3DataFifoSize 0 +#define W_TXDATAFIFO1__Tx3DataFifoSize 7 +#define R_TXDATAFIFO2 0x223 +#define O_TXDATAFIFO2__Tx4DataFifoStart 24 +#define W_TXDATAFIFO2__Tx4DataFifoStart 7 +#define O_TXDATAFIFO2__Tx4DataFifoSize 16 +#define W_TXDATAFIFO2__Tx4DataFifoSize 7 +#define O_TXDATAFIFO2__Tx5DataFifoStart 8 +#define W_TXDATAFIFO2__Tx5DataFifoStart 7 +#define O_TXDATAFIFO2__Tx5DataFifoSize 0 +#define W_TXDATAFIFO2__Tx5DataFifoSize 7 +#define R_TXDATAFIFO3 0x224 +#define O_TXDATAFIFO3__Tx6DataFifoStart 24 +#define W_TXDATAFIFO3__Tx6DataFifoStart 7 +#define O_TXDATAFIFO3__Tx6DataFifoSize 16 +#define W_TXDATAFIFO3__Tx6DataFifoSize 7 +#define O_TXDATAFIFO3__Tx7DataFifoStart 8 +#define W_TXDATAFIFO3__Tx7DataFifoStart 7 +#define O_TXDATAFIFO3__Tx7DataFifoSize 0 +#define W_TXDATAFIFO3__Tx7DataFifoSize 7 +#define R_TXDATAFIFO4 0x225 +#define O_TXDATAFIFO4__Tx8DataFifoStart 24 +#define W_TXDATAFIFO4__Tx8DataFifoStart 7 +#define O_TXDATAFIFO4__Tx8DataFifoSize 16 +#define W_TXDATAFIFO4__Tx8DataFifoSize 7 +#define O_TXDATAFIFO4__Tx9DataFifoStart 8 +#define W_TXDATAFIFO4__Tx9DataFifoStart 7 +#define O_TXDATAFIFO4__Tx9DataFifoSize 0 +#define W_TXDATAFIFO4__Tx9DataFifoSize 7 +#define R_TXDATAFIFO5 0x226 +#define O_TXDATAFIFO5__Tx10DataFifoStart 24 +#define W_TXDATAFIFO5__Tx10DataFifoStart 7 +#define O_TXDATAFIFO5__Tx10DataFifoSize 16 +#define W_TXDATAFIFO5__Tx10DataFifoSize 7 +#define O_TXDATAFIFO5__Tx11DataFifoStart 8 +#define W_TXDATAFIFO5__Tx11DataFifoStart 7 +#define O_TXDATAFIFO5__Tx11DataFifoSize 0 +#define W_TXDATAFIFO5__Tx11DataFifoSize 7 +#define R_TXDATAFIFO6 0x227 +#define O_TXDATAFIFO6__Tx12DataFifoStart 24 +#define W_TXDATAFIFO6__Tx12DataFifoStart 7 +#define O_TXDATAFIFO6__Tx12DataFifoSize 16 +#define W_TXDATAFIFO6__Tx12DataFifoSize 7 +#define O_TXDATAFIFO6__Tx13DataFifoStart 8 +#define W_TXDATAFIFO6__Tx13DataFifoStart 7 +#define O_TXDATAFIFO6__Tx13DataFifoSize 0 +#define W_TXDATAFIFO6__Tx13DataFifoSize 7 +#define R_TXDATAFIFO7 0x228 +#define O_TXDATAFIFO7__Tx14DataFifoStart 24 +#define W_TXDATAFIFO7__Tx14DataFifoStart 7 +#define O_TXDATAFIFO7__Tx14DataFifoSize 16 +#define W_TXDATAFIFO7__Tx14DataFifoSize 7 +#define O_TXDATAFIFO7__Tx15DataFifoStart 8 +#define W_TXDATAFIFO7__Tx15DataFifoStart 7 +#define O_TXDATAFIFO7__Tx15DataFifoSize 0 +#define W_TXDATAFIFO7__Tx15DataFifoSize 7 +#define R_RXDATAFIFO0 0x229 +#define O_RXDATAFIFO0__Rx0DataFifoStart 24 +#define W_RXDATAFIFO0__Rx0DataFifoStart 7 +#define O_RXDATAFIFO0__Rx0DataFifoSize 16 +#define W_RXDATAFIFO0__Rx0DataFifoSize 7 +#define O_RXDATAFIFO0__Rx1DataFifoStart 8 +#define W_RXDATAFIFO0__Rx1DataFifoStart 7 +#define O_RXDATAFIFO0__Rx1DataFifoSize 0 +#define W_RXDATAFIFO0__Rx1DataFifoSize 7 +#define R_RXDATAFIFO1 0x22A +#define O_RXDATAFIFO1__Rx2DataFifoStart 24 +#define W_RXDATAFIFO1__Rx2DataFifoStart 7 +#define O_RXDATAFIFO1__Rx2DataFifoSize 16 +#define W_RXDATAFIFO1__Rx2DataFifoSize 7 +#define O_RXDATAFIFO1__Rx3DataFifoStart 8 +#define W_RXDATAFIFO1__Rx3DataFifoStart 7 +#define O_RXDATAFIFO1__Rx3DataFifoSize 0 +#define W_RXDATAFIFO1__Rx3DataFifoSize 7 +#define R_RXDATAFIFO2 0x22B +#define O_RXDATAFIFO2__Rx4DataFifoStart 24 +#define W_RXDATAFIFO2__Rx4DataFifoStart 7 +#define O_RXDATAFIFO2__Rx4DataFifoSize 16 +#define W_RXDATAFIFO2__Rx4DataFifoSize 7 +#define O_RXDATAFIFO2__Rx5DataFifoStart 8 +#define W_RXDATAFIFO2__Rx5DataFifoStart 7 +#define O_RXDATAFIFO2__Rx5DataFifoSize 0 +#define W_RXDATAFIFO2__Rx5DataFifoSize 7 +#define R_RXDATAFIFO3 0x22C +#define O_RXDATAFIFO3__Rx6DataFifoStart 24 +#define W_RXDATAFIFO3__Rx6DataFifoStart 7 +#define O_RXDATAFIFO3__Rx6DataFifoSize 16 +#define W_RXDATAFIFO3__Rx6DataFifoSize 7 +#define O_RXDATAFIFO3__Rx7DataFifoStart 8 +#define W_RXDATAFIFO3__Rx7DataFifoStart 7 +#define O_RXDATAFIFO3__Rx7DataFifoSize 0 +#define W_RXDATAFIFO3__Rx7DataFifoSize 7 +#define R_RXDATAFIFO4 0x22D +#define O_RXDATAFIFO4__Rx8DataFifoStart 24 +#define W_RXDATAFIFO4__Rx8DataFifoStart 7 +#define O_RXDATAFIFO4__Rx8DataFifoSize 16 +#define W_RXDATAFIFO4__Rx8DataFifoSize 7 +#define O_RXDATAFIFO4__Rx9DataFifoStart 8 +#define W_RXDATAFIFO4__Rx9DataFifoStart 7 +#define O_RXDATAFIFO4__Rx9DataFifoSize 0 +#define W_RXDATAFIFO4__Rx9DataFifoSize 7 +#define R_RXDATAFIFO5 0x22E +#define O_RXDATAFIFO5__Rx10DataFifoStart 24 +#define W_RXDATAFIFO5__Rx10DataFifoStart 7 +#define O_RXDATAFIFO5__Rx10DataFifoSize 16 +#define W_RXDATAFIFO5__Rx10DataFifoSize 7 +#define O_RXDATAFIFO5__Rx11DataFifoStart 8 +#define W_RXDATAFIFO5__Rx11DataFifoStart 7 +#define O_RXDATAFIFO5__Rx11DataFifoSize 0 +#define W_RXDATAFIFO5__Rx11DataFifoSize 7 +#define R_RXDATAFIFO6 0x22F +#define O_RXDATAFIFO6__Rx12DataFifoStart 24 +#define W_RXDATAFIFO6__Rx12DataFifoStart 7 +#define O_RXDATAFIFO6__Rx12DataFifoSize 16 +#define W_RXDATAFIFO6__Rx12DataFifoSize 7 +#define O_RXDATAFIFO6__Rx13DataFifoStart 8 +#define W_RXDATAFIFO6__Rx13DataFifoStart 7 +#define O_RXDATAFIFO6__Rx13DataFifoSize 0 +#define W_RXDATAFIFO6__Rx13DataFifoSize 7 +#define R_RXDATAFIFO7 0x230 +#define O_RXDATAFIFO7__Rx14DataFifoStart 24 +#define W_RXDATAFIFO7__Rx14DataFifoStart 7 +#define O_RXDATAFIFO7__Rx14DataFifoSize 16 +#define W_RXDATAFIFO7__Rx14DataFifoSize 7 +#define O_RXDATAFIFO7__Rx15DataFifoStart 8 +#define W_RXDATAFIFO7__Rx15DataFifoStart 7 +#define O_RXDATAFIFO7__Rx15DataFifoSize 0 +#define W_RXDATAFIFO7__Rx15DataFifoSize 7 +#define R_XGMACPADCALIBRATION 0x231 +#define R_FREEQCARVE 0x233 +#define R_SPI4STATICDELAY0 0x240 +#define O_SPI4STATICDELAY0__DataLine7 28 +#define W_SPI4STATICDELAY0__DataLine7 4 +#define O_SPI4STATICDELAY0__DataLine6 24 +#define W_SPI4STATICDELAY0__DataLine6 4 +#define O_SPI4STATICDELAY0__DataLine5 20 +#define W_SPI4STATICDELAY0__DataLine5 4 +#define O_SPI4STATICDELAY0__DataLine4 16 +#define W_SPI4STATICDELAY0__DataLine4 4 +#define O_SPI4STATICDELAY0__DataLine3 12 +#define W_SPI4STATICDELAY0__DataLine3 4 +#define O_SPI4STATICDELAY0__DataLine2 8 +#define W_SPI4STATICDELAY0__DataLine2 4 +#define O_SPI4STATICDELAY0__DataLine1 4 +#define W_SPI4STATICDELAY0__DataLine1 4 +#define O_SPI4STATICDELAY0__DataLine0 0 +#define W_SPI4STATICDELAY0__DataLine0 4 +#define R_SPI4STATICDELAY1 0x241 +#define O_SPI4STATICDELAY1__DataLine15 28 +#define W_SPI4STATICDELAY1__DataLine15 4 +#define O_SPI4STATICDELAY1__DataLine14 24 +#define W_SPI4STATICDELAY1__DataLine14 4 +#define O_SPI4STATICDELAY1__DataLine13 20 +#define W_SPI4STATICDELAY1__DataLine13 4 +#define O_SPI4STATICDELAY1__DataLine12 16 +#define W_SPI4STATICDELAY1__DataLine12 4 +#define O_SPI4STATICDELAY1__DataLine11 12 +#define W_SPI4STATICDELAY1__DataLine11 4 +#define O_SPI4STATICDELAY1__DataLine10 8 +#define W_SPI4STATICDELAY1__DataLine10 4 +#define O_SPI4STATICDELAY1__DataLine9 4 +#define W_SPI4STATICDELAY1__DataLine9 4 +#define O_SPI4STATICDELAY1__DataLine8 0 +#define W_SPI4STATICDELAY1__DataLine8 4 +#define R_SPI4STATICDELAY2 0x242 +#define O_SPI4STATICDELAY0__TxStat1 8 +#define W_SPI4STATICDELAY0__TxStat1 4 +#define O_SPI4STATICDELAY0__TxStat0 4 +#define W_SPI4STATICDELAY0__TxStat0 4 +#define O_SPI4STATICDELAY0__RxControl 0 +#define W_SPI4STATICDELAY0__RxControl 4 +#define R_SPI4CONTROL 0x243 +#define O_SPI4CONTROL__StaticDelay 2 +#define O_SPI4CONTROL__LVDS_LVTTL 1 +#define O_SPI4CONTROL__SPI4Enable 0 +#define R_CLASSWATERMARKS 0x244 +#define O_CLASSWATERMARKS__Class0Watermark 24 +#define W_CLASSWATERMARKS__Class0Watermark 5 +#define O_CLASSWATERMARKS__Class1Watermark 16 +#define W_CLASSWATERMARKS__Class1Watermark 5 +#define O_CLASSWATERMARKS__Class3Watermark 0 +#define W_CLASSWATERMARKS__Class3Watermark 5 +#define R_RXWATERMARKS1 0x245 +#define O_RXWATERMARKS__Rx0DataWatermark 24 +#define W_RXWATERMARKS__Rx0DataWatermark 7 +#define O_RXWATERMARKS__Rx1DataWatermark 16 +#define W_RXWATERMARKS__Rx1DataWatermark 7 +#define O_RXWATERMARKS__Rx3DataWatermark 0 +#define W_RXWATERMARKS__Rx3DataWatermark 7 +#define R_RXWATERMARKS2 0x246 +#define O_RXWATERMARKS__Rx4DataWatermark 24 +#define W_RXWATERMARKS__Rx4DataWatermark 7 +#define O_RXWATERMARKS__Rx5DataWatermark 16 +#define W_RXWATERMARKS__Rx5DataWatermark 7 +#define O_RXWATERMARKS__Rx6DataWatermark 8 +#define W_RXWATERMARKS__Rx6DataWatermark 7 +#define O_RXWATERMARKS__Rx7DataWatermark 0 +#define W_RXWATERMARKS__Rx7DataWatermark 7 +#define R_RXWATERMARKS3 0x247 +#define O_RXWATERMARKS__Rx8DataWatermark 24 +#define W_RXWATERMARKS__Rx8DataWatermark 7 +#define O_RXWATERMARKS__Rx9DataWatermark 16 +#define W_RXWATERMARKS__Rx9DataWatermark 7 +#define O_RXWATERMARKS__Rx10DataWatermark 8 +#define W_RXWATERMARKS__Rx10DataWatermark 7 +#define O_RXWATERMARKS__Rx11DataWatermark 0 +#define W_RXWATERMARKS__Rx11DataWatermark 7 +#define R_RXWATERMARKS4 0x248 +#define O_RXWATERMARKS__Rx12DataWatermark 24 +#define W_RXWATERMARKS__Rx12DataWatermark 7 +#define O_RXWATERMARKS__Rx13DataWatermark 16 +#define W_RXWATERMARKS__Rx13DataWatermark 7 +#define O_RXWATERMARKS__Rx14DataWatermark 8 +#define W_RXWATERMARKS__Rx14DataWatermark 7 +#define O_RXWATERMARKS__Rx15DataWatermark 0 +#define W_RXWATERMARKS__Rx15DataWatermark 7 +#define R_FREEWATERMARKS 0x249 +#define O_FREEWATERMARKS__FreeOutWatermark 16 +#define W_FREEWATERMARKS__FreeOutWatermark 16 +#define O_FREEWATERMARKS__JumFrWatermark 8 +#define W_FREEWATERMARKS__JumFrWatermark 7 +#define O_FREEWATERMARKS__RegFrWatermark 0 +#define W_FREEWATERMARKS__RegFrWatermark 7 +#define R_EGRESSFIFOCARVINGSLOTS 0x24a + +#define CTRL_RES0 0 +#define CTRL_RES1 1 +#define CTRL_REG_FREE 2 +#define CTRL_JUMBO_FREE 3 +#define CTRL_CONT 4 +#define CTRL_EOP 5 +#define CTRL_START 6 +#define CTRL_SNGL 7 + +#define CTRL_B0_NOT_EOP 0 +#define CTRL_B0_EOP 1 + +#define R_ROUND_ROBIN_TABLE 0 +#define R_PDE_CLASS_0 0x300 +#define R_PDE_CLASS_1 0x302 +#define R_PDE_CLASS_2 0x304 +#define R_PDE_CLASS_3 0x306 + +#define R_MSG_TX_THRESHOLD 0x308 + +#define R_GMAC_JFR0_BUCKET_SIZE 0x320 +#define R_GMAC_RFR0_BUCKET_SIZE 0x321 +#define R_GMAC_TX0_BUCKET_SIZE 0x322 +#define R_GMAC_TX1_BUCKET_SIZE 0x323 +#define R_GMAC_TX2_BUCKET_SIZE 0x324 +#define R_GMAC_TX3_BUCKET_SIZE 0x325 +#define R_GMAC_JFR1_BUCKET_SIZE 0x326 +#define R_GMAC_RFR1_BUCKET_SIZE 0x327 + +#define R_XGS_TX0_BUCKET_SIZE 0x320 +#define R_XGS_TX1_BUCKET_SIZE 0x321 +#define R_XGS_TX2_BUCKET_SIZE 0x322 +#define R_XGS_TX3_BUCKET_SIZE 0x323 +#define R_XGS_TX4_BUCKET_SIZE 0x324 +#define R_XGS_TX5_BUCKET_SIZE 0x325 +#define R_XGS_TX6_BUCKET_SIZE 0x326 +#define R_XGS_TX7_BUCKET_SIZE 0x327 +#define R_XGS_TX8_BUCKET_SIZE 0x328 +#define R_XGS_TX9_BUCKET_SIZE 0x329 +#define R_XGS_TX10_BUCKET_SIZE 0x32A +#define R_XGS_TX11_BUCKET_SIZE 0x32B +#define R_XGS_TX12_BUCKET_SIZE 0x32C +#define R_XGS_TX13_BUCKET_SIZE 0x32D +#define R_XGS_TX14_BUCKET_SIZE 0x32E +#define R_XGS_TX15_BUCKET_SIZE 0x32F +#define R_XGS_JFR_BUCKET_SIZE 0x330 +#define R_XGS_RFR_BUCKET_SIZE 0x331 + +#define R_CC_CPU0_0 0x380 +#define R_CC_CPU1_0 0x388 +#define R_CC_CPU2_0 0x390 +#define R_CC_CPU3_0 0x398 +#define R_CC_CPU4_0 0x3a0 +#define R_CC_CPU5_0 0x3a8 +#define R_CC_CPU6_0 0x3b0 +#define R_CC_CPU7_0 0x3b8 + +#define XLR_GMAC_BLK_SZ (XLR_IO_GMAC_1_OFFSET - \ + XLR_IO_GMAC_0_OFFSET) + +/* Constants used for configuring the devices */ + +#define XLR_FB_STN 6 /* Bucket used for Tx freeback */ + +#define MAC_B2B_IPG 88 + +#define XLR_NET_PREPAD_LEN 32 + +/* frame sizes need to be cacheline aligned */ +#define MAX_FRAME_SIZE (1536 + XLR_NET_PREPAD_LEN) +#define MAX_FRAME_SIZE_JUMBO 9216 + +#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES +#define MAC_PREPAD 0 +#define BYTE_OFFSET 2 +#define XLR_RX_BUF_SIZE (MAX_FRAME_SIZE + BYTE_OFFSET + \ + MAC_PREPAD + MAC_SKB_BACK_PTR_SIZE + SMP_CACHE_BYTES) +#define MAC_CRC_LEN 4 +#define MAX_NUM_MSGRNG_STN_CC 128 +#define MAX_MSG_SND_ATTEMPTS 100 /* 13 stns x 4 entry msg/stn + + headroom */ + +#define MAC_FRIN_TO_BE_SENT_THRESHOLD 16 + +#define MAX_NUM_DESC_SPILL 1024 +#define MAX_FRIN_SPILL (MAX_NUM_DESC_SPILL << 2) +#define MAX_FROUT_SPILL (MAX_NUM_DESC_SPILL << 2) +#define MAX_CLASS_0_SPILL (MAX_NUM_DESC_SPILL << 2) +#define MAX_CLASS_1_SPILL (MAX_NUM_DESC_SPILL << 2) +#define MAX_CLASS_2_SPILL (MAX_NUM_DESC_SPILL << 2) +#define MAX_CLASS_3_SPILL (MAX_NUM_DESC_SPILL << 2) + +enum { + SGMII_SPEED_10 = 0x00000000, + SGMII_SPEED_100 = 0x02000000, + SGMII_SPEED_1000 = 0x04000000, +}; + +enum tsv_rsv_reg { + TX_RX_64_BYTE_FRAME = 0x20, + TX_RX_64_127_BYTE_FRAME, + TX_RX_128_255_BYTE_FRAME, + TX_RX_256_511_BYTE_FRAME, + TX_RX_512_1023_BYTE_FRAME, + TX_RX_1024_1518_BYTE_FRAME, + TX_RX_1519_1522_VLAN_BYTE_FRAME, + + RX_BYTE_COUNTER = 0x27, + RX_PACKET_COUNTER, + RX_FCS_ERROR_COUNTER, + RX_MULTICAST_PACKET_COUNTER, + RX_BROADCAST_PACKET_COUNTER, + RX_CONTROL_FRAME_PACKET_COUNTER, + RX_PAUSE_FRAME_PACKET_COUNTER, + RX_UNKNOWN_OP_CODE_COUNTER, + RX_ALIGNMENT_ERROR_COUNTER, + RX_FRAME_LENGTH_ERROR_COUNTER, + RX_CODE_ERROR_COUNTER, + RX_CARRIER_SENSE_ERROR_COUNTER, + RX_UNDERSIZE_PACKET_COUNTER, + RX_OVERSIZE_PACKET_COUNTER, + RX_FRAGMENTS_COUNTER, + RX_JABBER_COUNTER, + RX_DROP_PACKET_COUNTER, + + TX_BYTE_COUNTER = 0x38, + TX_PACKET_COUNTER, + TX_MULTICAST_PACKET_COUNTER, + TX_BROADCAST_PACKET_COUNTER, + TX_PAUSE_CONTROL_FRAME_COUNTER, + TX_DEFERRAL_PACKET_COUNTER, + TX_EXCESSIVE_DEFERRAL_PACKET_COUNTER, + TX_SINGLE_COLLISION_PACKET_COUNTER, + TX_MULTI_COLLISION_PACKET_COUNTER, + TX_LATE_COLLISION_PACKET_COUNTER, + TX_EXCESSIVE_COLLISION_PACKET_COUNTER, + TX_TOTAL_COLLISION_COUNTER, + TX_PAUSE_FRAME_HONERED_COUNTER, + TX_DROP_FRAME_COUNTER, + TX_JABBER_FRAME_COUNTER, + TX_FCS_ERROR_COUNTER, + TX_CONTROL_FRAME_COUNTER, + TX_OVERSIZE_FRAME_COUNTER, + TX_UNDERSIZE_FRAME_COUNTER, + TX_FRAGMENT_FRAME_COUNTER, + + CARRY_REG_1 = 0x4c, + CARRY_REG_2 = 0x4d, +}; + +struct xlr_net_priv { + u32 __iomem *base_addr; + struct net_device *ndev; + struct mii_bus *mii_bus; + int num_rx_desc; + int phy_addr; /* PHY addr on MDIO bus */ + int pcs_id; /* PCS id on MDIO bus */ + int port_id; /* Port(gmac/xgmac) number, i.e 0-7 */ + u32 __iomem *mii_addr; + u32 __iomem *serdes_addr; + u32 __iomem *pcs_addr; + u32 __iomem *gpio_addr; + int phy_speed; + int port_type; + struct timer_list queue_timer; + int wakeup_q; + struct platform_device *pdev; + struct xlr_net_data *nd; + + u64 *frin_spill; + u64 *frout_spill; + u64 *class_0_spill; + u64 *class_1_spill; + u64 *class_2_spill; + u64 *class_3_spill; +}; + +extern void xlr_set_gmac_speed(struct xlr_net_priv *priv); -- cgit From 4363b57786f8e5c82d52906d4dd29bf67304564e Mon Sep 17 00:00:00 2001 From: Michal Pecio Date: Fri, 8 Mar 2013 22:42:03 +0100 Subject: orinoco_usb: don't release nonexistent firmware Initialize fw_entry to NULL to prevent cleanup code from passing bogus pointer to release_firmware() when priv allocation fails. Signed-off-by: Michal Pecio Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index 7744f42de1ea..1f9cb55c3360 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1584,7 +1584,7 @@ static int ezusb_probe(struct usb_interface *interface, struct ezusb_priv *upriv = NULL; struct usb_interface_descriptor *iface_desc; struct usb_endpoint_descriptor *ep; - const struct firmware *fw_entry; + const struct firmware *fw_entry = NULL; int retval = 0; int i; -- cgit From 60c46bf8176bd4cf28314a8bf0cf26f2ddc3b793 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 8 Mar 2013 11:12:56 -0800 Subject: iwlegacy: fix sparse warnings Make local functions and tables static. Make ops table Mark 3945 ops as read_mostly. Signed-off-by: Stephen Hemminger Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 2 +- drivers/net/wireless/iwlegacy/4965-mac.c | 16 ++++++++-------- drivers/net/wireless/iwlegacy/common.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 3630a41df50d..df5a57c74808 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3475,7 +3475,7 @@ static struct attribute_group il3945_attribute_group = { .attrs = il3945_sysfs_entries, }; -struct ieee80211_ops il3945_mac_ops = { +static struct ieee80211_ops il3945_mac_ops __read_mostly = { .tx = il3945_mac_tx, .start = il3945_mac_start, .stop = il3945_mac_stop, diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index c092fcbbe965..5bc995a48519 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -612,7 +612,7 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr, /* Called for N_RX (legacy ABG frames), or * N_RX_MPDU (HT high-throughput N frames). */ -void +static void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) { struct ieee80211_hdr *header; @@ -744,7 +744,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) /* Cache phy data (Rx signal strength, etc) for HT frame (N_RX_PHY). * This will be used later in il_hdl_rx() for N_RX_MPDU. */ -void +static void il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); @@ -1250,7 +1250,7 @@ il4965_dump_fh(struct il_priv *il, char **buf, bool display) return 0; } -void +static void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); @@ -1357,7 +1357,7 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats) } #endif -void +static void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) { const int recalib_seconds = 60; @@ -1399,7 +1399,7 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) il4965_temperature_calib(il); } -void +static void il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); @@ -2050,7 +2050,7 @@ il4965_txq_ctx_reset(struct il_priv *il) il_tx_queue_reset(il, txq_id); } -void +static void il4965_txq_ctx_unmap(struct il_priv *il) { int txq_id; @@ -2896,7 +2896,7 @@ il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags, * Handles block-acknowledge notification from device, which reports success * of frames sent via aggregation. */ -void +static void il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); @@ -6317,7 +6317,7 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); } -const struct ieee80211_ops il4965_mac_ops = { +static const struct ieee80211_ops il4965_mac_ops = { .tx = il4965_mac_tx, .start = il4965_mac_start, .stop = il4965_mac_stop, diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index e006ea831320..bc465da40476 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1122,7 +1122,7 @@ il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd) sizeof(struct il_powertable_cmd), cmd); } -int +static int il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force) { int ret; -- cgit From 7c21bb6996d40f6bb21a015392be41ebb0e538c2 Mon Sep 17 00:00:00 2001 From: Andrei Epure Date: Sun, 10 Mar 2013 15:09:47 +0200 Subject: wireless:rtlwifi: replaced kmalloc+memcpy with kmemdup Signed-off-by: Andrei Epure Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 156b52732f3d..b5c80b5d57ef 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -224,10 +224,9 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data, u8 *buffer; wvalue = (u16)(addr & 0x0000ffff); - buffer = kmalloc(len, GFP_ATOMIC); + buffer = kmemdup(data, len, GFP_ATOMIC); if (!buffer) return; - memcpy(buffer, data, len); usb_control_msg(udev, pipe, request, reqtype, wvalue, index, buffer, len, 50); -- cgit From c3f251a317e032c9ceaf539b02a962986f70b523 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Mon, 11 Mar 2013 17:44:21 +0100 Subject: mwl8k: don't overwrite regulatory settings on fw reload Currently the caps are parsed on every firmware reload, causing any channel flags to be cleared. When there is a firmware to interface mode mismatch, the triggered firmware reload causes a reset of the regulatory settings, causing all channels to become available: root@openrouter:/# iw phy phy0 info Wiphy phy0 Band 1: (...) Frequencies: * 2412 MHz [1] (0.0 dBm) * 2417 MHz [2] (0.0 dBm) * 2422 MHz [3] (0.0 dBm) * 2427 MHz [4] (0.0 dBm) * 2432 MHz [5] (0.0 dBm) * 2437 MHz [6] (0.0 dBm) * 2442 MHz [7] (0.0 dBm) * 2447 MHz [8] (0.0 dBm) * 2452 MHz [9] (0.0 dBm) * 2457 MHz [10] (0.0 dBm) * 2462 MHz [11] (0.0 dBm) * 2467 MHz [12] (0.0 dBm) * 2472 MHz [13] (0.0 dBm) * 2484 MHz [14] (0.0 dBm) (...) To prevent this, only parse the caps on the first firmware load during hardware probe, and store them locally to know we have already parsed them. Signed-off-by: Jonas Gorski Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index aaaf10d48f7d..0640e7d7f0c2 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -232,6 +232,7 @@ struct mwl8k_priv { u16 num_mcaddrs; u8 hw_rev; u32 fw_rev; + u32 caps; /* * Running count of TX packets in flight, to avoid @@ -2410,6 +2411,9 @@ mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps) { struct mwl8k_priv *priv = hw->priv; + if (priv->caps) + return; + if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) { mwl8k_setup_2ghz_band(hw); if (caps & MWL8K_CAP_MIMO) @@ -2421,6 +2425,8 @@ mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps) if (caps & MWL8K_CAP_MIMO) mwl8k_set_ht_caps(hw, &priv->band_50, caps); } + + priv->caps = caps; } static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) -- cgit From bf161d2163f7b8bf4823829dbc1a14111760187e Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Fri, 8 Feb 2013 14:44:09 +0200 Subject: clk: tegra: No 7.1 super clk dividers on Tegra20 Unlike Tegra30, Tegra20 does not have a 7.1 divider for the CPU superclk. Remove the clocks related to the divider. Signed-off-by: Peter De Schrijver Signed-off-by: Stephen Warren --- drivers/clk/tegra/clk-tegra20.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 143ce1f899ad..fa3173e3b331 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -711,8 +711,8 @@ static void tegra20_pll_init(void) } static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", - "pll_p_cclk", "pll_p_out4_cclk", - "pll_p_out3_cclk", "clk_d", "pll_x" }; + "pll_p", "pll_p_out4", + "pll_p_out3", "clk_d", "pll_x" }; static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", "pll_p_out3", "pll_p_out2", "clk_d", "clk_32k", "pll_m_out1" }; @@ -721,38 +721,6 @@ static void tegra20_super_clk_init(void) { struct clk *clk; - /* - * DIV_U71 dividers for CCLK, these dividers are used only - * if parent clock is fixed rate. - */ - - /* - * Clock input to cclk divided from pll_p using - * U71 divider of cclk. - */ - clk = tegra_clk_register_divider("pll_p_cclk", "pll_p", - clk_base + SUPER_CCLK_DIVIDER, 0, - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); - clk_register_clkdev(clk, "pll_p_cclk", NULL); - - /* - * Clock input to cclk divided from pll_p_out3 using - * U71 divider of cclk. - */ - clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3", - clk_base + SUPER_CCLK_DIVIDER, 0, - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); - clk_register_clkdev(clk, "pll_p_out3_cclk", NULL); - - /* - * Clock input to cclk divided from pll_p_out4 using - * U71 divider of cclk. - */ - clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4", - clk_base + SUPER_CCLK_DIVIDER, 0, - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); - clk_register_clkdev(clk, "pll_p_out4_cclk", NULL); - /* CCLK */ clk = tegra_clk_register_super_mux("cclk", cclk_parents, ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, -- cgit From 6f88fb8af6c67f281b8e2cd607f08e0089c8ccbe Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 4 Feb 2013 15:40:30 +0200 Subject: clocksource: tegra: move to of_clk_get The new clockframework introduced DT IDs for each clock. To be able to remove the device registrations, this driver needs to be updated to use the DT IDs. Note that the actual removal of the clk_register_clkdev() calls will be done in a later series. Signed-off-by: Peter De Schrijver Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra20.dtsi | 2 ++ arch/arm/boot/dts/tegra30.dtsi | 2 ++ drivers/clocksource/tegra20_timer.c | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 9a428931d042..37701d8727d8 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -144,6 +144,7 @@ 0 1 0x04 0 41 0x04 0 42 0x04>; + clocks = <&tegra_car 5>; }; tegra_car: clock { @@ -303,6 +304,7 @@ compatible = "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = <0 2 0x04>; + clocks = <&tegra_car 4>; }; i2c@7000c000 { diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 767803e1fd55..7effa93ea9d9 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -147,6 +147,7 @@ 0 42 0x04 0 121 0x04 0 122 0x04>; + clocks = <&tegra_car 5>; }; tegra_car: clock { @@ -290,6 +291,7 @@ compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = <0 2 0x04>; + clocks = <&tegra_car 4>; }; i2c@7000c000 { diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index 0bde03feb095..bc4b8ad78aea 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c @@ -189,7 +189,7 @@ static void __init tegra20_init_timer(void) BUG(); } - clk = clk_get_sys("timer", NULL); + clk = of_clk_get(np, 0); if (IS_ERR(clk)) { pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n"); rate = 12000000; @@ -216,7 +216,7 @@ static void __init tegra20_init_timer(void) * rtc registers are used by read_persistent_clock, keep the rtc clock * enabled */ - clk = clk_get_sys("rtc-tegra", NULL); + clk = of_clk_get(np, 0); if (IS_ERR(clk)) pr_warn("Unable to get rtc-tegra clock\n"); else -- cgit From c13085e519e8984fede41fa3d6a5502523b10996 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:19:38 +0000 Subject: ACPICA: Resource Mgr: Prevent infinite loops in resource walks Add checks for zero-length resource descriptors in all code that loops through a resource descriptor list. This prevents possible infinite loops because the length is used to increment the traveral pointer and detect the end-of-descriptor. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/rscalc.c | 6 ++++++ drivers/acpi/acpica/rsdump.c | 8 ++++++++ drivers/acpi/acpica/rslist.c | 8 ++++++++ drivers/acpi/acpica/rsxface.c | 8 +++++++- 4 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 7816d4eef04e..72077fa1eea5 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -202,6 +202,12 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } + /* Sanity check the length. It must not be zero, or we loop forever */ + + if (!resource->length) { + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); + } + /* Get the base size of the (external stream) resource descriptor */ total_size = acpi_gbl_aml_resource_sizes[resource->type]; diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index cab51445189d..b5fc0db2e87b 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -385,6 +385,14 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) return; } + /* Sanity check the length. It must not be zero, or we loop forever */ + + if (!resource_list->length) { + acpi_os_printf + ("Invalid zero length descriptor in resource list\n"); + return; + } + /* Dump the resource descriptor */ if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index ee2e206fc6c8..6053aa182093 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -178,6 +178,14 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, return_ACPI_STATUS(AE_BAD_DATA); } + /* Sanity check the length. It must not be zero, or we loop forever */ + + if (!resource->length) { + ACPI_ERROR((AE_INFO, + "Invalid zero length descriptor in resource list\n")); + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); + } + /* Perform the conversion */ if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 15d6eaef0e28..c0e5d2d3ce67 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -563,13 +563,19 @@ acpi_walk_resource_buffer(struct acpi_buffer * buffer, while (resource < resource_end) { - /* Sanity check the resource */ + /* Sanity check the resource type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { status = AE_AML_INVALID_RESOURCE_TYPE; break; } + /* Sanity check the length. It must not be zero, or we loop forever */ + + if (!resource->length) { + return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); + } + /* Invoke the user function, abort on any error returned */ status = user_function(resource, context); -- cgit From 3cfcf50ba4b8ef34258464f529e09c3e4324b8d6 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Fri, 8 Mar 2013 09:20:04 +0000 Subject: ACPICA: Fix a couple warnings detected on FreeBSD build This fixes a global and a pointer cast. Jung-uk Kim. Signed-off-by: Jung-uk Kim Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ecb49927b817..feaa5d5ef579 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -413,7 +413,7 @@ ACPI_EXTERN u8 acpi_gbl_db_output_flags; #ifdef ACPI_DISASSEMBLER -u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); +ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; -- cgit From 3cf24497f45d61ed3c3290b5b03f3baeb8401f04 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Fri, 8 Mar 2013 09:21:02 +0000 Subject: ACPICA: Fix a long-standing bug in local cache Since 20060317, the pointer to next object is the first element in its common header. Remove bogus LinkOffset from ACPI_MEMORY_LIST and directly use NextObject. Signed-off-by: Jung-uk Kim Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utcache.c | 20 +++++++------------- include/acpi/actypes.h | 1 - 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index e0e8579deaac..2de22fbacf4b 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c @@ -85,7 +85,6 @@ acpi_os_create_cache(char *cache_name, /* Populate the cache object and return it */ ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); - cache->link_offset = 8; cache->list_name = cache_name; cache->object_size = object_size; cache->max_depth = max_depth; @@ -108,7 +107,7 @@ acpi_os_create_cache(char *cache_name, acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) { - char *next; + void *next; acpi_status status; ACPI_FUNCTION_ENTRY(); @@ -128,10 +127,9 @@ acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) /* Delete and unlink one cached state object */ - next = *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *)cache-> - list_head)[cache-> - link_offset]))); + next = + ((struct acpi_object_common *)cache->list_head)-> + next_object; ACPI_FREE(cache->list_head); cache->list_head = next; @@ -221,9 +219,7 @@ acpi_os_release_object(struct acpi_memory_list * cache, void *object) /* Put the object at the head of the cache list */ - *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *)object)[cache-> - link_offset]))) = + ((struct acpi_object_common *)object)->next_object = cache->list_head; cache->list_head = object; cache->current_depth++; @@ -272,10 +268,8 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) /* There is an object available, use it */ object = cache->list_head; - cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char, - &(((char *) - object)[cache-> - link_offset]))); + cache->list_head = + ((struct acpi_object_common *)object)->next_object; cache->current_depth--; diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 845e75f1ffd8..3fac1be2d8b4 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1128,7 +1128,6 @@ struct acpi_memory_list { u16 object_size; u16 max_depth; u16 current_depth; - u16 link_offset; #ifdef ACPI_DBG_TRACK_ALLOCATIONS -- cgit From d4d32195ff070acca43577250adee6b210decdd3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:21:41 +0000 Subject: ACPICA: Update error/debug messages for fixed events Add the actual fixed event name to all messages for clarity. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evevent.c | 12 +++++++----- drivers/acpi/acpica/evxface.c | 21 ++++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index b8ea0b26cde3..02219ffba8b6 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -257,6 +257,8 @@ u32 acpi_ev_fixed_event_detect(void) * * DESCRIPTION: Clears the status bit for the requested event, calls the * handler that previously registered for the event. + * NOTE: If there is no handler for the event, the event is + * disabled to prevent futher interrupts. * ******************************************************************************/ @@ -271,17 +273,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) status_register_id, ACPI_CLEAR_STATUS); /* - * Make sure we've got a handler. If not, report an error. The event is - * disabled to prevent further interrupts. + * Make sure that a handler exists. If not, report an error + * and disable the event to prevent further interrupts. */ - if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { + if (!acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. enable_register_id, ACPI_DISABLE_EVENT); ACPI_ERROR((AE_INFO, - "No installed handler for fixed event [0x%08X]", - event)); + "No installed handler for fixed event - %s (%u), disabling", + acpi_ut_get_event_name(event), event)); return (ACPI_INTERRUPT_NOT_HANDLED); } diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index ddffd6847914..ca5fba99c33b 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -467,9 +467,9 @@ acpi_install_fixed_event_handler(u32 event, return_ACPI_STATUS(status); } - /* Don't allow two handlers. */ + /* Do not allow multiple handlers */ - if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { + if (acpi_gbl_fixed_event_handlers[event].handler) { status = AE_ALREADY_EXISTS; goto cleanup; } @@ -483,8 +483,9 @@ acpi_install_fixed_event_handler(u32 event, if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", - event)); + ACPI_WARNING((AE_INFO, + "Could not enable fixed event - %s (%u)", + acpi_ut_get_event_name(event), event)); /* Remove the handler */ @@ -492,7 +493,8 @@ acpi_install_fixed_event_handler(u32 event, acpi_gbl_fixed_event_handlers[event].context = NULL; } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Enabled fixed event %X, Handler=%p\n", event, + "Enabled fixed event %s (%X), Handler=%p\n", + acpi_ut_get_event_name(event), event, handler)); } @@ -544,11 +546,12 @@ acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, - "Could not write to fixed event enable register 0x%X", - event)); + "Could not disable fixed event - %s (%u)", + acpi_ut_get_event_name(event), event)); } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", - event)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Disabled fixed event - %s (%X)\n", + acpi_ut_get_event_name(event), event)); } (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); -- cgit From 1af89271711b23ff9eee66de018bc92eb347ea68 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Fri, 8 Mar 2013 09:21:54 +0000 Subject: ACPICA: Add macros to access pointer to next object in the descriptor list Signed-off-by: Jung-uk Kim Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acmacros.h | 4 +++- drivers/acpi/acpica/utcache.c | 10 +++------- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index ed7943b9044f..8b7ca40c4eb5 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -322,8 +322,10 @@ * where a pointer to an object of type union acpi_operand_object can also * appear. This macro is used to distinguish them. * - * The "Descriptor" field is the first field in both structures. + * The "DescriptorType" field is the second field in both structures. */ +#define ACPI_GET_DESCRIPTOR_PTR(d) (((union acpi_descriptor *)(void *)(d))->common.common_pointer) +#define ACPI_SET_DESCRIPTOR_PTR(d, o) (((union acpi_descriptor *)(void *)(d))->common.common_pointer = o) #define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) #define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index 2de22fbacf4b..a877a9647fd9 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c @@ -127,9 +127,7 @@ acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) /* Delete and unlink one cached state object */ - next = - ((struct acpi_object_common *)cache->list_head)-> - next_object; + next = ACPI_GET_DESCRIPTOR_PTR(cache->list_head); ACPI_FREE(cache->list_head); cache->list_head = next; @@ -219,8 +217,7 @@ acpi_os_release_object(struct acpi_memory_list * cache, void *object) /* Put the object at the head of the cache list */ - ((struct acpi_object_common *)object)->next_object = - cache->list_head; + ACPI_SET_DESCRIPTOR_PTR(object, cache->list_head); cache->list_head = object; cache->current_depth++; @@ -268,8 +265,7 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) /* There is an object available, use it */ object = cache->list_head; - cache->list_head = - ((struct acpi_object_common *)object)->next_object; + cache->list_head = ACPI_GET_DESCRIPTOR_PTR(object); cache->current_depth--; -- cgit From f1778eb1ab3e3ef90826b6b6b0ad7fbafa46308b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:22:03 +0000 Subject: ACPICA: Add parens within macros around parameter names Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acmacros.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 8b7ca40c4eb5..53666bd9193d 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -325,9 +325,9 @@ * The "DescriptorType" field is the second field in both structures. */ #define ACPI_GET_DESCRIPTOR_PTR(d) (((union acpi_descriptor *)(void *)(d))->common.common_pointer) -#define ACPI_SET_DESCRIPTOR_PTR(d, o) (((union acpi_descriptor *)(void *)(d))->common.common_pointer = o) +#define ACPI_SET_DESCRIPTOR_PTR(d, p) (((union acpi_descriptor *)(void *)(d))->common.common_pointer = (p)) #define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) -#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) +#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = (t)) /* * Macros for the master AML opcode table -- cgit From c39660b232c5e4aee3cded5a02d28e71ca447fb8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:22:14 +0000 Subject: ACPICA: Update for ACPI 5 hardware-reduced feature Ensure that AcpiEnable and AcpiDisable work properly when the hardware-reduced flag is set in the FADT. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evxfevnt.c | 12 ++++++++++++ drivers/acpi/acpica/hwacpi.c | 12 ++++++++++++ 2 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d6e4e42316db..7039606a0ba8 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -74,6 +74,12 @@ acpi_status acpi_enable(void) return_ACPI_STATUS(AE_NO_ACPI_TABLES); } + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* Check current mode */ if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { @@ -126,6 +132,12 @@ acpi_status acpi_disable(void) ACPI_FUNCTION_TRACE(acpi_disable); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index deb3f61e2bd1..9b02a9f5b04a 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -66,6 +66,12 @@ acpi_status acpi_hw_set_mode(u32 mode) ACPI_FUNCTION_TRACE(hw_set_mode); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_ACPI_STATUS(AE_OK); + } + /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. @@ -146,6 +152,12 @@ u32 acpi_hw_get_mode(void) ACPI_FUNCTION_TRACE(hw_get_mode); + /* If the Hardware Reduced flag is set, machine is always in acpi mode */ + + if (acpi_gbl_reduced_hardware) { + return_VALUE(ACPI_SYS_MODE_ACPI); + } + /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, * system does not support mode transition. -- cgit From fd1af7126fb62688cfcf4b563c73b2909ac30f74 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:22:23 +0000 Subject: ACPICA: Regression fix: reinstate safe exit macros Removal caused a regression on at least FreeBSD. This fix reinstates the macros. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsutils.c | 10 ++++---- drivers/acpi/acpica/evgpe.c | 6 ++--- drivers/acpi/acpica/evsci.c | 4 ++-- drivers/acpi/acpica/exprep.c | 4 ++-- drivers/acpi/acpica/exutils.c | 4 ++-- drivers/acpi/acpica/hwacpi.c | 10 ++++---- drivers/acpi/acpica/nsutils.c | 8 +++---- drivers/acpi/acpica/psargs.c | 2 +- drivers/acpi/acpica/utaddress.c | 4 ++-- include/acpi/acoutput.h | 53 +++++++++++++++++++++++++++++++---------- 10 files changed, 67 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 4d8c992a51d8..99778997c35a 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -178,7 +178,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, if (!op) { ACPI_ERROR((AE_INFO, "Null Op")); - return_VALUE(TRUE); + return_UINT8(TRUE); } /* @@ -210,7 +210,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, "At Method level, result of [%s] not used\n", acpi_ps_get_opcode_name(op->common. aml_opcode))); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* Get info on the parent. The root_op is AML_SCOPE */ @@ -219,7 +219,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode); if (parent_info->class == AML_CLASS_UNKNOWN) { ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /* @@ -307,7 +307,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(TRUE); + return_UINT8(TRUE); result_not_used: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, @@ -316,7 +316,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, acpi_ps_get_opcode_name(op->common.parent->common. aml_opcode), op)); - return_VALUE(FALSE); + return_UINT8(FALSE); } /******************************************************************************* diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index b9adb9a7ed85..a493b528f8f9 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to clear GPE%02X", gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } } @@ -724,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE%02X", gpe_number)); - return_VALUE(ACPI_INTERRUPT_NOT_HANDLED); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } /* @@ -784,7 +784,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, break; } - return_VALUE(ACPI_INTERRUPT_HANDLED); + return_UINT32(ACPI_INTERRUPT_HANDLED); } #endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index f4b43bede015..b905acf7aacd 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -89,7 +89,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) */ interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /******************************************************************************* @@ -120,7 +120,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); - return_VALUE(interrupt_handled); + return_UINT32(interrupt_handled); } /****************************************************************************** diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index d6eab81f54fb..6b728aef2dca 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -276,7 +276,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, /* Invalid field access type */ ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access)); - return_VALUE(0); + return_UINT32(0); } if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { @@ -289,7 +289,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, } *return_byte_alignment = byte_alignment; - return_VALUE(bit_length); + return_UINT32(bit_length); } /******************************************************************************* diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index b205cbb4b50c..99dc7b287d55 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -340,7 +340,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base) /* u64 is unsigned, so we don't worry about a '-' prefix */ if (value == 0) { - return_VALUE(1); + return_UINT32(1); } current_value = value; @@ -354,7 +354,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base) num_digits++; } - return_VALUE(num_digits); + return_UINT32(num_digits); } /******************************************************************************* diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 9b02a9f5b04a..579c3a53ac87 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -155,7 +155,7 @@ u32 acpi_hw_get_mode(void) /* If the Hardware Reduced flag is set, machine is always in acpi mode */ if (acpi_gbl_reduced_hardware) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } /* @@ -163,18 +163,18 @@ u32 acpi_hw_get_mode(void) * system does not support mode transition. */ if (!acpi_gbl_FADT.smi_command) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value); if (ACPI_FAILURE(status)) { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } if (value) { - return_VALUE(ACPI_SYS_MODE_ACPI); + return_UINT32(ACPI_SYS_MODE_ACPI); } else { - return_VALUE(ACPI_SYS_MODE_LEGACY); + return_UINT32(ACPI_SYS_MODE_LEGACY); } } diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 686420df684f..2808586fad30 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -112,10 +112,10 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) if (!node) { ACPI_WARNING((AE_INFO, "Null Node parameter")); - return_VALUE(ACPI_TYPE_ANY); + return_UINT8(ACPI_TYPE_ANY); } - return_VALUE(node->type); + return_UINT8(node->type); } /******************************************************************************* @@ -140,10 +140,10 @@ u32 acpi_ns_local(acpi_object_type type) /* Type code out of range */ ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type)); - return_VALUE(ACPI_NS_NORMAL); + return_UINT32(ACPI_NS_NORMAL); } - return_VALUE(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); + return_UINT32(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); } /******************************************************************************* diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index f51308cdbc65..9f25a3d4e992 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -108,7 +108,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ package_length |= (aml[0] & byte_zero_mask); - return_VALUE(package_length); + return_UINT32(package_length); } /******************************************************************************* diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index 698b9d385516..e0a2e2779c2e 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c @@ -214,7 +214,7 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id, if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { - return_VALUE(0); + return_UINT32(0); } range_info = acpi_gbl_address_range_list[space_id]; @@ -256,7 +256,7 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id, range_info = range_info->next; } - return_VALUE(overlap_count); + return_UINT32(overlap_count); } /******************************************************************************* diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 9885276178e0..4f52ea795c7a 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h @@ -324,9 +324,9 @@ /* Helper macro */ -#define ACPI_TRACE_ENTRY(name, function, cast, param) \ +#define ACPI_TRACE_ENTRY(name, function, type, param) \ ACPI_FUNCTION_NAME (name) \ - function (ACPI_DEBUG_PARAMETERS, cast (param)) + function (ACPI_DEBUG_PARAMETERS, (type) (param)) /* The actual entry trace macros */ @@ -335,13 +335,13 @@ acpi_ut_trace (ACPI_DEBUG_PARAMETERS) #define ACPI_FUNCTION_TRACE_PTR(name, pointer) \ - ACPI_TRACE_ENTRY (name, acpi_ut_trace_ptr, (void *), pointer) + ACPI_TRACE_ENTRY (name, acpi_ut_trace_ptr, void *, pointer) #define ACPI_FUNCTION_TRACE_U32(name, value) \ - ACPI_TRACE_ENTRY (name, acpi_ut_trace_u32, (u32), value) + ACPI_TRACE_ENTRY (name, acpi_ut_trace_u32, u32, value) #define ACPI_FUNCTION_TRACE_STR(name, string) \ - ACPI_TRACE_ENTRY (name, acpi_ut_trace_str, (char *), string) + ACPI_TRACE_ENTRY (name, acpi_ut_trace_str, char *, string) #define ACPI_FUNCTION_ENTRY() \ acpi_ut_track_stack_ptr() @@ -355,16 +355,37 @@ * * One of the FUNCTION_TRACE macros above must be used in conjunction * with these macros so that "_AcpiFunctionName" is defined. + * + * There are two versions of most of the return macros. The default version is + * safer, since it avoids side-effects by guaranteeing that the argument will + * not be evaluated twice. + * + * A less-safe version of the macros is provided for optional use if the + * compiler uses excessive CPU stack (for example, this may happen in the + * debug case if code optimzation is disabled.) */ /* Exit trace helper macro */ -#define ACPI_TRACE_EXIT(function, cast, param) \ +#ifndef ACPI_SIMPLE_RETURN_MACROS + +#define ACPI_TRACE_EXIT(function, type, param) \ + ACPI_DO_WHILE0 ({ \ + register type _param = (type) (param); \ + function (ACPI_DEBUG_PARAMETERS, _param); \ + return (_param); \ + }) + +#else /* Use original less-safe macros */ + +#define ACPI_TRACE_EXIT(function, type, param) \ ACPI_DO_WHILE0 ({ \ - function (ACPI_DEBUG_PARAMETERS, cast (param)); \ - return ((param)); \ + function (ACPI_DEBUG_PARAMETERS, (type) (param)); \ + return (param); \ }) +#endif /* ACPI_SIMPLE_RETURN_MACROS */ + /* The actual exit macros */ #define return_VOID \ @@ -374,13 +395,19 @@ }) #define return_ACPI_STATUS(status) \ - ACPI_TRACE_EXIT (acpi_ut_status_exit, (acpi_status), status) + ACPI_TRACE_EXIT (acpi_ut_status_exit, acpi_status, status) #define return_PTR(pointer) \ - ACPI_TRACE_EXIT (acpi_ut_ptr_exit, (u8 *), pointer) + ACPI_TRACE_EXIT (acpi_ut_ptr_exit, void *, pointer) #define return_VALUE(value) \ - ACPI_TRACE_EXIT (acpi_ut_value_exit, (u64), value) + ACPI_TRACE_EXIT (acpi_ut_value_exit, u64, value) + +#define return_UINT32(value) \ + ACPI_TRACE_EXIT (acpi_ut_value_exit, u32, value) + +#define return_UINT8(value) \ + ACPI_TRACE_EXIT (acpi_ut_value_exit, u8, value) /* Conditional execution */ @@ -428,8 +455,10 @@ #define return_VOID return #define return_ACPI_STATUS(s) return(s) -#define return_VALUE(s) return(s) #define return_PTR(s) return(s) +#define return_VALUE(s) return(s) +#define return_UINT8(s) return(s) +#define return_UINT32(s) return(s) #endif /* ACPI_DEBUG_OUTPUT */ -- cgit From ae1b4769989f8707a1f092db191fa2f9a0fc8604 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:22:39 +0000 Subject: ACPICA: Add exception descriptions to exception info table Descriptions to be compiled/used by the acpihelp utility only. Not compiled for the kernel ACPICA code. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 3 +- drivers/acpi/acpica/utexcep.c | 26 ++-- include/acpi/acexcep.h | 269 ++++++++++++++++++++++++++---------------- 3 files changed, 183 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 0082fa0a6139..c01f1a10a9d7 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -483,7 +483,8 @@ acpi_ut_short_divide(u64 in_dividend, /* * utmisc */ -const char *acpi_ut_validate_exception(acpi_status status); +const struct acpi_exception_info *acpi_ut_validate_exception(acpi_status + status); u8 acpi_ut_is_pci_root_bridge(char *id); diff --git a/drivers/acpi/acpica/utexcep.c b/drivers/acpi/acpica/utexcep.c index a0ab7c02e87c..b543a144941a 100644 --- a/drivers/acpi/acpica/utexcep.c +++ b/drivers/acpi/acpica/utexcep.c @@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utexcep") ******************************************************************************/ const char *acpi_format_exception(acpi_status status) { - const char *exception = NULL; + const struct acpi_exception_info *exception; ACPI_FUNCTION_ENTRY(); @@ -76,10 +76,10 @@ const char *acpi_format_exception(acpi_status status) ACPI_ERROR((AE_INFO, "Unknown exception code: 0x%8.8X", status)); - exception = "UNKNOWN_STATUS_CODE"; + return ("UNKNOWN_STATUS_CODE"); } - return (ACPI_CAST_PTR(const char, exception)); + return (exception->name); } ACPI_EXPORT_SYMBOL(acpi_format_exception) @@ -97,10 +97,10 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception) * an ASCII string. * ******************************************************************************/ -const char *acpi_ut_validate_exception(acpi_status status) +const struct acpi_exception_info *acpi_ut_validate_exception(acpi_status status) { u32 sub_status; - const char *exception = NULL; + const struct acpi_exception_info *exception = NULL; ACPI_FUNCTION_ENTRY(); @@ -113,35 +113,35 @@ const char *acpi_ut_validate_exception(acpi_status status) case AE_CODE_ENVIRONMENTAL: if (sub_status <= AE_CODE_ENV_MAX) { - exception = acpi_gbl_exception_names_env[sub_status]; + exception = &acpi_gbl_exception_names_env[sub_status]; } break; case AE_CODE_PROGRAMMER: if (sub_status <= AE_CODE_PGM_MAX) { - exception = acpi_gbl_exception_names_pgm[sub_status]; + exception = &acpi_gbl_exception_names_pgm[sub_status]; } break; case AE_CODE_ACPI_TABLES: if (sub_status <= AE_CODE_TBL_MAX) { - exception = acpi_gbl_exception_names_tbl[sub_status]; + exception = &acpi_gbl_exception_names_tbl[sub_status]; } break; case AE_CODE_AML: if (sub_status <= AE_CODE_AML_MAX) { - exception = acpi_gbl_exception_names_aml[sub_status]; + exception = &acpi_gbl_exception_names_aml[sub_status]; } break; case AE_CODE_CONTROL: if (sub_status <= AE_CODE_CTRL_MAX) { - exception = acpi_gbl_exception_names_ctrl[sub_status]; + exception = &acpi_gbl_exception_names_ctrl[sub_status]; } break; @@ -149,5 +149,9 @@ const char *acpi_ut_validate_exception(acpi_status status) break; } - return (ACPI_CAST_PTR(const char, exception)); + if (!exception || !exception->name) { + return (NULL); + } + + return (exception); } diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 3e6b163ee15f..cf051e05a8fe 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -49,11 +49,12 @@ /* * Exception code classes */ -#define AE_CODE_ENVIRONMENTAL 0x0000 -#define AE_CODE_PROGRAMMER 0x1000 -#define AE_CODE_ACPI_TABLES 0x2000 -#define AE_CODE_AML 0x3000 -#define AE_CODE_CONTROL 0x4000 +#define AE_CODE_ENVIRONMENTAL 0x0000 /* General ACPICA environment */ +#define AE_CODE_PROGRAMMER 0x1000 /* External ACPICA interface caller */ +#define AE_CODE_ACPI_TABLES 0x2000 /* ACPI tables */ +#define AE_CODE_AML 0x3000 /* From executing AML code */ +#define AE_CODE_CONTROL 0x4000 /* Internal control codes */ + #define AE_CODE_MAX 0x4000 #define AE_CODE_MASK 0xF000 @@ -66,6 +67,24 @@ #define EXCEP_AML(code) ((acpi_status) (code | AE_CODE_AML)) #define EXCEP_CTL(code) ((acpi_status) (code | AE_CODE_CONTROL)) +/* + * Exception info table. The "Description" field is used only by the + * ACPICA help application (acpihelp). + */ +struct acpi_exception_info { + char *name; + +#ifdef ACPI_HELP_APP + char *description; +#endif +}; + +#ifdef ACPI_HELP_APP +#define EXCEP_TXT(name,description) {name, description} +#else +#define EXCEP_TXT(name,description) {name} +#endif + /* * Success is always zero, failure is non-zero */ @@ -202,112 +221,156 @@ * String versions of the exception codes above * These strings must match the corresponding defines exactly */ -char const *acpi_gbl_exception_names_env[] = { - "AE_OK", - "AE_ERROR", - "AE_NO_ACPI_TABLES", - "AE_NO_NAMESPACE", - "AE_NO_MEMORY", - "AE_NOT_FOUND", - "AE_NOT_EXIST", - "AE_ALREADY_EXISTS", - "AE_TYPE", - "AE_NULL_OBJECT", - "AE_NULL_ENTRY", - "AE_BUFFER_OVERFLOW", - "AE_STACK_OVERFLOW", - "AE_STACK_UNDERFLOW", - "AE_NOT_IMPLEMENTED", - "AE_SUPPORT", - "AE_LIMIT", - "AE_TIME", - "AE_ACQUIRE_DEADLOCK", - "AE_RELEASE_DEADLOCK", - "AE_NOT_ACQUIRED", - "AE_ALREADY_ACQUIRED", - "AE_NO_HARDWARE_RESPONSE", - "AE_NO_GLOBAL_LOCK", - "AE_ABORT_METHOD", - "AE_SAME_HANDLER", - "AE_NO_HANDLER", - "AE_OWNER_ID_LIMIT", - "AE_NOT_CONFIGURED" +static const struct acpi_exception_info acpi_gbl_exception_names_env[] = { + EXCEP_TXT("AE_OK", "No error"), + EXCEP_TXT("AE_ERROR", "Unspecified error"), + EXCEP_TXT("AE_NO_ACPI_TABLES", "ACPI tables could not be found"), + EXCEP_TXT("AE_NO_NAMESPACE", "A namespace has not been loaded"), + EXCEP_TXT("AE_NO_MEMORY", "Insufficient dynamic memory"), + EXCEP_TXT("AE_NOT_FOUND", "The name was not found in the namespace"), + EXCEP_TXT("AE_NOT_EXIST", "A required entity does not exist"), + EXCEP_TXT("AE_ALREADY_EXISTS", "An entity already exists"), + EXCEP_TXT("AE_TYPE", "The object type is incorrect"), + EXCEP_TXT("AE_NULL_OBJECT", "A required object was missing"), + EXCEP_TXT("AE_NULL_ENTRY", "The requested object does not exist"), + EXCEP_TXT("AE_BUFFER_OVERFLOW", "The buffer provided is too small"), + EXCEP_TXT("AE_STACK_OVERFLOW", "An internal stack overflowed"), + EXCEP_TXT("AE_STACK_UNDERFLOW", "An internal stack underflowed"), + EXCEP_TXT("AE_NOT_IMPLEMENTED", "The feature is not implemented"), + EXCEP_TXT("AE_SUPPORT", "The feature is not supported"), + EXCEP_TXT("AE_LIMIT", "A predefined limit was exceeded"), + EXCEP_TXT("AE_TIME", "A time limit or timeout expired"), + EXCEP_TXT("AE_ACQUIRE_DEADLOCK", + "Internal error, attempt was made to acquire a mutex in improper order"), + EXCEP_TXT("AE_RELEASE_DEADLOCK", + "Internal error, attempt was made to release a mutex in improper order"), + EXCEP_TXT("AE_NOT_ACQUIRED", + "An attempt to release a mutex or Global Lock without a previous acquire"), + EXCEP_TXT("AE_ALREADY_ACQUIRED", + "Internal error, attempt was made to acquire a mutex twice"), + EXCEP_TXT("AE_NO_HARDWARE_RESPONSE", + "Hardware did not respond after an I/O operation"), + EXCEP_TXT("AE_NO_GLOBAL_LOCK", "There is no FACS Global Lock"), + EXCEP_TXT("AE_ABORT_METHOD", "A control method was aborted"), + EXCEP_TXT("AE_SAME_HANDLER", + "Attempt was made to install the same handler that is already installed"), + EXCEP_TXT("AE_NO_HANDLER", + "A handler for the operation is not installed"), + EXCEP_TXT("AE_OWNER_ID_LIMIT", + "There are no more Owner IDs available for ACPI tables or control methods"), + EXCEP_TXT("AE_NOT_CONFIGURED", + "The interface is not part of the current subsystem configuration") }; -char const *acpi_gbl_exception_names_pgm[] = { - NULL, - "AE_BAD_PARAMETER", - "AE_BAD_CHARACTER", - "AE_BAD_PATHNAME", - "AE_BAD_DATA", - "AE_BAD_HEX_CONSTANT", - "AE_BAD_OCTAL_CONSTANT", - "AE_BAD_DECIMAL_CONSTANT", - "AE_MISSING_ARGUMENTS", - "AE_BAD_ADDRESS" +static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = { + EXCEP_TXT(NULL, NULL), + EXCEP_TXT("AE_BAD_PARAMETER", "A parameter is out of range or invalid"), + EXCEP_TXT("AE_BAD_CHARACTER", + "An invalid character was found in a name"), + EXCEP_TXT("AE_BAD_PATHNAME", + "An invalid character was found in a pathname"), + EXCEP_TXT("AE_BAD_DATA", + "A package or buffer contained incorrect data"), + EXCEP_TXT("AE_BAD_HEX_CONSTANT", "Invalid character in a Hex constant"), + EXCEP_TXT("AE_BAD_OCTAL_CONSTANT", + "Invalid character in an Octal constant"), + EXCEP_TXT("AE_BAD_DECIMAL_CONSTANT", + "Invalid character in a Decimal constant"), + EXCEP_TXT("AE_MISSING_ARGUMENTS", + "Too few arguments were passed to a control method"), + EXCEP_TXT("AE_BAD_ADDRESS", "An illegal null I/O address") }; -char const *acpi_gbl_exception_names_tbl[] = { - NULL, - "AE_BAD_SIGNATURE", - "AE_BAD_HEADER", - "AE_BAD_CHECKSUM", - "AE_BAD_VALUE", - "AE_INVALID_TABLE_LENGTH" +static const struct acpi_exception_info acpi_gbl_exception_names_tbl[] = { + EXCEP_TXT(NULL, NULL), + EXCEP_TXT("AE_BAD_SIGNATURE", "An ACPI table has an invalid signature"), + EXCEP_TXT("AE_BAD_HEADER", "Invalid field in an ACPI table header"), + EXCEP_TXT("AE_BAD_CHECKSUM", "An ACPI table checksum is not correct"), + EXCEP_TXT("AE_BAD_VALUE", "An invalid value was found in a table"), + EXCEP_TXT("AE_INVALID_TABLE_LENGTH", + "The FADT or FACS has improper length") }; -char const *acpi_gbl_exception_names_aml[] = { - NULL, - "AE_AML_BAD_OPCODE", - "AE_AML_NO_OPERAND", - "AE_AML_OPERAND_TYPE", - "AE_AML_OPERAND_VALUE", - "AE_AML_UNINITIALIZED_LOCAL", - "AE_AML_UNINITIALIZED_ARG", - "AE_AML_UNINITIALIZED_ELEMENT", - "AE_AML_NUMERIC_OVERFLOW", - "AE_AML_REGION_LIMIT", - "AE_AML_BUFFER_LIMIT", - "AE_AML_PACKAGE_LIMIT", - "AE_AML_DIVIDE_BY_ZERO", - "AE_AML_BAD_NAME", - "AE_AML_NAME_NOT_FOUND", - "AE_AML_INTERNAL", - "AE_AML_INVALID_SPACE_ID", - "AE_AML_STRING_LIMIT", - "AE_AML_NO_RETURN_VALUE", - "AE_AML_METHOD_LIMIT", - "AE_AML_NOT_OWNER", - "AE_AML_MUTEX_ORDER", - "AE_AML_MUTEX_NOT_ACQUIRED", - "AE_AML_INVALID_RESOURCE_TYPE", - "AE_AML_INVALID_INDEX", - "AE_AML_REGISTER_LIMIT", - "AE_AML_NO_WHILE", - "AE_AML_ALIGNMENT", - "AE_AML_NO_RESOURCE_END_TAG", - "AE_AML_BAD_RESOURCE_VALUE", - "AE_AML_CIRCULAR_REFERENCE", - "AE_AML_BAD_RESOURCE_LENGTH", - "AE_AML_ILLEGAL_ADDRESS", - "AE_AML_INFINITE_LOOP" +static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = { + EXCEP_TXT(NULL, NULL), + EXCEP_TXT("AE_AML_BAD_OPCODE", "Invalid AML opcode encountered"), + EXCEP_TXT("AE_AML_NO_OPERAND", "A required operand is missing"), + EXCEP_TXT("AE_AML_OPERAND_TYPE", + "An operand of an incorrect type was encountered"), + EXCEP_TXT("AE_AML_OPERAND_VALUE", + "The operand had an inappropriate or invalid value"), + EXCEP_TXT("AE_AML_UNINITIALIZED_LOCAL", + "Method tried to use an uninitialized local variable"), + EXCEP_TXT("AE_AML_UNINITIALIZED_ARG", + "Method tried to use an uninitialized argument"), + EXCEP_TXT("AE_AML_UNINITIALIZED_ELEMENT", + "Method tried to use an empty package element"), + EXCEP_TXT("AE_AML_NUMERIC_OVERFLOW", + "Overflow during BCD conversion or other"), + EXCEP_TXT("AE_AML_REGION_LIMIT", + "Tried to access beyond the end of an Operation Region"), + EXCEP_TXT("AE_AML_BUFFER_LIMIT", + "Tried to access beyond the end of a buffer"), + EXCEP_TXT("AE_AML_PACKAGE_LIMIT", + "Tried to access beyond the end of a package"), + EXCEP_TXT("AE_AML_DIVIDE_BY_ZERO", + "During execution of AML Divide operator"), + EXCEP_TXT("AE_AML_BAD_NAME", + "An ACPI name contains invalid character(s)"), + EXCEP_TXT("AE_AML_NAME_NOT_FOUND", + "Could not resolve a named reference"), + EXCEP_TXT("AE_AML_INTERNAL", "An internal error within the interprete"), + EXCEP_TXT("AE_AML_INVALID_SPACE_ID", + "An Operation Region SpaceID is invalid"), + EXCEP_TXT("AE_AML_STRING_LIMIT", + "String is longer than 200 characters"), + EXCEP_TXT("AE_AML_NO_RETURN_VALUE", + "A method did not return a required value"), + EXCEP_TXT("AE_AML_METHOD_LIMIT", + "A control method reached the maximum reentrancy limit of 255"), + EXCEP_TXT("AE_AML_NOT_OWNER", + "A thread tried to release a mutex that it does not own"), + EXCEP_TXT("AE_AML_MUTEX_ORDER", "Mutex SyncLevel release mismatch"), + EXCEP_TXT("AE_AML_MUTEX_NOT_ACQUIRED", + "Attempt to release a mutex that was not previously acquired"), + EXCEP_TXT("AE_AML_INVALID_RESOURCE_TYPE", + "Invalid resource type in resource list"), + EXCEP_TXT("AE_AML_INVALID_INDEX", + "Invalid Argx or Localx (x too large)"), + EXCEP_TXT("AE_AML_REGISTER_LIMIT", + "Bank value or Index value beyond range of register"), + EXCEP_TXT("AE_AML_NO_WHILE", "Break or Continue without a While"), + EXCEP_TXT("AE_AML_ALIGNMENT", + "Non-aligned memory transfer on platform that does not support this"), + EXCEP_TXT("AE_AML_NO_RESOURCE_END_TAG", + "No End Tag in a resource list"), + EXCEP_TXT("AE_AML_BAD_RESOURCE_VALUE", + "Invalid value of a resource element"), + EXCEP_TXT("AE_AML_CIRCULAR_REFERENCE", + "Two references refer to each other"), + EXCEP_TXT("AE_AML_BAD_RESOURCE_LENGTH", + "The length of a Resource Descriptor in the AML is incorrect"), + EXCEP_TXT("AE_AML_ILLEGAL_ADDRESS", + "A memory, I/O, or PCI configuration address is invalid"), + EXCEP_TXT("AE_AML_INFINITE_LOOP", + "An apparent infinite AML While loop, method was aborted") }; -char const *acpi_gbl_exception_names_ctrl[] = { - NULL, - "AE_CTRL_RETURN_VALUE", - "AE_CTRL_PENDING", - "AE_CTRL_TERMINATE", - "AE_CTRL_TRUE", - "AE_CTRL_FALSE", - "AE_CTRL_DEPTH", - "AE_CTRL_END", - "AE_CTRL_TRANSFER", - "AE_CTRL_BREAK", - "AE_CTRL_CONTINUE", - "AE_CTRL_SKIP", - "AE_CTRL_PARSE_CONTINUE", - "AE_CTRL_PARSE_PENDING" +static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = { + EXCEP_TXT(NULL, NULL), + EXCEP_TXT("AE_CTRL_RETURN_VALUE", "A Method returned a value"), + EXCEP_TXT("AE_CTRL_PENDING", "Method is calling another method"), + EXCEP_TXT("AE_CTRL_TERMINATE", "Terminate the executing method"), + EXCEP_TXT("AE_CTRL_TRUE", "An If or While predicate result"), + EXCEP_TXT("AE_CTRL_FALSE", "An If or While predicate result"), + EXCEP_TXT("AE_CTRL_DEPTH", "Maximum search depth has been reached"), + EXCEP_TXT("AE_CTRL_END", "An If or While predicate is false"), + EXCEP_TXT("AE_CTRL_TRANSFER", "Transfer control to called method"), + EXCEP_TXT("AE_CTRL_BREAK", "A Break has been executed"), + EXCEP_TXT("AE_CTRL_CONTINUE", "A Continue has been executed"), + EXCEP_TXT("AE_CTRL_SKIP", "Not currently used"), + EXCEP_TXT("AE_CTRL_PARSE_CONTINUE", "Used to skip over bad opcodes"), + EXCEP_TXT("AE_CTRL_PARSE_PENDING", "Used to implement AML While loops") }; #endif /* EXCEPTION_TABLE */ -- cgit From d5a36100f62fa6db5541344e08b361b34e9114c5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:23:03 +0000 Subject: ACPICA: Add mechanism for early object repairs on a per-name basis Adds the framework to allow object repairs very early in the return object analysis. Enables repairs like string->unicode, etc. Bob Moore, Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 15 +++++ drivers/acpi/acpica/acnamesp.h | 2 +- drivers/acpi/acpica/nspredef.c | 141 +++++++++++++++++++--------------------- drivers/acpi/acpica/nsrepair.c | 134 ++++++++++++++++++++++++++++++++++++-- drivers/acpi/acpica/nsrepair2.c | 16 ++--- 5 files changed, 221 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 805f419086ab..9d45f976a31e 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -363,6 +363,7 @@ struct acpi_predefined_data { union acpi_operand_object *parent_package; struct acpi_namespace_node *node; u32 flags; + u32 return_btype; u8 node_flags; }; @@ -371,6 +372,20 @@ struct acpi_predefined_data { #define ACPI_OBJECT_REPAIRED 1 #define ACPI_OBJECT_WRAPPED 2 +/* Return object auto-repair info */ + +typedef acpi_status(*acpi_object_converter) (union acpi_operand_object + *original_object, + union acpi_operand_object + **converted_object); + +struct acpi_simple_repair_info { + char name[ACPI_NAME_SIZE]; + u32 unexpected_btypes; + u32 package_index; + acpi_object_converter object_converter; +}; + /* * Bitmapped return value types * Note: the actual data types must be contiguous, a loop in nspredef.c diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 02cd5482ff8b..dec6e9ec2e0c 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -289,7 +289,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, * predefined methods/objects */ acpi_status -acpi_ns_repair_object(struct acpi_predefined_data *data, +acpi_ns_simple_repair(struct acpi_predefined_data *data, u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr); diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 224c30053401..36f724085dca 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -78,6 +78,8 @@ acpi_ns_check_reference(struct acpi_predefined_data *data, static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); +static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object); + /* * Names for the types that can be returned by the predefined objects. * Used for warning messages. Must be in the same order as the ACPI_RTYPEs @@ -112,7 +114,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, acpi_status return_status, union acpi_operand_object **return_object_ptr) { - union acpi_operand_object *return_object = *return_object_ptr; acpi_status status = AE_OK; const union acpi_predefined_info *predefined; char *pathname; @@ -151,25 +152,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, goto cleanup; } - /* - * If there is no return value, check if we require a return value for - * this predefined name. Either one return value is expected, or none, - * for both methods and other objects. - * - * Exit now if there is no return object. Warning if one was expected. - */ - if (!return_object) { - if ((predefined->info.expected_btypes) && - (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_WARN_PREDEFINED((AE_INFO, pathname, - ACPI_WARN_ALWAYS, - "Missing expected return value")); - - status = AE_AML_NO_RETURN_VALUE; - } - goto cleanup; - } - /* * Return value validation and possible repair. * @@ -410,28 +392,12 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, { union acpi_operand_object *return_object = *return_object_ptr; acpi_status status = AE_OK; - u32 return_btype; char type_buffer[48]; /* Room for 5 types */ - /* - * If we get a NULL return_object here, it is a NULL package element. - * Since all extraneous NULL package elements were removed earlier by a - * call to acpi_ns_remove_null_elements, this is an unexpected NULL element. - * We will attempt to repair it. - */ - if (!return_object) { - status = acpi_ns_repair_null_element(data, expected_btypes, - package_index, - return_object_ptr); - if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ - } - goto type_error_exit; - } - /* A Namespace node should not get here, but make sure */ - if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { + if (return_object && + ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, "Invalid return type - Found a Namespace node [%4.4s] type %s", return_object->node.name.ascii, @@ -448,53 +414,25 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data, * from all of the predefined names (including elements of returned * packages) */ - switch (return_object->common.type) { - case ACPI_TYPE_INTEGER: - return_btype = ACPI_RTYPE_INTEGER; - break; - - case ACPI_TYPE_BUFFER: - return_btype = ACPI_RTYPE_BUFFER; - break; - - case ACPI_TYPE_STRING: - return_btype = ACPI_RTYPE_STRING; - break; + data->return_btype = acpi_ns_get_bitmapped_type(return_object); + if (data->return_btype == ACPI_RTYPE_ANY) { - case ACPI_TYPE_PACKAGE: - return_btype = ACPI_RTYPE_PACKAGE; - break; - - case ACPI_TYPE_LOCAL_REFERENCE: - return_btype = ACPI_RTYPE_REFERENCE; - break; - - default: /* Not one of the supported objects, must be incorrect */ - goto type_error_exit; } - /* Is the object one of the expected types? */ - - if (return_btype & expected_btypes) { - - /* For reference objects, check that the reference type is correct */ - - if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(data, return_object); - } + /* For reference objects, check that the reference type is correct */ + if ((data->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) { + status = acpi_ns_check_reference(data, return_object); return (status); } - /* Type mismatch -- attempt repair of the returned object */ + /* Attempt simple repair of the returned object if necessary */ - status = acpi_ns_repair_object(data, expected_btypes, + status = acpi_ns_simple_repair(data, expected_btypes, package_index, return_object_ptr); - if (ACPI_SUCCESS(status)) { - return (AE_OK); /* Repair was successful */ - } + return (status); type_error_exit: @@ -556,6 +494,61 @@ acpi_ns_check_reference(struct acpi_predefined_data *data, return (AE_AML_OPERAND_TYPE); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_bitmapped_type + * + * PARAMETERS: return_object - Object returned from method/obj evaluation + * + * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object + * type is not supported. ACPI_RTYPE_NONE indicates that no + * object was returned (return_object is NULL). + * + * DESCRIPTION: Convert object type into a bitmapped object return type. + * + ******************************************************************************/ + +static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object) +{ + u32 return_btype; + + if (!return_object) { + return (ACPI_RTYPE_NONE); + } + + /* Map acpi_object_type to internal bitmapped type */ + + switch (return_object->common.type) { + case ACPI_TYPE_INTEGER: + return_btype = ACPI_RTYPE_INTEGER; + break; + + case ACPI_TYPE_BUFFER: + return_btype = ACPI_RTYPE_BUFFER; + break; + + case ACPI_TYPE_STRING: + return_btype = ACPI_RTYPE_STRING; + break; + + case ACPI_TYPE_PACKAGE: + return_btype = ACPI_RTYPE_PACKAGE; + break; + + case ACPI_TYPE_LOCAL_REFERENCE: + return_btype = ACPI_RTYPE_REFERENCE; + break; + + default: + /* Not one of the supported objects, must be incorrect */ + + return_btype = ACPI_RTYPE_ANY; + break; + } + + return (return_btype); +} + /******************************************************************************* * * FUNCTION: acpi_ns_get_expected_types diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 9e833353c06a..f9c9fd45cd1f 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -46,6 +46,7 @@ #include "acnamesp.h" #include "acinterp.h" #include "acpredef.h" +#include "amlresrc.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsrepair") @@ -71,6 +72,11 @@ ACPI_MODULE_NAME("nsrepair") * Buffer -> String * Buffer -> Package of Integers * Package -> Package of one Package + * + * Additional conversions that are available: + * Convert a null return or zero return value to an end_tag descriptor + * Convert an ASCII string to a Unicode buffer + * * An incorrect standalone object is wrapped with required outer package * * Additional possible repairs: @@ -90,9 +96,26 @@ static acpi_status acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, union acpi_operand_object **return_object); +static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct + acpi_namespace_node + *node, + u32 + return_btype, + u32 + package_index); + +/* + * Special but simple repairs for some names. + * + * 2nd argument: Unexpected types that can be repaired + */ +static const struct acpi_simple_repair_info acpi_object_repair_info[] = { + {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */ +}; + /******************************************************************************* * - * FUNCTION: acpi_ns_repair_object + * FUNCTION: acpi_ns_simple_repair * * PARAMETERS: data - Pointer to validation data structure * expected_btypes - Object types expected @@ -110,16 +133,54 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, ******************************************************************************/ acpi_status -acpi_ns_repair_object(struct acpi_predefined_data *data, +acpi_ns_simple_repair(struct acpi_predefined_data *data, u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr) { union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object *new_object; + union acpi_operand_object *new_object = NULL; acpi_status status; + const struct acpi_simple_repair_info *predefined; - ACPI_FUNCTION_NAME(ns_repair_object); + ACPI_FUNCTION_NAME(ns_simple_repair); + + /* + * Special repairs for certain names that are in the repair table. + * Check if this name is in the list of repairable names. + */ + predefined = acpi_ns_match_simple_repair(data->node, + data->return_btype, + package_index); + if (predefined) { + if (!return_object) { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); + } + + status = + predefined->object_converter(return_object, &new_object); + if (ACPI_FAILURE(status)) { + + /* A fatal error occurred during a conversion */ + + ACPI_EXCEPTION((AE_INFO, status, + "During return object analysis")); + return (status); + } + if (new_object) { + goto object_repaired; + } + } + + /* + * Do not perform simple object repair unless the return type is not + * expected. + */ + if (data->return_btype & expected_btypes) { + return (AE_OK); + } /* * At this point, we know that the type of the returned object was not @@ -127,6 +188,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, * repair the object by converting it to one of the expected object * types for this predefined name. */ + + /* + * If there is no return value, check if we require a return value for + * this predefined name. Either one return value is expected, or none, + * for both methods and other objects. + * + * Exit now if there is no return object. Warning if one was expected. + */ + if (!return_object) { + if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); + + return (AE_AML_NO_RETURN_VALUE); + } + } + if (expected_btypes & ACPI_RTYPE_INTEGER) { status = acpi_ns_convert_to_integer(return_object, &new_object); if (ACPI_SUCCESS(status)) { @@ -216,6 +295,53 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, return (AE_OK); } +/****************************************************************************** + * + * FUNCTION: acpi_ns_match_simple_repair + * + * PARAMETERS: node - Namespace node for the method/object + * return_btype - Object type that was returned + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) + * + * RETURN: Pointer to entry in repair table. NULL indicates not found. + * + * DESCRIPTION: Check an object name against the repairable object list. + * + *****************************************************************************/ + +static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct + acpi_namespace_node + *node, + u32 + return_btype, + u32 + package_index) +{ + const struct acpi_simple_repair_info *this_name; + + /* Search info table for a repairable predefined method/object name */ + + this_name = acpi_object_repair_info; + while (this_name->object_converter) { + if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) { + + /* Check if we can actually repair this name/type combination */ + + if ((return_btype & this_name->unexpected_btypes) && + (package_index == this_name->package_index)) { + return (this_name); + } + + return (NULL); + } + this_name++; + } + + return (NULL); /* Name was not found in the repair table */ +} + /******************************************************************************* * * FUNCTION: acpi_ns_convert_to_integer diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index ba4d98287c6a..149e9b9c2c1b 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -66,9 +66,9 @@ typedef struct acpi_repair_info { /* Local prototypes */ -static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct - acpi_namespace_node - *node); +static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct + acpi_namespace_node + *node); static acpi_status acpi_ns_repair_ALR(struct acpi_predefined_data *data, @@ -175,7 +175,7 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data, /* Check if this name is in the list of repairable names */ - predefined = acpi_ns_match_repairable_name(node); + predefined = acpi_ns_match_complex_repair(node); if (!predefined) { return (validate_status); } @@ -186,7 +186,7 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data, /****************************************************************************** * - * FUNCTION: acpi_ns_match_repairable_name + * FUNCTION: acpi_ns_match_complex_repair * * PARAMETERS: node - Namespace node for the method/object * @@ -196,9 +196,9 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data, * *****************************************************************************/ -static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct - acpi_namespace_node - *node) +static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct + acpi_namespace_node + *node) { const struct acpi_repair_info *this_name; -- cgit From 76a6225bf0b64572251a8c27d33e84afac6af713 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:23:16 +0000 Subject: ACPICA: Split object conversion functions to a new file New file, nsconvert.c, for return object conversion functions. Created in preparation for new conversion functions forthcoming. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 1 + drivers/acpi/acpica/acnamesp.h | 15 ++ drivers/acpi/acpica/nsconvert.c | 302 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/nsrepair.c | 262 ---------------------------------- 4 files changed, 318 insertions(+), 262 deletions(-) create mode 100644 drivers/acpi/acpica/nsconvert.c (limited to 'drivers') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a1b9bf5085a2..5a542c8db942 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o acpi-y += \ nsaccess.o \ nsalloc.o \ + nsconvert.o \ nsdump.o \ nseval.o \ nsinit.o \ diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index dec6e9ec2e0c..7156bc75ebe0 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -166,6 +166,21 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent); int acpi_ns_compare_names(char *name1, char *name2); +/* + * nsconvert - Dynamic object conversion routines + */ +acpi_status +acpi_ns_convert_to_integer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_string(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + /* * nsdump - Namespace dump/print utilities */ diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c new file mode 100644 index 000000000000..fcb7dfb494cd --- /dev/null +++ b/drivers/acpi/acpica/nsconvert.c @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * Module Name: nsconvert - Object conversions for objects returned by + * predefined methods + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2013, Intel Corp. + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + */ + +#include +#include "accommon.h" +#include "acnamesp.h" +#include "acinterp.h" +#include "acpredef.h" +#include "amlresrc.h" + +#define _COMPONENT ACPI_NAMESPACE +ACPI_MODULE_NAME("nsconvert") + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_integer + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. + * + ******************************************************************************/ +acpi_status +acpi_ns_convert_to_integer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_status status; + u64 value = 0; + u32 i; + + switch (original_object->common.type) { + case ACPI_TYPE_STRING: + + /* String-to-Integer conversion */ + + status = acpi_ut_strtoul64(original_object->string.pointer, + ACPI_ANY_BASE, &value); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ + + if (original_object->buffer.length > 8) { + return (AE_AML_OPERAND_TYPE); + } + + /* Extract each buffer byte to create the integer */ + + for (i = 0; i < original_object->buffer.length; i++) { + value |= + ((u64)original_object->buffer. + pointer[i] << (i * 8)); + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + new_object = acpi_ut_create_integer_object(value); + if (!new_object) { + return (AE_NO_MEMORY); + } + + *return_object = new_object; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_string + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_string(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_size length; + acpi_status status; + + switch (original_object->common.type) { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-String conversion. Commonly, convert + * an integer of value 0 to a NULL string. The last element of + * _BIF and _BIX packages occasionally need this fix. + */ + if (original_object->integer.value == 0) { + + /* Allocate a new NULL string object */ + + new_object = acpi_ut_create_string_object(0); + if (!new_object) { + return (AE_NO_MEMORY); + } + } else { + status = + acpi_ex_convert_to_string(original_object, + &new_object, + ACPI_IMPLICIT_CONVERT_HEX); + if (ACPI_FAILURE(status)) { + return (status); + } + } + break; + + case ACPI_TYPE_BUFFER: + /* + * Buffer-to-String conversion. Use a to_string + * conversion, no transform performed on the buffer data. The best + * example of this is the _BIF method, where the string data from + * the battery is often (incorrectly) returned as buffer object(s). + */ + length = 0; + while ((length < original_object->buffer.length) && + (original_object->buffer.pointer[length])) { + length++; + } + + /* Allocate a new string object */ + + new_object = acpi_ut_create_string_object(length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY(new_object->string.pointer, + original_object->buffer.pointer, length); + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *return_object = new_object; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_buffer + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + acpi_status status; + union acpi_operand_object **elements; + u32 *dword_buffer; + u32 count; + u32 i; + + switch (original_object->common.type) { + case ACPI_TYPE_INTEGER: + /* + * Integer-to-Buffer conversion. + * Convert the Integer to a packed-byte buffer. _MAT and other + * objects need this sometimes, if a read has been performed on a + * Field object that is less than or equal to the global integer + * size (32 or 64 bits). + */ + status = + acpi_ex_convert_to_buffer(original_object, &new_object); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_TYPE_STRING: + + /* String-to-Buffer conversion. Simple data copy */ + + new_object = + acpi_ut_create_buffer_object(original_object->string. + length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY(new_object->buffer.pointer, + original_object->string.pointer, + original_object->string.length); + break; + + case ACPI_TYPE_PACKAGE: + /* + * This case is often seen for predefined names that must return a + * Buffer object with multiple DWORD integers within. For example, + * _FDE and _GTM. The Package can be converted to a Buffer. + */ + + /* All elements of the Package must be integers */ + + elements = original_object->package.elements; + count = original_object->package.count; + + for (i = 0; i < count; i++) { + if ((!*elements) || + ((*elements)->common.type != ACPI_TYPE_INTEGER)) { + return (AE_AML_OPERAND_TYPE); + } + elements++; + } + + /* Create the new buffer object to replace the Package */ + + new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* Copy the package elements (integers) to the buffer as DWORDs */ + + elements = original_object->package.elements; + dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); + + for (i = 0; i < count; i++) { + *dword_buffer = (u32)(*elements)->integer.value; + dword_buffer++; + elements++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *return_object = new_object; + return (AE_OK); +} diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index f9c9fd45cd1f..c5e828f4ed0b 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -84,18 +84,6 @@ ACPI_MODULE_NAME("nsrepair") * ******************************************************************************/ /* Local prototypes */ -static acpi_status -acpi_ns_convert_to_integer(union acpi_operand_object *original_object, - union acpi_operand_object **return_object); - -static acpi_status -acpi_ns_convert_to_string(union acpi_operand_object *original_object, - union acpi_operand_object **return_object); - -static acpi_status -acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, - union acpi_operand_object **return_object); - static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct acpi_namespace_node *node, @@ -342,256 +330,6 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct return (NULL); /* Name was not found in the repair table */ } -/******************************************************************************* - * - * FUNCTION: acpi_ns_convert_to_integer - * - * PARAMETERS: original_object - Object to be converted - * return_object - Where the new converted object is returned - * - * RETURN: Status. AE_OK if conversion was successful. - * - * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_convert_to_integer(union acpi_operand_object *original_object, - union acpi_operand_object **return_object) -{ - union acpi_operand_object *new_object; - acpi_status status; - u64 value = 0; - u32 i; - - switch (original_object->common.type) { - case ACPI_TYPE_STRING: - - /* String-to-Integer conversion */ - - status = acpi_ut_strtoul64(original_object->string.pointer, - ACPI_ANY_BASE, &value); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_TYPE_BUFFER: - - /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ - - if (original_object->buffer.length > 8) { - return (AE_AML_OPERAND_TYPE); - } - - /* Extract each buffer byte to create the integer */ - - for (i = 0; i < original_object->buffer.length; i++) { - value |= - ((u64) original_object->buffer. - pointer[i] << (i * 8)); - } - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - new_object = acpi_ut_create_integer_object(value); - if (!new_object) { - return (AE_NO_MEMORY); - } - - *return_object = new_object; - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_convert_to_string - * - * PARAMETERS: original_object - Object to be converted - * return_object - Where the new converted object is returned - * - * RETURN: Status. AE_OK if conversion was successful. - * - * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_convert_to_string(union acpi_operand_object *original_object, - union acpi_operand_object **return_object) -{ - union acpi_operand_object *new_object; - acpi_size length; - acpi_status status; - - switch (original_object->common.type) { - case ACPI_TYPE_INTEGER: - /* - * Integer-to-String conversion. Commonly, convert - * an integer of value 0 to a NULL string. The last element of - * _BIF and _BIX packages occasionally need this fix. - */ - if (original_object->integer.value == 0) { - - /* Allocate a new NULL string object */ - - new_object = acpi_ut_create_string_object(0); - if (!new_object) { - return (AE_NO_MEMORY); - } - } else { - status = - acpi_ex_convert_to_string(original_object, - &new_object, - ACPI_IMPLICIT_CONVERT_HEX); - if (ACPI_FAILURE(status)) { - return (status); - } - } - break; - - case ACPI_TYPE_BUFFER: - /* - * Buffer-to-String conversion. Use a to_string - * conversion, no transform performed on the buffer data. The best - * example of this is the _BIF method, where the string data from - * the battery is often (incorrectly) returned as buffer object(s). - */ - length = 0; - while ((length < original_object->buffer.length) && - (original_object->buffer.pointer[length])) { - length++; - } - - /* Allocate a new string object */ - - new_object = acpi_ut_create_string_object(length); - if (!new_object) { - return (AE_NO_MEMORY); - } - - /* - * Copy the raw buffer data with no transform. String is already NULL - * terminated at Length+1. - */ - ACPI_MEMCPY(new_object->string.pointer, - original_object->buffer.pointer, length); - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - *return_object = new_object; - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_convert_to_buffer - * - * PARAMETERS: original_object - Object to be converted - * return_object - Where the new converted object is returned - * - * RETURN: Status. AE_OK if conversion was successful. - * - * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, - union acpi_operand_object **return_object) -{ - union acpi_operand_object *new_object; - acpi_status status; - union acpi_operand_object **elements; - u32 *dword_buffer; - u32 count; - u32 i; - - switch (original_object->common.type) { - case ACPI_TYPE_INTEGER: - /* - * Integer-to-Buffer conversion. - * Convert the Integer to a packed-byte buffer. _MAT and other - * objects need this sometimes, if a read has been performed on a - * Field object that is less than or equal to the global integer - * size (32 or 64 bits). - */ - status = - acpi_ex_convert_to_buffer(original_object, &new_object); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_TYPE_STRING: - - /* String-to-Buffer conversion. Simple data copy */ - - new_object = - acpi_ut_create_buffer_object(original_object->string. - length); - if (!new_object) { - return (AE_NO_MEMORY); - } - - ACPI_MEMCPY(new_object->buffer.pointer, - original_object->string.pointer, - original_object->string.length); - break; - - case ACPI_TYPE_PACKAGE: - /* - * This case is often seen for predefined names that must return a - * Buffer object with multiple DWORD integers within. For example, - * _FDE and _GTM. The Package can be converted to a Buffer. - */ - - /* All elements of the Package must be integers */ - - elements = original_object->package.elements; - count = original_object->package.count; - - for (i = 0; i < count; i++) { - if ((!*elements) || - ((*elements)->common.type != ACPI_TYPE_INTEGER)) { - return (AE_AML_OPERAND_TYPE); - } - elements++; - } - - /* Create the new buffer object to replace the Package */ - - new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); - if (!new_object) { - return (AE_NO_MEMORY); - } - - /* Copy the package elements (integers) to the buffer as DWORDs */ - - elements = original_object->package.elements; - dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); - - for (i = 0; i < count; i++) { - *dword_buffer = (u32) (*elements)->integer.value; - dword_buffer++; - elements++; - } - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - *return_object = new_object; - return (AE_OK); -} - /******************************************************************************* * * FUNCTION: acpi_ns_repair_null_element -- cgit From 96b44cc684b315dbcf77191809df011067f2e206 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 8 Mar 2013 09:23:24 +0000 Subject: ACPICA: Return object repair: Add string-to-unicode conversion Used for the _STR and _MLS predefined names. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acnamesp.h | 4 +++ drivers/acpi/acpica/nsconvert.c | 64 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/nsrepair.c | 7 +++++ 3 files changed, 75 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 7156bc75ebe0..b6ee5192f2ae 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -181,6 +181,10 @@ acpi_status acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, union acpi_operand_object **return_object); +acpi_status +acpi_ns_convert_to_unicode(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + /* * nsdump - Namespace dump/print utilities */ diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index fcb7dfb494cd..84f66994256f 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c @@ -300,3 +300,67 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, *return_object = new_object; return (AE_OK); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_unicode + * + * PARAMETERS: original_object - ASCII String Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a String object to a Unicode string Buffer. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_unicode(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + char *ascii_string; + u16 *unicode_buffer; + u32 unicode_length; + u32 i; + + if (!original_object) { + return (AE_OK); + } + + /* If a Buffer was returned, it must be at least two bytes long */ + + if (original_object->common.type == ACPI_TYPE_BUFFER) { + if (original_object->buffer.length < 2) { + return (AE_AML_OPERAND_VALUE); + } + + *return_object = NULL; + return (AE_OK); + } + + /* + * The original object is an ASCII string. Convert this string to + * a unicode buffer. + */ + ascii_string = original_object->string.pointer; + unicode_length = (original_object->string.length * 2) + 2; + + /* Create a new buffer object for the Unicode data */ + + new_object = acpi_ut_create_buffer_object(unicode_length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + unicode_buffer = ACPI_CAST_PTR(u16, new_object->buffer.pointer); + + /* Convert ASCII to Unicode */ + + for (i = 0; i < original_object->string.length; i++) { + unicode_buffer[i] = (u16)ascii_string[i]; + } + + *return_object = new_object; + return (AE_OK); +} diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index c5e828f4ed0b..a1918fdf92f2 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -98,6 +98,13 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct * 2nd argument: Unexpected types that can be repaired */ static const struct acpi_simple_repair_info acpi_object_repair_info[] = { + /* Unicode conversions */ + + {"_MLS", ACPI_RTYPE_STRING, 1, + acpi_ns_convert_to_unicode}, + {"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, + ACPI_NOT_PACKAGE_ELEMENT, + acpi_ns_convert_to_unicode}, {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */ }; -- cgit From 88fd0ac831095f52691810a3b832e884766c657e Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 8 Mar 2013 09:23:32 +0000 Subject: ACPICA: Return object repair: Add resource template repairs Fixes several possible problems with resource templates returned by _CRS/_PRS/_DMA predefined names. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acnamesp.h | 4 +++ drivers/acpi/acpica/nsconvert.c | 77 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/nsrepair.c | 18 ++++++++++ 3 files changed, 99 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index b6ee5192f2ae..6475962a7f2d 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -185,6 +185,10 @@ acpi_status acpi_ns_convert_to_unicode(union acpi_operand_object *original_object, union acpi_operand_object **return_object); +acpi_status +acpi_ns_convert_to_resource(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + /* * nsdump - Namespace dump/print utilities */ diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index 84f66994256f..8f79a9d2d50e 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c @@ -364,3 +364,80 @@ acpi_ns_convert_to_unicode(union acpi_operand_object *original_object, *return_object = new_object; return (AE_OK); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_resource + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful + * + * DESCRIPTION: Attempt to convert a Integer object to a resource_template + * Buffer. + * + ******************************************************************************/ + +acpi_status +acpi_ns_convert_to_resource(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + u8 *buffer; + + /* + * We can fix the following cases for an expected resource template: + * 1. No return value (interpreter slack mode is disabled) + * 2. A "Return (Zero)" statement + * 3. A "Return empty buffer" statement + * + * We will return a buffer containing a single end_tag + * resource descriptor. + */ + if (original_object) { + switch (original_object->common.type) { + case ACPI_TYPE_INTEGER: + + /* We can only repair an Integer==0 */ + + if (original_object->integer.value) { + return (AE_AML_OPERAND_TYPE); + } + break; + + case ACPI_TYPE_BUFFER: + + if (original_object->buffer.length) { + + /* Additional checks can be added in the future */ + + *return_object = NULL; + return (AE_OK); + } + break; + + case ACPI_TYPE_STRING: + default: + + return (AE_AML_OPERAND_TYPE); + } + } + + /* Create the new buffer object for the resource descriptor */ + + new_object = acpi_ut_create_buffer_object(2); + if (!new_object) { + return (AE_NO_MEMORY); + } + + buffer = ACPI_CAST_PTR(u8, new_object->buffer.pointer); + + /* Initialize the Buffer with a single end_tag descriptor */ + + buffer[0] = (ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE); + buffer[1] = 0x00; + + *return_object = new_object; + return (AE_OK); +} diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index a1918fdf92f2..18f02e4ece01 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -98,6 +98,24 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct * 2nd argument: Unexpected types that can be repaired */ static const struct acpi_simple_repair_info acpi_object_repair_info[] = { + /* Resource descriptor conversions */ + + {"_CRS", + ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | + ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + acpi_ns_convert_to_resource}, + {"_DMA", + ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | + ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + acpi_ns_convert_to_resource}, + {"_PRS", + ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | + ACPI_RTYPE_NONE, + ACPI_NOT_PACKAGE_ELEMENT, + acpi_ns_convert_to_resource}, + /* Unicode conversions */ {"_MLS", ACPI_RTYPE_STRING, 1, -- cgit From 40411255c89eb382ed695933155a606c000d855e Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:23:39 +0000 Subject: ACPICA: Disassembler: Add warnings for unresolved control methods Flags the case where external control methods are unresolved, meaning that the disassembler had no idea how many arguments to parse for the method invocation. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 ++ drivers/acpi/acpica/aclocal.h | 1 + drivers/acpi/acpica/utglobal.c | 2 ++ 3 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index feaa5d5ef579..833fbc5be2d6 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -417,6 +417,8 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; +ACPI_EXTERN u8 acpi_gbl_num_external_methods; +ACPI_EXTERN u32 acpi_gbl_resolved_external_methods; ACPI_EXTERN struct acpi_external_list *acpi_gbl_external_list; ACPI_EXTERN struct acpi_external_file *acpi_gbl_external_file_list; #endif diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 9d45f976a31e..636658ffc9b1 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1052,6 +1052,7 @@ struct acpi_external_list { u16 length; u8 type; u8 flags; + u8 resolved; }; /* Values for Flags field above */ diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index ffecf4b4f0dd..f736448a8606 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -359,6 +359,8 @@ acpi_status acpi_ut_init_globals(void) #ifdef ACPI_DISASSEMBLER acpi_gbl_external_list = NULL; + acpi_gbl_num_external_methods = 0; + acpi_gbl_resolved_external_methods = 0; #endif #ifdef ACPI_DEBUG_OUTPUT -- cgit From 02d4fb36867c33f7e0cec8d6e6dad47ad712a497 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 8 Mar 2013 09:23:51 +0000 Subject: ACPICA: Object repair: Allow 0-length packages for variable-length packages For the predefined names that return fully variable-length packages, allow a zero-length package with no warning, since it is technically a legal construct (and BIOS writers use it.) Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsprepkg.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index a40155467d2e..77cdd539de16 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c @@ -112,9 +112,15 @@ acpi_ns_check_package(struct acpi_predefined_data *data, elements = return_object->package.elements; count = return_object->package.count; - /* The package must have at least one element, else invalid */ - + /* + * Most packages must have at least one element. The only exception + * is the variable-length package (ACPI_PTYPE1_VAR). + */ if (!count) { + if (package->ret_info.type == ACPI_PTYPE1_VAR) { + return (AE_OK); + } + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, "Return Package has no elements (empty)")); -- cgit From 56f5b1cff22a1d6eeb3f7fc6981b8a55af43332b Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 11 Mar 2013 17:47:58 -0700 Subject: staging: Core files for the DWC2 driver The core code provides basic services for accessing and managing the DWC_otg hardware. These services are used by both the Host Controller Driver and (in future) the Peripheral Controller Driver. Signed-off-by: Paul Zimmerman Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/core.c | 2678 ++++++++++++++++++++++++++++++++++++++ drivers/staging/dwc2/core.h | 658 ++++++++++ drivers/staging/dwc2/core_intr.c | 505 +++++++ drivers/staging/dwc2/hw.h | 811 ++++++++++++ 4 files changed, 4652 insertions(+) create mode 100644 drivers/staging/dwc2/core.c create mode 100644 drivers/staging/dwc2/core.h create mode 100644 drivers/staging/dwc2/core_intr.c create mode 100644 drivers/staging/dwc2/hw.h (limited to 'drivers') diff --git a/drivers/staging/dwc2/core.c b/drivers/staging/dwc2/core.c new file mode 100644 index 000000000000..f695a9b08f29 --- /dev/null +++ b/drivers/staging/dwc2/core.c @@ -0,0 +1,2678 @@ +/* + * core.c - DesignWare HS OTG Controller common routines + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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. + */ + +/* + * The Core code provides basic services for accessing and managing the + * DWC_otg hardware. These services are used by both the Host Controller + * Driver and the Peripheral Controller Driver. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +/** + * dwc2_enable_common_interrupts() - Initializes the commmon interrupts, + * used in both device and host modes + * + * @hsotg: Programming view of the DWC_otg controller + */ +static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) +{ + u32 intmsk; + + /* Clear any pending OTG Interrupts */ + writel(0xffffffff, hsotg->regs + GOTGINT); + + /* Clear any pending interrupts */ + writel(0xffffffff, hsotg->regs + GINTSTS); + + /* Enable the interrupts in the GINTMSK */ + intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT; + + if (hsotg->core_params->dma_enable <= 0) + intmsk |= GINTSTS_RXFLVL; + + intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP | + GINTSTS_SESSREQINT; + + writel(intmsk, hsotg->regs + GINTMSK); +} + +/* + * Initializes the FSLSPClkSel field of the HCFG register depending on the + * PHY type + */ +static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) +{ + u32 hs_phy_type = hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK; + u32 fs_phy_type = hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK; + u32 hcfg, val; + + if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && + fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && + hsotg->core_params->ulpi_fs_ls > 0) || + hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { + /* Full speed PHY */ + val = HCFG_FSLSPCLKSEL_48_MHZ; + } else { + /* High speed PHY running at full speed or high speed */ + val = HCFG_FSLSPCLKSEL_30_60_MHZ; + } + + dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val); + hcfg = readl(hsotg->regs + HCFG); + hcfg &= ~HCFG_FSLSPCLKSEL_MASK; + hcfg |= val; + writel(hcfg, hsotg->regs + HCFG); +} + +/* + * Do core a soft reset of the core. Be careful with this because it + * resets all the internal state machines of the core. + */ +static void dwc2_core_reset(struct dwc2_hsotg *hsotg) +{ + u32 greset; + int count = 0; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + /* Wait for AHB master IDLE state */ + do { + usleep_range(20000, 40000); + greset = readl(hsotg->regs + GRSTCTL); + if (++count > 50) { + dev_warn(hsotg->dev, + "%s() HANG! AHB Idle GRSTCTL=%0x\n", + __func__, greset); + return; + } + } while (!(greset & GRSTCTL_AHBIDLE)); + + /* Core Soft Reset */ + count = 0; + greset |= GRSTCTL_CSFTRST; + writel(greset, hsotg->regs + GRSTCTL); + do { + usleep_range(20000, 40000); + greset = readl(hsotg->regs + GRSTCTL); + if (++count > 50) { + dev_warn(hsotg->dev, + "%s() HANG! Soft Reset GRSTCTL=%0x\n", + __func__, greset); + break; + } + } while (greset & GRSTCTL_CSFTRST); + + /* + * NOTE: This long sleep is _very_ important, otherwise the core will + * not stay in host mode after a connector ID change! + */ + usleep_range(150000, 200000); +} + +static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +{ + u32 usbcfg, i2cctl; + + /* + * core_init() is now called on every switch so only call the + * following for the first time through + */ + if (select_phy) { + dev_dbg(hsotg->dev, "FS PHY selected\n"); + usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg |= GUSBCFG_PHYSEL; + writel(usbcfg, hsotg->regs + GUSBCFG); + + /* Reset after a PHY select */ + dwc2_core_reset(hsotg); + } + + /* + * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also + * do this on HNP Dev/Host mode switches (done in dev_init and + * host_init). + */ + if (dwc2_is_host_mode(hsotg)) + dwc2_init_fs_ls_pclk_sel(hsotg); + + if (hsotg->core_params->i2c_enable > 0) { + dev_dbg(hsotg->dev, "FS PHY enabling I2C\n"); + + /* Program GUSBCFG.OtgUtmiFsSel to I2C */ + usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL; + writel(usbcfg, hsotg->regs + GUSBCFG); + + /* Program GI2CCTL.I2CEn */ + i2cctl = readl(hsotg->regs + GI2CCTL); + i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK; + i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT; + i2cctl &= ~GI2CCTL_I2CEN; + writel(i2cctl, hsotg->regs + GI2CCTL); + i2cctl |= GI2CCTL_I2CEN; + writel(i2cctl, hsotg->regs + GI2CCTL); + } +} + +static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +{ + u32 usbcfg; + + if (!select_phy) + return; + + usbcfg = readl(hsotg->regs + GUSBCFG); + + /* + * HS PHY parameters. These parameters are preserved during soft reset + * so only program the first time. Do a soft reset immediately after + * setting phyif. + */ + switch (hsotg->core_params->phy_type) { + case DWC2_PHY_TYPE_PARAM_ULPI: + /* ULPI interface */ + dev_dbg(hsotg->dev, "HS ULPI PHY selected\n"); + usbcfg |= GUSBCFG_ULPI_UTMI_SEL; + usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); + if (hsotg->core_params->phy_ulpi_ddr > 0) + usbcfg |= GUSBCFG_DDRSEL; + break; + case DWC2_PHY_TYPE_PARAM_UTMI: + /* UTMI+ interface */ + dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n"); + usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); + if (hsotg->core_params->phy_utmi_width == 16) + usbcfg |= GUSBCFG_PHYIF16; + break; + default: + dev_err(hsotg->dev, "FS PHY selected at HS!\n"); + break; + } + + writel(usbcfg, hsotg->regs + GUSBCFG); + + /* Reset after setting the PHY parameters */ + dwc2_core_reset(hsotg); +} + +static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +{ + u32 usbcfg, hs_phy_type, fs_phy_type; + + if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL && + hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { + /* If FS mode with FS PHY */ + dwc2_fs_phy_init(hsotg, select_phy); + } else { + /* High speed PHY */ + dwc2_hs_phy_init(hsotg, select_phy); + } + + hs_phy_type = hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK; + fs_phy_type = hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK; + + if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && + fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && + hsotg->core_params->ulpi_fs_ls > 0) { + dev_dbg(hsotg->dev, "Setting ULPI FSLS\n"); + usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg |= GUSBCFG_ULPI_FS_LS; + usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M; + writel(usbcfg, hsotg->regs + GUSBCFG); + } else { + usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg &= ~GUSBCFG_ULPI_FS_LS; + usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M; + writel(usbcfg, hsotg->regs + GUSBCFG); + } +} + +static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) +{ + u32 ahbcfg = 0; + + switch (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) { + case GHWCFG2_EXT_DMA_ARCH: + dev_err(hsotg->dev, "External DMA Mode not supported\n"); + return -EINVAL; + + case GHWCFG2_INT_DMA_ARCH: + dev_dbg(hsotg->dev, "Internal DMA Mode\n"); + /* + * Old value was GAHBCFG_HBSTLEN_INCR - done for + * Host mode ISOC in issue fix - vahrama + */ + ahbcfg |= GAHBCFG_HBSTLEN_INCR4; + break; + + case GHWCFG2_SLAVE_ONLY_ARCH: + default: + dev_dbg(hsotg->dev, "Slave Only Mode\n"); + break; + } + + dev_dbg(hsotg->dev, "dma_enable:%d dma_desc_enable:%d\n", + hsotg->core_params->dma_enable, + hsotg->core_params->dma_desc_enable); + + if (hsotg->core_params->dma_enable > 0) { + if (hsotg->core_params->dma_desc_enable > 0) + dev_dbg(hsotg->dev, "Using Descriptor DMA mode\n"); + else + dev_dbg(hsotg->dev, "Using Buffer DMA mode\n"); + } else { + dev_dbg(hsotg->dev, "Using Slave mode\n"); + hsotg->core_params->dma_desc_enable = 0; + } + + if (hsotg->core_params->ahb_single > 0) + ahbcfg |= GAHBCFG_AHB_SINGLE; + + if (hsotg->core_params->dma_enable > 0) + ahbcfg |= GAHBCFG_DMA_EN; + + writel(ahbcfg, hsotg->regs + GAHBCFG); + + return 0; +} + +static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) +{ + u32 usbcfg; + + usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP); + + switch (hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK) { + case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: + if (hsotg->core_params->otg_cap == + DWC2_CAP_PARAM_HNP_SRP_CAPABLE) + usbcfg |= GUSBCFG_HNPCAP; + if (hsotg->core_params->otg_cap != + DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE) + usbcfg |= GUSBCFG_SRPCAP; + break; + + case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST: + if (hsotg->core_params->otg_cap != + DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE) + usbcfg |= GUSBCFG_SRPCAP; + break; + + case GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE: + case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE: + case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST: + default: + break; + } + + writel(usbcfg, hsotg->regs + GUSBCFG); +} + +/** + * dwc2_core_init() - Initializes the DWC_otg controller registers and + * prepares the core for device mode or host mode operation + * + * @hsotg: Programming view of the DWC_otg controller + * @select_phy: If true then also set the Phy type + */ +int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy) +{ + u32 usbcfg, otgctl; + int retval; + + dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); + + usbcfg = readl(hsotg->regs + GUSBCFG); + + /* Set ULPI External VBUS bit if needed */ + usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV; + if (hsotg->core_params->phy_ulpi_ext_vbus == + DWC2_PHY_ULPI_EXTERNAL_VBUS) + usbcfg |= GUSBCFG_ULPI_EXT_VBUS_DRV; + + /* Set external TS Dline pulsing bit if needed */ + usbcfg &= ~GUSBCFG_TERMSELDLPULSE; + if (hsotg->core_params->ts_dline > 0) + usbcfg |= GUSBCFG_TERMSELDLPULSE; + + writel(usbcfg, hsotg->regs + GUSBCFG); + + /* Reset the Controller */ + dwc2_core_reset(hsotg); + + dev_dbg(hsotg->dev, "num_dev_perio_in_ep=%d\n", + hsotg->hwcfg4 >> GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT & + GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK >> + GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT); + + hsotg->total_fifo_size = hsotg->hwcfg3 >> GHWCFG3_DFIFO_DEPTH_SHIFT & + GHWCFG3_DFIFO_DEPTH_MASK >> GHWCFG3_DFIFO_DEPTH_SHIFT; + hsotg->rx_fifo_size = readl(hsotg->regs + GRXFSIZ); + hsotg->nperio_tx_fifo_size = + readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff; + + dev_dbg(hsotg->dev, "Total FIFO SZ=%d\n", hsotg->total_fifo_size); + dev_dbg(hsotg->dev, "RxFIFO SZ=%d\n", hsotg->rx_fifo_size); + dev_dbg(hsotg->dev, "NP TxFIFO SZ=%d\n", hsotg->nperio_tx_fifo_size); + + /* + * This needs to happen in FS mode before any other programming occurs + */ + dwc2_phy_init(hsotg, select_phy); + + /* Program the GAHBCFG Register */ + retval = dwc2_gahbcfg_init(hsotg); + if (retval) + return retval; + + /* Program the GUSBCFG register */ + dwc2_gusbcfg_init(hsotg); + + /* Program the GOTGCTL register */ + otgctl = readl(hsotg->regs + GOTGCTL); + otgctl &= ~GOTGCTL_OTGVER; + if (hsotg->core_params->otg_ver > 0) + otgctl |= GOTGCTL_OTGVER; + writel(otgctl, hsotg->regs + GOTGCTL); + dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver); + + /* Clear the SRP success bit for FS-I2c */ + hsotg->srp_success = 0; + + /* Enable common interrupts */ + dwc2_enable_common_interrupts(hsotg); + + /* + * Do device or host intialization based on mode during PCD and + * HCD initialization + */ + if (dwc2_is_host_mode(hsotg)) { + dev_dbg(hsotg->dev, "Host Mode\n"); + hsotg->op_state = OTG_STATE_A_HOST; + } else { + dev_dbg(hsotg->dev, "Device Mode\n"); + hsotg->op_state = OTG_STATE_B_PERIPHERAL; + } + + return 0; +} + +/** + * dwc2_enable_host_interrupts() - Enables the Host mode interrupts + * + * @hsotg: Programming view of DWC_otg controller + */ +void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) +{ + u32 intmsk; + + dev_dbg(hsotg->dev, "%s()\n", __func__); + + /* Disable all interrupts */ + writel(0, hsotg->regs + GINTMSK); + writel(0, hsotg->regs + HAINTMSK); + + /* Clear any pending interrupts */ + writel(0xffffffff, hsotg->regs + GINTSTS); + + /* Enable the common interrupts */ + dwc2_enable_common_interrupts(hsotg); + + /* Enable host mode interrupts without disturbing common interrupts */ + intmsk = readl(hsotg->regs + GINTMSK); + intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT; + writel(intmsk, hsotg->regs + GINTMSK); +} + +/** + * dwc2_disable_host_interrupts() - Disables the Host Mode interrupts + * + * @hsotg: Programming view of DWC_otg controller + */ +void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg) +{ + u32 intmsk = readl(hsotg->regs + GINTMSK); + + /* Disable host mode interrupts without disturbing common interrupts */ + intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT | + GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP); + writel(intmsk, hsotg->regs + GINTMSK); +} + +static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) +{ + struct dwc2_core_params *params = hsotg->core_params; + u32 rxfsiz, nptxfsiz, ptxfsiz, hptxfsiz, dfifocfg; + + if (!(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO) || + !params->enable_dynamic_fifo) + return; + + dev_dbg(hsotg->dev, "Total FIFO Size=%d\n", hsotg->total_fifo_size); + dev_dbg(hsotg->dev, "Rx FIFO Size=%d\n", params->host_rx_fifo_size); + dev_dbg(hsotg->dev, "NP Tx FIFO Size=%d\n", + params->host_nperio_tx_fifo_size); + dev_dbg(hsotg->dev, "P Tx FIFO Size=%d\n", + params->host_perio_tx_fifo_size); + + /* Rx FIFO */ + dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", + readl(hsotg->regs + GRXFSIZ)); + writel(params->host_rx_fifo_size, hsotg->regs + GRXFSIZ); + dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", readl(hsotg->regs + GRXFSIZ)); + + /* Non-periodic Tx FIFO */ + dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n", + readl(hsotg->regs + GNPTXFSIZ)); + nptxfsiz = params->host_nperio_tx_fifo_size << + FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; + nptxfsiz |= params->host_rx_fifo_size << + FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; + writel(nptxfsiz, hsotg->regs + GNPTXFSIZ); + dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n", + readl(hsotg->regs + GNPTXFSIZ)); + + /* Periodic Tx FIFO */ + dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n", + readl(hsotg->regs + HPTXFSIZ)); + ptxfsiz = params->host_perio_tx_fifo_size << + FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; + ptxfsiz |= (params->host_rx_fifo_size + + params->host_nperio_tx_fifo_size) << + FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; + writel(ptxfsiz, hsotg->regs + HPTXFSIZ); + dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n", + readl(hsotg->regs + HPTXFSIZ)); + + if (hsotg->core_params->en_multiple_tx_fifo > 0 && + hsotg->snpsid <= DWC2_CORE_REV_2_94a) { + /* + * Global DFIFOCFG calculation for Host mode - + * include RxFIFO, NPTXFIFO and HPTXFIFO + */ + dfifocfg = readl(hsotg->regs + GDFIFOCFG); + rxfsiz = readl(hsotg->regs + GRXFSIZ) & 0x0000ffff; + nptxfsiz = readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff; + hptxfsiz = readl(hsotg->regs + HPTXFSIZ) >> 16 & 0xffff; + dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK; + dfifocfg |= (rxfsiz + nptxfsiz + hptxfsiz) << + GDFIFOCFG_EPINFOBASE_SHIFT & + GDFIFOCFG_EPINFOBASE_MASK; + writel(dfifocfg, hsotg->regs + GDFIFOCFG); + } +} + +/** + * dwc2_core_host_init() - Initializes the DWC_otg controller registers for + * Host mode + * + * @hsotg: Programming view of DWC_otg controller + * + * This function flushes the Tx and Rx FIFOs and flushes any entries in the + * request queues. Host channels are reset to ensure that they are ready for + * performing transfers. + */ +void dwc2_core_host_init(struct dwc2_hsotg *hsotg) +{ + u32 hcfg, hfir, otgctl; + + dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); + + /* Restart the Phy Clock */ + writel(0, hsotg->regs + PCGCTL); + + /* Initialize Host Configuration Register */ + dwc2_init_fs_ls_pclk_sel(hsotg); + if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) { + hcfg = readl(hsotg->regs + HCFG); + hcfg |= HCFG_FSLSSUPP; + writel(hcfg, hsotg->regs + HCFG); + } + + /* + * This bit allows dynamic reloading of the HFIR register during + * runtime. This bit needs to be programmed during inital configuration + * and its value must not be changed during runtime. + */ + if (hsotg->core_params->reload_ctl > 0) { + hfir = readl(hsotg->regs + HFIR); + hfir |= HFIR_RLDCTRL; + writel(hfir, hsotg->regs + HFIR); + } + + if (hsotg->core_params->dma_desc_enable > 0) { + u32 op_mode = hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK; + + if (hsotg->snpsid < DWC2_CORE_REV_2_90a || + !(hsotg->hwcfg4 & GHWCFG4_DESC_DMA) || + op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE || + op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE || + op_mode == GHWCFG2_OP_MODE_UNDEFINED) { + dev_err(hsotg->dev, + "Hardware does not support descriptor DMA mode -\n"); + dev_err(hsotg->dev, + "falling back to buffer DMA mode.\n"); + hsotg->core_params->dma_desc_enable = 0; + } else { + hcfg = readl(hsotg->regs + HCFG); + hcfg |= HCFG_DESCDMA; + writel(hcfg, hsotg->regs + HCFG); + } + } + + /* Configure data FIFO sizes */ + dwc2_config_fifos(hsotg); + + /* TODO - check this */ + /* Clear Host Set HNP Enable in the OTG Control Register */ + otgctl = readl(hsotg->regs + GOTGCTL); + otgctl &= ~GOTGCTL_HSTSETHNPEN; + writel(otgctl, hsotg->regs + GOTGCTL); + + /* Make sure the FIFOs are flushed */ + dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */); + dwc2_flush_rx_fifo(hsotg); + + /* Clear Host Set HNP Enable in the OTG Control Register */ + otgctl = readl(hsotg->regs + GOTGCTL); + otgctl &= ~GOTGCTL_HSTSETHNPEN; + writel(otgctl, hsotg->regs + GOTGCTL); + + if (hsotg->core_params->dma_desc_enable <= 0) { + int num_channels, i; + u32 hcchar; + + /* Flush out any leftover queued requests */ + num_channels = hsotg->core_params->host_channels; + for (i = 0; i < num_channels; i++) { + hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar &= ~HCCHAR_CHENA; + hcchar |= HCCHAR_CHDIS; + hcchar &= ~HCCHAR_EPDIR; + writel(hcchar, hsotg->regs + HCCHAR(i)); + } + + /* Halt all channels to put them into a known state */ + for (i = 0; i < num_channels; i++) { + int count = 0; + + hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; + hcchar &= ~HCCHAR_EPDIR; + writel(hcchar, hsotg->regs + HCCHAR(i)); + dev_dbg(hsotg->dev, "%s: Halt channel %d\n", + __func__, i); + do { + hcchar = readl(hsotg->regs + HCCHAR(i)); + if (++count > 1000) { + dev_err(hsotg->dev, + "Unable to clear enable on channel %d\n", + i); + break; + } + udelay(1); + } while (hcchar & HCCHAR_CHENA); + } + } + + /* Turn on the vbus power */ + dev_dbg(hsotg->dev, "Init: Port Power? op_state=%d\n", hsotg->op_state); + if (hsotg->op_state == OTG_STATE_A_HOST) { + u32 hprt0 = dwc2_read_hprt0(hsotg); + + dev_dbg(hsotg->dev, "Init: Power Port (%d)\n", + !!(hprt0 & HPRT0_PWR)); + if (!(hprt0 & HPRT0_PWR)) { + hprt0 |= HPRT0_PWR; + writel(hprt0, hsotg->regs + HPRT0); + } + } + + dwc2_enable_host_interrupts(hsotg); +} + +static void dwc2_hc_enable_slave_ints(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 hcintmsk = HCINTMSK_CHHLTD; + + switch (chan->ep_type) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + dev_vdbg(hsotg->dev, "control/bulk\n"); + hcintmsk |= HCINTMSK_XFERCOMPL; + hcintmsk |= HCINTMSK_STALL; + hcintmsk |= HCINTMSK_XACTERR; + hcintmsk |= HCINTMSK_DATATGLERR; + if (chan->ep_is_in) { + hcintmsk |= HCINTMSK_BBLERR; + } else { + hcintmsk |= HCINTMSK_NAK; + hcintmsk |= HCINTMSK_NYET; + if (chan->do_ping) + hcintmsk |= HCINTMSK_ACK; + } + + if (chan->do_split) { + hcintmsk |= HCINTMSK_NAK; + if (chan->complete_split) + hcintmsk |= HCINTMSK_NYET; + else + hcintmsk |= HCINTMSK_ACK; + } + + if (chan->error_state) + hcintmsk |= HCINTMSK_ACK; + break; + + case USB_ENDPOINT_XFER_INT: + dev_vdbg(hsotg->dev, "intr\n"); + hcintmsk |= HCINTMSK_XFERCOMPL; + hcintmsk |= HCINTMSK_NAK; + hcintmsk |= HCINTMSK_STALL; + hcintmsk |= HCINTMSK_XACTERR; + hcintmsk |= HCINTMSK_DATATGLERR; + hcintmsk |= HCINTMSK_FRMOVRUN; + + if (chan->ep_is_in) + hcintmsk |= HCINTMSK_BBLERR; + if (chan->error_state) + hcintmsk |= HCINTMSK_ACK; + if (chan->do_split) { + if (chan->complete_split) + hcintmsk |= HCINTMSK_NYET; + else + hcintmsk |= HCINTMSK_ACK; + } + break; + + case USB_ENDPOINT_XFER_ISOC: + dev_vdbg(hsotg->dev, "isoc\n"); + hcintmsk |= HCINTMSK_XFERCOMPL; + hcintmsk |= HCINTMSK_FRMOVRUN; + hcintmsk |= HCINTMSK_ACK; + + if (chan->ep_is_in) { + hcintmsk |= HCINTMSK_XACTERR; + hcintmsk |= HCINTMSK_BBLERR; + } + break; + default: + dev_err(hsotg->dev, "## Unknown EP type ##\n"); + break; + } + + writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); +} + +static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 hcintmsk = HCINTMSK_CHHLTD; + + /* + * For Descriptor DMA mode core halts the channel on AHB error. + * Interrupt is not required. + */ + if (hsotg->core_params->dma_desc_enable <= 0) { + dev_vdbg(hsotg->dev, "desc DMA disabled\n"); + hcintmsk |= HCINTMSK_AHBERR; + } else { + dev_vdbg(hsotg->dev, "desc DMA enabled\n"); + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) + hcintmsk |= HCINTMSK_XFERCOMPL; + } + + if (chan->error_state && !chan->do_split && + chan->ep_type != USB_ENDPOINT_XFER_ISOC) { + dev_vdbg(hsotg->dev, "setting ACK\n"); + hcintmsk |= HCINTMSK_ACK; + if (chan->ep_is_in) { + hcintmsk |= HCINTMSK_DATATGLERR; + if (chan->ep_type != USB_ENDPOINT_XFER_INT) + hcintmsk |= HCINTMSK_NAK; + } + } + + writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); +} + +static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 intmsk; + + if (hsotg->core_params->dma_enable > 0) { + dev_vdbg(hsotg->dev, "DMA enabled\n"); + dwc2_hc_enable_dma_ints(hsotg, chan); + } else { + dev_vdbg(hsotg->dev, "DMA disabled\n"); + dwc2_hc_enable_slave_ints(hsotg, chan); + } + + /* Enable the top level host channel interrupt */ + intmsk = readl(hsotg->regs + HAINTMSK); + intmsk |= 1 << chan->hc_num; + writel(intmsk, hsotg->regs + HAINTMSK); + dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk); + + /* Make sure host channel interrupts are enabled */ + intmsk = readl(hsotg->regs + GINTMSK); + intmsk |= GINTSTS_HCHINT; + writel(intmsk, hsotg->regs + GINTMSK); + dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk); +} + +/** + * dwc2_hc_init() - Prepares a host channel for transferring packets to/from + * a specific endpoint + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel + * + * The HCCHARn register is set up with the characteristics specified in chan. + * Host channel interrupts that may need to be serviced while this transfer is + * in progress are enabled. + */ +void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) +{ + u8 hc_num = chan->hc_num; + u32 hcintmsk; + u32 hcchar; + u32 hcsplt = 0; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + /* Clear old interrupt conditions for this host channel */ + hcintmsk = 0xffffffff; + hcintmsk &= ~HCINTMSK_RESERVED14_31; + writel(hcintmsk, hsotg->regs + HCINT(hc_num)); + + /* Enable channel interrupts required for this transfer */ + dwc2_hc_enable_ints(hsotg, chan); + + /* + * Program the HCCHARn register with the endpoint characteristics for + * the current transfer + */ + hcchar = chan->dev_addr << HCCHAR_DEVADDR_SHIFT & HCCHAR_DEVADDR_MASK; + hcchar |= chan->ep_num << HCCHAR_EPNUM_SHIFT & HCCHAR_EPNUM_MASK; + if (chan->ep_is_in) + hcchar |= HCCHAR_EPDIR; + if (chan->speed == USB_SPEED_LOW) + hcchar |= HCCHAR_LSPDDEV; + hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK; + hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK; + writel(hcchar, hsotg->regs + HCCHAR(hc_num)); + dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n", hc_num, hcchar); + + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, hc_num); + dev_vdbg(hsotg->dev, " Dev Addr: %d\n", + hcchar >> HCCHAR_DEVADDR_SHIFT & + HCCHAR_DEVADDR_MASK >> HCCHAR_DEVADDR_SHIFT); + dev_vdbg(hsotg->dev, " Ep Num: %d\n", + hcchar >> HCCHAR_EPNUM_SHIFT & + HCCHAR_EPNUM_MASK >> HCCHAR_EPNUM_SHIFT); + dev_vdbg(hsotg->dev, " Is In: %d\n", !!(hcchar & HCCHAR_EPDIR)); + dev_vdbg(hsotg->dev, " Is Low Speed: %d\n", + !!(hcchar & HCCHAR_LSPDDEV)); + dev_vdbg(hsotg->dev, " Ep Type: %d\n", + hcchar >> HCCHAR_EPTYPE_SHIFT & + HCCHAR_EPTYPE_MASK >> HCCHAR_EPTYPE_SHIFT); + dev_vdbg(hsotg->dev, " Max Pkt: %d\n", + hcchar >> HCCHAR_MPS_SHIFT & + HCCHAR_MPS_MASK >> HCCHAR_MPS_SHIFT); + dev_vdbg(hsotg->dev, " Multi Cnt: %d\n", + hcchar >> HCCHAR_MULTICNT_SHIFT & + HCCHAR_MULTICNT_MASK >> HCCHAR_MULTICNT_SHIFT); + + /* Program the HCSPLT register for SPLITs */ + if (chan->do_split) { + dev_vdbg(hsotg->dev, "Programming HC %d with split --> %s\n", + hc_num, chan->complete_split ? "CSPLIT" : "SSPLIT"); + if (chan->complete_split) + hcsplt |= HCSPLT_COMPSPLT; + hcsplt |= chan->xact_pos << HCSPLT_XACTPOS_SHIFT & + HCSPLT_XACTPOS_MASK; + hcsplt |= chan->hub_addr << HCSPLT_HUBADDR_SHIFT & + HCSPLT_HUBADDR_MASK; + hcsplt |= chan->hub_port << HCSPLT_PRTADDR_SHIFT & + HCSPLT_PRTADDR_MASK; + dev_vdbg(hsotg->dev, " comp split %d\n", + chan->complete_split); + dev_vdbg(hsotg->dev, " xact pos %d\n", chan->xact_pos); + dev_vdbg(hsotg->dev, " hub addr %d\n", chan->hub_addr); + dev_vdbg(hsotg->dev, " hub port %d\n", chan->hub_port); + dev_vdbg(hsotg->dev, " is_in %d\n", chan->ep_is_in); + dev_vdbg(hsotg->dev, " Max Pkt %d\n", + hcchar >> HCCHAR_MPS_SHIFT & + HCCHAR_MPS_MASK >> HCCHAR_MPS_SHIFT); + dev_vdbg(hsotg->dev, " xferlen %d\n", chan->xfer_len); + } + + writel(hcsplt, hsotg->regs + HCSPLT(hc_num)); +} + +/** + * dwc2_hc_halt() - Attempts to halt a host channel + * + * @hsotg: Controller register interface + * @chan: Host channel to halt + * @halt_status: Reason for halting the channel + * + * This function should only be called in Slave mode or to abort a transfer in + * either Slave mode or DMA mode. Under normal circumstances in DMA mode, the + * controller halts the channel when the transfer is complete or a condition + * occurs that requires application intervention. + * + * In slave mode, checks for a free request queue entry, then sets the Channel + * Enable and Channel Disable bits of the Host Channel Characteristics + * register of the specified channel to intiate the halt. If there is no free + * request queue entry, sets only the Channel Disable bit of the HCCHARn + * register to flush requests for this channel. In the latter case, sets a + * flag to indicate that the host channel needs to be halted when a request + * queue slot is open. + * + * In DMA mode, always sets the Channel Enable and Channel Disable bits of the + * HCCHARn register. The controller ensures there is space in the request + * queue before submitting the halt request. + * + * Some time may elapse before the core flushes any posted requests for this + * host channel and halts. The Channel Halted interrupt handler completes the + * deactivation of the host channel. + */ +void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, + enum dwc2_halt_status halt_status) +{ + u32 nptxsts, hptxsts, hcchar; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + if (halt_status == DWC2_HC_XFER_NO_HALT_STATUS) + dev_err(hsotg->dev, "!!! halt_status = %d !!!\n", halt_status); + + if (halt_status == DWC2_HC_XFER_URB_DEQUEUE || + halt_status == DWC2_HC_XFER_AHB_ERR) { + /* + * Disable all channel interrupts except Ch Halted. The QTD + * and QH state associated with this transfer has been cleared + * (in the case of URB_DEQUEUE), so the channel needs to be + * shut down carefully to prevent crashes. + */ + u32 hcintmsk = HCINTMSK_CHHLTD; + + dev_vdbg(hsotg->dev, "dequeue/error\n"); + writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + + /* + * Make sure no other interrupts besides halt are currently + * pending. Handling another interrupt could cause a crash due + * to the QTD and QH state. + */ + writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num)); + + /* + * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR + * even if the channel was already halted for some other + * reason + */ + chan->halt_status = halt_status; + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + if (!(hcchar & HCCHAR_CHENA)) { + /* + * The channel is either already halted or it hasn't + * started yet. In DMA mode, the transfer may halt if + * it finishes normally or a condition occurs that + * requires driver intervention. Don't want to halt + * the channel again. In either Slave or DMA mode, + * it's possible that the transfer has been assigned + * to a channel, but not started yet when an URB is + * dequeued. Don't want to halt a channel that hasn't + * started yet. + */ + return; + } + } + if (chan->halt_pending) { + /* + * A halt has already been issued for this channel. This might + * happen when a transfer is aborted by a higher level in + * the stack. + */ + dev_vdbg(hsotg->dev, + "*** %s: Channel %d, chan->halt_pending already set ***\n", + __func__, chan->hc_num); + return; + } + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + + /* No need to set the bit in DDMA for disabling the channel */ + /* TODO check it everywhere channel is disabled */ + if (hsotg->core_params->dma_desc_enable <= 0) { + dev_vdbg(hsotg->dev, "desc DMA disabled\n"); + hcchar |= HCCHAR_CHENA; + } else { + dev_dbg(hsotg->dev, "desc DMA enabled\n"); + } + hcchar |= HCCHAR_CHDIS; + + if (hsotg->core_params->dma_enable <= 0) { + dev_vdbg(hsotg->dev, "DMA not enabled\n"); + hcchar |= HCCHAR_CHENA; + + /* Check for space in the request queue to issue the halt */ + if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || + chan->ep_type == USB_ENDPOINT_XFER_BULK) { + dev_vdbg(hsotg->dev, "control/bulk\n"); + nptxsts = readl(hsotg->regs + GNPTXSTS); + if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) { + dev_vdbg(hsotg->dev, "Disabling channel\n"); + hcchar &= ~HCCHAR_CHENA; + } + } else { + dev_vdbg(hsotg->dev, "isoc/intr\n"); + hptxsts = readl(hsotg->regs + HPTXSTS); + if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 || + hsotg->queuing_high_bandwidth) { + dev_vdbg(hsotg->dev, "Disabling channel\n"); + hcchar &= ~HCCHAR_CHENA; + } + } + } else { + dev_vdbg(hsotg->dev, "DMA enabled\n"); + } + + writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + chan->halt_status = halt_status; + + if (hcchar & HCCHAR_CHENA) { + dev_vdbg(hsotg->dev, "Channel enabled\n"); + chan->halt_pending = 1; + chan->halt_on_queue = 0; + } else { + dev_vdbg(hsotg->dev, "Channel disabled\n"); + chan->halt_on_queue = 1; + } + + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, chan->hc_num); + dev_vdbg(hsotg->dev, " hcchar: 0x%08x\n", hcchar); + dev_vdbg(hsotg->dev, " halt_pending: %d\n", chan->halt_pending); + dev_vdbg(hsotg->dev, " halt_on_queue: %d\n", chan->halt_on_queue); + dev_vdbg(hsotg->dev, " halt_status: %d\n", chan->halt_status); +} + +/** + * dwc2_hc_cleanup() - Clears the transfer state for a host channel + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Identifies the host channel to clean up + * + * This function is normally called after a transfer is done and the host + * channel is being released + */ +void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) +{ + u32 hcintmsk; + + chan->xfer_started = 0; + + /* + * Clear channel interrupt enables and any unhandled channel interrupt + * conditions + */ + writel(0, hsotg->regs + HCINTMSK(chan->hc_num)); + hcintmsk = 0xffffffff; + hcintmsk &= ~HCINTMSK_RESERVED14_31; + writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num)); +} + +/** + * dwc2_hc_set_even_odd_frame() - Sets the channel property that indicates in + * which frame a periodic transfer should occur + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Identifies the host channel to set up and its properties + * @hcchar: Current value of the HCCHAR register for the specified host channel + * + * This function has no effect on non-periodic transfers + */ +static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, u32 *hcchar) +{ + u32 hfnum, frnum; + + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + hfnum = readl(hsotg->regs + HFNUM); + frnum = hfnum >> HFNUM_FRNUM_SHIFT & + HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT; + + /* 1 if _next_ frame is odd, 0 if it's even */ + if (frnum & 0x1) + *hcchar |= HCCHAR_ODDFRM; + } +} + +static void dwc2_set_pid_isoc(struct dwc2_host_chan *chan) +{ + /* Set up the initial PID for the transfer */ + if (chan->speed == USB_SPEED_HIGH) { + if (chan->ep_is_in) { + if (chan->multi_count == 1) + chan->data_pid_start = DWC2_HC_PID_DATA0; + else if (chan->multi_count == 2) + chan->data_pid_start = DWC2_HC_PID_DATA1; + else + chan->data_pid_start = DWC2_HC_PID_DATA2; + } else { + if (chan->multi_count == 1) + chan->data_pid_start = DWC2_HC_PID_DATA0; + else + chan->data_pid_start = DWC2_HC_PID_MDATA; + } + } else { + chan->data_pid_start = DWC2_HC_PID_DATA0; + } +} + +/** + * dwc2_hc_write_packet() - Writes a packet into the Tx FIFO associated with + * the Host Channel + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel + * + * This function should only be called in Slave mode. For a channel associated + * with a non-periodic EP, the non-periodic Tx FIFO is written. For a channel + * associated with a periodic EP, the periodic Tx FIFO is written. + * + * Upon return the xfer_buf and xfer_count fields in chan are incremented by + * the number of bytes written to the Tx FIFO. + */ +static void dwc2_hc_write_packet(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 i; + u32 remaining_count; + u32 byte_count; + u32 dword_count; + u32 __iomem *data_fifo; + u32 *data_buf = (u32 *)chan->xfer_buf; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + data_fifo = (u32 __iomem *)(hsotg->regs + HCFIFO(chan->hc_num)); + + remaining_count = chan->xfer_len - chan->xfer_count; + if (remaining_count > chan->max_packet) + byte_count = chan->max_packet; + else + byte_count = remaining_count; + + dword_count = (byte_count + 3) / 4; + + if (((unsigned long)data_buf & 0x3) == 0) { + /* xfer_buf is DWORD aligned */ + for (i = 0; i < dword_count; i++, data_buf++) + writel(*data_buf, data_fifo); + } else { + /* xfer_buf is not DWORD aligned */ + for (i = 0; i < dword_count; i++, data_buf++) { + u32 data = data_buf[0] | data_buf[1] << 8 | + data_buf[2] << 16 | data_buf[3] << 24; + writel(data, data_fifo); + } + } + + chan->xfer_count += byte_count; + chan->xfer_buf += byte_count; +} + +/** + * dwc2_hc_start_transfer() - Does the setup for a data transfer for a host + * channel and starts the transfer + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel. The xfer_len value + * may be reduced to accommodate the max widths of the XferSize and + * PktCnt fields in the HCTSIZn register. The multi_count value may be + * changed to reflect the final xfer_len value. + * + * This function may be called in either Slave mode or DMA mode. In Slave mode, + * the caller must ensure that there is sufficient space in the request queue + * and Tx Data FIFO. + * + * For an OUT transfer in Slave mode, it loads a data packet into the + * appropriate FIFO. If necessary, additional data packets are loaded in the + * Host ISR. + * + * For an IN transfer in Slave mode, a data packet is requested. The data + * packets are unloaded from the Rx FIFO in the Host ISR. If necessary, + * additional data packets are requested in the Host ISR. + * + * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ + * register along with a packet count of 1 and the channel is enabled. This + * causes a single PING transaction to occur. Other fields in HCTSIZ are + * simply set to 0 since no data transfer occurs in this case. + * + * For a PING transfer in DMA mode, the HCTSIZ register is initialized with + * all the information required to perform the subsequent data transfer. In + * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the + * controller performs the entire PING protocol, then starts the data + * transfer. + */ +void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 max_hc_xfer_size = hsotg->core_params->max_transfer_size; + u16 max_hc_pkt_count = hsotg->core_params->max_packet_count; + u32 hcchar; + u32 hctsiz = 0; + u16 num_packets; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (chan->do_ping) { + if (hsotg->core_params->dma_enable <= 0) { + dev_vdbg(hsotg->dev, "ping, no DMA\n"); + dwc2_hc_do_ping(hsotg, chan); + chan->xfer_started = 1; + return; + } else { + dev_vdbg(hsotg->dev, "ping, DMA\n"); + hctsiz |= TSIZ_DOPNG; + } + } + + if (chan->do_split) { + dev_vdbg(hsotg->dev, "split\n"); + num_packets = 1; + + if (chan->complete_split && !chan->ep_is_in) + /* + * For CSPLIT OUT Transfer, set the size to 0 so the + * core doesn't expect any data written to the FIFO + */ + chan->xfer_len = 0; + else if (chan->ep_is_in || chan->xfer_len > chan->max_packet) + chan->xfer_len = chan->max_packet; + else if (!chan->ep_is_in && chan->xfer_len > 188) + chan->xfer_len = 188; + + hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & + TSIZ_XFERSIZE_MASK; + } else { + dev_vdbg(hsotg->dev, "no split\n"); + /* + * Ensure that the transfer length and packet count will fit + * in the widths allocated for them in the HCTSIZn register + */ + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + /* + * Make sure the transfer size is no larger than one + * (micro)frame's worth of data. (A check was done + * when the periodic transfer was accepted to ensure + * that a (micro)frame's worth of data can be + * programmed into a channel.) + */ + u32 max_periodic_len = + chan->multi_count * chan->max_packet; + + if (chan->xfer_len > max_periodic_len) + chan->xfer_len = max_periodic_len; + } else if (chan->xfer_len > max_hc_xfer_size) { + /* + * Make sure that xfer_len is a multiple of max packet + * size + */ + chan->xfer_len = + max_hc_xfer_size - chan->max_packet + 1; + } + + if (chan->xfer_len > 0) { + num_packets = (chan->xfer_len + chan->max_packet - 1) / + chan->max_packet; + if (num_packets > max_hc_pkt_count) { + num_packets = max_hc_pkt_count; + chan->xfer_len = num_packets * chan->max_packet; + } + } else { + /* Need 1 packet for transfer length of 0 */ + num_packets = 1; + } + + if (chan->ep_is_in) + /* + * Always program an integral # of max packets for IN + * transfers + */ + chan->xfer_len = num_packets * chan->max_packet; + + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) + /* + * Make sure that the multi_count field matches the + * actual transfer length + */ + chan->multi_count = num_packets; + + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) + dwc2_set_pid_isoc(chan); + + hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & + TSIZ_XFERSIZE_MASK; + } + + chan->start_pkt_count = num_packets; + hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK; + hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT & + TSIZ_SC_MC_PID_MASK; + writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n", + hctsiz, chan->hc_num); + + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, chan->hc_num); + dev_vdbg(hsotg->dev, " Xfer Size: %d\n", + hctsiz >> TSIZ_XFERSIZE_SHIFT & + TSIZ_XFERSIZE_MASK >> TSIZ_XFERSIZE_SHIFT); + dev_vdbg(hsotg->dev, " Num Pkts: %d\n", + hctsiz >> TSIZ_PKTCNT_SHIFT & + TSIZ_PKTCNT_MASK >> TSIZ_PKTCNT_SHIFT); + dev_vdbg(hsotg->dev, " Start PID: %d\n", + hctsiz >> TSIZ_SC_MC_PID_SHIFT & + TSIZ_SC_MC_PID_MASK >> TSIZ_SC_MC_PID_SHIFT); + + if (hsotg->core_params->dma_enable > 0) { + dma_addr_t dma_addr; + + if (chan->align_buf) { + dev_vdbg(hsotg->dev, "align_buf\n"); + dma_addr = chan->align_buf; + } else { + dma_addr = chan->xfer_dma; + } + writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num)); + dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n", + (unsigned long)dma_addr, chan->hc_num); + } + + /* Start the split */ + if (chan->do_split) { + u32 hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num)); + + hcsplt |= HCSPLT_SPLTENA; + writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num)); + } + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar &= ~HCCHAR_MULTICNT_MASK; + hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & + HCCHAR_MULTICNT_MASK; + dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); + + if (hcchar & HCCHAR_CHDIS) + dev_warn(hsotg->dev, + "%s: chdis set, channel %d, hcchar 0x%08x\n", + __func__, chan->hc_num, hcchar); + + /* Set host channel enable after all other setup is complete */ + hcchar |= HCCHAR_CHENA; + hcchar &= ~HCCHAR_CHDIS; + + dev_vdbg(hsotg->dev, " Multi Cnt: %d\n", + hcchar >> HCCHAR_MULTICNT_SHIFT & + HCCHAR_MULTICNT_MASK >> HCCHAR_MULTICNT_SHIFT); + + writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, + chan->hc_num); + + chan->xfer_started = 1; + chan->requests++; + + if (hsotg->core_params->dma_enable <= 0 && + !chan->ep_is_in && chan->xfer_len > 0) + /* Load OUT packet into the appropriate Tx FIFO */ + dwc2_hc_write_packet(hsotg, chan); +} + +/** + * dwc2_hc_start_transfer_ddma() - Does the setup for a data transfer for a + * host channel and starts the transfer in Descriptor DMA mode + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel + * + * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set. + * Sets PID and NTD values. For periodic transfers initializes SCHED_INFO field + * with micro-frame bitmap. + * + * Initializes HCDMA register with descriptor list address and CTD value then + * starts the transfer via enabling the channel. + */ +void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + u32 hcchar; + u32 hc_dma; + u32 hctsiz = 0; + + if (chan->do_ping) + hctsiz |= TSIZ_DOPNG; + + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) + dwc2_set_pid_isoc(chan); + + /* Packet Count and Xfer Size are not used in Descriptor DMA mode */ + hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT & + TSIZ_SC_MC_PID_MASK; + + /* 0 - 1 descriptor, 1 - 2 descriptors, etc */ + hctsiz |= (chan->ntd - 1) << TSIZ_NTD_SHIFT & TSIZ_NTD_MASK; + + /* Non-zero only for high-speed interrupt endpoints */ + hctsiz |= chan->schinfo << TSIZ_SCHINFO_SHIFT & TSIZ_SCHINFO_MASK; + + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, chan->hc_num); + dev_vdbg(hsotg->dev, " Start PID: %d\n", chan->data_pid_start); + dev_vdbg(hsotg->dev, " NTD: %d\n", chan->ntd - 1); + + writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + + hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK; + + /* Always start from first descriptor */ + hc_dma &= ~HCDMA_CTD_MASK; + writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num)); + dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n", hc_dma, chan->hc_num); + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar &= ~HCCHAR_MULTICNT_MASK; + hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & + HCCHAR_MULTICNT_MASK; + + if (hcchar & HCCHAR_CHDIS) + dev_warn(hsotg->dev, + "%s: chdis set, channel %d, hcchar 0x%08x\n", + __func__, chan->hc_num, hcchar); + + /* Set host channel enable after all other setup is complete */ + hcchar |= HCCHAR_CHENA; + hcchar &= ~HCCHAR_CHDIS; + + dev_vdbg(hsotg->dev, " Multi Cnt: %d\n", + hcchar >> HCCHAR_MULTICNT_SHIFT & + HCCHAR_MULTICNT_MASK >> HCCHAR_MULTICNT_SHIFT); + + writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, + chan->hc_num); + + chan->xfer_started = 1; + chan->requests++; +} + +/** + * dwc2_hc_continue_transfer() - Continues a data transfer that was started by + * a previous call to dwc2_hc_start_transfer() + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel + * + * The caller must ensure there is sufficient space in the request queue and Tx + * Data FIFO. This function should only be called in Slave mode. In DMA mode, + * the controller acts autonomously to complete transfers programmed to a host + * channel. + * + * For an OUT transfer, a new data packet is loaded into the appropriate FIFO + * if there is any data remaining to be queued. For an IN transfer, another + * data packet is always requested. For the SETUP phase of a control transfer, + * this function does nothing. + * + * Return: 1 if a new request is queued, 0 if no more requests are required + * for this transfer + */ +int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, chan->hc_num); + + if (chan->do_split) + /* SPLITs always queue just once per channel */ + return 0; + + if (chan->data_pid_start == DWC2_HC_PID_SETUP) + /* SETUPs are queued only once since they can't be NAK'd */ + return 0; + + if (chan->ep_is_in) { + /* + * Always queue another request for other IN transfers. If + * back-to-back INs are issued and NAKs are received for both, + * the driver may still be processing the first NAK when the + * second NAK is received. When the interrupt handler clears + * the NAK interrupt for the first NAK, the second NAK will + * not be seen. So we can't depend on the NAK interrupt + * handler to requeue a NAK'd request. Instead, IN requests + * are issued each time this function is called. When the + * transfer completes, the extra requests for the channel will + * be flushed. + */ + u32 hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + + dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); + hcchar |= HCCHAR_CHENA; + hcchar &= ~HCCHAR_CHDIS; + dev_vdbg(hsotg->dev, " IN xfer: hcchar = 0x%08x\n", hcchar); + writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + chan->requests++; + return 1; + } + + /* OUT transfers */ + + if (chan->xfer_count < chan->xfer_len) { + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + u32 hcchar = readl(hsotg->regs + + HCCHAR(chan->hc_num)); + + dwc2_hc_set_even_odd_frame(hsotg, chan, + &hcchar); + } + + /* Load OUT packet into the appropriate Tx FIFO */ + dwc2_hc_write_packet(hsotg, chan); + chan->requests++; + return 1; + } + + return 0; +} + +/** + * dwc2_hc_do_ping() - Starts a PING transfer + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Information needed to initialize the host channel + * + * This function should only be called in Slave mode. The Do Ping bit is set in + * the HCTSIZ register, then the channel is enabled. + */ +void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) +{ + u32 hcchar; + u32 hctsiz; + + dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, chan->hc_num); + + hctsiz = TSIZ_DOPNG; + hctsiz |= 1 << TSIZ_PKTCNT_SHIFT; + writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar |= HCCHAR_CHENA; + hcchar &= ~HCCHAR_CHDIS; + writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); +} + +/** + * dwc2_calc_frame_interval() - Calculates the correct frame Interval value for + * the HFIR register according to PHY type and speed + * + * @hsotg: Programming view of DWC_otg controller + * + * NOTE: The caller can modify the value of the HFIR register only after the + * Port Enable bit of the Host Port Control and Status register (HPRT.EnaPort) + * has been set + */ +u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) +{ + u32 usbcfg; + u32 hwcfg2; + u32 hprt0; + int clock = 60; /* default value */ + + usbcfg = readl(hsotg->regs + GUSBCFG); + hwcfg2 = readl(hsotg->regs + GHWCFG2); + hprt0 = readl(hsotg->regs + HPRT0); + + if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) && + !(usbcfg & GUSBCFG_PHYIF16)) + clock = 60; + if ((usbcfg & GUSBCFG_PHYSEL) && (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) == + GHWCFG2_FS_PHY_TYPE_SHARED_ULPI) + clock = 48; + if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && + !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16)) + clock = 30; + if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && + !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & GUSBCFG_PHYIF16)) + clock = 60; + if ((usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && + !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16)) + clock = 48; + if ((usbcfg & GUSBCFG_PHYSEL) && !(usbcfg & GUSBCFG_PHYIF16) && + (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) == + GHWCFG2_FS_PHY_TYPE_SHARED_UTMI) + clock = 48; + if ((usbcfg & GUSBCFG_PHYSEL) && (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) == + GHWCFG2_FS_PHY_TYPE_DEDICATED) + clock = 48; + + if ((hprt0 & HPRT0_SPD_MASK) == 0) + /* High speed case */ + return 125 * clock; + else + /* FS/LS case */ + return 1000 * clock; +} + +/** + * dwc2_read_packet() - Reads a packet from the Rx FIFO into the destination + * buffer + * + * @core_if: Programming view of DWC_otg controller + * @dest: Destination buffer for the packet + * @bytes: Number of bytes to copy to the destination + */ +void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes) +{ + u32 __iomem *fifo = hsotg->regs + HCFIFO(0); + u32 *data_buf = (u32 *)dest; + int word_count = (bytes + 3) / 4; + int i; + + /* + * Todo: Account for the case where dest is not dword aligned. This + * requires reading data from the FIFO into a u32 temp buffer, then + * moving it into the data buffer. + */ + + dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes); + + for (i = 0; i < word_count; i++, data_buf++) + *data_buf = readl(fifo); +} + +/** + * dwc2_dump_host_registers() - Prints the host registers + * + * @hsotg: Programming view of DWC_otg controller + * + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg) +{ +#ifdef DEBUG + u32 __iomem *addr; + int i; + + dev_dbg(hsotg->dev, "Host Global Registers\n"); + addr = hsotg->regs + HCFG; + dev_dbg(hsotg->dev, "HCFG @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HFIR; + dev_dbg(hsotg->dev, "HFIR @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HFNUM; + dev_dbg(hsotg->dev, "HFNUM @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HPTXSTS; + dev_dbg(hsotg->dev, "HPTXSTS @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HAINT; + dev_dbg(hsotg->dev, "HAINT @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HAINTMSK; + dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + if (hsotg->core_params->dma_desc_enable > 0) { + addr = hsotg->regs + HFLBADDR; + dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + } + + addr = hsotg->regs + HPRT0; + dev_dbg(hsotg->dev, "HPRT0 @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + + for (i = 0; i < hsotg->core_params->host_channels; i++) { + dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i); + addr = hsotg->regs + HCCHAR(i); + dev_dbg(hsotg->dev, "HCCHAR @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HCSPLT(i); + dev_dbg(hsotg->dev, "HCSPLT @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HCINT(i); + dev_dbg(hsotg->dev, "HCINT @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HCINTMSK(i); + dev_dbg(hsotg->dev, "HCINTMSK @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HCTSIZ(i); + dev_dbg(hsotg->dev, "HCTSIZ @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HCDMA(i); + dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + if (hsotg->core_params->dma_desc_enable > 0) { + addr = hsotg->regs + HCDMAB(i); + dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + } + } +#endif +} + +/** + * dwc2_dump_global_registers() - Prints the core global registers + * + * @hsotg: Programming view of DWC_otg controller + * + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg) +{ +#ifdef DEBUG + u32 __iomem *addr; + int i, ep_num; + char *txfsiz; + + dev_dbg(hsotg->dev, "Core Global Registers\n"); + addr = hsotg->regs + GOTGCTL; + dev_dbg(hsotg->dev, "GOTGCTL @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GOTGINT; + dev_dbg(hsotg->dev, "GOTGINT @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GAHBCFG; + dev_dbg(hsotg->dev, "GAHBCFG @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GUSBCFG; + dev_dbg(hsotg->dev, "GUSBCFG @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GRSTCTL; + dev_dbg(hsotg->dev, "GRSTCTL @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GINTSTS; + dev_dbg(hsotg->dev, "GINTSTS @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GINTMSK; + dev_dbg(hsotg->dev, "GINTMSK @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GRXSTSR; + dev_dbg(hsotg->dev, "GRXSTSR @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GRXFSIZ; + dev_dbg(hsotg->dev, "GRXFSIZ @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GNPTXFSIZ; + dev_dbg(hsotg->dev, "GNPTXFSIZ @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GNPTXSTS; + dev_dbg(hsotg->dev, "GNPTXSTS @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GI2CCTL; + dev_dbg(hsotg->dev, "GI2CCTL @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GPVNDCTL; + dev_dbg(hsotg->dev, "GPVNDCTL @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GGPIO; + dev_dbg(hsotg->dev, "GGPIO @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GUID; + dev_dbg(hsotg->dev, "GUID @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GSNPSID; + dev_dbg(hsotg->dev, "GSNPSID @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GHWCFG1; + dev_dbg(hsotg->dev, "GHWCFG1 @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GHWCFG2; + dev_dbg(hsotg->dev, "GHWCFG2 @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GHWCFG3; + dev_dbg(hsotg->dev, "GHWCFG3 @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GHWCFG4; + dev_dbg(hsotg->dev, "GHWCFG4 @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GLPMCFG; + dev_dbg(hsotg->dev, "GLPMCFG @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GPWRDN; + dev_dbg(hsotg->dev, "GPWRDN @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + GDFIFOCFG; + dev_dbg(hsotg->dev, "GDFIFOCFG @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + addr = hsotg->regs + HPTXFSIZ; + dev_dbg(hsotg->dev, "HPTXFSIZ @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); + + if (hsotg->core_params->en_multiple_tx_fifo <= 0) { + ep_num = hsotg->hwcfg4 >> GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT & + GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK >> + GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT; + txfsiz = "DPTXFSIZ"; + } else { + ep_num = hsotg->hwcfg4 >> GHWCFG4_NUM_IN_EPS_SHIFT & + GHWCFG4_NUM_IN_EPS_MASK >> GHWCFG4_NUM_IN_EPS_SHIFT; + txfsiz = "DIENPTXF"; + } + + for (i = 0; i < ep_num; i++) { + addr = hsotg->regs + DPTXFSIZN(i + 1); + dev_dbg(hsotg->dev, "%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1, + (unsigned long)addr, readl(addr)); + } + + addr = hsotg->regs + PCGCTL; + dev_dbg(hsotg->dev, "PCGCTL @0x%08lX : 0x%08X\n", + (unsigned long)addr, readl(addr)); +#endif +} + +/** + * dwc2_flush_tx_fifo() - Flushes a Tx FIFO + * + * @hsotg: Programming view of DWC_otg controller + * @num: Tx FIFO to flush + */ +void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num) +{ + u32 greset; + int count = 0; + + dev_vdbg(hsotg->dev, "Flush Tx FIFO %d\n", num); + + greset = GRSTCTL_TXFFLSH; + greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK; + writel(greset, hsotg->regs + GRSTCTL); + + do { + greset = readl(hsotg->regs + GRSTCTL); + if (++count > 10000) { + dev_warn(hsotg->dev, + "%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n", + __func__, greset, + readl(hsotg->regs + GNPTXSTS)); + break; + } + udelay(1); + } while (greset & GRSTCTL_TXFFLSH); + + /* Wait for at least 3 PHY Clocks */ + udelay(1); +} + +/** + * dwc2_flush_rx_fifo() - Flushes the Rx FIFO + * + * @hsotg: Programming view of DWC_otg controller + */ +void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg) +{ + u32 greset; + int count = 0; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + greset = GRSTCTL_RXFFLSH; + writel(greset, hsotg->regs + GRSTCTL); + + do { + greset = readl(hsotg->regs + GRSTCTL); + if (++count > 10000) { + dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x\n", + __func__, greset); + break; + } + udelay(1); + } while (greset & GRSTCTL_RXFFLSH); + + /* Wait for at least 3 PHY Clocks */ + udelay(1); +} + +#define DWC2_PARAM_TEST(a, b, c) ((a) < (b) || (a) > (c)) + +/* Parameter access functions */ +int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + u32 op_mode; + + op_mode = hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK; + + switch (val) { + case DWC2_CAP_PARAM_HNP_SRP_CAPABLE: + if (op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) + valid = 0; + break; + case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE: + switch (op_mode) { + case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: + case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST: + break; + default: + valid = 0; + break; + } + break; + case DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE: + /* always valid */ + break; + default: + valid = 0; + break; + } + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for otg_cap parameter. Check HW configuration.\n", + val); + switch (op_mode) { + case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: + val = DWC2_CAP_PARAM_HNP_SRP_CAPABLE; + break; + case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: + case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST: + val = DWC2_CAP_PARAM_SRP_ONLY_CAPABLE; + break; + default: + val = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE; + break; + } + dev_dbg(hsotg->dev, "Setting otg_cap to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->otg_cap = val; + return retval; +} + +int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val > 0 && (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) == + GHWCFG2_SLAVE_ONLY_ARCH) + valid = 0; + if (val < 0) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for dma_enable parameter. Check HW configuration.\n", + val); + val = (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) != + GHWCFG2_SLAVE_ONLY_ARCH; + dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->dma_enable = val; + return retval; +} + +int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val > 0 && (hsotg->core_params->dma_enable <= 0 || + !(hsotg->hwcfg4 & GHWCFG4_DESC_DMA))) + valid = 0; + if (val < 0) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for dma_desc_enable parameter. Check HW configuration.\n", + val); + val = (hsotg->core_params->dma_enable > 0 && + (hsotg->hwcfg4 & GHWCFG4_DESC_DMA)); + dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->dma_desc_enable = val; + return retval; +} + +int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, + int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "Wrong value for host_support_fs_low_power\n"); + dev_err(hsotg->dev, + "host_support_fs_low_power must be 0 or 1\n"); + } + val = 0; + dev_dbg(hsotg->dev, + "Setting host_support_fs_low_power to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->host_support_fs_ls_low_power = val; + return retval; +} + +int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val > 0 && !(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO)) + valid = 0; + if (val < 0) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for enable_dynamic_fifo parameter. Check HW configuration.\n", + val); + val = !!(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO); + dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->enable_dynamic_fifo = val; + return retval; +} + +int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val < 16 || val > readl(hsotg->regs + GRXFSIZ)) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for host_rx_fifo_size. Check HW configuration.\n", + val); + val = readl(hsotg->regs + GRXFSIZ); + dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->host_rx_fifo_size = val; + return retval; +} + +int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val < 16 || val > (readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff)) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n", + val); + val = readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff; + dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n", + val); + retval = -EINVAL; + } + + hsotg->core_params->host_nperio_tx_fifo_size = val; + return retval; +} + +int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (val < 16 || val > (hsotg->hptxfsiz >> 16)) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n", + val); + val = hsotg->hptxfsiz >> 16; + dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n", + val); + retval = -EINVAL; + } + + hsotg->core_params->host_perio_tx_fifo_size = val; + return retval; +} + +int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + int width = hsotg->hwcfg3 >> GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT & + GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK >> + GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT; + + if (val < 2047 || val >= (1 << (width + 11))) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for max_transfer_size. Check HW configuration.\n", + val); + val = (1 << (width + 11)) - 1; + dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->max_transfer_size = val; + return retval; +} + +int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + int width = hsotg->hwcfg3 >> GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT & + GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK >> + GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT; + + if (val < 15 || val > (1 << (width + 4))) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for max_packet_count. Check HW configuration.\n", + val); + val = (1 << (width + 4)) - 1; + dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->max_packet_count = val; + return retval; +} + +int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + int num_chan = hsotg->hwcfg2 >> GHWCFG2_NUM_HOST_CHAN_SHIFT & + GHWCFG2_NUM_HOST_CHAN_MASK >> GHWCFG2_NUM_HOST_CHAN_SHIFT; + + if (val < 1 || val > num_chan + 1) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for host_channels. Check HW configuration.\n", + val); + val = num_chan + 1; + dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->host_channels = val; + return retval; +} + +int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) +{ +#ifndef NO_FS_PHY_HW_CHECKS + int valid = 0; + u32 hs_phy_type; + u32 fs_phy_type; +#endif + int retval = 0; + + if (DWC2_PARAM_TEST(val, DWC2_PHY_TYPE_PARAM_FS, + DWC2_PHY_TYPE_PARAM_ULPI)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for phy_type\n"); + dev_err(hsotg->dev, "phy_type must be 0, 1 or 2\n"); + } + +#ifndef NO_FS_PHY_HW_CHECKS + valid = 0; +#else + val = 0; + dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val); + retval = -EINVAL; +#endif + } + +#ifndef NO_FS_PHY_HW_CHECKS + hs_phy_type = hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK; + fs_phy_type = hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK; + + if (val == DWC2_PHY_TYPE_PARAM_UTMI && + (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI || + hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)) + valid = 1; + else if (val == DWC2_PHY_TYPE_PARAM_ULPI && + (hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI || + hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)) + valid = 1; + else if (val == DWC2_PHY_TYPE_PARAM_FS && + fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) + valid = 1; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for phy_type. Check HW configuration.\n", + val); + val = 0; + if (hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED) { + if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI || + hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI) + val = DWC2_PHY_TYPE_PARAM_UTMI; + else + val = DWC2_PHY_TYPE_PARAM_ULPI; + } + dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val); + retval = -EINVAL; + } +#endif + + hsotg->core_params->phy_type = val; + return retval; +} + +static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg) +{ + return hsotg->core_params->phy_type; +} + +int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for speed parameter\n"); + dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n"); + } + valid = 0; + } + + if (val == 0 && dwc2_get_param_phy_type(hsotg) == + DWC2_PHY_TYPE_PARAM_FS) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for speed parameter. Check HW configuration.\n", + val); + val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ? + 1 : 0; + dev_dbg(hsotg->dev, "Setting speed to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->speed = val; + return retval; +} + +int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (DWC2_PARAM_TEST(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ, + DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) { + if (val >= 0) { + dev_err(hsotg->dev, + "Wrong value for host_ls_low_power_phy_clk parameter\n"); + dev_err(hsotg->dev, + "host_ls_low_power_phy_clk must be 0 or 1\n"); + } + valid = 0; + } + + if (val == DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ && + dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n", + val); + val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS + ? DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ + : DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ; + dev_dbg(hsotg->dev, "Setting host_ls_low_power_phy_clk to %d\n", + val); + retval = -EINVAL; + } + + hsotg->core_params->host_ls_low_power_phy_clk = val; + return retval; +} + +int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for phy_ulpi_ddr\n"); + dev_err(hsotg->dev, "phy_upli_ddr must be 0 or 1\n"); + } + val = 0; + dev_dbg(hsotg->dev, "Setting phy_upli_ddr to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->phy_ulpi_ddr = val; + return retval; +} + +int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "Wrong value for phy_ulpi_ext_vbus\n"); + dev_err(hsotg->dev, + "phy_ulpi_ext_vbus must be 0 or 1\n"); + } + val = 0; + dev_dbg(hsotg->dev, "Setting phy_ulpi_ext_vbus to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->phy_ulpi_ext_vbus = val; + return retval; +} + +int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 8, 8) && DWC2_PARAM_TEST(val, 16, 16)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for phy_utmi_width\n"); + dev_err(hsotg->dev, "phy_utmi_width must be 8 or 16\n"); + } + val = 8; + dev_dbg(hsotg->dev, "Setting phy_utmi_width to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->phy_utmi_width = val; + return retval; +} + +int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for ulpi_fs_ls\n"); + dev_err(hsotg->dev, "ulpi_fs_ls must be 0 or 1\n"); + } + val = 0; + dev_dbg(hsotg->dev, "Setting ulpi_fs_ls to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->ulpi_fs_ls = val; + return retval; +} + +int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for ts_dline\n"); + dev_err(hsotg->dev, "ts_dline must be 0 or 1\n"); + } + val = 0; + dev_dbg(hsotg->dev, "Setting ts_dline to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->ts_dline = val; + return retval; +} + +int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) +{ +#ifndef NO_FS_PHY_HW_CHECKS + int valid = 1; +#endif + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, "Wrong value for i2c_enable\n"); + dev_err(hsotg->dev, "i2c_enable must be 0 or 1\n"); + } + +#ifndef NO_FS_PHY_HW_CHECKS + valid = 0; +#else + val = 0; + dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val); + retval = -EINVAL; +#endif + } + +#ifndef NO_FS_PHY_HW_CHECKS + if (val == 1 && !(hsotg->hwcfg3 & GHWCFG3_I2C)) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for i2c_enable. Check HW configuration.\n", + val); + val = !!(hsotg->hwcfg3 & GHWCFG3_I2C); + dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val); + retval = -EINVAL; + } +#endif + + hsotg->core_params->i2c_enable = val; + return retval; +} + +int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "Wrong value for en_multiple_tx_fifo,\n"); + dev_err(hsotg->dev, + "en_multiple_tx_fifo must be 0 or 1\n"); + } + valid = 0; + } + + if (val == 1 && !(hsotg->hwcfg4 & GHWCFG4_DED_FIFO_EN)) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n", + val); + val = !!(hsotg->hwcfg4 & GHWCFG4_DED_FIFO_EN); + dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->en_multiple_tx_fifo = val; + return retval; +} + +int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "'%d' invalid for parameter reload_ctl\n", val); + dev_err(hsotg->dev, "reload_ctl must be 0 or 1\n"); + } + valid = 0; + } + + if (val == 1 && hsotg->snpsid < DWC2_CORE_REV_2_92a) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for parameter reload_ctl. Check HW configuration.\n", + val); + val = hsotg->snpsid >= DWC2_CORE_REV_2_92a; + dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->reload_ctl = val; + return retval; +} + +int dwc2_set_param_ahb_single(struct dwc2_hsotg *hsotg, int val) +{ + int valid = 1; + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "'%d' invalid for parameter ahb_single\n", val); + dev_err(hsotg->dev, "ahb_single must be 0 or 1\n"); + } + valid = 0; + } + + if (val > 0 && hsotg->snpsid < DWC2_CORE_REV_2_94a) + valid = 0; + + if (!valid) { + if (val >= 0) + dev_err(hsotg->dev, + "%d invalid for parameter ahb_single. Check HW configuration.\n", + val); + val = 0; + dev_dbg(hsotg->dev, "Setting ahb_single to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->ahb_single = val; + return retval; +} + +int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val) +{ + int retval = 0; + + if (DWC2_PARAM_TEST(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "'%d' invalid for parameter otg_ver\n", val); + dev_err(hsotg->dev, + "otg_ver must be 0 (for OTG 1.3 support) or 1 (for OTG 2.0 support)\n"); + } + val = 0; + dev_dbg(hsotg->dev, "Setting otg_ver to %d\n", val); + retval = -EINVAL; + } + + hsotg->core_params->otg_ver = val; + return retval; +} + +/* + * This function is called during module intialization to pass module parameters + * for the DWC_otg core. It returns non-0 if any parameters are invalid. + */ +int dwc2_set_parameters(struct dwc2_hsotg *hsotg, + struct dwc2_core_params *params) +{ + int retval = 0; + + dev_dbg(hsotg->dev, "%s()\n", __func__); + + retval |= dwc2_set_param_otg_cap(hsotg, params->otg_cap); + retval |= dwc2_set_param_dma_enable(hsotg, params->dma_enable); + retval |= dwc2_set_param_dma_desc_enable(hsotg, + params->dma_desc_enable); + retval |= dwc2_set_param_host_support_fs_ls_low_power(hsotg, + params->host_support_fs_ls_low_power); + retval |= dwc2_set_param_enable_dynamic_fifo(hsotg, + params->enable_dynamic_fifo); + retval |= dwc2_set_param_host_rx_fifo_size(hsotg, + params->host_rx_fifo_size); + retval |= dwc2_set_param_host_nperio_tx_fifo_size(hsotg, + params->host_nperio_tx_fifo_size); + retval |= dwc2_set_param_host_perio_tx_fifo_size(hsotg, + params->host_perio_tx_fifo_size); + retval |= dwc2_set_param_max_transfer_size(hsotg, + params->max_transfer_size); + retval |= dwc2_set_param_max_packet_count(hsotg, + params->max_packet_count); + retval |= dwc2_set_param_host_channels(hsotg, params->host_channels); + retval |= dwc2_set_param_phy_type(hsotg, params->phy_type); + retval |= dwc2_set_param_speed(hsotg, params->speed); + retval |= dwc2_set_param_host_ls_low_power_phy_clk(hsotg, + params->host_ls_low_power_phy_clk); + retval |= dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr); + retval |= dwc2_set_param_phy_ulpi_ext_vbus(hsotg, + params->phy_ulpi_ext_vbus); + retval |= dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width); + retval |= dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls); + retval |= dwc2_set_param_ts_dline(hsotg, params->ts_dline); + retval |= dwc2_set_param_i2c_enable(hsotg, params->i2c_enable); + retval |= dwc2_set_param_en_multiple_tx_fifo(hsotg, + params->en_multiple_tx_fifo); + retval |= dwc2_set_param_reload_ctl(hsotg, params->reload_ctl); + retval |= dwc2_set_param_ahb_single(hsotg, params->ahb_single); + retval |= dwc2_set_param_otg_ver(hsotg, params->otg_ver); + + return retval; +} + +u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg) +{ + return (u16)(hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103); +} + +int dwc2_check_core_status(struct dwc2_hsotg *hsotg) +{ + if (readl(hsotg->regs + GSNPSID) == 0xffffffff) + return -1; + else + return 0; +} + +/** + * dwc2_enable_global_interrupts() - Enables the controller's Global + * Interrupt in the AHB Config register + * + * @hsotg: Programming view of DWC_otg controller + */ +void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg) +{ + u32 ahbcfg = readl(hsotg->regs + GAHBCFG); + + ahbcfg |= GAHBCFG_GLBL_INTR_EN; + writel(ahbcfg, hsotg->regs + GAHBCFG); +} + +/** + * dwc2_disable_global_interrupts() - Disables the controller's Global + * Interrupt in the AHB Config register + * + * @hsotg: Programming view of DWC_otg controller + */ +void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg) +{ + u32 ahbcfg = readl(hsotg->regs + GAHBCFG); + + ahbcfg &= ~GAHBCFG_GLBL_INTR_EN; + writel(ahbcfg, hsotg->regs + GAHBCFG); +} + +MODULE_DESCRIPTION("DESIGNWARE HS OTG Core"); +MODULE_AUTHOR("Synopsys, Inc."); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/staging/dwc2/core.h b/drivers/staging/dwc2/core.h new file mode 100644 index 000000000000..f8ee04b7cc00 --- /dev/null +++ b/drivers/staging/dwc2/core.h @@ -0,0 +1,658 @@ +/* + * core.h - DesignWare HS OTG Controller common declarations + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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. + */ + +#ifndef __DWC2_CORE_H__ +#define __DWC2_CORE_H__ + +#include +#include "hw.h" + +#ifdef DWC2_LOG_WRITES +static inline void do_write(u32 value, void *addr) +{ + writel(value, addr); + pr_info("INFO:: wrote %08x to %p\n", value, addr); +} + +#undef writel +#define writel(v, a) do_write(v, a) +#endif + +/* Maximum number of Endpoints/HostChannels */ +#define MAX_EPS_CHANNELS 16 + +struct dwc2_hsotg; +struct dwc2_host_chan; + +/* Device States */ +enum dwc2_lx_state { + DWC2_L0, /* On state */ + DWC2_L1, /* LPM sleep state */ + DWC2_L2, /* USB suspend state */ + DWC2_L3, /* Off state */ +}; + +/** + * struct dwc2_core_params - Parameters for configuring the core + * + * @otg_cap: Specifies the OTG capabilities. The driver will + * automatically detect the value for this parameter if + * none is specified. + * 0 - HNP and SRP capable (default) + * 1 - SRP Only capable + * 2 - No HNP/SRP capable + * @dma_enable: Specifies whether to use slave or DMA mode for accessing + * the data FIFOs. The driver will automatically detect the + * value for this parameter if none is specified. + * 0 - Slave + * 1 - DMA (default, if available) + * @dma_desc_enable: When DMA mode is enabled, specifies whether to use + * address DMA mode or descriptor DMA mode for accessing + * the data FIFOs. The driver will automatically detect the + * value for this if none is specified. + * 0 - Address DMA + * 1 - Descriptor DMA (default, if available) + * @speed: Specifies the maximum speed of operation in host and + * device mode. The actual speed depends on the speed of + * the attached device and the value of phy_type. + * 0 - High Speed (default) + * 1 - Full Speed + * @host_support_fs_ls_low_power: Specifies whether low power mode is supported + * when attached to a Full Speed or Low Speed device in + * host mode. + * 0 - Don't support low power mode (default) + * 1 - Support low power mode + * @host_ls_low_power_phy_clk: Specifies the PHY clock rate in low power mode + * when connected to a Low Speed device in host mode. This + * parameter is applicable only if + * host_support_fs_ls_low_power is enabled. If phy_type is + * set to FS then defaults to 6 MHZ otherwise 48 MHZ. + * 0 - 48 MHz + * 1 - 6 MHz + * @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters + * 1 - Allow dynamic FIFO sizing (default) + * @host_rx_fifo_size: Number of 4-byte words in the Rx FIFO in host mode when + * dynamic FIFO sizing is enabled + * 16 to 32768 (default 1024) + * @host_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO + * in host mode when dynamic FIFO sizing is enabled + * 16 to 32768 (default 1024) + * @host_perio_tx_fifo_size: Number of 4-byte words in the periodic Tx FIFO in + * host mode when dynamic FIFO sizing is enabled + * 16 to 32768 (default 1024) + * @max_transfer_size: The maximum transfer size supported, in bytes + * 2047 to 65,535 (default 65,535) + * @max_packet_count: The maximum number of packets in a transfer + * 15 to 511 (default 511) + * @host_channels: The number of host channel registers to use + * 1 to 16 (default 12) + * @phy_type: Specifies the type of PHY interface to use. By default, + * the driver will automatically detect the phy_type. + * @phy_utmi_width: Specifies the UTMI+ Data Width (in bits). This parameter + * is applicable for a phy_type of UTMI+ or ULPI. (For a + * ULPI phy_type, this parameter indicates the data width + * between the MAC and the ULPI Wrapper.) Also, this + * parameter is applicable only if the OTG_HSPHY_WIDTH cC + * parameter was set to "8 and 16 bits", meaning that the + * core has been configured to work at either data path + * width. + * 8 or 16 (default 16) + * @phy_ulpi_ddr: Specifies whether the ULPI operates at double or single + * data rate. This parameter is only applicable if phy_type + * is ULPI. + * 0 - single data rate ULPI interface with 8 bit wide + * data bus (default) + * 1 - double data rate ULPI interface with 4 bit wide + * data bus + * @phy_ulpi_ext_vbus: For a ULPI phy, specifies whether to use the internal or + * external supply to drive the VBus + * @i2c_enable: Specifies whether to use the I2Cinterface for a full + * speed PHY. This parameter is only applicable if phy_type + * is FS. + * 0 - No (default) + * 1 - Yes + * @ulpi_fs_ls: True to make ULPI phy operate in FS/LS mode only + * @ts_dline: True to enable Term Select Dline pulsing + * @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs + * are enabled + * @reload_ctl: True to allow dynamic reloading of HFIR register during + * runtime + * @ahb_single: This bit enables SINGLE transfers for remainder data in + * a transfer for DMA mode of operation. + * 0 - remainder data will be sent using INCR burst size + * 1 - remainder data will be sent using SINGLE burst size + * @otg_ver: OTG version supported + * 0 - 1.3 + * 1 - 2.0 + * + * The following parameters may be specified when starting the module. These + * parameters define how the DWC_otg controller should be configured. + */ +struct dwc2_core_params { + int otg_cap; + int otg_ver; + int dma_enable; + int dma_desc_enable; + int speed; + int enable_dynamic_fifo; + int en_multiple_tx_fifo; + int host_rx_fifo_size; + int host_nperio_tx_fifo_size; + int host_perio_tx_fifo_size; + int max_transfer_size; + int max_packet_count; + int host_channels; + int phy_type; + int phy_utmi_width; + int phy_ulpi_ddr; + int phy_ulpi_ext_vbus; + int i2c_enable; + int ulpi_fs_ls; + int host_support_fs_ls_low_power; + int host_ls_low_power_phy_clk; + int ts_dline; + int reload_ctl; + int ahb_single; +}; + +/** + * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic + * and periodic schedules + * + * @dev: The struct device pointer + * @regs: Pointer to controller regs + * @core_params: Parameters that define how the core should be configured + * @hwcfg1: Hardware Configuration - stored here for convenience + * @hwcfg2: Hardware Configuration - stored here for convenience + * @hwcfg3: Hardware Configuration - stored here for convenience + * @hwcfg4: Hardware Configuration - stored here for convenience + * @hptxfsiz: Hardware Configuration - stored here for convenience + * @snpsid: Value from SNPSID register + * @total_fifo_size: Total internal RAM for FIFOs (bytes) + * @rx_fifo_size: Size of Rx FIFO (bytes) + * @nperio_tx_fifo_size: Size of Non-periodic Tx FIFO (Bytes) + * @op_state: The operational State, during transitions (a_host=> + * a_peripheral and b_device=>b_host) this may not match + * the core, but allows the software to determine + * transitions + * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth + * transfer are in process of being queued + * @srp_success: Stores status of SRP request in the case of a FS PHY + * with an I2C interface + * @wq_otg: Workqueue object used for handling of some interrupts + * @wf_otg: Work object for handling Connector ID Status Change + * interrupt + * @wkp_timer: Timer object for handling Wakeup Detected interrupt + * @lx_state: Lx state of connected device + * @flags: Flags for handling root port state changes + * @non_periodic_sched_inactive: Inactive QHs in the non-periodic schedule. + * Transfers associated with these QHs are not currently + * assigned to a host channel. + * @non_periodic_sched_active: Active QHs in the non-periodic schedule. + * Transfers associated with these QHs are currently + * assigned to a host channel. + * @non_periodic_qh_ptr: Pointer to next QH to process in the active + * non-periodic schedule + * @periodic_sched_inactive: Inactive QHs in the periodic schedule. This is a + * list of QHs for periodic transfers that are _not_ + * scheduled for the next frame. Each QH in the list has an + * interval counter that determines when it needs to be + * scheduled for execution. This scheduling mechanism + * allows only a simple calculation for periodic bandwidth + * used (i.e. must assume that all periodic transfers may + * need to execute in the same frame). However, it greatly + * simplifies scheduling and should be sufficient for the + * vast majority of OTG hosts, which need to connect to a + * small number of peripherals at one time. Items move from + * this list to periodic_sched_ready when the QH interval + * counter is 0 at SOF. + * @periodic_sched_ready: List of periodic QHs that are ready for execution in + * the next frame, but have not yet been assigned to host + * channels. Items move from this list to + * periodic_sched_assigned as host channels become + * available during the current frame. + * @periodic_sched_assigned: List of periodic QHs to be executed in the next + * frame that are assigned to host channels. Items move + * from this list to periodic_sched_queued as the + * transactions for the QH are queued to the DWC_otg + * controller. + * @periodic_sched_queued: List of periodic QHs that have been queued for + * execution. Items move from this list to either + * periodic_sched_inactive or periodic_sched_ready when the + * channel associated with the transfer is released. If the + * interval for the QH is 1, the item moves to + * periodic_sched_ready because it must be rescheduled for + * the next frame. Otherwise, the item moves to + * periodic_sched_inactive. + * @periodic_usecs: Total bandwidth claimed so far for periodic transfers. + * This value is in microseconds per (micro)frame. The + * assumption is that all periodic transfers may occur in + * the same (micro)frame. + * @frame_number: Frame number read from the core at SOF. The value ranges + * from 0 to HFNUM_MAX_FRNUM. + * @periodic_qh_count: Count of periodic QHs, if using several eps. Used for + * SOF enable/disable. + * @free_hc_list: Free host channels in the controller. This is a list of + * struct dwc2_host_chan items. + * @periodic_channels: Number of host channels assigned to periodic transfers. + * Currently assuming that there is a dedicated host + * channel for each periodic transaction and at least one + * host channel is available for non-periodic transactions. + * @non_periodic_channels: Number of host channels assigned to non-periodic + * transfers + * @hc_ptr_array: Array of pointers to the host channel descriptors. + * Allows accessing a host channel descriptor given the + * host channel number. This is useful in interrupt + * handlers. + * @status_buf: Buffer used for data received during the status phase of + * a control transfer. + * @status_buf_dma: DMA address for status_buf + * @start_work: Delayed work for handling host A-cable connection + * @reset_work: Delayed work for handling a port reset + * @lock: Spinlock that protects all the driver data structures + * @priv: Stores a pointer to the struct usb_hcd + * @otg_port: OTG port number + * @frame_list: Frame list + * @frame_list_dma: Frame list DMA address + */ +struct dwc2_hsotg { + struct device *dev; + void __iomem *regs; + struct dwc2_core_params *core_params; + u32 hwcfg1; + u32 hwcfg2; + u32 hwcfg3; + u32 hwcfg4; + u32 hptxfsiz; + u32 snpsid; + u16 total_fifo_size; + u16 rx_fifo_size; + u16 nperio_tx_fifo_size; + enum usb_otg_state op_state; + + unsigned int queuing_high_bandwidth:1; + unsigned int srp_success:1; + + struct workqueue_struct *wq_otg; + struct work_struct wf_otg; + struct timer_list wkp_timer; + enum dwc2_lx_state lx_state; + + union dwc2_hcd_internal_flags { + u32 d32; + struct { + unsigned port_connect_status_change:1; + unsigned port_connect_status:1; + unsigned port_reset_change:1; + unsigned port_enable_change:1; + unsigned port_suspend_change:1; + unsigned port_over_current_change:1; + unsigned port_l1_change:1; + unsigned reserved:26; + } b; + } flags; + + struct list_head non_periodic_sched_inactive; + struct list_head non_periodic_sched_active; + struct list_head *non_periodic_qh_ptr; + struct list_head periodic_sched_inactive; + struct list_head periodic_sched_ready; + struct list_head periodic_sched_assigned; + struct list_head periodic_sched_queued; + u16 periodic_usecs; + u16 frame_number; + u16 periodic_qh_count; + +#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS +#define FRAME_NUM_ARRAY_SIZE 1000 + u16 last_frame_num; + u16 *frame_num_array; + u16 *last_frame_num_array; + int frame_num_idx; + int dumped_frame_num_array; +#endif + + struct list_head free_hc_list; + int periodic_channels; + int non_periodic_channels; + struct dwc2_host_chan *hc_ptr_array[MAX_EPS_CHANNELS]; + u8 *status_buf; + dma_addr_t status_buf_dma; +#define DWC2_HCD_STATUS_BUF_SIZE 64 + + struct delayed_work start_work; + struct delayed_work reset_work; + spinlock_t lock; + void *priv; + u8 otg_port; + u32 *frame_list; + dma_addr_t frame_list_dma; + + /* DWC OTG HW Release versions */ +#define DWC2_CORE_REV_2_71a 0x4f54271a +#define DWC2_CORE_REV_2_90a 0x4f54290a +#define DWC2_CORE_REV_2_92a 0x4f54292a +#define DWC2_CORE_REV_2_94a 0x4f54294a +#define DWC2_CORE_REV_3_00a 0x4f54300a + +#ifdef DEBUG + u32 frrem_samples; + u64 frrem_accum; + + u32 hfnum_7_samples_a; + u64 hfnum_7_frrem_accum_a; + u32 hfnum_0_samples_a; + u64 hfnum_0_frrem_accum_a; + u32 hfnum_other_samples_a; + u64 hfnum_other_frrem_accum_a; + + u32 hfnum_7_samples_b; + u64 hfnum_7_frrem_accum_b; + u32 hfnum_0_samples_b; + u64 hfnum_0_frrem_accum_b; + u32 hfnum_other_samples_b; + u64 hfnum_other_frrem_accum_b; +#endif +}; + +/* Reasons for halting a host channel */ +enum dwc2_halt_status { + DWC2_HC_XFER_NO_HALT_STATUS, + DWC2_HC_XFER_COMPLETE, + DWC2_HC_XFER_URB_COMPLETE, + DWC2_HC_XFER_ACK, + DWC2_HC_XFER_NAK, + DWC2_HC_XFER_NYET, + DWC2_HC_XFER_STALL, + DWC2_HC_XFER_XACT_ERR, + DWC2_HC_XFER_FRAME_OVERRUN, + DWC2_HC_XFER_BABBLE_ERR, + DWC2_HC_XFER_DATA_TOGGLE_ERR, + DWC2_HC_XFER_AHB_ERR, + DWC2_HC_XFER_PERIODIC_INCOMPLETE, + DWC2_HC_XFER_URB_DEQUEUE, +}; + +/* + * The following functions support initialization of the core driver component + * and the DWC_otg controller + */ +extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); + +/* + * Host core Functions. + * The following functions support managing the DWC_otg controller in host + * mode. + */ +extern void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan); +extern void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, + enum dwc2_halt_status halt_status); +extern void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan); +extern void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan); +extern void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan); +extern int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan); +extern void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan); +extern void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg); +extern void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg); + +extern u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg); +extern int dwc2_check_core_status(struct dwc2_hsotg *hsotg); + +/* + * Common core Functions. + * The following functions support managing the DWC_otg controller in either + * device or host mode. + */ +extern void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes); +extern void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num); +extern void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg); + +extern int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy); +extern void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd); +extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd); + +/* This function should be called on every hardware interrupt. */ +extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev); + +/* OTG Core Parameters */ + +/* + * Specifies the OTG capabilities. The driver will automatically + * detect the value for this parameter if none is specified. + * 0 - HNP and SRP capable (default) + * 1 - SRP Only capable + * 2 - No HNP/SRP capable + */ +extern int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val); +#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0 +#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1 +#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 + +/* + * Specifies whether to use slave or DMA mode for accessing the data + * FIFOs. The driver will automatically detect the value for this + * parameter if none is specified. + * 0 - Slave + * 1 - DMA (default, if available) + */ +extern int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val); + +/* + * When DMA mode is enabled specifies whether to use + * address DMA or DMA Descritor mode for accessing the data + * FIFOs in device mode. The driver will automatically detect + * the value for this parameter if none is specified. + * 0 - address DMA + * 1 - DMA Descriptor(default, if available) + */ +extern int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val); + +/* + * Specifies the maximum speed of operation in host and device mode. + * The actual speed depends on the speed of the attached device and + * the value of phy_type. The actual speed depends on the speed of the + * attached device. + * 0 - High Speed (default) + * 1 - Full Speed + */ +extern int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val); +#define DWC2_SPEED_PARAM_HIGH 0 +#define DWC2_SPEED_PARAM_FULL 1 + +/* + * Specifies whether low power mode is supported when attached + * to a Full Speed or Low Speed device in host mode. + * + * 0 - Don't support low power mode (default) + * 1 - Support low power mode + */ +extern int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, + int val); + +/* + * Specifies the PHY clock rate in low power mode when connected to a + * Low Speed device in host mode. This parameter is applicable only if + * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS + * then defaults to 6 MHZ otherwise 48 MHZ. + * + * 0 - 48 MHz + * 1 - 6 MHz + */ +extern int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, + int val); +#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0 +#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1 + +/* + * 0 - Use cC FIFO size parameters + * 1 - Allow dynamic FIFO sizing (default) + */ +extern int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, + int val); + +/* + * Number of 4-byte words in the Rx FIFO in host mode when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ +extern int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val); + +/* + * Number of 4-byte words in the non-periodic Tx FIFO in host mode + * when Dynamic FIFO sizing is enabled in the core. + * 16 to 32768 (default 256) + */ +extern int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, + int val); + +/* + * Number of 4-byte words in the host periodic Tx FIFO when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 256) + */ +extern int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, + int val); + +/* + * The maximum transfer size supported in bytes. + * 2047 to 65,535 (default 65,535) + */ +extern int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val); + +/* + * The maximum number of packets in a transfer. + * 15 to 511 (default 511) + */ +extern int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val); + +/* + * The number of host channel registers to use. + * 1 to 16 (default 11) + * Note: The FPGA configuration supports a maximum of 11 host channels. + */ +extern int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val); + +/* + * Specifies the type of PHY interface to use. By default, the driver + * will automatically detect the phy_type. + * + * 0 - Full Speed PHY + * 1 - UTMI+ (default) + * 2 - ULPI + */ +extern int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val); +#define DWC2_PHY_TYPE_PARAM_FS 0 +#define DWC2_PHY_TYPE_PARAM_UTMI 1 +#define DWC2_PHY_TYPE_PARAM_ULPI 2 + +/* + * Specifies the UTMI+ Data Width. This parameter is + * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI + * PHY_TYPE, this parameter indicates the data width between + * the MAC and the ULPI Wrapper.) Also, this parameter is + * applicable only if the OTG_HSPHY_WIDTH cC parameter was set + * to "8 and 16 bits", meaning that the core has been + * configured to work at either data path width. + * + * 8 or 16 bits (default 16) + */ +extern int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val); + +/* + * Specifies whether the ULPI operates at double or single + * data rate. This parameter is only applicable if PHY_TYPE is + * ULPI. + * + * 0 - single data rate ULPI interface with 8 bit wide data + * bus (default) + * 1 - double data rate ULPI interface with 4 bit wide data + * bus + */ +extern int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val); + +/* + * Specifies whether to use the internal or external supply to + * drive the vbus with a ULPI phy. + */ +extern int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val); +#define DWC2_PHY_ULPI_INTERNAL_VBUS 0 +#define DWC2_PHY_ULPI_EXTERNAL_VBUS 1 + +/* + * Specifies whether to use the I2Cinterface for full speed PHY. This + * parameter is only applicable if PHY_TYPE is FS. + * 0 - No (default) + * 1 - Yes + */ +extern int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val); + +extern int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val); + +extern int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val); + +/* + * Specifies whether dedicated transmit FIFOs are + * enabled for non periodic IN endpoints in device mode + * 0 - No + * 1 - Yes + */ +extern int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, + int val); + +extern int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val); + +extern int dwc2_set_param_ahb_single(struct dwc2_hsotg *hsotg, int val); + +extern int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val); + +/* + * Dump core registers and SPRAM + */ +extern void dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg); +extern void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg); +extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); + +/* + * Return OTG version - either 1.3 or 2.0 + */ +extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); + +#endif /* __DWC2_CORE_H__ */ diff --git a/drivers/staging/dwc2/core_intr.c b/drivers/staging/dwc2/core_intr.c new file mode 100644 index 000000000000..44c016670a16 --- /dev/null +++ b/drivers/staging/dwc2/core_intr.c @@ -0,0 +1,505 @@ +/* + * core_intr.c - DesignWare HS OTG Controller common interrupt handling + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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 file contains the common interrupt handlers + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) +{ +#ifdef DEBUG + switch (hsotg->op_state) { + case OTG_STATE_A_HOST: + return "a_host"; + case OTG_STATE_A_SUSPEND: + return "a_suspend"; + case OTG_STATE_A_PERIPHERAL: + return "a_peripheral"; + case OTG_STATE_B_PERIPHERAL: + return "b_peripheral"; + case OTG_STATE_B_HOST: + return "b_host"; + default: + return "unknown"; + } +#else + return ""; +#endif +} + +/** + * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message + * + * @hsotg: Programming view of DWC_otg controller + */ +static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg) +{ + dev_warn(hsotg->dev, "Mode Mismatch Interrupt: currently in %s mode\n", + dwc2_is_host_mode(hsotg) ? "Host" : "Device"); + + /* Clear interrupt */ + writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); +} + +/** + * dwc2_handle_otg_intr() - Handles the OTG Interrupts. It reads the OTG + * Interrupt Register (GOTGINT) to determine what interrupt has occurred. + * + * @hsotg: Programming view of DWC_otg controller + */ +static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) +{ + u32 gotgint; + u32 gotgctl; + u32 gintmsk; + + gotgint = readl(hsotg->regs + GOTGINT); + gotgctl = readl(hsotg->regs + GOTGCTL); + dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint, + dwc2_op_state_str(hsotg)); + + if (gotgint & GOTGINT_SES_END_DET) { + dev_dbg(hsotg->dev, + " ++OTG Interrupt: Session End Detected++ (%s)\n", + dwc2_op_state_str(hsotg)); + gotgctl = readl(hsotg->regs + GOTGCTL); + + if (hsotg->op_state == OTG_STATE_B_HOST) { + hsotg->op_state = OTG_STATE_B_PERIPHERAL; + } else { + /* + * If not B_HOST and Device HNP still set, HNP did + * not succeed! + */ + if (gotgctl & GOTGCTL_DEVHNPEN) { + dev_dbg(hsotg->dev, "Session End Detected\n"); + dev_err(hsotg->dev, + "Device Not Connected/Responding!\n"); + } + + /* + * If Session End Detected the B-Cable has been + * disconnected + */ + /* Reset to a clean state */ + hsotg->lx_state = DWC2_L0; + } + + gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl &= ~GOTGCTL_DEVHNPEN; + writel(gotgctl, hsotg->regs + GOTGCTL); + } + + if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) { + dev_dbg(hsotg->dev, + " ++OTG Interrupt: Session Request Success Status Change++\n"); + gotgctl = readl(hsotg->regs + GOTGCTL); + if (gotgctl & GOTGCTL_SESREQSCS) { + if (hsotg->core_params->phy_type == + DWC2_PHY_TYPE_PARAM_FS + && hsotg->core_params->i2c_enable > 0) { + hsotg->srp_success = 1; + } else { + /* Clear Session Request */ + gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl &= ~GOTGCTL_SESREQ; + writel(gotgctl, hsotg->regs + GOTGCTL); + } + } + } + + if (gotgint & GOTGINT_HST_NEG_SUC_STS_CHNG) { + /* + * Print statements during the HNP interrupt handling + * can cause it to fail + */ + gotgctl = readl(hsotg->regs + GOTGCTL); + /* + * WA for 3.00a- HW is not setting cur_mode, even sometimes + * this does not help + */ + if (hsotg->snpsid >= DWC2_CORE_REV_3_00a) + udelay(100); + if (gotgctl & GOTGCTL_HSTNEGSCS) { + if (dwc2_is_host_mode(hsotg)) { + hsotg->op_state = OTG_STATE_B_HOST; + /* + * Need to disable SOF interrupt immediately. + * When switching from device to host, the PCD + * interrupt handler won't handle the interrupt + * if host mode is already set. The HCD + * interrupt handler won't get called if the + * HCD state is HALT. This means that the + * interrupt does not get handled and Linux + * complains loudly. + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk &= ~GINTSTS_SOF; + writel(gintmsk, hsotg->regs + GINTMSK); + + /* + * Call callback function with spin lock + * released + */ + spin_unlock(&hsotg->lock); + + /* Initialize the Core for Host mode */ + dwc2_hcd_start(hsotg); + spin_lock(&hsotg->lock); + hsotg->op_state = OTG_STATE_B_HOST; + } + } else { + gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN); + writel(gotgctl, hsotg->regs + GOTGCTL); + dev_dbg(hsotg->dev, "HNP Failed\n"); + dev_err(hsotg->dev, + "Device Not Connected/Responding\n"); + } + } + + if (gotgint & GOTGINT_HST_NEG_DET) { + /* + * The disconnect interrupt is set at the same time as + * Host Negotiation Detected. During the mode switch all + * interrupts are cleared so the disconnect interrupt + * handler will not get executed. + */ + dev_dbg(hsotg->dev, + " ++OTG Interrupt: Host Negotiation Detected++ (%s)\n", + (dwc2_is_host_mode(hsotg) ? "Host" : "Device")); + if (dwc2_is_device_mode(hsotg)) { + dev_dbg(hsotg->dev, "a_suspend->a_peripheral (%d)\n", + hsotg->op_state); + spin_unlock(&hsotg->lock); + dwc2_hcd_disconnect(hsotg); + spin_lock(&hsotg->lock); + hsotg->op_state = OTG_STATE_A_PERIPHERAL; + } else { + /* Need to disable SOF interrupt immediately */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk &= ~GINTSTS_SOF; + writel(gintmsk, hsotg->regs + GINTMSK); + spin_unlock(&hsotg->lock); + dwc2_hcd_start(hsotg); + spin_lock(&hsotg->lock); + hsotg->op_state = OTG_STATE_A_HOST; + } + } + + if (gotgint & GOTGINT_A_DEV_TOUT_CHG) + dev_dbg(hsotg->dev, + " ++OTG Interrupt: A-Device Timeout Change++\n"); + if (gotgint & GOTGINT_DBNCE_DONE) + dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n"); + + /* Clear GOTGINT */ + writel(gotgint, hsotg->regs + GOTGINT); +} + +/** + * dwc2_handle_conn_id_status_change_intr() - Handles the Connector ID Status + * Change Interrupt + * + * @hsotg: Programming view of DWC_otg controller + * + * Reads the OTG Interrupt Register (GOTCTL) to determine whether this is a + * Device to Host Mode transition or a Host to Device Mode transition. This only + * occurs when the cable is connected/removed from the PHY connector. + */ +static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) +{ + u32 gintmsk = readl(hsotg->regs + GINTMSK); + + /* Need to disable SOF interrupt immediately */ + gintmsk &= ~GINTSTS_SOF; + writel(gintmsk, hsotg->regs + GINTMSK); + + dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++ (%s)\n", + dwc2_is_host_mode(hsotg) ? "Host" : "Device"); + + /* + * Need to schedule a work, as there are possible DELAY function calls. + * Release lock before scheduling workq as it holds spinlock during + * scheduling. + */ + spin_unlock(&hsotg->lock); + queue_work(hsotg->wq_otg, &hsotg->wf_otg); + spin_lock(&hsotg->lock); + + /* Clear interrupt */ + writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); +} + +/** + * dwc2_handle_session_req_intr() - This interrupt indicates that a device is + * initiating the Session Request Protocol to request the host to turn on bus + * power so a new session can begin + * + * @hsotg: Programming view of DWC_otg controller + * + * This handler responds by turning on bus power. If the DWC_otg controller is + * in low power mode, this handler brings the controller out of low power mode + * before turning on bus power. + */ +static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) +{ + dev_dbg(hsotg->dev, "++Session Request Interrupt++\n"); + + /* Clear interrupt */ + writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); +} + +/* + * This interrupt indicates that the DWC_otg controller has detected a + * resume or remote wakeup sequence. If the DWC_otg controller is in + * low power mode, the handler must brings the controller out of low + * power mode. The controller automatically begins resume signaling. + * The handler schedules a time to stop resume signaling. + */ +static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) +{ + dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n"); + dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); + + if (dwc2_is_device_mode(hsotg)) { + dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS)); + if (hsotg->lx_state == DWC2_L2) { + u32 dctl = readl(hsotg->regs + DCTL); + + /* Clear Remote Wakeup Signaling */ + dctl &= ~DCTL_RMTWKUPSIG; + writel(dctl, hsotg->regs + DCTL); + } + /* Change to L0 state */ + hsotg->lx_state = DWC2_L0; + } else { + if (hsotg->lx_state != DWC2_L1) { + u32 pcgcctl = readl(hsotg->regs + PCGCTL); + + /* Restart the Phy Clock */ + pcgcctl &= ~PCGCTL_STOPPCLK; + writel(pcgcctl, hsotg->regs + PCGCTL); + mod_timer(&hsotg->wkp_timer, + jiffies + msecs_to_jiffies(71)); + } else { + /* Change to L0 state */ + hsotg->lx_state = DWC2_L0; + } + } + + /* Clear interrupt */ + writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); +} + +/* + * This interrupt indicates that a device has been disconnected from the + * root port + */ +static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) +{ + dev_dbg(hsotg->dev, "++Disconnect Detected Interrupt++ (%s) %s\n", + dwc2_is_host_mode(hsotg) ? "Host" : "Device", + dwc2_op_state_str(hsotg)); + + /* Change to L3 (OFF) state */ + hsotg->lx_state = DWC2_L3; + + writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); +} + +/* + * This interrupt indicates that SUSPEND state has been detected on the USB. + * + * For HNP the USB Suspend interrupt signals the change from "a_peripheral" + * to "a_host". + * + * When power management is enabled the core will be put in low power mode. + */ +static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) +{ + u32 dsts; + + dev_dbg(hsotg->dev, "USB SUSPEND\n"); + + if (dwc2_is_device_mode(hsotg)) { + /* + * Check the Device status register to determine if the Suspend + * state is active + */ + dsts = readl(hsotg->regs + DSTS); + dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts); + dev_dbg(hsotg->dev, + "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", + !!(dsts & DSTS_SUSPSTS), + !!(hsotg->hwcfg4 & GHWCFG4_POWER_OPTIMIZ)); + } else { + if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { + dev_dbg(hsotg->dev, "a_peripheral->a_host\n"); + + /* Clear the a_peripheral flag, back to a_host */ + spin_unlock(&hsotg->lock); + dwc2_hcd_start(hsotg); + spin_lock(&hsotg->lock); + hsotg->op_state = OTG_STATE_A_HOST; + } + } + + /* Change to L2 (suspend) state */ + hsotg->lx_state = DWC2_L2; + + /* Clear interrupt */ + writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); +} + +#define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \ + GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT | \ + GINTSTS_MODEMIS | GINTSTS_DISCONNINT | \ + GINTSTS_USBSUSP | GINTSTS_RESTOREDONE | \ + GINTSTS_PRTINT) + +/* + * This function returns the Core Interrupt register + */ +static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) +{ + u32 gintsts; + u32 gintmsk; + u32 gahbcfg; + u32 gintmsk_common = GINTMSK_COMMON; + + gintsts = readl(hsotg->regs + GINTSTS); + gintmsk = readl(hsotg->regs + GINTMSK); + gahbcfg = readl(hsotg->regs + GAHBCFG); + +#ifdef DEBUG + /* If any common interrupts set */ + if (gintsts & gintmsk_common) + dev_dbg(hsotg->dev, "gintsts=%08x gintmsk=%08x\n", + gintsts, gintmsk); +#endif + + if (gahbcfg & GAHBCFG_GLBL_INTR_EN) + return gintsts & gintmsk & gintmsk_common; + else + return 0; +} + +/* + * Common interrupt handler + * + * The common interrupts are those that occur in both Host and Device mode. + * This handler handles the following interrupts: + * - Mode Mismatch Interrupt + * - OTG Interrupt + * - Connector ID Status Change Interrupt + * - Disconnect Interrupt + * - Session Request Interrupt + * - Resume / Remote Wakeup Detected Interrupt + * - Suspend Interrupt + */ +irqreturn_t dwc2_handle_common_intr(int irq, void *dev) +{ + struct dwc2_hsotg *hsotg = dev; + u32 gintsts; + int retval = 0; + + if (dwc2_check_core_status(hsotg) < 0) { + dev_warn(hsotg->dev, "Controller is disconnected"); + goto out; + } + + spin_lock(&hsotg->lock); + + gintsts = dwc2_read_common_intr(hsotg); + if (gintsts & ~GINTSTS_PRTINT) + retval = 1; + + if (gintsts & GINTSTS_MODEMIS) + dwc2_handle_mode_mismatch_intr(hsotg); + if (gintsts & GINTSTS_OTGINT) + dwc2_handle_otg_intr(hsotg); + if (gintsts & GINTSTS_CONIDSTSCHNG) + dwc2_handle_conn_id_status_change_intr(hsotg); + if (gintsts & GINTSTS_DISCONNINT) + dwc2_handle_disconnect_intr(hsotg); + if (gintsts & GINTSTS_SESSREQINT) + dwc2_handle_session_req_intr(hsotg); + if (gintsts & GINTSTS_WKUPINT) + dwc2_handle_wakeup_detected_intr(hsotg); + if (gintsts & GINTSTS_USBSUSP) + dwc2_handle_usb_suspend_intr(hsotg); + + if (gintsts & GINTSTS_RESTOREDONE) { + gintsts = GINTSTS_RESTOREDONE; + writel(gintsts, hsotg->regs + GINTSTS); + dev_dbg(hsotg->dev, " --Restore done interrupt received--\n"); + } + + if (gintsts & GINTSTS_PRTINT) { + /* + * The port interrupt occurs while in device mode with HPRT0 + * Port Enable/Disable + */ + if (dwc2_is_device_mode(hsotg)) { + dev_dbg(hsotg->dev, + " --Port interrupt received in Device mode--\n"); + gintsts = GINTSTS_PRTINT; + writel(gintsts, hsotg->regs + GINTSTS); + retval = 1; + } + } + + spin_unlock(&hsotg->lock); +out: + return IRQ_RETVAL(retval); +} +EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); diff --git a/drivers/staging/dwc2/hw.h b/drivers/staging/dwc2/hw.h new file mode 100644 index 000000000000..382a1d74865d --- /dev/null +++ b/drivers/staging/dwc2/hw.h @@ -0,0 +1,811 @@ +/* + * hw.h - DesignWare HS OTG Controller hardware definitions + * + * Copyright 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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. + */ + +#ifndef __DWC2_HW_H__ +#define __DWC2_HW_H__ + +#define HSOTG_REG(x) (x) + +#define GOTGCTL HSOTG_REG(0x000) +#define GOTGCTL_CHIRPEN (1 << 27) +#define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) +#define GOTGCTL_MULT_VALID_BC_SHIFT 22 +#define GOTGCTL_OTGVER (1 << 20) +#define GOTGCTL_BSESVLD (1 << 19) +#define GOTGCTL_ASESVLD (1 << 18) +#define GOTGCTL_DBNC_SHORT (1 << 17) +#define GOTGCTL_CONID_B (1 << 16) +#define GOTGCTL_DEVHNPEN (1 << 11) +#define GOTGCTL_HSTSETHNPEN (1 << 10) +#define GOTGCTL_HNPREQ (1 << 9) +#define GOTGCTL_HSTNEGSCS (1 << 8) +#define GOTGCTL_SESREQ (1 << 1) +#define GOTGCTL_SESREQSCS (1 << 0) + +#define GOTGINT HSOTG_REG(0x004) +#define GOTGINT_DBNCE_DONE (1 << 19) +#define GOTGINT_A_DEV_TOUT_CHG (1 << 18) +#define GOTGINT_HST_NEG_DET (1 << 17) +#define GOTGINT_HST_NEG_SUC_STS_CHNG (1 << 9) +#define GOTGINT_SES_REQ_SUC_STS_CHNG (1 << 8) +#define GOTGINT_SES_END_DET (1 << 2) + +#define GAHBCFG HSOTG_REG(0x008) +#define GAHBCFG_AHB_SINGLE (1 << 23) +#define GAHBCFG_NOTI_ALL_DMA_WRIT (1 << 22) +#define GAHBCFG_REM_MEM_SUPP (1 << 21) +#define GAHBCFG_P_TXF_EMP_LVL (1 << 8) +#define GAHBCFG_NP_TXF_EMP_LVL (1 << 7) +#define GAHBCFG_DMA_EN (1 << 5) +#define GAHBCFG_HBSTLEN_MASK (0xf << 1) +#define GAHBCFG_HBSTLEN_SHIFT 1 +#define GAHBCFG_HBSTLEN_SINGLE (0 << 1) +#define GAHBCFG_HBSTLEN_INCR (1 << 1) +#define GAHBCFG_HBSTLEN_INCR4 (3 << 1) +#define GAHBCFG_HBSTLEN_INCR8 (5 << 1) +#define GAHBCFG_HBSTLEN_INCR16 (7 << 1) +#define GAHBCFG_GLBL_INTR_EN (1 << 0) + +#define GUSBCFG HSOTG_REG(0x00C) +#define GUSBCFG_FORCEDEVMODE (1 << 30) +#define GUSBCFG_FORCEHOSTMODE (1 << 29) +#define GUSBCFG_TXENDDELAY (1 << 28) +#define GUSBCFG_ICTRAFFICPULLREMOVE (1 << 27) +#define GUSBCFG_ICUSBCAP (1 << 26) +#define GUSBCFG_ULPI_INT_PROT_DIS (1 << 25) +#define GUSBCFG_INDICATORPASSTHROUGH (1 << 24) +#define GUSBCFG_INDICATORCOMPLEMENT (1 << 23) +#define GUSBCFG_TERMSELDLPULSE (1 << 22) +#define GUSBCFG_ULPI_INT_VBUS_IND (1 << 21) +#define GUSBCFG_ULPI_EXT_VBUS_DRV (1 << 20) +#define GUSBCFG_ULPI_CLK_SUSP_M (1 << 19) +#define GUSBCFG_ULPI_AUTO_RES (1 << 18) +#define GUSBCFG_ULPI_FS_LS (1 << 17) +#define GUSBCFG_OTG_UTMI_FS_SEL (1 << 16) +#define GUSBCFG_PHY_LP_CLK_SEL (1 << 15) +#define GUSBCFG_USBTRDTIM_MASK (0xf << 10) +#define GUSBCFG_USBTRDTIM_SHIFT 10 +#define GUSBCFG_HNPCAP (1 << 9) +#define GUSBCFG_SRPCAP (1 << 8) +#define GUSBCFG_DDRSEL (1 << 7) +#define GUSBCFG_PHYSEL (1 << 6) +#define GUSBCFG_FSINTF (1 << 5) +#define GUSBCFG_ULPI_UTMI_SEL (1 << 4) +#define GUSBCFG_PHYIF16 (1 << 3) +#define GUSBCFG_TOUTCAL_MASK (0x7 << 0) +#define GUSBCFG_TOUTCAL_SHIFT 0 +#define GUSBCFG_TOUTCAL_LIMIT 0x7 +#define GUSBCFG_TOUTCAL(_x) ((_x) << 0) + +#define GRSTCTL HSOTG_REG(0x010) +#define GRSTCTL_AHBIDLE (1 << 31) +#define GRSTCTL_DMAREQ (1 << 30) +#define GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define GRSTCTL_TXFNUM_SHIFT 6 +#define GRSTCTL_TXFNUM_LIMIT 0x1f +#define GRSTCTL_TXFNUM(_x) ((_x) << 6) +#define GRSTCTL_TXFFLSH (1 << 5) +#define GRSTCTL_RXFFLSH (1 << 4) +#define GRSTCTL_IN_TKNQ_FLSH (1 << 3) +#define GRSTCTL_FRMCNTRRST (1 << 2) +#define GRSTCTL_HSFTRST (1 << 1) +#define GRSTCTL_CSFTRST (1 << 0) + +#define GINTSTS HSOTG_REG(0x014) +#define GINTMSK HSOTG_REG(0x018) +#define GINTSTS_WKUPINT (1 << 31) +#define GINTSTS_SESSREQINT (1 << 30) +#define GINTSTS_DISCONNINT (1 << 29) +#define GINTSTS_CONIDSTSCHNG (1 << 28) +#define GINTSTS_LPMTRANRCVD (1 << 27) +#define GINTSTS_PTXFEMP (1 << 26) +#define GINTSTS_HCHINT (1 << 25) +#define GINTSTS_PRTINT (1 << 24) +#define GINTSTS_RESETDET (1 << 23) +#define GINTSTS_FET_SUSP (1 << 22) +#define GINTSTS_INCOMPL_IP (1 << 21) +#define GINTSTS_INCOMPL_SOIN (1 << 20) +#define GINTSTS_OEPINT (1 << 19) +#define GINTSTS_IEPINT (1 << 18) +#define GINTSTS_EPMIS (1 << 17) +#define GINTSTS_RESTOREDONE (1 << 16) +#define GINTSTS_EOPF (1 << 15) +#define GINTSTS_ISOUTDROP (1 << 14) +#define GINTSTS_ENUMDONE (1 << 13) +#define GINTSTS_USBRST (1 << 12) +#define GINTSTS_USBSUSP (1 << 11) +#define GINTSTS_ERLYSUSP (1 << 10) +#define GINTSTS_I2CINT (1 << 9) +#define GINTSTS_ULPI_CK_INT (1 << 8) +#define GINTSTS_GOUTNAKEFF (1 << 7) +#define GINTSTS_GINNAKEFF (1 << 6) +#define GINTSTS_NPTXFEMP (1 << 5) +#define GINTSTS_RXFLVL (1 << 4) +#define GINTSTS_SOF (1 << 3) +#define GINTSTS_OTGINT (1 << 2) +#define GINTSTS_MODEMIS (1 << 1) +#define GINTSTS_CURMODE_HOST (1 << 0) + +#define GRXSTSR HSOTG_REG(0x01C) +#define GRXSTSP HSOTG_REG(0x020) +#define GRXSTS_FN_MASK (0x7f << 25) +#define GRXSTS_FN_SHIFT 25 +#define GRXSTS_PKTSTS_MASK (0xf << 17) +#define GRXSTS_PKTSTS_SHIFT 17 +#define GRXSTS_PKTSTS_GLOBALOUTNAK (1 << 17) +#define GRXSTS_PKTSTS_OUTRX (2 << 17) +#define GRXSTS_PKTSTS_HCHIN (2 << 17) +#define GRXSTS_PKTSTS_OUTDONE (3 << 17) +#define GRXSTS_PKTSTS_HCHIN_XFER_COMP (3 << 17) +#define GRXSTS_PKTSTS_SETUPDONE (4 << 17) +#define GRXSTS_PKTSTS_DATATOGGLEERR (5 << 17) +#define GRXSTS_PKTSTS_SETUPRX (6 << 17) +#define GRXSTS_PKTSTS_HCHHALTED (7 << 17) +#define GRXSTS_HCHNUM_MASK (0xf << 0) +#define GRXSTS_HCHNUM_SHIFT 0 +#define GRXSTS_DPID_MASK (0x3 << 15) +#define GRXSTS_DPID_SHIFT 15 +#define GRXSTS_BYTECNT_MASK (0x7ff << 4) +#define GRXSTS_BYTECNT_SHIFT 4 +#define GRXSTS_EPNUM_MASK (0xf << 0) +#define GRXSTS_EPNUM_SHIFT 0 + +#define GRXFSIZ HSOTG_REG(0x024) + +#define GNPTXFSIZ HSOTG_REG(0x028) +#define GNPTXFSIZ_NP_TXF_DEP_MASK (0xffff << 16) +#define GNPTXFSIZ_NP_TXF_DEP_SHIFT 16 +#define GNPTXFSIZ_NP_TXF_DEP_LIMIT 0xffff +#define GNPTXFSIZ_NP_TXF_DEP(_x) ((_x) << 16) +#define GNPTXFSIZ_NP_TXF_ST_ADDR_MASK (0xffff << 0) +#define GNPTXFSIZ_NP_TXF_ST_ADDR_SHIFT 0 +#define GNPTXFSIZ_NP_TXF_ST_ADDR_LIMIT 0xffff +#define GNPTXFSIZ_NP_TXF_ST_ADDR(_x) ((_x) << 0) + +#define GNPTXSTS HSOTG_REG(0x02C) +#define GNPTXSTS_NP_TXQ_TOP_MASK (0x7f << 24) +#define GNPTXSTS_NP_TXQ_TOP_SHIFT 24 +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_MASK (0xff << 16) +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_SHIFT 16 +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_GET(_v) (((_v) >> 16) & 0xff) +#define GNPTXSTS_NP_TXF_SPC_AVAIL_MASK (0xffff << 0) +#define GNPTXSTS_NP_TXF_SPC_AVAIL_SHIFT 0 +#define GNPTXSTS_NP_TXF_SPC_AVAIL_GET(_v) (((_v) >> 0) & 0xffff) + +#define GI2CCTL HSOTG_REG(0x0030) +#define GI2CCTL_BSYDNE (1 << 31) +#define GI2CCTL_RW (1 << 30) +#define GI2CCTL_I2CDATSE0 (1 << 28) +#define GI2CCTL_I2CDEVADDR_MASK (0x3 << 26) +#define GI2CCTL_I2CDEVADDR_SHIFT 26 +#define GI2CCTL_I2CSUSPCTL (1 << 25) +#define GI2CCTL_ACK (1 << 24) +#define GI2CCTL_I2CEN (1 << 23) +#define GI2CCTL_ADDR_MASK (0x7f << 16) +#define GI2CCTL_ADDR_SHIFT 16 +#define GI2CCTL_REGADDR_MASK (0xff << 8) +#define GI2CCTL_REGADDR_SHIFT 8 +#define GI2CCTL_RWDATA_MASK (0xff << 0) +#define GI2CCTL_RWDATA_SHIFT 0 + +#define GPVNDCTL HSOTG_REG(0x0034) +#define GGPIO HSOTG_REG(0x0038) +#define GUID HSOTG_REG(0x003c) +#define GSNPSID HSOTG_REG(0x0040) +#define GHWCFG1 HSOTG_REG(0x0044) + +#define GHWCFG2 HSOTG_REG(0x0048) +#define GHWCFG2_OTG_ENABLE_IC_USB (1 << 31) +#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26) +#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26 +#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24) +#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24 +#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22) +#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22 +#define GHWCFG2_MULTI_PROC_INT (1 << 20) +#define GHWCFG2_DYNAMIC_FIFO (1 << 19) +#define GHWCFG2_PERIO_EP_SUPPORTED (1 << 18) +#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14) +#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14 +#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10) +#define GHWCFG2_NUM_DEV_EP_SHIFT 10 +#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8) +#define GHWCFG2_FS_PHY_TYPE_SHIFT 8 +#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED (0 << 8) +#define GHWCFG2_FS_PHY_TYPE_DEDICATED (1 << 8) +#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI (2 << 8) +#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI (3 << 8) +#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6) +#define GHWCFG2_HS_PHY_TYPE_SHIFT 6 +#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED (0 << 6) +#define GHWCFG2_HS_PHY_TYPE_UTMI (1 << 6) +#define GHWCFG2_HS_PHY_TYPE_ULPI (2 << 6) +#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI (3 << 6) +#define GHWCFG2_POINT2POINT (1 << 5) +#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3) +#define GHWCFG2_ARCHITECTURE_SHIFT 3 +#define GHWCFG2_SLAVE_ONLY_ARCH (0 << 3) +#define GHWCFG2_EXT_DMA_ARCH (1 << 3) +#define GHWCFG2_INT_DMA_ARCH (2 << 3) +#define GHWCFG2_OP_MODE_MASK (0x7 << 0) +#define GHWCFG2_OP_MODE_SHIFT 0 +#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE (0 << 0) +#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE (1 << 0) +#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE (2 << 0) +#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE (3 << 0) +#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE (4 << 0) +#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST (5 << 0) +#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST (6 << 0) +#define GHWCFG2_OP_MODE_UNDEFINED (7 << 0) + +#define GHWCFG3 HSOTG_REG(0x004c) +#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16) +#define GHWCFG3_DFIFO_DEPTH_SHIFT 16 +#define GHWCFG3_OTG_LPM_EN (1 << 15) +#define GHWCFG3_BC_SUPPORT (1 << 14) +#define GHWCFG3_OTG_ENABLE_HSIC (1 << 13) +#define GHWCFG3_ADP_SUPP (1 << 12) +#define GHWCFG3_SYNCH_RESET_TYPE (1 << 11) +#define GHWCFG3_OPTIONAL_FEATURES (1 << 10) +#define GHWCFG3_VENDOR_CTRL_IF (1 << 9) +#define GHWCFG3_I2C (1 << 8) +#define GHWCFG3_OTG_FUNC (1 << 7) +#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4) +#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4 +#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0) +#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0 + +#define GHWCFG4 HSOTG_REG(0x0050) +#define GHWCFG4_DESC_DMA_DYN (1 << 31) +#define GHWCFG4_DESC_DMA (1 << 30) +#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) +#define GHWCFG4_NUM_IN_EPS_SHIFT 26 +#define GHWCFG4_DED_FIFO_EN (1 << 25) +#define GHWCFG4_SESSION_END_FILT_EN (1 << 24) +#define GHWCFG4_B_VALID_FILT_EN (1 << 23) +#define GHWCFG4_A_VALID_FILT_EN (1 << 22) +#define GHWCFG4_VBUS_VALID_FILT_EN (1 << 21) +#define GHWCFG4_IDDIG_FILT_EN (1 << 20) +#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16) +#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16 +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14 +#define GHWCFG4_XHIBER (1 << 7) +#define GHWCFG4_HIBER (1 << 6) +#define GHWCFG4_MIN_AHB_FREQ (1 << 5) +#define GHWCFG4_POWER_OPTIMIZ (1 << 4) +#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0) +#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0 + +#define GLPMCFG HSOTG_REG(0x0054) +#define GLPMCFG_INV_SEL_HSIC (1 << 31) +#define GLPMCFG_HSIC_CONNECT (1 << 30) +#define GLPMCFG_RETRY_COUNT_STS_MASK (0x7 << 25) +#define GLPMCFG_RETRY_COUNT_STS_SHIFT 25 +#define GLPMCFG_SEND_LPM (1 << 24) +#define GLPMCFG_RETRY_COUNT_MASK (0x7 << 21) +#define GLPMCFG_RETRY_COUNT_SHIFT 21 +#define GLPMCFG_LPM_CHAN_INDEX_MASK (0xf << 17) +#define GLPMCFG_LPM_CHAN_INDEX_SHIFT 17 +#define GLPMCFG_SLEEP_STATE_RESUMEOK (1 << 16) +#define GLPMCFG_PRT_SLEEP_STS (1 << 15) +#define GLPMCFG_LPM_RESP_MASK (0x3 << 13) +#define GLPMCFG_LPM_RESP_SHIFT 13 +#define GLPMCFG_HIRD_THRES_MASK (0x1f << 8) +#define GLPMCFG_HIRD_THRES_SHIFT 8 +#define GLPMCFG_HIRD_THRES_EN (0x10 << 8) +#define GLPMCFG_EN_UTMI_SLEEP (1 << 7) +#define GLPMCFG_REM_WKUP_EN (1 << 6) +#define GLPMCFG_HIRD_MASK (0xf << 2) +#define GLPMCFG_HIRD_SHIFT 2 +#define GLPMCFG_APPL_RESP (1 << 1) +#define GLPMCFG_LPM_CAP_EN (1 << 0) + +#define GPWRDN HSOTG_REG(0x0058) +#define GPWRDN_MULT_VAL_ID_BC_MASK (0x1f << 24) +#define GPWRDN_MULT_VAL_ID_BC_SHIFT 24 +#define GPWRDN_ADP_INT (1 << 23) +#define GPWRDN_BSESSVLD (1 << 22) +#define GPWRDN_IDSTS (1 << 21) +#define GPWRDN_LINESTATE_MASK (0x3 << 19) +#define GPWRDN_LINESTATE_SHIFT 19 +#define GPWRDN_STS_CHGINT_MSK (1 << 18) +#define GPWRDN_STS_CHGINT (1 << 17) +#define GPWRDN_SRP_DET_MSK (1 << 16) +#define GPWRDN_SRP_DET (1 << 15) +#define GPWRDN_CONNECT_DET_MSK (1 << 14) +#define GPWRDN_CONNECT_DET (1 << 13) +#define GPWRDN_DISCONN_DET_MSK (1 << 12) +#define GPWRDN_DISCONN_DET (1 << 11) +#define GPWRDN_RST_DET_MSK (1 << 10) +#define GPWRDN_RST_DET (1 << 9) +#define GPWRDN_LNSTSCHG_MSK (1 << 8) +#define GPWRDN_LNSTSCHG (1 << 7) +#define GPWRDN_DIS_VBUS (1 << 6) +#define GPWRDN_PWRDNSWTCH (1 << 5) +#define GPWRDN_PWRDNRSTN (1 << 4) +#define GPWRDN_PWRDNCLMP (1 << 3) +#define GPWRDN_RESTORE (1 << 2) +#define GPWRDN_PMUACTV (1 << 1) +#define GPWRDN_PMUINTSEL (1 << 0) + +#define GDFIFOCFG HSOTG_REG(0x005c) +#define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) +#define GDFIFOCFG_EPINFOBASE_SHIFT 16 +#define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) +#define GDFIFOCFG_GDFIFOCFG_SHIFT 0 + +#define ADPCTL HSOTG_REG(0x0060) +#define ADPCTL_AR_MASK (0x3 << 27) +#define ADPCTL_AR_SHIFT 27 +#define ADPCTL_ADP_TMOUT_INT_MSK (1 << 26) +#define ADPCTL_ADP_SNS_INT_MSK (1 << 25) +#define ADPCTL_ADP_PRB_INT_MSK (1 << 24) +#define ADPCTL_ADP_TMOUT_INT (1 << 23) +#define ADPCTL_ADP_SNS_INT (1 << 22) +#define ADPCTL_ADP_PRB_INT (1 << 21) +#define ADPCTL_ADPENA (1 << 20) +#define ADPCTL_ADPRES (1 << 19) +#define ADPCTL_ENASNS (1 << 18) +#define ADPCTL_ENAPRB (1 << 17) +#define ADPCTL_RTIM_MASK (0x7ff << 6) +#define ADPCTL_RTIM_SHIFT 6 +#define ADPCTL_PRB_PER_MASK (0x3 << 4) +#define ADPCTL_PRB_PER_SHIFT 4 +#define ADPCTL_PRB_DELTA_MASK (0x3 << 2) +#define ADPCTL_PRB_DELTA_SHIFT 2 +#define ADPCTL_PRB_DSCHRG_MASK (0x3 << 0) +#define ADPCTL_PRB_DSCHRG_SHIFT 0 + +#define HPTXFSIZ HSOTG_REG(0x100) + +#define DPTXFSIZN(_a) HSOTG_REG(0x104 + (((_a) - 1) * 4)) +#define DPTXFSIZN_DP_TXF_SIZE_MASK (0xffff << 16) +#define DPTXFSIZN_DP_TXF_SIZE_SHIFT 16 +#define DPTXFSIZN_DP_TXF_SIZE_GET(_v) (((_v) >> 16) & 0xffff) +#define DPTXFSIZN_DP_TXF_SIZE_LIMIT 0xffff +#define DPTXFSIZN_DP_TXF_SIZE(_x) ((_x) << 16) +#define DPTXFSIZN_DP_TXF_ST_ADDR_MASK (0xffff << 0) +#define DPTXFSIZN_DP_TXF_ST_ADDR_SHIFT 0 + +#define FIFOSIZE_DEPTH_MASK (0xffff << 16) +#define FIFOSIZE_DEPTH_SHIFT 16 +#define FIFOSIZE_STARTADDR_MASK (0xffff << 0) +#define FIFOSIZE_STARTADDR_SHIFT 0 + +/* Device mode registers */ + +#define DCFG HSOTG_REG(0x800) +#define DCFG_EPMISCNT_MASK (0x1f << 18) +#define DCFG_EPMISCNT_SHIFT 18 +#define DCFG_EPMISCNT_LIMIT 0x1f +#define DCFG_EPMISCNT(_x) ((_x) << 18) +#define DCFG_PERFRINT_MASK (0x3 << 11) +#define DCFG_PERFRINT_SHIFT 11 +#define DCFG_PERFRINT_LIMIT 0x3 +#define DCFG_PERFRINT(_x) ((_x) << 11) +#define DCFG_DEVADDR_MASK (0x7f << 4) +#define DCFG_DEVADDR_SHIFT 4 +#define DCFG_DEVADDR_LIMIT 0x7f +#define DCFG_DEVADDR(_x) ((_x) << 4) +#define DCFG_NZ_STS_OUT_HSHK (1 << 2) +#define DCFG_DEVSPD_MASK (0x3 << 0) +#define DCFG_DEVSPD_SHIFT 0 +#define DCFG_DEVSPD_HS (0 << 0) +#define DCFG_DEVSPD_FS (1 << 0) +#define DCFG_DEVSPD_LS (2 << 0) +#define DCFG_DEVSPD_FS48 (3 << 0) + +#define DCTL HSOTG_REG(0x804) +#define DCTL_PWRONPRGDONE (1 << 11) +#define DCTL_CGOUTNAK (1 << 10) +#define DCTL_SGOUTNAK (1 << 9) +#define DCTL_CGNPINNAK (1 << 8) +#define DCTL_SGNPINNAK (1 << 7) +#define DCTL_TSTCTL_MASK (0x7 << 4) +#define DCTL_TSTCTL_SHIFT 4 +#define DCTL_GOUTNAKSTS (1 << 3) +#define DCTL_GNPINNAKSTS (1 << 2) +#define DCTL_SFTDISCON (1 << 1) +#define DCTL_RMTWKUPSIG (1 << 0) + +#define DSTS HSOTG_REG(0x808) +#define DSTS_SOFFN_MASK (0x3fff << 8) +#define DSTS_SOFFN_SHIFT 8 +#define DSTS_SOFFN_LIMIT 0x3fff +#define DSTS_SOFFN(_x) ((_x) << 8) +#define DSTS_ERRATICERR (1 << 3) +#define DSTS_ENUMSPD_MASK (0x3 << 1) +#define DSTS_ENUMSPD_SHIFT 1 +#define DSTS_ENUMSPD_HS (0 << 1) +#define DSTS_ENUMSPD_FS (1 << 1) +#define DSTS_ENUMSPD_LS (2 << 1) +#define DSTS_ENUMSPD_FS48 (3 << 1) +#define DSTS_SUSPSTS (1 << 0) + +#define DIEPMSK HSOTG_REG(0x810) +#define DIEPMSK_TXFIFOEMPTY (1 << 7) +#define DIEPMSK_INEPNAKEFFMSK (1 << 6) +#define DIEPMSK_INTKNEPMISMSK (1 << 5) +#define DIEPMSK_INTKNTXFEMPMSK (1 << 4) +#define DIEPMSK_TIMEOUTMSK (1 << 3) +#define DIEPMSK_AHBERRMSK (1 << 2) +#define DIEPMSK_EPDISBLDMSK (1 << 1) +#define DIEPMSK_XFERCOMPLMSK (1 << 0) + +#define DOEPMSK HSOTG_REG(0x814) +#define DOEPMSK_BACK2BACKSETUP (1 << 6) +#define DOEPMSK_OUTTKNEPDISMSK (1 << 4) +#define DOEPMSK_SETUPMSK (1 << 3) +#define DOEPMSK_AHBERRMSK (1 << 2) +#define DOEPMSK_EPDISBLDMSK (1 << 1) +#define DOEPMSK_XFERCOMPLMSK (1 << 0) + +#define DAINT HSOTG_REG(0x818) +#define DAINTMSK HSOTG_REG(0x81C) +#define DAINT_OUTEP_SHIFT 16 +#define DAINT_OUTEP(_x) (1 << ((_x) + 16)) +#define DAINT_INEP(_x) (1 << (_x)) + +#define DTKNQR1 HSOTG_REG(0x820) +#define DTKNQR2 HSOTG_REG(0x824) +#define DTKNQR3 HSOTG_REG(0x830) +#define DTKNQR4 HSOTG_REG(0x834) + +#define DVBUSDIS HSOTG_REG(0x828) +#define DVBUSPULSE HSOTG_REG(0x82C) + +#define DIEPCTL0 HSOTG_REG(0x900) +#define DIEPCTL(_a) HSOTG_REG(0x900 + ((_a) * 0x20)) + +#define DOEPCTL0 HSOTG_REG(0xB00) +#define DOEPCTL(_a) HSOTG_REG(0xB00 + ((_a) * 0x20)) + +/* EP0 specialness: + * bits[29..28] - reserved (no SetD0PID, SetD1PID) + * bits[25..22] - should always be zero, this isn't a periodic endpoint + * bits[10..0] - MPS setting different for EP0 + */ +#define D0EPCTL_MPS_MASK (0x3 << 0) +#define D0EPCTL_MPS_SHIFT 0 +#define D0EPCTL_MPS_64 (0 << 0) +#define D0EPCTL_MPS_32 (1 << 0) +#define D0EPCTL_MPS_16 (2 << 0) +#define D0EPCTL_MPS_8 (3 << 0) + +#define DXEPCTL_EPENA (1 << 31) +#define DXEPCTL_EPDIS (1 << 30) +#define DXEPCTL_SETD1PID (1 << 29) +#define DXEPCTL_SETODDFR (1 << 29) +#define DXEPCTL_SETD0PID (1 << 28) +#define DXEPCTL_SETEVENFR (1 << 28) +#define DXEPCTL_SNAK (1 << 27) +#define DXEPCTL_CNAK (1 << 26) +#define DXEPCTL_TXFNUM_MASK (0xf << 22) +#define DXEPCTL_TXFNUM_SHIFT 22 +#define DXEPCTL_TXFNUM_LIMIT 0xf +#define DXEPCTL_TXFNUM(_x) ((_x) << 22) +#define DXEPCTL_STALL (1 << 21) +#define DXEPCTL_SNP (1 << 20) +#define DXEPCTL_EPTYPE_MASK (0x3 << 18) +#define DXEPCTL_EPTYPE_SHIFT 18 +#define DXEPCTL_EPTYPE_CONTROL (0 << 18) +#define DXEPCTL_EPTYPE_ISO (1 << 18) +#define DXEPCTL_EPTYPE_BULK (2 << 18) +#define DXEPCTL_EPTYPE_INTTERUPT (3 << 18) +#define DXEPCTL_NAKSTS (1 << 17) +#define DXEPCTL_DPID (1 << 16) +#define DXEPCTL_EOFRNUM (1 << 16) +#define DXEPCTL_USBACTEP (1 << 15) +#define DXEPCTL_NEXTEP_MASK (0xf << 11) +#define DXEPCTL_NEXTEP_SHIFT 11 +#define DXEPCTL_NEXTEP_LIMIT 0xf +#define DXEPCTL_NEXTEP(_x) ((_x) << 11) +#define DXEPCTL_MPS_MASK (0x7ff << 0) +#define DXEPCTL_MPS_SHIFT 0 +#define DXEPCTL_MPS_LIMIT 0x7ff +#define DXEPCTL_MPS(_x) ((_x) << 0) + +#define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) +#define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) +#define DXEPINT_INEPNAKEFF (1 << 6) +#define DXEPINT_BACK2BACKSETUP (1 << 6) +#define DXEPINT_INTKNEPMIS (1 << 5) +#define DXEPINT_INTKNTXFEMP (1 << 4) +#define DXEPINT_OUTTKNEPDIS (1 << 4) +#define DXEPINT_TIMEOUT (1 << 3) +#define DXEPINT_SETUP (1 << 3) +#define DXEPINT_AHBERR (1 << 2) +#define DXEPINT_EPDISBLD (1 << 1) +#define DXEPINT_XFERCOMPL (1 << 0) + +#define DIEPTSIZ0 HSOTG_REG(0x910) +#define DIEPTSIZ0_PKTCNT_MASK (0x3 << 19) +#define DIEPTSIZ0_PKTCNT_SHIFT 19 +#define DIEPTSIZ0_PKTCNT_LIMIT 0x3 +#define DIEPTSIZ0_PKTCNT(_x) ((_x) << 19) +#define DIEPTSIZ0_XFERSIZE_MASK (0x7f << 0) +#define DIEPTSIZ0_XFERSIZE_SHIFT 0 +#define DIEPTSIZ0_XFERSIZE_LIMIT 0x7f +#define DIEPTSIZ0_XFERSIZE(_x) ((_x) << 0) + +#define DOEPTSIZ0 HSOTG_REG(0xB10) +#define DOEPTSIZ0_SUPCNT_MASK (0x3 << 29) +#define DOEPTSIZ0_SUPCNT_SHIFT 29 +#define DOEPTSIZ0_SUPCNT_LIMIT 0x3 +#define DOEPTSIZ0_SUPCNT(_x) ((_x) << 29) +#define DOEPTSIZ0_PKTCNT (1 << 19) +#define DOEPTSIZ0_XFERSIZE_MASK (0x7f << 0) +#define DOEPTSIZ0_XFERSIZE_SHIFT 0 + +#define DIEPTSIZ(_a) HSOTG_REG(0x910 + ((_a) * 0x20)) +#define DOEPTSIZ(_a) HSOTG_REG(0xB10 + ((_a) * 0x20)) +#define DXEPTSIZ_MC_MASK (0x3 << 29) +#define DXEPTSIZ_MC_SHIFT 29 +#define DXEPTSIZ_MC_LIMIT 0x3 +#define DXEPTSIZ_MC(_x) ((_x) << 29) +#define DXEPTSIZ_PKTCNT_MASK (0x3ff << 19) +#define DXEPTSIZ_PKTCNT_SHIFT 19 +#define DXEPTSIZ_PKTCNT_LIMIT 0x3ff +#define DXEPTSIZ_PKTCNT_GET(_v) (((_v) >> 19) & 0x3ff) +#define DXEPTSIZ_PKTCNT(_x) ((_x) << 19) +#define DXEPTSIZ_XFERSIZE_MASK (0x7ffff << 0) +#define DXEPTSIZ_XFERSIZE_SHIFT 0 +#define DXEPTSIZ_XFERSIZE_LIMIT 0x7ffff +#define DXEPTSIZ_XFERSIZE_GET(_v) (((_v) >> 0) & 0x7ffff) +#define DXEPTSIZ_XFERSIZE(_x) ((_x) << 0) + +#define DIEPDMA(_a) HSOTG_REG(0x914 + ((_a) * 0x20)) +#define DOEPDMA(_a) HSOTG_REG(0xB14 + ((_a) * 0x20)) + +#define DTXFSTS(_a) HSOTG_REG(0x918 + ((_a) * 0x20)) + +#define PCGCTL HSOTG_REG(0x0e00) +#define PCGCTL_IF_DEV_MODE (1 << 31) +#define PCGCTL_P2HD_PRT_SPD_MASK (0x3 << 29) +#define PCGCTL_P2HD_PRT_SPD_SHIFT 29 +#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3 << 27) +#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 +#define PCGCTL_MAC_DEV_ADDR_MASK (0x7f << 20) +#define PCGCTL_MAC_DEV_ADDR_SHIFT 20 +#define PCGCTL_MAX_TERMSEL (1 << 19) +#define PCGCTL_MAX_XCVRSELECT_MASK (0x3 << 17) +#define PCGCTL_MAX_XCVRSELECT_SHIFT 17 +#define PCGCTL_PORT_POWER (1 << 16) +#define PCGCTL_PRT_CLK_SEL_MASK (0x3 << 14) +#define PCGCTL_PRT_CLK_SEL_SHIFT 14 +#define PCGCTL_ESS_REG_RESTORED (1 << 13) +#define PCGCTL_EXTND_HIBER_SWITCH (1 << 12) +#define PCGCTL_EXTND_HIBER_PWRCLMP (1 << 11) +#define PCGCTL_ENBL_EXTND_HIBER (1 << 10) +#define PCGCTL_RESTOREMODE (1 << 9) +#define PCGCTL_RESETAFTSUSP (1 << 8) +#define PCGCTL_DEEP_SLEEP (1 << 7) +#define PCGCTL_PHY_IN_SLEEP (1 << 6) +#define PCGCTL_ENBL_SLEEP_GATING (1 << 5) +#define PCGCTL_RSTPDWNMODULE (1 << 3) +#define PCGCTL_PWRCLMP (1 << 2) +#define PCGCTL_GATEHCLK (1 << 1) +#define PCGCTL_STOPPCLK (1 << 0) + +#define EPFIFO(_a) HSOTG_REG(0x1000 + ((_a) * 0x1000)) + +/* Host Mode Registers */ + +#define HCFG HSOTG_REG(0x0400) +#define HCFG_MODECHTIMEN (1 << 31) +#define HCFG_PERSCHEDENA (1 << 26) +#define HCFG_FRLISTEN_MASK (0x3 << 24) +#define HCFG_FRLISTEN_SHIFT 24 +#define HCFG_FRLISTEN_8 (0 << 24) +#define FRLISTEN_8_SIZE 8 +#define HCFG_FRLISTEN_16 (1 << 24) +#define FRLISTEN_16_SIZE 16 +#define HCFG_FRLISTEN_32 (2 << 24) +#define FRLISTEN_32_SIZE 32 +#define HCFG_FRLISTEN_64 (3 << 24) +#define FRLISTEN_64_SIZE 64 +#define HCFG_DESCDMA (1 << 23) +#define HCFG_RESVALID_MASK (0xff << 8) +#define HCFG_RESVALID_SHIFT 8 +#define HCFG_ENA32KHZ (1 << 7) +#define HCFG_FSLSSUPP (1 << 2) +#define HCFG_FSLSPCLKSEL_MASK (0x3 << 0) +#define HCFG_FSLSPCLKSEL_SHIFT 0 +#define HCFG_FSLSPCLKSEL_30_60_MHZ (0 << 0) +#define HCFG_FSLSPCLKSEL_48_MHZ (1 << 0) +#define HCFG_FSLSPCLKSEL_6_MHZ (2 << 0) + +#define HFIR HSOTG_REG(0x0404) +#define HFIR_FRINT_MASK (0xffff << 0) +#define HFIR_FRINT_SHIFT 0 +#define HFIR_RLDCTRL (1 << 16) + +#define HFNUM HSOTG_REG(0x0408) +#define HFNUM_FRREM_MASK (0xffff << 16) +#define HFNUM_FRREM_SHIFT 16 +#define HFNUM_FRNUM_MASK (0xffff << 0) +#define HFNUM_FRNUM_SHIFT 0 +#define HFNUM_MAX_FRNUM 0x3fff + +#define HPTXSTS HSOTG_REG(0x0410) +#define TXSTS_QTOP_ODD (1 << 31) +#define TXSTS_QTOP_CHNEP_MASK (0xf << 27) +#define TXSTS_QTOP_CHNEP_SHIFT 27 +#define TXSTS_QTOP_TOKEN_MASK (0x3 << 25) +#define TXSTS_QTOP_TOKEN_SHIFT 25 +#define TXSTS_QTOP_TERMINATE (1 << 24) +#define TXSTS_QSPCAVAIL_MASK (0xff << 16) +#define TXSTS_QSPCAVAIL_SHIFT 16 +#define TXSTS_FSPCAVAIL_MASK (0xffff << 0) +#define TXSTS_FSPCAVAIL_SHIFT 0 + +#define HAINT HSOTG_REG(0x0414) +#define HAINTMSK HSOTG_REG(0x0418) +#define HFLBADDR HSOTG_REG(0x041c) + +#define HPRT0 HSOTG_REG(0x0440) +#define HPRT0_SPD_MASK (0x3 << 17) +#define HPRT0_SPD_SHIFT 17 +#define HPRT0_SPD_HIGH_SPEED (0 << 17) +#define HPRT0_SPD_FULL_SPEED (1 << 17) +#define HPRT0_SPD_LOW_SPEED (2 << 17) +#define HPRT0_TSTCTL_MASK (0xf << 13) +#define HPRT0_TSTCTL_SHIFT 13 +#define HPRT0_PWR (1 << 12) +#define HPRT0_LNSTS_MASK (0x3 << 10) +#define HPRT0_LNSTS_SHIFT 10 +#define HPRT0_RST (1 << 8) +#define HPRT0_SUSP (1 << 7) +#define HPRT0_RES (1 << 6) +#define HPRT0_OVRCURRCHG (1 << 5) +#define HPRT0_OVRCURRACT (1 << 4) +#define HPRT0_ENACHG (1 << 3) +#define HPRT0_ENA (1 << 2) +#define HPRT0_CONNDET (1 << 1) +#define HPRT0_CONNSTS (1 << 0) + +#define HCCHAR(_ch) HSOTG_REG(0x0500 + 0x20 * (_ch)) +#define HCCHAR_CHENA (1 << 31) +#define HCCHAR_CHDIS (1 << 30) +#define HCCHAR_ODDFRM (1 << 29) +#define HCCHAR_DEVADDR_MASK (0x7f << 22) +#define HCCHAR_DEVADDR_SHIFT 22 +#define HCCHAR_MULTICNT_MASK (0x3 << 20) +#define HCCHAR_MULTICNT_SHIFT 20 +#define HCCHAR_EPTYPE_MASK (0x3 << 18) +#define HCCHAR_EPTYPE_SHIFT 18 +#define HCCHAR_LSPDDEV (1 << 17) +#define HCCHAR_EPDIR (1 << 15) +#define HCCHAR_EPNUM_MASK (0xf << 11) +#define HCCHAR_EPNUM_SHIFT 11 +#define HCCHAR_MPS_MASK (0x7ff << 0) +#define HCCHAR_MPS_SHIFT 0 + +#define HCSPLT(_ch) HSOTG_REG(0x0504 + 0x20 * (_ch)) +#define HCSPLT_SPLTENA (1 << 31) +#define HCSPLT_COMPSPLT (1 << 16) +#define HCSPLT_XACTPOS_MASK (0x3 << 14) +#define HCSPLT_XACTPOS_SHIFT 14 +#define HCSPLT_XACTPOS_MID (0 << 14) +#define HCSPLT_XACTPOS_END (1 << 14) +#define HCSPLT_XACTPOS_BEGIN (2 << 14) +#define HCSPLT_XACTPOS_ALL (3 << 14) +#define HCSPLT_HUBADDR_MASK (0x7f << 7) +#define HCSPLT_HUBADDR_SHIFT 7 +#define HCSPLT_PRTADDR_MASK (0x7f << 0) +#define HCSPLT_PRTADDR_SHIFT 0 + +#define HCINT(_ch) HSOTG_REG(0x0508 + 0x20 * (_ch)) +#define HCINTMSK(_ch) HSOTG_REG(0x050c + 0x20 * (_ch)) +#define HCINTMSK_RESERVED14_31 (0x3ffff << 14) +#define HCINTMSK_FRM_LIST_ROLL (1 << 13) +#define HCINTMSK_XCS_XACT (1 << 12) +#define HCINTMSK_BNA (1 << 11) +#define HCINTMSK_DATATGLERR (1 << 10) +#define HCINTMSK_FRMOVRUN (1 << 9) +#define HCINTMSK_BBLERR (1 << 8) +#define HCINTMSK_XACTERR (1 << 7) +#define HCINTMSK_NYET (1 << 6) +#define HCINTMSK_ACK (1 << 5) +#define HCINTMSK_NAK (1 << 4) +#define HCINTMSK_STALL (1 << 3) +#define HCINTMSK_AHBERR (1 << 2) +#define HCINTMSK_CHHLTD (1 << 1) +#define HCINTMSK_XFERCOMPL (1 << 0) + +#define HCTSIZ(_ch) HSOTG_REG(0x0510 + 0x20 * (_ch)) +#define TSIZ_DOPNG (1 << 31) +#define TSIZ_SC_MC_PID_MASK (0x3 << 29) +#define TSIZ_SC_MC_PID_SHIFT 29 +#define TSIZ_SC_MC_PID_DATA0 (0 << 29) +#define TSIZ_SC_MC_PID_DATA2 (1 << 29) +#define TSIZ_SC_MC_PID_DATA1 (2 << 29) +#define TSIZ_SC_MC_PID_MDATA (3 << 29) +#define TSIZ_SC_MC_PID_SETUP (3 << 29) +#define TSIZ_PKTCNT_MASK (0x3ff << 19) +#define TSIZ_PKTCNT_SHIFT 19 +#define TSIZ_NTD_MASK (0xff << 8) +#define TSIZ_NTD_SHIFT 8 +#define TSIZ_SCHINFO_MASK (0xff << 0) +#define TSIZ_SCHINFO_SHIFT 0 +#define TSIZ_XFERSIZE_MASK (0x7ffff << 0) +#define TSIZ_XFERSIZE_SHIFT 0 + +#define HCDMA(_ch) HSOTG_REG(0x0514 + 0x20 * (_ch)) +#define HCDMA_DMA_ADDR_MASK (0x1fffff << 11) +#define HCDMA_DMA_ADDR_SHIFT 11 +#define HCDMA_CTD_MASK (0xff << 3) +#define HCDMA_CTD_SHIFT 3 + +#define HCDMAB(_ch) HSOTG_REG(0x051c + 0x20 * (_ch)) + +#define HCFIFO(_ch) HSOTG_REG(0x1000 + 0x1000 * (_ch)) + +/** + * struct dwc2_hcd_dma_desc - Host-mode DMA descriptor structure + * + * @status: DMA descriptor status quadlet + * @buf: DMA descriptor data buffer pointer + * + * DMA Descriptor structure contains two quadlets: + * Status quadlet and Data buffer pointer. + */ +struct dwc2_hcd_dma_desc { + u32 status; + u32 buf; +}; + +#define HOST_DMA_A (1 << 31) +#define HOST_DMA_STS_MASK (0x3 << 28) +#define HOST_DMA_STS_SHIFT 28 +#define HOST_DMA_STS_PKTERR (1 << 28) +#define HOST_DMA_EOL (1 << 26) +#define HOST_DMA_IOC (1 << 25) +#define HOST_DMA_SUP (1 << 24) +#define HOST_DMA_ALT_QTD (1 << 23) +#define HOST_DMA_QTD_OFFSET_MASK (0x3f << 17) +#define HOST_DMA_QTD_OFFSET_SHIFT 17 +#define HOST_DMA_ISOC_NBYTES_MASK (0xfff << 0) +#define HOST_DMA_ISOC_NBYTES_SHIFT 0 +#define HOST_DMA_NBYTES_MASK (0x1ffff << 0) +#define HOST_DMA_NBYTES_SHIFT 0 + +#define MAX_DMA_DESC_SIZE 131071 +#define MAX_DMA_DESC_NUM_GENERIC 64 +#define MAX_DMA_DESC_NUM_HS_ISOC 256 + +#endif /* __DWC2_HW_H__ */ -- cgit From 7359d482eb4d3967cc8be354405ae6be6eaf732c Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 11 Mar 2013 17:47:59 -0700 Subject: staging: HCD files for the DWC2 driver These files contain the HCD code, and implement the Linux hc_driver API. Support for both slave mode and buffer DMA mode of the controller is included. Signed-off-by: Paul Zimmerman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/hcd.c | 2951 ++++++++++++++++++++++++++++++++++++++ drivers/staging/dwc2/hcd.h | 737 ++++++++++ drivers/staging/dwc2/hcd_intr.c | 2079 +++++++++++++++++++++++++++ drivers/staging/dwc2/hcd_queue.c | 675 +++++++++ 4 files changed, 6442 insertions(+) create mode 100644 drivers/staging/dwc2/hcd.c create mode 100644 drivers/staging/dwc2/hcd.h create mode 100644 drivers/staging/dwc2/hcd_intr.c create mode 100644 drivers/staging/dwc2/hcd_queue.c (limited to 'drivers') diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c new file mode 100644 index 000000000000..cdb142dda476 --- /dev/null +++ b/drivers/staging/dwc2/hcd.c @@ -0,0 +1,2951 @@ +/* + * hcd.c - DesignWare HS OTG Controller host-mode routines + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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 file contains the core HCD code, and implements the Linux hc_driver + * API + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +/** + * dwc2_dump_channel_info() - Prints the state of a host channel + * + * @hsotg: Programming view of DWC_otg controller + * @chan: Pointer to the channel to dump + * + * Must be called with interrupt disabled and spinlock held + * + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan) +{ +#ifdef VERBOSE_DEBUG + int num_channels = hsotg->core_params->host_channels; + struct dwc2_qh *qh; + u32 hcchar; + u32 hcsplt; + u32 hctsiz; + u32 hc_dma; + int i; + + if (chan == NULL) + return; + + hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num)); + hctsiz = readl(hsotg->regs + HCTSIZ(chan->hc_num)); + hc_dma = readl(hsotg->regs + HCDMA(chan->hc_num)); + + dev_dbg(hsotg->dev, " Assigned to channel %p:\n", chan); + dev_dbg(hsotg->dev, " hcchar 0x%08x, hcsplt 0x%08x\n", + hcchar, hcsplt); + dev_dbg(hsotg->dev, " hctsiz 0x%08x, hc_dma 0x%08x\n", + hctsiz, hc_dma); + dev_dbg(hsotg->dev, " dev_addr: %d, ep_num: %d, ep_is_in: %d\n", + chan->dev_addr, chan->ep_num, chan->ep_is_in); + dev_dbg(hsotg->dev, " ep_type: %d\n", chan->ep_type); + dev_dbg(hsotg->dev, " max_packet: %d\n", chan->max_packet); + dev_dbg(hsotg->dev, " data_pid_start: %d\n", chan->data_pid_start); + dev_dbg(hsotg->dev, " xfer_started: %d\n", chan->xfer_started); + dev_dbg(hsotg->dev, " halt_status: %d\n", chan->halt_status); + dev_dbg(hsotg->dev, " xfer_buf: %p\n", chan->xfer_buf); + dev_dbg(hsotg->dev, " xfer_dma: %08lx\n", + (unsigned long)chan->xfer_dma); + dev_dbg(hsotg->dev, " xfer_len: %d\n", chan->xfer_len); + dev_dbg(hsotg->dev, " qh: %p\n", chan->qh); + dev_dbg(hsotg->dev, " NP inactive sched:\n"); + list_for_each_entry(qh, &hsotg->non_periodic_sched_inactive, + qh_list_entry) + dev_dbg(hsotg->dev, " %p\n", qh); + dev_dbg(hsotg->dev, " NP active sched:\n"); + list_for_each_entry(qh, &hsotg->non_periodic_sched_active, + qh_list_entry) + dev_dbg(hsotg->dev, " %p\n", qh); + dev_dbg(hsotg->dev, " Channels:\n"); + for (i = 0; i < num_channels; i++) { + struct dwc2_host_chan *chan = hsotg->hc_ptr_array[i]; + + dev_dbg(hsotg->dev, " %2d: %p\n", i, chan); + } +#endif /* VERBOSE_DEBUG */ +} + +/* + * Processes all the URBs in a single list of QHs. Completes them with + * -ETIMEDOUT and frees the QTD. + * + * Must be called with interrupt disabled and spinlock held + */ +static void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg, + struct list_head *qh_list) +{ + struct dwc2_qh *qh, *qh_tmp; + struct dwc2_qtd *qtd, *qtd_tmp; + + list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { + list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, + qtd_list_entry) { + if (qtd->urb != NULL) { + dwc2_host_complete(hsotg, qtd->urb->priv, + qtd->urb, -ETIMEDOUT); + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + } + } + } +} + +static void dwc2_qh_list_free(struct dwc2_hsotg *hsotg, + struct list_head *qh_list) +{ + struct dwc2_qtd *qtd, *qtd_tmp; + struct dwc2_qh *qh, *qh_tmp; + unsigned long flags; + + if (!qh_list->next) + /* The list hasn't been initialized yet */ + return; + + spin_lock_irqsave(&hsotg->lock, flags); + + /* Ensure there are no QTDs or URBs left */ + dwc2_kill_urbs_in_qh_list(hsotg, qh_list); + + list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { + dwc2_hcd_qh_unlink(hsotg, qh); + + /* Free each QTD in the QH's QTD list */ + list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, + qtd_list_entry) + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_hcd_qh_free(hsotg, qh); + spin_lock_irqsave(&hsotg->lock, flags); + } + + spin_unlock_irqrestore(&hsotg->lock, flags); +} + +/* + * Responds with an error status of -ETIMEDOUT to all URBs in the non-periodic + * and periodic schedules. The QTD associated with each URB is removed from + * the schedule and freed. This function may be called when a disconnect is + * detected or when the HCD is being stopped. + * + * Must be called with interrupt disabled and spinlock held + */ +static void dwc2_kill_all_urbs(struct dwc2_hsotg *hsotg) +{ + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->non_periodic_sched_inactive); + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->non_periodic_sched_active); + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->periodic_sched_inactive); + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->periodic_sched_ready); + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->periodic_sched_assigned); + dwc2_kill_urbs_in_qh_list(hsotg, &hsotg->periodic_sched_queued); +} + +/** + * dwc2_hcd_start() - Starts the HCD when switching to Host mode + * + * @hsotg: Pointer to struct dwc2_hsotg + */ +void dwc2_hcd_start(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + if (hsotg->op_state == OTG_STATE_B_HOST) { + /* + * Reset the port. During a HNP mode switch the reset + * needs to occur within 1ms and have a duration of at + * least 50ms. + */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RST; + writel(hprt0, hsotg->regs + HPRT0); + } + + queue_delayed_work(hsotg->wq_otg, &hsotg->start_work, + msecs_to_jiffies(50)); +} + +/* Must be called with interrupt disabled and spinlock held */ +static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) +{ + int num_channels = hsotg->core_params->host_channels; + struct dwc2_host_chan *channel; + u32 hcchar; + int i; + + if (hsotg->core_params->dma_enable <= 0) { + /* Flush out any channel requests in slave mode */ + for (i = 0; i < num_channels; i++) { + channel = hsotg->hc_ptr_array[i]; + if (!list_empty(&channel->hc_list_entry)) + continue; + hcchar = readl(hsotg->regs + HCCHAR(i)); + if (hcchar & HCCHAR_CHENA) { + hcchar &= ~(HCCHAR_CHENA | HCCHAR_EPDIR); + hcchar |= HCCHAR_CHDIS; + writel(hcchar, hsotg->regs + HCCHAR(i)); + } + } + } + + for (i = 0; i < num_channels; i++) { + channel = hsotg->hc_ptr_array[i]; + if (!list_empty(&channel->hc_list_entry)) + continue; + hcchar = readl(hsotg->regs + HCCHAR(i)); + if (hcchar & HCCHAR_CHENA) { + /* Halt the channel */ + hcchar |= HCCHAR_CHDIS; + writel(hcchar, hsotg->regs + HCCHAR(i)); + } + + dwc2_hc_cleanup(hsotg, channel); + list_add_tail(&channel->hc_list_entry, &hsotg->free_hc_list); + /* + * Added for Descriptor DMA to prevent channel double cleanup in + * release_channel_ddma(), which is called from ep_disable when + * device disconnects + */ + channel->qh = NULL; + } +} + +/** + * dwc2_hcd_disconnect() - Handles disconnect of the HCD + * + * @hsotg: Pointer to struct dwc2_hsotg + * + * Must be called with interrupt disabled and spinlock held + */ +void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) +{ + u32 intr; + + /* Set status flags for the hub driver */ + hsotg->flags.b.port_connect_status_change = 1; + hsotg->flags.b.port_connect_status = 0; + + /* + * Shutdown any transfers in process by clearing the Tx FIFO Empty + * interrupt mask and status bits and disabling subsequent host + * channel interrupts. + */ + intr = readl(hsotg->regs + GINTMSK); + intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT); + writel(intr, hsotg->regs + GINTMSK); + intr = GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT; + writel(intr, hsotg->regs + GINTSTS); + + /* + * Turn off the vbus power only if the core has transitioned to device + * mode. If still in host mode, need to keep power on to detect a + * reconnection. + */ + if (dwc2_is_device_mode(hsotg)) { + if (hsotg->op_state != OTG_STATE_A_SUSPEND) { + dev_dbg(hsotg->dev, "Disconnect: PortPower off\n"); + writel(0, hsotg->regs + HPRT0); + } + + dwc2_disable_host_interrupts(hsotg); + } + + /* Respond with an error status to all URBs in the schedule */ + dwc2_kill_all_urbs(hsotg); + + if (dwc2_is_host_mode(hsotg)) + /* Clean up any host channels that were in use */ + dwc2_hcd_cleanup_channels(hsotg); + + dwc2_host_disconnect(hsotg); +} + +/** + * dwc2_hcd_rem_wakeup() - Handles Remote Wakeup + * + * @hsotg: Pointer to struct dwc2_hsotg + */ +static void dwc2_hcd_rem_wakeup(struct dwc2_hsotg *hsotg) +{ + if (hsotg->lx_state == DWC2_L2) + hsotg->flags.b.port_suspend_change = 1; + else + hsotg->flags.b.port_l1_change = 1; +} + +/** + * dwc2_hcd_stop() - Halts the DWC_otg host mode operations in a clean manner + * + * @hsotg: Pointer to struct dwc2_hsotg + * + * Must be called with interrupt disabled and spinlock held + */ +void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) +{ + dev_dbg(hsotg->dev, "DWC OTG HCD STOP\n"); + + /* + * The root hub should be disconnected before this function is called. + * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue) + * and the QH lists (via ..._hcd_endpoint_disable). + */ + + /* Turn off all host-specific interrupts */ + dwc2_disable_host_interrupts(hsotg); + + /* Turn off the vbus power */ + dev_dbg(hsotg->dev, "PortPower off\n"); + writel(0, hsotg->regs + HPRT0); +} + +static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, + struct dwc2_hcd_urb *urb, void **ep_handle, + gfp_t mem_flags) +{ + struct dwc2_qtd *qtd; + unsigned long flags; + u32 intr_mask; + int retval; + + if (!hsotg->flags.b.port_connect_status) { + /* No longer connected */ + dev_err(hsotg->dev, "Not connected\n"); + return -ENODEV; + } + + qtd = kzalloc(sizeof(*qtd), mem_flags); + if (!qtd) + return -ENOMEM; + + dwc2_hcd_qtd_init(qtd, urb); + retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle, + mem_flags); + if (retval < 0) { + dev_err(hsotg->dev, + "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n", + retval); + kfree(qtd); + return retval; + } + + intr_mask = readl(hsotg->regs + GINTMSK); + if (!(intr_mask & GINTSTS_SOF) && retval == 0) { + enum dwc2_transaction_type tr_type; + + if (qtd->qh->ep_type == USB_ENDPOINT_XFER_BULK && + !(qtd->urb->flags & URB_GIVEBACK_ASAP)) + /* + * Do not schedule SG transactions until qtd has + * URB_GIVEBACK_ASAP set + */ + return 0; + + spin_lock_irqsave(&hsotg->lock, flags); + tr_type = dwc2_hcd_select_transactions(hsotg); + if (tr_type != DWC2_TRANSACTION_NONE) + dwc2_hcd_queue_transactions(hsotg, tr_type); + spin_unlock_irqrestore(&hsotg->lock, flags); + } + + return retval; +} + +/* Must be called with interrupt disabled and spinlock held */ +static int dwc2_hcd_urb_dequeue(struct dwc2_hsotg *hsotg, + struct dwc2_hcd_urb *urb) +{ + struct dwc2_qh *qh; + struct dwc2_qtd *urb_qtd; + + urb_qtd = urb->qtd; + if (!urb_qtd) { + dev_dbg(hsotg->dev, "## Urb QTD is NULL ##\n"); + return -EINVAL; + } + + qh = urb_qtd->qh; + if (!qh) { + dev_dbg(hsotg->dev, "## Urb QTD QH is NULL ##\n"); + return -EINVAL; + } + + if (urb_qtd->in_process && qh->channel) { + dwc2_dump_channel_info(hsotg, qh->channel); + + /* The QTD is in process (it has been assigned to a channel) */ + if (hsotg->flags.b.port_connect_status) + /* + * If still connected (i.e. in host mode), halt the + * channel so it can be used for other transfers. If + * no longer connected, the host registers can't be + * written to halt the channel since the core is in + * device mode. + */ + dwc2_hc_halt(hsotg, qh->channel, + DWC2_HC_XFER_URB_DEQUEUE); + } + + /* + * Free the QTD and clean up the associated QH. Leave the QH in the + * schedule if it has any remaining QTDs. + */ + if (hsotg->core_params->dma_desc_enable <= 0) { + u8 in_process = urb_qtd->in_process; + + dwc2_hcd_qtd_unlink_and_free(hsotg, urb_qtd, qh); + if (in_process) { + dwc2_hcd_qh_deactivate(hsotg, qh, 0); + qh->channel = NULL; + } else if (list_empty(&qh->qtd_list)) { + dwc2_hcd_qh_unlink(hsotg, qh); + } + } else { + dwc2_hcd_qtd_unlink_and_free(hsotg, urb_qtd, qh); + } + + return 0; +} + +/* Must NOT be called with interrupt disabled or spinlock held */ +static int dwc2_hcd_endpoint_disable(struct dwc2_hsotg *hsotg, + struct usb_host_endpoint *ep, int retry) +{ + struct dwc2_qtd *qtd, *qtd_tmp; + struct dwc2_qh *qh; + unsigned long flags; + int rc; + + spin_lock_irqsave(&hsotg->lock, flags); + + qh = ep->hcpriv; + if (!qh) { + rc = -EINVAL; + goto err; + } + + while (!list_empty(&qh->qtd_list) && retry--) { + if (retry == 0) { + dev_err(hsotg->dev, + "## timeout in dwc2_hcd_endpoint_disable() ##\n"); + rc = -EBUSY; + goto err; + } + + spin_unlock_irqrestore(&hsotg->lock, flags); + usleep_range(20000, 40000); + spin_lock_irqsave(&hsotg->lock, flags); + qh = ep->hcpriv; + if (!qh) { + rc = -EINVAL; + goto err; + } + } + + dwc2_hcd_qh_unlink(hsotg, qh); + + /* Free each QTD in the QH's QTD list */ + list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + + ep->hcpriv = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_hcd_qh_free(hsotg, qh); + + return 0; + +err: + ep->hcpriv = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); + + return rc; +} + +/* Must be called with interrupt disabled and spinlock held */ +static int dwc2_hcd_endpoint_reset(struct dwc2_hsotg *hsotg, + struct usb_host_endpoint *ep) +{ + struct dwc2_qh *qh = ep->hcpriv; + + if (!qh) + return -EINVAL; + + qh->data_toggle = DWC2_HC_PID_DATA0; + + return 0; +} + +/* + * Initializes dynamic portions of the DWC_otg HCD state + * + * Must be called with interrupt disabled and spinlock held + */ +static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg) +{ + struct dwc2_host_chan *chan, *chan_tmp; + int num_channels; + int i; + + hsotg->flags.d32 = 0; + + hsotg->non_periodic_qh_ptr = &hsotg->non_periodic_sched_active; + hsotg->non_periodic_channels = 0; + hsotg->periodic_channels = 0; + + /* + * Put all channels in the free channel list and clean up channel + * states + */ + list_for_each_entry_safe(chan, chan_tmp, &hsotg->free_hc_list, + hc_list_entry) + list_del_init(&chan->hc_list_entry); + + num_channels = hsotg->core_params->host_channels; + for (i = 0; i < num_channels; i++) { + chan = hsotg->hc_ptr_array[i]; + list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + dwc2_hc_cleanup(hsotg, chan); + } + + /* Initialize the DWC core for host mode operation */ + dwc2_core_host_init(hsotg); +} + +static void dwc2_hc_init_split(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) +{ + int hub_addr, hub_port; + + chan->do_split = 1; + chan->xact_pos = qtd->isoc_split_pos; + chan->complete_split = qtd->complete_split; + dwc2_host_hub_info(hsotg, urb->priv, &hub_addr, &hub_port); + chan->hub_addr = (u8)hub_addr; + chan->hub_port = (u8)hub_port; +} + +static void *dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, void *bufptr) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + struct dwc2_hcd_iso_packet_desc *frame_desc; + + switch (dwc2_hcd_get_pipe_type(&urb->pipe_info)) { + case USB_ENDPOINT_XFER_CONTROL: + chan->ep_type = USB_ENDPOINT_XFER_CONTROL; + + switch (qtd->control_phase) { + case DWC2_CONTROL_SETUP: + dev_vdbg(hsotg->dev, " Control setup transaction\n"); + chan->do_ping = 0; + chan->ep_is_in = 0; + chan->data_pid_start = DWC2_HC_PID_SETUP; + if (hsotg->core_params->dma_enable > 0) + chan->xfer_dma = urb->setup_dma; + else + chan->xfer_buf = urb->setup_packet; + chan->xfer_len = 8; + bufptr = NULL; + break; + + case DWC2_CONTROL_DATA: + dev_vdbg(hsotg->dev, " Control data transaction\n"); + chan->data_pid_start = qtd->data_toggle; + break; + + case DWC2_CONTROL_STATUS: + /* + * Direction is opposite of data direction or IN if no + * data + */ + dev_vdbg(hsotg->dev, " Control status transaction\n"); + if (urb->length == 0) + chan->ep_is_in = 1; + else + chan->ep_is_in = + dwc2_hcd_is_pipe_out(&urb->pipe_info); + if (chan->ep_is_in) + chan->do_ping = 0; + chan->data_pid_start = DWC2_HC_PID_DATA1; + chan->xfer_len = 0; + if (hsotg->core_params->dma_enable > 0) + chan->xfer_dma = hsotg->status_buf_dma; + else + chan->xfer_buf = hsotg->status_buf; + bufptr = NULL; + break; + } + break; + + case USB_ENDPOINT_XFER_BULK: + chan->ep_type = USB_ENDPOINT_XFER_BULK; + break; + + case USB_ENDPOINT_XFER_INT: + chan->ep_type = USB_ENDPOINT_XFER_INT; + break; + + case USB_ENDPOINT_XFER_ISOC: + chan->ep_type = USB_ENDPOINT_XFER_ISOC; + if (hsotg->core_params->dma_desc_enable > 0) + break; + + frame_desc = &urb->iso_descs[qtd->isoc_frame_index]; + frame_desc->status = 0; + + if (hsotg->core_params->dma_enable > 0) { + chan->xfer_dma = urb->dma; + chan->xfer_dma += frame_desc->offset + + qtd->isoc_split_offset; + } else { + chan->xfer_buf = urb->buf; + chan->xfer_buf += frame_desc->offset + + qtd->isoc_split_offset; + } + + chan->xfer_len = frame_desc->length - qtd->isoc_split_offset; + + /* For non-dword aligned buffers */ + if (hsotg->core_params->dma_enable > 0 && + (chan->xfer_dma & 0x3)) + bufptr = (u8 *)urb->buf + frame_desc->offset + + qtd->isoc_split_offset; + else + bufptr = NULL; + + if (chan->xact_pos == DWC2_HCSPLT_XACTPOS_ALL) { + if (chan->xfer_len <= 188) + chan->xact_pos = DWC2_HCSPLT_XACTPOS_ALL; + else + chan->xact_pos = DWC2_HCSPLT_XACTPOS_BEGIN; + } + break; + } + + return bufptr; +} + +static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + struct dwc2_host_chan *chan, void *bufptr) +{ + u32 buf_size; + + if (chan->ep_type != USB_ENDPOINT_XFER_ISOC) + buf_size = hsotg->core_params->max_transfer_size; + else + buf_size = 4096; + + if (!qh->dw_align_buf) { + qh->dw_align_buf = dma_alloc_coherent(hsotg->dev, buf_size, + &qh->dw_align_buf_dma, + GFP_ATOMIC); + if (!qh->dw_align_buf) + return -ENOMEM; + } + + if (!chan->ep_is_in && chan->xfer_len) { + dma_sync_single_for_cpu(hsotg->dev, chan->xfer_dma, buf_size, + DMA_TO_DEVICE); + memcpy(qh->dw_align_buf, bufptr, chan->xfer_len); + dma_sync_single_for_device(hsotg->dev, chan->xfer_dma, buf_size, + DMA_TO_DEVICE); + } + + chan->align_buf = qh->dw_align_buf_dma; + return 0; +} + +/** + * dwc2_assign_and_init_hc() - Assigns transactions from a QTD to a free host + * channel and initializes the host channel to perform the transactions. The + * host channel is removed from the free list. + * + * @hsotg: The HCD state structure + * @qh: Transactions from the first QTD for this QH are selected and assigned + * to a free host channel + */ +static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + struct dwc2_host_chan *chan; + struct dwc2_hcd_urb *urb; + struct dwc2_qtd *qtd; + void *bufptr = NULL; + + dev_vdbg(hsotg->dev, "%s(%p,%p)\n", __func__, hsotg, qh); + + if (list_empty(&qh->qtd_list)) { + dev_dbg(hsotg->dev, "No QTDs in QH list\n"); + return; + } + + if (list_empty(&hsotg->free_hc_list)) { + dev_dbg(hsotg->dev, "No free channel to assign\n"); + return; + } + + chan = list_first_entry(&hsotg->free_hc_list, struct dwc2_host_chan, + hc_list_entry); + + /* Remove the host channel from the free list */ + list_del_init(&chan->hc_list_entry); + + qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry); + urb = qtd->urb; + qh->channel = chan; + qtd->in_process = 1; + + /* + * Use usb_pipedevice to determine device address. This address is + * 0 before the SET_ADDRESS command and the correct address afterward. + */ + chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info); + chan->ep_num = dwc2_hcd_get_ep_num(&urb->pipe_info); + chan->speed = qh->dev_speed; + chan->max_packet = dwc2_max_packet(qh->maxp); + + chan->xfer_started = 0; + chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS; + chan->error_state = (qtd->error_count > 0); + chan->halt_on_queue = 0; + chan->halt_pending = 0; + chan->requests = 0; + + /* + * The following values may be modified in the transfer type section + * below. The xfer_len value may be reduced when the transfer is + * started to accommodate the max widths of the XferSize and PktCnt + * fields in the HCTSIZn register. + */ + + chan->ep_is_in = (dwc2_hcd_is_pipe_in(&urb->pipe_info) != 0); + if (chan->ep_is_in) + chan->do_ping = 0; + else + chan->do_ping = qh->ping_state; + + chan->data_pid_start = qh->data_toggle; + chan->multi_count = 1; + + if (hsotg->core_params->dma_enable > 0) { + chan->xfer_dma = urb->dma + urb->actual_length; + + /* For non-dword aligned case */ + if (hsotg->core_params->dma_desc_enable <= 0 && + (chan->xfer_dma & 0x3)) + bufptr = (u8 *)urb->buf + urb->actual_length; + } else { + chan->xfer_buf = (u8 *)urb->buf + urb->actual_length; + } + + chan->xfer_len = urb->length - urb->actual_length; + chan->xfer_count = 0; + + /* Set the split attributes if required */ + if (qh->do_split) + dwc2_hc_init_split(hsotg, chan, qtd, urb); + else + chan->do_split = 0; + + /* Set the transfer attributes */ + bufptr = dwc2_hc_init_xfer(hsotg, chan, qtd, bufptr); + + /* Non DWORD-aligned buffer case */ + if (bufptr) { + dev_vdbg(hsotg->dev, "Non-aligned buffer\n"); + if (dwc2_hc_setup_align_buf(hsotg, qh, chan, bufptr)) { + dev_err(hsotg->dev, + "%s: Failed to allocate memory to handle non-dword aligned buffer\n", + __func__); + /* Add channel back to free list */ + chan->align_buf = 0; + chan->multi_count = 0; + list_add_tail(&chan->hc_list_entry, + &hsotg->free_hc_list); + qtd->in_process = 0; + qh->channel = NULL; + return; + } + } else { + chan->align_buf = 0; + } + + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) + /* + * This value may be modified when the transfer is started + * to reflect the actual transfer length + */ + chan->multi_count = dwc2_hb_mult(qh->maxp); + + if (hsotg->core_params->dma_desc_enable > 0) + chan->desc_list_addr = qh->desc_list_dma; + + dwc2_hc_init(hsotg, chan); + chan->qh = qh; +} + +/** + * dwc2_hcd_select_transactions() - Selects transactions from the HCD transfer + * schedule and assigns them to available host channels. Called from the HCD + * interrupt handler functions. + * + * @hsotg: The HCD state structure + * + * Return: The types of new transactions that were assigned to host channels + */ +enum dwc2_transaction_type dwc2_hcd_select_transactions( + struct dwc2_hsotg *hsotg) +{ + enum dwc2_transaction_type ret_val = DWC2_TRANSACTION_NONE; + struct list_head *qh_ptr; + struct dwc2_qh *qh; + int num_channels; + +#ifdef DWC2_DEBUG_SOF + dev_vdbg(hsotg->dev, " Select Transactions\n"); +#endif + + /* Process entries in the periodic ready list */ + qh_ptr = hsotg->periodic_sched_ready.next; + while (qh_ptr != &hsotg->periodic_sched_ready) { + if (list_empty(&hsotg->free_hc_list)) + break; + qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); + dwc2_assign_and_init_hc(hsotg, qh); + + /* + * Move the QH from the periodic ready schedule to the + * periodic assigned schedule + */ + qh_ptr = qh_ptr->next; + list_move(&qh->qh_list_entry, &hsotg->periodic_sched_assigned); + ret_val = DWC2_TRANSACTION_PERIODIC; + } + + /* + * Process entries in the inactive portion of the non-periodic + * schedule. Some free host channels may not be used if they are + * reserved for periodic transfers. + */ + num_channels = hsotg->core_params->host_channels; + qh_ptr = hsotg->non_periodic_sched_inactive.next; + while (qh_ptr != &hsotg->non_periodic_sched_inactive) { + if (hsotg->non_periodic_channels >= num_channels - + hsotg->periodic_channels) + break; + if (list_empty(&hsotg->free_hc_list)) + break; + qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); + dwc2_assign_and_init_hc(hsotg, qh); + + /* + * Move the QH from the non-periodic inactive schedule to the + * non-periodic active schedule + */ + qh_ptr = qh_ptr->next; + list_move(&qh->qh_list_entry, + &hsotg->non_periodic_sched_active); + + if (ret_val == DWC2_TRANSACTION_NONE) + ret_val = DWC2_TRANSACTION_NON_PERIODIC; + else + ret_val = DWC2_TRANSACTION_ALL; + + hsotg->non_periodic_channels++; + } + + return ret_val; +} + +/** + * dwc2_queue_transaction() - Attempts to queue a single transaction request for + * a host channel associated with either a periodic or non-periodic transfer + * + * @hsotg: The HCD state structure + * @chan: Host channel descriptor associated with either a periodic or + * non-periodic transfer + * @fifo_dwords_avail: Number of DWORDs available in the periodic Tx FIFO + * for periodic transfers or the non-periodic Tx FIFO + * for non-periodic transfers + * + * Return: 1 if a request is queued and more requests may be needed to + * complete the transfer, 0 if no more requests are required for this + * transfer, -1 if there is insufficient space in the Tx FIFO + * + * This function assumes that there is space available in the appropriate + * request queue. For an OUT transfer or SETUP transaction in Slave mode, + * it checks whether space is available in the appropriate Tx FIFO. + * + * Must be called with interrupt disabled and spinlock held + */ +static int dwc2_queue_transaction(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + u16 fifo_dwords_avail) +{ + int retval = 0; + + if (hsotg->core_params->dma_enable > 0) { + if (hsotg->core_params->dma_desc_enable > 0) { + if (!chan->xfer_started || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + dwc2_hcd_start_xfer_ddma(hsotg, chan->qh); + chan->qh->ping_state = 0; + } + } else if (!chan->xfer_started) { + dwc2_hc_start_transfer(hsotg, chan); + chan->qh->ping_state = 0; + } + } else if (chan->halt_pending) { + /* Don't queue a request if the channel has been halted */ + } else if (chan->halt_on_queue) { + dwc2_hc_halt(hsotg, chan, chan->halt_status); + } else if (chan->do_ping) { + if (!chan->xfer_started) + dwc2_hc_start_transfer(hsotg, chan); + } else if (!chan->ep_is_in || + chan->data_pid_start == DWC2_HC_PID_SETUP) { + if ((fifo_dwords_avail * 4) >= chan->max_packet) { + if (!chan->xfer_started) { + dwc2_hc_start_transfer(hsotg, chan); + retval = 1; + } else { + retval = dwc2_hc_continue_transfer(hsotg, chan); + } + } else { + retval = -1; + } + } else { + if (!chan->xfer_started) { + dwc2_hc_start_transfer(hsotg, chan); + retval = 1; + } else { + retval = dwc2_hc_continue_transfer(hsotg, chan); + } + } + + return retval; +} + +/* + * Processes periodic channels for the next frame and queues transactions for + * these channels to the DWC_otg controller. After queueing transactions, the + * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions + * to queue as Periodic Tx FIFO or request queue space becomes available. + * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled. + * + * Must be called with interrupt disabled and spinlock held + */ +static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) +{ + struct list_head *qh_ptr; + struct dwc2_qh *qh; + u32 tx_status; + u32 fspcavail; + u32 gintmsk; + int status; + int no_queue_space = 0; + int no_fifo_space = 0; + u32 qspcavail; + + dev_vdbg(hsotg->dev, "Queue periodic transactions\n"); + + tx_status = readl(hsotg->regs + HPTXSTS); + qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + dev_vdbg(hsotg->dev, " P Tx Req Queue Space Avail (before queue): %d\n", + qspcavail); + dev_vdbg(hsotg->dev, " P Tx FIFO Space Avail (before queue): %d\n", + fspcavail); + + qh_ptr = hsotg->periodic_sched_assigned.next; + while (qh_ptr != &hsotg->periodic_sched_assigned) { + tx_status = readl(hsotg->regs + HPTXSTS); + if ((tx_status & TXSTS_QSPCAVAIL_MASK) == 0) { + no_queue_space = 1; + break; + } + + qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); + if (!qh->channel) { + qh_ptr = qh_ptr->next; + continue; + } + + /* Make sure EP's TT buffer is clean before queueing qtds */ + if (qh->tt_buffer_dirty) { + qh_ptr = qh_ptr->next; + continue; + } + + /* + * Set a flag if we're queuing high-bandwidth in slave mode. + * The flag prevents any halts to get into the request queue in + * the middle of multiple high-bandwidth packets getting queued. + */ + if (hsotg->core_params->dma_enable <= 0 && + qh->channel->multi_count > 1) + hsotg->queuing_high_bandwidth = 1; + + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + status = dwc2_queue_transaction(hsotg, qh->channel, fspcavail); + if (status < 0) { + no_fifo_space = 1; + break; + } + + /* + * In Slave mode, stay on the current transfer until there is + * nothing more to do or the high-bandwidth request count is + * reached. In DMA mode, only need to queue one request. The + * controller automatically handles multiple packets for + * high-bandwidth transfers. + */ + if (hsotg->core_params->dma_enable > 0 || status == 0 || + qh->channel->requests == qh->channel->multi_count) { + qh_ptr = qh_ptr->next; + /* + * Move the QH from the periodic assigned schedule to + * the periodic queued schedule + */ + list_move(&qh->qh_list_entry, + &hsotg->periodic_sched_queued); + + /* done queuing high bandwidth */ + hsotg->queuing_high_bandwidth = 0; + } + } + + if (hsotg->core_params->dma_enable <= 0) { + tx_status = readl(hsotg->regs + HPTXSTS); + qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + dev_vdbg(hsotg->dev, + " P Tx Req Queue Space Avail (after queue): %d\n", + qspcavail); + dev_vdbg(hsotg->dev, + " P Tx FIFO Space Avail (after queue): %d\n", + fspcavail); + + if (!list_empty(&hsotg->periodic_sched_assigned) || + no_queue_space || no_fifo_space) { + /* + * May need to queue more transactions as the request + * queue or Tx FIFO empties. Enable the periodic Tx + * FIFO empty interrupt. (Always use the half-empty + * level to ensure that new requests are loaded as + * soon as possible.) + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk |= GINTSTS_PTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } else { + /* + * Disable the Tx FIFO empty interrupt since there are + * no more transactions that need to be queued right + * now. This function is called from interrupt + * handlers to queue more transactions as transfer + * states change. + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk &= ~GINTSTS_PTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } + } +} + +/* + * Processes active non-periodic channels and queues transactions for these + * channels to the DWC_otg controller. After queueing transactions, the NP Tx + * FIFO Empty interrupt is enabled if there are more transactions to queue as + * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx + * FIFO Empty interrupt is disabled. + * + * Must be called with interrupt disabled and spinlock held + */ +static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) +{ + struct list_head *orig_qh_ptr; + struct dwc2_qh *qh; + u32 tx_status; + u32 qspcavail; + u32 fspcavail; + u32 gintmsk; + int status; + int no_queue_space = 0; + int no_fifo_space = 0; + int more_to_do = 0; + + dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n"); + + tx_status = readl(hsotg->regs + GNPTXSTS); + qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + dev_vdbg(hsotg->dev, " NP Tx Req Queue Space Avail (before queue): %d\n", + qspcavail); + dev_vdbg(hsotg->dev, " NP Tx FIFO Space Avail (before queue): %d\n", + fspcavail); + + /* + * Keep track of the starting point. Skip over the start-of-list + * entry. + */ + if (hsotg->non_periodic_qh_ptr == &hsotg->non_periodic_sched_active) + hsotg->non_periodic_qh_ptr = hsotg->non_periodic_qh_ptr->next; + orig_qh_ptr = hsotg->non_periodic_qh_ptr; + + /* + * Process once through the active list or until no more space is + * available in the request queue or the Tx FIFO + */ + do { + tx_status = readl(hsotg->regs + GNPTXSTS); + qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) { + no_queue_space = 1; + break; + } + + qh = list_entry(hsotg->non_periodic_qh_ptr, struct dwc2_qh, + qh_list_entry); + if (!qh->channel) + goto next; + + /* Make sure EP's TT buffer is clean before queueing qtds */ + if (qh->tt_buffer_dirty) + goto next; + + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + status = dwc2_queue_transaction(hsotg, qh->channel, fspcavail); + + if (status > 0) { + more_to_do = 1; + } else if (status < 0) { + no_fifo_space = 1; + break; + } +next: + /* Advance to next QH, skipping start-of-list entry */ + hsotg->non_periodic_qh_ptr = hsotg->non_periodic_qh_ptr->next; + if (hsotg->non_periodic_qh_ptr == + &hsotg->non_periodic_sched_active) + hsotg->non_periodic_qh_ptr = + hsotg->non_periodic_qh_ptr->next; + } while (hsotg->non_periodic_qh_ptr != orig_qh_ptr); + + if (hsotg->core_params->dma_enable <= 0) { + tx_status = readl(hsotg->regs + GNPTXSTS); + qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + dev_vdbg(hsotg->dev, + " NP Tx Req Queue Space Avail (after queue): %d\n", + qspcavail); + dev_vdbg(hsotg->dev, + " NP Tx FIFO Space Avail (after queue): %d\n", + fspcavail); + + if (more_to_do || no_queue_space || no_fifo_space) { + /* + * May need to queue more transactions as the request + * queue or Tx FIFO empties. Enable the non-periodic + * Tx FIFO empty interrupt. (Always use the half-empty + * level to ensure that new requests are loaded as + * soon as possible.) + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk |= GINTSTS_NPTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } else { + /* + * Disable the Tx FIFO empty interrupt since there are + * no more transactions that need to be queued right + * now. This function is called from interrupt + * handlers to queue more transactions as transfer + * states change. + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk &= ~GINTSTS_NPTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } + } +} + +/** + * dwc2_hcd_queue_transactions() - Processes the currently active host channels + * and queues transactions for these channels to the DWC_otg controller. Called + * from the HCD interrupt handler functions. + * + * @hsotg: The HCD state structure + * @tr_type: The type(s) of transactions to queue (non-periodic, periodic, + * or both) + * + * Must be called with interrupt disabled and spinlock held + */ +void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, + enum dwc2_transaction_type tr_type) +{ +#ifdef DWC2_DEBUG_SOF + dev_vdbg(hsotg->dev, "Queue Transactions\n"); +#endif + /* Process host channels associated with periodic transfers */ + if ((tr_type == DWC2_TRANSACTION_PERIODIC || + tr_type == DWC2_TRANSACTION_ALL) && + !list_empty(&hsotg->periodic_sched_assigned)) + dwc2_process_periodic_channels(hsotg); + + /* Process host channels associated with non-periodic transfers */ + if (tr_type == DWC2_TRANSACTION_NON_PERIODIC || + tr_type == DWC2_TRANSACTION_ALL) { + if (!list_empty(&hsotg->non_periodic_sched_active)) { + dwc2_process_non_periodic_channels(hsotg); + } else { + /* + * Ensure NP Tx FIFO empty interrupt is disabled when + * there are no non-periodic transfers to process + */ + u32 gintmsk = readl(hsotg->regs + GINTMSK); + + gintmsk &= ~GINTSTS_NPTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } + } +} + +static void dwc2_conn_id_status_change(struct work_struct *work) +{ + struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, + wf_otg); + u32 count = 0; + u32 gotgctl; + + dev_dbg(hsotg->dev, "%s()\n", __func__); + + gotgctl = readl(hsotg->regs + GOTGCTL); + dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl); + dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n", + !!(gotgctl & GOTGCTL_CONID_B)); + + /* B-Device connector (Device Mode) */ + if (gotgctl & GOTGCTL_CONID_B) { + /* Wait for switch to device mode */ + dev_dbg(hsotg->dev, "connId B\n"); + while (!dwc2_is_device_mode(hsotg)) { + dev_info(hsotg->dev, + "Waiting for Peripheral Mode, Mode=%s\n", + dwc2_is_host_mode(hsotg) ? "Host" : + "Peripheral"); + usleep_range(20000, 40000); + if (++count > 250) + break; + } + if (count > 250) + dev_err(hsotg->dev, + "Connection id status change timed out"); + hsotg->op_state = OTG_STATE_B_PERIPHERAL; + dwc2_core_init(hsotg, false); + dwc2_enable_global_interrupts(hsotg); + } else { + /* A-Device connector (Host Mode) */ + dev_dbg(hsotg->dev, "connId A\n"); + while (!dwc2_is_host_mode(hsotg)) { + dev_info(hsotg->dev, "Waiting for Host Mode, Mode=%s\n", + dwc2_is_host_mode(hsotg) ? + "Host" : "Peripheral"); + usleep_range(20000, 40000); + if (++count > 250) + break; + } + if (count > 250) + dev_err(hsotg->dev, + "Connection id status change timed out"); + hsotg->op_state = OTG_STATE_A_HOST; + + /* Initialize the Core for Host mode */ + dwc2_core_init(hsotg, false); + dwc2_enable_global_interrupts(hsotg); + dwc2_hcd_start(hsotg); + } +} + +static void dwc2_wakeup_detected(unsigned long data) +{ + struct dwc2_hsotg *hsotg = (struct dwc2_hsotg *)data; + u32 hprt0; + + dev_dbg(hsotg->dev, "%s()\n", __func__); + + /* + * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms + * so that OPT tests pass with all PHYs.) + */ + hprt0 = dwc2_read_hprt0(hsotg); + dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0); + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n", + readl(hsotg->regs + HPRT0)); + + dwc2_hcd_rem_wakeup(hsotg); + + /* Change to L0 state */ + hsotg->lx_state = DWC2_L0; +} + +static int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg) +{ + struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg); + + return hcd->self.b_hnp_enable; +} + +/* Must NOT be called with interrupt disabled or spinlock held */ +static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) +{ + unsigned long flags; + u32 hprt0; + u32 pcgctl; + u32 gotgctl; + + dev_dbg(hsotg->dev, "%s()\n", __func__); + + spin_lock_irqsave(&hsotg->lock, flags); + + if (windex == hsotg->otg_port && dwc2_host_is_b_hnp_enabled(hsotg)) { + gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl |= GOTGCTL_HSTSETHNPEN; + writel(gotgctl, hsotg->regs + GOTGCTL); + hsotg->op_state = OTG_STATE_A_SUSPEND; + } + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_SUSP; + writel(hprt0, hsotg->regs + HPRT0); + + /* Update lx_state */ + hsotg->lx_state = DWC2_L2; + + /* Suspend the Phy Clock */ + pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl |= PCGCTL_STOPPCLK; + writel(pcgctl, hsotg->regs + PCGCTL); + udelay(10); + + /* For HNP the bus must be suspended for at least 200ms */ + if (dwc2_host_is_b_hnp_enabled(hsotg)) { + pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl &= ~PCGCTL_STOPPCLK; + writel(pcgctl, hsotg->regs + PCGCTL); + + spin_unlock_irqrestore(&hsotg->lock, flags); + + usleep_range(200000, 250000); + } else { + spin_unlock_irqrestore(&hsotg->lock, flags); + } +} + +/* Handles hub class-specific requests */ +static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, + u16 wvalue, u16 windex, char *buf, u16 wlength) +{ + struct usb_hub_descriptor *hub_desc; + int retval = 0; + u32 hprt0; + u32 port_status; + u32 speed; + u32 pcgctl; + + switch (typereq) { + case ClearHubFeature: + dev_dbg(hsotg->dev, "ClearHubFeature %1xh\n", wvalue); + + switch (wvalue) { + case C_HUB_LOCAL_POWER: + case C_HUB_OVER_CURRENT: + /* Nothing required here */ + break; + + default: + retval = -EINVAL; + dev_err(hsotg->dev, + "ClearHubFeature request %1xh unknown\n", + wvalue); + } + break; + + case ClearPortFeature: + if (wvalue != USB_PORT_FEAT_L1) + if (!windex || windex > 1) + goto error; + switch (wvalue) { + case USB_PORT_FEAT_ENABLE: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_ENA; + writel(hprt0, hsotg->regs + HPRT0); + break; + + case USB_PORT_FEAT_SUSPEND: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); + writel(0, hsotg->regs + PCGCTL); + usleep_range(20000, 40000); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + usleep_range(100000, 150000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + break; + + case USB_PORT_FEAT_POWER: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_POWER\n"); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 &= ~HPRT0_PWR; + writel(hprt0, hsotg->regs + HPRT0); + break; + + case USB_PORT_FEAT_INDICATOR: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_INDICATOR\n"); + /* Port indicator not supported */ + break; + + case USB_PORT_FEAT_C_CONNECTION: + /* + * Clears driver's internal Connect Status Change flag + */ + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n"); + hsotg->flags.b.port_connect_status_change = 0; + break; + + case USB_PORT_FEAT_C_RESET: + /* Clears driver's internal Port Reset Change flag */ + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_RESET\n"); + hsotg->flags.b.port_reset_change = 0; + break; + + case USB_PORT_FEAT_C_ENABLE: + /* + * Clears the driver's internal Port Enable/Disable + * Change flag + */ + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n"); + hsotg->flags.b.port_enable_change = 0; + break; + + case USB_PORT_FEAT_C_SUSPEND: + /* + * Clears the driver's internal Port Suspend Change + * flag, which is set when resume signaling on the host + * port is complete + */ + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n"); + hsotg->flags.b.port_suspend_change = 0; + break; + + case USB_PORT_FEAT_C_PORT_L1: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_PORT_L1\n"); + hsotg->flags.b.port_l1_change = 0; + break; + + case USB_PORT_FEAT_C_OVER_CURRENT: + dev_dbg(hsotg->dev, + "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n"); + hsotg->flags.b.port_over_current_change = 0; + break; + + default: + retval = -EINVAL; + dev_err(hsotg->dev, + "ClearPortFeature request %1xh unknown or unsupported\n", + wvalue); + } + break; + + case GetHubDescriptor: + dev_dbg(hsotg->dev, "GetHubDescriptor\n"); + hub_desc = (struct usb_hub_descriptor *)buf; + hub_desc->bDescLength = 9; + hub_desc->bDescriptorType = 0x29; + hub_desc->bNbrPorts = 1; + hub_desc->wHubCharacteristics = cpu_to_le16(0x08); + hub_desc->bPwrOn2PwrGood = 1; + hub_desc->bHubContrCurrent = 0; + hub_desc->u.hs.DeviceRemovable[0] = 0; + hub_desc->u.hs.DeviceRemovable[1] = 0xff; + break; + + case GetHubStatus: + dev_dbg(hsotg->dev, "GetHubStatus\n"); + memset(buf, 0, 4); + break; + + case GetPortStatus: + dev_dbg(hsotg->dev, + "GetPortStatus wIndex=0x%04x flags=0x%08x\n", windex, + hsotg->flags.d32); + if (!windex || windex > 1) + goto error; + + port_status = 0; + if (hsotg->flags.b.port_connect_status_change) + port_status |= USB_PORT_STAT_C_CONNECTION << 16; + if (hsotg->flags.b.port_enable_change) + port_status |= USB_PORT_STAT_C_ENABLE << 16; + if (hsotg->flags.b.port_suspend_change) + port_status |= USB_PORT_STAT_C_SUSPEND << 16; + if (hsotg->flags.b.port_l1_change) + port_status |= USB_PORT_STAT_C_L1 << 16; + if (hsotg->flags.b.port_reset_change) + port_status |= USB_PORT_STAT_C_RESET << 16; + if (hsotg->flags.b.port_over_current_change) { + dev_warn(hsotg->dev, "Overcurrent change detected\n"); + port_status |= USB_PORT_STAT_C_OVERCURRENT << 16; + } + + if (!hsotg->flags.b.port_connect_status) { + /* + * The port is disconnected, which means the core is + * either in device mode or it soon will be. Just + * return 0's for the remainder of the port status + * since the port register can't be read if the core + * is in device mode. + */ + *(__le32 *)buf = cpu_to_le32(port_status); + break; + } + + hprt0 = readl(hsotg->regs + HPRT0); + dev_dbg(hsotg->dev, " HPRT0: 0x%08x\n", hprt0); + + if (hprt0 & HPRT0_CONNSTS) + port_status |= USB_PORT_STAT_CONNECTION; + if (hprt0 & HPRT0_ENA) + port_status |= USB_PORT_STAT_ENABLE; + if (hprt0 & HPRT0_SUSP) + port_status |= USB_PORT_STAT_SUSPEND; + if (hprt0 & HPRT0_OVRCURRACT) + port_status |= USB_PORT_STAT_OVERCURRENT; + if (hprt0 & HPRT0_RST) + port_status |= USB_PORT_STAT_RESET; + if (hprt0 & HPRT0_PWR) + port_status |= USB_PORT_STAT_POWER; + + speed = hprt0 & HPRT0_SPD_MASK; + if (speed == HPRT0_SPD_HIGH_SPEED) + port_status |= USB_PORT_STAT_HIGH_SPEED; + else if (speed == HPRT0_SPD_LOW_SPEED) + port_status |= USB_PORT_STAT_LOW_SPEED; + + if (hprt0 & HPRT0_TSTCTL_MASK) + port_status |= USB_PORT_STAT_TEST; + /* USB_PORT_FEAT_INDICATOR unsupported always 0 */ + + dev_dbg(hsotg->dev, "port_status=%08x\n", port_status); + *(__le32 *)buf = cpu_to_le32(port_status); + break; + + case SetHubFeature: + dev_dbg(hsotg->dev, "SetHubFeature\n"); + /* No HUB features supported */ + break; + + case SetPortFeature: + dev_dbg(hsotg->dev, "SetPortFeature\n"); + if (wvalue != USB_PORT_FEAT_TEST && (!windex || windex > 1)) + goto error; + + if (!hsotg->flags.b.port_connect_status) { + /* + * The port is disconnected, which means the core is + * either in device mode or it soon will be. Just + * return without doing anything since the port + * register can't be written if the core is in device + * mode. + */ + break; + } + + switch (wvalue) { + case USB_PORT_FEAT_SUSPEND: + dev_dbg(hsotg->dev, + "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); + if (windex != hsotg->otg_port) + goto error; + dwc2_port_suspend(hsotg, windex); + break; + + case USB_PORT_FEAT_POWER: + dev_dbg(hsotg->dev, + "SetPortFeature - USB_PORT_FEAT_POWER\n"); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + writel(hprt0, hsotg->regs + HPRT0); + break; + + case USB_PORT_FEAT_RESET: + hprt0 = dwc2_read_hprt0(hsotg); + dev_dbg(hsotg->dev, + "SetPortFeature - USB_PORT_FEAT_RESET\n"); + pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK); + writel(pcgctl, hsotg->regs + PCGCTL); + /* ??? Original driver does this */ + writel(0, hsotg->regs + PCGCTL); + + hprt0 = dwc2_read_hprt0(hsotg); + /* Clear suspend bit if resetting from suspend state */ + hprt0 &= ~HPRT0_SUSP; + + /* + * When B-Host the Port reset bit is set in the Start + * HCD Callback function, so that the reset is started + * within 1ms of the HNP success interrupt + */ + if (!dwc2_hcd_is_b_host(hsotg)) { + hprt0 |= HPRT0_PWR | HPRT0_RST; + dev_dbg(hsotg->dev, + "In host mode, hprt0=%08x\n", hprt0); + writel(hprt0, hsotg->regs + HPRT0); + } + + /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ + usleep_range(50000, 70000); + hprt0 &= ~HPRT0_RST; + writel(hprt0, hsotg->regs + HPRT0); + hsotg->lx_state = DWC2_L0; /* Now back to On state */ + break; + + case USB_PORT_FEAT_INDICATOR: + dev_dbg(hsotg->dev, + "SetPortFeature - USB_PORT_FEAT_INDICATOR\n"); + /* Not supported */ + break; + + default: + retval = -EINVAL; + dev_err(hsotg->dev, + "SetPortFeature %1xh unknown or unsupported\n", + wvalue); + break; + } + break; + + default: +error: + retval = -EINVAL; + dev_dbg(hsotg->dev, + "Unknown hub control request: %1xh wIndex: %1xh wValue: %1xh\n", + typereq, windex, wvalue); + break; + } + + return retval; +} + +static int dwc2_hcd_is_status_changed(struct dwc2_hsotg *hsotg, int port) +{ + int retval; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (port != 1) + return -EINVAL; + + retval = (hsotg->flags.b.port_connect_status_change || + hsotg->flags.b.port_reset_change || + hsotg->flags.b.port_enable_change || + hsotg->flags.b.port_suspend_change || + hsotg->flags.b.port_over_current_change); + + if (retval) { + dev_dbg(hsotg->dev, + "DWC OTG HCD HUB STATUS DATA: Root port status changed\n"); + dev_dbg(hsotg->dev, " port_connect_status_change: %d\n", + hsotg->flags.b.port_connect_status_change); + dev_dbg(hsotg->dev, " port_reset_change: %d\n", + hsotg->flags.b.port_reset_change); + dev_dbg(hsotg->dev, " port_enable_change: %d\n", + hsotg->flags.b.port_enable_change); + dev_dbg(hsotg->dev, " port_suspend_change: %d\n", + hsotg->flags.b.port_suspend_change); + dev_dbg(hsotg->dev, " port_over_current_change: %d\n", + hsotg->flags.b.port_over_current_change); + } + + return retval; +} + +int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ + u32 hfnum = readl(hsotg->regs + HFNUM); + +#ifdef DWC2_DEBUG_SOF + dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n", + hfnum >> HFNUM_FRNUM_SHIFT & + HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT); +#endif + return hfnum >> HFNUM_FRNUM_SHIFT & + HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT; +} + +int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg) +{ + return (hsotg->op_state == OTG_STATE_B_HOST); +} + +static struct dwc2_hcd_urb *dwc2_hcd_urb_alloc(struct dwc2_hsotg *hsotg, + int iso_desc_count, + gfp_t mem_flags) +{ + struct dwc2_hcd_urb *urb; + u32 size = sizeof(*urb) + iso_desc_count * + sizeof(struct dwc2_hcd_iso_packet_desc); + + urb = kzalloc(size, mem_flags); + if (urb) + urb->packet_count = iso_desc_count; + return urb; +} + +static void dwc2_hcd_urb_set_pipeinfo(struct dwc2_hsotg *hsotg, + struct dwc2_hcd_urb *urb, u8 dev_addr, + u8 ep_num, u8 ep_type, u8 ep_dir, u16 mps) +{ + dev_vdbg(hsotg->dev, + "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, mps=%d\n", + dev_addr, ep_num, ep_dir, ep_type, mps); + urb->pipe_info.dev_addr = dev_addr; + urb->pipe_info.ep_num = ep_num; + urb->pipe_info.pipe_type = ep_type; + urb->pipe_info.pipe_dir = ep_dir; + urb->pipe_info.mps = mps; +} + +/* + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) +{ +#ifdef DEBUG + struct dwc2_host_chan *chan; + struct dwc2_hcd_urb *urb; + struct dwc2_qtd *qtd; + int num_channels; + u32 np_tx_status; + u32 p_tx_status; + int i; + + num_channels = hsotg->core_params->host_channels; + dev_dbg(hsotg->dev, "\n"); + dev_dbg(hsotg->dev, + "************************************************************\n"); + dev_dbg(hsotg->dev, "HCD State:\n"); + dev_dbg(hsotg->dev, " Num channels: %d\n", num_channels); + + for (i = 0; i < num_channels; i++) { + chan = hsotg->hc_ptr_array[i]; + dev_dbg(hsotg->dev, " Channel %d:\n", i); + dev_dbg(hsotg->dev, + " dev_addr: %d, ep_num: %d, ep_is_in: %d\n", + chan->dev_addr, chan->ep_num, chan->ep_is_in); + dev_dbg(hsotg->dev, " speed: %d\n", chan->speed); + dev_dbg(hsotg->dev, " ep_type: %d\n", chan->ep_type); + dev_dbg(hsotg->dev, " max_packet: %d\n", chan->max_packet); + dev_dbg(hsotg->dev, " data_pid_start: %d\n", + chan->data_pid_start); + dev_dbg(hsotg->dev, " multi_count: %d\n", chan->multi_count); + dev_dbg(hsotg->dev, " xfer_started: %d\n", + chan->xfer_started); + dev_dbg(hsotg->dev, " xfer_buf: %p\n", chan->xfer_buf); + dev_dbg(hsotg->dev, " xfer_dma: %08lx\n", + (unsigned long)chan->xfer_dma); + dev_dbg(hsotg->dev, " xfer_len: %d\n", chan->xfer_len); + dev_dbg(hsotg->dev, " xfer_count: %d\n", chan->xfer_count); + dev_dbg(hsotg->dev, " halt_on_queue: %d\n", + chan->halt_on_queue); + dev_dbg(hsotg->dev, " halt_pending: %d\n", + chan->halt_pending); + dev_dbg(hsotg->dev, " halt_status: %d\n", chan->halt_status); + dev_dbg(hsotg->dev, " do_split: %d\n", chan->do_split); + dev_dbg(hsotg->dev, " complete_split: %d\n", + chan->complete_split); + dev_dbg(hsotg->dev, " hub_addr: %d\n", chan->hub_addr); + dev_dbg(hsotg->dev, " hub_port: %d\n", chan->hub_port); + dev_dbg(hsotg->dev, " xact_pos: %d\n", chan->xact_pos); + dev_dbg(hsotg->dev, " requests: %d\n", chan->requests); + dev_dbg(hsotg->dev, " qh: %p\n", chan->qh); + + if (chan->xfer_started) { + u32 hfnum, hcchar, hctsiz, hcint, hcintmsk; + + hfnum = readl(hsotg->regs + HFNUM); + hcchar = readl(hsotg->regs + HCCHAR(i)); + hctsiz = readl(hsotg->regs + HCTSIZ(i)); + hcint = readl(hsotg->regs + HCINT(i)); + hcintmsk = readl(hsotg->regs + HCINTMSK(i)); + dev_dbg(hsotg->dev, " hfnum: 0x%08x\n", hfnum); + dev_dbg(hsotg->dev, " hcchar: 0x%08x\n", hcchar); + dev_dbg(hsotg->dev, " hctsiz: 0x%08x\n", hctsiz); + dev_dbg(hsotg->dev, " hcint: 0x%08x\n", hcint); + dev_dbg(hsotg->dev, " hcintmsk: 0x%08x\n", hcintmsk); + } + + if (!(chan->xfer_started && chan->qh)) + continue; + + list_for_each_entry(qtd, &chan->qh->qtd_list, qtd_list_entry) { + if (!qtd->in_process) + break; + urb = qtd->urb; + dev_dbg(hsotg->dev, " URB Info:\n"); + dev_dbg(hsotg->dev, " qtd: %p, urb: %p\n", + qtd, urb); + if (urb) { + dev_dbg(hsotg->dev, + " Dev: %d, EP: %d %s\n", + dwc2_hcd_get_dev_addr(&urb->pipe_info), + dwc2_hcd_get_ep_num(&urb->pipe_info), + dwc2_hcd_is_pipe_in(&urb->pipe_info) ? + "IN" : "OUT"); + dev_dbg(hsotg->dev, + " Max packet size: %d\n", + dwc2_hcd_get_mps(&urb->pipe_info)); + dev_dbg(hsotg->dev, + " transfer_buffer: %p\n", + urb->buf); + dev_dbg(hsotg->dev, " transfer_dma: %p\n", + (void *)urb->dma); + dev_dbg(hsotg->dev, + " transfer_buffer_length: %d\n", + urb->length); + dev_dbg(hsotg->dev, " actual_length: %d\n", + urb->actual_length); + } + } + } + + dev_dbg(hsotg->dev, " non_periodic_channels: %d\n", + hsotg->non_periodic_channels); + dev_dbg(hsotg->dev, " periodic_channels: %d\n", + hsotg->periodic_channels); + dev_dbg(hsotg->dev, " periodic_usecs: %d\n", hsotg->periodic_usecs); + np_tx_status = readl(hsotg->regs + GNPTXSTS); + dev_dbg(hsotg->dev, " NP Tx Req Queue Space Avail: %d\n", + np_tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT); + dev_dbg(hsotg->dev, " NP Tx FIFO Space Avail: %d\n", + np_tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT); + p_tx_status = readl(hsotg->regs + HPTXSTS); + dev_dbg(hsotg->dev, " P Tx Req Queue Space Avail: %d\n", + p_tx_status >> TXSTS_QSPCAVAIL_SHIFT & + TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT); + dev_dbg(hsotg->dev, " P Tx FIFO Space Avail: %d\n", + p_tx_status >> TXSTS_FSPCAVAIL_SHIFT & + TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT); + dwc2_hcd_dump_frrem(hsotg); + dwc2_dump_global_registers(hsotg); + dwc2_dump_host_registers(hsotg); + dev_dbg(hsotg->dev, + "************************************************************\n"); + dev_dbg(hsotg->dev, "\n"); +#endif +} + +/* + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg) +{ +#ifdef DWC2_DUMP_FRREM + dev_dbg(hsotg->dev, "Frame remaining at SOF:\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->frrem_samples, hsotg->frrem_accum, + hsotg->frrem_samples > 0 ? + hsotg->frrem_accum / hsotg->frrem_samples : 0); + dev_dbg(hsotg->dev, "\n"); + dev_dbg(hsotg->dev, "Frame remaining at start_transfer (uframe 7):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_7_samples, + hsotg->hfnum_7_frrem_accum, + hsotg->hfnum_7_samples > 0 ? + hsotg->hfnum_7_frrem_accum / hsotg->hfnum_7_samples : 0); + dev_dbg(hsotg->dev, "Frame remaining at start_transfer (uframe 0):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_0_samples, + hsotg->hfnum_0_frrem_accum, + hsotg->hfnum_0_samples > 0 ? + hsotg->hfnum_0_frrem_accum / hsotg->hfnum_0_samples : 0); + dev_dbg(hsotg->dev, "Frame remaining at start_transfer (uframe 1-6):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_other_samples, + hsotg->hfnum_other_frrem_accum, + hsotg->hfnum_other_samples > 0 ? + hsotg->hfnum_other_frrem_accum / hsotg->hfnum_other_samples : + 0); + dev_dbg(hsotg->dev, "\n"); + dev_dbg(hsotg->dev, "Frame remaining at sample point A (uframe 7):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_7_samples_a, hsotg->hfnum_7_frrem_accum_a, + hsotg->hfnum_7_samples_a > 0 ? + hsotg->hfnum_7_frrem_accum_a / hsotg->hfnum_7_samples_a : 0); + dev_dbg(hsotg->dev, "Frame remaining at sample point A (uframe 0):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_0_samples_a, hsotg->hfnum_0_frrem_accum_a, + hsotg->hfnum_0_samples_a > 0 ? + hsotg->hfnum_0_frrem_accum_a / hsotg->hfnum_0_samples_a : 0); + dev_dbg(hsotg->dev, "Frame remaining at sample point A (uframe 1-6):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_other_samples_a, hsotg->hfnum_other_frrem_accum_a, + hsotg->hfnum_other_samples_a > 0 ? + hsotg->hfnum_other_frrem_accum_a / hsotg->hfnum_other_samples_a + : 0); + dev_dbg(hsotg->dev, "\n"); + dev_dbg(hsotg->dev, "Frame remaining at sample point B (uframe 7):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_7_samples_b, hsotg->hfnum_7_frrem_accum_b, + hsotg->hfnum_7_samples_b > 0 ? + hsotg->hfnum_7_frrem_accum_b / hsotg->hfnum_7_samples_b : 0); + dev_dbg(hsotg->dev, "Frame remaining at sample point B (uframe 0):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_0_samples_b, hsotg->hfnum_0_frrem_accum_b, + (hsotg->hfnum_0_samples_b > 0) ? + hsotg->hfnum_0_frrem_accum_b / hsotg->hfnum_0_samples_b : 0); + dev_dbg(hsotg->dev, "Frame remaining at sample point B (uframe 1-6):\n"); + dev_dbg(hsotg->dev, " samples %u, accum %llu, avg %llu\n", + hsotg->hfnum_other_samples_b, hsotg->hfnum_other_frrem_accum_b, + (hsotg->hfnum_other_samples_b > 0) ? + hsotg->hfnum_other_frrem_accum_b / hsotg->hfnum_other_samples_b + : 0); +#endif +} + +struct wrapper_priv_data { + struct dwc2_hsotg *hsotg; +}; + +/* Gets the dwc2_hsotg from a usb_hcd */ +static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd) +{ + struct wrapper_priv_data *p; + + p = (struct wrapper_priv_data *) &hcd->hcd_priv; + return p->hsotg; +} + +static int _dwc2_hcd_start(struct usb_hcd *hcd); + +void dwc2_host_start(struct dwc2_hsotg *hsotg) +{ + struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg); + + hcd->self.is_b_host = dwc2_hcd_is_b_host(hsotg); + _dwc2_hcd_start(hcd); +} + +void dwc2_host_disconnect(struct dwc2_hsotg *hsotg) +{ + struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg); + + hcd->self.is_b_host = 0; +} + +void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context, int *hub_addr, + int *hub_port) +{ + struct urb *urb = context; + + if (urb->dev->tt) + *hub_addr = urb->dev->tt->hub->devnum; + else + *hub_addr = 0; + *hub_port = urb->dev->ttport; +} + +int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context) +{ + struct urb *urb = context; + + return urb->dev->speed; +} + +static void dwc2_allocate_bus_bandwidth(struct usb_hcd *hcd, u16 bw, + struct urb *urb) +{ + struct usb_bus *bus = hcd_to_bus(hcd); + + if (urb->interval) + bus->bandwidth_allocated += bw / urb->interval; + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + bus->bandwidth_isoc_reqs++; + else + bus->bandwidth_int_reqs++; +} + +static void dwc2_free_bus_bandwidth(struct usb_hcd *hcd, u16 bw, + struct urb *urb) +{ + struct usb_bus *bus = hcd_to_bus(hcd); + + if (urb->interval) + bus->bandwidth_allocated -= bw / urb->interval; + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + bus->bandwidth_isoc_reqs--; + else + bus->bandwidth_int_reqs--; +} + +/* + * Sets the final status of an URB and returns it to the upper layer. Any + * required cleanup of the URB is performed. + * + * Must be called with interrupt disabled and spinlock held + */ +void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context, + struct dwc2_hcd_urb *dwc2_urb, int status) +{ + struct urb *urb = context; + int i; + + if (!urb) { + dev_dbg(hsotg->dev, "## %s: context is NULL ##\n", __func__); + return; + } + + if (!dwc2_urb) { + dev_dbg(hsotg->dev, "## %s: dwc2_urb is NULL ##\n", __func__); + return; + } + + urb->actual_length = dwc2_hcd_urb_get_actual_length(dwc2_urb); + + dev_vdbg(hsotg->dev, + "%s: urb %p device %d ep %d-%s status %d actual %d\n", + __func__, urb, usb_pipedevice(urb->pipe), + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "IN" : "OUT", status, + urb->actual_length); + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + for (i = 0; i < urb->number_of_packets; i++) + dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n", + i, urb->iso_frame_desc[i].status); + } + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + urb->error_count = dwc2_hcd_urb_get_error_count(dwc2_urb); + for (i = 0; i < urb->number_of_packets; ++i) { + urb->iso_frame_desc[i].actual_length = + dwc2_hcd_urb_get_iso_desc_actual_length( + dwc2_urb, i); + urb->iso_frame_desc[i].status = + dwc2_hcd_urb_get_iso_desc_status(dwc2_urb, i); + } + } + + urb->status = status; + urb->hcpriv = NULL; + if (!status) { + if ((urb->transfer_flags & URB_SHORT_NOT_OK) && + urb->actual_length < urb->transfer_buffer_length) + urb->status = -EREMOTEIO; + } + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS || + usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + struct usb_host_endpoint *ep = urb->ep; + + if (ep) + dwc2_free_bus_bandwidth(dwc2_hsotg_to_hcd(hsotg), + dwc2_hcd_get_ep_bandwidth(hsotg, ep), + urb); + } + + kfree(dwc2_urb); + + spin_unlock(&hsotg->lock); + usb_hcd_giveback_urb(dwc2_hsotg_to_hcd(hsotg), urb, status); + spin_lock(&hsotg->lock); +} + +/* + * Work queue function for starting the HCD when A-Cable is connected + */ +static void dwc2_hcd_start_func(struct work_struct *work) +{ + struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, + start_work.work); + + dev_dbg(hsotg->dev, "%s() %p\n", __func__, hsotg); + dwc2_host_start(hsotg); +} + +/* + * Reset work queue function + */ +static void dwc2_hcd_reset_func(struct work_struct *work) +{ + struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, + reset_work.work); + u32 hprt0; + + dev_dbg(hsotg->dev, "USB RESET function called\n"); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 &= ~HPRT0_RST; + writel(hprt0, hsotg->regs + HPRT0); + hsotg->flags.b.port_reset_change = 1; +} + +/* + * ========================================================================= + * Linux HC Driver Functions + * ========================================================================= + */ + +/* + * Initializes the DWC_otg controller and its root hub and prepares it for host + * mode operation. Activates the root port. Returns 0 on success and a negative + * error code on failure. + */ +static int _dwc2_hcd_start(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + struct usb_bus *bus = hcd_to_bus(hcd); + unsigned long flags; + + dev_dbg(hsotg->dev, "DWC OTG HCD START\n"); + + spin_lock_irqsave(&hsotg->lock, flags); + + hcd->state = HC_STATE_RUNNING; + + if (dwc2_is_device_mode(hsotg)) { + spin_unlock_irqrestore(&hsotg->lock, flags); + return 0; /* why 0 ?? */ + } + + dwc2_hcd_reinit(hsotg); + + /* Initialize and connect root hub if one is not already attached */ + if (bus->root_hub) { + dev_dbg(hsotg->dev, "DWC OTG HCD Has Root Hub\n"); + /* Inform the HUB driver to resume */ + usb_hcd_resume_root_hub(hcd); + } + + spin_unlock_irqrestore(&hsotg->lock, flags); + return 0; +} + +/* + * Halts the DWC_otg host mode operations in a clean manner. USB transfers are + * stopped. + */ +static void _dwc2_hcd_stop(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + unsigned long flags; + + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_hcd_stop(hsotg); + spin_unlock_irqrestore(&hsotg->lock, flags); + + usleep_range(1000, 3000); +} + +/* Returns the current frame number */ +static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + + return dwc2_hcd_get_frame_number(hsotg); +} + +static void dwc2_dump_urb_info(struct usb_hcd *hcd, struct urb *urb, + char *fn_name) +{ +#ifdef VERBOSE_DEBUG + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + char *pipetype; + char *speed; + + dev_vdbg(hsotg->dev, "%s, urb %p\n", fn_name, urb); + dev_vdbg(hsotg->dev, " Device address: %d\n", + usb_pipedevice(urb->pipe)); + dev_vdbg(hsotg->dev, " Endpoint: %d, %s\n", + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "IN" : "OUT"); + + switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: + pipetype = "CONTROL"; + break; + case PIPE_BULK: + pipetype = "BULK"; + break; + case PIPE_INTERRUPT: + pipetype = "INTERRUPT"; + break; + case PIPE_ISOCHRONOUS: + pipetype = "ISOCHRONOUS"; + break; + default: + pipetype = "UNKNOWN"; + break; + } + + dev_vdbg(hsotg->dev, " Endpoint type: %s %s (%s)\n", pipetype, + usb_urb_dir_in(urb) ? "IN" : "OUT", usb_pipein(urb->pipe) ? + "IN" : "OUT"); + + switch (urb->dev->speed) { + case USB_SPEED_HIGH: + speed = "HIGH"; + break; + case USB_SPEED_FULL: + speed = "FULL"; + break; + case USB_SPEED_LOW: + speed = "LOW"; + break; + default: + speed = "UNKNOWN"; + break; + } + + dev_vdbg(hsotg->dev, " Speed: %s\n", speed); + dev_vdbg(hsotg->dev, " Max packet size: %d\n", + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); + dev_vdbg(hsotg->dev, " Data buffer length: %d\n", + urb->transfer_buffer_length); + dev_vdbg(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %p\n", + urb->transfer_buffer, (void *)urb->transfer_dma); + dev_vdbg(hsotg->dev, " Setup buffer: %p, Setup DMA: %p\n", + urb->setup_packet, (void *)urb->setup_dma); + dev_vdbg(hsotg->dev, " Interval: %d\n", urb->interval); + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + int i; + + for (i = 0; i < urb->number_of_packets; i++) { + dev_vdbg(hsotg->dev, " ISO Desc %d:\n", i); + dev_vdbg(hsotg->dev, " offset: %d, length %d\n", + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].length); + } + } +#endif +} + +/* + * Starts processing a USB transfer request specified by a USB Request Block + * (URB). mem_flags indicates the type of memory allocation to use while + * processing this URB. + */ +static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + struct usb_host_endpoint *ep = urb->ep; + struct dwc2_hcd_urb *dwc2_urb; + int i; + int alloc_bandwidth = 0; + int retval = 0; + u8 ep_type = 0; + u32 tflags = 0; + void *buf; + unsigned long flags; + + dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n"); + dwc2_dump_urb_info(hcd, urb, "urb_enqueue"); + + if (ep == NULL) + return -EINVAL; + + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS || + usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + spin_lock_irqsave(&hsotg->lock, flags); + if (!dwc2_hcd_is_bandwidth_allocated(hsotg, ep)) + alloc_bandwidth = 1; + spin_unlock_irqrestore(&hsotg->lock, flags); + } + + switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: + ep_type = USB_ENDPOINT_XFER_CONTROL; + break; + case PIPE_ISOCHRONOUS: + ep_type = USB_ENDPOINT_XFER_ISOC; + break; + case PIPE_BULK: + ep_type = USB_ENDPOINT_XFER_BULK; + break; + case PIPE_INTERRUPT: + ep_type = USB_ENDPOINT_XFER_INT; + break; + default: + dev_warn(hsotg->dev, "Wrong ep type\n"); + } + + dwc2_urb = dwc2_hcd_urb_alloc(hsotg, urb->number_of_packets, + mem_flags); + if (!dwc2_urb) + return -ENOMEM; + + dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, usb_pipedevice(urb->pipe), + usb_pipeendpoint(urb->pipe), ep_type, + usb_pipein(urb->pipe), + usb_maxpacket(urb->dev, urb->pipe, + !(usb_pipein(urb->pipe)))); + + buf = urb->transfer_buffer; + if (hcd->self.uses_dma) { + /* + * Calculate virtual address from physical address, because + * some class driver may not fill transfer_buffer. + * In Buffer DMA mode virtual address is used, when handling + * non-DWORD aligned buffers. + */ + buf = bus_to_virt(urb->transfer_dma); + } + + if (!(urb->transfer_flags & URB_NO_INTERRUPT)) + tflags |= URB_GIVEBACK_ASAP; + if (urb->transfer_flags & URB_ZERO_PACKET) + tflags |= URB_SEND_ZERO_PACKET; + + dwc2_urb->priv = urb; + dwc2_urb->buf = buf; + dwc2_urb->dma = urb->transfer_dma; + dwc2_urb->length = urb->transfer_buffer_length; + dwc2_urb->setup_packet = urb->setup_packet; + dwc2_urb->setup_dma = urb->setup_dma; + dwc2_urb->flags = tflags; + dwc2_urb->interval = urb->interval; + dwc2_urb->status = -EINPROGRESS; + + for (i = 0; i < urb->number_of_packets; ++i) + dwc2_hcd_urb_set_iso_desc_params(dwc2_urb, i, + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].length); + + urb->hcpriv = dwc2_urb; + retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, + mem_flags); + if (retval) { + urb->hcpriv = NULL; + kfree(dwc2_urb); + } else { + if (alloc_bandwidth) { + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_allocate_bus_bandwidth(hcd, + dwc2_hcd_get_ep_bandwidth(hsotg, ep), + urb); + spin_unlock_irqrestore(&hsotg->lock, flags); + } + } + + return retval; +} + +/* + * Aborts/cancels a USB transfer request. Always returns 0 to indicate success. + */ +static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, + int status) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + int rc = 0; + unsigned long flags; + + dev_dbg(hsotg->dev, "DWC OTG HCD URB Dequeue\n"); + dwc2_dump_urb_info(hcd, urb, "urb_dequeue"); + + spin_lock_irqsave(&hsotg->lock, flags); + + if (!urb->hcpriv) { + dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n"); + goto out; + } + + rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); + + kfree(urb->hcpriv); + urb->hcpriv = NULL; + + /* Higher layer software sets URB status */ + spin_unlock(&hsotg->lock); + usb_hcd_giveback_urb(hcd, urb, status); + spin_lock(&hsotg->lock); + + dev_dbg(hsotg->dev, "Called usb_hcd_giveback_urb()\n"); + dev_dbg(hsotg->dev, " urb->status = %d\n", urb->status); +out: + spin_unlock_irqrestore(&hsotg->lock, flags); + + return rc; +} + +/* + * Frees resources in the DWC_otg controller related to a given endpoint. Also + * clears state in the HCD related to the endpoint. Any URBs for the endpoint + * must already be dequeued. + */ +static void _dwc2_hcd_endpoint_disable(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + + dev_dbg(hsotg->dev, + "DWC OTG HCD EP DISABLE: bEndpointAddress=0x%02x, ep->hcpriv=%p\n", + ep->desc.bEndpointAddress, ep->hcpriv); + dwc2_hcd_endpoint_disable(hsotg, ep, 250); +} + +/* + * Resets endpoint specific parameter values, in current version used to reset + * the data toggle (as a WA). This function can be called from usb_clear_halt + * routine. + */ +static void _dwc2_hcd_endpoint_reset(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + int is_control = usb_endpoint_xfer_control(&ep->desc); + int is_out = usb_endpoint_dir_out(&ep->desc); + int epnum = usb_endpoint_num(&ep->desc); + struct usb_device *udev; + unsigned long flags; + + dev_dbg(hsotg->dev, + "DWC OTG HCD EP RESET: bEndpointAddress=0x%02x\n", + ep->desc.bEndpointAddress); + + udev = to_usb_device(hsotg->dev); + + spin_lock_irqsave(&hsotg->lock, flags); + + usb_settoggle(udev, epnum, is_out, 0); + if (is_control) + usb_settoggle(udev, epnum, !is_out, 0); + dwc2_hcd_endpoint_reset(hsotg, ep); + + spin_unlock_irqrestore(&hsotg->lock, flags); +} + +/* + * Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if + * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid + * interrupt. + * + * This function is called by the USB core when an interrupt occurs + */ +static irqreturn_t _dwc2_hcd_irq(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + int retval = dwc2_hcd_intr(hsotg); + + return IRQ_RETVAL(retval); +} + +/* + * Creates Status Change bitmap for the root hub and root port. The bitmap is + * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1 + * is the status change indicator for the single root port. Returns 1 if either + * change indicator is 1, otherwise returns 0. + */ +static int _dwc2_hcd_hub_status_data(struct usb_hcd *hcd, char *buf) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + + buf[0] = dwc2_hcd_is_status_changed(hsotg, 1) << 1; + return buf[0] != 0; +} + +/* Handles hub class-specific requests */ +static int _dwc2_hcd_hub_control(struct usb_hcd *hcd, u16 typereq, u16 wvalue, + u16 windex, char *buf, u16 wlength) +{ + int retval = dwc2_hcd_hub_control(dwc2_hcd_to_hsotg(hcd), typereq, + wvalue, windex, buf, wlength); + return retval; +} + +/* Handles hub TT buffer clear completions */ +static void _dwc2_hcd_clear_tt_buffer_complete(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + struct dwc2_qh *qh; + unsigned long flags; + + qh = ep->hcpriv; + if (!qh) + return; + + spin_lock_irqsave(&hsotg->lock, flags); + qh->tt_buffer_dirty = 0; + + if (hsotg->flags.b.port_connect_status) + dwc2_hcd_queue_transactions(hsotg, DWC2_TRANSACTION_ALL); + + spin_unlock_irqrestore(&hsotg->lock, flags); +} + +static struct hc_driver dwc2_hc_driver = { + .description = "dwc2_hsotg", + .product_desc = "DWC OTG Controller", + .hcd_priv_size = sizeof(struct wrapper_priv_data), + + .irq = _dwc2_hcd_irq, + .flags = HCD_MEMORY | HCD_USB2, + + .start = _dwc2_hcd_start, + .stop = _dwc2_hcd_stop, + .urb_enqueue = _dwc2_hcd_urb_enqueue, + .urb_dequeue = _dwc2_hcd_urb_dequeue, + .endpoint_disable = _dwc2_hcd_endpoint_disable, + .endpoint_reset = _dwc2_hcd_endpoint_reset, + .get_frame_number = _dwc2_hcd_get_frame_number, + + .hub_status_data = _dwc2_hcd_hub_status_data, + .hub_control = _dwc2_hcd_hub_control, + .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, +}; + +/* + * Frees secondary storage associated with the dwc2_hsotg structure contained + * in the struct usb_hcd field + */ +static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) +{ + u32 ahbcfg; + u32 dctl; + int i; + + dev_dbg(hsotg->dev, "DWC OTG HCD FREE\n"); + + /* Free memory for QH/QTD lists */ + dwc2_qh_list_free(hsotg, &hsotg->non_periodic_sched_inactive); + dwc2_qh_list_free(hsotg, &hsotg->non_periodic_sched_active); + dwc2_qh_list_free(hsotg, &hsotg->periodic_sched_inactive); + dwc2_qh_list_free(hsotg, &hsotg->periodic_sched_ready); + dwc2_qh_list_free(hsotg, &hsotg->periodic_sched_assigned); + dwc2_qh_list_free(hsotg, &hsotg->periodic_sched_queued); + + /* Free memory for the host channels */ + for (i = 0; i < MAX_EPS_CHANNELS; i++) { + struct dwc2_host_chan *chan = hsotg->hc_ptr_array[i]; + + if (chan != NULL) { + dev_dbg(hsotg->dev, "HCD Free channel #%i, chan=%p\n", + i, chan); + hsotg->hc_ptr_array[i] = NULL; + kfree(chan); + } + } + + if (hsotg->core_params->dma_enable > 0) { + if (hsotg->status_buf) { + dma_free_coherent(hsotg->dev, DWC2_HCD_STATUS_BUF_SIZE, + hsotg->status_buf, + hsotg->status_buf_dma); + hsotg->status_buf = NULL; + } + } else { + kfree(hsotg->status_buf); + hsotg->status_buf = NULL; + } + + ahbcfg = readl(hsotg->regs + GAHBCFG); + + /* Disable all interrupts */ + ahbcfg &= ~GAHBCFG_GLBL_INTR_EN; + writel(ahbcfg, hsotg->regs + GAHBCFG); + writel(0, hsotg->regs + GINTMSK); + + if (hsotg->snpsid >= DWC2_CORE_REV_3_00a) { + dctl = readl(hsotg->regs + DCTL); + dctl |= DCTL_SFTDISCON; + writel(dctl, hsotg->regs + DCTL); + } + + if (hsotg->wq_otg) { + if (!cancel_work_sync(&hsotg->wf_otg)) + flush_workqueue(hsotg->wq_otg); + destroy_workqueue(hsotg->wq_otg); + } + + kfree(hsotg->core_params); + hsotg->core_params = NULL; + del_timer(&hsotg->wkp_timer); +} + +static void dwc2_hcd_release(struct dwc2_hsotg *hsotg) +{ + /* Turn off all host-specific interrupts */ + dwc2_disable_host_interrupts(hsotg); + + dwc2_hcd_free(hsotg); +} + +static void dwc2_set_uninitialized(int *p, int size) +{ + int i; + + for (i = 0; i < size; i++) + p[i] = -1; +} + +/* + * Initializes the HCD. This function allocates memory for and initializes the + * static parts of the usb_hcd and dwc2_hsotg structures. It also registers the + * USB bus with the core and calls the hc_driver->start() function. It returns + * a negative error on failure. + */ +int dwc2_hcd_init(struct device *dev, struct dwc2_hsotg *hsotg, int irq, + struct dwc2_core_params *params) +{ + struct usb_hcd *hcd; + struct dwc2_host_chan *channel; + u32 snpsid, gusbcfg, hcfg; + int i, num_channels; + int retval = -ENOMEM; + + dev_dbg(dev, "DWC OTG HCD INIT\n"); + + /* + * Attempt to ensure this device is really a DWC_otg Controller. + * Read and verify the GSNPSID register contents. The value should be + * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3", + * as in "OTG version 2.xx" or "OTG version 3.xx". + */ + snpsid = readl(hsotg->regs + GSNPSID); + if ((snpsid & 0xfffff000) != 0x4f542000 && + (snpsid & 0xfffff000) != 0x4f543000) { + dev_err(dev, "Bad value for GSNPSID: 0x%08x\n", snpsid); + retval = -ENODEV; + goto error1; + } + + hcd = usb_create_hcd(&dwc2_hc_driver, dev, dev_name(dev)); + if (!hcd) + goto error1; + + hcd->has_tt = 1; + + spin_lock_init(&hsotg->lock); + ((struct wrapper_priv_data *) &hcd->hcd_priv)->hsotg = hsotg; + hsotg->priv = hcd; + hsotg->dev = dev; + + /* + * Store the contents of the hardware configuration registers here for + * easy access later + */ + hsotg->hwcfg1 = readl(hsotg->regs + GHWCFG1); + hsotg->hwcfg2 = readl(hsotg->regs + GHWCFG2); + hsotg->hwcfg3 = readl(hsotg->regs + GHWCFG3); + hsotg->hwcfg4 = readl(hsotg->regs + GHWCFG4); + + dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hsotg->hwcfg1); + dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hsotg->hwcfg2); + dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hsotg->hwcfg3); + dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hsotg->hwcfg4); + + /* Force host mode to get HPTXFSIZ exact power on value */ + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + + hsotg->hptxfsiz = readl(hsotg->regs + HPTXFSIZ); + dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hsotg->hptxfsiz); + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + + hcfg = readl(hsotg->regs + HCFG); + dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg); + dev_dbg(hsotg->dev, "op_mode=%0x\n", + hsotg->hwcfg2 >> GHWCFG2_OP_MODE_SHIFT & + GHWCFG2_OP_MODE_MASK >> GHWCFG2_OP_MODE_SHIFT); + dev_dbg(hsotg->dev, "arch=%0x\n", + hsotg->hwcfg2 >> GHWCFG2_ARCHITECTURE_SHIFT & + GHWCFG2_ARCHITECTURE_MASK >> GHWCFG2_ARCHITECTURE_SHIFT); + dev_dbg(hsotg->dev, "num_dev_ep=%d\n", + hsotg->hwcfg2 >> GHWCFG2_NUM_DEV_EP_SHIFT & + GHWCFG2_NUM_DEV_EP_MASK >> GHWCFG2_NUM_DEV_EP_SHIFT); + dev_dbg(hsotg->dev, "max_host_chan=%d\n", + hsotg->hwcfg2 >> GHWCFG2_NUM_HOST_CHAN_SHIFT & + GHWCFG2_NUM_HOST_CHAN_MASK >> GHWCFG2_NUM_HOST_CHAN_SHIFT); + dev_dbg(hsotg->dev, "nonperio_tx_q_depth=0x%0x\n", + hsotg->hwcfg2 >> GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT & + GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK >> + GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT); + dev_dbg(hsotg->dev, "host_perio_tx_q_depth=0x%0x\n", + hsotg->hwcfg2 >> GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT & + GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK >> + GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT); + dev_dbg(hsotg->dev, "dev_token_q_depth=0x%0x\n", + hsotg->hwcfg2 >> GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT & + GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK >> + GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT); + +#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS + hsotg->frame_num_array = kzalloc(sizeof(*hsotg->frame_num_array) * + FRAME_NUM_ARRAY_SIZE, GFP_KERNEL); + if (!hsotg->frame_num_array) + goto error2; + hsotg->last_frame_num_array = kzalloc( + sizeof(*hsotg->last_frame_num_array) * + FRAME_NUM_ARRAY_SIZE, GFP_KERNEL); + if (!hsotg->last_frame_num_array) + goto error2; + hsotg->last_frame_num = HFNUM_MAX_FRNUM; +#endif + + hsotg->core_params = kzalloc(sizeof(*hsotg->core_params), GFP_KERNEL); + if (!hsotg->core_params) + goto error2; + + dwc2_set_uninitialized((int *)hsotg->core_params, + sizeof(*hsotg->core_params) / sizeof(int)); + + /* Validate parameter values */ + dwc2_set_parameters(hsotg, params); + + /* Initialize the DWC_otg core, and select the Phy type */ + retval = dwc2_core_init(hsotg, true); + if (retval) + goto error2; + + /* + * Disable the global interrupt until all the interrupt handlers are + * installed + */ + dwc2_disable_global_interrupts(hsotg); + + /* Create new workqueue and init work */ + hsotg->wq_otg = create_singlethread_workqueue("dwc_otg"); + if (!hsotg->wq_otg) { + dev_err(hsotg->dev, "Failed to create workqueue\n"); + goto error2; + } + INIT_WORK(&hsotg->wf_otg, dwc2_conn_id_status_change); + + hsotg->snpsid = readl(hsotg->regs + GSNPSID); + dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x\n", + hsotg->snpsid >> 12 & 0xf, hsotg->snpsid >> 8 & 0xf, + hsotg->snpsid >> 4 & 0xf, hsotg->snpsid & 0xf); + + setup_timer(&hsotg->wkp_timer, dwc2_wakeup_detected, + (unsigned long)hsotg); + + /* Initialize the non-periodic schedule */ + INIT_LIST_HEAD(&hsotg->non_periodic_sched_inactive); + INIT_LIST_HEAD(&hsotg->non_periodic_sched_active); + + /* Initialize the periodic schedule */ + INIT_LIST_HEAD(&hsotg->periodic_sched_inactive); + INIT_LIST_HEAD(&hsotg->periodic_sched_ready); + INIT_LIST_HEAD(&hsotg->periodic_sched_assigned); + INIT_LIST_HEAD(&hsotg->periodic_sched_queued); + + /* + * Create a host channel descriptor for each host channel implemented + * in the controller. Initialize the channel descriptor array. + */ + INIT_LIST_HEAD(&hsotg->free_hc_list); + num_channels = hsotg->core_params->host_channels; + memset(&hsotg->hc_ptr_array[0], 0, sizeof(hsotg->hc_ptr_array)); + + for (i = 0; i < num_channels; i++) { + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (channel == NULL) + goto error3; + channel->hc_num = i; + hsotg->hc_ptr_array[i] = channel; + } + + /* Initialize hsotg start work */ + INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func); + + /* Initialize port reset work */ + INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func); + + /* + * Allocate space for storing data on status transactions. Normally no + * data is sent, but this space acts as a bit bucket. This must be + * done after usb_add_hcd since that function allocates the DMA buffer + * pool. + */ + if (hsotg->core_params->dma_enable > 0) + hsotg->status_buf = dma_alloc_coherent(hsotg->dev, + DWC2_HCD_STATUS_BUF_SIZE, + &hsotg->status_buf_dma, GFP_KERNEL); + else + hsotg->status_buf = kzalloc(DWC2_HCD_STATUS_BUF_SIZE, + GFP_KERNEL); + + if (!hsotg->status_buf) + goto error3; + + hsotg->otg_port = 1; + hsotg->frame_list = NULL; + hsotg->frame_list_dma = 0; + hsotg->periodic_qh_count = 0; + + /* Initiate lx_state to L3 disconnected state */ + hsotg->lx_state = DWC2_L3; + + hcd->self.otg_port = hsotg->otg_port; + + /* Don't support SG list at this point */ + hcd->self.sg_tablesize = 0; + + /* + * Finish generic HCD initialization and start the HCD. This function + * allocates the DMA buffer pool, registers the USB bus, requests the + * IRQ line, and calls hcd_start method. + */ + retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); + if (retval < 0) + goto error3; + + dwc2_dump_global_registers(hsotg); + dwc2_dump_host_registers(hsotg); + dwc2_hcd_dump_state(hsotg); + + dwc2_enable_global_interrupts(hsotg); + + return 0; + +error3: + dwc2_hcd_release(hsotg); +error2: + kfree(hsotg->core_params); + +#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS + kfree(hsotg->last_frame_num_array); + kfree(hsotg->frame_num_array); +#endif + + usb_put_hcd(hcd); +error1: + dev_err(dev, "%s() FAILED, returning %d\n", __func__, retval); + return retval; +} +EXPORT_SYMBOL_GPL(dwc2_hcd_init); + +/* + * Removes the HCD. + * Frees memory and resources associated with the HCD and deregisters the bus. + */ +void dwc2_hcd_remove(struct device *dev, struct dwc2_hsotg *hsotg) +{ + struct usb_hcd *hcd; + + dev_dbg(dev, "DWC OTG HCD REMOVE\n"); + + hcd = dwc2_hsotg_to_hcd(hsotg); + dev_dbg(dev, "hsotg->hcd = %p\n", hcd); + + if (!hcd) { + dev_dbg(dev, "%s: dwc2_hsotg_to_hcd(hsotg) NULL!\n", + __func__); + return; + } + + usb_remove_hcd(hcd); + hsotg->priv = NULL; + dwc2_hcd_release(hsotg); + kfree(hsotg->core_params); + +#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS + kfree(hsotg->last_frame_num_array); + kfree(hsotg->frame_num_array); +#endif + + usb_put_hcd(hcd); +} +EXPORT_SYMBOL_GPL(dwc2_hcd_remove); diff --git a/drivers/staging/dwc2/hcd.h b/drivers/staging/dwc2/hcd.h new file mode 100644 index 000000000000..775337e92785 --- /dev/null +++ b/drivers/staging/dwc2/hcd.h @@ -0,0 +1,737 @@ +/* + * hcd.h - DesignWare HS OTG Controller host-mode declarations + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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. + */ +#ifndef __DWC2_HCD_H__ +#define __DWC2_HCD_H__ + +/* + * This file contains the structures, constants, and interfaces for the + * Host Contoller Driver (HCD) + * + * The Host Controller Driver (HCD) is responsible for translating requests + * from the USB Driver into the appropriate actions on the DWC_otg controller. + * It isolates the USBD from the specifics of the controller by providing an + * API to the USBD. + */ + +struct dwc2_qh; + +/** + * struct dwc2_host_chan - Software host channel descriptor + * + * @hc_num: Host channel number, used for register address lookup + * @dev_addr: Address of the device + * @ep_num: Endpoint of the device + * @ep_is_in: Endpoint direction + * @speed: Device speed. One of the following values: + * - USB_SPEED_LOW + * - USB_SPEED_FULL + * - USB_SPEED_HIGH + * @ep_type: Endpoint type. One of the following values: + * - USB_ENDPOINT_XFER_CONTROL: 0 + * - USB_ENDPOINT_XFER_ISOC: 1 + * - USB_ENDPOINT_XFER_BULK: 2 + * - USB_ENDPOINT_XFER_INTR: 3 + * @max_packet: Max packet size in bytes + * @data_pid_start: PID for initial transaction. + * 0: DATA0 + * 1: DATA2 + * 2: DATA1 + * 3: MDATA (non-Control EP), + * SETUP (Control EP) + * @multi_count: Number of additional periodic transactions per + * (micro)frame + * @xfer_buf: Pointer to current transfer buffer position + * @xfer_dma: DMA address of xfer_buf + * @align_buf: In Buffer DMA mode this will be used if xfer_buf is not + * DWORD aligned + * @xfer_len: Total number of bytes to transfer + * @xfer_count: Number of bytes transferred so far + * @start_pkt_count: Packet count at start of transfer + * @xfer_started: True if the transfer has been started + * @ping: True if a PING request should be issued on this channel + * @error_state: True if the error count for this transaction is non-zero + * @halt_on_queue: True if this channel should be halted the next time a + * request is queued for the channel. This is necessary in + * slave mode if no request queue space is available when + * an attempt is made to halt the channel. + * @halt_pending: True if the host channel has been halted, but the core + * is not finished flushing queued requests + * @do_split: Enable split for the channel + * @complete_split: Enable complete split + * @hub_addr: Address of high speed hub for the split + * @hub_port: Port of the low/full speed device for the split + * @xact_pos: Split transaction position. One of the following values: + * - DWC2_HCSPLT_XACTPOS_MID + * - DWC2_HCSPLT_XACTPOS_BEGIN + * - DWC2_HCSPLT_XACTPOS_END + * - DWC2_HCSPLT_XACTPOS_ALL + * @requests: Number of requests issued for this channel since it was + * assigned to the current transfer (not counting PINGs) + * @schinfo: Scheduling micro-frame bitmap + * @ntd: Number of transfer descriptors for the transfer + * @halt_status: Reason for halting the host channel + * @hcint Contents of the HCINT register when the interrupt came + * @qh: QH for the transfer being processed by this channel + * @hc_list_entry: For linking to list of host channels + * @desc_list_addr: Current QH's descriptor list DMA address + * + * This structure represents the state of a single host channel when acting in + * host mode. It contains the data items needed to transfer packets to an + * endpoint via a host channel. + */ +struct dwc2_host_chan { + u8 hc_num; + + unsigned dev_addr:7; + unsigned ep_num:4; + unsigned ep_is_in:1; + unsigned speed:4; + unsigned ep_type:2; + unsigned max_packet:11; + unsigned data_pid_start:2; +#define DWC2_HC_PID_DATA0 (TSIZ_SC_MC_PID_DATA0 >> TSIZ_SC_MC_PID_SHIFT) +#define DWC2_HC_PID_DATA2 (TSIZ_SC_MC_PID_DATA2 >> TSIZ_SC_MC_PID_SHIFT) +#define DWC2_HC_PID_DATA1 (TSIZ_SC_MC_PID_DATA1 >> TSIZ_SC_MC_PID_SHIFT) +#define DWC2_HC_PID_MDATA (TSIZ_SC_MC_PID_MDATA >> TSIZ_SC_MC_PID_SHIFT) +#define DWC2_HC_PID_SETUP (TSIZ_SC_MC_PID_SETUP >> TSIZ_SC_MC_PID_SHIFT) + + unsigned multi_count:2; + + u8 *xfer_buf; + dma_addr_t xfer_dma; + dma_addr_t align_buf; + u32 xfer_len; + u32 xfer_count; + u16 start_pkt_count; + u8 xfer_started; + u8 do_ping; + u8 error_state; + u8 halt_on_queue; + u8 halt_pending; + u8 do_split; + u8 complete_split; + u8 hub_addr; + u8 hub_port; + u8 xact_pos; +#define DWC2_HCSPLT_XACTPOS_MID (HCSPLT_XACTPOS_MID >> HCSPLT_XACTPOS_SHIFT) +#define DWC2_HCSPLT_XACTPOS_END (HCSPLT_XACTPOS_END >> HCSPLT_XACTPOS_SHIFT) +#define DWC2_HCSPLT_XACTPOS_BEGIN (HCSPLT_XACTPOS_BEGIN >> HCSPLT_XACTPOS_SHIFT) +#define DWC2_HCSPLT_XACTPOS_ALL (HCSPLT_XACTPOS_ALL >> HCSPLT_XACTPOS_SHIFT) + + u8 requests; + u8 schinfo; + u16 ntd; + enum dwc2_halt_status halt_status; + u32 hcint; + struct dwc2_qh *qh; + struct list_head hc_list_entry; + dma_addr_t desc_list_addr; +}; + +struct dwc2_hcd_pipe_info { + u8 dev_addr; + u8 ep_num; + u8 pipe_type; + u8 pipe_dir; + u16 mps; +}; + +struct dwc2_hcd_iso_packet_desc { + u32 offset; + u32 length; + u32 actual_length; + u32 status; +}; + +struct dwc2_qtd; + +struct dwc2_hcd_urb { + void *priv; + struct dwc2_qtd *qtd; + void *buf; + dma_addr_t dma; + void *setup_packet; + dma_addr_t setup_dma; + u32 length; + u32 actual_length; + u32 status; + u32 error_count; + u32 packet_count; + u32 flags; + u16 interval; + struct dwc2_hcd_pipe_info pipe_info; + struct dwc2_hcd_iso_packet_desc iso_descs[0]; +}; + +/* Phases for control transfers */ +enum dwc2_control_phase { + DWC2_CONTROL_SETUP, + DWC2_CONTROL_DATA, + DWC2_CONTROL_STATUS, +}; + +/* Transaction types */ +enum dwc2_transaction_type { + DWC2_TRANSACTION_NONE, + DWC2_TRANSACTION_PERIODIC, + DWC2_TRANSACTION_NON_PERIODIC, + DWC2_TRANSACTION_ALL, +}; + +/** + * struct dwc2_qh - Software queue head structure + * + * @ep_type: Endpoint type. One of the following values: + * - USB_ENDPOINT_XFER_CONTROL + * - USB_ENDPOINT_XFER_BULK + * - USB_ENDPOINT_XFER_INT + * - USB_ENDPOINT_XFER_ISOC + * @ep_is_in: Endpoint direction + * @maxp: Value from wMaxPacketSize field of Endpoint Descriptor + * @dev_speed: Device speed. One of the following values: + * - USB_SPEED_LOW + * - USB_SPEED_FULL + * - USB_SPEED_HIGH + * @data_toggle: Determines the PID of the next data packet for + * non-controltransfers. Ignored for control transfers. + * One of the following values: + * - DWC2_HC_PID_DATA0 + * - DWC2_HC_PID_DATA1 + * @ping_state: Ping state + * @do_split: Full/low speed endpoint on high-speed hub requires split + * @qtd_list: List of QTDs for this QH + * @channel: Host channel currently processing transfers for this QH + * @usecs: Bandwidth in microseconds per (micro)frame + * @interval: Interval between transfers in (micro)frames + * @sched_frame: (micro)frame to initialize a periodic transfer. + * The transfer executes in the following (micro)frame. + * @start_split_frame: (Micro)frame at which last start split was initialized + * @dw_align_buf: Used instead of original buffer if its physical address + * is not dword-aligned + * @dw_align_buf_dma: DMA address for align_buf + * @qh_list_entry: Entry for QH in either the periodic or non-periodic + * schedule + * @desc_list: List of transfer descriptors + * @desc_list_dma: Physical address of desc_list + * @n_bytes: Xfer Bytes array. Each element corresponds to a transfer + * descriptor and indicates original XferSize value for the + * descriptor + * @ntd: Actual number of transfer descriptors in a list + * @td_first: Index of first activated isochronous transfer descriptor + * @td_last: Index of last activated isochronous transfer descriptor + * @tt_buffer_dirty True if clear_tt_buffer_complete is pending + * + * A Queue Head (QH) holds the static characteristics of an endpoint and + * maintains a list of transfers (QTDs) for that endpoint. A QH structure may + * be entered in either the non-periodic or periodic schedule. + */ +struct dwc2_qh { + u8 ep_type; + u8 ep_is_in; + u16 maxp; + u8 dev_speed; + u8 data_toggle; + u8 ping_state; + u8 do_split; + struct list_head qtd_list; + struct dwc2_host_chan *channel; + u16 usecs; + u16 interval; + u16 sched_frame; + u16 start_split_frame; + u8 *dw_align_buf; + dma_addr_t dw_align_buf_dma; + struct list_head qh_list_entry; + struct dwc2_hcd_dma_desc *desc_list; + dma_addr_t desc_list_dma; + u32 *n_bytes; + u16 ntd; + u8 td_first; + u8 td_last; + unsigned tt_buffer_dirty:1; +}; + +/** + * struct dwc2_qtd - Software queue transfer descriptor (QTD) + * + * @control_phase: Current phase for control transfers (Setup, Data, or + * Status) + * @in_process: Indicates if this QTD is currently processed by HW + * @data_toggle: Determines the PID of the next data packet for the + * data phase of control transfers. Ignored for other + * transfer types. One of the following values: + * - DWC2_HC_PID_DATA0 + * - DWC2_HC_PID_DATA1 + * @complete_split: Keeps track of the current split type for FS/LS + * endpoints on a HS Hub + * @isoc_split_pos: Position of the ISOC split in full/low speed + * @isoc_frame_index: Index of the next frame descriptor for an isochronous + * transfer. A frame descriptor describes the buffer + * position and length of the data to be transferred in the + * next scheduled (micro)frame of an isochronous transfer. + * It also holds status for that transaction. The frame + * index starts at 0. + * @isoc_split_offset: Position of the ISOC split in the buffer for the + * current frame + * @ssplit_out_xfer_count: How many bytes transferred during SSPLIT OUT + * @error_count: Holds the number of bus errors that have occurred for + * a transaction within this transfer + * @n_desc: Number of DMA descriptors for this QTD + * @isoc_frame_index_last: Last activated frame (packet) index, used in + * descriptor DMA mode only + * @urb: URB for this transfer + * @qh: Queue head for this QTD + * @qtd_list_entry: For linking to the QH's list of QTDs + * + * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control, + * interrupt, or isochronous transfer. A single QTD is created for each URB + * (of one of these types) submitted to the HCD. The transfer associated with + * a QTD may require one or multiple transactions. + * + * A QTD is linked to a Queue Head, which is entered in either the + * non-periodic or periodic schedule for execution. When a QTD is chosen for + * execution, some or all of its transactions may be executed. After + * execution, the state of the QTD is updated. The QTD may be retired if all + * its transactions are complete or if an error occurred. Otherwise, it + * remains in the schedule so more transactions can be executed later. + */ +struct dwc2_qtd { + enum dwc2_control_phase control_phase; + u8 in_process; + u8 data_toggle; + u8 complete_split; + u8 isoc_split_pos; + u16 isoc_frame_index; + u16 isoc_split_offset; + u32 ssplit_out_xfer_count; + u8 error_count; + u8 n_desc; + u16 isoc_frame_index_last; + struct dwc2_hcd_urb *urb; + struct dwc2_qh *qh; + struct list_head qtd_list_entry; +}; + +#ifdef DEBUG +struct hc_xfer_info { + struct dwc2_hsotg *hsotg; + struct dwc2_host_chan *chan; +}; +#endif + +/* Gets the struct usb_hcd that contains a struct dwc2_hsotg */ +static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg) +{ + return (struct usb_hcd *)hsotg->priv; +} + +/* + * Inline used to disable one channel interrupt. Channel interrupts are + * disabled when the channel is halted or released by the interrupt handler. + * There is no need to handle further interrupts of that type until the + * channel is re-assigned. In fact, subsequent handling may cause crashes + * because the channel structures are cleaned up when the channel is released. + */ +static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr) +{ + u32 mask = readl(hsotg->regs + HCINTMSK(chnum)); + + mask &= ~intr; + writel(mask, hsotg->regs + HCINTMSK(chnum)); +} + +/* + * Returns the mode of operation, host or device + */ +static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) +{ + return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; +} +static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) +{ + return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; +} + +/* + * Reads HPRT0 in preparation to modify. It keeps the WC bits 0 so that if they + * are read as 1, they won't clear when written back. + */ +static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg) +{ + u32 hprt0 = readl(hsotg->regs + HPRT0); + + hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG); + return hprt0; +} + +static inline u8 dwc2_hcd_get_ep_num(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->ep_num; +} + +static inline u8 dwc2_hcd_get_pipe_type(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_type; +} + +static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->mps; +} + +static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->dev_addr; +} + +static inline u8 dwc2_hcd_is_pipe_isoc(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_type == USB_ENDPOINT_XFER_ISOC; +} + +static inline u8 dwc2_hcd_is_pipe_int(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_type == USB_ENDPOINT_XFER_INT; +} + +static inline u8 dwc2_hcd_is_pipe_bulk(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_type == USB_ENDPOINT_XFER_BULK; +} + +static inline u8 dwc2_hcd_is_pipe_control(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_type == USB_ENDPOINT_XFER_CONTROL; +} + +static inline u8 dwc2_hcd_is_pipe_in(struct dwc2_hcd_pipe_info *pipe) +{ + return pipe->pipe_dir == USB_DIR_IN; +} + +static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe) +{ + return !dwc2_hcd_is_pipe_in(pipe); +} + +extern int dwc2_hcd_init(struct device *dev, struct dwc2_hsotg *hsotg, + int irq, struct dwc2_core_params *params); +extern void dwc2_hcd_remove(struct device *dev, struct dwc2_hsotg *hsotg); +extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg, + struct dwc2_core_params *params); + +/* Transaction Execution Functions */ +extern enum dwc2_transaction_type dwc2_hcd_select_transactions( + struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, + enum dwc2_transaction_type tr_type); + +/* Schedule Queue Functions */ +/* Implemented in hcd_queue.c */ +extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); +extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); +extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); +extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + int sched_csplit); + +extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb); +extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, + struct dwc2_qh **qh, gfp_t mem_flags); + +/* Unlinks and frees a QTD */ +static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, + struct dwc2_qtd *qtd, + struct dwc2_qh *qh) +{ + list_del(&qtd->qtd_list_entry); + kfree(qtd); +} + +/* Descriptor DMA support functions */ +extern void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh); +extern void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + enum dwc2_halt_status halt_status); + +extern int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + gfp_t mem_flags); +extern void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); + +/* Check if QH is non-periodic */ +#define dwc2_qh_is_non_per(_qh_ptr_) \ + ((_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_BULK || \ + (_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_CONTROL) + +/* High bandwidth multiplier as encoded in highspeed endpoint descriptors */ +#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03)) + +/* Packet size for any kind of endpoint descriptor */ +#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff) + +/* + * Returns true if frame1 is less than or equal to frame2. The comparison is + * done modulo HFNUM_MAX_FRNUM. This accounts for the rollover of the + * frame number when the max frame number is reached. + */ +static inline int dwc2_frame_num_le(u16 frame1, u16 frame2) +{ + return ((frame2 - frame1) & HFNUM_MAX_FRNUM) <= (HFNUM_MAX_FRNUM >> 1); +} + +/* + * Returns true if frame1 is greater than frame2. The comparison is done + * modulo HFNUM_MAX_FRNUM. This accounts for the rollover of the frame + * number when the max frame number is reached. + */ +static inline int dwc2_frame_num_gt(u16 frame1, u16 frame2) +{ + return (frame1 != frame2) && + ((frame1 - frame2) & HFNUM_MAX_FRNUM) < (HFNUM_MAX_FRNUM >> 1); +} + +/* + * Increments frame by the amount specified by inc. The addition is done + * modulo HFNUM_MAX_FRNUM. Returns the incremented value. + */ +static inline u16 dwc2_frame_num_inc(u16 frame, u16 inc) +{ + return (frame + inc) & HFNUM_MAX_FRNUM; +} + +static inline u16 dwc2_full_frame_num(u16 frame) +{ + return (frame & HFNUM_MAX_FRNUM) >> 3; +} + +static inline u16 dwc2_micro_frame_num(u16 frame) +{ + return frame & 0x7; +} + +/* + * Returns the Core Interrupt Status register contents, ANDed with the Core + * Interrupt Mask register contents + */ +static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg) +{ + return readl(hsotg->regs + GINTSTS) & readl(hsotg->regs + GINTMSK); +} + +static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb) +{ + return dwc2_urb->status; +} + +static inline u32 dwc2_hcd_urb_get_actual_length( + struct dwc2_hcd_urb *dwc2_urb) +{ + return dwc2_urb->actual_length; +} + +static inline u32 dwc2_hcd_urb_get_error_count(struct dwc2_hcd_urb *dwc2_urb) +{ + return dwc2_urb->error_count; +} + +static inline void dwc2_hcd_urb_set_iso_desc_params( + struct dwc2_hcd_urb *dwc2_urb, int desc_num, u32 offset, + u32 length) +{ + dwc2_urb->iso_descs[desc_num].offset = offset; + dwc2_urb->iso_descs[desc_num].length = length; +} + +static inline u32 dwc2_hcd_urb_get_iso_desc_status( + struct dwc2_hcd_urb *dwc2_urb, int desc_num) +{ + return dwc2_urb->iso_descs[desc_num].status; +} + +static inline u32 dwc2_hcd_urb_get_iso_desc_actual_length( + struct dwc2_hcd_urb *dwc2_urb, int desc_num) +{ + return dwc2_urb->iso_descs[desc_num].actual_length; +} + +static inline int dwc2_hcd_is_bandwidth_allocated(struct dwc2_hsotg *hsotg, + struct usb_host_endpoint *ep) +{ + struct dwc2_qh *qh = ep->hcpriv; + + if (qh && !list_empty(&qh->qh_list_entry)) + return 1; + + return 0; +} + +static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg, + struct usb_host_endpoint *ep) +{ + struct dwc2_qh *qh = ep->hcpriv; + + if (!qh) { + WARN_ON(1); + return 0; + } + + return qh->usecs; +} + +extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd); + +/* HCD Core API */ + +/** + * dwc2_hcd_intr() - Called on every hardware interrupt + * + * @hsotg: The DWC2 HCD + * + * Returns non zero if interrupt is handled + * Return 0 if interrupt is not handled + */ +extern int dwc2_hcd_intr(struct dwc2_hsotg *hsotg); + +/** + * dwc2_hcd_stop() - Halts the DWC_otg host mode operation + * + * @hsotg: The DWC2 HCD + */ +extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg); + +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); + +/** + * dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host, + * and 0 otherwise + * + * @hsotg: The DWC2 HCD + */ +extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg); + +/** + * dwc2_hcd_get_frame_number() - Returns current frame number + * + * @hsotg: The DWC2 HCD + */ +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); + +/** + * dwc2_hcd_dump_state() - Dumps hsotg state + * + * @hsotg: The DWC2 HCD + * + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg); + +/** + * dwc2_hcd_dump_frrem() - Dumps the average frame remaining at SOF + * + * @hsotg: The DWC2 HCD + * + * This can be used to determine average interrupt latency. Frame remaining is + * also shown for start transfer and two additional sample points. + * + * NOTE: This function will be removed once the peripheral controller code + * is integrated and the driver is stable + */ +extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg); + +/* URB interface */ + +/* Transfer flags */ +#define URB_GIVEBACK_ASAP 0x1 +#define URB_SEND_ZERO_PACKET 0x2 + +/* Host driver callbacks */ + +extern void dwc2_host_start(struct dwc2_hsotg *hsotg); +extern void dwc2_host_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context, + int *hub_addr, int *hub_port); +extern int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context); +extern void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context, + struct dwc2_hcd_urb *dwc2_urb, int status); + +#ifdef DEBUG +/* + * Macro to sample the remaining PHY clocks left in the current frame. This + * may be used during debugging to determine the average time it takes to + * execute sections of code. There are two possible sample points, "a" and + * "b", so the _letter_ argument must be one of these values. + * + * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For + * example, "cat /sys/devices/lm0/hcd_frrem". + */ +#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) \ +do { \ + struct hfnum_data _hfnum_; \ + struct dwc2_qtd *_qtd_; \ + \ + _qtd_ = list_entry((_qh_)->qtd_list.next, struct dwc2_qtd, \ + qtd_list_entry); \ + if (usb_pipeint(_qtd_->urb->pipe) && \ + (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) { \ + _hfnum_.d32 = readl((_hcd_)->regs + HFNUM); \ + switch (_hfnum_.b.frnum & 0x7) { \ + case 7: \ + (_hcd_)->hfnum_7_samples_##_letter_++; \ + (_hcd_)->hfnum_7_frrem_accum_##_letter_ += \ + _hfnum_.b.frrem; \ + break; \ + case 0: \ + (_hcd_)->hfnum_0_samples_##_letter_++; \ + (_hcd_)->hfnum_0_frrem_accum_##_letter_ += \ + _hfnum_.b.frrem; \ + break; \ + default: \ + (_hcd_)->hfnum_other_samples_##_letter_++; \ + (_hcd_)->hfnum_other_frrem_accum_##_letter_ += \ + _hfnum_.b.frrem; \ + break; \ + } \ + } \ +} while (0) +#else +#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) do {} while (0) +#endif + +#endif /* __DWC2_HCD_H__ */ diff --git a/drivers/staging/dwc2/hcd_intr.c b/drivers/staging/dwc2/hcd_intr.c new file mode 100644 index 000000000000..01addd0889dc --- /dev/null +++ b/drivers/staging/dwc2/hcd_intr.c @@ -0,0 +1,2079 @@ +/* + * hcd_intr.c - DesignWare HS OTG Controller host-mode interrupt handling + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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 file contains the interrupt handlers for Host mode + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +/* This function is for debug only */ +static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg) +{ +#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS +#warning Compiling code to track missed SOFs + + u16 curr_frame_number = hsotg->frame_number; + + if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) { + if (((hsotg->last_frame_num + 1) & HFNUM_MAX_FRNUM) != + curr_frame_number) { + hsotg->frame_num_array[hsotg->frame_num_idx] = + curr_frame_number; + hsotg->last_frame_num_array[hsotg->frame_num_idx] = + hsotg->last_frame_num; + hsotg->frame_num_idx++; + } + } else if (!hsotg->dumped_frame_num_array) { + int i; + + dev_info(hsotg->dev, "Frame Last Frame\n"); + dev_info(hsotg->dev, "----- ----------\n"); + for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) { + dev_info(hsotg->dev, "0x%04x 0x%04x\n", + hsotg->frame_num_array[i], + hsotg->last_frame_num_array[i]); + } + hsotg->dumped_frame_num_array = 1; + } + hsotg->last_frame_num = curr_frame_number; +#endif +} + +static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd) +{ + struct urb *usb_urb; + + if (!chan->qh || !qtd->urb) + return; + + usb_urb = qtd->urb->priv; + if (!usb_urb || !usb_urb->dev) + return; + + if (chan->qh->dev_speed != USB_SPEED_HIGH && + qtd->urb->status != -EPIPE && qtd->urb->status != -EREMOTEIO) { + chan->qh->tt_buffer_dirty = 1; + if (usb_hub_clear_tt_buffer(usb_urb)) + /* Clear failed; let's hope things work anyway */ + chan->qh->tt_buffer_dirty = 0; + } +} + +/* + * Handles the start-of-frame interrupt in host mode. Non-periodic + * transactions may be queued to the DWC_otg controller for the current + * (micro)frame. Periodic transactions may be queued to the controller + * for the next (micro)frame. + */ +static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) +{ + struct list_head *qh_entry; + struct dwc2_qh *qh; + u32 hfnum; + enum dwc2_transaction_type tr_type; + +#ifdef DEBUG_SOF + dev_vdbg(hsotg->dev, "--Start of Frame Interrupt--\n"); +#endif + + hfnum = readl(hsotg->regs + HFNUM); + hsotg->frame_number = hfnum >> HFNUM_FRNUM_SHIFT & + HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT; + + dwc2_track_missed_sofs(hsotg); + + /* Determine whether any periodic QHs should be executed */ + qh_entry = hsotg->periodic_sched_inactive.next; + while (qh_entry != &hsotg->periodic_sched_inactive) { + qh = list_entry(qh_entry, struct dwc2_qh, qh_list_entry); + qh_entry = qh_entry->next; + if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) + /* + * Move QH to the ready list to be executed next + * (micro)frame + */ + list_move(&qh->qh_list_entry, + &hsotg->periodic_sched_ready); + } + tr_type = dwc2_hcd_select_transactions(hsotg); + if (tr_type != DWC2_TRANSACTION_NONE) + dwc2_hcd_queue_transactions(hsotg, tr_type); + + /* Clear interrupt */ + writel(GINTSTS_SOF, hsotg->regs + GINTSTS); +} + +/* + * Handles the Rx FIFO Level Interrupt, which indicates that there is + * at least one packet in the Rx FIFO. The packets are moved from the FIFO to + * memory if the DWC_otg controller is operating in Slave mode. + */ +static void dwc2_rx_fifo_level_intr(struct dwc2_hsotg *hsotg) +{ + u32 grxsts, chnum, bcnt, dpid, pktsts; + struct dwc2_host_chan *chan; + + dev_vdbg(hsotg->dev, "--RxFIFO Level Interrupt--\n"); + + grxsts = readl(hsotg->regs + GRXSTSP); + chnum = grxsts >> GRXSTS_HCHNUM_SHIFT & + GRXSTS_HCHNUM_MASK >> GRXSTS_HCHNUM_SHIFT; + chan = hsotg->hc_ptr_array[chnum]; + if (!chan) { + dev_err(hsotg->dev, "Unable to get corresponding channel\n"); + return; + } + + bcnt = grxsts >> GRXSTS_BYTECNT_SHIFT & + GRXSTS_BYTECNT_MASK >> GRXSTS_BYTECNT_SHIFT; + dpid = grxsts >> GRXSTS_DPID_SHIFT & + GRXSTS_DPID_MASK >> GRXSTS_DPID_SHIFT; + pktsts = grxsts & GRXSTS_PKTSTS_MASK; + + /* Packet Status */ + dev_vdbg(hsotg->dev, " Ch num = %d\n", chnum); + dev_vdbg(hsotg->dev, " Count = %d\n", bcnt); + dev_vdbg(hsotg->dev, " DPID = %d, chan.dpid = %d\n", dpid, + chan->data_pid_start); + dev_vdbg(hsotg->dev, " PStatus = %d\n", + pktsts >> GRXSTS_PKTSTS_SHIFT & + GRXSTS_PKTSTS_MASK >> GRXSTS_PKTSTS_SHIFT); + + switch (pktsts) { + case GRXSTS_PKTSTS_HCHIN: + /* Read the data into the host buffer */ + if (bcnt > 0) { + dwc2_read_packet(hsotg, chan->xfer_buf, bcnt); + + /* Update the HC fields for the next packet received */ + chan->xfer_count += bcnt; + chan->xfer_buf += bcnt; + } + break; + case GRXSTS_PKTSTS_HCHIN_XFER_COMP: + case GRXSTS_PKTSTS_DATATOGGLEERR: + case GRXSTS_PKTSTS_HCHHALTED: + /* Handled in interrupt, just ignore data */ + break; + default: + dev_err(hsotg->dev, + "RxFIFO Level Interrupt: Unknown status %d\n", pktsts); + break; + } +} + +/* + * This interrupt occurs when the non-periodic Tx FIFO is half-empty. More + * data packets may be written to the FIFO for OUT transfers. More requests + * may be written to the non-periodic request queue for IN transfers. This + * interrupt is enabled only in Slave mode. + */ +static void dwc2_np_tx_fifo_empty_intr(struct dwc2_hsotg *hsotg) +{ + dev_vdbg(hsotg->dev, "--Non-Periodic TxFIFO Empty Interrupt--\n"); + dwc2_hcd_queue_transactions(hsotg, DWC2_TRANSACTION_NON_PERIODIC); +} + +/* + * This interrupt occurs when the periodic Tx FIFO is half-empty. More data + * packets may be written to the FIFO for OUT transfers. More requests may be + * written to the periodic request queue for IN transfers. This interrupt is + * enabled only in Slave mode. + */ +static void dwc2_perio_tx_fifo_empty_intr(struct dwc2_hsotg *hsotg) +{ + dev_vdbg(hsotg->dev, "--Periodic TxFIFO Empty Interrupt--\n"); + dwc2_hcd_queue_transactions(hsotg, DWC2_TRANSACTION_PERIODIC); +} + +static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, + u32 *hprt0_modify) +{ + struct dwc2_core_params *params = hsotg->core_params; + int do_reset = 0; + u32 usbcfg; + u32 prtspd; + u32 hcfg; + u32 hfir; + + dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); + + /* Every time when port enables calculate HFIR.FrInterval */ + hfir = readl(hsotg->regs + HFIR); + hfir &= ~HFIR_FRINT_MASK; + hfir |= dwc2_calc_frame_interval(hsotg) << HFIR_FRINT_SHIFT & + HFIR_FRINT_MASK; + writel(hfir, hsotg->regs + HFIR); + + /* Check if we need to adjust the PHY clock speed for low power */ + if (!params->host_support_fs_ls_low_power) { + /* Port has been enabled, set the reset change flag */ + hsotg->flags.b.port_reset_change = 1; + return; + } + + usbcfg = readl(hsotg->regs + GUSBCFG); + prtspd = hprt0 & HPRT0_SPD_MASK; + + if (prtspd == HPRT0_SPD_LOW_SPEED || prtspd == HPRT0_SPD_FULL_SPEED) { + /* Low power */ + if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL)) { + /* Set PHY low power clock select for FS/LS devices */ + usbcfg |= GUSBCFG_PHY_LP_CLK_SEL; + writel(usbcfg, hsotg->regs + GUSBCFG); + do_reset = 1; + } + + hcfg = readl(hsotg->regs + HCFG); + + if (prtspd == HPRT0_SPD_LOW_SPEED && + params->host_ls_low_power_phy_clk == + DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) { + /* 6 MHZ */ + dev_vdbg(hsotg->dev, + "FS_PHY programming HCFG to 6 MHz\n"); + if ((hcfg & HCFG_FSLSPCLKSEL_MASK) != + HCFG_FSLSPCLKSEL_6_MHZ) { + hcfg &= ~HCFG_FSLSPCLKSEL_MASK; + hcfg |= HCFG_FSLSPCLKSEL_6_MHZ; + writel(hcfg, hsotg->regs + HCFG); + do_reset = 1; + } + } else { + /* 48 MHZ */ + dev_vdbg(hsotg->dev, + "FS_PHY programming HCFG to 48 MHz\n"); + if ((hcfg & HCFG_FSLSPCLKSEL_MASK) != + HCFG_FSLSPCLKSEL_48_MHZ) { + hcfg &= ~HCFG_FSLSPCLKSEL_MASK; + hcfg |= HCFG_FSLSPCLKSEL_48_MHZ; + writel(hcfg, hsotg->regs + HCFG); + do_reset = 1; + } + } + } else { + /* Not low power */ + if (usbcfg & GUSBCFG_PHY_LP_CLK_SEL) { + usbcfg &= ~GUSBCFG_PHY_LP_CLK_SEL; + writel(usbcfg, hsotg->regs + GUSBCFG); + do_reset = 1; + } + } + + if (do_reset) { + *hprt0_modify |= HPRT0_RST; + queue_delayed_work(hsotg->wq_otg, &hsotg->reset_work, + msecs_to_jiffies(60)); + } else { + /* Port has been enabled, set the reset change flag */ + hsotg->flags.b.port_reset_change = 1; + } +} + +/* + * There are multiple conditions that can cause a port interrupt. This function + * determines which interrupt conditions have occurred and handles them + * appropriately. + */ +static void dwc2_port_intr(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + u32 hprt0_modify; + + dev_vdbg(hsotg->dev, "--Port Interrupt--\n"); + + hprt0 = readl(hsotg->regs + HPRT0); + hprt0_modify = hprt0; + + /* + * Clear appropriate bits in HPRT0 to clear the interrupt bit in + * GINTSTS + */ + hprt0_modify &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | + HPRT0_OVRCURRCHG); + + /* + * Port Connect Detected + * Set flag and clear if detected + */ + if (hprt0 & HPRT0_CONNDET) { + dev_vdbg(hsotg->dev, + "--Port Interrupt HPRT0=0x%08x Port Connect Detected--\n", + hprt0); + hsotg->flags.b.port_connect_status_change = 1; + hsotg->flags.b.port_connect_status = 1; + hprt0_modify |= HPRT0_CONNDET; + + /* + * The Hub driver asserts a reset when it sees port connect + * status change flag + */ + } + + /* + * Port Enable Changed + * Clear if detected - Set internal flag if disabled + */ + if (hprt0 & HPRT0_ENACHG) { + dev_vdbg(hsotg->dev, + " --Port Interrupt HPRT0=0x%08x Port Enable Changed (now %d)--\n", + hprt0, !!(hprt0 & HPRT0_ENA)); + hprt0_modify |= HPRT0_ENACHG; + if (hprt0 & HPRT0_ENA) + dwc2_hprt0_enable(hsotg, hprt0, &hprt0_modify); + else + hsotg->flags.b.port_enable_change = 1; + } + + /* Overcurrent Change Interrupt */ + if (hprt0 & HPRT0_OVRCURRCHG) { + dev_vdbg(hsotg->dev, + " --Port Interrupt HPRT0=0x%08x Port Overcurrent Changed--\n", + hprt0); + hsotg->flags.b.port_over_current_change = 1; + hprt0_modify |= HPRT0_OVRCURRCHG; + } + + /* Clear Port Interrupts */ + writel(hprt0_modify, hsotg->regs + HPRT0); +} + +/* + * Gets the actual length of a transfer after the transfer halts. halt_status + * holds the reason for the halt. + * + * For IN transfers where halt_status is DWC2_HC_XFER_COMPLETE, *short_read + * is set to 1 upon return if less than the requested number of bytes were + * transferred. short_read may also be NULL on entry, in which case it remains + * unchanged. + */ +static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status, + int *short_read) +{ + u32 hctsiz, count, length; + + hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + + if (halt_status == DWC2_HC_XFER_COMPLETE) { + if (chan->ep_is_in) { + count = hctsiz >> TSIZ_XFERSIZE_SHIFT & + TSIZ_XFERSIZE_MASK >> TSIZ_XFERSIZE_SHIFT; + length = chan->xfer_len - count; + if (short_read != NULL) + *short_read = (count != 0); + } else if (chan->qh->do_split) { + length = qtd->ssplit_out_xfer_count; + } else { + length = chan->xfer_len; + } + } else { + /* + * Must use the hctsiz.pktcnt field to determine how much data + * has been transferred. This field reflects the number of + * packets that have been transferred via the USB. This is + * always an integral number of packets if the transfer was + * halted before its normal completion. (Can't use the + * hctsiz.xfersize field because that reflects the number of + * bytes transferred via the AHB, not the USB). + */ + count = hctsiz >> TSIZ_PKTCNT_SHIFT & + TSIZ_PKTCNT_MASK >> TSIZ_PKTCNT_SHIFT; + length = (chan->start_pkt_count - count) * chan->max_packet; + } + + return length; +} + +/** + * dwc2_update_urb_state() - Updates the state of the URB after a Transfer + * Complete interrupt on the host channel. Updates the actual_length field + * of the URB based on the number of bytes transferred via the host channel. + * Sets the URB status if the data transfer is finished. + * + * Return: 1 if the data transfer specified by the URB is completely finished, + * 0 otherwise + */ +static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_hcd_urb *urb, + struct dwc2_qtd *qtd) +{ + u32 hctsiz; + int xfer_done = 0; + int short_read = 0; + int xfer_length = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd, + DWC2_HC_XFER_COMPLETE, + &short_read); + + if (urb->actual_length + xfer_length > urb->length) { + dev_warn(hsotg->dev, "%s(): trimming xfer length\n", __func__); + xfer_length = urb->length - urb->actual_length; + } + + /* Non DWORD-aligned buffer case handling */ + if (chan->align_buf && xfer_length && chan->ep_is_in) { + dev_dbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); + dma_sync_single_for_cpu(hsotg->dev, urb->dma, urb->length, + DMA_FROM_DEVICE); + memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, + xfer_length); + dma_sync_single_for_device(hsotg->dev, urb->dma, urb->length, + DMA_FROM_DEVICE); + } + + dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n", + urb->actual_length, xfer_length); + urb->actual_length += xfer_length; + + if (xfer_length && chan->ep_type == USB_ENDPOINT_XFER_BULK && + (urb->flags & URB_SEND_ZERO_PACKET) && + urb->actual_length >= urb->length && + !(urb->length % chan->max_packet)) { + xfer_done = 0; + } else if (short_read || urb->actual_length >= urb->length) { + xfer_done = 1; + urb->status = 0; + } + + hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n", + __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum); + dev_vdbg(hsotg->dev, " chan->xfer_len %d\n", chan->xfer_len); + dev_vdbg(hsotg->dev, " hctsiz.xfersize %d\n", + hctsiz >> TSIZ_XFERSIZE_SHIFT & + TSIZ_XFERSIZE_MASK >> TSIZ_XFERSIZE_SHIFT); + dev_vdbg(hsotg->dev, " urb->transfer_buffer_length %d\n", urb->length); + dev_vdbg(hsotg->dev, " urb->actual_length %d\n", urb->actual_length); + dev_vdbg(hsotg->dev, " short_read %d, xfer_done %d\n", short_read, + xfer_done); + + return xfer_done; +} + +/* + * Save the starting data toggle for the next transfer. The data toggle is + * saved in the QH for non-control transfers and it's saved in the QTD for + * control transfers. + */ +void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + u32 pid = hctsiz & TSIZ_SC_MC_PID_MASK; + + if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) { + if (pid == TSIZ_SC_MC_PID_DATA0) + chan->qh->data_toggle = DWC2_HC_PID_DATA0; + else + chan->qh->data_toggle = DWC2_HC_PID_DATA1; + } else { + if (pid == TSIZ_SC_MC_PID_DATA0) + qtd->data_toggle = DWC2_HC_PID_DATA0; + else + qtd->data_toggle = DWC2_HC_PID_DATA1; + } +} + +/** + * dwc2_update_isoc_urb_state() - Updates the state of an Isochronous URB when + * the transfer is stopped for any reason. The fields of the current entry in + * the frame descriptor array are set based on the transfer state and the input + * halt_status. Completes the Isochronous URB if all the URB frames have been + * completed. + * + * Return: DWC2_HC_XFER_COMPLETE if there are more frames remaining to be + * transferred in the URB. Otherwise return DWC2_HC_XFER_URB_COMPLETE. + */ +static enum dwc2_halt_status dwc2_update_isoc_urb_state( + struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, + int chnum, struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + struct dwc2_hcd_iso_packet_desc *frame_desc; + struct dwc2_hcd_urb *urb = qtd->urb; + + if (!urb) + return DWC2_HC_XFER_NO_HALT_STATUS; + + frame_desc = &urb->iso_descs[qtd->isoc_frame_index]; + + switch (halt_status) { + case DWC2_HC_XFER_COMPLETE: + frame_desc->status = 0; + frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg, + chan, chnum, qtd, halt_status, NULL); + + /* Non DWORD-aligned buffer case handling */ + if (chan->align_buf && frame_desc->actual_length && + chan->ep_is_in) { + dev_dbg(hsotg->dev, "%s(): non-aligned buffer\n", + __func__); + dma_sync_single_for_cpu(hsotg->dev, urb->dma, + urb->length, DMA_FROM_DEVICE); + memcpy(urb->buf + frame_desc->offset + + qtd->isoc_split_offset, chan->qh->dw_align_buf, + frame_desc->actual_length); + dma_sync_single_for_device(hsotg->dev, urb->dma, + urb->length, + DMA_FROM_DEVICE); + } + break; + case DWC2_HC_XFER_FRAME_OVERRUN: + urb->error_count++; + if (chan->ep_is_in) + frame_desc->status = -ENOSR; + else + frame_desc->status = -ECOMM; + frame_desc->actual_length = 0; + break; + case DWC2_HC_XFER_BABBLE_ERR: + urb->error_count++; + frame_desc->status = -EOVERFLOW; + /* Don't need to update actual_length in this case */ + break; + case DWC2_HC_XFER_XACT_ERR: + urb->error_count++; + frame_desc->status = -EPROTO; + frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg, + chan, chnum, qtd, halt_status, NULL); + + /* Non DWORD-aligned buffer case handling */ + if (chan->align_buf && frame_desc->actual_length && + chan->ep_is_in) { + dev_dbg(hsotg->dev, "%s(): non-aligned buffer\n", + __func__); + dma_sync_single_for_cpu(hsotg->dev, urb->dma, + urb->length, DMA_FROM_DEVICE); + memcpy(urb->buf + frame_desc->offset + + qtd->isoc_split_offset, chan->qh->dw_align_buf, + frame_desc->actual_length); + dma_sync_single_for_device(hsotg->dev, urb->dma, + urb->length, + DMA_FROM_DEVICE); + } + + /* Skip whole frame */ + if (chan->qh->do_split && + chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in && + hsotg->core_params->dma_enable > 0) { + qtd->complete_split = 0; + qtd->isoc_split_offset = 0; + } + + break; + default: + dev_err(hsotg->dev, "Unhandled halt_status (%d)\n", + halt_status); + break; + } + + if (++qtd->isoc_frame_index == urb->packet_count) { + /* + * urb->status is not used for isoc transfers. The individual + * frame_desc statuses are used instead. + */ + dwc2_host_complete(hsotg, urb->priv, urb, 0); + halt_status = DWC2_HC_XFER_URB_COMPLETE; + } else { + halt_status = DWC2_HC_XFER_COMPLETE; + } + + return halt_status; +} + +/* + * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic + * QHs, removes the QH from the active non-periodic schedule. If any QTDs are + * still linked to the QH, the QH is added to the end of the inactive + * non-periodic schedule. For periodic QHs, removes the QH from the periodic + * schedule if no more QTDs are linked to the QH. + */ +static void dwc2_deactivate_qh(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + int free_qtd) +{ + int continue_split = 0; + struct dwc2_qtd *qtd; + + dev_vdbg(hsotg->dev, " %s(%p,%p,%d)\n", __func__, hsotg, qh, free_qtd); + + if (list_empty(&qh->qtd_list)) { + dev_dbg(hsotg->dev, "## QTD list empty ##\n"); + goto no_qtd; + } + + qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry); + + if (qtd->complete_split) + continue_split = 1; + else if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_MID || + qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_END) + continue_split = 1; + + if (free_qtd) { + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + continue_split = 0; + } + +no_qtd: + if (qh->channel) + qh->channel->align_buf = 0; + qh->channel = NULL; + dwc2_hcd_qh_deactivate(hsotg, qh, continue_split); +} + +/** + * dwc2_release_channel() - Releases a host channel for use by other transfers + * + * @hsotg: The HCD state structure + * @chan: The host channel to release + * @qtd: The QTD associated with the host channel. This QTD may be + * freed if the transfer is complete or an error has occurred. + * @halt_status: Reason the channel is being released. This status + * determines the actions taken by this function. + * + * Also attempts to select and queue more transactions since at least one host + * channel is available. + */ +static void dwc2_release_channel(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + enum dwc2_transaction_type tr_type; + u32 haintmsk; + int free_qtd = 0; + + dev_vdbg(hsotg->dev, " %s: channel %d, halt_status %d\n", + __func__, chan->hc_num, halt_status); + + switch (halt_status) { + case DWC2_HC_XFER_URB_COMPLETE: + free_qtd = 1; + break; + case DWC2_HC_XFER_AHB_ERR: + case DWC2_HC_XFER_STALL: + case DWC2_HC_XFER_BABBLE_ERR: + free_qtd = 1; + break; + case DWC2_HC_XFER_XACT_ERR: + if (qtd->error_count >= 3) { + dev_vdbg(hsotg->dev, + " Complete URB with transaction error\n"); + free_qtd = 1; + if (qtd->urb) { + qtd->urb->status = -EPROTO; + dwc2_host_complete(hsotg, qtd->urb->priv, + qtd->urb, -EPROTO); + } + } + break; + case DWC2_HC_XFER_URB_DEQUEUE: + /* + * The QTD has already been removed and the QH has been + * deactivated. Don't want to do anything except release the + * host channel and try to queue more transfers. + */ + goto cleanup; + case DWC2_HC_XFER_PERIODIC_INCOMPLETE: + dev_vdbg(hsotg->dev, " Complete URB with I/O error\n"); + free_qtd = 1; + if (qtd->urb) { + qtd->urb->status = -EIO; + dwc2_host_complete(hsotg, qtd->urb->priv, qtd->urb, + -EIO); + } + break; + case DWC2_HC_XFER_NO_HALT_STATUS: + default: + break; + } + + dwc2_deactivate_qh(hsotg, chan->qh, free_qtd); + +cleanup: + /* + * Release the host channel for use by other transfers. The cleanup + * function clears the channel interrupt enables and conditions, so + * there's no need to clear the Channel Halted interrupt separately. + */ + if (!list_empty(&chan->hc_list_entry)) + list_del(&chan->hc_list_entry); + dwc2_hc_cleanup(hsotg, chan); + list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + + switch (chan->ep_type) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + hsotg->non_periodic_channels--; + break; + default: + /* + * Don't release reservations for periodic channels here. + * That's done when a periodic transfer is descheduled (i.e. + * when the QH is removed from the periodic schedule). + */ + break; + } + + haintmsk = readl(hsotg->regs + HAINTMSK); + haintmsk &= ~(1 << chan->hc_num); + writel(haintmsk, hsotg->regs + HAINTMSK); + + /* Try to queue more transfers now that there's a free channel */ + tr_type = dwc2_hcd_select_transactions(hsotg); + if (tr_type != DWC2_TRANSACTION_NONE) + dwc2_hcd_queue_transactions(hsotg, tr_type); +} + +/* + * Halts a host channel. If the channel cannot be halted immediately because + * the request queue is full, this function ensures that the FIFO empty + * interrupt for the appropriate queue is enabled so that the halt request can + * be queued when there is space in the request queue. + * + * This function may also be called in DMA mode. In that case, the channel is + * simply released since the core always halts the channel automatically in + * DMA mode. + */ +static void dwc2_halt_channel(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (hsotg->core_params->dma_enable > 0) { + dev_vdbg(hsotg->dev, "DMA enabled\n"); + dwc2_release_channel(hsotg, chan, qtd, halt_status); + return; + } + + /* Slave mode processing */ + dwc2_hc_halt(hsotg, chan, halt_status); + + if (chan->halt_on_queue) { + u32 gintmsk; + + dev_vdbg(hsotg->dev, "Halt on queue\n"); + if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || + chan->ep_type == USB_ENDPOINT_XFER_BULK) { + dev_vdbg(hsotg->dev, "control/bulk\n"); + /* + * Make sure the Non-periodic Tx FIFO empty interrupt + * is enabled so that the non-periodic schedule will + * be processed + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk |= GINTSTS_NPTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } else { + dev_vdbg(hsotg->dev, "isoc/intr\n"); + /* + * Move the QH from the periodic queued schedule to + * the periodic assigned schedule. This allows the + * halt to be queued when the periodic schedule is + * processed. + */ + list_move(&chan->qh->qh_list_entry, + &hsotg->periodic_sched_assigned); + + /* + * Make sure the Periodic Tx FIFO Empty interrupt is + * enabled so that the periodic schedule will be + * processed + */ + gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk |= GINTSTS_PTXFEMP; + writel(gintmsk, hsotg->regs + GINTMSK); + } + } +} + +/* + * Performs common cleanup for non-periodic transfers after a Transfer + * Complete interrupt. This function should be called after any endpoint type + * specific handling is finished to release the host channel. + */ +static void dwc2_complete_non_periodic_xfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + int chnum, struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + qtd->error_count = 0; + + if (chan->hcint & HCINTMSK_NYET) { + /* + * Got a NYET on the last transaction of the transfer. This + * means that the endpoint should be in the PING state at the + * beginning of the next transfer. + */ + dev_vdbg(hsotg->dev, "got NYET\n"); + chan->qh->ping_state = 1; + } + + /* + * Always halt and release the host channel to make it available for + * more transfers. There may still be more phases for a control + * transfer or more data packets for a bulk transfer at this point, + * but the host channel is still halted. A channel will be reassigned + * to the transfer when the non-periodic schedule is processed after + * the channel is released. This allows transactions to be queued + * properly via dwc2_hcd_queue_transactions, which also enables the + * Tx FIFO Empty interrupt if necessary. + */ + if (chan->ep_is_in) { + /* + * IN transfers in Slave mode require an explicit disable to + * halt the channel. (In DMA mode, this call simply releases + * the channel.) + */ + dwc2_halt_channel(hsotg, chan, qtd, halt_status); + } else { + /* + * The channel is automatically disabled by the core for OUT + * transfers in Slave mode + */ + dwc2_release_channel(hsotg, chan, qtd, halt_status); + } +} + +/* + * Performs common cleanup for periodic transfers after a Transfer Complete + * interrupt. This function should be called after any endpoint type specific + * handling is finished to release the host channel. + */ +static void dwc2_complete_periodic_xfer(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + + qtd->error_count = 0; + + if (!chan->ep_is_in || (hctsiz & TSIZ_PKTCNT_MASK) == 0) + /* Core halts channel in these cases */ + dwc2_release_channel(hsotg, chan, qtd, halt_status); + else + /* Flush any outstanding requests from the Tx queue */ + dwc2_halt_channel(hsotg, chan, qtd, halt_status); +} + +static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + struct dwc2_hcd_iso_packet_desc *frame_desc; + u32 len; + + if (!qtd->urb) + return 0; + + frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index]; + len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd, + DWC2_HC_XFER_COMPLETE, NULL); + if (!len) { + qtd->complete_split = 0; + qtd->isoc_split_offset = 0; + return 0; + } + + frame_desc->actual_length += len; + + if (chan->align_buf && len) { + dev_dbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); + dma_sync_single_for_cpu(hsotg->dev, qtd->urb->dma, + qtd->urb->length, DMA_FROM_DEVICE); + memcpy(qtd->urb->buf + frame_desc->offset + + qtd->isoc_split_offset, chan->qh->dw_align_buf, len); + dma_sync_single_for_device(hsotg->dev, qtd->urb->dma, + qtd->urb->length, DMA_FROM_DEVICE); + } + + qtd->isoc_split_offset += len; + + if (frame_desc->actual_length >= frame_desc->length) { + frame_desc->status = 0; + qtd->isoc_frame_index++; + qtd->complete_split = 0; + qtd->isoc_split_offset = 0; + } + + if (qtd->isoc_frame_index == qtd->urb->packet_count) { + dwc2_host_complete(hsotg, qtd->urb->priv, qtd->urb, 0); + dwc2_release_channel(hsotg, chan, qtd, + DWC2_HC_XFER_URB_COMPLETE); + } else { + dwc2_release_channel(hsotg, chan, qtd, + DWC2_HC_XFER_NO_HALT_STATUS); + } + + return 1; /* Indicates that channel released */ +} + +/* + * Handles a host channel Transfer Complete interrupt. This handler may be + * called in either DMA mode or Slave mode. + */ +static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + enum dwc2_halt_status halt_status = DWC2_HC_XFER_COMPLETE; + int urb_xfer_done; + + dev_vdbg(hsotg->dev, + "--Host Channel %d Interrupt: Transfer Complete--\n", chnum); + + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status); + if (pipe_type == USB_ENDPOINT_XFER_ISOC) + /* Do not disable the interrupt, just clear it */ + return; + goto handle_xfercomp_done; + } + + /* Handle xfer complete on CSPLIT */ + if (chan->qh->do_split) { + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in && + hsotg->core_params->dma_enable > 0) { + if (qtd->complete_split && + dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum, + qtd)) + goto handle_xfercomp_done; + } else { + qtd->complete_split = 0; + } + } + + if (!urb) + goto handle_xfercomp_done; + + /* Update the QTD and URB states */ + switch (pipe_type) { + case USB_ENDPOINT_XFER_CONTROL: + switch (qtd->control_phase) { + case DWC2_CONTROL_SETUP: + if (urb->length > 0) + qtd->control_phase = DWC2_CONTROL_DATA; + else + qtd->control_phase = DWC2_CONTROL_STATUS; + dev_vdbg(hsotg->dev, + " Control setup transaction done\n"); + halt_status = DWC2_HC_XFER_COMPLETE; + break; + case DWC2_CONTROL_DATA: + urb_xfer_done = dwc2_update_urb_state(hsotg, chan, + chnum, urb, qtd); + if (urb_xfer_done) { + qtd->control_phase = DWC2_CONTROL_STATUS; + dev_vdbg(hsotg->dev, + " Control data transfer done\n"); + } else { + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, + qtd); + } + halt_status = DWC2_HC_XFER_COMPLETE; + break; + case DWC2_CONTROL_STATUS: + dev_vdbg(hsotg->dev, " Control transfer complete\n"); + if (urb->status == -EINPROGRESS) + urb->status = 0; + dwc2_host_complete(hsotg, urb->priv, urb, urb->status); + halt_status = DWC2_HC_XFER_URB_COMPLETE; + break; + } + + dwc2_complete_non_periodic_xfer(hsotg, chan, chnum, qtd, + halt_status); + break; + case USB_ENDPOINT_XFER_BULK: + dev_vdbg(hsotg->dev, " Bulk transfer complete\n"); + urb_xfer_done = dwc2_update_urb_state(hsotg, chan, chnum, urb, + qtd); + if (urb_xfer_done) { + dwc2_host_complete(hsotg, urb->priv, urb, urb->status); + halt_status = DWC2_HC_XFER_URB_COMPLETE; + } else { + halt_status = DWC2_HC_XFER_COMPLETE; + } + + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + dwc2_complete_non_periodic_xfer(hsotg, chan, chnum, qtd, + halt_status); + break; + case USB_ENDPOINT_XFER_INT: + dev_vdbg(hsotg->dev, " Interrupt transfer complete\n"); + urb_xfer_done = dwc2_update_urb_state(hsotg, chan, chnum, urb, + qtd); + + /* + * Interrupt URB is done on the first transfer complete + * interrupt + */ + if (urb_xfer_done) { + dwc2_host_complete(hsotg, urb->priv, urb, + urb->status); + halt_status = DWC2_HC_XFER_URB_COMPLETE; + } else { + halt_status = DWC2_HC_XFER_COMPLETE; + } + + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd, + halt_status); + break; + case USB_ENDPOINT_XFER_ISOC: + dev_vdbg(hsotg->dev, " Isochronous transfer complete\n"); + if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL) + halt_status = dwc2_update_isoc_urb_state(hsotg, chan, + chnum, qtd, DWC2_HC_XFER_COMPLETE); + dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd, + halt_status); + break; + } + +handle_xfercomp_done: + disable_hc_int(hsotg, chnum, HCINTMSK_XFERCOMPL); +} + +/* + * Handles a host channel STALL interrupt. This handler may be called in + * either DMA mode or Slave mode. + */ +static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + + dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n", + chnum); + + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, + DWC2_HC_XFER_STALL); + goto handle_stall_done; + } + + if (!urb) + goto handle_stall_halt; + + if (pipe_type == USB_ENDPOINT_XFER_CONTROL) + dwc2_host_complete(hsotg, urb->priv, urb, -EPIPE); + + if (pipe_type == USB_ENDPOINT_XFER_BULK || + pipe_type == USB_ENDPOINT_XFER_INT) { + dwc2_host_complete(hsotg, urb->priv, urb, -EPIPE); + /* + * USB protocol requires resetting the data toggle for bulk + * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT) + * setup command is issued to the endpoint. Anticipate the + * CLEAR_FEATURE command since a STALL has occurred and reset + * the data toggle now. + */ + chan->qh->data_toggle = 0; + } + +handle_stall_halt: + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_STALL); + +handle_stall_done: + disable_hc_int(hsotg, chnum, HCINTMSK_STALL); +} + +/* + * Updates the state of the URB when a transfer has been stopped due to an + * abnormal condition before the transfer completes. Modifies the + * actual_length field of the URB to reflect the number of bytes that have + * actually been transferred via the host channel. + */ +static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_hcd_urb *urb, + struct dwc2_qtd *qtd, + enum dwc2_halt_status halt_status) +{ + u32 xfer_length = dwc2_get_actual_xfer_length(hsotg, chan, chnum, + qtd, halt_status, NULL); + u32 hctsiz; + + if (urb->actual_length + xfer_length > urb->length) { + dev_warn(hsotg->dev, "%s(): trimming xfer length\n", __func__); + xfer_length = urb->length - urb->actual_length; + } + + /* Non DWORD-aligned buffer case handling */ + if (chan->align_buf && xfer_length && chan->ep_is_in) { + dev_dbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); + dma_sync_single_for_cpu(hsotg->dev, urb->dma, urb->length, + DMA_FROM_DEVICE); + memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, + xfer_length); + dma_sync_single_for_device(hsotg->dev, urb->dma, urb->length, + DMA_FROM_DEVICE); + } + + urb->actual_length += xfer_length; + + hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n", + __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum); + dev_vdbg(hsotg->dev, " chan->start_pkt_count %d\n", + chan->start_pkt_count); + dev_vdbg(hsotg->dev, " hctsiz.pktcnt %d\n", + hctsiz >> TSIZ_PKTCNT_SHIFT & + TSIZ_PKTCNT_MASK >> TSIZ_PKTCNT_SHIFT); + dev_vdbg(hsotg->dev, " chan->max_packet %d\n", chan->max_packet); + dev_vdbg(hsotg->dev, " bytes_transferred %d\n", + xfer_length); + dev_vdbg(hsotg->dev, " urb->actual_length %d\n", + urb->actual_length); + dev_vdbg(hsotg->dev, " urb->transfer_buffer_length %d\n", + urb->length); +} + +/* + * Handles a host channel NAK interrupt. This handler may be called in either + * DMA mode or Slave mode. + */ +static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: NAK Received--\n", + chnum); + + /* + * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and + * interrupt. Re-start the SSPLIT transfer. + */ + if (chan->do_split) { + if (chan->complete_split) + qtd->error_count = 0; + qtd->complete_split = 0; + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK); + goto handle_nak_done; + } + + switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + if (hsotg->core_params->dma_enable > 0 && chan->ep_is_in) { + /* + * NAK interrupts are enabled on bulk/control IN + * transfers in DMA mode for the sole purpose of + * resetting the error count after a transaction error + * occurs. The core will continue transferring data. + */ + qtd->error_count = 0; + break; + } + + /* + * NAK interrupts normally occur during OUT transfers in DMA + * or Slave mode. For IN transfers, more requests will be + * queued as request queue space is available. + */ + qtd->error_count = 0; + + if (!chan->qh->ping_state) { + dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb, + qtd, DWC2_HC_XFER_NAK); + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + + if (chan->speed == USB_SPEED_HIGH) + chan->qh->ping_state = 1; + } + + /* + * Halt the channel so the transfer can be re-started from + * the appropriate point or the PING protocol will + * start/continue + */ + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK); + break; + case USB_ENDPOINT_XFER_INT: + qtd->error_count = 0; + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK); + break; + case USB_ENDPOINT_XFER_ISOC: + /* Should never get called for isochronous transfers */ + dev_err(hsotg->dev, "NACK interrupt for ISOC transfer\n"); + break; + } + +handle_nak_done: + disable_hc_int(hsotg, chnum, HCINTMSK_NAK); +} + +/* + * Handles a host channel ACK interrupt. This interrupt is enabled when + * performing the PING protocol in Slave mode, when errors occur during + * either Slave mode or DMA mode, and during Start Split transactions. + */ +static void dwc2_hc_ack_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + struct dwc2_hcd_iso_packet_desc *frame_desc; + + dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: ACK Received--\n", + chnum); + + if (chan->do_split) { + /* Handle ACK on SSPLIT. ACK should not occur in CSPLIT. */ + if (!chan->ep_is_in && + chan->data_pid_start != DWC2_HC_PID_SETUP) + qtd->ssplit_out_xfer_count = chan->xfer_len; + + if (chan->ep_type != USB_ENDPOINT_XFER_ISOC || chan->ep_is_in) { + qtd->complete_split = 1; + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_ACK); + } else { + /* ISOC OUT */ + switch (chan->xact_pos) { + case DWC2_HCSPLT_XACTPOS_ALL: + break; + case DWC2_HCSPLT_XACTPOS_END: + qtd->isoc_split_pos = DWC2_HCSPLT_XACTPOS_ALL; + qtd->isoc_split_offset = 0; + break; + case DWC2_HCSPLT_XACTPOS_BEGIN: + case DWC2_HCSPLT_XACTPOS_MID: + /* + * For BEGIN or MID, calculate the length for + * the next microframe to determine the correct + * SSPLIT token, either MID or END + */ + frame_desc = &qtd->urb->iso_descs[ + qtd->isoc_frame_index]; + qtd->isoc_split_offset += 188; + + if (frame_desc->length - qtd->isoc_split_offset + <= 188) + qtd->isoc_split_pos = + DWC2_HCSPLT_XACTPOS_END; + else + qtd->isoc_split_pos = + DWC2_HCSPLT_XACTPOS_MID; + break; + } + } + } else { + qtd->error_count = 0; + + if (chan->qh->ping_state) { + chan->qh->ping_state = 0; + /* + * Halt the channel so the transfer can be re-started + * from the appropriate point. This only happens in + * Slave mode. In DMA mode, the ping_state is cleared + * when the transfer is started because the core + * automatically executes the PING, then the transfer. + */ + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_ACK); + } + } + + /* + * If the ACK occurred when _not_ in the PING state, let the channel + * continue transferring data after clearing the error count + */ + disable_hc_int(hsotg, chnum, HCINTMSK_ACK); +} + +/* + * Handles a host channel NYET interrupt. This interrupt should only occur on + * Bulk and Control OUT endpoints and for complete split transactions. If a + * NYET occurs at the same time as a Transfer Complete interrupt, it is + * handled in the xfercomp interrupt handler, not here. This handler may be + * called in either DMA mode or Slave mode. + */ +static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: NYET Received--\n", + chnum); + + /* + * NYET on CSPLIT + * re-do the CSPLIT immediately on non-periodic + */ + if (chan->do_split && chan->complete_split) { + if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC && + hsotg->core_params->dma_enable > 0) { + qtd->complete_split = 0; + qtd->isoc_split_offset = 0; + if (++qtd->isoc_frame_index == qtd->urb->packet_count) { + if (qtd->urb) + dwc2_host_complete(hsotg, + qtd->urb->priv, + qtd->urb, 0); + dwc2_release_channel(hsotg, chan, qtd, + DWC2_HC_XFER_URB_COMPLETE); + } else { + dwc2_release_channel(hsotg, chan, qtd, + DWC2_HC_XFER_NO_HALT_STATUS); + } + goto handle_nyet_done; + } + + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + int frnum = dwc2_hcd_get_frame_number(hsotg); + + if (dwc2_full_frame_num(frnum) != + dwc2_full_frame_num(chan->qh->sched_frame)) { + /* + * No longer in the same full speed frame. + * Treat this as a transaction error. + */ +#if 0 + /* + * Todo: Fix system performance so this can + * be treated as an error. Right now complete + * splits cannot be scheduled precisely enough + * due to other system activity, so this error + * occurs regularly in Slave mode. + */ + qtd->error_count++; +#endif + qtd->complete_split = 0; + dwc2_halt_channel(hsotg, chan, qtd, + DWC2_HC_XFER_XACT_ERR); + /* Todo: add support for isoc release */ + goto handle_nyet_done; + } + } + + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NYET); + goto handle_nyet_done; + } + + chan->qh->ping_state = 1; + qtd->error_count = 0; + + dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb, qtd, + DWC2_HC_XFER_NYET); + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + + /* + * Halt the channel and re-start the transfer so the PING protocol + * will start + */ + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NYET); + +handle_nyet_done: + disable_hc_int(hsotg, chnum, HCINTMSK_NYET); +} + +/* + * Handles a host channel babble interrupt. This handler may be called in + * either DMA mode or Slave mode. + */ +static void dwc2_hc_babble_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: Babble Error--\n", + chnum); + + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, + DWC2_HC_XFER_BABBLE_ERR); + goto handle_babble_done; + } + + if (chan->ep_type != USB_ENDPOINT_XFER_ISOC) { + if (qtd->urb) + dwc2_host_complete(hsotg, qtd->urb->priv, qtd->urb, + -EOVERFLOW); + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_BABBLE_ERR); + } else { + enum dwc2_halt_status halt_status; + + halt_status = dwc2_update_isoc_urb_state(hsotg, chan, chnum, + qtd, DWC2_HC_XFER_BABBLE_ERR); + dwc2_halt_channel(hsotg, chan, qtd, halt_status); + } + +handle_babble_done: + dwc2_hc_handle_tt_clear(hsotg, chan, qtd); + disable_hc_int(hsotg, chnum, HCINTMSK_BBLERR); +} + +/* + * Handles a host channel AHB error interrupt. This handler is only called in + * DMA mode. + */ +static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + char *pipetype, *speed; + u32 hcchar; + u32 hcsplt; + u32 hctsiz; + u32 hc_dma; + + dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: AHB Error--\n", + chnum); + + if (!urb) + goto handle_ahberr_halt; + + hcchar = readl(hsotg->regs + HCCHAR(chnum)); + hcsplt = readl(hsotg->regs + HCSPLT(chnum)); + hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + hc_dma = readl(hsotg->regs + HCDMA(chnum)); + + dev_err(hsotg->dev, "AHB ERROR, Channel %d\n", chnum); + dev_err(hsotg->dev, " hcchar 0x%08x, hcsplt 0x%08x\n", hcchar, hcsplt); + dev_err(hsotg->dev, " hctsiz 0x%08x, hc_dma 0x%08x\n", hctsiz, hc_dma); + dev_err(hsotg->dev, " Device address: %d\n", + dwc2_hcd_get_dev_addr(&urb->pipe_info)); + dev_err(hsotg->dev, " Endpoint: %d, %s\n", + dwc2_hcd_get_ep_num(&urb->pipe_info), + dwc2_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"); + + switch (dwc2_hcd_get_pipe_type(&urb->pipe_info)) { + case USB_ENDPOINT_XFER_CONTROL: + pipetype = "CONTROL"; + break; + case USB_ENDPOINT_XFER_BULK: + pipetype = "BULK"; + break; + case USB_ENDPOINT_XFER_INT: + pipetype = "INTERRUPT"; + break; + case USB_ENDPOINT_XFER_ISOC: + pipetype = "ISOCHRONOUS"; + break; + default: + pipetype = "UNKNOWN"; + break; + } + + dev_err(hsotg->dev, " Endpoint type: %s\n", pipetype); + + switch (chan->speed) { + case USB_SPEED_HIGH: + speed = "HIGH"; + break; + case USB_SPEED_FULL: + speed = "FULL"; + break; + case USB_SPEED_LOW: + speed = "LOW"; + break; + default: + speed = "UNKNOWN"; + break; + } + + dev_err(hsotg->dev, " Speed: %s\n", speed); + + dev_err(hsotg->dev, " Max packet size: %d\n", + dwc2_hcd_get_mps(&urb->pipe_info)); + dev_err(hsotg->dev, " Data buffer length: %d\n", urb->length); + dev_err(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %p\n", + urb->buf, (void *)urb->dma); + dev_err(hsotg->dev, " Setup buffer: %p, Setup DMA: %p\n", + urb->setup_packet, (void *)urb->setup_dma); + dev_err(hsotg->dev, " Interval: %d\n", urb->interval); + + /* Core halts the channel for Descriptor DMA mode */ + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, + DWC2_HC_XFER_AHB_ERR); + goto handle_ahberr_done; + } + + dwc2_host_complete(hsotg, urb->priv, urb, -EIO); + +handle_ahberr_halt: + /* + * Force a channel halt. Don't call dwc2_halt_channel because that won't + * write to the HCCHARn register in DMA mode to force the halt. + */ + dwc2_hc_halt(hsotg, chan, DWC2_HC_XFER_AHB_ERR); + +handle_ahberr_done: + dwc2_hc_handle_tt_clear(hsotg, chan, qtd); + disable_hc_int(hsotg, chnum, HCINTMSK_AHBERR); +} + +/* + * Handles a host channel transaction error interrupt. This handler may be + * called in either DMA mode or Slave mode. + */ +static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_dbg(hsotg->dev, + "--Host Channel %d Interrupt: Transaction Error--\n", chnum); + + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, + DWC2_HC_XFER_XACT_ERR); + goto handle_xacterr_done; + } + + switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + qtd->error_count++; + if (!chan->qh->ping_state) { + + dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb, + qtd, DWC2_HC_XFER_XACT_ERR); + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + if (!chan->ep_is_in && chan->speed == USB_SPEED_HIGH) + chan->qh->ping_state = 1; + } + + /* + * Halt the channel so the transfer can be re-started from + * the appropriate point or the PING protocol will start + */ + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_XACT_ERR); + break; + case USB_ENDPOINT_XFER_INT: + qtd->error_count++; + if (chan->do_split && chan->complete_split) + qtd->complete_split = 0; + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_XACT_ERR); + break; + case USB_ENDPOINT_XFER_ISOC: + { + enum dwc2_halt_status halt_status; + + halt_status = dwc2_update_isoc_urb_state(hsotg, chan, + chnum, qtd, DWC2_HC_XFER_XACT_ERR); + dwc2_halt_channel(hsotg, chan, qtd, halt_status); + } + break; + } + +handle_xacterr_done: + dwc2_hc_handle_tt_clear(hsotg, chan, qtd); + disable_hc_int(hsotg, chnum, HCINTMSK_XACTERR); +} + +/* + * Handles a host channel frame overrun interrupt. This handler may be called + * in either DMA mode or Slave mode. + */ +static void dwc2_hc_frmovrun_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + enum dwc2_halt_status halt_status; + + dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: Frame Overrun--\n", + chnum); + + switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + break; + case USB_ENDPOINT_XFER_INT: + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_FRAME_OVERRUN); + break; + case USB_ENDPOINT_XFER_ISOC: + halt_status = dwc2_update_isoc_urb_state(hsotg, chan, chnum, + qtd, DWC2_HC_XFER_FRAME_OVERRUN); + dwc2_halt_channel(hsotg, chan, qtd, halt_status); + break; + } + + dwc2_hc_handle_tt_clear(hsotg, chan, qtd); + disable_hc_int(hsotg, chnum, HCINTMSK_FRMOVRUN); +} + +/* + * Handles a host channel data toggle error interrupt. This handler may be + * called in either DMA mode or Slave mode. + */ +static void dwc2_hc_datatglerr_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_dbg(hsotg->dev, + "--Host Channel %d Interrupt: Data Toggle Error--\n", chnum); + + if (chan->ep_is_in) + qtd->error_count = 0; + else + dev_err(hsotg->dev, + "Data Toggle Error on OUT transfer, channel %d\n", + chnum); + + dwc2_hc_handle_tt_clear(hsotg, chan, qtd); + disable_hc_int(hsotg, chnum, HCINTMSK_DATATGLERR); +} + +/* + * For debug only. It checks that a valid halt status is set and that + * HCCHARn.chdis is clear. If there's a problem, corrective action is + * taken and a warning is issued. + * + * Return: true if halt status is ok, false otherwise + */ +static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ +#ifdef DEBUG + u32 hcchar; + u32 hctsiz; + u32 hcintmsk; + u32 hcsplt; + + if (chan->halt_status == DWC2_HC_XFER_NO_HALT_STATUS) { + /* + * This code is here only as a check. This condition should + * never happen. Ignore the halt if it does occur. + */ + hcchar = readl(hsotg->regs + HCCHAR(chnum)); + hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); + hcsplt = readl(hsotg->regs + HCSPLT(chnum)); + dev_dbg(hsotg->dev, + "%s: chan->halt_status DWC2_HC_XFER_NO_HALT_STATUS,\n", + __func__); + dev_dbg(hsotg->dev, + "channel %d, hcchar 0x%08x, hctsiz 0x%08x,\n", + chnum, hcchar, hctsiz); + dev_dbg(hsotg->dev, + "hcint 0x%08x, hcintmsk 0x%08x, hcsplt 0x%08x,\n", + chan->hcint, hcintmsk, hcsplt); + dev_dbg(hsotg->dev, "qtd->complete_split %d\n", + qtd->complete_split); + dev_warn(hsotg->dev, + "%s: no halt status, channel %d, ignoring interrupt\n", + __func__, chnum); + return false; + } + + /* + * This code is here only as a check. hcchar.chdis should never be set + * when the halt interrupt occurs. Halt the channel again if it does + * occur. + */ + hcchar = readl(hsotg->regs + HCCHAR(chnum)); + if (hcchar & HCCHAR_CHDIS) { + dev_warn(hsotg->dev, + "%s: hcchar.chdis set unexpectedly, hcchar 0x%08x, trying to halt again\n", + __func__, hcchar); + chan->halt_pending = 0; + dwc2_halt_channel(hsotg, chan, qtd, chan->halt_status); + return false; + } +#endif + + return true; +} + +/* + * Handles a host Channel Halted interrupt in DMA mode. This handler + * determines the reason the channel halted and proceeds accordingly. + */ +static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + u32 hcintmsk; + int out_nak_enh = 0; + + dev_vdbg(hsotg->dev, + "--Host Channel %d Interrupt: DMA Channel Halted--\n", chnum); + + /* + * For core with OUT NAK enhancement, the flow for high-speed + * CONTROL/BULK OUT is handled a little differently + */ + if (hsotg->snpsid >= DWC2_CORE_REV_2_71a) { + if (chan->speed == USB_SPEED_HIGH && !chan->ep_is_in && + (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || + chan->ep_type == USB_ENDPOINT_XFER_BULK)) { + out_nak_enh = 1; + } + } + + if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE || + (chan->halt_status == DWC2_HC_XFER_AHB_ERR && + hsotg->core_params->dma_desc_enable <= 0)) { + if (hsotg->core_params->dma_desc_enable > 0) + dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, + chan->halt_status); + else + /* + * Just release the channel. A dequeue can happen on a + * transfer timeout. In the case of an AHB Error, the + * channel was forced to halt because there's no way to + * gracefully recover. + */ + dwc2_release_channel(hsotg, chan, qtd, + chan->halt_status); + return; + } + + hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); + + if (chan->hcint & HCINTMSK_XFERCOMPL) { + /* + * Todo: This is here because of a possible hardware bug. Spec + * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT + * interrupt w/ACK bit set should occur, but I only see the + * XFERCOMP bit, even with it masked out. This is a workaround + * for that behavior. Should fix this when hardware is fixed. + */ + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && !chan->ep_is_in) + dwc2_hc_ack_intr(hsotg, chan, chnum, qtd); + dwc2_hc_xfercomp_intr(hsotg, chan, chnum, qtd); + } else if (chan->hcint & HCINTMSK_STALL) { + dwc2_hc_stall_intr(hsotg, chan, chnum, qtd); + } else if ((chan->hcint & HCINTMSK_XACTERR) && + hsotg->core_params->dma_desc_enable <= 0) { + if (out_nak_enh) { + if (chan->hcint & + (HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) { + dev_vdbg(hsotg->dev, + "XactErr with NYET/NAK/ACK\n"); + qtd->error_count = 0; + } else { + dev_vdbg(hsotg->dev, + "XactErr without NYET/NAK/ACK\n"); + } + } + + /* + * Must handle xacterr before nak or ack. Could get a xacterr + * at the same time as either of these on a BULK/CONTROL OUT + * that started with a PING. The xacterr takes precedence. + */ + dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); + } else if ((chan->hcint & HCINTMSK_XCS_XACT) && + hsotg->core_params->dma_desc_enable > 0) { + dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); + } else if ((chan->hcint & HCINTMSK_AHBERR) && + hsotg->core_params->dma_desc_enable > 0) { + dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd); + } else if (chan->hcint & HCINTMSK_BBLERR) { + dwc2_hc_babble_intr(hsotg, chan, chnum, qtd); + } else if (chan->hcint & HCINTMSK_FRMOVRUN) { + dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd); + } else if (!out_nak_enh) { + if (chan->hcint & HCINTMSK_NYET) { + /* + * Must handle nyet before nak or ack. Could get a nyet + * at the same time as either of those on a BULK/CONTROL + * OUT that started with a PING. The nyet takes + * precedence. + */ + dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd); + } else if ((chan->hcint & HCINTMSK_NAK) && + !(hcintmsk & HCINTMSK_NAK)) { + /* + * If nak is not masked, it's because a non-split IN + * transfer is in an error state. In that case, the nak + * is handled by the nak interrupt handler, not here. + * Handle nak here for BULK/CONTROL OUT transfers, which + * halt on a NAK to allow rewinding the buffer pointer. + */ + dwc2_hc_nak_intr(hsotg, chan, chnum, qtd); + } else if ((chan->hcint & HCINTMSK_ACK) && + !(hcintmsk & HCINTMSK_ACK)) { + /* + * If ack is not masked, it's because a non-split IN + * transfer is in an error state. In that case, the ack + * is handled by the ack interrupt handler, not here. + * Handle ack here for split transfers. Start splits + * halt on ACK. + */ + dwc2_hc_ack_intr(hsotg, chan, chnum, qtd); + } else { + if (chan->ep_type == USB_ENDPOINT_XFER_INT || + chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + /* + * A periodic transfer halted with no other + * channel interrupts set. Assume it was halted + * by the core because it could not be completed + * in its scheduled (micro)frame. + */ + dev_dbg(hsotg->dev, + "%s: Halt channel %d (assume incomplete periodic transfer)\n", + __func__, chnum); + dwc2_halt_channel(hsotg, chan, qtd, + DWC2_HC_XFER_PERIODIC_INCOMPLETE); + } else { + dev_err(hsotg->dev, + "%s: Channel %d - ChHltd set, but reason is unknown\n", + __func__, chnum); + dev_err(hsotg->dev, + "hcint 0x%08x, intsts 0x%08x\n", + chan->hcint, + readl(hsotg->regs + GINTSTS)); + } + } + } else { + dev_info(hsotg->dev, + "NYET/NAK/ACK/other in non-error case, 0x%08x\n", + chan->hcint); + } +} + +/* + * Handles a host channel Channel Halted interrupt + * + * In slave mode, this handler is called only when the driver specifically + * requests a halt. This occurs during handling other host channel interrupts + * (e.g. nak, xacterr, stall, nyet, etc.). + * + * In DMA mode, this is the interrupt that occurs when the core has finished + * processing a transfer on a channel. Other host channel interrupts (except + * ahberr) are disabled in DMA mode. + */ +static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + struct dwc2_qtd *qtd) +{ + dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n", + chnum); + + if (hsotg->core_params->dma_enable > 0) { + dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd); + } else { + if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd)) + return; + dwc2_release_channel(hsotg, chan, qtd, chan->halt_status); + } +} + +/* Handles interrupt for a specific Host Channel */ +static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) +{ + struct dwc2_qtd *qtd; + struct dwc2_host_chan *chan; + u32 hcint, hcintmsk; + + dev_vdbg(hsotg->dev, "--Host Channel Interrupt--, Channel %d\n", chnum); + + hcint = readl(hsotg->regs + HCINT(chnum)); + hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); + dev_vdbg(hsotg->dev, + " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n", + hcint, hcintmsk, hcint & hcintmsk); + + chan = hsotg->hc_ptr_array[chnum]; + if (!chan) { + dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n"); + writel(hcint, hsotg->regs + HCINT(chnum)); + return; + } + + writel(hcint, hsotg->regs + HCINT(chnum)); + chan->hcint = hcint; + hcint &= hcintmsk; + + if (list_empty(&chan->qh->qtd_list)) { + dev_dbg(hsotg->dev, "## no QTD queued for channel %d ##\n", + chnum); + dev_dbg(hsotg->dev, + " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n", + chan->hcint, hcintmsk, hcint); + chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS; + disable_hc_int(hsotg, chnum, HCINTMSK_CHHLTD); + chan->hcint = 0; + return; + } + + qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd, + qtd_list_entry); + + if (hsotg->core_params->dma_enable <= 0) { + if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD) + hcint &= ~HCINTMSK_CHHLTD; + } + + if (hcint & HCINTMSK_XFERCOMPL) { + dwc2_hc_xfercomp_intr(hsotg, chan, chnum, qtd); + /* + * If NYET occurred at same time as Xfer Complete, the NYET is + * handled by the Xfer Complete interrupt handler. Don't want + * to call the NYET interrupt handler in this case. + */ + hcint &= ~HCINTMSK_NYET; + } + if (hcint & HCINTMSK_CHHLTD) + dwc2_hc_chhltd_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_AHBERR) + dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_STALL) + dwc2_hc_stall_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_NAK) + dwc2_hc_nak_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_ACK) + dwc2_hc_ack_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_NYET) + dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_XACTERR) + dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_BBLERR) + dwc2_hc_babble_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_FRMOVRUN) + dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd); + if (hcint & HCINTMSK_DATATGLERR) + dwc2_hc_datatglerr_intr(hsotg, chan, chnum, qtd); + + chan->hcint = 0; +} + +/* + * This interrupt indicates that one or more host channels has a pending + * interrupt. There are multiple conditions that can cause each host channel + * interrupt. This function determines which conditions have occurred for each + * host channel interrupt and handles them appropriately. + */ +static void dwc2_hc_intr(struct dwc2_hsotg *hsotg) +{ + u32 haint; + int i; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + haint = readl(hsotg->regs + HAINT); + dev_vdbg(hsotg->dev, "HAINT=%08x\n", haint); + + for (i = 0; i < hsotg->core_params->host_channels; i++) { + if (haint & (1 << i)) + dwc2_hc_n_intr(hsotg, i); + } +} + +/* This function handles interrupts for the HCD */ +int dwc2_hcd_intr(struct dwc2_hsotg *hsotg) +{ + u32 gintsts; + int retval = 0; + + if (dwc2_check_core_status(hsotg) < 0) { + dev_warn(hsotg->dev, "Controller is disconnected"); + return 0; + } + + spin_lock(&hsotg->lock); + + /* Check if HOST Mode */ + if (dwc2_is_host_mode(hsotg)) { + gintsts = dwc2_read_core_intr(hsotg); + if (!gintsts) { + spin_unlock(&hsotg->lock); + return 0; + } + + retval = 1; + +#ifndef DEBUG_SOF + /* Don't print debug message in the interrupt handler on SOF */ + if (gintsts != GINTSTS_SOF) +#endif + dev_vdbg(hsotg->dev, + "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", + gintsts); + + if (gintsts & GINTSTS_SOF) + dwc2_sof_intr(hsotg); + if (gintsts & GINTSTS_RXFLVL) + dwc2_rx_fifo_level_intr(hsotg); + if (gintsts & GINTSTS_NPTXFEMP) + dwc2_np_tx_fifo_empty_intr(hsotg); + if (gintsts & GINTSTS_I2CINT) + /* Todo: Implement i2cintr handler */ + writel(GINTSTS_I2CINT, hsotg->regs + GINTSTS); + if (gintsts & GINTSTS_PRTINT) + dwc2_port_intr(hsotg); + if (gintsts & GINTSTS_HCHINT) + dwc2_hc_intr(hsotg); + if (gintsts & GINTSTS_PTXFEMP) + dwc2_perio_tx_fifo_empty_intr(hsotg); + +#ifndef DEBUG_SOF + if (gintsts != GINTSTS_SOF) { +#endif + dev_vdbg(hsotg->dev, + "DWC OTG HCD Finished Servicing Interrupts\n"); + dev_vdbg(hsotg->dev, + "DWC OTG HCD gintsts=0x%08x gintmsk=0x%08x\n", + readl(hsotg->regs + GINTSTS), + readl(hsotg->regs + GINTMSK)); +#ifndef DEBUG_SOF + } +#endif + } + + spin_unlock(&hsotg->lock); + + return retval; +} diff --git a/drivers/staging/dwc2/hcd_queue.c b/drivers/staging/dwc2/hcd_queue.c new file mode 100644 index 000000000000..74b7b9b0ef34 --- /dev/null +++ b/drivers/staging/dwc2/hcd_queue.c @@ -0,0 +1,675 @@ +/* + * hcd_queue.c - DesignWare HS OTG Controller host queuing routines + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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 file contains the functions to manage Queue Heads and Queue + * Transfer Descriptors for Host mode + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +/** + * dwc2_qh_init() - Initializes a QH structure + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: The QH to init + * @urb: Holds the information about the device/endpoint needed to initialize + * the QH + */ +#define SCHEDULE_SLOP 10 +static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + struct dwc2_hcd_urb *urb) +{ + int dev_speed, hub_addr, hub_port; + char *speed, *type; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + /* Initialize QH */ + qh->ep_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + qh->ep_is_in = dwc2_hcd_is_pipe_in(&urb->pipe_info) ? 1 : 0; + + qh->data_toggle = DWC2_HC_PID_DATA0; + qh->maxp = dwc2_hcd_get_mps(&urb->pipe_info); + INIT_LIST_HEAD(&qh->qtd_list); + INIT_LIST_HEAD(&qh->qh_list_entry); + + /* FS/LS Endpoint on HS Hub, NOT virtual root hub */ + dev_speed = dwc2_host_get_speed(hsotg, urb->priv); + + dwc2_host_hub_info(hsotg, urb->priv, &hub_addr, &hub_port); + + if ((dev_speed == USB_SPEED_LOW || dev_speed == USB_SPEED_FULL) && + hub_addr != 0 && hub_addr != 1) { + dev_vdbg(hsotg->dev, + "QH init: EP %d: TT found at hub addr %d, for port %d\n", + dwc2_hcd_get_ep_num(&urb->pipe_info), hub_addr, + hub_port); + qh->do_split = 1; + } + + if (qh->ep_type == USB_ENDPOINT_XFER_INT || + qh->ep_type == USB_ENDPOINT_XFER_ISOC) { + /* Compute scheduling parameters once and save them */ + u32 hprt, prtspd; + + /* Todo: Account for split transfers in the bus time */ + int bytecount = + dwc2_hb_mult(qh->maxp) * dwc2_max_packet(qh->maxp); + + qh->usecs = NS_TO_US(usb_calc_bus_time(qh->do_split ? + USB_SPEED_HIGH : dev_speed, qh->ep_is_in, + qh->ep_type == USB_ENDPOINT_XFER_ISOC, + bytecount)); + /* Start in a slightly future (micro)frame */ + qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number, + SCHEDULE_SLOP); + qh->interval = urb->interval; +#if 0 + /* Increase interrupt polling rate for debugging */ + if (qh->ep_type == USB_ENDPOINT_XFER_INT) + qh->interval = 8; +#endif + hprt = readl(hsotg->regs + HPRT0); + prtspd = hprt & HPRT0_SPD_MASK; + if (prtspd == HPRT0_SPD_HIGH_SPEED && + (dev_speed == USB_SPEED_LOW || + dev_speed == USB_SPEED_FULL)) { + qh->interval *= 8; + qh->sched_frame |= 0x7; + qh->start_split_frame = qh->sched_frame; + } + dev_dbg(hsotg->dev, "interval=%d\n", qh->interval); + } + + dev_vdbg(hsotg->dev, "DWC OTG HCD QH Initialized\n"); + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - qh = %p\n", qh); + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Device Address = %d\n", + dwc2_hcd_get_dev_addr(&urb->pipe_info)); + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Endpoint %d, %s\n", + dwc2_hcd_get_ep_num(&urb->pipe_info), + dwc2_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"); + + qh->dev_speed = dev_speed; + + switch (dev_speed) { + case USB_SPEED_LOW: + speed = "low"; + break; + case USB_SPEED_FULL: + speed = "full"; + break; + case USB_SPEED_HIGH: + speed = "high"; + break; + default: + speed = "?"; + break; + } + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Speed = %s\n", speed); + + switch (qh->ep_type) { + case USB_ENDPOINT_XFER_ISOC: + type = "isochronous"; + break; + case USB_ENDPOINT_XFER_INT: + type = "interrupt"; + break; + case USB_ENDPOINT_XFER_CONTROL: + type = "control"; + break; + case USB_ENDPOINT_XFER_BULK: + type = "bulk"; + break; + default: + type = "?"; + break; + } + + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - Type = %s\n", type); + + if (qh->ep_type == USB_ENDPOINT_XFER_INT) { + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - usecs = %d\n", + qh->usecs); + dev_vdbg(hsotg->dev, "DWC OTG HCD QH - interval = %d\n", + qh->interval); + } +} + +/** + * dwc2_hcd_qh_create() - Allocates and initializes a QH + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @urb: Holds the information about the device/endpoint needed + * to initialize the QH + * @atomic_alloc: Flag to do atomic allocation if needed + * + * Return: Pointer to the newly allocated QH, or NULL on error + */ +static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, + struct dwc2_hcd_urb *urb, + gfp_t mem_flags) +{ + struct dwc2_qh *qh; + + /* Allocate memory */ + qh = kzalloc(sizeof(*qh), mem_flags); + if (!qh) + return NULL; + + dwc2_qh_init(hsotg, qh, urb); + + if (hsotg->core_params->dma_desc_enable > 0 && + dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) { + dwc2_hcd_qh_free(hsotg, qh); + return NULL; + } + + return qh; +} + +/** + * dwc2_hcd_qh_free() - Frees the QH + * + * @hsotg: HCD instance + * @qh: The QH to free + * + * QH should already be removed from the list. QTD list should already be empty + * if called from URB Dequeue. + * + * Must NOT be called with interrupt disabled or spinlock held + */ +void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + u32 buf_size; + + if (hsotg->core_params->dma_desc_enable > 0) { + dwc2_hcd_qh_free_ddma(hsotg, qh); + } else if (qh->dw_align_buf) { + if (qh->ep_type == USB_ENDPOINT_XFER_ISOC) + buf_size = 4096; + else + buf_size = hsotg->core_params->max_transfer_size; + dma_free_coherent(hsotg->dev, buf_size, qh->dw_align_buf, + qh->dw_align_buf_dma); + } + + kfree(qh); +} + +/** + * dwc2_periodic_channel_available() - Checks that a channel is available for a + * periodic transfer + * + * @hsotg: The HCD state structure for the DWC OTG controller + * + * Return: 0 if successful, negative error code otherise + */ +static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg) +{ + /* + * Currently assuming that there is a dedicated host channnel for + * each periodic transaction plus at least one host channel for + * non-periodic transactions + */ + int status; + int num_channels; + + num_channels = hsotg->core_params->host_channels; + if (hsotg->periodic_channels + hsotg->non_periodic_channels < + num_channels + && hsotg->periodic_channels < num_channels - 1) { + status = 0; + } else { + dev_dbg(hsotg->dev, + "%s: Total channels: %d, Periodic: %d, " + "Non-periodic: %d\n", __func__, num_channels, + hsotg->periodic_channels, hsotg->non_periodic_channels); + status = -ENOSPC; + } + + return status; +} + +/** + * dwc2_check_periodic_bandwidth() - Checks that there is sufficient bandwidth + * for the specified QH in the periodic schedule + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: QH containing periodic bandwidth required + * + * Return: 0 if successful, negative error code otherwise + * + * For simplicity, this calculation assumes that all the transfers in the + * periodic schedule may occur in the same (micro)frame + */ +static int dwc2_check_periodic_bandwidth(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + int status; + s16 max_claimed_usecs; + + status = 0; + + if (qh->dev_speed == USB_SPEED_HIGH || qh->do_split) { + /* + * High speed mode + * Max periodic usecs is 80% x 125 usec = 100 usec + */ + max_claimed_usecs = 100 - qh->usecs; + } else { + /* + * Full speed mode + * Max periodic usecs is 90% x 1000 usec = 900 usec + */ + max_claimed_usecs = 900 - qh->usecs; + } + + if (hsotg->periodic_usecs > max_claimed_usecs) { + dev_err(hsotg->dev, + "%s: already claimed usecs %d, required usecs %d\n", + __func__, hsotg->periodic_usecs, qh->usecs); + status = -ENOSPC; + } + + return status; +} + +/** + * dwc2_check_max_xfer_size() - Checks that the max transfer size allowed in a + * host channel is large enough to handle the maximum data transfer in a single + * (micro)frame for a periodic transfer + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: QH for a periodic endpoint + * + * Return: 0 if successful, negative error code otherwise + */ +static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + u32 max_xfer_size; + u32 max_channel_xfer_size; + int status = 0; + + max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp); + max_channel_xfer_size = hsotg->core_params->max_transfer_size; + + if (max_xfer_size > max_channel_xfer_size) { + dev_err(hsotg->dev, + "%s: Periodic xfer length %d > max xfer length for channel %d\n", + __func__, max_xfer_size, max_channel_xfer_size); + status = -ENOSPC; + } + + return status; +} + +/** + * dwc2_schedule_periodic() - Schedules an interrupt or isochronous transfer in + * the periodic schedule + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: QH for the periodic transfer. The QH should already contain the + * scheduling information. + * + * Return: 0 if successful, negative error code otherwise + */ +static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + int status; + + status = dwc2_periodic_channel_available(hsotg); + if (status) { + dev_dbg(hsotg->dev, + "%s: No host channel available for periodic transfer\n", + __func__); + return status; + } + + status = dwc2_check_periodic_bandwidth(hsotg, qh); + if (status) { + dev_dbg(hsotg->dev, + "%s: Insufficient periodic bandwidth for periodic transfer\n", + __func__); + return status; + } + + status = dwc2_check_max_xfer_size(hsotg, qh); + if (status) { + dev_dbg(hsotg->dev, + "%s: Channel max transfer size too small for periodic transfer\n", + __func__); + return status; + } + + if (hsotg->core_params->dma_desc_enable > 0) + /* Don't rely on SOF and start in ready schedule */ + list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); + else + /* Always start in inactive schedule */ + list_add_tail(&qh->qh_list_entry, + &hsotg->periodic_sched_inactive); + + /* Reserve periodic channel */ + hsotg->periodic_channels++; + + /* Update claimed usecs per (micro)frame */ + hsotg->periodic_usecs += qh->usecs; + + return status; +} + +/** + * dwc2_deschedule_periodic() - Removes an interrupt or isochronous transfer + * from the periodic schedule + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: QH for the periodic transfer + */ +static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + list_del_init(&qh->qh_list_entry); + + /* Release periodic channel reservation */ + hsotg->periodic_channels--; + + /* Update claimed usecs per (micro)frame */ + hsotg->periodic_usecs -= qh->usecs; +} + +/** + * dwc2_hcd_qh_add() - Adds a QH to either the non periodic or periodic + * schedule if it is not already in the schedule. If the QH is already in + * the schedule, no action is taken. + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: The QH to add + * + * Return: 0 if successful, negative error code otherwise + */ +int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + int status = 0; + u32 intr_mask; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (!list_empty(&qh->qh_list_entry)) + /* QH already in a schedule */ + return status; + + /* Add the new QH to the appropriate schedule */ + if (dwc2_qh_is_non_per(qh)) { + /* Always start in inactive schedule */ + list_add_tail(&qh->qh_list_entry, + &hsotg->non_periodic_sched_inactive); + } else { + status = dwc2_schedule_periodic(hsotg, qh); + if (status == 0) { + if (!hsotg->periodic_qh_count) { + intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask |= GINTSTS_SOF; + writel(intr_mask, hsotg->regs + GINTMSK); + } + hsotg->periodic_qh_count++; + } + } + + return status; +} + +/** + * dwc2_hcd_qh_unlink() - Removes a QH from either the non-periodic or periodic + * schedule. Memory is not freed. + * + * @hsotg: The HCD state structure + * @qh: QH to remove from schedule + */ +void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + u32 intr_mask; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (list_empty(&qh->qh_list_entry)) + /* QH is not in a schedule */ + return; + + if (dwc2_qh_is_non_per(qh)) { + if (hsotg->non_periodic_qh_ptr == &qh->qh_list_entry) + hsotg->non_periodic_qh_ptr = + hsotg->non_periodic_qh_ptr->next; + list_del_init(&qh->qh_list_entry); + } else { + dwc2_deschedule_periodic(hsotg, qh); + hsotg->periodic_qh_count--; + if (!hsotg->periodic_qh_count) { + intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask &= ~GINTSTS_SOF; + writel(intr_mask, hsotg->regs + GINTMSK); + } + } +} + +/* + * Schedule the next continuing periodic split transfer + */ +static void dwc2_sched_periodic_split(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh, u16 frame_number, + int sched_next_periodic_split) +{ + u16 incr; + + if (sched_next_periodic_split) { + qh->sched_frame = frame_number; + incr = dwc2_frame_num_inc(qh->start_split_frame, 1); + if (dwc2_frame_num_le(frame_number, incr)) { + /* + * Allow one frame to elapse after start split + * microframe before scheduling complete split, but + * DON'T if we are doing the next start split in the + * same frame for an ISOC out + */ + if (qh->ep_type != USB_ENDPOINT_XFER_ISOC || + qh->ep_is_in != 0) { + qh->sched_frame = + dwc2_frame_num_inc(qh->sched_frame, 1); + } + } + } else { + qh->sched_frame = dwc2_frame_num_inc(qh->start_split_frame, + qh->interval); + if (dwc2_frame_num_le(qh->sched_frame, frame_number)) + qh->sched_frame = frame_number; + qh->sched_frame |= 0x7; + qh->start_split_frame = qh->sched_frame; + } +} + +/* + * Deactivates a QH. For non-periodic QHs, removes the QH from the active + * non-periodic schedule. The QH is added to the inactive non-periodic + * schedule if any QTDs are still attached to the QH. + * + * For periodic QHs, the QH is removed from the periodic queued schedule. If + * there are any QTDs still attached to the QH, the QH is added to either the + * periodic inactive schedule or the periodic ready schedule and its next + * scheduled frame is calculated. The QH is placed in the ready schedule if + * the scheduled frame has been reached already. Otherwise it's placed in the + * inactive schedule. If there are no QTDs attached to the QH, the QH is + * completely removed from the periodic schedule. + */ +void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + int sched_next_periodic_split) +{ + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + if (dwc2_qh_is_non_per(qh)) { + dwc2_hcd_qh_unlink(hsotg, qh); + if (!list_empty(&qh->qtd_list)) + /* Add back to inactive non-periodic schedule */ + dwc2_hcd_qh_add(hsotg, qh); + } else { + u16 frame_number = dwc2_hcd_get_frame_number(hsotg); + + if (qh->do_split) { + dwc2_sched_periodic_split(hsotg, qh, frame_number, + sched_next_periodic_split); + } else { + qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame, + qh->interval); + if (dwc2_frame_num_le(qh->sched_frame, frame_number)) + qh->sched_frame = frame_number; + } + + if (list_empty(&qh->qtd_list)) { + dwc2_hcd_qh_unlink(hsotg, qh); + } else { + /* + * Remove from periodic_sched_queued and move to + * appropriate queue + */ + if (qh->sched_frame == frame_number) + list_move(&qh->qh_list_entry, + &hsotg->periodic_sched_ready); + else + list_move(&qh->qh_list_entry, + &hsotg->periodic_sched_inactive); + } + } +} + +/** + * dwc2_hcd_qtd_init() - Initializes a QTD structure + * + * @qtd: The QTD to initialize + * @urb: The associated URB + */ +void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) +{ + qtd->urb = urb; + if (dwc2_hcd_get_pipe_type(&urb->pipe_info) == + USB_ENDPOINT_XFER_CONTROL) { + /* + * The only time the QTD data toggle is used is on the data + * phase of control transfers. This phase always starts with + * DATA1. + */ + qtd->data_toggle = DWC2_HC_PID_DATA1; + qtd->control_phase = DWC2_CONTROL_SETUP; + } + + /* Start split */ + qtd->complete_split = 0; + qtd->isoc_split_pos = DWC2_HCSPLT_XACTPOS_ALL; + qtd->isoc_split_offset = 0; + qtd->in_process = 0; + + /* Store the qtd ptr in the urb to reference the QTD */ + urb->qtd = qtd; +} + +/** + * dwc2_hcd_qtd_add() - Adds a QTD to the QTD-list of a QH + * + * @hsotg: The DWC HCD structure + * @qtd: The QTD to add + * @qh: Out parameter to return queue head + * @atomic_alloc: Flag to do atomic alloc if needed + * + * Return: 0 if successful, negative error code otherwise + * + * Finds the correct QH to place the QTD into. If it does not find a QH, it + * will create a new QH. If the QH to which the QTD is added is not currently + * scheduled, it is placed into the proper schedule based on its EP type. + */ +int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, + struct dwc2_qh **qh, gfp_t mem_flags) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + unsigned long flags; + int allocated = 0; + int retval = 0; + + /* + * Get the QH which holds the QTD-list to insert to. Create QH if it + * doesn't exist. + */ + if (*qh == NULL) { + *qh = dwc2_hcd_qh_create(hsotg, urb, mem_flags); + if (*qh == NULL) + return -ENOMEM; + allocated = 1; + } + + spin_lock_irqsave(&hsotg->lock, flags); + retval = dwc2_hcd_qh_add(hsotg, *qh); + if (retval && allocated) { + struct dwc2_qtd *qtd2, *qtd2_tmp; + struct dwc2_qh *qh_tmp = *qh; + + *qh = NULL; + dwc2_hcd_qh_unlink(hsotg, qh_tmp); + + /* Free each QTD in the QH's QTD list */ + list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list, + qtd_list_entry) + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); + + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_hcd_qh_free(hsotg, qh_tmp); + } else { + qtd->qh = *qh; + list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); + spin_unlock_irqrestore(&hsotg->lock, flags); + } + + return retval; +} -- cgit From dc4c76e7b22cdcc1ba71ff87edee55f464e01658 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 11 Mar 2013 17:48:00 -0700 Subject: staging: HCD descriptor DMA support for the DWC2 driver This file contains code to support the HCD descriptor DMA mode of the controller Signed-off-by: Paul Zimmerman Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/hcd_ddma.c | 1196 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1196 insertions(+) create mode 100644 drivers/staging/dwc2/hcd_ddma.c (limited to 'drivers') diff --git a/drivers/staging/dwc2/hcd_ddma.c b/drivers/staging/dwc2/hcd_ddma.c new file mode 100644 index 000000000000..ab88f5069183 --- /dev/null +++ b/drivers/staging/dwc2/hcd_ddma.c @@ -0,0 +1,1196 @@ +/* + * hcd_ddma.c - DesignWare HS OTG Controller descriptor DMA routines + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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 file contains the Descriptor DMA implementation for Host mode + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +static u16 dwc2_frame_list_idx(u16 frame) +{ + return frame & (FRLISTEN_64_SIZE - 1); +} + +static u16 dwc2_desclist_idx_inc(u16 idx, u16 inc, u8 speed) +{ + return (idx + inc) & + ((speed == USB_SPEED_HIGH ? MAX_DMA_DESC_NUM_HS_ISOC : + MAX_DMA_DESC_NUM_GENERIC) - 1); +} + +static u16 dwc2_desclist_idx_dec(u16 idx, u16 inc, u8 speed) +{ + return (idx - inc) & + ((speed == USB_SPEED_HIGH ? MAX_DMA_DESC_NUM_HS_ISOC : + MAX_DMA_DESC_NUM_GENERIC) - 1); +} + +static u16 dwc2_max_desc_num(struct dwc2_qh *qh) +{ + return (qh->ep_type == USB_ENDPOINT_XFER_ISOC && + qh->dev_speed == USB_SPEED_HIGH) ? + MAX_DMA_DESC_NUM_HS_ISOC : MAX_DMA_DESC_NUM_GENERIC; +} + +static u16 dwc2_frame_incr_val(struct dwc2_qh *qh) +{ + return qh->dev_speed == USB_SPEED_HIGH ? + (qh->interval + 8 - 1) / 8 : qh->interval; +} + +static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + gfp_t flags) +{ + qh->desc_list = dma_alloc_coherent(hsotg->dev, + sizeof(struct dwc2_hcd_dma_desc) * + dwc2_max_desc_num(qh), &qh->desc_list_dma, + flags); + + if (!qh->desc_list) + return -ENOMEM; + + memset(qh->desc_list, 0, + sizeof(struct dwc2_hcd_dma_desc) * dwc2_max_desc_num(qh)); + + qh->n_bytes = kzalloc(sizeof(u32) * dwc2_max_desc_num(qh), flags); + if (!qh->n_bytes) { + dma_free_coherent(hsotg->dev, sizeof(struct dwc2_hcd_dma_desc) + * dwc2_max_desc_num(qh), qh->desc_list, + qh->desc_list_dma); + qh->desc_list = NULL; + return -ENOMEM; + } + + return 0; +} + +static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + if (qh->desc_list) { + dma_free_coherent(hsotg->dev, sizeof(struct dwc2_hcd_dma_desc) + * dwc2_max_desc_num(qh), qh->desc_list, + qh->desc_list_dma); + qh->desc_list = NULL; + } + + kfree(qh->n_bytes); + qh->n_bytes = NULL; +} + +static int dwc2_frame_list_alloc(struct dwc2_hsotg *hsotg, gfp_t mem_flags) +{ + if (hsotg->frame_list) + return 0; + + hsotg->frame_list = dma_alloc_coherent(hsotg->dev, + 4 * FRLISTEN_64_SIZE, + &hsotg->frame_list_dma, + mem_flags); + if (!hsotg->frame_list) + return -ENOMEM; + + memset(hsotg->frame_list, 0, 4 * FRLISTEN_64_SIZE); + return 0; +} + +static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg) +{ + u32 *frame_list; + dma_addr_t frame_list_dma; + unsigned long flags; + + spin_lock_irqsave(&hsotg->lock, flags); + + if (!hsotg->frame_list) { + spin_unlock_irqrestore(&hsotg->lock, flags); + return; + } + + frame_list = hsotg->frame_list; + frame_list_dma = hsotg->frame_list_dma; + hsotg->frame_list = NULL; + + spin_unlock_irqrestore(&hsotg->lock, flags); + + dma_free_coherent(hsotg->dev, 4 * FRLISTEN_64_SIZE, frame_list, + frame_list_dma); +} + +static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en) +{ + u32 hcfg; + unsigned long flags; + + spin_lock_irqsave(&hsotg->lock, flags); + + hcfg = readl(hsotg->regs + HCFG); + if (hcfg & HCFG_PERSCHEDENA) { + /* already enabled */ + spin_unlock_irqrestore(&hsotg->lock, flags); + return; + } + + writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR); + + hcfg &= ~HCFG_FRLISTEN_MASK; + hcfg |= fr_list_en | HCFG_PERSCHEDENA; + dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n"); + writel(hcfg, hsotg->regs + HCFG); + + spin_unlock_irqrestore(&hsotg->lock, flags); +} + +static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg) +{ + u32 hcfg; + unsigned long flags; + + spin_lock_irqsave(&hsotg->lock, flags); + + hcfg = readl(hsotg->regs + HCFG); + if (!(hcfg & HCFG_PERSCHEDENA)) { + /* already disabled */ + spin_unlock_irqrestore(&hsotg->lock, flags); + return; + } + + hcfg &= ~HCFG_PERSCHEDENA; + dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n"); + writel(hcfg, hsotg->regs + HCFG); + + spin_unlock_irqrestore(&hsotg->lock, flags); +} + +/* + * Activates/Deactivates FrameList entries for the channel based on endpoint + * servicing period + */ +static void dwc2_update_frame_list(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + int enable) +{ + struct dwc2_host_chan *chan; + u16 i, j, inc; + + if (!qh->channel) { + dev_err(hsotg->dev, "qh->channel = %p", qh->channel); + return; + } + + if (!hsotg) { + dev_err(hsotg->dev, "------hsotg = %p", hsotg); + return; + } + + if (!hsotg->frame_list) { + dev_err(hsotg->dev, "-------hsotg->frame_list = %p", + hsotg->frame_list); + return; + } + + chan = qh->channel; + inc = dwc2_frame_incr_val(qh); + if (qh->ep_type == USB_ENDPOINT_XFER_ISOC) + i = dwc2_frame_list_idx(qh->sched_frame); + else + i = 0; + + j = i; + do { + if (enable) + hsotg->frame_list[j] |= 1 << chan->hc_num; + else + hsotg->frame_list[j] &= ~(1 << chan->hc_num); + j = (j + inc) & (FRLISTEN_64_SIZE - 1); + } while (j != i); + + if (!enable) + return; + + chan->schinfo = 0; + if (chan->speed == USB_SPEED_HIGH && qh->interval) { + j = 1; + /* TODO - check this */ + inc = (8 + qh->interval - 1) / qh->interval; + for (i = 0; i < inc; i++) { + chan->schinfo |= j; + j = j << qh->interval; + } + } else { + chan->schinfo = 0xff; + } +} + +static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + struct dwc2_host_chan *chan = qh->channel; + + if (dwc2_qh_is_non_per(qh)) + hsotg->non_periodic_channels--; + else + dwc2_update_frame_list(hsotg, qh, 0); + + /* + * The condition is added to prevent double cleanup try in case of + * device disconnect. See channel cleanup in dwc2_hcd_disconnect(). + */ + if (chan->qh) { + if (!list_empty(&chan->hc_list_entry)) + list_del(&chan->hc_list_entry); + dwc2_hc_cleanup(hsotg, chan); + list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + chan->qh = NULL; + } + + qh->channel = NULL; + qh->ntd = 0; + + if (qh->desc_list) + memset(qh->desc_list, 0, sizeof(struct dwc2_hcd_dma_desc) * + dwc2_max_desc_num(qh)); +} + +/** + * dwc2_hcd_qh_init_ddma() - Initializes a QH structure's Descriptor DMA + * related members + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: The QH to init + * + * Return: 0 if successful, negative error code otherwise + * + * Allocates memory for the descriptor list. For the first periodic QH, + * allocates memory for the FrameList and enables periodic scheduling. + */ +int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, + gfp_t mem_flags) +{ + int retval; + + if (qh->do_split) { + dev_err(hsotg->dev, + "SPLIT Transfers are not supported in Descriptor DMA mode.\n"); + retval = -EINVAL; + goto err0; + } + + retval = dwc2_desc_list_alloc(hsotg, qh, mem_flags); + if (retval) + goto err0; + + if (qh->ep_type == USB_ENDPOINT_XFER_ISOC || + qh->ep_type == USB_ENDPOINT_XFER_INT) { + if (!hsotg->frame_list) { + retval = dwc2_frame_list_alloc(hsotg, mem_flags); + if (retval) + goto err1; + /* Enable periodic schedule on first periodic QH */ + dwc2_per_sched_enable(hsotg, HCFG_FRLISTEN_64); + } + } + + qh->ntd = 0; + return 0; + +err1: + dwc2_desc_list_free(hsotg, qh); +err0: + return retval; +} + +/** + * dwc2_hcd_qh_free_ddma() - Frees a QH structure's Descriptor DMA related + * members + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: The QH to free + * + * Frees descriptor list memory associated with the QH. If QH is periodic and + * the last, frees FrameList memory and disables periodic scheduling. + */ +void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + dwc2_desc_list_free(hsotg, qh); + + /* + * Channel still assigned due to some reasons. + * Seen on Isoc URB dequeue. Channel halted but no subsequent + * ChHalted interrupt to release the channel. Afterwards + * when it comes here from endpoint disable routine + * channel remains assigned. + */ + if (qh->channel) + dwc2_release_channel_ddma(hsotg, qh); + + if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC || + qh->ep_type == USB_ENDPOINT_XFER_INT) && + !hsotg->periodic_channels && hsotg->frame_list) { + dwc2_per_sched_disable(hsotg); + dwc2_frame_list_free(hsotg); + } +} + +static u8 dwc2_frame_to_desc_idx(struct dwc2_qh *qh, u16 frame_idx) +{ + if (qh->dev_speed == USB_SPEED_HIGH) + /* Descriptor set (8 descriptors) index which is 8-aligned */ + return (frame_idx & ((MAX_DMA_DESC_NUM_HS_ISOC / 8) - 1)) * 8; + else + return frame_idx & (MAX_DMA_DESC_NUM_GENERIC - 1); +} + +/* + * Determine starting frame for Isochronous transfer. + * Few frames skipped to prevent race condition with HC. + */ +static u16 dwc2_calc_starting_frame(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh, u16 *skip_frames) +{ + u16 frame; + + hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); + + /* sched_frame is always frame number (not uFrame) both in FS and HS! */ + + /* + * skip_frames is used to limit activated descriptors number + * to avoid the situation when HC services the last activated + * descriptor firstly. + * Example for FS: + * Current frame is 1, scheduled frame is 3. Since HC always fetches + * the descriptor corresponding to curr_frame+1, the descriptor + * corresponding to frame 2 will be fetched. If the number of + * descriptors is max=64 (or greather) the list will be fully programmed + * with Active descriptors and it is possible case (rare) that the + * latest descriptor(considering rollback) corresponding to frame 2 will + * be serviced first. HS case is more probable because, in fact, up to + * 11 uframes (16 in the code) may be skipped. + */ + if (qh->dev_speed == USB_SPEED_HIGH) { + /* + * Consider uframe counter also, to start xfer asap. If half of + * the frame elapsed skip 2 frames otherwise just 1 frame. + * Starting descriptor index must be 8-aligned, so if the + * current frame is near to complete the next one is skipped as + * well. + */ + if (dwc2_micro_frame_num(hsotg->frame_number) >= 5) { + *skip_frames = 2 * 8; + frame = dwc2_frame_num_inc(hsotg->frame_number, + *skip_frames); + } else { + *skip_frames = 1 * 8; + frame = dwc2_frame_num_inc(hsotg->frame_number, + *skip_frames); + } + + frame = dwc2_full_frame_num(frame); + } else { + /* + * Two frames are skipped for FS - the current and the next. + * But for descriptor programming, 1 frame (descriptor) is + * enough, see example above. + */ + *skip_frames = 1; + frame = dwc2_frame_num_inc(hsotg->frame_number, 2); + } + + return frame; +} + +/* + * Calculate initial descriptor index for isochronous transfer based on + * scheduled frame + */ +static u16 dwc2_recalc_initial_desc_idx(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + u16 frame, fr_idx, fr_idx_tmp, skip_frames; + + /* + * With current ISOC processing algorithm the channel is being released + * when no more QTDs in the list (qh->ntd == 0). Thus this function is + * called only when qh->ntd == 0 and qh->channel == 0. + * + * So qh->channel != NULL branch is not used and just not removed from + * the source file. It is required for another possible approach which + * is, do not disable and release the channel when ISOC session + * completed, just move QH to inactive schedule until new QTD arrives. + * On new QTD, the QH moved back to 'ready' schedule, starting frame and + * therefore starting desc_index are recalculated. In this case channel + * is released only on ep_disable. + */ + + /* + * Calculate starting descriptor index. For INTERRUPT endpoint it is + * always 0. + */ + if (qh->channel) { + frame = dwc2_calc_starting_frame(hsotg, qh, &skip_frames); + /* + * Calculate initial descriptor index based on FrameList current + * bitmap and servicing period + */ + fr_idx_tmp = dwc2_frame_list_idx(frame); + fr_idx = (FRLISTEN_64_SIZE + + dwc2_frame_list_idx(qh->sched_frame) - fr_idx_tmp) + % dwc2_frame_incr_val(qh); + fr_idx = (fr_idx + fr_idx_tmp) % FRLISTEN_64_SIZE; + } else { + qh->sched_frame = dwc2_calc_starting_frame(hsotg, qh, + &skip_frames); + fr_idx = dwc2_frame_list_idx(qh->sched_frame); + } + + qh->td_first = qh->td_last = dwc2_frame_to_desc_idx(qh, fr_idx); + + return skip_frames; +} + +#define ISOC_URB_GIVEBACK_ASAP + +#define MAX_ISOC_XFER_SIZE_FS 1023 +#define MAX_ISOC_XFER_SIZE_HS 3072 +#define DESCNUM_THRESHOLD 4 + +static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, + struct dwc2_qtd *qtd, + struct dwc2_qh *qh, u32 max_xfer_size, + u16 idx) +{ + struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[idx]; + struct dwc2_hcd_iso_packet_desc *frame_desc; + + memset(dma_desc, 0, sizeof(*dma_desc)); + frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; + + if (frame_desc->length > max_xfer_size) + qh->n_bytes[idx] = max_xfer_size; + else + qh->n_bytes[idx] = frame_desc->length; + + dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); + dma_desc->status = qh->n_bytes[idx] << HOST_DMA_ISOC_NBYTES_SHIFT & + HOST_DMA_ISOC_NBYTES_MASK; + +#ifdef ISOC_URB_GIVEBACK_ASAP + /* Set IOC for each descriptor corresponding to last frame of URB */ + if (qtd->isoc_frame_index_last == qtd->urb->packet_count) + dma_desc->status |= HOST_DMA_IOC; +#endif + + qh->ntd++; + qtd->isoc_frame_index_last++; +} + +static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh, u16 skip_frames) +{ + struct dwc2_qtd *qtd; + u32 max_xfer_size; + u16 idx, inc, n_desc, ntd_max = 0; + + idx = qh->td_last; + inc = qh->interval; + n_desc = 0; + + if (qh->interval) { + ntd_max = (dwc2_max_desc_num(qh) + qh->interval - 1) / + qh->interval; + if (skip_frames && !qh->channel) + ntd_max -= skip_frames / qh->interval; + } + + max_xfer_size = qh->dev_speed == USB_SPEED_HIGH ? + MAX_ISOC_XFER_SIZE_HS : MAX_ISOC_XFER_SIZE_FS; + + list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { + while (qh->ntd < ntd_max && qtd->isoc_frame_index_last < + qtd->urb->packet_count) { + if (n_desc > 1) + qh->desc_list[n_desc - 1].status |= HOST_DMA_A; + dwc2_fill_host_isoc_dma_desc(hsotg, qtd, qh, + max_xfer_size, idx); + idx = dwc2_desclist_idx_inc(idx, inc, qh->dev_speed); + n_desc++; + } + qtd->in_process = 1; + } + + qh->td_last = idx; + +#ifdef ISOC_URB_GIVEBACK_ASAP + /* Set IOC for last descriptor if descriptor list is full */ + if (qh->ntd == ntd_max) { + idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); + qh->desc_list[idx].status |= HOST_DMA_IOC; + } +#else + /* + * Set IOC bit only for one descriptor. Always try to be ahead of HW + * processing, i.e. on IOC generation driver activates next descriptor + * but core continues to process descriptors following the one with IOC + * set. + */ + + if (n_desc > DESCNUM_THRESHOLD) + /* + * Move IOC "up". Required even if there is only one QTD + * in the list, because QTDs might continue to be queued, + * but during the activation it was only one queued. + * Actually more than one QTD might be in the list if this + * function called from XferCompletion - QTDs was queued during + * HW processing of the previous descriptor chunk. + */ + idx = dwc2_desclist_idx_dec(idx, inc * ((qh->ntd + 1) / 2), + qh->dev_speed); + else + /* + * Set the IOC for the latest descriptor if either number of + * descriptors is not greater than threshold or no more new + * descriptors activated + */ + idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); + + qh->desc_list[idx].status |= HOST_DMA_IOC; +#endif + + if (n_desc) { + qh->desc_list[n_desc - 1].status |= HOST_DMA_A; + if (n_desc > 1) + qh->desc_list[0].status |= HOST_DMA_A; + } +} + +static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, struct dwc2_qh *qh, + int n_desc) +{ + struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[n_desc]; + int len = chan->xfer_len; + + if (len > MAX_DMA_DESC_SIZE) + len = MAX_DMA_DESC_SIZE - chan->max_packet + 1; + + if (chan->ep_is_in) { + int num_packets; + + if (len > 0 && chan->max_packet) + num_packets = (len + chan->max_packet - 1) + / chan->max_packet; + else + /* Need 1 packet for transfer length of 0 */ + num_packets = 1; + + /* Always program an integral # of packets for IN transfers */ + len = num_packets * chan->max_packet; + } + + dma_desc->status = len << HOST_DMA_NBYTES_SHIFT & HOST_DMA_NBYTES_MASK; + qh->n_bytes[n_desc] = len; + + if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL && + qtd->control_phase == DWC2_CONTROL_SETUP) + dma_desc->status |= HOST_DMA_SUP; + + dma_desc->buf = (u32)chan->xfer_dma; + + /* + * Last (or only) descriptor of IN transfer with actual size less + * than MaxPacket + */ + if (len > chan->xfer_len) { + chan->xfer_len = 0; + } else { + chan->xfer_dma += len; + chan->xfer_len -= len; + } +} + +static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg, + struct dwc2_qh *qh) +{ + struct dwc2_qtd *qtd; + struct dwc2_host_chan *chan = qh->channel; + int n_desc = 0; + + dev_vdbg(hsotg->dev, "%s(): qh=%p dma=%08lx len=%d\n", __func__, qh, + (unsigned long)chan->xfer_dma, chan->xfer_len); + + /* + * Start with chan->xfer_dma initialized in assign_and_init_hc(), then + * if SG transfer consists of multiple URBs, this pointer is re-assigned + * to the buffer of the currently processed QTD. For non-SG request + * there is always one QTD active. + */ + + list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { + dev_vdbg(hsotg->dev, "qtd=%p\n", qtd); + + if (n_desc) { + /* SG request - more than 1 QTD */ + chan->xfer_dma = qtd->urb->dma + + qtd->urb->actual_length; + chan->xfer_len = qtd->urb->length - + qtd->urb->actual_length; + dev_vdbg(hsotg->dev, "buf=%08lx len=%d\n", + (unsigned long)chan->xfer_dma, chan->xfer_len); + } + + qtd->n_desc = 0; + do { + if (n_desc > 1) { + qh->desc_list[n_desc - 1].status |= HOST_DMA_A; + dev_vdbg(hsotg->dev, + "set A bit in desc %d (%p)\n", + n_desc - 1, + &qh->desc_list[n_desc - 1]); + } + dwc2_fill_host_dma_desc(hsotg, chan, qtd, qh, n_desc); + dev_vdbg(hsotg->dev, + "desc %d (%p) buf=%08x status=%08x\n", + n_desc, &qh->desc_list[n_desc], + qh->desc_list[n_desc].buf, + qh->desc_list[n_desc].status); + qtd->n_desc++; + n_desc++; + } while (chan->xfer_len > 0 && + n_desc != MAX_DMA_DESC_NUM_GENERIC); + + dev_vdbg(hsotg->dev, "n_desc=%d\n", n_desc); + qtd->in_process = 1; + if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL) + break; + if (n_desc == MAX_DMA_DESC_NUM_GENERIC) + break; + } + + if (n_desc) { + qh->desc_list[n_desc - 1].status |= + HOST_DMA_IOC | HOST_DMA_EOL | HOST_DMA_A; + dev_vdbg(hsotg->dev, "set IOC/EOL/A bits in desc %d (%p)\n", + n_desc - 1, &qh->desc_list[n_desc - 1]); + if (n_desc > 1) { + qh->desc_list[0].status |= HOST_DMA_A; + dev_vdbg(hsotg->dev, "set A bit in desc 0 (%p)\n", + &qh->desc_list[0]); + } + chan->ntd = n_desc; + } +} + +/** + * dwc2_hcd_start_xfer_ddma() - Starts a transfer in Descriptor DMA mode + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @qh: The QH to init + * + * Return: 0 if successful, negative error code otherwise + * + * For Control and Bulk endpoints, initializes descriptor list and starts the + * transfer. For Interrupt and Isochronous endpoints, initializes descriptor + * list then updates FrameList, marking appropriate entries as active. + * + * For Isochronous endpoints the starting descriptor index is calculated based + * on the scheduled frame, but only on the first transfer descriptor within a + * session. Then the transfer is started via enabling the channel. + * + * For Isochronous endpoints the channel is not halted on XferComplete + * interrupt so remains assigned to the endpoint(QH) until session is done. + */ +void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) +{ + /* Channel is already assigned */ + struct dwc2_host_chan *chan = qh->channel; + u16 skip_frames = 0; + + switch (chan->ep_type) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + dwc2_init_non_isoc_dma_desc(hsotg, qh); + dwc2_hc_start_transfer_ddma(hsotg, chan); + break; + case USB_ENDPOINT_XFER_INT: + dwc2_init_non_isoc_dma_desc(hsotg, qh); + dwc2_update_frame_list(hsotg, qh, 1); + dwc2_hc_start_transfer_ddma(hsotg, chan); + break; + case USB_ENDPOINT_XFER_ISOC: + if (!qh->ntd) + skip_frames = dwc2_recalc_initial_desc_idx(hsotg, qh); + dwc2_init_isoc_dma_desc(hsotg, qh, skip_frames); + + if (!chan->xfer_started) { + dwc2_update_frame_list(hsotg, qh, 1); + + /* + * Always set to max, instead of actual size. Otherwise + * ntd will be changed with channel being enabled. Not + * recommended. + */ + chan->ntd = dwc2_max_desc_num(qh); + + /* Enable channel only once for ISOC */ + dwc2_hc_start_transfer_ddma(hsotg, chan); + } + + break; + default: + break; + } +} + +#define DWC2_CMPL_DONE 1 +#define DWC2_CMPL_STOP 2 + +static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, + struct dwc2_qh *qh, u16 idx) +{ + struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[idx]; + struct dwc2_hcd_iso_packet_desc *frame_desc; + u16 remain = 0; + int rc = 0; + + frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; + dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); + if (chan->ep_is_in) + remain = dma_desc->status >> HOST_DMA_ISOC_NBYTES_SHIFT & + HOST_DMA_ISOC_NBYTES_MASK >> HOST_DMA_ISOC_NBYTES_SHIFT; + + if ((dma_desc->status & HOST_DMA_STS_MASK) == HOST_DMA_STS_PKTERR) { + /* + * XactError, or unable to complete all the transactions + * in the scheduled micro-frame/frame, both indicated by + * HOST_DMA_STS_PKTERR + */ + qtd->urb->error_count++; + frame_desc->actual_length = qh->n_bytes[idx] - remain; + frame_desc->status = -EPROTO; + } else { + /* Success */ + frame_desc->actual_length = qh->n_bytes[idx] - remain; + frame_desc->status = 0; + } + + if (++qtd->isoc_frame_index == qtd->urb->packet_count) { + /* + * urb->status is not used for isoc transfers here. The + * individual frame_desc status are used instead. + */ + dwc2_host_complete(hsotg, qtd->urb->priv, qtd->urb, 0); + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + + /* + * This check is necessary because urb_dequeue can be called + * from urb complete callback (sound driver for example). All + * pending URBs are dequeued there, so no need for further + * processing. + */ + if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) + return -1; + rc = DWC2_CMPL_DONE; + } + + qh->ntd--; + + /* Stop if IOC requested descriptor reached */ + if (dma_desc->status & HOST_DMA_IOC) + rc = DWC2_CMPL_STOP; + + return rc; +} + +static void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + enum dwc2_halt_status halt_status) +{ + struct dwc2_hcd_iso_packet_desc *frame_desc; + struct dwc2_qtd *qtd, *qtd_tmp; + struct dwc2_qh *qh; + u16 idx; + int rc; + + qh = chan->qh; + idx = qh->td_first; + + if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { + list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) + qtd->in_process = 0; + return; + } + + if (halt_status == DWC2_HC_XFER_AHB_ERR || + halt_status == DWC2_HC_XFER_BABBLE_ERR) { + /* + * Channel is halted in these error cases, considered as serious + * issues. + * Complete all URBs marking all frames as failed, irrespective + * whether some of the descriptors (frames) succeeded or not. + * Pass error code to completion routine as well, to update + * urb->status, some of class drivers might use it to stop + * queing transfer requests. + */ + int err = halt_status == DWC2_HC_XFER_AHB_ERR ? + -EIO : -EOVERFLOW; + + list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, + qtd_list_entry) { + for (idx = 0; idx < qtd->urb->packet_count; idx++) { + frame_desc = &qtd->urb->iso_descs[idx]; + frame_desc->status = err; + } + + dwc2_host_complete(hsotg, qtd->urb->priv, qtd->urb, + err); + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + } + + return; + } + + list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { + if (!qtd->in_process) + break; + do { + rc = dwc2_cmpl_host_isoc_dma_desc(hsotg, chan, qtd, qh, + idx); + if (rc < 0) + return; + idx = dwc2_desclist_idx_inc(idx, qh->interval, + chan->speed); + if (rc == DWC2_CMPL_STOP) + goto stop_scan; + if (rc == DWC2_CMPL_DONE) + break; + } while (idx != qh->td_first); + } + +stop_scan: + qh->td_first = idx; +} + +static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + struct dwc2_qtd *qtd, + struct dwc2_hcd_dma_desc *dma_desc, + enum dwc2_halt_status halt_status, + u32 n_bytes, int *xfer_done) +{ + struct dwc2_hcd_urb *urb = qtd->urb; + u16 remain = 0; + + if (chan->ep_is_in) + remain = dma_desc->status >> HOST_DMA_NBYTES_SHIFT & + HOST_DMA_NBYTES_MASK >> HOST_DMA_NBYTES_SHIFT; + + dev_vdbg(hsotg->dev, "remain=%d dwc2_urb=%p\n", remain, urb); + + if (halt_status == DWC2_HC_XFER_AHB_ERR) { + dev_err(hsotg->dev, "EIO\n"); + urb->status = -EIO; + return 1; + } + + if ((dma_desc->status & HOST_DMA_STS_MASK) == HOST_DMA_STS_PKTERR) { + switch (halt_status) { + case DWC2_HC_XFER_STALL: + dev_vdbg(hsotg->dev, "Stall\n"); + urb->status = -EPIPE; + break; + case DWC2_HC_XFER_BABBLE_ERR: + dev_err(hsotg->dev, "Babble\n"); + urb->status = -EOVERFLOW; + break; + case DWC2_HC_XFER_XACT_ERR: + dev_err(hsotg->dev, "XactErr\n"); + urb->status = -EPROTO; + break; + default: + dev_err(hsotg->dev, + "%s: Unhandled descriptor error status (%d)\n", + __func__, halt_status); + break; + } + return 1; + } + + if (dma_desc->status & HOST_DMA_A) { + dev_vdbg(hsotg->dev, + "Active descriptor encountered on channel %d\n", + chan->hc_num); + return 0; + } + + if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL) { + if (qtd->control_phase == DWC2_CONTROL_DATA) { + urb->actual_length += n_bytes - remain; + if (remain || urb->actual_length >= urb->length) { + /* + * For Control Data stage do not set urb->status + * to 0, to prevent URB callback. Set it when + * Status phase is done. See below. + */ + *xfer_done = 1; + } + } else if (qtd->control_phase == DWC2_CONTROL_STATUS) { + urb->status = 0; + *xfer_done = 1; + } + /* No handling for SETUP stage */ + } else { + /* BULK and INTR */ + urb->actual_length += n_bytes - remain; + dev_vdbg(hsotg->dev, "length=%d actual=%d\n", urb->length, + urb->actual_length); + if (remain || urb->actual_length >= urb->length) { + urb->status = 0; + *xfer_done = 1; + } + } + + return 0; +} + +static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + int chnum, struct dwc2_qtd *qtd, + int desc_num, + enum dwc2_halt_status halt_status, + int *xfer_done) +{ + struct dwc2_qh *qh = chan->qh; + struct dwc2_hcd_urb *urb = qtd->urb; + struct dwc2_hcd_dma_desc *dma_desc; + u32 n_bytes; + int failed; + + dev_vdbg(hsotg->dev, "%s()\n", __func__); + + dma_desc = &qh->desc_list[desc_num]; + n_bytes = qh->n_bytes[desc_num]; + dev_vdbg(hsotg->dev, + "qtd=%p dwc2_urb=%p desc_num=%d desc=%p n_bytes=%d\n", + qtd, urb, desc_num, dma_desc, n_bytes); + failed = dwc2_update_non_isoc_urb_state_ddma(hsotg, chan, qtd, dma_desc, + halt_status, n_bytes, + xfer_done); + if (failed || (*xfer_done && urb->status != -EINPROGRESS)) { + dwc2_host_complete(hsotg, urb->priv, urb, urb->status); + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x status=%08x\n", + failed, *xfer_done, urb->status); + return failed; + } + + if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL) { + switch (qtd->control_phase) { + case DWC2_CONTROL_SETUP: + if (urb->length > 0) + qtd->control_phase = DWC2_CONTROL_DATA; + else + qtd->control_phase = DWC2_CONTROL_STATUS; + dev_vdbg(hsotg->dev, + " Control setup transaction done\n"); + break; + case DWC2_CONTROL_DATA: + if (*xfer_done) { + qtd->control_phase = DWC2_CONTROL_STATUS; + dev_vdbg(hsotg->dev, + " Control data transfer done\n"); + } else if (desc_num + 1 == qtd->n_desc) { + /* + * Last descriptor for Control data stage which + * is not completed yet + */ + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, + qtd); + } + break; + default: + break; + } + } + + return 0; +} + +static void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, + int chnum, + enum dwc2_halt_status halt_status) +{ + struct list_head *qtd_item, *qtd_tmp; + struct dwc2_qh *qh = chan->qh; + struct dwc2_qtd *qtd = NULL; + int xfer_done; + int desc_num = 0; + + if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { + list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) + qtd->in_process = 0; + return; + } + + list_for_each_safe(qtd_item, qtd_tmp, &qh->qtd_list) { + int i; + + qtd = list_entry(qtd_item, struct dwc2_qtd, qtd_list_entry); + xfer_done = 0; + + for (i = 0; i < qtd->n_desc; i++) { + if (dwc2_process_non_isoc_desc(hsotg, chan, chnum, qtd, + desc_num, halt_status, + &xfer_done)) + break; + desc_num++; + } + } + + if (qh->ep_type != USB_ENDPOINT_XFER_CONTROL) { + /* + * Resetting the data toggle for bulk and interrupt endpoints + * in case of stall. See handle_hc_stall_intr(). + */ + if (halt_status == DWC2_HC_XFER_STALL) + qh->data_toggle = DWC2_HC_PID_DATA0; + else if (qtd) + dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd); + } + + if (halt_status == DWC2_HC_XFER_COMPLETE) { + if (chan->hcint & HCINTMSK_NYET) { + /* + * Got a NYET on the last transaction of the transfer. + * It means that the endpoint should be in the PING + * state at the beginning of the next transfer. + */ + qh->ping_state = 1; + } + } +} + +/** + * dwc2_hcd_complete_xfer_ddma() - Scans the descriptor list, updates URB's + * status and calls completion routine for the URB if it's done. Called from + * interrupt handlers. + * + * @hsotg: The HCD state structure for the DWC OTG controller + * @chan: Host channel the transfer is completed on + * @chnum: Index of Host channel registers + * @halt_status: Reason the channel is being halted or just XferComplete + * for isochronous transfers + * + * Releases the channel to be used by other transfers. + * In case of Isochronous endpoint the channel is not halted until the end of + * the session, i.e. QTD list is empty. + * If periodic channel released the FrameList is updated accordingly. + * Calls transaction selection routines to activate pending transfers. + */ +void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, + struct dwc2_host_chan *chan, int chnum, + enum dwc2_halt_status halt_status) +{ + struct dwc2_qh *qh = chan->qh; + int continue_isoc_xfer = 0; + enum dwc2_transaction_type tr_type; + + if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) { + dwc2_complete_isoc_xfer_ddma(hsotg, chan, halt_status); + + /* Release the channel if halted or session completed */ + if (halt_status != DWC2_HC_XFER_COMPLETE || + list_empty(&qh->qtd_list)) { + /* Halt the channel if session completed */ + if (halt_status == DWC2_HC_XFER_COMPLETE) + dwc2_hc_halt(hsotg, chan, halt_status); + dwc2_release_channel_ddma(hsotg, qh); + dwc2_hcd_qh_unlink(hsotg, qh); + } else { + /* Keep in assigned schedule to continue transfer */ + list_move(&qh->qh_list_entry, + &hsotg->periodic_sched_assigned); + continue_isoc_xfer = 1; + } + /* + * Todo: Consider the case when period exceeds FrameList size. + * Frame Rollover interrupt should be used. + */ + } else { + /* + * Scan descriptor list to complete the URB(s), then release + * the channel + */ + dwc2_complete_non_isoc_xfer_ddma(hsotg, chan, chnum, + halt_status); + dwc2_release_channel_ddma(hsotg, qh); + dwc2_hcd_qh_unlink(hsotg, qh); + + if (!list_empty(&qh->qtd_list)) { + /* + * Add back to inactive non-periodic schedule on normal + * completion + */ + dwc2_hcd_qh_add(hsotg, qh); + } + } + + tr_type = dwc2_hcd_select_transactions(hsotg); + if (tr_type != DWC2_TRANSACTION_NONE || continue_isoc_xfer) { + if (continue_isoc_xfer) { + if (tr_type == DWC2_TRANSACTION_NONE) + tr_type = DWC2_TRANSACTION_PERIODIC; + else if (tr_type == DWC2_TRANSACTION_NON_PERIODIC) + tr_type = DWC2_TRANSACTION_ALL; + } + dwc2_hcd_queue_transactions(hsotg, tr_type); + } +} -- cgit From 99882e3f881814284450575bb412acf257f73196 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 11 Mar 2013 17:48:01 -0700 Subject: staging: PCI bus interface for the DWC2 driver This file contains the PCI bus interface "glue" for the DWC2 driver Signed-off-by: Paul Zimmerman Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/pci.c | 198 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 drivers/staging/dwc2/pci.c (limited to 'drivers') diff --git a/drivers/staging/dwc2/pci.c b/drivers/staging/dwc2/pci.c new file mode 100644 index 000000000000..117d3ce404dd --- /dev/null +++ b/drivers/staging/dwc2/pci.c @@ -0,0 +1,198 @@ +/* + * pci.c - DesignWare HS OTG Controller PCI driver + * + * Copyright (C) 2004-2013 Synopsys, Inc. + * + * 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, this list of conditions, and the following disclaimer, + * without modification. + * 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 names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR + * CONTRIBUTORS 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. + */ + +/* + * Provides the initialization and cleanup entry points for the DWC_otg PCI + * driver + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "core.h" +#include "hcd.h" + +#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 +#define PCI_PRODUCT_ID_HAPS_HSOTG 0xabc0 + +static const char dwc2_driver_name[] = "dwc_otg"; + +static struct dwc2_core_params dwc2_module_params = { + .otg_cap = -1, + .otg_ver = -1, + .dma_enable = -1, + .dma_desc_enable = 0, + .speed = -1, + .enable_dynamic_fifo = -1, + .en_multiple_tx_fifo = -1, + .host_rx_fifo_size = 1024, + .host_nperio_tx_fifo_size = 256, + .host_perio_tx_fifo_size = 1024, + .max_transfer_size = 65535, + .max_packet_count = 511, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = 16, /* 16 bits - NOT DETECTABLE */ + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahb_single = -1, +}; + +/** + * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the + * DWC_otg driver + * + * @dev: Bus device + * + * This routine is called, for example, when the rmmod command is executed. The + * device may or may not be electrically present. If it is present, the driver + * stops device processing. Any resources used on behalf of this device are + * freed. + */ +static void dwc2_driver_remove(struct pci_dev *dev) +{ + struct dwc2_hsotg *hsotg = pci_get_drvdata(dev); + + dev_dbg(&dev->dev, "%s(%p)\n", __func__, dev); + + dwc2_hcd_remove(&dev->dev, hsotg); + pci_disable_device(dev); +} + +/** + * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg + * driver + * + * @dev: Bus device + * + * This routine creates the driver components required to control the device + * (core, HCD, and PCD) and initializes the device. The driver components are + * stored in a dwc2_hsotg structure. A reference to the dwc2_hsotg is saved + * in the device private data. This allows the driver to access the dwc2_hsotg + * structure on subsequent calls to driver methods for this device. + */ +static int dwc2_driver_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct dwc2_hsotg *hsotg; + int retval; + + dev_dbg(&dev->dev, "%s(%p)\n", __func__, dev); + + hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL); + if (!hsotg) + return -ENOMEM; + + pci_set_power_state(dev, PCI_D0); + + hsotg->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]); + if (!hsotg->regs) + return -ENOMEM; + + dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", + (unsigned long)pci_resource_start(dev, 0), hsotg->regs); + + if (pci_enable_device(dev) < 0) + return -ENODEV; + + pci_set_master(dev); + + if (dwc2_module_params.dma_enable > 0) { + if (pci_set_dma_mask(dev, DMA_BIT_MASK(31)) < 0) + dev_warn(&dev->dev, + "can't enable workaround for >2GB RAM\n"); + if (pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(31)) < 0) + dev_warn(&dev->dev, + "can't enable workaround for >2GB RAM\n"); + } else { + pci_set_dma_mask(dev, 0); + pci_set_consistent_dma_mask(dev, 0); + } + + retval = dwc2_hcd_init(&dev->dev, hsotg, dev->irq, &dwc2_module_params); + if (retval) { + pci_disable_device(dev); + return retval; + } + + pci_set_drvdata(dev, hsotg); + dev_dbg(&dev->dev, "hsotg=%p\n", hsotg); + + dev_dbg(&dev->dev, "registering common handler for irq%d\n", dev->irq); + retval = devm_request_irq(&dev->dev, dev->irq, dwc2_handle_common_intr, + IRQF_SHARED | IRQ_LEVEL, dev_name(&dev->dev), + hsotg); + if (retval) + dwc2_hcd_remove(&dev->dev, hsotg); + + return retval; +} + +static DEFINE_PCI_DEVICE_TABLE(dwc2_pci_ids) = { + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG), + }, + { /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE(pci, dwc2_pci_ids); + +static struct pci_driver dwc2_pci_driver = { + .name = dwc2_driver_name, + .id_table = dwc2_pci_ids, + .probe = dwc2_driver_probe, + .remove = dwc2_driver_remove, +}; + +module_pci_driver(dwc2_pci_driver); + +MODULE_DESCRIPTION("DESIGNWARE HS OTG PCI Bus Glue"); +MODULE_AUTHOR("Synopsys, Inc."); +MODULE_LICENSE("Dual BSD/GPL"); -- cgit From 535f60a405a06b23ed4430d2443b1afb5aa96850 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 11 Mar 2013 17:48:02 -0700 Subject: staging: Hook the DWC2 driver into the build system Add the DWC2 Kconfig and Makefile, and modify the staging Kconfig and Makefile to include them Signed-off-by: Paul Zimmerman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/dwc2/Kconfig | 41 +++++++++++++++++++++++++++++++++++++++++ drivers/staging/dwc2/Makefile | 23 +++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 drivers/staging/dwc2/Kconfig create mode 100644 drivers/staging/dwc2/Makefile (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index daeeec17ac9b..95f911022b70 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -142,4 +142,6 @@ source "drivers/staging/goldfish/Kconfig" source "drivers/staging/netlogic/Kconfig" +source "drivers/staging/dwc2/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d3040d7bdded..1c486cbcbe2c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -63,3 +63,4 @@ obj-$(CONFIG_SB105X) += sb105x/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_GOLDFISH) += goldfish/ +obj-$(CONFIG_USB_DWC2) += dwc2/ diff --git a/drivers/staging/dwc2/Kconfig b/drivers/staging/dwc2/Kconfig new file mode 100644 index 000000000000..610418a55fea --- /dev/null +++ b/drivers/staging/dwc2/Kconfig @@ -0,0 +1,41 @@ +config USB_DWC2 + tristate "DesignWare USB2 DRD Core Support" + depends on USB + select USB_OTG_UTILS + help + Say Y or M here if your system has a Dual Role HighSpeed + USB controller based on the DesignWare HSOTG IP Core. + + If you choose to build this driver as dynamically linked + modules, the core module will be called dwc2.ko, and the + PCI bus interface module (if you have a PCI bus system) + will be called dwc2_pci.ko. + + NOTE: This driver at present only implements the Host mode + of the controller. The existing s3c-hsotg driver supports + Peripheral mode, but only for the Samsung S3C platforms. + There are plans to merge the s3c-hsotg driver with this + driver in the near future to create a dual-role driver. + +if USB_DWC2 + +config USB_DWC2_DEBUG + bool "Enable Debugging Messages" + help + Say Y here to enable debugging messages in the DWC2 Driver. + +config USB_DWC2_VERBOSE + bool "Enable Verbose Debugging Messages" + depends on USB_DWC2_DEBUG + help + Say Y here to enable verbose debugging messages in the DWC2 Driver. + WARNING: Enabling this will quickly fill your message log. + If in doubt, say N. + +config USB_DWC2_TRACK_MISSED_SOFS + bool "Enable Missed SOF Tracking" + help + Say Y here to enable logging of missed SOF events to the dmesg log. + If in doubt, say N. + +endif diff --git a/drivers/staging/dwc2/Makefile b/drivers/staging/dwc2/Makefile new file mode 100644 index 000000000000..6dccf46cf4b5 --- /dev/null +++ b/drivers/staging/dwc2/Makefile @@ -0,0 +1,23 @@ +ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG +ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG + +obj-$(CONFIG_USB_DWC2) += dwc2.o + +dwc2-y += core.o core_intr.o + +# NOTE: This driver at present only implements the Host mode +# of the controller. The existing s3c-hsotg driver supports +# Peripheral mode, but only for the Samsung S3C platforms. +# There are plans to merge the s3c-hsotg driver with this +# driver in the near future to create a dual-role driver. Once +# that is done, Host mode will become an optional feature that +# is selected with a config option. + +dwc2-y += hcd.o hcd_intr.o +dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(CONFIG_PCI),) + obj-$(CONFIG_USB_DWC2) += dwc2_pci.o +endif + +dwc2_pci-y += pci.o -- cgit From ba06d1e1d3350a38476ea6b7655ba7c047baad67 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Tue, 12 Mar 2013 15:34:40 +1030 Subject: virtio-scsi: use pr_err() instead of printk() Convert the virtio-scsi driver to use pr_err() instead of printk(). Signed-off-by: Wanlong Gao Acked-by: Paolo Bonzini Signed-off-by: Rusty Russell --- drivers/scsi/virtio_scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 3449a1f8c656..0f5dd2804ae5 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -13,6 +13,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -794,8 +796,7 @@ static int __init init(void) virtscsi_cmd_cache = KMEM_CACHE(virtio_scsi_cmd, 0); if (!virtscsi_cmd_cache) { - printk(KERN_ERR "kmem_cache_create() for " - "virtscsi_cmd_cache failed\n"); + pr_err("kmem_cache_create() for virtscsi_cmd_cache failed\n"); goto error; } @@ -804,8 +805,7 @@ static int __init init(void) mempool_create_slab_pool(VIRTIO_SCSI_MEMPOOL_SZ, virtscsi_cmd_cache); if (!virtscsi_cmd_pool) { - printk(KERN_ERR "mempool_create() for" - "virtscsi_cmd_pool failed\n"); + pr_err("mempool_create() for virtscsi_cmd_pool failed\n"); goto error; } ret = register_virtio_driver(&virtio_scsi_driver); -- cgit From 9d9598b81c5c05495009e81ac0508ec8d1558015 Mon Sep 17 00:00:00 2001 From: Milos Vyletel Date: Tue, 12 Mar 2013 15:34:40 +1030 Subject: virtio-blk: emit udev event when device is resized When virtio-blk device is resized from host (using block_resize from QEMU) emit KOBJ_CHANGE uevent to notify guest about such change. This allows user to have custom udev rules which would take whatever action if such event occurs. As a proof of concept I've created simple udev rule that automatically resize filesystem on virtio-blk device. ACTION=="change", KERNEL=="vd*", \ ENV{RESIZE}=="1", \ ENV{ID_FS_TYPE}=="ext[3-4]", \ RUN+="/sbin/resize2fs /dev/%k" ACTION=="change", KERNEL=="vd*", \ ENV{RESIZE}=="1", \ ENV{ID_FS_TYPE}=="LVM2_member", \ RUN+="/sbin/pvresize /dev/%k" Signed-off-by: Milos Vyletel Tested-by: Asias He Signed-off-by: Rusty Russell (minor simplification) --- drivers/block/virtio_blk.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 8ad21a25bc0d..922bcb97e23a 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -539,6 +539,7 @@ static void virtblk_config_changed_work(struct work_struct *work) struct virtio_device *vdev = vblk->vdev; struct request_queue *q = vblk->disk->queue; char cap_str_2[10], cap_str_10[10]; + char *envp[] = { "RESIZE=1", NULL }; u64 capacity, size; mutex_lock(&vblk->config_lock); @@ -568,6 +569,7 @@ static void virtblk_config_changed_work(struct work_struct *work) set_capacity(vblk->disk, capacity); revalidate_disk(vblk->disk); + kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp); done: mutex_unlock(&vblk->config_lock); } -- cgit From b818d1a7f72575eef17e00dc4085512c9cc8897d Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Sun, 10 Mar 2013 22:50:02 +0000 Subject: phy/micrel: Add support for KSZ8031 Micrel PHY KSZ8031 is similar to KSZ8021 and also requires the special initialization of "Operation Mode Strap Override" in reg 0x16 introduced in 212ea99 (phy/micrel: Implement support for KSZ8021). Signed-off-by: Hector Palacios Reviewed-by: Marek Vasut Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 14 ++++++++++++++ include/linux/micrel_phy.h | 1 + 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index abf7b6153d00..018af1852fe1 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -191,6 +191,19 @@ static struct phy_driver ksphy_driver[] = { .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, +}, { + .phy_id = PHY_ID_KSZ8031, + .phy_id_mask = 0x00ffffff, + .name = "Micrel KSZ8031", + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .config_init = ksz8021_config_init, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .ack_interrupt = kszphy_ack_interrupt, + .config_intr = kszphy_config_intr, + .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8041, .phy_id_mask = 0x00fffff0, @@ -325,6 +338,7 @@ static struct mdio_device_id __maybe_unused micrel_tbl[] = { { PHY_ID_KSZ8001, 0x00ffffff }, { PHY_ID_KS8737, 0x00fffff0 }, { PHY_ID_KSZ8021, 0x00ffffff }, + { PHY_ID_KSZ8031, 0x00ffffff }, { PHY_ID_KSZ8041, 0x00fffff0 }, { PHY_ID_KSZ8051, 0x00fffff0 }, { PHY_ID_KSZ8061, 0x00fffff0 }, diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index 9dbb41a4e250..8752dbbc6135 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h @@ -19,6 +19,7 @@ #define PHY_ID_KSZ9021 0x00221610 #define PHY_ID_KS8737 0x00221720 #define PHY_ID_KSZ8021 0x00221555 +#define PHY_ID_KSZ8031 0x00221556 #define PHY_ID_KSZ8041 0x00221510 #define PHY_ID_KSZ8051 0x00221550 /* same id: ks8001 Rev. A/B, and ks8721 Rev 3. */ -- cgit From b6bb4dfcb1803765e7d12a9807a8d4650545199a Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Sun, 10 Mar 2013 22:50:03 +0000 Subject: phy/micrel: move flag handling to function for common use The flag MICREL_PHY_50MHZ_CLK is not of exclusive use of KSZ8051 model. At least KSZ8021 and KSZ8031 models also use it. This patch moves the handling of this and future flags to a separate function so that the different PHY models can call it on their init function, if needed. Signed-off-by: Hector Palacios Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 018af1852fe1..2510435f34ed 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -53,6 +53,18 @@ #define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) #define KSZ8051_RMII_50MHZ_CLK (1 << 7) +static int ksz_config_flags(struct phy_device *phydev) +{ + int regval; + + if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { + regval = phy_read(phydev, MII_KSZPHY_CTRL); + regval |= KSZ8051_RMII_50MHZ_CLK; + return phy_write(phydev, MII_KSZPHY_CTRL, regval); + } + return 0; +} + static int kszphy_ack_interrupt(struct phy_device *phydev) { /* bit[7..0] int status, which is a read and clear register. */ @@ -114,22 +126,19 @@ static int kszphy_config_init(struct phy_device *phydev) static int ksz8021_config_init(struct phy_device *phydev) { + int rc; const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE; phy_write(phydev, MII_KSZPHY_OMSO, val); - return 0; + rc = ksz_config_flags(phydev); + return rc < 0 ? rc : 0; } static int ks8051_config_init(struct phy_device *phydev) { - int regval; - - if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { - regval = phy_read(phydev, MII_KSZPHY_CTRL); - regval |= KSZ8051_RMII_50MHZ_CLK; - phy_write(phydev, MII_KSZPHY_CTRL, regval); - } + int rc; - return 0; + rc = ksz_config_flags(phydev); + return rc < 0 ? rc : 0; } #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 -- cgit From 3ffd880d3c6c63cdf575764da9e903fc3249937d Mon Sep 17 00:00:00 2001 From: Silviu-Mihai Popescu Date: Mon, 11 Mar 2013 21:48:07 +0000 Subject: ethernet: amd: use PTR_RET instead of IS_ERR + PTR_ERR This uses PTR_RET instead of IS_ERR and PTR_ERR in order to increase readability. Signed-off-by: Silviu-Mihai Popescu Acked-by: Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/atarilance.c | 4 +--- drivers/net/ethernet/amd/mvme147.c | 4 +--- drivers/net/ethernet/amd/ni65.c | 2 +- drivers/net/ethernet/amd/sun3lance.c | 4 +--- 4 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index ab9bedb8d276..e8d0ef508f48 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -1147,9 +1147,7 @@ static struct net_device *atarilance_dev; static int __init atarilance_module_init(void) { atarilance_dev = atarilance_probe(-1); - if (IS_ERR(atarilance_dev)) - return PTR_ERR(atarilance_dev); - return 0; + return PTR_RET(atarilance_dev); } static void __exit atarilance_module_exit(void) diff --git a/drivers/net/ethernet/amd/mvme147.c b/drivers/net/ethernet/amd/mvme147.c index 9af3c307862c..a51497c9d2af 100644 --- a/drivers/net/ethernet/amd/mvme147.c +++ b/drivers/net/ethernet/amd/mvme147.c @@ -188,9 +188,7 @@ static struct net_device *dev_mvme147_lance; int __init init_module(void) { dev_mvme147_lance = mvme147lance_probe(-1); - if (IS_ERR(dev_mvme147_lance)) - return PTR_ERR(dev_mvme147_lance); - return 0; + return PTR_RET(dev_mvme147_lance); } void __exit cleanup_module(void) diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index 013b65108536..26fc0ce0faa3 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -1238,7 +1238,7 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)"); int __init init_module(void) { dev_ni65 = ni65_probe(-1); - return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0; + return PTR_RET(dev_ni65); } void __exit cleanup_module(void) diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c index de412d331a72..4375abe61da1 100644 --- a/drivers/net/ethernet/amd/sun3lance.c +++ b/drivers/net/ethernet/amd/sun3lance.c @@ -940,9 +940,7 @@ static struct net_device *sun3lance_dev; int __init init_module(void) { sun3lance_dev = sun3lance_probe(-1); - if (IS_ERR(sun3lance_dev)) - return PTR_ERR(sun3lance_dev); - return 0; + return PTR_RET(sun3lance_dev); } void __exit cleanup_module(void) -- cgit From 9665f7f234d095fc7c28c70df819a3f7b6a7b4e8 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Feb 2013 14:23:08 +0530 Subject: mmc: dw_mmc: Make dw_mci_exynos_probe static Silences the following sparse warning: drivers/mmc/host/dw_mmc-exynos.c:218:5: warning: symbol 'dw_mci_exynos_probe' was not declared. Should it be static? Signed-off-by: Sachin Kamat Acked-by: Jaehoon Chung Acked-by: Seungwon Jeon Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc-exynos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 72fd0f2c9013..5a09c779a937 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -215,7 +215,7 @@ static const struct of_device_id dw_mci_exynos_match[] = { }; MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); -int dw_mci_exynos_probe(struct platform_device *pdev) +static int dw_mci_exynos_probe(struct platform_device *pdev) { const struct dw_mci_drv_data *drv_data; const struct of_device_id *match; -- cgit From 07ef7bec683beed65ccef330df66d88738c50a4a Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Mon, 11 Mar 2013 05:17:41 +0000 Subject: bnx2x: fix vlan-mac memory leak Release (previously leaking) memory when elements are removed from pending execution lists in the bnx2x driver. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 7306416bc90d..9f2637c295c8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1854,6 +1854,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, return rc; } list_del(&exeq_pos->link); + bnx2x_exe_queue_free_elem(bp, exeq_pos); } } -- cgit From 005a07baa1713861a060fab66a3d7d91f8d759c6 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Mon, 11 Mar 2013 05:17:42 +0000 Subject: bnx2x: Set ethtool ops for vfs Virtual functions don't have access to HW registers, therefore most ethtool ops are forbidden to them. Instead of checking in each op whether the device being driven is a virtual function or a physical function, this patch creates a separate ethtool ops struct for virtual functions and uses it to initialize the ethtool ops of the driver in case it is driving a virtual function device. Signed-off-by: Ariel Elior Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 29 ++++++++++++++++++++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 9577cceafac4..8ddc78bada49 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2285,7 +2285,7 @@ static const u32 dmae_reg_go_c[] = { DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15 }; -void bnx2x_set_ethtool_ops(struct net_device *netdev); +void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev); void bnx2x_notify_link_changed(struct bnx2x *bp); #define BNX2X_MF_SD_PROTOCOL(bp) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index edfa67adf2f9..324d6913af62 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -3232,7 +3232,32 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .get_ts_info = ethtool_op_get_ts_info, }; -void bnx2x_set_ethtool_ops(struct net_device *netdev) +static const struct ethtool_ops bnx2x_vf_ethtool_ops = { + .get_settings = bnx2x_get_settings, + .set_settings = bnx2x_set_settings, + .get_drvinfo = bnx2x_get_drvinfo, + .get_msglevel = bnx2x_get_msglevel, + .set_msglevel = bnx2x_set_msglevel, + .get_link = bnx2x_get_link, + .get_coalesce = bnx2x_get_coalesce, + .get_ringparam = bnx2x_get_ringparam, + .set_ringparam = bnx2x_set_ringparam, + .get_sset_count = bnx2x_get_sset_count, + .get_strings = bnx2x_get_strings, + .get_ethtool_stats = bnx2x_get_ethtool_stats, + .get_rxnfc = bnx2x_get_rxnfc, + .set_rxnfc = bnx2x_set_rxnfc, + .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, + .get_rxfh_indir = bnx2x_get_rxfh_indir, + .set_rxfh_indir = bnx2x_set_rxfh_indir, + .get_channels = bnx2x_get_channels, + .set_channels = bnx2x_set_channels, +}; + +void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev) { - SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops); + if (IS_PF(bp)) + SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops); + else /* vf */ + SET_ETHTOOL_OPS(netdev, &bnx2x_vf_ethtool_ops); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e81a747ea8ce..14a778433522 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11953,7 +11953,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, dev->watchdog_timeo = TX_TIMEOUT; dev->netdev_ops = &bnx2x_netdev_ops; - bnx2x_set_ethtool_ops(dev); + bnx2x_set_ethtool_ops(bp, dev); dev->priv_flags |= IFF_UNICAST_FLT; -- cgit From f22fdf25f4d4e9a2124ca6a2521f36dd73a32dad Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Mon, 11 Mar 2013 05:17:43 +0000 Subject: bnx2x: Take chip version from MFW In latest boards, the CHIP_METAL register contains an incorrect revision value, so the correct one needs to be obtained in a different manner. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 8 ++++++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 14a778433522..82f2e963782b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10034,8 +10034,12 @@ static void bnx2x_get_common_hwinfo(struct bnx2x *bp) id = ((val & 0xffff) << 16); val = REG_RD(bp, MISC_REG_CHIP_REV); id |= ((val & 0xf) << 12); - val = REG_RD(bp, MISC_REG_CHIP_METAL); - id |= ((val & 0xff) << 4); + + /* Metal is read from PCI regs, but we can't access >=0x400 from + * the configuration space (so we need to reg_rd) + */ + val = REG_RD(bp, PCICFG_OFFSET + PCI_ID_VAL3); + id |= (((val >> 24) & 0xf) << 4); val = REG_RD(bp, MISC_REG_BOND_ID); id |= (val & 0xf); bp->common.chip_id = id; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 791eb2d53011..d22bc40091ec 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -1491,10 +1491,6 @@ /* [R 4] This field indicates the type of the device. '0' - 2 Ports; '1' - 1 Port. */ #define MISC_REG_BOND_ID 0xa400 -/* [R 8] These bits indicate the metal revision of the chip. This value - starts at 0x00 for each all-layer tape-out and increments by one for each - tape-out. */ -#define MISC_REG_CHIP_METAL 0xa404 /* [R 16] These bits indicate the part number for the chip. */ #define MISC_REG_CHIP_NUM 0xa408 /* [R 4] These bits indicate the base revision of the chip. This value @@ -6331,6 +6327,8 @@ #define PCI_PM_DATA_B 0x414 #define PCI_ID_VAL1 0x434 #define PCI_ID_VAL2 0x438 +#define PCI_ID_VAL3 0x43c + #define GRC_CONFIG_REG_PF_INIT_VF 0x624 #define GRC_CR_PF_INIT_VF_PF_FIRST_VF_NUM_MASK 0xf /* First VF_NUM for PF is encoded in this register. -- cgit From 3786b9426d943ef167575be2ba20dab3d858243e Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Mon, 11 Mar 2013 05:17:44 +0000 Subject: bnx2x: Prevent "Unknown MF" print in SF mode When using a chip operating in Single Function mode, when the chip is probed the bnx2x would print a message warning of an unknown Multi Function mode. This patch prevents said message. Signed-off-by: Ariel Elior Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 82f2e963782b..423b5a074c80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11060,6 +11060,9 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp) } else BNX2X_DEV_INFO("illegal OV for SD\n"); break; + case SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF: + bp->mf_config[vn] = 0; + break; default: /* Unknown configuration: reset mf_config */ bp->mf_config[vn] = 0; -- cgit From 3ec9f9ca79757c54b12f87e51a6664ba1e597b17 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Mon, 11 Mar 2013 05:17:45 +0000 Subject: bnx2x: Add iproute2 support for vfs This patch adds support for iproute2 callbacks allowing querying a physical function as to its child virtual functions, and setting the macs and vlans of said virtual functions. Signed-off-by: Ariel Elior Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 3 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 38 +++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 24 +-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 6 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 239 ++++++++++++++++++++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 3 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | 9 +- 8 files changed, 277 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8ddc78bada49..d62d037b2928 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1214,6 +1214,7 @@ enum { BNX2X_SP_RTNL_ENABLE_SRIOV, BNX2X_SP_RTNL_VFPF_MCAST, BNX2X_SP_RTNL_VFPF_STORM_RX_MODE, + BNX2X_SP_RTNL_HYPERVISOR_VLAN, }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 8d158d8240a2..4620fa5666e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -496,7 +496,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); /* setup_tc callback */ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc); +int bnx2x_get_vf_config(struct net_device *dev, int vf, + struct ifla_vf_info *ivi); int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); +int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); /* select_queue callback */ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 423b5a074c80..9be9b0373ca9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -75,8 +75,6 @@ #define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" -#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) - /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -3227,16 +3225,29 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp) { struct eth_stats_info *ether_stat = &bp->slowpath->drv_info_to_mcp.ether_stat; + struct bnx2x_vlan_mac_obj *mac_obj = + &bp->sp_objs->mac_obj; + int i; strlcpy(ether_stat->version, DRV_MODULE_VERSION, ETH_STAT_INFO_VERSION_LEN); - bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj, - DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, - ether_stat->mac_local); - + /* get DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED macs, placing them in the + * mac_local field in ether_stat struct. The base address is offset by 2 + * bytes to account for the field being 8 bytes but a mac address is + * only 6 bytes. Likewise, the stride for the get_n_elements function is + * 2 bytes to compensate from the 6 bytes of a mac to the 8 bytes + * allocated by the ether_stat struct, so the macs will land in their + * proper positions. + */ + for (i = 0; i < DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED; i++) + memset(ether_stat->mac_local + i, 0, + sizeof(ether_stat->mac_local[0])); + mac_obj->get_n_elements(bp, &bp->sp_objs[0].mac_obj, + DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, + ether_stat->mac_local + MAC_PAD, MAC_PAD, + ETH_ALEN); ether_stat->mtu_size = bp->dev->mtu; - if (bp->dev->features & NETIF_F_RXCSUM) ether_stat->feature_flags |= FEATURE_ETH_CHKSUM_OFFLOAD_MASK; if (bp->dev->features & NETIF_F_TSO) @@ -3258,8 +3269,7 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) if (!CNIC_LOADED(bp)) return; - memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT, - bp->fip_mac, ETH_ALEN); + memcpy(fcoe_stat->mac_local + MAC_PAD, bp->fip_mac, ETH_ALEN); fcoe_stat->qos_priority = app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]; @@ -3361,8 +3371,8 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp) if (!CNIC_LOADED(bp)) return; - memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT, - bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); + memcpy(iscsi_stat->mac_local + MAC_PAD, bp->cnic_eth_dev.iscsi_mac, + ETH_ALEN); iscsi_stat->qos_priority = app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI]; @@ -9525,6 +9535,10 @@ sp_rtnl_not_reset: bnx2x_vfpf_storm_rx_mode(bp); } + if (test_and_clear_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN, + &bp->sp_rtnl_state)) + bnx2x_pf_set_vfs_vlan(bp); + /* work which needs rtnl lock not-taken (as it takes the lock itself and * can be called from other contexts as well) */ @@ -11798,6 +11812,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_setup_tc = bnx2x_setup_tc, #ifdef CONFIG_BNX2X_SRIOV .ndo_set_vf_mac = bnx2x_set_vf_mac, + .ndo_set_vf_vlan = bnx2x_set_vf_vlan, + .ndo_get_vf_config = bnx2x_get_vf_config, #endif #ifdef NETDEV_FCOE_WWNN .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 9f2637c295c8..6b03acd5d9ad 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -30,8 +30,6 @@ #define BNX2X_MAX_EMUL_MULTI 16 -#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) - /**** Exe Queue interfaces ****/ /** @@ -444,30 +442,21 @@ static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) } static int bnx2x_get_n_elements(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o, - int n, u8 *buf) + int n, u8 *base, u8 stride, u8 size) { struct bnx2x_vlan_mac_registry_elem *pos; - u8 *next = buf; + u8 *next = base; int counter = 0; /* traverse list */ list_for_each_entry(pos, &o->head, link) { if (counter < n) { - /* place leading zeroes in buffer */ - memset(next, 0, MAC_LEADING_ZERO_CNT); - - /* place mac after leading zeroes*/ - memcpy(next + MAC_LEADING_ZERO_CNT, pos->u.mac.mac, - ETH_ALEN); - - /* calculate address of next element and - * advance counter - */ + memcpy(next, &pos->u, size); counter++; - next = buf + counter * ALIGN(ETH_ALEN, sizeof(u32)); + DP(BNX2X_MSG_SP, "copied element number %d to address %p element was:\n", + counter, next); + next += stride + size; - DP(BNX2X_MSG_SP, "copied element number %d to address %p element was %pM\n", - counter, next, pos->u.mac.mac); } } return counter * ETH_ALEN; @@ -2013,6 +2002,7 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp, vlan_obj->check_move = bnx2x_check_move; vlan_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; + vlan_obj->get_n_elements = bnx2x_get_n_elements; /* Exe Queue */ bnx2x_exe_queue_init(bp, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index ff907609b9fc..ac57e63a08ed 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -313,8 +313,9 @@ struct bnx2x_vlan_mac_obj { * * @return number of copied bytes */ - int (*get_n_elements)(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o, - int n, u8 *buf); + int (*get_n_elements)(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, int n, u8 *base, + u8 stride, u8 size); /** * Checks if ADD-ramrod with the given params may be performed. @@ -842,6 +843,7 @@ enum bnx2x_q_type { #define BNX2X_MULTI_TX_COS_E3B0 3 #define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ +#define MAC_PAD (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN) struct bnx2x_queue_init_params { struct { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 6adfa2093581..7b234e41fea8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -20,7 +20,9 @@ #include "bnx2x.h" #include "bnx2x_init.h" #include "bnx2x_cmn.h" +#include "bnx2x_sp.h" #include +#include /* General service functions */ static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, @@ -958,6 +960,12 @@ op_err: BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, vfop->rc); op_done: case BNX2X_VFOP_QSETUP_DONE: + vf->cfg_flags |= VF_CFG_VLAN; + smp_mb__before_clear_bit(); + set_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN, + &bp->sp_rtnl_state); + smp_mb__after_clear_bit(); + schedule_delayed_work(&bp->sp_rtnl_task, 0); bnx2x_vfop_end(bp, vf, vfop); return; default: @@ -3029,6 +3037,88 @@ void bnx2x_enable_sriov(struct bnx2x *bp) DP(BNX2X_MSG_IOV, "sriov enabled\n"); } +void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) +{ + int vfidx; + struct pf_vf_bulletin_content *bulletin; + + DP(BNX2X_MSG_IOV, "configuring vlan for VFs from sp-task\n"); + for_each_vf(bp, vfidx) { + bulletin = BP_VF_BULLETIN(bp, vfidx); + if (BP_VF(bp, vfidx)->cfg_flags & VF_CFG_VLAN) + bnx2x_set_vf_vlan(bp->dev, vfidx, bulletin->vlan, 0); + } +} + +static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, + struct bnx2x_virtf *vf) +{ + if (!IS_SRIOV(bp)) { + BNX2X_ERR("vf ndo called though sriov is disabled\n"); + return -EINVAL; + } + + if (vfidx >= BNX2X_NR_VIRTFN(bp)) { + BNX2X_ERR("vf ndo called for uninitialized VF. vfidx was %d BNX2X_NR_VIRTFN was %d\n", + vfidx, BNX2X_NR_VIRTFN(bp)); + return -EINVAL; + } + + if (!vf) { + BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n", + vfidx); + return -EINVAL; + } + + return 0; +} + +int bnx2x_get_vf_config(struct net_device *dev, int vfidx, + struct ifla_vf_info *ivi) +{ + struct bnx2x *bp = netdev_priv(dev); + struct bnx2x_virtf *vf = BP_VF(bp, vfidx); + struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj); + struct bnx2x_vlan_mac_obj *vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj); + struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); + int rc; + + /* sanity */ + rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); + if (rc) + return rc; + + ivi->vf = vfidx; + ivi->qos = 0; + ivi->tx_rate = 10000; /* always 10G. TBA take from link struct */ + ivi->spoofchk = 1; /*always enabled */ + if (vf->state == VF_ENABLED) { + /* mac and vlan are in vlan_mac objects */ + mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac, + 0, ETH_ALEN); + vlan_obj->get_n_elements(bp, vlan_obj, 1, (u8 *)&ivi->vlan, + 0, VLAN_HLEN); + } else { + /* mac */ + if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID)) + /* mac configured by ndo so its in bulletin board */ + memcpy(&ivi->mac, bulletin->mac, ETH_ALEN); + else + /* funtion has not been loaded yet. Show mac as 0s */ + memset(&ivi->mac, 0, ETH_ALEN); + + /* vlan */ + if (bulletin->valid_bitmap & (1 << VLAN_VALID)) + /* vlan configured by ndo so its in bulletin board */ + memcpy(&ivi->vlan, &bulletin->vlan, VLAN_HLEN); + else + /* funtion has not been loaded yet. Show vlans as 0s */ + memset(&ivi->vlan, 0, VLAN_HLEN); + } + + return 0; +} + /* New mac for VF. Consider these cases: * 1. VF hasn't been acquired yet - save the mac in local bulletin board and * supply at acquire. @@ -3044,23 +3134,19 @@ void bnx2x_enable_sriov(struct bnx2x *bp) * VF to configure any mac for itself except for this mac. In case of a race * where the VF fails to see the new post on its bulletin board before sending a * mac configuration request, the PF will simply fail the request and VF can try - * again after consulting its bulletin board + * again after consulting its bulletin board. */ -int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac) +int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac) { struct bnx2x *bp = netdev_priv(dev); - int rc, q_logical_state, vfidx = queue; + int rc, q_logical_state; struct bnx2x_virtf *vf = BP_VF(bp, vfidx); struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); - /* if SRIOV is disabled there is nothing to do (and somewhere, someone - * has erred). - */ - if (!IS_SRIOV(bp)) { - BNX2X_ERR("bnx2x_set_vf_mac called though sriov is disabled\n"); - return -EINVAL; - } - + /* sanity */ + rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); + if (rc) + return rc; if (!is_valid_ether_addr(mac)) { BNX2X_ERR("mac address invalid\n"); return -EINVAL; @@ -3085,7 +3171,7 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac) if (vf->state == VF_ENABLED && q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) { /* configure the mac in device on this vf's queue */ - unsigned long flags = 0; + unsigned long ramrod_flags = 0; struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj); /* must lock vfpf channel to protect against vf flows */ @@ -3106,14 +3192,133 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac) } /* configure the new mac to device */ - __set_bit(RAMROD_COMP_WAIT, &flags); + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true, - BNX2X_ETH_MAC, &flags); + BNX2X_ETH_MAC, &ramrod_flags); bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC); } - return rc; + return 0; +} + +int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc, q_logical_state; + struct bnx2x_virtf *vf = BP_VF(bp, vfidx); + struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); + + /* sanity */ + rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); + if (rc) + return rc; + + if (vlan > 4095) { + BNX2X_ERR("illegal vlan value %d\n", vlan); + return -EINVAL; + } + + DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n", + vfidx, vlan, 0); + + /* update PF's copy of the VF's bulletin. No point in posting the vlan + * to the VF since it doesn't have anything to do with it. But it useful + * to store it here in case the VF is not up yet and we can only + * configure the vlan later when it does. + */ + bulletin->valid_bitmap |= 1 << VLAN_VALID; + bulletin->vlan = vlan; + + /* is vf initialized and queue set up? */ + q_logical_state = + bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj)); + if (vf->state == VF_ENABLED && + q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) { + /* configure the vlan in device on this vf's queue */ + unsigned long ramrod_flags = 0; + unsigned long vlan_mac_flags = 0; + struct bnx2x_vlan_mac_obj *vlan_obj = + &bnx2x_vfq(vf, 0, vlan_obj); + struct bnx2x_vlan_mac_ramrod_params ramrod_param; + struct bnx2x_queue_state_params q_params = {NULL}; + struct bnx2x_queue_update_params *update_params; + + memset(&ramrod_param, 0, sizeof(ramrod_param)); + + /* must lock vfpf channel to protect against vf flows */ + bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN); + + /* remove existing vlans */ + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); + rc = vlan_obj->delete_all(bp, vlan_obj, &vlan_mac_flags, + &ramrod_flags); + if (rc) { + BNX2X_ERR("failed to delete vlans\n"); + return -EINVAL; + } + + /* send queue update ramrod to configure default vlan and silent + * vlan removal + */ + __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); + q_params.cmd = BNX2X_Q_CMD_UPDATE; + q_params.q_obj = &bnx2x_vfq(vf, 0, sp_obj); + update_params = &q_params.params.update; + __set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG, + &update_params->update_flags); + __set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, + &update_params->update_flags); + + if (vlan == 0) { + /* if vlan is 0 then we want to leave the VF traffic + * untagged, and leave the incoming traffic untouched + * (i.e. do not remove any vlan tags). + */ + __clear_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN, + &update_params->update_flags); + __clear_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM, + &update_params->update_flags); + } else { + /* configure the new vlan to device */ + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); + ramrod_param.vlan_mac_obj = vlan_obj; + ramrod_param.ramrod_flags = ramrod_flags; + ramrod_param.user_req.u.vlan.vlan = vlan; + ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_ADD; + rc = bnx2x_config_vlan_mac(bp, &ramrod_param); + if (rc) { + BNX2X_ERR("failed to configure vlan\n"); + return -EINVAL; + } + + /* configure default vlan to vf queue and set silent + * vlan removal (the vf remains unaware of this vlan). + */ + update_params = &q_params.params.update; + __set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN, + &update_params->update_flags); + __set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM, + &update_params->update_flags); + update_params->def_vlan = vlan; + } + + /* Update the Queue state */ + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) { + BNX2X_ERR("Failed to configure default VLAN\n"); + return rc; + } + + /* clear the flag indicating that this VF needs its vlan + * (will only be set if the HV configured th Vlan before vf was + * and we were called because the VF came up later + */ + vf->cfg_flags &= ~VF_CFG_VLAN; + + bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN); + } + return 0; } /* crc is the first field in the bulletin board. compute the crc over the @@ -3165,6 +3370,10 @@ enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp) memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN); } + /* the vlan in bulletin board is valid and is new */ + if (bulletin.valid_bitmap & 1 << VLAN_VALID) + memcpy(&bulletin.vlan, &bp->old_bulletin.vlan, VLAN_HLEN); + /* copy new bulletin board to bp */ bp->old_bulletin = bulletin; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index b4050173add9..33d49516fcea 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -193,6 +193,7 @@ struct bnx2x_virtf { #define VF_CFG_TPA 0x0004 #define VF_CFG_INT_SIMD 0x0008 #define VF_CACHE_LINE 0x0010 +#define VF_CFG_VLAN 0x0020 u8 state; #define VF_FREE 0 /* VF ready to be acquired holds no resc */ @@ -757,6 +758,7 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp) { return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF; } +void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); #else /* CONFIG_BNX2X_SRIOV */ @@ -804,6 +806,7 @@ static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; } static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } +static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} #endif /* CONFIG_BNX2X_SRIOV */ #endif /* bnx2x_sriov.h */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h index bfc80baec00d..41708faab575 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h @@ -328,9 +328,15 @@ struct pf_vf_bulletin_content { #define MAC_ADDR_VALID 0 /* alert the vf that a new mac address * is available for it */ +#define VLAN_VALID 1 /* when set, the vf should not access + * the vfpf channel + */ u8 mac[ETH_ALEN]; - u8 padding[2]; + u8 mac_padding[2]; + + u16 vlan; + u8 vlan_padding[6]; }; union pf_vf_bulletin { @@ -353,6 +359,7 @@ enum channel_tlvs { CHANNEL_TLV_LIST_END, CHANNEL_TLV_FLR, CHANNEL_TLV_PF_SET_MAC, + CHANNEL_TLV_PF_SET_VLAN, CHANNEL_TLV_MAX }; -- cgit From 3c76feff68559bf9ec08d4d86abe57bc56a9847a Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Mon, 11 Mar 2013 05:17:46 +0000 Subject: bnx2x: Control number of vfs dynamically 1. Support sysfs interface for getting the maximal number of virtual functions of a given physical function. 2. Support sysfs interface for getting and setting the current number of virtual functions. Signed-off-by: Ariel Elior Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 36 +++------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 87 +++++++++++++++++++---- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 10 ++- 4 files changed, 91 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index d62d037b2928..33fbdfdc8e12 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1281,6 +1281,8 @@ struct bnx2x { dma_addr_t pf2vf_bulletin_mapping; struct pf_vf_bulletin_content old_bulletin; + + u16 requested_nr_virtfn; #endif /* CONFIG_BNX2X_SRIOV */ struct net_device *dev; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9be9b0373ca9..f685d2e77fcb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9546,8 +9546,10 @@ sp_rtnl_not_reset: /* enable SR-IOV if applicable */ if (IS_SRIOV(bp) && test_and_clear_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, - &bp->sp_rtnl_state)) + &bp->sp_rtnl_state)) { + bnx2x_disable_sriov(bp); bnx2x_enable_sriov(bp); + } } static void bnx2x_period_task(struct work_struct *work) @@ -11423,26 +11425,6 @@ static int bnx2x_init_bp(struct bnx2x *bp) * net_device service functions */ -static int bnx2x_open_epilog(struct bnx2x *bp) -{ - /* Enable sriov via delayed work. This must be done via delayed work - * because it causes the probe of the vf devices to be run, which invoke - * register_netdevice which must have rtnl lock taken. As we are holding - * the lock right now, that could only work if the probe would not take - * the lock. However, as the probe of the vf may be called from other - * contexts as well (such as passthrough to vm failes) it can't assume - * the lock is being held for it. Using delayed work here allows the - * probe code to simply take the lock (i.e. wait for it to be released - * if it is being held). - */ - smp_mb__before_clear_bit(); - set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state); - smp_mb__after_clear_bit(); - schedule_delayed_work(&bp->sp_rtnl_task, 0); - - return 0; -} - /* called with rtnl_lock */ static int bnx2x_open(struct net_device *dev) { @@ -12498,13 +12480,8 @@ static int bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } - /* Enable SRIOV if capability found in configuration space. - * Once the generic SR-IOV framework makes it in from the - * pci tree this will be revised, to allow dynamic control - * over the number of VFs. Right now, change the num of vfs - * param below to enable SR-IOV. - */ - rc = bnx2x_iov_init_one(bp, int_mode, 0/*num vfs*/); + /* Enable SRIOV if capability found in configuration space */ + rc = bnx2x_iov_init_one(bp, int_mode, BNX2X_MAX_NUM_OF_VFS); if (rc) goto init_one_exit; @@ -12820,6 +12797,9 @@ static struct pci_driver bnx2x_pci_driver = { .suspend = bnx2x_suspend, .resume = bnx2x_resume, .err_handler = &bnx2x_err_handler, +#ifdef CONFIG_BNX2X_SRIOV + .sriov_configure = bnx2x_sriov_configure, +#endif }; static int __init bnx2x_init(void) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 7b234e41fea8..df930e30e1b1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -1467,7 +1467,6 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) return bnx2x_is_pcie_pending(dev); unknown_dev: - BNX2X_ERR("Unknown device\n"); return false; } @@ -1972,8 +1971,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, if (iov->total == 0) goto failed; - /* calculate the actual number of VFs */ - iov->nr_virtfn = min_t(u16, iov->total, (u16)num_vfs_param); + iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); + + DP(BNX2X_MSG_IOV, "num_vfs_param was %d, nr_virtfn was %d\n", + num_vfs_param, iov->nr_virtfn); /* allocate the vf array */ bp->vfdb->vfs = kzalloc(sizeof(struct bnx2x_virtf) * @@ -3020,21 +3021,47 @@ void bnx2x_unlock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, vf->op_current = CHANNEL_TLV_NONE; } -void bnx2x_enable_sriov(struct bnx2x *bp) +int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param) { - int rc = 0; - /* disbale sriov in case it is still enabled */ - pci_disable_sriov(bp->pdev); - DP(BNX2X_MSG_IOV, "sriov disabled\n"); + struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev)); - /* enable sriov */ - DP(BNX2X_MSG_IOV, "vf num (%d)\n", (bp->vfdb->sriov.nr_virtfn)); - rc = pci_enable_sriov(bp->pdev, (bp->vfdb->sriov.nr_virtfn)); - if (rc) + DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n", + num_vfs_param, BNX2X_NR_VIRTFN(bp)); + + /* HW channel is only operational when PF is up */ + if (bp->state != BNX2X_STATE_OPEN) { + BNX2X_ERR("VF num configurtion via sysfs not supported while PF is down"); + return -EINVAL; + } + + /* we are always bound by the total_vfs in the configuration space */ + if (num_vfs_param > BNX2X_NR_VIRTFN(bp)) { + BNX2X_ERR("truncating requested number of VFs (%d) down to maximum allowed (%d)\n", + num_vfs_param, BNX2X_NR_VIRTFN(bp)); + num_vfs_param = BNX2X_NR_VIRTFN(bp); + } + + bp->requested_nr_virtfn = num_vfs_param; + if (num_vfs_param == 0) { + pci_disable_sriov(dev); + return 0; + } else { + return bnx2x_enable_sriov(bp); + } +} + +int bnx2x_enable_sriov(struct bnx2x *bp) +{ + int rc = 0, req_vfs = bp->requested_nr_virtfn; + + rc = pci_enable_sriov(bp->pdev, req_vfs); + if (rc) { BNX2X_ERR("pci_enable_sriov failed with %d\n", rc); - else - DP(BNX2X_MSG_IOV, "sriov enabled\n"); + return rc; + } + DP(BNX2X_MSG_IOV, "sriov enabled (%d vfs)\n", req_vfs); + return req_vfs; } void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) @@ -3050,6 +3077,11 @@ void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) } } +void bnx2x_disable_sriov(struct bnx2x *bp) +{ + pci_disable_sriov(bp->pdev); +} + static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, struct bnx2x_virtf *vf) { @@ -3087,6 +3119,10 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); if (rc) return rc; + if (!mac_obj || !vlan_obj || !bulletin) { + BNX2X_ERR("VF partially initialized\n"); + return -EINVAL; + } ivi->vf = vfidx; ivi->qos = 0; @@ -3405,3 +3441,26 @@ alloc_mem_err: sizeof(union pf_vf_bulletin)); return -ENOMEM; } + +int bnx2x_open_epilog(struct bnx2x *bp) +{ + /* Enable sriov via delayed work. This must be done via delayed work + * because it causes the probe of the vf devices to be run, which invoke + * register_netdevice which must have rtnl lock taken. As we are holding + * the lock right now, that could only work if the probe would not take + * the lock. However, as the probe of the vf may be called from other + * contexts as well (such as passthrough to vm failes) it can't assume + * the lock is being held for it. Using delayed work here allows the + * probe code to simply take the lock (i.e. wait for it to be released + * if it is being held). We only want to do this if the number of VFs + * was set before PF driver was loaded. + */ + if (IS_SRIOV(bp) && BNX2X_NR_VIRTFN(bp)) { + smp_mb__before_clear_bit(); + set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state); + smp_mb__after_clear_bit(); + schedule_delayed_work(&bp->sp_rtnl_task, 0); + } + + return 0; +} diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 33d49516fcea..a10bdb2fd900 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -753,12 +753,15 @@ static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp, enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); void bnx2x_vf_map_doorbells(struct bnx2x *bp); int bnx2x_vf_pci_alloc(struct bnx2x *bp); -void bnx2x_enable_sriov(struct bnx2x *bp); +int bnx2x_enable_sriov(struct bnx2x *bp); +void bnx2x_disable_sriov(struct bnx2x *bp); static inline int bnx2x_vf_headroom(struct bnx2x *bp) { return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF; } void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); +int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs); +int bnx2x_open_epilog(struct bnx2x *bp); #else /* CONFIG_BNX2X_SRIOV */ @@ -781,7 +784,8 @@ static inline void bnx2x_iov_init_dmae(struct bnx2x *bp) {} static inline int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, int num_vfs_param) {return 0; } static inline void bnx2x_iov_remove_one(struct bnx2x *bp) {} -static inline void bnx2x_enable_sriov(struct bnx2x *bp) {} +static inline int bnx2x_enable_sriov(struct bnx2x *bp) {return 0; } +static inline void bnx2x_disable_sriov(struct bnx2x *bp) {} static inline int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) {return 0; } static inline int bnx2x_vfpf_release(struct bnx2x *bp) {return 0; } @@ -807,6 +811,8 @@ static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; } static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} +static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } +static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; } #endif /* CONFIG_BNX2X_SRIOV */ #endif /* bnx2x_sriov.h */ -- cgit From ab5777d7483026c9bf795eba573c22ef8d2e32cd Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Mon, 11 Mar 2013 05:17:47 +0000 Subject: bnx2x: Get gso_segs from FW Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index a923bc4d5a1f..cd74ee5be5f4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -451,7 +451,8 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, * Compute number of aggregated segments, and gso_type. */ static void bnx2x_set_gro_params(struct sk_buff *skb, u16 parsing_flags, - u16 len_on_bd, unsigned int pkt_len) + u16 len_on_bd, unsigned int pkt_len, + u16 num_of_coalesced_segs) { /* TPA aggregation won't have either IP options or TCP options * other than timestamp or IPv6 extension headers. @@ -480,8 +481,7 @@ static void bnx2x_set_gro_params(struct sk_buff *skb, u16 parsing_flags, /* tcp_gro_complete() will copy NAPI_GRO_CB(skb)->count * to skb_shinfo(skb)->gso_segs */ - NAPI_GRO_CB(skb)->count = DIV_ROUND_UP(pkt_len - hdrs_len, - skb_shinfo(skb)->gso_size); + NAPI_GRO_CB(skb)->count = num_of_coalesced_segs; } static int bnx2x_alloc_rx_sge(struct bnx2x *bp, @@ -537,7 +537,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* This is needed in order to enable forwarding support */ if (frag_size) bnx2x_set_gro_params(skb, tpa_info->parsing_flags, len_on_bd, - le16_to_cpu(cqe->pkt_len)); + le16_to_cpu(cqe->pkt_len), + le16_to_cpu(cqe->num_of_coalesced_segs)); #ifdef BNX2X_STOP_ON_ERROR if (pages > min_t(u32, 8, MAX_SKB_FRAGS) * SGE_PAGES) { -- cgit From b807c74855ebc3d686a323c13843146fac200f41 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 11 Mar 2013 05:17:48 +0000 Subject: bnx2x: Add RJ45 SFP module detection Add RJ45 SFP module detection. In case the user set 10G link speed, and the module doesn't support it, then force the speed to 1G and notify the user. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 77ebae0ac64a..329c7f9a2694 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -152,6 +152,7 @@ #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 + #define SFP_EEPROM_CON_TYPE_VAL_RJ45 0x22 #define SFP_EEPROM_COMP_CODE_ADDR 0x3 @@ -8049,20 +8050,24 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, break; } case SFP_EEPROM_CON_TYPE_VAL_LC: + case SFP_EEPROM_CON_TYPE_VAL_RJ45: check_limiting_mode = 1; if ((val[1] & (SFP_EEPROM_COMP_CODE_SR_MASK | SFP_EEPROM_COMP_CODE_LR_MASK | SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) { - DP(NETIF_MSG_LINK, "1G Optic module detected\n"); + DP(NETIF_MSG_LINK, "1G SFP module detected\n"); gport = params->port; phy->media_type = ETH_PHY_SFP_1G_FIBER; - phy->req_line_speed = SPEED_1000; - if (!CHIP_IS_E1x(bp)) - gport = BP_PATH(bp) + (params->port << 1); - netdev_err(bp->dev, "Warning: Link speed was forced to 1000Mbps." - " Current SFP module in port %d is not" - " compliant with 10G Ethernet\n", - gport); + if (phy->req_line_speed != SPEED_1000) { + phy->req_line_speed = SPEED_1000; + if (!CHIP_IS_E1x(bp)) { + gport = BP_PATH(bp) + + (params->port << 1); + } + netdev_err(bp->dev, + "Warning: Link speed was forced to 1000Mbps. Current SFP module in port %d is not compliant with 10G Ethernet\n", + gport); + } } else { int idx, cfg_idx = 0; DP(NETIF_MSG_LINK, "10G Optic module detected\n"); -- cgit From 31b958d755d1d124ce3a0fbc998434fe9c0ab88b Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 11 Mar 2013 05:17:49 +0000 Subject: bnx2x: Add EEE support for BCM84834 Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 329c7f9a2694..5fc205fba8c0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -10286,7 +10286,8 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE; /* Determine if EEE was negotiated */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) || + (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) bnx2x_eee_an_resolve(phy, params, vars); } -- cgit From e438c5d651e2a7b7d6d1bad23cc3a878392e6a5c Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 11 Mar 2013 05:17:50 +0000 Subject: bnx2x: Control SFP+ tap values via nvm config Configure SFP+ tap values to optimize link signal according to NVRAM setup. Signed-off-by: Yaniv Rosner Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 17 +++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 77 ++++++++++++++---------- 2 files changed, 60 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 037860ecc343..a7a3504e1bd5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -508,7 +508,22 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_PAUSE_ON_HOST_RING_DISABLED 0x00000000 #define PORT_HW_CFG_PAUSE_ON_HOST_RING_ENABLED 0x00000001 - u32 reserved0[6]; /* 0x178 */ + /* SFP+ Tx Equalization: NIC recommended and tested value is 0xBEB2 + * LOM recommended and tested value is 0xBEB2. Using a different + * value means using a value not tested by BRCM + */ + u32 sfi_tap_values; /* 0x178 */ + #define PORT_HW_CFG_TX_EQUALIZATION_MASK 0x0000FFFF + #define PORT_HW_CFG_TX_EQUALIZATION_SHIFT 0 + + /* SFP+ Tx driver broadcast IDRIVER: NIC recommended and tested + * value is 0x2. LOM recommended and tested value is 0x2. Using a + * different value means using a value not tested by BRCM + */ + #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 + #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 + + u32 reserved0[5]; /* 0x17c */ u32 aeu_int_mask; /* 0x190 */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 5fc205fba8c0..e3fa80807394 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -3630,6 +3630,16 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, * init configuration, and set/clear SGMII flag. Internal * phy init is done purely in phy_init stage. */ +#define WC_TX_DRIVER(post2, idriver, ipre) \ + ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ + (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ + (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)) + +#define WC_TX_FIR(post, main, pre) \ + ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ + (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \ + (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)) + static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -3754,20 +3764,13 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Set Transmit PMD settings */ lane = bnx2x_get_warpcore_lane(phy, params); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, - ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | - (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, + WC_TX_DRIVER(0x02, 0x06, 0x09)); /* Configure the next lane if dual mode */ if (phy->flags & FLAGS_WC_DUAL_MODE) bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), - ((0x02 << - MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | - (0x06 << - MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x09 << - MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); + WC_TX_DRIVER(0x02, 0x06, 0x09)); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 0x03f0); @@ -3910,6 +3913,8 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 misc1_val, tap_val, tx_driver_val, lane, val; + u32 cfg_tap_val, tx_drv_brdct, tx_equal; + /* Hold rxSeqStart */ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000); @@ -3953,23 +3958,33 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, if (is_xfi) { misc1_val |= 0x5; - tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | - (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | - (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); - tx_driver_val = - ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | - (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); - + tap_val = WC_TX_FIR(0x08, 0x37, 0x00); + tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03); } else { + cfg_tap_val = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port]. + sfi_tap_values)); + + tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; + + tx_drv_brdct = (cfg_tap_val & + PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> + PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; + misc1_val |= 0x9; - tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | - (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | - (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); - tx_driver_val = - ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | - (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); + + /* TAP values are controlled by nvram, if value there isn't 0 */ + if (tx_equal) + tap_val = (u16)tx_equal; + else + tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); + + if (tx_drv_brdct) + tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct, + 0x06); + else + tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06); } bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); @@ -4106,15 +4121,11 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, /* Set Transmit PMD settings */ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, - ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | - (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | - (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) | - MDIO_WC_REG_TX_FIR_TAP_ENABLE)); + (WC_TX_FIR(0x12, 0x2d, 0x00) | + MDIO_WC_REG_TX_FIR_TAP_ENABLE)); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, - ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | - (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, + WC_TX_DRIVER(0x02, 0x02, 0x02)); } static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, -- cgit From 82594f8f47bc1167d55776cfb599633ec4ac8e77 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Mon, 11 Mar 2013 05:17:51 +0000 Subject: bnx2x: Avoid using zero MAC Prevent bnx2x devices which are used mainly for storage from using zero MAC addresses as their primary MAC address. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f685d2e77fcb..e5662a141451 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10832,14 +10832,12 @@ static void bnx2x_get_cnic_mac_hwinfo(struct bnx2x *bp) } } - if (IS_MF_STORAGE_SD(bp)) - /* Zero primary MAC configuration */ - memset(bp->dev->dev_addr, 0, ETH_ALEN); - - if (IS_MF_FCOE_AFEX(bp) || IS_MF_FCOE_SD(bp)) - /* use FIP MAC as primary MAC */ + /* If this is a storage-only interface, use SAN mac as + * primary MAC. Notice that for SD this is already the case, + * as the SAN mac was copied from the primary MAC. + */ + if (IS_MF_FCOE_AFEX(bp)) memcpy(bp->dev->dev_addr, fip_mac, ETH_ALEN); - } else { val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. iscsi_mac_upper); -- cgit From 91226790bbe2dbfbba48dd79d49f2b38ef10eb97 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 11 Mar 2013 05:17:52 +0000 Subject: bnx2x: use FW 7.8.17 Update appropriate HSI files and adapt driver accordingly. Signed-off-by: Dmitry Kravkov Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 122 ++++++----- .../net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 87 ++++---- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 235 ++++++++++++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 29 ++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 5 +- 7 files changed, 338 insertions(+), 147 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 33fbdfdc8e12..f865ad5002f6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -729,7 +729,7 @@ struct bnx2x_fastpath { #define SKB_CS(skb) (*(u16 *)(skb_transport_header(skb) + \ skb->csum_offset)) -#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff) +#define pbd_tcp_flags(tcp_hdr) (ntohl(tcp_flag_word(tcp_hdr))>>16 & 0xff) #define XMIT_PLAIN 0 #define XMIT_CSUM_V4 0x1 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index cd74ee5be5f4..9f7a3793590b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3086,11 +3086,11 @@ int bnx2x_poll(struct napi_struct *napi, int budget) * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs */ -static noinline u16 bnx2x_tx_split(struct bnx2x *bp, - struct bnx2x_fp_txdata *txdata, - struct sw_tx_bd *tx_buf, - struct eth_tx_start_bd **tx_bd, u16 hlen, - u16 bd_prod, int nbd) +static u16 bnx2x_tx_split(struct bnx2x *bp, + struct bnx2x_fp_txdata *txdata, + struct sw_tx_bd *tx_buf, + struct eth_tx_start_bd **tx_bd, u16 hlen, + u16 bd_prod) { struct eth_tx_start_bd *h_tx_bd = *tx_bd; struct eth_tx_bd *d_tx_bd; @@ -3098,11 +3098,10 @@ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, int old_len = le16_to_cpu(h_tx_bd->nbytes); /* first fix first BD */ - h_tx_bd->nbd = cpu_to_le16(nbd); h_tx_bd->nbytes = cpu_to_le16(hlen); - DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d (%x:%x) nbd %d\n", - h_tx_bd->nbytes, h_tx_bd->addr_hi, h_tx_bd->addr_lo, h_tx_bd->nbd); + DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d (%x:%x)\n", + h_tx_bd->nbytes, h_tx_bd->addr_hi, h_tx_bd->addr_lo); /* now get a new data BD * (after the pbd) and fill it */ @@ -3131,7 +3130,7 @@ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, #define bswab32(b32) ((__force __le32) swab32((__force __u32) (b32))) #define bswab16(b16) ((__force __le16) swab16((__force __u16) (b16))) -static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) +static __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) { __sum16 tsum = (__force __sum16) csum; @@ -3146,7 +3145,7 @@ static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) return bswab16(tsum); } -static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) +static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) { u32 rc; @@ -3254,8 +3253,8 @@ exit_lbl: } #endif -static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, - u32 xmit_type) +static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, + u32 xmit_type) { *parsing_data |= (skb_shinfo(skb)->gso_size << ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & @@ -3272,13 +3271,13 @@ static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, * @pbd: parse BD * @xmit_type: xmit flags */ -static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, - struct eth_tx_parse_bd_e1x *pbd, - u32 xmit_type) +static void bnx2x_set_pbd_gso(struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) { pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); pbd->tcp_send_seq = bswab32(tcp_hdr(skb)->seq); - pbd->tcp_flags = pbd_tcp_flags(skb); + pbd->tcp_flags = pbd_tcp_flags(tcp_hdr(skb)); if (xmit_type & XMIT_GSO_V4) { pbd->ip_id = bswab16(ip_hdr(skb)->id); @@ -3305,15 +3304,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, * @parsing_data: data to be updated * @xmit_type: xmit flags * - * 57712 related + * 57712/578xx related */ -static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, - u32 *parsing_data, u32 xmit_type) +static u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, + u32 *parsing_data, u32 xmit_type) { *parsing_data |= ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) << - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; + ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W; if (xmit_type & XMIT_CSUM_TCP) { *parsing_data |= ((tcp_hdrlen(skb) / 4) << @@ -3328,17 +3327,14 @@ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, return skb_transport_header(skb) + sizeof(struct udphdr) - skb->data; } -static inline void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, - struct eth_tx_start_bd *tx_start_bd, u32 xmit_type) +static void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_start_bd *tx_start_bd, + u32 xmit_type) { tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - if (xmit_type & XMIT_CSUM_V4) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IP_CSUM; - else - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IPV6; + if (xmit_type & XMIT_CSUM_V6) + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6; if (!(xmit_type & XMIT_CSUM_TCP)) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP; @@ -3352,9 +3348,9 @@ static inline void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, * @pbd: parse BD to be updated * @xmit_type: xmit flags */ -static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, - struct eth_tx_parse_bd_e1x *pbd, - u32 xmit_type) +static u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) { u8 hlen = (skb_network_header(skb) - skb->data) >> 1; @@ -3482,7 +3478,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) mac_type = MULTICAST_ADDRESS; } -#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - BDS_PER_TX_PKT) /* First, check if we need to linearize the skb (due to FW restrictions). No need to check fragmentation if page size > 8K (there will be no violation to FW restrictions) */ @@ -3530,12 +3526,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) first_bd = tx_start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - SET_FLAG(tx_start_bd->general_data, - ETH_TX_START_BD_PARSE_NBDS, - 0); - /* header nbd */ - SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1); + /* header nbd: indirectly zero other flags! */ + tx_start_bd->general_data = 1 << ETH_TX_START_BD_HDR_NBDS_SHIFT; /* remember the first BD of the packet */ tx_buf->first_bd = txdata->tx_bd_prod; @@ -3555,19 +3548,16 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* when transmitting in a vf, start bd must hold the ethertype * for fw to enforce it */ -#ifndef BNX2X_STOP_ON_ERROR - if (IS_VF(bp)) { -#endif + if (IS_VF(bp)) tx_start_bd->vlan_or_ethertype = cpu_to_le16(ntohs(eth->h_proto)); -#ifndef BNX2X_STOP_ON_ERROR - } else { + else /* used by FW for packet accounting */ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); - } -#endif } + nbd = 2; /* start_bd + pbd + frags (updated when pages are mapped) */ + /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); @@ -3579,21 +3569,22 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) + /* Set PBD in checksum offload case w/o encapsulation */ hlen = bnx2x_set_pbd_csum_e2(bp, skb, &pbd_e2_parsing_data, xmit_type); - if (IS_MF_SI(bp) || IS_VF(bp)) { - /* fill in the MAC addresses in the PBD - for local - * switching - */ - bnx2x_set_fw_mac_addr(&pbd_e2->src_mac_addr_hi, - &pbd_e2->src_mac_addr_mid, - &pbd_e2->src_mac_addr_lo, + /* Add the macs to the parsing BD this is a vf */ + if (IS_VF(bp)) { + /* override GRE parameters in BD */ + bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, + &pbd_e2->data.mac_addr.src_mid, + &pbd_e2->data.mac_addr.src_lo, eth->h_source); - bnx2x_set_fw_mac_addr(&pbd_e2->dst_mac_addr_hi, - &pbd_e2->dst_mac_addr_mid, - &pbd_e2->dst_mac_addr_lo, + + bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi, + &pbd_e2->data.mac_addr.dst_mid, + &pbd_e2->data.mac_addr.dst_lo, eth->h_dest); } @@ -3615,14 +3606,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Setup the data pointer of the first BD of the packet */ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - nbd = 2; /* start_bd + pbd + frags (updated when pages are mapped) */ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); pkt_size = tx_start_bd->nbytes; DP(NETIF_MSG_TX_QUEUED, - "first bd @%p addr (%x:%x) nbd %d nbytes %d flags %x vlan %x\n", + "first bd @%p addr (%x:%x) nbytes %d flags %x vlan %x\n", tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, - le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), + le16_to_cpu(tx_start_bd->nbytes), tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan_or_ethertype)); @@ -3635,10 +3625,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO; - if (unlikely(skb_headlen(skb) > hlen)) + if (unlikely(skb_headlen(skb) > hlen)) { + nbd++; bd_prod = bnx2x_tx_split(bp, txdata, tx_buf, &tx_start_bd, hlen, - bd_prod, ++nbd); + bd_prod); + } if (!CHIP_IS_E1x(bp)) bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, xmit_type); @@ -3728,9 +3720,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (pbd_e2) DP(NETIF_MSG_TX_QUEUED, "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n", - pbd_e2, pbd_e2->dst_mac_addr_hi, pbd_e2->dst_mac_addr_mid, - pbd_e2->dst_mac_addr_lo, pbd_e2->src_mac_addr_hi, - pbd_e2->src_mac_addr_mid, pbd_e2->src_mac_addr_lo, + pbd_e2, + pbd_e2->data.mac_addr.dst_hi, + pbd_e2->data.mac_addr.dst_mid, + pbd_e2->data.mac_addr.dst_lo, + pbd_e2->data.mac_addr.src_hi, + pbd_e2->data.mac_addr.src_mid, + pbd_e2->data.mac_addr.src_lo, pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h index e5f808377c91..40f22c6794cd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h @@ -30,31 +30,31 @@ * IRO[138].m2) + ((sbId) * IRO[138].m3)) #define CSTORM_IGU_MODE_OFFSET (IRO[157].base) #define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[316].base + ((pfId) * IRO[316].m1)) -#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ (IRO[317].base + ((pfId) * IRO[317].m1)) +#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[318].base + ((pfId) * IRO[318].m1)) #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ - (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2)) + (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2)) #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ - (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2)) + (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2)) #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ - (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2)) + (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2)) #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ - (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2)) + (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2)) #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ - (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2)) + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2)) #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ - (IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2)) + (IRO[315].base + ((pfId) * IRO[315].m1) + ((iscsiEqId) * IRO[315].m2)) #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ - (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2)) + (IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2)) #define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[315].base + ((pfId) * IRO[315].m1)) + (IRO[316].base + ((pfId) * IRO[316].m1)) #define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[307].base + ((pfId) * IRO[307].m1)) + (IRO[308].base + ((pfId) * IRO[308].m1)) #define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[306].base + ((pfId) * IRO[306].m1)) + (IRO[307].base + ((pfId) * IRO[307].m1)) #define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[305].base + ((pfId) * IRO[305].m1)) + (IRO[306].base + ((pfId) * IRO[306].m1)) #define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ (IRO[151].base + ((funcId) * IRO[151].m1)) #define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ @@ -114,7 +114,7 @@ #define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ (IRO[268].base + ((pfId) * IRO[268].m1)) #define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ - (IRO[277].base + ((pfId) * IRO[277].m1)) + (IRO[278].base + ((pfId) * IRO[278].m1)) #define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ (IRO[264].base + ((pfId) * IRO[264].m1)) #define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ @@ -136,35 +136,32 @@ #define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[177].base) #define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \ (IRO[176].base + ((assertListEntry) * IRO[176].m1)) -#define USTORM_CQE_PAGE_NEXT_OFFSET(portId, clientId) \ - (IRO[205].base + ((portId) * IRO[205].m1) + ((clientId) * \ - IRO[205].m2)) #define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ (IRO[183].base + ((portId) * IRO[183].m1)) #define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ - (IRO[318].base + ((pfId) * IRO[318].m1)) + (IRO[319].base + ((pfId) * IRO[319].m1)) #define USTORM_FUNC_EN_OFFSET(funcId) \ (IRO[178].base + ((funcId) * IRO[178].m1)) #define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[282].base + ((pfId) * IRO[282].m1)) -#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ (IRO[283].base + ((pfId) * IRO[283].m1)) +#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[284].base + ((pfId) * IRO[284].m1)) #define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ - (IRO[287].base + ((pfId) * IRO[287].m1)) + (IRO[288].base + ((pfId) * IRO[288].m1)) #define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ - (IRO[284].base + ((pfId) * IRO[284].m1)) + (IRO[285].base + ((pfId) * IRO[285].m1)) #define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[280].base + ((pfId) * IRO[280].m1)) + (IRO[281].base + ((pfId) * IRO[281].m1)) #define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[279].base + ((pfId) * IRO[279].m1)) + (IRO[280].base + ((pfId) * IRO[280].m1)) #define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[278].base + ((pfId) * IRO[278].m1)) + (IRO[279].base + ((pfId) * IRO[279].m1)) #define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[281].base + ((pfId) * IRO[281].m1)) + (IRO[282].base + ((pfId) * IRO[282].m1)) #define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ - (IRO[285].base + ((pfId) * IRO[285].m1)) -#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ (IRO[286].base + ((pfId) * IRO[286].m1)) +#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[287].base + ((pfId) * IRO[287].m1)) #define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ (IRO[182].base + ((pfId) * IRO[182].m1)) #define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ @@ -190,39 +187,39 @@ #define XSTORM_FUNC_EN_OFFSET(funcId) \ (IRO[47].base + ((funcId) * IRO[47].m1)) #define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[295].base + ((pfId) * IRO[295].m1)) + (IRO[296].base + ((pfId) * IRO[296].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ - (IRO[298].base + ((pfId) * IRO[298].m1)) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ (IRO[299].base + ((pfId) * IRO[299].m1)) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ +#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ (IRO[300].base + ((pfId) * IRO[300].m1)) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ +#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ (IRO[301].base + ((pfId) * IRO[301].m1)) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ +#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ (IRO[302].base + ((pfId) * IRO[302].m1)) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ +#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ (IRO[303].base + ((pfId) * IRO[303].m1)) -#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ +#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ (IRO[304].base + ((pfId) * IRO[304].m1)) +#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ + (IRO[305].base + ((pfId) * IRO[305].m1)) #define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[294].base + ((pfId) * IRO[294].m1)) + (IRO[295].base + ((pfId) * IRO[295].m1)) #define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[293].base + ((pfId) * IRO[293].m1)) + (IRO[294].base + ((pfId) * IRO[294].m1)) #define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[292].base + ((pfId) * IRO[292].m1)) + (IRO[293].base + ((pfId) * IRO[293].m1)) #define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[297].base + ((pfId) * IRO[297].m1)) + (IRO[298].base + ((pfId) * IRO[298].m1)) #define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ - (IRO[296].base + ((pfId) * IRO[296].m1)) + (IRO[297].base + ((pfId) * IRO[297].m1)) #define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ - (IRO[291].base + ((pfId) * IRO[291].m1)) + (IRO[292].base + ((pfId) * IRO[292].m1)) #define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ - (IRO[290].base + ((pfId) * IRO[290].m1)) + (IRO[291].base + ((pfId) * IRO[291].m1)) #define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ - (IRO[289].base + ((pfId) * IRO[289].m1)) + (IRO[290].base + ((pfId) * IRO[290].m1)) #define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ - (IRO[288].base + ((pfId) * IRO[288].m1)) + (IRO[289].base + ((pfId) * IRO[289].m1)) #define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ (IRO[44].base + ((pfId) * IRO[44].m1)) #define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index a7a3504e1bd5..12f00a40cdf0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -114,6 +114,10 @@ struct license_key { #define EPIO_CFG_EPIO30 0x0000001f #define EPIO_CFG_EPIO31 0x00000020 +struct mac_addr { + u32 upper; + u32 lower; +}; struct shared_hw_cfg { /* NVRAM Offset */ /* Up to 16 bytes of NULL-terminated string */ @@ -2836,8 +2840,8 @@ struct afex_stats { #define BCM_5710_FW_MAJOR_VERSION 7 #define BCM_5710_FW_MINOR_VERSION 8 -#define BCM_5710_FW_REVISION_VERSION 2 -#define BCM_5710_FW_ENGINEERING_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 17 +#define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 @@ -3528,11 +3532,14 @@ struct client_init_tx_data { #define CLIENT_INIT_TX_DATA_BCAST_ACCEPT_ALL_SHIFT 2 #define CLIENT_INIT_TX_DATA_ACCEPT_ANY_VLAN (0x1<<3) #define CLIENT_INIT_TX_DATA_ACCEPT_ANY_VLAN_SHIFT 3 -#define CLIENT_INIT_TX_DATA_RESERVED1 (0xFFF<<4) -#define CLIENT_INIT_TX_DATA_RESERVED1_SHIFT 4 +#define CLIENT_INIT_TX_DATA_RESERVED0 (0xFFF<<4) +#define CLIENT_INIT_TX_DATA_RESERVED0_SHIFT 4 u8 default_vlan_flg; u8 force_default_pri_flg; - __le32 reserved3; + u8 tunnel_lso_inc_ip_id; + u8 refuse_outband_vlan_flg; + u8 tunnel_non_lso_pcsum_location; + u8 reserved1; }; /* @@ -3566,6 +3573,11 @@ struct client_update_ramrod_data { __le16 silent_vlan_mask; u8 silent_vlan_removal_flg; u8 silent_vlan_change_flg; + u8 refuse_outband_vlan_flg; + u8 refuse_outband_vlan_change_flg; + u8 tx_switching_flg; + u8 tx_switching_change_flg; + __le32 reserved1; __le32 echo; }; @@ -3635,7 +3647,8 @@ struct eth_classify_header { */ struct eth_classify_mac_cmd { struct eth_classify_cmd_header header; - __le32 reserved0; + __le16 reserved0; + __le16 inner_mac; __le16 mac_lsb; __le16 mac_mid; __le16 mac_msb; @@ -3648,7 +3661,8 @@ struct eth_classify_mac_cmd { */ struct eth_classify_pair_cmd { struct eth_classify_cmd_header header; - __le32 reserved0; + __le16 reserved0; + __le16 inner_mac; __le16 mac_lsb; __le16 mac_mid; __le16 mac_msb; @@ -3870,8 +3884,68 @@ struct eth_halt_ramrod_data { /* - * Command for setting multicast classification for a client + * destination and source mac address. + */ +struct eth_mac_addresses { +#if defined(__BIG_ENDIAN) + __le16 dst_mid; + __le16 dst_lo; +#elif defined(__LITTLE_ENDIAN) + __le16 dst_lo; + __le16 dst_mid; +#endif +#if defined(__BIG_ENDIAN) + __le16 src_lo; + __le16 dst_hi; +#elif defined(__LITTLE_ENDIAN) + __le16 dst_hi; + __le16 src_lo; +#endif +#if defined(__BIG_ENDIAN) + __le16 src_hi; + __le16 src_mid; +#elif defined(__LITTLE_ENDIAN) + __le16 src_mid; + __le16 src_hi; +#endif +}; + +/* tunneling related data */ +struct eth_tunnel_data { +#if defined(__BIG_ENDIAN) + __le16 dst_mid; + __le16 dst_lo; +#elif defined(__LITTLE_ENDIAN) + __le16 dst_lo; + __le16 dst_mid; +#endif +#if defined(__BIG_ENDIAN) + __le16 reserved0; + __le16 dst_hi; +#elif defined(__LITTLE_ENDIAN) + __le16 dst_hi; + __le16 reserved0; +#endif +#if defined(__BIG_ENDIAN) + u8 reserved1; + u8 ip_hdr_start_inner_w; + __le16 pseudo_csum; +#elif defined(__LITTLE_ENDIAN) + __le16 pseudo_csum; + u8 ip_hdr_start_inner_w; + u8 reserved1; +#endif +}; + +/* union for mac addresses and for tunneling data. + * considered as tunneling data only if (tunnel_exist == 1). */ +union eth_mac_addr_or_tunnel_data { + struct eth_mac_addresses mac_addr; + struct eth_tunnel_data tunnel_data; +}; + +/*Command for setting multicast classification for a client */ struct eth_multicast_rules_cmd { u8 cmd_general_data; #define ETH_MULTICAST_RULES_CMD_RX_CMD (0x1<<0) @@ -3889,7 +3963,6 @@ struct eth_multicast_rules_cmd { struct regpair reserved3; }; - /* * parameters for multicast classification ramrod */ @@ -3898,7 +3971,6 @@ struct eth_multicast_rules_ramrod_data { struct eth_multicast_rules_cmd rules[MULTICAST_RULES_COUNT]; }; - /* * Place holder for ramrods protocol specific data */ @@ -3962,11 +4034,14 @@ struct eth_rss_update_ramrod_data { #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY_SHIFT 4 #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY (0x1<<5) #define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY_SHIFT 5 +#define ETH_RSS_UPDATE_RAMROD_DATA_EN_5_TUPLE_CAPABILITY (0x1<<6) +#define ETH_RSS_UPDATE_RAMROD_DATA_EN_5_TUPLE_CAPABILITY_SHIFT 6 #define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY (0x1<<7) #define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY_SHIFT 7 u8 rss_result_mask; u8 rss_mode; - __le32 __reserved2; + __le16 udp_4tuple_dst_port_mask; + __le16 udp_4tuple_dst_port_value; u8 indirection_table[T_ETH_INDIRECTION_TABLE_SIZE]; __le32 rss_key[T_ETH_RSS_KEY]; __le32 echo; @@ -4130,6 +4205,23 @@ enum eth_tpa_update_command { MAX_ETH_TPA_UPDATE_COMMAND }; +/* In case of LSO over IPv4 tunnel, whether to increment + * IP ID on external IP header or internal IP header + */ +enum eth_tunnel_lso_inc_ip_id { + EXT_HEADER, + INT_HEADER, + MAX_ETH_TUNNEL_LSO_INC_IP_ID +}; + +/* In case tunnel exist and L4 checksum offload, + * the pseudo checksum location, on packet or on BD. + */ +enum eth_tunnel_non_lso_pcsum_location { + PCSUM_ON_PKT, + PCSUM_ON_BD, + MAX_ETH_TUNNEL_NON_LSO_PCSUM_LOCATION +}; /* * Tx regular BD structure @@ -4181,8 +4273,8 @@ struct eth_tx_start_bd { #define ETH_TX_START_BD_FORCE_VLAN_MODE_SHIFT 4 #define ETH_TX_START_BD_PARSE_NBDS (0x3<<5) #define ETH_TX_START_BD_PARSE_NBDS_SHIFT 5 -#define ETH_TX_START_BD_RESREVED (0x1<<7) -#define ETH_TX_START_BD_RESREVED_SHIFT 7 +#define ETH_TX_START_BD_TUNNEL_EXIST (0x1<<7) +#define ETH_TX_START_BD_TUNNEL_EXIST_SHIFT 7 }; /* @@ -4231,15 +4323,10 @@ struct eth_tx_parse_bd_e1x { * Tx parsing BD structure for ETH E2 */ struct eth_tx_parse_bd_e2 { - __le16 dst_mac_addr_lo; - __le16 dst_mac_addr_mid; - __le16 dst_mac_addr_hi; - __le16 src_mac_addr_lo; - __le16 src_mac_addr_mid; - __le16 src_mac_addr_hi; + union eth_mac_addr_or_tunnel_data data; __le32 parsing_data; -#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x7FF<<0) -#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W (0x7FF<<0) +#define ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W_SHIFT 0 #define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<11) #define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 11 #define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<15) @@ -4251,8 +4338,51 @@ struct eth_tx_parse_bd_e2 { }; /* - * The last BD in the BD memory will hold a pointer to the next BD memory + * Tx 2nd parsing BD structure for ETH packet */ +struct eth_tx_parse_2nd_bd { + __le16 global_data; +#define ETH_TX_PARSE_2ND_BD_IP_HDR_START_OUTER_W (0xF<<0) +#define ETH_TX_PARSE_2ND_BD_IP_HDR_START_OUTER_W_SHIFT 0 +#define ETH_TX_PARSE_2ND_BD_IP_HDR_TYPE_OUTER (0x1<<4) +#define ETH_TX_PARSE_2ND_BD_IP_HDR_TYPE_OUTER_SHIFT 4 +#define ETH_TX_PARSE_2ND_BD_LLC_SNAP_EN (0x1<<5) +#define ETH_TX_PARSE_2ND_BD_LLC_SNAP_EN_SHIFT 5 +#define ETH_TX_PARSE_2ND_BD_NS_FLG (0x1<<6) +#define ETH_TX_PARSE_2ND_BD_NS_FLG_SHIFT 6 +#define ETH_TX_PARSE_2ND_BD_TUNNEL_UDP_EXIST (0x1<<7) +#define ETH_TX_PARSE_2ND_BD_TUNNEL_UDP_EXIST_SHIFT 7 +#define ETH_TX_PARSE_2ND_BD_IP_HDR_LEN_OUTER_W (0x1F<<8) +#define ETH_TX_PARSE_2ND_BD_IP_HDR_LEN_OUTER_W_SHIFT 8 +#define ETH_TX_PARSE_2ND_BD_RESERVED0 (0x7<<13) +#define ETH_TX_PARSE_2ND_BD_RESERVED0_SHIFT 13 + __le16 reserved1; + u8 tcp_flags; +#define ETH_TX_PARSE_2ND_BD_FIN_FLG (0x1<<0) +#define ETH_TX_PARSE_2ND_BD_FIN_FLG_SHIFT 0 +#define ETH_TX_PARSE_2ND_BD_SYN_FLG (0x1<<1) +#define ETH_TX_PARSE_2ND_BD_SYN_FLG_SHIFT 1 +#define ETH_TX_PARSE_2ND_BD_RST_FLG (0x1<<2) +#define ETH_TX_PARSE_2ND_BD_RST_FLG_SHIFT 2 +#define ETH_TX_PARSE_2ND_BD_PSH_FLG (0x1<<3) +#define ETH_TX_PARSE_2ND_BD_PSH_FLG_SHIFT 3 +#define ETH_TX_PARSE_2ND_BD_ACK_FLG (0x1<<4) +#define ETH_TX_PARSE_2ND_BD_ACK_FLG_SHIFT 4 +#define ETH_TX_PARSE_2ND_BD_URG_FLG (0x1<<5) +#define ETH_TX_PARSE_2ND_BD_URG_FLG_SHIFT 5 +#define ETH_TX_PARSE_2ND_BD_ECE_FLG (0x1<<6) +#define ETH_TX_PARSE_2ND_BD_ECE_FLG_SHIFT 6 +#define ETH_TX_PARSE_2ND_BD_CWR_FLG (0x1<<7) +#define ETH_TX_PARSE_2ND_BD_CWR_FLG_SHIFT 7 + u8 reserved2; + u8 tunnel_udp_hdr_start_w; + u8 fw_ip_hdr_to_payload_w; + __le16 fw_ip_csum_wo_len_flags_frag; + __le16 hw_ip_id; + __le32 tcp_send_seq; +}; + +/* The last BD in the BD memory will hold a pointer to the next BD memory */ struct eth_tx_next_bd { __le32 addr_lo; __le32 addr_hi; @@ -4267,6 +4397,7 @@ union eth_tx_bd_types { struct eth_tx_bd reg_bd; struct eth_tx_parse_bd_e1x parse_bd_e1x; struct eth_tx_parse_bd_e2 parse_bd_e2; + struct eth_tx_parse_2nd_bd parse_2nd_bd; struct eth_tx_next_bd next_bd; }; @@ -4678,10 +4809,10 @@ enum common_spqe_cmd_id { RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, RAMROD_CMD_ID_COMMON_START_TRAFFIC, RAMROD_CMD_ID_COMMON_AFEX_VIF_LISTS, + RAMROD_CMD_ID_COMMON_SET_TIMESYNC, MAX_COMMON_SPQE_CMD_ID }; - /* * Per-protocol connection types */ @@ -4878,7 +5009,7 @@ struct vf_flr_event_data { */ struct malicious_vf_event_data { u8 vf_id; - u8 reserved0; + u8 err_id; u16 reserved1; u32 reserved2; u32 reserved3; @@ -4984,10 +5115,10 @@ enum event_ring_opcode { EVENT_RING_OPCODE_CLASSIFICATION_RULES, EVENT_RING_OPCODE_FILTERS_RULES, EVENT_RING_OPCODE_MULTICAST_RULES, + EVENT_RING_OPCODE_SET_TIMESYNC, MAX_EVENT_RING_OPCODE }; - /* * Modes for fairness algorithm */ @@ -5025,14 +5156,18 @@ struct flow_control_configuration { */ struct function_start_data { u8 function_mode; - u8 reserved; + u8 allow_npar_tx_switching; __le16 sd_vlan_tag; __le16 vif_id; u8 path_id; u8 network_cos_mode; + u8 dmae_cmd_id; + u8 gre_tunnel_mode; + u8 gre_tunnel_rss; + u8 nvgre_clss_en; + __le16 reserved1[2]; }; - struct function_update_data { u8 vif_id_change_flg; u8 afex_default_vlan_change_flg; @@ -5042,14 +5177,19 @@ struct function_update_data { __le16 afex_default_vlan; u8 allowed_priorities; u8 network_cos_mode; + u8 lb_mode_en_change_flg; u8 lb_mode_en; u8 tx_switch_suspend_change_flg; u8 tx_switch_suspend; u8 echo; - __le16 reserved1; + u8 reserved1; + u8 update_gre_cfg_flg; + u8 gre_tunnel_mode; + u8 gre_tunnel_rss; + u8 nvgre_clss_en; + u32 reserved3; }; - /* * FW version stored in the Xstorm RAM */ @@ -5076,6 +5216,22 @@ struct fw_version { #define __FW_VERSION_RESERVED_SHIFT 4 }; +/* GRE RSS Mode */ +enum gre_rss_mode { + GRE_OUTER_HEADERS_RSS, + GRE_INNER_HEADERS_RSS, + NVGRE_KEY_ENTROPY_RSS, + MAX_GRE_RSS_MODE +}; + +/* GRE Tunnel Mode */ +enum gre_tunnel_type { + NO_GRE_TUNNEL, + NVGRE_TUNNEL, + L2GRE_TUNNEL, + IPGRE_TUNNEL, + MAX_GRE_TUNNEL_TYPE +}; /* * Dynamic Host-Coalescing - Driver(host) counters @@ -5239,6 +5395,26 @@ enum ip_ver { MAX_IP_VER }; +/* + * Malicious VF error ID + */ +enum malicious_vf_error_id { + VF_PF_CHANNEL_NOT_READY, + ETH_ILLEGAL_BD_LENGTHS, + ETH_PACKET_TOO_SHORT, + ETH_PAYLOAD_TOO_BIG, + ETH_ILLEGAL_ETH_TYPE, + ETH_ILLEGAL_LSO_HDR_LEN, + ETH_TOO_MANY_BDS, + ETH_ZERO_HDR_NBDS, + ETH_START_BD_NOT_SET, + ETH_ILLEGAL_PARSE_NBDS, + ETH_IPV6_AND_CHECKSUM, + ETH_VLAN_FLG_INCORRECT, + ETH_ILLEGAL_LSO_MSS, + ETH_TUNNEL_NOT_SUPPORTED, + MAX_MALICIOUS_VF_ERROR_ID +}; /* * Multi-function modes @@ -5383,7 +5559,6 @@ struct protocol_common_spe { union protocol_common_specific_data data; }; - /* * The send queue element */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e5662a141451..c7df223d7a10 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -2953,14 +2953,15 @@ static unsigned long bnx2x_get_common_flags(struct bnx2x *bp, __set_bit(BNX2X_Q_FLG_ACTIVE, &flags); /* tx only connections collect statistics (on the same index as the - * parent connection). The statistics are zeroed when the parent - * connection is initialized. + * parent connection). The statistics are zeroed when the parent + * connection is initialized. */ __set_bit(BNX2X_Q_FLG_STATS, &flags); if (zero_stats) __set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags); + __set_bit(BNX2X_Q_FLG_PCSUM_ON_PKT, &flags); #ifdef BNX2X_STOP_ON_ERROR __set_bit(BNX2X_Q_FLG_TX_SEC, &flags); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 6b03acd5d9ad..66ab25908086 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -476,7 +476,8 @@ static int bnx2x_check_mac_add(struct bnx2x *bp, /* Check if a requested MAC already exists */ list_for_each_entry(pos, &o->head, link) - if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) + if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN) && + (data->mac.is_inner_mac == pos->u.mac.is_inner_mac)) return -EEXIST; return 0; @@ -509,7 +510,9 @@ static int bnx2x_check_vlan_mac_add(struct bnx2x *bp, list_for_each_entry(pos, &o->head, link) if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, - ETH_ALEN))) + ETH_ALEN)) && + (data->vlan_mac.is_inner_mac == + pos->u.vlan_mac.is_inner_mac)) return -EEXIST; return 0; @@ -527,7 +530,8 @@ static struct bnx2x_vlan_mac_registry_elem * DP(BNX2X_MSG_SP, "Checking MAC %pM for DEL command\n", data->mac.mac); list_for_each_entry(pos, &o->head, link) - if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) + if ((!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) && + (data->mac.is_inner_mac == pos->u.mac.is_inner_mac)) return pos; return NULL; @@ -562,7 +566,9 @@ static struct bnx2x_vlan_mac_registry_elem * list_for_each_entry(pos, &o->head, link) if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, - ETH_ALEN))) + ETH_ALEN)) && + (data->vlan_mac.is_inner_mac == + pos->u.vlan_mac.is_inner_mac)) return pos; return NULL; @@ -759,6 +765,8 @@ static void bnx2x_set_one_mac_e2(struct bnx2x *bp, bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, &rule_entry->mac.mac_mid, &rule_entry->mac.mac_lsb, mac); + rule_entry->mac.inner_mac = + cpu_to_le16(elem->cmd_data.vlan_mac.u.mac.is_inner_mac); /* MOVE: Add a rule that will add this MAC to the target Queue */ if (cmd == BNX2X_VLAN_MAC_MOVE) { @@ -775,6 +783,9 @@ static void bnx2x_set_one_mac_e2(struct bnx2x *bp, bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, &rule_entry->mac.mac_mid, &rule_entry->mac.mac_lsb, mac); + rule_entry->mac.inner_mac = + cpu_to_le16(elem->cmd_data.vlan_mac. + u.mac.is_inner_mac); } /* Set the ramrod data header */ @@ -963,7 +974,8 @@ static void bnx2x_set_one_vlan_mac_e2(struct bnx2x *bp, bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, &rule_entry->pair.mac_mid, &rule_entry->pair.mac_lsb, mac); - + rule_entry->pair.inner_mac = + cpu_to_le16(elem->cmd_data.vlan_mac.u.vlan_mac.is_inner_mac); /* MOVE: Add a rule that will add this MAC to the target Queue */ if (cmd == BNX2X_VLAN_MAC_MOVE) { rule_entry++; @@ -980,6 +992,9 @@ static void bnx2x_set_one_vlan_mac_e2(struct bnx2x *bp, bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, &rule_entry->pair.mac_mid, &rule_entry->pair.mac_lsb, mac); + rule_entry->pair.inner_mac = + cpu_to_le16(elem->cmd_data.vlan_mac.u. + vlan_mac.is_inner_mac); } /* Set the ramrod data header */ @@ -4417,6 +4432,10 @@ static void bnx2x_q_fill_init_tx_data(struct bnx2x_queue_sp_obj *o, tx_data->force_default_pri_flg = test_bit(BNX2X_Q_FLG_FORCE_DEFAULT_PRI, flags); + tx_data->tunnel_non_lso_pcsum_location = + test_bit(BNX2X_Q_FLG_PCSUM_ON_PKT, flags) ? PCSUM_ON_PKT : + PCSUM_ON_BD; + tx_data->tx_status_block_id = params->fw_sb_id; tx_data->tx_sb_index_number = params->sb_cq_index; tx_data->tss_leading_client_id = params->tss_leading_cl_id; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index ac57e63a08ed..064dba24610d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -100,6 +100,7 @@ struct bnx2x_raw_obj { /************************* VLAN-MAC commands related parameters ***************/ struct bnx2x_mac_ramrod_data { u8 mac[ETH_ALEN]; + u8 is_inner_mac; }; struct bnx2x_vlan_ramrod_data { @@ -108,6 +109,7 @@ struct bnx2x_vlan_ramrod_data { struct bnx2x_vlan_mac_ramrod_data { u8 mac[ETH_ALEN]; + u8 is_inner_mac; u16 vlan; }; @@ -825,7 +827,8 @@ enum { BNX2X_Q_FLG_TX_SEC, BNX2X_Q_FLG_ANTI_SPOOF, BNX2X_Q_FLG_SILENT_VLAN_REM, - BNX2X_Q_FLG_FORCE_DEFAULT_PRI + BNX2X_Q_FLG_FORCE_DEFAULT_PRI, + BNX2X_Q_FLG_PCSUM_ON_PKT }; /* Queue type options: queue type may be a compination of below. */ -- cgit From 704ba4b7778f60e0a22108ebda3f7f6dba32ab9a Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 11 Mar 2013 05:17:53 +0000 Subject: bnx2x: Restore FCoE 4-port devices support bnx2x FW 1.78.17 properly supports DCBX configuration for 4-port devices, enabling FCoE support on 57840 boards. Signed-off-by: Dmitry Kravkov Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c7df223d7a10..04d123ff11a2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12492,16 +12492,6 @@ static int bnx2x_init_one(struct pci_dev *pdev, if (CHIP_IS_E1x(bp)) bp->flags |= NO_FCOE_FLAG; - /* disable FCOE for 57840 device, until FW supports it */ - switch (ent->driver_data) { - case BCM57840_O: - case BCM57840_4_10: - case BCM57840_2_20: - case BCM57840_MFO: - case BCM57840_MF: - bp->flags |= NO_FCOE_FLAG; - } - /* Set bp->num_queues for MSI-X mode*/ bnx2x_set_num_queues(bp); -- cgit From 2e3a118f82a64f55a5cd0b44b6c00a884cad4ff9 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 04:29:50 +0000 Subject: qlcnic: remove duplicated include from qlcnic_sysfs.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 987fb6f8adc3..4e464dcfcb3f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -21,8 +21,6 @@ #include #include -#include - #define QLC_STATUS_UNSUPPORTED_CMD -2 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) -- cgit From 3a918f4036f5c4689a091c2b9affcca2066803ee Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 04:40:14 +0000 Subject: bnx2x: use list_move instead of list_del/list_add Using list_move() instead of list_del() + list_add(). Signed-off-by: Wei Yongjun Acked-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index df930e30e1b1..faadd153f7ad 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -557,8 +557,7 @@ static int bnx2x_vfop_config_list(struct bnx2x *bp, rc = bnx2x_config_vlan_mac(bp, vlan_mac); if (rc >= 0) { cnt += pos->add ? 1 : -1; - list_del(&pos->link); - list_add(&pos->link, &rollback_list); + list_move(&pos->link, &rollback_list); rc = 0; } else if (rc == -EEXIST) { rc = 0; -- cgit From a2e4b59a71d9178f68a970ee423cbde68b70fa74 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Mar 2013 07:32:54 +0000 Subject: fec: Remove unused pci header PCI header is not needed, so get rid of it. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index f97c60f78089..46e6bc0150ea 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit From 83e519b63480e691d43ee106547b10941bfa0232 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Mar 2013 07:32:55 +0000 Subject: fec: Use devm_request_and_ioremap() Using devm_request_and_ioremap() can make the code cleaner and simpler. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 46e6bc0150ea..e6224949891f 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1731,16 +1731,10 @@ fec_probe(struct platform_device *pdev) if (!r) return -ENXIO; - r = request_mem_region(r->start, resource_size(r), pdev->name); - if (!r) - return -EBUSY; - /* Init network device */ ndev = alloc_etherdev(sizeof(struct fec_enet_private)); - if (!ndev) { - ret = -ENOMEM; - goto failed_alloc_etherdev; - } + if (!ndev) + return -ENOMEM; SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1752,7 +1746,7 @@ fec_probe(struct platform_device *pdev) (pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT)) fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG; - fep->hwp = ioremap(r->start, resource_size(r)); + fep->hwp = devm_request_and_ioremap(&pdev->dev, r); fep->pdev = pdev; fep->dev_id = dev_id++; @@ -1874,11 +1868,8 @@ failed_regulator: clk_disable_unprepare(fep->clk_ptp); failed_pin: failed_clk: - iounmap(fep->hwp); failed_ioremap: free_netdev(ndev); -failed_alloc_etherdev: - release_mem_region(r->start, resource_size(r)); return ret; } @@ -1888,7 +1879,6 @@ fec_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); - struct resource *r; int i; unregister_netdev(ndev); @@ -1904,13 +1894,8 @@ fec_drv_remove(struct platform_device *pdev) if (irq > 0) free_irq(irq, ndev); } - iounmap(fep->hwp); free_netdev(ndev); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - BUG_ON(!r); - release_mem_region(r->start, resource_size(r)); - platform_set_drvdata(pdev, NULL); return 0; -- cgit From a38884f681a4d044befd30d9f3d19a0821bae63a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Mar 2013 10:15:43 +0200 Subject: videomode: simplify videomode Kconfig and Makefile This patch simplifies videomode related Kconfig and Makefile. After this patch, there's only one non-user selectable Kconfig option left, VIDEOMODE_HELPERS. The reasons for the change: * Videomode helper functions are not something that should be shown in the kernel configuration options. The related code should just be included if it's needed, i.e. selected by drivers using videomode. * There's no need to have separate Kconfig options for videomode and display_timing. First of all, the amount of code for both is quite small. Second, videomode depends on display_timing, and display_timing in itself is not really useful, so both would be included in any case. * CONFIG_VIDEOMODE is a bit vague name, and CONFIG_VIDEOMODE_HELPERS describes better what's included. Signed-off-by: Tomi Valkeinen Cc: Steffen Trumtrar Acked-by: Laurent Pinchart --- drivers/gpu/drm/drm_modes.c | 8 ++++---- drivers/gpu/drm/tilcdc/Kconfig | 3 +-- drivers/video/Kconfig | 22 ++-------------------- drivers/video/Makefile | 8 ++++---- drivers/video/fbmon.c | 8 ++++---- 5 files changed, 15 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 04fa6f1808d1..0698c0e9bc26 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -506,7 +506,7 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, } EXPORT_SYMBOL(drm_gtf_mode); -#if IS_ENABLED(CONFIG_VIDEOMODE) +#ifdef CONFIG_VIDEOMODE_HELPERS int drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode) { @@ -540,9 +540,8 @@ int drm_display_mode_from_videomode(const struct videomode *vm, return 0; } EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode); -#endif -#if IS_ENABLED(CONFIG_OF_VIDEOMODE) +#ifdef CONFIG_OF /** * of_get_drm_display_mode - get a drm_display_mode from devicetree * @np: device_node with the timing specification @@ -572,7 +571,8 @@ int of_get_drm_display_mode(struct device_node *np, return 0; } EXPORT_SYMBOL_GPL(of_get_drm_display_mode); -#endif +#endif /* CONFIG_OF */ +#endif /* CONFIG_VIDEOMODE_HELPERS */ /** * drm_mode_set_name - set the name on a mode diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig index d24d04013476..e461e9972455 100644 --- a/drivers/gpu/drm/tilcdc/Kconfig +++ b/drivers/gpu/drm/tilcdc/Kconfig @@ -4,8 +4,7 @@ config DRM_TILCDC select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER - select OF_VIDEOMODE - select OF_DISPLAY_TIMING + select VIDEOMODE_HELPERS select BACKLIGHT_CLASS_DEVICE help Choose this option if you have an TI SoC with LCDC display diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4c1546f71d56..2a81b11367fe 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -31,26 +31,8 @@ config VIDEO_OUTPUT_CONTROL This framework adds support for low-level control of the video output switch. -config DISPLAY_TIMING - bool - -config VIDEOMODE - bool - -config OF_DISPLAY_TIMING - bool "Enable device tree display timing support" - depends on OF - select DISPLAY_TIMING - help - helper to parse display timings from the devicetree - -config OF_VIDEOMODE - bool "Enable device tree videomode support" - depends on OF - select VIDEOMODE - select OF_DISPLAY_TIMING - help - helper to get videomodes from the devicetree +config VIDEOMODE_HELPERS + bool config HDMI bool diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 9df387334cb7..e414378d6a51 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -171,7 +171,7 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o #video output switch sysfs driver obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o -obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o -obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o -obj-$(CONFIG_VIDEOMODE) += videomode.o -obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o +obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o +ifeq ($(CONFIG_OF),y) +obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o +endif diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 94ad0f71383c..368cedfeaf1d 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1376,7 +1376,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf return err; } -#if IS_ENABLED(CONFIG_VIDEOMODE) +#ifdef CONFIG_VIDEOMODE_HELPERS int fb_videomode_from_videomode(const struct videomode *vm, struct fb_videomode *fbmode) { @@ -1424,9 +1424,8 @@ int fb_videomode_from_videomode(const struct videomode *vm, return 0; } EXPORT_SYMBOL_GPL(fb_videomode_from_videomode); -#endif -#if IS_ENABLED(CONFIG_OF_VIDEOMODE) +#ifdef CONFIG_OF static inline void dump_fb_videomode(const struct fb_videomode *m) { pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n", @@ -1465,7 +1464,8 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb, return 0; } EXPORT_SYMBOL_GPL(of_get_fb_videomode); -#endif +#endif /* CONFIG_OF */ +#endif /* CONFIG_VIDEOMODE_HELPERS */ #else int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) -- cgit From 06a3307975aac2d5b5a0e0f2e05d23e769f176b4 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Mar 2013 10:26:45 +0200 Subject: videomode: combine videomode dmt_flags and data_flags Both videomode and display_timing contain flags describing the modes. These are stored in dmt_flags and data_flags. There's no need to separate these flags, and having separate fields just makes the flags more difficult to use. This patch combines the fields and renames VESA_DMT_* flags to DISPLAY_FLAGS_*. Signed-off-by: Tomi Valkeinen Cc: Steffen Trumtrar --- drivers/gpu/drm/drm_modes.c | 12 ++++++------ drivers/video/fbmon.c | 8 ++++---- drivers/video/of_display_timing.c | 19 +++++++++---------- drivers/video/videomode.c | 3 +-- include/video/display_timing.h | 26 +++++++++++--------------- include/video/videomode.h | 3 +-- 6 files changed, 32 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 0698c0e9bc26..f83f0719922e 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -523,17 +523,17 @@ int drm_display_mode_from_videomode(const struct videomode *vm, dmode->clock = vm->pixelclock / 1000; dmode->flags = 0; - if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) + if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) dmode->flags |= DRM_MODE_FLAG_PHSYNC; - else if (vm->dmt_flags & VESA_DMT_HSYNC_LOW) + else if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW) dmode->flags |= DRM_MODE_FLAG_NHSYNC; - if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH) + if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH) dmode->flags |= DRM_MODE_FLAG_PVSYNC; - else if (vm->dmt_flags & VESA_DMT_VSYNC_LOW) + else if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW) dmode->flags |= DRM_MODE_FLAG_NVSYNC; - if (vm->data_flags & DISPLAY_FLAGS_INTERLACED) + if (vm->flags & DISPLAY_FLAGS_INTERLACED) dmode->flags |= DRM_MODE_FLAG_INTERLACE; - if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN) + if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN) dmode->flags |= DRM_MODE_FLAG_DBLSCAN; drm_mode_set_name(dmode); diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 368cedfeaf1d..e5cc2fdb4c8d 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1398,13 +1398,13 @@ int fb_videomode_from_videomode(const struct videomode *vm, fbmode->sync = 0; fbmode->vmode = 0; - if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) + if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) fbmode->sync |= FB_SYNC_HOR_HIGH_ACT; - if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) + if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH) fbmode->sync |= FB_SYNC_VERT_HIGH_ACT; - if (vm->data_flags & DISPLAY_FLAGS_INTERLACED) + if (vm->flags & DISPLAY_FLAGS_INTERLACED) fbmode->vmode |= FB_VMODE_INTERLACED; - if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN) + if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN) fbmode->vmode |= FB_VMODE_DOUBLE; fbmode->flag = 0; diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 13ecd9897010..56009bc02b02 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -79,25 +79,24 @@ static struct display_timing *of_get_display_timing(struct device_node *np) ret |= parse_timing_property(np, "vsync-len", &dt->vsync_len); ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock); - dt->dmt_flags = 0; - dt->data_flags = 0; + dt->flags = 0; if (!of_property_read_u32(np, "vsync-active", &val)) - dt->dmt_flags |= val ? VESA_DMT_VSYNC_HIGH : - VESA_DMT_VSYNC_LOW; + dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH : + DISPLAY_FLAGS_VSYNC_LOW; if (!of_property_read_u32(np, "hsync-active", &val)) - dt->dmt_flags |= val ? VESA_DMT_HSYNC_HIGH : - VESA_DMT_HSYNC_LOW; + dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH : + DISPLAY_FLAGS_HSYNC_LOW; if (!of_property_read_u32(np, "de-active", &val)) - dt->data_flags |= val ? DISPLAY_FLAGS_DE_HIGH : + dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH : DISPLAY_FLAGS_DE_LOW; if (!of_property_read_u32(np, "pixelclk-active", &val)) - dt->data_flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : + dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : DISPLAY_FLAGS_PIXDATA_NEGEDGE; if (of_property_read_bool(np, "interlaced")) - dt->data_flags |= DISPLAY_FLAGS_INTERLACED; + dt->flags |= DISPLAY_FLAGS_INTERLACED; if (of_property_read_bool(np, "doublescan")) - dt->data_flags |= DISPLAY_FLAGS_DOUBLESCAN; + dt->flags |= DISPLAY_FLAGS_DOUBLESCAN; if (ret) { pr_err("%s: error reading timing properties\n", diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c index 21c47a202afa..810afff79bc1 100644 --- a/drivers/video/videomode.c +++ b/drivers/video/videomode.c @@ -31,8 +31,7 @@ int videomode_from_timing(const struct display_timings *disp, vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP); vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP); - vm->dmt_flags = dt->dmt_flags; - vm->data_flags = dt->data_flags; + vm->flags = dt->flags; return 0; } diff --git a/include/video/display_timing.h b/include/video/display_timing.h index 71e9a383a981..a8a4be5b0af7 100644 --- a/include/video/display_timing.h +++ b/include/video/display_timing.h @@ -12,19 +12,16 @@ #include #include -/* VESA display monitor timing parameters */ -#define VESA_DMT_HSYNC_LOW BIT(0) -#define VESA_DMT_HSYNC_HIGH BIT(1) -#define VESA_DMT_VSYNC_LOW BIT(2) -#define VESA_DMT_VSYNC_HIGH BIT(3) - -/* display specific flags */ -#define DISPLAY_FLAGS_DE_LOW BIT(0) /* data enable flag */ -#define DISPLAY_FLAGS_DE_HIGH BIT(1) -#define DISPLAY_FLAGS_PIXDATA_POSEDGE BIT(2) /* drive data on pos. edge */ -#define DISPLAY_FLAGS_PIXDATA_NEGEDGE BIT(3) /* drive data on neg. edge */ -#define DISPLAY_FLAGS_INTERLACED BIT(4) -#define DISPLAY_FLAGS_DOUBLESCAN BIT(5) +#define DISPLAY_FLAGS_HSYNC_LOW BIT(0) +#define DISPLAY_FLAGS_HSYNC_HIGH BIT(1) +#define DISPLAY_FLAGS_VSYNC_LOW BIT(2) +#define DISPLAY_FLAGS_VSYNC_HIGH BIT(3) +#define DISPLAY_FLAGS_DE_LOW BIT(4) /* data enable flag */ +#define DISPLAY_FLAGS_DE_HIGH BIT(5) +#define DISPLAY_FLAGS_PIXDATA_POSEDGE BIT(6) /* drive data on pos. edge */ +#define DISPLAY_FLAGS_PIXDATA_NEGEDGE BIT(7) /* drive data on neg. edge */ +#define DISPLAY_FLAGS_INTERLACED BIT(8) +#define DISPLAY_FLAGS_DOUBLESCAN BIT(9) /* * A single signal can be specified via a range of minimal and maximal values @@ -72,8 +69,7 @@ struct display_timing { struct timing_entry vback_porch; /* ver. back porch */ struct timing_entry vsync_len; /* ver. sync len */ - unsigned int dmt_flags; /* VESA DMT flags */ - unsigned int data_flags; /* video data flags */ + unsigned int flags; /* display flags */ }; /* diff --git a/include/video/videomode.h b/include/video/videomode.h index a42156234dd4..f4ae6edfeb08 100644 --- a/include/video/videomode.h +++ b/include/video/videomode.h @@ -29,8 +29,7 @@ struct videomode { u32 vback_porch; u32 vsync_len; - unsigned int dmt_flags; /* VESA DMT flags */ - unsigned int data_flags; /* video data flags */ + unsigned int flags; /* display flags */ }; /** -- cgit From 694f050650798b82f2c7b9983e80117d58b34bf3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Mar 2013 10:35:16 +0200 Subject: videomode: remove timing_entry_index Display timing's fields have minimum, typical and maximum values. These can be accessed by using timing_entry_index enum, and display_timing_get_value() function. There's no real need for this extra complexity. The values can be accessed more easily by just using the min/typ/max fields. Signed-off-by: Tomi Valkeinen Cc: Steffen Trumtrar --- drivers/video/videomode.c | 18 +++++++++--------- include/video/display_timing.h | 25 ------------------------- 2 files changed, 9 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c index 810afff79bc1..a3d95f263cd5 100644 --- a/drivers/video/videomode.c +++ b/drivers/video/videomode.c @@ -20,16 +20,16 @@ int videomode_from_timing(const struct display_timings *disp, if (!dt) return -EINVAL; - vm->pixelclock = display_timing_get_value(&dt->pixelclock, TE_TYP); - vm->hactive = display_timing_get_value(&dt->hactive, TE_TYP); - vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, TE_TYP); - vm->hback_porch = display_timing_get_value(&dt->hback_porch, TE_TYP); - vm->hsync_len = display_timing_get_value(&dt->hsync_len, TE_TYP); + vm->pixelclock = dt->pixelclock.typ; + vm->hactive = dt->hactive.typ; + vm->hfront_porch = dt->hfront_porch.typ; + vm->hback_porch = dt->hback_porch.typ; + vm->hsync_len = dt->hsync_len.typ; - vm->vactive = display_timing_get_value(&dt->vactive, TE_TYP); - vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, TE_TYP); - vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP); - vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP); + vm->vactive = dt->vactive.typ; + vm->vfront_porch = dt->vfront_porch.typ; + vm->vback_porch = dt->vback_porch.typ; + vm->vsync_len = dt->vsync_len.typ; vm->flags = dt->flags; diff --git a/include/video/display_timing.h b/include/video/display_timing.h index b63471d14097..5d0259b08e01 100644 --- a/include/video/display_timing.h +++ b/include/video/display_timing.h @@ -39,12 +39,6 @@ struct timing_entry { u32 max; }; -enum timing_entry_index { - TE_MIN = 0, - TE_TYP = 1, - TE_MAX = 2, -}; - /* * Single "mode" entry. This describes one set of signal timings a display can * have in one setting. This struct can later be converted to struct videomode @@ -91,25 +85,6 @@ struct display_timings { struct display_timing **timings; }; -/* get value specified by index from struct timing_entry */ -static inline u32 display_timing_get_value(const struct timing_entry *te, - enum timing_entry_index index) -{ - switch (index) { - case TE_MIN: - return te->min; - break; - case TE_TYP: - return te->typ; - break; - case TE_MAX: - return te->max; - break; - default: - return te->typ; - } -} - /* get one entry from struct display_timings */ static inline struct display_timing *display_timings_get(const struct display_timings *disp, -- cgit From 42e836eb4527fb635cb799a701fe4c9fe741c03a Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 11 Mar 2013 13:56:44 +0000 Subject: phy: add set_wol/get_wol functions This allows ethernet drivers (such as the mv643xx_eth) to support Wake on LAN on platforms where PHY registers have to be configured for Wake on LAN (e.g. the Marvell Kirkwood based qnap TS-119P II). Signed-off-by: Michael Stapelberg Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 16 ++++++++++++++++ include/linux/phy.h | 10 ++++++++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index ef9ea9248223..298b4c201733 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1188,3 +1188,19 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) return 0; } EXPORT_SYMBOL(phy_ethtool_set_eee); + +int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) +{ + if (phydev->drv->set_wol) + return phydev->drv->set_wol(phydev, wol); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(phy_ethtool_set_wol); + +void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) +{ + if (phydev->drv->get_wol) + phydev->drv->get_wol(phydev, wol); +} +EXPORT_SYMBOL(phy_ethtool_get_wol); diff --git a/include/linux/phy.h b/include/linux/phy.h index 33999adbf8c8..9e11039dd7a3 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -455,6 +455,14 @@ struct phy_driver { */ void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); + /* Some devices (e.g. qnap TS-119P II) require PHY register changes to + * enable Wake on LAN, so set_wol is provided to be called in the + * ethernet driver's set_wol function. */ + int (*set_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol); + + /* See set_wol, but for checking whether Wake on LAN is enabled. */ + void (*get_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol); + struct device_driver driver; }; #define to_phy_driver(d) container_of(d, struct phy_driver, driver) @@ -560,6 +568,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable); int phy_get_eee_err(struct phy_device *phydev); int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data); int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data); +int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol); +void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol); int __init mdio_bus_init(void); void mdio_bus_exit(void); -- cgit From 3871c3876f8084a2f40ba3c3fc20a6bb5754d88d Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 11 Mar 2013 13:56:45 +0000 Subject: mv643xx_eth with 88E1318S: support Wake on LAN This has been tested on a qnap TS-119P II. Note that enabling WOL with "ethtool -s eth0 wol g" is not enough; you also need to tell the PIC microcontroller inside the qnap that WOL should be enabled by sending 0xF2 with qcontrol(1) and you have to disable EUP ("Energy-using Products", a European power-saving thing) by sending 0xF4. Signed-off-by: Michael Stapelberg Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mv643xx_eth.c | 32 ++++++++ drivers/net/phy/marvell.c | 127 +++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 6562c736a1d8..d1ecf4bf7da7 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -20,6 +20,8 @@ * Copyright (C) 2007-2008 Marvell Semiconductor * Lennert Buytenhek * + * Copyright (C) 2013 Michael Stapelberg + * * 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 @@ -1523,6 +1525,34 @@ mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp, return 0; } +static void +mv643xx_eth_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct mv643xx_eth_private *mp = netdev_priv(dev); + wol->supported = 0; + wol->wolopts = 0; + if (mp->phy) + phy_ethtool_get_wol(mp->phy, wol); +} + +static int +mv643xx_eth_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct mv643xx_eth_private *mp = netdev_priv(dev); + int err; + + if (mp->phy == NULL) + return -EOPNOTSUPP; + + err = phy_ethtool_set_wol(mp->phy, wol); + /* Given that mv643xx_eth works without the marvell-specific PHY driver, + * this debugging hint is useful to have. + */ + if (err == -EOPNOTSUPP) + netdev_info(dev, "The PHY does not support set_wol, was CONFIG_MARVELL_PHY enabled?\n"); + return err; +} + static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -1708,6 +1738,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = { .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, .get_sset_count = mv643xx_eth_get_sset_count, .get_ts_info = ethtool_op_get_ts_info, + .get_wol = mv643xx_eth_get_wol, + .set_wol = mv643xx_eth_set_wol, }; diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 22dec9c7ef05..202fe1ff1987 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -7,6 +7,8 @@ * * Copyright (c) 2004 Freescale Semiconductor, Inc. * + * Copyright (c) 2013 Michael Stapelberg + * * 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 @@ -80,6 +82,28 @@ #define MII_88E1318S_PHY_MSCR1_REG 16 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) +/* Copper Specific Interrupt Enable Register */ +#define MII_88E1318S_PHY_CSIER 0x12 +/* WOL Event Interrupt Enable */ +#define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) + +/* LED Timer Control Register */ +#define MII_88E1318S_PHY_LED_PAGE 0x03 +#define MII_88E1318S_PHY_LED_TCR 0x12 +#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) +#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) +#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) + +/* Magic Packet MAC address registers */ +#define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 +#define MII_88E1318S_PHY_MAGIC_PACKET_WORD1 0x18 +#define MII_88E1318S_PHY_MAGIC_PACKET_WORD0 0x19 + +#define MII_88E1318S_PHY_WOL_PAGE 0x11 +#define MII_88E1318S_PHY_WOL_CTRL 0x10 +#define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS BIT(12) +#define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14) + #define MII_88E1121_PHY_LED_CTRL 16 #define MII_88E1121_PHY_LED_PAGE 3 #define MII_88E1121_PHY_LED_DEF 0x0030 @@ -696,6 +720,107 @@ static int m88e1121_did_interrupt(struct phy_device *phydev) return 0; } +static void m88e1318_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) +{ + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + + if (phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1318S_PHY_WOL_PAGE) < 0) + return; + + if (phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL) & + MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE) + wol->wolopts |= WAKE_MAGIC; + + if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00) < 0) + return; +} + +static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) +{ + int err, oldpage, temp; + + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + + if (wol->wolopts & WAKE_MAGIC) { + /* Explicitly switch to page 0x00, just to be sure */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00); + if (err < 0) + return err; + + /* Enable the WOL interrupt */ + temp = phy_read(phydev, MII_88E1318S_PHY_CSIER); + temp |= MII_88E1318S_PHY_CSIER_WOL_EIE; + err = phy_write(phydev, MII_88E1318S_PHY_CSIER, temp); + if (err < 0) + return err; + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1318S_PHY_LED_PAGE); + if (err < 0) + return err; + + /* Setup LED[2] as interrupt pin (active low) */ + temp = phy_read(phydev, MII_88E1318S_PHY_LED_TCR); + temp &= ~MII_88E1318S_PHY_LED_TCR_FORCE_INT; + temp |= MII_88E1318S_PHY_LED_TCR_INTn_ENABLE; + temp |= MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW; + err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, temp); + if (err < 0) + return err; + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1318S_PHY_WOL_PAGE); + if (err < 0) + return err; + + /* Store the device address for the magic packet */ + err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2, + ((phydev->attached_dev->dev_addr[5] << 8) | + phydev->attached_dev->dev_addr[4])); + if (err < 0) + return err; + err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1, + ((phydev->attached_dev->dev_addr[3] << 8) | + phydev->attached_dev->dev_addr[2])); + if (err < 0) + return err; + err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0, + ((phydev->attached_dev->dev_addr[1] << 8) | + phydev->attached_dev->dev_addr[0])); + if (err < 0) + return err; + + /* Clear WOL status and enable magic packet matching */ + temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); + temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; + temp |= MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; + err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); + if (err < 0) + return err; + } else { + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1318S_PHY_WOL_PAGE); + if (err < 0) + return err; + + /* Clear WOL status and disable magic packet matching */ + temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL); + temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS; + temp &= ~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE; + err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp); + if (err < 0) + return err; + } + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + if (err < 0) + return err; + + return 0; +} + static struct phy_driver marvell_drivers[] = { { .phy_id = MARVELL_PHY_ID_88E1101, @@ -772,6 +897,8 @@ static struct phy_driver marvell_drivers[] = { .ack_interrupt = &marvell_ack_interrupt, .config_intr = &marvell_config_intr, .did_interrupt = &m88e1121_did_interrupt, + .get_wol = &m88e1318_get_wol, + .set_wol = &m88e1318_set_wol, .driver = { .owner = THIS_MODULE }, }, { -- cgit From c3f14cf924c7d97a89d505bdc0a06cf0d8efcdf6 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Mon, 11 Mar 2013 19:13:47 +0000 Subject: driver: isdn: capi: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Andrew Morton Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/capi/capidrv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 832bc807ed20..cc9f1927a322 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -469,8 +469,7 @@ static int capidrv_add_ack(struct capidrv_ncci *nccip, { struct ncci_datahandle_queue *n, **pp; - n = (struct ncci_datahandle_queue *) - kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC); + n = kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC); if (!n) { printk(KERN_ERR "capidrv: kmalloc ncci_datahandle failed\n"); return -1; -- cgit From f754e913e51709b7d842a9c5e17184198e83b2c8 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Mon, 11 Mar 2013 19:15:49 +0000 Subject: driver: isdn: hisax: remove cast for kmalloc/kzalloc return value remove cast for kmalloc/kzalloc return value. Signed-off-by: Zhang Yanfei Cc: Andrew Morton Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/hisax/fsm.c | 2 +- drivers/isdn/hisax/hfc_sx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c index 1bb291021fdb..c7a94713e9ec 100644 --- a/drivers/isdn/hisax/fsm.c +++ b/drivers/isdn/hisax/fsm.c @@ -26,7 +26,7 @@ FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount) { int i; - fsm->jumpmatrix = (FSMFNPTR *) + fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL); if (!fsm->jumpmatrix) return -ENOMEM; diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 90f34ae2b80f..dc4574f735ef 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -1479,7 +1479,7 @@ int setup_hfcsx(struct IsdnCard *card) release_region(cs->hw.hfcsx.base, 2); return (0); } - if (!(cs->hw.hfcsx.extra = (void *) + if (!(cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) { release_region(cs->hw.hfcsx.base, 2); printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); -- cgit From c1ad32af5ec281bf30d2ca4fa20415bd2edef181 Mon Sep 17 00:00:00 2001 From: "David J. Choi" Date: Mon, 11 Mar 2013 09:22:54 -0700 Subject: ks8851_mll: basic ethernet statistics Implement to collect ethernet statistical information on ks8851_mll device. Signed-off-by: David J. Choi Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851_mll.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index a343066f7b43..ddaf138ce0d4 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -792,20 +792,35 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) frame_hdr = ks->frame_head_info; while (ks->frame_cnt--) { + if (unlikely(!(frame_hdr->sts & RXFSHR_RXFV) || + frame_hdr->len >= RX_BUF_SIZE || + frame_hdr->len <= 0)) { + + /* discard an invalid packet */ + ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); + netdev->stats.rx_dropped++; + if (!(frame_hdr->sts & RXFSHR_RXFV)) + netdev->stats.rx_frame_errors++; + else + netdev->stats.rx_length_errors++; + frame_hdr++; + continue; + } + skb = netdev_alloc_skb(netdev, frame_hdr->len + 16); - if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) && - (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { + if (likely(skb)) { skb_reserve(skb, 2); /* read data block including CRC 4 bytes */ ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); - skb_put(skb, frame_hdr->len); + skb_put(skb, frame_hdr->len - 4); skb->protocol = eth_type_trans(skb, netdev); netif_rx(skb); + /* exclude CRC size */ + netdev->stats.rx_bytes += frame_hdr->len - 4; + netdev->stats.rx_packets++; } else { - pr_err("%s: err:skb alloc\n", __func__); ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); - if (skb) - dev_kfree_skb_irq(skb); + netdev->stats.rx_dropped++; } frame_hdr++; } @@ -877,6 +892,8 @@ static irqreturn_t ks_irq(int irq, void *pw) ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); } + if (unlikely(status & IRQ_RXOI)) + ks->netdev->stats.rx_over_errors++; /* this should be the last in IRQ handler*/ ks_restore_cmd_reg(ks); return IRQ_HANDLED; @@ -1015,6 +1032,9 @@ static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) { ks_write_qmu(ks, skb->data, skb->len); + /* add tx statistics */ + netdev->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; dev_kfree_skb(skb); } else retv = NETDEV_TX_BUSY; -- cgit From b4a034dab147776eab8eb8b2997ea16ef0e32c17 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 25 Feb 2013 22:51:37 -0800 Subject: Input: add support for GRLIB APBPS2 PS/2 Keyboard/Mouse APBPS2 is a PS/2 core part of GRLIB found in SPARC32/LEON products. Signed-off-by: Daniel Hellstrom Signed-off-by: Dmitry Torokhov --- .../bindings/input/ps2keyb-mouse-apbps2.txt | 16 ++ drivers/input/serio/Kconfig | 10 + drivers/input/serio/Makefile | 1 + drivers/input/serio/apbps2.c | 230 +++++++++++++++++++++ 4 files changed, 257 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt create mode 100644 drivers/input/serio/apbps2.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt b/Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt new file mode 100644 index 000000000000..3029c5694cf6 --- /dev/null +++ b/Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt @@ -0,0 +1,16 @@ +Aeroflex Gaisler APBPS2 PS/2 Core, supporting Keyboard or Mouse. + +The APBPS2 PS/2 core is available in the GRLIB VHDL IP core library. + +Note: In the ordinary environment for the APBPS2 core, a LEON SPARC system, +these properties are built from information in the AMBA plug&play and from +bootloader settings. + +Required properties: + +- name : Should be "GAISLER_APBPS2" or "01_060" +- reg : Address and length of the register set for the device +- interrupts : Interrupt numbers for this device + +For further information look in the documentation for the GLIB IP core library: +http://www.gaisler.com/products/grlib/grip.pdf diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 560c243bfcaf..dbb170916dd1 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -244,4 +244,14 @@ config SERIO_ARC_PS2 To compile this driver as a module, choose M here; the module will be called arc_ps2. +config SERIO_APBPS2 + tristate "GRLIB APBPS2 PS/2 keyboard/mouse controller" + depends on OF + help + Say Y here if you want support for GRLIB APBPS2 peripherals used + to connect to PS/2 keyboard and/or mouse. + + To compile this driver as a module, choose M here: the module will + be called apbps2. + endif diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 4b0c8f84f1c1..8edb36c2cdb4 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile @@ -26,3 +26,4 @@ obj-$(CONFIG_SERIO_AMS_DELTA) += ams_delta_serio.o obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o +obj-$(CONFIG_SERIO_APBPS2) += apbps2.o diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c new file mode 100644 index 000000000000..2c14e6fa64c2 --- /dev/null +++ b/drivers/input/serio/apbps2.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2013 Aeroflex Gaisler + * + * This driver supports the APBPS2 PS/2 core available in the GRLIB + * VHDL IP core library. + * + * Full documentation of the APBPS2 core can be found here: + * http://www.gaisler.com/products/grlib/grip.pdf + * + * See "Documentation/devicetree/bindings/input/ps2keyb-mouse-apbps2.txt" for + * information on open firmware properties. + * + * 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. + * + * Contributors: Daniel Hellstrom + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct apbps2_regs { + u32 __iomem data; /* 0x00 */ + u32 __iomem status; /* 0x04 */ + u32 __iomem ctrl; /* 0x08 */ + u32 __iomem reload; /* 0x0c */ +}; + +#define APBPS2_STATUS_DR (1<<0) +#define APBPS2_STATUS_PE (1<<1) +#define APBPS2_STATUS_FE (1<<2) +#define APBPS2_STATUS_KI (1<<3) +#define APBPS2_STATUS_RF (1<<4) +#define APBPS2_STATUS_TF (1<<5) +#define APBPS2_STATUS_TCNT (0x1f<<22) +#define APBPS2_STATUS_RCNT (0x1f<<27) + +#define APBPS2_CTRL_RE (1<<0) +#define APBPS2_CTRL_TE (1<<1) +#define APBPS2_CTRL_RI (1<<2) +#define APBPS2_CTRL_TI (1<<3) + +struct apbps2_priv { + struct serio *io; + struct apbps2_regs *regs; +}; + +static int apbps2_idx; + +static irqreturn_t apbps2_isr(int irq, void *dev_id) +{ + struct apbps2_priv *priv = dev_id; + unsigned long status, data, rxflags; + irqreturn_t ret = IRQ_NONE; + + while ((status = ioread32be(&priv->regs->status)) & APBPS2_STATUS_DR) { + data = ioread32be(&priv->regs->data); + rxflags = (status & APBPS2_STATUS_PE) ? SERIO_PARITY : 0; + rxflags |= (status & APBPS2_STATUS_FE) ? SERIO_FRAME : 0; + + /* clear error bits? */ + if (rxflags) + iowrite32be(0, &priv->regs->status); + + serio_interrupt(priv->io, data, rxflags); + + ret = IRQ_HANDLED; + } + + return ret; +} + +static int apbps2_write(struct serio *io, unsigned char val) +{ + struct apbps2_priv *priv = io->port_data; + unsigned int tleft = 10000; /* timeout in 100ms */ + + /* delay until PS/2 controller has room for more chars */ + while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_TF) && tleft--) + udelay(10); + + if ((ioread32be(&priv->regs->status) & APBPS2_STATUS_TF) == 0) { + iowrite32be(val, &priv->regs->data); + + iowrite32be(APBPS2_CTRL_RE | APBPS2_CTRL_RI | APBPS2_CTRL_TE, + &priv->regs->ctrl); + return 0; + } + + return -ETIMEDOUT; +} + +static int apbps2_open(struct serio *io) +{ + struct apbps2_priv *priv = io->port_data; + int limit; + unsigned long tmp; + + /* clear error flags */ + iowrite32be(0, &priv->regs->status); + + /* Clear old data if available (unlikely) */ + limit = 1024; + while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_DR) && --limit) + tmp = ioread32be(&priv->regs->data); + + /* Enable reciever and it's interrupt */ + iowrite32be(APBPS2_CTRL_RE | APBPS2_CTRL_RI, &priv->regs->ctrl); + + return 0; +} + +static void apbps2_close(struct serio *io) +{ + struct apbps2_priv *priv = io->port_data; + + /* stop interrupts at PS/2 HW level */ + iowrite32be(0, &priv->regs->ctrl); +} + +/* Initialize one APBPS2 PS/2 core */ +static int apbps2_of_probe(struct platform_device *ofdev) +{ + struct apbps2_priv *priv; + int irq, err; + u32 freq_hz; + struct resource *res; + + priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&ofdev->dev, "memory allocation failed\n"); + return -ENOMEM; + } + + /* Find Device Address */ + res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); + priv->regs = devm_request_and_ioremap(&ofdev->dev, res); + if (!priv->regs) { + dev_err(&ofdev->dev, "io-regs mapping failed\n"); + return -EBUSY; + } + + /* Reset hardware, disable interrupt */ + iowrite32be(0, &priv->regs->ctrl); + + /* IRQ */ + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + err = devm_request_irq(&ofdev->dev, irq, apbps2_isr, + IRQF_SHARED, "apbps2", priv); + if (err) { + dev_err(&ofdev->dev, "request IRQ%d failed\n", irq); + return err; + } + + /* Get core frequency */ + if (of_property_read_u32(ofdev->dev.of_node, "freq", &freq_hz)) { + dev_err(&ofdev->dev, "unable to get core frequency\n"); + return -EINVAL; + } + + /* Set reload register to core freq in kHz/10 */ + iowrite32be(freq_hz / 10000, &priv->regs->reload); + + priv->io = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!priv->io) + return -ENOMEM; + + priv->io->id.type = SERIO_8042; + priv->io->open = apbps2_open; + priv->io->close = apbps2_close; + priv->io->write = apbps2_write; + priv->io->port_data = priv; + strlcpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name)); + snprintf(priv->io->phys, sizeof(priv->io->phys), + "apbps2_%d", apbps2_idx++); + + dev_info(&ofdev->dev, "irq = %d, base = 0x%p\n", irq, priv->regs); + + serio_register_port(priv->io); + + platform_set_drvdata(ofdev, priv); + + return 0; +} + +static int apbps2_of_remove(struct platform_device *of_dev) +{ + struct apbps2_priv *priv = platform_get_drvdata(of_dev); + + serio_unregister_port(priv->io); + + return 0; +} + +static struct of_device_id apbps2_of_match[] = { + { .name = "GAISLER_APBPS2", }, + { .name = "01_060", }, + {} +}; + +MODULE_DEVICE_TABLE(of, apbps2_of_match); + +static struct platform_driver apbps2_of_driver = { + .driver = { + .name = "grlib-apbps2", + .owner = THIS_MODULE, + .of_match_table = apbps2_of_match, + }, + .probe = apbps2_of_probe, + .remove = apbps2_of_remove, +}; + +module_platform_driver(apbps2_of_driver); + +MODULE_AUTHOR("Aeroflex Gaisler AB."); +MODULE_DESCRIPTION("GRLIB APBPS2 PS/2 serial I/O"); +MODULE_LICENSE("GPL"); -- cgit From cfd5d09691ee188a36c00f5c3b220fbf082a78d7 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 9 Mar 2013 15:19:56 -0800 Subject: Input: wm97xx - drop out of range inputs With fast movements, there occured some out of screen jumps with my touchscreen. The abs_x and abs_y module parameters should fix this by default, but the driver doesn't actively checks the x/y coordinates. Instead it seems that the input layer was supposed to drop out of range inputs, as described in the comments: "These parameters are used to help the input layer discard out of range readings and reduce jitter etc" The input layer documentation describes that values that are not in the absolute range are also accepted. So this patch adds a check within the driver. Signed-off-by: Markus Pargmann Acked-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm97xx-core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 5dbe73af2f8f..7e45c9f6e6b7 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -442,6 +442,16 @@ static int wm97xx_read_samples(struct wm97xx *wm) "pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n", data.x >> 12, data.x & 0xfff, data.y >> 12, data.y & 0xfff, data.p >> 12, data.p & 0xfff); + + if (abs_x[0] > (data.x & 0xfff) || + abs_x[1] < (data.x & 0xfff) || + abs_y[0] > (data.y & 0xfff) || + abs_y[1] < (data.y & 0xfff)) { + dev_dbg(wm->dev, "Measurement out of range, dropping it\n"); + rc = RC_AGAIN; + goto out; + } + input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); @@ -455,6 +465,7 @@ static int wm97xx_read_samples(struct wm97xx *wm) wm->ts_reader_interval = wm->ts_reader_min_interval; } +out: mutex_unlock(&wm->codec_mutex); return rc; } -- cgit From fa45255ee72649bd061116f7d3a765f5784bf078 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 9 Mar 2013 15:20:50 -0800 Subject: Input: wm9712 - fix return code for wrong sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of interpreting a wrong measurement as pen up, we should try to read again. Based on wm9712: pen up by Teresa Gámez and Christian Hemp. Signed-off-by: Markus Pargmann Acked-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm9712.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 6e743e3dfda4..a983da1744e8 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c @@ -298,7 +298,7 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", adcsel & WM97XX_ADCSEL_MASK, *sample & WM97XX_ADCSEL_MASK); - return RC_PENUP; + return RC_AGAIN; } if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { -- cgit From 540792753c292bce53f42eb7b8fb3d3510f57e00 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 9 Mar 2013 15:21:33 -0800 Subject: Input: wm9712 - fix wrong pen up readings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Often a reading can be wrong. This patch assures that this is really a pen up event and not a false reading. Based on wm9712: pen up by Teresa Gámez and Christian Hemp. Signed-off-by: Markus Pargmann Acked-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm9712.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index a983da1744e8..3b4eed4b8690 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c @@ -302,8 +302,12 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) } if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { - wm->pen_probably_down = 0; - return RC_PENUP; + /* Sometimes it reads a wrong value the first time. */ + *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(*sample & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } } return RC_VALID; -- cgit From d73a17e6c85010f2249e823231ccc0345d1e016f Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 9 Mar 2013 15:22:35 -0800 Subject: Input: wm9712 - fix dev_dbg newlines dev_dbg should end with a new line. Signed-off-by: Markus Pargmann Acked-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm9712.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 3b4eed4b8690..16b52115c27f 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c @@ -162,14 +162,14 @@ static void wm9712_phy_init(struct wm97xx *wm) if (rpu) { dig2 &= 0xffc0; dig2 |= WM9712_RPU(rpu); - dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms", + dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms\n", 64000 / rpu); } /* WM9712 five wire */ if (five_wire) { dig2 |= WM9712_45W; - dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); + dev_dbg(wm->dev, "setting 5-wire touchscreen mode.\n"); if (pil) { dev_warn(wm->dev, "pressure measurement is not " @@ -182,21 +182,21 @@ static void wm9712_phy_init(struct wm97xx *wm) if (pil == 2) { dig2 |= WM9712_PIL; dev_dbg(wm->dev, - "setting pressure measurement current to 400uA."); + "setting pressure measurement current to 400uA.\n"); } else if (pil) dev_dbg(wm->dev, - "setting pressure measurement current to 200uA."); + "setting pressure measurement current to 200uA.\n"); if (!pil) pressure = 0; /* polling mode sample settling delay */ if (delay < 0 || delay > 15) { - dev_dbg(wm->dev, "supplied delay out of range."); + dev_dbg(wm->dev, "supplied delay out of range.\n"); delay = 4; } dig1 &= 0xff0f; dig1 |= WM97XX_DELAY(delay); - dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", + dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.\n", delay_table[delay]); /* mask */ @@ -285,7 +285,7 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) if (is_pden(wm)) wm->pen_probably_down = 0; else - dev_dbg(wm->dev, "adc sample timeout"); + dev_dbg(wm->dev, "adc sample timeout\n"); return RC_PENUP; } @@ -295,7 +295,7 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) /* check we have correct sample */ if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { - dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", + dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x\n", adcsel & WM97XX_ADCSEL_MASK, *sample & WM97XX_ADCSEL_MASK); return RC_AGAIN; @@ -349,7 +349,7 @@ static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) if (is_pden(wm)) wm->pen_probably_down = 0; else - dev_dbg(wm->dev, "adc sample timeout"); + dev_dbg(wm->dev, "adc sample timeout\n"); return RC_PENUP; } -- cgit From 628329d52474323938a03826941e166bc7c8eff4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 2 Feb 2013 11:26:13 -0800 Subject: Input: add IMS Passenger Control Unit driver The PCU is a device installed in the armrest of a plane seat and is connected to IMS Rave Entertainment System. It has a set of control buttons (Volume Up/Down, Attendant, Lights, etc) on one side and gamepad-like controls on the other side. Originally the device was handled from userspace and because of that it presents itself on USB bus as a CDC-ACM modem device that however can not make calls. However the custom handling is not as convenient as using standard input subsystem facilities. If it was pure input device it would be possible to continue using userspace solution (moving it over to uinput), but the device also has backlighted keys which can not be supported via uinput. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 10 + drivers/input/misc/Makefile | 1 + drivers/input/misc/ims-pcu.c | 1900 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1911 insertions(+) create mode 100644 drivers/input/misc/ims-pcu.c (limited to 'drivers') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 2a1647ef5610..3ec8887ce451 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -580,6 +580,16 @@ config INPUT_ADXL34X_SPI To compile this driver as a module, choose M here: the module will be called adxl34x-spi. +config INPUT_IMS_PCU + tristate "IMS Passenger Control Unit driver" + depends on USB + depends on LEDS_CLASS + help + Say Y here if you have system with IMS Rave Passenger Control Unit. + + To compile this driver as a module, choose M here: the module will be + called ims_pcu. + config INPUT_CMA3000 tristate "VTI CMA3000 Tri-axis accelerometer" help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 1f874afeea6a..d6873433ba71 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o +obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c new file mode 100644 index 000000000000..1b044b99da66 --- /dev/null +++ b/drivers/input/misc/ims-pcu.c @@ -0,0 +1,1900 @@ +/* + * Driver for IMS Passenger Control Unit Devices + * + * Copyright (C) 2013 The IMS Company + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMS_PCU_KEYMAP_LEN 32 + +struct ims_pcu_buttons { + struct input_dev *input; + char name[32]; + char phys[32]; + unsigned short keymap[IMS_PCU_KEYMAP_LEN]; +}; + +struct ims_pcu_gamepad { + struct input_dev *input; + char name[32]; + char phys[32]; +}; + +struct ims_pcu_backlight { + struct led_classdev cdev; + struct work_struct work; + enum led_brightness desired_brightness; + char name[32]; +}; + +#define IMS_PCU_PART_NUMBER_LEN 15 +#define IMS_PCU_SERIAL_NUMBER_LEN 8 +#define IMS_PCU_DOM_LEN 8 +#define IMS_PCU_FW_VERSION_LEN (9 + 1) +#define IMS_PCU_BL_VERSION_LEN (9 + 1) +#define IMS_PCU_BL_RESET_REASON_LEN (2 + 1) + +#define IMS_PCU_BUF_SIZE 128 + +struct ims_pcu { + struct usb_device *udev; + struct device *dev; /* control interface's device, used for logging */ + + unsigned int device_no; + + bool bootloader_mode; + + char part_number[IMS_PCU_PART_NUMBER_LEN]; + char serial_number[IMS_PCU_SERIAL_NUMBER_LEN]; + char date_of_manufacturing[IMS_PCU_DOM_LEN]; + char fw_version[IMS_PCU_FW_VERSION_LEN]; + char bl_version[IMS_PCU_BL_VERSION_LEN]; + char reset_reason[IMS_PCU_BL_RESET_REASON_LEN]; + int update_firmware_status; + + struct usb_interface *ctrl_intf; + + struct usb_endpoint_descriptor *ep_ctrl; + struct urb *urb_ctrl; + u8 *urb_ctrl_buf; + dma_addr_t ctrl_dma; + size_t max_ctrl_size; + + struct usb_interface *data_intf; + + struct usb_endpoint_descriptor *ep_in; + struct urb *urb_in; + u8 *urb_in_buf; + dma_addr_t read_dma; + size_t max_in_size; + + struct usb_endpoint_descriptor *ep_out; + u8 *urb_out_buf; + size_t max_out_size; + + u8 read_buf[IMS_PCU_BUF_SIZE]; + u8 read_pos; + u8 check_sum; + bool have_stx; + bool have_dle; + + u8 cmd_buf[IMS_PCU_BUF_SIZE]; + u8 ack_id; + u8 expected_response; + u8 cmd_buf_len; + struct completion cmd_done; + struct mutex cmd_mutex; + + u32 fw_start_addr; + u32 fw_end_addr; + struct completion async_firmware_done; + + struct ims_pcu_buttons buttons; + struct ims_pcu_gamepad *gamepad; + struct ims_pcu_backlight backlight; + + bool setup_complete; /* Input and LED devices have been created */ +}; + + +/********************************************************************* + * Buttons Input device support * + *********************************************************************/ + +static const unsigned short ims_pcu_keymap_1[] = { + [1] = KEY_ATTENDANT_OFF, + [2] = KEY_ATTENDANT_ON, + [3] = KEY_LIGHTS_TOGGLE, + [4] = KEY_VOLUMEUP, + [5] = KEY_VOLUMEDOWN, + [6] = KEY_INFO, +}; + +static const unsigned short ims_pcu_keymap_2[] = { + [4] = KEY_VOLUMEUP, + [5] = KEY_VOLUMEDOWN, + [6] = KEY_INFO, +}; + +static const unsigned short ims_pcu_keymap_3[] = { + [1] = KEY_HOMEPAGE, + [2] = KEY_ATTENDANT_TOGGLE, + [3] = KEY_LIGHTS_TOGGLE, + [4] = KEY_VOLUMEUP, + [5] = KEY_VOLUMEDOWN, + [6] = KEY_DISPLAYTOGGLE, + [18] = KEY_PLAYPAUSE, +}; + +static const unsigned short ims_pcu_keymap_4[] = { + [1] = KEY_ATTENDANT_OFF, + [2] = KEY_ATTENDANT_ON, + [3] = KEY_LIGHTS_TOGGLE, + [4] = KEY_VOLUMEUP, + [5] = KEY_VOLUMEDOWN, + [6] = KEY_INFO, + [18] = KEY_PLAYPAUSE, +}; + +static const unsigned short ims_pcu_keymap_5[] = { + [1] = KEY_ATTENDANT_OFF, + [2] = KEY_ATTENDANT_ON, + [3] = KEY_LIGHTS_TOGGLE, +}; + +struct ims_pcu_device_info { + const unsigned short *keymap; + size_t keymap_len; + bool has_gamepad; +}; + +#define IMS_PCU_DEVINFO(_n, _gamepad) \ + [_n] = { \ + .keymap = ims_pcu_keymap_##_n, \ + .keymap_len = ARRAY_SIZE(ims_pcu_keymap_##_n), \ + .has_gamepad = _gamepad, \ + } + +static const struct ims_pcu_device_info ims_pcu_device_info[] = { + IMS_PCU_DEVINFO(1, true), + IMS_PCU_DEVINFO(2, true), + IMS_PCU_DEVINFO(3, true), + IMS_PCU_DEVINFO(4, true), + IMS_PCU_DEVINFO(5, false), +}; + +static void ims_pcu_buttons_report(struct ims_pcu *pcu, u32 data) +{ + struct ims_pcu_buttons *buttons = &pcu->buttons; + struct input_dev *input = buttons->input; + int i; + + for (i = 0; i < 32; i++) { + unsigned short keycode = buttons->keymap[i]; + + if (keycode != KEY_RESERVED) + input_report_key(input, keycode, data & (1UL << i)); + } + + input_sync(input); +} + +static int ims_pcu_setup_buttons(struct ims_pcu *pcu, + const unsigned short *keymap, + size_t keymap_len) +{ + struct ims_pcu_buttons *buttons = &pcu->buttons; + struct input_dev *input; + int i; + int error; + + input = input_allocate_device(); + if (!input) { + dev_err(pcu->dev, + "Not enough memory for input input device\n"); + return -ENOMEM; + } + + snprintf(buttons->name, sizeof(buttons->name), + "IMS PCU#%d Button Interface", pcu->device_no); + + usb_make_path(pcu->udev, buttons->phys, sizeof(buttons->phys)); + strlcat(buttons->phys, "/input0", sizeof(buttons->phys)); + + memcpy(buttons->keymap, keymap, sizeof(*keymap) * keymap_len); + + input->name = buttons->name; + input->phys = buttons->phys; + usb_to_input_id(pcu->udev, &input->id); + input->dev.parent = &pcu->ctrl_intf->dev; + + input->keycode = buttons->keymap; + input->keycodemax = ARRAY_SIZE(buttons->keymap); + input->keycodesize = sizeof(buttons->keymap[0]); + + __set_bit(EV_KEY, input->evbit); + for (i = 0; i < IMS_PCU_KEYMAP_LEN; i++) + __set_bit(buttons->keymap[i], input->keybit); + __clear_bit(KEY_RESERVED, input->keybit); + + error = input_register_device(input); + if (error) { + dev_err(pcu->dev, + "Failed to register buttons input device: %d\n", + error); + input_free_device(input); + return error; + } + + buttons->input = input; + return 0; +} + +static void ims_pcu_destroy_buttons(struct ims_pcu *pcu) +{ + struct ims_pcu_buttons *buttons = &pcu->buttons; + + input_unregister_device(buttons->input); +} + + +/********************************************************************* + * Gamepad Input device support * + *********************************************************************/ + +static void ims_pcu_gamepad_report(struct ims_pcu *pcu, u32 data) +{ + struct ims_pcu_gamepad *gamepad = pcu->gamepad; + struct input_dev *input = gamepad->input; + int x, y; + + x = !!(data & (1 << 14)) - !!(data & (1 << 13)); + y = !!(data & (1 << 12)) - !!(data & (1 << 11)); + + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + + input_report_key(input, BTN_A, data & (1 << 7)); + input_report_key(input, BTN_B, data & (1 << 8)); + input_report_key(input, BTN_X, data & (1 << 9)); + input_report_key(input, BTN_Y, data & (1 << 10)); + input_report_key(input, BTN_START, data & (1 << 15)); + input_report_key(input, BTN_SELECT, data & (1 << 16)); + + input_sync(input); +} + +static int ims_pcu_setup_gamepad(struct ims_pcu *pcu) +{ + struct ims_pcu_gamepad *gamepad; + struct input_dev *input; + int error; + + gamepad = kzalloc(sizeof(struct ims_pcu_gamepad), GFP_KERNEL); + input = input_allocate_device(); + if (!gamepad || !input) { + dev_err(pcu->dev, + "Not enough memory for gamepad device\n"); + return -ENOMEM; + } + + gamepad->input = input; + + snprintf(gamepad->name, sizeof(gamepad->name), + "IMS PCU#%d Gamepad Interface", pcu->device_no); + + usb_make_path(pcu->udev, gamepad->phys, sizeof(gamepad->phys)); + strlcat(gamepad->phys, "/input1", sizeof(gamepad->phys)); + + input->name = gamepad->name; + input->phys = gamepad->phys; + usb_to_input_id(pcu->udev, &input->id); + input->dev.parent = &pcu->ctrl_intf->dev; + + __set_bit(EV_KEY, input->evbit); + __set_bit(BTN_A, input->keybit); + __set_bit(BTN_B, input->keybit); + __set_bit(BTN_X, input->keybit); + __set_bit(BTN_Y, input->keybit); + __set_bit(BTN_START, input->keybit); + __set_bit(BTN_SELECT, input->keybit); + + __set_bit(EV_ABS, input->evbit); + input_set_abs_params(input, ABS_X, -1, 1, 0, 0); + input_set_abs_params(input, ABS_Y, -1, 1, 0, 0); + + error = input_register_device(input); + if (error) { + dev_err(pcu->dev, + "Failed to register gamepad input device: %d\n", + error); + goto err_free_mem; + } + + pcu->gamepad = gamepad; + return 0; + +err_free_mem: + input_free_device(input); + kfree(gamepad); + return -ENOMEM; +} + +static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu) +{ + struct ims_pcu_gamepad *gamepad = pcu->gamepad; + + input_unregister_device(gamepad->input); + kfree(gamepad); +} + + +/********************************************************************* + * PCU Communication protocol handling * + *********************************************************************/ + +#define IMS_PCU_PROTOCOL_STX 0x02 +#define IMS_PCU_PROTOCOL_ETX 0x03 +#define IMS_PCU_PROTOCOL_DLE 0x10 + +/* PCU commands */ +#define IMS_PCU_CMD_STATUS 0xa0 +#define IMS_PCU_CMD_PCU_RESET 0xa1 +#define IMS_PCU_CMD_RESET_REASON 0xa2 +#define IMS_PCU_CMD_SEND_BUTTONS 0xa3 +#define IMS_PCU_CMD_JUMP_TO_BTLDR 0xa4 +#define IMS_PCU_CMD_GET_INFO 0xa5 +#define IMS_PCU_CMD_SET_BRIGHTNESS 0xa6 +#define IMS_PCU_CMD_EEPROM 0xa7 +#define IMS_PCU_CMD_GET_FW_VERSION 0xa8 +#define IMS_PCU_CMD_GET_BL_VERSION 0xa9 +#define IMS_PCU_CMD_SET_INFO 0xab +#define IMS_PCU_CMD_GET_BRIGHTNESS 0xac +#define IMS_PCU_CMD_GET_DEVICE_ID 0xae +#define IMS_PCU_CMD_SPECIAL_INFO 0xb0 +#define IMS_PCU_CMD_BOOTLOADER 0xb1 /* Pass data to bootloader */ + +/* PCU responses */ +#define IMS_PCU_RSP_STATUS 0xc0 +#define IMS_PCU_RSP_PCU_RESET 0 /* Originally 0xc1 */ +#define IMS_PCU_RSP_RESET_REASON 0xc2 +#define IMS_PCU_RSP_SEND_BUTTONS 0xc3 +#define IMS_PCU_RSP_JUMP_TO_BTLDR 0 /* Originally 0xc4 */ +#define IMS_PCU_RSP_GET_INFO 0xc5 +#define IMS_PCU_RSP_SET_BRIGHTNESS 0xc6 +#define IMS_PCU_RSP_EEPROM 0xc7 +#define IMS_PCU_RSP_GET_FW_VERSION 0xc8 +#define IMS_PCU_RSP_GET_BL_VERSION 0xc9 +#define IMS_PCU_RSP_SET_INFO 0xcb +#define IMS_PCU_RSP_GET_BRIGHTNESS 0xcc +#define IMS_PCU_RSP_CMD_INVALID 0xcd +#define IMS_PCU_RSP_GET_DEVICE_ID 0xce +#define IMS_PCU_RSP_SPECIAL_INFO 0xd0 +#define IMS_PCU_RSP_BOOTLOADER 0xd1 /* Bootloader response */ + +#define IMS_PCU_RSP_EVNT_BUTTONS 0xe0 /* Unsolicited, button state */ +#define IMS_PCU_GAMEPAD_MASK 0x0001ff80UL /* Bits 7 through 16 */ + + +#define IMS_PCU_MIN_PACKET_LEN 3 +#define IMS_PCU_DATA_OFFSET 2 + +#define IMS_PCU_CMD_WRITE_TIMEOUT 100 /* msec */ +#define IMS_PCU_CMD_RESPONSE_TIMEOUT 500 /* msec */ + +static void ims_pcu_report_events(struct ims_pcu *pcu) +{ + u32 data = get_unaligned_be32(&pcu->read_buf[3]); + + ims_pcu_buttons_report(pcu, data & ~IMS_PCU_GAMEPAD_MASK); + if (pcu->gamepad) + ims_pcu_gamepad_report(pcu, data); +} + +static void ims_pcu_handle_response(struct ims_pcu *pcu) +{ + switch (pcu->read_buf[0]) { + case IMS_PCU_RSP_EVNT_BUTTONS: + if (likely(pcu->setup_complete)) + ims_pcu_report_events(pcu); + break; + + default: + /* + * See if we got command completion. + * If both the sequence and response code match save + * the data and signal completion. + */ + if (pcu->read_buf[0] == pcu->expected_response && + pcu->read_buf[1] == pcu->ack_id - 1) { + + memcpy(pcu->cmd_buf, pcu->read_buf, pcu->read_pos); + pcu->cmd_buf_len = pcu->read_pos; + complete(&pcu->cmd_done); + } + break; + } +} + +static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb) +{ + int i; + + for (i = 0; i < urb->actual_length; i++) { + u8 data = pcu->urb_in_buf[i]; + + /* Skip everything until we get Start Xmit */ + if (!pcu->have_stx && data != IMS_PCU_PROTOCOL_STX) + continue; + + if (pcu->have_dle) { + pcu->have_dle = false; + pcu->read_buf[pcu->read_pos++] = data; + pcu->check_sum += data; + continue; + } + + switch (data) { + case IMS_PCU_PROTOCOL_STX: + if (pcu->have_stx) + dev_warn(pcu->dev, + "Unexpected STX at byte %d, discarding old data\n", + pcu->read_pos); + pcu->have_stx = true; + pcu->have_dle = false; + pcu->read_pos = 0; + pcu->check_sum = 0; + break; + + case IMS_PCU_PROTOCOL_DLE: + pcu->have_dle = true; + break; + + case IMS_PCU_PROTOCOL_ETX: + if (pcu->read_pos < IMS_PCU_MIN_PACKET_LEN) { + dev_warn(pcu->dev, + "Short packet received (%d bytes), ignoring\n", + pcu->read_pos); + } else if (pcu->check_sum != 0) { + dev_warn(pcu->dev, + "Invalid checksum in packet (%d bytes), ignoring\n", + pcu->read_pos); + } else { + ims_pcu_handle_response(pcu); + } + + pcu->have_stx = false; + pcu->have_dle = false; + pcu->read_pos = 0; + break; + + default: + pcu->read_buf[pcu->read_pos++] = data; + pcu->check_sum += data; + break; + } + } +} + +static bool ims_pcu_byte_needs_escape(u8 byte) +{ + return byte == IMS_PCU_PROTOCOL_STX || + byte == IMS_PCU_PROTOCOL_ETX || + byte == IMS_PCU_PROTOCOL_DLE; +} + +static int ims_pcu_send_cmd_chunk(struct ims_pcu *pcu, + u8 command, int chunk, int len) +{ + int error; + + error = usb_bulk_msg(pcu->udev, + usb_sndbulkpipe(pcu->udev, + pcu->ep_out->bEndpointAddress), + pcu->urb_out_buf, len, + NULL, IMS_PCU_CMD_WRITE_TIMEOUT); + if (error < 0) { + dev_dbg(pcu->dev, + "Sending 0x%02x command failed at chunk %d: %d\n", + command, chunk, error); + return error; + } + + return 0; +} + +static int ims_pcu_send_command(struct ims_pcu *pcu, + u8 command, const u8 *data, int len) +{ + int count = 0; + int chunk = 0; + int delta; + int i; + int error; + u8 csum = 0; + u8 ack_id; + + pcu->urb_out_buf[count++] = IMS_PCU_PROTOCOL_STX; + + /* We know the command need not be escaped */ + pcu->urb_out_buf[count++] = command; + csum += command; + + ack_id = pcu->ack_id++; + if (ack_id == 0xff) + ack_id = pcu->ack_id++; + + if (ims_pcu_byte_needs_escape(ack_id)) + pcu->urb_out_buf[count++] = IMS_PCU_PROTOCOL_DLE; + + pcu->urb_out_buf[count++] = ack_id; + csum += ack_id; + + for (i = 0; i < len; i++) { + + delta = ims_pcu_byte_needs_escape(data[i]) ? 2 : 1; + if (count + delta >= pcu->max_out_size) { + error = ims_pcu_send_cmd_chunk(pcu, command, + ++chunk, count); + if (error) + return error; + + count = 0; + } + + if (delta == 2) + pcu->urb_out_buf[count++] = IMS_PCU_PROTOCOL_DLE; + + pcu->urb_out_buf[count++] = data[i]; + csum += data[i]; + } + + csum = 1 + ~csum; + + delta = ims_pcu_byte_needs_escape(csum) ? 3 : 2; + if (count + delta >= pcu->max_out_size) { + error = ims_pcu_send_cmd_chunk(pcu, command, ++chunk, count); + if (error) + return error; + + count = 0; + } + + if (delta == 3) + pcu->urb_out_buf[count++] = IMS_PCU_PROTOCOL_DLE; + + pcu->urb_out_buf[count++] = csum; + pcu->urb_out_buf[count++] = IMS_PCU_PROTOCOL_ETX; + + return ims_pcu_send_cmd_chunk(pcu, command, ++chunk, count); +} + +static int __ims_pcu_execute_command(struct ims_pcu *pcu, + u8 command, const void *data, size_t len, + u8 expected_response, int response_time) +{ + int error; + + pcu->expected_response = expected_response; + init_completion(&pcu->cmd_done); + + error = ims_pcu_send_command(pcu, command, data, len); + if (error) + return error; + + if (expected_response && + !wait_for_completion_timeout(&pcu->cmd_done, + msecs_to_jiffies(response_time))) { + dev_dbg(pcu->dev, "Command 0x%02x timed out\n", command); + return -ETIMEDOUT; + } + + return 0; +} + +#define ims_pcu_execute_command(pcu, code, data, len) \ + __ims_pcu_execute_command(pcu, \ + IMS_PCU_CMD_##code, data, len, \ + IMS_PCU_RSP_##code, \ + IMS_PCU_CMD_RESPONSE_TIMEOUT) + +#define ims_pcu_execute_query(pcu, code) \ + ims_pcu_execute_command(pcu, code, NULL, 0) + +/* Bootloader commands */ +#define IMS_PCU_BL_CMD_QUERY_DEVICE 0xa1 +#define IMS_PCU_BL_CMD_UNLOCK_CONFIG 0xa2 +#define IMS_PCU_BL_CMD_ERASE_APP 0xa3 +#define IMS_PCU_BL_CMD_PROGRAM_DEVICE 0xa4 +#define IMS_PCU_BL_CMD_PROGRAM_COMPLETE 0xa5 +#define IMS_PCU_BL_CMD_READ_APP 0xa6 +#define IMS_PCU_BL_CMD_RESET_DEVICE 0xa7 +#define IMS_PCU_BL_CMD_LAUNCH_APP 0xa8 + +/* Bootloader commands */ +#define IMS_PCU_BL_RSP_QUERY_DEVICE 0xc1 +#define IMS_PCU_BL_RSP_UNLOCK_CONFIG 0xc2 +#define IMS_PCU_BL_RSP_ERASE_APP 0xc3 +#define IMS_PCU_BL_RSP_PROGRAM_DEVICE 0xc4 +#define IMS_PCU_BL_RSP_PROGRAM_COMPLETE 0xc5 +#define IMS_PCU_BL_RSP_READ_APP 0xc6 +#define IMS_PCU_BL_RSP_RESET_DEVICE 0 /* originally 0xa7 */ +#define IMS_PCU_BL_RSP_LAUNCH_APP 0 /* originally 0xa8 */ + +#define IMS_PCU_BL_DATA_OFFSET 3 + +static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu, + u8 command, const void *data, size_t len, + u8 expected_response, int response_time) +{ + int error; + + pcu->cmd_buf[0] = command; + if (data) + memcpy(&pcu->cmd_buf[1], data, len); + + error = __ims_pcu_execute_command(pcu, + IMS_PCU_CMD_BOOTLOADER, pcu->cmd_buf, len + 1, + expected_response ? IMS_PCU_RSP_BOOTLOADER : 0, + response_time); + if (error) { + dev_err(pcu->dev, + "Failure when sending 0x%02x command to bootloader, error: %d\n", + pcu->cmd_buf[0], error); + return error; + } + + if (expected_response && pcu->cmd_buf[2] != expected_response) { + dev_err(pcu->dev, + "Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n", + pcu->cmd_buf[2], expected_response); + return -EINVAL; + } + + return 0; +} + +#define ims_pcu_execute_bl_command(pcu, code, data, len, timeout) \ + __ims_pcu_execute_bl_command(pcu, \ + IMS_PCU_BL_CMD_##code, data, len, \ + IMS_PCU_BL_RSP_##code, timeout) \ + +#define IMS_PCU_INFO_PART_OFFSET 2 +#define IMS_PCU_INFO_DOM_OFFSET 17 +#define IMS_PCU_INFO_SERIAL_OFFSET 25 + +#define IMS_PCU_SET_INFO_SIZE 31 + +static int ims_pcu_get_info(struct ims_pcu *pcu) +{ + int error; + + error = ims_pcu_execute_query(pcu, GET_INFO); + if (error) { + dev_err(pcu->dev, + "GET_INFO command failed, error: %d\n", error); + return error; + } + + memcpy(pcu->part_number, + &pcu->cmd_buf[IMS_PCU_INFO_PART_OFFSET], + sizeof(pcu->part_number)); + memcpy(pcu->date_of_manufacturing, + &pcu->cmd_buf[IMS_PCU_INFO_DOM_OFFSET], + sizeof(pcu->date_of_manufacturing)); + memcpy(pcu->serial_number, + &pcu->cmd_buf[IMS_PCU_INFO_SERIAL_OFFSET], + sizeof(pcu->serial_number)); + + return 0; +} + +static int ims_pcu_set_info(struct ims_pcu *pcu) +{ + int error; + + memcpy(&pcu->cmd_buf[IMS_PCU_INFO_PART_OFFSET], + pcu->part_number, sizeof(pcu->part_number)); + memcpy(&pcu->cmd_buf[IMS_PCU_INFO_DOM_OFFSET], + pcu->date_of_manufacturing, sizeof(pcu->date_of_manufacturing)); + memcpy(&pcu->cmd_buf[IMS_PCU_INFO_SERIAL_OFFSET], + pcu->serial_number, sizeof(pcu->serial_number)); + + error = ims_pcu_execute_command(pcu, SET_INFO, + &pcu->cmd_buf[IMS_PCU_DATA_OFFSET], + IMS_PCU_SET_INFO_SIZE); + if (error) { + dev_err(pcu->dev, + "Failed to update device information, error: %d\n", + error); + return error; + } + + return 0; +} + +static int ims_pcu_switch_to_bootloader(struct ims_pcu *pcu) +{ + int error; + + /* Execute jump to the bootoloader */ + error = ims_pcu_execute_command(pcu, JUMP_TO_BTLDR, NULL, 0); + if (error) { + dev_err(pcu->dev, + "Failure when sending JUMP TO BOOLTLOADER command, error: %d\n", + error); + return error; + } + + return 0; +} + +/********************************************************************* + * Firmware Update handling * + *********************************************************************/ + +#define IMS_PCU_FIRMWARE_NAME "imspcu.fw" + +struct ims_pcu_flash_fmt { + __le32 addr; + u8 len; + u8 data[]; +}; + +static unsigned int ims_pcu_count_fw_records(const struct firmware *fw) +{ + const struct ihex_binrec *rec = (const struct ihex_binrec *)fw->data; + unsigned int count = 0; + + while (rec) { + count++; + rec = ihex_next_binrec(rec); + } + + return count; +} + +static int ims_pcu_verify_block(struct ims_pcu *pcu, + u32 addr, u8 len, const u8 *data) +{ + struct ims_pcu_flash_fmt *fragment; + int error; + + fragment = (void *)&pcu->cmd_buf[1]; + put_unaligned_le32(addr, &fragment->addr); + fragment->len = len; + + error = ims_pcu_execute_bl_command(pcu, READ_APP, NULL, 5, + IMS_PCU_CMD_RESPONSE_TIMEOUT); + if (error) { + dev_err(pcu->dev, + "Failed to retrieve block at 0x%08x, len %d, error: %d\n", + addr, len, error); + return error; + } + + fragment = (void *)&pcu->cmd_buf[IMS_PCU_BL_DATA_OFFSET]; + if (get_unaligned_le32(&fragment->addr) != addr || + fragment->len != len) { + dev_err(pcu->dev, + "Wrong block when retrieving 0x%08x (0x%08x), len %d (%d)\n", + addr, get_unaligned_le32(&fragment->addr), + len, fragment->len); + return -EINVAL; + } + + if (memcmp(fragment->data, data, len)) { + dev_err(pcu->dev, + "Mismatch in block at 0x%08x, len %d\n", + addr, len); + return -EINVAL; + } + + return 0; +} + +static int ims_pcu_flash_firmware(struct ims_pcu *pcu, + const struct firmware *fw, + unsigned int n_fw_records) +{ + const struct ihex_binrec *rec = (const struct ihex_binrec *)fw->data; + struct ims_pcu_flash_fmt *fragment; + unsigned int count = 0; + u32 addr; + u8 len; + int error; + + error = ims_pcu_execute_bl_command(pcu, ERASE_APP, NULL, 0, 2000); + if (error) { + dev_err(pcu->dev, + "Failed to erase application image, error: %d\n", + error); + return error; + } + + while (rec) { + /* + * The firmware format is messed up for some reason. + * The address twice that of what is needed for some + * reason and we end up overwriting half of the data + * with the next record. + */ + addr = be32_to_cpu(rec->addr) / 2; + len = be16_to_cpu(rec->len); + + fragment = (void *)&pcu->cmd_buf[1]; + put_unaligned_le32(addr, &fragment->addr); + fragment->len = len; + memcpy(fragment->data, rec->data, len); + + error = ims_pcu_execute_bl_command(pcu, PROGRAM_DEVICE, + NULL, len + 5, + IMS_PCU_CMD_RESPONSE_TIMEOUT); + if (error) { + dev_err(pcu->dev, + "Failed to write block at 0x%08x, len %d, error: %d\n", + addr, len, error); + return error; + } + + if (addr >= pcu->fw_start_addr && addr < pcu->fw_end_addr) { + error = ims_pcu_verify_block(pcu, addr, len, rec->data); + if (error) + return error; + } + + count++; + pcu->update_firmware_status = (count * 100) / n_fw_records; + + rec = ihex_next_binrec(rec); + } + + error = ims_pcu_execute_bl_command(pcu, PROGRAM_COMPLETE, + NULL, 0, 2000); + if (error) + dev_err(pcu->dev, + "Failed to send PROGRAM_COMPLETE, error: %d\n", + error); + + return 0; +} + +static int ims_pcu_handle_firmware_update(struct ims_pcu *pcu, + const struct firmware *fw) +{ + unsigned int n_fw_records; + int retval; + + dev_info(pcu->dev, "Updating firmware %s, size: %zu\n", + IMS_PCU_FIRMWARE_NAME, fw->size); + + n_fw_records = ims_pcu_count_fw_records(fw); + + retval = ims_pcu_flash_firmware(pcu, fw, n_fw_records); + if (retval) + goto out; + + retval = ims_pcu_execute_bl_command(pcu, LAUNCH_APP, NULL, 0, 0); + if (retval) + dev_err(pcu->dev, + "Failed to start application image, error: %d\n", + retval); + +out: + pcu->update_firmware_status = retval; + sysfs_notify(&pcu->dev->kobj, NULL, "update_firmware_status"); + return retval; +} + +static void ims_pcu_process_async_firmware(const struct firmware *fw, + void *context) +{ + struct ims_pcu *pcu = context; + int error; + + if (!fw) { + dev_err(pcu->dev, "Failed to get firmware %s\n", + IMS_PCU_FIRMWARE_NAME); + goto out; + } + + error = ihex_validate_fw(fw); + if (error) { + dev_err(pcu->dev, "Firmware %s is invalid\n", + IMS_PCU_FIRMWARE_NAME); + goto out; + } + + mutex_lock(&pcu->cmd_mutex); + ims_pcu_handle_firmware_update(pcu, fw); + mutex_unlock(&pcu->cmd_mutex); + + release_firmware(fw); + +out: + complete(&pcu->async_firmware_done); +} + +/********************************************************************* + * Backlight LED device support * + *********************************************************************/ + +#define IMS_PCU_MAX_BRIGHTNESS 31998 + +static void ims_pcu_backlight_work(struct work_struct *work) +{ + struct ims_pcu_backlight *backlight = + container_of(work, struct ims_pcu_backlight, work); + struct ims_pcu *pcu = + container_of(backlight, struct ims_pcu, backlight); + int desired_brightness = backlight->desired_brightness; + __le16 br_val = cpu_to_le16(desired_brightness); + int error; + + mutex_lock(&pcu->cmd_mutex); + + error = ims_pcu_execute_command(pcu, SET_BRIGHTNESS, + &br_val, sizeof(br_val)); + if (error && error != -ENODEV) + dev_warn(pcu->dev, + "Failed to set desired brightness %u, error: %d\n", + desired_brightness, error); + + mutex_unlock(&pcu->cmd_mutex); +} + +static void ims_pcu_backlight_set_brightness(struct led_classdev *cdev, + enum led_brightness value) +{ + struct ims_pcu_backlight *backlight = + container_of(cdev, struct ims_pcu_backlight, cdev); + + backlight->desired_brightness = value; + schedule_work(&backlight->work); +} + +static enum led_brightness +ims_pcu_backlight_get_brightness(struct led_classdev *cdev) +{ + struct ims_pcu_backlight *backlight = + container_of(cdev, struct ims_pcu_backlight, cdev); + struct ims_pcu *pcu = + container_of(backlight, struct ims_pcu, backlight); + int brightness; + int error; + + mutex_lock(&pcu->cmd_mutex); + + error = ims_pcu_execute_query(pcu, GET_BRIGHTNESS); + if (error) { + dev_warn(pcu->dev, + "Failed to get current brightness, error: %d\n", + error); + /* Assume the LED is OFF */ + brightness = LED_OFF; + } else { + brightness = + get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]); + } + + mutex_unlock(&pcu->cmd_mutex); + + return brightness; +} + +static int ims_pcu_setup_backlight(struct ims_pcu *pcu) +{ + struct ims_pcu_backlight *backlight = &pcu->backlight; + int error; + + INIT_WORK(&backlight->work, ims_pcu_backlight_work); + snprintf(backlight->name, sizeof(backlight->name), + "pcu%d::kbd_backlight", pcu->device_no); + + backlight->cdev.name = backlight->name; + backlight->cdev.max_brightness = IMS_PCU_MAX_BRIGHTNESS; + backlight->cdev.brightness_get = ims_pcu_backlight_get_brightness; + backlight->cdev.brightness_set = ims_pcu_backlight_set_brightness; + + error = led_classdev_register(pcu->dev, &backlight->cdev); + if (error) { + dev_err(pcu->dev, + "Failed to register backlight LED device, error: %d\n", + error); + return error; + } + + return 0; +} + +static void ims_pcu_destroy_backlight(struct ims_pcu *pcu) +{ + struct ims_pcu_backlight *backlight = &pcu->backlight; + + led_classdev_unregister(&backlight->cdev); + cancel_work_sync(&backlight->work); +} + + +/********************************************************************* + * Sysfs attributes handling * + *********************************************************************/ + +struct ims_pcu_attribute { + struct device_attribute dattr; + size_t field_offset; + int field_length; +}; + +static ssize_t ims_pcu_attribute_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + struct ims_pcu_attribute *attr = + container_of(dattr, struct ims_pcu_attribute, dattr); + char *field = (char *)pcu + attr->field_offset; + + return scnprintf(buf, PAGE_SIZE, "%.*s\n", attr->field_length, field); +} + +static ssize_t ims_pcu_attribute_store(struct device *dev, + struct device_attribute *dattr, + const char *buf, size_t count) +{ + + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + struct ims_pcu_attribute *attr = + container_of(dattr, struct ims_pcu_attribute, dattr); + char *field = (char *)pcu + attr->field_offset; + size_t data_len; + int error; + + if (count > attr->field_length) + return -EINVAL; + + data_len = strnlen(buf, attr->field_length); + if (data_len > attr->field_length) + return -EINVAL; + + error = mutex_lock_interruptible(&pcu->cmd_mutex); + if (error) + return error; + + memset(field, 0, attr->field_length); + memcpy(field, buf, data_len); + + error = ims_pcu_set_info(pcu); + + /* + * Even if update failed, let's fetch the info again as we just + * clobbered one of the fields. + */ + ims_pcu_get_info(pcu); + + mutex_unlock(&pcu->cmd_mutex); + + return error < 0 ? error : count; +} + +#define IMS_PCU_ATTR(_field, _mode) \ +struct ims_pcu_attribute ims_pcu_attr_##_field = { \ + .dattr = __ATTR(_field, _mode, \ + ims_pcu_attribute_show, \ + ims_pcu_attribute_store), \ + .field_offset = offsetof(struct ims_pcu, _field), \ + .field_length = sizeof(((struct ims_pcu *)NULL)->_field), \ +} + +#define IMS_PCU_RO_ATTR(_field) \ + IMS_PCU_ATTR(_field, S_IRUGO) +#define IMS_PCU_RW_ATTR(_field) \ + IMS_PCU_ATTR(_field, S_IRUGO | S_IWUSR) + +static IMS_PCU_RW_ATTR(part_number); +static IMS_PCU_RW_ATTR(serial_number); +static IMS_PCU_RW_ATTR(date_of_manufacturing); + +static IMS_PCU_RO_ATTR(fw_version); +static IMS_PCU_RO_ATTR(bl_version); +static IMS_PCU_RO_ATTR(reset_reason); + +static ssize_t ims_pcu_reset_device(struct device *dev, + struct device_attribute *dattr, + const char *buf, size_t count) +{ + static const u8 reset_byte = 1; + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + int value; + int error; + + error = kstrtoint(buf, 0, &value); + if (error) + return error; + + if (value != 1) + return -EINVAL; + + dev_info(pcu->dev, "Attempting to reset device\n"); + + error = ims_pcu_execute_command(pcu, PCU_RESET, &reset_byte, 1); + if (error) { + dev_info(pcu->dev, + "Failed to reset device, error: %d\n", + error); + return error; + } + + return count; +} + +static DEVICE_ATTR(reset_device, S_IWUSR, NULL, ims_pcu_reset_device); + +static ssize_t ims_pcu_update_firmware_store(struct device *dev, + struct device_attribute *dattr, + const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + const struct firmware *fw; + int value; + int error; + + error = kstrtoint(buf, 0, &value); + if (error) + return error; + + if (value != 1) + return -EINVAL; + + error = mutex_lock_interruptible(&pcu->cmd_mutex); + if (error) + return error; + + error = request_ihex_firmware(&fw, IMS_PCU_FIRMWARE_NAME, pcu->dev); + if (error) { + dev_err(pcu->dev, "Failed to request firmware %s, error: %d\n", + IMS_PCU_FIRMWARE_NAME, error); + goto out; + } + + /* + * If we are already in bootloader mode we can proceed with + * flashing the firmware. + * + * If we are in application mode, then we need to switch into + * bootloader mode, which will cause the device to disconnect + * and reconnect as different device. + */ + if (pcu->bootloader_mode) + error = ims_pcu_handle_firmware_update(pcu, fw); + else + error = ims_pcu_switch_to_bootloader(pcu); + + release_firmware(fw); + +out: + mutex_unlock(&pcu->cmd_mutex); + return error ?: count; +} + +static DEVICE_ATTR(update_firmware, S_IWUSR, + NULL, ims_pcu_update_firmware_store); + +static ssize_t +ims_pcu_update_firmware_status_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + + return scnprintf(buf, PAGE_SIZE, "%d\n", pcu->update_firmware_status); +} + +static DEVICE_ATTR(update_firmware_status, S_IRUGO, + ims_pcu_update_firmware_status_show, NULL); + +static struct attribute *ims_pcu_attrs[] = { + &ims_pcu_attr_part_number.dattr.attr, + &ims_pcu_attr_serial_number.dattr.attr, + &ims_pcu_attr_date_of_manufacturing.dattr.attr, + &ims_pcu_attr_fw_version.dattr.attr, + &ims_pcu_attr_bl_version.dattr.attr, + &ims_pcu_attr_reset_reason.dattr.attr, + &dev_attr_reset_device.attr, + &dev_attr_update_firmware.attr, + &dev_attr_update_firmware_status.attr, + NULL +}; + +static umode_t ims_pcu_is_attr_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + umode_t mode = attr->mode; + + if (pcu->bootloader_mode) { + if (attr != &dev_attr_update_firmware_status.attr && + attr != &dev_attr_update_firmware.attr && + attr != &dev_attr_reset_device.attr) { + mode = 0; + } + } else { + if (attr == &dev_attr_update_firmware_status.attr) + mode = 0; + } + + return mode; +} + +static struct attribute_group ims_pcu_attr_group = { + .is_visible = ims_pcu_is_attr_visible, + .attrs = ims_pcu_attrs, +}; + +static void ims_pcu_irq(struct urb *urb) +{ + struct ims_pcu *pcu = urb->context; + int retval, status; + + status = urb->status; + + switch (status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dev_dbg(pcu->dev, "%s - urb shutting down with status: %d\n", + __func__, status); + return; + default: + dev_dbg(pcu->dev, "%s - nonzero urb status received: %d\n", + __func__, status); + goto exit; + } + + dev_dbg(pcu->dev, "%s: received %d: %*ph\n", __func__, + urb->actual_length, urb->actual_length, pcu->urb_in_buf); + + if (urb == pcu->urb_in) + ims_pcu_process_data(pcu, urb); + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval && retval != -ENODEV) + dev_err(pcu->dev, "%s - usb_submit_urb failed with result %d\n", + __func__, retval); +} + +static int ims_pcu_buffers_alloc(struct ims_pcu *pcu) +{ + int error; + + pcu->urb_in_buf = usb_alloc_coherent(pcu->udev, pcu->max_in_size, + GFP_KERNEL, &pcu->read_dma); + if (!pcu->urb_in_buf) { + dev_err(pcu->dev, + "Failed to allocate memory for read buffer\n"); + return -ENOMEM; + } + + pcu->urb_in = usb_alloc_urb(0, GFP_KERNEL); + if (!pcu->urb_in) { + dev_err(pcu->dev, "Failed to allocate input URB\n"); + error = -ENOMEM; + goto err_free_urb_in_buf; + } + + pcu->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + pcu->urb_in->transfer_dma = pcu->read_dma; + + usb_fill_bulk_urb(pcu->urb_in, pcu->udev, + usb_rcvbulkpipe(pcu->udev, + pcu->ep_in->bEndpointAddress), + pcu->urb_in_buf, pcu->max_in_size, + ims_pcu_irq, pcu); + + /* + * We are using usb_bulk_msg() for sending so there is no point + * in allocating memory with usb_alloc_coherent(). + */ + pcu->urb_out_buf = kmalloc(pcu->max_out_size, GFP_KERNEL); + if (!pcu->urb_out_buf) { + dev_err(pcu->dev, "Failed to allocate memory for write buffer\n"); + error = -ENOMEM; + goto err_free_in_urb; + } + + pcu->urb_ctrl_buf = usb_alloc_coherent(pcu->udev, pcu->max_ctrl_size, + GFP_KERNEL, &pcu->ctrl_dma); + if (!pcu->urb_ctrl_buf) { + dev_err(pcu->dev, + "Failed to allocate memory for read buffer\n"); + goto err_free_urb_out_buf; + } + + pcu->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL); + if (!pcu->urb_ctrl) { + dev_err(pcu->dev, "Failed to allocate input URB\n"); + error = -ENOMEM; + goto err_free_urb_ctrl_buf; + } + + pcu->urb_ctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + pcu->urb_ctrl->transfer_dma = pcu->ctrl_dma; + + usb_fill_int_urb(pcu->urb_ctrl, pcu->udev, + usb_rcvintpipe(pcu->udev, + pcu->ep_ctrl->bEndpointAddress), + pcu->urb_ctrl_buf, pcu->max_ctrl_size, + ims_pcu_irq, pcu, pcu->ep_ctrl->bInterval); + + return 0; + +err_free_urb_ctrl_buf: + usb_free_coherent(pcu->udev, pcu->max_ctrl_size, + pcu->urb_ctrl_buf, pcu->ctrl_dma); +err_free_urb_out_buf: + kfree(pcu->urb_out_buf); +err_free_in_urb: + usb_free_urb(pcu->urb_in); +err_free_urb_in_buf: + usb_free_coherent(pcu->udev, pcu->max_in_size, + pcu->urb_in_buf, pcu->read_dma); + return error; +} + +static void ims_pcu_buffers_free(struct ims_pcu *pcu) +{ + usb_kill_urb(pcu->urb_in); + usb_free_urb(pcu->urb_in); + + usb_free_coherent(pcu->udev, pcu->max_out_size, + pcu->urb_in_buf, pcu->read_dma); + + kfree(pcu->urb_out_buf); + + usb_kill_urb(pcu->urb_ctrl); + usb_free_urb(pcu->urb_ctrl); + + usb_free_coherent(pcu->udev, pcu->max_ctrl_size, + pcu->urb_ctrl_buf, pcu->ctrl_dma); +} + +static const struct usb_cdc_union_desc * +ims_pcu_get_cdc_union_desc(struct usb_interface *intf) +{ + const void *buf = intf->altsetting->extra; + size_t buflen = intf->altsetting->extralen; + struct usb_cdc_union_desc *union_desc; + + if (!buf) { + dev_err(&intf->dev, "Missing descriptor data\n"); + return NULL; + } + + if (!buflen) { + dev_err(&intf->dev, "Zero length descriptor\n"); + return NULL; + } + + while (buflen > 0) { + union_desc = (struct usb_cdc_union_desc *)buf; + + if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE && + union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) { + dev_dbg(&intf->dev, "Found union header\n"); + return union_desc; + } + + buflen -= union_desc->bLength; + buf += union_desc->bLength; + } + + dev_err(&intf->dev, "Missing CDC union descriptor\n"); + return NULL; +} + +static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pcu) +{ + const struct usb_cdc_union_desc *union_desc; + struct usb_host_interface *alt; + + union_desc = ims_pcu_get_cdc_union_desc(intf); + if (!union_desc) + return -EINVAL; + + pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bMasterInterface0); + + alt = pcu->ctrl_intf->cur_altsetting; + pcu->ep_ctrl = &alt->endpoint[0].desc; + pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl); + + pcu->data_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bSlaveInterface0); + + alt = pcu->data_intf->cur_altsetting; + if (alt->desc.bNumEndpoints != 2) { + dev_err(pcu->dev, + "Incorrect number of endpoints on data interface (%d)\n", + alt->desc.bNumEndpoints); + return -EINVAL; + } + + pcu->ep_out = &alt->endpoint[0].desc; + if (!usb_endpoint_is_bulk_out(pcu->ep_out)) { + dev_err(pcu->dev, + "First endpoint on data interface is not BULK OUT\n"); + return -EINVAL; + } + + pcu->max_out_size = usb_endpoint_maxp(pcu->ep_out); + if (pcu->max_out_size < 8) { + dev_err(pcu->dev, + "Max OUT packet size is too small (%zd)\n", + pcu->max_out_size); + return -EINVAL; + } + + pcu->ep_in = &alt->endpoint[1].desc; + if (!usb_endpoint_is_bulk_in(pcu->ep_in)) { + dev_err(pcu->dev, + "Second endpoint on data interface is not BULK IN\n"); + return -EINVAL; + } + + pcu->max_in_size = usb_endpoint_maxp(pcu->ep_in); + if (pcu->max_in_size < 8) { + dev_err(pcu->dev, + "Max IN packet size is too small (%zd)\n", + pcu->max_in_size); + return -EINVAL; + } + + return 0; +} + +static int ims_pcu_start_io(struct ims_pcu *pcu) +{ + int error; + + error = usb_submit_urb(pcu->urb_ctrl, GFP_KERNEL); + if (error) { + dev_err(pcu->dev, + "Failed to start control IO - usb_submit_urb failed with result: %d\n", + error); + return -EIO; + } + + error = usb_submit_urb(pcu->urb_in, GFP_KERNEL); + if (error) { + dev_err(pcu->dev, + "Failed to start IO - usb_submit_urb failed with result: %d\n", + error); + usb_kill_urb(pcu->urb_ctrl); + return -EIO; + } + + return 0; +} + +static void ims_pcu_stop_io(struct ims_pcu *pcu) +{ + usb_kill_urb(pcu->urb_in); + usb_kill_urb(pcu->urb_ctrl); +} + +static int ims_pcu_line_setup(struct ims_pcu *pcu) +{ + struct usb_host_interface *interface = pcu->ctrl_intf->cur_altsetting; + struct usb_cdc_line_coding *line = (void *)pcu->cmd_buf; + int error; + + memset(line, 0, sizeof(*line)); + line->dwDTERate = cpu_to_le32(57600); + line->bDataBits = 8; + + error = usb_control_msg(pcu->udev, usb_sndctrlpipe(pcu->udev, 0), + USB_CDC_REQ_SET_LINE_CODING, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, interface->desc.bInterfaceNumber, + line, sizeof(struct usb_cdc_line_coding), + 5000); + if (error < 0) { + dev_err(pcu->dev, "Failed to set line coding, error: %d\n", + error); + return error; + } + + error = usb_control_msg(pcu->udev, usb_sndctrlpipe(pcu->udev, 0), + USB_CDC_REQ_SET_CONTROL_LINE_STATE, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0x03, interface->desc.bInterfaceNumber, + NULL, 0, 5000); + if (error < 0) { + dev_err(pcu->dev, "Failed to set line state, error: %d\n", + error); + return error; + } + + return 0; +} + +static int ims_pcu_get_device_info(struct ims_pcu *pcu) +{ + int error; + + error = ims_pcu_get_info(pcu); + if (error) + return error; + + error = ims_pcu_execute_query(pcu, GET_FW_VERSION); + if (error) { + dev_err(pcu->dev, + "GET_FW_VERSION command failed, error: %d\n", error); + return error; + } + + snprintf(pcu->fw_version, sizeof(pcu->fw_version), + "%02d%02d%02d%02d.%c%c", + pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5], + pcu->cmd_buf[6], pcu->cmd_buf[7]); + + error = ims_pcu_execute_query(pcu, GET_BL_VERSION); + if (error) { + dev_err(pcu->dev, + "GET_BL_VERSION command failed, error: %d\n", error); + return error; + } + + snprintf(pcu->bl_version, sizeof(pcu->bl_version), + "%02d%02d%02d%02d.%c%c", + pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5], + pcu->cmd_buf[6], pcu->cmd_buf[7]); + + error = ims_pcu_execute_query(pcu, RESET_REASON); + if (error) { + dev_err(pcu->dev, + "RESET_REASON command failed, error: %d\n", error); + return error; + } + + snprintf(pcu->reset_reason, sizeof(pcu->reset_reason), + "%02x", pcu->cmd_buf[IMS_PCU_DATA_OFFSET]); + + dev_dbg(pcu->dev, + "P/N: %s, MD: %s, S/N: %s, FW: %s, BL: %s, RR: %s\n", + pcu->part_number, + pcu->date_of_manufacturing, + pcu->serial_number, + pcu->fw_version, + pcu->bl_version, + pcu->reset_reason); + + return 0; +} + +static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id) +{ + int error; + + error = ims_pcu_execute_query(pcu, GET_DEVICE_ID); + if (error) { + dev_err(pcu->dev, + "GET_DEVICE_ID command failed, error: %d\n", error); + return error; + } + + *device_id = pcu->cmd_buf[IMS_PCU_DATA_OFFSET]; + dev_dbg(pcu->dev, "Detected device ID: %d\n", *device_id); + + return 0; +} + +static int ims_pcu_init_application_mode(struct ims_pcu *pcu) +{ + static atomic_t device_no = ATOMIC_INIT(0); + + const struct ims_pcu_device_info *info; + u8 device_id; + int error; + + error = ims_pcu_get_device_info(pcu); + if (error) { + /* Device does not respond to basic queries, hopeless */ + return error; + } + + error = ims_pcu_identify_type(pcu, &device_id); + if (error) { + dev_err(pcu->dev, + "Failed to identify device, error: %d\n", error); + /* + * Do not signal error, but do not create input nor + * backlight devices either, let userspace figure this + * out (flash a new firmware?). + */ + return 0; + } + + if (device_id >= ARRAY_SIZE(ims_pcu_device_info) || + !ims_pcu_device_info[device_id].keymap) { + dev_err(pcu->dev, "Device ID %d is not valid\n", device_id); + /* Same as above, punt to userspace */ + return 0; + } + + /* Device appears to be operable, complete initialization */ + pcu->device_no = atomic_inc_return(&device_no) - 1; + + error = ims_pcu_setup_backlight(pcu); + if (error) + return error; + + info = &ims_pcu_device_info[device_id]; + error = ims_pcu_setup_buttons(pcu, info->keymap, info->keymap_len); + if (error) + goto err_destroy_backlight; + + if (info->has_gamepad) { + error = ims_pcu_setup_gamepad(pcu); + if (error) + goto err_destroy_buttons; + } + + pcu->setup_complete = true; + + return 0; + +err_destroy_backlight: + ims_pcu_destroy_backlight(pcu); +err_destroy_buttons: + ims_pcu_destroy_buttons(pcu); + return error; +} + +static void ims_pcu_destroy_application_mode(struct ims_pcu *pcu) +{ + if (pcu->setup_complete) { + pcu->setup_complete = false; + mb(); /* make sure flag setting is not reordered */ + + if (pcu->gamepad) + ims_pcu_destroy_gamepad(pcu); + ims_pcu_destroy_buttons(pcu); + ims_pcu_destroy_backlight(pcu); + } +} + +static int ims_pcu_init_bootloader_mode(struct ims_pcu *pcu) +{ + int error; + + error = ims_pcu_execute_bl_command(pcu, QUERY_DEVICE, NULL, 0, + IMS_PCU_CMD_RESPONSE_TIMEOUT); + if (error) { + dev_err(pcu->dev, "Bootloader does not respond, aborting\n"); + return error; + } + + pcu->fw_start_addr = + get_unaligned_le32(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET + 11]); + pcu->fw_end_addr = + get_unaligned_le32(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET + 15]); + + dev_info(pcu->dev, + "Device is in bootloader mode (addr 0x%08x-0x%08x), requesting firmware\n", + pcu->fw_start_addr, pcu->fw_end_addr); + + error = request_firmware_nowait(THIS_MODULE, true, + IMS_PCU_FIRMWARE_NAME, + pcu->dev, GFP_KERNEL, pcu, + ims_pcu_process_async_firmware); + if (error) { + /* This error is not fatal, let userspace have another chance */ + complete(&pcu->async_firmware_done); + } + + return 0; +} + +static void ims_pcu_destroy_bootloader_mode(struct ims_pcu *pcu) +{ + /* Make sure our initial firmware request has completed */ + wait_for_completion(&pcu->async_firmware_done); +} + +#define IMS_PCU_APPLICATION_MODE 0 +#define IMS_PCU_BOOTLOADER_MODE 1 + +static struct usb_driver ims_pcu_driver; + +static int ims_pcu_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct ims_pcu *pcu; + int error; + + pcu = kzalloc(sizeof(struct ims_pcu), GFP_KERNEL); + if (!pcu) + return -ENOMEM; + + pcu->dev = &intf->dev; + pcu->udev = udev; + pcu->bootloader_mode = id->driver_info == IMS_PCU_BOOTLOADER_MODE; + mutex_init(&pcu->cmd_mutex); + init_completion(&pcu->cmd_done); + init_completion(&pcu->async_firmware_done); + + error = ims_pcu_parse_cdc_data(intf, pcu); + if (error) + goto err_free_mem; + + error = usb_driver_claim_interface(&ims_pcu_driver, + pcu->data_intf, pcu); + if (error) { + dev_err(&intf->dev, + "Unable to claim corresponding data interface: %d\n", + error); + goto err_free_mem; + } + + usb_set_intfdata(pcu->ctrl_intf, pcu); + usb_set_intfdata(pcu->data_intf, pcu); + + error = ims_pcu_buffers_alloc(pcu); + if (error) + goto err_unclaim_intf; + + error = ims_pcu_start_io(pcu); + if (error) + goto err_free_buffers; + + error = ims_pcu_line_setup(pcu); + if (error) + goto err_stop_io; + + error = sysfs_create_group(&intf->dev.kobj, &ims_pcu_attr_group); + if (error) + goto err_stop_io; + + error = pcu->bootloader_mode ? + ims_pcu_init_bootloader_mode(pcu) : + ims_pcu_init_application_mode(pcu); + if (error) + goto err_remove_sysfs; + + return 0; + +err_remove_sysfs: + sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group); +err_stop_io: + ims_pcu_stop_io(pcu); +err_free_buffers: + ims_pcu_buffers_free(pcu); +err_unclaim_intf: + usb_driver_release_interface(&ims_pcu_driver, pcu->data_intf); +err_free_mem: + kfree(pcu); + return error; +} + +static void ims_pcu_disconnect(struct usb_interface *intf) +{ + struct ims_pcu *pcu = usb_get_intfdata(intf); + struct usb_host_interface *alt = intf->cur_altsetting; + + usb_set_intfdata(intf, NULL); + + /* + * See if we are dealing with control or data interface. The cleanup + * happens when we unbind primary (control) interface. + */ + if (alt->desc.bInterfaceClass != USB_CLASS_COMM) + return; + + sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group); + + ims_pcu_stop_io(pcu); + + if (pcu->bootloader_mode) + ims_pcu_destroy_bootloader_mode(pcu); + else + ims_pcu_destroy_application_mode(pcu); + + ims_pcu_buffers_free(pcu); + kfree(pcu); +} + +#ifdef CONFIG_PM +static int ims_pcu_suspend(struct usb_interface *intf, + pm_message_t message) +{ + struct ims_pcu *pcu = usb_get_intfdata(intf); + struct usb_host_interface *alt = intf->cur_altsetting; + + if (alt->desc.bInterfaceClass == USB_CLASS_COMM) + ims_pcu_stop_io(pcu); + + return 0; +} + +static int ims_pcu_resume(struct usb_interface *intf) +{ + struct ims_pcu *pcu = usb_get_intfdata(intf); + struct usb_host_interface *alt = intf->cur_altsetting; + int retval = 0; + + if (alt->desc.bInterfaceClass == USB_CLASS_COMM) { + retval = ims_pcu_start_io(pcu); + if (retval == 0) + retval = ims_pcu_line_setup(pcu); + } + + return retval; +} +#endif + +static const struct usb_device_id ims_pcu_id_table[] = { + { + USB_DEVICE_AND_INTERFACE_INFO(0x04d8, 0x0082, + USB_CLASS_COMM, + USB_CDC_SUBCLASS_ACM, + USB_CDC_ACM_PROTO_AT_V25TER), + .driver_info = IMS_PCU_APPLICATION_MODE, + }, + { + USB_DEVICE_AND_INTERFACE_INFO(0x04d8, 0x0083, + USB_CLASS_COMM, + USB_CDC_SUBCLASS_ACM, + USB_CDC_ACM_PROTO_AT_V25TER), + .driver_info = IMS_PCU_BOOTLOADER_MODE, + }, + { } +}; + +static struct usb_driver ims_pcu_driver = { + .name = "ims_pcu", + .id_table = ims_pcu_id_table, + .probe = ims_pcu_probe, + .disconnect = ims_pcu_disconnect, +#ifdef CONFIG_PM + .suspend = ims_pcu_suspend, + .resume = ims_pcu_resume, + .reset_resume = ims_pcu_resume, +#endif +}; + +module_usb_driver(ims_pcu_driver); + +MODULE_DESCRIPTION("IMS Passenger Control Unit driver"); +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_LICENSE("GPL"); -- cgit From 16142655269aaf580488e074eabfdcf0fb4e3687 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 2 Feb 2013 11:02:14 -0800 Subject: USB: cdc-acm - blacklist IMS PCU device The IMS PCU (Passenger Control Unit) device used custom protocol over serial line, so it is presenting itself as CDC ACM device. Now that we have proper in-kernel driver for it we need to black-list the device in cdc-acm driver. Acked-by: Greg Kroah-Hartman Signed-off-by: Dmitry Torokhov --- drivers/usb/class/cdc-acm.c | 13 +++++++++++++ drivers/usb/class/cdc-acm.h | 1 + 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6e49ec6f3adc..278bf5256a95 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -949,6 +949,10 @@ static int acm_probe(struct usb_interface *intf, /* normal quirks */ quirks = (unsigned long)id->driver_info; + + if (quirks == IGNORE_DEVICE) + return -ENODEV; + num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; /* handle quirks deadly to normal probing*/ @@ -1650,6 +1654,15 @@ static const struct usb_device_id acm_ids[] = { .driver_info = NO_DATA_INTERFACE, }, +#if IS_ENABLED(CONFIG_INPUT_IMS_PCU) + { USB_DEVICE(0x04d8, 0x0082), /* Application mode */ + .driver_info = IGNORE_DEVICE, + }, + { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */ + .driver_info = IGNORE_DEVICE, + }, +#endif + /* control interfaces without any protocol set */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE) }, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 35ef887b7417..0f76e4af600e 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -128,3 +128,4 @@ struct acm { #define NO_CAP_LINE 4 #define NOT_A_MODEM 8 #define NO_DATA_INTERFACE 16 +#define IGNORE_DEVICE 32 -- cgit From 94cc409be782a3fdbf86a4f8c9dd8c93e0fea395 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 12 Mar 2013 14:14:37 +0000 Subject: staging: comedi: adv_pci1710: restore PCI-1710HG support The Advantech PCI-1710HG is similar to the PCI-1710 but has a different set of ranges for analog input (HG = high gain). Because they share the same PCI vendor and device ID, the adv_pci1710 driver does not currently distinguish them. This is more of a problem since auto-configuration code was added to the driver (and manual configuration support removed), as the PCI-1710HG would be automatically configured as a PCI-1710. More recently, the unused code for PCI-1710HG support was #ifdef'ed out. In fact, the PCI-1710 and PCI-1710HG can be distinguished by considering the PCI subvendor and subdevice IDs according to the following table: vendor device subven subdev model treat as ====== ====== ====== ====== ============ ========== 0x13fe 0x1710 0x10b5 0x9050 PCI-1710S PCI-1710 0x13fe 0x1710 0x13fe 0x0000 PCI-1710 PCI-1710 0x13fe 0x1710 0x13fe 0xb100 PCI-1710B PCI-1710 0x13fe 0x1710 0x13fe 0xb200 PCI-1710B2 PCI-1710 0x13fe 0x1710 0x13fe 0xc100 PCI-1710C PCI-1710 0x13fe 0x1710 0x13fe 0xc200 PCI-1710C2 PCI-1710 0x13fe 0x1710 0x1000 0xd100 PCI-1710U PCI-1710 0x13fe 0x1710 0x13fe 0x0002 PCI-1710HG PCI-1710HG 0x13fe 0x1710 0x13fe 0xb102 PCI-1710HGB PCI-1710HG 0x13fe 0x1710 0x13fe 0xb202 PCI-1710HGB2 PCI-1710HG 0x13fe 0x1710 0x13fe 0xc102 PCI-1710HGC PCI-1710HG 0x13fe 0x1710 0x13fe 0xc202 PCI-1710HGC2 PCI-1710HG 0x13fe 0x1710 0x1000 0xd102 PCI-1710HGU PCI-1710HG The above information is extracted from Advantech's own GPL'ed Linux (non-Comedi) driver source from "advdaq-1.10.0001-1.tar.bz2" on their website. (0x13fe = PCI_VENDOR_ID_ADVANTECH, 0x10b5 = PCI_VENDOR_ID_PLX, 0x9050 = PCI_DEVICE_ID_PLX_9050, 0x1000 = PCI_VENDOR_ID_NCR or PCI_VENDOR_ID_LSI_LOGIC but I assume this subvendor ID was chosen "randomly".) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 86 ++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8683e2564618..2f6c2d72986d 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -50,17 +50,6 @@ Configuration options: #include "8253.h" #include "amcc_s5933.h" -/* - * The pci1710 and pci1710hg boards have the same device id! - * - * The only difference between these boards is in the - * supported analog input ranges. - * - * #define this if your card is a pci1710hg and you need the - * correct ranges reported to user space. - */ -#undef USE_PCI1710HG_RANGE - #define PCI171x_PARANOIDCHECK /* if defined, then is used code which control * correct channel number on every 12 bit * sample */ @@ -144,7 +133,6 @@ static const struct comedi_lrange range_pci1710_3 = { 9, { static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 }; -#ifdef USE_PCI1710HG_RANGE static const struct comedi_lrange range_pci1710hg = { 12, { BIP_RANGE(5), BIP_RANGE(0.5), @@ -164,7 +152,6 @@ static const struct comedi_lrange range_pci1710hg = { 12, { static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13 }; -#endif /* USE_PCI1710HG_RANGE */ static const struct comedi_lrange range_pci17x1 = { 5, { BIP_RANGE(10), @@ -193,6 +180,7 @@ static const struct comedi_lrange range_pci171x_da = { 2, { enum pci1710_boardid { BOARD_PCI1710, + BOARD_PCI1710HG, BOARD_PCI1711, BOARD_PCI1713, BOARD_PCI1720, @@ -233,13 +221,27 @@ static const struct boardtype boardtypes[] = { .n_counter = 1, .ai_maxdata = 0x0fff, .ao_maxdata = 0x0fff, -#ifndef USE_PCI1710HG_RANGE .rangelist_ai = &range_pci1710_3, .rangecode_ai = range_codes_pci1710_3, -#else + .rangelist_ao = &range_pci171x_da, + .ai_ns_min = 10000, + .fifo_half_size = 2048, + }, + [BOARD_PCI1710HG] = { + .name = "pci1710hg", + .iorange = IORANGE_171x, + .have_irq = 1, + .cardtype = TYPE_PCI171X, + .n_aichan = 16, + .n_aichand = 8, + .n_aochan = 2, + .n_dichan = 16, + .n_dochan = 16, + .n_counter = 1, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, .rangelist_ai = &range_pci1710hg, .rangecode_ai = range_codes_pci1710hg, -#endif .rangelist_ao = &range_pci171x_da, .ai_ns_min = 10000, .fifo_half_size = 2048, @@ -1397,7 +1399,57 @@ static int adv_pci1710_pci_probe(struct pci_dev *dev, } static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { - { PCI_VDEVICE(ADVANTECH, 0x1710), BOARD_PCI1710 }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0x0000), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xb100), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xb200), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xc100), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xc200), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd100), + .driver_data = BOARD_PCI1710, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0x0002), + .driver_data = BOARD_PCI1710HG, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xb102), + .driver_data = BOARD_PCI1710HG, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xb202), + .driver_data = BOARD_PCI1710HG, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xc102), + .driver_data = BOARD_PCI1710HG, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, + PCI_VENDOR_ID_ADVANTECH, 0xc202), + .driver_data = BOARD_PCI1710HG, + }, { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd102), + .driver_data = BOARD_PCI1710HG, + }, { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 }, { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 }, { PCI_VDEVICE(ADVANTECH, 0x1720), BOARD_PCI1720 }, -- cgit From f165d815d50f158be43aa12c5c800fd27bbecad3 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Tue, 12 Mar 2013 11:42:32 +0000 Subject: staging: comedi: adv_pci1724: new driver New comedi driver for Advantech PCI-1724U with modifications by Ian Abbott . Signed-off-by: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 10 + drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/adv_pci1724.c | 421 +++++++++++++++++++++++++++ 3 files changed, 432 insertions(+) create mode 100644 drivers/staging/comedi/drivers/adv_pci1724.c (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 1967852eeb17..109168ca9c36 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -728,6 +728,16 @@ config COMEDI_ADV_PCI1723 To compile this driver as a module, choose M here: the module will be called adv_pci1723. +config COMEDI_ADV_PCI1724 + tristate "Advantech PCI-1724U support" + ---help--- + Enable support for Advantech PCI-1724U cards. These are 32-channel + analog output cards with voltage and current loop output ranges and + 14-bit resolution. + + To compile this driver as a module, choose M here: the module will be + called adv_pci1724. + config COMEDI_ADV_PCI_DIO tristate "Advantech PCI DIO card support" select COMEDI_8255 diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 315e836ff99b..6cdef4514fbf 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o +obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200.o obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236.o diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c new file mode 100644 index 000000000000..f448e4db4d95 --- /dev/null +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -0,0 +1,421 @@ +/* + comedi/drivers/adv_pci1724.c + This is a driver for the Advantech PCI-1724U card. + + Author: Frank Mori Hess + Copyright (C) 2013 GnuBIO Inc + + COMEDI - Linux Control and Measurement Device Interface + Copyright (C) 1997-8 David A. Schleef + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +************************************************************************/ + +/* + +Driver: adv_1724 +Description: Advantech PCI-1724U +Author: Frank Mori Hess +Status: works +Updated: 2013-02-09 +Devices: [Advantech] PCI-1724U (adv_pci1724) + +Subdevice 0 is the analog output. +Subdevice 1 is the offset calibration for the analog output. +Subdevice 2 is the gain calibration for the analog output. + +The calibration offset and gains have quite a large effect +on the analog output, so it is possible to adjust the analog output to +have an output range significantly different from the board's +nominal output ranges. For a calibrated +/- 10V range, the analog +output's offset will be set somewhere near mid-range (0x2000) and its +gain will be near maximum (0x3fff). + +There is really no difference between the board's documented 0-20mA +versus 4-20mA output ranges. To pick one or the other is simply a matter +of adjusting the offset and gain calibration until the board outputs in +the desired range. + +Configuration options: + None + +Manual configuration of comedi devices is not supported by this driver; +supported PCI devices are configured as comedi devices automatically. + +*/ + +#include + +#include "../comedidev.h" + +#define PCI_VENDOR_ID_ADVANTECH 0x13fe + +#define NUM_AO_CHANNELS 32 + +/* register offsets */ +enum board_registers { + DAC_CONTROL_REG = 0x0, + SYNC_OUTPUT_REG = 0x4, + EEPROM_CONTROL_REG = 0x8, + SYNC_OUTPUT_TRIGGER_REG = 0xc, + BOARD_ID_REG = 0x10 +}; + +/* bit definitions for registers */ +enum dac_control_contents { + DAC_DATA_MASK = 0x3fff, + DAC_DESTINATION_MASK = 0xc000, + DAC_NORMAL_MODE = 0xc000, + DAC_OFFSET_MODE = 0x8000, + DAC_GAIN_MODE = 0x4000, + DAC_CHANNEL_SELECT_MASK = 0xf0000, + DAC_GROUP_SELECT_MASK = 0xf00000 +}; + +static uint32_t dac_data_bits(uint16_t dac_data) +{ + return dac_data & DAC_DATA_MASK; +} + +static uint32_t dac_channel_select_bits(unsigned channel) +{ + return (channel << 16) & DAC_CHANNEL_SELECT_MASK; +} + +static uint32_t dac_group_select_bits(unsigned group) +{ + return (1 << (20 + group)) & DAC_GROUP_SELECT_MASK; +} + +static uint32_t dac_channel_and_group_select_bits(unsigned comedi_channel) +{ + return dac_channel_select_bits(comedi_channel % 8) | + dac_group_select_bits(comedi_channel / 8); +} + +enum sync_output_contents { + SYNC_MODE = 0x1, + DAC_BUSY = 0x2, /* dac state machine is not ready */ +}; + +enum sync_output_trigger_contents { + SYNC_TRIGGER_BITS = 0x0 /* any value works */ +}; + +enum board_id_contents { + BOARD_ID_MASK = 0xf +}; + +static const struct comedi_lrange ao_ranges_1724 = { 4, + { + BIP_RANGE(10), + RANGE_mA(0, 20), + RANGE_mA(4, 20), + RANGE_unitless(0, 1) + } +}; + +static const struct comedi_lrange *const ao_range_list_1724[NUM_AO_CHANNELS] = { + [0 ... NUM_AO_CHANNELS - 1] = &ao_ranges_1724, +}; + +/* this structure is for data unique to this hardware driver. */ +struct adv_pci1724_private { + int ao_value[NUM_AO_CHANNELS]; + int offset_value[NUM_AO_CHANNELS]; + int gain_value[NUM_AO_CHANNELS]; +}; + +static int wait_for_dac_idle(struct comedi_device *dev) +{ + static const int timeout = 10000; + int i; + + for (i = 0; i < timeout; ++i) { + if ((inl(dev->iobase + SYNC_OUTPUT_REG) & DAC_BUSY) == 0) + break; + udelay(1); + } + if (i == timeout) { + comedi_error(dev, "Timed out waiting for dac to become idle."); + return -EIO; + } + return 0; +} + +static int set_dac(struct comedi_device *dev, unsigned mode, unsigned channel, + unsigned data) +{ + int retval; + unsigned control_bits; + + retval = wait_for_dac_idle(dev); + if (retval < 0) + return retval; + + control_bits = mode; + control_bits |= dac_channel_and_group_select_bits(channel); + control_bits |= dac_data_bits(data); + outl(control_bits, dev->iobase + DAC_CONTROL_REG); + return 0; +} + +static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + int channel = CR_CHAN(insn->chanspec); + int retval; + int i; + + /* turn off synchronous mode */ + outl(0, dev->iobase + SYNC_OUTPUT_REG); + + for (i = 0; i < insn->n; ++i) { + retval = set_dac(dev, DAC_NORMAL_MODE, channel, data[i]); + if (retval < 0) + return retval; + devpriv->ao_value[channel] = data[i]; + } + return insn->n; +} + +static int ao_readback_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + int channel = CR_CHAN(insn->chanspec); + int i; + + if (devpriv->ao_value[channel] < 0) { + comedi_error(dev, + "Cannot read back channels which have not yet been written to."); + return -EIO; + } + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_value[channel]; + + return insn->n; +} + +static int offset_write_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + int channel = CR_CHAN(insn->chanspec); + int retval; + int i; + + /* turn off synchronous mode */ + outl(0, dev->iobase + SYNC_OUTPUT_REG); + + for (i = 0; i < insn->n; ++i) { + retval = set_dac(dev, DAC_OFFSET_MODE, channel, data[i]); + if (retval < 0) + return retval; + devpriv->offset_value[channel] = data[i]; + } + + return insn->n; +} + +static int offset_read_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); + int i; + + if (devpriv->offset_value[channel] < 0) { + comedi_error(dev, + "Cannot read back channels which have not yet been written to."); + return -EIO; + } + for (i = 0; i < insn->n; i++) + data[i] = devpriv->offset_value[channel]; + + return insn->n; +} + +static int gain_write_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + int channel = CR_CHAN(insn->chanspec); + int retval; + int i; + + /* turn off synchronous mode */ + outl(0, dev->iobase + SYNC_OUTPUT_REG); + + for (i = 0; i < insn->n; ++i) { + retval = set_dac(dev, DAC_GAIN_MODE, channel, data[i]); + if (retval < 0) + return retval; + devpriv->gain_value[channel] = data[i]; + } + + return insn->n; +} + +static int gain_read_insn(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_insn *insn, + unsigned int *data) +{ + struct adv_pci1724_private *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); + int i; + + if (devpriv->gain_value[channel] < 0) { + comedi_error(dev, + "Cannot read back channels which have not yet been written to."); + return -EIO; + } + for (i = 0; i < insn->n; i++) + data[i] = devpriv->gain_value[channel]; + + return insn->n; +} + +/* Allocate and initialize the subdevice structures. + */ +static int setup_subdevices(struct comedi_device *dev) +{ + struct comedi_subdevice *s; + int ret; + + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; + + /* analog output subdevice */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; + s->n_chan = NUM_AO_CHANNELS; + s->maxdata = 0x3fff; + s->range_table_list = ao_range_list_1724; + s->insn_read = ao_readback_insn; + s->insn_write = ao_winsn; + + /* offset calibration */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = NUM_AO_CHANNELS; + s->insn_read = offset_read_insn; + s->insn_write = offset_write_insn; + s->maxdata = 0x3fff; + + /* gain calibration */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = NUM_AO_CHANNELS; + s->insn_read = gain_read_insn; + s->insn_write = gain_write_insn; + s->maxdata = 0x3fff; + + return 0; +} + +static int adv_pci1724_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct adv_pci1724_private *devpriv; + int i; + int retval; + unsigned int board_id; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + /* init software copies of output values to indicate we don't know + * what the output value is since it has never been written. */ + for (i = 0; i < NUM_AO_CHANNELS; ++i) { + devpriv->ao_value[i] = -1; + devpriv->offset_value[i] = -1; + devpriv->gain_value[i] = -1; + } + + dev->board_name = dev->driver->driver_name; + + retval = comedi_pci_enable(pcidev, dev->board_name); + if (retval) + return retval; + + dev->iobase = pci_resource_start(pcidev, 2); + board_id = inl(dev->iobase + BOARD_ID_REG) & BOARD_ID_MASK; + dev_info(dev->class_dev, "board id: %d\n", board_id); + + retval = setup_subdevices(dev); + if (retval < 0) + return retval; + + dev_info(dev->class_dev, "%s (pci %s) attached, board id: %u\n", + dev->board_name, pci_name(pcidev), board_id); + return 0; +} + +static void adv_pci1724_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (pcidev && dev->iobase) { + comedi_pci_disable(pcidev); + dev_info(dev->class_dev, "detached\n"); + } +} + +static struct comedi_driver adv_pci1724_driver = { + .driver_name = "adv_pci1724", + .module = THIS_MODULE, + .auto_attach = adv_pci1724_auto_attach, + .detach = adv_pci1724_detach, +}; + +static int adv_pci1724_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &adv_pci1724_driver, + id->driver_data); +} + +static DEFINE_PCI_DEVICE_TABLE(adv_pci1724_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1724) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adv_pci1724_pci_table); + +static struct pci_driver adv_pci1724_pci_driver = { + .name = "adv_pci1724", + .id_table = adv_pci1724_pci_table, + .probe = adv_pci1724_pci_probe, + .remove = comedi_pci_auto_unconfig, +}; + +module_comedi_pci_driver(adv_pci1724_driver, adv_pci1724_pci_driver); + +MODULE_AUTHOR("Frank Mori Hess "); +MODULE_DESCRIPTION("Advantech PCI-1724U Comedi driver"); +MODULE_LICENSE("GPL"); -- cgit From 8dd4a9665280eafc042d6420f6a21bf0d20c19d9 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 12 Mar 2013 01:34:45 -0400 Subject: staging: et131x: fix invalid fail after the call to eeprom_wait_ready should be err < 0 instead of if (err) which actually the read register value can be a positive number Acked-by: Mark Einon Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 42ae5e83f907..c7e9e1d6bf70 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -595,7 +595,7 @@ static int eeprom_write(struct et131x_adapter *adapter, u32 addr, u8 data) */ err = eeprom_wait_ready(pdev, NULL); - if (err) + if (err < 0) return err; /* 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0, @@ -709,7 +709,7 @@ static int eeprom_read(struct et131x_adapter *adapter, u32 addr, u8 *pdata) */ err = eeprom_wait_ready(pdev, NULL); - if (err) + if (err < 0) return err; /* Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, * and bits 1:0 both =0. Bit 5 should be set according to the type -- cgit From f4309c0f1463cdea69f958de169ed987fb4dfdb2 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:03:35 +0800 Subject: driver: staging: csr: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/drv.c | 4 ++-- drivers/staging/csr/netdev.c | 2 +- drivers/staging/csr/sdio_mmc.c | 3 +-- drivers/staging/csr/sme_native.c | 2 +- drivers/staging/csr/unifi_pdu_processing.c | 4 ++-- 5 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 3bd52fdeac3b..5520d6539f77 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -1815,7 +1815,7 @@ udi_log_event(ul_client_t *pcli, } /* Allocate log structure plus actual signal. */ - logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); + logptr = kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); if (logptr == NULL) { printk(KERN_ERR @@ -1890,7 +1890,7 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) } /* Allocate log structure plus actual signal. */ - logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + length, GFP_ATOMIC); + logptr = kmalloc(sizeof(udi_log_t) + length, GFP_ATOMIC); if (logptr == NULL) { unifi_error(priv, "Failed to allocate %d bytes for an SME message\n", sizeof(udi_log_t) + length); diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 7dad26f70175..a0177d998978 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -2365,7 +2365,7 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) rx_buffered_packets_t *rx_q_item; struct list_head *rx_list; - rx_q_item = (rx_buffered_packets_t *)kmalloc(sizeof(rx_buffered_packets_t), + rx_q_item = kmalloc(sizeof(rx_buffered_packets_t), GFP_KERNEL); if (rx_q_item == NULL) { unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n", diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index b6a16de08f4e..30271d35af55 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -1031,8 +1031,7 @@ uf_glue_sdio_probe(struct sdio_func *func, sdio_func_id(func), instance); /* Allocate context */ - sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction), - GFP_KERNEL); + sdio_ctx = kmalloc(sizeof(CsrSdioFunction), GFP_KERNEL); if (sdio_ctx == NULL) { sdio_release_host(func); return -ENOMEM; diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index 525fe1bce0e6..ca55249bde3e 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -273,7 +273,7 @@ sme_native_log_event(ul_client_t *pcli, } /* Allocate log structure plus actual signal. */ - logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); + logptr = kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL); if (logptr == NULL) { unifi_error(priv, diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index 95efc360cc2d..bf7c00a815ed 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -403,7 +403,7 @@ CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, - tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); + tx_q_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); if (tx_q_item == NULL) { unifi_error(priv, "Failed to allocate %d bytes for tx packet record\n", @@ -3282,7 +3282,7 @@ void add_to_send_cfm_list(unifi_priv_t * priv, { tx_buffered_packets_t *send_cfm_list_item = NULL; - send_cfm_list_item = (tx_buffered_packets_t *) kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); + send_cfm_list_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); if(send_cfm_list_item == NULL){ unifi_warning(priv, "%s: Failed to allocate memory for new list item \n"); -- cgit From d9909ebe650f028459b9be5a2321fee520b446b0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 2 Dec 2012 17:59:57 +0100 Subject: ARM: spear: make clock driver independent of headers Device drivers should not access MMIO registers through hardcoded platform specific address constants. Instead, we can pass the MMIO token to the spear clock driver in the initialization routine to contain that knowledge in the platform code itself. Ideally, the clock driver would use of_iomap() or similar to get the address, and that can be used later, but for now, this is the minimal change. Signed-off-by: Arnd Bergmann Acked-by: Viresh Kumar --- arch/arm/mach-spear/generic.h | 13 +++--- arch/arm/mach-spear/include/mach/misc_regs.h | 2 +- arch/arm/mach-spear/include/mach/spear.h | 28 +++++------- arch/arm/mach-spear/spear1310.c | 2 - arch/arm/mach-spear/spear13xx.c | 4 +- arch/arm/mach-spear/spear320.c | 2 +- arch/arm/mach-spear/spear3xx.c | 7 +-- arch/arm/mach-spear/spear6xx.c | 9 ++-- drivers/clk/spear/spear1310_clock.c | 64 ++++++++++++++-------------- drivers/clk/spear/spear1340_clock.c | 63 ++++++++++++++------------- drivers/clk/spear/spear3xx_clock.c | 60 +++++++++++++++----------- drivers/clk/spear/spear6xx_clock.c | 31 +++++++------- 12 files changed, 143 insertions(+), 142 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h index af47d9b0d83d..8ba7e75b648d 100644 --- a/arch/arm/mach-spear/generic.h +++ b/arch/arm/mach-spear/generic.h @@ -29,10 +29,11 @@ extern struct dw_dma_slave nand_write_dma_priv; bool dw_dma_filter(struct dma_chan *chan, void *slave); void __init spear_setup_of_timer(void); -void __init spear3xx_clk_init(void); +void __init spear3xx_clk_init(void __iomem *misc_base, + void __iomem *soc_config_base); void __init spear3xx_map_io(void); void __init spear3xx_dt_init_irq(void); -void __init spear6xx_clk_init(void); +void __init spear6xx_clk_init(void __iomem *misc_base); void __init spear13xx_map_io(void); void __init spear13xx_l2x0_init(void); @@ -44,15 +45,15 @@ void __cpuinit spear13xx_cpu_die(unsigned int cpu); extern struct smp_operations spear13xx_smp_ops; #ifdef CONFIG_MACH_SPEAR1310 -void __init spear1310_clk_init(void); +void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base); #else -static inline void spear1310_clk_init(void) {} +static inline void spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) {} #endif #ifdef CONFIG_MACH_SPEAR1340 -void __init spear1340_clk_init(void); +void __init spear1340_clk_init(void __iomem *misc_base); #else -static inline void spear1340_clk_init(void) {} +static inline void spear1340_clk_init(void __iomem *misc_base) {} #endif #endif /* __MACH_GENERIC_H */ diff --git a/arch/arm/mach-spear/include/mach/misc_regs.h b/arch/arm/mach-spear/include/mach/misc_regs.h index 075812c4ca18..935639ce59ba 100644 --- a/arch/arm/mach-spear/include/mach/misc_regs.h +++ b/arch/arm/mach-spear/include/mach/misc_regs.h @@ -16,7 +16,7 @@ #include -#define MISC_BASE IOMEM(VA_SPEAR_ICM3_MISC_REG_BASE) +#define MISC_BASE (VA_SPEAR_ICM3_MISC_REG_BASE) #define DMA_CHN_CFG (MISC_BASE + 0x0A0) #endif /* __MACH_MISC_REGS_H */ diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h index 2198ab96df9d..374ddc393df1 100644 --- a/arch/arm/mach-spear/include/mach/spear.h +++ b/arch/arm/mach-spear/include/mach/spear.h @@ -19,23 +19,23 @@ /* ICM1 - Low speed connection */ #define SPEAR_ICM1_2_BASE UL(0xD0000000) -#define VA_SPEAR_ICM1_2_BASE UL(0xFD000000) +#define VA_SPEAR_ICM1_2_BASE IOMEM(0xFD000000) #define SPEAR_ICM1_UART_BASE UL(0xD0000000) -#define VA_SPEAR_ICM1_UART_BASE (VA_SPEAR_ICM1_2_BASE | SPEAR_ICM1_UART_BASE) +#define VA_SPEAR_ICM1_UART_BASE (VA_SPEAR_ICM1_2_BASE - SPEAR_ICM1_2_BASE + SPEAR_ICM1_UART_BASE) #define SPEAR3XX_ICM1_SSP_BASE UL(0xD0100000) /* ML-1, 2 - Multi Layer CPU Subsystem */ #define SPEAR_ICM3_ML1_2_BASE UL(0xF0000000) -#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000) +#define VA_SPEAR6XX_ML_CPU_BASE IOMEM(0xF0000000) /* ICM3 - Basic Subsystem */ #define SPEAR_ICM3_SMI_CTRL_BASE UL(0xFC000000) -#define VA_SPEAR_ICM3_SMI_CTRL_BASE UL(0xFC000000) +#define VA_SPEAR_ICM3_SMI_CTRL_BASE IOMEM(0xFC000000) #define SPEAR_ICM3_DMA_BASE UL(0xFC400000) #define SPEAR_ICM3_SYS_CTRL_BASE UL(0xFCA00000) -#define VA_SPEAR_ICM3_SYS_CTRL_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE | SPEAR_ICM3_SYS_CTRL_BASE) +#define VA_SPEAR_ICM3_SYS_CTRL_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_SYS_CTRL_BASE) #define SPEAR_ICM3_MISC_REG_BASE UL(0xFCA80000) -#define VA_SPEAR_ICM3_MISC_REG_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE | SPEAR_ICM3_MISC_REG_BASE) +#define VA_SPEAR_ICM3_MISC_REG_BASE (VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_MISC_REG_BASE) /* Debug uart for linux, will be used for debug and uncompress messages */ #define SPEAR_DBG_UART_BASE SPEAR_ICM1_UART_BASE @@ -44,20 +44,11 @@ /* Sysctl base for spear platform */ #define SPEAR_SYS_CTRL_BASE SPEAR_ICM3_SYS_CTRL_BASE #define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR_ICM3_SYS_CTRL_BASE +#endif /* SPEAR3xx || SPEAR6XX */ /* SPEAr320 Macros */ #define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000) -#define VA_SPEAR320_SOC_CONFIG_BASE UL(0xFE000000) -#define SPEAR320_CONTROL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE) -#define SPEAR320_EXT_CTRL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE + 0x0018) - #define SPEAR320_UARTX_PCLK_MASK 0x1 - #define SPEAR320_UART2_PCLK_SHIFT 8 - #define SPEAR320_UART3_PCLK_SHIFT 9 - #define SPEAR320_UART4_PCLK_SHIFT 10 - #define SPEAR320_UART5_PCLK_SHIFT 11 - #define SPEAR320_UART6_PCLK_SHIFT 12 - #define SPEAR320_RS485_PCLK_SHIFT 13 -#endif /* SPEAR3xx || SPEAR6XX */ +#define VA_SPEAR320_SOC_CONFIG_BASE IOMEM(0xFE000000) #ifdef CONFIG_ARCH_SPEAR13XX @@ -79,6 +70,9 @@ #define A9SM_AND_MPMC_BASE UL(0xEC000000) #define VA_A9SM_AND_MPMC_BASE IOMEM(0xFC000000) +#define SPEAR1310_RAS_BASE UL(0xD8400000) +#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) + /* A9SM peripheral offsets */ #define A9SM_PERIP_BASE UL(0xEC800000) #define VA_A9SM_PERIP_BASE IOMEM(0xFC800000) diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c index fe868b20b46e..ed3b5c287a7b 100644 --- a/arch/arm/mach-spear/spear1310.c +++ b/arch/arm/mach-spear/spear1310.c @@ -30,8 +30,6 @@ #define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) #define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) -#define SPEAR1310_RAS_BASE UL(0xD8400000) -#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) static struct arasan_cf_pdata cf_pdata = { .cf_if_clk = CF_IF_CLK_166M, diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c index 6f62dd59daf6..1b97e8623472 100644 --- a/arch/arm/mach-spear/spear13xx.c +++ b/arch/arm/mach-spear/spear13xx.c @@ -146,9 +146,9 @@ void __init spear13xx_map_io(void) static void __init spear13xx_clk_init(void) { if (of_machine_is_compatible("st,spear1310")) - spear1310_clk_init(); + spear1310_clk_init(VA_MISC_BASE, VA_SPEAR1310_RAS_BASE); else if (of_machine_is_compatible("st,spear1340")) - spear1340_clk_init(); + spear1340_clk_init(VA_MISC_BASE); else pr_err("%s: Unknown machine\n", __func__); } diff --git a/arch/arm/mach-spear/spear320.c b/arch/arm/mach-spear/spear320.c index b8a4bb5fcee5..6eb3eec65f96 100644 --- a/arch/arm/mach-spear/spear320.c +++ b/arch/arm/mach-spear/spear320.c @@ -254,7 +254,7 @@ static const char * const spear320_dt_board_compat[] = { struct map_desc spear320_io_desc[] __initdata = { { - .virtual = VA_SPEAR320_SOC_CONFIG_BASE, + .virtual = (unsigned long)VA_SPEAR320_SOC_CONFIG_BASE, .pfn = __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE), .length = SZ_16M, .type = MT_DEVICE diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c index be0c94d04d50..0227c97797cd 100644 --- a/arch/arm/mach-spear/spear3xx.c +++ b/arch/arm/mach-spear/spear3xx.c @@ -21,6 +21,7 @@ #include "pl080.h" #include "generic.h" #include +#include /* ssp device registration */ struct pl022_ssp_controller pl022_plat_data = { @@ -67,12 +68,12 @@ struct pl08x_platform_data pl080_plat_data = { */ struct map_desc spear3xx_io_desc[] __initdata = { { - .virtual = VA_SPEAR_ICM1_2_BASE, + .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE, .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE), .length = SZ_16M, .type = MT_DEVICE }, { - .virtual = VA_SPEAR_ICM3_SMI_CTRL_BASE, + .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE, .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE), .length = SZ_16M, .type = MT_DEVICE @@ -90,7 +91,7 @@ void __init spear3xx_timer_init(void) char pclk_name[] = "pll3_clk"; struct clk *gpt_clk, *pclk; - spear3xx_clk_init(); + spear3xx_clk_init(MISC_BASE, VA_SPEAR320_SOC_CONFIG_BASE); /* get the system timer clock */ gpt_clk = clk_get_sys("gpt0", NULL); diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c index 78e135977146..9b5ea254ed82 100644 --- a/arch/arm/mach-spear/spear6xx.c +++ b/arch/arm/mach-spear/spear6xx.c @@ -27,6 +27,7 @@ #include "pl080.h" #include "generic.h" #include +#include /* dmac device registration */ static struct pl08x_channel_data spear600_dma_info[] = { @@ -350,17 +351,17 @@ struct pl08x_platform_data pl080_plat_data = { */ struct map_desc spear6xx_io_desc[] __initdata = { { - .virtual = VA_SPEAR6XX_ML_CPU_BASE, + .virtual = (unsigned long)VA_SPEAR6XX_ML_CPU_BASE, .pfn = __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE), .length = 2 * SZ_16M, .type = MT_DEVICE }, { - .virtual = VA_SPEAR_ICM1_2_BASE, + .virtual = (unsigned long)VA_SPEAR_ICM1_2_BASE, .pfn = __phys_to_pfn(SPEAR_ICM1_2_BASE), .length = SZ_16M, .type = MT_DEVICE }, { - .virtual = VA_SPEAR_ICM3_SMI_CTRL_BASE, + .virtual = (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE, .pfn = __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE), .length = SZ_16M, .type = MT_DEVICE @@ -378,7 +379,7 @@ void __init spear6xx_timer_init(void) char pclk_name[] = "pll3_clk"; struct clk *gpt_clk, *pclk; - spear6xx_clk_init(); + spear6xx_clk_init(MISC_BASE); /* get the system timer clock */ gpt_clk = clk_get_sys("gpt0", NULL); diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index ed9af4278619..aedbbe12f321 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -17,12 +17,10 @@ #include #include #include -#include #include "clk.h" -#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) /* PLL related registers and bit values */ -#define SPEAR1310_PLL_CFG (VA_MISC_BASE + 0x210) +#define SPEAR1310_PLL_CFG (misc_base + 0x210) /* PLL_CFG bit values */ #define SPEAR1310_CLCD_SYNT_CLK_MASK 1 #define SPEAR1310_CLCD_SYNT_CLK_SHIFT 31 @@ -35,15 +33,15 @@ #define SPEAR1310_PLL2_CLK_SHIFT 22 #define SPEAR1310_PLL1_CLK_SHIFT 20 -#define SPEAR1310_PLL1_CTR (VA_MISC_BASE + 0x214) -#define SPEAR1310_PLL1_FRQ (VA_MISC_BASE + 0x218) -#define SPEAR1310_PLL2_CTR (VA_MISC_BASE + 0x220) -#define SPEAR1310_PLL2_FRQ (VA_MISC_BASE + 0x224) -#define SPEAR1310_PLL3_CTR (VA_MISC_BASE + 0x22C) -#define SPEAR1310_PLL3_FRQ (VA_MISC_BASE + 0x230) -#define SPEAR1310_PLL4_CTR (VA_MISC_BASE + 0x238) -#define SPEAR1310_PLL4_FRQ (VA_MISC_BASE + 0x23C) -#define SPEAR1310_PERIP_CLK_CFG (VA_MISC_BASE + 0x244) +#define SPEAR1310_PLL1_CTR (misc_base + 0x214) +#define SPEAR1310_PLL1_FRQ (misc_base + 0x218) +#define SPEAR1310_PLL2_CTR (misc_base + 0x220) +#define SPEAR1310_PLL2_FRQ (misc_base + 0x224) +#define SPEAR1310_PLL3_CTR (misc_base + 0x22C) +#define SPEAR1310_PLL3_FRQ (misc_base + 0x230) +#define SPEAR1310_PLL4_CTR (misc_base + 0x238) +#define SPEAR1310_PLL4_FRQ (misc_base + 0x23C) +#define SPEAR1310_PERIP_CLK_CFG (misc_base + 0x244) /* PERIP_CLK_CFG bit values */ #define SPEAR1310_GPT_OSC24_VAL 0 #define SPEAR1310_GPT_APB_VAL 1 @@ -65,7 +63,7 @@ #define SPEAR1310_C3_CLK_MASK 1 #define SPEAR1310_C3_CLK_SHIFT 1 -#define SPEAR1310_GMAC_CLK_CFG (VA_MISC_BASE + 0x248) +#define SPEAR1310_GMAC_CLK_CFG (misc_base + 0x248) #define SPEAR1310_GMAC_PHY_IF_SEL_MASK 3 #define SPEAR1310_GMAC_PHY_IF_SEL_SHIFT 4 #define SPEAR1310_GMAC_PHY_CLK_MASK 1 @@ -73,7 +71,7 @@ #define SPEAR1310_GMAC_PHY_INPUT_CLK_MASK 2 #define SPEAR1310_GMAC_PHY_INPUT_CLK_SHIFT 1 -#define SPEAR1310_I2S_CLK_CFG (VA_MISC_BASE + 0x24C) +#define SPEAR1310_I2S_CLK_CFG (misc_base + 0x24C) /* I2S_CLK_CFG register mask */ #define SPEAR1310_I2S_SCLK_X_MASK 0x1F #define SPEAR1310_I2S_SCLK_X_SHIFT 27 @@ -91,21 +89,21 @@ #define SPEAR1310_I2S_SRC_CLK_MASK 2 #define SPEAR1310_I2S_SRC_CLK_SHIFT 0 -#define SPEAR1310_C3_CLK_SYNT (VA_MISC_BASE + 0x250) -#define SPEAR1310_UART_CLK_SYNT (VA_MISC_BASE + 0x254) -#define SPEAR1310_GMAC_CLK_SYNT (VA_MISC_BASE + 0x258) -#define SPEAR1310_SDHCI_CLK_SYNT (VA_MISC_BASE + 0x25C) -#define SPEAR1310_CFXD_CLK_SYNT (VA_MISC_BASE + 0x260) -#define SPEAR1310_ADC_CLK_SYNT (VA_MISC_BASE + 0x264) -#define SPEAR1310_AMBA_CLK_SYNT (VA_MISC_BASE + 0x268) -#define SPEAR1310_CLCD_CLK_SYNT (VA_MISC_BASE + 0x270) -#define SPEAR1310_RAS_CLK_SYNT0 (VA_MISC_BASE + 0x280) -#define SPEAR1310_RAS_CLK_SYNT1 (VA_MISC_BASE + 0x288) -#define SPEAR1310_RAS_CLK_SYNT2 (VA_MISC_BASE + 0x290) -#define SPEAR1310_RAS_CLK_SYNT3 (VA_MISC_BASE + 0x298) +#define SPEAR1310_C3_CLK_SYNT (misc_base + 0x250) +#define SPEAR1310_UART_CLK_SYNT (misc_base + 0x254) +#define SPEAR1310_GMAC_CLK_SYNT (misc_base + 0x258) +#define SPEAR1310_SDHCI_CLK_SYNT (misc_base + 0x25C) +#define SPEAR1310_CFXD_CLK_SYNT (misc_base + 0x260) +#define SPEAR1310_ADC_CLK_SYNT (misc_base + 0x264) +#define SPEAR1310_AMBA_CLK_SYNT (misc_base + 0x268) +#define SPEAR1310_CLCD_CLK_SYNT (misc_base + 0x270) +#define SPEAR1310_RAS_CLK_SYNT0 (misc_base + 0x280) +#define SPEAR1310_RAS_CLK_SYNT1 (misc_base + 0x288) +#define SPEAR1310_RAS_CLK_SYNT2 (misc_base + 0x290) +#define SPEAR1310_RAS_CLK_SYNT3 (misc_base + 0x298) /* Check Fractional synthesizer reg masks */ -#define SPEAR1310_PERIP1_CLK_ENB (VA_MISC_BASE + 0x300) +#define SPEAR1310_PERIP1_CLK_ENB (misc_base + 0x300) /* PERIP1_CLK_ENB register masks */ #define SPEAR1310_RTC_CLK_ENB 31 #define SPEAR1310_ADC_CLK_ENB 30 @@ -138,7 +136,7 @@ #define SPEAR1310_SYSROM_CLK_ENB 1 #define SPEAR1310_BUS_CLK_ENB 0 -#define SPEAR1310_PERIP2_CLK_ENB (VA_MISC_BASE + 0x304) +#define SPEAR1310_PERIP2_CLK_ENB (misc_base + 0x304) /* PERIP2_CLK_ENB register masks */ #define SPEAR1310_THSENS_CLK_ENB 8 #define SPEAR1310_I2S_REF_PAD_CLK_ENB 7 @@ -150,7 +148,7 @@ #define SPEAR1310_DDR_CORE_CLK_ENB 1 #define SPEAR1310_DDR_CTRL_CLK_ENB 0 -#define SPEAR1310_RAS_CLK_ENB (VA_MISC_BASE + 0x310) +#define SPEAR1310_RAS_CLK_ENB (misc_base + 0x310) /* RAS_CLK_ENB register masks */ #define SPEAR1310_SYNT3_CLK_ENB 17 #define SPEAR1310_SYNT2_CLK_ENB 16 @@ -172,7 +170,7 @@ #define SPEAR1310_ACLK_CLK_ENB 0 /* RAS Area Control Register */ -#define SPEAR1310_RAS_CTRL_REG0 (VA_SPEAR1310_RAS_BASE + 0x000) +#define SPEAR1310_RAS_CTRL_REG0 (ras_base + 0x000) #define SPEAR1310_SSP1_CLK_MASK 3 #define SPEAR1310_SSP1_CLK_SHIFT 26 #define SPEAR1310_TDM_CLK_MASK 1 @@ -197,12 +195,12 @@ #define SPEAR1310_PCI_CLK_MASK 1 #define SPEAR1310_PCI_CLK_SHIFT 0 -#define SPEAR1310_RAS_CTRL_REG1 (VA_SPEAR1310_RAS_BASE + 0x004) +#define SPEAR1310_RAS_CTRL_REG1 (ras_base + 0x004) #define SPEAR1310_PHY_CLK_MASK 0x3 #define SPEAR1310_RMII_PHY_CLK_SHIFT 0 #define SPEAR1310_SMII_RGMII_PHY_CLK_SHIFT 2 -#define SPEAR1310_RAS_SW_CLK_CTRL (VA_SPEAR1310_RAS_BASE + 0x0148) +#define SPEAR1310_RAS_SW_CLK_CTRL (ras_base + 0x0148) #define SPEAR1310_CAN1_CLK_ENB 25 #define SPEAR1310_CAN0_CLK_ENB 24 #define SPEAR1310_GPT64_CLK_ENB 23 @@ -385,7 +383,7 @@ static const char *ssp1_parents[] = { "ras_apb_clk", "gen_syn1_clk", static const char *pci_parents[] = { "ras_pll3_clk", "gen_syn2_clk", }; static const char *tdm_parents[] = { "ras_pll3_clk", "gen_syn1_clk", }; -void __init spear1310_clk_init(void) +void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) { struct clk *clk, *clk1; diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 82abea366b78..3ceb4507e95f 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -17,18 +17,17 @@ #include #include #include -#include #include "clk.h" /* Clock Configuration Registers */ -#define SPEAR1340_SYS_CLK_CTRL (VA_MISC_BASE + 0x200) +#define SPEAR1340_SYS_CLK_CTRL (misc_base + 0x200) #define SPEAR1340_HCLK_SRC_SEL_SHIFT 27 #define SPEAR1340_HCLK_SRC_SEL_MASK 1 #define SPEAR1340_SCLK_SRC_SEL_SHIFT 23 #define SPEAR1340_SCLK_SRC_SEL_MASK 3 /* PLL related registers and bit values */ -#define SPEAR1340_PLL_CFG (VA_MISC_BASE + 0x210) +#define SPEAR1340_PLL_CFG (misc_base + 0x210) /* PLL_CFG bit values */ #define SPEAR1340_CLCD_SYNT_CLK_MASK 1 #define SPEAR1340_CLCD_SYNT_CLK_SHIFT 31 @@ -40,15 +39,15 @@ #define SPEAR1340_PLL2_CLK_SHIFT 22 #define SPEAR1340_PLL1_CLK_SHIFT 20 -#define SPEAR1340_PLL1_CTR (VA_MISC_BASE + 0x214) -#define SPEAR1340_PLL1_FRQ (VA_MISC_BASE + 0x218) -#define SPEAR1340_PLL2_CTR (VA_MISC_BASE + 0x220) -#define SPEAR1340_PLL2_FRQ (VA_MISC_BASE + 0x224) -#define SPEAR1340_PLL3_CTR (VA_MISC_BASE + 0x22C) -#define SPEAR1340_PLL3_FRQ (VA_MISC_BASE + 0x230) -#define SPEAR1340_PLL4_CTR (VA_MISC_BASE + 0x238) -#define SPEAR1340_PLL4_FRQ (VA_MISC_BASE + 0x23C) -#define SPEAR1340_PERIP_CLK_CFG (VA_MISC_BASE + 0x244) +#define SPEAR1340_PLL1_CTR (misc_base + 0x214) +#define SPEAR1340_PLL1_FRQ (misc_base + 0x218) +#define SPEAR1340_PLL2_CTR (misc_base + 0x220) +#define SPEAR1340_PLL2_FRQ (misc_base + 0x224) +#define SPEAR1340_PLL3_CTR (misc_base + 0x22C) +#define SPEAR1340_PLL3_FRQ (misc_base + 0x230) +#define SPEAR1340_PLL4_CTR (misc_base + 0x238) +#define SPEAR1340_PLL4_FRQ (misc_base + 0x23C) +#define SPEAR1340_PERIP_CLK_CFG (misc_base + 0x244) /* PERIP_CLK_CFG bit values */ #define SPEAR1340_SPDIF_CLK_MASK 1 #define SPEAR1340_SPDIF_OUT_CLK_SHIFT 15 @@ -66,13 +65,13 @@ #define SPEAR1340_C3_CLK_MASK 1 #define SPEAR1340_C3_CLK_SHIFT 1 -#define SPEAR1340_GMAC_CLK_CFG (VA_MISC_BASE + 0x248) +#define SPEAR1340_GMAC_CLK_CFG (misc_base + 0x248) #define SPEAR1340_GMAC_PHY_CLK_MASK 1 #define SPEAR1340_GMAC_PHY_CLK_SHIFT 2 #define SPEAR1340_GMAC_PHY_INPUT_CLK_MASK 2 #define SPEAR1340_GMAC_PHY_INPUT_CLK_SHIFT 0 -#define SPEAR1340_I2S_CLK_CFG (VA_MISC_BASE + 0x24C) +#define SPEAR1340_I2S_CLK_CFG (misc_base + 0x24C) /* I2S_CLK_CFG register mask */ #define SPEAR1340_I2S_SCLK_X_MASK 0x1F #define SPEAR1340_I2S_SCLK_X_SHIFT 27 @@ -90,21 +89,21 @@ #define SPEAR1340_I2S_SRC_CLK_MASK 2 #define SPEAR1340_I2S_SRC_CLK_SHIFT 0 -#define SPEAR1340_C3_CLK_SYNT (VA_MISC_BASE + 0x250) -#define SPEAR1340_UART0_CLK_SYNT (VA_MISC_BASE + 0x254) -#define SPEAR1340_UART1_CLK_SYNT (VA_MISC_BASE + 0x258) -#define SPEAR1340_GMAC_CLK_SYNT (VA_MISC_BASE + 0x25C) -#define SPEAR1340_SDHCI_CLK_SYNT (VA_MISC_BASE + 0x260) -#define SPEAR1340_CFXD_CLK_SYNT (VA_MISC_BASE + 0x264) -#define SPEAR1340_ADC_CLK_SYNT (VA_MISC_BASE + 0x270) -#define SPEAR1340_AMBA_CLK_SYNT (VA_MISC_BASE + 0x274) -#define SPEAR1340_CLCD_CLK_SYNT (VA_MISC_BASE + 0x27C) -#define SPEAR1340_SYS_CLK_SYNT (VA_MISC_BASE + 0x284) -#define SPEAR1340_GEN_CLK_SYNT0 (VA_MISC_BASE + 0x28C) -#define SPEAR1340_GEN_CLK_SYNT1 (VA_MISC_BASE + 0x294) -#define SPEAR1340_GEN_CLK_SYNT2 (VA_MISC_BASE + 0x29C) -#define SPEAR1340_GEN_CLK_SYNT3 (VA_MISC_BASE + 0x304) -#define SPEAR1340_PERIP1_CLK_ENB (VA_MISC_BASE + 0x30C) +#define SPEAR1340_C3_CLK_SYNT (misc_base + 0x250) +#define SPEAR1340_UART0_CLK_SYNT (misc_base + 0x254) +#define SPEAR1340_UART1_CLK_SYNT (misc_base + 0x258) +#define SPEAR1340_GMAC_CLK_SYNT (misc_base + 0x25C) +#define SPEAR1340_SDHCI_CLK_SYNT (misc_base + 0x260) +#define SPEAR1340_CFXD_CLK_SYNT (misc_base + 0x264) +#define SPEAR1340_ADC_CLK_SYNT (misc_base + 0x270) +#define SPEAR1340_AMBA_CLK_SYNT (misc_base + 0x274) +#define SPEAR1340_CLCD_CLK_SYNT (misc_base + 0x27C) +#define SPEAR1340_SYS_CLK_SYNT (misc_base + 0x284) +#define SPEAR1340_GEN_CLK_SYNT0 (misc_base + 0x28C) +#define SPEAR1340_GEN_CLK_SYNT1 (misc_base + 0x294) +#define SPEAR1340_GEN_CLK_SYNT2 (misc_base + 0x29C) +#define SPEAR1340_GEN_CLK_SYNT3 (misc_base + 0x304) +#define SPEAR1340_PERIP1_CLK_ENB (misc_base + 0x30C) #define SPEAR1340_RTC_CLK_ENB 31 #define SPEAR1340_ADC_CLK_ENB 30 #define SPEAR1340_C3_CLK_ENB 29 @@ -133,7 +132,7 @@ #define SPEAR1340_SYSROM_CLK_ENB 1 #define SPEAR1340_BUS_CLK_ENB 0 -#define SPEAR1340_PERIP2_CLK_ENB (VA_MISC_BASE + 0x310) +#define SPEAR1340_PERIP2_CLK_ENB (misc_base + 0x310) #define SPEAR1340_THSENS_CLK_ENB 8 #define SPEAR1340_I2S_REF_PAD_CLK_ENB 7 #define SPEAR1340_ACP_CLK_ENB 6 @@ -144,7 +143,7 @@ #define SPEAR1340_DDR_CORE_CLK_ENB 1 #define SPEAR1340_DDR_CTRL_CLK_ENB 0 -#define SPEAR1340_PERIP3_CLK_ENB (VA_MISC_BASE + 0x314) +#define SPEAR1340_PERIP3_CLK_ENB (misc_base + 0x314) #define SPEAR1340_PLGPIO_CLK_ENB 18 #define SPEAR1340_VIDEO_DEC_CLK_ENB 16 #define SPEAR1340_VIDEO_ENC_CLK_ENB 15 @@ -441,7 +440,7 @@ static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco2div2_clk", "pll2_clk", }; -void __init spear1340_clk_init(void) +void __init spear1340_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 33d3ac588da7..f9ec43fd1320 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -15,21 +15,20 @@ #include #include #include -#include #include "clk.h" static DEFINE_SPINLOCK(_lock); -#define PLL1_CTR (MISC_BASE + 0x008) -#define PLL1_FRQ (MISC_BASE + 0x00C) -#define PLL2_CTR (MISC_BASE + 0x014) -#define PLL2_FRQ (MISC_BASE + 0x018) -#define PLL_CLK_CFG (MISC_BASE + 0x020) +#define PLL1_CTR (misc_base + 0x008) +#define PLL1_FRQ (misc_base + 0x00C) +#define PLL2_CTR (misc_base + 0x014) +#define PLL2_FRQ (misc_base + 0x018) +#define PLL_CLK_CFG (misc_base + 0x020) /* PLL_CLK_CFG register masks */ #define MCTR_CLK_SHIFT 28 #define MCTR_CLK_MASK 3 -#define CORE_CLK_CFG (MISC_BASE + 0x024) +#define CORE_CLK_CFG (misc_base + 0x024) /* CORE CLK CFG register masks */ #define GEN_SYNTH2_3_CLK_SHIFT 18 #define GEN_SYNTH2_3_CLK_MASK 1 @@ -39,7 +38,7 @@ static DEFINE_SPINLOCK(_lock); #define PCLK_RATIO_SHIFT 8 #define PCLK_RATIO_MASK 2 -#define PERIP_CLK_CFG (MISC_BASE + 0x028) +#define PERIP_CLK_CFG (misc_base + 0x028) /* PERIP_CLK_CFG register masks */ #define UART_CLK_SHIFT 4 #define UART_CLK_MASK 1 @@ -50,7 +49,7 @@ static DEFINE_SPINLOCK(_lock); #define GPT2_CLK_SHIFT 12 #define GPT_CLK_MASK 1 -#define PERIP1_CLK_ENB (MISC_BASE + 0x02C) +#define PERIP1_CLK_ENB (misc_base + 0x02C) /* PERIP1_CLK_ENB register masks */ #define UART_CLK_ENB 3 #define SSP_CLK_ENB 5 @@ -69,7 +68,7 @@ static DEFINE_SPINLOCK(_lock); #define USBH_CLK_ENB 25 #define C3_CLK_ENB 31 -#define RAS_CLK_ENB (MISC_BASE + 0x034) +#define RAS_CLK_ENB (misc_base + 0x034) #define RAS_AHB_CLK_ENB 0 #define RAS_PLL1_CLK_ENB 1 #define RAS_APB_CLK_ENB 2 @@ -82,20 +81,20 @@ static DEFINE_SPINLOCK(_lock); #define RAS_SYNT2_CLK_ENB 10 #define RAS_SYNT3_CLK_ENB 11 -#define PRSC0_CLK_CFG (MISC_BASE + 0x044) -#define PRSC1_CLK_CFG (MISC_BASE + 0x048) -#define PRSC2_CLK_CFG (MISC_BASE + 0x04C) -#define AMEM_CLK_CFG (MISC_BASE + 0x050) +#define PRSC0_CLK_CFG (misc_base + 0x044) +#define PRSC1_CLK_CFG (misc_base + 0x048) +#define PRSC2_CLK_CFG (misc_base + 0x04C) +#define AMEM_CLK_CFG (misc_base + 0x050) #define AMEM_CLK_ENB 0 -#define CLCD_CLK_SYNT (MISC_BASE + 0x05C) -#define FIRDA_CLK_SYNT (MISC_BASE + 0x060) -#define UART_CLK_SYNT (MISC_BASE + 0x064) -#define GMAC_CLK_SYNT (MISC_BASE + 0x068) -#define GEN0_CLK_SYNT (MISC_BASE + 0x06C) -#define GEN1_CLK_SYNT (MISC_BASE + 0x070) -#define GEN2_CLK_SYNT (MISC_BASE + 0x074) -#define GEN3_CLK_SYNT (MISC_BASE + 0x078) +#define CLCD_CLK_SYNT (misc_base + 0x05C) +#define FIRDA_CLK_SYNT (misc_base + 0x060) +#define UART_CLK_SYNT (misc_base + 0x064) +#define GMAC_CLK_SYNT (misc_base + 0x068) +#define GEN0_CLK_SYNT (misc_base + 0x06C) +#define GEN1_CLK_SYNT (misc_base + 0x070) +#define GEN2_CLK_SYNT (misc_base + 0x074) +#define GEN3_CLK_SYNT (misc_base + 0x078) /* pll rate configuration table, in ascending order of rates */ static struct pll_rate_tbl pll_rtbl[] = { @@ -211,6 +210,17 @@ static inline void spear310_clk_init(void) { } /* array of all spear 320 clock lookups */ #ifdef CONFIG_MACH_SPEAR320 + +#define SPEAR320_CONTROL_REG (soc_config_base + 0x0000) +#define SPEAR320_EXT_CTRL_REG (soc_config_base + 0x0018) + + #define SPEAR320_UARTX_PCLK_MASK 0x1 + #define SPEAR320_UART2_PCLK_SHIFT 8 + #define SPEAR320_UART3_PCLK_SHIFT 9 + #define SPEAR320_UART4_PCLK_SHIFT 10 + #define SPEAR320_UART5_PCLK_SHIFT 11 + #define SPEAR320_UART6_PCLK_SHIFT 12 + #define SPEAR320_RS485_PCLK_SHIFT 13 #define SMII_PCLK_SHIFT 18 #define SMII_PCLK_MASK 2 #define SMII_PCLK_VAL_PAD 0x0 @@ -235,7 +245,7 @@ static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk", "ras_syn0_gclk", }; static const char *uartx_parents[] = { "ras_syn1_gclk", "ras_apb_clk", }; -static void __init spear320_clk_init(void) +static void __init spear320_clk_init(void __iomem *soc_config_base) { struct clk *clk; @@ -362,7 +372,7 @@ static void __init spear320_clk_init(void) static inline void spear320_clk_init(void) { } #endif -void __init spear3xx_clk_init(void) +void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base) { struct clk *clk, *clk1; @@ -634,5 +644,5 @@ void __init spear3xx_clk_init(void) else if (of_machine_is_compatible("st,spear310")) spear310_clk_init(); else if (of_machine_is_compatible("st,spear320")) - spear320_clk_init(); + spear320_clk_init(soc_config_base); } diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index e862a333ad30..9406f2426d64 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -13,28 +13,27 @@ #include #include #include -#include #include "clk.h" static DEFINE_SPINLOCK(_lock); -#define PLL1_CTR (MISC_BASE + 0x008) -#define PLL1_FRQ (MISC_BASE + 0x00C) -#define PLL2_CTR (MISC_BASE + 0x014) -#define PLL2_FRQ (MISC_BASE + 0x018) -#define PLL_CLK_CFG (MISC_BASE + 0x020) +#define PLL1_CTR (misc_base + 0x008) +#define PLL1_FRQ (misc_base + 0x00C) +#define PLL2_CTR (misc_base + 0x014) +#define PLL2_FRQ (misc_base + 0x018) +#define PLL_CLK_CFG (misc_base + 0x020) /* PLL_CLK_CFG register masks */ #define MCTR_CLK_SHIFT 28 #define MCTR_CLK_MASK 3 -#define CORE_CLK_CFG (MISC_BASE + 0x024) +#define CORE_CLK_CFG (misc_base + 0x024) /* CORE CLK CFG register masks */ #define HCLK_RATIO_SHIFT 10 #define HCLK_RATIO_MASK 2 #define PCLK_RATIO_SHIFT 8 #define PCLK_RATIO_MASK 2 -#define PERIP_CLK_CFG (MISC_BASE + 0x028) +#define PERIP_CLK_CFG (misc_base + 0x028) /* PERIP_CLK_CFG register masks */ #define CLCD_CLK_SHIFT 2 #define CLCD_CLK_MASK 2 @@ -48,7 +47,7 @@ static DEFINE_SPINLOCK(_lock); #define GPT3_CLK_SHIFT 12 #define GPT_CLK_MASK 1 -#define PERIP1_CLK_ENB (MISC_BASE + 0x02C) +#define PERIP1_CLK_ENB (misc_base + 0x02C) /* PERIP1_CLK_ENB register masks */ #define UART0_CLK_ENB 3 #define UART1_CLK_ENB 4 @@ -74,13 +73,13 @@ static DEFINE_SPINLOCK(_lock); #define USBH0_CLK_ENB 25 #define USBH1_CLK_ENB 26 -#define PRSC0_CLK_CFG (MISC_BASE + 0x044) -#define PRSC1_CLK_CFG (MISC_BASE + 0x048) -#define PRSC2_CLK_CFG (MISC_BASE + 0x04C) +#define PRSC0_CLK_CFG (misc_base + 0x044) +#define PRSC1_CLK_CFG (misc_base + 0x048) +#define PRSC2_CLK_CFG (misc_base + 0x04C) -#define CLCD_CLK_SYNT (MISC_BASE + 0x05C) -#define FIRDA_CLK_SYNT (MISC_BASE + 0x060) -#define UART_CLK_SYNT (MISC_BASE + 0x064) +#define CLCD_CLK_SYNT (misc_base + 0x05C) +#define FIRDA_CLK_SYNT (misc_base + 0x060) +#define UART_CLK_SYNT (misc_base + 0x064) /* vco rate configuration table, in ascending order of rates */ static struct pll_rate_tbl pll_rtbl[] = { @@ -115,7 +114,7 @@ static struct gpt_rate_tbl gpt_rtbl[] = { {.mscale = 1, .nscale = 0}, /* 83 MHz */ }; -void __init spear6xx_clk_init(void) +void __init spear6xx_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; -- cgit From dc715452e9145156840b09df765ea2ede4851eda Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 28 Jan 2013 16:24:37 +0000 Subject: spi: pl022: use generic DMA slave configuration if possible With the new OF DMA binding, it is possible to completely avoid the need for platform_data for configuring a DMA channel. In cases where the platform has already been converted, calling dma_request_slave_channel should get all the necessary information from the device tree. Like the patch that converts the dw_dma controller, this is completely untested and is looking for someone to try it out. Signed-off-by: Arnd Bergmann Acked-by: Grant Likely Acked-by: Mark Brown Acked-by: Linus Walleij Cc: spi-devel-general@lists.sourceforge.net Cc: Viresh Kumar Cc: Andy Shevchenko Cc: Vinod Koul Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org --- .../devicetree/bindings/spi/spi_pl022.txt | 36 ++++++++++++++++++ drivers/spi/spi-pl022.c | 43 +++++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/spi/spi_pl022.txt b/Documentation/devicetree/bindings/spi/spi_pl022.txt index f158fd31cfda..22ed6797216d 100644 --- a/Documentation/devicetree/bindings/spi/spi_pl022.txt +++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt @@ -16,6 +16,11 @@ Optional properties: device will be suspended immediately - pl022,rt : indicates the controller should run the message pump with realtime priority to minimise the transfer latency on the bus (boolean) +- dmas : Two or more DMA channel specifiers following the convention outlined + in bindings/dma/dma.txt +- dma-names: Names for the dma channels, if present. There must be at + least one channel named "tx" for transmit and named "rx" for + receive. SPI slave nodes must be children of the SPI master node and can @@ -32,3 +37,34 @@ contain the following properties. - pl022,wait-state : Microwire interface: Wait state - pl022,duplex : Microwire interface: Full/Half duplex + +Example: + + spi@e0100000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0xe0100000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 31 0x4>; + dmas = <&dma-controller 23 1>, + <&dma-controller 24 0>; + dma-names = "rx", "tx"; + + m25p80@1 { + compatible = "st,m25p80"; + reg = <1>; + spi-max-frequency = <12000000>; + spi-cpol; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; + }; + diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index b0fe393c882c..371cc66f1a0e 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1139,6 +1139,35 @@ err_no_rxchan: return -ENODEV; } +static int pl022_dma_autoprobe(struct pl022 *pl022) +{ + struct device *dev = &pl022->adev->dev; + + /* automatically configure DMA channels from platform, normally using DT */ + pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx"); + if (!pl022->dma_rx_channel) + goto err_no_rxchan; + + pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx"); + if (!pl022->dma_tx_channel) + goto err_no_txchan; + + pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!pl022->dummypage) + goto err_no_dummypage; + + return 0; + +err_no_dummypage: + dma_release_channel(pl022->dma_tx_channel); + pl022->dma_tx_channel = NULL; +err_no_txchan: + dma_release_channel(pl022->dma_rx_channel); + pl022->dma_rx_channel = NULL; +err_no_rxchan: + return -ENODEV; +} + static void terminate_dma(struct pl022 *pl022) { struct dma_chan *rxchan = pl022->dma_rx_channel; @@ -1167,6 +1196,11 @@ static inline int configure_dma(struct pl022 *pl022) return -ENODEV; } +static inline int pl022_dma_autoprobe(struct pl022 *pl022) +{ + return 0; +} + static inline int pl022_dma_probe(struct pl022 *pl022) { return 0; @@ -2226,8 +2260,13 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) goto err_no_irq; } - /* Get DMA channels */ - if (platform_info->enable_dma) { + /* Get DMA channels, try autoconfiguration first */ + status = pl022_dma_autoprobe(pl022); + + /* If that failed, use channels from platform_info */ + if (status == 0) + platform_info->enable_dma = 1; + else if (platform_info->enable_dma) { status = pl022_dma_probe(pl022); if (status != 0) platform_info->enable_dma = 0; -- cgit From 787b0c1f8e1975157fe73104e67cac18f955281b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 28 Jan 2013 16:24:37 +0000 Subject: serial: pl011: use generic DMA slave configuration if possible With the new OF DMA binding, it is possible to completely avoid the need for platform_data for configuring a DMA channel. In cases where the platform has already been converted, calling dma_request_slave_channel should get all the necessary information from the device tree. This also adds a binding document specific to the pl011 controller, and extends the generic primecell binding to mention "dmas" and other common properties. Like the patch that converts the dw_dma controller, this is completely untested and is looking for someone to try it out. Signed-off-by: Arnd Bergmann Acked-by: Grant Likely Acked-by: Greg Kroah-Hartman Cc: Russell King Cc: Jiri Slaby Cc: Viresh Kumar Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org --- .../devicetree/bindings/arm/primecell.txt | 19 ++++++- Documentation/devicetree/bindings/serial/pl011.txt | 17 ++++++ drivers/tty/serial/amba-pl011.c | 62 +++++++++++++--------- 3 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/serial/pl011.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/arm/primecell.txt b/Documentation/devicetree/bindings/arm/primecell.txt index 64fc82bc8928..0df6acacfaea 100644 --- a/Documentation/devicetree/bindings/arm/primecell.txt +++ b/Documentation/devicetree/bindings/arm/primecell.txt @@ -16,14 +16,31 @@ Optional properties: - clocks : From common clock binding. First clock is phandle to clock for apb pclk. Additional clocks are optional and specific to those peripherals. - clock-names : From common clock binding. Shall be "apb_pclk" for first clock. +- dmas : From common DMA binding. If present, refers to one or more dma channels. +- dma-names : From common DMA binding, needs to match the 'dmas' property. + Devices with exactly one receive and transmit channel shall name + these "rx" and "tx", respectively. +- pinctrl- : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt +- pinctrl-names : Names corresponding to the numbered pinctrl states +- interrupts : one or more interrupt specifiers +- interrupt-names : names corresponding to the interrupts properties Example: serial@fff36000 { compatible = "arm,pl011", "arm,primecell"; arm,primecell-periphid = <0x00341011>; + clocks = <&pclk>; clock-names = "apb_pclk"; - + + dmas = <&dma-controller 4>, <&dma-controller 5>; + dma-names = "rx", "tx"; + + pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>; + pinctrl-1 = <&uart0_sleep_mode>; + pinctrl-names = "default","sleep"; + + interrupts = <0 11 0x4>; }; diff --git a/Documentation/devicetree/bindings/serial/pl011.txt b/Documentation/devicetree/bindings/serial/pl011.txt new file mode 100644 index 000000000000..5d2e840ae65c --- /dev/null +++ b/Documentation/devicetree/bindings/serial/pl011.txt @@ -0,0 +1,17 @@ +* ARM AMBA Primecell PL011 serial UART + +Required properties: +- compatible: must be "arm,primecell", "arm,pl011" +- reg: exactly one register range with length 0x1000 +- interrupts: exactly one interrupt specifier + +Optional properties: +- pinctrl: When present, must have one state named "sleep" + and one state named "default" +- clocks: When present, must refer to exactly one clock named + "apb_pclk" +- dmas: When present, may have one or two dma channels. + The first one must be named "rx", the second one + must be named "tx". + +See also bindings/arm/primecell.txt diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3ea5408fcbeb..c25b00ef9dbb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -245,7 +245,7 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg, } } -static void pl011_dma_probe_initcall(struct uart_amba_port *uap) +static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *uap) { /* DMA is the sole user of the platform data right now */ struct amba_pl011_data *plat = uap->port.dev->platform_data; @@ -259,20 +259,25 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap) struct dma_chan *chan; dma_cap_mask_t mask; - /* We need platform data */ - if (!plat || !plat->dma_filter) { - dev_info(uap->port.dev, "no DMA platform data\n"); - return; - } + chan = dma_request_slave_channel(dev, "tx"); - /* Try to acquire a generic DMA engine slave TX channel */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param); if (!chan) { - dev_err(uap->port.dev, "no TX DMA channel!\n"); - return; + /* We need platform data */ + if (!plat || !plat->dma_filter) { + dev_info(uap->port.dev, "no DMA platform data\n"); + return; + } + + /* Try to acquire a generic DMA engine slave TX channel */ + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + chan = dma_request_channel(mask, plat->dma_filter, + plat->dma_tx_param); + if (!chan) { + dev_err(uap->port.dev, "no TX DMA channel!\n"); + return; + } } dmaengine_slave_config(chan, &tx_conf); @@ -282,7 +287,18 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap) dma_chan_name(uap->dmatx.chan)); /* Optionally make use of an RX channel as well */ - if (plat->dma_rx_param) { + chan = dma_request_slave_channel(dev, "rx"); + + if (!chan && plat->dma_rx_param) { + chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param); + + if (!chan) { + dev_err(uap->port.dev, "no RX DMA channel!\n"); + return; + } + } + + if (chan) { struct dma_slave_config rx_conf = { .src_addr = uap->port.mapbase + UART01x_DR, .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, @@ -291,12 +307,6 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap) .device_fc = false, }; - chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param); - if (!chan) { - dev_err(uap->port.dev, "no RX DMA channel!\n"); - return; - } - dmaengine_slave_config(chan, &rx_conf); uap->dmarx.chan = chan; @@ -315,6 +325,7 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap) struct dma_uap { struct list_head node; struct uart_amba_port *uap; + struct device *dev; }; static LIST_HEAD(pl011_dma_uarts); @@ -325,7 +336,7 @@ static int __init pl011_dma_initcall(void) list_for_each_safe(node, tmp, &pl011_dma_uarts) { struct dma_uap *dmau = list_entry(node, struct dma_uap, node); - pl011_dma_probe_initcall(dmau->uap); + pl011_dma_probe_initcall(dmau->dev, dmau->uap); list_del(node); kfree(dmau); } @@ -334,18 +345,19 @@ static int __init pl011_dma_initcall(void) device_initcall(pl011_dma_initcall); -static void pl011_dma_probe(struct uart_amba_port *uap) +static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap) { struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL); if (dmau) { dmau->uap = uap; + dmau->dev = dev; list_add_tail(&dmau->node, &pl011_dma_uarts); } } #else -static void pl011_dma_probe(struct uart_amba_port *uap) +static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap) { - pl011_dma_probe_initcall(uap); + pl011_dma_probe_initcall(dev, uap); } #endif @@ -2020,7 +2032,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = i; - pl011_dma_probe(uap); + pl011_dma_probe(&dev->dev, uap); /* Ensure interrupts from this UART are masked and cleared */ writew(0, uap->port.membase + UART011_IMSC); -- cgit From 2fd61b32764c82b8410a4374d0ab3ec418ce37c7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:53:32 +0900 Subject: clocksource: sh_cmt: Take care of clk_put() when setup_irq() fails Make sure clk_put() is called in case of failure in sh_cmt_setup(). Signed-off-by: Shinya Kuribayashi Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 488c14cc8dbf..4b8d2962cad7 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -708,17 +708,19 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) cfg->clocksource_rating); if (ret) { dev_err(&p->pdev->dev, "registration failed\n"); - goto err1; + goto err2; } p->cs_enabled = false; ret = setup_irq(irq, &p->irqaction); if (ret) { dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); - goto err1; + goto err2; } return 0; +err2: + clk_put(p->clk); err1: iounmap(p->mapbase); -- cgit From 44a10f943f59339f1206d599d4269a35995e397e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:53:41 +0900 Subject: clocksource: sh_cmt: Initialize 'max_match_value' and 'lock' in sh_cmt_setup() Move the setup of spinlock and max_match_value to sh_cmt_setup(). There's no need to defer those steps until sh_cmt_register(). Signed-off-by: Shinya Kuribayashi Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 4b8d2962cad7..2e496841b167 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -625,14 +625,6 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name, unsigned long clockevent_rating, unsigned long clocksource_rating) { - if (p->width == (sizeof(p->max_match_value) * 8)) - p->max_match_value = ~0; - else - p->max_match_value = (1 << p->width) - 1; - - p->match_value = p->max_match_value; - raw_spin_lock_init(&p->lock); - if (clockevent_rating) sh_cmt_register_clockevent(p, name, clockevent_rating); @@ -703,6 +695,14 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) p->clear_bits = ~0xc000; } + if (p->width == (sizeof(p->max_match_value) * 8)) + p->max_match_value = ~0; + else + p->max_match_value = (1 << p->width) - 1; + + p->match_value = p->max_match_value; + raw_spin_lock_init(&p->lock); + ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev), cfg->clockevent_rating, cfg->clocksource_rating); -- cgit From 1b56b96b663d135305c3c47755fbdde3dc0ef720 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:54:00 +0900 Subject: clocksource: sh_cmt: Introduce per-register functions Introduce sh_cmt_read_cmstr/cmcsr/cmcnt() and sh_cmt_write_cmstr/cmcsr/cmcnt/cmcor() to in the future allow us to split counter registers from control registers and reduce code complexity by removing sh_cmt_read() and sh_cmt_write(). Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 71 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 2e496841b167..94fd3abd6434 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -86,6 +86,21 @@ static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) return ioread16(base + offs); } +static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) +{ + return sh_cmt_read(p, CMSTR); +} + +static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) +{ + return sh_cmt_read(p, CMCSR); +} + +static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) +{ + return sh_cmt_read(p, CMCNT); +} + static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, unsigned long value) { @@ -112,21 +127,45 @@ static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, iowrite16(value, base + offs); } +static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, + unsigned long value) +{ + sh_cmt_write(p, CMSTR, value); +} + +static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, + unsigned long value) +{ + sh_cmt_write(p, CMCSR, value); +} + +static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, + unsigned long value) +{ + sh_cmt_write(p, CMCNT, value); +} + +static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p, + unsigned long value) +{ + sh_cmt_write(p, CMCOR, value); +} + static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, int *has_wrapped) { unsigned long v1, v2, v3; int o1, o2; - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; + o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit; /* Make sure the timer value is stable. Stolen from acpi_pm.c */ do { o2 = o1; - v1 = sh_cmt_read(p, CMCNT); - v2 = sh_cmt_read(p, CMCNT); - v3 = sh_cmt_read(p, CMCNT); - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; + v1 = sh_cmt_read_cmcnt(p); + v2 = sh_cmt_read_cmcnt(p); + v3 = sh_cmt_read_cmcnt(p); + o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit; } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); @@ -142,14 +181,14 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) /* start stop register shared by multiple timer channels */ raw_spin_lock_irqsave(&sh_cmt_lock, flags); - value = sh_cmt_read(p, CMSTR); + value = sh_cmt_read_cmstr(p); if (start) value |= 1 << cfg->timer_bit; else value &= ~(1 << cfg->timer_bit); - sh_cmt_write(p, CMSTR, value); + sh_cmt_write_cmstr(p, value); raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); } @@ -173,14 +212,14 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) /* configure channel, periodic mode and maximum timeout */ if (p->width == 16) { *rate = clk_get_rate(p->clk) / 512; - sh_cmt_write(p, CMCSR, 0x43); + sh_cmt_write_cmcsr(p, 0x43); } else { *rate = clk_get_rate(p->clk) / 8; - sh_cmt_write(p, CMCSR, 0x01a4); + sh_cmt_write_cmcsr(p, 0x01a4); } - sh_cmt_write(p, CMCOR, 0xffffffff); - sh_cmt_write(p, CMCNT, 0); + sh_cmt_write_cmcor(p, 0xffffffff); + sh_cmt_write_cmcnt(p, 0); /* * According to the sh73a0 user's manual, as CMCNT can be operated @@ -194,12 +233,12 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) * take RCLKx2 at maximum. */ for (k = 0; k < 100; k++) { - if (!sh_cmt_read(p, CMCNT)) + if (!sh_cmt_read_cmcnt(p)) break; udelay(1); } - if (sh_cmt_read(p, CMCNT)) { + if (sh_cmt_read_cmcnt(p)) { dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); ret = -ETIMEDOUT; goto err1; @@ -222,7 +261,7 @@ static void sh_cmt_disable(struct sh_cmt_priv *p) sh_cmt_start_stop_ch(p, 0); /* disable interrupts in CMT block */ - sh_cmt_write(p, CMCSR, 0); + sh_cmt_write_cmcsr(p, 0); /* stop clock */ clk_disable(p->clk); @@ -270,7 +309,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, if (new_match > p->max_match_value) new_match = p->max_match_value; - sh_cmt_write(p, CMCOR, new_match); + sh_cmt_write_cmcor(p, new_match); now = sh_cmt_get_counter(p, &has_wrapped); if (has_wrapped && (new_match > p->match_value)) { @@ -346,7 +385,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) struct sh_cmt_priv *p = dev_id; /* clear flags */ - sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits); + sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits); /* update clock source counter to begin with if enabled * the wrap flag should be cleared by the timer specific -- cgit From adccc69e7ad1815ce79b073830b244a803776bbd Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:53:51 +0900 Subject: clocksource: sh_cmt: Consolidate platform_set_drvdata() call Cleanup the use of platform_set_drvdata() to reduce code size Signed-off-by: Shinya Kuribayashi Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 94fd3abd6434..a2f8023a846b 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -688,8 +688,6 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) goto err0; } - platform_set_drvdata(pdev, p); - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&p->pdev->dev, "failed to get I/O memory\n"); @@ -757,6 +755,8 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) goto err2; } + platform_set_drvdata(pdev, p); + return 0; err2: clk_put(p->clk); @@ -792,7 +792,6 @@ static int sh_cmt_probe(struct platform_device *pdev) ret = sh_cmt_setup(p, pdev); if (ret) { kfree(p); - platform_set_drvdata(pdev, NULL); pm_runtime_idle(&pdev->dev); return ret; } -- cgit From 587acb3dd5cf387de1325309e831fd0f560d1bf6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:54:10 +0900 Subject: clocksource: sh_cmt: CMSTR and CMCSR register access update Update hardware register access code for CMSTR and CMCSR from using sh_cmt_read() and sh_cmt_write() to make use of 16-bit register access functions such as sh_cmt_read16() and sh_cmt_write16(). Also update sh_cmt_read() and sh_cmt_write() now when the special cases are gone. This patch moves us one step closer to the goal of separating counter register access functions from control control register functions. Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 66 ++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index a2f8023a846b..eefacc3ac4f2 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -56,44 +56,46 @@ struct sh_cmt_priv { bool cs_enabled; }; -static DEFINE_RAW_SPINLOCK(sh_cmt_lock); +static inline unsigned long sh_cmt_read16(void __iomem *base, + unsigned long offs) +{ + return ioread16(base + (offs << 1)); +} + +static inline void sh_cmt_write16(void __iomem *base, unsigned long offs, + unsigned long value) +{ + iowrite16(value, base + (offs << 1)); +} -#define CMSTR -1 /* shared register */ #define CMCSR 0 /* channel register */ #define CMCNT 1 /* channel register */ #define CMCOR 2 /* channel register */ static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) { - struct sh_timer_config *cfg = p->pdev->dev.platform_data; void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; + unsigned long offs = reg_nr; - if (p->width == 16) + if (p->width == 16) { offs <<= 1; - else { + return ioread16(base + offs); + } else { offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) - return ioread32(base + offs); + return ioread32(base + offs); } - - return ioread16(base + offs); } static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) { - return sh_cmt_read(p, CMSTR); + struct sh_timer_config *cfg = p->pdev->dev.platform_data; + + return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0); } static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) { - return sh_cmt_read(p, CMCSR); + return sh_cmt_read16(p->mapbase, CMCSR); } static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) @@ -104,39 +106,30 @@ static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, unsigned long value) { - struct sh_timer_config *cfg = p->pdev->dev.platform_data; void __iomem *base = p->mapbase; - unsigned long offs; + unsigned long offs = reg_nr; - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; - - if (p->width == 16) + if (p->width == 16) { offs <<= 1; - else { + iowrite16(value, base + offs); + } else { offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) { - iowrite32(value, base + offs); - return; - } + iowrite32(value, base + offs); } - - iowrite16(value, base + offs); } static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, unsigned long value) { - sh_cmt_write(p, CMSTR, value); + struct sh_timer_config *cfg = p->pdev->dev.platform_data; + + sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value); } static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, unsigned long value) { - sh_cmt_write(p, CMCSR, value); + sh_cmt_write16(p->mapbase, CMCSR, value); } static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, @@ -173,6 +166,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, return v2; } +static DEFINE_RAW_SPINLOCK(sh_cmt_lock); static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) { -- cgit From a6a912ca43843d43590ce5f1cbc85cbc7ac14bba Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:54:19 +0900 Subject: clocksource: sh_cmt: CMCNT and CMCOR register access update Break out the CMCNT and CMCOR register access code into separate 16-bit and 32-bit functions that are hooked into callbacks at init time. This reduces the amount of software calculations happening at runtime. Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 62 +++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index eefacc3ac4f2..da904d7f7530 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -54,38 +54,39 @@ struct sh_cmt_priv { struct clocksource cs; unsigned long total_cycles; bool cs_enabled; + + /* callbacks for CMCNT and CMCOR access */ + unsigned long (*read_count)(void __iomem *base, unsigned long offs); + void (*write_count)(void __iomem *base, unsigned long offs, + unsigned long value); }; -static inline unsigned long sh_cmt_read16(void __iomem *base, - unsigned long offs) +static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) { return ioread16(base + (offs << 1)); } -static inline void sh_cmt_write16(void __iomem *base, unsigned long offs, - unsigned long value) +static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs) +{ + return ioread32(base + (offs << 2)); +} + +static void sh_cmt_write16(void __iomem *base, unsigned long offs, + unsigned long value) { iowrite16(value, base + (offs << 1)); } +static void sh_cmt_write32(void __iomem *base, unsigned long offs, + unsigned long value) +{ + iowrite32(value, base + (offs << 2)); +} + #define CMCSR 0 /* channel register */ #define CMCNT 1 /* channel register */ #define CMCOR 2 /* channel register */ -static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) -{ - void __iomem *base = p->mapbase; - unsigned long offs = reg_nr; - - if (p->width == 16) { - offs <<= 1; - return ioread16(base + offs); - } else { - offs <<= 2; - return ioread32(base + offs); - } -} - static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) { struct sh_timer_config *cfg = p->pdev->dev.platform_data; @@ -100,22 +101,7 @@ static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) { - return sh_cmt_read(p, CMCNT); -} - -static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, - unsigned long value) -{ - void __iomem *base = p->mapbase; - unsigned long offs = reg_nr; - - if (p->width == 16) { - offs <<= 1; - iowrite16(value, base + offs); - } else { - offs <<= 2; - iowrite32(value, base + offs); - } + return p->read_count(p->mapbase, CMCNT); } static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, @@ -135,13 +121,13 @@ static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, unsigned long value) { - sh_cmt_write(p, CMCNT, value); + p->write_count(p->mapbase, CMCNT, value); } static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p, unsigned long value) { - sh_cmt_write(p, CMCOR, value); + p->write_count(p->mapbase, CMCOR, value); } static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, @@ -718,10 +704,14 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) if (resource_size(res) == 6) { p->width = 16; + p->read_count = sh_cmt_read16; + p->write_count = sh_cmt_write16; p->overflow_bit = 0x80; p->clear_bits = ~0x80; } else { p->width = 32; + p->read_count = sh_cmt_read32; + p->write_count = sh_cmt_write32; p->overflow_bit = 0x8000; p->clear_bits = ~0xc000; } -- cgit From cccd70455c351604d0a9075d35298ed4ff66dab3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:54:28 +0900 Subject: clocksource: sh_cmt: Add control register callbacks This patch adds control register callbacks for the CMT driver. At this point only 16-bit access is supported but in the future this will be updated to allow 32-bit access as well. Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index da904d7f7530..7108963a6ab8 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -55,6 +55,11 @@ struct sh_cmt_priv { unsigned long total_cycles; bool cs_enabled; + /* callbacks for CMSTR and CMCSR access */ + unsigned long (*read_control)(void __iomem *base, unsigned long offs); + void (*write_control)(void __iomem *base, unsigned long offs, + unsigned long value); + /* callbacks for CMCNT and CMCOR access */ unsigned long (*read_count)(void __iomem *base, unsigned long offs); void (*write_count)(void __iomem *base, unsigned long offs, @@ -91,12 +96,12 @@ static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) { struct sh_timer_config *cfg = p->pdev->dev.platform_data; - return sh_cmt_read16(p->mapbase - cfg->channel_offset, 0); + return p->read_control(p->mapbase - cfg->channel_offset, 0); } static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) { - return sh_cmt_read16(p->mapbase, CMCSR); + return p->read_control(p->mapbase, CMCSR); } static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) @@ -109,13 +114,13 @@ static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, { struct sh_timer_config *cfg = p->pdev->dev.platform_data; - sh_cmt_write16(p->mapbase - cfg->channel_offset, 0, value); + p->write_control(p->mapbase - cfg->channel_offset, 0, value); } static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, unsigned long value) { - sh_cmt_write16(p->mapbase, CMCSR, value); + p->write_control(p->mapbase, CMCSR, value); } static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p, @@ -702,6 +707,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) goto err1; } + p->read_control = sh_cmt_read16; + p->write_control = sh_cmt_write16; + if (resource_size(res) == 6) { p->width = 16; p->read_count = sh_cmt_read16; -- cgit From 118aee4dd91cf3c0b9546788ef66b65d3e9e31b1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Dec 2012 14:54:37 +0900 Subject: clocksource: sh_cmt: Add CMT register layout comment Add a comment about different register layouts supported by the CMT driver. Signed-off-by: Magnus Damm Acked-by: John Stultz Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 7108963a6ab8..b72b7242125e 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -66,6 +66,21 @@ struct sh_cmt_priv { unsigned long value); }; +/* Examples of supported CMT timer register layouts and I/O access widths: + * + * "16-bit counter and 16-bit control" as found on sh7263: + * CMSTR 0xfffec000 16-bit + * CMCSR 0xfffec002 16-bit + * CMCNT 0xfffec004 16-bit + * CMCOR 0xfffec006 16-bit + * + * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740: + * CMSTR 0xffca0000 16-bit + * CMCSR 0xffca0060 16-bit + * CMCNT 0xffca0064 32-bit + * CMCOR 0xffca0068 32-bit + */ + static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) { return ioread16(base + (offs << 1)); -- cgit From e903a031402c8dccc675b2f0cf8af40ac89163b0 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Mar 2013 15:40:42 +0900 Subject: clocksource: sh_cmt: Set initcall level to subsys The reason for this is to ensure that CMT is probed earlier than with its previous initcall level, module init. This came up as a problem with using kzm9g-reference which does not make use of early timers or devices. In that scenario initialisation of SDHI and MMCIF both stall on msleep() calls due to the absence of a initialised clock source. Boot tested on: armadillo800eva, mackerel and kzm9g Signed-off-by: Simon Horman --- drivers/clocksource/sh_cmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index b72b7242125e..08d0c418c94a 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -838,7 +838,7 @@ static void __exit sh_cmt_exit(void) } early_platform_init("earlytimer", &sh_cmt_device_driver); -module_init(sh_cmt_init); +subsys_initcall(sh_cmt_init); module_exit(sh_cmt_exit); MODULE_AUTHOR("Magnus Damm"); -- cgit From b9773c3f52540ada159dc135c07653be010deee7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Mar 2013 15:40:42 +0900 Subject: clocksource: sh_tmu: Set initcall level to subsys The reason for this is to ensure that TMU is probed earlier than with its previous initcall level, module init. This came up as a problem with using CMT as a clock source kzm9g-reference which does not make use of early timers or devices. In that scenario initialisation of SDHI and MMCIF both stall on msleep() calls due to the absence of a initialised clock source. The purpose of this change is to keep the TMU code in sync with the CMT code which has been modified in a similar manner.. Boot tested on: mackerel. Signed-off-by: Simon Horman --- drivers/clocksource/sh_tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index b4502edce2a1..78b8dae49628 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -549,7 +549,7 @@ static void __exit sh_tmu_exit(void) } early_platform_init("earlytimer", &sh_tmu_device_driver); -module_init(sh_tmu_init); +subsys_initcall(sh_tmu_init); module_exit(sh_tmu_exit); MODULE_AUTHOR("Magnus Damm"); -- cgit From 09acc3a1e0dee537fcfcd5a6c17a1e9b26586066 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Mar 2013 15:40:42 +0900 Subject: clocksource: em_sti: Set initcall level to subsys The reason for this is to ensure that STI is probed earlier than with its previous initcall level, module init. This came up as a problem with using CMT as a clock source kzm9g-reference which does not make use of early timers or devices. In that scenario initialisation of SDHI and MMCIF both stall on msleep() calls due to the absence of a initialised clock source. The purpose of this change is to keep the STI code in sync with the CMT code which has been modified in a similar manner.. Boot tested on: kzm9d. Signed-off-by: Simon Horman --- drivers/clocksource/em_sti.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index e6a553cb73e8..4329a29a5310 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c @@ -399,7 +399,18 @@ static struct platform_driver em_sti_device_driver = { } }; -module_platform_driver(em_sti_device_driver); +static int __init em_sti_init(void) +{ + return platform_driver_register(&em_sti_device_driver); +} + +static void __exit em_sti_exit(void) +{ + platform_driver_unregister(&em_sti_device_driver); +} + +subsys_initcall(em_sti_init); +module_exit(em_sti_exit); MODULE_AUTHOR("Magnus Damm"); MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver"); -- cgit From 342896a5c565e38dfb87954f362735f03ae1efb0 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Mar 2013 15:40:42 +0900 Subject: clocksource: sh_mtu2: Set initcall level to subsys The reason for this is to ensure that MTU2 is probed earlier than with its previous initcall level, module init. This came up as a problem with using CMT as a clock source kzm9g-reference which does not make use of early timers or devices. In that scenario initialisation of SDHI and MMCIF both stall on msleep() calls due to the absence of a initialised clock source. The purpose of this change is to keep the MTU2 code in sync with the CMT code which has been modified in a similar manner.. Compile tested only using se7206_defconfig. I do not believe I have any boards that support the MTU2. Signed-off-by: Simon Horman --- drivers/clocksource/sh_mtu2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 83943e27cfac..4aac9ee0d0c0 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -386,7 +386,7 @@ static void __exit sh_mtu2_exit(void) } early_platform_init("earlytimer", &sh_mtu2_device_driver); -module_init(sh_mtu2_init); +subsys_initcall(sh_mtu2_init); module_exit(sh_mtu2_exit); MODULE_AUTHOR("Magnus Damm"); -- cgit From 71f2146f6c22716838ffafd054391826341874f9 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Mar 2013 23:40:19 +0800 Subject: regulator: palmas: Use of_property_read_bool to read "ti,warm-reset" DT property It does not make sense to assign return value of of_property_read_u32() to pdata->reg_init[idx]->warm_reset. Use of_property_read_bool() to read "ti,warm-reset" DT property instead which will return correct setting for pdata->reg_init[idx]->warm_reset. Signed-off-by: Axel Lin Acked-by: Graeme Gregory Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index c25c2ff48305..122fea432d38 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -553,8 +553,8 @@ static void palmas_dt_to_pdata(struct device *dev, sizeof(struct palmas_reg_init), GFP_KERNEL); pdata->reg_init[idx]->warm_reset = - of_property_read_u32(palmas_matches[idx].of_node, - "ti,warm-reset", &prop); + of_property_read_bool(palmas_matches[idx].of_node, + "ti,warm-reset"); pdata->reg_init[idx]->roof_floor = of_property_read_bool(palmas_matches[idx].of_node, -- cgit From d77b5382e67d1e1394e40c5c95fb5947efe0ff9e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 22 Feb 2013 10:52:35 +0800 Subject: spi: fix return value check in ce4100_spi_probe() In case of error, the function platform_device_register_full() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). Signed-off-by: Wei Yongjun Acked-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 364964d2ed04..0a11dcfc631b 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -47,8 +47,8 @@ static int ce4100_spi_probe(struct pci_dev *dev, pi.size_data = sizeof(spi_pdata); pdev = platform_device_register_full(&pi); - if (!pdev) - return -ENOMEM; + if (IS_ERR(pdev)) + return PTR_ERR(pdev); pci_set_drvdata(dev, pdev); -- cgit From f8043872e79614ae9c5aaf7804e0b0ccb1932ed0 Mon Sep 17 00:00:00 2001 From: Chris Boot Date: Mon, 11 Mar 2013 21:38:24 -0600 Subject: spi: add driver for BCM2835 The BCM2835 contains two forms of SPI master controller (one known simply as SPI0, and the other known as the "Universal SPI Master", in the auxilliary block) and one form of SPI slave controller. This patch adds support for the SPI0 controller. This driver is taken from Chris Boot's repository at git://github.com/bootc/linux.git rpi-linear as of commit 6de2905 "spi-bcm2708: fix printf with spurious %s". In the first SPI-related commit there, Chris wrote: Thanks to csoutreach / A Robinson for his driver which I used as an inspiration. You can find his version here: http://piface.openlx.org.uk/raspberry-pi-spi-kernel-driver-available-for Changes made during upstreaming: * Renamed bcm2708 to bcm2835 as per upstream naming for this SoC. * Removed support for brcm,realtime property. * Increased transfer timeout to 30 seconds. * Return IRQ_NONE from the IRQ handler if no interrupt was handled. * Disable TA (Transfer Active) and clear FIFOs on a transfer timeout. * Wrote device tree binding documentation. * Request unnamed clock rather than "sys_pclk"; the DT will provide the correct clock. * Assume that tfr->speed_hz and tfr->bits_per_word are always set in bcm2835_spi_start_transfer(), bcm2835_spi_transfer_one(), so no need to check spi->speed_hz or tft->bits_per_word. * Re-ordered probe() to remove the need for temporary variables. * Call clk_disable_unprepare() rather than just clk_unprepare() on probe() failure. * Don't use devm_request_irq(), to ensure that the IRQ doesn't fire after we've torn down the device, but not unhooked the IRQ. * Moved probe()'s call to clk_prepare_enable() so we can be sure the clock is enabled if the IRQ handler fires immediately. * Remove redundant checks from bcm2835_spi_check_transfer() and bcm2835_spi_setup(). * Re-ordered IRQ handler to check for RXR before DONE. Added comments to ISR. * Removed empty prepare/unprepare implementations. * Removed use of devinit/devexit. * Added BCM2835_ prefix to defines. Signed-off-by: Chris Boot Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/brcm,bcm2835-spi.txt | 22 + drivers/spi/Kconfig | 11 + drivers/spi/Makefile | 1 + drivers/spi/spi-bcm2835.c | 456 +++++++++++++++++++++ 4 files changed, 490 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt create mode 100644 drivers/spi/spi-bcm2835.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt b/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt new file mode 100644 index 000000000000..8bf89c643640 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt @@ -0,0 +1,22 @@ +Broadcom BCM2835 SPI0 controller + +The BCM2835 contains two forms of SPI master controller, one known simply as +SPI0, and the other known as the "Universal SPI Master"; part of the +auxilliary block. This binding applies to the SPI0 controller. + +Required properties: +- compatible: Should be "brcm,bcm2835-spi". +- reg: Should contain register location and length. +- interrupts: Should contain interrupt. +- clocks: The clock feeding the SPI controller. + +Example: + +spi@20204000 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x1000>; + interrupts = <2 22>; + clocks = <&clk_spi>; + #address-cells = <1>; + #size-cells = <0>; +}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f80eee74a311..32b85d43bbe2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -74,6 +74,17 @@ config SPI_ATMEL This selects a driver for the Atmel SPI Controller, present on many AT32 (AVR32) and AT91 (ARM) chips. +config SPI_BCM2835 + tristate "BCM2835 SPI controller" + depends on ARCH_BCM2835 + help + This selects a driver for the Broadcom BCM2835 SPI master. + + The BCM2835 contains two types of SPI master controller; the + "universal SPI master", and the regular SPI controller. This driver + is for the regular SPI controller. Slave mode operation is not also + not supported. + config SPI_BFIN5XX tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e53c30941340..3ce1d082ce79 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi-altera.o obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o obj-$(CONFIG_SPI_ATH79) += spi-ath79.o obj-$(CONFIG_SPI_AU1550) += spi-au1550.o +obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c new file mode 100644 index 000000000000..346601e2461d --- /dev/null +++ b/drivers/spi/spi-bcm2835.c @@ -0,0 +1,456 @@ +/* + * Driver for Broadcom BCM2835 SPI Controllers + * + * Copyright (C) 2012 Chris Boot + * Copyright (C) 2013 Stephen Warren + * + * This driver is inspired by: + * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos + * spi-atmel.c, Copyright (C) 2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SPI register offsets */ +#define BCM2835_SPI_CS 0x00 +#define BCM2835_SPI_FIFO 0x04 +#define BCM2835_SPI_CLK 0x08 +#define BCM2835_SPI_DLEN 0x0c +#define BCM2835_SPI_LTOH 0x10 +#define BCM2835_SPI_DC 0x14 + +/* Bitfields in CS */ +#define BCM2835_SPI_CS_LEN_LONG 0x02000000 +#define BCM2835_SPI_CS_DMA_LEN 0x01000000 +#define BCM2835_SPI_CS_CSPOL2 0x00800000 +#define BCM2835_SPI_CS_CSPOL1 0x00400000 +#define BCM2835_SPI_CS_CSPOL0 0x00200000 +#define BCM2835_SPI_CS_RXF 0x00100000 +#define BCM2835_SPI_CS_RXR 0x00080000 +#define BCM2835_SPI_CS_TXD 0x00040000 +#define BCM2835_SPI_CS_RXD 0x00020000 +#define BCM2835_SPI_CS_DONE 0x00010000 +#define BCM2835_SPI_CS_LEN 0x00002000 +#define BCM2835_SPI_CS_REN 0x00001000 +#define BCM2835_SPI_CS_ADCS 0x00000800 +#define BCM2835_SPI_CS_INTR 0x00000400 +#define BCM2835_SPI_CS_INTD 0x00000200 +#define BCM2835_SPI_CS_DMAEN 0x00000100 +#define BCM2835_SPI_CS_TA 0x00000080 +#define BCM2835_SPI_CS_CSPOL 0x00000040 +#define BCM2835_SPI_CS_CLEAR_RX 0x00000020 +#define BCM2835_SPI_CS_CLEAR_TX 0x00000010 +#define BCM2835_SPI_CS_CPOL 0x00000008 +#define BCM2835_SPI_CS_CPHA 0x00000004 +#define BCM2835_SPI_CS_CS_10 0x00000002 +#define BCM2835_SPI_CS_CS_01 0x00000001 + +#define BCM2835_SPI_TIMEOUT_MS 30000 +#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS) + +#define DRV_NAME "spi-bcm2835" + +struct bcm2835_spi { + void __iomem *regs; + struct clk *clk; + int irq; + struct completion done; + const u8 *tx_buf; + u8 *rx_buf; + int len; +}; + +static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) +{ + return readl(bs->regs + reg); +} + +static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned reg, u32 val) +{ + writel(val, bs->regs + reg); +} + +static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs, int len) +{ + u8 byte; + + while (len--) { + byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); + if (bs->rx_buf) + *bs->rx_buf++ = byte; + } +} + +static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs, int len) +{ + u8 byte; + + if (len > bs->len) + len = bs->len; + + while (len--) { + byte = bs->tx_buf ? *bs->tx_buf++ : 0; + bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); + bs->len--; + } +} + +static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) +{ + struct spi_master *master = dev_id; + struct bcm2835_spi *bs = spi_master_get_devdata(master); + u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); + + /* + * RXR - RX needs Reading. This means 12 (or more) bytes have been + * transmitted and hence 12 (or more) bytes have been received. + * + * The FIFO is 16-bytes deep. We check for this interrupt to keep the + * FIFO full; we have a 4-byte-time buffer for IRQ latency. We check + * this before DONE (TX empty) just in case we delayed processing this + * interrupt for some reason. + * + * We only check for this case if we have more bytes to TX; at the end + * of the transfer, we ignore this pipelining optimization, and let + * bcm2835_spi_finish_transfer() drain the RX FIFO. + */ + if (bs->len && (cs & BCM2835_SPI_CS_RXR)) { + /* Read 12 bytes of data */ + bcm2835_rd_fifo(bs, 12); + + /* Write up to 12 bytes */ + bcm2835_wr_fifo(bs, 12); + + /* + * We must have written something to the TX FIFO due to the + * bs->len check above, so cannot be DONE. Hence, return + * early. Note that DONE could also be set if we serviced an + * RXR interrupt really late. + */ + return IRQ_HANDLED; + } + + /* + * DONE - TX empty. This occurs when we first enable the transfer + * since we do not pre-fill the TX FIFO. At any other time, given that + * we refill the TX FIFO above based on RXR, and hence ignore DONE if + * RXR is set, DONE really does mean end-of-transfer. + */ + if (cs & BCM2835_SPI_CS_DONE) { + if (bs->len) { /* First interrupt in a transfer */ + bcm2835_wr_fifo(bs, 16); + } else { /* Transfer complete */ + /* Disable SPI interrupts */ + cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); + bcm2835_wr(bs, BCM2835_SPI_CS, cs); + + /* + * Wake up bcm2835_spi_transfer_one(), which will call + * bcm2835_spi_finish_transfer(), to drain the RX FIFO. + */ + complete(&bs->done); + } + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int bcm2835_spi_check_transfer(struct spi_device *spi, + struct spi_transfer *tfr) +{ + /* tfr==NULL when called from bcm2835_spi_setup() */ + u32 bpw = tfr ? tfr->bits_per_word : spi->bits_per_word; + + switch (bpw) { + case 8: + break; + default: + dev_err(&spi->dev, "unsupported bits_per_word=%d\n", bpw); + return -EINVAL; + } + + return 0; +} + +static int bcm2835_spi_start_transfer(struct spi_device *spi, + struct spi_transfer *tfr) +{ + struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); + unsigned long spi_hz, clk_hz, cdiv; + u32 cs = BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; + + spi_hz = tfr->speed_hz; + clk_hz = clk_get_rate(bs->clk); + + if (spi_hz >= clk_hz / 2) { + cdiv = 2; /* clk_hz/2 is the fastest we can go */ + } else if (spi_hz) { + /* CDIV must be a power of two */ + cdiv = roundup_pow_of_two(DIV_ROUND_UP(clk_hz, spi_hz)); + + if (cdiv >= 65536) + cdiv = 0; /* 0 is the slowest we can go */ + } else + cdiv = 0; /* 0 is the slowest we can go */ + + if (spi->mode & SPI_CPOL) + cs |= BCM2835_SPI_CS_CPOL; + if (spi->mode & SPI_CPHA) + cs |= BCM2835_SPI_CS_CPHA; + + if (!(spi->mode & SPI_NO_CS)) { + if (spi->mode & SPI_CS_HIGH) { + cs |= BCM2835_SPI_CS_CSPOL; + cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; + } + + cs |= spi->chip_select; + } + + INIT_COMPLETION(bs->done); + bs->tx_buf = tfr->tx_buf; + bs->rx_buf = tfr->rx_buf; + bs->len = tfr->len; + + bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); + /* + * Enable the HW block. This will immediately trigger a DONE (TX + * empty) interrupt, upon which we will fill the TX FIFO with the + * first TX bytes. Pre-filling the TX FIFO here to avoid the + * interrupt doesn't work:-( + */ + bcm2835_wr(bs, BCM2835_SPI_CS, cs); + + return 0; +} + +static int bcm2835_spi_finish_transfer(struct spi_device *spi, + struct spi_transfer *tfr, bool cs_change) +{ + struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); + u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); + + /* Drain RX FIFO */ + while (cs & BCM2835_SPI_CS_RXD) { + bcm2835_rd_fifo(bs, 1); + cs = bcm2835_rd(bs, BCM2835_SPI_CS); + } + + if (tfr->delay_usecs) + udelay(tfr->delay_usecs); + + if (cs_change) + /* Clear TA flag */ + bcm2835_wr(bs, BCM2835_SPI_CS, cs & ~BCM2835_SPI_CS_TA); + + return 0; +} + +static int bcm2835_spi_setup(struct spi_device *spi) +{ + int ret; + + ret = bcm2835_spi_check_transfer(spi, NULL); + if (ret) { + dev_err(&spi->dev, "setup: invalid message\n"); + return ret; + } + + return 0; +} + +static int bcm2835_spi_transfer_one(struct spi_master *master, + struct spi_message *mesg) +{ + struct bcm2835_spi *bs = spi_master_get_devdata(master); + struct spi_transfer *tfr; + struct spi_device *spi = mesg->spi; + int err = 0; + unsigned int timeout; + bool cs_change; + + list_for_each_entry(tfr, &mesg->transfers, transfer_list) { + err = bcm2835_spi_check_transfer(spi, tfr); + if (err) + goto out; + + err = bcm2835_spi_start_transfer(spi, tfr); + if (err) + goto out; + + timeout = wait_for_completion_timeout(&bs->done, + msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)); + if (!timeout) { + err = -ETIMEDOUT; + goto out; + } + + cs_change = tfr->cs_change || + list_is_last(&tfr->transfer_list, &mesg->transfers); + + err = bcm2835_spi_finish_transfer(spi, tfr, cs_change); + if (err) + goto out; + + mesg->actual_length += (tfr->len - bs->len); + } + +out: + /* Clear FIFOs, and disable the HW block */ + bcm2835_wr(bs, BCM2835_SPI_CS, + BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); + mesg->status = err; + spi_finalize_current_message(master); + + return 0; +} + +static int bcm2835_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct bcm2835_spi *bs; + struct resource *res; + int err; + + master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + if (!master) { + dev_err(&pdev->dev, "spi_alloc_master() failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, master); + + master->mode_bits = BCM2835_SPI_MODE_BITS; + master->bus_num = -1; + master->num_chipselect = 3; + master->setup = bcm2835_spi_setup; + master->transfer_one_message = bcm2835_spi_transfer_one; + master->dev.of_node = pdev->dev.of_node; + + bs = spi_master_get_devdata(master); + + init_completion(&bs->done); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "could not get memory resource\n"); + err = -ENODEV; + goto out_master_put; + } + + bs->regs = devm_request_and_ioremap(&pdev->dev, res); + if (!bs->regs) { + dev_err(&pdev->dev, "could not request/map memory region\n"); + err = -ENODEV; + goto out_master_put; + } + + bs->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(bs->clk)) { + err = PTR_ERR(bs->clk); + dev_err(&pdev->dev, "could not get clk: %d\n", err); + goto out_master_put; + } + + bs->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + if (bs->irq <= 0) { + dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); + err = bs->irq ? bs->irq : -ENODEV; + goto out_master_put; + } + + clk_prepare_enable(bs->clk); + + err = request_irq(bs->irq, bcm2835_spi_interrupt, 0, + dev_name(&pdev->dev), master); + if (err) { + dev_err(&pdev->dev, "could not request IRQ: %d\n", err); + goto out_clk_disable; + } + + /* initialise the hardware */ + bcm2835_wr(bs, BCM2835_SPI_CS, + BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); + + err = spi_register_master(master); + if (err) { + dev_err(&pdev->dev, "could not register SPI master: %d\n", err); + goto out_free_irq; + } + + return 0; + +out_free_irq: + free_irq(bs->irq, master); +out_clk_disable: + clk_disable_unprepare(bs->clk); +out_master_put: + spi_master_put(master); + return err; +} + +static int bcm2835_spi_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + struct bcm2835_spi *bs = spi_master_get_devdata(master); + + free_irq(bs->irq, master); + spi_unregister_master(master); + + /* Clear FIFOs, and disable the HW block */ + bcm2835_wr(bs, BCM2835_SPI_CS, + BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); + + clk_disable_unprepare(bs->clk); + spi_master_put(master); + + return 0; +} + +static const struct of_device_id bcm2835_spi_match[] = { + { .compatible = "brcm,bcm2835-spi", }, + {} +}; +MODULE_DEVICE_TABLE(of, bcm2835_spi_match); + +static struct platform_driver bcm2835_spi_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = bcm2835_spi_match, + }, + .probe = bcm2835_spi_probe, + .remove = bcm2835_spi_remove, +}; +module_platform_driver(bcm2835_spi_driver); + +MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2835"); +MODULE_AUTHOR("Chris Boot "); +MODULE_LICENSE("GPL v2"); -- cgit From c6432ea9cc043994d5b7dcb3ad86a087777cb40c Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 11 Mar 2013 17:27:02 +0000 Subject: regmap: Initialize `map->debugfs' before regcache In the rbtree code we are exposing statistics relating to the number of nodes/registers of the rbtree cache for each of the devices. Ensure that `map->debugfs' has been initialized before we attempt to initialize the debugfs entry for the rbtree cache. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..50ef277ea4b6 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -710,12 +710,12 @@ skip_format_initialization: } } + regmap_debugfs_init(map, config->name); + ret = regcache_init(map, config); if (ret != 0) goto err_range; - regmap_debugfs_init(map, config->name); - /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { -- cgit From c134634077942404a285f6b64bc1ce5932ac22fe Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 5 Mar 2013 12:05:16 +0200 Subject: spi/pxa2xx-pci: correct the return value check of pcim_iomap_regions() The function returns 0 on success and negative errno in case of failure. Fix this. Signed-off-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 0a11dcfc631b..74bc18775658 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -22,7 +22,7 @@ static int ce4100_spi_probe(struct pci_dev *dev, return ret; ret = pcim_iomap_regions(dev, 1 << 0, "PXA2xx SPI"); - if (!ret) + if (ret) return ret; memset(&spi_pdata, 0, sizeof(spi_pdata)); -- cgit From 0054e28dc9d2d7c43b569ed5d491bc8bc2f903a9 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 5 Mar 2013 12:05:17 +0200 Subject: spi/pxa2xx: enable multiblock DMA transfers for LPSS devices Intel LPSS SPI controllers need to have bit 0 (disable_ssp_dma_finish) set in SSP_REG in order to properly perform DMA transfers spanning over multiple blocks. Signed-off-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 90b27a3508a6..c6d5b97c7240 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -68,6 +68,7 @@ MODULE_ALIAS("platform:pxa2xx-spi"); #define LPSS_TX_HITHRESH_DFLT 224 /* Offset from drv_data->lpss_base */ +#define SSP_REG 0x0c #define SPI_CS_CONTROL 0x18 #define SPI_CS_CONTROL_SW_MODE BIT(0) #define SPI_CS_CONTROL_CS_HIGH BIT(1) @@ -138,6 +139,10 @@ detection_done: /* Enable software chip select control */ value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH; __lpss_ssp_write_priv(drv_data, SPI_CS_CONTROL, value); + + /* Enable multiblock DMA transfers */ + if (drv_data->master_info->enable_dma) + __lpss_ssp_write_priv(drv_data, SSP_REG, 1); } static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) -- cgit From d73ce004225a7b2ed75f4340bb63721d55552265 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 12 Mar 2013 11:30:05 -0700 Subject: driver/base: implement subsys_virtual_register() Kay tells me the most appropriate place to expose workqueues to userland would be /sys/devices/virtual/workqueues/WQ_NAME which is symlinked to /sys/bus/workqueue/devices/WQ_NAME and that we're lacking a way to do that outside of driver core as virtual_device_parent() isn't exported and there's no inteface to conveniently create a virtual subsystem. This patch implements subsys_virtual_register() by factoring out subsys_register() from subsys_system_register() and using it with virtual_device_parent() as the origin directory. It's identical to subsys_system_register() other than the origin directory but we aren't gonna restrict the device names which should be used under it. This will be used to expose workqueue attributes to userland. Signed-off-by: Tejun Heo Acked-by: Greg Kroah-Hartman Cc: Kay Sievers --- drivers/base/base.h | 2 ++ drivers/base/bus.c | 73 +++++++++++++++++++++++++++++++++++--------------- drivers/base/core.c | 2 +- include/linux/device.h | 2 ++ 4 files changed, 57 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/base/base.h b/drivers/base/base.h index 6ee17bb391a9..b8bdfe61daa6 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -101,6 +101,8 @@ static inline int hypervisor_init(void) { return 0; } extern int platform_bus_init(void); extern void cpu_dev_init(void); +struct kobject *virtual_device_parent(struct device *dev); + extern int bus_add_device(struct device *dev); extern void bus_probe_device(struct device *dev); extern void bus_remove_device(struct device *dev); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 519865b53f76..2ae2d2f92b6b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -1205,26 +1205,10 @@ static void system_root_device_release(struct device *dev) { kfree(dev); } -/** - * subsys_system_register - register a subsystem at /sys/devices/system/ - * @subsys: system subsystem - * @groups: default attributes for the root device - * - * All 'system' subsystems have a /sys/devices/system/ root device - * with the name of the subsystem. The root device can carry subsystem- - * wide attributes. All registered devices are below this single root - * device and are named after the subsystem with a simple enumeration - * number appended. The registered devices are not explicitely named; - * only 'id' in the device needs to be set. - * - * Do not use this interface for anything new, it exists for compatibility - * with bad ideas only. New subsystems should use plain subsystems; and - * add the subsystem-wide attributes should be added to the subsystem - * directory itself and not some create fake root-device placed in - * /sys/devices/system/. - */ -int subsys_system_register(struct bus_type *subsys, - const struct attribute_group **groups) + +static int subsys_register(struct bus_type *subsys, + const struct attribute_group **groups, + struct kobject *parent_of_root) { struct device *dev; int err; @@ -1243,7 +1227,7 @@ int subsys_system_register(struct bus_type *subsys, if (err < 0) goto err_name; - dev->kobj.parent = &system_kset->kobj; + dev->kobj.parent = parent_of_root; dev->groups = groups; dev->release = system_root_device_release; @@ -1263,8 +1247,55 @@ err_dev: bus_unregister(subsys); return err; } + +/** + * subsys_system_register - register a subsystem at /sys/devices/system/ + * @subsys: system subsystem + * @groups: default attributes for the root device + * + * All 'system' subsystems have a /sys/devices/system/ root device + * with the name of the subsystem. The root device can carry subsystem- + * wide attributes. All registered devices are below this single root + * device and are named after the subsystem with a simple enumeration + * number appended. The registered devices are not explicitely named; + * only 'id' in the device needs to be set. + * + * Do not use this interface for anything new, it exists for compatibility + * with bad ideas only. New subsystems should use plain subsystems; and + * add the subsystem-wide attributes should be added to the subsystem + * directory itself and not some create fake root-device placed in + * /sys/devices/system/. + */ +int subsys_system_register(struct bus_type *subsys, + const struct attribute_group **groups) +{ + return subsys_register(subsys, groups, &system_kset->kobj); +} EXPORT_SYMBOL_GPL(subsys_system_register); +/** + * subsys_virtual_register - register a subsystem at /sys/devices/virtual/ + * @subsys: virtual subsystem + * @groups: default attributes for the root device + * + * All 'virtual' subsystems have a /sys/devices/system/ root device + * with the name of the subystem. The root device can carry subsystem-wide + * attributes. All registered devices are below this single root device. + * There's no restriction on device naming. This is for kernel software + * constructs which need sysfs interface. + */ +int subsys_virtual_register(struct bus_type *subsys, + const struct attribute_group **groups) +{ + struct kobject *virtual_dir; + + virtual_dir = virtual_device_parent(NULL); + if (!virtual_dir) + return -ENOMEM; + + return subsys_register(subsys, groups, virtual_dir); +} + int __init buses_init(void) { bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); diff --git a/drivers/base/core.c b/drivers/base/core.c index 56536f4b0f6b..f58084a86e8c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -690,7 +690,7 @@ void device_initialize(struct device *dev) set_dev_node(dev, -1); } -static struct kobject *virtual_device_parent(struct device *dev) +struct kobject *virtual_device_parent(struct device *dev) { static struct kobject *virtual_dir = NULL; diff --git a/include/linux/device.h b/include/linux/device.h index 9d6464ea99c6..ee10d4e7be1a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -302,6 +302,8 @@ void subsys_interface_unregister(struct subsys_interface *sif); int subsys_system_register(struct bus_type *subsys, const struct attribute_group **groups); +int subsys_virtual_register(struct bus_type *subsys, + const struct attribute_group **groups); /** * struct class - device classes -- cgit From ca4d4aa6b79f143f4c8606c60bad005405623faa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Mar 2013 10:53:11 -0700 Subject: staging: comedi: ni_atmio: fix build errors The following commits introduced a couple build errors in this driver due to the removal of some macros in ni_stc.h. commit: f5a1d92b "staging: comedi: ni_stc.h: remove n_ni_boards macro" commit: 6293e357 "staging: comedi: ni_stc.h: remove boardtype macro" The n_ni_boards macro is an open coded version of ARRAY_SIZE. The boardtype macro is removed in favor of using the comedi_board() helper and accessing the boardinfo with a pointer. Fix both issues. Reported-by: kbuild test robot Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 2cc29965e157..279f2cd99cdc 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -350,7 +350,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev) struct pnp_dev *isapnp_dev = NULL; int i; - for (i = 0; i < n_ni_boards; i++) { + for (i = 0; i < ARRAY_SIZE(ni_boards); i++) { isapnp_dev = pnp_find_dev(NULL, ISAPNP_VENDOR('N', 'I', 'C'), ISAPNP_FUNCTION(ni_boards[i]. @@ -377,7 +377,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev) } break; } - if (i == n_ni_boards) + if (i == ARRAY_SIZE(ni_boards)) return -ENODEV; *dev = isapnp_dev; return 0; @@ -388,7 +388,7 @@ static int ni_getboardtype(struct comedi_device *dev) int device_id = ni_read_eeprom(dev, 511); int i; - for (i = 0; i < n_ni_boards; i++) { + for (i = 0; i < ARRAY_SIZE(ni_boards); i++) { if (ni_boards[i].device_id == device_id) return i; @@ -406,6 +406,7 @@ static int ni_getboardtype(struct comedi_device *dev) static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct ni_board_struct *boardtype; struct ni_private *devpriv; struct pnp_dev *isapnp_dev; int ret; @@ -466,9 +467,10 @@ static int ni_atmio_attach(struct comedi_device *dev, return -EIO; dev->board_ptr = ni_boards + board; + boardtype = comedi_board(dev) - printk(" %s", boardtype.name); - dev->board_name = boardtype.name; + printk(" %s", boardtype->name); + dev->board_name = boardtype->name; /* irq stuff */ -- cgit From d558c4733759e077cf449246983a5d1fe97fc434 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 8 Mar 2013 11:51:19 +0530 Subject: spi: slink-tegra20: move runtime pm calls to transfer_one_message The prepare_transfer_hardware() is called in atomic context and calling synchronous runtime pm calls can create scheduling deadlock. Therefore, in place of calling runtime PM calls from prepare/unprepare message transfer, calling this in transfer_one_message(). Signed-off-by: Laxman Dewangan Tested-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-tegra20-slink.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index b8698b389ef3..a829563f4713 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -858,21 +858,6 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } -static int tegra_slink_prepare_transfer(struct spi_master *master) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); - - return pm_runtime_get_sync(tspi->dev); -} - -static int tegra_slink_unprepare_transfer(struct spi_master *master) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); - - pm_runtime_put(tspi->dev); - return 0; -} - static int tegra_slink_transfer_one_message(struct spi_master *master, struct spi_message *msg) { @@ -885,6 +870,12 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, msg->status = 0; msg->actual_length = 0; + ret = pm_runtime_get_sync(tspi->dev); + if (ret < 0) { + dev_err(tspi->dev, "runtime get failed: %d\n", ret); + goto done; + } + single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { INIT_COMPLETION(tspi->xfer_completion); @@ -921,6 +912,8 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, exit: tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); + pm_runtime_put(tspi->dev); +done: msg->status = ret; spi_finalize_current_message(master); return ret; @@ -1148,9 +1141,7 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; - master->prepare_transfer_hardware = tegra_slink_prepare_transfer; master->transfer_one_message = tegra_slink_transfer_one_message; - master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; master->num_chipselect = MAX_CHIP_SELECT; master->bus_num = -1; -- cgit From 4a25b680b1e84cf97c740c8005e2c6655d6cfa7f Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 12 Mar 2013 00:13:36 +0100 Subject: spi/bcm63xx: Remove unused variable This fixes the following warning: drivers/spi/spi-bcm63xx.c: In function 'bcm63xx_spi_setup': drivers/spi/spi-bcm63xx.c:157:6: warning: unused variable 'ret' Signed-off-by: Kevin Cernekee Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 9578af782a77..0415a32cce33 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -152,7 +152,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { struct bcm63xx_spi *bs; - int ret; bs = spi_master_get_devdata(spi->master); -- cgit From b435ff212e91bddc2d12e6638a4d846d5f60daa6 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:37 +0100 Subject: spi/bcm63xx: don't disable non enabled clocks in probe error path When msg_ctl_width is set to an invalid value we try to disable the clock despite it never being enabled. Fix it by jumping to the correct label. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 0415a32cce33..d7df435d962e 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -489,7 +489,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) default: dev_err(dev, "unsupported MSG_CTL width: %d\n", bs->msg_ctl_width); - goto out_clk_disable; + goto out_err; } /* Initialize hardware */ -- cgit From 4fbb82a76db3ef0ec8f5d2e01e288b7821eff687 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:38 +0100 Subject: spi/bcm63xx: properly prepare clocks before enabling them Use proper clk_prepare/unprepare calls in preparation for switching to the generic clock framework. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index d7df435d962e..ef9b89fc2f32 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -493,7 +493,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) } /* Initialize hardware */ - clk_enable(bs->clk); + clk_prepare_enable(bs->clk); bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); /* register and we are done */ @@ -509,7 +509,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) return 0; out_clk_disable: - clk_disable(clk); + clk_disable_unprepare(clk); out_err: platform_set_drvdata(pdev, NULL); spi_master_put(master); @@ -530,7 +530,7 @@ static int bcm63xx_spi_remove(struct platform_device *pdev) bcm_spi_writeb(bs, 0, SPI_INT_MASK); /* HW shutdown */ - clk_disable(bs->clk); + clk_disable_unprepare(bs->clk); clk_put(bs->clk); platform_set_drvdata(pdev, 0); @@ -549,7 +549,7 @@ static int bcm63xx_spi_suspend(struct device *dev) spi_master_suspend(master); - clk_disable(bs->clk); + clk_disable_unprepare(bs->clk); return 0; } @@ -560,7 +560,7 @@ static int bcm63xx_spi_resume(struct device *dev) platform_get_drvdata(to_platform_device(dev)); struct bcm63xx_spi *bs = spi_master_get_devdata(master); - clk_enable(bs->clk); + clk_prepare_enable(bs->clk); spi_master_resume(master); -- cgit From ef9ed4b9c9de59eb3f2215b4773990159af92dc1 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:39 +0100 Subject: spi/bcm63xx: remove duplicated mode bits check The spi subsystem already checks the mode bits before calling setup. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ef9b89fc2f32..79ad8bce7032 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -158,12 +158,6 @@ static int bcm63xx_spi_setup(struct spi_device *spi) if (!spi->bits_per_word) spi->bits_per_word = 8; - if (spi->mode & ~MODEBITS) { - dev_err(&spi->dev, "%s, unsupported mode bits %x\n", - __func__, spi->mode & ~MODEBITS); - return -EINVAL; - } - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", __func__, spi->mode & MODEBITS, spi->bits_per_word, 0); -- cgit From c3db2b0b14b487430083209c040acc672a4945c4 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:40 +0100 Subject: spi/bcm63xx: remove unneeded debug message The spi subsystem already provides this info in a more extensive debug print except for the nsecs/bit - which wasn't calculated anyway and fixed to 0. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 79ad8bce7032..13806e31ece0 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -158,9 +158,6 @@ static int bcm63xx_spi_setup(struct spi_device *spi) if (!spi->bits_per_word) spi->bits_per_word = 8; - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", - __func__, spi->mode & MODEBITS, spi->bits_per_word, 0); - return 0; } -- cgit From 52f83bbd65c1178ac989e511943ecd6e0c5f8ad8 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:41 +0100 Subject: spi/bcm63xx: remove unused variable bs from bcm63xx_spi_setup It is only written, but never read. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 13806e31ece0..04c460e8bd27 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -151,10 +151,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { - struct bcm63xx_spi *bs; - - bs = spi_master_get_devdata(spi->master); - if (!spi->bits_per_word) spi->bits_per_word = 8; -- cgit From e2bdae06329ef3fb8918032735cd963efc701b7e Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:42 +0100 Subject: spi/bcm63xx: check spi bits_per_word in spi_setup Instead of fixing up the bits_per_word (which the spi subsystem already does for us), check it for supported values. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 04c460e8bd27..b64229ca7f54 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -151,8 +151,11 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { - if (!spi->bits_per_word) - spi->bits_per_word = 8; + if (spi->bits_per_word != 8) { + dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", + __func__, spi->bits_per_word); + return -EINVAL; + } return 0; } -- cgit From 58d8bebea57b519cb606a59dc1263556e8746119 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:43 +0100 Subject: spi/bcm63xx: simplify bcm63xx_spi_check_transfer bcm63xx_spi_check_transfer is only called from one place that has t always set, so directly check the transfer's bits_per_word. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index b64229ca7f54..b9c9431286e4 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -96,12 +96,9 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { static int bcm63xx_spi_check_transfer(struct spi_device *spi, struct spi_transfer *t) { - u8 bits_per_word; - - bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; - if (bits_per_word != 8) { + if (t->bits_per_word != 8) { dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", - __func__, bits_per_word); + __func__, t->bits_per_word); return -EINVAL; } -- cgit From 31e4eaaa54effd8544d1e8679e27d439bb6cb10c Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:44 +0100 Subject: spi/bcm63xx: remove spi chip select validity check The check would belong in bcm63xx_spi_setup if the spi subsystem weren't already doing the check for us, so just drop it. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index b9c9431286e4..9574e47e4ff4 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -102,12 +102,6 @@ static int bcm63xx_spi_check_transfer(struct spi_device *spi, return -EINVAL; } - if (spi->chip_select > spi->master->num_chipselect) { - dev_err(&spi->dev, "%s, unsupported slave %d\n", - __func__, spi->chip_select); - return -EINVAL; - } - return 0; } -- cgit From c94df49542a9cf2c095468e62be6a16ba86dd811 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:45 +0100 Subject: spi/bcm63xx: inline bcm63xx_spi_check_transfer It only does one check, so just do the check directly in the caller. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 9574e47e4ff4..d777f6311100 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -93,18 +93,6 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { { 391000, SPI_CLK_0_391MHZ } }; -static int bcm63xx_spi_check_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - if (t->bits_per_word != 8) { - dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", - __func__, t->bits_per_word); - return -EINVAL; - } - - return 0; -} - static void bcm63xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { @@ -293,9 +281,12 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master, * full-duplex transfers. */ list_for_each_entry(t, &m->transfers, transfer_list) { - status = bcm63xx_spi_check_transfer(spi, t); - if (status < 0) + if (t->bits_per_word != 8) { + dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", + __func__, t->bits_per_word); + status = -EINVAL; goto exit; + } if (!first) first = t; -- cgit From 68792e2a1989bf34a9498356c3e3cc70b9231df2 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:46 +0100 Subject: spi/bcm63xx: inline hz usage in bcm63xx_spi_setup_transfer bcm63xx_spi_setup_transfer is called from only one place, and that has t always set, to hz will always be t->speed_hz - just use it directly in the two places instead of moving it in a local variable. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index d777f6311100..2d64db4ac6a2 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -97,15 +97,12 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); - u32 hz; u8 clk_cfg, reg; int i; - hz = (t) ? t->speed_hz : spi->max_speed_hz; - /* Find the closest clock configuration */ for (i = 0; i < SPI_CLK_MASK; i++) { - if (hz >= bcm63xx_spi_freq_table[i][0]) { + if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) { clk_cfg = bcm63xx_spi_freq_table[i][1]; break; } @@ -122,7 +119,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, bcm_spi_writeb(bs, reg, SPI_CLK_CFG); dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", - clk_cfg, hz); + clk_cfg, t->speed_hz); } /* the spi->mode bits understood by this driver: */ -- cgit From b66c7730027509620ced3c7ebc84e28f623ebe9a Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:47 +0100 Subject: spi/bcm63xx: use devm_ioremap_resource() Use devm_ioremap_resource() which provides its own error messages. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 2d64db4ac6a2..973099bd760d 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -412,18 +412,9 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); bs->pdev = pdev; - if (!devm_request_mem_region(&pdev->dev, r->start, - resource_size(r), PFX)) { - dev_err(dev, "iomem request failed\n"); - ret = -ENXIO; - goto out_err; - } - - bs->regs = devm_ioremap_nocache(&pdev->dev, r->start, - resource_size(r)); - if (!bs->regs) { - dev_err(dev, "unable to ioremap regs\n"); - ret = -ENOMEM; + bs->regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(bs->regs)) { + ret = PTR_ERR(bs->regs); goto out_err; } -- cgit From 388f7bd24d2ffc945ad08be3a592672c1e32156e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Mar 2013 20:18:15 -0300 Subject: w1: mxc_w1: Convert to devm_ioremap_resource() According to Documentation/driver-model/devres.txt: devm_request_and_ioremap() : obsoleted by devm_ioremap_resource() Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/mxc_w1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 950d354d50e2..47e12cfc2a57 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -121,9 +121,9 @@ static int mxc_w1_probe(struct platform_device *pdev) mdev->clkdiv = (clk_get_rate(mdev->clk) / 1000000) - 1; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mdev->regs = devm_request_and_ioremap(&pdev->dev, res); - if (!mdev->regs) - return -EBUSY; + mdev->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mdev->regs)) + return PTR_ERR(mdev->regs); clk_prepare_enable(mdev->clk); __raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER); -- cgit From e86ac13b031cf71d8f40ff513e627aac80e6b765 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Mon, 11 Mar 2013 23:16:35 +0000 Subject: drivers: net: ethernet: cpsw: change cpts_active_slave to active_slave Change cpts_active_slave to active_slave so that the same DT property can be used to ethtool and SIOCGMIIPHY. CC: Richard Cochran Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/cpsw.txt | 7 ++++--- arch/arm/boot/dts/am33xx.dtsi | 2 +- drivers/net/ethernet/ti/cpsw.c | 10 +++++----- include/linux/platform_data/cpsw.h | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index 8e49c4200928..4f2ca6b4a182 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt @@ -15,7 +15,8 @@ Required properties: - mac_control : Specifies Default MAC control register content for the specific platform - slaves : Specifies number for slaves -- cpts_active_slave : Specifies the slave to use for time stamping +- active_slave : Specifies the slave to use for time stamping, + ethtool and SIOCGMIIPHY - cpts_clock_mult : Numerator to convert input clock ticks into nanoseconds - cpts_clock_shift : Denominator to convert input clock ticks into nanoseconds @@ -52,7 +53,7 @@ Examples: rx_descs = <64>; mac_control = <0x20>; slaves = <2>; - cpts_active_slave = <0>; + active_slave = <0>; cpts_clock_mult = <0x80000000>; cpts_clock_shift = <29>; cpsw_emac0: slave@0 { @@ -78,7 +79,7 @@ Examples: rx_descs = <64>; mac_control = <0x20>; slaves = <2>; - cpts_active_slave = <0>; + active_slave = <0>; cpts_clock_mult = <0x80000000>; cpts_clock_shift = <29>; cpsw_emac0: slave@0 { diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0957645b73af..91fe4f148f80 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -349,7 +349,7 @@ rx_descs = <64>; mac_control = <0x20>; slaves = <2>; - cpts_active_slave = <0>; + active_slave = <0>; cpts_clock_mult = <0x80000000>; cpts_clock_shift = <29>; reg = <0x4a100000 0x800 diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 01ffbc486982..98aa17a9516a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -942,7 +942,7 @@ static void cpsw_ndo_change_rx_flags(struct net_device *ndev, int flags) static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) { - struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave]; + struct cpsw_slave *slave = &priv->slaves[priv->data.active_slave]; u32 ts_en, seq_id; if (!priv->cpts->tx_enable && !priv->cpts->rx_enable) { @@ -971,7 +971,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) if (priv->data.dual_emac) slave = &priv->slaves[priv->emac_port]; else - slave = &priv->slaves[priv->data.cpts_active_slave]; + slave = &priv->slaves[priv->data.active_slave]; ctrl = slave_read(slave, CPSW2_CONTROL); ctrl &= ~CTRL_ALL_TS_MASK; @@ -1282,12 +1282,12 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } data->slaves = prop; - if (of_property_read_u32(node, "cpts_active_slave", &prop)) { - pr_err("Missing cpts_active_slave property in the DT.\n"); + if (of_property_read_u32(node, "active_slave", &prop)) { + pr_err("Missing active_slave property in the DT.\n"); ret = -EINVAL; goto error_ret; } - data->cpts_active_slave = prop; + data->active_slave = prop; if (of_property_read_u32(node, "cpts_clock_mult", &prop)) { pr_err("Missing cpts_clock_mult property in the DT.\n"); diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h index 798fb80b024b..bb3cd58d71e3 100644 --- a/include/linux/platform_data/cpsw.h +++ b/include/linux/platform_data/cpsw.h @@ -30,7 +30,7 @@ struct cpsw_platform_data { u32 channels; /* number of cpdma channels (symmetric) */ u32 slaves; /* number of slave cpgmac ports */ struct cpsw_slave_data *slave_data; - u32 cpts_active_slave; /* time stamping slave */ + u32 active_slave; /* time stamping, ethtool and SIOCGMIIPHY slave */ u32 cpts_clock_mult; /* convert input clock ticks to nanoseconds */ u32 cpts_clock_shift; /* convert input clock ticks to nanoseconds */ u32 ale_entries; /* ale table size */ -- cgit From d3bb9c58b567d240eaaa2dc8bd778696eaed5fbd Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Mon, 11 Mar 2013 23:16:36 +0000 Subject: driver: net: ethernet: cpsw: implement ethtool get/set phy setting This patch implements get/set of the phy settings via ethtool apis Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 98aa17a9516a..83ce890d6e97 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -139,6 +139,10 @@ do { \ disable_irq_nosync(priv->irqs_table[i]); \ } while (0); +#define cpsw_slave_index(priv) \ + ((priv->data.dual_emac) ? priv->emac_port : \ + priv->data.active_slave) + static int debug_level; module_param(debug_level, int, 0); MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)"); @@ -1244,12 +1248,37 @@ static int cpsw_get_ts_info(struct net_device *ndev, return 0; } +static int cpsw_get_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct cpsw_priv *priv = netdev_priv(ndev); + int slave_no = cpsw_slave_index(priv); + + if (priv->slaves[slave_no].phy) + return phy_ethtool_gset(priv->slaves[slave_no].phy, ecmd); + else + return -EOPNOTSUPP; +} + +static int cpsw_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) +{ + struct cpsw_priv *priv = netdev_priv(ndev); + int slave_no = cpsw_slave_index(priv); + + if (priv->slaves[slave_no].phy) + return phy_ethtool_sset(priv->slaves[slave_no].phy, ecmd); + else + return -EOPNOTSUPP; +} + static const struct ethtool_ops cpsw_ethtool_ops = { .get_drvinfo = cpsw_get_drvinfo, .get_msglevel = cpsw_get_msglevel, .set_msglevel = cpsw_set_msglevel, .get_link = ethtool_op_get_link, .get_ts_info = cpsw_get_ts_info, + .get_settings = cpsw_get_settings, + .set_settings = cpsw_set_settings, }; static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, -- cgit From ff5b8ef2ef3af0fd7e1cf6c8c1ed9ec5afbda422 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Mon, 11 Mar 2013 23:16:37 +0000 Subject: driver: net: ethernet: cpsw: implement interrupt pacing via ethtool This patch implements support for interrupt pacing block of CPSW via ethtool Inetrrupt pacing block is common of both the ethernet interface in dual emac mode Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 83ce890d6e97..d6cf6982904e 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -126,6 +126,13 @@ do { \ #define CPSW_FIFO_DUAL_MAC_MODE (1 << 15) #define CPSW_FIFO_RATE_LIMIT_MODE (2 << 15) +#define CPSW_INTPACEEN (0x3f << 16) +#define CPSW_INTPRESCALE_MASK (0x7FF << 0) +#define CPSW_CMINTMAX_CNT 63 +#define CPSW_CMINTMIN_CNT 2 +#define CPSW_CMINTMAX_INTVL (1000 / CPSW_CMINTMIN_CNT) +#define CPSW_CMINTMIN_INTVL ((1000 / CPSW_CMINTMAX_CNT) + 1) + #define cpsw_enable_irq(priv) \ do { \ u32 i; \ @@ -164,6 +171,15 @@ struct cpsw_wr_regs { u32 rx_en; u32 tx_en; u32 misc_en; + u32 mem_allign1[8]; + u32 rx_thresh_stat; + u32 rx_stat; + u32 tx_stat; + u32 misc_stat; + u32 mem_allign2[8]; + u32 rx_imax; + u32 tx_imax; + }; struct cpsw_ss_regs { @@ -318,6 +334,8 @@ struct cpsw_priv { struct cpsw_host_regs __iomem *host_port_regs; u32 msg_enable; u32 version; + u32 coal_intvl; + u32 bus_freq_mhz; struct net_device_stats stats; int rx_packet_max; int host_port; @@ -616,6 +634,77 @@ static void cpsw_adjust_link(struct net_device *ndev) } } +static int cpsw_get_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct cpsw_priv *priv = netdev_priv(ndev); + + coal->rx_coalesce_usecs = priv->coal_intvl; + return 0; +} + +static int cpsw_set_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct cpsw_priv *priv = netdev_priv(ndev); + u32 int_ctrl; + u32 num_interrupts = 0; + u32 prescale = 0; + u32 addnl_dvdr = 1; + u32 coal_intvl = 0; + + if (!coal->rx_coalesce_usecs) + return -EINVAL; + + coal_intvl = coal->rx_coalesce_usecs; + + int_ctrl = readl(&priv->wr_regs->int_control); + prescale = priv->bus_freq_mhz * 4; + + if (coal_intvl < CPSW_CMINTMIN_INTVL) + coal_intvl = CPSW_CMINTMIN_INTVL; + + if (coal_intvl > CPSW_CMINTMAX_INTVL) { + /* Interrupt pacer works with 4us Pulse, we can + * throttle further by dilating the 4us pulse. + */ + addnl_dvdr = CPSW_INTPRESCALE_MASK / prescale; + + if (addnl_dvdr > 1) { + prescale *= addnl_dvdr; + if (coal_intvl > (CPSW_CMINTMAX_INTVL * addnl_dvdr)) + coal_intvl = (CPSW_CMINTMAX_INTVL + * addnl_dvdr); + } else { + addnl_dvdr = 1; + coal_intvl = CPSW_CMINTMAX_INTVL; + } + } + + num_interrupts = (1000 * addnl_dvdr) / coal_intvl; + writel(num_interrupts, &priv->wr_regs->rx_imax); + writel(num_interrupts, &priv->wr_regs->tx_imax); + + int_ctrl |= CPSW_INTPACEEN; + int_ctrl &= (~CPSW_INTPRESCALE_MASK); + int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK); + writel(int_ctrl, &priv->wr_regs->int_control); + + cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl); + if (priv->data.dual_emac) { + int i; + + for (i = 0; i < priv->data.slaves; i++) { + priv = netdev_priv(priv->slaves[i].ndev); + priv->coal_intvl = coal_intvl; + } + } else { + priv->coal_intvl = coal_intvl; + } + + return 0; +} + static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val) { static char *leader = "........................................"; @@ -838,6 +927,14 @@ static int cpsw_ndo_open(struct net_device *ndev) cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); } + /* Enable Interrupt pacing if configured */ + if (priv->coal_intvl != 0) { + struct ethtool_coalesce coal; + + coal.rx_coalesce_usecs = (priv->coal_intvl << 4); + cpsw_set_coalesce(ndev, &coal); + } + cpdma_ctlr_start(priv->dma); cpsw_intr_enable(priv); napi_enable(&priv->napi); @@ -1279,6 +1376,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = { .get_ts_info = cpsw_get_ts_info, .get_settings = cpsw_get_settings, .set_settings = cpsw_set_settings, + .get_coalesce = cpsw_get_coalesce, + .set_coalesce = cpsw_set_coalesce, }; static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, @@ -1466,6 +1565,9 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, priv_sl2->slaves = priv->slaves; priv_sl2->clk = priv->clk; + priv_sl2->coal_intvl = 0; + priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; + priv_sl2->cpsw_res = priv->cpsw_res; priv_sl2->regs = priv->regs; priv_sl2->host_port = priv->host_port; @@ -1575,6 +1677,8 @@ static int cpsw_probe(struct platform_device *pdev) ret = -ENODEV; goto clean_slave_ret; } + priv->coal_intvl = 0; + priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000; priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!priv->cpsw_res) { -- cgit From 11f2c988382b880e602a005c26436043c5d2c274 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Mon, 11 Mar 2013 23:16:38 +0000 Subject: drivers: net: ethernet: cpsw: implement get phy_id via ioctl Implement get phy_id via ioctl SIOCGMIIPHY. In switch mode active phy_id is returned and in dual EMAC mode slave's specific phy_id is returned. Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index d6cf6982904e..8ff1d3dde778 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1157,14 +1157,26 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { + struct cpsw_priv *priv = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(req); + int slave_no = cpsw_slave_index(priv); + if (!netif_running(dev)) return -EINVAL; + switch (cmd) { #ifdef CONFIG_TI_CPTS - if (cmd == SIOCSHWTSTAMP) + case SIOCSHWTSTAMP: return cpsw_hwtstamp_ioctl(dev, req); #endif - return -ENOTSUPP; + case SIOCGMIIPHY: + data->phy_id = priv->slaves[slave_no].phy->addr; + break; + default: + return -ENOTSUPP; + } + + return 0; } static void cpsw_ndo_tx_timeout(struct net_device *ndev) -- cgit From a520030e326a1267fba6babe685ad574174bde27 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 12 Mar 2013 09:02:16 +0000 Subject: qlcnic: Implement flash sysfs callback for 83xx adapter QLogic applications use these callbacks to perform o NIC Partitioning (NPAR) configuration and management o Diagnostic tests o Flash access and updates Signed-off-by: Himanshu Madhani Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 12 +- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 8 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 253 +++++++++++++++++++++ 3 files changed, 265 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index c08fa20dd5f0..56c3676bdbfe 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -2272,7 +2272,7 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter) return 0; } -static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter) +int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter) { int ret; u32 cmd; @@ -2290,7 +2290,7 @@ static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter) return 0; } -static int qlcnic_83xx_disable_flash_write_op(struct qlcnic_adapter *adapter) +int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter) { int ret; @@ -2364,7 +2364,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter, return -EIO; if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { - ret = qlcnic_83xx_enable_flash_write_op(adapter); + ret = qlcnic_83xx_enable_flash_write(adapter); if (ret) { qlcnic_83xx_unlock_flash(adapter); dev_err(&adapter->pdev->dev, @@ -2406,7 +2406,7 @@ int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter, } if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { - ret = qlcnic_83xx_disable_flash_write_op(adapter); + ret = qlcnic_83xx_disable_flash_write(adapter); if (ret) { qlcnic_83xx_unlock_flash(adapter); dev_err(&adapter->pdev->dev, @@ -2446,8 +2446,8 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr, u32 temp; int ret = -EIO; - if ((count < QLC_83XX_FLASH_BULK_WRITE_MIN) || - (count > QLC_83XX_FLASH_BULK_WRITE_MAX)) { + if ((count < QLC_83XX_FLASH_WRITE_MIN) || + (count > QLC_83XX_FLASH_WRITE_MAX)) { dev_err(&adapter->pdev->dev, "%s: Invalid word count\n", __func__); return -EIO; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 648a73f904ee..fbb3d1d9e55c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -12,6 +12,8 @@ #include #include "qlcnic_hw.h" +#define QLCNIC_83XX_BAR0_LENGTH 0x4000 + /* Directly mapped registers */ #define QLC_83XX_CRB_WIN_BASE 0x3800 #define QLC_83XX_CRB_WIN_FUNC(f) (QLC_83XX_CRB_WIN_BASE+((f)*4)) @@ -257,8 +259,8 @@ struct qlc_83xx_idc { #define QLC_83XX_FLASH_BULK_WRITE_CMD 0xcadcadca #define QLC_83XX_FLASH_READ_RETRY_COUNT 5000 #define QLC_83XX_FLASH_STATUS_READY 0x6 -#define QLC_83XX_FLASH_BULK_WRITE_MIN 2 -#define QLC_83XX_FLASH_BULK_WRITE_MAX 64 +#define QLC_83XX_FLASH_WRITE_MIN 2 +#define QLC_83XX_FLASH_WRITE_MAX 64 #define QLC_83XX_FLASH_STATUS_REG_POLL_DELAY 1 #define QLC_83XX_ERASE_MODE 1 #define QLC_83XX_WRITE_MODE 2 @@ -451,4 +453,6 @@ int qlcnic_83xx_loopback_test(struct net_device *, u8); int qlcnic_83xx_interrupt_test(struct net_device *); int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state); int qlcnic_83xx_flash_test(struct qlcnic_adapter *); +int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); +int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); #endif diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 4e464dcfcb3f..c77675da671f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -884,6 +884,244 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, return size; } +static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t offset, + size_t size) +{ + unsigned char *p_read_buf; + int ret, count; + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + + if (!size) + return QL_STATUS_INVALID_PARAM; + if (!buf) + return QL_STATUS_INVALID_PARAM; + + count = size / sizeof(u32); + + if (size % sizeof(u32)) + count++; + + p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL); + if (!p_read_buf) + return -ENOMEM; + if (qlcnic_83xx_lock_flash(adapter) != 0) { + kfree(p_read_buf); + return -EIO; + } + + ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf, + count); + + if (ret) { + qlcnic_83xx_unlock_flash(adapter); + kfree(p_read_buf); + return ret; + } + + qlcnic_83xx_unlock_flash(adapter); + memcpy(buf, p_read_buf, size); + kfree(p_read_buf); + + return size; +} + +static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter, + char *buf, loff_t offset, + size_t size) +{ + int i, ret, count; + unsigned char *p_cache, *p_src; + + p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL); + if (!p_cache) + return -ENOMEM; + + memcpy(p_cache, buf, size); + p_src = p_cache; + count = size / sizeof(u32); + + if (qlcnic_83xx_lock_flash(adapter) != 0) { + kfree(p_cache); + return -EIO; + } + + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_enable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + + for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) { + ret = qlcnic_83xx_flash_bulk_write(adapter, offset, + (u32 *)p_src, + QLC_83XX_FLASH_WRITE_MAX); + + if (ret) { + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_disable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + + p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX; + offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX; + } + + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_disable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + + return 0; +} + +static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter, + char *buf, loff_t offset, size_t size) +{ + int i, ret, count; + unsigned char *p_cache, *p_src; + + p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL); + if (!p_cache) + return -ENOMEM; + + memcpy(p_cache, buf, size); + p_src = p_cache; + count = size / sizeof(u32); + + if (qlcnic_83xx_lock_flash(adapter) != 0) { + kfree(p_cache); + return -EIO; + } + + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_enable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + + for (i = 0; i < count; i++) { + ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src); + if (ret) { + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_disable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + + p_src = p_src + sizeof(u32); + offset = offset + sizeof(u32); + } + + if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) { + ret = qlcnic_83xx_disable_flash_write(adapter); + if (ret) { + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + return -EIO; + } + } + + kfree(p_cache); + qlcnic_83xx_unlock_flash(adapter); + + return 0; +} + +static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t offset, + size_t size) +{ + int ret; + static int flash_mode; + unsigned long data; + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + + if (!buf) + return QL_STATUS_INVALID_PARAM; + + ret = kstrtoul(buf, 16, &data); + + switch (data) { + case QLC_83XX_FLASH_SECTOR_ERASE_CMD: + flash_mode = QLC_83XX_ERASE_MODE; + ret = qlcnic_83xx_erase_flash_sector(adapter, offset); + if (ret) { + dev_err(&adapter->pdev->dev, + "%s failed at %d\n", __func__, __LINE__); + return -EIO; + } + break; + + case QLC_83XX_FLASH_BULK_WRITE_CMD: + flash_mode = QLC_83XX_BULK_WRITE_MODE; + break; + + case QLC_83XX_FLASH_WRITE_CMD: + flash_mode = QLC_83XX_WRITE_MODE; + break; + default: + if (flash_mode == QLC_83XX_BULK_WRITE_MODE) { + ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf, + offset, size); + if (ret) { + dev_err(&adapter->pdev->dev, + "%s failed at %d\n", + __func__, __LINE__); + return -EIO; + } + } + + if (flash_mode == QLC_83XX_WRITE_MODE) { + ret = qlcnic_83xx_sysfs_flash_write(adapter, buf, + offset, size); + if (ret) { + dev_err(&adapter->pdev->dev, + "%s failed at %d\n", __func__, + __LINE__); + return -EIO; + } + } + } + + return size; +} + static struct device_attribute dev_attr_bridged_mode = { .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)}, .show = qlcnic_show_bridged_mode, @@ -958,6 +1196,13 @@ static struct bin_attribute bin_attr_pm_config = { .write = qlcnic_sysfs_write_pm_config, }; +static struct bin_attribute bin_attr_flash = { + .attr = {.name = "flash", .mode = (S_IRUGO | S_IWUSR)}, + .size = 0, + .read = qlcnic_83xx_sysfs_flash_read_handler, + .write = qlcnic_83xx_sysfs_flash_write_handler, +}; + void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; @@ -1046,10 +1291,18 @@ void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter) void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter) { + struct device *dev = &adapter->pdev->dev; + qlcnic_create_diag_entries(adapter); + + if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash)) + dev_info(dev, "failed to create flash sysfs entry\n"); } void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter) { + struct device *dev = &adapter->pdev->dev; + qlcnic_remove_diag_entries(adapter); + sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash); } -- cgit From 7f02d1601cf05ce79fde78cb9b9bc2e375f87126 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Tue, 12 Mar 2013 09:02:17 +0000 Subject: qlcnic: Bump up the version to 5.1.37 Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index c8b489516008..157779955885 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -38,8 +38,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 1 -#define _QLCNIC_LINUX_SUBVERSION 36 -#define QLCNIC_LINUX_VERSIONID "5.1.36" +#define _QLCNIC_LINUX_SUBVERSION 37 +#define QLCNIC_LINUX_VERSIONID "5.1.37" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit From 557b7d5d0787997247a798e6f46541fe9dc977fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:56 +0100 Subject: ARM: at91/avr32/atmel_lcdfb: add bus-clock entry Add hclk entry for the atmel_lcdfb bus clock. On at91sam9261, at91sam9g10 and at32ap the bus clock has to be enabled as well as the peripheral clock. Add the appropriate lookup entries to these SOCs and fake clocks to the SOCs that do not use it. This allows us to get rid of the conditional enabling of the clocks in the driver which relied on the cpu_is macros. Tested on at91sam9263 and at91sam9g45, compile-tested for other AT91-SOCs, and untested for AVR32. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91sam9261.c | 1 + arch/arm/mach-at91/at91sam9263.c | 1 + arch/arm/mach-at91/at91sam9g45.c | 1 + arch/arm/mach-at91/at91sam9rl.c | 1 + arch/avr32/mach-at32ap/at32ap700x.c | 4 ++-- drivers/video/atmel_lcdfb.c | 23 ++++++++--------------- 6 files changed, 14 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 2998a08afc2d..5838f12e6698 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -169,6 +169,7 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &hck1), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index b9fc60d1b33a..520a63d31329 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -190,6 +190,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), + CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index d3addee43d8d..ea6b62bcbe77 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -228,6 +228,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index eb98704db2d9..4cd4fa985d0d 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -179,6 +179,7 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index b323d8d3185b..cd25b01b5848 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1453,7 +1453,7 @@ static struct resource atmel_lcdfb0_resource[] = { }, }; DEFINE_DEV_DATA(atmel_lcdfb, 0); -DEV_CLK(hck1, atmel_lcdfb0, hsb, 7); +DEV_CLK(hclk, atmel_lcdfb0, hsb, 7); static struct clk atmel_lcdfb0_pixclk = { .name = "lcdc_clk", .dev = &atmel_lcdfb0_device.dev, @@ -2246,7 +2246,7 @@ static __initdata struct clk *init_clocks[] = { &atmel_twi0_pclk, &atmel_mci0_pclk, #if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) - &atmel_lcdfb0_hck1, + &atmel_lcdfb0_hclk, &atmel_lcdfb0_pixclk, #endif &ssc0_pclk, diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 025428e04c33..c5883cafa38a 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -821,15 +821,13 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_enable(sinfo->bus_clk); + clk_enable(sinfo->bus_clk); clk_enable(sinfo->lcdc_clk); } static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_disable(sinfo->bus_clk); + clk_disable(sinfo->bus_clk); clk_disable(sinfo->lcdc_clk); } @@ -888,13 +886,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) info->fix = atmel_lcdfb_fix; /* Enable LCDC Clocks */ - if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000()) { - sinfo->bus_clk = clk_get(dev, "hck1"); - if (IS_ERR(sinfo->bus_clk)) { - ret = PTR_ERR(sinfo->bus_clk); - goto free_info; - } + sinfo->bus_clk = clk_get(dev, "hclk"); + if (IS_ERR(sinfo->bus_clk)) { + ret = PTR_ERR(sinfo->bus_clk); + goto free_info; } sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); if (IS_ERR(sinfo->lcdc_clk)) { @@ -1055,8 +1050,7 @@ stop_clk: atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); put_bus_clk: - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); free_info: framebuffer_release(info); out: @@ -1081,8 +1075,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) unregister_framebuffer(info); atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); fb_dealloc_cmap(&info->cmap); free_irq(sinfo->irq_base, info); iounmap(sinfo->mmio); -- cgit From 934a50bd089789d1ed74f0bef4988a97bd590afe Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:57 +0100 Subject: atmel_lcdfb: move lcdcon2 register access to compute_hozval Pass atmel_lcd_info structure to compute_hozval and only do the register access on SOCs that actually use it. This will also simplify the removal of the cpu_is macros. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- drivers/video/atmel_lcdfb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c5883cafa38a..2effd35da589 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -193,14 +193,17 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { .accel = FB_ACCEL_NONE, }; -static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) +static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo, + unsigned long xres) { + unsigned long lcdcon2; unsigned long value; if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() || cpu_is_at32ap7000())) return xres; + lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2); value = xres; if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { /* STN display */ @@ -591,8 +594,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); /* Horizontal value (aka line size) */ - hozval_linesz = compute_hozval(info->var.xres, - lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2)); + hozval_linesz = compute_hozval(sinfo, info->var.xres); /* Display size */ value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; -- cgit From bbd44f6bd9d1aa735b180b29b5719d63a8e87b55 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:58 +0100 Subject: ARM: at91/avr32/atmel_lcdfb: add platform device-id table Add platform device-id table in order to identify the controller and determine its configuration. The currently used configuration parameters are: have_alt_pixclock - SOC uses an alternate pixel-clock calculation formula (at91sam9g45 non-ES) have_hozval - SOC has a HOZVAL field in LCDFRMCFG which is used to determine the linesize for STN displays (at91sam9261, at921sam9g10 and at32ap) have_intensity_bit - SOC uses IBGR:555 rather than BGR:565 16-bit pixel layout (at91sam9261, at91sam9263 and at91sam9rl) This allows us to remove all the remaining uses of cpu_is macros from the driver. Tested on at91sam9263 and at91sam9g45, compile-tested for other AT91-SOCs, and untested for AVR32. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91sam9261.c | 3 +- arch/arm/mach-at91/at91sam9261_devices.c | 6 ++- arch/arm/mach-at91/at91sam9263.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- arch/arm/mach-at91/at91sam9g45.c | 3 +- arch/arm/mach-at91/at91sam9g45_devices.c | 6 ++- arch/arm/mach-at91/at91sam9rl.c | 2 +- arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- arch/avr32/mach-at32ap/at32ap700x.c | 2 + drivers/video/atmel_lcdfb.c | 89 ++++++++++++++++++++++++++++---- include/video/atmel_lcdc.h | 4 +- 11 files changed, 102 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 5838f12e6698..0204f4cc9ebf 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -169,7 +169,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &hck1), + CLKDEV_CON_DEV_ID("hclk", "at91sam9261-lcdfb.0", &hck1), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g10-lcdfb.0", &hck1), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 92e0f861084a..629ea5fc95cf 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -488,7 +488,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -505,6 +504,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) return; } + if (cpu_is_at91sam9g10()) + at91_lcdc_device.name = "at91sam9g10-lcdfb"; + else + at91_lcdc_device.name = "at91sam9261-lcdfb"; + #if defined(CONFIG_FB_ATMEL_STN) at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 520a63d31329..2282fd7ad3e3 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -190,7 +190,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9263-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ed666f5cb01d..858c8aac2daf 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -848,7 +848,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9263-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index ea6b62bcbe77..c68960d82247 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -228,7 +228,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45-lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45es-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 827c9f2a70fb..fe626d431b69 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -981,7 +981,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -997,6 +996,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) if (!data) return; + if (cpu_is_at91sam9g45es()) + at91_lcdc_device.name = "at91sam9g45es-lcdfb"; + else + at91_lcdc_device.name = "at91sam9g45-lcdfb"; + at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 4cd4fa985d0d..3de3e04d0f81 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -179,7 +179,7 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("hclk", "atmel_lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9rl-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index ddf223ff35c4..352468f265a9 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -514,7 +514,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9rl-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index cd25b01b5848..7c2f6685bf43 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1530,6 +1530,8 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, memcpy(info, data, sizeof(struct atmel_lcdfb_info)); info->default_monspecs = monspecs; + pdev->name = "at32ap-lcdfb"; + platform_device_register(pdev); return pdev; diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 2effd35da589..c1a2914447e1 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -34,6 +34,77 @@ #define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ #define ATMEL_LCDC_FIFO_SIZE 512 /* words */ +struct atmel_lcdfb_config { + bool have_alt_pixclock; + bool have_hozval; + bool have_intensity_bit; +}; + +static struct atmel_lcdfb_config at91sam9261_config = { + .have_hozval = true, + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9263_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9g10_config = { + .have_hozval = true, +}; + +static struct atmel_lcdfb_config at91sam9g45_config = { + .have_alt_pixclock = true, +}; + +static struct atmel_lcdfb_config at91sam9g45es_config = { +}; + +static struct atmel_lcdfb_config at91sam9rl_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at32ap_config = { + .have_hozval = true, +}; + +static const struct platform_device_id atmel_lcdfb_devtypes[] = { + { + .name = "at91sam9261-lcdfb", + .driver_data = (unsigned long)&at91sam9261_config, + }, { + .name = "at91sam9263-lcdfb", + .driver_data = (unsigned long)&at91sam9263_config, + }, { + .name = "at91sam9g10-lcdfb", + .driver_data = (unsigned long)&at91sam9g10_config, + }, { + .name = "at91sam9g45-lcdfb", + .driver_data = (unsigned long)&at91sam9g45_config, + }, { + .name = "at91sam9g45es-lcdfb", + .driver_data = (unsigned long)&at91sam9g45es_config, + }, { + .name = "at91sam9rl-lcdfb", + .driver_data = (unsigned long)&at91sam9rl_config, + }, { + .name = "at32ap-lcdfb", + .driver_data = (unsigned long)&at32ap_config, + }, { + /* terminator */ + } +}; + +static struct atmel_lcdfb_config * +atmel_lcdfb_get_config(struct platform_device *pdev) +{ + unsigned long data; + + data = platform_get_device_id(pdev)->driver_data; + + return (struct atmel_lcdfb_config *)data; +} + #if defined(CONFIG_ARCH_AT91) #define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ | FBINFO_PARTIAL_PAN_OK \ @@ -199,8 +270,7 @@ static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo, unsigned long lcdcon2; unsigned long value; - if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000())) + if (!sinfo->config->have_hozval) return xres; lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2); @@ -426,7 +496,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, break; case 16: /* Older SOCs use IBGR:555 rather than BGR:565. */ - if (sinfo->have_intensity_bit) + if (sinfo->config->have_intensity_bit) var->green.length = 5; else var->green.length = 6; @@ -534,7 +604,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) /* Now, the LCDC core... */ /* Set pixel clock */ - if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) + if (sinfo->config->have_alt_pixclock) pix_factor = 1; clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; @@ -686,7 +756,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - if (sinfo->have_intensity_bit) { + if (sinfo->config->have_intensity_bit) { /* old style I+BGR:555 */ val = ((red >> 11) & 0x001f); val |= ((green >> 6) & 0x03e0); @@ -874,10 +944,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) } sinfo->info = info; sinfo->pdev = pdev; - if (cpu_is_at91sam9261() || cpu_is_at91sam9263() || - cpu_is_at91sam9rl()) { - sinfo->have_intensity_bit = true; - } + sinfo->config = atmel_lcdfb_get_config(pdev); + if (!sinfo->config) + goto free_info; strcpy(info->fix.id, sinfo->pdev->name); info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; @@ -1146,7 +1215,7 @@ static struct platform_driver atmel_lcdfb_driver = { .remove = __exit_p(atmel_lcdfb_remove), .suspend = atmel_lcdfb_suspend, .resume = atmel_lcdfb_resume, - + .id_table = atmel_lcdfb_devtypes, .driver = { .name = "atmel_lcdfb", .owner = THIS_MODULE, diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h index 8deb22672ada..0f5a2fc69af9 100644 --- a/include/video/atmel_lcdc.h +++ b/include/video/atmel_lcdc.h @@ -31,6 +31,7 @@ #define ATMEL_LCDC_WIRING_BGR 0 #define ATMEL_LCDC_WIRING_RGB 1 +struct atmel_lcdfb_config; /* LCD Controller info data structure, stored in device platform_data */ struct atmel_lcdfb_info { @@ -61,7 +62,8 @@ struct atmel_lcdfb_info { void (*atmel_lcdfb_power_control)(int on); struct fb_monspecs *default_monspecs; u32 pseudo_palette[16]; - bool have_intensity_bit; + + struct atmel_lcdfb_config *config; }; #define ATMEL_LCDC_DMABADDR1 0x00 -- cgit From a42277c739c29b06cb27502347f557e11fed8b0e Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 12 Mar 2013 17:26:49 +0000 Subject: regmap: rbtree Expose total memory consumption in the rbtree debugfs entry Provide a feel of how much overhead the rbtree cache adds to the game. [Slightly reworded output in debugfs -- broonie] Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- drivers/base/regmap/regcache-rbtree.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 461cff888bb1..045319615608 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -138,15 +138,20 @@ static int rbtree_show(struct seq_file *s, void *ignored) struct regcache_rbtree_node *n; struct rb_node *node; unsigned int base, top; + size_t mem_size; int nodes = 0; int registers = 0; int this_registers, average; map->lock(map); + mem_size = sizeof(*rbtree_ctx); + for (node = rb_first(&rbtree_ctx->root); node != NULL; node = rb_next(node)) { n = container_of(node, struct regcache_rbtree_node, node); + mem_size += sizeof(*n); + mem_size += (n->blklen * map->cache_word_size); regcache_rbtree_get_base_top_reg(map, n, &base, &top); this_registers = ((top - base) / map->reg_stride) + 1; @@ -161,8 +166,8 @@ static int rbtree_show(struct seq_file *s, void *ignored) else average = 0; - seq_printf(s, "%d nodes, %d registers, average %d registers\n", - nodes, registers, average); + seq_printf(s, "%d nodes, %d registers, average %d registers, used %zu bytes\n", + nodes, registers, average, mem_size); map->unlock(map); -- cgit From 5104a03d7d0ef4b0222155f2fa6902bf727b1005 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:07 +0900 Subject: firewire net: No need to reset dev->local_fifo after failure of fw_core_add_address_handler(). fwnet_broadcast_start() try to register address handler at first if it was not registered yet; dev->local_fifo == FWNET_NO_FIFO_ADDR. Since dev->local_info not changed if fw_core_add_address_hander() has failed, we do not need to set dev->local_info to FWNET_NO_FIFO_ADDR. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 2b27bff2591a..a7a0e8277147 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1220,8 +1220,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) dev->broadcast_rcv_context = NULL; failed_context_create: fw_core_remove_address_handler(&dev->handler); - failed_initial: dev->local_fifo = FWNET_NO_FIFO_ADDR; + failed_initial: return retval; } -- cgit From 9d39c90abc6766f875d2855a1a73c43b6ffa09c0 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:26 +0900 Subject: firewire net: Introduce fwnet_fifo_{start, stop}() helpers. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 51 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index a7a0e8277147..96f6ee5bffd4 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1116,6 +1116,36 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) return 0; } +static void fwnet_fifo_stop(struct fwnet_device *dev) +{ + if (dev->local_fifo == FWNET_NO_FIFO_ADDR) + return; + + fw_core_remove_address_handler(&dev->handler); + dev->local_fifo = FWNET_NO_FIFO_ADDR; +} + +static int fwnet_fifo_start(struct fwnet_device *dev) +{ + int retval; + + if (dev->local_fifo != FWNET_NO_FIFO_ADDR) + return 0; + + dev->handler.length = 4096; + dev->handler.address_callback = fwnet_receive_packet; + dev->handler.callback_data = dev; + + retval = fw_core_add_address_handler(&dev->handler, + &fw_high_memory_region); + if (retval < 0) + return retval; + + dev->local_fifo = dev->handler.offset; + + return 0; +} + static int fwnet_broadcast_start(struct fwnet_device *dev) { struct fw_iso_context *context; @@ -1126,18 +1156,9 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; - if (dev->local_fifo == FWNET_NO_FIFO_ADDR) { - dev->handler.length = 4096; - dev->handler.address_callback = fwnet_receive_packet; - dev->handler.callback_data = dev; - - retval = fw_core_add_address_handler(&dev->handler, - &fw_high_memory_region); - if (retval < 0) - goto failed_initial; - - dev->local_fifo = dev->handler.offset; - } + retval = fwnet_fifo_start(dev); + if (retval < 0) + goto failed_initial; max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1219,8 +1240,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: - fw_core_remove_address_handler(&dev->handler); - dev->local_fifo = FWNET_NO_FIFO_ADDR; + fwnet_fifo_stop(dev); failed_initial: return retval; @@ -1600,8 +1620,7 @@ static int fwnet_remove(struct device *_dev) if (list_empty(&dev->peer_list)) { unregister_netdev(net); - if (dev->local_fifo != FWNET_NO_FIFO_ADDR) - fw_core_remove_address_handler(&dev->handler); + fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, -- cgit From b9a8871ac2aab0cc87190f1ab870785b32cc24aa Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:38 +0900 Subject: firewire net: Setup broadcast and local fifo independently. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 96f6ee5bffd4..fbd07ebd3f5f 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1156,10 +1156,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; - retval = fwnet_fifo_start(dev); - if (retval < 0) - goto failed_initial; - max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1240,8 +1236,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: - fwnet_fifo_stop(dev); - failed_initial: return retval; } @@ -1260,10 +1254,14 @@ static int fwnet_open(struct net_device *net) struct fwnet_device *dev = netdev_priv(net); int ret; + ret = fwnet_fifo_start(dev); + if (ret) + return ret; + if (dev->broadcast_state == FWNET_BROADCAST_ERROR) { ret = fwnet_broadcast_start(dev); if (ret) - return ret; + goto out; } netif_start_queue(net); @@ -1272,6 +1270,9 @@ static int fwnet_open(struct net_device *net) spin_unlock_irq(&dev->lock); return 0; +out: + fwnet_fifo_stop(dev); + return ret; } /* ifdown */ -- cgit From 2fbd8dfee1dc50407eaf72e30333cf8ce1bba2cb Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:14 +0900 Subject: firewire net: Check dev->broadcast_state inside fwnet_broadcast_start(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index fbd07ebd3f5f..9a2634ad6426 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1156,6 +1156,9 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; + if (dev->broadcast_state != FWNET_BROADCAST_ERROR) + return 0; + max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1258,11 +1261,10 @@ static int fwnet_open(struct net_device *net) if (ret) return ret; - if (dev->broadcast_state == FWNET_BROADCAST_ERROR) { - ret = fwnet_broadcast_start(dev); - if (ret) - goto out; - } + ret = fwnet_broadcast_start(dev); + if (ret) + goto out; + netif_start_queue(net); spin_lock_irq(&dev->lock); -- cgit From 48a8406f5bd5cb49e1c03777ed19638de2628882 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:50 +0900 Subject: firewire net: Fix memory leakage in fwnet_remove(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 9a2634ad6426..d9b2105f22a0 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1626,6 +1626,8 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); -- cgit From f60bac4bc9f8c6b20b27a2be210a69e2f256f0a5 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:59 +0900 Subject: firewire net: Clear dev->broadcast_rcv_context and dev->broadcast_state after destruction of context. Clear dev->broadcast_rcv_context to NULL and set dev->broadcast_state to FWNET_BROADCAST_ERROR after descruction of broadcast context. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index d9b2105f22a0..efed4a65fb06 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1626,11 +1626,14 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); + kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); + dev->broadcast_rcv_context = NULL; + dev->broadcast_state = FWNET_BROADCAST_ERROR; } for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); -- cgit From f2090594dd28c033e0a9a267240ffca6d5afbd84 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:25 +0900 Subject: firewire net: Omit checking dev->broadcast_rcv_context in fwnet_broadcast_start(). dev->broadcast_rcv_context is always non-NULL if dev->broadcast_state is not FWNET_BROADCAST_ERROR. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 57 +++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index efed4a65fb06..d8cb6ac31044 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1154,6 +1154,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned max_receive; struct fw_iso_packet packet; unsigned long offset; + void **ptrptr; unsigned u; if (dev->broadcast_state != FWNET_BROADCAST_ERROR) @@ -1162,42 +1163,36 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; - if (!dev->broadcast_rcv_context) { - void **ptrptr; - - context = fw_iso_context_create(dev->card, - FW_ISO_CONTEXT_RECEIVE, IEEE1394_BROADCAST_CHANNEL, - dev->card->link_speed, 8, fwnet_receive_broadcast, dev); - if (IS_ERR(context)) { - retval = PTR_ERR(context); - goto failed_context_create; - } + context = fw_iso_context_create(dev->card, FW_ISO_CONTEXT_RECEIVE, + IEEE1394_BROADCAST_CHANNEL, + dev->card->link_speed, 8, + fwnet_receive_broadcast, dev); + if (IS_ERR(context)) { + retval = PTR_ERR(context); + goto failed_context_create; + } - retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, - dev->card, FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); - if (retval < 0) - goto failed_buffer_init; + retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, + FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); + if (retval < 0) + goto failed_buffer_init; - ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); - if (!ptrptr) { - retval = -ENOMEM; - goto failed_ptrs_alloc; - } + ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); + if (!ptrptr) { + retval = -ENOMEM; + goto failed_ptrs_alloc; + } - dev->broadcast_rcv_buffer_ptrs = ptrptr; - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { - void *ptr; - unsigned v; + dev->broadcast_rcv_buffer_ptrs = ptrptr; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { + void *ptr; + unsigned v; - ptr = kmap(dev->broadcast_rcv_buffer.pages[u]); - for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++) - *ptrptr++ = (void *) - ((char *)ptr + v * max_receive); - } - dev->broadcast_rcv_context = context; - } else { - context = dev->broadcast_rcv_context; + ptr = kmap(dev->broadcast_rcv_buffer.pages[u]); + for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++) + *ptrptr++ = (void *) ((char *)ptr + v * max_receive); } + dev->broadcast_rcv_context = context; packet.payload_length = max_receive; packet.interrupt = 1; -- cgit From d9d2b484e0006d51591c3b9594e9d5f73b1a8d08 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:37 +0900 Subject: firewire net: Fix leakage of kmap for broadcast receive buffer. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index d8cb6ac31044..0dc2fdf00562 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1228,6 +1228,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) failed_rcv_queue: kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); failed_ptrs_alloc: fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); failed_buffer_init: @@ -1620,10 +1622,15 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { + unsigned u; + fw_iso_context_stop(dev->broadcast_rcv_context); kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); + fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); -- cgit From eac31d58ca2818e3fdc7a6e78fa1b56965f604e9 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:55 +0900 Subject: firewire net: Allocate dev->broadcast_rcv_buffer_ptrs early. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 0dc2fdf00562..21210fb94762 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1163,6 +1163,13 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; + ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); + if (!ptrptr) { + retval = -ENOMEM; + goto failed_ptrs_alloc; + } + dev->broadcast_rcv_buffer_ptrs = ptrptr; + context = fw_iso_context_create(dev->card, FW_ISO_CONTEXT_RECEIVE, IEEE1394_BROADCAST_CHANNEL, dev->card->link_speed, 8, @@ -1177,13 +1184,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) if (retval < 0) goto failed_buffer_init; - ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); - if (!ptrptr) { - retval = -ENOMEM; - goto failed_ptrs_alloc; - } - - dev->broadcast_rcv_buffer_ptrs = ptrptr; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { void *ptr; unsigned v; @@ -1226,16 +1226,16 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return 0; failed_rcv_queue: - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) kunmap(dev->broadcast_rcv_buffer.pages[u]); - failed_ptrs_alloc: fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); failed_buffer_init: fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; + failed_ptrs_alloc: return retval; } @@ -1626,8 +1626,6 @@ static int fwnet_remove(struct device *_dev) fw_iso_context_stop(dev->broadcast_rcv_context); - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) kunmap(dev->broadcast_rcv_buffer.pages[u]); @@ -1635,6 +1633,8 @@ static int fwnet_remove(struct device *_dev) dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); dev->broadcast_rcv_context = NULL; + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; dev->broadcast_state = FWNET_BROADCAST_ERROR; } for (i = 0; dev->queued_datagrams && i < 5; i++) -- cgit From 111534cd7a376b75e72ddea0c6d00ec956ce3343 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:45:50 +0900 Subject: firewire net: Introduce fwnet_broadcast_stop() to destroy broadcast resources. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 68 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 21210fb94762..ca41446d62f4 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1146,6 +1146,32 @@ static int fwnet_fifo_start(struct fwnet_device *dev) return 0; } +static void __fwnet_broadcast_stop(struct fwnet_device *dev) +{ + unsigned u; + + if (dev->broadcast_state != FWNET_BROADCAST_ERROR) { + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); + fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); + } + if (dev->broadcast_rcv_context) { + fw_iso_context_destroy(dev->broadcast_rcv_context); + dev->broadcast_rcv_context = NULL; + } + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; + dev->broadcast_state = FWNET_BROADCAST_ERROR; +} + +static void fwnet_broadcast_stop(struct fwnet_device *dev) +{ + if (dev->broadcast_state == FWNET_BROADCAST_ERROR) + return; + fw_iso_context_stop(dev->broadcast_rcv_context); + __fwnet_broadcast_stop(dev); +} + static int fwnet_broadcast_start(struct fwnet_device *dev) { struct fw_iso_context *context; @@ -1166,7 +1192,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); if (!ptrptr) { retval = -ENOMEM; - goto failed_ptrs_alloc; + goto failed; } dev->broadcast_rcv_buffer_ptrs = ptrptr; @@ -1176,13 +1202,15 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fwnet_receive_broadcast, dev); if (IS_ERR(context)) { retval = PTR_ERR(context); - goto failed_context_create; + goto failed; } retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); if (retval < 0) - goto failed_buffer_init; + goto failed; + + dev->broadcast_state = FWNET_BROADCAST_STOPPED; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { void *ptr; @@ -1206,7 +1234,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) retval = fw_iso_context_queue(context, &packet, &dev->broadcast_rcv_buffer, offset); if (retval < 0) - goto failed_rcv_queue; + goto failed; offset += max_receive; } @@ -1216,7 +1244,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) retval = fw_iso_context_start(context, -1, 0, FW_ISO_CONTEXT_MATCH_ALL_TAGS); /* ??? sync */ if (retval < 0) - goto failed_rcv_queue; + goto failed; /* FIXME: adjust it according to the min. speed of all known peers? */ dev->broadcast_xmt_max_payload = IEEE1394_MAX_PAYLOAD_S100 @@ -1225,18 +1253,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return 0; - failed_rcv_queue: - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) - kunmap(dev->broadcast_rcv_buffer.pages[u]); - fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); - failed_buffer_init: - fw_iso_context_destroy(context); - dev->broadcast_rcv_context = NULL; - failed_context_create: - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; - failed_ptrs_alloc: - + failed: + __fwnet_broadcast_stop(dev); return retval; } @@ -1621,22 +1639,8 @@ static int fwnet_remove(struct device *_dev) unregister_netdev(net); fwnet_fifo_stop(dev); - if (dev->broadcast_rcv_context) { - unsigned u; - - fw_iso_context_stop(dev->broadcast_rcv_context); + fwnet_broadcast_stop(dev); - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) - kunmap(dev->broadcast_rcv_buffer.pages[u]); - - fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, - dev->card); - fw_iso_context_destroy(dev->broadcast_rcv_context); - dev->broadcast_rcv_context = NULL; - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; - dev->broadcast_state = FWNET_BROADCAST_ERROR; - } for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); WARN_ON(dev->queued_datagrams); -- cgit From 8559e7f0694e3fb192aab00a495be5a510afc8c3 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:45:57 +0900 Subject: firewire net: Release broadcast/fifo resources on ifdown. Since those resources are allocated on ifup, relsase them on ifdown. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index ca41446d62f4..c1898adeb900 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1295,9 +1295,12 @@ out: /* ifdown */ static int fwnet_stop(struct net_device *net) { + struct fwnet_device *dev = netdev_priv(net); + netif_stop_queue(net); - /* Deallocate iso context for use by other applications? */ + fwnet_broadcast_stop(dev); + fwnet_fifo_stop(dev); return 0; } @@ -1638,9 +1641,6 @@ static int fwnet_remove(struct device *_dev) if (list_empty(&dev->peer_list)) { unregister_netdev(net); - fwnet_fifo_stop(dev); - fwnet_broadcast_stop(dev); - for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); WARN_ON(dev->queued_datagrams); -- cgit From df594563fc8503d8473341fc67fc890c65c3a7c9 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 13 Mar 2013 03:02:20 +0000 Subject: sfc: remove duplicated include from efx.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/efx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index f050248e9fba..78c33249a21b 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include "net_driver.h" -- cgit From f7de0b936811296f7d88d378af80ad14b061769a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 13 Mar 2013 03:03:58 +0000 Subject: tuntap: remove unused variable in __tun_detach() The variable dev is initialized but never used otherwise, so remove the unused variable. Signed-off-by: Wei Yongjun Acked-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index b7c457adc0dc..95837c1b197a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -409,14 +409,12 @@ static void __tun_detach(struct tun_file *tfile, bool clean) { struct tun_file *ntfile; struct tun_struct *tun; - struct net_device *dev; tun = rtnl_dereference(tfile->tun); if (tun && !tfile->detached) { u16 index = tfile->queue_index; BUG_ON(index >= tun->numqueues); - dev = tun->dev; rcu_assign_pointer(tun->tfiles[index], tun->tfiles[tun->numqueues - 1]); -- cgit From be871b7e54711479d3b9d3617d49898770830db2 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Tue, 12 Mar 2013 17:21:19 +0100 Subject: device: separate all subsys mutexes ca22e56d (driver-core: implement 'sysdev' functionality for regular devices and buses) has introduced bus_register macro with a static key to distinguish different subsys mutex classes. This however doesn't work for different subsys which use a common registering function. One example is subsys_system_register (and mce_device and cpu_device). In the end this leads to the following lockdep splat: [ 207.271924] ====================================================== [ 207.271932] [ INFO: possible circular locking dependency detected ] [ 207.271942] 3.9.0-rc1-0.7-default+ #34 Not tainted [ 207.271948] ------------------------------------------------------- [ 207.271957] bash/10493 is trying to acquire lock: [ 207.271963] (subsys mutex){+.+.+.}, at: [] bus_remove_device+0x37/0x1c0 [ 207.271987] [ 207.271987] but task is already holding lock: [ 207.271995] (cpu_hotplug.lock){+.+.+.}, at: [] cpu_hotplug_begin+0x2f/0x60 [ 207.272012] [ 207.272012] which lock already depends on the new lock. [ 207.272012] [ 207.272023] [ 207.272023] the existing dependency chain (in reverse order) is: [ 207.272033] [ 207.272033] -> #4 (cpu_hotplug.lock){+.+.+.}: [ 207.272044] [] lock_acquire+0xe9/0x120 [ 207.272056] [] mutex_lock_nested+0x37/0x360 [ 207.272069] [] get_online_cpus+0x29/0x40 [ 207.272082] [] drain_all_stock+0x30/0x150 [ 207.272094] [] mem_cgroup_reclaim+0xaa/0xe0 [ 207.272104] [] __mem_cgroup_try_charge+0x51e/0xcf0 [ 207.272114] [] mem_cgroup_charge_common+0x36/0x60 [ 207.272125] [] mem_cgroup_newpage_charge+0x2a/0x30 [ 207.272135] [] do_wp_page+0x231/0x830 [ 207.272147] [] handle_pte_fault+0x19e/0x8d0 [ 207.272157] [] handle_mm_fault+0x158/0x1e0 [ 207.272166] [] do_page_fault+0x2a3/0x4e0 [ 207.272178] [] page_fault+0x28/0x30 [ 207.272189] [ 207.272189] -> #3 (&mm->mmap_sem){++++++}: [ 207.272199] [] lock_acquire+0xe9/0x120 [ 207.272208] [] might_fault+0x6d/0x90 [ 207.272218] [] filldir64+0xb3/0x120 [ 207.272229] [] call_filldir+0x89/0x130 [ext3] [ 207.272248] [] ext3_readdir+0x6b7/0x7e0 [ext3] [ 207.272263] [] vfs_readdir+0xa9/0xc0 [ 207.272273] [] sys_getdents64+0x9b/0x110 [ 207.272284] [] system_call_fastpath+0x16/0x1b [ 207.272296] [ 207.272296] -> #2 (&type->i_mutex_dir_key#3){+.+.+.}: [ 207.272309] [] lock_acquire+0xe9/0x120 [ 207.272319] [] mutex_lock_nested+0x37/0x360 [ 207.272329] [] link_path_walk+0x6f4/0x9a0 [ 207.272339] [] path_openat+0xba/0x470 [ 207.272349] [] do_filp_open+0x48/0xa0 [ 207.272358] [] file_open_name+0xdc/0x110 [ 207.272369] [] filp_open+0x35/0x40 [ 207.272378] [] _request_firmware+0x52e/0xb20 [ 207.272389] [] request_firmware+0x16/0x20 [ 207.272399] [] request_microcode_fw+0x61/0xd0 [microcode] [ 207.272416] [] microcode_init_cpu+0x104/0x150 [microcode] [ 207.272431] [] mc_device_add+0x7c/0xb0 [microcode] [ 207.272444] [] subsys_interface_register+0xc9/0x100 [ 207.272457] [] 0xffffffffa04fc0f4 [ 207.272472] [] do_one_initcall+0x42/0x180 [ 207.272485] [] load_module+0x19df/0x1b70 [ 207.272499] [] sys_init_module+0xe6/0x130 [ 207.272511] [] system_call_fastpath+0x16/0x1b [ 207.272523] [ 207.272523] -> #1 (umhelper_sem){++++.+}: [ 207.272537] [] lock_acquire+0xe9/0x120 [ 207.272548] [] down_read+0x34/0x50 [ 207.272559] [] usermodehelper_read_trylock+0x4f/0x100 [ 207.272575] [] _request_firmware+0x59d/0xb20 [ 207.272587] [] request_firmware+0x16/0x20 [ 207.272599] [] request_microcode_fw+0x61/0xd0 [microcode] [ 207.272613] [] microcode_init_cpu+0x104/0x150 [microcode] [ 207.272627] [] mc_device_add+0x7c/0xb0 [microcode] [ 207.272641] [] subsys_interface_register+0xc9/0x100 [ 207.272654] [] 0xffffffffa04fc0f4 [ 207.272666] [] do_one_initcall+0x42/0x180 [ 207.272678] [] load_module+0x19df/0x1b70 [ 207.272690] [] sys_init_module+0xe6/0x130 [ 207.272702] [] system_call_fastpath+0x16/0x1b [ 207.272715] [ 207.272715] -> #0 (subsys mutex){+.+.+.}: [ 207.272729] [] __lock_acquire+0x13b2/0x15f0 [ 207.272740] [] lock_acquire+0xe9/0x120 [ 207.272751] [] mutex_lock_nested+0x37/0x360 [ 207.272763] [] bus_remove_device+0x37/0x1c0 [ 207.272775] [] device_del+0x134/0x1f0 [ 207.272786] [] device_unregister+0x22/0x60 [ 207.272798] [] mce_cpu_callback+0x15e/0x1ad [ 207.272812] [] notifier_call_chain+0x72/0x130 [ 207.272824] [] __raw_notifier_call_chain+0xe/0x10 [ 207.272839] [] _cpu_down+0x1d6/0x350 [ 207.272851] [] cpu_down+0x40/0x60 [ 207.272862] [] store_online+0x75/0xe0 [ 207.272874] [] dev_attr_store+0x20/0x30 [ 207.272886] [] sysfs_write_file+0xd9/0x150 [ 207.272900] [] vfs_write+0xcb/0x130 [ 207.272911] [] sys_write+0x64/0xa0 [ 207.272923] [] system_call_fastpath+0x16/0x1b [ 207.272936] [ 207.272936] other info that might help us debug this: [ 207.272936] [ 207.272952] Chain exists of: [ 207.272952] subsys mutex --> &mm->mmap_sem --> cpu_hotplug.lock [ 207.272952] [ 207.272973] Possible unsafe locking scenario: [ 207.272973] [ 207.272984] CPU0 CPU1 [ 207.272992] ---- ---- [ 207.273000] lock(cpu_hotplug.lock); [ 207.273009] lock(&mm->mmap_sem); [ 207.273020] lock(cpu_hotplug.lock); [ 207.273031] lock(subsys mutex); [ 207.273040] [ 207.273040] *** DEADLOCK *** [ 207.273040] [ 207.273055] 5 locks held by bash/10493: [ 207.273062] #0: (&buffer->mutex){+.+.+.}, at: [] sysfs_write_file+0x49/0x150 [ 207.273080] #1: (s_active#150){.+.+.+}, at: [] sysfs_write_file+0xc2/0x150 [ 207.273099] #2: (x86_cpu_hotplug_driver_mutex){+.+.+.}, at: [] cpu_hotplug_driver_lock+0x17/0x20 [ 207.273121] #3: (cpu_add_remove_lock){+.+.+.}, at: [] cpu_down+0x2c/0x60 [ 207.273140] #4: (cpu_hotplug.lock){+.+.+.}, at: [] cpu_hotplug_begin+0x2f/0x60 [ 207.273158] [ 207.273158] stack backtrace: [ 207.273170] Pid: 10493, comm: bash Not tainted 3.9.0-rc1-0.7-default+ #34 [ 207.273180] Call Trace: [ 207.273192] [] print_circular_bug+0x223/0x310 [ 207.273204] [] __lock_acquire+0x13b2/0x15f0 [ 207.273216] [] ? sysfs_hash_and_remove+0x60/0xc0 [ 207.273227] [] lock_acquire+0xe9/0x120 [ 207.273239] [] ? bus_remove_device+0x37/0x1c0 [ 207.273251] [] mutex_lock_nested+0x37/0x360 [ 207.273263] [] ? bus_remove_device+0x37/0x1c0 [ 207.273274] [] ? sysfs_hash_and_remove+0x60/0xc0 [ 207.273286] [] bus_remove_device+0x37/0x1c0 [ 207.273298] [] device_del+0x134/0x1f0 [ 207.273309] [] device_unregister+0x22/0x60 [ 207.273321] [] mce_cpu_callback+0x15e/0x1ad [ 207.273332] [] notifier_call_chain+0x72/0x130 [ 207.273344] [] __raw_notifier_call_chain+0xe/0x10 [ 207.273356] [] _cpu_down+0x1d6/0x350 [ 207.273368] [] ? cpu_hotplug_driver_lock+0x17/0x20 [ 207.273380] [] cpu_down+0x40/0x60 [ 207.273391] [] store_online+0x75/0xe0 [ 207.273402] [] dev_attr_store+0x20/0x30 [ 207.273413] [] sysfs_write_file+0xd9/0x150 [ 207.273425] [] vfs_write+0xcb/0x130 [ 207.273436] [] sys_write+0x64/0xa0 [ 207.273447] [] system_call_fastpath+0x16/0x1b Which reports a false possitive deadlock because it sees: 1) load_module -> subsys_interface_register -> mc_deveice_add (*) -> subsys->p->mutex -> link_path_walk -> lookup_slow -> i_mutex 2) sys_write -> _cpu_down -> cpu_hotplug_begin -> cpu_hotplug.lock -> mce_cpu_callback -> mce_device_remove(**) -> device_unregister -> bus_remove_device -> subsys mutex 3) vfs_readdir -> i_mutex -> filldir64 -> might_fault -> might_lock_read(mmap_sem) -> page_fault -> mmap_sem -> drain_all_stock -> cpu_hotplug.lock but 1) takes cpu_subsys subsys (*) but 2) takes mce_device subsys (**) so the deadlock is not possible AFAICS. The fix is quite simple. We can pull the key inside bus_type structure because they are defined per device so the pointer will be unique as well. bus_register doesn't need to be a macro anymore so change it to the inline. We could get rid of __bus_register as there is no other caller but maybe somebody will want to use a different key so keep it around for now. Reported-by: Li Zefan Signed-off-by: Michal Hocko Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 8 ++++---- include/linux/device.h | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 519865b53f76..8a00dec574d6 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -898,18 +898,18 @@ static ssize_t bus_uevent_store(struct bus_type *bus, static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); /** - * __bus_register - register a driver-core subsystem + * bus_register - register a driver-core subsystem * @bus: bus to register - * @key: lockdep class key * * Once we have that, we register the bus with the kobject * infrastructure, then register the children subsystems it has: * the devices and drivers that belong to the subsystem. */ -int __bus_register(struct bus_type *bus, struct lock_class_key *key) +int bus_register(struct bus_type *bus) { int retval; struct subsys_private *priv; + struct lock_class_key *key = &bus->lock_key; priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); if (!priv) @@ -981,7 +981,7 @@ out: bus->p = NULL; return retval; } -EXPORT_SYMBOL_GPL(__bus_register); +EXPORT_SYMBOL_GPL(bus_register); /** * bus_unregister - remove a bus from the system diff --git a/include/linux/device.h b/include/linux/device.h index 9d6464ea99c6..4a7c4a84afee 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -111,17 +111,11 @@ struct bus_type { struct iommu_ops *iommu_ops; struct subsys_private *p; + struct lock_class_key lock_key; }; -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ -#define bus_register(subsys) \ -({ \ - static struct lock_class_key __key; \ - __bus_register(subsys, &__key); \ -}) -extern int __must_check __bus_register(struct bus_type *bus, - struct lock_class_key *key); +extern int __must_check bus_register(struct bus_type *bus); + extern void bus_unregister(struct bus_type *bus); extern int __must_check bus_rescan_devices(struct bus_type *bus); -- cgit From a9fac7399b45db668faeca6c33873d249111cf8b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 11 Mar 2013 15:38:26 -0500 Subject: ssb: pci: Fix flipping of MAC address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit e565275 entitled "ssb: pci: Standardize a function to get mac address", the SPROM readout of the MAC has had the values flipped so that 00:11:22:33:44:55 became 11:00:33:22:55:44. The fix has been tested on both little- and big-endian architectures. Reported-by: Rafał Miłecki Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 6d6e7b926aa5..63ff69f9d3eb 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -234,8 +234,8 @@ static void sprom_get_mac(char *mac, const u16 *in) { int i; for (i = 0; i < 3; i++) { - *mac++ = in[i]; *mac++ = in[i] >> 8; + *mac++ = in[i]; } } -- cgit From d95f1d20ab217eb4c2f1c1a0abb2320f0c38954b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 12 Mar 2013 11:09:34 +0800 Subject: wil6210: remove unused including Remove including that don't need it. Signed-off-by: Wei Yongjun Acked-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 9ecc1968262c..1999450761eb 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "wil6210.h" -- cgit From 3b0378a88be2f85f495d557ac096291b0b54a163 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:38 +0200 Subject: wil6210: Remove local implementation of dynamic hexdump This functionality now integrated in kernel, local hack not needed any more Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/dbg_hexdump.h | 20 -------------------- drivers/net/wireless/ath/wil6210/wil6210.h | 6 ++---- 2 files changed, 2 insertions(+), 24 deletions(-) delete mode 100644 drivers/net/wireless/ath/wil6210/dbg_hexdump.h (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/dbg_hexdump.h b/drivers/net/wireless/ath/wil6210/dbg_hexdump.h deleted file mode 100644 index e5712f026c47..000000000000 --- a/drivers/net/wireless/ath/wil6210/dbg_hexdump.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef WIL_DBG_HEXDUMP_H_ -#define WIL_DBG_HEXDUMP_H_ - -#include -#include - -#if defined(CONFIG_DYNAMIC_DEBUG) -#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) - -#else /* defined(CONFIG_DYNAMIC_DEBUG) */ -#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) \ - print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \ - groupsize, buf, len, ascii) -#endif /* defined(CONFIG_DYNAMIC_DEBUG) */ - -#endif /* WIL_DBG_HEXDUMP_H_ */ diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index aea961ff8f08..bdab0e253b2f 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -21,8 +21,6 @@ #include #include -#include "dbg_hexdump.h" - #define WIL_NAME "wil6210" /** @@ -277,13 +275,13 @@ struct wil6210_priv { #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ groupsize, buf, len, ascii) \ - wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\ + print_hex_dump_debug("DBG[TXRX]" prefix_str,\ prefix_type, rowsize, \ groupsize, buf, len, ascii) #define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \ groupsize, buf, len, ascii) \ - wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\ + print_hex_dump_debug("DBG[ WMI]" prefix_str,\ prefix_type, rowsize, \ groupsize, buf, len, ascii) -- cgit From 3442a5048a0e33e9f24fe2e19d3dff0d496c79fc Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:39 +0200 Subject: wil6210: handle linkup/linkdown WMI events Firmware indicates linkup/linkdown when data path becomes ready. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/wmi.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 0bb3b76b4b58..895ae9de3a12 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -528,6 +528,27 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, } } +static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len) +{ + struct net_device *ndev = wil_to_ndev(wil); + struct wmi_data_port_open_event *evt = d; + + wil_dbg_wmi(wil, "Link UP for CID %d\n", evt->cid); + + netif_carrier_on(ndev); +} + +static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len) +{ + struct net_device *ndev = wil_to_ndev(wil); + struct wmi_wbe_link_down_event *evt = d; + + wil_dbg_wmi(wil, "Link DOWN for CID %d, reason %d\n", + evt->cid, le32_to_cpu(evt->reason)); + + netif_carrier_off(ndev); +} + static const struct { int eventid; void (*handler)(struct wil6210_priv *wil, int eventid, @@ -541,6 +562,8 @@ static const struct { {WMI_DISCONNECT_EVENTID, wmi_evt_disconnect}, {WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify}, {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, + {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, + {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, }; /* -- cgit From 249a382b8a147593d40cc9cd1a0585b22aaca546 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:40 +0200 Subject: wil6210: handle WMI_BA_STATUS_EVENTID Firmware indicated block ack agreement status change. For now, just log it. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/wmi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 895ae9de3a12..d636ff493f89 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -549,6 +549,16 @@ static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len) netif_carrier_off(ndev); } +static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, + int len) +{ + struct wmi_vring_ba_status_event *evt = d; + + wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n", + evt->ringid, evt->status ? "N/A" : "OK", evt->agg_wsize, + __le16_to_cpu(evt->ba_timeout)); +} + static const struct { int eventid; void (*handler)(struct wil6210_priv *wil, int eventid, @@ -564,6 +574,7 @@ static const struct { {WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx}, {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, + {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, }; /* -- cgit From b1defa4d662ff838e943829323e277fb69b40550 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:41 +0200 Subject: wil6210: do not set IE's for beacon On the DMG band, there is no 'normal' beacon frame. Instead, transmitted is short 'DMG beacon' frame, that do not include IE's So, beacon IE's are not relevant for the DMG band. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 1999450761eb..839a4bcccdf8 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -445,8 +445,13 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, /* IE's */ /* bcon 'head IE's are not relevant for 60g band */ - wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len, - bcon->beacon_ies); + /* + * FW do not form regular beacon, so bcon IE's are not set + * For the DMG bcon, when it will be supported, bcon IE's will + * be reused; add something like: + * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len, + * bcon->beacon_ies); + */ wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len, bcon->proberesp_ies); wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, -- cgit From 03866e7d3f37eb5c3d96f2041bb823f9742db4ae Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:42 +0200 Subject: wil6210: Fix garbage sent to the FW with wmi_set_ie() Extra reference was taken by mistake. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index d636ff493f89..aa642dfd3024 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -877,7 +877,7 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) /* BUG: FW API define ieLen as u8. Will fix FW */ cmd->ie_len = cpu_to_le16(ie_len); memcpy(cmd->ie_info, ie, ie_len); - rc = wmi_send(wil, WMI_SET_APPIE_CMDID, &cmd, len); + rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len); kfree(cmd); return rc; -- cgit From d81079f170a70944d6c55f25e71e1bab269b6ef8 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:43 +0200 Subject: wil6210: refactor connect_worker Move wmi_connect_worker() to the main.c and change names for consistency. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/main.c | 22 +++++++++++++++++++++- drivers/net/wireless/ath/wil6210/wil6210.h | 3 +-- drivers/net/wireless/ath/wil6210/wmi.c | 23 +---------------------- 3 files changed, 23 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 761c389586d4..11b696072185 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -118,6 +118,26 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); } +static void wil_connect_worker(struct work_struct *work) +{ + int rc; + struct wil6210_priv *wil = container_of(work, struct wil6210_priv, + connect_worker); + int cid = wil->pending_connect_cid; + + if (cid < 0) { + wil_err(wil, "No connection pending\n"); + return; + } + + wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid); + + rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0); + wil->pending_connect_cid = -1; + if (rc == 0) + wil_link_on(wil); +} + int wil_priv_init(struct wil6210_priv *wil) { wil_dbg_misc(wil, "%s()\n", __func__); @@ -130,7 +150,7 @@ int wil_priv_init(struct wil6210_priv *wil) wil->pending_connect_cid = -1; setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); - INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker); + INIT_WORK(&wil->connect_worker, wil_connect_worker); INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index bdab0e253b2f..5f500de957fe 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -225,7 +225,7 @@ struct wil6210_priv { struct workqueue_struct *wmi_wq; /* for deferred calls */ struct work_struct wmi_event_worker; struct workqueue_struct *wmi_wq_conn; /* for connect worker */ - struct work_struct wmi_connect_worker; + struct work_struct connect_worker; struct work_struct disconnect_worker; struct timer_list connect_timer; int pending_connect_cid; @@ -311,7 +311,6 @@ int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len); void wmi_recv_cmd(struct wil6210_priv *wil); int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, u16 reply_id, void *reply, u8 reply_size, int to_msec); -void wmi_connect_worker(struct work_struct *work); void wmi_event_worker(struct work_struct *work); void wmi_event_flush(struct wil6210_priv *wil); int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index aa642dfd3024..dd3b7b1f0856 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -443,7 +443,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN); wil->pending_connect_cid = evt->cid; - queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker); + queue_work(wil->wmi_wq_conn, &wil->connect_worker); } static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, @@ -1031,24 +1031,3 @@ void wmi_event_worker(struct work_struct *work) kfree(evt); } } - -void wmi_connect_worker(struct work_struct *work) -{ - int rc; - struct wil6210_priv *wil = container_of(work, struct wil6210_priv, - wmi_connect_worker); - - if (wil->pending_connect_cid < 0) { - wil_err(wil, "No connection pending\n"); - return; - } - - wil_dbg_wmi(wil, "Configure for connection CID %d\n", - wil->pending_connect_cid); - - rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, - wil->pending_connect_cid, 0); - wil->pending_connect_cid = -1; - if (rc == 0) - wil_link_on(wil); -} -- cgit From a0f7845b7e58f022d2348f58120a2a5ee3a7c2bc Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:44 +0200 Subject: wil6210: use cfg80211_inform_bss_frame() Avoid unnecessary frame parsing Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/wmi.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index dd3b7b1f0856..9c069428557e 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -324,17 +324,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { struct cfg80211_bss *bss; - u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); - u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); - u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); - const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable; - size_t ie_len = d_len - offsetof(struct ieee80211_mgmt, - u.beacon.variable); - wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); - - bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid, - tsf, cap, bi, ie_buf, ie_len, - signal, GFP_KERNEL); + + bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, + d_len, signal, GFP_KERNEL); if (bss) { wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); -- cgit From 102b1d99e555ddaddcc1bd7b0a976909c75aefc2 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:45 +0200 Subject: wil6210: report all received mgmt frames Pass to cfg80211 all management frames. Used by wpa_supplicant. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/wmi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 9c069428557e..dc2ad853d0a7 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -334,6 +334,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) } else { wil_err(wil, "cfg80211_inform_bss() failed\n"); } + } else { + cfg80211_rx_mgmt(wil->wdev, freq, signal, + (void *)rx_mgmt_frame, d_len, GFP_KERNEL); } } -- cgit From de70ab87b1e4ba1669638381b80f2d90ea09576c Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:46 +0200 Subject: wil6210: fix FW error notification user space get notified through kobject_uevent_env(), that might sleep and thus should run in thread context. Move user space notification to the thread handler, while mark FW is non-functional right in the hard IRQ. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/interrupt.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index dc97e7b2609c..de9b971ea159 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -257,10 +257,13 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) wil6210_mask_irq_misc(wil); if (isr & ISR_MISC_FW_ERROR) { - wil_dbg_irq(wil, "IRQ: Firmware error\n"); + wil_err(wil, "Firmware error detected\n"); clear_bit(wil_status_fwready, &wil->status); - wil_notify_fw_error(wil); - isr &= ~ISR_MISC_FW_ERROR; + /* + * do not clear @isr here - we do 2-nd part in thread + * there, user space get notified, and it should be done + * in non-atomic context + */ } if (isr & ISR_MISC_FW_READY) { @@ -289,6 +292,11 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie) wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); + if (isr & ISR_MISC_FW_ERROR) { + wil_notify_fw_error(wil); + isr &= ~ISR_MISC_FW_ERROR; + } + if (isr & ISR_MISC_MBOX_EVT) { wil_dbg_irq(wil, "MBOX event\n"); wmi_recv_cmd(wil); -- cgit From acc9780d6e4e034b0ea98e199c196799a02049fd Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:47 +0200 Subject: wil6210: use WLAN_CAPABILITY_DMG_TYPE_MASK Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 839a4bcccdf8..664022dda1f6 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -291,7 +291,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, /* WMI_CONNECT_CMD */ memset(&conn, 0, sizeof(conn)); - switch (bss->capability & 0x03) { + switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { case WLAN_CAPABILITY_DMG_TYPE_AP: conn.network_type = WMI_NETTYPE_INFRA; break; -- cgit From c7996ef852d2c8382b381268b53657175cc2dbc0 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:48 +0200 Subject: wil6210: headers clean-up Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 9 --------- drivers/net/wireless/ath/wil6210/main.c | 6 ------ drivers/net/wireless/ath/wil6210/netdev.c | 3 --- drivers/net/wireless/ath/wil6210/pcie_bus.c | 3 --- drivers/net/wireless/ath/wil6210/txrx.c | 3 --- drivers/net/wireless/ath/wil6210/wmi.c | 3 --- 6 files changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 664022dda1f6..3e31e3778c5b 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -14,15 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include -#include - #include "wil6210.h" #include "wmi.h" diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 11b696072185..f11efa4d6ab8 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -14,12 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include #include #include diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 8ce2e33dce20..098a8ec6b841 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -14,10 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include #include -#include #include "wil6210.h" diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 81c35c6e3832..eb1dc7ad80fb 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -14,10 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include -#include -#include #include #include #include diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index d1315b442375..4af996749eac 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -14,10 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include #include -#include #include #include #include diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index dc2ad853d0a7..8d9e145f0983 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -14,9 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include #include #include -- cgit From 55f7acdd2440285c5b1236e29c4194eacd624008 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:49 +0200 Subject: wil6210: new SW reset New firmware allows for shorter SW reset procedure. After SW reset, FW raises "fw done" IRQ, at this moment mailbox control structures are initialized, driver caches it. New status bit wil_status_reset_done introduced to track completion of the reset. It is set by "fw ready" irq, and required for WMI rx flow to access control structures. WMI Tx flow protected by other status bit, wil_status_fwready. It can't be set before wil_status_reset_done is set by design. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/interrupt.c | 11 +++++++++++ drivers/net/wireless/ath/wil6210/main.c | 23 ----------------------- drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 5 +++++ 4 files changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index de9b971ea159..e3c1e7684f9c 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); } +static void wil_cache_mbox_regs(struct wil6210_priv *wil) +{ + /* make shadow copy of registers that should not change on run time */ + wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, + sizeof(struct wil6210_mbox_ctl)); + wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); + wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); +} + static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; @@ -268,6 +277,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_READY) { wil_dbg_irq(wil, "IRQ: FW ready\n"); + wil_cache_mbox_regs(wil); + set_bit(wil_status_reset_done, &wil->status); /** * Actual FW ready indicated by the * WMI_FW_READY_EVENTID diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index f11efa4d6ab8..9d05628e450d 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -103,15 +103,6 @@ static void wil_connect_timer_fn(ulong x) schedule_work(&wil->disconnect_worker); } -static void wil_cache_mbox_regs(struct wil6210_priv *wil) -{ - /* make shadow copy of registers that should not change on run time */ - wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, - sizeof(struct wil6210_mbox_ctl)); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); - wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); -} - static void wil_connect_worker(struct work_struct *work) { int rc; @@ -161,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil) return -EAGAIN; } - wil_cache_mbox_regs(wil); - return 0; } @@ -199,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil) W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ - msleep(100); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); - msleep(100); - W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); @@ -217,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil) W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); - msleep(2000); - - W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */ - - msleep(2000); - wil_dbg_misc(wil, "Reset completed\n"); #undef W @@ -279,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil) wil->pending_connect_cid = -1; INIT_COMPLETION(wil->wmi_ready); - wil_cache_mbox_regs(wil); - /* TODO: release MAC reset */ wil6210_enable_irq(wil); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 5f500de957fe..2ec7258b191c 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -186,6 +186,7 @@ enum { /* for wil6210_priv.status */ wil_status_fwready = 0, wil_status_fwconnected, wil_status_dontscan, + wil_status_reset_done, wil_status_irqen, /* FIXME: interrupts enabled - for debug */ }; diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 8d9e145f0983..ed2b097ee02a 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -585,6 +585,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil) void __iomem *src; ulong flags; + if (!test_bit(wil_status_reset_done, &wil->status)) { + wil_err(wil, "Reset not completed\n"); + return; + } + for (;;) { u16 len; -- cgit From b80231773ad0b89f6abee8cf26fde8fe4638fceb Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:50 +0200 Subject: wil6210: sync with new firmware Adjust driver for changes in the FW API. Noticeable changes in the FW are: - temperature sensing - infrastructure for multiple connections - infrastructure for P2P - signal strength indication This commit introduces only changes that are required to support same functionality as previous firmware, no new features. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 12 +- drivers/net/wireless/ath/wil6210/main.c | 15 +- drivers/net/wireless/ath/wil6210/txrx.c | 2 +- drivers/net/wireless/ath/wil6210/wil6210.h | 6 +- drivers/net/wireless/ath/wil6210/wmi.c | 45 +++- drivers/net/wireless/ath/wil6210/wmi.h | 363 ++++++++++++++++++++-------- 6 files changed, 321 insertions(+), 122 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 3e31e3778c5b..c5d4a87abaaf 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -427,10 +427,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, if (rc) return rc; - rc = wmi_set_channel(wil, channel->hw_value); - if (rc) - return rc; - /* MAC address - pre-requisite for other commands */ wmi_set_mac_address(wil, ndev->dev_addr); @@ -450,7 +446,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, wil->secure_pcp = info->privacy; - rc = wmi_set_bcon(wil, info->beacon_interval, wmi_nettype); + rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, + channel->hw_value); if (rc) return rc; @@ -467,11 +464,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, { int rc = 0; struct wil6210_priv *wil = wiphy_to_wil(wiphy); - struct wireless_dev *wdev = ndev->ieee80211_ptr; - u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); - /* To stop beaconing, set BI to 0 */ - rc = wmi_set_bcon(wil, 0, wmi_nettype); + rc = wmi_pcp_stop(wil); return rc; } diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 9d05628e450d..a0478e2f6868 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -343,9 +343,9 @@ static int __wil_up(struct wil6210_priv *wil) wil_err(wil, "SSID not set\n"); return -EINVAL; } - wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid); - if (channel) - wmi_set_channel(wil, channel->hw_value); + rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid); + if (rc) + return rc; break; default: break; @@ -355,9 +355,12 @@ static int __wil_up(struct wil6210_priv *wil) wmi_set_mac_address(wil, ndev->dev_addr); /* Set up beaconing if required. */ - rc = wmi_set_bcon(wil, bi, wmi_nettype); - if (rc) - return rc; + if (bi > 0) { + rc = wmi_pcp_start(wil, bi, wmi_nettype, + (channel ? channel->hw_value : 0)); + if (rc) + return rc; + } /* Rx VRING. After MAC and beacon */ wil_rx_init(wil); diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 4af996749eac..1bfa736cc1f2 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -557,7 +557,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, if (rc) goto out_free; - if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) { + if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) { wil_err(wil, "Tx config failed, status 0x%02x\n", reply.cmd.status); rc = -EINVAL; diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 2ec7258b191c..3bbd86d54ba1 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -209,6 +209,8 @@ struct wil6210_priv { struct wireless_dev *wdev; void __iomem *csr; ulong status; + u32 fw_version; + u8 n_mids; /* number of additional MIDs as reported by FW */ /* profile */ u32 monitor_flags; u32 secure_pcp; /* create secure PCP? */ @@ -326,6 +328,7 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, int wmi_echo(struct wil6210_priv *wil); int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); +int wmi_p2p_cfg(struct wil6210_priv *wil, int channel); int wil6210_init_irq(struct wil6210_priv *wil, int irq); void wil6210_fini_irq(struct wil6210_priv *wil, int irq); @@ -339,7 +342,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev); void wil_wdev_free(struct wil6210_priv *wil); int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); -int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype); +int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); +int wmi_pcp_stop(struct wil6210_priv *wil); void wil6210_disconnect(struct wil6210_priv *wil, void *bssid); int wil_rx_init(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index ed2b097ee02a..706ee9d86e61 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -269,16 +269,18 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; struct wmi_ready_event *evt = d; - u32 ver = le32_to_cpu(evt->sw_version); + wil->fw_version = le32_to_cpu(evt->sw_version); + wil->n_mids = evt->numof_additional_mids; - wil_dbg_wmi(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac); + wil_dbg_wmi(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version, + evt->mac, wil->n_mids); if (!is_valid_ether_addr(ndev->dev_addr)) { memcpy(ndev->dev_addr, evt->mac, ETH_ALEN); memcpy(ndev->perm_addr, evt->mac, ETH_ALEN); } snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), - "%d", ver); + "%d", wil->fw_version); } static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, @@ -714,18 +716,39 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); } -int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype) +int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan) { - struct wmi_bcon_ctrl_cmd cmd = { + int rc; + + struct wmi_pcp_start_cmd cmd = { .bcon_interval = cpu_to_le16(bi), .network_type = wmi_nettype, .disable_sec_offload = 1, + .channel = chan, }; + struct { + struct wil6210_mbox_hdr_wmi wmi; + struct wmi_pcp_started_event evt; + } __packed reply; if (!wil->secure_pcp) cmd.disable_sec = 1; - return wmi_send(wil, WMI_BCON_CTRL_CMDID, &cmd, sizeof(cmd)); + rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd), + WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 100); + if (rc) + return rc; + + if (reply.evt.status != WMI_FW_STATUS_SUCCESS) + rc = -EINVAL; + + return rc; +} + +int wmi_pcp_stop(struct wil6210_priv *wil) +{ + return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0, + WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); } int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) @@ -796,6 +819,16 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel) return 0; } +int wmi_p2p_cfg(struct wil6210_priv *wil, int channel) +{ + struct wmi_p2p_cfg_cmd cmd = { + .discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD, + .channel = channel - 1, + }; + + return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd)); +} + int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb) { struct wmi_eapol_tx_cmd *cmd; diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 3bbf87572b07..50b8528394f4 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -36,6 +36,7 @@ enum wmi_command_id { WMI_CONNECT_CMDID = 0x0001, WMI_DISCONNECT_CMDID = 0x0003, + WMI_DISCONNECT_STA_CMDID = 0x0004, WMI_START_SCAN_CMDID = 0x0007, WMI_SET_BSS_FILTER_CMDID = 0x0009, WMI_SET_PROBED_SSID_CMDID = 0x000a, @@ -44,7 +45,6 @@ enum wmi_command_id { WMI_ADD_CIPHER_KEY_CMDID = 0x0016, WMI_DELETE_CIPHER_KEY_CMDID = 0x0017, WMI_SET_APPIE_CMDID = 0x003f, - WMI_GET_APPIE_CMDID = 0x0040, WMI_SET_WSC_STATUS_CMDID = 0x0041, WMI_PXMT_RANGE_CFG_CMDID = 0x0042, WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043, @@ -55,11 +55,11 @@ enum wmi_command_id { WMI_DEEP_ECHO_CMDID = 0x0804, WMI_CONFIG_MAC_CMDID = 0x0805, WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806, - WMI_ADD_STATION_CMDID = 0x0807, WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808, WMI_PHY_GET_STATISTICS_CMDID = 0x0809, WMI_FS_TUNE_CMDID = 0x080a, WMI_CORR_MEASURE_CMDID = 0x080b, + WMI_READ_RSSI_CMDID = 0x080c, WMI_TEMP_SENSE_CMDID = 0x080e, WMI_DC_CALIB_CMDID = 0x080f, WMI_SEND_TONE_CMDID = 0x0810, @@ -75,9 +75,9 @@ enum wmi_command_id { MAC_IO_STATIC_PARAMS_CMDID = 0x081b, MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c, WMI_SILENT_RSSI_CALIB_CMDID = 0x081d, + WMI_RF_RX_TEST_CMDID = 0x081e, WMI_CFG_RX_CHAIN_CMDID = 0x0820, WMI_VRING_CFG_CMDID = 0x0821, - WMI_RX_ON_CMDID = 0x0822, WMI_VRING_BA_EN_CMDID = 0x0823, WMI_VRING_BA_DIS_CMDID = 0x0824, WMI_RCP_ADDBA_RESP_CMDID = 0x0825, @@ -87,7 +87,6 @@ enum wmi_command_id { WMI_SET_PCP_CHANNEL_CMDID = 0x0829, WMI_GET_PCP_CHANNEL_CMDID = 0x082a, WMI_SW_TX_REQ_CMDID = 0x082b, - WMI_RX_OFF_CMDID = 0x082c, WMI_READ_MAC_RXQ_CMDID = 0x0830, WMI_READ_MAC_TXQ_CMDID = 0x0831, WMI_WRITE_MAC_RXQ_CMDID = 0x0832, @@ -112,6 +111,18 @@ enum wmi_command_id { WMI_FLASH_READ_CMDID = 0x0902, WMI_FLASH_WRITE_CMDID = 0x0903, WMI_SECURITY_UNIT_TEST_CMDID = 0x0904, + /*P2P*/ + WMI_P2P_CFG_CMDID = 0x0910, + WMI_PORT_ALLOCATE_CMDID = 0x0911, + WMI_PORT_DELETE_CMDID = 0x0912, + WMI_POWER_MGMT_CFG_CMDID = 0x0913, + WMI_START_LISTEN_CMDID = 0x0914, + WMI_START_SEARCH_CMDID = 0x0915, + WMI_DISCOVERY_START_CMDID = 0x0916, + WMI_DISCOVERY_STOP_CMDID = 0x0917, + WMI_PCP_START_CMDID = 0x0918, + WMI_PCP_STOP_CMDID = 0x0919, + WMI_GET_PCP_FACTOR_CMDID = 0x091b, WMI_SET_MAC_ADDRESS_CMDID = 0xf003, WMI_ABORT_SCAN_CMDID = 0xf007, @@ -131,18 +142,6 @@ enum wmi_command_id { * Commands data structures */ -/* - * Frame Types - */ -enum wmi_mgmt_frame_type { - WMI_FRAME_BEACON = 0, - WMI_FRAME_PROBE_REQ = 1, - WMI_FRAME_PROBE_RESP = 2, - WMI_FRAME_ASSOC_REQ = 3, - WMI_FRAME_ASSOC_RESP = 4, - WMI_NUM_MGMT_FRAME, -}; - /* * WMI_CONNECT_CMDID */ @@ -184,7 +183,7 @@ enum wmi_crypto_type { enum wmi_connect_ctrl_flag_bits { WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, WMI_CONNECT_SEND_REASSOC = 0x0002, - WMI_CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, + WMI_CONNECT_IGNORE_WPA_GROUP_CIPHER = 0x0004, WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008, WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010, WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020, @@ -212,6 +211,13 @@ struct wmi_connect_cmd { u8 reserved1[2]; } __packed; +/* + * WMI_DISCONNECT_STA_CMDID + */ +struct wmi_disconnect_sta_cmd { + u8 dst_mac[WMI_MAC_LEN]; + __le16 disconnect_reason; +} __packed; /* * WMI_RECONNECT_CMDID @@ -289,10 +295,12 @@ struct wmi_delete_cipher_key_cmd { enum wmi_scan_type { WMI_LONG_SCAN = 0, WMI_SHORT_SCAN = 1, + WMI_PBC_SCAN = 2, }; struct wmi_start_scan_cmd { u8 reserved[8]; + __le32 home_dwell_time; /* Max duration in the home channel(ms) */ __le32 force_scan_interval; /* Time interval between scans (ms)*/ u8 scan_type; /* wmi_scan_type */ @@ -309,7 +317,7 @@ struct wmi_start_scan_cmd { /* * WMI_SET_PROBED_SSID_CMDID */ -#define MAX_PROBED_SSID_INDEX (15) +#define MAX_PROBED_SSID_INDEX (3) enum wmi_ssid_flag { WMI_SSID_FLAG_DISABLE = 0, /* disables entry */ @@ -328,6 +336,20 @@ struct wmi_probed_ssid_cmd { * WMI_SET_APPIE_CMDID * Add Application specified IE to a management frame */ +#define WMI_MAX_IE_LEN (1024) + +/* + * Frame Types + */ +enum wmi_mgmt_frame_type { + WMI_FRAME_BEACON = 0, + WMI_FRAME_PROBE_REQ = 1, + WMI_FRAME_PROBE_RESP = 2, + WMI_FRAME_ASSOC_REQ = 3, + WMI_FRAME_ASSOC_RESP = 4, + WMI_NUM_MGMT_FRAME, +}; + struct wmi_set_appie_cmd { u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */ u8 reserved; @@ -335,13 +357,18 @@ struct wmi_set_appie_cmd { u8 ie_info[0]; } __packed; -#define WMI_MAX_IE_LEN (1024) +/* + * WMI_PXMT_RANGE_CFG_CMDID + */ struct wmi_pxmt_range_cfg_cmd { u8 dst_mac[WMI_MAC_LEN]; __le16 range; } __packed; +/* + * WMI_PXMT_SNR2_RANGE_CFG_CMDID + */ struct wmi_pxmt_snr2_range_cfg_cmd { s8 snr2range_arr[WMI_PROX_RANGE_NUM-1]; } __packed; @@ -359,6 +386,23 @@ struct wmi_rf_mgmt_cmd { __le32 rf_mgmt_type; } __packed; + +/* + * WMI_RF_RX_TEST_CMDID + */ +struct wmi_rf_rx_test_cmd { + __le32 sector; +} __packed; + +/* + * WMI_CORR_MEASURE_CMDID + */ +struct wmi_corr_measure_cmd { + s32 freq_mhz; + __le32 length_samples; + __le32 iterations; +} __packed; + /* * WMI_SET_SSID_CMDID */ @@ -388,6 +432,74 @@ struct wmi_bcon_ctrl_cmd { u8 disable_sec; } __packed; + +/******* P2P ***********/ + +/* + * WMI_PORT_ALLOCATE_CMDID + */ +enum wmi_port_role { + WMI_PORT_STA = 0, + WMI_PORT_PCP = 1, + WMI_PORT_AP = 2, + WMI_PORT_P2P_DEV = 3, + WMI_PORT_P2P_CLIENT = 4, + WMI_PORT_P2P_GO = 5, +}; + +struct wmi_port_allocate_cmd { + u8 mac[WMI_MAC_LEN]; + u8 port_role; + u8 midid; +} __packed; + +/* + * WMI_PORT_DELETE_CMDID + */ +struct wmi_delete_port_cmd { + u8 mid; + u8 reserved[3]; +} __packed; + +/* + * WMI_P2P_CFG_CMDID + */ +enum wmi_discovery_mode { + WMI_DISCOVERY_MODE_NON_OFFLOAD = 0, + WMI_DISCOVERY_MODE_OFFLOAD = 1, +}; + +struct wmi_p2p_cfg_cmd { + u8 discovery_mode; /* wmi_discovery_mode */ + u8 channel; + __le16 bcon_interval; /* base to listen/search duration calculation */ +} __packed; + +/* + * WMI_POWER_MGMT_CFG_CMDID + */ +enum wmi_power_source_type { + WMI_POWER_SOURCE_BATTERY = 0, + WMI_POWER_SOURCE_OTHER = 1, +}; + +struct wmi_power_mgmt_cfg_cmd { + u8 power_source; /* wmi_power_source_type */ + u8 reserved[3]; +} __packed; + +/* + * WMI_PCP_START_CMDID + */ +struct wmi_pcp_start_cmd { + __le16 bcon_interval; + u8 reserved0[10]; + u8 network_type; + u8 channel; + u8 disable_sec_offload; + u8 disable_sec; +} __packed; + /* * WMI_SW_TX_REQ_CMDID */ @@ -435,16 +547,17 @@ enum wmi_vring_cfg_schd_params_priority { WMI_SCH_PRIO_HIGH = 1, }; +#define CIDXTID_CID_POS (0) +#define CIDXTID_CID_LEN (4) +#define CIDXTID_CID_MSK (0xF) +#define CIDXTID_TID_POS (4) +#define CIDXTID_TID_LEN (4) +#define CIDXTID_TID_MSK (0xF0) + struct wmi_vring_cfg { struct wmi_sw_ring_cfg tx_sw_ring; u8 ringid; /* 0-23 vrings */ - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; u8 encap_trans_type; @@ -501,8 +614,14 @@ struct wmi_vring_ba_dis_cmd { */ struct wmi_notify_req_cmd { u8 cid; - u8 reserved[3]; + u8 year; + u8 month; + u8 day; __le32 interval_usec; + u8 hour; + u8 minute; + u8 second; + u8 miliseconds; } __packed; /* @@ -548,6 +667,11 @@ enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type { WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2, }; +enum wmi_cfg_rx_chain_cmd_reorder_type { + WMI_RX_HW_REORDER = 0, + WMI_RX_SW_REORDER = 1, +}; + struct wmi_cfg_rx_chain_cmd { __le32 action; struct wmi_sw_ring_cfg rx_sw_ring; @@ -596,7 +720,8 @@ struct wmi_cfg_rx_chain_cmd { __le16 wb_thrsh; __le32 itr_value; __le16 host_thrsh; - u8 reserved[2]; + u8 reorder_type; + u8 reserved; struct wmi_sniffer_cfg sniffer_cfg; } __packed; @@ -604,15 +729,7 @@ struct wmi_cfg_rx_chain_cmd { * WMI_RCP_ADDBA_RESP_CMDID */ struct wmi_rcp_addba_resp_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 dialog_token; __le16 status_code; __le16 ba_param_set; /* ieee80211_ba_parameterset field to send */ @@ -623,15 +740,7 @@ struct wmi_rcp_addba_resp_cmd { * WMI_RCP_DELBA_CMDID */ struct wmi_rcp_delba_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 reserved; __le16 reason; } __packed; @@ -640,15 +749,7 @@ struct wmi_rcp_delba_cmd { * WMI_RCP_ADDBA_REQ_CMDID */ struct wmi_rcp_addba_req_cmd { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 dialog_token; /* ieee80211_ba_parameterset field as it received */ __le16 ba_param_set; @@ -665,7 +766,6 @@ struct wmi_set_mac_address_cmd { u8 reserved[2]; } __packed; - /* * WMI_EAPOL_TX_CMDID */ @@ -691,6 +791,17 @@ struct wmi_echo_cmd { __le32 value; } __packed; +/* + * WMI_TEMP_SENSE_CMDID + * + * Measure MAC and radio temperatures + */ +struct wmi_temp_sense_cmd { + __le32 measure_marlon_m_en; + __le32 measure_marlon_r_en; +} __packed; + + /* * WMI Events */ @@ -699,7 +810,6 @@ struct wmi_echo_cmd { * List of Events (target to host) */ enum wmi_event_id { - WMI_IMM_RSP_EVENTID = 0x0000, WMI_READY_EVENTID = 0x1001, WMI_CONNECT_EVENTID = 0x1002, WMI_DISCONNECT_EVENTID = 0x1003, @@ -709,13 +819,9 @@ enum wmi_event_id { WMI_FW_READY_EVENTID = 0x1801, WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200, WMI_ECHO_RSP_EVENTID = 0x1803, - WMI_CONFIG_MAC_DONE_EVENTID = 0x1805, - WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806, - WMI_ADD_STATION_DONE_EVENTID = 0x1807, - WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808, - WMI_PHY_GET_STATISTICS_EVENTID = 0x1809, WMI_FS_TUNE_DONE_EVENTID = 0x180a, - WMI_CORR_MEASURE_DONE_EVENTID = 0x180b, + WMI_CORR_MEASURE_EVENTID = 0x180b, + WMI_READ_RSSI_EVENTID = 0x180c, WMI_TEMP_SENSE_DONE_EVENTID = 0x180e, WMI_DC_CALIB_DONE_EVENTID = 0x180f, WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811, @@ -727,10 +833,9 @@ enum wmi_event_id { WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819, WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a, WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d, - + WMI_RF_RX_TEST_DONE_EVENTID = 0x181e, WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820, WMI_VRING_CFG_DONE_EVENTID = 0x1821, - WMI_RX_ON_DONE_EVENTID = 0x1822, WMI_BA_STATUS_EVENTID = 0x1823, WMI_RCP_ADDBA_REQ_EVENTID = 0x1824, WMI_ADDBA_RESP_SENT_EVENTID = 0x1825, @@ -738,7 +843,6 @@ enum wmi_event_id { WMI_GET_SSID_EVENTID = 0x1828, WMI_GET_PCP_CHANNEL_EVENTID = 0x182a, WMI_SW_TX_COMPLETE_EVENTID = 0x182b, - WMI_RX_OFF_DONE_EVENTID = 0x182c, WMI_READ_MAC_RXQ_EVENTID = 0x1830, WMI_READ_MAC_TXQ_EVENTID = 0x1831, @@ -765,7 +869,16 @@ enum wmi_event_id { WMI_UNIT_TEST_EVENTID = 0x1900, WMI_FLASH_READ_DONE_EVENTID = 0x1902, WMI_FLASH_WRITE_DONE_EVENTID = 0x1903, - + /*P2P*/ + WMI_PORT_ALLOCATED_EVENTID = 0x1911, + WMI_PORT_DELETED_EVENTID = 0x1912, + WMI_LISTEN_STARTED_EVENTID = 0x1914, + WMI_SEARCH_STARTED_EVENTID = 0x1915, + WMI_DISCOVERY_STARTED_EVENTID = 0x1916, + WMI_DISCOVERY_STOPPED_EVENTID = 0x1917, + WMI_PCP_STARTED_EVENTID = 0x1918, + WMI_PCP_STOPPED_EVENTID = 0x1919, + WMI_PCP_FACTOR_EVENTID = 0x191a, WMI_SET_CHANNEL_EVENTID = 0x9000, WMI_ASSOC_REQ_EVENTID = 0x9001, WMI_EAPOL_RX_EVENTID = 0x9002, @@ -777,6 +890,12 @@ enum wmi_event_id { * Events data structures */ + +enum wmi_fw_status { + WMI_FW_STATUS_SUCCESS, + WMI_FW_STATUS_FAILURE, +}; + /* * WMI_RF_MGMT_STATUS_EVENTID */ @@ -857,7 +976,7 @@ struct wmi_ready_event { __le32 abi_version; u8 mac[WMI_MAC_LEN]; u8 phy_capability; /* enum wmi_phy_capability */ - u8 reserved; + u8 numof_additional_mids; } __packed; /* @@ -876,6 +995,8 @@ struct wmi_notify_req_done_event { __le16 other_rx_sector; __le16 other_tx_sector; __le16 range; + u8 sqi; + u8 reserved[3]; } __packed; /* @@ -951,27 +1072,15 @@ struct wmi_vring_ba_status_event { * WMI_DELBA_EVENTID */ struct wmi_delba_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 from_initiator; __le16 reason; } __packed; + /* * WMI_VRING_CFG_DONE_EVENTID */ -enum wmi_vring_cfg_done_event_status { - WMI_VRING_CFG_SUCCESS = 0, - WMI_VRING_CFG_FAILURE = 1, -}; - struct wmi_vring_cfg_done_event { u8 ringid; u8 status; @@ -982,21 +1091,8 @@ struct wmi_vring_cfg_done_event { /* * WMI_ADDBA_RESP_SENT_EVENTID */ -enum wmi_rcp_addba_resp_sent_event_status { - WMI_ADDBA_SUCCESS = 0, - WMI_ADDBA_FAIL = 1, -}; - struct wmi_rcp_addba_resp_sent_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 reserved; __le16 status; } __packed; @@ -1005,15 +1101,7 @@ struct wmi_rcp_addba_resp_sent_event { * WMI_RCP_ADDBA_REQ_EVENTID */ struct wmi_rcp_addba_req_event { - - #define CIDXTID_CID_POS (0) - #define CIDXTID_CID_LEN (4) - #define CIDXTID_CID_MSK (0xF) - #define CIDXTID_TID_POS (4) - #define CIDXTID_TID_LEN (4) - #define CIDXTID_TID_MSK (0xF0) u8 cidxtid; - u8 dialog_token; __le16 ba_param_set; /* ieee80211_ba_parameterset as it received */ __le16 ba_timeout; @@ -1055,6 +1143,7 @@ struct wmi_data_port_open_event { u8 reserved[3]; } __packed; + /* * WMI_GET_PCP_CHANNEL_EVENTID */ @@ -1063,6 +1152,54 @@ struct wmi_get_pcp_channel_event { u8 reserved[3]; } __packed; + +/* +* WMI_PORT_ALLOCATED_EVENTID +*/ +struct wmi_port_allocated_event { + u8 status; /* wmi_fw_status */ + u8 reserved[3]; +} __packed; + +/* +* WMI_PORT_DELETED_EVENTID +*/ +struct wmi_port_deleted_event { + u8 status; /* wmi_fw_status */ + u8 reserved[3]; +} __packed; + +/* + * WMI_LISTEN_STARTED_EVENTID + */ +struct wmi_listen_started_event { + u8 status; /* wmi_fw_status */ + u8 reserved[3]; +} __packed; + +/* + * WMI_SEARCH_STARTED_EVENTID + */ +struct wmi_search_started_event { + u8 status; /* wmi_fw_status */ + u8 reserved[3]; +} __packed; + +/* + * WMI_PCP_STARTED_EVENTID + */ +struct wmi_pcp_started_event { + u8 status; /* wmi_fw_status */ + u8 reserved[3]; +} __packed; + +/* + * WMI_PCP_FACTOR_EVENTID + */ +struct wmi_pcp_factor_event { + __le32 pcp_factor; +} __packed; + /* * WMI_SW_TX_COMPLETE_EVENTID */ @@ -1077,6 +1214,23 @@ struct wmi_sw_tx_complete_event { u8 reserved[3]; } __packed; +/* + * WMI_CORR_MEASURE_EVENTID + */ +struct wmi_corr_measure_event { + s32 i; + s32 q; + s32 image_i; + s32 image_q; +} __packed; + +/* + * WMI_READ_RSSI_EVENTID + */ +struct wmi_read_rssi_event { + __le32 ina_rssi_adc_dbm; +} __packed; + /* * WMI_GET_SSID_EVENTID */ @@ -1091,7 +1245,8 @@ struct wmi_get_ssid_event { struct wmi_rx_mgmt_info { u8 mcs; s8 snr; - __le16 range; + u8 range; + u8 sqi; __le16 stype; __le16 status; __le32 len; @@ -1113,4 +1268,14 @@ struct wmi_echo_event { __le32 echoed_value; } __packed; +/* + * WMI_TEMP_SENSE_DONE_EVENTID + * + * Measure MAC and radio temperatures + */ +struct wmi_temp_sense_done_event { + __le32 marlon_m_t1000; + __le32 marlon_r_t1000; +} __packed; + #endif /* __WILOCITY_WMI_H__ */ -- cgit From 1a2780e0f3bef7288190e1107350d085c49e3d33 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Wed, 13 Mar 2013 14:12:51 +0200 Subject: wil6210: temperature measurement Firmware got support for temperature measurement. There are 2 temperature sensors: MAC and radio "not available" temperature - reported by FW as 0 or ~0 Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/debugfs.c | 44 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 25 +++++++++++++++++ 3 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 1e709bfb63a3..4be07f5e22b9 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -521,6 +521,49 @@ static const struct file_operations fops_ssid = { .open = simple_open, }; +/*---------temp------------*/ +static void print_temp(struct seq_file *s, const char *prefix, u32 t) +{ + switch (t) { + case 0: + case ~(u32)0: + seq_printf(s, "%s N/A\n", prefix); + break; + default: + seq_printf(s, "%s %d.%03d\n", prefix, t / 1000, t % 1000); + break; + } +} + +static int wil_temp_debugfs_show(struct seq_file *s, void *data) +{ + struct wil6210_priv *wil = s->private; + u32 t_m, t_r; + + int rc = wmi_get_temperature(wil, &t_m, &t_r); + if (rc) { + seq_printf(s, "Failed\n"); + return 0; + } + + print_temp(s, "MAC temperature :", t_m); + print_temp(s, "Radio temperature :", t_r); + + return 0; +} + +static int wil_temp_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, wil_temp_debugfs_show, inode->i_private); +} + +static const struct file_operations fops_temp = { + .open = wil_temp_seq_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek, +}; + /*----------------*/ int wil6210_debugfs_init(struct wil6210_priv *wil) { @@ -555,6 +598,7 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset); + debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp); wil->rgf_blob.data = (void * __force)wil->csr + 0; wil->rgf_blob.size = 0xa000; diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 3bbd86d54ba1..8f76ecd8a7e5 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -329,6 +329,7 @@ int wmi_echo(struct wil6210_priv *wil); int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); int wmi_p2p_cfg(struct wil6210_priv *wil, int channel); +int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); int wil6210_init_irq(struct wil6210_priv *wil, int irq); void wil6210_fini_irq(struct wil6210_priv *wil, int irq); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 706ee9d86e61..45b04e383f9a 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -962,6 +962,31 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) return rc; } +int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r) +{ + int rc; + struct wmi_temp_sense_cmd cmd = { + .measure_marlon_m_en = cpu_to_le32(!!t_m), + .measure_marlon_r_en = cpu_to_le32(!!t_r), + }; + struct { + struct wil6210_mbox_hdr_wmi wmi; + struct wmi_temp_sense_done_event evt; + } __packed reply; + + rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd), + WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); + if (rc) + return rc; + + if (t_m) + *t_m = le32_to_cpu(reply.evt.marlon_m_t1000); + if (t_r) + *t_r = le32_to_cpu(reply.evt.marlon_r_t1000); + + return 0; +} + void wmi_event_flush(struct wil6210_priv *wil) { struct pending_wmi_event *evt, *t; -- cgit From 476069224d3584692563a571768cf3ccf2fee8e0 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sat, 9 Mar 2013 13:43:49 +0100 Subject: b43: HT-PHY: rename AFE defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It you take a look at N-PHY analog switch function it touches every core on the chipset. It seems HT-PHY does they same, it just has 3 cores instead of 2 (which make sense since BCM4331 is 3x3). Rename AFE defines to include core id. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 38 +++++++++++++++++++------------------- drivers/net/wireless/b43/phy_ht.h | 12 ++++++------ 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 3719a8884c1e..df07c83dec89 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -176,10 +176,10 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev) { u8 i; - const u16 ctl_regs[3][2] = { - { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 }, - { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 }, - { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6}, + static const u16 ctl_regs[3][2] = { + { B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 }, + { B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 }, + { B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3}, }; for (i = 0; i < 3; i++) { @@ -362,9 +362,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0); + b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0); + b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0); + b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0); b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20); b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20); @@ -511,19 +511,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) { if (on) { - b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000); } else { - b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd); } } diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 6544c4293b34..60824faa823d 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -36,12 +36,12 @@ #define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) -#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) -#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) -#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) -#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) -#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) -#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) +#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110) +#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111) +#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114) +#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115) +#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118) +#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119) /* Values for PHY registers used on channel switching */ -- cgit From b372afaed5c1392dd6be3bbfea15a411d7ceb54d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:16 +0100 Subject: b43: HT-PHY: add classifier control function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After comparing operations on reg 0xB on N and HT it seems to be the same register with similar ops. Implement them for HT-PHY. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 36 +++++++++++++++++++++++++++++++----- drivers/net/wireless/b43/phy_ht.h | 6 ++++++ 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index df07c83dec89..05790fa81bc1 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -157,6 +157,22 @@ static void b43_radio_2059_init(struct b43_wldev *dev) * Various PHY ops **************************************************/ +static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val) +{ + u16 tmp; + u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN | + B43_PHY_HT_CLASS_CTL_OFDM_EN | + B43_PHY_HT_CLASS_CTL_WAITED_EN; + + tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL); + tmp &= allowed; + tmp &= ~mask; + tmp |= (val & mask); + b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp); + + return tmp; +} + static void b43_phy_ht_zero_extg(struct b43_wldev *dev) { u8 i, j; @@ -264,7 +280,15 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); - /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */ + if (new_channel->hw_value == 14) { + b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN, 0); + b43_phy_set(dev, B43_PHY_HT_TEST, 0x0800); + } else { + b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN, + B43_PHY_HT_CLASS_CTL_OFDM_EN); + if (new_channel->band == IEEE80211_BAND_2GHZ) + b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840); + } /* TODO: separated function? */ for (i = 0; i < 3; i++) { @@ -376,8 +400,11 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) if (0) /* TODO: condition */ ; /* TODO: PHY op on reg 0x217 */ - b43_phy_read(dev, 0xb0); /* TODO: what for? */ - b43_phy_set(dev, 0xb0, 0x1); + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) + b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, 0); + else + b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, + B43_PHY_HT_CLASS_CTL_CCK_EN); b43_phy_set(dev, 0xb1, 0x91); b43_phy_write(dev, 0x32f, 0x0003); @@ -456,9 +483,8 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); - /* TODO: PHY op on reg 0xb0 */ - /* TODO: Should we restore it? Or store it in global PHY info? */ + b43_phy_ht_classifier(dev, 0, 0); b43_phy_ht_read_clip_detection(dev, clip_state); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 60824faa823d..52603affa2d6 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -12,6 +12,10 @@ #define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ #define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ #define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ +#define B43_PHY_HT_CLASS_CTL 0x0B0 /* Classifier control */ +#define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */ +#define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */ +#define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */ #define B43_PHY_HT_BW1 0x1CE #define B43_PHY_HT_BW2 0x1CF #define B43_PHY_HT_BW3 0x1D0 @@ -43,6 +47,8 @@ #define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118) #define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119) +#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) + /* Values for PHY registers used on channel switching */ struct b43_phy_ht_channeltab_e_phy { -- cgit From f6099f89e6932a98db82ae72272ef9268b14e6db Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:17 +0100 Subject: b43: HT-PHY: move TX fix to the separated function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On N-PHY after B43_PHY_B_TEST operation there is a call to TX power fix function which iterates over available cores. It matches our HT-PHY code which means it's probably also some TX fix. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 46 ++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 05790fa81bc1..72356148f689 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -255,6 +255,32 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); } +/************************************************** + * Tx/Rx + **************************************************/ + +static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev) +{ + int i; + + for (i = 0; i < 3; i++) { + u16 mask; + u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); + + if (0) /* FIXME */ + mask = 0x2 << (i * 4); + else + mask = 0; + b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask); + + b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); + b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), + tmp & 0xFF); + b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)), + tmp & 0xFF); + } +} + /************************************************** * Channel switching ops. **************************************************/ @@ -264,7 +290,6 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, struct ieee80211_channel *new_channel) { bool old_band_5ghz; - u8 i; old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { @@ -290,23 +315,8 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840); } - /* TODO: separated function? */ - for (i = 0; i < 3; i++) { - u16 mask; - u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); - - if (0) /* FIXME */ - mask = 0x2 << (i * 4); - else - mask = 0; - b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask); - - b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); - b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), - tmp & 0xFF); - b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)), - tmp & 0xFF); - } + if (1) /* TODO: On N it's for early devices only, what about HT? */ + b43_phy_ht_tx_power_fix(dev); b43_phy_write(dev, 0x017e, 0x3830); } -- cgit From 2dacfe7c107170f060b09623d36b945ee1bfb8f3 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:18 +0100 Subject: b43: HT-PHY: implement spurious tone avoidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On N-PHY it's also done after TX power fix, so it was easy to spot. Unfortunately the MMIO logs I have from ndsiwrapper include channels 1-12 only, so enabling code for 13 and 14 is just a N-PHY-based guess. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 72356148f689..558f77c393e0 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -285,6 +285,24 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev) * Channel switching ops. **************************************************/ +static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, + struct ieee80211_channel *new_channel) +{ + struct bcma_device *core = dev->dev->bdev; + int spuravoid = 0; + + /* Check for 13 and 14 is just a guess, we don't have enough logs. */ + if (new_channel->hw_value == 13 || new_channel->hw_value == 14) + spuravoid = 1; + bcma_core_pll_ctl(core, B43_BCMA_CLKCTLST_PHY_PLL_REQ, 0, false); + bcma_pmu_spuravoid_pllupdate(&core->bus->drv_cc, spuravoid); + bcma_core_pll_ctl(core, + B43_BCMA_CLKCTLST_80211_PLL_REQ | + B43_BCMA_CLKCTLST_PHY_PLL_REQ, + B43_BCMA_CLKCTLST_80211_PLL_ST | + B43_BCMA_CLKCTLST_PHY_PLL_ST, false); +} + static void b43_phy_ht_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_phy *e, struct ieee80211_channel *new_channel) @@ -318,6 +336,8 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, if (1) /* TODO: On N it's for early devices only, what about HT? */ b43_phy_ht_tx_power_fix(dev); + b43_phy_ht_spur_avoid(dev, new_channel); + b43_phy_write(dev, 0x017e, 0x3830); } -- cgit From d7bb7ca8e5613991b522f21b74bb67447a36eacd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:19 +0100 Subject: b43: HT-PHY: implement MAC reclocking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 558f77c393e0..9d2a7e545bf6 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -290,6 +290,7 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, { struct bcma_device *core = dev->dev->bdev; int spuravoid = 0; + u16 tmp; /* Check for 13 and 14 is just a guess, we don't have enough logs. */ if (new_channel->hw_value == 13 || new_channel->hw_value == 14) @@ -301,6 +302,23 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, B43_BCMA_CLKCTLST_PHY_PLL_REQ, B43_BCMA_CLKCTLST_80211_PLL_ST | B43_BCMA_CLKCTLST_PHY_PLL_ST, false); + + /* Values has been taken from wlc_bmac_switch_macfreq comments */ + switch (spuravoid) { + case 2: /* 126MHz */ + tmp = 0x2082; + break; + case 1: /* 123MHz */ + tmp = 0x5341; + break; + default: /* 120MHz */ + tmp = 0x8889; + } + + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); + + /* TODO: reset PLL */ } static void b43_phy_ht_channel_setup(struct b43_wldev *dev, -- cgit From 4cce0956239d324aca045be2b589c43b9baa561d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:20 +0100 Subject: b43: HT-PHY: implement CCA reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was just another similar-to-N-PHY and easy-to-track routine: write32 0xb0601408 <- 0x00002057 phy_read(0x0001) -> 0x0000 phy_write(0x0001) <- 0x4000 phy_write(0x0001) <- 0x0000 write32 0xb0601408 <- 0x00002055 (b43_phy_ht_force_rf_sequence was moved up unmodified) Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 68 +++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 9d2a7e545bf6..23a46c667974 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -153,6 +153,31 @@ static void b43_radio_2059_init(struct b43_wldev *dev) b43_radio_mask(dev, 0x11, ~0x0008); } +/************************************************** + * RF + **************************************************/ + +static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq) +{ + u8 i; + + u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE); + b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3); + + b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq); + for (i = 0; i < 200; i++) { + if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) { + i = 0; + break; + } + msleep(1); + } + if (i) + b43err(dev->wl, "Forcing RF sequence timeout\n"); + + b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); +} + /************************************************** * Various PHY ops **************************************************/ @@ -173,6 +198,20 @@ static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val) return tmp; } +static void b43_phy_ht_reset_cca(struct b43_wldev *dev) +{ + u16 bbcfg; + + b43_phy_force_clock(dev, true); + bbcfg = b43_phy_read(dev, B43_PHY_HT_BBCFG); + b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg | B43_PHY_HT_BBCFG_RSTCCA); + udelay(1); + b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg & ~B43_PHY_HT_BBCFG_RSTCCA); + b43_phy_force_clock(dev, false); + + b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); +} + static void b43_phy_ht_zero_extg(struct b43_wldev *dev) { u8 i, j; @@ -209,27 +248,6 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev) } } -static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq) -{ - u8 i; - - u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE); - b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3); - - b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq); - for (i = 0; i < 200; i++) { - if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) { - i = 0; - break; - } - msleep(1); - } - if (i) - b43err(dev->wl, "Forcing RF sequence timeout\n"); - - b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); -} - static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) { clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES); @@ -319,6 +337,14 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); /* TODO: reset PLL */ + + if (spuravoid) + b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX); + else + b43_phy_mask(dev, B43_PHY_HT_BBCFG, + ~B43_PHY_HT_BBCFG_RSTRX & 0xFFFF); + + b43_phy_ht_reset_cca(dev); } static void b43_phy_ht_channel_setup(struct b43_wldev *dev, -- cgit From a51ab25811beef67bdd0ba2c5dd4b03e47948aa1 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sat, 9 Mar 2013 13:49:01 +0100 Subject: b43: HT-PHY: implement PA override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 22 ++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 5 +++++ 2 files changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 23a46c667974..1998dca73faa 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -178,6 +178,26 @@ static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq) b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); } +static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable) +{ + struct b43_phy_ht *htphy = dev->phy.ht; + static const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1, + B43_PHY_HT_RF_CTL_INT_C2, + B43_PHY_HT_RF_CTL_INT_C3 }; + int i; + + if (enable) { + for (i = 0; i < 3; i++) + b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]); + } else { + for (i = 0; i < 3; i++) + htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]); + /* TODO: Does 5GHz band use different value (not 0x0400)? */ + for (i = 0; i < 3; i++) + b43_phy_write(dev, regs[i], 0x0400); + } +} + /************************************************** * Various PHY ops **************************************************/ @@ -554,8 +574,10 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) b43_mac_phy_clock_set(dev, true); + b43_phy_ht_pa_override(dev, false); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); + b43_phy_ht_pa_override(dev, true); /* TODO: Should we restore it? Or store it in global PHY info? */ b43_phy_ht_classifier(dev, 0, 0); diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 52603affa2d6..684807c2f125 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -40,6 +40,10 @@ #define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) +#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c) +#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c) +#define B43_PHY_HT_RF_CTL_INT_C3 B43_PHY_EXTG(0x08c) + #define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110) #define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111) #define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114) @@ -62,6 +66,7 @@ struct b43_phy_ht_channeltab_e_phy { struct b43_phy_ht { + u16 rf_ctl_int_save[3]; }; -- cgit From 60e8fb9233e13e98b13a380ecc1cc05515e6e34c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sat, 9 Mar 2013 13:52:12 +0100 Subject: b43: HT-PHY: implement controlling TX power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't enable it until we have (almost?) whole TX power management figured out. It's similar to the N-PHY, the difference is that we call a "fix" *before* disabling power control. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 55 +++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 13 +++++++++ 2 files changed, 68 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 1998dca73faa..1663551f9428 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -319,6 +319,46 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev) } } +#if 0 +static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) +{ + struct b43_phy_ht *phy_ht = dev->phy.ht; + u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF | + B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN | + B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN; + static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1, + B43_PHY_HT_TXPCTL_CMD_C2, + B43_PHY_HT_TXPCTL_CMD_C3 }; + int i; + + if (!enable) { + if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { + /* We disable enabled TX pwr ctl, save it's state */ + /* + * TODO: find the registers. On N-PHY they were 0x1ed + * and 0x1ee, we need 3 such a registers for HT-PHY + */ + } + b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); + } else { + b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + for (i = 0; i < 3; i++) + b43_phy_write(dev, cmd_regs[i], 0x32); + } + + for (i = 0; i < 3; i++) + if (phy_ht->tx_pwr_idx[i] <= + B43_PHY_HT_TXPCTL_CMD_C1_INIT) + b43_phy_write(dev, cmd_regs[i], + phy_ht->tx_pwr_idx[i]); + } + + phy_ht->tx_pwr_ctl = enable; +} +#endif + /************************************************** * Channel switching ops. **************************************************/ @@ -455,14 +495,21 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; struct b43_phy_ht *phy_ht = phy->ht; + int i; memset(phy_ht, 0, sizeof(*phy_ht)); + + phy_ht->tx_pwr_ctl = true; + for (i = 0; i < 3; i++) + phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1; } static int b43_phy_ht_op_init(struct b43_wldev *dev) { + struct b43_phy_ht *phy_ht = dev->phy.ht; u16 tmp; u16 clip_state[3]; + bool saved_tx_pwr_ctl; if (dev->dev->bus_type != B43_BUS_BCMA) { b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n"); @@ -589,6 +636,14 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0), B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late); + saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl; + b43_phy_ht_tx_power_fix(dev); +#if 0 + b43_phy_ht_tx_power_ctl(dev, false); + /* TODO */ + b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); +#endif + return 0; } diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 684807c2f125..bc7a43f58c61 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -22,6 +22,13 @@ #define B43_PHY_HT_BW4 0x1D1 #define B43_PHY_HT_BW5 0x1D2 #define B43_PHY_HT_BW6 0x1D3 +#define B43_PHY_HT_TXPCTL_CMD_C1 0x1E7 /* TX power control command */ +#define B43_PHY_HT_TXPCTL_CMD_C1_INIT 0x007F /* Init */ +#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */ +#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */ +#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */ +#define B43_PHY_HT_TXPCTL_CMD_C2 0x222 +#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F #define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E) #define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E) @@ -51,6 +58,9 @@ #define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118) #define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119) +#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164) +#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F + #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) @@ -67,6 +77,9 @@ struct b43_phy_ht_channeltab_e_phy { struct b43_phy_ht { u16 rf_ctl_int_save[3]; + + bool tx_pwr_ctl; + u8 tx_pwr_idx[3]; }; -- cgit From 371ec465a3589b27a81af7e5bf39b614aeab202c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:23 +0100 Subject: b43: HT-PHY: implement stopping sample tone playback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was another sequence I recognized in HT-PHY dump: phy_read(0x00c7) -> 0x0001 phy_read(0x00c3) -> 0x0000 phy_write(0x00c3) <- 0x0002 phy_read(0x00c3) -> 0x0000 phy_write(0x00c3) <- 0x0000 The difference to N-PHY is that it writes to 6 tables instead of a one (after above). Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 41 +++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 6 ++++++ 2 files changed, 47 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 1663551f9428..e511f595929c 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -293,6 +293,36 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); } +/************************************************** + * Samples + **************************************************/ + +#if 0 +static void b43_phy_ht_stop_playback(struct b43_wldev *dev) +{ + struct b43_phy_ht *phy_ht = dev->phy.ht; + u16 tmp; + int i; + + tmp = b43_phy_read(dev, B43_PHY_HT_SAMP_STAT); + if (tmp & 0x1) + b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, B43_PHY_HT_SAMP_CMD_STOP); + else if (tmp & 0x2) + b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, 0x7FFF); + + b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0x0004); + + for (i = 0; i < 3; i++) { + if (phy_ht->bb_mult_save[i] >= 0) { + b43_httab_write(dev, B43_HTTAB16(13, 0x63 + i * 4), + phy_ht->bb_mult_save[i]); + b43_httab_write(dev, B43_HTTAB16(13, 0x67 + i * 4), + phy_ht->bb_mult_save[i]); + } + } +} +#endif + /************************************************** * Tx/Rx **************************************************/ @@ -357,6 +387,13 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) phy_ht->tx_pwr_ctl = enable; } + +static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) +{ + /* TODO */ + b43_phy_ht_stop_playback(dev); + /* TODO */ +} #endif /************************************************** @@ -502,6 +539,9 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) phy_ht->tx_pwr_ctl = true; for (i = 0; i < 3; i++) phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1; + + for (i = 0; i < 3; i++) + phy_ht->bb_mult_save[i] = -1; } static int b43_phy_ht_op_init(struct b43_wldev *dev) @@ -640,6 +680,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) b43_phy_ht_tx_power_fix(dev); #if 0 b43_phy_ht_tx_power_ctl(dev, false); + b43_phy_ht_tx_power_ctl_idle_tssi(dev); /* TODO */ b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); #endif diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index bc7a43f58c61..7ec794b70f03 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -16,6 +16,10 @@ #define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */ #define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */ #define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */ +#define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */ +#define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */ +#define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */ +#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ #define B43_PHY_HT_BW1 0x1CE #define B43_PHY_HT_BW2 0x1CF #define B43_PHY_HT_BW3 0x1D0 @@ -80,6 +84,8 @@ struct b43_phy_ht { bool tx_pwr_ctl; u8 tx_pwr_idx[3]; + + s32 bb_mult_save[3]; }; -- cgit From 396535e137c969dae91c879b8533d74079bba4c2 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:24 +0100 Subject: b43: HT-PHY: implement playing sample tone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 69 +++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 5 +++ 2 files changed, 74 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index e511f595929c..22fdde613a58 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -321,6 +321,70 @@ static void b43_phy_ht_stop_playback(struct b43_wldev *dev) } } } + +static u16 b43_phy_ht_load_samples(struct b43_wldev *dev) +{ + int i; + u16 len = 20 << 3; + + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, 0x4400); + + for (i = 0; i < len; i++) { + b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, 0); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, 0); + } + + return len; +} + +static void b43_phy_ht_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, + u16 wait) +{ + struct b43_phy_ht *phy_ht = dev->phy.ht; + u16 save_seq_mode; + int i; + + for (i = 0; i < 3; i++) { + if (phy_ht->bb_mult_save[i] < 0) + phy_ht->bb_mult_save[i] = b43_httab_read(dev, B43_HTTAB16(13, 0x63 + i * 4)); + } + + b43_phy_write(dev, B43_PHY_HT_SAMP_DEP_CNT, samps - 1); + if (loops != 0xFFFF) + loops--; + b43_phy_write(dev, B43_PHY_HT_SAMP_LOOP_CNT, loops); + b43_phy_write(dev, B43_PHY_HT_SAMP_WAIT_CNT, wait); + + save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE); + b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, + B43_PHY_HT_RF_SEQ_MODE_CA_OVER); + + /* TODO: find out mask bits! Do we need more function arguments? */ + b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0); + b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0); + b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, ~0); + b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, 0x1); + + for (i = 0; i < 100; i++) { + if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & 1)) { + i = 0; + break; + } + udelay(10); + } + if (i) + b43err(dev->wl, "run samples timeout\n"); + + b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); +} + +static void b43_phy_ht_tx_tone(struct b43_wldev *dev) +{ + u16 samp; + + samp = b43_phy_ht_load_samples(dev); + b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0); +} #endif /************************************************** @@ -391,7 +455,12 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) { /* TODO */ + + b43_phy_ht_tx_tone(dev); + udelay(20); + /* TODO: poll RSSI */ b43_phy_ht_stop_playback(dev); + /* TODO */ } #endif diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 7ec794b70f03..c51795862b6d 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -19,6 +19,9 @@ #define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */ #define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */ #define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */ +#define B43_PHY_HT_SAMP_LOOP_CNT 0x0C4 /* Sample loop count */ +#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ +#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ #define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ #define B43_PHY_HT_BW1 0x1CE #define B43_PHY_HT_BW2 0x1CF @@ -39,6 +42,8 @@ #define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E) #define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000) +#define B43_PHY_HT_RF_SEQ_MODE_CA_OVER 0x0001 /* Core active override */ +#define B43_PHY_HT_RF_SEQ_MODE_TR_OVER 0x0002 /* Trigger override */ #define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003) #define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */ #define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */ -- cgit From 4409a23f6bca71d256e05d03215439d6796d9f4e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sat, 9 Mar 2013 13:56:26 +0100 Subject: b43: HT-PHY: implement RSSI polling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 96 ++++++++++++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_ht.h | 5 ++ 2 files changed, 100 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 22fdde613a58..ae9cd2978060 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -387,6 +387,92 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev) } #endif +/************************************************** + * RSSI + **************************************************/ + +#if 0 +static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, + u8 rssi_type) +{ + static const u16 ctl_regs[3][2] = { + { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, }, + { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, }, + { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, }, + }; + static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, }; + int core; + + if (core_sel == 0) { + b43err(dev->wl, "RSSI selection for core off not implemented yet\n"); + } else { + for (core = 0; core < 3; core++) { + /* Check if caller requested a one specific core */ + if ((core_sel == 1 && core != 0) || + (core_sel == 2 && core != 1) || + (core_sel == 3 && core != 2)) + continue; + + switch (rssi_type) { + case 4: + b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8); + b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10); + b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9); + b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10); + + b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1); + b43_radio_write(dev, radio_r[core] | 0x159, + 0x11); + break; + default: + b43err(dev->wl, "RSSI selection for type %d not implemented yet\n", + rssi_type); + } + } + } +} + +static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, + u8 nsamp) +{ + u16 phy_regs_values[12]; + static const u16 phy_regs_to_save[] = { + B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, + 0x848, 0x841, + B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, + 0x868, 0x861, + B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, + 0x888, 0x881, + }; + u16 tmp[3]; + int i; + + for (i = 0; i < 12; i++) + phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]); + + b43_phy_ht_rssi_select(dev, 5, type); + + for (i = 0; i < 6; i++) + buf[i] = 0; + + for (i = 0; i < nsamp; i++) { + tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1); + tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2); + tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3); + + buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2; + buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2; + buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2; + buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2; + buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2; + buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2; + } + + for (i = 0; i < 12; i++) + b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]); +} +#endif + /************************************************** * Tx/Rx **************************************************/ @@ -454,12 +540,20 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) { + struct b43_phy_ht *phy_ht = dev->phy.ht; + s32 rssi_buf[6]; + /* TODO */ b43_phy_ht_tx_tone(dev); udelay(20); - /* TODO: poll RSSI */ + b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1); b43_phy_ht_stop_playback(dev); + b43_phy_ht_reset_cca(dev); + + phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff; + phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff; + phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff; /* TODO */ } diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index c51795862b6d..165c5014b7c8 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -36,6 +36,9 @@ #define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */ #define B43_PHY_HT_TXPCTL_CMD_C2 0x222 #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F +#define B43_PHY_HT_RSSI_C1 0x219 +#define B43_PHY_HT_RSSI_C2 0x21A +#define B43_PHY_HT_RSSI_C3 0x21B #define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E) #define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E) @@ -91,6 +94,8 @@ struct b43_phy_ht { u8 tx_pwr_idx[3]; s32 bb_mult_save[3]; + + u8 idle_tssi[3]; }; -- cgit From 5949e040604128106db1421ab7a73efcc5351809 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:26 +0100 Subject: b43: HT-PHY: setup TX power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 109 ++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 25 +++++++++ 2 files changed, 134 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index ae9cd2978060..5e098b844a60 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -557,6 +557,114 @@ static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) /* TODO */ } + +static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev) +{ + struct b43_phy_ht *phy_ht = dev->phy.ht; + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + u8 *idle = phy_ht->idle_tssi; + u8 target[3]; + s16 a1[3], b0[3], b1[3]; + + u16 freq = dev->phy.channel_freq; + int i, c; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + for (c = 0; c < 3; c++) { + target[c] = sprom->core_pwr_info[c].maxpwr_2g; + a1[c] = sprom->core_pwr_info[c].pa_2g[0]; + b0[c] = sprom->core_pwr_info[c].pa_2g[1]; + b1[c] = sprom->core_pwr_info[c].pa_2g[2]; + } + } else if (freq >= 4900 && freq < 5100) { + for (c = 0; c < 3; c++) { + target[c] = sprom->core_pwr_info[c].maxpwr_5gl; + a1[c] = sprom->core_pwr_info[c].pa_5gl[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gl[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gl[2]; + } + } else if (freq >= 5100 && freq < 5500) { + for (c = 0; c < 3; c++) { + target[c] = sprom->core_pwr_info[c].maxpwr_5g; + a1[c] = sprom->core_pwr_info[c].pa_5g[0]; + b0[c] = sprom->core_pwr_info[c].pa_5g[1]; + b1[c] = sprom->core_pwr_info[c].pa_5g[2]; + } + } else if (freq >= 5500) { + for (c = 0; c < 3; c++) { + target[c] = sprom->core_pwr_info[c].maxpwr_5gh; + a1[c] = sprom->core_pwr_info[c].pa_5gh[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gh[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gh[2]; + } + } else { + target[0] = target[1] = target[2] = 52; + a1[0] = a1[1] = a1[2] = -424; + b0[0] = b0[1] = b0[2] = 5612; + b1[0] = b1[1] = b1[2] = -1393; + } + + b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN); + b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, + ~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF); + + /* TODO: Does it depend on sprom->fem.ghz2.tssipos? */ + b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000); + + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, + ~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2, + ~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3, + ~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19); + + b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, + B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF); + + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, + ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1, + idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, + ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2, + idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2, + ~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3, + idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT); + + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID, + 0xf0); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2, + 0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT); +#if 0 + /* TODO: what to mask/set? */ + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0) + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0) +#endif + + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR, + ~B43_PHY_HT_TXPCTL_TARG_PWR_C1, + target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR, + ~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF, + target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT); + b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2, + ~B43_PHY_HT_TXPCTL_TARG_PWR2_C3, + target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT); + + for (c = 0; c < 3; c++) { + s32 num, den, pwr; + u32 regval[64]; + + for (i = 0; i < 64; i++) { + num = 8 * (16 * b0[c] + b1[c] * i); + den = 32768 + a1[c] * i; + pwr = max((4 * num + den / 2) / den, -8); + regval[i] = pwr; + } + b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval); + } +} #endif /************************************************** @@ -844,6 +952,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) #if 0 b43_phy_ht_tx_power_ctl(dev, false); b43_phy_ht_tx_power_ctl_idle_tssi(dev); + b43_phy_ht_tx_power_ctl_setup(dev); /* TODO */ b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); #endif diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 165c5014b7c8..9b2408efb224 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -23,6 +23,9 @@ #define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ #define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ #define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ +#define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */ +#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */ +#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */ #define B43_PHY_HT_BW1 0x1CE #define B43_PHY_HT_BW2 0x1CF #define B43_PHY_HT_BW3 0x1D0 @@ -34,6 +37,22 @@ #define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */ #define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */ #define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */ +#define B43_PHY_HT_TXPCTL_N 0x1E8 /* TX power control N num */ +#define B43_PHY_HT_TXPCTL_N_TSSID 0x00FF /* N TSSI delay */ +#define B43_PHY_HT_TXPCTL_N_TSSID_SHIFT 0 +#define B43_PHY_HT_TXPCTL_N_NPTIL2 0x0700 /* N PT integer log2 */ +#define B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT 8 +#define B43_PHY_HT_TXPCTL_IDLE_TSSI 0x1E9 /* TX power control idle TSSI */ +#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1 0x003F +#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT 0 +#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2 0x3F00 +#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT 8 +#define B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF 0x8000 /* Raw TSSI offset bin format */ +#define B43_PHY_HT_TXPCTL_TARG_PWR 0x1EA /* TX power control target power */ +#define B43_PHY_HT_TXPCTL_TARG_PWR_C1 0x00FF /* Power 0 */ +#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0 +#define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */ +#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8 #define B43_PHY_HT_TXPCTL_CMD_C2 0x222 #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F #define B43_PHY_HT_RSSI_C1 0x219 @@ -72,6 +91,12 @@ #define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164) #define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F +#define B43_PHY_HT_TXPCTL_IDLE_TSSI2 B43_PHY_EXTG(0x165) /* TX power control idle TSSI */ +#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3 0x003F +#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT 0 +#define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */ +#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF +#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) -- cgit From 4969b41798e512689bba57c8c44d873216eba814 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Mar 2013 16:47:27 +0100 Subject: b43: HT-PHY: enable basic TX power setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 5e098b844a60..b8667706fc27 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -297,7 +297,6 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev) * Samples **************************************************/ -#if 0 static void b43_phy_ht_stop_playback(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; @@ -385,13 +384,11 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev) samp = b43_phy_ht_load_samples(dev); b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0); } -#endif /************************************************** * RSSI **************************************************/ -#if 0 static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, u8 rssi_type) { @@ -471,7 +468,6 @@ static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, for (i = 0; i < 12; i++) b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]); } -#endif /************************************************** * Tx/Rx @@ -499,7 +495,6 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev) } } -#if 0 static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) { struct b43_phy_ht *phy_ht = dev->phy.ht; @@ -665,7 +660,6 @@ static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev) b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval); } } -#endif /************************************************** * Channel switching ops. @@ -949,13 +943,10 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl; b43_phy_ht_tx_power_fix(dev); -#if 0 b43_phy_ht_tx_power_ctl(dev, false); b43_phy_ht_tx_power_ctl_idle_tssi(dev); b43_phy_ht_tx_power_ctl_setup(dev); - /* TODO */ b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); -#endif return 0; } -- cgit From 7cba5b3f5fdfcb0be4f15b54a1f3a7455f973c16 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 13 Mar 2013 16:01:26 +0800 Subject: pinctrl: single: correct argument for pinconf pcs_pinconf_set() is always using "arg << shift" to configure two parameters case. But pcs_add_conf2() didn't remove shift for config argument. So correct it. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index e35dabd3135d..5f2d2bfd356e 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -623,8 +623,8 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, { struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); struct pcs_function *func; - unsigned offset = 0, shift = 0, arg = 0, i, data, ret; - u16 argument; + unsigned offset = 0, shift = 0, i, data, ret; + u16 arg; ret = pcs_get_function(pctldev, pin, &func); if (ret) @@ -634,14 +634,13 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, if (pinconf_to_config_param(config) == func->conf[i].param) { offset = pin * (pcs->width / BITS_PER_BYTE); data = pcs->read(pcs->base + offset); - argument = pinconf_to_config_argument(config); + arg = pinconf_to_config_argument(config); switch (func->conf[i].param) { /* 2 parameters */ case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_SLEW_RATE: shift = ffs(func->conf[i].mask) - 1; - arg = pinconf_to_config_argument(config); data &= ~func->conf[i].mask; data |= (arg << shift) & func->conf[i].mask; break; @@ -651,12 +650,12 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, break; case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_UP: - if (argument) + if (arg) pcs_pinconf_clear_bias(pctldev, pin); /* fall through */ case PIN_CONFIG_INPUT_SCHMITT_ENABLE: data &= ~func->conf[i].mask; - if (argument) + if (arg) data |= func->conf[i].enable; else data |= func->conf[i].disable; @@ -965,7 +964,7 @@ static void pcs_add_conf2(struct pcs_device *pcs, struct device_node *np, const char *name, enum pin_config_param param, struct pcs_conf_vals **conf, unsigned long **settings) { - unsigned value[2]; + unsigned value[2], shift; int ret; ret = of_property_read_u32_array(np, name, value, 2); @@ -973,9 +972,10 @@ static void pcs_add_conf2(struct pcs_device *pcs, struct device_node *np, return; /* set value & mask */ value[0] &= value[1]; + shift = ffs(value[1]) - 1; /* skip enable & disable */ add_config(conf, param, value[0], 0, 0, value[1]); - add_setting(settings, param, value[0]); + add_setting(settings, param, value[0] >> shift); } /* add pinconf setting with 4 parameters */ -- cgit From 9cca1173594dccc67c50f0530dc5743fa395da67 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 13 Mar 2013 17:27:13 +0530 Subject: pinctrl: pinctrl-nomadik-stn8815: Fix checkpatch error Fixes the following error: ERROR: space required after that ',' (ctx:VxV) Signed-off-by: Sachin Kamat Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-stn8815.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/pinctrl-nomadik-stn8815.c index 924a3393fa82..ed39dcafd4f8 100644 --- a/drivers/pinctrl/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/pinctrl-nomadik-stn8815.c @@ -299,7 +299,7 @@ static const unsigned i2c0_a_1_pins[] = { STN8815_PIN_D3, STN8815_PIN_D2 }; static const unsigned u1_b_1_pins[] = { STN8815_PIN_B16, STN8815_PIN_A16 }; static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 }; -#define STN8815_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ +#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \ .npins = ARRAY_SIZE(a##_pins), .altsetting = b } static const struct nmk_pingroup nmk_stn8815_groups[] = { -- cgit From 8abac3ba51b5525354e9b2ec0eed1c9e95c905d9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 13 Mar 2013 16:38:33 +0100 Subject: regmap: cache Fix regcache-rbtree sync The last register block, which falls into the specified range, is not handled correctly. The formula which calculates the number of register which should be synced is inverse (and off by one). E.g. if all registers in that block should be synced only one is synced, and if only one should be synced all (but one) are synced. To calculate the number of registers that need to be synced we need to subtract the number of the first register in the block from the max register number and add one. This patch updates the code accordingly. The issue was introduced in commit ac8d91c ("regmap: Supply ranges to the sync operations"). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regcache-rbtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index e6732cf7c06e..79f4fca9877a 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, base = 0; if (max < rbnode->base_reg + rbnode->blklen) - end = rbnode->base_reg + rbnode->blklen - max; + end = max - rbnode->base_reg + 1; else end = rbnode->blklen; -- cgit From 72c0493ceb88ec9774ee4fa3f37fd19096fb7870 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Wed, 13 Mar 2013 16:19:55 +0800 Subject: gma500: remove unused drm_psb_no_fb commit f9f23a77f07506a32d9dc1d925bf85c0e7507b66(gma500: remove no_fb bits) remove all the drm_psb_no_fb relations code in gma500 except this line code, so remove it also. Signed-off-by: Wang YanQing Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/psb_drv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index a7fd6c48b793..6053b8abcd12 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -876,7 +876,6 @@ extern const struct psb_ops cdv_chip_ops; #define PSB_D_MSVDX (1 << 9) #define PSB_D_TOPAZ (1 << 10) -extern int drm_psb_no_fb; extern int drm_idle_check_interval; /* -- cgit From bc6a541941df6e05b0c53133537ce4cf31336c3f Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghiu Date: Mon, 11 Mar 2013 21:46:14 +0200 Subject: drivers: gpu: drm: gma500: Replaced calls kzalloc & memcpy with kmemdup Replaced calls kzalloc followed by memcpy with call to kmemdup. Patch found using coccinelle. Signed-off-by: Alexandru Gheorghiu Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/intel_bios.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index 403fffb03abd..d3497348c4d5 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c @@ -218,12 +218,11 @@ static void parse_backlight_data(struct drm_psb_private *dev_priv, 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); + lvds_bl = kmemdup(vbt_lvds_bl, sizeof(*vbt_lvds_bl), GFP_KERNEL); if (!lvds_bl) { 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; } -- cgit From 22ccb2a146f92b81cc5731db8c1ee2316cca3576 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 04:01:48 +0530 Subject: gma500: medfield: Fix possible NULL pointer dereference The use of pointer sender should be after the NULL check. Signed-off-by: Syam Sidhardhan Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/mdfld_dsi_output.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index 2d4ab48f07a2..3abf8315f57c 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -92,8 +92,8 @@ 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; + struct drm_device *dev; + struct drm_psb_private *dev_priv; u32 gen_ctrl_val; if (!sender) { @@ -101,6 +101,9 @@ void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe) return; } + dev = sender->dev; + dev_priv = dev->dev_private; + /* Set default display backlight value to 85% (0xd8)*/ mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, true); -- cgit From 8936aa31cd5fd0bea828416a3c07efd303269a45 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 10 Mar 2013 12:32:44 +0100 Subject: HID: roccat: add support for Roccat Kone Pure gaming mouse Userland-tools can already be found at http://sourceforge.net/projects/roccat Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- .../ABI/testing/sysfs-driver-hid-roccat-konepure | 105 +++++++ drivers/hid/Makefile | 4 +- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-roccat-konepure.c | 304 +++++++++++++++++++++ drivers/hid/hid-roccat-konepure.h | 72 +++++ 6 files changed, 485 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-roccat-konepure create mode 100644 drivers/hid/hid-roccat-konepure.c create mode 100644 drivers/hid/hid-roccat-konepure.h (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-konepure b/Documentation/ABI/testing/sysfs-driver-hid-roccat-konepure new file mode 100644 index 000000000000..41a9b7fbfc79 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-konepure @@ -0,0 +1,105 @@ +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/actual_profile +Date: December 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. actual_profile holds number of actual profile. + This value is persistent, so its value determines the profile + that's active when the mouse is powered on next time. + When written, the mouse activates the set profile immediately. + The data has to be 3 bytes long. + The mouse will reject invalid data. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/control +Date: December 2012 +Contact: Stefan Achatz +Description: When written, this file lets one select which data from which + profile will be read next. The data has to be 3 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/info +Date: December 2012 +Contact: Stefan Achatz +Description: When read, this file returns general data like firmware version. + When written, the device can be reset. + The data is 6 bytes long. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/macro +Date: December 2012 +Contact: Stefan Achatz +Description: The mouse can store a macro with max 500 key/button strokes + internally. + When written, this file lets one set the sequence for a specific + button for a specific profile. Button and profile numbers are + included in written data. The data has to be 2082 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/profile_buttons +Date: December 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. A profile is split in settings and buttons. + profile_buttons holds information about button layout. + When written, this file lets one write the respective profile + buttons back to the mouse. The data has to be 59 bytes long. + The mouse will reject invalid data. + Which profile to write is determined by the profile number + contained in the data. + Before reading this file, control has to be written to select + which profile to read. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/profile_settings +Date: December 2012 +Contact: Stefan Achatz +Description: The mouse can store 5 profiles which can be switched by the + press of a button. A profile is split in settings and buttons. + profile_settings holds information like resolution, sensitivity + and light effects. + When written, this file lets one write the respective profile + settings back to the mouse. The data has to be 31 bytes long. + The mouse will reject invalid data. + Which profile to write is determined by the profile number + contained in the data. + Before reading this file, control has to be written to select + which profile to read. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/sensor +Date: December 2012 +Contact: Stefan Achatz +Description: The mouse has a tracking- and a distance-control-unit. These + can be activated/deactivated and the lift-off distance can be + set. The data has to be 6 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/talk +Date: December 2012 +Contact: Stefan Achatz +Description: Used to active some easy* functions of the mouse from outside. + The data has to be 16 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/tcu +Date: December 2012 +Contact: Stefan Achatz +Description: When written a calibration process for the tracking control unit + can be initiated/cancelled. Also lets one read/write sensor + registers. + The data has to be 4 bytes long. +Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./konepure/roccatkonepure/tcu_image +Date: December 2012 +Contact: Stefan Achatz +Description: When read the mouse returns a 30x30 pixel image of the + sampled underground. This works only in the course of a + calibration process initiated with tcu. + The returned data is 1028 bytes in size. + This file is readonly. +Users: http://roccat.sourceforge.net diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 72d1b0bc0a97..273515197c37 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -94,8 +94,8 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ - hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-lua.o \ - hid-roccat-pyra.o hid-roccat-savu.o + hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ + hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-savu.o obj-$(CONFIG_HID_SAITEK) += hid-saitek.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 512b01c04ea7..733d7e059708 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1687,6 +1687,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 92e47e5c9564..007ee7441e34 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -689,6 +689,7 @@ #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 +#define USB_DEVICE_ID_ROCCAT_KONEPURE 0x2dbe #define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 #define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c new file mode 100644 index 000000000000..c79d0b06c143 --- /dev/null +++ b/drivers/hid/hid-roccat-konepure.c @@ -0,0 +1,304 @@ +/* + * Roccat KonePure driver for Linux + * + * Copyright (c) 2012 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +/* + * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights. + */ + +#include +#include +#include +#include +#include +#include +#include "hid-ids.h" +#include "hid-roccat-common.h" +#include "hid-roccat-konepure.h" + +static struct class *konepure_class; + +static ssize_t konepure_sysfs_read(struct file *fp, struct kobject *kobj, + char *buf, loff_t off, size_t count, + size_t real_size, uint command) +{ + struct device *dev = + container_of(kobj, struct device, kobj)->parent->parent; + struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); + int retval; + + if (off >= real_size) + return 0; + + if (off != 0 || count != real_size) + return -EINVAL; + + mutex_lock(&konepure->konepure_lock); + retval = roccat_common2_receive(usb_dev, command, buf, real_size); + mutex_unlock(&konepure->konepure_lock); + + return retval ? retval : real_size; +} + +static ssize_t konepure_sysfs_write(struct file *fp, struct kobject *kobj, + void const *buf, loff_t off, size_t count, + size_t real_size, uint command) +{ + struct device *dev = + container_of(kobj, struct device, kobj)->parent->parent; + struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev)); + struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); + int retval; + + if (off != 0 || count != real_size) + return -EINVAL; + + mutex_lock(&konepure->konepure_lock); + retval = roccat_common2_send_with_status(usb_dev, command, + (void *)buf, real_size); + mutex_unlock(&konepure->konepure_lock); + + return retval ? retval : real_size; +} + +#define KONEPURE_SYSFS_W(thingy, THINGY) \ +static ssize_t konepure_sysfs_write_ ## thingy(struct file *fp, \ + struct kobject *kobj, struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + return konepure_sysfs_write(fp, kobj, buf, off, count, \ + KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \ +} + +#define KONEPURE_SYSFS_R(thingy, THINGY) \ +static ssize_t konepure_sysfs_read_ ## thingy(struct file *fp, \ + struct kobject *kobj, struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + return konepure_sysfs_read(fp, kobj, buf, off, count, \ + KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \ +} + +#define KONEPURE_SYSFS_RW(thingy, THINGY) \ +KONEPURE_SYSFS_W(thingy, THINGY) \ +KONEPURE_SYSFS_R(thingy, THINGY) + +#define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0660 }, \ + .size = KONEPURE_SIZE_ ## THINGY, \ + .read = konepure_sysfs_read_ ## thingy, \ + .write = konepure_sysfs_write_ ## thingy \ +} + +#define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0440 }, \ + .size = KONEPURE_SIZE_ ## THINGY, \ + .read = konepure_sysfs_read_ ## thingy, \ +} + +#define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \ +{ \ + .attr = { .name = #thingy, .mode = 0220 }, \ + .size = KONEPURE_SIZE_ ## THINGY, \ + .write = konepure_sysfs_write_ ## thingy \ +} + +KONEPURE_SYSFS_RW(actual_profile, ACTUAL_PROFILE) +KONEPURE_SYSFS_W(control, CONTROL) +KONEPURE_SYSFS_RW(info, INFO) +KONEPURE_SYSFS_W(talk, TALK) +KONEPURE_SYSFS_W(macro, MACRO) +KONEPURE_SYSFS_RW(sensor, SENSOR) +KONEPURE_SYSFS_RW(tcu, TCU) +KONEPURE_SYSFS_R(tcu_image, TCU_IMAGE) +KONEPURE_SYSFS_RW(profile_settings, PROFILE_SETTINGS) +KONEPURE_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) + +static struct bin_attribute konepure_bin_attributes[] = { + KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE), + KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL), + KONEPURE_BIN_ATTRIBUTE_RW(info, INFO), + KONEPURE_BIN_ATTRIBUTE_W(talk, TALK), + KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO), + KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR), + KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU), + KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), + KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), + KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), + __ATTR_NULL +}; + +static int konepure_init_konepure_device_struct(struct usb_device *usb_dev, + struct konepure_device *konepure) +{ + mutex_init(&konepure->konepure_lock); + + return 0; +} + +static int konepure_init_specials(struct hid_device *hdev) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct konepure_device *konepure; + int retval; + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) { + hid_set_drvdata(hdev, NULL); + return 0; + } + + konepure = kzalloc(sizeof(*konepure), GFP_KERNEL); + if (!konepure) { + hid_err(hdev, "can't alloc device descriptor\n"); + return -ENOMEM; + } + hid_set_drvdata(hdev, konepure); + + retval = konepure_init_konepure_device_struct(usb_dev, konepure); + if (retval) { + hid_err(hdev, "couldn't init struct konepure_device\n"); + goto exit_free; + } + + retval = roccat_connect(konepure_class, hdev, + sizeof(struct konepure_mouse_report_button)); + if (retval < 0) { + hid_err(hdev, "couldn't init char dev\n"); + } else { + konepure->chrdev_minor = retval; + konepure->roccat_claimed = 1; + } + + return 0; +exit_free: + kfree(konepure); + return retval; +} + +static void konepure_remove_specials(struct hid_device *hdev) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct konepure_device *konepure; + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) + return; + + konepure = hid_get_drvdata(hdev); + if (konepure->roccat_claimed) + roccat_disconnect(konepure->chrdev_minor); + kfree(konepure); +} + +static int konepure_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int retval; + + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); + goto exit; + } + + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (retval) { + hid_err(hdev, "hw start failed\n"); + goto exit; + } + + retval = konepure_init_specials(hdev); + if (retval) { + hid_err(hdev, "couldn't install mouse\n"); + goto exit_stop; + } + + return 0; + +exit_stop: + hid_hw_stop(hdev); +exit: + return retval; +} + +static void konepure_remove(struct hid_device *hdev) +{ + konepure_remove_specials(hdev); + hid_hw_stop(hdev); +} + +static int konepure_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct konepure_device *konepure = hid_get_drvdata(hdev); + + if (intf->cur_altsetting->desc.bInterfaceProtocol + != USB_INTERFACE_PROTOCOL_MOUSE) + return 0; + + if (data[0] != KONEPURE_MOUSE_REPORT_NUMBER_BUTTON) + return 0; + + if (konepure != NULL && konepure->roccat_claimed) + roccat_report_event(konepure->chrdev_minor, data); + + return 0; +} + +static const struct hid_device_id konepure_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, + { } +}; + +MODULE_DEVICE_TABLE(hid, konepure_devices); + +static struct hid_driver konepure_driver = { + .name = "konepure", + .id_table = konepure_devices, + .probe = konepure_probe, + .remove = konepure_remove, + .raw_event = konepure_raw_event +}; + +static int __init konepure_init(void) +{ + int retval; + + konepure_class = class_create(THIS_MODULE, "konepure"); + if (IS_ERR(konepure_class)) + return PTR_ERR(konepure_class); + konepure_class->dev_bin_attrs = konepure_bin_attributes; + + retval = hid_register_driver(&konepure_driver); + if (retval) + class_destroy(konepure_class); + return retval; +} + +static void __exit konepure_exit(void) +{ + hid_unregister_driver(&konepure_driver); + class_destroy(konepure_class); +} + +module_init(konepure_init); +module_exit(konepure_exit); + +MODULE_AUTHOR("Stefan Achatz"); +MODULE_DESCRIPTION("USB Roccat KonePure driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-roccat-konepure.h b/drivers/hid/hid-roccat-konepure.h new file mode 100644 index 000000000000..2cd24e93dfd6 --- /dev/null +++ b/drivers/hid/hid-roccat-konepure.h @@ -0,0 +1,72 @@ +#ifndef __HID_ROCCAT_KONEPURE_H +#define __HID_ROCCAT_KONEPURE_H + +/* + * Copyright (c) 2012 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include + +enum { + KONEPURE_SIZE_ACTUAL_PROFILE = 0x03, + KONEPURE_SIZE_CONTROL = 0x03, + KONEPURE_SIZE_FIRMWARE_WRITE = 0x0402, + KONEPURE_SIZE_INFO = 0x06, + KONEPURE_SIZE_MACRO = 0x0822, + KONEPURE_SIZE_PROFILE_SETTINGS = 0x1f, + KONEPURE_SIZE_PROFILE_BUTTONS = 0x3b, + KONEPURE_SIZE_SENSOR = 0x06, + KONEPURE_SIZE_TALK = 0x10, + KONEPURE_SIZE_TCU = 0x04, + KONEPURE_SIZE_TCU_IMAGE = 0x0404, +}; + +enum konepure_control_requests { + KONEPURE_CONTROL_REQUEST_GENERAL = 0x80, + KONEPURE_CONTROL_REQUEST_BUTTONS = 0x90, +}; + +enum konepure_commands { + KONEPURE_COMMAND_CONTROL = 0x04, + KONEPURE_COMMAND_ACTUAL_PROFILE = 0x05, + KONEPURE_COMMAND_PROFILE_SETTINGS = 0x06, + KONEPURE_COMMAND_PROFILE_BUTTONS = 0x07, + KONEPURE_COMMAND_MACRO = 0x08, + KONEPURE_COMMAND_INFO = 0x09, + KONEPURE_COMMAND_TCU = 0x0c, + KONEPURE_COMMAND_TCU_IMAGE = 0x0c, + KONEPURE_COMMAND_E = 0x0e, + KONEPURE_COMMAND_SENSOR = 0x0f, + KONEPURE_COMMAND_TALK = 0x10, + KONEPURE_COMMAND_FIRMWARE_WRITE = 0x1b, + KONEPURE_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, +}; + +enum { + KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3, +}; + +struct konepure_mouse_report_button { + uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */ + uint8_t zero; + uint8_t type; + uint8_t data1; + uint8_t data2; + uint8_t zero2; + uint8_t unknown[2]; +} __packed; + +struct konepure_device { + int roccat_claimed; + int chrdev_minor; + struct mutex konepure_lock; +}; + +#endif -- cgit From ce7169652532a95bebbf2f02cd330a4e66f171ae Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 10 Mar 2013 12:33:02 +0100 Subject: HID: roccat: add support for IskuFX Extending isku module with one additional and one changed sysfs attr. IskuFX has larger light sysfs attr. Made the code size tolerant so both devices can be handled. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-driver-hid-roccat-isku | 12 +++++++++++- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-roccat-isku.c | 17 ++++++++++------- drivers/hid/hid-roccat-isku.h | 4 +++- 4 files changed, 25 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku index 9eca5a182e64..c601d0f2ac46 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku @@ -101,7 +101,8 @@ Date: June 2011 Contact: Stefan Achatz Description: When written, this file lets one set the backlight intensity for a specific profile. Profile number is included in written data. - The data has to be 10 bytes long. + The data has to be 10 bytes long for Isku, IskuFX needs 16 bytes + of data. Before reading this file, control has to be written to select which profile to read. Users: http://roccat.sourceforge.net @@ -141,3 +142,12 @@ Description: When written, this file lets one trigger easyshift functionality The data has to be 16 bytes long. This file is writeonly. Users: http://roccat.sourceforge.net + +What: /sys/bus/usb/devices/-:./::./isku/roccatisku/talkfx +Date: February 2013 +Contact: Stefan Achatz +Description: When written, this file lets one trigger temporary color schemes + from the host. + The data has to be 16 bytes long. + This file is writeonly. +Users: http://roccat.sourceforge.net diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 007ee7441e34..a2e767b3d5d2 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -687,6 +687,7 @@ #define USB_VENDOR_ID_ROCCAT 0x1e7d #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c +#define USB_DEVICE_ID_ROCCAT_ISKUFX 0x3264 #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 #define USB_DEVICE_ID_ROCCAT_KONEPURE 0x2dbe diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 1219998a02d6..8023751d5257 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -130,14 +130,14 @@ static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj, if (off >= real_size) return 0; - if (off != 0 || count != real_size) + if (off != 0 || count > real_size) return -EINVAL; mutex_lock(&isku->isku_lock); - retval = isku_receive(usb_dev, command, buf, real_size); + retval = isku_receive(usb_dev, command, buf, count); mutex_unlock(&isku->isku_lock); - return retval ? retval : real_size; + return retval ? retval : count; } static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, @@ -150,15 +150,15 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval; - if (off != 0 || count != real_size) + if (off != 0 || count > real_size) return -EINVAL; mutex_lock(&isku->isku_lock); retval = roccat_common2_send_with_status(usb_dev, command, - (void *)buf, real_size); + (void *)buf, count); mutex_unlock(&isku->isku_lock); - return retval ? retval : real_size; + return retval ? retval : count; } #define ISKU_SYSFS_W(thingy, THINGY) \ @@ -216,6 +216,7 @@ ISKU_SYSFS_RW(light, LIGHT) ISKU_SYSFS_RW(key_mask, KEY_MASK) ISKU_SYSFS_RW(last_set, LAST_SET) ISKU_SYSFS_W(talk, TALK) +ISKU_SYSFS_W(talkfx, TALKFX) ISKU_SYSFS_R(info, INFO) ISKU_SYSFS_W(control, CONTROL) ISKU_SYSFS_W(reset, RESET) @@ -232,6 +233,7 @@ static struct bin_attribute isku_bin_attributes[] = { ISKU_BIN_ATTR_RW(key_mask, KEY_MASK), ISKU_BIN_ATTR_RW(last_set, LAST_SET), ISKU_BIN_ATTR_W(talk, TALK), + ISKU_BIN_ATTR_W(talkfx, TALKFX), ISKU_BIN_ATTR_R(info, INFO), ISKU_BIN_ATTR_W(control, CONTROL), ISKU_BIN_ATTR_W(reset, RESET), @@ -405,6 +407,7 @@ static int isku_raw_event(struct hid_device *hdev, static const struct hid_device_id isku_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) }, { } }; @@ -443,5 +446,5 @@ module_init(isku_init); module_exit(isku_exit); MODULE_AUTHOR("Stefan Achatz"); -MODULE_DESCRIPTION("USB Roccat Isku driver"); +MODULE_DESCRIPTION("USB Roccat Isku/FX driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h index cf6896c83867..53056860d4d8 100644 --- a/drivers/hid/hid-roccat-isku.h +++ b/drivers/hid/hid-roccat-isku.h @@ -25,10 +25,11 @@ enum { ISKU_SIZE_KEYS_MACRO = 0x23, ISKU_SIZE_KEYS_CAPSLOCK = 0x06, ISKU_SIZE_LAST_SET = 0x14, - ISKU_SIZE_LIGHT = 0x0a, + ISKU_SIZE_LIGHT = 0x10, ISKU_SIZE_MACRO = 0x823, ISKU_SIZE_RESET = 0x03, ISKU_SIZE_TALK = 0x10, + ISKU_SIZE_TALKFX = 0x10, }; enum { @@ -59,6 +60,7 @@ enum isku_commands { ISKU_COMMAND_LAST_SET = 0x14, ISKU_COMMAND_15 = 0x15, ISKU_COMMAND_TALK = 0x16, + ISKU_COMMAND_TALKFX = 0x17, ISKU_COMMAND_FIRMWARE_WRITE = 0x1b, ISKU_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, }; -- cgit From 02060045cd93b886381b02ec816e312f19d5e505 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 10 Mar 2013 12:33:04 +0100 Subject: HID: roccat: fix comments on chardevice Fixed parameter documentation. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index d7437ef5c695..b59b3df9ca95 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -242,7 +242,6 @@ static int roccat_release(struct inode *inode, struct file *file) * roccat_report_event() - output data to readers * @minor: minor device number returned by roccat_connect() * @data: pointer to data - * @len: size of data * * Return value is zero on success, a negative error code on failure. * @@ -290,6 +289,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event); * @class: the class thats used to create the device. Meant to hold device * specific sysfs attributes. * @hid: the hid device the char device should be connected to. + * @report_size: size of reports * * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on * success, a negative error code on failure. -- cgit From 9bb05696af3f808c3ad684c9fcf4b870ddbff804 Mon Sep 17 00:00:00 2001 From: Gianluca Gennari Date: Thu, 7 Mar 2013 12:19:29 -0300 Subject: [media] cx231xx: fix undefined function cx231xx_g_chip_ident() This patch: http://git.linuxtv.org/media_tree.git/commit/b86d15440b683f8634c0cb26fc0861a5bc4913ac is missing a chunk when compared to an older version: https://patchwork.kernel.org/patch/2063281/ probably because of an unresolved merging conflict. This causes the following error: WARNING: "cx231xx_g_chip_ident" [/home/jena/media_build/v4l/cx231xx.ko] undefined! Signed-off-by: Gianluca Gennari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 41c5c996ed2c..ac6200870a62 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1227,7 +1227,7 @@ int cx231xx_s_frequency(struct file *file, void *priv, return rc; } -int vidioc_g_chip_ident(struct file *file, void *fh, +int cx231xx_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) { chip->ident = V4L2_IDENT_NONE; -- cgit From d9b7595bed61930987308be946563ce084148c14 Mon Sep 17 00:00:00 2001 From: Fabrizio Gazzato Date: Sun, 17 Feb 2013 18:25:34 -0300 Subject: [media] af9035: add ID [0ccd:00aa] TerraTec Cinergy T Stick (rev. 2) This patch adds USB ID for alternative "Terratec Cinergy T Stick". Tested by a friend: works similarly to 0ccd:0093 version (af9035+tua9001) Signed-off-by: Fabrizio Gazzato Acked-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index f11cc42454f0..d3cb8d55febc 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1312,6 +1312,8 @@ static const struct usb_device_id af9035_id_table[] = { &af9035_props, "AVerMedia Twinstar (A825)", NULL) }, { DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS, &af9035_props, "Asus U3100Mini Plus", NULL) }, + { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa, + &af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, af9035_id_table); -- cgit From a9fc36afc074db2d5995136b50b018c2ca77f48f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 19 Feb 2013 08:00:36 -0300 Subject: [media] timblogiw: Fix sparse warning Fixes the below warning: drivers/media/platform/timblogiw.c:81:31: warning: symbol 'timblogiw_tvnorms' was not declared. Should it be static? Signed-off-by: Sachin Kamat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/timblogiw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c index c3a2a4484401..2d91eeb1d2ae 100644 --- a/drivers/media/platform/timblogiw.c +++ b/drivers/media/platform/timblogiw.c @@ -78,7 +78,7 @@ struct timblogiw_buffer { struct timblogiw_fh *fh; }; -const struct timblogiw_tvnorm timblogiw_tvnorms[] = { +static const struct timblogiw_tvnorm timblogiw_tvnorms[] = { { .std = V4L2_STD_PAL, .width = 720, -- cgit From c67d2f074073b39e5eba84e852c894c22057d159 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Tue, 19 Feb 2013 14:58:53 -0300 Subject: [media] stv090x: do not unlock unheld mutex in stv090x_sleep() goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock) lead to unlock of unheld mutex in stv090x_sleep(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Cc: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv090x.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index f36eeefb76a6..56d470ad5a82 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -3906,12 +3906,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_TSTTNR1); STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) - goto err; + goto err_unlock; /* power off DiSEqC 1 */ reg = stv090x_read_reg(state, STV090x_TSTTNR2); STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) - goto err; + goto err_unlock; /* check whether path 2 is already sleeping, that is when ADC2 is off */ @@ -3930,7 +3930,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) - goto err; + goto err_unlock; reg = stv090x_read_reg(state, STV090x_STOPCLK2); /* sampling 1 clock */ STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); @@ -3941,7 +3941,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) - goto err; + goto err_unlock; break; case STV090x_DEMODULATOR_1: @@ -3949,12 +3949,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_TSTTNR3); STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) - goto err; + goto err_unlock; /* power off DiSEqC 2 */ reg = stv090x_read_reg(state, STV090x_TSTTNR4); STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) - goto err; + goto err_unlock; /* check whether path 1 is already sleeping, that is when ADC1 is off */ @@ -3973,7 +3973,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) - goto err; + goto err_unlock; reg = stv090x_read_reg(state, STV090x_STOPCLK2); /* sampling 2 clock */ STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); @@ -3984,7 +3984,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) - goto err; + goto err_unlock; break; default: @@ -3997,7 +3997,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_SYNTCTRL); STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) - goto err; + goto err_unlock; } mutex_unlock(&state->internal->demod_lock); @@ -4005,8 +4005,10 @@ static int stv090x_sleep(struct dvb_frontend *fe) err_gateoff: stv090x_i2c_gate_ctrl(state, 0); -err: + goto err; +err_unlock: mutex_unlock(&state->internal->demod_lock); +err: dprintk(FE_ERROR, 1, "I/O error"); return -1; } -- cgit From 44122dd6b6b872d6f1ec151f89942f66b715222c Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Thu, 21 Feb 2013 08:11:41 -0300 Subject: [media] media: Terratec Cinergy S2 USB HD Rev.2 Terratec Cinergy S2 USB HD Rev.2 support. This commit is a corrected cherry-pick of 03228792 which got reverted in b7e38636 because it was rebased incorrectly and introduced compilation errors. Signed-off-by: Stephan Hilb Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 9578a6761f1b..24cfd4bbbc8a 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1548,6 +1548,7 @@ enum dw2102_table_entry { X3M_SPC1400HD, TEVII_S421, TEVII_S632, + TERRATEC_CINERGY_S2_R2, }; static struct usb_device_id dw2102_table[] = { @@ -1568,6 +1569,7 @@ static struct usb_device_id dw2102_table[] = { [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)}, [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, + [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, { } }; @@ -1968,7 +1970,7 @@ static struct dvb_usb_device_properties su3000_properties = { }}, } }, - .num_device_descs = 3, + .num_device_descs = 4, .devices = { { "SU3000HD DVB-S USB2.0", { &dw2102_table[GENIATECH_SU3000], NULL }, @@ -1982,6 +1984,10 @@ static struct dvb_usb_device_properties su3000_properties = { { &dw2102_table[X3M_SPC1400HD], NULL }, { NULL }, }, + { "Terratec Cinergy S2 USB HD Rev.2", + { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL }, + { NULL }, + }, } }; -- cgit From 0169ab28b3992d46ac703d13940c415fe0795974 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Thu, 21 Feb 2013 16:18:16 -0300 Subject: [media] media/usb: cx231xx-pcb-cfg.h: Remove unused enum _true_false Signed-off-by: Thiago Farina Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h index f5e46e89f3ab..b3c6190e0c69 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h @@ -68,11 +68,6 @@ enum USB_SPEED{ HIGH_SPEED = 0x1 /* 1: high speed */ }; -enum _true_false{ - FALSE = 0, - TRUE = 1 -}; - #define TS_MASK 0x6 enum TS_PORT{ NO_TS_PORT = 0x0, /* 2'b00: Neither port used. PCB not a Hybrid, -- cgit From b2decadd837fd7f5e789bd7e1de11be79ed22a06 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:47 +0000 Subject: cxgb4: Add register definations for T5 Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 94 ++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 83ec5f7844ac..22cbcb36d81d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -68,9 +68,14 @@ #define QID_SHIFT 15 #define QID(x) ((x) << QID_SHIFT) #define DBPRIO(x) ((x) << 14) +#define DBTYPE(x) ((x) << 13) #define PIDX_MASK 0x00003fffU #define PIDX_SHIFT 0 #define PIDX(x) ((x) << PIDX_SHIFT) +#define S_PIDX_T5 0 +#define M_PIDX_T5 0x1fffU +#define PIDX_T5(x) (((x) >> S_PIDX_T5) & M_PIDX_T5) + #define SGE_PF_GTS 0x4 #define INGRESSQID_MASK 0xffff0000U @@ -152,6 +157,8 @@ #define QUEUESPERPAGEPF0_MASK 0x0000000fU #define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK) +#define QUEUESPERPAGEPF1 4 + #define SGE_INT_CAUSE1 0x1024 #define SGE_INT_CAUSE2 0x1030 #define SGE_INT_CAUSE3 0x103c @@ -272,17 +279,36 @@ #define S_HP_INT_THRESH 28 #define M_HP_INT_THRESH 0xfU #define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH) +#define S_LP_INT_THRESH_T5 18 +#define V_LP_INT_THRESH_T5(x) ((x) << S_LP_INT_THRESH_T5) +#define M_LP_COUNT_T5 0x3ffffU +#define G_LP_COUNT_T5(x) (((x) >> S_LP_COUNT) & M_LP_COUNT_T5) #define M_HP_COUNT 0x7ffU #define S_HP_COUNT 16 #define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT) #define S_LP_INT_THRESH 12 #define M_LP_INT_THRESH 0xfU +#define M_LP_INT_THRESH_T5 0xfffU #define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH) #define M_LP_COUNT 0x7ffU #define S_LP_COUNT 0 #define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT) #define A_SGE_DBFIFO_STATUS 0x10a4 +#define SGE_STAT_TOTAL 0x10e4 +#define SGE_STAT_MATCH 0x10e8 + +#define SGE_STAT_CFG 0x10ec +#define S_STATSOURCE_T5 9 +#define STATSOURCE_T5(x) ((x) << S_STATSOURCE_T5) + +#define SGE_DBFIFO_STATUS2 0x1118 +#define M_HP_COUNT_T5 0x3ffU +#define G_HP_COUNT_T5(x) ((x) & M_HP_COUNT_T5) +#define S_HP_INT_THRESH_T5 10 +#define M_HP_INT_THRESH_T5 0xfU +#define V_HP_INT_THRESH_T5(x) ((x) << S_HP_INT_THRESH_T5) + #define S_ENABLE_DROP 13 #define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP) #define F_ENABLE_DROP V_ENABLE_DROP(1U) @@ -331,8 +357,27 @@ #define MSIADDRHPERR 0x00000002U #define MSIADDRLPERR 0x00000001U +#define READRSPERR 0x20000000U +#define TRGT1GRPPERR 0x10000000U +#define IPSOTPERR 0x08000000U +#define IPRXDATAGRPPERR 0x02000000U +#define IPRXHDRGRPPERR 0x01000000U +#define MAGRPPERR 0x00400000U +#define VFIDPERR 0x00200000U +#define HREQWRPERR 0x00010000U +#define DREQWRPERR 0x00002000U +#define MSTTAGQPERR 0x00000400U +#define PIOREQGRPPERR 0x00000100U +#define PIOCPLGRPPERR 0x00000080U +#define MSIXSTIPERR 0x00000004U +#define MSTTIMEOUTPERR 0x00000002U +#define MSTGRPPERR 0x00000001U + #define PCIE_NONFAT_ERR 0x3010 #define PCIE_MEM_ACCESS_BASE_WIN 0x3068 +#define S_PCIEOFST 10 +#define M_PCIEOFST 0x3fffffU +#define GET_PCIEOFST(x) (((x) >> S_PCIEOFST) & M_PCIEOFST) #define PCIEOFST_MASK 0xfffffc00U #define BIR_MASK 0x00000300U #define BIR_SHIFT 8 @@ -342,6 +387,9 @@ #define WINDOW(x) ((x) << WINDOW_SHIFT) #define PCIE_MEM_ACCESS_OFFSET 0x306c +#define S_PFNUM 0 +#define V_PFNUM(x) ((x) << S_PFNUM) + #define PCIE_FW 0x30b8 #define PCIE_FW_ERR 0x80000000U #define PCIE_FW_INIT 0x40000000U @@ -407,12 +455,18 @@ #define MC_BIST_STATUS_RDATA 0x7688 +#define MA_EDRAM0_BAR 0x77c0 +#define MA_EDRAM1_BAR 0x77c4 +#define EDRAM_SIZE_MASK 0xfffU +#define EDRAM_SIZE_GET(x) ((x) & EDRAM_SIZE_MASK) + #define MA_EXT_MEMORY_BAR 0x77c8 #define EXT_MEM_SIZE_MASK 0x00000fffU #define EXT_MEM_SIZE_SHIFT 0 #define EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT) #define MA_TARGET_MEM_ENABLE 0x77d8 +#define EXT_MEM1_ENABLE 0x00000010U #define EXT_MEM_ENABLE 0x00000004U #define EDRAM1_ENABLE 0x00000002U #define EDRAM0_ENABLE 0x00000001U @@ -431,6 +485,7 @@ #define MA_PCIE_FW 0x30b8 #define MA_PARITY_ERROR_STATUS 0x77f4 +#define MA_EXT_MEMORY1_BAR 0x7808 #define EDC_0_BASE_ADDR 0x7900 #define EDC_BIST_CMD 0x7904 @@ -801,6 +856,15 @@ #define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c #define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610 #define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614 +#define MAC_PORT_CFG2 0x818 +#define MAC_PORT_MAGIC_MACID_LO 0x824 +#define MAC_PORT_MAGIC_MACID_HI 0x828 +#define MAC_PORT_EPIO_DATA0 0x8c0 +#define MAC_PORT_EPIO_DATA1 0x8c4 +#define MAC_PORT_EPIO_DATA2 0x8c8 +#define MAC_PORT_EPIO_DATA3 0x8cc +#define MAC_PORT_EPIO_OP 0x8d0 + #define MPS_CMN_CTL 0x9000 #define NUMPORTS_MASK 0x00000003U #define NUMPORTS_SHIFT 0 @@ -1063,6 +1127,7 @@ #define ADDRESS_SHIFT 0 #define ADDRESS(x) ((x) << ADDRESS_SHIFT) +#define MAC_PORT_INT_CAUSE 0x8dc #define XGMAC_PORT_INT_CAUSE 0x10dc #define A_TP_TX_MOD_QUEUE_REQ_MAP 0x7e28 @@ -1101,4 +1166,33 @@ #define V_PORT(x) ((x) << S_PORT) #define F_PORT V_PORT(1U) +#define NUM_MPS_CLS_SRAM_L_INSTANCES 336 +#define NUM_MPS_T5_CLS_SRAM_L_INSTANCES 512 + +#define T5_PORT0_BASE 0x30000 +#define T5_PORT_STRIDE 0x4000 +#define T5_PORT_BASE(idx) (T5_PORT0_BASE + (idx) * T5_PORT_STRIDE) +#define T5_PORT_REG(idx, reg) (T5_PORT_BASE(idx) + (reg)) + +#define MC_0_BASE_ADDR 0x40000 +#define MC_1_BASE_ADDR 0x48000 +#define MC_STRIDE (MC_1_BASE_ADDR - MC_0_BASE_ADDR) +#define MC_REG(reg, idx) (reg + MC_STRIDE * idx) + +#define MC_P_BIST_CMD 0x41400 +#define MC_P_BIST_CMD_ADDR 0x41404 +#define MC_P_BIST_CMD_LEN 0x41408 +#define MC_P_BIST_DATA_PATTERN 0x4140c +#define MC_P_BIST_STATUS_RDATA 0x41488 +#define EDC_T50_BASE_ADDR 0x50000 +#define EDC_H_BIST_CMD 0x50004 +#define EDC_H_BIST_CMD_ADDR 0x50008 +#define EDC_H_BIST_CMD_LEN 0x5000c +#define EDC_H_BIST_DATA_PATTERN 0x50010 +#define EDC_H_BIST_STATUS_RDATA 0x50028 + +#define EDC_T51_BASE_ADDR 0x50800 +#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) +#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) + #endif /* __T4_REGS_H */ -- cgit From 2422d9a32747b85801ca705f4d6376e16d230c67 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:48 +0000 Subject: cxgb4: Add macros, structures and inline functions for T5 Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 50 ++++++++++++++++++++++++++- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 45 ++++++++++++++++++++++++ drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 2 +- 3 files changed, 95 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 6db997c78a5f..a91dea621fcf 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -54,6 +54,10 @@ #define FW_VERSION_MINOR 1 #define FW_VERSION_MICRO 0 +#define FW_VERSION_MAJOR_T5 0 +#define FW_VERSION_MINOR_T5 0 +#define FW_VERSION_MICRO_T5 0 + #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) enum { @@ -66,7 +70,9 @@ enum { enum { MEM_EDC0, MEM_EDC1, - MEM_MC + MEM_MC, + MEM_MC0 = MEM_MC, + MEM_MC1 }; enum { @@ -74,8 +80,10 @@ enum { MEMWIN0_BASE = 0x1b800, MEMWIN1_APERTURE = 32768, MEMWIN1_BASE = 0x28000, + MEMWIN1_BASE_T5 = 0x52000, MEMWIN2_APERTURE = 65536, MEMWIN2_BASE = 0x30000, + MEMWIN2_BASE_T5 = 0x54000, }; enum dev_master { @@ -504,6 +512,35 @@ struct sge { struct l2t_data; +#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) +#define CHELSIO_CHIP_VERSION(code) ((code) >> 4) +#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) + +#define CHELSIO_T4 0x4 +#define CHELSIO_T5 0x5 + +enum chip_type { + T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0), + T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), + T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), + T4_FIRST_REV = T4_A1, + T4_LAST_REV = T4_A3, + + T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), + T5_FIRST_REV = T5_A1, + T5_LAST_REV = T5_A1, +}; + +#ifdef CONFIG_PCI_IOV + +/* T4 - 4 PFs support SRIOV + * T5 - 8 PFs support SRIOV + */ +#define NUM_OF_PF_WITH_SRIOV_T4 4 +#define NUM_OF_PF_WITH_SRIOV_T5 8 + +#endif + struct adapter { void __iomem *regs; struct pci_dev *pdev; @@ -511,6 +548,7 @@ struct adapter { unsigned int mbox; unsigned int fn; unsigned int flags; + enum chip_type chip; int msg_enable; @@ -673,6 +711,16 @@ enum { VLAN_REWRITE }; +static inline int is_t5(enum chip_type chip) +{ + return (chip >= T5_FIRST_REV && chip <= T5_LAST_REV); +} + +static inline int is_t4(enum chip_type chip) +{ + return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV); +} + static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) { return readl(adap->regs + reg_addr); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index 261d17703adc..0c9f14f87a4f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -74,6 +74,7 @@ enum { CPL_PASS_ESTABLISH = 0x41, CPL_RX_DATA_DDP = 0x42, CPL_PASS_ACCEPT_REQ = 0x44, + CPL_TRACE_PKT_T5 = 0x48, CPL_RDMA_READ_REQ = 0x60, @@ -287,6 +288,23 @@ struct cpl_act_open_req { __be32 opt2; }; +#define S_FILTER_TUPLE 24 +#define M_FILTER_TUPLE 0xFFFFFFFFFF +#define V_FILTER_TUPLE(x) ((x) << S_FILTER_TUPLE) +#define G_FILTER_TUPLE(x) (((x) >> S_FILTER_TUPLE) & M_FILTER_TUPLE) +struct cpl_t5_act_open_req { + WR_HDR; + union opcode_tid ot; + __be16 local_port; + __be16 peer_port; + __be32 local_ip; + __be32 peer_ip; + __be64 opt0; + __be32 rsvd; + __be32 opt2; + __be64 params; +}; + struct cpl_act_open_req6 { WR_HDR; union opcode_tid ot; @@ -566,6 +584,11 @@ struct cpl_rx_pkt { #define V_RX_ETHHDR_LEN(x) ((x) << S_RX_ETHHDR_LEN) #define G_RX_ETHHDR_LEN(x) (((x) >> S_RX_ETHHDR_LEN) & M_RX_ETHHDR_LEN) +#define S_RX_T5_ETHHDR_LEN 0 +#define M_RX_T5_ETHHDR_LEN 0x3F +#define V_RX_T5_ETHHDR_LEN(x) ((x) << S_RX_T5_ETHHDR_LEN) +#define G_RX_T5_ETHHDR_LEN(x) (((x) >> S_RX_T5_ETHHDR_LEN) & M_RX_T5_ETHHDR_LEN) + #define S_RX_MACIDX 8 #define M_RX_MACIDX 0x1FF #define V_RX_MACIDX(x) ((x) << S_RX_MACIDX) @@ -612,6 +635,28 @@ struct cpl_trace_pkt { __be64 tstamp; }; +struct cpl_t5_trace_pkt { + __u8 opcode; + __u8 intf; +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 runt:4; + __u8 filter_hit:4; + __u8:6; + __u8 err:1; + __u8 trunc:1; +#else + __u8 filter_hit:4; + __u8 runt:4; + __u8 trunc:1; + __u8 err:1; + __u8:6; +#endif + __be16 rsvd; + __be16 len; + __be64 tstamp; + __be64 rsvd1; +}; + struct cpl_l2t_write_req { WR_HDR; union opcode_tid ot; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index a0dcccd846c9..93444325b1e8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -574,7 +574,7 @@ struct fw_eth_tx_pkt_vm_wr { __be16 vlantci; }; -#define FW_CMD_MAX_TIMEOUT 3000 +#define FW_CMD_MAX_TIMEOUT 10000 /* * If a host driver does a HELLO and discovers that there's already a MASTER -- cgit From 0a57a5366a9878ba2a038f8eba08c6ffa180ab2f Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:49 +0000 Subject: cxgb4: Initialize T5 Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 85 +++++++++---- drivers/net/ethernet/chelsio/cxgb4/sge.c | 37 ++++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 152 +++++++++++++++++++++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 1 - 4 files changed, 227 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index e707e31abd81..dd7bcc2a87e7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -233,7 +233,9 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { }; #define FW_FNAME "cxgb4/t4fw.bin" +#define FW5_FNAME "cxgb4/t5fw.bin" #define FW_CFNAME "cxgb4/t4-config.txt" +#define FW5_CFNAME "cxgb4/t5-config.txt" MODULE_DESCRIPTION(DRV_DESC); MODULE_AUTHOR("Chelsio Communications"); @@ -241,6 +243,7 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRV_VERSION); MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); MODULE_FIRMWARE(FW_FNAME); +MODULE_FIRMWARE(FW5_FNAME); /* * Normally we're willing to become the firmware's Master PF but will be happy @@ -319,10 +322,14 @@ static bool vf_acls; module_param(vf_acls, bool, 0644); MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement"); -static unsigned int num_vf[4]; +/* Since T5 has more num of PFs, using NUM_OF_PF_WITH_SRIOV_T5 + * macro as num_vf array size + */ +static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV_T5]; module_param_array(num_vf, uint, NULL, 0644); -MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3"); +MODULE_PARM_DESC(num_vf, + "number of VFs for each of PFs 0-3 for T4 and PFs 0-7 for T5"); #endif /* @@ -1002,21 +1009,36 @@ freeout: t4_free_sge_resources(adap); static int upgrade_fw(struct adapter *adap) { int ret; - u32 vers; + u32 vers, exp_major; const struct fw_hdr *hdr; const struct firmware *fw; struct device *dev = adap->pdev_dev; + char *fw_file_name; - ret = request_firmware(&fw, FW_FNAME, dev); + switch (CHELSIO_CHIP_VERSION(adap->chip)) { + case CHELSIO_T4: + fw_file_name = FW_FNAME; + exp_major = FW_VERSION_MAJOR; + break; + case CHELSIO_T5: + fw_file_name = FW5_FNAME; + exp_major = FW_VERSION_MAJOR_T5; + break; + default: + dev_err(dev, "Unsupported chip type, %x\n", adap->chip); + return -EINVAL; + } + + ret = request_firmware(&fw, fw_file_name, dev); if (ret < 0) { - dev_err(dev, "unable to load firmware image " FW_FNAME - ", error %d\n", ret); + dev_err(dev, "unable to load firmware image %s, error %d\n", + fw_file_name, ret); return ret; } hdr = (const struct fw_hdr *)fw->data; vers = ntohl(hdr->fw_ver); - if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) { + if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) { ret = -EINVAL; /* wrong major version, won't do */ goto out; } @@ -1024,18 +1046,15 @@ static int upgrade_fw(struct adapter *adap) /* * If the flash FW is unusable or we found something newer, load it. */ - if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR || + if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major || vers > adap->params.fw_vers) { dev_info(dev, "upgrading firmware ...\n"); ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size, /*force=*/false); if (!ret) - dev_info(dev, "firmware successfully upgraded to " - FW_FNAME " (%d.%d.%d.%d)\n", - FW_HDR_FW_VER_MAJOR_GET(vers), - FW_HDR_FW_VER_MINOR_GET(vers), - FW_HDR_FW_VER_MICRO_GET(vers), - FW_HDR_FW_VER_BUILD_GET(vers)); + dev_info(dev, + "firmware upgraded to version %pI4 from %s\n", + &hdr->fw_ver, fw_file_name); else dev_err(dev, "firmware upgrade failed! err=%d\n", -ret); } else { @@ -1413,7 +1432,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, */ static inline unsigned int mk_adap_vers(const struct adapter *ap) { - return 4 | (ap->params.rev << 10) | (1 << 16); + return CHELSIO_CHIP_VERSION(ap->chip) | + (CHELSIO_CHIP_RELEASE(ap->chip) << 10) | (1 << 16); } static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, @@ -3745,6 +3765,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) unsigned long mtype = 0, maddr = 0; u32 finiver, finicsum, cfcsum; int ret, using_flash; + char *fw_config_file, fw_config_file_path[256]; /* * Reset device if necessary. @@ -3761,7 +3782,21 @@ static int adap_init0_config(struct adapter *adapter, int reset) * then use that. Otherwise, use the configuration file stored * in the adapter flash ... */ - ret = request_firmware(&cf, FW_CFNAME, adapter->pdev_dev); + switch (CHELSIO_CHIP_VERSION(adapter->chip)) { + case CHELSIO_T4: + fw_config_file = FW_CFNAME; + break; + case CHELSIO_T5: + fw_config_file = FW5_CFNAME; + break; + default: + dev_err(adapter->pdev_dev, "Device %d is not supported\n", + adapter->pdev->device); + ret = -EINVAL; + goto bye; + } + + ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev); if (ret < 0) { using_flash = 1; mtype = FW_MEMTYPE_CF_FLASH; @@ -3877,6 +3912,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) if (ret < 0) goto bye; + sprintf(fw_config_file_path, "/lib/firmware/%s", fw_config_file); /* * Return successfully and note that we're operating with parameters * not supplied by the driver, rather than from hard-wired @@ -3887,7 +3923,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) "Configuration File %s, version %#x, computed checksum %#x\n", (using_flash ? "in device FLASH" - : "/lib/firmware/" FW_CFNAME), + : fw_config_file_path), finiver, cfcsum); return 0; @@ -4015,8 +4051,10 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) */ { int pf, vf; + int max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 : + NUM_OF_PF_WITH_SRIOV_T5; - for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) { + for (pf = 0; pf < max_no_pf; pf++) { if (num_vf[pf] <= 0) continue; @@ -4814,7 +4852,8 @@ static void print_port_info(const struct net_device *dev) sprintf(bufp, "BASE-%s", base[pi->port_type]); netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", - adap->params.vpd.id, adap->params.rev, buf, + adap->params.vpd.id, + CHELSIO_CHIP_RELEASE(adap->params.rev), buf, is_offload(adap) ? "R" : "", adap->params.pci.width, spd, (adap->flags & USING_MSIX) ? " MSI-X" : (adap->flags & USING_MSI) ? " MSI" : ""); @@ -4861,6 +4900,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct port_info *pi; bool highdma = false; struct adapter *adapter = NULL; +#ifdef CONFIG_PCI_IOV + int max_no_pf; +#endif printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); @@ -5052,7 +5094,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) sriov: #ifdef CONFIG_PCI_IOV - if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) + max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 : + NUM_OF_PF_WITH_SRIOV_T5; + + if (func < max_no_pf && num_vf[func] > 0) if (pci_enable_sriov(pdev, num_vf[func]) == 0) dev_info(&pdev->dev, "instantiated %u virtual functions\n", diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index fe9a2ea3588b..7b17623afda3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -506,10 +506,14 @@ static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q) static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q) { + u32 val; if (q->pend_cred >= 8) { + val = PIDX(q->pend_cred / 8); + if (!is_t4(adap->chip)) + val |= DBTYPE(1); wmb(); t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) | - QID(q->cntxt_id) | PIDX(q->pend_cred / 8)); + QID(q->cntxt_id) | val); q->pend_cred &= 7; } } @@ -1555,7 +1559,6 @@ static noinline int handle_trace_pkt(struct adapter *adap, const struct pkt_gl *gl) { struct sk_buff *skb; - struct cpl_trace_pkt *p; skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN); if (unlikely(!skb)) { @@ -1563,8 +1566,11 @@ static noinline int handle_trace_pkt(struct adapter *adap, return 0; } - p = (struct cpl_trace_pkt *)skb->data; - __skb_pull(skb, sizeof(*p)); + if (is_t4(adap->chip)) + __skb_pull(skb, sizeof(struct cpl_trace_pkt)); + else + __skb_pull(skb, sizeof(struct cpl_t5_trace_pkt)); + skb_reset_mac_header(skb); skb->protocol = htons(0xffff); skb->dev = adap->port[0]; @@ -1625,8 +1631,10 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, const struct cpl_rx_pkt *pkt; struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); struct sge *s = &q->adap->sge; + int cpl_trace_pkt = is_t4(q->adap->chip) ? + CPL_TRACE_PKT : CPL_TRACE_PKT_T5; - if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT)) + if (unlikely(*(u8 *)rsp == cpl_trace_pkt)) return handle_trace_pkt(q->adap, si); pkt = (const struct cpl_rx_pkt *)rsp; @@ -2587,11 +2595,20 @@ static int t4_sge_init_hard(struct adapter *adap) * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows * and generate an interrupt when this occurs so we can recover. */ - t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, - V_HP_INT_THRESH(M_HP_INT_THRESH) | - V_LP_INT_THRESH(M_LP_INT_THRESH), - V_HP_INT_THRESH(dbfifo_int_thresh) | - V_LP_INT_THRESH(dbfifo_int_thresh)); + if (is_t4(adap->chip)) { + t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, + V_HP_INT_THRESH(M_HP_INT_THRESH) | + V_LP_INT_THRESH(M_LP_INT_THRESH), + V_HP_INT_THRESH(dbfifo_int_thresh) | + V_LP_INT_THRESH(dbfifo_int_thresh)); + } else { + t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, + V_LP_INT_THRESH_T5(M_LP_INT_THRESH_T5), + V_LP_INT_THRESH_T5(dbfifo_int_thresh)); + t4_set_reg_field(adap, SGE_DBFIFO_STATUS2, + V_HP_INT_THRESH_T5(M_HP_INT_THRESH_T5), + V_HP_INT_THRESH_T5(dbfifo_int_thresh)); + } t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP, F_ENABLE_DROP); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 8049268ce0f2..229a3bfa5ba0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -497,9 +497,9 @@ int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, } #define EEPROM_STAT_ADDR 0x7bfc -#define VPD_LEN 512 #define VPD_BASE 0x400 #define VPD_BASE_OLD 0 +#define VPD_LEN 1024 /** * t4_seeprom_wp - enable/disable EEPROM write protection @@ -856,6 +856,7 @@ int t4_check_fw_version(struct adapter *adapter) { u32 api_vers[2]; int ret, major, minor, micro; + int exp_major, exp_minor, exp_micro; ret = get_fw_version(adapter, &adapter->params.fw_vers); if (!ret) @@ -870,17 +871,35 @@ int t4_check_fw_version(struct adapter *adapter) major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers); minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers); micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers); + + switch (CHELSIO_CHIP_VERSION(adapter->chip)) { + case CHELSIO_T4: + exp_major = FW_VERSION_MAJOR; + exp_minor = FW_VERSION_MINOR; + exp_micro = FW_VERSION_MICRO; + break; + case CHELSIO_T5: + exp_major = FW_VERSION_MAJOR_T5; + exp_minor = FW_VERSION_MINOR_T5; + exp_micro = FW_VERSION_MICRO_T5; + break; + default: + dev_err(adapter->pdev_dev, "Unsupported chip type, %x\n", + adapter->chip); + return -EINVAL; + } + memcpy(adapter->params.api_vers, api_vers, sizeof(adapter->params.api_vers)); - if (major != FW_VERSION_MAJOR) { /* major mismatch - fail */ + if (major != exp_major) { /* major mismatch - fail */ dev_err(adapter->pdev_dev, "card FW has major version %u, driver wants %u\n", - major, FW_VERSION_MAJOR); + major, exp_major); return -EINVAL; } - if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO) + if (minor == exp_minor && micro == exp_micro) return 0; /* perfect match */ /* Minor/micro version mismatch. Report it but often it's OK. */ @@ -1246,6 +1265,45 @@ static void pcie_intr_handler(struct adapter *adapter) { 0 } }; + static struct intr_info t5_pcie_intr_info[] = { + { MSTGRPPERR, "Master Response Read Queue parity error", + -1, 1 }, + { MSTTIMEOUTPERR, "Master Timeout FIFO parity error", -1, 1 }, + { MSIXSTIPERR, "MSI-X STI SRAM parity error", -1, 1 }, + { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 }, + { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 }, + { MSIXDATAPERR, "MSI-X data parity error", -1, 1 }, + { MSIXDIPERR, "MSI-X DI parity error", -1, 1 }, + { PIOCPLGRPPERR, "PCI PIO completion Group FIFO parity error", + -1, 1 }, + { PIOREQGRPPERR, "PCI PIO request Group FIFO parity error", + -1, 1 }, + { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 }, + { MSTTAGQPERR, "PCI master tag queue parity error", -1, 1 }, + { CREQPERR, "PCI CMD channel request parity error", -1, 1 }, + { CRSPPERR, "PCI CMD channel response parity error", -1, 1 }, + { DREQWRPERR, "PCI DMA channel write request parity error", + -1, 1 }, + { DREQPERR, "PCI DMA channel request parity error", -1, 1 }, + { DRSPPERR, "PCI DMA channel response parity error", -1, 1 }, + { HREQWRPERR, "PCI HMA channel count parity error", -1, 1 }, + { HREQPERR, "PCI HMA channel request parity error", -1, 1 }, + { HRSPPERR, "PCI HMA channel response parity error", -1, 1 }, + { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 }, + { FIDPERR, "PCI FID parity error", -1, 1 }, + { VFIDPERR, "PCI INTx clear parity error", -1, 1 }, + { MAGRPPERR, "PCI MA group FIFO parity error", -1, 1 }, + { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 }, + { IPRXHDRGRPPERR, "PCI IP Rx header group parity error", + -1, 1 }, + { IPRXDATAGRPPERR, "PCI IP Rx data group parity error", -1, 1 }, + { RPLPERR, "PCI IP replay buffer parity error", -1, 1 }, + { IPSOTPERR, "PCI IP SOT buffer parity error", -1, 1 }, + { TRGT1GRPPERR, "PCI TRGT1 group FIFOs parity error", -1, 1 }, + { READRSPERR, "Outbound read error", -1, 0 }, + { 0 } + }; + int fat; fat = t4_handle_intr_status(adapter, @@ -1254,7 +1312,10 @@ static void pcie_intr_handler(struct adapter *adapter) t4_handle_intr_status(adapter, PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, pcie_port_intr_info) + - t4_handle_intr_status(adapter, PCIE_INT_CAUSE, pcie_intr_info); + t4_handle_intr_status(adapter, PCIE_INT_CAUSE, + is_t4(adapter->chip) ? + pcie_intr_info : t5_pcie_intr_info); + if (fat) t4_fatal_err(adapter); } @@ -1664,7 +1725,14 @@ static void ncsi_intr_handler(struct adapter *adap) */ static void xgmac_intr_handler(struct adapter *adap, int port) { - u32 v = t4_read_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE)); + u32 v, int_cause_reg; + + if (is_t4(adap->chip)) + int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE); + else + int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE); + + v = t4_read_reg(adap, int_cause_reg); v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR; if (!v) @@ -2126,7 +2194,9 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) u32 bgmap = get_mps_bg_map(adap, idx); #define GET_STAT(name) \ - t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_##name##_L)) + t4_read_reg64(adap, \ + (is_t4(adap->chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \ + T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L))) #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) p->tx_octets = GET_STAT(TX_PORT_BYTES); @@ -2205,14 +2275,26 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) void t4_wol_magic_enable(struct adapter *adap, unsigned int port, const u8 *addr) { + u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg; + + if (is_t4(adap->chip)) { + mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO); + mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI); + port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); + } else { + mag_id_reg_l = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_LO); + mag_id_reg_h = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_HI); + port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2); + } + if (addr) { - t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO), + t4_write_reg(adap, mag_id_reg_l, (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]); - t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI), + t4_write_reg(adap, mag_id_reg_h, (addr[0] << 8) | addr[1]); } - t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), MAGICEN, + t4_set_reg_field(adap, port_cfg_reg, MAGICEN, addr ? MAGICEN : 0); } @@ -2235,16 +2317,23 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, u64 mask0, u64 mask1, unsigned int crc, bool enable) { int i; + u32 port_cfg_reg; + + if (is_t4(adap->chip)) + port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); + else + port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2); if (!enable) { - t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), - PATEN, 0); + t4_set_reg_field(adap, port_cfg_reg, PATEN, 0); return 0; } if (map > 0xff) return -EINVAL; -#define EPIO_REG(name) PORT_REG(port, XGMAC_PORT_EPIO_##name) +#define EPIO_REG(name) \ + (is_t4(adap->chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \ + T5_PORT_REG(port, MAC_PORT_EPIO_##name)) t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); t4_write_reg(adap, EPIO_REG(DATA2), mask1); @@ -3162,6 +3251,9 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, int i, ret; struct fw_vi_mac_cmd c; struct fw_vi_mac_exact *p; + unsigned int max_naddr = is_t4(adap->chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; if (naddr > 7) return -EINVAL; @@ -3187,8 +3279,8 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); if (idx) - idx[i] = index >= NEXACT_MAC ? 0xffff : index; - if (index < NEXACT_MAC) + idx[i] = index >= max_naddr ? 0xffff : index; + if (index < max_naddr) ret++; else if (hash) *hash |= (1ULL << hash_mac_addr(addr[i])); @@ -3221,6 +3313,9 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, int ret, mode; struct fw_vi_mac_cmd c; struct fw_vi_mac_exact *p = c.u.exact; + unsigned int max_mac_addr = is_t4(adap->chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; if (idx < 0) /* new allocation */ idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; @@ -3238,7 +3333,7 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); if (ret == 0) { ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); - if (ret >= NEXACT_MAC) + if (ret >= max_mac_addr) ret = -ENOMEM; } return ret; @@ -3547,7 +3642,8 @@ static int get_flash_params(struct adapter *adap) */ int t4_prep_adapter(struct adapter *adapter) { - int ret; + int ret, ver; + uint16_t device_id; ret = t4_wait_dev_ready(adapter); if (ret < 0) @@ -3562,6 +3658,28 @@ int t4_prep_adapter(struct adapter *adapter) return ret; } + /* Retrieve adapter's device ID + */ + pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id); + ver = device_id >> 12; + switch (ver) { + case CHELSIO_T4: + adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, + adapter->params.rev); + break; + case CHELSIO_T5: + adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, + adapter->params.rev); + break; + default: + dev_err(adapter->pdev_dev, "Device %d is not supported\n", + device_id); + return -EINVAL; + } + + /* Reassign the updated revision field */ + adapter->params.rev = adapter->chip; + init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); /* diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h index f534ed7e10e9..1d1623be9f1e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h @@ -47,7 +47,6 @@ enum { TCB_SIZE = 128, /* TCB size */ NMTUS = 16, /* size of MTU table */ NCCTRL_WIN = 32, /* # of congestion control windows */ - NEXACT_MAC = 336, /* # of exact MAC address filters */ L2T_SIZE = 4096, /* # of L2T entries */ MBOX_LEN = 64, /* mailbox size in bytes */ TRACE_LEN = 112, /* length of trace data and mask */ -- cgit From 251f9e88a2c1e61071bd0eefa0f5f2e1ebc3fcff Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:50 +0000 Subject: cxgb4: Dump T5 registers Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 452 +++++++++++++++++++++++- 1 file changed, 448 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index dd7bcc2a87e7..3d6d23a53636 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1340,10 +1340,15 @@ static int get_sset_count(struct net_device *dev, int sset) } #define T4_REGMAP_SIZE (160 * 1024) +#define T5_REGMAP_SIZE (332 * 1024) static int get_regs_len(struct net_device *dev) { - return T4_REGMAP_SIZE; + struct adapter *adap = netdev2adap(dev); + if (is_t4(adap->chip)) + return T4_REGMAP_SIZE; + else + return T5_REGMAP_SIZE; } static int get_eeprom_len(struct net_device *dev) @@ -1448,7 +1453,7 @@ static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, static void get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) { - static const unsigned int reg_ranges[] = { + static const unsigned int t4_reg_ranges[] = { 0x1008, 0x1108, 0x1180, 0x11b4, 0x11fc, 0x123c, @@ -1668,13 +1673,452 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, 0x27e00, 0x27e04 }; + static const unsigned int t5_reg_ranges[] = { + 0x1008, 0x1148, + 0x1180, 0x11b4, + 0x11fc, 0x123c, + 0x1280, 0x173c, + 0x1800, 0x18fc, + 0x3000, 0x3028, + 0x3060, 0x30d8, + 0x30e0, 0x30fc, + 0x3140, 0x357c, + 0x35a8, 0x35cc, + 0x35ec, 0x35ec, + 0x3600, 0x5624, + 0x56cc, 0x575c, + 0x580c, 0x5814, + 0x5890, 0x58bc, + 0x5940, 0x59dc, + 0x59fc, 0x5a18, + 0x5a60, 0x5a9c, + 0x5b9c, 0x5bfc, + 0x6000, 0x6040, + 0x6058, 0x614c, + 0x7700, 0x7798, + 0x77c0, 0x78fc, + 0x7b00, 0x7c54, + 0x7d00, 0x7efc, + 0x8dc0, 0x8de0, + 0x8df8, 0x8e84, + 0x8ea0, 0x8f84, + 0x8fc0, 0x90f8, + 0x9400, 0x9470, + 0x9600, 0x96f4, + 0x9800, 0x9808, + 0x9820, 0x983c, + 0x9850, 0x9864, + 0x9c00, 0x9c6c, + 0x9c80, 0x9cec, + 0x9d00, 0x9d6c, + 0x9d80, 0x9dec, + 0x9e00, 0x9e6c, + 0x9e80, 0x9eec, + 0x9f00, 0x9f6c, + 0x9f80, 0xa020, + 0xd004, 0xd03c, + 0xdfc0, 0xdfe0, + 0xe000, 0x11088, + 0x1109c, 0x1117c, + 0x11190, 0x11204, + 0x19040, 0x1906c, + 0x19078, 0x19080, + 0x1908c, 0x19124, + 0x19150, 0x191b0, + 0x191d0, 0x191e8, + 0x19238, 0x19290, + 0x193f8, 0x19474, + 0x19490, 0x194cc, + 0x194f0, 0x194f8, + 0x19c00, 0x19c60, + 0x19c94, 0x19e10, + 0x19e50, 0x19f34, + 0x19f40, 0x19f50, + 0x19f90, 0x19fe4, + 0x1a000, 0x1a06c, + 0x1a0b0, 0x1a120, + 0x1a128, 0x1a138, + 0x1a190, 0x1a1c4, + 0x1a1fc, 0x1a1fc, + 0x1e008, 0x1e00c, + 0x1e040, 0x1e04c, + 0x1e284, 0x1e290, + 0x1e2c0, 0x1e2c0, + 0x1e2e0, 0x1e2e0, + 0x1e300, 0x1e384, + 0x1e3c0, 0x1e3c8, + 0x1e408, 0x1e40c, + 0x1e440, 0x1e44c, + 0x1e684, 0x1e690, + 0x1e6c0, 0x1e6c0, + 0x1e6e0, 0x1e6e0, + 0x1e700, 0x1e784, + 0x1e7c0, 0x1e7c8, + 0x1e808, 0x1e80c, + 0x1e840, 0x1e84c, + 0x1ea84, 0x1ea90, + 0x1eac0, 0x1eac0, + 0x1eae0, 0x1eae0, + 0x1eb00, 0x1eb84, + 0x1ebc0, 0x1ebc8, + 0x1ec08, 0x1ec0c, + 0x1ec40, 0x1ec4c, + 0x1ee84, 0x1ee90, + 0x1eec0, 0x1eec0, + 0x1eee0, 0x1eee0, + 0x1ef00, 0x1ef84, + 0x1efc0, 0x1efc8, + 0x1f008, 0x1f00c, + 0x1f040, 0x1f04c, + 0x1f284, 0x1f290, + 0x1f2c0, 0x1f2c0, + 0x1f2e0, 0x1f2e0, + 0x1f300, 0x1f384, + 0x1f3c0, 0x1f3c8, + 0x1f408, 0x1f40c, + 0x1f440, 0x1f44c, + 0x1f684, 0x1f690, + 0x1f6c0, 0x1f6c0, + 0x1f6e0, 0x1f6e0, + 0x1f700, 0x1f784, + 0x1f7c0, 0x1f7c8, + 0x1f808, 0x1f80c, + 0x1f840, 0x1f84c, + 0x1fa84, 0x1fa90, + 0x1fac0, 0x1fac0, + 0x1fae0, 0x1fae0, + 0x1fb00, 0x1fb84, + 0x1fbc0, 0x1fbc8, + 0x1fc08, 0x1fc0c, + 0x1fc40, 0x1fc4c, + 0x1fe84, 0x1fe90, + 0x1fec0, 0x1fec0, + 0x1fee0, 0x1fee0, + 0x1ff00, 0x1ff84, + 0x1ffc0, 0x1ffc8, + 0x30000, 0x30030, + 0x30100, 0x30144, + 0x30190, 0x301d0, + 0x30200, 0x30318, + 0x30400, 0x3052c, + 0x30540, 0x3061c, + 0x30800, 0x30834, + 0x308c0, 0x30908, + 0x30910, 0x309ac, + 0x30a00, 0x30a04, + 0x30a0c, 0x30a2c, + 0x30a44, 0x30a50, + 0x30a74, 0x30c24, + 0x30d08, 0x30d14, + 0x30d1c, 0x30d20, + 0x30d3c, 0x30d50, + 0x31200, 0x3120c, + 0x31220, 0x31220, + 0x31240, 0x31240, + 0x31600, 0x31600, + 0x31608, 0x3160c, + 0x31a00, 0x31a1c, + 0x31e04, 0x31e20, + 0x31e38, 0x31e3c, + 0x31e80, 0x31e80, + 0x31e88, 0x31ea8, + 0x31eb0, 0x31eb4, + 0x31ec8, 0x31ed4, + 0x31fb8, 0x32004, + 0x32208, 0x3223c, + 0x32600, 0x32630, + 0x32a00, 0x32abc, + 0x32b00, 0x32b70, + 0x33000, 0x33048, + 0x33060, 0x3309c, + 0x330f0, 0x33148, + 0x33160, 0x3319c, + 0x331f0, 0x332e4, + 0x332f8, 0x333e4, + 0x333f8, 0x33448, + 0x33460, 0x3349c, + 0x334f0, 0x33548, + 0x33560, 0x3359c, + 0x335f0, 0x336e4, + 0x336f8, 0x337e4, + 0x337f8, 0x337fc, + 0x33814, 0x33814, + 0x3382c, 0x3382c, + 0x33880, 0x3388c, + 0x338e8, 0x338ec, + 0x33900, 0x33948, + 0x33960, 0x3399c, + 0x339f0, 0x33ae4, + 0x33af8, 0x33b10, + 0x33b28, 0x33b28, + 0x33b3c, 0x33b50, + 0x33bf0, 0x33c10, + 0x33c28, 0x33c28, + 0x33c3c, 0x33c50, + 0x33cf0, 0x33cfc, + 0x34000, 0x34030, + 0x34100, 0x34144, + 0x34190, 0x341d0, + 0x34200, 0x34318, + 0x34400, 0x3452c, + 0x34540, 0x3461c, + 0x34800, 0x34834, + 0x348c0, 0x34908, + 0x34910, 0x349ac, + 0x34a00, 0x34a04, + 0x34a0c, 0x34a2c, + 0x34a44, 0x34a50, + 0x34a74, 0x34c24, + 0x34d08, 0x34d14, + 0x34d1c, 0x34d20, + 0x34d3c, 0x34d50, + 0x35200, 0x3520c, + 0x35220, 0x35220, + 0x35240, 0x35240, + 0x35600, 0x35600, + 0x35608, 0x3560c, + 0x35a00, 0x35a1c, + 0x35e04, 0x35e20, + 0x35e38, 0x35e3c, + 0x35e80, 0x35e80, + 0x35e88, 0x35ea8, + 0x35eb0, 0x35eb4, + 0x35ec8, 0x35ed4, + 0x35fb8, 0x36004, + 0x36208, 0x3623c, + 0x36600, 0x36630, + 0x36a00, 0x36abc, + 0x36b00, 0x36b70, + 0x37000, 0x37048, + 0x37060, 0x3709c, + 0x370f0, 0x37148, + 0x37160, 0x3719c, + 0x371f0, 0x372e4, + 0x372f8, 0x373e4, + 0x373f8, 0x37448, + 0x37460, 0x3749c, + 0x374f0, 0x37548, + 0x37560, 0x3759c, + 0x375f0, 0x376e4, + 0x376f8, 0x377e4, + 0x377f8, 0x377fc, + 0x37814, 0x37814, + 0x3782c, 0x3782c, + 0x37880, 0x3788c, + 0x378e8, 0x378ec, + 0x37900, 0x37948, + 0x37960, 0x3799c, + 0x379f0, 0x37ae4, + 0x37af8, 0x37b10, + 0x37b28, 0x37b28, + 0x37b3c, 0x37b50, + 0x37bf0, 0x37c10, + 0x37c28, 0x37c28, + 0x37c3c, 0x37c50, + 0x37cf0, 0x37cfc, + 0x38000, 0x38030, + 0x38100, 0x38144, + 0x38190, 0x381d0, + 0x38200, 0x38318, + 0x38400, 0x3852c, + 0x38540, 0x3861c, + 0x38800, 0x38834, + 0x388c0, 0x38908, + 0x38910, 0x389ac, + 0x38a00, 0x38a04, + 0x38a0c, 0x38a2c, + 0x38a44, 0x38a50, + 0x38a74, 0x38c24, + 0x38d08, 0x38d14, + 0x38d1c, 0x38d20, + 0x38d3c, 0x38d50, + 0x39200, 0x3920c, + 0x39220, 0x39220, + 0x39240, 0x39240, + 0x39600, 0x39600, + 0x39608, 0x3960c, + 0x39a00, 0x39a1c, + 0x39e04, 0x39e20, + 0x39e38, 0x39e3c, + 0x39e80, 0x39e80, + 0x39e88, 0x39ea8, + 0x39eb0, 0x39eb4, + 0x39ec8, 0x39ed4, + 0x39fb8, 0x3a004, + 0x3a208, 0x3a23c, + 0x3a600, 0x3a630, + 0x3aa00, 0x3aabc, + 0x3ab00, 0x3ab70, + 0x3b000, 0x3b048, + 0x3b060, 0x3b09c, + 0x3b0f0, 0x3b148, + 0x3b160, 0x3b19c, + 0x3b1f0, 0x3b2e4, + 0x3b2f8, 0x3b3e4, + 0x3b3f8, 0x3b448, + 0x3b460, 0x3b49c, + 0x3b4f0, 0x3b548, + 0x3b560, 0x3b59c, + 0x3b5f0, 0x3b6e4, + 0x3b6f8, 0x3b7e4, + 0x3b7f8, 0x3b7fc, + 0x3b814, 0x3b814, + 0x3b82c, 0x3b82c, + 0x3b880, 0x3b88c, + 0x3b8e8, 0x3b8ec, + 0x3b900, 0x3b948, + 0x3b960, 0x3b99c, + 0x3b9f0, 0x3bae4, + 0x3baf8, 0x3bb10, + 0x3bb28, 0x3bb28, + 0x3bb3c, 0x3bb50, + 0x3bbf0, 0x3bc10, + 0x3bc28, 0x3bc28, + 0x3bc3c, 0x3bc50, + 0x3bcf0, 0x3bcfc, + 0x3c000, 0x3c030, + 0x3c100, 0x3c144, + 0x3c190, 0x3c1d0, + 0x3c200, 0x3c318, + 0x3c400, 0x3c52c, + 0x3c540, 0x3c61c, + 0x3c800, 0x3c834, + 0x3c8c0, 0x3c908, + 0x3c910, 0x3c9ac, + 0x3ca00, 0x3ca04, + 0x3ca0c, 0x3ca2c, + 0x3ca44, 0x3ca50, + 0x3ca74, 0x3cc24, + 0x3cd08, 0x3cd14, + 0x3cd1c, 0x3cd20, + 0x3cd3c, 0x3cd50, + 0x3d200, 0x3d20c, + 0x3d220, 0x3d220, + 0x3d240, 0x3d240, + 0x3d600, 0x3d600, + 0x3d608, 0x3d60c, + 0x3da00, 0x3da1c, + 0x3de04, 0x3de20, + 0x3de38, 0x3de3c, + 0x3de80, 0x3de80, + 0x3de88, 0x3dea8, + 0x3deb0, 0x3deb4, + 0x3dec8, 0x3ded4, + 0x3dfb8, 0x3e004, + 0x3e208, 0x3e23c, + 0x3e600, 0x3e630, + 0x3ea00, 0x3eabc, + 0x3eb00, 0x3eb70, + 0x3f000, 0x3f048, + 0x3f060, 0x3f09c, + 0x3f0f0, 0x3f148, + 0x3f160, 0x3f19c, + 0x3f1f0, 0x3f2e4, + 0x3f2f8, 0x3f3e4, + 0x3f3f8, 0x3f448, + 0x3f460, 0x3f49c, + 0x3f4f0, 0x3f548, + 0x3f560, 0x3f59c, + 0x3f5f0, 0x3f6e4, + 0x3f6f8, 0x3f7e4, + 0x3f7f8, 0x3f7fc, + 0x3f814, 0x3f814, + 0x3f82c, 0x3f82c, + 0x3f880, 0x3f88c, + 0x3f8e8, 0x3f8ec, + 0x3f900, 0x3f948, + 0x3f960, 0x3f99c, + 0x3f9f0, 0x3fae4, + 0x3faf8, 0x3fb10, + 0x3fb28, 0x3fb28, + 0x3fb3c, 0x3fb50, + 0x3fbf0, 0x3fc10, + 0x3fc28, 0x3fc28, + 0x3fc3c, 0x3fc50, + 0x3fcf0, 0x3fcfc, + 0x40000, 0x4000c, + 0x40040, 0x40068, + 0x40080, 0x40144, + 0x40180, 0x4018c, + 0x40200, 0x40298, + 0x402ac, 0x4033c, + 0x403f8, 0x403fc, + 0x41300, 0x413c4, + 0x41400, 0x4141c, + 0x41480, 0x414d0, + 0x44000, 0x44078, + 0x440c0, 0x44278, + 0x442c0, 0x44478, + 0x444c0, 0x44678, + 0x446c0, 0x44878, + 0x448c0, 0x449fc, + 0x45000, 0x45068, + 0x45080, 0x45084, + 0x450a0, 0x450b0, + 0x45200, 0x45268, + 0x45280, 0x45284, + 0x452a0, 0x452b0, + 0x460c0, 0x460e4, + 0x47000, 0x4708c, + 0x47200, 0x47250, + 0x47400, 0x47420, + 0x47600, 0x47618, + 0x47800, 0x47814, + 0x48000, 0x4800c, + 0x48040, 0x48068, + 0x48080, 0x48144, + 0x48180, 0x4818c, + 0x48200, 0x48298, + 0x482ac, 0x4833c, + 0x483f8, 0x483fc, + 0x49300, 0x493c4, + 0x49400, 0x4941c, + 0x49480, 0x494d0, + 0x4c000, 0x4c078, + 0x4c0c0, 0x4c278, + 0x4c2c0, 0x4c478, + 0x4c4c0, 0x4c678, + 0x4c6c0, 0x4c878, + 0x4c8c0, 0x4c9fc, + 0x4d000, 0x4d068, + 0x4d080, 0x4d084, + 0x4d0a0, 0x4d0b0, + 0x4d200, 0x4d268, + 0x4d280, 0x4d284, + 0x4d2a0, 0x4d2b0, + 0x4e0c0, 0x4e0e4, + 0x4f000, 0x4f08c, + 0x4f200, 0x4f250, + 0x4f400, 0x4f420, + 0x4f600, 0x4f618, + 0x4f800, 0x4f814, + 0x50000, 0x500cc, + 0x50400, 0x50400, + 0x50800, 0x508cc, + 0x50c00, 0x50c00, + 0x51000, 0x5101c, + 0x51300, 0x51308, + }; + int i; struct adapter *ap = netdev2adap(dev); + static const unsigned int *reg_ranges; + int arr_size = 0, buf_size = 0; + + if (is_t4(ap->chip)) { + reg_ranges = &t4_reg_ranges[0]; + arr_size = ARRAY_SIZE(t4_reg_ranges); + buf_size = T4_REGMAP_SIZE; + } else { + reg_ranges = &t5_reg_ranges[0]; + arr_size = ARRAY_SIZE(t5_reg_ranges); + buf_size = T5_REGMAP_SIZE; + } regs->version = mk_adap_vers(ap); - memset(buf, 0, T4_REGMAP_SIZE); - for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2) + memset(buf, 0, buf_size); + for (i = 0; i < arr_size; i += 2) reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]); } -- cgit From 22adfe0a85ca3808e09e7b4787cb08299d89aeaa Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:51 +0000 Subject: cxgb4: Add T5 write combining support This patch implements a low latency Write Combining (aka Write Coalescing) work request path. PCIE maps User Space Doorbell BAR2 region writes to the new interface to SGE. SGE pulls a new message from PCIE new interface and if its a coalesced write work request then pushes it for processing. This patch copies coalesced work request to memory mapped BAR2 space. Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 53 ++++++++++++++++++++++++- drivers/net/ethernet/chelsio/cxgb4/sge.c | 52 ++++++++++++++++++++++-- 3 files changed, 102 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index a91dea621fcf..f8ff30e749b0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -439,6 +439,7 @@ struct sge_txq { spinlock_t db_lock; int db_disabled; unsigned short db_pidx; + u64 udb; }; struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */ @@ -543,6 +544,7 @@ enum chip_type { struct adapter { void __iomem *regs; + void __iomem *bar2; struct pci_dev *pdev; struct device *pdev_dev; unsigned int mbox; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 3d6d23a53636..ce1451cb5a26 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1327,6 +1327,8 @@ static char stats_strings[][ETH_GSTRING_LEN] = { "VLANinsertions ", "GROpackets ", "GROmerged ", + "WriteCoalSuccess ", + "WriteCoalFail ", }; static int get_sset_count(struct net_device *dev, int sset) @@ -1422,11 +1424,25 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; + u32 val1, val2; t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data); data += sizeof(struct port_stats) / sizeof(u64); collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); + data += sizeof(struct queue_port_stats) / sizeof(u64); + if (!is_t4(adapter->chip)) { + t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7)); + val1 = t4_read_reg(adapter, SGE_STAT_TOTAL); + val2 = t4_read_reg(adapter, SGE_STAT_MATCH); + *data = val1 - val2; + data++; + *data = val2; + data++; + } else { + memset(data, 0, 2 * sizeof(u64)); + *data += 2; + } } /* @@ -5337,10 +5353,11 @@ static void free_some_resources(struct adapter *adapter) #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) +#define SEGMENT_SIZE 128 static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - int func, i, err; + int func, i, err, s_qpp, qpp, num_seg; struct port_info *pi; bool highdma = false; struct adapter *adapter = NULL; @@ -5420,7 +5437,34 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) err = t4_prep_adapter(adapter); if (err) - goto out_unmap_bar; + goto out_unmap_bar0; + + if (!is_t4(adapter->chip)) { + s_qpp = QUEUESPERPAGEPF1 * adapter->fn; + qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter, + SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp); + num_seg = PAGE_SIZE / SEGMENT_SIZE; + + /* Each segment size is 128B. Write coalescing is enabled only + * when SGE_EGRESS_QUEUES_PER_PAGE_PF reg value for the + * queue is less no of segments that can be accommodated in + * a page size. + */ + if (qpp > num_seg) { + dev_err(&pdev->dev, + "Incorrect number of egress queues per page\n"); + err = -EINVAL; + goto out_unmap_bar0; + } + adapter->bar2 = ioremap_wc(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); + if (!adapter->bar2) { + dev_err(&pdev->dev, "cannot map device bar2 region\n"); + err = -ENOMEM; + goto out_unmap_bar0; + } + } + setup_memwin(adapter); err = adap_init0(adapter); setup_memwin_rdma(adapter); @@ -5552,6 +5596,9 @@ sriov: out_free_dev: free_some_resources(adapter); out_unmap_bar: + if (!is_t4(adapter->chip)) + iounmap(adapter->bar2); + out_unmap_bar0: iounmap(adapter->regs); out_free_adapter: kfree(adapter); @@ -5602,6 +5649,8 @@ static void remove_one(struct pci_dev *pdev) free_some_resources(adapter); iounmap(adapter->regs); + if (!is_t4(adapter->chip)) + iounmap(adapter->bar2); kfree(adapter); pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 7b17623afda3..8b47b253e204 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -816,6 +816,22 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, *end = 0; } +/* This function copies 64 byte coalesced work request to + * memory mapped BAR2 space(user space writes). + * For coalesced WR SGE, fetches data from the FIFO instead of from Host. + */ +static void cxgb_pio_copy(u64 __iomem *dst, u64 *src) +{ + int count = 8; + + while (count) { + writeq(*src, dst); + src++; + dst++; + count--; + } +} + /** * ring_tx_db - check and potentially ring a Tx queue's doorbell * @adap: the adapter @@ -826,11 +842,25 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, */ static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n) { + unsigned int *wr, index; + wmb(); /* write descriptors before telling HW */ spin_lock(&q->db_lock); if (!q->db_disabled) { - t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), - QID(q->cntxt_id) | PIDX(n)); + if (is_t4(adap->chip)) { + t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), + QID(q->cntxt_id) | PIDX(n)); + } else { + if (n == 1) { + index = q->pidx ? (q->pidx - 1) : (q->size - 1); + wr = (unsigned int *)&q->desc[index]; + cxgb_pio_copy((u64 __iomem *) + (adap->bar2 + q->udb + 64), + (u64 *)wr); + } else + writel(n, adap->bar2 + q->udb + 8); + wmb(); + } } q->db_pidx = q->pidx; spin_unlock(&q->db_lock); @@ -2151,11 +2181,27 @@ err: static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) { + q->cntxt_id = id; + if (!is_t4(adap->chip)) { + unsigned int s_qpp; + unsigned short udb_density; + unsigned long qpshift; + int page; + + s_qpp = QUEUESPERPAGEPF1 * adap->fn; + udb_density = 1 << QUEUESPERPAGEPF0_GET((t4_read_reg(adap, + SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp)); + qpshift = PAGE_SHIFT - ilog2(udb_density); + q->udb = q->cntxt_id << qpshift; + q->udb &= PAGE_MASK; + page = q->udb / PAGE_SIZE; + q->udb += (q->cntxt_id - (page * udb_density)) * 128; + } + q->in_use = 0; q->cidx = q->pidx = 0; q->stops = q->restarts = 0; q->stat = (void *)&q->desc[q->size]; - q->cntxt_id = id; spin_lock_init(&q->db_lock); adap->sge.egr_map[id - adap->sge.egr_start] = q; } -- cgit From 2cc301d20f80ecf532754aad39e150f488acdcb7 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:52 +0000 Subject: cxgb4: Enable doorbell drop recovery only for T4 adapter Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 87 ++++++++++++++++++++----- 1 file changed, 71 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index ce1451cb5a26..177d0c199e01 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3227,10 +3227,18 @@ EXPORT_SYMBOL(cxgb4_port_chan); unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo) { struct adapter *adap = netdev2adap(dev); - u32 v; + u32 v1, v2, lp_count, hp_count; - v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); - return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v); + v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); + v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); + if (is_t4(adap->chip)) { + lp_count = G_LP_COUNT(v1); + hp_count = G_HP_COUNT(v1); + } else { + lp_count = G_LP_COUNT_T5(v1); + hp_count = G_HP_COUNT_T5(v2); + } + return lpfifo ? lp_count : hp_count; } EXPORT_SYMBOL(cxgb4_dbfifo_count); @@ -3368,14 +3376,23 @@ static struct notifier_block cxgb4_netevent_nb = { static void drain_db_fifo(struct adapter *adap, int usecs) { - u32 v; + u32 v1, v2, lp_count, hp_count; do { + v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); + v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); + if (is_t4(adap->chip)) { + lp_count = G_LP_COUNT(v1); + hp_count = G_HP_COUNT(v1); + } else { + lp_count = G_LP_COUNT_T5(v1); + hp_count = G_HP_COUNT_T5(v2); + } + + if (lp_count == 0 && hp_count == 0) + break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(usecs_to_jiffies(usecs)); - v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); - if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0) - break; } while (1); } @@ -3484,24 +3501,62 @@ static void process_db_drop(struct work_struct *work) adap = container_of(work, struct adapter, db_drop_task); + if (is_t4(adap->chip)) { + disable_dbs(adap); + notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); + drain_db_fifo(adap, 1); + recover_all_queues(adap); + enable_dbs(adap); + } else { + u32 dropped_db = t4_read_reg(adap, 0x010ac); + u16 qid = (dropped_db >> 15) & 0x1ffff; + u16 pidx_inc = dropped_db & 0x1fff; + unsigned int s_qpp; + unsigned short udb_density; + unsigned long qpshift; + int page; + u32 udb; + + dev_warn(adap->pdev_dev, + "Dropped DB 0x%x qid %d bar2 %d coalesce %d pidx %d\n", + dropped_db, qid, + (dropped_db >> 14) & 1, + (dropped_db >> 13) & 1, + pidx_inc); + + drain_db_fifo(adap, 1); + + s_qpp = QUEUESPERPAGEPF1 * adap->fn; + udb_density = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adap, + SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp); + qpshift = PAGE_SHIFT - ilog2(udb_density); + udb = qid << qpshift; + udb &= PAGE_MASK; + page = udb / PAGE_SIZE; + udb += (qid - (page * udb_density)) * 128; + + writel(PIDX(pidx_inc), adap->bar2 + udb + 8); + + /* Re-enable BAR2 WC */ + t4_set_reg_field(adap, 0x10b0, 1<<15, 1<<15); + } + t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0); - disable_dbs(adap); - notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); - drain_db_fifo(adap, 1); - recover_all_queues(adap); - enable_dbs(adap); } void t4_db_full(struct adapter *adap) { - t4_set_reg_field(adap, SGE_INT_ENABLE3, - DBFIFO_HP_INT | DBFIFO_LP_INT, 0); - queue_work(workq, &adap->db_full_task); + if (is_t4(adap->chip)) { + t4_set_reg_field(adap, SGE_INT_ENABLE3, + DBFIFO_HP_INT | DBFIFO_LP_INT, 0); + queue_work(workq, &adap->db_full_task); + } } void t4_db_dropped(struct adapter *adap) { - queue_work(workq, &adap->db_drop_task); + if (is_t4(adap->chip)) + queue_work(workq, &adap->db_drop_task); } static void uld_attach(struct adapter *adap, unsigned int uld) -- cgit From 19dd37ba45f1f0593a6d90eac3a861dad958f6bd Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:53 +0000 Subject: cxgb4: Add T5 debugfs support Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 55 ++++++++++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 104 +++++++++++++++++------- 3 files changed, 119 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index f8ff30e749b0..45b18bdbeab9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -908,7 +908,8 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, unsigned int flags); -int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity); +int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, + u64 *parity); int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 177d0c199e01..ca8807080404 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2843,8 +2843,8 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count, int ret, ofst; __be32 data[16]; - if (mem == MEM_MC) - ret = t4_mc_read(adap, pos, data, NULL); + if ((mem == MEM_MC) || (mem == MEM_MC1)) + ret = t4_mc_read(adap, mem % MEM_MC, pos, data, NULL); else ret = t4_edc_read(adap, mem, pos, data, NULL); if (ret) @@ -2885,18 +2885,37 @@ static void add_debugfs_mem(struct adapter *adap, const char *name, static int setup_debugfs(struct adapter *adap) { int i; + u32 size; if (IS_ERR_OR_NULL(adap->debugfs_root)) return -1; i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); - if (i & EDRAM0_ENABLE) - add_debugfs_mem(adap, "edc0", MEM_EDC0, 5); - if (i & EDRAM1_ENABLE) - add_debugfs_mem(adap, "edc1", MEM_EDC1, 5); - if (i & EXT_MEM_ENABLE) - add_debugfs_mem(adap, "mc", MEM_MC, - EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR))); + if (i & EDRAM0_ENABLE) { + size = t4_read_reg(adap, MA_EDRAM0_BAR); + add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM_SIZE_GET(size)); + } + if (i & EDRAM1_ENABLE) { + size = t4_read_reg(adap, MA_EDRAM1_BAR); + add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); + } + if (is_t4(adap->chip)) { + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + if (i & EXT_MEM_ENABLE) + add_debugfs_mem(adap, "mc", MEM_MC, + EXT_MEM_SIZE_GET(size)); + } else { + if (i & EXT_MEM_ENABLE) { + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + add_debugfs_mem(adap, "mc0", MEM_MC0, + EXT_MEM_SIZE_GET(size)); + } + if (i & EXT_MEM1_ENABLE) { + size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR); + add_debugfs_mem(adap, "mc1", MEM_MC1, + EXT_MEM_SIZE_GET(size)); + } + } if (adap->l2t) debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap, &t4_l2t_fops); @@ -4101,17 +4120,27 @@ void t4_fatal_err(struct adapter *adap) static void setup_memwin(struct adapter *adap) { - u32 bar0; + u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base; bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ + if (is_t4(adap->chip)) { + mem_win0_base = bar0 + MEMWIN0_BASE; + mem_win1_base = bar0 + MEMWIN1_BASE; + mem_win2_base = bar0 + MEMWIN2_BASE; + } else { + /* For T5, only relative offset inside the PCIe BAR is passed */ + mem_win0_base = MEMWIN0_BASE; + mem_win1_base = MEMWIN1_BASE_T5; + mem_win2_base = MEMWIN2_BASE_T5; + } t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0), - (bar0 + MEMWIN0_BASE) | BIR(0) | + mem_win0_base | BIR(0) | WINDOW(ilog2(MEMWIN0_APERTURE) - 10)); t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1), - (bar0 + MEMWIN1_BASE) | BIR(0) | + mem_win1_base | BIR(0) | WINDOW(ilog2(MEMWIN1_APERTURE) - 10)); t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2), - (bar0 + MEMWIN2_BASE) | BIR(0) | + mem_win2_base | BIR(0) | WINDOW(ilog2(MEMWIN2_APERTURE) - 10)); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 229a3bfa5ba0..d02d4e8c4417 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -282,6 +282,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, * t4_mc_read - read from MC through backdoor accesses * @adap: the adapter * @addr: address of first byte requested + * @idx: which MC to access * @data: 64 bytes of data containing the requested address * @ecc: where to store the corresponding 64-bit ECC word * @@ -289,22 +290,38 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, * that covers the requested address @addr. If @parity is not %NULL it * is assigned the 64-bit ECC word for the read data. */ -int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc) +int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) { int i; + u32 mc_bist_cmd, mc_bist_cmd_addr, mc_bist_cmd_len; + u32 mc_bist_status_rdata, mc_bist_data_pattern; - if (t4_read_reg(adap, MC_BIST_CMD) & START_BIST) + if (is_t4(adap->chip)) { + mc_bist_cmd = MC_BIST_CMD; + mc_bist_cmd_addr = MC_BIST_CMD_ADDR; + mc_bist_cmd_len = MC_BIST_CMD_LEN; + mc_bist_status_rdata = MC_BIST_STATUS_RDATA; + mc_bist_data_pattern = MC_BIST_DATA_PATTERN; + } else { + mc_bist_cmd = MC_REG(MC_P_BIST_CMD, idx); + mc_bist_cmd_addr = MC_REG(MC_P_BIST_CMD_ADDR, idx); + mc_bist_cmd_len = MC_REG(MC_P_BIST_CMD_LEN, idx); + mc_bist_status_rdata = MC_REG(MC_P_BIST_STATUS_RDATA, idx); + mc_bist_data_pattern = MC_REG(MC_P_BIST_DATA_PATTERN, idx); + } + + if (t4_read_reg(adap, mc_bist_cmd) & START_BIST) return -EBUSY; - t4_write_reg(adap, MC_BIST_CMD_ADDR, addr & ~0x3fU); - t4_write_reg(adap, MC_BIST_CMD_LEN, 64); - t4_write_reg(adap, MC_BIST_DATA_PATTERN, 0xc); - t4_write_reg(adap, MC_BIST_CMD, BIST_OPCODE(1) | START_BIST | + t4_write_reg(adap, mc_bist_cmd_addr, addr & ~0x3fU); + t4_write_reg(adap, mc_bist_cmd_len, 64); + t4_write_reg(adap, mc_bist_data_pattern, 0xc); + t4_write_reg(adap, mc_bist_cmd, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1)); - i = t4_wait_op_done(adap, MC_BIST_CMD, START_BIST, 0, 10, 1); + i = t4_wait_op_done(adap, mc_bist_cmd, START_BIST, 0, 10, 1); if (i) return i; -#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i) +#define MC_DATA(i) MC_BIST_STATUS_REG(mc_bist_status_rdata, i) for (i = 15; i >= 0; i--) *data++ = htonl(t4_read_reg(adap, MC_DATA(i))); @@ -329,20 +346,39 @@ int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc) int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) { int i; + u32 edc_bist_cmd, edc_bist_cmd_addr, edc_bist_cmd_len; + u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata; - idx *= EDC_STRIDE; - if (t4_read_reg(adap, EDC_BIST_CMD + idx) & START_BIST) + if (is_t4(adap->chip)) { + edc_bist_cmd = EDC_REG(EDC_BIST_CMD, idx); + edc_bist_cmd_addr = EDC_REG(EDC_BIST_CMD_ADDR, idx); + edc_bist_cmd_len = EDC_REG(EDC_BIST_CMD_LEN, idx); + edc_bist_cmd_data_pattern = EDC_REG(EDC_BIST_DATA_PATTERN, + idx); + edc_bist_status_rdata = EDC_REG(EDC_BIST_STATUS_RDATA, + idx); + } else { + edc_bist_cmd = EDC_REG_T5(EDC_H_BIST_CMD, idx); + edc_bist_cmd_addr = EDC_REG_T5(EDC_H_BIST_CMD_ADDR, idx); + edc_bist_cmd_len = EDC_REG_T5(EDC_H_BIST_CMD_LEN, idx); + edc_bist_cmd_data_pattern = + EDC_REG_T5(EDC_H_BIST_DATA_PATTERN, idx); + edc_bist_status_rdata = + EDC_REG_T5(EDC_H_BIST_STATUS_RDATA, idx); + } + + if (t4_read_reg(adap, edc_bist_cmd) & START_BIST) return -EBUSY; - t4_write_reg(adap, EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU); - t4_write_reg(adap, EDC_BIST_CMD_LEN + idx, 64); - t4_write_reg(adap, EDC_BIST_DATA_PATTERN + idx, 0xc); - t4_write_reg(adap, EDC_BIST_CMD + idx, + t4_write_reg(adap, edc_bist_cmd_addr, addr & ~0x3fU); + t4_write_reg(adap, edc_bist_cmd_len, 64); + t4_write_reg(adap, edc_bist_cmd_data_pattern, 0xc); + t4_write_reg(adap, edc_bist_cmd, BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST); - i = t4_wait_op_done(adap, EDC_BIST_CMD + idx, START_BIST, 0, 10, 1); + i = t4_wait_op_done(adap, edc_bist_cmd, START_BIST, 0, 10, 1); if (i) return i; -#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx) +#define EDC_DATA(i) (EDC_BIST_STATUS_REG(edc_bist_status_rdata, i)) for (i = 15; i >= 0; i--) *data++ = htonl(t4_read_reg(adap, EDC_DATA(i))); @@ -366,6 +402,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir) { int i; + u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); /* * Setup offset into PCIE memory window. Address must be a @@ -374,7 +411,7 @@ static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir) * values.) */ t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET, - addr & ~(MEMWIN0_APERTURE - 1)); + (addr & ~(MEMWIN0_APERTURE - 1)) | win_pf); t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET); /* Collecting data 4 bytes at a time upto MEMWIN0_APERTURE */ @@ -410,6 +447,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, __be32 *buf, int dir) { u32 pos, start, end, offset, memoffset; + u32 edc_size, mc_size; int ret = 0; __be32 *data; @@ -423,13 +461,21 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, if (!data) return -ENOMEM; - /* - * Offset into the region of memory which is being accessed + /* Offset into the region of memory which is being accessed * MEM_EDC0 = 0 * MEM_EDC1 = 1 - * MEM_MC = 2 + * MEM_MC = 2 -- T4 + * MEM_MC0 = 2 -- For T5 + * MEM_MC1 = 3 -- For T5 */ - memoffset = (mtype * (5 * 1024 * 1024)); + edc_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM0_BAR)); + if (mtype != MEM_MC1) + memoffset = (mtype * (edc_size * 1024 * 1024)); + else { + mc_size = EXT_MEM_SIZE_GET(t4_read_reg(adap, + MA_EXT_MEMORY_BAR)); + memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; + } /* Determine the PCIE_MEM_ACCESS_OFFSET */ addr = addr + memoffset; @@ -2411,24 +2457,24 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, * @addr: address of first byte requested aligned on 32b. * @data: len bytes to hold the data read * @len: amount of data to read from window. Must be <= - * MEMWIN0_APERATURE after adjusting for 16B alignment - * requirements of the the memory window. + * MEMWIN0_APERATURE after adjusting for 16B for T4 and + * 128B for T5 alignment requirements of the the memory window. * * Read len bytes of data from MC starting at @addr. */ int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len) { - int i; - int off; + int i, off; + u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); - /* - * Align on a 16B boundary. + /* Align on a 2KB boundary. */ - off = addr & 15; + off = addr & MEMWIN0_APERTURE; if ((addr & 3) || (len + off) > MEMWIN0_APERTURE) return -EINVAL; - t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET, addr & ~15); + t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET, + (addr & ~MEMWIN0_APERTURE) | win_pf); t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET); for (i = 0; i < len; i += 4) -- cgit From 9616407cbc09663d3de925d9ed41830acb66a5b1 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:54 +0000 Subject: cxgb4: Add T5 PCI ids Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index ca8807080404..eceee44e44c2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -229,6 +229,44 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { CH_DEVICE(0x440a, 4), CH_DEVICE(0x440d, 4), CH_DEVICE(0x440e, 4), + CH_DEVICE(0x5001, 5), + CH_DEVICE(0x5002, 5), + CH_DEVICE(0x5003, 5), + CH_DEVICE(0x5004, 5), + CH_DEVICE(0x5005, 5), + CH_DEVICE(0x5006, 5), + CH_DEVICE(0x5007, 5), + CH_DEVICE(0x5008, 5), + CH_DEVICE(0x5009, 5), + CH_DEVICE(0x500A, 5), + CH_DEVICE(0x500B, 5), + CH_DEVICE(0x500C, 5), + CH_DEVICE(0x500D, 5), + CH_DEVICE(0x500E, 5), + CH_DEVICE(0x500F, 5), + CH_DEVICE(0x5010, 5), + CH_DEVICE(0x5011, 5), + CH_DEVICE(0x5012, 5), + CH_DEVICE(0x5013, 5), + CH_DEVICE(0x5401, 5), + CH_DEVICE(0x5402, 5), + CH_DEVICE(0x5403, 5), + CH_DEVICE(0x5404, 5), + CH_DEVICE(0x5405, 5), + CH_DEVICE(0x5406, 5), + CH_DEVICE(0x5407, 5), + CH_DEVICE(0x5408, 5), + CH_DEVICE(0x5409, 5), + CH_DEVICE(0x540A, 5), + CH_DEVICE(0x540B, 5), + CH_DEVICE(0x540C, 5), + CH_DEVICE(0x540D, 5), + CH_DEVICE(0x540E, 5), + CH_DEVICE(0x540F, 5), + CH_DEVICE(0x5410, 5), + CH_DEVICE(0x5411, 5), + CH_DEVICE(0x5412, 5), + CH_DEVICE(0x5413, 5), { 0, } }; -- cgit From 3a7f85540d171963691b1f6322cef835515e4698 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:55 +0000 Subject: cxgb4: Update driver version and description Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index eceee44e44c2..c502e36ec269 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -68,8 +68,8 @@ #include "t4fw_api.h" #include "l2t.h" -#define DRV_VERSION "1.3.0-ko" -#define DRV_DESC "Chelsio T4 Network Driver" +#define DRV_VERSION "2.0.0-ko" +#define DRV_DESC "Chelsio T4/T5 Network Driver" /* * Max interrupt hold-off timer value in us. Queues fall back to this value -- cgit From 7d6727cfe5815816466b94db5180b8d3ef08fbb0 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:56 +0000 Subject: cxgb4: Disable SR-IOV support for PF4-7 for T5 All T5 adapters will only support VFs on PF0-3 despite the ability of the hardware to support them on PF4-7. This keeps our T4 and T5 adapters more similar which simplifies host driver software. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 ++++---- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 21 ++++++--------------- 2 files changed, 10 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 45b18bdbeab9..681804b30a3f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -534,11 +534,11 @@ enum chip_type { #ifdef CONFIG_PCI_IOV -/* T4 - 4 PFs support SRIOV - * T5 - 8 PFs support SRIOV +/* T4 supports SRIOV on PF0-3 and T5 on PF0-7. However, the Serial + * Configuration initialization for T5 only has SR-IOV functionality enabled + * on PF0-3 in order to simplify everything. */ -#define NUM_OF_PF_WITH_SRIOV_T4 4 -#define NUM_OF_PF_WITH_SRIOV_T5 8 +#define NUM_OF_PF_WITH_SRIOV 4 #endif diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c502e36ec269..a59bb231bea2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -360,14 +360,13 @@ static bool vf_acls; module_param(vf_acls, bool, 0644); MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement"); -/* Since T5 has more num of PFs, using NUM_OF_PF_WITH_SRIOV_T5 - * macro as num_vf array size +/* Configure the number of PCI-E Virtual Function which are to be instantiated + * on SR-IOV Capable Physical Functions. */ -static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV_T5]; +static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV]; module_param_array(num_vf, uint, NULL, 0644); -MODULE_PARM_DESC(num_vf, - "number of VFs for each of PFs 0-3 for T4 and PFs 0-7 for T5"); +MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3"); #endif /* @@ -4633,10 +4632,8 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) */ { int pf, vf; - int max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 : - NUM_OF_PF_WITH_SRIOV_T5; - for (pf = 0; pf < max_no_pf; pf++) { + for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) { if (num_vf[pf] <= 0) continue; @@ -5483,9 +5480,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct port_info *pi; bool highdma = false; struct adapter *adapter = NULL; -#ifdef CONFIG_PCI_IOV - int max_no_pf; -#endif printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); @@ -5704,10 +5698,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) sriov: #ifdef CONFIG_PCI_IOV - max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 : - NUM_OF_PF_WITH_SRIOV_T5; - - if (func < max_no_pf && num_vf[func] > 0) + if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) if (pci_enable_sriov(pdev, num_vf[func]) == 0) dev_info(&pdev->dev, "instantiated %u virtual functions\n", -- cgit From 622c62b52fae7c1367f0fd55442d5e162c052d5f Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Thu, 14 Mar 2013 05:08:57 +0000 Subject: cxgb4vf: Add support for Chelsio T5 adapter Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 1 + .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 35 ++++++++++++++++++++-- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 8 +++-- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 24 +++++++++++++++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 14 ++++++--- 5 files changed, 73 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index 68eaa9c88c7d..be5c7ef6ca93 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h @@ -344,6 +344,7 @@ struct adapter { unsigned long registered_device_map; unsigned long open_device_map; unsigned long flags; + enum chip_type chip; struct adapter_params params; /* queue and interrupt resources */ diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 56b46ab2d4c5..7fcac2003769 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -54,8 +54,8 @@ /* * Generic information about the driver. */ -#define DRV_VERSION "1.0.0" -#define DRV_DESC "Chelsio T4 Virtual Function (VF) Network Driver" +#define DRV_VERSION "2.0.0-ko" +#define DRV_DESC "Chelsio T4/T5 Virtual Function (VF) Network Driver" /* * Module Parameters. @@ -1050,7 +1050,7 @@ static inline unsigned int mk_adap_vers(const struct adapter *adapter) /* * Chip version 4, revision 0x3f (cxgb4vf). */ - return 4 | (0x3f << 10); + return CHELSIO_CHIP_VERSION(adapter->chip) | (0x3f << 10); } /* @@ -2099,6 +2099,15 @@ static int adap_init0(struct adapter *adapter) return err; } + switch (adapter->pdev->device >> 12) { + case CHELSIO_T4: + adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0); + break; + case CHELSIO_T5: + adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, 0); + break; + } + /* * Grab basic operational parameters. These will predominantly have * been set up by the Physical Function Driver or will be hard coded @@ -2888,6 +2897,26 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = { CH_DEVICE(0x480a, 0), /* T404-bt */ CH_DEVICE(0x480d, 0), /* T480-cr */ CH_DEVICE(0x480e, 0), /* T440-lp-cr */ + CH_DEVICE(0x5800, 0), /* T580-dbg */ + CH_DEVICE(0x5801, 0), /* T520-cr */ + CH_DEVICE(0x5802, 0), /* T522-cr */ + CH_DEVICE(0x5803, 0), /* T540-cr */ + CH_DEVICE(0x5804, 0), /* T520-bch */ + CH_DEVICE(0x5805, 0), /* T540-bch */ + CH_DEVICE(0x5806, 0), /* T540-ch */ + CH_DEVICE(0x5807, 0), /* T520-so */ + CH_DEVICE(0x5808, 0), /* T520-cx */ + CH_DEVICE(0x5809, 0), /* T520-bt */ + CH_DEVICE(0x580a, 0), /* T504-bt */ + CH_DEVICE(0x580b, 0), /* T520-sr */ + CH_DEVICE(0x580c, 0), /* T504-bt */ + CH_DEVICE(0x580d, 0), /* T580-cr */ + CH_DEVICE(0x580e, 0), /* T540-lp-cr */ + CH_DEVICE(0x580f, 0), /* Amsterdam */ + CH_DEVICE(0x5810, 0), /* T580-lp-cr */ + CH_DEVICE(0x5811, 0), /* T520-lp-cr */ + CH_DEVICE(0x5812, 0), /* T560-cr */ + CH_DEVICE(0x5813, 0), /* T580-cr */ { 0, } }; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 9488032d6d2d..61dfb2a47929 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -528,17 +528,21 @@ static void unmap_rx_buf(struct adapter *adapter, struct sge_fl *fl) */ static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl) { + u32 val; + /* * The SGE keeps track of its Producer and Consumer Indices in terms * of Egress Queue Units so we can only tell it about integral numbers * of multiples of Free List Entries per Egress Queue Units ... */ if (fl->pend_cred >= FL_PER_EQ_UNIT) { + val = PIDX(fl->pend_cred / FL_PER_EQ_UNIT); + if (!is_t4(adapter->chip)) + val |= DBTYPE(1); wmb(); t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL, DBPRIO(1) | - QID(fl->cntxt_id) | - PIDX(fl->pend_cred / FL_PER_EQ_UNIT)); + QID(fl->cntxt_id) | val); fl->pend_cred %= FL_PER_EQ_UNIT; } } diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 283f9d0d37fd..53cbfed21d0b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -38,6 +38,25 @@ #include "../cxgb4/t4fw_api.h" +#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) +#define CHELSIO_CHIP_VERSION(code) ((code) >> 4) +#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) + +#define CHELSIO_T4 0x4 +#define CHELSIO_T5 0x5 + +enum chip_type { + T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0), + T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), + T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), + T4_FIRST_REV = T4_A1, + T4_LAST_REV = T4_A3, + + T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), + T5_FIRST_REV = T5_A1, + T5_LAST_REV = T5_A1, +}; + /* * The "len16" field of a Firmware Command Structure ... */ @@ -232,6 +251,11 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd, return t4vf_wr_mbox_core(adapter, cmd, size, rpl, false); } +static inline int is_t4(enum chip_type chip) +{ + return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV); +} + int t4vf_wait_dev_ready(struct adapter *); int t4vf_port_init(struct adapter *, int); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 7127c7b9efde..9f96dc3bb112 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -1027,8 +1027,11 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, unsigned nfilters = 0; unsigned int rem = naddr; struct fw_vi_mac_cmd cmd, rpl; + unsigned int max_naddr = is_t4(adapter->chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; - if (naddr > FW_CLS_TCAM_NUM_ENTRIES) + if (naddr > max_naddr) return -EINVAL; for (offset = 0; offset < naddr; /**/) { @@ -1069,10 +1072,10 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, if (idx) idx[offset+i] = - (index >= FW_CLS_TCAM_NUM_ENTRIES + (index >= max_naddr ? 0xffff : index); - if (index < FW_CLS_TCAM_NUM_ENTRIES) + if (index < max_naddr) nfilters++; else if (hash) *hash |= (1ULL << hash_mac_addr(addr[offset+i])); @@ -1118,6 +1121,9 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid, struct fw_vi_mac_exact *p = &cmd.u.exact[0]; size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, u.exact[1]), 16); + unsigned int max_naddr = is_t4(adapter->chip) ? + NUM_MPS_CLS_SRAM_L_INSTANCES : + NUM_MPS_T5_CLS_SRAM_L_INSTANCES; /* * If this is a new allocation, determine whether it should be @@ -1140,7 +1146,7 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid, if (ret == 0) { p = &rpl.u.exact[0]; ret = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx)); - if (ret >= FW_CLS_TCAM_NUM_ENTRIES) + if (ret >= max_naddr) ret = -ENOMEM; } return ret; -- cgit From f079af7a117504b5b307b727858c972261047907 Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:08:58 +0000 Subject: RDMA/cxgb4: Add Support for Chelsio T5 adapter Adds support for Chelsio T5 adapter. Enables T5's Write Combining feature. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 64 +++++++++++++++++++++++++--------- drivers/infiniband/hw/cxgb4/device.c | 13 ++++--- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 9 +++++ drivers/infiniband/hw/cxgb4/provider.c | 15 +++++--- drivers/infiniband/hw/cxgb4/qp.c | 2 +- drivers/infiniband/hw/cxgb4/t4.h | 9 ----- 6 files changed, 77 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 565bfb161c1a..272bf789c53b 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -511,12 +511,16 @@ static unsigned int select_ntuple(struct c4iw_dev *dev, struct dst_entry *dst, static int send_connect(struct c4iw_ep *ep) { struct cpl_act_open_req *req; + struct cpl_t5_act_open_req *t5_req; struct sk_buff *skb; u64 opt0; u32 opt2; unsigned int mtu_idx; int wscale; - int wrlen = roundup(sizeof *req, 16); + int size = is_t4(ep->com.dev->rdev.lldi.adapter_type) ? + sizeof(struct cpl_act_open_req) : + sizeof(struct cpl_t5_act_open_req); + int wrlen = roundup(size, 16); PDBG("%s ep %p atid %u\n", __func__, ep, ep->atid); @@ -552,17 +556,36 @@ static int send_connect(struct c4iw_ep *ep) opt2 |= WND_SCALE_EN(1); t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure); - req = (struct cpl_act_open_req *) skb_put(skb, wrlen); - INIT_TP_WR(req, 0); - OPCODE_TID(req) = cpu_to_be32( - MK_OPCODE_TID(CPL_ACT_OPEN_REQ, ((ep->rss_qid<<14)|ep->atid))); - req->local_port = ep->com.local_addr.sin_port; - req->peer_port = ep->com.remote_addr.sin_port; - req->local_ip = ep->com.local_addr.sin_addr.s_addr; - req->peer_ip = ep->com.remote_addr.sin_addr.s_addr; - req->opt0 = cpu_to_be64(opt0); - req->params = cpu_to_be32(select_ntuple(ep->com.dev, ep->dst, ep->l2t)); - req->opt2 = cpu_to_be32(opt2); + if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) { + req = (struct cpl_act_open_req *) skb_put(skb, wrlen); + INIT_TP_WR(req, 0); + OPCODE_TID(req) = cpu_to_be32( + MK_OPCODE_TID(CPL_ACT_OPEN_REQ, + ((ep->rss_qid << 14) | ep->atid))); + req->local_port = ep->com.local_addr.sin_port; + req->peer_port = ep->com.remote_addr.sin_port; + req->local_ip = ep->com.local_addr.sin_addr.s_addr; + req->peer_ip = ep->com.remote_addr.sin_addr.s_addr; + req->opt0 = cpu_to_be64(opt0); + req->params = cpu_to_be32(select_ntuple(ep->com.dev, + ep->dst, ep->l2t)); + req->opt2 = cpu_to_be32(opt2); + } else { + t5_req = (struct cpl_t5_act_open_req *) skb_put(skb, wrlen); + INIT_TP_WR(t5_req, 0); + OPCODE_TID(t5_req) = cpu_to_be32( + MK_OPCODE_TID(CPL_ACT_OPEN_REQ, + ((ep->rss_qid << 14) | ep->atid))); + t5_req->local_port = ep->com.local_addr.sin_port; + t5_req->peer_port = ep->com.remote_addr.sin_port; + t5_req->local_ip = ep->com.local_addr.sin_addr.s_addr; + t5_req->peer_ip = ep->com.remote_addr.sin_addr.s_addr; + t5_req->opt0 = cpu_to_be64(opt0); + t5_req->params = cpu_to_be64(V_FILTER_TUPLE( + select_ntuple(ep->com.dev, ep->dst, ep->l2t))); + t5_req->opt2 = cpu_to_be32(opt2); + } + set_bit(ACT_OPEN_REQ, &ep->com.history); return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); } @@ -2869,12 +2892,14 @@ static int deferred_fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos) { u32 l2info; - u16 vlantag, len, hdr_len; + u16 vlantag, len, hdr_len, eth_hdr_len; u8 intf; struct cpl_rx_pkt *cpl = cplhdr(skb); struct cpl_pass_accept_req *req; struct tcp_options_received tmp_opt; + struct c4iw_dev *dev; + dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *))); /* Store values from cpl_rx_pkt in temporary location. */ vlantag = (__force u16) cpl->vlan; len = (__force u16) cpl->len; @@ -2898,14 +2923,16 @@ static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos) V_SYN_MAC_IDX(G_RX_MACIDX( (__force int) htonl(l2info))) | F_SYN_XACT_MATCH); + eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ? + G_RX_ETHHDR_LEN((__force int) htonl(l2info)) : + G_RX_T5_ETHHDR_LEN((__force int) htonl(l2info)); req->hdr_len = cpu_to_be32(V_SYN_RX_CHAN(G_RX_CHAN( (__force int) htonl(l2info))) | V_TCP_HDR_LEN(G_RX_TCPHDR_LEN( (__force int) htons(hdr_len))) | V_IP_HDR_LEN(G_RX_IPHDR_LEN( (__force int) htons(hdr_len))) | - V_ETH_HDR_LEN(G_RX_ETHHDR_LEN( - (__force int) htonl(l2info)))); + V_ETH_HDR_LEN(G_RX_ETHHDR_LEN(eth_hdr_len))); req->vlan = (__force __be16) vlantag; req->len = (__force __be16) len; req->tos_stid = cpu_to_be32(PASS_OPEN_TID(stid) | @@ -2993,7 +3020,7 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) u16 window; struct port_info *pi; struct net_device *pdev; - u16 rss_qid; + u16 rss_qid, eth_hdr_len; int step; u32 tx_chan; struct neighbour *neigh; @@ -3022,7 +3049,10 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) goto reject; } - if (G_RX_ETHHDR_LEN(ntohl(cpl->l2info)) == ETH_HLEN) { + eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ? + G_RX_ETHHDR_LEN(htonl(cpl->l2info)) : + G_RX_T5_ETHHDR_LEN(htonl(cpl->l2info)); + if (eth_hdr_len == ETH_HLEN) { eh = (struct ethhdr *)(req + 1); iph = (struct iphdr *)(eh + 1); } else { diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 80069ad595c1..3487c08828f7 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -41,7 +41,7 @@ #define DRV_VERSION "0.1" MODULE_AUTHOR("Steve Wise"); -MODULE_DESCRIPTION("Chelsio T4 RDMA Driver"); +MODULE_DESCRIPTION("Chelsio T4/T5 RDMA Driver"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRV_VERSION); @@ -614,7 +614,7 @@ static int rdma_supported(const struct cxgb4_lld_info *infop) { return infop->vr->stag.size > 0 && infop->vr->pbl.size > 0 && infop->vr->rq.size > 0 && infop->vr->qp.size > 0 && - infop->vr->cq.size > 0 && infop->vr->ocq.size > 0; + infop->vr->cq.size > 0; } static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) @@ -627,6 +627,11 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) pci_name(infop->pdev)); return ERR_PTR(-ENOSYS); } + if (!ocqp_supported(infop)) + pr_info("%s: On-Chip Queues not supported on this device.\n", + pci_name(infop->pdev)); + if (!is_t4(infop->adapter_type)) + db_fc_threshold = 100000; devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); if (!devp) { printk(KERN_ERR MOD "Cannot allocate ib device\n"); @@ -678,8 +683,8 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) int i; if (!vers_printed++) - printk(KERN_INFO MOD "Chelsio T4 RDMA Driver - version %s\n", - DRV_VERSION); + pr_info("Chelsio T4/T5 RDMA Driver - version %s\n", + DRV_VERSION); ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) { diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 7eec5e13fa8c..34c7e62b8676 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -817,6 +817,15 @@ static inline int compute_wscale(int win) return wscale; } +static inline int ocqp_supported(const struct cxgb4_lld_info *infop) +{ +#if defined(__i386__) || defined(__x86_64__) || defined(CONFIG_PPC64) + return infop->vr->ocq.size > 0; +#else + return 0; +#endif +} + u32 c4iw_id_alloc(struct c4iw_id_table *alloc); void c4iw_id_free(struct c4iw_id_table *alloc, u32 obj); int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num, diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index e084fdc6da7f..7e94c9a656a1 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -162,8 +162,14 @@ static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) */ if (addr >= rdev->oc_mw_pa) vma->vm_page_prot = t4_pgprot_wc(vma->vm_page_prot); - else - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + else { + if (is_t5(rdev->lldi.adapter_type)) + vma->vm_page_prot = + t4_pgprot_wc(vma->vm_page_prot); + else + vma->vm_page_prot = + pgprot_noncached(vma->vm_page_prot); + } ret = io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, len, vma->vm_page_prot); @@ -263,7 +269,7 @@ static int c4iw_query_device(struct ib_device *ibdev, dev = to_c4iw_dev(ibdev); memset(props, 0, sizeof *props); memcpy(&props->sys_image_guid, dev->rdev.lldi.ports[0]->dev_addr, 6); - props->hw_ver = dev->rdev.lldi.adapter_type; + props->hw_ver = CHELSIO_CHIP_RELEASE(dev->rdev.lldi.adapter_type); props->fw_ver = dev->rdev.lldi.fw_vers; props->device_cap_flags = dev->device_cap_flags; props->page_size_cap = T4_PAGESIZE_MASK; @@ -346,7 +352,8 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev, ibdev.dev); PDBG("%s dev 0x%p\n", __func__, dev); - return sprintf(buf, "%d\n", c4iw_dev->rdev.lldi.adapter_type); + return sprintf(buf, "%d\n", + CHELSIO_CHIP_RELEASE(c4iw_dev->rdev.lldi.adapter_type)); } static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 17ba4f8bc12d..c46024409c4e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -76,7 +76,7 @@ static void dealloc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) static int alloc_oc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) { - if (!ocqp_support || !t4_ocqp_supported()) + if (!ocqp_support || !ocqp_supported(&rdev->lldi)) return -ENOSYS; sq->dma_addr = c4iw_ocqp_pool_alloc(rdev, sq->memsize); if (!sq->dma_addr) diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 16f26ab29302..689edc96155d 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -280,15 +280,6 @@ static inline pgprot_t t4_pgprot_wc(pgprot_t prot) #endif } -static inline int t4_ocqp_supported(void) -{ -#if defined(__i386__) || defined(__x86_64__) || defined(CONFIG_PPC64) - return 1; -#else - return 0; -#endif -} - enum { T4_SQ_ONCHIP = (1<<0), }; -- cgit From 3cbdb928e2ddd16649769c8597a3ebc06c7594fd Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:08:59 +0000 Subject: RDMA/cxgb4: Turn off db coalescing when RDMA QPs are in use. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/qp.c | 20 ++++++++++++++++---- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 19 +++++++++++++++++++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 3 +++ drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 4 ++++ 4 files changed, 42 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index c46024409c4e..da4869f41e35 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -42,10 +42,17 @@ static int ocqp_support = 1; module_param(ocqp_support, int, 0644); MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)"); -int db_fc_threshold = 2000; +int db_fc_threshold = 1000; module_param(db_fc_threshold, int, 0644); -MODULE_PARM_DESC(db_fc_threshold, "QP count/threshold that triggers automatic " - "db flow control mode (default = 2000)"); +MODULE_PARM_DESC(db_fc_threshold, + "QP count/threshold that triggers" + " automatic db flow control mode (default = 1000)"); + +int db_coalescing_threshold; +module_param(db_coalescing_threshold, int, 0644); +MODULE_PARM_DESC(db_coalescing_threshold, + "QP count/threshold that triggers" + " disabling db coalescing (default = 0)"); static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) { @@ -1448,6 +1455,8 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) rhp->db_state = NORMAL; idr_for_each(&rhp->qpidr, enable_qp_db, NULL); } + if (rhp->qpcnt <= db_coalescing_threshold) + cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]); spin_unlock_irq(&rhp->lock); atomic_dec(&qhp->refcnt); wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); @@ -1559,11 +1568,14 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, spin_lock_irq(&rhp->lock); if (rhp->db_state != NORMAL) t4_disable_wq_db(&qhp->wq); - if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) { + rhp->qpcnt++; + if (rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) { rhp->rdev.stats.db_state_transitions++; rhp->db_state = FLOW_CONTROL; idr_for_each(&rhp->qpidr, disable_qp_db, NULL); } + if (rhp->qpcnt > db_coalescing_threshold) + cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]); ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); spin_unlock_irq(&rhp->lock); if (ret) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a59bb231bea2..e76cf035100b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3397,6 +3397,25 @@ out: } EXPORT_SYMBOL(cxgb4_sync_txq_pidx); +void cxgb4_disable_db_coalescing(struct net_device *dev) +{ + struct adapter *adap; + + adap = netdev2adap(dev); + t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_NOCOALESCE, + F_NOCOALESCE); +} +EXPORT_SYMBOL(cxgb4_disable_db_coalescing); + +void cxgb4_enable_db_coalescing(struct net_device *dev) +{ + struct adapter *adap; + + adap = netdev2adap(dev); + t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_NOCOALESCE, 0); +} +EXPORT_SYMBOL(cxgb4_enable_db_coalescing); + static struct pci_driver cxgb4_driver; static void check_neigh_update(struct neighbour *neigh) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index e2bbc7f3e2de..4faf4d067ee7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -269,4 +269,7 @@ struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl, unsigned int skb_len, unsigned int pull_len); int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size); int cxgb4_flush_eq_cache(struct net_device *dev); +void cxgb4_disable_db_coalescing(struct net_device *dev); +void cxgb4_enable_db_coalescing(struct net_device *dev); + #endif /* !__CXGB4_OFLD_H */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 22cbcb36d81d..ef146c0ba481 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -241,6 +241,10 @@ #define SGE_DOORBELL_CONTROL 0x10a8 #define ENABLE_DROP (1 << 13) +#define S_NOCOALESCE 26 +#define V_NOCOALESCE(x) ((x) << S_NOCOALESCE) +#define F_NOCOALESCE V_NOCOALESCE(1U) + #define SGE_TIMER_VALUE_0_AND_1 0x10b8 #define TIMERVALUE0_MASK 0xffff0000U #define TIMERVALUE0_SHIFT 16 -- cgit From 80ccdd60512fc19fa87bf02876c59aeeb82fe4bc Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:09:00 +0000 Subject: RDMA/cxgb4: Add module_params to enable DB FC & Coalescing on T5 Both DB Flow-Control and DB Coalescing are disabled by default on T5 Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/device.c | 25 +++++++++++++++++++++++-- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 + drivers/infiniband/hw/cxgb4/qp.c | 10 ++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 3487c08828f7..ae656016e1ae 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -45,6 +45,16 @@ MODULE_DESCRIPTION("Chelsio T4/T5 RDMA Driver"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRV_VERSION); +static int allow_db_fc_on_t5; +module_param(allow_db_fc_on_t5, int, 0644); +MODULE_PARM_DESC(allow_db_fc_on_t5, + "Allow DB Flow Control on T5 (default = 0)"); + +static int allow_db_coalescing_on_t5; +module_param(allow_db_coalescing_on_t5, int, 0644); +MODULE_PARM_DESC(allow_db_coalescing_on_t5, + "Allow DB Coalescing on T5 (default = 0)"); + struct uld_ctx { struct list_head entry; struct cxgb4_lld_info lldi; @@ -630,8 +640,19 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) if (!ocqp_supported(infop)) pr_info("%s: On-Chip Queues not supported on this device.\n", pci_name(infop->pdev)); - if (!is_t4(infop->adapter_type)) - db_fc_threshold = 100000; + + if (!is_t4(infop->adapter_type)) { + if (!allow_db_fc_on_t5) { + db_fc_threshold = 100000; + pr_info("DB Flow Control Disabled.\n"); + } + + if (!allow_db_coalescing_on_t5) { + db_coalescing_threshold = -1; + pr_info("DB Coalescing Disabled.\n"); + } + } + devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); if (!devp) { printk(KERN_ERR MOD "Cannot allocate ib device\n"); diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 34c7e62b8676..4dbe96a06a84 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -939,6 +939,7 @@ extern struct cxgb4_client t4c_client; extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS]; extern int c4iw_max_read_depth; extern int db_fc_threshold; +extern int db_coalescing_threshold; #endif diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index da4869f41e35..28592d45809b 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1455,8 +1455,9 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) rhp->db_state = NORMAL; idr_for_each(&rhp->qpidr, enable_qp_db, NULL); } - if (rhp->qpcnt <= db_coalescing_threshold) - cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]); + if (db_coalescing_threshold >= 0) + if (rhp->qpcnt <= db_coalescing_threshold) + cxgb4_enable_db_coalescing(rhp->rdev.lldi.ports[0]); spin_unlock_irq(&rhp->lock); atomic_dec(&qhp->refcnt); wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); @@ -1574,8 +1575,9 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, rhp->db_state = FLOW_CONTROL; idr_for_each(&rhp->qpidr, disable_qp_db, NULL); } - if (rhp->qpcnt > db_coalescing_threshold) - cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]); + if (db_coalescing_threshold >= 0) + if (rhp->qpcnt > db_coalescing_threshold) + cxgb4_disable_db_coalescing(rhp->rdev.lldi.ports[0]); ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); spin_unlock_irq(&rhp->lock); if (ret) -- cgit From 42b6a949903d28f59c95f4c71080aa8b41e3d1d1 Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:09:01 +0000 Subject: RDMA/cxgb4: Use DSGLs for fastreg and adapter memory writes for T5. It enables direct DMA by HW to memory region PBL arrays and fast register PBL arrays from host memory, vs the T4 way of passing these arrays in the WR itself. The result is lower latency for memory registration, and larger PBL array support for fast register operations. This patch also updates ULP_TX_MEM_WRITE command fields for T5. Ordering bit of ULP_TX_MEM_WRITE is at bit position 22 in T5 and at 23 in T4. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 2 +- drivers/infiniband/hw/cxgb4/mem.c | 138 +++++++++++++++++++++++++--- drivers/infiniband/hw/cxgb4/qp.c | 76 ++++++++++----- drivers/infiniband/hw/cxgb4/t4.h | 2 +- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 8 ++ 5 files changed, 190 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 4dbe96a06a84..08e406ca815b 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -369,7 +369,6 @@ struct c4iw_fr_page_list { DEFINE_DMA_UNMAP_ADDR(mapping); dma_addr_t dma_addr; struct c4iw_dev *dev; - int size; }; static inline struct c4iw_fr_page_list *to_c4iw_fr_page_list( @@ -940,6 +939,7 @@ extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS]; extern int c4iw_max_read_depth; extern int db_fc_threshold; extern int db_coalescing_threshold; +extern int use_dsgl; #endif diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 903a92d6f91d..33db9ee307dc 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -30,16 +30,76 @@ * SOFTWARE. */ +#include +#include #include #include #include "iw_cxgb4.h" +int use_dsgl = 1; +module_param(use_dsgl, int, 0644); +MODULE_PARM_DESC(use_dsgl, "Use DSGL for PBL/FastReg (default=1)"); + #define T4_ULPTX_MIN_IO 32 #define C4IW_MAX_INLINE_SIZE 96 +#define T4_ULPTX_MAX_DMA 1024 +#define C4IW_INLINE_THRESHOLD 128 -static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, - void *data) +static int inline_threshold = C4IW_INLINE_THRESHOLD; +module_param(inline_threshold, int, 0644); +MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); + +static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, + u32 len, void *data, int wait) +{ + struct sk_buff *skb; + struct ulp_mem_io *req; + struct ulptx_sgl *sgl; + u8 wr_len; + int ret = 0; + struct c4iw_wr_wait wr_wait; + + addr &= 0x7FFFFFF; + + if (wait) + c4iw_init_wr_wait(&wr_wait); + wr_len = roundup(sizeof(*req) + sizeof(*sgl), 16); + + skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL); + if (!skb) + return -ENOMEM; + set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0); + + req = (struct ulp_mem_io *)__skb_put(skb, wr_len); + memset(req, 0, wr_len); + INIT_ULPTX_WR(req, wr_len, 0, 0); + req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) | + (wait ? FW_WR_COMPL(1) : 0)); + req->wr.wr_lo = wait ? (__force __be64)&wr_wait : 0; + req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16))); + req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); + req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1)); + req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN(len>>5)); + req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), 16)); + req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR(addr)); + + sgl = (struct ulptx_sgl *)(req + 1); + sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_DSGL) | + ULPTX_NSGE(1)); + sgl->len0 = cpu_to_be32(len); + sgl->addr0 = cpu_to_be64(virt_to_phys(data)); + + ret = c4iw_ofld_send(rdev, skb); + if (ret) + return ret; + if (wait) + ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__); + return ret; +} + +static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, + void *data) { struct sk_buff *skb; struct ulp_mem_io *req; @@ -47,6 +107,12 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, u8 wr_len, *to_dp, *from_dp; int copy_len, num_wqe, i, ret = 0; struct c4iw_wr_wait wr_wait; + __be32 cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); + + if (is_t4(rdev->lldi.adapter_type)) + cmd |= cpu_to_be32(ULP_MEMIO_ORDER(1)); + else + cmd |= cpu_to_be32(V_T5_ULP_MEMIO_IMM(1)); addr &= 0x7FFFFFF; PDBG("%s addr 0x%x len %u\n", __func__, addr, len); @@ -77,7 +143,7 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, req->wr.wr_mid = cpu_to_be32( FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16))); - req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1<<23)); + req->cmd = cmd; req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN( DIV_ROUND_UP(copy_len, T4_ULPTX_MIN_IO))); req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), @@ -107,6 +173,50 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, return ret; } +int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) +{ + u32 remain = len; + u32 dmalen; + int ret = 0; + + while (remain > inline_threshold) { + if (remain < T4_ULPTX_MAX_DMA) { + if (remain & ~T4_ULPTX_MIN_IO) + dmalen = remain & ~(T4_ULPTX_MIN_IO-1); + else + dmalen = remain; + } else + dmalen = T4_ULPTX_MAX_DMA; + remain -= dmalen; + ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, data, + !remain); + if (ret) + goto out; + addr += dmalen >> 5; + data += dmalen; + } + if (remain) + ret = _c4iw_write_mem_inline(rdev, addr, remain, data); +out: + return ret; +} + +/* + * write len bytes of data into addr (32B aligned address) + * If data is NULL, clear len byte of memory to zero. + */ +static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, + void *data) +{ + if (is_t5(rdev->lldi.adapter_type) && use_dsgl) { + if (len > inline_threshold) + return _c4iw_write_mem_dma(rdev, addr, len, data); + else + return _c4iw_write_mem_inline(rdev, addr, len, data); + } else + return _c4iw_write_mem_inline(rdev, addr, len, data); +} + /* * Build and write a TPT entry. * IN: stag key, pdid, perm, bind_enabled, zbva, to, len, page_size, @@ -760,19 +870,23 @@ struct ib_fast_reg_page_list *c4iw_alloc_fastreg_pbl(struct ib_device *device, struct c4iw_fr_page_list *c4pl; struct c4iw_dev *dev = to_c4iw_dev(device); dma_addr_t dma_addr; - int size = sizeof *c4pl + page_list_len * sizeof(u64); + int pll_len = roundup(page_list_len * sizeof(u64), 32); - c4pl = dma_alloc_coherent(&dev->rdev.lldi.pdev->dev, size, - &dma_addr, GFP_KERNEL); + c4pl = kmalloc(sizeof(*c4pl), GFP_KERNEL); if (!c4pl) return ERR_PTR(-ENOMEM); + c4pl->ibpl.page_list = dma_alloc_coherent(&dev->rdev.lldi.pdev->dev, + pll_len, &dma_addr, + GFP_KERNEL); + if (!c4pl->ibpl.page_list) { + kfree(c4pl); + return ERR_PTR(-ENOMEM); + } dma_unmap_addr_set(c4pl, mapping, dma_addr); c4pl->dma_addr = dma_addr; c4pl->dev = dev; - c4pl->size = size; - c4pl->ibpl.page_list = (u64 *)(c4pl + 1); - c4pl->ibpl.max_page_list_len = page_list_len; + c4pl->ibpl.max_page_list_len = pll_len; return &c4pl->ibpl; } @@ -781,8 +895,10 @@ void c4iw_free_fastreg_pbl(struct ib_fast_reg_page_list *ibpl) { struct c4iw_fr_page_list *c4pl = to_c4iw_fr_page_list(ibpl); - dma_free_coherent(&c4pl->dev->rdev.lldi.pdev->dev, c4pl->size, - c4pl, dma_unmap_addr(c4pl, mapping)); + dma_free_coherent(&c4pl->dev->rdev.lldi.pdev->dev, + c4pl->ibpl.max_page_list_len, + c4pl->ibpl.page_list, dma_unmap_addr(c4pl, mapping)); + kfree(c4pl); } int c4iw_dereg_mr(struct ib_mr *ib_mr) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 28592d45809b..90833d701631 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -54,6 +54,10 @@ MODULE_PARM_DESC(db_coalescing_threshold, "QP count/threshold that triggers" " disabling db coalescing (default = 0)"); +static int max_fr_immd = T4_MAX_FR_IMMD; +module_param(max_fr_immd, int, 0644); +MODULE_PARM_DESC(max_fr_immd, "fastreg threshold for using DSGL instead of immedate"); + static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) { unsigned long flag; @@ -539,7 +543,7 @@ static int build_rdma_recv(struct c4iw_qp *qhp, union t4_recv_wr *wqe, } static int build_fastreg(struct t4_sq *sq, union t4_wr *wqe, - struct ib_send_wr *wr, u8 *len16) + struct ib_send_wr *wr, u8 *len16, u8 t5dev) { struct fw_ri_immd *imdp; @@ -561,28 +565,51 @@ static int build_fastreg(struct t4_sq *sq, union t4_wr *wqe, wqe->fr.va_hi = cpu_to_be32(wr->wr.fast_reg.iova_start >> 32); wqe->fr.va_lo_fbo = cpu_to_be32(wr->wr.fast_reg.iova_start & 0xffffffff); - WARN_ON(pbllen > T4_MAX_FR_IMMD); - imdp = (struct fw_ri_immd *)(&wqe->fr + 1); - imdp->op = FW_RI_DATA_IMMD; - imdp->r1 = 0; - imdp->r2 = 0; - imdp->immdlen = cpu_to_be32(pbllen); - p = (__be64 *)(imdp + 1); - rem = pbllen; - for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) { - *p = cpu_to_be64((u64)wr->wr.fast_reg.page_list->page_list[i]); - rem -= sizeof *p; - if (++p == (__be64 *)&sq->queue[sq->size]) - p = (__be64 *)sq->queue; - } - BUG_ON(rem < 0); - while (rem) { - *p = 0; - rem -= sizeof *p; - if (++p == (__be64 *)&sq->queue[sq->size]) - p = (__be64 *)sq->queue; + + if (t5dev && use_dsgl && (pbllen > max_fr_immd)) { + struct c4iw_fr_page_list *c4pl = + to_c4iw_fr_page_list(wr->wr.fast_reg.page_list); + struct fw_ri_dsgl *sglp; + + for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) { + wr->wr.fast_reg.page_list->page_list[i] = (__force u64) + cpu_to_be64((u64) + wr->wr.fast_reg.page_list->page_list[i]); + } + + sglp = (struct fw_ri_dsgl *)(&wqe->fr + 1); + sglp->op = FW_RI_DATA_DSGL; + sglp->r1 = 0; + sglp->nsge = cpu_to_be16(1); + sglp->addr0 = cpu_to_be64(c4pl->dma_addr); + sglp->len0 = cpu_to_be32(pbllen); + + *len16 = DIV_ROUND_UP(sizeof(wqe->fr) + sizeof(*sglp), 16); + } else { + imdp = (struct fw_ri_immd *)(&wqe->fr + 1); + imdp->op = FW_RI_DATA_IMMD; + imdp->r1 = 0; + imdp->r2 = 0; + imdp->immdlen = cpu_to_be32(pbllen); + p = (__be64 *)(imdp + 1); + rem = pbllen; + for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) { + *p = cpu_to_be64( + (u64)wr->wr.fast_reg.page_list->page_list[i]); + rem -= sizeof(*p); + if (++p == (__be64 *)&sq->queue[sq->size]) + p = (__be64 *)sq->queue; + } + BUG_ON(rem < 0); + while (rem) { + *p = 0; + rem -= sizeof(*p); + if (++p == (__be64 *)&sq->queue[sq->size]) + p = (__be64 *)sq->queue; + } + *len16 = DIV_ROUND_UP(sizeof(wqe->fr) + sizeof(*imdp) + + pbllen, 16); } - *len16 = DIV_ROUND_UP(sizeof wqe->fr + sizeof *imdp + pbllen, 16); return 0; } @@ -683,7 +710,10 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, case IB_WR_FAST_REG_MR: fw_opcode = FW_RI_FR_NSMR_WR; swsqe->opcode = FW_RI_FAST_REGISTER; - err = build_fastreg(&qhp->wq.sq, wqe, wr, &len16); + err = build_fastreg(&qhp->wq.sq, wqe, wr, &len16, + is_t5( + qhp->rhp->rdev.lldi.adapter_type) ? + 1 : 0); break; case IB_WR_LOCAL_INV: if (wr->send_flags & IB_SEND_FENCE) diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 689edc96155d..ebcb03bd1b72 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -84,7 +84,7 @@ struct t4_status_page { sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge)) #define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \ sizeof(struct fw_ri_immd)) & ~31UL) -#define T4_MAX_FR_DEPTH (T4_MAX_FR_IMMD / sizeof(u64)) +#define T4_MAX_FR_DEPTH (1024 / sizeof(u64)) #define T4_RQ_NUM_SLOTS 2 #define T4_RQ_NUM_BYTES (T4_EQ_ENTRY_SIZE * T4_RQ_NUM_SLOTS) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index 0c9f14f87a4f..47656ac1ac25 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -787,4 +787,12 @@ struct ulp_mem_io { #define ULP_MEMIO_LOCK(x) ((x) << 31) }; +#define S_T5_ULP_MEMIO_IMM 23 +#define V_T5_ULP_MEMIO_IMM(x) ((x) << S_T5_ULP_MEMIO_IMM) +#define F_T5_ULP_MEMIO_IMM V_T5_ULP_MEMIO_IMM(1U) + +#define S_T5_ULP_MEMIO_ORDER 22 +#define V_T5_ULP_MEMIO_ORDER(x) ((x) << S_T5_ULP_MEMIO_ORDER) +#define F_T5_ULP_MEMIO_ORDER V_T5_ULP_MEMIO_ORDER(1U) + #endif /* __T4_MSG_H */ -- cgit From 0e5eca791c8d8dd7622a58785947f1cab92e595c Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:09:02 +0000 Subject: RDMA/cxgb4: Map pbl buffers for dma if using DSGL. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/mem.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 33db9ee307dc..4cb8eb24497c 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -51,7 +51,7 @@ module_param(inline_threshold, int, 0644); MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, - u32 len, void *data, int wait) + u32 len, dma_addr_t data, int wait) { struct sk_buff *skb; struct ulp_mem_io *req; @@ -88,7 +88,7 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(1)); sgl->len0 = cpu_to_be32(len); - sgl->addr0 = cpu_to_be64(virt_to_phys(data)); + sgl->addr0 = cpu_to_be64(data); ret = c4iw_ofld_send(rdev, skb); if (ret) @@ -178,6 +178,13 @@ int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) u32 remain = len; u32 dmalen; int ret = 0; + dma_addr_t daddr; + dma_addr_t save; + + daddr = dma_map_single(&rdev->lldi.pdev->dev, data, len, DMA_TO_DEVICE); + if (dma_mapping_error(&rdev->lldi.pdev->dev, daddr)) + return -1; + save = daddr; while (remain > inline_threshold) { if (remain < T4_ULPTX_MAX_DMA) { @@ -188,16 +195,18 @@ int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) } else dmalen = T4_ULPTX_MAX_DMA; remain -= dmalen; - ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, data, + ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, daddr, !remain); if (ret) goto out; addr += dmalen >> 5; data += dmalen; + daddr += dmalen; } if (remain) ret = _c4iw_write_mem_inline(rdev, addr, remain, data); out: + dma_unmap_single(&rdev->lldi.pdev->dev, save, len, DMA_TO_DEVICE); return ret; } @@ -209,9 +218,17 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, void *data) { if (is_t5(rdev->lldi.adapter_type) && use_dsgl) { - if (len > inline_threshold) - return _c4iw_write_mem_dma(rdev, addr, len, data); - else + if (len > inline_threshold) { + if (_c4iw_write_mem_dma(rdev, addr, len, data)) { + printk_ratelimited(KERN_WARNING + "%s: dma map" + " failure (non fatal)\n", + pci_name(rdev->lldi.pdev)); + return _c4iw_write_mem_inline(rdev, addr, len, + data); + } else + return 0; + } else return _c4iw_write_mem_inline(rdev, addr, len, data); } else return _c4iw_write_mem_inline(rdev, addr, len, data); -- cgit From 3b174d942c927a5064c890ed7b326673c8fa1679 Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:09:03 +0000 Subject: RDMA/cxgb4: Bump tcam_full stat and WR reply timeout Always bump the tcam_full stat. Also, bump wr reply timeout to 30 seconds. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 2 +- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 272bf789c53b..8dcc84fd9d30 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1693,9 +1693,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) case CPL_ERR_CONN_TIMEDOUT: break; case CPL_ERR_TCAM_FULL: + dev->rdev.stats.tcam_full++; if (dev->rdev.lldi.enable_fw_ofld_conn) { mutex_lock(&dev->rdev.stats.lock); - dev->rdev.stats.tcam_full++; mutex_unlock(&dev->rdev.stats.lock); send_fw_act_open_req(ep, GET_TID_TID(GET_AOPEN_ATID( diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 08e406ca815b..485183ad34cd 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -162,7 +162,7 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev) return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5)); } -#define C4IW_WR_TO (10*HZ) +#define C4IW_WR_TO (30*HZ) struct c4iw_wr_wait { struct completion completion; -- cgit From 9919d5bd01b9eaf4928439e804dd70de24ea9637 Mon Sep 17 00:00:00 2001 From: Vipul Pandya Date: Thu, 14 Mar 2013 05:09:04 +0000 Subject: RDMA/cxgb4: Fix onchip queue support for T5 T5 adapter does not support onchip queue memory. Present logic fails to allocate QP for T5 and returns an error. Also, if module parameter ocqp_support is zero then we are unable to allocate QP which should not be the case. Ideally if ocqp_support parameter is 0 or onchip queue support is disable then host QP should be allocated before returning an error. Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/qp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 90833d701631..9fe6f1e84373 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -140,7 +140,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, int wr_len; struct c4iw_wr_wait wr_wait; struct sk_buff *skb; - int ret; + int ret = 0; int eqsize; wq->sq.qid = c4iw_get_qpid(rdev, uctx); @@ -180,17 +180,14 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, } if (user) { - ret = alloc_oc_sq(rdev, &wq->sq); - if (ret) + if (alloc_oc_sq(rdev, &wq->sq) && alloc_host_sq(rdev, &wq->sq)) goto free_hwaddr; - - ret = alloc_host_sq(rdev, &wq->sq); - if (ret) - goto free_sq; - } else + } else { ret = alloc_host_sq(rdev, &wq->sq); if (ret) goto free_hwaddr; + } + memset(wq->sq.queue, 0, wq->sq.memsize); dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr); -- cgit From 3ac93660872c92a8d0cd795f031db81b4b14967c Mon Sep 17 00:00:00 2001 From: Arvind Bhushan Date: Thu, 14 Mar 2013 05:09:05 +0000 Subject: csiostor: Segregate T4 adapter operations. This patch separates T4 adapter operations into a new file. Signed-off-by: Arvind Bhushan Signed-off-by: Naresh Kumar Inna Signed-off-by: David S. Miller --- drivers/scsi/csiostor/csio_hw_t4.c | 403 +++++++++++++++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 drivers/scsi/csiostor/csio_hw_t4.c (limited to 'drivers') diff --git a/drivers/scsi/csiostor/csio_hw_t4.c b/drivers/scsi/csiostor/csio_hw_t4.c new file mode 100644 index 000000000000..89ecbac5478f --- /dev/null +++ b/drivers/scsi/csiostor/csio_hw_t4.c @@ -0,0 +1,403 @@ +/* + * This file is part of the Chelsio FCoE driver for Linux. + * + * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "csio_hw.h" +#include "csio_init.h" + +/* + * Return the specified PCI-E Configuration Space register from our Physical + * Function. We try first via a Firmware LDST Command since we prefer to let + * the firmware own all of these registers, but if that fails we go for it + * directly ourselves. + */ +static uint32_t +csio_t4_read_pcie_cfg4(struct csio_hw *hw, int reg) +{ + u32 val = 0; + struct csio_mb *mbp; + int rv; + struct fw_ldst_cmd *ldst_cmd; + + mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); + if (!mbp) { + CSIO_INC_STATS(hw, n_err_nomem); + pci_read_config_dword(hw->pdev, reg, &val); + return val; + } + + csio_mb_ldst(hw, mbp, CSIO_MB_DEFAULT_TMO, reg); + rv = csio_mb_issue(hw, mbp); + + /* + * If the LDST Command suucceeded, exctract the returned register + * value. Otherwise read it directly ourself. + */ + if (rv == 0) { + ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb); + val = ntohl(ldst_cmd->u.pcie.data[0]); + } else + pci_read_config_dword(hw->pdev, reg, &val); + + mempool_free(mbp, hw->mb_mempool); + + return val; +} + +static int +csio_t4_set_mem_win(struct csio_hw *hw, uint32_t win) +{ + u32 bar0; + u32 mem_win_base; + + /* + * Truncation intentional: we only read the bottom 32-bits of the + * 64-bit BAR0/BAR1 ... We use the hardware backdoor mechanism to + * read BAR0 instead of using pci_resource_start() because we could be + * operating from within a Virtual Machine which is trapping our + * accesses to our Configuration Space and we need to set up the PCI-E + * Memory Window decoders with the actual addresses which will be + * coming across the PCI-E link. + */ + bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0); + bar0 &= PCI_BASE_ADDRESS_MEM_MASK; + + mem_win_base = bar0 + MEMWIN_BASE; + + /* + * Set up memory window for accessing adapter memory ranges. (Read + * back MA register to ensure that changes propagate before we attempt + * to use the new values.) + */ + csio_wr_reg32(hw, mem_win_base | BIR(0) | + WINDOW(ilog2(MEMWIN_APERTURE) - 10), + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + return 0; +} + +/* + * Interrupt handler for the PCIE module. + */ +static void +csio_t4_pcie_intr_handler(struct csio_hw *hw) +{ + static struct intr_info sysbus_intr_info[] = { + { RNPP, "RXNP array parity error", -1, 1 }, + { RPCP, "RXPC array parity error", -1, 1 }, + { RCIP, "RXCIF array parity error", -1, 1 }, + { RCCP, "Rx completions control array parity error", -1, 1 }, + { RFTP, "RXFT array parity error", -1, 1 }, + { 0, NULL, 0, 0 } + }; + static struct intr_info pcie_port_intr_info[] = { + { TPCP, "TXPC array parity error", -1, 1 }, + { TNPP, "TXNP array parity error", -1, 1 }, + { TFTP, "TXFT array parity error", -1, 1 }, + { TCAP, "TXCA array parity error", -1, 1 }, + { TCIP, "TXCIF array parity error", -1, 1 }, + { RCAP, "RXCA array parity error", -1, 1 }, + { OTDD, "outbound request TLP discarded", -1, 1 }, + { RDPE, "Rx data parity error", -1, 1 }, + { TDUE, "Tx uncorrectable data error", -1, 1 }, + { 0, NULL, 0, 0 } + }; + + static struct intr_info pcie_intr_info[] = { + { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 }, + { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 }, + { MSIDATAPERR, "MSI data parity error", -1, 1 }, + { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 }, + { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 }, + { MSIXDATAPERR, "MSI-X data parity error", -1, 1 }, + { MSIXDIPERR, "MSI-X DI parity error", -1, 1 }, + { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 }, + { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 }, + { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 }, + { CCNTPERR, "PCI CMD channel count parity error", -1, 1 }, + { CREQPERR, "PCI CMD channel request parity error", -1, 1 }, + { CRSPPERR, "PCI CMD channel response parity error", -1, 1 }, + { DCNTPERR, "PCI DMA channel count parity error", -1, 1 }, + { DREQPERR, "PCI DMA channel request parity error", -1, 1 }, + { DRSPPERR, "PCI DMA channel response parity error", -1, 1 }, + { HCNTPERR, "PCI HMA channel count parity error", -1, 1 }, + { HREQPERR, "PCI HMA channel request parity error", -1, 1 }, + { HRSPPERR, "PCI HMA channel response parity error", -1, 1 }, + { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 }, + { FIDPERR, "PCI FID parity error", -1, 1 }, + { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 }, + { MATAGPERR, "PCI MA tag parity error", -1, 1 }, + { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 }, + { RXCPLPERR, "PCI Rx completion parity error", -1, 1 }, + { RXWRPERR, "PCI Rx write parity error", -1, 1 }, + { RPLPERR, "PCI replay buffer parity error", -1, 1 }, + { PCIESINT, "PCI core secondary fault", -1, 1 }, + { PCIEPINT, "PCI core primary fault", -1, 1 }, + { UNXSPLCPLERR, "PCI unexpected split completion error", -1, + 0 }, + { 0, NULL, 0, 0 } + }; + + int fat; + fat = csio_handle_intr_status(hw, + PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, + sysbus_intr_info) + + csio_handle_intr_status(hw, + PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, + pcie_port_intr_info) + + csio_handle_intr_status(hw, PCIE_INT_CAUSE, pcie_intr_info); + if (fat) + csio_hw_fatal_err(hw); +} + +/* + * csio_t4_flash_cfg_addr - return the address of the flash configuration file + * @hw: the HW module + * + * Return the address within the flash where the Firmware Configuration + * File is stored. + */ +static unsigned int +csio_t4_flash_cfg_addr(struct csio_hw *hw) +{ + return FLASH_CFG_OFFSET; +} + +/* + * csio_t4_mc_read - read from MC through backdoor accesses + * @hw: the hw module + * @idx: not used for T4 adapter + * @addr: address of first byte requested + * @data: 64 bytes of data containing the requested address + * @ecc: where to store the corresponding 64-bit ECC word + * + * Read 64 bytes of data from MC starting at a 64-byte-aligned address + * that covers the requested address @addr. If @parity is not %NULL it + * is assigned the 64-bit ECC word for the read data. + */ +static int +csio_t4_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, + uint64_t *ecc) +{ + int i; + + if (csio_rd_reg32(hw, MC_BIST_CMD) & START_BIST) + return -EBUSY; + csio_wr_reg32(hw, addr & ~0x3fU, MC_BIST_CMD_ADDR); + csio_wr_reg32(hw, 64, MC_BIST_CMD_LEN); + csio_wr_reg32(hw, 0xc, MC_BIST_DATA_PATTERN); + csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1), + MC_BIST_CMD); + i = csio_hw_wait_op_done_val(hw, MC_BIST_CMD, START_BIST, + 0, 10, 1, NULL); + if (i) + return i; + +#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i) + + for (i = 15; i >= 0; i--) + *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i))); + if (ecc) + *ecc = csio_rd_reg64(hw, MC_DATA(16)); +#undef MC_DATA + return 0; +} + +/* + * csio_t4_edc_read - read from EDC through backdoor accesses + * @hw: the hw module + * @idx: which EDC to access + * @addr: address of first byte requested + * @data: 64 bytes of data containing the requested address + * @ecc: where to store the corresponding 64-bit ECC word + * + * Read 64 bytes of data from EDC starting at a 64-byte-aligned address + * that covers the requested address @addr. If @parity is not %NULL it + * is assigned the 64-bit ECC word for the read data. + */ +static int +csio_t4_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, + uint64_t *ecc) +{ + int i; + + idx *= EDC_STRIDE; + if (csio_rd_reg32(hw, EDC_BIST_CMD + idx) & START_BIST) + return -EBUSY; + csio_wr_reg32(hw, addr & ~0x3fU, EDC_BIST_CMD_ADDR + idx); + csio_wr_reg32(hw, 64, EDC_BIST_CMD_LEN + idx); + csio_wr_reg32(hw, 0xc, EDC_BIST_DATA_PATTERN + idx); + csio_wr_reg32(hw, BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST, + EDC_BIST_CMD + idx); + i = csio_hw_wait_op_done_val(hw, EDC_BIST_CMD + idx, START_BIST, + 0, 10, 1, NULL); + if (i) + return i; + +#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx) + + for (i = 15; i >= 0; i--) + *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i))); + if (ecc) + *ecc = csio_rd_reg64(hw, EDC_DATA(16)); +#undef EDC_DATA + return 0; +} + +/* + * csio_t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window + * @hw: the csio_hw + * @win: PCI-E memory Window to use + * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_MC0 (or MEM_MC) or MEM_MC1 + * @addr: address within indicated memory type + * @len: amount of memory to transfer + * @buf: host memory buffer + * @dir: direction of transfer 1 => read, 0 => write + * + * Reads/writes an [almost] arbitrary memory region in the firmware: the + * firmware memory address, length and host buffer must be aligned on + * 32-bit boudaries. The memory is transferred as a raw byte sequence + * from/to the firmware's memory. If this memory contains data + * structures which contain multi-byte integers, it's the callers + * responsibility to perform appropriate byte order conversions. + */ +static int +csio_t4_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr, + u32 len, uint32_t *buf, int dir) +{ + u32 pos, start, offset, memoffset, bar0; + u32 edc_size, mc_size, mem_reg, mem_aperture, mem_base; + + /* + * Argument sanity checks ... + */ + if ((addr & 0x3) || (len & 0x3)) + return -EINVAL; + + /* Offset into the region of memory which is being accessed + * MEM_EDC0 = 0 + * MEM_EDC1 = 1 + * MEM_MC = 2 -- T4 + */ + edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR)); + if (mtype != MEM_MC1) + memoffset = (mtype * (edc_size * 1024 * 1024)); + else { + mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw, + MA_EXT_MEMORY_BAR)); + memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; + } + + /* Determine the PCIE_MEM_ACCESS_OFFSET */ + addr = addr + memoffset; + + /* + * Each PCI-E Memory Window is programmed with a window size -- or + * "aperture" -- which controls the granularity of its mapping onto + * adapter memory. We need to grab that aperture in order to know + * how to use the specified window. The window is also programmed + * with the base address of the Memory Window in BAR0's address + * space. For T4 this is an absolute PCI-E Bus Address. For T5 + * the address is relative to BAR0. + */ + mem_reg = csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + mem_aperture = 1 << (WINDOW(mem_reg) + 10); + mem_base = GET_PCIEOFST(mem_reg) << 10; + + bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0); + bar0 &= PCI_BASE_ADDRESS_MEM_MASK; + mem_base -= bar0; + + start = addr & ~(mem_aperture-1); + offset = addr - start; + + csio_dbg(hw, "csio_t4_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n", + mem_reg, mem_aperture); + csio_dbg(hw, "csio_t4_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n", + mem_base, memoffset); + csio_dbg(hw, "csio_t4_memory_rw: bar0: 0x%x, start:0x%x, offset:0x%x\n", + bar0, start, offset); + csio_dbg(hw, "csio_t4_memory_rw: mtype: %d, addr: 0x%x, len: %d\n", + mtype, addr, len); + + for (pos = start; len > 0; pos += mem_aperture, offset = 0) { + /* + * Move PCI-E Memory Window to our current transfer + * position. Read it back to ensure that changes propagate + * before we attempt to use the new value. + */ + csio_wr_reg32(hw, pos, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win)); + csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win)); + + while (offset < mem_aperture && len > 0) { + if (dir) + *buf++ = csio_rd_reg32(hw, mem_base + offset); + else + csio_wr_reg32(hw, *buf++, mem_base + offset); + + offset += sizeof(__be32); + len -= sizeof(__be32); + } + } + return 0; +} + +/* + * csio_t4_dfs_create_ext_mem - setup debugfs for MC to read the values + * @hw: the csio_hw + * + * This function creates files in the debugfs with external memory region MC. + */ +static void +csio_t4_dfs_create_ext_mem(struct csio_hw *hw) +{ + u32 size; + int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE); + if (i & EXT_MEM_ENABLE) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR); + csio_add_debugfs_mem(hw, "mc", MEM_MC, + EXT_MEM_SIZE_GET(size)); + } +} + +/* T4 adapter specific function */ +struct csio_hw_chip_ops t4_ops = { + .chip_set_mem_win = csio_t4_set_mem_win, + .chip_pcie_intr_handler = csio_t4_pcie_intr_handler, + .chip_flash_cfg_addr = csio_t4_flash_cfg_addr, + .chip_mc_read = csio_t4_mc_read, + .chip_edc_read = csio_t4_edc_read, + .chip_memory_rw = csio_t4_memory_rw, + .chip_dfs_create_ext_mem = csio_t4_dfs_create_ext_mem, +}; -- cgit From 4a22edb593012041ee656a88ea7f9889837cb0d1 Mon Sep 17 00:00:00 2001 From: Arvind Bhushan Date: Thu, 14 Mar 2013 05:09:06 +0000 Subject: csiostor: Add T5 adapter operations. This patch creates a new file for T5 adapter operations. Signed-off-by: Arvind Bhushan Signed-off-by: Naresh Kumar Inna Signed-off-by: David S. Miller --- drivers/scsi/csiostor/csio_hw_t5.c | 397 +++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 drivers/scsi/csiostor/csio_hw_t5.c (limited to 'drivers') diff --git a/drivers/scsi/csiostor/csio_hw_t5.c b/drivers/scsi/csiostor/csio_hw_t5.c new file mode 100644 index 000000000000..27745c170c24 --- /dev/null +++ b/drivers/scsi/csiostor/csio_hw_t5.c @@ -0,0 +1,397 @@ +/* + * This file is part of the Chelsio FCoE driver for Linux. + * + * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "csio_hw.h" +#include "csio_init.h" + +static int +csio_t5_set_mem_win(struct csio_hw *hw, uint32_t win) +{ + u32 mem_win_base; + /* + * Truncation intentional: we only read the bottom 32-bits of the + * 64-bit BAR0/BAR1 ... We use the hardware backdoor mechanism to + * read BAR0 instead of using pci_resource_start() because we could be + * operating from within a Virtual Machine which is trapping our + * accesses to our Configuration Space and we need to set up the PCI-E + * Memory Window decoders with the actual addresses which will be + * coming across the PCI-E link. + */ + + /* For T5, only relative offset inside the PCIe BAR is passed */ + mem_win_base = MEMWIN_BASE; + + /* + * Set up memory window for accessing adapter memory ranges. (Read + * back MA register to ensure that changes propagate before we attempt + * to use the new values.) + */ + csio_wr_reg32(hw, mem_win_base | BIR(0) | + WINDOW(ilog2(MEMWIN_APERTURE) - 10), + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + + return 0; +} + +/* + * Interrupt handler for the PCIE module. + */ +static void +csio_t5_pcie_intr_handler(struct csio_hw *hw) +{ + static struct intr_info sysbus_intr_info[] = { + { RNPP, "RXNP array parity error", -1, 1 }, + { RPCP, "RXPC array parity error", -1, 1 }, + { RCIP, "RXCIF array parity error", -1, 1 }, + { RCCP, "Rx completions control array parity error", -1, 1 }, + { RFTP, "RXFT array parity error", -1, 1 }, + { 0, NULL, 0, 0 } + }; + static struct intr_info pcie_port_intr_info[] = { + { TPCP, "TXPC array parity error", -1, 1 }, + { TNPP, "TXNP array parity error", -1, 1 }, + { TFTP, "TXFT array parity error", -1, 1 }, + { TCAP, "TXCA array parity error", -1, 1 }, + { TCIP, "TXCIF array parity error", -1, 1 }, + { RCAP, "RXCA array parity error", -1, 1 }, + { OTDD, "outbound request TLP discarded", -1, 1 }, + { RDPE, "Rx data parity error", -1, 1 }, + { TDUE, "Tx uncorrectable data error", -1, 1 }, + { 0, NULL, 0, 0 } + }; + + static struct intr_info pcie_intr_info[] = { + { MSTGRPPERR, "Master Response Read Queue parity error", + -1, 1 }, + { MSTTIMEOUTPERR, "Master Timeout FIFO parity error", -1, 1 }, + { MSIXSTIPERR, "MSI-X STI SRAM parity error", -1, 1 }, + { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 }, + { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 }, + { MSIXDATAPERR, "MSI-X data parity error", -1, 1 }, + { MSIXDIPERR, "MSI-X DI parity error", -1, 1 }, + { PIOCPLGRPPERR, "PCI PIO completion Group FIFO parity error", + -1, 1 }, + { PIOREQGRPPERR, "PCI PIO request Group FIFO parity error", + -1, 1 }, + { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 }, + { MSTTAGQPERR, "PCI master tag queue parity error", -1, 1 }, + { CREQPERR, "PCI CMD channel request parity error", -1, 1 }, + { CRSPPERR, "PCI CMD channel response parity error", -1, 1 }, + { DREQWRPERR, "PCI DMA channel write request parity error", + -1, 1 }, + { DREQPERR, "PCI DMA channel request parity error", -1, 1 }, + { DRSPPERR, "PCI DMA channel response parity error", -1, 1 }, + { HREQWRPERR, "PCI HMA channel count parity error", -1, 1 }, + { HREQPERR, "PCI HMA channel request parity error", -1, 1 }, + { HRSPPERR, "PCI HMA channel response parity error", -1, 1 }, + { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 }, + { FIDPERR, "PCI FID parity error", -1, 1 }, + { VFIDPERR, "PCI INTx clear parity error", -1, 1 }, + { MAGRPPERR, "PCI MA group FIFO parity error", -1, 1 }, + { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 }, + { IPRXHDRGRPPERR, "PCI IP Rx header group parity error", + -1, 1 }, + { IPRXDATAGRPPERR, "PCI IP Rx data group parity error", + -1, 1 }, + { RPLPERR, "PCI IP replay buffer parity error", -1, 1 }, + { IPSOTPERR, "PCI IP SOT buffer parity error", -1, 1 }, + { TRGT1GRPPERR, "PCI TRGT1 group FIFOs parity error", -1, 1 }, + { READRSPERR, "Outbound read error", -1, 0 }, + { 0, NULL, 0, 0 } + }; + + int fat; + fat = csio_handle_intr_status(hw, + PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, + sysbus_intr_info) + + csio_handle_intr_status(hw, + PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, + pcie_port_intr_info) + + csio_handle_intr_status(hw, PCIE_INT_CAUSE, pcie_intr_info); + if (fat) + csio_hw_fatal_err(hw); +} + +/* + * csio_t5_flash_cfg_addr - return the address of the flash configuration file + * @hw: the HW module + * + * Return the address within the flash where the Firmware Configuration + * File is stored. + */ +static unsigned int +csio_t5_flash_cfg_addr(struct csio_hw *hw) +{ + return FLASH_CFG_START; +} + +/* + * csio_t5_mc_read - read from MC through backdoor accesses + * @hw: the hw module + * @idx: index to the register + * @addr: address of first byte requested + * @data: 64 bytes of data containing the requested address + * @ecc: where to store the corresponding 64-bit ECC word + * + * Read 64 bytes of data from MC starting at a 64-byte-aligned address + * that covers the requested address @addr. If @parity is not %NULL it + * is assigned the 64-bit ECC word for the read data. + */ +static int +csio_t5_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, + uint64_t *ecc) +{ + int i; + uint32_t mc_bist_cmd_reg, mc_bist_cmd_addr_reg, mc_bist_cmd_len_reg; + uint32_t mc_bist_status_rdata_reg, mc_bist_data_pattern_reg; + + mc_bist_cmd_reg = MC_REG(MC_P_BIST_CMD, idx); + mc_bist_cmd_addr_reg = MC_REG(MC_P_BIST_CMD_ADDR, idx); + mc_bist_cmd_len_reg = MC_REG(MC_P_BIST_CMD_LEN, idx); + mc_bist_status_rdata_reg = MC_REG(MC_P_BIST_STATUS_RDATA, idx); + mc_bist_data_pattern_reg = MC_REG(MC_P_BIST_DATA_PATTERN, idx); + + if (csio_rd_reg32(hw, mc_bist_cmd_reg) & START_BIST) + return -EBUSY; + csio_wr_reg32(hw, addr & ~0x3fU, mc_bist_cmd_addr_reg); + csio_wr_reg32(hw, 64, mc_bist_cmd_len_reg); + csio_wr_reg32(hw, 0xc, mc_bist_data_pattern_reg); + csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1), + mc_bist_cmd_reg); + i = csio_hw_wait_op_done_val(hw, mc_bist_cmd_reg, START_BIST, + 0, 10, 1, NULL); + if (i) + return i; + +#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i) + + for (i = 15; i >= 0; i--) + *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i))); + if (ecc) + *ecc = csio_rd_reg64(hw, MC_DATA(16)); +#undef MC_DATA + return 0; +} + +/* + * csio_t5_edc_read - read from EDC through backdoor accesses + * @hw: the hw module + * @idx: which EDC to access + * @addr: address of first byte requested + * @data: 64 bytes of data containing the requested address + * @ecc: where to store the corresponding 64-bit ECC word + * + * Read 64 bytes of data from EDC starting at a 64-byte-aligned address + * that covers the requested address @addr. If @parity is not %NULL it + * is assigned the 64-bit ECC word for the read data. + */ +static int +csio_t5_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, + uint64_t *ecc) +{ + int i; + uint32_t edc_bist_cmd_reg, edc_bist_cmd_addr_reg, edc_bist_cmd_len_reg; + uint32_t edc_bist_cmd_data_pattern, edc_bist_status_rdata_reg; + +/* + * These macro are missing in t4_regs.h file. + */ +#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) +#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) + + edc_bist_cmd_reg = EDC_REG_T5(EDC_H_BIST_CMD, idx); + edc_bist_cmd_addr_reg = EDC_REG_T5(EDC_H_BIST_CMD_ADDR, idx); + edc_bist_cmd_len_reg = EDC_REG_T5(EDC_H_BIST_CMD_LEN, idx); + edc_bist_cmd_data_pattern = EDC_REG_T5(EDC_H_BIST_DATA_PATTERN, idx); + edc_bist_status_rdata_reg = EDC_REG_T5(EDC_H_BIST_STATUS_RDATA, idx); +#undef EDC_REG_T5 +#undef EDC_STRIDE_T5 + + if (csio_rd_reg32(hw, edc_bist_cmd_reg) & START_BIST) + return -EBUSY; + csio_wr_reg32(hw, addr & ~0x3fU, edc_bist_cmd_addr_reg); + csio_wr_reg32(hw, 64, edc_bist_cmd_len_reg); + csio_wr_reg32(hw, 0xc, edc_bist_cmd_data_pattern); + csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1), + edc_bist_cmd_reg); + i = csio_hw_wait_op_done_val(hw, edc_bist_cmd_reg, START_BIST, + 0, 10, 1, NULL); + if (i) + return i; + +#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx) + + for (i = 15; i >= 0; i--) + *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i))); + if (ecc) + *ecc = csio_rd_reg64(hw, EDC_DATA(16)); +#undef EDC_DATA + return 0; +} + +/* + * csio_t5_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window + * @hw: the csio_hw + * @win: PCI-E memory Window to use + * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_MC0 (or MEM_MC) or MEM_MC1 + * @addr: address within indicated memory type + * @len: amount of memory to transfer + * @buf: host memory buffer + * @dir: direction of transfer 1 => read, 0 => write + * + * Reads/writes an [almost] arbitrary memory region in the firmware: the + * firmware memory address, length and host buffer must be aligned on + * 32-bit boudaries. The memory is transferred as a raw byte sequence + * from/to the firmware's memory. If this memory contains data + * structures which contain multi-byte integers, it's the callers + * responsibility to perform appropriate byte order conversions. + */ +static int +csio_t5_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr, + u32 len, uint32_t *buf, int dir) +{ + u32 pos, start, offset, memoffset; + u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base; + + /* + * Argument sanity checks ... + */ + if ((addr & 0x3) || (len & 0x3)) + return -EINVAL; + + /* Offset into the region of memory which is being accessed + * MEM_EDC0 = 0 + * MEM_EDC1 = 1 + * MEM_MC = 2 -- T4 + * MEM_MC0 = 2 -- For T5 + * MEM_MC1 = 3 -- For T5 + */ + edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR)); + if (mtype != MEM_MC1) + memoffset = (mtype * (edc_size * 1024 * 1024)); + else { + mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw, + MA_EXT_MEMORY_BAR)); + memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; + } + + /* Determine the PCIE_MEM_ACCESS_OFFSET */ + addr = addr + memoffset; + + /* + * Each PCI-E Memory Window is programmed with a window size -- or + * "aperture" -- which controls the granularity of its mapping onto + * adapter memory. We need to grab that aperture in order to know + * how to use the specified window. The window is also programmed + * with the base address of the Memory Window in BAR0's address + * space. For T4 this is an absolute PCI-E Bus Address. For T5 + * the address is relative to BAR0. + */ + mem_reg = csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win)); + mem_aperture = 1 << (WINDOW(mem_reg) + 10); + mem_base = GET_PCIEOFST(mem_reg) << 10; + + start = addr & ~(mem_aperture-1); + offset = addr - start; + win_pf = V_PFNUM(hw->pfn); + + csio_dbg(hw, "csio_t5_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n", + mem_reg, mem_aperture); + csio_dbg(hw, "csio_t5_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n", + mem_base, memoffset); + csio_dbg(hw, "csio_t5_memory_rw: start:0x%x, offset:0x%x, win_pf:%d\n", + start, offset, win_pf); + csio_dbg(hw, "csio_t5_memory_rw: mtype: %d, addr: 0x%x, len: %d\n", + mtype, addr, len); + + for (pos = start; len > 0; pos += mem_aperture, offset = 0) { + /* + * Move PCI-E Memory Window to our current transfer + * position. Read it back to ensure that changes propagate + * before we attempt to use the new value. + */ + csio_wr_reg32(hw, pos | win_pf, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win)); + csio_rd_reg32(hw, + PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win)); + + while (offset < mem_aperture && len > 0) { + if (dir) + *buf++ = csio_rd_reg32(hw, mem_base + offset); + else + csio_wr_reg32(hw, *buf++, mem_base + offset); + + offset += sizeof(__be32); + len -= sizeof(__be32); + } + } + return 0; +} + +/* + * csio_t5_dfs_create_ext_mem - setup debugfs for MC0 or MC1 to read the values + * @hw: the csio_hw + * + * This function creates files in the debugfs with external memory region + * MC0 & MC1. + */ +static void +csio_t5_dfs_create_ext_mem(struct csio_hw *hw) +{ + u32 size; + int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE); + if (i & EXT_MEM_ENABLE) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR); + csio_add_debugfs_mem(hw, "mc0", MEM_MC0, + EXT_MEM_SIZE_GET(size)); + } + if (i & EXT_MEM1_ENABLE) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY1_BAR); + csio_add_debugfs_mem(hw, "mc1", MEM_MC1, + EXT_MEM_SIZE_GET(size)); + } +} + +/* T5 adapter specific function */ +struct csio_hw_chip_ops t5_ops = { + .chip_set_mem_win = csio_t5_set_mem_win, + .chip_pcie_intr_handler = csio_t5_pcie_intr_handler, + .chip_flash_cfg_addr = csio_t5_flash_cfg_addr, + .chip_mc_read = csio_t5_mc_read, + .chip_edc_read = csio_t5_edc_read, + .chip_memory_rw = csio_t5_memory_rw, + .chip_dfs_create_ext_mem = csio_t5_dfs_create_ext_mem, +}; -- cgit From d69630e8a42220b04318995d8ed0637ea79a717e Mon Sep 17 00:00:00 2001 From: Arvind Bhushan Date: Thu, 14 Mar 2013 05:09:07 +0000 Subject: csiostor: Header file modifications for chip support and bug fixes. This patch defines the common operations to support multiple chips. It includes common header file modifications to support the current chips (T4 and T5). It also includes the following bug fixes: - reconfirms the rnode state after an implicit logo. - corrects the stats array size. - sets up and checks flags correctly when coming up as master and finding the card initialized Reported-by: Dan Carpenter Signed-off-by: Arvind Bhushan Signed-off-by: Naresh Kumar Inna Signed-off-by: David S. Miller --- drivers/scsi/csiostor/csio_hw_chip.h | 175 +++++++++++++++++++++++++++++++++++ drivers/scsi/csiostor/csio_lnode.h | 2 +- drivers/scsi/csiostor/csio_rnode.c | 10 +- drivers/scsi/csiostor/csio_rnode.h | 2 +- drivers/scsi/csiostor/csio_wr.c | 41 +++++--- 5 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 drivers/scsi/csiostor/csio_hw_chip.h (limited to 'drivers') diff --git a/drivers/scsi/csiostor/csio_hw_chip.h b/drivers/scsi/csiostor/csio_hw_chip.h new file mode 100644 index 000000000000..bca0de61ae80 --- /dev/null +++ b/drivers/scsi/csiostor/csio_hw_chip.h @@ -0,0 +1,175 @@ +/* + * This file is part of the Chelsio FCoE driver for Linux. + * + * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __CSIO_HW_CHIP_H__ +#define __CSIO_HW_CHIP_H__ + +#include "csio_defs.h" + +/* FCoE device IDs for T4 */ +#define CSIO_DEVID_T440DBG_FCOE 0x4600 +#define CSIO_DEVID_T420CR_FCOE 0x4601 +#define CSIO_DEVID_T422CR_FCOE 0x4602 +#define CSIO_DEVID_T440CR_FCOE 0x4603 +#define CSIO_DEVID_T420BCH_FCOE 0x4604 +#define CSIO_DEVID_T440BCH_FCOE 0x4605 +#define CSIO_DEVID_T440CH_FCOE 0x4606 +#define CSIO_DEVID_T420SO_FCOE 0x4607 +#define CSIO_DEVID_T420CX_FCOE 0x4608 +#define CSIO_DEVID_T420BT_FCOE 0x4609 +#define CSIO_DEVID_T404BT_FCOE 0x460A +#define CSIO_DEVID_B420_FCOE 0x460B +#define CSIO_DEVID_B404_FCOE 0x460C +#define CSIO_DEVID_T480CR_FCOE 0x460D +#define CSIO_DEVID_T440LPCR_FCOE 0x460E +#define CSIO_DEVID_AMSTERDAM_T4_FCOE 0x460F +#define CSIO_DEVID_HUAWEI_T480_FCOE 0x4680 +#define CSIO_DEVID_HUAWEI_T440_FCOE 0x4681 +#define CSIO_DEVID_HUAWEI_STG310_FCOE 0x4682 +#define CSIO_DEVID_ACROMAG_XMC_XAUI 0x4683 +#define CSIO_DEVID_ACROMAG_XMC_SFP_FCOE 0x4684 +#define CSIO_DEVID_QUANTA_MEZZ_SFP_FCOE 0x4685 +#define CSIO_DEVID_HUAWEI_10GT_FCOE 0x4686 +#define CSIO_DEVID_HUAWEI_T440_TOE_FCOE 0x4687 + +/* FCoE device IDs for T5 */ +#define CSIO_DEVID_T580DBG_FCOE 0x5600 +#define CSIO_DEVID_T520CR_FCOE 0x5601 +#define CSIO_DEVID_T522CR_FCOE 0x5602 +#define CSIO_DEVID_T540CR_FCOE 0x5603 +#define CSIO_DEVID_T520BCH_FCOE 0x5604 +#define CSIO_DEVID_T540BCH_FCOE 0x5605 +#define CSIO_DEVID_T540CH_FCOE 0x5606 +#define CSIO_DEVID_T520SO_FCOE 0x5607 +#define CSIO_DEVID_T520CX_FCOE 0x5608 +#define CSIO_DEVID_T520BT_FCOE 0x5609 +#define CSIO_DEVID_T504BT_FCOE 0x560A +#define CSIO_DEVID_B520_FCOE 0x560B +#define CSIO_DEVID_B504_FCOE 0x560C +#define CSIO_DEVID_T580CR2_FCOE 0x560D +#define CSIO_DEVID_T540LPCR_FCOE 0x560E +#define CSIO_DEVID_AMSTERDAM_T5_FCOE 0x560F +#define CSIO_DEVID_T580LPCR_FCOE 0x5610 +#define CSIO_DEVID_T520LLCR_FCOE 0x5611 +#define CSIO_DEVID_T560CR_FCOE 0x5612 +#define CSIO_DEVID_T580CR_FCOE 0x5613 + +/* Define MACRO values */ +#define CSIO_HW_T4 0x4000 +#define CSIO_T4_FCOE_ASIC 0x4600 +#define CSIO_HW_T5 0x5000 +#define CSIO_T5_FCOE_ASIC 0x5600 +#define CSIO_HW_CHIP_MASK 0xF000 +#define T4_REGMAP_SIZE (160 * 1024) +#define T5_REGMAP_SIZE (332 * 1024) +#define FW_FNAME_T4 "cxgb4/t4fw.bin" +#define FW_FNAME_T5 "cxgb4/t5fw.bin" +#define FW_CFG_NAME_T4 "cxgb4/t4-config.txt" +#define FW_CFG_NAME_T5 "cxgb4/t5-config.txt" + +/* Define static functions */ +static inline int csio_is_t4(uint16_t chip) +{ + return (chip == CSIO_HW_T4); +} + +static inline int csio_is_t5(uint16_t chip) +{ + return (chip == CSIO_HW_T5); +} + +/* Define MACRO DEFINITIONS */ +#define CSIO_DEVICE(devid, idx) \ + { PCI_VENDOR_ID_CHELSIO, (devid), PCI_ANY_ID, PCI_ANY_ID, 0, 0, (idx) } + +#define CSIO_HW_PIDX(hw, index) \ + (csio_is_t4(hw->chip_id) ? (PIDX(index)) : \ + (PIDX_T5(index) | DBTYPE(1U))) + +#define CSIO_HW_LP_INT_THRESH(hw, val) \ + (csio_is_t4(hw->chip_id) ? (LP_INT_THRESH(val)) : \ + (V_LP_INT_THRESH_T5(val))) + +#define CSIO_HW_M_LP_INT_THRESH(hw) \ + (csio_is_t4(hw->chip_id) ? (LP_INT_THRESH_MASK) : (M_LP_INT_THRESH_T5)) + +#define CSIO_MAC_INT_CAUSE_REG(hw, port) \ + (csio_is_t4(hw->chip_id) ? (PORT_REG(port, XGMAC_PORT_INT_CAUSE)) : \ + (T5_PORT_REG(port, MAC_PORT_INT_CAUSE))) + +#define FW_VERSION_MAJOR(hw) (csio_is_t4(hw->chip_id) ? 1 : 0) +#define FW_VERSION_MINOR(hw) (csio_is_t4(hw->chip_id) ? 2 : 0) +#define FW_VERSION_MICRO(hw) (csio_is_t4(hw->chip_id) ? 8 : 0) + +#define CSIO_FW_FNAME(hw) \ + (csio_is_t4(hw->chip_id) ? FW_FNAME_T4 : FW_FNAME_T5) + +#define CSIO_CF_FNAME(hw) \ + (csio_is_t4(hw->chip_id) ? FW_CFG_NAME_T4 : FW_CFG_NAME_T5) + +/* Declare ENUMS */ +enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 }; + +enum { + MEMWIN_APERTURE = 2048, + MEMWIN_BASE = 0x1b800, + MEMWIN_CSIOSTOR = 6, /* PCI-e Memory Window access */ +}; + +/* Slow path handlers */ +struct intr_info { + unsigned int mask; /* bits to check in interrupt status */ + const char *msg; /* message to print or NULL */ + short stat_idx; /* stat counter to increment or -1 */ + unsigned short fatal; /* whether the condition reported is fatal */ +}; + +/* T4/T5 Chip specific ops */ +struct csio_hw; +struct csio_hw_chip_ops { + int (*chip_set_mem_win)(struct csio_hw *, uint32_t); + void (*chip_pcie_intr_handler)(struct csio_hw *); + uint32_t (*chip_flash_cfg_addr)(struct csio_hw *); + int (*chip_mc_read)(struct csio_hw *, int, uint32_t, + __be32 *, uint64_t *); + int (*chip_edc_read)(struct csio_hw *, int, uint32_t, + __be32 *, uint64_t *); + int (*chip_memory_rw)(struct csio_hw *, u32, int, u32, + u32, uint32_t *, int); + void (*chip_dfs_create_ext_mem)(struct csio_hw *); +}; + +extern struct csio_hw_chip_ops t4_ops; +extern struct csio_hw_chip_ops t5_ops; + +#endif /* #ifndef __CSIO_HW_CHIP_H__ */ diff --git a/drivers/scsi/csiostor/csio_lnode.h b/drivers/scsi/csiostor/csio_lnode.h index 8d84988ab06d..0f9c04175b11 100644 --- a/drivers/scsi/csiostor/csio_lnode.h +++ b/drivers/scsi/csiostor/csio_lnode.h @@ -114,7 +114,7 @@ struct csio_lnode_stats { uint32_t n_rnode_match; /* matched rnode */ uint32_t n_dev_loss_tmo; /* Device loss timeout */ uint32_t n_fdmi_err; /* fdmi err */ - uint32_t n_evt_fw[RSCN_DEV_LOST]; /* fw events */ + uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO]; /* fw events */ enum csio_ln_ev n_evt_sm[CSIO_LNE_MAX_EVENT]; /* State m/c events */ uint32_t n_rnode_alloc; /* rnode allocated */ uint32_t n_rnode_free; /* rnode freed */ diff --git a/drivers/scsi/csiostor/csio_rnode.c b/drivers/scsi/csiostor/csio_rnode.c index 51c6a388de2b..e9c3b045f587 100644 --- a/drivers/scsi/csiostor/csio_rnode.c +++ b/drivers/scsi/csiostor/csio_rnode.c @@ -302,7 +302,7 @@ csio_confirm_rnode(struct csio_lnode *ln, uint32_t rdev_flowid, { uint8_t rport_type; struct csio_rnode *rn, *match_rn; - uint32_t vnp_flowid; + uint32_t vnp_flowid = 0; __be32 *port_id; port_id = (__be32 *)&rdevp->r_id[0]; @@ -350,6 +350,14 @@ csio_confirm_rnode(struct csio_lnode *ln, uint32_t rdev_flowid, * Else, go ahead and alloc a new rnode. */ if (!memcmp(csio_rn_wwpn(match_rn), rdevp->wwpn, 8)) { + if (rn == match_rn) + goto found_rnode; + csio_ln_dbg(ln, + "nport_id:x%x and wwpn:%llx" + " match for ssni:x%x\n", + rn->nport_id, + wwn_to_u64(rdevp->wwpn), + rdev_flowid); if (csio_is_rnode_ready(rn)) { csio_ln_warn(ln, "rnode is already" diff --git a/drivers/scsi/csiostor/csio_rnode.h b/drivers/scsi/csiostor/csio_rnode.h index a3b434c801da..65940096a80d 100644 --- a/drivers/scsi/csiostor/csio_rnode.h +++ b/drivers/scsi/csiostor/csio_rnode.h @@ -63,7 +63,7 @@ struct csio_rnode_stats { uint32_t n_err_nomem; /* error nomem */ uint32_t n_evt_unexp; /* unexpected event */ uint32_t n_evt_drop; /* unexpected event */ - uint32_t n_evt_fw[RSCN_DEV_LOST]; /* fw events */ + uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO]; /* fw events */ enum csio_rn_ev n_evt_sm[CSIO_RNFE_MAX_EVENT]; /* State m/c events */ uint32_t n_lun_rst; /* Number of resets of * of LUNs under this diff --git a/drivers/scsi/csiostor/csio_wr.c b/drivers/scsi/csiostor/csio_wr.c index c32df1bdaa97..713e77d12cb4 100644 --- a/drivers/scsi/csiostor/csio_wr.c +++ b/drivers/scsi/csiostor/csio_wr.c @@ -1331,14 +1331,21 @@ csio_wr_fixup_host_params(struct csio_hw *hw) /* FL BUFFER SIZE#0 is Page size i,e already aligned to cache line */ csio_wr_reg32(hw, PAGE_SIZE, SGE_FL_BUFFER_SIZE0); - csio_wr_reg32(hw, - (csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE2) + - sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1), - SGE_FL_BUFFER_SIZE2); - csio_wr_reg32(hw, - (csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE3) + - sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1), - SGE_FL_BUFFER_SIZE3); + + /* + * If using hard params, the following will get set correctly + * in csio_wr_set_sge(). + */ + if (hw->flags & CSIO_HWF_USING_SOFT_PARAMS) { + csio_wr_reg32(hw, + (csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE2) + + sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1), + SGE_FL_BUFFER_SIZE2); + csio_wr_reg32(hw, + (csio_rd_reg32(hw, SGE_FL_BUFFER_SIZE3) + + sge->csio_fl_align - 1) & ~(sge->csio_fl_align - 1), + SGE_FL_BUFFER_SIZE3); + } csio_wr_reg32(hw, HPZ0(PAGE_SHIFT - 12), ULP_RX_TDDP_PSZ); @@ -1470,8 +1477,10 @@ csio_wr_set_sge(struct csio_hw *hw) /* SGE_FL_BUFFER_SIZE0 is set up by csio_wr_fixup_host_params(). */ CSIO_SET_FLBUF_SIZE(hw, 1, CSIO_SGE_FLBUF_SIZE1); - CSIO_SET_FLBUF_SIZE(hw, 2, CSIO_SGE_FLBUF_SIZE2); - CSIO_SET_FLBUF_SIZE(hw, 3, CSIO_SGE_FLBUF_SIZE3); + csio_wr_reg32(hw, (CSIO_SGE_FLBUF_SIZE2 + sge->csio_fl_align - 1) + & ~(sge->csio_fl_align - 1), SGE_FL_BUFFER_SIZE2); + csio_wr_reg32(hw, (CSIO_SGE_FLBUF_SIZE3 + sge->csio_fl_align - 1) + & ~(sge->csio_fl_align - 1), SGE_FL_BUFFER_SIZE3); CSIO_SET_FLBUF_SIZE(hw, 4, CSIO_SGE_FLBUF_SIZE4); CSIO_SET_FLBUF_SIZE(hw, 5, CSIO_SGE_FLBUF_SIZE5); CSIO_SET_FLBUF_SIZE(hw, 6, CSIO_SGE_FLBUF_SIZE6); @@ -1522,22 +1531,24 @@ void csio_wr_sge_init(struct csio_hw *hw) { /* - * If we are master: + * If we are master and chip is not initialized: * - If we plan to use the config file, we need to fixup some * host specific registers, and read the rest of the SGE * configuration. * - If we dont plan to use the config file, we need to initialize * SGE entirely, including fixing the host specific registers. + * If we are master and chip is initialized, just read and work off of + * the already initialized SGE values. * If we arent the master, we are only allowed to read and work off of * the already initialized SGE values. * * Therefore, before calling this function, we assume that the master- - * ship of the card, and whether to use config file or not, have - * already been decided. In other words, CSIO_HWF_USING_SOFT_PARAMS and - * CSIO_HWF_MASTER should be set/unset. + * ship of the card, state and whether to use config file or not, have + * already been decided. */ if (csio_is_hw_master(hw)) { - csio_wr_fixup_host_params(hw); + if (hw->fw_state != CSIO_DEV_STATE_INIT) + csio_wr_fixup_host_params(hw); if (hw->flags & CSIO_HWF_USING_SOFT_PARAMS) csio_wr_get_sge(hw); -- cgit From 7cc163806b0dc31ea2067d48a2732b452a709f48 Mon Sep 17 00:00:00 2001 From: Arvind Bhushan Date: Thu, 14 Mar 2013 05:09:08 +0000 Subject: csiostor: Cleanup chip specific operations. This patch removes chip specific operations from the common hardware paths, as well as the Makefile change to accomodate the new files. Signed-off-by: Arvind Bhushan Signed-off-by: Naresh Kumar Inna Signed-off-by: David S. Miller --- drivers/scsi/csiostor/Makefile | 3 +- drivers/scsi/csiostor/csio_hw.c | 559 ++++++++------------------------------ drivers/scsi/csiostor/csio_hw.h | 47 ++-- drivers/scsi/csiostor/csio_init.c | 48 +++- drivers/scsi/csiostor/csio_init.h | 29 +- drivers/scsi/csiostor/csio_wr.c | 19 +- 6 files changed, 193 insertions(+), 512 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/csiostor/Makefile b/drivers/scsi/csiostor/Makefile index b581966c88f9..913b9a92fb06 100644 --- a/drivers/scsi/csiostor/Makefile +++ b/drivers/scsi/csiostor/Makefile @@ -8,4 +8,5 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4 obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor.o csiostor-objs := csio_attr.o csio_init.o csio_lnode.o csio_scsi.o \ - csio_hw.o csio_isr.o csio_mb.o csio_rnode.o csio_wr.o + csio_hw.o csio_hw_t4.o csio_hw_t5.o csio_isr.o \ + csio_mb.o csio_rnode.o csio_wr.o diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index bdd78fb4fc70..a0b4c8991deb 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -61,7 +61,7 @@ int csio_msi = 2; static int dev_num; /* FCoE Adapter types & its description */ -static const struct csio_adap_desc csio_fcoe_adapters[] = { +static const struct csio_adap_desc csio_t4_fcoe_adapters[] = { {"T440-Dbg 10G", "Chelsio T440-Dbg 10G [FCoE]"}, {"T420-CR 10G", "Chelsio T420-CR 10G [FCoE]"}, {"T422-CR 10G/1G", "Chelsio T422-CR 10G/1G [FCoE]"}, @@ -77,7 +77,38 @@ static const struct csio_adap_desc csio_fcoe_adapters[] = { {"B404-BT 1G", "Chelsio B404-BT 1G [FCoE]"}, {"T480-CR 10G", "Chelsio T480-CR 10G [FCoE]"}, {"T440-LP-CR 10G", "Chelsio T440-LP-CR 10G [FCoE]"}, - {"T4 FPGA", "Chelsio T4 FPGA [FCoE]"} + {"AMSTERDAM 10G", "Chelsio AMSTERDAM 10G [FCoE]"}, + {"HUAWEI T480 10G", "Chelsio HUAWEI T480 10G [FCoE]"}, + {"HUAWEI T440 10G", "Chelsio HUAWEI T440 10G [FCoE]"}, + {"HUAWEI STG 10G", "Chelsio HUAWEI STG 10G [FCoE]"}, + {"ACROMAG XAUI 10G", "Chelsio ACROMAG XAUI 10G [FCoE]"}, + {"ACROMAG SFP+ 10G", "Chelsio ACROMAG SFP+ 10G [FCoE]"}, + {"QUANTA SFP+ 10G", "Chelsio QUANTA SFP+ 10G [FCoE]"}, + {"HUAWEI 10Gbase-T", "Chelsio HUAWEI 10Gbase-T [FCoE]"}, + {"HUAWEI T4TOE 10G", "Chelsio HUAWEI T4TOE 10G [FCoE]"} +}; + +static const struct csio_adap_desc csio_t5_fcoe_adapters[] = { + {"T580-Dbg 10G", "Chelsio T580-Dbg 10G [FCoE]"}, + {"T520-CR 10G", "Chelsio T520-CR 10G [FCoE]"}, + {"T522-CR 10G/1G", "Chelsio T452-CR 10G/1G [FCoE]"}, + {"T540-CR 10G", "Chelsio T540-CR 10G [FCoE]"}, + {"T520-BCH 10G", "Chelsio T520-BCH 10G [FCoE]"}, + {"T540-BCH 10G", "Chelsio T540-BCH 10G [FCoE]"}, + {"T540-CH 10G", "Chelsio T540-CH 10G [FCoE]"}, + {"T520-SO 10G", "Chelsio T520-SO 10G [FCoE]"}, + {"T520-CX4 10G", "Chelsio T520-CX4 10G [FCoE]"}, + {"T520-BT 10G", "Chelsio T520-BT 10G [FCoE]"}, + {"T504-BT 1G", "Chelsio T504-BT 1G [FCoE]"}, + {"B520-SR 10G", "Chelsio B520-SR 10G [FCoE]"}, + {"B504-BT 1G", "Chelsio B504-BT 1G [FCoE]"}, + {"T580-CR 10G", "Chelsio T580-CR 10G [FCoE]"}, + {"T540-LP-CR 10G", "Chelsio T540-LP-CR 10G [FCoE]"}, + {"AMSTERDAM 10G", "Chelsio AMSTERDAM 10G [FCoE]"}, + {"T580-LP-CR 40G", "Chelsio T580-LP-CR 40G [FCoE]"}, + {"T520-LL-CR 10G", "Chelsio T520-LL-CR 10G [FCoE]"}, + {"T560-CR 40G", "Chelsio T560-CR 40G [FCoE]"}, + {"T580-CR 40G", "Chelsio T580-CR 40G [FCoE]"} }; static void csio_mgmtm_cleanup(struct csio_mgmtm *); @@ -124,7 +155,7 @@ int csio_is_hw_removing(struct csio_hw *hw) * at the time it indicated completion is stored there. Returns 0 if the * operation completes and -EAGAIN otherwise. */ -static int +int csio_hw_wait_op_done_val(struct csio_hw *hw, int reg, uint32_t mask, int polarity, int attempts, int delay, uint32_t *valp) { @@ -145,6 +176,24 @@ csio_hw_wait_op_done_val(struct csio_hw *hw, int reg, uint32_t mask, } } +/* + * csio_hw_tp_wr_bits_indirect - set/clear bits in an indirect TP register + * @hw: the adapter + * @addr: the indirect TP register address + * @mask: specifies the field within the register to modify + * @val: new value for the field + * + * Sets a field of an indirect TP register to the given value. + */ +void +csio_hw_tp_wr_bits_indirect(struct csio_hw *hw, unsigned int addr, + unsigned int mask, unsigned int val) +{ + csio_wr_reg32(hw, addr, TP_PIO_ADDR); + val |= csio_rd_reg32(hw, TP_PIO_DATA) & ~mask; + csio_wr_reg32(hw, val, TP_PIO_DATA); +} + void csio_set_reg_field(struct csio_hw *hw, uint32_t reg, uint32_t mask, uint32_t value) @@ -157,242 +206,22 @@ csio_set_reg_field(struct csio_hw *hw, uint32_t reg, uint32_t mask, } -/* - * csio_hw_mc_read - read from MC through backdoor accesses - * @hw: the hw module - * @addr: address of first byte requested - * @data: 64 bytes of data containing the requested address - * @ecc: where to store the corresponding 64-bit ECC word - * - * Read 64 bytes of data from MC starting at a 64-byte-aligned address - * that covers the requested address @addr. If @parity is not %NULL it - * is assigned the 64-bit ECC word for the read data. - */ -int -csio_hw_mc_read(struct csio_hw *hw, uint32_t addr, __be32 *data, - uint64_t *ecc) -{ - int i; - - if (csio_rd_reg32(hw, MC_BIST_CMD) & START_BIST) - return -EBUSY; - csio_wr_reg32(hw, addr & ~0x3fU, MC_BIST_CMD_ADDR); - csio_wr_reg32(hw, 64, MC_BIST_CMD_LEN); - csio_wr_reg32(hw, 0xc, MC_BIST_DATA_PATTERN); - csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1), - MC_BIST_CMD); - i = csio_hw_wait_op_done_val(hw, MC_BIST_CMD, START_BIST, - 0, 10, 1, NULL); - if (i) - return i; - -#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i) - - for (i = 15; i >= 0; i--) - *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i))); - if (ecc) - *ecc = csio_rd_reg64(hw, MC_DATA(16)); -#undef MC_DATA - return 0; -} - -/* - * csio_hw_edc_read - read from EDC through backdoor accesses - * @hw: the hw module - * @idx: which EDC to access - * @addr: address of first byte requested - * @data: 64 bytes of data containing the requested address - * @ecc: where to store the corresponding 64-bit ECC word - * - * Read 64 bytes of data from EDC starting at a 64-byte-aligned address - * that covers the requested address @addr. If @parity is not %NULL it - * is assigned the 64-bit ECC word for the read data. - */ -int -csio_hw_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, - uint64_t *ecc) -{ - int i; - - idx *= EDC_STRIDE; - if (csio_rd_reg32(hw, EDC_BIST_CMD + idx) & START_BIST) - return -EBUSY; - csio_wr_reg32(hw, addr & ~0x3fU, EDC_BIST_CMD_ADDR + idx); - csio_wr_reg32(hw, 64, EDC_BIST_CMD_LEN + idx); - csio_wr_reg32(hw, 0xc, EDC_BIST_DATA_PATTERN + idx); - csio_wr_reg32(hw, BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST, - EDC_BIST_CMD + idx); - i = csio_hw_wait_op_done_val(hw, EDC_BIST_CMD + idx, START_BIST, - 0, 10, 1, NULL); - if (i) - return i; - -#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx) - - for (i = 15; i >= 0; i--) - *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i))); - if (ecc) - *ecc = csio_rd_reg64(hw, EDC_DATA(16)); -#undef EDC_DATA - return 0; -} - -/* - * csio_mem_win_rw - read/write memory through PCIE memory window - * @hw: the adapter - * @addr: address of first byte requested - * @data: MEMWIN0_APERTURE bytes of data containing the requested address - * @dir: direction of transfer 1 => read, 0 => write - * - * Read/write MEMWIN0_APERTURE bytes of data from MC starting at a - * MEMWIN0_APERTURE-byte-aligned address that covers the requested - * address @addr. - */ -static int -csio_mem_win_rw(struct csio_hw *hw, u32 addr, u32 *data, int dir) -{ - int i; - - /* - * Setup offset into PCIE memory window. Address must be a - * MEMWIN0_APERTURE-byte-aligned address. (Read back MA register to - * ensure that changes propagate before we attempt to use the new - * values.) - */ - csio_wr_reg32(hw, addr & ~(MEMWIN0_APERTURE - 1), - PCIE_MEM_ACCESS_OFFSET); - csio_rd_reg32(hw, PCIE_MEM_ACCESS_OFFSET); - - /* Collecting data 4 bytes at a time upto MEMWIN0_APERTURE */ - for (i = 0; i < MEMWIN0_APERTURE; i = i + sizeof(__be32)) { - if (dir) - *data++ = csio_rd_reg32(hw, (MEMWIN0_BASE + i)); - else - csio_wr_reg32(hw, *data++, (MEMWIN0_BASE + i)); - } - - return 0; -} - -/* - * csio_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window - * @hw: the csio_hw - * @mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC - * @addr: address within indicated memory type - * @len: amount of memory to transfer - * @buf: host memory buffer - * @dir: direction of transfer 1 => read, 0 => write - * - * Reads/writes an [almost] arbitrary memory region in the firmware: the - * firmware memory address, length and host buffer must be aligned on - * 32-bit boudaries. The memory is transferred as a raw byte sequence - * from/to the firmware's memory. If this memory contains data - * structures which contain multi-byte integers, it's the callers - * responsibility to perform appropriate byte order conversions. - */ -static int -csio_memory_rw(struct csio_hw *hw, int mtype, u32 addr, u32 len, - uint32_t *buf, int dir) -{ - uint32_t pos, start, end, offset, memoffset; - int ret; - uint32_t *data; - - /* - * Argument sanity checks ... - */ - if ((addr & 0x3) || (len & 0x3)) - return -EINVAL; - - data = kzalloc(MEMWIN0_APERTURE, GFP_KERNEL); - if (!data) - return -ENOMEM; - - /* Offset into the region of memory which is being accessed - * MEM_EDC0 = 0 - * MEM_EDC1 = 1 - * MEM_MC = 2 - */ - memoffset = (mtype * (5 * 1024 * 1024)); - - /* Determine the PCIE_MEM_ACCESS_OFFSET */ - addr = addr + memoffset; - - /* - * The underlaying EDC/MC read routines read MEMWIN0_APERTURE bytes - * at a time so we need to round down the start and round up the end. - * We'll start copying out of the first line at (addr - start) a word - * at a time. - */ - start = addr & ~(MEMWIN0_APERTURE-1); - end = (addr + len + MEMWIN0_APERTURE-1) & ~(MEMWIN0_APERTURE-1); - offset = (addr - start)/sizeof(__be32); - - for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) { - /* - * If we're writing, copy the data from the caller's memory - * buffer - */ - if (!dir) { - /* - * If we're doing a partial write, then we need to do - * a read-modify-write ... - */ - if (offset || len < MEMWIN0_APERTURE) { - ret = csio_mem_win_rw(hw, pos, data, 1); - if (ret) { - kfree(data); - return ret; - } - } - while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) && - len > 0) { - data[offset++] = *buf++; - len -= sizeof(__be32); - } - } - - /* - * Transfer a block of memory and bail if there's an error. - */ - ret = csio_mem_win_rw(hw, pos, data, dir); - if (ret) { - kfree(data); - return ret; - } - - /* - * If we're reading, copy the data into the caller's memory - * buffer. - */ - if (dir) - while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) && - len > 0) { - *buf++ = data[offset++]; - len -= sizeof(__be32); - } - } - - kfree(data); - - return 0; -} - static int csio_memory_write(struct csio_hw *hw, int mtype, u32 addr, u32 len, u32 *buf) { - return csio_memory_rw(hw, mtype, addr, len, buf, 0); + return hw->chip_ops->chip_memory_rw(hw, MEMWIN_CSIOSTOR, mtype, + addr, len, buf, 0); } /* * EEPROM reads take a few tens of us while writes can take a bit over 5 ms. */ -#define EEPROM_MAX_RD_POLL 40 -#define EEPROM_MAX_WR_POLL 6 -#define EEPROM_STAT_ADDR 0x7bfc -#define VPD_BASE 0x400 -#define VPD_BASE_OLD 0 -#define VPD_LEN 512 +#define EEPROM_MAX_RD_POLL 40 +#define EEPROM_MAX_WR_POLL 6 +#define EEPROM_STAT_ADDR 0x7bfc +#define VPD_BASE 0x400 +#define VPD_BASE_OLD 0 +#define VPD_LEN 1024 #define VPD_INFO_FLD_HDR_SIZE 3 /* @@ -817,23 +646,6 @@ out: return 0; } -/* - * csio_hw_flash_cfg_addr - return the address of the flash - * configuration file - * @hw: the HW module - * - * Return the address within the flash where the Firmware Configuration - * File is stored. - */ -static unsigned int -csio_hw_flash_cfg_addr(struct csio_hw *hw) -{ - if (hw->params.sf_size == 0x100000) - return FPGA_FLASH_CFG_OFFSET; - else - return FLASH_CFG_OFFSET; -} - static void csio_hw_print_fw_version(struct csio_hw *hw, char *str) { @@ -898,13 +710,13 @@ csio_hw_check_fw_version(struct csio_hw *hw) minor = FW_HDR_FW_VER_MINOR_GET(hw->fwrev); micro = FW_HDR_FW_VER_MICRO_GET(hw->fwrev); - if (major != FW_VERSION_MAJOR) { /* major mismatch - fail */ + if (major != FW_VERSION_MAJOR(hw)) { /* major mismatch - fail */ csio_err(hw, "card FW has major version %u, driver wants %u\n", - major, FW_VERSION_MAJOR); + major, FW_VERSION_MAJOR(hw)); return -EINVAL; } - if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO) + if (minor == FW_VERSION_MINOR(hw) && micro == FW_VERSION_MICRO(hw)) return 0; /* perfect match */ /* Minor/micro version mismatch */ @@ -1044,7 +856,7 @@ static void csio_set_pcie_completion_timeout(struct csio_hw *hw, u8 range) { uint16_t val; - uint32_t pcie_cap; + int pcie_cap; if (!csio_pci_capability(hw->pdev, PCI_CAP_ID_EXP, &pcie_cap)) { pci_read_config_word(hw->pdev, @@ -1056,84 +868,6 @@ csio_set_pcie_completion_timeout(struct csio_hw *hw, u8 range) } } - -/* - * Return the specified PCI-E Configuration Space register from our Physical - * Function. We try first via a Firmware LDST Command since we prefer to let - * the firmware own all of these registers, but if that fails we go for it - * directly ourselves. - */ -static uint32_t -csio_read_pcie_cfg4(struct csio_hw *hw, int reg) -{ - u32 val = 0; - struct csio_mb *mbp; - int rv; - struct fw_ldst_cmd *ldst_cmd; - - mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); - if (!mbp) { - CSIO_INC_STATS(hw, n_err_nomem); - pci_read_config_dword(hw->pdev, reg, &val); - return val; - } - - csio_mb_ldst(hw, mbp, CSIO_MB_DEFAULT_TMO, reg); - - rv = csio_mb_issue(hw, mbp); - - /* - * If the LDST Command suucceeded, exctract the returned register - * value. Otherwise read it directly ourself. - */ - if (rv == 0) { - ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb); - val = ntohl(ldst_cmd->u.pcie.data[0]); - } else - pci_read_config_dword(hw->pdev, reg, &val); - - mempool_free(mbp, hw->mb_mempool); - - return val; -} /* csio_read_pcie_cfg4 */ - -static int -csio_hw_set_mem_win(struct csio_hw *hw) -{ - u32 bar0; - - /* - * Truncation intentional: we only read the bottom 32-bits of the - * 64-bit BAR0/BAR1 ... We use the hardware backdoor mechanism to - * read BAR0 instead of using pci_resource_start() because we could be - * operating from within a Virtual Machine which is trapping our - * accesses to our Configuration Space and we need to set up the PCI-E - * Memory Window decoders with the actual addresses which will be - * coming across the PCI-E link. - */ - bar0 = csio_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0); - bar0 &= PCI_BASE_ADDRESS_MEM_MASK; - - /* - * Set up memory window for accessing adapter memory ranges. (Read - * back MA register to ensure that changes propagate before we attempt - * to use the new values.) - */ - csio_wr_reg32(hw, (bar0 + MEMWIN0_BASE) | BIR(0) | - WINDOW(ilog2(MEMWIN0_APERTURE) - 10), - PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0)); - csio_wr_reg32(hw, (bar0 + MEMWIN1_BASE) | BIR(0) | - WINDOW(ilog2(MEMWIN1_APERTURE) - 10), - PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1)); - csio_wr_reg32(hw, (bar0 + MEMWIN2_BASE) | BIR(0) | - WINDOW(ilog2(MEMWIN2_APERTURE) - 10), - PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2)); - csio_rd_reg32(hw, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2)); - return 0; -} /* csio_hw_set_mem_win */ - - - /*****************************************************************************/ /* HW State machine assists */ /*****************************************************************************/ @@ -1234,7 +968,9 @@ retry: for (;;) { uint32_t pcie_fw; + spin_unlock_irq(&hw->lock); msleep(50); + spin_lock_irq(&hw->lock); waiting -= 50; /* @@ -2121,9 +1857,9 @@ csio_hw_flash_config(struct csio_hw *hw, u32 *fw_cfg_param, char *path) uint32_t *cfg_data; int value_to_add = 0; - if (request_firmware(&cf, CSIO_CF_FNAME, dev) < 0) { - csio_err(hw, "could not find config file " CSIO_CF_FNAME - ",err: %d\n", ret); + if (request_firmware(&cf, CSIO_CF_FNAME(hw), dev) < 0) { + csio_err(hw, "could not find config file %s, err: %d\n", + CSIO_CF_FNAME(hw), ret); return -ENOENT; } @@ -2147,9 +1883,24 @@ csio_hw_flash_config(struct csio_hw *hw, u32 *fw_cfg_param, char *path) ret = csio_memory_write(hw, mtype, maddr, cf->size + value_to_add, cfg_data); + + if ((ret == 0) && (value_to_add != 0)) { + union { + u32 word; + char buf[4]; + } last; + size_t size = cf->size & ~0x3; + int i; + + last.word = cfg_data[size >> 2]; + for (i = value_to_add; i < 4; i++) + last.buf[i] = 0; + ret = csio_memory_write(hw, mtype, maddr + size, 4, &last.word); + } if (ret == 0) { - csio_info(hw, "config file upgraded to " CSIO_CF_FNAME "\n"); - strncpy(path, "/lib/firmware/" CSIO_CF_FNAME, 64); + csio_info(hw, "config file upgraded to %s\n", + CSIO_CF_FNAME(hw)); + snprintf(path, 64, "%s%s", "/lib/firmware/", CSIO_CF_FNAME(hw)); } leave: @@ -2179,7 +1930,7 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) { unsigned int mtype, maddr; int rv; - uint32_t finiver, finicsum, cfcsum; + uint32_t finiver = 0, finicsum = 0, cfcsum = 0; int using_flash; char path[64]; @@ -2207,7 +1958,7 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) * config file from flash. */ mtype = FW_MEMTYPE_CF_FLASH; - maddr = csio_hw_flash_cfg_addr(hw); + maddr = hw->chip_ops->chip_flash_cfg_addr(hw); using_flash = 1; } else { /* @@ -2346,30 +2097,32 @@ csio_hw_flash_fw(struct csio_hw *hw) struct pci_dev *pci_dev = hw->pdev; struct device *dev = &pci_dev->dev ; - if (request_firmware(&fw, CSIO_FW_FNAME, dev) < 0) { - csio_err(hw, "could not find firmware image " CSIO_FW_FNAME - ",err: %d\n", ret); + if (request_firmware(&fw, CSIO_FW_FNAME(hw), dev) < 0) { + csio_err(hw, "could not find firmware image %s, err: %d\n", + CSIO_FW_FNAME(hw), ret); return -EINVAL; } hdr = (const struct fw_hdr *)fw->data; fw_ver = ntohl(hdr->fw_ver); - if (FW_HDR_FW_VER_MAJOR_GET(fw_ver) != FW_VERSION_MAJOR) + if (FW_HDR_FW_VER_MAJOR_GET(fw_ver) != FW_VERSION_MAJOR(hw)) return -EINVAL; /* wrong major version, won't do */ /* * If the flash FW is unusable or we found something newer, load it. */ - if (FW_HDR_FW_VER_MAJOR_GET(hw->fwrev) != FW_VERSION_MAJOR || + if (FW_HDR_FW_VER_MAJOR_GET(hw->fwrev) != FW_VERSION_MAJOR(hw) || fw_ver > hw->fwrev) { ret = csio_hw_fw_upgrade(hw, hw->pfn, fw->data, fw->size, /*force=*/false); if (!ret) - csio_info(hw, "firmware upgraded to version %pI4 from " - CSIO_FW_FNAME "\n", &hdr->fw_ver); + csio_info(hw, + "firmware upgraded to version %pI4 from %s\n", + &hdr->fw_ver, CSIO_FW_FNAME(hw)); else csio_err(hw, "firmware upgrade failed! err=%d\n", ret); - } + } else + ret = -EINVAL; release_firmware(fw); @@ -2410,7 +2163,7 @@ csio_hw_configure(struct csio_hw *hw) /* Set pci completion timeout value to 4 seconds. */ csio_set_pcie_completion_timeout(hw, 0xd); - csio_hw_set_mem_win(hw); + hw->chip_ops->chip_set_mem_win(hw, MEMWIN_CSIOSTOR); rv = csio_hw_get_fw_version(hw, &hw->fwrev); if (rv != 0) @@ -2478,6 +2231,8 @@ csio_hw_configure(struct csio_hw *hw) } else { if (hw->fw_state == CSIO_DEV_STATE_INIT) { + hw->flags |= CSIO_HWF_USING_SOFT_PARAMS; + /* device parameters */ rv = csio_get_device_params(hw); if (rv != 0) @@ -2651,7 +2406,7 @@ csio_hw_intr_disable(struct csio_hw *hw) } -static void +void csio_hw_fatal_err(struct csio_hw *hw) { csio_set_reg_field(hw, SGE_CONTROL, GLOBALENABLE, 0); @@ -2990,14 +2745,6 @@ csio_hws_pcierr(struct csio_hw *hw, enum csio_hw_ev evt) /* END: HW SM */ /*****************************************************************************/ -/* Slow path handlers */ -struct intr_info { - unsigned int mask; /* bits to check in interrupt status */ - const char *msg; /* message to print or NULL */ - short stat_idx; /* stat counter to increment or -1 */ - unsigned short fatal; /* whether the condition reported is fatal */ -}; - /* * csio_handle_intr_status - table driven interrupt handler * @hw: HW instance @@ -3011,7 +2758,7 @@ struct intr_info { * by an entry specifying mask 0. Returns the number of fatal interrupt * conditions. */ -static int +int csio_handle_intr_status(struct csio_hw *hw, unsigned int reg, const struct intr_info *acts) { @@ -3037,80 +2784,6 @@ csio_handle_intr_status(struct csio_hw *hw, unsigned int reg, return fatal; } -/* - * Interrupt handler for the PCIE module. - */ -static void -csio_pcie_intr_handler(struct csio_hw *hw) -{ - static struct intr_info sysbus_intr_info[] = { - { RNPP, "RXNP array parity error", -1, 1 }, - { RPCP, "RXPC array parity error", -1, 1 }, - { RCIP, "RXCIF array parity error", -1, 1 }, - { RCCP, "Rx completions control array parity error", -1, 1 }, - { RFTP, "RXFT array parity error", -1, 1 }, - { 0, NULL, 0, 0 } - }; - static struct intr_info pcie_port_intr_info[] = { - { TPCP, "TXPC array parity error", -1, 1 }, - { TNPP, "TXNP array parity error", -1, 1 }, - { TFTP, "TXFT array parity error", -1, 1 }, - { TCAP, "TXCA array parity error", -1, 1 }, - { TCIP, "TXCIF array parity error", -1, 1 }, - { RCAP, "RXCA array parity error", -1, 1 }, - { OTDD, "outbound request TLP discarded", -1, 1 }, - { RDPE, "Rx data parity error", -1, 1 }, - { TDUE, "Tx uncorrectable data error", -1, 1 }, - { 0, NULL, 0, 0 } - }; - static struct intr_info pcie_intr_info[] = { - { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 }, - { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 }, - { MSIDATAPERR, "MSI data parity error", -1, 1 }, - { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 }, - { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 }, - { MSIXDATAPERR, "MSI-X data parity error", -1, 1 }, - { MSIXDIPERR, "MSI-X DI parity error", -1, 1 }, - { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 }, - { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 }, - { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 }, - { CCNTPERR, "PCI CMD channel count parity error", -1, 1 }, - { CREQPERR, "PCI CMD channel request parity error", -1, 1 }, - { CRSPPERR, "PCI CMD channel response parity error", -1, 1 }, - { DCNTPERR, "PCI DMA channel count parity error", -1, 1 }, - { DREQPERR, "PCI DMA channel request parity error", -1, 1 }, - { DRSPPERR, "PCI DMA channel response parity error", -1, 1 }, - { HCNTPERR, "PCI HMA channel count parity error", -1, 1 }, - { HREQPERR, "PCI HMA channel request parity error", -1, 1 }, - { HRSPPERR, "PCI HMA channel response parity error", -1, 1 }, - { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 }, - { FIDPERR, "PCI FID parity error", -1, 1 }, - { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 }, - { MATAGPERR, "PCI MA tag parity error", -1, 1 }, - { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 }, - { RXCPLPERR, "PCI Rx completion parity error", -1, 1 }, - { RXWRPERR, "PCI Rx write parity error", -1, 1 }, - { RPLPERR, "PCI replay buffer parity error", -1, 1 }, - { PCIESINT, "PCI core secondary fault", -1, 1 }, - { PCIEPINT, "PCI core primary fault", -1, 1 }, - { UNXSPLCPLERR, "PCI unexpected split completion error", -1, - 0 }, - { 0, NULL, 0, 0 } - }; - - int fat; - - fat = csio_handle_intr_status(hw, - PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, - sysbus_intr_info) + - csio_handle_intr_status(hw, - PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, - pcie_port_intr_info) + - csio_handle_intr_status(hw, PCIE_INT_CAUSE, pcie_intr_info); - if (fat) - csio_hw_fatal_err(hw); -} - /* * TP interrupt handler. */ @@ -3517,7 +3190,7 @@ static void csio_ncsi_intr_handler(struct csio_hw *hw) */ static void csio_xgmac_intr_handler(struct csio_hw *hw, int port) { - uint32_t v = csio_rd_reg32(hw, PORT_REG(port, XGMAC_PORT_INT_CAUSE)); + uint32_t v = csio_rd_reg32(hw, CSIO_MAC_INT_CAUSE_REG(hw, port)); v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR; if (!v) @@ -3527,7 +3200,7 @@ static void csio_xgmac_intr_handler(struct csio_hw *hw, int port) csio_fatal(hw, "XGMAC %d Tx FIFO parity error\n", port); if (v & RXFIFO_PRTY_ERR) csio_fatal(hw, "XGMAC %d Rx FIFO parity error\n", port); - csio_wr_reg32(hw, v, PORT_REG(port, XGMAC_PORT_INT_CAUSE)); + csio_wr_reg32(hw, v, CSIO_MAC_INT_CAUSE_REG(hw, port)); csio_hw_fatal_err(hw); } @@ -3596,7 +3269,7 @@ csio_hw_slow_intr_handler(struct csio_hw *hw) csio_xgmac_intr_handler(hw, 3); if (cause & PCIE) - csio_pcie_intr_handler(hw); + hw->chip_ops->chip_pcie_intr_handler(hw); if (cause & MC) csio_mem_intr_handler(hw, MEM_MC); @@ -4262,6 +3935,7 @@ csio_hw_get_device_id(struct csio_hw *hw) &hw->params.pci.device_id); csio_dev_id_cached(hw); + hw->chip_id = (hw->params.pci.device_id & CSIO_HW_CHIP_MASK); } /* csio_hw_get_device_id */ @@ -4280,19 +3954,21 @@ csio_hw_set_description(struct csio_hw *hw, uint16_t ven_id, uint16_t dev_id) prot_type = (dev_id & CSIO_ASIC_DEVID_PROTO_MASK); adap_type = (dev_id & CSIO_ASIC_DEVID_TYPE_MASK); - if (prot_type == CSIO_FPGA) { + if (prot_type == CSIO_T4_FCOE_ASIC) { + memcpy(hw->hw_ver, + csio_t4_fcoe_adapters[adap_type].model_no, 16); memcpy(hw->model_desc, - csio_fcoe_adapters[13].description, 32); - } else if (prot_type == CSIO_T4_FCOE_ASIC) { + csio_t4_fcoe_adapters[adap_type].description, + 32); + } else if (prot_type == CSIO_T5_FCOE_ASIC) { memcpy(hw->hw_ver, - csio_fcoe_adapters[adap_type].model_no, 16); + csio_t5_fcoe_adapters[adap_type].model_no, 16); memcpy(hw->model_desc, - csio_fcoe_adapters[adap_type].description, 32); + csio_t5_fcoe_adapters[adap_type].description, + 32); } else { char tempName[32] = "Chelsio FCoE Controller"; memcpy(hw->model_desc, tempName, 32); - - CSIO_DB_ASSERT(0); } } } /* csio_hw_set_description */ @@ -4321,6 +3997,9 @@ csio_hw_init(struct csio_hw *hw) strcpy(hw->name, CSIO_HW_NAME); + /* Initialize the HW chip ops with T4/T5 specific ops */ + hw->chip_ops = csio_is_t4(hw->chip_id) ? &t4_ops : &t5_ops; + /* Set the model & its description */ ven_id = hw->params.pci.vendor_id; diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h index 9edcca4c71af..489fc095cb03 100644 --- a/drivers/scsi/csiostor/csio_hw.h +++ b/drivers/scsi/csiostor/csio_hw.h @@ -48,6 +48,7 @@ #include #include +#include "csio_hw_chip.h" #include "csio_wr.h" #include "csio_mb.h" #include "csio_scsi.h" @@ -60,13 +61,6 @@ */ #define FW_HOSTERROR 255 -#define CSIO_FW_FNAME "cxgb4/t4fw.bin" -#define CSIO_CF_FNAME "cxgb4/t4-config.txt" - -#define FW_VERSION_MAJOR 1 -#define FW_VERSION_MINOR 2 -#define FW_VERSION_MICRO 8 - #define CSIO_HW_NAME "Chelsio FCoE Adapter" #define CSIO_MAX_PFN 8 #define CSIO_MAX_PPORTS 4 @@ -123,8 +117,6 @@ extern int csio_msi; #define CSIO_VENDOR_ID 0x1425 #define CSIO_ASIC_DEVID_PROTO_MASK 0xFF00 #define CSIO_ASIC_DEVID_TYPE_MASK 0x00FF -#define CSIO_FPGA 0xA000 -#define CSIO_T4_FCOE_ASIC 0x4600 #define CSIO_GLBL_INTR_MASK (CIM | MPS | PL | PCIE | MC | EDC0 | \ EDC1 | LE | TP | MA | PM_TX | PM_RX | \ @@ -207,17 +199,6 @@ enum { SF_SIZE = SF_SEC_SIZE * 16, /* serial flash size */ }; -enum { MEM_EDC0, MEM_EDC1, MEM_MC }; - -enum { - MEMWIN0_APERTURE = 2048, - MEMWIN0_BASE = 0x1b800, - MEMWIN1_APERTURE = 32768, - MEMWIN1_BASE = 0x28000, - MEMWIN2_APERTURE = 65536, - MEMWIN2_BASE = 0x30000, -}; - /* serial flash and firmware constants */ enum { SF_ATTEMPTS = 10, /* max retries for SF operations */ @@ -239,9 +220,6 @@ enum { FLASH_CFG_MAX_SIZE = 0x10000 , /* max size of the flash config file*/ FLASH_CFG_OFFSET = 0x1f0000, FLASH_CFG_START_SEC = FLASH_CFG_OFFSET / SF_SEC_SIZE, - FPGA_FLASH_CFG_OFFSET = 0xf0000 , /* if FPGA mode, then cfg file is - * at 1MB - 64KB */ - FPGA_FLASH_CFG_START_SEC = FPGA_FLASH_CFG_OFFSET / SF_SEC_SIZE, }; /* @@ -259,6 +237,8 @@ enum { FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC), FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS), + /* Location of Firmware Configuration File in FLASH. */ + FLASH_CFG_START = FLASH_START(FLASH_CFG_START_SEC), }; #undef FLASH_START @@ -310,7 +290,7 @@ struct csio_adap_desc { struct pci_params { uint16_t vendor_id; uint16_t device_id; - uint32_t vpd_cap_addr; + int vpd_cap_addr; uint16_t speed; uint8_t width; }; @@ -513,6 +493,7 @@ struct csio_hw { uint32_t fwrev; uint32_t tp_vers; char chip_ver; + uint16_t chip_id; /* Tells T4/T5 chip */ uint32_t cfg_finiver; uint32_t cfg_finicsum; uint32_t cfg_cfcsum; @@ -556,6 +537,9 @@ struct csio_hw { */ struct csio_fcoe_res_info fres_info; /* Fcoe resource info */ + struct csio_hw_chip_ops *chip_ops; /* T4/T5 Chip specific + * Operations + */ /* MSIX vectors */ struct csio_msix_entries msix_entries[CSIO_MAX_MSIX_VECS]; @@ -636,9 +620,16 @@ csio_us_to_core_ticks(struct csio_hw *hw, uint32_t us) #define csio_dbg(__hw, __fmt, ...) #endif +int csio_hw_wait_op_done_val(struct csio_hw *, int, uint32_t, int, + int, int, uint32_t *); +void csio_hw_tp_wr_bits_indirect(struct csio_hw *, unsigned int, + unsigned int, unsigned int); int csio_mgmt_req_lookup(struct csio_mgmtm *, struct csio_ioreq *); void csio_hw_intr_disable(struct csio_hw *); -int csio_hw_slow_intr_handler(struct csio_hw *hw); +int csio_hw_slow_intr_handler(struct csio_hw *); +int csio_handle_intr_status(struct csio_hw *, unsigned int, + const struct intr_info *); + int csio_hw_start(struct csio_hw *); int csio_hw_stop(struct csio_hw *); int csio_hw_reset(struct csio_hw *); @@ -647,19 +638,17 @@ int csio_is_hw_removing(struct csio_hw *); int csio_fwevtq_handler(struct csio_hw *); void csio_evtq_worker(struct work_struct *); -int csio_enqueue_evt(struct csio_hw *hw, enum csio_evt type, - void *evt_msg, uint16_t len); +int csio_enqueue_evt(struct csio_hw *, enum csio_evt, void *, uint16_t); void csio_evtq_flush(struct csio_hw *hw); int csio_request_irqs(struct csio_hw *); void csio_intr_enable(struct csio_hw *); void csio_intr_disable(struct csio_hw *, bool); +void csio_hw_fatal_err(struct csio_hw *); struct csio_lnode *csio_lnode_alloc(struct csio_hw *); int csio_config_queues(struct csio_hw *); -int csio_hw_mc_read(struct csio_hw *, uint32_t, __be32 *, uint64_t *); -int csio_hw_edc_read(struct csio_hw *, int, uint32_t, __be32 *, uint64_t *); int csio_hw_init(struct csio_hw *); void csio_hw_exit(struct csio_hw *); #endif /* ifndef __CSIO_HW_H__ */ diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 0604b5ff3638..00346fe939d5 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -81,9 +81,11 @@ csio_mem_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) __be32 data[16]; if (mem == MEM_MC) - ret = csio_hw_mc_read(hw, pos, data, NULL); + ret = hw->chip_ops->chip_mc_read(hw, 0, pos, + data, NULL); else - ret = csio_hw_edc_read(hw, mem, pos, data, NULL); + ret = hw->chip_ops->chip_edc_read(hw, mem, pos, + data, NULL); if (ret) return ret; @@ -108,7 +110,7 @@ static const struct file_operations csio_mem_debugfs_fops = { .llseek = default_llseek, }; -static void csio_add_debugfs_mem(struct csio_hw *hw, const char *name, +void csio_add_debugfs_mem(struct csio_hw *hw, const char *name, unsigned int idx, unsigned int size_mb) { struct dentry *de; @@ -131,9 +133,8 @@ static int csio_setup_debugfs(struct csio_hw *hw) csio_add_debugfs_mem(hw, "edc0", MEM_EDC0, 5); if (i & EDRAM1_ENABLE) csio_add_debugfs_mem(hw, "edc1", MEM_EDC1, 5); - if (i & EXT_MEM_ENABLE) - csio_add_debugfs_mem(hw, "mc", MEM_MC, - EXT_MEM_SIZE_GET(csio_rd_reg32(hw, MA_EXT_MEMORY_BAR))); + + hw->chip_ops->chip_dfs_create_ext_mem(hw); return 0; } @@ -1169,7 +1170,7 @@ static struct pci_error_handlers csio_err_handler = { }; static DEFINE_PCI_DEVICE_TABLE(csio_pci_tbl) = { - CSIO_DEVICE(CSIO_DEVID_T440DBG_FCOE, 0), /* T440DBG FCOE */ + CSIO_DEVICE(CSIO_DEVID_T440DBG_FCOE, 0), /* T4 DEBUG FCOE */ CSIO_DEVICE(CSIO_DEVID_T420CR_FCOE, 0), /* T420CR FCOE */ CSIO_DEVICE(CSIO_DEVID_T422CR_FCOE, 0), /* T422CR FCOE */ CSIO_DEVICE(CSIO_DEVID_T440CR_FCOE, 0), /* T440CR FCOE */ @@ -1184,8 +1185,34 @@ static DEFINE_PCI_DEVICE_TABLE(csio_pci_tbl) = { CSIO_DEVICE(CSIO_DEVID_B404_FCOE, 0), /* B404 FCOE */ CSIO_DEVICE(CSIO_DEVID_T480CR_FCOE, 0), /* T480 CR FCOE */ CSIO_DEVICE(CSIO_DEVID_T440LPCR_FCOE, 0), /* T440 LP-CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_PE10K, 0), /* PE10K FCOE */ - CSIO_DEVICE(CSIO_DEVID_PE10K_PF1, 0), /* PE10K FCOE on PF1 */ + CSIO_DEVICE(CSIO_DEVID_AMSTERDAM_T4_FCOE, 0), /* AMSTERDAM T4 FCOE */ + CSIO_DEVICE(CSIO_DEVID_HUAWEI_T480_FCOE, 0), /* HUAWEI T480 FCOE */ + CSIO_DEVICE(CSIO_DEVID_HUAWEI_T440_FCOE, 0), /* HUAWEI T440 FCOE */ + CSIO_DEVICE(CSIO_DEVID_HUAWEI_STG310_FCOE, 0), /* HUAWEI STG FCOE */ + CSIO_DEVICE(CSIO_DEVID_ACROMAG_XMC_XAUI, 0), /* ACROMAG XAUI FCOE */ + CSIO_DEVICE(CSIO_DEVID_QUANTA_MEZZ_SFP_FCOE, 0),/* QUANTA MEZZ FCOE */ + CSIO_DEVICE(CSIO_DEVID_HUAWEI_10GT_FCOE, 0), /* HUAWEI 10GT FCOE */ + CSIO_DEVICE(CSIO_DEVID_HUAWEI_T440_TOE_FCOE, 0),/* HUAWEI T4 TOE FCOE */ + CSIO_DEVICE(CSIO_DEVID_T580DBG_FCOE, 0), /* T5 DEBUG FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520CR_FCOE, 0), /* T520CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T522CR_FCOE, 0), /* T522CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T540CR_FCOE, 0), /* T540CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520BCH_FCOE, 0), /* T520BCH FCOE */ + CSIO_DEVICE(CSIO_DEVID_T540BCH_FCOE, 0), /* T540BCH FCOE */ + CSIO_DEVICE(CSIO_DEVID_T540CH_FCOE, 0), /* T540CH FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520SO_FCOE, 0), /* T520SO FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520CX_FCOE, 0), /* T520CX FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520BT_FCOE, 0), /* T520BT FCOE */ + CSIO_DEVICE(CSIO_DEVID_T504BT_FCOE, 0), /* T504BT FCOE */ + CSIO_DEVICE(CSIO_DEVID_B520_FCOE, 0), /* B520 FCOE */ + CSIO_DEVICE(CSIO_DEVID_B504_FCOE, 0), /* B504 FCOE */ + CSIO_DEVICE(CSIO_DEVID_T580CR2_FCOE, 0), /* T580 CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T540LPCR_FCOE, 0), /* T540 LP-CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_AMSTERDAM_T5_FCOE, 0), /* AMSTERDAM T5 FCOE */ + CSIO_DEVICE(CSIO_DEVID_T580LPCR_FCOE, 0), /* T580 LP-CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T520LLCR_FCOE, 0), /* T520 LL-CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T560CR_FCOE, 0), /* T560 CR FCOE */ + CSIO_DEVICE(CSIO_DEVID_T580CR_FCOE, 0), /* T580 CR FCOE */ { 0, 0, 0, 0, 0, 0, 0 } }; @@ -1259,4 +1286,5 @@ MODULE_DESCRIPTION(CSIO_DRV_DESC); MODULE_LICENSE(CSIO_DRV_LICENSE); MODULE_DEVICE_TABLE(pci, csio_pci_tbl); MODULE_VERSION(CSIO_DRV_VERSION); -MODULE_FIRMWARE(CSIO_FW_FNAME); +MODULE_FIRMWARE(FW_FNAME_T4); +MODULE_FIRMWARE(FW_FNAME_T5); diff --git a/drivers/scsi/csiostor/csio_init.h b/drivers/scsi/csiostor/csio_init.h index 0838fd7ec9c7..5cc5d317a442 100644 --- a/drivers/scsi/csiostor/csio_init.h +++ b/drivers/scsi/csiostor/csio_init.h @@ -52,31 +52,6 @@ #define CSIO_DRV_DESC "Chelsio FCoE driver" #define CSIO_DRV_VERSION "1.0.0" -#define CSIO_DEVICE(devid, idx) \ -{ PCI_VENDOR_ID_CHELSIO, (devid), PCI_ANY_ID, PCI_ANY_ID, 0, 0, (idx) } - -#define CSIO_IS_T4_FPGA(_dev) (((_dev) == CSIO_DEVID_PE10K) ||\ - ((_dev) == CSIO_DEVID_PE10K_PF1)) - -/* FCoE device IDs */ -#define CSIO_DEVID_PE10K 0xA000 -#define CSIO_DEVID_PE10K_PF1 0xA001 -#define CSIO_DEVID_T440DBG_FCOE 0x4600 -#define CSIO_DEVID_T420CR_FCOE 0x4601 -#define CSIO_DEVID_T422CR_FCOE 0x4602 -#define CSIO_DEVID_T440CR_FCOE 0x4603 -#define CSIO_DEVID_T420BCH_FCOE 0x4604 -#define CSIO_DEVID_T440BCH_FCOE 0x4605 -#define CSIO_DEVID_T440CH_FCOE 0x4606 -#define CSIO_DEVID_T420SO_FCOE 0x4607 -#define CSIO_DEVID_T420CX_FCOE 0x4608 -#define CSIO_DEVID_T420BT_FCOE 0x4609 -#define CSIO_DEVID_T404BT_FCOE 0x460A -#define CSIO_DEVID_B420_FCOE 0x460B -#define CSIO_DEVID_B404_FCOE 0x460C -#define CSIO_DEVID_T480CR_FCOE 0x460D -#define CSIO_DEVID_T440LPCR_FCOE 0x460E - extern struct fc_function_template csio_fc_transport_funcs; extern struct fc_function_template csio_fc_transport_vport_funcs; @@ -100,6 +75,10 @@ struct csio_lnode *csio_shost_init(struct csio_hw *, struct device *, bool, void csio_shost_exit(struct csio_lnode *); void csio_lnodes_exit(struct csio_hw *, bool); +/* DebugFS helper routines */ +void csio_add_debugfs_mem(struct csio_hw *, const char *, + unsigned int, unsigned int); + static inline struct Scsi_Host * csio_ln_to_shost(struct csio_lnode *ln) { diff --git a/drivers/scsi/csiostor/csio_wr.c b/drivers/scsi/csiostor/csio_wr.c index 713e77d12cb4..4255ce264abf 100644 --- a/drivers/scsi/csiostor/csio_wr.c +++ b/drivers/scsi/csiostor/csio_wr.c @@ -85,8 +85,8 @@ csio_wr_ring_fldb(struct csio_hw *hw, struct csio_q *flq) */ if (flq->inc_idx >= 8) { csio_wr_reg32(hw, DBPRIO(1) | QID(flq->un.fl.flid) | - PIDX(flq->inc_idx / 8), - MYPF_REG(SGE_PF_KDOORBELL)); + CSIO_HW_PIDX(hw, flq->inc_idx / 8), + MYPF_REG(SGE_PF_KDOORBELL)); flq->inc_idx &= 7; } } @@ -989,7 +989,8 @@ csio_wr_issue(struct csio_hw *hw, int qidx, bool prio) wmb(); /* Ring SGE Doorbell writing q->pidx into it */ csio_wr_reg32(hw, DBPRIO(prio) | QID(q->un.eq.physeqid) | - PIDX(q->inc_idx), MYPF_REG(SGE_PF_KDOORBELL)); + CSIO_HW_PIDX(hw, q->inc_idx), + MYPF_REG(SGE_PF_KDOORBELL)); q->inc_idx = 0; return 0; @@ -1352,6 +1353,9 @@ csio_wr_fixup_host_params(struct csio_hw *hw) /* default value of rx_dma_offset of the NIC driver */ csio_set_reg_field(hw, SGE_CONTROL, PKTSHIFT_MASK, PKTSHIFT(CSIO_SGE_RX_DMA_OFFSET)); + + csio_hw_tp_wr_bits_indirect(hw, TP_INGRESS_CONFIG, + CSUM_HAS_PSEUDO_HDR, 0); } static void @@ -1467,10 +1471,11 @@ csio_wr_set_sge(struct csio_hw *hw) * and generate an interrupt when this occurs so we can recover. */ csio_set_reg_field(hw, SGE_DBFIFO_STATUS, - HP_INT_THRESH(HP_INT_THRESH_MASK) | - LP_INT_THRESH(LP_INT_THRESH_MASK), - HP_INT_THRESH(CSIO_SGE_DBFIFO_INT_THRESH) | - LP_INT_THRESH(CSIO_SGE_DBFIFO_INT_THRESH)); + HP_INT_THRESH(HP_INT_THRESH_MASK) | + CSIO_HW_LP_INT_THRESH(hw, CSIO_HW_M_LP_INT_THRESH(hw)), + HP_INT_THRESH(CSIO_SGE_DBFIFO_INT_THRESH) | + CSIO_HW_LP_INT_THRESH(hw, CSIO_SGE_DBFIFO_INT_THRESH)); + csio_set_reg_field(hw, SGE_DOORBELL_CONTROL, ENABLE_DROP, ENABLE_DROP); -- cgit From 3f9fb2a08f55c79b4c6cde423c1e8ddcc5a49781 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 13 Mar 2013 13:15:25 +0100 Subject: ARM: cns3xxx: make mach header files local The mach/cns3xxx.h and mach/pm.h header files are used only in the platform code itself, so there is no need to make them globally visible. This gets us closer to multiplatform configuration for cns3xxx. Signed-off-by: Arnd Bergmann --- arch/arm/mach-cns3xxx/cns3420vb.c | 5 +- arch/arm/mach-cns3xxx/cns3xxx.h | 629 +++++++++++++++++++++++ arch/arm/mach-cns3xxx/core.c | 2 +- arch/arm/mach-cns3xxx/devices.c | 5 +- arch/arm/mach-cns3xxx/include/mach/cns3xxx.h | 632 ------------------------ arch/arm/mach-cns3xxx/include/mach/pm.h | 23 - arch/arm/mach-cns3xxx/include/mach/uncompress.h | 2 +- arch/arm/mach-cns3xxx/pcie.c | 2 +- arch/arm/mach-cns3xxx/pm.c | 4 +- arch/arm/mach-cns3xxx/pm.h | 23 + drivers/mmc/host/sdhci-cns3xxx.c | 1 - 11 files changed, 661 insertions(+), 667 deletions(-) create mode 100644 arch/arm/mach-cns3xxx/cns3xxx.h delete mode 100644 arch/arm/mach-cns3xxx/include/mach/cns3xxx.h delete mode 100644 arch/arm/mach-cns3xxx/include/mach/pm.h create mode 100644 arch/arm/mach-cns3xxx/pm.h (limited to 'drivers') diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index a71867e1d8d6..d863d8729edc 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -31,9 +31,8 @@ #include #include #include -#include -#include -#include +#include "cns3xxx.h" +#include "pm.h" #include "core.h" #include "devices.h" diff --git a/arch/arm/mach-cns3xxx/cns3xxx.h b/arch/arm/mach-cns3xxx/cns3xxx.h new file mode 100644 index 000000000000..d7d3a8d64282 --- /dev/null +++ b/arch/arm/mach-cns3xxx/cns3xxx.h @@ -0,0 +1,629 @@ +/* + * Copyright 2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + */ + +#ifndef __MACH_BOARD_CNS3XXXH +#define __MACH_BOARD_CNS3XXXH + +/* + * Memory map + */ +#define CNS3XXX_FLASH_BASE 0x10000000 /* Flash/SRAM Memory Bank 0 */ +#define CNS3XXX_FLASH_SIZE SZ_256M + +#define CNS3XXX_DDR2SDRAM_BASE 0x20000000 /* DDR2 SDRAM Memory */ + +#define CNS3XXX_SPI_FLASH_BASE 0x60000000 /* SPI Serial Flash Memory */ + +#define CNS3XXX_SWITCH_BASE 0x70000000 /* Switch and HNAT Control */ +#define CNS3XXX_SWITCH_BASE_VIRT 0xFFF00000 + +#define CNS3XXX_PPE_BASE 0x70001000 /* HANT */ +#define CNS3XXX_PPE_BASE_VIRT 0xFFF50000 + +#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */ +#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT 0xFFF60000 + +#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */ +#define CNS3XXX_SSP_BASE_VIRT 0xFFF01000 + +#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */ +#define CNS3XXX_DMC_BASE_VIRT 0xFFF02000 + +#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */ +#define CNS3XXX_SMC_BASE_VIRT 0xFFF03000 + +#define SMC_MEMC_STATUS_OFFSET 0x000 +#define SMC_MEMIF_CFG_OFFSET 0x004 +#define SMC_MEMC_CFG_SET_OFFSET 0x008 +#define SMC_MEMC_CFG_CLR_OFFSET 0x00C +#define SMC_DIRECT_CMD_OFFSET 0x010 +#define SMC_SET_CYCLES_OFFSET 0x014 +#define SMC_SET_OPMODE_OFFSET 0x018 +#define SMC_REFRESH_PERIOD_0_OFFSET 0x020 +#define SMC_REFRESH_PERIOD_1_OFFSET 0x024 +#define SMC_SRAM_CYCLES0_0_OFFSET 0x100 +#define SMC_NAND_CYCLES0_0_OFFSET 0x100 +#define SMC_OPMODE0_0_OFFSET 0x104 +#define SMC_SRAM_CYCLES0_1_OFFSET 0x120 +#define SMC_NAND_CYCLES0_1_OFFSET 0x120 +#define SMC_OPMODE0_1_OFFSET 0x124 +#define SMC_USER_STATUS_OFFSET 0x200 +#define SMC_USER_CONFIG_OFFSET 0x204 +#define SMC_ECC_STATUS_OFFSET 0x300 +#define SMC_ECC_MEMCFG_OFFSET 0x304 +#define SMC_ECC_MEMCOMMAND1_OFFSET 0x308 +#define SMC_ECC_MEMCOMMAND2_OFFSET 0x30C +#define SMC_ECC_ADDR0_OFFSET 0x310 +#define SMC_ECC_ADDR1_OFFSET 0x314 +#define SMC_ECC_VALUE0_OFFSET 0x318 +#define SMC_ECC_VALUE1_OFFSET 0x31C +#define SMC_ECC_VALUE2_OFFSET 0x320 +#define SMC_ECC_VALUE3_OFFSET 0x324 +#define SMC_PERIPH_ID_0_OFFSET 0xFE0 +#define SMC_PERIPH_ID_1_OFFSET 0xFE4 +#define SMC_PERIPH_ID_2_OFFSET 0xFE8 +#define SMC_PERIPH_ID_3_OFFSET 0xFEC +#define SMC_PCELL_ID_0_OFFSET 0xFF0 +#define SMC_PCELL_ID_1_OFFSET 0xFF4 +#define SMC_PCELL_ID_2_OFFSET 0xFF8 +#define SMC_PCELL_ID_3_OFFSET 0xFFC + +#define CNS3XXX_GPIOA_BASE 0x74000000 /* GPIO port A */ +#define CNS3XXX_GPIOA_BASE_VIRT 0xFFF04000 + +#define CNS3XXX_GPIOB_BASE 0x74800000 /* GPIO port B */ +#define CNS3XXX_GPIOB_BASE_VIRT 0xFFF05000 + +#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */ +#define CNS3XXX_RTC_BASE_VIRT 0xFFF06000 + +#define RTC_SEC_OFFSET 0x00 +#define RTC_MIN_OFFSET 0x04 +#define RTC_HOUR_OFFSET 0x08 +#define RTC_DAY_OFFSET 0x0C +#define RTC_SEC_ALM_OFFSET 0x10 +#define RTC_MIN_ALM_OFFSET 0x14 +#define RTC_HOUR_ALM_OFFSET 0x18 +#define RTC_REC_OFFSET 0x1C +#define RTC_CTRL_OFFSET 0x20 +#define RTC_INTR_STS_OFFSET 0x34 + +#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ +#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ + +#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ +#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 + +#define PM_CLK_GATE_OFFSET 0x00 +#define PM_SOFT_RST_OFFSET 0x04 +#define PM_HS_CFG_OFFSET 0x08 +#define PM_CACTIVE_STA_OFFSET 0x0C +#define PM_PWR_STA_OFFSET 0x10 +#define PM_SYS_CLK_CTRL_OFFSET 0x14 +#define PM_PLL_LCD_I2S_CTRL_OFFSET 0x18 +#define PM_PLL_HM_PD_OFFSET 0x1C + +#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ +#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 + +#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ +#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 + +#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */ +#define CNS3XXX_UART2_BASE_VIRT 0xFFF0B000 + +#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */ +#define CNS3XXX_DMAC_BASE_VIRT 0xFFF0D000 + +#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */ +#define CNS3XXX_CORESIGHT_BASE_VIRT 0xFFF0E000 + +#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */ +#define CNS3XXX_CRYPTO_BASE_VIRT 0xFFF0F000 + +#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */ +#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 + +#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 + +#define TIMER1_COUNTER_OFFSET 0x00 +#define TIMER1_AUTO_RELOAD_OFFSET 0x04 +#define TIMER1_MATCH_V1_OFFSET 0x08 +#define TIMER1_MATCH_V2_OFFSET 0x0C + +#define TIMER2_COUNTER_OFFSET 0x10 +#define TIMER2_AUTO_RELOAD_OFFSET 0x14 +#define TIMER2_MATCH_V1_OFFSET 0x18 +#define TIMER2_MATCH_V2_OFFSET 0x1C + +#define TIMER1_2_CONTROL_OFFSET 0x30 +#define TIMER1_2_INTERRUPT_STATUS_OFFSET 0x34 +#define TIMER1_2_INTERRUPT_MASK_OFFSET 0x38 + +#define TIMER_FREERUN_OFFSET 0x40 +#define TIMER_FREERUN_CONTROL_OFFSET 0x44 + +#define CNS3XXX_HCIE_BASE 0x7D000000 /* HCIE Control */ +#define CNS3XXX_HCIE_BASE_VIRT 0xFFF30000 + +#define CNS3XXX_RAID_BASE 0x7E000000 /* RAID Control */ +#define CNS3XXX_RAID_BASE_VIRT 0xFFF12000 + +#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */ +#define CNS3XXX_AXI_IXC_BASE_VIRT 0xFFF13000 + +#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */ +#define CNS3XXX_CLCD_BASE_VIRT 0xFFF14000 + +#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */ +#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000 + +#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */ + +#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */ +#define CNS3XXX_SATA2_SIZE SZ_16M +#define CNS3XXX_SATA2_BASE_VIRT 0xFFF17000 + +#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */ +#define CNS3XXX_CAMERA_BASE_VIRT 0xFFF18000 + +#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */ +#define CNS3XXX_SDIO_BASE_VIRT 0xFFF19000 + +#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */ +#define CNS3XXX_I2S_TDM_BASE_VIRT 0xFFF1A000 + +#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */ +#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000 + +#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */ + +#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ +#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000 + +#define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */ +#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000 + +#define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */ +#define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000 + +#define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */ +#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000 + +#define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */ +#define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000 + +#define CNS3XXX_PCIE0_CFG1_BASE 0xAE000000 /* PCIe Port 0 CFG Type 1 */ +#define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000 + +#define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */ +#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000 + +#define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */ +#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000 + +#define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */ +#define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000 + +#define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */ +#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000 + +#define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */ +#define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000 + +#define CNS3XXX_PCIE1_CFG1_BASE 0xBE000000 /* PCIe Port 1 CFG Type 1 */ +#define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000 + +#define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */ +#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000 + +/* + * Testchip peripheral and fpga gic regions + */ +#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 + +#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 + +#define CNS3XXX_TC11MP_TWD_BASE 0x90000600 +#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 + +#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 + +#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ +#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 + +/* + * Misc block + */ +#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs)) + +#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP(0x00) +#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP(0x04) +#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP(0x08) +#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP(0x0C) +#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP(0x10) +#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP(0x14) +#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP(0x18) +#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP(0x1C) +#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP(0x20) +#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x24) +#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x28) +#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x2C) +#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x30) +#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP(0x34) +#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP(0x40) +#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP(0x44) +#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP(0x48) +#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP(0x4C) +#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP(0x50) +#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP(0x54) + +#define MISC_SATA_POWER_MODE MISC_MEM_MAP(0x310) + +#define MISC_USB_CFG_REG MISC_MEM_MAP(0x800) +#define MISC_USB_STS_REG MISC_MEM_MAP(0x804) +#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP(0x808) +#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP(0x80c) +#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP(0x810) +#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP(0x814) + +#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004) +#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100) +#define MISC_PCIE_AXIS_AWMISC(x) MISC_MEM_MAP(0x944 + (x) * 0x100) +#define MISC_PCIE_AXIS_ARMISC(x) MISC_MEM_MAP(0x948 + (x) * 0x100) +#define MISC_PCIE_AXIS_RMISC(x) MISC_MEM_MAP(0x94C + (x) * 0x100) +#define MISC_PCIE_AXIS_BMISC(x) MISC_MEM_MAP(0x950 + (x) * 0x100) +#define MISC_PCIE_AXIM_RMISC(x) MISC_MEM_MAP(0x954 + (x) * 0x100) +#define MISC_PCIE_AXIM_BMISC(x) MISC_MEM_MAP(0x958 + (x) * 0x100) +#define MISC_PCIE_CTRL(x) MISC_MEM_MAP(0x95C + (x) * 0x100) +#define MISC_PCIE_PM_DEBUG(x) MISC_MEM_MAP(0x960 + (x) * 0x100) +#define MISC_PCIE_RFC_DEBUG(x) MISC_MEM_MAP(0x964 + (x) * 0x100) +#define MISC_PCIE_CXPL_DEBUGL(x) MISC_MEM_MAP(0x968 + (x) * 0x100) +#define MISC_PCIE_CXPL_DEBUGH(x) MISC_MEM_MAP(0x96C + (x) * 0x100) +#define MISC_PCIE_DIAG_DEBUGH(x) MISC_MEM_MAP(0x970 + (x) * 0x100) +#define MISC_PCIE_W1CLR(x) MISC_MEM_MAP(0x974 + (x) * 0x100) +#define MISC_PCIE_INT_MASK(x) MISC_MEM_MAP(0x978 + (x) * 0x100) +#define MISC_PCIE_INT_STATUS(x) MISC_MEM_MAP(0x97C + (x) * 0x100) + +/* + * Power management and clock control + */ +#define PMU_MEM_MAP(offs) (void __iomem *)(CNS3XXX_PM_BASE_VIRT + (offs)) + +#define PM_CLK_GATE_REG PMU_MEM_MAP(0x000) +#define PM_SOFT_RST_REG PMU_MEM_MAP(0x004) +#define PM_HS_CFG_REG PMU_MEM_MAP(0x008) +#define PM_CACTIVE_STA_REG PMU_MEM_MAP(0x00C) +#define PM_PWR_STA_REG PMU_MEM_MAP(0x010) +#define PM_CLK_CTRL_REG PMU_MEM_MAP(0x014) +#define PM_PLL_LCD_I2S_CTRL_REG PMU_MEM_MAP(0x018) +#define PM_PLL_HM_PD_CTRL_REG PMU_MEM_MAP(0x01C) +#define PM_REGULAT_CTRL_REG PMU_MEM_MAP(0x020) +#define PM_WDT_CTRL_REG PMU_MEM_MAP(0x024) +#define PM_WU_CTRL0_REG PMU_MEM_MAP(0x028) +#define PM_WU_CTRL1_REG PMU_MEM_MAP(0x02C) +#define PM_CSR_REG PMU_MEM_MAP(0x030) + +/* PM_CLK_GATE_REG */ +#define PM_CLK_GATE_REG_OFFSET_SDIO (25) +#define PM_CLK_GATE_REG_OFFSET_GPU (24) +#define PM_CLK_GATE_REG_OFFSET_CIM (23) +#define PM_CLK_GATE_REG_OFFSET_LCDC (22) +#define PM_CLK_GATE_REG_OFFSET_I2S (21) +#define PM_CLK_GATE_REG_OFFSET_RAID (20) +#define PM_CLK_GATE_REG_OFFSET_SATA (19) +#define PM_CLK_GATE_REG_OFFSET_PCIE(x) (17 + (x)) +#define PM_CLK_GATE_REG_OFFSET_USB_HOST (16) +#define PM_CLK_GATE_REG_OFFSET_USB_OTG (15) +#define PM_CLK_GATE_REG_OFFSET_TIMER (14) +#define PM_CLK_GATE_REG_OFFSET_CRYPTO (13) +#define PM_CLK_GATE_REG_OFFSET_HCIE (12) +#define PM_CLK_GATE_REG_OFFSET_SWITCH (11) +#define PM_CLK_GATE_REG_OFFSET_GPIO (10) +#define PM_CLK_GATE_REG_OFFSET_UART3 (9) +#define PM_CLK_GATE_REG_OFFSET_UART2 (8) +#define PM_CLK_GATE_REG_OFFSET_UART1 (7) +#define PM_CLK_GATE_REG_OFFSET_RTC (5) +#define PM_CLK_GATE_REG_OFFSET_GDMA (4) +#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C (3) +#define PM_CLK_GATE_REG_OFFSET_SMC_NFI (1) +#define PM_CLK_GATE_REG_MASK (0x03FFFFBA) + +/* PM_SOFT_RST_REG */ +#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG (31) +#define PM_SOFT_RST_REG_OFFST_CPU1 (29) +#define PM_SOFT_RST_REG_OFFST_CPU0 (28) +#define PM_SOFT_RST_REG_OFFST_SDIO (25) +#define PM_SOFT_RST_REG_OFFST_GPU (24) +#define PM_SOFT_RST_REG_OFFST_CIM (23) +#define PM_SOFT_RST_REG_OFFST_LCDC (22) +#define PM_SOFT_RST_REG_OFFST_I2S (21) +#define PM_SOFT_RST_REG_OFFST_RAID (20) +#define PM_SOFT_RST_REG_OFFST_SATA (19) +#define PM_SOFT_RST_REG_OFFST_PCIE(x) (17 + (x)) +#define PM_SOFT_RST_REG_OFFST_USB_HOST (16) +#define PM_SOFT_RST_REG_OFFST_USB_OTG (15) +#define PM_SOFT_RST_REG_OFFST_TIMER (14) +#define PM_SOFT_RST_REG_OFFST_CRYPTO (13) +#define PM_SOFT_RST_REG_OFFST_HCIE (12) +#define PM_SOFT_RST_REG_OFFST_SWITCH (11) +#define PM_SOFT_RST_REG_OFFST_GPIO (10) +#define PM_SOFT_RST_REG_OFFST_UART3 (9) +#define PM_SOFT_RST_REG_OFFST_UART2 (8) +#define PM_SOFT_RST_REG_OFFST_UART1 (7) +#define PM_SOFT_RST_REG_OFFST_RTC (5) +#define PM_SOFT_RST_REG_OFFST_GDMA (4) +#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C (3) +#define PM_SOFT_RST_REG_OFFST_DMC (2) +#define PM_SOFT_RST_REG_OFFST_SMC_NFI (1) +#define PM_SOFT_RST_REG_OFFST_GLOBAL (0) +#define PM_SOFT_RST_REG_MASK (0xF3FFFFBF) + +/* PMHS_CFG_REG */ +#define PM_HS_CFG_REG_OFFSET_SDIO (25) +#define PM_HS_CFG_REG_OFFSET_GPU (24) +#define PM_HS_CFG_REG_OFFSET_CIM (23) +#define PM_HS_CFG_REG_OFFSET_LCDC (22) +#define PM_HS_CFG_REG_OFFSET_I2S (21) +#define PM_HS_CFG_REG_OFFSET_RAID (20) +#define PM_HS_CFG_REG_OFFSET_SATA (19) +#define PM_HS_CFG_REG_OFFSET_PCIE1 (18) +#define PM_HS_CFG_REG_OFFSET_PCIE0 (17) +#define PM_HS_CFG_REG_OFFSET_USB_HOST (16) +#define PM_HS_CFG_REG_OFFSET_USB_OTG (15) +#define PM_HS_CFG_REG_OFFSET_TIMER (14) +#define PM_HS_CFG_REG_OFFSET_CRYPTO (13) +#define PM_HS_CFG_REG_OFFSET_HCIE (12) +#define PM_HS_CFG_REG_OFFSET_SWITCH (11) +#define PM_HS_CFG_REG_OFFSET_GPIO (10) +#define PM_HS_CFG_REG_OFFSET_UART3 (9) +#define PM_HS_CFG_REG_OFFSET_UART2 (8) +#define PM_HS_CFG_REG_OFFSET_UART1 (7) +#define PM_HS_CFG_REG_OFFSET_RTC (5) +#define PM_HS_CFG_REG_OFFSET_GDMA (4) +#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_HS_CFG_REG_OFFSET_DMC (2) +#define PM_HS_CFG_REG_OFFSET_SMC_NFI (1) +#define PM_HS_CFG_REG_MASK (0x03FFFFBE) +#define PM_HS_CFG_REG_MASK_SUPPORT (0x01100806) + +/* PM_CACTIVE_STA_REG */ +#define PM_CACTIVE_STA_REG_OFFSET_SDIO (25) +#define PM_CACTIVE_STA_REG_OFFSET_GPU (24) +#define PM_CACTIVE_STA_REG_OFFSET_CIM (23) +#define PM_CACTIVE_STA_REG_OFFSET_LCDC (22) +#define PM_CACTIVE_STA_REG_OFFSET_I2S (21) +#define PM_CACTIVE_STA_REG_OFFSET_RAID (20) +#define PM_CACTIVE_STA_REG_OFFSET_SATA (19) +#define PM_CACTIVE_STA_REG_OFFSET_PCIE1 (18) +#define PM_CACTIVE_STA_REG_OFFSET_PCIE0 (17) +#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST (16) +#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG (15) +#define PM_CACTIVE_STA_REG_OFFSET_TIMER (14) +#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO (13) +#define PM_CACTIVE_STA_REG_OFFSET_HCIE (12) +#define PM_CACTIVE_STA_REG_OFFSET_SWITCH (11) +#define PM_CACTIVE_STA_REG_OFFSET_GPIO (10) +#define PM_CACTIVE_STA_REG_OFFSET_UART3 (9) +#define PM_CACTIVE_STA_REG_OFFSET_UART2 (8) +#define PM_CACTIVE_STA_REG_OFFSET_UART1 (7) +#define PM_CACTIVE_STA_REG_OFFSET_RTC (5) +#define PM_CACTIVE_STA_REG_OFFSET_GDMA (4) +#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_CACTIVE_STA_REG_OFFSET_DMC (2) +#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI (1) +#define PM_CACTIVE_STA_REG_MASK (0x03FFFFBE) + +/* PM_PWR_STA_REG */ +#define PM_PWR_STA_REG_REG_OFFSET_SDIO (25) +#define PM_PWR_STA_REG_REG_OFFSET_GPU (24) +#define PM_PWR_STA_REG_REG_OFFSET_CIM (23) +#define PM_PWR_STA_REG_REG_OFFSET_LCDC (22) +#define PM_PWR_STA_REG_REG_OFFSET_I2S (21) +#define PM_PWR_STA_REG_REG_OFFSET_RAID (20) +#define PM_PWR_STA_REG_REG_OFFSET_SATA (19) +#define PM_PWR_STA_REG_REG_OFFSET_PCIE1 (18) +#define PM_PWR_STA_REG_REG_OFFSET_PCIE0 (17) +#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST (16) +#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG (15) +#define PM_PWR_STA_REG_REG_OFFSET_TIMER (14) +#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO (13) +#define PM_PWR_STA_REG_REG_OFFSET_HCIE (12) +#define PM_PWR_STA_REG_REG_OFFSET_SWITCH (11) +#define PM_PWR_STA_REG_REG_OFFSET_GPIO (10) +#define PM_PWR_STA_REG_REG_OFFSET_UART3 (9) +#define PM_PWR_STA_REG_REG_OFFSET_UART2 (8) +#define PM_PWR_STA_REG_REG_OFFSET_UART1 (7) +#define PM_PWR_STA_REG_REG_OFFSET_RTC (5) +#define PM_PWR_STA_REG_REG_OFFSET_GDMA (4) +#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_PWR_STA_REG_REG_OFFSET_DMC (2) +#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI (1) +#define PM_PWR_STA_REG_REG_MASK (0x03FFFFBE) + +/* PM_CLK_CTRL_REG */ +#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK (31) +#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN (30) +#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN (29) +#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN (28) +#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE (27) +#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV (24) +#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL (22) +#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV (20) +#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL (16) +#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV (14) +#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL (12) +#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE (9) +#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL (7) +#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE (6) +#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV (4) +#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL (0) + +#define PM_CPU_CLK_DIV(DIV) { \ + PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ + PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ +} + +#define PM_PLL_CPU_SEL(CPU) { \ + PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ + PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ +} + +/* PM_PLL_LCD_I2S_CTRL_REG */ +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV (22) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL (17) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P (11) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M (3) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S (0) + +/* PM_PLL_HM_PD_CTRL_REG */ +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1 (11) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0 (10) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD (6) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S (5) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD (4) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB (3) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII (2) +#define PM_PLL_HM_PD_CTRL_REG_MASK (0x00000C7C) + +/* PM_WDT_CTRL_REG */ +#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY (0) + +/* PM_CSR_REG - Clock Scaling Register*/ +#define PM_CSR_REG_OFFSET_CSR_EN (30) +#define PM_CSR_REG_OFFSET_CSR_NUM (0) + +#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1< #include #include -#include +#include "cns3xxx.h" #include "core.h" static struct map_desc cns3xxx_io_desc[] __initdata = { diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c index 1e40c99b015f..7da78a2451f1 100644 --- a/arch/arm/mach-cns3xxx/devices.c +++ b/arch/arm/mach-cns3xxx/devices.c @@ -16,9 +16,8 @@ #include #include #include -#include -#include -#include +#include "cns3xxx.h" +#include "pm.h" #include "core.h" #include "devices.h" diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h deleted file mode 100644 index 191c8e57f289..000000000000 --- a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright 2008 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. - */ - -#ifndef __MACH_BOARD_CNS3XXXH -#define __MACH_BOARD_CNS3XXXH - -/* - * Memory map - */ -#define CNS3XXX_FLASH_BASE 0x10000000 /* Flash/SRAM Memory Bank 0 */ -#define CNS3XXX_FLASH_SIZE SZ_256M - -#define CNS3XXX_DDR2SDRAM_BASE 0x20000000 /* DDR2 SDRAM Memory */ - -#define CNS3XXX_SPI_FLASH_BASE 0x60000000 /* SPI Serial Flash Memory */ - -#define CNS3XXX_SWITCH_BASE 0x70000000 /* Switch and HNAT Control */ -#define CNS3XXX_SWITCH_BASE_VIRT 0xFFF00000 - -#define CNS3XXX_PPE_BASE 0x70001000 /* HANT */ -#define CNS3XXX_PPE_BASE_VIRT 0xFFF50000 - -#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */ -#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT 0xFFF60000 - -#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */ -#define CNS3XXX_SSP_BASE_VIRT 0xFFF01000 - -#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */ -#define CNS3XXX_DMC_BASE_VIRT 0xFFF02000 - -#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */ -#define CNS3XXX_SMC_BASE_VIRT 0xFFF03000 - -#define SMC_MEMC_STATUS_OFFSET 0x000 -#define SMC_MEMIF_CFG_OFFSET 0x004 -#define SMC_MEMC_CFG_SET_OFFSET 0x008 -#define SMC_MEMC_CFG_CLR_OFFSET 0x00C -#define SMC_DIRECT_CMD_OFFSET 0x010 -#define SMC_SET_CYCLES_OFFSET 0x014 -#define SMC_SET_OPMODE_OFFSET 0x018 -#define SMC_REFRESH_PERIOD_0_OFFSET 0x020 -#define SMC_REFRESH_PERIOD_1_OFFSET 0x024 -#define SMC_SRAM_CYCLES0_0_OFFSET 0x100 -#define SMC_NAND_CYCLES0_0_OFFSET 0x100 -#define SMC_OPMODE0_0_OFFSET 0x104 -#define SMC_SRAM_CYCLES0_1_OFFSET 0x120 -#define SMC_NAND_CYCLES0_1_OFFSET 0x120 -#define SMC_OPMODE0_1_OFFSET 0x124 -#define SMC_USER_STATUS_OFFSET 0x200 -#define SMC_USER_CONFIG_OFFSET 0x204 -#define SMC_ECC_STATUS_OFFSET 0x300 -#define SMC_ECC_MEMCFG_OFFSET 0x304 -#define SMC_ECC_MEMCOMMAND1_OFFSET 0x308 -#define SMC_ECC_MEMCOMMAND2_OFFSET 0x30C -#define SMC_ECC_ADDR0_OFFSET 0x310 -#define SMC_ECC_ADDR1_OFFSET 0x314 -#define SMC_ECC_VALUE0_OFFSET 0x318 -#define SMC_ECC_VALUE1_OFFSET 0x31C -#define SMC_ECC_VALUE2_OFFSET 0x320 -#define SMC_ECC_VALUE3_OFFSET 0x324 -#define SMC_PERIPH_ID_0_OFFSET 0xFE0 -#define SMC_PERIPH_ID_1_OFFSET 0xFE4 -#define SMC_PERIPH_ID_2_OFFSET 0xFE8 -#define SMC_PERIPH_ID_3_OFFSET 0xFEC -#define SMC_PCELL_ID_0_OFFSET 0xFF0 -#define SMC_PCELL_ID_1_OFFSET 0xFF4 -#define SMC_PCELL_ID_2_OFFSET 0xFF8 -#define SMC_PCELL_ID_3_OFFSET 0xFFC - -#define CNS3XXX_GPIOA_BASE 0x74000000 /* GPIO port A */ -#define CNS3XXX_GPIOA_BASE_VIRT 0xFFF04000 - -#define CNS3XXX_GPIOB_BASE 0x74800000 /* GPIO port B */ -#define CNS3XXX_GPIOB_BASE_VIRT 0xFFF05000 - -#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */ -#define CNS3XXX_RTC_BASE_VIRT 0xFFF06000 - -#define RTC_SEC_OFFSET 0x00 -#define RTC_MIN_OFFSET 0x04 -#define RTC_HOUR_OFFSET 0x08 -#define RTC_DAY_OFFSET 0x0C -#define RTC_SEC_ALM_OFFSET 0x10 -#define RTC_MIN_ALM_OFFSET 0x14 -#define RTC_HOUR_ALM_OFFSET 0x18 -#define RTC_REC_OFFSET 0x1C -#define RTC_CTRL_OFFSET 0x20 -#define RTC_INTR_STS_OFFSET 0x34 - -#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ -#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ - -#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ -#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 - -#define PM_CLK_GATE_OFFSET 0x00 -#define PM_SOFT_RST_OFFSET 0x04 -#define PM_HS_CFG_OFFSET 0x08 -#define PM_CACTIVE_STA_OFFSET 0x0C -#define PM_PWR_STA_OFFSET 0x10 -#define PM_SYS_CLK_CTRL_OFFSET 0x14 -#define PM_PLL_LCD_I2S_CTRL_OFFSET 0x18 -#define PM_PLL_HM_PD_OFFSET 0x1C - -#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ -#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 - -#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ -#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 - -#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */ -#define CNS3XXX_UART2_BASE_VIRT 0xFFF0B000 - -#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */ -#define CNS3XXX_DMAC_BASE_VIRT 0xFFF0D000 - -#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */ -#define CNS3XXX_CORESIGHT_BASE_VIRT 0xFFF0E000 - -#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */ -#define CNS3XXX_CRYPTO_BASE_VIRT 0xFFF0F000 - -#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */ -#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 - -#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ -#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 - -#define TIMER1_COUNTER_OFFSET 0x00 -#define TIMER1_AUTO_RELOAD_OFFSET 0x04 -#define TIMER1_MATCH_V1_OFFSET 0x08 -#define TIMER1_MATCH_V2_OFFSET 0x0C - -#define TIMER2_COUNTER_OFFSET 0x10 -#define TIMER2_AUTO_RELOAD_OFFSET 0x14 -#define TIMER2_MATCH_V1_OFFSET 0x18 -#define TIMER2_MATCH_V2_OFFSET 0x1C - -#define TIMER1_2_CONTROL_OFFSET 0x30 -#define TIMER1_2_INTERRUPT_STATUS_OFFSET 0x34 -#define TIMER1_2_INTERRUPT_MASK_OFFSET 0x38 - -#define TIMER_FREERUN_OFFSET 0x40 -#define TIMER_FREERUN_CONTROL_OFFSET 0x44 - -#define CNS3XXX_HCIE_BASE 0x7D000000 /* HCIE Control */ -#define CNS3XXX_HCIE_BASE_VIRT 0xFFF30000 - -#define CNS3XXX_RAID_BASE 0x7E000000 /* RAID Control */ -#define CNS3XXX_RAID_BASE_VIRT 0xFFF12000 - -#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */ -#define CNS3XXX_AXI_IXC_BASE_VIRT 0xFFF13000 - -#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */ -#define CNS3XXX_CLCD_BASE_VIRT 0xFFF14000 - -#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */ -#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000 - -#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */ - -#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */ -#define CNS3XXX_SATA2_SIZE SZ_16M -#define CNS3XXX_SATA2_BASE_VIRT 0xFFF17000 - -#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */ -#define CNS3XXX_CAMERA_BASE_VIRT 0xFFF18000 - -#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */ -#define CNS3XXX_SDIO_BASE_VIRT 0xFFF19000 - -#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */ -#define CNS3XXX_I2S_TDM_BASE_VIRT 0xFFF1A000 - -#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */ -#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000 - -#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */ - -#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ -#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000 - -#define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */ -#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000 - -#define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */ -#define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000 - -#define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */ -#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000 - -#define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */ -#define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000 - -#define CNS3XXX_PCIE0_CFG1_BASE 0xAE000000 /* PCIe Port 0 CFG Type 1 */ -#define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000 - -#define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */ -#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000 - -#define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */ -#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000 - -#define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */ -#define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000 - -#define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */ -#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000 - -#define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */ -#define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000 - -#define CNS3XXX_PCIE1_CFG1_BASE 0xBE000000 /* PCIe Port 1 CFG Type 1 */ -#define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000 - -#define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */ -#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000 - -/* - * Testchip peripheral and fpga gic regions - */ -#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ -#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 - -#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ -#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 - -#define CNS3XXX_TC11MP_TWD_BASE 0x90000600 -#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 - -#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ -#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 - -#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ -#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 - -/* - * Misc block - */ -#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs)) - -#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP(0x00) -#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP(0x04) -#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP(0x08) -#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP(0x0C) -#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP(0x10) -#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP(0x14) -#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP(0x18) -#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP(0x1C) -#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP(0x20) -#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x24) -#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x28) -#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x2C) -#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x30) -#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP(0x34) -#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP(0x40) -#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP(0x44) -#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP(0x48) -#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP(0x4C) -#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP(0x50) -#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP(0x54) - -#define MISC_SATA_POWER_MODE MISC_MEM_MAP(0x310) - -#define MISC_USB_CFG_REG MISC_MEM_MAP(0x800) -#define MISC_USB_STS_REG MISC_MEM_MAP(0x804) -#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP(0x808) -#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP(0x80c) -#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP(0x810) -#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP(0x814) - -#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004) -#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100) -#define MISC_PCIE_AXIS_AWMISC(x) MISC_MEM_MAP(0x944 + (x) * 0x100) -#define MISC_PCIE_AXIS_ARMISC(x) MISC_MEM_MAP(0x948 + (x) * 0x100) -#define MISC_PCIE_AXIS_RMISC(x) MISC_MEM_MAP(0x94C + (x) * 0x100) -#define MISC_PCIE_AXIS_BMISC(x) MISC_MEM_MAP(0x950 + (x) * 0x100) -#define MISC_PCIE_AXIM_RMISC(x) MISC_MEM_MAP(0x954 + (x) * 0x100) -#define MISC_PCIE_AXIM_BMISC(x) MISC_MEM_MAP(0x958 + (x) * 0x100) -#define MISC_PCIE_CTRL(x) MISC_MEM_MAP(0x95C + (x) * 0x100) -#define MISC_PCIE_PM_DEBUG(x) MISC_MEM_MAP(0x960 + (x) * 0x100) -#define MISC_PCIE_RFC_DEBUG(x) MISC_MEM_MAP(0x964 + (x) * 0x100) -#define MISC_PCIE_CXPL_DEBUGL(x) MISC_MEM_MAP(0x968 + (x) * 0x100) -#define MISC_PCIE_CXPL_DEBUGH(x) MISC_MEM_MAP(0x96C + (x) * 0x100) -#define MISC_PCIE_DIAG_DEBUGH(x) MISC_MEM_MAP(0x970 + (x) * 0x100) -#define MISC_PCIE_W1CLR(x) MISC_MEM_MAP(0x974 + (x) * 0x100) -#define MISC_PCIE_INT_MASK(x) MISC_MEM_MAP(0x978 + (x) * 0x100) -#define MISC_PCIE_INT_STATUS(x) MISC_MEM_MAP(0x97C + (x) * 0x100) - -/* - * Power management and clock control - */ -#define PMU_MEM_MAP(offs) (void __iomem *)(CNS3XXX_PM_BASE_VIRT + (offs)) - -#define PM_CLK_GATE_REG PMU_MEM_MAP(0x000) -#define PM_SOFT_RST_REG PMU_MEM_MAP(0x004) -#define PM_HS_CFG_REG PMU_MEM_MAP(0x008) -#define PM_CACTIVE_STA_REG PMU_MEM_MAP(0x00C) -#define PM_PWR_STA_REG PMU_MEM_MAP(0x010) -#define PM_CLK_CTRL_REG PMU_MEM_MAP(0x014) -#define PM_PLL_LCD_I2S_CTRL_REG PMU_MEM_MAP(0x018) -#define PM_PLL_HM_PD_CTRL_REG PMU_MEM_MAP(0x01C) -#define PM_REGULAT_CTRL_REG PMU_MEM_MAP(0x020) -#define PM_WDT_CTRL_REG PMU_MEM_MAP(0x024) -#define PM_WU_CTRL0_REG PMU_MEM_MAP(0x028) -#define PM_WU_CTRL1_REG PMU_MEM_MAP(0x02C) -#define PM_CSR_REG PMU_MEM_MAP(0x030) - -/* PM_CLK_GATE_REG */ -#define PM_CLK_GATE_REG_OFFSET_SDIO (25) -#define PM_CLK_GATE_REG_OFFSET_GPU (24) -#define PM_CLK_GATE_REG_OFFSET_CIM (23) -#define PM_CLK_GATE_REG_OFFSET_LCDC (22) -#define PM_CLK_GATE_REG_OFFSET_I2S (21) -#define PM_CLK_GATE_REG_OFFSET_RAID (20) -#define PM_CLK_GATE_REG_OFFSET_SATA (19) -#define PM_CLK_GATE_REG_OFFSET_PCIE(x) (17 + (x)) -#define PM_CLK_GATE_REG_OFFSET_USB_HOST (16) -#define PM_CLK_GATE_REG_OFFSET_USB_OTG (15) -#define PM_CLK_GATE_REG_OFFSET_TIMER (14) -#define PM_CLK_GATE_REG_OFFSET_CRYPTO (13) -#define PM_CLK_GATE_REG_OFFSET_HCIE (12) -#define PM_CLK_GATE_REG_OFFSET_SWITCH (11) -#define PM_CLK_GATE_REG_OFFSET_GPIO (10) -#define PM_CLK_GATE_REG_OFFSET_UART3 (9) -#define PM_CLK_GATE_REG_OFFSET_UART2 (8) -#define PM_CLK_GATE_REG_OFFSET_UART1 (7) -#define PM_CLK_GATE_REG_OFFSET_RTC (5) -#define PM_CLK_GATE_REG_OFFSET_GDMA (4) -#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C (3) -#define PM_CLK_GATE_REG_OFFSET_SMC_NFI (1) -#define PM_CLK_GATE_REG_MASK (0x03FFFFBA) - -/* PM_SOFT_RST_REG */ -#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG (31) -#define PM_SOFT_RST_REG_OFFST_CPU1 (29) -#define PM_SOFT_RST_REG_OFFST_CPU0 (28) -#define PM_SOFT_RST_REG_OFFST_SDIO (25) -#define PM_SOFT_RST_REG_OFFST_GPU (24) -#define PM_SOFT_RST_REG_OFFST_CIM (23) -#define PM_SOFT_RST_REG_OFFST_LCDC (22) -#define PM_SOFT_RST_REG_OFFST_I2S (21) -#define PM_SOFT_RST_REG_OFFST_RAID (20) -#define PM_SOFT_RST_REG_OFFST_SATA (19) -#define PM_SOFT_RST_REG_OFFST_PCIE(x) (17 + (x)) -#define PM_SOFT_RST_REG_OFFST_USB_HOST (16) -#define PM_SOFT_RST_REG_OFFST_USB_OTG (15) -#define PM_SOFT_RST_REG_OFFST_TIMER (14) -#define PM_SOFT_RST_REG_OFFST_CRYPTO (13) -#define PM_SOFT_RST_REG_OFFST_HCIE (12) -#define PM_SOFT_RST_REG_OFFST_SWITCH (11) -#define PM_SOFT_RST_REG_OFFST_GPIO (10) -#define PM_SOFT_RST_REG_OFFST_UART3 (9) -#define PM_SOFT_RST_REG_OFFST_UART2 (8) -#define PM_SOFT_RST_REG_OFFST_UART1 (7) -#define PM_SOFT_RST_REG_OFFST_RTC (5) -#define PM_SOFT_RST_REG_OFFST_GDMA (4) -#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C (3) -#define PM_SOFT_RST_REG_OFFST_DMC (2) -#define PM_SOFT_RST_REG_OFFST_SMC_NFI (1) -#define PM_SOFT_RST_REG_OFFST_GLOBAL (0) -#define PM_SOFT_RST_REG_MASK (0xF3FFFFBF) - -/* PMHS_CFG_REG */ -#define PM_HS_CFG_REG_OFFSET_SDIO (25) -#define PM_HS_CFG_REG_OFFSET_GPU (24) -#define PM_HS_CFG_REG_OFFSET_CIM (23) -#define PM_HS_CFG_REG_OFFSET_LCDC (22) -#define PM_HS_CFG_REG_OFFSET_I2S (21) -#define PM_HS_CFG_REG_OFFSET_RAID (20) -#define PM_HS_CFG_REG_OFFSET_SATA (19) -#define PM_HS_CFG_REG_OFFSET_PCIE1 (18) -#define PM_HS_CFG_REG_OFFSET_PCIE0 (17) -#define PM_HS_CFG_REG_OFFSET_USB_HOST (16) -#define PM_HS_CFG_REG_OFFSET_USB_OTG (15) -#define PM_HS_CFG_REG_OFFSET_TIMER (14) -#define PM_HS_CFG_REG_OFFSET_CRYPTO (13) -#define PM_HS_CFG_REG_OFFSET_HCIE (12) -#define PM_HS_CFG_REG_OFFSET_SWITCH (11) -#define PM_HS_CFG_REG_OFFSET_GPIO (10) -#define PM_HS_CFG_REG_OFFSET_UART3 (9) -#define PM_HS_CFG_REG_OFFSET_UART2 (8) -#define PM_HS_CFG_REG_OFFSET_UART1 (7) -#define PM_HS_CFG_REG_OFFSET_RTC (5) -#define PM_HS_CFG_REG_OFFSET_GDMA (4) -#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S (3) -#define PM_HS_CFG_REG_OFFSET_DMC (2) -#define PM_HS_CFG_REG_OFFSET_SMC_NFI (1) -#define PM_HS_CFG_REG_MASK (0x03FFFFBE) -#define PM_HS_CFG_REG_MASK_SUPPORT (0x01100806) - -/* PM_CACTIVE_STA_REG */ -#define PM_CACTIVE_STA_REG_OFFSET_SDIO (25) -#define PM_CACTIVE_STA_REG_OFFSET_GPU (24) -#define PM_CACTIVE_STA_REG_OFFSET_CIM (23) -#define PM_CACTIVE_STA_REG_OFFSET_LCDC (22) -#define PM_CACTIVE_STA_REG_OFFSET_I2S (21) -#define PM_CACTIVE_STA_REG_OFFSET_RAID (20) -#define PM_CACTIVE_STA_REG_OFFSET_SATA (19) -#define PM_CACTIVE_STA_REG_OFFSET_PCIE1 (18) -#define PM_CACTIVE_STA_REG_OFFSET_PCIE0 (17) -#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST (16) -#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG (15) -#define PM_CACTIVE_STA_REG_OFFSET_TIMER (14) -#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO (13) -#define PM_CACTIVE_STA_REG_OFFSET_HCIE (12) -#define PM_CACTIVE_STA_REG_OFFSET_SWITCH (11) -#define PM_CACTIVE_STA_REG_OFFSET_GPIO (10) -#define PM_CACTIVE_STA_REG_OFFSET_UART3 (9) -#define PM_CACTIVE_STA_REG_OFFSET_UART2 (8) -#define PM_CACTIVE_STA_REG_OFFSET_UART1 (7) -#define PM_CACTIVE_STA_REG_OFFSET_RTC (5) -#define PM_CACTIVE_STA_REG_OFFSET_GDMA (4) -#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S (3) -#define PM_CACTIVE_STA_REG_OFFSET_DMC (2) -#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI (1) -#define PM_CACTIVE_STA_REG_MASK (0x03FFFFBE) - -/* PM_PWR_STA_REG */ -#define PM_PWR_STA_REG_REG_OFFSET_SDIO (25) -#define PM_PWR_STA_REG_REG_OFFSET_GPU (24) -#define PM_PWR_STA_REG_REG_OFFSET_CIM (23) -#define PM_PWR_STA_REG_REG_OFFSET_LCDC (22) -#define PM_PWR_STA_REG_REG_OFFSET_I2S (21) -#define PM_PWR_STA_REG_REG_OFFSET_RAID (20) -#define PM_PWR_STA_REG_REG_OFFSET_SATA (19) -#define PM_PWR_STA_REG_REG_OFFSET_PCIE1 (18) -#define PM_PWR_STA_REG_REG_OFFSET_PCIE0 (17) -#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST (16) -#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG (15) -#define PM_PWR_STA_REG_REG_OFFSET_TIMER (14) -#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO (13) -#define PM_PWR_STA_REG_REG_OFFSET_HCIE (12) -#define PM_PWR_STA_REG_REG_OFFSET_SWITCH (11) -#define PM_PWR_STA_REG_REG_OFFSET_GPIO (10) -#define PM_PWR_STA_REG_REG_OFFSET_UART3 (9) -#define PM_PWR_STA_REG_REG_OFFSET_UART2 (8) -#define PM_PWR_STA_REG_REG_OFFSET_UART1 (7) -#define PM_PWR_STA_REG_REG_OFFSET_RTC (5) -#define PM_PWR_STA_REG_REG_OFFSET_GDMA (4) -#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S (3) -#define PM_PWR_STA_REG_REG_OFFSET_DMC (2) -#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI (1) -#define PM_PWR_STA_REG_REG_MASK (0x03FFFFBE) - -/* PM_CLK_CTRL_REG */ -#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK (31) -#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN (30) -#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN (29) -#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN (28) -#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE (27) -#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV (24) -#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL (22) -#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV (20) -#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL (16) -#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV (14) -#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL (12) -#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE (9) -#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL (7) -#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE (6) -#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV (4) -#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL (0) - -#define PM_CPU_CLK_DIV(DIV) { \ - PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ - PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ -} - -#define PM_PLL_CPU_SEL(CPU) { \ - PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ - PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ -} - -/* PM_PLL_LCD_I2S_CTRL_REG */ -#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV (22) -#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL (17) -#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P (11) -#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M (3) -#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S (0) - -/* PM_PLL_HM_PD_CTRL_REG */ -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1 (11) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0 (10) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD (6) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S (5) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD (4) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB (3) -#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII (2) -#define PM_PLL_HM_PD_CTRL_REG_MASK (0x00000C7C) - -/* PM_WDT_CTRL_REG */ -#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY (0) - -/* PM_CSR_REG - Clock Scaling Register*/ -#define PM_CSR_REG_OFFSET_CSR_EN (30) -#define PM_CSR_REG_OFFSET_CSR_NUM (0) - -#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1< - -void cns3xxx_pwr_clk_en(unsigned int block); -void cns3xxx_pwr_clk_dis(unsigned int block); -void cns3xxx_pwr_power_up(unsigned int block); -void cns3xxx_pwr_power_down(unsigned int block); - -extern atomic_t usb_pwr_ref; - -#endif /* __CNS3XXX_PM_H */ diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h index 7a030b99df84..e2c642c1c66c 100644 --- a/arch/arm/mach-cns3xxx/include/mach/uncompress.h +++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h @@ -8,7 +8,7 @@ */ #include -#include +#include "cns3xxx.h" #define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00)) #define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c)) diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 311328314163..c7b204bff386 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include "cns3xxx.h" #include "core.h" enum cns3xxx_access_type { diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c index 36458080332a..79e3d47aad65 100644 --- a/arch/arm/mach-cns3xxx/pm.c +++ b/arch/arm/mach-cns3xxx/pm.c @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include "cns3xxx.h" +#include "pm.h" #include "core.h" void cns3xxx_pwr_clk_en(unsigned int block) diff --git a/arch/arm/mach-cns3xxx/pm.h b/arch/arm/mach-cns3xxx/pm.h new file mode 100644 index 000000000000..c2588cc991d1 --- /dev/null +++ b/arch/arm/mach-cns3xxx/pm.h @@ -0,0 +1,23 @@ +/* + * Copyright 2000 Deep Blue Solutions Ltd + * Copyright 2004 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + */ + +#ifndef __CNS3XXX_PM_H +#define __CNS3XXX_PM_H + +#include + +void cns3xxx_pwr_clk_en(unsigned int block); +void cns3xxx_pwr_clk_dis(unsigned int block); +void cns3xxx_pwr_power_up(unsigned int block); +void cns3xxx_pwr_power_down(unsigned int block); + +extern atomic_t usb_pwr_ref; + +#endif /* __CNS3XXX_PM_H */ diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index 30bfdc4ae52a..6ba8502c1ee2 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "sdhci-pltfm.h" static unsigned int sdhci_cns3xxx_get_max_clk(struct sdhci_host *host) -- cgit From 157dfaac1f2922a3cbd90685339511cb97cad225 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Thu, 14 Mar 2013 13:12:00 -0700 Subject: staging: dwc2: fix compiler warnings Fix some compiler warnings when building for i386 arch. Reported by Fengguang's build-bot. Signed-off-by: Paul Zimmerman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/hcd.c | 13 +++++++------ drivers/staging/dwc2/hcd_intr.c | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index cdb142dda476..246b483481fa 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -1890,8 +1890,9 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " transfer_buffer: %p\n", urb->buf); - dev_dbg(hsotg->dev, " transfer_dma: %p\n", - (void *)urb->dma); + dev_dbg(hsotg->dev, + " transfer_dma: %08lx\n", + (unsigned long)urb->dma); dev_dbg(hsotg->dev, " transfer_buffer_length: %d\n", urb->length); @@ -2296,10 +2297,10 @@ static void dwc2_dump_urb_info(struct usb_hcd *hcd, struct urb *urb, usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); dev_vdbg(hsotg->dev, " Data buffer length: %d\n", urb->transfer_buffer_length); - dev_vdbg(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %p\n", - urb->transfer_buffer, (void *)urb->transfer_dma); - dev_vdbg(hsotg->dev, " Setup buffer: %p, Setup DMA: %p\n", - urb->setup_packet, (void *)urb->setup_dma); + dev_vdbg(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n", + urb->transfer_buffer, (unsigned long)urb->transfer_dma); + dev_vdbg(hsotg->dev, " Setup buffer: %p, Setup DMA: %08lx\n", + urb->setup_packet, (unsigned long)urb->setup_dma); dev_vdbg(hsotg->dev, " Interval: %d\n", urb->interval); if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { diff --git a/drivers/staging/dwc2/hcd_intr.c b/drivers/staging/dwc2/hcd_intr.c index 01addd0889dc..4b007ab3649b 100644 --- a/drivers/staging/dwc2/hcd_intr.c +++ b/drivers/staging/dwc2/hcd_intr.c @@ -1535,10 +1535,10 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg, dev_err(hsotg->dev, " Max packet size: %d\n", dwc2_hcd_get_mps(&urb->pipe_info)); dev_err(hsotg->dev, " Data buffer length: %d\n", urb->length); - dev_err(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %p\n", - urb->buf, (void *)urb->dma); - dev_err(hsotg->dev, " Setup buffer: %p, Setup DMA: %p\n", - urb->setup_packet, (void *)urb->setup_dma); + dev_err(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n", + urb->buf, (unsigned long)urb->dma); + dev_err(hsotg->dev, " Setup buffer: %p, Setup DMA: %08lx\n", + urb->setup_packet, (unsigned long)urb->setup_dma); dev_err(hsotg->dev, " Interval: %d\n", urb->interval); /* Core halts the channel for Descriptor DMA mode */ -- cgit From 51cfbbb95dfc3b8202b26bd17d975448a477876f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 13 Mar 2013 16:39:35 +1100 Subject: staging: the DWC2 driver uses bus_to_virt Signed-off-by: Stephen Rothwell Acked-by: Paul Zimmerman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/dwc2/Kconfig b/drivers/staging/dwc2/Kconfig index 610418a55fea..bc4cdfee6e0b 100644 --- a/drivers/staging/dwc2/Kconfig +++ b/drivers/staging/dwc2/Kconfig @@ -1,6 +1,7 @@ config USB_DWC2 tristate "DesignWare USB2 DRD Core Support" depends on USB + depends on VIRT_TO_BUS select USB_OTG_UTILS help Say Y or M here if your system has a Dual Role HighSpeed -- cgit From b74e5f560c24929f71af5d08020edd5ec9a64904 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 13 Mar 2013 12:19:20 -0400 Subject: Staging: comedi: Fixed camel case style issue in usbdux.c This is a patch to usbdux.c that fixes the camel case warnings found by the checkpatch.pl tool Signed-off-by: Jacob Garber Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 404 ++++++++++++++++---------------- 1 file changed, 202 insertions(+), 202 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 6f2e42972289..2eac8f0fe7b5 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -250,26 +250,26 @@ struct usbduxsub { /* pointer to the usb-device */ struct usb_device *usbdev; /* actual number of in-buffers */ - int numOfInBuffers; + int num_in_buffers; /* actual number of out-buffers */ - int numOfOutBuffers; + int num_out_buffers; /* ISO-transfer handling: buffers */ - struct urb **urbIn; - struct urb **urbOut; + struct urb **urb_in; + struct urb **urb_out; /* pwm-transfer handling */ - struct urb *urbPwm; + struct urb *urb_pwm; /* PWM period */ - unsigned int pwmPeriod; + unsigned int pwm_period; /* PWM internal delay for the GPIF in the FX2 */ - int8_t pwmDelay; + int8_t pwn_delay; /* size of the PWM buffer which holds the bit pattern */ - int sizePwmBuf; + int size_pwm_buf; /* input buffer for the ISO-transfer */ - int16_t *inBuffer; + int16_t *in_buffer; /* input buffer for single insn */ - int16_t *insnBuffer; + int16_t *insn_buffer; /* output buffer for single DA outputs */ - int16_t *outBuffer; + int16_t *out_buffer; /* interface number */ int ifnum; /* interface structure in 2.6 */ @@ -319,17 +319,17 @@ static DEFINE_SEMAPHORE(start_stop_sem); * Stops the data acquision * It should be safe to call this function from any context */ -static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp) +static int usbduxsub_unlink_inurbs(struct usbduxsub *usbduxsub_tmp) { int i = 0; int err = 0; - if (usbduxsub_tmp && usbduxsub_tmp->urbIn) { - for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) { - if (usbduxsub_tmp->urbIn[i]) { + if (usbduxsub_tmp && usbduxsub_tmp->urb_in) { + for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) { + if (usbduxsub_tmp->urb_in[i]) { /* We wait here until all transfers have been * cancelled. */ - usb_kill_urb(usbduxsub_tmp->urbIn[i]); + usb_kill_urb(usbduxsub_tmp->urb_in[i]); } dev_dbg(&usbduxsub_tmp->interface->dev, "comedi: usbdux: unlinked InURB %d, err=%d\n", @@ -356,7 +356,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink) if (do_unlink) { /* stop aquistion */ - ret = usbduxsub_unlink_InURBs(this_usbduxsub); + ret = usbduxsub_unlink_inurbs(this_usbduxsub); } this_usbduxsub->ai_cmd_running = 0; @@ -394,7 +394,7 @@ static int usbdux_ai_cancel(struct comedi_device *dev, } /* analogue IN - interrupt service routine */ -static void usbduxsub_ai_IsocIrq(struct urb *urb) +static void usbduxsub_ai_isoc_irq(struct urb *urb) { int i, err, n; struct usbduxsub *this_usbduxsub; @@ -412,7 +412,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) switch (urb->status) { case 0: /* copy the result in the transfer buffer */ - memcpy(this_usbduxsub->inBuffer, + memcpy(this_usbduxsub->in_buffer, urb->transfer_buffer, SIZEINBUF); break; case -EILSEQ: @@ -517,11 +517,11 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) { err = comedi_buf_put (s->async, - le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800); + le16_to_cpu(this_usbduxsub->in_buffer[i]) ^ 0x800); } else { err = comedi_buf_put (s->async, - le16_to_cpu(this_usbduxsub->inBuffer[i])); + le16_to_cpu(this_usbduxsub->in_buffer[i])); } if (unlikely(err == 0)) { /* buffer overflow */ @@ -534,15 +534,15 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) comedi_event(this_usbduxsub->comedidev, s); } -static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp) +static int usbduxsub_unlink_outurbs(struct usbduxsub *usbduxsub_tmp) { int i = 0; int err = 0; - if (usbduxsub_tmp && usbduxsub_tmp->urbOut) { - for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) { - if (usbduxsub_tmp->urbOut[i]) - usb_kill_urb(usbduxsub_tmp->urbOut[i]); + if (usbduxsub_tmp && usbduxsub_tmp->urb_out) { + for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) { + if (usbduxsub_tmp->urb_out[i]) + usb_kill_urb(usbduxsub_tmp->urb_out[i]); dev_dbg(&usbduxsub_tmp->interface->dev, "comedi: usbdux: unlinked OutURB %d: res=%d\n", @@ -564,7 +564,7 @@ static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink) dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n"); if (do_unlink) - ret = usbduxsub_unlink_OutURBs(this_usbduxsub); + ret = usbduxsub_unlink_outurbs(this_usbduxsub); this_usbduxsub->ao_cmd_running = 0; @@ -593,7 +593,7 @@ static int usbdux_ao_cancel(struct comedi_device *dev, return res; } -static void usbduxsub_ao_IsocIrq(struct urb *urb) +static void usbduxsub_ao_isoc_irq(struct urb *urb) { int i, ret; int8_t *datap; @@ -791,7 +791,7 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) static int usbduxsub_upload(struct usbduxsub *usbduxsub, uint8_t *local_transfer_buffer, - unsigned int startAddr, unsigned int len) + unsigned int start_addr, unsigned int len) { int errcode; @@ -802,7 +802,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub, /* bmRequestType */ VENDOR_DIR_OUT, /* value */ - startAddr, + start_addr, /* index */ 0x0000, /* our local safe buffer */ @@ -821,24 +821,24 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub, #define FIRMWARE_MAX_LEN 0x2000 -static int firmwareUpload(struct usbduxsub *usbduxsub, - const u8 *firmwareBinary, int sizeFirmware) +static int firmware_upload(struct usbduxsub *usbduxsub, + const u8 *firmware_binary, int size_firmware) { int ret; - uint8_t *fwBuf; + uint8_t *fw_buf; - if (!firmwareBinary) + if (!firmware_binary) return 0; - if (sizeFirmware > FIRMWARE_MAX_LEN) { + if (size_firmware > FIRMWARE_MAX_LEN) { dev_err(&usbduxsub->interface->dev, "usbdux firmware binary it too large for FX2.\n"); return -ENOMEM; } /* we generate a local buffer for the firmware */ - fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL); - if (!fwBuf) { + fw_buf = kmemdup(firmware_binary, size_firmware, GFP_KERNEL); + if (!fw_buf) { dev_err(&usbduxsub->interface->dev, "comedi_: mem alloc for firmware failed\n"); return -ENOMEM; @@ -848,81 +848,81 @@ static int firmwareUpload(struct usbduxsub *usbduxsub, if (ret < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: can not stop firmware\n"); - kfree(fwBuf); + kfree(fw_buf); return ret; } - ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware); + ret = usbduxsub_upload(usbduxsub, fw_buf, 0, size_firmware); if (ret < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: firmware upload failed\n"); - kfree(fwBuf); + kfree(fw_buf); return ret; } ret = usbduxsub_start(usbduxsub); if (ret < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: can not start firmware\n"); - kfree(fwBuf); + kfree(fw_buf); return ret; } - kfree(fwBuf); + kfree(fw_buf); return 0; } -static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub) +static int usbduxsub_submit_inurbs(struct usbduxsub *usbduxsub) { - int i, errFlag; + int i, err_flag; if (!usbduxsub) return -EFAULT; /* Submit all URBs and start the transfer on the bus */ - for (i = 0; i < usbduxsub->numOfInBuffers; i++) { + for (i = 0; i < usbduxsub->num_in_buffers; i++) { /* in case of a resubmission after an unlink... */ - usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval; - usbduxsub->urbIn[i]->context = usbduxsub->comedidev; - usbduxsub->urbIn[i]->dev = usbduxsub->usbdev; - usbduxsub->urbIn[i]->status = 0; - usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP; + usbduxsub->urb_in[i]->interval = usbduxsub->ai_interval; + usbduxsub->urb_in[i]->context = usbduxsub->comedidev; + usbduxsub->urb_in[i]->dev = usbduxsub->usbdev; + usbduxsub->urb_in[i]->status = 0; + usbduxsub->urb_in[i]->transfer_flags = URB_ISO_ASAP; dev_dbg(&usbduxsub->interface->dev, "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n", usbduxsub->comedidev->minor, i, - (usbduxsub->urbIn[i]->context), - (usbduxsub->urbIn[i]->dev), - (usbduxsub->urbIn[i]->interval)); - errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC); - if (errFlag) { + (usbduxsub->urb_in[i]->context), + (usbduxsub->urb_in[i]->dev), + (usbduxsub->urb_in[i]->interval)); + err_flag = usb_submit_urb(usbduxsub->urb_in[i], GFP_ATOMIC); + if (err_flag) { dev_err(&usbduxsub->interface->dev, "comedi_: ai: usb_submit_urb(%d) error %d\n", - i, errFlag); - return errFlag; + i, err_flag); + return err_flag; } } return 0; } -static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub) +static int usbduxsub_submit_outurbs(struct usbduxsub *usbduxsub) { - int i, errFlag; + int i, err_flag; if (!usbduxsub) return -EFAULT; - for (i = 0; i < usbduxsub->numOfOutBuffers; i++) { + for (i = 0; i < usbduxsub->num_out_buffers; i++) { dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting out-urb[%d]\n", i); /* in case of a resubmission after an unlink... */ - usbduxsub->urbOut[i]->context = usbduxsub->comedidev; - usbduxsub->urbOut[i]->dev = usbduxsub->usbdev; - usbduxsub->urbOut[i]->status = 0; - usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP; - errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC); - if (errFlag) { + usbduxsub->urb_out[i]->context = usbduxsub->comedidev; + usbduxsub->urb_out[i]->dev = usbduxsub->usbdev; + usbduxsub->urb_out[i]->status = 0; + usbduxsub->urb_out[i]->transfer_flags = URB_ISO_ASAP; + err_flag = usb_submit_urb(usbduxsub->urb_out[i], GFP_ATOMIC); + if (err_flag) { dev_err(&usbduxsub->interface->dev, "comedi_: ao: usb_submit_urb(%d) error %d\n", - i, errFlag); - return errFlag; + i, err_flag); + return err_flag; } } return 0; @@ -933,7 +933,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, { struct usbduxsub *this_usbduxsub = dev->private; int err = 0, i; - unsigned int tmpTimer; + unsigned int tmp_timer; if (!(this_usbduxsub->probed)) return -ENODEV; @@ -983,7 +983,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, 1000000 / 8 * i); /* now calc the real sampling rate with all the * rounding errors */ - tmpTimer = + tmp_timer = ((unsigned int)(cmd->scan_begin_arg / 125000)) * 125000; } else { @@ -994,11 +994,11 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, /* * calc the real sampling rate with the rounding errors */ - tmpTimer = ((unsigned int)(cmd->scan_begin_arg / + tmp_timer = ((unsigned int)(cmd->scan_begin_arg / 1000000)) * 1000000; } err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, - tmpTimer); + tmp_timer); } err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); @@ -1074,7 +1074,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command) result = usb_bulk_msg(this_usbduxsub->usbdev, usb_rcvbulkpipe(this_usbduxsub->usbdev, COMMAND_IN_EP), - this_usbduxsub->insnBuffer, SIZEINSNBUF, + this_usbduxsub->insn_buffer, SIZEINSNBUF, &nrec, BULK_TIMEOUT); if (result < 0) { dev_err(&this_usbduxsub->interface->dev, "comedi%d: " @@ -1082,7 +1082,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command) "\n", this_usbduxsub->comedidev->minor, result); return result; } - if (le16_to_cpu(this_usbduxsub->insnBuffer[0]) == command) + if (le16_to_cpu(this_usbduxsub->insn_buffer[0]) == command) return result; } /* this is only reached if the data has been requested a couple of @@ -1090,7 +1090,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command) dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: " "wrong data returned from firmware: want cmd %d, got cmd %d.\n", this_usbduxsub->comedidev->minor, command, - le16_to_cpu(this_usbduxsub->insnBuffer[0])); + le16_to_cpu(this_usbduxsub->insn_buffer[0])); return -EFAULT; } @@ -1119,7 +1119,7 @@ static int usbdux_ai_inttrig(struct comedi_device *dev, } if (!(this_usbduxsub->ai_cmd_running)) { this_usbduxsub->ai_cmd_running = 1; - ret = usbduxsub_submit_InURBs(this_usbduxsub); + ret = usbduxsub_submit_inurbs(this_usbduxsub); if (ret < 0) { dev_err(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ai_inttrig: " @@ -1236,7 +1236,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->start_src == TRIG_NOW) { /* enable this acquisition operation */ this_usbduxsub->ai_cmd_running = 1; - ret = usbduxsub_submit_InURBs(this_usbduxsub); + ret = usbduxsub_submit_inurbs(this_usbduxsub); if (ret < 0) { this_usbduxsub->ai_cmd_running = 0; /* fixme: unlink here?? */ @@ -1304,7 +1304,7 @@ static int usbdux_ai_insn_read(struct comedi_device *dev, up(&this_usbduxsub->sem); return 0; } - one = le16_to_cpu(this_usbduxsub->insnBuffer[1]); + one = le16_to_cpu(this_usbduxsub->insn_buffer[1]); if (CR_RANGE(insn->chanspec) <= 1) one = one ^ 0x800; @@ -1334,7 +1334,7 @@ static int usbdux_ao_insn_read(struct comedi_device *dev, return -ENODEV; } for (i = 0; i < insn->n; i++) - data[i] = this_usbduxsub->outBuffer[chan]; + data[i] = this_usbduxsub->out_buffer[chan]; up(&this_usbduxsub->sem); return i; @@ -1377,7 +1377,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev, /* one 16 bit value */ *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(data[i]); - this_usbduxsub->outBuffer[chan] = data[i]; + this_usbduxsub->out_buffer[chan] = data[i]; /* channel number */ this_usbduxsub->dux_commands[4] = (chan << 6); err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS); @@ -1414,7 +1414,7 @@ static int usbdux_ao_inttrig(struct comedi_device *dev, } if (!(this_usbduxsub->ao_cmd_running)) { this_usbduxsub->ao_cmd_running = 1; - ret = usbduxsub_submit_OutURBs(this_usbduxsub); + ret = usbduxsub_submit_outurbs(this_usbduxsub); if (ret < 0) { dev_err(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ao_inttrig: submitURB: " @@ -1609,7 +1609,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->start_src == TRIG_NOW) { /* enable this acquisition operation */ this_usbduxsub->ao_cmd_running = 1; - ret = usbduxsub_submit_OutURBs(this_usbduxsub); + ret = usbduxsub_submit_outurbs(this_usbduxsub); if (ret < 0) { this_usbduxsub->ao_cmd_running = 0; /* fixme: unlink here?? */ @@ -1697,7 +1697,7 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, return err; } - data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]); + data[1] = le16_to_cpu(this_usbduxsub->insn_buffer[1]); up(&this_usbduxsub->sem); return insn->n; } @@ -1733,7 +1733,7 @@ static int usbdux_counter_read(struct comedi_device *dev, return err; } - data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]); + data[0] = le16_to_cpu(this_usbduxsub->insn_buffer[chan + 1]); up(&this_usbduxsub->sem); return 1; } @@ -1780,13 +1780,13 @@ static int usbdux_counter_config(struct comedi_device *dev, /***********************************/ /* PWM */ -static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp) +static int usbduxsub_unlink_pwm_urbs(struct usbduxsub *usbduxsub_tmp) { int err = 0; - if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) { - if (usbduxsub_tmp->urbPwm) - usb_kill_urb(usbduxsub_tmp->urbPwm); + if (usbduxsub_tmp && usbduxsub_tmp->urb_pwm) { + if (usbduxsub_tmp->urb_pwm) + usb_kill_urb(usbduxsub_tmp->urb_pwm); dev_dbg(&usbduxsub_tmp->interface->dev, "comedi: unlinked PwmURB: res=%d\n", err); } @@ -1805,7 +1805,7 @@ static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink) dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__); if (do_unlink) - ret = usbduxsub_unlink_PwmURBs(this_usbduxsub); + ret = usbduxsub_unlink_pwm_urbs(this_usbduxsub); this_usbduxsub->pwm_cmd_running = 0; @@ -1878,7 +1878,7 @@ static void usbduxsub_pwm_irq(struct urb *urb) if (!(this_usbduxsub->pwm_cmd_running)) return; - urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf; + urb->transfer_buffer_length = this_usbduxsub->size_pwm_buf; urb->dev = this_usbduxsub->usbdev; urb->status = 0; if (this_usbduxsub->pwm_cmd_running) { @@ -1898,9 +1898,9 @@ static void usbduxsub_pwm_irq(struct urb *urb) } } -static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub) +static int usbduxsub_submit_pwm_urbs(struct usbduxsub *usbduxsub) { - int errFlag; + int err_flag; if (!usbduxsub) return -EFAULT; @@ -1908,19 +1908,19 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub) dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n"); /* in case of a resubmission after an unlink... */ - usb_fill_bulk_urb(usbduxsub->urbPwm, + usb_fill_bulk_urb(usbduxsub->urb_pwm, usbduxsub->usbdev, usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP), - usbduxsub->urbPwm->transfer_buffer, - usbduxsub->sizePwmBuf, usbduxsub_pwm_irq, + usbduxsub->urb_pwm->transfer_buffer, + usbduxsub->size_pwm_buf, usbduxsub_pwm_irq, usbduxsub->comedidev); - errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC); - if (errFlag) { + err_flag = usb_submit_urb(usbduxsub->urb_pwm, GFP_ATOMIC); + if (err_flag) { dev_err(&usbduxsub->interface->dev, "comedi_: usbdux: pwm: usb_submit_urb error %d\n", - errFlag); - return errFlag; + err_flag); + return err_flag; } return 0; } @@ -1945,8 +1945,8 @@ static int usbdux_pwm_period(struct comedi_device *dev, return -EAGAIN; } } - this_usbduxsub->pwmDelay = fx2delay; - this_usbduxsub->pwmPeriod = period; + this_usbduxsub->pwn_delay = fx2delay; + this_usbduxsub->pwm_period = period; dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n", __func__, period, fx2delay); return 0; @@ -1967,17 +1967,17 @@ static int usbdux_pwm_start(struct comedi_device *dev, return 0; } - this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay); + this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwn_delay); ret = send_dux_commands(this_usbduxsub, SENDPWMON); if (ret < 0) return ret; /* initialise the buffer */ - for (i = 0; i < this_usbduxsub->sizePwmBuf; i++) - ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0; + for (i = 0; i < this_usbduxsub->size_pwm_buf; i++) + ((char *)(this_usbduxsub->urb_pwm->transfer_buffer))[i] = 0; this_usbduxsub->pwm_cmd_running = 1; - ret = usbduxsub_submit_PwmURBs(this_usbduxsub); + ret = usbduxsub_submit_pwm_urbs(this_usbduxsub); if (ret < 0) { this_usbduxsub->pwm_cmd_running = 0; return ret; @@ -1992,7 +1992,7 @@ static int usbdux_pwm_pattern(struct comedi_device *dev, { struct usbduxsub *this_usbduxsub = dev->private; int i, szbuf; - char *pBuf; + char *p_buf; char pwm_mask; char sgn_mask; char c; @@ -2006,10 +2006,10 @@ static int usbdux_pwm_pattern(struct comedi_device *dev, sgn_mask = (16 << channel); /* this is the buffer which will be filled with the with bit */ /* pattern for one period */ - szbuf = this_usbduxsub->sizePwmBuf; - pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer); + szbuf = this_usbduxsub->size_pwm_buf; + p_buf = (char *)(this_usbduxsub->urb_pwm->transfer_buffer); for (i = 0; i < szbuf; i++) { - c = *pBuf; + c = *p_buf; /* reset bits */ c = c & (~pwm_mask); /* set the bit as long as the index is lower than the value */ @@ -2023,7 +2023,7 @@ static int usbdux_pwm_pattern(struct comedi_device *dev, /* negative value */ c = c | sgn_mask; } - *(pBuf++) = c; + *(p_buf++) = c; } return 1; } @@ -2095,7 +2095,7 @@ static int usbdux_pwm_config(struct comedi_device *dev, "comedi%d: %s: setting period\n", dev->minor, __func__); return usbdux_pwm_period(dev, s, data[1]); case INSN_CONFIG_PWM_GET_PERIOD: - data[1] = this_usbduxsub->pwmPeriod; + data[1] = this_usbduxsub->pwm_period; return 0; case INSN_CONFIG_PWM_SET_H_BRIDGE: /* value in the first byte and the sign in the second for a @@ -2131,55 +2131,55 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_tmp->probed = 0; - if (usbduxsub_tmp->urbIn) { + if (usbduxsub_tmp->urb_in) { if (usbduxsub_tmp->ai_cmd_running) { usbduxsub_tmp->ai_cmd_running = 0; - usbduxsub_unlink_InURBs(usbduxsub_tmp); + usbduxsub_unlink_inurbs(usbduxsub_tmp); } - for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) { - kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer); - usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL; - usb_kill_urb(usbduxsub_tmp->urbIn[i]); - usb_free_urb(usbduxsub_tmp->urbIn[i]); - usbduxsub_tmp->urbIn[i] = NULL; + for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) { + kfree(usbduxsub_tmp->urb_in[i]->transfer_buffer); + usbduxsub_tmp->urb_in[i]->transfer_buffer = NULL; + usb_kill_urb(usbduxsub_tmp->urb_in[i]); + usb_free_urb(usbduxsub_tmp->urb_in[i]); + usbduxsub_tmp->urb_in[i] = NULL; } - kfree(usbduxsub_tmp->urbIn); - usbduxsub_tmp->urbIn = NULL; + kfree(usbduxsub_tmp->urb_in); + usbduxsub_tmp->urb_in = NULL; } - if (usbduxsub_tmp->urbOut) { + if (usbduxsub_tmp->urb_out) { if (usbduxsub_tmp->ao_cmd_running) { usbduxsub_tmp->ao_cmd_running = 0; - usbduxsub_unlink_OutURBs(usbduxsub_tmp); + usbduxsub_unlink_outurbs(usbduxsub_tmp); } - for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) { - kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer); - usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL; - if (usbduxsub_tmp->urbOut[i]) { - usb_kill_urb(usbduxsub_tmp->urbOut[i]); - usb_free_urb(usbduxsub_tmp->urbOut[i]); - usbduxsub_tmp->urbOut[i] = NULL; + for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) { + kfree(usbduxsub_tmp->urb_out[i]->transfer_buffer); + usbduxsub_tmp->urb_out[i]->transfer_buffer = NULL; + if (usbduxsub_tmp->urb_out[i]) { + usb_kill_urb(usbduxsub_tmp->urb_out[i]); + usb_free_urb(usbduxsub_tmp->urb_out[i]); + usbduxsub_tmp->urb_out[i] = NULL; } } - kfree(usbduxsub_tmp->urbOut); - usbduxsub_tmp->urbOut = NULL; + kfree(usbduxsub_tmp->urb_out); + usbduxsub_tmp->urb_out = NULL; } - if (usbduxsub_tmp->urbPwm) { + if (usbduxsub_tmp->urb_pwm) { if (usbduxsub_tmp->pwm_cmd_running) { usbduxsub_tmp->pwm_cmd_running = 0; - usbduxsub_unlink_PwmURBs(usbduxsub_tmp); + usbduxsub_unlink_pwm_urbs(usbduxsub_tmp); } - kfree(usbduxsub_tmp->urbPwm->transfer_buffer); - usbduxsub_tmp->urbPwm->transfer_buffer = NULL; - usb_kill_urb(usbduxsub_tmp->urbPwm); - usb_free_urb(usbduxsub_tmp->urbPwm); - usbduxsub_tmp->urbPwm = NULL; - } - kfree(usbduxsub_tmp->inBuffer); - usbduxsub_tmp->inBuffer = NULL; - kfree(usbduxsub_tmp->insnBuffer); - usbduxsub_tmp->insnBuffer = NULL; - kfree(usbduxsub_tmp->outBuffer); - usbduxsub_tmp->outBuffer = NULL; + kfree(usbduxsub_tmp->urb_pwm->transfer_buffer); + usbduxsub_tmp->urb_pwm->transfer_buffer = NULL; + usb_kill_urb(usbduxsub_tmp->urb_pwm); + usb_free_urb(usbduxsub_tmp->urb_pwm); + usbduxsub_tmp->urb_pwm = NULL; + } + kfree(usbduxsub_tmp->in_buffer); + usbduxsub_tmp->in_buffer = NULL; + kfree(usbduxsub_tmp->insn_buffer); + usbduxsub_tmp->insn_buffer = NULL; + kfree(usbduxsub_tmp->out_buffer); + usbduxsub_tmp->out_buffer = NULL; kfree(usbduxsub_tmp->dac_commands); usbduxsub_tmp->dac_commands = NULL; kfree(usbduxsub_tmp->dux_commands); @@ -2302,7 +2302,7 @@ static int usbdux_attach_common(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; s->n_chan = 8; /* this defines the max duty cycle resolution */ - s->maxdata = udev->sizePwmBuf; + s->maxdata = udev->size_pwm_buf; s->insn_write = usbdux_pwm_write; s->insn_read = usbdux_pwm_read; s->insn_config = usbdux_pwm_config; @@ -2381,7 +2381,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, * we need to upload the firmware here because fw will be * freed once we've left this function */ - ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); + ret = firmware_upload(usbduxsub_tmp, fw->data, fw->size); if (ret) { dev_err(&uinterf->dev, @@ -2457,22 +2457,22 @@ static int usbdux_usb_probe(struct usb_interface *uinterf, return -ENOMEM; } /* create space for the in buffer and set it to zero */ - usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL); - if (!(usbduxsub[index].inBuffer)) { + usbduxsub[index].in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL); + if (!(usbduxsub[index].in_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } /* create space of the instruction buffer */ - usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL); - if (!(usbduxsub[index].insnBuffer)) { + usbduxsub[index].insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL); + if (!(usbduxsub[index].insn_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } /* create space for the outbuffer */ - usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); - if (!(usbduxsub[index].outBuffer)) { + usbduxsub[index].out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); + if (!(usbduxsub[index].out_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -2489,124 +2489,124 @@ static int usbdux_usb_probe(struct usb_interface *uinterf, return -ENODEV; } if (usbduxsub[index].high_speed) - usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH; + usbduxsub[index].num_in_buffers = NUMOFINBUFFERSHIGH; else - usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL; + usbduxsub[index].num_in_buffers = NUMOFINBUFFERSFULL; - usbduxsub[index].urbIn = - kcalloc(usbduxsub[index].numOfInBuffers, sizeof(struct urb *), + usbduxsub[index].urb_in = + kcalloc(usbduxsub[index].num_in_buffers, sizeof(struct urb *), GFP_KERNEL); - if (!(usbduxsub[index].urbIn)) { + if (!(usbduxsub[index].urb_in)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) { + for (i = 0; i < usbduxsub[index].num_in_buffers; i++) { /* one frame: 1ms */ - usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL); - if (usbduxsub[index].urbIn[i] == NULL) { + usbduxsub[index].urb_in[i] = usb_alloc_urb(1, GFP_KERNEL); + if (usbduxsub[index].urb_in[i] == NULL) { dev_err(dev, "comedi_: usbdux%d: " "Could not alloc. urb(%d)\n", index, i); tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev; + usbduxsub[index].urb_in[i]->dev = usbduxsub[index].usbdev; /* will be filled later with a pointer to the comedi-device */ /* and ONLY then the urb should be submitted */ - usbduxsub[index].urbIn[i]->context = NULL; - usbduxsub[index].urbIn[i]->pipe = + usbduxsub[index].urb_in[i]->context = NULL; + usbduxsub[index].urb_in[i]->pipe = usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP); - usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP; - usbduxsub[index].urbIn[i]->transfer_buffer = + usbduxsub[index].urb_in[i]->transfer_flags = URB_ISO_ASAP; + usbduxsub[index].urb_in[i]->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL); - if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) { + if (!(usbduxsub[index].urb_in[i]->transfer_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq; - usbduxsub[index].urbIn[i]->number_of_packets = 1; - usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF; - usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0; - usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF; + usbduxsub[index].urb_in[i]->complete = usbduxsub_ai_isoc_irq; + usbduxsub[index].urb_in[i]->number_of_packets = 1; + usbduxsub[index].urb_in[i]->transfer_buffer_length = SIZEINBUF; + usbduxsub[index].urb_in[i]->iso_frame_desc[0].offset = 0; + usbduxsub[index].urb_in[i]->iso_frame_desc[0].length = SIZEINBUF; } /* out */ if (usbduxsub[index].high_speed) - usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH; + usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSHIGH; else - usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL; + usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSFULL; - usbduxsub[index].urbOut = - kcalloc(usbduxsub[index].numOfOutBuffers, sizeof(struct urb *), + usbduxsub[index].urb_out = + kcalloc(usbduxsub[index].num_out_buffers, sizeof(struct urb *), GFP_KERNEL); - if (!(usbduxsub[index].urbOut)) { + if (!(usbduxsub[index].urb_out)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) { + for (i = 0; i < usbduxsub[index].num_out_buffers; i++) { /* one frame: 1ms */ - usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL); - if (usbduxsub[index].urbOut[i] == NULL) { + usbduxsub[index].urb_out[i] = usb_alloc_urb(1, GFP_KERNEL); + if (usbduxsub[index].urb_out[i] == NULL) { dev_err(dev, "comedi_: usbdux%d: " "Could not alloc. urb(%d)\n", index, i); tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev; + usbduxsub[index].urb_out[i]->dev = usbduxsub[index].usbdev; /* will be filled later with a pointer to the comedi-device */ /* and ONLY then the urb should be submitted */ - usbduxsub[index].urbOut[i]->context = NULL; - usbduxsub[index].urbOut[i]->pipe = + usbduxsub[index].urb_out[i]->context = NULL; + usbduxsub[index].urb_out[i]->pipe = usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP); - usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP; - usbduxsub[index].urbOut[i]->transfer_buffer = + usbduxsub[index].urb_out[i]->transfer_flags = URB_ISO_ASAP; + usbduxsub[index].urb_out[i]->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); - if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) { + if (!(usbduxsub[index].urb_out[i]->transfer_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq; - usbduxsub[index].urbOut[i]->number_of_packets = 1; - usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF; - usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0; - usbduxsub[index].urbOut[i]->iso_frame_desc[0].length = + usbduxsub[index].urb_out[i]->complete = usbduxsub_ao_isoc_irq; + usbduxsub[index].urb_out[i]->number_of_packets = 1; + usbduxsub[index].urb_out[i]->transfer_buffer_length = SIZEOUTBUF; + usbduxsub[index].urb_out[i]->iso_frame_desc[0].offset = 0; + usbduxsub[index].urb_out[i]->iso_frame_desc[0].length = SIZEOUTBUF; if (usbduxsub[index].high_speed) { /* uframes */ - usbduxsub[index].urbOut[i]->interval = 8; + usbduxsub[index].urb_out[i]->interval = 8; } else { /* frames */ - usbduxsub[index].urbOut[i]->interval = 1; + usbduxsub[index].urb_out[i]->interval = 1; } } /* pwm */ if (usbduxsub[index].high_speed) { /* max bulk ep size in high speed */ - usbduxsub[index].sizePwmBuf = 512; - usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL); - if (usbduxsub[index].urbPwm == NULL) { + usbduxsub[index].size_pwm_buf = 512; + usbduxsub[index].urb_pwm = usb_alloc_urb(0, GFP_KERNEL); + if (usbduxsub[index].urb_pwm == NULL) { dev_err(dev, "comedi_: usbdux%d: " "Could not alloc. pwm urb\n", index); tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } - usbduxsub[index].urbPwm->transfer_buffer = - kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL); - if (!(usbduxsub[index].urbPwm->transfer_buffer)) { + usbduxsub[index].urb_pwm->transfer_buffer = + kzalloc(usbduxsub[index].size_pwm_buf, GFP_KERNEL); + if (!(usbduxsub[index].urb_pwm->transfer_buffer)) { tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; } } else { - usbduxsub[index].urbPwm = NULL; - usbduxsub[index].sizePwmBuf = 0; + usbduxsub[index].urb_pwm = NULL; + usbduxsub[index].size_pwm_buf = 0; } usbduxsub[index].ai_cmd_running = 0; -- cgit From d4a67bb2e2ac02fbcd3d1c780bbf7200eeb2a76d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 14 Mar 2013 02:40:28 -0400 Subject: staging: csr: fix compilation warning in unifi_siwscan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit got the warnings drivers/staging/csr/sme_wext.c: In function ‘unifi_siwscan’: drivers/staging/csr/sme_wext.c:1276:9: warning: variable ‘scantype’ set but not used [-Wunused-but-set-variable] fixed by removing the variable Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_wext.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 5e06a380b40a..4129a6436b76 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -1273,7 +1273,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info, { netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - int scantype; int r; CsrWifiSsid scan_ssid; unsigned char *channel_list = NULL; @@ -1293,8 +1292,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info, } - scantype = UNIFI_SCAN_ACTIVE; - #if WIRELESS_EXT > 17 /* Providing a valid channel list will force an active scan */ if (req) { -- cgit From 2c0fb1c969ddedf15b4d9d0c106f4dca82dffc21 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 14 Mar 2013 10:41:39 +0100 Subject: staging: android: remove dependency on TINY_SHMEM The Kconfig entry for the "Anonymous Shared Memory Subsystem" got added in v3.3. It has an optional dependency on TINY_SHMEM. But TINY_SHMEM had already been removed in v2.6.29. So this optional dependency can safely be removed too. Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index cc406cc8b8d1..9f61d46da157 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -22,7 +22,7 @@ config ANDROID_BINDER_IPC config ASHMEM bool "Enable the Anonymous Shared Memory Subsystem" default n - depends on SHMEM || TINY_SHMEM + depends on SHMEM ---help--- The ashmem subsystem is a new shared memory allocator, similar to POSIX SHM but with different behavior and sporting a simpler -- cgit From 433121c6ef516e4a55d0dbc4c90d75f7a3084c55 Mon Sep 17 00:00:00 2001 From: Nathan Zimmer Date: Wed, 13 Mar 2013 13:05:59 -0500 Subject: staging: dgrp: cleanup sparse warnings A cleanup patch to remove sparse warnings caused by my other patch "procfs: Improve Scaling in proc" since now proc_fops is protected by the rcu. Signed-off-by: Nathan Zimmer Cc: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_dpa_ops.c | 2 +- drivers/staging/dgrp/dgrp_mon_ops.c | 2 +- drivers/staging/dgrp/dgrp_net_ops.c | 2 +- drivers/staging/dgrp/dgrp_ports_ops.c | 2 +- drivers/staging/dgrp/dgrp_specproc.c | 6 ++++-- 5 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c index 021cca498f2c..67fb3d6c45ea 100644 --- a/drivers/staging/dgrp/dgrp_dpa_ops.c +++ b/drivers/staging/dgrp/dgrp_dpa_ops.c @@ -116,7 +116,7 @@ void dgrp_register_dpa_hook(struct proc_dir_entry *de) struct nd_struct *node = de->data; de->proc_iops = &dpa_inode_ops; - de->proc_fops = &dpa_ops; + rcu_assign_pointer(de->proc_fops, &dpa_ops); node->nd_dpa_de = de; spin_lock_init(&node->nd_dpa_lock); diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c index 4792d056a365..b484fccb494e 100644 --- a/drivers/staging/dgrp/dgrp_mon_ops.c +++ b/drivers/staging/dgrp/dgrp_mon_ops.c @@ -66,7 +66,7 @@ void dgrp_register_mon_hook(struct proc_dir_entry *de) struct nd_struct *node = de->data; de->proc_iops = &mon_inode_ops; - de->proc_fops = &mon_ops; + rcu_assign_pointer(de->proc_fops, &mon_ops); node->nd_mon_de = de; sema_init(&node->nd_mon_semaphore, 1); } diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index f364e8e1722d..64f48ffb9d4e 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -91,7 +91,7 @@ void dgrp_register_net_hook(struct proc_dir_entry *de) struct nd_struct *node = de->data; de->proc_iops = &net_inode_ops; - de->proc_fops = &net_ops; + rcu_assign_pointer(de->proc_fops, &net_ops); node->nd_net_de = de; sema_init(&node->nd_net_semaphore, 1); node->nd_state = NS_CLOSED; diff --git a/drivers/staging/dgrp/dgrp_ports_ops.c b/drivers/staging/dgrp/dgrp_ports_ops.c index cd1fc2088624..f93dc1f262f5 100644 --- a/drivers/staging/dgrp/dgrp_ports_ops.c +++ b/drivers/staging/dgrp/dgrp_ports_ops.c @@ -65,7 +65,7 @@ void dgrp_register_ports_hook(struct proc_dir_entry *de) struct nd_struct *node = de->data; de->proc_iops = &ports_inode_ops; - de->proc_fops = &ports_ops; + rcu_assign_pointer(de->proc_fops, &ports_ops); node->nd_ports_de = de; } diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index 73f287f96604..d66712c8aa94 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -271,9 +271,11 @@ static void register_proc_table(struct dgrp_proc_entry *table, if (!table->child) { de->proc_iops = &proc_inode_ops; if (table->proc_file_ops) - de->proc_fops = table->proc_file_ops; + rcu_assign_pointer(de->proc_fops, + table->proc_file_ops); else - de->proc_fops = &dgrp_proc_file_ops; + rcu_assign_pointer(de->proc_fops, + &dgrp_proc_file_ops); } } table->de = de; -- cgit From 7f072f54ae5dc9965cbe450419b1389d13e2b849 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Mar 2013 10:35:51 -0700 Subject: staging: comedi_pci: make comedi_pci_disable() safe to call Currently all the comedi PCI drivers need to do some checking in their (*detach) before calling comedi_pci_disable() in order to make sure the PCI device has actually be enabled. Change the parameter passed to comedi_pci_disable() from a struct pci_dev pointer to a comedi_device pointer and have comedi_pci_disable() handle all the checking. For most comedi PCI drivers this also allows removing the local variable holding the pointer to the pci_dev. For some of the drivers comedi_pci_disable can now be used directly as the (*detach) function. The National Instruments drivers that use the mite module currently enable/disable the PCI device in the mite module. For those drivers move the call to comedi_pci_disable into the driver and make sure dev->iobase is set to a non-zero value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_pci.c | 14 ++++++++------ drivers/staging/comedi/comedidev.h | 4 ++-- drivers/staging/comedi/drivers/8255_pci.c | 10 +++------- drivers/staging/comedi/drivers/addi-data/addi_common.c | 6 +----- drivers/staging/comedi/drivers/addi_apci_1032.c | 7 +------ drivers/staging/comedi/drivers/addi_apci_1516.c | 5 +---- drivers/staging/comedi/drivers/addi_apci_16xx.c | 12 +----------- drivers/staging/comedi/drivers/addi_apci_1710.c | 7 +------ drivers/staging/comedi/drivers/addi_apci_2032.c | 7 +------ drivers/staging/comedi/drivers/addi_apci_2200.c | 7 +------ drivers/staging/comedi/drivers/addi_apci_3120.c | 6 +----- drivers/staging/comedi/drivers/addi_apci_3501.c | 7 +------ drivers/staging/comedi/drivers/adl_pci6208.c | 12 +----------- drivers/staging/comedi/drivers/adl_pci7x3x.c | 12 +----------- drivers/staging/comedi/drivers/adl_pci8164.c | 12 +----------- drivers/staging/comedi/drivers/adl_pci9111.c | 7 +------ drivers/staging/comedi/drivers/adl_pci9118.c | 7 ++----- drivers/staging/comedi/drivers/adv_pci1710.c | 7 +------ drivers/staging/comedi/drivers/adv_pci1723.c | 11 +++-------- drivers/staging/comedi/drivers/adv_pci1724.c | 12 +----------- drivers/staging/comedi/drivers/adv_pci_dio.c | 6 +----- drivers/staging/comedi/drivers/amplc_dio200.c | 11 +++-------- drivers/staging/comedi/drivers/amplc_pc236.c | 6 ++---- drivers/staging/comedi/drivers/amplc_pc263.c | 6 ++---- drivers/staging/comedi/drivers/amplc_pci224.c | 6 ++---- drivers/staging/comedi/drivers/amplc_pci230.c | 6 ++---- drivers/staging/comedi/drivers/cb_pcidas.c | 7 ++----- drivers/staging/comedi/drivers/cb_pcidas64.c | 5 +---- drivers/staging/comedi/drivers/cb_pcidda.c | 7 +------ drivers/staging/comedi/drivers/cb_pcimdas.c | 7 +------ drivers/staging/comedi/drivers/cb_pcimdda.c | 7 +------ drivers/staging/comedi/drivers/contec_pci_dio.c | 12 +----------- drivers/staging/comedi/drivers/daqboard2000.c | 7 +------ drivers/staging/comedi/drivers/das08_pci.c | 5 +---- drivers/staging/comedi/drivers/dt3000.c | 6 +----- drivers/staging/comedi/drivers/dyna_pci10xx.c | 6 +----- drivers/staging/comedi/drivers/gsc_hpdi.c | 3 +-- drivers/staging/comedi/drivers/icp_multi.c | 6 +----- drivers/staging/comedi/drivers/jr3_pci.c | 4 +--- drivers/staging/comedi/drivers/ke_counter.c | 12 +----------- drivers/staging/comedi/drivers/me4000.c | 11 +++-------- drivers/staging/comedi/drivers/me_daq.c | 6 +----- drivers/staging/comedi/drivers/mite.c | 4 +--- drivers/staging/comedi/drivers/ni_6527.c | 2 ++ drivers/staging/comedi/drivers/ni_65xx.c | 2 ++ drivers/staging/comedi/drivers/ni_660x.c | 2 ++ drivers/staging/comedi/drivers/ni_670x.c | 2 ++ drivers/staging/comedi/drivers/ni_labpc.c | 2 ++ drivers/staging/comedi/drivers/ni_pcidio.c | 2 ++ drivers/staging/comedi/drivers/ni_pcimio.c | 2 ++ drivers/staging/comedi/drivers/rtd520.c | 6 +----- drivers/staging/comedi/drivers/s626.c | 6 +----- drivers/staging/comedi/drivers/skel.c | 4 +--- 53 files changed, 82 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index bf5095601e00..bee012c1e6a2 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -57,14 +57,16 @@ EXPORT_SYMBOL_GPL(comedi_pci_enable); /** * comedi_pci_disable() - Release the regions and disable the PCI device. - * @pcidev: pci_dev struct - * - * This must be matched with a previous successful call to comedi_pci_enable(). + * @dev: comedi_device struct */ -void comedi_pci_disable(struct pci_dev *pcidev) +void comedi_pci_disable(struct comedi_device *dev) { - pci_release_regions(pcidev); - pci_disable_device(pcidev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (pcidev && dev->iobase) { + pci_release_regions(pcidev); + pci_disable_device(pcidev); + } } EXPORT_SYMBOL_GPL(comedi_pci_disable); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index b8e5d091fff8..9846c2ecc916 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -385,7 +385,7 @@ struct pci_driver; struct pci_dev *comedi_to_pci_dev(struct comedi_device *); int comedi_pci_enable(struct pci_dev *, const char *); -void comedi_pci_disable(struct pci_dev *); +void comedi_pci_disable(struct comedi_device *); int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *, unsigned long context); @@ -426,7 +426,7 @@ static inline int comedi_pci_enable(struct pci_dev *dev, const char *name) return -ENOSYS; } -static inline void comedi_pci_disable(struct pci_dev *dev) +static inline void comedi_pci_disable(struct comedi_device *dev) { } diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 7e25500cd996..a546dff61925 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -247,7 +247,6 @@ static int pci_8255_auto_attach(struct comedi_device *dev, static void pci_8255_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board = comedi_board(dev); struct pci_8255_private *devpriv = dev->private; struct comedi_subdevice *s; @@ -261,12 +260,9 @@ static void pci_8255_detach(struct comedi_device *dev) subdev_8255_cleanup(dev, s); } } - if (pcidev) { - if (devpriv->mmio_base) - iounmap(devpriv->mmio_base); - if (dev->iobase) - comedi_pci_disable(pcidev); - } + if (devpriv->mmio_base) + iounmap(devpriv->mmio_base); + comedi_pci_disable(dev); } static struct comedi_driver pci_8255_driver = { diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 3140880948e1..704a56eec6b7 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -317,7 +317,6 @@ static int addi_auto_attach(struct comedi_device *dev, static void i_ADDI_Detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct addi_private *devpriv = dev->private; if (devpriv) { @@ -328,8 +327,5 @@ static void i_ADDI_Detach(struct comedi_device *dev) if (devpriv->dw_AiBase) iounmap(devpriv->dw_AiBase); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index fdd053c61a63..4da6e8b14dc1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -353,16 +353,11 @@ static int apci1032_auto_attach(struct comedi_device *dev, static void apci1032_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) apci1032_reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci1032_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 0319315ba9bd..a7e449db4693 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -201,14 +201,11 @@ static int apci1516_auto_attach(struct comedi_device *dev, static void apci1516_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) apci1516_reset(dev); if (dev->subdevices) addi_watchdog_cleanup(&dev->subdevices[2]); - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); } static struct comedi_driver apci1516_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 8aca57f8590a..e2f9357d4c35 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -184,21 +184,11 @@ static int apci16xx_auto_attach(struct comedi_device *dev, return 0; } -static void apci16xx_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver apci16xx_driver = { .driver_name = "addi_apci_16xx", .module = THIS_MODULE, .auto_attach = apci16xx_auto_attach, - .detach = apci16xx_detach, + .detach = comedi_pci_disable, }; static int apci16xx_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index f654eb03473a..05e1b9c391e6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -73,16 +73,11 @@ static int apci1710_auto_attach(struct comedi_device *dev, static void apci1710_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) i_APCI1710_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci1710_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 4a33b3502f40..6e4ee0ae67aa 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -350,8 +350,6 @@ static int apci2032_auto_attach(struct comedi_device *dev, static void apci2032_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) apci2032_reset(dev); if (dev->irq) @@ -360,10 +358,7 @@ static void apci2032_detach(struct comedi_device *dev) kfree(dev->read_subdev->private); if (dev->subdevices) addi_watchdog_cleanup(&dev->subdevices[1]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci2032_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 48afa2316497..aea0abb1a0af 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -130,16 +130,11 @@ static int apci2200_auto_attach(struct comedi_device *dev, static void apci2200_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) apci2200_reset(dev); if (dev->subdevices) addi_watchdog_cleanup(&dev->subdevices[2]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci2200_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 07bcb388fc5f..056153157e51 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -203,7 +203,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, static void apci3120_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct addi_private *devpriv = dev->private; if (devpriv) { @@ -222,10 +221,7 @@ static void apci3120_detach(struct comedi_device *dev) devpriv->ui_DmaBufferPages[1]); } } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci3120_driver = { diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index ecd54ea6f8de..8bd3d72df0a6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -423,16 +423,11 @@ static int apci3501_auto_attach(struct comedi_device *dev, static void apci3501_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) apci3501_reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver apci3501_driver = { diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 49f82f48bf09..8939bbdaee5f 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -233,21 +233,11 @@ static int pci6208_auto_attach(struct comedi_device *dev, return 0; } -static void pci6208_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver adl_pci6208_driver = { .driver_name = "adl_pci6208", .module = THIS_MODULE, .auto_attach = pci6208_auto_attach, - .detach = pci6208_detach, + .detach = comedi_pci_disable, }; static int adl_pci6208_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 70f8c93ef7ad..bd2e58415d77 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -259,21 +259,11 @@ static int adl_pci7x3x_auto_attach(struct comedi_device *dev, return 0; } -static void adl_pci7x3x_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver adl_pci7x3x_driver = { .driver_name = "adl_pci7x3x", .module = THIS_MODULE, .auto_attach = adl_pci7x3x_auto_attach, - .detach = adl_pci7x3x_detach, + .detach = comedi_pci_disable, }; static int adl_pci7x3x_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index de5cac052888..008f89aea4ba 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -136,21 +136,11 @@ static int adl_pci8164_auto_attach(struct comedi_device *dev, return 0; } -static void adl_pci8164_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver adl_pci8164_driver = { .driver_name = "adl_pci8164", .module = THIS_MODULE, .auto_attach = adl_pci8164_auto_attach, - .detach = adl_pci8164_detach, + .detach = comedi_pci_disable, }; static int adl_pci8164_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 8680cf18b7de..ee45ee8c03c4 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -939,16 +939,11 @@ static int pci9111_auto_attach(struct comedi_device *dev, static void pci9111_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) pci9111_reset(dev); if (dev->irq != 0) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver adl_pci9111_driver = { diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index a0277a83115d..2bf00e834540 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2202,12 +2202,9 @@ static void pci9118_detach(struct comedi_device *dev) free_pages((unsigned long)devpriv->dmabuf_virt[1], devpriv->dmabuf_pages[1]); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - + comedi_pci_disable(dev); + if (pcidev) pci_dev_put(pcidev); - } } static struct comedi_driver adl_pci9118_driver = { diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 2f6c2d72986d..af302fe3f5cb 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1372,16 +1372,11 @@ static int pci1710_auto_attach(struct comedi_device *dev, static void pci1710_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) pci1710_reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver adv_pci1710_driver = { diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index bd95b1d4338a..25f4cba5a75b 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -306,14 +306,9 @@ static int pci1723_auto_attach(struct comedi_device *dev, static void pci1723_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) { - pci1723_reset(dev); - comedi_pci_disable(pcidev); - } - } + if (dev->iobase) + pci1723_reset(dev); + comedi_pci_disable(dev); } static struct comedi_driver adv_pci1723_driver = { diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index f448e4db4d95..c799308adfb4 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -377,21 +377,11 @@ static int adv_pci1724_auto_attach(struct comedi_device *dev, return 0; } -static void adv_pci1724_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev && dev->iobase) { - comedi_pci_disable(pcidev); - dev_info(dev->class_dev, "detached\n"); - } -} - static struct comedi_driver adv_pci1724_driver = { .driver_name = "adv_pci1724", .module = THIS_MODULE, .auto_attach = adv_pci1724_auto_attach, - .detach = adv_pci1724_detach, + .detach = comedi_pci_disable, }; static int adv_pci1724_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 52b6d0264d34..79f72d6d7de1 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1165,7 +1165,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, static void pci_dio_detach(struct comedi_device *dev) { struct pci_dio_private *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int i; @@ -1181,10 +1180,7 @@ static void pci_dio_detach(struct comedi_device *dev) s->private = NULL; } } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver adv_pci_dio_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 82f80d563fbe..d13a6dddcd09 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -2029,14 +2029,9 @@ static void dio200_detach(struct comedi_device *dev) release_region(devpriv->io.u.iobase, thisboard->mainsize); } else if (is_pci_board(thisboard)) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (pcidev) { - if (devpriv->io.regtype != no_regtype) { - if (devpriv->io.regtype == mmio_regtype) - iounmap(devpriv->io.u.membase); - comedi_pci_disable(pcidev); - } - } + if (devpriv->io.regtype == mmio_regtype) + iounmap(devpriv->io.u.membase); + comedi_pci_disable(dev); } } diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index b6bba4d15a5a..45168488503d 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -576,11 +576,9 @@ static void pc236_detach(struct comedi_device *dev) release_region(dev->iobase, PC236_IO_SIZE); } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); + if (pcidev) pci_dev_put(pcidev); - } } } diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index e61d55679a77..d825414994b8 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -335,11 +335,9 @@ static void pc263_detach(struct comedi_device *dev) release_region(dev->iobase, PC263_IO_SIZE); } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); + if (pcidev) pci_dev_put(pcidev); - } } } diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4a56468cb7ba..3d5c1332eb34 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1488,11 +1488,9 @@ static void pci224_detach(struct comedi_device *dev) kfree(devpriv->ao_scan_vals); kfree(devpriv->ao_scan_order); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); + if (pcidev) pci_dev_put(pcidev); - } } static struct comedi_driver amplc_pci224_driver = { diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 70074b512130..1bfe893b4cb2 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2840,11 +2840,9 @@ static void pci230_detach(struct comedi_device *dev) subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); + if (pcidev) pci_dev_put(pcidev); - } } static struct comedi_driver amplc_pci230_driver = { diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 1f9316996951..04aa8d948a8b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1458,6 +1458,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; + dev->iobase = 1; devpriv->s5933_config = pci_resource_start(pcidev, 0); devpriv->control_status = pci_resource_start(pcidev, 1); @@ -1599,7 +1600,6 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, static void cb_pcidas_detach(struct comedi_device *dev) { struct cb_pcidas_private *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (devpriv) { if (devpriv->s5933_config) { @@ -1611,10 +1611,7 @@ static void cb_pcidas_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (dev->subdevices) subdev_8255_cleanup(dev, &dev->subdevices[2]); - if (pcidev) { - if (devpriv->s5933_config) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver cb_pcidas_driver = { diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index e61cf71d46ef..15a97212b158 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4194,10 +4194,7 @@ static void detach(struct comedi_device *dev) } if (dev->subdevices) subdev_8255_cleanup(dev, &dev->subdevices[4]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver cb_pcidas64_driver = { diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 54cdb2728a81..aff16171ca93 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -399,16 +399,11 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, static void cb_pcidda_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->subdevices) { subdev_8255_cleanup(dev, &dev->subdevices[1]); subdev_8255_cleanup(dev, &dev->subdevices[2]); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver cb_pcidda_driver = { diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 7d456ad2aad4..8a8677f2525e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -277,14 +277,9 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, static void cb_pcimdas_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver cb_pcimdas_driver = { diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 5db4f4ada463..7b8adec5e7b9 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -201,14 +201,9 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev, static void cb_pcimdda_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->subdevices) subdev_8255_cleanup(dev, &dev->subdevices[1]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver cb_pcimdda_driver = { diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index d6597445aae8..b8c56a60cda9 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -109,21 +109,11 @@ static int contec_auto_attach(struct comedi_device *dev, return 0; } -static void contec_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, .auto_attach = contec_auto_attach, - .detach = contec_detach, + .detach = comedi_pci_disable, }; static int contec_pci_dio_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 42e13e30d502..077f9a5eb7c8 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -767,7 +767,6 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, static void daqboard2000_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct daqboard2000_private *devpriv = dev->private; if (dev->subdevices) @@ -780,11 +779,7 @@ static void daqboard2000_detach(struct comedi_device *dev) if (devpriv->plx) iounmap(devpriv->plx); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - pci_dev_put(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver daqboard2000_driver = { diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index a56cee7f86dd..c64fb2775b8c 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -81,11 +81,8 @@ static int das08_pci_auto_attach(struct comedi_device *dev, static void das08_pci_detach(struct comedi_device *dev) { - struct pci_dev *pdev = comedi_to_pci_dev(dev); - das08_common_detach(dev); - if (dev->iobase) - comedi_pci_disable(pdev); + comedi_pci_disable(dev); } static struct comedi_driver das08_pci_comedi_driver = { diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 5726d56346c8..296c5205ac9f 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -814,7 +814,6 @@ static int dt3000_auto_attach(struct comedi_device *dev, static void dt3000_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct dt3k_private *devpriv = dev->private; if (dev->irq) @@ -823,10 +822,7 @@ static void dt3000_detach(struct comedi_device *dev) if (devpriv->io_addr) iounmap(devpriv->io_addr); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver dt3000_driver = { diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 58ff129a8339..9f83dfbcf295 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -254,15 +254,11 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, static void dyna_pci10xx_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct dyna_pci10xx_private *devpriv = dev->private; if (devpriv) mutex_destroy(&devpriv->mutex); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver dyna_pci10xx_driver = { diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index a18d897606f8..f0e92143ac89 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -596,9 +596,8 @@ static void hpdi_detach(struct comedi_device *dev) NUM_DMA_DESCRIPTORS, devpriv->dma_desc, devpriv->dma_desc_phys_addr); - if (dev->iobase) - comedi_pci_disable(pcidev); } + comedi_pci_disable(dev); } static int dio_config_block_size(struct comedi_device *dev, unsigned int *data) diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 9a466879e493..65265c3ce3ff 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -594,7 +594,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev, static void icp_multi_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct icp_multi_private *devpriv = dev->private; if (devpriv) @@ -604,10 +603,7 @@ static void icp_multi_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (devpriv && devpriv->io_addr) iounmap(devpriv->io_addr); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver icp_multi_driver = { diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index aea940121c58..f1ae9a814d8f 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -816,7 +816,6 @@ static int jr3_pci_auto_attach(struct comedi_device *dev, static void jr3_pci_detach(struct comedi_device *dev) { int i; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct jr3_pci_dev_private *devpriv = dev->private; if (devpriv) { @@ -828,9 +827,8 @@ static void jr3_pci_detach(struct comedi_device *dev) } if (devpriv->iobase) iounmap(devpriv->iobase); - if (dev->iobase) - comedi_pci_disable(pcidev); } + comedi_pci_disable(dev); } static struct comedi_driver jr3_pci_driver = { diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index ac40e355dff2..74318f204e25 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -131,21 +131,11 @@ static int cnt_auto_attach(struct comedi_device *dev, return 0; } -static void cnt_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver ke_counter_driver = { .driver_name = "ke_counter", .module = THIS_MODULE, .auto_attach = cnt_auto_attach, - .detach = cnt_detach, + .detach = comedi_pci_disable, }; static int ke_counter_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 141a3f7bbf15..6bc1347eaf68 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1697,16 +1697,11 @@ static int me4000_auto_attach(struct comedi_device *dev, static void me4000_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->irq) free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) { - me4000_reset(dev); - comedi_pci_disable(pcidev); - } - } + if (dev->iobase) + me4000_reset(dev); + comedi_pci_disable(dev); } static struct comedi_driver me4000_driver = { diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 55d66d0295e0..8951a673c2d1 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -580,7 +580,6 @@ static int me_auto_attach(struct comedi_device *dev, static void me_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct me_private_data *dev_private = dev->private; if (dev_private) { @@ -591,10 +590,7 @@ static void me_detach(struct comedi_device *dev) if (dev_private->plx_regbase) iounmap(dev_private->plx_regbase); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver me_daq_driver = { diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index be2c15f84614..5a3b14fb4de1 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -208,10 +208,8 @@ void mite_unsetup(struct mite_struct *mite) iounmap(mite->daq_io_addr); mite->daq_io_addr = NULL; } - if (mite->mite_phys_addr) { - comedi_pci_disable(mite->pcidev); + if (mite->mite_phys_addr) mite->mite_phys_addr = 0; - } } EXPORT_SYMBOL(mite_unsetup); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 514d5db92028..194eac63dd3e 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -350,6 +350,7 @@ static int ni6527_auto_attach(struct comedi_device *dev, dev_err(dev->class_dev, "error setting up mite\n"); return ret; } + dev->iobase = 1; dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name, readb(devpriv->mite->daq_io_addr + ID_Register)); @@ -419,6 +420,7 @@ static void ni6527_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); mite_free(devpriv->mite); } + comedi_pci_disable(dev); } static struct comedi_driver ni6527_driver = { diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 74a1e65010cf..b882a5f5b035 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -614,6 +614,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } + dev->iobase = 1; dev->irq = mite_irq(devpriv->mite); dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, @@ -748,6 +749,7 @@ static void ni_65xx_detach(struct comedi_device *dev) mite_free(devpriv->mite); } } + comedi_pci_disable(dev); } static struct comedi_driver ni_65xx_driver = { diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index d2e061a195d0..cc82106af7f0 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1188,6 +1188,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } + dev->iobase = 1; ret = ni_660x_alloc_mite_rings(dev); if (ret < 0) @@ -1302,6 +1303,7 @@ static void ni_660x_detach(struct comedi_device *dev) mite_free(devpriv->mite); } } + comedi_pci_disable(dev); } static struct comedi_driver ni_660x_driver = { diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 0e7b957afbe4..5ec6f829a924 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -222,6 +222,7 @@ static int ni_670x_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } + dev->iobase = 1; ret = comedi_alloc_subdevices(dev, 2); if (ret) @@ -286,6 +287,7 @@ static void ni_670x_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); mite_free(devpriv->mite); } + comedi_pci_disable(dev); } static struct comedi_driver ni_670x_driver = { diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index d386c3e2b976..9082eca09499 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -722,6 +722,7 @@ static int labpc_auto_attach(struct comedi_device *dev, ret = mite_setup(devpriv->mite); if (ret < 0) return ret; + dev->iobase = 1; iobase = (unsigned long)devpriv->mite->daq_io_addr; irq = mite_irq(devpriv->mite); return labpc_common_attach(dev, iobase, irq, 0); @@ -800,6 +801,7 @@ void labpc_common_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); mite_free(devpriv->mite); } + comedi_pci_disable(dev); #endif }; EXPORT_SYMBOL_GPL(labpc_common_detach); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 50e025b07780..8f743751507b 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1128,6 +1128,7 @@ static int nidio_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } + dev->iobase = 1; devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->di_mite_ring == NULL) @@ -1202,6 +1203,7 @@ static void nidio_detach(struct comedi_device *dev) mite_free(devpriv->mite); } } + comedi_pci_disable(dev); } static struct comedi_driver ni_pcidio_driver = { diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 4d1a431edee0..0f18f8dda5fb 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1470,6 +1470,7 @@ static void pcimio_detach(struct comedi_device *dev) mite_free(devpriv->mite); } } + comedi_pci_disable(dev); } static int pcimio_auto_attach(struct comedi_device *dev, @@ -1513,6 +1514,7 @@ static int pcimio_auto_attach(struct comedi_device *dev, pr_warn("error setting up mite\n"); return ret; } + dev->iobase = 1; devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->ai_mite_ring == NULL) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 5ee38b149b51..5b0676817726 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1373,7 +1373,6 @@ static int rtd_auto_attach(struct comedi_device *dev, static void rtd_detach(struct comedi_device *dev) { struct rtdPrivate *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (devpriv) { /* Shut down any board ops by resetting it */ @@ -1392,10 +1391,7 @@ static void rtd_detach(struct comedi_device *dev) if (devpriv->lcfg) iounmap(devpriv->lcfg); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver rtd520_driver = { diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 4fec6d6a04ab..92338791f4a2 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2790,7 +2790,6 @@ static int s626_auto_attach(struct comedi_device *dev, static void s626_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct s626_private *devpriv = dev->private; if (devpriv) { @@ -2818,10 +2817,7 @@ static void s626_detach(struct comedi_device *dev) if (devpriv->base_addr) iounmap(devpriv->base_addr); } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } + comedi_pci_disable(dev); } static struct comedi_driver s626_driver = { diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 1737c2a06ae3..f5d708c3aa5b 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -606,7 +606,6 @@ static void skel_detach(struct comedi_device *dev) { const struct skel_board *thisboard = comedi_board(dev); struct skel_private *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (!thisboard || !devpriv) return; @@ -626,8 +625,7 @@ static void skel_detach(struct comedi_device *dev) * If PCI device enabled by _auto_attach() (or _attach()), * disable it here. */ - if (pcidev && dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(dev); } else { /* * ISA board -- cgit From 818f569fe930c5b8a05d1a44ece3c63c99c13c88 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Mar 2013 10:36:31 -0700 Subject: staging: comedi_pci: pass comedi_device to comedi_pci_enable() Make comedi_pci_enable() use the same parameter type as comedi_pci_disable(). This also allows comedi_pci_enable to automatically determine the resource name passed to pci_request_regions(). Make sure the errno value returned is passed on instead of assuming an errno. Also, remove any kernel noise that is generated when the call fails. The National Instruments drivers that use the mite module currently enable the PCI device in the mite module. For those drivers move the call to comedi_pci_enable into the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_pci.c | 13 +++++++++---- drivers/staging/comedi/comedidev.h | 4 ++-- drivers/staging/comedi/drivers/8255_pci.c | 2 +- drivers/staging/comedi/drivers/addi-data/addi_common.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci7x3x.c | 2 +- drivers/staging/comedi/drivers/adl_pci8164.c | 2 +- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 7 ++----- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci1724.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/amplc_dio200.c | 9 ++++----- drivers/staging/comedi/drivers/amplc_pc236.c | 8 +++----- drivers/staging/comedi/drivers/amplc_pc263.c | 8 +++----- drivers/staging/comedi/drivers/amplc_pci224.c | 9 +++------ drivers/staging/comedi/drivers/amplc_pci230.c | 11 +++++------ drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 8 +++----- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 2 +- drivers/staging/comedi/drivers/contec_pci_dio.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 4 ++-- drivers/staging/comedi/drivers/das08_pci.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 8 +++----- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 6 +++--- drivers/staging/comedi/drivers/ke_counter.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/mite.c | 5 ----- drivers/staging/comedi/drivers/ni_6527.c | 6 +++++- drivers/staging/comedi/drivers/ni_65xx.c | 6 +++++- drivers/staging/comedi/drivers/ni_660x.c | 6 +++++- drivers/staging/comedi/drivers/ni_670x.c | 6 +++++- drivers/staging/comedi/drivers/ni_labpc.c | 6 +++++- drivers/staging/comedi/drivers/ni_pcidio.c | 6 +++++- drivers/staging/comedi/drivers/ni_pcimio.c | 6 +++++- drivers/staging/comedi/drivers/rtd520.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/drivers/skel.c | 2 +- 53 files changed, 110 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index bee012c1e6a2..b164b0353ebe 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -36,18 +36,23 @@ EXPORT_SYMBOL_GPL(comedi_to_pci_dev); /** * comedi_pci_enable() - Enable the PCI device and request the regions. - * @pcidev: pci_dev struct - * @res_name: name for the requested reqource + * @dev: comedi_device struct */ -int comedi_pci_enable(struct pci_dev *pcidev, const char *res_name) +int comedi_pci_enable(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); int rc; + if (!pcidev) + return -ENODEV; + rc = pci_enable_device(pcidev); if (rc < 0) return rc; - rc = pci_request_regions(pcidev, res_name); + rc = pci_request_regions(pcidev, dev->board_name + ? dev->board_name + : dev->driver->driver_name); if (rc < 0) pci_disable_device(pcidev); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 9846c2ecc916..f638381fe424 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -384,7 +384,7 @@ struct pci_driver; struct pci_dev *comedi_to_pci_dev(struct comedi_device *); -int comedi_pci_enable(struct pci_dev *, const char *); +int comedi_pci_enable(struct comedi_device *); void comedi_pci_disable(struct comedi_device *); int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *, @@ -421,7 +421,7 @@ static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) return NULL; } -static inline int comedi_pci_enable(struct pci_dev *dev, const char *name) +static inline int comedi_pci_enable(struct comedi_device *dev) { return -ENOSYS; } diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index a546dff61925..808460bbd32e 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -204,7 +204,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; iobase = pci_resource_start(pcidev, board->dio_badr); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 704a56eec6b7..cb9b590f63b9 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -101,7 +101,7 @@ static int addi_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 4da6e8b14dc1..3d32448e4e69 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -303,7 +303,7 @@ static int apci1032_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index a7e449db4693..e66ff4e05cdb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -148,7 +148,7 @@ static int apci1516_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index e2f9357d4c35..4c6a9b5a06ae 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -142,7 +142,7 @@ static int apci16xx_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 05e1b9c391e6..f36ad00cee4a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -42,7 +42,7 @@ static int apci1710_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 6e4ee0ae67aa..59e092eab9f3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -289,7 +289,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 1); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index aea0abb1a0af..0953f65ab0ad 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -90,7 +90,7 @@ static int apci2200_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 056153157e51..1c5ac16aad15 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -70,7 +70,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; pci_set_master(pcidev); diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 8bd3d72df0a6..75a36e364932 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -346,7 +346,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 8939bbdaee5f..8a438ff1bd45 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -181,7 +181,7 @@ static int pci6208_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index bd2e58415d77..e3960745f506 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -164,7 +164,7 @@ static int adl_pci7x3x_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 008f89aea4ba..469a51d97b82 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -80,7 +80,7 @@ static int adl_pci8164_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index ee45ee8c03c4..9c27e981db0c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -872,7 +872,7 @@ static int pci9111_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = dev_private; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev_private->lcr_io_base = pci_resource_start(pcidev, 1); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 2bf00e834540..cb4ef2dcbf02 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1970,12 +1970,9 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, u16 u16w; dev->board_name = this_board->name; - ret = comedi_pci_enable(pcidev, dev->board_name); - if (ret) { - dev_err(dev->class_dev, - "cannot enable PCI device %s\n", pci_name(pcidev)); + ret = comedi_pci_enable(dev); + if (ret) return ret; - } if (master) pci_set_master(pcidev); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index af302fe3f5cb..52672c53e11e 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1248,7 +1248,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 25f4cba5a75b..9e81e58a6e69 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -249,7 +249,7 @@ static int pci1723_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index c799308adfb4..a33929e87a2f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -360,7 +360,7 @@ static int adv_pci1724_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - retval = comedi_pci_enable(pcidev, dev->board_name); + retval = comedi_pci_enable(dev); if (retval) return retval; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 79f72d6d7de1..3a05fbca9299 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1104,7 +1104,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, this_board->main_pci_region); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d13a6dddcd09..652494289a13 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1950,12 +1950,11 @@ static int dio200_auto_attach(struct comedi_device *dev, return -EINVAL; } thisboard = comedi_board(dev); - ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); + + ret = comedi_pci_enable(dev); + if (ret) return ret; - } + bar = thisboard->mainbar; base = pci_resource_start(pci_dev, bar); len = pci_resource_len(pci_dev, bar); diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 45168488503d..4507f92e1579 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -470,12 +470,10 @@ static int pc236_pci_common_attach(struct comedi_device *dev, comedi_set_hw_dev(dev, &pci_dev->dev); - ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); + ret = comedi_pci_enable(dev); + if (ret) return ret; - } + devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); iobase = pci_resource_start(pci_dev, 2); return pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index d825414994b8..b8449433eee7 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -249,13 +249,11 @@ static int pc263_pci_common_attach(struct comedi_device *dev, comedi_set_hw_dev(dev, &pci_dev->dev); - ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); + ret = comedi_pci_enable(dev); + if (ret) return ret; - } iobase = pci_resource_start(pci_dev, 2); + return pc263_common_attach(dev, iobase); } diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 3d5c1332eb34..4d7eab9b5565 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1280,13 +1280,10 @@ static int pci224_attach_common(struct comedi_device *dev, comedi_set_hw_dev(dev, &pci_dev->dev); - ret = comedi_pci_enable(pci_dev, DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n" - ); + ret = comedi_pci_enable(dev); + if (ret) return ret; - } + spin_lock_init(&devpriv->ao_spinlock); devpriv->iobase1 = pci_resource_start(pci_dev, 2); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1bfe893b4cb2..b6e4af444ef5 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2645,12 +2645,11 @@ static int pci230_attach_common(struct comedi_device *dev, comedi_set_hw_dev(dev, &pci_dev->dev); dev->board_name = thisboard->name; - /* Enable PCI device and reserve I/O spaces. */ - if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) { - dev_err(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } + + rc = comedi_pci_enable(dev); + if (rc) + return rc; + /* Read base addresses of the PCI230's two I/O regions from PCI * configuration register. */ iobase1 = pci_resource_start(pci_dev, 2); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 04aa8d948a8b..7a23d56645e7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1455,7 +1455,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = 1; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 15a97212b158..46b6af4c517d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4059,11 +4059,9 @@ static int auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_warn(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } + retval = comedi_pci_enable(dev); + if (retval) + return retval; pci_set_master(pcidev); /* Initialize dev->board_name */ diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index aff16171ca93..2da6bd663aff 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -357,7 +357,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 3); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 8a8677f2525e..f6d99a3a972e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -222,7 +222,7 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 7b8adec5e7b9..d00f7f629d36 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -168,7 +168,7 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 3); diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index b8c56a60cda9..da0be62aef60 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -79,7 +79,7 @@ static int contec_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 0); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 077f9a5eb7c8..7c549eb442f8 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -709,8 +709,8 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - result = comedi_pci_enable(pcidev, dev->driver->driver_name); - if (result < 0) + result = comedi_pci_enable(dev); + if (result) return result; dev->iobase = 1; /* the "detach" needs this */ diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index c64fb2775b8c..53fa943dd0b7 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -71,7 +71,7 @@ static int das08_pci_auto_attach(struct comedi_device *dev, /* The das08 driver needs the board_ptr */ dev->board_ptr = &das08_pci_boards[0]; - ret = comedi_pci_enable(pdev, dev->driver->driver_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pdev, 2); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 296c5205ac9f..edbcd89aff9d 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -735,7 +735,7 @@ static int dt3000_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret < 0) return ret; dev->iobase = 1; /* the "detach" needs this */ diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 9f83dfbcf295..17f9ec2a9072 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -194,7 +194,7 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index f0e92143ac89..16b4cc050d35 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -499,11 +499,9 @@ static int hpdi_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - if (comedi_pci_enable(pcidev, dev->board_name)) { - dev_warn(dev->class_dev, - "failed enable PCI device and request regions\n"); - return -EIO; - } + retval = comedi_pci_enable(dev); + if (retval) + return retval; dev->iobase = 1; /* the "detach" needs this */ pci_set_master(pcidev); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 65265c3ce3ff..f29a797fd9d5 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -510,7 +510,7 @@ static int icp_multi_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; iobase = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index f1ae9a814d8f..36659e500f40 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -702,11 +702,11 @@ static int jr3_pci_auto_attach(struct comedi_device *dev, } dev->board_name = "jr3_pci"; - result = comedi_pci_enable(pcidev, "jr3_pci"); - if (result < 0) + result = comedi_pci_enable(dev); + if (result) return result; - dev->iobase = 1; /* the "detach" needs this */ + devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), offsetof(struct jr3_t, channel[devpriv->n_channels])); diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 74318f204e25..bca29e5f4fc5 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -98,7 +98,7 @@ static int cnt_auto_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 0); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 6bc1347eaf68..e415db2d069e 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1571,7 +1571,7 @@ static int me4000_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = info; - result = comedi_pci_enable(pcidev, dev->board_name); + result = comedi_pci_enable(dev); if (result) return result; diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 8951a673c2d1..fbbac1259ebd 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -511,7 +511,7 @@ static int me_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = dev_private; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = 1; /* detach needs this */ diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 5a3b14fb4de1..9a456624ab4e 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -109,11 +109,6 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1) u32 csigr_bits; unsigned unknown_dma_burst_bits; - if (comedi_pci_enable(mite->pcidev, "mite")) { - dev_err(&mite->pcidev->dev, - "error enabling mite and requesting io regions\n"); - return -EIO; - } pci_set_master(mite->pcidev); addr = pci_resource_start(mite->pcidev, 0); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 194eac63dd3e..65dd1c68721a 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -336,6 +336,11 @@ static int ni6527_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -350,7 +355,6 @@ static int ni6527_auto_attach(struct comedi_device *dev, dev_err(dev->class_dev, "error setting up mite\n"); return ret; } - dev->iobase = 1; dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name, readb(devpriv->mite->daq_io_addr + ID_Register)); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index b882a5f5b035..eec712e5e138 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -600,6 +600,11 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -614,7 +619,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - dev->iobase = 1; dev->irq = mite_irq(devpriv->mite); dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index cc82106af7f0..f97a668143d8 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1174,6 +1174,11 @@ static int ni_660x_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; @@ -1188,7 +1193,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - dev->iobase = 1; ret = ni_660x_alloc_mite_rings(dev); if (ret < 0) diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 5ec6f829a924..524f6cd72687 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -208,6 +208,11 @@ static int ni_670x_auto_attach(struct comedi_device *dev, dev->board_ptr = thisboard; dev->board_name = thisboard->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -222,7 +227,6 @@ static int ni_670x_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - dev->iobase = 1; ret = comedi_alloc_subdevices(dev, 2); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 9082eca09499..78f01709e222 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -708,6 +708,11 @@ static int labpc_auto_attach(struct comedi_device *dev, if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) return -ENODEV; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -722,7 +727,6 @@ static int labpc_auto_attach(struct comedi_device *dev, ret = mite_setup(devpriv->mite); if (ret < 0) return ret; - dev->iobase = 1; iobase = (unsigned long)devpriv->mite->daq_io_addr; irq = mite_irq(devpriv->mite); return labpc_common_attach(dev, iobase, irq, 0); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 8f743751507b..2298d6ee12ef 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1112,6 +1112,11 @@ static int nidio_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -1128,7 +1133,6 @@ static int nidio_auto_attach(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - dev->iobase = 1; devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->di_mite_ring == NULL) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 0f18f8dda5fb..098c398f2bea 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1488,6 +1488,11 @@ static int pcimio_auto_attach(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; + ret = comedi_pci_enable(dev); + if (ret) + return ret; + dev->iobase = 1; + ret = ni_alloc_private(dev); if (ret) return ret; @@ -1514,7 +1519,6 @@ static int pcimio_auto_attach(struct comedi_device *dev, pr_warn("error setting up mite\n"); return ret; } - dev->iobase = 1; devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->ai_mite_ring == NULL) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 5b0676817726..c0935d4a89c1 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1283,7 +1283,7 @@ static int rtd_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = 1; /* the "detach" needs this */ diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 92338791f4a2..cd164ee3a5e1 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2673,7 +2673,7 @@ static int s626_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = 1; /* detach needs this */ diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index f5d708c3aa5b..6fb7d5d22094 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -567,7 +567,7 @@ static int skel_auto_attach(struct comedi_device *dev, dev->private = devpriv; /* Enable the PCI device. */ - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; -- cgit From 0b33e43ab39b0080fca9c2cfab58e60af0dd4971 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 13 Mar 2013 12:18:12 -0700 Subject: staging: comedi: addi_apci_1710: only pci bar 2 is used This driver used to be tied to the addi-data common code which always saved the start address of pci bars 0, 1, 2, and 3 for use by the driver. This driver only uses pci bar 2. Remove all the non-used pci bars and move the saving of pci bar 2 so it occurs right after the pci device is enabled. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index f36ad00cee4a..3640c50f2cb0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -45,16 +45,7 @@ static int apci1710_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, @@ -65,8 +56,6 @@ static int apci1710_auto_attach(struct comedi_device *dev, i_ADDI_AttachPCI1710(dev); - devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); - i_APCI1710_Reset(dev); return 0; } -- cgit From c2a10d70f2c84459152ba7de164701cabff53043 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 14 Mar 2013 11:40:54 +0000 Subject: staging: comedi: adv_pci1710: remove iorange member The `iorange` member of `struct boardtype` is initialized but not used. Get rid of it and the macro constants `IORANGE_171x` and `IORANGE_1720`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 52672c53e11e..f847bbc175e7 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -59,9 +59,6 @@ Configuration options: #define TYPE_PCI1713 2 #define TYPE_PCI1720 3 -#define IORANGE_171x 32 -#define IORANGE_1720 16 - #define PCI171x_AD_DATA 0 /* R: A/D data */ #define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */ #define PCI171x_RANGE 2 /* W: A/D gain/range register */ @@ -189,7 +186,6 @@ enum pci1710_boardid { struct boardtype { const char *name; /* board name */ - int iorange; /* I/O range len */ char have_irq; /* 1=card support IRQ */ char cardtype; /* 0=1710& co. 2=1713, ... */ int n_aichan; /* num of A/D chans */ @@ -210,7 +206,6 @@ struct boardtype { static const struct boardtype boardtypes[] = { [BOARD_PCI1710] = { .name = "pci1710", - .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, @@ -229,7 +224,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1710HG] = { .name = "pci1710hg", - .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, @@ -248,7 +242,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1711] = { .name = "pci1711", - .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, @@ -266,7 +259,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1713] = { .name = "pci1713", - .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI1713, .n_aichan = 32, @@ -279,7 +271,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1720] = { .name = "pci1720", - .iorange = IORANGE_1720, .cardtype = TYPE_PCI1720, .n_aochan = 4, .ao_maxdata = 0x0fff, @@ -287,7 +278,6 @@ static const struct boardtype boardtypes[] = { }, [BOARD_PCI1731] = { .name = "pci1731", - .iorange = IORANGE_171x, .have_irq = 1, .cardtype = TYPE_PCI171X, .n_aichan = 16, -- cgit From 44c0186d0c7cf589ba96d7f59246b040dc7408f1 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 14 Mar 2013 22:55:47 +0800 Subject: Staging: netlogic: remove unused variable in xlr_net_start_xmit() The variable 'qmap' is initialized but never used otherwise, so remove the unused variable. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/netlogic/xlr_net.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index efc6172b73b6..dd98cb1468a4 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c @@ -293,10 +293,8 @@ static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb, struct nlm_fmn_msg msg; struct xlr_net_priv *priv = netdev_priv(ndev); int ret; - u16 qmap; u32 flags; - qmap = skb->queue_mapping; xlr_make_tx_desc(&msg, virt_to_phys(skb->data), skb); flags = nlm_cop2_enable(); ret = nlm_fmn_send(2, 0, priv->nd->tx_stnid, &msg); -- cgit From ad76663264f5237a79fd000c95970360dcac7073 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Mar 2013 15:22:40 -0700 Subject: Staging: ccg: remove it from the build This driver has been nothing but trouble, and no one shipping a new Android device uses it, so let's just drop it, making the USB Gadget driver authors lives a whole lot easier as they do their rework. Cc: John Stultz Cc: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 -- drivers/staging/Makefile | 1 - 2 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 95f911022b70..d4775a5de65c 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -116,8 +116,6 @@ source "drivers/staging/android/Kconfig" source "drivers/staging/ozwpan/Kconfig" -source "drivers/staging/ccg/Kconfig" - source "drivers/staging/gdm72xx/Kconfig" source "drivers/staging/csr/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 1c486cbcbe2c..e1ed6ad01c8e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ -obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_CSR_WIFI) += csr/ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ -- cgit From 901cb2ab2c9aaeb16304ff99ebc4af968893c8ec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Mar 2013 15:22:40 -0700 Subject: Staging: ccg: remove it from the build This driver has been nothing but trouble, and no one shipping a new Android device uses it, so let's just drop it, making the USB Gadget driver authors lives a whole lot easier as they do their rework. Cc: John Stultz Cc: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 -- drivers/staging/Makefile | 1 - 2 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 093f10c88cce..659855cecda5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -116,8 +116,6 @@ source "drivers/staging/android/Kconfig" source "drivers/staging/ozwpan/Kconfig" -source "drivers/staging/ccg/Kconfig" - source "drivers/staging/gdm72xx/Kconfig" source "drivers/staging/csr/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fa41b04cf4cb..b367ea876854 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ -obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_CSR_WIFI) += csr/ obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal/ -- cgit From 515e6dd20b3ff1acc94d026935fc4be080a224c5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Mar 2013 15:27:31 -0700 Subject: Staging: ccg: delete it from the tree Now that it isn't in the build, just delete the ccg driver from the tree entirely. Cc: John Stultz Cc: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ccg/Kconfig | 25 - drivers/staging/ccg/Makefile | 2 - drivers/staging/ccg/TODO | 6 - drivers/staging/ccg/ccg.c | 1292 ------------- drivers/staging/ccg/composite.c | 1688 ----------------- drivers/staging/ccg/composite.h | 395 ---- drivers/staging/ccg/config.c | 158 -- drivers/staging/ccg/epautoconf.c | 393 ---- drivers/staging/ccg/f_acm.c | 814 -------- drivers/staging/ccg/f_fs.c | 2455 ------------------------ drivers/staging/ccg/f_mass_storage.c | 3135 ------------------------------- drivers/staging/ccg/f_rndis.c | 918 --------- drivers/staging/ccg/gadget_chips.h | 150 -- drivers/staging/ccg/ndis.h | 47 - drivers/staging/ccg/rndis.c | 1175 ------------ drivers/staging/ccg/rndis.h | 222 --- drivers/staging/ccg/storage_common.c | 893 --------- drivers/staging/ccg/sysfs-class-ccg_usb | 158 -- drivers/staging/ccg/u_ether.c | 986 ---------- drivers/staging/ccg/u_ether.h | 154 -- drivers/staging/ccg/u_serial.c | 1339 ------------- drivers/staging/ccg/u_serial.h | 65 - drivers/staging/ccg/usbstring.c | 71 - 23 files changed, 16541 deletions(-) delete mode 100644 drivers/staging/ccg/Kconfig delete mode 100644 drivers/staging/ccg/Makefile delete mode 100644 drivers/staging/ccg/TODO delete mode 100644 drivers/staging/ccg/ccg.c delete mode 100644 drivers/staging/ccg/composite.c delete mode 100644 drivers/staging/ccg/composite.h delete mode 100644 drivers/staging/ccg/config.c delete mode 100644 drivers/staging/ccg/epautoconf.c delete mode 100644 drivers/staging/ccg/f_acm.c delete mode 100644 drivers/staging/ccg/f_fs.c delete mode 100644 drivers/staging/ccg/f_mass_storage.c delete mode 100644 drivers/staging/ccg/f_rndis.c delete mode 100644 drivers/staging/ccg/gadget_chips.h delete mode 100644 drivers/staging/ccg/ndis.h delete mode 100644 drivers/staging/ccg/rndis.c delete mode 100644 drivers/staging/ccg/rndis.h delete mode 100644 drivers/staging/ccg/storage_common.c delete mode 100644 drivers/staging/ccg/sysfs-class-ccg_usb delete mode 100644 drivers/staging/ccg/u_ether.c delete mode 100644 drivers/staging/ccg/u_ether.h delete mode 100644 drivers/staging/ccg/u_serial.c delete mode 100644 drivers/staging/ccg/u_serial.h delete mode 100644 drivers/staging/ccg/usbstring.c (limited to 'drivers') diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig deleted file mode 100644 index 7ed5bc6caadb..000000000000 --- a/drivers/staging/ccg/Kconfig +++ /dev/null @@ -1,25 +0,0 @@ -if USB_GADGET - -config USB_G_CCG - tristate "Configurable Composite Gadget (STAGING)" - depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM && TTY - help - The Configurable Composite Gadget supports multiple USB - functions: acm, mass storage, rndis and FunctionFS. - Each function can be configured and enabled/disabled - dynamically from userspace through a sysfs interface. - - In order to compile this (either as a module or built-in), - "USB Gadget Drivers" and anything under it must not be - selected compiled-in in - Device Drivers->USB Support->USB Gadget Support. - However, you can say "M" there, if you do, the - Configurable Composite Gadget can be compiled "M" only - or not at all. - - BIG FAT NOTE: DON'T RELY ON THIS USERINTERFACE HERE! AS PART - OF THE REWORK DONE HERE WILL BE A NEW USER INTERFACE WITHOUT ANY - COMPATIBILITY TO THIS SYSFS INTERFACE HERE. BE AWARE OF THIS - BEFORE SELECTING THIS. - -endif # USB_GADGET diff --git a/drivers/staging/ccg/Makefile b/drivers/staging/ccg/Makefile deleted file mode 100644 index 814fa9de5f57..000000000000 --- a/drivers/staging/ccg/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -g_ccg-y := ccg.o -obj-$(CONFIG_USB_G_CCG) += g_ccg.o diff --git a/drivers/staging/ccg/TODO b/drivers/staging/ccg/TODO deleted file mode 100644 index 18612fe70171..000000000000 --- a/drivers/staging/ccg/TODO +++ /dev/null @@ -1,6 +0,0 @@ -TODO: - - change configuration interface from sysfs to configfs - -Please send patches to Greg Kroah-Hartmann , -Andrzej Pietrasiewicz , and -Cc: Mike Lockwood diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c deleted file mode 100644 index ffc5f73a5b5b..000000000000 --- a/drivers/staging/ccg/ccg.c +++ /dev/null @@ -1,1292 +0,0 @@ -/* - * Configurable Composite Gadget - * - * Initially contributed as "Android Composite Gdaget" by: - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * Benoit Goby - * - * Tailoring it to become a generic Configurable Composite Gadget is - * - * Copyright (C) 2012 Samsung Electronics - * Author: Andrzej Pietrasiewicz - * - * 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 "composite.h" -#include - -#include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" -#include "composite.c" - -#include "f_mass_storage.c" -#include "u_serial.c" -#include "f_acm.c" -#define USB_ETH_RNDIS y -#include "f_rndis.c" -#include "rndis.c" -#include "u_ether.c" -#include "f_fs.c" - -MODULE_AUTHOR("Mike Lockwood, Andrzej Pietrasiewicz"); -MODULE_DESCRIPTION("Configurable Composite USB Gadget"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -static const char longname[] = "Configurable Composite Gadget"; - -/* Default vendor and product IDs, overridden by userspace */ -#define VENDOR_ID 0x1d6b /* Linux Foundation */ -#define PRODUCT_ID 0x0107 -#define GFS_MAX_DEVS 10 - -struct ccg_usb_function { - char *name; - void *config; - - struct device *dev; - char *dev_name; - struct device_attribute **attributes; - - /* for ccg_dev.enabled_functions */ - struct list_head enabled_list; - - /* Optional: initialization during gadget bind */ - int (*init)(struct ccg_usb_function *, struct usb_composite_dev *); - /* Optional: cleanup during gadget unbind */ - void (*cleanup)(struct ccg_usb_function *); - - int (*bind_config)(struct ccg_usb_function *, - struct usb_configuration *); - - /* Optional: called when the configuration is removed */ - void (*unbind_config)(struct ccg_usb_function *, - struct usb_configuration *); - /* Optional: handle ctrl requests before the device is configured */ - int (*ctrlrequest)(struct ccg_usb_function *, - struct usb_composite_dev *, - const struct usb_ctrlrequest *); -}; - -struct ffs_obj { - const char *name; - bool mounted; - bool desc_ready; - bool used; - struct ffs_data *ffs_data; -}; - -struct ccg_dev { - struct ccg_usb_function **functions; - struct list_head enabled_functions; - struct usb_composite_dev *cdev; - struct device *dev; - - bool enabled; - struct mutex mutex; - bool connected; - bool sw_connected; - struct work_struct work; - - unsigned int max_func_num; - unsigned int func_num; - struct ffs_obj ffs_tab[GFS_MAX_DEVS]; -}; - -static struct class *ccg_class; -static struct ccg_dev *_ccg_dev; -static int ccg_bind_config(struct usb_configuration *c); -static void ccg_unbind_config(struct usb_configuration *c); - -static char func_names_buf[256]; - -static struct usb_device_descriptor device_desc = { - .bLength = sizeof(device_desc), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .idVendor = __constant_cpu_to_le16(VENDOR_ID), - .idProduct = __constant_cpu_to_le16(PRODUCT_ID), - .bcdDevice = __constant_cpu_to_le16(0xffff), - .bNumConfigurations = 1, -}; - -static struct usb_configuration ccg_config_driver = { - .label = "ccg", - .unbind = ccg_unbind_config, - .bConfigurationValue = 1, - .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 0xFA, /* 500ma */ -}; - -static void ccg_work(struct work_struct *data) -{ - struct ccg_dev *dev = container_of(data, struct ccg_dev, work); - struct usb_composite_dev *cdev = dev->cdev; - static char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; - static char *connected[2] = { "USB_STATE=CONNECTED", NULL }; - static char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; - char **uevent_envp = NULL; - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->config) - uevent_envp = configured; - else if (dev->connected != dev->sw_connected) - uevent_envp = dev->connected ? connected : disconnected; - dev->sw_connected = dev->connected; - spin_unlock_irqrestore(&cdev->lock, flags); - - if (uevent_envp) { - kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp); - pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]); - } else { - pr_info("%s: did not send uevent (%d %d %p)\n", __func__, - dev->connected, dev->sw_connected, cdev->config); - } -} - - -/*-------------------------------------------------------------------------*/ -/* Supported functions initialization */ - -static struct ffs_obj *functionfs_find_dev(struct ccg_dev *dev, - const char *dev_name) -{ - int i; - - for (i = 0; i < dev->max_func_num; i++) - if (strcmp(dev->ffs_tab[i].name, dev_name) == 0) - return &dev->ffs_tab[i]; - - return NULL; -} - -static bool functionfs_all_ready(struct ccg_dev *dev) -{ - int i; - - for (i = 0; i < dev->max_func_num; i++) - if (dev->ffs_tab[i].used && !dev->ffs_tab[i].desc_ready) - return false; - - return true; -} - -static int functionfs_ready_callback(struct ffs_data *ffs) -{ - struct ffs_obj *ffs_obj; - int ret; - - mutex_lock(&_ccg_dev->mutex); - - ffs_obj = ffs->private_data; - if (!ffs_obj) { - ret = -EINVAL; - goto done; - } - if (WARN_ON(ffs_obj->desc_ready)) { - ret = -EBUSY; - goto done; - } - ffs_obj->ffs_data = ffs; - - if (functionfs_all_ready(_ccg_dev)) { - ret = -EBUSY; - goto done; - } - ffs_obj->desc_ready = true; - -done: - mutex_unlock(&_ccg_dev->mutex); - return ret; -} - -static void reset_usb(struct ccg_dev *dev) -{ - /* Cancel pending control requests */ - usb_ep_dequeue(dev->cdev->gadget->ep0, dev->cdev->req); - usb_remove_config(dev->cdev, &ccg_config_driver); - dev->enabled = false; - usb_gadget_disconnect(dev->cdev->gadget); -} - -static void functionfs_closed_callback(struct ffs_data *ffs) -{ - struct ffs_obj *ffs_obj; - - mutex_lock(&_ccg_dev->mutex); - - ffs_obj = ffs->private_data; - if (!ffs_obj) - goto done; - - ffs_obj->desc_ready = false; - - if (_ccg_dev->enabled) - reset_usb(_ccg_dev); - -done: - mutex_unlock(&_ccg_dev->mutex); -} - -static void *functionfs_acquire_dev_callback(const char *dev_name) -{ - struct ffs_obj *ffs_dev; - - mutex_lock(&_ccg_dev->mutex); - - ffs_dev = functionfs_find_dev(_ccg_dev, dev_name); - if (!ffs_dev) { - ffs_dev = ERR_PTR(-ENODEV); - goto done; - } - - if (ffs_dev->mounted) { - ffs_dev = ERR_PTR(-EBUSY); - goto done; - } - ffs_dev->mounted = true; - -done: - mutex_unlock(&_ccg_dev->mutex); - return ffs_dev; -} - -static void functionfs_release_dev_callback(struct ffs_data *ffs_data) -{ - struct ffs_obj *ffs_dev; - - mutex_lock(&_ccg_dev->mutex); - - ffs_dev = ffs_data->private_data; - if (ffs_dev) - ffs_dev->mounted = false; - - mutex_unlock(&_ccg_dev->mutex); -} - -static int functionfs_function_init(struct ccg_usb_function *f, - struct usb_composite_dev *cdev) -{ - return functionfs_init(); -} - -static void functionfs_function_cleanup(struct ccg_usb_function *f) -{ - functionfs_cleanup(); -} - -static int functionfs_function_bind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - struct ccg_dev *dev = _ccg_dev; - int i, ret; - - for (i = dev->max_func_num; i--; ) { - if (!dev->ffs_tab[i].used) - continue; - ret = functionfs_bind(dev->ffs_tab[i].ffs_data, c->cdev); - if (unlikely(ret < 0)) { - while (++i < dev->max_func_num) - functionfs_unbind(dev->ffs_tab[i].ffs_data); - return ret; - } - } - - for (i = dev->max_func_num; i--; ) { - if (!dev->ffs_tab[i].used) - continue; - ret = functionfs_bind_config(c->cdev, c, - dev->ffs_tab[i].ffs_data); - if (unlikely(ret < 0)) - return ret; - } - - return 0; -} - -static void functionfs_function_unbind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - struct ccg_dev *dev = _ccg_dev; - int i; - - for (i = dev->max_func_num; i--; ) - if (dev->ffs_tab[i].ffs_data) - functionfs_unbind(dev->ffs_tab[i].ffs_data); -} - -static ssize_t functionfs_user_functions_show(struct device *_dev, - struct device_attribute *attr, - char *buf) -{ - struct ccg_dev *dev = _ccg_dev; - char *buff = buf; - int i; - - mutex_lock(&dev->mutex); - - for (i = 0; i < dev->max_func_num; i++) - buff += snprintf(buff, PAGE_SIZE + buf - buff, "%s,", - dev->ffs_tab[i].name); - - mutex_unlock(&dev->mutex); - - if (buff != buf) - *(buff - 1) = '\n'; - return buff - buf; -} - -static ssize_t functionfs_user_functions_store(struct device *_dev, - struct device_attribute *attr, - const char *buff, size_t size) -{ - struct ccg_dev *dev = _ccg_dev; - char *name, *b; - ssize_t ret = size; - int i; - - buff = skip_spaces(buff); - if (!*buff) - return -EINVAL; - - mutex_lock(&dev->mutex); - - if (dev->enabled) { - ret = -EBUSY; - goto end; - } - - for (i = 0; i < dev->max_func_num; i++) - if (dev->ffs_tab[i].mounted) { - ret = -EBUSY; - goto end; - } - - strlcpy(func_names_buf, buff, sizeof(func_names_buf)); - b = strim(func_names_buf); - - /* replace the list of functions */ - dev->max_func_num = 0; - while (b) { - name = strsep(&b, ","); - if (dev->max_func_num == GFS_MAX_DEVS) { - ret = -ENOSPC; - goto end; - } - if (functionfs_find_dev(dev, name)) { - ret = -EEXIST; - continue; - } - dev->ffs_tab[dev->max_func_num++].name = name; - } - -end: - mutex_unlock(&dev->mutex); - return ret; -} - -static DEVICE_ATTR(user_functions, S_IRUGO | S_IWUSR, - functionfs_user_functions_show, - functionfs_user_functions_store); - -static ssize_t functionfs_max_user_functions_show(struct device *_dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d", GFS_MAX_DEVS); -} - -static DEVICE_ATTR(max_user_functions, S_IRUGO, - functionfs_max_user_functions_show, NULL); - -static struct device_attribute *functionfs_function_attributes[] = { - &dev_attr_user_functions, - &dev_attr_max_user_functions, - NULL -}; - -static struct ccg_usb_function functionfs_function = { - .name = "fs", - .init = functionfs_function_init, - .cleanup = functionfs_function_cleanup, - .bind_config = functionfs_function_bind_config, - .unbind_config = functionfs_function_unbind_config, - .attributes = functionfs_function_attributes, -}; - -#define MAX_ACM_INSTANCES 4 -struct acm_function_config { - int instances; -}; - -static int -acm_function_init(struct ccg_usb_function *f, struct usb_composite_dev *cdev) -{ - f->config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL); - if (!f->config) - return -ENOMEM; - - return gserial_setup(cdev->gadget, MAX_ACM_INSTANCES); -} - -static void acm_function_cleanup(struct ccg_usb_function *f) -{ - gserial_cleanup(); - kfree(f->config); - f->config = NULL; -} - -static int -acm_function_bind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - int i; - int ret = 0; - struct acm_function_config *config = f->config; - - for (i = 0; i < config->instances; i++) { - ret = acm_bind_config(c, i); - if (ret) { - pr_err("Could not bind acm%u config\n", i); - break; - } - } - - return ret; -} - -static ssize_t acm_instances_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct acm_function_config *config = f->config; - return sprintf(buf, "%d\n", config->instances); -} - -static ssize_t acm_instances_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct acm_function_config *config = f->config; - int value; - int ret = 0; - - ret = kstrtoint(buf, 10, &value); - if (ret) - return ret; - - if (value > MAX_ACM_INSTANCES) - return -EINVAL; - - config->instances = value; - - return size; -} - -static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show, - acm_instances_store); -static struct device_attribute *acm_function_attributes[] = { - &dev_attr_instances, - NULL -}; - -static struct ccg_usb_function acm_function = { - .name = "acm", - .init = acm_function_init, - .cleanup = acm_function_cleanup, - .bind_config = acm_function_bind_config, - .attributes = acm_function_attributes, -}; - -struct rndis_function_config { - u8 ethaddr[ETH_ALEN]; - u32 vendorID; - char manufacturer[256]; - /* "Wireless" RNDIS; auto-detected by Windows */ - bool wceis; -}; - -static int rndis_function_init(struct ccg_usb_function *f, - struct usb_composite_dev *cdev) -{ - f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL); - if (!f->config) - return -ENOMEM; - return 0; -} - -static void rndis_function_cleanup(struct ccg_usb_function *f) -{ - kfree(f->config); - f->config = NULL; -} - -static int rndis_function_bind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - int ret; - struct rndis_function_config *rndis = f->config; - - if (!rndis) { - pr_err("%s: rndis_pdata\n", __func__); - return -1; - } - - pr_info("%s MAC: %pM\n", __func__, rndis->ethaddr); - - ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis"); - if (ret) { - pr_err("%s: gether_setup failed\n", __func__); - return ret; - } - - if (rndis->wceis) { - /* "Wireless" RNDIS; auto-detected by Windows */ - rndis_iad_descriptor.bFunctionClass = - USB_CLASS_WIRELESS_CONTROLLER; - rndis_iad_descriptor.bFunctionSubClass = 0x01; - rndis_iad_descriptor.bFunctionProtocol = 0x03; - rndis_control_intf.bInterfaceClass = - USB_CLASS_WIRELESS_CONTROLLER; - rndis_control_intf.bInterfaceSubClass = 0x01; - rndis_control_intf.bInterfaceProtocol = 0x03; - } - - return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID, - rndis->manufacturer); -} - -static void rndis_function_unbind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - gether_cleanup(); -} - -static ssize_t rndis_manufacturer_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%s\n", config->manufacturer); -} - -static ssize_t rndis_manufacturer_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - - if (size >= sizeof(config->manufacturer)) - return -EINVAL; - memcpy(config->manufacturer, buf, size); - config->manufacturer[size] = 0; - - return size; -} - -static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show, - rndis_manufacturer_store); - -static ssize_t rndis_wceis_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%d\n", config->wceis); -} - -static ssize_t rndis_wceis_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - int value; - int ret; - - ret = kstrtoint(buf, 10, &value); - if (ret) - return ret; - - config->wceis = value; - - return size; -} - -static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show, - rndis_wceis_store); - -static ssize_t rndis_ethaddr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *rndis = f->config; - return sprintf(buf, "%pM\n", rndis->ethaddr); -} - -static ssize_t rndis_ethaddr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *rndis = f->config; - unsigned char tmp[6]; - - if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - tmp + 0, tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5) != - ETH_ALEN) - return -EINVAL; - - memcpy(rndis->ethaddr, tmp, ETH_ALEN); - - return ETH_ALEN; - -} - -static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show, - rndis_ethaddr_store); - -static ssize_t rndis_vendorID_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - return sprintf(buf, "%04x\n", config->vendorID); -} - -static ssize_t rndis_vendorID_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct ccg_usb_function *f = dev_get_drvdata(dev); - struct rndis_function_config *config = f->config; - int value; - int ret; - - ret = kstrtou32(buf, 16, &value); - if (ret) - return ret; - - config->vendorID = value; - - return size; -} - -static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show, - rndis_vendorID_store); - -static struct device_attribute *rndis_function_attributes[] = { - &dev_attr_manufacturer, - &dev_attr_wceis, - &dev_attr_ethaddr, - &dev_attr_vendorID, - NULL -}; - -static struct ccg_usb_function rndis_function = { - .name = "rndis", - .init = rndis_function_init, - .cleanup = rndis_function_cleanup, - .bind_config = rndis_function_bind_config, - .unbind_config = rndis_function_unbind_config, - .attributes = rndis_function_attributes, -}; - -static int mass_storage_function_init(struct ccg_usb_function *f, - struct usb_composite_dev *cdev) -{ - struct fsg_config fsg; - struct fsg_common *common; - int err; - - memset(&fsg, 0, sizeof(fsg)); - fsg.nluns = 1; - fsg.luns[0].removable = 1; - fsg.vendor_name = iManufacturer; - fsg.product_name = iProduct; - - common = fsg_common_init(NULL, cdev, &fsg); - if (IS_ERR(common)) - return PTR_ERR(common); - - err = sysfs_create_link(&f->dev->kobj, - &common->luns[0].dev.kobj, - "lun"); - if (err) { - fsg_common_put(common); - return err; - } - - f->config = common; - return 0; -} - -static void mass_storage_function_cleanup(struct ccg_usb_function *f) -{ - fsg_common_put(f->config); - f->config = NULL; -} - -static int mass_storage_function_bind_config(struct ccg_usb_function *f, - struct usb_configuration *c) -{ - struct fsg_common *common = f->config; - return fsg_bind_config(c->cdev, c, common); -} - -static struct ccg_usb_function mass_storage_function = { - .name = "mass_storage", - .init = mass_storage_function_init, - .cleanup = mass_storage_function_cleanup, - .bind_config = mass_storage_function_bind_config, -}; - -static struct ccg_usb_function *supported_functions[] = { - &functionfs_function, - &acm_function, - &rndis_function, - &mass_storage_function, - NULL -}; - - -static int ccg_init_functions(struct ccg_usb_function **functions, - struct usb_composite_dev *cdev) -{ - struct ccg_dev *dev = _ccg_dev; - struct ccg_usb_function *f; - struct device_attribute **attrs; - struct device_attribute *attr; - int err; - int index = 0; - - for (; (f = *functions++); index++) { - f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name); - if (!f->dev_name) { - pr_err("%s: Failed to alloc name %s", __func__, - f->name); - err = -ENOMEM; - goto err_alloc; - } - f->dev = device_create(ccg_class, dev->dev, - MKDEV(0, index), f, f->dev_name); - if (IS_ERR(f->dev)) { - pr_err("%s: Failed to create dev %s", __func__, - f->dev_name); - err = PTR_ERR(f->dev); - f->dev = NULL; - goto err_create; - } - - if (f->init) { - err = f->init(f, cdev); - if (err) { - pr_err("%s: Failed to init %s", __func__, - f->name); - goto err_out; - } - } - - attrs = f->attributes; - if (attrs) { - while ((attr = *attrs++) && !err) - err = device_create_file(f->dev, attr); - } - if (err) { - pr_err("%s: Failed to create function %s attributes", - __func__, f->name); - goto err_uninit; - } - } - return 0; - -err_uninit: - if (f->cleanup) - f->cleanup(f); -err_out: - device_destroy(ccg_class, f->dev->devt); - f->dev = NULL; -err_create: - kfree(f->dev_name); -err_alloc: - return err; -} - -static void ccg_cleanup_functions(struct ccg_usb_function **functions) -{ - struct ccg_usb_function *f; - - while (*functions) { - f = *functions++; - - if (f->dev) { - if (f->cleanup) - f->cleanup(f); - device_destroy(ccg_class, f->dev->devt); - kfree(f->dev_name); - } - } -} - -static int ccg_bind_enabled_functions(struct ccg_dev *dev, - struct usb_configuration *c) -{ - struct ccg_usb_function *f; - int ret; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - ret = f->bind_config(f, c); - if (ret) { - pr_err("%s: %s failed", __func__, f->name); - return ret; - } - } - return 0; -} - -static void ccg_unbind_enabled_functions(struct ccg_dev *dev, - struct usb_configuration *c) -{ - struct ccg_usb_function *f; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) - if (f->unbind_config) - f->unbind_config(f, c); -} - -static int ccg_enable_function(struct ccg_dev *dev, char *name) -{ - struct ccg_usb_function **functions = dev->functions; - struct ccg_usb_function *f; - while ((f = *functions++)) { - if (!strcmp(name, f->name)) { - list_add_tail(&f->enabled_list, - &dev->enabled_functions); - return 0; - } - } - return -EINVAL; -} - -/*-------------------------------------------------------------------------*/ -/* /sys/class/ccg_usb/ccg%d/ interface */ - -static ssize_t -functions_show(struct device *pdev, struct device_attribute *attr, char *buf) -{ - struct ccg_dev *dev = dev_get_drvdata(pdev); - struct ccg_usb_function *f; - char *buff = buf; - int i; - - mutex_lock(&dev->mutex); - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) - buff += sprintf(buff, "%s,", f->name); - for (i = 0; i < dev->max_func_num; i++) - if (dev->ffs_tab[i].used) - buff += sprintf(buff, "%s", dev->ffs_tab[i].name); - - mutex_unlock(&dev->mutex); - - if (buff != buf) - *(buff-1) = '\n'; - return buff - buf; -} - -static ssize_t -functions_store(struct device *pdev, struct device_attribute *attr, - const char *buff, size_t size) -{ - struct ccg_dev *dev = dev_get_drvdata(pdev); - char *name; - char buf[256], *b; - int err, i; - bool functionfs_enabled; - - buff = skip_spaces(buff); - if (!*buff) - return -EINVAL; - - mutex_lock(&dev->mutex); - - if (dev->enabled) { - mutex_unlock(&dev->mutex); - return -EBUSY; - } - - INIT_LIST_HEAD(&dev->enabled_functions); - functionfs_enabled = false; - for (i = 0; i < dev->max_func_num; i++) - dev->ffs_tab[i].used = false; - - strlcpy(buf, buff, sizeof(buf)); - b = strim(buf); - - while (b) { - struct ffs_obj *user_func; - - name = strsep(&b, ","); - /* handle FunctionFS implicitly */ - if (!strcmp(name, functionfs_function.name)) { - pr_err("ccg_usb: Cannot explicitly enable '%s'", name); - continue; - } - user_func = functionfs_find_dev(dev, name); - if (user_func) - name = functionfs_function.name; - err = 0; - if (!user_func || !functionfs_enabled) - err = ccg_enable_function(dev, name); - if (err) - pr_err("ccg_usb: Cannot enable '%s'", name); - else if (user_func) { - user_func->used = true; - dev->func_num++; - functionfs_enabled = true; - } - } - - mutex_unlock(&dev->mutex); - - return size; -} - -static ssize_t enable_show(struct device *pdev, struct device_attribute *attr, - char *buf) -{ - struct ccg_dev *dev = dev_get_drvdata(pdev); - return sprintf(buf, "%d\n", dev->enabled); -} - -static ssize_t enable_store(struct device *pdev, struct device_attribute *attr, - const char *buff, size_t size) -{ - struct ccg_dev *dev = dev_get_drvdata(pdev); - struct usb_composite_dev *cdev = dev->cdev; - int enabled = 0; - - mutex_lock(&dev->mutex); - sscanf(buff, "%d", &enabled); - if (enabled && dev->func_num && !functionfs_all_ready(dev)) { - mutex_unlock(&dev->mutex); - return -ENODEV; - } - - if (enabled && !dev->enabled) { - int ret; - - cdev->next_string_id = 0; - /* - * Update values in composite driver's copy of - * device descriptor. - */ - cdev->desc.bDeviceClass = device_desc.bDeviceClass; - cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass; - cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol; - cdev->desc.idVendor = idVendor; - cdev->desc.idProduct = idProduct; - cdev->desc.bcdDevice = bcdDevice; - - usb_add_config(cdev, &ccg_config_driver, ccg_bind_config); - dev->enabled = true; - ret = usb_gadget_connect(cdev->gadget); - if (ret) { - dev->enabled = false; - usb_remove_config(cdev, &ccg_config_driver); - } - } else if (!enabled && dev->enabled) { - reset_usb(dev); - } else { - pr_err("ccg_usb: already %s\n", - dev->enabled ? "enabled" : "disabled"); - } - - mutex_unlock(&dev->mutex); - return size; -} - -static ssize_t state_show(struct device *pdev, struct device_attribute *attr, - char *buf) -{ - struct ccg_dev *dev = dev_get_drvdata(pdev); - struct usb_composite_dev *cdev = dev->cdev; - char *state = "DISCONNECTED"; - unsigned long flags; - - if (!cdev) - goto out; - - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->config) - state = "CONFIGURED"; - else if (dev->connected) - state = "CONNECTED"; - spin_unlock_irqrestore(&cdev->lock, flags); -out: - return sprintf(buf, "%s\n", state); -} - -#define DESCRIPTOR_ATTR(field, format_string) \ -static ssize_t \ -field ## _show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - return sprintf(buf, format_string, device_desc.field); \ -} \ -static ssize_t \ -field ## _store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t size) \ -{ \ - int value; \ - if (sscanf(buf, format_string, &value) == 1) { \ - device_desc.field = value; \ - return size; \ - } \ - return -1; \ -} \ -static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store); - -DESCRIPTOR_ATTR(bDeviceClass, "%d\n") -DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n") -DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n") - -static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, - functions_store); -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); -static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); - -static struct device_attribute *ccg_usb_attributes[] = { - &dev_attr_bDeviceClass, - &dev_attr_bDeviceSubClass, - &dev_attr_bDeviceProtocol, - &dev_attr_functions, - &dev_attr_enable, - &dev_attr_state, - NULL -}; - -/*-------------------------------------------------------------------------*/ -/* Composite driver */ - -static int ccg_bind_config(struct usb_configuration *c) -{ - struct ccg_dev *dev = _ccg_dev; - return ccg_bind_enabled_functions(dev, c); -} - -static void ccg_unbind_config(struct usb_configuration *c) -{ - struct ccg_dev *dev = _ccg_dev; - - ccg_unbind_enabled_functions(dev, c); - - usb_ep_autoconfig_reset(dev->cdev->gadget); -} - -static int ccg_bind(struct usb_composite_dev *cdev) -{ - struct ccg_dev *dev = _ccg_dev; - struct usb_gadget *gadget = cdev->gadget; - int gcnum, ret; - - /* - * Start disconnected. Userspace will connect the gadget once - * it is done configuring the functions. - */ - usb_gadget_disconnect(gadget); - - ret = ccg_init_functions(dev->functions, cdev); - if (ret) - return ret; - - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - else { - pr_warn("%s: controller '%s' not recognized\n", - longname, gadget->name); - device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); - } - - usb_gadget_set_selfpowered(gadget); - dev->cdev = cdev; - - return 0; -} - -static int ccg_usb_unbind(struct usb_composite_dev *cdev) -{ - struct ccg_dev *dev = _ccg_dev; - - cancel_work_sync(&dev->work); - ccg_cleanup_functions(dev->functions); - return 0; -} - -static struct usb_composite_driver ccg_usb_driver = { - .name = "configurable_usb", - .dev = &device_desc, - .bind = ccg_bind, - .unbind = ccg_usb_unbind, - .needs_serial = true, - .iManufacturer = "Linux Foundation", - .iProduct = longname, - .iSerialNumber = "1234567890123456", -}; - -static int ccg_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c) -{ - struct ccg_dev *dev = _ccg_dev; - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_request *req = cdev->req; - struct ccg_usb_function *f; - int value = -EOPNOTSUPP; - unsigned long flags; - - req->zero = 0; - req->complete = composite_setup_complete; - req->length = 0; - gadget->ep0->driver_data = cdev; - - list_for_each_entry(f, &dev->enabled_functions, enabled_list) { - if (f->ctrlrequest) { - value = f->ctrlrequest(f, cdev, c); - if (value >= 0) - break; - } - } - - if (value < 0) - value = composite_setup(gadget, c); - - spin_lock_irqsave(&cdev->lock, flags); - if (!dev->connected) { - dev->connected = 1; - schedule_work(&dev->work); - } else if (c->bRequest == USB_REQ_SET_CONFIGURATION && - cdev->config) { - schedule_work(&dev->work); - } - spin_unlock_irqrestore(&cdev->lock, flags); - - return value; -} - -static void ccg_disconnect(struct usb_gadget *gadget) -{ - struct ccg_dev *dev = _ccg_dev; - struct usb_composite_dev *cdev = get_gadget_data(gadget); - unsigned long flags; - - composite_disconnect(gadget); - - spin_lock_irqsave(&cdev->lock, flags); - dev->connected = 0; - schedule_work(&dev->work); - spin_unlock_irqrestore(&cdev->lock, flags); -} - -static int ccg_create_device(struct ccg_dev *dev) -{ - struct device_attribute **attrs = ccg_usb_attributes; - struct device_attribute *attr; - int err; - - dev->dev = device_create(ccg_class, NULL, MKDEV(0, 0), NULL, "ccg0"); - if (IS_ERR(dev->dev)) - return PTR_ERR(dev->dev); - - dev_set_drvdata(dev->dev, dev); - - while ((attr = *attrs++)) { - err = device_create_file(dev->dev, attr); - if (err) { - device_destroy(ccg_class, dev->dev->devt); - return err; - } - } - return 0; -} - - -static int __init ccg_init(void) -{ - struct ccg_dev *dev; - int err; - - ccg_class = class_create(THIS_MODULE, "ccg_usb"); - if (IS_ERR(ccg_class)) - return PTR_ERR(ccg_class); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - class_destroy(ccg_class); - return -ENOMEM; - } - - dev->functions = supported_functions; - INIT_LIST_HEAD(&dev->enabled_functions); - INIT_WORK(&dev->work, ccg_work); - mutex_init(&dev->mutex); - - err = ccg_create_device(dev); - if (err) { - class_destroy(ccg_class); - kfree(dev); - return err; - } - - _ccg_dev = dev; - - /* Override composite driver functions */ - composite_driver.setup = ccg_setup; - composite_driver.disconnect = ccg_disconnect; - - err = usb_composite_probe(&ccg_usb_driver); - if (err) { - class_destroy(ccg_class); - kfree(dev); - } - - return err; -} -module_init(ccg_init); - -static void __exit ccg_exit(void) -{ - usb_composite_unregister(&ccg_usb_driver); - class_destroy(ccg_class); - kfree(_ccg_dev); - _ccg_dev = NULL; -} -module_exit(ccg_exit); diff --git a/drivers/staging/ccg/composite.c b/drivers/staging/ccg/composite.c deleted file mode 100644 index 228b4574f228..000000000000 --- a/drivers/staging/ccg/composite.c +++ /dev/null @@ -1,1688 +0,0 @@ -/* - * composite.c - infrastructure for Composite USB Gadgets - * - * Copyright (C) 2006-2008 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. - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * The code in this file is utility code, used to build a gadget driver - * from one or more "function" drivers, one or more "configuration" - * objects, and a "usb_composite_driver" by gluing them together along - * with the relevant device-wide data. - */ - -/* big enough to hold our biggest descriptor */ -#define USB_BUFSIZ 1024 - -static struct usb_composite_driver *composite; - -/* Some systems will need runtime overrides for the product identifiers - * published in the device descriptor, either numbers or strings or both. - * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). - */ - -static ushort idVendor; -module_param(idVendor, ushort, 0644); -MODULE_PARM_DESC(idVendor, "USB Vendor ID"); - -static ushort idProduct; -module_param(idProduct, ushort, 0644); -MODULE_PARM_DESC(idProduct, "USB Product ID"); - -static ushort bcdDevice; -module_param(bcdDevice, ushort, 0644); -MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); - -static char *iManufacturer; -module_param(iManufacturer, charp, 0644); -MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); - -static char *iProduct; -module_param(iProduct, charp, 0644); -MODULE_PARM_DESC(iProduct, "USB Product string"); - -static char *iSerialNumber; -module_param(iSerialNumber, charp, 0644); -MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); - -static char composite_manufacturer[50]; - -/*-------------------------------------------------------------------------*/ -/** - * next_ep_desc() - advance to the next EP descriptor - * @t: currect pointer within descriptor array - * - * Return: next EP descriptor or NULL - * - * Iterate over @t until either EP descriptor found or - * NULL (that indicates end of list) encountered - */ -static struct usb_descriptor_header** -next_ep_desc(struct usb_descriptor_header **t) -{ - for (; *t; t++) { - if ((*t)->bDescriptorType == USB_DT_ENDPOINT) - return t; - } - return NULL; -} - -/* - * for_each_ep_desc()- iterate over endpoint descriptors in the - * descriptors list - * @start: pointer within descriptor array. - * @ep_desc: endpoint descriptor to use as the loop cursor - */ -#define for_each_ep_desc(start, ep_desc) \ - for (ep_desc = next_ep_desc(start); \ - ep_desc; ep_desc = next_ep_desc(ep_desc+1)) - -/** - * config_ep_by_speed() - configures the given endpoint - * according to gadget speed. - * @g: pointer to the gadget - * @f: usb function - * @_ep: the endpoint to configure - * - * Return: error code, 0 on success - * - * This function chooses the right descriptors for a given - * endpoint according to gadget speed and saves it in the - * endpoint desc field. If the endpoint already has a descriptor - * assigned to it - overwrites it with currently corresponding - * descriptor. The endpoint maxpacket field is updated according - * to the chosen descriptor. - * Note: the supplied function should hold all the descriptors - * for supported speeds - */ -int config_ep_by_speed(struct usb_gadget *g, - struct usb_function *f, - struct usb_ep *_ep) -{ - struct usb_composite_dev *cdev = get_gadget_data(g); - struct usb_endpoint_descriptor *chosen_desc = NULL; - struct usb_descriptor_header **speed_desc = NULL; - - struct usb_ss_ep_comp_descriptor *comp_desc = NULL; - int want_comp_desc = 0; - - struct usb_descriptor_header **d_spd; /* cursor for speed desc */ - - if (!g || !f || !_ep) - return -EIO; - - /* select desired speed */ - switch (g->speed) { - case USB_SPEED_SUPER: - if (gadget_is_superspeed(g)) { - speed_desc = f->ss_descriptors; - want_comp_desc = 1; - break; - } - /* else: Fall trough */ - case USB_SPEED_HIGH: - if (gadget_is_dualspeed(g)) { - speed_desc = f->hs_descriptors; - break; - } - /* else: fall through */ - default: - speed_desc = f->descriptors; - } - /* find descriptors */ - for_each_ep_desc(speed_desc, d_spd) { - chosen_desc = (struct usb_endpoint_descriptor *)*d_spd; - if (chosen_desc->bEndpointAddress == _ep->address) - goto ep_found; - } - return -EIO; - -ep_found: - /* commit results */ - _ep->maxpacket = usb_endpoint_maxp(chosen_desc); - _ep->desc = chosen_desc; - _ep->comp_desc = NULL; - _ep->maxburst = 0; - _ep->mult = 0; - if (!want_comp_desc) - return 0; - - /* - * Companion descriptor should follow EP descriptor - * USB 3.0 spec, #9.6.7 - */ - comp_desc = (struct usb_ss_ep_comp_descriptor *)*(++d_spd); - if (!comp_desc || - (comp_desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP)) - return -EIO; - _ep->comp_desc = comp_desc; - if (g->speed == USB_SPEED_SUPER) { - switch (usb_endpoint_type(_ep->desc)) { - case USB_ENDPOINT_XFER_ISOC: - /* mult: bits 1:0 of bmAttributes */ - _ep->mult = comp_desc->bmAttributes & 0x3; - case USB_ENDPOINT_XFER_BULK: - case USB_ENDPOINT_XFER_INT: - _ep->maxburst = comp_desc->bMaxBurst + 1; - break; - default: - if (comp_desc->bMaxBurst != 0) - ERROR(cdev, "ep0 bMaxBurst must be 0\n"); - _ep->maxburst = 1; - break; - } - } - return 0; -} - -/** - * usb_add_function() - add a function to a configuration - * @config: the configuration - * @function: the function being added - * Context: single threaded during gadget setup - * - * After initialization, each configuration must have one or more - * functions added to it. Adding a function involves calling its @bind() - * method to allocate resources such as interface and string identifiers - * and endpoints. - * - * This function returns the value of the function's bind(), which is - * zero for success else a negative errno value. - */ -int usb_add_function(struct usb_configuration *config, - struct usb_function *function) -{ - int value = -EINVAL; - - DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", - function->name, function, - config->label, config); - - if (!function->set_alt || !function->disable) - goto done; - - function->config = config; - list_add_tail(&function->list, &config->functions); - - /* REVISIT *require* function->bind? */ - if (function->bind) { - value = function->bind(config, function); - if (value < 0) { - list_del(&function->list); - function->config = NULL; - } - } else - value = 0; - - /* We allow configurations that don't work at both speeds. - * If we run into a lowspeed Linux system, treat it the same - * as full speed ... it's the function drivers that will need - * to avoid bulk and ISO transfers. - */ - if (!config->fullspeed && function->descriptors) - config->fullspeed = true; - if (!config->highspeed && function->hs_descriptors) - config->highspeed = true; - if (!config->superspeed && function->ss_descriptors) - config->superspeed = true; - -done: - if (value) - DBG(config->cdev, "adding '%s'/%p --> %d\n", - function->name, function, value); - return value; -} - -/** - * usb_function_deactivate - prevent function and gadget enumeration - * @function: the function that isn't yet ready to respond - * - * Blocks response of the gadget driver to host enumeration by - * preventing the data line pullup from being activated. This is - * normally called during @bind() processing to change from the - * initial "ready to respond" state, or when a required resource - * becomes available. - * - * For example, drivers that serve as a passthrough to a userspace - * daemon can block enumeration unless that daemon (such as an OBEX, - * MTP, or print server) is ready to handle host requests. - * - * Not all systems support software control of their USB peripheral - * data pullups. - * - * Returns zero on success, else negative errno. - */ -int usb_function_deactivate(struct usb_function *function) -{ - struct usb_composite_dev *cdev = function->config->cdev; - unsigned long flags; - int status = 0; - - spin_lock_irqsave(&cdev->lock, flags); - - if (cdev->deactivations == 0) - status = usb_gadget_disconnect(cdev->gadget); - if (status == 0) - cdev->deactivations++; - - spin_unlock_irqrestore(&cdev->lock, flags); - return status; -} - -/** - * usb_function_activate - allow function and gadget enumeration - * @function: function on which usb_function_activate() was called - * - * Reverses effect of usb_function_deactivate(). If no more functions - * are delaying their activation, the gadget driver will respond to - * host enumeration procedures. - * - * Returns zero on success, else negative errno. - */ -int usb_function_activate(struct usb_function *function) -{ - struct usb_composite_dev *cdev = function->config->cdev; - unsigned long flags; - int status = 0; - - spin_lock_irqsave(&cdev->lock, flags); - - if (WARN_ON(cdev->deactivations == 0)) - status = -EINVAL; - else { - cdev->deactivations--; - if (cdev->deactivations == 0) - status = usb_gadget_connect(cdev->gadget); - } - - spin_unlock_irqrestore(&cdev->lock, flags); - return status; -} - -/** - * usb_interface_id() - allocate an unused interface ID - * @config: configuration associated with the interface - * @function: function handling the interface - * Context: single threaded during gadget setup - * - * usb_interface_id() is called from usb_function.bind() callbacks to - * allocate new interface IDs. The function driver will then store that - * ID in interface, association, CDC union, and other descriptors. It - * will also handle any control requests targeted at that interface, - * particularly changing its altsetting via set_alt(). There may - * also be class-specific or vendor-specific requests to handle. - * - * All interface identifier should be allocated using this routine, to - * ensure that for example different functions don't wrongly assign - * different meanings to the same identifier. Note that since interface - * identifiers are configuration-specific, functions used in more than - * one configuration (or more than once in a given configuration) need - * multiple versions of the relevant descriptors. - * - * Returns the interface ID which was allocated; or -ENODEV if no - * more interface IDs can be allocated. - */ -int usb_interface_id(struct usb_configuration *config, - struct usb_function *function) -{ - unsigned id = config->next_interface_id; - - if (id < MAX_CONFIG_INTERFACES) { - config->interface[id] = function; - config->next_interface_id = id + 1; - return id; - } - return -ENODEV; -} - -static int config_buf(struct usb_configuration *config, - enum usb_device_speed speed, void *buf, u8 type) -{ - struct usb_config_descriptor *c = buf; - void *next = buf + USB_DT_CONFIG_SIZE; - int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE; - struct usb_function *f; - int status; - - /* write the config descriptor */ - c = buf; - c->bLength = USB_DT_CONFIG_SIZE; - c->bDescriptorType = type; - /* wTotalLength is written later */ - c->bNumInterfaces = config->next_interface_id; - c->bConfigurationValue = config->bConfigurationValue; - c->iConfiguration = config->iConfiguration; - c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; - c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2); - - /* There may be e.g. OTG descriptors */ - if (config->descriptors) { - status = usb_descriptor_fillbuf(next, len, - config->descriptors); - if (status < 0) - return status; - len -= status; - next += status; - } - - /* add each function's descriptors */ - list_for_each_entry(f, &config->functions, list) { - struct usb_descriptor_header **descriptors; - - switch (speed) { - case USB_SPEED_SUPER: - descriptors = f->ss_descriptors; - break; - case USB_SPEED_HIGH: - descriptors = f->hs_descriptors; - break; - default: - descriptors = f->descriptors; - } - - if (!descriptors) - continue; - status = usb_descriptor_fillbuf(next, len, - (const struct usb_descriptor_header **) descriptors); - if (status < 0) - return status; - len -= status; - next += status; - } - - len = next - buf; - c->wTotalLength = cpu_to_le16(len); - return len; -} - -static int config_desc(struct usb_composite_dev *cdev, unsigned w_value) -{ - struct usb_gadget *gadget = cdev->gadget; - struct usb_configuration *c; - u8 type = w_value >> 8; - enum usb_device_speed speed = USB_SPEED_UNKNOWN; - - if (gadget->speed == USB_SPEED_SUPER) - speed = gadget->speed; - else if (gadget_is_dualspeed(gadget)) { - int hs = 0; - if (gadget->speed == USB_SPEED_HIGH) - hs = 1; - if (type == USB_DT_OTHER_SPEED_CONFIG) - hs = !hs; - if (hs) - speed = USB_SPEED_HIGH; - - } - - /* This is a lookup by config *INDEX* */ - w_value &= 0xff; - list_for_each_entry(c, &cdev->configs, list) { - /* ignore configs that won't work at this speed */ - switch (speed) { - case USB_SPEED_SUPER: - if (!c->superspeed) - continue; - break; - case USB_SPEED_HIGH: - if (!c->highspeed) - continue; - break; - default: - if (!c->fullspeed) - continue; - } - - if (w_value == 0) - return config_buf(c, speed, cdev->req->buf, type); - w_value--; - } - return -EINVAL; -} - -static int count_configs(struct usb_composite_dev *cdev, unsigned type) -{ - struct usb_gadget *gadget = cdev->gadget; - struct usb_configuration *c; - unsigned count = 0; - int hs = 0; - int ss = 0; - - if (gadget_is_dualspeed(gadget)) { - if (gadget->speed == USB_SPEED_HIGH) - hs = 1; - if (gadget->speed == USB_SPEED_SUPER) - ss = 1; - if (type == USB_DT_DEVICE_QUALIFIER) - hs = !hs; - } - list_for_each_entry(c, &cdev->configs, list) { - /* ignore configs that won't work at this speed */ - if (ss) { - if (!c->superspeed) - continue; - } else if (hs) { - if (!c->highspeed) - continue; - } else { - if (!c->fullspeed) - continue; - } - count++; - } - return count; -} - -/** - * bos_desc() - prepares the BOS descriptor. - * @cdev: pointer to usb_composite device to generate the bos - * descriptor for - * - * This function generates the BOS (Binary Device Object) - * descriptor and its device capabilities descriptors. The BOS - * descriptor should be supported by a SuperSpeed device. - */ -static int bos_desc(struct usb_composite_dev *cdev) -{ - struct usb_ext_cap_descriptor *usb_ext; - struct usb_ss_cap_descriptor *ss_cap; - struct usb_dcd_config_params dcd_config_params; - struct usb_bos_descriptor *bos = cdev->req->buf; - - bos->bLength = USB_DT_BOS_SIZE; - bos->bDescriptorType = USB_DT_BOS; - - bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE); - bos->bNumDeviceCaps = 0; - - /* - * A SuperSpeed device shall include the USB2.0 extension descriptor - * and shall support LPM when operating in USB2.0 HS mode. - */ - usb_ext = cdev->req->buf + le16_to_cpu(bos->wTotalLength); - bos->bNumDeviceCaps++; - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_EXT_CAP_SIZE); - usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; - usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; - usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; - usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT); - - /* - * The Superspeed USB Capability descriptor shall be implemented by all - * SuperSpeed devices. - */ - ss_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); - bos->bNumDeviceCaps++; - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SS_CAP_SIZE); - ss_cap->bLength = USB_DT_USB_SS_CAP_SIZE; - ss_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; - ss_cap->bDevCapabilityType = USB_SS_CAP_TYPE; - ss_cap->bmAttributes = 0; /* LTM is not supported yet */ - ss_cap->wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION | - USB_FULL_SPEED_OPERATION | - USB_HIGH_SPEED_OPERATION | - USB_5GBPS_OPERATION); - ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION; - - /* Get Controller configuration */ - if (cdev->gadget->ops->get_config_params) - cdev->gadget->ops->get_config_params(&dcd_config_params); - else { - dcd_config_params.bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT; - dcd_config_params.bU2DevExitLat = - cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT); - } - ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat; - ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat; - - return le16_to_cpu(bos->wTotalLength); -} - -static void device_qual(struct usb_composite_dev *cdev) -{ - struct usb_qualifier_descriptor *qual = cdev->req->buf; - - qual->bLength = sizeof(*qual); - qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER; - /* POLICY: same bcdUSB and device type info at both speeds */ - qual->bcdUSB = cdev->desc.bcdUSB; - qual->bDeviceClass = cdev->desc.bDeviceClass; - qual->bDeviceSubClass = cdev->desc.bDeviceSubClass; - qual->bDeviceProtocol = cdev->desc.bDeviceProtocol; - /* ASSUME same EP0 fifo size at both speeds */ - qual->bMaxPacketSize0 = cdev->gadget->ep0->maxpacket; - qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER); - qual->bRESERVED = 0; -} - -/*-------------------------------------------------------------------------*/ - -static void reset_config(struct usb_composite_dev *cdev) -{ - struct usb_function *f; - - DBG(cdev, "reset config\n"); - - list_for_each_entry(f, &cdev->config->functions, list) { - if (f->disable) - f->disable(f); - - bitmap_zero(f->endpoints, 32); - } - cdev->config = NULL; -} - -static int set_config(struct usb_composite_dev *cdev, - const struct usb_ctrlrequest *ctrl, unsigned number) -{ - struct usb_gadget *gadget = cdev->gadget; - struct usb_configuration *c = NULL; - int result = -EINVAL; - unsigned power = gadget_is_otg(gadget) ? 8 : 100; - int tmp; - - if (number) { - list_for_each_entry(c, &cdev->configs, list) { - if (c->bConfigurationValue == number) { - /* - * We disable the FDs of the previous - * configuration only if the new configuration - * is a valid one - */ - if (cdev->config) - reset_config(cdev); - result = 0; - break; - } - } - if (result < 0) - goto done; - } else { /* Zero configuration value - need to reset the config */ - if (cdev->config) - reset_config(cdev); - result = 0; - } - - INFO(cdev, "%s config #%d: %s\n", - usb_speed_string(gadget->speed), - number, c ? c->label : "unconfigured"); - - if (!c) - goto done; - - cdev->config = c; - - /* Initialize all interfaces by setting them to altsetting zero. */ - for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) { - struct usb_function *f = c->interface[tmp]; - struct usb_descriptor_header **descriptors; - - if (!f) - break; - - /* - * Record which endpoints are used by the function. This is used - * to dispatch control requests targeted at that endpoint to the - * function's setup callback instead of the current - * configuration's setup callback. - */ - switch (gadget->speed) { - case USB_SPEED_SUPER: - descriptors = f->ss_descriptors; - break; - case USB_SPEED_HIGH: - descriptors = f->hs_descriptors; - break; - default: - descriptors = f->descriptors; - } - - for (; *descriptors; ++descriptors) { - struct usb_endpoint_descriptor *ep; - int addr; - - if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT) - continue; - - ep = (struct usb_endpoint_descriptor *)*descriptors; - addr = ((ep->bEndpointAddress & 0x80) >> 3) - | (ep->bEndpointAddress & 0x0f); - set_bit(addr, f->endpoints); - } - - result = f->set_alt(f, tmp, 0); - if (result < 0) { - DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", - tmp, f->name, f, result); - - reset_config(cdev); - goto done; - } - - if (result == USB_GADGET_DELAYED_STATUS) { - DBG(cdev, - "%s: interface %d (%s) requested delayed status\n", - __func__, tmp, f->name); - cdev->delayed_status++; - DBG(cdev, "delayed_status count %d\n", - cdev->delayed_status); - } - } - - /* when we return, be sure our power usage is valid */ - power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; -done: - usb_gadget_vbus_draw(gadget, power); - if (result >= 0 && cdev->delayed_status) - result = USB_GADGET_DELAYED_STATUS; - return result; -} - -/** - * usb_add_config() - add a configuration to a device. - * @cdev: wraps the USB gadget - * @config: the configuration, with bConfigurationValue assigned - * @bind: the configuration's bind function - * Context: single threaded during gadget setup - * - * One of the main tasks of a composite @bind() routine is to - * add each of the configurations it supports, using this routine. - * - * This function returns the value of the configuration's @bind(), which - * is zero for success else a negative errno value. Binding configurations - * assigns global resources including string IDs, and per-configuration - * resources such as interface IDs and endpoints. - */ -int usb_add_config(struct usb_composite_dev *cdev, - struct usb_configuration *config, - int (*bind)(struct usb_configuration *)) -{ - int status = -EINVAL; - struct usb_configuration *c; - - DBG(cdev, "adding config #%u '%s'/%p\n", - config->bConfigurationValue, - config->label, config); - - if (!config->bConfigurationValue || !bind) - goto done; - - /* Prevent duplicate configuration identifiers */ - list_for_each_entry(c, &cdev->configs, list) { - if (c->bConfigurationValue == config->bConfigurationValue) { - status = -EBUSY; - goto done; - } - } - - config->cdev = cdev; - list_add_tail(&config->list, &cdev->configs); - - INIT_LIST_HEAD(&config->functions); - config->next_interface_id = 0; - memset(config->interface, 0, sizeof(config->interface)); - - status = bind(config); - if (status < 0) { - while (!list_empty(&config->functions)) { - struct usb_function *f; - - f = list_first_entry(&config->functions, - struct usb_function, list); - list_del(&f->list); - if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", - f->name, f); - f->unbind(config, f); - /* may free memory for "f" */ - } - } - list_del(&config->list); - config->cdev = NULL; - } else { - unsigned i; - - DBG(cdev, "cfg %d/%p speeds:%s%s%s\n", - config->bConfigurationValue, config, - config->superspeed ? " super" : "", - config->highspeed ? " high" : "", - config->fullspeed - ? (gadget_is_dualspeed(cdev->gadget) - ? " full" - : " full/low") - : ""); - - for (i = 0; i < MAX_CONFIG_INTERFACES; i++) { - struct usb_function *f = config->interface[i]; - - if (!f) - continue; - DBG(cdev, " interface %d = %s/%p\n", - i, f->name, f); - } - } - - /* set_alt(), or next bind(), sets up - * ep->driver_data as needed. - */ - usb_ep_autoconfig_reset(cdev->gadget); - -done: - if (status) - DBG(cdev, "added config '%s'/%u --> %d\n", config->label, - config->bConfigurationValue, status); - return status; -} - -static void remove_config(struct usb_composite_dev *cdev, - struct usb_configuration *config) -{ - while (!list_empty(&config->functions)) { - struct usb_function *f; - - f = list_first_entry(&config->functions, - struct usb_function, list); - list_del(&f->list); - if (f->unbind) { - DBG(cdev, "unbind function '%s'/%p\n", f->name, f); - f->unbind(config, f); - /* may free memory for "f" */ - } - } - list_del(&config->list); - if (config->unbind) { - DBG(cdev, "unbind config '%s'/%p\n", config->label, config); - config->unbind(config); - /* may free memory for "c" */ - } -} - -/** - * usb_remove_config() - remove a configuration from a device. - * @cdev: wraps the USB gadget - * @config: the configuration - * - * Drivers must call usb_gadget_disconnect before calling this function - * to disconnect the device from the host and make sure the host will not - * try to enumerate the device while we are changing the config list. - */ -void usb_remove_config(struct usb_composite_dev *cdev, - struct usb_configuration *config) -{ - unsigned long flags; - - spin_lock_irqsave(&cdev->lock, flags); - - if (cdev->config == config) - reset_config(cdev); - - spin_unlock_irqrestore(&cdev->lock, flags); - - remove_config(cdev, config); -} - -/*-------------------------------------------------------------------------*/ - -/* We support strings in multiple languages ... string descriptor zero - * says which languages are supported. The typical case will be that - * only one language (probably English) is used, with I18N handled on - * the host side. - */ - -static void collect_langs(struct usb_gadget_strings **sp, __le16 *buf) -{ - const struct usb_gadget_strings *s; - __le16 language; - __le16 *tmp; - - while (*sp) { - s = *sp; - language = cpu_to_le16(s->language); - for (tmp = buf; *tmp && tmp < &buf[126]; tmp++) { - if (*tmp == language) - goto repeat; - } - *tmp++ = language; -repeat: - sp++; - } -} - -static int lookup_string( - struct usb_gadget_strings **sp, - void *buf, - u16 language, - int id -) -{ - struct usb_gadget_strings *s; - int value; - - while (*sp) { - s = *sp++; - if (s->language != language) - continue; - value = usb_gadget_get_string(s, id, buf); - if (value > 0) - return value; - } - return -EINVAL; -} - -static int get_string(struct usb_composite_dev *cdev, - void *buf, u16 language, int id) -{ - struct usb_configuration *c; - struct usb_function *f; - int len; - const char *str; - - /* Yes, not only is USB's I18N support probably more than most - * folk will ever care about ... also, it's all supported here. - * (Except for UTF8 support for Unicode's "Astral Planes".) - */ - - /* 0 == report all available language codes */ - if (id == 0) { - struct usb_string_descriptor *s = buf; - struct usb_gadget_strings **sp; - - memset(s, 0, 256); - s->bDescriptorType = USB_DT_STRING; - - sp = composite->strings; - if (sp) - collect_langs(sp, s->wData); - - list_for_each_entry(c, &cdev->configs, list) { - sp = c->strings; - if (sp) - collect_langs(sp, s->wData); - - list_for_each_entry(f, &c->functions, list) { - sp = f->strings; - if (sp) - collect_langs(sp, s->wData); - } - } - - for (len = 0; len <= 126 && s->wData[len]; len++) - continue; - if (!len) - return -EINVAL; - - s->bLength = 2 * (len + 1); - return s->bLength; - } - - /* Otherwise, look up and return a specified string. First - * check if the string has not been overridden. - */ - if (cdev->manufacturer_override == id) - str = iManufacturer ?: composite->iManufacturer ?: - composite_manufacturer; - else if (cdev->product_override == id) - str = iProduct ?: composite->iProduct; - else if (cdev->serial_override == id) - str = iSerialNumber ?: composite->iSerialNumber; - else - str = NULL; - if (str) { - struct usb_gadget_strings strings = { - .language = language, - .strings = &(struct usb_string) { 0xff, str } - }; - return usb_gadget_get_string(&strings, 0xff, buf); - } - - /* String IDs are device-scoped, so we look up each string - * table we're told about. These lookups are infrequent; - * simpler-is-better here. - */ - if (composite->strings) { - len = lookup_string(composite->strings, buf, language, id); - if (len > 0) - return len; - } - list_for_each_entry(c, &cdev->configs, list) { - if (c->strings) { - len = lookup_string(c->strings, buf, language, id); - if (len > 0) - return len; - } - list_for_each_entry(f, &c->functions, list) { - if (!f->strings) - continue; - len = lookup_string(f->strings, buf, language, id); - if (len > 0) - return len; - } - } - return -EINVAL; -} - -/** - * usb_string_id() - allocate an unused string ID - * @cdev: the device whose string descriptor IDs are being allocated - * Context: single threaded during gadget setup - * - * @usb_string_id() is called from bind() callbacks to allocate - * string IDs. Drivers for functions, configurations, or gadgets will - * then store that ID in the appropriate descriptors and string table. - * - * All string identifier should be allocated using this, - * @usb_string_ids_tab() or @usb_string_ids_n() routine, to ensure - * that for example different functions don't wrongly assign different - * meanings to the same identifier. - */ -int usb_string_id(struct usb_composite_dev *cdev) -{ - if (cdev->next_string_id < 254) { - /* string id 0 is reserved by USB spec for list of - * supported languages */ - /* 255 reserved as well? -- mina86 */ - cdev->next_string_id++; - return cdev->next_string_id; - } - return -ENODEV; -} - -/** - * usb_string_ids() - allocate unused string IDs in batch - * @cdev: the device whose string descriptor IDs are being allocated - * @str: an array of usb_string objects to assign numbers to - * Context: single threaded during gadget setup - * - * @usb_string_ids() is called from bind() callbacks to allocate - * string IDs. Drivers for functions, configurations, or gadgets will - * then copy IDs from the string table to the appropriate descriptors - * and string table for other languages. - * - * All string identifier should be allocated using this, - * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for - * example different functions don't wrongly assign different meanings - * to the same identifier. - */ -int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) -{ - int next = cdev->next_string_id; - - for (; str->s; ++str) { - if (unlikely(next >= 254)) - return -ENODEV; - str->id = ++next; - } - - cdev->next_string_id = next; - - return 0; -} - -/** - * usb_string_ids_n() - allocate unused string IDs in batch - * @c: the device whose string descriptor IDs are being allocated - * @n: number of string IDs to allocate - * Context: single threaded during gadget setup - * - * Returns the first requested ID. This ID and next @n-1 IDs are now - * valid IDs. At least provided that @n is non-zero because if it - * is, returns last requested ID which is now very useful information. - * - * @usb_string_ids_n() is called from bind() callbacks to allocate - * string IDs. Drivers for functions, configurations, or gadgets will - * then store that ID in the appropriate descriptors and string table. - * - * All string identifier should be allocated using this, - * @usb_string_id() or @usb_string_ids_n() routine, to ensure that for - * example different functions don't wrongly assign different meanings - * to the same identifier. - */ -int usb_string_ids_n(struct usb_composite_dev *c, unsigned n) -{ - unsigned next = c->next_string_id; - if (unlikely(n > 254 || (unsigned)next + n > 254)) - return -ENODEV; - c->next_string_id += n; - return next + 1; -} - - -/*-------------------------------------------------------------------------*/ - -static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) -{ - if (req->status || req->actual != req->length) - DBG((struct usb_composite_dev *) ep->driver_data, - "setup complete --> %d, %d/%d\n", - req->status, req->actual, req->length); -} - -/* - * The setup() callback implements all the ep0 functionality that's - * not handled lower down, in hardware or the hardware driver(like - * device and endpoint feature flags, and their status). It's all - * housekeeping for the gadget function we're implementing. Most of - * the work is in config and function specific setup. - */ -static int -composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) -{ - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - int status = 0; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u8 intf = w_index & 0xFF; - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - struct usb_function *f = NULL; - u8 endp; - - /* partial re-init of the response message; the function or the - * gadget might need to intercept e.g. a control-OUT completion - * when we delegate to it. - */ - req->zero = 0; - req->complete = composite_setup_complete; - req->length = 0; - gadget->ep0->driver_data = cdev; - - switch (ctrl->bRequest) { - - /* we handle all standard USB descriptors */ - case USB_REQ_GET_DESCRIPTOR: - if (ctrl->bRequestType != USB_DIR_IN) - goto unknown; - switch (w_value >> 8) { - - case USB_DT_DEVICE: - cdev->desc.bNumConfigurations = - count_configs(cdev, USB_DT_DEVICE); - cdev->desc.bMaxPacketSize0 = - cdev->gadget->ep0->maxpacket; - if (gadget_is_superspeed(gadget)) { - if (gadget->speed >= USB_SPEED_SUPER) { - cdev->desc.bcdUSB = cpu_to_le16(0x0300); - cdev->desc.bMaxPacketSize0 = 9; - } else { - cdev->desc.bcdUSB = cpu_to_le16(0x0210); - } - } - - value = min(w_length, (u16) sizeof cdev->desc); - memcpy(req->buf, &cdev->desc, value); - break; - case USB_DT_DEVICE_QUALIFIER: - if (!gadget_is_dualspeed(gadget) || - gadget->speed >= USB_SPEED_SUPER) - break; - device_qual(cdev); - value = min_t(int, w_length, - sizeof(struct usb_qualifier_descriptor)); - break; - case USB_DT_OTHER_SPEED_CONFIG: - if (!gadget_is_dualspeed(gadget) || - gadget->speed >= USB_SPEED_SUPER) - break; - /* FALLTHROUGH */ - case USB_DT_CONFIG: - value = config_desc(cdev, w_value); - if (value >= 0) - value = min(w_length, (u16) value); - break; - case USB_DT_STRING: - value = get_string(cdev, req->buf, - w_index, w_value & 0xff); - if (value >= 0) - value = min(w_length, (u16) value); - break; - case USB_DT_BOS: - if (gadget_is_superspeed(gadget)) { - value = bos_desc(cdev); - value = min(w_length, (u16) value); - } - break; - } - break; - - /* any number of configs can work */ - case USB_REQ_SET_CONFIGURATION: - if (ctrl->bRequestType != 0) - goto unknown; - if (gadget_is_otg(gadget)) { - if (gadget->a_hnp_support) - DBG(cdev, "HNP available\n"); - else if (gadget->a_alt_hnp_support) - DBG(cdev, "HNP on another port\n"); - else - VDBG(cdev, "HNP inactive\n"); - } - spin_lock(&cdev->lock); - value = set_config(cdev, ctrl, w_value); - spin_unlock(&cdev->lock); - break; - case USB_REQ_GET_CONFIGURATION: - if (ctrl->bRequestType != USB_DIR_IN) - goto unknown; - if (cdev->config) - *(u8 *)req->buf = cdev->config->bConfigurationValue; - else - *(u8 *)req->buf = 0; - value = min(w_length, (u16) 1); - break; - - /* function drivers must handle get/set altsetting; if there's - * no get() method, we know only altsetting zero works. - */ - case USB_REQ_SET_INTERFACE: - if (ctrl->bRequestType != USB_RECIP_INTERFACE) - goto unknown; - if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; - if (!f) - break; - if (w_value && !f->set_alt) - break; - value = f->set_alt(f, w_index, w_value); - if (value == USB_GADGET_DELAYED_STATUS) { - DBG(cdev, - "%s: interface %d (%s) requested delayed status\n", - __func__, intf, f->name); - cdev->delayed_status++; - DBG(cdev, "delayed_status count %d\n", - cdev->delayed_status); - } - break; - case USB_REQ_GET_INTERFACE: - if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) - goto unknown; - if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; - if (!f) - break; - /* lots of interfaces only need altsetting zero... */ - value = f->get_alt ? f->get_alt(f, w_index) : 0; - if (value < 0) - break; - *((u8 *)req->buf) = value; - value = min(w_length, (u16) 1); - break; - - /* - * USB 3.0 additions: - * Function driver should handle get_status request. If such cb - * wasn't supplied we respond with default value = 0 - * Note: function driver should supply such cb only for the first - * interface of the function - */ - case USB_REQ_GET_STATUS: - if (!gadget_is_superspeed(gadget)) - goto unknown; - if (ctrl->bRequestType != (USB_DIR_IN | USB_RECIP_INTERFACE)) - goto unknown; - value = 2; /* This is the length of the get_status reply */ - put_unaligned_le16(0, req->buf); - if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; - if (!f) - break; - status = f->get_status ? f->get_status(f) : 0; - if (status < 0) - break; - put_unaligned_le16(status & 0x0000ffff, req->buf); - break; - /* - * Function drivers should handle SetFeature/ClearFeature - * (FUNCTION_SUSPEND) request. function_suspend cb should be supplied - * only for the first interface of the function - */ - case USB_REQ_CLEAR_FEATURE: - case USB_REQ_SET_FEATURE: - if (!gadget_is_superspeed(gadget)) - goto unknown; - if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE)) - goto unknown; - switch (w_value) { - case USB_INTRF_FUNC_SUSPEND: - if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; - if (!f) - break; - value = 0; - if (f->func_suspend) - value = f->func_suspend(f, w_index >> 8); - if (value < 0) { - ERROR(cdev, - "func_suspend() returned error %d\n", - value); - value = 0; - } - break; - } - break; - default: -unknown: - VDBG(cdev, - "non-core control req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - - /* functions always handle their interfaces and endpoints... - * punt other recipients (other, WUSB, ...) to the current - * configuration code. - * - * REVISIT it could make sense to let the composite device - * take such requests too, if that's ever needed: to work - * in config 0, etc. - */ - switch (ctrl->bRequestType & USB_RECIP_MASK) { - case USB_RECIP_INTERFACE: - if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; - break; - - case USB_RECIP_ENDPOINT: - endp = ((w_index & 0x80) >> 3) | (w_index & 0x0f); - list_for_each_entry(f, &cdev->config->functions, list) { - if (test_bit(endp, f->endpoints)) - break; - } - if (&f->list == &cdev->config->functions) - f = NULL; - break; - } - - if (f && f->setup) - value = f->setup(f, ctrl); - else { - struct usb_configuration *c; - - c = cdev->config; - if (c && c->setup) - value = c->setup(c, ctrl); - } - - goto done; - } - - /* respond with data transfer before status phase? */ - if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { - req->length = value; - req->zero = value < w_length; - value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); - if (value < 0) { - DBG(cdev, "ep_queue --> %d\n", value); - req->status = 0; - composite_setup_complete(gadget->ep0, req); - } - } else if (value == USB_GADGET_DELAYED_STATUS && w_length != 0) { - WARN(cdev, - "%s: Delayed status not supported for w_length != 0", - __func__); - } - -done: - /* device either stalls (value < 0) or reports success */ - return value; -} - -static void composite_disconnect(struct usb_gadget *gadget) -{ - struct usb_composite_dev *cdev = get_gadget_data(gadget); - unsigned long flags; - - /* REVISIT: should we have config and device level - * disconnect callbacks? - */ - spin_lock_irqsave(&cdev->lock, flags); - if (cdev->config) - reset_config(cdev); - if (composite->disconnect) - composite->disconnect(cdev); - spin_unlock_irqrestore(&cdev->lock, flags); -} - -/*-------------------------------------------------------------------------*/ - -static ssize_t composite_show_suspended(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct usb_gadget *gadget = dev_to_usb_gadget(dev); - struct usb_composite_dev *cdev = get_gadget_data(gadget); - - return sprintf(buf, "%d\n", cdev->suspended); -} - -static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL); - -static void -composite_unbind(struct usb_gadget *gadget) -{ - struct usb_composite_dev *cdev = get_gadget_data(gadget); - - /* composite_disconnect() must already have been called - * by the underlying peripheral controller driver! - * so there's no i/o concurrency that could affect the - * state protected by cdev->lock. - */ - WARN_ON(cdev->config); - - while (!list_empty(&cdev->configs)) { - struct usb_configuration *c; - c = list_first_entry(&cdev->configs, - struct usb_configuration, list); - remove_config(cdev, c); - } - if (composite->unbind) - composite->unbind(cdev); - - if (cdev->req) { - kfree(cdev->req->buf); - usb_ep_free_request(gadget->ep0, cdev->req); - } - device_remove_file(&gadget->dev, &dev_attr_suspended); - kfree(cdev); - set_gadget_data(gadget, NULL); - composite = NULL; -} - -static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) -{ - if (!*desc) { - int ret = usb_string_id(cdev); - if (unlikely(ret < 0)) - WARNING(cdev, "failed to override string ID\n"); - else - *desc = ret; - } - - return *desc; -} - -static int composite_bind(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) -{ - struct usb_composite_dev *cdev; - int status = -ENOMEM; - - cdev = kzalloc(sizeof *cdev, GFP_KERNEL); - if (!cdev) - return status; - - spin_lock_init(&cdev->lock); - cdev->gadget = gadget; - set_gadget_data(gadget, cdev); - INIT_LIST_HEAD(&cdev->configs); - - /* preallocate control response and buffer */ - cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); - if (!cdev->req) - goto fail; - cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); - if (!cdev->req->buf) - goto fail; - cdev->req->complete = composite_setup_complete; - gadget->ep0->driver_data = cdev; - - cdev->bufsiz = USB_BUFSIZ; - cdev->driver = composite; - - /* - * As per USB compliance update, a device that is actively drawing - * more than 100mA from USB must report itself as bus-powered in - * the GetStatus(DEVICE) call. - */ - if (CONFIG_USB_GADGET_VBUS_DRAW <= USB_SELF_POWER_VBUS_MAX_DRAW) - usb_gadget_set_selfpowered(gadget); - - /* interface and string IDs start at zero via kzalloc. - * we force endpoints to start unassigned; few controller - * drivers will zero ep->driver_data. - */ - usb_ep_autoconfig_reset(cdev->gadget); - - /* composite gadget needs to assign strings for whole device (like - * serial number), register function drivers, potentially update - * power state and consumption, etc - */ - status = composite->bind(cdev); - if (status < 0) - goto fail; - - cdev->desc = *composite->dev; - - /* standardized runtime overrides for device ID data */ - if (idVendor) - cdev->desc.idVendor = cpu_to_le16(idVendor); - else - idVendor = le16_to_cpu(cdev->desc.idVendor); - if (idProduct) - cdev->desc.idProduct = cpu_to_le16(idProduct); - else - idProduct = le16_to_cpu(cdev->desc.idProduct); - if (bcdDevice) - cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); - else - bcdDevice = le16_to_cpu(cdev->desc.bcdDevice); - - /* string overrides */ - if (iManufacturer || !cdev->desc.iManufacturer) { - if (!iManufacturer && !composite->iManufacturer && - !*composite_manufacturer) - snprintf(composite_manufacturer, - sizeof composite_manufacturer, - "%s %s with %s", - init_utsname()->sysname, - init_utsname()->release, - gadget->name); - - cdev->manufacturer_override = - override_id(cdev, &cdev->desc.iManufacturer); - } - - if (iProduct || (!cdev->desc.iProduct && composite->iProduct)) - cdev->product_override = - override_id(cdev, &cdev->desc.iProduct); - - if (iSerialNumber || - (!cdev->desc.iSerialNumber && composite->iSerialNumber)) - cdev->serial_override = - override_id(cdev, &cdev->desc.iSerialNumber); - - /* has userspace failed to provide a serial number? */ - if (composite->needs_serial && !cdev->desc.iSerialNumber) - WARNING(cdev, "userspace failed to provide iSerialNumber\n"); - - /* finish up */ - status = device_create_file(&gadget->dev, &dev_attr_suspended); - if (status) - goto fail; - - INFO(cdev, "%s ready\n", composite->name); - return 0; - -fail: - composite_unbind(gadget); - return status; -} - -/*-------------------------------------------------------------------------*/ - -static void -composite_suspend(struct usb_gadget *gadget) -{ - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_function *f; - - /* REVISIT: should we have config level - * suspend/resume callbacks? - */ - DBG(cdev, "suspend\n"); - if (cdev->config) { - list_for_each_entry(f, &cdev->config->functions, list) { - if (f->suspend) - f->suspend(f); - } - } - if (composite->suspend) - composite->suspend(cdev); - - cdev->suspended = 1; - - usb_gadget_vbus_draw(gadget, 2); -} - -static void -composite_resume(struct usb_gadget *gadget) -{ - struct usb_composite_dev *cdev = get_gadget_data(gadget); - struct usb_function *f; - u8 maxpower; - - /* REVISIT: should we have config level - * suspend/resume callbacks? - */ - DBG(cdev, "resume\n"); - if (composite->resume) - composite->resume(cdev); - if (cdev->config) { - list_for_each_entry(f, &cdev->config->functions, list) { - if (f->resume) - f->resume(f); - } - - maxpower = cdev->config->bMaxPower; - - usb_gadget_vbus_draw(gadget, maxpower ? - (2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW); - } - - cdev->suspended = 0; -} - -/*-------------------------------------------------------------------------*/ - -static struct usb_gadget_driver composite_driver = { - .bind = composite_bind, - .unbind = composite_unbind, - - .setup = composite_setup, - .disconnect = composite_disconnect, - - .suspend = composite_suspend, - .resume = composite_resume, - - .driver = { - .owner = THIS_MODULE, - }, -}; - -/** - * usb_composite_probe() - register a composite driver - * @driver: the driver to register - * @bind: the callback used to allocate resources that are shared across the - * whole device, such as string IDs, and add its configurations using - * @usb_add_config(). This may fail by returning a negative errno - * value; it should return zero on successful initialization. - * Context: single threaded during gadget setup - * - * This function is used to register drivers using the composite driver - * framework. The return value is zero, or a negative errno value. - * Those values normally come from the driver's @bind method, which does - * all the work of setting up the driver to match the hardware. - * - * On successful return, the gadget is ready to respond to requests from - * the host, unless one of its components invokes usb_gadget_disconnect() - * while it was binding. That would usually be done in order to wait for - * some userspace participation. - */ -int usb_composite_probe(struct usb_composite_driver *driver) -{ - if (!driver || !driver->dev || composite || !driver->bind) - return -EINVAL; - - if (!driver->name) - driver->name = "composite"; - if (!driver->iProduct) - driver->iProduct = driver->name; - composite_driver.function = (char *) driver->name; - composite_driver.driver.name = driver->name; - composite_driver.max_speed = driver->max_speed; - composite = driver; - - return usb_gadget_probe_driver(&composite_driver); -} - -/** - * usb_composite_unregister() - unregister a composite driver - * @driver: the driver to unregister - * - * This function is used to unregister drivers using the composite - * driver framework. - */ -void usb_composite_unregister(struct usb_composite_driver *driver) -{ - if (composite != driver) - return; - usb_gadget_unregister_driver(&composite_driver); -} - -/** - * usb_composite_setup_continue() - Continue with the control transfer - * @cdev: the composite device who's control transfer was kept waiting - * - * This function must be called by the USB function driver to continue - * with the control transfer's data/status stage in case it had requested to - * delay the data/status stages. A USB function's setup handler (e.g. set_alt()) - * can request the composite framework to delay the setup request's data/status - * stages by returning USB_GADGET_DELAYED_STATUS. - */ -void usb_composite_setup_continue(struct usb_composite_dev *cdev) -{ - int value; - struct usb_request *req = cdev->req; - unsigned long flags; - - DBG(cdev, "%s\n", __func__); - spin_lock_irqsave(&cdev->lock, flags); - - if (cdev->delayed_status == 0) { - WARN(cdev, "%s: Unexpected call\n", __func__); - - } else if (--cdev->delayed_status == 0) { - DBG(cdev, "%s: Completing delayed status\n", __func__); - req->length = 0; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) { - DBG(cdev, "ep_queue --> %d\n", value); - req->status = 0; - composite_setup_complete(cdev->gadget->ep0, req); - } - } - - spin_unlock_irqrestore(&cdev->lock, flags); -} - diff --git a/drivers/staging/ccg/composite.h b/drivers/staging/ccg/composite.h deleted file mode 100644 index 19a5adf18bf4..000000000000 --- a/drivers/staging/ccg/composite.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - * composite.h -- framework for usb gadgets which are composite devices - * - * Copyright (C) 2006-2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __LINUX_USB_COMPOSITE_H -#define __LINUX_USB_COMPOSITE_H - -/* - * This framework is an optional layer on top of the USB Gadget interface, - * making it easier to build (a) Composite devices, supporting multiple - * functions within any single configuration, and (b) Multi-configuration - * devices, also supporting multiple functions but without necessarily - * having more than one function per configuration. - * - * Example: a device with a single configuration supporting both network - * link and mass storage functions is a composite device. Those functions - * might alternatively be packaged in individual configurations, but in - * the composite model the host can use both functions at the same time. - */ - -#include -#include - -/* - * USB function drivers should return USB_GADGET_DELAYED_STATUS if they - * wish to delay the data/status stages of the control transfer till they - * are ready. The control transfer will then be kept from completing till - * all the function drivers that requested for USB_GADGET_DELAYED_STAUS - * invoke usb_composite_setup_continue(). - */ -#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ - -struct usb_configuration; - -/** - * struct usb_function - describes one function of a configuration - * @name: For diagnostics, identifies the function. - * @strings: tables of strings, keyed by identifiers assigned during bind() - * and by language IDs provided in control requests - * @descriptors: Table of full (or low) speed descriptors, using interface and - * string identifiers assigned during @bind(). If this pointer is null, - * the function will not be available at full speed (or at low speed). - * @hs_descriptors: Table of high speed descriptors, using interface and - * string identifiers assigned during @bind(). If this pointer is null, - * the function will not be available at high speed. - * @ss_descriptors: Table of super speed descriptors, using interface and - * string identifiers assigned during @bind(). If this - * pointer is null after initiation, the function will not - * be available at super speed. - * @config: assigned when @usb_add_function() is called; this is the - * configuration with which this function is associated. - * @bind: Before the gadget can register, all of its functions bind() to the - * available resources including string and interface identifiers used - * in interface or class descriptors; endpoints; I/O buffers; and so on. - * @unbind: Reverses @bind; called as a side effect of unregistering the - * driver which added this function. - * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may - * initialize usb_ep.driver data at this time (when it is used). - * Note that setting an interface to its current altsetting resets - * interface state, and that all interfaces have a disabled state. - * @get_alt: Returns the active altsetting. If this is not provided, - * then only altsetting zero is supported. - * @disable: (REQUIRED) Indicates the function should be disabled. Reasons - * include host resetting or reconfiguring the gadget, and disconnection. - * @setup: Used for interface-specific control requests. - * @suspend: Notifies functions when the host stops sending USB traffic. - * @resume: Notifies functions when the host restarts USB traffic. - * @get_status: Returns function status as a reply to - * GetStatus() request when the recepient is Interface. - * @func_suspend: callback to be called when - * SetFeature(FUNCTION_SUSPEND) is reseived - * - * A single USB function uses one or more interfaces, and should in most - * cases support operation at both full and high speeds. Each function is - * associated by @usb_add_function() with a one configuration; that function - * causes @bind() to be called so resources can be allocated as part of - * setting up a gadget driver. Those resources include endpoints, which - * should be allocated using @usb_ep_autoconfig(). - * - * To support dual speed operation, a function driver provides descriptors - * for both high and full speed operation. Except in rare cases that don't - * involve bulk endpoints, each speed needs different endpoint descriptors. - * - * Function drivers choose their own strategies for managing instance data. - * The simplest strategy just declares it "static', which means the function - * can only be activated once. If the function needs to be exposed in more - * than one configuration at a given speed, it needs to support multiple - * usb_function structures (one for each configuration). - * - * A more complex strategy might encapsulate a @usb_function structure inside - * a driver-specific instance structure to allows multiple activations. An - * example of multiple activations might be a CDC ACM function that supports - * two or more distinct instances within the same configuration, providing - * several independent logical data links to a USB host. - */ -struct usb_function { - const char *name; - struct usb_gadget_strings **strings; - struct usb_descriptor_header **descriptors; - struct usb_descriptor_header **hs_descriptors; - struct usb_descriptor_header **ss_descriptors; - - struct usb_configuration *config; - - /* REVISIT: bind() functions can be marked __init, which - * makes trouble for section mismatch analysis. See if - * we can't restructure things to avoid mismatching. - * Related: unbind() may kfree() but bind() won't... - */ - - /* configuration management: bind/unbind */ - int (*bind)(struct usb_configuration *, - struct usb_function *); - void (*unbind)(struct usb_configuration *, - struct usb_function *); - - /* runtime state management */ - int (*set_alt)(struct usb_function *, - unsigned interface, unsigned alt); - int (*get_alt)(struct usb_function *, - unsigned interface); - void (*disable)(struct usb_function *); - int (*setup)(struct usb_function *, - const struct usb_ctrlrequest *); - void (*suspend)(struct usb_function *); - void (*resume)(struct usb_function *); - - /* USB 3.0 additions */ - int (*get_status)(struct usb_function *); - int (*func_suspend)(struct usb_function *, - u8 suspend_opt); - /* private: */ - /* internals */ - struct list_head list; - DECLARE_BITMAP(endpoints, 32); -}; - -int usb_add_function(struct usb_configuration *, struct usb_function *); - -int usb_function_deactivate(struct usb_function *); -int usb_function_activate(struct usb_function *); - -int usb_interface_id(struct usb_configuration *, struct usb_function *); - -int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, - struct usb_ep *_ep); - -#define MAX_CONFIG_INTERFACES 16 /* arbitrary; max 255 */ - -/** - * struct usb_configuration - represents one gadget configuration - * @label: For diagnostics, describes the configuration. - * @strings: Tables of strings, keyed by identifiers assigned during @bind() - * and by language IDs provided in control requests. - * @descriptors: Table of descriptors preceding all function descriptors. - * Examples include OTG and vendor-specific descriptors. - * @unbind: Reverses @bind; called as a side effect of unregistering the - * driver which added this configuration. - * @setup: Used to delegate control requests that aren't handled by standard - * device infrastructure or directed at a specific interface. - * @bConfigurationValue: Copied into configuration descriptor. - * @iConfiguration: Copied into configuration descriptor. - * @bmAttributes: Copied into configuration descriptor. - * @bMaxPower: Copied into configuration descriptor. - * @cdev: assigned by @usb_add_config() before calling @bind(); this is - * the device associated with this configuration. - * - * Configurations are building blocks for gadget drivers structured around - * function drivers. Simple USB gadgets require only one function and one - * configuration, and handle dual-speed hardware by always providing the same - * functionality. Slightly more complex gadgets may have more than one - * single-function configuration at a given speed; or have configurations - * that only work at one speed. - * - * Composite devices are, by definition, ones with configurations which - * include more than one function. - * - * The lifecycle of a usb_configuration includes allocation, initialization - * of the fields described above, and calling @usb_add_config() to set up - * internal data and bind it to a specific device. The configuration's - * @bind() method is then used to initialize all the functions and then - * call @usb_add_function() for them. - * - * Those functions would normally be independent of each other, but that's - * not mandatory. CDC WMC devices are an example where functions often - * depend on other functions, with some functions subsidiary to others. - * Such interdependency may be managed in any way, so long as all of the - * descriptors complete by the time the composite driver returns from - * its bind() routine. - */ -struct usb_configuration { - const char *label; - struct usb_gadget_strings **strings; - const struct usb_descriptor_header **descriptors; - - /* REVISIT: bind() functions can be marked __init, which - * makes trouble for section mismatch analysis. See if - * we can't restructure things to avoid mismatching... - */ - - /* configuration management: unbind/setup */ - void (*unbind)(struct usb_configuration *); - int (*setup)(struct usb_configuration *, - const struct usb_ctrlrequest *); - - /* fields in the config descriptor */ - u8 bConfigurationValue; - u8 iConfiguration; - u8 bmAttributes; - u8 bMaxPower; - - struct usb_composite_dev *cdev; - - /* private: */ - /* internals */ - struct list_head list; - struct list_head functions; - u8 next_interface_id; - unsigned superspeed:1; - unsigned highspeed:1; - unsigned fullspeed:1; - struct usb_function *interface[MAX_CONFIG_INTERFACES]; -}; - -int usb_add_config(struct usb_composite_dev *, - struct usb_configuration *, - int (*)(struct usb_configuration *)); - -void usb_remove_config(struct usb_composite_dev *, - struct usb_configuration *); - -/** - * struct usb_composite_driver - groups configurations into a gadget - * @name: For diagnostics, identifies the driver. - * @iProduct: Used as iProduct override if @dev->iProduct is not set. - * If NULL value of @name is taken. - * @iManufacturer: Used as iManufacturer override if @dev->iManufacturer is - * not set. If NULL a default " with " value - * will be used. - * @iSerialNumber: Used as iSerialNumber override if @dev->iSerialNumber is - * not set. - * @dev: Template descriptor for the device, including default device - * identifiers. - * @strings: tables of strings, keyed by identifiers assigned during @bind - * and language IDs provided in control requests - * @max_speed: Highest speed the driver supports. - * @needs_serial: set to 1 if the gadget needs userspace to provide - * a serial number. If one is not provided, warning will be printed. - * @bind: (REQUIRED) Used to allocate resources that are shared across the - * whole device, such as string IDs, and add its configurations using - * @usb_add_config(). This may fail by returning a negative errno - * value; it should return zero on successful initialization. - * @unbind: Reverses @bind; called as a side effect of unregistering - * this driver. - * @disconnect: optional driver disconnect method - * @suspend: Notifies when the host stops sending USB traffic, - * after function notifications - * @resume: Notifies configuration when the host restarts USB traffic, - * before function notifications - * - * Devices default to reporting self powered operation. Devices which rely - * on bus powered operation should report this in their @bind method. - * - * Before returning from @bind, various fields in the template descriptor - * may be overridden. These include the idVendor/idProduct/bcdDevice values - * normally to bind the appropriate host side driver, and the three strings - * (iManufacturer, iProduct, iSerialNumber) normally used to provide user - * meaningful device identifiers. (The strings will not be defined unless - * they are defined in @dev and @strings.) The correct ep0 maxpacket size - * is also reported, as defined by the underlying controller driver. - */ -struct usb_composite_driver { - const char *name; - const char *iProduct; - const char *iManufacturer; - const char *iSerialNumber; - const struct usb_device_descriptor *dev; - struct usb_gadget_strings **strings; - enum usb_device_speed max_speed; - unsigned needs_serial:1; - - int (*bind)(struct usb_composite_dev *cdev); - int (*unbind)(struct usb_composite_dev *); - - void (*disconnect)(struct usb_composite_dev *); - - /* global suspend hooks */ - void (*suspend)(struct usb_composite_dev *); - void (*resume)(struct usb_composite_dev *); -}; - -extern int usb_composite_probe(struct usb_composite_driver *driver); -extern void usb_composite_unregister(struct usb_composite_driver *driver); -extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); - - -/** - * struct usb_composite_device - represents one composite usb gadget - * @gadget: read-only, abstracts the gadget's usb peripheral controller - * @req: used for control responses; buffer is pre-allocated - * @bufsiz: size of buffer pre-allocated in @req - * @config: the currently active configuration - * - * One of these devices is allocated and initialized before the - * associated device driver's bind() is called. - * - * OPEN ISSUE: it appears that some WUSB devices will need to be - * built by combining a normal (wired) gadget with a wireless one. - * This revision of the gadget framework should probably try to make - * sure doing that won't hurt too much. - * - * One notion for how to handle Wireless USB devices involves: - * (a) a second gadget here, discovery mechanism TBD, but likely - * needing separate "register/unregister WUSB gadget" calls; - * (b) updates to usb_gadget to include flags "is it wireless", - * "is it wired", plus (presumably in a wrapper structure) - * bandgroup and PHY info; - * (c) presumably a wireless_ep wrapping a usb_ep, and reporting - * wireless-specific parameters like maxburst and maxsequence; - * (d) configurations that are specific to wireless links; - * (e) function drivers that understand wireless configs and will - * support wireless for (additional) function instances; - * (f) a function to support association setup (like CBAF), not - * necessarily requiring a wireless adapter; - * (g) composite device setup that can create one or more wireless - * configs, including appropriate association setup support; - * (h) more, TBD. - */ -struct usb_composite_dev { - struct usb_gadget *gadget; - struct usb_request *req; - unsigned bufsiz; - - struct usb_configuration *config; - - /* private: */ - /* internals */ - unsigned int suspended:1; - struct usb_device_descriptor desc; - struct list_head configs; - struct usb_composite_driver *driver; - u8 next_string_id; - u8 manufacturer_override; - u8 product_override; - u8 serial_override; - - /* the gadget driver won't enable the data pullup - * while the deactivation count is nonzero. - */ - unsigned deactivations; - - /* the composite driver won't complete the control transfer's - * data/status stages till delayed_status is zero. - */ - int delayed_status; - - /* protects deactivations and delayed_status counts*/ - spinlock_t lock; -}; - -extern int usb_string_id(struct usb_composite_dev *c); -extern int usb_string_ids_tab(struct usb_composite_dev *c, - struct usb_string *str); -extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n); - - -/* messaging utils */ -#define DBG(d, fmt, args...) \ - dev_dbg(&(d)->gadget->dev , fmt , ## args) -#define VDBG(d, fmt, args...) \ - dev_vdbg(&(d)->gadget->dev , fmt , ## args) -#define ERROR(d, fmt, args...) \ - dev_err(&(d)->gadget->dev , fmt , ## args) -#define WARNING(d, fmt, args...) \ - dev_warn(&(d)->gadget->dev , fmt , ## args) -#define INFO(d, fmt, args...) \ - dev_info(&(d)->gadget->dev , fmt , ## args) - -#endif /* __LINUX_USB_COMPOSITE_H */ diff --git a/drivers/staging/ccg/config.c b/drivers/staging/ccg/config.c deleted file mode 100644 index 7542a72ce51a..000000000000 --- a/drivers/staging/ccg/config.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * usb/gadget/config.c -- simplify building config descriptors - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - - -/** - * usb_descriptor_fillbuf - fill buffer with descriptors - * @buf: Buffer to be filled - * @buflen: Size of buf - * @src: Array of descriptor pointers, terminated by null pointer. - * - * Copies descriptors into the buffer, returning the length or a - * negative error code if they can't all be copied. Useful when - * assembling descriptors for an associated set of interfaces used - * as part of configuring a composite device; or in other cases where - * sets of descriptors need to be marshaled. - */ -int -usb_descriptor_fillbuf(void *buf, unsigned buflen, - const struct usb_descriptor_header **src) -{ - u8 *dest = buf; - - if (!src) - return -EINVAL; - - /* fill buffer from src[] until null descriptor ptr */ - for (; NULL != *src; src++) { - unsigned len = (*src)->bLength; - - if (len > buflen) - return -EINVAL; - memcpy(dest, *src, len); - buflen -= len; - dest += len; - } - return dest - (u8 *)buf; -} - - -/** - * usb_gadget_config_buf - builts a complete configuration descriptor - * @config: Header for the descriptor, including characteristics such - * as power requirements and number of interfaces. - * @desc: Null-terminated vector of pointers to the descriptors (interface, - * endpoint, etc) defining all functions in this device configuration. - * @buf: Buffer for the resulting configuration descriptor. - * @length: Length of buffer. If this is not big enough to hold the - * entire configuration descriptor, an error code will be returned. - * - * This copies descriptors into the response buffer, building a descriptor - * for that configuration. It returns the buffer length or a negative - * status code. The config.wTotalLength field is set to match the length - * of the result, but other descriptor fields (including power usage and - * interface count) must be set by the caller. - * - * Gadget drivers could use this when constructing a config descriptor - * in response to USB_REQ_GET_DESCRIPTOR. They will need to patch the - * resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed. - */ -int usb_gadget_config_buf( - const struct usb_config_descriptor *config, - void *buf, - unsigned length, - const struct usb_descriptor_header **desc -) -{ - struct usb_config_descriptor *cp = buf; - int len; - - /* config descriptor first */ - if (length < USB_DT_CONFIG_SIZE || !desc) - return -EINVAL; - *cp = *config; - - /* then interface/endpoint/class/vendor/... */ - len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf, - length - USB_DT_CONFIG_SIZE, desc); - if (len < 0) - return len; - len += USB_DT_CONFIG_SIZE; - if (len > 0xffff) - return -EINVAL; - - /* patch up the config descriptor */ - cp->bLength = USB_DT_CONFIG_SIZE; - cp->bDescriptorType = USB_DT_CONFIG; - cp->wTotalLength = cpu_to_le16(len); - cp->bmAttributes |= USB_CONFIG_ATT_ONE; - return len; -} - -/** - * usb_copy_descriptors - copy a vector of USB descriptors - * @src: null-terminated vector to copy - * Context: initialization code, which may sleep - * - * This makes a copy of a vector of USB descriptors. Its primary use - * is to support usb_function objects which can have multiple copies, - * each needing different descriptors. Functions may have static - * tables of descriptors, which are used as templates and customized - * with identifiers (for interfaces, strings, endpoints, and more) - * as needed by a given function instance. - */ -struct usb_descriptor_header ** -usb_copy_descriptors(struct usb_descriptor_header **src) -{ - struct usb_descriptor_header **tmp; - unsigned bytes; - unsigned n_desc; - void *mem; - struct usb_descriptor_header **ret; - - /* count descriptors and their sizes; then add vector size */ - for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++) - bytes += (*tmp)->bLength; - bytes += (n_desc + 1) * sizeof(*tmp); - - mem = kmalloc(bytes, GFP_KERNEL); - if (!mem) - return NULL; - - /* fill in pointers starting at "tmp", - * to descriptors copied starting at "mem"; - * and return "ret" - */ - tmp = mem; - ret = mem; - mem += (n_desc + 1) * sizeof(*tmp); - while (*src) { - memcpy(mem, *src, (*src)->bLength); - *tmp = mem; - tmp++; - mem += (*src)->bLength; - src++; - } - *tmp = NULL; - - return ret; -} - diff --git a/drivers/staging/ccg/epautoconf.c b/drivers/staging/ccg/epautoconf.c deleted file mode 100644 index 51f3d42f5a64..000000000000 --- a/drivers/staging/ccg/epautoconf.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers - * - * Copyright (C) 2004 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. - */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "gadget_chips.h" - - -/* we must assign addresses for configurable endpoints (like net2280) */ -static unsigned epnum; - -// #define MANY_ENDPOINTS -#ifdef MANY_ENDPOINTS -/* more than 15 configurable endpoints */ -static unsigned in_epnum; -#endif - - -/* - * This should work with endpoints from controller drivers sharing the - * same endpoint naming convention. By example: - * - * - ep1, ep2, ... address is fixed, not direction or type - * - ep1in, ep2out, ... address and direction are fixed, not type - * - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction - * - ep1in-bulk, ep2out-iso, ... all three are fixed - * - ep-* ... no functionality restrictions - * - * Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal. - * Less common restrictions are implied by gadget_is_*(). - * - * NOTE: each endpoint is unidirectional, as specified by its USB - * descriptor; and isn't specific to a configuration or altsetting. - */ -static int -ep_matches ( - struct usb_gadget *gadget, - struct usb_ep *ep, - struct usb_endpoint_descriptor *desc, - struct usb_ss_ep_comp_descriptor *ep_comp -) -{ - u8 type; - const char *tmp; - u16 max; - - int num_req_streams = 0; - - /* endpoint already claimed? */ - if (NULL != ep->driver_data) - return 0; - - /* only support ep0 for portable CONTROL traffic */ - type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (USB_ENDPOINT_XFER_CONTROL == type) - return 0; - - /* some other naming convention */ - if ('e' != ep->name[0]) - return 0; - - /* type-restriction: "-iso", "-bulk", or "-int". - * direction-restriction: "in", "out". - */ - if ('-' != ep->name[2]) { - tmp = strrchr (ep->name, '-'); - if (tmp) { - switch (type) { - case USB_ENDPOINT_XFER_INT: - /* bulk endpoints handle interrupt transfers, - * except the toggle-quirky iso-synch kind - */ - if ('s' == tmp[2]) // == "-iso" - return 0; - /* for now, avoid PXA "interrupt-in"; - * it's documented as never using DATA1. - */ - if (gadget_is_pxa (gadget) - && 'i' == tmp [1]) - return 0; - break; - case USB_ENDPOINT_XFER_BULK: - if ('b' != tmp[1]) // != "-bulk" - return 0; - break; - case USB_ENDPOINT_XFER_ISOC: - if ('s' != tmp[2]) // != "-iso" - return 0; - } - } else { - tmp = ep->name + strlen (ep->name); - } - - /* direction-restriction: "..in-..", "out-.." */ - tmp--; - if (!isdigit (*tmp)) { - if (desc->bEndpointAddress & USB_DIR_IN) { - if ('n' != *tmp) - return 0; - } else { - if ('t' != *tmp) - return 0; - } - } - } - - /* - * Get the number of required streams from the EP companion - * descriptor and see if the EP matches it - */ - if (usb_endpoint_xfer_bulk(desc)) { - if (ep_comp && gadget->max_speed >= USB_SPEED_SUPER) { - num_req_streams = ep_comp->bmAttributes & 0x1f; - if (num_req_streams > ep->max_streams) - return 0; - } - - } - - /* - * If the protocol driver hasn't yet decided on wMaxPacketSize - * and wants to know the maximum possible, provide the info. - */ - if (desc->wMaxPacketSize == 0) - desc->wMaxPacketSize = cpu_to_le16(ep->maxpacket); - - /* endpoint maxpacket size is an input parameter, except for bulk - * where it's an output parameter representing the full speed limit. - * the usb spec fixes high speed bulk maxpacket at 512 bytes. - */ - max = 0x7ff & usb_endpoint_maxp(desc); - switch (type) { - case USB_ENDPOINT_XFER_INT: - /* INT: limit 64 bytes full speed, 1024 high/super speed */ - if (!gadget_is_dualspeed(gadget) && max > 64) - return 0; - /* FALLTHROUGH */ - - case USB_ENDPOINT_XFER_ISOC: - /* ISO: limit 1023 bytes full speed, 1024 high/super speed */ - if (ep->maxpacket < max) - return 0; - if (!gadget_is_dualspeed(gadget) && max > 1023) - return 0; - - /* BOTH: "high bandwidth" works only at high speed */ - if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { - if (!gadget_is_dualspeed(gadget)) - return 0; - /* configure your hardware with enough buffering!! */ - } - break; - } - - /* MATCH!! */ - - /* report address */ - desc->bEndpointAddress &= USB_DIR_IN; - if (isdigit (ep->name [2])) { - u8 num = simple_strtoul (&ep->name [2], NULL, 10); - desc->bEndpointAddress |= num; -#ifdef MANY_ENDPOINTS - } else if (desc->bEndpointAddress & USB_DIR_IN) { - if (++in_epnum > 15) - return 0; - desc->bEndpointAddress = USB_DIR_IN | in_epnum; -#endif - } else { - if (++epnum > 15) - return 0; - desc->bEndpointAddress |= epnum; - } - - /* report (variable) full speed bulk maxpacket */ - if ((USB_ENDPOINT_XFER_BULK == type) && !ep_comp) { - int size = ep->maxpacket; - - /* min() doesn't work on bitfields with gcc-3.5 */ - if (size > 64) - size = 64; - desc->wMaxPacketSize = cpu_to_le16(size); - } - ep->address = desc->bEndpointAddress; - return 1; -} - -static struct usb_ep * -find_ep (struct usb_gadget *gadget, const char *name) -{ - struct usb_ep *ep; - - list_for_each_entry (ep, &gadget->ep_list, ep_list) { - if (0 == strcmp (ep->name, name)) - return ep; - } - return NULL; -} - -/** - * usb_ep_autoconfig_ss() - choose an endpoint matching the ep - * descriptor and ep companion descriptor - * @gadget: The device to which the endpoint must belong. - * @desc: Endpoint descriptor, with endpoint direction and transfer mode - * initialized. For periodic transfers, the maximum packet - * size must also be initialized. This is modified on - * success. - * @ep_comp: Endpoint companion descriptor, with the required - * number of streams. Will be modified when the chosen EP - * supports a different number of streams. - * - * This routine replaces the usb_ep_autoconfig when needed - * superspeed enhancments. If such enhancemnets are required, - * the FD should call usb_ep_autoconfig_ss directly and provide - * the additional ep_comp parameter. - * - * By choosing an endpoint to use with the specified descriptor, - * this routine simplifies writing gadget drivers that work with - * multiple USB device controllers. The endpoint would be - * passed later to usb_ep_enable(), along with some descriptor. - * - * That second descriptor won't always be the same as the first one. - * For example, isochronous endpoints can be autoconfigured for high - * bandwidth, and then used in several lower bandwidth altsettings. - * Also, high and full speed descriptors will be different. - * - * Be sure to examine and test the results of autoconfiguration - * on your hardware. This code may not make the best choices - * about how to use the USB controller, and it can't know all - * the restrictions that may apply. Some combinations of driver - * and hardware won't be able to autoconfigure. - * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint - * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value - * is initialized as if the endpoint were used at full speed and - * the bmAttribute field in the ep companion descriptor is - * updated with the assigned number of streams if it is - * different from the original value. To prevent the endpoint - * from being returned by a later autoconfig call, claim it by - * assigning ep->driver_data to some non-null value. - * - * On failure, this returns a null endpoint descriptor. - */ -struct usb_ep *usb_ep_autoconfig_ss( - struct usb_gadget *gadget, - struct usb_endpoint_descriptor *desc, - struct usb_ss_ep_comp_descriptor *ep_comp -) -{ - struct usb_ep *ep; - u8 type; - - type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - - /* First, apply chip-specific "best usage" knowledge. - * This might make a good usb_gadget_ops hook ... - */ - if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) { - /* ep-e, ep-f are PIO with only 64 byte fifos */ - ep = find_ep (gadget, "ep-e"); - if (ep && ep_matches(gadget, ep, desc, ep_comp)) - goto found_ep; - ep = find_ep (gadget, "ep-f"); - if (ep && ep_matches(gadget, ep, desc, ep_comp)) - goto found_ep; - - } else if (gadget_is_goku (gadget)) { - if (USB_ENDPOINT_XFER_INT == type) { - /* single buffering is enough */ - ep = find_ep(gadget, "ep3-bulk"); - if (ep && ep_matches(gadget, ep, desc, ep_comp)) - goto found_ep; - } else if (USB_ENDPOINT_XFER_BULK == type - && (USB_DIR_IN & desc->bEndpointAddress)) { - /* DMA may be available */ - ep = find_ep(gadget, "ep2-bulk"); - if (ep && ep_matches(gadget, ep, desc, - ep_comp)) - goto found_ep; - } - -#ifdef CONFIG_BLACKFIN - } else if (gadget_is_musbhdrc(gadget)) { - if ((USB_ENDPOINT_XFER_BULK == type) || - (USB_ENDPOINT_XFER_ISOC == type)) { - if (USB_DIR_IN & desc->bEndpointAddress) - ep = find_ep (gadget, "ep5in"); - else - ep = find_ep (gadget, "ep6out"); - } else if (USB_ENDPOINT_XFER_INT == type) { - if (USB_DIR_IN & desc->bEndpointAddress) - ep = find_ep(gadget, "ep1in"); - else - ep = find_ep(gadget, "ep2out"); - } else - ep = NULL; - if (ep && ep_matches(gadget, ep, desc, ep_comp)) - goto found_ep; -#endif - } - - /* Second, look at endpoints until an unclaimed one looks usable */ - list_for_each_entry (ep, &gadget->ep_list, ep_list) { - if (ep_matches(gadget, ep, desc, ep_comp)) - goto found_ep; - } - - /* Fail */ - return NULL; -found_ep: - ep->desc = NULL; - ep->comp_desc = NULL; - return ep; -} - -/** - * usb_ep_autoconfig() - choose an endpoint matching the - * descriptor - * @gadget: The device to which the endpoint must belong. - * @desc: Endpoint descriptor, with endpoint direction and transfer mode - * initialized. For periodic transfers, the maximum packet - * size must also be initialized. This is modified on success. - * - * By choosing an endpoint to use with the specified descriptor, this - * routine simplifies writing gadget drivers that work with multiple - * USB device controllers. The endpoint would be passed later to - * usb_ep_enable(), along with some descriptor. - * - * That second descriptor won't always be the same as the first one. - * For example, isochronous endpoints can be autoconfigured for high - * bandwidth, and then used in several lower bandwidth altsettings. - * Also, high and full speed descriptors will be different. - * - * Be sure to examine and test the results of autoconfiguration on your - * hardware. This code may not make the best choices about how to use the - * USB controller, and it can't know all the restrictions that may apply. - * Some combinations of driver and hardware won't be able to autoconfigure. - * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint - * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value - * is initialized as if the endpoint were used at full speed. To prevent - * the endpoint from being returned by a later autoconfig call, claim it - * by assigning ep->driver_data to some non-null value. - * - * On failure, this returns a null endpoint descriptor. - */ -struct usb_ep *usb_ep_autoconfig( - struct usb_gadget *gadget, - struct usb_endpoint_descriptor *desc -) -{ - return usb_ep_autoconfig_ss(gadget, desc, NULL); -} - - -/** - * usb_ep_autoconfig_reset - reset endpoint autoconfig state - * @gadget: device for which autoconfig state will be reset - * - * Use this for devices where one configuration may need to assign - * endpoint resources very differently from the next one. It clears - * state such as ep->driver_data and the record of assigned endpoints - * used by usb_ep_autoconfig(). - */ -void usb_ep_autoconfig_reset (struct usb_gadget *gadget) -{ - struct usb_ep *ep; - - list_for_each_entry (ep, &gadget->ep_list, ep_list) { - ep->driver_data = NULL; - } -#ifdef MANY_ENDPOINTS - in_epnum = 0; -#endif - epnum = 0; -} - diff --git a/drivers/staging/ccg/f_acm.c b/drivers/staging/ccg/f_acm.c deleted file mode 100644 index d672250a61fa..000000000000 --- a/drivers/staging/ccg/f_acm.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * f_acm.c -- USB CDC serial (ACM) function driver - * - * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) - * Copyright (C) 2008 by David Brownell - * Copyright (C) 2008 by Nokia Corporation - * Copyright (C) 2009 by Samsung Electronics - * Author: Michal Nazarewicz (mina86@mina86.com) - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include - -#include "u_serial.h" -#include "gadget_chips.h" - - -/* - * This CDC ACM function support just wraps control functions and - * notifications around the generic serial-over-usb code. - * - * Because CDC ACM is standardized by the USB-IF, many host operating - * systems have drivers for it. Accordingly, ACM is the preferred - * interop solution for serial-port type connections. The control - * models are often not necessary, and in any case don't do much in - * this bare-bones implementation. - * - * Note that even MS-Windows has some support for ACM. However, that - * support is somewhat broken because when you use ACM in a composite - * device, having multiple interfaces confuses the poor OS. It doesn't - * seem to understand CDC Union descriptors. The new "association" - * descriptors (roughly equivalent to CDC Unions) may sometimes help. - */ - -struct f_acm { - struct gserial port; - u8 ctrl_id, data_id; - u8 port_num; - - u8 pending; - - /* lock is mostly for pending and notify_req ... they get accessed - * by callbacks both from tty (open/close/break) under its spinlock, - * and notify_req.complete() which can't use that lock. - */ - spinlock_t lock; - - struct usb_ep *notify; - struct usb_request *notify_req; - - struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ - - /* SetControlLineState request -- CDC 1.1 section 6.2.14 (INPUT) */ - u16 port_handshake_bits; -#define ACM_CTRL_RTS (1 << 1) /* unused with full duplex */ -#define ACM_CTRL_DTR (1 << 0) /* host is ready for data r/w */ - - /* SerialState notification -- CDC 1.1 section 6.3.5 (OUTPUT) */ - u16 serial_state; -#define ACM_CTRL_OVERRUN (1 << 6) -#define ACM_CTRL_PARITY (1 << 5) -#define ACM_CTRL_FRAMING (1 << 4) -#define ACM_CTRL_RI (1 << 3) -#define ACM_CTRL_BRK (1 << 2) -#define ACM_CTRL_DSR (1 << 1) -#define ACM_CTRL_DCD (1 << 0) -}; - -static inline struct f_acm *func_to_acm(struct usb_function *f) -{ - return container_of(f, struct f_acm, port.func); -} - -static inline struct f_acm *port_to_acm(struct gserial *p) -{ - return container_of(p, struct f_acm, port); -} - -/*-------------------------------------------------------------------------*/ - -/* notification endpoint uses smallish and infrequent fixed-size messages */ - -#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ -#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */ - -/* interface and class descriptors: */ - -static struct usb_interface_assoc_descriptor -acm_iad_descriptor = { - .bLength = sizeof acm_iad_descriptor, - .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - - /* .bFirstInterface = DYNAMIC, */ - .bInterfaceCount = 2, // control + data - .bFunctionClass = USB_CLASS_COMM, - .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, - .bFunctionProtocol = USB_CDC_ACM_PROTO_AT_V25TER, - /* .iFunction = DYNAMIC */ -}; - - -static struct usb_interface_descriptor acm_control_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - /* .bInterfaceNumber = DYNAMIC */ - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = USB_CDC_ACM_PROTO_AT_V25TER, - /* .iInterface = DYNAMIC */ -}; - -static struct usb_interface_descriptor acm_data_interface_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - /* .bInterfaceNumber = DYNAMIC */ - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_CDC_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - /* .iInterface = DYNAMIC */ -}; - -static struct usb_cdc_header_desc acm_header_desc = { - .bLength = sizeof(acm_header_desc), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_HEADER_TYPE, - .bcdCDC = cpu_to_le16(0x0110), -}; - -static struct usb_cdc_call_mgmt_descriptor -acm_call_mgmt_descriptor = { - .bLength = sizeof(acm_call_mgmt_descriptor), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, - .bmCapabilities = 0, - /* .bDataInterface = DYNAMIC */ -}; - -static struct usb_cdc_acm_descriptor acm_descriptor = { - .bLength = sizeof(acm_descriptor), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_ACM_TYPE, - .bmCapabilities = USB_CDC_CAP_LINE, -}; - -static struct usb_cdc_union_desc acm_union_desc = { - .bLength = sizeof(acm_union_desc), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_UNION_TYPE, - /* .bMasterInterface0 = DYNAMIC */ - /* .bSlaveInterface0 = DYNAMIC */ -}; - -/* full speed support: */ - -static struct usb_endpoint_descriptor acm_fs_notify_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), - .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, -}; - -static struct usb_endpoint_descriptor acm_fs_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor acm_fs_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *acm_fs_function[] = { - (struct usb_descriptor_header *) &acm_iad_descriptor, - (struct usb_descriptor_header *) &acm_control_interface_desc, - (struct usb_descriptor_header *) &acm_header_desc, - (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, - (struct usb_descriptor_header *) &acm_descriptor, - (struct usb_descriptor_header *) &acm_union_desc, - (struct usb_descriptor_header *) &acm_fs_notify_desc, - (struct usb_descriptor_header *) &acm_data_interface_desc, - (struct usb_descriptor_header *) &acm_fs_in_desc, - (struct usb_descriptor_header *) &acm_fs_out_desc, - NULL, -}; - -/* high speed support: */ - -static struct usb_endpoint_descriptor acm_hs_notify_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), - .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, -}; - -static struct usb_endpoint_descriptor acm_hs_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor acm_hs_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_descriptor_header *acm_hs_function[] = { - (struct usb_descriptor_header *) &acm_iad_descriptor, - (struct usb_descriptor_header *) &acm_control_interface_desc, - (struct usb_descriptor_header *) &acm_header_desc, - (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, - (struct usb_descriptor_header *) &acm_descriptor, - (struct usb_descriptor_header *) &acm_union_desc, - (struct usb_descriptor_header *) &acm_hs_notify_desc, - (struct usb_descriptor_header *) &acm_data_interface_desc, - (struct usb_descriptor_header *) &acm_hs_in_desc, - (struct usb_descriptor_header *) &acm_hs_out_desc, - NULL, -}; - -static struct usb_endpoint_descriptor acm_ss_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_endpoint_descriptor acm_ss_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc = { - .bLength = sizeof acm_ss_bulk_comp_desc, - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -}; - -static struct usb_descriptor_header *acm_ss_function[] = { - (struct usb_descriptor_header *) &acm_iad_descriptor, - (struct usb_descriptor_header *) &acm_control_interface_desc, - (struct usb_descriptor_header *) &acm_header_desc, - (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, - (struct usb_descriptor_header *) &acm_descriptor, - (struct usb_descriptor_header *) &acm_union_desc, - (struct usb_descriptor_header *) &acm_hs_notify_desc, - (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, - (struct usb_descriptor_header *) &acm_data_interface_desc, - (struct usb_descriptor_header *) &acm_ss_in_desc, - (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, - (struct usb_descriptor_header *) &acm_ss_out_desc, - (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, - NULL, -}; - -/* string descriptors: */ - -#define ACM_CTRL_IDX 0 -#define ACM_DATA_IDX 1 -#define ACM_IAD_IDX 2 - -/* static strings, in UTF-8 */ -static struct usb_string acm_string_defs[] = { - [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)", - [ACM_DATA_IDX].s = "CDC ACM Data", - [ACM_IAD_IDX ].s = "CDC Serial", - { /* ZEROES END LIST */ }, -}; - -static struct usb_gadget_strings acm_string_table = { - .language = 0x0409, /* en-us */ - .strings = acm_string_defs, -}; - -static struct usb_gadget_strings *acm_strings[] = { - &acm_string_table, - NULL, -}; - -/*-------------------------------------------------------------------------*/ - -/* ACM control ... data handling is delegated to tty library code. - * The main task of this function is to activate and deactivate - * that code based on device state; track parameters like line - * speed, handshake state, and so on; and issue notifications. - */ - -static void acm_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req) -{ - struct f_acm *acm = ep->driver_data; - struct usb_composite_dev *cdev = acm->port.func.config->cdev; - - if (req->status != 0) { - DBG(cdev, "acm ttyGS%d completion, err %d\n", - acm->port_num, req->status); - return; - } - - /* normal completion */ - if (req->actual != sizeof(acm->port_line_coding)) { - DBG(cdev, "acm ttyGS%d short resp, len %d\n", - acm->port_num, req->actual); - usb_ep_set_halt(ep); - } else { - struct usb_cdc_line_coding *value = req->buf; - - /* REVISIT: we currently just remember this data. - * If we change that, (a) validate it first, then - * (b) update whatever hardware needs updating, - * (c) worry about locking. This is information on - * the order of 9600-8-N-1 ... most of which means - * nothing unless we control a real RS232 line. - */ - acm->port_line_coding = *value; - } -} - -static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -{ - struct f_acm *acm = func_to_acm(f); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - /* composite driver infrastructure handles everything except - * CDC class messages; interface activation uses set_alt(). - * - * Note CDC spec table 4 lists the ACM request profile. It requires - * encapsulated command support ... we don't handle any, and respond - * to them by stalling. Options include get/set/clear comm features - * (not that useful) and SEND_BREAK. - */ - switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { - - /* SET_LINE_CODING ... just read and save what the host sends */ - case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) - | USB_CDC_REQ_SET_LINE_CODING: - if (w_length != sizeof(struct usb_cdc_line_coding) - || w_index != acm->ctrl_id) - goto invalid; - - value = w_length; - cdev->gadget->ep0->driver_data = acm; - req->complete = acm_complete_set_line_coding; - break; - - /* GET_LINE_CODING ... return what host sent, or initial value */ - case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) - | USB_CDC_REQ_GET_LINE_CODING: - if (w_index != acm->ctrl_id) - goto invalid; - - value = min_t(unsigned, w_length, - sizeof(struct usb_cdc_line_coding)); - memcpy(req->buf, &acm->port_line_coding, value); - break; - - /* SET_CONTROL_LINE_STATE ... save what the host sent */ - case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) - | USB_CDC_REQ_SET_CONTROL_LINE_STATE: - if (w_index != acm->ctrl_id) - goto invalid; - - value = 0; - - /* FIXME we should not allow data to flow until the - * host sets the ACM_CTRL_DTR bit; and when it clears - * that bit, we should return to that no-flow state. - */ - acm->port_handshake_bits = w_value; - break; - - default: -invalid: - VDBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - } - - /* respond with data transfer or status phase? */ - if (value >= 0) { - DBG(cdev, "acm ttyGS%d req%02x.%02x v%04x i%04x l%d\n", - acm->port_num, ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - req->zero = 0; - req->length = value; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) - ERROR(cdev, "acm response on ttyGS%d, err %d\n", - acm->port_num, value); - } - - /* device either stalls (value < 0) or reports success */ - return value; -} - -static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -{ - struct f_acm *acm = func_to_acm(f); - struct usb_composite_dev *cdev = f->config->cdev; - - /* we know alt == 0, so this is an activation or a reset */ - - if (intf == acm->ctrl_id) { - if (acm->notify->driver_data) { - VDBG(cdev, "reset acm control interface %d\n", intf); - usb_ep_disable(acm->notify); - } else { - VDBG(cdev, "init acm ctrl interface %d\n", intf); - if (config_ep_by_speed(cdev->gadget, f, acm->notify)) - return -EINVAL; - } - usb_ep_enable(acm->notify); - acm->notify->driver_data = acm; - - } else if (intf == acm->data_id) { - if (acm->port.in->driver_data) { - DBG(cdev, "reset acm ttyGS%d\n", acm->port_num); - gserial_disconnect(&acm->port); - } - if (!acm->port.in->desc || !acm->port.out->desc) { - DBG(cdev, "activate acm ttyGS%d\n", acm->port_num); - if (config_ep_by_speed(cdev->gadget, f, - acm->port.in) || - config_ep_by_speed(cdev->gadget, f, - acm->port.out)) { - acm->port.in->desc = NULL; - acm->port.out->desc = NULL; - return -EINVAL; - } - } - gserial_connect(&acm->port, acm->port_num); - - } else - return -EINVAL; - - return 0; -} - -static void acm_disable(struct usb_function *f) -{ - struct f_acm *acm = func_to_acm(f); - struct usb_composite_dev *cdev = f->config->cdev; - - DBG(cdev, "acm ttyGS%d deactivated\n", acm->port_num); - gserial_disconnect(&acm->port); - usb_ep_disable(acm->notify); - acm->notify->driver_data = NULL; -} - -/*-------------------------------------------------------------------------*/ - -/** - * acm_cdc_notify - issue CDC notification to host - * @acm: wraps host to be notified - * @type: notification type - * @value: Refer to cdc specs, wValue field. - * @data: data to be sent - * @length: size of data - * Context: irqs blocked, acm->lock held, acm_notify_req non-null - * - * Returns zero on success or a negative errno. - * - * See section 6.3.5 of the CDC 1.1 specification for information - * about the only notification we issue: SerialState change. - */ -static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value, - void *data, unsigned length) -{ - struct usb_ep *ep = acm->notify; - struct usb_request *req; - struct usb_cdc_notification *notify; - const unsigned len = sizeof(*notify) + length; - void *buf; - int status; - - req = acm->notify_req; - acm->notify_req = NULL; - acm->pending = false; - - req->length = len; - notify = req->buf; - buf = notify + 1; - - notify->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS - | USB_RECIP_INTERFACE; - notify->bNotificationType = type; - notify->wValue = cpu_to_le16(value); - notify->wIndex = cpu_to_le16(acm->ctrl_id); - notify->wLength = cpu_to_le16(length); - memcpy(buf, data, length); - - /* ep_queue() can complete immediately if it fills the fifo... */ - spin_unlock(&acm->lock); - status = usb_ep_queue(ep, req, GFP_ATOMIC); - spin_lock(&acm->lock); - - if (status < 0) { - ERROR(acm->port.func.config->cdev, - "acm ttyGS%d can't notify serial state, %d\n", - acm->port_num, status); - acm->notify_req = req; - } - - return status; -} - -static int acm_notify_serial_state(struct f_acm *acm) -{ - struct usb_composite_dev *cdev = acm->port.func.config->cdev; - int status; - - spin_lock(&acm->lock); - if (acm->notify_req) { - DBG(cdev, "acm ttyGS%d serial state %04x\n", - acm->port_num, acm->serial_state); - status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE, - 0, &acm->serial_state, sizeof(acm->serial_state)); - } else { - acm->pending = true; - status = 0; - } - spin_unlock(&acm->lock); - return status; -} - -static void acm_cdc_notify_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_acm *acm = req->context; - u8 doit = false; - - /* on this call path we do NOT hold the port spinlock, - * which is why ACM needs its own spinlock - */ - spin_lock(&acm->lock); - if (req->status != -ESHUTDOWN) - doit = acm->pending; - acm->notify_req = req; - spin_unlock(&acm->lock); - - if (doit) - acm_notify_serial_state(acm); -} - -/* connect == the TTY link is open */ - -static void acm_connect(struct gserial *port) -{ - struct f_acm *acm = port_to_acm(port); - - acm->serial_state |= ACM_CTRL_DSR | ACM_CTRL_DCD; - acm_notify_serial_state(acm); -} - -static void acm_disconnect(struct gserial *port) -{ - struct f_acm *acm = port_to_acm(port); - - acm->serial_state &= ~(ACM_CTRL_DSR | ACM_CTRL_DCD); - acm_notify_serial_state(acm); -} - -static int acm_send_break(struct gserial *port, int duration) -{ - struct f_acm *acm = port_to_acm(port); - u16 state; - - state = acm->serial_state; - state &= ~ACM_CTRL_BRK; - if (duration) - state |= ACM_CTRL_BRK; - - acm->serial_state = state; - return acm_notify_serial_state(acm); -} - -/*-------------------------------------------------------------------------*/ - -/* ACM function driver setup/binding */ -static int -acm_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct f_acm *acm = func_to_acm(f); - int status; - struct usb_ep *ep; - - /* allocate instance-specific interface IDs, and patch descriptors */ - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - acm->ctrl_id = status; - acm_iad_descriptor.bFirstInterface = status; - - acm_control_interface_desc.bInterfaceNumber = status; - acm_union_desc .bMasterInterface0 = status; - - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - acm->data_id = status; - - acm_data_interface_desc.bInterfaceNumber = status; - acm_union_desc.bSlaveInterface0 = status; - acm_call_mgmt_descriptor.bDataInterface = status; - - status = -ENODEV; - - /* allocate instance-specific endpoints */ - ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_in_desc); - if (!ep) - goto fail; - acm->port.in = ep; - ep->driver_data = cdev; /* claim */ - - ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); - if (!ep) - goto fail; - acm->port.out = ep; - ep->driver_data = cdev; /* claim */ - - ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); - if (!ep) - goto fail; - acm->notify = ep; - ep->driver_data = cdev; /* claim */ - - /* allocate notification */ - acm->notify_req = gs_alloc_req(ep, - sizeof(struct usb_cdc_notification) + 2, - GFP_KERNEL); - if (!acm->notify_req) - goto fail; - - acm->notify_req->complete = acm_cdc_notify_complete; - acm->notify_req->context = acm; - - /* copy descriptors */ - f->descriptors = usb_copy_descriptors(acm_fs_function); - if (!f->descriptors) - goto fail; - - /* support all relevant hardware speeds... we expect that when - * hardware is dual speed, all bulk-capable endpoints work at - * both speeds - */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - acm_hs_in_desc.bEndpointAddress = - acm_fs_in_desc.bEndpointAddress; - acm_hs_out_desc.bEndpointAddress = - acm_fs_out_desc.bEndpointAddress; - acm_hs_notify_desc.bEndpointAddress = - acm_fs_notify_desc.bEndpointAddress; - - /* copy descriptors */ - f->hs_descriptors = usb_copy_descriptors(acm_hs_function); - } - if (gadget_is_superspeed(c->cdev->gadget)) { - acm_ss_in_desc.bEndpointAddress = - acm_fs_in_desc.bEndpointAddress; - acm_ss_out_desc.bEndpointAddress = - acm_fs_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(acm_ss_function); - if (!f->ss_descriptors) - goto fail; - } - - DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", - acm->port_num, - gadget_is_superspeed(c->cdev->gadget) ? "super" : - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - acm->port.in->name, acm->port.out->name, - acm->notify->name); - return 0; - -fail: - if (acm->notify_req) - gs_free_req(acm->notify, acm->notify_req); - - /* we might as well release our claims on endpoints */ - if (acm->notify) - acm->notify->driver_data = NULL; - if (acm->port.out) - acm->port.out->driver_data = NULL; - if (acm->port.in) - acm->port.in->driver_data = NULL; - - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); - - return status; -} - -static void -acm_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_acm *acm = func_to_acm(f); - - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - usb_free_descriptors(f->descriptors); - gs_free_req(acm->notify, acm->notify_req); - kfree(acm); -} - -/* Some controllers can't support CDC ACM ... */ -static inline bool can_support_cdc(struct usb_configuration *c) -{ - /* everything else is *probably* fine ... */ - return true; -} - -/** - * acm_bind_config - add a CDC ACM function to a configuration - * @c: the configuration to support the CDC ACM instance - * @port_num: /dev/ttyGS* port this interface will use - * Context: single threaded during gadget setup - * - * Returns zero on success, else negative errno. - * - * Caller must have called @gserial_setup() with enough ports to - * handle all the ones it binds. Caller is also responsible - * for calling @gserial_cleanup() before module unload. - */ -int acm_bind_config(struct usb_configuration *c, u8 port_num) -{ - struct f_acm *acm; - int status; - - if (!can_support_cdc(c)) - return -EINVAL; - - /* REVISIT might want instance-specific strings to help - * distinguish instances ... - */ - - /* maybe allocate device-global string IDs, and patch descriptors */ - if (acm_string_defs[ACM_CTRL_IDX].id == 0) { - status = usb_string_id(c->cdev); - if (status < 0) - return status; - acm_string_defs[ACM_CTRL_IDX].id = status; - - acm_control_interface_desc.iInterface = status; - - status = usb_string_id(c->cdev); - if (status < 0) - return status; - acm_string_defs[ACM_DATA_IDX].id = status; - - acm_data_interface_desc.iInterface = status; - - status = usb_string_id(c->cdev); - if (status < 0) - return status; - acm_string_defs[ACM_IAD_IDX].id = status; - - acm_iad_descriptor.iFunction = status; - } - - /* allocate and initialize one new instance */ - acm = kzalloc(sizeof *acm, GFP_KERNEL); - if (!acm) - return -ENOMEM; - - spin_lock_init(&acm->lock); - - acm->port_num = port_num; - - acm->port.connect = acm_connect; - acm->port.disconnect = acm_disconnect; - acm->port.send_break = acm_send_break; - - acm->port.func.name = "acm"; - acm->port.func.strings = acm_strings; - /* descriptors are per-instance copies */ - acm->port.func.bind = acm_bind; - acm->port.func.unbind = acm_unbind; - acm->port.func.set_alt = acm_set_alt; - acm->port.func.setup = acm_setup; - acm->port.func.disable = acm_disable; - - status = usb_add_function(c, &acm->port.func); - if (status) - kfree(acm); - return status; -} diff --git a/drivers/staging/ccg/f_fs.c b/drivers/staging/ccg/f_fs.c deleted file mode 100644 index 8adc79d1b402..000000000000 --- a/drivers/staging/ccg/f_fs.c +++ /dev/null @@ -1,2455 +0,0 @@ -/* - * f_fs.c -- user mode file system API for USB composite function controllers - * - * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz - * - * Based on inode.c (GadgetFS) which was: - * Copyright (C) 2003-2004 David Brownell - * Copyright (C) 2003 Agilent Technologies - * - * 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. - */ - - -/* #define DEBUG */ -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include - -#include -#include - - -#define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ - - -/* Debugging ****************************************************************/ - -#ifdef VERBOSE_DEBUG -# define pr_vdebug pr_debug -# define ffs_dump_mem(prefix, ptr, len) \ - print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) -#else -# define pr_vdebug(...) do { } while (0) -# define ffs_dump_mem(prefix, ptr, len) do { } while (0) -#endif /* VERBOSE_DEBUG */ - -#define ENTER() pr_vdebug("%s()\n", __func__) - - -/* The data structure and setup file ****************************************/ - -enum ffs_state { - /* - * Waiting for descriptors and strings. - * - * In this state no open(2), read(2) or write(2) on epfiles - * may succeed (which should not be the problem as there - * should be no such files opened in the first place). - */ - FFS_READ_DESCRIPTORS, - FFS_READ_STRINGS, - - /* - * We've got descriptors and strings. We are or have called - * functionfs_ready_callback(). functionfs_bind() may have - * been called but we don't know. - * - * This is the only state in which operations on epfiles may - * succeed. - */ - FFS_ACTIVE, - - /* - * All endpoints have been closed. This state is also set if - * we encounter an unrecoverable error. The only - * unrecoverable error is situation when after reading strings - * from user space we fail to initialise epfiles or - * functionfs_ready_callback() returns with error (<0). - * - * In this state no open(2), read(2) or write(2) (both on ep0 - * as well as epfile) may succeed (at this point epfiles are - * unlinked and all closed so this is not a problem; ep0 is - * also closed but ep0 file exists and so open(2) on ep0 must - * fail). - */ - FFS_CLOSING -}; - - -enum ffs_setup_state { - /* There is no setup request pending. */ - FFS_NO_SETUP, - /* - * User has read events and there was a setup request event - * there. The next read/write on ep0 will handle the - * request. - */ - FFS_SETUP_PENDING, - /* - * There was event pending but before user space handled it - * some other event was introduced which canceled existing - * setup. If this state is set read/write on ep0 return - * -EIDRM. This state is only set when adding event. - */ - FFS_SETUP_CANCELED -}; - - - -struct ffs_epfile; -struct ffs_function; - -struct ffs_data { - struct usb_gadget *gadget; - - /* - * Protect access read/write operations, only one read/write - * at a time. As a consequence protects ep0req and company. - * While setup request is being processed (queued) this is - * held. - */ - struct mutex mutex; - - /* - * Protect access to endpoint related structures (basically - * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for - * endpoint zero. - */ - spinlock_t eps_lock; - - /* - * XXX REVISIT do we need our own request? Since we are not - * handling setup requests immediately user space may be so - * slow that another setup will be sent to the gadget but this - * time not to us but another function and then there could be - * a race. Is that the case? Or maybe we can use cdev->req - * after all, maybe we just need some spinlock for that? - */ - struct usb_request *ep0req; /* P: mutex */ - struct completion ep0req_completion; /* P: mutex */ - int ep0req_status; /* P: mutex */ - - /* reference counter */ - atomic_t ref; - /* how many files are opened (EP0 and others) */ - atomic_t opened; - - /* EP0 state */ - enum ffs_state state; - - /* - * Possible transitions: - * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock - * happens only in ep0 read which is P: mutex - * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock - * happens only in ep0 i/o which is P: mutex - * + FFS_SETUP_PENDING -> FFS_SETUP_CANCELED -- P: ev.waitq.lock - * + FFS_SETUP_CANCELED -> FFS_NO_SETUP -- cmpxchg - */ - enum ffs_setup_state setup_state; - -#define FFS_SETUP_STATE(ffs) \ - ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state, \ - FFS_SETUP_CANCELED, FFS_NO_SETUP)) - - /* Events & such. */ - struct { - u8 types[4]; - unsigned short count; - /* XXX REVISIT need to update it in some places, or do we? */ - unsigned short can_stall; - struct usb_ctrlrequest setup; - - wait_queue_head_t waitq; - } ev; /* the whole structure, P: ev.waitq.lock */ - - /* Flags */ - unsigned long flags; -#define FFS_FL_CALL_CLOSED_CALLBACK 0 -#define FFS_FL_BOUND 1 - - /* Active function */ - struct ffs_function *func; - - /* - * Device name, write once when file system is mounted. - * Intended for user to read if she wants. - */ - const char *dev_name; - /* Private data for our user (ie. gadget). Managed by user. */ - void *private_data; - - /* filled by __ffs_data_got_descs() */ - /* - * Real descriptors are 16 bytes after raw_descs (so you need - * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the - * first full speed descriptor). raw_descs_length and - * raw_fs_descs_length do not have those 16 bytes added. - */ - const void *raw_descs; - unsigned raw_descs_length; - unsigned raw_fs_descs_length; - unsigned fs_descs_count; - unsigned hs_descs_count; - - unsigned short strings_count; - unsigned short interfaces_count; - unsigned short eps_count; - unsigned short _pad1; - - /* filled by __ffs_data_got_strings() */ - /* ids in stringtabs are set in functionfs_bind() */ - const void *raw_strings; - struct usb_gadget_strings **stringtabs; - - /* - * File system's super block, write once when file system is - * mounted. - */ - struct super_block *sb; - - /* File permissions, written once when fs is mounted */ - struct ffs_file_perms { - umode_t mode; - uid_t uid; - gid_t gid; - } file_perms; - - /* - * The endpoint files, filled by ffs_epfiles_create(), - * destroyed by ffs_epfiles_destroy(). - */ - struct ffs_epfile *epfiles; -}; - -/* Reference counter handling */ -static void ffs_data_get(struct ffs_data *ffs); -static void ffs_data_put(struct ffs_data *ffs); -/* Creates new ffs_data object. */ -static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); - -/* Opened counter handling. */ -static void ffs_data_opened(struct ffs_data *ffs); -static void ffs_data_closed(struct ffs_data *ffs); - -/* Called with ffs->mutex held; take over ownership of data. */ -static int __must_check -__ffs_data_got_descs(struct ffs_data *ffs, char *data, size_t len); -static int __must_check -__ffs_data_got_strings(struct ffs_data *ffs, char *data, size_t len); - - -/* The function structure ***************************************************/ - -struct ffs_ep; - -struct ffs_function { - struct usb_configuration *conf; - struct usb_gadget *gadget; - struct ffs_data *ffs; - - struct ffs_ep *eps; - u8 eps_revmap[16]; - short *interfaces_nums; - - struct usb_function function; -}; - - -static struct ffs_function *ffs_func_from_usb(struct usb_function *f) -{ - return container_of(f, struct ffs_function, function); -} - -static void ffs_func_free(struct ffs_function *func); - -static void ffs_func_eps_disable(struct ffs_function *func); -static int __must_check ffs_func_eps_enable(struct ffs_function *func); - -static int ffs_func_bind(struct usb_configuration *, - struct usb_function *); -static void ffs_func_unbind(struct usb_configuration *, - struct usb_function *); -static int ffs_func_set_alt(struct usb_function *, unsigned, unsigned); -static void ffs_func_disable(struct usb_function *); -static int ffs_func_setup(struct usb_function *, - const struct usb_ctrlrequest *); -static void ffs_func_suspend(struct usb_function *); -static void ffs_func_resume(struct usb_function *); - - -static int ffs_func_revmap_ep(struct ffs_function *func, u8 num); -static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf); - - -/* The endpoints structures *************************************************/ - -struct ffs_ep { - struct usb_ep *ep; /* P: ffs->eps_lock */ - struct usb_request *req; /* P: epfile->mutex */ - - /* [0]: full speed, [1]: high speed */ - struct usb_endpoint_descriptor *descs[2]; - - u8 num; - - int status; /* P: epfile->mutex */ -}; - -struct ffs_epfile { - /* Protects ep->ep and ep->req. */ - struct mutex mutex; - wait_queue_head_t wait; - - struct ffs_data *ffs; - struct ffs_ep *ep; /* P: ffs->eps_lock */ - - struct dentry *dentry; - - char name[5]; - - unsigned char in; /* P: ffs->eps_lock */ - unsigned char isoc; /* P: ffs->eps_lock */ - - unsigned char _pad; -}; - -static int __must_check ffs_epfiles_create(struct ffs_data *ffs); -static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); - -static struct inode *__must_check -ffs_sb_create_file(struct super_block *sb, const char *name, void *data, - const struct file_operations *fops, - struct dentry **dentry_p); - - -/* Misc helper functions ****************************************************/ - -static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock) - __attribute__((warn_unused_result, nonnull)); -static char *ffs_prepare_buffer(const char * __user buf, size_t len) - __attribute__((warn_unused_result, nonnull)); - - -/* Control file aka ep0 *****************************************************/ - -static void ffs_ep0_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct ffs_data *ffs = req->context; - - complete_all(&ffs->ep0req_completion); -} - -static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) -{ - struct usb_request *req = ffs->ep0req; - int ret; - - req->zero = len < le16_to_cpu(ffs->ev.setup.wLength); - - spin_unlock_irq(&ffs->ev.waitq.lock); - - req->buf = data; - req->length = len; - - /* - * UDC layer requires to provide a buffer even for ZLP, but should - * not use it at all. Let's provide some poisoned pointer to catch - * possible bug in the driver. - */ - if (req->buf == NULL) - req->buf = (void *)0xDEADBABE; - - INIT_COMPLETION(ffs->ep0req_completion); - - ret = usb_ep_queue(ffs->gadget->ep0, req, GFP_ATOMIC); - if (unlikely(ret < 0)) - return ret; - - ret = wait_for_completion_interruptible(&ffs->ep0req_completion); - if (unlikely(ret)) { - usb_ep_dequeue(ffs->gadget->ep0, req); - return -EINTR; - } - - ffs->setup_state = FFS_NO_SETUP; - return ffs->ep0req_status; -} - -static int __ffs_ep0_stall(struct ffs_data *ffs) -{ - if (ffs->ev.can_stall) { - pr_vdebug("ep0 stall\n"); - usb_ep_set_halt(ffs->gadget->ep0); - ffs->setup_state = FFS_NO_SETUP; - return -EL2HLT; - } else { - pr_debug("bogus ep0 stall!\n"); - return -ESRCH; - } -} - -static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, - size_t len, loff_t *ptr) -{ - struct ffs_data *ffs = file->private_data; - ssize_t ret; - char *data; - - ENTER(); - - /* Fast check if setup was canceled */ - if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) - return -EIDRM; - - /* Acquire mutex */ - ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK); - if (unlikely(ret < 0)) - return ret; - - /* Check state */ - switch (ffs->state) { - case FFS_READ_DESCRIPTORS: - case FFS_READ_STRINGS: - /* Copy data */ - if (unlikely(len < 16)) { - ret = -EINVAL; - break; - } - - data = ffs_prepare_buffer(buf, len); - if (IS_ERR(data)) { - ret = PTR_ERR(data); - break; - } - - /* Handle data */ - if (ffs->state == FFS_READ_DESCRIPTORS) { - pr_info("read descriptors\n"); - ret = __ffs_data_got_descs(ffs, data, len); - if (unlikely(ret < 0)) - break; - - ffs->state = FFS_READ_STRINGS; - ret = len; - } else { - pr_info("read strings\n"); - ret = __ffs_data_got_strings(ffs, data, len); - if (unlikely(ret < 0)) - break; - - ret = ffs_epfiles_create(ffs); - if (unlikely(ret)) { - ffs->state = FFS_CLOSING; - break; - } - - ffs->state = FFS_ACTIVE; - mutex_unlock(&ffs->mutex); - - ret = functionfs_ready_callback(ffs); - if (unlikely(ret < 0)) { - ffs->state = FFS_CLOSING; - return ret; - } - - set_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags); - return len; - } - break; - - case FFS_ACTIVE: - data = NULL; - /* - * We're called from user space, we can use _irq - * rather then _irqsave - */ - spin_lock_irq(&ffs->ev.waitq.lock); - switch (FFS_SETUP_STATE(ffs)) { - case FFS_SETUP_CANCELED: - ret = -EIDRM; - goto done_spin; - - case FFS_NO_SETUP: - ret = -ESRCH; - goto done_spin; - - case FFS_SETUP_PENDING: - break; - } - - /* FFS_SETUP_PENDING */ - if (!(ffs->ev.setup.bRequestType & USB_DIR_IN)) { - spin_unlock_irq(&ffs->ev.waitq.lock); - ret = __ffs_ep0_stall(ffs); - break; - } - - /* FFS_SETUP_PENDING and not stall */ - len = min(len, (size_t)le16_to_cpu(ffs->ev.setup.wLength)); - - spin_unlock_irq(&ffs->ev.waitq.lock); - - data = ffs_prepare_buffer(buf, len); - if (IS_ERR(data)) { - ret = PTR_ERR(data); - break; - } - - spin_lock_irq(&ffs->ev.waitq.lock); - - /* - * We are guaranteed to be still in FFS_ACTIVE state - * but the state of setup could have changed from - * FFS_SETUP_PENDING to FFS_SETUP_CANCELED so we need - * to check for that. If that happened we copied data - * from user space in vain but it's unlikely. - * - * For sure we are not in FFS_NO_SETUP since this is - * the only place FFS_SETUP_PENDING -> FFS_NO_SETUP - * transition can be performed and it's protected by - * mutex. - */ - if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { - ret = -EIDRM; -done_spin: - spin_unlock_irq(&ffs->ev.waitq.lock); - } else { - /* unlocks spinlock */ - ret = __ffs_ep0_queue_wait(ffs, data, len); - } - kfree(data); - break; - - default: - ret = -EBADFD; - break; - } - - mutex_unlock(&ffs->mutex); - return ret; -} - -static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, - size_t n) -{ - /* - * We are holding ffs->ev.waitq.lock and ffs->mutex and we need - * to release them. - */ - struct usb_functionfs_event events[n]; - unsigned i = 0; - - memset(events, 0, sizeof events); - - do { - events[i].type = ffs->ev.types[i]; - if (events[i].type == FUNCTIONFS_SETUP) { - events[i].u.setup = ffs->ev.setup; - ffs->setup_state = FFS_SETUP_PENDING; - } - } while (++i < n); - - if (n < ffs->ev.count) { - ffs->ev.count -= n; - memmove(ffs->ev.types, ffs->ev.types + n, - ffs->ev.count * sizeof *ffs->ev.types); - } else { - ffs->ev.count = 0; - } - - spin_unlock_irq(&ffs->ev.waitq.lock); - mutex_unlock(&ffs->mutex); - - return unlikely(__copy_to_user(buf, events, sizeof events)) - ? -EFAULT : sizeof events; -} - -static ssize_t ffs_ep0_read(struct file *file, char __user *buf, - size_t len, loff_t *ptr) -{ - struct ffs_data *ffs = file->private_data; - char *data = NULL; - size_t n; - int ret; - - ENTER(); - - /* Fast check if setup was canceled */ - if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) - return -EIDRM; - - /* Acquire mutex */ - ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK); - if (unlikely(ret < 0)) - return ret; - - /* Check state */ - if (ffs->state != FFS_ACTIVE) { - ret = -EBADFD; - goto done_mutex; - } - - /* - * We're called from user space, we can use _irq rather then - * _irqsave - */ - spin_lock_irq(&ffs->ev.waitq.lock); - - switch (FFS_SETUP_STATE(ffs)) { - case FFS_SETUP_CANCELED: - ret = -EIDRM; - break; - - case FFS_NO_SETUP: - n = len / sizeof(struct usb_functionfs_event); - if (unlikely(!n)) { - ret = -EINVAL; - break; - } - - if ((file->f_flags & O_NONBLOCK) && !ffs->ev.count) { - ret = -EAGAIN; - break; - } - - if (wait_event_interruptible_exclusive_locked_irq(ffs->ev.waitq, - ffs->ev.count)) { - ret = -EINTR; - break; - } - - return __ffs_ep0_read_events(ffs, buf, - min(n, (size_t)ffs->ev.count)); - - case FFS_SETUP_PENDING: - if (ffs->ev.setup.bRequestType & USB_DIR_IN) { - spin_unlock_irq(&ffs->ev.waitq.lock); - ret = __ffs_ep0_stall(ffs); - goto done_mutex; - } - - len = min(len, (size_t)le16_to_cpu(ffs->ev.setup.wLength)); - - spin_unlock_irq(&ffs->ev.waitq.lock); - - if (likely(len)) { - data = kmalloc(len, GFP_KERNEL); - if (unlikely(!data)) { - ret = -ENOMEM; - goto done_mutex; - } - } - - spin_lock_irq(&ffs->ev.waitq.lock); - - /* See ffs_ep0_write() */ - if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { - ret = -EIDRM; - break; - } - - /* unlocks spinlock */ - ret = __ffs_ep0_queue_wait(ffs, data, len); - if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len))) - ret = -EFAULT; - goto done_mutex; - - default: - ret = -EBADFD; - break; - } - - spin_unlock_irq(&ffs->ev.waitq.lock); -done_mutex: - mutex_unlock(&ffs->mutex); - kfree(data); - return ret; -} - -static int ffs_ep0_open(struct inode *inode, struct file *file) -{ - struct ffs_data *ffs = inode->i_private; - - ENTER(); - - if (unlikely(ffs->state == FFS_CLOSING)) - return -EBUSY; - - file->private_data = ffs; - ffs_data_opened(ffs); - - return 0; -} - -static int ffs_ep0_release(struct inode *inode, struct file *file) -{ - struct ffs_data *ffs = file->private_data; - - ENTER(); - - ffs_data_closed(ffs); - - return 0; -} - -static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) -{ - struct ffs_data *ffs = file->private_data; - struct usb_gadget *gadget = ffs->gadget; - long ret; - - ENTER(); - - if (code == FUNCTIONFS_INTERFACE_REVMAP) { - struct ffs_function *func = ffs->func; - ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget && gadget->ops->ioctl) { - ret = gadget->ops->ioctl(gadget, code, value); - } else { - ret = -ENOTTY; - } - - return ret; -} - -static const struct file_operations ffs_ep0_operations = { - .owner = THIS_MODULE, - .llseek = no_llseek, - - .open = ffs_ep0_open, - .write = ffs_ep0_write, - .read = ffs_ep0_read, - .release = ffs_ep0_release, - .unlocked_ioctl = ffs_ep0_ioctl, -}; - - -/* "Normal" endpoints operations ********************************************/ - -static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) -{ - ENTER(); - if (likely(req->context)) { - struct ffs_ep *ep = _ep->driver_data; - ep->status = req->status ? req->status : req->actual; - complete(req->context); - } -} - -static ssize_t ffs_epfile_io(struct file *file, - char __user *buf, size_t len, int read) -{ - struct ffs_epfile *epfile = file->private_data; - struct ffs_ep *ep; - char *data = NULL; - ssize_t ret; - int halt; - - goto first_try; - do { - spin_unlock_irq(&epfile->ffs->eps_lock); - mutex_unlock(&epfile->mutex); - -first_try: - /* Are we still active? */ - if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) { - ret = -ENODEV; - goto error; - } - - /* Wait for endpoint to be enabled */ - ep = epfile->ep; - if (!ep) { - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto error; - } - - if (wait_event_interruptible(epfile->wait, - (ep = epfile->ep))) { - ret = -EINTR; - goto error; - } - } - - /* Do we halt? */ - halt = !read == !epfile->in; - if (halt && epfile->isoc) { - ret = -EINVAL; - goto error; - } - - /* Allocate & copy */ - if (!halt && !data) { - data = kzalloc(len, GFP_KERNEL); - if (unlikely(!data)) - return -ENOMEM; - - if (!read && - unlikely(__copy_from_user(data, buf, len))) { - ret = -EFAULT; - goto error; - } - } - - /* We will be using request */ - ret = ffs_mutex_lock(&epfile->mutex, - file->f_flags & O_NONBLOCK); - if (unlikely(ret)) - goto error; - - /* - * We're called from user space, we can use _irq rather then - * _irqsave - */ - spin_lock_irq(&epfile->ffs->eps_lock); - - /* - * While we were acquiring mutex endpoint got disabled - * or changed? - */ - } while (unlikely(epfile->ep != ep)); - - /* Halt */ - if (unlikely(halt)) { - if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep)) - usb_ep_set_halt(ep->ep); - spin_unlock_irq(&epfile->ffs->eps_lock); - ret = -EBADMSG; - } else { - /* Fire the request */ - DECLARE_COMPLETION_ONSTACK(done); - - struct usb_request *req = ep->req; - req->context = &done; - req->complete = ffs_epfile_io_complete; - req->buf = data; - req->length = len; - - ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); - - spin_unlock_irq(&epfile->ffs->eps_lock); - - if (unlikely(ret < 0)) { - /* nop */ - } else if (unlikely(wait_for_completion_interruptible(&done))) { - ret = -EINTR; - usb_ep_dequeue(ep->ep, req); - } else { - ret = ep->status; - if (read && ret > 0 && - unlikely(copy_to_user(buf, data, ret))) - ret = -EFAULT; - } - } - - mutex_unlock(&epfile->mutex); -error: - kfree(data); - return ret; -} - -static ssize_t -ffs_epfile_write(struct file *file, const char __user *buf, size_t len, - loff_t *ptr) -{ - ENTER(); - - return ffs_epfile_io(file, (char __user *)buf, len, 0); -} - -static ssize_t -ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) -{ - ENTER(); - - return ffs_epfile_io(file, buf, len, 1); -} - -static int -ffs_epfile_open(struct inode *inode, struct file *file) -{ - struct ffs_epfile *epfile = inode->i_private; - - ENTER(); - - if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) - return -ENODEV; - - file->private_data = epfile; - ffs_data_opened(epfile->ffs); - - return 0; -} - -static int -ffs_epfile_release(struct inode *inode, struct file *file) -{ - struct ffs_epfile *epfile = inode->i_private; - - ENTER(); - - ffs_data_closed(epfile->ffs); - - return 0; -} - -static long ffs_epfile_ioctl(struct file *file, unsigned code, - unsigned long value) -{ - struct ffs_epfile *epfile = file->private_data; - int ret; - - ENTER(); - - if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) - return -ENODEV; - - spin_lock_irq(&epfile->ffs->eps_lock); - if (likely(epfile->ep)) { - switch (code) { - case FUNCTIONFS_FIFO_STATUS: - ret = usb_ep_fifo_status(epfile->ep->ep); - break; - case FUNCTIONFS_FIFO_FLUSH: - usb_ep_fifo_flush(epfile->ep->ep); - ret = 0; - break; - case FUNCTIONFS_CLEAR_HALT: - ret = usb_ep_clear_halt(epfile->ep->ep); - break; - case FUNCTIONFS_ENDPOINT_REVMAP: - ret = epfile->ep->num; - break; - default: - ret = -ENOTTY; - } - } else { - ret = -ENODEV; - } - spin_unlock_irq(&epfile->ffs->eps_lock); - - return ret; -} - -static const struct file_operations ffs_epfile_operations = { - .owner = THIS_MODULE, - .llseek = no_llseek, - - .open = ffs_epfile_open, - .write = ffs_epfile_write, - .read = ffs_epfile_read, - .release = ffs_epfile_release, - .unlocked_ioctl = ffs_epfile_ioctl, -}; - - -/* File system and super block operations ***********************************/ - -/* - * Mounting the file system creates a controller file, used first for - * function configuration then later for event monitoring. - */ - -static struct inode *__must_check -ffs_sb_make_inode(struct super_block *sb, void *data, - const struct file_operations *fops, - const struct inode_operations *iops, - struct ffs_file_perms *perms) -{ - struct inode *inode; - - ENTER(); - - inode = new_inode(sb); - - if (likely(inode)) { - struct timespec current_time = CURRENT_TIME; - - inode->i_ino = get_next_ino(); - inode->i_mode = perms->mode; - inode->i_uid = perms->uid; - inode->i_gid = perms->gid; - inode->i_atime = current_time; - inode->i_mtime = current_time; - inode->i_ctime = current_time; - inode->i_private = data; - if (fops) - inode->i_fop = fops; - if (iops) - inode->i_op = iops; - } - - return inode; -} - -/* Create "regular" file */ -static struct inode *ffs_sb_create_file(struct super_block *sb, - const char *name, void *data, - const struct file_operations *fops, - struct dentry **dentry_p) -{ - struct ffs_data *ffs = sb->s_fs_info; - struct dentry *dentry; - struct inode *inode; - - ENTER(); - - dentry = d_alloc_name(sb->s_root, name); - if (unlikely(!dentry)) - return NULL; - - inode = ffs_sb_make_inode(sb, data, fops, NULL, &ffs->file_perms); - if (unlikely(!inode)) { - dput(dentry); - return NULL; - } - - d_add(dentry, inode); - if (dentry_p) - *dentry_p = dentry; - - return inode; -} - -/* Super block */ -static const struct super_operations ffs_sb_operations = { - .statfs = simple_statfs, - .drop_inode = generic_delete_inode, -}; - -struct ffs_sb_fill_data { - struct ffs_file_perms perms; - umode_t root_mode; - const char *dev_name; - union { - /* set by ffs_fs_mount(), read by ffs_sb_fill() */ - void *private_data; - /* set by ffs_sb_fill(), read by ffs_fs_mount */ - struct ffs_data *ffs_data; - }; -}; - -static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) -{ - struct ffs_sb_fill_data *data = _data; - struct inode *inode; - struct ffs_data *ffs; - - ENTER(); - - /* Initialise data */ - ffs = ffs_data_new(); - if (unlikely(!ffs)) - goto Enomem; - - ffs->sb = sb; - ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL); - if (unlikely(!ffs->dev_name)) - goto Enomem; - ffs->file_perms = data->perms; - ffs->private_data = data->private_data; - - /* used by the caller of this function */ - data->ffs_data = ffs; - - sb->s_fs_info = ffs; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = FUNCTIONFS_MAGIC; - sb->s_op = &ffs_sb_operations; - sb->s_time_gran = 1; - - /* Root inode */ - data->perms.mode = data->root_mode; - inode = ffs_sb_make_inode(sb, NULL, - &simple_dir_operations, - &simple_dir_inode_operations, - &data->perms); - sb->s_root = d_make_root(inode); - if (unlikely(!sb->s_root)) - goto Enomem; - - /* EP0 file */ - if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, - &ffs_ep0_operations, NULL))) - goto Enomem; - - return 0; - -Enomem: - return -ENOMEM; -} - -static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) -{ - ENTER(); - - if (!opts || !*opts) - return 0; - - for (;;) { - char *end, *eq, *comma; - unsigned long value; - - /* Option limit */ - comma = strchr(opts, ','); - if (comma) - *comma = 0; - - /* Value limit */ - eq = strchr(opts, '='); - if (unlikely(!eq)) { - pr_err("'=' missing in %s\n", opts); - return -EINVAL; - } - *eq = 0; - - /* Parse value */ - value = simple_strtoul(eq + 1, &end, 0); - if (unlikely(*end != ',' && *end != 0)) { - pr_err("%s: invalid value: %s\n", opts, eq + 1); - return -EINVAL; - } - - /* Interpret option */ - switch (eq - opts) { - case 5: - if (!memcmp(opts, "rmode", 5)) - data->root_mode = (value & 0555) | S_IFDIR; - else if (!memcmp(opts, "fmode", 5)) - data->perms.mode = (value & 0666) | S_IFREG; - else - goto invalid; - break; - - case 4: - if (!memcmp(opts, "mode", 4)) { - data->root_mode = (value & 0555) | S_IFDIR; - data->perms.mode = (value & 0666) | S_IFREG; - } else { - goto invalid; - } - break; - - case 3: - if (!memcmp(opts, "uid", 3)) - data->perms.uid = value; - else if (!memcmp(opts, "gid", 3)) - data->perms.gid = value; - else - goto invalid; - break; - - default: -invalid: - pr_err("%s: invalid option\n", opts); - return -EINVAL; - } - - /* Next iteration */ - if (!comma) - break; - opts = comma + 1; - } - - return 0; -} - -/* "mount -t functionfs dev_name /dev/function" ends up here */ - -static struct dentry * -ffs_fs_mount(struct file_system_type *t, int flags, - const char *dev_name, void *opts) -{ - struct ffs_sb_fill_data data = { - .perms = { - .mode = S_IFREG | 0600, - .uid = 0, - .gid = 0 - }, - .root_mode = S_IFDIR | 0500, - }; - struct dentry *rv; - int ret; - void *ffs_dev; - - ENTER(); - - ret = ffs_fs_parse_opts(&data, opts); - if (unlikely(ret < 0)) - return ERR_PTR(ret); - - ffs_dev = functionfs_acquire_dev_callback(dev_name); - if (IS_ERR(ffs_dev)) - return ffs_dev; - - data.dev_name = dev_name; - data.private_data = ffs_dev; - rv = mount_nodev(t, flags, &data, ffs_sb_fill); - - /* data.ffs_data is set by ffs_sb_fill */ - if (IS_ERR(rv)) - functionfs_release_dev_callback(data.ffs_data); - - return rv; -} - -static void -ffs_fs_kill_sb(struct super_block *sb) -{ - ENTER(); - - kill_litter_super(sb); - if (sb->s_fs_info) { - functionfs_release_dev_callback(sb->s_fs_info); - ffs_data_put(sb->s_fs_info); - } -} - -static struct file_system_type ffs_fs_type = { - .owner = THIS_MODULE, - .name = "functionfs", - .mount = ffs_fs_mount, - .kill_sb = ffs_fs_kill_sb, -}; - - -/* Driver's main init/cleanup functions *************************************/ - -static int functionfs_init(void) -{ - int ret; - - ENTER(); - - ret = register_filesystem(&ffs_fs_type); - if (likely(!ret)) - pr_info("file system registered\n"); - else - pr_err("failed registering file system (%d)\n", ret); - - return ret; -} - -static void functionfs_cleanup(void) -{ - ENTER(); - - pr_info("unloading\n"); - unregister_filesystem(&ffs_fs_type); -} - - -/* ffs_data and ffs_function construction and destruction code **************/ - -static void ffs_data_clear(struct ffs_data *ffs); -static void ffs_data_reset(struct ffs_data *ffs); - -static void ffs_data_get(struct ffs_data *ffs) -{ - ENTER(); - - atomic_inc(&ffs->ref); -} - -static void ffs_data_opened(struct ffs_data *ffs) -{ - ENTER(); - - atomic_inc(&ffs->ref); - atomic_inc(&ffs->opened); -} - -static void ffs_data_put(struct ffs_data *ffs) -{ - ENTER(); - - if (unlikely(atomic_dec_and_test(&ffs->ref))) { - pr_info("%s(): freeing\n", __func__); - ffs_data_clear(ffs); - BUG_ON(waitqueue_active(&ffs->ev.waitq) || - waitqueue_active(&ffs->ep0req_completion.wait)); - kfree(ffs->dev_name); - kfree(ffs); - } -} - -static void ffs_data_closed(struct ffs_data *ffs) -{ - ENTER(); - - if (atomic_dec_and_test(&ffs->opened)) { - ffs->state = FFS_CLOSING; - ffs_data_reset(ffs); - } - - ffs_data_put(ffs); -} - -static struct ffs_data *ffs_data_new(void) -{ - struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); - if (unlikely(!ffs)) - return 0; - - ENTER(); - - atomic_set(&ffs->ref, 1); - atomic_set(&ffs->opened, 0); - ffs->state = FFS_READ_DESCRIPTORS; - mutex_init(&ffs->mutex); - spin_lock_init(&ffs->eps_lock); - init_waitqueue_head(&ffs->ev.waitq); - init_completion(&ffs->ep0req_completion); - - /* XXX REVISIT need to update it in some places, or do we? */ - ffs->ev.can_stall = 1; - - return ffs; -} - -static void ffs_data_clear(struct ffs_data *ffs) -{ - ENTER(); - - if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags)) - functionfs_closed_callback(ffs); - - BUG_ON(ffs->gadget); - - if (ffs->epfiles) - ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); - - kfree(ffs->raw_descs); - kfree(ffs->raw_strings); - kfree(ffs->stringtabs); -} - -static void ffs_data_reset(struct ffs_data *ffs) -{ - ENTER(); - - ffs_data_clear(ffs); - - ffs->epfiles = NULL; - ffs->raw_descs = NULL; - ffs->raw_strings = NULL; - ffs->stringtabs = NULL; - - ffs->raw_descs_length = 0; - ffs->raw_fs_descs_length = 0; - ffs->fs_descs_count = 0; - ffs->hs_descs_count = 0; - - ffs->strings_count = 0; - ffs->interfaces_count = 0; - ffs->eps_count = 0; - - ffs->ev.count = 0; - - ffs->state = FFS_READ_DESCRIPTORS; - ffs->setup_state = FFS_NO_SETUP; - ffs->flags = 0; -} - - -static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) -{ - struct usb_gadget_strings **lang; - int first_id; - - ENTER(); - - if (WARN_ON(ffs->state != FFS_ACTIVE - || test_and_set_bit(FFS_FL_BOUND, &ffs->flags))) - return -EBADFD; - - first_id = usb_string_ids_n(cdev, ffs->strings_count); - if (unlikely(first_id < 0)) - return first_id; - - ffs->ep0req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); - if (unlikely(!ffs->ep0req)) - return -ENOMEM; - ffs->ep0req->complete = ffs_ep0_complete; - ffs->ep0req->context = ffs; - - lang = ffs->stringtabs; - for (lang = ffs->stringtabs; *lang; ++lang) { - struct usb_string *str = (*lang)->strings; - int id = first_id; - for (; str->s; ++id, ++str) - str->id = id; - } - - ffs->gadget = cdev->gadget; - ffs_data_get(ffs); - return 0; -} - -static void functionfs_unbind(struct ffs_data *ffs) -{ - ENTER(); - - if (!WARN_ON(!ffs->gadget)) { - usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req); - ffs->ep0req = NULL; - ffs->gadget = NULL; - ffs_data_put(ffs); - clear_bit(FFS_FL_BOUND, &ffs->flags); - } -} - -static int ffs_epfiles_create(struct ffs_data *ffs) -{ - struct ffs_epfile *epfile, *epfiles; - unsigned i, count; - - ENTER(); - - count = ffs->eps_count; - epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL); - if (!epfiles) - return -ENOMEM; - - epfile = epfiles; - for (i = 1; i <= count; ++i, ++epfile) { - epfile->ffs = ffs; - mutex_init(&epfile->mutex); - init_waitqueue_head(&epfile->wait); - sprintf(epfiles->name, "ep%u", i); - if (!unlikely(ffs_sb_create_file(ffs->sb, epfiles->name, epfile, - &ffs_epfile_operations, - &epfile->dentry))) { - ffs_epfiles_destroy(epfiles, i - 1); - return -ENOMEM; - } - } - - ffs->epfiles = epfiles; - return 0; -} - -static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) -{ - struct ffs_epfile *epfile = epfiles; - - ENTER(); - - for (; count; --count, ++epfile) { - BUG_ON(mutex_is_locked(&epfile->mutex) || - waitqueue_active(&epfile->wait)); - if (epfile->dentry) { - d_delete(epfile->dentry); - dput(epfile->dentry); - epfile->dentry = NULL; - } - } - - kfree(epfiles); -} - -static int functionfs_bind_config(struct usb_composite_dev *cdev, - struct usb_configuration *c, - struct ffs_data *ffs) -{ - struct ffs_function *func; - int ret; - - ENTER(); - - func = kzalloc(sizeof *func, GFP_KERNEL); - if (unlikely(!func)) - return -ENOMEM; - - func->function.name = "Function FS Gadget"; - func->function.strings = ffs->stringtabs; - - func->function.bind = ffs_func_bind; - func->function.unbind = ffs_func_unbind; - func->function.set_alt = ffs_func_set_alt; - func->function.disable = ffs_func_disable; - func->function.setup = ffs_func_setup; - func->function.suspend = ffs_func_suspend; - func->function.resume = ffs_func_resume; - - func->conf = c; - func->gadget = cdev->gadget; - func->ffs = ffs; - ffs_data_get(ffs); - - ret = usb_add_function(c, &func->function); - if (unlikely(ret)) - ffs_func_free(func); - - return ret; -} - -static void ffs_func_free(struct ffs_function *func) -{ - struct ffs_ep *ep = func->eps; - unsigned count = func->ffs->eps_count; - unsigned long flags; - - ENTER(); - - /* cleanup after autoconfig */ - spin_lock_irqsave(&func->ffs->eps_lock, flags); - do { - if (ep->ep && ep->req) - usb_ep_free_request(ep->ep, ep->req); - ep->req = NULL; - ++ep; - } while (--count); - spin_unlock_irqrestore(&func->ffs->eps_lock, flags); - - ffs_data_put(func->ffs); - - kfree(func->eps); - /* - * eps and interfaces_nums are allocated in the same chunk so - * only one free is required. Descriptors are also allocated - * in the same chunk. - */ - - kfree(func); -} - -static void ffs_func_eps_disable(struct ffs_function *func) -{ - struct ffs_ep *ep = func->eps; - struct ffs_epfile *epfile = func->ffs->epfiles; - unsigned count = func->ffs->eps_count; - unsigned long flags; - - spin_lock_irqsave(&func->ffs->eps_lock, flags); - do { - /* pending requests get nuked */ - if (likely(ep->ep)) - usb_ep_disable(ep->ep); - epfile->ep = NULL; - - ++ep; - ++epfile; - } while (--count); - spin_unlock_irqrestore(&func->ffs->eps_lock, flags); -} - -static int ffs_func_eps_enable(struct ffs_function *func) -{ - struct ffs_data *ffs = func->ffs; - struct ffs_ep *ep = func->eps; - struct ffs_epfile *epfile = ffs->epfiles; - unsigned count = ffs->eps_count; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&func->ffs->eps_lock, flags); - do { - struct usb_endpoint_descriptor *ds; - ds = ep->descs[ep->descs[1] ? 1 : 0]; - - ep->ep->driver_data = ep; - ep->ep->desc = ds; - ret = usb_ep_enable(ep->ep); - if (likely(!ret)) { - epfile->ep = ep; - epfile->in = usb_endpoint_dir_in(ds); - epfile->isoc = usb_endpoint_xfer_isoc(ds); - } else { - break; - } - - wake_up(&epfile->wait); - - ++ep; - ++epfile; - } while (--count); - spin_unlock_irqrestore(&func->ffs->eps_lock, flags); - - return ret; -} - - -/* Parsing and building descriptors and strings *****************************/ - -/* - * This validates if data pointed by data is a valid USB descriptor as - * well as record how many interfaces, endpoints and strings are - * required by given configuration. Returns address after the - * descriptor or NULL if data is invalid. - */ - -enum ffs_entity_type { - FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT -}; - -typedef int (*ffs_entity_callback)(enum ffs_entity_type entity, - u8 *valuep, - struct usb_descriptor_header *desc, - void *priv); - -static int __must_check ffs_do_desc(char *data, unsigned len, - ffs_entity_callback entity, void *priv) -{ - struct usb_descriptor_header *_ds = (void *)data; - u8 length; - int ret; - - ENTER(); - - /* At least two bytes are required: length and type */ - if (len < 2) { - pr_vdebug("descriptor too short\n"); - return -EINVAL; - } - - /* If we have at least as many bytes as the descriptor takes? */ - length = _ds->bLength; - if (len < length) { - pr_vdebug("descriptor longer then available data\n"); - return -EINVAL; - } - -#define __entity_check_INTERFACE(val) 1 -#define __entity_check_STRING(val) (val) -#define __entity_check_ENDPOINT(val) ((val) & USB_ENDPOINT_NUMBER_MASK) -#define __entity(type, val) do { \ - pr_vdebug("entity " #type "(%02x)\n", (val)); \ - if (unlikely(!__entity_check_ ##type(val))) { \ - pr_vdebug("invalid entity's value\n"); \ - return -EINVAL; \ - } \ - ret = entity(FFS_ ##type, &val, _ds, priv); \ - if (unlikely(ret < 0)) { \ - pr_debug("entity " #type "(%02x); ret = %d\n", \ - (val), ret); \ - return ret; \ - } \ - } while (0) - - /* Parse descriptor depending on type. */ - switch (_ds->bDescriptorType) { - case USB_DT_DEVICE: - case USB_DT_CONFIG: - case USB_DT_STRING: - case USB_DT_DEVICE_QUALIFIER: - /* function can't have any of those */ - pr_vdebug("descriptor reserved for gadget: %d\n", - _ds->bDescriptorType); - return -EINVAL; - - case USB_DT_INTERFACE: { - struct usb_interface_descriptor *ds = (void *)_ds; - pr_vdebug("interface descriptor\n"); - if (length != sizeof *ds) - goto inv_length; - - __entity(INTERFACE, ds->bInterfaceNumber); - if (ds->iInterface) - __entity(STRING, ds->iInterface); - } - break; - - case USB_DT_ENDPOINT: { - struct usb_endpoint_descriptor *ds = (void *)_ds; - pr_vdebug("endpoint descriptor\n"); - if (length != USB_DT_ENDPOINT_SIZE && - length != USB_DT_ENDPOINT_AUDIO_SIZE) - goto inv_length; - __entity(ENDPOINT, ds->bEndpointAddress); - } - break; - - case HID_DT_HID: - pr_vdebug("hid descriptor\n"); - if (length != sizeof(struct hid_descriptor)) - goto inv_length; - break; - - case USB_DT_OTG: - if (length != sizeof(struct usb_otg_descriptor)) - goto inv_length; - break; - - case USB_DT_INTERFACE_ASSOCIATION: { - struct usb_interface_assoc_descriptor *ds = (void *)_ds; - pr_vdebug("interface association descriptor\n"); - if (length != sizeof *ds) - goto inv_length; - if (ds->iFunction) - __entity(STRING, ds->iFunction); - } - break; - - case USB_DT_OTHER_SPEED_CONFIG: - case USB_DT_INTERFACE_POWER: - case USB_DT_DEBUG: - case USB_DT_SECURITY: - case USB_DT_CS_RADIO_CONTROL: - /* TODO */ - pr_vdebug("unimplemented descriptor: %d\n", _ds->bDescriptorType); - return -EINVAL; - - default: - /* We should never be here */ - pr_vdebug("unknown descriptor: %d\n", _ds->bDescriptorType); - return -EINVAL; - -inv_length: - pr_vdebug("invalid length: %d (descriptor %d)\n", - _ds->bLength, _ds->bDescriptorType); - return -EINVAL; - } - -#undef __entity -#undef __entity_check_DESCRIPTOR -#undef __entity_check_INTERFACE -#undef __entity_check_STRING -#undef __entity_check_ENDPOINT - - return length; -} - -static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, - ffs_entity_callback entity, void *priv) -{ - const unsigned _len = len; - unsigned long num = 0; - - ENTER(); - - for (;;) { - int ret; - - if (num == count) - data = NULL; - - /* Record "descriptor" entity */ - ret = entity(FFS_DESCRIPTOR, (u8 *)num, (void *)data, priv); - if (unlikely(ret < 0)) { - pr_debug("entity DESCRIPTOR(%02lx); ret = %d\n", - num, ret); - return ret; - } - - if (!data) - return _len - len; - - ret = ffs_do_desc(data, len, entity, priv); - if (unlikely(ret < 0)) { - pr_debug("%s returns %d\n", __func__, ret); - return ret; - } - - len -= ret; - data += ret; - ++num; - } -} - -static int __ffs_data_do_entity(enum ffs_entity_type type, - u8 *valuep, struct usb_descriptor_header *desc, - void *priv) -{ - struct ffs_data *ffs = priv; - - ENTER(); - - switch (type) { - case FFS_DESCRIPTOR: - break; - - case FFS_INTERFACE: - /* - * Interfaces are indexed from zero so if we - * encountered interface "n" then there are at least - * "n+1" interfaces. - */ - if (*valuep >= ffs->interfaces_count) - ffs->interfaces_count = *valuep + 1; - break; - - case FFS_STRING: - /* - * Strings are indexed from 1 (0 is magic ;) reserved - * for languages list or some such) - */ - if (*valuep > ffs->strings_count) - ffs->strings_count = *valuep; - break; - - case FFS_ENDPOINT: - /* Endpoints are indexed from 1 as well. */ - if ((*valuep & USB_ENDPOINT_NUMBER_MASK) > ffs->eps_count) - ffs->eps_count = (*valuep & USB_ENDPOINT_NUMBER_MASK); - break; - } - - return 0; -} - -static int __ffs_data_got_descs(struct ffs_data *ffs, - char *const _data, size_t len) -{ - unsigned fs_count, hs_count; - int fs_len, ret = -EINVAL; - char *data = _data; - - ENTER(); - - if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_DESCRIPTORS_MAGIC || - get_unaligned_le32(data + 4) != len)) - goto error; - fs_count = get_unaligned_le32(data + 8); - hs_count = get_unaligned_le32(data + 12); - - if (!fs_count && !hs_count) - goto einval; - - data += 16; - len -= 16; - - if (likely(fs_count)) { - fs_len = ffs_do_descs(fs_count, data, len, - __ffs_data_do_entity, ffs); - if (unlikely(fs_len < 0)) { - ret = fs_len; - goto error; - } - - data += fs_len; - len -= fs_len; - } else { - fs_len = 0; - } - - if (likely(hs_count)) { - ret = ffs_do_descs(hs_count, data, len, - __ffs_data_do_entity, ffs); - if (unlikely(ret < 0)) - goto error; - } else { - ret = 0; - } - - if (unlikely(len != ret)) - goto einval; - - ffs->raw_fs_descs_length = fs_len; - ffs->raw_descs_length = fs_len + ret; - ffs->raw_descs = _data; - ffs->fs_descs_count = fs_count; - ffs->hs_descs_count = hs_count; - - return 0; - -einval: - ret = -EINVAL; -error: - kfree(_data); - return ret; -} - -static int __ffs_data_got_strings(struct ffs_data *ffs, - char *const _data, size_t len) -{ - u32 str_count, needed_count, lang_count; - struct usb_gadget_strings **stringtabs, *t; - struct usb_string *strings, *s; - const char *data = _data; - - ENTER(); - - if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC || - get_unaligned_le32(data + 4) != len)) - goto error; - str_count = get_unaligned_le32(data + 8); - lang_count = get_unaligned_le32(data + 12); - - /* if one is zero the other must be zero */ - if (unlikely(!str_count != !lang_count)) - goto error; - - /* Do we have at least as many strings as descriptors need? */ - needed_count = ffs->strings_count; - if (unlikely(str_count < needed_count)) - goto error; - - /* - * If we don't need any strings just return and free all - * memory. - */ - if (!needed_count) { - kfree(_data); - return 0; - } - - /* Allocate everything in one chunk so there's less maintenance. */ - { - struct { - struct usb_gadget_strings *stringtabs[lang_count + 1]; - struct usb_gadget_strings stringtab[lang_count]; - struct usb_string strings[lang_count*(needed_count+1)]; - } *d; - unsigned i = 0; - - d = kmalloc(sizeof *d, GFP_KERNEL); - if (unlikely(!d)) { - kfree(_data); - return -ENOMEM; - } - - stringtabs = d->stringtabs; - t = d->stringtab; - i = lang_count; - do { - *stringtabs++ = t++; - } while (--i); - *stringtabs = NULL; - - stringtabs = d->stringtabs; - t = d->stringtab; - s = d->strings; - strings = s; - } - - /* For each language */ - data += 16; - len -= 16; - - do { /* lang_count > 0 so we can use do-while */ - unsigned needed = needed_count; - - if (unlikely(len < 3)) - goto error_free; - t->language = get_unaligned_le16(data); - t->strings = s; - ++t; - - data += 2; - len -= 2; - - /* For each string */ - do { /* str_count > 0 so we can use do-while */ - size_t length = strnlen(data, len); - - if (unlikely(length == len)) - goto error_free; - - /* - * User may provide more strings then we need, - * if that's the case we simply ignore the - * rest - */ - if (likely(needed)) { - /* - * s->id will be set while adding - * function to configuration so for - * now just leave garbage here. - */ - s->s = data; - --needed; - ++s; - } - - data += length + 1; - len -= length + 1; - } while (--str_count); - - s->id = 0; /* terminator */ - s->s = NULL; - ++s; - - } while (--lang_count); - - /* Some garbage left? */ - if (unlikely(len)) - goto error_free; - - /* Done! */ - ffs->stringtabs = stringtabs; - ffs->raw_strings = _data; - - return 0; - -error_free: - kfree(stringtabs); -error: - kfree(_data); - return -EINVAL; -} - - -/* Events handling and management *******************************************/ - -static void __ffs_event_add(struct ffs_data *ffs, - enum usb_functionfs_event_type type) -{ - enum usb_functionfs_event_type rem_type1, rem_type2 = type; - int neg = 0; - - /* - * Abort any unhandled setup - * - * We do not need to worry about some cmpxchg() changing value - * of ffs->setup_state without holding the lock because when - * state is FFS_SETUP_PENDING cmpxchg() in several places in - * the source does nothing. - */ - if (ffs->setup_state == FFS_SETUP_PENDING) - ffs->setup_state = FFS_SETUP_CANCELED; - - switch (type) { - case FUNCTIONFS_RESUME: - rem_type2 = FUNCTIONFS_SUSPEND; - /* FALL THROUGH */ - case FUNCTIONFS_SUSPEND: - case FUNCTIONFS_SETUP: - rem_type1 = type; - /* Discard all similar events */ - break; - - case FUNCTIONFS_BIND: - case FUNCTIONFS_UNBIND: - case FUNCTIONFS_DISABLE: - case FUNCTIONFS_ENABLE: - /* Discard everything other then power management. */ - rem_type1 = FUNCTIONFS_SUSPEND; - rem_type2 = FUNCTIONFS_RESUME; - neg = 1; - break; - - default: - BUG(); - } - - { - u8 *ev = ffs->ev.types, *out = ev; - unsigned n = ffs->ev.count; - for (; n; --n, ++ev) - if ((*ev == rem_type1 || *ev == rem_type2) == neg) - *out++ = *ev; - else - pr_vdebug("purging event %d\n", *ev); - ffs->ev.count = out - ffs->ev.types; - } - - pr_vdebug("adding event %d\n", type); - ffs->ev.types[ffs->ev.count++] = type; - wake_up_locked(&ffs->ev.waitq); -} - -static void ffs_event_add(struct ffs_data *ffs, - enum usb_functionfs_event_type type) -{ - unsigned long flags; - spin_lock_irqsave(&ffs->ev.waitq.lock, flags); - __ffs_event_add(ffs, type); - spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); -} - - -/* Bind/unbind USB function hooks *******************************************/ - -static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, - struct usb_descriptor_header *desc, - void *priv) -{ - struct usb_endpoint_descriptor *ds = (void *)desc; - struct ffs_function *func = priv; - struct ffs_ep *ffs_ep; - - /* - * If hs_descriptors is not NULL then we are reading hs - * descriptors now - */ - const int isHS = func->function.hs_descriptors != NULL; - unsigned idx; - - if (type != FFS_DESCRIPTOR) - return 0; - - if (isHS) - func->function.hs_descriptors[(long)valuep] = desc; - else - func->function.descriptors[(long)valuep] = desc; - - if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) - return 0; - - idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; - ffs_ep = func->eps + idx; - - if (unlikely(ffs_ep->descs[isHS])) { - pr_vdebug("two %sspeed descriptors for EP %d\n", - isHS ? "high" : "full", - ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - return -EINVAL; - } - ffs_ep->descs[isHS] = ds; - - ffs_dump_mem(": Original ep desc", ds, ds->bLength); - if (ffs_ep->ep) { - ds->bEndpointAddress = ffs_ep->descs[0]->bEndpointAddress; - if (!ds->wMaxPacketSize) - ds->wMaxPacketSize = ffs_ep->descs[0]->wMaxPacketSize; - } else { - struct usb_request *req; - struct usb_ep *ep; - - pr_vdebug("autoconfig\n"); - ep = usb_ep_autoconfig(func->gadget, ds); - if (unlikely(!ep)) - return -ENOTSUPP; - ep->driver_data = func->eps + idx; - - req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (unlikely(!req)) - return -ENOMEM; - - ffs_ep->ep = ep; - ffs_ep->req = req; - func->eps_revmap[ds->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK] = idx + 1; - } - ffs_dump_mem(": Rewritten ep desc", ds, ds->bLength); - - return 0; -} - -static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, - struct usb_descriptor_header *desc, - void *priv) -{ - struct ffs_function *func = priv; - unsigned idx; - u8 newValue; - - switch (type) { - default: - case FFS_DESCRIPTOR: - /* Handled in previous pass by __ffs_func_bind_do_descs() */ - return 0; - - case FFS_INTERFACE: - idx = *valuep; - if (func->interfaces_nums[idx] < 0) { - int id = usb_interface_id(func->conf, &func->function); - if (unlikely(id < 0)) - return id; - func->interfaces_nums[idx] = id; - } - newValue = func->interfaces_nums[idx]; - break; - - case FFS_STRING: - /* String' IDs are allocated when fsf_data is bound to cdev */ - newValue = func->ffs->stringtabs[0]->strings[*valuep - 1].id; - break; - - case FFS_ENDPOINT: - /* - * USB_DT_ENDPOINT are handled in - * __ffs_func_bind_do_descs(). - */ - if (desc->bDescriptorType == USB_DT_ENDPOINT) - return 0; - - idx = (*valuep & USB_ENDPOINT_NUMBER_MASK) - 1; - if (unlikely(!func->eps[idx].ep)) - return -EINVAL; - - { - struct usb_endpoint_descriptor **descs; - descs = func->eps[idx].descs; - newValue = descs[descs[0] ? 0 : 1]->bEndpointAddress; - } - break; - } - - pr_vdebug("%02x -> %02x\n", *valuep, newValue); - *valuep = newValue; - return 0; -} - -static int ffs_func_bind(struct usb_configuration *c, - struct usb_function *f) -{ - struct ffs_function *func = ffs_func_from_usb(f); - struct ffs_data *ffs = func->ffs; - - const int full = !!func->ffs->fs_descs_count; - const int high = gadget_is_dualspeed(func->gadget) && - func->ffs->hs_descs_count; - - int ret; - - /* Make it a single chunk, less management later on */ - struct { - struct ffs_ep eps[ffs->eps_count]; - struct usb_descriptor_header - *fs_descs[full ? ffs->fs_descs_count + 1 : 0]; - struct usb_descriptor_header - *hs_descs[high ? ffs->hs_descs_count + 1 : 0]; - short inums[ffs->interfaces_count]; - char raw_descs[high ? ffs->raw_descs_length - : ffs->raw_fs_descs_length]; - } *data; - - ENTER(); - - /* Only high speed but not supported by gadget? */ - if (unlikely(!(full | high))) - return -ENOTSUPP; - - /* Allocate */ - data = kmalloc(sizeof *data, GFP_KERNEL); - if (unlikely(!data)) - return -ENOMEM; - - /* Zero */ - memset(data->eps, 0, sizeof data->eps); - memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs); - memset(data->inums, 0xff, sizeof data->inums); - for (ret = ffs->eps_count; ret; --ret) - data->eps[ret].num = -1; - - /* Save pointers */ - func->eps = data->eps; - func->interfaces_nums = data->inums; - - /* - * Go through all the endpoint descriptors and allocate - * endpoints first, so that later we can rewrite the endpoint - * numbers without worrying that it may be described later on. - */ - if (likely(full)) { - func->function.descriptors = data->fs_descs; - ret = ffs_do_descs(ffs->fs_descs_count, - data->raw_descs, - sizeof data->raw_descs, - __ffs_func_bind_do_descs, func); - if (unlikely(ret < 0)) - goto error; - } else { - ret = 0; - } - - if (likely(high)) { - func->function.hs_descriptors = data->hs_descs; - ret = ffs_do_descs(ffs->hs_descs_count, - data->raw_descs + ret, - (sizeof data->raw_descs) - ret, - __ffs_func_bind_do_descs, func); - } - - /* - * Now handle interface numbers allocation and interface and - * endpoint numbers rewriting. We can do that in one go - * now. - */ - ret = ffs_do_descs(ffs->fs_descs_count + - (high ? ffs->hs_descs_count : 0), - data->raw_descs, sizeof data->raw_descs, - __ffs_func_bind_do_nums, func); - if (unlikely(ret < 0)) - goto error; - - /* And we're done */ - ffs_event_add(ffs, FUNCTIONFS_BIND); - return 0; - -error: - /* XXX Do we need to release all claimed endpoints here? */ - return ret; -} - - -/* Other USB function hooks *************************************************/ - -static void ffs_func_unbind(struct usb_configuration *c, - struct usb_function *f) -{ - struct ffs_function *func = ffs_func_from_usb(f); - struct ffs_data *ffs = func->ffs; - - ENTER(); - - if (ffs->func == func) { - ffs_func_eps_disable(func); - ffs->func = NULL; - } - - ffs_event_add(ffs, FUNCTIONFS_UNBIND); - - ffs_func_free(func); -} - -static int ffs_func_set_alt(struct usb_function *f, - unsigned interface, unsigned alt) -{ - struct ffs_function *func = ffs_func_from_usb(f); - struct ffs_data *ffs = func->ffs; - int ret = 0, intf; - - if (alt != (unsigned)-1) { - intf = ffs_func_revmap_intf(func, interface); - if (unlikely(intf < 0)) - return intf; - } - - if (ffs->func) - ffs_func_eps_disable(ffs->func); - - if (ffs->state != FFS_ACTIVE) - return -ENODEV; - - if (alt == (unsigned)-1) { - ffs->func = NULL; - ffs_event_add(ffs, FUNCTIONFS_DISABLE); - return 0; - } - - ffs->func = func; - ret = ffs_func_eps_enable(func); - if (likely(ret >= 0)) - ffs_event_add(ffs, FUNCTIONFS_ENABLE); - return ret; -} - -static void ffs_func_disable(struct usb_function *f) -{ - ffs_func_set_alt(f, 0, (unsigned)-1); -} - -static int ffs_func_setup(struct usb_function *f, - const struct usb_ctrlrequest *creq) -{ - struct ffs_function *func = ffs_func_from_usb(f); - struct ffs_data *ffs = func->ffs; - unsigned long flags; - int ret; - - ENTER(); - - pr_vdebug("creq->bRequestType = %02x\n", creq->bRequestType); - pr_vdebug("creq->bRequest = %02x\n", creq->bRequest); - pr_vdebug("creq->wValue = %04x\n", le16_to_cpu(creq->wValue)); - pr_vdebug("creq->wIndex = %04x\n", le16_to_cpu(creq->wIndex)); - pr_vdebug("creq->wLength = %04x\n", le16_to_cpu(creq->wLength)); - - /* - * Most requests directed to interface go through here - * (notable exceptions are set/get interface) so we need to - * handle them. All other either handled by composite or - * passed to usb_configuration->setup() (if one is set). No - * matter, we will handle requests directed to endpoint here - * as well (as it's straightforward) but what to do with any - * other request? - */ - if (ffs->state != FFS_ACTIVE) - return -ENODEV; - - switch (creq->bRequestType & USB_RECIP_MASK) { - case USB_RECIP_INTERFACE: - ret = ffs_func_revmap_intf(func, le16_to_cpu(creq->wIndex)); - if (unlikely(ret < 0)) - return ret; - break; - - case USB_RECIP_ENDPOINT: - ret = ffs_func_revmap_ep(func, le16_to_cpu(creq->wIndex)); - if (unlikely(ret < 0)) - return ret; - break; - - default: - return -EOPNOTSUPP; - } - - spin_lock_irqsave(&ffs->ev.waitq.lock, flags); - ffs->ev.setup = *creq; - ffs->ev.setup.wIndex = cpu_to_le16(ret); - __ffs_event_add(ffs, FUNCTIONFS_SETUP); - spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); - - return 0; -} - -static void ffs_func_suspend(struct usb_function *f) -{ - ENTER(); - ffs_event_add(ffs_func_from_usb(f)->ffs, FUNCTIONFS_SUSPEND); -} - -static void ffs_func_resume(struct usb_function *f) -{ - ENTER(); - ffs_event_add(ffs_func_from_usb(f)->ffs, FUNCTIONFS_RESUME); -} - - -/* Endpoint and interface numbers reverse mapping ***************************/ - -static int ffs_func_revmap_ep(struct ffs_function *func, u8 num) -{ - num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK]; - return num ? num : -EDOM; -} - -static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf) -{ - short *nums = func->interfaces_nums; - unsigned count = func->ffs->interfaces_count; - - for (; count; --count, ++nums) { - if (*nums >= 0 && *nums == intf) - return nums - func->interfaces_nums; - } - - return -EDOM; -} - - -/* Misc helper functions ****************************************************/ - -static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock) -{ - return nonblock - ? likely(mutex_trylock(mutex)) ? 0 : -EAGAIN - : mutex_lock_interruptible(mutex); -} - -static char *ffs_prepare_buffer(const char * __user buf, size_t len) -{ - char *data; - - if (unlikely(!len)) - return NULL; - - data = kmalloc(len, GFP_KERNEL); - if (unlikely(!data)) - return ERR_PTR(-ENOMEM); - - if (unlikely(__copy_from_user(data, buf, len))) { - kfree(data); - return ERR_PTR(-EFAULT); - } - - pr_vdebug("Buffer from user space:\n"); - ffs_dump_mem("", data, len); - - return data; -} diff --git a/drivers/staging/ccg/f_mass_storage.c b/drivers/staging/ccg/f_mass_storage.c deleted file mode 100644 index 20bc2b454ac2..000000000000 --- a/drivers/staging/ccg/f_mass_storage.c +++ /dev/null @@ -1,3135 +0,0 @@ -/* - * f_mass_storage.c -- Mass Storage USB Composite Function - * - * Copyright (C) 2003-2008 Alan Stern - * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz - * 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, this list of conditions, and the following disclaimer, - * without modification. - * 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 names of the above-listed copyright holders may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR - * CONTRIBUTORS 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. - */ - -/* - * The Mass Storage Function acts as a USB Mass Storage device, - * appearing to the host as a disk drive or as a CD-ROM drive. In - * addition to providing an example of a genuinely useful composite - * function for a USB device, it also illustrates a technique of - * double-buffering for increased throughput. - * - * For more information about MSF and in particular its module - * parameters and sysfs interface read the - * file. - */ - -/* - * MSF is configured by specifying a fsg_config structure. It has the - * following fields: - * - * nluns Number of LUNs function have (anywhere from 1 - * to FSG_MAX_LUNS which is 8). - * luns An array of LUN configuration values. This - * should be filled for each LUN that - * function will include (ie. for "nluns" - * LUNs). Each element of the array has - * the following fields: - * ->filename The path to the backing file for the LUN. - * Required if LUN is not marked as - * removable. - * ->ro Flag specifying access to the LUN shall be - * read-only. This is implied if CD-ROM - * emulation is enabled as well as when - * it was impossible to open "filename" - * in R/W mode. - * ->removable Flag specifying that LUN shall be indicated as - * being removable. - * ->cdrom Flag specifying that LUN shall be reported as - * being a CD-ROM. - * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12) - * commands for this LUN shall be ignored. - * - * vendor_name - * product_name - * release Information used as a reply to INQUIRY - * request. To use default set to NULL, - * NULL, 0xffff respectively. The first - * field should be 8 and the second 16 - * characters or less. - * - * can_stall Set to permit function to halt bulk endpoints. - * Disabled on some USB devices known not - * to work correctly. You should set it - * to true. - * - * If "removable" is not set for a LUN then a backing file must be - * specified. If it is set, then NULL filename means the LUN's medium - * is not loaded (an empty string as "filename" in the fsg_config - * structure causes error). The CD-ROM emulation includes a single - * data track and no audio tracks; hence there need be only one - * backing file per LUN. - * - * This function is heavily based on "File-backed Storage Gadget" by - * Alan Stern which in turn is heavily based on "Gadget Zero" by David - * Brownell. The driver's SCSI command interface was based on the - * "Information technology - Small Computer System Interface - 2" - * document from X3T9.2 Project 375D, Revision 10L, 7-SEP-93, - * available at . - * The single exception is opcode 0x23 (READ FORMAT CAPACITIES), which - * was based on the "Universal Serial Bus Mass Storage Class UFI - * Command Specification" document, Revision 1.0, December 14, 1998, - * available at - * . - */ - -/* - * Driver Design - * - * The MSF is fairly straightforward. There is a main kernel - * thread that handles most of the work. Interrupt routines field - * callbacks from the controller driver: bulk- and interrupt-request - * completion notifications, endpoint-0 events, and disconnect events. - * Completion events are passed to the main thread by wakeup calls. Many - * ep0 requests are handled at interrupt time, but SetInterface, - * SetConfiguration, and device reset requests are forwarded to the - * thread in the form of "exceptions" using SIGUSR1 signals (since they - * should interrupt any ongoing file I/O operations). - * - * The thread's main routine implements the standard command/data/status - * parts of a SCSI interaction. It and its subroutines are full of tests - * for pending signals/exceptions -- all this polling is necessary since - * the kernel has no setjmp/longjmp equivalents. (Maybe this is an - * indication that the driver really wants to be running in userspace.) - * An important point is that so long as the thread is alive it keeps an - * open reference to the backing file. This will prevent unmounting - * the backing file's underlying filesystem and could cause problems - * during system shutdown, for example. To prevent such problems, the - * thread catches INT, TERM, and KILL signals and converts them into - * an EXIT exception. - * - * In normal operation the main thread is started during the gadget's - * fsg_bind() callback and stopped during fsg_unbind(). But it can - * also exit when it receives a signal, and there's no point leaving - * the gadget running when the thread is dead. As of this moment, MSF - * provides no way to deregister the gadget when thread dies -- maybe - * a callback functions is needed. - * - * To provide maximum throughput, the driver uses a circular pipeline of - * buffer heads (struct fsg_buffhd). In principle the pipeline can be - * arbitrarily long; in practice the benefits don't justify having more - * than 2 stages (i.e., double buffering). But it helps to think of the - * pipeline as being a long one. Each buffer head contains a bulk-in and - * a bulk-out request pointer (since the buffer can be used for both - * output and input -- directions always are given from the host's - * point of view) as well as a pointer to the buffer and various state - * variables. - * - * Use of the pipeline follows a simple protocol. There is a variable - * (fsg->next_buffhd_to_fill) that points to the next buffer head to use. - * At any time that buffer head may still be in use from an earlier - * request, so each buffer head has a state variable indicating whether - * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the - * buffer head to be EMPTY, filling the buffer either by file I/O or by - * USB I/O (during which the buffer head is BUSY), and marking the buffer - * head FULL when the I/O is complete. Then the buffer will be emptied - * (again possibly by USB I/O, during which it is marked BUSY) and - * finally marked EMPTY again (possibly by a completion routine). - * - * A module parameter tells the driver to avoid stalling the bulk - * endpoints wherever the transport specification allows. This is - * necessary for some UDCs like the SuperH, which cannot reliably clear a - * halt on a bulk endpoint. However, under certain circumstances the - * Bulk-only specification requires a stall. In such cases the driver - * will halt the endpoint and set a flag indicating that it should clear - * the halt in software during the next device reset. Hopefully this - * will permit everything to work correctly. Furthermore, although the - * specification allows the bulk-out endpoint to halt when the host sends - * too much data, implementing this would cause an unavoidable race. - * The driver will always use the "no-stall" approach for OUT transfers. - * - * One subtle point concerns sending status-stage responses for ep0 - * requests. Some of these requests, such as device reset, can involve - * interrupting an ongoing file I/O operation, which might take an - * arbitrarily long time. During that delay the host might give up on - * the original ep0 request and issue a new one. When that happens the - * driver should not notify the host about completion of the original - * request, as the host will no longer be waiting for it. So the driver - * assigns to each ep0 request a unique tag, and it keeps track of the - * tag value of the request associated with a long-running exception - * (device-reset, interface-change, or configuration-change). When the - * exception handler is finished, the status-stage response is submitted - * only if the current ep0 request tag is equal to the exception request - * tag. Thus only the most recently received ep0 request will get a - * status-stage response. - * - * Warning: This driver source file is too long. It ought to be split up - * into a header file plus about 3 separate .c files, to handle the details - * of the Gadget, USB Mass Storage, and SCSI protocols. - */ - - -/* #define VERBOSE_DEBUG */ -/* #define DUMP_MSGS */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gadget_chips.h" - - -/*------------------------------------------------------------------------*/ - -#define FSG_DRIVER_DESC "Mass Storage Function" -#define FSG_DRIVER_VERSION "2009/09/11" - -static const char fsg_string_interface[] = "Mass Storage"; - -#define FSG_NO_DEVICE_STRINGS 1 -#define FSG_NO_OTG 1 -#define FSG_NO_INTR_EP 1 - -#include "storage_common.c" - - -/*-------------------------------------------------------------------------*/ - -struct fsg_dev; -struct fsg_common; - -/* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); - - /* - * Called prior to ejection. Negative return means error, - * zero means to continue with ejection, positive means not to - * eject. - */ - int (*pre_eject)(struct fsg_common *common, - struct fsg_lun *lun, int num); - /* - * Called after ejection. Negative return means error, zero - * or positive is just a success. - */ - int (*post_eject)(struct fsg_common *common, - struct fsg_lun *lun, int num); -}; - -/* Data shared by all the FSG instances. */ -struct fsg_common { - struct usb_gadget *gadget; - struct usb_composite_dev *cdev; - struct fsg_dev *fsg, *new_fsg; - wait_queue_head_t fsg_wait; - - /* filesem protects: backing files in use */ - struct rw_semaphore filesem; - - /* lock protects: state, all the req_busy's */ - spinlock_t lock; - - struct usb_ep *ep0; /* Copy of gadget->ep0 */ - struct usb_request *ep0req; /* Copy of cdev->req */ - unsigned int ep0_req_tag; - - struct fsg_buffhd *next_buffhd_to_fill; - struct fsg_buffhd *next_buffhd_to_drain; - struct fsg_buffhd *buffhds; - - int cmnd_size; - u8 cmnd[MAX_COMMAND_SIZE]; - - unsigned int nluns; - unsigned int lun; - struct fsg_lun *luns; - struct fsg_lun *curlun; - - unsigned int bulk_out_maxpacket; - enum fsg_state state; /* For exception handling */ - unsigned int exception_req_tag; - - enum data_direction data_dir; - u32 data_size; - u32 data_size_from_cmnd; - u32 tag; - u32 residue; - u32 usb_amount_left; - - unsigned int can_stall:1; - unsigned int free_storage_on_release:1; - unsigned int phase_error:1; - unsigned int short_packet_received:1; - unsigned int bad_lun_okay:1; - unsigned int running:1; - - int thread_wakeup_needed; - struct completion thread_notifier; - struct task_struct *thread_task; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void *private_data; - - /* - * Vendor (8 chars), product (16 chars), release (4 - * hexadecimal digits) and NUL byte - */ - char inquiry_string[8 + 16 + 4 + 1]; - - struct kref ref; -}; - -struct fsg_config { - unsigned nluns; - struct fsg_lun_config { - const char *filename; - char ro; - char removable; - char cdrom; - char nofua; - } luns[FSG_MAX_LUNS]; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void *private_data; - - const char *vendor_name; /* 8 characters or less */ - const char *product_name; /* 16 characters or less */ - u16 release; - - char can_stall; -}; - -struct fsg_dev { - struct usb_function function; - struct usb_gadget *gadget; /* Copy of cdev->gadget */ - struct fsg_common *common; - - u16 interface_number; - - unsigned int bulk_in_enabled:1; - unsigned int bulk_out_enabled:1; - - unsigned long atomic_bitflags; -#define IGNORE_BULK_OUT 0 - - struct usb_ep *bulk_in; - struct usb_ep *bulk_out; -}; - -static inline int __fsg_is_set(struct fsg_common *common, - const char *func, unsigned line) -{ - if (common->fsg) - return 1; - ERROR(common, "common->fsg is NULL in %s at %u\n", func, line); - WARN_ON(1); - return 0; -} - -#define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__)) - -static inline struct fsg_dev *fsg_from_func(struct usb_function *f) -{ - return container_of(f, struct fsg_dev, function); -} - -typedef void (*fsg_routine_t)(struct fsg_dev *); - -static int exception_in_progress(struct fsg_common *common) -{ - return common->state > FSG_STATE_IDLE; -} - -/* Make bulk-out requests be divisible by the maxpacket size */ -static void set_bulk_out_req_length(struct fsg_common *common, - struct fsg_buffhd *bh, unsigned int length) -{ - unsigned int rem; - - bh->bulk_out_intended_length = length; - rem = length % common->bulk_out_maxpacket; - if (rem > 0) - length += common->bulk_out_maxpacket - rem; - bh->outreq->length = length; -} - - -/*-------------------------------------------------------------------------*/ - -static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) -{ - const char *name; - - if (ep == fsg->bulk_in) - name = "bulk-in"; - else if (ep == fsg->bulk_out) - name = "bulk-out"; - else - name = ep->name; - DBG(fsg, "%s set halt\n", name); - return usb_ep_set_halt(ep); -} - - -/*-------------------------------------------------------------------------*/ - -/* These routines may be called in process context or in_irq */ - -/* Caller must hold fsg->lock */ -static void wakeup_thread(struct fsg_common *common) -{ - /* Tell the main thread that something has happened */ - common->thread_wakeup_needed = 1; - if (common->thread_task) - wake_up_process(common->thread_task); -} - -static void raise_exception(struct fsg_common *common, enum fsg_state new_state) -{ - unsigned long flags; - - /* - * Do nothing if a higher-priority exception is already in progress. - * If a lower-or-equal priority exception is in progress, preempt it - * and notify the main thread by sending it a signal. - */ - spin_lock_irqsave(&common->lock, flags); - if (common->state <= new_state) { - common->exception_req_tag = common->ep0_req_tag; - common->state = new_state; - if (common->thread_task) - send_sig_info(SIGUSR1, SEND_SIG_FORCED, - common->thread_task); - } - spin_unlock_irqrestore(&common->lock, flags); -} - - -/*-------------------------------------------------------------------------*/ - -static int ep0_queue(struct fsg_common *common) -{ - int rc; - - rc = usb_ep_queue(common->ep0, common->ep0req, GFP_ATOMIC); - common->ep0->driver_data = common; - if (rc != 0 && rc != -ESHUTDOWN) { - /* We can't do much more than wait for a reset */ - WARNING(common, "error in submission: %s --> %d\n", - common->ep0->name, rc); - } - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -/* Completion handlers. These always run in_irq. */ - -static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_common *common = ep->driver_data; - struct fsg_buffhd *bh = req->context; - - if (req->status || req->actual != req->length) - DBG(common, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); - if (req->status == -ECONNRESET) /* Request was cancelled */ - usb_ep_fifo_flush(ep); - - /* Hold the lock while we update the request and buffer states */ - smp_wmb(); - spin_lock(&common->lock); - bh->inreq_busy = 0; - bh->state = BUF_STATE_EMPTY; - wakeup_thread(common); - spin_unlock(&common->lock); -} - -static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_common *common = ep->driver_data; - struct fsg_buffhd *bh = req->context; - - dump_msg(common, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != bh->bulk_out_intended_length) - DBG(common, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, bh->bulk_out_intended_length); - if (req->status == -ECONNRESET) /* Request was cancelled */ - usb_ep_fifo_flush(ep); - - /* Hold the lock while we update the request and buffer states */ - smp_wmb(); - spin_lock(&common->lock); - bh->outreq_busy = 0; - bh->state = BUF_STATE_FULL; - wakeup_thread(common); - spin_unlock(&common->lock); -} - -static int fsg_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct fsg_dev *fsg = fsg_from_func(f); - struct usb_request *req = fsg->common->ep0req; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - if (!fsg_is_set(fsg->common)) - return -EOPNOTSUPP; - - ++fsg->common->ep0_req_tag; /* Record arrival of a new request */ - req->context = NULL; - req->length = 0; - dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); - - switch (ctrl->bRequest) { - - case US_BULK_RESET_REQUEST: - if (ctrl->bRequestType != - (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) - break; - if (w_index != fsg->interface_number || w_value != 0 || - w_length != 0) - return -EDOM; - - /* - * Raise an exception to stop the current operation - * and reinitialize our state. - */ - DBG(fsg, "bulk reset request\n"); - raise_exception(fsg->common, FSG_STATE_RESET); - return DELAYED_STATUS; - - case US_BULK_GET_MAX_LUN: - if (ctrl->bRequestType != - (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) - break; - if (w_index != fsg->interface_number || w_value != 0 || - w_length != 1) - return -EDOM; - VDBG(fsg, "get max LUN\n"); - *(u8 *)req->buf = fsg->common->nluns - 1; - - /* Respond with data/status */ - req->length = min((u16)1, w_length); - return ep0_queue(fsg->common); - } - - VDBG(fsg, - "unknown class-specific control req %02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - le16_to_cpu(ctrl->wValue), w_index, w_length); - return -EOPNOTSUPP; -} - - -/*-------------------------------------------------------------------------*/ - -/* All the following routines run in process context */ - -/* Use this for bulk or interrupt transfers, not ep0 */ -static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, - struct usb_request *req, int *pbusy, - enum fsg_buffer_state *state) -{ - int rc; - - if (ep == fsg->bulk_in) - dump_msg(fsg, "bulk-in", req->buf, req->length); - - spin_lock_irq(&fsg->common->lock); - *pbusy = 1; - *state = BUF_STATE_BUSY; - spin_unlock_irq(&fsg->common->lock); - rc = usb_ep_queue(ep, req, GFP_KERNEL); - if (rc != 0) { - *pbusy = 0; - *state = BUF_STATE_EMPTY; - - /* We can't do much more than wait for a reset */ - - /* - * Note: currently the net2280 driver fails zero-length - * submissions if DMA is enabled. - */ - if (rc != -ESHUTDOWN && - !(rc == -EOPNOTSUPP && req->length == 0)) - WARNING(fsg, "error in submission: %s --> %d\n", - ep->name, rc); - } -} - -static bool start_in_transfer(struct fsg_common *common, struct fsg_buffhd *bh) -{ - if (!fsg_is_set(common)) - return false; - start_transfer(common->fsg, common->fsg->bulk_in, - bh->inreq, &bh->inreq_busy, &bh->state); - return true; -} - -static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh) -{ - if (!fsg_is_set(common)) - return false; - start_transfer(common->fsg, common->fsg->bulk_out, - bh->outreq, &bh->outreq_busy, &bh->state); - return true; -} - -static int sleep_thread(struct fsg_common *common) -{ - int rc = 0; - - /* Wait until a signal arrives or we are woken up */ - for (;;) { - try_to_freeze(); - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) { - rc = -EINTR; - break; - } - if (common->thread_wakeup_needed) - break; - schedule(); - } - __set_current_state(TASK_RUNNING); - common->thread_wakeup_needed = 0; - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static int do_read(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - u32 lba; - struct fsg_buffhd *bh; - int rc; - u32 amount_left; - loff_t file_offset, file_offset_tmp; - unsigned int amount; - ssize_t nread; - - /* - * Get the starting Logical Block Address and check that it's - * not too big. - */ - if (common->cmnd[0] == READ_6) - lba = get_unaligned_be24(&common->cmnd[1]); - else { - lba = get_unaligned_be32(&common->cmnd[2]); - - /* - * We allow DPO (Disable Page Out = don't save data in the - * cache) and FUA (Force Unit Access = don't read from the - * cache), but we don't implement them. - */ - if ((common->cmnd[1] & ~0x18) != 0) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - file_offset = ((loff_t) lba) << curlun->blkbits; - - /* Carry out the file reads */ - amount_left = common->data_size_from_cmnd; - if (unlikely(amount_left == 0)) - return -EIO; /* No default reply */ - - for (;;) { - /* - * Figure out how much we need to read: - * Try to read the remaining amount. - * But don't read more than the buffer size. - * And don't try to read past the end of the file. - */ - amount = min(amount_left, FSG_BUFLEN); - amount = min((loff_t)amount, - curlun->file_length - file_offset); - - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(common); - if (rc) - return rc; - } - - /* - * If we were asked to read past the end of file, - * end with an empty buffer. - */ - if (amount == 0) { - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - bh->inreq->length = 0; - bh->state = BUF_STATE_FULL; - break; - } - - /* Perform the read */ - file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *)bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, - (unsigned long long)file_offset, (int)nread); - if (signal_pending(current)) - return -EINTR; - - if (nread < 0) { - LDBG(curlun, "error in file read: %d\n", (int)nread); - nread = 0; - } else if (nread < amount) { - LDBG(curlun, "partial file read: %d/%u\n", - (int)nread, amount); - nread = round_down(nread, curlun->blksize); - } - file_offset += nread; - amount_left -= nread; - common->residue -= nread; - - /* - * Except at the end of the transfer, nread will be - * equal to the buffer size, which is divisible by the - * bulk-in maxpacket size. - */ - bh->inreq->length = nread; - bh->state = BUF_STATE_FULL; - - /* If an error occurred, report it and its position */ - if (nread < amount) { - curlun->sense_data = SS_UNRECOVERED_READ_ERROR; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - if (amount_left == 0) - break; /* No more left to read */ - - /* Send this buffer and go read some more */ - bh->inreq->zero = 0; - if (!start_in_transfer(common, bh)) - /* Don't know what to do if common->fsg is NULL */ - return -EIO; - common->next_buffhd_to_fill = bh->next; - } - - return -EIO; /* No default reply */ -} - - -/*-------------------------------------------------------------------------*/ - -static int do_write(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - u32 lba; - struct fsg_buffhd *bh; - int get_some_more; - u32 amount_left_to_req, amount_left_to_write; - loff_t usb_offset, file_offset, file_offset_tmp; - unsigned int amount; - ssize_t nwritten; - int rc; - - if (curlun->ro) { - curlun->sense_data = SS_WRITE_PROTECTED; - return -EINVAL; - } - spin_lock(&curlun->filp->f_lock); - curlun->filp->f_flags &= ~O_SYNC; /* Default is not to wait */ - spin_unlock(&curlun->filp->f_lock); - - /* - * Get the starting Logical Block Address and check that it's - * not too big - */ - if (common->cmnd[0] == WRITE_6) - lba = get_unaligned_be24(&common->cmnd[1]); - else { - lba = get_unaligned_be32(&common->cmnd[2]); - - /* - * We allow DPO (Disable Page Out = don't save data in the - * cache) and FUA (Force Unit Access = write directly to the - * medium). We don't implement DPO; we implement FUA by - * performing synchronous output. - */ - if (common->cmnd[1] & ~0x18) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */ - spin_lock(&curlun->filp->f_lock); - curlun->filp->f_flags |= O_SYNC; - spin_unlock(&curlun->filp->f_lock); - } - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - /* Carry out the file writes */ - get_some_more = 1; - file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; - amount_left_to_req = common->data_size_from_cmnd; - amount_left_to_write = common->data_size_from_cmnd; - - while (amount_left_to_write > 0) { - - /* Queue a request for more data from the host */ - bh = common->next_buffhd_to_fill; - if (bh->state == BUF_STATE_EMPTY && get_some_more) { - - /* - * Figure out how much we want to get: - * Try to get the remaining amount, - * but not more than the buffer size. - */ - amount = min(amount_left_to_req, FSG_BUFLEN); - - /* Beyond the end of the backing file? */ - if (usb_offset >= curlun->file_length) { - get_some_more = 0; - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = - usb_offset >> curlun->blkbits; - curlun->info_valid = 1; - continue; - } - - /* Get the next buffer */ - usb_offset += amount; - common->usb_amount_left -= amount; - amount_left_to_req -= amount; - if (amount_left_to_req == 0) - get_some_more = 0; - - /* - * Except at the end of the transfer, amount will be - * equal to the buffer size, which is divisible by - * the bulk-out maxpacket size. - */ - set_bulk_out_req_length(common, bh, amount); - if (!start_out_transfer(common, bh)) - /* Dunno what to do if common->fsg is NULL */ - return -EIO; - common->next_buffhd_to_fill = bh->next; - continue; - } - - /* Write the received data to the backing file */ - bh = common->next_buffhd_to_drain; - if (bh->state == BUF_STATE_EMPTY && !get_some_more) - break; /* We stopped early */ - if (bh->state == BUF_STATE_FULL) { - smp_rmb(); - common->next_buffhd_to_drain = bh->next; - bh->state = BUF_STATE_EMPTY; - - /* Did something go wrong with the transfer? */ - if (bh->outreq->status != 0) { - curlun->sense_data = SS_COMMUNICATION_FAILURE; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - amount = bh->outreq->actual; - if (curlun->file_length - file_offset < amount) { - LERROR(curlun, - "write %u @ %llu beyond end %llu\n", - amount, (unsigned long long)file_offset, - (unsigned long long)curlun->file_length); - amount = curlun->file_length - file_offset; - } - - /* Don't accept excess data. The spec doesn't say - * what to do in this case. We'll ignore the error. - */ - amount = min(amount, bh->bulk_out_intended_length); - - /* Don't write a partial block */ - amount = round_down(amount, curlun->blksize); - if (amount == 0) - goto empty_write; - - /* Perform the write */ - file_offset_tmp = file_offset; - nwritten = vfs_write(curlun->filp, - (char __user *)bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, - (unsigned long long)file_offset, (int)nwritten); - if (signal_pending(current)) - return -EINTR; /* Interrupted! */ - - if (nwritten < 0) { - LDBG(curlun, "error in file write: %d\n", - (int)nwritten); - nwritten = 0; - } else if (nwritten < amount) { - LDBG(curlun, "partial file write: %d/%u\n", - (int)nwritten, amount); - nwritten = round_down(nwritten, curlun->blksize); - } - file_offset += nwritten; - amount_left_to_write -= nwritten; - common->residue -= nwritten; - - /* If an error occurred, report it and its position */ - if (nwritten < amount) { - curlun->sense_data = SS_WRITE_ERROR; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - empty_write: - /* Did the host decide to stop early? */ - if (bh->outreq->actual < bh->bulk_out_intended_length) { - common->short_packet_received = 1; - break; - } - continue; - } - - /* Wait for something to happen */ - rc = sleep_thread(common); - if (rc) - return rc; - } - - return -EIO; /* No default reply */ -} - - -/*-------------------------------------------------------------------------*/ - -static int do_synchronize_cache(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - int rc; - - /* We ignore the requested LBA and write out all file's - * dirty data buffers. */ - rc = fsg_lun_fsync_sub(curlun); - if (rc) - curlun->sense_data = SS_WRITE_ERROR; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static void invalidate_sub(struct fsg_lun *curlun) -{ - struct file *filp = curlun->filp; - struct inode *inode = file_inode(filp); - unsigned long rc; - - rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); - VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); -} - -static int do_verify(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - u32 lba; - u32 verification_length; - struct fsg_buffhd *bh = common->next_buffhd_to_fill; - loff_t file_offset, file_offset_tmp; - u32 amount_left; - unsigned int amount; - ssize_t nread; - - /* - * Get the starting Logical Block Address and check that it's - * not too big. - */ - lba = get_unaligned_be32(&common->cmnd[2]); - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - /* - * We allow DPO (Disable Page Out = don't save data in the - * cache) but we don't implement it. - */ - if (common->cmnd[1] & ~0x10) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - verification_length = get_unaligned_be16(&common->cmnd[7]); - if (unlikely(verification_length == 0)) - return -EIO; /* No default reply */ - - /* Prepare to carry out the file verify */ - amount_left = verification_length << curlun->blkbits; - file_offset = ((loff_t) lba) << curlun->blkbits; - - /* Write out all the dirty buffers before invalidating them */ - fsg_lun_fsync_sub(curlun); - if (signal_pending(current)) - return -EINTR; - - invalidate_sub(curlun); - if (signal_pending(current)) - return -EINTR; - - /* Just try to read the requested blocks */ - while (amount_left > 0) { - /* - * Figure out how much we need to read: - * Try to read the remaining amount, but not more than - * the buffer size. - * And don't try to read past the end of the file. - */ - amount = min(amount_left, FSG_BUFLEN); - amount = min((loff_t)amount, - curlun->file_length - file_offset); - if (amount == 0) { - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - /* Perform the read */ - file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, - (unsigned long long) file_offset, - (int) nread); - if (signal_pending(current)) - return -EINTR; - - if (nread < 0) { - LDBG(curlun, "error in file verify: %d\n", (int)nread); - nread = 0; - } else if (nread < amount) { - LDBG(curlun, "partial file verify: %d/%u\n", - (int)nread, amount); - nread = round_down(nread, curlun->blksize); - } - if (nread == 0) { - curlun->sense_data = SS_UNRECOVERED_READ_ERROR; - curlun->sense_data_info = - file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - file_offset += nread; - amount_left -= nread; - } - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - u8 *buf = (u8 *) bh->buf; - - if (!curlun) { /* Unsupported LUNs are okay */ - common->bad_lun_okay = 1; - memset(buf, 0, 36); - buf[0] = 0x7f; /* Unsupported, no device-type */ - buf[4] = 31; /* Additional length */ - return 36; - } - - buf[0] = curlun->cdrom ? TYPE_ROM : TYPE_DISK; - buf[1] = curlun->removable ? 0x80 : 0; - buf[2] = 2; /* ANSI SCSI level 2 */ - buf[3] = 2; /* SCSI-2 INQUIRY data format */ - buf[4] = 31; /* Additional length */ - buf[5] = 0; /* No special options */ - buf[6] = 0; - buf[7] = 0; - memcpy(buf + 8, common->inquiry_string, sizeof common->inquiry_string); - return 36; -} - -static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - u8 *buf = (u8 *) bh->buf; - u32 sd, sdinfo; - int valid; - - /* - * From the SCSI-2 spec., section 7.9 (Unit attention condition): - * - * If a REQUEST SENSE command is received from an initiator - * with a pending unit attention condition (before the target - * generates the contingent allegiance condition), then the - * target shall either: - * a) report any pending sense data and preserve the unit - * attention condition on the logical unit, or, - * b) report the unit attention condition, may discard any - * pending sense data, and clear the unit attention - * condition on the logical unit for that initiator. - * - * FSG normally uses option a); enable this code to use option b). - */ -#if 0 - if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { - curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; - } -#endif - - if (!curlun) { /* Unsupported LUNs are okay */ - common->bad_lun_okay = 1; - sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; - sdinfo = 0; - valid = 0; - } else { - sd = curlun->sense_data; - sdinfo = curlun->sense_data_info; - valid = curlun->info_valid << 7; - curlun->sense_data = SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - - memset(buf, 0, 18); - buf[0] = valid | 0x70; /* Valid, current error */ - buf[2] = SK(sd); - put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ - buf[7] = 18 - 8; /* Additional sense length */ - buf[12] = ASC(sd); - buf[13] = ASCQ(sd); - return 18; -} - -static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - u32 lba = get_unaligned_be32(&common->cmnd[2]); - int pmi = common->cmnd[8]; - u8 *buf = (u8 *)bh->buf; - - /* Check the PMI and LBA fields */ - if (pmi > 1 || (pmi == 0 && lba != 0)) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); - /* Max logical block */ - put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ - return 8; -} - -static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - int msf = common->cmnd[1] & 0x02; - u32 lba = get_unaligned_be32(&common->cmnd[2]); - u8 *buf = (u8 *)bh->buf; - - if (common->cmnd[1] & ~0x02) { /* Mask away MSF */ - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - memset(buf, 0, 8); - buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */ - store_cdrom_address(&buf[4], msf, lba); - return 8; -} - -static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - int msf = common->cmnd[1] & 0x02; - int start_track = common->cmnd[6]; - u8 *buf = (u8 *)bh->buf; - - if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ - start_track > 1) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - memset(buf, 0, 20); - buf[1] = (20-2); /* TOC data length */ - buf[2] = 1; /* First track number */ - buf[3] = 1; /* Last track number */ - buf[5] = 0x16; /* Data track, copying allowed */ - buf[6] = 0x01; /* Only track is number 1 */ - store_cdrom_address(&buf[8], msf, 0); - - buf[13] = 0x16; /* Lead-out track is data */ - buf[14] = 0xAA; /* Lead-out track number */ - store_cdrom_address(&buf[16], msf, curlun->num_sectors); - return 20; -} - -static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - int mscmnd = common->cmnd[0]; - u8 *buf = (u8 *) bh->buf; - u8 *buf0 = buf; - int pc, page_code; - int changeable_values, all_pages; - int valid_page = 0; - int len, limit; - - if ((common->cmnd[1] & ~0x08) != 0) { /* Mask away DBD */ - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - pc = common->cmnd[2] >> 6; - page_code = common->cmnd[2] & 0x3f; - if (pc == 3) { - curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; - return -EINVAL; - } - changeable_values = (pc == 1); - all_pages = (page_code == 0x3f); - - /* - * Write the mode parameter header. Fixed values are: default - * medium type, no cache control (DPOFUA), and no block descriptors. - * The only variable value is the WriteProtect bit. We will fill in - * the mode data length later. - */ - memset(buf, 0, 8); - if (mscmnd == MODE_SENSE) { - buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ - buf += 4; - limit = 255; - } else { /* MODE_SENSE_10 */ - buf[3] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ - buf += 8; - limit = 65535; /* Should really be FSG_BUFLEN */ - } - - /* No block descriptors */ - - /* - * The mode pages, in numerical order. The only page we support - * is the Caching page. - */ - if (page_code == 0x08 || all_pages) { - valid_page = 1; - buf[0] = 0x08; /* Page code */ - buf[1] = 10; /* Page length */ - memset(buf+2, 0, 10); /* None of the fields are changeable */ - - if (!changeable_values) { - buf[2] = 0x04; /* Write cache enable, */ - /* Read cache not disabled */ - /* No cache retention priorities */ - put_unaligned_be16(0xffff, &buf[4]); - /* Don't disable prefetch */ - /* Minimum prefetch = 0 */ - put_unaligned_be16(0xffff, &buf[8]); - /* Maximum prefetch */ - put_unaligned_be16(0xffff, &buf[10]); - /* Maximum prefetch ceiling */ - } - buf += 12; - } - - /* - * Check that a valid page was requested and the mode data length - * isn't too long. - */ - len = buf - buf0; - if (!valid_page || len > limit) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - /* Store the mode data length */ - if (mscmnd == MODE_SENSE) - buf0[0] = len - 1; - else - put_unaligned_be16(len - 2, buf0); - return len; -} - -static int do_start_stop(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - int loej, start; - - if (!curlun) { - return -EINVAL; - } else if (!curlun->removable) { - curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; - } else if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */ - (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */ - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - loej = common->cmnd[4] & 0x02; - start = common->cmnd[4] & 0x01; - - /* - * Our emulation doesn't support mounting; the medium is - * available for use as soon as it is loaded. - */ - if (start) { - if (!fsg_lun_is_open(curlun)) { - curlun->sense_data = SS_MEDIUM_NOT_PRESENT; - return -EINVAL; - } - return 0; - } - - /* Are we allowed to unload the media? */ - if (curlun->prevent_medium_removal) { - LDBG(curlun, "unload attempt prevented\n"); - curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; - return -EINVAL; - } - - if (!loej) - return 0; - - /* Simulate an unload/eject */ - if (common->ops && common->ops->pre_eject) { - int r = common->ops->pre_eject(common, curlun, - curlun - common->luns); - if (unlikely(r < 0)) - return r; - else if (r) - return 0; - } - - up_read(&common->filesem); - down_write(&common->filesem); - fsg_lun_close(curlun); - up_write(&common->filesem); - down_read(&common->filesem); - - return common->ops && common->ops->post_eject - ? min(0, common->ops->post_eject(common, curlun, - curlun - common->luns)) - : 0; -} - -static int do_prevent_allow(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - int prevent; - - if (!common->curlun) { - return -EINVAL; - } else if (!common->curlun->removable) { - common->curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; - } - - prevent = common->cmnd[4] & 0x01; - if ((common->cmnd[4] & ~0x01) != 0) { /* Mask away Prevent */ - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - if (curlun->prevent_medium_removal && !prevent) - fsg_lun_fsync_sub(curlun); - curlun->prevent_medium_removal = prevent; - return 0; -} - -static int do_read_format_capacities(struct fsg_common *common, - struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - u8 *buf = (u8 *) bh->buf; - - buf[0] = buf[1] = buf[2] = 0; - buf[3] = 8; /* Only the Current/Maximum Capacity Descriptor */ - buf += 4; - - put_unaligned_be32(curlun->num_sectors, &buf[0]); - /* Number of blocks */ - put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ - buf[4] = 0x02; /* Current capacity */ - return 12; -} - -static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = common->curlun; - - /* We don't support MODE SELECT */ - if (curlun) - curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; -} - - -/*-------------------------------------------------------------------------*/ - -static int halt_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - rc = fsg_set_halt(fsg, fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint halt\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_halt(fsg->bulk_in); - } - return rc; -} - -static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - DBG(fsg, "bulk-in set wedge\n"); - rc = usb_ep_set_wedge(fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint wedge\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_wedge(fsg->bulk_in); - } - return rc; -} - -static int throw_away_data(struct fsg_common *common) -{ - struct fsg_buffhd *bh; - u32 amount; - int rc; - - for (bh = common->next_buffhd_to_drain; - bh->state != BUF_STATE_EMPTY || common->usb_amount_left > 0; - bh = common->next_buffhd_to_drain) { - - /* Throw away the data in a filled buffer */ - if (bh->state == BUF_STATE_FULL) { - smp_rmb(); - bh->state = BUF_STATE_EMPTY; - common->next_buffhd_to_drain = bh->next; - - /* A short packet or an error ends everything */ - if (bh->outreq->actual < bh->bulk_out_intended_length || - bh->outreq->status != 0) { - raise_exception(common, - FSG_STATE_ABORT_BULK_OUT); - return -EINTR; - } - continue; - } - - /* Try to submit another request if we need one */ - bh = common->next_buffhd_to_fill; - if (bh->state == BUF_STATE_EMPTY - && common->usb_amount_left > 0) { - amount = min(common->usb_amount_left, FSG_BUFLEN); - - /* - * Except at the end of the transfer, amount will be - * equal to the buffer size, which is divisible by - * the bulk-out maxpacket size. - */ - set_bulk_out_req_length(common, bh, amount); - if (!start_out_transfer(common, bh)) - /* Dunno what to do if common->fsg is NULL */ - return -EIO; - common->next_buffhd_to_fill = bh->next; - common->usb_amount_left -= amount; - continue; - } - - /* Otherwise wait for something to happen */ - rc = sleep_thread(common); - if (rc) - return rc; - } - return 0; -} - -static int finish_reply(struct fsg_common *common) -{ - struct fsg_buffhd *bh = common->next_buffhd_to_fill; - int rc = 0; - - switch (common->data_dir) { - case DATA_DIR_NONE: - break; /* Nothing to send */ - - /* - * If we don't know whether the host wants to read or write, - * this must be CB or CBI with an unknown command. We mustn't - * try to send or receive any data. So stall both bulk pipes - * if we can and wait for a reset. - */ - case DATA_DIR_UNKNOWN: - if (!common->can_stall) { - /* Nothing */ - } else if (fsg_is_set(common)) { - fsg_set_halt(common->fsg, common->fsg->bulk_out); - rc = halt_bulk_in_endpoint(common->fsg); - } else { - /* Don't know what to do if common->fsg is NULL */ - rc = -EIO; - } - break; - - /* All but the last buffer of data must have already been sent */ - case DATA_DIR_TO_HOST: - if (common->data_size == 0) { - /* Nothing to send */ - - /* Don't know what to do if common->fsg is NULL */ - } else if (!fsg_is_set(common)) { - rc = -EIO; - - /* If there's no residue, simply send the last buffer */ - } else if (common->residue == 0) { - bh->inreq->zero = 0; - if (!start_in_transfer(common, bh)) - return -EIO; - common->next_buffhd_to_fill = bh->next; - - /* - * For Bulk-only, mark the end of the data with a short - * packet. If we are allowed to stall, halt the bulk-in - * endpoint. (Note: This violates the Bulk-Only Transport - * specification, which requires us to pad the data if we - * don't halt the endpoint. Presumably nobody will mind.) - */ - } else { - bh->inreq->zero = 1; - if (!start_in_transfer(common, bh)) - rc = -EIO; - common->next_buffhd_to_fill = bh->next; - if (common->can_stall) - rc = halt_bulk_in_endpoint(common->fsg); - } - break; - - /* - * We have processed all we want from the data the host has sent. - * There may still be outstanding bulk-out requests. - */ - case DATA_DIR_FROM_HOST: - if (common->residue == 0) { - /* Nothing to receive */ - - /* Did the host stop sending unexpectedly early? */ - } else if (common->short_packet_received) { - raise_exception(common, FSG_STATE_ABORT_BULK_OUT); - rc = -EINTR; - - /* - * We haven't processed all the incoming data. Even though - * we may be allowed to stall, doing so would cause a race. - * The controller may already have ACK'ed all the remaining - * bulk-out packets, in which case the host wouldn't see a - * STALL. Not realizing the endpoint was halted, it wouldn't - * clear the halt -- leading to problems later on. - */ -#if 0 - } else if (common->can_stall) { - if (fsg_is_set(common)) - fsg_set_halt(common->fsg, - common->fsg->bulk_out); - raise_exception(common, FSG_STATE_ABORT_BULK_OUT); - rc = -EINTR; -#endif - - /* - * We can't stall. Read in the excess data and throw it - * all away. - */ - } else { - rc = throw_away_data(common); - } - break; - } - return rc; -} - -static int send_status(struct fsg_common *common) -{ - struct fsg_lun *curlun = common->curlun; - struct fsg_buffhd *bh; - struct bulk_cs_wrap *csw; - int rc; - u8 status = US_BULK_STAT_OK; - u32 sd, sdinfo = 0; - - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(common); - if (rc) - return rc; - } - - if (curlun) { - sd = curlun->sense_data; - sdinfo = curlun->sense_data_info; - } else if (common->bad_lun_okay) - sd = SS_NO_SENSE; - else - sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; - - if (common->phase_error) { - DBG(common, "sending phase-error status\n"); - status = US_BULK_STAT_PHASE; - sd = SS_INVALID_COMMAND; - } else if (sd != SS_NO_SENSE) { - DBG(common, "sending command-failure status\n"); - status = US_BULK_STAT_FAIL; - VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" - " info x%x\n", - SK(sd), ASC(sd), ASCQ(sd), sdinfo); - } - - /* Store and send the Bulk-only CSW */ - csw = (void *)bh->buf; - - csw->Signature = cpu_to_le32(US_BULK_CS_SIGN); - csw->Tag = common->tag; - csw->Residue = cpu_to_le32(common->residue); - csw->Status = status; - - bh->inreq->length = US_BULK_CS_WRAP_LEN; - bh->inreq->zero = 0; - if (!start_in_transfer(common, bh)) - /* Don't know what to do if common->fsg is NULL */ - return -EIO; - - common->next_buffhd_to_fill = bh->next; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* - * Check whether the command is properly formed and whether its data size - * and direction agree with the values we already have. - */ -static int check_command(struct fsg_common *common, int cmnd_size, - enum data_direction data_dir, unsigned int mask, - int needs_medium, const char *name) -{ - int i; - int lun = common->cmnd[1] >> 5; - static const char dirletter[4] = {'u', 'o', 'i', 'n'}; - char hdlen[20]; - struct fsg_lun *curlun; - - hdlen[0] = 0; - if (common->data_dir != DATA_DIR_UNKNOWN) - sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir], - common->data_size); - VDBG(common, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", - name, cmnd_size, dirletter[(int) data_dir], - common->data_size_from_cmnd, common->cmnd_size, hdlen); - - /* - * We can't reply at all until we know the correct data direction - * and size. - */ - if (common->data_size_from_cmnd == 0) - data_dir = DATA_DIR_NONE; - if (common->data_size < common->data_size_from_cmnd) { - /* - * Host data size < Device data size is a phase error. - * Carry out the command, but only transfer as much as - * we are allowed. - */ - common->data_size_from_cmnd = common->data_size; - common->phase_error = 1; - } - common->residue = common->data_size; - common->usb_amount_left = common->data_size; - - /* Conflicting data directions is a phase error */ - if (common->data_dir != data_dir && common->data_size_from_cmnd > 0) { - common->phase_error = 1; - return -EINVAL; - } - - /* Verify the length of the command itself */ - if (cmnd_size != common->cmnd_size) { - - /* - * Special case workaround: There are plenty of buggy SCSI - * implementations. Many have issues with cbw->Length - * field passing a wrong command size. For those cases we - * always try to work around the problem by using the length - * sent by the host side provided it is at least as large - * as the correct command length. - * Examples of such cases would be MS-Windows, which issues - * REQUEST SENSE with cbw->Length == 12 where it should - * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and - * REQUEST SENSE with cbw->Length == 10 where it should - * be 6 as well. - */ - if (cmnd_size <= common->cmnd_size) { - DBG(common, "%s is buggy! Expected length %d " - "but we got %d\n", name, - cmnd_size, common->cmnd_size); - cmnd_size = common->cmnd_size; - } else { - common->phase_error = 1; - return -EINVAL; - } - } - - /* Check that the LUN values are consistent */ - if (common->lun != lun) - DBG(common, "using LUN %d from CBW, not LUN %d from CDB\n", - common->lun, lun); - - /* Check the LUN */ - curlun = common->curlun; - if (curlun) { - if (common->cmnd[0] != REQUEST_SENSE) { - curlun->sense_data = SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - } else { - common->bad_lun_okay = 0; - - /* - * INQUIRY and REQUEST SENSE commands are explicitly allowed - * to use unsupported LUNs; all others may not. - */ - if (common->cmnd[0] != INQUIRY && - common->cmnd[0] != REQUEST_SENSE) { - DBG(common, "unsupported LUN %d\n", common->lun); - return -EINVAL; - } - } - - /* - * If a unit attention condition exists, only INQUIRY and - * REQUEST SENSE commands are allowed; anything else must fail. - */ - if (curlun && curlun->unit_attention_data != SS_NO_SENSE && - common->cmnd[0] != INQUIRY && - common->cmnd[0] != REQUEST_SENSE) { - curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; - return -EINVAL; - } - - /* Check that only command bytes listed in the mask are non-zero */ - common->cmnd[1] &= 0x1f; /* Mask away the LUN */ - for (i = 1; i < cmnd_size; ++i) { - if (common->cmnd[i] && !(mask & (1 << i))) { - if (curlun) - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - } - - /* If the medium isn't mounted and the command needs to access - * it, return an error. */ - if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { - curlun->sense_data = SS_MEDIUM_NOT_PRESENT; - return -EINVAL; - } - - return 0; -} - -/* wrapper of check_command for data size in blocks handling */ -static int check_command_size_in_blocks(struct fsg_common *common, - int cmnd_size, enum data_direction data_dir, - unsigned int mask, int needs_medium, const char *name) -{ - if (common->curlun) - common->data_size_from_cmnd <<= common->curlun->blkbits; - return check_command(common, cmnd_size, data_dir, - mask, needs_medium, name); -} - -static int do_scsi_command(struct fsg_common *common) -{ - struct fsg_buffhd *bh; - int rc; - int reply = -EINVAL; - int i; - static char unknown[16]; - - dump_cdb(common); - - /* Wait for the next buffer to become available for data or status */ - bh = common->next_buffhd_to_fill; - common->next_buffhd_to_drain = bh; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(common); - if (rc) - return rc; - } - common->phase_error = 0; - common->short_packet_received = 0; - - down_read(&common->filesem); /* We're using the backing file */ - switch (common->cmnd[0]) { - - case INQUIRY: - common->data_size_from_cmnd = common->cmnd[4]; - reply = check_command(common, 6, DATA_DIR_TO_HOST, - (1<<4), 0, - "INQUIRY"); - if (reply == 0) - reply = do_inquiry(common, bh); - break; - - case MODE_SELECT: - common->data_size_from_cmnd = common->cmnd[4]; - reply = check_command(common, 6, DATA_DIR_FROM_HOST, - (1<<1) | (1<<4), 0, - "MODE SELECT(6)"); - if (reply == 0) - reply = do_mode_select(common, bh); - break; - - case MODE_SELECT_10: - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command(common, 10, DATA_DIR_FROM_HOST, - (1<<1) | (3<<7), 0, - "MODE SELECT(10)"); - if (reply == 0) - reply = do_mode_select(common, bh); - break; - - case MODE_SENSE: - common->data_size_from_cmnd = common->cmnd[4]; - reply = check_command(common, 6, DATA_DIR_TO_HOST, - (1<<1) | (1<<2) | (1<<4), 0, - "MODE SENSE(6)"); - if (reply == 0) - reply = do_mode_sense(common, bh); - break; - - case MODE_SENSE_10: - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command(common, 10, DATA_DIR_TO_HOST, - (1<<1) | (1<<2) | (3<<7), 0, - "MODE SENSE(10)"); - if (reply == 0) - reply = do_mode_sense(common, bh); - break; - - case ALLOW_MEDIUM_REMOVAL: - common->data_size_from_cmnd = 0; - reply = check_command(common, 6, DATA_DIR_NONE, - (1<<4), 0, - "PREVENT-ALLOW MEDIUM REMOVAL"); - if (reply == 0) - reply = do_prevent_allow(common); - break; - - case READ_6: - i = common->cmnd[4]; - common->data_size_from_cmnd = (i == 0) ? 256 : i; - reply = check_command_size_in_blocks(common, 6, - DATA_DIR_TO_HOST, - (7<<1) | (1<<4), 1, - "READ(6)"); - if (reply == 0) - reply = do_read(common); - break; - - case READ_10: - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command_size_in_blocks(common, 10, - DATA_DIR_TO_HOST, - (1<<1) | (0xf<<2) | (3<<7), 1, - "READ(10)"); - if (reply == 0) - reply = do_read(common); - break; - - case READ_12: - common->data_size_from_cmnd = - get_unaligned_be32(&common->cmnd[6]); - reply = check_command_size_in_blocks(common, 12, - DATA_DIR_TO_HOST, - (1<<1) | (0xf<<2) | (0xf<<6), 1, - "READ(12)"); - if (reply == 0) - reply = do_read(common); - break; - - case READ_CAPACITY: - common->data_size_from_cmnd = 8; - reply = check_command(common, 10, DATA_DIR_TO_HOST, - (0xf<<2) | (1<<8), 1, - "READ CAPACITY"); - if (reply == 0) - reply = do_read_capacity(common, bh); - break; - - case READ_HEADER: - if (!common->curlun || !common->curlun->cdrom) - goto unknown_cmnd; - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command(common, 10, DATA_DIR_TO_HOST, - (3<<7) | (0x1f<<1), 1, - "READ HEADER"); - if (reply == 0) - reply = do_read_header(common, bh); - break; - - case READ_TOC: - if (!common->curlun || !common->curlun->cdrom) - goto unknown_cmnd; - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command(common, 10, DATA_DIR_TO_HOST, - (7<<6) | (1<<1), 1, - "READ TOC"); - if (reply == 0) - reply = do_read_toc(common, bh); - break; - - case READ_FORMAT_CAPACITIES: - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command(common, 10, DATA_DIR_TO_HOST, - (3<<7), 1, - "READ FORMAT CAPACITIES"); - if (reply == 0) - reply = do_read_format_capacities(common, bh); - break; - - case REQUEST_SENSE: - common->data_size_from_cmnd = common->cmnd[4]; - reply = check_command(common, 6, DATA_DIR_TO_HOST, - (1<<4), 0, - "REQUEST SENSE"); - if (reply == 0) - reply = do_request_sense(common, bh); - break; - - case START_STOP: - common->data_size_from_cmnd = 0; - reply = check_command(common, 6, DATA_DIR_NONE, - (1<<1) | (1<<4), 0, - "START-STOP UNIT"); - if (reply == 0) - reply = do_start_stop(common); - break; - - case SYNCHRONIZE_CACHE: - common->data_size_from_cmnd = 0; - reply = check_command(common, 10, DATA_DIR_NONE, - (0xf<<2) | (3<<7), 1, - "SYNCHRONIZE CACHE"); - if (reply == 0) - reply = do_synchronize_cache(common); - break; - - case TEST_UNIT_READY: - common->data_size_from_cmnd = 0; - reply = check_command(common, 6, DATA_DIR_NONE, - 0, 1, - "TEST UNIT READY"); - break; - - /* - * Although optional, this command is used by MS-Windows. We - * support a minimal version: BytChk must be 0. - */ - case VERIFY: - common->data_size_from_cmnd = 0; - reply = check_command(common, 10, DATA_DIR_NONE, - (1<<1) | (0xf<<2) | (3<<7), 1, - "VERIFY"); - if (reply == 0) - reply = do_verify(common); - break; - - case WRITE_6: - i = common->cmnd[4]; - common->data_size_from_cmnd = (i == 0) ? 256 : i; - reply = check_command_size_in_blocks(common, 6, - DATA_DIR_FROM_HOST, - (7<<1) | (1<<4), 1, - "WRITE(6)"); - if (reply == 0) - reply = do_write(common); - break; - - case WRITE_10: - common->data_size_from_cmnd = - get_unaligned_be16(&common->cmnd[7]); - reply = check_command_size_in_blocks(common, 10, - DATA_DIR_FROM_HOST, - (1<<1) | (0xf<<2) | (3<<7), 1, - "WRITE(10)"); - if (reply == 0) - reply = do_write(common); - break; - - case WRITE_12: - common->data_size_from_cmnd = - get_unaligned_be32(&common->cmnd[6]); - reply = check_command_size_in_blocks(common, 12, - DATA_DIR_FROM_HOST, - (1<<1) | (0xf<<2) | (0xf<<6), 1, - "WRITE(12)"); - if (reply == 0) - reply = do_write(common); - break; - - /* - * Some mandatory commands that we recognize but don't implement. - * They don't mean much in this setting. It's left as an exercise - * for anyone interested to implement RESERVE and RELEASE in terms - * of Posix locks. - */ - case FORMAT_UNIT: - case RELEASE: - case RESERVE: - case SEND_DIAGNOSTIC: - /* Fall through */ - - default: -unknown_cmnd: - common->data_size_from_cmnd = 0; - sprintf(unknown, "Unknown x%02x", common->cmnd[0]); - reply = check_command(common, common->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown); - if (reply == 0) { - common->curlun->sense_data = SS_INVALID_COMMAND; - reply = -EINVAL; - } - break; - } - up_read(&common->filesem); - - if (reply == -EINTR || signal_pending(current)) - return -EINTR; - - /* Set up the single reply buffer for finish_reply() */ - if (reply == -EINVAL) - reply = 0; /* Error reply length */ - if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) { - reply = min((u32)reply, common->data_size_from_cmnd); - bh->inreq->length = reply; - bh->state = BUF_STATE_FULL; - common->residue -= reply; - } /* Otherwise it's already set */ - - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct usb_request *req = bh->outreq; - struct bulk_cb_wrap *cbw = req->buf; - struct fsg_common *common = fsg->common; - - /* Was this a real packet? Should it be ignored? */ - if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) - return -EINVAL; - - /* Is the CBW valid? */ - if (req->actual != US_BULK_CB_WRAP_LEN || - cbw->Signature != cpu_to_le32( - US_BULK_CB_SIGN)) { - DBG(fsg, "invalid CBW: len %u sig 0x%x\n", - req->actual, - le32_to_cpu(cbw->Signature)); - - /* - * The Bulk-only spec says we MUST stall the IN endpoint - * (6.6.1), so it's unavoidable. It also says we must - * retain this state until the next reset, but there's - * no way to tell the controller driver it should ignore - * Clear-Feature(HALT) requests. - * - * We aren't required to halt the OUT endpoint; instead - * we can simply accept and discard any data received - * until the next reset. - */ - wedge_bulk_in_endpoint(fsg); - set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - return -EINVAL; - } - - /* Is the CBW meaningful? */ - if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN || - cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { - DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " - "cmdlen %u\n", - cbw->Lun, cbw->Flags, cbw->Length); - - /* - * We can do anything we want here, so let's stall the - * bulk pipes if we are allowed to. - */ - if (common->can_stall) { - fsg_set_halt(fsg, fsg->bulk_out); - halt_bulk_in_endpoint(fsg); - } - return -EINVAL; - } - - /* Save the command for later */ - common->cmnd_size = cbw->Length; - memcpy(common->cmnd, cbw->CDB, common->cmnd_size); - if (cbw->Flags & US_BULK_FLAG_IN) - common->data_dir = DATA_DIR_TO_HOST; - else - common->data_dir = DATA_DIR_FROM_HOST; - common->data_size = le32_to_cpu(cbw->DataTransferLength); - if (common->data_size == 0) - common->data_dir = DATA_DIR_NONE; - common->lun = cbw->Lun; - if (common->lun >= 0 && common->lun < common->nluns) - common->curlun = &common->luns[common->lun]; - else - common->curlun = NULL; - common->tag = cbw->Tag; - return 0; -} - -static int get_next_command(struct fsg_common *common) -{ - struct fsg_buffhd *bh; - int rc = 0; - - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(common); - if (rc) - return rc; - } - - /* Queue a request to read a Bulk-only CBW */ - set_bulk_out_req_length(common, bh, US_BULK_CB_WRAP_LEN); - if (!start_out_transfer(common, bh)) - /* Don't know what to do if common->fsg is NULL */ - return -EIO; - - /* - * We will drain the buffer in software, which means we - * can reuse it for the next filling. No need to advance - * next_buffhd_to_fill. - */ - - /* Wait for the CBW to arrive */ - while (bh->state != BUF_STATE_FULL) { - rc = sleep_thread(common); - if (rc) - return rc; - } - smp_rmb(); - rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO; - bh->state = BUF_STATE_EMPTY; - - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static int alloc_request(struct fsg_common *common, struct usb_ep *ep, - struct usb_request **preq) -{ - *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); - if (*preq) - return 0; - ERROR(common, "can't allocate request for %s\n", ep->name); - return -ENOMEM; -} - -/* Reset interface setting and re-init endpoint state (toggle etc). */ -static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) -{ - struct fsg_dev *fsg; - int i, rc = 0; - - if (common->running) - DBG(common, "reset interface\n"); - -reset: - /* Deallocate the requests */ - if (common->fsg) { - fsg = common->fsg; - - for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - if (bh->inreq) { - usb_ep_free_request(fsg->bulk_in, bh->inreq); - bh->inreq = NULL; - } - if (bh->outreq) { - usb_ep_free_request(fsg->bulk_out, bh->outreq); - bh->outreq = NULL; - } - } - - /* Disable the endpoints */ - if (fsg->bulk_in_enabled) { - usb_ep_disable(fsg->bulk_in); - fsg->bulk_in_enabled = 0; - } - if (fsg->bulk_out_enabled) { - usb_ep_disable(fsg->bulk_out); - fsg->bulk_out_enabled = 0; - } - - common->fsg = NULL; - wake_up(&common->fsg_wait); - } - - common->running = 0; - if (!new_fsg || rc) - return rc; - - common->fsg = new_fsg; - fsg = common->fsg; - - /* Enable the endpoints */ - rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in); - if (rc) - goto reset; - rc = usb_ep_enable(fsg->bulk_in); - if (rc) - goto reset; - fsg->bulk_in->driver_data = common; - fsg->bulk_in_enabled = 1; - - rc = config_ep_by_speed(common->gadget, &(fsg->function), - fsg->bulk_out); - if (rc) - goto reset; - rc = usb_ep_enable(fsg->bulk_out); - if (rc) - goto reset; - fsg->bulk_out->driver_data = common; - fsg->bulk_out_enabled = 1; - common->bulk_out_maxpacket = usb_endpoint_maxp(fsg->bulk_out->desc); - clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - - /* Allocate the requests */ - for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - rc = alloc_request(common, fsg->bulk_in, &bh->inreq); - if (rc) - goto reset; - rc = alloc_request(common, fsg->bulk_out, &bh->outreq); - if (rc) - goto reset; - bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->context = bh->outreq->context = bh; - bh->inreq->complete = bulk_in_complete; - bh->outreq->complete = bulk_out_complete; - } - - common->running = 1; - for (i = 0; i < common->nluns; ++i) - common->luns[i].unit_attention_data = SS_RESET_OCCURRED; - return rc; -} - - -/****************************** ALT CONFIGS ******************************/ - -static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -{ - struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = fsg; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - return USB_GADGET_DELAYED_STATUS; -} - -static void fsg_disable(struct usb_function *f) -{ - struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); -} - - -/*-------------------------------------------------------------------------*/ - -static void handle_exception(struct fsg_common *common) -{ - siginfo_t info; - int i; - struct fsg_buffhd *bh; - enum fsg_state old_state; - struct fsg_lun *curlun; - unsigned int exception_req_tag; - - /* - * Clear the existing signals. Anything but SIGUSR1 is converted - * into a high-priority EXIT exception. - */ - for (;;) { - int sig = - dequeue_signal_lock(current, ¤t->blocked, &info); - if (!sig) - break; - if (sig != SIGUSR1) { - if (common->state < FSG_STATE_EXIT) - DBG(common, "Main thread exiting on signal\n"); - raise_exception(common, FSG_STATE_EXIT); - } - } - - /* Cancel all the pending transfers */ - if (likely(common->fsg)) { - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - if (bh->inreq_busy) - usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); - if (bh->outreq_busy) - usb_ep_dequeue(common->fsg->bulk_out, - bh->outreq); - } - - /* Wait until everything is idle */ - for (;;) { - int num_active = 0; - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - num_active += bh->inreq_busy + bh->outreq_busy; - } - if (num_active == 0) - break; - if (sleep_thread(common)) - return; - } - - /* Clear out the controller's fifos */ - if (common->fsg->bulk_in_enabled) - usb_ep_fifo_flush(common->fsg->bulk_in); - if (common->fsg->bulk_out_enabled) - usb_ep_fifo_flush(common->fsg->bulk_out); - } - - /* - * Reset the I/O buffer states and pointers, the SCSI - * state, and the exception. Then invoke the handler. - */ - spin_lock_irq(&common->lock); - - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - bh->state = BUF_STATE_EMPTY; - } - common->next_buffhd_to_fill = &common->buffhds[0]; - common->next_buffhd_to_drain = &common->buffhds[0]; - exception_req_tag = common->exception_req_tag; - old_state = common->state; - - if (old_state == FSG_STATE_ABORT_BULK_OUT) - common->state = FSG_STATE_STATUS_PHASE; - else { - for (i = 0; i < common->nluns; ++i) { - curlun = &common->luns[i]; - curlun->prevent_medium_removal = 0; - curlun->sense_data = SS_NO_SENSE; - curlun->unit_attention_data = SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - common->state = FSG_STATE_IDLE; - } - spin_unlock_irq(&common->lock); - - /* Carry out any extra actions required for the exception */ - switch (old_state) { - case FSG_STATE_ABORT_BULK_OUT: - send_status(common); - spin_lock_irq(&common->lock); - if (common->state == FSG_STATE_STATUS_PHASE) - common->state = FSG_STATE_IDLE; - spin_unlock_irq(&common->lock); - break; - - case FSG_STATE_RESET: - /* - * In case we were forced against our will to halt a - * bulk endpoint, clear the halt now. (The SuperH UDC - * requires this.) - */ - if (!fsg_is_set(common)) - break; - if (test_and_clear_bit(IGNORE_BULK_OUT, - &common->fsg->atomic_bitflags)) - usb_ep_clear_halt(common->fsg->bulk_in); - - if (common->ep0_req_tag == exception_req_tag) - ep0_queue(common); /* Complete the status stage */ - - /* - * Technically this should go here, but it would only be - * a waste of time. Ditto for the INTERFACE_CHANGE and - * CONFIG_CHANGE cases. - */ - /* for (i = 0; i < common->nluns; ++i) */ - /* common->luns[i].unit_attention_data = */ - /* SS_RESET_OCCURRED; */ - break; - - case FSG_STATE_CONFIG_CHANGE: - do_set_interface(common, common->new_fsg); - if (common->new_fsg) - usb_composite_setup_continue(common->cdev); - break; - - case FSG_STATE_EXIT: - case FSG_STATE_TERMINATED: - do_set_interface(common, NULL); /* Free resources */ - spin_lock_irq(&common->lock); - common->state = FSG_STATE_TERMINATED; /* Stop the thread */ - spin_unlock_irq(&common->lock); - break; - - case FSG_STATE_INTERFACE_CHANGE: - case FSG_STATE_DISCONNECT: - case FSG_STATE_COMMAND_PHASE: - case FSG_STATE_DATA_PHASE: - case FSG_STATE_STATUS_PHASE: - case FSG_STATE_IDLE: - break; - } -} - - -/*-------------------------------------------------------------------------*/ - -static int fsg_main_thread(void *common_) -{ - struct fsg_common *common = common_; - - /* - * Allow the thread to be killed by a signal, but set the signal mask - * to block everything but INT, TERM, KILL, and USR1. - */ - allow_signal(SIGINT); - allow_signal(SIGTERM); - allow_signal(SIGKILL); - allow_signal(SIGUSR1); - - /* Allow the thread to be frozen */ - set_freezable(); - - /* - * Arrange for userspace references to be interpreted as kernel - * pointers. That way we can pass a kernel pointer to a routine - * that expects a __user pointer and it will work okay. - */ - set_fs(get_ds()); - - /* The main loop */ - while (common->state != FSG_STATE_TERMINATED) { - if (exception_in_progress(common) || signal_pending(current)) { - handle_exception(common); - continue; - } - - if (!common->running) { - sleep_thread(common); - continue; - } - - if (get_next_command(common)) - continue; - - spin_lock_irq(&common->lock); - if (!exception_in_progress(common)) - common->state = FSG_STATE_DATA_PHASE; - spin_unlock_irq(&common->lock); - - if (do_scsi_command(common) || finish_reply(common)) - continue; - - spin_lock_irq(&common->lock); - if (!exception_in_progress(common)) - common->state = FSG_STATE_STATUS_PHASE; - spin_unlock_irq(&common->lock); - - if (send_status(common)) - continue; - - spin_lock_irq(&common->lock); - if (!exception_in_progress(common)) - common->state = FSG_STATE_IDLE; - spin_unlock_irq(&common->lock); - } - - spin_lock_irq(&common->lock); - common->thread_task = NULL; - spin_unlock_irq(&common->lock); - - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { - struct fsg_lun *curlun = common->luns; - unsigned i = common->nluns; - - down_write(&common->filesem); - for (; i--; ++curlun) { - if (!fsg_lun_is_open(curlun)) - continue; - - fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(&common->filesem); - } - - /* Let fsg_unbind() know the thread has exited */ - complete_and_exit(&common->thread_notifier, 0); -} - - -/*************************** DEVICE ATTRIBUTES ***************************/ - -static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); -static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua); -static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); - -static struct device_attribute dev_attr_ro_cdrom = - __ATTR(ro, 0444, fsg_show_ro, NULL); -static struct device_attribute dev_attr_file_nonremovable = - __ATTR(file, 0444, fsg_show_file, NULL); - - -/****************************** FSG COMMON ******************************/ - -static void fsg_common_release(struct kref *ref); - -static void fsg_lun_release(struct device *dev) -{ - /* Nothing needs to be done */ -} - -static inline void fsg_common_get(struct fsg_common *common) -{ - kref_get(&common->ref); -} - -static inline void fsg_common_put(struct fsg_common *common) -{ - kref_put(&common->ref, fsg_common_release); -} - -static struct fsg_common *fsg_common_init(struct fsg_common *common, - struct usb_composite_dev *cdev, - struct fsg_config *cfg) -{ - struct usb_gadget *gadget = cdev->gadget; - struct fsg_buffhd *bh; - struct fsg_lun *curlun; - struct fsg_lun_config *lcfg; - int nluns, i, rc; - char *pathbuf; - - rc = fsg_num_buffers_validate(); - if (rc != 0) - return ERR_PTR(rc); - - /* Find out how many LUNs there should be */ - nluns = cfg->nluns; - if (nluns < 1 || nluns > FSG_MAX_LUNS) { - dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns); - return ERR_PTR(-EINVAL); - } - - /* Allocate? */ - if (!common) { - common = kzalloc(sizeof *common, GFP_KERNEL); - if (!common) - return ERR_PTR(-ENOMEM); - common->free_storage_on_release = 1; - } else { - memset(common, 0, sizeof *common); - common->free_storage_on_release = 0; - } - - common->buffhds = kcalloc(fsg_num_buffers, - sizeof *(common->buffhds), GFP_KERNEL); - if (!common->buffhds) { - if (common->free_storage_on_release) - kfree(common); - return ERR_PTR(-ENOMEM); - } - - common->ops = cfg->ops; - common->private_data = cfg->private_data; - - common->gadget = gadget; - common->ep0 = gadget->ep0; - common->ep0req = cdev->req; - common->cdev = cdev; - - /* Maybe allocate device-global string IDs, and patch descriptors */ - if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { - rc = usb_string_id(cdev); - if (unlikely(rc < 0)) - goto error_release; - fsg_strings[FSG_STRING_INTERFACE].id = rc; - fsg_intf_desc.iInterface = rc; - } - - /* - * Create the LUNs, open their backing files, and register the - * LUN devices in sysfs. - */ - curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); - if (unlikely(!curlun)) { - rc = -ENOMEM; - goto error_release; - } - common->luns = curlun; - - init_rwsem(&common->filesem); - - for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { - curlun->cdrom = !!lcfg->cdrom; - curlun->ro = lcfg->cdrom || lcfg->ro; - curlun->initially_ro = curlun->ro; - curlun->removable = lcfg->removable; - curlun->dev.release = fsg_lun_release; - curlun->dev.parent = &gadget->dev; - /* curlun->dev.driver = &fsg_driver.driver; XXX */ - dev_set_drvdata(&curlun->dev, &common->filesem); - dev_set_name(&curlun->dev, "lun%d", i); - - rc = device_register(&curlun->dev); - if (rc) { - INFO(common, "failed to register LUN%d: %d\n", i, rc); - common->nluns = i; - put_device(&curlun->dev); - goto error_release; - } - - rc = device_create_file(&curlun->dev, - curlun->cdrom - ? &dev_attr_ro_cdrom - : &dev_attr_ro); - if (rc) - goto error_luns; - rc = device_create_file(&curlun->dev, - curlun->removable - ? &dev_attr_file - : &dev_attr_file_nonremovable); - if (rc) - goto error_luns; - rc = device_create_file(&curlun->dev, &dev_attr_nofua); - if (rc) - goto error_luns; - - if (lcfg->filename) { - rc = fsg_lun_open(curlun, lcfg->filename); - if (rc) - goto error_luns; - } else if (!curlun->removable) { - ERROR(common, "no file given for LUN%d\n", i); - rc = -EINVAL; - goto error_luns; - } - } - common->nluns = nluns; - - /* Data buffers cyclic list */ - bh = common->buffhds; - i = fsg_num_buffers; - goto buffhds_first_it; - do { - bh->next = bh + 1; - ++bh; -buffhds_first_it: - bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); - if (unlikely(!bh->buf)) { - rc = -ENOMEM; - goto error_release; - } - } while (--i); - bh->next = common->buffhds; - - /* Prepare inquiryString */ - if (cfg->release != 0xffff) { - i = cfg->release; - } else { - i = usb_gadget_controller_number(gadget); - if (i >= 0) { - i = 0x0300 + i; - } else { - WARNING(common, "controller '%s' not recognized\n", - gadget->name); - i = 0x0399; - } - } - snprintf(common->inquiry_string, sizeof common->inquiry_string, - "%-8s%-16s%04x", cfg->vendor_name ?: "Linux", - /* Assume product name dependent on the first LUN */ - cfg->product_name ?: (common->luns->cdrom - ? "File-Stor Gadget" - : "File-CD Gadget"), - i); - - /* - * Some peripheral controllers are known not to be able to - * halt bulk endpoints correctly. If one of them is present, - * disable stalls. - */ - common->can_stall = cfg->can_stall && - !(gadget_is_at91(common->gadget)); - - spin_lock_init(&common->lock); - kref_init(&common->ref); - - /* Tell the thread to start working */ - common->thread_task = - kthread_create(fsg_main_thread, common, "file-storage"); - if (IS_ERR(common->thread_task)) { - rc = PTR_ERR(common->thread_task); - goto error_release; - } - init_completion(&common->thread_notifier); - init_waitqueue_head(&common->fsg_wait); - - /* Information */ - INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); - INFO(common, "Number of LUNs=%d\n", common->nluns); - - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); - for (i = 0, nluns = common->nluns, curlun = common->luns; - i < nluns; - ++curlun, ++i) { - char *p = "(no medium)"; - if (fsg_lun_is_open(curlun)) { - p = "(error)"; - if (pathbuf) { - p = d_path(&curlun->filp->f_path, - pathbuf, PATH_MAX); - if (IS_ERR(p)) - p = "(error)"; - } - } - LINFO(curlun, "LUN: %s%s%sfile: %s\n", - curlun->removable ? "removable " : "", - curlun->ro ? "read only " : "", - curlun->cdrom ? "CD-ROM " : "", - p); - } - kfree(pathbuf); - - DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); - - wake_up_process(common->thread_task); - - return common; - -error_luns: - common->nluns = i + 1; -error_release: - common->state = FSG_STATE_TERMINATED; /* The thread is dead */ - /* Call fsg_common_release() directly, ref might be not initialised. */ - fsg_common_release(&common->ref); - return ERR_PTR(rc); -} - -static void fsg_common_release(struct kref *ref) -{ - struct fsg_common *common = container_of(ref, struct fsg_common, ref); - - /* If the thread isn't already dead, tell it to exit now */ - if (common->state != FSG_STATE_TERMINATED) { - raise_exception(common, FSG_STATE_EXIT); - wait_for_completion(&common->thread_notifier); - } - - if (likely(common->luns)) { - struct fsg_lun *lun = common->luns; - unsigned i = common->nluns; - - /* In error recovery common->nluns may be zero. */ - for (; i; --i, ++lun) { - device_remove_file(&lun->dev, &dev_attr_nofua); - device_remove_file(&lun->dev, - lun->cdrom - ? &dev_attr_ro_cdrom - : &dev_attr_ro); - device_remove_file(&lun->dev, - lun->removable - ? &dev_attr_file - : &dev_attr_file_nonremovable); - fsg_lun_close(lun); - device_unregister(&lun->dev); - } - - kfree(common->luns); - } - - { - struct fsg_buffhd *bh = common->buffhds; - unsigned i = fsg_num_buffers; - do { - kfree(bh->buf); - } while (++bh, --i); - } - - kfree(common->buffhds); - if (common->free_storage_on_release) - kfree(common); -} - - -/*-------------------------------------------------------------------------*/ - -static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct fsg_dev *fsg = fsg_from_func(f); - struct fsg_common *common = fsg->common; - - DBG(fsg, "unbind\n"); - if (fsg->common->fsg == fsg) { - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - /* FIXME: make interruptible or killable somehow? */ - wait_event(common->fsg_wait, common->fsg != fsg); - } - - fsg_common_put(common); - usb_free_descriptors(fsg->function.descriptors); - usb_free_descriptors(fsg->function.hs_descriptors); - usb_free_descriptors(fsg->function.ss_descriptors); - kfree(fsg); -} - -static int fsg_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct fsg_dev *fsg = fsg_from_func(f); - struct usb_gadget *gadget = c->cdev->gadget; - int i; - struct usb_ep *ep; - - fsg->gadget = gadget; - - /* New interface */ - i = usb_interface_id(c, f); - if (i < 0) - return i; - fsg_intf_desc.bInterfaceNumber = i; - fsg->interface_number = i; - - /* Find all the endpoints we will use */ - ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); - if (!ep) - goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ - fsg->bulk_in = ep; - - ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); - if (!ep) - goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ - fsg->bulk_out = ep; - - /* Copy descriptors */ - f->descriptors = usb_copy_descriptors(fsg_fs_function); - if (unlikely(!f->descriptors)) - return -ENOMEM; - - if (gadget_is_dualspeed(gadget)) { - /* Assume endpoint addresses are the same for both speeds */ - fsg_hs_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_hs_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); - if (unlikely(!f->hs_descriptors)) { - usb_free_descriptors(f->descriptors); - return -ENOMEM; - } - } - - if (gadget_is_superspeed(gadget)) { - unsigned max_burst; - - /* Calculate bMaxBurst, we know packet size is 1024 */ - max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); - - fsg_ss_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; - - fsg_ss_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; - - f->ss_descriptors = usb_copy_descriptors(fsg_ss_function); - if (unlikely(!f->ss_descriptors)) { - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); - return -ENOMEM; - } - } - - return 0; - -autoconf_fail: - ERROR(fsg, "unable to autoconfigure all endpoints\n"); - return -ENOTSUPP; -} - - -/****************************** ADD FUNCTION ******************************/ - -static struct usb_gadget_strings *fsg_strings_array[] = { - &fsg_stringtab, - NULL, -}; - -static int fsg_bind_config(struct usb_composite_dev *cdev, - struct usb_configuration *c, - struct fsg_common *common) -{ - struct fsg_dev *fsg; - int rc; - - fsg = kzalloc(sizeof *fsg, GFP_KERNEL); - if (unlikely(!fsg)) - return -ENOMEM; - - fsg->function.name = FSG_DRIVER_DESC; - fsg->function.strings = fsg_strings_array; - fsg->function.bind = fsg_bind; - fsg->function.unbind = fsg_unbind; - fsg->function.setup = fsg_setup; - fsg->function.set_alt = fsg_set_alt; - fsg->function.disable = fsg_disable; - - fsg->common = common; - /* - * Our caller holds a reference to common structure so we - * don't have to be worry about it being freed until we return - * from this function. So instead of incrementing counter now - * and decrement in error recovery we increment it only when - * call to usb_add_function() was successful. - */ - - rc = usb_add_function(c, &fsg->function); - if (unlikely(rc)) - kfree(fsg); - else - fsg_common_get(fsg->common); - return rc; -} - - -/************************* Module parameters *************************/ - -struct fsg_module_parameters { - char *file[FSG_MAX_LUNS]; - bool ro[FSG_MAX_LUNS]; - bool removable[FSG_MAX_LUNS]; - bool cdrom[FSG_MAX_LUNS]; - bool nofua[FSG_MAX_LUNS]; - - unsigned int file_count, ro_count, removable_count, cdrom_count; - unsigned int nofua_count; - unsigned int luns; /* nluns */ - bool stall; /* can_stall */ -}; - -#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ - module_param_array_named(prefix ## name, params.name, type, \ - &prefix ## params.name ## _count, \ - S_IRUGO); \ - MODULE_PARM_DESC(prefix ## name, desc) - -#define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \ - module_param_named(prefix ## name, params.name, type, \ - S_IRUGO); \ - MODULE_PARM_DESC(prefix ## name, desc) - -#define FSG_MODULE_PARAMETERS(prefix, params) \ - _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \ - "names of backing files or devices"); \ - _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \ - "true to force read-only"); \ - _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \ - "true to simulate removable media"); \ - _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \ - "true to simulate CD-ROM instead of disk"); \ - _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \ - "true to ignore SCSI WRITE(10,12) FUA bit"); \ - _FSG_MODULE_PARAM(prefix, params, luns, uint, \ - "number of LUNs"); \ - _FSG_MODULE_PARAM(prefix, params, stall, bool, \ - "false to prevent bulk stalls") - -static void -fsg_config_from_params(struct fsg_config *cfg, - const struct fsg_module_parameters *params) -{ - struct fsg_lun_config *lun; - unsigned i; - - /* Configure LUNs */ - cfg->nluns = - min(params->luns ?: (params->file_count ?: 1u), - (unsigned)FSG_MAX_LUNS); - for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) { - lun->ro = !!params->ro[i]; - lun->cdrom = !!params->cdrom[i]; - lun->removable = !!params->removable[i]; - lun->filename = - params->file_count > i && params->file[i][0] - ? params->file[i] - : 0; - } - - /* Let MSF use defaults */ - cfg->vendor_name = 0; - cfg->product_name = 0; - cfg->release = 0xffff; - - cfg->ops = NULL; - cfg->private_data = NULL; - - /* Finalise */ - cfg->can_stall = params->stall; -} - -static inline struct fsg_common * -fsg_common_from_params(struct fsg_common *common, - struct usb_composite_dev *cdev, - const struct fsg_module_parameters *params) - __attribute__((unused)); -static inline struct fsg_common * -fsg_common_from_params(struct fsg_common *common, - struct usb_composite_dev *cdev, - const struct fsg_module_parameters *params) -{ - struct fsg_config cfg; - fsg_config_from_params(&cfg, params); - return fsg_common_init(common, cdev, &cfg); -} diff --git a/drivers/staging/ccg/f_rndis.c b/drivers/staging/ccg/f_rndis.c deleted file mode 100644 index b1681e45aca7..000000000000 --- a/drivers/staging/ccg/f_rndis.c +++ /dev/null @@ -1,918 +0,0 @@ -/* - * f_rndis.c -- RNDIS link function driver - * - * Copyright (C) 2003-2005,2008 David Brownell - * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger - * Copyright (C) 2008 Nokia Corporation - * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (mina86@mina86.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. - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include - -#include - -#include "u_ether.h" -#include "rndis.h" - - -/* - * This function is an RNDIS Ethernet port -- a Microsoft protocol that's - * been promoted instead of the standard CDC Ethernet. The published RNDIS - * spec is ambiguous, incomplete, and needlessly complex. Variants such as - * ActiveSync have even worse status in terms of specification. - * - * In short: it's a protocol controlled by (and for) Microsoft, not for an - * Open ecosystem or markets. Linux supports it *only* because Microsoft - * doesn't support the CDC Ethernet standard. - * - * The RNDIS data transfer model is complex, with multiple Ethernet packets - * per USB message, and out of band data. The control model is built around - * what's essentially an "RNDIS RPC" protocol. It's all wrapped in a CDC ACM - * (modem, not Ethernet) veneer, with those ACM descriptors being entirely - * useless (they're ignored). RNDIS expects to be the only function in its - * configuration, so it's no real help if you need composite devices; and - * it expects to be the first configuration too. - * - * There is a single technical advantage of RNDIS over CDC Ethernet, if you - * discount the fluff that its RPC can be made to deliver: it doesn't need - * a NOP altsetting for the data interface. That lets it work on some of the - * "so smart it's stupid" hardware which takes over configuration changes - * from the software, and adds restrictions like "no altsettings". - * - * Unfortunately MSFT's RNDIS drivers are buggy. They hang or oops, and - * have all sorts of contrary-to-specification oddities that can prevent - * them from working sanely. Since bugfixes (or accurate specs, letting - * Linux work around those bugs) are unlikely to ever come from MSFT, you - * may want to avoid using RNDIS on purely operational grounds. - * - * Omissions from the RNDIS 1.0 specification include: - * - * - Power management ... references data that's scattered around lots - * of other documentation, which is incorrect/incomplete there too. - * - * - There are various undocumented protocol requirements, like the need - * to send garbage in some control-OUT messages. - * - * - MS-Windows drivers sometimes emit undocumented requests. - */ - -struct f_rndis { - struct gether port; - u8 ctrl_id, data_id; - u8 ethaddr[ETH_ALEN]; - u32 vendorID; - const char *manufacturer; - int config; - - struct usb_ep *notify; - struct usb_request *notify_req; - atomic_t notify_count; -}; - -static inline struct f_rndis *func_to_rndis(struct usb_function *f) -{ - return container_of(f, struct f_rndis, port.func); -} - -/* peak (theoretical) bulk transfer rate in bits-per-second */ -static unsigned int bitrate(struct usb_gadget *g) -{ - if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) - return 13 * 1024 * 8 * 1000 * 8; - else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return 13 * 512 * 8 * 1000 * 8; - else - return 19 * 64 * 1 * 1000 * 8; -} - -/*-------------------------------------------------------------------------*/ - -/* - */ - -#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ -#define STATUS_BYTECOUNT 8 /* 8 bytes data */ - - -/* interface descriptor: */ - -static struct usb_interface_descriptor rndis_control_intf = { - .bLength = sizeof rndis_control_intf, - .bDescriptorType = USB_DT_INTERFACE, - - /* .bInterfaceNumber = DYNAMIC */ - /* status endpoint is optional; this could be patched later */ - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR, - /* .iInterface = DYNAMIC */ -}; - -static struct usb_cdc_header_desc header_desc = { - .bLength = sizeof header_desc, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_HEADER_TYPE, - - .bcdCDC = cpu_to_le16(0x0110), -}; - -static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = { - .bLength = sizeof call_mgmt_descriptor, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, - - .bmCapabilities = 0x00, - .bDataInterface = 0x01, -}; - -static struct usb_cdc_acm_descriptor rndis_acm_descriptor = { - .bLength = sizeof rndis_acm_descriptor, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_ACM_TYPE, - - .bmCapabilities = 0x00, -}; - -static struct usb_cdc_union_desc rndis_union_desc = { - .bLength = sizeof(rndis_union_desc), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_UNION_TYPE, - /* .bMasterInterface0 = DYNAMIC */ - /* .bSlaveInterface0 = DYNAMIC */ -}; - -/* the data interface has two bulk endpoints */ - -static struct usb_interface_descriptor rndis_data_intf = { - .bLength = sizeof rndis_data_intf, - .bDescriptorType = USB_DT_INTERFACE, - - /* .bInterfaceNumber = DYNAMIC */ - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_CDC_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - /* .iInterface = DYNAMIC */ -}; - - -static struct usb_interface_assoc_descriptor -rndis_iad_descriptor = { - .bLength = sizeof rndis_iad_descriptor, - .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, - - .bFirstInterface = 0, /* XXX, hardcoded */ - .bInterfaceCount = 2, // control + data - .bFunctionClass = USB_CLASS_COMM, - .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bFunctionProtocol = USB_CDC_PROTO_NONE, - /* .iFunction = DYNAMIC */ -}; - -/* full speed support: */ - -static struct usb_endpoint_descriptor fs_notify_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, -}; - -static struct usb_endpoint_descriptor fs_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_endpoint_descriptor fs_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_descriptor_header *eth_fs_function[] = { - (struct usb_descriptor_header *) &rndis_iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) &rndis_control_intf, - (struct usb_descriptor_header *) &header_desc, - (struct usb_descriptor_header *) &call_mgmt_descriptor, - (struct usb_descriptor_header *) &rndis_acm_descriptor, - (struct usb_descriptor_header *) &rndis_union_desc, - (struct usb_descriptor_header *) &fs_notify_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) &rndis_data_intf, - (struct usb_descriptor_header *) &fs_in_desc, - (struct usb_descriptor_header *) &fs_out_desc, - NULL, -}; - -/* high speed support: */ - -static struct usb_endpoint_descriptor hs_notify_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, -}; - -static struct usb_endpoint_descriptor hs_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor hs_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_descriptor_header *eth_hs_function[] = { - (struct usb_descriptor_header *) &rndis_iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) &rndis_control_intf, - (struct usb_descriptor_header *) &header_desc, - (struct usb_descriptor_header *) &call_mgmt_descriptor, - (struct usb_descriptor_header *) &rndis_acm_descriptor, - (struct usb_descriptor_header *) &rndis_union_desc, - (struct usb_descriptor_header *) &hs_notify_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) &rndis_data_intf, - (struct usb_descriptor_header *) &hs_in_desc, - (struct usb_descriptor_header *) &hs_out_desc, - NULL, -}; - -/* super speed support: */ - -static struct usb_endpoint_descriptor ss_notify_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, -}; - -static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = { - .bLength = sizeof ss_intr_comp_desc, - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /* the following 3 values can be tweaked if necessary */ - /* .bMaxBurst = 0, */ - /* .bmAttributes = 0, */ - .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT), -}; - -static struct usb_endpoint_descriptor ss_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_endpoint_descriptor ss_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = { - .bLength = sizeof ss_bulk_comp_desc, - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /* the following 2 values can be tweaked if necessary */ - /* .bMaxBurst = 0, */ - /* .bmAttributes = 0, */ -}; - -static struct usb_descriptor_header *eth_ss_function[] = { - (struct usb_descriptor_header *) &rndis_iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) &rndis_control_intf, - (struct usb_descriptor_header *) &header_desc, - (struct usb_descriptor_header *) &call_mgmt_descriptor, - (struct usb_descriptor_header *) &rndis_acm_descriptor, - (struct usb_descriptor_header *) &rndis_union_desc, - (struct usb_descriptor_header *) &ss_notify_desc, - (struct usb_descriptor_header *) &ss_intr_comp_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) &rndis_data_intf, - (struct usb_descriptor_header *) &ss_in_desc, - (struct usb_descriptor_header *) &ss_bulk_comp_desc, - (struct usb_descriptor_header *) &ss_out_desc, - (struct usb_descriptor_header *) &ss_bulk_comp_desc, - NULL, -}; - -/* string descriptors: */ - -static struct usb_string rndis_string_defs[] = { - [0].s = "RNDIS Communications Control", - [1].s = "RNDIS Ethernet Data", - [2].s = "RNDIS", - { } /* end of list */ -}; - -static struct usb_gadget_strings rndis_string_table = { - .language = 0x0409, /* en-us */ - .strings = rndis_string_defs, -}; - -static struct usb_gadget_strings *rndis_strings[] = { - &rndis_string_table, - NULL, -}; - -/*-------------------------------------------------------------------------*/ - -static struct sk_buff *rndis_add_header(struct gether *port, - struct sk_buff *skb) -{ - struct sk_buff *skb2; - - skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); - if (skb2) - rndis_add_hdr(skb2); - - dev_kfree_skb_any(skb); - return skb2; -} - -static void rndis_response_available(void *_rndis) -{ - struct f_rndis *rndis = _rndis; - struct usb_request *req = rndis->notify_req; - struct usb_composite_dev *cdev = rndis->port.func.config->cdev; - __le32 *data = req->buf; - int status; - - if (atomic_inc_return(&rndis->notify_count) != 1) - return; - - /* Send RNDIS RESPONSE_AVAILABLE notification; a - * USB_CDC_NOTIFY_RESPONSE_AVAILABLE "should" work too - * - * This is the only notification defined by RNDIS. - */ - data[0] = cpu_to_le32(1); - data[1] = cpu_to_le32(0); - - status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC); - if (status) { - atomic_dec(&rndis->notify_count); - DBG(cdev, "notify/0 --> %d\n", status); - } -} - -static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_rndis *rndis = req->context; - struct usb_composite_dev *cdev = rndis->port.func.config->cdev; - int status = req->status; - - /* after TX: - * - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control) - * - RNDIS_RESPONSE_AVAILABLE (status/irq) - */ - switch (status) { - case -ECONNRESET: - case -ESHUTDOWN: - /* connection gone */ - atomic_set(&rndis->notify_count, 0); - break; - default: - DBG(cdev, "RNDIS %s response error %d, %d/%d\n", - ep->name, status, - req->actual, req->length); - /* FALLTHROUGH */ - case 0: - if (ep != rndis->notify) - break; - - /* handle multiple pending RNDIS_RESPONSE_AVAILABLE - * notifications by resending until we're done - */ - if (atomic_dec_and_test(&rndis->notify_count)) - break; - status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC); - if (status) { - atomic_dec(&rndis->notify_count); - DBG(cdev, "notify/1 --> %d\n", status); - } - break; - } -} - -static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_rndis *rndis = req->context; - struct usb_composite_dev *cdev = rndis->port.func.config->cdev; - int status; - - /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ -// spin_lock(&dev->lock); - status = rndis_msg_parser(rndis->config, (u8 *) req->buf); - if (status < 0) - ERROR(cdev, "RNDIS command error %d, %d/%d\n", - status, req->actual, req->length); -// spin_unlock(&dev->lock); -} - -static int -rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -{ - struct f_rndis *rndis = func_to_rndis(f); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - /* composite driver infrastructure handles everything except - * CDC class messages; interface activation uses set_alt(). - */ - switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { - - /* RNDIS uses the CDC command encapsulation mechanism to implement - * an RPC scheme, with much getting/setting of attributes by OID. - */ - case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) - | USB_CDC_SEND_ENCAPSULATED_COMMAND: - if (w_value || w_index != rndis->ctrl_id) - goto invalid; - /* read the request; process it later */ - value = w_length; - req->complete = rndis_command_complete; - req->context = rndis; - /* later, rndis_response_available() sends a notification */ - break; - - case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) - | USB_CDC_GET_ENCAPSULATED_RESPONSE: - if (w_value || w_index != rndis->ctrl_id) - goto invalid; - else { - u8 *buf; - u32 n; - - /* return the result */ - buf = rndis_get_next_response(rndis->config, &n); - if (buf) { - memcpy(req->buf, buf, n); - req->complete = rndis_response_complete; - req->context = rndis; - rndis_free_response(rndis->config, buf); - value = n; - } - /* else stalls ... spec says to avoid that */ - } - break; - - default: -invalid: - VDBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - } - - /* respond with data transfer or status phase? */ - if (value >= 0) { - DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); - req->zero = (value < w_length); - req->length = value; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) - ERROR(cdev, "rndis response on err %d\n", value); - } - - /* device either stalls (value < 0) or reports success */ - return value; -} - - -static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -{ - struct f_rndis *rndis = func_to_rndis(f); - struct usb_composite_dev *cdev = f->config->cdev; - - /* we know alt == 0 */ - - if (intf == rndis->ctrl_id) { - if (rndis->notify->driver_data) { - VDBG(cdev, "reset rndis control %d\n", intf); - usb_ep_disable(rndis->notify); - } - if (!rndis->notify->desc) { - VDBG(cdev, "init rndis ctrl %d\n", intf); - if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) - goto fail; - } - usb_ep_enable(rndis->notify); - rndis->notify->driver_data = rndis; - - } else if (intf == rndis->data_id) { - struct net_device *net; - - if (rndis->port.in_ep->driver_data) { - DBG(cdev, "reset rndis\n"); - gether_disconnect(&rndis->port); - } - - if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) { - DBG(cdev, "init rndis\n"); - if (config_ep_by_speed(cdev->gadget, f, - rndis->port.in_ep) || - config_ep_by_speed(cdev->gadget, f, - rndis->port.out_ep)) { - rndis->port.in_ep->desc = NULL; - rndis->port.out_ep->desc = NULL; - goto fail; - } - } - - /* Avoid ZLPs; they can be troublesome. */ - rndis->port.is_zlp_ok = false; - - /* RNDIS should be in the "RNDIS uninitialized" state, - * either never activated or after rndis_uninit(). - * - * We don't want data to flow here until a nonzero packet - * filter is set, at which point it enters "RNDIS data - * initialized" state ... but we do want the endpoints - * to be activated. It's a strange little state. - * - * REVISIT the RNDIS gadget code has done this wrong for a - * very long time. We need another call to the link layer - * code -- gether_updown(...bool) maybe -- to do it right. - */ - rndis->port.cdc_filter = 0; - - DBG(cdev, "RNDIS RX/TX early activation ... \n"); - net = gether_connect(&rndis->port); - if (IS_ERR(net)) - return PTR_ERR(net); - - rndis_set_param_dev(rndis->config, net, - &rndis->port.cdc_filter); - } else - goto fail; - - return 0; -fail: - return -EINVAL; -} - -static void rndis_disable(struct usb_function *f) -{ - struct f_rndis *rndis = func_to_rndis(f); - struct usb_composite_dev *cdev = f->config->cdev; - - if (!rndis->notify->driver_data) - return; - - DBG(cdev, "rndis deactivated\n"); - - rndis_uninit(rndis->config); - gether_disconnect(&rndis->port); - - usb_ep_disable(rndis->notify); - rndis->notify->driver_data = NULL; -} - -/*-------------------------------------------------------------------------*/ - -/* - * This isn't quite the same mechanism as CDC Ethernet, since the - * notification scheme passes less data, but the same set of link - * states must be tested. A key difference is that altsettings are - * not used to tell whether the link should send packets or not. - */ - -static void rndis_open(struct gether *geth) -{ - struct f_rndis *rndis = func_to_rndis(&geth->func); - struct usb_composite_dev *cdev = geth->func.config->cdev; - - DBG(cdev, "%s\n", __func__); - - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, - bitrate(cdev->gadget) / 100); - rndis_signal_connect(rndis->config); -} - -static void rndis_close(struct gether *geth) -{ - struct f_rndis *rndis = func_to_rndis(&geth->func); - - DBG(geth->func.config->cdev, "%s\n", __func__); - - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); - rndis_signal_disconnect(rndis->config); -} - -/*-------------------------------------------------------------------------*/ - -/* ethernet function driver setup/binding */ - -static int -rndis_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct usb_composite_dev *cdev = c->cdev; - struct f_rndis *rndis = func_to_rndis(f); - int status; - struct usb_ep *ep; - - /* allocate instance-specific interface IDs */ - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - rndis->ctrl_id = status; - rndis_iad_descriptor.bFirstInterface = status; - - rndis_control_intf.bInterfaceNumber = status; - rndis_union_desc.bMasterInterface0 = status; - - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - rndis->data_id = status; - - rndis_data_intf.bInterfaceNumber = status; - rndis_union_desc.bSlaveInterface0 = status; - - status = -ENODEV; - - /* allocate instance-specific endpoints */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc); - if (!ep) - goto fail; - rndis->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ - - ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); - if (!ep) - goto fail; - rndis->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ - - /* NOTE: a status/notification endpoint is, strictly speaking, - * optional. We don't treat it that way though! It's simpler, - * and some newer profiles don't treat it as optional. - */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc); - if (!ep) - goto fail; - rndis->notify = ep; - ep->driver_data = cdev; /* claim */ - - status = -ENOMEM; - - /* allocate notification request and buffer */ - rndis->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); - if (!rndis->notify_req) - goto fail; - rndis->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL); - if (!rndis->notify_req->buf) - goto fail; - rndis->notify_req->length = STATUS_BYTECOUNT; - rndis->notify_req->context = rndis; - rndis->notify_req->complete = rndis_response_complete; - - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(eth_fs_function); - if (!f->descriptors) - goto fail; - - /* support all relevant hardware speeds... we expect that when - * hardware is dual speed, all bulk-capable endpoints work at - * both speeds - */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_in_desc.bEndpointAddress = - fs_in_desc.bEndpointAddress; - hs_out_desc.bEndpointAddress = - fs_out_desc.bEndpointAddress; - hs_notify_desc.bEndpointAddress = - fs_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(eth_hs_function); - if (!f->hs_descriptors) - goto fail; - } - - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_in_desc.bEndpointAddress = - fs_in_desc.bEndpointAddress; - ss_out_desc.bEndpointAddress = - fs_out_desc.bEndpointAddress; - ss_notify_desc.bEndpointAddress = - fs_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(eth_ss_function); - if (!f->ss_descriptors) - goto fail; - } - - rndis->port.open = rndis_open; - rndis->port.close = rndis_close; - - status = rndis_register(rndis_response_available, rndis); - if (status < 0) - goto fail; - rndis->config = status; - - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); - rndis_set_host_mac(rndis->config, rndis->ethaddr); - - if (rndis->manufacturer && rndis->vendorID && - rndis_set_param_vendor(rndis->config, rndis->vendorID, - rndis->manufacturer)) - goto fail; - - /* NOTE: all that is done without knowing or caring about - * the network link ... which is unavailable to this code - * until we're activated via set_alt(). - */ - - DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n", - gadget_is_superspeed(c->cdev->gadget) ? "super" : - gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", - rndis->port.in_ep->name, rndis->port.out_ep->name, - rndis->notify->name); - return 0; - -fail: - if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors) - usb_free_descriptors(f->hs_descriptors); - if (f->descriptors) - usb_free_descriptors(f->descriptors); - - if (rndis->notify_req) { - kfree(rndis->notify_req->buf); - usb_ep_free_request(rndis->notify, rndis->notify_req); - } - - /* we might as well release our claims on endpoints */ - if (rndis->notify) - rndis->notify->driver_data = NULL; - if (rndis->port.out_ep->desc) - rndis->port.out_ep->driver_data = NULL; - if (rndis->port.in_ep->desc) - rndis->port.in_ep->driver_data = NULL; - - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); - - return status; -} - -static void -rndis_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_rndis *rndis = func_to_rndis(f); - - rndis_deregister(rndis->config); - rndis_exit(); - rndis_string_defs[0].id = 0; - - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); - - kfree(rndis->notify_req->buf); - usb_ep_free_request(rndis->notify, rndis->notify_req); - - kfree(rndis); -} - -/* Some controllers can't support RNDIS ... */ -static inline bool can_support_rndis(struct usb_configuration *c) -{ - /* everything else is *presumably* fine */ - return true; -} - -int -rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer) -{ - struct f_rndis *rndis; - int status; - - if (!can_support_rndis(c) || !ethaddr) - return -EINVAL; - - /* maybe allocate device-global string IDs */ - if (rndis_string_defs[0].id == 0) { - - /* ... and setup RNDIS itself */ - status = rndis_init(); - if (status < 0) - return status; - - /* control interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - rndis_string_defs[0].id = status; - rndis_control_intf.iInterface = status; - - /* data interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - rndis_string_defs[1].id = status; - rndis_data_intf.iInterface = status; - - /* IAD iFunction label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - rndis_string_defs[2].id = status; - rndis_iad_descriptor.iFunction = status; - } - - /* allocate and initialize one new instance */ - status = -ENOMEM; - rndis = kzalloc(sizeof *rndis, GFP_KERNEL); - if (!rndis) - goto fail; - - memcpy(rndis->ethaddr, ethaddr, ETH_ALEN); - rndis->vendorID = vendorID; - rndis->manufacturer = manufacturer; - - /* RNDIS activates when the host changes this filter */ - rndis->port.cdc_filter = 0; - - /* RNDIS has special (and complex) framing */ - rndis->port.header_len = sizeof(struct rndis_packet_msg_type); - rndis->port.wrap = rndis_add_header; - rndis->port.unwrap = rndis_rm_hdr; - - rndis->port.func.name = "rndis"; - rndis->port.func.strings = rndis_strings; - /* descriptors are per-instance copies */ - rndis->port.func.bind = rndis_bind; - rndis->port.func.unbind = rndis_unbind; - rndis->port.func.set_alt = rndis_set_alt; - rndis->port.func.setup = rndis_setup; - rndis->port.func.disable = rndis_disable; - - status = usb_add_function(c, &rndis->port.func); - if (status) { - kfree(rndis); -fail: - rndis_exit(); - } - return status; -} diff --git a/drivers/staging/ccg/gadget_chips.h b/drivers/staging/ccg/gadget_chips.h deleted file mode 100644 index 0ccca58e7a8f..000000000000 --- a/drivers/staging/ccg/gadget_chips.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * USB device controllers have lots of quirks. Use these macros in - * gadget drivers or other code that needs to deal with them, and which - * autoconfigures instead of using early binding to the hardware. - * - * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by - * some config file that gets updated as new hardware is supported. - * (And avoiding all runtime comparisons in typical one-choice configs!) - * - * NOTE: some of these controller drivers may not be available yet. - * Some are available on 2.4 kernels; several are available, but not - * yet pushed in the 2.6 mainline tree. - */ - -#ifndef __GADGET_CHIPS_H -#define __GADGET_CHIPS_H - -/* - * NOTICE: the entries below are alphabetical and should be kept - * that way. - * - * Always be sure to add new entries to the correct position or - * accept the bashing later. - * - * If you have forgotten the alphabetical order let VIM/EMACS - * do that for you. - */ -#define gadget_is_amd5536udc(g) (!strcmp("amd5536udc", (g)->name)) -#define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name)) -#define gadget_is_atmel_usba(g) (!strcmp("atmel_usba_udc", (g)->name)) -#define gadget_is_bcm63xx(g) (!strcmp("bcm63xx_udc", (g)->name)) -#define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) -#define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) -#define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name)) -#define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name)) -#define gadget_is_fsl_qe(g) (!strcmp("fsl_qe_udc", (g)->name)) -#define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name)) -#define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name)) -#define gadget_is_imx(g) (!strcmp("imx_udc", (g)->name)) -#define gadget_is_langwell(g) (!strcmp("langwell_udc", (g)->name)) -#define gadget_is_lpc32xx(g) (!strcmp("lpc32xx_udc", (g)->name)) -#define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name)) -#define gadget_is_musbhdrc(g) (!strcmp("musb-hdrc", (g)->name)) -#define gadget_is_net2272(g) (!strcmp("net2272", (g)->name)) -#define gadget_is_net2280(g) (!strcmp("net2280", (g)->name)) -#define gadget_is_omap(g) (!strcmp("omap_udc", (g)->name)) -#define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name)) -#define gadget_is_pxa(g) (!strcmp("pxa25x_udc", (g)->name)) -#define gadget_is_pxa27x(g) (!strcmp("pxa27x_udc", (g)->name)) -#define gadget_is_r8a66597(g) (!strcmp("r8a66597_udc", (g)->name)) -#define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name)) -#define gadget_is_s3c2410(g) (!strcmp("s3c2410_udc", (g)->name)) -#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) -#define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name)) - -/** - * usb_gadget_controller_number - support bcdDevice id convention - * @gadget: the controller being driven - * - * Return a 2-digit BCD value associated with the peripheral controller, - * suitable for use as part of a bcdDevice value, or a negative error code. - * - * NOTE: this convention is purely optional, and has no meaning in terms of - * any USB specification. If you want to use a different convention in your - * gadget driver firmware -- maybe a more formal revision ID -- feel free. - * - * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!) - * to change their behavior accordingly. For example it might help avoiding - * some chip bug. - */ -static inline int usb_gadget_controller_number(struct usb_gadget *gadget) -{ - if (gadget_is_net2280(gadget)) - return 0x01; - else if (gadget_is_dummy(gadget)) - return 0x02; - else if (gadget_is_pxa(gadget)) - return 0x03; - else if (gadget_is_goku(gadget)) - return 0x06; - else if (gadget_is_omap(gadget)) - return 0x08; - else if (gadget_is_pxa27x(gadget)) - return 0x11; - else if (gadget_is_s3c2410(gadget)) - return 0x12; - else if (gadget_is_at91(gadget)) - return 0x13; - else if (gadget_is_imx(gadget)) - return 0x14; - else if (gadget_is_musbhdrc(gadget)) - return 0x16; - else if (gadget_is_atmel_usba(gadget)) - return 0x18; - else if (gadget_is_fsl_usb2(gadget)) - return 0x19; - else if (gadget_is_amd5536udc(gadget)) - return 0x20; - else if (gadget_is_m66592(gadget)) - return 0x21; - else if (gadget_is_fsl_qe(gadget)) - return 0x22; - else if (gadget_is_ci13xxx_pci(gadget)) - return 0x23; - else if (gadget_is_langwell(gadget)) - return 0x24; - else if (gadget_is_r8a66597(gadget)) - return 0x25; - else if (gadget_is_s3c_hsotg(gadget)) - return 0x26; - else if (gadget_is_pch(gadget)) - return 0x27; - else if (gadget_is_ci13xxx_msm(gadget)) - return 0x28; - else if (gadget_is_renesas_usbhs(gadget)) - return 0x29; - else if (gadget_is_s3c_hsudc(gadget)) - return 0x30; - else if (gadget_is_net2272(gadget)) - return 0x31; - else if (gadget_is_dwc3(gadget)) - return 0x32; - else if (gadget_is_lpc32xx(gadget)) - return 0x33; - else if (gadget_is_bcm63xx(gadget)) - return 0x34; - - return -ENOENT; -} - - -/** - * gadget_supports_altsettings - return true if altsettings work - * @gadget: the gadget in question - */ -static inline bool gadget_supports_altsettings(struct usb_gadget *gadget) -{ - /* PXA 21x/25x/26x has no altsettings at all */ - if (gadget_is_pxa(gadget)) - return false; - - /* PXA 27x and 3xx have *broken* altsetting support */ - if (gadget_is_pxa27x(gadget)) - return false; - - /* Everything else is *presumably* fine ... */ - return true; -} - -#endif /* __GADGET_CHIPS_H */ diff --git a/drivers/staging/ccg/ndis.h b/drivers/staging/ccg/ndis.h deleted file mode 100644 index a19f72dec0cd..000000000000 --- a/drivers/staging/ccg/ndis.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ndis.h - * - * ntddndis.h modified by Benedikt Spranger - * - * Thanks to the cygwin development team, - * espacially to Casper S. Hornstrup - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - */ - -#ifndef _LINUX_NDIS_H -#define _LINUX_NDIS_H - -enum NDIS_DEVICE_POWER_STATE { - NdisDeviceStateUnspecified = 0, - NdisDeviceStateD0, - NdisDeviceStateD1, - NdisDeviceStateD2, - NdisDeviceStateD3, - NdisDeviceStateMaximum -}; - -struct NDIS_PM_WAKE_UP_CAPABILITIES { - enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; - enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; - enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; -}; - -struct NDIS_PNP_CAPABILITIES { - __le32 Flags; - struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; -}; - -struct NDIS_PM_PACKET_PATTERN { - __le32 Priority; - __le32 Reserved; - __le32 MaskSize; - __le32 PatternOffset; - __le32 PatternSize; - __le32 PatternFlags; -}; - -#endif /* _LINUX_NDIS_H */ diff --git a/drivers/staging/ccg/rndis.c b/drivers/staging/ccg/rndis.c deleted file mode 100644 index d9297eebbf73..000000000000 --- a/drivers/staging/ccg/rndis.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * RNDIS MSG parser - * - * Authors: Benedikt Spranger, Pengutronix - * Robert Schwebel, Pengutronix - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * - * This software was originally developed in conformance with - * Microsoft's Remote NDIS Specification License Agreement. - * - * 03/12/2004 Kai-Uwe Bloem - * Fixed message length bug in init_response - * - * 03/25/2004 Kai-Uwe Bloem - * Fixed rndis_rm_hdr length bug. - * - * Copyright (C) 2004 by David Brownell - * updates to merge with Linux 2.6, better match RNDIS spec - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#undef VERBOSE_DEBUG - -#include "rndis.h" - - -/* The driver for your USB chip needs to support ep0 OUT to work with - * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional). - * - * Windows hosts need an INF file like Documentation/usb/linux.inf - * and will be happier if you provide the host_addr module parameter. - */ - -#if 0 -static int rndis_debug = 0; -module_param (rndis_debug, int, 0); -MODULE_PARM_DESC (rndis_debug, "enable debugging"); -#else -#define rndis_debug 0 -#endif - -#define RNDIS_MAX_CONFIGS 1 - - -static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; - -/* Driver Version */ -static const __le32 rndis_driver_version = cpu_to_le32(1); - -/* Function Prototypes */ -static rndis_resp_t *rndis_add_response(int configNr, u32 length); - - -/* supported OIDs */ -static const u32 oid_supported_list[] = -{ - /* the general stuff */ - RNDIS_OID_GEN_SUPPORTED_LIST, - RNDIS_OID_GEN_HARDWARE_STATUS, - RNDIS_OID_GEN_MEDIA_SUPPORTED, - RNDIS_OID_GEN_MEDIA_IN_USE, - RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, - RNDIS_OID_GEN_LINK_SPEED, - RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, - RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE, - RNDIS_OID_GEN_VENDOR_ID, - RNDIS_OID_GEN_VENDOR_DESCRIPTION, - RNDIS_OID_GEN_VENDOR_DRIVER_VERSION, - RNDIS_OID_GEN_CURRENT_PACKET_FILTER, - RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, - RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, - RNDIS_OID_GEN_PHYSICAL_MEDIUM, - - /* the statistical stuff */ - RNDIS_OID_GEN_XMIT_OK, - RNDIS_OID_GEN_RCV_OK, - RNDIS_OID_GEN_XMIT_ERROR, - RNDIS_OID_GEN_RCV_ERROR, - RNDIS_OID_GEN_RCV_NO_BUFFER, -#ifdef RNDIS_OPTIONAL_STATS - RNDIS_OID_GEN_DIRECTED_BYTES_XMIT, - RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT, - RNDIS_OID_GEN_MULTICAST_BYTES_XMIT, - RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT, - RNDIS_OID_GEN_BROADCAST_BYTES_XMIT, - RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT, - RNDIS_OID_GEN_DIRECTED_BYTES_RCV, - RNDIS_OID_GEN_DIRECTED_FRAMES_RCV, - RNDIS_OID_GEN_MULTICAST_BYTES_RCV, - RNDIS_OID_GEN_MULTICAST_FRAMES_RCV, - RNDIS_OID_GEN_BROADCAST_BYTES_RCV, - RNDIS_OID_GEN_BROADCAST_FRAMES_RCV, - RNDIS_OID_GEN_RCV_CRC_ERROR, - RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH, -#endif /* RNDIS_OPTIONAL_STATS */ - - /* mandatory 802.3 */ - /* the general stuff */ - RNDIS_OID_802_3_PERMANENT_ADDRESS, - RNDIS_OID_802_3_CURRENT_ADDRESS, - RNDIS_OID_802_3_MULTICAST_LIST, - RNDIS_OID_802_3_MAC_OPTIONS, - RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, - - /* the statistical stuff */ - RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT, - RNDIS_OID_802_3_XMIT_ONE_COLLISION, - RNDIS_OID_802_3_XMIT_MORE_COLLISIONS, -#ifdef RNDIS_OPTIONAL_STATS - RNDIS_OID_802_3_XMIT_DEFERRED, - RNDIS_OID_802_3_XMIT_MAX_COLLISIONS, - RNDIS_OID_802_3_RCV_OVERRUN, - RNDIS_OID_802_3_XMIT_UNDERRUN, - RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE, - RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST, - RNDIS_OID_802_3_XMIT_LATE_COLLISIONS, -#endif /* RNDIS_OPTIONAL_STATS */ - -#ifdef RNDIS_PM - /* PM and wakeup are "mandatory" for USB, but the RNDIS specs - * don't say what they mean ... and the NDIS specs are often - * confusing and/or ambiguous in this context. (That is, more - * so than their specs for the other OIDs.) - * - * FIXME someone who knows what these should do, please - * implement them! - */ - - /* power management */ - OID_PNP_CAPABILITIES, - OID_PNP_QUERY_POWER, - OID_PNP_SET_POWER, - -#ifdef RNDIS_WAKEUP - /* wake up host */ - OID_PNP_ENABLE_WAKE_UP, - OID_PNP_ADD_WAKE_UP_PATTERN, - OID_PNP_REMOVE_WAKE_UP_PATTERN, -#endif /* RNDIS_WAKEUP */ -#endif /* RNDIS_PM */ -}; - - -/* NDIS Functions */ -static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, - unsigned buf_len, rndis_resp_t *r) -{ - int retval = -ENOTSUPP; - u32 length = 4; /* usually */ - __le32 *outbuf; - int i, count; - rndis_query_cmplt_type *resp; - struct net_device *net; - struct rtnl_link_stats64 temp; - const struct rtnl_link_stats64 *stats; - - if (!r) return -ENOMEM; - resp = (rndis_query_cmplt_type *)r->buf; - - if (!resp) return -ENOMEM; - - if (buf_len && rndis_debug > 1) { - pr_debug("query OID %08x value, len %d:\n", OID, buf_len); - for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, - get_unaligned_le32(&buf[i]), - get_unaligned_le32(&buf[i + 4]), - get_unaligned_le32(&buf[i + 8]), - get_unaligned_le32(&buf[i + 12])); - } - } - - /* response goes here, right after the header */ - outbuf = (__le32 *)&resp[1]; - resp->InformationBufferOffset = cpu_to_le32(16); - - net = rndis_per_dev_params[configNr].dev; - stats = dev_get_stats(net, &temp); - - switch (OID) { - - /* general oids (table 4-1) */ - - /* mandatory */ - case RNDIS_OID_GEN_SUPPORTED_LIST: - pr_debug("%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__); - length = sizeof(oid_supported_list); - count = length / sizeof(u32); - for (i = 0; i < count; i++) - outbuf[i] = cpu_to_le32(oid_supported_list[i]); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_HARDWARE_STATUS: - pr_debug("%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__); - /* Bogus question! - * Hardware must be ready to receive high level protocols. - * BTW: - * reddite ergo quae sunt Caesaris Caesari - * et quae sunt Dei Deo! - */ - *outbuf = cpu_to_le32(0); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_MEDIA_SUPPORTED: - pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); - *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_MEDIA_IN_USE: - pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); - /* one medium, one transport... (maybe you do it better) */ - *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: - pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); - if (rndis_per_dev_params[configNr].dev) { - *outbuf = cpu_to_le32( - rndis_per_dev_params[configNr].dev->mtu); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_LINK_SPEED: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); - if (rndis_per_dev_params[configNr].media_state - == RNDIS_MEDIA_STATE_DISCONNECTED) - *outbuf = cpu_to_le32(0); - else - *outbuf = cpu_to_le32( - rndis_per_dev_params[configNr].speed); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: - pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); - if (rndis_per_dev_params[configNr].dev) { - *outbuf = cpu_to_le32( - rndis_per_dev_params[configNr].dev->mtu); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: - pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); - if (rndis_per_dev_params[configNr].dev) { - *outbuf = cpu_to_le32( - rndis_per_dev_params[configNr].dev->mtu); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_VENDOR_ID: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); - *outbuf = cpu_to_le32( - rndis_per_dev_params[configNr].vendorID); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_VENDOR_DESCRIPTION: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); - if (rndis_per_dev_params[configNr].vendorDescr) { - length = strlen(rndis_per_dev_params[configNr]. - vendorDescr); - memcpy(outbuf, - rndis_per_dev_params[configNr].vendorDescr, - length); - } else { - outbuf[0] = 0; - } - retval = 0; - break; - - case RNDIS_OID_GEN_VENDOR_DRIVER_VERSION: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); - /* Created as LE */ - *outbuf = rndis_driver_version; - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: - pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); - *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE: - pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); - *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); - *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] - .media_state); - retval = 0; - break; - - case RNDIS_OID_GEN_PHYSICAL_MEDIUM: - pr_debug("%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__); - *outbuf = cpu_to_le32(0); - retval = 0; - break; - - /* The RNDIS specification is incomplete/wrong. Some versions - * of MS-Windows expect OIDs that aren't specified there. Other - * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! - */ - case RNDIS_OID_GEN_MAC_OPTIONS: /* from WinME */ - pr_debug("%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__); - *outbuf = cpu_to_le32( - RNDIS_MAC_OPTION_RECEIVE_SERIALIZED - | RNDIS_MAC_OPTION_FULL_DUPLEX); - retval = 0; - break; - - /* statistics OIDs (table 4-2) */ - - /* mandatory */ - case RNDIS_OID_GEN_XMIT_OK: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_XMIT_OK\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->tx_packets - - stats->tx_errors - stats->tx_dropped); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_RCV_OK: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_RCV_OK\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_packets - - stats->rx_errors - stats->rx_dropped); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_XMIT_ERROR: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->tx_errors); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_RCV_ERROR: - if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_errors); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_GEN_RCV_NO_BUFFER: - pr_debug("%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_dropped); - retval = 0; - } - break; - - /* ieee802.3 OIDs (table 4-3) */ - - /* mandatory */ - case RNDIS_OID_802_3_PERMANENT_ADDRESS: - pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); - if (rndis_per_dev_params[configNr].dev) { - length = ETH_ALEN; - memcpy(outbuf, - rndis_per_dev_params[configNr].host_mac, - length); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_802_3_CURRENT_ADDRESS: - pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); - if (rndis_per_dev_params[configNr].dev) { - length = ETH_ALEN; - memcpy(outbuf, - rndis_per_dev_params [configNr].host_mac, - length); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_802_3_MULTICAST_LIST: - pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); - /* Multicast base address only */ - *outbuf = cpu_to_le32(0xE0000000); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_802_3_MAXIMUM_LIST_SIZE: - pr_debug("%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); - /* Multicast base address only */ - *outbuf = cpu_to_le32(1); - retval = 0; - break; - - case RNDIS_OID_802_3_MAC_OPTIONS: - pr_debug("%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__); - *outbuf = cpu_to_le32(0); - retval = 0; - break; - - /* ieee802.3 statistics OIDs (table 4-4) */ - - /* mandatory */ - case RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT: - pr_debug("%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); - if (stats) { - *outbuf = cpu_to_le32(stats->rx_frame_errors); - retval = 0; - } - break; - - /* mandatory */ - case RNDIS_OID_802_3_XMIT_ONE_COLLISION: - pr_debug("%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__); - *outbuf = cpu_to_le32(0); - retval = 0; - break; - - /* mandatory */ - case RNDIS_OID_802_3_XMIT_MORE_COLLISIONS: - pr_debug("%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); - *outbuf = cpu_to_le32(0); - retval = 0; - break; - - default: - pr_warning("%s: query unknown OID 0x%08X\n", - __func__, OID); - } - if (retval < 0) - length = 0; - - resp->InformationBufferLength = cpu_to_le32(length); - r->length = length + sizeof(*resp); - resp->MessageLength = cpu_to_le32(r->length); - return retval; -} - -static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, - rndis_resp_t *r) -{ - rndis_set_cmplt_type *resp; - int i, retval = -ENOTSUPP; - struct rndis_params *params; - - if (!r) - return -ENOMEM; - resp = (rndis_set_cmplt_type *)r->buf; - if (!resp) - return -ENOMEM; - - if (buf_len && rndis_debug > 1) { - pr_debug("set OID %08x value, len %d:\n", OID, buf_len); - for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, - get_unaligned_le32(&buf[i]), - get_unaligned_le32(&buf[i + 4]), - get_unaligned_le32(&buf[i + 8]), - get_unaligned_le32(&buf[i + 12])); - } - } - - params = &rndis_per_dev_params[configNr]; - switch (OID) { - case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: - - /* these NDIS_PACKET_TYPE_* bitflags are shared with - * cdc_filter; it's not RNDIS-specific - * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in: - * PROMISCUOUS, DIRECTED, - * MULTICAST, ALL_MULTICAST, BROADCAST - */ - *params->filter = (u16)get_unaligned_le32(buf); - pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n", - __func__, *params->filter); - - /* this call has a significant side effect: it's - * what makes the packet flow start and stop, like - * activating the CDC Ethernet altsetting. - */ - retval = 0; - if (*params->filter) { - params->state = RNDIS_DATA_INITIALIZED; - netif_carrier_on(params->dev); - if (netif_running(params->dev)) - netif_wake_queue(params->dev); - } else { - params->state = RNDIS_INITIALIZED; - netif_carrier_off(params->dev); - netif_stop_queue(params->dev); - } - break; - - case RNDIS_OID_802_3_MULTICAST_LIST: - /* I think we can ignore this */ - pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); - retval = 0; - break; - - default: - pr_warning("%s: set unknown OID 0x%08X, size %d\n", - __func__, OID, buf_len); - } - - return retval; -} - -/* - * Response Functions - */ - -static int rndis_init_response(int configNr, rndis_init_msg_type *buf) -{ - rndis_init_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - if (!params->dev) - return -ENOTSUPP; - - r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type)); - if (!r) - return -ENOMEM; - resp = (rndis_init_cmplt_type *)r->buf; - - resp->MessageType = cpu_to_le32(RNDIS_MSG_INIT_C); - resp->MessageLength = cpu_to_le32(52); - resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); - resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); - resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); - resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); - resp->MaxPacketsPerTransfer = cpu_to_le32(1); - resp->MaxTransferSize = cpu_to_le32( - params->dev->mtu - + sizeof(struct ethhdr) - + sizeof(struct rndis_packet_msg_type) - + 22); - resp->PacketAlignmentFactor = cpu_to_le32(0); - resp->AFListOffset = cpu_to_le32(0); - resp->AFListSize = cpu_to_le32(0); - - params->resp_avail(params->v); - return 0; -} - -static int rndis_query_response(int configNr, rndis_query_msg_type *buf) -{ - rndis_query_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ - if (!params->dev) - return -ENOTSUPP; - - /* - * we need more memory: - * gen_ndis_query_resp expects enough space for - * rndis_query_cmplt_type followed by data. - * oid_supported_list is the largest data reply - */ - r = rndis_add_response(configNr, - sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type)); - if (!r) - return -ENOMEM; - resp = (rndis_query_cmplt_type *)r->buf; - - resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); - resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - - if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), - le32_to_cpu(buf->InformationBufferOffset) - + 8 + (u8 *)buf, - le32_to_cpu(buf->InformationBufferLength), - r)) { - /* OID not supported */ - resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); - resp->MessageLength = cpu_to_le32(sizeof *resp); - resp->InformationBufferLength = cpu_to_le32(0); - resp->InformationBufferOffset = cpu_to_le32(0); - } else - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - - params->resp_avail(params->v); - return 0; -} - -static int rndis_set_response(int configNr, rndis_set_msg_type *buf) -{ - u32 BufLength, BufOffset; - rndis_set_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type)); - if (!r) - return -ENOMEM; - resp = (rndis_set_cmplt_type *)r->buf; - - BufLength = le32_to_cpu(buf->InformationBufferLength); - BufOffset = le32_to_cpu(buf->InformationBufferOffset); - -#ifdef VERBOSE_DEBUG - pr_debug("%s: Length: %d\n", __func__, BufLength); - pr_debug("%s: Offset: %d\n", __func__, BufOffset); - pr_debug("%s: InfoBuffer: ", __func__); - - for (i = 0; i < BufLength; i++) { - pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); - } - - pr_debug("\n"); -#endif - - resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); - resp->MessageLength = cpu_to_le32(16); - resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), - ((u8 *)buf) + 8 + BufOffset, BufLength, r)) - resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); - else - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - - params->resp_avail(params->v); - return 0; -} - -static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) -{ - rndis_reset_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type)); - if (!r) - return -ENOMEM; - resp = (rndis_reset_cmplt_type *)r->buf; - - resp->MessageType = cpu_to_le32(RNDIS_MSG_RESET_C); - resp->MessageLength = cpu_to_le32(16); - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - /* resent information */ - resp->AddressingReset = cpu_to_le32(1); - - params->resp_avail(params->v); - return 0; -} - -static int rndis_keepalive_response(int configNr, - rndis_keepalive_msg_type *buf) -{ - rndis_keepalive_cmplt_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - /* host "should" check only in RNDIS_DATA_INITIALIZED state */ - - r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type)); - if (!r) - return -ENOMEM; - resp = (rndis_keepalive_cmplt_type *)r->buf; - - resp->MessageType = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); - resp->MessageLength = cpu_to_le32(16); - resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); - - params->resp_avail(params->v); - return 0; -} - - -/* - * Device to Host Comunication - */ -static int rndis_indicate_status_msg(int configNr, u32 status) -{ - rndis_indicate_status_msg_type *resp; - rndis_resp_t *r; - struct rndis_params *params = rndis_per_dev_params + configNr; - - if (params->state == RNDIS_UNINITIALIZED) - return -ENOTSUPP; - - r = rndis_add_response(configNr, - sizeof(rndis_indicate_status_msg_type)); - if (!r) - return -ENOMEM; - resp = (rndis_indicate_status_msg_type *)r->buf; - - resp->MessageType = cpu_to_le32(RNDIS_MSG_INDICATE); - resp->MessageLength = cpu_to_le32(20); - resp->Status = cpu_to_le32(status); - resp->StatusBufferLength = cpu_to_le32(0); - resp->StatusBufferOffset = cpu_to_le32(0); - - params->resp_avail(params->v); - return 0; -} - -int rndis_signal_connect(int configNr) -{ - rndis_per_dev_params[configNr].media_state - = RNDIS_MEDIA_STATE_CONNECTED; - return rndis_indicate_status_msg(configNr, - RNDIS_STATUS_MEDIA_CONNECT); -} - -int rndis_signal_disconnect(int configNr) -{ - rndis_per_dev_params[configNr].media_state - = RNDIS_MEDIA_STATE_DISCONNECTED; - return rndis_indicate_status_msg(configNr, - RNDIS_STATUS_MEDIA_DISCONNECT); -} - -void rndis_uninit(int configNr) -{ - u8 *buf; - u32 length; - - if (configNr >= RNDIS_MAX_CONFIGS) - return; - rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED; - - /* drain the response queue */ - while ((buf = rndis_get_next_response(configNr, &length))) - rndis_free_response(configNr, buf); -} - -void rndis_set_host_mac(int configNr, const u8 *addr) -{ - rndis_per_dev_params[configNr].host_mac = addr; -} - -/* - * Message Parser - */ -int rndis_msg_parser(u8 configNr, u8 *buf) -{ - u32 MsgType, MsgLength; - __le32 *tmp; - struct rndis_params *params; - - if (!buf) - return -ENOMEM; - - tmp = (__le32 *)buf; - MsgType = get_unaligned_le32(tmp++); - MsgLength = get_unaligned_le32(tmp++); - - if (configNr >= RNDIS_MAX_CONFIGS) - return -ENOTSUPP; - params = &rndis_per_dev_params[configNr]; - - /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for - * rx/tx statistics and link status, in addition to KEEPALIVE traffic - * and normal HC level polling to see if there's any IN traffic. - */ - - /* For USB: responses may take up to 10 seconds */ - switch (MsgType) { - case RNDIS_MSG_INIT: - pr_debug("%s: RNDIS_MSG_INIT\n", - __func__); - params->state = RNDIS_INITIALIZED; - return rndis_init_response(configNr, - (rndis_init_msg_type *)buf); - - case RNDIS_MSG_HALT: - pr_debug("%s: RNDIS_MSG_HALT\n", - __func__); - params->state = RNDIS_UNINITIALIZED; - if (params->dev) { - netif_carrier_off(params->dev); - netif_stop_queue(params->dev); - } - return 0; - - case RNDIS_MSG_QUERY: - return rndis_query_response(configNr, - (rndis_query_msg_type *)buf); - - case RNDIS_MSG_SET: - return rndis_set_response(configNr, - (rndis_set_msg_type *)buf); - - case RNDIS_MSG_RESET: - pr_debug("%s: RNDIS_MSG_RESET\n", - __func__); - return rndis_reset_response(configNr, - (rndis_reset_msg_type *)buf); - - case RNDIS_MSG_KEEPALIVE: - /* For USB: host does this every 5 seconds */ - if (rndis_debug > 1) - pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", - __func__); - return rndis_keepalive_response(configNr, - (rndis_keepalive_msg_type *) - buf); - - default: - /* At least Windows XP emits some undefined RNDIS messages. - * In one case those messages seemed to relate to the host - * suspending itself. - */ - pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", - __func__, MsgType, MsgLength); - print_hex_dump_bytes(__func__, DUMP_PREFIX_OFFSET, - buf, MsgLength); - break; - } - - return -ENOTSUPP; -} - -int rndis_register(void (*resp_avail)(void *v), void *v) -{ - u8 i; - - if (!resp_avail) - return -EINVAL; - - for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { - if (!rndis_per_dev_params[i].used) { - rndis_per_dev_params[i].used = 1; - rndis_per_dev_params[i].resp_avail = resp_avail; - rndis_per_dev_params[i].v = v; - pr_debug("%s: configNr = %d\n", __func__, i); - return i; - } - } - pr_debug("failed\n"); - - return -ENODEV; -} - -void rndis_deregister(int configNr) -{ - pr_debug("%s:\n", __func__); - - if (configNr >= RNDIS_MAX_CONFIGS) return; - rndis_per_dev_params[configNr].used = 0; -} - -int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) -{ - pr_debug("%s:\n", __func__); - if (!dev) - return -EINVAL; - if (configNr >= RNDIS_MAX_CONFIGS) return -1; - - rndis_per_dev_params[configNr].dev = dev; - rndis_per_dev_params[configNr].filter = cdc_filter; - - return 0; -} - -int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) -{ - pr_debug("%s:\n", __func__); - if (!vendorDescr) return -1; - if (configNr >= RNDIS_MAX_CONFIGS) return -1; - - rndis_per_dev_params[configNr].vendorID = vendorID; - rndis_per_dev_params[configNr].vendorDescr = vendorDescr; - - return 0; -} - -int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) -{ - pr_debug("%s: %u %u\n", __func__, medium, speed); - if (configNr >= RNDIS_MAX_CONFIGS) return -1; - - rndis_per_dev_params[configNr].medium = medium; - rndis_per_dev_params[configNr].speed = speed; - - return 0; -} - -void rndis_add_hdr(struct sk_buff *skb) -{ - struct rndis_packet_msg_type *header; - - if (!skb) - return; - header = (void *)skb_push(skb, sizeof(*header)); - memset(header, 0, sizeof *header); - header->MessageType = cpu_to_le32(RNDIS_MSG_PACKET); - header->MessageLength = cpu_to_le32(skb->len); - header->DataOffset = cpu_to_le32(36); - header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); -} - -void rndis_free_response(int configNr, u8 *buf) -{ - rndis_resp_t *r; - struct list_head *act, *tmp; - - list_for_each_safe(act, tmp, - &(rndis_per_dev_params[configNr].resp_queue)) - { - r = list_entry(act, rndis_resp_t, list); - if (r && r->buf == buf) { - list_del(&r->list); - kfree(r); - } - } -} - -u8 *rndis_get_next_response(int configNr, u32 *length) -{ - rndis_resp_t *r; - struct list_head *act, *tmp; - - if (!length) return NULL; - - list_for_each_safe(act, tmp, - &(rndis_per_dev_params[configNr].resp_queue)) - { - r = list_entry(act, rndis_resp_t, list); - if (!r->send) { - r->send = 1; - *length = r->length; - return r->buf; - } - } - - return NULL; -} - -static rndis_resp_t *rndis_add_response(int configNr, u32 length) -{ - rndis_resp_t *r; - - /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ - r = kmalloc(sizeof(rndis_resp_t) + length, GFP_ATOMIC); - if (!r) return NULL; - - r->buf = (u8 *)(r + 1); - r->length = length; - r->send = 0; - - list_add_tail(&r->list, - &(rndis_per_dev_params[configNr].resp_queue)); - return r; -} - -int rndis_rm_hdr(struct gether *port, - struct sk_buff *skb, - struct sk_buff_head *list) -{ - /* tmp points to a struct rndis_packet_msg_type */ - __le32 *tmp = (void *)skb->data; - - /* MessageType, MessageLength */ - if (cpu_to_le32(RNDIS_MSG_PACKET) - != get_unaligned(tmp++)) { - dev_kfree_skb_any(skb); - return -EINVAL; - } - tmp++; - - /* DataOffset, DataLength */ - if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) { - dev_kfree_skb_any(skb); - return -EOVERFLOW; - } - skb_trim(skb, get_unaligned_le32(tmp++)); - - skb_queue_tail(list, skb); - return 0; -} - -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - -static int rndis_proc_show(struct seq_file *m, void *v) -{ - rndis_params *param = m->private; - - seq_printf(m, - "Config Nr. %d\n" - "used : %s\n" - "state : %s\n" - "medium : 0x%08X\n" - "speed : %d\n" - "cable : %s\n" - "vendor ID : 0x%08X\n" - "vendor : %s\n", - param->confignr, (param->used) ? "y" : "n", - ({ char *s = "?"; - switch (param->state) { - case RNDIS_UNINITIALIZED: - s = "RNDIS_UNINITIALIZED"; break; - case RNDIS_INITIALIZED: - s = "RNDIS_INITIALIZED"; break; - case RNDIS_DATA_INITIALIZED: - s = "RNDIS_DATA_INITIALIZED"; break; - }; s; }), - param->medium, - (param->media_state) ? 0 : param->speed*100, - (param->media_state) ? "disconnected" : "connected", - param->vendorID, param->vendorDescr); - return 0; -} - -static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - rndis_params *p = PDE(file_inode(file))->data; - u32 speed = 0; - int i, fl_speed = 0; - - for (i = 0; i < count; i++) { - char c; - if (get_user(c, buffer)) - return -EFAULT; - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - fl_speed = 1; - speed = speed * 10 + c - '0'; - break; - case 'C': - case 'c': - rndis_signal_connect(p->confignr); - break; - case 'D': - case 'd': - rndis_signal_disconnect(p->confignr); - break; - default: - if (fl_speed) p->speed = speed; - else pr_debug("%c is not valid\n", c); - break; - } - - buffer++; - } - - return count; -} - -static int rndis_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rndis_proc_show, PDE(inode)->data); -} - -static const struct file_operations rndis_proc_fops = { - .owner = THIS_MODULE, - .open = rndis_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = rndis_proc_write, -}; - -#define NAME_TEMPLATE "driver/rndis-%03d" - -static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; - -#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ - - -int rndis_init(void) -{ - u8 i; - - for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - char name [20]; - - sprintf(name, NAME_TEMPLATE, i); - rndis_connect_state[i] = proc_create_data(name, 0660, NULL, - &rndis_proc_fops, - (void *)(rndis_per_dev_params + i)); - if (!rndis_connect_state[i]) { - pr_debug("%s: remove entries", __func__); - while (i) { - sprintf(name, NAME_TEMPLATE, --i); - remove_proc_entry(name, NULL); - } - pr_debug("\n"); - return -EIO; - } -#endif - rndis_per_dev_params[i].confignr = i; - rndis_per_dev_params[i].used = 0; - rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; - rndis_per_dev_params[i].media_state - = RNDIS_MEDIA_STATE_DISCONNECTED; - INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); - } - - return 0; -} - -void rndis_exit(void) -{ -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - u8 i; - char name[20]; - - for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { - sprintf(name, NAME_TEMPLATE, i); - remove_proc_entry(name, NULL); - } -#endif -} diff --git a/drivers/staging/ccg/rndis.h b/drivers/staging/ccg/rndis.h deleted file mode 100644 index 0647f2f34e89..000000000000 --- a/drivers/staging/ccg/rndis.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * RNDIS Definitions for Remote NDIS - * - * Authors: Benedikt Spranger, Pengutronix - * Robert Schwebel, Pengutronix - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * - * This software was originally developed in conformance with - * Microsoft's Remote NDIS Specification License Agreement. - */ - -#ifndef _LINUX_RNDIS_H -#define _LINUX_RNDIS_H - -#include -#include "ndis.h" - -#define RNDIS_MAXIMUM_FRAME_SIZE 1518 -#define RNDIS_MAX_TOTAL_SIZE 1558 - -typedef struct rndis_init_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 MajorVersion; - __le32 MinorVersion; - __le32 MaxTransferSize; -} rndis_init_msg_type; - -typedef struct rndis_init_cmplt_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 Status; - __le32 MajorVersion; - __le32 MinorVersion; - __le32 DeviceFlags; - __le32 Medium; - __le32 MaxPacketsPerTransfer; - __le32 MaxTransferSize; - __le32 PacketAlignmentFactor; - __le32 AFListOffset; - __le32 AFListSize; -} rndis_init_cmplt_type; - -typedef struct rndis_halt_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; -} rndis_halt_msg_type; - -typedef struct rndis_query_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 OID; - __le32 InformationBufferLength; - __le32 InformationBufferOffset; - __le32 DeviceVcHandle; -} rndis_query_msg_type; - -typedef struct rndis_query_cmplt_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 Status; - __le32 InformationBufferLength; - __le32 InformationBufferOffset; -} rndis_query_cmplt_type; - -typedef struct rndis_set_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 OID; - __le32 InformationBufferLength; - __le32 InformationBufferOffset; - __le32 DeviceVcHandle; -} rndis_set_msg_type; - -typedef struct rndis_set_cmplt_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 Status; -} rndis_set_cmplt_type; - -typedef struct rndis_reset_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 Reserved; -} rndis_reset_msg_type; - -typedef struct rndis_reset_cmplt_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 Status; - __le32 AddressingReset; -} rndis_reset_cmplt_type; - -typedef struct rndis_indicate_status_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 Status; - __le32 StatusBufferLength; - __le32 StatusBufferOffset; -} rndis_indicate_status_msg_type; - -typedef struct rndis_keepalive_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; -} rndis_keepalive_msg_type; - -typedef struct rndis_keepalive_cmplt_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 RequestID; - __le32 Status; -} rndis_keepalive_cmplt_type; - -struct rndis_packet_msg_type -{ - __le32 MessageType; - __le32 MessageLength; - __le32 DataOffset; - __le32 DataLength; - __le32 OOBDataOffset; - __le32 OOBDataLength; - __le32 NumOOBDataElements; - __le32 PerPacketInfoOffset; - __le32 PerPacketInfoLength; - __le32 VcHandle; - __le32 Reserved; -} __attribute__ ((packed)); - -struct rndis_config_parameter -{ - __le32 ParameterNameOffset; - __le32 ParameterNameLength; - __le32 ParameterType; - __le32 ParameterValueOffset; - __le32 ParameterValueLength; -}; - -/* implementation specific */ -enum rndis_state -{ - RNDIS_UNINITIALIZED, - RNDIS_INITIALIZED, - RNDIS_DATA_INITIALIZED, -}; - -typedef struct rndis_resp_t -{ - struct list_head list; - u8 *buf; - u32 length; - int send; -} rndis_resp_t; - -typedef struct rndis_params -{ - u8 confignr; - u8 used; - u16 saved_filter; - enum rndis_state state; - u32 medium; - u32 speed; - u32 media_state; - - const u8 *host_mac; - u16 *filter; - struct net_device *dev; - - u32 vendorID; - const char *vendorDescr; - void (*resp_avail)(void *v); - void *v; - struct list_head resp_queue; -} rndis_params; - -/* RNDIS Message parser and other useless functions */ -int rndis_msg_parser (u8 configNr, u8 *buf); -int rndis_register(void (*resp_avail)(void *v), void *v); -void rndis_deregister (int configNr); -int rndis_set_param_dev (u8 configNr, struct net_device *dev, - u16 *cdc_filter); -int rndis_set_param_vendor (u8 configNr, u32 vendorID, - const char *vendorDescr); -int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); -void rndis_add_hdr (struct sk_buff *skb); -int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, - struct sk_buff_head *list); -u8 *rndis_get_next_response (int configNr, u32 *length); -void rndis_free_response (int configNr, u8 *buf); - -void rndis_uninit (int configNr); -int rndis_signal_connect (int configNr); -int rndis_signal_disconnect (int configNr); -int rndis_state (int configNr); -extern void rndis_set_host_mac (int configNr, const u8 *addr); - -int rndis_init(void); -void rndis_exit (void); - -#endif /* _LINUX_RNDIS_H */ diff --git a/drivers/staging/ccg/storage_common.c b/drivers/staging/ccg/storage_common.c deleted file mode 100644 index abb01ac74cec..000000000000 --- a/drivers/staging/ccg/storage_common.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * storage_common.c -- Common definitions for mass storage functionality - * - * Copyright (C) 2003-2008 Alan Stern - * Copyeight (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (mina86@mina86.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 file requires the following identifiers used in USB strings to - * be defined (each of type pointer to char): - * - fsg_string_manufacturer -- name of the manufacturer - * - fsg_string_product -- name of the product - * - fsg_string_config -- name of the configuration - * - fsg_string_interface -- name of the interface - * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS - * macro is defined prior to including this file. - */ - -/* - * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and - * fsg_hs_intr_in_desc objects as well as - * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES - * macros are not defined. - * - * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER, - * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not - * defined (as well as corresponding entries in string tables are - * missing) and FSG_STRING_INTERFACE has value of zero. - * - * When FSG_NO_OTG is defined fsg_otg_desc won't be defined. - */ - -/* - * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers - * sets the number of pipeline buffers (length of the fsg_buffhd array). - * The valid range of num_buffers is: num >= 2 && num <= 4. - */ - - -#include -#include -#include - - -/* - * Thanks to NetChip Technologies for donating this product ID. - * - * DO NOT REUSE THESE IDs with any other driver!! Ever!! - * Instead: allocate your own, using normal USB-IF procedures. - */ -#define FSG_VENDOR_ID 0x0525 /* NetChip */ -#define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ - - -/*-------------------------------------------------------------------------*/ - - -#ifndef DEBUG -#undef VERBOSE_DEBUG -#undef DUMP_MSGS -#endif /* !DEBUG */ - -#ifdef VERBOSE_DEBUG -#define VLDBG LDBG -#else -#define VLDBG(lun, fmt, args...) do { } while (0) -#endif /* VERBOSE_DEBUG */ - -#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args) -#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args) -#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) -#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) - -/* - * Keep those macros in sync with those in - * include/linux/usb/composite.h or else GCC will complain. If they - * are identical (the same names of arguments, white spaces in the - * same places) GCC will allow redefinition otherwise (even if some - * white space is removed or added) warning will be issued. - * - * Those macros are needed here because File Storage Gadget does not - * include the composite.h header. For composite gadgets those macros - * are redundant since composite.h is included any way. - * - * One could check whether those macros are already defined (which - * would indicate composite.h had been included) or not (which would - * indicate we were in FSG) but this is not done because a warning is - * desired if definitions here differ from the ones in composite.h. - * - * We want the definitions to match and be the same in File Storage - * Gadget as well as Mass Storage Function (and so composite gadgets - * using MSF). If someone changes them in composite.h it will produce - * a warning in this file when building MSF. - */ -#define DBG(d, fmt, args...) dev_dbg(&(d)->gadget->dev , fmt , ## args) -#define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev , fmt , ## args) -#define ERROR(d, fmt, args...) dev_err(&(d)->gadget->dev , fmt , ## args) -#define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args) -#define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev , fmt , ## args) - - - -#ifdef DUMP_MSGS - -# define dump_msg(fsg, /* const char * */ label, \ - /* const u8 * */ buf, /* unsigned */ length) do { \ - if (length < 512) { \ - DBG(fsg, "%s, length %u:\n", label, length); \ - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ - 16, 1, buf, length, 0); \ - } \ -} while (0) - -# define dump_cdb(fsg) do { } while (0) - -#else - -# define dump_msg(fsg, /* const char * */ label, \ - /* const u8 * */ buf, /* unsigned */ length) do { } while (0) - -# ifdef VERBOSE_DEBUG - -# define dump_cdb(fsg) \ - print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \ - 16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \ - -# else - -# define dump_cdb(fsg) do { } while (0) - -# endif /* VERBOSE_DEBUG */ - -#endif /* DUMP_MSGS */ - -/*-------------------------------------------------------------------------*/ - -/* CBI Interrupt data structure */ -struct interrupt_data { - u8 bType; - u8 bValue; -}; - -#define CBI_INTERRUPT_DATA_LEN 2 - -/* CBI Accept Device-Specific Command request */ -#define USB_CBI_ADSC_REQUEST 0x00 - - -/* Length of a SCSI Command Data Block */ -#define MAX_COMMAND_SIZE 16 - -/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ -#define SS_NO_SENSE 0 -#define SS_COMMUNICATION_FAILURE 0x040800 -#define SS_INVALID_COMMAND 0x052000 -#define SS_INVALID_FIELD_IN_CDB 0x052400 -#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 -#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 -#define SS_MEDIUM_NOT_PRESENT 0x023a00 -#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 -#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 -#define SS_RESET_OCCURRED 0x062900 -#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 -#define SS_UNRECOVERED_READ_ERROR 0x031100 -#define SS_WRITE_ERROR 0x030c02 -#define SS_WRITE_PROTECTED 0x072700 - -#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ -#define ASC(x) ((u8) ((x) >> 8)) -#define ASCQ(x) ((u8) (x)) - - -/*-------------------------------------------------------------------------*/ - - -struct fsg_lun { - struct file *filp; - loff_t file_length; - loff_t num_sectors; - - unsigned int initially_ro:1; - unsigned int ro:1; - unsigned int removable:1; - unsigned int cdrom:1; - unsigned int prevent_medium_removal:1; - unsigned int registered:1; - unsigned int info_valid:1; - unsigned int nofua:1; - - u32 sense_data; - u32 sense_data_info; - u32 unit_attention_data; - - unsigned int blkbits; /* Bits of logical block size of bound block device */ - unsigned int blksize; /* logical block size of bound block device */ - struct device dev; -}; - -#define fsg_lun_is_open(curlun) ((curlun)->filp != NULL) - -static struct fsg_lun *fsg_lun_from_dev(struct device *dev) -{ - return container_of(dev, struct fsg_lun, dev); -} - - -/* Big enough to hold our biggest descriptor */ -#define EP0_BUFSIZE 256 -#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ - -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - -static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; -module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO); -MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers"); - -#else - -/* - * Number of buffers we will use. - * 2 is usually enough for good buffering pipeline - */ -#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS - -#endif /* CONFIG_USB_DEBUG */ - -/* check if fsg_num_buffers is within a valid range */ -static inline int fsg_num_buffers_validate(void) -{ - if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) - return 0; - pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", - fsg_num_buffers, 2 ,4); - return -EINVAL; -} - -/* Default size of buffer length. */ -#define FSG_BUFLEN ((u32)16384) - -/* Maximal number of LUNs supported in mass storage function */ -#define FSG_MAX_LUNS 8 - -enum fsg_buffer_state { - BUF_STATE_EMPTY = 0, - BUF_STATE_FULL, - BUF_STATE_BUSY -}; - -struct fsg_buffhd { - void *buf; - enum fsg_buffer_state state; - struct fsg_buffhd *next; - - /* - * The NetChip 2280 is faster, and handles some protocol faults - * better, if we don't submit any short bulk-out read requests. - * So we will record the intended request length here. - */ - unsigned int bulk_out_intended_length; - - struct usb_request *inreq; - int inreq_busy; - struct usb_request *outreq; - int outreq_busy; -}; - -enum fsg_state { - /* This one isn't used anywhere */ - FSG_STATE_COMMAND_PHASE = -10, - FSG_STATE_DATA_PHASE, - FSG_STATE_STATUS_PHASE, - - FSG_STATE_IDLE = 0, - FSG_STATE_ABORT_BULK_OUT, - FSG_STATE_RESET, - FSG_STATE_INTERFACE_CHANGE, - FSG_STATE_CONFIG_CHANGE, - FSG_STATE_DISCONNECT, - FSG_STATE_EXIT, - FSG_STATE_TERMINATED -}; - -enum data_direction { - DATA_DIR_UNKNOWN = 0, - DATA_DIR_FROM_HOST, - DATA_DIR_TO_HOST, - DATA_DIR_NONE -}; - - -/*-------------------------------------------------------------------------*/ - - -static inline u32 get_unaligned_be24(u8 *buf) -{ - return 0xffffff & (u32) get_unaligned_be32(buf - 1); -} - - -/*-------------------------------------------------------------------------*/ - - -enum { -#ifndef FSG_NO_DEVICE_STRINGS - FSG_STRING_MANUFACTURER = 1, - FSG_STRING_PRODUCT, - FSG_STRING_SERIAL, - FSG_STRING_CONFIG, -#endif - FSG_STRING_INTERFACE -}; - - -#ifndef FSG_NO_OTG -static struct usb_otg_descriptor -fsg_otg_desc = { - .bLength = sizeof fsg_otg_desc, - .bDescriptorType = USB_DT_OTG, - - .bmAttributes = USB_OTG_SRP, -}; -#endif - -/* There is only one interface. */ - -static struct usb_interface_descriptor -fsg_intf_desc = { - .bLength = sizeof fsg_intf_desc, - .bDescriptorType = USB_DT_INTERFACE, - - .bNumEndpoints = 2, /* Adjusted during fsg_bind() */ - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */ - .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ - .iInterface = FSG_STRING_INTERFACE, -}; - -/* - * Three full-speed endpoint descriptors: bulk-in, bulk-out, and - * interrupt-in. - */ - -static struct usb_endpoint_descriptor -fsg_fs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; - -static struct usb_endpoint_descriptor -fsg_fs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; - -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_fs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 32, /* frames -> 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - -static struct usb_descriptor_header *fsg_fs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_fs_intr_in_desc, -#endif - NULL, -}; - - -/* - * USB 2.0 devices need to expose both high speed and full speed - * descriptors, unless they only run at full speed. - * - * That means alternate endpoint descriptors (bigger packets) - * and a "device qualifier" ... plus more construction options - * for the configuration descriptor. - */ -static struct usb_endpoint_descriptor -fsg_hs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor -fsg_hs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), - .bInterval = 1, /* NAK every 1 uframe */ -}; - -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_hs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - -static struct usb_descriptor_header *fsg_hs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_hs_intr_in_desc, -#endif - NULL, -}; - -static struct usb_endpoint_descriptor -fsg_ss_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /*.bMaxBurst = DYNAMIC, */ -}; - -static struct usb_endpoint_descriptor -fsg_ss_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /*.bMaxBurst = DYNAMIC, */ -}; - -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_ss_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ -}; - -static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - .wBytesPerInterval = cpu_to_le16(2), -}; - -#ifndef FSG_NO_OTG -# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - -static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = { - .bLength = USB_DT_USB_EXT_CAP_SIZE, - .bDescriptorType = USB_DT_DEVICE_CAPABILITY, - .bDevCapabilityType = USB_CAP_TYPE_EXT, - - .bmAttributes = cpu_to_le32(USB_LPM_SUPPORT), -}; - -static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = { - .bLength = USB_DT_USB_SS_CAP_SIZE, - .bDescriptorType = USB_DT_DEVICE_CAPABILITY, - .bDevCapabilityType = USB_SS_CAP_TYPE, - - /* .bmAttributes = LTM is not supported yet */ - - .wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION - | USB_FULL_SPEED_OPERATION - | USB_HIGH_SPEED_OPERATION - | USB_5GBPS_OPERATION), - .bFunctionalitySupport = USB_LOW_SPEED_OPERATION, - .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT, - .bU2DevExitLat = cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT), -}; - -static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { - .bLength = USB_DT_BOS_SIZE, - .bDescriptorType = USB_DT_BOS, - - .wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE - + USB_DT_USB_EXT_CAP_SIZE - + USB_DT_USB_SS_CAP_SIZE), - - .bNumDeviceCaps = 2, -}; - -static struct usb_descriptor_header *fsg_ss_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_ss_intr_in_desc, - (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc, -#endif - NULL, -}; - -/* Maxpacket and other transfer characteristics vary by speed. */ -static __maybe_unused struct usb_endpoint_descriptor * -fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, - struct usb_endpoint_descriptor *hs, - struct usb_endpoint_descriptor *ss) -{ - if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) - return ss; - else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return hs; - return fs; -} - - -/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ -static struct usb_string fsg_strings[] = { -#ifndef FSG_NO_DEVICE_STRINGS - {FSG_STRING_MANUFACTURER, fsg_string_manufacturer}, - {FSG_STRING_PRODUCT, fsg_string_product}, - {FSG_STRING_SERIAL, ""}, - {FSG_STRING_CONFIG, fsg_string_config}, -#endif - {FSG_STRING_INTERFACE, fsg_string_interface}, - {} -}; - -static struct usb_gadget_strings fsg_stringtab = { - .language = 0x0409, /* en-us */ - .strings = fsg_strings, -}; - - - /*-------------------------------------------------------------------------*/ - -/* - * If the next two routines are called while the gadget is registered, - * the caller must own fsg->filesem for writing. - */ - -static void fsg_lun_close(struct fsg_lun *curlun) -{ - if (curlun->filp) { - LDBG(curlun, "close backing file\n"); - fput(curlun->filp); - curlun->filp = NULL; - } -} - - -static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) -{ - int ro; - struct file *filp = NULL; - int rc = -EINVAL; - struct inode *inode = NULL; - loff_t size; - loff_t num_sectors; - loff_t min_sectors; - unsigned int blkbits; - unsigned int blksize; - - /* R/W if we can, R/O if we must */ - ro = curlun->initially_ro; - if (!ro) { - filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); - if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES) - ro = 1; - } - if (ro) - filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - LINFO(curlun, "unable to open backing file: %s\n", filename); - return PTR_ERR(filp); - } - - if (!(filp->f_mode & FMODE_WRITE)) - ro = 1; - - inode = file_inode(filp); - if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) { - LINFO(curlun, "invalid file type: %s\n", filename); - goto out; - } - - /* - * If we can't read the file, it's no good. - * If we can't write the file, use it read-only. - */ - if (!(filp->f_op->read || filp->f_op->aio_read)) { - LINFO(curlun, "file not readable: %s\n", filename); - goto out; - } - if (!(filp->f_op->write || filp->f_op->aio_write)) - ro = 1; - - size = i_size_read(inode->i_mapping->host); - if (size < 0) { - LINFO(curlun, "unable to find file size: %s\n", filename); - rc = (int) size; - goto out; - } - - if (curlun->cdrom) { - blksize = 2048; - blkbits = 11; - } else if (inode->i_bdev) { - blksize = bdev_logical_block_size(inode->i_bdev); - blkbits = blksize_bits(blksize); - } else { - blksize = 512; - blkbits = 9; - } - - num_sectors = size >> blkbits; /* File size in logic-block-size blocks */ - min_sectors = 1; - if (curlun->cdrom) { - min_sectors = 300; /* Smallest track is 300 frames */ - if (num_sectors >= 256*60*75) { - num_sectors = 256*60*75 - 1; - LINFO(curlun, "file too big: %s\n", filename); - LINFO(curlun, "using only first %d blocks\n", - (int) num_sectors); - } - } - if (num_sectors < min_sectors) { - LINFO(curlun, "file too small: %s\n", filename); - rc = -ETOOSMALL; - goto out; - } - - if (fsg_lun_is_open(curlun)) - fsg_lun_close(curlun); - - curlun->blksize = blksize; - curlun->blkbits = blkbits; - curlun->ro = ro; - curlun->filp = filp; - curlun->file_length = size; - curlun->num_sectors = num_sectors; - LDBG(curlun, "open backing file: %s\n", filename); - return 0; - -out: - fput(filp); - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -/* - * Sync the file data, don't bother with the metadata. - * This code was copied from fs/buffer.c:sys_fdatasync(). - */ -static int fsg_lun_fsync_sub(struct fsg_lun *curlun) -{ - struct file *filp = curlun->filp; - - if (curlun->ro || !filp) - return 0; - return vfs_fsync(filp, 1); -} - -static void store_cdrom_address(u8 *dest, int msf, u32 addr) -{ - if (msf) { - /* Convert to Minutes-Seconds-Frames */ - addr >>= 2; /* Convert to 2048-byte frames */ - addr += 2*75; /* Lead-in occupies 2 seconds */ - dest[3] = addr % 75; /* Frames */ - addr /= 75; - dest[2] = addr % 60; /* Seconds */ - addr /= 60; - dest[1] = addr; /* Minutes */ - dest[0] = 0; /* Reserved */ - } else { - /* Absolute sector */ - put_unaligned_be32(addr, dest); - } -} - - -/*-------------------------------------------------------------------------*/ - - -static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - - return sprintf(buf, "%d\n", fsg_lun_is_open(curlun) - ? curlun->ro - : curlun->initially_ro); -} - -static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - - return sprintf(buf, "%u\n", curlun->nofua); -} - -static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct rw_semaphore *filesem = dev_get_drvdata(dev); - char *p; - ssize_t rc; - - down_read(filesem); - if (fsg_lun_is_open(curlun)) { /* Get the complete pathname */ - p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); - if (IS_ERR(p)) - rc = PTR_ERR(p); - else { - rc = strlen(p); - memmove(buf, p, rc); - buf[rc] = '\n'; /* Add a newline */ - buf[++rc] = 0; - } - } else { /* No file, return 0 bytes */ - *buf = 0; - rc = 0; - } - up_read(filesem); - return rc; -} - - -static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - ssize_t rc; - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct rw_semaphore *filesem = dev_get_drvdata(dev); - unsigned ro; - - rc = kstrtouint(buf, 2, &ro); - if (rc) - return rc; - - /* - * Allow the write-enable status to change only while the - * backing file is closed. - */ - down_read(filesem); - if (fsg_lun_is_open(curlun)) { - LDBG(curlun, "read-only status change prevented\n"); - rc = -EBUSY; - } else { - curlun->ro = ro; - curlun->initially_ro = ro; - LDBG(curlun, "read-only status set to %d\n", curlun->ro); - rc = count; - } - up_read(filesem); - return rc; -} - -static ssize_t fsg_store_nofua(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - unsigned nofua; - int ret; - - ret = kstrtouint(buf, 2, &nofua); - if (ret) - return ret; - - /* Sync data when switching from async mode to sync */ - if (!nofua && curlun->nofua) - fsg_lun_fsync_sub(curlun); - - curlun->nofua = nofua; - - return count; -} - -static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - struct rw_semaphore *filesem = dev_get_drvdata(dev); - int rc = 0; - - if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { - LDBG(curlun, "eject attempt prevented\n"); - return -EBUSY; /* "Door is locked" */ - } - - /* Remove a trailing newline */ - if (count > 0 && buf[count-1] == '\n') - ((char *) buf)[count-1] = 0; /* Ugh! */ - - /* Load new medium */ - down_write(filesem); - if (count > 0 && buf[0]) { - /* fsg_lun_open() will close existing file if any. */ - rc = fsg_lun_open(curlun, buf); - if (rc == 0) - curlun->unit_attention_data = - SS_NOT_READY_TO_READY_TRANSITION; - } else if (fsg_lun_is_open(curlun)) { - fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(filesem); - return (rc < 0 ? rc : count); -} diff --git a/drivers/staging/ccg/sysfs-class-ccg_usb b/drivers/staging/ccg/sysfs-class-ccg_usb deleted file mode 100644 index dd12a332fb00..000000000000 --- a/drivers/staging/ccg/sysfs-class-ccg_usb +++ /dev/null @@ -1,158 +0,0 @@ -What: /sys/class/ccg_usb -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The ccg_usb/ class subdirectory belongs to ccg - USB gadget. - -What: /sys/class/ccg_usb/ccgX -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccg{0,1,2,3...} class - subdirectories correspond to each ccg gadget device; - at the time of this writing there is only ccg0 and it - represents the ccg gadget. - -What: /sys/class/ccg_usb/ccgX/functions -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - A comma-separated list of USB function names to be activated - in this ccg gadget. It includes both the functions provided - in-kernel by the ccg gadget and the functions provided from - userspace through FunctionFS. - -What: /sys/class/ccg_usb/ccgX/enable -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - A flag activating/deactivating the ccg usb gadget. - -What: /sys/class/ccg_usb/ccgX/state -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - Configurable usb gadget state: - - DISCONNECTED - CONNECTED - CONFIGURED - -What: /sys/class/ccg_usb/ccgX/f_acm/ -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_acm subdirectory - corresponds to the gadget's USB CDC serial (ACM) function - driver. - -What: /sys/class/ccg_usb/ccgX/f_acm/instances -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - Maximum number of the /dev/ttyGS interface the driver uses. - -What: /sys/class/ccg_usb/ccgX/f_fs -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_fs subdirectory - corresponds to the gadget's FunctionFS driver. - -What: /sys/class/ccg_usb/ccgX/f_fs/user_functions -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - A comma-separeted list of USB function names to be supported - from userspace. No other userspace FunctionFS functions can - be supported than listed here. However, the actual activation - of these functions is still done through - /sys/class/ccg_usb/ccgX/functions, where it is possible - to specify any subset (including maximum and empty) of - /sys/class/ccg_usb/ccgX/f_fs/user_functions. - -What: /sys/class/ccg_usb/ccgX/f_fs/max_user_functions -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - Maximum number of USB functions to be supported from userspace. - -What: /sys/class/ccg_usb/ccgX/f_rndis -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_rndis subdirectory - corresponds to the gadget's RNDIS driver. - -What: /sys/class/ccg_usb/ccgX/f_rndis/manufacturer -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - RNDIS Ethernet port manufacturer string. - -What: /sys/class/ccg_usb/ccgX/f_rndis/wceis -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - RNDIS Ethernet port wireless flag. - -What: /sys/class/ccg_usb/ccgX/f_rndis/ethaddr -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - RNDIS Ethernet port Ethernet address. - -What: /sys/class/ccg_usb/ccgX/f_rndis/vendorID -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - RNDIS Ethernet port vendor ID. - -What: /sys/class/ccg_usb/ccgX/f_mass_storage -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_mass_storage subdirectory - corresponds to the gadget's USB mass storage driver. - -What: /sys/class/ccg_usb/ccgX/f_mass_storage/lun -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_mass_storage/lun - subdirectory corresponds to the gadget's USB mass storage - driver and its underlying storage. - -What: /sys/class/ccg_usb/ccgX/f_mass_storage/lun -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - The /sys/class/ccg_usb/ccgX/f_mass_storage/lun - subdirectory corresponds to the gadget's USB mass storage - driver and its underlying storage. - -What: /sys/class/ccg_usb/ccgX/f_mass_storage/lun/file -Date: May 2012 -KernelVersion: 3.4 -Contact: linux-usb@vger.kernel.org -Description: - Gadget's USB mass storage underlying file. diff --git a/drivers/staging/ccg/u_ether.c b/drivers/staging/ccg/u_ether.c deleted file mode 100644 index fed78865adc6..000000000000 --- a/drivers/staging/ccg/u_ether.c +++ /dev/null @@ -1,986 +0,0 @@ -/* - * u_ether.c -- Ethernet-over-USB link layer utilities for Gadget stack - * - * Copyright (C) 2003-2005,2008 David Brownell - * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger - * Copyright (C) 2008 Nokia Corporation - * - * 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. - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include - -#include "u_ether.h" - - -/* - * This component encapsulates the Ethernet link glue needed to provide - * one (!) network link through the USB gadget stack, normally "usb0". - * - * The control and data models are handled by the function driver which - * connects to this code; such as CDC Ethernet (ECM or EEM), - * "CDC Subset", or RNDIS. That includes all descriptor and endpoint - * management. - * - * Link level addressing is handled by this component using module - * parameters; if no such parameters are provided, random link level - * addresses are used. Each end of the link uses one address. The - * host end address is exported in various ways, and is often recorded - * in configuration databases. - * - * The driver which assembles each configuration using such a link is - * responsible for ensuring that each configuration includes at most one - * instance of is network link. (The network layer provides ways for - * this single "physical" link to be used by multiple virtual links.) - */ - -#define UETH__VERSION "29-May-2008" - -struct eth_dev { - /* lock is held while accessing port_usb - * or updating its backlink port_usb->ioport - */ - spinlock_t lock; - struct gether *port_usb; - - struct net_device *net; - struct usb_gadget *gadget; - - spinlock_t req_lock; /* guard {rx,tx}_reqs */ - struct list_head tx_reqs, rx_reqs; - atomic_t tx_qlen; - - struct sk_buff_head rx_frames; - - unsigned header_len; - struct sk_buff *(*wrap)(struct gether *, struct sk_buff *skb); - int (*unwrap)(struct gether *, - struct sk_buff *skb, - struct sk_buff_head *list); - - struct work_struct work; - - unsigned long todo; -#define WORK_RX_MEMORY 0 - - bool zlp; - u8 host_mac[ETH_ALEN]; -}; - -/*-------------------------------------------------------------------------*/ - -#define RX_EXTRA 20 /* bytes guarding against rx overflows */ - -#define DEFAULT_QLEN 2 /* double buffering by default */ - -static unsigned qmult = 5; -module_param(qmult, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed"); - -/* for dual-speed hardware, use deeper queues at high/super speed */ -static inline int qlen(struct usb_gadget *gadget) -{ - if (gadget_is_dualspeed(gadget) && (gadget->speed == USB_SPEED_HIGH || - gadget->speed == USB_SPEED_SUPER)) - return qmult * DEFAULT_QLEN; - else - return DEFAULT_QLEN; -} - -/*-------------------------------------------------------------------------*/ - -/* REVISIT there must be a better way than having two sets - * of debug calls ... - */ - -#undef DBG -#undef VDBG -#undef ERROR -#undef INFO - -#define xprintk(d, level, fmt, args...) \ - printk(level "%s: " fmt , (d)->net->name , ## args) - -#ifdef DEBUG -#undef DEBUG -#define DBG(dev, fmt, args...) \ - xprintk(dev , KERN_DEBUG , fmt , ## args) -#else -#define DBG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - -#ifdef VERBOSE_DEBUG -#define VDBG DBG -#else -#define VDBG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - -#define ERROR(dev, fmt, args...) \ - xprintk(dev , KERN_ERR , fmt , ## args) -#define INFO(dev, fmt, args...) \ - xprintk(dev , KERN_INFO , fmt , ## args) - -/*-------------------------------------------------------------------------*/ - -/* NETWORK DRIVER HOOKUP (to the layer above this driver) */ - -static int ueth_change_mtu(struct net_device *net, int new_mtu) -{ - struct eth_dev *dev = netdev_priv(net); - unsigned long flags; - int status = 0; - - /* don't change MTU on "live" link (peer won't know) */ - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) - status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN) - status = -ERANGE; - else - net->mtu = new_mtu; - spin_unlock_irqrestore(&dev->lock, flags); - - return status; -} - -static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) -{ - struct eth_dev *dev = netdev_priv(net); - - strlcpy(p->driver, "g_ether", sizeof(p->driver)); - strlcpy(p->version, UETH__VERSION, sizeof(p->version)); - strlcpy(p->fw_version, dev->gadget->name, sizeof(p->fw_version)); - strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof(p->bus_info)); -} - -/* REVISIT can also support: - * - WOL (by tracking suspends and issuing remote wakeup) - * - msglevel (implies updated messaging) - * - ... probably more ethtool ops - */ - -static const struct ethtool_ops ops = { - .get_drvinfo = eth_get_drvinfo, - .get_link = ethtool_op_get_link, -}; - -static void defer_kevent(struct eth_dev *dev, int flag) -{ - if (test_and_set_bit(flag, &dev->todo)) - return; - if (!schedule_work(&dev->work)) - ERROR(dev, "kevent %d may have been dropped\n", flag); - else - DBG(dev, "kevent %d scheduled\n", flag); -} - -static void rx_complete(struct usb_ep *ep, struct usb_request *req); - -static int -rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) -{ - struct sk_buff *skb; - int retval = -ENOMEM; - size_t size = 0; - struct usb_ep *out; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) - out = dev->port_usb->out_ep; - else - out = NULL; - spin_unlock_irqrestore(&dev->lock, flags); - - if (!out) - return -ENOTCONN; - - - /* Padding up to RX_EXTRA handles minor disagreements with host. - * Normally we use the USB "terminate on short read" convention; - * so allow up to (N*maxpacket), since that memory is normally - * already allocated. Some hardware doesn't deal well with short - * reads (e.g. DMA must be N*maxpacket), so for now don't trim a - * byte off the end (to force hardware errors on overflow). - * - * RNDIS uses internal framing, and explicitly allows senders to - * pad to end-of-packet. That's potentially nice for speed, but - * means receivers can't recover lost synch on their own (because - * new packets don't only start after a short RX). - */ - size += sizeof(struct ethhdr) + dev->net->mtu + RX_EXTRA; - size += dev->port_usb->header_len; - size += out->maxpacket - 1; - size -= size % out->maxpacket; - - if (dev->port_usb->is_fixed) - size = max_t(size_t, size, dev->port_usb->fixed_out_len); - - skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); - if (skb == NULL) { - DBG(dev, "no rx skb\n"); - goto enomem; - } - - /* Some platforms perform better when IP packets are aligned, - * but on at least one, checksumming fails otherwise. Note: - * RNDIS headers involve variable numbers of LE32 values. - */ - skb_reserve(skb, NET_IP_ALIGN); - - req->buf = skb->data; - req->length = size; - req->complete = rx_complete; - req->context = skb; - - retval = usb_ep_queue(out, req, gfp_flags); - if (retval == -ENOMEM) -enomem: - defer_kevent(dev, WORK_RX_MEMORY); - if (retval) { - DBG(dev, "rx submit --> %d\n", retval); - if (skb) - dev_kfree_skb_any(skb); - spin_lock_irqsave(&dev->req_lock, flags); - list_add(&req->list, &dev->rx_reqs); - spin_unlock_irqrestore(&dev->req_lock, flags); - } - return retval; -} - -static void rx_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct sk_buff *skb = req->context, *skb2; - struct eth_dev *dev = ep->driver_data; - int status = req->status; - - switch (status) { - - /* normal completion */ - case 0: - skb_put(skb, req->actual); - - if (dev->unwrap) { - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) { - status = dev->unwrap(dev->port_usb, - skb, - &dev->rx_frames); - } else { - dev_kfree_skb_any(skb); - status = -ENOTCONN; - } - spin_unlock_irqrestore(&dev->lock, flags); - } else { - skb_queue_tail(&dev->rx_frames, skb); - } - skb = NULL; - - skb2 = skb_dequeue(&dev->rx_frames); - while (skb2) { - if (status < 0 - || ETH_HLEN > skb2->len - || skb2->len > ETH_FRAME_LEN) { - dev->net->stats.rx_errors++; - dev->net->stats.rx_length_errors++; - DBG(dev, "rx length %d\n", skb2->len); - dev_kfree_skb_any(skb2); - goto next_frame; - } - skb2->protocol = eth_type_trans(skb2, dev->net); - dev->net->stats.rx_packets++; - dev->net->stats.rx_bytes += skb2->len; - - /* no buffer copies needed, unless hardware can't - * use skb buffers. - */ - status = netif_rx(skb2); -next_frame: - skb2 = skb_dequeue(&dev->rx_frames); - } - break; - - /* software-driven interface shutdown */ - case -ECONNRESET: /* unlink */ - case -ESHUTDOWN: /* disconnect etc */ - VDBG(dev, "rx shutdown, code %d\n", status); - goto quiesce; - - /* for hardware automagic (such as pxa) */ - case -ECONNABORTED: /* endpoint reset */ - DBG(dev, "rx %s reset\n", ep->name); - defer_kevent(dev, WORK_RX_MEMORY); -quiesce: - dev_kfree_skb_any(skb); - goto clean; - - /* data overrun */ - case -EOVERFLOW: - dev->net->stats.rx_over_errors++; - /* FALLTHROUGH */ - - default: - dev->net->stats.rx_errors++; - DBG(dev, "rx status %d\n", status); - break; - } - - if (skb) - dev_kfree_skb_any(skb); - if (!netif_running(dev->net)) { -clean: - spin_lock(&dev->req_lock); - list_add(&req->list, &dev->rx_reqs); - spin_unlock(&dev->req_lock); - req = NULL; - } - if (req) - rx_submit(dev, req, GFP_ATOMIC); -} - -static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n) -{ - unsigned i; - struct usb_request *req; - - if (!n) - return -ENOMEM; - - /* queue/recycle up to N requests */ - i = n; - list_for_each_entry(req, list, list) { - if (i-- == 0) - goto extra; - } - while (i--) { - req = usb_ep_alloc_request(ep, GFP_ATOMIC); - if (!req) - return list_empty(list) ? -ENOMEM : 0; - list_add(&req->list, list); - } - return 0; - -extra: - /* free extras */ - for (;;) { - struct list_head *next; - - next = req->list.next; - list_del(&req->list); - usb_ep_free_request(ep, req); - - if (next == list) - break; - - req = container_of(next, struct usb_request, list); - } - return 0; -} - -static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n) -{ - int status; - - spin_lock(&dev->req_lock); - status = prealloc(&dev->tx_reqs, link->in_ep, n); - if (status < 0) - goto fail; - status = prealloc(&dev->rx_reqs, link->out_ep, n); - if (status < 0) - goto fail; - goto done; -fail: - DBG(dev, "can't alloc requests\n"); -done: - spin_unlock(&dev->req_lock); - return status; -} - -static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) -{ - struct usb_request *req; - unsigned long flags; - - /* fill unused rxq slots with some skb */ - spin_lock_irqsave(&dev->req_lock, flags); - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del_init(&req->list); - spin_unlock_irqrestore(&dev->req_lock, flags); - - if (rx_submit(dev, req, gfp_flags) < 0) { - defer_kevent(dev, WORK_RX_MEMORY); - return; - } - - spin_lock_irqsave(&dev->req_lock, flags); - } - spin_unlock_irqrestore(&dev->req_lock, flags); -} - -static void eth_work(struct work_struct *work) -{ - struct eth_dev *dev = container_of(work, struct eth_dev, work); - - if (test_and_clear_bit(WORK_RX_MEMORY, &dev->todo)) { - if (netif_running(dev->net)) - rx_fill(dev, GFP_KERNEL); - } - - if (dev->todo) - DBG(dev, "work done, flags = 0x%lx\n", dev->todo); -} - -static void tx_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct sk_buff *skb = req->context; - struct eth_dev *dev = ep->driver_data; - - switch (req->status) { - default: - dev->net->stats.tx_errors++; - VDBG(dev, "tx err %d\n", req->status); - /* FALLTHROUGH */ - case -ECONNRESET: /* unlink */ - case -ESHUTDOWN: /* disconnect etc */ - break; - case 0: - dev->net->stats.tx_bytes += skb->len; - } - dev->net->stats.tx_packets++; - - spin_lock(&dev->req_lock); - list_add(&req->list, &dev->tx_reqs); - spin_unlock(&dev->req_lock); - dev_kfree_skb_any(skb); - - atomic_dec(&dev->tx_qlen); - if (netif_carrier_ok(dev->net)) - netif_wake_queue(dev->net); -} - -static inline int is_promisc(u16 cdc_filter) -{ - return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS; -} - -static netdev_tx_t eth_start_xmit(struct sk_buff *skb, - struct net_device *net) -{ - struct eth_dev *dev = netdev_priv(net); - int length = skb->len; - int retval; - struct usb_request *req = NULL; - unsigned long flags; - struct usb_ep *in; - u16 cdc_filter; - - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) { - in = dev->port_usb->in_ep; - cdc_filter = dev->port_usb->cdc_filter; - } else { - in = NULL; - cdc_filter = 0; - } - spin_unlock_irqrestore(&dev->lock, flags); - - if (!in) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - /* apply outgoing CDC or RNDIS filters */ - if (!is_promisc(cdc_filter)) { - u8 *dest = skb->data; - - if (is_multicast_ether_addr(dest)) { - u16 type; - - /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host - * SET_ETHERNET_MULTICAST_FILTERS requests - */ - if (is_broadcast_ether_addr(dest)) - type = USB_CDC_PACKET_TYPE_BROADCAST; - else - type = USB_CDC_PACKET_TYPE_ALL_MULTICAST; - if (!(cdc_filter & type)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - } - /* ignores USB_CDC_PACKET_TYPE_DIRECTED */ - } - - spin_lock_irqsave(&dev->req_lock, flags); - /* - * this freelist can be empty if an interrupt triggered disconnect() - * and reconfigured the gadget (shutting down this queue) after the - * network stack decided to xmit but before we got the spinlock. - */ - if (list_empty(&dev->tx_reqs)) { - spin_unlock_irqrestore(&dev->req_lock, flags); - return NETDEV_TX_BUSY; - } - - req = container_of(dev->tx_reqs.next, struct usb_request, list); - list_del(&req->list); - - /* temporarily stop TX queue when the freelist empties */ - if (list_empty(&dev->tx_reqs)) - netif_stop_queue(net); - spin_unlock_irqrestore(&dev->req_lock, flags); - - /* no buffer copies needed, unless the network stack did it - * or the hardware can't use skb buffers. - * or there's not enough space for extra headers we need - */ - if (dev->wrap) { - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) - skb = dev->wrap(dev->port_usb, skb); - spin_unlock_irqrestore(&dev->lock, flags); - if (!skb) - goto drop; - - length = skb->len; - } - req->buf = skb->data; - req->context = skb; - req->complete = tx_complete; - - /* NCM requires no zlp if transfer is dwNtbInMaxSize */ - if (dev->port_usb->is_fixed && - length == dev->port_usb->fixed_in_len && - (length % in->maxpacket) == 0) - req->zero = 0; - else - req->zero = 1; - - /* use zlp framing on tx for strict CDC-Ether conformance, - * though any robust network rx path ignores extra padding. - * and some hardware doesn't like to write zlps. - */ - if (req->zero && !dev->zlp && (length % in->maxpacket) == 0) - length++; - - req->length = length; - - /* throttle high/super speed IRQ rate back slightly */ - if (gadget_is_dualspeed(dev->gadget)) - req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH || - dev->gadget->speed == USB_SPEED_SUPER) - ? ((atomic_read(&dev->tx_qlen) % qmult) != 0) - : 0; - - retval = usb_ep_queue(in, req, GFP_ATOMIC); - switch (retval) { - default: - DBG(dev, "tx queue err %d\n", retval); - break; - case 0: - net->trans_start = jiffies; - atomic_inc(&dev->tx_qlen); - } - - if (retval) { - dev_kfree_skb_any(skb); -drop: - dev->net->stats.tx_dropped++; - spin_lock_irqsave(&dev->req_lock, flags); - if (list_empty(&dev->tx_reqs)) - netif_start_queue(net); - list_add(&req->list, &dev->tx_reqs); - spin_unlock_irqrestore(&dev->req_lock, flags); - } - return NETDEV_TX_OK; -} - -/*-------------------------------------------------------------------------*/ - -static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) -{ - DBG(dev, "%s\n", __func__); - - /* fill the rx queue */ - rx_fill(dev, gfp_flags); - - /* and open the tx floodgates */ - atomic_set(&dev->tx_qlen, 0); - netif_wake_queue(dev->net); -} - -static int eth_open(struct net_device *net) -{ - struct eth_dev *dev = netdev_priv(net); - struct gether *link; - - DBG(dev, "%s\n", __func__); - if (netif_carrier_ok(dev->net)) - eth_start(dev, GFP_KERNEL); - - spin_lock_irq(&dev->lock); - link = dev->port_usb; - if (link && link->open) - link->open(link); - spin_unlock_irq(&dev->lock); - - return 0; -} - -static int eth_stop(struct net_device *net) -{ - struct eth_dev *dev = netdev_priv(net); - unsigned long flags; - - VDBG(dev, "%s\n", __func__); - netif_stop_queue(net); - - DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", - dev->net->stats.rx_packets, dev->net->stats.tx_packets, - dev->net->stats.rx_errors, dev->net->stats.tx_errors - ); - - /* ensure there are no more active requests */ - spin_lock_irqsave(&dev->lock, flags); - if (dev->port_usb) { - struct gether *link = dev->port_usb; - - if (link->close) - link->close(link); - - /* NOTE: we have no abort-queue primitive we could use - * to cancel all pending I/O. Instead, we disable then - * reenable the endpoints ... this idiom may leave toggle - * wrong, but that's a self-correcting error. - * - * REVISIT: we *COULD* just let the transfers complete at - * their own pace; the network stack can handle old packets. - * For the moment we leave this here, since it works. - */ - usb_ep_disable(link->in_ep); - usb_ep_disable(link->out_ep); - if (netif_carrier_ok(net)) { - DBG(dev, "host still using in/out endpoints\n"); - usb_ep_enable(link->in_ep); - usb_ep_enable(link->out_ep); - } - } - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */ -static char *dev_addr; -module_param(dev_addr, charp, S_IRUGO); -MODULE_PARM_DESC(dev_addr, "Device Ethernet Address"); - -/* this address is invisible to ifconfig */ -static char *host_addr; -module_param(host_addr, charp, S_IRUGO); -MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); - -static int get_ether_addr(const char *str, u8 *dev_addr) -{ - if (str) { - unsigned i; - - for (i = 0; i < 6; i++) { - unsigned char num; - - if ((*str == '.') || (*str == ':')) - str++; - num = hex_to_bin(*str++) << 4; - num |= hex_to_bin(*str++); - dev_addr [i] = num; - } - if (is_valid_ether_addr(dev_addr)) - return 0; - } - eth_random_addr(dev_addr); - return 1; -} - -static struct eth_dev *the_dev; - -static const struct net_device_ops eth_netdev_ops = { - .ndo_open = eth_open, - .ndo_stop = eth_stop, - .ndo_start_xmit = eth_start_xmit, - .ndo_change_mtu = ueth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static struct device_type gadget_type = { - .name = "gadget", -}; - -/** - * gether_setup_name - initialize one ethernet-over-usb link - * @g: gadget to associated with these links - * @ethaddr: NULL, or a buffer in which the ethernet address of the - * host side of the link is recorded - * @netname: name for network device (for example, "usb") - * Context: may sleep - * - * This sets up the single network link that may be exported by a - * gadget driver using this framework. The link layer addresses are - * set up using module parameters. - * - * Returns negative errno, or zero on success - */ -int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], - const char *netname) -{ - struct eth_dev *dev; - struct net_device *net; - int status; - - if (the_dev) - return -EBUSY; - - net = alloc_etherdev(sizeof *dev); - if (!net) - return -ENOMEM; - - dev = netdev_priv(net); - spin_lock_init(&dev->lock); - spin_lock_init(&dev->req_lock); - INIT_WORK(&dev->work, eth_work); - INIT_LIST_HEAD(&dev->tx_reqs); - INIT_LIST_HEAD(&dev->rx_reqs); - - skb_queue_head_init(&dev->rx_frames); - - /* network device setup */ - dev->net = net; - snprintf(net->name, sizeof(net->name), "%s%%d", netname); - - if (get_ether_addr(dev_addr, net->dev_addr)) - dev_warn(&g->dev, - "using random %s ethernet address\n", "self"); - if (get_ether_addr(host_addr, dev->host_mac)) - dev_warn(&g->dev, - "using random %s ethernet address\n", "host"); - - if (ethaddr) - memcpy(ethaddr, dev->host_mac, ETH_ALEN); - - net->netdev_ops = ð_netdev_ops; - - SET_ETHTOOL_OPS(net, &ops); - - dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); - SET_NETDEV_DEVTYPE(net, &gadget_type); - - status = register_netdev(net); - if (status < 0) { - dev_dbg(&g->dev, "register_netdev failed, %d\n", status); - free_netdev(net); - } else { - INFO(dev, "MAC %pM\n", net->dev_addr); - INFO(dev, "HOST MAC %pM\n", dev->host_mac); - - the_dev = dev; - - /* two kinds of host-initiated state changes: - * - iff DATA transfer is active, carrier is "on" - * - tx queueing enabled if open *and* carrier is "on" - */ - netif_carrier_off(net); - } - - return status; -} - -/** - * gether_cleanup - remove Ethernet-over-USB device - * Context: may sleep - * - * This is called to free all resources allocated by @gether_setup(). - */ -void gether_cleanup(void) -{ - if (!the_dev) - return; - - unregister_netdev(the_dev->net); - flush_work(&the_dev->work); - free_netdev(the_dev->net); - - the_dev = NULL; -} - - -/** - * gether_connect - notify network layer that USB link is active - * @link: the USB link, set up with endpoints, descriptors matching - * current device speed, and any framing wrapper(s) set up. - * Context: irqs blocked - * - * This is called to activate endpoints and let the network layer know - * the connection is active ("carrier detect"). It may cause the I/O - * queues to open and start letting network packets flow, but will in - * any case activate the endpoints so that they respond properly to the - * USB host. - * - * Verify net_device pointer returned using IS_ERR(). If it doesn't - * indicate some error code (negative errno), ep->driver_data values - * have been overwritten. - */ -struct net_device *gether_connect(struct gether *link) -{ - struct eth_dev *dev = the_dev; - int result = 0; - - if (!dev) - return ERR_PTR(-EINVAL); - - link->in_ep->driver_data = dev; - result = usb_ep_enable(link->in_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", - link->in_ep->name, result); - goto fail0; - } - - link->out_ep->driver_data = dev; - result = usb_ep_enable(link->out_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", - link->out_ep->name, result); - goto fail1; - } - - if (result == 0) - result = alloc_requests(dev, link, qlen(dev->gadget)); - - if (result == 0) { - dev->zlp = link->is_zlp_ok; - DBG(dev, "qlen %d\n", qlen(dev->gadget)); - - dev->header_len = link->header_len; - dev->unwrap = link->unwrap; - dev->wrap = link->wrap; - - spin_lock(&dev->lock); - dev->port_usb = link; - link->ioport = dev; - if (netif_running(dev->net)) { - if (link->open) - link->open(link); - } else { - if (link->close) - link->close(link); - } - spin_unlock(&dev->lock); - - netif_carrier_on(dev->net); - if (netif_running(dev->net)) - eth_start(dev, GFP_ATOMIC); - - /* on error, disable any endpoints */ - } else { - (void) usb_ep_disable(link->out_ep); -fail1: - (void) usb_ep_disable(link->in_ep); - } -fail0: - /* caller is responsible for cleanup on error */ - if (result < 0) - return ERR_PTR(result); - return dev->net; -} - -/** - * gether_disconnect - notify network layer that USB link is inactive - * @link: the USB link, on which gether_connect() was called - * Context: irqs blocked - * - * This is called to deactivate endpoints and let the network layer know - * the connection went inactive ("no carrier"). - * - * On return, the state is as if gether_connect() had never been called. - * The endpoints are inactive, and accordingly without active USB I/O. - * Pointers to endpoint descriptors and endpoint private data are nulled. - */ -void gether_disconnect(struct gether *link) -{ - struct eth_dev *dev = link->ioport; - struct usb_request *req; - - WARN_ON(!dev); - if (!dev) - return; - - DBG(dev, "%s\n", __func__); - - netif_stop_queue(dev->net); - netif_carrier_off(dev->net); - - /* disable endpoints, forcing (synchronous) completion - * of all pending i/o. then free the request objects - * and forget about the endpoints. - */ - usb_ep_disable(link->in_ep); - spin_lock(&dev->req_lock); - while (!list_empty(&dev->tx_reqs)) { - req = container_of(dev->tx_reqs.next, - struct usb_request, list); - list_del(&req->list); - - spin_unlock(&dev->req_lock); - usb_ep_free_request(link->in_ep, req); - spin_lock(&dev->req_lock); - } - spin_unlock(&dev->req_lock); - link->in_ep->driver_data = NULL; - link->in_ep->desc = NULL; - - usb_ep_disable(link->out_ep); - spin_lock(&dev->req_lock); - while (!list_empty(&dev->rx_reqs)) { - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del(&req->list); - - spin_unlock(&dev->req_lock); - usb_ep_free_request(link->out_ep, req); - spin_lock(&dev->req_lock); - } - spin_unlock(&dev->req_lock); - link->out_ep->driver_data = NULL; - link->out_ep->desc = NULL; - - /* finish forgetting about this USB link episode */ - dev->header_len = 0; - dev->unwrap = NULL; - dev->wrap = NULL; - - spin_lock(&dev->lock); - dev->port_usb = NULL; - link->ioport = NULL; - spin_unlock(&dev->lock); -} diff --git a/drivers/staging/ccg/u_ether.h b/drivers/staging/ccg/u_ether.h deleted file mode 100644 index 6f4a1623d854..000000000000 --- a/drivers/staging/ccg/u_ether.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * u_ether.h -- interface to USB gadget "ethernet link" utilities - * - * Copyright (C) 2003-2005,2008 David Brownell - * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __U_ETHER_H -#define __U_ETHER_H - -#include -#include -#include -#include - -#include "gadget_chips.h" - - -/* - * This represents the USB side of an "ethernet" link, managed by a USB - * function which provides control and (maybe) framing. Two functions - * in different configurations could share the same ethernet link/netdev, - * using different host interaction models. - * - * There is a current limitation that only one instance of this link may - * be present in any given configuration. When that's a problem, network - * layer facilities can be used to package multiple logical links on this - * single "physical" one. - */ -struct gether { - struct usb_function func; - - /* updated by gether_{connect,disconnect} */ - struct eth_dev *ioport; - - /* endpoints handle full and/or high speeds */ - struct usb_ep *in_ep; - struct usb_ep *out_ep; - - bool is_zlp_ok; - - u16 cdc_filter; - - /* hooks for added framing, as needed for RNDIS and EEM. */ - u32 header_len; - /* NCM requires fixed size bundles */ - bool is_fixed; - u32 fixed_out_len; - u32 fixed_in_len; - struct sk_buff *(*wrap)(struct gether *port, - struct sk_buff *skb); - int (*unwrap)(struct gether *port, - struct sk_buff *skb, - struct sk_buff_head *list); - - /* called on network open/close */ - void (*open)(struct gether *); - void (*close)(struct gether *); -}; - -#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ - |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ - |USB_CDC_PACKET_TYPE_PROMISCUOUS \ - |USB_CDC_PACKET_TYPE_DIRECTED) - -/* variant of gether_setup that allows customizing network device name */ -int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], - const char *netname); - -/* netdev setup/teardown as directed by the gadget driver */ -/* gether_setup - initialize one ethernet-over-usb link - * @g: gadget to associated with these links - * @ethaddr: NULL, or a buffer in which the ethernet address of the - * host side of the link is recorded - * Context: may sleep - * - * This sets up the single network link that may be exported by a - * gadget driver using this framework. The link layer addresses are - * set up using module parameters. - * - * Returns negative errno, or zero on success - */ -static inline int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) -{ - return gether_setup_name(g, ethaddr, "usb"); -} - -void gether_cleanup(void); - -/* connect/disconnect is handled by individual functions */ -struct net_device *gether_connect(struct gether *); -void gether_disconnect(struct gether *); - -/* Some controllers can't support CDC Ethernet (ECM) ... */ -static inline bool can_support_ecm(struct usb_gadget *gadget) -{ - if (!gadget_supports_altsettings(gadget)) - return false; - - /* Everything else is *presumably* fine ... but this is a bit - * chancy, so be **CERTAIN** there are no hardware issues with - * your controller. Add it above if it can't handle CDC. - */ - return true; -} - -/* each configuration may bind one instance of an ethernet link */ -int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); -int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); -int ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); -int eem_bind_config(struct usb_configuration *c); - -#ifdef USB_ETH_RNDIS - -int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer); - -#else - -static inline int -rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], - u32 vendorID, const char *manufacturer) -{ - return 0; -} - -#endif - -/** - * rndis_bind_config - add RNDIS network link to a configuration - * @c: the configuration to support the network link - * @ethaddr: a buffer in which the ethernet address of the host side - * side of the link was recorded - * Context: single threaded during gadget setup - * - * Returns zero on success, else negative errno. - * - * Caller must have called @gether_setup(). Caller is also responsible - * for calling @gether_cleanup() before module unload. - */ -static inline int rndis_bind_config(struct usb_configuration *c, - u8 ethaddr[ETH_ALEN]) -{ - return rndis_bind_config_vendor(c, ethaddr, 0, NULL); -} - - -#endif /* __U_ETHER_H */ diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c deleted file mode 100644 index b10947ae0ac5..000000000000 --- a/drivers/staging/ccg/u_serial.c +++ /dev/null @@ -1,1339 +0,0 @@ -/* - * u_serial.c - utilities for USB gadget "serial port"/TTY support - * - * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) - * Copyright (C) 2008 David Brownell - * Copyright (C) 2008 by Nokia Corporation - * - * This code also borrows from usbserial.c, which is - * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2000 Peter Berger (pberger@brimson.com) - * Copyright (C) 2000 Al Borchers (alborchers@steinerpoint.com) - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "u_serial.h" - - -/* - * This component encapsulates the TTY layer glue needed to provide basic - * "serial port" functionality through the USB gadget stack. Each such - * port is exposed through a /dev/ttyGS* node. - * - * After initialization (gserial_setup), these TTY port devices stay - * available until they are removed (gserial_cleanup). Each one may be - * connected to a USB function (gserial_connect), or disconnected (with - * gserial_disconnect) when the USB host issues a config change event. - * Data can only flow when the port is connected to the host. - * - * A given TTY port can be made available in multiple configurations. - * For example, each one might expose a ttyGS0 node which provides a - * login application. In one case that might use CDC ACM interface 0, - * while another configuration might use interface 3 for that. The - * work to handle that (including descriptor management) is not part - * of this component. - * - * Configurations may expose more than one TTY port. For example, if - * ttyGS0 provides login service, then ttyGS1 might provide dialer access - * for a telephone or fax link. And ttyGS2 might be something that just - * needs a simple byte stream interface for some messaging protocol that - * is managed in userspace ... OBEX, PTP, and MTP have been mentioned. - */ - -#define PREFIX "ttyGS" - -/* - * gserial is the lifecycle interface, used by USB functions - * gs_port is the I/O nexus, used by the tty driver - * tty_struct links to the tty/filesystem framework - * - * gserial <---> gs_port ... links will be null when the USB link is - * inactive; managed by gserial_{connect,disconnect}(). each gserial - * instance can wrap its own USB control protocol. - * gserial->ioport == usb_ep->driver_data ... gs_port - * gs_port->port_usb ... gserial - * - * gs_port <---> tty_struct ... links will be null when the TTY file - * isn't opened; managed by gs_open()/gs_close() - * gserial->port_tty ... tty_struct - * tty_struct->driver_data ... gserial - */ - -/* RX and TX queues can buffer QUEUE_SIZE packets before they hit the - * next layer of buffering. For TX that's a circular buffer; for RX - * consider it a NOP. A third layer is provided by the TTY code. - */ -#define QUEUE_SIZE 16 -#define WRITE_BUF_SIZE 8192 /* TX only */ - -/* circular buffer */ -struct gs_buf { - unsigned buf_size; - char *buf_buf; - char *buf_get; - char *buf_put; -}; - -/* - * The port structure holds info for each port, one for each minor number - * (and thus for each /dev/ node). - */ -struct gs_port { - struct tty_port port; - spinlock_t port_lock; /* guard port_* access */ - - struct gserial *port_usb; - - bool openclose; /* open/close in progress */ - u8 port_num; - - struct list_head read_pool; - int read_started; - int read_allocated; - struct list_head read_queue; - unsigned n_read; - struct tasklet_struct push; - - struct list_head write_pool; - int write_started; - int write_allocated; - struct gs_buf port_write_buf; - wait_queue_head_t drain_wait; /* wait while writes drain */ - - /* REVISIT this state ... */ - struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ -}; - -/* increase N_PORTS if you need more */ -#define N_PORTS 4 -static struct portmaster { - struct mutex lock; /* protect open/close */ - struct gs_port *port; -} ports[N_PORTS]; -static unsigned n_ports; - -#define GS_CLOSE_TIMEOUT 15 /* seconds */ - - - -#ifdef VERBOSE_DEBUG -#define pr_vdebug(fmt, arg...) \ - pr_debug(fmt, ##arg) -#else -#define pr_vdebug(fmt, arg...) \ - ({ if (0) pr_debug(fmt, ##arg); }) -#endif - -/*-------------------------------------------------------------------------*/ - -/* Circular Buffer */ - -/* - * gs_buf_alloc - * - * Allocate a circular buffer and all associated memory. - */ -static int gs_buf_alloc(struct gs_buf *gb, unsigned size) -{ - gb->buf_buf = kmalloc(size, GFP_KERNEL); - if (gb->buf_buf == NULL) - return -ENOMEM; - - gb->buf_size = size; - gb->buf_put = gb->buf_buf; - gb->buf_get = gb->buf_buf; - - return 0; -} - -/* - * gs_buf_free - * - * Free the buffer and all associated memory. - */ -static void gs_buf_free(struct gs_buf *gb) -{ - kfree(gb->buf_buf); - gb->buf_buf = NULL; -} - -/* - * gs_buf_clear - * - * Clear out all data in the circular buffer. - */ -static void gs_buf_clear(struct gs_buf *gb) -{ - gb->buf_get = gb->buf_put; - /* equivalent to a get of all data available */ -} - -/* - * gs_buf_data_avail - * - * Return the number of bytes of data written into the circular - * buffer. - */ -static unsigned gs_buf_data_avail(struct gs_buf *gb) -{ - return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size; -} - -/* - * gs_buf_space_avail - * - * Return the number of bytes of space available in the circular - * buffer. - */ -static unsigned gs_buf_space_avail(struct gs_buf *gb) -{ - return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size; -} - -/* - * gs_buf_put - * - * Copy data data from a user buffer and put it into the circular buffer. - * Restrict to the amount of space available. - * - * Return the number of bytes copied. - */ -static unsigned -gs_buf_put(struct gs_buf *gb, const char *buf, unsigned count) -{ - unsigned len; - - len = gs_buf_space_avail(gb); - if (count > len) - count = len; - - if (count == 0) - return 0; - - len = gb->buf_buf + gb->buf_size - gb->buf_put; - if (count > len) { - memcpy(gb->buf_put, buf, len); - memcpy(gb->buf_buf, buf+len, count - len); - gb->buf_put = gb->buf_buf + count - len; - } else { - memcpy(gb->buf_put, buf, count); - if (count < len) - gb->buf_put += count; - else /* count == len */ - gb->buf_put = gb->buf_buf; - } - - return count; -} - -/* - * gs_buf_get - * - * Get data from the circular buffer and copy to the given buffer. - * Restrict to the amount of data available. - * - * Return the number of bytes copied. - */ -static unsigned -gs_buf_get(struct gs_buf *gb, char *buf, unsigned count) -{ - unsigned len; - - len = gs_buf_data_avail(gb); - if (count > len) - count = len; - - if (count == 0) - return 0; - - len = gb->buf_buf + gb->buf_size - gb->buf_get; - if (count > len) { - memcpy(buf, gb->buf_get, len); - memcpy(buf+len, gb->buf_buf, count - len); - gb->buf_get = gb->buf_buf + count - len; - } else { - memcpy(buf, gb->buf_get, count); - if (count < len) - gb->buf_get += count; - else /* count == len */ - gb->buf_get = gb->buf_buf; - } - - return count; -} - -/*-------------------------------------------------------------------------*/ - -/* I/O glue between TTY (upper) and USB function (lower) driver layers */ - -/* - * gs_alloc_req - * - * Allocate a usb_request and its buffer. Returns a pointer to the - * usb_request or NULL if there is an error. - */ -struct usb_request * -gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) -{ - struct usb_request *req; - - req = usb_ep_alloc_request(ep, kmalloc_flags); - - if (req != NULL) { - req->length = len; - req->buf = kmalloc(len, kmalloc_flags); - if (req->buf == NULL) { - usb_ep_free_request(ep, req); - return NULL; - } - } - - return req; -} - -/* - * gs_free_req - * - * Free a usb_request and its buffer. - */ -void gs_free_req(struct usb_ep *ep, struct usb_request *req) -{ - kfree(req->buf); - usb_ep_free_request(ep, req); -} - -/* - * gs_send_packet - * - * If there is data to send, a packet is built in the given - * buffer and the size is returned. If there is no data to - * send, 0 is returned. - * - * Called with port_lock held. - */ -static unsigned -gs_send_packet(struct gs_port *port, char *packet, unsigned size) -{ - unsigned len; - - len = gs_buf_data_avail(&port->port_write_buf); - if (len < size) - size = len; - if (size != 0) - size = gs_buf_get(&port->port_write_buf, packet, size); - return size; -} - -/* - * gs_start_tx - * - * This function finds available write requests, calls - * gs_send_packet to fill these packets with data, and - * continues until either there are no more write requests - * available or no more data to send. This function is - * run whenever data arrives or write requests are available. - * - * Context: caller owns port_lock; port_usb is non-null. - */ -static int gs_start_tx(struct gs_port *port) -/* -__releases(&port->port_lock) -__acquires(&port->port_lock) -*/ -{ - struct list_head *pool = &port->write_pool; - struct usb_ep *in = port->port_usb->in; - int status = 0; - bool do_tty_wake = false; - - while (!list_empty(pool)) { - struct usb_request *req; - int len; - - if (port->write_started >= QUEUE_SIZE) - break; - - req = list_entry(pool->next, struct usb_request, list); - len = gs_send_packet(port, req->buf, in->maxpacket); - if (len == 0) { - wake_up_interruptible(&port->drain_wait); - break; - } - do_tty_wake = true; - - req->length = len; - list_del(&req->list); - req->zero = (gs_buf_data_avail(&port->port_write_buf) == 0); - - pr_vdebug(PREFIX "%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n", - port->port_num, len, *((u8 *)req->buf), - *((u8 *)req->buf+1), *((u8 *)req->buf+2)); - - /* Drop lock while we call out of driver; completions - * could be issued while we do so. Disconnection may - * happen too; maybe immediately before we queue this! - * - * NOTE that we may keep sending data for a while after - * the TTY closed (dev->ioport->port_tty is NULL). - */ - spin_unlock(&port->port_lock); - status = usb_ep_queue(in, req, GFP_ATOMIC); - spin_lock(&port->port_lock); - - if (status) { - pr_debug("%s: %s %s err %d\n", - __func__, "queue", in->name, status); - list_add(&req->list, pool); - break; - } - - port->write_started++; - - /* abort immediately after disconnect */ - if (!port->port_usb) - break; - } - - if (do_tty_wake && port->port.tty) - tty_wakeup(port->port.tty); - return status; -} - -/* - * Context: caller owns port_lock, and port_usb is set - */ -static unsigned gs_start_rx(struct gs_port *port) -/* -__releases(&port->port_lock) -__acquires(&port->port_lock) -*/ -{ - struct list_head *pool = &port->read_pool; - struct usb_ep *out = port->port_usb->out; - - while (!list_empty(pool)) { - struct usb_request *req; - int status; - struct tty_struct *tty; - - /* no more rx if closed */ - tty = port->port.tty; - if (!tty) - break; - - if (port->read_started >= QUEUE_SIZE) - break; - - req = list_entry(pool->next, struct usb_request, list); - list_del(&req->list); - req->length = out->maxpacket; - - /* drop lock while we call out; the controller driver - * may need to call us back (e.g. for disconnect) - */ - spin_unlock(&port->port_lock); - status = usb_ep_queue(out, req, GFP_ATOMIC); - spin_lock(&port->port_lock); - - if (status) { - pr_debug("%s: %s %s err %d\n", - __func__, "queue", out->name, status); - list_add(&req->list, pool); - break; - } - port->read_started++; - - /* abort immediately after disconnect */ - if (!port->port_usb) - break; - } - return port->read_started; -} - -/* - * RX tasklet takes data out of the RX queue and hands it up to the TTY - * layer until it refuses to take any more data (or is throttled back). - * Then it issues reads for any further data. - * - * If the RX queue becomes full enough that no usb_request is queued, - * the OUT endpoint may begin NAKing as soon as its FIFO fills up. - * So QUEUE_SIZE packets plus however many the FIFO holds (usually two) - * can be buffered before the TTY layer's buffers (currently 64 KB). - */ -static void gs_rx_push(unsigned long _port) -{ - struct gs_port *port = (void *)_port; - struct tty_struct *tty; - struct list_head *queue = &port->read_queue; - bool disconnect = false; - bool do_push = false; - - /* hand any queued data to the tty */ - spin_lock_irq(&port->port_lock); - tty = port->port.tty; - while (!list_empty(queue)) { - struct usb_request *req; - - req = list_first_entry(queue, struct usb_request, list); - - /* leave data queued if tty was rx throttled */ - if (tty && test_bit(TTY_THROTTLED, &tty->flags)) - break; - - switch (req->status) { - case -ESHUTDOWN: - disconnect = true; - pr_vdebug(PREFIX "%d: shutdown\n", port->port_num); - break; - - default: - /* presumably a transient fault */ - pr_warning(PREFIX "%d: unexpected RX status %d\n", - port->port_num, req->status); - /* FALLTHROUGH */ - case 0: - /* normal completion */ - break; - } - - /* push data to (open) tty */ - if (req->actual) { - char *packet = req->buf; - unsigned size = req->actual; - unsigned n; - int count; - - /* we may have pushed part of this packet already... */ - n = port->n_read; - if (n) { - packet += n; - size -= n; - } - - count = tty_insert_flip_string(&port->port, packet, size); - if (count) - do_push = true; - if (count != size) { - /* stop pushing; TTY layer can't handle more */ - port->n_read += count; - pr_vdebug(PREFIX "%d: rx block %d/%d\n", - port->port_num, - count, req->actual); - break; - } - port->n_read = 0; - } - list_move(&req->list, &port->read_pool); - port->read_started--; - } - - /* Push from tty to ldisc; without low_latency set this is handled by - * a workqueue, so we won't get callbacks and can hold port_lock - */ - if (do_push) - tty_flip_buffer_push(&port->port); - - - /* We want our data queue to become empty ASAP, keeping data - * in the tty and ldisc (not here). If we couldn't push any - * this time around, there may be trouble unless there's an - * implicit tty_unthrottle() call on its way... - * - * REVISIT we should probably add a timer to keep the tasklet - * from starving ... but it's not clear that case ever happens. - */ - if (!list_empty(queue) && tty) { - if (!test_bit(TTY_THROTTLED, &tty->flags)) { - if (do_push) - tasklet_schedule(&port->push); - else - pr_warning(PREFIX "%d: RX not scheduled?\n", - port->port_num); - } - } - - /* If we're still connected, refill the USB RX queue. */ - if (!disconnect && port->port_usb) - gs_start_rx(port); - - spin_unlock_irq(&port->port_lock); -} - -static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct gs_port *port = ep->driver_data; - - /* Queue all received data until the tty layer is ready for it. */ - spin_lock(&port->port_lock); - list_add_tail(&req->list, &port->read_queue); - tasklet_schedule(&port->push); - spin_unlock(&port->port_lock); -} - -static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct gs_port *port = ep->driver_data; - - spin_lock(&port->port_lock); - list_add(&req->list, &port->write_pool); - port->write_started--; - - switch (req->status) { - default: - /* presumably a transient fault */ - pr_warning("%s: unexpected %s status %d\n", - __func__, ep->name, req->status); - /* FALL THROUGH */ - case 0: - /* normal completion */ - gs_start_tx(port); - break; - - case -ESHUTDOWN: - /* disconnect */ - pr_vdebug("%s: %s shutdown\n", __func__, ep->name); - break; - } - - spin_unlock(&port->port_lock); -} - -static void gs_free_requests(struct usb_ep *ep, struct list_head *head, - int *allocated) -{ - struct usb_request *req; - - while (!list_empty(head)) { - req = list_entry(head->next, struct usb_request, list); - list_del(&req->list); - gs_free_req(ep, req); - if (allocated) - (*allocated)--; - } -} - -static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head, - void (*fn)(struct usb_ep *, struct usb_request *), - int *allocated) -{ - int i; - struct usb_request *req; - int n = allocated ? QUEUE_SIZE - *allocated : QUEUE_SIZE; - - /* Pre-allocate up to QUEUE_SIZE transfers, but if we can't - * do quite that many this time, don't fail ... we just won't - * be as speedy as we might otherwise be. - */ - for (i = 0; i < n; i++) { - req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC); - if (!req) - return list_empty(head) ? -ENOMEM : 0; - req->complete = fn; - list_add_tail(&req->list, head); - if (allocated) - (*allocated)++; - } - return 0; -} - -/** - * gs_start_io - start USB I/O streams - * @dev: encapsulates endpoints to use - * Context: holding port_lock; port_tty and port_usb are non-null - * - * We only start I/O when something is connected to both sides of - * this port. If nothing is listening on the host side, we may - * be pointlessly filling up our TX buffers and FIFO. - */ -static int gs_start_io(struct gs_port *port) -{ - struct list_head *head = &port->read_pool; - struct usb_ep *ep = port->port_usb->out; - int status; - unsigned started; - - /* Allocate RX and TX I/O buffers. We can't easily do this much - * earlier (with GFP_KERNEL) because the requests are coupled to - * endpoints, as are the packet sizes we'll be using. Different - * configurations may use different endpoints with a given port; - * and high speed vs full speed changes packet sizes too. - */ - status = gs_alloc_requests(ep, head, gs_read_complete, - &port->read_allocated); - if (status) - return status; - - status = gs_alloc_requests(port->port_usb->in, &port->write_pool, - gs_write_complete, &port->write_allocated); - if (status) { - gs_free_requests(ep, head, &port->read_allocated); - return status; - } - - /* queue read requests */ - port->n_read = 0; - started = gs_start_rx(port); - - /* unblock any pending writes into our circular buffer */ - if (started) { - tty_wakeup(port->port.tty); - } else { - gs_free_requests(ep, head, &port->read_allocated); - gs_free_requests(port->port_usb->in, &port->write_pool, - &port->write_allocated); - status = -EIO; - } - - return status; -} - -/*-------------------------------------------------------------------------*/ - -/* TTY Driver */ - -/* - * gs_open sets up the link between a gs_port and its associated TTY. - * That link is broken *only* by TTY close(), and all driver methods - * know that. - */ -static int gs_open(struct tty_struct *tty, struct file *file) -{ - int port_num = tty->index; - struct gs_port *port; - int status; - - do { - mutex_lock(&ports[port_num].lock); - port = ports[port_num].port; - if (!port) - status = -ENODEV; - else { - spin_lock_irq(&port->port_lock); - - /* already open? Great. */ - if (port->port.count) { - status = 0; - port->port.count++; - - /* currently opening/closing? wait ... */ - } else if (port->openclose) { - status = -EBUSY; - - /* ... else we do the work */ - } else { - status = -EAGAIN; - port->openclose = true; - } - spin_unlock_irq(&port->port_lock); - } - mutex_unlock(&ports[port_num].lock); - - switch (status) { - default: - /* fully handled */ - return status; - case -EAGAIN: - /* must do the work */ - break; - case -EBUSY: - /* wait for EAGAIN task to finish */ - msleep(1); - /* REVISIT could have a waitchannel here, if - * concurrent open performance is important - */ - break; - } - } while (status != -EAGAIN); - - /* Do the "real open" */ - spin_lock_irq(&port->port_lock); - - /* allocate circular buffer on first open */ - if (port->port_write_buf.buf_buf == NULL) { - - spin_unlock_irq(&port->port_lock); - status = gs_buf_alloc(&port->port_write_buf, WRITE_BUF_SIZE); - spin_lock_irq(&port->port_lock); - - if (status) { - pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n", - port->port_num, tty, file); - port->openclose = false; - goto exit_unlock_port; - } - } - - /* REVISIT if REMOVED (ports[].port NULL), abort the open - * to let rmmod work faster (but this way isn't wrong). - */ - - /* REVISIT maybe wait for "carrier detect" */ - - tty->driver_data = port; - port->port.tty = tty; - - port->port.count = 1; - port->openclose = false; - - /* if connected, start the I/O stream */ - if (port->port_usb) { - struct gserial *gser = port->port_usb; - - pr_debug("gs_open: start ttyGS%d\n", port->port_num); - gs_start_io(port); - - if (gser->connect) - gser->connect(gser); - } - - pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file); - - status = 0; - -exit_unlock_port: - spin_unlock_irq(&port->port_lock); - return status; -} - -static int gs_writes_finished(struct gs_port *p) -{ - int cond; - - /* return true on disconnect or empty buffer */ - spin_lock_irq(&p->port_lock); - cond = (p->port_usb == NULL) || !gs_buf_data_avail(&p->port_write_buf); - spin_unlock_irq(&p->port_lock); - - return cond; -} - -static void gs_close(struct tty_struct *tty, struct file *file) -{ - struct gs_port *port = tty->driver_data; - struct gserial *gser; - - spin_lock_irq(&port->port_lock); - - if (port->port.count != 1) { - if (port->port.count == 0) - WARN_ON(1); - else - --port->port.count; - goto exit; - } - - pr_debug("gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file); - - /* mark port as closing but in use; we can drop port lock - * and sleep if necessary - */ - port->openclose = true; - port->port.count = 0; - - gser = port->port_usb; - if (gser && gser->disconnect) - gser->disconnect(gser); - - /* wait for circular write buffer to drain, disconnect, or at - * most GS_CLOSE_TIMEOUT seconds; then discard the rest - */ - if (gs_buf_data_avail(&port->port_write_buf) > 0 && gser) { - spin_unlock_irq(&port->port_lock); - wait_event_interruptible_timeout(port->drain_wait, - gs_writes_finished(port), - GS_CLOSE_TIMEOUT * HZ); - spin_lock_irq(&port->port_lock); - gser = port->port_usb; - } - - /* Iff we're disconnected, there can be no I/O in flight so it's - * ok to free the circular buffer; else just scrub it. And don't - * let the push tasklet fire again until we're re-opened. - */ - if (gser == NULL) - gs_buf_free(&port->port_write_buf); - else - gs_buf_clear(&port->port_write_buf); - - tty->driver_data = NULL; - port->port.tty = NULL; - - port->openclose = false; - - pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", - port->port_num, tty, file); - - wake_up_interruptible(&port->port.close_wait); -exit: - spin_unlock_irq(&port->port_lock); -} - -static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - int status; - - pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n", - port->port_num, tty, count); - - spin_lock_irqsave(&port->port_lock, flags); - if (count) - count = gs_buf_put(&port->port_write_buf, buf, count); - /* treat count == 0 as flush_chars() */ - if (port->port_usb) - status = gs_start_tx(port); - spin_unlock_irqrestore(&port->port_lock, flags); - - return count; -} - -static int gs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - int status; - - pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %pf\n", - port->port_num, tty, ch, __builtin_return_address(0)); - - spin_lock_irqsave(&port->port_lock, flags); - status = gs_buf_put(&port->port_write_buf, &ch, 1); - spin_unlock_irqrestore(&port->port_lock, flags); - - return status; -} - -static void gs_flush_chars(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - - pr_vdebug("gs_flush_chars: (%d,%p)\n", port->port_num, tty); - - spin_lock_irqsave(&port->port_lock, flags); - if (port->port_usb) - gs_start_tx(port); - spin_unlock_irqrestore(&port->port_lock, flags); -} - -static int gs_write_room(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - int room = 0; - - spin_lock_irqsave(&port->port_lock, flags); - if (port->port_usb) - room = gs_buf_space_avail(&port->port_write_buf); - spin_unlock_irqrestore(&port->port_lock, flags); - - pr_vdebug("gs_write_room: (%d,%p) room=%d\n", - port->port_num, tty, room); - - return room; -} - -static int gs_chars_in_buffer(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - int chars = 0; - - spin_lock_irqsave(&port->port_lock, flags); - chars = gs_buf_data_avail(&port->port_write_buf); - spin_unlock_irqrestore(&port->port_lock, flags); - - pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%d\n", - port->port_num, tty, chars); - - return chars; -} - -/* undo side effects of setting TTY_THROTTLED */ -static void gs_unthrottle(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&port->port_lock, flags); - if (port->port_usb) { - /* Kickstart read queue processing. We don't do xon/xoff, - * rts/cts, or other handshaking with the host, but if the - * read queue backs up enough we'll be NAKing OUT packets. - */ - tasklet_schedule(&port->push); - pr_vdebug(PREFIX "%d: unthrottle\n", port->port_num); - } - spin_unlock_irqrestore(&port->port_lock, flags); -} - -static int gs_break_ctl(struct tty_struct *tty, int duration) -{ - struct gs_port *port = tty->driver_data; - int status = 0; - struct gserial *gser; - - pr_vdebug("gs_break_ctl: ttyGS%d, send break (%d) \n", - port->port_num, duration); - - spin_lock_irq(&port->port_lock); - gser = port->port_usb; - if (gser && gser->send_break) - status = gser->send_break(gser, duration); - spin_unlock_irq(&port->port_lock); - - return status; -} - -static const struct tty_operations gs_tty_ops = { - .open = gs_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, - .unthrottle = gs_unthrottle, - .break_ctl = gs_break_ctl, -}; - -/*-------------------------------------------------------------------------*/ - -static struct tty_driver *gs_tty_driver; - -static int -gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) -{ - struct gs_port *port; - - port = kzalloc(sizeof(struct gs_port), GFP_KERNEL); - if (port == NULL) - return -ENOMEM; - - tty_port_init(&port->port); - spin_lock_init(&port->port_lock); - init_waitqueue_head(&port->drain_wait); - - tasklet_init(&port->push, gs_rx_push, (unsigned long) port); - - INIT_LIST_HEAD(&port->read_pool); - INIT_LIST_HEAD(&port->read_queue); - INIT_LIST_HEAD(&port->write_pool); - - port->port_num = port_num; - port->port_line_coding = *coding; - - ports[port_num].port = port; - - return 0; -} - -/** - * gserial_setup - initialize TTY driver for one or more ports - * @g: gadget to associate with these ports - * @count: how many ports to support - * Context: may sleep - * - * The TTY stack needs to know in advance how many devices it should - * plan to manage. Use this call to set up the ports you will be - * exporting through USB. Later, connect them to functions based - * on what configuration is activated by the USB host; and disconnect - * them as appropriate. - * - * An example would be a two-configuration device in which both - * configurations expose port 0, but through different functions. - * One configuration could even expose port 1 while the other - * one doesn't. - * - * Returns negative errno or zero. - */ -int gserial_setup(struct usb_gadget *g, unsigned count) -{ - unsigned i; - struct usb_cdc_line_coding coding; - int status; - - if (count == 0 || count > N_PORTS) - return -EINVAL; - - gs_tty_driver = alloc_tty_driver(count); - if (!gs_tty_driver) - return -ENOMEM; - - gs_tty_driver->driver_name = "g_serial"; - gs_tty_driver->name = PREFIX; - /* uses dynamically assigned dev_t values */ - - gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; - gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - gs_tty_driver->init_termios = tty_std_termios; - - /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on - * MS-Windows. Otherwise, most of these flags shouldn't affect - * anything unless we were to actually hook up to a serial line. - */ - gs_tty_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - gs_tty_driver->init_termios.c_ispeed = 9600; - gs_tty_driver->init_termios.c_ospeed = 9600; - - coding.dwDTERate = cpu_to_le32(9600); - coding.bCharFormat = 8; - coding.bParityType = USB_CDC_NO_PARITY; - coding.bDataBits = USB_CDC_1_STOP_BITS; - - tty_set_operations(gs_tty_driver, &gs_tty_ops); - - /* make devices be openable */ - for (i = 0; i < count; i++) { - mutex_init(&ports[i].lock); - status = gs_port_alloc(i, &coding); - if (status) { - count = i; - goto fail; - } - } - n_ports = count; - - /* export the driver ... */ - status = tty_register_driver(gs_tty_driver); - if (status) { - pr_err("%s: cannot register, err %d\n", - __func__, status); - goto fail; - } - - /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ - for (i = 0; i < count; i++) { - struct device *tty_dev; - - tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); - if (IS_ERR(tty_dev)) - pr_warning("%s: no classdev for port %d, err %ld\n", - __func__, i, PTR_ERR(tty_dev)); - } - - pr_debug("%s: registered %d ttyGS* device%s\n", __func__, - count, (count == 1) ? "" : "s"); - - return status; -fail: - while (count--) { - tty_port_destroy(&ports[count].port->port); - kfree(ports[count].port); - } - put_tty_driver(gs_tty_driver); - gs_tty_driver = NULL; - return status; -} - -static int gs_closed(struct gs_port *port) -{ - int cond; - - spin_lock_irq(&port->port_lock); - cond = (port->port.count == 0) && !port->openclose; - spin_unlock_irq(&port->port_lock); - return cond; -} - -/** - * gserial_cleanup - remove TTY-over-USB driver and devices - * Context: may sleep - * - * This is called to free all resources allocated by @gserial_setup(). - * Accordingly, it may need to wait until some open /dev/ files have - * closed. - * - * The caller must have issued @gserial_disconnect() for any ports - * that had previously been connected, so that there is never any - * I/O pending when it's called. - */ -void gserial_cleanup(void) -{ - unsigned i; - struct gs_port *port; - - if (!gs_tty_driver) - return; - - /* start sysfs and /dev/ttyGS* node removal */ - for (i = 0; i < n_ports; i++) - tty_unregister_device(gs_tty_driver, i); - - for (i = 0; i < n_ports; i++) { - /* prevent new opens */ - mutex_lock(&ports[i].lock); - port = ports[i].port; - ports[i].port = NULL; - mutex_unlock(&ports[i].lock); - - tasklet_kill(&port->push); - - /* wait for old opens to finish */ - wait_event(port->port.close_wait, gs_closed(port)); - - WARN_ON(port->port_usb != NULL); - - tty_port_destroy(&port->port); - kfree(port); - } - n_ports = 0; - - tty_unregister_driver(gs_tty_driver); - put_tty_driver(gs_tty_driver); - gs_tty_driver = NULL; - - pr_debug("%s: cleaned up ttyGS* support\n", __func__); -} - -/** - * gserial_connect - notify TTY I/O glue that USB link is active - * @gser: the function, set up with endpoints and descriptors - * @port_num: which port is active - * Context: any (usually from irq) - * - * This is called activate endpoints and let the TTY layer know that - * the connection is active ... not unlike "carrier detect". It won't - * necessarily start I/O queues; unless the TTY is held open by any - * task, there would be no point. However, the endpoints will be - * activated so the USB host can perform I/O, subject to basic USB - * hardware flow control. - * - * Caller needs to have set up the endpoints and USB function in @dev - * before calling this, as well as the appropriate (speed-specific) - * endpoint descriptors, and also have set up the TTY driver by calling - * @gserial_setup(). - * - * Returns negative errno or zero. - * On success, ep->driver_data will be overwritten. - */ -int gserial_connect(struct gserial *gser, u8 port_num) -{ - struct gs_port *port; - unsigned long flags; - int status; - - if (!gs_tty_driver || port_num >= n_ports) - return -ENXIO; - - /* we "know" gserial_cleanup() hasn't been called */ - port = ports[port_num].port; - - /* activate the endpoints */ - status = usb_ep_enable(gser->in); - if (status < 0) - return status; - gser->in->driver_data = port; - - status = usb_ep_enable(gser->out); - if (status < 0) - goto fail_out; - gser->out->driver_data = port; - - /* then tell the tty glue that I/O can work */ - spin_lock_irqsave(&port->port_lock, flags); - gser->ioport = port; - port->port_usb = gser; - - /* REVISIT unclear how best to handle this state... - * we don't really couple it with the Linux TTY. - */ - gser->port_line_coding = port->port_line_coding; - - /* REVISIT if waiting on "carrier detect", signal. */ - - /* if it's already open, start I/O ... and notify the serial - * protocol about open/close status (connect/disconnect). - */ - if (port->port.count) { - pr_debug("gserial_connect: start ttyGS%d\n", port->port_num); - gs_start_io(port); - if (gser->connect) - gser->connect(gser); - } else { - if (gser->disconnect) - gser->disconnect(gser); - } - - spin_unlock_irqrestore(&port->port_lock, flags); - - return status; - -fail_out: - usb_ep_disable(gser->in); - gser->in->driver_data = NULL; - return status; -} - -/** - * gserial_disconnect - notify TTY I/O glue that USB link is inactive - * @gser: the function, on which gserial_connect() was called - * Context: any (usually from irq) - * - * This is called to deactivate endpoints and let the TTY layer know - * that the connection went inactive ... not unlike "hangup". - * - * On return, the state is as if gserial_connect() had never been called; - * there is no active USB I/O on these endpoints. - */ -void gserial_disconnect(struct gserial *gser) -{ - struct gs_port *port = gser->ioport; - unsigned long flags; - - if (!port) - return; - - /* tell the TTY glue not to do I/O here any more */ - spin_lock_irqsave(&port->port_lock, flags); - - /* REVISIT as above: how best to track this? */ - port->port_line_coding = gser->port_line_coding; - - port->port_usb = NULL; - gser->ioport = NULL; - if (port->port.count > 0 || port->openclose) { - wake_up_interruptible(&port->drain_wait); - if (port->port.tty) - tty_hangup(port->port.tty); - } - spin_unlock_irqrestore(&port->port_lock, flags); - - /* disable endpoints, aborting down any active I/O */ - usb_ep_disable(gser->out); - gser->out->driver_data = NULL; - - usb_ep_disable(gser->in); - gser->in->driver_data = NULL; - - /* finally, free any unused/unusable I/O buffers */ - spin_lock_irqsave(&port->port_lock, flags); - if (port->port.count == 0 && !port->openclose) - gs_buf_free(&port->port_write_buf); - gs_free_requests(gser->out, &port->read_pool, NULL); - gs_free_requests(gser->out, &port->read_queue, NULL); - gs_free_requests(gser->in, &port->write_pool, NULL); - - port->read_allocated = port->read_started = - port->write_allocated = port->write_started = 0; - - spin_unlock_irqrestore(&port->port_lock, flags); -} diff --git a/drivers/staging/ccg/u_serial.h b/drivers/staging/ccg/u_serial.h deleted file mode 100644 index 9b0fe6450fbf..000000000000 --- a/drivers/staging/ccg/u_serial.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * u_serial.h - interface to USB gadget "serial port"/TTY utilities - * - * Copyright (C) 2008 David Brownell - * Copyright (C) 2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. - */ - -#ifndef __U_SERIAL_H -#define __U_SERIAL_H - -#include -#include - -/* - * One non-multiplexed "serial" I/O port ... there can be several of these - * on any given USB peripheral device, if it provides enough endpoints. - * - * The "u_serial" utility component exists to do one thing: manage TTY - * style I/O using the USB peripheral endpoints listed here, including - * hookups to sysfs and /dev for each logical "tty" device. - * - * REVISIT at least ACM could support tiocmget() if needed. - * - * REVISIT someday, allow multiplexing several TTYs over these endpoints. - */ -struct gserial { - struct usb_function func; - - /* port is managed by gserial_{connect,disconnect} */ - struct gs_port *ioport; - - struct usb_ep *in; - struct usb_ep *out; - - /* REVISIT avoid this CDC-ACM support harder ... */ - struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */ - - /* notification callbacks */ - void (*connect)(struct gserial *p); - void (*disconnect)(struct gserial *p); - int (*send_break)(struct gserial *p, int duration); -}; - -/* utilities to allocate/free request and buffer */ -struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags); -void gs_free_req(struct usb_ep *, struct usb_request *req); - -/* port setup/teardown is handled by gadget driver */ -int gserial_setup(struct usb_gadget *g, unsigned n_ports); -void gserial_cleanup(void); - -/* connect/disconnect is handled by individual functions */ -int gserial_connect(struct gserial *, u8 port_num); -void gserial_disconnect(struct gserial *); - -/* functions are bound to configurations by a config or gadget driver */ -int acm_bind_config(struct usb_configuration *c, u8 port_num); -int gser_bind_config(struct usb_configuration *c, u8 port_num); -int obex_bind_config(struct usb_configuration *c, u8 port_num); - -#endif /* __U_SERIAL_H */ diff --git a/drivers/staging/ccg/usbstring.c b/drivers/staging/ccg/usbstring.c deleted file mode 100644 index 4d25b9009edf..000000000000 --- a/drivers/staging/ccg/usbstring.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2003 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -/** - * usb_gadget_get_string - fill out a string descriptor - * @table: of c strings encoded using UTF-8 - * @id: string id, from low byte of wValue in get string descriptor - * @buf: at least 256 bytes, must be 16-bit aligned - * - * Finds the UTF-8 string matching the ID, and converts it into a - * string descriptor in utf16-le. - * Returns length of descriptor (always even) or negative errno - * - * If your driver needs stings in multiple languages, you'll probably - * "switch (wIndex) { ... }" in your ep0 string descriptor logic, - * using this routine after choosing which set of UTF-8 strings to use. - * Note that US-ASCII is a strict subset of UTF-8; any string bytes with - * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 - * characters (which are also widely used in C strings). - */ -int -usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) -{ - struct usb_string *s; - int len; - - /* descriptor 0 has the language id */ - if (id == 0) { - buf [0] = 4; - buf [1] = USB_DT_STRING; - buf [2] = (u8) table->language; - buf [3] = (u8) (table->language >> 8); - return 4; - } - for (s = table->strings; s && s->s; s++) - if (s->id == id) - break; - - /* unrecognized: stall. */ - if (!s || !s->s) - return -EINVAL; - - /* string descriptors have length, tag, then UTF16-LE text */ - len = min ((size_t) 126, strlen (s->s)); - len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, - (wchar_t *) &buf[2], 126); - if (len < 0) - return -EINVAL; - buf [0] = (len + 1) * 2; - buf [1] = USB_DT_STRING; - return buf [0]; -} - -- cgit From b92021b09df70c1609e3547f3d6128dd560be97f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 15 Mar 2013 15:04:17 +1030 Subject: CONFIG_SYMBOL_PREFIX: cleanup. We have CONFIG_SYMBOL_PREFIX, which three archs define to the string "_". But Al Viro broke this in "consolidate cond_syscall and SYSCALL_ALIAS declarations" (in linux-next), and he's not the first to do so. Using CONFIG_SYMBOL_PREFIX is awkward, since we usually just want to prefix it so something. So various places define helpers which are defined to nothing if CONFIG_SYMBOL_PREFIX isn't set: 1) include/asm-generic/unistd.h defines __SYMBOL_PREFIX. 2) include/asm-generic/vmlinux.lds.h defines VMLINUX_SYMBOL(sym) 3) include/linux/export.h defines MODULE_SYMBOL_PREFIX. 4) include/linux/kernel.h defines SYMBOL_PREFIX (which differs from #7) 5) kernel/modsign_certificate.S defines ASM_SYMBOL(sym) 6) scripts/modpost.c defines MODULE_SYMBOL_PREFIX 7) scripts/Makefile.lib defines SYMBOL_PREFIX on the commandline if CONFIG_SYMBOL_PREFIX is set, so that we have a non-string version for pasting. (arch/h8300/include/asm/linkage.h defines SYMBOL_NAME(), too). Let's solve this properly: 1) No more generic prefix, just CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX. 2) Make linux/export.h usable from asm. 3) Define VMLINUX_SYMBOL() and VMLINUX_SYMBOL_STR(). 4) Make everyone use them. Signed-off-by: Rusty Russell Reviewed-by: James Hogan Tested-by: James Hogan (metag) --- Makefile | 2 +- arch/Kconfig | 6 ++++++ arch/blackfin/Kconfig | 5 +---- arch/h8300/Kconfig | 5 +---- arch/metag/Kconfig | 5 +---- drivers/mtd/chips/gen_probe.c | 8 +++++--- include/asm-generic/unistd.h | 12 ++++-------- include/asm-generic/vmlinux.lds.h | 8 +------- include/linux/export.h | 20 ++++++++++++++------ include/linux/kernel.h | 7 ------- include/linux/module.h | 4 ++-- kernel/modsign_certificate.S | 13 +++---------- kernel/module.c | 2 +- scripts/Makefile.lib | 7 ------- scripts/link-vmlinux.sh | 5 ++--- scripts/mod/modpost.c | 36 +++++++++++++++--------------------- 16 files changed, 57 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/Makefile b/Makefile index a05ea42c5f18..0b09ba5e492a 100644 --- a/Makefile +++ b/Makefile @@ -1398,7 +1398,7 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)) # Run depmod only if we have System.map and depmod is executable quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ - $(KERNELRELEASE) "$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))" + $(KERNELRELEASE) "$(patsubst y,_,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))" # Create temporary dir for module support files # clean it up only when building all modules diff --git a/arch/Kconfig b/arch/Kconfig index 1455579791ec..7b433a4bcc28 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -384,6 +384,12 @@ config MODULES_USE_ELF_REL Modules only use ELF REL relocations. Modules with ELF RELA relocations will give an error. +config HAVE_UNDERSCORE_SYMBOL_PREFIX + bool + help + Some architectures generate an _ in front of C symbols; things like + module loading and assembly files need to know about this. + # # ABI hall of shame # diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c3f2e0bc644a..453ebe46b065 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1,7 +1,3 @@ -config SYMBOL_PREFIX - string - default "_" - config MMU def_bool n @@ -33,6 +29,7 @@ config BLACKFIN select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_UID16 + select HAVE_UNDERSCORE_SYMBOL_PREFIX select VIRT_TO_BUS select ARCH_WANT_IPC_PARSE_VERSION select HAVE_GENERIC_HARDIRQS diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 79250de1b12a..303e4f9a79d1 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -12,10 +12,7 @@ config H8300 select MODULES_USE_ELF_RELA select OLD_SIGSUSPEND3 select OLD_SIGACTION - -config SYMBOL_PREFIX - string - default "_" + select HAVE_UNDERSCORE_SYMBOL_PREFIX config MMU bool diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig index afc8973d1488..2099617e3ec0 100644 --- a/arch/metag/Kconfig +++ b/arch/metag/Kconfig @@ -1,7 +1,3 @@ -config SYMBOL_PREFIX - string - default "_" - config METAG def_bool y select EMBEDDED @@ -27,6 +23,7 @@ config METAG select HAVE_MOD_ARCH_SPECIFIC select HAVE_PERF_EVENTS select HAVE_SYSCALL_TRACEPOINTS + select HAVE_UNDERSCORE_SYMBOL_PREFIX select IRQ_DOMAIN select MODULES_USE_ELF_RELA select OF diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index 3b9a2843c5f8..74dbb6bcf488 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c @@ -204,14 +204,16 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, struct cfi_private *cfi = map->fldrv_priv; __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; #ifdef CONFIG_MODULES - char probename[16+sizeof(MODULE_SYMBOL_PREFIX)]; + char probename[sizeof(VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X))]; cfi_cmdset_fn_t *probe_function; - sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type); + sprintf(probename, VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X), type); probe_function = __symbol_get(probename); if (!probe_function) { - request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1); + char modname[sizeof("cfi_cmdset_%4.4X")]; + sprintf(modname, "cfi_cmdset_%4.4X", type); + request_module(modname); probe_function = __symbol_get(probename); } diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index 4077b5d9ff81..15c0598e1109 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h @@ -1,4 +1,5 @@ #include +#include /* * These are required system calls, we should @@ -17,12 +18,7 @@ * but it doesn't work on all toolchains, so we just do it by hand */ #ifndef cond_syscall -#ifdef CONFIG_SYMBOL_PREFIX -#define __SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define __SYMBOL_PREFIX -#endif -#define cond_syscall(x) asm(".weak\t" __SYMBOL_PREFIX #x "\n\t" \ - ".set\t" __SYMBOL_PREFIX #x "," \ - __SYMBOL_PREFIX "sys_ni_syscall") +#define cond_syscall(x) asm(".weak\t" VMLINUX_SYMBOL_STR(x) "\n\t" \ + ".set\t" VMLINUX_SYMBOL_STR(x) "," \ + VMLINUX_SYMBOL_STR(sys_ni_syscall)) #endif diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index afa12c7a025c..eb58d2d7d971 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -52,13 +52,7 @@ #define LOAD_OFFSET 0 #endif -#ifndef SYMBOL_PREFIX -#define VMLINUX_SYMBOL(sym) sym -#else -#define PASTE2(x,y) x##y -#define PASTE(x,y) PASTE2(x,y) -#define VMLINUX_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) -#endif +#include /* Align . to a 8 byte boundary equals to maximum function alignment. */ #define ALIGN_FUNCTION() . = ALIGN(8) diff --git a/include/linux/export.h b/include/linux/export.h index 696c0f48afc7..412cd509effe 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -5,17 +5,24 @@ * to reduce the amount of pointless cruft we feed to gcc when only * exporting a simple symbol or two. * - * If you feel the need to add #include to this file - * then you are doing something wrong and should go away silently. + * Try not to add #includes here. It slows compilation and makes kernel + * hackers place grumpy comments in header files. */ /* Some toolchains use a `_' prefix for all user symbols. */ -#ifdef CONFIG_SYMBOL_PREFIX -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX +#define __VMLINUX_SYMBOL(x) _##x +#define __VMLINUX_SYMBOL_STR(x) "_" #x #else -#define MODULE_SYMBOL_PREFIX "" +#define __VMLINUX_SYMBOL(x) x +#define __VMLINUX_SYMBOL_STR(x) #x #endif +/* Indirect, so macros are expanded before pasting. */ +#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x) +#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) + +#ifndef __ASSEMBLY__ struct kernel_symbol { unsigned long value; @@ -51,7 +58,7 @@ extern struct module __this_module; __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"), aligned(1))) \ - = MODULE_SYMBOL_PREFIX #sym; \ + = VMLINUX_SYMBOL_STR(sym); \ static const struct kernel_symbol __ksymtab_##sym \ __used \ __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ @@ -85,5 +92,6 @@ extern struct module __this_module; #define EXPORT_UNUSED_SYMBOL_GPL(sym) #endif /* CONFIG_MODULES */ +#endif /* !__ASSEMBLY__ */ #endif /* _LINUX_EXPORT_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 80d36874689b..e13e992eae8a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -723,13 +723,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } /* Trap pasters of __FUNCTION__ at compile-time */ #define __FUNCTION__ (__func__) -/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */ -#ifdef CONFIG_SYMBOL_PREFIX -#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define SYMBOL_PREFIX "" -#endif - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD diff --git a/include/linux/module.h b/include/linux/module.h index ead1b5719a12..46f1ea01e6f6 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -190,7 +190,7 @@ extern int modules_disabled; /* for sysctl */ /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); -#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x)))) /* modules using other modules: kdb wants to see this. */ struct module_use { @@ -453,7 +453,7 @@ extern void __module_put_and_exit(struct module *mod, long code) #ifdef CONFIG_MODULE_UNLOAD unsigned long module_refcount(struct module *mod); void __symbol_put(const char *symbol); -#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) +#define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x)) void symbol_put_addr(void *addr); /* Sometimes we know we already have a refcount, and it's easier not diff --git a/kernel/modsign_certificate.S b/kernel/modsign_certificate.S index 246b4c6e6135..4a9a86d12c8b 100644 --- a/kernel/modsign_certificate.S +++ b/kernel/modsign_certificate.S @@ -1,15 +1,8 @@ -/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */ -#ifndef SYMBOL_PREFIX -#define ASM_SYMBOL(sym) sym -#else -#define PASTE2(x,y) x##y -#define PASTE(x,y) PASTE2(x,y) -#define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) -#endif +#include #define GLOBAL(name) \ - .globl ASM_SYMBOL(name); \ - ASM_SYMBOL(name): + .globl VMLINUX_SYMBOL(name); \ + VMLINUX_SYMBOL(name): .section ".init.data","aw" diff --git a/kernel/module.c b/kernel/module.c index 0925c9a71975..cfd4a3f68d7d 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1209,7 +1209,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, /* Since this should be found in kernel (which can't be removed), * no locking is necessary. */ - if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, + if (!find_symbol(VMLINUX_SYMBOL_STR(module_layout), NULL, &crc, true, false)) BUG(); return check_version(sechdrs, versindex, "module_layout", mod, crc, diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 07125e697d7a..a373a1f66023 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -119,13 +119,6 @@ _c_flags += $(if $(patsubst n%,, \ $(CFLAGS_GCOV)) endif -ifdef CONFIG_SYMBOL_PREFIX -_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) -_cpp_flags += $(_sym_flags) -_a_flags += $(_sym_flags) -endif - - # If building the kernel in a separate objtree expand all occurrences # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 3d569d6022c2..014994936b1c 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -74,9 +74,8 @@ kallsyms() info KSYM ${2} local kallsymopt; - if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then - kallsymopt="${kallsymopt} \ - --symbol-prefix=${CONFIG_SYMBOL_PREFIX}" + if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then + kallsymopt="${kallsymopt} --symbol-prefix=_" fi if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 78b30c1548e9..282decfa29ae 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -18,14 +18,7 @@ #include "modpost.h" #include "../../include/generated/autoconf.h" #include "../../include/linux/license.h" - -/* Some toolchains use a `_' prefix for all user symbols. */ -#ifdef CONFIG_SYMBOL_PREFIX -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define MODULE_SYMBOL_PREFIX "" -#endif - +#include "../../include/linux/export.h" /* Are we using CONFIG_MODVERSIONS? */ int modversions = 0; @@ -562,7 +555,7 @@ static void parse_elf_finish(struct elf_info *info) static int ignore_undef_symbol(struct elf_info *info, const char *symname) { /* ignore __this_module, it will be resolved shortly */ - if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0) return 1; /* ignore global offset table */ if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) @@ -583,8 +576,8 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) return 0; } -#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" -#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" +#define CRC_PFX VMLINUX_SYMBOL_STR(__crc_) +#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_) static void handle_modversions(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname) @@ -637,14 +630,15 @@ static void handle_modversions(struct module *mod, struct elf_info *info, } #endif - if (memcmp(symname, MODULE_SYMBOL_PREFIX, - strlen(MODULE_SYMBOL_PREFIX)) == 0) { - mod->unres = - alloc_symbol(symname + - strlen(MODULE_SYMBOL_PREFIX), - ELF_ST_BIND(sym->st_info) == STB_WEAK, - mod->unres); - } +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX + if (symname[0] != '_') + break; + else + symname++; +#endif + mod->unres = alloc_symbol(symname, + ELF_ST_BIND(sym->st_info) == STB_WEAK, + mod->unres); break; default: /* All exported symbols */ @@ -652,9 +646,9 @@ static void handle_modversions(struct module *mod, struct elf_info *info, sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, export); } - if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0) mod->has_init = 1; - if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0) mod->has_cleanup = 1; break; } -- cgit From 8a7fbfab4be39b8690543f3d29b26860d2f6c576 Mon Sep 17 00:00:00 2001 From: "nikolay@redhat.com" Date: Tue, 12 Mar 2013 02:49:01 +0000 Subject: netxen: write IP address to firmware when using bonding This patch allows LRO aggregation on bonded devices that contain an NX3031 device. It also adds a for_each_netdev_in_bond_rcu(bond, slave) macro which executes for each slave that has bond as master. V3: After testing and discussing this with Rajesh, I decided to keep the vlan ip cache and just rename it to ip_cache since it will store bond ip addresses too. A new master flag has been added to the ip cache to denote that the address has been added because of a master device. I've taken care of the enslave/release cases by checking for various combinations of events and flags (e.g. netxen has a master, it's a bond master and it's not marked as a slave means it is being enslaved and is dev_open()ed in bond_enslave). I've changed netxen_free_ip_list() to have a "master" parameter which causes all IP addresses marked as master to be deleted (used when a netxen is being released). I've made the patch use the new upper device API as well. The following cases were tested: - bond -> netxen - vlan -> netxen - vlan -> bond -> netxen V2: Remove local ip caching, retrieve addresses dynamically and restore them if necessary. Note: Tested with NX3031 adapter. Tested-by: Rajesh Borundia Signed-off-by: Andy Gospodarek Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 5 +- .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 220 ++++++++++++++------- include/linux/netdevice.h | 8 + 3 files changed, 155 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index eb3dfdbb642b..322a36b76727 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -955,9 +955,10 @@ typedef struct nx_mac_list_s { uint8_t mac_addr[ETH_ALEN+2]; } nx_mac_list_t; -struct nx_vlan_ip_list { +struct nx_ip_list { struct list_head list; __be32 ip_addr; + bool master; }; /* @@ -1605,7 +1606,7 @@ struct netxen_adapter { struct net_device *netdev; struct pci_dev *pdev; struct list_head mac_list; - struct list_head vlan_ip_list; + struct list_head ip_list; spinlock_t tx_clean_lock; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 501f49207da5..7867aebc05f2 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -90,7 +90,7 @@ static irqreturn_t netxen_intr(int irq, void *data); static irqreturn_t netxen_msi_intr(int irq, void *data); static irqreturn_t netxen_msix_intr(int irq, void *data); -static void netxen_free_vlan_ip_list(struct netxen_adapter *); +static void netxen_free_ip_list(struct netxen_adapter *, bool); static void netxen_restore_indev_addr(struct net_device *dev, unsigned long); static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats); @@ -1450,7 +1450,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&adapter->tx_clean_lock); INIT_LIST_HEAD(&adapter->mac_list); - INIT_LIST_HEAD(&adapter->vlan_ip_list); + INIT_LIST_HEAD(&adapter->ip_list); err = netxen_setup_pci_map(adapter); if (err) @@ -1585,7 +1585,7 @@ static void netxen_nic_remove(struct pci_dev *pdev) cancel_work_sync(&adapter->tx_timeout_task); - netxen_free_vlan_ip_list(adapter); + netxen_free_ip_list(adapter, false); netxen_nic_detach(adapter); nx_decr_dev_ref_cnt(adapter); @@ -3137,62 +3137,77 @@ netxen_destip_supported(struct netxen_adapter *adapter) } static void -netxen_free_vlan_ip_list(struct netxen_adapter *adapter) +netxen_free_ip_list(struct netxen_adapter *adapter, bool master) { - struct nx_vlan_ip_list *cur; - struct list_head *head = &adapter->vlan_ip_list; + struct nx_ip_list *cur, *tmp_cur; - while (!list_empty(head)) { - cur = list_entry(head->next, struct nx_vlan_ip_list, list); - netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN); - list_del(&cur->list); - kfree(cur); + list_for_each_entry_safe(cur, tmp_cur, &adapter->ip_list, list) { + if (master) { + if (cur->master) { + netxen_config_ipaddr(adapter, cur->ip_addr, + NX_IP_DOWN); + list_del(&cur->list); + kfree(cur); + } + } else { + netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN); + list_del(&cur->list); + kfree(cur); + } } - } -static void -netxen_list_config_vlan_ip(struct netxen_adapter *adapter, + +static bool +netxen_list_config_ip(struct netxen_adapter *adapter, struct in_ifaddr *ifa, unsigned long event) { struct net_device *dev; - struct nx_vlan_ip_list *cur, *tmp_cur; + struct nx_ip_list *cur, *tmp_cur; struct list_head *head; + bool ret = false; dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; if (dev == NULL) - return; - - if (!is_vlan_dev(dev)) - return; + goto out; switch (event) { case NX_IP_UP: - list_for_each(head, &adapter->vlan_ip_list) { - cur = list_entry(head, struct nx_vlan_ip_list, list); + list_for_each(head, &adapter->ip_list) { + cur = list_entry(head, struct nx_ip_list, list); if (cur->ip_addr == ifa->ifa_address) - return; + goto out; } - cur = kzalloc(sizeof(struct nx_vlan_ip_list), GFP_ATOMIC); + cur = kzalloc(sizeof(struct nx_ip_list), GFP_ATOMIC); if (cur == NULL) - return; - + goto out; + if (dev->priv_flags & IFF_802_1Q_VLAN) + dev = vlan_dev_real_dev(dev); + cur->master = !!netif_is_bond_master(dev); cur->ip_addr = ifa->ifa_address; - list_add_tail(&cur->list, &adapter->vlan_ip_list); + list_add_tail(&cur->list, &adapter->ip_list); + netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP); + ret = true; break; case NX_IP_DOWN: list_for_each_entry_safe(cur, tmp_cur, - &adapter->vlan_ip_list, list) { + &adapter->ip_list, list) { if (cur->ip_addr == ifa->ifa_address) { list_del(&cur->list); kfree(cur); + netxen_config_ipaddr(adapter, ifa->ifa_address, + NX_IP_DOWN); + ret = true; break; } } } +out: + return ret; } + static void netxen_config_indev_addr(struct netxen_adapter *adapter, struct net_device *dev, unsigned long event) @@ -3209,14 +3224,10 @@ netxen_config_indev_addr(struct netxen_adapter *adapter, for_ifa(indev) { switch (event) { case NETDEV_UP: - netxen_config_ipaddr(adapter, - ifa->ifa_address, NX_IP_UP); - netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP); + netxen_list_config_ip(adapter, ifa, NX_IP_UP); break; case NETDEV_DOWN: - netxen_config_ipaddr(adapter, - ifa->ifa_address, NX_IP_DOWN); - netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN); + netxen_list_config_ip(adapter, ifa, NX_IP_DOWN); break; default: break; @@ -3231,23 +3242,78 @@ netxen_restore_indev_addr(struct net_device *netdev, unsigned long event) { struct netxen_adapter *adapter = netdev_priv(netdev); - struct nx_vlan_ip_list *pos, *tmp_pos; + struct nx_ip_list *pos, *tmp_pos; unsigned long ip_event; ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN; netxen_config_indev_addr(adapter, netdev, event); - list_for_each_entry_safe(pos, tmp_pos, &adapter->vlan_ip_list, list) { + list_for_each_entry_safe(pos, tmp_pos, &adapter->ip_list, list) { netxen_config_ipaddr(adapter, pos->ip_addr, ip_event); } } +static inline bool +netxen_config_checkdev(struct net_device *dev) +{ + struct netxen_adapter *adapter; + + if (!is_netxen_netdev(dev)) + return false; + adapter = netdev_priv(dev); + if (!adapter) + return false; + if (!netxen_destip_supported(adapter)) + return false; + if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) + return false; + + return true; +} + +/** + * netxen_config_master - configure addresses based on master + * @dev: netxen device + * @event: netdev event + */ +static void netxen_config_master(struct net_device *dev, unsigned long event) +{ + struct net_device *master, *slave; + struct netxen_adapter *adapter = netdev_priv(dev); + + rcu_read_lock(); + master = netdev_master_upper_dev_get_rcu(dev); + /* + * This is the case where the netxen nic is being + * enslaved and is dev_open()ed in bond_enslave() + * Now we should program the bond's (and its vlans') + * addresses in the netxen NIC. + */ + if (master && netif_is_bond_master(master) && + !netif_is_bond_slave(dev)) { + netxen_config_indev_addr(adapter, master, event); + for_each_netdev_rcu(&init_net, slave) + if (slave->priv_flags & IFF_802_1Q_VLAN && + vlan_dev_real_dev(slave) == master) + netxen_config_indev_addr(adapter, slave, event); + } + rcu_read_unlock(); + /* + * This is the case where the netxen nic is being + * released and is dev_close()ed in bond_release() + * just before IFF_BONDING is stripped. + */ + if (!master && dev->priv_flags & IFF_BONDING) + netxen_free_ip_list(adapter, true); +} + static int netxen_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct netxen_adapter *adapter; struct net_device *dev = (struct net_device *)ptr; struct net_device *orig_dev = dev; + struct net_device *slave; recheck: if (dev == NULL) @@ -3257,19 +3323,28 @@ recheck: dev = vlan_dev_real_dev(dev); goto recheck; } - - if (!is_netxen_netdev(dev)) - goto done; - - adapter = netdev_priv(dev); - - if (!adapter) - goto done; - - if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) - goto done; - - netxen_config_indev_addr(adapter, orig_dev, event); + if (event == NETDEV_UP || event == NETDEV_DOWN) { + /* If this is a bonding device, look for netxen-based slaves*/ + if (netif_is_bond_master(dev)) { + rcu_read_lock(); + for_each_netdev_in_bond_rcu(dev, slave) { + if (!netxen_config_checkdev(slave)) + continue; + adapter = netdev_priv(slave); + netxen_config_indev_addr(adapter, + orig_dev, event); + } + rcu_read_unlock(); + } else { + if (!netxen_config_checkdev(dev)) + goto done; + adapter = netdev_priv(dev); + /* Act only if the actual netxen is the target */ + if (orig_dev == dev) + netxen_config_master(dev, event); + netxen_config_indev_addr(adapter, orig_dev, event); + } + } done: return NOTIFY_DONE; } @@ -3279,12 +3354,12 @@ netxen_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) { struct netxen_adapter *adapter; - struct net_device *dev; - + struct net_device *dev, *slave; struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + unsigned long ip_event; dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; - + ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN; recheck: if (dev == NULL) goto done; @@ -3293,31 +3368,24 @@ recheck: dev = vlan_dev_real_dev(dev); goto recheck; } - - if (!is_netxen_netdev(dev)) - goto done; - - adapter = netdev_priv(dev); - - if (!adapter || !netxen_destip_supported(adapter)) - goto done; - - if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) - goto done; - - switch (event) { - case NETDEV_UP: - netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP); - netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP); - break; - case NETDEV_DOWN: - netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN); - netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN); - break; - default: - break; + if (event == NETDEV_UP || event == NETDEV_DOWN) { + /* If this is a bonding device, look for netxen-based slaves*/ + if (netif_is_bond_master(dev)) { + rcu_read_lock(); + for_each_netdev_in_bond_rcu(dev, slave) { + if (!netxen_config_checkdev(slave)) + continue; + adapter = netdev_priv(slave); + netxen_list_config_ip(adapter, ifa, ip_event); + } + rcu_read_unlock(); + } else { + if (!netxen_config_checkdev(dev)) + goto done; + adapter = netdev_priv(dev); + netxen_list_config_ip(adapter, ifa, ip_event); + } } - done: return NOTIFY_DONE; } @@ -3334,7 +3402,7 @@ static void netxen_restore_indev_addr(struct net_device *dev, unsigned long event) { } static void -netxen_free_vlan_ip_list(struct netxen_adapter *adapter) +netxen_free_ip_list(struct netxen_adapter *adapter, bool master) { } #endif diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e1ebeffa6b35..9fc1ab0c8914 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1617,6 +1617,9 @@ extern seqcount_t devnet_rename_seq; /* Device rename seq */ list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) #define for_each_netdev_continue_rcu(net, d) \ list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list) +#define for_each_netdev_in_bond_rcu(bond, slave) \ + for_each_netdev_rcu(&init_net, slave) \ + if (netdev_master_upper_dev_get_rcu(slave) == bond) #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) static inline struct net_device *next_net_device(struct net_device *dev) @@ -2774,6 +2777,11 @@ static inline void netif_set_gso_max_size(struct net_device *dev, dev->gso_max_size = size; } +static inline bool netif_is_bond_master(struct net_device *dev) +{ + return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING; +} + static inline bool netif_is_bond_slave(struct net_device *dev) { return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; -- cgit From fe330ce8e1cfc5cb3ba091e28e871aaab436b258 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 15 Feb 2013 16:04:47 +0100 Subject: sh-pfc: Declare operation structures as const The pinconf, pinctrl and pinmux operation structures hold function pointers that are never modified. Declare them as const. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 11e0e1374d65..887930e78d58 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -70,7 +70,7 @@ static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, seq_printf(s, "%s", DRV_NAME); } -static struct pinctrl_ops sh_pfc_pinctrl_ops = { +static const struct pinctrl_ops sh_pfc_pinctrl_ops = { .get_groups_count = sh_pfc_get_groups_count, .get_group_name = sh_pfc_get_group_name, .get_group_pins = sh_pfc_get_group_pins, @@ -252,7 +252,7 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, return sh_pfc_reconfig_pin(pmx->pfc, offset, type); } -static struct pinmux_ops sh_pfc_pinmux_ops = { +static const struct pinmux_ops sh_pfc_pinmux_ops = { .get_functions_count = sh_pfc_get_functions_count, .get_function_name = sh_pfc_get_function_name, .get_function_groups = sh_pfc_get_function_groups, @@ -308,7 +308,7 @@ static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, " %s", pinmux_type_str[config]); } -static struct pinconf_ops sh_pfc_pinconf_ops = { +static const struct pinconf_ops sh_pfc_pinconf_ops = { .pin_config_get = sh_pfc_pinconf_get, .pin_config_set = sh_pfc_pinconf_set, .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, -- cgit From dcc427e1a82df8ff123f12186af31dbe30dfa7cb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 16 Feb 2013 16:38:30 +0100 Subject: sh-pfc: Don't define the per-device pinctrl struct instances as global The pinctrl_desc and pinctrl_gpio_range structures registered with the pinctrl core are per-device instances. Move them to the dynamically allocated sh_pfc_pinctrl structure and initialize them at runtime. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 887930e78d58..d113746ec873 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -27,6 +27,9 @@ struct sh_pfc_pinctrl { struct pinctrl_dev *pctl; + struct pinctrl_desc pctl_desc; + struct pinctrl_gpio_range range; + struct sh_pfc *pfc; struct pinmux_gpio **functions; @@ -314,19 +317,6 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, }; -static struct pinctrl_gpio_range sh_pfc_gpio_range = { - .name = DRV_NAME, - .id = 0, -}; - -static struct pinctrl_desc sh_pfc_pinctrl_desc = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pctlops = &sh_pfc_pinctrl_ops, - .pmxops = &sh_pfc_pinmux_ops, - .confops = &sh_pfc_pinconf_ops, -}; - static void sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, struct pinmux_gpio *gpio, unsigned offset) { @@ -386,9 +376,6 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) spin_unlock_irqrestore(&pfc->lock, flags); - sh_pfc_pinctrl_desc.pins = pmx->pads; - sh_pfc_pinctrl_desc.npins = pmx->nr_pads; - return 0; } @@ -438,16 +425,25 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) if (unlikely(ret != 0)) return ret; - pmx->pctl = pinctrl_register(&sh_pfc_pinctrl_desc, pfc->dev, pmx); + pmx->pctl_desc.name = DRV_NAME; + pmx->pctl_desc.owner = THIS_MODULE; + pmx->pctl_desc.pctlops = &sh_pfc_pinctrl_ops; + pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops; + pmx->pctl_desc.confops = &sh_pfc_pinconf_ops; + pmx->pctl_desc.pins = pmx->pads; + pmx->pctl_desc.npins = pmx->nr_pads; + + pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); if (IS_ERR(pmx->pctl)) return PTR_ERR(pmx->pctl); - sh_pfc_gpio_range.npins = pfc->info->last_gpio - - pfc->info->first_gpio + 1; - sh_pfc_gpio_range.base = pfc->info->first_gpio; - sh_pfc_gpio_range.pin_base = pfc->info->first_gpio; + pmx->range.name = DRV_NAME, + pmx->range.id = 0; + pmx->range.npins = pfc->info->last_gpio - pfc->info->first_gpio + 1; + pmx->range.base = pfc->info->first_gpio; + pmx->range.pin_base = pfc->info->first_gpio; - pinctrl_add_gpio_range(pmx->pctl, &sh_pfc_gpio_range); + pinctrl_add_gpio_range(pmx->pctl, &pmx->range); return 0; } -- cgit From 942785db87740d144eba0dd717991e07878aaffb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 12 Feb 2013 16:34:31 +0100 Subject: sh-pfc: Fix a typo and simplify a definition on sh73a0 Fix definition of the SDHIWP0 function and simplify the CPU_ALL_PORT definition on sh73a0. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 709008e94124..232731bcdd22 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -25,11 +25,7 @@ #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ - PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ - PORT_10(fn, pfx##2, sfx), PORT_10(fn, pfx##3, sfx), \ - PORT_10(fn, pfx##4, sfx), PORT_10(fn, pfx##5, sfx), \ - PORT_10(fn, pfx##6, sfx), PORT_10(fn, pfx##7, sfx), \ - PORT_10(fn, pfx##8, sfx), PORT_10(fn, pfx##9, sfx), \ + PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \ PORT_10(fn, pfx##10, sfx), \ PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx), \ PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx), \ @@ -1502,7 +1498,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU), PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU), PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU), - PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT256_IN_PU), + PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT257_IN_PU), PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU), PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU), PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU), -- cgit From e3e89ae43e132b80039614098597ad2fec6cfbb1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 28 Nov 2012 20:52:53 +0100 Subject: sh-pfc: Drop the sh_pfc_pinctrl spinlock The spinlock is used to protect data that is only accessed sequentially during initialization. Remove it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index d113746ec873..9bd0a830c140 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -37,8 +37,6 @@ struct sh_pfc_pinctrl { struct pinctrl_pin_desc *pads; unsigned int nr_pads; - - spinlock_t lock; }; static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) @@ -321,7 +319,6 @@ static void sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, struct pinmux_gpio *gpio, unsigned offset) { struct pinmux_data_reg *dummy; - unsigned long flags; int bit; gpio->flags &= ~PINMUX_FLAG_TYPE; @@ -330,10 +327,7 @@ static void sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, gpio->flags |= PINMUX_TYPE_GPIO; else { gpio->flags |= PINMUX_TYPE_FUNCTION; - - spin_lock_irqsave(&pmx->lock, flags); pmx->nr_functions++; - spin_unlock_irqrestore(&pmx->lock, flags); } } @@ -381,7 +375,6 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { - unsigned long flags; int i, fn; pmx->functions = devm_kzalloc(pfc->dev, pmx->nr_functions * @@ -389,8 +382,6 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) if (unlikely(!pmx->functions)) return -ENOMEM; - spin_lock_irqsave(&pmx->lock, flags); - for (i = fn = 0; i < pmx->nr_pads; i++) { struct pinmux_gpio *gpio = pfc->info->gpios + i; @@ -398,8 +389,6 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) pmx->functions[fn++] = gpio; } - spin_unlock_irqrestore(&pmx->lock, flags); - return 0; } @@ -412,8 +401,6 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) if (unlikely(!pmx)) return -ENOMEM; - spin_lock_init(&pmx->lock); - pmx->pfc = pfc; pfc->pinctrl = pmx; -- cgit From d785fdb5d8ebdb0081624e9d8b220ff199c22645 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 28 Nov 2012 20:56:48 +0100 Subject: sh-pfc: Don't take the sh_pfc spinlock in sh_pfc_map_gpios() The sh_pfc_map_gpios() function is only called at initialization time when no other task can access the sh_pfc fields. Don't protect the operation with a spinlock. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 9bd0a830c140..4ce2753cb2df 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -334,7 +334,6 @@ static void sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, /* pinmux ranges -> pinctrl pin descs */ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { - unsigned long flags; int i; pmx->nr_pads = pfc->info->last_gpio - pfc->info->first_gpio + 1; @@ -346,8 +345,6 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) return -ENOMEM; } - spin_lock_irqsave(&pfc->lock, flags); - /* * We don't necessarily have a 1:1 mapping between pin and linux * GPIO number, as the latter maps to the associated enum_id. @@ -368,8 +365,6 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) sh_pfc_map_one_gpio(pfc, pmx, gpio, i); } - spin_unlock_irqrestore(&pfc->lock, flags); - return 0; } -- cgit From 35ad42719efcd25d310d1ad5f8b0f3a5c68e671d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 28 Nov 2012 22:05:49 +0100 Subject: sh-pfc: Use GPIO_FN instead of PINMUX_GPIO where possible The GPIO_FN macro expands to the PINMUX_GPIO macro. The regular expression to 'unexpand' PINMUX_GPIO to GPIO_FN is s/\tPINMUX_GPIO(GPIO_FN_\([A-Z0-9_]*\),[ \t]*\1_MARK)/\tGPIO_FN(\1)/ This consolidates SoC-specific PFC information to use the same macros for all SoCs. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 464 +++++++++++++-------------- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 436 ++++++++++++------------- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 600 +++++++++++++++++----------------- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 309 +++++++++--------- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 456 +++++++++++++------------- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 618 ++++++++++++++++++------------------ drivers/pinctrl/sh-pfc/pfc-sh7724.c | 614 +++++++++++++++++------------------ drivers/pinctrl/sh-pfc/pfc-sh7757.c | 596 +++++++++++++++++----------------- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 330 +++++++++---------- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 272 ++++++++-------- drivers/pinctrl/sh-pfc/pfc-shx3.c | 124 ++++---- 11 files changed, 2409 insertions(+), 2410 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index 01b425dfd162..22be49b3bd38 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -817,260 +817,260 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PF0, PF0_DATA), /* INTC */ - PINMUX_GPIO(GPIO_FN_PINT7_PB, PINT7_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PB, PINT6_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PB, PINT5_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PB, PINT4_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PB, PINT3_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PB, PINT2_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PB, PINT1_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT0_PB, PINT0_PB_MARK), - PINMUX_GPIO(GPIO_FN_PINT7_PD, PINT7_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PD, PINT6_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PD, PINT5_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PD, PINT4_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PD, PINT3_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PD, PINT2_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PD, PINT1_PD_MARK), - PINMUX_GPIO(GPIO_FN_PINT0_PD, PINT0_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7_PB, IRQ7_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PB, IRQ6_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PB, IRQ5_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PB, IRQ4_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PB, IRQ3_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PB, IRQ2_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PB, IRQ1_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PB, IRQ0_PB_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7_PD, IRQ7_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PD, IRQ6_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PD, IRQ5_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PD, IRQ4_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PD, IRQ3_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PD, IRQ2_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PD, IRQ1_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PD, IRQ0_PD_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7_PE, IRQ7_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PE, IRQ6_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PE, IRQ5_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PE, IRQ4_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PE, IRQ3_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PE, IRQ2_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PE, IRQ1_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PE, IRQ0_PE_MARK), - - PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK), - PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK), - PINMUX_GPIO(GPIO_FN_REFOUT, REFOUT_MARK), - PINMUX_GPIO(GPIO_FN_IRQOUT_REFOUT, IRQOUT_REFOUT_MARK), - PINMUX_GPIO(GPIO_FN_UBCTRG, UBCTRG_MARK), + GPIO_FN(PINT7_PB), + GPIO_FN(PINT6_PB), + GPIO_FN(PINT5_PB), + GPIO_FN(PINT4_PB), + GPIO_FN(PINT3_PB), + GPIO_FN(PINT2_PB), + GPIO_FN(PINT1_PB), + GPIO_FN(PINT0_PB), + GPIO_FN(PINT7_PD), + GPIO_FN(PINT6_PD), + GPIO_FN(PINT5_PD), + GPIO_FN(PINT4_PD), + GPIO_FN(PINT3_PD), + GPIO_FN(PINT2_PD), + GPIO_FN(PINT1_PD), + GPIO_FN(PINT0_PD), + GPIO_FN(IRQ7_PB), + GPIO_FN(IRQ6_PB), + GPIO_FN(IRQ5_PB), + GPIO_FN(IRQ4_PB), + GPIO_FN(IRQ3_PB), + GPIO_FN(IRQ2_PB), + GPIO_FN(IRQ1_PB), + GPIO_FN(IRQ0_PB), + GPIO_FN(IRQ7_PD), + GPIO_FN(IRQ6_PD), + GPIO_FN(IRQ5_PD), + GPIO_FN(IRQ4_PD), + GPIO_FN(IRQ3_PD), + GPIO_FN(IRQ2_PD), + GPIO_FN(IRQ1_PD), + GPIO_FN(IRQ0_PD), + GPIO_FN(IRQ7_PE), + GPIO_FN(IRQ6_PE), + GPIO_FN(IRQ5_PE), + GPIO_FN(IRQ4_PE), + GPIO_FN(IRQ3_PE), + GPIO_FN(IRQ2_PE), + GPIO_FN(IRQ1_PE), + GPIO_FN(IRQ0_PE), + + GPIO_FN(WDTOVF), + GPIO_FN(IRQOUT), + GPIO_FN(REFOUT), + GPIO_FN(IRQOUT_REFOUT), + GPIO_FN(UBCTRG), /* CAN */ - PINMUX_GPIO(GPIO_FN_CTX1, CTX1_MARK), - PINMUX_GPIO(GPIO_FN_CRX1, CRX1_MARK), - PINMUX_GPIO(GPIO_FN_CTX0, CTX0_MARK), - PINMUX_GPIO(GPIO_FN_CTX0_CTX1, CTX0_CTX1_MARK), - PINMUX_GPIO(GPIO_FN_CRX0, CRX0_MARK), - PINMUX_GPIO(GPIO_FN_CRX0_CRX1, CRX0_CRX1_MARK), + GPIO_FN(CTX1), + GPIO_FN(CRX1), + GPIO_FN(CTX0), + GPIO_FN(CTX0_CTX1), + GPIO_FN(CRX0), + GPIO_FN(CRX0_CRX1), /* IIC3 */ - PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK), - PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK), - PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK), - PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK), - PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK), - PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK), - PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK), - PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK), + GPIO_FN(SDA3), + GPIO_FN(SCL3), + GPIO_FN(SDA2), + GPIO_FN(SCL2), + GPIO_FN(SDA1), + GPIO_FN(SCL1), + GPIO_FN(SDA0), + GPIO_FN(SCL0), /* DMAC */ - PINMUX_GPIO(GPIO_FN_TEND0_PD, TEND0_PD_MARK), - PINMUX_GPIO(GPIO_FN_TEND0_PE, TEND0_PE_MARK), - PINMUX_GPIO(GPIO_FN_DACK0_PD, DACK0_PD_MARK), - PINMUX_GPIO(GPIO_FN_DACK0_PE, DACK0_PE_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0_PD, DREQ0_PD_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0_PE, DREQ0_PE_MARK), - PINMUX_GPIO(GPIO_FN_TEND1_PD, TEND1_PD_MARK), - PINMUX_GPIO(GPIO_FN_TEND1_PE, TEND1_PE_MARK), - PINMUX_GPIO(GPIO_FN_DACK1_PD, DACK1_PD_MARK), - PINMUX_GPIO(GPIO_FN_DACK1_PE, DACK1_PE_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1_PD, DREQ1_PD_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1_PE, DREQ1_PE_MARK), - PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK), - PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK), - PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK), - PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK), + GPIO_FN(TEND0_PD), + GPIO_FN(TEND0_PE), + GPIO_FN(DACK0_PD), + GPIO_FN(DACK0_PE), + GPIO_FN(DREQ0_PD), + GPIO_FN(DREQ0_PE), + GPIO_FN(TEND1_PD), + GPIO_FN(TEND1_PE), + GPIO_FN(DACK1_PD), + GPIO_FN(DACK1_PE), + GPIO_FN(DREQ1_PD), + GPIO_FN(DREQ1_PE), + GPIO_FN(DACK2), + GPIO_FN(DREQ2), + GPIO_FN(DACK3), + GPIO_FN(DREQ3), /* ADC */ - PINMUX_GPIO(GPIO_FN_ADTRG_PD, ADTRG_PD_MARK), - PINMUX_GPIO(GPIO_FN_ADTRG_PE, ADTRG_PE_MARK), + GPIO_FN(ADTRG_PD), + GPIO_FN(ADTRG_PE), /* BSC */ - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_A21, A21_MARK), - PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK), - PINMUX_GPIO(GPIO_FN_MRES, MRES_MARK), - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_CS1, CS1_MARK), - PINMUX_GPIO(GPIO_FN_CS6_CE1B, CS6_CE1B_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_CS5_CE1A, CS5_CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_FRAME, FRAME_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK), - PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK), - PINMUX_GPIO(GPIO_FN_CASU, CASU_MARK), - PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK), - PINMUX_GPIO(GPIO_FN_RASU, RASU_MARK), - PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK), - PINMUX_GPIO(GPIO_FN_CASL, CASL_MARK), - PINMUX_GPIO(GPIO_FN_RASL, RASL_MARK), - PINMUX_GPIO(GPIO_FN_WE3_DQMUU_AH_ICIO_WR, WE3_DQMUU_AH_ICIO_WR_MARK), - PINMUX_GPIO(GPIO_FN_WE2_DQMUL_ICIORD, WE2_DQMUL_ICIORD_MARK), - PINMUX_GPIO(GPIO_FN_WE1_DQMLU_WE, WE1_DQMLU_WE_MARK), - PINMUX_GPIO(GPIO_FN_WE0_DQMLL, WE0_DQMLL_MARK), - PINMUX_GPIO(GPIO_FN_CS3, CS3_MARK), - PINMUX_GPIO(GPIO_FN_CS2, CS2_MARK), - PINMUX_GPIO(GPIO_FN_A1, A1_MARK), - PINMUX_GPIO(GPIO_FN_A0, A0_MARK), - PINMUX_GPIO(GPIO_FN_CS7, CS7_MARK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(A21), + GPIO_FN(CS4), + GPIO_FN(MRES), + GPIO_FN(BS), + GPIO_FN(IOIS16), + GPIO_FN(CS1), + GPIO_FN(CS6_CE1B), + GPIO_FN(CE2B), + GPIO_FN(CS5_CE1A), + GPIO_FN(CE2A), + GPIO_FN(FRAME), + GPIO_FN(WAIT), + GPIO_FN(RDWR), + GPIO_FN(CKE), + GPIO_FN(CASU), + GPIO_FN(BREQ), + GPIO_FN(RASU), + GPIO_FN(BACK), + GPIO_FN(CASL), + GPIO_FN(RASL), + GPIO_FN(WE3_DQMUU_AH_ICIO_WR), + GPIO_FN(WE2_DQMUL_ICIORD), + GPIO_FN(WE1_DQMLU_WE), + GPIO_FN(WE0_DQMLL), + GPIO_FN(CS3), + GPIO_FN(CS2), + GPIO_FN(A1), + GPIO_FN(A0), + GPIO_FN(CS7), /* TMU */ - PINMUX_GPIO(GPIO_FN_TIOC4D, TIOC4D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4C, TIOC4C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4B, TIOC4B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4A, TIOC4A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3D, TIOC3D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3C, TIOC3C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3B, TIOC3B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3A, TIOC3A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2B, TIOC2B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1B, TIOC1B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2A, TIOC2A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1A, TIOC1A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0D, TIOC0D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0C, TIOC0C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0B, TIOC0B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0A, TIOC0A_MARK), - PINMUX_GPIO(GPIO_FN_TCLKD_PD, TCLKD_PD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKC_PD, TCLKC_PD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKB_PD, TCLKB_PD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKA_PD, TCLKA_PD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKD_PF, TCLKD_PF_MARK), - PINMUX_GPIO(GPIO_FN_TCLKC_PF, TCLKC_PF_MARK), - PINMUX_GPIO(GPIO_FN_TCLKB_PF, TCLKB_PF_MARK), - PINMUX_GPIO(GPIO_FN_TCLKA_PF, TCLKA_PF_MARK), + GPIO_FN(TIOC4D), + GPIO_FN(TIOC4C), + GPIO_FN(TIOC4B), + GPIO_FN(TIOC4A), + GPIO_FN(TIOC3D), + GPIO_FN(TIOC3C), + GPIO_FN(TIOC3B), + GPIO_FN(TIOC3A), + GPIO_FN(TIOC2B), + GPIO_FN(TIOC1B), + GPIO_FN(TIOC2A), + GPIO_FN(TIOC1A), + GPIO_FN(TIOC0D), + GPIO_FN(TIOC0C), + GPIO_FN(TIOC0B), + GPIO_FN(TIOC0A), + GPIO_FN(TCLKD_PD), + GPIO_FN(TCLKC_PD), + GPIO_FN(TCLKB_PD), + GPIO_FN(TCLKA_PD), + GPIO_FN(TCLKD_PF), + GPIO_FN(TCLKC_PF), + GPIO_FN(TCLKB_PF), + GPIO_FN(TCLKA_PF), /* SSU */ - PINMUX_GPIO(GPIO_FN_SCS0_PD, SCS0_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSO0_PD, SSO0_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_PD, SSI0_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSCK0_PD, SSCK0_PD_MARK), - PINMUX_GPIO(GPIO_FN_SCS0_PF, SCS0_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSO0_PF, SSO0_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_PF, SSI0_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSCK0_PF, SSCK0_PF_MARK), - PINMUX_GPIO(GPIO_FN_SCS1_PD, SCS1_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSO1_PD, SSO1_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_PD, SSI1_PD_MARK), - PINMUX_GPIO(GPIO_FN_SSCK1_PD, SSCK1_PD_MARK), - PINMUX_GPIO(GPIO_FN_SCS1_PF, SCS1_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSO1_PF, SSO1_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_PF, SSI1_PF_MARK), - PINMUX_GPIO(GPIO_FN_SSCK1_PF, SSCK1_PF_MARK), + GPIO_FN(SCS0_PD), + GPIO_FN(SSO0_PD), + GPIO_FN(SSI0_PD), + GPIO_FN(SSCK0_PD), + GPIO_FN(SCS0_PF), + GPIO_FN(SSO0_PF), + GPIO_FN(SSI0_PF), + GPIO_FN(SSCK0_PF), + GPIO_FN(SCS1_PD), + GPIO_FN(SSO1_PD), + GPIO_FN(SSI1_PD), + GPIO_FN(SSCK1_PD), + GPIO_FN(SCS1_PF), + GPIO_FN(SSO1_PF), + GPIO_FN(SSI1_PF), + GPIO_FN(SSCK1_PF), /* SCIF */ - PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK), - PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK), - PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK), - PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK), - PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK), - PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK), - PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK), - PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK), - PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK), - PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK), - PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK), - PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK), + GPIO_FN(TXD0), + GPIO_FN(RXD0), + GPIO_FN(SCK0), + GPIO_FN(TXD1), + GPIO_FN(RXD1), + GPIO_FN(SCK1), + GPIO_FN(TXD2), + GPIO_FN(RXD2), + GPIO_FN(SCK2), + GPIO_FN(RTS3), + GPIO_FN(CTS3), + GPIO_FN(TXD3), + GPIO_FN(RXD3), + GPIO_FN(SCK3), /* SSI */ - PINMUX_GPIO(GPIO_FN_AUDIO_CLK, AUDIO_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA3, SSIDATA3_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS3, SSIWS3_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK3, SSISCK3_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA2, SSIDATA2_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS2, SSIWS2_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK2, SSISCK2_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA1, SSIDATA1_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS1, SSIWS1_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK1, SSISCK1_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA0, SSIDATA0_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS0, SSIWS0_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK0, SSISCK0_MARK), + GPIO_FN(AUDIO_CLK), + GPIO_FN(SSIDATA3), + GPIO_FN(SSIWS3), + GPIO_FN(SSISCK3), + GPIO_FN(SSIDATA2), + GPIO_FN(SSIWS2), + GPIO_FN(SSISCK2), + GPIO_FN(SSIDATA1), + GPIO_FN(SSIWS1), + GPIO_FN(SSISCK1), + GPIO_FN(SSIDATA0), + GPIO_FN(SSIWS0), + GPIO_FN(SSISCK0), /* FLCTL */ - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), - PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK), - PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK), - PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK), - PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK), - PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK), - PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK), - PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK), - PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK), - PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK), - PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK), - PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK), - PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK), + GPIO_FN(FCE), + GPIO_FN(FRB), + GPIO_FN(NAF7), + GPIO_FN(NAF6), + GPIO_FN(NAF5), + GPIO_FN(NAF4), + GPIO_FN(NAF3), + GPIO_FN(NAF2), + GPIO_FN(NAF1), + GPIO_FN(NAF0), + GPIO_FN(FSC), + GPIO_FN(FOE), + GPIO_FN(FCDE), + GPIO_FN(FWE), /* LCDC */ - PINMUX_GPIO(GPIO_FN_LCD_VEPWC, LCD_VEPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_VCPWC, LCD_VCPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_CLK, LCD_CLK_MARK), - PINMUX_GPIO(GPIO_FN_LCD_FLM, LCD_FLM_MARK), - PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), - PINMUX_GPIO(GPIO_FN_LCD_CL2, LCD_CL2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_CL1, LCD_CL1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DON, LCD_DON_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK), + GPIO_FN(LCD_VEPWC), + GPIO_FN(LCD_VCPWC), + GPIO_FN(LCD_CLK), + GPIO_FN(LCD_FLM), + GPIO_FN(LCD_M_DISP), + GPIO_FN(LCD_CL2), + GPIO_FN(LCD_CL1), + GPIO_FN(LCD_DON), + GPIO_FN(LCD_DATA15), + GPIO_FN(LCD_DATA14), + GPIO_FN(LCD_DATA13), + GPIO_FN(LCD_DATA12), + GPIO_FN(LCD_DATA11), + GPIO_FN(LCD_DATA10), + GPIO_FN(LCD_DATA9), + GPIO_FN(LCD_DATA8), + GPIO_FN(LCD_DATA7), + GPIO_FN(LCD_DATA6), + GPIO_FN(LCD_DATA5), + GPIO_FN(LCD_DATA4), + GPIO_FN(LCD_DATA3), + GPIO_FN(LCD_DATA2), + GPIO_FN(LCD_DATA1), + GPIO_FN(LCD_DATA0), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index 2ba5639dcf34..ebe9c7ceb575 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -1218,252 +1218,252 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PK0, PK0_DATA), /* INTC */ - PINMUX_GPIO(GPIO_FN_PINT7_PG, PINT7_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PG, PINT6_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PG, PINT5_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PG, PINT4_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PG, PINT3_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PG, PINT2_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PG, PINT1_PG_MARK), - - PINMUX_GPIO(GPIO_FN_IRQ7_PC, IRQ7_PC_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PC, IRQ6_PC_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PC, IRQ5_PC_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PC, IRQ4_PC_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PG, IRQ3_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PG, IRQ2_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PJ, IRQ1_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PJ, IRQ0_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PE, IRQ3_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PE, IRQ2_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PE, IRQ1_PE_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PE, IRQ0_PE_MARK), + GPIO_FN(PINT7_PG), + GPIO_FN(PINT6_PG), + GPIO_FN(PINT5_PG), + GPIO_FN(PINT4_PG), + GPIO_FN(PINT3_PG), + GPIO_FN(PINT2_PG), + GPIO_FN(PINT1_PG), + + GPIO_FN(IRQ7_PC), + GPIO_FN(IRQ6_PC), + GPIO_FN(IRQ5_PC), + GPIO_FN(IRQ4_PC), + GPIO_FN(IRQ3_PG), + GPIO_FN(IRQ2_PG), + GPIO_FN(IRQ1_PJ), + GPIO_FN(IRQ0_PJ), + GPIO_FN(IRQ3_PE), + GPIO_FN(IRQ2_PE), + GPIO_FN(IRQ1_PE), + GPIO_FN(IRQ0_PE), /* WDT */ - PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK), + GPIO_FN(WDTOVF), /* CAN */ - PINMUX_GPIO(GPIO_FN_CTX1, CTX1_MARK), - PINMUX_GPIO(GPIO_FN_CRX1, CRX1_MARK), - PINMUX_GPIO(GPIO_FN_CTX0, CTX0_MARK), - PINMUX_GPIO(GPIO_FN_CRX0, CRX0_MARK), - PINMUX_GPIO(GPIO_FN_CRX0_CRX1, CRX0_CRX1_MARK), + GPIO_FN(CTX1), + GPIO_FN(CRX1), + GPIO_FN(CTX0), + GPIO_FN(CRX0), + GPIO_FN(CRX0_CRX1), /* DMAC */ - PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK), - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), + GPIO_FN(TEND0), + GPIO_FN(DACK0), + GPIO_FN(DREQ0), + GPIO_FN(TEND1), + GPIO_FN(DACK1), + GPIO_FN(DREQ1), /* ADC */ - PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK), + GPIO_FN(ADTRG), /* BSCh */ - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_A21, A21_MARK), - PINMUX_GPIO(GPIO_FN_A20, A20_MARK), - PINMUX_GPIO(GPIO_FN_A19, A19_MARK), - PINMUX_GPIO(GPIO_FN_A18, A18_MARK), - PINMUX_GPIO(GPIO_FN_A17, A17_MARK), - PINMUX_GPIO(GPIO_FN_A16, A16_MARK), - PINMUX_GPIO(GPIO_FN_A15, A15_MARK), - PINMUX_GPIO(GPIO_FN_A14, A14_MARK), - PINMUX_GPIO(GPIO_FN_A13, A13_MARK), - PINMUX_GPIO(GPIO_FN_A12, A12_MARK), - PINMUX_GPIO(GPIO_FN_A11, A11_MARK), - PINMUX_GPIO(GPIO_FN_A10, A10_MARK), - PINMUX_GPIO(GPIO_FN_A9, A9_MARK), - PINMUX_GPIO(GPIO_FN_A8, A8_MARK), - PINMUX_GPIO(GPIO_FN_A7, A7_MARK), - PINMUX_GPIO(GPIO_FN_A6, A6_MARK), - PINMUX_GPIO(GPIO_FN_A5, A5_MARK), - PINMUX_GPIO(GPIO_FN_A4, A4_MARK), - PINMUX_GPIO(GPIO_FN_A3, A3_MARK), - PINMUX_GPIO(GPIO_FN_A2, A2_MARK), - PINMUX_GPIO(GPIO_FN_A1, A1_MARK), - PINMUX_GPIO(GPIO_FN_A0, A0_MARK), - - PINMUX_GPIO(GPIO_FN_D15, D15_MARK), - PINMUX_GPIO(GPIO_FN_D14, D14_MARK), - PINMUX_GPIO(GPIO_FN_D13, D13_MARK), - PINMUX_GPIO(GPIO_FN_D12, D12_MARK), - PINMUX_GPIO(GPIO_FN_D11, D11_MARK), - PINMUX_GPIO(GPIO_FN_D10, D10_MARK), - PINMUX_GPIO(GPIO_FN_D9, D9_MARK), - PINMUX_GPIO(GPIO_FN_D8, D8_MARK), - PINMUX_GPIO(GPIO_FN_D7, D7_MARK), - PINMUX_GPIO(GPIO_FN_D6, D6_MARK), - PINMUX_GPIO(GPIO_FN_D5, D5_MARK), - PINMUX_GPIO(GPIO_FN_D4, D4_MARK), - PINMUX_GPIO(GPIO_FN_D3, D3_MARK), - PINMUX_GPIO(GPIO_FN_D2, D2_MARK), - PINMUX_GPIO(GPIO_FN_D1, D1_MARK), - PINMUX_GPIO(GPIO_FN_D0, D0_MARK), - - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK), - PINMUX_GPIO(GPIO_FN_CS3, CS3_MARK), - PINMUX_GPIO(GPIO_FN_CS2, CS2_MARK), - PINMUX_GPIO(GPIO_FN_CS1, CS1_MARK), - PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK), - PINMUX_GPIO(GPIO_FN_CS6CE1B, CS6CE1B_MARK), - PINMUX_GPIO(GPIO_FN_CS5CE1A, CS5CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_RD, RD_MARK), - PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK), - PINMUX_GPIO(GPIO_FN_ICIOWRAH, ICIOWRAH_MARK), - PINMUX_GPIO(GPIO_FN_ICIORD, ICIORD_MARK), - PINMUX_GPIO(GPIO_FN_WE1DQMUWE, WE1DQMUWE_MARK), - PINMUX_GPIO(GPIO_FN_WE0DQML, WE0DQML_MARK), - PINMUX_GPIO(GPIO_FN_RAS, RAS_MARK), - PINMUX_GPIO(GPIO_FN_CAS, CAS_MARK), - PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK), - PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(A21), + GPIO_FN(A20), + GPIO_FN(A19), + GPIO_FN(A18), + GPIO_FN(A17), + GPIO_FN(A16), + GPIO_FN(A15), + GPIO_FN(A14), + GPIO_FN(A13), + GPIO_FN(A12), + GPIO_FN(A11), + GPIO_FN(A10), + GPIO_FN(A9), + GPIO_FN(A8), + GPIO_FN(A7), + GPIO_FN(A6), + GPIO_FN(A5), + GPIO_FN(A4), + GPIO_FN(A3), + GPIO_FN(A2), + GPIO_FN(A1), + GPIO_FN(A0), + + GPIO_FN(D15), + GPIO_FN(D14), + GPIO_FN(D13), + GPIO_FN(D12), + GPIO_FN(D11), + GPIO_FN(D10), + GPIO_FN(D9), + GPIO_FN(D8), + GPIO_FN(D7), + GPIO_FN(D6), + GPIO_FN(D5), + GPIO_FN(D4), + GPIO_FN(D3), + GPIO_FN(D2), + GPIO_FN(D1), + GPIO_FN(D0), + + GPIO_FN(BS), + GPIO_FN(CS4), + GPIO_FN(CS3), + GPIO_FN(CS2), + GPIO_FN(CS1), + GPIO_FN(CS0), + GPIO_FN(CS6CE1B), + GPIO_FN(CS5CE1A), + GPIO_FN(CE2A), + GPIO_FN(CE2B), + GPIO_FN(RD), + GPIO_FN(RDWR), + GPIO_FN(ICIOWRAH), + GPIO_FN(ICIORD), + GPIO_FN(WE1DQMUWE), + GPIO_FN(WE0DQML), + GPIO_FN(RAS), + GPIO_FN(CAS), + GPIO_FN(CKE), + GPIO_FN(WAIT), + GPIO_FN(BREQ), + GPIO_FN(BACK), + GPIO_FN(IOIS16), /* TMU */ - PINMUX_GPIO(GPIO_FN_TIOC4D, TIOC4D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4C, TIOC4C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4B, TIOC4B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4A, TIOC4A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3D, TIOC3D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3C, TIOC3C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3B, TIOC3B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3A, TIOC3A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2B, TIOC2B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1B, TIOC1B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2A, TIOC2A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1A, TIOC1A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0D, TIOC0D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0C, TIOC0C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0B, TIOC0B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0A, TIOC0A_MARK), - PINMUX_GPIO(GPIO_FN_TCLKD, TCLKD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKC, TCLKC_MARK), - PINMUX_GPIO(GPIO_FN_TCLKB, TCLKB_MARK), - PINMUX_GPIO(GPIO_FN_TCLKA, TCLKA_MARK), + GPIO_FN(TIOC4D), + GPIO_FN(TIOC4C), + GPIO_FN(TIOC4B), + GPIO_FN(TIOC4A), + GPIO_FN(TIOC3D), + GPIO_FN(TIOC3C), + GPIO_FN(TIOC3B), + GPIO_FN(TIOC3A), + GPIO_FN(TIOC2B), + GPIO_FN(TIOC1B), + GPIO_FN(TIOC2A), + GPIO_FN(TIOC1A), + GPIO_FN(TIOC0D), + GPIO_FN(TIOC0C), + GPIO_FN(TIOC0B), + GPIO_FN(TIOC0A), + GPIO_FN(TCLKD), + GPIO_FN(TCLKC), + GPIO_FN(TCLKB), + GPIO_FN(TCLKA), /* SCIF */ - PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK), - PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK), - PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK), - PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK), - PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK), - PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK), - PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK), - PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK), - PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK), - PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK), - PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK), - PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK), - PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK), - PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK), - PINMUX_GPIO(GPIO_FN_TXD5, TXD5_MARK), - PINMUX_GPIO(GPIO_FN_RXD5, RXD5_MARK), - PINMUX_GPIO(GPIO_FN_TXD6, TXD6_MARK), - PINMUX_GPIO(GPIO_FN_RXD6, RXD6_MARK), - PINMUX_GPIO(GPIO_FN_TXD7, TXD7_MARK), - PINMUX_GPIO(GPIO_FN_RXD7, RXD7_MARK), - PINMUX_GPIO(GPIO_FN_RTS1, RTS1_MARK), - PINMUX_GPIO(GPIO_FN_CTS1, CTS1_MARK), + GPIO_FN(TXD0), + GPIO_FN(RXD0), + GPIO_FN(SCK0), + GPIO_FN(TXD1), + GPIO_FN(RXD1), + GPIO_FN(SCK1), + GPIO_FN(TXD2), + GPIO_FN(RXD2), + GPIO_FN(SCK2), + GPIO_FN(RTS3), + GPIO_FN(CTS3), + GPIO_FN(TXD3), + GPIO_FN(RXD3), + GPIO_FN(SCK3), + GPIO_FN(TXD4), + GPIO_FN(RXD4), + GPIO_FN(TXD5), + GPIO_FN(RXD5), + GPIO_FN(TXD6), + GPIO_FN(RXD6), + GPIO_FN(TXD7), + GPIO_FN(RXD7), + GPIO_FN(RTS1), + GPIO_FN(CTS1), /* RSPI */ - PINMUX_GPIO(GPIO_FN_RSPCK0, RSPCK0_MARK), - PINMUX_GPIO(GPIO_FN_MOSI0, MOSI0_MARK), - PINMUX_GPIO(GPIO_FN_MISO0_PF12, MISO0_PF12_MARK), - PINMUX_GPIO(GPIO_FN_MISO1, MISO1_MARK), - PINMUX_GPIO(GPIO_FN_SSL00, SSL00_MARK), - PINMUX_GPIO(GPIO_FN_RSPCK1, RSPCK1_MARK), - PINMUX_GPIO(GPIO_FN_MOSI1, MOSI1_MARK), - PINMUX_GPIO(GPIO_FN_MISO1_PG19, MISO1_PG19_MARK), - PINMUX_GPIO(GPIO_FN_SSL10, SSL10_MARK), + GPIO_FN(RSPCK0), + GPIO_FN(MOSI0), + GPIO_FN(MISO0_PF12), + GPIO_FN(MISO1), + GPIO_FN(SSL00), + GPIO_FN(RSPCK1), + GPIO_FN(MOSI1), + GPIO_FN(MISO1_PG19), + GPIO_FN(SSL10), /* IIC3 */ - PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK), - PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK), - PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK), - PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK), - PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK), - PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK), + GPIO_FN(SCL0), + GPIO_FN(SCL1), + GPIO_FN(SCL2), + GPIO_FN(SDA0), + GPIO_FN(SDA1), + GPIO_FN(SDA2), /* SSI */ - PINMUX_GPIO(GPIO_FN_SSISCK0, SSISCK0_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS0, SSIWS0_MARK), - PINMUX_GPIO(GPIO_FN_SSITXD0, SSITXD0_MARK), - PINMUX_GPIO(GPIO_FN_SSIRXD0, SSIRXD0_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS1, SSIWS1_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS2, SSIWS2_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS3, SSIWS3_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK1, SSISCK1_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK2, SSISCK2_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK3, SSISCK3_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA1, SSIDATA1_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA2, SSIDATA2_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA3, SSIDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDIO_CLK, AUDIO_CLK_MARK), + GPIO_FN(SSISCK0), + GPIO_FN(SSIWS0), + GPIO_FN(SSITXD0), + GPIO_FN(SSIRXD0), + GPIO_FN(SSIWS1), + GPIO_FN(SSIWS2), + GPIO_FN(SSIWS3), + GPIO_FN(SSISCK1), + GPIO_FN(SSISCK2), + GPIO_FN(SSISCK3), + GPIO_FN(SSIDATA1), + GPIO_FN(SSIDATA2), + GPIO_FN(SSIDATA3), + GPIO_FN(AUDIO_CLK), /* SIOF */ /* NOTE Shares AUDIO_CLK with SSI */ - PINMUX_GPIO(GPIO_FN_SIOFTXD, SIOFTXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOFRXD, SIOFRXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOFSYNC, SIOFSYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOFSCK, SIOFSCK_MARK), + GPIO_FN(SIOFTXD), + GPIO_FN(SIOFRXD), + GPIO_FN(SIOFSYNC), + GPIO_FN(SIOFSCK), /* SPDIF */ /* NOTE Shares AUDIO_CLK with SSI */ - PINMUX_GPIO(GPIO_FN_SPDIF_IN, SPDIF_IN_MARK), - PINMUX_GPIO(GPIO_FN_SPDIF_OUT, SPDIF_OUT_MARK), + GPIO_FN(SPDIF_IN), + GPIO_FN(SPDIF_OUT), /* NANDFMC */ /* NOTE Controller is not available in boot mode 0 */ - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), + GPIO_FN(FCE), + GPIO_FN(FRB), /* VDC3 */ - PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), - - PINMUX_GPIO(GPIO_FN_DV_DATA7, DV_DATA7_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA6, DV_DATA6_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA5, DV_DATA5_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA4, DV_DATA4_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA3, DV_DATA3_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA2, DV_DATA2_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA1, DV_DATA1_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA0, DV_DATA0_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_CLK, LCD_CLK_MARK), - PINMUX_GPIO(GPIO_FN_LCD_EXTCLK, LCD_EXTCLK_MARK), - PINMUX_GPIO(GPIO_FN_LCD_VSYNC, LCD_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_HSYNC, LCD_HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DE, LCD_DE_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), + GPIO_FN(DV_CLK), + GPIO_FN(DV_VSYNC), + GPIO_FN(DV_HSYNC), + + GPIO_FN(DV_DATA7), + GPIO_FN(DV_DATA6), + GPIO_FN(DV_DATA5), + GPIO_FN(DV_DATA4), + GPIO_FN(DV_DATA3), + GPIO_FN(DV_DATA2), + GPIO_FN(DV_DATA1), + GPIO_FN(DV_DATA0), + + GPIO_FN(LCD_CLK), + GPIO_FN(LCD_EXTCLK), + GPIO_FN(LCD_VSYNC), + GPIO_FN(LCD_HSYNC), + GPIO_FN(LCD_DE), + + GPIO_FN(LCD_DATA15), + GPIO_FN(LCD_DATA14), + GPIO_FN(LCD_DATA13), + GPIO_FN(LCD_DATA12), + GPIO_FN(LCD_DATA11), + GPIO_FN(LCD_DATA10), + GPIO_FN(LCD_DATA9), + GPIO_FN(LCD_DATA8), + GPIO_FN(LCD_DATA7), + GPIO_FN(LCD_DATA6), + GPIO_FN(LCD_DATA5), + GPIO_FN(LCD_DATA4), + GPIO_FN(LCD_DATA3), + GPIO_FN(LCD_DATA2), + GPIO_FN(LCD_DATA1), + GPIO_FN(LCD_DATA0), + + GPIO_FN(LCD_M_DISP), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index b1b5d6d4ad76..87cb6933e02b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -1615,334 +1615,334 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PJ0, PJ0_DATA), /* INTC */ - PINMUX_GPIO(GPIO_FN_IRQ7_PG, IRQ7_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PG, IRQ6_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PG, IRQ5_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PG, IRQ4_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PG, IRQ3_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PG, IRQ2_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PG, IRQ1_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PG, IRQ0_PG_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7_PF, IRQ7_PF_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6_PF, IRQ6_PF_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5_PF, IRQ5_PF_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4_PF, IRQ4_PF_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_PJ, IRQ3_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_PJ, IRQ2_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PJ, IRQ1_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PJ, IRQ0_PJ_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_PC, IRQ1_PC_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_PC, IRQ0_PC_MARK), - - PINMUX_GPIO(GPIO_FN_PINT7_PG, PINT7_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PG, PINT6_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PG, PINT5_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PG, PINT4_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PG, PINT3_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PG, PINT2_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PG, PINT1_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT0_PG, PINT0_PG_MARK), - PINMUX_GPIO(GPIO_FN_PINT7_PH, PINT7_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PH, PINT6_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PH, PINT5_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PH, PINT4_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PH, PINT3_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PH, PINT2_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PH, PINT1_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT0_PH, PINT0_PH_MARK), - PINMUX_GPIO(GPIO_FN_PINT7_PJ, PINT7_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT6_PJ, PINT6_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT5_PJ, PINT5_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT4_PJ, PINT4_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT3_PJ, PINT3_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT2_PJ, PINT2_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT1_PJ, PINT1_PJ_MARK), - PINMUX_GPIO(GPIO_FN_PINT0_PJ, PINT0_PJ_MARK), + GPIO_FN(IRQ7_PG), + GPIO_FN(IRQ6_PG), + GPIO_FN(IRQ5_PG), + GPIO_FN(IRQ4_PG), + GPIO_FN(IRQ3_PG), + GPIO_FN(IRQ2_PG), + GPIO_FN(IRQ1_PG), + GPIO_FN(IRQ0_PG), + GPIO_FN(IRQ7_PF), + GPIO_FN(IRQ6_PF), + GPIO_FN(IRQ5_PF), + GPIO_FN(IRQ4_PF), + GPIO_FN(IRQ3_PJ), + GPIO_FN(IRQ2_PJ), + GPIO_FN(IRQ1_PJ), + GPIO_FN(IRQ0_PJ), + GPIO_FN(IRQ1_PC), + GPIO_FN(IRQ0_PC), + + GPIO_FN(PINT7_PG), + GPIO_FN(PINT6_PG), + GPIO_FN(PINT5_PG), + GPIO_FN(PINT4_PG), + GPIO_FN(PINT3_PG), + GPIO_FN(PINT2_PG), + GPIO_FN(PINT1_PG), + GPIO_FN(PINT0_PG), + GPIO_FN(PINT7_PH), + GPIO_FN(PINT6_PH), + GPIO_FN(PINT5_PH), + GPIO_FN(PINT4_PH), + GPIO_FN(PINT3_PH), + GPIO_FN(PINT2_PH), + GPIO_FN(PINT1_PH), + GPIO_FN(PINT0_PH), + GPIO_FN(PINT7_PJ), + GPIO_FN(PINT6_PJ), + GPIO_FN(PINT5_PJ), + GPIO_FN(PINT4_PJ), + GPIO_FN(PINT3_PJ), + GPIO_FN(PINT2_PJ), + GPIO_FN(PINT1_PJ), + GPIO_FN(PINT0_PJ), /* WDT */ - PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK), + GPIO_FN(WDTOVF), /* CAN */ - PINMUX_GPIO(GPIO_FN_CTX1, CTX1_MARK), - PINMUX_GPIO(GPIO_FN_CRX1, CRX1_MARK), - PINMUX_GPIO(GPIO_FN_CTX0, CTX0_MARK), - PINMUX_GPIO(GPIO_FN_CRX0, CRX0_MARK), - PINMUX_GPIO(GPIO_FN_CRX0_CRX1, CRX0_CRX1_MARK), - PINMUX_GPIO(GPIO_FN_CRX0_CRX1_CRX2, CRX0_CRX1_CRX2_MARK), + GPIO_FN(CTX1), + GPIO_FN(CRX1), + GPIO_FN(CTX0), + GPIO_FN(CRX0), + GPIO_FN(CRX0_CRX1), + GPIO_FN(CRX0_CRX1_CRX2), /* DMAC */ - PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK), - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), + GPIO_FN(TEND0), + GPIO_FN(DACK0), + GPIO_FN(DREQ0), + GPIO_FN(TEND1), + GPIO_FN(DACK1), + GPIO_FN(DREQ1), /* ADC */ - PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK), + GPIO_FN(ADTRG), /* BSCh */ - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_A21, A21_MARK), - PINMUX_GPIO(GPIO_FN_A20, A20_MARK), - PINMUX_GPIO(GPIO_FN_A19, A19_MARK), - PINMUX_GPIO(GPIO_FN_A18, A18_MARK), - PINMUX_GPIO(GPIO_FN_A17, A17_MARK), - PINMUX_GPIO(GPIO_FN_A16, A16_MARK), - PINMUX_GPIO(GPIO_FN_A15, A15_MARK), - PINMUX_GPIO(GPIO_FN_A14, A14_MARK), - PINMUX_GPIO(GPIO_FN_A13, A13_MARK), - PINMUX_GPIO(GPIO_FN_A12, A12_MARK), - PINMUX_GPIO(GPIO_FN_A11, A11_MARK), - PINMUX_GPIO(GPIO_FN_A10, A10_MARK), - PINMUX_GPIO(GPIO_FN_A9, A9_MARK), - PINMUX_GPIO(GPIO_FN_A8, A8_MARK), - PINMUX_GPIO(GPIO_FN_A7, A7_MARK), - PINMUX_GPIO(GPIO_FN_A6, A6_MARK), - PINMUX_GPIO(GPIO_FN_A5, A5_MARK), - PINMUX_GPIO(GPIO_FN_A4, A4_MARK), - PINMUX_GPIO(GPIO_FN_A3, A3_MARK), - PINMUX_GPIO(GPIO_FN_A2, A2_MARK), - PINMUX_GPIO(GPIO_FN_A1, A1_MARK), - PINMUX_GPIO(GPIO_FN_A0, A0_MARK), - - PINMUX_GPIO(GPIO_FN_D15, D15_MARK), - PINMUX_GPIO(GPIO_FN_D14, D14_MARK), - PINMUX_GPIO(GPIO_FN_D13, D13_MARK), - PINMUX_GPIO(GPIO_FN_D12, D12_MARK), - PINMUX_GPIO(GPIO_FN_D11, D11_MARK), - PINMUX_GPIO(GPIO_FN_D10, D10_MARK), - PINMUX_GPIO(GPIO_FN_D9, D9_MARK), - PINMUX_GPIO(GPIO_FN_D8, D8_MARK), - PINMUX_GPIO(GPIO_FN_D7, D7_MARK), - PINMUX_GPIO(GPIO_FN_D6, D6_MARK), - PINMUX_GPIO(GPIO_FN_D5, D5_MARK), - PINMUX_GPIO(GPIO_FN_D4, D4_MARK), - PINMUX_GPIO(GPIO_FN_D3, D3_MARK), - PINMUX_GPIO(GPIO_FN_D2, D2_MARK), - PINMUX_GPIO(GPIO_FN_D1, D1_MARK), - PINMUX_GPIO(GPIO_FN_D0, D0_MARK), - - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK), - PINMUX_GPIO(GPIO_FN_CS3, CS3_MARK), - PINMUX_GPIO(GPIO_FN_CS2, CS2_MARK), - PINMUX_GPIO(GPIO_FN_CS1, CS1_MARK), - PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK), - PINMUX_GPIO(GPIO_FN_CS5CE1A, CS5CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_RD, RD_MARK), - PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK), - PINMUX_GPIO(GPIO_FN_WE3ICIOWRAHDQMUU, WE3ICIOWRAHDQMUU_MARK), - PINMUX_GPIO(GPIO_FN_WE2ICIORDDQMUL, WE2ICIORDDQMUL_MARK), - PINMUX_GPIO(GPIO_FN_WE1DQMUWE, WE1DQMUWE_MARK), - PINMUX_GPIO(GPIO_FN_WE0DQML, WE0DQML_MARK), - PINMUX_GPIO(GPIO_FN_RAS, RAS_MARK), - PINMUX_GPIO(GPIO_FN_CAS, CAS_MARK), - PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK), - PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(A21), + GPIO_FN(A20), + GPIO_FN(A19), + GPIO_FN(A18), + GPIO_FN(A17), + GPIO_FN(A16), + GPIO_FN(A15), + GPIO_FN(A14), + GPIO_FN(A13), + GPIO_FN(A12), + GPIO_FN(A11), + GPIO_FN(A10), + GPIO_FN(A9), + GPIO_FN(A8), + GPIO_FN(A7), + GPIO_FN(A6), + GPIO_FN(A5), + GPIO_FN(A4), + GPIO_FN(A3), + GPIO_FN(A2), + GPIO_FN(A1), + GPIO_FN(A0), + + GPIO_FN(D15), + GPIO_FN(D14), + GPIO_FN(D13), + GPIO_FN(D12), + GPIO_FN(D11), + GPIO_FN(D10), + GPIO_FN(D9), + GPIO_FN(D8), + GPIO_FN(D7), + GPIO_FN(D6), + GPIO_FN(D5), + GPIO_FN(D4), + GPIO_FN(D3), + GPIO_FN(D2), + GPIO_FN(D1), + GPIO_FN(D0), + + GPIO_FN(BS), + GPIO_FN(CS4), + GPIO_FN(CS3), + GPIO_FN(CS2), + GPIO_FN(CS1), + GPIO_FN(CS0), + GPIO_FN(CS5CE1A), + GPIO_FN(CE2A), + GPIO_FN(CE2B), + GPIO_FN(RD), + GPIO_FN(RDWR), + GPIO_FN(WE3ICIOWRAHDQMUU), + GPIO_FN(WE2ICIORDDQMUL), + GPIO_FN(WE1DQMUWE), + GPIO_FN(WE0DQML), + GPIO_FN(RAS), + GPIO_FN(CAS), + GPIO_FN(CKE), + GPIO_FN(WAIT), + GPIO_FN(BREQ), + GPIO_FN(BACK), + GPIO_FN(IOIS16), /* TMU */ - PINMUX_GPIO(GPIO_FN_TIOC4D, TIOC4D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4C, TIOC4C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4B, TIOC4B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC4A, TIOC4A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3D, TIOC3D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3C, TIOC3C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3B, TIOC3B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC3A, TIOC3A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2B, TIOC2B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1B, TIOC1B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC2A, TIOC2A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC1A, TIOC1A_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0D, TIOC0D_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0C, TIOC0C_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0B, TIOC0B_MARK), - PINMUX_GPIO(GPIO_FN_TIOC0A, TIOC0A_MARK), - PINMUX_GPIO(GPIO_FN_TCLKD, TCLKD_MARK), - PINMUX_GPIO(GPIO_FN_TCLKC, TCLKC_MARK), - PINMUX_GPIO(GPIO_FN_TCLKB, TCLKB_MARK), - PINMUX_GPIO(GPIO_FN_TCLKA, TCLKA_MARK), + GPIO_FN(TIOC4D), + GPIO_FN(TIOC4C), + GPIO_FN(TIOC4B), + GPIO_FN(TIOC4A), + GPIO_FN(TIOC3D), + GPIO_FN(TIOC3C), + GPIO_FN(TIOC3B), + GPIO_FN(TIOC3A), + GPIO_FN(TIOC2B), + GPIO_FN(TIOC1B), + GPIO_FN(TIOC2A), + GPIO_FN(TIOC1A), + GPIO_FN(TIOC0D), + GPIO_FN(TIOC0C), + GPIO_FN(TIOC0B), + GPIO_FN(TIOC0A), + GPIO_FN(TCLKD), + GPIO_FN(TCLKC), + GPIO_FN(TCLKB), + GPIO_FN(TCLKA), /* SCIF */ - PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK), - PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK), - PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK), - PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK), - PINMUX_GPIO(GPIO_FN_RTS1, RTS1_MARK), - PINMUX_GPIO(GPIO_FN_CTS1, CTS1_MARK), - PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK), - PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK), - PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK), - PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK), - PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK), - PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK), - PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK), - PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK), - PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK), - PINMUX_GPIO(GPIO_FN_SCK5, SCK5_MARK), - PINMUX_GPIO(GPIO_FN_TXD5, TXD5_MARK), - PINMUX_GPIO(GPIO_FN_RXD5, RXD5_MARK), - PINMUX_GPIO(GPIO_FN_RTS5, RTS5_MARK), - PINMUX_GPIO(GPIO_FN_CTS5, CTS5_MARK), - PINMUX_GPIO(GPIO_FN_SCK6, SCK6_MARK), - PINMUX_GPIO(GPIO_FN_TXD6, TXD6_MARK), - PINMUX_GPIO(GPIO_FN_RXD6, RXD6_MARK), - PINMUX_GPIO(GPIO_FN_SCK7, SCK7_MARK), - PINMUX_GPIO(GPIO_FN_TXD7, TXD7_MARK), - PINMUX_GPIO(GPIO_FN_RXD7, RXD7_MARK), - PINMUX_GPIO(GPIO_FN_RTS7, RTS7_MARK), - PINMUX_GPIO(GPIO_FN_CTS7, CTS7_MARK), + GPIO_FN(SCK0), + GPIO_FN(TXD0), + GPIO_FN(RXD0), + GPIO_FN(SCK1), + GPIO_FN(TXD1), + GPIO_FN(RXD1), + GPIO_FN(RTS1), + GPIO_FN(CTS1), + GPIO_FN(SCK2), + GPIO_FN(TXD2), + GPIO_FN(RXD2), + GPIO_FN(SCK3), + GPIO_FN(TXD3), + GPIO_FN(RXD3), + GPIO_FN(SCK4), + GPIO_FN(TXD4), + GPIO_FN(RXD4), + GPIO_FN(SCK5), + GPIO_FN(TXD5), + GPIO_FN(RXD5), + GPIO_FN(RTS5), + GPIO_FN(CTS5), + GPIO_FN(SCK6), + GPIO_FN(TXD6), + GPIO_FN(RXD6), + GPIO_FN(SCK7), + GPIO_FN(TXD7), + GPIO_FN(RXD7), + GPIO_FN(RTS7), + GPIO_FN(CTS7), /* RSPI */ - PINMUX_GPIO(GPIO_FN_RSPCK0_PJ16, RSPCK0_PJ16_MARK), - PINMUX_GPIO(GPIO_FN_SSL00_PJ17, SSL00_PJ17_MARK), - PINMUX_GPIO(GPIO_FN_MOSI0_PJ18, MOSI0_PJ18_MARK), - PINMUX_GPIO(GPIO_FN_MISO0_PJ19, MISO0_PJ19_MARK), - PINMUX_GPIO(GPIO_FN_RSPCK0_PB17, RSPCK0_PB17_MARK), - PINMUX_GPIO(GPIO_FN_SSL00_PB18, SSL00_PB18_MARK), - PINMUX_GPIO(GPIO_FN_MOSI0_PB19, MOSI0_PB19_MARK), - PINMUX_GPIO(GPIO_FN_MISO0_PB20, MISO0_PB20_MARK), - PINMUX_GPIO(GPIO_FN_RSPCK1, RSPCK1_MARK), - PINMUX_GPIO(GPIO_FN_MOSI1, MOSI1_MARK), - PINMUX_GPIO(GPIO_FN_MISO1, MISO1_MARK), - PINMUX_GPIO(GPIO_FN_SSL10, SSL10_MARK), + GPIO_FN(RSPCK0_PJ16), + GPIO_FN(SSL00_PJ17), + GPIO_FN(MOSI0_PJ18), + GPIO_FN(MISO0_PJ19), + GPIO_FN(RSPCK0_PB17), + GPIO_FN(SSL00_PB18), + GPIO_FN(MOSI0_PB19), + GPIO_FN(MISO0_PB20), + GPIO_FN(RSPCK1), + GPIO_FN(MOSI1), + GPIO_FN(MISO1), + GPIO_FN(SSL10), /* IIC3 */ - PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK), - PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK), - PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK), - PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK), - PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK), - PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK), + GPIO_FN(SCL0), + GPIO_FN(SCL1), + GPIO_FN(SCL2), + GPIO_FN(SDA0), + GPIO_FN(SDA1), + GPIO_FN(SDA2), /* SSI */ - PINMUX_GPIO(GPIO_FN_SSISCK0, SSISCK0_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS0, SSIWS0_MARK), - PINMUX_GPIO(GPIO_FN_SSITXD0, SSITXD0_MARK), - PINMUX_GPIO(GPIO_FN_SSIRXD0, SSIRXD0_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS1, SSIWS1_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS2, SSIWS2_MARK), - PINMUX_GPIO(GPIO_FN_SSIWS3, SSIWS3_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK1, SSISCK1_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK2, SSISCK2_MARK), - PINMUX_GPIO(GPIO_FN_SSISCK3, SSISCK3_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA1, SSIDATA1_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA2, SSIDATA2_MARK), - PINMUX_GPIO(GPIO_FN_SSIDATA3, SSIDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDIO_CLK, AUDIO_CLK_MARK), - PINMUX_GPIO(GPIO_FN_AUDIO_XOUT, AUDIO_XOUT_MARK), + GPIO_FN(SSISCK0), + GPIO_FN(SSIWS0), + GPIO_FN(SSITXD0), + GPIO_FN(SSIRXD0), + GPIO_FN(SSIWS1), + GPIO_FN(SSIWS2), + GPIO_FN(SSIWS3), + GPIO_FN(SSISCK1), + GPIO_FN(SSISCK2), + GPIO_FN(SSISCK3), + GPIO_FN(SSIDATA1), + GPIO_FN(SSIDATA2), + GPIO_FN(SSIDATA3), + GPIO_FN(AUDIO_CLK), + GPIO_FN(AUDIO_XOUT), /* SIOF */ /* NOTE Shares AUDIO_CLK with SSI */ - PINMUX_GPIO(GPIO_FN_SIOFTXD, SIOFTXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOFRXD, SIOFRXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOFSYNC, SIOFSYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOFSCK, SIOFSCK_MARK), + GPIO_FN(SIOFTXD), + GPIO_FN(SIOFRXD), + GPIO_FN(SIOFSYNC), + GPIO_FN(SIOFSCK), /* SPDIF */ /* NOTE Shares AUDIO_CLK with SSI */ - PINMUX_GPIO(GPIO_FN_SPDIF_IN, SPDIF_IN_MARK), - PINMUX_GPIO(GPIO_FN_SPDIF_OUT, SPDIF_OUT_MARK), + GPIO_FN(SPDIF_IN), + GPIO_FN(SPDIF_OUT), /* NANDFMC */ /* NOTE Controller is not available in boot mode 0 */ - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), + GPIO_FN(FCE), + GPIO_FN(FRB), /* VDC3 */ - PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), - - PINMUX_GPIO(GPIO_FN_DV_DATA23, DV_DATA23_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA22, DV_DATA22_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA21, DV_DATA21_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA20, DV_DATA20_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA19, DV_DATA19_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA18, DV_DATA18_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA17, DV_DATA17_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA16, DV_DATA16_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA15, DV_DATA15_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA14, DV_DATA14_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA13, DV_DATA13_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA12, DV_DATA12_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA11, DV_DATA11_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA10, DV_DATA10_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA9, DV_DATA9_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA8, DV_DATA8_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA7, DV_DATA7_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA6, DV_DATA6_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA5, DV_DATA5_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA4, DV_DATA4_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA3, DV_DATA3_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA2, DV_DATA2_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA1, DV_DATA1_MARK), - PINMUX_GPIO(GPIO_FN_DV_DATA0, DV_DATA0_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_CLK, LCD_CLK_MARK), - PINMUX_GPIO(GPIO_FN_LCD_EXTCLK, LCD_EXTCLK_MARK), - PINMUX_GPIO(GPIO_FN_LCD_VSYNC, LCD_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_HSYNC, LCD_HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DE, LCD_DE_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_DATA23_PG23, LCD_DATA23_PG23_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA22_PG22, LCD_DATA22_PG22_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA21_PG21, LCD_DATA21_PG21_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA20_PG20, LCD_DATA20_PG20_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA19_PG19, LCD_DATA19_PG19_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA18_PG18, LCD_DATA18_PG18_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA17_PG17, LCD_DATA17_PG17_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA16_PG16, LCD_DATA16_PG16_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA15_PG15, LCD_DATA15_PG15_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA14_PG14, LCD_DATA14_PG14_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA13_PG13, LCD_DATA13_PG13_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA12_PG12, LCD_DATA12_PG12_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA11_PG11, LCD_DATA11_PG11_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA10_PG10, LCD_DATA10_PG10_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA9_PG9, LCD_DATA9_PG9_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA8_PG8, LCD_DATA8_PG8_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA7_PG7, LCD_DATA7_PG7_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA6_PG6, LCD_DATA6_PG6_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA5_PG5, LCD_DATA5_PG5_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA4_PG4, LCD_DATA4_PG4_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA3_PG3, LCD_DATA3_PG3_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA2_PG2, LCD_DATA2_PG2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA1_PG1, LCD_DATA1_PG1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA0_PG0, LCD_DATA0_PG0_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_DATA23_PJ23, LCD_DATA23_PJ23_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA22_PJ22, LCD_DATA22_PJ22_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA21_PJ21, LCD_DATA21_PJ21_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA20_PJ20, LCD_DATA20_PJ20_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA19_PJ19, LCD_DATA19_PJ19_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA18_PJ18, LCD_DATA18_PJ18_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA17_PJ17, LCD_DATA17_PJ17_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA16_PJ16, LCD_DATA16_PJ16_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA15_PJ15, LCD_DATA15_PJ15_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA14_PJ14, LCD_DATA14_PJ14_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA13_PJ13, LCD_DATA13_PJ13_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA12_PJ12, LCD_DATA12_PJ12_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA11_PJ11, LCD_DATA11_PJ11_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA10_PJ10, LCD_DATA10_PJ10_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA9_PJ9, LCD_DATA9_PJ9_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA8_PJ8, LCD_DATA8_PJ8_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA7_PJ7, LCD_DATA7_PJ7_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA6_PJ6, LCD_DATA6_PJ6_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA5_PJ5, LCD_DATA5_PJ5_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA4_PJ4, LCD_DATA4_PJ4_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA3_PJ3, LCD_DATA3_PJ3_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA2_PJ2, LCD_DATA2_PJ2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA1_PJ1, LCD_DATA1_PJ1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA0_PJ0, LCD_DATA0_PJ0_MARK), - - PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), + GPIO_FN(DV_CLK), + GPIO_FN(DV_VSYNC), + GPIO_FN(DV_HSYNC), + + GPIO_FN(DV_DATA23), + GPIO_FN(DV_DATA22), + GPIO_FN(DV_DATA21), + GPIO_FN(DV_DATA20), + GPIO_FN(DV_DATA19), + GPIO_FN(DV_DATA18), + GPIO_FN(DV_DATA17), + GPIO_FN(DV_DATA16), + GPIO_FN(DV_DATA15), + GPIO_FN(DV_DATA14), + GPIO_FN(DV_DATA13), + GPIO_FN(DV_DATA12), + GPIO_FN(DV_DATA11), + GPIO_FN(DV_DATA10), + GPIO_FN(DV_DATA9), + GPIO_FN(DV_DATA8), + GPIO_FN(DV_DATA7), + GPIO_FN(DV_DATA6), + GPIO_FN(DV_DATA5), + GPIO_FN(DV_DATA4), + GPIO_FN(DV_DATA3), + GPIO_FN(DV_DATA2), + GPIO_FN(DV_DATA1), + GPIO_FN(DV_DATA0), + + GPIO_FN(LCD_CLK), + GPIO_FN(LCD_EXTCLK), + GPIO_FN(LCD_VSYNC), + GPIO_FN(LCD_HSYNC), + GPIO_FN(LCD_DE), + + GPIO_FN(LCD_DATA23_PG23), + GPIO_FN(LCD_DATA22_PG22), + GPIO_FN(LCD_DATA21_PG21), + GPIO_FN(LCD_DATA20_PG20), + GPIO_FN(LCD_DATA19_PG19), + GPIO_FN(LCD_DATA18_PG18), + GPIO_FN(LCD_DATA17_PG17), + GPIO_FN(LCD_DATA16_PG16), + GPIO_FN(LCD_DATA15_PG15), + GPIO_FN(LCD_DATA14_PG14), + GPIO_FN(LCD_DATA13_PG13), + GPIO_FN(LCD_DATA12_PG12), + GPIO_FN(LCD_DATA11_PG11), + GPIO_FN(LCD_DATA10_PG10), + GPIO_FN(LCD_DATA9_PG9), + GPIO_FN(LCD_DATA8_PG8), + GPIO_FN(LCD_DATA7_PG7), + GPIO_FN(LCD_DATA6_PG6), + GPIO_FN(LCD_DATA5_PG5), + GPIO_FN(LCD_DATA4_PG4), + GPIO_FN(LCD_DATA3_PG3), + GPIO_FN(LCD_DATA2_PG2), + GPIO_FN(LCD_DATA1_PG1), + GPIO_FN(LCD_DATA0_PG0), + + GPIO_FN(LCD_DATA23_PJ23), + GPIO_FN(LCD_DATA22_PJ22), + GPIO_FN(LCD_DATA21_PJ21), + GPIO_FN(LCD_DATA20_PJ20), + GPIO_FN(LCD_DATA19_PJ19), + GPIO_FN(LCD_DATA18_PJ18), + GPIO_FN(LCD_DATA17_PJ17), + GPIO_FN(LCD_DATA16_PJ16), + GPIO_FN(LCD_DATA15_PJ15), + GPIO_FN(LCD_DATA14_PJ14), + GPIO_FN(LCD_DATA13_PJ13), + GPIO_FN(LCD_DATA12_PJ12), + GPIO_FN(LCD_DATA11_PJ11), + GPIO_FN(LCD_DATA10_PJ10), + GPIO_FN(LCD_DATA9_PJ9), + GPIO_FN(LCD_DATA8_PJ8), + GPIO_FN(LCD_DATA7_PJ7), + GPIO_FN(LCD_DATA6_PJ6), + GPIO_FN(LCD_DATA5_PJ5), + GPIO_FN(LCD_DATA4_PJ4), + GPIO_FN(LCD_DATA3_PJ3), + GPIO_FN(LCD_DATA2_PJ2), + GPIO_FN(LCD_DATA1_PJ1), + GPIO_FN(LCD_DATA0_PJ0), + + GPIO_FN(LCD_M_DISP), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 10872ed688a6..e2e4520a14c4 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -761,197 +761,196 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTV0, PTV0_DATA), /* BSC */ - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_RAS, RAS_MARK), - PINMUX_GPIO(GPIO_FN_CAS, CAS_MARK), - PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK), - PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_A21, A21_MARK), - PINMUX_GPIO(GPIO_FN_A20, A20_MARK), - PINMUX_GPIO(GPIO_FN_A19, A19_MARK), - PINMUX_GPIO(GPIO_FN_A0, A0_MARK), - PINMUX_GPIO(GPIO_FN_REFOUT, REFOUT_MARK), - PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(IOIS16), + GPIO_FN(RAS), + GPIO_FN(CAS), + GPIO_FN(CKE), + GPIO_FN(CS5B_CE1A), + GPIO_FN(CS6B_CE1B), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(A21), + GPIO_FN(A20), + GPIO_FN(A19), + GPIO_FN(A0), + GPIO_FN(REFOUT), + GPIO_FN(IRQOUT), /* LCDC */ - PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK), - PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), - PINMUX_GPIO(GPIO_FN_LCD_CL1, LCD_CL1_MARK), - PINMUX_GPIO(GPIO_FN_LCD_CL2, LCD_CL2_MARK), - PINMUX_GPIO(GPIO_FN_LCD_DON, LCD_DON_MARK), - PINMUX_GPIO(GPIO_FN_LCD_FLM, LCD_FLM_MARK), - PINMUX_GPIO(GPIO_FN_LCD_VEPWC, LCD_VEPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCD_VCPWC, LCD_VCPWC_MARK), + GPIO_FN(LCD_DATA15), + GPIO_FN(LCD_DATA14), + GPIO_FN(LCD_DATA13), + GPIO_FN(LCD_DATA12), + GPIO_FN(LCD_DATA11), + GPIO_FN(LCD_DATA10), + GPIO_FN(LCD_DATA9), + GPIO_FN(LCD_DATA8), + GPIO_FN(LCD_DATA7), + GPIO_FN(LCD_DATA6), + GPIO_FN(LCD_DATA5), + GPIO_FN(LCD_DATA4), + GPIO_FN(LCD_DATA3), + GPIO_FN(LCD_DATA2), + GPIO_FN(LCD_DATA1), + GPIO_FN(LCD_DATA0), + GPIO_FN(LCD_M_DISP), + GPIO_FN(LCD_CL1), + GPIO_FN(LCD_CL2), + GPIO_FN(LCD_DON), + GPIO_FN(LCD_FLM), + GPIO_FN(LCD_VEPWC), + GPIO_FN(LCD_VCPWC), /* AFEIF */ - PINMUX_GPIO(GPIO_FN_AFE_RXIN, AFE_RXIN_MARK), - PINMUX_GPIO(GPIO_FN_AFE_RDET, AFE_RDET_MARK), - PINMUX_GPIO(GPIO_FN_AFE_FS, AFE_FS_MARK), - PINMUX_GPIO(GPIO_FN_AFE_TXOUT, AFE_TXOUT_MARK), - PINMUX_GPIO(GPIO_FN_AFE_SCLK, AFE_SCLK_MARK), - PINMUX_GPIO(GPIO_FN_AFE_RLYCNT, AFE_RLYCNT_MARK), - PINMUX_GPIO(GPIO_FN_AFE_HC1, AFE_HC1_MARK), + GPIO_FN(AFE_RXIN), + GPIO_FN(AFE_RDET), + GPIO_FN(AFE_FS), + GPIO_FN(AFE_TXOUT), + GPIO_FN(AFE_SCLK), + GPIO_FN(AFE_RLYCNT), + GPIO_FN(AFE_HC1), /* IIC */ - PINMUX_GPIO(GPIO_FN_IIC_SCL, IIC_SCL_MARK), - PINMUX_GPIO(GPIO_FN_IIC_SDA, IIC_SDA_MARK), + GPIO_FN(IIC_SCL), + GPIO_FN(IIC_SDA), /* DAC */ - PINMUX_GPIO(GPIO_FN_DA1, DA1_MARK), - PINMUX_GPIO(GPIO_FN_DA0, DA0_MARK), + GPIO_FN(DA1), + GPIO_FN(DA0), /* ADC */ - PINMUX_GPIO(GPIO_FN_AN3, AN3_MARK), - PINMUX_GPIO(GPIO_FN_AN2, AN2_MARK), - PINMUX_GPIO(GPIO_FN_AN1, AN1_MARK), - PINMUX_GPIO(GPIO_FN_AN0, AN0_MARK), - PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK), + GPIO_FN(AN3), + GPIO_FN(AN2), + GPIO_FN(AN1), + GPIO_FN(AN0), + GPIO_FN(ADTRG), /* USB */ - PINMUX_GPIO(GPIO_FN_USB1D_RCV, USB1D_RCV_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_TXSE0, USB1D_TXSE0_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_TXDPLS, USB1D_TXDPLS_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_DMNS, USB1D_DMNS_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_DPLS, USB1D_DPLS_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_SPEED, USB1D_SPEED_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_TXENL, USB1D_TXENL_MARK), - - PINMUX_GPIO(GPIO_FN_USB2_PWR_EN, USB2_PWR_EN_MARK), - PINMUX_GPIO(GPIO_FN_USB1_PWR_EN_USBF_UPLUP, - USB1_PWR_EN_USBF_UPLUP_MARK), - PINMUX_GPIO(GPIO_FN_USB1D_SUSPEND, USB1D_SUSPEND_MARK), + GPIO_FN(USB1D_RCV), + GPIO_FN(USB1D_TXSE0), + GPIO_FN(USB1D_TXDPLS), + GPIO_FN(USB1D_DMNS), + GPIO_FN(USB1D_DPLS), + GPIO_FN(USB1D_SPEED), + GPIO_FN(USB1D_TXENL), + + GPIO_FN(USB2_PWR_EN), + GPIO_FN(USB1_PWR_EN_USBF_UPLUP), + GPIO_FN(USB1D_SUSPEND), /* INTC */ - PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3_IRL3, IRQ3_IRL3_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2_IRL2, IRQ2_IRL2_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1_IRL1, IRQ1_IRL1_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0_IRL0, IRQ0_IRL0_MARK), + GPIO_FN(IRQ5), + GPIO_FN(IRQ4), + GPIO_FN(IRQ3_IRL3), + GPIO_FN(IRQ2_IRL2), + GPIO_FN(IRQ1_IRL1), + GPIO_FN(IRQ0_IRL0), /* PCC */ - PINMUX_GPIO(GPIO_FN_PCC_REG, PCC_REG_MARK), - PINMUX_GPIO(GPIO_FN_PCC_DRV, PCC_DRV_MARK), - PINMUX_GPIO(GPIO_FN_PCC_BVD2, PCC_BVD2_MARK), - PINMUX_GPIO(GPIO_FN_PCC_BVD1, PCC_BVD1_MARK), - PINMUX_GPIO(GPIO_FN_PCC_CD2, PCC_CD2_MARK), - PINMUX_GPIO(GPIO_FN_PCC_CD1, PCC_CD1_MARK), - PINMUX_GPIO(GPIO_FN_PCC_RESET, PCC_RESET_MARK), - PINMUX_GPIO(GPIO_FN_PCC_RDY, PCC_RDY_MARK), - PINMUX_GPIO(GPIO_FN_PCC_VS2, PCC_VS2_MARK), - PINMUX_GPIO(GPIO_FN_PCC_VS1, PCC_VS1_MARK), + GPIO_FN(PCC_REG), + GPIO_FN(PCC_DRV), + GPIO_FN(PCC_BVD2), + GPIO_FN(PCC_BVD1), + GPIO_FN(PCC_CD2), + GPIO_FN(PCC_CD1), + GPIO_FN(PCC_RESET), + GPIO_FN(PCC_RDY), + GPIO_FN(PCC_VS2), + GPIO_FN(PCC_VS1), /* HUDI */ - PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), - PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK), - PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), - PINMUX_GPIO(GPIO_FN_ASEBRKAK, ASEBRKAK_MARK), - PINMUX_GPIO(GPIO_FN_TRST, TRST_MARK), - PINMUX_GPIO(GPIO_FN_TMS, TMS_MARK), - PINMUX_GPIO(GPIO_FN_TDO, TDO_MARK), - PINMUX_GPIO(GPIO_FN_TDI, TDI_MARK), - PINMUX_GPIO(GPIO_FN_TCK, TCK_MARK), + GPIO_FN(AUDATA3), + GPIO_FN(AUDATA2), + GPIO_FN(AUDATA1), + GPIO_FN(AUDATA0), + GPIO_FN(AUDCK), + GPIO_FN(AUDSYNC), + GPIO_FN(ASEBRKAK), + GPIO_FN(TRST), + GPIO_FN(TMS), + GPIO_FN(TDO), + GPIO_FN(TDI), + GPIO_FN(TCK), /* DMAC */ - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK), - PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK), + GPIO_FN(DACK1), + GPIO_FN(DREQ1), + GPIO_FN(DACK0), + GPIO_FN(DREQ0), + GPIO_FN(TEND1), + GPIO_FN(TEND0), /* SIOF0 */ - PINMUX_GPIO(GPIO_FN_SIOF0_SYNC, SIOF0_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_MCLK, SIOF0_MCLK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_TXD, SIOF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_RXD, SIOF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_SCK, SIOF0_SCK_MARK), + GPIO_FN(SIOF0_SYNC), + GPIO_FN(SIOF0_MCLK), + GPIO_FN(SIOF0_TXD), + GPIO_FN(SIOF0_RXD), + GPIO_FN(SIOF0_SCK), /* SIOF1 */ - PINMUX_GPIO(GPIO_FN_SIOF1_SYNC, SIOF1_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_MCLK, SIOF1_MCLK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_TXD, SIOF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_RXD, SIOF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_SCK, SIOF1_SCK_MARK), + GPIO_FN(SIOF1_SYNC), + GPIO_FN(SIOF1_MCLK), + GPIO_FN(SIOF1_TXD), + GPIO_FN(SIOF1_RXD), + GPIO_FN(SIOF1_SCK), /* SCIF0 */ - PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), + GPIO_FN(SCIF0_TXD), + GPIO_FN(SCIF0_RXD), + GPIO_FN(SCIF0_RTS), + GPIO_FN(SCIF0_CTS), + GPIO_FN(SCIF0_SCK), /* SCIF1 */ - PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RTS, SCIF1_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_CTS, SCIF1_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), + GPIO_FN(SCIF1_TXD), + GPIO_FN(SCIF1_RXD), + GPIO_FN(SCIF1_RTS), + GPIO_FN(SCIF1_CTS), + GPIO_FN(SCIF1_SCK), /* TPU */ - PINMUX_GPIO(GPIO_FN_TPU_TO1, TPU_TO1_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TO0, TPU_TO0_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TI3B, TPU_TI3B_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TI3A, TPU_TI3A_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TI2B, TPU_TI2B_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TI2A, TPU_TI2A_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TO3, TPU_TO3_MARK), - PINMUX_GPIO(GPIO_FN_TPU_TO2, TPU_TO2_MARK), + GPIO_FN(TPU_TO1), + GPIO_FN(TPU_TO0), + GPIO_FN(TPU_TI3B), + GPIO_FN(TPU_TI3A), + GPIO_FN(TPU_TI2B), + GPIO_FN(TPU_TI2A), + GPIO_FN(TPU_TO3), + GPIO_FN(TPU_TO2), /* SIM */ - PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK), - PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK), + GPIO_FN(SIM_D), + GPIO_FN(SIM_CLK), + GPIO_FN(SIM_RST), /* MMC */ - PINMUX_GPIO(GPIO_FN_MMC_DAT, MMC_DAT_MARK), - PINMUX_GPIO(GPIO_FN_MMC_CMD, MMC_CMD_MARK), - PINMUX_GPIO(GPIO_FN_MMC_CLK, MMC_CLK_MARK), - PINMUX_GPIO(GPIO_FN_MMC_VDDON, MMC_VDDON_MARK), - PINMUX_GPIO(GPIO_FN_MMC_ODMOD, MMC_ODMOD_MARK), + GPIO_FN(MMC_DAT), + GPIO_FN(MMC_CMD), + GPIO_FN(MMC_CLK), + GPIO_FN(MMC_VDDON), + GPIO_FN(MMC_ODMOD), /* SYSC */ - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), - PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK), + GPIO_FN(STATUS0), + GPIO_FN(STATUS1), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index 2de0929315e6..225fa96b6a21 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -984,284 +984,284 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), /* SCIF0 */ - PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), + GPIO_FN(SCIF0_TXD), + GPIO_FN(SCIF0_RXD), + GPIO_FN(SCIF0_RTS), + GPIO_FN(SCIF0_CTS), + GPIO_FN(SCIF0_SCK), /* SCIF1 */ - PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RTS, SCIF1_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_CTS, SCIF1_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), + GPIO_FN(SCIF1_TXD), + GPIO_FN(SCIF1_RXD), + GPIO_FN(SCIF1_RTS), + GPIO_FN(SCIF1_CTS), + GPIO_FN(SCIF1_SCK), /* SCIF2 */ - PINMUX_GPIO(GPIO_FN_SCIF2_TXD, SCIF2_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_RXD, SCIF2_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_RTS, SCIF2_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_CTS, SCIF2_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_SCK, SCIF2_SCK_MARK), + GPIO_FN(SCIF2_TXD), + GPIO_FN(SCIF2_RXD), + GPIO_FN(SCIF2_RTS), + GPIO_FN(SCIF2_CTS), + GPIO_FN(SCIF2_SCK), /* SIO */ - PINMUX_GPIO(GPIO_FN_SIOTXD, SIOTXD_MARK), - PINMUX_GPIO(GPIO_FN_SIORXD, SIORXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOD, SIOD_MARK), - PINMUX_GPIO(GPIO_FN_SIOSTRB0, SIOSTRB0_MARK), - PINMUX_GPIO(GPIO_FN_SIOSTRB1, SIOSTRB1_MARK), - PINMUX_GPIO(GPIO_FN_SIOSCK, SIOSCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOMCK, SIOMCK_MARK), + GPIO_FN(SIOTXD), + GPIO_FN(SIORXD), + GPIO_FN(SIOD), + GPIO_FN(SIOSTRB0), + GPIO_FN(SIOSTRB1), + GPIO_FN(SIOSCK), + GPIO_FN(SIOMCK), /* CEU */ - PINMUX_GPIO(GPIO_FN_VIO_D15, VIO_D15_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D14, VIO_D14_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D13, VIO_D13_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D12, VIO_D12_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D11, VIO_D11_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D10, VIO_D10_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D9, VIO_D9_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D8, VIO_D8_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D7, VIO_D7_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D6, VIO_D6_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D5, VIO_D5_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D4, VIO_D4_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D3, VIO_D3_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D2, VIO_D2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D1, VIO_D1_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D0, VIO_D0_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CLK, VIO_CLK_MARK), - PINMUX_GPIO(GPIO_FN_VIO_VD, VIO_VD_MARK), - PINMUX_GPIO(GPIO_FN_VIO_HD, VIO_HD_MARK), - PINMUX_GPIO(GPIO_FN_VIO_FLD, VIO_FLD_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK), - PINMUX_GPIO(GPIO_FN_VIO_STEX, VIO_STEX_MARK), - PINMUX_GPIO(GPIO_FN_VIO_STEM, VIO_STEM_MARK), - PINMUX_GPIO(GPIO_FN_VIO_VD2, VIO_VD2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_HD2, VIO_HD2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CLK2, VIO_CLK2_MARK), + GPIO_FN(VIO_D15), + GPIO_FN(VIO_D14), + GPIO_FN(VIO_D13), + GPIO_FN(VIO_D12), + GPIO_FN(VIO_D11), + GPIO_FN(VIO_D10), + GPIO_FN(VIO_D9), + GPIO_FN(VIO_D8), + GPIO_FN(VIO_D7), + GPIO_FN(VIO_D6), + GPIO_FN(VIO_D5), + GPIO_FN(VIO_D4), + GPIO_FN(VIO_D3), + GPIO_FN(VIO_D2), + GPIO_FN(VIO_D1), + GPIO_FN(VIO_D0), + GPIO_FN(VIO_CLK), + GPIO_FN(VIO_VD), + GPIO_FN(VIO_HD), + GPIO_FN(VIO_FLD), + GPIO_FN(VIO_CKO), + GPIO_FN(VIO_STEX), + GPIO_FN(VIO_STEM), + GPIO_FN(VIO_VD2), + GPIO_FN(VIO_HD2), + GPIO_FN(VIO_CLK2), /* LCDC */ - PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK), - PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK), - PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK), - PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK), - PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK), - PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK), - PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK), - PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK), - PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK), - PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK), - PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK), - PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK), - PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK), - PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK), - PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK), - PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK), - PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK), - PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK), - PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK), - PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK), - PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK), - PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK), - PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK), - PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK), - PINMUX_GPIO(GPIO_FN_LCDLCLK, LCDLCLK_MARK), + GPIO_FN(LCDD23), + GPIO_FN(LCDD22), + GPIO_FN(LCDD21), + GPIO_FN(LCDD20), + GPIO_FN(LCDD19), + GPIO_FN(LCDD18), + GPIO_FN(LCDD17), + GPIO_FN(LCDD16), + GPIO_FN(LCDD15), + GPIO_FN(LCDD14), + GPIO_FN(LCDD13), + GPIO_FN(LCDD12), + GPIO_FN(LCDD11), + GPIO_FN(LCDD10), + GPIO_FN(LCDD9), + GPIO_FN(LCDD8), + GPIO_FN(LCDD7), + GPIO_FN(LCDD6), + GPIO_FN(LCDD5), + GPIO_FN(LCDD4), + GPIO_FN(LCDD3), + GPIO_FN(LCDD2), + GPIO_FN(LCDD1), + GPIO_FN(LCDD0), + GPIO_FN(LCDLCLK), /* Main LCD */ - PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK), - PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK), + GPIO_FN(LCDDON), + GPIO_FN(LCDVCPWC), + GPIO_FN(LCDVEPWC), + GPIO_FN(LCDVSYN), /* Main LCD - RGB Mode */ - PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK), - PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK), - PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK), + GPIO_FN(LCDDCK), + GPIO_FN(LCDHSYN), + GPIO_FN(LCDDISP), /* Main LCD - SYS Mode */ - PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK), - PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK), - PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK), - PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK), + GPIO_FN(LCDRS), + GPIO_FN(LCDCS), + GPIO_FN(LCDWR), + GPIO_FN(LCDRD), /* Sub LCD - SYS Mode */ - PINMUX_GPIO(GPIO_FN_LCDDON2, LCDDON2_MARK), - PINMUX_GPIO(GPIO_FN_LCDVCPWC2, LCDVCPWC2_MARK), - PINMUX_GPIO(GPIO_FN_LCDVEPWC2, LCDVEPWC2_MARK), - PINMUX_GPIO(GPIO_FN_LCDVSYN2, LCDVSYN2_MARK), - PINMUX_GPIO(GPIO_FN_LCDCS2, LCDCS2_MARK), + GPIO_FN(LCDDON2), + GPIO_FN(LCDVCPWC2), + GPIO_FN(LCDVEPWC2), + GPIO_FN(LCDVSYN2), + GPIO_FN(LCDCS2), /* BSC */ - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK), + GPIO_FN(IOIS16), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(BS), + GPIO_FN(CS6B_CE1B), + GPIO_FN(WAIT), + GPIO_FN(CS6A_CE2B), /* SBSC */ - PINMUX_GPIO(GPIO_FN_HPD63, HPD63_MARK), - PINMUX_GPIO(GPIO_FN_HPD62, HPD62_MARK), - PINMUX_GPIO(GPIO_FN_HPD61, HPD61_MARK), - PINMUX_GPIO(GPIO_FN_HPD60, HPD60_MARK), - PINMUX_GPIO(GPIO_FN_HPD59, HPD59_MARK), - PINMUX_GPIO(GPIO_FN_HPD58, HPD58_MARK), - PINMUX_GPIO(GPIO_FN_HPD57, HPD57_MARK), - PINMUX_GPIO(GPIO_FN_HPD56, HPD56_MARK), - PINMUX_GPIO(GPIO_FN_HPD55, HPD55_MARK), - PINMUX_GPIO(GPIO_FN_HPD54, HPD54_MARK), - PINMUX_GPIO(GPIO_FN_HPD53, HPD53_MARK), - PINMUX_GPIO(GPIO_FN_HPD52, HPD52_MARK), - PINMUX_GPIO(GPIO_FN_HPD51, HPD51_MARK), - PINMUX_GPIO(GPIO_FN_HPD50, HPD50_MARK), - PINMUX_GPIO(GPIO_FN_HPD49, HPD49_MARK), - PINMUX_GPIO(GPIO_FN_HPD48, HPD48_MARK), - PINMUX_GPIO(GPIO_FN_HPDQM7, HPDQM7_MARK), - PINMUX_GPIO(GPIO_FN_HPDQM6, HPDQM6_MARK), - PINMUX_GPIO(GPIO_FN_HPDQM5, HPDQM5_MARK), - PINMUX_GPIO(GPIO_FN_HPDQM4, HPDQM4_MARK), + GPIO_FN(HPD63), + GPIO_FN(HPD62), + GPIO_FN(HPD61), + GPIO_FN(HPD60), + GPIO_FN(HPD59), + GPIO_FN(HPD58), + GPIO_FN(HPD57), + GPIO_FN(HPD56), + GPIO_FN(HPD55), + GPIO_FN(HPD54), + GPIO_FN(HPD53), + GPIO_FN(HPD52), + GPIO_FN(HPD51), + GPIO_FN(HPD50), + GPIO_FN(HPD49), + GPIO_FN(HPD48), + GPIO_FN(HPDQM7), + GPIO_FN(HPDQM6), + GPIO_FN(HPDQM5), + GPIO_FN(HPDQM4), /* IRQ */ - PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK), + GPIO_FN(IRQ0), + GPIO_FN(IRQ1), + GPIO_FN(IRQ2), + GPIO_FN(IRQ3), + GPIO_FN(IRQ4), + GPIO_FN(IRQ5), + GPIO_FN(IRQ6), + GPIO_FN(IRQ7), /* SDHI */ - PINMUX_GPIO(GPIO_FN_SDHICD, SDHICD_MARK), - PINMUX_GPIO(GPIO_FN_SDHIWP, SDHIWP_MARK), - PINMUX_GPIO(GPIO_FN_SDHID3, SDHID3_MARK), - PINMUX_GPIO(GPIO_FN_SDHID2, SDHID2_MARK), - PINMUX_GPIO(GPIO_FN_SDHID1, SDHID1_MARK), - PINMUX_GPIO(GPIO_FN_SDHID0, SDHID0_MARK), - PINMUX_GPIO(GPIO_FN_SDHICMD, SDHICMD_MARK), - PINMUX_GPIO(GPIO_FN_SDHICLK, SDHICLK_MARK), + GPIO_FN(SDHICD), + GPIO_FN(SDHIWP), + GPIO_FN(SDHID3), + GPIO_FN(SDHID2), + GPIO_FN(SDHID1), + GPIO_FN(SDHID0), + GPIO_FN(SDHICMD), + GPIO_FN(SDHICLK), /* SIU - Port A */ - PINMUX_GPIO(GPIO_FN_SIUAOLR, SIUAOLR_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOBT, SIUAOBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUAISLD, SIUAISLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUAILR, SIUAILR_MARK), - PINMUX_GPIO(GPIO_FN_SIUAIBT, SIUAIBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOSLD, SIUAOSLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUMCKA, SIUMCKA_MARK), - PINMUX_GPIO(GPIO_FN_SIUFCKA, SIUFCKA_MARK), + GPIO_FN(SIUAOLR), + GPIO_FN(SIUAOBT), + GPIO_FN(SIUAISLD), + GPIO_FN(SIUAILR), + GPIO_FN(SIUAIBT), + GPIO_FN(SIUAOSLD), + GPIO_FN(SIUMCKA), + GPIO_FN(SIUFCKA), /* SIU - Port B */ - PINMUX_GPIO(GPIO_FN_SIUBOLR, SIUBOLR_MARK), - PINMUX_GPIO(GPIO_FN_SIUBOBT, SIUBOBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUBISLD, SIUBISLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUBILR, SIUBILR_MARK), - PINMUX_GPIO(GPIO_FN_SIUBIBT, SIUBIBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUBOSLD, SIUBOSLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUMCKB, SIUMCKB_MARK), - PINMUX_GPIO(GPIO_FN_SIUFCKB, SIUFCKB_MARK), + GPIO_FN(SIUBOLR), + GPIO_FN(SIUBOBT), + GPIO_FN(SIUBISLD), + GPIO_FN(SIUBILR), + GPIO_FN(SIUBIBT), + GPIO_FN(SIUBOSLD), + GPIO_FN(SIUMCKB), + GPIO_FN(SIUFCKB), /* AUD */ - PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), + GPIO_FN(AUDSYNC), + GPIO_FN(AUDATA3), + GPIO_FN(AUDATA2), + GPIO_FN(AUDATA1), + GPIO_FN(AUDATA0), /* DMAC */ - PINMUX_GPIO(GPIO_FN_DACK, DACK_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), + GPIO_FN(DACK), + GPIO_FN(DREQ0), /* VOU */ - PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK), - PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK), - PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK), - PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK), - PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK), - PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK), - PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK), - PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK), - PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK), - PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK), - PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK), - PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK), - PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK), - PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK), - PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK), - PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK), - PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK), + GPIO_FN(DV_CLKI), + GPIO_FN(DV_CLK), + GPIO_FN(DV_HSYNC), + GPIO_FN(DV_VSYNC), + GPIO_FN(DV_D15), + GPIO_FN(DV_D14), + GPIO_FN(DV_D13), + GPIO_FN(DV_D12), + GPIO_FN(DV_D11), + GPIO_FN(DV_D10), + GPIO_FN(DV_D9), + GPIO_FN(DV_D8), + GPIO_FN(DV_D7), + GPIO_FN(DV_D6), + GPIO_FN(DV_D5), + GPIO_FN(DV_D4), + GPIO_FN(DV_D3), + GPIO_FN(DV_D2), + GPIO_FN(DV_D1), + GPIO_FN(DV_D0), /* CPG */ - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), - PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK), + GPIO_FN(STATUS0), + GPIO_FN(PDSTATUS), /* SIOF0 */ - PINMUX_GPIO(GPIO_FN_SIOF0_MCK, SIOF0_MCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_SCK, SIOF0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_SYNC, SIOF0_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_SS1, SIOF0_SS1_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_SS2, SIOF0_SS2_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_TXD, SIOF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF0_RXD, SIOF0_RXD_MARK), + GPIO_FN(SIOF0_MCK), + GPIO_FN(SIOF0_SCK), + GPIO_FN(SIOF0_SYNC), + GPIO_FN(SIOF0_SS1), + GPIO_FN(SIOF0_SS2), + GPIO_FN(SIOF0_TXD), + GPIO_FN(SIOF0_RXD), /* SIOF1 */ - PINMUX_GPIO(GPIO_FN_SIOF1_MCK, SIOF1_MCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_SCK, SIOF1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_SYNC, SIOF1_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_SS1, SIOF1_SS1_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_SS2, SIOF1_SS2_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_TXD, SIOF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF1_RXD, SIOF1_RXD_MARK), + GPIO_FN(SIOF1_MCK), + GPIO_FN(SIOF1_SCK), + GPIO_FN(SIOF1_SYNC), + GPIO_FN(SIOF1_SS1), + GPIO_FN(SIOF1_SS2), + GPIO_FN(SIOF1_TXD), + GPIO_FN(SIOF1_RXD), /* SIM */ - PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK), - PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK), + GPIO_FN(SIM_D), + GPIO_FN(SIM_CLK), + GPIO_FN(SIM_RST), /* TSIF */ - PINMUX_GPIO(GPIO_FN_TS_SDAT, TS_SDAT_MARK), - PINMUX_GPIO(GPIO_FN_TS_SCK, TS_SCK_MARK), - PINMUX_GPIO(GPIO_FN_TS_SDEN, TS_SDEN_MARK), - PINMUX_GPIO(GPIO_FN_TS_SPSYNC, TS_SPSYNC_MARK), + GPIO_FN(TS_SDAT), + GPIO_FN(TS_SCK), + GPIO_FN(TS_SDEN), + GPIO_FN(TS_SPSYNC), /* IRDA */ - PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK), - PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK), + GPIO_FN(IRDA_IN), + GPIO_FN(IRDA_OUT), /* TPU */ - PINMUX_GPIO(GPIO_FN_TPUTO, TPUTO_MARK), + GPIO_FN(TPUTO), /* FLCTL */ - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK), - PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK), - PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK), - PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK), - PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK), - PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK), - PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK), - PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK), - PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK), - PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK), - PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK), - PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), + GPIO_FN(FCE), + GPIO_FN(NAF7), + GPIO_FN(NAF6), + GPIO_FN(NAF5), + GPIO_FN(NAF4), + GPIO_FN(NAF3), + GPIO_FN(NAF2), + GPIO_FN(NAF1), + GPIO_FN(NAF0), + GPIO_FN(FCDE), + GPIO_FN(FOE), + GPIO_FN(FSC), + GPIO_FN(FWE), + GPIO_FN(FRB), /* KEYSC */ - PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK), + GPIO_FN(KEYIN0), + GPIO_FN(KEYIN1), + GPIO_FN(KEYIN2), + GPIO_FN(KEYIN3), + GPIO_FN(KEYIN4), + GPIO_FN(KEYOUT0), + GPIO_FN(KEYOUT1), + GPIO_FN(KEYOUT2), + GPIO_FN(KEYOUT3), + GPIO_FN(KEYOUT4_IN6), + GPIO_FN(KEYOUT5_IN5), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index 609673d3d70e..49fd5c82e3cf 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -1141,374 +1141,374 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), /* SCIF0 */ - PINMUX_GPIO(GPIO_FN_SCIF0_PTT_TXD, SCIF0_PTT_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_PTT_RXD, SCIF0_PTT_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_PTT_SCK, SCIF0_PTT_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_PTU_TXD, SCIF0_PTU_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_PTU_RXD, SCIF0_PTU_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_PTU_SCK, SCIF0_PTU_SCK_MARK), + GPIO_FN(SCIF0_PTT_TXD), + GPIO_FN(SCIF0_PTT_RXD), + GPIO_FN(SCIF0_PTT_SCK), + GPIO_FN(SCIF0_PTU_TXD), + GPIO_FN(SCIF0_PTU_RXD), + GPIO_FN(SCIF0_PTU_SCK), /* SCIF1 */ - PINMUX_GPIO(GPIO_FN_SCIF1_PTS_TXD, SCIF1_PTS_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_PTS_RXD, SCIF1_PTS_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_PTS_SCK, SCIF1_PTS_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_PTV_TXD, SCIF1_PTV_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_PTV_RXD, SCIF1_PTV_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_PTV_SCK, SCIF1_PTV_SCK_MARK), + GPIO_FN(SCIF1_PTS_TXD), + GPIO_FN(SCIF1_PTS_RXD), + GPIO_FN(SCIF1_PTS_SCK), + GPIO_FN(SCIF1_PTV_TXD), + GPIO_FN(SCIF1_PTV_RXD), + GPIO_FN(SCIF1_PTV_SCK), /* SCIF2 */ - PINMUX_GPIO(GPIO_FN_SCIF2_PTT_TXD, SCIF2_PTT_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_PTT_RXD, SCIF2_PTT_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_PTT_SCK, SCIF2_PTT_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_PTU_TXD, SCIF2_PTU_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_PTU_RXD, SCIF2_PTU_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_PTU_SCK, SCIF2_PTU_SCK_MARK), + GPIO_FN(SCIF2_PTT_TXD), + GPIO_FN(SCIF2_PTT_RXD), + GPIO_FN(SCIF2_PTT_SCK), + GPIO_FN(SCIF2_PTU_TXD), + GPIO_FN(SCIF2_PTU_RXD), + GPIO_FN(SCIF2_PTU_SCK), /* SCIF3 */ - PINMUX_GPIO(GPIO_FN_SCIF3_PTS_TXD, SCIF3_PTS_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTS_RXD, SCIF3_PTS_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTS_SCK, SCIF3_PTS_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTS_RTS, SCIF3_PTS_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTS_CTS, SCIF3_PTS_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTV_TXD, SCIF3_PTV_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTV_RXD, SCIF3_PTV_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTV_SCK, SCIF3_PTV_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTV_RTS, SCIF3_PTV_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_PTV_CTS, SCIF3_PTV_CTS_MARK), + GPIO_FN(SCIF3_PTS_TXD), + GPIO_FN(SCIF3_PTS_RXD), + GPIO_FN(SCIF3_PTS_SCK), + GPIO_FN(SCIF3_PTS_RTS), + GPIO_FN(SCIF3_PTS_CTS), + GPIO_FN(SCIF3_PTV_TXD), + GPIO_FN(SCIF3_PTV_RXD), + GPIO_FN(SCIF3_PTV_SCK), + GPIO_FN(SCIF3_PTV_RTS), + GPIO_FN(SCIF3_PTV_CTS), /* SCIF4 */ - PINMUX_GPIO(GPIO_FN_SCIF4_PTE_TXD, SCIF4_PTE_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_PTE_RXD, SCIF4_PTE_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_PTE_SCK, SCIF4_PTE_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_PTN_TXD, SCIF4_PTN_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_PTN_RXD, SCIF4_PTN_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_PTN_SCK, SCIF4_PTN_SCK_MARK), + GPIO_FN(SCIF4_PTE_TXD), + GPIO_FN(SCIF4_PTE_RXD), + GPIO_FN(SCIF4_PTE_SCK), + GPIO_FN(SCIF4_PTN_TXD), + GPIO_FN(SCIF4_PTN_RXD), + GPIO_FN(SCIF4_PTN_SCK), /* SCIF5 */ - PINMUX_GPIO(GPIO_FN_SCIF5_PTE_TXD, SCIF5_PTE_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_PTE_RXD, SCIF5_PTE_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_PTE_SCK, SCIF5_PTE_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_PTN_TXD, SCIF5_PTN_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_PTN_RXD, SCIF5_PTN_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_PTN_SCK, SCIF5_PTN_SCK_MARK), + GPIO_FN(SCIF5_PTE_TXD), + GPIO_FN(SCIF5_PTE_RXD), + GPIO_FN(SCIF5_PTE_SCK), + GPIO_FN(SCIF5_PTN_TXD), + GPIO_FN(SCIF5_PTN_RXD), + GPIO_FN(SCIF5_PTN_SCK), /* CEU */ - PINMUX_GPIO(GPIO_FN_VIO_D15, VIO_D15_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D14, VIO_D14_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D13, VIO_D13_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D12, VIO_D12_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D11, VIO_D11_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D10, VIO_D10_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D9, VIO_D9_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D8, VIO_D8_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D7, VIO_D7_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D6, VIO_D6_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D5, VIO_D5_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D4, VIO_D4_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D3, VIO_D3_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D2, VIO_D2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D1, VIO_D1_MARK), - PINMUX_GPIO(GPIO_FN_VIO_D0, VIO_D0_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CLK1, VIO_CLK1_MARK), - PINMUX_GPIO(GPIO_FN_VIO_VD1, VIO_VD1_MARK), - PINMUX_GPIO(GPIO_FN_VIO_HD1, VIO_HD1_MARK), - PINMUX_GPIO(GPIO_FN_VIO_FLD, VIO_FLD_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK), - PINMUX_GPIO(GPIO_FN_VIO_VD2, VIO_VD2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_HD2, VIO_HD2_MARK), - PINMUX_GPIO(GPIO_FN_VIO_CLK2, VIO_CLK2_MARK), + GPIO_FN(VIO_D15), + GPIO_FN(VIO_D14), + GPIO_FN(VIO_D13), + GPIO_FN(VIO_D12), + GPIO_FN(VIO_D11), + GPIO_FN(VIO_D10), + GPIO_FN(VIO_D9), + GPIO_FN(VIO_D8), + GPIO_FN(VIO_D7), + GPIO_FN(VIO_D6), + GPIO_FN(VIO_D5), + GPIO_FN(VIO_D4), + GPIO_FN(VIO_D3), + GPIO_FN(VIO_D2), + GPIO_FN(VIO_D1), + GPIO_FN(VIO_D0), + GPIO_FN(VIO_CLK1), + GPIO_FN(VIO_VD1), + GPIO_FN(VIO_HD1), + GPIO_FN(VIO_FLD), + GPIO_FN(VIO_CKO), + GPIO_FN(VIO_VD2), + GPIO_FN(VIO_HD2), + GPIO_FN(VIO_CLK2), /* LCDC */ - PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK), - PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK), - PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK), - PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK), - PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK), - PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK), - PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK), - PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK), - PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK), - PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK), - PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK), - PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK), - PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK), - PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK), - PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK), - PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK), - PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK), - PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK), - PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK), - PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK), - PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK), - PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK), - PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK), - PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK), - PINMUX_GPIO(GPIO_FN_LCDLCLK_PTR, LCDLCLK_PTR_MARK), - PINMUX_GPIO(GPIO_FN_LCDLCLK_PTW, LCDLCLK_PTW_MARK), + GPIO_FN(LCDD23), + GPIO_FN(LCDD22), + GPIO_FN(LCDD21), + GPIO_FN(LCDD20), + GPIO_FN(LCDD19), + GPIO_FN(LCDD18), + GPIO_FN(LCDD17), + GPIO_FN(LCDD16), + GPIO_FN(LCDD15), + GPIO_FN(LCDD14), + GPIO_FN(LCDD13), + GPIO_FN(LCDD12), + GPIO_FN(LCDD11), + GPIO_FN(LCDD10), + GPIO_FN(LCDD9), + GPIO_FN(LCDD8), + GPIO_FN(LCDD7), + GPIO_FN(LCDD6), + GPIO_FN(LCDD5), + GPIO_FN(LCDD4), + GPIO_FN(LCDD3), + GPIO_FN(LCDD2), + GPIO_FN(LCDD1), + GPIO_FN(LCDD0), + GPIO_FN(LCDLCLK_PTR), + GPIO_FN(LCDLCLK_PTW), /* Main LCD */ - PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK), - PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK), + GPIO_FN(LCDDON), + GPIO_FN(LCDVCPWC), + GPIO_FN(LCDVEPWC), + GPIO_FN(LCDVSYN), /* Main LCD - RGB Mode */ - PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK), - PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK), - PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK), + GPIO_FN(LCDDCK), + GPIO_FN(LCDHSYN), + GPIO_FN(LCDDISP), /* Main LCD - SYS Mode */ - PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK), - PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK), - PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK), - PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK), + GPIO_FN(LCDRS), + GPIO_FN(LCDCS), + GPIO_FN(LCDWR), + GPIO_FN(LCDRD), /* IRQ */ - PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK), - PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK), + GPIO_FN(IRQ0), + GPIO_FN(IRQ1), + GPIO_FN(IRQ2), + GPIO_FN(IRQ3), + GPIO_FN(IRQ4), + GPIO_FN(IRQ5), + GPIO_FN(IRQ6), + GPIO_FN(IRQ7), /* AUD */ - PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK), - PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), + GPIO_FN(AUDCK), + GPIO_FN(AUDSYNC), + GPIO_FN(AUDATA3), + GPIO_FN(AUDATA2), + GPIO_FN(AUDATA1), + GPIO_FN(AUDATA0), /* SDHI0 (PTD) */ - PINMUX_GPIO(GPIO_FN_SDHI0CD_PTD, SDHI0CD_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0WP_PTD, SDHI0WP_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D3_PTD, SDHI0D3_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D2_PTD, SDHI0D2_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D1_PTD, SDHI0D1_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D0_PTD, SDHI0D0_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CMD_PTD, SDHI0CMD_PTD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CLK_PTD, SDHI0CLK_PTD_MARK), + GPIO_FN(SDHI0CD_PTD), + GPIO_FN(SDHI0WP_PTD), + GPIO_FN(SDHI0D3_PTD), + GPIO_FN(SDHI0D2_PTD), + GPIO_FN(SDHI0D1_PTD), + GPIO_FN(SDHI0D0_PTD), + GPIO_FN(SDHI0CMD_PTD), + GPIO_FN(SDHI0CLK_PTD), /* SDHI0 (PTS) */ - PINMUX_GPIO(GPIO_FN_SDHI0CD_PTS, SDHI0CD_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0WP_PTS, SDHI0WP_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D3_PTS, SDHI0D3_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D2_PTS, SDHI0D2_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D1_PTS, SDHI0D1_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D0_PTS, SDHI0D0_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CMD_PTS, SDHI0CMD_PTS_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CLK_PTS, SDHI0CLK_PTS_MARK), + GPIO_FN(SDHI0CD_PTS), + GPIO_FN(SDHI0WP_PTS), + GPIO_FN(SDHI0D3_PTS), + GPIO_FN(SDHI0D2_PTS), + GPIO_FN(SDHI0D1_PTS), + GPIO_FN(SDHI0D0_PTS), + GPIO_FN(SDHI0CMD_PTS), + GPIO_FN(SDHI0CLK_PTS), /* SDHI1 */ - PINMUX_GPIO(GPIO_FN_SDHI1CD, SDHI1CD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1WP, SDHI1WP_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D3, SDHI1D3_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D2, SDHI1D2_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D1, SDHI1D1_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D0, SDHI1D0_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1CMD, SDHI1CMD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1CLK, SDHI1CLK_MARK), + GPIO_FN(SDHI1CD), + GPIO_FN(SDHI1WP), + GPIO_FN(SDHI1D3), + GPIO_FN(SDHI1D2), + GPIO_FN(SDHI1D1), + GPIO_FN(SDHI1D0), + GPIO_FN(SDHI1CMD), + GPIO_FN(SDHI1CLK), /* SIUA */ - PINMUX_GPIO(GPIO_FN_SIUAFCK, SIUAFCK_MARK), - PINMUX_GPIO(GPIO_FN_SIUAILR, SIUAILR_MARK), - PINMUX_GPIO(GPIO_FN_SIUAIBT, SIUAIBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUAISLD, SIUAISLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOLR, SIUAOLR_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOBT, SIUAOBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOSLD, SIUAOSLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUAMCK, SIUAMCK_MARK), - PINMUX_GPIO(GPIO_FN_SIUAISPD, SIUAISPD_MARK), - PINMUX_GPIO(GPIO_FN_SIUAOSPD, SIUAOSPD_MARK), + GPIO_FN(SIUAFCK), + GPIO_FN(SIUAILR), + GPIO_FN(SIUAIBT), + GPIO_FN(SIUAISLD), + GPIO_FN(SIUAOLR), + GPIO_FN(SIUAOBT), + GPIO_FN(SIUAOSLD), + GPIO_FN(SIUAMCK), + GPIO_FN(SIUAISPD), + GPIO_FN(SIUAOSPD), /* SIUB */ - PINMUX_GPIO(GPIO_FN_SIUBFCK, SIUBFCK_MARK), - PINMUX_GPIO(GPIO_FN_SIUBILR, SIUBILR_MARK), - PINMUX_GPIO(GPIO_FN_SIUBIBT, SIUBIBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUBISLD, SIUBISLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUBOLR, SIUBOLR_MARK), - PINMUX_GPIO(GPIO_FN_SIUBOBT, SIUBOBT_MARK), - PINMUX_GPIO(GPIO_FN_SIUBOSLD, SIUBOSLD_MARK), - PINMUX_GPIO(GPIO_FN_SIUBMCK, SIUBMCK_MARK), + GPIO_FN(SIUBFCK), + GPIO_FN(SIUBILR), + GPIO_FN(SIUBIBT), + GPIO_FN(SIUBISLD), + GPIO_FN(SIUBOLR), + GPIO_FN(SIUBOBT), + GPIO_FN(SIUBOSLD), + GPIO_FN(SIUBMCK), /* IRDA */ - PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK), - PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK), + GPIO_FN(IRDA_IN), + GPIO_FN(IRDA_OUT), /* VOU */ - PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK), - PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK), - PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK), - PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK), - PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK), - PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK), - PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK), - PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK), - PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK), - PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK), - PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK), - PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK), - PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK), - PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK), - PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK), - PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK), - PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK), + GPIO_FN(DV_CLKI), + GPIO_FN(DV_CLK), + GPIO_FN(DV_HSYNC), + GPIO_FN(DV_VSYNC), + GPIO_FN(DV_D15), + GPIO_FN(DV_D14), + GPIO_FN(DV_D13), + GPIO_FN(DV_D12), + GPIO_FN(DV_D11), + GPIO_FN(DV_D10), + GPIO_FN(DV_D9), + GPIO_FN(DV_D8), + GPIO_FN(DV_D7), + GPIO_FN(DV_D6), + GPIO_FN(DV_D5), + GPIO_FN(DV_D4), + GPIO_FN(DV_D3), + GPIO_FN(DV_D2), + GPIO_FN(DV_D1), + GPIO_FN(DV_D0), /* KEYSC */ - PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK), + GPIO_FN(KEYIN0), + GPIO_FN(KEYIN1), + GPIO_FN(KEYIN2), + GPIO_FN(KEYIN3), + GPIO_FN(KEYIN4), + GPIO_FN(KEYOUT0), + GPIO_FN(KEYOUT1), + GPIO_FN(KEYOUT2), + GPIO_FN(KEYOUT3), + GPIO_FN(KEYOUT4_IN6), + GPIO_FN(KEYOUT5_IN5), /* MSIOF0 (PTF) */ - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TXD, MSIOF0_PTF_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RXD, MSIOF0_PTF_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_MCK, MSIOF0_PTF_MCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TSYNC, MSIOF0_PTF_TSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TSCK, MSIOF0_PTF_TSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RSYNC, MSIOF0_PTF_RSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RSCK, MSIOF0_PTF_RSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_SS1, MSIOF0_PTF_SS1_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_SS2, MSIOF0_PTF_SS2_MARK), + GPIO_FN(MSIOF0_PTF_TXD), + GPIO_FN(MSIOF0_PTF_RXD), + GPIO_FN(MSIOF0_PTF_MCK), + GPIO_FN(MSIOF0_PTF_TSYNC), + GPIO_FN(MSIOF0_PTF_TSCK), + GPIO_FN(MSIOF0_PTF_RSYNC), + GPIO_FN(MSIOF0_PTF_RSCK), + GPIO_FN(MSIOF0_PTF_SS1), + GPIO_FN(MSIOF0_PTF_SS2), /* MSIOF0 (PTT+PTX) */ - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TXD, MSIOF0_PTT_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RXD, MSIOF0_PTT_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTX_MCK, MSIOF0_PTX_MCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TSYNC, MSIOF0_PTT_TSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TSCK, MSIOF0_PTT_TSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RSYNC, MSIOF0_PTT_RSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RSCK, MSIOF0_PTT_RSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_SS1, MSIOF0_PTT_SS1_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_SS2, MSIOF0_PTT_SS2_MARK), + GPIO_FN(MSIOF0_PTT_TXD), + GPIO_FN(MSIOF0_PTT_RXD), + GPIO_FN(MSIOF0_PTX_MCK), + GPIO_FN(MSIOF0_PTT_TSYNC), + GPIO_FN(MSIOF0_PTT_TSCK), + GPIO_FN(MSIOF0_PTT_RSYNC), + GPIO_FN(MSIOF0_PTT_RSCK), + GPIO_FN(MSIOF0_PTT_SS1), + GPIO_FN(MSIOF0_PTT_SS2), /* MSIOF1 */ - PINMUX_GPIO(GPIO_FN_MSIOF1_TXD, MSIOF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_RXD, MSIOF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_MCK, MSIOF1_MCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_TSYNC, MSIOF1_TSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_TSCK, MSIOF1_TSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_RSYNC, MSIOF1_RSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_RSCK, MSIOF1_RSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_SS1, MSIOF1_SS1_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_SS2, MSIOF1_SS2_MARK), + GPIO_FN(MSIOF1_TXD), + GPIO_FN(MSIOF1_RXD), + GPIO_FN(MSIOF1_MCK), + GPIO_FN(MSIOF1_TSYNC), + GPIO_FN(MSIOF1_TSCK), + GPIO_FN(MSIOF1_RSYNC), + GPIO_FN(MSIOF1_RSCK), + GPIO_FN(MSIOF1_SS1), + GPIO_FN(MSIOF1_SS2), /* TSIF */ - PINMUX_GPIO(GPIO_FN_TS0_SDAT, TS0_SDAT_MARK), - PINMUX_GPIO(GPIO_FN_TS0_SCK, TS0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_TS0_SDEN, TS0_SDEN_MARK), - PINMUX_GPIO(GPIO_FN_TS0_SPSYNC, TS0_SPSYNC_MARK), + GPIO_FN(TS0_SDAT), + GPIO_FN(TS0_SCK), + GPIO_FN(TS0_SDEN), + GPIO_FN(TS0_SPSYNC), /* FLCTL */ - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK), - PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK), - PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK), - PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK), - PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK), - PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK), - PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK), - PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK), - PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK), - PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK), - PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK), - PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), + GPIO_FN(FCE), + GPIO_FN(NAF7), + GPIO_FN(NAF6), + GPIO_FN(NAF5), + GPIO_FN(NAF4), + GPIO_FN(NAF3), + GPIO_FN(NAF2), + GPIO_FN(NAF1), + GPIO_FN(NAF0), + GPIO_FN(FCDE), + GPIO_FN(FOE), + GPIO_FN(FSC), + GPIO_FN(FWE), + GPIO_FN(FRB), /* DMAC */ - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), + GPIO_FN(DACK1), + GPIO_FN(DREQ1), + GPIO_FN(DACK0), + GPIO_FN(DREQ0), /* ADC */ - PINMUX_GPIO(GPIO_FN_AN3, AN3_MARK), - PINMUX_GPIO(GPIO_FN_AN2, AN2_MARK), - PINMUX_GPIO(GPIO_FN_AN1, AN1_MARK), - PINMUX_GPIO(GPIO_FN_AN0, AN0_MARK), - PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK), + GPIO_FN(AN3), + GPIO_FN(AN2), + GPIO_FN(AN1), + GPIO_FN(AN0), + GPIO_FN(ADTRG), /* CPG */ - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), - PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK), + GPIO_FN(STATUS0), + GPIO_FN(PDSTATUS), /* TPU */ - PINMUX_GPIO(GPIO_FN_TPUTO0, TPUTO0_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO1, TPUTO1_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO2, TPUTO2_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO3, TPUTO3_MARK), + GPIO_FN(TPUTO0), + GPIO_FN(TPUTO1), + GPIO_FN(TPUTO2), + GPIO_FN(TPUTO3), /* BSC */ - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK), - PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK), - PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CS5A_CE2A, CS5A_CE2A_MARK), - PINMUX_GPIO(GPIO_FN_WE3_ICIOWR, WE3_ICIOWR_MARK), - PINMUX_GPIO(GPIO_FN_WE2_ICIORD, WE2_ICIORD_MARK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(IOIS16), + GPIO_FN(WAIT), + GPIO_FN(BS), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(CS6B_CE1B), + GPIO_FN(CS6A_CE2B), + GPIO_FN(CS5B_CE1A), + GPIO_FN(CS5A_CE2A), + GPIO_FN(WE3_ICIOWR), + GPIO_FN(WE2_ICIORD), /* ATAPI */ - PINMUX_GPIO(GPIO_FN_IDED15, IDED15_MARK), - PINMUX_GPIO(GPIO_FN_IDED14, IDED14_MARK), - PINMUX_GPIO(GPIO_FN_IDED13, IDED13_MARK), - PINMUX_GPIO(GPIO_FN_IDED12, IDED12_MARK), - PINMUX_GPIO(GPIO_FN_IDED11, IDED11_MARK), - PINMUX_GPIO(GPIO_FN_IDED10, IDED10_MARK), - PINMUX_GPIO(GPIO_FN_IDED9, IDED9_MARK), - PINMUX_GPIO(GPIO_FN_IDED8, IDED8_MARK), - PINMUX_GPIO(GPIO_FN_IDED7, IDED7_MARK), - PINMUX_GPIO(GPIO_FN_IDED6, IDED6_MARK), - PINMUX_GPIO(GPIO_FN_IDED5, IDED5_MARK), - PINMUX_GPIO(GPIO_FN_IDED4, IDED4_MARK), - PINMUX_GPIO(GPIO_FN_IDED3, IDED3_MARK), - PINMUX_GPIO(GPIO_FN_IDED2, IDED2_MARK), - PINMUX_GPIO(GPIO_FN_IDED1, IDED1_MARK), - PINMUX_GPIO(GPIO_FN_IDED0, IDED0_MARK), - PINMUX_GPIO(GPIO_FN_DIRECTION, DIRECTION_MARK), - PINMUX_GPIO(GPIO_FN_EXBUF_ENB, EXBUF_ENB_MARK), - PINMUX_GPIO(GPIO_FN_IDERST, IDERST_MARK), - PINMUX_GPIO(GPIO_FN_IODACK, IODACK_MARK), - PINMUX_GPIO(GPIO_FN_IODREQ, IODREQ_MARK), - PINMUX_GPIO(GPIO_FN_IDEIORDY, IDEIORDY_MARK), - PINMUX_GPIO(GPIO_FN_IDEINT, IDEINT_MARK), - PINMUX_GPIO(GPIO_FN_IDEIOWR, IDEIOWR_MARK), - PINMUX_GPIO(GPIO_FN_IDEIORD, IDEIORD_MARK), - PINMUX_GPIO(GPIO_FN_IDECS1, IDECS1_MARK), - PINMUX_GPIO(GPIO_FN_IDECS0, IDECS0_MARK), - PINMUX_GPIO(GPIO_FN_IDEA2, IDEA2_MARK), - PINMUX_GPIO(GPIO_FN_IDEA1, IDEA1_MARK), - PINMUX_GPIO(GPIO_FN_IDEA0, IDEA0_MARK), + GPIO_FN(IDED15), + GPIO_FN(IDED14), + GPIO_FN(IDED13), + GPIO_FN(IDED12), + GPIO_FN(IDED11), + GPIO_FN(IDED10), + GPIO_FN(IDED9), + GPIO_FN(IDED8), + GPIO_FN(IDED7), + GPIO_FN(IDED6), + GPIO_FN(IDED5), + GPIO_FN(IDED4), + GPIO_FN(IDED3), + GPIO_FN(IDED2), + GPIO_FN(IDED1), + GPIO_FN(IDED0), + GPIO_FN(DIRECTION), + GPIO_FN(EXBUF_ENB), + GPIO_FN(IDERST), + GPIO_FN(IODACK), + GPIO_FN(IODREQ), + GPIO_FN(IDEIORDY), + GPIO_FN(IDEINT), + GPIO_FN(IDEIOWR), + GPIO_FN(IDEIORD), + GPIO_FN(IDECS1), + GPIO_FN(IDECS0), + GPIO_FN(IDEA2), + GPIO_FN(IDEA1), + GPIO_FN(IDEA0), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 233fbf750b39..054b700a7e01 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -1420,367 +1420,367 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), /* BSC */ - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_D15, D15_MARK), - PINMUX_GPIO(GPIO_FN_D14, D14_MARK), - PINMUX_GPIO(GPIO_FN_D13, D13_MARK), - PINMUX_GPIO(GPIO_FN_D12, D12_MARK), - PINMUX_GPIO(GPIO_FN_D11, D11_MARK), - PINMUX_GPIO(GPIO_FN_D10, D10_MARK), - PINMUX_GPIO(GPIO_FN_D9, D9_MARK), - PINMUX_GPIO(GPIO_FN_D8, D8_MARK), - PINMUX_GPIO(GPIO_FN_D7, D7_MARK), - PINMUX_GPIO(GPIO_FN_D6, D6_MARK), - PINMUX_GPIO(GPIO_FN_D5, D5_MARK), - PINMUX_GPIO(GPIO_FN_D4, D4_MARK), - PINMUX_GPIO(GPIO_FN_D3, D3_MARK), - PINMUX_GPIO(GPIO_FN_D2, D2_MARK), - PINMUX_GPIO(GPIO_FN_D1, D1_MARK), - PINMUX_GPIO(GPIO_FN_D0, D0_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK), - PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK), - PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK), - PINMUX_GPIO(GPIO_FN_CS5A_CE2A, CS5A_CE2A_MARK), - PINMUX_GPIO(GPIO_FN_WE3_ICIOWR, WE3_ICIOWR_MARK), - PINMUX_GPIO(GPIO_FN_WE2_ICIORD, WE2_ICIORD_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(D15), + GPIO_FN(D14), + GPIO_FN(D13), + GPIO_FN(D12), + GPIO_FN(D11), + GPIO_FN(D10), + GPIO_FN(D9), + GPIO_FN(D8), + GPIO_FN(D7), + GPIO_FN(D6), + GPIO_FN(D5), + GPIO_FN(D4), + GPIO_FN(D3), + GPIO_FN(D2), + GPIO_FN(D1), + GPIO_FN(D0), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(CS6B_CE1B), + GPIO_FN(CS6A_CE2B), + GPIO_FN(CS5B_CE1A), + GPIO_FN(CS5A_CE2A), + GPIO_FN(WE3_ICIOWR), + GPIO_FN(WE2_ICIORD), + GPIO_FN(IOIS16), + GPIO_FN(WAIT), + GPIO_FN(BS), /* KEYSC */ - PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK), - PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK), - PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK), + GPIO_FN(KEYOUT5_IN5), + GPIO_FN(KEYOUT4_IN6), + GPIO_FN(KEYIN4), + GPIO_FN(KEYIN3), + GPIO_FN(KEYIN2), + GPIO_FN(KEYIN1), + GPIO_FN(KEYIN0), + GPIO_FN(KEYOUT3), + GPIO_FN(KEYOUT2), + GPIO_FN(KEYOUT1), + GPIO_FN(KEYOUT0), /* ATAPI */ - PINMUX_GPIO(GPIO_FN_IDED15, IDED15_MARK), - PINMUX_GPIO(GPIO_FN_IDED14, IDED14_MARK), - PINMUX_GPIO(GPIO_FN_IDED13, IDED13_MARK), - PINMUX_GPIO(GPIO_FN_IDED12, IDED12_MARK), - PINMUX_GPIO(GPIO_FN_IDED11, IDED11_MARK), - PINMUX_GPIO(GPIO_FN_IDED10, IDED10_MARK), - PINMUX_GPIO(GPIO_FN_IDED9, IDED9_MARK), - PINMUX_GPIO(GPIO_FN_IDED8, IDED8_MARK), - PINMUX_GPIO(GPIO_FN_IDED7, IDED7_MARK), - PINMUX_GPIO(GPIO_FN_IDED6, IDED6_MARK), - PINMUX_GPIO(GPIO_FN_IDED5, IDED5_MARK), - PINMUX_GPIO(GPIO_FN_IDED4, IDED4_MARK), - PINMUX_GPIO(GPIO_FN_IDED3, IDED3_MARK), - PINMUX_GPIO(GPIO_FN_IDED2, IDED2_MARK), - PINMUX_GPIO(GPIO_FN_IDED1, IDED1_MARK), - PINMUX_GPIO(GPIO_FN_IDED0, IDED0_MARK), - PINMUX_GPIO(GPIO_FN_IDEA2, IDEA2_MARK), - PINMUX_GPIO(GPIO_FN_IDEA1, IDEA1_MARK), - PINMUX_GPIO(GPIO_FN_IDEA0, IDEA0_MARK), - PINMUX_GPIO(GPIO_FN_IDEIOWR, IDEIOWR_MARK), - PINMUX_GPIO(GPIO_FN_IODREQ, IODREQ_MARK), - PINMUX_GPIO(GPIO_FN_IDECS0, IDECS0_MARK), - PINMUX_GPIO(GPIO_FN_IDECS1, IDECS1_MARK), - PINMUX_GPIO(GPIO_FN_IDEIORD, IDEIORD_MARK), - PINMUX_GPIO(GPIO_FN_DIRECTION, DIRECTION_MARK), - PINMUX_GPIO(GPIO_FN_EXBUF_ENB, EXBUF_ENB_MARK), - PINMUX_GPIO(GPIO_FN_IDERST, IDERST_MARK), - PINMUX_GPIO(GPIO_FN_IODACK, IODACK_MARK), - PINMUX_GPIO(GPIO_FN_IDEINT, IDEINT_MARK), - PINMUX_GPIO(GPIO_FN_IDEIORDY, IDEIORDY_MARK), + GPIO_FN(IDED15), + GPIO_FN(IDED14), + GPIO_FN(IDED13), + GPIO_FN(IDED12), + GPIO_FN(IDED11), + GPIO_FN(IDED10), + GPIO_FN(IDED9), + GPIO_FN(IDED8), + GPIO_FN(IDED7), + GPIO_FN(IDED6), + GPIO_FN(IDED5), + GPIO_FN(IDED4), + GPIO_FN(IDED3), + GPIO_FN(IDED2), + GPIO_FN(IDED1), + GPIO_FN(IDED0), + GPIO_FN(IDEA2), + GPIO_FN(IDEA1), + GPIO_FN(IDEA0), + GPIO_FN(IDEIOWR), + GPIO_FN(IODREQ), + GPIO_FN(IDECS0), + GPIO_FN(IDECS1), + GPIO_FN(IDEIORD), + GPIO_FN(DIRECTION), + GPIO_FN(EXBUF_ENB), + GPIO_FN(IDERST), + GPIO_FN(IODACK), + GPIO_FN(IDEINT), + GPIO_FN(IDEIORDY), /* TPU */ - PINMUX_GPIO(GPIO_FN_TPUTO3, TPUTO3_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO2, TPUTO2_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO1, TPUTO1_MARK), - PINMUX_GPIO(GPIO_FN_TPUTO0, TPUTO0_MARK), - PINMUX_GPIO(GPIO_FN_TPUTI3, TPUTI3_MARK), - PINMUX_GPIO(GPIO_FN_TPUTI2, TPUTI2_MARK), + GPIO_FN(TPUTO3), + GPIO_FN(TPUTO2), + GPIO_FN(TPUTO1), + GPIO_FN(TPUTO0), + GPIO_FN(TPUTI3), + GPIO_FN(TPUTI2), /* LCDC */ - PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK), - PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK), - PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK), - PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK), - PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK), - PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK), - PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK), - PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK), - PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK), - PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK), - PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK), - PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK), - PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK), - PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK), - PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK), - PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK), - PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK), - PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK), - PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK), - PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK), - PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK), - PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK), - PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK), - PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK), - PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK), - PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK), - PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK), - PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK), - PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK), - PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK), - PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK), - PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK), - PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK), - PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK), - PINMUX_GPIO(GPIO_FN_LCDLCLK, LCDLCLK_MARK), + GPIO_FN(LCDD23), + GPIO_FN(LCDD22), + GPIO_FN(LCDD21), + GPIO_FN(LCDD20), + GPIO_FN(LCDD19), + GPIO_FN(LCDD18), + GPIO_FN(LCDD17), + GPIO_FN(LCDD16), + GPIO_FN(LCDD15), + GPIO_FN(LCDD14), + GPIO_FN(LCDD13), + GPIO_FN(LCDD12), + GPIO_FN(LCDD11), + GPIO_FN(LCDD10), + GPIO_FN(LCDD9), + GPIO_FN(LCDD8), + GPIO_FN(LCDD7), + GPIO_FN(LCDD6), + GPIO_FN(LCDD5), + GPIO_FN(LCDD4), + GPIO_FN(LCDD3), + GPIO_FN(LCDD2), + GPIO_FN(LCDD1), + GPIO_FN(LCDD0), + GPIO_FN(LCDVSYN), + GPIO_FN(LCDDISP), + GPIO_FN(LCDRS), + GPIO_FN(LCDHSYN), + GPIO_FN(LCDCS), + GPIO_FN(LCDDON), + GPIO_FN(LCDDCK), + GPIO_FN(LCDWR), + GPIO_FN(LCDVEPWC), + GPIO_FN(LCDVCPWC), + GPIO_FN(LCDRD), + GPIO_FN(LCDLCLK), /* SCIF0 */ - PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), + GPIO_FN(SCIF0_TXD), + GPIO_FN(SCIF0_RXD), + GPIO_FN(SCIF0_SCK), /* SCIF1 */ - PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), + GPIO_FN(SCIF1_SCK), + GPIO_FN(SCIF1_RXD), + GPIO_FN(SCIF1_TXD), /* SCIF2 */ - PINMUX_GPIO(GPIO_FN_SCIF2_L_TXD, SCIF2_L_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_L_SCK, SCIF2_L_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_L_RXD, SCIF2_L_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_V_TXD, SCIF2_V_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_V_SCK, SCIF2_V_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_V_RXD, SCIF2_V_RXD_MARK), + GPIO_FN(SCIF2_L_TXD), + GPIO_FN(SCIF2_L_SCK), + GPIO_FN(SCIF2_L_RXD), + GPIO_FN(SCIF2_V_TXD), + GPIO_FN(SCIF2_V_SCK), + GPIO_FN(SCIF2_V_RXD), /* SCIF3 */ - PINMUX_GPIO(GPIO_FN_SCIF3_V_SCK, SCIF3_V_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_V_RXD, SCIF3_V_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_V_TXD, SCIF3_V_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_V_CTS, SCIF3_V_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_V_RTS, SCIF3_V_RTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_I_SCK, SCIF3_I_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_I_RXD, SCIF3_I_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_I_TXD, SCIF3_I_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_I_CTS, SCIF3_I_CTS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_I_RTS, SCIF3_I_RTS_MARK), + GPIO_FN(SCIF3_V_SCK), + GPIO_FN(SCIF3_V_RXD), + GPIO_FN(SCIF3_V_TXD), + GPIO_FN(SCIF3_V_CTS), + GPIO_FN(SCIF3_V_RTS), + GPIO_FN(SCIF3_I_SCK), + GPIO_FN(SCIF3_I_RXD), + GPIO_FN(SCIF3_I_TXD), + GPIO_FN(SCIF3_I_CTS), + GPIO_FN(SCIF3_I_RTS), /* SCIF4 */ - PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK), + GPIO_FN(SCIF4_SCK), + GPIO_FN(SCIF4_RXD), + GPIO_FN(SCIF4_TXD), /* SCIF5 */ - PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK), + GPIO_FN(SCIF5_SCK), + GPIO_FN(SCIF5_RXD), + GPIO_FN(SCIF5_TXD), /* FSI */ - PINMUX_GPIO(GPIO_FN_FSIMCKB, FSIMCKB_MARK), - PINMUX_GPIO(GPIO_FN_FSIMCKA, FSIMCKA_MARK), - PINMUX_GPIO(GPIO_FN_FSIOASD, FSIOASD_MARK), - PINMUX_GPIO(GPIO_FN_FSIIABCK, FSIIABCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIIALRCK, FSIIALRCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIOABCK, FSIOABCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIOALRCK, FSIOALRCK_MARK), - PINMUX_GPIO(GPIO_FN_CLKAUDIOAO, CLKAUDIOAO_MARK), - PINMUX_GPIO(GPIO_FN_FSIIBSD, FSIIBSD_MARK), - PINMUX_GPIO(GPIO_FN_FSIOBSD, FSIOBSD_MARK), - PINMUX_GPIO(GPIO_FN_FSIIBBCK, FSIIBBCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIIBLRCK, FSIIBLRCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIOBBCK, FSIOBBCK_MARK), - PINMUX_GPIO(GPIO_FN_FSIOBLRCK, FSIOBLRCK_MARK), - PINMUX_GPIO(GPIO_FN_CLKAUDIOBO, CLKAUDIOBO_MARK), - PINMUX_GPIO(GPIO_FN_FSIIASD, FSIIASD_MARK), + GPIO_FN(FSIMCKB), + GPIO_FN(FSIMCKA), + GPIO_FN(FSIOASD), + GPIO_FN(FSIIABCK), + GPIO_FN(FSIIALRCK), + GPIO_FN(FSIOABCK), + GPIO_FN(FSIOALRCK), + GPIO_FN(CLKAUDIOAO), + GPIO_FN(FSIIBSD), + GPIO_FN(FSIOBSD), + GPIO_FN(FSIIBBCK), + GPIO_FN(FSIIBLRCK), + GPIO_FN(FSIOBBCK), + GPIO_FN(FSIOBLRCK), + GPIO_FN(CLKAUDIOBO), + GPIO_FN(FSIIASD), /* AUD */ - PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK), - PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), + GPIO_FN(AUDCK), + GPIO_FN(AUDSYNC), + GPIO_FN(AUDATA3), + GPIO_FN(AUDATA2), + GPIO_FN(AUDATA1), + GPIO_FN(AUDATA0), /* VIO */ - PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK), + GPIO_FN(VIO_CKO), /* VIO0 */ - PINMUX_GPIO(GPIO_FN_VIO0_D15, VIO0_D15_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D14, VIO0_D14_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D13, VIO0_D13_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D12, VIO0_D12_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D11, VIO0_D11_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D10, VIO0_D10_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D9, VIO0_D9_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D8, VIO0_D8_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D7, VIO0_D7_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D6, VIO0_D6_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D5, VIO0_D5_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D4, VIO0_D4_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D3, VIO0_D3_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D2, VIO0_D2_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D1, VIO0_D1_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_D0, VIO0_D0_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_VD, VIO0_VD_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_CLK, VIO0_CLK_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_FLD, VIO0_FLD_MARK), - PINMUX_GPIO(GPIO_FN_VIO0_HD, VIO0_HD_MARK), + GPIO_FN(VIO0_D15), + GPIO_FN(VIO0_D14), + GPIO_FN(VIO0_D13), + GPIO_FN(VIO0_D12), + GPIO_FN(VIO0_D11), + GPIO_FN(VIO0_D10), + GPIO_FN(VIO0_D9), + GPIO_FN(VIO0_D8), + GPIO_FN(VIO0_D7), + GPIO_FN(VIO0_D6), + GPIO_FN(VIO0_D5), + GPIO_FN(VIO0_D4), + GPIO_FN(VIO0_D3), + GPIO_FN(VIO0_D2), + GPIO_FN(VIO0_D1), + GPIO_FN(VIO0_D0), + GPIO_FN(VIO0_VD), + GPIO_FN(VIO0_CLK), + GPIO_FN(VIO0_FLD), + GPIO_FN(VIO0_HD), /* VIO1 */ - PINMUX_GPIO(GPIO_FN_VIO1_D7, VIO1_D7_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D6, VIO1_D6_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D5, VIO1_D5_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D4, VIO1_D4_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D3, VIO1_D3_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D2, VIO1_D2_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D1, VIO1_D1_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_D0, VIO1_D0_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_FLD, VIO1_FLD_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_HD, VIO1_HD_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_VD, VIO1_VD_MARK), - PINMUX_GPIO(GPIO_FN_VIO1_CLK, VIO1_CLK_MARK), + GPIO_FN(VIO1_D7), + GPIO_FN(VIO1_D6), + GPIO_FN(VIO1_D5), + GPIO_FN(VIO1_D4), + GPIO_FN(VIO1_D3), + GPIO_FN(VIO1_D2), + GPIO_FN(VIO1_D1), + GPIO_FN(VIO1_D0), + GPIO_FN(VIO1_FLD), + GPIO_FN(VIO1_HD), + GPIO_FN(VIO1_VD), + GPIO_FN(VIO1_CLK), /* Eth */ - PINMUX_GPIO(GPIO_FN_RMII_RXD0, RMII_RXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII_RXD1, RMII_RXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII_TXD0, RMII_TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII_TXD1, RMII_TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII_REF_CLK, RMII_REF_CLK_MARK), - PINMUX_GPIO(GPIO_FN_RMII_TX_EN, RMII_TX_EN_MARK), - PINMUX_GPIO(GPIO_FN_RMII_RX_ER, RMII_RX_ER_MARK), - PINMUX_GPIO(GPIO_FN_RMII_CRS_DV, RMII_CRS_DV_MARK), - PINMUX_GPIO(GPIO_FN_LNKSTA, LNKSTA_MARK), - PINMUX_GPIO(GPIO_FN_MDIO, MDIO_MARK), - PINMUX_GPIO(GPIO_FN_MDC, MDC_MARK), + GPIO_FN(RMII_RXD0), + GPIO_FN(RMII_RXD1), + GPIO_FN(RMII_TXD0), + GPIO_FN(RMII_TXD1), + GPIO_FN(RMII_REF_CLK), + GPIO_FN(RMII_TX_EN), + GPIO_FN(RMII_RX_ER), + GPIO_FN(RMII_CRS_DV), + GPIO_FN(LNKSTA), + GPIO_FN(MDIO), + GPIO_FN(MDC), /* System */ - PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK), - PINMUX_GPIO(GPIO_FN_STATUS2, STATUS2_MARK), - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), + GPIO_FN(PDSTATUS), + GPIO_FN(STATUS2), + GPIO_FN(STATUS0), /* VOU */ - PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK), - PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK), - PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK), - PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK), - PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK), - PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK), - PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK), - PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK), - PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK), - PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK), - PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK), - PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK), - PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK), - PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK), - PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK), - PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK), - PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK), - PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), + GPIO_FN(DV_D15), + GPIO_FN(DV_D14), + GPIO_FN(DV_D13), + GPIO_FN(DV_D12), + GPIO_FN(DV_D11), + GPIO_FN(DV_D10), + GPIO_FN(DV_D9), + GPIO_FN(DV_D8), + GPIO_FN(DV_D7), + GPIO_FN(DV_D6), + GPIO_FN(DV_D5), + GPIO_FN(DV_D4), + GPIO_FN(DV_D3), + GPIO_FN(DV_D2), + GPIO_FN(DV_D1), + GPIO_FN(DV_D0), + GPIO_FN(DV_CLKI), + GPIO_FN(DV_CLK), + GPIO_FN(DV_VSYNC), + GPIO_FN(DV_HSYNC), /* MSIOF0 */ - PINMUX_GPIO(GPIO_FN_MSIOF0_RXD, MSIOF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_TXD, MSIOF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_MCK, MSIOF0_MCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_TSCK, MSIOF0_TSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_SS1, MSIOF0_SS1_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_SS2, MSIOF0_SS2_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_TSYNC, MSIOF0_TSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_RSCK, MSIOF0_RSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF0_RSYNC, MSIOF0_RSYNC_MARK), + GPIO_FN(MSIOF0_RXD), + GPIO_FN(MSIOF0_TXD), + GPIO_FN(MSIOF0_MCK), + GPIO_FN(MSIOF0_TSCK), + GPIO_FN(MSIOF0_SS1), + GPIO_FN(MSIOF0_SS2), + GPIO_FN(MSIOF0_TSYNC), + GPIO_FN(MSIOF0_RSCK), + GPIO_FN(MSIOF0_RSYNC), /* MSIOF1 */ - PINMUX_GPIO(GPIO_FN_MSIOF1_RXD, MSIOF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_TXD, MSIOF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_MCK, MSIOF1_MCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_TSCK, MSIOF1_TSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_SS1, MSIOF1_SS1_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_SS2, MSIOF1_SS2_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_TSYNC, MSIOF1_TSYNC_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_RSCK, MSIOF1_RSCK_MARK), - PINMUX_GPIO(GPIO_FN_MSIOF1_RSYNC, MSIOF1_RSYNC_MARK), + GPIO_FN(MSIOF1_RXD), + GPIO_FN(MSIOF1_TXD), + GPIO_FN(MSIOF1_MCK), + GPIO_FN(MSIOF1_TSCK), + GPIO_FN(MSIOF1_SS1), + GPIO_FN(MSIOF1_SS2), + GPIO_FN(MSIOF1_TSYNC), + GPIO_FN(MSIOF1_RSCK), + GPIO_FN(MSIOF1_RSYNC), /* DMAC */ - PINMUX_GPIO(GPIO_FN_DMAC_DACK0, DMAC_DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DMAC_DREQ0, DMAC_DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_DMAC_DACK1, DMAC_DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DMAC_DREQ1, DMAC_DREQ1_MARK), + GPIO_FN(DMAC_DACK0), + GPIO_FN(DMAC_DREQ0), + GPIO_FN(DMAC_DACK1), + GPIO_FN(DMAC_DREQ1), /* SDHI0 */ - PINMUX_GPIO(GPIO_FN_SDHI0CD, SDHI0CD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0WP, SDHI0WP_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CMD, SDHI0CMD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0CLK, SDHI0CLK_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D3, SDHI0D3_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D2, SDHI0D2_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D1, SDHI0D1_MARK), - PINMUX_GPIO(GPIO_FN_SDHI0D0, SDHI0D0_MARK), + GPIO_FN(SDHI0CD), + GPIO_FN(SDHI0WP), + GPIO_FN(SDHI0CMD), + GPIO_FN(SDHI0CLK), + GPIO_FN(SDHI0D3), + GPIO_FN(SDHI0D2), + GPIO_FN(SDHI0D1), + GPIO_FN(SDHI0D0), /* SDHI1 */ - PINMUX_GPIO(GPIO_FN_SDHI1CD, SDHI1CD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1WP, SDHI1WP_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1CMD, SDHI1CMD_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1CLK, SDHI1CLK_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D3, SDHI1D3_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D2, SDHI1D2_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D1, SDHI1D1_MARK), - PINMUX_GPIO(GPIO_FN_SDHI1D0, SDHI1D0_MARK), + GPIO_FN(SDHI1CD), + GPIO_FN(SDHI1WP), + GPIO_FN(SDHI1CMD), + GPIO_FN(SDHI1CLK), + GPIO_FN(SDHI1D3), + GPIO_FN(SDHI1D2), + GPIO_FN(SDHI1D1), + GPIO_FN(SDHI1D0), /* MMC */ - PINMUX_GPIO(GPIO_FN_MMC_D7, MMC_D7_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D6, MMC_D6_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D5, MMC_D5_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D4, MMC_D4_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D3, MMC_D3_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D2, MMC_D2_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D1, MMC_D1_MARK), - PINMUX_GPIO(GPIO_FN_MMC_D0, MMC_D0_MARK), - PINMUX_GPIO(GPIO_FN_MMC_CLK, MMC_CLK_MARK), - PINMUX_GPIO(GPIO_FN_MMC_CMD, MMC_CMD_MARK), + GPIO_FN(MMC_D7), + GPIO_FN(MMC_D6), + GPIO_FN(MMC_D5), + GPIO_FN(MMC_D4), + GPIO_FN(MMC_D3), + GPIO_FN(MMC_D2), + GPIO_FN(MMC_D1), + GPIO_FN(MMC_D0), + GPIO_FN(MMC_CLK), + GPIO_FN(MMC_CMD), /* IrDA */ - PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK), - PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK), + GPIO_FN(IRDA_OUT), + GPIO_FN(IRDA_IN), /* TSIF */ - PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDAT, TSIF_TS0_SDAT_MARK), - PINMUX_GPIO(GPIO_FN_TSIF_TS0_SCK, TSIF_TS0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDEN, TSIF_TS0_SDEN_MARK), - PINMUX_GPIO(GPIO_FN_TSIF_TS0_SPSYNC, TSIF_TS0_SPSYNC_MARK), + GPIO_FN(TSIF_TS0_SDAT), + GPIO_FN(TSIF_TS0_SCK), + GPIO_FN(TSIF_TS0_SDEN), + GPIO_FN(TSIF_TS0_SPSYNC), /* IRQ */ - PINMUX_GPIO(GPIO_FN_INTC_IRQ7, INTC_IRQ7_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ6, INTC_IRQ6_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ5, INTC_IRQ5_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ4, INTC_IRQ4_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ3, INTC_IRQ3_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ2, INTC_IRQ2_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ1, INTC_IRQ1_MARK), - PINMUX_GPIO(GPIO_FN_INTC_IRQ0, INTC_IRQ0_MARK), + GPIO_FN(INTC_IRQ7), + GPIO_FN(INTC_IRQ6), + GPIO_FN(INTC_IRQ5), + GPIO_FN(INTC_IRQ4), + GPIO_FN(INTC_IRQ3), + GPIO_FN(INTC_IRQ2), + GPIO_FN(INTC_IRQ1), + GPIO_FN(INTC_IRQ0), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index 5ed74cd0ba99..ffbd8b7ee72e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -1372,354 +1372,354 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), /* PTA (mobule: LBSC, RGMII) */ - PINMUX_GPIO(GPIO_FN_BS, BS_MARK), - PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK), - PINMUX_GPIO(GPIO_FN_WE1, WE1_MARK), - PINMUX_GPIO(GPIO_FN_RDY, RDY_MARK), - PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK), - PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDIO_MARK), - PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK), - PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDIO_MARK), + GPIO_FN(BS), + GPIO_FN(RDWR), + GPIO_FN(WE1), + GPIO_FN(RDY), + GPIO_FN(ET0_MDC), + GPIO_FN(ET0_MDIO), + GPIO_FN(ET1_MDC), + GPIO_FN(ET1_MDIO), /* PTB (mobule: INTC, ONFI, TMU) */ - PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK), - PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK), - PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK), - PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK), - PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK), - PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK), - PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK), - PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK), - PINMUX_GPIO(GPIO_FN_ON_NRE, ON_NRE_MARK), - PINMUX_GPIO(GPIO_FN_ON_NWE, ON_NWE_MARK), - PINMUX_GPIO(GPIO_FN_ON_NWP, ON_NWP_MARK), - PINMUX_GPIO(GPIO_FN_ON_NCE0, ON_NCE0_MARK), - PINMUX_GPIO(GPIO_FN_ON_R_B0, ON_R_B0_MARK), - PINMUX_GPIO(GPIO_FN_ON_ALE, ON_ALE_MARK), - PINMUX_GPIO(GPIO_FN_ON_CLE, ON_CLE_MARK), - PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK), + GPIO_FN(IRQ15), + GPIO_FN(IRQ14), + GPIO_FN(IRQ13), + GPIO_FN(IRQ12), + GPIO_FN(IRQ11), + GPIO_FN(IRQ10), + GPIO_FN(IRQ9), + GPIO_FN(IRQ8), + GPIO_FN(ON_NRE), + GPIO_FN(ON_NWE), + GPIO_FN(ON_NWP), + GPIO_FN(ON_NCE0), + GPIO_FN(ON_R_B0), + GPIO_FN(ON_ALE), + GPIO_FN(ON_CLE), + GPIO_FN(TCLK), /* PTC (mobule: IRQ, PWMU) */ - PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK), - PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK), - PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK), - PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK), - PINMUX_GPIO(GPIO_FN_PWMU0, PWMU0_MARK), - PINMUX_GPIO(GPIO_FN_PWMU1, PWMU1_MARK), - PINMUX_GPIO(GPIO_FN_PWMU2, PWMU2_MARK), - PINMUX_GPIO(GPIO_FN_PWMU3, PWMU3_MARK), - PINMUX_GPIO(GPIO_FN_PWMU4, PWMU4_MARK), - PINMUX_GPIO(GPIO_FN_PWMU5, PWMU5_MARK), + GPIO_FN(IRQ7), + GPIO_FN(IRQ6), + GPIO_FN(IRQ5), + GPIO_FN(IRQ4), + GPIO_FN(IRQ3), + GPIO_FN(IRQ2), + GPIO_FN(IRQ1), + GPIO_FN(IRQ0), + GPIO_FN(PWMU0), + GPIO_FN(PWMU1), + GPIO_FN(PWMU2), + GPIO_FN(PWMU3), + GPIO_FN(PWMU4), + GPIO_FN(PWMU5), /* PTD (mobule: SPI0, DMAC) */ - PINMUX_GPIO(GPIO_FN_SP0_MOSI, SP0_MOSI_MARK), - PINMUX_GPIO(GPIO_FN_SP0_MISO, SP0_MISO_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SCK, SP0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SCK_FB, SP0_SCK_FB_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SS0, SP0_SS0_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SS2, SP0_SS2_MARK), - PINMUX_GPIO(GPIO_FN_SP0_SS3, SP0_SS3_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK), + GPIO_FN(SP0_MOSI), + GPIO_FN(SP0_MISO), + GPIO_FN(SP0_SCK), + GPIO_FN(SP0_SCK_FB), + GPIO_FN(SP0_SS0), + GPIO_FN(SP0_SS1), + GPIO_FN(SP0_SS2), + GPIO_FN(SP0_SS3), + GPIO_FN(DREQ0), + GPIO_FN(DACK0), + GPIO_FN(TEND0), /* PTE (mobule: RMII) */ - PINMUX_GPIO(GPIO_FN_RMII0_CRS_DV, RMII0_CRS_DV_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_TXD1, RMII0_TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_TXD0, RMII0_TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_TXEN, RMII0_TXEN_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_REFCLK, RMII0_REFCLK_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_RXD1, RMII0_RXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_RXD0, RMII0_RXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII0_RX_ER, RMII0_RX_ER_MARK), + GPIO_FN(RMII0_CRS_DV), + GPIO_FN(RMII0_TXD1), + GPIO_FN(RMII0_TXD0), + GPIO_FN(RMII0_TXEN), + GPIO_FN(RMII0_REFCLK), + GPIO_FN(RMII0_RXD1), + GPIO_FN(RMII0_RXD0), + GPIO_FN(RMII0_RX_ER), /* PTF (mobule: RMII, SerMux) */ - PINMUX_GPIO(GPIO_FN_RMII1_CRS_DV, RMII1_CRS_DV_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_TXD1, RMII1_TXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_TXD0, RMII1_TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_TXEN, RMII1_TXEN_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_REFCLK, RMII1_REFCLK_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_RXD1, RMII1_RXD1_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_RXD0, RMII1_RXD0_MARK), - PINMUX_GPIO(GPIO_FN_RMII1_RX_ER, RMII1_RX_ER_MARK), - PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK), + GPIO_FN(RMII1_CRS_DV), + GPIO_FN(RMII1_TXD1), + GPIO_FN(RMII1_TXD0), + GPIO_FN(RMII1_TXEN), + GPIO_FN(RMII1_REFCLK), + GPIO_FN(RMII1_RXD1), + GPIO_FN(RMII1_RXD0), + GPIO_FN(RMII1_RX_ER), + GPIO_FN(RAC_RI), /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */ - PINMUX_GPIO(GPIO_FN_BOOTFMS, BOOTFMS_MARK), - PINMUX_GPIO(GPIO_FN_BOOTWP, BOOTWP_MARK), - PINMUX_GPIO(GPIO_FN_A25, A25_MARK), - PINMUX_GPIO(GPIO_FN_A24, A24_MARK), - PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK), - PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK), - PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK), - PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK), - PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK), - PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK), + GPIO_FN(BOOTFMS), + GPIO_FN(BOOTWP), + GPIO_FN(A25), + GPIO_FN(A24), + GPIO_FN(SERIRQ), + GPIO_FN(WDTOVF), + GPIO_FN(LPCPD), + GPIO_FN(LDRQ), + GPIO_FN(MMCCLK), + GPIO_FN(MMCCMD), /* PTH (mobule: SPI1, LPC, DMAC, ADC) */ - PINMUX_GPIO(GPIO_FN_SP1_MOSI, SP1_MOSI_MARK), - PINMUX_GPIO(GPIO_FN_SP1_MISO, SP1_MISO_MARK), - PINMUX_GPIO(GPIO_FN_SP1_SCK, SP1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SP1_SCK_FB, SP1_SCK_FB_MARK), - PINMUX_GPIO(GPIO_FN_SP1_SS0, SP1_SS0_MARK), - PINMUX_GPIO(GPIO_FN_SP1_SS1, SP1_SS1_MARK), - PINMUX_GPIO(GPIO_FN_WP, WP_MARK), - PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK), - PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK), - PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK), + GPIO_FN(SP1_MOSI), + GPIO_FN(SP1_MISO), + GPIO_FN(SP1_SCK), + GPIO_FN(SP1_SCK_FB), + GPIO_FN(SP1_SS0), + GPIO_FN(SP1_SS1), + GPIO_FN(WP), + GPIO_FN(FMS0), + GPIO_FN(TEND1), + GPIO_FN(DREQ1), + GPIO_FN(DACK1), + GPIO_FN(ADTRG1), + GPIO_FN(ADTRG0), /* PTI (mobule: LBSC, SDHI) */ - PINMUX_GPIO(GPIO_FN_D15, D15_MARK), - PINMUX_GPIO(GPIO_FN_D14, D14_MARK), - PINMUX_GPIO(GPIO_FN_D13, D13_MARK), - PINMUX_GPIO(GPIO_FN_D12, D12_MARK), - PINMUX_GPIO(GPIO_FN_D11, D11_MARK), - PINMUX_GPIO(GPIO_FN_D10, D10_MARK), - PINMUX_GPIO(GPIO_FN_D9, D9_MARK), - PINMUX_GPIO(GPIO_FN_D8, D8_MARK), - PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK), - PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK), - PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK), - PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK), - PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK), - PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK), - PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK), + GPIO_FN(D15), + GPIO_FN(D14), + GPIO_FN(D13), + GPIO_FN(D12), + GPIO_FN(D11), + GPIO_FN(D10), + GPIO_FN(D9), + GPIO_FN(D8), + GPIO_FN(SD_WP), + GPIO_FN(SD_CD), + GPIO_FN(SD_CLK), + GPIO_FN(SD_CMD), + GPIO_FN(SD_D3), + GPIO_FN(SD_D2), + GPIO_FN(SD_D1), + GPIO_FN(SD_D0), /* PTJ (mobule: SCIF234, SERMUX) */ - PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK), - PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK), - PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK), - PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK), - PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK), - PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK), - PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK), + GPIO_FN(RTS3), + GPIO_FN(CTS3), + GPIO_FN(TXD3), + GPIO_FN(RXD3), + GPIO_FN(RTS4), + GPIO_FN(RXD4), + GPIO_FN(TXD4), /* PTK (mobule: SERMUX, LBSC, SCIF) */ - PINMUX_GPIO(GPIO_FN_COM2_TXD, COM2_TXD_MARK), - PINMUX_GPIO(GPIO_FN_COM2_RXD, COM2_RXD_MARK), - PINMUX_GPIO(GPIO_FN_COM2_RTS, COM2_RTS_MARK), - PINMUX_GPIO(GPIO_FN_COM2_CTS, COM2_CTS_MARK), - PINMUX_GPIO(GPIO_FN_COM2_DTR, COM2_DTR_MARK), - PINMUX_GPIO(GPIO_FN_COM2_DSR, COM2_DSR_MARK), - PINMUX_GPIO(GPIO_FN_COM2_DCD, COM2_DCD_MARK), - PINMUX_GPIO(GPIO_FN_CLKOUT, CLKOUT_MARK), - PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK), - PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK), - PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK), + GPIO_FN(COM2_TXD), + GPIO_FN(COM2_RXD), + GPIO_FN(COM2_RTS), + GPIO_FN(COM2_CTS), + GPIO_FN(COM2_DTR), + GPIO_FN(COM2_DSR), + GPIO_FN(COM2_DCD), + GPIO_FN(CLKOUT), + GPIO_FN(SCK2), + GPIO_FN(SCK4), + GPIO_FN(SCK3), /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */ - PINMUX_GPIO(GPIO_FN_RAC_RXD, RAC_RXD_MARK), - PINMUX_GPIO(GPIO_FN_RAC_RTS, RAC_RTS_MARK), - PINMUX_GPIO(GPIO_FN_RAC_CTS, RAC_CTS_MARK), - PINMUX_GPIO(GPIO_FN_RAC_DTR, RAC_DTR_MARK), - PINMUX_GPIO(GPIO_FN_RAC_DSR, RAC_DSR_MARK), - PINMUX_GPIO(GPIO_FN_RAC_DCD, RAC_DCD_MARK), - PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK), - PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK), - PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK), - PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK), - PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), - PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK), - PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK), + GPIO_FN(RAC_RXD), + GPIO_FN(RAC_RTS), + GPIO_FN(RAC_CTS), + GPIO_FN(RAC_DTR), + GPIO_FN(RAC_DSR), + GPIO_FN(RAC_DCD), + GPIO_FN(RAC_TXD), + GPIO_FN(RXD2), + GPIO_FN(CS5), + GPIO_FN(CS6), + GPIO_FN(AUDSYNC), + GPIO_FN(AUDCK), + GPIO_FN(TXD2), /* PTM (mobule: LBSC, IIC) */ - PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK), - PINMUX_GPIO(GPIO_FN_RD, RD_MARK), - PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK), - PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK), - PINMUX_GPIO(GPIO_FN_SDA6, SDA6_MARK), - PINMUX_GPIO(GPIO_FN_SCL6, SCL6_MARK), - PINMUX_GPIO(GPIO_FN_SDA7, SDA7_MARK), - PINMUX_GPIO(GPIO_FN_SCL7, SCL7_MARK), + GPIO_FN(CS4), + GPIO_FN(RD), + GPIO_FN(WE0), + GPIO_FN(CS0), + GPIO_FN(SDA6), + GPIO_FN(SCL6), + GPIO_FN(SDA7), + GPIO_FN(SCL7), /* PTN (mobule: USB, JMC, SGPIO, WDT) */ - PINMUX_GPIO(GPIO_FN_VBUS_EN, VBUS_EN_MARK), - PINMUX_GPIO(GPIO_FN_VBUS_OC, VBUS_OC_MARK), - PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK), - PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK), - PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK), - PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK), - PINMUX_GPIO(GPIO_FN_JMCTRST, JMCTRST_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK), - PINMUX_GPIO(GPIO_FN_SUB_CLKIN, SUB_CLKIN_MARK), + GPIO_FN(VBUS_EN), + GPIO_FN(VBUS_OC), + GPIO_FN(JMCTCK), + GPIO_FN(JMCTMS), + GPIO_FN(JMCTDO), + GPIO_FN(JMCTDI), + GPIO_FN(JMCTRST), + GPIO_FN(SGPIO1_CLK), + GPIO_FN(SGPIO1_LOAD), + GPIO_FN(SGPIO1_DI), + GPIO_FN(SGPIO1_DO), + GPIO_FN(SUB_CLKIN), /* PTO (mobule: SGPIO, SerMux) */ - PINMUX_GPIO(GPIO_FN_SGPIO0_CLK, SGPIO0_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO0_LOAD, SGPIO0_LOAD_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO0_DI, SGPIO0_DI_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO0_DO, SGPIO0_DO_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO2_CLK, SGPIO2_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO2_LOAD, SGPIO2_LOAD_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO2_DI, SGPIO2_DI_MARK), - PINMUX_GPIO(GPIO_FN_SGPIO2_DO, SGPIO2_DO_MARK), - PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK), - PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK), + GPIO_FN(SGPIO0_CLK), + GPIO_FN(SGPIO0_LOAD), + GPIO_FN(SGPIO0_DI), + GPIO_FN(SGPIO0_DO), + GPIO_FN(SGPIO2_CLK), + GPIO_FN(SGPIO2_LOAD), + GPIO_FN(SGPIO2_DI), + GPIO_FN(SGPIO2_DO), + GPIO_FN(COM1_TXD), + GPIO_FN(COM1_RXD), + GPIO_FN(COM1_RTS), + GPIO_FN(COM1_CTS), /* PTP (mobule: EVC, ADC) */ /* PTQ (mobule: LPC) */ - PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK), - PINMUX_GPIO(GPIO_FN_LAD2, LAD2_MARK), - PINMUX_GPIO(GPIO_FN_LAD1, LAD1_MARK), - PINMUX_GPIO(GPIO_FN_LAD0, LAD0_MARK), - PINMUX_GPIO(GPIO_FN_LFRAME, LFRAME_MARK), - PINMUX_GPIO(GPIO_FN_LRESET, LRESET_MARK), - PINMUX_GPIO(GPIO_FN_LCLK, LCLK_MARK), + GPIO_FN(LAD3), + GPIO_FN(LAD2), + GPIO_FN(LAD1), + GPIO_FN(LAD0), + GPIO_FN(LFRAME), + GPIO_FN(LRESET), + GPIO_FN(LCLK), /* PTR (mobule: GRA, IIC) */ - PINMUX_GPIO(GPIO_FN_DDC3, DDC3_MARK), - PINMUX_GPIO(GPIO_FN_DDC2, DDC2_MARK), - PINMUX_GPIO(GPIO_FN_SDA8, SDA8_MARK), - PINMUX_GPIO(GPIO_FN_SCL8, SCL8_MARK), - PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK), - PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK), - PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK), - PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK), - PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK), - PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK), + GPIO_FN(DDC3), + GPIO_FN(DDC2), + GPIO_FN(SDA8), + GPIO_FN(SCL8), + GPIO_FN(SDA2), + GPIO_FN(SCL2), + GPIO_FN(SDA1), + GPIO_FN(SCL1), + GPIO_FN(SDA0), + GPIO_FN(SCL0), /* PTS (mobule: GRA, IIC) */ - PINMUX_GPIO(GPIO_FN_DDC1, DDC1_MARK), - PINMUX_GPIO(GPIO_FN_DDC0, DDC0_MARK), - PINMUX_GPIO(GPIO_FN_SDA9, SDA9_MARK), - PINMUX_GPIO(GPIO_FN_SCL9, SCL9_MARK), - PINMUX_GPIO(GPIO_FN_SDA5, SDA5_MARK), - PINMUX_GPIO(GPIO_FN_SCL5, SCL5_MARK), - PINMUX_GPIO(GPIO_FN_SDA4, SDA4_MARK), - PINMUX_GPIO(GPIO_FN_SCL4, SCL4_MARK), - PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK), - PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK), + GPIO_FN(DDC1), + GPIO_FN(DDC0), + GPIO_FN(SDA9), + GPIO_FN(SCL9), + GPIO_FN(SDA5), + GPIO_FN(SCL5), + GPIO_FN(SDA4), + GPIO_FN(SCL4), + GPIO_FN(SDA3), + GPIO_FN(SCL3), /* PTT (mobule: PWMX, AUD) */ - PINMUX_GPIO(GPIO_FN_PWMX7, PWMX7_MARK), - PINMUX_GPIO(GPIO_FN_PWMX6, PWMX6_MARK), - PINMUX_GPIO(GPIO_FN_PWMX5, PWMX5_MARK), - PINMUX_GPIO(GPIO_FN_PWMX4, PWMX4_MARK), - PINMUX_GPIO(GPIO_FN_PWMX3, PWMX3_MARK), - PINMUX_GPIO(GPIO_FN_PWMX2, PWMX2_MARK), - PINMUX_GPIO(GPIO_FN_PWMX1, PWMX1_MARK), - PINMUX_GPIO(GPIO_FN_PWMX0, PWMX0_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), - PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), - PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK), - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), + GPIO_FN(PWMX7), + GPIO_FN(PWMX6), + GPIO_FN(PWMX5), + GPIO_FN(PWMX4), + GPIO_FN(PWMX3), + GPIO_FN(PWMX2), + GPIO_FN(PWMX1), + GPIO_FN(PWMX0), + GPIO_FN(AUDATA3), + GPIO_FN(AUDATA2), + GPIO_FN(AUDATA1), + GPIO_FN(AUDATA0), + GPIO_FN(STATUS1), + GPIO_FN(STATUS0), /* PTU (mobule: LPC, APM) */ - PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK), - PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK), - PINMUX_GPIO(GPIO_FN_APMONCTL_O, APMONCTL_O_MARK), - PINMUX_GPIO(GPIO_FN_APMPWBTOUT_O, APMPWBTOUT_O_MARK), - PINMUX_GPIO(GPIO_FN_APMSCI_O, APMSCI_O_MARK), - PINMUX_GPIO(GPIO_FN_APMVDDON, APMVDDON_MARK), - PINMUX_GPIO(GPIO_FN_APMSLPBTN, APMSLPBTN_MARK), - PINMUX_GPIO(GPIO_FN_APMPWRBTN, APMPWRBTN_MARK), - PINMUX_GPIO(GPIO_FN_APMS5N, APMS5N_MARK), - PINMUX_GPIO(GPIO_FN_APMS3N, APMS3N_MARK), + GPIO_FN(LGPIO7), + GPIO_FN(LGPIO6), + GPIO_FN(LGPIO5), + GPIO_FN(LGPIO4), + GPIO_FN(LGPIO3), + GPIO_FN(LGPIO2), + GPIO_FN(LGPIO1), + GPIO_FN(LGPIO0), + GPIO_FN(APMONCTL_O), + GPIO_FN(APMPWBTOUT_O), + GPIO_FN(APMSCI_O), + GPIO_FN(APMVDDON), + GPIO_FN(APMSLPBTN), + GPIO_FN(APMPWRBTN), + GPIO_FN(APMS5N), + GPIO_FN(APMS3N), /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */ - PINMUX_GPIO(GPIO_FN_A23, A23_MARK), - PINMUX_GPIO(GPIO_FN_A22, A22_MARK), - PINMUX_GPIO(GPIO_FN_A21, A21_MARK), - PINMUX_GPIO(GPIO_FN_A20, A20_MARK), - PINMUX_GPIO(GPIO_FN_A19, A19_MARK), - PINMUX_GPIO(GPIO_FN_A18, A18_MARK), - PINMUX_GPIO(GPIO_FN_A17, A17_MARK), - PINMUX_GPIO(GPIO_FN_A16, A16_MARK), - PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK), - PINMUX_GPIO(GPIO_FN_R_SPI_MOSI, R_SPI_MOSI_MARK), - PINMUX_GPIO(GPIO_FN_R_SPI_MISO, R_SPI_MISO_MARK), - PINMUX_GPIO(GPIO_FN_R_SPI_RSPCK, R_SPI_RSPCK_MARK), - PINMUX_GPIO(GPIO_FN_R_SPI_SSL0, R_SPI_SSL0_MARK), - PINMUX_GPIO(GPIO_FN_R_SPI_SSL1, R_SPI_SSL1_MARK), - PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK), - PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK), - PINMUX_GPIO(GPIO_FN_VBIOS_DI, VBIOS_DI_MARK), - PINMUX_GPIO(GPIO_FN_VBIOS_DO, VBIOS_DO_MARK), - PINMUX_GPIO(GPIO_FN_VBIOS_CLK, VBIOS_CLK_MARK), - PINMUX_GPIO(GPIO_FN_VBIOS_CS, VBIOS_CS_MARK), + GPIO_FN(A23), + GPIO_FN(A22), + GPIO_FN(A21), + GPIO_FN(A20), + GPIO_FN(A19), + GPIO_FN(A18), + GPIO_FN(A17), + GPIO_FN(A16), + GPIO_FN(COM2_RI), + GPIO_FN(R_SPI_MOSI), + GPIO_FN(R_SPI_MISO), + GPIO_FN(R_SPI_RSPCK), + GPIO_FN(R_SPI_SSL0), + GPIO_FN(R_SPI_SSL1), + GPIO_FN(EVENT7), + GPIO_FN(EVENT6), + GPIO_FN(VBIOS_DI), + GPIO_FN(VBIOS_DO), + GPIO_FN(VBIOS_CLK), + GPIO_FN(VBIOS_CS), /* PTW (mobule: LBSC, EVC, SCIF) */ - PINMUX_GPIO(GPIO_FN_A16, A16_MARK), - PINMUX_GPIO(GPIO_FN_A15, A15_MARK), - PINMUX_GPIO(GPIO_FN_A14, A14_MARK), - PINMUX_GPIO(GPIO_FN_A13, A13_MARK), - PINMUX_GPIO(GPIO_FN_A12, A12_MARK), - PINMUX_GPIO(GPIO_FN_A11, A11_MARK), - PINMUX_GPIO(GPIO_FN_A10, A10_MARK), - PINMUX_GPIO(GPIO_FN_A9, A9_MARK), - PINMUX_GPIO(GPIO_FN_A8, A8_MARK), - PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK), - PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK), - PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK), - PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK), - PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK), - PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK), - PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK), - PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK), + GPIO_FN(A16), + GPIO_FN(A15), + GPIO_FN(A14), + GPIO_FN(A13), + GPIO_FN(A12), + GPIO_FN(A11), + GPIO_FN(A10), + GPIO_FN(A9), + GPIO_FN(A8), + GPIO_FN(EVENT5), + GPIO_FN(EVENT4), + GPIO_FN(EVENT3), + GPIO_FN(EVENT2), + GPIO_FN(EVENT1), + GPIO_FN(EVENT0), + GPIO_FN(CTS4), + GPIO_FN(CTS2), /* PTX (mobule: LBSC) */ - PINMUX_GPIO(GPIO_FN_A7, A7_MARK), - PINMUX_GPIO(GPIO_FN_A6, A6_MARK), - PINMUX_GPIO(GPIO_FN_A5, A5_MARK), - PINMUX_GPIO(GPIO_FN_A4, A4_MARK), - PINMUX_GPIO(GPIO_FN_A3, A3_MARK), - PINMUX_GPIO(GPIO_FN_A2, A2_MARK), - PINMUX_GPIO(GPIO_FN_A1, A1_MARK), - PINMUX_GPIO(GPIO_FN_A0, A0_MARK), - PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK), - PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK), - PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK), + GPIO_FN(A7), + GPIO_FN(A6), + GPIO_FN(A5), + GPIO_FN(A4), + GPIO_FN(A3), + GPIO_FN(A2), + GPIO_FN(A1), + GPIO_FN(A0), + GPIO_FN(RTS2), + GPIO_FN(SIM_D), + GPIO_FN(SIM_CLK), + GPIO_FN(SIM_RST), /* PTY (mobule: LBSC) */ - PINMUX_GPIO(GPIO_FN_D7, D7_MARK), - PINMUX_GPIO(GPIO_FN_D6, D6_MARK), - PINMUX_GPIO(GPIO_FN_D5, D5_MARK), - PINMUX_GPIO(GPIO_FN_D4, D4_MARK), - PINMUX_GPIO(GPIO_FN_D3, D3_MARK), - PINMUX_GPIO(GPIO_FN_D2, D2_MARK), - PINMUX_GPIO(GPIO_FN_D1, D1_MARK), - PINMUX_GPIO(GPIO_FN_D0, D0_MARK), + GPIO_FN(D7), + GPIO_FN(D6), + GPIO_FN(D5), + GPIO_FN(D4), + GPIO_FN(D3), + GPIO_FN(D2), + GPIO_FN(D1), + GPIO_FN(D0), /* PTZ (mobule: eMMC, ONFI) */ - PINMUX_GPIO(GPIO_FN_MMCDAT7, MMCDAT7_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT6, MMCDAT6_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT5, MMCDAT5_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT4, MMCDAT4_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT3, MMCDAT3_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT2, MMCDAT2_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT1, MMCDAT1_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT0, MMCDAT0_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ7, ON_DQ7_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ6, ON_DQ6_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ5, ON_DQ5_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ4, ON_DQ4_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ3, ON_DQ3_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ2, ON_DQ2_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ1, ON_DQ1_MARK), - PINMUX_GPIO(GPIO_FN_ON_DQ0, ON_DQ0_MARK), + GPIO_FN(MMCDAT7), + GPIO_FN(MMCDAT6), + GPIO_FN(MMCDAT5), + GPIO_FN(MMCDAT4), + GPIO_FN(MMCDAT3), + GPIO_FN(MMCDAT2), + GPIO_FN(MMCDAT1), + GPIO_FN(MMCDAT0), + GPIO_FN(ON_DQ7), + GPIO_FN(ON_DQ6), + GPIO_FN(ON_DQ5), + GPIO_FN(ON_DQ4), + GPIO_FN(ON_DQ3), + GPIO_FN(ON_DQ2), + GPIO_FN(ON_DQ1), + GPIO_FN(ON_DQ0), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 3b1825d925bb..2e9d7cbec783 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -847,171 +847,171 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PR0, PR0_DATA), /* FN */ - PINMUX_GPIO(GPIO_FN_D63_AD31, D63_AD31_MARK), - PINMUX_GPIO(GPIO_FN_D62_AD30, D62_AD30_MARK), - PINMUX_GPIO(GPIO_FN_D61_AD29, D61_AD29_MARK), - PINMUX_GPIO(GPIO_FN_D60_AD28, D60_AD28_MARK), - PINMUX_GPIO(GPIO_FN_D59_AD27, D59_AD27_MARK), - PINMUX_GPIO(GPIO_FN_D58_AD26, D58_AD26_MARK), - PINMUX_GPIO(GPIO_FN_D57_AD25, D57_AD25_MARK), - PINMUX_GPIO(GPIO_FN_D56_AD24, D56_AD24_MARK), - PINMUX_GPIO(GPIO_FN_D55_AD23, D55_AD23_MARK), - PINMUX_GPIO(GPIO_FN_D54_AD22, D54_AD22_MARK), - PINMUX_GPIO(GPIO_FN_D53_AD21, D53_AD21_MARK), - PINMUX_GPIO(GPIO_FN_D52_AD20, D52_AD20_MARK), - PINMUX_GPIO(GPIO_FN_D51_AD19, D51_AD19_MARK), - PINMUX_GPIO(GPIO_FN_D50_AD18, D50_AD18_MARK), - PINMUX_GPIO(GPIO_FN_D49_AD17_DB5, D49_AD17_DB5_MARK), - PINMUX_GPIO(GPIO_FN_D48_AD16_DB4, D48_AD16_DB4_MARK), - PINMUX_GPIO(GPIO_FN_D47_AD15_DB3, D47_AD15_DB3_MARK), - PINMUX_GPIO(GPIO_FN_D46_AD14_DB2, D46_AD14_DB2_MARK), - PINMUX_GPIO(GPIO_FN_D45_AD13_DB1, D45_AD13_DB1_MARK), - PINMUX_GPIO(GPIO_FN_D44_AD12_DB0, D44_AD12_DB0_MARK), - PINMUX_GPIO(GPIO_FN_D43_AD11_DG5, D43_AD11_DG5_MARK), - PINMUX_GPIO(GPIO_FN_D42_AD10_DG4, D42_AD10_DG4_MARK), - PINMUX_GPIO(GPIO_FN_D41_AD9_DG3, D41_AD9_DG3_MARK), - PINMUX_GPIO(GPIO_FN_D40_AD8_DG2, D40_AD8_DG2_MARK), - PINMUX_GPIO(GPIO_FN_D39_AD7_DG1, D39_AD7_DG1_MARK), - PINMUX_GPIO(GPIO_FN_D38_AD6_DG0, D38_AD6_DG0_MARK), - PINMUX_GPIO(GPIO_FN_D37_AD5_DR5, D37_AD5_DR5_MARK), - PINMUX_GPIO(GPIO_FN_D36_AD4_DR4, D36_AD4_DR4_MARK), - PINMUX_GPIO(GPIO_FN_D35_AD3_DR3, D35_AD3_DR3_MARK), - PINMUX_GPIO(GPIO_FN_D34_AD2_DR2, D34_AD2_DR2_MARK), - PINMUX_GPIO(GPIO_FN_D33_AD1_DR1, D33_AD1_DR1_MARK), - PINMUX_GPIO(GPIO_FN_D32_AD0_DR0, D32_AD0_DR0_MARK), - PINMUX_GPIO(GPIO_FN_REQ1, REQ1_MARK), - PINMUX_GPIO(GPIO_FN_REQ2, REQ2_MARK), - PINMUX_GPIO(GPIO_FN_REQ3, REQ3_MARK), - PINMUX_GPIO(GPIO_FN_GNT1, GNT1_MARK), - PINMUX_GPIO(GPIO_FN_GNT2, GNT2_MARK), - PINMUX_GPIO(GPIO_FN_GNT3, GNT3_MARK), - PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK), - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK), - PINMUX_GPIO(GPIO_FN_INTD, INTD_MARK), - PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_CS, HSPI_CS_MARK), - PINMUX_GPIO(GPIO_FN_FSE, FSE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_CLK, HSPI_CLK_MARK), - PINMUX_GPIO(GPIO_FN_FRE, FRE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_RX, HSPI_RX_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_TX, HSPI_TX_MARK), - PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SYNC, HAC1_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_WS, SSI1_WS_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_TXD_PJ, SIOF_TXD_PJ_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SDOUT, HAC0_SDOUT_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_SDATA, SSI0_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_RXD_PJ, SIOF_RXD_PJ_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SDIN, HAC0_SDIN_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_SCK, SSI0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_SYNC_PJ, SIOF_SYNC_PJ_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SYNC, HAC0_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_WS, SSI0_WS_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_MCLK_PJ, SIOF_MCLK_PJ_MARK), - PINMUX_GPIO(GPIO_FN_HAC_RES, HAC_RES_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_SCK_PJ, SIOF_SCK_PJ_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_BITCLK, HAC0_BITCLK_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_CLK, SSI0_CLK_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_BITCLK, HAC1_BITCLK_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_CLK, SSI1_CLK_MARK), - PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), - PINMUX_GPIO(GPIO_FN_DRAK0_PK3, DRAK0_PK3_MARK), - PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK), - PINMUX_GPIO(GPIO_FN_DRAK1_PK2, DRAK1_PK2_MARK), - PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_TXD, SCIF2_TXD_MARK), - PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_TXD_PK, SIOF_TXD_PK_MARK), - PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_SCK, SCIF2_SCK_MARK), - PINMUX_GPIO(GPIO_FN_MMCDAT, MMCDAT_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_SCK_PK, SIOF_SCK_PK_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_DRAK0_PK1, DRAK0_PK1_MARK), - PINMUX_GPIO(GPIO_FN_DRAK1_PK0, DRAK1_PK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK), - PINMUX_GPIO(GPIO_FN_INTB, INTB_MARK), - PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK), - PINMUX_GPIO(GPIO_FN_INTC, INTC_MARK), - PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_IRL4, IRL4_MARK), - PINMUX_GPIO(GPIO_FN_FD4, FD4_MARK), - PINMUX_GPIO(GPIO_FN_IRL5, IRL5_MARK), - PINMUX_GPIO(GPIO_FN_FD5, FD5_MARK), - PINMUX_GPIO(GPIO_FN_IRL6, IRL6_MARK), - PINMUX_GPIO(GPIO_FN_FD6, FD6_MARK), - PINMUX_GPIO(GPIO_FN_IRL7, IRL7_MARK), - PINMUX_GPIO(GPIO_FN_FD7, FD7_MARK), - PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_BREQ_BSACK, BREQ_BSACK_MARK), - PINMUX_GPIO(GPIO_FN_BACK_BSREQ, BACK_BSREQ_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SDIN, HAC1_SDIN_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_SCK, SSI1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SDOUT, HAC1_SDOUT_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_SDATA, SSI1_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_TXD, SCIF3_TXD_MARK), - PINMUX_GPIO(GPIO_FN_FCLE, FCLE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_RXD, SCIF3_RXD_MARK), - PINMUX_GPIO(GPIO_FN_FALE, FALE_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_SCK, SCIF3_SCK_MARK), - PINMUX_GPIO(GPIO_FN_FD0, FD0_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK), - PINMUX_GPIO(GPIO_FN_FD1, FD1_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK), - PINMUX_GPIO(GPIO_FN_FD2, FD2_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK), - PINMUX_GPIO(GPIO_FN_FD3, FD3_MARK), - PINMUX_GPIO(GPIO_FN_DEVSEL_DCLKOUT, DEVSEL_DCLKOUT_MARK), - PINMUX_GPIO(GPIO_FN_STOP_CDE, STOP_CDE_MARK), - PINMUX_GPIO(GPIO_FN_LOCK_ODDF, LOCK_ODDF_MARK), - PINMUX_GPIO(GPIO_FN_TRDY_DISPL, TRDY_DISPL_MARK), - PINMUX_GPIO(GPIO_FN_IRDY_HSYNC, IRDY_HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_PCIFRAME_VSYNC, PCIFRAME_VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_INTA, INTA_MARK), - PINMUX_GPIO(GPIO_FN_GNT0_GNTIN, GNT0_GNTIN_MARK), - PINMUX_GPIO(GPIO_FN_REQ0_REQOUT, REQ0_REQOUT_MARK), - PINMUX_GPIO(GPIO_FN_PERR, PERR_MARK), - PINMUX_GPIO(GPIO_FN_SERR, SERR_MARK), - PINMUX_GPIO(GPIO_FN_WE7_CBE3, WE7_CBE3_MARK), - PINMUX_GPIO(GPIO_FN_WE6_CBE2, WE6_CBE2_MARK), - PINMUX_GPIO(GPIO_FN_WE5_CBE1, WE5_CBE1_MARK), - PINMUX_GPIO(GPIO_FN_WE4_CBE0, WE4_CBE0_MARK), - PINMUX_GPIO(GPIO_FN_SCIF2_RXD, SCIF2_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SIOF_RXD, SIOF_RXD_MARK), - PINMUX_GPIO(GPIO_FN_MRESETOUT, MRESETOUT_MARK), - PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK), + GPIO_FN(D63_AD31), + GPIO_FN(D62_AD30), + GPIO_FN(D61_AD29), + GPIO_FN(D60_AD28), + GPIO_FN(D59_AD27), + GPIO_FN(D58_AD26), + GPIO_FN(D57_AD25), + GPIO_FN(D56_AD24), + GPIO_FN(D55_AD23), + GPIO_FN(D54_AD22), + GPIO_FN(D53_AD21), + GPIO_FN(D52_AD20), + GPIO_FN(D51_AD19), + GPIO_FN(D50_AD18), + GPIO_FN(D49_AD17_DB5), + GPIO_FN(D48_AD16_DB4), + GPIO_FN(D47_AD15_DB3), + GPIO_FN(D46_AD14_DB2), + GPIO_FN(D45_AD13_DB1), + GPIO_FN(D44_AD12_DB0), + GPIO_FN(D43_AD11_DG5), + GPIO_FN(D42_AD10_DG4), + GPIO_FN(D41_AD9_DG3), + GPIO_FN(D40_AD8_DG2), + GPIO_FN(D39_AD7_DG1), + GPIO_FN(D38_AD6_DG0), + GPIO_FN(D37_AD5_DR5), + GPIO_FN(D36_AD4_DR4), + GPIO_FN(D35_AD3_DR3), + GPIO_FN(D34_AD2_DR2), + GPIO_FN(D33_AD1_DR1), + GPIO_FN(D32_AD0_DR0), + GPIO_FN(REQ1), + GPIO_FN(REQ2), + GPIO_FN(REQ3), + GPIO_FN(GNT1), + GPIO_FN(GNT2), + GPIO_FN(GNT3), + GPIO_FN(MMCCLK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(SCIF1_SCK), + GPIO_FN(SCIF1_RXD), + GPIO_FN(SCIF1_TXD), + GPIO_FN(SCIF0_CTS), + GPIO_FN(INTD), + GPIO_FN(FCE), + GPIO_FN(SCIF0_RTS), + GPIO_FN(HSPI_CS), + GPIO_FN(FSE), + GPIO_FN(SCIF0_SCK), + GPIO_FN(HSPI_CLK), + GPIO_FN(FRE), + GPIO_FN(SCIF0_RXD), + GPIO_FN(HSPI_RX), + GPIO_FN(FRB), + GPIO_FN(SCIF0_TXD), + GPIO_FN(HSPI_TX), + GPIO_FN(FWE), + GPIO_FN(SCIF5_TXD), + GPIO_FN(HAC1_SYNC), + GPIO_FN(SSI1_WS), + GPIO_FN(SIOF_TXD_PJ), + GPIO_FN(HAC0_SDOUT), + GPIO_FN(SSI0_SDATA), + GPIO_FN(SIOF_RXD_PJ), + GPIO_FN(HAC0_SDIN), + GPIO_FN(SSI0_SCK), + GPIO_FN(SIOF_SYNC_PJ), + GPIO_FN(HAC0_SYNC), + GPIO_FN(SSI0_WS), + GPIO_FN(SIOF_MCLK_PJ), + GPIO_FN(HAC_RES), + GPIO_FN(SIOF_SCK_PJ), + GPIO_FN(HAC0_BITCLK), + GPIO_FN(SSI0_CLK), + GPIO_FN(HAC1_BITCLK), + GPIO_FN(SSI1_CLK), + GPIO_FN(TCLK), + GPIO_FN(IOIS16), + GPIO_FN(STATUS0), + GPIO_FN(DRAK0_PK3), + GPIO_FN(STATUS1), + GPIO_FN(DRAK1_PK2), + GPIO_FN(DACK2), + GPIO_FN(SCIF2_TXD), + GPIO_FN(MMCCMD), + GPIO_FN(SIOF_TXD_PK), + GPIO_FN(DACK3), + GPIO_FN(SCIF2_SCK), + GPIO_FN(MMCDAT), + GPIO_FN(SIOF_SCK_PK), + GPIO_FN(DREQ0), + GPIO_FN(DREQ1), + GPIO_FN(DRAK0_PK1), + GPIO_FN(DRAK1_PK0), + GPIO_FN(DREQ2), + GPIO_FN(INTB), + GPIO_FN(DREQ3), + GPIO_FN(INTC), + GPIO_FN(DRAK2), + GPIO_FN(CE2A), + GPIO_FN(IRL4), + GPIO_FN(FD4), + GPIO_FN(IRL5), + GPIO_FN(FD5), + GPIO_FN(IRL6), + GPIO_FN(FD6), + GPIO_FN(IRL7), + GPIO_FN(FD7), + GPIO_FN(DRAK3), + GPIO_FN(CE2B), + GPIO_FN(BREQ_BSACK), + GPIO_FN(BACK_BSREQ), + GPIO_FN(SCIF5_RXD), + GPIO_FN(HAC1_SDIN), + GPIO_FN(SSI1_SCK), + GPIO_FN(SCIF5_SCK), + GPIO_FN(HAC1_SDOUT), + GPIO_FN(SSI1_SDATA), + GPIO_FN(SCIF3_TXD), + GPIO_FN(FCLE), + GPIO_FN(SCIF3_RXD), + GPIO_FN(FALE), + GPIO_FN(SCIF3_SCK), + GPIO_FN(FD0), + GPIO_FN(SCIF4_TXD), + GPIO_FN(FD1), + GPIO_FN(SCIF4_RXD), + GPIO_FN(FD2), + GPIO_FN(SCIF4_SCK), + GPIO_FN(FD3), + GPIO_FN(DEVSEL_DCLKOUT), + GPIO_FN(STOP_CDE), + GPIO_FN(LOCK_ODDF), + GPIO_FN(TRDY_DISPL), + GPIO_FN(IRDY_HSYNC), + GPIO_FN(PCIFRAME_VSYNC), + GPIO_FN(INTA), + GPIO_FN(GNT0_GNTIN), + GPIO_FN(REQ0_REQOUT), + GPIO_FN(PERR), + GPIO_FN(SERR), + GPIO_FN(WE7_CBE3), + GPIO_FN(WE6_CBE2), + GPIO_FN(WE5_CBE1), + GPIO_FN(WE4_CBE0), + GPIO_FN(SCIF2_RXD), + GPIO_FN(SIOF_RXD), + GPIO_FN(MRESETOUT), + GPIO_FN(IRQOUT), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index 1e18b58f9e5f..c9d8f500a6d3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -507,142 +507,142 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PJ1, PJ1_DATA), /* FN */ - PINMUX_GPIO(GPIO_FN_CDE, CDE_MARK), - PINMUX_GPIO(GPIO_FN_ETH_MAGIC, ETH_MAGIC_MARK), - PINMUX_GPIO(GPIO_FN_DISP, DISP_MARK), - PINMUX_GPIO(GPIO_FN_ETH_LINK, ETH_LINK_MARK), - PINMUX_GPIO(GPIO_FN_DR5, DR5_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TX_ER, ETH_TX_ER_MARK), - PINMUX_GPIO(GPIO_FN_DR4, DR4_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TX_EN, ETH_TX_EN_MARK), - PINMUX_GPIO(GPIO_FN_DR3, DR3_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TXD3, ETH_TXD3_MARK), - PINMUX_GPIO(GPIO_FN_DR2, DR2_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TXD2, ETH_TXD2_MARK), - PINMUX_GPIO(GPIO_FN_DR1, DR1_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TXD1, ETH_TXD1_MARK), - PINMUX_GPIO(GPIO_FN_DR0, DR0_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TXD0, ETH_TXD0_MARK), - PINMUX_GPIO(GPIO_FN_VSYNC, VSYNC_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_CLK, HSPI_CLK_MARK), - PINMUX_GPIO(GPIO_FN_ODDF, ODDF_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_CS, HSPI_CS_MARK), - PINMUX_GPIO(GPIO_FN_DG5, DG5_MARK), - PINMUX_GPIO(GPIO_FN_ETH_MDIO, ETH_MDIO_MARK), - PINMUX_GPIO(GPIO_FN_DG4, DG4_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RX_CLK, ETH_RX_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DG3, DG3_MARK), - PINMUX_GPIO(GPIO_FN_ETH_MDC, ETH_MDC_MARK), - PINMUX_GPIO(GPIO_FN_DG2, DG2_MARK), - PINMUX_GPIO(GPIO_FN_ETH_COL, ETH_COL_MARK), - PINMUX_GPIO(GPIO_FN_DG1, DG1_MARK), - PINMUX_GPIO(GPIO_FN_ETH_TX_CLK, ETH_TX_CLK_MARK), - PINMUX_GPIO(GPIO_FN_DG0, DG0_MARK), - PINMUX_GPIO(GPIO_FN_ETH_CRS, ETH_CRS_MARK), - PINMUX_GPIO(GPIO_FN_DCLKIN, DCLKIN_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_RX, HSPI_RX_MARK), - PINMUX_GPIO(GPIO_FN_HSYNC, HSYNC_MARK), - PINMUX_GPIO(GPIO_FN_HSPI_TX, HSPI_TX_MARK), - PINMUX_GPIO(GPIO_FN_DB5, DB5_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RXD3, ETH_RXD3_MARK), - PINMUX_GPIO(GPIO_FN_DB4, DB4_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RXD2, ETH_RXD2_MARK), - PINMUX_GPIO(GPIO_FN_DB3, DB3_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RXD1, ETH_RXD1_MARK), - PINMUX_GPIO(GPIO_FN_DB2, DB2_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RXD0, ETH_RXD0_MARK), - PINMUX_GPIO(GPIO_FN_DB1, DB1_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RX_DV, ETH_RX_DV_MARK), - PINMUX_GPIO(GPIO_FN_DB0, DB0_MARK), - PINMUX_GPIO(GPIO_FN_ETH_RX_ER, ETH_RX_ER_MARK), - PINMUX_GPIO(GPIO_FN_DCLKOUT, DCLKOUT_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), - PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK), - PINMUX_GPIO(GPIO_FN_FALE, FALE_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_FCLE, FCLE_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK), - PINMUX_GPIO(GPIO_FN_USB_OVC1, USB_OVC1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_USB_OVC0, USB_OVC0_MARK), - PINMUX_GPIO(GPIO_FN_USB_PENC1, USB_PENC1_MARK), - PINMUX_GPIO(GPIO_FN_USB_PENC0, USB_PENC0_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SDOUT, HAC1_SDOUT_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_SDATA, SSI1_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1CMD, SDIF1CMD_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SDIN, HAC1_SDIN_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_SCK, SSI1_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1CD, SDIF1CD_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_SYNC, HAC1_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_WS, SSI1_WS_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1WP, SDIF1WP_MARK), - PINMUX_GPIO(GPIO_FN_HAC1_BITCLK, HAC1_BITCLK_MARK), - PINMUX_GPIO(GPIO_FN_SSI1_CLK, SSI1_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1CLK, SDIF1CLK_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SDOUT, HAC0_SDOUT_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_SDATA, SSI0_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1D3, SDIF1D3_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SDIN, HAC0_SDIN_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_SCK, SSI0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1D2, SDIF1D2_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_SYNC, HAC0_SYNC_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_WS, SSI0_WS_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1D1, SDIF1D1_MARK), - PINMUX_GPIO(GPIO_FN_HAC0_BITCLK, HAC0_BITCLK_MARK), - PINMUX_GPIO(GPIO_FN_SSI0_CLK, SSI0_CLK_MARK), - PINMUX_GPIO(GPIO_FN_SDIF1D0, SDIF1D0_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_SCK, SCIF3_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SSI2_SDATA, SSI2_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_RXD, SCIF3_RXD_MARK), - PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK), - PINMUX_GPIO(GPIO_FN_SSI2_SCK, SSI2_SCK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF3_TXD, SCIF3_TXD_MARK), - PINMUX_GPIO(GPIO_FN_HAC_RES, HAC_RES_MARK), - PINMUX_GPIO(GPIO_FN_SSI2_WS, SSI2_WS_MARK), - PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0CMD, SDIF0CMD_MARK), - PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0CD, SDIF0CD_MARK), - PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0WP, SDIF0WP_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK), - PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0CLK, SDIF0CLK_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK), - PINMUX_GPIO(GPIO_FN_IRL7, IRL7_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0D3, SDIF0D3_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), - PINMUX_GPIO(GPIO_FN_IRL6, IRL6_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0D2, SDIF0D2_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), - PINMUX_GPIO(GPIO_FN_IRL5, IRL5_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0D1, SDIF0D1_MARK), - PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), - PINMUX_GPIO(GPIO_FN_IRL4, IRL4_MARK), - PINMUX_GPIO(GPIO_FN_SDIF0D0, SDIF0D0_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK), - PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK), - PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK), - PINMUX_GPIO(GPIO_FN_SSI3_WS, SSI3_WS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK), - PINMUX_GPIO(GPIO_FN_DRAK1, DRAK1_MARK), - PINMUX_GPIO(GPIO_FN_SSI3_SDATA, SSI3_SDATA_MARK), - PINMUX_GPIO(GPIO_FN_FSTATUS, FSTATUS_MARK), - PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK), - PINMUX_GPIO(GPIO_FN_DRAK0, DRAK0_MARK), - PINMUX_GPIO(GPIO_FN_SSI3_SCK, SSI3_SCK_MARK), - PINMUX_GPIO(GPIO_FN_FSE, FSE_MARK), + GPIO_FN(CDE), + GPIO_FN(ETH_MAGIC), + GPIO_FN(DISP), + GPIO_FN(ETH_LINK), + GPIO_FN(DR5), + GPIO_FN(ETH_TX_ER), + GPIO_FN(DR4), + GPIO_FN(ETH_TX_EN), + GPIO_FN(DR3), + GPIO_FN(ETH_TXD3), + GPIO_FN(DR2), + GPIO_FN(ETH_TXD2), + GPIO_FN(DR1), + GPIO_FN(ETH_TXD1), + GPIO_FN(DR0), + GPIO_FN(ETH_TXD0), + GPIO_FN(VSYNC), + GPIO_FN(HSPI_CLK), + GPIO_FN(ODDF), + GPIO_FN(HSPI_CS), + GPIO_FN(DG5), + GPIO_FN(ETH_MDIO), + GPIO_FN(DG4), + GPIO_FN(ETH_RX_CLK), + GPIO_FN(DG3), + GPIO_FN(ETH_MDC), + GPIO_FN(DG2), + GPIO_FN(ETH_COL), + GPIO_FN(DG1), + GPIO_FN(ETH_TX_CLK), + GPIO_FN(DG0), + GPIO_FN(ETH_CRS), + GPIO_FN(DCLKIN), + GPIO_FN(HSPI_RX), + GPIO_FN(HSYNC), + GPIO_FN(HSPI_TX), + GPIO_FN(DB5), + GPIO_FN(ETH_RXD3), + GPIO_FN(DB4), + GPIO_FN(ETH_RXD2), + GPIO_FN(DB3), + GPIO_FN(ETH_RXD1), + GPIO_FN(DB2), + GPIO_FN(ETH_RXD0), + GPIO_FN(DB1), + GPIO_FN(ETH_RX_DV), + GPIO_FN(DB0), + GPIO_FN(ETH_RX_ER), + GPIO_FN(DCLKOUT), + GPIO_FN(SCIF1_SCK), + GPIO_FN(SCIF1_RXD), + GPIO_FN(SCIF1_TXD), + GPIO_FN(DACK1), + GPIO_FN(BACK), + GPIO_FN(FALE), + GPIO_FN(DACK0), + GPIO_FN(FCLE), + GPIO_FN(DREQ1), + GPIO_FN(BREQ), + GPIO_FN(USB_OVC1), + GPIO_FN(DREQ0), + GPIO_FN(USB_OVC0), + GPIO_FN(USB_PENC1), + GPIO_FN(USB_PENC0), + GPIO_FN(HAC1_SDOUT), + GPIO_FN(SSI1_SDATA), + GPIO_FN(SDIF1CMD), + GPIO_FN(HAC1_SDIN), + GPIO_FN(SSI1_SCK), + GPIO_FN(SDIF1CD), + GPIO_FN(HAC1_SYNC), + GPIO_FN(SSI1_WS), + GPIO_FN(SDIF1WP), + GPIO_FN(HAC1_BITCLK), + GPIO_FN(SSI1_CLK), + GPIO_FN(SDIF1CLK), + GPIO_FN(HAC0_SDOUT), + GPIO_FN(SSI0_SDATA), + GPIO_FN(SDIF1D3), + GPIO_FN(HAC0_SDIN), + GPIO_FN(SSI0_SCK), + GPIO_FN(SDIF1D2), + GPIO_FN(HAC0_SYNC), + GPIO_FN(SSI0_WS), + GPIO_FN(SDIF1D1), + GPIO_FN(HAC0_BITCLK), + GPIO_FN(SSI0_CLK), + GPIO_FN(SDIF1D0), + GPIO_FN(SCIF3_SCK), + GPIO_FN(SSI2_SDATA), + GPIO_FN(SCIF3_RXD), + GPIO_FN(TCLK), + GPIO_FN(SSI2_SCK), + GPIO_FN(SCIF3_TXD), + GPIO_FN(HAC_RES), + GPIO_FN(SSI2_WS), + GPIO_FN(DACK3), + GPIO_FN(SDIF0CMD), + GPIO_FN(DACK2), + GPIO_FN(SDIF0CD), + GPIO_FN(DREQ3), + GPIO_FN(SDIF0WP), + GPIO_FN(SCIF0_CTS), + GPIO_FN(DREQ2), + GPIO_FN(SDIF0CLK), + GPIO_FN(SCIF0_RTS), + GPIO_FN(IRL7), + GPIO_FN(SDIF0D3), + GPIO_FN(SCIF0_SCK), + GPIO_FN(IRL6), + GPIO_FN(SDIF0D2), + GPIO_FN(SCIF0_RXD), + GPIO_FN(IRL5), + GPIO_FN(SDIF0D1), + GPIO_FN(SCIF0_TXD), + GPIO_FN(IRL4), + GPIO_FN(SDIF0D0), + GPIO_FN(SCIF5_SCK), + GPIO_FN(FRB), + GPIO_FN(SCIF5_RXD), + GPIO_FN(IOIS16), + GPIO_FN(SCIF5_TXD), + GPIO_FN(CE2B), + GPIO_FN(DRAK3), + GPIO_FN(CE2A), + GPIO_FN(SCIF4_SCK), + GPIO_FN(DRAK2), + GPIO_FN(SSI3_WS), + GPIO_FN(SCIF4_RXD), + GPIO_FN(DRAK1), + GPIO_FN(SSI3_SDATA), + GPIO_FN(FSTATUS), + GPIO_FN(SCIF4_TXD), + GPIO_FN(DRAK0), + GPIO_FN(SSI3_SCK), + GPIO_FN(FSE), }; static struct pinmux_cfg_reg pinmux_config_regs[] = { diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index ccf6918b03c6..04e89407aecd 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -386,68 +386,68 @@ static struct pinmux_gpio shx3_pinmux_gpios[] = { PINMUX_GPIO(GPIO_PH0, PH0_DATA), /* FN */ - PINMUX_GPIO(GPIO_FN_D31, D31_MARK), - PINMUX_GPIO(GPIO_FN_D30, D30_MARK), - PINMUX_GPIO(GPIO_FN_D29, D29_MARK), - PINMUX_GPIO(GPIO_FN_D28, D28_MARK), - PINMUX_GPIO(GPIO_FN_D27, D27_MARK), - PINMUX_GPIO(GPIO_FN_D26, D26_MARK), - PINMUX_GPIO(GPIO_FN_D25, D25_MARK), - PINMUX_GPIO(GPIO_FN_D24, D24_MARK), - PINMUX_GPIO(GPIO_FN_D23, D23_MARK), - PINMUX_GPIO(GPIO_FN_D22, D22_MARK), - PINMUX_GPIO(GPIO_FN_D21, D21_MARK), - PINMUX_GPIO(GPIO_FN_D20, D20_MARK), - PINMUX_GPIO(GPIO_FN_D19, D19_MARK), - PINMUX_GPIO(GPIO_FN_D18, D18_MARK), - PINMUX_GPIO(GPIO_FN_D17, D17_MARK), - PINMUX_GPIO(GPIO_FN_D16, D16_MARK), - PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK), - PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK), - PINMUX_GPIO(GPIO_FN_WE3, WE3_MARK), - PINMUX_GPIO(GPIO_FN_WE2, WE2_MARK), - PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK), - PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK), - PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK), - PINMUX_GPIO(GPIO_FN_CLKOUTENB, CLKOUTENB_MARK), - PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK), - PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK), - PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK), - PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK), - PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK), - PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK), - PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK), - PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK), - PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK), - PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK), - PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK), - PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK), - PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK), - PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK), - PINMUX_GPIO(GPIO_FN_DRAK1, DRAK1_MARK), - PINMUX_GPIO(GPIO_FN_DRAK0, DRAK0_MARK), - PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK), - PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK), - PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK), - PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK), - PINMUX_GPIO(GPIO_FN_IRL3, IRL3_MARK), - PINMUX_GPIO(GPIO_FN_IRL2, IRL2_MARK), - PINMUX_GPIO(GPIO_FN_IRL1, IRL1_MARK), - PINMUX_GPIO(GPIO_FN_IRL0, IRL0_MARK), - PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK), - PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK), - PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK), - PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK), - PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK), - PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK), - PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK), - PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK), - PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK), - PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK), - PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), - PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK), - PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), - PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK), + GPIO_FN(D31), + GPIO_FN(D30), + GPIO_FN(D29), + GPIO_FN(D28), + GPIO_FN(D27), + GPIO_FN(D26), + GPIO_FN(D25), + GPIO_FN(D24), + GPIO_FN(D23), + GPIO_FN(D22), + GPIO_FN(D21), + GPIO_FN(D20), + GPIO_FN(D19), + GPIO_FN(D18), + GPIO_FN(D17), + GPIO_FN(D16), + GPIO_FN(BACK), + GPIO_FN(BREQ), + GPIO_FN(WE3), + GPIO_FN(WE2), + GPIO_FN(CS6), + GPIO_FN(CS5), + GPIO_FN(CS4), + GPIO_FN(CLKOUTENB), + GPIO_FN(DACK3), + GPIO_FN(DACK2), + GPIO_FN(DACK1), + GPIO_FN(DACK0), + GPIO_FN(DREQ3), + GPIO_FN(DREQ2), + GPIO_FN(DREQ1), + GPIO_FN(DREQ0), + GPIO_FN(IRQ3), + GPIO_FN(IRQ2), + GPIO_FN(IRQ1), + GPIO_FN(IRQ0), + GPIO_FN(DRAK3), + GPIO_FN(DRAK2), + GPIO_FN(DRAK1), + GPIO_FN(DRAK0), + GPIO_FN(SCK3), + GPIO_FN(SCK2), + GPIO_FN(SCK1), + GPIO_FN(SCK0), + GPIO_FN(IRL3), + GPIO_FN(IRL2), + GPIO_FN(IRL1), + GPIO_FN(IRL0), + GPIO_FN(TXD3), + GPIO_FN(TXD2), + GPIO_FN(TXD1), + GPIO_FN(TXD0), + GPIO_FN(RXD3), + GPIO_FN(RXD2), + GPIO_FN(RXD1), + GPIO_FN(RXD0), + GPIO_FN(CE2B), + GPIO_FN(CE2A), + GPIO_FN(IOIS16), + GPIO_FN(STATUS1), + GPIO_FN(STATUS0), + GPIO_FN(IRQOUT), }; static struct pinmux_cfg_reg shx3_pinmux_config_regs[] = { -- cgit From d7a7ca5781fa2ac40319acc7125c487db5b26d91 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 28 Nov 2012 17:51:00 +0100 Subject: sh-pfc: Replace first_gpio and last_gpio with nr_gpios The SoC information first_gpio field is always equal to 0, and the last_gpio field is the index of the last entry in the pinmux_gpios array. Replace the first_gpio and last_gpio fields by a nr_gpios field, and initialize it to ARRAY_SIZE(pinmux_gpios). Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 2 +- drivers/pinctrl/sh-pfc/gpio.c | 11 ++++------- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7724.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7757.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 5 ++--- drivers/pinctrl/sh-pfc/pfc-shx3.c | 3 +-- drivers/pinctrl/sh-pfc/pinctrl.c | 16 +++++----------- drivers/pinctrl/sh-pfc/sh_pfc.h | 4 ++-- 20 files changed, 43 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 970ddff2b0b6..1b86a906a97b 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -260,7 +260,7 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) struct pinmux_data_reg *drp; int k; - for (k = pfc->info->first_gpio; k <= pfc->info->last_gpio; k++) + for (k = 0; k < pfc->info->nr_gpios; k++) sh_pfc_setup_data_reg(pfc, k); k = 0; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index a535075c8b69..f46f06997b99 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -130,12 +130,10 @@ static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip) gc->set = sh_gpio_set; gc->to_irq = sh_gpio_to_irq; - WARN_ON(pfc->info->first_gpio != 0); /* needs testing */ - gc->label = pfc->info->name; gc->owner = THIS_MODULE; - gc->base = pfc->info->first_gpio; - gc->ngpio = (pfc->info->last_gpio - pfc->info->first_gpio) + 1; + gc->base = 0; + gc->ngpio = pfc->info->nr_gpios; } int sh_pfc_register_gpiochip(struct sh_pfc *pfc) @@ -157,9 +155,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) pfc->gpio = chip; - pr_info("%s handling gpio %d -> %d\n", - pfc->info->name, pfc->info->first_gpio, - pfc->info->last_gpio); + pr_info("%s handling gpio 0 -> %u\n", + pfc->info->name, pfc->info->nr_gpios - 1); return 0; } diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index 214788c4a606..c189a86fe8d3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2597,10 +2597,9 @@ struct sh_pfc_soc_info r8a7740_pinmux_info = { .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PORT0, - .last_gpio = GPIO_FN_TRACEAUD_FROM_MEMC, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 13feaa0c0eb7..16ec97a31b38 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2612,10 +2612,9 @@ struct sh_pfc_soc_info r8a7779_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_GP_0_0, - .last_gpio = GPIO_FN_SCK4_B, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index 22be49b3bd38..6cc67017e8fe 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -1580,10 +1580,9 @@ struct sh_pfc_soc_info sh7203_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA7, - .last_gpio = GPIO_FN_LCD_DATA0, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index ebe9c7ceb575..c2ecc65ff252 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -2119,10 +2119,9 @@ struct sh_pfc_soc_info sh7264_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA3, - .last_gpio = GPIO_FN_LCD_M_DISP, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index 87cb6933e02b..2013f4fa24f2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -2822,10 +2822,9 @@ struct sh_pfc_soc_info sh7269_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA1, - .last_gpio = GPIO_FN_LCD_M_DISP, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index d44e7f02069b..332cf34a867f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -1643,10 +1643,9 @@ struct sh_pfc_soc_info sh7372_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PORT0, - .last_gpio = GPIO_FN_SDENC_DV_CLKI, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 232731bcdd22..d5ee0f7680af 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2779,10 +2779,9 @@ struct sh_pfc_soc_info sh73a0_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PORT0, - .last_gpio = GPIO_FN_FSIAISLD_PU, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index e2e4520a14c4..8646237e9dff 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -1223,10 +1223,9 @@ struct sh_pfc_soc_info sh7720_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PTA7, - .last_gpio = GPIO_FN_STATUS1, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index 225fa96b6a21..194ae3de5a05 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -1767,10 +1767,9 @@ struct sh_pfc_soc_info sh7722_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PTA7, - .last_gpio = GPIO_FN_KEYOUT5_IN5, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index 49fd5c82e3cf..f31aa4f6b165 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -1891,10 +1891,9 @@ struct sh_pfc_soc_info sh7723_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PTA7, - .last_gpio = GPIO_FN_IDEA0, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 054b700a7e01..64b69b709f0f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -2213,10 +2213,9 @@ struct sh_pfc_soc_info sh7724_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PTA7, - .last_gpio = GPIO_FN_INTC_IRQ0, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index 23d76d262c32..d67a572de822 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -2463,10 +2463,9 @@ struct sh_pfc_soc_info sh7734_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_GP_0_0, - .last_gpio = GPIO_FN_ST_CLKOUT, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index ffbd8b7ee72e..7fc1310faf9c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -2270,10 +2270,9 @@ struct sh_pfc_soc_info sh7757_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PTA0, - .last_gpio = GPIO_FN_ON_DQ0, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 2e9d7cbec783..4bde4b56de58 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -1292,10 +1292,9 @@ struct sh_pfc_soc_info sh7785_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA7, - .last_gpio = GPIO_FN_IRQOUT, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index c9d8f500a6d3..9a42d25312d9 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -825,10 +825,9 @@ struct sh_pfc_soc_info sh7786_pinmux_info = { .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA7, - .last_gpio = GPIO_FN_IRL4, - .gpios = pinmux_gpios, + .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index 04e89407aecd..b23f5f9a8429 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -572,9 +572,8 @@ struct sh_pfc_soc_info shx3_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .first_gpio = GPIO_PA7, - .last_gpio = GPIO_FN_STATUS0, .gpios = shx3_pinmux_gpios, + .nr_gpios = ARRAY_SIZE(shx3_pinmux_gpios), .gpio_data = shx3_pinmux_data, .gpio_data_size = ARRAY_SIZE(shx3_pinmux_data), .cfg_regs = shx3_pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 4ce2753cb2df..908b5362b1cd 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -336,7 +336,7 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { int i; - pmx->nr_pads = pfc->info->last_gpio - pfc->info->first_gpio + 1; + pmx->nr_pads = pfc->info->nr_gpios; pmx->pads = devm_kzalloc(pfc->dev, sizeof(*pmx->pads) * pmx->nr_pads, GFP_KERNEL); @@ -345,17 +345,11 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) return -ENOMEM; } - /* - * We don't necessarily have a 1:1 mapping between pin and linux - * GPIO number, as the latter maps to the associated enum_id. - * Care needs to be taken to translate back to pin space when - * dealing with any pin configurations. - */ for (i = 0; i < pmx->nr_pads; i++) { struct pinctrl_pin_desc *pin = pmx->pads + i; struct pinmux_gpio *gpio = pfc->info->gpios + i; - pin->number = pfc->info->first_gpio + i; + pin->number = i; pin->name = gpio->name; /* XXX */ @@ -421,9 +415,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->range.name = DRV_NAME, pmx->range.id = 0; - pmx->range.npins = pfc->info->last_gpio - pfc->info->first_gpio + 1; - pmx->range.base = pfc->info->first_gpio; - pmx->range.pin_base = pfc->info->first_gpio; + pmx->range.npins = pfc->info->nr_gpios; + pmx->range.base = 0; + pmx->range.pin_base = 0; pinctrl_add_gpio_range(pmx->pctl, &pmx->range); diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 13049c4c8d30..67fe91b051cb 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -99,9 +99,9 @@ struct sh_pfc_soc_info { struct pinmux_range mark; struct pinmux_range function; - unsigned first_gpio, last_gpio; - struct pinmux_gpio *gpios; + unsigned int nr_gpios; + struct pinmux_cfg_reg *cfg_regs; struct pinmux_data_reg *data_regs; -- cgit From caa5bac3b4749ae3dca1db33d648280197f91a56 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 12:24:51 +0100 Subject: sh-pfc: Replace SoC info data and mark ranges with a number of pins The data and mark ranges are only used to check whether a GPIO corresponds to a real pin or a function. As pins come first in the list of GPIOs and in the platform-specific GPIO enumerations, we can replace the data and mark ranges by a number of pins. Add an nr_pins field to struct sh_pfc_soc_info to store the number of pins implemented by the SoC, remove the data and mark range fields and introduce sh_pfc_gpio_is_pin() and sh_pfc_gpio_is_function() functions to replace range-based checks. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 27 +++++++++++++++++++-------- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 5 +---- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7724.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7757.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 3 +-- drivers/pinctrl/sh-pfc/pfc-shx3.c | 3 +-- drivers/pinctrl/sh-pfc/sh_pfc.h | 3 +-- 18 files changed, 36 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 1b86a906a97b..e7ad0d93fed4 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -89,6 +89,18 @@ static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) return 1; } +static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) +{ + return (gpio < pfc->info->nr_pins) && + (pfc->info->gpios[gpio].enum_id != 0); +} + +static bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) +{ + return (gpio >= pfc->info->nr_pins) && (gpio < pfc->info->nr_gpios) && + (pfc->info->gpios[gpio].enum_id != 0); +} + static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned long reg_width) { @@ -226,7 +238,7 @@ static int sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) struct pinmux_data_reg *data_reg; int k, n; - if (!sh_pfc_enum_in_range(gpiop->enum_id, &pfc->info->data)) + if (!sh_pfc_gpio_is_pin(pfc, gpio)) return -1; k = 0; @@ -260,7 +272,7 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) struct pinmux_data_reg *drp; int k; - for (k = 0; k < pfc->info->nr_gpios; k++) + for (k = 0; k < pfc->info->nr_pins; k++) sh_pfc_setup_data_reg(pfc, k); k = 0; @@ -282,7 +294,7 @@ int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_gpio *gpiop = &pfc->info->gpios[gpio]; int k, n; - if (!sh_pfc_enum_in_range(gpiop->enum_id, &pfc->info->data)) + if (!sh_pfc_gpio_is_pin(pfc, gpio)) return -1; k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; @@ -344,11 +356,10 @@ int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, pinmux_enum_t *data = pfc->info->gpio_data; int k; - if (!sh_pfc_enum_in_range(enum_id, &pfc->info->data)) { - if (!sh_pfc_enum_in_range(enum_id, &pfc->info->mark)) { - pr_err("non data/mark enum_id for gpio %d\n", gpio); - return -1; - } + if (!sh_pfc_gpio_is_pin(pfc, gpio) && + !sh_pfc_gpio_is_function(pfc, gpio)) { + pr_err("non data/mark enum_id for gpio %d\n", gpio); + return -1; } if (pos) { diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index c189a86fe8d3..f1ef9f77dd83 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2582,8 +2582,6 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info r8a7740_pinmux_info = { .name = "r8a7740_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, - PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, @@ -2592,12 +2590,11 @@ struct sh_pfc_soc_info r8a7740_pinmux_info = { PINMUX_INPUT_PULLDOWN_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, - PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PORT211 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 16ec97a31b38..c8018ce0e894 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2606,13 +2606,12 @@ struct sh_pfc_soc_info r8a7779_pinmux_info = { .unlock_reg = 0xfffc0000, /* PMMR */ .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_GP_6_8 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index 6cc67017e8fe..07377e4920a3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -1574,13 +1574,12 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7203_pinmux_info = { .name = "sh7203_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PF0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index c2ecc65ff252..21b5899f32cb 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -2113,13 +2113,12 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7264_pinmux_info = { .name = "sh7264_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PK0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index 2013f4fa24f2..b722de1e7b28 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -2816,13 +2816,12 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7269_pinmux_info = { .name = "sh7269_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PJ0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 332cf34a867f..0c56f579fc0f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -1635,15 +1635,14 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info sh7372_pinmux_info = { .name = "sh7372_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PORT190 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index d5ee0f7680af..6573dbab7b27 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2771,15 +2771,14 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info sh73a0_pinmux_info = { .name = "sh73a0_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PORT309 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 8646237e9dff..48771779946c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -1216,14 +1216,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7720_pinmux_info = { .name = "sh7720_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PTV0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index 194ae3de5a05..7cedac6e735d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -1759,15 +1759,14 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7722_pinmux_info = { .name = "sh7722_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PTZ1 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index f31aa4f6b165..160edf01c04b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -1884,14 +1884,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7723_pinmux_info = { .name = "sh7723_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PTZ0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 64b69b709f0f..269f33d6eb0a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -2206,14 +2206,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7724_pinmux_info = { .name = "sh7724_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PTZ0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index d67a572de822..be5cca66815e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -2457,13 +2457,12 @@ struct sh_pfc_soc_info sh7734_pinmux_info = { .unlock_reg = 0xFFFC0000, .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_GP_5_11 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index 7fc1310faf9c..d95f5b8ae36f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -2263,14 +2263,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7757_pinmux_info = { .name = "sh7757_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PTZ7 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 4bde4b56de58..0d4c6de2c0be 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -1285,14 +1285,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7785_pinmux_info = { .name = "sh7785_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PR0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index 9a42d25312d9..2981d0be82a5 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -818,14 +818,13 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7786_pinmux_info = { .name = "sh7786_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = pinmux_gpios, + .nr_pins = GPIO_PJ0 + 1, .nr_gpios = ARRAY_SIZE(pinmux_gpios), .cfg_regs = pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index b23f5f9a8429..e985099b7777 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -565,14 +565,13 @@ static struct pinmux_data_reg shx3_pinmux_data_regs[] = { struct sh_pfc_soc_info shx3_pinmux_info = { .name = "shx3_pfc", .reserved_id = PINMUX_RESERVED, - .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, - .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, .gpios = shx3_pinmux_gpios, + .nr_pins = GPIO_PH0 + 1, .nr_gpios = ARRAY_SIZE(shx3_pinmux_gpios), .gpio_data = shx3_pinmux_data, .gpio_data_size = ARRAY_SIZE(shx3_pinmux_data), diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 67fe91b051cb..c50fb51a7fac 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -91,15 +91,14 @@ struct pinmux_range { struct sh_pfc_soc_info { char *name; pinmux_enum_t reserved_id; - struct pinmux_range data; struct pinmux_range input; struct pinmux_range input_pd; struct pinmux_range input_pu; struct pinmux_range output; - struct pinmux_range mark; struct pinmux_range function; struct pinmux_gpio *gpios; + unsigned int nr_pins; unsigned int nr_gpios; struct pinmux_cfg_reg *cfg_regs; -- cgit From 53f374b13413c072ec4717703479ef7d5b632f90 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 16:18:24 +0100 Subject: sh-pfc: Remove unused sh_pfc_soc_info reserved_id field The field is unused, remove it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 1 - drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7203.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7264.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7269.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7372.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7720.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7722.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7723.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7724.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7734.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7757.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7785.c | 1 - drivers/pinctrl/sh-pfc/pfc-sh7786.c | 1 - drivers/pinctrl/sh-pfc/pfc-shx3.c | 1 - drivers/pinctrl/sh-pfc/sh_pfc.h | 1 - 17 files changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index f1ef9f77dd83..957502ebcc5b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2581,7 +2581,6 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info r8a7740_pinmux_info = { .name = "r8a7740_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index c8018ce0e894..bd5a70d5247f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2605,7 +2605,6 @@ struct sh_pfc_soc_info r8a7779_pinmux_info = { .unlock_reg = 0xfffc0000, /* PMMR */ - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index 07377e4920a3..ee972f0bc696 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -1573,7 +1573,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7203_pinmux_info = { .name = "sh7203_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index 21b5899f32cb..44066dec1c3f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -2112,7 +2112,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7264_pinmux_info = { .name = "sh7264_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index b722de1e7b28..072c7d5da512 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -2815,7 +2815,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7269_pinmux_info = { .name = "sh7269_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 0c56f579fc0f..c11207442415 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -1634,7 +1634,6 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info sh7372_pinmux_info = { .name = "sh7372_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 6573dbab7b27..e41aa21edac0 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2770,7 +2770,6 @@ static struct pinmux_irq pinmux_irqs[] = { struct sh_pfc_soc_info sh73a0_pinmux_info = { .name = "sh73a0_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 48771779946c..294b75858c9e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -1215,7 +1215,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7720_pinmux_info = { .name = "sh7720_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index 7cedac6e735d..e7eadaf8e444 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -1758,7 +1758,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7722_pinmux_info = { .name = "sh7722_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index 160edf01c04b..06b1d736001d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -1883,7 +1883,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7723_pinmux_info = { .name = "sh7723_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 269f33d6eb0a..41160a3efb40 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -2205,7 +2205,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7724_pinmux_info = { .name = "sh7724_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index be5cca66815e..df32e71625b1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -2456,7 +2456,6 @@ struct sh_pfc_soc_info sh7734_pinmux_info = { .unlock_reg = 0xFFFC0000, - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index d95f5b8ae36f..dd32f347ce5a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -2262,7 +2262,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7757_pinmux_info = { .name = "sh7757_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 0d4c6de2c0be..447bd921b0ea 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -1284,7 +1284,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7785_pinmux_info = { .name = "sh7785_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index 2981d0be82a5..dee3cfbe3bbe 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -817,7 +817,6 @@ static struct pinmux_data_reg pinmux_data_regs[] = { struct sh_pfc_soc_info sh7786_pinmux_info = { .name = "sh7786_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index e985099b7777..e59da7999348 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -564,7 +564,6 @@ static struct pinmux_data_reg shx3_pinmux_data_regs[] = { struct sh_pfc_soc_info shx3_pinmux_info = { .name = "shx3_pfc", - .reserved_id = PINMUX_RESERVED, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index c50fb51a7fac..2627a89273ee 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -90,7 +90,6 @@ struct pinmux_range { struct sh_pfc_soc_info { char *name; - pinmux_enum_t reserved_id; struct pinmux_range input; struct pinmux_range input_pd; struct pinmux_range input_pu; -- cgit From 380c2ed92412d519c71d8c270d6b073b2c5bfdec Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 02:23:26 +0100 Subject: sh-pfc: Initialize pinmux_gpio flags statically All function GPIO entries are initialized with the GPIO_FN macro that expands to the PINMUX_GPIO macro, used to initialize real GPIOs. Create a PINMUX_GPIO_FN macro that duplicates PINMUX_GPIO and sets flags to PINMUX_TYPE_FUNCTION and use it in GPIO_FN, and make PINMUX_GPIO set flags to PINMUX_TYPE_GPIO. This removes the need to initialize GPIO flags at runtime and thus simplifies the code, preparing for the GPIO and functions split. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 19 ++----------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 908b5362b1cd..682b3a62b080 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -315,22 +315,6 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, }; -static void sh_pfc_map_one_gpio(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx, - struct pinmux_gpio *gpio, unsigned offset) -{ - struct pinmux_data_reg *dummy; - int bit; - - gpio->flags &= ~PINMUX_FLAG_TYPE; - - if (sh_pfc_get_data_reg(pfc, offset, &dummy, &bit) == 0) - gpio->flags |= PINMUX_TYPE_GPIO; - else { - gpio->flags |= PINMUX_TYPE_FUNCTION; - pmx->nr_functions++; - } -} - /* pinmux ranges -> pinctrl pin descs */ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { @@ -356,7 +340,8 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) if (unlikely(!gpio->enum_id)) continue; - sh_pfc_map_one_gpio(pfc, pmx, gpio, i); + if ((gpio->flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_FUNCTION) + pmx->nr_functions++; } return 0; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 2627a89273ee..e15039504a1c 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -41,8 +41,18 @@ struct pinmux_gpio { const char *name; }; -#define PINMUX_GPIO(gpio, data_or_mark) \ - [gpio] = { .name = __stringify(gpio), .enum_id = data_or_mark, .flags = PINMUX_TYPE_NONE } +#define PINMUX_GPIO(gpio, data_or_mark) \ + [gpio] = { \ + .name = __stringify(gpio), \ + .enum_id = data_or_mark, \ + .flags = PINMUX_TYPE_GPIO \ + } +#define PINMUX_GPIO_FN(gpio, data_or_mark) \ + [gpio] = { \ + .name = __stringify(gpio), \ + .enum_id = data_or_mark, \ + .flags = PINMUX_TYPE_FUNCTION \ + } #define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 @@ -135,7 +145,7 @@ enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; #define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA) #define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str) #define GPIO_PORT_ALL() CPU_ALL_PORT(_GPIO_PORT, , unused) -#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK) +#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, str##_MARK) /* helper macro for pinmux_enum_t */ #define PORT_DATA_I(nr) \ -- cgit From 051fae4bec226b1b139e70d2416b57ce344dba19 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 28 Nov 2012 19:22:18 +0100 Subject: sh-pfc: Make struct pinmux_gpio enum_id field const This ensures that the field is not modified, which is a prerequisite for the rest of the PFC refactoring work. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/sh_pfc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index e15039504a1c..6ed7ab9d56d4 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -36,7 +36,7 @@ enum { #define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) struct pinmux_gpio { - pinmux_enum_t enum_id; + const pinmux_enum_t enum_id; pinmux_flag_t flags; const char *name; }; -- cgit From 2119f7c9afaf4c5fe88e9ffec1f34c5bc6b02f78 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 13:03:53 +0100 Subject: sh-pfc: Shrink the pinctrl GPIO range to include real GPIOs only As a step towards GPIO function removal, shorten the GPIO range registered with the pinctrl core. Function GPIOs are now handled in the GPIO handlers directly instead of going through the pinctrl API. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 2 +- drivers/pinctrl/sh-pfc/core.h | 1 + drivers/pinctrl/sh-pfc/gpio.c | 57 ++++++++++++++++++++++++++++++++++++++-- drivers/pinctrl/sh-pfc/pinctrl.c | 27 ++----------------- 4 files changed, 59 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index e7ad0d93fed4..bed2d23e2464 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -95,7 +95,7 @@ static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) (pfc->info->gpios[gpio].enum_id != 0); } -static bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) +bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) { return (gpio >= pfc->info->nr_pins) && (gpio < pfc->info->nr_gpios) && (pfc->info->gpios[gpio].enum_id != 0); diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index ba7c33c33599..dceaec0f6277 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -47,6 +47,7 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); +bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio); int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, pinmux_enum_t *enum_idp); int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index f46f06997b99..80a50d8a50e7 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -38,12 +38,51 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) static int sh_gpio_request(struct gpio_chip *gc, unsigned offset) { - return pinctrl_request_gpio(offset); + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int ret = -EINVAL; + + if (offset < pfc->info->nr_pins) + return pinctrl_request_gpio(offset); + + pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); + + spin_lock_irqsave(&pfc->lock, flags); + + if (!sh_pfc_gpio_is_function(pfc, offset)) + goto done; + + if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, + GPIO_CFG_DRYRUN)) + goto done; + + if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, + GPIO_CFG_REQ)) + goto done; + + ret = 0; + +done: + spin_unlock_irqrestore(&pfc->lock, flags); + return ret; } static void sh_gpio_free(struct gpio_chip *gc, unsigned offset) { - pinctrl_free_gpio(offset); + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned long flags; + int pinmux_type; + + if (offset < pfc->info->nr_pins) + return pinctrl_free_gpio(offset); + + spin_lock_irqsave(&pfc->lock, flags); + + pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; + + sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + + spin_unlock_irqrestore(&pfc->lock, flags); } static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value) @@ -70,12 +109,26 @@ static int sh_gpio_get_value(struct sh_pfc *pfc, unsigned gpio) static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset) { + struct sh_pfc *pfc = gpio_to_pfc(gc); + + if (offset >= pfc->info->nr_pins) { + /* Function GPIOs can only be requested, never configured. */ + return -EINVAL; + } + return pinctrl_gpio_direction_input(offset); } static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { + struct sh_pfc *pfc = gpio_to_pfc(gc); + + if (offset >= pfc->info->nr_pins) { + /* Function GPIOs can only be requested, never configured. */ + return -EINVAL; + } + sh_gpio_set_value(gpio_to_pfc(gc), offset, value); return pinctrl_gpio_direction_output(offset); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 682b3a62b080..747ee6487fd7 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -116,21 +116,6 @@ static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func, { } -static int sh_pfc_config_function(struct sh_pfc *pfc, unsigned offset) -{ - if (sh_pfc_config_gpio(pfc, offset, - PINMUX_TYPE_FUNCTION, - GPIO_CFG_DRYRUN) != 0) - return -EINVAL; - - if (sh_pfc_config_gpio(pfc, offset, - PINMUX_TYPE_FUNCTION, - GPIO_CFG_REQ) != 0) - return -EINVAL; - - return 0; -} - static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, int new_type) { @@ -198,19 +183,11 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; switch (pinmux_type) { - case PINMUX_TYPE_FUNCTION: - pr_notice_once("Use of GPIO API for function requests is " - "deprecated, convert to pinctrl\n"); - /* handle for now */ - ret = sh_pfc_config_function(pfc, offset); - if (unlikely(ret < 0)) - goto err; - - break; case PINMUX_TYPE_GPIO: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_OUTPUT: break; + case PINMUX_TYPE_FUNCTION: default: pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); ret = -ENOTSUPP; @@ -400,7 +377,7 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->range.name = DRV_NAME, pmx->range.id = 0; - pmx->range.npins = pfc->info->nr_gpios; + pmx->range.npins = pfc->info->nr_pins; pmx->range.base = 0; pmx->range.pin_base = 0; -- cgit From 24d6b36e91b0503cd1c88b34fa793c0c65fa767d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 18:00:32 +0100 Subject: sh-pfc: Don't needlessly check GPIO type in sh_gpio_free() The GPIO type is always PINMUX_TYPE_FUNCTION when freeing a function GPIO. Hardcode the type value. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/gpio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 80a50d8a50e7..8f01113d0ecb 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -71,16 +71,13 @@ static void sh_gpio_free(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); unsigned long flags; - int pinmux_type; if (offset < pfc->info->nr_pins) return pinctrl_free_gpio(offset); spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; - - sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } -- cgit From a373ed0aa229f06e7d699797669b664ef39d97c1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Nov 2012 13:24:07 +0100 Subject: sh-pfc: Split pins and functions definition tables Split the GPIOs table into a pins table for real GPIOs and a functions table for function GPIOs. Only register pins with the pinctrl core. The function GPIOs remain accessible as GPIOs. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 21 +++++++++++------- drivers/pinctrl/sh-pfc/gpio.c | 5 +++-- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 15 +++++++------ drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 14 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 15 +++++++------ drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7724.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7757.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pfc-shx3.c | 13 ++++++++---- drivers/pinctrl/sh-pfc/pinctrl.c | 41 ++++++++++++++++++------------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 19 +++++++++++------ 20 files changed, 193 insertions(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index bed2d23e2464..9dee3b911283 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -92,13 +92,14 @@ static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) { return (gpio < pfc->info->nr_pins) && - (pfc->info->gpios[gpio].enum_id != 0); + (pfc->info->pins[gpio].enum_id != 0); } bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) { - return (gpio >= pfc->info->nr_pins) && (gpio < pfc->info->nr_gpios) && - (pfc->info->gpios[gpio].enum_id != 0); + return (gpio >= pfc->info->nr_pins) && + (gpio < pfc->info->nr_pins + pfc->info->nr_func_gpios) && + (pfc->info->func_gpios[gpio - pfc->info->nr_pins].enum_id != 0); } static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, @@ -234,7 +235,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, static int sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) { - struct pinmux_gpio *gpiop = &pfc->info->gpios[gpio]; + struct pinmux_pin *gpiop = &pfc->info->pins[gpio]; struct pinmux_data_reg *data_reg; int k, n; @@ -291,7 +292,7 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp) { - struct pinmux_gpio *gpiop = &pfc->info->gpios[gpio]; + struct pinmux_pin *gpiop = &pfc->info->pins[gpio]; int k, n; if (!sh_pfc_gpio_is_pin(pfc, gpio)) @@ -352,12 +353,16 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, pinmux_enum_t *enum_idp) { - pinmux_enum_t enum_id = pfc->info->gpios[gpio].enum_id; pinmux_enum_t *data = pfc->info->gpio_data; + pinmux_enum_t enum_id; int k; - if (!sh_pfc_gpio_is_pin(pfc, gpio) && - !sh_pfc_gpio_is_function(pfc, gpio)) { + if (sh_pfc_gpio_is_pin(pfc, gpio)) { + enum_id = pfc->info->pins[gpio].enum_id; + } else if (sh_pfc_gpio_is_function(pfc, gpio)) { + unsigned int offset = gpio - pfc->info->nr_pins; + enum_id = pfc->info->func_gpios[offset].enum_id; + } else { pr_err("non data/mark enum_id for gpio %d\n", gpio); return -1; } diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 8f01113d0ecb..2a99bef281ad 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -183,7 +183,7 @@ static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip) gc->label = pfc->info->name; gc->owner = THIS_MODULE; gc->base = 0; - gc->ngpio = pfc->info->nr_gpios; + gc->ngpio = pfc->info->nr_pins + pfc->info->nr_func_gpios; } int sh_pfc_register_gpiochip(struct sh_pfc *pfc) @@ -206,7 +206,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) pfc->gpio = chip; pr_info("%s handling gpio 0 -> %u\n", - pfc->info->name, pfc->info->nr_gpios - 1); + pfc->info->name, + pfc->info->nr_pins + pfc->info->nr_func_gpios - 1); return 0; } diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index 957502ebcc5b..a22763e3a32e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -1654,11 +1654,13 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(TRACEAUD_FROM_MEMC_MARK, MSEL5CR_30_1, MSEL5CR_29_0), }; -static struct pinmux_gpio pinmux_gpios[] = { - - /* PORT */ +static struct pinmux_pin pinmux_pins[] = { GPIO_PORT_ALL(), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* IRQ */ GPIO_FN(IRQ0_PORT2), GPIO_FN(IRQ0_PORT13), GPIO_FN(IRQ1), @@ -2592,9 +2594,10 @@ struct sh_pfc_soc_info r8a7740_pinmux_info = { .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PORT211 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index bd5a70d5247f..f771239f93e4 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1450,8 +1450,13 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_IPSR_MODSEL_DATA(IP12_17_15, SCK4_B, SEL_SCIF4_1), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) + +static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(AVS1), GPIO_FN(AVS2), GPIO_FN(A17), GPIO_FN(A18), GPIO_FN(A19), @@ -2609,9 +2614,10 @@ struct sh_pfc_soc_info r8a7779_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_GP_6_8 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index ee972f0bc696..17e2d06cf7a0 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -703,7 +703,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SSCK0_PF_MARK, PF0MD_11), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), @@ -815,7 +815,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PF2, PF2_DATA), PINMUX_GPIO(GPIO_PF1, PF1_DATA), PINMUX_GPIO(GPIO_PF0, PF0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(PINT7_PB), GPIO_FN(PINT6_PB), @@ -1577,9 +1581,10 @@ struct sh_pfc_soc_info sh7203_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PF0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index 44066dec1c3f..b927440564b7 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -1072,7 +1072,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SD_D2_MARK, PK0MD_10), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* Port A */ PINMUX_GPIO(GPIO_PA3, PA3_DATA), @@ -1216,7 +1216,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PK2, PK2_DATA), PINMUX_GPIO(GPIO_PK1, PK1_DATA), PINMUX_GPIO(GPIO_PK0, PK0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(PINT7_PG), GPIO_FN(PINT6_PG), @@ -2116,9 +2120,10 @@ struct sh_pfc_soc_info sh7264_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PK0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index 072c7d5da512..8f9b975670c2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -1452,7 +1452,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(PWM1A_MARK, PJ0MD_100), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* Port A */ PINMUX_GPIO(GPIO_PA1, PA1_DATA), PINMUX_GPIO(GPIO_PA0, PA0_DATA), @@ -1613,7 +1613,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PJ2, PJ2_DATA), PINMUX_GPIO(GPIO_PJ1, PJ1_DATA), PINMUX_GPIO(GPIO_PJ0, PJ0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(IRQ7_PG), GPIO_FN(IRQ6_PG), @@ -2819,9 +2823,10 @@ struct sh_pfc_soc_info sh7269_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PJ0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index c11207442415..3a1961b3d902 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -929,11 +929,13 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(MFIv4_MARK, MSEL4CR_6_1), }; -static struct pinmux_gpio pinmux_gpios[] = { - - /* PORT */ +static struct pinmux_pin pinmux_pins[] = { GPIO_PORT_ALL(), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* IRQ */ GPIO_FN(IRQ0_6), GPIO_FN(IRQ0_162), GPIO_FN(IRQ1), GPIO_FN(IRQ2_4), GPIO_FN(IRQ2_5), GPIO_FN(IRQ3_8), @@ -1640,9 +1642,10 @@ struct sh_pfc_soc_info sh7372_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PORT190 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index e41aa21edac0..02cb1dc6d12e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1539,9 +1539,13 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { GPIO_PORT_ALL(), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* Table 25-1 (Functions 0-7) */ GPIO_FN(VBUS_0), GPIO_FN(GPI0), @@ -2776,9 +2780,10 @@ struct sh_pfc_soc_info sh73a0_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PORT309 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 294b75858c9e..9952a7c2d287 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -606,7 +606,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SIM_CLK_MARK, PSELD_1_0_10, PTV0_FN), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), @@ -759,7 +759,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTV2, PTV2_DATA), PINMUX_GPIO(GPIO_PTV1, PTV1_DATA), PINMUX_GPIO(GPIO_PTV0, PTV0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* BSC */ GPIO_FN(D31), GPIO_FN(D30), @@ -1220,9 +1224,10 @@ struct sh_pfc_soc_info sh7720_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PTV0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index e7eadaf8e444..d561737a385b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -787,7 +787,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(KEYOUT5_IN5_MARK, HIZA14_KEYSC, KEYOUT5_IN5), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), @@ -982,7 +982,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA), PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA), PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* SCIF0 */ GPIO_FN(SCIF0_TXD), GPIO_FN(SCIF0_RXD), @@ -1764,9 +1768,10 @@ struct sh_pfc_soc_info sh7722_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PTZ1 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index 06b1d736001d..60831bfa177a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -923,7 +923,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SIUBISLD_MARK, PSD1_PSD0_FN2, PTZ0_FN), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), @@ -1139,7 +1139,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA), PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* SCIF0 */ GPIO_FN(SCIF0_PTT_TXD), GPIO_FN(SCIF0_PTT_RXD), @@ -1888,9 +1892,10 @@ struct sh_pfc_soc_info sh7723_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PTZ0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 41160a3efb40..0b9d16ed3524 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -1192,7 +1192,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SCIF3_I_TXD_MARK, PSB14_1, PTZ3_FN), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), @@ -1418,7 +1418,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA), PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* BSC */ GPIO_FN(D31), GPIO_FN(D30), @@ -2210,9 +2214,10 @@ struct sh_pfc_soc_info sh7724_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PTZ0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index df32e71625b1..e3bfeffba392 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -1384,9 +1384,13 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_IPSR_DATA(IP11_28, ST_CLKOUT), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CLKOUT), GPIO_FN(BS), GPIO_FN(CS0), GPIO_FN(EX_CS0), GPIO_FN(RD), GPIO_FN(WE0), GPIO_FN(WE1), GPIO_FN(SCL0), GPIO_FN(PENC0), GPIO_FN(USB_OVC0), @@ -2460,9 +2464,10 @@ struct sh_pfc_soc_info sh7734_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_GP_5_11 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index dd32f347ce5a..6e78358bbdef 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -1114,7 +1114,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(ON_DQ0_MARK, PS8_8_FN2, PTZ0_FN), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), @@ -1370,7 +1370,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA), PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* PTA (mobule: LBSC, RGMII) */ GPIO_FN(BS), GPIO_FN(RDWR), @@ -2267,9 +2271,10 @@ struct sh_pfc_soc_info sh7757_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PTZ7 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 447bd921b0ea..cce232d47276 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -702,7 +702,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(IRQOUT_MARK, P2MSEL2_1), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), @@ -845,7 +845,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PR2, PR2_DATA), PINMUX_GPIO(GPIO_PR1, PR1_DATA), PINMUX_GPIO(GPIO_PR0, PR0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* FN */ GPIO_FN(D63_AD31), GPIO_FN(D62_AD30), @@ -1289,9 +1293,10 @@ struct sh_pfc_soc_info sh7785_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PR0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index dee3cfbe3bbe..74a0e1128f22 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -427,7 +427,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SSI3_SCK_MARK, P2MSEL6_1, P2MSEL5_1, PJ1_FN), }; -static struct pinmux_gpio pinmux_gpios[] = { +static struct pinmux_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), @@ -505,7 +505,11 @@ static struct pinmux_gpio pinmux_gpios[] = { PINMUX_GPIO(GPIO_PJ3, PJ3_DATA), PINMUX_GPIO(GPIO_PJ2, PJ2_DATA), PINMUX_GPIO(GPIO_PJ1, PJ1_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_func pinmux_func_gpios[] = { /* FN */ GPIO_FN(CDE), GPIO_FN(ETH_MAGIC), @@ -822,9 +826,10 @@ struct sh_pfc_soc_info sh7786_pinmux_info = { .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = pinmux_gpios, - .nr_pins = GPIO_PJ0 + 1, - .nr_gpios = ARRAY_SIZE(pinmux_gpios), + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .func_gpios = pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), .cfg_regs = pinmux_config_regs, .data_regs = pinmux_data_regs, diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index e59da7999348..eeecffc562c1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -306,7 +306,7 @@ static pinmux_enum_t shx3_pinmux_data[] = { PINMUX_DATA(IRQOUT_MARK, PH0_FN), }; -static struct pinmux_gpio shx3_pinmux_gpios[] = { +static struct pinmux_pin shx3_pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), @@ -384,7 +384,11 @@ static struct pinmux_gpio shx3_pinmux_gpios[] = { PINMUX_GPIO(GPIO_PH2, PH2_DATA), PINMUX_GPIO(GPIO_PH1, PH1_DATA), PINMUX_GPIO(GPIO_PH0, PH0_DATA), +}; + +#define PINMUX_FN_BASE ARRAY_SIZE(shx3_pinmux_pins) +static struct pinmux_func shx3_pinmux_func_gpios[] = { /* FN */ GPIO_FN(D31), GPIO_FN(D30), @@ -569,9 +573,10 @@ struct sh_pfc_soc_info shx3_pinmux_info = { PINMUX_INPUT_PULLUP_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, - .gpios = shx3_pinmux_gpios, - .nr_pins = GPIO_PH0 + 1, - .nr_gpios = ARRAY_SIZE(shx3_pinmux_gpios), + .pins = shx3_pinmux_pins, + .nr_pins = ARRAY_SIZE(shx3_pinmux_pins), + .func_gpios = shx3_pinmux_func_gpios, + .nr_func_gpios = ARRAY_SIZE(shx3_pinmux_func_gpios), .gpio_data = shx3_pinmux_data, .gpio_data_size = ARRAY_SIZE(shx3_pinmux_data), .cfg_regs = shx3_pinmux_config_regs, diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 747ee6487fd7..77592900b601 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -32,7 +32,7 @@ struct sh_pfc_pinctrl { struct sh_pfc *pfc; - struct pinmux_gpio **functions; + struct pinmux_func **functions; unsigned int nr_functions; struct pinctrl_pin_desc *pads; @@ -125,7 +125,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; /* * See if the present config needs to first be de-configured. @@ -157,8 +157,8 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, GPIO_CFG_REQ) != 0) goto err; - pfc->info->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; - pfc->info->gpios[offset].flags |= new_type; + pfc->info->pins[offset].flags &= ~PINMUX_FLAG_TYPE; + pfc->info->pins[offset].flags |= new_type; ret = 0; @@ -168,7 +168,6 @@ err: return ret; } - static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -180,7 +179,7 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; switch (pinmux_type) { case PINMUX_TYPE_GPIO: @@ -213,7 +212,7 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->gpios[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); @@ -247,7 +246,7 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - *config = pfc->info->gpios[pin].flags & PINMUX_FLAG_TYPE; + *config = pfc->info->pins[pin].flags & PINMUX_FLAG_TYPE; return 0; } @@ -297,7 +296,7 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { int i; - pmx->nr_pads = pfc->info->nr_gpios; + pmx->nr_pads = pfc->info->nr_pins; pmx->pads = devm_kzalloc(pfc->dev, sizeof(*pmx->pads) * pmx->nr_pads, GFP_KERNEL); @@ -308,17 +307,10 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) for (i = 0; i < pmx->nr_pads; i++) { struct pinctrl_pin_desc *pin = pmx->pads + i; - struct pinmux_gpio *gpio = pfc->info->gpios + i; + struct pinmux_pin *gpio = pfc->info->pins + i; pin->number = i; pin->name = gpio->name; - - /* XXX */ - if (unlikely(!gpio->enum_id)) - continue; - - if ((gpio->flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_FUNCTION) - pmx->nr_functions++; } return 0; @@ -328,16 +320,23 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { int i, fn; + for (i = 0; i < pfc->info->nr_func_gpios; i++) { + struct pinmux_func *func = pfc->info->func_gpios + i; + + if (func->enum_id) + pmx->nr_functions++; + } + pmx->functions = devm_kzalloc(pfc->dev, pmx->nr_functions * sizeof(*pmx->functions), GFP_KERNEL); if (unlikely(!pmx->functions)) return -ENOMEM; - for (i = fn = 0; i < pmx->nr_pads; i++) { - struct pinmux_gpio *gpio = pfc->info->gpios + i; + for (i = fn = 0; i < pfc->info->nr_func_gpios; i++) { + struct pinmux_func *func = pfc->info->func_gpios + i; - if ((gpio->flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_FUNCTION) - pmx->functions[fn++] = gpio; + if (func->enum_id) + pmx->functions[fn++] = func; } return 0; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 6ed7ab9d56d4..940170a4c64f 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -35,23 +35,27 @@ enum { #define PINMUX_FLAG_DREG_SHIFT 10 #define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) -struct pinmux_gpio { +struct pinmux_pin { const pinmux_enum_t enum_id; pinmux_flag_t flags; const char *name; }; +struct pinmux_func { + const pinmux_enum_t enum_id; + const char *name; +}; + #define PINMUX_GPIO(gpio, data_or_mark) \ [gpio] = { \ .name = __stringify(gpio), \ .enum_id = data_or_mark, \ .flags = PINMUX_TYPE_GPIO \ } -#define PINMUX_GPIO_FN(gpio, data_or_mark) \ - [gpio] = { \ +#define PINMUX_GPIO_FN(gpio, base, data_or_mark) \ + [gpio - (base)] = { \ .name = __stringify(gpio), \ .enum_id = data_or_mark, \ - .flags = PINMUX_TYPE_FUNCTION \ } #define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 @@ -106,9 +110,10 @@ struct sh_pfc_soc_info { struct pinmux_range output; struct pinmux_range function; - struct pinmux_gpio *gpios; + struct pinmux_pin *pins; unsigned int nr_pins; - unsigned int nr_gpios; + struct pinmux_func *func_gpios; + unsigned int nr_func_gpios; struct pinmux_cfg_reg *cfg_regs; struct pinmux_data_reg *data_regs; @@ -145,7 +150,7 @@ enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; #define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA) #define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str) #define GPIO_PORT_ALL() CPU_ALL_PORT(_GPIO_PORT, , unused) -#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, str##_MARK) +#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, PINMUX_FN_BASE, str##_MARK) /* helper macro for pinmux_enum_t */ #define PORT_DATA_I(nr) \ -- cgit From 16883814eca229506cd2a4e447b2b5a2338fa35e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 6 Dec 2012 14:49:25 +0100 Subject: sh-pfc: Split pins and functions into separate gpio_chip instances Register two GPIO chips, one for the real GPIOs and one for the function GPIOs. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 2 +- drivers/pinctrl/sh-pfc/core.h | 3 +- drivers/pinctrl/sh-pfc/gpio.c | 227 ++++++++++++++++++++++++------------------ 3 files changed, 132 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 9dee3b911283..6cf39439694f 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -95,7 +95,7 @@ static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) (pfc->info->pins[gpio].enum_id != 0); } -bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) +static bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) { return (gpio >= pfc->info->nr_pins) && (gpio < pfc->info->nr_pins + pfc->info->nr_func_gpios) && diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index dceaec0f6277..5a0143b27e0b 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -33,6 +33,8 @@ struct sh_pfc { struct sh_pfc_window *window; struct sh_pfc_chip *gpio; + struct sh_pfc_chip *func; + struct sh_pfc_pinctrl *pinctrl; }; @@ -47,7 +49,6 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); -bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio); int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, pinmux_enum_t *enum_idp); int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 2a99bef281ad..82fcb5f9faf0 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -36,112 +36,62 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) return gpio_to_pfc_chip(gc)->pfc; } -static int sh_gpio_request(struct gpio_chip *gc, unsigned offset) -{ - struct sh_pfc *pfc = gpio_to_pfc(gc); - unsigned long flags; - int ret = -EINVAL; - - if (offset < pfc->info->nr_pins) - return pinctrl_request_gpio(offset); - - pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); - - spin_lock_irqsave(&pfc->lock, flags); - - if (!sh_pfc_gpio_is_function(pfc, offset)) - goto done; - - if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, - GPIO_CFG_DRYRUN)) - goto done; - - if (sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, - GPIO_CFG_REQ)) - goto done; - - ret = 0; - -done: - spin_unlock_irqrestore(&pfc->lock, flags); - return ret; -} +/* ----------------------------------------------------------------------------- + * Pin GPIOs + */ -static void sh_gpio_free(struct gpio_chip *gc, unsigned offset) +static int gpio_pin_request(struct gpio_chip *gc, unsigned offset) { - struct sh_pfc *pfc = gpio_to_pfc(gc); - unsigned long flags; - - if (offset < pfc->info->nr_pins) - return pinctrl_free_gpio(offset); - - spin_lock_irqsave(&pfc->lock, flags); - - sh_pfc_config_gpio(pfc, offset, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); - - spin_unlock_irqrestore(&pfc->lock, flags); + return pinctrl_request_gpio(offset); } -static void sh_gpio_set_value(struct sh_pfc *pfc, unsigned gpio, int value) +static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) { - struct pinmux_data_reg *dr = NULL; - int bit = 0; - - if (sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0) - BUG(); - else - sh_pfc_write_bit(dr, bit, value); + return pinctrl_free_gpio(offset); } -static int sh_gpio_get_value(struct sh_pfc *pfc, unsigned gpio) +static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) { struct pinmux_data_reg *dr = NULL; int bit = 0; - if (sh_pfc_get_data_reg(pfc, gpio, &dr, &bit) != 0) - return -EINVAL; + if (sh_pfc_get_data_reg(pfc, offset, &dr, &bit) != 0) + BUG(); - return sh_pfc_read_bit(dr, bit); + sh_pfc_write_bit(dr, bit, value); } -static int sh_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) { - struct sh_pfc *pfc = gpio_to_pfc(gc); - - if (offset >= pfc->info->nr_pins) { - /* Function GPIOs can only be requested, never configured. */ - return -EINVAL; - } - return pinctrl_gpio_direction_input(offset); } -static int sh_gpio_direction_output(struct gpio_chip *gc, unsigned offset, +static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset, int value) { - struct sh_pfc *pfc = gpio_to_pfc(gc); - - if (offset >= pfc->info->nr_pins) { - /* Function GPIOs can only be requested, never configured. */ - return -EINVAL; - } - - sh_gpio_set_value(gpio_to_pfc(gc), offset, value); + gpio_pin_set_value(gpio_to_pfc(gc), offset, value); return pinctrl_gpio_direction_output(offset); } -static int sh_gpio_get(struct gpio_chip *gc, unsigned offset) +static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { - return sh_gpio_get_value(gpio_to_pfc(gc), offset); + struct sh_pfc *pfc = gpio_to_pfc(gc); + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (sh_pfc_get_data_reg(pfc, offset, &dr, &bit) != 0) + return -EINVAL; + + return sh_pfc_read_bit(dr, bit); } -static void sh_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) { - sh_gpio_set_value(gpio_to_pfc(gc), offset, value); + gpio_pin_set_value(gpio_to_pfc(gc), offset, value); } -static int sh_gpio_to_irq(struct gpio_chip *gc, unsigned offset) +static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); pinmux_enum_t enum_id; @@ -167,60 +117,141 @@ static int sh_gpio_to_irq(struct gpio_chip *gc, unsigned offset) return -ENOSYS; } -static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip) +static void gpio_pin_setup(struct sh_pfc_chip *chip) { struct sh_pfc *pfc = chip->pfc; struct gpio_chip *gc = &chip->gpio_chip; - gc->request = sh_gpio_request; - gc->free = sh_gpio_free; - gc->direction_input = sh_gpio_direction_input; - gc->get = sh_gpio_get; - gc->direction_output = sh_gpio_direction_output; - gc->set = sh_gpio_set; - gc->to_irq = sh_gpio_to_irq; + gc->request = gpio_pin_request; + gc->free = gpio_pin_free; + gc->direction_input = gpio_pin_direction_input; + gc->get = gpio_pin_get; + gc->direction_output = gpio_pin_direction_output; + gc->set = gpio_pin_set; + gc->to_irq = gpio_pin_to_irq; gc->label = pfc->info->name; + gc->dev = pfc->dev; gc->owner = THIS_MODULE; gc->base = 0; - gc->ngpio = pfc->info->nr_pins + pfc->info->nr_func_gpios; + gc->ngpio = pfc->info->nr_pins; } -int sh_pfc_register_gpiochip(struct sh_pfc *pfc) +/* ----------------------------------------------------------------------------- + * Function GPIOs + */ + +static int gpio_function_request(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned int gpio = gc->base + offset; + unsigned long flags; + int ret = -EINVAL; + + pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); + + if (pfc->info->func_gpios[offset].enum_id == 0) + return ret; + + spin_lock_irqsave(&pfc->lock, flags); + + if (sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, + GPIO_CFG_DRYRUN)) + goto done; + + if (sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, + GPIO_CFG_REQ)) + goto done; + + ret = 0; + +done: + spin_unlock_irqrestore(&pfc->lock, flags); + return ret; +} + +static void gpio_function_free(struct gpio_chip *gc, unsigned offset) +{ + struct sh_pfc *pfc = gpio_to_pfc(gc); + unsigned int gpio = gc->base + offset; + unsigned long flags; + + spin_lock_irqsave(&pfc->lock, flags); + + sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); + + spin_unlock_irqrestore(&pfc->lock, flags); +} + +static void gpio_function_setup(struct sh_pfc_chip *chip) +{ + struct sh_pfc *pfc = chip->pfc; + struct gpio_chip *gc = &chip->gpio_chip; + + gc->request = gpio_function_request; + gc->free = gpio_function_free; + + gc->label = pfc->info->name; + gc->owner = THIS_MODULE; + gc->base = pfc->info->nr_pins; + gc->ngpio = pfc->info->nr_func_gpios; +} + +/* ----------------------------------------------------------------------------- + * Register/unregister + */ + +static struct sh_pfc_chip * +sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *)) { struct sh_pfc_chip *chip; int ret; chip = devm_kzalloc(pfc->dev, sizeof(*chip), GFP_KERNEL); if (unlikely(!chip)) - return -ENOMEM; + return ERR_PTR(-ENOMEM); chip->pfc = pfc; - sh_pfc_gpio_setup(chip); + setup(chip); ret = gpiochip_add(&chip->gpio_chip); if (unlikely(ret < 0)) - return ret; + return ERR_PTR(ret); + + pr_info("%s handling gpio %u -> %u\n", + chip->gpio_chip.label, chip->gpio_chip.base, + chip->gpio_chip.base + chip->gpio_chip.ngpio - 1); + + return chip; +} + +int sh_pfc_register_gpiochip(struct sh_pfc *pfc) +{ + struct sh_pfc_chip *chip; + + chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); + if (IS_ERR(chip)) + return PTR_ERR(chip); pfc->gpio = chip; - pr_info("%s handling gpio 0 -> %u\n", - pfc->info->name, - pfc->info->nr_pins + pfc->info->nr_func_gpios - 1); + chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + pfc->func = chip; return 0; } int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc) { - struct sh_pfc_chip *chip = pfc->gpio; + int err; int ret; - ret = gpiochip_remove(&chip->gpio_chip); - if (unlikely(ret < 0)) - return ret; + ret = gpiochip_remove(&pfc->gpio->gpio_chip); + err = gpiochip_remove(&pfc->func->gpio_chip); - pfc->gpio = NULL; - return 0; + return ret < 0 ? ret : err; } -- cgit From a3db40a68a5b2f3ed2190f586bdaf3904f4933b2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Jan 2013 14:53:37 +0100 Subject: sh-pfc: Rename struct pinmux_pin to struct sh_pfc_pin And drop the pinmux_flag_t typedef. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 4 ++-- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 2 +- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7724.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7757.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 2 +- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 2 +- drivers/pinctrl/sh-pfc/pfc-shx3.c | 2 +- drivers/pinctrl/sh-pfc/pinctrl.c | 2 +- drivers/pinctrl/sh-pfc/sh_pfc.h | 7 +++---- 19 files changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 6cf39439694f..f94d80c67ef3 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -235,7 +235,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, static int sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) { - struct pinmux_pin *gpiop = &pfc->info->pins[gpio]; + struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; struct pinmux_data_reg *data_reg; int k, n; @@ -292,7 +292,7 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp) { - struct pinmux_pin *gpiop = &pfc->info->pins[gpio]; + struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; int k, n; if (!sh_pfc_gpio_is_pin(pfc, gpio)) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index a22763e3a32e..ccf9161585d1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -1654,7 +1654,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(TRACEAUD_FROM_MEMC_MARK, MSEL5CR_30_1, MSEL5CR_29_0), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index f771239f93e4..0e536744f3d2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1450,7 +1450,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_IPSR_MODSEL_DATA(IP12_17_15, SCK4_B, SEL_SCIF4_1), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), }; diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index 17e2d06cf7a0..fc4a1280accb 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -703,7 +703,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SSCK0_PF_MARK, PF0MD_11), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index b927440564b7..c03365cd945d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -1072,7 +1072,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SD_D2_MARK, PK0MD_10), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* Port A */ PINMUX_GPIO(GPIO_PA3, PA3_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index 8f9b975670c2..1fa0950519e4 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -1452,7 +1452,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(PWM1A_MARK, PJ0MD_100), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* Port A */ PINMUX_GPIO(GPIO_PA1, PA1_DATA), PINMUX_GPIO(GPIO_PA0, PA0_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 3a1961b3d902..b15a16ab388d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -929,7 +929,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(MFIv4_MARK, MSEL4CR_6_1), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 02cb1dc6d12e..ca1e97aa6eda 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1539,7 +1539,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 9952a7c2d287..0b3078b6acdf 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -606,7 +606,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SIM_CLK_MARK, PSELD_1_0_10, PTV0_FN), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index d561737a385b..3a8d95fd3ed3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -787,7 +787,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(KEYOUT5_IN5_MARK, HIZA14_KEYSC, KEYOUT5_IN5), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index 60831bfa177a..d8797ff4339b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -923,7 +923,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SIUBISLD_MARK, PSD1_PSD0_FN2, PTZ0_FN), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 0b9d16ed3524..40f430be71a8 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -1192,7 +1192,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SCIF3_I_TXD_MARK, PSB14_1, PTZ3_FN), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index e3bfeffba392..20c44dd7001a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -1384,7 +1384,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_IPSR_DATA(IP11_28, ST_CLKOUT), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), }; diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index 6e78358bbdef..e81ab0ecea8c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -1114,7 +1114,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(ON_DQ0_MARK, PS8_8_FN2, PTZ0_FN), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PTA */ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index cce232d47276..6049f594d37e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -702,7 +702,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(IRQOUT_MARK, P2MSEL2_1), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index 74a0e1128f22..526e78482d5b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -427,7 +427,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SSI3_SCK_MARK, P2MSEL6_1, P2MSEL5_1, PJ1_FN), }; -static struct pinmux_pin pinmux_pins[] = { +static struct sh_pfc_pin pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index eeecffc562c1..93d60cd4c437 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -306,7 +306,7 @@ static pinmux_enum_t shx3_pinmux_data[] = { PINMUX_DATA(IRQOUT_MARK, PH0_FN), }; -static struct pinmux_pin shx3_pinmux_pins[] = { +static struct sh_pfc_pin shx3_pinmux_pins[] = { /* PA */ PINMUX_GPIO(GPIO_PA7, PA7_DATA), PINMUX_GPIO(GPIO_PA6, PA6_DATA), diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 77592900b601..d420d9981725 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -307,7 +307,7 @@ static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) for (i = 0; i < pmx->nr_pads; i++) { struct pinctrl_pin_desc *pin = pmx->pads + i; - struct pinmux_pin *gpio = pfc->info->pins + i; + struct sh_pfc_pin *gpio = pfc->info->pins + i; pin->number = i; pin->name = gpio->name; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 940170a4c64f..dae9e155be17 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -15,7 +15,6 @@ #include typedef unsigned short pinmux_enum_t; -typedef unsigned short pinmux_flag_t; enum { PINMUX_TYPE_NONE, @@ -35,9 +34,9 @@ enum { #define PINMUX_FLAG_DREG_SHIFT 10 #define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) -struct pinmux_pin { +struct sh_pfc_pin { const pinmux_enum_t enum_id; - pinmux_flag_t flags; + unsigned short flags; const char *name; }; @@ -110,7 +109,7 @@ struct sh_pfc_soc_info { struct pinmux_range output; struct pinmux_range function; - struct pinmux_pin *pins; + struct sh_pfc_pin *pins; unsigned int nr_pins; struct pinmux_func *func_gpios; unsigned int nr_func_gpios; -- cgit From c07f54f604b3b458f10452b60fe21c549218bf02 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 14:12:14 +0100 Subject: sh-pfc: Look up IRQ table entries by GPIO number Instead of converting the GPIO number to an enum_id and looking up IRQ table entries by enum_id, replace the pinmux_irq enum_ids field with a gpios field and lookup entries using the GPIO number. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 4 +-- drivers/pinctrl/sh-pfc/core.h | 2 -- drivers/pinctrl/sh-pfc/gpio.c | 25 +++++--------- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 64 ++++++++++++++++++------------------ drivers/pinctrl/sh-pfc/pfc-sh7372.c | 64 ++++++++++++++++++------------------ drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 64 ++++++++++++++++++------------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 4 +-- 7 files changed, 108 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index f94d80c67ef3..22f299993a36 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -350,8 +350,8 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, return -1; } -int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, - pinmux_enum_t *enum_idp) +static int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, + pinmux_enum_t *enum_idp) { pinmux_enum_t *data = pfc->info->gpio_data; pinmux_enum_t enum_id; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 5a0143b27e0b..f22d03f1e503 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -49,8 +49,6 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); -int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, - pinmux_enum_t *enum_idp); int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, int cfg_mode); diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 82fcb5f9faf0..454c965ea555 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -94,23 +94,14 @@ static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); - pinmux_enum_t enum_id; - pinmux_enum_t *enum_ids; - int i, k, pos; - - pos = 0; - enum_id = 0; - while (1) { - pos = sh_pfc_gpio_to_enum(pfc, offset, pos, &enum_id); - if (pos <= 0 || !enum_id) - break; - - for (i = 0; i < pfc->info->gpio_irq_size; i++) { - enum_ids = pfc->info->gpio_irq[i].enum_ids; - for (k = 0; enum_ids[k]; k++) { - if (enum_ids[k] == enum_id) - return pfc->info->gpio_irq[i].irq; - } + int i, k; + + for (i = 0; i < pfc->info->gpio_irq_size; i++) { + unsigned short *gpios = pfc->info->gpio_irq[i].gpios; + + for (k = 0; gpios[k]; k++) { + if (gpios[k] == offset) + return pfc->info->gpio_irq[i].irq; } } diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index ccf9161585d1..fd91381aaaf3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2547,38 +2547,38 @@ static struct pinmux_data_reg pinmux_data_regs[] = { }; static struct pinmux_irq pinmux_irqs[] = { - PINMUX_IRQ(evt2irq(0x0200), PORT2_FN0, PORT13_FN0), /* IRQ0A */ - PINMUX_IRQ(evt2irq(0x0220), PORT20_FN0), /* IRQ1A */ - PINMUX_IRQ(evt2irq(0x0240), PORT11_FN0, PORT12_FN0), /* IRQ2A */ - PINMUX_IRQ(evt2irq(0x0260), PORT10_FN0, PORT14_FN0), /* IRQ3A */ - PINMUX_IRQ(evt2irq(0x0280), PORT15_FN0, PORT172_FN0), /* IRQ4A */ - PINMUX_IRQ(evt2irq(0x02A0), PORT0_FN0, PORT1_FN0), /* IRQ5A */ - PINMUX_IRQ(evt2irq(0x02C0), PORT121_FN0, PORT173_FN0), /* IRQ6A */ - PINMUX_IRQ(evt2irq(0x02E0), PORT120_FN0, PORT209_FN0), /* IRQ7A */ - PINMUX_IRQ(evt2irq(0x0300), PORT119_FN0), /* IRQ8A */ - PINMUX_IRQ(evt2irq(0x0320), PORT118_FN0, PORT210_FN0), /* IRQ9A */ - PINMUX_IRQ(evt2irq(0x0340), PORT19_FN0), /* IRQ10A */ - PINMUX_IRQ(evt2irq(0x0360), PORT104_FN0), /* IRQ11A */ - PINMUX_IRQ(evt2irq(0x0380), PORT42_FN0, PORT97_FN0), /* IRQ12A */ - PINMUX_IRQ(evt2irq(0x03A0), PORT64_FN0, PORT98_FN0), /* IRQ13A */ - PINMUX_IRQ(evt2irq(0x03C0), PORT63_FN0, PORT99_FN0), /* IRQ14A */ - PINMUX_IRQ(evt2irq(0x03E0), PORT62_FN0, PORT100_FN0), /* IRQ15A */ - PINMUX_IRQ(evt2irq(0x3200), PORT68_FN0, PORT211_FN0), /* IRQ16A */ - PINMUX_IRQ(evt2irq(0x3220), PORT69_FN0), /* IRQ17A */ - PINMUX_IRQ(evt2irq(0x3240), PORT70_FN0), /* IRQ18A */ - PINMUX_IRQ(evt2irq(0x3260), PORT71_FN0), /* IRQ19A */ - PINMUX_IRQ(evt2irq(0x3280), PORT67_FN0), /* IRQ20A */ - PINMUX_IRQ(evt2irq(0x32A0), PORT202_FN0), /* IRQ21A */ - PINMUX_IRQ(evt2irq(0x32C0), PORT95_FN0), /* IRQ22A */ - PINMUX_IRQ(evt2irq(0x32E0), PORT96_FN0), /* IRQ23A */ - PINMUX_IRQ(evt2irq(0x3300), PORT180_FN0), /* IRQ24A */ - PINMUX_IRQ(evt2irq(0x3320), PORT38_FN0), /* IRQ25A */ - PINMUX_IRQ(evt2irq(0x3340), PORT58_FN0, PORT81_FN0), /* IRQ26A */ - PINMUX_IRQ(evt2irq(0x3360), PORT57_FN0, PORT168_FN0), /* IRQ27A */ - PINMUX_IRQ(evt2irq(0x3380), PORT56_FN0, PORT169_FN0), /* IRQ28A */ - PINMUX_IRQ(evt2irq(0x33A0), PORT50_FN0, PORT170_FN0), /* IRQ29A */ - PINMUX_IRQ(evt2irq(0x33C0), PORT49_FN0, PORT171_FN0), /* IRQ30A */ - PINMUX_IRQ(evt2irq(0x33E0), PORT41_FN0, PORT167_FN0), /* IRQ31A */ + PINMUX_IRQ(evt2irq(0x0200), GPIO_PORT2, GPIO_PORT13), /* IRQ0A */ + PINMUX_IRQ(evt2irq(0x0220), GPIO_PORT20), /* IRQ1A */ + PINMUX_IRQ(evt2irq(0x0240), GPIO_PORT11, GPIO_PORT12), /* IRQ2A */ + PINMUX_IRQ(evt2irq(0x0260), GPIO_PORT10, GPIO_PORT14), /* IRQ3A */ + PINMUX_IRQ(evt2irq(0x0280), GPIO_PORT15, GPIO_PORT172),/* IRQ4A */ + PINMUX_IRQ(evt2irq(0x02A0), GPIO_PORT0, GPIO_PORT1), /* IRQ5A */ + PINMUX_IRQ(evt2irq(0x02C0), GPIO_PORT121, GPIO_PORT173),/* IRQ6A */ + PINMUX_IRQ(evt2irq(0x02E0), GPIO_PORT120, GPIO_PORT209),/* IRQ7A */ + PINMUX_IRQ(evt2irq(0x0300), GPIO_PORT119), /* IRQ8A */ + PINMUX_IRQ(evt2irq(0x0320), GPIO_PORT118, GPIO_PORT210),/* IRQ9A */ + PINMUX_IRQ(evt2irq(0x0340), GPIO_PORT19), /* IRQ10A */ + PINMUX_IRQ(evt2irq(0x0360), GPIO_PORT104), /* IRQ11A */ + PINMUX_IRQ(evt2irq(0x0380), GPIO_PORT42, GPIO_PORT97), /* IRQ12A */ + PINMUX_IRQ(evt2irq(0x03A0), GPIO_PORT64, GPIO_PORT98), /* IRQ13A */ + PINMUX_IRQ(evt2irq(0x03C0), GPIO_PORT63, GPIO_PORT99), /* IRQ14A */ + PINMUX_IRQ(evt2irq(0x03E0), GPIO_PORT62, GPIO_PORT100),/* IRQ15A */ + PINMUX_IRQ(evt2irq(0x3200), GPIO_PORT68, GPIO_PORT211),/* IRQ16A */ + PINMUX_IRQ(evt2irq(0x3220), GPIO_PORT69), /* IRQ17A */ + PINMUX_IRQ(evt2irq(0x3240), GPIO_PORT70), /* IRQ18A */ + PINMUX_IRQ(evt2irq(0x3260), GPIO_PORT71), /* IRQ19A */ + PINMUX_IRQ(evt2irq(0x3280), GPIO_PORT67), /* IRQ20A */ + PINMUX_IRQ(evt2irq(0x32A0), GPIO_PORT202), /* IRQ21A */ + PINMUX_IRQ(evt2irq(0x32C0), GPIO_PORT95), /* IRQ22A */ + PINMUX_IRQ(evt2irq(0x32E0), GPIO_PORT96), /* IRQ23A */ + PINMUX_IRQ(evt2irq(0x3300), GPIO_PORT180), /* IRQ24A */ + PINMUX_IRQ(evt2irq(0x3320), GPIO_PORT38), /* IRQ25A */ + PINMUX_IRQ(evt2irq(0x3340), GPIO_PORT58, GPIO_PORT81), /* IRQ26A */ + PINMUX_IRQ(evt2irq(0x3360), GPIO_PORT57, GPIO_PORT168),/* IRQ27A */ + PINMUX_IRQ(evt2irq(0x3380), GPIO_PORT56, GPIO_PORT169),/* IRQ28A */ + PINMUX_IRQ(evt2irq(0x33A0), GPIO_PORT50, GPIO_PORT170),/* IRQ29A */ + PINMUX_IRQ(evt2irq(0x33C0), GPIO_PORT49, GPIO_PORT171),/* IRQ30A */ + PINMUX_IRQ(evt2irq(0x33E0), GPIO_PORT41, GPIO_PORT167),/* IRQ31A */ }; struct sh_pfc_soc_info r8a7740_pinmux_info = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index b15a16ab388d..847e0cd1b748 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -1600,38 +1600,38 @@ static struct pinmux_data_reg pinmux_data_regs[] = { #define EXT_IRQ16L(n) evt2irq(0x200 + ((n) << 5)) #define EXT_IRQ16H(n) evt2irq(0x3200 + (((n) - 16) << 5)) static struct pinmux_irq pinmux_irqs[] = { - PINMUX_IRQ(EXT_IRQ16L(0), PORT6_FN0, PORT162_FN0), - PINMUX_IRQ(EXT_IRQ16L(1), PORT12_FN0), - PINMUX_IRQ(EXT_IRQ16L(2), PORT4_FN0, PORT5_FN0), - PINMUX_IRQ(EXT_IRQ16L(3), PORT8_FN0, PORT16_FN0), - PINMUX_IRQ(EXT_IRQ16L(4), PORT17_FN0, PORT163_FN0), - PINMUX_IRQ(EXT_IRQ16L(5), PORT18_FN0), - PINMUX_IRQ(EXT_IRQ16L(6), PORT39_FN0, PORT164_FN0), - PINMUX_IRQ(EXT_IRQ16L(7), PORT40_FN0, PORT167_FN0), - PINMUX_IRQ(EXT_IRQ16L(8), PORT41_FN0, PORT168_FN0), - PINMUX_IRQ(EXT_IRQ16L(9), PORT42_FN0, PORT169_FN0), - PINMUX_IRQ(EXT_IRQ16L(10), PORT65_FN0), - PINMUX_IRQ(EXT_IRQ16L(11), PORT67_FN0), - PINMUX_IRQ(EXT_IRQ16L(12), PORT80_FN0, PORT137_FN0), - PINMUX_IRQ(EXT_IRQ16L(13), PORT81_FN0, PORT145_FN0), - PINMUX_IRQ(EXT_IRQ16L(14), PORT82_FN0, PORT146_FN0), - PINMUX_IRQ(EXT_IRQ16L(15), PORT83_FN0, PORT147_FN0), - PINMUX_IRQ(EXT_IRQ16H(16), PORT84_FN0, PORT170_FN0), - PINMUX_IRQ(EXT_IRQ16H(17), PORT85_FN0), - PINMUX_IRQ(EXT_IRQ16H(18), PORT86_FN0), - PINMUX_IRQ(EXT_IRQ16H(19), PORT87_FN0), - PINMUX_IRQ(EXT_IRQ16H(20), PORT92_FN0), - PINMUX_IRQ(EXT_IRQ16H(21), PORT93_FN0), - PINMUX_IRQ(EXT_IRQ16H(22), PORT94_FN0), - PINMUX_IRQ(EXT_IRQ16H(23), PORT95_FN0), - PINMUX_IRQ(EXT_IRQ16H(24), PORT112_FN0), - PINMUX_IRQ(EXT_IRQ16H(25), PORT119_FN0), - PINMUX_IRQ(EXT_IRQ16H(26), PORT121_FN0, PORT172_FN0), - PINMUX_IRQ(EXT_IRQ16H(27), PORT122_FN0, PORT180_FN0), - PINMUX_IRQ(EXT_IRQ16H(28), PORT123_FN0, PORT181_FN0), - PINMUX_IRQ(EXT_IRQ16H(29), PORT129_FN0, PORT182_FN0), - PINMUX_IRQ(EXT_IRQ16H(30), PORT130_FN0, PORT183_FN0), - PINMUX_IRQ(EXT_IRQ16H(31), PORT138_FN0, PORT184_FN0), + PINMUX_IRQ(EXT_IRQ16L(0), GPIO_PORT6, GPIO_PORT162), + PINMUX_IRQ(EXT_IRQ16L(1), GPIO_PORT12), + PINMUX_IRQ(EXT_IRQ16L(2), GPIO_PORT4, GPIO_PORT5), + PINMUX_IRQ(EXT_IRQ16L(3), GPIO_PORT8, GPIO_PORT16), + PINMUX_IRQ(EXT_IRQ16L(4), GPIO_PORT17, GPIO_PORT163), + PINMUX_IRQ(EXT_IRQ16L(5), GPIO_PORT18), + PINMUX_IRQ(EXT_IRQ16L(6), GPIO_PORT39, GPIO_PORT164), + PINMUX_IRQ(EXT_IRQ16L(7), GPIO_PORT40, GPIO_PORT167), + PINMUX_IRQ(EXT_IRQ16L(8), GPIO_PORT41, GPIO_PORT168), + PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT42, GPIO_PORT169), + PINMUX_IRQ(EXT_IRQ16L(10), GPIO_PORT65), + PINMUX_IRQ(EXT_IRQ16L(11), GPIO_PORT67), + PINMUX_IRQ(EXT_IRQ16L(12), GPIO_PORT80, GPIO_PORT137), + PINMUX_IRQ(EXT_IRQ16L(13), GPIO_PORT81, GPIO_PORT145), + PINMUX_IRQ(EXT_IRQ16L(14), GPIO_PORT82, GPIO_PORT146), + PINMUX_IRQ(EXT_IRQ16L(15), GPIO_PORT83, GPIO_PORT147), + PINMUX_IRQ(EXT_IRQ16H(16), GPIO_PORT84, GPIO_PORT170), + PINMUX_IRQ(EXT_IRQ16H(17), GPIO_PORT85), + PINMUX_IRQ(EXT_IRQ16H(18), GPIO_PORT86), + PINMUX_IRQ(EXT_IRQ16H(19), GPIO_PORT87), + PINMUX_IRQ(EXT_IRQ16H(20), GPIO_PORT92), + PINMUX_IRQ(EXT_IRQ16H(21), GPIO_PORT93), + PINMUX_IRQ(EXT_IRQ16H(22), GPIO_PORT94), + PINMUX_IRQ(EXT_IRQ16H(23), GPIO_PORT95), + PINMUX_IRQ(EXT_IRQ16H(24), GPIO_PORT112), + PINMUX_IRQ(EXT_IRQ16H(25), GPIO_PORT119), + PINMUX_IRQ(EXT_IRQ16H(26), GPIO_PORT121, GPIO_PORT172), + PINMUX_IRQ(EXT_IRQ16H(27), GPIO_PORT122, GPIO_PORT180), + PINMUX_IRQ(EXT_IRQ16H(28), GPIO_PORT123, GPIO_PORT181), + PINMUX_IRQ(EXT_IRQ16H(29), GPIO_PORT129, GPIO_PORT182), + PINMUX_IRQ(EXT_IRQ16H(30), GPIO_PORT130, GPIO_PORT183), + PINMUX_IRQ(EXT_IRQ16H(31), GPIO_PORT138, GPIO_PORT184), }; struct sh_pfc_soc_info sh7372_pinmux_info = { diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index ca1e97aa6eda..639b5e21d9bc 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2738,38 +2738,38 @@ static struct pinmux_data_reg pinmux_data_regs[] = { #define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) static struct pinmux_irq pinmux_irqs[] = { - PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0), - PINMUX_IRQ(EXT_IRQ16L(1), PORT10_FN0), - PINMUX_IRQ(EXT_IRQ16L(0), PORT11_FN0), - PINMUX_IRQ(EXT_IRQ16H(18), PORT13_FN0), - PINMUX_IRQ(EXT_IRQ16H(20), PORT14_FN0), - PINMUX_IRQ(EXT_IRQ16H(21), PORT15_FN0), - PINMUX_IRQ(EXT_IRQ16H(31), PORT26_FN0), - PINMUX_IRQ(EXT_IRQ16H(30), PORT27_FN0), - PINMUX_IRQ(EXT_IRQ16H(29), PORT28_FN0), - PINMUX_IRQ(EXT_IRQ16H(22), PORT40_FN0), - PINMUX_IRQ(EXT_IRQ16H(23), PORT53_FN0), - PINMUX_IRQ(EXT_IRQ16L(10), PORT54_FN0), - PINMUX_IRQ(EXT_IRQ16L(9), PORT56_FN0), - PINMUX_IRQ(EXT_IRQ16H(26), PORT115_FN0), - PINMUX_IRQ(EXT_IRQ16H(27), PORT116_FN0), - PINMUX_IRQ(EXT_IRQ16H(28), PORT117_FN0), - PINMUX_IRQ(EXT_IRQ16H(24), PORT118_FN0), - PINMUX_IRQ(EXT_IRQ16L(6), PORT147_FN0), - PINMUX_IRQ(EXT_IRQ16L(2), PORT149_FN0), - PINMUX_IRQ(EXT_IRQ16L(7), PORT150_FN0), - PINMUX_IRQ(EXT_IRQ16L(12), PORT156_FN0), - PINMUX_IRQ(EXT_IRQ16L(4), PORT159_FN0), - PINMUX_IRQ(EXT_IRQ16H(25), PORT164_FN0), - PINMUX_IRQ(EXT_IRQ16L(8), PORT223_FN0), - PINMUX_IRQ(EXT_IRQ16L(3), PORT224_FN0), - PINMUX_IRQ(EXT_IRQ16L(5), PORT227_FN0), - PINMUX_IRQ(EXT_IRQ16H(17), PORT234_FN0), - PINMUX_IRQ(EXT_IRQ16L(11), PORT238_FN0), - PINMUX_IRQ(EXT_IRQ16L(13), PORT239_FN0), - PINMUX_IRQ(EXT_IRQ16H(16), PORT249_FN0), - PINMUX_IRQ(EXT_IRQ16L(14), PORT251_FN0), - PINMUX_IRQ(EXT_IRQ16L(9), PORT308_FN0), + PINMUX_IRQ(EXT_IRQ16H(19), GPIO_PORT9), + PINMUX_IRQ(EXT_IRQ16L(1), GPIO_PORT10), + PINMUX_IRQ(EXT_IRQ16L(0), GPIO_PORT11), + PINMUX_IRQ(EXT_IRQ16H(18), GPIO_PORT13), + PINMUX_IRQ(EXT_IRQ16H(20), GPIO_PORT14), + PINMUX_IRQ(EXT_IRQ16H(21), GPIO_PORT15), + PINMUX_IRQ(EXT_IRQ16H(31), GPIO_PORT26), + PINMUX_IRQ(EXT_IRQ16H(30), GPIO_PORT27), + PINMUX_IRQ(EXT_IRQ16H(29), GPIO_PORT28), + PINMUX_IRQ(EXT_IRQ16H(22), GPIO_PORT40), + PINMUX_IRQ(EXT_IRQ16H(23), GPIO_PORT53), + PINMUX_IRQ(EXT_IRQ16L(10), GPIO_PORT54), + PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT56), + PINMUX_IRQ(EXT_IRQ16H(26), GPIO_PORT115), + PINMUX_IRQ(EXT_IRQ16H(27), GPIO_PORT116), + PINMUX_IRQ(EXT_IRQ16H(28), GPIO_PORT117), + PINMUX_IRQ(EXT_IRQ16H(24), GPIO_PORT118), + PINMUX_IRQ(EXT_IRQ16L(6), GPIO_PORT147), + PINMUX_IRQ(EXT_IRQ16L(2), GPIO_PORT149), + PINMUX_IRQ(EXT_IRQ16L(7), GPIO_PORT150), + PINMUX_IRQ(EXT_IRQ16L(12), GPIO_PORT156), + PINMUX_IRQ(EXT_IRQ16L(4), GPIO_PORT159), + PINMUX_IRQ(EXT_IRQ16H(25), GPIO_PORT164), + PINMUX_IRQ(EXT_IRQ16L(8), GPIO_PORT223), + PINMUX_IRQ(EXT_IRQ16L(3), GPIO_PORT224), + PINMUX_IRQ(EXT_IRQ16L(5), GPIO_PORT227), + PINMUX_IRQ(EXT_IRQ16H(17), GPIO_PORT234), + PINMUX_IRQ(EXT_IRQ16L(11), GPIO_PORT238), + PINMUX_IRQ(EXT_IRQ16L(13), GPIO_PORT239), + PINMUX_IRQ(EXT_IRQ16H(16), GPIO_PORT249), + PINMUX_IRQ(EXT_IRQ16L(14), GPIO_PORT251), + PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT308), }; struct sh_pfc_soc_info sh73a0_pinmux_info = { diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index dae9e155be17..f9d448099bcb 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -89,11 +89,11 @@ struct pinmux_data_reg { struct pinmux_irq { int irq; - pinmux_enum_t *enum_ids; + unsigned short *gpios; }; #define PINMUX_IRQ(irq_nr, ids...) \ - { .irq = irq_nr, .enum_ids = (pinmux_enum_t []) { ids, 0 } } \ + { .irq = irq_nr, .gpios = (unsigned short []) { ids, 0 } } \ struct pinmux_range { pinmux_enum_t begin; -- cgit From 17dffe48d18f9c31ba7499af385e10bc02d7c7d9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Feb 2013 22:09:27 +0100 Subject: sh-pfc: Share the PORT_10_REV, PORT_32 and PORT_32_REV definitions The macros are defined identically and used in two SoC-specific files, share them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 34 ++++++++-------------------------- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 31 +++++++------------------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 0e536744f3d2..e9a7ead139fa 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -23,11 +23,6 @@ #include "sh_pfc.h" -#define CPU_32_PORT(fn, pfx, sfx) \ - PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ - PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ - PORT_1(fn, pfx##31, sfx) - #define CPU_32_PORT6(fn, pfx, sfx) \ PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \ PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \ @@ -36,12 +31,12 @@ PORT_1(fn, pfx##8, sfx) #define CPU_ALL_PORT(fn, pfx, sfx) \ - CPU_32_PORT(fn, pfx##_0_, sfx), \ - CPU_32_PORT(fn, pfx##_1_, sfx), \ - CPU_32_PORT(fn, pfx##_2_, sfx), \ - CPU_32_PORT(fn, pfx##_3_, sfx), \ - CPU_32_PORT(fn, pfx##_4_, sfx), \ - CPU_32_PORT(fn, pfx##_5_, sfx), \ + PORT_32(fn, pfx##_0_, sfx), \ + PORT_32(fn, pfx##_1_, sfx), \ + PORT_32(fn, pfx##_2_, sfx), \ + PORT_32(fn, pfx##_3_, sfx), \ + PORT_32(fn, pfx##_4_, sfx), \ + PORT_32(fn, pfx##_5_, sfx), \ CPU_32_PORT6(fn, pfx##_6_, sfx) #define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA) @@ -55,21 +50,8 @@ #define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused) #define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused) - -#define PORT_10_REV(fn, pfx, sfx) \ - PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ - PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ - PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ - PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ - PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) - -#define CPU_32_PORT_REV(fn, pfx, sfx) \ - PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ - PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ - PORT_10_REV(fn, pfx, sfx) - -#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused) -#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused) +#define GP_INOUTSEL(bank) PORT_32_REV(_GP_INOUTSEL, _##bank##_, unused) +#define GP_INDT(bank) PORT_32_REV(_GP_INDT, _##bank##_, unused) #define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn) #define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \ diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index 20c44dd7001a..99ea220269ff 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -14,11 +14,6 @@ #include "sh_pfc.h" -#define CPU_32_PORT(fn, pfx, sfx) \ - PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ - PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ - PORT_1(fn, pfx##31, sfx) - #define CPU_32_PORT5(fn, pfx, sfx) \ PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \ PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \ @@ -29,11 +24,11 @@ /* GPSR0 - GPSR5 */ #define CPU_ALL_PORT(fn, pfx, sfx) \ - CPU_32_PORT(fn, pfx##_0_, sfx), \ - CPU_32_PORT(fn, pfx##_1_, sfx), \ - CPU_32_PORT(fn, pfx##_2_, sfx), \ - CPU_32_PORT(fn, pfx##_3_, sfx), \ - CPU_32_PORT(fn, pfx##_4_, sfx), \ + PORT_32(fn, pfx##_0_, sfx), \ + PORT_32(fn, pfx##_1_, sfx), \ + PORT_32(fn, pfx##_2_, sfx), \ + PORT_32(fn, pfx##_3_, sfx), \ + PORT_32(fn, pfx##_4_, sfx), \ CPU_32_PORT5(fn, pfx##_5_, sfx) #define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA) @@ -47,20 +42,8 @@ #define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused) #define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused) -#define PORT_10_REV(fn, pfx, sfx) \ - PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ - PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ - PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ - PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ - PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) - -#define CPU_32_PORT_REV(fn, pfx, sfx) \ - PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ - PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ - PORT_10_REV(fn, pfx, sfx) - -#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused) -#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused) +#define GP_INOUTSEL(bank) PORT_32_REV(_GP_INOUTSEL, _##bank##_, unused) +#define GP_INDT(bank) PORT_32_REV(_GP_INDT, _##bank##_, unused) #define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn) #define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \ diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index f9d448099bcb..43c858d98321 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -138,6 +138,23 @@ enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx), \ PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx) +#define PORT_10_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ + PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ + PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ + PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ + PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) + +#define PORT_32(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_1(fn, pfx##31, sfx) + +#define PORT_32_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ + PORT_10_REV(fn, pfx, sfx) + #define PORT_90(fn, pfx, sfx) \ PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx), \ PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx), \ -- cgit From a68fdca9b0447a0e7a85ee378510509be8b70d90 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 14 Feb 2013 17:36:56 +0100 Subject: sh-pfc: Use pinmux identifiers in the pin muxing API The PFC core exposes a sh_pfc_config_gpio() function that configures pinmuxing for a given GPIO (either a real GPIO or a function GPIO). Handling of real and function GPIOs belong to the GPIO layer, move the GPIO number to mark translation to the caller and rename the function to sh_pfc_config_mux(). Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 32 +++++++------------------------- drivers/pinctrl/sh-pfc/core.h | 4 ++-- drivers/pinctrl/sh-pfc/gpio.c | 14 ++++++-------- drivers/pinctrl/sh-pfc/pinctrl.c | 12 ++++++------ 4 files changed, 21 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 22f299993a36..3387f824920b 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -95,13 +95,6 @@ static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) (pfc->info->pins[gpio].enum_id != 0); } -static bool sh_pfc_gpio_is_function(struct sh_pfc *pfc, unsigned int gpio) -{ - return (gpio >= pfc->info->nr_pins) && - (gpio < pfc->info->nr_pins + pfc->info->nr_func_gpios) && - (pfc->info->func_gpios[gpio - pfc->info->nr_pins].enum_id != 0); -} - static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned long reg_width) { @@ -350,41 +343,30 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, return -1; } -static int sh_pfc_gpio_to_enum(struct sh_pfc *pfc, unsigned gpio, int pos, - pinmux_enum_t *enum_idp) +static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, + pinmux_enum_t *enum_idp) { pinmux_enum_t *data = pfc->info->gpio_data; - pinmux_enum_t enum_id; int k; - if (sh_pfc_gpio_is_pin(pfc, gpio)) { - enum_id = pfc->info->pins[gpio].enum_id; - } else if (sh_pfc_gpio_is_function(pfc, gpio)) { - unsigned int offset = gpio - pfc->info->nr_pins; - enum_id = pfc->info->func_gpios[offset].enum_id; - } else { - pr_err("non data/mark enum_id for gpio %d\n", gpio); - return -1; - } - if (pos) { *enum_idp = data[pos + 1]; return pos + 1; } for (k = 0; k < pfc->info->gpio_data_size; k++) { - if (data[k] == enum_id) { + if (data[k] == mark) { *enum_idp = data[k + 1]; return k + 1; } } - pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio); + pr_err("cannot locate data/mark enum_id for mark %d\n", mark); return -1; } -int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, - int cfg_mode) +int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, + int cfg_mode) { struct pinmux_cfg_reg *cr = NULL; pinmux_enum_t enum_id; @@ -423,7 +405,7 @@ int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, field = 0; value = 0; while (1) { - pos = sh_pfc_gpio_to_enum(pfc, gpio, pos, &enum_id); + pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); if (pos <= 0) goto out_err; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index f22d03f1e503..ab816b7fddfb 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -49,8 +49,8 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); -int sh_pfc_config_gpio(struct sh_pfc *pfc, unsigned gpio, int pinmux_type, - int cfg_mode); +int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, + int cfg_mode); extern struct sh_pfc_soc_info r8a7740_pinmux_info; extern struct sh_pfc_soc_info r8a7779_pinmux_info; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 454c965ea555..3ad938fd7ecc 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -135,23 +135,21 @@ static void gpio_pin_setup(struct sh_pfc_chip *chip) static int gpio_function_request(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); - unsigned int gpio = gc->base + offset; + unsigned int mark = pfc->info->func_gpios[offset].enum_id; unsigned long flags; int ret = -EINVAL; pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); - if (pfc->info->func_gpios[offset].enum_id == 0) + if (mark == 0) return ret; spin_lock_irqsave(&pfc->lock, flags); - if (sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, - GPIO_CFG_DRYRUN)) + if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_DRYRUN)) goto done; - if (sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, - GPIO_CFG_REQ)) + if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_REQ)) goto done; ret = 0; @@ -164,12 +162,12 @@ done: static void gpio_function_free(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); - unsigned int gpio = gc->base + offset; + unsigned int mark = pfc->info->func_gpios[offset].enum_id; unsigned long flags; spin_lock_irqsave(&pfc->lock, flags); - sh_pfc_config_gpio(pfc, gpio, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index d420d9981725..a83f40070b3b 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -119,6 +119,7 @@ static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func, static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, int new_type) { + unsigned int mark = pfc->info->pins[offset].enum_id; unsigned long flags; int pinmux_type; int ret = -EINVAL; @@ -137,7 +138,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, case PINMUX_TYPE_INPUT: case PINMUX_TYPE_INPUT_PULLUP: case PINMUX_TYPE_INPUT_PULLDOWN: - sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, mark, pinmux_type, GPIO_CFG_FREE); break; default: goto err; @@ -146,15 +147,13 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, /* * Dry run */ - if (sh_pfc_config_gpio(pfc, offset, new_type, - GPIO_CFG_DRYRUN) != 0) + if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_DRYRUN) != 0) goto err; /* * Request */ - if (sh_pfc_config_gpio(pfc, offset, new_type, - GPIO_CFG_REQ) != 0) + if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0) goto err; pfc->info->pins[offset].flags &= ~PINMUX_FLAG_TYPE; @@ -214,7 +213,8 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; - sh_pfc_config_gpio(pfc, offset, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, pfc->info->pins[offset].enum_id, pinmux_type, + GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } -- cgit From 0b73ee5d534cc6dcb96efb9eac4cf96b40910911 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 14 Feb 2013 22:12:11 +0100 Subject: sh-pfc: Simplify the sh_pfc_gpio_is_pin() logic The function is guaranteed to be called with a gpio number smaller than nr_pins. The condition can the be simplified, and the function inlined. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 29 +++++++++-------------------- drivers/pinctrl/sh-pfc/core.h | 4 ++-- drivers/pinctrl/sh-pfc/gpio.c | 21 +++++++++++---------- 3 files changed, 22 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 3387f824920b..9b5c0319eb77 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -89,12 +89,6 @@ static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) return 1; } -static bool sh_pfc_gpio_is_pin(struct sh_pfc *pfc, unsigned int gpio) -{ - return (gpio < pfc->info->nr_pins) && - (pfc->info->pins[gpio].enum_id != 0); -} - static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned long reg_width) { @@ -226,15 +220,12 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data); } -static int sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) +static void sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) { struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; struct pinmux_data_reg *data_reg; int k, n; - if (!sh_pfc_gpio_is_pin(pfc, gpio)) - return -1; - k = 0; while (1) { data_reg = pfc->info->data_regs + k; @@ -250,15 +241,13 @@ static int sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); gpiop->flags &= ~PINMUX_FLAG_DBIT; gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); - return 0; + return; } } k++; } BUG(); - - return -1; } static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) @@ -266,8 +255,12 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) struct pinmux_data_reg *drp; int k; - for (k = 0; k < pfc->info->nr_pins; k++) + for (k = 0; k < pfc->info->nr_pins; k++) { + if (pfc->info->pins[k].enum_id == 0) + continue; + sh_pfc_setup_data_reg(pfc, k); + } k = 0; while (1) { @@ -282,20 +275,16 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) } } -int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, - struct pinmux_data_reg **drp, int *bitp) +void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, + struct pinmux_data_reg **drp, int *bitp) { struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; int k, n; - if (!sh_pfc_gpio_is_pin(pfc, gpio)) - return -1; - k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; *drp = pfc->info->data_regs + k; *bitp = n; - return 0; } static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index ab816b7fddfb..a3111b73fb94 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -47,8 +47,8 @@ int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); -int sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, - struct pinmux_data_reg **drp, int *bitp); +void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, + struct pinmux_data_reg **drp, int *bitp); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, int cfg_mode); diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 3ad938fd7ecc..db9af4e548a0 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -42,6 +42,11 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) static int gpio_pin_request(struct gpio_chip *gc, unsigned offset) { + struct sh_pfc *pfc = gpio_to_pfc(gc); + + if (pfc->info->pins[offset].enum_id == 0) + return -EINVAL; + return pinctrl_request_gpio(offset); } @@ -52,12 +57,10 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) { - struct pinmux_data_reg *dr = NULL; - int bit = 0; - - if (sh_pfc_get_data_reg(pfc, offset, &dr, &bit) != 0) - BUG(); + struct pinmux_data_reg *dr; + int bit; + sh_pfc_get_data_reg(pfc, offset, &dr, &bit); sh_pfc_write_bit(dr, bit, value); } @@ -77,12 +80,10 @@ static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset, static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); - struct pinmux_data_reg *dr = NULL; - int bit = 0; - - if (sh_pfc_get_data_reg(pfc, offset, &dr, &bit) != 0) - return -EINVAL; + struct pinmux_data_reg *dr; + int bit; + sh_pfc_get_data_reg(pfc, offset, &dr, &bit); return sh_pfc_read_bit(dr, bit); } -- cgit From 934cb02bab9003bf65afe73e9146a1ea63b26c40 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 14 Feb 2013 22:35:09 +0100 Subject: sh-pfc: Add function to retrieve a pin instance from its pin number This prepares support for sparse pin numbering. The function currently just performs and indexed lookup in the pins array. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 7 ++++++- drivers/pinctrl/sh-pfc/core.h | 1 + drivers/pinctrl/sh-pfc/gpio.c | 3 ++- drivers/pinctrl/sh-pfc/pinctrl.c | 23 +++++++++++++---------- 4 files changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 9b5c0319eb77..667db99fb510 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -78,6 +78,11 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, return (void __iomem *)address; } +struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin) +{ + return &pfc->info->pins[pin]; +} + static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) { if (enum_id < r->begin) @@ -278,7 +283,7 @@ static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp) { - struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; + struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); int k, n; k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index a3111b73fb94..6ea3d4f3d05e 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -49,6 +49,7 @@ void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, unsigned long value); void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, struct pinmux_data_reg **drp, int *bitp); +struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, int cfg_mode); diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index db9af4e548a0..45090d8381a2 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -43,8 +43,9 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) static int gpio_pin_request(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); + struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); - if (pfc->info->pins[offset].enum_id == 0) + if (pin->enum_id == 0) return -EINVAL; return pinctrl_request_gpio(offset); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index a83f40070b3b..78bd277c01d9 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -119,14 +119,15 @@ static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func, static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, int new_type) { - unsigned int mark = pfc->info->pins[offset].enum_id; + struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + unsigned int mark = pin->enum_id; unsigned long flags; int pinmux_type; int ret = -EINVAL; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pin->flags & PINMUX_FLAG_TYPE; /* * See if the present config needs to first be de-configured. @@ -156,8 +157,8 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0) goto err; - pfc->info->pins[offset].flags &= ~PINMUX_FLAG_TYPE; - pfc->info->pins[offset].flags |= new_type; + pin->flags &= ~PINMUX_FLAG_TYPE; + pin->flags |= new_type; ret = 0; @@ -173,12 +174,13 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; + struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); unsigned long flags; int ret, pinmux_type; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pin->flags & PINMUX_FLAG_TYPE; switch (pinmux_type) { case PINMUX_TYPE_GPIO: @@ -206,15 +208,15 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; + struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); unsigned long flags; int pinmux_type; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pfc->info->pins[offset].flags & PINMUX_FLAG_TYPE; + pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - sh_pfc_config_mux(pfc, pfc->info->pins[offset].enum_id, pinmux_type, - GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, pin->enum_id, pinmux_type, GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } @@ -240,13 +242,14 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { .gpio_set_direction = sh_pfc_gpio_set_direction, }; -static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, +static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, unsigned long *config) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; + struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, _pin); - *config = pfc->info->pins[pin].flags & PINMUX_FLAG_TYPE; + *config = pin->flags & PINMUX_FLAG_TYPE; return 0; } -- cgit From 247127f90ba1fcc234008e00e937537a89eef9ca Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Mar 2013 00:45:12 +0100 Subject: sh-pfc: Replace pinctrl_add_gpio_range() with gpiochip_add_pin_range() Adding a GPIO range to a pinctrl device logically belongs to the GPIO driver. Switch to the right API. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/gpio.c | 6 ++++++ drivers/pinctrl/sh-pfc/pinctrl.c | 9 --------- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 45090d8381a2..32a9c7870a16 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -220,6 +220,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *)) int sh_pfc_register_gpiochip(struct sh_pfc *pfc) { struct sh_pfc_chip *chip; + int ret; chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); if (IS_ERR(chip)) @@ -227,6 +228,11 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) pfc->gpio = chip; + ret = gpiochip_add_pin_range(&chip->gpio_chip, dev_name(pfc->dev), 0, 0, + chip->gpio_chip.ngpio); + if (ret < 0) + return ret; + chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup); if (IS_ERR(chip)) return PTR_ERR(chip); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 78bd277c01d9..a60c317d988a 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -28,7 +28,6 @@ struct sh_pfc_pinctrl { struct pinctrl_dev *pctl; struct pinctrl_desc pctl_desc; - struct pinctrl_gpio_range range; struct sh_pfc *pfc; @@ -377,14 +376,6 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) if (IS_ERR(pmx->pctl)) return PTR_ERR(pmx->pctl); - pmx->range.name = DRV_NAME, - pmx->range.id = 0; - pmx->range.npins = pfc->info->nr_pins; - pmx->range.base = 0; - pmx->range.pin_base = 0; - - pinctrl_add_gpio_range(pmx->pctl, &pmx->range); - return 0; } -- cgit From 63d573835f835aab4c44d0e0342cf5976fb14b35 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 15 Feb 2013 01:33:38 +0100 Subject: sh-pfc: Add support for sparse pin numbers The PFC driver assumes that the value of the GPIO_PORTxxx enumeration names are equal to the port number. This isn't true when the port number space is sparse, as with the SH73A0. Fix the issue by adding support for pin numbers ranges specified through SoC data. When no range is specified the driver considers that the PFC implements a single contiguous range for all pins. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 19 ++++++++++++- drivers/pinctrl/sh-pfc/core.h | 2 ++ drivers/pinctrl/sh-pfc/gpio.c | 37 ++++++++++++++++++++----- drivers/pinctrl/sh-pfc/pinctrl.c | 58 +++++++++++++++++++++++++++------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 2 ++ 5 files changed, 91 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 667db99fb510..798248261f30 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -80,7 +80,24 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin) { - return &pfc->info->pins[pin]; + unsigned int offset; + unsigned int i; + + if (pfc->info->ranges == NULL) + return &pfc->info->pins[pin]; + + for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) { + const struct pinmux_range *range = &pfc->info->ranges[i]; + + if (pin <= range->end) + return pin >= range->begin + ? &pfc->info->pins[offset + pin - range->begin] + : NULL; + + offset += range->end - range->begin + 1; + } + + return NULL; } static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 6ea3d4f3d05e..b8b3e872cc19 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -32,6 +32,8 @@ struct sh_pfc { unsigned int num_windows; struct sh_pfc_window *window; + unsigned int nr_pins; + struct sh_pfc_chip *gpio; struct sh_pfc_chip *func; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 32a9c7870a16..806e2dd62137 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -45,7 +45,7 @@ static int gpio_pin_request(struct gpio_chip *gc, unsigned offset) struct sh_pfc *pfc = gpio_to_pfc(gc); struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); - if (pin->enum_id == 0) + if (pin == NULL || pin->enum_id == 0) return -EINVAL; return pinctrl_request_gpio(offset); @@ -127,7 +127,7 @@ static void gpio_pin_setup(struct sh_pfc_chip *chip) gc->dev = pfc->dev; gc->owner = THIS_MODULE; gc->base = 0; - gc->ngpio = pfc->info->nr_pins; + gc->ngpio = pfc->nr_pins; } /* ----------------------------------------------------------------------------- @@ -184,7 +184,7 @@ static void gpio_function_setup(struct sh_pfc_chip *chip) gc->label = pfc->info->name; gc->owner = THIS_MODULE; - gc->base = pfc->info->nr_pins; + gc->base = pfc->nr_pins; gc->ngpio = pfc->info->nr_func_gpios; } @@ -219,20 +219,43 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *)) int sh_pfc_register_gpiochip(struct sh_pfc *pfc) { + const struct pinmux_range *ranges; + struct pinmux_range def_range; struct sh_pfc_chip *chip; + unsigned int nr_ranges; + unsigned int i; int ret; + /* Register the real GPIOs chip. */ chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); if (IS_ERR(chip)) return PTR_ERR(chip); pfc->gpio = chip; - ret = gpiochip_add_pin_range(&chip->gpio_chip, dev_name(pfc->dev), 0, 0, - chip->gpio_chip.ngpio); - if (ret < 0) - return ret; + /* Register the GPIO to pin mappings. */ + if (pfc->info->ranges == NULL) { + def_range.begin = 0; + def_range.end = pfc->info->nr_pins - 1; + ranges = &def_range; + nr_ranges = 1; + } else { + ranges = pfc->info->ranges; + nr_ranges = pfc->info->nr_ranges; + } + + for (i = 0; i < nr_ranges; ++i) { + const struct pinmux_range *range = &ranges[i]; + + ret = gpiochip_add_pin_range(&chip->gpio_chip, + dev_name(pfc->dev), + range->begin, range->begin, + range->end - range->begin + 1); + if (ret < 0) + return ret; + } + /* Register the function GPIOs chip. */ chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup); if (IS_ERR(chip)) return PTR_ERR(chip); diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index a60c317d988a..c9e9a1d95230 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -293,29 +293,48 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, }; -/* pinmux ranges -> pinctrl pin descs */ -static int sh_pfc_map_gpios(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) +/* PFC ranges -> pinctrl pin descs */ +static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { - int i; - - pmx->nr_pads = pfc->info->nr_pins; + const struct pinmux_range *ranges; + struct pinmux_range def_range; + unsigned int nr_ranges; + unsigned int nr_pins; + unsigned int i; + + if (pfc->info->ranges == NULL) { + def_range.begin = 0; + def_range.end = pfc->info->nr_pins - 1; + ranges = &def_range; + nr_ranges = 1; + } else { + ranges = pfc->info->ranges; + nr_ranges = pfc->info->nr_ranges; + } - pmx->pads = devm_kzalloc(pfc->dev, sizeof(*pmx->pads) * pmx->nr_pads, + pmx->pads = devm_kzalloc(pfc->dev, + sizeof(*pmx->pads) * pfc->info->nr_pins, GFP_KERNEL); - if (unlikely(!pmx->pads)) { - pmx->nr_pads = 0; + if (unlikely(!pmx->pads)) return -ENOMEM; - } - for (i = 0; i < pmx->nr_pads; i++) { - struct pinctrl_pin_desc *pin = pmx->pads + i; - struct sh_pfc_pin *gpio = pfc->info->pins + i; + for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { + const struct pinmux_range *range = &ranges[i]; + unsigned int number; + + for (number = range->begin; number <= range->end; + number++, nr_pins++) { + struct pinctrl_pin_desc *pin = &pmx->pads[nr_pins]; + struct sh_pfc_pin *info = &pfc->info->pins[nr_pins]; - pin->number = i; - pin->name = gpio->name; + pin->number = number; + pin->name = info->name; + } } - return 0; + pfc->nr_pins = ranges[nr_ranges-1].end + 1; + + return nr_ranges; } static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) @@ -347,6 +366,7 @@ static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) int sh_pfc_register_pinctrl(struct sh_pfc *pfc) { struct sh_pfc_pinctrl *pmx; + int nr_ranges; int ret; pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); @@ -356,9 +376,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->pfc = pfc; pfc->pinctrl = pmx; - ret = sh_pfc_map_gpios(pfc, pmx); - if (unlikely(ret != 0)) - return ret; + nr_ranges = sh_pfc_map_pins(pfc, pmx); + if (unlikely(nr_ranges < 0)) + return nr_ranges; ret = sh_pfc_map_functions(pfc, pmx); if (unlikely(ret != 0)) @@ -370,7 +390,7 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops; pmx->pctl_desc.confops = &sh_pfc_pinconf_ops; pmx->pctl_desc.pins = pmx->pads; - pmx->pctl_desc.npins = pmx->nr_pads; + pmx->pctl_desc.npins = pfc->info->nr_pins; pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); if (IS_ERR(pmx->pctl)) diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 43c858d98321..dbcaa600ccc6 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -111,6 +111,8 @@ struct sh_pfc_soc_info { struct sh_pfc_pin *pins; unsigned int nr_pins; + const struct pinmux_range *ranges; + unsigned int nr_ranges; struct pinmux_func *func_gpios; unsigned int nr_func_gpios; -- cgit From b58e5fac96e4f24fc9d5bce8692506ada3e244ca Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 12 Feb 2013 16:50:02 +0100 Subject: ARM: shmobile: sh73a0: Support sparse GPIO numbers The SH73A0 SoC has sparse GPIO numbers. Declare the pin numbers ranges in the PFC SoC data and use the pin numbers in the GPIO API. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- arch/arm/mach-shmobile/board-ag5evm.c | 26 +++++----- arch/arm/mach-shmobile/board-kota2.c | 42 ++++++++-------- arch/arm/mach-shmobile/board-kzm9g.c | 14 +++--- arch/arm/mach-shmobile/include/mach/sh73a0.h | 2 +- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 75 ++++++++++++++++------------ 5 files changed, 84 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 8ff53a19c48c..a4ac46a89b27 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -304,9 +304,9 @@ static int lcd_backlight_set_brightness(int brightness) if (brightness == 0) { /* Reset the chip */ - gpio_set_value(GPIO_PORT235, 0); + gpio_set_value(235, 0); mdelay(24); - gpio_set_value(GPIO_PORT235, 1); + gpio_set_value(235, 1); return 0; } @@ -406,7 +406,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = { .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, - .cd_gpio = GPIO_PORT251, + .cd_gpio = 251, }; static struct resource sdhi0_resources[] = { @@ -461,7 +461,7 @@ static struct regulator_init_data cn4_power_init_data = { static struct fixed_voltage_config cn4_power_info = { .supply_name = "CN4 SD/MMC Vdd", .microvolts = 3300000, - .gpio = GPIO_PORT114, + .gpio = 114, .enable_high = 1, .init_data = &cn4_power_init_data, }; @@ -479,10 +479,10 @@ static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) static int power_gpio = -EINVAL; if (power_gpio < 0) { - int ret = gpio_request_one(GPIO_PORT114, GPIOF_OUT_INIT_LOW, + int ret = gpio_request_one(114, GPIOF_OUT_INIT_LOW, "sdhi1_power"); if (!ret) - power_gpio = GPIO_PORT114; + power_gpio = 114; } /* @@ -493,7 +493,7 @@ static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) * regulator driver. We have to live with the race in case the driver * gets unloaded and the GPIO freed between these two steps. */ - gpio_set_value(GPIO_PORT114, state); + gpio_set_value(114, state); } static struct sh_mobile_sdhi_info sh_sdhi1_info = { @@ -603,11 +603,11 @@ static void __init ag5evm_init(void) gpio_request(GPIO_FN_MMCD0_5_PU, NULL); gpio_request(GPIO_FN_MMCD0_6_PU, NULL); gpio_request(GPIO_FN_MMCD0_7_PU, NULL); - gpio_request_one(GPIO_PORT208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ + gpio_request_one(208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ /* enable SMSC911X */ - gpio_request_one(GPIO_PORT144, GPIOF_IN, NULL); /* PINTA2 */ - gpio_request_one(GPIO_PORT145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ + gpio_request_one(144, GPIOF_IN, NULL); /* PINTA2 */ + gpio_request_one(145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ /* FSI A */ gpio_request(GPIO_FN_FSIACK, NULL); @@ -622,13 +622,13 @@ static void __init ag5evm_init(void) gpio_request(GPIO_FN_PORT243_IRDA_FIRSEL, NULL); /* LCD panel */ - gpio_request_one(GPIO_PORT217, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ + gpio_request_one(217, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ mdelay(1); - gpio_set_value(GPIO_PORT217, 1); + gpio_set_value(217, 1); mdelay(100); /* LCD backlight controller */ - gpio_request_one(GPIO_PORT235, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ + gpio_request_one(235, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ lcd_backlight_set_brightness(0); /* enable SDHI0 on CN15 [SD I/F] */ diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index 2ccc860403ef..b6f051573b4a 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -135,17 +135,17 @@ static struct platform_device keysc_device = { #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } static struct gpio_keys_button gpio_buttons[] = { - GPIO_KEY(KEY_VOLUMEUP, GPIO_PORT56, "+"), /* S2: VOL+ [IRQ9] */ - GPIO_KEY(KEY_VOLUMEDOWN, GPIO_PORT54, "-"), /* S3: VOL- [IRQ10] */ - GPIO_KEY(KEY_MENU, GPIO_PORT27, "Menu"), /* S4: MENU [IRQ30] */ - GPIO_KEY(KEY_HOMEPAGE, GPIO_PORT26, "Home"), /* S5: HOME [IRQ31] */ - GPIO_KEY(KEY_BACK, GPIO_PORT11, "Back"), /* S6: BACK [IRQ0] */ - GPIO_KEY(KEY_PHONE, GPIO_PORT238, "Tel"), /* S7: TEL [IRQ11] */ - GPIO_KEY(KEY_POWER, GPIO_PORT239, "C1"), /* S8: CAM [IRQ13] */ - GPIO_KEY(KEY_MAIL, GPIO_PORT224, "Mail"), /* S9: MAIL [IRQ3] */ - /* Omitted button "C3?": GPIO_PORT223 - S10: CUST [IRQ8] */ - GPIO_KEY(KEY_CAMERA, GPIO_PORT164, "C2"), /* S11: CAM_HALF [IRQ25] */ - /* Omitted button "?": GPIO_PORT152 - S12: CAM_FULL [No IRQ] */ + GPIO_KEY(KEY_VOLUMEUP, 56, "+"), /* S2: VOL+ [IRQ9] */ + GPIO_KEY(KEY_VOLUMEDOWN, 54, "-"), /* S3: VOL- [IRQ10] */ + GPIO_KEY(KEY_MENU, 27, "Menu"), /* S4: MENU [IRQ30] */ + GPIO_KEY(KEY_HOMEPAGE, 26, "Home"), /* S5: HOME [IRQ31] */ + GPIO_KEY(KEY_BACK, 11, "Back"), /* S6: BACK [IRQ0] */ + GPIO_KEY(KEY_PHONE, 238, "Tel"), /* S7: TEL [IRQ11] */ + GPIO_KEY(KEY_POWER, 239, "C1"), /* S8: CAM [IRQ13] */ + GPIO_KEY(KEY_MAIL, 224, "Mail"), /* S9: MAIL [IRQ3] */ + /* Omitted button "C3?": 223 - S10: CUST [IRQ8] */ + GPIO_KEY(KEY_CAMERA, 164, "C2"), /* S11: CAM_HALF [IRQ25] */ + /* Omitted button "?": 152 - S12: CAM_FULL [No IRQ] */ }; static struct gpio_keys_platform_data gpio_key_info = { @@ -165,9 +165,9 @@ static struct platform_device gpio_keys_device = { #define GPIO_LED(n, g) { .name = n, .gpio = g } static struct gpio_led gpio_leds[] = { - GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */ - GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */ - GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */ + GPIO_LED("G", 20), /* PORT20 [GPO0] -> LED7 -> "G" */ + GPIO_LED("H", 21), /* PORT21 [GPO1] -> LED8 -> "H" */ + GPIO_LED("J", 22), /* PORT22 [GPO2] -> LED9 -> "J" */ }; static struct gpio_led_platform_data gpio_leds_info = { @@ -187,7 +187,7 @@ static struct platform_device gpio_leds_device = { static struct led_renesas_tpu_config led_renesas_tpu12_pdata = { .name = "V2513", .pin_gpio_fn = GPIO_FN_TPU1TO2, - .pin_gpio = GPIO_PORT153, + .pin_gpio = 153, .channel_offset = 0x90, .timer_bit = 2, .max_brightness = 1000, @@ -215,7 +215,7 @@ static struct platform_device leds_tpu12_device = { static struct led_renesas_tpu_config led_renesas_tpu41_pdata = { .name = "V2514", .pin_gpio_fn = GPIO_FN_TPU4TO1, - .pin_gpio = GPIO_PORT199, + .pin_gpio = 199, .channel_offset = 0x50, .timer_bit = 1, .max_brightness = 1000, @@ -243,7 +243,7 @@ static struct platform_device leds_tpu41_device = { static struct led_renesas_tpu_config led_renesas_tpu21_pdata = { .name = "V2515", .pin_gpio_fn = GPIO_FN_TPU2TO1, - .pin_gpio = GPIO_PORT197, + .pin_gpio = 197, .channel_offset = 0x50, .timer_bit = 1, .max_brightness = 1000, @@ -271,7 +271,7 @@ static struct platform_device leds_tpu21_device = { static struct led_renesas_tpu_config led_renesas_tpu30_pdata = { .name = "KEYLED", .pin_gpio_fn = GPIO_FN_TPU3TO0, - .pin_gpio = GPIO_PORT163, + .pin_gpio = 163, .channel_offset = 0x10, .timer_bit = 0, .max_brightness = 1000, @@ -474,8 +474,8 @@ static void __init kota2_init(void) gpio_request(GPIO_FN_D15_NAF15, NULL); gpio_request(GPIO_FN_CS5A_, NULL); gpio_request(GPIO_FN_WE0__FWE, NULL); - gpio_request_one(GPIO_PORT144, GPIOF_IN, NULL); /* PINTA2 */ - gpio_request_one(GPIO_PORT145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ + gpio_request_one(144, GPIOF_IN, NULL); /* PINTA2 */ + gpio_request_one(145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ /* KEYSC */ gpio_request(GPIO_FN_KEYIN0_PU, NULL); @@ -507,7 +507,7 @@ static void __init kota2_init(void) gpio_request(GPIO_FN_MMCD0_6, NULL); gpio_request(GPIO_FN_MMCD0_7, NULL); gpio_request(GPIO_FN_MMCCMD0, NULL); - gpio_request_one(GPIO_PORT208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ + gpio_request_one(208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ /* SDHI0 (microSD) */ gpio_request(GPIO_FN_SDHICD0_PU, NULL); diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7f3a6b7e7b7c..65a5e0b80f06 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -433,7 +433,7 @@ static struct sh_mobile_sdhi_info sdhi2_info = { TMIO_MMC_WRPROTECT_DISABLE, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, - .cd_gpio = GPIO_PORT13, + .cd_gpio = 13, }; static struct resource sdhi2_resources[] = { @@ -672,7 +672,7 @@ static void __init kzm_init(void) gpio_request(GPIO_FN_CS4_, NULL); /* CS4 */ /* SMSC */ - gpio_request_one(GPIO_PORT224, GPIOF_IN, NULL); /* IRQ3 */ + gpio_request_one(224, GPIOF_IN, NULL); /* IRQ3 */ /* LCDC */ gpio_request(GPIO_FN_LCDD23, NULL); @@ -702,11 +702,11 @@ static void __init kzm_init(void) gpio_request(GPIO_FN_LCDDISP, NULL); gpio_request(GPIO_FN_LCDDCK, NULL); - gpio_request_one(GPIO_PORT222, GPIOF_OUT_INIT_HIGH, NULL); /* LCDCDON */ - gpio_request_one(GPIO_PORT226, GPIOF_OUT_INIT_HIGH, NULL); /* SC */ + gpio_request_one(222, GPIOF_OUT_INIT_HIGH, NULL); /* LCDCDON */ + gpio_request_one(226, GPIOF_OUT_INIT_HIGH, NULL); /* SC */ /* Touchscreen */ - gpio_request_one(GPIO_PORT223, GPIOF_IN, NULL); /* IRQ8 */ + gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */ /* enable MMCIF */ gpio_request(GPIO_FN_MMCCLK0, NULL); @@ -730,7 +730,7 @@ static void __init kzm_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL); - gpio_request_one(GPIO_PORT15, GPIOF_OUT_INIT_HIGH, NULL); /* power */ + gpio_request_one(15, GPIOF_OUT_INIT_HIGH, NULL); /* power */ /* enable Micro SD */ gpio_request(GPIO_FN_SDHID2_0, NULL); @@ -739,7 +739,7 @@ static void __init kzm_init(void) gpio_request(GPIO_FN_SDHID2_3, NULL); gpio_request(GPIO_FN_SDHICMD2, NULL); gpio_request(GPIO_FN_SDHICLK2, NULL); - gpio_request_one(GPIO_PORT14, GPIOF_OUT_INIT_HIGH, NULL); /* power */ + gpio_request_one(14, GPIOF_OUT_INIT_HIGH, NULL); /* power */ /* I2C 3 */ gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h index 606d31d02a4e..4dca135f3aa8 100644 --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h @@ -94,7 +94,7 @@ enum { GPIO_PORT305, GPIO_PORT306, GPIO_PORT307, GPIO_PORT308, GPIO_PORT309, /* Table 25-1 (Function 0-7) */ - GPIO_FN_VBUS_0, + GPIO_FN_VBUS_0 = 310, GPIO_FN_GPI0, GPIO_FN_GPI1, GPIO_FN_GPI2, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 639b5e21d9bc..9cef0d8b8ccd 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1543,7 +1543,14 @@ static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; -#define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) +static struct pinmux_range pinmux_ranges[] = { + {.begin = 0, .end = 118,}, + {.begin = 128, .end = 164,}, + {.begin = 192, .end = 282,}, + {.begin = 288, .end = 309,}, +}; + +#define PINMUX_FN_BASE GPIO_FN_VBUS_0 static struct pinmux_func pinmux_func_gpios[] = { /* Table 25-1 (Functions 0-7) */ @@ -2738,38 +2745,38 @@ static struct pinmux_data_reg pinmux_data_regs[] = { #define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) static struct pinmux_irq pinmux_irqs[] = { - PINMUX_IRQ(EXT_IRQ16H(19), GPIO_PORT9), - PINMUX_IRQ(EXT_IRQ16L(1), GPIO_PORT10), - PINMUX_IRQ(EXT_IRQ16L(0), GPIO_PORT11), - PINMUX_IRQ(EXT_IRQ16H(18), GPIO_PORT13), - PINMUX_IRQ(EXT_IRQ16H(20), GPIO_PORT14), - PINMUX_IRQ(EXT_IRQ16H(21), GPIO_PORT15), - PINMUX_IRQ(EXT_IRQ16H(31), GPIO_PORT26), - PINMUX_IRQ(EXT_IRQ16H(30), GPIO_PORT27), - PINMUX_IRQ(EXT_IRQ16H(29), GPIO_PORT28), - PINMUX_IRQ(EXT_IRQ16H(22), GPIO_PORT40), - PINMUX_IRQ(EXT_IRQ16H(23), GPIO_PORT53), - PINMUX_IRQ(EXT_IRQ16L(10), GPIO_PORT54), - PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT56), - PINMUX_IRQ(EXT_IRQ16H(26), GPIO_PORT115), - PINMUX_IRQ(EXT_IRQ16H(27), GPIO_PORT116), - PINMUX_IRQ(EXT_IRQ16H(28), GPIO_PORT117), - PINMUX_IRQ(EXT_IRQ16H(24), GPIO_PORT118), - PINMUX_IRQ(EXT_IRQ16L(6), GPIO_PORT147), - PINMUX_IRQ(EXT_IRQ16L(2), GPIO_PORT149), - PINMUX_IRQ(EXT_IRQ16L(7), GPIO_PORT150), - PINMUX_IRQ(EXT_IRQ16L(12), GPIO_PORT156), - PINMUX_IRQ(EXT_IRQ16L(4), GPIO_PORT159), - PINMUX_IRQ(EXT_IRQ16H(25), GPIO_PORT164), - PINMUX_IRQ(EXT_IRQ16L(8), GPIO_PORT223), - PINMUX_IRQ(EXT_IRQ16L(3), GPIO_PORT224), - PINMUX_IRQ(EXT_IRQ16L(5), GPIO_PORT227), - PINMUX_IRQ(EXT_IRQ16H(17), GPIO_PORT234), - PINMUX_IRQ(EXT_IRQ16L(11), GPIO_PORT238), - PINMUX_IRQ(EXT_IRQ16L(13), GPIO_PORT239), - PINMUX_IRQ(EXT_IRQ16H(16), GPIO_PORT249), - PINMUX_IRQ(EXT_IRQ16L(14), GPIO_PORT251), - PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT308), + PINMUX_IRQ(EXT_IRQ16H(19), 9), + PINMUX_IRQ(EXT_IRQ16L(1), 10), + PINMUX_IRQ(EXT_IRQ16L(0), 11), + PINMUX_IRQ(EXT_IRQ16H(18), 13), + PINMUX_IRQ(EXT_IRQ16H(20), 14), + PINMUX_IRQ(EXT_IRQ16H(21), 15), + PINMUX_IRQ(EXT_IRQ16H(31), 26), + PINMUX_IRQ(EXT_IRQ16H(30), 27), + PINMUX_IRQ(EXT_IRQ16H(29), 28), + PINMUX_IRQ(EXT_IRQ16H(22), 40), + PINMUX_IRQ(EXT_IRQ16H(23), 53), + PINMUX_IRQ(EXT_IRQ16L(10), 54), + PINMUX_IRQ(EXT_IRQ16L(9), 56), + PINMUX_IRQ(EXT_IRQ16H(26), 115), + PINMUX_IRQ(EXT_IRQ16H(27), 116), + PINMUX_IRQ(EXT_IRQ16H(28), 117), + PINMUX_IRQ(EXT_IRQ16H(24), 118), + PINMUX_IRQ(EXT_IRQ16L(6), 147), + PINMUX_IRQ(EXT_IRQ16L(2), 149), + PINMUX_IRQ(EXT_IRQ16L(7), 150), + PINMUX_IRQ(EXT_IRQ16L(12), 156), + PINMUX_IRQ(EXT_IRQ16L(4), 159), + PINMUX_IRQ(EXT_IRQ16H(25), 164), + PINMUX_IRQ(EXT_IRQ16L(8), 223), + PINMUX_IRQ(EXT_IRQ16L(3), 224), + PINMUX_IRQ(EXT_IRQ16L(5), 227), + PINMUX_IRQ(EXT_IRQ16H(17), 234), + PINMUX_IRQ(EXT_IRQ16L(11), 238), + PINMUX_IRQ(EXT_IRQ16L(13), 239), + PINMUX_IRQ(EXT_IRQ16H(16), 249), + PINMUX_IRQ(EXT_IRQ16L(14), 251), + PINMUX_IRQ(EXT_IRQ16L(9), 308), }; struct sh_pfc_soc_info sh73a0_pinmux_info = { @@ -2782,6 +2789,8 @@ struct sh_pfc_soc_info sh73a0_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), + .ranges = pinmux_ranges, + .nr_ranges = ARRAY_SIZE(pinmux_ranges), .func_gpios = pinmux_func_gpios, .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), -- cgit From 3d8d9f1df93362f319cf60b9ad10721a059b058f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 14:33:13 +0100 Subject: sh-pfc: Expose real groups and functions in pinctrl/pinmux operations The sh-pfc driver exposes one fake group and function per GPIO pin. As the pinctrl and pinmux APIs are not used by any SuperH and SH Mobile board or driver, drop the fake groups and functions and replace them by a real pinctrl and pinmux implementation. Groups and functions must now be explicitly provided by PFC SoC-specific data. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 114 ++++++++++++++++++++------------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 35 ++++++++++++ 2 files changed, 93 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index c9e9a1d95230..c7f3c406f9de 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -31,18 +31,14 @@ struct sh_pfc_pinctrl { struct sh_pfc *pfc; - struct pinmux_func **functions; - unsigned int nr_functions; - - struct pinctrl_pin_desc *pads; - unsigned int nr_pads; + struct pinctrl_pin_desc *pins; }; static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->nr_pads; + return pmx->pfc->info->nr_groups; } static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev, @@ -50,16 +46,16 @@ static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->pads[selector].name; + return pmx->pfc->info->groups[selector].name; } -static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, +static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, const unsigned **pins, unsigned *num_pins) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - *pins = &pmx->pads[group].number; - *num_pins = 1; + *pins = pmx->pfc->info->groups[selector].pins; + *num_pins = pmx->pfc->info->groups[selector].nr_pins; return 0; } @@ -81,7 +77,7 @@ static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->nr_functions; + return pmx->pfc->info->nr_functions; } static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev, @@ -89,30 +85,67 @@ static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->functions[selector]->name; + return pmx->pfc->info->functions[selector].name; } -static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev, unsigned func, +static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev, + unsigned selector, const char * const **groups, unsigned * const num_groups) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - *groups = &pmx->functions[func]->name; - *num_groups = 1; + *groups = pmx->pfc->info->functions[selector].groups; + *num_groups = pmx->pfc->info->functions[selector].nr_groups; return 0; } -static int sh_pfc_noop_enable(struct pinctrl_dev *pctldev, unsigned func, +static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { - return 0; + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; + unsigned long flags; + unsigned int i; + int ret = -EINVAL; + + spin_lock_irqsave(&pfc->lock, flags); + + for (i = 0; i < grp->nr_pins; ++i) { + if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, + GPIO_CFG_DRYRUN)) + goto done; + + if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, + GPIO_CFG_REQ)) + goto done; + } + + ret = 0; + +done: + spin_unlock_irqrestore(&pfc->lock, flags); + return ret; } -static void sh_pfc_noop_disable(struct pinctrl_dev *pctldev, unsigned func, +static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&pfc->lock, flags); + + for (i = 0; i < grp->nr_pins; ++i) + sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, + GPIO_CFG_FREE); + + spin_unlock_irqrestore(&pfc->lock, flags); } static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, @@ -234,8 +267,8 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { .get_functions_count = sh_pfc_get_functions_count, .get_function_name = sh_pfc_get_function_name, .get_function_groups = sh_pfc_get_function_groups, - .enable = sh_pfc_noop_enable, - .disable = sh_pfc_noop_disable, + .enable = sh_pfc_func_enable, + .disable = sh_pfc_func_disable, .gpio_request_enable = sh_pfc_gpio_request_enable, .gpio_disable_free = sh_pfc_gpio_disable_free, .gpio_set_direction = sh_pfc_gpio_set_direction, @@ -312,10 +345,10 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) nr_ranges = pfc->info->nr_ranges; } - pmx->pads = devm_kzalloc(pfc->dev, - sizeof(*pmx->pads) * pfc->info->nr_pins, + pmx->pins = devm_kzalloc(pfc->dev, + sizeof(*pmx->pins) * pfc->info->nr_pins, GFP_KERNEL); - if (unlikely(!pmx->pads)) + if (unlikely(!pmx->pins)) return -ENOMEM; for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { @@ -324,7 +357,7 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) for (number = range->begin; number <= range->end; number++, nr_pins++) { - struct pinctrl_pin_desc *pin = &pmx->pads[nr_pins]; + struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; struct sh_pfc_pin *info = &pfc->info->pins[nr_pins]; pin->number = number; @@ -337,37 +370,10 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) return nr_ranges; } -static int sh_pfc_map_functions(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) -{ - int i, fn; - - for (i = 0; i < pfc->info->nr_func_gpios; i++) { - struct pinmux_func *func = pfc->info->func_gpios + i; - - if (func->enum_id) - pmx->nr_functions++; - } - - pmx->functions = devm_kzalloc(pfc->dev, pmx->nr_functions * - sizeof(*pmx->functions), GFP_KERNEL); - if (unlikely(!pmx->functions)) - return -ENOMEM; - - for (i = fn = 0; i < pfc->info->nr_func_gpios; i++) { - struct pinmux_func *func = pfc->info->func_gpios + i; - - if (func->enum_id) - pmx->functions[fn++] = func; - } - - return 0; -} - int sh_pfc_register_pinctrl(struct sh_pfc *pfc) { struct sh_pfc_pinctrl *pmx; int nr_ranges; - int ret; pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); if (unlikely(!pmx)) @@ -380,16 +386,12 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) if (unlikely(nr_ranges < 0)) return nr_ranges; - ret = sh_pfc_map_functions(pfc, pmx); - if (unlikely(ret != 0)) - return ret; - pmx->pctl_desc.name = DRV_NAME; pmx->pctl_desc.owner = THIS_MODULE; pmx->pctl_desc.pctlops = &sh_pfc_pinctrl_ops; pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops; pmx->pctl_desc.confops = &sh_pfc_pinconf_ops; - pmx->pctl_desc.pins = pmx->pads; + pmx->pctl_desc.pins = pmx->pins; pmx->pctl_desc.npins = pfc->info->nr_pins; pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index dbcaa600ccc6..028e29ae0727 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -16,6 +16,8 @@ typedef unsigned short pinmux_enum_t; +#define SH_PFC_MARK_INVALID ((pinmux_enum_t)-1) + enum { PINMUX_TYPE_NONE, @@ -40,6 +42,34 @@ struct sh_pfc_pin { const char *name; }; +#define SH_PFC_PIN_GROUP(n) \ + { \ + .name = #n, \ + .pins = n##_pins, \ + .mux = n##_mux, \ + .nr_pins = ARRAY_SIZE(n##_pins), \ + } + +struct sh_pfc_pin_group { + const char *name; + const unsigned int *pins; + const unsigned int *mux; + unsigned int nr_pins; +}; + +#define SH_PFC_FUNCTION(n) \ + { \ + .name = #n, \ + .groups = n##_groups, \ + .nr_groups = ARRAY_SIZE(n##_groups), \ + } + +struct sh_pfc_function { + const char *name; + const char * const *groups; + unsigned int nr_groups; +}; + struct pinmux_func { const pinmux_enum_t enum_id; const char *name; @@ -113,6 +143,11 @@ struct sh_pfc_soc_info { unsigned int nr_pins; const struct pinmux_range *ranges; unsigned int nr_ranges; + const struct sh_pfc_pin_group *groups; + unsigned int nr_groups; + const struct sh_pfc_function *functions; + unsigned int nr_functions; + struct pinmux_func *func_gpios; unsigned int nr_func_gpios; -- cgit From fd9d05b0fdb0a8a2bbe2451b9e520547813d0562 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 22:08:12 +0800 Subject: sh-pfc: Fix return value check in sh_pfc_register_pinctrl() In case of error, the function pinctrl_register() returns NULL not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test. Signed-off-by: Wei Yongjun Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index c7f3c406f9de..3e49bf0eac25 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -395,8 +395,8 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->pctl_desc.npins = pfc->info->nr_pins; pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); - if (IS_ERR(pmx->pctl)) - return PTR_ERR(pmx->pctl); + if (pmx->pctl == NULL) + return -EINVAL; return 0; } -- cgit From 41f1219fae987f97787677d3a91c2f33ca9bab98 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 15 Feb 2013 02:04:55 +0100 Subject: sh-pfc: Move GPIO registers access functions to gpio.c Move the sh_pfc_setup_data_regs(), sh_pfc_setup_data_reg(), sh_pfc_get_data_reg(), sh_pfc_read_bit() and sh_pfc_write_bit() function to gpio.c as they belong to the GPIO implementation. Inline sh_pfc_read_bit() and sh_pfc_write_bit() in their only call location. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 110 ++---------------------------------------- drivers/pinctrl/sh-pfc/core.h | 11 +++-- drivers/pinctrl/sh-pfc/gpio.c | 92 ++++++++++++++++++++++++++++++++--- 3 files changed, 97 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 798248261f30..49fde283decd 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -55,8 +55,7 @@ static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev) return 0; } -static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, - unsigned long address) +void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address) { struct sh_pfc_window *window; int k; @@ -111,8 +110,8 @@ static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) return 1; } -static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, - unsigned long reg_width) +unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, + unsigned long reg_width) { switch (reg_width) { case 8: @@ -127,8 +126,8 @@ static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, return 0; } -static void sh_pfc_write_raw_reg(void __iomem *mapped_reg, - unsigned long reg_width, unsigned long data) +void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, + unsigned long data) { switch (reg_width) { case 8: @@ -145,37 +144,6 @@ static void sh_pfc_write_raw_reg(void __iomem *mapped_reg, BUG(); } -int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos) -{ - unsigned long pos; - - pos = dr->reg_width - (in_pos + 1); - - pr_debug("read_bit: addr = %lx, pos = %ld, " - "r_width = %ld\n", dr->reg, pos, dr->reg_width); - - return (sh_pfc_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; -} - -void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, - unsigned long value) -{ - unsigned long pos; - - pos = dr->reg_width - (in_pos + 1); - - pr_debug("write_bit addr = %lx, value = %d, pos = %ld, " - "r_width = %ld\n", - dr->reg, !!value, pos, dr->reg_width); - - if (value) - set_bit(pos, &dr->reg_shadow); - else - clear_bit(pos, &dr->reg_shadow); - - sh_pfc_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); -} - static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, struct pinmux_cfg_reg *crp, unsigned long in_pos, @@ -242,73 +210,6 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data); } -static void sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) -{ - struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; - struct pinmux_data_reg *data_reg; - int k, n; - - k = 0; - while (1) { - data_reg = pfc->info->data_regs + k; - - if (!data_reg->reg_width) - break; - - data_reg->mapped_reg = sh_pfc_phys_to_virt(pfc, data_reg->reg); - - for (n = 0; n < data_reg->reg_width; n++) { - if (data_reg->enum_ids[n] == gpiop->enum_id) { - gpiop->flags &= ~PINMUX_FLAG_DREG; - gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); - gpiop->flags &= ~PINMUX_FLAG_DBIT; - gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); - return; - } - } - k++; - } - - BUG(); -} - -static void sh_pfc_setup_data_regs(struct sh_pfc *pfc) -{ - struct pinmux_data_reg *drp; - int k; - - for (k = 0; k < pfc->info->nr_pins; k++) { - if (pfc->info->pins[k].enum_id == 0) - continue; - - sh_pfc_setup_data_reg(pfc, k); - } - - k = 0; - while (1) { - drp = pfc->info->data_regs + k; - - if (!drp->reg_width) - break; - - drp->reg_shadow = sh_pfc_read_raw_reg(drp->mapped_reg, - drp->reg_width); - k++; - } -} - -void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, - struct pinmux_data_reg **drp, int *bitp) -{ - struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); - int k, n; - - k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; - n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; - *drp = pfc->info->data_regs + k; - *bitp = n; -} - static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, struct pinmux_cfg_reg **crp, int *fieldp, int *valuep, unsigned long **cntp) @@ -518,7 +419,6 @@ static int sh_pfc_probe(struct platform_device *pdev) spin_lock_init(&pfc->lock); pinctrl_provide_dummies(); - sh_pfc_setup_data_regs(pfc); /* * Initialize pinctrl bindings first diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index b8b3e872cc19..434b62868764 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -46,11 +46,12 @@ int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); int sh_pfc_register_pinctrl(struct sh_pfc *pfc); int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); -int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos); -void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos, - unsigned long value); -void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio, - struct pinmux_data_reg **drp, int *bitp); +void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address); +unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, + unsigned long reg_width); +void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, + unsigned long data); + struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, int cfg_mode); diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 806e2dd62137..027c77762d8f 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -36,6 +36,71 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) return gpio_to_pfc_chip(gc)->pfc; } +static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, + struct pinmux_data_reg **dr, unsigned int *bit) +{ + struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); + + *dr = pfc->info->data_regs + + ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT); + *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; +} + +static void gpio_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) +{ + struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; + struct pinmux_data_reg *data_reg; + int k, n; + + k = 0; + while (1) { + data_reg = pfc->info->data_regs + k; + + if (!data_reg->reg_width) + break; + + data_reg->mapped_reg = sh_pfc_phys_to_virt(pfc, data_reg->reg); + + for (n = 0; n < data_reg->reg_width; n++) { + if (data_reg->enum_ids[n] == gpiop->enum_id) { + gpiop->flags &= ~PINMUX_FLAG_DREG; + gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); + gpiop->flags &= ~PINMUX_FLAG_DBIT; + gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); + return; + } + } + k++; + } + + BUG(); +} + +static void gpio_setup_data_regs(struct sh_pfc *pfc) +{ + struct pinmux_data_reg *drp; + int k; + + for (k = 0; k < pfc->info->nr_pins; k++) { + if (pfc->info->pins[k].enum_id == 0) + continue; + + gpio_setup_data_reg(pfc, k); + } + + k = 0; + while (1) { + drp = pfc->info->data_regs + k; + + if (!drp->reg_width) + break; + + drp->reg_shadow = sh_pfc_read_raw_reg(drp->mapped_reg, + drp->reg_width); + k++; + } +} + /* ----------------------------------------------------------------------------- * Pin GPIOs */ @@ -59,10 +124,19 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) { struct pinmux_data_reg *dr; - int bit; + unsigned long pos; + unsigned int bit; - sh_pfc_get_data_reg(pfc, offset, &dr, &bit); - sh_pfc_write_bit(dr, bit, value); + gpio_get_data_reg(pfc, offset, &dr, &bit); + + pos = dr->reg_width - (bit + 1); + + if (value) + set_bit(pos, &dr->reg_shadow); + else + clear_bit(pos, &dr->reg_shadow); + + sh_pfc_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); } static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) @@ -82,10 +156,14 @@ static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); struct pinmux_data_reg *dr; - int bit; + unsigned long pos; + unsigned int bit; - sh_pfc_get_data_reg(pfc, offset, &dr, &bit); - return sh_pfc_read_bit(dr, bit); + gpio_get_data_reg(pfc, offset, &dr, &bit); + + pos = dr->reg_width - (bit + 1); + + return (sh_pfc_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; } static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) @@ -226,6 +304,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) unsigned int i; int ret; + gpio_setup_data_regs(pfc); + /* Register the real GPIOs chip. */ chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); if (IS_ERR(chip)) -- cgit From e51d5343ffc4b81172178e51e6ca2ee00da67045 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 17 Feb 2013 00:26:33 +0100 Subject: sh-pfc: Don't map data registers individually All data registers are located in the same memory resource. Locate the mapped resource at initializat time and use it directly instead of computing a mapped address for each register. This gets rid of the mapped_reg field of the pinmux_data_reg structure. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 3 +- drivers/pinctrl/sh-pfc/core.h | 1 - drivers/pinctrl/sh-pfc/gpio.c | 130 ++++++++++++++++++++++++---------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 1 - 4 files changed, 82 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 49fde283decd..e847d1683546 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -55,7 +55,8 @@ static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev) return 0; } -void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address) +static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, + unsigned long address) { struct sh_pfc_window *window; int k; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 434b62868764..1c3816d60b4d 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -46,7 +46,6 @@ int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); int sh_pfc_register_pinctrl(struct sh_pfc *pfc); int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); -void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address); unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned long reg_width); void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 027c77762d8f..b370d2865041 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -24,6 +24,8 @@ struct sh_pfc_chip { struct sh_pfc *pfc; struct gpio_chip gpio_chip; + + struct sh_pfc_window *mem; }; static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc) @@ -46,59 +48,77 @@ static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; } -static void gpio_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) +static unsigned long gpio_read_data_reg(struct sh_pfc_chip *chip, + const struct pinmux_data_reg *dreg) { - struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; - struct pinmux_data_reg *data_reg; - int k, n; + void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt; - k = 0; - while (1) { - data_reg = pfc->info->data_regs + k; + return sh_pfc_read_raw_reg(mem, dreg->reg_width); +} - if (!data_reg->reg_width) - break; +static void gpio_write_data_reg(struct sh_pfc_chip *chip, + const struct pinmux_data_reg *dreg, + unsigned long value) +{ + void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt; - data_reg->mapped_reg = sh_pfc_phys_to_virt(pfc, data_reg->reg); + sh_pfc_write_raw_reg(mem, dreg->reg_width, value); +} - for (n = 0; n < data_reg->reg_width; n++) { - if (data_reg->enum_ids[n] == gpiop->enum_id) { +static void gpio_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) +{ + struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; + const struct pinmux_data_reg *dreg; + unsigned int bit; + unsigned int i; + + for (i = 0, dreg = pfc->info->data_regs; dreg->reg; ++i, ++dreg) { + for (bit = 0; bit < dreg->reg_width; bit++) { + if (dreg->enum_ids[bit] == gpiop->enum_id) { gpiop->flags &= ~PINMUX_FLAG_DREG; - gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); + gpiop->flags |= i << PINMUX_FLAG_DREG_SHIFT; gpiop->flags &= ~PINMUX_FLAG_DBIT; - gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); + gpiop->flags |= bit << PINMUX_FLAG_DBIT_SHIFT; return; } } - k++; } BUG(); } -static void gpio_setup_data_regs(struct sh_pfc *pfc) +static int gpio_setup_data_regs(struct sh_pfc_chip *chip) { - struct pinmux_data_reg *drp; - int k; + struct sh_pfc *pfc = chip->pfc; + unsigned long addr = pfc->info->data_regs[0].reg; + struct pinmux_data_reg *dreg; + unsigned int i; - for (k = 0; k < pfc->info->nr_pins; k++) { - if (pfc->info->pins[k].enum_id == 0) - continue; + /* Find the window that contain the GPIO registers. */ + for (i = 0; i < pfc->num_windows; ++i) { + struct sh_pfc_window *window = &pfc->window[i]; - gpio_setup_data_reg(pfc, k); + if (addr >= window->phys && addr < window->phys + window->size) + break; } - k = 0; - while (1) { - drp = pfc->info->data_regs + k; + if (i == pfc->num_windows) + return -EINVAL; - if (!drp->reg_width) - break; + /* GPIO data registers must be in the first memory resource. */ + chip->mem = &pfc->window[i]; + + for (dreg = pfc->info->data_regs; dreg->reg; ++dreg) + dreg->reg_shadow = gpio_read_data_reg(chip, dreg); + + for (i = 0; i < pfc->info->nr_pins; i++) { + if (pfc->info->pins[i].enum_id == 0) + continue; - drp->reg_shadow = sh_pfc_read_raw_reg(drp->mapped_reg, - drp->reg_width); - k++; + gpio_setup_data_reg(pfc, i); } + + return 0; } /* ----------------------------------------------------------------------------- @@ -121,22 +141,23 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) return pinctrl_free_gpio(offset); } -static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) +static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset, + int value) { - struct pinmux_data_reg *dr; + struct pinmux_data_reg *dreg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(pfc, offset, &dr, &bit); + gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); - pos = dr->reg_width - (bit + 1); + pos = dreg->reg_width - (bit + 1); if (value) - set_bit(pos, &dr->reg_shadow); + set_bit(pos, &dreg->reg_shadow); else - clear_bit(pos, &dr->reg_shadow); + clear_bit(pos, &dreg->reg_shadow); - sh_pfc_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); + gpio_write_data_reg(chip, dreg, dreg->reg_shadow); } static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) @@ -147,28 +168,28 @@ static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset, int value) { - gpio_pin_set_value(gpio_to_pfc(gc), offset, value); + gpio_pin_set_value(gpio_to_pfc_chip(gc), offset, value); return pinctrl_gpio_direction_output(offset); } static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { - struct sh_pfc *pfc = gpio_to_pfc(gc); - struct pinmux_data_reg *dr; + struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc); + struct pinmux_data_reg *dreg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(pfc, offset, &dr, &bit); + gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); - pos = dr->reg_width - (bit + 1); + pos = dreg->reg_width - (bit + 1); - return (sh_pfc_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; + return (gpio_read_data_reg(chip, dreg) >> pos) & 1; } static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) { - gpio_pin_set_value(gpio_to_pfc(gc), offset, value); + gpio_pin_set_value(gpio_to_pfc_chip(gc), offset, value); } static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset) @@ -188,10 +209,15 @@ static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset) return -ENOSYS; } -static void gpio_pin_setup(struct sh_pfc_chip *chip) +static int gpio_pin_setup(struct sh_pfc_chip *chip) { struct sh_pfc *pfc = chip->pfc; struct gpio_chip *gc = &chip->gpio_chip; + int ret; + + ret = gpio_setup_data_regs(chip); + if (ret < 0) + return ret; gc->request = gpio_pin_request; gc->free = gpio_pin_free; @@ -206,6 +232,8 @@ static void gpio_pin_setup(struct sh_pfc_chip *chip) gc->owner = THIS_MODULE; gc->base = 0; gc->ngpio = pfc->nr_pins; + + return 0; } /* ----------------------------------------------------------------------------- @@ -252,7 +280,7 @@ static void gpio_function_free(struct gpio_chip *gc, unsigned offset) spin_unlock_irqrestore(&pfc->lock, flags); } -static void gpio_function_setup(struct sh_pfc_chip *chip) +static int gpio_function_setup(struct sh_pfc_chip *chip) { struct sh_pfc *pfc = chip->pfc; struct gpio_chip *gc = &chip->gpio_chip; @@ -264,6 +292,8 @@ static void gpio_function_setup(struct sh_pfc_chip *chip) gc->owner = THIS_MODULE; gc->base = pfc->nr_pins; gc->ngpio = pfc->info->nr_func_gpios; + + return 0; } /* ----------------------------------------------------------------------------- @@ -271,7 +301,7 @@ static void gpio_function_setup(struct sh_pfc_chip *chip) */ static struct sh_pfc_chip * -sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *)) +sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *)) { struct sh_pfc_chip *chip; int ret; @@ -282,7 +312,9 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, void(*setup)(struct sh_pfc_chip *)) chip->pfc = pfc; - setup(chip); + ret = setup(chip); + if (ret < 0) + return ERR_PTR(ret); ret = gpiochip_add(&chip->gpio_chip); if (unlikely(ret < 0)) @@ -304,8 +336,6 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) unsigned int i; int ret; - gpio_setup_data_regs(pfc); - /* Register the real GPIOs chip. */ chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); if (IS_ERR(chip)) diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 028e29ae0727..ba3697dac869 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -110,7 +110,6 @@ struct pinmux_cfg_reg { struct pinmux_data_reg { unsigned long reg, reg_width, reg_shadow; pinmux_enum_t *enum_ids; - void __iomem *mapped_reg; }; #define PINMUX_DATA_REG(name, r, r_width) \ -- cgit From bee9f22ba196b0fa3b07507f685eb92b2075e1d1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 16 Feb 2013 23:39:07 +0100 Subject: sh-pfc: Drop unused support for 1:1 physical to virtual memory mappings Now that all PFC platform devices provide memory resources support for registers without an associated memory resource isn't used anymore. Drop it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index e847d1683546..cadfb376cb21 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -30,10 +30,8 @@ static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev) struct resource *res; int k; - if (pdev->num_resources == 0) { - pfc->num_windows = 0; - return 0; - } + if (pdev->num_resources == 0) + return -EINVAL; pfc->window = devm_kzalloc(pfc->dev, pdev->num_resources * sizeof(*pfc->window), GFP_NOWAIT); @@ -59,11 +57,11 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, unsigned long address) { struct sh_pfc_window *window; - int k; + unsigned int i; /* scan through physical windows and convert address */ - for (k = 0; k < pfc->num_windows; k++) { - window = pfc->window + k; + for (i = 0; i < pfc->num_windows; i++) { + window = pfc->window + i; if (address < window->phys) continue; @@ -74,8 +72,7 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, return window->virt + (address - window->phys); } - /* no windows defined, register must be 1:1 mapped virt:phys */ - return (void __iomem *)address; + BUG(); } struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin) -- cgit From 51cb226b359bc48fed4a92b9bbd9af34640b1be8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 16 Feb 2013 18:34:32 +0100 Subject: sh-pfc: Don't modify pinmux_data_reg SoC data The pinmux_data_reg structure supplied in SoC data contains information about data registers. It's abused to store per-device mapped iomem and shadow values. Move those fields out of the pinmux_data_reg structure into the per-device sh_pfc_chip structure. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/gpio.c | 58 ++++++++++++++++++++++++++++------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 2 +- 2 files changed, 41 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index b370d2865041..55eaf75decff 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -21,11 +21,17 @@ #include "core.h" +struct sh_pfc_gpio_data_reg { + const struct pinmux_data_reg *info; + unsigned long shadow; +}; + struct sh_pfc_chip { struct sh_pfc *pfc; struct gpio_chip gpio_chip; struct sh_pfc_window *mem; + struct sh_pfc_gpio_data_reg *regs; }; static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc) @@ -38,13 +44,16 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) return gpio_to_pfc_chip(gc)->pfc; } -static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, - struct pinmux_data_reg **dr, unsigned int *bit) +static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int gpio, + struct sh_pfc_gpio_data_reg **reg, + unsigned int *bit) { - struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); + struct sh_pfc_pin *gpiop = sh_pfc_get_pin(chip->pfc, gpio); + unsigned int reg_idx; - *dr = pfc->info->data_regs - + ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT); + reg_idx = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; + + *reg = &chip->regs[reg_idx]; *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; } @@ -91,7 +100,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) { struct sh_pfc *pfc = chip->pfc; unsigned long addr = pfc->info->data_regs[0].reg; - struct pinmux_data_reg *dreg; + const struct pinmux_data_reg *dreg; unsigned int i; /* Find the window that contain the GPIO registers. */ @@ -108,8 +117,21 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) /* GPIO data registers must be in the first memory resource. */ chip->mem = &pfc->window[i]; - for (dreg = pfc->info->data_regs; dreg->reg; ++dreg) - dreg->reg_shadow = gpio_read_data_reg(chip, dreg); + /* Count the number of data registers, allocate memory and initialize + * them. + */ + for (i = 0; pfc->info->data_regs[i].reg_width; ++i) + ; + + chip->regs = devm_kzalloc(pfc->dev, i * sizeof(*chip->regs), + GFP_KERNEL); + if (chip->regs == NULL) + return -ENOMEM; + + for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) { + chip->regs[i].info = dreg; + chip->regs[i].shadow = gpio_read_data_reg(chip, dreg); + } for (i = 0; i < pfc->info->nr_pins; i++) { if (pfc->info->pins[i].enum_id == 0) @@ -144,20 +166,20 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset, int value) { - struct pinmux_data_reg *dreg; + struct sh_pfc_gpio_data_reg *reg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); + gpio_get_data_reg(chip, offset, ®, &bit); - pos = dreg->reg_width - (bit + 1); + pos = reg->info->reg_width - (bit + 1); if (value) - set_bit(pos, &dreg->reg_shadow); + set_bit(pos, ®->shadow); else - clear_bit(pos, &dreg->reg_shadow); + clear_bit(pos, ®->shadow); - gpio_write_data_reg(chip, dreg, dreg->reg_shadow); + gpio_write_data_reg(chip, reg->info, reg->shadow); } static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) @@ -176,15 +198,15 @@ static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset, static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc); - struct pinmux_data_reg *dreg; + struct sh_pfc_gpio_data_reg *reg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); + gpio_get_data_reg(chip, offset, ®, &bit); - pos = dreg->reg_width - (bit + 1); + pos = reg->info->reg_width - (bit + 1); - return (gpio_read_data_reg(chip, dreg) >> pos) & 1; + return (gpio_read_data_reg(chip, reg->info) >> pos) & 1; } static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index ba3697dac869..e6a51a9e47ba 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -108,7 +108,7 @@ struct pinmux_cfg_reg { .enum_ids = (pinmux_enum_t []) struct pinmux_data_reg { - unsigned long reg, reg_width, reg_shadow; + unsigned long reg, reg_width; pinmux_enum_t *enum_ids; }; -- cgit From 1a0039dce269317a843d4fc85c4a3430b484bc2d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Mar 2013 17:43:54 +0100 Subject: sh-pfc: Don't modify sh_pfc_pin SoC data The sh_pfc_pin structure supplied in SoC data contains information about pin configuration and name. It's abused to store GPIO data registers information and pin config type. Move those fields out of the pinmux_data_reg structure into the new sh_pfc_gpio_pin and sh_pfc_pin_config structures. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 14 +++------- drivers/pinctrl/sh-pfc/core.h | 2 +- drivers/pinctrl/sh-pfc/gpio.c | 47 +++++++++++++++++++------------- drivers/pinctrl/sh-pfc/pinctrl.c | 59 ++++++++++++++++++++++++---------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 7 ----- 5 files changed, 68 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index cadfb376cb21..19735012ffb4 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -75,26 +75,25 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, BUG(); } -struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin) +int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) { unsigned int offset; unsigned int i; if (pfc->info->ranges == NULL) - return &pfc->info->pins[pin]; + return pin; for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) { const struct pinmux_range *range = &pfc->info->ranges[i]; if (pin <= range->end) return pin >= range->begin - ? &pfc->info->pins[offset + pin - range->begin] - : NULL; + ? offset + pin - range->begin : -1; offset += range->end - range->begin + 1; } - return NULL; + return -1; } static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) @@ -393,11 +392,6 @@ static int sh_pfc_probe(struct platform_device *pdev) struct sh_pfc *pfc; int ret; - /* - * Ensure that the type encoding fits - */ - BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1)); - info = pdev->id_entry->driver_data ? (void *)pdev->id_entry->driver_data : pdev->dev.platform_data; if (info == NULL) diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 1c3816d60b4d..6db54aa083f2 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -51,7 +51,7 @@ unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, unsigned long data); -struct sh_pfc_pin *sh_pfc_get_pin(struct sh_pfc *pfc, unsigned int pin); +int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, int cfg_mode); diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 55eaf75decff..ce074b22f426 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -26,12 +26,18 @@ struct sh_pfc_gpio_data_reg { unsigned long shadow; }; +struct sh_pfc_gpio_pin { + u8 dbit; + u8 dreg; +}; + struct sh_pfc_chip { - struct sh_pfc *pfc; - struct gpio_chip gpio_chip; + struct sh_pfc *pfc; + struct gpio_chip gpio_chip; - struct sh_pfc_window *mem; + struct sh_pfc_window *mem; struct sh_pfc_gpio_data_reg *regs; + struct sh_pfc_gpio_pin *pins; }; static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc) @@ -48,13 +54,11 @@ static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int gpio, struct sh_pfc_gpio_data_reg **reg, unsigned int *bit) { - struct sh_pfc_pin *gpiop = sh_pfc_get_pin(chip->pfc, gpio); - unsigned int reg_idx; + int idx = sh_pfc_get_pin_index(chip->pfc, gpio); + struct sh_pfc_gpio_pin *gpio_pin = &chip->pins[idx]; - reg_idx = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; - - *reg = &chip->regs[reg_idx]; - *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; + *reg = &chip->regs[gpio_pin->dreg]; + *bit = gpio_pin->dbit; } static unsigned long gpio_read_data_reg(struct sh_pfc_chip *chip, @@ -74,20 +78,20 @@ static void gpio_write_data_reg(struct sh_pfc_chip *chip, sh_pfc_write_raw_reg(mem, dreg->reg_width, value); } -static void gpio_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) +static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned gpio) { - struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; + struct sh_pfc *pfc = chip->pfc; + struct sh_pfc_gpio_pin *gpio_pin = &chip->pins[gpio]; + struct sh_pfc_pin *pin = &pfc->info->pins[gpio]; const struct pinmux_data_reg *dreg; unsigned int bit; unsigned int i; for (i = 0, dreg = pfc->info->data_regs; dreg->reg; ++i, ++dreg) { for (bit = 0; bit < dreg->reg_width; bit++) { - if (dreg->enum_ids[bit] == gpiop->enum_id) { - gpiop->flags &= ~PINMUX_FLAG_DREG; - gpiop->flags |= i << PINMUX_FLAG_DREG_SHIFT; - gpiop->flags &= ~PINMUX_FLAG_DBIT; - gpiop->flags |= bit << PINMUX_FLAG_DBIT_SHIFT; + if (dreg->enum_ids[bit] == pin->enum_id) { + gpio_pin->dreg = i; + gpio_pin->dbit = bit; return; } } @@ -137,7 +141,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) if (pfc->info->pins[i].enum_id == 0) continue; - gpio_setup_data_reg(pfc, i); + gpio_setup_data_reg(chip, i); } return 0; @@ -150,9 +154,9 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) static int gpio_pin_request(struct gpio_chip *gc, unsigned offset) { struct sh_pfc *pfc = gpio_to_pfc(gc); - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + int idx = sh_pfc_get_pin_index(pfc, offset); - if (pin == NULL || pin->enum_id == 0) + if (idx < 0 || pfc->info->pins[idx].enum_id == 0) return -EINVAL; return pinctrl_request_gpio(offset); @@ -237,6 +241,11 @@ static int gpio_pin_setup(struct sh_pfc_chip *chip) struct gpio_chip *gc = &chip->gpio_chip; int ret; + chip->pins = devm_kzalloc(pfc->dev, pfc->nr_pins * sizeof(*chip->pins), + GFP_KERNEL); + if (chip->pins == NULL) + return -ENOMEM; + ret = gpio_setup_data_regs(chip); if (ret < 0) return ret; diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 3e49bf0eac25..ef5cf5d8298f 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -25,6 +25,10 @@ #include "core.h" +struct sh_pfc_pin_config { + u32 type; +}; + struct sh_pfc_pinctrl { struct pinctrl_dev *pctl; struct pinctrl_desc pctl_desc; @@ -32,6 +36,7 @@ struct sh_pfc_pinctrl { struct sh_pfc *pfc; struct pinctrl_pin_desc *pins; + struct sh_pfc_pin_config *configs; }; static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) @@ -148,30 +153,30 @@ static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, spin_unlock_irqrestore(&pfc->lock, flags); } -static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, +static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, int new_type) { - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + struct sh_pfc *pfc = pmx->pfc; + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned int mark = pin->enum_id; unsigned long flags; - int pinmux_type; int ret = -EINVAL; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - /* * See if the present config needs to first be de-configured. */ - switch (pinmux_type) { + switch (cfg->type) { case PINMUX_TYPE_GPIO: break; case PINMUX_TYPE_OUTPUT: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_INPUT_PULLUP: case PINMUX_TYPE_INPUT_PULLDOWN: - sh_pfc_config_mux(pfc, mark, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, mark, cfg->type, GPIO_CFG_FREE); break; default: goto err; @@ -189,8 +194,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0) goto err; - pin->flags &= ~PINMUX_FLAG_TYPE; - pin->flags |= new_type; + cfg->type = new_type; ret = 0; @@ -206,22 +210,21 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; unsigned long flags; - int ret, pinmux_type; + int ret; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - - switch (pinmux_type) { + switch (cfg->type) { case PINMUX_TYPE_GPIO: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_OUTPUT: break; case PINMUX_TYPE_FUNCTION: default: - pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); + pr_err("Unsupported mux type (%d), bailing...\n", cfg->type); ret = -ENOTSUPP; goto err; } @@ -240,15 +243,14 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned long flags; - int pinmux_type; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - - sh_pfc_config_mux(pfc, pin->enum_id, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, pin->enum_id, cfg->type, GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } @@ -260,7 +262,7 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; - return sh_pfc_reconfig_pin(pmx->pfc, offset, type); + return sh_pfc_reconfig_pin(pmx, offset, type); } static const struct pinmux_ops sh_pfc_pinmux_ops = { @@ -279,9 +281,10 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, _pin); + int idx = sh_pfc_get_pin_index(pfc, _pin); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - *config = pin->flags & PINMUX_FLAG_TYPE; + *config = cfg->type; return 0; } @@ -295,7 +298,7 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, if (config >= PINMUX_FLAG_TYPE) return -EINVAL; - return sh_pfc_reconfig_pin(pmx->pfc, pin, config); + return sh_pfc_reconfig_pin(pmx, pin, config); } static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev, @@ -351,17 +354,25 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) if (unlikely(!pmx->pins)) return -ENOMEM; + pmx->configs = devm_kzalloc(pfc->dev, + sizeof(*pmx->configs) * pfc->info->nr_pins, + GFP_KERNEL); + if (unlikely(!pmx->configs)) + return -ENOMEM; + for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { const struct pinmux_range *range = &ranges[i]; unsigned int number; for (number = range->begin; number <= range->end; number++, nr_pins++) { + struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; struct sh_pfc_pin *info = &pfc->info->pins[nr_pins]; pin->number = number; pin->name = info->name; + cfg->type = PINMUX_TYPE_GPIO; } } diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index e6a51a9e47ba..6a4a62fd39ec 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -31,14 +31,8 @@ enum { PINMUX_FLAG_TYPE, /* must be last */ }; -#define PINMUX_FLAG_DBIT_SHIFT 5 -#define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) -#define PINMUX_FLAG_DREG_SHIFT 10 -#define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) - struct sh_pfc_pin { const pinmux_enum_t enum_id; - unsigned short flags; const char *name; }; @@ -79,7 +73,6 @@ struct pinmux_func { [gpio] = { \ .name = __stringify(gpio), \ .enum_id = data_or_mark, \ - .flags = PINMUX_TYPE_GPIO \ } #define PINMUX_GPIO_FN(gpio, base, data_or_mark) \ [gpio - (base)] = { \ -- cgit From 861601de101215494e2cc7918e8633d63da490ef Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 15:29:14 +0100 Subject: sh-pfc: Remove configuration dry-run and free The purpose of the dry-run is to ensure that a pin about to be configured isn't in use. However, the current implementation is a no-op. This proves that the dry-run isn't essential. Remove it. Freeing configuration then becomes a no-op as well. Remove it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 50 ++++++---------------------------------- drivers/pinctrl/sh-pfc/core.h | 3 +-- drivers/pinctrl/sh-pfc/gpio.c | 14 +---------- drivers/pinctrl/sh-pfc/pinctrl.c | 48 ++------------------------------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 5 +--- 5 files changed, 12 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 19735012ffb4..e2864ec900f4 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -163,22 +163,6 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, } } -static int sh_pfc_read_config_reg(struct sh_pfc *pfc, - struct pinmux_cfg_reg *crp, - unsigned long field) -{ - void __iomem *mapped_reg; - unsigned long mask, pos; - - sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos); - - pr_debug("read_reg: addr = %lx, field = %ld, " - "r_width = %ld, f_width = %ld\n", - crp->reg, field, crp->reg_width, crp->field_width); - - return (sh_pfc_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask; -} - static void sh_pfc_write_config_reg(struct sh_pfc *pfc, struct pinmux_cfg_reg *crp, unsigned long field, unsigned long value) @@ -209,7 +193,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, struct pinmux_cfg_reg **crp, int *fieldp, - int *valuep, unsigned long **cntp) + int *valuep) { struct pinmux_cfg_reg *config_reg; unsigned long r_width, f_width, curr_width, ncomb; @@ -239,7 +223,6 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, *crp = config_reg; *fieldp = m; *valuep = n; - *cntp = &config_reg->cnt[m]; return 0; } } @@ -274,14 +257,12 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, return -1; } -int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, - int cfg_mode) +int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) { struct pinmux_cfg_reg *cr = NULL; pinmux_enum_t enum_id; struct pinmux_range *range; int in_range, pos, field, value; - unsigned long *cntp; switch (pinmux_type) { @@ -306,7 +287,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, break; default: - goto out_err; + return -1; } pos = 0; @@ -316,7 +297,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, while (1) { pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); if (pos <= 0) - goto out_err; + return -1; if (!enum_id) break; @@ -360,30 +341,13 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, continue; if (sh_pfc_get_config_reg(pfc, enum_id, &cr, - &field, &value, &cntp) != 0) - goto out_err; - - switch (cfg_mode) { - case GPIO_CFG_DRYRUN: - if (!*cntp || - (sh_pfc_read_config_reg(pfc, cr, field) != value)) - continue; - break; - - case GPIO_CFG_REQ: - sh_pfc_write_config_reg(pfc, cr, field, value); - *cntp = *cntp + 1; - break; + &field, &value) != 0) + return -1; - case GPIO_CFG_FREE: - *cntp = *cntp - 1; - break; - } + sh_pfc_write_config_reg(pfc, cr, field, value); } return 0; - out_err: - return -1; } static int sh_pfc_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 6db54aa083f2..7b2b4f0accfc 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -52,8 +52,7 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, unsigned long data); int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); -int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type, - int cfg_mode); +int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); extern struct sh_pfc_soc_info r8a7740_pinmux_info; extern struct sh_pfc_soc_info r8a7779_pinmux_info; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index ce074b22f426..761a0dad0450 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -285,10 +285,7 @@ static int gpio_function_request(struct gpio_chip *gc, unsigned offset) spin_lock_irqsave(&pfc->lock, flags); - if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_DRYRUN)) - goto done; - - if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_REQ)) + if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION)) goto done; ret = 0; @@ -300,15 +297,6 @@ done: static void gpio_function_free(struct gpio_chip *gc, unsigned offset) { - struct sh_pfc *pfc = gpio_to_pfc(gc); - unsigned int mark = pfc->info->func_gpios[offset].enum_id; - unsigned long flags; - - spin_lock_irqsave(&pfc->lock, flags); - - sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION, GPIO_CFG_FREE); - - spin_unlock_irqrestore(&pfc->lock, flags); } static int gpio_function_setup(struct sh_pfc_chip *chip) diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index ef5cf5d8298f..9978ad1818fd 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -119,12 +119,7 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, spin_lock_irqsave(&pfc->lock, flags); for (i = 0; i < grp->nr_pins; ++i) { - if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, - GPIO_CFG_DRYRUN)) - goto done; - - if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, - GPIO_CFG_REQ)) + if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION)) goto done; } @@ -138,19 +133,6 @@ done: static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { - struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - struct sh_pfc *pfc = pmx->pfc; - const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; - unsigned long flags; - unsigned int i; - - spin_lock_irqsave(&pfc->lock, flags); - - for (i = 0; i < grp->nr_pins; ++i) - sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION, - GPIO_CFG_FREE); - - spin_unlock_irqrestore(&pfc->lock, flags); } static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, @@ -166,32 +148,18 @@ static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, spin_lock_irqsave(&pfc->lock, flags); - /* - * See if the present config needs to first be de-configured. - */ switch (cfg->type) { case PINMUX_TYPE_GPIO: - break; case PINMUX_TYPE_OUTPUT: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_INPUT_PULLUP: case PINMUX_TYPE_INPUT_PULLDOWN: - sh_pfc_config_mux(pfc, mark, cfg->type, GPIO_CFG_FREE); break; default: goto err; } - /* - * Dry run - */ - if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_DRYRUN) != 0) - goto err; - - /* - * Request - */ - if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0) + if (sh_pfc_config_mux(pfc, mark, new_type) != 0) goto err; cfg->type = new_type; @@ -241,18 +209,6 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) { - struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - struct sh_pfc *pfc = pmx->pfc; - int idx = sh_pfc_get_pin_index(pfc, offset); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - struct sh_pfc_pin *pin = &pfc->info->pins[idx]; - unsigned long flags; - - spin_lock_irqsave(&pfc->lock, flags); - - sh_pfc_config_mux(pfc, pin->enum_id, cfg->type, GPIO_CFG_FREE); - - spin_unlock_irqrestore(&pfc->lock, flags); } static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 6a4a62fd39ec..19da3b7c57f1 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -84,19 +84,16 @@ struct pinmux_func { struct pinmux_cfg_reg { unsigned long reg, reg_width, field_width; - unsigned long *cnt; pinmux_enum_t *enum_ids; unsigned long *var_field_width; }; #define PINMUX_CFG_REG(name, r, r_width, f_width) \ .reg = r, .reg_width = r_width, .field_width = f_width, \ - .cnt = (unsigned long [r_width / f_width]) {}, \ .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) #define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \ .reg = r, .reg_width = r_width, \ - .cnt = (unsigned long [r_width]) {}, \ .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \ .enum_ids = (pinmux_enum_t []) @@ -155,7 +152,7 @@ struct sh_pfc_soc_info { unsigned long unlock_reg; }; -enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; +enum { GPIO_CFG_REQ, GPIO_CFG_FREE }; /* helper macro for port */ #define PORT_1(fn, pfx, sfx) fn(pfx, sfx) -- cgit From cd3c1beecfeb757b16904386ea474d3c272de4ee Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 16 Feb 2013 18:47:05 +0100 Subject: sh-pfc: Constify all SoC data None of the SoC data need to be modified. Constify it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 19 ++++++++++--------- drivers/pinctrl/sh-pfc/core.h | 34 +++++++++++++++++----------------- drivers/pinctrl/sh-pfc/gpio.c | 2 +- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 12 ++++++------ drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7203.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7269.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 12 ++++++------ drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 14 +++++++------- drivers/pinctrl/sh-pfc/pfc-sh7720.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7722.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7723.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7724.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7757.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7785.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-sh7786.c | 10 +++++----- drivers/pinctrl/sh-pfc/pfc-shx3.c | 10 +++++----- drivers/pinctrl/sh-pfc/pinctrl.c | 5 +++-- drivers/pinctrl/sh-pfc/sh_pfc.h | 20 ++++++++++---------- 21 files changed, 125 insertions(+), 123 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index e2864ec900f4..3a949465e88e 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -96,7 +96,8 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) return -1; } -static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) +static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, + const struct pinmux_range *r) { if (enum_id < r->begin) return 0; @@ -142,7 +143,7 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, } static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, - struct pinmux_cfg_reg *crp, + const struct pinmux_cfg_reg *crp, unsigned long in_pos, void __iomem **mapped_regp, unsigned long *maskp, @@ -164,7 +165,7 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, } static void sh_pfc_write_config_reg(struct sh_pfc *pfc, - struct pinmux_cfg_reg *crp, + const struct pinmux_cfg_reg *crp, unsigned long field, unsigned long value) { void __iomem *mapped_reg; @@ -192,10 +193,10 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, } static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, - struct pinmux_cfg_reg **crp, int *fieldp, + const struct pinmux_cfg_reg **crp, int *fieldp, int *valuep) { - struct pinmux_cfg_reg *config_reg; + const struct pinmux_cfg_reg *config_reg; unsigned long r_width, f_width, curr_width, ncomb; int k, m, n, pos, bit_pos; @@ -238,7 +239,7 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, pinmux_enum_t *enum_idp) { - pinmux_enum_t *data = pfc->info->gpio_data; + const pinmux_enum_t *data = pfc->info->gpio_data; int k; if (pos) { @@ -259,9 +260,9 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) { - struct pinmux_cfg_reg *cr = NULL; + const struct pinmux_cfg_reg *cr = NULL; pinmux_enum_t enum_id; - struct pinmux_range *range; + const struct pinmux_range *range; int in_range, pos, field, value; switch (pinmux_type) { @@ -352,7 +353,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) static int sh_pfc_probe(struct platform_device *pdev) { - struct sh_pfc_soc_info *info; + const struct sh_pfc_soc_info *info; struct sh_pfc *pfc; int ret; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 7b2b4f0accfc..763d717ca979 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -26,7 +26,7 @@ struct sh_pfc_pinctrl; struct sh_pfc { struct device *dev; - struct sh_pfc_soc_info *info; + const struct sh_pfc_soc_info *info; spinlock_t lock; unsigned int num_windows; @@ -54,21 +54,21 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); -extern struct sh_pfc_soc_info r8a7740_pinmux_info; -extern struct sh_pfc_soc_info r8a7779_pinmux_info; -extern struct sh_pfc_soc_info sh7203_pinmux_info; -extern struct sh_pfc_soc_info sh7264_pinmux_info; -extern struct sh_pfc_soc_info sh7269_pinmux_info; -extern struct sh_pfc_soc_info sh7372_pinmux_info; -extern struct sh_pfc_soc_info sh73a0_pinmux_info; -extern struct sh_pfc_soc_info sh7720_pinmux_info; -extern struct sh_pfc_soc_info sh7722_pinmux_info; -extern struct sh_pfc_soc_info sh7723_pinmux_info; -extern struct sh_pfc_soc_info sh7724_pinmux_info; -extern struct sh_pfc_soc_info sh7734_pinmux_info; -extern struct sh_pfc_soc_info sh7757_pinmux_info; -extern struct sh_pfc_soc_info sh7785_pinmux_info; -extern struct sh_pfc_soc_info sh7786_pinmux_info; -extern struct sh_pfc_soc_info shx3_pinmux_info; +extern const struct sh_pfc_soc_info r8a7740_pinmux_info; +extern const struct sh_pfc_soc_info r8a7779_pinmux_info; +extern const struct sh_pfc_soc_info sh7203_pinmux_info; +extern const struct sh_pfc_soc_info sh7264_pinmux_info; +extern const struct sh_pfc_soc_info sh7269_pinmux_info; +extern const struct sh_pfc_soc_info sh7372_pinmux_info; +extern const struct sh_pfc_soc_info sh73a0_pinmux_info; +extern const struct sh_pfc_soc_info sh7720_pinmux_info; +extern const struct sh_pfc_soc_info sh7722_pinmux_info; +extern const struct sh_pfc_soc_info sh7723_pinmux_info; +extern const struct sh_pfc_soc_info sh7724_pinmux_info; +extern const struct sh_pfc_soc_info sh7734_pinmux_info; +extern const struct sh_pfc_soc_info sh7757_pinmux_info; +extern const struct sh_pfc_soc_info sh7785_pinmux_info; +extern const struct sh_pfc_soc_info sh7786_pinmux_info; +extern const struct sh_pfc_soc_info shx3_pinmux_info; #endif /* __SH_PFC_CORE_H__ */ diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 761a0dad0450..480beae2ee67 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -82,7 +82,7 @@ static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned gpio) { struct sh_pfc *pfc = chip->pfc; struct sh_pfc_gpio_pin *gpio_pin = &chip->pins[gpio]; - struct sh_pfc_pin *pin = &pfc->info->pins[gpio]; + const struct sh_pfc_pin *pin = &pfc->info->pins[gpio]; const struct pinmux_data_reg *dreg; unsigned int bit; unsigned int i; diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index fd91381aaaf3..de13348be5c0 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -577,7 +577,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* specify valid pin states for each pin in GPIO mode */ /* I/O and Pull U/D */ @@ -1660,7 +1660,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* IRQ */ GPIO_FN(IRQ0_PORT2), GPIO_FN(IRQ0_PORT13), GPIO_FN(IRQ1), @@ -2128,7 +2128,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(TRACEAUD_FROM_MEMC), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { PORTCR(0, 0xe6050000), /* PORT0CR */ PORTCR(1, 0xe6050001), /* PORT1CR */ PORTCR(2, 0xe6050002), /* PORT2CR */ @@ -2442,7 +2442,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054800, 32) { PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA, PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA, @@ -2546,7 +2546,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -static struct pinmux_irq pinmux_irqs[] = { +static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(evt2irq(0x0200), GPIO_PORT2, GPIO_PORT13), /* IRQ0A */ PINMUX_IRQ(evt2irq(0x0220), GPIO_PORT20), /* IRQ1A */ PINMUX_IRQ(evt2irq(0x0240), GPIO_PORT11, GPIO_PORT12), /* IRQ2A */ @@ -2581,7 +2581,7 @@ static struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(evt2irq(0x33E0), GPIO_PORT41, GPIO_PORT167),/* IRQ31A */ }; -struct sh_pfc_soc_info r8a7740_pinmux_info = { +const struct sh_pfc_soc_info r8a7740_pinmux_info = { .name = "r8a7740_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index e9a7ead139fa..eb5685848b68 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -631,7 +631,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ PINMUX_DATA(AVS1_MARK, FN_AVS1), @@ -1438,7 +1438,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(AVS1), GPIO_FN(AVS2), GPIO_FN(A17), GPIO_FN(A18), GPIO_FN(A19), @@ -1710,7 +1710,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI3_DATA7), GPIO_FN(GPS_MAG), GPIO_FN(FCE), GPIO_FN(SCK4_B), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("GPSR0", 0xfffc0004, 32, 1) { GP_0_31_FN, FN_IP3_31_29, GP_0_30_FN, FN_IP3_26_24, @@ -2571,7 +2571,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("INDT0", 0xffc40008, 32) { GP_INDT(0) } }, { PINMUX_DATA_REG("INDT1", 0xffc41008, 32) { GP_INDT(1) } }, { PINMUX_DATA_REG("INDT2", 0xffc42008, 32) { GP_INDT(2) } }, @@ -2587,7 +2587,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info r8a7779_pinmux_info = { +const struct sh_pfc_soc_info r8a7779_pinmux_info = { .name = "r8a7779_pfc", .unlock_reg = 0xfffc0000, /* PMMR */ diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7203.c b/drivers/pinctrl/sh-pfc/pfc-sh7203.c index fc4a1280accb..f63d51dc3f4c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7203.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7203.c @@ -272,7 +272,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PA */ PINMUX_DATA(PA7_DATA, PA7_IN), @@ -819,7 +819,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(PINT7_PB), GPIO_FN(PINT6_PB), @@ -1077,7 +1077,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(LCD_DATA0), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PBIORL", 0xfffe3886, 16, 1) { 0, 0, 0, 0, @@ -1529,7 +1529,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADRL", 0xfffe3802, 16) { 0, 0, 0, 0, 0, 0, 0, 0, @@ -1575,7 +1575,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7203_pinmux_info = { +const struct sh_pfc_soc_info sh7203_pinmux_info = { .name = "sh7203_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index c03365cd945d..284675249ed9 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -604,7 +604,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* Port A */ PINMUX_DATA(PA3_DATA, PA3_IN), @@ -1220,7 +1220,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(PINT7_PG), GPIO_FN(PINT6_PG), @@ -1470,7 +1470,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(LCD_M_DISP), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PAIOR0", 0xfffe3812, 16, 1) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2036,7 +2036,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR1", 0xfffe3814, 16) { 0, 0, 0, 0, 0, 0, 0, PA3_DATA, 0, 0, 0, 0, 0, 0, 0, PA2_DATA } @@ -2114,7 +2114,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { } }; -struct sh_pfc_soc_info sh7264_pinmux_info = { +const struct sh_pfc_soc_info sh7264_pinmux_info = { .name = "sh7264_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c index 1fa0950519e4..4c401a74acd5 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -781,7 +781,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* Port A */ PINMUX_DATA(PA1_DATA, PA1_IN), @@ -1617,7 +1617,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* INTC */ GPIO_FN(IRQ7_PG), GPIO_FN(IRQ6_PG), @@ -1949,7 +1949,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(LCD_M_DISP), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { /* "name" addr register_size Field_Width */ /* where Field_Width is 1 for single mode registers or 4 for upto 16 @@ -2738,7 +2738,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR0", 0xfffe3816, 16) { 0, 0, 0, 0, 0, 0, 0, PA1_DATA, 0, 0, 0, 0, 0, 0, 0, PA0_DATA } @@ -2817,7 +2817,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { } }; -struct sh_pfc_soc_info sh7269_pinmux_info = { +const struct sh_pfc_soc_info sh7269_pinmux_info = { .name = "sh7269_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 847e0cd1b748..6b5634454956 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -368,7 +368,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* specify valid pin states for each pin in GPIO mode */ PORT_DATA_IO_PD(0), PORT_DATA_IO_PD(1), @@ -935,7 +935,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* IRQ */ GPIO_FN(IRQ0_6), GPIO_FN(IRQ0_162), GPIO_FN(IRQ1), GPIO_FN(IRQ2_4), GPIO_FN(IRQ2_5), GPIO_FN(IRQ3_8), @@ -1202,7 +1202,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SDENC_DV_CLKI), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { PORTCR(0, 0xE6051000), /* PORT0CR */ PORTCR(1, 0xE6051001), /* PORT1CR */ PORTCR(2, 0xE6051002), /* PORT2CR */ @@ -1474,7 +1474,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PORTL095_064DR", 0xE6054008, 32) { PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA, PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA, @@ -1599,7 +1599,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { #define EXT_IRQ16L(n) evt2irq(0x200 + ((n) << 5)) #define EXT_IRQ16H(n) evt2irq(0x3200 + (((n) - 16) << 5)) -static struct pinmux_irq pinmux_irqs[] = { +static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16L(0), GPIO_PORT6, GPIO_PORT162), PINMUX_IRQ(EXT_IRQ16L(1), GPIO_PORT12), PINMUX_IRQ(EXT_IRQ16L(2), GPIO_PORT4, GPIO_PORT5), @@ -1634,7 +1634,7 @@ static struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16H(31), GPIO_PORT138, GPIO_PORT184), }; -struct sh_pfc_soc_info sh7372_pinmux_info = { +const struct sh_pfc_soc_info sh7372_pinmux_info = { .name = "sh7372_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 9cef0d8b8ccd..3200fc2f34b1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -509,7 +509,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* specify valid pin states for each pin in GPIO mode */ /* Table 25-1 (I/O and Pull U/D) */ @@ -1543,7 +1543,7 @@ static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; -static struct pinmux_range pinmux_ranges[] = { +static const struct pinmux_range pinmux_ranges[] = { {.begin = 0, .end = 118,}, {.begin = 128, .end = 164,}, {.begin = 192, .end = 282,}, @@ -1552,7 +1552,7 @@ static struct pinmux_range pinmux_ranges[] = { #define PINMUX_FN_BASE GPIO_FN_VBUS_0 -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* Table 25-1 (Functions 0-7) */ GPIO_FN(VBUS_0), GPIO_FN(GPI0), @@ -2228,7 +2228,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(FSIAISLD_PU), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { PORTCR(0, 0xe6050000), /* PORT0CR */ PORTCR(1, 0xe6050001), /* PORT1CR */ PORTCR(2, 0xe6050002), /* PORT2CR */ @@ -2636,7 +2636,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) { PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA, PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA, @@ -2744,7 +2744,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { #define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5)) #define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) -static struct pinmux_irq pinmux_irqs[] = { +static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16H(19), 9), PINMUX_IRQ(EXT_IRQ16L(1), 10), PINMUX_IRQ(EXT_IRQ16L(0), 11), @@ -2779,7 +2779,7 @@ static struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16L(9), 308), }; -struct sh_pfc_soc_info sh73a0_pinmux_info = { +const struct sh_pfc_soc_info sh73a0_pinmux_info = { .name = "sh73a0_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7720.c b/drivers/pinctrl/sh-pfc/pfc-sh7720.c index 0b3078b6acdf..52e9f6be665f 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7720.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7720.c @@ -262,7 +262,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PTA GPIO */ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT, PTA7_IN_PU), PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT, PTA6_IN_PU), @@ -763,7 +763,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* BSC */ GPIO_FN(D31), GPIO_FN(D30), @@ -957,7 +957,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(STATUS1), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) { PTA7_FN, PTA7_OUT, PTA7_IN_PU, PTA7_IN, PTA6_FN, PTA6_OUT, PTA6_IN_PU, PTA6_IN, @@ -1141,7 +1141,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xa4050140, 8) { PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } @@ -1217,7 +1217,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7720_pinmux_info = { +const struct sh_pfc_soc_info sh7720_pinmux_info = { .name = "sh7720_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7722.c b/drivers/pinctrl/sh-pfc/pfc-sh7722.c index 3a8d95fd3ed3..32034387477b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7722.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7722.c @@ -296,7 +296,7 @@ enum { PINMUX_FUNCTION_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PTA */ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_IN_PD, PTA7_OUT), PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_IN_PD), @@ -986,7 +986,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* SCIF0 */ GPIO_FN(SCIF0_TXD), GPIO_FN(SCIF0_RXD), @@ -1268,7 +1268,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(KEYOUT5_IN5), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) { VIO_D7_SCIF1_SCK, PTA7_OUT, PTA7_IN_PD, PTA7_IN, VIO_D6_SCIF1_RXD, 0, PTA6_IN_PD, PTA6_IN, @@ -1664,7 +1664,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xa4050120, 8) { PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } @@ -1760,7 +1760,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7722_pinmux_info = { +const struct sh_pfc_soc_info sh7722_pinmux_info = { .name = "sh7722_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7723.c b/drivers/pinctrl/sh-pfc/pfc-sh7723.c index d8797ff4339b..07ad1d8d6c8b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7723.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7723.c @@ -350,7 +350,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PTA GPIO */ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT), PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT), @@ -1143,7 +1143,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* SCIF0 */ GPIO_FN(SCIF0_PTT_TXD), GPIO_FN(SCIF0_PTT_RXD), @@ -1515,7 +1515,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(IDEA0), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) { PTA7_FN, PTA7_OUT, 0, PTA7_IN, PTA6_FN, PTA6_OUT, 0, PTA6_IN, @@ -1789,7 +1789,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xa4050120, 8) { PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } @@ -1885,7 +1885,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7723_pinmux_info = { +const struct sh_pfc_soc_info sh7723_pinmux_info = { .name = "sh7723_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7724.c b/drivers/pinctrl/sh-pfc/pfc-sh7724.c index 40f430be71a8..35e551609805 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7724.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7724.c @@ -572,7 +572,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PTA GPIO */ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT, PTA7_IN_PU), PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT, PTA6_IN_PU), @@ -1422,7 +1422,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* BSC */ GPIO_FN(D31), GPIO_FN(D30), @@ -1787,7 +1787,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(INTC_IRQ0), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) { PTA7_FN, PTA7_OUT, PTA7_IN_PU, PTA7_IN, PTA6_FN, PTA6_OUT, PTA6_IN_PU, PTA6_IN, @@ -2111,7 +2111,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xa4050120, 8) { PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } @@ -2207,7 +2207,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7724_pinmux_info = { +const struct sh_pfc_soc_info sh7724_pinmux_info = { .name = "sh7724_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index 99ea220269ff..2fd5b7d4cb94 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -592,7 +592,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ PINMUX_DATA(CLKOUT_MARK, FN_CLKOUT), @@ -1373,7 +1373,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CLKOUT), GPIO_FN(BS), GPIO_FN(CS0), GPIO_FN(EX_CS0), GPIO_FN(RD), GPIO_FN(WE0), GPIO_FN(WE1), GPIO_FN(SCL0), GPIO_FN(PENC0), GPIO_FN(USB_OVC0), @@ -1652,7 +1652,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SCL1), GPIO_FN(SCIF_CLK_C), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("GPSR0", 0xFFFC0004, 32, 1) { GP_0_31_FN, FN_IP2_2_0, GP_0_30_FN, FN_IP1_31_29, @@ -2421,7 +2421,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { /* GPIO 0 - 5*/ { PINMUX_DATA_REG("INDT0", 0xFFC4000C, 32) { GP_INDT(0) } }, { PINMUX_DATA_REG("INDT1", 0xFFC4100C, 32) { GP_INDT(1) } }, @@ -2438,7 +2438,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7734_pinmux_info = { +const struct sh_pfc_soc_info sh7734_pinmux_info = { .name = "sh7734_pfc", .unlock_reg = 0xFFFC0000, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index e81ab0ecea8c..e074230e6243 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -526,7 +526,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PTA GPIO */ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT), PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT), @@ -1374,7 +1374,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* PTA (mobule: LBSC, RGMII) */ GPIO_FN(BS), GPIO_FN(RDWR), @@ -1726,7 +1726,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(ON_DQ0), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xffec0000, 16, 2) { PTA7_FN, PTA7_OUT, PTA7_IN, PTA7_IN_PU, PTA6_FN, PTA6_OUT, PTA6_IN, PTA6_IN_PU, @@ -2156,7 +2156,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xffec0034, 8) { PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } @@ -2264,7 +2264,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7757_pinmux_info = { +const struct sh_pfc_soc_info sh7757_pinmux_info = { .name = "sh7757_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7785.c b/drivers/pinctrl/sh-pfc/pfc-sh7785.c index 6049f594d37e..c176b794f240 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7785.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7785.c @@ -355,7 +355,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PA GPIO */ PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU), @@ -849,7 +849,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* FN */ GPIO_FN(D63_AD31), GPIO_FN(D62_AD30), @@ -1018,7 +1018,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(IRQOUT), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xffe70000, 16, 2) { PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU, PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU, @@ -1218,7 +1218,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xffe70020, 8) { PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA, PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA } @@ -1286,7 +1286,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7785_pinmux_info = { +const struct sh_pfc_soc_info sh7785_pinmux_info = { .name = "sh7785_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7786.c b/drivers/pinctrl/sh-pfc/pfc-sh7786.c index 526e78482d5b..8ae0e32844e9 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7786.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7786.c @@ -191,7 +191,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t pinmux_data[] = { +static const pinmux_enum_t pinmux_data[] = { /* PA GPIO */ PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU), @@ -509,7 +509,7 @@ static struct sh_pfc_pin pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -static struct pinmux_func pinmux_func_gpios[] = { +static const struct pinmux_func pinmux_func_gpios[] = { /* FN */ GPIO_FN(CDE), GPIO_FN(ETH_MAGIC), @@ -649,7 +649,7 @@ static struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(FSE), }; -static struct pinmux_cfg_reg pinmux_config_regs[] = { +static const struct pinmux_cfg_reg pinmux_config_regs[] = { { PINMUX_CFG_REG("PACR", 0xffcc0000, 16, 2) { PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU, PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU, @@ -779,7 +779,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { {} }; -static struct pinmux_data_reg pinmux_data_regs[] = { +static const struct pinmux_data_reg pinmux_data_regs[] = { { PINMUX_DATA_REG("PADR", 0xffcc0020, 8) { PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA, PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA } @@ -819,7 +819,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info sh7786_pinmux_info = { +const struct sh_pfc_soc_info sh7786_pinmux_info = { .name = "sh7786_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-shx3.c b/drivers/pinctrl/sh-pfc/pfc-shx3.c index 93d60cd4c437..6594c8c48747 100644 --- a/drivers/pinctrl/sh-pfc/pfc-shx3.c +++ b/drivers/pinctrl/sh-pfc/pfc-shx3.c @@ -147,7 +147,7 @@ enum { PINMUX_MARK_END, }; -static pinmux_enum_t shx3_pinmux_data[] = { +static const pinmux_enum_t shx3_pinmux_data[] = { /* PA GPIO */ PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU), @@ -388,7 +388,7 @@ static struct sh_pfc_pin shx3_pinmux_pins[] = { #define PINMUX_FN_BASE ARRAY_SIZE(shx3_pinmux_pins) -static struct pinmux_func shx3_pinmux_func_gpios[] = { +static const struct pinmux_func shx3_pinmux_func_gpios[] = { /* FN */ GPIO_FN(D31), GPIO_FN(D30), @@ -454,7 +454,7 @@ static struct pinmux_func shx3_pinmux_func_gpios[] = { GPIO_FN(IRQOUT), }; -static struct pinmux_cfg_reg shx3_pinmux_config_regs[] = { +static const struct pinmux_cfg_reg shx3_pinmux_config_regs[] = { { PINMUX_CFG_REG("PABCR", 0xffc70000, 32, 2) { PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU, PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU, @@ -530,7 +530,7 @@ static struct pinmux_cfg_reg shx3_pinmux_config_regs[] = { { }, }; -static struct pinmux_data_reg shx3_pinmux_data_regs[] = { +static const struct pinmux_data_reg shx3_pinmux_data_regs[] = { { PINMUX_DATA_REG("PABDR", 0xffc70010, 32) { 0, 0, 0, 0, 0, 0, 0, 0, PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA, @@ -566,7 +566,7 @@ static struct pinmux_data_reg shx3_pinmux_data_regs[] = { { }, }; -struct sh_pfc_soc_info shx3_pinmux_info = { +const struct sh_pfc_soc_info shx3_pinmux_info = { .name = "shx3_pfc", .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 9978ad1818fd..b4960df6aa2d 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -141,7 +141,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, struct sh_pfc *pfc = pmx->pfc; int idx = sh_pfc_get_pin_index(pfc, offset); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - struct sh_pfc_pin *pin = &pfc->info->pins[idx]; + const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned int mark = pin->enum_id; unsigned long flags; int ret = -EINVAL; @@ -324,7 +324,8 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) number++, nr_pins++) { struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; - struct sh_pfc_pin *info = &pfc->info->pins[nr_pins]; + const struct sh_pfc_pin *info = + &pfc->info->pins[nr_pins]; pin->number = number; pin->name = info->name; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 19da3b7c57f1..b250dacaf8dd 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -84,8 +84,8 @@ struct pinmux_func { struct pinmux_cfg_reg { unsigned long reg, reg_width, field_width; - pinmux_enum_t *enum_ids; - unsigned long *var_field_width; + const pinmux_enum_t *enum_ids; + const unsigned long *var_field_width; }; #define PINMUX_CFG_REG(name, r, r_width, f_width) \ @@ -99,7 +99,7 @@ struct pinmux_cfg_reg { struct pinmux_data_reg { unsigned long reg, reg_width; - pinmux_enum_t *enum_ids; + const pinmux_enum_t *enum_ids; }; #define PINMUX_DATA_REG(name, r, r_width) \ @@ -121,14 +121,14 @@ struct pinmux_range { }; struct sh_pfc_soc_info { - char *name; + const char *name; struct pinmux_range input; struct pinmux_range input_pd; struct pinmux_range input_pu; struct pinmux_range output; struct pinmux_range function; - struct sh_pfc_pin *pins; + const struct sh_pfc_pin *pins; unsigned int nr_pins; const struct pinmux_range *ranges; unsigned int nr_ranges; @@ -137,16 +137,16 @@ struct sh_pfc_soc_info { const struct sh_pfc_function *functions; unsigned int nr_functions; - struct pinmux_func *func_gpios; + const struct pinmux_func *func_gpios; unsigned int nr_func_gpios; - struct pinmux_cfg_reg *cfg_regs; - struct pinmux_data_reg *data_regs; + const struct pinmux_cfg_reg *cfg_regs; + const struct pinmux_data_reg *data_regs; - pinmux_enum_t *gpio_data; + const pinmux_enum_t *gpio_data; unsigned int gpio_data_size; - struct pinmux_irq *gpio_irq; + const struct pinmux_irq *gpio_irq; unsigned int gpio_irq_size; unsigned long unlock_reg; -- cgit From b705c054255ae3264aa02d46347e9cfbcf26523a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 16:38:23 +0100 Subject: sh-pfc: Use proper error codes Return proper error codes instead of -1, and propagate the error codes. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 19 ++++++++++--------- drivers/pinctrl/sh-pfc/gpio.c | 13 ++++--------- drivers/pinctrl/sh-pfc/pinctrl.c | 24 +++++++++++------------- 3 files changed, 25 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 3a949465e88e..a04c497deccd 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -93,7 +93,7 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) offset += range->end - range->begin + 1; } - return -1; + return -EINVAL; } static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, @@ -233,7 +233,7 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id, k++; } - return -1; + return -EINVAL; } static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, @@ -255,7 +255,7 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, } pr_err("cannot locate data/mark enum_id for mark %d\n", mark); - return -1; + return -EINVAL; } int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) @@ -264,6 +264,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) pinmux_enum_t enum_id; const struct pinmux_range *range; int in_range, pos, field, value; + int ret; switch (pinmux_type) { @@ -288,7 +289,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) break; default: - return -1; + return -EINVAL; } pos = 0; @@ -297,8 +298,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) value = 0; while (1) { pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); - if (pos <= 0) - return -1; + if (pos < 0) + return pos; if (!enum_id) break; @@ -341,9 +342,9 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) if (!in_range) continue; - if (sh_pfc_get_config_reg(pfc, enum_id, &cr, - &field, &value) != 0) - return -1; + ret = sh_pfc_get_config_reg(pfc, enum_id, &cr, &field, &value); + if (ret < 0) + return ret; sh_pfc_write_config_reg(pfc, cr, field, value); } diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 480beae2ee67..e299f14bc50a 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -276,22 +276,17 @@ static int gpio_function_request(struct gpio_chip *gc, unsigned offset) struct sh_pfc *pfc = gpio_to_pfc(gc); unsigned int mark = pfc->info->func_gpios[offset].enum_id; unsigned long flags; - int ret = -EINVAL; + int ret; pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); if (mark == 0) - return ret; + return -EINVAL; spin_lock_irqsave(&pfc->lock, flags); - - if (sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION)) - goto done; - - ret = 0; - -done: + ret = sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION); spin_unlock_irqrestore(&pfc->lock, flags); + return ret; } diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index b4960df6aa2d..c15091096f65 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -114,18 +114,16 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; unsigned long flags; unsigned int i; - int ret = -EINVAL; + int ret = 0; spin_lock_irqsave(&pfc->lock, flags); for (i = 0; i < grp->nr_pins; ++i) { - if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION)) - goto done; + ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); + if (ret < 0) + break; } - ret = 0; - -done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; } @@ -144,7 +142,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned int mark = pin->enum_id; unsigned long flags; - int ret = -EINVAL; + int ret; spin_lock_irqsave(&pfc->lock, flags); @@ -156,17 +154,17 @@ static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, case PINMUX_TYPE_INPUT_PULLDOWN: break; default: - goto err; + ret = -EINVAL; + goto done; } - if (sh_pfc_config_mux(pfc, mark, new_type) != 0) - goto err; + ret = sh_pfc_config_mux(pfc, mark, new_type); + if (ret < 0) + goto done; cfg->type = new_type; - ret = 0; - -err: +done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; -- cgit From c58d9c1b26e3ab2933abc7d5444e945ddad44809 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 16:44:02 +0100 Subject: sh-pfc: Implement generic pinconf support The existing PFC pinconf implementation, tied to the PFC-specific pin types, isn't used by drivers or boards. Replace it with the generic pinconf types to implement bias (pull-up/down) setup. Other pin configuration options can be implemented later if needed. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/Kconfig | 1 + drivers/pinctrl/sh-pfc/pinctrl.c | 123 +++++++++++++++++++++++++++++---------- drivers/pinctrl/sh-pfc/sh_pfc.h | 16 +++++ 3 files changed, 110 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig index c3340f54d2ad..af16f8f6ab6c 100644 --- a/drivers/pinctrl/sh-pfc/Kconfig +++ b/drivers/pinctrl/sh-pfc/Kconfig @@ -10,6 +10,7 @@ config PINCTRL_SH_PFC select GPIO_SH_PFC if ARCH_REQUIRE_GPIOLIB select PINMUX select PINCONF + select GENERIC_PINCONF def_bool y help This enables pin control drivers for SH and SH Mobile platforms diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index c15091096f65..79fa170b4872 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -24,6 +24,8 @@ #include #include "core.h" +#include "../core.h" +#include "../pinconf.h" struct sh_pfc_pin_config { u32 type; @@ -230,57 +232,118 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { .gpio_set_direction = sh_pfc_gpio_set_direction, }; +/* Check whether the requested parameter is supported for a pin. */ +static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin, + enum pin_config_param param) +{ + int idx = sh_pfc_get_pin_index(pfc, _pin); + const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + return true; + + case PIN_CONFIG_BIAS_PULL_UP: + return pin->configs & SH_PFC_PIN_CFG_PULL_UP; + + case PIN_CONFIG_BIAS_PULL_DOWN: + return pin->configs & SH_PFC_PIN_CFG_PULL_DOWN; + + default: + return false; + } +} + static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, unsigned long *config) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - int idx = sh_pfc_get_pin_index(pfc, _pin); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned long flags; + unsigned int bias; + + if (!sh_pfc_pinconf_validate(pfc, _pin, param)) + return -ENOTSUPP; - *config = cfg->type; + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + if (!pfc->info->ops || !pfc->info->ops->get_bias) + return -ENOTSUPP; + + spin_lock_irqsave(&pfc->lock, flags); + bias = pfc->info->ops->get_bias(pfc, _pin); + spin_unlock_irqrestore(&pfc->lock, flags); + + if (bias != param) + return -EINVAL; + + *config = 0; + break; + + default: + return -ENOTSUPP; + } return 0; } -static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, +static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, unsigned long config) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + enum pin_config_param param = pinconf_to_config_param(config); + unsigned long flags; - /* Validate the new type */ - if (config >= PINMUX_FLAG_TYPE) - return -EINVAL; + if (!sh_pfc_pinconf_validate(pfc, _pin, param)) + return -ENOTSUPP; - return sh_pfc_reconfig_pin(pmx, pin, config); + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_DISABLE: + if (!pfc->info->ops || !pfc->info->ops->set_bias) + return -ENOTSUPP; + + spin_lock_irqsave(&pfc->lock, flags); + pfc->info->ops->set_bias(pfc, _pin, param); + spin_unlock_irqrestore(&pfc->lock, flags); + + break; + + default: + return -ENOTSUPP; + } + + return 0; } -static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin) +static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, + unsigned long config) { - const char *pinmux_type_str[] = { - [PINMUX_TYPE_NONE] = "none", - [PINMUX_TYPE_FUNCTION] = "function", - [PINMUX_TYPE_GPIO] = "gpio", - [PINMUX_TYPE_OUTPUT] = "output", - [PINMUX_TYPE_INPUT] = "input", - [PINMUX_TYPE_INPUT_PULLUP] = "input bias pull up", - [PINMUX_TYPE_INPUT_PULLDOWN] = "input bias pull down", - }; - unsigned long config; - int rc; - - rc = sh_pfc_pinconf_get(pctldev, pin, &config); - if (unlikely(rc != 0)) - return; - - seq_printf(s, " %s", pinmux_type_str[config]); + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + const unsigned int *pins; + unsigned int num_pins; + unsigned int i; + + pins = pmx->pfc->info->groups[group].pins; + num_pins = pmx->pfc->info->groups[group].nr_pins; + + for (i = 0; i < num_pins; ++i) + sh_pfc_pinconf_set(pctldev, pins[i], config); + + return 0; } static const struct pinconf_ops sh_pfc_pinconf_ops = { - .pin_config_get = sh_pfc_pinconf_get, - .pin_config_set = sh_pfc_pinconf_set, - .pin_config_dbg_show = sh_pfc_pinconf_dbg_show, + .is_generic = true, + .pin_config_get = sh_pfc_pinconf_get, + .pin_config_set = sh_pfc_pinconf_set, + .pin_config_group_set = sh_pfc_pinconf_group_set, + .pin_config_config_dbg_show = pinconf_generic_dump_config, }; /* PFC ranges -> pinctrl pin descs */ diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index b250dacaf8dd..3b785fc428d5 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -31,9 +31,15 @@ enum { PINMUX_FLAG_TYPE, /* must be last */ }; +#define SH_PFC_PIN_CFG_INPUT (1 << 0) +#define SH_PFC_PIN_CFG_OUTPUT (1 << 1) +#define SH_PFC_PIN_CFG_PULL_UP (1 << 2) +#define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3) + struct sh_pfc_pin { const pinmux_enum_t enum_id; const char *name; + unsigned int configs; }; #define SH_PFC_PIN_GROUP(n) \ @@ -120,8 +126,18 @@ struct pinmux_range { pinmux_enum_t force; }; +struct sh_pfc; + +struct sh_pfc_soc_operations { + unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin); + void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias); +}; + struct sh_pfc_soc_info { const char *name; + const struct sh_pfc_soc_operations *ops; + struct pinmux_range input; struct pinmux_range input_pd; struct pinmux_range input_pu; -- cgit From 0d00f00a1077ae89fb0ecbbba8da4c2c6bc93446 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 16:55:19 +0100 Subject: sh-pfc: Merge sh_pfc_reconfig_pin() into sh_pfc_gpio_set_direction() The sh_pfc_reconfig_pin() is only called from a single location. Merge it into its call site to make the code easier to follow. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 71 ++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 79fa170b4872..36f08f826a5e 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -135,43 +135,6 @@ static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, { } -static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, - int new_type) -{ - struct sh_pfc *pfc = pmx->pfc; - int idx = sh_pfc_get_pin_index(pfc, offset); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; - unsigned int mark = pin->enum_id; - unsigned long flags; - int ret; - - spin_lock_irqsave(&pfc->lock, flags); - - switch (cfg->type) { - case PINMUX_TYPE_GPIO: - case PINMUX_TYPE_OUTPUT: - case PINMUX_TYPE_INPUT: - case PINMUX_TYPE_INPUT_PULLUP: - case PINMUX_TYPE_INPUT_PULLDOWN: - break; - default: - ret = -EINVAL; - goto done; - } - - ret = sh_pfc_config_mux(pfc, mark, new_type); - if (ret < 0) - goto done; - - cfg->type = new_type; - -done: - spin_unlock_irqrestore(&pfc->lock, flags); - - return ret; -} - static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -216,9 +179,39 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned offset, bool input) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; + struct sh_pfc *pfc = pmx->pfc; + int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; + unsigned int mark = pin->enum_id; + unsigned long flags; + int ret; - return sh_pfc_reconfig_pin(pmx, offset, type); + spin_lock_irqsave(&pfc->lock, flags); + + switch (cfg->type) { + case PINMUX_TYPE_GPIO: + case PINMUX_TYPE_OUTPUT: + case PINMUX_TYPE_INPUT: + case PINMUX_TYPE_INPUT_PULLUP: + case PINMUX_TYPE_INPUT_PULLDOWN: + break; + default: + ret = -EINVAL; + goto done; + } + + ret = sh_pfc_config_mux(pfc, mark, new_type); + if (ret < 0) + goto done; + + cfg->type = new_type; + +done: + spin_unlock_irqrestore(&pfc->lock, flags); + + return ret; } static const struct pinmux_ops sh_pfc_pinmux_ops = { -- cgit From 9fddc4a589c6d1bd9c935d445b1a1d216b1457ab Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 17:25:29 +0100 Subject: sh-pfc: Clean up pin configuration type handling Set pin configuration type to - PINMUX_TYPE_NONE at initialization time and when disabling a function or freeing a GPIO - PINMUX_TYPE_FUNCTION when enabling a function - PINMUX_TYPE_INPUT or PINMUX_TYPE_OUTPUT when setting the GPIO direction Verify that the type is PINMUX_TYPE_NONE when enabling a function or requesting a GPIO and return -EBUSY if it isn't. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 74 +++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 36f08f826a5e..82e4fb21853e 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -120,12 +120,23 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, spin_lock_irqsave(&pfc->lock, flags); + for (i = 0; i < grp->nr_pins; ++i) { + int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + + if (cfg->type != PINMUX_TYPE_NONE) { + ret = -EBUSY; + goto done; + } + } + for (i = 0; i < grp->nr_pins; ++i) { ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) break; } +done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; } @@ -133,6 +144,22 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&pfc->lock, flags); + + for (i = 0; i < grp->nr_pins; ++i) { + int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + + cfg->type = PINMUX_TYPE_NONE; + } + + spin_unlock_irqrestore(&pfc->lock, flags); } static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, @@ -148,21 +175,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pfc->lock, flags); - switch (cfg->type) { - case PINMUX_TYPE_GPIO: - case PINMUX_TYPE_INPUT: - case PINMUX_TYPE_OUTPUT: - break; - case PINMUX_TYPE_FUNCTION: - default: - pr_err("Unsupported mux type (%d), bailing...\n", cfg->type); - ret = -ENOTSUPP; - goto err; + if (cfg->type != PINMUX_TYPE_NONE) { + pr_err("Pin %u is busy, can't configure it as GPIO.\n", offset); + ret = -EBUSY; + goto done; } + cfg->type = PINMUX_TYPE_GPIO; + ret = 0; -err: +done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; @@ -172,6 +195,15 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) { + struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); + struct sh_pfc *pfc = pmx->pfc; + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + unsigned long flags; + + spin_lock_irqsave(&pfc->lock, flags); + cfg->type = PINMUX_TYPE_NONE; + spin_unlock_irqrestore(&pfc->lock, flags); } static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, @@ -182,27 +214,14 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, struct sh_pfc *pfc = pmx->pfc; int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; int idx = sh_pfc_get_pin_index(pfc, offset); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; - unsigned int mark = pin->enum_id; + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; unsigned long flags; int ret; spin_lock_irqsave(&pfc->lock, flags); - switch (cfg->type) { - case PINMUX_TYPE_GPIO: - case PINMUX_TYPE_OUTPUT: - case PINMUX_TYPE_INPUT: - case PINMUX_TYPE_INPUT_PULLUP: - case PINMUX_TYPE_INPUT_PULLDOWN: - break; - default: - ret = -EINVAL; - goto done; - } - - ret = sh_pfc_config_mux(pfc, mark, new_type); + ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type); if (ret < 0) goto done; @@ -210,7 +229,6 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, done: spin_unlock_irqrestore(&pfc->lock, flags); - return ret; } @@ -383,7 +401,7 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) pin->number = number; pin->name = info->name; - cfg->type = PINMUX_TYPE_GPIO; + cfg->type = PINMUX_TYPE_NONE; } } -- cgit From 9a643c9a11259955ec6961f9a2509604c6df1cd9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 10 Mar 2013 18:00:02 +0100 Subject: sh-pfc: Convert message printing from pr_* to dev_* Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/core.c | 14 +++++++------- drivers/pinctrl/sh-pfc/gpio.c | 16 ++++++++++------ drivers/pinctrl/sh-pfc/pinctrl.c | 5 +++-- 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index a04c497deccd..feef89792568 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -10,7 +10,6 @@ */ #define DRV_NAME "sh-pfc" -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -173,9 +172,9 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos); - pr_debug("write_reg addr = %lx, value = %ld, field = %ld, " - "r_width = %ld, f_width = %ld\n", - crp->reg, value, field, crp->reg_width, crp->field_width); + dev_dbg(pfc->dev, "write_reg addr = %lx, value = %ld, field = %ld, " + "r_width = %ld, f_width = %ld\n", + crp->reg, value, field, crp->reg_width, crp->field_width); mask = ~(mask << pos); value = value << pos; @@ -254,7 +253,8 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos, } } - pr_err("cannot locate data/mark enum_id for mark %d\n", mark); + dev_err(pfc->dev, "cannot locate data/mark enum_id for mark %d\n", + mark); return -EINVAL; } @@ -396,13 +396,13 @@ static int sh_pfc_probe(struct platform_device *pdev) * PFC state as it is, given that there are already * extant users of it that have succeeded by this point. */ - pr_notice("failed to init GPIO chip, ignoring...\n"); + dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n"); } #endif platform_set_drvdata(pdev, pfc); - pr_info("%s support registered\n", info->name); + dev_info(pfc->dev, "%s support registered\n", info->name); return 0; } diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index e299f14bc50a..d7acb06d888c 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -9,8 +9,6 @@ * for more details. */ -#define pr_fmt(fmt) KBUILD_MODNAME " gpio: " fmt - #include #include #include @@ -273,12 +271,18 @@ static int gpio_pin_setup(struct sh_pfc_chip *chip) static int gpio_function_request(struct gpio_chip *gc, unsigned offset) { + static bool __print_once; struct sh_pfc *pfc = gpio_to_pfc(gc); unsigned int mark = pfc->info->func_gpios[offset].enum_id; unsigned long flags; int ret; - pr_notice_once("Use of GPIO API for function requests is deprecated, convert to pinctrl\n"); + if (!__print_once) { + dev_notice(pfc->dev, + "Use of GPIO API for function requests is deprecated." + " Convert to pinctrl\n"); + __print_once = true; + } if (mark == 0) return -EINVAL; @@ -334,9 +338,9 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *)) if (unlikely(ret < 0)) return ERR_PTR(ret); - pr_info("%s handling gpio %u -> %u\n", - chip->gpio_chip.label, chip->gpio_chip.base, - chip->gpio_chip.base + chip->gpio_chip.ngpio - 1); + dev_info(pfc->dev, "%s handling gpio %u -> %u\n", + chip->gpio_chip.label, chip->gpio_chip.base, + chip->gpio_chip.base + chip->gpio_chip.ngpio - 1); return chip; } diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 82e4fb21853e..52179bbcf6b4 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -9,7 +9,6 @@ */ #define DRV_NAME "sh-pfc" -#define pr_fmt(fmt) KBUILD_MODNAME " pinctrl: " fmt #include #include @@ -176,7 +175,9 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pfc->lock, flags); if (cfg->type != PINMUX_TYPE_NONE) { - pr_err("Pin %u is busy, can't configure it as GPIO.\n", offset); + dev_err(pfc->dev, + "Pin %u is busy, can't configure it as GPIO.\n", + offset); ret = -EBUSY; goto done; } -- cgit From 6dc9b4550a74cad7daed0be192030983dad44755 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:18:30 +0100 Subject: sh-pfc: Return an error if a pin doesn't support the requested direction When setting a pin direction verify that the requested direction is supported, and return an error if it isn't. This requires pin configuration information to be supplied by SoC data. The check is a no-op if the information is not supplied. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pinctrl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 52179bbcf6b4..aef268bc17ba 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -218,8 +218,18 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; unsigned long flags; + unsigned int dir; int ret; + /* Check if the requested direction is supported by the pin. Not all SoC + * provide pin config data, so perform the check conditionally. + */ + if (pin->configs) { + dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT; + if (!(pin->configs & dir)) + return -EINVAL; + } + spin_lock_irqsave(&pfc->lock, flags); ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type); -- cgit From 55f11f0ec1bad183440ab4717f6e1a142c062613 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 23 Jan 2013 17:37:45 +0100 Subject: sh-pfc: sh7372: Add SDHCI and MMCIF pin groups and functions Add pin groups for all three SDHI interfaces and two alternative pin groups for the MMCIF interface on the sh7372 SoC. Signed-off-by: Guennadi Liakhovetski Acked-by: Linus Walleij Signed-off-by: Laurent Pinchart --- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 206 ++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index 6b5634454956..cef4d6a598dd 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -933,6 +933,207 @@ static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; +/* - MMCIF ------------------------------------------------------------------ */ +static const unsigned int mmc0_data1_0_pins[] = { + /* D[0] */ + 84, +}; +static const unsigned int mmc0_data1_0_mux[] = { + MMCD0_0_MARK, +}; +static const unsigned int mmc0_data4_0_pins[] = { + /* D[0:3] */ + 84, 85, 86, 87, +}; +static const unsigned int mmc0_data4_0_mux[] = { + MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK, +}; +static const unsigned int mmc0_data8_0_pins[] = { + /* D[0:7] */ + 84, 85, 86, 87, 88, 89, 90, 91, +}; +static const unsigned int mmc0_data8_0_mux[] = { + MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK, + MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK, +}; +static const unsigned int mmc0_ctrl_0_pins[] = { + /* CMD, CLK */ + 92, 99, +}; +static const unsigned int mmc0_ctrl_0_mux[] = { + MMCCMD0_MARK, MMCCLK0_MARK, +}; + +static const unsigned int mmc0_data1_1_pins[] = { + /* D[0] */ + 54, +}; +static const unsigned int mmc0_data1_1_mux[] = { + MMCD1_0_MARK, +}; +static const unsigned int mmc0_data4_1_pins[] = { + /* D[0:3] */ + 54, 55, 56, 57, +}; +static const unsigned int mmc0_data4_1_mux[] = { + MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK, +}; +static const unsigned int mmc0_data8_1_pins[] = { + /* D[0:7] */ + 54, 55, 56, 57, 58, 59, 60, 61, +}; +static const unsigned int mmc0_data8_1_mux[] = { + MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK, + MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK, +}; +static const unsigned int mmc0_ctrl_1_pins[] = { + /* CMD, CLK */ + 67, 66, +}; +static const unsigned int mmc0_ctrl_1_mux[] = { + MMCCMD1_MARK, MMCCLK1_MARK, +}; +/* - SDHI0 ------------------------------------------------------------------ */ +static const unsigned int sdhi0_data1_pins[] = { + /* D0 */ + 173, +}; +static const unsigned int sdhi0_data1_mux[] = { + SDHID0_0_MARK, +}; +static const unsigned int sdhi0_data4_pins[] = { + /* D[0:3] */ + 173, 174, 175, 176, +}; +static const unsigned int sdhi0_data4_mux[] = { + SDHID0_0_MARK, SDHID0_1_MARK, SDHID0_2_MARK, SDHID0_3_MARK, +}; +static const unsigned int sdhi0_ctrl_pins[] = { + /* CMD, CLK */ + 177, 171, +}; +static const unsigned int sdhi0_ctrl_mux[] = { + SDHICMD0_MARK, SDHICLK0_MARK, +}; +static const unsigned int sdhi0_cd_pins[] = { + /* CD */ + 172, +}; +static const unsigned int sdhi0_cd_mux[] = { + SDHICD0_MARK, +}; +static const unsigned int sdhi0_wp_pins[] = { + /* WP */ + 178, +}; +static const unsigned int sdhi0_wp_mux[] = { + SDHIWP0_MARK, +}; +/* - SDHI1 ------------------------------------------------------------------ */ +static const unsigned int sdhi1_data1_pins[] = { + /* D0 */ + 180, +}; +static const unsigned int sdhi1_data1_mux[] = { + SDHID1_0_MARK, +}; +static const unsigned int sdhi1_data4_pins[] = { + /* D[0:3] */ + 180, 181, 182, 183, +}; +static const unsigned int sdhi1_data4_mux[] = { + SDHID1_0_MARK, SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK, +}; +static const unsigned int sdhi1_ctrl_pins[] = { + /* CMD, CLK */ + 184, 179, +}; +static const unsigned int sdhi1_ctrl_mux[] = { + SDHICMD1_MARK, SDHICLK1_MARK, +}; + +static const unsigned int sdhi2_data1_pins[] = { + /* D0 */ + 186, +}; +static const unsigned int sdhi2_data1_mux[] = { + SDHID2_0_MARK, +}; +static const unsigned int sdhi2_data4_pins[] = { + /* D[0:3] */ + 186, 187, 188, 189, +}; +static const unsigned int sdhi2_data4_mux[] = { + SDHID2_0_MARK, SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK, +}; +static const unsigned int sdhi2_ctrl_pins[] = { + /* CMD, CLK */ + 190, 185, +}; +static const unsigned int sdhi2_ctrl_mux[] = { + SDHICMD2_MARK, SDHICLK2_MARK, +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(mmc0_data1_0), + SH_PFC_PIN_GROUP(mmc0_data4_0), + SH_PFC_PIN_GROUP(mmc0_data8_0), + SH_PFC_PIN_GROUP(mmc0_ctrl_0), + SH_PFC_PIN_GROUP(mmc0_data1_1), + SH_PFC_PIN_GROUP(mmc0_data4_1), + SH_PFC_PIN_GROUP(mmc0_data8_1), + SH_PFC_PIN_GROUP(mmc0_ctrl_1), + SH_PFC_PIN_GROUP(sdhi0_data1), + SH_PFC_PIN_GROUP(sdhi0_data4), + SH_PFC_PIN_GROUP(sdhi0_ctrl), + SH_PFC_PIN_GROUP(sdhi0_cd), + SH_PFC_PIN_GROUP(sdhi0_wp), + SH_PFC_PIN_GROUP(sdhi1_data1), + SH_PFC_PIN_GROUP(sdhi1_data4), + SH_PFC_PIN_GROUP(sdhi1_ctrl), + SH_PFC_PIN_GROUP(sdhi2_data1), + SH_PFC_PIN_GROUP(sdhi2_data4), + SH_PFC_PIN_GROUP(sdhi2_ctrl), +}; + +static const char * const mmc0_groups[] = { + "mmc0_data1_0", + "mmc0_data4_0", + "mmc0_data8_0", + "mmc0_ctrl_0", + "mmc0_data1_1", + "mmc0_data4_1", + "mmc0_data8_1", + "mmc0_ctrl_1", +}; + +static const char * const sdhi0_groups[] = { + "sdhi0_data1", + "sdhi0_data4", + "sdhi0_ctrl", + "sdhi0_cd", + "sdhi0_wp", +}; + +static const char * const sdhi1_groups[] = { + "sdhi1_data1", + "sdhi1_data4", + "sdhi1_ctrl", +}; + +static const char * const sdhi2_groups[] = { + "sdhi2_data1", + "sdhi2_data4", + "sdhi2_ctrl", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(mmc0), + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), +}; + #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) static const struct pinmux_func pinmux_func_gpios[] = { @@ -1644,6 +1845,11 @@ const struct sh_pfc_soc_info sh7372_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + .func_gpios = pinmux_func_gpios, .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), -- cgit From b8238993ed2ba222a456bcdf53370ff7fe1fe501 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 01:31:23 +0100 Subject: sh-pfc: sh73a0: Add bias (pull-up/down) pinconf support Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 351 +++++++++++++++++++++++++++++++++++- 1 file changed, 350 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 3200fc2f34b1..f31adfc687fa 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -18,10 +18,14 @@ * 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 "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ @@ -1539,8 +1543,300 @@ static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU), }; +#define SH73A0_PIN(pin, cfgs) \ + { \ + .name = __stringify(PORT##pin), \ + .enum_id = PORT##pin##_DATA, \ + .configs = cfgs, \ + } + +#define __I (SH_PFC_PIN_CFG_INPUT) +#define __O (SH_PFC_PIN_CFG_OUTPUT) +#define __IO (SH_PFC_PIN_CFG_INPUT | SH_PFC_PIN_CFG_OUTPUT) +#define __PD (SH_PFC_PIN_CFG_PULL_DOWN) +#define __PU (SH_PFC_PIN_CFG_PULL_UP) +#define __PUD (SH_PFC_PIN_CFG_PULL_DOWN | SH_PFC_PIN_CFG_PULL_UP) + +#define SH73A0_PIN_I_PD(pin) SH73A0_PIN(pin, __I | __PD) +#define SH73A0_PIN_I_PU(pin) SH73A0_PIN(pin, __I | __PU) +#define SH73A0_PIN_I_PU_PD(pin) SH73A0_PIN(pin, __I | __PUD) +#define SH73A0_PIN_IO(pin) SH73A0_PIN(pin, __IO) +#define SH73A0_PIN_IO_PD(pin) SH73A0_PIN(pin, __IO | __PD) +#define SH73A0_PIN_IO_PU(pin) SH73A0_PIN(pin, __IO | __PU) +#define SH73A0_PIN_IO_PU_PD(pin) SH73A0_PIN(pin, __IO | __PUD) +#define SH73A0_PIN_O(pin) SH73A0_PIN(pin, __O) + static struct sh_pfc_pin pinmux_pins[] = { - GPIO_PORT_ALL(), + /* Table 25-1 (I/O and Pull U/D) */ + SH73A0_PIN_I_PD(0), + SH73A0_PIN_I_PU(1), + SH73A0_PIN_I_PU(2), + SH73A0_PIN_I_PU(3), + SH73A0_PIN_I_PU(4), + SH73A0_PIN_I_PU(5), + SH73A0_PIN_I_PU(6), + SH73A0_PIN_I_PU(7), + SH73A0_PIN_I_PU(8), + SH73A0_PIN_I_PD(9), + SH73A0_PIN_I_PD(10), + SH73A0_PIN_I_PU_PD(11), + SH73A0_PIN_IO_PU_PD(12), + SH73A0_PIN_IO_PU_PD(13), + SH73A0_PIN_IO_PU_PD(14), + SH73A0_PIN_IO_PU_PD(15), + SH73A0_PIN_IO_PD(16), + SH73A0_PIN_IO_PD(17), + SH73A0_PIN_IO_PU(18), + SH73A0_PIN_IO_PU(19), + SH73A0_PIN_O(20), + SH73A0_PIN_O(21), + SH73A0_PIN_O(22), + SH73A0_PIN_O(23), + SH73A0_PIN_O(24), + SH73A0_PIN_I_PD(25), + SH73A0_PIN_I_PD(26), + SH73A0_PIN_IO_PU(27), + SH73A0_PIN_IO_PU(28), + SH73A0_PIN_IO_PD(29), + SH73A0_PIN_IO_PD(30), + SH73A0_PIN_IO_PU(31), + SH73A0_PIN_IO_PD(32), + SH73A0_PIN_I_PU_PD(33), + SH73A0_PIN_IO_PD(34), + SH73A0_PIN_I_PU_PD(35), + SH73A0_PIN_IO_PD(36), + SH73A0_PIN_IO(37), + SH73A0_PIN_O(38), + SH73A0_PIN_I_PU(39), + SH73A0_PIN_I_PU_PD(40), + SH73A0_PIN_O(41), + SH73A0_PIN_IO_PD(42), + SH73A0_PIN_IO_PU_PD(43), + SH73A0_PIN_IO_PU_PD(44), + SH73A0_PIN_IO_PD(45), + SH73A0_PIN_IO_PD(46), + SH73A0_PIN_IO_PD(47), + SH73A0_PIN_I_PD(48), + SH73A0_PIN_IO_PU_PD(49), + SH73A0_PIN_IO_PD(50), + SH73A0_PIN_IO_PD(51), + SH73A0_PIN_O(52), + SH73A0_PIN_IO_PU_PD(53), + SH73A0_PIN_IO_PU_PD(54), + SH73A0_PIN_IO_PD(55), + SH73A0_PIN_I_PU_PD(56), + SH73A0_PIN_IO(57), + SH73A0_PIN_IO(58), + SH73A0_PIN_IO(59), + SH73A0_PIN_IO(60), + SH73A0_PIN_IO(61), + SH73A0_PIN_IO_PD(62), + SH73A0_PIN_IO_PD(63), + SH73A0_PIN_IO_PU_PD(64), + SH73A0_PIN_IO_PD(65), + SH73A0_PIN_IO_PU_PD(66), + SH73A0_PIN_IO_PU_PD(67), + SH73A0_PIN_IO_PU_PD(68), + SH73A0_PIN_IO_PU_PD(69), + SH73A0_PIN_IO_PU_PD(70), + SH73A0_PIN_IO_PU_PD(71), + SH73A0_PIN_IO_PU_PD(72), + SH73A0_PIN_I_PU_PD(73), + SH73A0_PIN_IO_PU(74), + SH73A0_PIN_IO_PU(75), + SH73A0_PIN_IO_PU(76), + SH73A0_PIN_IO_PU(77), + SH73A0_PIN_IO_PU(78), + SH73A0_PIN_IO_PU(79), + SH73A0_PIN_IO_PU(80), + SH73A0_PIN_IO_PU(81), + SH73A0_PIN_IO_PU(82), + SH73A0_PIN_IO_PU(83), + SH73A0_PIN_IO_PU(84), + SH73A0_PIN_IO_PU(85), + SH73A0_PIN_IO_PU(86), + SH73A0_PIN_IO_PU(87), + SH73A0_PIN_IO_PU(88), + SH73A0_PIN_IO_PU(89), + SH73A0_PIN_O(90), + SH73A0_PIN_IO_PU(91), + SH73A0_PIN_O(92), + SH73A0_PIN_IO_PU(93), + SH73A0_PIN_O(94), + SH73A0_PIN_I_PU_PD(95), + SH73A0_PIN_IO(96), + SH73A0_PIN_IO(97), + SH73A0_PIN_IO(98), + SH73A0_PIN_I_PU(99), + SH73A0_PIN_O(100), + SH73A0_PIN_O(101), + SH73A0_PIN_I_PU(102), + SH73A0_PIN_IO_PD(103), + SH73A0_PIN_I_PU_PD(104), + SH73A0_PIN_I_PD(105), + SH73A0_PIN_I_PD(106), + SH73A0_PIN_I_PU_PD(107), + SH73A0_PIN_I_PU_PD(108), + SH73A0_PIN_IO_PD(109), + SH73A0_PIN_IO_PD(110), + SH73A0_PIN_IO_PU_PD(111), + SH73A0_PIN_IO_PU_PD(112), + SH73A0_PIN_IO_PU_PD(113), + SH73A0_PIN_IO_PD(114), + SH73A0_PIN_IO_PU(115), + SH73A0_PIN_IO_PU(116), + SH73A0_PIN_IO_PU_PD(117), + SH73A0_PIN_IO_PU_PD(118), + SH73A0_PIN_IO_PD(128), + SH73A0_PIN_IO_PD(129), + SH73A0_PIN_IO_PU_PD(130), + SH73A0_PIN_IO_PD(131), + SH73A0_PIN_IO_PD(132), + SH73A0_PIN_IO_PD(133), + SH73A0_PIN_IO_PU_PD(134), + SH73A0_PIN_IO_PU_PD(135), + SH73A0_PIN_IO_PU_PD(136), + SH73A0_PIN_IO_PU_PD(137), + SH73A0_PIN_IO_PD(138), + SH73A0_PIN_IO_PD(139), + SH73A0_PIN_IO_PD(140), + SH73A0_PIN_IO_PD(141), + SH73A0_PIN_IO_PD(142), + SH73A0_PIN_IO_PD(143), + SH73A0_PIN_IO_PU_PD(144), + SH73A0_PIN_IO_PD(145), + SH73A0_PIN_IO_PU_PD(146), + SH73A0_PIN_IO_PU_PD(147), + SH73A0_PIN_IO_PU_PD(148), + SH73A0_PIN_IO_PU_PD(149), + SH73A0_PIN_I_PU_PD(150), + SH73A0_PIN_IO_PU_PD(151), + SH73A0_PIN_IO_PU_PD(152), + SH73A0_PIN_IO_PD(153), + SH73A0_PIN_IO_PD(154), + SH73A0_PIN_I_PU_PD(155), + SH73A0_PIN_IO_PU_PD(156), + SH73A0_PIN_I_PD(157), + SH73A0_PIN_IO_PD(158), + SH73A0_PIN_IO_PU_PD(159), + SH73A0_PIN_IO_PU_PD(160), + SH73A0_PIN_I_PU_PD(161), + SH73A0_PIN_I_PU_PD(162), + SH73A0_PIN_IO_PU_PD(163), + SH73A0_PIN_I_PU_PD(164), + SH73A0_PIN_IO_PD(192), + SH73A0_PIN_IO_PU_PD(193), + SH73A0_PIN_IO_PD(194), + SH73A0_PIN_IO_PU_PD(195), + SH73A0_PIN_IO_PD(196), + SH73A0_PIN_IO_PD(197), + SH73A0_PIN_IO_PD(198), + SH73A0_PIN_IO_PD(199), + SH73A0_PIN_IO_PU_PD(200), + SH73A0_PIN_IO_PU_PD(201), + SH73A0_PIN_IO_PU_PD(202), + SH73A0_PIN_IO_PU_PD(203), + SH73A0_PIN_IO_PU_PD(204), + SH73A0_PIN_IO_PU_PD(205), + SH73A0_PIN_IO_PU_PD(206), + SH73A0_PIN_IO_PD(207), + SH73A0_PIN_IO_PD(208), + SH73A0_PIN_IO_PD(209), + SH73A0_PIN_IO_PD(210), + SH73A0_PIN_IO_PD(211), + SH73A0_PIN_IO_PD(212), + SH73A0_PIN_IO_PD(213), + SH73A0_PIN_IO_PU_PD(214), + SH73A0_PIN_IO_PU_PD(215), + SH73A0_PIN_IO_PD(216), + SH73A0_PIN_IO_PD(217), + SH73A0_PIN_O(218), + SH73A0_PIN_IO_PD(219), + SH73A0_PIN_IO_PD(220), + SH73A0_PIN_IO_PU_PD(221), + SH73A0_PIN_IO_PU_PD(222), + SH73A0_PIN_I_PU_PD(223), + SH73A0_PIN_I_PU_PD(224), + SH73A0_PIN_IO_PU_PD(225), + SH73A0_PIN_O(226), + SH73A0_PIN_IO_PU_PD(227), + SH73A0_PIN_I_PU_PD(228), + SH73A0_PIN_I_PD(229), + SH73A0_PIN_IO(230), + SH73A0_PIN_IO_PU_PD(231), + SH73A0_PIN_IO_PU_PD(232), + SH73A0_PIN_I_PU_PD(233), + SH73A0_PIN_IO_PU_PD(234), + SH73A0_PIN_IO_PU_PD(235), + SH73A0_PIN_IO_PU_PD(236), + SH73A0_PIN_IO_PD(237), + SH73A0_PIN_IO_PU_PD(238), + SH73A0_PIN_IO_PU_PD(239), + SH73A0_PIN_IO_PU_PD(240), + SH73A0_PIN_O(241), + SH73A0_PIN_I_PD(242), + SH73A0_PIN_IO_PU_PD(243), + SH73A0_PIN_IO_PU_PD(244), + SH73A0_PIN_IO_PU_PD(245), + SH73A0_PIN_IO_PU_PD(246), + SH73A0_PIN_IO_PU_PD(247), + SH73A0_PIN_IO_PU_PD(248), + SH73A0_PIN_IO_PU_PD(249), + SH73A0_PIN_IO_PU_PD(250), + SH73A0_PIN_IO_PU_PD(251), + SH73A0_PIN_IO_PU_PD(252), + SH73A0_PIN_IO_PU_PD(253), + SH73A0_PIN_IO_PU_PD(254), + SH73A0_PIN_IO_PU_PD(255), + SH73A0_PIN_IO_PU_PD(256), + SH73A0_PIN_IO_PU_PD(257), + SH73A0_PIN_IO_PU_PD(258), + SH73A0_PIN_IO_PU_PD(259), + SH73A0_PIN_IO_PU_PD(260), + SH73A0_PIN_IO_PU_PD(261), + SH73A0_PIN_IO_PU_PD(262), + SH73A0_PIN_IO_PU_PD(263), + SH73A0_PIN_IO_PU_PD(264), + SH73A0_PIN_IO_PU_PD(265), + SH73A0_PIN_IO_PU_PD(266), + SH73A0_PIN_IO_PU_PD(267), + SH73A0_PIN_IO_PU_PD(268), + SH73A0_PIN_IO_PU_PD(269), + SH73A0_PIN_IO_PU_PD(270), + SH73A0_PIN_IO_PU_PD(271), + SH73A0_PIN_IO_PU_PD(272), + SH73A0_PIN_IO_PU_PD(273), + SH73A0_PIN_IO_PU_PD(274), + SH73A0_PIN_IO_PU_PD(275), + SH73A0_PIN_IO_PU_PD(276), + SH73A0_PIN_IO_PU_PD(277), + SH73A0_PIN_IO_PU_PD(278), + SH73A0_PIN_IO_PU_PD(279), + SH73A0_PIN_IO_PU_PD(280), + SH73A0_PIN_O(281), + SH73A0_PIN_O(282), + SH73A0_PIN_I_PU(288), + SH73A0_PIN_IO_PU_PD(289), + SH73A0_PIN_IO_PU_PD(290), + SH73A0_PIN_IO_PU_PD(291), + SH73A0_PIN_IO_PU_PD(292), + SH73A0_PIN_IO_PU_PD(293), + SH73A0_PIN_IO_PU_PD(294), + SH73A0_PIN_IO_PU_PD(295), + SH73A0_PIN_IO_PU_PD(296), + SH73A0_PIN_IO_PU_PD(297), + SH73A0_PIN_IO_PU_PD(298), + SH73A0_PIN_IO_PU_PD(299), + SH73A0_PIN_IO_PU_PD(300), + SH73A0_PIN_IO_PU_PD(301), + SH73A0_PIN_IO_PU_PD(302), + SH73A0_PIN_IO_PU_PD(303), + SH73A0_PIN_IO_PU_PD(304), + SH73A0_PIN_IO_PU_PD(305), + SH73A0_PIN_O(306), + SH73A0_PIN_O(307), + SH73A0_PIN_I_PU(308), + SH73A0_PIN_O(309), }; static const struct pinmux_range pinmux_ranges[] = { @@ -2779,8 +3075,61 @@ static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16L(9), 308), }; +#define PORTnCR_PULMD_OFF (0 << 6) +#define PORTnCR_PULMD_DOWN (2 << 6) +#define PORTnCR_PULMD_UP (3 << 6) +#define PORTnCR_PULMD_MASK (3 << 6) + +static const unsigned int sh73a0_portcr_offsets[] = { + 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, + 0x00002000, 0x00002000, 0x00003000, 0x00003000, 0x00002000, +}; + +static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) +{ + void __iomem *addr = pfc->window->virt + + sh73a0_portcr_offsets[pin >> 5] + pin; + u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; + + switch (value) { + case PORTnCR_PULMD_UP: + return PIN_CONFIG_BIAS_PULL_UP; + case PORTnCR_PULMD_DOWN: + return PIN_CONFIG_BIAS_PULL_DOWN; + case PORTnCR_PULMD_OFF: + default: + return PIN_CONFIG_BIAS_DISABLE; + } +} + +static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias) +{ + void __iomem *addr = pfc->window->virt + + sh73a0_portcr_offsets[pin >> 5] + pin; + u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; + + switch (bias) { + case PIN_CONFIG_BIAS_PULL_UP: + value |= PORTnCR_PULMD_UP; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + value |= PORTnCR_PULMD_DOWN; + break; + } + + iowrite8(value, addr); +} + +static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = { + .get_bias = sh73a0_pinmux_get_bias, + .set_bias = sh73a0_pinmux_set_bias, +}; + const struct sh_pfc_soc_info sh73a0_pinmux_info = { .name = "sh73a0_pfc", + .ops = &sh73a0_pinmux_ops, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, -- cgit From df68a28d1765d9409262136b1fb098f44aa32642 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Add LCD and LCD2 pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 254 ++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index f31adfc687fa..c8b2604eb8f6 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1846,6 +1846,255 @@ static const struct pinmux_range pinmux_ranges[] = { {.begin = 288, .end = 309,}, }; +/* - LCD -------------------------------------------------------------------- */ +static const unsigned int lcd_data8_pins[] = { + /* D[0:7] */ + 192, 193, 194, 195, 196, 197, 198, 199, +}; +static const unsigned int lcd_data8_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, +}; +static const unsigned int lcd_data9_pins[] = { + /* D[0:8] */ + 192, 193, 194, 195, 196, 197, 198, 199, + 200, +}; +static const unsigned int lcd_data9_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, + LCDD8_MARK, +}; +static const unsigned int lcd_data12_pins[] = { + /* D[0:11] */ + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, +}; +static const unsigned int lcd_data12_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, + LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK, +}; +static const unsigned int lcd_data16_pins[] = { + /* D[0:15] */ + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, +}; +static const unsigned int lcd_data16_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, + LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK, + LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK, +}; +static const unsigned int lcd_data18_pins[] = { + /* D[0:17] */ + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, +}; +static const unsigned int lcd_data18_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, + LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK, + LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK, + LCDD16_MARK, LCDD17_MARK, +}; +static const unsigned int lcd_data24_pins[] = { + /* D[0:23] */ + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215 +}; +static const unsigned int lcd_data24_mux[] = { + LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK, + LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK, + LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK, + LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK, + LCDD16_MARK, LCDD17_MARK, LCDD18_MARK, LCDD19_MARK, + LCDD20_MARK, LCDD21_MARK, LCDD22_MARK, LCDD23_MARK, +}; +static const unsigned int lcd_display_pins[] = { + /* DON */ + 222, +}; +static const unsigned int lcd_display_mux[] = { + LCDDON_MARK, +}; +static const unsigned int lcd_lclk_pins[] = { + /* LCLK */ + 221, +}; +static const unsigned int lcd_lclk_mux[] = { + LCDLCLK_MARK, +}; +static const unsigned int lcd_sync_pins[] = { + /* VSYN, HSYN, DCK, DISP */ + 220, 218, 216, 219, +}; +static const unsigned int lcd_sync_mux[] = { + LCDVSYN_MARK, LCDHSYN_MARK, LCDDCK_MARK, LCDDISP_MARK, +}; +static const unsigned int lcd_sys_pins[] = { + /* CS, WR, RD, RS */ + 218, 216, 217, 219, +}; +static const unsigned int lcd_sys_mux[] = { + LCDCS__MARK, LCDWR__MARK, LCDRD__MARK, LCDRS_MARK, +}; +/* - LCD2 ------------------------------------------------------------------- */ +static const unsigned int lcd2_data8_pins[] = { + /* D[0:7] */ + 128, 129, 142, 143, 144, 145, 138, 139, +}; +static const unsigned int lcd2_data8_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, +}; +static const unsigned int lcd2_data9_pins[] = { + /* D[0:8] */ + 128, 129, 142, 143, 144, 145, 138, 139, + 140, +}; +static const unsigned int lcd2_data9_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, + LCD2D8_MARK, +}; +static const unsigned int lcd2_data12_pins[] = { + /* D[0:12] */ + 128, 129, 142, 143, 144, 145, 138, 139, + 140, 141, 130, 131, +}; +static const unsigned int lcd2_data12_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, + LCD2D8_MARK, LCD2D9_MARK, LCD2D10_MARK, LCD2D11_MARK, +}; +static const unsigned int lcd2_data16_pins[] = { + /* D[0:15] */ + 128, 129, 142, 143, 144, 145, 138, 139, + 140, 141, 130, 131, 132, 133, 134, 135, +}; +static const unsigned int lcd2_data16_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, + LCD2D8_MARK, LCD2D9_MARK, LCD2D10_MARK, LCD2D11_MARK, + LCD2D12_MARK, LCD2D13_MARK, LCD2D14_MARK, LCD2D15_MARK, +}; +static const unsigned int lcd2_data18_pins[] = { + /* D[0:17] */ + 128, 129, 142, 143, 144, 145, 138, 139, + 140, 141, 130, 131, 132, 133, 134, 135, + 136, 137, +}; +static const unsigned int lcd2_data18_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, + LCD2D8_MARK, LCD2D9_MARK, LCD2D10_MARK, LCD2D11_MARK, + LCD2D12_MARK, LCD2D13_MARK, LCD2D14_MARK, LCD2D15_MARK, + LCD2D16_MARK, LCD2D17_MARK, +}; +static const unsigned int lcd2_data24_pins[] = { + /* D[0:23] */ + 128, 129, 142, 143, 144, 145, 138, 139, + 140, 141, 130, 131, 132, 133, 134, 135, + 136, 137, 146, 147, 234, 235, 238, 239 +}; +static const unsigned int lcd2_data24_mux[] = { + LCD2D0_MARK, LCD2D1_MARK, LCD2D2_MARK, LCD2D3_MARK, + LCD2D4_MARK, LCD2D5_MARK, LCD2D6_MARK, LCD2D7_MARK, + LCD2D8_MARK, LCD2D9_MARK, LCD2D10_MARK, LCD2D11_MARK, + LCD2D12_MARK, LCD2D13_MARK, LCD2D14_MARK, LCD2D15_MARK, + LCD2D16_MARK, LCD2D17_MARK, LCD2D18_MARK, LCD2D19_MARK, + LCD2D20_MARK, LCD2D21_MARK, LCD2D22_MARK, LCD2D23_MARK, +}; +static const unsigned int lcd2_sync_0_pins[] = { + /* VSYN, HSYN, DCK, DISP */ + 128, 129, 146, 145, +}; +static const unsigned int lcd2_sync_0_mux[] = { + PORT128_LCD2VSYN_MARK, PORT129_LCD2HSYN_MARK, + LCD2DCK_MARK, PORT145_LCD2DISP_MARK, +}; +static const unsigned int lcd2_sync_1_pins[] = { + /* VSYN, HSYN, DCK, DISP */ + 222, 221, 219, 217, +}; +static const unsigned int lcd2_sync_1_mux[] = { + PORT222_LCD2VSYN_MARK, PORT221_LCD2HSYN_MARK, + LCD2DCK_2_MARK, PORT217_LCD2DISP_MARK, +}; +static const unsigned int lcd2_sys_0_pins[] = { + /* CS, WR, RD, RS */ + 129, 146, 147, 145, +}; +static const unsigned int lcd2_sys_0_mux[] = { + PORT129_LCD2CS__MARK, PORT146_LCD2WR__MARK, + LCD2RD__MARK, PORT145_LCD2RS_MARK, +}; +static const unsigned int lcd2_sys_1_pins[] = { + /* CS, WR, RD, RS */ + 221, 219, 147, 217, +}; +static const unsigned int lcd2_sys_1_mux[] = { + PORT221_LCD2CS__MARK, PORT219_LCD2WR__MARK, + LCD2RD__MARK, PORT217_LCD2RS_MARK, +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(lcd_data8), + SH_PFC_PIN_GROUP(lcd_data9), + SH_PFC_PIN_GROUP(lcd_data12), + SH_PFC_PIN_GROUP(lcd_data16), + SH_PFC_PIN_GROUP(lcd_data18), + SH_PFC_PIN_GROUP(lcd_data24), + SH_PFC_PIN_GROUP(lcd_display), + SH_PFC_PIN_GROUP(lcd_lclk), + SH_PFC_PIN_GROUP(lcd_sync), + SH_PFC_PIN_GROUP(lcd_sys), + SH_PFC_PIN_GROUP(lcd2_data8), + SH_PFC_PIN_GROUP(lcd2_data9), + SH_PFC_PIN_GROUP(lcd2_data12), + SH_PFC_PIN_GROUP(lcd2_data16), + SH_PFC_PIN_GROUP(lcd2_data18), + SH_PFC_PIN_GROUP(lcd2_data24), + SH_PFC_PIN_GROUP(lcd2_sync_0), + SH_PFC_PIN_GROUP(lcd2_sync_1), + SH_PFC_PIN_GROUP(lcd2_sys_0), + SH_PFC_PIN_GROUP(lcd2_sys_1), +}; + +static const char * const lcd_groups[] = { + "lcd_data8", + "lcd_data9", + "lcd_data12", + "lcd_data16", + "lcd_data18", + "lcd_data24", + "lcd_display", + "lcd_lclk", + "lcd_sync", + "lcd_sys", +}; + +static const char * const lcd2_groups[] = { + "lcd2_data8", + "lcd2_data9", + "lcd2_data12", + "lcd2_data16", + "lcd2_data18", + "lcd2_data24", + "lcd2_sync_0", + "lcd2_sync_1", + "lcd2_sys_0", + "lcd2_sys_1", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(lcd), + SH_PFC_FUNCTION(lcd2), +}; + #define PINMUX_FN_BASE GPIO_FN_VBUS_0 static const struct pinmux_func pinmux_func_gpios[] = { @@ -3140,6 +3389,11 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = { .nr_pins = ARRAY_SIZE(pinmux_pins), .ranges = pinmux_ranges, .nr_ranges = ARRAY_SIZE(pinmux_ranges), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + .func_gpios = pinmux_func_gpios, .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), -- cgit From 64d87acb278fe90dbe5c69d7b1242eaf670ccc46 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Add SCIFA and SCIFB pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 351 ++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index c8b2604eb8f6..4b0a34958fdb 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2040,6 +2040,253 @@ static const unsigned int lcd2_sys_1_mux[] = { PORT221_LCD2CS__MARK, PORT219_LCD2WR__MARK, LCD2RD__MARK, PORT217_LCD2RS_MARK, }; +/* - SCIFA0 ----------------------------------------------------------------- */ +static const unsigned int scifa0_data_pins[] = { + /* RXD, TXD */ + 43, 17, +}; +static const unsigned int scifa0_data_mux[] = { + SCIFA0_RXD_MARK, SCIFA0_TXD_MARK, +}; +static const unsigned int scifa0_clk_pins[] = { + /* SCK */ + 16, +}; +static const unsigned int scifa0_clk_mux[] = { + SCIFA0_SCK_MARK, +}; +static const unsigned int scifa0_ctrl_pins[] = { + /* RTS, CTS */ + 42, 44, +}; +static const unsigned int scifa0_ctrl_mux[] = { + SCIFA0_RTS__MARK, SCIFA0_CTS__MARK, +}; +/* - SCIFA1 ----------------------------------------------------------------- */ +static const unsigned int scifa1_data_pins[] = { + /* RXD, TXD */ + 228, 225, +}; +static const unsigned int scifa1_data_mux[] = { + SCIFA1_RXD_MARK, SCIFA1_TXD_MARK, +}; +static const unsigned int scifa1_clk_pins[] = { + /* SCK */ + 226, +}; +static const unsigned int scifa1_clk_mux[] = { + SCIFA1_SCK_MARK, +}; +static const unsigned int scifa1_ctrl_pins[] = { + /* RTS, CTS */ + 227, 229, +}; +static const unsigned int scifa1_ctrl_mux[] = { + SCIFA1_RTS__MARK, SCIFA1_CTS__MARK, +}; +/* - SCIFA2 ----------------------------------------------------------------- */ +static const unsigned int scifa2_data_0_pins[] = { + /* RXD, TXD */ + 155, 154, +}; +static const unsigned int scifa2_data_0_mux[] = { + SCIFA2_RXD1_MARK, SCIFA2_TXD1_MARK, +}; +static const unsigned int scifa2_clk_0_pins[] = { + /* SCK */ + 158, +}; +static const unsigned int scifa2_clk_0_mux[] = { + SCIFA2_SCK1_MARK, +}; +static const unsigned int scifa2_ctrl_0_pins[] = { + /* RTS, CTS */ + 156, 157, +}; +static const unsigned int scifa2_ctrl_0_mux[] = { + SCIFA2_RTS1__MARK, SCIFA2_CTS1__MARK, +}; +static const unsigned int scifa2_data_1_pins[] = { + /* RXD, TXD */ + 233, 230, +}; +static const unsigned int scifa2_data_1_mux[] = { + SCIFA2_RXD2_MARK, SCIFA2_TXD2_MARK, +}; +static const unsigned int scifa2_clk_1_pins[] = { + /* SCK */ + 232, +}; +static const unsigned int scifa2_clk_1_mux[] = { + SCIFA2_SCK2_MARK, +}; +static const unsigned int scifa2_ctrl_1_pins[] = { + /* RTS, CTS */ + 234, 231, +}; +static const unsigned int scifa2_ctrl_1_mux[] = { + SCIFA2_RTS2__MARK, SCIFA2_CTS2__MARK, +}; +/* - SCIFA3 ----------------------------------------------------------------- */ +static const unsigned int scifa3_data_pins[] = { + /* RXD, TXD */ + 108, 110, +}; +static const unsigned int scifa3_data_mux[] = { + SCIFA3_RXD_MARK, SCIFA3_TXD_MARK, +}; +static const unsigned int scifa3_ctrl_pins[] = { + /* RTS, CTS */ + 109, 107, +}; +static const unsigned int scifa3_ctrl_mux[] = { + SCIFA3_RTS__MARK, SCIFA3_CTS__MARK, +}; +/* - SCIFA4 ----------------------------------------------------------------- */ +static const unsigned int scifa4_data_pins[] = { + /* RXD, TXD */ + 33, 32, +}; +static const unsigned int scifa4_data_mux[] = { + SCIFA4_RXD_MARK, SCIFA4_TXD_MARK, +}; +static const unsigned int scifa4_ctrl_pins[] = { + /* RTS, CTS */ + 34, 35, +}; +static const unsigned int scifa4_ctrl_mux[] = { + SCIFA4_RTS__MARK, SCIFA4_CTS__MARK, +}; +/* - SCIFA5 ----------------------------------------------------------------- */ +static const unsigned int scifa5_data_0_pins[] = { + /* RXD, TXD */ + 246, 247, +}; +static const unsigned int scifa5_data_0_mux[] = { + PORT246_SCIFA5_RXD_MARK, PORT247_SCIFA5_TXD_MARK, +}; +static const unsigned int scifa5_clk_0_pins[] = { + /* SCK */ + 248, +}; +static const unsigned int scifa5_clk_0_mux[] = { + PORT248_SCIFA5_SCK_MARK, +}; +static const unsigned int scifa5_ctrl_0_pins[] = { + /* RTS, CTS */ + 245, 244, +}; +static const unsigned int scifa5_ctrl_0_mux[] = { + PORT245_SCIFA5_RTS__MARK, PORT244_SCIFA5_CTS__MARK, +}; +static const unsigned int scifa5_data_1_pins[] = { + /* RXD, TXD */ + 195, 196, +}; +static const unsigned int scifa5_data_1_mux[] = { + PORT195_SCIFA5_RXD_MARK, PORT196_SCIFA5_TXD_MARK, +}; +static const unsigned int scifa5_clk_1_pins[] = { + /* SCK */ + 197, +}; +static const unsigned int scifa5_clk_1_mux[] = { + PORT197_SCIFA5_SCK_MARK, +}; +static const unsigned int scifa5_ctrl_1_pins[] = { + /* RTS, CTS */ + 194, 193, +}; +static const unsigned int scifa5_ctrl_1_mux[] = { + PORT194_SCIFA5_RTS__MARK, PORT193_SCIFA5_CTS__MARK, +}; +static const unsigned int scifa5_data_2_pins[] = { + /* RXD, TXD */ + 162, 160, +}; +static const unsigned int scifa5_data_2_mux[] = { + PORT162_SCIFA5_RXD_MARK, PORT160_SCIFA5_TXD_MARK, +}; +static const unsigned int scifa5_clk_2_pins[] = { + /* SCK */ + 159, +}; +static const unsigned int scifa5_clk_2_mux[] = { + PORT159_SCIFA5_SCK_MARK, +}; +static const unsigned int scifa5_ctrl_2_pins[] = { + /* RTS, CTS */ + 163, 161, +}; +static const unsigned int scifa5_ctrl_2_mux[] = { + PORT163_SCIFA5_RTS__MARK, PORT161_SCIFA5_CTS__MARK, +}; +/* - SCIFA6 ----------------------------------------------------------------- */ +static const unsigned int scifa6_pins[] = { + /* TXD */ + 240, +}; +static const unsigned int scifa6_mux[] = { + SCIFA6_TXD_MARK, +}; +/* - SCIFA7 ----------------------------------------------------------------- */ +static const unsigned int scifa7_data_pins[] = { + /* RXD, TXD */ + 12, 18, +}; +static const unsigned int scifa7_data_mux[] = { + SCIFA7_RXD_MARK, SCIFA7_TXD_MARK, +}; +static const unsigned int scifa7_ctrl_pins[] = { + /* RTS, CTS */ + 19, 13, +}; +static const unsigned int scifa7_ctrl_mux[] = { + SCIFA7_RTS__MARK, SCIFA7_CTS__MARK, +}; +/* - SCIFB ------------------------------------------------------------------ */ +static const unsigned int scifb_data_0_pins[] = { + /* RXD, TXD */ + 162, 160, +}; +static const unsigned int scifb_data_0_mux[] = { + PORT162_SCIFB_RXD_MARK, PORT160_SCIFB_TXD_MARK, +}; +static const unsigned int scifb_clk_0_pins[] = { + /* SCK */ + 159, +}; +static const unsigned int scifb_clk_0_mux[] = { + PORT159_SCIFB_SCK_MARK, +}; +static const unsigned int scifb_ctrl_0_pins[] = { + /* RTS, CTS */ + 163, 161, +}; +static const unsigned int scifb_ctrl_0_mux[] = { + PORT163_SCIFB_RTS__MARK, PORT161_SCIFB_CTS__MARK, +}; +static const unsigned int scifb_data_1_pins[] = { + /* RXD, TXD */ + 246, 247, +}; +static const unsigned int scifb_data_1_mux[] = { + PORT246_SCIFB_RXD_MARK, PORT247_SCIFB_TXD_MARK, +}; +static const unsigned int scifb_clk_1_pins[] = { + /* SCK */ + 248, +}; +static const unsigned int scifb_clk_1_mux[] = { + PORT248_SCIFB_SCK_MARK, +}; +static const unsigned int scifb_ctrl_1_pins[] = { + /* RTS, CTS */ + 245, 244, +}; +static const unsigned int scifb_ctrl_1_mux[] = { + PORT245_SCIFB_RTS__MARK, PORT244_SCIFB_CTS__MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(lcd_data8), @@ -2062,6 +2309,40 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(lcd2_sync_1), SH_PFC_PIN_GROUP(lcd2_sys_0), SH_PFC_PIN_GROUP(lcd2_sys_1), + SH_PFC_PIN_GROUP(scifa0_data), + SH_PFC_PIN_GROUP(scifa0_clk), + SH_PFC_PIN_GROUP(scifa0_ctrl), + SH_PFC_PIN_GROUP(scifa1_data), + SH_PFC_PIN_GROUP(scifa1_clk), + SH_PFC_PIN_GROUP(scifa1_ctrl), + SH_PFC_PIN_GROUP(scifa2_data_0), + SH_PFC_PIN_GROUP(scifa2_clk_0), + SH_PFC_PIN_GROUP(scifa2_ctrl_0), + SH_PFC_PIN_GROUP(scifa2_data_1), + SH_PFC_PIN_GROUP(scifa2_clk_1), + SH_PFC_PIN_GROUP(scifa2_ctrl_1), + SH_PFC_PIN_GROUP(scifa3_data), + SH_PFC_PIN_GROUP(scifa3_ctrl), + SH_PFC_PIN_GROUP(scifa4_data), + SH_PFC_PIN_GROUP(scifa4_ctrl), + SH_PFC_PIN_GROUP(scifa5_data_0), + SH_PFC_PIN_GROUP(scifa5_clk_0), + SH_PFC_PIN_GROUP(scifa5_ctrl_0), + SH_PFC_PIN_GROUP(scifa5_data_1), + SH_PFC_PIN_GROUP(scifa5_clk_1), + SH_PFC_PIN_GROUP(scifa5_ctrl_1), + SH_PFC_PIN_GROUP(scifa5_data_2), + SH_PFC_PIN_GROUP(scifa5_clk_2), + SH_PFC_PIN_GROUP(scifa5_ctrl_2), + SH_PFC_PIN_GROUP(scifa6), + SH_PFC_PIN_GROUP(scifa7_data), + SH_PFC_PIN_GROUP(scifa7_ctrl), + SH_PFC_PIN_GROUP(scifb_data_0), + SH_PFC_PIN_GROUP(scifb_clk_0), + SH_PFC_PIN_GROUP(scifb_ctrl_0), + SH_PFC_PIN_GROUP(scifb_data_1), + SH_PFC_PIN_GROUP(scifb_clk_1), + SH_PFC_PIN_GROUP(scifb_ctrl_1), }; static const char * const lcd_groups[] = { @@ -2090,9 +2371,79 @@ static const char * const lcd2_groups[] = { "lcd2_sys_1", }; +static const char * const scifa0_groups[] = { + "scifa0_data", + "scifa0_clk", + "scifa0_ctrl", +}; + +static const char * const scifa1_groups[] = { + "scifa1_data", + "scifa1_clk", + "scifa1_ctrl", +}; + +static const char * const scifa2_groups[] = { + "scifa2_data_0", + "scifa2_clk_0", + "scifa2_ctrl_0", + "scifa2_data_1", + "scifa2_clk_1", + "scifa2_ctrl_1", +}; + +static const char * const scifa3_groups[] = { + "scifa3_data", + "scifa3_ctrl", +}; + +static const char * const scifa4_groups[] = { + "scifa4_data", + "scifa4_ctrl", +}; + +static const char * const scifa5_groups[] = { + "scifa5_data_0", + "scifa5_clk_0", + "scifa5_ctrl_0", + "scifa5_data_1", + "scifa5_clk_1", + "scifa5_ctrl_1", + "scifa5_data_2", + "scifa5_clk_2", + "scifa5_ctrl_2", +}; + +static const char * const scifa6_groups[] = { + "scifa6", +}; + +static const char * const scifa7_groups[] = { + "scifa7_data", + "scifa7_ctrl", +}; + +static const char * const scifb_groups[] = { + "scifb_data_0", + "scifb_clk_0", + "scifb_ctrl_0", + "scifb_data_1", + "scifb_clk_1", + "scifb_ctrl_1", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(lcd), SH_PFC_FUNCTION(lcd2), + SH_PFC_FUNCTION(scifa0), + SH_PFC_FUNCTION(scifa1), + SH_PFC_FUNCTION(scifa2), + SH_PFC_FUNCTION(scifa3), + SH_PFC_FUNCTION(scifa4), + SH_PFC_FUNCTION(scifa5), + SH_PFC_FUNCTION(scifa6), + SH_PFC_FUNCTION(scifa7), + SH_PFC_FUNCTION(scifb), }; #define PINMUX_FN_BASE GPIO_FN_VBUS_0 -- cgit From ec3a57bb3b69a2af0f136872105335ec965cdd98 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Add I2C2 and I2C3 pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 4b0a34958fdb..fad11d7a7dde 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1846,6 +1846,50 @@ static const struct pinmux_range pinmux_ranges[] = { {.begin = 288, .end = 309,}, }; +/* - I2C2 ------------------------------------------------------------------- */ +static const unsigned int i2c2_0_pins[] = { + /* SCL, SDA */ + 237, 236, +}; +static const unsigned int i2c2_0_mux[] = { + PORT237_I2C_SCL2_MARK, PORT236_I2C_SDA2_MARK, +}; +static const unsigned int i2c2_1_pins[] = { + /* SCL, SDA */ + 27, 28, +}; +static const unsigned int i2c2_1_mux[] = { + PORT27_I2C_SCL2_MARK, PORT28_I2C_SDA2_MARK, +}; +static const unsigned int i2c2_2_pins[] = { + /* SCL, SDA */ + 115, 116, +}; +static const unsigned int i2c2_2_mux[] = { + PORT115_I2C_SCL2_MARK, PORT116_I2C_SDA2_MARK, +}; +/* - I2C3 ------------------------------------------------------------------- */ +static const unsigned int i2c3_0_pins[] = { + /* SCL, SDA */ + 248, 249, +}; +static const unsigned int i2c3_0_mux[] = { + PORT248_I2C_SCL3_MARK, PORT249_I2C_SDA3_MARK, +}; +static const unsigned int i2c3_1_pins[] = { + /* SCL, SDA */ + 27, 28, +}; +static const unsigned int i2c3_1_mux[] = { + PORT27_I2C_SCL3_MARK, PORT28_I2C_SDA3_MARK, +}; +static const unsigned int i2c3_2_pins[] = { + /* SCL, SDA */ + 115, 116, +}; +static const unsigned int i2c3_2_mux[] = { + PORT115_I2C_SCL3_MARK, PORT116_I2C_SDA3_MARK, +}; /* - LCD -------------------------------------------------------------------- */ static const unsigned int lcd_data8_pins[] = { /* D[0:7] */ @@ -2289,6 +2333,12 @@ static const unsigned int scifb_ctrl_1_mux[] = { }; static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(i2c2_0), + SH_PFC_PIN_GROUP(i2c2_1), + SH_PFC_PIN_GROUP(i2c2_2), + SH_PFC_PIN_GROUP(i2c3_0), + SH_PFC_PIN_GROUP(i2c3_1), + SH_PFC_PIN_GROUP(i2c3_2), SH_PFC_PIN_GROUP(lcd_data8), SH_PFC_PIN_GROUP(lcd_data9), SH_PFC_PIN_GROUP(lcd_data12), @@ -2345,6 +2395,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(scifb_ctrl_1), }; +static const char * const i2c2_groups[] = { + "i2c2_0", + "i2c2_1", + "i2c2_2", +}; + +static const char * const i2c3_groups[] = { + "i2c3_0", + "i2c3_1", + "i2c3_2", +}; + static const char * const lcd_groups[] = { "lcd_data8", "lcd_data9", @@ -2433,6 +2495,8 @@ static const char * const scifb_groups[] = { }; static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c3), SH_PFC_FUNCTION(lcd), SH_PFC_FUNCTION(lcd2), SH_PFC_FUNCTION(scifa0), -- cgit From 2ecd4154c906b7d60e7d06a515e6384cc58e93ab Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Add FSI pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 244 ++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index fad11d7a7dde..0d35f7b3e5b4 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1846,6 +1846,185 @@ static const struct pinmux_range pinmux_ranges[] = { {.begin = 288, .end = 309,}, }; +/* - FSIA ------------------------------------------------------------------- */ +static const unsigned int fsia_mclk_in_pins[] = { + /* CK */ + 49, +}; +static const unsigned int fsia_mclk_in_mux[] = { + FSIACK_MARK, +}; +static const unsigned int fsia_mclk_out_pins[] = { + /* OMC */ + 49, +}; +static const unsigned int fsia_mclk_out_mux[] = { + FSIAOMC_MARK, +}; +static const unsigned int fsia_sclk_in_pins[] = { + /* ILR, IBT */ + 50, 51, +}; +static const unsigned int fsia_sclk_in_mux[] = { + FSIAILR_MARK, FSIAIBT_MARK, +}; +static const unsigned int fsia_sclk_out_pins[] = { + /* OLR, OBT */ + 50, 51, +}; +static const unsigned int fsia_sclk_out_mux[] = { + FSIAOLR_MARK, FSIAOBT_MARK, +}; +static const unsigned int fsia_data_in_pins[] = { + /* ISLD */ + 55, +}; +static const unsigned int fsia_data_in_mux[] = { + FSIAISLD_MARK, +}; +static const unsigned int fsia_data_out_pins[] = { + /* OSLD */ + 52, +}; +static const unsigned int fsia_data_out_mux[] = { + FSIAOSLD_MARK, +}; +static const unsigned int fsia_spdif_pins[] = { + /* SPDIF */ + 53, +}; +static const unsigned int fsia_spdif_mux[] = { + FSIASPDIF_MARK, +}; +/* - FSIB ------------------------------------------------------------------- */ +static const unsigned int fsib_mclk_in_pins[] = { + /* CK */ + 54, +}; +static const unsigned int fsib_mclk_in_mux[] = { + FSIBCK_MARK, +}; +static const unsigned int fsib_mclk_out_pins[] = { + /* OMC */ + 54, +}; +static const unsigned int fsib_mclk_out_mux[] = { + FSIBOMC_MARK, +}; +static const unsigned int fsib_sclk_in_pins[] = { + /* ILR, IBT */ + 37, 36, +}; +static const unsigned int fsib_sclk_in_mux[] = { + FSIBILR_MARK, FSIBIBT_MARK, +}; +static const unsigned int fsib_sclk_out_pins[] = { + /* OLR, OBT */ + 37, 36, +}; +static const unsigned int fsib_sclk_out_mux[] = { + FSIBOLR_MARK, FSIBOBT_MARK, +}; +static const unsigned int fsib_data_in_pins[] = { + /* ISLD */ + 39, +}; +static const unsigned int fsib_data_in_mux[] = { + FSIBISLD_MARK, +}; +static const unsigned int fsib_data_out_pins[] = { + /* OSLD */ + 38, +}; +static const unsigned int fsib_data_out_mux[] = { + FSIBOSLD_MARK, +}; +static const unsigned int fsib_spdif_pins[] = { + /* SPDIF */ + 53, +}; +static const unsigned int fsib_spdif_mux[] = { + FSIBSPDIF_MARK, +}; +/* - FSIC ------------------------------------------------------------------- */ +static const unsigned int fsic_mclk_in_pins[] = { + /* CK */ + 54, +}; +static const unsigned int fsic_mclk_in_mux[] = { + FSICCK_MARK, +}; +static const unsigned int fsic_mclk_out_pins[] = { + /* OMC */ + 54, +}; +static const unsigned int fsic_mclk_out_mux[] = { + FSICOMC_MARK, +}; +static const unsigned int fsic_sclk_in_pins[] = { + /* ILR, IBT */ + 46, 45, +}; +static const unsigned int fsic_sclk_in_mux[] = { + FSICILR_MARK, FSICIBT_MARK, +}; +static const unsigned int fsic_sclk_out_pins[] = { + /* OLR, OBT */ + 46, 45, +}; +static const unsigned int fsic_sclk_out_mux[] = { + FSICOLR_MARK, FSICOBT_MARK, +}; +static const unsigned int fsic_data_in_pins[] = { + /* ISLD */ + 48, +}; +static const unsigned int fsic_data_in_mux[] = { + FSICISLD_MARK, +}; +static const unsigned int fsic_data_out_pins[] = { + /* OSLD, OSLDT1, OSLDT2, OSLDT3 */ + 47, 44, 42, 16, +}; +static const unsigned int fsic_data_out_mux[] = { + FSICOSLD_MARK, FSICOSLDT1_MARK, FSICOSLDT2_MARK, FSICOSLDT3_MARK, +}; +static const unsigned int fsic_spdif_0_pins[] = { + /* SPDIF */ + 53, +}; +static const unsigned int fsic_spdif_0_mux[] = { + PORT53_FSICSPDIF_MARK, +}; +static const unsigned int fsic_spdif_1_pins[] = { + /* SPDIF */ + 47, +}; +static const unsigned int fsic_spdif_1_mux[] = { + PORT47_FSICSPDIF_MARK, +}; +/* - FSID ------------------------------------------------------------------- */ +static const unsigned int fsid_sclk_in_pins[] = { + /* ILR, IBT */ + 46, 45, +}; +static const unsigned int fsid_sclk_in_mux[] = { + FSIDILR_MARK, FSIDIBT_MARK, +}; +static const unsigned int fsid_sclk_out_pins[] = { + /* OLR, OBT */ + 46, 45, +}; +static const unsigned int fsid_sclk_out_mux[] = { + FSIDOLR_MARK, FSIDOBT_MARK, +}; +static const unsigned int fsid_data_in_pins[] = { + /* ISLD */ + 48, +}; +static const unsigned int fsid_data_in_mux[] = { + FSIDISLD_MARK, +}; /* - I2C2 ------------------------------------------------------------------- */ static const unsigned int i2c2_0_pins[] = { /* SCL, SDA */ @@ -2333,6 +2512,31 @@ static const unsigned int scifb_ctrl_1_mux[] = { }; static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(fsia_mclk_in), + SH_PFC_PIN_GROUP(fsia_mclk_out), + SH_PFC_PIN_GROUP(fsia_sclk_in), + SH_PFC_PIN_GROUP(fsia_sclk_out), + SH_PFC_PIN_GROUP(fsia_data_in), + SH_PFC_PIN_GROUP(fsia_data_out), + SH_PFC_PIN_GROUP(fsia_spdif), + SH_PFC_PIN_GROUP(fsib_mclk_in), + SH_PFC_PIN_GROUP(fsib_mclk_out), + SH_PFC_PIN_GROUP(fsib_sclk_in), + SH_PFC_PIN_GROUP(fsib_sclk_out), + SH_PFC_PIN_GROUP(fsib_data_in), + SH_PFC_PIN_GROUP(fsib_data_out), + SH_PFC_PIN_GROUP(fsib_spdif), + SH_PFC_PIN_GROUP(fsic_mclk_in), + SH_PFC_PIN_GROUP(fsic_mclk_out), + SH_PFC_PIN_GROUP(fsic_sclk_in), + SH_PFC_PIN_GROUP(fsic_sclk_out), + SH_PFC_PIN_GROUP(fsic_data_in), + SH_PFC_PIN_GROUP(fsic_data_out), + SH_PFC_PIN_GROUP(fsic_spdif_0), + SH_PFC_PIN_GROUP(fsic_spdif_1), + SH_PFC_PIN_GROUP(fsid_sclk_in), + SH_PFC_PIN_GROUP(fsid_sclk_out), + SH_PFC_PIN_GROUP(fsid_data_in), SH_PFC_PIN_GROUP(i2c2_0), SH_PFC_PIN_GROUP(i2c2_1), SH_PFC_PIN_GROUP(i2c2_2), @@ -2395,6 +2599,42 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(scifb_ctrl_1), }; +static const char * const fsia_groups[] = { + "fsia_mclk_in", + "fsia_mclk_out", + "fsia_sclk_in", + "fsia_sclk_out", + "fsia_data_in", + "fsia_data_out", + "fsia_spdif", +}; + +static const char * const fsib_groups[] = { + "fsib_mclk_in", + "fsib_mclk_out", + "fsib_sclk_in", + "fsib_sclk_out", + "fsib_data_in", + "fsib_data_out", + "fsib_spdif", +}; + +static const char * const fsic_groups[] = { + "fsic_mclk_in", + "fsic_mclk_out", + "fsic_sclk_in", + "fsic_sclk_out", + "fsic_data_in", + "fsic_data_out", + "fsic_spdif", +}; + +static const char * const fsid_groups[] = { + "fsid_sclk_in", + "fsid_sclk_out", + "fsid_data_in", +}; + static const char * const i2c2_groups[] = { "i2c2_0", "i2c2_1", @@ -2495,6 +2735,10 @@ static const char * const scifb_groups[] = { }; static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(fsia), + SH_PFC_FUNCTION(fsib), + SH_PFC_FUNCTION(fsic), + SH_PFC_FUNCTION(fsid), SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c3), SH_PFC_FUNCTION(lcd), -- cgit From 82f6b6da703e784b923763cc7161116829b2ca66 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 12 Feb 2013 16:50:03 +0100 Subject: sh-pfc: sh73a0: Add SDHI and MMCIF pin groups and functions Add pin group definitions for SDHI0, SDHI1, SDHI2 and MMCIF interfaces on sh73a0. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 194 ++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 0d35f7b3e5b4..ed5cbaf66ac2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2263,6 +2263,66 @@ static const unsigned int lcd2_sys_1_mux[] = { PORT221_LCD2CS__MARK, PORT219_LCD2WR__MARK, LCD2RD__MARK, PORT217_LCD2RS_MARK, }; +/* - MMCIF ------------------------------------------------------------------ */ +static const unsigned int mmc0_data1_0_pins[] = { + /* D[0] */ + 271, +}; +static const unsigned int mmc0_data1_0_mux[] = { + MMCD0_0_MARK, +}; +static const unsigned int mmc0_data4_0_pins[] = { + /* D[0:3] */ + 271, 272, 273, 274, +}; +static const unsigned int mmc0_data4_0_mux[] = { + MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK, +}; +static const unsigned int mmc0_data8_0_pins[] = { + /* D[0:7] */ + 271, 272, 273, 274, 275, 276, 277, 278, +}; +static const unsigned int mmc0_data8_0_mux[] = { + MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK, + MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK, +}; +static const unsigned int mmc0_ctrl_0_pins[] = { + /* CMD, CLK */ + 279, 270, +}; +static const unsigned int mmc0_ctrl_0_mux[] = { + MMCCMD0_MARK, MMCCLK0_MARK, +}; + +static const unsigned int mmc0_data1_1_pins[] = { + /* D[0] */ + 305, +}; +static const unsigned int mmc0_data1_1_mux[] = { + MMCD1_0_MARK, +}; +static const unsigned int mmc0_data4_1_pins[] = { + /* D[0:3] */ + 305, 304, 303, 302, +}; +static const unsigned int mmc0_data4_1_mux[] = { + MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK, +}; +static const unsigned int mmc0_data8_1_pins[] = { + /* D[0:7] */ + 305, 304, 303, 302, 301, 300, 299, 298, +}; +static const unsigned int mmc0_data8_1_mux[] = { + MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK, + MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK, +}; +static const unsigned int mmc0_ctrl_1_pins[] = { + /* CMD, CLK */ + 297, 289, +}; +static const unsigned int mmc0_ctrl_1_mux[] = { + MMCCMD1_MARK, MMCCLK1_MARK, +}; /* - SCIFA0 ----------------------------------------------------------------- */ static const unsigned int scifa0_data_pins[] = { /* RXD, TXD */ @@ -2510,6 +2570,86 @@ static const unsigned int scifb_ctrl_1_pins[] = { static const unsigned int scifb_ctrl_1_mux[] = { PORT245_SCIFB_RTS__MARK, PORT244_SCIFB_CTS__MARK, }; +/* - SDHI0 ------------------------------------------------------------------ */ +static const unsigned int sdhi0_data1_pins[] = { + /* D0 */ + 252, +}; +static const unsigned int sdhi0_data1_mux[] = { + SDHID0_0_MARK, +}; +static const unsigned int sdhi0_data4_pins[] = { + /* D[0:3] */ + 252, 253, 254, 255, +}; +static const unsigned int sdhi0_data4_mux[] = { + SDHID0_0_MARK, SDHID0_1_MARK, SDHID0_2_MARK, SDHID0_3_MARK, +}; +static const unsigned int sdhi0_ctrl_pins[] = { + /* CMD, CLK */ + 256, 250, +}; +static const unsigned int sdhi0_ctrl_mux[] = { + SDHICMD0_MARK, SDHICLK0_MARK, +}; +static const unsigned int sdhi0_cd_pins[] = { + /* CD */ + 251, +}; +static const unsigned int sdhi0_cd_mux[] = { + SDHICD0_MARK, +}; +static const unsigned int sdhi0_wp_pins[] = { + /* WP */ + 257, +}; +static const unsigned int sdhi0_wp_mux[] = { + SDHIWP0_MARK, +}; +/* - SDHI1 ------------------------------------------------------------------ */ +static const unsigned int sdhi1_data1_pins[] = { + /* D0 */ + 259, +}; +static const unsigned int sdhi1_data1_mux[] = { + SDHID1_0_MARK, +}; +static const unsigned int sdhi1_data4_pins[] = { + /* D[0:3] */ + 259, 260, 261, 262, +}; +static const unsigned int sdhi1_data4_mux[] = { + SDHID1_0_MARK, SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK, +}; +static const unsigned int sdhi1_ctrl_pins[] = { + /* CMD, CLK */ + 263, 258, +}; +static const unsigned int sdhi1_ctrl_mux[] = { + SDHICMD1_MARK, SDHICLK1_MARK, +}; +/* - SDHI2 ------------------------------------------------------------------ */ +static const unsigned int sdhi2_data1_pins[] = { + /* D0 */ + 265, +}; +static const unsigned int sdhi2_data1_mux[] = { + SDHID2_0_MARK, +}; +static const unsigned int sdhi2_data4_pins[] = { + /* D[0:3] */ + 265, 266, 267, 268, +}; +static const unsigned int sdhi2_data4_mux[] = { + SDHID2_0_MARK, SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK, +}; +static const unsigned int sdhi2_ctrl_pins[] = { + /* CMD, CLK */ + 269, 264, +}; +static const unsigned int sdhi2_ctrl_mux[] = { + SDHICMD2_MARK, SDHICLK2_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(fsia_mclk_in), @@ -2563,6 +2703,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(lcd2_sync_1), SH_PFC_PIN_GROUP(lcd2_sys_0), SH_PFC_PIN_GROUP(lcd2_sys_1), + SH_PFC_PIN_GROUP(mmc0_data1_0), + SH_PFC_PIN_GROUP(mmc0_data4_0), + SH_PFC_PIN_GROUP(mmc0_data8_0), + SH_PFC_PIN_GROUP(mmc0_ctrl_0), + SH_PFC_PIN_GROUP(mmc0_data1_1), + SH_PFC_PIN_GROUP(mmc0_data4_1), + SH_PFC_PIN_GROUP(mmc0_data8_1), + SH_PFC_PIN_GROUP(mmc0_ctrl_1), SH_PFC_PIN_GROUP(scifa0_data), SH_PFC_PIN_GROUP(scifa0_clk), SH_PFC_PIN_GROUP(scifa0_ctrl), @@ -2597,6 +2745,17 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(scifb_data_1), SH_PFC_PIN_GROUP(scifb_clk_1), SH_PFC_PIN_GROUP(scifb_ctrl_1), + SH_PFC_PIN_GROUP(sdhi0_data1), + SH_PFC_PIN_GROUP(sdhi0_data4), + SH_PFC_PIN_GROUP(sdhi0_ctrl), + SH_PFC_PIN_GROUP(sdhi0_cd), + SH_PFC_PIN_GROUP(sdhi0_wp), + SH_PFC_PIN_GROUP(sdhi1_data1), + SH_PFC_PIN_GROUP(sdhi1_data4), + SH_PFC_PIN_GROUP(sdhi1_ctrl), + SH_PFC_PIN_GROUP(sdhi2_data1), + SH_PFC_PIN_GROUP(sdhi2_data4), + SH_PFC_PIN_GROUP(sdhi2_ctrl), }; static const char * const fsia_groups[] = { @@ -2673,6 +2832,17 @@ static const char * const lcd2_groups[] = { "lcd2_sys_1", }; +static const char * const mmc0_groups[] = { + "mmc0_data1_0", + "mmc0_data4_0", + "mmc0_data8_0", + "mmc0_ctrl_0", + "mmc0_data1_1", + "mmc0_data4_1", + "mmc0_data8_1", + "mmc0_ctrl_1", +}; + static const char * const scifa0_groups[] = { "scifa0_data", "scifa0_clk", @@ -2734,6 +2904,26 @@ static const char * const scifb_groups[] = { "scifb_ctrl_1", }; +static const char * const sdhi0_groups[] = { + "sdhi0_data1", + "sdhi0_data4", + "sdhi0_ctrl", + "sdhi0_cd", + "sdhi0_wp", +}; + +static const char * const sdhi1_groups[] = { + "sdhi1_data1", + "sdhi1_data4", + "sdhi1_ctrl", +}; + +static const char * const sdhi2_groups[] = { + "sdhi2_data1", + "sdhi2_data4", + "sdhi2_ctrl", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(fsia), SH_PFC_FUNCTION(fsib), @@ -2743,6 +2933,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(i2c3), SH_PFC_FUNCTION(lcd), SH_PFC_FUNCTION(lcd2), + SH_PFC_FUNCTION(mmc0), SH_PFC_FUNCTION(scifa0), SH_PFC_FUNCTION(scifa1), SH_PFC_FUNCTION(scifa2), @@ -2752,6 +2943,9 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(scifa6), SH_PFC_FUNCTION(scifa7), SH_PFC_FUNCTION(scifb), + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), }; #define PINMUX_FN_BASE GPIO_FN_VBUS_0 -- cgit From d6bab7b12e815e6c2a637a3b509143c866683c2a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Mar 2013 01:55:08 +0100 Subject: sh-pfc: sh73a0: Add KEYSC pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 213 ++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index ed5cbaf66ac2..aad800431241 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1846,6 +1846,12 @@ static const struct pinmux_range pinmux_ranges[] = { {.begin = 288, .end = 309,}, }; +/* Pin numbers for pins without a corresponding GPIO port number are computed + * from the row and column numbers with a 1000 offset to avoid collisions with + * GPIO port numbers. + */ +#define PIN_NUMBER(row, col) (1000+((row)-1)*34+(col)-1) + /* - FSIA ------------------------------------------------------------------- */ static const unsigned int fsia_mclk_in_pins[] = { /* CK */ @@ -2069,6 +2075,165 @@ static const unsigned int i2c3_2_pins[] = { static const unsigned int i2c3_2_mux[] = { PORT115_I2C_SCL3_MARK, PORT116_I2C_SDA3_MARK, }; +/* - KEYSC ------------------------------------------------------------------ */ +static const unsigned int keysc_in5_pins[] = { + /* KEYIN[0:4] */ + 66, 67, 68, 69, 70, +}; +static const unsigned int keysc_in5_mux[] = { + KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, + KEYIN4_MARK, +}; +static const unsigned int keysc_in6_pins[] = { + /* KEYIN[0:5] */ + 66, 67, 68, 69, 70, 71, +}; +static const unsigned int keysc_in6_mux[] = { + KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, + KEYIN4_MARK, KEYIN5_MARK, +}; +static const unsigned int keysc_in7_pins[] = { + /* KEYIN[0:6] */ + 66, 67, 68, 69, 70, 71, 72, +}; +static const unsigned int keysc_in7_mux[] = { + KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, + KEYIN4_MARK, KEYIN5_MARK, KEYIN6_MARK, +}; +static const unsigned int keysc_in8_pins[] = { + /* KEYIN[0:7] */ + 66, 67, 68, 69, 70, 71, 72, 73, +}; +static const unsigned int keysc_in8_mux[] = { + KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, + KEYIN4_MARK, KEYIN5_MARK, KEYIN6_MARK, KEYIN7_MARK, +}; +static const unsigned int keysc_out04_pins[] = { + /* KEYOUT[0:4] */ + 65, 64, 63, 62, 61, +}; +static const unsigned int keysc_out04_mux[] = { + KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK, KEYOUT4_MARK, +}; +static const unsigned int keysc_out5_pins[] = { + /* KEYOUT5 */ + 60, +}; +static const unsigned int keysc_out5_mux[] = { + KEYOUT5_MARK, +}; +static const unsigned int keysc_out6_0_pins[] = { + /* KEYOUT6 */ + 59, +}; +static const unsigned int keysc_out6_0_mux[] = { + PORT59_KEYOUT6_MARK, +}; +static const unsigned int keysc_out6_1_pins[] = { + /* KEYOUT6 */ + 131, +}; +static const unsigned int keysc_out6_1_mux[] = { + PORT131_KEYOUT6_MARK, +}; +static const unsigned int keysc_out6_2_pins[] = { + /* KEYOUT6 */ + 143, +}; +static const unsigned int keysc_out6_2_mux[] = { + PORT143_KEYOUT6_MARK, +}; +static const unsigned int keysc_out7_0_pins[] = { + /* KEYOUT7 */ + 58, +}; +static const unsigned int keysc_out7_0_mux[] = { + PORT58_KEYOUT7_MARK, +}; +static const unsigned int keysc_out7_1_pins[] = { + /* KEYOUT7 */ + 132, +}; +static const unsigned int keysc_out7_1_mux[] = { + PORT132_KEYOUT7_MARK, +}; +static const unsigned int keysc_out7_2_pins[] = { + /* KEYOUT7 */ + 144, +}; +static const unsigned int keysc_out7_2_mux[] = { + PORT144_KEYOUT7_MARK, +}; +static const unsigned int keysc_out8_0_pins[] = { + /* KEYOUT8 */ + PIN_NUMBER(6, 26), +}; +static const unsigned int keysc_out8_0_mux[] = { + KEYOUT8_MARK, +}; +static const unsigned int keysc_out8_1_pins[] = { + /* KEYOUT8 */ + 136, +}; +static const unsigned int keysc_out8_1_mux[] = { + PORT136_KEYOUT8_MARK, +}; +static const unsigned int keysc_out8_2_pins[] = { + /* KEYOUT8 */ + 138, +}; +static const unsigned int keysc_out8_2_mux[] = { + PORT138_KEYOUT8_MARK, +}; +static const unsigned int keysc_out9_0_pins[] = { + /* KEYOUT9 */ + 137, +}; +static const unsigned int keysc_out9_0_mux[] = { + PORT137_KEYOUT9_MARK, +}; +static const unsigned int keysc_out9_1_pins[] = { + /* KEYOUT9 */ + 139, +}; +static const unsigned int keysc_out9_1_mux[] = { + PORT139_KEYOUT9_MARK, +}; +static const unsigned int keysc_out9_2_pins[] = { + /* KEYOUT9 */ + 149, +}; +static const unsigned int keysc_out9_2_mux[] = { + PORT149_KEYOUT9_MARK, +}; +static const unsigned int keysc_out10_0_pins[] = { + /* KEYOUT10 */ + 132, +}; +static const unsigned int keysc_out10_0_mux[] = { + PORT132_KEYOUT10_MARK, +}; +static const unsigned int keysc_out10_1_pins[] = { + /* KEYOUT10 */ + 142, +}; +static const unsigned int keysc_out10_1_mux[] = { + PORT142_KEYOUT10_MARK, +}; +static const unsigned int keysc_out11_0_pins[] = { + /* KEYOUT11 */ + 131, +}; +static const unsigned int keysc_out11_0_mux[] = { + PORT131_KEYOUT11_MARK, +}; +static const unsigned int keysc_out11_1_pins[] = { + /* KEYOUT11 */ + 143, +}; +static const unsigned int keysc_out11_1_mux[] = { + PORT143_KEYOUT11_MARK, +}; /* - LCD -------------------------------------------------------------------- */ static const unsigned int lcd_data8_pins[] = { /* D[0:7] */ @@ -2683,6 +2848,28 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(i2c3_0), SH_PFC_PIN_GROUP(i2c3_1), SH_PFC_PIN_GROUP(i2c3_2), + SH_PFC_PIN_GROUP(keysc_in5), + SH_PFC_PIN_GROUP(keysc_in6), + SH_PFC_PIN_GROUP(keysc_in7), + SH_PFC_PIN_GROUP(keysc_in8), + SH_PFC_PIN_GROUP(keysc_out04), + SH_PFC_PIN_GROUP(keysc_out5), + SH_PFC_PIN_GROUP(keysc_out6_0), + SH_PFC_PIN_GROUP(keysc_out6_1), + SH_PFC_PIN_GROUP(keysc_out6_2), + SH_PFC_PIN_GROUP(keysc_out7_0), + SH_PFC_PIN_GROUP(keysc_out7_1), + SH_PFC_PIN_GROUP(keysc_out7_2), + SH_PFC_PIN_GROUP(keysc_out8_0), + SH_PFC_PIN_GROUP(keysc_out8_1), + SH_PFC_PIN_GROUP(keysc_out8_2), + SH_PFC_PIN_GROUP(keysc_out9_0), + SH_PFC_PIN_GROUP(keysc_out9_1), + SH_PFC_PIN_GROUP(keysc_out9_2), + SH_PFC_PIN_GROUP(keysc_out10_0), + SH_PFC_PIN_GROUP(keysc_out10_1), + SH_PFC_PIN_GROUP(keysc_out11_0), + SH_PFC_PIN_GROUP(keysc_out11_1), SH_PFC_PIN_GROUP(lcd_data8), SH_PFC_PIN_GROUP(lcd_data9), SH_PFC_PIN_GROUP(lcd_data12), @@ -2806,6 +2993,31 @@ static const char * const i2c3_groups[] = { "i2c3_2", }; +static const char * const keysc_groups[] = { + "keysc_in5", + "keysc_in6", + "keysc_in7", + "keysc_in8", + "keysc_out04", + "keysc_out5", + "keysc_out6_0", + "keysc_out6_1", + "keysc_out6_2", + "keysc_out7_0", + "keysc_out7_1", + "keysc_out7_2", + "keysc_out8_0", + "keysc_out8_1", + "keysc_out8_2", + "keysc_out9_0", + "keysc_out9_1", + "keysc_out9_2", + "keysc_out10_0", + "keysc_out10_1", + "keysc_out11_0", + "keysc_out11_1", +}; + static const char * const lcd_groups[] = { "lcd_data8", "lcd_data9", @@ -2931,6 +3143,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(fsid), SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(keysc), SH_PFC_FUNCTION(lcd), SH_PFC_FUNCTION(lcd2), SH_PFC_FUNCTION(mmc0), -- cgit From e24c62a6ce6b789d1372397894ffdea43e3a9f36 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Mar 2013 01:55:08 +0100 Subject: sh-pfc: sh73a0: Add BSC pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 124 ++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index aad800431241..76674af19d29 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1852,6 +1852,100 @@ static const struct pinmux_range pinmux_ranges[] = { */ #define PIN_NUMBER(row, col) (1000+((row)-1)*34+(col)-1) +/* - BSC -------------------------------------------------------------------- */ +static const unsigned int bsc_data_0_7_pins[] = { + /* D[0:7] */ + 74, 75, 76, 77, 78, 79, 80, 81, +}; +static const unsigned int bsc_data_0_7_mux[] = { + D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK, + D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK, +}; +static const unsigned int bsc_data_8_15_pins[] = { + /* D[8:15] */ + 82, 83, 84, 85, 86, 87, 88, 89, +}; +static const unsigned int bsc_data_8_15_mux[] = { + D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK, + D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK, +}; +static const unsigned int bsc_cs4_pins[] = { + /* CS */ + 90, +}; +static const unsigned int bsc_cs4_mux[] = { + CS4__MARK, +}; +static const unsigned int bsc_cs5_a_pins[] = { + /* CS */ + 91, +}; +static const unsigned int bsc_cs5_a_mux[] = { + CS5A__MARK, +}; +static const unsigned int bsc_cs5_b_pins[] = { + /* CS */ + 92, +}; +static const unsigned int bsc_cs5_b_mux[] = { + CS5B__MARK, +}; +static const unsigned int bsc_cs6_a_pins[] = { + /* CS */ + 94, +}; +static const unsigned int bsc_cs6_a_mux[] = { + CS6A__MARK, +}; +static const unsigned int bsc_cs6_b_pins[] = { + /* CS */ + 93, +}; +static const unsigned int bsc_cs6_b_mux[] = { + CS6B__MARK, +}; +static const unsigned int bsc_rd_pins[] = { + /* RD */ + 96, +}; +static const unsigned int bsc_rd_mux[] = { + RD__FSC_MARK, +}; +static const unsigned int bsc_rdwr_0_pins[] = { + /* RDWR */ + 91, +}; +static const unsigned int bsc_rdwr_0_mux[] = { + PORT91_RDWR_MARK, +}; +static const unsigned int bsc_rdwr_1_pins[] = { + /* RDWR */ + 97, +}; +static const unsigned int bsc_rdwr_1_mux[] = { + RDWR_FWE_MARK, +}; +static const unsigned int bsc_rdwr_2_pins[] = { + /* RDWR */ + 149, +}; +static const unsigned int bsc_rdwr_2_mux[] = { + PORT149_RDWR_MARK, +}; +static const unsigned int bsc_we0_pins[] = { + /* WE0 */ + 97, +}; +static const unsigned int bsc_we0_mux[] = { + WE0__FWE_MARK, +}; +static const unsigned int bsc_we1_pins[] = { + /* WE1 */ + 98, +}; +static const unsigned int bsc_we1_mux[] = { + WE1__MARK, +}; /* - FSIA ------------------------------------------------------------------- */ static const unsigned int fsia_mclk_in_pins[] = { /* CK */ @@ -2817,6 +2911,19 @@ static const unsigned int sdhi2_ctrl_mux[] = { }; static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(bsc_data_0_7), + SH_PFC_PIN_GROUP(bsc_data_8_15), + SH_PFC_PIN_GROUP(bsc_cs4), + SH_PFC_PIN_GROUP(bsc_cs5_a), + SH_PFC_PIN_GROUP(bsc_cs5_b), + SH_PFC_PIN_GROUP(bsc_cs6_a), + SH_PFC_PIN_GROUP(bsc_cs6_b), + SH_PFC_PIN_GROUP(bsc_rd), + SH_PFC_PIN_GROUP(bsc_rdwr_0), + SH_PFC_PIN_GROUP(bsc_rdwr_1), + SH_PFC_PIN_GROUP(bsc_rdwr_2), + SH_PFC_PIN_GROUP(bsc_we0), + SH_PFC_PIN_GROUP(bsc_we1), SH_PFC_PIN_GROUP(fsia_mclk_in), SH_PFC_PIN_GROUP(fsia_mclk_out), SH_PFC_PIN_GROUP(fsia_sclk_in), @@ -2945,6 +3052,22 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi2_ctrl), }; +static const char * const bsc_groups[] = { + "bsc_data_0_7", + "bsc_data_8_15", + "bsc_cs4", + "bsc_cs5_a", + "bsc_cs5_b", + "bsc_cs6_a", + "bsc_cs6_b", + "bsc_rd", + "bsc_rdwr_0", + "bsc_rdwr_1", + "bsc_rdwr_2", + "bsc_we0", + "bsc_we1", +}; + static const char * const fsia_groups[] = { "fsia_mclk_in", "fsia_mclk_out", @@ -3137,6 +3260,7 @@ static const char * const sdhi2_groups[] = { }; static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(bsc), SH_PFC_FUNCTION(fsia), SH_PFC_FUNCTION(fsib), SH_PFC_FUNCTION(fsic), -- cgit From a6aa1c7b0ac6a57dac5855c64316057771f186e4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Mar 2013 01:55:08 +0100 Subject: sh-pfc: sh73a0: Add USB pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 76674af19d29..61c682aa38ef 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2909,6 +2909,14 @@ static const unsigned int sdhi2_ctrl_pins[] = { static const unsigned int sdhi2_ctrl_mux[] = { SDHICMD2_MARK, SDHICLK2_MARK, }; +/* - USB -------------------------------------------------------------------- */ +static const unsigned int usb_vbus_pins[] = { + /* VBUS */ + 0, +}; +static const unsigned int usb_vbus_mux[] = { + VBUS_0_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(bsc_data_0_7), @@ -3050,6 +3058,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi2_data1), SH_PFC_PIN_GROUP(sdhi2_data4), SH_PFC_PIN_GROUP(sdhi2_ctrl), + SH_PFC_PIN_GROUP(usb_vbus), }; static const char * const bsc_groups[] = { @@ -3259,6 +3268,10 @@ static const char * const sdhi2_groups[] = { "sdhi2_ctrl", }; +static const char * const usb_groups[] = { + "usb_vbus", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(bsc), SH_PFC_FUNCTION(fsia), @@ -3283,6 +3296,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(sdhi0), SH_PFC_FUNCTION(sdhi1), SH_PFC_FUNCTION(sdhi2), + SH_PFC_FUNCTION(usb), }; #define PINMUX_FN_BASE GPIO_FN_VBUS_0 -- cgit From 512b156cefb2931a483ff3dd25852d122230894a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Mar 2013 01:55:08 +0100 Subject: sh-pfc: sh73a0: Add IrDA pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 61c682aa38ef..8fc5eb0025c5 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2169,6 +2169,21 @@ static const unsigned int i2c3_2_pins[] = { static const unsigned int i2c3_2_mux[] = { PORT115_I2C_SCL3_MARK, PORT116_I2C_SDA3_MARK, }; +/* - IrDA ------------------------------------------------------------------- */ +static const unsigned int irda_0_pins[] = { + /* OUT, IN, FIRSEL */ + 241, 242, 243, +}; +static const unsigned int irda_0_mux[] = { + PORT241_IRDA_OUT_MARK, PORT242_IRDA_IN_MARK, PORT243_IRDA_FIRSEL_MARK, +}; +static const unsigned int irda_1_pins[] = { + /* OUT, IN, FIRSEL */ + 49, 53, 54, +}; +static const unsigned int irda_1_mux[] = { + PORT49_IRDA_OUT_MARK, PORT53_IRDA_IN_MARK, PORT54_IRDA_FIRSEL_MARK, +}; /* - KEYSC ------------------------------------------------------------------ */ static const unsigned int keysc_in5_pins[] = { /* KEYIN[0:4] */ @@ -2963,6 +2978,8 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(i2c3_0), SH_PFC_PIN_GROUP(i2c3_1), SH_PFC_PIN_GROUP(i2c3_2), + SH_PFC_PIN_GROUP(irda_0), + SH_PFC_PIN_GROUP(irda_1), SH_PFC_PIN_GROUP(keysc_in5), SH_PFC_PIN_GROUP(keysc_in6), SH_PFC_PIN_GROUP(keysc_in7), @@ -3125,6 +3142,11 @@ static const char * const i2c3_groups[] = { "i2c3_2", }; +static const char * const irda_groups[] = { + "irda_0", + "irda_1", +}; + static const char * const keysc_groups[] = { "keysc_in5", "keysc_in6", @@ -3280,6 +3302,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(fsid), SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(irda), SH_PFC_FUNCTION(keysc), SH_PFC_FUNCTION(lcd), SH_PFC_FUNCTION(lcd2), -- cgit From 06c7dd866da70f6c324ae3990b2c0d77fb2d07f5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: r8a7740: Add LCDC0 and LCDC1 pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 276 +++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index de13348be5c0..e16ec10b7dc1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -1658,6 +1658,277 @@ static struct sh_pfc_pin pinmux_pins[] = { GPIO_PORT_ALL(), }; +/* - LCD0 ------------------------------------------------------------------- */ +static const unsigned int lcd0_data8_pins[] = { + /* D[0:7] */ + 58, 57, 56, 55, 54, 53, 52, 51, +}; +static const unsigned int lcd0_data8_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, +}; +static const unsigned int lcd0_data9_pins[] = { + /* D[0:8] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, +}; +static const unsigned int lcd0_data9_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, +}; +static const unsigned int lcd0_data12_pins[] = { + /* D[0:11] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, 49, 48, 47, +}; +static const unsigned int lcd0_data12_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, +}; +static const unsigned int lcd0_data16_pins[] = { + /* D[0:15] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, +}; +static const unsigned int lcd0_data16_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, + LCD0_D12_MARK, LCD0_D13_MARK, LCD0_D14_MARK, LCD0_D15_MARK, +}; +static const unsigned int lcd0_data18_pins[] = { + /* D[0:17] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, + 42, 41, +}; +static const unsigned int lcd0_data18_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, + LCD0_D12_MARK, LCD0_D13_MARK, LCD0_D14_MARK, LCD0_D15_MARK, + LCD0_D16_MARK, LCD0_D17_MARK, +}; +static const unsigned int lcd0_data24_0_pins[] = { + /* D[0:23] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, + 42, 41, 40, 4, 3, 2, 0, 1, +}; +static const unsigned int lcd0_data24_0_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, + LCD0_D12_MARK, LCD0_D13_MARK, LCD0_D14_MARK, LCD0_D15_MARK, + LCD0_D16_MARK, LCD0_D17_MARK, LCD0_D18_PORT40_MARK, LCD0_D19_PORT4_MARK, + LCD0_D20_PORT3_MARK, LCD0_D21_PORT2_MARK, LCD0_D22_PORT0_MARK, + LCD0_D23_PORT1_MARK, +}; +static const unsigned int lcd0_data24_1_pins[] = { + /* D[0:23] */ + 58, 57, 56, 55, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, + 42, 41, 163, 162, 161, 158, 160, 159, +}; +static const unsigned int lcd0_data24_1_mux[] = { + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, + LCD0_D16_MARK, LCD0_D17_MARK, LCD0_D18_PORT163_MARK, + LCD0_D19_PORT162_MARK, LCD0_D20_PORT161_MARK, LCD0_D21_PORT158_MARK, + LCD0_D22_PORT160_MARK, LCD0_D23_PORT159_MARK, +}; +static const unsigned int lcd0_display_pins[] = { + /* DON, VCPWC, VEPWC */ + 61, 59, 60, +}; +static const unsigned int lcd0_display_mux[] = { + LCD0_DON_MARK, LCD0_VCPWC_MARK, LCD0_VEPWC_MARK, +}; +static const unsigned int lcd0_lclk_0_pins[] = { + /* LCLK */ + 102, +}; +static const unsigned int lcd0_lclk_0_mux[] = { + LCD0_LCLK_PORT102_MARK, +}; +static const unsigned int lcd0_lclk_1_pins[] = { + /* LCLK */ + 165, +}; +static const unsigned int lcd0_lclk_1_mux[] = { + LCD0_LCLK_PORT165_MARK, +}; +static const unsigned int lcd0_sync_pins[] = { + /* VSYN, HSYN, DCK, DISP */ + 63, 64, 62, 65, +}; +static const unsigned int lcd0_sync_mux[] = { + LCD0_VSYN_MARK, LCD0_HSYN_MARK, LCD0_DCK_MARK, LCD0_DISP_MARK, +}; +static const unsigned int lcd0_sys_pins[] = { + /* CS, WR, RD, RS */ + 64, 62, 164, 65, +}; +static const unsigned int lcd0_sys_mux[] = { + LCD0_CS_MARK, LCD0_WR_MARK, LCD0_RD_MARK, LCD0_RS_MARK, +}; +/* - LCD1 ------------------------------------------------------------------- */ +static const unsigned int lcd1_data8_pins[] = { + /* D[0:7] */ + 4, 3, 2, 1, 0, 91, 92, 23, +}; +static const unsigned int lcd1_data8_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, +}; +static const unsigned int lcd1_data9_pins[] = { + /* D[0:8] */ + 4, 3, 2, 1, 0, 91, 92, 23, + 93, +}; +static const unsigned int lcd1_data9_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, +}; +static const unsigned int lcd1_data12_pins[] = { + /* D[0:12] */ + 4, 3, 2, 1, 0, 91, 92, 23, + 93, 94, 21, 201, +}; +static const unsigned int lcd1_data12_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK, +}; +static const unsigned int lcd1_data16_pins[] = { + /* D[0:15] */ + 4, 3, 2, 1, 0, 91, 92, 23, + 93, 94, 21, 201, 200, 199, 196, 195, +}; +static const unsigned int lcd1_data16_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK, + LCD1_D12_MARK, LCD1_D13_MARK, LCD1_D14_MARK, LCD1_D15_MARK, +}; +static const unsigned int lcd1_data18_pins[] = { + /* D[0:17] */ + 4, 3, 2, 1, 0, 91, 92, 23, + 93, 94, 21, 201, 200, 199, 196, 195, + 194, 193, +}; +static const unsigned int lcd1_data18_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK, + LCD1_D12_MARK, LCD1_D13_MARK, LCD1_D14_MARK, LCD1_D15_MARK, + LCD1_D16_MARK, LCD1_D17_MARK, +}; +static const unsigned int lcd1_data24_pins[] = { + /* D[0:23] */ + 4, 3, 2, 1, 0, 91, 92, 23, + 93, 94, 21, 201, 200, 199, 196, 195, + 194, 193, 198, 197, 75, 74, 15, 14, +}; +static const unsigned int lcd1_data24_mux[] = { + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK, + LCD1_D12_MARK, LCD1_D13_MARK, LCD1_D14_MARK, LCD1_D15_MARK, + LCD1_D16_MARK, LCD1_D17_MARK, LCD1_D18_MARK, LCD1_D19_MARK, + LCD1_D20_MARK, LCD1_D21_MARK, LCD1_D22_MARK, LCD1_D23_MARK, +}; +static const unsigned int lcd1_display_pins[] = { + /* DON, VCPWC, VEPWC */ + 100, 5, 6, +}; +static const unsigned int lcd1_display_mux[] = { + LCD1_DON_MARK, LCD1_VCPWC_MARK, LCD1_VEPWC_MARK, +}; +static const unsigned int lcd1_lclk_pins[] = { + /* LCLK */ + 40, +}; +static const unsigned int lcd1_lclk_mux[] = { + LCD1_LCLK_MARK, +}; +static const unsigned int lcd1_sync_pins[] = { + /* VSYN, HSYN, DCK, DISP */ + 98, 97, 99, 12, +}; +static const unsigned int lcd1_sync_mux[] = { + LCD1_VSYN_MARK, LCD1_HSYN_MARK, LCD1_DCK_MARK, LCD1_DISP_MARK, +}; +static const unsigned int lcd1_sys_pins[] = { + /* CS, WR, RD, RS */ + 97, 99, 13, 12, +}; +static const unsigned int lcd1_sys_mux[] = { + LCD1_CS_MARK, LCD1_WR_MARK, LCD1_RD_MARK, LCD1_RS_MARK, +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(lcd0_data8), + SH_PFC_PIN_GROUP(lcd0_data9), + SH_PFC_PIN_GROUP(lcd0_data12), + SH_PFC_PIN_GROUP(lcd0_data16), + SH_PFC_PIN_GROUP(lcd0_data18), + SH_PFC_PIN_GROUP(lcd0_data24_0), + SH_PFC_PIN_GROUP(lcd0_data24_1), + SH_PFC_PIN_GROUP(lcd0_display), + SH_PFC_PIN_GROUP(lcd0_lclk_0), + SH_PFC_PIN_GROUP(lcd0_lclk_1), + SH_PFC_PIN_GROUP(lcd0_sync), + SH_PFC_PIN_GROUP(lcd0_sys), + SH_PFC_PIN_GROUP(lcd1_data8), + SH_PFC_PIN_GROUP(lcd1_data9), + SH_PFC_PIN_GROUP(lcd1_data12), + SH_PFC_PIN_GROUP(lcd1_data16), + SH_PFC_PIN_GROUP(lcd1_data18), + SH_PFC_PIN_GROUP(lcd1_data24), + SH_PFC_PIN_GROUP(lcd1_display), + SH_PFC_PIN_GROUP(lcd1_lclk), + SH_PFC_PIN_GROUP(lcd1_sync), + SH_PFC_PIN_GROUP(lcd1_sys), +}; + +static const char * const lcd0_groups[] = { + "lcd0_data8", + "lcd0_data9", + "lcd0_data12", + "lcd0_data16", + "lcd0_data18", + "lcd0_data24_0", + "lcd0_data24_1", + "lcd0_display", + "lcd0_lclk_0", + "lcd0_lclk_1", + "lcd0_sync", + "lcd0_sys", +}; + +static const char * const lcd1_groups[] = { + "lcd1_data8", + "lcd1_data9", + "lcd1_data12", + "lcd1_data16", + "lcd1_data18", + "lcd1_data24", + "lcd1_display", + "lcd1_lclk", + "lcd1_sync", + "lcd1_sys", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(lcd0), + SH_PFC_FUNCTION(lcd1), +}; + #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) static const struct pinmux_func pinmux_func_gpios[] = { @@ -2596,6 +2867,11 @@ const struct sh_pfc_soc_info r8a7740_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + .func_gpios = pinmux_func_gpios, .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), -- cgit From 8b2810b9578612e093420a8c9d56d2e83e3c9496 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 23 Jan 2013 17:37:44 +0100 Subject: sh-pfc: r8a7740: Add SDHI and MMCIF pin groups and functions Add pin groups for the first two SDHI interfaces and two alternative pin groups for the MMCIF interface on the r8a7740 SoC. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 248 +++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index e16ec10b7dc1..a2f909a7c235 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -1870,6 +1870,188 @@ static const unsigned int lcd1_sys_pins[] = { static const unsigned int lcd1_sys_mux[] = { LCD1_CS_MARK, LCD1_WR_MARK, LCD1_RD_MARK, LCD1_RS_MARK, }; +/* - MMCIF ------------------------------------------------------------------ */ +static const unsigned int mmc0_data1_0_pins[] = { + /* D[0] */ + 68, +}; +static const unsigned int mmc0_data1_0_mux[] = { + MMC0_D0_PORT68_MARK, +}; +static const unsigned int mmc0_data4_0_pins[] = { + /* D[0:3] */ + 68, 69, 70, 71, +}; +static const unsigned int mmc0_data4_0_mux[] = { + MMC0_D0_PORT68_MARK, MMC0_D1_PORT69_MARK, MMC0_D2_PORT70_MARK, MMC0_D3_PORT71_MARK, +}; +static const unsigned int mmc0_data8_0_pins[] = { + /* D[0:7] */ + 68, 69, 70, 71, 72, 73, 74, 75, +}; +static const unsigned int mmc0_data8_0_mux[] = { + MMC0_D0_PORT68_MARK, MMC0_D1_PORT69_MARK, MMC0_D2_PORT70_MARK, MMC0_D3_PORT71_MARK, + MMC0_D4_PORT72_MARK, MMC0_D5_PORT73_MARK, MMC0_D6_PORT74_MARK, MMC0_D7_PORT75_MARK, +}; +static const unsigned int mmc0_ctrl_0_pins[] = { + /* CMD, CLK */ + 67, 66, +}; +static const unsigned int mmc0_ctrl_0_mux[] = { + MMC0_CMD_PORT67_MARK, MMC0_CLK_PORT66_MARK, +}; + +static const unsigned int mmc0_data1_1_pins[] = { + /* D[0] */ + 149, +}; +static const unsigned int mmc0_data1_1_mux[] = { + MMC1_D0_PORT149_MARK, +}; +static const unsigned int mmc0_data4_1_pins[] = { + /* D[0:3] */ + 149, 148, 147, 146, +}; +static const unsigned int mmc0_data4_1_mux[] = { + MMC1_D0_PORT149_MARK, MMC1_D1_PORT148_MARK, MMC1_D2_PORT147_MARK, MMC1_D3_PORT146_MARK, +}; +static const unsigned int mmc0_data8_1_pins[] = { + /* D[0:7] */ + 149, 148, 147, 146, 145, 144, 143, 142, +}; +static const unsigned int mmc0_data8_1_mux[] = { + MMC1_D0_PORT149_MARK, MMC1_D1_PORT148_MARK, MMC1_D2_PORT147_MARK, MMC1_D3_PORT146_MARK, + MMC1_D4_PORT145_MARK, MMC1_D5_PORT144_MARK, MMC1_D6_PORT143_MARK, MMC1_D7_PORT142_MARK, +}; +static const unsigned int mmc0_ctrl_1_pins[] = { + /* CMD, CLK */ + 104, 103, +}; +static const unsigned int mmc0_ctrl_1_mux[] = { + MMC1_CMD_PORT104_MARK, MMC1_CLK_PORT103_MARK, +}; +/* - SDHI0 ------------------------------------------------------------------ */ +static const unsigned int sdhi0_data1_pins[] = { + /* D0 */ + 77, +}; +static const unsigned int sdhi0_data1_mux[] = { + SDHI0_D0_MARK, +}; +static const unsigned int sdhi0_data4_pins[] = { + /* D[0:3] */ + 77, 78, 79, 80, +}; +static const unsigned int sdhi0_data4_mux[] = { + SDHI0_D0_MARK, SDHI0_D1_MARK, SDHI0_D2_MARK, SDHI0_D3_MARK, +}; +static const unsigned int sdhi0_ctrl_pins[] = { + /* CMD, CLK */ + 76, 82, +}; +static const unsigned int sdhi0_ctrl_mux[] = { + SDHI0_CMD_MARK, SDHI0_CLK_MARK, +}; +static const unsigned int sdhi0_cd_pins[] = { + /* CD */ + 81, +}; +static const unsigned int sdhi0_cd_mux[] = { + SDHI0_CD_MARK, +}; +static const unsigned int sdhi0_wp_pins[] = { + /* WP */ + 83, +}; +static const unsigned int sdhi0_wp_mux[] = { + SDHI0_WP_MARK, +}; +/* - SDHI1 ------------------------------------------------------------------ */ +static const unsigned int sdhi1_data1_pins[] = { + /* D0 */ + 68, +}; +static const unsigned int sdhi1_data1_mux[] = { + SDHI1_D0_MARK, +}; +static const unsigned int sdhi1_data4_pins[] = { + /* D[0:3] */ + 68, 69, 70, 71, +}; +static const unsigned int sdhi1_data4_mux[] = { + SDHI1_D0_MARK, SDHI1_D1_MARK, SDHI1_D2_MARK, SDHI1_D3_MARK, +}; +static const unsigned int sdhi1_ctrl_pins[] = { + /* CMD, CLK */ + 67, 66, +}; +static const unsigned int sdhi1_ctrl_mux[] = { + SDHI1_CMD_MARK, SDHI1_CLK_MARK, +}; +static const unsigned int sdhi1_cd_pins[] = { + /* CD */ + 72, +}; +static const unsigned int sdhi1_cd_mux[] = { + SDHI1_CD_MARK, +}; +static const unsigned int sdhi1_wp_pins[] = { + /* WP */ + 73, +}; +static const unsigned int sdhi1_wp_mux[] = { + SDHI1_WP_MARK, +}; +/* - SDHI2 ------------------------------------------------------------------ */ +static const unsigned int sdhi2_data1_pins[] = { + /* D0 */ + 205, +}; +static const unsigned int sdhi2_data1_mux[] = { + SDHI2_D0_MARK, +}; +static const unsigned int sdhi2_data4_pins[] = { + /* D[0:3] */ + 205, 206, 207, 208, +}; +static const unsigned int sdhi2_data4_mux[] = { + SDHI2_D0_MARK, SDHI2_D1_MARK, SDHI2_D2_MARK, SDHI2_D3_MARK, +}; +static const unsigned int sdhi2_ctrl_pins[] = { + /* CMD, CLK */ + 204, 203, +}; +static const unsigned int sdhi2_ctrl_mux[] = { + SDHI2_CMD_MARK, SDHI2_CLK_MARK, +}; +static const unsigned int sdhi2_cd_0_pins[] = { + /* CD */ + 202, +}; +static const unsigned int sdhi2_cd_0_mux[] = { + SDHI2_CD_PORT202_MARK, +}; +static const unsigned int sdhi2_wp_0_pins[] = { + /* WP */ + 177, +}; +static const unsigned int sdhi2_wp_0_mux[] = { + SDHI2_WP_PORT177_MARK, +}; +static const unsigned int sdhi2_cd_1_pins[] = { + /* CD */ + 24, +}; +static const unsigned int sdhi2_cd_1_mux[] = { + SDHI2_CD_PORT24_MARK, +}; +static const unsigned int sdhi2_wp_1_pins[] = { + /* WP */ + 25, +}; +static const unsigned int sdhi2_wp_1_mux[] = { + SDHI2_WP_PORT25_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(lcd0_data8), @@ -1894,6 +2076,31 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(lcd1_lclk), SH_PFC_PIN_GROUP(lcd1_sync), SH_PFC_PIN_GROUP(lcd1_sys), + SH_PFC_PIN_GROUP(mmc0_data1_0), + SH_PFC_PIN_GROUP(mmc0_data4_0), + SH_PFC_PIN_GROUP(mmc0_data8_0), + SH_PFC_PIN_GROUP(mmc0_ctrl_0), + SH_PFC_PIN_GROUP(mmc0_data1_1), + SH_PFC_PIN_GROUP(mmc0_data4_1), + SH_PFC_PIN_GROUP(mmc0_data8_1), + SH_PFC_PIN_GROUP(mmc0_ctrl_1), + SH_PFC_PIN_GROUP(sdhi0_data1), + SH_PFC_PIN_GROUP(sdhi0_data4), + SH_PFC_PIN_GROUP(sdhi0_ctrl), + SH_PFC_PIN_GROUP(sdhi0_cd), + SH_PFC_PIN_GROUP(sdhi0_wp), + SH_PFC_PIN_GROUP(sdhi1_data1), + SH_PFC_PIN_GROUP(sdhi1_data4), + SH_PFC_PIN_GROUP(sdhi1_ctrl), + SH_PFC_PIN_GROUP(sdhi1_cd), + SH_PFC_PIN_GROUP(sdhi1_wp), + SH_PFC_PIN_GROUP(sdhi2_data1), + SH_PFC_PIN_GROUP(sdhi2_data4), + SH_PFC_PIN_GROUP(sdhi2_ctrl), + SH_PFC_PIN_GROUP(sdhi2_cd_0), + SH_PFC_PIN_GROUP(sdhi2_wp_0), + SH_PFC_PIN_GROUP(sdhi2_cd_1), + SH_PFC_PIN_GROUP(sdhi2_wp_1), }; static const char * const lcd0_groups[] = { @@ -1924,9 +2131,50 @@ static const char * const lcd1_groups[] = { "lcd1_sys", }; +static const char * const mmc0_groups[] = { + "mmc0_data1_0", + "mmc0_data4_0", + "mmc0_data8_0", + "mmc0_ctrl_0", + "mmc0_data1_1", + "mmc0_data4_1", + "mmc0_data8_1", + "mmc0_ctrl_1", +}; + +static const char * const sdhi0_groups[] = { + "sdhi0_data1", + "sdhi0_data4", + "sdhi0_ctrl", + "sdhi0_cd", + "sdhi0_wp", +}; + +static const char * const sdhi1_groups[] = { + "sdhi1_data1", + "sdhi1_data4", + "sdhi1_ctrl", + "sdhi1_cd", + "sdhi1_wp", +}; + +static const char * const sdhi2_groups[] = { + "sdhi2_data1", + "sdhi2_data4", + "sdhi2_ctrl", + "sdhi2_cd_0", + "sdhi2_wp_0", + "sdhi2_cd_1", + "sdhi2_wp_1", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(lcd0), SH_PFC_FUNCTION(lcd1), + SH_PFC_FUNCTION(mmc0), + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), }; #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -- cgit From e8ebafdfea399580b1bee7e83b955c6175b8a6c4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: r8a7779: Add DU pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 283 +++++++++++++++++++++++++++++------ 1 file changed, 236 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index eb5685848b68..9046a8f71d49 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1436,6 +1436,190 @@ static struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), }; +/* - DU0 -------------------------------------------------------------------- */ +static const unsigned int du0_rgb666_pins[] = { + /* R[7:2], G[7:2], B[7:2] */ + 188, 187, 186, 185, 184, 183, + 194, 193, 192, 191, 190, 189, + 200, 199, 198, 197, 196, 195, +}; +static const unsigned int du0_rgb666_mux[] = { + DU0_DR7_MARK, DU0_DR6_MARK, DU0_DR5_MARK, DU0_DR4_MARK, + DU0_DR3_MARK, DU0_DR2_MARK, + DU0_DG7_MARK, DU0_DG6_MARK, DU0_DG5_MARK, DU0_DG4_MARK, + DU0_DG3_MARK, DU0_DG2_MARK, + DU0_DB7_MARK, DU0_DB6_MARK, DU0_DB5_MARK, DU0_DB4_MARK, + DU0_DB3_MARK, DU0_DB2_MARK, +}; +static const unsigned int du0_rgb888_pins[] = { + /* R[7:0], G[7:0], B[7:0] */ + 188, 187, 186, 185, 184, 183, 24, 23, + 194, 193, 192, 191, 190, 189, 26, 25, + 200, 199, 198, 197, 196, 195, 28, 27, +}; +static const unsigned int du0_rgb888_mux[] = { + DU0_DR7_MARK, DU0_DR6_MARK, DU0_DR5_MARK, DU0_DR4_MARK, + DU0_DR3_MARK, DU0_DR2_MARK, DU0_DR1_MARK, DU0_DR0_MARK, + DU0_DG7_MARK, DU0_DG6_MARK, DU0_DG5_MARK, DU0_DG4_MARK, + DU0_DG3_MARK, DU0_DG2_MARK, DU0_DG1_MARK, DU0_DG0_MARK, + DU0_DB7_MARK, DU0_DB6_MARK, DU0_DB5_MARK, DU0_DB4_MARK, + DU0_DB3_MARK, DU0_DB2_MARK, DU0_DB1_MARK, DU0_DB0_MARK, +}; +static const unsigned int du0_clk_0_pins[] = { + /* CLKIN, CLKOUT */ + 29, 180, +}; +static const unsigned int du0_clk_0_mux[] = { + DU0_DOTCLKIN_MARK, DU0_DOTCLKOUT0_MARK, +}; +static const unsigned int du0_clk_1_pins[] = { + /* CLKIN, CLKOUT */ + 29, 30, +}; +static const unsigned int du0_clk_1_mux[] = { + DU0_DOTCLKIN_MARK, DU0_DOTCLKOUT1_MARK, +}; +static const unsigned int du0_sync_0_pins[] = { + /* VSYNC, HSYNC, DISP */ + 182, 181, 31, +}; +static const unsigned int du0_sync_0_mux[] = { + DU0_EXHSYNC_DU0_HSYNC_MARK, DU0_EXVSYNC_DU0_VSYNC_MARK, + DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK +}; +static const unsigned int du0_sync_1_pins[] = { + /* VSYNC, HSYNC, DISP */ + 182, 181, 32, +}; +static const unsigned int du0_sync_1_mux[] = { + DU0_EXHSYNC_DU0_HSYNC_MARK, DU0_EXVSYNC_DU0_VSYNC_MARK, + DU0_DISP_MARK +}; +static const unsigned int du0_oddf_pins[] = { + /* ODDF */ + 31, +}; +static const unsigned int du0_oddf_mux[] = { + DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK +}; +static const unsigned int du0_cde_pins[] = { + /* CDE */ + 33, +}; +static const unsigned int du0_cde_mux[] = { + DU0_CDE_MARK +}; +/* - DU1 -------------------------------------------------------------------- */ +static const unsigned int du1_rgb666_pins[] = { + /* R[7:2], G[7:2], B[7:2] */ + 41, 40, 39, 38, 37, 36, + 49, 48, 47, 46, 45, 44, + 57, 56, 55, 54, 53, 52, +}; +static const unsigned int du1_rgb666_mux[] = { + DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, + DU1_DR3_MARK, DU1_DR2_MARK, + DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, + DU1_DG3_MARK, DU1_DG2_MARK, + DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, + DU1_DB3_MARK, DU1_DB2_MARK, +}; +static const unsigned int du1_rgb888_pins[] = { + /* R[7:0], G[7:0], B[7:0] */ + 41, 40, 39, 38, 37, 36, 35, 34, + 49, 48, 47, 46, 45, 44, 43, 32, + 57, 56, 55, 54, 53, 52, 51, 50, +}; +static const unsigned int du1_rgb888_mux[] = { + DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, + DU1_DR3_MARK, DU1_DR2_MARK, DU1_DR1_MARK, DU1_DR0_MARK, + DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, + DU1_DG3_MARK, DU1_DG2_MARK, DU1_DG1_MARK, DU1_DG0_MARK, + DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, + DU1_DB3_MARK, DU1_DB2_MARK, DU1_DB1_MARK, DU1_DB0_MARK, +}; +static const unsigned int du1_clk_pins[] = { + /* CLKIN, CLKOUT */ + 58, 59, +}; +static const unsigned int du1_clk_mux[] = { + DU1_DOTCLKIN_MARK, DU1_DOTCLKOUT_MARK, +}; +static const unsigned int du1_sync_0_pins[] = { + /* VSYNC, HSYNC, DISP */ + 61, 60, 62, +}; +static const unsigned int du1_sync_0_mux[] = { + DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK, + DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK +}; +static const unsigned int du1_sync_1_pins[] = { + /* VSYNC, HSYNC, DISP */ + 61, 60, 63, +}; +static const unsigned int du1_sync_1_mux[] = { + DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK, + DU1_DISP_MARK +}; +static const unsigned int du1_oddf_pins[] = { + /* ODDF */ + 62, +}; +static const unsigned int du1_oddf_mux[] = { + DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK +}; +static const unsigned int du1_cde_pins[] = { + /* CDE */ + 64, +}; +static const unsigned int du1_cde_mux[] = { + DU1_CDE_MARK +}; + +static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(du0_rgb666), + SH_PFC_PIN_GROUP(du0_rgb888), + SH_PFC_PIN_GROUP(du0_clk_0), + SH_PFC_PIN_GROUP(du0_clk_1), + SH_PFC_PIN_GROUP(du0_sync_0), + SH_PFC_PIN_GROUP(du0_sync_1), + SH_PFC_PIN_GROUP(du0_oddf), + SH_PFC_PIN_GROUP(du0_cde), + SH_PFC_PIN_GROUP(du1_rgb666), + SH_PFC_PIN_GROUP(du1_rgb888), + SH_PFC_PIN_GROUP(du1_clk), + SH_PFC_PIN_GROUP(du1_sync_0), + SH_PFC_PIN_GROUP(du1_sync_1), + SH_PFC_PIN_GROUP(du1_oddf), + SH_PFC_PIN_GROUP(du1_cde), +}; + +static const char * const du0_groups[] = { + "du0_rgb666", + "du0_rgb888", + "du0_clk_0", + "du0_clk_1", + "du0_sync_0", + "du0_sync_1", + "du0_oddf", + "du0_cde", +}; + +static const char * const du1_groups[] = { + "du1_rgb666", + "du1_rgb888", + "du1_clk", + "du1_sync_0", + "du1_sync_1", + "du1_oddf", + "du1_cde", +}; + +static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(du0), + SH_PFC_FUNCTION(du1), +}; + #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) static const struct pinmux_func pinmux_func_gpios[] = { @@ -1494,79 +1678,79 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CC5_OSCOUT), GPIO_FN(HRTS0), GPIO_FN(RTS1_TANS), GPIO_FN(MDATA), GPIO_FN(TX0_C), GPIO_FN(SUB_TMS), GPIO_FN(CC5_STATE1), GPIO_FN(CC5_STATE9), GPIO_FN(CC5_STATE17), GPIO_FN(CC5_STATE25), - GPIO_FN(CC5_STATE33), GPIO_FN(DU0_DR0), GPIO_FN(LCDOUT0), + GPIO_FN(CC5_STATE33), GPIO_FN(LCDOUT0), GPIO_FN(DREQ0), GPIO_FN(GPS_CLK_B), GPIO_FN(AUDATA0), - GPIO_FN(TX5_C), GPIO_FN(DU0_DR1), GPIO_FN(LCDOUT1), GPIO_FN(DACK0), + GPIO_FN(TX5_C), GPIO_FN(LCDOUT1), GPIO_FN(DACK0), GPIO_FN(DRACK0), GPIO_FN(GPS_SIGN_B), GPIO_FN(AUDATA1), GPIO_FN(RX5_C), - GPIO_FN(DU0_DR2), GPIO_FN(LCDOUT2), GPIO_FN(DU0_DR3), GPIO_FN(LCDOUT3), - GPIO_FN(DU0_DR4), GPIO_FN(LCDOUT4), GPIO_FN(DU0_DR5), GPIO_FN(LCDOUT5), - GPIO_FN(DU0_DR6), GPIO_FN(LCDOUT6), GPIO_FN(DU0_DR7), GPIO_FN(LCDOUT7), - GPIO_FN(DU0_DG0), GPIO_FN(LCDOUT8), GPIO_FN(DREQ1), GPIO_FN(SCL2), + GPIO_FN(LCDOUT2), GPIO_FN(LCDOUT3), + GPIO_FN(LCDOUT4), GPIO_FN(LCDOUT5), + GPIO_FN(LCDOUT6), GPIO_FN(LCDOUT7), + GPIO_FN(LCDOUT8), GPIO_FN(DREQ1), GPIO_FN(SCL2), GPIO_FN(AUDATA2), /* IPSR3 */ - GPIO_FN(DU0_DG1), GPIO_FN(LCDOUT9), GPIO_FN(DACK1), GPIO_FN(SDA2), - GPIO_FN(AUDATA3), GPIO_FN(DU0_DG2), GPIO_FN(LCDOUT10), - GPIO_FN(DU0_DG3), GPIO_FN(LCDOUT11), GPIO_FN(DU0_DG4), - GPIO_FN(LCDOUT12), GPIO_FN(DU0_DG5), GPIO_FN(LCDOUT13), - GPIO_FN(DU0_DG6), GPIO_FN(LCDOUT14), GPIO_FN(DU0_DG7), - GPIO_FN(LCDOUT15), GPIO_FN(DU0_DB0), GPIO_FN(LCDOUT16), + GPIO_FN(LCDOUT9), GPIO_FN(DACK1), GPIO_FN(SDA2), + GPIO_FN(AUDATA3), GPIO_FN(LCDOUT10), + GPIO_FN(LCDOUT11), + GPIO_FN(LCDOUT12), GPIO_FN(LCDOUT13), + GPIO_FN(LCDOUT14), + GPIO_FN(LCDOUT15), GPIO_FN(LCDOUT16), GPIO_FN(EX_WAIT1), GPIO_FN(SCL1), GPIO_FN(TCLK1), GPIO_FN(AUDATA4), - GPIO_FN(DU0_DB1), GPIO_FN(LCDOUT17), GPIO_FN(EX_WAIT2), GPIO_FN(SDA1), + GPIO_FN(LCDOUT17), GPIO_FN(EX_WAIT2), GPIO_FN(SDA1), GPIO_FN(GPS_MAG_B), GPIO_FN(AUDATA5), GPIO_FN(SCK5_C), - GPIO_FN(DU0_DB2), GPIO_FN(LCDOUT18), GPIO_FN(DU0_DB3), - GPIO_FN(LCDOUT19), GPIO_FN(DU0_DB4), GPIO_FN(LCDOUT20), - GPIO_FN(DU0_DB5), GPIO_FN(LCDOUT21), GPIO_FN(DU0_DB6), - GPIO_FN(LCDOUT22), GPIO_FN(DU0_DB7), GPIO_FN(LCDOUT23), - GPIO_FN(DU0_DOTCLKIN), GPIO_FN(QSTVA_QVS), GPIO_FN(TX3_D_IRDA_TX_D), - GPIO_FN(SCL3_B), GPIO_FN(DU0_DOTCLKOUT0), GPIO_FN(QCLK), - GPIO_FN(DU0_DOTCLKOUT1), GPIO_FN(QSTVB_QVE), GPIO_FN(RX3_D_IRDA_RX_D), + GPIO_FN(LCDOUT18), + GPIO_FN(LCDOUT19), GPIO_FN(LCDOUT20), + GPIO_FN(LCDOUT21), + GPIO_FN(LCDOUT22), GPIO_FN(LCDOUT23), + GPIO_FN(QSTVA_QVS), GPIO_FN(TX3_D_IRDA_TX_D), + GPIO_FN(SCL3_B), GPIO_FN(QCLK), + GPIO_FN(QSTVB_QVE), GPIO_FN(RX3_D_IRDA_RX_D), GPIO_FN(SDA3_B), GPIO_FN(SDA2_C), GPIO_FN(DACK0_B), GPIO_FN(DRACK0_B), - GPIO_FN(DU0_EXHSYNC_DU0_HSYNC), GPIO_FN(QSTH_QHS), - GPIO_FN(DU0_EXVSYNC_DU0_VSYNC), GPIO_FN(QSTB_QHE), - GPIO_FN(DU0_EXODDF_DU0_ODDF_DISP_CDE), GPIO_FN(QCPV_QDE), + GPIO_FN(QSTH_QHS), + GPIO_FN(QSTB_QHE), + GPIO_FN(QCPV_QDE), GPIO_FN(CAN1_TX), GPIO_FN(TX2_C), GPIO_FN(SCL2_C), GPIO_FN(REMOCON), /* IPSR4 */ - GPIO_FN(DU0_DISP), GPIO_FN(QPOLA), GPIO_FN(CAN_CLK_C), GPIO_FN(SCK2_C), - GPIO_FN(DU0_CDE), GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), GPIO_FN(RX2_C), + GPIO_FN(QPOLA), GPIO_FN(CAN_CLK_C), GPIO_FN(SCK2_C), + GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), GPIO_FN(RX2_C), GPIO_FN(DREQ0_B), GPIO_FN(SSI_SCK78_B), GPIO_FN(SCK0_B), - GPIO_FN(DU1_DR0), GPIO_FN(VI2_DATA0_VI2_B0), GPIO_FN(PWM6), + GPIO_FN(VI2_DATA0_VI2_B0), GPIO_FN(PWM6), GPIO_FN(SD3_CLK), GPIO_FN(TX3_E_IRDA_TX_E), GPIO_FN(AUDCK), - GPIO_FN(PWMFSW0_B), GPIO_FN(DU1_DR1), GPIO_FN(VI2_DATA1_VI2_B1), + GPIO_FN(PWMFSW0_B), GPIO_FN(VI2_DATA1_VI2_B1), GPIO_FN(PWM0), GPIO_FN(SD3_CMD), GPIO_FN(RX3_E_IRDA_RX_E), - GPIO_FN(AUDSYNC), GPIO_FN(CTS0_D), GPIO_FN(DU1_DR2), GPIO_FN(VI2_G0), - GPIO_FN(DU1_DR3), GPIO_FN(VI2_G1), GPIO_FN(DU1_DR4), GPIO_FN(VI2_G2), - GPIO_FN(DU1_DR5), GPIO_FN(VI2_G3), GPIO_FN(DU1_DR6), GPIO_FN(VI2_G4), - GPIO_FN(DU1_DR7), GPIO_FN(VI2_G5), GPIO_FN(DU1_DG0), + GPIO_FN(AUDSYNC), GPIO_FN(CTS0_D), GPIO_FN(VI2_G0), + GPIO_FN(VI2_G1), GPIO_FN(VI2_G2), + GPIO_FN(VI2_G3), GPIO_FN(VI2_G4), + GPIO_FN(VI2_G5), GPIO_FN(VI2_DATA2_VI2_B2), GPIO_FN(SCL1_B), GPIO_FN(SD3_DAT2), - GPIO_FN(SCK3_E), GPIO_FN(AUDATA6), GPIO_FN(TX0_D), GPIO_FN(DU1_DG1), + GPIO_FN(SCK3_E), GPIO_FN(AUDATA6), GPIO_FN(TX0_D), GPIO_FN(VI2_DATA3_VI2_B3), GPIO_FN(SDA1_B), GPIO_FN(SD3_DAT3), - GPIO_FN(SCK5), GPIO_FN(AUDATA7), GPIO_FN(RX0_D), GPIO_FN(DU1_DG2), - GPIO_FN(VI2_G6), GPIO_FN(DU1_DG3), GPIO_FN(VI2_G7), GPIO_FN(DU1_DG4), - GPIO_FN(VI2_R0), GPIO_FN(DU1_DG5), GPIO_FN(VI2_R1), GPIO_FN(DU1_DG6), - GPIO_FN(VI2_R2), GPIO_FN(DU1_DG7), GPIO_FN(VI2_R3), GPIO_FN(DU1_DB0), + GPIO_FN(SCK5), GPIO_FN(AUDATA7), GPIO_FN(RX0_D), + GPIO_FN(VI2_G6), GPIO_FN(VI2_G7), + GPIO_FN(VI2_R0), GPIO_FN(VI2_R1), + GPIO_FN(VI2_R2), GPIO_FN(VI2_R3), GPIO_FN(VI2_DATA4_VI2_B4), GPIO_FN(SCL2_B), GPIO_FN(SD3_DAT0), GPIO_FN(TX5), GPIO_FN(SCK0_D), /* IPSR5 */ - GPIO_FN(DU1_DB1), GPIO_FN(VI2_DATA5_VI2_B5), GPIO_FN(SDA2_B), + GPIO_FN(VI2_DATA5_VI2_B5), GPIO_FN(SDA2_B), GPIO_FN(SD3_DAT1), GPIO_FN(RX5), GPIO_FN(RTS0_D_TANS_D), - GPIO_FN(DU1_DB2), GPIO_FN(VI2_R4), GPIO_FN(DU1_DB3), GPIO_FN(VI2_R5), - GPIO_FN(DU1_DB4), GPIO_FN(VI2_R6), GPIO_FN(DU1_DB5), GPIO_FN(VI2_R7), - GPIO_FN(DU1_DB6), GPIO_FN(SCL2_D), GPIO_FN(DU1_DB7), GPIO_FN(SDA2_D), - GPIO_FN(DU1_DOTCLKIN), GPIO_FN(VI2_CLKENB), GPIO_FN(HSPI_CS1), - GPIO_FN(SCL1_D), GPIO_FN(DU1_DOTCLKOUT), GPIO_FN(VI2_FIELD), - GPIO_FN(SDA1_D), GPIO_FN(DU1_EXHSYNC_DU1_HSYNC), GPIO_FN(VI2_HSYNC), - GPIO_FN(VI3_HSYNC), GPIO_FN(DU1_EXVSYNC_DU1_VSYNC), GPIO_FN(VI2_VSYNC), - GPIO_FN(VI3_VSYNC), GPIO_FN(DU1_EXODDF_DU1_ODDF_DISP_CDE), + GPIO_FN(VI2_R4), GPIO_FN(VI2_R5), + GPIO_FN(VI2_R6), GPIO_FN(VI2_R7), + GPIO_FN(SCL2_D), GPIO_FN(SDA2_D), + GPIO_FN(VI2_CLKENB), GPIO_FN(HSPI_CS1), + GPIO_FN(SCL1_D), GPIO_FN(VI2_FIELD), + GPIO_FN(SDA1_D), GPIO_FN(VI2_HSYNC), + GPIO_FN(VI3_HSYNC), GPIO_FN(VI2_VSYNC), + GPIO_FN(VI3_VSYNC), GPIO_FN(VI2_CLK), GPIO_FN(TX3_B_IRDA_TX_B), GPIO_FN(SD3_CD), GPIO_FN(HSPI_TX1), GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB), GPIO_FN(AUDIO_CLKC), GPIO_FN(TX2_D), GPIO_FN(SPEEDIN), - GPIO_FN(GPS_SIGN_D), GPIO_FN(DU1_DISP), GPIO_FN(VI2_DATA6_VI2_B6), + GPIO_FN(GPS_SIGN_D), GPIO_FN(VI2_DATA6_VI2_B6), GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(HSPI_CLK1), GPIO_FN(SCK2_D), GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D), - GPIO_FN(DU1_CDE), GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(RX3_B_IRDA_RX_B), + GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(RX3_B_IRDA_RX_B), GPIO_FN(SD3_WP), GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD), GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(RX2_D), GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA), @@ -2598,6 +2782,11 @@ const struct sh_pfc_soc_info r8a7779_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups, + .nr_groups = ARRAY_SIZE(pinmux_groups), + .functions = pinmux_functions, + .nr_functions = ARRAY_SIZE(pinmux_functions), + .func_gpios = pinmux_func_gpios, .nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios), -- cgit From 6dbf296a452ff5c1613be989f4e3ce10568cf6df Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 19:04:43 +0100 Subject: sh-pfc: r8a7779: Add SDHI and MMCIF pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 284 +++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 9046a8f71d49..ca16b04edd6d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1575,6 +1575,210 @@ static const unsigned int du1_cde_pins[] = { static const unsigned int du1_cde_mux[] = { DU1_CDE_MARK }; +/* - MMCIF ------------------------------------------------------------------ */ +static const unsigned int mmc0_data1_pins[] = { + /* D[0] */ + 19, +}; +static const unsigned int mmc0_data1_mux[] = { + MMC0_D0_MARK, +}; +static const unsigned int mmc0_data4_pins[] = { + /* D[0:3] */ + 19, 20, 21, 2, +}; +static const unsigned int mmc0_data4_mux[] = { + MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK, +}; +static const unsigned int mmc0_data8_pins[] = { + /* D[0:7] */ + 19, 20, 21, 2, 10, 11, 15, 16, +}; +static const unsigned int mmc0_data8_mux[] = { + MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK, + MMC0_D4_MARK, MMC0_D5_MARK, MMC0_D6_MARK, MMC0_D7_MARK, +}; +static const unsigned int mmc0_ctrl_pins[] = { + /* CMD, CLK */ + 18, 17, +}; +static const unsigned int mmc0_ctrl_mux[] = { + MMC0_CMD_MARK, MMC0_CLK_MARK, +}; + +static const unsigned int mmc1_data1_pins[] = { + /* D[0] */ + 72, +}; +static const unsigned int mmc1_data1_mux[] = { + MMC1_D0_MARK, +}; +static const unsigned int mmc1_data4_pins[] = { + /* D[0:3] */ + 72, 73, 74, 75, +}; +static const unsigned int mmc1_data4_mux[] = { + MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK, +}; +static const unsigned int mmc1_data8_pins[] = { + /* D[0:7] */ + 72, 73, 74, 75, 76, 77, 80, 81, +}; +static const unsigned int mmc1_data8_mux[] = { + MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK, + MMC1_D4_MARK, MMC1_D5_MARK, MMC1_D6_MARK, MMC1_D7_MARK, +}; +static const unsigned int mmc1_ctrl_pins[] = { + /* CMD, CLK */ + 68, 65, +}; +static const unsigned int mmc1_ctrl_mux[] = { + MMC1_CMD_MARK, MMC1_CLK_MARK, +}; +/* - SDHI0 ------------------------------------------------------------------ */ +static const unsigned int sdhi0_data1_pins[] = { + /* D0 */ + 117, +}; +static const unsigned int sdhi0_data1_mux[] = { + SD0_DAT0_MARK, +}; +static const unsigned int sdhi0_data4_pins[] = { + /* D[0:3] */ + 117, 118, 119, 120, +}; +static const unsigned int sdhi0_data4_mux[] = { + SD0_DAT0_MARK, SD0_DAT1_MARK, SD0_DAT2_MARK, SD0_DAT3_MARK, +}; +static const unsigned int sdhi0_ctrl_pins[] = { + /* CMD, CLK */ + 114, 113, +}; +static const unsigned int sdhi0_ctrl_mux[] = { + SD0_CMD_MARK, SD0_CLK_MARK, +}; +static const unsigned int sdhi0_cd_pins[] = { + /* CD */ + 115, +}; +static const unsigned int sdhi0_cd_mux[] = { + SD0_CD_MARK, +}; +static const unsigned int sdhi0_wp_pins[] = { + /* WP */ + 116, +}; +static const unsigned int sdhi0_wp_mux[] = { + SD0_WP_MARK, +}; +/* - SDHI1 ------------------------------------------------------------------ */ +static const unsigned int sdhi1_data1_pins[] = { + /* D0 */ + 19, +}; +static const unsigned int sdhi1_data1_mux[] = { + SD1_DAT0_MARK, +}; +static const unsigned int sdhi1_data4_pins[] = { + /* D[0:3] */ + 19, 20, 21, 2, +}; +static const unsigned int sdhi1_data4_mux[] = { + SD1_DAT0_MARK, SD1_DAT1_MARK, SD1_DAT2_MARK, SD1_DAT3_MARK, +}; +static const unsigned int sdhi1_ctrl_pins[] = { + /* CMD, CLK */ + 18, 17, +}; +static const unsigned int sdhi1_ctrl_mux[] = { + SD1_CMD_MARK, SD1_CLK_MARK, +}; +static const unsigned int sdhi1_cd_pins[] = { + /* CD */ + 10, +}; +static const unsigned int sdhi1_cd_mux[] = { + SD1_CD_MARK, +}; +static const unsigned int sdhi1_wp_pins[] = { + /* WP */ + 11, +}; +static const unsigned int sdhi1_wp_mux[] = { + SD1_WP_MARK, +}; +/* - SDHI2 ------------------------------------------------------------------ */ +static const unsigned int sdhi2_data1_pins[] = { + /* D0 */ + 97, +}; +static const unsigned int sdhi2_data1_mux[] = { + SD2_DAT0_MARK, +}; +static const unsigned int sdhi2_data4_pins[] = { + /* D[0:3] */ + 97, 98, 99, 100, +}; +static const unsigned int sdhi2_data4_mux[] = { + SD2_DAT0_MARK, SD2_DAT1_MARK, SD2_DAT2_MARK, SD2_DAT3_MARK, +}; +static const unsigned int sdhi2_ctrl_pins[] = { + /* CMD, CLK */ + 102, 101, +}; +static const unsigned int sdhi2_ctrl_mux[] = { + SD2_CMD_MARK, SD2_CLK_MARK, +}; +static const unsigned int sdhi2_cd_pins[] = { + /* CD */ + 103, +}; +static const unsigned int sdhi2_cd_mux[] = { + SD2_CD_MARK, +}; +static const unsigned int sdhi2_wp_pins[] = { + /* WP */ + 104, +}; +static const unsigned int sdhi2_wp_mux[] = { + SD2_WP_MARK, +}; +/* - SDHI3 ------------------------------------------------------------------ */ +static const unsigned int sdhi3_data1_pins[] = { + /* D0 */ + 50, +}; +static const unsigned int sdhi3_data1_mux[] = { + SD3_DAT0_MARK, +}; +static const unsigned int sdhi3_data4_pins[] = { + /* D[0:3] */ + 50, 51, 52, 53, +}; +static const unsigned int sdhi3_data4_mux[] = { + SD3_DAT0_MARK, SD3_DAT1_MARK, SD3_DAT2_MARK, SD3_DAT3_MARK, +}; +static const unsigned int sdhi3_ctrl_pins[] = { + /* CMD, CLK */ + 35, 34, +}; +static const unsigned int sdhi3_ctrl_mux[] = { + SD3_CMD_MARK, SD3_CLK_MARK, +}; +static const unsigned int sdhi3_cd_pins[] = { + /* CD */ + 62, +}; +static const unsigned int sdhi3_cd_mux[] = { + SD3_CD_MARK, +}; +static const unsigned int sdhi3_wp_pins[] = { + /* WP */ + 64, +}; +static const unsigned int sdhi3_wp_mux[] = { + SD3_WP_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du0_rgb666), @@ -1592,6 +1796,34 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du1_sync_1), SH_PFC_PIN_GROUP(du1_oddf), SH_PFC_PIN_GROUP(du1_cde), + SH_PFC_PIN_GROUP(mmc0_data1), + SH_PFC_PIN_GROUP(mmc0_data4), + SH_PFC_PIN_GROUP(mmc0_data8), + SH_PFC_PIN_GROUP(mmc0_ctrl), + SH_PFC_PIN_GROUP(mmc1_data1), + SH_PFC_PIN_GROUP(mmc1_data4), + SH_PFC_PIN_GROUP(mmc1_data8), + SH_PFC_PIN_GROUP(mmc1_ctrl), + SH_PFC_PIN_GROUP(sdhi0_data1), + SH_PFC_PIN_GROUP(sdhi0_data4), + SH_PFC_PIN_GROUP(sdhi0_ctrl), + SH_PFC_PIN_GROUP(sdhi0_cd), + SH_PFC_PIN_GROUP(sdhi0_wp), + SH_PFC_PIN_GROUP(sdhi1_data1), + SH_PFC_PIN_GROUP(sdhi1_data4), + SH_PFC_PIN_GROUP(sdhi1_ctrl), + SH_PFC_PIN_GROUP(sdhi1_cd), + SH_PFC_PIN_GROUP(sdhi1_wp), + SH_PFC_PIN_GROUP(sdhi2_data1), + SH_PFC_PIN_GROUP(sdhi2_data4), + SH_PFC_PIN_GROUP(sdhi2_ctrl), + SH_PFC_PIN_GROUP(sdhi2_cd), + SH_PFC_PIN_GROUP(sdhi2_wp), + SH_PFC_PIN_GROUP(sdhi3_data1), + SH_PFC_PIN_GROUP(sdhi3_data4), + SH_PFC_PIN_GROUP(sdhi3_ctrl), + SH_PFC_PIN_GROUP(sdhi3_cd), + SH_PFC_PIN_GROUP(sdhi3_wp), }; static const char * const du0_groups[] = { @@ -1615,9 +1847,61 @@ static const char * const du1_groups[] = { "du1_cde", }; +static const char * const mmc0_groups[] = { + "mmc0_data1", + "mmc0_data4", + "mmc0_data8", + "mmc0_ctrl", +}; + +static const char * const mmc1_groups[] = { + "mmc1_data1", + "mmc1_data4", + "mmc1_data8", + "mmc1_ctrl", +}; + +static const char * const sdhi0_groups[] = { + "sdhi0_data1", + "sdhi0_data4", + "sdhi0_ctrl", + "sdhi0_cd", + "sdhi0_wp", +}; + +static const char * const sdhi1_groups[] = { + "sdhi1_data1", + "sdhi1_data4", + "sdhi1_ctrl", + "sdhi1_cd", + "sdhi1_wp", +}; + +static const char * const sdhi2_groups[] = { + "sdhi2_data1", + "sdhi2_data4", + "sdhi2_ctrl", + "sdhi2_cd", + "sdhi2_wp", +}; + +static const char * const sdhi3_groups[] = { + "sdhi3_data1", + "sdhi3_data4", + "sdhi3_ctrl", + "sdhi3_cd", + "sdhi3_wp", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), + SH_PFC_FUNCTION(mmc0), + SH_PFC_FUNCTION(mmc1), + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), + SH_PFC_FUNCTION(sdhi3), }; #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -- cgit From 081b69bbb2c2df2f00b420f9f612c1c3ee0be592 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 19:04:43 +0100 Subject: sh-pfc: r8a7779: Add SCIF pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 490 +++++++++++++++++++++++++++++++++++ 1 file changed, 490 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index ca16b04edd6d..a01adea444e1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1635,6 +1635,370 @@ static const unsigned int mmc1_ctrl_pins[] = { static const unsigned int mmc1_ctrl_mux[] = { MMC1_CMD_MARK, MMC1_CLK_MARK, }; +/* - SCIF0 ------------------------------------------------------------------ */ +static const unsigned int scif0_data_pins[] = { + /* RXD, TXD */ + 153, 152, +}; +static const unsigned int scif0_data_mux[] = { + RX0_MARK, TX0_MARK, +}; +static const unsigned int scif0_clk_pins[] = { + /* SCK */ + 156, +}; +static const unsigned int scif0_clk_mux[] = { + SCK0_MARK, +}; +static const unsigned int scif0_ctrl_pins[] = { + /* RTS, CTS */ + 151, 150, +}; +static const unsigned int scif0_ctrl_mux[] = { + RTS0_TANS_MARK, CTS0_MARK, +}; +static const unsigned int scif0_data_b_pins[] = { + /* RXD, TXD */ + 20, 19, +}; +static const unsigned int scif0_data_b_mux[] = { + RX0_B_MARK, TX0_B_MARK, +}; +static const unsigned int scif0_clk_b_pins[] = { + /* SCK */ + 33, +}; +static const unsigned int scif0_clk_b_mux[] = { + SCK0_B_MARK, +}; +static const unsigned int scif0_ctrl_b_pins[] = { + /* RTS, CTS */ + 18, 11, +}; +static const unsigned int scif0_ctrl_b_mux[] = { + RTS0_B_TANS_B_MARK, CTS0_B_MARK, +}; +static const unsigned int scif0_data_c_pins[] = { + /* RXD, TXD */ + 146, 147, +}; +static const unsigned int scif0_data_c_mux[] = { + RX0_C_MARK, TX0_C_MARK, +}; +static const unsigned int scif0_clk_c_pins[] = { + /* SCK */ + 145, +}; +static const unsigned int scif0_clk_c_mux[] = { + SCK0_C_MARK, +}; +static const unsigned int scif0_ctrl_c_pins[] = { + /* RTS, CTS */ + 149, 148, +}; +static const unsigned int scif0_ctrl_c_mux[] = { + RTS0_C_TANS_C_MARK, CTS0_C_MARK, +}; +static const unsigned int scif0_data_d_pins[] = { + /* RXD, TXD */ + 43, 42, +}; +static const unsigned int scif0_data_d_mux[] = { + RX0_D_MARK, TX0_D_MARK, +}; +static const unsigned int scif0_clk_d_pins[] = { + /* SCK */ + 50, +}; +static const unsigned int scif0_clk_d_mux[] = { + SCK0_D_MARK, +}; +static const unsigned int scif0_ctrl_d_pins[] = { + /* RTS, CTS */ + 51, 35, +}; +static const unsigned int scif0_ctrl_d_mux[] = { + RTS0_D_TANS_D_MARK, CTS0_D_MARK, +}; +/* - SCIF1 ------------------------------------------------------------------ */ +static const unsigned int scif1_data_pins[] = { + /* RXD, TXD */ + 149, 148, +}; +static const unsigned int scif1_data_mux[] = { + RX1_MARK, TX1_MARK, +}; +static const unsigned int scif1_clk_pins[] = { + /* SCK */ + 145, +}; +static const unsigned int scif1_clk_mux[] = { + SCK1_MARK, +}; +static const unsigned int scif1_ctrl_pins[] = { + /* RTS, CTS */ + 147, 146, +}; +static const unsigned int scif1_ctrl_mux[] = { + RTS1_TANS_MARK, CTS1_MARK, +}; +static const unsigned int scif1_data_b_pins[] = { + /* RXD, TXD */ + 117, 114, +}; +static const unsigned int scif1_data_b_mux[] = { + RX1_B_MARK, TX1_B_MARK, +}; +static const unsigned int scif1_clk_b_pins[] = { + /* SCK */ + 113, +}; +static const unsigned int scif1_clk_b_mux[] = { + SCK1_B_MARK, +}; +static const unsigned int scif1_ctrl_b_pins[] = { + /* RTS, CTS */ + 115, 116, +}; +static const unsigned int scif1_ctrl_b_mux[] = { + RTS1_B_TANS_B_MARK, CTS1_B_MARK, +}; +static const unsigned int scif1_data_c_pins[] = { + /* RXD, TXD */ + 67, 66, +}; +static const unsigned int scif1_data_c_mux[] = { + RX1_C_MARK, TX1_C_MARK, +}; +static const unsigned int scif1_clk_c_pins[] = { + /* SCK */ + 86, +}; +static const unsigned int scif1_clk_c_mux[] = { + SCK1_C_MARK, +}; +static const unsigned int scif1_ctrl_c_pins[] = { + /* RTS, CTS */ + 69, 68, +}; +static const unsigned int scif1_ctrl_c_mux[] = { + RTS1_C_TANS_C_MARK, CTS1_C_MARK, +}; +/* - SCIF2 ------------------------------------------------------------------ */ +static const unsigned int scif2_data_pins[] = { + /* RXD, TXD */ + 106, 105, +}; +static const unsigned int scif2_data_mux[] = { + RX2_MARK, TX2_MARK, +}; +static const unsigned int scif2_clk_pins[] = { + /* SCK */ + 107, +}; +static const unsigned int scif2_clk_mux[] = { + SCK2_MARK, +}; +static const unsigned int scif2_data_b_pins[] = { + /* RXD, TXD */ + 120, 119, +}; +static const unsigned int scif2_data_b_mux[] = { + RX2_B_MARK, TX2_B_MARK, +}; +static const unsigned int scif2_clk_b_pins[] = { + /* SCK */ + 118, +}; +static const unsigned int scif2_clk_b_mux[] = { + SCK2_B_MARK, +}; +static const unsigned int scif2_data_c_pins[] = { + /* RXD, TXD */ + 33, 31, +}; +static const unsigned int scif2_data_c_mux[] = { + RX2_C_MARK, TX2_C_MARK, +}; +static const unsigned int scif2_clk_c_pins[] = { + /* SCK */ + 32, +}; +static const unsigned int scif2_clk_c_mux[] = { + SCK2_C_MARK, +}; +static const unsigned int scif2_data_d_pins[] = { + /* RXD, TXD */ + 64, 62, +}; +static const unsigned int scif2_data_d_mux[] = { + RX2_D_MARK, TX2_D_MARK, +}; +static const unsigned int scif2_clk_d_pins[] = { + /* SCK */ + 63, +}; +static const unsigned int scif2_clk_d_mux[] = { + SCK2_D_MARK, +}; +static const unsigned int scif2_data_e_pins[] = { + /* RXD, TXD */ + 20, 19, +}; +static const unsigned int scif2_data_e_mux[] = { + RX2_E_MARK, TX2_E_MARK, +}; +/* - SCIF3 ------------------------------------------------------------------ */ +static const unsigned int scif3_data_pins[] = { + /* RXD, TXD */ + 137, 136, +}; +static const unsigned int scif3_data_mux[] = { + RX3_IRDA_RX_MARK, TX3_IRDA_TX_MARK, +}; +static const unsigned int scif3_clk_pins[] = { + /* SCK */ + 135, +}; +static const unsigned int scif3_clk_mux[] = { + SCK3_MARK, +}; + +static const unsigned int scif3_data_b_pins[] = { + /* RXD, TXD */ + 64, 62, +}; +static const unsigned int scif3_data_b_mux[] = { + RX3_B_IRDA_RX_B_MARK, TX3_B_IRDA_TX_B_MARK, +}; +static const unsigned int scif3_data_c_pins[] = { + /* RXD, TXD */ + 15, 12, +}; +static const unsigned int scif3_data_c_mux[] = { + RX3_C_IRDA_RX_C_MARK, TX3C_IRDA_TX_C_MARK, +}; +static const unsigned int scif3_data_d_pins[] = { + /* RXD, TXD */ + 30, 29, +}; +static const unsigned int scif3_data_d_mux[] = { + RX3_D_IRDA_RX_D_MARK, TX3_D_IRDA_TX_D_MARK, +}; +static const unsigned int scif3_data_e_pins[] = { + /* RXD, TXD */ + 35, 34, +}; +static const unsigned int scif3_data_e_mux[] = { + RX3_E_IRDA_RX_E_MARK, TX3_E_IRDA_TX_E_MARK, +}; +static const unsigned int scif3_clk_e_pins[] = { + /* SCK */ + 42, +}; +static const unsigned int scif3_clk_e_mux[] = { + SCK3_E_MARK, +}; +/* - SCIF4 ------------------------------------------------------------------ */ +static const unsigned int scif4_data_pins[] = { + /* RXD, TXD */ + 123, 122, +}; +static const unsigned int scif4_data_mux[] = { + RX4_MARK, TX4_MARK, +}; +static const unsigned int scif4_clk_pins[] = { + /* SCK */ + 121, +}; +static const unsigned int scif4_clk_mux[] = { + SCK4_MARK, +}; +static const unsigned int scif4_data_b_pins[] = { + /* RXD, TXD */ + 111, 110, +}; +static const unsigned int scif4_data_b_mux[] = { + RX4_B_MARK, TX4_B_MARK, +}; +static const unsigned int scif4_clk_b_pins[] = { + /* SCK */ + 112, +}; +static const unsigned int scif4_clk_b_mux[] = { + SCK4_B_MARK, +}; +static const unsigned int scif4_data_c_pins[] = { + /* RXD, TXD */ + 22, 21, +}; +static const unsigned int scif4_data_c_mux[] = { + RX4_C_MARK, TX4_C_MARK, +}; +static const unsigned int scif4_data_d_pins[] = { + /* RXD, TXD */ + 69, 68, +}; +static const unsigned int scif4_data_d_mux[] = { + RX4_D_MARK, TX4_D_MARK, +}; +/* - SCIF5 ------------------------------------------------------------------ */ +static const unsigned int scif5_data_pins[] = { + /* RXD, TXD */ + 51, 50, +}; +static const unsigned int scif5_data_mux[] = { + RX5_MARK, TX5_MARK, +}; +static const unsigned int scif5_clk_pins[] = { + /* SCK */ + 43, +}; +static const unsigned int scif5_clk_mux[] = { + SCK5_MARK, +}; +static const unsigned int scif5_data_b_pins[] = { + /* RXD, TXD */ + 18, 11, +}; +static const unsigned int scif5_data_b_mux[] = { + RX5_B_MARK, TX5_B_MARK, +}; +static const unsigned int scif5_clk_b_pins[] = { + /* SCK */ + 19, +}; +static const unsigned int scif5_clk_b_mux[] = { + SCK5_B_MARK, +}; +static const unsigned int scif5_data_c_pins[] = { + /* RXD, TXD */ + 24, 23, +}; +static const unsigned int scif5_data_c_mux[] = { + RX5_C_MARK, TX5_C_MARK, +}; +static const unsigned int scif5_clk_c_pins[] = { + /* SCK */ + 28, +}; +static const unsigned int scif5_clk_c_mux[] = { + SCK5_C_MARK, +}; +static const unsigned int scif5_data_d_pins[] = { + /* RXD, TXD */ + 8, 6, +}; +static const unsigned int scif5_data_d_mux[] = { + RX5_D_MARK, TX5_D_MARK, +}; +static const unsigned int scif5_clk_d_pins[] = { + /* SCK */ + 7, +}; +static const unsigned int scif5_clk_d_mux[] = { + SCK5_D_MARK, +}; /* - SDHI0 ------------------------------------------------------------------ */ static const unsigned int sdhi0_data1_pins[] = { /* D0 */ @@ -1804,6 +2168,57 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(mmc1_data4), SH_PFC_PIN_GROUP(mmc1_data8), SH_PFC_PIN_GROUP(mmc1_ctrl), + SH_PFC_PIN_GROUP(scif0_data), + SH_PFC_PIN_GROUP(scif0_clk), + SH_PFC_PIN_GROUP(scif0_ctrl), + SH_PFC_PIN_GROUP(scif0_data_b), + SH_PFC_PIN_GROUP(scif0_clk_b), + SH_PFC_PIN_GROUP(scif0_ctrl_b), + SH_PFC_PIN_GROUP(scif0_data_c), + SH_PFC_PIN_GROUP(scif0_clk_c), + SH_PFC_PIN_GROUP(scif0_ctrl_c), + SH_PFC_PIN_GROUP(scif0_data_d), + SH_PFC_PIN_GROUP(scif0_clk_d), + SH_PFC_PIN_GROUP(scif0_ctrl_d), + SH_PFC_PIN_GROUP(scif1_data), + SH_PFC_PIN_GROUP(scif1_clk), + SH_PFC_PIN_GROUP(scif1_ctrl), + SH_PFC_PIN_GROUP(scif1_data_b), + SH_PFC_PIN_GROUP(scif1_clk_b), + SH_PFC_PIN_GROUP(scif1_ctrl_b), + SH_PFC_PIN_GROUP(scif1_data_c), + SH_PFC_PIN_GROUP(scif1_clk_c), + SH_PFC_PIN_GROUP(scif1_ctrl_c), + SH_PFC_PIN_GROUP(scif2_data), + SH_PFC_PIN_GROUP(scif2_clk), + SH_PFC_PIN_GROUP(scif2_data_b), + SH_PFC_PIN_GROUP(scif2_clk_b), + SH_PFC_PIN_GROUP(scif2_data_c), + SH_PFC_PIN_GROUP(scif2_clk_c), + SH_PFC_PIN_GROUP(scif2_data_d), + SH_PFC_PIN_GROUP(scif2_clk_d), + SH_PFC_PIN_GROUP(scif2_data_e), + SH_PFC_PIN_GROUP(scif3_data), + SH_PFC_PIN_GROUP(scif3_clk), + SH_PFC_PIN_GROUP(scif3_data_b), + SH_PFC_PIN_GROUP(scif3_data_c), + SH_PFC_PIN_GROUP(scif3_data_d), + SH_PFC_PIN_GROUP(scif3_data_e), + SH_PFC_PIN_GROUP(scif3_clk_e), + SH_PFC_PIN_GROUP(scif4_data), + SH_PFC_PIN_GROUP(scif4_clk), + SH_PFC_PIN_GROUP(scif4_data_b), + SH_PFC_PIN_GROUP(scif4_clk_b), + SH_PFC_PIN_GROUP(scif4_data_c), + SH_PFC_PIN_GROUP(scif4_data_d), + SH_PFC_PIN_GROUP(scif5_data), + SH_PFC_PIN_GROUP(scif5_clk), + SH_PFC_PIN_GROUP(scif5_data_b), + SH_PFC_PIN_GROUP(scif5_clk_b), + SH_PFC_PIN_GROUP(scif5_data_c), + SH_PFC_PIN_GROUP(scif5_clk_c), + SH_PFC_PIN_GROUP(scif5_data_d), + SH_PFC_PIN_GROUP(scif5_clk_d), SH_PFC_PIN_GROUP(sdhi0_data1), SH_PFC_PIN_GROUP(sdhi0_data4), SH_PFC_PIN_GROUP(sdhi0_ctrl), @@ -1861,6 +2276,75 @@ static const char * const mmc1_groups[] = { "mmc1_ctrl", }; +static const char * const scif0_groups[] = { + "scif0_data", + "scif0_clk", + "scif0_ctrl", + "scif0_data_b", + "scif0_clk_b", + "scif0_ctrl_b", + "scif0_data_c", + "scif0_clk_c", + "scif0_ctrl_c", + "scif0_data_d", + "scif0_clk_d", + "scif0_ctrl_d", +}; + +static const char * const scif1_groups[] = { + "scif1_data", + "scif1_clk", + "scif1_ctrl", + "scif1_data_b", + "scif1_clk_b", + "scif1_ctrl_b", + "scif1_data_c", + "scif1_clk_c", + "scif1_ctrl_c", +}; + +static const char * const scif2_groups[] = { + "scif2_data", + "scif2_clk", + "scif2_data_b", + "scif2_clk_b", + "scif2_data_c", + "scif2_clk_c", + "scif2_data_d", + "scif2_clk_d", + "scif2_data_e", +}; + +static const char * const scif3_groups[] = { + "scif3_data", + "scif3_clk", + "scif3_data_b", + "scif3_data_c", + "scif3_data_d", + "scif3_data_e", + "scif3_clk_e", +}; + +static const char * const scif4_groups[] = { + "scif4_data", + "scif4_clk", + "scif4_data_b", + "scif4_clk_b", + "scif4_data_c", + "scif4_data_d", +}; + +static const char * const scif5_groups[] = { + "scif5_data", + "scif5_clk", + "scif5_data_b", + "scif5_clk_b", + "scif5_data_c", + "scif5_clk_c", + "scif5_data_d", + "scif5_clk_d", +}; + static const char * const sdhi0_groups[] = { "sdhi0_data1", "sdhi0_data4", @@ -1902,6 +2386,12 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(sdhi1), SH_PFC_FUNCTION(sdhi2), SH_PFC_FUNCTION(sdhi3), + SH_PFC_FUNCTION(scif0), + SH_PFC_FUNCTION(scif1), + SH_PFC_FUNCTION(scif2), + SH_PFC_FUNCTION(scif3), + SH_PFC_FUNCTION(scif4), + SH_PFC_FUNCTION(scif5), }; #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -- cgit From f516238737e1412613aee493961f352977666bbd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 19:04:43 +0100 Subject: sh-pfc: r8a7779: Add HSPI pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 79 +++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index a01adea444e1..361b16240887 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1575,6 +1575,58 @@ static const unsigned int du1_cde_pins[] = { static const unsigned int du1_cde_mux[] = { DU1_CDE_MARK }; +/* - HSPI0 ------------------------------------------------------------------ */ +static const unsigned int hspi0_pins[] = { + /* CLK, CS, RX, TX */ + 150, 151, 153, 152, +}; +static const unsigned int hspi0_mux[] = { + HSPI_CLK0_MARK, HSPI_CS0_MARK, HSPI_RX0_MARK, HSPI_TX0_MARK, +}; +/* - HSPI1 ------------------------------------------------------------------ */ +static const unsigned int hspi1_pins[] = { + /* CLK, CS, RX, TX */ + 63, 58, 64, 62, +}; +static const unsigned int hspi1_mux[] = { + HSPI_CLK1_MARK, HSPI_CS1_MARK, HSPI_RX1_MARK, HSPI_TX1_MARK, +}; +static const unsigned int hspi1_b_pins[] = { + /* CLK, CS, RX, TX */ + 90, 91, 93, 92, +}; +static const unsigned int hspi1_b_mux[] = { + HSPI_CLK1_B_MARK, HSPI_CS1_B_MARK, HSPI_RX1_B_MARK, HSPI_TX1_B_MARK, +}; +static const unsigned int hspi1_c_pins[] = { + /* CLK, CS, RX, TX */ + 141, 142, 144, 143, +}; +static const unsigned int hspi1_c_mux[] = { + HSPI_CLK1_C_MARK, HSPI_CS1_C_MARK, HSPI_RX1_C_MARK, HSPI_TX1_C_MARK, +}; +static const unsigned int hspi1_d_pins[] = { + /* CLK, CS, RX, TX */ + 101, 102, 104, 103, +}; +static const unsigned int hspi1_d_mux[] = { + HSPI_CLK1_D_MARK, HSPI_CS1_D_MARK, HSPI_RX1_D_MARK, HSPI_TX1_D_MARK, +}; +/* - HSPI2 ------------------------------------------------------------------ */ +static const unsigned int hspi2_pins[] = { + /* CLK, CS, RX, TX */ + 9, 10, 11, 14, +}; +static const unsigned int hspi2_mux[] = { + HSPI_CLK2_MARK, HSPI_CS2_MARK, HSPI_RX2_MARK, HSPI_TX2_MARK, +}; +static const unsigned int hspi2_b_pins[] = { + /* CLK, CS, RX, TX */ + 7, 13, 8, 6, +}; +static const unsigned int hspi2_b_mux[] = { + HSPI_CLK2_B_MARK, HSPI_CS2_B_MARK, HSPI_RX2_B_MARK, HSPI_TX2_B_MARK, +}; /* - MMCIF ------------------------------------------------------------------ */ static const unsigned int mmc0_data1_pins[] = { /* D[0] */ @@ -1605,7 +1657,6 @@ static const unsigned int mmc0_ctrl_pins[] = { static const unsigned int mmc0_ctrl_mux[] = { MMC0_CMD_MARK, MMC0_CLK_MARK, }; - static const unsigned int mmc1_data1_pins[] = { /* D[0] */ 72, @@ -2160,6 +2211,13 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du1_sync_1), SH_PFC_PIN_GROUP(du1_oddf), SH_PFC_PIN_GROUP(du1_cde), + SH_PFC_PIN_GROUP(hspi0), + SH_PFC_PIN_GROUP(hspi1), + SH_PFC_PIN_GROUP(hspi1_b), + SH_PFC_PIN_GROUP(hspi1_c), + SH_PFC_PIN_GROUP(hspi1_d), + SH_PFC_PIN_GROUP(hspi2), + SH_PFC_PIN_GROUP(hspi2_b), SH_PFC_PIN_GROUP(mmc0_data1), SH_PFC_PIN_GROUP(mmc0_data4), SH_PFC_PIN_GROUP(mmc0_data8), @@ -2262,6 +2320,22 @@ static const char * const du1_groups[] = { "du1_cde", }; +static const char * const hspi0_groups[] = { + "hspi0", +}; + +static const char * const hspi1_groups[] = { + "hspi1", + "hspi1_b", + "hspi1_c", + "hspi1_d", +}; + +static const char * const hspi2_groups[] = { + "hspi2", + "hspi2_b", +}; + static const char * const mmc0_groups[] = { "mmc0_data1", "mmc0_data4", @@ -2380,6 +2454,9 @@ static const char * const sdhi3_groups[] = { static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), + SH_PFC_FUNCTION(hspi0), + SH_PFC_FUNCTION(hspi1), + SH_PFC_FUNCTION(hspi2), SH_PFC_FUNCTION(mmc0), SH_PFC_FUNCTION(mmc1), SH_PFC_FUNCTION(sdhi0), -- cgit From 0f6e2e0e4e3cf5899c9acf03884991bb67301132 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:36:36 +0100 Subject: sh-pfc: r8a7779: Add USB0 and USB1 PENC pinmux support The USB0 and USB1 PENC functions were missing. Add them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 361b16240887..946572bcdaac 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -429,7 +429,8 @@ enum { A0_MARK, SD1_DAT3_MARK, MMC0_D3_MARK, FD3_MARK, BS_MARK, SD1_DAT2_MARK, MMC0_D2_MARK, FD2_MARK, ATADIR0_MARK, SDSELF_MARK, HCTS1_MARK, TX4_C_MARK, - USB_PENC2_MARK, SCK0_MARK, PWM1_MARK, PWMFSW0_MARK, + USB_PENC0_MARK, USB_PENC1_MARK, USB_PENC2_MARK, + SCK0_MARK, PWM1_MARK, PWMFSW0_MARK, SCIF_CLK_MARK, TCLK0_C_MARK, EX_CS0_MARK, RX3_C_IRDA_RX_C_MARK, MMC0_D6_MARK, @@ -640,6 +641,9 @@ static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA(A18_MARK, FN_A18), PINMUX_DATA(A19_MARK, FN_A19), + PINMUX_DATA(USB_PENC0_MARK, FN_USB_PENC0), + PINMUX_DATA(USB_PENC1_MARK, FN_USB_PENC1), + PINMUX_IPSR_DATA(IP0_2_0, USB_PENC2), PINMUX_IPSR_MODSEL_DATA(IP0_2_0, SCK0, SEL_SCIF0_0), PINMUX_IPSR_DATA(IP0_2_0, PWM1), -- cgit From 97d40c4224172451f666febdd865c24b1c3c3fe5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:38:51 +0100 Subject: sh-pfc: r8a7779: Add USB pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 946572bcdaac..6043d2c8dd8d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2198,6 +2198,30 @@ static const unsigned int sdhi3_wp_pins[] = { static const unsigned int sdhi3_wp_mux[] = { SD3_WP_MARK, }; +/* - USB0 ------------------------------------------------------------------- */ +static const unsigned int usb0_pins[] = { + /* OVC */ + 150, 154, +}; +static const unsigned int usb0_mux[] = { + USB_OVC0_MARK, USB_PENC0_MARK, +}; +/* - USB1 ------------------------------------------------------------------- */ +static const unsigned int usb1_pins[] = { + /* OVC */ + 152, 155, +}; +static const unsigned int usb1_mux[] = { + USB_OVC1_MARK, USB_PENC1_MARK, +}; +/* - USB2 ------------------------------------------------------------------- */ +static const unsigned int usb2_pins[] = { + /* OVC, PENC */ + 125, 156, +}; +static const unsigned int usb2_mux[] = { + USB_OVC2_MARK, USB_PENC2_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du0_rgb666), @@ -2301,6 +2325,9 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi3_ctrl), SH_PFC_PIN_GROUP(sdhi3_cd), SH_PFC_PIN_GROUP(sdhi3_wp), + SH_PFC_PIN_GROUP(usb0), + SH_PFC_PIN_GROUP(usb1), + SH_PFC_PIN_GROUP(usb2), }; static const char * const du0_groups[] = { @@ -2455,6 +2482,18 @@ static const char * const sdhi3_groups[] = { "sdhi3_wp", }; +static const char * const usb0_groups[] = { + "usb0", +}; + +static const char * const usb1_groups[] = { + "usb1", +}; + +static const char * const usb2_groups[] = { + "usb2", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), @@ -2473,6 +2512,9 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(scif3), SH_PFC_FUNCTION(scif4), SH_PFC_FUNCTION(scif5), + SH_PFC_FUNCTION(usb0), + SH_PFC_FUNCTION(usb1), + SH_PFC_FUNCTION(usb2), }; #define PINMUX_FN_BASE ARRAY_SIZE(pinmux_pins) -- cgit From f27f81f2c04e1cd382a3c3bb072c708a895d83bb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:38:51 +0100 Subject: sh-pfc: r8a7779: Add LBSC pin groups and functions Only the CS pins and functions are currently handled. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 6043d2c8dd8d..3f671439ae6e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1631,6 +1631,63 @@ static const unsigned int hspi2_b_pins[] = { static const unsigned int hspi2_b_mux[] = { HSPI_CLK2_B_MARK, HSPI_CS2_B_MARK, HSPI_RX2_B_MARK, HSPI_TX2_B_MARK, }; +/* - LSBC ------------------------------------------------------------------- */ +static const unsigned int lbsc_cs0_pins[] = { + /* CS */ + 13, +}; +static const unsigned int lbsc_cs0_mux[] = { + CS0_MARK, +}; +static const unsigned int lbsc_cs1_pins[] = { + /* CS */ + 14, +}; +static const unsigned int lbsc_cs1_mux[] = { + CS1_A26_MARK, +}; +static const unsigned int lbsc_ex_cs0_pins[] = { + /* CS */ + 15, +}; +static const unsigned int lbsc_ex_cs0_mux[] = { + EX_CS0_MARK, +}; +static const unsigned int lbsc_ex_cs1_pins[] = { + /* CS */ + 16, +}; +static const unsigned int lbsc_ex_cs1_mux[] = { + EX_CS1_MARK, +}; +static const unsigned int lbsc_ex_cs2_pins[] = { + /* CS */ + 17, +}; +static const unsigned int lbsc_ex_cs2_mux[] = { + EX_CS2_MARK, +}; +static const unsigned int lbsc_ex_cs3_pins[] = { + /* CS */ + 18, +}; +static const unsigned int lbsc_ex_cs3_mux[] = { + EX_CS3_MARK, +}; +static const unsigned int lbsc_ex_cs4_pins[] = { + /* CS */ + 19, +}; +static const unsigned int lbsc_ex_cs4_mux[] = { + EX_CS4_MARK, +}; +static const unsigned int lbsc_ex_cs5_pins[] = { + /* CS */ + 20, +}; +static const unsigned int lbsc_ex_cs5_mux[] = { + EX_CS5_MARK, +}; /* - MMCIF ------------------------------------------------------------------ */ static const unsigned int mmc0_data1_pins[] = { /* D[0] */ @@ -2246,6 +2303,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(hspi1_d), SH_PFC_PIN_GROUP(hspi2), SH_PFC_PIN_GROUP(hspi2_b), + SH_PFC_PIN_GROUP(lbsc_cs0), + SH_PFC_PIN_GROUP(lbsc_cs1), + SH_PFC_PIN_GROUP(lbsc_ex_cs0), + SH_PFC_PIN_GROUP(lbsc_ex_cs1), + SH_PFC_PIN_GROUP(lbsc_ex_cs2), + SH_PFC_PIN_GROUP(lbsc_ex_cs3), + SH_PFC_PIN_GROUP(lbsc_ex_cs4), + SH_PFC_PIN_GROUP(lbsc_ex_cs5), SH_PFC_PIN_GROUP(mmc0_data1), SH_PFC_PIN_GROUP(mmc0_data4), SH_PFC_PIN_GROUP(mmc0_data8), @@ -2367,6 +2432,17 @@ static const char * const hspi2_groups[] = { "hspi2_b", }; +static const char * const lbsc_groups[] = { + "lbsc_cs0", + "lbsc_cs1", + "lbsc_ex_cs0", + "lbsc_ex_cs1", + "lbsc_ex_cs2", + "lbsc_ex_cs3", + "lbsc_ex_cs4", + "lbsc_ex_cs5", +}; + static const char * const mmc0_groups[] = { "mmc0_data1", "mmc0_data4", @@ -2500,6 +2576,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(hspi0), SH_PFC_FUNCTION(hspi1), SH_PFC_FUNCTION(hspi2), + SH_PFC_FUNCTION(lbsc), SH_PFC_FUNCTION(mmc0), SH_PFC_FUNCTION(mmc1), SH_PFC_FUNCTION(sdhi0), -- cgit From fd9e7feb9ae96346724f35fd20eb2009743fb868 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:38:51 +0100 Subject: sh-pfc: r8a7779: Add INTC pin groups and functions Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 77 ++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 3f671439ae6e..5b498ffaef03 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -1631,6 +1631,63 @@ static const unsigned int hspi2_b_pins[] = { static const unsigned int hspi2_b_mux[] = { HSPI_CLK2_B_MARK, HSPI_CS2_B_MARK, HSPI_RX2_B_MARK, HSPI_TX2_B_MARK, }; +/* - INTC ------------------------------------------------------------------- */ +static const unsigned int intc_irq0_pins[] = { + /* IRQ */ + 78, +}; +static const unsigned int intc_irq0_mux[] = { + IRQ0_MARK, +}; +static const unsigned int intc_irq0_b_pins[] = { + /* IRQ */ + 141, +}; +static const unsigned int intc_irq0_b_mux[] = { + IRQ0_B_MARK, +}; +static const unsigned int intc_irq1_pins[] = { + /* IRQ */ + 79, +}; +static const unsigned int intc_irq1_mux[] = { + IRQ1_MARK, +}; +static const unsigned int intc_irq1_b_pins[] = { + /* IRQ */ + 142, +}; +static const unsigned int intc_irq1_b_mux[] = { + IRQ1_B_MARK, +}; +static const unsigned int intc_irq2_pins[] = { + /* IRQ */ + 88, +}; +static const unsigned int intc_irq2_mux[] = { + IRQ2_MARK, +}; +static const unsigned int intc_irq2_b_pins[] = { + /* IRQ */ + 143, +}; +static const unsigned int intc_irq2_b_mux[] = { + IRQ2_B_MARK, +}; +static const unsigned int intc_irq3_pins[] = { + /* IRQ */ + 89, +}; +static const unsigned int intc_irq3_mux[] = { + IRQ3_MARK, +}; +static const unsigned int intc_irq3_b_pins[] = { + /* IRQ */ + 144, +}; +static const unsigned int intc_irq3_b_mux[] = { + IRQ3_B_MARK, +}; /* - LSBC ------------------------------------------------------------------- */ static const unsigned int lbsc_cs0_pins[] = { /* CS */ @@ -2303,6 +2360,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(hspi1_d), SH_PFC_PIN_GROUP(hspi2), SH_PFC_PIN_GROUP(hspi2_b), + SH_PFC_PIN_GROUP(intc_irq0), + SH_PFC_PIN_GROUP(intc_irq0_b), + SH_PFC_PIN_GROUP(intc_irq1), + SH_PFC_PIN_GROUP(intc_irq1_b), + SH_PFC_PIN_GROUP(intc_irq2), + SH_PFC_PIN_GROUP(intc_irq2_b), + SH_PFC_PIN_GROUP(intc_irq3), + SH_PFC_PIN_GROUP(intc_irq3_b), SH_PFC_PIN_GROUP(lbsc_cs0), SH_PFC_PIN_GROUP(lbsc_cs1), SH_PFC_PIN_GROUP(lbsc_ex_cs0), @@ -2432,6 +2497,17 @@ static const char * const hspi2_groups[] = { "hspi2_b", }; +static const char * const intc_groups[] = { + "intc_irq0", + "intc_irq0_b", + "intc_irq1", + "intc_irq1_b", + "intc_irq2", + "intc_irq2_b", + "intc_irq3", + "intc_irq4_b", +}; + static const char * const lbsc_groups[] = { "lbsc_cs0", "lbsc_cs1", @@ -2576,6 +2652,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(hspi0), SH_PFC_FUNCTION(hspi1), SH_PFC_FUNCTION(hspi2), + SH_PFC_FUNCTION(intc), SH_PFC_FUNCTION(lbsc), SH_PFC_FUNCTION(mmc0), SH_PFC_FUNCTION(mmc1), -- cgit From 570f76a867b98b61a018bea490adec065d871029 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 14:23:17 +0100 Subject: sh-pfc: sh7372: Remove SDHI and MMCIF function GPIOS All sh7372 platforms now use the pinctrl API to control the SDHI and MMCIF pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh7372.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c index cef4d6a598dd..df0ae21a5ac8 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c @@ -1277,18 +1277,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(D11_NAF11), GPIO_FN(D12_NAF12), GPIO_FN(D13_NAF13), GPIO_FN(D14_NAF14), GPIO_FN(D15_NAF15), - /* MMCIF(1) */ - GPIO_FN(MMCD0_0), GPIO_FN(MMCD0_1), GPIO_FN(MMCD0_2), - GPIO_FN(MMCD0_3), GPIO_FN(MMCD0_4), GPIO_FN(MMCD0_5), - GPIO_FN(MMCD0_6), GPIO_FN(MMCD0_7), GPIO_FN(MMCCMD0), - GPIO_FN(MMCCLK0), - - /* MMCIF(2) */ - GPIO_FN(MMCD1_0), GPIO_FN(MMCD1_1), GPIO_FN(MMCD1_2), - GPIO_FN(MMCD1_3), GPIO_FN(MMCD1_4), GPIO_FN(MMCD1_5), - GPIO_FN(MMCD1_6), GPIO_FN(MMCD1_7), GPIO_FN(MMCCLK1), - GPIO_FN(MMCCMD1), - /* SPU2 */ GPIO_FN(VINT_I), @@ -1385,19 +1373,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { /* HDMI */ GPIO_FN(HDMI_HPD), GPIO_FN(HDMI_CEC), - /* SDHI0 */ - GPIO_FN(SDHICLK0), GPIO_FN(SDHICD0), GPIO_FN(SDHICMD0), - GPIO_FN(SDHIWP0), GPIO_FN(SDHID0_0), GPIO_FN(SDHID0_1), - GPIO_FN(SDHID0_2), GPIO_FN(SDHID0_3), - - /* SDHI1 */ - GPIO_FN(SDHICLK1), GPIO_FN(SDHICMD1), GPIO_FN(SDHID1_0), - GPIO_FN(SDHID1_1), GPIO_FN(SDHID1_2), GPIO_FN(SDHID1_3), - - /* SDHI2 */ - GPIO_FN(SDHICLK2), GPIO_FN(SDHICMD2), GPIO_FN(SDHID2_0), - GPIO_FN(SDHID2_1), GPIO_FN(SDHID2_2), GPIO_FN(SDHID2_3), - /* SDENC */ GPIO_FN(SDENC_CPG), GPIO_FN(SDENC_DV_CLKI), -- cgit From 31d3a01a870d9d69a1d407af651ccd65a099dc79 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Remove LCD and LCD2 function GPIOS All sh73a0 platforms now use the pinctrl API to control the LCD and LCD2 pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 76 ------------------------------------- 1 file changed, 76 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 8fc5eb0025c5..1054a4265e0a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3545,87 +3545,59 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(BBIF1_FLOW), GPIO_FN(HSI_TX_FLAG), GPIO_FN(VIO_VD), \ - GPIO_FN(PORT128_LCD2VSYN), \ GPIO_FN(VIO2_VD), \ - GPIO_FN(LCD2D0), GPIO_FN(VIO_HD), \ - GPIO_FN(PORT129_LCD2HSYN), \ - GPIO_FN(PORT129_LCD2CS_), \ GPIO_FN(VIO2_HD), \ - GPIO_FN(LCD2D1), GPIO_FN(VIO_D0), \ GPIO_FN(PORT130_MSIOF2_RXD), \ - GPIO_FN(LCD2D10), GPIO_FN(VIO_D1), \ GPIO_FN(PORT131_KEYOUT6), \ GPIO_FN(PORT131_MSIOF2_SS1), \ GPIO_FN(PORT131_KEYOUT11), \ - GPIO_FN(LCD2D11), GPIO_FN(VIO_D2), \ GPIO_FN(PORT132_KEYOUT7), \ GPIO_FN(PORT132_MSIOF2_SS2), \ GPIO_FN(PORT132_KEYOUT10), \ - GPIO_FN(LCD2D12), GPIO_FN(VIO_D3), \ GPIO_FN(MSIOF2_TSYNC), \ - GPIO_FN(LCD2D13), GPIO_FN(VIO_D4), \ GPIO_FN(MSIOF2_TXD), \ - GPIO_FN(LCD2D14), GPIO_FN(VIO_D5), \ GPIO_FN(MSIOF2_TSCK), \ - GPIO_FN(LCD2D15), GPIO_FN(VIO_D6), \ GPIO_FN(PORT136_KEYOUT8), \ - GPIO_FN(LCD2D16), GPIO_FN(VIO_D7), \ GPIO_FN(PORT137_KEYOUT9), \ - GPIO_FN(LCD2D17), GPIO_FN(VIO_D8), \ GPIO_FN(PORT138_KEYOUT8), \ GPIO_FN(VIO2_D0), \ - GPIO_FN(LCD2D6), GPIO_FN(VIO_D9), \ GPIO_FN(PORT139_KEYOUT9), \ GPIO_FN(VIO2_D1), \ - GPIO_FN(LCD2D7), GPIO_FN(VIO_D10), \ GPIO_FN(TPU0TO2), \ GPIO_FN(VIO2_D2), \ - GPIO_FN(LCD2D8), GPIO_FN(VIO_D11), \ GPIO_FN(TPU0TO3), \ GPIO_FN(VIO2_D3), \ - GPIO_FN(LCD2D9), GPIO_FN(VIO_D12), \ GPIO_FN(PORT142_KEYOUT10), \ GPIO_FN(VIO2_D4), \ - GPIO_FN(LCD2D2), GPIO_FN(VIO_D13), \ GPIO_FN(PORT143_KEYOUT11), \ GPIO_FN(PORT143_KEYOUT6), \ GPIO_FN(VIO2_D5), \ - GPIO_FN(LCD2D3), GPIO_FN(VIO_D14), \ GPIO_FN(PORT144_KEYOUT7), \ GPIO_FN(VIO2_D6), \ - GPIO_FN(LCD2D4), GPIO_FN(VIO_D15), \ GPIO_FN(TPU1TO3), \ - GPIO_FN(PORT145_LCD2DISP), \ - GPIO_FN(PORT145_LCD2RS), \ GPIO_FN(VIO2_D7), \ - GPIO_FN(LCD2D5), GPIO_FN(VIO_CLK), \ - GPIO_FN(LCD2DCK), \ - GPIO_FN(PORT146_LCD2WR_), \ GPIO_FN(VIO2_CLK), \ - GPIO_FN(LCD2D18), GPIO_FN(VIO_FIELD), \ - GPIO_FN(LCD2RD_), \ GPIO_FN(VIO2_FIELD), \ - GPIO_FN(LCD2D19), GPIO_FN(VIO_CKO), GPIO_FN(A27), \ GPIO_FN(PORT149_RDWR), \ @@ -3662,107 +3634,63 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(PORT163_SCIFB_RTS_), \ GPIO_FN(PORT163_SCIFA5_RTS_), \ GPIO_FN(TPU3TO0), - GPIO_FN(LCDD0), - GPIO_FN(LCDD1), \ GPIO_FN(PORT193_SCIFA5_CTS_), \ GPIO_FN(BBIF2_TSYNC1), - GPIO_FN(LCDD2), \ GPIO_FN(PORT194_SCIFA5_RTS_), \ GPIO_FN(BBIF2_TSCK1), - GPIO_FN(LCDD3), \ GPIO_FN(PORT195_SCIFA5_RXD), \ GPIO_FN(BBIF2_TXD1), - GPIO_FN(LCDD4), \ GPIO_FN(PORT196_SCIFA5_TXD), - GPIO_FN(LCDD5), \ GPIO_FN(PORT197_SCIFA5_SCK), \ GPIO_FN(MFG2_OUT2), \ GPIO_FN(TPU2TO1), - GPIO_FN(LCDD6), - GPIO_FN(LCDD7), \ GPIO_FN(TPU4TO1), \ GPIO_FN(MFG4_OUT2), - GPIO_FN(LCDD8), \ GPIO_FN(D16), - GPIO_FN(LCDD9), \ GPIO_FN(D17), - GPIO_FN(LCDD10), \ GPIO_FN(D18), - GPIO_FN(LCDD11), \ GPIO_FN(D19), - GPIO_FN(LCDD12), \ GPIO_FN(D20), - GPIO_FN(LCDD13), \ GPIO_FN(D21), - GPIO_FN(LCDD14), \ GPIO_FN(D22), - GPIO_FN(LCDD15), \ GPIO_FN(PORT207_MSIOF0L_SS1), \ GPIO_FN(D23), - GPIO_FN(LCDD16), \ GPIO_FN(PORT208_MSIOF0L_SS2), \ GPIO_FN(D24), - GPIO_FN(LCDD17), \ GPIO_FN(D25), - GPIO_FN(LCDD18), \ GPIO_FN(DREQ2), \ GPIO_FN(PORT210_MSIOF0L_SS1), \ GPIO_FN(D26), - GPIO_FN(LCDD19), \ GPIO_FN(PORT211_MSIOF0L_SS2), \ GPIO_FN(D27), - GPIO_FN(LCDD20), \ GPIO_FN(TS_SPSYNC1), \ GPIO_FN(MSIOF0L_MCK0), \ GPIO_FN(D28), - GPIO_FN(LCDD21), \ GPIO_FN(TS_SDAT1), \ GPIO_FN(MSIOF0L_MCK1), \ GPIO_FN(D29), - GPIO_FN(LCDD22), \ GPIO_FN(TS_SDEN1), \ GPIO_FN(MSIOF0L_RSCK), \ GPIO_FN(D30), - GPIO_FN(LCDD23), \ GPIO_FN(TS_SCK1), \ GPIO_FN(MSIOF0L_RSYNC), \ GPIO_FN(D31), - GPIO_FN(LCDDCK), \ - GPIO_FN(LCDWR_), - GPIO_FN(LCDRD_), \ GPIO_FN(DACK2), \ - GPIO_FN(PORT217_LCD2RS), \ GPIO_FN(MSIOF0L_TSYNC), \ GPIO_FN(VIO2_FIELD3), \ - GPIO_FN(PORT217_LCD2DISP), - GPIO_FN(LCDHSYN), \ - GPIO_FN(LCDCS_), \ - GPIO_FN(LCDCS2_), \ GPIO_FN(DACK3), \ GPIO_FN(PORT218_VIO_CKOR), - GPIO_FN(LCDDISP), \ - GPIO_FN(LCDRS), \ - GPIO_FN(PORT219_LCD2WR_), \ GPIO_FN(DREQ3), \ GPIO_FN(MSIOF0L_TSCK), \ GPIO_FN(VIO2_CLK3), \ - GPIO_FN(LCD2DCK_2), - GPIO_FN(LCDVSYN), \ - GPIO_FN(LCDVSYN2), - GPIO_FN(LCDLCLK), \ GPIO_FN(DREQ1), \ - GPIO_FN(PORT221_LCD2CS_), \ GPIO_FN(PWEN), \ GPIO_FN(MSIOF0L_RXD), \ GPIO_FN(VIO2_HD3), \ - GPIO_FN(PORT221_LCD2HSYN), - GPIO_FN(LCDDON), \ - GPIO_FN(LCDDON2), \ GPIO_FN(DACK1), \ GPIO_FN(OVCN), \ GPIO_FN(MSIOF0L_TXD), \ GPIO_FN(VIO2_VD3), \ - GPIO_FN(PORT222_LCD2VSYN), GPIO_FN(SCIFA1_TXD), \ GPIO_FN(OVCN2), @@ -3785,21 +3713,17 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(MSIOF1_RSCK), \ GPIO_FN(SCIFA2_RTS2_), \ GPIO_FN(VIO2_CLK2), \ - GPIO_FN(LCD2D20), GPIO_FN(MSIOF1_RSYNC), \ GPIO_FN(MFG1_IN2), \ GPIO_FN(VIO2_VD2), \ - GPIO_FN(LCD2D21), GPIO_FN(MSIOF1_MCK0), \ GPIO_FN(PORT236_I2C_SDA2), GPIO_FN(MSIOF1_MCK1), \ GPIO_FN(PORT237_I2C_SCL2), GPIO_FN(MSIOF1_SS1), \ GPIO_FN(VIO2_FIELD2), \ - GPIO_FN(LCD2D22), GPIO_FN(MSIOF1_SS2), \ GPIO_FN(VIO2_HD2), \ - GPIO_FN(LCD2D23), GPIO_FN(SCIFA6_TXD), GPIO_FN(PORT241_IRDA_OUT), \ GPIO_FN(PORT241_IROUT), \ -- cgit From 27d9b21f79fdd59a3592b8c973be1472d8f54d46 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Remove SCIFA and SCIFB function GPIOS All sh73a0 platforms now use the pinctrl API to control the SCIFA and SCIFB pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 58 ------------------------------------- 1 file changed, 58 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 1054a4265e0a..6d36ebbdcdd3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3335,19 +3335,13 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(GPI5), GPIO_FN(GPI6), GPIO_FN(GPI7), - GPIO_FN(SCIFA7_RXD), - GPIO_FN(SCIFA7_CTS_), GPIO_FN(GPO7), \ GPIO_FN(MFG0_OUT2), GPIO_FN(GPO6), \ GPIO_FN(MFG1_OUT2), GPIO_FN(GPO5), \ - GPIO_FN(SCIFA0_SCK), \ GPIO_FN(FSICOSLDT3), \ GPIO_FN(PORT16_VIO_CKOR), - GPIO_FN(SCIFA0_TXD), - GPIO_FN(SCIFA7_TXD), - GPIO_FN(SCIFA7_RTS_), \ GPIO_FN(PORT19_VIO_CKO2), GPIO_FN(GPO0), GPIO_FN(GPO1), @@ -3374,11 +3368,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(PORT30_VIO_CKOR), GPIO_FN(SIM_D), \ GPIO_FN(PORT31_IROUT), - GPIO_FN(SCIFA4_TXD), - GPIO_FN(SCIFA4_RXD), \ GPIO_FN(XWUP), - GPIO_FN(SCIFA4_RTS_), - GPIO_FN(SCIFA4_CTS_), GPIO_FN(FSIBOBT), \ GPIO_FN(FSIBIBT), GPIO_FN(FSIBOLR), \ @@ -3387,10 +3377,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(FSIBISLD), GPIO_FN(VACK), GPIO_FN(XTAL1L), - GPIO_FN(SCIFA0_RTS_), \ GPIO_FN(FSICOSLDT2), - GPIO_FN(SCIFA0_RXD), - GPIO_FN(SCIFA0_CTS_), \ GPIO_FN(FSICOSLDT1), GPIO_FN(FSICOBT), \ GPIO_FN(FSICIBT), \ @@ -3516,14 +3503,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(BBIF2_RXD), GPIO_FN(BBIF2_SYNC), GPIO_FN(BBIF2_SCK), - GPIO_FN(SCIFA3_CTS_), \ GPIO_FN(MFG3_IN2), - GPIO_FN(SCIFA3_RXD), \ GPIO_FN(MFG3_IN1), GPIO_FN(BBIF1_SS2), \ - GPIO_FN(SCIFA3_RTS_), \ GPIO_FN(MFG3_OUT1), - GPIO_FN(SCIFA3_TXD), GPIO_FN(HSI_RX_DATA), \ GPIO_FN(BBIF1_RXD), GPIO_FN(HSI_TX_WAKE), \ @@ -3611,37 +3594,17 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(TPU1TO2), \ GPIO_FN(TS_SDEN3), \ GPIO_FN(PORT153_MSIOF2_SS1), - GPIO_FN(SCIFA2_TXD1), \ GPIO_FN(MSIOF2_MCK0), - GPIO_FN(SCIFA2_RXD1), \ GPIO_FN(MSIOF2_MCK1), - GPIO_FN(SCIFA2_RTS1_), \ GPIO_FN(PORT156_MSIOF2_SS2), - GPIO_FN(SCIFA2_CTS1_), \ GPIO_FN(PORT157_MSIOF2_RXD), GPIO_FN(DINT_), \ - GPIO_FN(SCIFA2_SCK1), \ GPIO_FN(TS_SCK3), - GPIO_FN(PORT159_SCIFB_SCK), \ - GPIO_FN(PORT159_SCIFA5_SCK), \ GPIO_FN(NMI), - GPIO_FN(PORT160_SCIFB_TXD), \ - GPIO_FN(PORT160_SCIFA5_TXD), - GPIO_FN(PORT161_SCIFB_CTS_), \ - GPIO_FN(PORT161_SCIFA5_CTS_), - GPIO_FN(PORT162_SCIFB_RXD), \ - GPIO_FN(PORT162_SCIFA5_RXD), - GPIO_FN(PORT163_SCIFB_RTS_), \ - GPIO_FN(PORT163_SCIFA5_RTS_), \ GPIO_FN(TPU3TO0), - GPIO_FN(PORT193_SCIFA5_CTS_), \ GPIO_FN(BBIF2_TSYNC1), - GPIO_FN(PORT194_SCIFA5_RTS_), \ GPIO_FN(BBIF2_TSCK1), - GPIO_FN(PORT195_SCIFA5_RXD), \ GPIO_FN(BBIF2_TXD1), - GPIO_FN(PORT196_SCIFA5_TXD), - GPIO_FN(PORT197_SCIFA5_SCK), \ GPIO_FN(MFG2_OUT2), \ GPIO_FN(TPU2TO1), GPIO_FN(TPU4TO1), \ @@ -3692,26 +3655,16 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(MSIOF0L_TXD), \ GPIO_FN(VIO2_VD3), \ - GPIO_FN(SCIFA1_TXD), \ GPIO_FN(OVCN2), GPIO_FN(EXTLP), \ - GPIO_FN(SCIFA1_SCK), \ GPIO_FN(PORT226_VIO_CKO2), - GPIO_FN(SCIFA1_RTS_), \ GPIO_FN(IDIN), - GPIO_FN(SCIFA1_RXD), - GPIO_FN(SCIFA1_CTS_), \ GPIO_FN(MFG1_IN1), GPIO_FN(MSIOF1_TXD), \ - GPIO_FN(SCIFA2_TXD2), GPIO_FN(MSIOF1_TSYNC), \ - GPIO_FN(SCIFA2_CTS2_), GPIO_FN(MSIOF1_TSCK), \ - GPIO_FN(SCIFA2_SCK2), GPIO_FN(MSIOF1_RXD), \ - GPIO_FN(SCIFA2_RXD2), GPIO_FN(MSIOF1_RSCK), \ - GPIO_FN(SCIFA2_RTS2_), \ GPIO_FN(VIO2_CLK2), \ GPIO_FN(MSIOF1_RSYNC), \ GPIO_FN(MFG1_IN2), \ @@ -3724,7 +3677,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VIO2_FIELD2), \ GPIO_FN(MSIOF1_SS2), \ GPIO_FN(VIO2_HD2), \ - GPIO_FN(SCIFA6_TXD), GPIO_FN(PORT241_IRDA_OUT), \ GPIO_FN(PORT241_IROUT), \ GPIO_FN(MFG4_OUT1), \ @@ -3733,25 +3685,15 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(MFG4_IN2), GPIO_FN(PORT243_IRDA_FIRSEL), \ GPIO_FN(PORT243_VIO_CKO2), - GPIO_FN(PORT244_SCIFA5_CTS_), \ GPIO_FN(MFG2_IN1), \ - GPIO_FN(PORT244_SCIFB_CTS_), \ GPIO_FN(MSIOF2R_RXD), - GPIO_FN(PORT245_SCIFA5_RTS_), \ GPIO_FN(MFG2_IN2), \ - GPIO_FN(PORT245_SCIFB_RTS_), \ GPIO_FN(MSIOF2R_TXD), - GPIO_FN(PORT246_SCIFA5_RXD), \ GPIO_FN(MFG1_OUT1), \ - GPIO_FN(PORT246_SCIFB_RXD), \ GPIO_FN(TPU1TO0), - GPIO_FN(PORT247_SCIFA5_TXD), \ GPIO_FN(MFG3_OUT2), \ - GPIO_FN(PORT247_SCIFB_TXD), \ GPIO_FN(TPU3TO1), - GPIO_FN(PORT248_SCIFA5_SCK), \ GPIO_FN(MFG2_OUT1), \ - GPIO_FN(PORT248_SCIFB_SCK), \ GPIO_FN(TPU2TO0), \ GPIO_FN(PORT248_I2C_SCL3), \ GPIO_FN(MSIOF2R_TSCK), -- cgit From 85ef3315475fc999730fc24c58343091dd4d1727 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Remove I2C function GPIOS All sh73a0 platforms now use the pinctrl API to control the I2C pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 6d36ebbdcdd3..13bd1380316d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3354,13 +3354,9 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VINT), GPIO_FN(TCKON), GPIO_FN(XDVFS1), \ - GPIO_FN(PORT27_I2C_SCL2), \ - GPIO_FN(PORT27_I2C_SCL3), \ GPIO_FN(MFG0_OUT1), \ GPIO_FN(PORT27_IROUT), GPIO_FN(XDVFS2), \ - GPIO_FN(PORT28_I2C_SDA2), \ - GPIO_FN(PORT28_I2C_SDA3), \ GPIO_FN(PORT28_TPU1TO1), GPIO_FN(SIM_RST), \ GPIO_FN(PORT29_TPU1TO1), @@ -3517,12 +3513,8 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(BBIF1_TXD), GPIO_FN(HSI_RX_READY), \ GPIO_FN(BBIF1_RSCK), \ - GPIO_FN(PORT115_I2C_SCL2), \ - GPIO_FN(PORT115_I2C_SCL3), GPIO_FN(HSI_RX_WAKE), \ GPIO_FN(BBIF1_RSYNC), \ - GPIO_FN(PORT116_I2C_SDA2), \ - GPIO_FN(PORT116_I2C_SDA3), GPIO_FN(HSI_RX_FLAG), \ GPIO_FN(BBIF1_SS1), \ GPIO_FN(BBIF1_FLOW), @@ -3670,9 +3662,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(MFG1_IN2), \ GPIO_FN(VIO2_VD2), \ GPIO_FN(MSIOF1_MCK0), \ - GPIO_FN(PORT236_I2C_SDA2), GPIO_FN(MSIOF1_MCK1), \ - GPIO_FN(PORT237_I2C_SCL2), GPIO_FN(MSIOF1_SS1), \ GPIO_FN(VIO2_FIELD2), \ GPIO_FN(MSIOF1_SS2), \ @@ -3695,11 +3685,9 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(TPU3TO1), GPIO_FN(MFG2_OUT1), \ GPIO_FN(TPU2TO0), \ - GPIO_FN(PORT248_I2C_SCL3), \ GPIO_FN(MSIOF2R_TSCK), GPIO_FN(PORT249_IROUT), \ GPIO_FN(MFG4_IN1), \ - GPIO_FN(PORT249_I2C_SDA3), \ GPIO_FN(MSIOF2R_TSYNC), GPIO_FN(SDHICLK0), GPIO_FN(SDHICD0), -- cgit From 0b1e75ccc18c34a0f4c37e501aa4cf17a3ae37f7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: sh73a0: Remove FSI function GPIOS All sh73a0 platforms now use the pinctrl API to control the FSI pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 13bd1380316d..1a638f2c7ec2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3340,7 +3340,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(GPO6), \ GPIO_FN(MFG1_OUT2), GPIO_FN(GPO5), \ - GPIO_FN(FSICOSLDT3), \ GPIO_FN(PORT16_VIO_CKOR), GPIO_FN(PORT19_VIO_CKO2), GPIO_FN(GPO0), @@ -3365,55 +3364,20 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SIM_D), \ GPIO_FN(PORT31_IROUT), GPIO_FN(XWUP), - GPIO_FN(FSIBOBT), \ - GPIO_FN(FSIBIBT), - GPIO_FN(FSIBOLR), \ - GPIO_FN(FSIBILR), - GPIO_FN(FSIBOSLD), - GPIO_FN(FSIBISLD), GPIO_FN(VACK), GPIO_FN(XTAL1L), - GPIO_FN(FSICOSLDT2), - GPIO_FN(FSICOSLDT1), - GPIO_FN(FSICOBT), \ - GPIO_FN(FSICIBT), \ - GPIO_FN(FSIDOBT), \ - GPIO_FN(FSIDIBT), - GPIO_FN(FSICOLR), \ - GPIO_FN(FSICILR), \ - GPIO_FN(FSIDOLR), \ - GPIO_FN(FSIDILR), - GPIO_FN(FSICOSLD), \ - GPIO_FN(PORT47_FSICSPDIF), - GPIO_FN(FSICISLD), \ - GPIO_FN(FSIDISLD), - GPIO_FN(FSIACK), \ GPIO_FN(PORT49_IRDA_OUT), \ GPIO_FN(PORT49_IROUT), \ - GPIO_FN(FSIAOMC), - GPIO_FN(FSIAOLR), \ GPIO_FN(BBIF2_TSYNC2), \ GPIO_FN(TPU2TO2), \ - GPIO_FN(FSIAILR), - GPIO_FN(FSIAOBT), \ GPIO_FN(BBIF2_TSCK2), \ GPIO_FN(TPU2TO3), \ - GPIO_FN(FSIAIBT), - GPIO_FN(FSIAOSLD), \ GPIO_FN(BBIF2_TXD2), - GPIO_FN(FSIASPDIF), \ GPIO_FN(PORT53_IRDA_IN), \ GPIO_FN(TPU3TO3), \ - GPIO_FN(FSIBSPDIF), \ - GPIO_FN(PORT53_FSICSPDIF), - GPIO_FN(FSIBCK), \ GPIO_FN(PORT54_IRDA_FIRSEL), \ GPIO_FN(TPU3TO2), \ - GPIO_FN(FSIBOMC), \ - GPIO_FN(FSICCK), \ - GPIO_FN(FSICOMC), - GPIO_FN(FSIAISLD), \ GPIO_FN(TPU0TO0), GPIO_FN(A0), \ GPIO_FN(BS_), -- cgit From 19ac5557e74fb4f9d7364235ff805f96c2c4f562 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:32:00 +0100 Subject: sh-pfc: sh73a0: Remove pull-up function GPIOS All sh73a0 platforms now use the pinconf API to control pull-ups, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 465 ++---------------------------------- 1 file changed, 23 insertions(+), 442 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 1a638f2c7ec2..1249a3ffdb31 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -66,14 +66,6 @@ enum { PORT_ALL(IN), /* PORT0_IN -> PORT309_IN */ PINMUX_INPUT_END, - PINMUX_INPUT_PULLUP_BEGIN, - PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */ - PINMUX_INPUT_PULLUP_END, - - PINMUX_INPUT_PULLDOWN_BEGIN, - PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */ - PINMUX_INPUT_PULLDOWN_END, - PINMUX_OUTPUT_BEGIN, PORT_ALL(OUT), /* PORT0_OUT -> PORT309_OUT */ PINMUX_OUTPUT_END, @@ -468,328 +460,15 @@ enum { EDBGREQ_PD_MARK, EDBGREQ_PU_MARK, - /* Functions with pull-ups */ - KEYIN0_PU_MARK, - KEYIN1_PU_MARK, - KEYIN2_PU_MARK, - KEYIN3_PU_MARK, - KEYIN4_PU_MARK, - KEYIN5_PU_MARK, - KEYIN6_PU_MARK, - KEYIN7_PU_MARK, - SDHICD0_PU_MARK, - SDHID0_0_PU_MARK, - SDHID0_1_PU_MARK, - SDHID0_2_PU_MARK, - SDHID0_3_PU_MARK, - SDHICMD0_PU_MARK, - SDHIWP0_PU_MARK, - SDHID1_0_PU_MARK, - SDHID1_1_PU_MARK, - SDHID1_2_PU_MARK, - SDHID1_3_PU_MARK, - SDHICMD1_PU_MARK, - SDHID2_0_PU_MARK, - SDHID2_1_PU_MARK, - SDHID2_2_PU_MARK, - SDHID2_3_PU_MARK, - SDHICMD2_PU_MARK, - MMCCMD0_PU_MARK, - MMCCMD1_PU_MARK, - MMCD0_0_PU_MARK, - MMCD0_1_PU_MARK, - MMCD0_2_PU_MARK, - MMCD0_3_PU_MARK, - MMCD0_4_PU_MARK, - MMCD0_5_PU_MARK, - MMCD0_6_PU_MARK, - MMCD0_7_PU_MARK, - FSIBISLD_PU_MARK, - FSIACK_PU_MARK, - FSIAILR_PU_MARK, - FSIAIBT_PU_MARK, - FSIAISLD_PU_MARK, - PINMUX_MARK_END, }; +#define _PORT_DATA(pfx, sfx) PORT_DATA_IO(pfx) +#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_PORT_DATA, , unused) + static const pinmux_enum_t pinmux_data[] = { /* specify valid pin states for each pin in GPIO mode */ - - /* Table 25-1 (I/O and Pull U/D) */ - PORT_DATA_I_PD(0), - PORT_DATA_I_PU(1), - PORT_DATA_I_PU(2), - PORT_DATA_I_PU(3), - PORT_DATA_I_PU(4), - PORT_DATA_I_PU(5), - PORT_DATA_I_PU(6), - PORT_DATA_I_PU(7), - PORT_DATA_I_PU(8), - PORT_DATA_I_PD(9), - PORT_DATA_I_PD(10), - PORT_DATA_I_PU_PD(11), - PORT_DATA_IO_PU_PD(12), - PORT_DATA_IO_PU_PD(13), - PORT_DATA_IO_PU_PD(14), - PORT_DATA_IO_PU_PD(15), - PORT_DATA_IO_PD(16), - PORT_DATA_IO_PD(17), - PORT_DATA_IO_PU(18), - PORT_DATA_IO_PU(19), - PORT_DATA_O(20), - PORT_DATA_O(21), - PORT_DATA_O(22), - PORT_DATA_O(23), - PORT_DATA_O(24), - PORT_DATA_I_PD(25), - PORT_DATA_I_PD(26), - PORT_DATA_IO_PU(27), - PORT_DATA_IO_PU(28), - PORT_DATA_IO_PD(29), - PORT_DATA_IO_PD(30), - PORT_DATA_IO_PU(31), - PORT_DATA_IO_PD(32), - PORT_DATA_I_PU_PD(33), - PORT_DATA_IO_PD(34), - PORT_DATA_I_PU_PD(35), - PORT_DATA_IO_PD(36), - PORT_DATA_IO(37), - PORT_DATA_O(38), - PORT_DATA_I_PU(39), - PORT_DATA_I_PU_PD(40), - PORT_DATA_O(41), - PORT_DATA_IO_PD(42), - PORT_DATA_IO_PU_PD(43), - PORT_DATA_IO_PU_PD(44), - PORT_DATA_IO_PD(45), - PORT_DATA_IO_PD(46), - PORT_DATA_IO_PD(47), - PORT_DATA_I_PD(48), - PORT_DATA_IO_PU_PD(49), - PORT_DATA_IO_PD(50), - - PORT_DATA_IO_PD(51), - PORT_DATA_O(52), - PORT_DATA_IO_PU_PD(53), - PORT_DATA_IO_PU_PD(54), - PORT_DATA_IO_PD(55), - PORT_DATA_I_PU_PD(56), - PORT_DATA_IO(57), - PORT_DATA_IO(58), - PORT_DATA_IO(59), - PORT_DATA_IO(60), - PORT_DATA_IO(61), - PORT_DATA_IO_PD(62), - PORT_DATA_IO_PD(63), - PORT_DATA_IO_PU_PD(64), - PORT_DATA_IO_PD(65), - PORT_DATA_IO_PU_PD(66), - PORT_DATA_IO_PU_PD(67), - PORT_DATA_IO_PU_PD(68), - PORT_DATA_IO_PU_PD(69), - PORT_DATA_IO_PU_PD(70), - PORT_DATA_IO_PU_PD(71), - PORT_DATA_IO_PU_PD(72), - PORT_DATA_I_PU_PD(73), - PORT_DATA_IO_PU(74), - PORT_DATA_IO_PU(75), - PORT_DATA_IO_PU(76), - PORT_DATA_IO_PU(77), - PORT_DATA_IO_PU(78), - PORT_DATA_IO_PU(79), - PORT_DATA_IO_PU(80), - PORT_DATA_IO_PU(81), - PORT_DATA_IO_PU(82), - PORT_DATA_IO_PU(83), - PORT_DATA_IO_PU(84), - PORT_DATA_IO_PU(85), - PORT_DATA_IO_PU(86), - PORT_DATA_IO_PU(87), - PORT_DATA_IO_PU(88), - PORT_DATA_IO_PU(89), - PORT_DATA_O(90), - PORT_DATA_IO_PU(91), - PORT_DATA_O(92), - PORT_DATA_IO_PU(93), - PORT_DATA_O(94), - PORT_DATA_I_PU_PD(95), - PORT_DATA_IO(96), - PORT_DATA_IO(97), - PORT_DATA_IO(98), - PORT_DATA_I_PU(99), - PORT_DATA_O(100), - PORT_DATA_O(101), - PORT_DATA_I_PU(102), - PORT_DATA_IO_PD(103), - PORT_DATA_I_PU_PD(104), - PORT_DATA_I_PD(105), - PORT_DATA_I_PD(106), - PORT_DATA_I_PU_PD(107), - PORT_DATA_I_PU_PD(108), - PORT_DATA_IO_PD(109), - PORT_DATA_IO_PD(110), - PORT_DATA_IO_PU_PD(111), - PORT_DATA_IO_PU_PD(112), - PORT_DATA_IO_PU_PD(113), - PORT_DATA_IO_PD(114), - PORT_DATA_IO_PU(115), - PORT_DATA_IO_PU(116), - PORT_DATA_IO_PU_PD(117), - PORT_DATA_IO_PU_PD(118), - PORT_DATA_IO_PD(128), - - PORT_DATA_IO_PD(129), - PORT_DATA_IO_PU_PD(130), - PORT_DATA_IO_PD(131), - PORT_DATA_IO_PD(132), - PORT_DATA_IO_PD(133), - PORT_DATA_IO_PU_PD(134), - PORT_DATA_IO_PU_PD(135), - PORT_DATA_IO_PU_PD(136), - PORT_DATA_IO_PU_PD(137), - PORT_DATA_IO_PD(138), - PORT_DATA_IO_PD(139), - PORT_DATA_IO_PD(140), - PORT_DATA_IO_PD(141), - PORT_DATA_IO_PD(142), - PORT_DATA_IO_PD(143), - PORT_DATA_IO_PU_PD(144), - PORT_DATA_IO_PD(145), - PORT_DATA_IO_PU_PD(146), - PORT_DATA_IO_PU_PD(147), - PORT_DATA_IO_PU_PD(148), - PORT_DATA_IO_PU_PD(149), - PORT_DATA_I_PU_PD(150), - PORT_DATA_IO_PU_PD(151), - PORT_DATA_IO_PU_PD(152), - PORT_DATA_IO_PD(153), - PORT_DATA_IO_PD(154), - PORT_DATA_I_PU_PD(155), - PORT_DATA_IO_PU_PD(156), - PORT_DATA_I_PD(157), - PORT_DATA_IO_PD(158), - PORT_DATA_IO_PU_PD(159), - PORT_DATA_IO_PU_PD(160), - PORT_DATA_I_PU_PD(161), - PORT_DATA_I_PU_PD(162), - PORT_DATA_IO_PU_PD(163), - PORT_DATA_I_PU_PD(164), - PORT_DATA_IO_PD(192), - PORT_DATA_IO_PU_PD(193), - PORT_DATA_IO_PD(194), - PORT_DATA_IO_PU_PD(195), - PORT_DATA_IO_PD(196), - PORT_DATA_IO_PD(197), - PORT_DATA_IO_PD(198), - PORT_DATA_IO_PD(199), - PORT_DATA_IO_PU_PD(200), - PORT_DATA_IO_PU_PD(201), - PORT_DATA_IO_PU_PD(202), - PORT_DATA_IO_PU_PD(203), - PORT_DATA_IO_PU_PD(204), - PORT_DATA_IO_PU_PD(205), - PORT_DATA_IO_PU_PD(206), - PORT_DATA_IO_PD(207), - PORT_DATA_IO_PD(208), - PORT_DATA_IO_PD(209), - PORT_DATA_IO_PD(210), - PORT_DATA_IO_PD(211), - PORT_DATA_IO_PD(212), - PORT_DATA_IO_PD(213), - PORT_DATA_IO_PU_PD(214), - PORT_DATA_IO_PU_PD(215), - PORT_DATA_IO_PD(216), - PORT_DATA_IO_PD(217), - PORT_DATA_O(218), - PORT_DATA_IO_PD(219), - PORT_DATA_IO_PD(220), - PORT_DATA_IO_PU_PD(221), - PORT_DATA_IO_PU_PD(222), - PORT_DATA_I_PU_PD(223), - PORT_DATA_I_PU_PD(224), - - PORT_DATA_IO_PU_PD(225), - PORT_DATA_O(226), - PORT_DATA_IO_PU_PD(227), - PORT_DATA_I_PU_PD(228), - PORT_DATA_I_PD(229), - PORT_DATA_IO(230), - PORT_DATA_IO_PU_PD(231), - PORT_DATA_IO_PU_PD(232), - PORT_DATA_I_PU_PD(233), - PORT_DATA_IO_PU_PD(234), - PORT_DATA_IO_PU_PD(235), - PORT_DATA_IO_PU_PD(236), - PORT_DATA_IO_PD(237), - PORT_DATA_IO_PU_PD(238), - PORT_DATA_IO_PU_PD(239), - PORT_DATA_IO_PU_PD(240), - PORT_DATA_O(241), - PORT_DATA_I_PD(242), - PORT_DATA_IO_PU_PD(243), - PORT_DATA_IO_PU_PD(244), - PORT_DATA_IO_PU_PD(245), - PORT_DATA_IO_PU_PD(246), - PORT_DATA_IO_PU_PD(247), - PORT_DATA_IO_PU_PD(248), - PORT_DATA_IO_PU_PD(249), - PORT_DATA_IO_PU_PD(250), - PORT_DATA_IO_PU_PD(251), - PORT_DATA_IO_PU_PD(252), - PORT_DATA_IO_PU_PD(253), - PORT_DATA_IO_PU_PD(254), - PORT_DATA_IO_PU_PD(255), - PORT_DATA_IO_PU_PD(256), - PORT_DATA_IO_PU_PD(257), - PORT_DATA_IO_PU_PD(258), - PORT_DATA_IO_PU_PD(259), - PORT_DATA_IO_PU_PD(260), - PORT_DATA_IO_PU_PD(261), - PORT_DATA_IO_PU_PD(262), - PORT_DATA_IO_PU_PD(263), - PORT_DATA_IO_PU_PD(264), - PORT_DATA_IO_PU_PD(265), - PORT_DATA_IO_PU_PD(266), - PORT_DATA_IO_PU_PD(267), - PORT_DATA_IO_PU_PD(268), - PORT_DATA_IO_PU_PD(269), - PORT_DATA_IO_PU_PD(270), - PORT_DATA_IO_PU_PD(271), - PORT_DATA_IO_PU_PD(272), - PORT_DATA_IO_PU_PD(273), - PORT_DATA_IO_PU_PD(274), - PORT_DATA_IO_PU_PD(275), - PORT_DATA_IO_PU_PD(276), - PORT_DATA_IO_PU_PD(277), - PORT_DATA_IO_PU_PD(278), - PORT_DATA_IO_PU_PD(279), - PORT_DATA_IO_PU_PD(280), - PORT_DATA_O(281), - PORT_DATA_O(282), - PORT_DATA_I_PU(288), - PORT_DATA_IO_PU_PD(289), - PORT_DATA_IO_PU_PD(290), - PORT_DATA_IO_PU_PD(291), - PORT_DATA_IO_PU_PD(292), - PORT_DATA_IO_PU_PD(293), - PORT_DATA_IO_PU_PD(294), - PORT_DATA_IO_PU_PD(295), - PORT_DATA_IO_PU_PD(296), - PORT_DATA_IO_PU_PD(297), - PORT_DATA_IO_PU_PD(298), - - PORT_DATA_IO_PU_PD(299), - PORT_DATA_IO_PU_PD(300), - PORT_DATA_IO_PU_PD(301), - PORT_DATA_IO_PU_PD(302), - PORT_DATA_IO_PU_PD(303), - PORT_DATA_IO_PU_PD(304), - PORT_DATA_IO_PU_PD(305), - PORT_DATA_O(306), - PORT_DATA_O(307), - PORT_DATA_I_PU(308), - PORT_DATA_O(309), + PINMUX_DATA_GP_ALL(), /* Table 25-1 (Function 0-7) */ PINMUX_DATA(VBUS_0_MARK, PORT0_FN1), @@ -1358,28 +1037,19 @@ static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3), PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1), PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, PORT271_IN_PU, - MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, PORT272_IN_PU, - MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, PORT273_IN_PU, - MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, PORT274_IN_PU, - MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, PORT275_IN_PU, - MSEL4CR_MSEL15_0), \ + PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3), - PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, PORT276_IN_PU, - MSEL4CR_MSEL15_0), \ + PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3), - PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, PORT277_IN_PU, - MSEL4CR_MSEL15_0), \ + PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3), - PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, PORT278_IN_PU, - MSEL4CR_MSEL15_0), \ + PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3), - PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, PORT279_IN_PU, - MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0), PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \ PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2), PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1), @@ -1485,62 +1155,6 @@ static const pinmux_enum_t pinmux_data[] = { PINMUX_DATA(RESETA_N_PU_OFF_MARK, MSEL4CR_MSEL4_1), PINMUX_DATA(EDBGREQ_PD_MARK, MSEL4CR_MSEL1_0), PINMUX_DATA(EDBGREQ_PU_MARK, MSEL4CR_MSEL1_1), - - /* Functions with pull-ups */ - PINMUX_DATA(KEYIN0_PU_MARK, PORT66_FN2, PORT66_IN_PU), - PINMUX_DATA(KEYIN1_PU_MARK, PORT67_FN2, PORT67_IN_PU), - PINMUX_DATA(KEYIN2_PU_MARK, PORT68_FN2, PORT68_IN_PU), - PINMUX_DATA(KEYIN3_PU_MARK, PORT69_FN2, PORT69_IN_PU), - PINMUX_DATA(KEYIN4_PU_MARK, PORT70_FN2, PORT70_IN_PU), - PINMUX_DATA(KEYIN5_PU_MARK, PORT71_FN2, PORT71_IN_PU), - PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU), - PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU), - - PINMUX_DATA(SDHICD0_PU_MARK, PORT251_FN1, PORT251_IN_PU), - PINMUX_DATA(SDHID0_0_PU_MARK, PORT252_FN1, PORT252_IN_PU), - PINMUX_DATA(SDHID0_1_PU_MARK, PORT253_FN1, PORT253_IN_PU), - PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU), - PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU), - PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU), - PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT257_IN_PU), - PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU), - PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU), - PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU), - PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_FN1, PORT262_IN_PU), - PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_FN1, PORT263_IN_PU), - PINMUX_DATA(SDHID2_0_PU_MARK, PORT265_FN1, PORT265_IN_PU), - PINMUX_DATA(SDHID2_1_PU_MARK, PORT266_FN1, PORT266_IN_PU), - PINMUX_DATA(SDHID2_2_PU_MARK, PORT267_FN1, PORT267_IN_PU), - PINMUX_DATA(SDHID2_3_PU_MARK, PORT268_FN1, PORT268_IN_PU), - PINMUX_DATA(SDHICMD2_PU_MARK, PORT269_FN1, PORT269_IN_PU), - - PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU, - MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU, - MSEL4CR_MSEL15_1), - - PINMUX_DATA(MMCD0_0_PU_MARK, - PORT271_FN1, PORT271_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_1_PU_MARK, - PORT272_FN1, PORT272_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_2_PU_MARK, - PORT273_FN1, PORT273_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_3_PU_MARK, - PORT274_FN1, PORT274_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_4_PU_MARK, - PORT275_FN1, PORT275_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_5_PU_MARK, - PORT276_FN1, PORT276_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_6_PU_MARK, - PORT277_FN1, PORT277_IN_PU, MSEL4CR_MSEL15_0), - PINMUX_DATA(MMCD0_7_PU_MARK, - PORT278_FN1, PORT278_IN_PU, MSEL4CR_MSEL15_0), - - PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU), - PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU), - PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU), - PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU), - PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU), }; #define SH73A0_PIN(pin, cfgs) \ @@ -3775,49 +3389,18 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(RESETA_N_PU_OFF), GPIO_FN(EDBGREQ_PD), GPIO_FN(EDBGREQ_PU), - - /* Functions with pull-ups */ - GPIO_FN(KEYIN0_PU), - GPIO_FN(KEYIN1_PU), - GPIO_FN(KEYIN2_PU), - GPIO_FN(KEYIN3_PU), - GPIO_FN(KEYIN4_PU), - GPIO_FN(KEYIN5_PU), - GPIO_FN(KEYIN6_PU), - GPIO_FN(KEYIN7_PU), - GPIO_FN(SDHICD0_PU), - GPIO_FN(SDHID0_0_PU), - GPIO_FN(SDHID0_1_PU), - GPIO_FN(SDHID0_2_PU), - GPIO_FN(SDHID0_3_PU), - GPIO_FN(SDHICMD0_PU), - GPIO_FN(SDHIWP0_PU), - GPIO_FN(SDHID1_0_PU), - GPIO_FN(SDHID1_1_PU), - GPIO_FN(SDHID1_2_PU), - GPIO_FN(SDHID1_3_PU), - GPIO_FN(SDHICMD1_PU), - GPIO_FN(SDHID2_0_PU), - GPIO_FN(SDHID2_1_PU), - GPIO_FN(SDHID2_2_PU), - GPIO_FN(SDHID2_3_PU), - GPIO_FN(SDHICMD2_PU), - GPIO_FN(MMCCMD0_PU), - GPIO_FN(MMCCMD1_PU), - GPIO_FN(MMCD0_0_PU), - GPIO_FN(MMCD0_1_PU), - GPIO_FN(MMCD0_2_PU), - GPIO_FN(MMCD0_3_PU), - GPIO_FN(MMCD0_4_PU), - GPIO_FN(MMCD0_5_PU), - GPIO_FN(MMCD0_6_PU), - GPIO_FN(MMCD0_7_PU), - GPIO_FN(FSIACK_PU), - GPIO_FN(FSIAILR_PU), - GPIO_FN(FSIAIBT_PU), - GPIO_FN(FSIAISLD_PU), }; +#undef PORTCR +#define PORTCR(nr, reg) \ + { \ + PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \ + _PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \ + PORT##nr##_FN0, PORT##nr##_FN1, \ + PORT##nr##_FN2, PORT##nr##_FN3, \ + PORT##nr##_FN4, PORT##nr##_FN5, \ + PORT##nr##_FN6, PORT##nr##_FN7 } \ + } static const struct pinmux_cfg_reg pinmux_config_regs[] = { PORTCR(0, 0xe6050000), /* PORT0CR */ PORTCR(1, 0xe6050001), /* PORT1CR */ @@ -4425,8 +4008,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = { .ops = &sh73a0_pinmux_ops, .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, - .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, - .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, -- cgit From d28d6d1d0d0e119f55c55da2bfcb38d62ff1c2db Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:53:05 +0100 Subject: sh-pfc: sh73a0: Remove KEYSC function GPIOS All sh73a0 platforms now use the pinctrl API to control the KEYSC pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 1249a3ffdb31..33e2b3f8f144 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2996,48 +2996,32 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(A0), \ GPIO_FN(BS_), GPIO_FN(A12), \ - GPIO_FN(PORT58_KEYOUT7), \ GPIO_FN(TPU4TO2), GPIO_FN(A13), \ - GPIO_FN(PORT59_KEYOUT6), \ GPIO_FN(TPU0TO1), GPIO_FN(A14), \ - GPIO_FN(KEYOUT5), GPIO_FN(A15), \ - GPIO_FN(KEYOUT4), GPIO_FN(A16), \ - GPIO_FN(KEYOUT3), \ GPIO_FN(MSIOF0_SS1), GPIO_FN(A17), \ - GPIO_FN(KEYOUT2), \ GPIO_FN(MSIOF0_TSYNC), GPIO_FN(A18), \ - GPIO_FN(KEYOUT1), \ GPIO_FN(MSIOF0_TSCK), GPIO_FN(A19), \ - GPIO_FN(KEYOUT0), \ GPIO_FN(MSIOF0_TXD), GPIO_FN(A20), \ - GPIO_FN(KEYIN0), \ GPIO_FN(MSIOF0_RSCK), GPIO_FN(A21), \ - GPIO_FN(KEYIN1), \ GPIO_FN(MSIOF0_RSYNC), GPIO_FN(A22), \ - GPIO_FN(KEYIN2), \ GPIO_FN(MSIOF0_MCK0), GPIO_FN(A23), \ - GPIO_FN(KEYIN3), \ GPIO_FN(MSIOF0_MCK1), GPIO_FN(A24), \ - GPIO_FN(KEYIN4), \ GPIO_FN(MSIOF0_RXD), GPIO_FN(A25), \ - GPIO_FN(KEYIN5), \ GPIO_FN(MSIOF0_SS2), GPIO_FN(A26), \ - GPIO_FN(KEYIN6), - GPIO_FN(KEYIN7), GPIO_FN(D0_NAF0), GPIO_FN(D1_NAF1), GPIO_FN(D2_NAF2), @@ -3105,13 +3089,9 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VIO_D0), \ GPIO_FN(PORT130_MSIOF2_RXD), \ GPIO_FN(VIO_D1), \ - GPIO_FN(PORT131_KEYOUT6), \ GPIO_FN(PORT131_MSIOF2_SS1), \ - GPIO_FN(PORT131_KEYOUT11), \ GPIO_FN(VIO_D2), \ - GPIO_FN(PORT132_KEYOUT7), \ GPIO_FN(PORT132_MSIOF2_SS2), \ - GPIO_FN(PORT132_KEYOUT10), \ GPIO_FN(VIO_D3), \ GPIO_FN(MSIOF2_TSYNC), \ GPIO_FN(VIO_D4), \ @@ -3119,14 +3099,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VIO_D5), \ GPIO_FN(MSIOF2_TSCK), \ GPIO_FN(VIO_D6), \ - GPIO_FN(PORT136_KEYOUT8), \ GPIO_FN(VIO_D7), \ - GPIO_FN(PORT137_KEYOUT9), \ GPIO_FN(VIO_D8), \ - GPIO_FN(PORT138_KEYOUT8), \ GPIO_FN(VIO2_D0), \ GPIO_FN(VIO_D9), \ - GPIO_FN(PORT139_KEYOUT9), \ GPIO_FN(VIO2_D1), \ GPIO_FN(VIO_D10), \ GPIO_FN(TPU0TO2), \ @@ -3135,14 +3111,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(TPU0TO3), \ GPIO_FN(VIO2_D3), \ GPIO_FN(VIO_D12), \ - GPIO_FN(PORT142_KEYOUT10), \ GPIO_FN(VIO2_D4), \ GPIO_FN(VIO_D13), \ - GPIO_FN(PORT143_KEYOUT11), \ - GPIO_FN(PORT143_KEYOUT6), \ GPIO_FN(VIO2_D5), \ GPIO_FN(VIO_D14), \ - GPIO_FN(PORT144_KEYOUT7), \ GPIO_FN(VIO2_D6), \ GPIO_FN(VIO_D15), \ GPIO_FN(TPU1TO3), \ @@ -3155,7 +3127,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(A27), \ GPIO_FN(PORT149_RDWR), \ GPIO_FN(MFG0_IN1), \ - GPIO_FN(PORT149_KEYOUT9), GPIO_FN(MFG0_IN2), GPIO_FN(TS_SPSYNC3), \ GPIO_FN(MSIOF2_RSCK), @@ -3383,7 +3354,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(IRQ9_MEM_INT), GPIO_FN(IRQ9_MCP_INT), GPIO_FN(A11), - GPIO_FN(KEYOUT8), GPIO_FN(TPU4TO3), GPIO_FN(RESETA_N_PU_ON), GPIO_FN(RESETA_N_PU_OFF), -- cgit From 0ad6fe53678abf33b6d3d882688d0b82591cbc54 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:53:05 +0100 Subject: sh-pfc: sh73a0: Remove BSC function GPIOS All sh73a0 platforms now use the pinctrl API to control the BSC pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 33e2b3f8f144..7b010b6ce44e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3022,37 +3022,11 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(A25), \ GPIO_FN(MSIOF0_SS2), GPIO_FN(A26), \ - GPIO_FN(D0_NAF0), - GPIO_FN(D1_NAF1), - GPIO_FN(D2_NAF2), - GPIO_FN(D3_NAF3), - GPIO_FN(D4_NAF4), - GPIO_FN(D5_NAF5), - GPIO_FN(D6_NAF6), - GPIO_FN(D7_NAF7), - GPIO_FN(D8_NAF8), - GPIO_FN(D9_NAF9), - GPIO_FN(D10_NAF10), - GPIO_FN(D11_NAF11), - GPIO_FN(D12_NAF12), - GPIO_FN(D13_NAF13), - GPIO_FN(D14_NAF14), - GPIO_FN(D15_NAF15), - GPIO_FN(CS4_), - GPIO_FN(CS5A_), \ - GPIO_FN(PORT91_RDWR), - GPIO_FN(CS5B_), \ GPIO_FN(FCE1_), - GPIO_FN(CS6B_), \ GPIO_FN(DACK0), GPIO_FN(FCE0_), \ - GPIO_FN(CS6A_), GPIO_FN(WAIT_), \ GPIO_FN(DREQ0), - GPIO_FN(RD__FSC), - GPIO_FN(WE0__FWE), \ - GPIO_FN(RDWR_FWE), - GPIO_FN(WE1_), GPIO_FN(FRB), GPIO_FN(CKO), GPIO_FN(NBRSTOUT_), @@ -3125,7 +3099,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VIO2_FIELD), \ GPIO_FN(VIO_CKO), GPIO_FN(A27), \ - GPIO_FN(PORT149_RDWR), \ GPIO_FN(MFG0_IN1), \ GPIO_FN(MFG0_IN2), GPIO_FN(TS_SPSYNC3), \ -- cgit From f03e4be625c652e12bc14e9f975ebcde9119a762 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:53:05 +0100 Subject: sh-pfc: sh73a0: Remove USB function GPIOS All sh73a0 platforms now use the pinctrl API to control the USB pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 7b010b6ce44e..273345ceaeec 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2936,11 +2936,10 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(usb), }; -#define PINMUX_FN_BASE GPIO_FN_VBUS_0 +#define PINMUX_FN_BASE GPIO_FN_GPI0 static const struct pinmux_func pinmux_func_gpios[] = { /* Table 25-1 (Functions 0-7) */ - GPIO_FN(VBUS_0), GPIO_FN(GPI0), GPIO_FN(GPI1), GPIO_FN(GPI2), -- cgit From f89fa856639398550528bebd307d4d5e1e625348 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 18:53:05 +0100 Subject: sh-pfc: sh73a0: Remove IrDA function GPIOS All sh73a0 platforms now use the pinctrl API to control the IrDA pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 273345ceaeec..cde4387edce1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2979,7 +2979,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(XWUP), GPIO_FN(VACK), GPIO_FN(XTAL1L), - GPIO_FN(PORT49_IRDA_OUT), \ GPIO_FN(PORT49_IROUT), \ GPIO_FN(BBIF2_TSYNC2), \ GPIO_FN(TPU2TO2), \ @@ -2987,9 +2986,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(BBIF2_TSCK2), \ GPIO_FN(TPU2TO3), \ GPIO_FN(BBIF2_TXD2), - GPIO_FN(PORT53_IRDA_IN), \ GPIO_FN(TPU3TO3), \ - GPIO_FN(PORT54_IRDA_FIRSEL), \ GPIO_FN(TPU3TO2), \ GPIO_FN(TPU0TO0), GPIO_FN(A0), \ @@ -3188,13 +3185,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VIO2_FIELD2), \ GPIO_FN(MSIOF1_SS2), \ GPIO_FN(VIO2_HD2), \ - GPIO_FN(PORT241_IRDA_OUT), \ GPIO_FN(PORT241_IROUT), \ GPIO_FN(MFG4_OUT1), \ GPIO_FN(TPU4TO0), - GPIO_FN(PORT242_IRDA_IN), \ GPIO_FN(MFG4_IN2), - GPIO_FN(PORT243_IRDA_FIRSEL), \ GPIO_FN(PORT243_VIO_CKO2), GPIO_FN(MFG2_IN1), \ GPIO_FN(MSIOF2R_RXD), -- cgit From b56479f233d7205466037ebc8fb2d1851459c86c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 3 Jan 2013 13:07:05 +0100 Subject: sh-pfc: r8a7740: Remove LCD0 and LCD1 function GPIOS All r8a7740 platforms now use the pinctrl API to control the LCD0 and LCD1 pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 37 ------------------------------------ 1 file changed, 37 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index a2f909a7c235..de1212d0912a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2313,43 +2313,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SCIFB_RTS_PORT172), GPIO_FN(SCIFB_CTS_PORT173), - /* LCD0 */ - GPIO_FN(LCD0_D0), GPIO_FN(LCD0_D1), GPIO_FN(LCD0_D2), - GPIO_FN(LCD0_D3), GPIO_FN(LCD0_D4), GPIO_FN(LCD0_D5), - GPIO_FN(LCD0_D6), GPIO_FN(LCD0_D7), GPIO_FN(LCD0_D8), - GPIO_FN(LCD0_D9), GPIO_FN(LCD0_D10), GPIO_FN(LCD0_D11), - GPIO_FN(LCD0_D12), GPIO_FN(LCD0_D13), GPIO_FN(LCD0_D14), - GPIO_FN(LCD0_D15), GPIO_FN(LCD0_D16), GPIO_FN(LCD0_D17), - GPIO_FN(LCD0_DON), GPIO_FN(LCD0_VCPWC), GPIO_FN(LCD0_VEPWC), - GPIO_FN(LCD0_DCK), GPIO_FN(LCD0_VSYN), - GPIO_FN(LCD0_HSYN), GPIO_FN(LCD0_DISP), - GPIO_FN(LCD0_WR), GPIO_FN(LCD0_RD), - GPIO_FN(LCD0_CS), GPIO_FN(LCD0_RS), - - GPIO_FN(LCD0_D18_PORT163), GPIO_FN(LCD0_D19_PORT162), - GPIO_FN(LCD0_D20_PORT161), GPIO_FN(LCD0_D21_PORT158), - GPIO_FN(LCD0_D22_PORT160), GPIO_FN(LCD0_D23_PORT159), - GPIO_FN(LCD0_LCLK_PORT165), /* MSEL5CR_6_1 */ - - GPIO_FN(LCD0_D18_PORT40), GPIO_FN(LCD0_D19_PORT4), - GPIO_FN(LCD0_D20_PORT3), GPIO_FN(LCD0_D21_PORT2), - GPIO_FN(LCD0_D22_PORT0), GPIO_FN(LCD0_D23_PORT1), - GPIO_FN(LCD0_LCLK_PORT102), /* MSEL5CR_6_0 */ - - /* LCD1 */ - GPIO_FN(LCD1_D0), GPIO_FN(LCD1_D1), GPIO_FN(LCD1_D2), - GPIO_FN(LCD1_D3), GPIO_FN(LCD1_D4), GPIO_FN(LCD1_D5), - GPIO_FN(LCD1_D6), GPIO_FN(LCD1_D7), GPIO_FN(LCD1_D8), - GPIO_FN(LCD1_D9), GPIO_FN(LCD1_D10), GPIO_FN(LCD1_D11), - GPIO_FN(LCD1_D12), GPIO_FN(LCD1_D13), GPIO_FN(LCD1_D14), - GPIO_FN(LCD1_D15), GPIO_FN(LCD1_D16), GPIO_FN(LCD1_D17), - GPIO_FN(LCD1_D18), GPIO_FN(LCD1_D19), GPIO_FN(LCD1_D20), - GPIO_FN(LCD1_D21), GPIO_FN(LCD1_D22), GPIO_FN(LCD1_D23), - GPIO_FN(LCD1_RS), GPIO_FN(LCD1_RD), GPIO_FN(LCD1_CS), - GPIO_FN(LCD1_WR), GPIO_FN(LCD1_DCK), GPIO_FN(LCD1_DON), - GPIO_FN(LCD1_VCPWC), GPIO_FN(LCD1_LCLK), GPIO_FN(LCD1_HSYN), - GPIO_FN(LCD1_VSYN), GPIO_FN(LCD1_VEPWC), GPIO_FN(LCD1_DISP), - /* RSPI */ GPIO_FN(RSPI_SSL0_A), GPIO_FN(RSPI_SSL1_A), GPIO_FN(RSPI_SSL2_A), GPIO_FN(RSPI_SSL3_A), GPIO_FN(RSPI_CK_A), GPIO_FN(RSPI_MOSI_A), -- cgit From 3dff629bd8b98759b2a652d0a2b9eda6fb085b18 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 14:36:28 +0100 Subject: sh-pfc: r8a7740: Remove SDHI and MMCIF function GPIOS All r8a7740 platforms now use the pinctrl API to control the SDHI and MMCIF pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index de1212d0912a..3621d3e81fc3 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -2373,26 +2373,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SIM_D_PORT22), /* SIM_D Port 22/199 */ GPIO_FN(SIM_D_PORT199), - /* SDHI0 */ - GPIO_FN(SDHI0_D0), GPIO_FN(SDHI0_D1), GPIO_FN(SDHI0_D2), - GPIO_FN(SDHI0_D3), GPIO_FN(SDHI0_CD), GPIO_FN(SDHI0_WP), - GPIO_FN(SDHI0_CMD), GPIO_FN(SDHI0_CLK), - - /* SDHI1 */ - GPIO_FN(SDHI1_D0), GPIO_FN(SDHI1_D1), GPIO_FN(SDHI1_D2), - GPIO_FN(SDHI1_D3), GPIO_FN(SDHI1_CD), GPIO_FN(SDHI1_WP), - GPIO_FN(SDHI1_CMD), GPIO_FN(SDHI1_CLK), - - /* SDHI2 */ - GPIO_FN(SDHI2_D0), GPIO_FN(SDHI2_D1), GPIO_FN(SDHI2_D2), - GPIO_FN(SDHI2_D3), GPIO_FN(SDHI2_CLK), GPIO_FN(SDHI2_CMD), - - GPIO_FN(SDHI2_CD_PORT24), /* MSEL5CR_19_0 */ - GPIO_FN(SDHI2_WP_PORT25), - - GPIO_FN(SDHI2_WP_PORT177), /* MSEL5CR_19_1 */ - GPIO_FN(SDHI2_CD_PORT202), - /* MSIOF2 */ GPIO_FN(MSIOF2_TXD), GPIO_FN(MSIOF2_RXD), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_SS2), GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_SS1), @@ -2437,21 +2417,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(MEMC_WAIT), GPIO_FN(MEMC_DREQ1), GPIO_FN(MEMC_BUSCLK), GPIO_FN(MEMC_A0), - /* MMC */ - GPIO_FN(MMC0_D0_PORT68), GPIO_FN(MMC0_D1_PORT69), - GPIO_FN(MMC0_D2_PORT70), GPIO_FN(MMC0_D3_PORT71), - GPIO_FN(MMC0_D4_PORT72), GPIO_FN(MMC0_D5_PORT73), - GPIO_FN(MMC0_D6_PORT74), GPIO_FN(MMC0_D7_PORT75), - GPIO_FN(MMC0_CLK_PORT66), - GPIO_FN(MMC0_CMD_PORT67), /* MSEL4CR_15_0 */ - - GPIO_FN(MMC1_D0_PORT149), GPIO_FN(MMC1_D1_PORT148), - GPIO_FN(MMC1_D2_PORT147), GPIO_FN(MMC1_D3_PORT146), - GPIO_FN(MMC1_D4_PORT145), GPIO_FN(MMC1_D5_PORT144), - GPIO_FN(MMC1_D6_PORT143), GPIO_FN(MMC1_D7_PORT142), - GPIO_FN(MMC1_CLK_PORT103), - GPIO_FN(MMC1_CMD_PORT104), /* MSEL4CR_15_1 */ - /* MSIOF0 */ GPIO_FN(MSIOF0_SS1), GPIO_FN(MSIOF0_SS2), GPIO_FN(MSIOF0_RXD), GPIO_FN(MSIOF0_TXD), GPIO_FN(MSIOF0_MCK0), GPIO_FN(MSIOF0_MCK1), -- cgit From 2a02818cbbbc0971312bdbe2971cbcb8092e445c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jan 2013 22:32:25 +0100 Subject: sh-pfc: r8a7779: Remove DU1_DOTCLKOUT1 GPIO The function is not documented in the r8a7779 datasheet. Remove it. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 5b498ffaef03..f1fa355f5d0b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -353,7 +353,7 @@ enum { FN_VI1_DATA6_VI1_B6, FN_SD2_CD, FN_MT0_VCXO, FN_SPA_TMS, FN_HSPI_TX1_D, FN_VI1_DATA7_VI1_B7, FN_SD2_WP, FN_MT0_PWM, FN_SPA_TDI, FN_HSPI_RX1_D, FN_VI1_G0, FN_VI3_DATA0, - FN_DU1_DOTCLKOUT1, FN_TS_SCK1, FN_DREQ2_B, FN_TX2, + FN_TS_SCK1, FN_DREQ2_B, FN_TX2, FN_SPA_TDO, FN_HCTS0_B, FN_VI1_G1, FN_VI3_DATA1, FN_SSI_SCK1, FN_TS_SDEN1, FN_DACK2_B, FN_RX2, FN_HRTS0_B, @@ -615,7 +615,7 @@ enum { HSPI_CS1_D_MARK, ADICHS2_B_MARK, VI1_DATA6_VI1_B6_MARK, SD2_CD_MARK, MT0_VCXO_MARK, SPA_TMS_MARK, HSPI_TX1_D_MARK, VI1_DATA7_VI1_B7_MARK, SD2_WP_MARK, MT0_PWM_MARK, SPA_TDI_MARK, HSPI_RX1_D_MARK, - VI1_G0_MARK, VI3_DATA0_MARK, DU1_DOTCLKOUT1_MARK, TS_SCK1_MARK, + VI1_G0_MARK, VI3_DATA0_MARK, TS_SCK1_MARK, DREQ2_B_MARK, TX2_MARK, SPA_TDO_MARK, HCTS0_B_MARK, VI1_G1_MARK, VI3_DATA1_MARK, SSI_SCK1_MARK, TS_SDEN1_MARK, DACK2_B_MARK, RX2_MARK, HRTS0_B_MARK, @@ -1385,7 +1385,6 @@ static const pinmux_enum_t pinmux_data[] = { PINMUX_IPSR_MODSEL_DATA(IP11_23_21, HSPI_RX1_D, SEL_HSPI1_3), PINMUX_IPSR_DATA(IP11_26_24, VI1_G0), PINMUX_IPSR_DATA(IP11_26_24, VI3_DATA0), - PINMUX_IPSR_DATA(IP11_26_24, DU1_DOTCLKOUT1), PINMUX_IPSR_DATA(IP11_26_24, TS_SCK1), PINMUX_IPSR_MODSEL_DATA(IP11_26_24, DREQ2_B, SEL_EXBUS2_1), PINMUX_IPSR_DATA(IP11_26_24, TX2), @@ -2926,7 +2925,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SD2_CD), GPIO_FN(MT0_VCXO), GPIO_FN(SPA_TMS), GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(SD2_WP), GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(HSPI_RX1_D), - GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), GPIO_FN(DU1_DOTCLKOUT1), + GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(TX2), GPIO_FN(SPA_TDO), GPIO_FN(HCTS0_B), GPIO_FN(VI1_G1), GPIO_FN(VI3_DATA1), GPIO_FN(SSI_SCK1), GPIO_FN(TS_SDEN1), GPIO_FN(DACK2_B), GPIO_FN(RX2), @@ -3634,7 +3633,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { FN_VI1_G1, FN_VI3_DATA1, FN_SSI_SCK1, FN_TS_SDEN1, FN_DACK2_B, FN_RX2, FN_HRTS0_B, 0, /* IP11_26_24 [3] */ - FN_VI1_G0, FN_VI3_DATA0, FN_DU1_DOTCLKOUT1, FN_TS_SCK1, + FN_VI1_G0, FN_VI3_DATA0, 0, FN_TS_SCK1, FN_DREQ2_B, FN_TX2, FN_SPA_TDO, FN_HCTS0_B, /* IP11_23_21 [3] */ FN_VI1_DATA7_VI1_B7, FN_SD2_WP, FN_MT0_PWM, FN_SPA_TDI, -- cgit From dd11cd3d1b92b5d4d8a1918a4cf58f6c335af6a4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 14:36:28 +0100 Subject: sh-pfc: r8a7779: Remove SDHI and MMCIF function GPIOS All r8a7779 platforms now use the pinctrl API to control the SDHI and MMCIF pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 112 +++++++++++++++++------------------ 1 file changed, 56 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index f1fa355f5d0b..0a6500387bd8 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2678,16 +2678,16 @@ static const struct pinmux_func pinmux_func_gpios[] = { /* IPSR0 */ GPIO_FN(USB_PENC2), GPIO_FN(SCK0), GPIO_FN(PWM1), GPIO_FN(PWMFSW0), - GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), GPIO_FN(SD1_DAT2), - GPIO_FN(MMC0_D2), GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF), - GPIO_FN(HCTS1), GPIO_FN(TX4_C), GPIO_FN(A0), GPIO_FN(SD1_DAT3), - GPIO_FN(MMC0_D3), GPIO_FN(FD3), GPIO_FN(A20), GPIO_FN(TX5_D), + GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), + GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF), + GPIO_FN(HCTS1), GPIO_FN(TX4_C), GPIO_FN(A0), + GPIO_FN(FD3), GPIO_FN(A20), GPIO_FN(TX5_D), GPIO_FN(HSPI_TX2_B), GPIO_FN(A21), GPIO_FN(SCK5_D), GPIO_FN(HSPI_CLK2_B), GPIO_FN(A22), GPIO_FN(RX5_D), GPIO_FN(HSPI_RX2_B), GPIO_FN(VI1_R0), GPIO_FN(A23), GPIO_FN(FCLE), - GPIO_FN(HSPI_CLK2), GPIO_FN(VI1_R1), GPIO_FN(A24), GPIO_FN(SD1_CD), - GPIO_FN(MMC0_D4), GPIO_FN(FD4), GPIO_FN(HSPI_CS2), GPIO_FN(VI1_R2), - GPIO_FN(SSI_WS78_B), GPIO_FN(A25), GPIO_FN(SD1_WP), GPIO_FN(MMC0_D5), + GPIO_FN(HSPI_CLK2), GPIO_FN(VI1_R1), GPIO_FN(A24), + GPIO_FN(FD4), GPIO_FN(HSPI_CS2), GPIO_FN(VI1_R2), + GPIO_FN(SSI_WS78_B), GPIO_FN(A25), GPIO_FN(FD5), GPIO_FN(HSPI_RX2), GPIO_FN(VI1_R3), GPIO_FN(TX5_B), GPIO_FN(SSI_SDATA7_B), GPIO_FN(CTS0_B), GPIO_FN(CLKOUT), GPIO_FN(TX3C_IRDA_TX_C), GPIO_FN(PWM0_B), GPIO_FN(CS0), @@ -2696,17 +2696,17 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI1_R7), GPIO_FN(HRTS1), GPIO_FN(RX4_C), /* IPSR1 */ - GPIO_FN(EX_CS0), GPIO_FN(RX3_C_IRDA_RX_C), GPIO_FN(MMC0_D6), - GPIO_FN(FD6), GPIO_FN(EX_CS1), GPIO_FN(MMC0_D7), GPIO_FN(FD7), - GPIO_FN(EX_CS2), GPIO_FN(SD1_CLK), GPIO_FN(MMC0_CLK), GPIO_FN(FALE), - GPIO_FN(ATACS00), GPIO_FN(EX_CS3), GPIO_FN(SD1_CMD), GPIO_FN(MMC0_CMD), + GPIO_FN(EX_CS0), GPIO_FN(RX3_C_IRDA_RX_C), + GPIO_FN(FD6), GPIO_FN(EX_CS1), GPIO_FN(FD7), + GPIO_FN(EX_CS2), GPIO_FN(FALE), + GPIO_FN(ATACS00), GPIO_FN(EX_CS3), GPIO_FN(FRE), GPIO_FN(ATACS10), GPIO_FN(VI1_R4), GPIO_FN(RX5_B), GPIO_FN(HSCK1), GPIO_FN(SSI_SDATA8_B), GPIO_FN(RTS0_B_TANS_B), - GPIO_FN(SSI_SDATA9), GPIO_FN(EX_CS4), GPIO_FN(SD1_DAT0), - GPIO_FN(MMC0_D0), GPIO_FN(FD0), GPIO_FN(ATARD0), GPIO_FN(VI1_R5), + GPIO_FN(SSI_SDATA9), GPIO_FN(EX_CS4), + GPIO_FN(FD0), GPIO_FN(ATARD0), GPIO_FN(VI1_R5), GPIO_FN(SCK5_B), GPIO_FN(HTX1), GPIO_FN(TX2_E), GPIO_FN(TX0_B), - GPIO_FN(SSI_SCK9), GPIO_FN(EX_CS5), GPIO_FN(SD1_DAT1), - GPIO_FN(MMC0_D1), GPIO_FN(FD1), GPIO_FN(ATAWR0), GPIO_FN(VI1_R6), + GPIO_FN(SSI_SCK9), GPIO_FN(EX_CS5), + GPIO_FN(FD1), GPIO_FN(ATAWR0), GPIO_FN(VI1_R6), GPIO_FN(HRX1), GPIO_FN(RX2_E), GPIO_FN(RX0_B), GPIO_FN(SSI_WS9), GPIO_FN(MLB_CLK), GPIO_FN(PWM2), GPIO_FN(SCK4), GPIO_FN(MLB_SIG), GPIO_FN(PWM3), GPIO_FN(TX4), GPIO_FN(MLB_DAT), GPIO_FN(PWM4), @@ -2766,26 +2766,26 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), GPIO_FN(RX2_C), GPIO_FN(DREQ0_B), GPIO_FN(SSI_SCK78_B), GPIO_FN(SCK0_B), GPIO_FN(VI2_DATA0_VI2_B0), GPIO_FN(PWM6), - GPIO_FN(SD3_CLK), GPIO_FN(TX3_E_IRDA_TX_E), GPIO_FN(AUDCK), + GPIO_FN(TX3_E_IRDA_TX_E), GPIO_FN(AUDCK), GPIO_FN(PWMFSW0_B), GPIO_FN(VI2_DATA1_VI2_B1), - GPIO_FN(PWM0), GPIO_FN(SD3_CMD), GPIO_FN(RX3_E_IRDA_RX_E), + GPIO_FN(PWM0), GPIO_FN(RX3_E_IRDA_RX_E), GPIO_FN(AUDSYNC), GPIO_FN(CTS0_D), GPIO_FN(VI2_G0), GPIO_FN(VI2_G1), GPIO_FN(VI2_G2), GPIO_FN(VI2_G3), GPIO_FN(VI2_G4), GPIO_FN(VI2_G5), - GPIO_FN(VI2_DATA2_VI2_B2), GPIO_FN(SCL1_B), GPIO_FN(SD3_DAT2), + GPIO_FN(VI2_DATA2_VI2_B2), GPIO_FN(SCL1_B), GPIO_FN(SCK3_E), GPIO_FN(AUDATA6), GPIO_FN(TX0_D), - GPIO_FN(VI2_DATA3_VI2_B3), GPIO_FN(SDA1_B), GPIO_FN(SD3_DAT3), + GPIO_FN(VI2_DATA3_VI2_B3), GPIO_FN(SDA1_B), GPIO_FN(SCK5), GPIO_FN(AUDATA7), GPIO_FN(RX0_D), GPIO_FN(VI2_G6), GPIO_FN(VI2_G7), GPIO_FN(VI2_R0), GPIO_FN(VI2_R1), GPIO_FN(VI2_R2), GPIO_FN(VI2_R3), - GPIO_FN(VI2_DATA4_VI2_B4), GPIO_FN(SCL2_B), GPIO_FN(SD3_DAT0), + GPIO_FN(VI2_DATA4_VI2_B4), GPIO_FN(SCL2_B), GPIO_FN(TX5), GPIO_FN(SCK0_D), /* IPSR5 */ GPIO_FN(VI2_DATA5_VI2_B5), GPIO_FN(SDA2_B), - GPIO_FN(SD3_DAT1), GPIO_FN(RX5), GPIO_FN(RTS0_D_TANS_D), + GPIO_FN(RX5), GPIO_FN(RTS0_D_TANS_D), GPIO_FN(VI2_R4), GPIO_FN(VI2_R5), GPIO_FN(VI2_R6), GPIO_FN(VI2_R7), GPIO_FN(SCL2_D), GPIO_FN(SDA2_D), @@ -2794,14 +2794,14 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SDA1_D), GPIO_FN(VI2_HSYNC), GPIO_FN(VI3_HSYNC), GPIO_FN(VI2_VSYNC), GPIO_FN(VI3_VSYNC), - GPIO_FN(VI2_CLK), GPIO_FN(TX3_B_IRDA_TX_B), GPIO_FN(SD3_CD), + GPIO_FN(VI2_CLK), GPIO_FN(TX3_B_IRDA_TX_B), GPIO_FN(HSPI_TX1), GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB), GPIO_FN(AUDIO_CLKC), GPIO_FN(TX2_D), GPIO_FN(SPEEDIN), GPIO_FN(GPS_SIGN_D), GPIO_FN(VI2_DATA6_VI2_B6), GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(HSPI_CLK1), GPIO_FN(SCK2_D), GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D), GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(RX3_B_IRDA_RX_B), - GPIO_FN(SD3_WP), GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD), + GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD), GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(RX2_D), GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA), GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(USB_OVC2), @@ -2835,14 +2835,14 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SSI_WS9_B), GPIO_FN(HSPI_CS1_C), GPIO_FN(SSI_SDATA7), GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(IRQ2_B), GPIO_FN(TCLK1_C), GPIO_FN(HSPI_TX1_C), GPIO_FN(SSI_SDATA8), GPIO_FN(VSP), - GPIO_FN(IRQ3_B), GPIO_FN(HSPI_RX1_C), GPIO_FN(SD0_CLK), - GPIO_FN(ATACS01), GPIO_FN(SCK1_B), GPIO_FN(SD0_CMD), GPIO_FN(ATACS11), - GPIO_FN(TX1_B), GPIO_FN(CC5_TDO), GPIO_FN(SD0_DAT0), GPIO_FN(ATADIR1), - GPIO_FN(RX1_B), GPIO_FN(CC5_TRST), GPIO_FN(SD0_DAT1), GPIO_FN(ATAG1), - GPIO_FN(SCK2_B), GPIO_FN(CC5_TMS), GPIO_FN(SD0_DAT2), GPIO_FN(ATARD1), - GPIO_FN(TX2_B), GPIO_FN(CC5_TCK), GPIO_FN(SD0_DAT3), GPIO_FN(ATAWR1), - GPIO_FN(RX2_B), GPIO_FN(CC5_TDI), GPIO_FN(SD0_CD), GPIO_FN(DREQ2), - GPIO_FN(RTS1_B_TANS_B), GPIO_FN(SD0_WP), GPIO_FN(DACK2), + GPIO_FN(IRQ3_B), GPIO_FN(HSPI_RX1_C), + GPIO_FN(ATACS01), GPIO_FN(SCK1_B), GPIO_FN(ATACS11), + GPIO_FN(TX1_B), GPIO_FN(CC5_TDO), GPIO_FN(ATADIR1), + GPIO_FN(RX1_B), GPIO_FN(CC5_TRST), GPIO_FN(ATAG1), + GPIO_FN(SCK2_B), GPIO_FN(CC5_TMS), GPIO_FN(ATARD1), + GPIO_FN(TX2_B), GPIO_FN(CC5_TCK), GPIO_FN(ATAWR1), + GPIO_FN(RX2_B), GPIO_FN(CC5_TDI), GPIO_FN(DREQ2), + GPIO_FN(RTS1_B_TANS_B), GPIO_FN(DACK2), GPIO_FN(CTS1_B), /* IPSR8 */ @@ -2859,46 +2859,46 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CC5_STATE15), GPIO_FN(CC5_STATE23), GPIO_FN(CC5_STATE31), GPIO_FN(CC5_STATE39), GPIO_FN(FMCLK), GPIO_FN(RDS_CLK), GPIO_FN(PCMOE), GPIO_FN(BPFCLK), GPIO_FN(PCMWE), GPIO_FN(FMIN), GPIO_FN(RDS_DATA), - GPIO_FN(VI0_CLK), GPIO_FN(MMC1_CLK), GPIO_FN(VI0_CLKENB), + GPIO_FN(VI0_CLK), GPIO_FN(VI0_CLKENB), GPIO_FN(TX1_C), GPIO_FN(HTX1_B), GPIO_FN(MT1_SYNC), GPIO_FN(VI0_FIELD), GPIO_FN(RX1_C), GPIO_FN(HRX1_B), GPIO_FN(VI0_HSYNC), GPIO_FN(VI0_DATA0_B_VI0_B0_B), GPIO_FN(CTS1_C), - GPIO_FN(TX4_D), GPIO_FN(MMC1_CMD), GPIO_FN(HSCK1_B), + GPIO_FN(TX4_D), GPIO_FN(HSCK1_B), GPIO_FN(VI0_VSYNC), GPIO_FN(VI0_DATA1_B_VI0_B1_B), GPIO_FN(RTS1_C_TANS_C), GPIO_FN(RX4_D), GPIO_FN(PWMFSW0_C), /* IPSR9 */ GPIO_FN(VI0_DATA0_VI0_B0), GPIO_FN(HRTS1_B), GPIO_FN(MT1_VCXO), GPIO_FN(VI0_DATA1_VI0_B1), GPIO_FN(HCTS1_B), GPIO_FN(MT1_PWM), - GPIO_FN(VI0_DATA2_VI0_B2), GPIO_FN(MMC1_D0), GPIO_FN(VI0_DATA3_VI0_B3), - GPIO_FN(MMC1_D1), GPIO_FN(VI0_DATA4_VI0_B4), GPIO_FN(MMC1_D2), - GPIO_FN(VI0_DATA5_VI0_B5), GPIO_FN(MMC1_D3), GPIO_FN(VI0_DATA6_VI0_B6), - GPIO_FN(MMC1_D4), GPIO_FN(ARM_TRACEDATA_0), GPIO_FN(VI0_DATA7_VI0_B7), - GPIO_FN(MMC1_D5), GPIO_FN(ARM_TRACEDATA_1), GPIO_FN(VI0_G0), + GPIO_FN(VI0_DATA2_VI0_B2), GPIO_FN(VI0_DATA3_VI0_B3), + GPIO_FN(VI0_DATA4_VI0_B4), + GPIO_FN(VI0_DATA5_VI0_B5), GPIO_FN(VI0_DATA6_VI0_B6), + GPIO_FN(ARM_TRACEDATA_0), GPIO_FN(VI0_DATA7_VI0_B7), + GPIO_FN(ARM_TRACEDATA_1), GPIO_FN(VI0_G0), GPIO_FN(SSI_SCK78_C), GPIO_FN(IRQ0), GPIO_FN(ARM_TRACEDATA_2), GPIO_FN(VI0_G1), GPIO_FN(SSI_WS78_C), GPIO_FN(IRQ1), GPIO_FN(ARM_TRACEDATA_3), GPIO_FN(VI0_G2), GPIO_FN(ETH_TXD1), - GPIO_FN(MMC1_D6), GPIO_FN(ARM_TRACEDATA_4), GPIO_FN(TS_SPSYNC0), - GPIO_FN(VI0_G3), GPIO_FN(ETH_CRS_DV), GPIO_FN(MMC1_D7), + GPIO_FN(ARM_TRACEDATA_4), GPIO_FN(TS_SPSYNC0), + GPIO_FN(VI0_G3), GPIO_FN(ETH_CRS_DV), GPIO_FN(ARM_TRACEDATA_5), GPIO_FN(TS_SDAT0), GPIO_FN(VI0_G4), - GPIO_FN(ETH_TX_EN), GPIO_FN(SD2_DAT0_B), GPIO_FN(ARM_TRACEDATA_6), - GPIO_FN(VI0_G5), GPIO_FN(ETH_RX_ER), GPIO_FN(SD2_DAT1_B), + GPIO_FN(ETH_TX_EN), GPIO_FN(ARM_TRACEDATA_6), + GPIO_FN(VI0_G5), GPIO_FN(ETH_RX_ER), GPIO_FN(ARM_TRACEDATA_7), GPIO_FN(VI0_G6), GPIO_FN(ETH_RXD0), - GPIO_FN(SD2_DAT2_B), GPIO_FN(ARM_TRACEDATA_8), GPIO_FN(VI0_G7), - GPIO_FN(ETH_RXD1), GPIO_FN(SD2_DAT3_B), GPIO_FN(ARM_TRACEDATA_9), + GPIO_FN(ARM_TRACEDATA_8), GPIO_FN(VI0_G7), + GPIO_FN(ETH_RXD1), GPIO_FN(ARM_TRACEDATA_9), /* IPSR10 */ GPIO_FN(VI0_R0), GPIO_FN(SSI_SDATA7_C), GPIO_FN(SCK1_C), GPIO_FN(DREQ1_B), GPIO_FN(ARM_TRACEDATA_10), GPIO_FN(DREQ0_C), GPIO_FN(VI0_R1), GPIO_FN(SSI_SDATA8_C), GPIO_FN(DACK1_B), GPIO_FN(ARM_TRACEDATA_11), GPIO_FN(DACK0_C), GPIO_FN(DRACK0_C), - GPIO_FN(VI0_R2), GPIO_FN(ETH_LINK), GPIO_FN(SD2_CLK_B), GPIO_FN(IRQ2), + GPIO_FN(VI0_R2), GPIO_FN(ETH_LINK), GPIO_FN(IRQ2), GPIO_FN(ARM_TRACEDATA_12), GPIO_FN(VI0_R3), GPIO_FN(ETH_MAGIC), - GPIO_FN(SD2_CMD_B), GPIO_FN(IRQ3), GPIO_FN(ARM_TRACEDATA_13), - GPIO_FN(VI0_R4), GPIO_FN(ETH_REFCLK), GPIO_FN(SD2_CD_B), + GPIO_FN(IRQ3), GPIO_FN(ARM_TRACEDATA_13), + GPIO_FN(VI0_R4), GPIO_FN(ETH_REFCLK), GPIO_FN(HSPI_CLK1_B), GPIO_FN(ARM_TRACEDATA_14), GPIO_FN(MT1_CLK), GPIO_FN(TS_SCK0), GPIO_FN(VI0_R5), GPIO_FN(ETH_TXD0), - GPIO_FN(SD2_WP_B), GPIO_FN(HSPI_CS1_B), GPIO_FN(ARM_TRACEDATA_15), + GPIO_FN(HSPI_CS1_B), GPIO_FN(ARM_TRACEDATA_15), GPIO_FN(MT1_D), GPIO_FN(TS_SDEN0), GPIO_FN(VI0_R6), GPIO_FN(ETH_MDC), GPIO_FN(DREQ2_C), GPIO_FN(HSPI_TX1_B), GPIO_FN(TRACECLK), GPIO_FN(MT1_BEN), GPIO_FN(PWMFSW0_D), GPIO_FN(VI0_R7), @@ -2911,19 +2911,19 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SPV_TRST), GPIO_FN(SCL3), /* IPSR11 */ - GPIO_FN(VI1_DATA0_VI1_B0), GPIO_FN(SD2_DAT0), GPIO_FN(SIM_RST), + GPIO_FN(VI1_DATA0_VI1_B0), GPIO_FN(SIM_RST), GPIO_FN(SPV_TCK), GPIO_FN(ADICLK_B), GPIO_FN(VI1_DATA1_VI1_B1), - GPIO_FN(SD2_DAT1), GPIO_FN(MT0_CLK), GPIO_FN(SPV_TMS), - GPIO_FN(ADICS_B_SAMP_B), GPIO_FN(VI1_DATA2_VI1_B2), GPIO_FN(SD2_DAT2), + GPIO_FN(MT0_CLK), GPIO_FN(SPV_TMS), + GPIO_FN(ADICS_B_SAMP_B), GPIO_FN(VI1_DATA2_VI1_B2), GPIO_FN(MT0_D), GPIO_FN(SPVTDI), GPIO_FN(ADIDATA_B), - GPIO_FN(VI1_DATA3_VI1_B3), GPIO_FN(SD2_DAT3), GPIO_FN(MT0_BEN), + GPIO_FN(VI1_DATA3_VI1_B3), GPIO_FN(MT0_BEN), GPIO_FN(SPV_TDO), GPIO_FN(ADICHS0_B), GPIO_FN(VI1_DATA4_VI1_B4), - GPIO_FN(SD2_CLK), GPIO_FN(MT0_PEN), GPIO_FN(SPA_TRST), + GPIO_FN(MT0_PEN), GPIO_FN(SPA_TRST), GPIO_FN(HSPI_CLK1_D), GPIO_FN(ADICHS1_B), GPIO_FN(VI1_DATA5_VI1_B5), - GPIO_FN(SD2_CMD), GPIO_FN(MT0_SYNC), GPIO_FN(SPA_TCK), + GPIO_FN(MT0_SYNC), GPIO_FN(SPA_TCK), GPIO_FN(HSPI_CS1_D), GPIO_FN(ADICHS2_B), GPIO_FN(VI1_DATA6_VI1_B6), - GPIO_FN(SD2_CD), GPIO_FN(MT0_VCXO), GPIO_FN(SPA_TMS), - GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(SD2_WP), + GPIO_FN(MT0_VCXO), GPIO_FN(SPA_TMS), + GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(HSPI_RX1_D), GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(TX2), GPIO_FN(SPA_TDO), -- cgit From c97c7464f9b131ab16ce3dd39f5ddf8eeb68d7c0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 14:36:28 +0100 Subject: sh-pfc: r8a7779: Remove SCIF function GPIOS All r8a7779 platforms now use the pinctrl API to control the SCIF pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 141 +++++++++++++++++------------------ 1 file changed, 69 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 0a6500387bd8..ecc300db2370 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2677,61 +2677,61 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(A19), /* IPSR0 */ - GPIO_FN(USB_PENC2), GPIO_FN(SCK0), GPIO_FN(PWM1), GPIO_FN(PWMFSW0), + GPIO_FN(USB_PENC2), GPIO_FN(PWM1), GPIO_FN(PWMFSW0), GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF), - GPIO_FN(HCTS1), GPIO_FN(TX4_C), GPIO_FN(A0), - GPIO_FN(FD3), GPIO_FN(A20), GPIO_FN(TX5_D), - GPIO_FN(HSPI_TX2_B), GPIO_FN(A21), GPIO_FN(SCK5_D), - GPIO_FN(HSPI_CLK2_B), GPIO_FN(A22), GPIO_FN(RX5_D), + GPIO_FN(HCTS1), GPIO_FN(A0), + GPIO_FN(FD3), GPIO_FN(A20), + GPIO_FN(HSPI_TX2_B), GPIO_FN(A21), + GPIO_FN(HSPI_CLK2_B), GPIO_FN(A22), GPIO_FN(HSPI_RX2_B), GPIO_FN(VI1_R0), GPIO_FN(A23), GPIO_FN(FCLE), GPIO_FN(HSPI_CLK2), GPIO_FN(VI1_R1), GPIO_FN(A24), GPIO_FN(FD4), GPIO_FN(HSPI_CS2), GPIO_FN(VI1_R2), GPIO_FN(SSI_WS78_B), GPIO_FN(A25), - GPIO_FN(FD5), GPIO_FN(HSPI_RX2), GPIO_FN(VI1_R3), GPIO_FN(TX5_B), - GPIO_FN(SSI_SDATA7_B), GPIO_FN(CTS0_B), GPIO_FN(CLKOUT), - GPIO_FN(TX3C_IRDA_TX_C), GPIO_FN(PWM0_B), GPIO_FN(CS0), + GPIO_FN(FD5), GPIO_FN(HSPI_RX2), GPIO_FN(VI1_R3), + GPIO_FN(SSI_SDATA7_B), GPIO_FN(CLKOUT), + GPIO_FN(PWM0_B), GPIO_FN(CS0), GPIO_FN(HSPI_CS2_B), GPIO_FN(CS1_A26), GPIO_FN(HSPI_TX2), GPIO_FN(SDSELF_B), GPIO_FN(RD_WR), GPIO_FN(FWE), GPIO_FN(ATAG0), - GPIO_FN(VI1_R7), GPIO_FN(HRTS1), GPIO_FN(RX4_C), + GPIO_FN(VI1_R7), GPIO_FN(HRTS1), /* IPSR1 */ - GPIO_FN(EX_CS0), GPIO_FN(RX3_C_IRDA_RX_C), + GPIO_FN(EX_CS0), GPIO_FN(FD6), GPIO_FN(EX_CS1), GPIO_FN(FD7), GPIO_FN(EX_CS2), GPIO_FN(FALE), GPIO_FN(ATACS00), GPIO_FN(EX_CS3), - GPIO_FN(FRE), GPIO_FN(ATACS10), GPIO_FN(VI1_R4), GPIO_FN(RX5_B), - GPIO_FN(HSCK1), GPIO_FN(SSI_SDATA8_B), GPIO_FN(RTS0_B_TANS_B), + GPIO_FN(FRE), GPIO_FN(ATACS10), GPIO_FN(VI1_R4), + GPIO_FN(HSCK1), GPIO_FN(SSI_SDATA8_B), GPIO_FN(SSI_SDATA9), GPIO_FN(EX_CS4), GPIO_FN(FD0), GPIO_FN(ATARD0), GPIO_FN(VI1_R5), - GPIO_FN(SCK5_B), GPIO_FN(HTX1), GPIO_FN(TX2_E), GPIO_FN(TX0_B), + GPIO_FN(HTX1), GPIO_FN(SSI_SCK9), GPIO_FN(EX_CS5), GPIO_FN(FD1), GPIO_FN(ATAWR0), GPIO_FN(VI1_R6), - GPIO_FN(HRX1), GPIO_FN(RX2_E), GPIO_FN(RX0_B), GPIO_FN(SSI_WS9), - GPIO_FN(MLB_CLK), GPIO_FN(PWM2), GPIO_FN(SCK4), GPIO_FN(MLB_SIG), - GPIO_FN(PWM3), GPIO_FN(TX4), GPIO_FN(MLB_DAT), GPIO_FN(PWM4), - GPIO_FN(RX4), GPIO_FN(HTX0), GPIO_FN(TX1), GPIO_FN(SDATA), - GPIO_FN(CTS0_C), GPIO_FN(SUB_TCK), GPIO_FN(CC5_STATE2), + GPIO_FN(HRX1), GPIO_FN(SSI_WS9), + GPIO_FN(MLB_CLK), GPIO_FN(PWM2), GPIO_FN(MLB_SIG), + GPIO_FN(PWM3), GPIO_FN(MLB_DAT), GPIO_FN(PWM4), + GPIO_FN(HTX0), GPIO_FN(SDATA), + GPIO_FN(SUB_TCK), GPIO_FN(CC5_STATE2), GPIO_FN(CC5_STATE10), GPIO_FN(CC5_STATE18), GPIO_FN(CC5_STATE26), GPIO_FN(CC5_STATE34), /* IPSR2 */ - GPIO_FN(HRX0), GPIO_FN(RX1), GPIO_FN(SCKZ), GPIO_FN(RTS0_C_TANS_C), + GPIO_FN(HRX0), GPIO_FN(SCKZ), GPIO_FN(SUB_TDI), GPIO_FN(CC5_STATE3), GPIO_FN(CC5_STATE11), GPIO_FN(CC5_STATE19), GPIO_FN(CC5_STATE27), GPIO_FN(CC5_STATE35), - GPIO_FN(HSCK0), GPIO_FN(SCK1), GPIO_FN(MTS), GPIO_FN(PWM5), - GPIO_FN(SCK0_C), GPIO_FN(SSI_SDATA9_B), GPIO_FN(SUB_TDO), + GPIO_FN(HSCK0), GPIO_FN(MTS), GPIO_FN(PWM5), + GPIO_FN(SSI_SDATA9_B), GPIO_FN(SUB_TDO), GPIO_FN(CC5_STATE0), GPIO_FN(CC5_STATE8), GPIO_FN(CC5_STATE16), GPIO_FN(CC5_STATE24), GPIO_FN(CC5_STATE32), GPIO_FN(HCTS0), - GPIO_FN(CTS1), GPIO_FN(STM), GPIO_FN(PWM0_D), GPIO_FN(RX0_C), + GPIO_FN(STM), GPIO_FN(PWM0_D), GPIO_FN(SCIF_CLK_C), GPIO_FN(SUB_TRST), GPIO_FN(TCLK1_B), - GPIO_FN(CC5_OSCOUT), GPIO_FN(HRTS0), GPIO_FN(RTS1_TANS), - GPIO_FN(MDATA), GPIO_FN(TX0_C), GPIO_FN(SUB_TMS), GPIO_FN(CC5_STATE1), + GPIO_FN(CC5_OSCOUT), GPIO_FN(HRTS0), + GPIO_FN(MDATA), GPIO_FN(SUB_TMS), GPIO_FN(CC5_STATE1), GPIO_FN(CC5_STATE9), GPIO_FN(CC5_STATE17), GPIO_FN(CC5_STATE25), GPIO_FN(CC5_STATE33), GPIO_FN(LCDOUT0), GPIO_FN(DREQ0), GPIO_FN(GPS_CLK_B), GPIO_FN(AUDATA0), - GPIO_FN(TX5_C), GPIO_FN(LCDOUT1), GPIO_FN(DACK0), - GPIO_FN(DRACK0), GPIO_FN(GPS_SIGN_B), GPIO_FN(AUDATA1), GPIO_FN(RX5_C), + GPIO_FN(LCDOUT1), GPIO_FN(DACK0), + GPIO_FN(DRACK0), GPIO_FN(GPS_SIGN_B), GPIO_FN(AUDATA1), GPIO_FN(LCDOUT2), GPIO_FN(LCDOUT3), GPIO_FN(LCDOUT4), GPIO_FN(LCDOUT5), GPIO_FN(LCDOUT6), GPIO_FN(LCDOUT7), @@ -2747,45 +2747,43 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(LCDOUT15), GPIO_FN(LCDOUT16), GPIO_FN(EX_WAIT1), GPIO_FN(SCL1), GPIO_FN(TCLK1), GPIO_FN(AUDATA4), GPIO_FN(LCDOUT17), GPIO_FN(EX_WAIT2), GPIO_FN(SDA1), - GPIO_FN(GPS_MAG_B), GPIO_FN(AUDATA5), GPIO_FN(SCK5_C), + GPIO_FN(GPS_MAG_B), GPIO_FN(AUDATA5), GPIO_FN(LCDOUT18), GPIO_FN(LCDOUT19), GPIO_FN(LCDOUT20), GPIO_FN(LCDOUT21), GPIO_FN(LCDOUT22), GPIO_FN(LCDOUT23), - GPIO_FN(QSTVA_QVS), GPIO_FN(TX3_D_IRDA_TX_D), + GPIO_FN(QSTVA_QVS), GPIO_FN(SCL3_B), GPIO_FN(QCLK), - GPIO_FN(QSTVB_QVE), GPIO_FN(RX3_D_IRDA_RX_D), + GPIO_FN(QSTVB_QVE), GPIO_FN(SDA3_B), GPIO_FN(SDA2_C), GPIO_FN(DACK0_B), GPIO_FN(DRACK0_B), GPIO_FN(QSTH_QHS), GPIO_FN(QSTB_QHE), GPIO_FN(QCPV_QDE), - GPIO_FN(CAN1_TX), GPIO_FN(TX2_C), GPIO_FN(SCL2_C), GPIO_FN(REMOCON), + GPIO_FN(CAN1_TX), GPIO_FN(SCL2_C), GPIO_FN(REMOCON), /* IPSR4 */ - GPIO_FN(QPOLA), GPIO_FN(CAN_CLK_C), GPIO_FN(SCK2_C), - GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), GPIO_FN(RX2_C), - GPIO_FN(DREQ0_B), GPIO_FN(SSI_SCK78_B), GPIO_FN(SCK0_B), + GPIO_FN(QPOLA), GPIO_FN(CAN_CLK_C), + GPIO_FN(QPOLB), GPIO_FN(CAN1_RX), + GPIO_FN(DREQ0_B), GPIO_FN(SSI_SCK78_B), GPIO_FN(VI2_DATA0_VI2_B0), GPIO_FN(PWM6), - GPIO_FN(TX3_E_IRDA_TX_E), GPIO_FN(AUDCK), + GPIO_FN(AUDCK), GPIO_FN(PWMFSW0_B), GPIO_FN(VI2_DATA1_VI2_B1), - GPIO_FN(PWM0), GPIO_FN(RX3_E_IRDA_RX_E), - GPIO_FN(AUDSYNC), GPIO_FN(CTS0_D), GPIO_FN(VI2_G0), + GPIO_FN(PWM0), + GPIO_FN(AUDSYNC), GPIO_FN(VI2_G0), GPIO_FN(VI2_G1), GPIO_FN(VI2_G2), GPIO_FN(VI2_G3), GPIO_FN(VI2_G4), GPIO_FN(VI2_G5), GPIO_FN(VI2_DATA2_VI2_B2), GPIO_FN(SCL1_B), - GPIO_FN(SCK3_E), GPIO_FN(AUDATA6), GPIO_FN(TX0_D), + GPIO_FN(AUDATA6), GPIO_FN(VI2_DATA3_VI2_B3), GPIO_FN(SDA1_B), - GPIO_FN(SCK5), GPIO_FN(AUDATA7), GPIO_FN(RX0_D), + GPIO_FN(AUDATA7), GPIO_FN(VI2_G6), GPIO_FN(VI2_G7), GPIO_FN(VI2_R0), GPIO_FN(VI2_R1), GPIO_FN(VI2_R2), GPIO_FN(VI2_R3), GPIO_FN(VI2_DATA4_VI2_B4), GPIO_FN(SCL2_B), - GPIO_FN(TX5), GPIO_FN(SCK0_D), /* IPSR5 */ GPIO_FN(VI2_DATA5_VI2_B5), GPIO_FN(SDA2_B), - GPIO_FN(RX5), GPIO_FN(RTS0_D_TANS_D), GPIO_FN(VI2_R4), GPIO_FN(VI2_R5), GPIO_FN(VI2_R6), GPIO_FN(VI2_R7), GPIO_FN(SCL2_D), GPIO_FN(SDA2_D), @@ -2794,15 +2792,15 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SDA1_D), GPIO_FN(VI2_HSYNC), GPIO_FN(VI3_HSYNC), GPIO_FN(VI2_VSYNC), GPIO_FN(VI3_VSYNC), - GPIO_FN(VI2_CLK), GPIO_FN(TX3_B_IRDA_TX_B), + GPIO_FN(VI2_CLK), GPIO_FN(HSPI_TX1), GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB), - GPIO_FN(AUDIO_CLKC), GPIO_FN(TX2_D), GPIO_FN(SPEEDIN), + GPIO_FN(AUDIO_CLKC), GPIO_FN(SPEEDIN), GPIO_FN(GPS_SIGN_D), GPIO_FN(VI2_DATA6_VI2_B6), GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(HSPI_CLK1), - GPIO_FN(SCK2_D), GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D), - GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(RX3_B_IRDA_RX_B), + GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D), + GPIO_FN(VI2_DATA7_VI2_B7), GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD), - GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(RX2_D), + GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA), GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(USB_OVC2), GPIO_FN(CAN_DEBUGOUT0), GPIO_FN(MOUT0), @@ -2820,10 +2818,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CAN_CLK_B), GPIO_FN(IECLK), GPIO_FN(SCIF_CLK_B), GPIO_FN(TCLK0_B), GPIO_FN(SSI_SDATA4), GPIO_FN(CAN_DEBUGOUT9), GPIO_FN(SSI_SDATA9_C), GPIO_FN(SSI_SCK5), GPIO_FN(ADICLK), - GPIO_FN(CAN_DEBUGOUT10), GPIO_FN(SCK3), GPIO_FN(TCLK0_D), + GPIO_FN(CAN_DEBUGOUT10), GPIO_FN(TCLK0_D), GPIO_FN(SSI_WS5), GPIO_FN(ADICS_SAMP), GPIO_FN(CAN_DEBUGOUT11), - GPIO_FN(TX3_IRDA_TX), GPIO_FN(SSI_SDATA5), GPIO_FN(ADIDATA), - GPIO_FN(CAN_DEBUGOUT12), GPIO_FN(RX3_IRDA_RX), GPIO_FN(SSI_SCK6), + GPIO_FN(SSI_SDATA5), GPIO_FN(ADIDATA), + GPIO_FN(CAN_DEBUGOUT12), GPIO_FN(SSI_SCK6), GPIO_FN(ADICHS0), GPIO_FN(CAN0_TX), GPIO_FN(IERX_B), /* IPSR7 */ @@ -2836,36 +2834,35 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(IRQ2_B), GPIO_FN(TCLK1_C), GPIO_FN(HSPI_TX1_C), GPIO_FN(SSI_SDATA8), GPIO_FN(VSP), GPIO_FN(IRQ3_B), GPIO_FN(HSPI_RX1_C), - GPIO_FN(ATACS01), GPIO_FN(SCK1_B), GPIO_FN(ATACS11), - GPIO_FN(TX1_B), GPIO_FN(CC5_TDO), GPIO_FN(ATADIR1), - GPIO_FN(RX1_B), GPIO_FN(CC5_TRST), GPIO_FN(ATAG1), - GPIO_FN(SCK2_B), GPIO_FN(CC5_TMS), GPIO_FN(ATARD1), - GPIO_FN(TX2_B), GPIO_FN(CC5_TCK), GPIO_FN(ATAWR1), - GPIO_FN(RX2_B), GPIO_FN(CC5_TDI), GPIO_FN(DREQ2), - GPIO_FN(RTS1_B_TANS_B), GPIO_FN(DACK2), - GPIO_FN(CTS1_B), + GPIO_FN(ATACS01), GPIO_FN(ATACS11), + GPIO_FN(CC5_TDO), GPIO_FN(ATADIR1), + GPIO_FN(CC5_TRST), GPIO_FN(ATAG1), + GPIO_FN(CC5_TMS), GPIO_FN(ATARD1), + GPIO_FN(CC5_TCK), GPIO_FN(ATAWR1), + GPIO_FN(CC5_TDI), GPIO_FN(DREQ2), + GPIO_FN(DACK2), /* IPSR8 */ - GPIO_FN(HSPI_CLK0), GPIO_FN(CTS0), GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK), + GPIO_FN(HSPI_CLK0), GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK), GPIO_FN(CC5_STATE4), GPIO_FN(CC5_STATE12), GPIO_FN(CC5_STATE20), GPIO_FN(CC5_STATE28), GPIO_FN(CC5_STATE36), GPIO_FN(HSPI_CS0), - GPIO_FN(RTS0_TANS), GPIO_FN(USB_OVC1), GPIO_FN(AD_DI), + GPIO_FN(USB_OVC1), GPIO_FN(AD_DI), GPIO_FN(CC5_STATE5), GPIO_FN(CC5_STATE13), GPIO_FN(CC5_STATE21), GPIO_FN(CC5_STATE29), GPIO_FN(CC5_STATE37), GPIO_FN(HSPI_TX0), - GPIO_FN(TX0), GPIO_FN(CAN_DEBUG_HW_TRIGGER), GPIO_FN(AD_DO), + GPIO_FN(CAN_DEBUG_HW_TRIGGER), GPIO_FN(AD_DO), GPIO_FN(CC5_STATE6), GPIO_FN(CC5_STATE14), GPIO_FN(CC5_STATE22), GPIO_FN(CC5_STATE30), GPIO_FN(CC5_STATE38), GPIO_FN(HSPI_RX0), - GPIO_FN(RX0), GPIO_FN(CAN_STEP0), GPIO_FN(AD_NCS), GPIO_FN(CC5_STATE7), + GPIO_FN(CAN_STEP0), GPIO_FN(AD_NCS), GPIO_FN(CC5_STATE7), GPIO_FN(CC5_STATE15), GPIO_FN(CC5_STATE23), GPIO_FN(CC5_STATE31), GPIO_FN(CC5_STATE39), GPIO_FN(FMCLK), GPIO_FN(RDS_CLK), GPIO_FN(PCMOE), GPIO_FN(BPFCLK), GPIO_FN(PCMWE), GPIO_FN(FMIN), GPIO_FN(RDS_DATA), GPIO_FN(VI0_CLK), GPIO_FN(VI0_CLKENB), - GPIO_FN(TX1_C), GPIO_FN(HTX1_B), GPIO_FN(MT1_SYNC), - GPIO_FN(VI0_FIELD), GPIO_FN(RX1_C), GPIO_FN(HRX1_B), - GPIO_FN(VI0_HSYNC), GPIO_FN(VI0_DATA0_B_VI0_B0_B), GPIO_FN(CTS1_C), - GPIO_FN(TX4_D), GPIO_FN(HSCK1_B), + GPIO_FN(HTX1_B), GPIO_FN(MT1_SYNC), + GPIO_FN(VI0_FIELD), GPIO_FN(HRX1_B), + GPIO_FN(VI0_HSYNC), GPIO_FN(VI0_DATA0_B_VI0_B0_B), + GPIO_FN(HSCK1_B), GPIO_FN(VI0_VSYNC), GPIO_FN(VI0_DATA1_B_VI0_B1_B), - GPIO_FN(RTS1_C_TANS_C), GPIO_FN(RX4_D), GPIO_FN(PWMFSW0_C), + GPIO_FN(PWMFSW0_C), /* IPSR9 */ GPIO_FN(VI0_DATA0_VI0_B0), GPIO_FN(HRTS1_B), GPIO_FN(MT1_VCXO), @@ -2888,7 +2885,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(ETH_RXD1), GPIO_FN(ARM_TRACEDATA_9), /* IPSR10 */ - GPIO_FN(VI0_R0), GPIO_FN(SSI_SDATA7_C), GPIO_FN(SCK1_C), + GPIO_FN(VI0_R0), GPIO_FN(SSI_SDATA7_C), GPIO_FN(DREQ1_B), GPIO_FN(ARM_TRACEDATA_10), GPIO_FN(DREQ0_C), GPIO_FN(VI0_R1), GPIO_FN(SSI_SDATA8_C), GPIO_FN(DACK1_B), GPIO_FN(ARM_TRACEDATA_11), GPIO_FN(DACK0_C), GPIO_FN(DRACK0_C), @@ -2926,22 +2923,22 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(HSPI_RX1_D), GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), - GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(TX2), GPIO_FN(SPA_TDO), + GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(SPA_TDO), GPIO_FN(HCTS0_B), GPIO_FN(VI1_G1), GPIO_FN(VI3_DATA1), - GPIO_FN(SSI_SCK1), GPIO_FN(TS_SDEN1), GPIO_FN(DACK2_B), GPIO_FN(RX2), + GPIO_FN(SSI_SCK1), GPIO_FN(TS_SDEN1), GPIO_FN(DACK2_B), GPIO_FN(HRTS0_B), /* IPSR12 */ GPIO_FN(VI1_G2), GPIO_FN(VI3_DATA2), GPIO_FN(SSI_WS1), - GPIO_FN(TS_SPSYNC1), GPIO_FN(SCK2), GPIO_FN(HSCK0_B), GPIO_FN(VI1_G3), + GPIO_FN(TS_SPSYNC1), GPIO_FN(HSCK0_B), GPIO_FN(VI1_G3), GPIO_FN(VI3_DATA3), GPIO_FN(SSI_SCK2), GPIO_FN(TS_SDAT1), GPIO_FN(SCL1_C), GPIO_FN(HTX0_B), GPIO_FN(VI1_G4), GPIO_FN(VI3_DATA4), GPIO_FN(SSI_WS2), GPIO_FN(SDA1_C), GPIO_FN(SIM_RST_B), GPIO_FN(HRX0_B), GPIO_FN(VI1_G5), GPIO_FN(VI3_DATA5), - GPIO_FN(GPS_CLK), GPIO_FN(FSE), GPIO_FN(TX4_B), GPIO_FN(SIM_D_B), + GPIO_FN(GPS_CLK), GPIO_FN(FSE), GPIO_FN(SIM_D_B), GPIO_FN(VI1_G6), GPIO_FN(VI3_DATA6), GPIO_FN(GPS_SIGN), GPIO_FN(FRB), - GPIO_FN(RX4_B), GPIO_FN(SIM_CLK_B), GPIO_FN(VI1_G7), - GPIO_FN(VI3_DATA7), GPIO_FN(GPS_MAG), GPIO_FN(FCE), GPIO_FN(SCK4_B), + GPIO_FN(SIM_CLK_B), GPIO_FN(VI1_G7), + GPIO_FN(VI3_DATA7), GPIO_FN(GPS_MAG), GPIO_FN(FCE), }; static const struct pinmux_cfg_reg pinmux_config_regs[] = { -- cgit From 52c5d0327e101ff57d7a6be8a983a610588d7332 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 6 Mar 2013 14:36:28 +0100 Subject: sh-pfc: r8a7779: Remove HSPI function GPIOS All r8a7779 platforms now use the pinctrl API to control the HSPI pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index ecc300db2370..ca59a187b021 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2682,16 +2682,16 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF), GPIO_FN(HCTS1), GPIO_FN(A0), GPIO_FN(FD3), GPIO_FN(A20), - GPIO_FN(HSPI_TX2_B), GPIO_FN(A21), - GPIO_FN(HSPI_CLK2_B), GPIO_FN(A22), - GPIO_FN(HSPI_RX2_B), GPIO_FN(VI1_R0), GPIO_FN(A23), GPIO_FN(FCLE), - GPIO_FN(HSPI_CLK2), GPIO_FN(VI1_R1), GPIO_FN(A24), - GPIO_FN(FD4), GPIO_FN(HSPI_CS2), GPIO_FN(VI1_R2), + GPIO_FN(A21), + GPIO_FN(A22), + GPIO_FN(VI1_R0), GPIO_FN(A23), GPIO_FN(FCLE), + GPIO_FN(VI1_R1), GPIO_FN(A24), + GPIO_FN(FD4), GPIO_FN(VI1_R2), GPIO_FN(SSI_WS78_B), GPIO_FN(A25), - GPIO_FN(FD5), GPIO_FN(HSPI_RX2), GPIO_FN(VI1_R3), + GPIO_FN(FD5), GPIO_FN(VI1_R3), GPIO_FN(SSI_SDATA7_B), GPIO_FN(CLKOUT), GPIO_FN(PWM0_B), GPIO_FN(CS0), - GPIO_FN(HSPI_CS2_B), GPIO_FN(CS1_A26), GPIO_FN(HSPI_TX2), + GPIO_FN(CS1_A26), GPIO_FN(SDSELF_B), GPIO_FN(RD_WR), GPIO_FN(FWE), GPIO_FN(ATAG0), GPIO_FN(VI1_R7), GPIO_FN(HRTS1), @@ -2787,19 +2787,19 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI2_R4), GPIO_FN(VI2_R5), GPIO_FN(VI2_R6), GPIO_FN(VI2_R7), GPIO_FN(SCL2_D), GPIO_FN(SDA2_D), - GPIO_FN(VI2_CLKENB), GPIO_FN(HSPI_CS1), + GPIO_FN(VI2_CLKENB), GPIO_FN(SCL1_D), GPIO_FN(VI2_FIELD), GPIO_FN(SDA1_D), GPIO_FN(VI2_HSYNC), GPIO_FN(VI3_HSYNC), GPIO_FN(VI2_VSYNC), GPIO_FN(VI3_VSYNC), GPIO_FN(VI2_CLK), - GPIO_FN(HSPI_TX1), GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB), + GPIO_FN(VI1_CLKENB), GPIO_FN(VI3_CLKENB), GPIO_FN(AUDIO_CLKC), GPIO_FN(SPEEDIN), GPIO_FN(GPS_SIGN_D), GPIO_FN(VI2_DATA6_VI2_B6), - GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(HSPI_CLK1), + GPIO_FN(TCLK0), GPIO_FN(QSTVA_B_QVS_B), GPIO_FN(AUDIO_CLKOUT_B), GPIO_FN(GPS_MAG_D), GPIO_FN(VI2_DATA7_VI2_B7), - GPIO_FN(HSPI_RX1), GPIO_FN(VI1_FIELD), + GPIO_FN(VI1_FIELD), GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA), GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(USB_OVC2), @@ -2828,12 +2828,12 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SSI_WS6), GPIO_FN(ADICHS1), GPIO_FN(CAN0_RX), GPIO_FN(IETX_B), GPIO_FN(SSI_SDATA6), GPIO_FN(ADICHS2), GPIO_FN(CAN_CLK), GPIO_FN(IECLK_B), GPIO_FN(SSI_SCK78), GPIO_FN(CAN_DEBUGOUT13), - GPIO_FN(IRQ0_B), GPIO_FN(SSI_SCK9_B), GPIO_FN(HSPI_CLK1_C), + GPIO_FN(IRQ0_B), GPIO_FN(SSI_SCK9_B), GPIO_FN(SSI_WS78), GPIO_FN(CAN_DEBUGOUT14), GPIO_FN(IRQ1_B), - GPIO_FN(SSI_WS9_B), GPIO_FN(HSPI_CS1_C), GPIO_FN(SSI_SDATA7), + GPIO_FN(SSI_WS9_B), GPIO_FN(SSI_SDATA7), GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(IRQ2_B), GPIO_FN(TCLK1_C), - GPIO_FN(HSPI_TX1_C), GPIO_FN(SSI_SDATA8), GPIO_FN(VSP), - GPIO_FN(IRQ3_B), GPIO_FN(HSPI_RX1_C), + GPIO_FN(SSI_SDATA8), GPIO_FN(VSP), + GPIO_FN(IRQ3_B), GPIO_FN(ATACS01), GPIO_FN(ATACS11), GPIO_FN(CC5_TDO), GPIO_FN(ATADIR1), GPIO_FN(CC5_TRST), GPIO_FN(ATAG1), @@ -2843,15 +2843,15 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(DACK2), /* IPSR8 */ - GPIO_FN(HSPI_CLK0), GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK), + GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK), GPIO_FN(CC5_STATE4), GPIO_FN(CC5_STATE12), GPIO_FN(CC5_STATE20), - GPIO_FN(CC5_STATE28), GPIO_FN(CC5_STATE36), GPIO_FN(HSPI_CS0), + GPIO_FN(CC5_STATE28), GPIO_FN(CC5_STATE36), GPIO_FN(USB_OVC1), GPIO_FN(AD_DI), GPIO_FN(CC5_STATE5), GPIO_FN(CC5_STATE13), GPIO_FN(CC5_STATE21), - GPIO_FN(CC5_STATE29), GPIO_FN(CC5_STATE37), GPIO_FN(HSPI_TX0), + GPIO_FN(CC5_STATE29), GPIO_FN(CC5_STATE37), GPIO_FN(CAN_DEBUG_HW_TRIGGER), GPIO_FN(AD_DO), GPIO_FN(CC5_STATE6), GPIO_FN(CC5_STATE14), GPIO_FN(CC5_STATE22), - GPIO_FN(CC5_STATE30), GPIO_FN(CC5_STATE38), GPIO_FN(HSPI_RX0), + GPIO_FN(CC5_STATE30), GPIO_FN(CC5_STATE38), GPIO_FN(CAN_STEP0), GPIO_FN(AD_NCS), GPIO_FN(CC5_STATE7), GPIO_FN(CC5_STATE15), GPIO_FN(CC5_STATE23), GPIO_FN(CC5_STATE31), GPIO_FN(CC5_STATE39), GPIO_FN(FMCLK), GPIO_FN(RDS_CLK), GPIO_FN(PCMOE), @@ -2893,13 +2893,13 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(ARM_TRACEDATA_12), GPIO_FN(VI0_R3), GPIO_FN(ETH_MAGIC), GPIO_FN(IRQ3), GPIO_FN(ARM_TRACEDATA_13), GPIO_FN(VI0_R4), GPIO_FN(ETH_REFCLK), - GPIO_FN(HSPI_CLK1_B), GPIO_FN(ARM_TRACEDATA_14), GPIO_FN(MT1_CLK), + GPIO_FN(ARM_TRACEDATA_14), GPIO_FN(MT1_CLK), GPIO_FN(TS_SCK0), GPIO_FN(VI0_R5), GPIO_FN(ETH_TXD0), - GPIO_FN(HSPI_CS1_B), GPIO_FN(ARM_TRACEDATA_15), + GPIO_FN(ARM_TRACEDATA_15), GPIO_FN(MT1_D), GPIO_FN(TS_SDEN0), GPIO_FN(VI0_R6), GPIO_FN(ETH_MDC), - GPIO_FN(DREQ2_C), GPIO_FN(HSPI_TX1_B), GPIO_FN(TRACECLK), + GPIO_FN(DREQ2_C), GPIO_FN(TRACECLK), GPIO_FN(MT1_BEN), GPIO_FN(PWMFSW0_D), GPIO_FN(VI0_R7), - GPIO_FN(ETH_MDIO), GPIO_FN(DACK2_C), GPIO_FN(HSPI_RX1_B), + GPIO_FN(ETH_MDIO), GPIO_FN(DACK2_C), GPIO_FN(SCIF_CLK_D), GPIO_FN(TRACECTL), GPIO_FN(MT1_PEN), GPIO_FN(VI1_CLK), GPIO_FN(SIM_D), GPIO_FN(SDA3), GPIO_FN(VI1_HSYNC), GPIO_FN(VI3_CLK), GPIO_FN(SSI_SCK4), GPIO_FN(GPS_SIGN_C), @@ -2916,12 +2916,12 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI1_DATA3_VI1_B3), GPIO_FN(MT0_BEN), GPIO_FN(SPV_TDO), GPIO_FN(ADICHS0_B), GPIO_FN(VI1_DATA4_VI1_B4), GPIO_FN(MT0_PEN), GPIO_FN(SPA_TRST), - GPIO_FN(HSPI_CLK1_D), GPIO_FN(ADICHS1_B), GPIO_FN(VI1_DATA5_VI1_B5), + GPIO_FN(ADICHS1_B), GPIO_FN(VI1_DATA5_VI1_B5), GPIO_FN(MT0_SYNC), GPIO_FN(SPA_TCK), - GPIO_FN(HSPI_CS1_D), GPIO_FN(ADICHS2_B), GPIO_FN(VI1_DATA6_VI1_B6), + GPIO_FN(ADICHS2_B), GPIO_FN(VI1_DATA6_VI1_B6), GPIO_FN(MT0_VCXO), GPIO_FN(SPA_TMS), - GPIO_FN(HSPI_TX1_D), GPIO_FN(VI1_DATA7_VI1_B7), - GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(HSPI_RX1_D), + GPIO_FN(VI1_DATA7_VI1_B7), + GPIO_FN(MT0_PWM), GPIO_FN(SPA_TDI), GPIO_FN(VI1_G0), GPIO_FN(VI3_DATA0), GPIO_FN(TS_SCK1), GPIO_FN(DREQ2_B), GPIO_FN(SPA_TDO), GPIO_FN(HCTS0_B), GPIO_FN(VI1_G1), GPIO_FN(VI3_DATA1), -- cgit From e1114715f4dc2c6f75a9d6e25ebc519faa4437fb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:58:48 +0100 Subject: sh-pfc: r8a7779: Remove USB function GPIOS All r8a7779 platforms now use the pinctrl API to control the USB pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index ca59a187b021..6f8cc53c07d5 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2677,7 +2677,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(A19), /* IPSR0 */ - GPIO_FN(USB_PENC2), GPIO_FN(PWM1), GPIO_FN(PWMFSW0), + GPIO_FN(PWM1), GPIO_FN(PWMFSW0), GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF), GPIO_FN(HCTS1), GPIO_FN(A0), @@ -2802,7 +2802,7 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI1_FIELD), GPIO_FN(VI3_FIELD), GPIO_FN(AUDIO_CLKOUT), GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), GPIO_FN(AUDIO_CLKA), - GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(USB_OVC2), + GPIO_FN(CAN_TXCLK), GPIO_FN(AUDIO_CLKB), GPIO_FN(CAN_DEBUGOUT0), GPIO_FN(MOUT0), /* IPSR6 */ @@ -2843,10 +2843,10 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(DACK2), /* IPSR8 */ - GPIO_FN(USB_OVC0), GPIO_FN(AD_CLK), + GPIO_FN(AD_CLK), GPIO_FN(CC5_STATE4), GPIO_FN(CC5_STATE12), GPIO_FN(CC5_STATE20), GPIO_FN(CC5_STATE28), GPIO_FN(CC5_STATE36), - GPIO_FN(USB_OVC1), GPIO_FN(AD_DI), + GPIO_FN(AD_DI), GPIO_FN(CC5_STATE5), GPIO_FN(CC5_STATE13), GPIO_FN(CC5_STATE21), GPIO_FN(CC5_STATE29), GPIO_FN(CC5_STATE37), GPIO_FN(CAN_DEBUG_HW_TRIGGER), GPIO_FN(AD_DO), -- cgit From cb1f8abc79e16edf776627ae7f1c0e76762cc7fd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:58:48 +0100 Subject: sh-pfc: r8a7779: Remove LBSC function GPIOS All r8a7779 platforms now use the pinctrl API to control the LBSC pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 6f8cc53c07d5..5d6549953b4b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2690,22 +2690,20 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SSI_WS78_B), GPIO_FN(A25), GPIO_FN(FD5), GPIO_FN(VI1_R3), GPIO_FN(SSI_SDATA7_B), GPIO_FN(CLKOUT), - GPIO_FN(PWM0_B), GPIO_FN(CS0), - GPIO_FN(CS1_A26), + GPIO_FN(PWM0_B), GPIO_FN(SDSELF_B), GPIO_FN(RD_WR), GPIO_FN(FWE), GPIO_FN(ATAG0), GPIO_FN(VI1_R7), GPIO_FN(HRTS1), /* IPSR1 */ - GPIO_FN(EX_CS0), - GPIO_FN(FD6), GPIO_FN(EX_CS1), GPIO_FN(FD7), - GPIO_FN(EX_CS2), GPIO_FN(FALE), - GPIO_FN(ATACS00), GPIO_FN(EX_CS3), + GPIO_FN(FD6), GPIO_FN(FD7), + GPIO_FN(FALE), + GPIO_FN(ATACS00), GPIO_FN(FRE), GPIO_FN(ATACS10), GPIO_FN(VI1_R4), GPIO_FN(HSCK1), GPIO_FN(SSI_SDATA8_B), - GPIO_FN(SSI_SDATA9), GPIO_FN(EX_CS4), + GPIO_FN(SSI_SDATA9), GPIO_FN(FD0), GPIO_FN(ATARD0), GPIO_FN(VI1_R5), GPIO_FN(HTX1), - GPIO_FN(SSI_SCK9), GPIO_FN(EX_CS5), + GPIO_FN(SSI_SCK9), GPIO_FN(FD1), GPIO_FN(ATAWR0), GPIO_FN(VI1_R6), GPIO_FN(HRX1), GPIO_FN(SSI_WS9), GPIO_FN(MLB_CLK), GPIO_FN(PWM2), GPIO_FN(MLB_SIG), -- cgit From fdd7fc55f54ef0c811bdc2f9d81b25f6cf3085c7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 7 Mar 2013 13:58:48 +0100 Subject: sh-pfc: r8a7779: Remove INTC function GPIOS All r8a7779 platforms now use the pinctrl API to control the INTC pins, the corresponding function GPIOS are unused. Remove them. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7779.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c index 5d6549953b4b..1d7b0dfbbb21 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7779.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7779.c @@ -2826,12 +2826,11 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(SSI_WS6), GPIO_FN(ADICHS1), GPIO_FN(CAN0_RX), GPIO_FN(IETX_B), GPIO_FN(SSI_SDATA6), GPIO_FN(ADICHS2), GPIO_FN(CAN_CLK), GPIO_FN(IECLK_B), GPIO_FN(SSI_SCK78), GPIO_FN(CAN_DEBUGOUT13), - GPIO_FN(IRQ0_B), GPIO_FN(SSI_SCK9_B), - GPIO_FN(SSI_WS78), GPIO_FN(CAN_DEBUGOUT14), GPIO_FN(IRQ1_B), + GPIO_FN(SSI_SCK9_B), + GPIO_FN(SSI_WS78), GPIO_FN(CAN_DEBUGOUT14), GPIO_FN(SSI_WS9_B), GPIO_FN(SSI_SDATA7), - GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(IRQ2_B), GPIO_FN(TCLK1_C), + GPIO_FN(CAN_DEBUGOUT15), GPIO_FN(TCLK1_C), GPIO_FN(SSI_SDATA8), GPIO_FN(VSP), - GPIO_FN(IRQ3_B), GPIO_FN(ATACS01), GPIO_FN(ATACS11), GPIO_FN(CC5_TDO), GPIO_FN(ATADIR1), GPIO_FN(CC5_TRST), GPIO_FN(ATAG1), @@ -2870,8 +2869,8 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VI0_DATA5_VI0_B5), GPIO_FN(VI0_DATA6_VI0_B6), GPIO_FN(ARM_TRACEDATA_0), GPIO_FN(VI0_DATA7_VI0_B7), GPIO_FN(ARM_TRACEDATA_1), GPIO_FN(VI0_G0), - GPIO_FN(SSI_SCK78_C), GPIO_FN(IRQ0), GPIO_FN(ARM_TRACEDATA_2), - GPIO_FN(VI0_G1), GPIO_FN(SSI_WS78_C), GPIO_FN(IRQ1), + GPIO_FN(SSI_SCK78_C), GPIO_FN(ARM_TRACEDATA_2), + GPIO_FN(VI0_G1), GPIO_FN(SSI_WS78_C), GPIO_FN(ARM_TRACEDATA_3), GPIO_FN(VI0_G2), GPIO_FN(ETH_TXD1), GPIO_FN(ARM_TRACEDATA_4), GPIO_FN(TS_SPSYNC0), GPIO_FN(VI0_G3), GPIO_FN(ETH_CRS_DV), @@ -2887,9 +2886,9 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(DREQ1_B), GPIO_FN(ARM_TRACEDATA_10), GPIO_FN(DREQ0_C), GPIO_FN(VI0_R1), GPIO_FN(SSI_SDATA8_C), GPIO_FN(DACK1_B), GPIO_FN(ARM_TRACEDATA_11), GPIO_FN(DACK0_C), GPIO_FN(DRACK0_C), - GPIO_FN(VI0_R2), GPIO_FN(ETH_LINK), GPIO_FN(IRQ2), + GPIO_FN(VI0_R2), GPIO_FN(ETH_LINK), GPIO_FN(ARM_TRACEDATA_12), GPIO_FN(VI0_R3), GPIO_FN(ETH_MAGIC), - GPIO_FN(IRQ3), GPIO_FN(ARM_TRACEDATA_13), + GPIO_FN(ARM_TRACEDATA_13), GPIO_FN(VI0_R4), GPIO_FN(ETH_REFCLK), GPIO_FN(ARM_TRACEDATA_14), GPIO_FN(MT1_CLK), GPIO_FN(TS_SCK0), GPIO_FN(VI0_R5), GPIO_FN(ETH_TXD0), -- cgit From 8cef7a7892e7820a825aab28a1bff42ca216e9f0 Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Thu, 14 Mar 2013 02:41:51 +0000 Subject: be2net: enable interrupts in be_probe() (RoCE and other ULPs need them) As the NIC PCI function may be used by other protocols, the chip interrupts must be enabled in be_probe() itself rather than be_open(). Signed-off-by: Sathya Perla Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index b8e5019398f0..dae7172c2404 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -157,6 +157,10 @@ static void be_intr_set(struct be_adapter *adapter, bool enable) { u32 reg, enabled; + /* On lancer interrupts can't be controlled via this register */ + if (lancer_chip(adapter)) + return; + if (adapter->eeh_error) return; @@ -2435,9 +2439,6 @@ static int be_close(struct net_device *netdev) be_roce_dev_close(adapter); - if (!lancer_chip(adapter)) - be_intr_set(adapter, false); - for_all_evt_queues(adapter, eqo, i) napi_disable(&eqo->napi); @@ -2525,9 +2526,6 @@ static int be_open(struct net_device *netdev) be_irq_register(adapter); - if (!lancer_chip(adapter)) - be_intr_set(adapter, true); - for_all_rx_queues(adapter, rxo, i) be_cq_notify(adapter, rxo->cq.id, true, 0); @@ -3853,6 +3851,7 @@ static void be_remove(struct pci_dev *pdev) return; be_roce_dev_remove(adapter); + be_intr_set(adapter, false); cancel_delayed_work_sync(&adapter->func_recovery_work); @@ -4142,11 +4141,11 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) goto ctrl_clean; } - /* The INTR bit may be set in the card when probed by a kdump kernel - * after a crash. - */ - if (!lancer_chip(adapter)) - be_intr_set(adapter, false); + /* Wait for interrupts to quiesce after an FLR */ + msleep(100); + + /* Allow interrupts for other ULPs running on NIC function */ + be_intr_set(adapter, true); status = be_stats_init(adapter); if (status) -- cgit From 68c45a2da34cb44962c6a48f8e474ec6b7853641 Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Thu, 14 Mar 2013 02:42:07 +0000 Subject: be2net: Use new F/W mailbox cmd to manipulate interrupts. This is needed as the earlier method of manipulating this register via PCI Config space is disallowed by certain Hypervisors. Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 25 +++++++++++++++++++++++++ drivers/net/ethernet/emulex/benet/be_cmds.h | 8 ++++++++ drivers/net/ethernet/emulex/benet/be_main.c | 25 +++++++++++++++++-------- 3 files changed, 50 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 6ed46396bb36..99163646113f 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3202,6 +3202,31 @@ err: return status; } +int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_intr_set *req; + int status; + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + + req = embedded_payload(wrb); + + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req), + wrb, NULL); + + req->intr_enabled = intr_enable; + + status = be_mbox_notify_wait(adapter); + + mutex_unlock(&adapter->mbox_lock); + return status; +} + int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, int wrb_payload_size, u16 *cmd_status, u16 *ext_status) { diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 6ef4575ce1c8..f2af85517218 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -188,6 +188,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_GET_BEACON_STATE 70 #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PORT_NAME 77 +#define OPCODE_COMMON_SET_INTERRUPT_ENABLE 89 #define OPCODE_COMMON_GET_PHY_DETAILS 102 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 @@ -1791,6 +1792,12 @@ struct be_cmd_enable_disable_vf { u8 rsvd[3]; }; +struct be_cmd_req_intr_set { + struct be_cmd_req_hdr hdr; + u8 intr_enabled; + u8 rsvd[3]; +}; + static inline bool check_privilege(struct be_adapter *adapter, u32 flags) { return flags & adapter->cmd_privileges ? true : false; @@ -1938,3 +1945,4 @@ extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, extern int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, int vf_num); extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); +extern int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index dae7172c2404..c71b180f4678 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -153,17 +153,10 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, return 0; } -static void be_intr_set(struct be_adapter *adapter, bool enable) +static void be_reg_intr_set(struct be_adapter *adapter, bool enable) { u32 reg, enabled; - /* On lancer interrupts can't be controlled via this register */ - if (lancer_chip(adapter)) - return; - - if (adapter->eeh_error) - return; - pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, ®); enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; @@ -179,6 +172,22 @@ static void be_intr_set(struct be_adapter *adapter, bool enable) PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, reg); } +static void be_intr_set(struct be_adapter *adapter, bool enable) +{ + int status = 0; + + /* On lancer interrupts can't be controlled via this register */ + if (lancer_chip(adapter)) + return; + + if (adapter->eeh_error) + return; + + status = be_cmd_intr_set(adapter, enable); + if (status) + be_reg_intr_set(adapter, enable); +} + static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted) { u32 val = 0; -- cgit From d0320f750093d012d3ed69fc1e8b385f654523d5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 14 Mar 2013 13:07:21 +0000 Subject: drivers:net: Remove dma_alloc_coherent OOM messages I believe these error messages are already logged on allocation failure by warn_alloc_failed and so get a dump_stack on OOM. Remove the unnecessary additional error logging. Around these deletions: o Alignment neatening. o Remove unnecessary casts of dma_alloc_coherent. o Hoist assigns from ifs. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/aeroflex/greth.c | 20 ++++------- drivers/net/ethernet/amd/sunlance.c | 5 ++- drivers/net/ethernet/apple/macmace.c | 16 ++++----- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 -- drivers/net/ethernet/cadence/at91_ether.c | 19 +++++----- drivers/net/ethernet/dec/tulip/xircom_cb.c | 9 ++--- drivers/net/ethernet/emulex/benet/be_cmds.c | 4 +-- drivers/net/ethernet/emulex/benet/be_ethtool.c | 9 ++--- drivers/net/ethernet/emulex/benet/be_main.c | 6 +--- drivers/net/ethernet/freescale/fec.c | 6 ++-- drivers/net/ethernet/freescale/gianfar.c | 13 ++++--- drivers/net/ethernet/ibm/emac/mal.c | 8 ++--- drivers/net/ethernet/ibm/ibmveth.c | 6 ++-- drivers/net/ethernet/intel/e1000/e1000_main.c | 7 ---- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 4 --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 -- drivers/net/ethernet/marvell/mvneta.c | 14 ++------ drivers/net/ethernet/marvell/pxa168_eth.c | 11 ++---- drivers/net/ethernet/mellanox/mlx4/cmd.c | 4 +-- drivers/net/ethernet/natsemi/jazzsonic.c | 12 +++---- drivers/net/ethernet/natsemi/macsonic.c | 12 +++---- drivers/net/ethernet/natsemi/xtsonic.c | 12 +++---- drivers/net/ethernet/nuvoton/w90p910_ether.c | 19 ++++------ drivers/net/ethernet/nxp/lpc_eth.c | 2 -- .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 12 +++---- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 40 ++++++++-------------- .../net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | 5 +-- drivers/net/ethernet/renesas/sh_eth.c | 9 ++--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 24 +++++-------- drivers/net/ethernet/sun/sunbmac.c | 4 +-- drivers/net/ethernet/sun/sunhme.c | 13 +++---- drivers/net/ethernet/tundra/tsi108_eth.c | 10 ++---- drivers/net/ethernet/xilinx/ll_temac_main.c | 11 ++---- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++---- drivers/net/fddi/defxx.c | 6 ++-- drivers/net/irda/bfin_sir.c | 3 +- drivers/net/irda/smsc-ircc2.c | 10 ++---- drivers/net/wireless/ath/wil6210/txrx.c | 2 -- drivers/net/wireless/b43legacy/dma.c | 5 +-- drivers/net/wireless/iwlegacy/3945.c | 4 +-- drivers/net/wireless/iwlegacy/common.c | 5 ++- drivers/net/wireless/iwlwifi/pcie/tx.c | 4 +-- 42 files changed, 122 insertions(+), 278 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 0be2195e5034..3a9fbacc3729 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1464,14 +1464,10 @@ static int greth_of_probe(struct platform_device *ofdev) } /* Allocate TX descriptor ring in coherent memory */ - greth->tx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, - 1024, - &greth->tx_bd_base_phys, - GFP_KERNEL); - + greth->tx_bd_base = dma_alloc_coherent(greth->dev, 1024, + &greth->tx_bd_base_phys, + GFP_KERNEL); if (!greth->tx_bd_base) { - if (netif_msg_probe(greth)) - dev_err(&dev->dev, "could not allocate descriptor memory.\n"); err = -ENOMEM; goto error3; } @@ -1479,14 +1475,10 @@ static int greth_of_probe(struct platform_device *ofdev) memset(greth->tx_bd_base, 0, 1024); /* Allocate RX descriptor ring in coherent memory */ - greth->rx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, - 1024, - &greth->rx_bd_base_phys, - GFP_KERNEL); - + greth->rx_bd_base = dma_alloc_coherent(greth->dev, 1024, + &greth->rx_bd_base_phys, + GFP_KERNEL); if (!greth->rx_bd_base) { - if (netif_msg_probe(greth)) - dev_err(greth->dev, "could not allocate descriptor memory.\n"); err = -ENOMEM; goto error4; } diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 70d543063993..f47b780892e9 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -1373,10 +1373,9 @@ static int sparc_lance_probe_one(struct platform_device *op, dma_alloc_coherent(&op->dev, sizeof(struct lance_init_block), &lp->init_block_dvma, GFP_ATOMIC); - if (!lp->init_block_mem) { - printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n"); + if (!lp->init_block_mem) goto fail; - } + lp->pio_buffer = 0; lp->init_ring = lance_init_ring_dvma; lp->rx = lance_rx_dvma; diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index a206779c68cf..4ce8ceb62205 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -386,20 +386,16 @@ static int mace_open(struct net_device *dev) /* Allocate the DMA ring buffers */ mp->tx_ring = dma_alloc_coherent(mp->device, - N_TX_RING * MACE_BUFF_SIZE, - &mp->tx_ring_phys, GFP_KERNEL); - if (mp->tx_ring == NULL) { - printk(KERN_ERR "%s: unable to allocate DMA tx buffers\n", dev->name); + N_TX_RING * MACE_BUFF_SIZE, + &mp->tx_ring_phys, GFP_KERNEL); + if (mp->tx_ring == NULL) goto out1; - } mp->rx_ring = dma_alloc_coherent(mp->device, - N_RX_RING * MACE_BUFF_SIZE, - &mp->rx_ring_phys, GFP_KERNEL); - if (mp->rx_ring == NULL) { - printk(KERN_ERR "%s: unable to allocate DMA rx buffers\n", dev->name); + N_RX_RING * MACE_BUFF_SIZE, + &mp->rx_ring_phys, GFP_KERNEL); + if (mp->rx_ring == NULL) goto out2; - } mace_dma_off(dev); diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index db343a1d0835..79cf620ab449 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -864,7 +864,6 @@ static int bcm_enet_open(struct net_device *dev) size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL); if (!p) { - dev_err(kdev, "cannot allocate rx ring %u\n", size); ret = -ENOMEM; goto out_freeirq_tx; } @@ -877,7 +876,6 @@ static int bcm_enet_open(struct net_device *dev) size = priv->tx_ring_size * sizeof(struct bcm_enet_desc); p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL); if (!p) { - dev_err(kdev, "cannot allocate tx ring\n"); ret = -ENOMEM; goto out_free_rx_ring; } diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 5bd7786e8413..c6e40d65a3df 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -47,22 +47,19 @@ static int at91ether_start(struct net_device *dev) int i; lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev, - MAX_RX_DESCR * sizeof(struct macb_dma_desc), - &lp->rx_ring_dma, GFP_KERNEL); - if (!lp->rx_ring) { - netdev_err(dev, "unable to alloc rx ring DMA buffer\n"); + (MAX_RX_DESCR * + sizeof(struct macb_dma_desc)), + &lp->rx_ring_dma, GFP_KERNEL); + if (!lp->rx_ring) return -ENOMEM; - } lp->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, - MAX_RX_DESCR * MAX_RBUFF_SZ, - &lp->rx_buffers_dma, GFP_KERNEL); + MAX_RX_DESCR * MAX_RBUFF_SZ, + &lp->rx_buffers_dma, GFP_KERNEL); if (!lp->rx_buffers) { - netdev_err(dev, "unable to alloc rx data DMA buffer\n"); - dma_free_coherent(&lp->pdev->dev, - MAX_RX_DESCR * sizeof(struct macb_dma_desc), - lp->rx_ring, lp->rx_ring_dma); + MAX_RX_DESCR * sizeof(struct macb_dma_desc), + lp->rx_ring, lp->rx_ring_dma); lp->rx_ring = NULL; return -ENOMEM; } diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c index 88feced9a629..cdbcd1643141 100644 --- a/drivers/net/ethernet/dec/tulip/xircom_cb.c +++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c @@ -236,17 +236,14 @@ static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id) private->rx_buffer = dma_alloc_coherent(d, 8192, &private->rx_dma_handle, GFP_KERNEL); - if (private->rx_buffer == NULL) { - pr_err("%s: no memory for rx buffer\n", __func__); + if (private->rx_buffer == NULL) goto rx_buf_fail; - } + private->tx_buffer = dma_alloc_coherent(d, 8192, &private->tx_dma_handle, GFP_KERNEL); - if (private->tx_buffer == NULL) { - pr_err("%s: no memory for tx buffer\n", __func__); + if (private->tx_buffer == NULL) goto tx_buf_fail; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 99163646113f..f286ad2da1ff 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -2667,10 +2667,8 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, cmd.size = sizeof(struct be_cmd_req_set_mac_list); cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, GFP_KERNEL); - if (!cmd.va) { - dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); + if (!cmd.va) return -ENOMEM; - } spin_lock_bh(&adapter->mcc_lock); diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 053f00d006c0..07b7f27cb0b9 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -719,10 +719,8 @@ be_test_ddr_dma(struct be_adapter *adapter) ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); ddrdma_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, ddrdma_cmd.size, &ddrdma_cmd.dma, GFP_KERNEL); - if (!ddrdma_cmd.va) { - dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); + if (!ddrdma_cmd.va) return -ENOMEM; - } for (i = 0; i < 2; i++) { ret = be_cmd_ddr_dma_test(adapter, pattern[i], @@ -845,11 +843,8 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, eeprom_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, eeprom_cmd.size, &eeprom_cmd.dma, GFP_KERNEL); - if (!eeprom_cmd.va) { - dev_err(&adapter->pdev->dev, - "Memory allocation failure. Could not read eeprom\n"); + if (!eeprom_cmd.va) return -ENOMEM; - } status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c71b180f4678..2dfa205c5b99 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3464,11 +3464,9 @@ static int lancer_fw_download(struct be_adapter *adapter, flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) + LANCER_FW_DOWNLOAD_CHUNK; flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, - &flash_cmd.dma, GFP_KERNEL); + &flash_cmd.dma, GFP_KERNEL); if (!flash_cmd.va) { status = -ENOMEM; - dev_err(&adapter->pdev->dev, - "Memory allocation failure while flashing\n"); goto lancer_fw_exit; } @@ -3570,8 +3568,6 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) &flash_cmd.dma, GFP_KERNEL); if (!flash_cmd.va) { status = -ENOMEM; - dev_err(&adapter->pdev->dev, - "Memory allocation failure while flashing\n"); goto be_fw_exit; } diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index e6224949891f..69a4adedad83 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1594,11 +1594,9 @@ static int fec_enet_init(struct net_device *ndev) /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, - GFP_KERNEL); - if (!cbd_base) { - printk("FEC: allocate descriptor memory failed?\n"); + GFP_KERNEL); + if (!cbd_base) return -ENOMEM; - } spin_lock_init(&fep->hw_lock); diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index d2c5441d1bf0..1b468a82a68f 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -245,14 +245,13 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) /* Allocate memory for the buffer descriptors */ vaddr = dma_alloc_coherent(dev, - sizeof(struct txbd8) * priv->total_tx_ring_size + - sizeof(struct rxbd8) * priv->total_rx_ring_size, - &addr, GFP_KERNEL); - if (!vaddr) { - netif_err(priv, ifup, ndev, - "Could not allocate buffer descriptors!\n"); + (priv->total_tx_ring_size * + sizeof(struct txbd8)) + + (priv->total_rx_ring_size * + sizeof(struct rxbd8)), + &addr, GFP_KERNEL); + if (!vaddr) return -ENOMEM; - } for (i = 0; i < priv->num_tx_queues; i++) { tx_queue = priv->tx_queue[i]; diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index 1f7ecf57181e..cc2db5c04d9c 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -637,13 +637,9 @@ static int mal_probe(struct platform_device *ofdev) bd_size = sizeof(struct mal_descriptor) * (NUM_TX_BUFF * mal->num_tx_chans + NUM_RX_BUFF * mal->num_rx_chans); - mal->bd_virt = - dma_alloc_coherent(&ofdev->dev, bd_size, &mal->bd_dma, - GFP_KERNEL); + mal->bd_virt = dma_alloc_coherent(&ofdev->dev, bd_size, &mal->bd_dma, + GFP_KERNEL); if (mal->bd_virt == NULL) { - printk(KERN_ERR - "mal%d: out of memory allocating RX/TX descriptors!\n", - index); err = -ENOMEM; goto fail_unmap; } diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index c859771a9902..302d59401065 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -556,11 +556,9 @@ static int ibmveth_open(struct net_device *netdev) adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries; adapter->rx_queue.queue_addr = - dma_alloc_coherent(dev, adapter->rx_queue.queue_len, - &adapter->rx_queue.queue_dma, GFP_KERNEL); - + dma_alloc_coherent(dev, adapter->rx_queue.queue_len, + &adapter->rx_queue.queue_dma, GFP_KERNEL); if (!adapter->rx_queue.queue_addr) { - netdev_err(netdev, "unable to allocate rx queue pages\n"); rc = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 8502c625dbef..d98e1d0996d4 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1516,8 +1516,6 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, if (!txdr->desc) { setup_tx_desc_die: vfree(txdr->buffer_info); - e_err(probe, "Unable to allocate memory for the Tx descriptor " - "ring\n"); return -ENOMEM; } @@ -1707,10 +1705,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, GFP_KERNEL); - if (!rxdr->desc) { - e_err(probe, "Unable to allocate memory for the Rx descriptor " - "ring\n"); setup_rx_desc_die: vfree(rxdr->buffer_info); return -ENOMEM; @@ -1729,8 +1724,6 @@ setup_rx_desc_die: if (!rxdr->desc) { dma_free_coherent(&pdev->dev, rxdr->size, olddesc, olddma); - e_err(probe, "Unable to allocate memory for the Rx " - "descriptor ring\n"); goto setup_rx_desc_die; } diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index ea4808373435..e23f0234cb27 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -720,8 +720,6 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) GFP_KERNEL); if (!txdr->desc) { vfree(txdr->buffer_info); - netif_err(adapter, probe, adapter->netdev, - "Unable to allocate transmit descriptor memory\n"); return -ENOMEM; } memset(txdr->desc, 0, txdr->size); @@ -807,8 +805,6 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) if (!rxdr->desc) { vfree(rxdr->buffer_info); - netif_err(adapter, probe, adapter->netdev, - "Unable to allocate receive descriptors\n"); return -ENOMEM; } memset(rxdr->desc, 0, rxdr->size); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2635b8303515..ac0c315659de 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2423,9 +2423,6 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter, &rx_ring->dma, GFP_KERNEL); if (!rx_ring->desc) { - hw_dbg(&adapter->hw, - "Unable to allocate memory for " - "the receive descriptor ring\n"); vfree(rx_ring->rx_buffer_info); rx_ring->rx_buffer_info = NULL; goto alloc_failed; diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index cd345b8969bc..e48261e468f3 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1969,13 +1969,8 @@ static int mvneta_rxq_init(struct mvneta_port *pp, rxq->descs = dma_alloc_coherent(pp->dev->dev.parent, rxq->size * MVNETA_DESC_ALIGNED_SIZE, &rxq->descs_phys, GFP_KERNEL); - if (rxq->descs == NULL) { - netdev_err(pp->dev, - "rxq=%d: Can't allocate %d bytes for %d RX descr\n", - rxq->id, rxq->size * MVNETA_DESC_ALIGNED_SIZE, - rxq->size); + if (rxq->descs == NULL) return -ENOMEM; - } BUG_ON(rxq->descs != PTR_ALIGN(rxq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE)); @@ -2029,13 +2024,8 @@ static int mvneta_txq_init(struct mvneta_port *pp, txq->descs = dma_alloc_coherent(pp->dev->dev.parent, txq->size * MVNETA_DESC_ALIGNED_SIZE, &txq->descs_phys, GFP_KERNEL); - if (txq->descs == NULL) { - netdev_err(pp->dev, - "txQ=%d: Can't allocate %d bytes for %d TX descr\n", - txq->id, txq->size * MVNETA_DESC_ALIGNED_SIZE, - txq->size); + if (txq->descs == NULL) return -ENOMEM; - } /* Make sure descriptor address is cache line size aligned */ BUG_ON(txq->descs != diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 037ed866c22f..3ae4c7f0834d 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1024,11 +1024,9 @@ static int rxq_init(struct net_device *dev) pep->rx_desc_area_size = size; pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, &pep->rx_desc_dma, GFP_KERNEL); - if (!pep->p_rx_desc_area) { - printk(KERN_ERR "%s: Cannot alloc RX ring (size %d bytes)\n", - dev->name, size); + if (!pep->p_rx_desc_area) goto out; - } + memset((void *)pep->p_rx_desc_area, 0, size); /* initialize the next_desc_ptr links in the Rx descriptors ring */ p_rx_desc = pep->p_rx_desc_area; @@ -1087,11 +1085,8 @@ static int txq_init(struct net_device *dev) pep->tx_desc_area_size = size; pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, &pep->tx_desc_dma, GFP_KERNEL); - if (!pep->p_tx_desc_area) { - printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", - dev->name, size); + if (!pep->p_tx_desc_area) goto out; - } memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); /* Initialize the next_desc_ptr links in the Tx descriptors ring */ p_tx_desc = pep->p_tx_desc_area; diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index fdc5f23d8e9f..05267d716e86 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1837,10 +1837,8 @@ int mlx4_cmd_init(struct mlx4_dev *dev) priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE, &priv->mfunc.vhcr_dma, GFP_KERNEL); - if (!priv->mfunc.vhcr) { - mlx4_err(dev, "Couldn't allocate VHCR.\n"); + if (!priv->mfunc.vhcr) goto err_hcr; - } } priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev, diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c index b0b361546365..c20766c2f65b 100644 --- a/drivers/net/ethernet/natsemi/jazzsonic.c +++ b/drivers/net/ethernet/natsemi/jazzsonic.c @@ -175,13 +175,13 @@ static int sonic_probe1(struct net_device *dev) /* Allocate the entire chunk of memory for the descriptors. Note that this cannot cross a 64K boundary. */ - if ((lp->descriptors = dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { - printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", - dev_name(lp->device)); + lp->descriptors = dma_alloc_coherent(lp->device, + SIZEOF_SONIC_DESC * + SONIC_BUS_SCALE(lp->dma_bitmode), + &lp->descriptors_laddr, + GFP_KERNEL); + if (lp->descriptors == NULL) goto out; - } /* Now set up the pointers to point to the appropriate places */ lp->cda = lp->descriptors; diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index 0ffde69c8d01..346a4e025c34 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -202,13 +202,13 @@ static int macsonic_init(struct net_device *dev) /* Allocate the entire chunk of memory for the descriptors. Note that this cannot cross a 64K boundary. */ - if ((lp->descriptors = dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { - printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", - dev_name(lp->device)); + lp->descriptors = dma_alloc_coherent(lp->device, + SIZEOF_SONIC_DESC * + SONIC_BUS_SCALE(lp->dma_bitmode), + &lp->descriptors_laddr, + GFP_KERNEL); + if (lp->descriptors == NULL) return -ENOMEM; - } /* Now set up the pointers to point to the appropriate places */ lp->cda = lp->descriptors; diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c index 5e4748e855f6..c2e0256fe3df 100644 --- a/drivers/net/ethernet/natsemi/xtsonic.c +++ b/drivers/net/ethernet/natsemi/xtsonic.c @@ -197,14 +197,12 @@ static int __init sonic_probe1(struct net_device *dev) * We also allocate extra space for a pointer to allow freeing * this structure later on (in xtsonic_cleanup_module()). */ - lp->descriptors = - dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, GFP_KERNEL); - + lp->descriptors = dma_alloc_coherent(lp->device, + SIZEOF_SONIC_DESC * + SONIC_BUS_SCALE(lp->dma_bitmode), + &lp->descriptors_laddr, + GFP_KERNEL); if (lp->descriptors == NULL) { - printk(KERN_ERR "%s: couldn't alloc DMA memory for " - " descriptors.\n", dev_name(lp->device)); err = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c index 539d2028e456..3df8287b7452 100644 --- a/drivers/net/ethernet/nuvoton/w90p910_ether.c +++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c @@ -287,23 +287,16 @@ static int w90p910_init_desc(struct net_device *dev) ether = netdev_priv(dev); pdev = ether->pdev; - ether->tdesc = (struct tran_pdesc *) - dma_alloc_coherent(&pdev->dev, sizeof(struct tran_pdesc), - ðer->tdesc_phys, GFP_KERNEL); - - if (!ether->tdesc) { - dev_err(&pdev->dev, "Failed to allocate memory for tx desc\n"); + ether->tdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct tran_pdesc), + ðer->tdesc_phys, GFP_KERNEL); + if (!ether->tdesc) return -ENOMEM; - } - - ether->rdesc = (struct recv_pdesc *) - dma_alloc_coherent(&pdev->dev, sizeof(struct recv_pdesc), - ðer->rdesc_phys, GFP_KERNEL); + ether->rdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct recv_pdesc), + ðer->rdesc_phys, GFP_KERNEL); if (!ether->rdesc) { - dev_err(&pdev->dev, "Failed to allocate memory for rx desc\n"); dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc), - ether->tdesc, ether->tdesc_phys); + ether->tdesc, ether->tdesc_phys); return -ENOMEM; } diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index c4122c86f829..9c88c00c0a42 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -1409,9 +1409,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) dma_alloc_coherent(&pldat->pdev->dev, pldat->dma_buff_size, &dma_handle, GFP_KERNEL); - if (pldat->dma_buff_base_v == NULL) { - dev_err(&pdev->dev, "error getting DMA region.\n"); ret = -ENOMEM; goto err_out_free_irq; } diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 39ab4d09faaa..4bdca9ec6a1a 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1469,12 +1469,11 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter, size = rx_ring->count * bufsz + PCH_GBE_RESERVE_MEMORY; rx_ring->rx_buff_pool = dma_alloc_coherent(&pdev->dev, size, - &rx_ring->rx_buff_pool_logic, - GFP_KERNEL); - if (!rx_ring->rx_buff_pool) { - pr_err("Unable to allocate memory for the receive pool buffer\n"); + &rx_ring->rx_buff_pool_logic, + GFP_KERNEL); + if (!rx_ring->rx_buff_pool) return -ENOMEM; - } + memset(rx_ring->rx_buff_pool, 0, size); rx_ring->rx_buff_pool_size = size; for (i = 0; i < rx_ring->count; i++) { @@ -1777,7 +1776,6 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, &tx_ring->dma, GFP_KERNEL); if (!tx_ring->desc) { vfree(tx_ring->buffer_info); - pr_err("Unable to allocate memory for the transmit descriptor ring\n"); return -ENOMEM; } memset(tx_ring->desc, 0, tx_ring->size); @@ -1821,9 +1819,7 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); - if (!rx_ring->desc) { - pr_err("Unable to allocate memory for the receive descriptor ring\n"); vfree(rx_ring->buffer_info); return -ENOMEM; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index a69097c6b84d..a0649ece8e0a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -532,20 +532,15 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) ptr = (__le32 *)dma_alloc_coherent(&pdev->dev, sizeof(u32), &tx_ring->hw_cons_phys_addr, GFP_KERNEL); - - if (ptr == NULL) { - dev_err(&pdev->dev, "failed to allocate tx consumer\n"); + if (ptr == NULL) return -ENOMEM; - } + tx_ring->hw_consumer = ptr; /* cmd desc ring */ addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring), &tx_ring->phys_addr, GFP_KERNEL); - if (addr == NULL) { - dev_err(&pdev->dev, - "failed to allocate tx desc ring\n"); err = -ENOMEM; goto err_out_free; } @@ -556,11 +551,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; addr = dma_alloc_coherent(&adapter->pdev->dev, - RCV_DESC_RINGSIZE(rds_ring), - &rds_ring->phys_addr, GFP_KERNEL); + RCV_DESC_RINGSIZE(rds_ring), + &rds_ring->phys_addr, GFP_KERNEL); if (addr == NULL) { - dev_err(&pdev->dev, - "failed to allocate rds ring [%d]\n", ring); err = -ENOMEM; goto err_out_free; } @@ -572,11 +565,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) sds_ring = &recv_ctx->sds_rings[ring]; addr = dma_alloc_coherent(&adapter->pdev->dev, - STATUS_DESC_RINGSIZE(sds_ring), - &sds_ring->phys_addr, GFP_KERNEL); + STATUS_DESC_RINGSIZE(sds_ring), + &sds_ring->phys_addr, GFP_KERNEL); if (addr == NULL) { - dev_err(&pdev->dev, - "failed to allocate sds ring [%d]\n", ring); err = -ENOMEM; goto err_out_free; } @@ -753,7 +744,7 @@ int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter, size_t nic_size = sizeof(struct qlcnic_info_le); nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, - &nic_dma_t, GFP_KERNEL); + &nic_dma_t, GFP_KERNEL); if (!nic_info_addr) return -ENOMEM; memset(nic_info_addr, 0, nic_size); @@ -804,7 +795,7 @@ int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter, return err; nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, - &nic_dma_t, GFP_KERNEL); + &nic_dma_t, GFP_KERNEL); if (!nic_info_addr) return -ENOMEM; @@ -949,11 +940,10 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, } stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, - &stats_dma_t, GFP_KERNEL); - if (!stats_addr) { - dev_err(&adapter->pdev->dev, "Unable to allocate memory\n"); + &stats_dma_t, GFP_KERNEL); + if (!stats_addr) return -ENOMEM; - } + memset(stats_addr, 0, stats_size); arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; @@ -1003,12 +993,10 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, return -ENOMEM; stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, - &stats_dma_t, GFP_KERNEL); - if (!stats_addr) { - dev_err(&adapter->pdev->dev, - "%s: Unable to allocate memory.\n", __func__); + &stats_dma_t, GFP_KERNEL); + if (!stats_addr) return -ENOMEM; - } + memset(stats_addr, 0, stats_size); qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS); cmd.req.arg[1] = stats_size << 16; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index abbd22c814a6..4b9bab18ebd9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c @@ -810,11 +810,8 @@ static int __qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter, tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size, &tmp_addr_t, GFP_KERNEL); - if (!tmp_addr) { - dev_err(&adapter->pdev->dev, - "Can't get memory for FW dump template\n"); + if (!tmp_addr) return -ENOMEM; - } if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_TEMP_HDR)) { err = -ENOMEM; diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 33e96176e4d8..7a6471d87300 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -908,11 +908,8 @@ static int sh_eth_ring_init(struct net_device *ndev) /* Allocate all Rx descriptors. */ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, - GFP_KERNEL); - + GFP_KERNEL); if (!mdp->rx_ring) { - dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n", - rx_ringsize); ret = -ENOMEM; goto desc_ring_free; } @@ -922,10 +919,8 @@ static int sh_eth_ring_init(struct net_device *ndev) /* Allocate all Tx descriptors. */ tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, - GFP_KERNEL); + GFP_KERNEL); if (!mdp->tx_ring) { - dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n", - tx_ringsize); ret = -ENOMEM; goto desc_ring_free; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 39c6c5524633..d02b446037d7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -534,25 +534,17 @@ static void init_dma_desc_rings(struct net_device *dev) GFP_KERNEL); priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), GFP_KERNEL); - priv->dma_rx = - (struct dma_desc *)dma_alloc_coherent(priv->device, - rxsize * - sizeof(struct dma_desc), - &priv->dma_rx_phy, - GFP_KERNEL); + priv->dma_rx = dma_alloc_coherent(priv->device, + rxsize * sizeof(struct dma_desc), + &priv->dma_rx_phy, GFP_KERNEL); priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), GFP_KERNEL); - priv->dma_tx = - (struct dma_desc *)dma_alloc_coherent(priv->device, - txsize * - sizeof(struct dma_desc), - &priv->dma_tx_phy, - GFP_KERNEL); - - if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) { - pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__); + priv->dma_tx = dma_alloc_coherent(priv->device, + txsize * sizeof(struct dma_desc), + &priv->dma_tx_phy, GFP_KERNEL); + + if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) return; - } DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, " "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c index 5fafca065305..054975939a18 100644 --- a/drivers/net/ethernet/sun/sunbmac.c +++ b/drivers/net/ethernet/sun/sunbmac.c @@ -1169,10 +1169,8 @@ static int bigmac_ether_init(struct platform_device *op, bp->bmac_block = dma_alloc_coherent(&bp->bigmac_op->dev, PAGE_SIZE, &bp->bblock_dvma, GFP_ATOMIC); - if (bp->bmac_block == NULL || bp->bblock_dvma == 0) { - printk(KERN_ERR "BIGMAC: Cannot allocate consistent DMA.\n"); + if (bp->bmac_block == NULL || bp->bblock_dvma == 0) goto fail_and_cleanup; - } /* Get the board revision of this BigMAC. */ bp->board_rev = of_getintprop_default(bp->bigmac_op->dev.of_node, diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index a1bff49a8155..436fa9d5a071 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2752,10 +2752,8 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe) &hp->hblock_dvma, GFP_ATOMIC); err = -ENOMEM; - if (!hp->happy_block) { - printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n"); + if (!hp->happy_block) goto err_out_iounmap; - } /* Force check of the link first time we are brought up. */ hp->linkcheck = 0; @@ -3068,14 +3066,11 @@ static int happy_meal_pci_probe(struct pci_dev *pdev, hp->happy_bursts = DMA_BURSTBITS; #endif - hp->happy_block = (struct hmeal_init_block *) - dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &hp->hblock_dvma, GFP_KERNEL); - + hp->happy_block = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, + &hp->hblock_dvma, GFP_KERNEL); err = -ENODEV; - if (!hp->happy_block) { - printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n"); + if (!hp->happy_block) goto err_out_iounmap; - } hp->linkcheck = 0; hp->timer_state = asleep; diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 8fa947a2d929..99fe3c6eea31 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1309,22 +1309,16 @@ static int tsi108_open(struct net_device *dev) } data->rxring = dma_alloc_coherent(NULL, rxring_size, - &data->rxdma, GFP_KERNEL); - + &data->rxdma, GFP_KERNEL); if (!data->rxring) { - printk(KERN_DEBUG - "TSI108_ETH: failed to allocate memory for rxring!\n"); return -ENOMEM; } else { memset(data->rxring, 0, rxring_size); } data->txring = dma_alloc_coherent(NULL, txring_size, - &data->txdma, GFP_KERNEL); - + &data->txdma, GFP_KERNEL); if (!data->txring) { - printk(KERN_DEBUG - "TSI108_ETH: failed to allocate memory for txring!\n"); pci_free_consistent(0, rxring_size, data->rxring, data->rxdma); return -ENOMEM; } else { diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 5ac43e4ace25..a64a6d74a5c8 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -246,19 +246,14 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->tx_bd_v) * TX_BD_NUM, &lp->tx_bd_p, GFP_KERNEL); - if (!lp->tx_bd_v) { - dev_err(&ndev->dev, - "unable to allocate DMA TX buffer descriptors"); + if (!lp->tx_bd_v) goto out; - } + lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->rx_bd_v) * RX_BD_NUM, &lp->rx_bd_p, GFP_KERNEL); - if (!lp->rx_bd_v) { - dev_err(&ndev->dev, - "unable to allocate DMA RX buffer descriptors"); + if (!lp->rx_bd_v) goto out; - } memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); for (i = 0; i < TX_BD_NUM; i++) { diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 397d4a6a1f30..c238f980e28e 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -205,21 +205,15 @@ static int axienet_dma_bd_init(struct net_device *ndev) sizeof(*lp->tx_bd_v) * TX_BD_NUM, &lp->tx_bd_p, GFP_KERNEL); - if (!lp->tx_bd_v) { - dev_err(&ndev->dev, "unable to allocate DMA Tx buffer " - "descriptors"); + if (!lp->tx_bd_v) goto out; - } lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->rx_bd_v) * RX_BD_NUM, &lp->rx_bd_p, GFP_KERNEL); - if (!lp->rx_bd_v) { - dev_err(&ndev->dev, "unable to allocate DMA Rx buffer " - "descriptors"); + if (!lp->rx_bd_v) goto out; - } memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); for (i = 0; i < TX_BD_NUM; i++) { diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index 502c8ff1d985..f116e51e3865 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -1071,11 +1071,9 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name, bp->kmalloced = top_v = dma_alloc_coherent(bp->bus_dev, alloc_size, &bp->kmalloced_dma, GFP_ATOMIC); - if (top_v == NULL) { - printk("%s: Could not allocate memory for host buffers " - "and structures!\n", print_name); + if (top_v == NULL) return DFX_K_FAILURE; - } + memset(top_v, 0, alloc_size); /* zero out memory before continuing */ top_p = bp->kmalloced_dma; /* get physical address of buffer */ diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index fed4a05d55c7..a06fca61c9a0 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c @@ -389,7 +389,8 @@ static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev) set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev); set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev); - port->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); + port->rx_dma_buf.buf = dma_alloc_coherent(NULL, PAGE_SIZE, + &dma_handle, GFP_DMA); port->rx_dma_buf.head = 0; port->rx_dma_buf.tail = 0; port->rx_dma_nrows = 0; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 5290952b60c2..59b45c10adbc 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -564,20 +564,14 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, self->rx_buff.head = dma_alloc_coherent(NULL, self->rx_buff.truesize, &self->rx_buff_dma, GFP_KERNEL); - if (self->rx_buff.head == NULL) { - IRDA_ERROR("%s, Can't allocate memory for receive buffer!\n", - driver_name); + if (self->rx_buff.head == NULL) goto err_out2; - } self->tx_buff.head = dma_alloc_coherent(NULL, self->tx_buff.truesize, &self->tx_buff_dma, GFP_KERNEL); - if (self->tx_buff.head == NULL) { - IRDA_ERROR("%s, Can't allocate memory for transmit buffer!\n", - driver_name); + if (self->tx_buff.head == NULL) goto err_out3; - } memset(self->rx_buff.head, 0, self->rx_buff.truesize); memset(self->tx_buff.head, 0, self->tx_buff.truesize); diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index d1315b442375..55dd95f9824f 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -83,8 +83,6 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) */ vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); if (!vring->va) { - wil_err(wil, "vring_alloc [%d] failed to alloc DMA mem\n", - vring->size); kfree(vring->ctx); vring->ctx = NULL; return -ENOMEM; diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 2d3c6644f82d..07d7e928eac7 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -335,11 +335,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) B43legacy_DMA_RINGMEMSIZE, &(ring->dmabase), GFP_KERNEL); - if (!ring->descbase) { - b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" - " failed\n"); + if (!ring->descbase) return -ENOMEM; - } memset(ring->descbase, 0, B43legacy_DMA_RINGMEMSIZE); return 0; diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index e0b9d7fa5de0..dc1e6da9976a 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -2379,10 +2379,8 @@ il3945_hw_set_hw_params(struct il_priv *il) il->_3945.shared_virt = dma_alloc_coherent(&il->pci_dev->dev, sizeof(struct il3945_shared), &il->_3945.shared_phys, GFP_KERNEL); - if (!il->_3945.shared_virt) { - IL_ERR("failed to allocate pci memory\n"); + if (!il->_3945.shared_virt) return -ENOMEM; - } il->hw_params.bcast_id = IL3945_BROADCAST_ID; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index e006ea831320..bd4c18804709 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -2941,10 +2941,9 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) * shared with device */ txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); - if (!txq->tfds) { - IL_ERR("Fail to alloc TFDs\n"); + if (!txq->tfds) goto error; - } + txq->q.id = id; return 0; diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8595c16f74de..7a508d835f5a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -501,10 +501,8 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, * shared with device */ txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); - if (!txq->tfds) { - IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); + if (!txq->tfds) goto error; - } BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != -- cgit From 1bcac3b08e2f13c31f798ac46897e33f08cfbd53 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Thu, 14 Mar 2013 22:50:07 +0000 Subject: driver/qlogic: replace ip_fast_csum with csum_replace2 replace ip_fast_csum with csum_replace2 to save cpu cycles Signed-off-by: Li RongQing Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 4 ++-- drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 4782dcfde736..7692dfd4f262 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "netxen_nic.h" #include "netxen_nic_hw.h" @@ -1641,9 +1642,8 @@ netxen_process_lro(struct netxen_adapter *adapter, th = (struct tcphdr *)((skb->data + vhdr_len) + (iph->ihl << 2)); length = (iph->ihl << 2) + (th->doff << 2) + lro_length; + csum_replace2(&iph->check, iph->tot_len, htons(length)); iph->tot_len = htons(length); - iph->check = 0; - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); th->psh = push; th->seq = htonl(seq_number); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 0e630061bff3..891f12d47c9c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "qlcnic.h" @@ -1132,9 +1133,8 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, iph = (struct iphdr *)skb->data; th = (struct tcphdr *)(skb->data + (iph->ihl << 2)); length = (iph->ihl << 2) + (th->doff << 2) + lro_length; + csum_replace2(&iph->check, iph->tot_len, htons(length)); iph->tot_len = htons(length); - iph->check = 0; - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } th->psh = push; @@ -1595,9 +1595,8 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, iph = (struct iphdr *)skb->data; th = (struct tcphdr *)(skb->data + (iph->ihl << 2)); length = (iph->ihl << 2) + (th->doff << 2) + lro_length; + csum_replace2(&iph->check, iph->tot_len, htons(length)); iph->tot_len = htons(length); - iph->check = 0; - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } th->psh = push; -- cgit From 0b15841b0bbbde75134a777c543dc51fe6187108 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 15 Mar 2013 10:55:31 -0400 Subject: intel_idle: additional Haswell CPU-id There is an additional HSW CPU-id, 0x46, which has C-states exactly like CPU-id 0x45. Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 5d6675013864..1a38dd7dfe4e 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -465,6 +465,7 @@ static const struct x86_cpu_id intel_idle_ids[] = { ICPU(0x3c, idle_cpu_hsw), ICPU(0x3f, idle_cpu_hsw), ICPU(0x45, idle_cpu_hsw), + ICPU(0x46, idle_cpu_hsw), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); -- cgit From af3c226283dd903cb0aad4bddf85b8c2243ee8a9 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:49 -0400 Subject: staging: omap-thermal: use BIT() macro For code readability, this patch changes the bit definition under omap-bandgap.h to use the BIT() macro. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 96 ++++++++++++++--------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 3e9072c8c6bd..8d3ee2bcf6d1 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -29,17 +29,17 @@ /* TEMP_SENSOR OMAP4430 */ #define OMAP4430_BGAP_TSHUT_SHIFT 11 -#define OMAP4430_BGAP_TSHUT_MASK (1 << 11) +#define OMAP4430_BGAP_TSHUT_MASK BIT(11) /* TEMP_SENSOR OMAP4430 */ #define OMAP4430_BGAP_TEMPSOFF_SHIFT 12 -#define OMAP4430_BGAP_TEMPSOFF_MASK (1 << 12) +#define OMAP4430_BGAP_TEMPSOFF_MASK BIT(12) #define OMAP4430_SINGLE_MODE_SHIFT 10 -#define OMAP4430_SINGLE_MODE_MASK (1 << 10) +#define OMAP4430_SINGLE_MODE_MASK BIT(10) #define OMAP4430_BGAP_TEMP_SENSOR_SOC_SHIFT 9 -#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9) +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK BIT(9) #define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 -#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8) +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(8) #define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) @@ -53,21 +53,21 @@ /* TEMP_SENSOR OMAP4460 */ #define OMAP4460_BGAP_TEMPSOFF_SHIFT 13 -#define OMAP4460_BGAP_TEMPSOFF_MASK (1 << 13) +#define OMAP4460_BGAP_TEMPSOFF_MASK BIT(13) #define OMAP4460_BGAP_TEMP_SENSOR_SOC_SHIFT 11 -#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK (1 << 11) +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK BIT(11) #define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 -#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 10) +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) #define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) /* BANDGAP_CTRL */ #define OMAP4460_SINGLE_MODE_SHIFT 31 -#define OMAP4460_SINGLE_MODE_MASK (1 << 31) +#define OMAP4460_SINGLE_MODE_MASK BIT(31) #define OMAP4460_MASK_HOT_SHIFT 1 -#define OMAP4460_MASK_HOT_MASK (1 << 1) +#define OMAP4460_MASK_HOT_MASK BIT(1) #define OMAP4460_MASK_COLD_SHIFT 0 -#define OMAP4460_MASK_COLD_MASK (1 << 0) +#define OMAP4460_MASK_COLD_MASK BIT(0) /* BANDGAP_COUNTER */ #define OMAP4460_COUNTER_SHIFT 0 @@ -87,57 +87,57 @@ /* BANDGAP_STATUS */ #define OMAP4460_CLEAN_STOP_SHIFT 3 -#define OMAP4460_CLEAN_STOP_MASK (1 << 3) +#define OMAP4460_CLEAN_STOP_MASK BIT(3) #define OMAP4460_BGAP_ALERT_SHIFT 2 -#define OMAP4460_BGAP_ALERT_MASK (1 << 2) +#define OMAP4460_BGAP_ALERT_MASK BIT(2) #define OMAP4460_HOT_FLAG_SHIFT 1 -#define OMAP4460_HOT_FLAG_MASK (1 << 1) +#define OMAP4460_HOT_FLAG_MASK BIT(1) #define OMAP4460_COLD_FLAG_SHIFT 0 -#define OMAP4460_COLD_FLAG_MASK (1 << 0) +#define OMAP4460_COLD_FLAG_MASK BIT(0) /* TEMP_SENSOR OMAP5430 */ #define OMAP5430_BGAP_TEMP_SENSOR_SOC_SHIFT 12 -#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK (1 << 12) +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK BIT(12) #define OMAP5430_BGAP_TEMPSOFF_SHIFT 11 -#define OMAP5430_BGAP_TEMPSOFF_MASK (1 << 11) +#define OMAP5430_BGAP_TEMPSOFF_MASK BIT(11) #define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 -#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 10) +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) #define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) /* BANDGAP_CTRL */ #define OMAP5430_MASK_HOT_CORE_SHIFT 5 -#define OMAP5430_MASK_HOT_CORE_MASK (1 << 5) +#define OMAP5430_MASK_HOT_CORE_MASK BIT(5) #define OMAP5430_MASK_COLD_CORE_SHIFT 4 -#define OMAP5430_MASK_COLD_CORE_MASK (1 << 4) +#define OMAP5430_MASK_COLD_CORE_MASK BIT(4) #define OMAP5430_MASK_HOT_GPU_SHIFT 3 -#define OMAP5430_MASK_HOT_GPU_MASK (1 << 3) +#define OMAP5430_MASK_HOT_GPU_MASK BIT(3) #define OMAP5430_MASK_COLD_GPU_SHIFT 2 -#define OMAP5430_MASK_COLD_GPU_MASK (1 << 2) +#define OMAP5430_MASK_COLD_GPU_MASK BIT(2) #define OMAP5430_MASK_HOT_MPU_SHIFT 1 -#define OMAP5430_MASK_HOT_MPU_MASK (1 << 1) +#define OMAP5430_MASK_HOT_MPU_MASK BIT(1) #define OMAP5430_MASK_COLD_MPU_SHIFT 0 -#define OMAP5430_MASK_COLD_MPU_MASK (1 << 0) +#define OMAP5430_MASK_COLD_MPU_MASK BIT(0) #define OMAP5430_MASK_SIDLEMODE_SHIFT 30 #define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30) #define OMAP5430_MASK_FREEZE_CORE_SHIFT 23 -#define OMAP5430_MASK_FREEZE_CORE_MASK (1 << 23) +#define OMAP5430_MASK_FREEZE_CORE_MASK BIT(23) #define OMAP5430_MASK_FREEZE_GPU_SHIFT 22 -#define OMAP5430_MASK_FREEZE_GPU_MASK (1 << 22) +#define OMAP5430_MASK_FREEZE_GPU_MASK BIT(22) #define OMAP5430_MASK_FREEZE_MPU_SHIFT 21 -#define OMAP5430_MASK_FREEZE_MPU_MASK (1 << 21) +#define OMAP5430_MASK_FREEZE_MPU_MASK BIT(21) #define OMAP5430_MASK_CLEAR_CORE_SHIFT 20 -#define OMAP5430_MASK_CLEAR_CORE_MASK (1 << 20) +#define OMAP5430_MASK_CLEAR_CORE_MASK BIT(20) #define OMAP5430_MASK_CLEAR_GPU_SHIFT 19 -#define OMAP5430_MASK_CLEAR_GPU_MASK (1 << 19) +#define OMAP5430_MASK_CLEAR_GPU_MASK BIT(19) #define OMAP5430_MASK_CLEAR_MPU_SHIFT 18 -#define OMAP5430_MASK_CLEAR_MPU_MASK (1 << 18) +#define OMAP5430_MASK_CLEAR_MPU_MASK BIT(18) #define OMAP5430_MASK_CLEAR_ACCUM_CORE_SHIFT 17 -#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK (1 << 17) +#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK BIT(17) #define OMAP5430_MASK_CLEAR_ACCUM_GPU_SHIFT 16 -#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK (1 << 16) +#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK BIT(16) #define OMAP5430_MASK_CLEAR_ACCUM_MPU_SHIFT 15 -#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK (1 << 15) +#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK BIT(15) /* BANDGAP_COUNTER */ #define OMAP5430_COUNTER_SHIFT 0 @@ -169,19 +169,19 @@ /* BANDGAP_STATUS */ #define OMAP5430_BGAP_ALERT_SHIFT 31 -#define OMAP5430_BGAP_ALERT_MASK (1 << 31) +#define OMAP5430_BGAP_ALERT_MASK BIT(31) #define OMAP5430_HOT_CORE_FLAG_SHIFT 5 -#define OMAP5430_HOT_CORE_FLAG_MASK (1 << 5) +#define OMAP5430_HOT_CORE_FLAG_MASK BIT(5) #define OMAP5430_COLD_CORE_FLAG_SHIFT 4 -#define OMAP5430_COLD_CORE_FLAG_MASK (1 << 4) +#define OMAP5430_COLD_CORE_FLAG_MASK BIT(4) #define OMAP5430_HOT_GPU_FLAG_SHIFT 3 -#define OMAP5430_HOT_GPU_FLAG_MASK (1 << 3) +#define OMAP5430_HOT_GPU_FLAG_MASK BIT(3) #define OMAP5430_COLD_GPU_FLAG_SHIFT 2 -#define OMAP5430_COLD_GPU_FLAG_MASK (1 << 2) +#define OMAP5430_COLD_GPU_FLAG_MASK BIT(2) #define OMAP5430_HOT_MPU_FLAG_SHIFT 1 -#define OMAP5430_HOT_MPU_FLAG_MASK (1 << 1) +#define OMAP5430_HOT_MPU_FLAG_MASK BIT(1) #define OMAP5430_COLD_MPU_FLAG_SHIFT 0 -#define OMAP5430_COLD_MPU_FLAG_MASK (1 << 0) +#define OMAP5430_COLD_MPU_FLAG_MASK BIT(0) /* Offsets from the base of temperature sensor registers */ @@ -434,14 +434,14 @@ struct omap_temp_sensor { * @expose_sensor: callback to export sensor to thermal API */ struct omap_bandgap_data { -#define OMAP_BANDGAP_FEATURE_TSHUT (1 << 0) -#define OMAP_BANDGAP_FEATURE_TSHUT_CONFIG (1 << 1) -#define OMAP_BANDGAP_FEATURE_TALERT (1 << 2) -#define OMAP_BANDGAP_FEATURE_MODE_CONFIG (1 << 3) -#define OMAP_BANDGAP_FEATURE_COUNTER (1 << 4) -#define OMAP_BANDGAP_FEATURE_POWER_SWITCH (1 << 5) -#define OMAP_BANDGAP_FEATURE_CLK_CTRL (1 << 6) -#define OMAP_BANDGAP_FEATURE_FREEZE_BIT (1 << 7) +#define OMAP_BANDGAP_FEATURE_TSHUT BIT(0) +#define OMAP_BANDGAP_FEATURE_TSHUT_CONFIG BIT(1) +#define OMAP_BANDGAP_FEATURE_TALERT BIT(2) +#define OMAP_BANDGAP_FEATURE_MODE_CONFIG BIT(3) +#define OMAP_BANDGAP_FEATURE_COUNTER BIT(4) +#define OMAP_BANDGAP_FEATURE_POWER_SWITCH BIT(5) +#define OMAP_BANDGAP_FEATURE_CLK_CTRL BIT(6) +#define OMAP_BANDGAP_FEATURE_FREEZE_BIT BIT(7) #define OMAP_BANDGAP_HAS(b, f) \ ((b)->conf->features & OMAP_BANDGAP_FEATURE_ ## f) unsigned int features; -- cgit From 9011cc2978666589056d9aa54547fc814b58f3a3 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:50 -0400 Subject: staging: omap-thermal: remove unused _SHIFT macros As these macros are not used on any part of the code, this patch removes all the *_SHIT defines. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 57 ----------------------------- 1 file changed, 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 8d3ee2bcf6d1..5ce1659f8885 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -28,19 +28,13 @@ #include /* TEMP_SENSOR OMAP4430 */ -#define OMAP4430_BGAP_TSHUT_SHIFT 11 #define OMAP4430_BGAP_TSHUT_MASK BIT(11) /* TEMP_SENSOR OMAP4430 */ -#define OMAP4430_BGAP_TEMPSOFF_SHIFT 12 #define OMAP4430_BGAP_TEMPSOFF_MASK BIT(12) -#define OMAP4430_SINGLE_MODE_SHIFT 10 #define OMAP4430_SINGLE_MODE_MASK BIT(10) -#define OMAP4430_BGAP_TEMP_SENSOR_SOC_SHIFT 9 #define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK BIT(9) -#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 #define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(8) -#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) #define OMAP4430_ADC_START_VALUE 0 @@ -52,135 +46,84 @@ #define OMAP4430_HYST_VAL 5000 /* TEMP_SENSOR OMAP4460 */ -#define OMAP4460_BGAP_TEMPSOFF_SHIFT 13 #define OMAP4460_BGAP_TEMPSOFF_MASK BIT(13) -#define OMAP4460_BGAP_TEMP_SENSOR_SOC_SHIFT 11 #define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK BIT(11) -#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 #define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) -#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) /* BANDGAP_CTRL */ -#define OMAP4460_SINGLE_MODE_SHIFT 31 #define OMAP4460_SINGLE_MODE_MASK BIT(31) -#define OMAP4460_MASK_HOT_SHIFT 1 #define OMAP4460_MASK_HOT_MASK BIT(1) -#define OMAP4460_MASK_COLD_SHIFT 0 #define OMAP4460_MASK_COLD_MASK BIT(0) /* BANDGAP_COUNTER */ -#define OMAP4460_COUNTER_SHIFT 0 #define OMAP4460_COUNTER_MASK (0xffffff << 0) /* BANDGAP_THRESHOLD */ -#define OMAP4460_T_HOT_SHIFT 16 #define OMAP4460_T_HOT_MASK (0x3ff << 16) -#define OMAP4460_T_COLD_SHIFT 0 #define OMAP4460_T_COLD_MASK (0x3ff << 0) /* TSHUT_THRESHOLD */ -#define OMAP4460_TSHUT_HOT_SHIFT 16 #define OMAP4460_TSHUT_HOT_MASK (0x3ff << 16) -#define OMAP4460_TSHUT_COLD_SHIFT 0 #define OMAP4460_TSHUT_COLD_MASK (0x3ff << 0) /* BANDGAP_STATUS */ -#define OMAP4460_CLEAN_STOP_SHIFT 3 #define OMAP4460_CLEAN_STOP_MASK BIT(3) -#define OMAP4460_BGAP_ALERT_SHIFT 2 #define OMAP4460_BGAP_ALERT_MASK BIT(2) -#define OMAP4460_HOT_FLAG_SHIFT 1 #define OMAP4460_HOT_FLAG_MASK BIT(1) -#define OMAP4460_COLD_FLAG_SHIFT 0 #define OMAP4460_COLD_FLAG_MASK BIT(0) /* TEMP_SENSOR OMAP5430 */ -#define OMAP5430_BGAP_TEMP_SENSOR_SOC_SHIFT 12 #define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK BIT(12) -#define OMAP5430_BGAP_TEMPSOFF_SHIFT 11 #define OMAP5430_BGAP_TEMPSOFF_MASK BIT(11) -#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 #define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) -#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 #define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) /* BANDGAP_CTRL */ -#define OMAP5430_MASK_HOT_CORE_SHIFT 5 #define OMAP5430_MASK_HOT_CORE_MASK BIT(5) -#define OMAP5430_MASK_COLD_CORE_SHIFT 4 #define OMAP5430_MASK_COLD_CORE_MASK BIT(4) -#define OMAP5430_MASK_HOT_GPU_SHIFT 3 #define OMAP5430_MASK_HOT_GPU_MASK BIT(3) -#define OMAP5430_MASK_COLD_GPU_SHIFT 2 #define OMAP5430_MASK_COLD_GPU_MASK BIT(2) -#define OMAP5430_MASK_HOT_MPU_SHIFT 1 #define OMAP5430_MASK_HOT_MPU_MASK BIT(1) -#define OMAP5430_MASK_COLD_MPU_SHIFT 0 #define OMAP5430_MASK_COLD_MPU_MASK BIT(0) -#define OMAP5430_MASK_SIDLEMODE_SHIFT 30 #define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30) -#define OMAP5430_MASK_FREEZE_CORE_SHIFT 23 #define OMAP5430_MASK_FREEZE_CORE_MASK BIT(23) -#define OMAP5430_MASK_FREEZE_GPU_SHIFT 22 #define OMAP5430_MASK_FREEZE_GPU_MASK BIT(22) -#define OMAP5430_MASK_FREEZE_MPU_SHIFT 21 #define OMAP5430_MASK_FREEZE_MPU_MASK BIT(21) -#define OMAP5430_MASK_CLEAR_CORE_SHIFT 20 #define OMAP5430_MASK_CLEAR_CORE_MASK BIT(20) -#define OMAP5430_MASK_CLEAR_GPU_SHIFT 19 #define OMAP5430_MASK_CLEAR_GPU_MASK BIT(19) -#define OMAP5430_MASK_CLEAR_MPU_SHIFT 18 #define OMAP5430_MASK_CLEAR_MPU_MASK BIT(18) -#define OMAP5430_MASK_CLEAR_ACCUM_CORE_SHIFT 17 #define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK BIT(17) -#define OMAP5430_MASK_CLEAR_ACCUM_GPU_SHIFT 16 #define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK BIT(16) -#define OMAP5430_MASK_CLEAR_ACCUM_MPU_SHIFT 15 #define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK BIT(15) /* BANDGAP_COUNTER */ -#define OMAP5430_COUNTER_SHIFT 0 #define OMAP5430_COUNTER_MASK (0xffffff << 0) /* BANDGAP_THRESHOLD */ -#define OMAP5430_T_HOT_SHIFT 16 #define OMAP5430_T_HOT_MASK (0x3ff << 16) -#define OMAP5430_T_COLD_SHIFT 0 #define OMAP5430_T_COLD_MASK (0x3ff << 0) /* TSHUT_THRESHOLD */ -#define OMAP5430_TSHUT_HOT_SHIFT 16 #define OMAP5430_TSHUT_HOT_MASK (0x3ff << 16) -#define OMAP5430_TSHUT_COLD_SHIFT 0 #define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0) /* BANDGAP_CUMUL_DTEMP_MPU */ -#define OMAP5430_CUMUL_DTEMP_MPU_SHIFT 0 #define OMAP5430_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0) /* BANDGAP_CUMUL_DTEMP_GPU */ -#define OMAP5430_CUMUL_DTEMP_GPU_SHIFT 0 #define OMAP5430_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0) /* BANDGAP_CUMUL_DTEMP_CORE */ -#define OMAP5430_CUMUL_DTEMP_CORE_SHIFT 0 #define OMAP5430_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0) /* BANDGAP_STATUS */ -#define OMAP5430_BGAP_ALERT_SHIFT 31 #define OMAP5430_BGAP_ALERT_MASK BIT(31) -#define OMAP5430_HOT_CORE_FLAG_SHIFT 5 #define OMAP5430_HOT_CORE_FLAG_MASK BIT(5) -#define OMAP5430_COLD_CORE_FLAG_SHIFT 4 #define OMAP5430_COLD_CORE_FLAG_MASK BIT(4) -#define OMAP5430_HOT_GPU_FLAG_SHIFT 3 #define OMAP5430_HOT_GPU_FLAG_MASK BIT(3) -#define OMAP5430_COLD_GPU_FLAG_SHIFT 2 #define OMAP5430_COLD_GPU_FLAG_MASK BIT(2) -#define OMAP5430_HOT_MPU_FLAG_SHIFT 1 #define OMAP5430_HOT_MPU_FLAG_MASK BIT(1) -#define OMAP5430_COLD_MPU_FLAG_SHIFT 0 #define OMAP5430_COLD_MPU_FLAG_MASK BIT(0) /* Offsets from the base of temperature sensor registers */ -- cgit From 787f3c27bd75f7d87c27570285457f83e3520aed Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:51 -0400 Subject: staging: omap-thermal: create header for register, bitfields and definitions In order to have a better code readability and organization, this patch splits omap-bandgap.h into three headers. . omap-bandgap.h will contain only the driver related data structures definitions and macros . omap4xxx-bandgap.h will contain only defines and bitfields related to OMAP4 based devices . omap5xxx-bandgap.h will contain only defines and bitfields related to OMAP5 based devices Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 195 --------------------- drivers/staging/omap-thermal/omap4-thermal-data.c | 1 + drivers/staging/omap-thermal/omap4xxx-bandgap.h | 175 +++++++++++++++++++ drivers/staging/omap-thermal/omap5-thermal-data.c | 1 + drivers/staging/omap-thermal/omap5xxx-bandgap.h | 199 ++++++++++++++++++++++ 5 files changed, 376 insertions(+), 195 deletions(-) create mode 100644 drivers/staging/omap-thermal/omap4xxx-bandgap.h create mode 100644 drivers/staging/omap-thermal/omap5xxx-bandgap.h (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 5ce1659f8885..7d5ac3fa91c5 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -27,201 +27,6 @@ #include #include -/* TEMP_SENSOR OMAP4430 */ -#define OMAP4430_BGAP_TSHUT_MASK BIT(11) - -/* TEMP_SENSOR OMAP4430 */ -#define OMAP4430_BGAP_TEMPSOFF_MASK BIT(12) -#define OMAP4430_SINGLE_MODE_MASK BIT(10) -#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK BIT(9) -#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(8) -#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) - -#define OMAP4430_ADC_START_VALUE 0 -#define OMAP4430_ADC_END_VALUE 127 -#define OMAP4430_MAX_FREQ 32768 -#define OMAP4430_MIN_FREQ 32768 -#define OMAP4430_MIN_TEMP -40000 -#define OMAP4430_MAX_TEMP 125000 -#define OMAP4430_HYST_VAL 5000 - -/* TEMP_SENSOR OMAP4460 */ -#define OMAP4460_BGAP_TEMPSOFF_MASK BIT(13) -#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK BIT(11) -#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) -#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) - -/* BANDGAP_CTRL */ -#define OMAP4460_SINGLE_MODE_MASK BIT(31) -#define OMAP4460_MASK_HOT_MASK BIT(1) -#define OMAP4460_MASK_COLD_MASK BIT(0) - -/* BANDGAP_COUNTER */ -#define OMAP4460_COUNTER_MASK (0xffffff << 0) - -/* BANDGAP_THRESHOLD */ -#define OMAP4460_T_HOT_MASK (0x3ff << 16) -#define OMAP4460_T_COLD_MASK (0x3ff << 0) - -/* TSHUT_THRESHOLD */ -#define OMAP4460_TSHUT_HOT_MASK (0x3ff << 16) -#define OMAP4460_TSHUT_COLD_MASK (0x3ff << 0) - -/* BANDGAP_STATUS */ -#define OMAP4460_CLEAN_STOP_MASK BIT(3) -#define OMAP4460_BGAP_ALERT_MASK BIT(2) -#define OMAP4460_HOT_FLAG_MASK BIT(1) -#define OMAP4460_COLD_FLAG_MASK BIT(0) - -/* TEMP_SENSOR OMAP5430 */ -#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK BIT(12) -#define OMAP5430_BGAP_TEMPSOFF_MASK BIT(11) -#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) -#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) - -/* BANDGAP_CTRL */ -#define OMAP5430_MASK_HOT_CORE_MASK BIT(5) -#define OMAP5430_MASK_COLD_CORE_MASK BIT(4) -#define OMAP5430_MASK_HOT_GPU_MASK BIT(3) -#define OMAP5430_MASK_COLD_GPU_MASK BIT(2) -#define OMAP5430_MASK_HOT_MPU_MASK BIT(1) -#define OMAP5430_MASK_COLD_MPU_MASK BIT(0) -#define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30) -#define OMAP5430_MASK_FREEZE_CORE_MASK BIT(23) -#define OMAP5430_MASK_FREEZE_GPU_MASK BIT(22) -#define OMAP5430_MASK_FREEZE_MPU_MASK BIT(21) -#define OMAP5430_MASK_CLEAR_CORE_MASK BIT(20) -#define OMAP5430_MASK_CLEAR_GPU_MASK BIT(19) -#define OMAP5430_MASK_CLEAR_MPU_MASK BIT(18) -#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK BIT(17) -#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK BIT(16) -#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK BIT(15) - -/* BANDGAP_COUNTER */ -#define OMAP5430_COUNTER_MASK (0xffffff << 0) - -/* BANDGAP_THRESHOLD */ -#define OMAP5430_T_HOT_MASK (0x3ff << 16) -#define OMAP5430_T_COLD_MASK (0x3ff << 0) - -/* TSHUT_THRESHOLD */ -#define OMAP5430_TSHUT_HOT_MASK (0x3ff << 16) -#define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0) - -/* BANDGAP_CUMUL_DTEMP_MPU */ -#define OMAP5430_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0) - -/* BANDGAP_CUMUL_DTEMP_GPU */ -#define OMAP5430_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0) - -/* BANDGAP_CUMUL_DTEMP_CORE */ -#define OMAP5430_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0) - -/* BANDGAP_STATUS */ -#define OMAP5430_BGAP_ALERT_MASK BIT(31) -#define OMAP5430_HOT_CORE_FLAG_MASK BIT(5) -#define OMAP5430_COLD_CORE_FLAG_MASK BIT(4) -#define OMAP5430_HOT_GPU_FLAG_MASK BIT(3) -#define OMAP5430_COLD_GPU_FLAG_MASK BIT(2) -#define OMAP5430_HOT_MPU_FLAG_MASK BIT(1) -#define OMAP5430_COLD_MPU_FLAG_MASK BIT(0) - -/* Offsets from the base of temperature sensor registers */ - -/* 4430 - All goes relative to OPP_BGAP */ -#define OMAP4430_FUSE_OPP_BGAP 0x0 -#define OMAP4430_TEMP_SENSOR_CTRL_OFFSET 0xCC - -/* 4460 - All goes relative to OPP_BGAP */ -#define OMAP4460_FUSE_OPP_BGAP 0x0 -#define OMAP4460_TEMP_SENSOR_CTRL_OFFSET 0xCC -#define OMAP4460_BGAP_CTRL_OFFSET 0x118 -#define OMAP4460_BGAP_COUNTER_OFFSET 0x11C -#define OMAP4460_BGAP_THRESHOLD_OFFSET 0x120 -#define OMAP4460_BGAP_TSHUT_OFFSET 0x124 -#define OMAP4460_BGAP_STATUS_OFFSET 0x128 - -/* 5430 - All goes relative to OPP_BGAP_GPU */ -#define OMAP5430_FUSE_OPP_BGAP_GPU 0x0 -#define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x150 -#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x1A8 -#define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x1B4 -#define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET 0x1C0 -#define OMAP5430_BGAP_DTEMP_GPU_0_OFFSET 0x1F4 -#define OMAP5430_BGAP_DTEMP_GPU_1_OFFSET 0x1F8 -#define OMAP5430_BGAP_DTEMP_GPU_2_OFFSET 0x1FC -#define OMAP5430_BGAP_DTEMP_GPU_3_OFFSET 0x200 -#define OMAP5430_BGAP_DTEMP_GPU_4_OFFSET 0x204 - -#define OMAP5430_FUSE_OPP_BGAP_MPU 0x4 -#define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x14C -#define OMAP5430_BGAP_CTRL_OFFSET 0x1A0 -#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x1A4 -#define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x1B0 -#define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET 0x1BC -#define OMAP5430_BGAP_DTEMP_MPU_0_OFFSET 0x1E0 -#define OMAP5430_BGAP_DTEMP_MPU_1_OFFSET 0x1E4 -#define OMAP5430_BGAP_DTEMP_MPU_2_OFFSET 0x1E8 -#define OMAP5430_BGAP_DTEMP_MPU_3_OFFSET 0x1EC -#define OMAP5430_BGAP_DTEMP_MPU_4_OFFSET 0x1F0 - -#define OMAP5430_FUSE_OPP_BGAP_CORE 0x8 -#define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x154 -#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x1AC -#define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x1B8 -#define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET 0x1C4 -#define OMAP5430_BGAP_DTEMP_CORE_0_OFFSET 0x208 -#define OMAP5430_BGAP_DTEMP_CORE_1_OFFSET 0x20C -#define OMAP5430_BGAP_DTEMP_CORE_2_OFFSET 0x210 -#define OMAP5430_BGAP_DTEMP_CORE_3_OFFSET 0x214 -#define OMAP5430_BGAP_DTEMP_CORE_4_OFFSET 0x218 - -#define OMAP5430_BGAP_STATUS_OFFSET 0x1C8 - -#define OMAP4460_TSHUT_HOT 900 /* 122 deg C */ -#define OMAP4460_TSHUT_COLD 895 /* 100 deg C */ -#define OMAP4460_T_HOT 800 /* 73 deg C */ -#define OMAP4460_T_COLD 795 /* 71 deg C */ -#define OMAP4460_MAX_FREQ 1500000 -#define OMAP4460_MIN_FREQ 1000000 -#define OMAP4460_MIN_TEMP -40000 -#define OMAP4460_MAX_TEMP 123000 -#define OMAP4460_HYST_VAL 5000 -#define OMAP4460_ADC_START_VALUE 530 -#define OMAP4460_ADC_END_VALUE 932 - -#define OMAP5430_MPU_TSHUT_HOT 915 -#define OMAP5430_MPU_TSHUT_COLD 900 -#define OMAP5430_MPU_T_HOT 800 -#define OMAP5430_MPU_T_COLD 795 -#define OMAP5430_MPU_MAX_FREQ 1500000 -#define OMAP5430_MPU_MIN_FREQ 1000000 -#define OMAP5430_MPU_MIN_TEMP -40000 -#define OMAP5430_MPU_MAX_TEMP 125000 -#define OMAP5430_MPU_HYST_VAL 5000 -#define OMAP5430_ADC_START_VALUE 540 -#define OMAP5430_ADC_END_VALUE 945 - -#define OMAP5430_GPU_TSHUT_HOT 915 -#define OMAP5430_GPU_TSHUT_COLD 900 -#define OMAP5430_GPU_T_HOT 800 -#define OMAP5430_GPU_T_COLD 795 -#define OMAP5430_GPU_MAX_FREQ 1500000 -#define OMAP5430_GPU_MIN_FREQ 1000000 -#define OMAP5430_GPU_MIN_TEMP -40000 -#define OMAP5430_GPU_MAX_TEMP 125000 -#define OMAP5430_GPU_HYST_VAL 5000 - -#define OMAP5430_CORE_TSHUT_HOT 915 -#define OMAP5430_CORE_TSHUT_COLD 900 -#define OMAP5430_CORE_T_HOT 800 -#define OMAP5430_CORE_T_COLD 795 -#define OMAP5430_CORE_MAX_FREQ 1500000 -#define OMAP5430_CORE_MIN_FREQ 1000000 -#define OMAP5430_CORE_MIN_TEMP -40000 -#define OMAP5430_CORE_MAX_TEMP 125000 -#define OMAP5430_CORE_HYST_VAL 5000 - /** * The register offsets and bit fields might change across * OMAP versions hence populating them in this structure. diff --git a/drivers/staging/omap-thermal/omap4-thermal-data.c b/drivers/staging/omap-thermal/omap4-thermal-data.c index 732c853174a2..7ec5570a21e8 100644 --- a/drivers/staging/omap-thermal/omap4-thermal-data.c +++ b/drivers/staging/omap-thermal/omap4-thermal-data.c @@ -18,6 +18,7 @@ #include "omap-thermal.h" #include "omap-bandgap.h" +#include "omap4xxx-bandgap.h" /* * OMAP4430 has one instance of thermal sensor for MPU diff --git a/drivers/staging/omap-thermal/omap4xxx-bandgap.h b/drivers/staging/omap-thermal/omap4xxx-bandgap.h new file mode 100644 index 000000000000..6f2de3a3356d --- /dev/null +++ b/drivers/staging/omap-thermal/omap4xxx-bandgap.h @@ -0,0 +1,175 @@ +/* + * OMAP4xxx bandgap registers, bitfields and temperature definitions + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Contact: + * Eduardo Valentin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#ifndef __OMAP4XXX_BANDGAP_H +#define __OMAP4XXX_BANDGAP_H + +/** + * *** OMAP4430 *** + * + * Below, in sequence, are the Register definitions, + * the bitfields and the temperature definitions for OMAP4430. + */ + +/** + * OMAP4430 register definitions + * + * Registers are defined as offsets. The offsets are + * relative to FUSE_OPP_BGAP on 4430. + */ + +/* OMAP4430.FUSE_OPP_BGAP */ +#define OMAP4430_FUSE_OPP_BGAP 0x0 + +/* OMAP4430.TEMP_SENSOR */ +#define OMAP4430_TEMP_SENSOR_CTRL_OFFSET 0xCC + +/** + * Register and bit definitions for OMAP4430 + * + * All the macros bellow define the required bits for + * controlling temperature on OMAP4430. Bit defines are + * grouped by register. + */ + +/* OMAP4430.TEMP_SENSOR bits */ +#define OMAP4430_BGAP_TEMPSOFF_MASK BIT(12) +#define OMAP4430_BGAP_TSHUT_MASK BIT(11) +#define OMAP4430_SINGLE_MODE_MASK BIT(10) +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK BIT(9) +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(8) +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) + +/** + * Temperature limits and thresholds for OMAP4430 + * + * All the macros bellow are definitions for handling the + * ADC conversions and representation of temperature limits + * and thresholds for OMAP4430. + */ + +/* ADC conversion table limits */ +#define OMAP4430_ADC_START_VALUE 0 +#define OMAP4430_ADC_END_VALUE 127 +/* bandgap clock limits (no control on 4430) */ +#define OMAP4430_MAX_FREQ 32768 +#define OMAP4430_MIN_FREQ 32768 +/* sensor limits */ +#define OMAP4430_MIN_TEMP -40000 +#define OMAP4430_MAX_TEMP 125000 +#define OMAP4430_HYST_VAL 5000 + +/** + * *** OMAP4460 *** Applicable for OMAP4470 + * + * Below, in sequence, are the Register definitions, + * the bitfields and the temperature definitions for OMAP4460. + */ + +/** + * OMAP4460 register definitions + * + * Registers are defined as offsets. The offsets are + * relative to FUSE_OPP_BGAP on 4460. + */ + +/* OMAP4460.FUSE_OPP_BGAP */ +#define OMAP4460_FUSE_OPP_BGAP 0x0 + +/* OMAP4460.TEMP_SENSOR */ +#define OMAP4460_TEMP_SENSOR_CTRL_OFFSET 0xCC + +/* OMAP4460.BANDGAP_CTRL */ +#define OMAP4460_BGAP_CTRL_OFFSET 0x118 + +/* OMAP4460.BANDGAP_COUNTER */ +#define OMAP4460_BGAP_COUNTER_OFFSET 0x11C + +/* OMAP4460.BANDGAP_THRESHOLD */ +#define OMAP4460_BGAP_THRESHOLD_OFFSET 0x120 + +/* OMAP4460.TSHUT_THRESHOLD */ +#define OMAP4460_BGAP_TSHUT_OFFSET 0x124 + +/* OMAP4460.BANDGAP_STATUS */ +#define OMAP4460_BGAP_STATUS_OFFSET 0x128 + +/** + * Register bitfields for OMAP4460 + * + * All the macros bellow define the required bits for + * controlling temperature on OMAP4460. Bit defines are + * grouped by register. + */ +/* OMAP4460.TEMP_SENSOR bits */ +#define OMAP4460_BGAP_TEMPSOFF_MASK BIT(13) +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK BIT(11) +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) + +/* OMAP4460.BANDGAP_CTRL bits */ +#define OMAP4460_SINGLE_MODE_MASK BIT(31) +#define OMAP4460_MASK_HOT_MASK BIT(1) +#define OMAP4460_MASK_COLD_MASK BIT(0) + +/* OMAP4460.BANDGAP_COUNTER bits */ +#define OMAP4460_COUNTER_MASK (0xffffff << 0) + +/* OMAP4460.BANDGAP_THRESHOLD bits */ +#define OMAP4460_T_HOT_MASK (0x3ff << 16) +#define OMAP4460_T_COLD_MASK (0x3ff << 0) + +/* OMAP4460.TSHUT_THRESHOLD bits */ +#define OMAP4460_TSHUT_HOT_MASK (0x3ff << 16) +#define OMAP4460_TSHUT_COLD_MASK (0x3ff << 0) + +/* OMAP4460.BANDGAP_STATUS bits */ +#define OMAP4460_CLEAN_STOP_MASK BIT(3) +#define OMAP4460_BGAP_ALERT_MASK BIT(2) +#define OMAP4460_HOT_FLAG_MASK BIT(1) +#define OMAP4460_COLD_FLAG_MASK BIT(0) + +/** + * Temperature limits and thresholds for OMAP4460 + * + * All the macros bellow are definitions for handling the + * ADC conversions and representation of temperature limits + * and thresholds for OMAP4460. + */ + +/* ADC conversion table limits */ +#define OMAP4460_ADC_START_VALUE 530 +#define OMAP4460_ADC_END_VALUE 932 +/* bandgap clock limits */ +#define OMAP4460_MAX_FREQ 1500000 +#define OMAP4460_MIN_FREQ 1000000 +/* sensor limits */ +#define OMAP4460_MIN_TEMP -40000 +#define OMAP4460_MAX_TEMP 123000 +#define OMAP4460_HYST_VAL 5000 +/* interrupts thresholds */ +#define OMAP4460_TSHUT_HOT 900 /* 122 deg C */ +#define OMAP4460_TSHUT_COLD 895 /* 100 deg C */ +#define OMAP4460_T_HOT 800 /* 73 deg C */ +#define OMAP4460_T_COLD 795 /* 71 deg C */ + +#endif /* __OMAP4XXX_BANDGAP_H */ diff --git a/drivers/staging/omap-thermal/omap5-thermal-data.c b/drivers/staging/omap-thermal/omap5-thermal-data.c index b20db0c65318..3d10704ce2eb 100644 --- a/drivers/staging/omap-thermal/omap5-thermal-data.c +++ b/drivers/staging/omap-thermal/omap5-thermal-data.c @@ -17,6 +17,7 @@ */ #include "omap-bandgap.h" +#include "omap5xxx-bandgap.h" #include "omap-thermal.h" /* diff --git a/drivers/staging/omap-thermal/omap5xxx-bandgap.h b/drivers/staging/omap-thermal/omap5xxx-bandgap.h new file mode 100644 index 000000000000..8824db4391c4 --- /dev/null +++ b/drivers/staging/omap-thermal/omap5xxx-bandgap.h @@ -0,0 +1,199 @@ +/* + * OMAP5xxx bandgap registers, bitfields and temperature definitions + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Contact: + * Eduardo Valentin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#ifndef __OMAP5XXX_BANDGAP_H +#define __OMAP5XXX_BANDGAP_H + +/** + * *** OMAP5430 *** + * + * Below, in sequence, are the Register definitions, + * the bitfields and the temperature definitions for OMAP5430. + */ + +/** + * OMAP5430 register definitions + * + * Registers are defined as offsets. The offsets are + * relative to FUSE_OPP_BGAP_GPU on 5430. + * + * Register below are grouped by domain (not necessarily in offset order) + */ + +/* OMAP5430.GPU register offsets */ +#define OMAP5430_FUSE_OPP_BGAP_GPU 0x0 +#define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x150 +#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x1A8 +#define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x1B4 +#define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET 0x1C0 +#define OMAP5430_BGAP_DTEMP_GPU_0_OFFSET 0x1F4 +#define OMAP5430_BGAP_DTEMP_GPU_1_OFFSET 0x1F8 +#define OMAP5430_BGAP_DTEMP_GPU_2_OFFSET 0x1FC +#define OMAP5430_BGAP_DTEMP_GPU_3_OFFSET 0x200 +#define OMAP5430_BGAP_DTEMP_GPU_4_OFFSET 0x204 + +/* OMAP5430.MPU register offsets */ +#define OMAP5430_FUSE_OPP_BGAP_MPU 0x4 +#define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x14C +#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x1A4 +#define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x1B0 +#define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET 0x1BC +#define OMAP5430_BGAP_DTEMP_MPU_0_OFFSET 0x1E0 +#define OMAP5430_BGAP_DTEMP_MPU_1_OFFSET 0x1E4 +#define OMAP5430_BGAP_DTEMP_MPU_2_OFFSET 0x1E8 +#define OMAP5430_BGAP_DTEMP_MPU_3_OFFSET 0x1EC +#define OMAP5430_BGAP_DTEMP_MPU_4_OFFSET 0x1F0 + +/* OMAP5430.MPU register offsets */ +#define OMAP5430_FUSE_OPP_BGAP_CORE 0x8 +#define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x154 +#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x1AC +#define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x1B8 +#define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET 0x1C4 +#define OMAP5430_BGAP_DTEMP_CORE_0_OFFSET 0x208 +#define OMAP5430_BGAP_DTEMP_CORE_1_OFFSET 0x20C +#define OMAP5430_BGAP_DTEMP_CORE_2_OFFSET 0x210 +#define OMAP5430_BGAP_DTEMP_CORE_3_OFFSET 0x214 +#define OMAP5430_BGAP_DTEMP_CORE_4_OFFSET 0x218 + +/* OMAP5430.common register offsets */ +#define OMAP5430_BGAP_CTRL_OFFSET 0x1A0 +#define OMAP5430_BGAP_STATUS_OFFSET 0x1C8 + +/** + * Register bitfields for OMAP5430 + * + * All the macros bellow define the required bits for + * controlling temperature on OMAP5430. Bit defines are + * grouped by register. + */ + +/* OMAP5430.TEMP_SENSOR */ +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK BIT(12) +#define OMAP5430_BGAP_TEMPSOFF_MASK BIT(11) +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK BIT(10) +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) + +/* OMAP5430.BANDGAP_CTRL */ +#define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30) +#define OMAP5430_MASK_FREEZE_CORE_MASK BIT(23) +#define OMAP5430_MASK_FREEZE_GPU_MASK BIT(22) +#define OMAP5430_MASK_FREEZE_MPU_MASK BIT(21) +#define OMAP5430_MASK_CLEAR_CORE_MASK BIT(20) +#define OMAP5430_MASK_CLEAR_GPU_MASK BIT(19) +#define OMAP5430_MASK_CLEAR_MPU_MASK BIT(18) +#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK BIT(17) +#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK BIT(16) +#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK BIT(15) +#define OMAP5430_MASK_HOT_CORE_MASK BIT(5) +#define OMAP5430_MASK_COLD_CORE_MASK BIT(4) +#define OMAP5430_MASK_HOT_GPU_MASK BIT(3) +#define OMAP5430_MASK_COLD_GPU_MASK BIT(2) +#define OMAP5430_MASK_HOT_MPU_MASK BIT(1) +#define OMAP5430_MASK_COLD_MPU_MASK BIT(0) + +/* OMAP5430.BANDGAP_COUNTER */ +#define OMAP5430_COUNTER_MASK (0xffffff << 0) + +/* OMAP5430.BANDGAP_THRESHOLD */ +#define OMAP5430_T_HOT_MASK (0x3ff << 16) +#define OMAP5430_T_COLD_MASK (0x3ff << 0) + +/* OMAP5430.TSHUT_THRESHOLD */ +#define OMAP5430_TSHUT_HOT_MASK (0x3ff << 16) +#define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0) + +/* OMAP5430.BANDGAP_CUMUL_DTEMP_MPU */ +#define OMAP5430_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0) + +/* OMAP5430.BANDGAP_CUMUL_DTEMP_GPU */ +#define OMAP5430_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0) + +/* OMAP5430.BANDGAP_CUMUL_DTEMP_CORE */ +#define OMAP5430_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0) + +/* OMAP5430.BANDGAP_STATUS */ +#define OMAP5430_BGAP_ALERT_MASK BIT(31) +#define OMAP5430_HOT_CORE_FLAG_MASK BIT(5) +#define OMAP5430_COLD_CORE_FLAG_MASK BIT(4) +#define OMAP5430_HOT_GPU_FLAG_MASK BIT(3) +#define OMAP5430_COLD_GPU_FLAG_MASK BIT(2) +#define OMAP5430_HOT_MPU_FLAG_MASK BIT(1) +#define OMAP5430_COLD_MPU_FLAG_MASK BIT(0) + +/** + * Temperature limits and thresholds for OMAP5430 + * + * All the macros bellow are definitions for handling the + * ADC conversions and representation of temperature limits + * and thresholds for OMAP5430. Definitions are grouped + * by temperature domain. + */ + +/* OMAP5430.common temperature definitions */ +/* ADC conversion table limits */ +#define OMAP5430_ADC_START_VALUE 540 +#define OMAP5430_ADC_END_VALUE 945 + +/* OMAP5430.GPU temperature definitions */ +/* bandgap clock limits */ +#define OMAP5430_GPU_MAX_FREQ 1500000 +#define OMAP5430_GPU_MIN_FREQ 1000000 +/* sensor limits */ +#define OMAP5430_GPU_MIN_TEMP -40000 +#define OMAP5430_GPU_MAX_TEMP 125000 +#define OMAP5430_GPU_HYST_VAL 5000 +/* interrupts thresholds */ +#define OMAP5430_GPU_TSHUT_HOT 915 +#define OMAP5430_GPU_TSHUT_COLD 900 +#define OMAP5430_GPU_T_HOT 800 +#define OMAP5430_GPU_T_COLD 795 + +/* OMAP5430.MPU temperature definitions */ +/* bandgap clock limits */ +#define OMAP5430_MPU_MAX_FREQ 1500000 +#define OMAP5430_MPU_MIN_FREQ 1000000 +/* sensor limits */ +#define OMAP5430_MPU_MIN_TEMP -40000 +#define OMAP5430_MPU_MAX_TEMP 125000 +#define OMAP5430_MPU_HYST_VAL 5000 +/* interrupts thresholds */ +#define OMAP5430_MPU_TSHUT_HOT 915 +#define OMAP5430_MPU_TSHUT_COLD 900 +#define OMAP5430_MPU_T_HOT 800 +#define OMAP5430_MPU_T_COLD 795 + +/* OMAP5430.CORE temperature definitions */ +/* bandgap clock limits */ +#define OMAP5430_CORE_MAX_FREQ 1500000 +#define OMAP5430_CORE_MIN_FREQ 1000000 +/* sensor limits */ +#define OMAP5430_CORE_MIN_TEMP -40000 +#define OMAP5430_CORE_MAX_TEMP 125000 +#define OMAP5430_CORE_HYST_VAL 5000 +/* interrupts thresholds */ +#define OMAP5430_CORE_TSHUT_HOT 915 +#define OMAP5430_CORE_TSHUT_COLD 900 +#define OMAP5430_CORE_T_HOT 800 +#define OMAP5430_CORE_T_COLD 795 + +#endif /* __OMAP5XXX_BANDGAP_H */ -- cgit From 0c00477daee106502d89f9e724aee8bf405a81b8 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:52 -0400 Subject: staging: omap-thermal: update documentation of omap-bandgap.h This patch updates the existing data structures for omap bandgap, inside omap-bandgap.h. TODO: remove unused fields. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 230 +++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 7d5ac3fa91c5..28d9104369cc 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -28,24 +28,101 @@ #include /** - * The register offsets and bit fields might change across - * OMAP versions hence populating them in this structure. + * DOC: bandgap driver data structure + * ================================== + * +---------------------+ +-----------------+ + * | struct omap_bandgap |-->| struct device * | + * +----------+----------+ +-----------------+ + * | + * | + * V + * +--------------------------+ + * | struct omap_bandgap_data | + * +--------------------------+ + * | + * | + * * (Array of) + * +------------+------------------------------------------------------+ + * | +----------+--------------+ +-------------------------+ | + * | | struct omap_temp_sensor |-->| struct temp_sensor_data | | + * | +-------------------------+ +------------+------------+ | + * | | | + * | +--------------------------+ | + * | V V | + * | +----------+- --------------+ +----+-------------------------+ | + * | | struct temp_sensor_regval | | struct temp_sensor_registers | | + * | +---------------------------+ +------------------------------+ | + * | | + * +-------------------------------------------------------------------+ + * + * Above is a simple diagram describing how the data structure below + * are organized. For each bandgap device there should be a omap_bandgap_data + * containing the device instance configuration, as well as, an array of + * sensors, representing every sensor instance present in this bandgap. + */ + +/** + * struct temp_sensor_registers - descriptor to access registers and bitfields + * @temp_sensor_ctrl: TEMP_SENSOR_CTRL register offset + * @bgap_tempsoff_mask: mask to temp_sensor_ctrl.tempsoff + * @bgap_soc_mask: mask to temp_sensor_ctrl.soc + * @bgap_eocz_mask: mask to temp_sensor_ctrl.eocz + * @bgap_dtemp_mask: mask to temp_sensor_ctrl.dtemp + * @bgap_mask_ctrl: BANDGAP_MASK_CTRL register offset + * @mask_hot_mask: mask to bandgap_mask_ctrl.mask_hot + * @mask_cold_mask: mask to bandgap_mask_ctrl.mask_cold + * @mask_sidlemode_mask: mask to bandgap_mask_ctrl.mask_sidlemode + * @mask_freeze_mask: mask to bandgap_mask_ctrl.mask_free + * @mask_clear_mask: mask to bandgap_mask_ctrl.mask_clear + * @mask_clear_accum_mask: mask to bandgap_mask_ctrl.mask_clear_accum + * @bgap_mode_ctrl: BANDGAP_MODE_CTRL register offset + * @mode_ctrl_mask: mask to bandgap_mode_ctrl.mode_ctrl + * @bgap_counter: BANDGAP_COUNTER register offset + * @counter_mask: mask to bandgap_counter.counter + * @bgap_threshold: BANDGAP_THRESHOLD register offset (TALERT thresholds) + * @threshold_thot_mask: mask to bandgap_threhold.thot + * @threshold_tcold_mask: mask to bandgap_threhold.tcold + * @tshut_threshold: TSHUT_THRESHOLD register offset (TSHUT thresholds) + * @tshut_efuse_mask: mask to tshut_threshold.tshut_efuse + * @tshut_efuse_shift: shift to tshut_threshold.tshut_efuse + * @tshut_hot_mask: mask to tshut_threhold.thot + * @tshut_cold_mask: mask to tshut_threhold.thot + * @bgap_status: BANDGAP_STATUS register offset + * @status_clean_stop_mask: mask to bandgap_status.clean_stop + * @status_bgap_alert_mask: mask to bandgap_status.bandgap_alert + * @status_hot_mask: mask to bandgap_status.hot + * @status_cold_mask: mask to bandgap_status.cold + * @bgap_cumul_dtemp: BANDGAP_CUMUL_DTEMP register offset + * @ctrl_dtemp_0: CTRL_DTEMP0 register offset + * @ctrl_dtemp_1: CTRL_DTEMP1 register offset + * @ctrl_dtemp_2: CTRL_DTEMP2 register offset + * @ctrl_dtemp_3: CTRL_DTEMP3 register offset + * @ctrl_dtemp_4: CTRL_DTEMP4 register offset + * @bgap_efuse: BANDGAP_EFUSE register offset + * + * The register offsets and bitfields might change across + * OMAP and variants versions. Hence this struct serves as a + * descriptor map on how to access the registers and the bitfields. + * + * This descriptor contains registers of all versions of bandgap chips. + * Not all versions will use all registers, depending on the available + * features. Please read TRMs for descriptive explanation on each bitfield. */ struct temp_sensor_registers { u32 temp_sensor_ctrl; u32 bgap_tempsoff_mask; u32 bgap_soc_mask; - u32 bgap_eocz_mask; + u32 bgap_eocz_mask; /* not used: but needs revisit */ u32 bgap_dtemp_mask; u32 bgap_mask_ctrl; u32 mask_hot_mask; u32 mask_cold_mask; - u32 mask_sidlemode_mask; + u32 mask_sidlemode_mask; /* not used: but may be needed for pm */ u32 mask_freeze_mask; - u32 mask_clear_mask; - u32 mask_clear_accum_mask; + u32 mask_clear_mask; /* not used: but needed for trending */ + u32 mask_clear_accum_mask; /* not used: but needed for trending */ u32 bgap_mode_ctrl; u32 mode_ctrl_mask; @@ -58,28 +135,45 @@ struct temp_sensor_registers { u32 threshold_tcold_mask; u32 tshut_threshold; - u32 tshut_efuse_mask; - u32 tshut_efuse_shift; + u32 tshut_efuse_mask; /* not used */ + u32 tshut_efuse_shift; /* not used */ u32 tshut_hot_mask; u32 tshut_cold_mask; u32 bgap_status; - u32 status_clean_stop_mask; - u32 status_bgap_alert_mask; + u32 status_clean_stop_mask; /* not used: but needed for trending */ + u32 status_bgap_alert_mask; /* not used */ u32 status_hot_mask; u32 status_cold_mask; - u32 bgap_cumul_dtemp; - u32 ctrl_dtemp_0; - u32 ctrl_dtemp_1; - u32 ctrl_dtemp_2; - u32 ctrl_dtemp_3; - u32 ctrl_dtemp_4; + u32 bgap_cumul_dtemp; /* not used: but needed for trending */ + u32 ctrl_dtemp_0; /* not used: but needed for trending */ + u32 ctrl_dtemp_1; /* not used: but needed for trending */ + u32 ctrl_dtemp_2; /* not used: but needed for trending */ + u32 ctrl_dtemp_3; /* not used: but needed for trending */ + u32 ctrl_dtemp_4; /* not used: but needed for trending */ u32 bgap_efuse; }; /** - * The thresholds and limits for temperature sensors. + * struct temp_sensor_data - The thresholds and limits for temperature sensors. + * @tshut_hot: temperature to trigger a thermal reset (initial value) + * @tshut_cold: temp to get the plat out of reset due to thermal (init val) + * @t_hot: temperature to trigger a thermal alert (high initial value) + * @t_cold: temperature to trigger a thermal alert (low initial value) + * @min_freq: sensor minimum clock rate + * @max_freq: sensor maximum clock rate + * @max_temp: sensor maximum temperature + * @min_temp: sensor minimum temperature + * @hyst_val: temperature hysteresis considered while converting ADC values + * @adc_start_val: ADC conversion table starting value + * @adc_end_val: ADC conversion table ending value + * @update_int1: update interval + * @update_int2: update interval + * + * This data structure will hold the required thresholds and temperature limits + * for a specific temperature sensor, like shutdown temperature, alert + * temperature, clock / rate used, ADC conversion limits and update intervals */ struct temp_sensor_data { u32 tshut_hot; @@ -93,23 +187,27 @@ struct temp_sensor_data { int hyst_val; u32 adc_start_val; u32 adc_end_val; - u32 update_int1; - u32 update_int2; + u32 update_int1; /* not used */ + u32 update_int2; /* not used */ }; struct omap_bandgap_data; /** * struct omap_bandgap - bandgap device structure - * @dev: device pointer - * @conf: platform data with sensor data + * @dev: struct device pointer + * @base: io memory base address + * @conf: struct with bandgap configuration set (# sensors, conv_table, etc) * @fclock: pointer to functional clock of temperature sensor - * @div_clk: pointer to parent clock of temperature sensor fclk - * @conv_table: Pointer to adc to temperature conversion table - * @bg_mutex: Mutex for sysfs, irq and PM - * @irq: MPU Irq number for thermal alert + * @div_clk: pointer to divider clock of temperature sensor fclk + * @bg_mutex: mutex for omap_bandgap structure + * @irq: MPU IRQ number for thermal alert * @tshut_gpio: GPIO where Tshut signal is routed * @clk_rate: Holds current clock rate + * + * The bandgap device structure representing the bandgap device instance. + * It holds most of the dynamic stuff. Configurations and sensor specific + * entries are inside the @conf structure. */ struct omap_bandgap { struct device *dev; @@ -117,7 +215,7 @@ struct omap_bandgap { struct omap_bandgap_data *conf; struct clk *fclock; struct clk *div_clk; - struct mutex bg_mutex; /* Mutex for irq and PM */ + struct mutex bg_mutex; /* shields this struct */ int irq; int tshut_gpio; u32 clk_rate; @@ -130,6 +228,9 @@ struct omap_bandgap { * @bg_counter: bandgap counter value * @bg_threshold: bandgap threshold register value * @tshut_threshold: bandgap tshut register value + * + * Data structure to save and restore bandgap register set context. Only + * required registers are shadowed, when needed. */ struct temp_sensor_regval { u32 bg_mode_ctrl; @@ -140,21 +241,26 @@ struct temp_sensor_regval { }; /** - * struct omap_temp_sensor - bandgap temperature sensor platform data + * struct omap_temp_sensor - bandgap temperature sensor configuration data * @ts_data: pointer to struct with thresholds, limits of temperature sensor * @registers: pointer to the list of register offsets and bitfields * @regval: temperature sensor register values * @domain: the name of the domain where the sensor is located - * @cooling_data: description on how the zone should be cooled off. - * @slope: sensor gradient slope info for hotspot extrapolation - * @const: sensor gradient const info for hotspot extrapolation - * @slope_pcb: sensor gradient slope info for hotspot extrapolation + * @slope: sensor gradient slope info for hotspot extrapolation equation + * @const: sensor gradient const info for hotspot extrapolation equation + * @slope_pcb: sensor gradient slope info for hotspot extrapolation equation * with no external influence - * @const_pcb: sensor gradient const info for hotspot extrapolation + * @constant_pcb: sensor gradient const info for hotspot extrapolation equation * with no external influence * @data: private data * @register_cooling: function to describe how this sensor is going to be cooled * @unregister_cooling: function to release cooling data + * + * Data structure to describe a temperature sensor handled by a bandgap device. + * It should provide configuration details on this sensor, such as how to + * access the registers affecting this sensor, shadow register buffer, how to + * assess the gradient from hotspot, how to cooldown the domain when sensor + * reports too hot temperature. */ struct omap_temp_sensor { struct temp_sensor_data *ts_data; @@ -172,16 +278,38 @@ struct omap_temp_sensor { }; /** - * struct omap_bandgap_data - bandgap platform data structure - * @features: a bitwise flag set to describe the device features - * @conv_table: Pointer to adc to temperature conversion table - * @fclock_name: clock name of the functional clock - * @div_ck_nme: clock name of the clock divisor - * @sensor_count: count of temperature sensor device in scm - * @sensors: array of sensors present in this bandgap instance - * @expose_sensor: callback to export sensor to thermal API + * DOC: omap bandgap feature types + * + * OMAP_BANDGAP_FEATURE_TSHUT - used when the thermal shutdown signal output + * of a bandgap device instance is routed to the processor. This means + * the system must react and perform the shutdown by itself (handle an + * IRQ, for instance). + * + * OMAP_BANDGAP_FEATURE_TSHUT_CONFIG - used when the bandgap device has control + * over the thermal shutdown configuration. This means that the thermal + * shutdown thresholds are programmable, for instance. + * + * OMAP_BANDGAP_FEATURE_TALERT - used when the bandgap device instance outputs + * a signal representing violation of programmable alert thresholds. + * + * OMAP_BANDGAP_FEATURE_MODE_CONFIG - used when it is possible to choose which + * mode, continuous or one shot, the bandgap device instance will operate. + * + * OMAP_BANDGAP_FEATURE_COUNTER - used when the bandgap device instance allows + * programming the update interval of its internal state machine. + * + * OMAP_BANDGAP_FEATURE_POWER_SWITCH - used when the bandgap device allows + * itself to be switched on/off. + * + * OMAP_BANDGAP_FEATURE_CLK_CTRL - used when the clocks feeding the bandgap + * device are gateable or not. + * + * OMAP_BANDGAP_FEATURE_FREEZE_BIT - used when the bandgap device features + * a history buffer that its update can be freezed/unfreezed. + * + * OMAP_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a + * specific feature (above) or not. Return non-zero, if yes. */ -struct omap_bandgap_data { #define OMAP_BANDGAP_FEATURE_TSHUT BIT(0) #define OMAP_BANDGAP_FEATURE_TSHUT_CONFIG BIT(1) #define OMAP_BANDGAP_FEATURE_TALERT BIT(2) @@ -192,6 +320,26 @@ struct omap_bandgap_data { #define OMAP_BANDGAP_FEATURE_FREEZE_BIT BIT(7) #define OMAP_BANDGAP_HAS(b, f) \ ((b)->conf->features & OMAP_BANDGAP_FEATURE_ ## f) + +/** + * struct omap_bandgap_data - omap bandgap data configuration structure + * @features: a bitwise flag set to describe the device features + * @conv_table: Pointer to ADC to temperature conversion table + * @fclock_name: clock name of the functional clock + * @div_ck_name: clock name of the clock divisor + * @sensor_count: count of temperature sensor within this bandgap device + * @report_temperature: callback to report thermal alert to thermal API + * @expose_sensor: callback to export sensor to thermal API + * @remove_sensor: callback to destroy sensor from thermal API + * @sensors: array of sensors present in this bandgap instance + * + * This is a data structure which should hold most of the static configuration + * of a bandgap device instance. It should describe which features this instance + * is capable of, the clock names to feed this device, the amount of sensors and + * their configuration representation, and how to export and unexport them to + * a thermal API. + */ +struct omap_bandgap_data { unsigned int features; const int *conv_table; char *fclock_name; -- cgit From 24796e128182ac6988a04d140134f953560b5083 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:53 -0400 Subject: staging: omap-thermal: style cleanup on omap-bandgap.c simple changes on alignments and white spaces Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index d4a37880f1de..9f2d7cc95016 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -437,7 +437,7 @@ static inline int omap_bandgap_validate(struct omap_bandgap *bg_ptr, int id) * returns 0 on success or the proper error code */ int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, - int *thot) + int *thot) { struct temp_sensor_registers *tsr; u32 temp; @@ -512,7 +512,7 @@ int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val) * returns 0 on success or the proper error code */ int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, - int *tcold) + int *tcold) { struct temp_sensor_registers *tsr; u32 temp; @@ -617,7 +617,7 @@ int omap_bandgap_read_update_interval(struct omap_bandgap *bg_ptr, int id, * returns 0 on success or the proper error code */ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, - int id, u32 interval) + int id, u32 interval) { int ret = omap_bandgap_validate(bg_ptr, id); if (ret) @@ -643,7 +643,7 @@ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, * returns 0 on success or the proper error code */ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, - int *temperature) + int *temperature) { struct temp_sensor_registers *tsr; u32 temp; @@ -677,7 +677,7 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, * returns 0 on success or the proper error code */ int omap_bandgap_set_sensor_data(struct omap_bandgap *bg_ptr, int id, - void *data) + void *data) { int ret = omap_bandgap_validate(bg_ptr, id); if (ret) @@ -762,7 +762,7 @@ static int enable_continuous_mode(struct omap_bandgap *bg_ptr) } static int omap_bandgap_tshut_init(struct omap_bandgap *bg_ptr, - struct platform_device *pdev) + struct platform_device *pdev) { int gpio_nr = bg_ptr->tshut_gpio; int status; @@ -795,7 +795,7 @@ static int omap_bandgap_tshut_init(struct omap_bandgap *bg_ptr, /* Initialization of Talert. Call it only if HAS(TALERT) is set */ static int omap_bandgap_talert_init(struct omap_bandgap *bg_ptr, - struct platform_device *pdev) + struct platform_device *pdev) { int ret; @@ -855,7 +855,7 @@ static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev) bg_ptr->base = chunk; if (IS_ERR(chunk)) return ERR_CAST(chunk); - + i++; } while (res); @@ -1108,9 +1108,8 @@ static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr) val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter); if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) - omap_bandgap_writel(bg_ptr, - rval->tshut_threshold, - tsr->tshut_threshold); + omap_bandgap_writel(bg_ptr, rval->tshut_threshold, + tsr->tshut_threshold); /* Force immediate temperature measurement and update * of the DTEMP field */ @@ -1118,16 +1117,15 @@ static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr) if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) omap_bandgap_writel(bg_ptr, rval->bg_counter, - tsr->bgap_counter); + tsr->bgap_counter); if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl, - tsr->bgap_mode_ctrl); + tsr->bgap_mode_ctrl); if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { - omap_bandgap_writel(bg_ptr, - rval->bg_threshold, - tsr->bgap_threshold); + omap_bandgap_writel(bg_ptr, rval->bg_threshold, + tsr->bgap_threshold); omap_bandgap_writel(bg_ptr, rval->bg_ctrl, - tsr->bgap_mask_ctrl); + tsr->bgap_mask_ctrl); } } -- cgit From 35b052a6c9a4de5eae6fee60663c9b6606651c1a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:54 -0400 Subject: staging: omap-thermal: fix error checking The omap_bandgap_get_sensor_data() function returns ERR_PTR(), but it can also return NULL, in case of initilization, so we need to use IS_ERR_OR_NULL() rather than only IS_ERR(). Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-thermal-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c index 79a55aaae5a3..8aebc6a12c40 100644 --- a/drivers/staging/omap-thermal/omap-thermal-common.c +++ b/drivers/staging/omap-thermal/omap-thermal-common.c @@ -260,7 +260,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id, data = omap_bandgap_get_sensor_data(bg_ptr, id); - if (IS_ERR(data)) + if (IS_ERR_OR_NULL(data)) data = omap_thermal_build_data(bg_ptr, id); if (!data) @@ -309,7 +309,7 @@ int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) struct omap_thermal_data *data; data = omap_bandgap_get_sensor_data(bg_ptr, id); - if (IS_ERR(data)) + if (IS_ERR_OR_NULL(data)) data = omap_thermal_build_data(bg_ptr, id); if (!data) -- cgit From d3c291ab802fe8d7c467eddfa1029fa6fc663434 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:55 -0400 Subject: staging: omap-thermal: introduce RMW_BITS macro This patch introduce a macro to read, update, write bitfields. It will be specific to bandgap data structures. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 178 +++++++--------------------- 1 file changed, 46 insertions(+), 132 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 9f2d7cc95016..1c1b905c32f9 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -52,25 +52,29 @@ static void omap_bandgap_writel(struct omap_bandgap *bg_ptr, u32 val, u32 reg) writel(val, bg_ptr->base + reg); } +/* update bits, value will be shifted */ +#define RMW_BITS(bg_ptr, id, reg, mask, val) \ +do { \ + struct temp_sensor_registers *t; \ + u32 r; \ + \ + t = bg_ptr->conf->sensors[(id)].registers; \ + r = omap_bandgap_readl(bg_ptr, t->reg); \ + r &= ~t->mask; \ + r |= (val) << __ffs(t->mask); \ + omap_bandgap_writel(bg_ptr, r, t->reg); \ +} while (0) + static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) { - struct temp_sensor_registers *tsr; int i; - u32 ctrl; if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH)) return 0; - for (i = 0; i < bg_ptr->conf->sensor_count; i++) { - tsr = bg_ptr->conf->sensors[i].registers; - ctrl = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - ctrl &= ~tsr->bgap_tempsoff_mask; + for (i = 0; i < bg_ptr->conf->sensor_count; i++) /* active on 0 */ - ctrl |= !on << __ffs(tsr->bgap_tempsoff_mask); - - /* write BGAP_TEMPSOFF should be reset to 0 */ - omap_bandgap_writel(bg_ptr, ctrl, tsr->temp_sensor_ctrl); - } + RMW_BITS(bg_ptr, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on); return 0; } @@ -78,15 +82,13 @@ static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) { struct temp_sensor_registers *tsr; - u32 temp, ctrl, reg; + u32 temp, reg; tsr = bg_ptr->conf->sensors[id].registers; reg = tsr->temp_sensor_ctrl; if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) { - ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); - ctrl |= tsr->mask_freeze_mask; - omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl); + RMW_BITS(bg_ptr, id, bgap_mask_ctrl, mask_freeze_mask, 1); /* * In case we cannot read from cur_dtemp / dtemp_0, * then we read from the last valid temp read @@ -98,11 +100,8 @@ static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) temp = omap_bandgap_readl(bg_ptr, reg); temp &= tsr->bgap_dtemp_mask; - if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) { - ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); - ctrl &= ~tsr->mask_freeze_mask; - omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl); - } + if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) + RMW_BITS(bg_ptr, id, bgap_mask_ctrl, mask_freeze_mask, 0); return temp; } @@ -290,37 +289,6 @@ int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) return temp_sensor_unmask_interrupts(bg_ptr, id, t_hot, cold); } -/* Talert Thot and Tcold thresholds. Call it only if HAS(TALERT) is set */ -static -int temp_sensor_init_talert_thresholds(struct omap_bandgap *bg_ptr, int id, - int t_hot, int t_cold) -{ - struct temp_sensor_registers *tsr; - u32 reg_val, thresh_val; - - tsr = bg_ptr->conf->sensors[id].registers; - thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - - /* write the new t_cold value */ - reg_val = thresh_val & ~tsr->threshold_tcold_mask; - reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask)); - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); - - thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - - /* write the new t_hot value */ - reg_val = thresh_val & ~tsr->threshold_thot_mask; - reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)); - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); - - reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl); - reg_val |= tsr->mask_hot_mask; - reg_val |= tsr->mask_cold_mask; - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl); - - return 0; -} - /* Talert Tcold threshold. Call it only if HAS(TALERT) is set */ static int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, @@ -359,54 +327,6 @@ int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, return temp_sensor_unmask_interrupts(bg_ptr, id, hot, t_cold); } -/* This is Tshut Thot config. Call it only if HAS(TSHUT_CONFIG) is set */ -static int temp_sensor_configure_tshut_hot(struct omap_bandgap *bg_ptr, - int id, int tshut_hot) -{ - struct temp_sensor_registers *tsr; - u32 reg_val; - - tsr = bg_ptr->conf->sensors[id].registers; - reg_val = omap_bandgap_readl(bg_ptr, tsr->tshut_threshold); - reg_val &= ~tsr->tshut_hot_mask; - reg_val |= tshut_hot << __ffs(tsr->tshut_hot_mask); - omap_bandgap_writel(bg_ptr, reg_val, tsr->tshut_threshold); - - return 0; -} - -/* This is Tshut Tcold config. Call it only if HAS(TSHUT_CONFIG) is set */ -static int temp_sensor_configure_tshut_cold(struct omap_bandgap *bg_ptr, - int id, int tshut_cold) -{ - struct temp_sensor_registers *tsr; - u32 reg_val; - - tsr = bg_ptr->conf->sensors[id].registers; - reg_val = omap_bandgap_readl(bg_ptr, tsr->tshut_threshold); - reg_val &= ~tsr->tshut_cold_mask; - reg_val |= tshut_cold << __ffs(tsr->tshut_cold_mask); - omap_bandgap_writel(bg_ptr, reg_val, tsr->tshut_threshold); - - return 0; -} - -/* This is counter config. Call it only if HAS(COUNTER) is set */ -static int configure_temp_sensor_counter(struct omap_bandgap *bg_ptr, int id, - u32 counter) -{ - struct temp_sensor_registers *tsr; - u32 val; - - tsr = bg_ptr->conf->sensors[id].registers; - val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter); - val &= ~tsr->counter_mask; - val |= counter << __ffs(tsr->counter_mask); - omap_bandgap_writel(bg_ptr, val, tsr->bgap_counter); - - return 0; -} - #define bandgap_is_valid(b) \ (!IS_ERR_OR_NULL(b)) #define bandgap_is_valid_sensor_id(b, i) \ @@ -628,7 +548,7 @@ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, interval = interval * bg_ptr->clk_rate / 1000; mutex_lock(&bg_ptr->bg_mutex); - configure_temp_sensor_counter(bg_ptr, id, interval); + RMW_BITS(bg_ptr, id, bgap_counter, counter_mask, interval); mutex_unlock(&bg_ptr->bg_mutex); return 0; @@ -645,7 +565,6 @@ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, int *temperature) { - struct temp_sensor_registers *tsr; u32 temp; int ret; @@ -653,7 +572,6 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, if (ret) return ret; - tsr = bg_ptr->conf->sensors[id].registers; mutex_lock(&bg_ptr->bg_mutex); temp = omap_bandgap_read_temp(bg_ptr, id); mutex_unlock(&bg_ptr->bg_mutex); @@ -708,31 +626,23 @@ void *omap_bandgap_get_sensor_data(struct omap_bandgap *bg_ptr, int id) static int omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) { - struct temp_sensor_registers *tsr; u32 temp = 0, counter = 1000; - tsr = bg_ptr->conf->sensors[id].registers; /* Select single conversion mode */ - if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) { - temp = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl); - temp &= ~(1 << __ffs(tsr->mode_ctrl_mask)); - omap_bandgap_writel(bg_ptr, temp, tsr->bgap_mode_ctrl); - } + if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) + RMW_BITS(bg_ptr, id, bgap_mode_ctrl, mode_ctrl_mask, 0); /* Start of Conversion = 1 */ - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp |= 1 << __ffs(tsr->bgap_soc_mask); - omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl); + RMW_BITS(bg_ptr, id, temp_sensor_ctrl, bgap_soc_mask, 1); /* Wait until DTEMP is updated */ temp = omap_bandgap_read_temp(bg_ptr, id); while ((temp == 0) && --counter) temp = omap_bandgap_read_temp(bg_ptr, id); + /* REVISIT: Check correct condition for end of conversion */ /* Start of Conversion = 0 */ - temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); - temp &= ~(1 << __ffs(tsr->bgap_soc_mask)); - omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl); + RMW_BITS(bg_ptr, id, temp_sensor_ctrl, bgap_soc_mask, 0); return 0; } @@ -745,17 +655,12 @@ omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) */ static int enable_continuous_mode(struct omap_bandgap *bg_ptr) { - struct temp_sensor_registers *tsr; int i; - u32 val; for (i = 0; i < bg_ptr->conf->sensor_count; i++) { /* Perform a single read just before enabling continuous */ omap_bandgap_force_single_read(bg_ptr, i); - tsr = bg_ptr->conf->sensors[i].registers; - val = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl); - val |= 1 << __ffs(tsr->mode_ctrl_mask); - omap_bandgap_writel(bg_ptr, val, tsr->bgap_mode_ctrl); + RMW_BITS(bg_ptr, i, bgap_mode_ctrl, mode_ctrl_mask, 1); } return 0; @@ -955,22 +860,31 @@ int omap_bandgap_probe(struct platform_device *pdev) /* Set default counter to 1 for now */ if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) for (i = 0; i < bg_ptr->conf->sensor_count; i++) - configure_temp_sensor_counter(bg_ptr, i, 1); + RMW_BITS(bg_ptr, i, bgap_counter, counter_mask, 1); + /* Set default thresholds for alert and shutdown */ for (i = 0; i < bg_ptr->conf->sensor_count; i++) { struct temp_sensor_data *ts_data; ts_data = bg_ptr->conf->sensors[i].ts_data; - if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) - temp_sensor_init_talert_thresholds(bg_ptr, i, - ts_data->t_hot, - ts_data->t_cold); + if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { + /* Set initial Talert thresholds */ + RMW_BITS(bg_ptr, i, bgap_threshold, + threshold_tcold_mask, ts_data->t_cold); + RMW_BITS(bg_ptr, i, bgap_threshold, + threshold_thot_mask, ts_data->t_hot); + /* Enable the alert events */ + RMW_BITS(bg_ptr, i, bgap_mask_ctrl, mask_hot_mask, 1); + RMW_BITS(bg_ptr, i, bgap_mask_ctrl, mask_cold_mask, 1); + } + if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) { - temp_sensor_configure_tshut_hot(bg_ptr, i, - ts_data->tshut_hot); - temp_sensor_configure_tshut_cold(bg_ptr, i, - ts_data->tshut_cold); + /* Set initial Tshut thresholds */ + RMW_BITS(bg_ptr, i, tshut_threshold, + tshut_hot_mask, ts_data->tshut_hot); + RMW_BITS(bg_ptr, i, tshut_threshold, + tshut_cold_mask, ts_data->tshut_cold); } } @@ -980,8 +894,8 @@ int omap_bandgap_probe(struct platform_device *pdev) /* Set .250 seconds time as default counter */ if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) for (i = 0; i < bg_ptr->conf->sensor_count; i++) - configure_temp_sensor_counter(bg_ptr, i, - bg_ptr->clk_rate / 4); + RMW_BITS(bg_ptr, i, bgap_counter, counter_mask, + bg_ptr->clk_rate / 4); /* Every thing is good? Then expose the sensors */ for (i = 0; i < bg_ptr->conf->sensor_count; i++) { -- cgit From 9c468aa2d5a376d4b3a1b5aac867f75c0754abed Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:56 -0400 Subject: staging: omap-thermal: add documentation for register access functions Document the helper functions that manipulates registers and their bitfields. All of them work based of the io mapped area. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 1c1b905c32f9..a8d63a26beb5 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -42,17 +42,38 @@ #include "omap-bandgap.h" +/** + * omap_bandgap_readl() - simple read helper function + * @bg_ptr: pointer to omap_bandgap structure + * @reg: desired register (offset) to be read + * + * Helper function to read bandgap registers. It uses the io remapped area. + * Returns the register value. + */ static u32 omap_bandgap_readl(struct omap_bandgap *bg_ptr, u32 reg) { return readl(bg_ptr->base + reg); } +/** + * omap_bandgap_writel() - simple write helper function + * @bg_ptr: pointer to omap_bandgap structure + * @val: desired register value to be written + * @reg: desired register (offset) to be written + * + * Helper function to write bandgap registers. It uses the io remapped area. + */ static void omap_bandgap_writel(struct omap_bandgap *bg_ptr, u32 val, u32 reg) { writel(val, bg_ptr->base + reg); } -/* update bits, value will be shifted */ +/** + * DOC: macro to update bits. + * + * RMW_BITS() - used to read, modify and update bandgap bitfields. + * The value passed will be shifted. + */ #define RMW_BITS(bg_ptr, id, reg, mask, val) \ do { \ struct temp_sensor_registers *t; \ -- cgit From 3d84e52962f1ec1720bf0d7e84d9e3e4b1e35d16 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:57 -0400 Subject: staging: omap-thermal: make a omap_bandgap_power with only one exit point Change the way the omap_bandgap_power is written so that it has only one exit entry (Documentation/CodingStyle). Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index a8d63a26beb5..ec79ec1cfacc 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -91,12 +91,13 @@ static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) int i; if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH)) - return 0; + goto exit; for (i = 0; i < bg_ptr->conf->sensor_count; i++) /* active on 0 */ RMW_BITS(bg_ptr, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on); +exit: return 0; } -- cgit From 7a556e6a4a8333ea0ddf9cffc9ef42c9a912925d Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:58 -0400 Subject: staging: omap-thermal: add documentation for omap_bandgap_power Document the helper function to turn a bandgap device on and off. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index ec79ec1cfacc..62a5fb9623b2 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -86,6 +86,14 @@ do { \ omap_bandgap_writel(bg_ptr, r, t->reg); \ } while (0) +/** + * omap_bandgap_power() - controls the power state of a bandgap device + * @bg_ptr: pointer to omap_bandgap structure + * @on: desired power state (1 - on, 0 - off) + * + * Used to power on/off a bandgap device instance. Only used on those + * that features tempsoff bit. + */ static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on) { int i; -- cgit From 4a6554ed29906be67082e26ac99cbbca9d2f9060 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 08:59:59 -0400 Subject: staging: omap-thermal: add documentation for omap_bandgap_read_temp Document function which reads temperature register, depending on bandgap device version. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 62a5fb9623b2..02817b54b456 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -109,6 +109,16 @@ exit: return 0; } +/** + * omap_bandgap_read_temp() - helper function to read sensor temperature + * @bg_ptr: pointer to omap_bandgap structure + * @id: bandgap sensor id + * + * Function to concentrate the steps to read sensor temperature register. + * This function is desired because, depending on bandgap device version, + * it might be needed to freeze the bandgap state machine, before fetching + * the register value. + */ static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) { struct temp_sensor_registers *tsr; -- cgit From f230427c47d6e3f56286ebdefd2b5db25581ed5d Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:00 -0400 Subject: staging: omap-thermal: rename talert handler Simple rename to cope with file naming pattern. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 02817b54b456..1906ef19a47c 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -147,7 +147,7 @@ static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) } /* This is the Talert handler. Call it only if HAS(TALERT) is set */ -static irqreturn_t talert_irq_handler(int irq, void *data) +static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) { struct omap_bandgap *bg_ptr = data; struct temp_sensor_registers *tsr; @@ -750,7 +750,7 @@ static int omap_bandgap_talert_init(struct omap_bandgap *bg_ptr, return bg_ptr->irq; } ret = request_threaded_irq(bg_ptr->irq, NULL, - talert_irq_handler, + omap_bandgap_talert_irq_handler, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "talert", bg_ptr); if (ret) { -- cgit From ee07d55abb660726dd93aec4b7f1de36c6e777f0 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:01 -0400 Subject: staging: omap-thermal: update documentation for talert irq handler Document the Talert IRQ handler. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 1906ef19a47c..aa60b7b920dc 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -146,7 +146,17 @@ static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) return temp; } -/* This is the Talert handler. Call it only if HAS(TALERT) is set */ +/** + * omap_bandgap_talert_irq_handler() - handles Temperature alert IRQs + * @irq: IRQ number + * @data: private data (struct omap_bandgap *) + * + * This is the Talert handler. Use it only if bandgap device features + * HAS(TALERT). This handler goes over all sensors and checks their + * conditions and acts accordingly. In case there are events pending, + * it will reset the event mask to wait for the opposite event (next event). + * Every time there is a new event, it will be reported to thermal layer. + */ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) { struct omap_bandgap *bg_ptr = data; -- cgit From 79857cd28ed5f738ef1d548bda797b171ac4ee5d Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:02 -0400 Subject: staging: omap-thermal: update tshut IRQ handler documentation Documents tshut handler better. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index aa60b7b920dc..d0db361d5e29 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -207,7 +207,15 @@ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) return IRQ_HANDLED; } -/* This is the Tshut handler. Call it only if HAS(TSHUT) is set */ +/** + * omap_bandgap_tshut_irq_handler() - handles Temperature shutdown signal + * @irq: IRQ number + * @data: private data (unused) + * + * This is the Tshut handler. Use it only if bandgap device features + * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown + * the system. + */ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) { pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n", -- cgit From 7cf46dbf0a3f0ae98f1e71425e7b50d6478e2457 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:03 -0400 Subject: staging: omap-thermal: remove duplicated code There is no need to assign twice the same variable with the very same value. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index d0db361d5e29..531e853c1480 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -164,7 +164,6 @@ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) u32 t_hot = 0, t_cold = 0, ctrl; int i; - bg_ptr = data; /* Read the status of t_hot */ for (i = 0; i < bg_ptr->conf->sensor_count; i++) { tsr = bg_ptr->conf->sensors[i].registers; -- cgit From e555c95648408de12b7278c730764c7644d72b08 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:04 -0400 Subject: staging: omap-thermal: read status only once inside alert IRQ There is no need to re-read status register. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 531e853c1480..fce394224bc7 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -164,15 +164,15 @@ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) u32 t_hot = 0, t_cold = 0, ctrl; int i; - /* Read the status of t_hot */ for (i = 0; i < bg_ptr->conf->sensor_count; i++) { tsr = bg_ptr->conf->sensors[i].registers; - t_hot = omap_bandgap_readl(bg_ptr, tsr->bgap_status); - t_hot &= tsr->status_hot_mask; + ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_status); + + /* Read the status of t_hot */ + t_hot = ctrl & tsr->status_hot_mask; /* Read the status of t_cold */ - t_cold = omap_bandgap_readl(bg_ptr, tsr->bgap_status); - t_cold &= tsr->status_cold_mask; + t_cold = ctrl & tsr->status_cold_mask; if (!t_cold && !t_hot) continue; -- cgit From 8abbe71ee501cf2c8b7c49b64ffe0a1acdc7fa2a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:05 -0400 Subject: staging: omap-thermal: add a section of register manipulation This is introduces a series of marks inside the code to better organize functions per group, aggregating their functionality. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index fce394224bc7..77ff495dacb6 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -42,6 +42,8 @@ #include "omap-bandgap.h" +/*** Helper functions to access registers and their bitfields ***/ + /** * omap_bandgap_readl() - simple read helper function * @bg_ptr: pointer to omap_bandgap structure -- cgit From 6ab52402ecf1d8544c698ac4f4e79f29a7c387cf Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:06 -0400 Subject: staging: omap-thermal: section of basic helpers Group of simple functions aggregating basic functionality. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 77ff495dacb6..7927c591716f 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -88,6 +88,8 @@ do { \ omap_bandgap_writel(bg_ptr, r, t->reg); \ } while (0) +/*** Basic helper functions ***/ + /** * omap_bandgap_power() - controls the power state of a bandgap device * @bg_ptr: pointer to omap_bandgap structure -- cgit From fb65b88a58dfd7cf7002e28d39d88f02a438922b Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:07 -0400 Subject: staging: omap-thermal: IRQ handler section Section of IRQ handlers Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 7927c591716f..ded2c8c8b2cc 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -150,6 +150,8 @@ static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id) return temp; } +/*** IRQ handlers ***/ + /** * omap_bandgap_talert_irq_handler() - handles Temperature alert IRQs * @irq: IRQ number -- cgit From 2f6af4b3dbe344bcae25b75a6a3bb22ee3a31169 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:08 -0400 Subject: staging: omap-thermal: ADC section Section of ADC helpers functions Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index ded2c8c8b2cc..2acd30e81b6c 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -231,6 +231,8 @@ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) return IRQ_HANDLED; } +/*** Helper functions which manipulate conversion ADC <-> mi Celsius ***/ + static int adc_to_temp_conversion(struct omap_bandgap *bg_ptr, int id, int adc_val, int *t) -- cgit From bf7a979d439c4d518f0a9d6ea1ff6029e5817ae3 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:09 -0400 Subject: staging: omap-thermal: name adc_to_temp_conversion in a better way Rename adc_to_temp_conversion to omap_bandgap_adc_to_mcelsius. This name, though longer, describes better the function. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 2acd30e81b6c..a7fd3e89ecde 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -234,8 +234,8 @@ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) /*** Helper functions which manipulate conversion ADC <-> mi Celsius ***/ static -int adc_to_temp_conversion(struct omap_bandgap *bg_ptr, int id, int adc_val, - int *t) +int omap_bandgap_adc_to_mcelsius(struct omap_bandgap *bg_ptr, int id, + int adc_val, int *t) { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data; @@ -308,7 +308,7 @@ int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, int i, { int temp, ret; - ret = adc_to_temp_conversion(bg_ptr, i, adc_val, &temp); + ret = omap_bandgap_adc_to_mcelsius(bg_ptr, i, adc_val, &temp); if (ret < 0) return ret; @@ -439,7 +439,7 @@ int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); temp = (temp & tsr->threshold_thot_mask) >> __ffs(tsr->threshold_thot_mask); - ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); if (ret) { dev_err(bg_ptr->dev, "failed to read thot\n"); return -EIO; @@ -514,7 +514,7 @@ int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); temp = (temp & tsr->threshold_tcold_mask) >> __ffs(tsr->threshold_tcold_mask); - ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); if (ret) return -EIO; @@ -641,7 +641,7 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_read_temp(bg_ptr, id); mutex_unlock(&bg_ptr->bg_mutex); - ret |= adc_to_temp_conversion(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); if (ret) return -EIO; -- cgit From 204705992112e75f7f69cca191d89bf1104df7c2 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:10 -0400 Subject: staging: omap-thermal: rewrite omap_bandgap_adc_to_mcelsius on kernel coding style Follow Documentation/CodingStyle while doing omap_bandgap_adc_to_mcelsius. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index a7fd3e89ecde..0068c6651989 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -238,14 +238,19 @@ int omap_bandgap_adc_to_mcelsius(struct omap_bandgap *bg_ptr, int id, int adc_val, int *t) { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data; + int ret = 0; /* look up for temperature in the table and return the temperature */ - if (adc_val < ts_data->adc_start_val || adc_val > ts_data->adc_end_val) - return -ERANGE; + if (adc_val < ts_data->adc_start_val || + adc_val > ts_data->adc_end_val) { + ret = -ERANGE; + goto exit; + } *t = bg_ptr->conf->conv_table[adc_val - ts_data->adc_start_val]; - return 0; +exit: + return ret; } static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i, -- cgit From 2577e937cb8a4cc6967c4af88546c5939c78dbc5 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:11 -0400 Subject: staging: omap-thermal: add documentation for omap_bandgap_adc_to_mcelsius Document the conversion function. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 0068c6651989..8279cca0a616 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -233,6 +233,17 @@ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) /*** Helper functions which manipulate conversion ADC <-> mi Celsius ***/ +/** + * omap_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale + * @bg_ptr: struct omap_bandgap pointer + * @id: sensor id + * @adc_val: value in ADC representation + * @t: address where to write the resulting temperature in mCelsius + * + * Simple conversion from ADC representation to mCelsius. In case the ADC value + * is out of the ADC conv table range, it returns -ERANGE, 0 on success. + * The conversion table is indexed by the ADC values. + */ static int omap_bandgap_adc_to_mcelsius(struct omap_bandgap *bg_ptr, int id, int adc_val, int *t) -- cgit From e16f072d5d65a8df53ba4693f1334c453bd303aa Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:12 -0400 Subject: staging: omap-thermal: name temp_to_adc_conversion in a better way Rename temp_to_adc_conversion to omap_bandgap_mcelsius_to_adc. This name, though longer, describes better the function. This patch also changes this function signature so the function follows the style of this file. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 8279cca0a616..d5359e367d8f 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -264,8 +264,9 @@ exit: return ret; } -static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i, - int *adc) +static +int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, int i, long temp, + int *adc) { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[i].ts_data; const int *conv_table = bg_ptr->conf->conv_table; @@ -330,7 +331,7 @@ int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, int i, temp += hyst_val; - return temp_to_adc_conversion(temp, bg_ptr, i, sum); + return omap_bandgap_mcelsius_to_adc(bg_ptr, i, temp, sum); } /* Talert Thot threshold. Call it only if HAS(TALERT) is set */ @@ -493,7 +494,7 @@ int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val) if (val < ts_data->min_temp + ts_data->hyst_val) return -EINVAL; - ret = temp_to_adc_conversion(val, bg_ptr, id, &t_hot); + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, id, val, &t_hot); if (ret < 0) return ret; @@ -566,7 +567,7 @@ int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val) if (val > ts_data->max_temp + ts_data->hyst_val) return -EINVAL; - ret = temp_to_adc_conversion(val, bg_ptr, id, &t_cold); + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, id, val, &t_cold); if (ret < 0) return ret; -- cgit From a619477f51908e1029a7f1afce7f56a856d6bb66 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:13 -0400 Subject: staging: omap-thermal: rewrite omap_bandgap_mcelsius_to_adc on kernel coding style Follow Documentation/CodingStyle while doing omap_bandgap_mcelsius_to_adc Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index d5359e367d8f..e49a11509fed 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -270,14 +270,16 @@ int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, int i, long temp, { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[i].ts_data; const int *conv_table = bg_ptr->conf->conv_table; - int high, low, mid; + int high, low, mid, ret = 0; low = 0; high = ts_data->adc_end_val - ts_data->adc_start_val; mid = (high + low) / 2; - if (temp < conv_table[low] || temp > conv_table[high]) - return -EINVAL; + if (temp < conv_table[low] || temp > conv_table[high]) { + ret = -ERANGE; + goto exit; + } while (low < high) { if (temp < conv_table[mid]) @@ -289,7 +291,8 @@ int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, int i, long temp, *adc = ts_data->adc_start_val + low; - return 0; +exit: + return ret; } /* Talert masks. Call it only if HAS(TALERT) is set */ -- cgit From 26a70ed987acc329d64fa26c230d375e8f631512 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:14 -0400 Subject: staging: omap-thermal: move conv table limits out of sensor data As we have one conv table per bandgap device and not per sensor, this patch changes the data structures so that the conv table min and max values are now part of bandgap_data and not sensor_data. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 39 +++++++++++------------ drivers/staging/omap-thermal/omap-bandgap.h | 8 ++--- drivers/staging/omap-thermal/omap4-thermal-data.c | 10 +++--- drivers/staging/omap-thermal/omap5-thermal-data.c | 8 ++--- 4 files changed, 30 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index e49a11509fed..963fcafc76e1 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -236,7 +236,6 @@ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) /** * omap_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale * @bg_ptr: struct omap_bandgap pointer - * @id: sensor id * @adc_val: value in ADC representation * @t: address where to write the resulting temperature in mCelsius * @@ -245,35 +244,34 @@ static irqreturn_t omap_bandgap_tshut_irq_handler(int irq, void *data) * The conversion table is indexed by the ADC values. */ static -int omap_bandgap_adc_to_mcelsius(struct omap_bandgap *bg_ptr, int id, +int omap_bandgap_adc_to_mcelsius(struct omap_bandgap *bg_ptr, int adc_val, int *t) { - struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data; + struct omap_bandgap_data *conf = bg_ptr->conf; int ret = 0; /* look up for temperature in the table and return the temperature */ - if (adc_val < ts_data->adc_start_val || - adc_val > ts_data->adc_end_val) { + if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val) { ret = -ERANGE; goto exit; } - *t = bg_ptr->conf->conv_table[adc_val - ts_data->adc_start_val]; + *t = bg_ptr->conf->conv_table[adc_val - conf->adc_start_val]; exit: return ret; } static -int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, int i, long temp, +int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, long temp, int *adc) { - struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[i].ts_data; + struct omap_bandgap_data *conf = bg_ptr->conf; const int *conv_table = bg_ptr->conf->conv_table; int high, low, mid, ret = 0; low = 0; - high = ts_data->adc_end_val - ts_data->adc_start_val; + high = conf->adc_end_val - conf->adc_start_val; mid = (high + low) / 2; if (temp < conv_table[low] || temp > conv_table[high]) { @@ -289,7 +287,7 @@ int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, int i, long temp, mid = (low + high) / 2; } - *adc = ts_data->adc_start_val + low; + *adc = conf->adc_start_val + low; exit: return ret; @@ -323,18 +321,17 @@ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, } static -int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, int i, - u32 *sum) +int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, u32 *sum) { int temp, ret; - ret = omap_bandgap_adc_to_mcelsius(bg_ptr, i, adc_val, &temp); + ret = omap_bandgap_adc_to_mcelsius(bg_ptr, adc_val, &temp); if (ret < 0) return ret; temp += hyst_val; - return omap_bandgap_mcelsius_to_adc(bg_ptr, i, temp, sum); + return omap_bandgap_mcelsius_to_adc(bg_ptr, temp, sum); } /* Talert Thot threshold. Call it only if HAS(TALERT) is set */ @@ -354,7 +351,7 @@ int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) __ffs(tsr->threshold_tcold_mask); if (t_hot <= cold) { /* change the t_cold to t_hot - 5000 millidegrees */ - err |= add_hyst(t_hot, -ts_data->hyst_val, bg_ptr, id, &cold); + err |= add_hyst(t_hot, -ts_data->hyst_val, bg_ptr, &cold); /* write the new t_cold value */ reg_val = thresh_val & (~tsr->threshold_tcold_mask); reg_val |= cold << __ffs(tsr->threshold_tcold_mask); @@ -392,7 +389,7 @@ int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, if (t_cold >= hot) { /* change the t_hot to t_cold + 5000 millidegrees */ - err |= add_hyst(t_cold, ts_data->hyst_val, bg_ptr, id, &hot); + err |= add_hyst(t_cold, ts_data->hyst_val, bg_ptr, &hot); /* write the new t_hot value */ reg_val = thresh_val & (~tsr->threshold_thot_mask); reg_val |= hot << __ffs(tsr->threshold_thot_mask); @@ -459,7 +456,7 @@ int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); temp = (temp & tsr->threshold_thot_mask) >> __ffs(tsr->threshold_thot_mask); - ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); if (ret) { dev_err(bg_ptr->dev, "failed to read thot\n"); return -EIO; @@ -497,7 +494,7 @@ int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val) if (val < ts_data->min_temp + ts_data->hyst_val) return -EINVAL; - ret = omap_bandgap_mcelsius_to_adc(bg_ptr, id, val, &t_hot); + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, val, &t_hot); if (ret < 0) return ret; @@ -534,7 +531,7 @@ int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); temp = (temp & tsr->threshold_tcold_mask) >> __ffs(tsr->threshold_tcold_mask); - ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); if (ret) return -EIO; @@ -570,7 +567,7 @@ int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val) if (val > ts_data->max_temp + ts_data->hyst_val) return -EINVAL; - ret = omap_bandgap_mcelsius_to_adc(bg_ptr, id, val, &t_cold); + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, val, &t_cold); if (ret < 0) return ret; @@ -661,7 +658,7 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, temp = omap_bandgap_read_temp(bg_ptr, id); mutex_unlock(&bg_ptr->bg_mutex); - ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, id, temp, &temp); + ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); if (ret) return -EIO; diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 28d9104369cc..edcc9652d53f 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -166,8 +166,6 @@ struct temp_sensor_registers { * @max_temp: sensor maximum temperature * @min_temp: sensor minimum temperature * @hyst_val: temperature hysteresis considered while converting ADC values - * @adc_start_val: ADC conversion table starting value - * @adc_end_val: ADC conversion table ending value * @update_int1: update interval * @update_int2: update interval * @@ -185,8 +183,6 @@ struct temp_sensor_data { int max_temp; int min_temp; int hyst_val; - u32 adc_start_val; - u32 adc_end_val; u32 update_int1; /* not used */ u32 update_int2; /* not used */ }; @@ -325,6 +321,8 @@ struct omap_temp_sensor { * struct omap_bandgap_data - omap bandgap data configuration structure * @features: a bitwise flag set to describe the device features * @conv_table: Pointer to ADC to temperature conversion table + * @adc_start_val: ADC conversion table starting value + * @adc_end_val: ADC conversion table ending value * @fclock_name: clock name of the functional clock * @div_ck_name: clock name of the clock divisor * @sensor_count: count of temperature sensor within this bandgap device @@ -342,6 +340,8 @@ struct omap_temp_sensor { struct omap_bandgap_data { unsigned int features; const int *conv_table; + u32 adc_start_val; + u32 adc_end_val; char *fclock_name; char *div_ck_name; int sensor_count; diff --git a/drivers/staging/omap-thermal/omap4-thermal-data.c b/drivers/staging/omap-thermal/omap4-thermal-data.c index 7ec5570a21e8..88ed01446d7c 100644 --- a/drivers/staging/omap-thermal/omap4-thermal-data.c +++ b/drivers/staging/omap-thermal/omap4-thermal-data.c @@ -45,8 +45,6 @@ static struct temp_sensor_data omap4430_mpu_temp_sensor_data = { .max_temp = OMAP4430_MAX_TEMP, .min_temp = OMAP4430_MIN_TEMP, .hyst_val = OMAP4430_HYST_VAL, - .adc_start_val = OMAP4430_ADC_START_VALUE, - .adc_end_val = OMAP4430_ADC_END_VALUE, }; /* @@ -75,6 +73,8 @@ const struct omap_bandgap_data omap4430_data = { .fclock_name = "bandgap_fclk", .div_ck_name = "bandgap_fclk", .conv_table = omap4430_adc_to_temp, + .adc_start_val = OMAP4430_ADC_START_VALUE, + .adc_end_val = OMAP4430_ADC_END_VALUE, .expose_sensor = omap_thermal_expose_sensor, .remove_sensor = omap_thermal_remove_sensor, .sensors = { @@ -142,8 +142,6 @@ static struct temp_sensor_data omap4460_mpu_temp_sensor_data = { .max_temp = OMAP4460_MAX_TEMP, .min_temp = OMAP4460_MIN_TEMP, .hyst_val = OMAP4460_HYST_VAL, - .adc_start_val = OMAP4460_ADC_START_VALUE, - .adc_end_val = OMAP4460_ADC_END_VALUE, .update_int1 = 1000, .update_int2 = 2000, }; @@ -214,6 +212,8 @@ const struct omap_bandgap_data omap4460_data = { .fclock_name = "bandgap_ts_fclk", .div_ck_name = "div_ts_ck", .conv_table = omap4460_adc_to_temp, + .adc_start_val = OMAP4460_ADC_START_VALUE, + .adc_end_val = OMAP4460_ADC_END_VALUE, .expose_sensor = omap_thermal_expose_sensor, .remove_sensor = omap_thermal_remove_sensor, .sensors = { @@ -244,6 +244,8 @@ const struct omap_bandgap_data omap4470_data = { .fclock_name = "bandgap_ts_fclk", .div_ck_name = "div_ts_ck", .conv_table = omap4460_adc_to_temp, + .adc_start_val = OMAP4460_ADC_START_VALUE, + .adc_end_val = OMAP4460_ADC_END_VALUE, .expose_sensor = omap_thermal_expose_sensor, .remove_sensor = omap_thermal_remove_sensor, .sensors = { diff --git a/drivers/staging/omap-thermal/omap5-thermal-data.c b/drivers/staging/omap-thermal/omap5-thermal-data.c index 3d10704ce2eb..a48c286dde01 100644 --- a/drivers/staging/omap-thermal/omap5-thermal-data.c +++ b/drivers/staging/omap-thermal/omap5-thermal-data.c @@ -171,8 +171,6 @@ static struct temp_sensor_data omap5430_mpu_temp_sensor_data = { .max_temp = OMAP5430_MPU_MAX_TEMP, .min_temp = OMAP5430_MPU_MIN_TEMP, .hyst_val = OMAP5430_MPU_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, .update_int1 = 1000, .update_int2 = 2000, }; @@ -188,8 +186,6 @@ static struct temp_sensor_data omap5430_gpu_temp_sensor_data = { .max_temp = OMAP5430_GPU_MAX_TEMP, .min_temp = OMAP5430_GPU_MIN_TEMP, .hyst_val = OMAP5430_GPU_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, .update_int1 = 1000, .update_int2 = 2000, }; @@ -205,8 +201,6 @@ static struct temp_sensor_data omap5430_core_temp_sensor_data = { .max_temp = OMAP5430_CORE_MAX_TEMP, .min_temp = OMAP5430_CORE_MIN_TEMP, .hyst_val = OMAP5430_CORE_HYST_VAL, - .adc_start_val = OMAP5430_ADC_START_VALUE, - .adc_end_val = OMAP5430_ADC_END_VALUE, .update_int1 = 1000, .update_int2 = 2000, }; @@ -325,6 +319,8 @@ const struct omap_bandgap_data omap5430_data = { .fclock_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div", .conv_table = omap5430_adc_to_temp, + .adc_start_val = OMAP5430_ADC_START_VALUE, + .adc_end_val = OMAP5430_ADC_END_VALUE, .expose_sensor = omap_thermal_expose_sensor, .remove_sensor = omap_thermal_remove_sensor, .sensors = { -- cgit From e7f60b5360ff093a220b0022e62648d9090eae4e Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:15 -0400 Subject: staging: omap-thermal: add documentation for omap_bandgap_mcelsius_to_adc Document the conversion function. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 963fcafc76e1..39bfe8d48eff 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -262,6 +262,16 @@ exit: return ret; } +/** + * omap_bandgap_mcelsius_to_adc() - converts a mCelsius value to ADC scale + * @bg_ptr: struct omap_bandgap pointer + * @temp: value in mCelsius + * @adc: address where to write the resulting temperature in ADC representation + * + * Simple conversion from mCelsius to ADC values. In case the temp value + * is out of the ADC conv table range, it returns -ERANGE, 0 on success. + * The conversion table is indexed by the ADC values. + */ static int omap_bandgap_mcelsius_to_adc(struct omap_bandgap *bg_ptr, long temp, int *adc) -- cgit From 0f0ed7dee23ff06456c13ad4f30829ccb761834b Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:16 -0400 Subject: staging: omap-thermal: rename add_hyst to omap_bandgap_add_hyst This patch improves the add_hyst function by: . Renaming it to omap_bandgap_add_hyst . Moving it to the ADC conversion functions section . Changing its signature to follow the driver standard Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 42 ++++++++++++++++++----------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 39bfe8d48eff..7b10d1851092 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -303,6 +303,28 @@ exit: return ret; } +static +int omap_bandgap_add_hyst(struct omap_bandgap *bg_ptr, int adc_val, + int hyst_val, u32 *sum) +{ + int temp, ret; + + /* + * Need to add in the mcelsius domain, so we have a temperature + * the conv_table range + */ + ret = omap_bandgap_adc_to_mcelsius(bg_ptr, adc_val, &temp); + if (ret < 0) + goto exit; + + temp += hyst_val; + + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, temp, sum); + +exit: + return ret; +} + /* Talert masks. Call it only if HAS(TALERT) is set */ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, u32 t_hot, u32 t_cold) @@ -330,20 +352,6 @@ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, return 0; } -static -int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, u32 *sum) -{ - int temp, ret; - - ret = omap_bandgap_adc_to_mcelsius(bg_ptr, adc_val, &temp); - if (ret < 0) - return ret; - - temp += hyst_val; - - return omap_bandgap_mcelsius_to_adc(bg_ptr, temp, sum); -} - /* Talert Thot threshold. Call it only if HAS(TALERT) is set */ static int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) @@ -361,7 +369,8 @@ int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) __ffs(tsr->threshold_tcold_mask); if (t_hot <= cold) { /* change the t_cold to t_hot - 5000 millidegrees */ - err |= add_hyst(t_hot, -ts_data->hyst_val, bg_ptr, &cold); + err |= omap_bandgap_add_hyst(bg_ptr, t_hot, + -ts_data->hyst_val, &cold); /* write the new t_cold value */ reg_val = thresh_val & (~tsr->threshold_tcold_mask); reg_val |= cold << __ffs(tsr->threshold_tcold_mask); @@ -399,7 +408,8 @@ int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, if (t_cold >= hot) { /* change the t_hot to t_cold + 5000 millidegrees */ - err |= add_hyst(t_cold, ts_data->hyst_val, bg_ptr, &hot); + err |= omap_bandgap_add_hyst(bg_ptr, t_cold, + ts_data->hyst_val, &hot); /* write the new t_hot value */ reg_val = thresh_val & (~tsr->threshold_thot_mask); reg_val |= hot << __ffs(tsr->threshold_thot_mask); -- cgit From 8a1cefe857ae936d5a5f731eb301737139434580 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:17 -0400 Subject: staging: omap-thermal: document omap_bandgap_add_hyst function Document function to handle hysteresis. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 7b10d1851092..bff4b757c51a 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -303,6 +303,16 @@ exit: return ret; } +/** + * omap_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value + * @bg_ptr: struct omap_bandgap pointer + * @adc_val: temperature value in ADC representation + * @hyst_val: hysteresis value in mCelsius + * @sum: address where to write the resulting temperature (in ADC scale) + * + * Adds an hysteresis value (in mCelsius) to a ADC temperature value. + * Returns 0 on success, -ERANGE otherwise. + */ static int omap_bandgap_add_hyst(struct omap_bandgap *bg_ptr, int adc_val, int hyst_val, u32 *sum) -- cgit From f8ccce20bfaeac648f44c24a140eda6e982239e1 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:18 -0400 Subject: staging: omap-thermal: threshold manipulation section Section of functions manipulating thresholds for Alert and Shutdown. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index bff4b757c51a..f86c104df951 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -335,6 +335,8 @@ exit: return ret; } +/*** Helper functions handling device Alert/Shutdown signals ***/ + /* Talert masks. Call it only if HAS(TALERT) is set */ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, u32 t_hot, u32 t_cold) -- cgit From 910216890a8db1e7c406839916dc8f3fb85238d6 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:19 -0400 Subject: staging: omap-thermal: refactor temp_sensor_unmask_interrupts This change improves temp_sensor_unmask_interrupts by: . renaming it to omap_bandgap_unmask_interrupts . making it a void function, as there is nothing really to report an error. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index f86c104df951..26d36f361cc2 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -338,8 +338,8 @@ exit: /*** Helper functions handling device Alert/Shutdown signals ***/ /* Talert masks. Call it only if HAS(TALERT) is set */ -static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, - u32 t_hot, u32 t_cold) +static void omap_bandgap_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, + u32 t_hot, u32 t_cold) { struct temp_sensor_registers *tsr; u32 temp, reg_val; @@ -360,8 +360,6 @@ static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, else reg_val &= ~tsr->mask_cold_mask; omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl); - - return 0; } /* Talert Thot threshold. Call it only if HAS(TALERT) is set */ @@ -399,7 +397,9 @@ int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) return -EIO; } - return temp_sensor_unmask_interrupts(bg_ptr, id, t_hot, cold); + omap_bandgap_unmask_interrupts(bg_ptr, id, t_hot, cold); + + return 0; } /* Talert Tcold threshold. Call it only if HAS(TALERT) is set */ @@ -438,7 +438,9 @@ int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, return -EIO; } - return temp_sensor_unmask_interrupts(bg_ptr, id, hot, t_cold); + omap_bandgap_unmask_interrupts(bg_ptr, id, hot, t_cold); + + return 0; } #define bandgap_is_valid(b) \ -- cgit From f47f6d31645c5020602469cafa1e6c8a228dcaab Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:20 -0400 Subject: staging: omap-thermal: update omap_bandgap_unmask_interrupts documentation Proper document the function to configure the IRQ event masks. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 26d36f361cc2..d001323d1342 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -337,7 +337,15 @@ exit: /*** Helper functions handling device Alert/Shutdown signals ***/ -/* Talert masks. Call it only if HAS(TALERT) is set */ +/** + * omap_bandgap_unmask_interrupts() - unmasks the events of thot & tcold + * @bg_ptr: struct omap_bandgap pointer + * @t_hot: hot temperature value to trigger alert signal + * @t_cold: cold temperature value to trigger alert signal + * + * Checks the requested t_hot and t_cold values and configures the IRQ event + * masks accordingly. Call this function only if bandgap features HAS(TALERT). + */ static void omap_bandgap_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, u32 t_hot, u32 t_cold) { -- cgit From 56f132f78e9ee6c45b3197290733aed1fd6eeafc Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:21 -0400 Subject: staging: omap-thermal: refactor APIs handling threshold values This patch improves the code that handles threshold values by creating single functions that are usable for tcold and thot. This way we won't have duplicated functionality just because it is handling different bitfields. Now the added functions are reused in several places where it is needed to update any threshold. This patch also removes macros that are used only inside the _validate helper function. In this patch there is also an addition of an extra function section for Exposed APIs, used outside the omap-bandgap.c, but inside the omap-thermal driver. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 278 ++++++++++++---------------- 1 file changed, 117 insertions(+), 161 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index d001323d1342..2a13bf039811 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -370,145 +370,172 @@ static void omap_bandgap_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl); } -/* Talert Thot threshold. Call it only if HAS(TALERT) is set */ static -int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot) +int omap_bandgap_update_alert_threshold(struct omap_bandgap *bg_ptr, int id, + int val, bool hot) { struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data; struct temp_sensor_registers *tsr; - u32 thresh_val, reg_val; - int cold, err = 0; + u32 thresh_val, reg_val, t_hot, t_cold; + int err = 0; tsr = bg_ptr->conf->sensors[id].registers; - /* obtain the T cold value */ + /* obtain the current value */ thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - cold = (thresh_val & tsr->threshold_tcold_mask) >> - __ffs(tsr->threshold_tcold_mask); - if (t_hot <= cold) { - /* change the t_cold to t_hot - 5000 millidegrees */ - err |= omap_bandgap_add_hyst(bg_ptr, t_hot, - -ts_data->hyst_val, &cold); - /* write the new t_cold value */ - reg_val = thresh_val & (~tsr->threshold_tcold_mask); - reg_val |= cold << __ffs(tsr->threshold_tcold_mask); - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); - thresh_val = reg_val; + t_cold = (thresh_val & tsr->threshold_tcold_mask) >> + __ffs(tsr->threshold_tcold_mask); + t_hot = (thresh_val & tsr->threshold_thot_mask) >> + __ffs(tsr->threshold_thot_mask); + if (hot) + t_hot = val; + else + t_cold = val; + + if (t_cold < t_hot) { + if (hot) + err = omap_bandgap_add_hyst(bg_ptr, t_hot, + -ts_data->hyst_val, + &t_cold); + else + err = omap_bandgap_add_hyst(bg_ptr, t_cold, + ts_data->hyst_val, + &t_hot); } - /* write the new t_hot value */ + /* write the new threshold values */ reg_val = thresh_val & ~tsr->threshold_thot_mask; reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)); + reg_val |= thresh_val & ~tsr->threshold_tcold_mask; + reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask)); omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); + if (err) { dev_err(bg_ptr->dev, "failed to reprogram thot threshold\n"); - return -EIO; + err = -EIO; + goto exit; } - omap_bandgap_unmask_interrupts(bg_ptr, id, t_hot, cold); - - return 0; + omap_bandgap_unmask_interrupts(bg_ptr, id, t_hot, t_cold); +exit: + return err; } -/* Talert Tcold threshold. Call it only if HAS(TALERT) is set */ -static -int temp_sensor_configure_tcold(struct omap_bandgap *bg_ptr, int id, - int t_cold) +static inline int omap_bandgap_validate(struct omap_bandgap *bg_ptr, int id) { - struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data; - struct temp_sensor_registers *tsr; - u32 thresh_val, reg_val; - int hot, err = 0; + int ret = 0; - tsr = bg_ptr->conf->sensors[id].registers; - /* obtain the T cold value */ - thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - hot = (thresh_val & tsr->threshold_thot_mask) >> - __ffs(tsr->threshold_thot_mask); - - if (t_cold >= hot) { - /* change the t_hot to t_cold + 5000 millidegrees */ - err |= omap_bandgap_add_hyst(bg_ptr, t_cold, - ts_data->hyst_val, &hot); - /* write the new t_hot value */ - reg_val = thresh_val & (~tsr->threshold_thot_mask); - reg_val |= hot << __ffs(tsr->threshold_thot_mask); - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); - thresh_val = reg_val; + if (IS_ERR_OR_NULL(bg_ptr)) { + pr_err("%s: invalid bandgap pointer\n", __func__); + ret = -EINVAL; + goto exit; } - /* write the new t_cold value */ - reg_val = thresh_val & ~tsr->threshold_tcold_mask; - reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask)); - omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold); - if (err) { - dev_err(bg_ptr->dev, "failed to reprogram tcold threshold\n"); - return -EIO; + if ((id < 0) || (id >= bg_ptr->conf->sensor_count)) { + dev_err(bg_ptr->dev, "%s: sensor id out of range (%d)\n", + __func__, id); + ret = -ERANGE; } - omap_bandgap_unmask_interrupts(bg_ptr, id, hot, t_cold); - - return 0; +exit: + return ret; } -#define bandgap_is_valid(b) \ - (!IS_ERR_OR_NULL(b)) -#define bandgap_is_valid_sensor_id(b, i) \ - ((i) >= 0 && (i) < (b)->conf->sensor_count) -static inline int omap_bandgap_validate(struct omap_bandgap *bg_ptr, int id) +int _omap_bandgap_write_threshold(struct omap_bandgap *bg_ptr, int id, int val, + bool hot) { - if (!bandgap_is_valid(bg_ptr)) { - pr_err("%s: invalid bandgap pointer\n", __func__); - return -EINVAL; + struct temp_sensor_data *ts_data; + struct temp_sensor_registers *tsr; + u32 adc_val; + int ret; + + ret = omap_bandgap_validate(bg_ptr, id); + if (ret) + goto exit; + + if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { + ret = -ENOTSUPP; + goto exit; } - if (!bandgap_is_valid_sensor_id(bg_ptr, id)) { - dev_err(bg_ptr->dev, "%s: sensor id out of range (%d)\n", - __func__, id); - return -ERANGE; + ts_data = bg_ptr->conf->sensors[id].ts_data; + tsr = bg_ptr->conf->sensors[id].registers; + if (hot) { + if (val < ts_data->min_temp + ts_data->hyst_val) + ret = -EINVAL; + } else { + if (val > ts_data->max_temp + ts_data->hyst_val) + ret = -EINVAL; } - return 0; + if (ret) + goto exit; + + ret = omap_bandgap_mcelsius_to_adc(bg_ptr, val, &adc_val); + if (ret < 0) + goto exit; + + mutex_lock(&bg_ptr->bg_mutex); + omap_bandgap_update_alert_threshold(bg_ptr, id, adc_val, hot); + mutex_unlock(&bg_ptr->bg_mutex); + +exit: + return ret; } -/* Exposed APIs */ -/** - * omap_bandgap_read_thot() - reads sensor current thot - * @bg_ptr - pointer to bandgap instance - * @id - sensor id - * @thot - resulting current thot value - * - * returns 0 on success or the proper error code - */ -int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, - int *thot) +int _omap_bandgap_read_threshold(struct omap_bandgap *bg_ptr, int id, + int *val, bool hot) { struct temp_sensor_registers *tsr; - u32 temp; - int ret; + u32 temp, mask; + int ret = 0; ret = omap_bandgap_validate(bg_ptr, id); if (ret) - return ret; + goto exit; - if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) - return -ENOTSUPP; + if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { + ret = -ENOTSUPP; + goto exit; + } tsr = bg_ptr->conf->sensors[id].registers; + if (hot) + mask = tsr->threshold_thot_mask; + else + mask = tsr->threshold_tcold_mask; + temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - temp = (temp & tsr->threshold_thot_mask) >> - __ffs(tsr->threshold_thot_mask); + temp = (temp & mask) >> __ffs(mask); ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); if (ret) { dev_err(bg_ptr->dev, "failed to read thot\n"); - return -EIO; + ret = -EIO; + goto exit; } - *thot = temp; + *val = temp; +exit: return 0; } +/*** Exposed APIs ***/ + +/** + * omap_bandgap_read_thot() - reads sensor current thot + * @bg_ptr - pointer to bandgap instance + * @id - sensor id + * @thot - resulting current thot value + * + * returns 0 on success or the proper error code + */ +int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, + int *thot) +{ + return _omap_bandgap_read_threshold(bg_ptr, id, thot, true); +} + /** * omap_bandgap_write_thot() - sets sensor current thot * @bg_ptr - pointer to bandgap instance @@ -519,32 +546,7 @@ int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, */ int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val) { - struct temp_sensor_data *ts_data; - struct temp_sensor_registers *tsr; - u32 t_hot; - int ret; - - ret = omap_bandgap_validate(bg_ptr, id); - if (ret) - return ret; - - if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) - return -ENOTSUPP; - - ts_data = bg_ptr->conf->sensors[id].ts_data; - tsr = bg_ptr->conf->sensors[id].registers; - - if (val < ts_data->min_temp + ts_data->hyst_val) - return -EINVAL; - ret = omap_bandgap_mcelsius_to_adc(bg_ptr, val, &t_hot); - if (ret < 0) - return ret; - - mutex_lock(&bg_ptr->bg_mutex); - temp_sensor_configure_thot(bg_ptr, id, t_hot); - mutex_unlock(&bg_ptr->bg_mutex); - - return 0; + return _omap_bandgap_write_threshold(bg_ptr, id, val, true); } /** @@ -558,28 +560,7 @@ int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val) int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, int *tcold) { - struct temp_sensor_registers *tsr; - u32 temp; - int ret; - - ret = omap_bandgap_validate(bg_ptr, id); - if (ret) - return ret; - - if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) - return -ENOTSUPP; - - tsr = bg_ptr->conf->sensors[id].registers; - temp = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold); - temp = (temp & tsr->threshold_tcold_mask) - >> __ffs(tsr->threshold_tcold_mask); - ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); - if (ret) - return -EIO; - - *tcold = temp; - - return 0; + return _omap_bandgap_read_threshold(bg_ptr, id, tcold, false); } /** @@ -592,32 +573,7 @@ int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, */ int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val) { - struct temp_sensor_data *ts_data; - struct temp_sensor_registers *tsr; - u32 t_cold; - int ret; - - ret = omap_bandgap_validate(bg_ptr, id); - if (ret) - return ret; - - if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) - return -ENOTSUPP; - - ts_data = bg_ptr->conf->sensors[id].ts_data; - tsr = bg_ptr->conf->sensors[id].registers; - if (val > ts_data->max_temp + ts_data->hyst_val) - return -EINVAL; - - ret = omap_bandgap_mcelsius_to_adc(bg_ptr, val, &t_cold); - if (ret < 0) - return ret; - - mutex_lock(&bg_ptr->bg_mutex); - temp_sensor_configure_tcold(bg_ptr, id, t_cold); - mutex_unlock(&bg_ptr->bg_mutex); - - return 0; + return _omap_bandgap_write_threshold(bg_ptr, id, val, false); } /** -- cgit From e195aba425069b259cf1d66b6309a3aeedb23a14 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:22 -0400 Subject: staging: omap-thermal: device initialization section Section of helper functions to initilize the bandgap device Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 2a13bf039811..8c7ac0e37183 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -703,6 +703,8 @@ void *omap_bandgap_get_sensor_data(struct omap_bandgap *bg_ptr, int id) return bg_ptr->conf->sensors[id].data; } +/*** Helper functions used during device initialization ***/ + static int omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) { -- cgit From f91ddfedfd94de94f283cd4b4e0f6ae9b1f9beb6 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:23 -0400 Subject: staging: omap-thermal: section of device driver callbacks Section with platform device callbacks Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 8c7ac0e37183..87461875829e 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -862,6 +862,8 @@ static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev) return bg_ptr; } +/*** Device driver call backs ***/ + static int omap_bandgap_probe(struct platform_device *pdev) { -- cgit From 37bf871dd0ad55c3a66d8a22e3cd5be0d9588e78 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:24 -0400 Subject: staging: omap-thermal: rename enable_continuous_mode This patch names 'enable_continuous_mode' accordingly to the file standard naming. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 87461875829e..e325269871ff 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -735,7 +735,7 @@ omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) * * Call this function only if HAS(MODE_CONFIG) is set */ -static int enable_continuous_mode(struct omap_bandgap *bg_ptr) +static int omap_bandgap_set_continuous_mode(struct omap_bandgap *bg_ptr) { int i; @@ -973,7 +973,7 @@ int omap_bandgap_probe(struct platform_device *pdev) } if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) - enable_continuous_mode(bg_ptr); + omap_bandgap_set_continuous_mode(bg_ptr); /* Set .250 seconds time as default counter */ if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) -- cgit From a84b6f4552e1db00a6e6ffbd85b35c0a169be02c Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:25 -0400 Subject: staging: omap-thermal: update omap_bandgap_set_continous_mode documentation Simple update on function documentation. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index e325269871ff..d89393129530 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -730,10 +730,13 @@ omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) } /** - * enable_continuous_mode() - One time enabling of continuous conversion mode - * @bg_ptr - pointer to scm instance + * omap_bandgap_set_continous_mode() - One time enabling of continuous mode + * @bg_ptr: pointer to struct omap_bandgap * - * Call this function only if HAS(MODE_CONFIG) is set + * Call this function only if HAS(MODE_CONFIG) is set. As this driver may + * be used for junction temperature monitoring, it is desirable that the + * sensors are operational all the time, so that alerts are generated + * properly. */ static int omap_bandgap_set_continuous_mode(struct omap_bandgap *bg_ptr) { -- cgit From 31102a7202dec13296a7de8e72427966813da75e Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:26 -0400 Subject: staging: omap-thermal: document omap_bandgap_force_single_read Document function to initialize the conversion state machine. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index d89393129530..065f3716c540 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -705,6 +705,14 @@ void *omap_bandgap_get_sensor_data(struct omap_bandgap *bg_ptr, int id) /*** Helper functions used during device initialization ***/ +/** + * omap_bandgap_force_single_read() - executes 1 single ADC conversion + * @bg_ptr: pointer to struct omap_bandgap + * @id: sensor id which it is desired to read 1 temperature + * + * Used to initialize the conversion state machine and set it to a valid + * state. Called during device initialization and context restore events. + */ static int omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id) { -- cgit From 38d99e807b0c555e768c60c3ff11fe7e3b2e9418 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:27 -0400 Subject: staging: omap-thermal: document omap_bandgap_update_alert_threshold function Document function to program alert thresholds Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 065f3716c540..0eb21b330415 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -370,6 +370,20 @@ static void omap_bandgap_unmask_interrupts(struct omap_bandgap *bg_ptr, int id, omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl); } +/** + * omap_bandgap_update_alert_threshold() - sequence to update thresholds + * @bg_ptr: struct omap_bandgap pointer + * @id: bandgap sensor id + * @val: value (ADC) of a new threshold + * @hot: desired threshold to be updated. true if threshold hot, false if + * threshold cold + * + * It will program the required thresholds (hot and cold) for TALERT signal. + * This function can be used to update t_hot or t_cold, depending on @hot value. + * It checks the resulting t_hot and t_cold values, based on the new passed @val + * and configures the thresholds so that t_hot is always greater than t_cold. + * Call this function only if bandgap features HAS(TALERT). + */ static int omap_bandgap_update_alert_threshold(struct omap_bandgap *bg_ptr, int id, int val, bool hot) -- cgit From 9efa93b0e695d759141f840b683394e642cbbb94 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:28 -0400 Subject: staging: omap-thermal: document _omap_bandgap_write_threshold function Document function to update alert thresholds. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 0eb21b330415..4cacfc1c546b 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -455,6 +455,19 @@ exit: return ret; } +/** + * _omap_bandgap_write_threshold() - helper to update TALERT t_cold or t_hot + * @bg_ptr: struct omap_bandgap pointer + * @id: bandgap sensor id + * @val: value (mCelsius) of a new threshold + * @hot: desired threshold to be updated. true if threshold hot, false if + * threshold cold + * + * It will update the required thresholds (hot and cold) for TALERT signal. + * This function can be used to update t_hot or t_cold, depending on @hot value. + * Validates the mCelsius range and update the requested threshold. + * Call this function only if bandgap features HAS(TALERT). + */ int _omap_bandgap_write_threshold(struct omap_bandgap *bg_ptr, int id, int val, bool hot) { -- cgit From 7a681a50ed97c7db60fdde608d885533b9f98acb Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:29 -0400 Subject: staging: omap-thermal: document _omap_bandgap_read_threshold function Add documentation of the function for reading alert thresholds Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 4cacfc1c546b..aa90539f20ca 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -510,6 +510,18 @@ exit: return ret; } +/** + * _omap_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot + * @bg_ptr: struct omap_bandgap pointer + * @id: bandgap sensor id + * @val: value (mCelsius) of a threshold + * @hot: desired threshold to be read. true if threshold hot, false if + * threshold cold + * + * It will fetch the required thresholds (hot and cold) for TALERT signal. + * This function can be used to read t_hot or t_cold, depending on @hot value. + * Call this function only if bandgap features HAS(TALERT). + */ int _omap_bandgap_read_threshold(struct omap_bandgap *bg_ptr, int id, int *val, bool hot) { -- cgit From d3790b3ddcccd2c62cb83aae33a36d3cb028506d Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:30 -0400 Subject: staging: omap-thermal: document omap_bandgap_tshut_init function Add documentation for the function to setup TSHUT handling Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index aa90539f20ca..f2ebbcf4facd 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -798,6 +798,18 @@ static int omap_bandgap_set_continuous_mode(struct omap_bandgap *bg_ptr) return 0; } +/** + * omap_bandgap_tshut_init() - setup and initialize tshut handling + * @bg_ptr: pointer to struct omap_bandgap + * @pdev: pointer to device struct platform_device + * + * Call this function only in case the bandgap features HAS(TSHUT). + * In this case, the driver needs to handle the TSHUT signal as an IRQ. + * The IRQ is wired as a GPIO, and for this purpose, it is required + * to specify which GPIO line is used. TSHUT IRQ is fired anytime + * one of the bandgap sensors violates the TSHUT high/hot threshold. + * And in that case, the system must go off. + */ static int omap_bandgap_tshut_init(struct omap_bandgap *bg_ptr, struct platform_device *pdev) { -- cgit From 094b8aca16afcd380b60d11ba23d74ee5836d781 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:31 -0400 Subject: staging: omap-thermal: document omap_bandgap_alert_init function Document function that sets talert handling up. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index f2ebbcf4facd..3150ec25dc6a 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -842,7 +842,17 @@ static int omap_bandgap_tshut_init(struct omap_bandgap *bg_ptr, return 0; } -/* Initialization of Talert. Call it only if HAS(TALERT) is set */ +/** + * omap_bandgap_alert_init() - setup and initialize talert handling + * @bg_ptr: pointer to struct omap_bandgap + * @pdev: pointer to device struct platform_device + * + * Call this function only in case the bandgap features HAS(TALERT). + * In this case, the driver needs to handle the TALERT signals as an IRQs. + * TALERT is a normal IRQ and it is fired any time thresholds (hot or cold) + * are violated. In these situation, the driver must reprogram the thresholds, + * accordingly to specified policy. + */ static int omap_bandgap_talert_init(struct omap_bandgap *bg_ptr, struct platform_device *pdev) { -- cgit From e9b6f8c4da4614549ad5c1497f6895ef5f26ea24 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:32 -0400 Subject: staging: omap-thermal: document omap_bandgap_build function Document function to build omap_bandgap structure Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 3150ec25dc6a..4b631fd20e3a 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -875,6 +875,15 @@ static int omap_bandgap_talert_init(struct omap_bandgap *bg_ptr, return 0; } +/** + * omap_bandgap_build() - parse DT and setup a struct omap_bandgap + * @bg_ptr: pointer to struct omap_bandgap + * @pdev: pointer to device struct platform_device + * + * Used to read the device tree properties accordingly to the bandgap + * matching version. Based on bandgap version and its capabilities it + * will build a struct omap_bandgap out of the required DT entries. + */ static const struct of_device_id of_omap_bandgap_match[]; static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev) { -- cgit From 494bbdd8b11f08dc703a76513674d57c5c349fa7 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:33 -0400 Subject: staging: omap-thermal: change Kconfig dependency method Now arch code has to specify CONFIG_ARCH_HAS_BANDGAP. So, this driver will be selectable only if the platform reports itself as having a bandgap device. Any OMAP variant or any other OMAP version needs to select ARCH_HAS_BANDGAP so that the driver will be applicable. A part from that it is required to device the data structures that maps the registers and their bitfields. The DT compatible list must also be updated. CC: Santosh Shilimkar CC: Vaibhav Bedia Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/Kconfig | 2 +- drivers/staging/omap-thermal/TODO | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/Kconfig b/drivers/staging/omap-thermal/Kconfig index 30cbc3bc8dfa..52170bfaf15d 100644 --- a/drivers/staging/omap-thermal/Kconfig +++ b/drivers/staging/omap-thermal/Kconfig @@ -1,7 +1,7 @@ config OMAP_BANDGAP tristate "Texas Instruments OMAP4+ temperature sensor driver" depends on THERMAL - depends on ARCH_OMAP4 || SOC_OMAP5 + depends on ARCH_HAS_BANDGAP help If you say yes here you get support for the Texas Instruments OMAP4460+ on die bandgap temperature sensor support. The register diff --git a/drivers/staging/omap-thermal/TODO b/drivers/staging/omap-thermal/TODO index 9e23cc4d551b..77b761befe92 100644 --- a/drivers/staging/omap-thermal/TODO +++ b/drivers/staging/omap-thermal/TODO @@ -20,7 +20,6 @@ on omap5-thermal.c - Add support for GPU cooling generally: -- write Kconfig dependencies so that omap variants are covered - make checkpatch.pl and sparse happy - make sure this code works on OMAP4430, OMAP4460 and OMAP5430 - update documentation -- cgit From ebf0bd52e657b41341bbfb0cbaabc308bf1c58e9 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:35 -0400 Subject: staging: omap-thermal: switch mutex to spinlock inside omap-bandgap Because there is a need to lock inside IRQ handler, this patch changes the locking mechanism inside the omap-bandgap.[c,h] to spinlocks. Now this lock is used to protect omap_bandgap struct during APIs exposed (possibly used in sysfs handling functions) and inside the ALERT IRQ handler. Because there are registers shared among the sensors, this lock is global, not per sensor. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/TODO | 1 - drivers/staging/omap-thermal/omap-bandgap.c | 18 ++++++++++-------- drivers/staging/omap-thermal/omap-bandgap.h | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/TODO b/drivers/staging/omap-thermal/TODO index 77b761befe92..0f24e9b7555b 100644 --- a/drivers/staging/omap-thermal/TODO +++ b/drivers/staging/omap-thermal/TODO @@ -1,7 +1,6 @@ List of TODOs (by Eduardo Valentin) on omap-bandgap.c: -- Rework locking - Improve driver code by adding usage of regmap-mmio - Test every exposed API to userland - Add support to hwmon diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 4b631fd20e3a..846ced66d10c 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -170,6 +170,7 @@ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) u32 t_hot = 0, t_cold = 0, ctrl; int i; + spin_lock(&bg_ptr->lock); for (i = 0; i < bg_ptr->conf->sensor_count; i++) { tsr = bg_ptr->conf->sensors[i].registers; ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_status); @@ -208,6 +209,7 @@ static irqreturn_t omap_bandgap_talert_irq_handler(int irq, void *data) if (bg_ptr->conf->report_temperature) bg_ptr->conf->report_temperature(bg_ptr, i); } + spin_unlock(&bg_ptr->lock); return IRQ_HANDLED; } @@ -502,9 +504,9 @@ int _omap_bandgap_write_threshold(struct omap_bandgap *bg_ptr, int id, int val, if (ret < 0) goto exit; - mutex_lock(&bg_ptr->bg_mutex); + spin_lock(&bg_ptr->lock); omap_bandgap_update_alert_threshold(bg_ptr, id, adc_val, hot); - mutex_unlock(&bg_ptr->bg_mutex); + spin_unlock(&bg_ptr->lock); exit: return ret; @@ -666,9 +668,9 @@ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, return -ENOTSUPP; interval = interval * bg_ptr->clk_rate / 1000; - mutex_lock(&bg_ptr->bg_mutex); + spin_lock(&bg_ptr->lock); RMW_BITS(bg_ptr, id, bgap_counter, counter_mask, interval); - mutex_unlock(&bg_ptr->bg_mutex); + spin_unlock(&bg_ptr->lock); return 0; } @@ -691,9 +693,9 @@ int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id, if (ret) return ret; - mutex_lock(&bg_ptr->bg_mutex); + spin_lock(&bg_ptr->lock); temp = omap_bandgap_read_temp(bg_ptr, id); - mutex_unlock(&bg_ptr->bg_mutex); + spin_unlock(&bg_ptr->lock); ret |= omap_bandgap_adc_to_mcelsius(bg_ptr, temp, &temp); if (ret) @@ -1016,7 +1018,7 @@ int omap_bandgap_probe(struct platform_device *pdev) clk_prepare_enable(bg_ptr->fclock); - mutex_init(&bg_ptr->bg_mutex); + spin_lock_init(&bg_ptr->lock); bg_ptr->dev = &pdev->dev; platform_set_drvdata(pdev, bg_ptr); diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index edcc9652d53f..57005862d4f9 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -23,7 +23,7 @@ #ifndef __OMAP_BANDGAP_H #define __OMAP_BANDGAP_H -#include +#include #include #include @@ -211,7 +211,7 @@ struct omap_bandgap { struct omap_bandgap_data *conf; struct clk *fclock; struct clk *div_clk; - struct mutex bg_mutex; /* shields this struct */ + spinlock_t lock; /* shields this struct */ int irq; int tshut_gpio; u32 clk_rate; -- cgit From 0205b15fa4f2ff5f0574de1f6eb327348acba422 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:36 -0400 Subject: staging: omap-thermal: remove TODO entry suggesting regmap usage It is hard to use regmap because benefit of using regmap cache may not be applicable as there is a specific sequence to restore the bandgap context. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/TODO | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/TODO b/drivers/staging/omap-thermal/TODO index 0f24e9b7555b..91e20705824a 100644 --- a/drivers/staging/omap-thermal/TODO +++ b/drivers/staging/omap-thermal/TODO @@ -1,7 +1,6 @@ List of TODOs (by Eduardo Valentin) on omap-bandgap.c: -- Improve driver code by adding usage of regmap-mmio - Test every exposed API to userland - Add support to hwmon - Review and revisit all API exposed -- cgit From ff4a44ce327567b83cae846c662c732758280bc6 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:37 -0400 Subject: staging: omap-thermal: remove TODO entry for exposed APIs Not all APIs exposed today are used. However all unused APIs will be required once the thermal layer allows IRQ based policies. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/TODO | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/TODO b/drivers/staging/omap-thermal/TODO index 91e20705824a..d45f556a7fb3 100644 --- a/drivers/staging/omap-thermal/TODO +++ b/drivers/staging/omap-thermal/TODO @@ -3,7 +3,6 @@ List of TODOs (by Eduardo Valentin) on omap-bandgap.c: - Test every exposed API to userland - Add support to hwmon -- Review and revisit all API exposed - Revisit PM support - Revisit data structures and simplify them - Once SCM-core api settles, update this driver accordingly -- cgit From e72b7bbd178bf0081b5f62f1daaf86a7daf13f3e Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 15 Mar 2013 09:00:38 -0400 Subject: staging: omap-thermal: add documentation for omap_bandgap_validate Document the helper to validate a struct omap_bandgap and a sensor id. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 846ced66d10c..33bfe3bbc367 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -437,6 +437,14 @@ exit: return err; } +/** + * omap_bandgap_validate() - helper to check the sanity of a struct omap_bandgap + * @bg_ptr: struct omap_bandgap pointer + * @id: bandgap sensor id + * + * Checks if the bandgap pointer is valid and if the sensor id is also + * applicable. + */ static inline int omap_bandgap_validate(struct omap_bandgap *bg_ptr, int id) { int ret = 0; -- cgit From 13b47d5f79f76293abda13c8b39570659bb9e9ca Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Mar 2013 17:20:08 +0800 Subject: staging: sep: fix possible memory leak in sep_prepare_input_dma_table() 'lli_array_ptr' etc. are malloced in sep_prepare_input_dma_table() and should be freed before leaving from the error handling case, otherwise it will cause memory leak. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index f5b73419eebc..6a98a208bbf2 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -1986,7 +1986,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, dma_ctx, sep_lli_entries); if (error) - return error; + goto end_function_error; lli_table_alloc_addr = *dmatables_region; } -- cgit From 673f98ccacf6fdf1f023531c2782b3887bc664a3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Mar 2013 09:03:31 +0300 Subject: Staging: dwc2: remove a kfree(NULL) dwc2_hcd_release() calls dwc2_hcd_free() which frees ->core_params and sets it to NULL. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/hcd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index 246b483481fa..01dbdd85c725 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -2940,7 +2940,6 @@ void dwc2_hcd_remove(struct device *dev, struct dwc2_hsotg *hsotg) usb_remove_hcd(hcd); hsotg->priv = NULL; dwc2_hcd_release(hsotg); - kfree(hsotg->core_params); #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS kfree(hsotg->last_frame_num_array); -- cgit From 615c902fb824d8273dd2b6837cda7ecb36b487e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 14 Mar 2013 13:33:24 -0700 Subject: staging: comedi: ni_atmio: fix build error due to missing '; ' Fix a build error due to a missing ';' at the end of a line. Signed-off-by: H Hartley Sweeten Reported-by: Geert Uytterhoeven Cc: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 279f2cd99cdc..37372a1f9ed9 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -467,7 +467,7 @@ static int ni_atmio_attach(struct comedi_device *dev, return -EIO; dev->board_ptr = ni_boards + board; - boardtype = comedi_board(dev) + boardtype = comedi_board(dev); printk(" %s", boardtype->name); dev->board_name = boardtype->name; -- cgit From 87f6991ba83ec8b0e054a450be1b1a17326fbc4e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 10:32:12 +0000 Subject: staging: comedi: adv_pci_dio: restore PCI-1753E support Back in the old days (before "staging") when Comedi only supported manual configuration of devices, the "adv_pci_dio" driver supported both PCI-1753 ("pci1753") and PCI-1753E ("pci1753e"). In actual fact, "pci1753e" is just a PCI-1753 connected by a ribbon cable to a PCI-1753E expansion card, which is plugged into a PCI slot but is not a PCI device itself. Now that the "adv_pci_dio" driver only supports automatic configuration of devices and the main "comedi" module no longer allows auto-configuration to be disabled, a PCI-1753 with a PCI-1753E expansion card is always treated as an unexpanded PCI-1753 ("pci1753") and there is no way to override it. (Recently, an undefined macro `USE_PCI1753E_BOARDINFO` was used to make the driver switch to supporting "pci1753e" instead of "pci1753", but this is less than ideal.) Advantech has their own Linux (non-Comedi) driver for the PCI-1753 which detects whether the PCI-1753E expansion card is connected to the PCI-1753 by fiddling with a register at offset 53 from the main registers base. Use Advantech's test in our "adv_pci_dio" driver. If the board appears to be a PCI-1753 ("pci1753"), check if the expansion card appears to be present, and if so, treat the device as a PCI-1753 plus PCI-1753E expansion card ("pci1753e"). Also, get rid of `enum dio_boardid` (`BOARD_...` enum values) which was added recently and just use the older `TYPE_...` enum values from `enum hw_cards_id` instead as the mapping is now 1-to-1. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 124 +++++++++++++++------------ 1 file changed, 67 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 3a05fbca9299..e98ddcc6ecfa 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -37,13 +37,6 @@ Configuration options: #include "8255.h" #include "8253.h" -/* - * The pci1753 and pci1753e have the same vendor/device id! - * - * These boards are quite different. #define this if your card is a pci1753e. - */ -#undef USE_PCI1753E_BOARDINFO - /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, @@ -233,23 +226,6 @@ enum hw_io_access { #define OMBCMD_RETRY 0x03 /* 3 times try request before error */ -enum dio_boardid { - BOARD_PCI1730, - BOARD_PCI1733, - BOARD_PCI1734, - BOARD_PCI1735, - BOARD_PCI1736, - BOARD_PCI1739, - BOARD_PCI1750, - BOARD_PCI1751, - BOARD_PCI1752, - BOARD_PCI1753, - BOARD_PCI1754, - BOARD_PCI1756, - BOARD_PCI1760, - BOARD_PCI1762, -}; - struct diosubd_data { int chans; /* num of chans */ int addr; /* PCI address ofset */ @@ -272,7 +248,7 @@ struct dio_boardtype { }; static const struct dio_boardtype boardtypes[] = { - [BOARD_PCI1730] = { + [TYPE_PCI1730] = { .name = "pci1730", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1730, @@ -284,7 +260,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, }, - [BOARD_PCI1733] = { + [TYPE_PCI1733] = { .name = "pci1733", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1733, @@ -293,7 +269,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, }, - [BOARD_PCI1734] = { + [TYPE_PCI1734] = { .name = "pci1734", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1734, @@ -302,7 +278,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, }, - [BOARD_PCI1735] = { + [TYPE_PCI1735] = { .name = "pci1735", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1735, @@ -313,7 +289,7 @@ static const struct dio_boardtype boardtypes[] = { .s8254[0] = { 3, PCI1735_C8254, 1, 0, }, .io_access = IO_8b, }, - [BOARD_PCI1736] = { + [TYPE_PCI1736] = { .name = "pci1736", .main_pci_region = PCI1736_MAINREG, .cardtype = TYPE_PCI1736, @@ -323,7 +299,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_8b, }, - [BOARD_PCI1739] = { + [TYPE_PCI1739] = { .name = "pci1739", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1739, @@ -331,7 +307,7 @@ static const struct dio_boardtype boardtypes[] = { .sdio[0] = { 48, PCI1739_DIO, 2, 0, }, .io_access = IO_8b, }, - [BOARD_PCI1750] = { + [TYPE_PCI1750] = { .name = "pci1750", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1750, @@ -340,7 +316,7 @@ static const struct dio_boardtype boardtypes[] = { .sdo[1] = { 16, PCI1750_IDO, 2, 0, }, .io_access = IO_8b, }, - [BOARD_PCI1751] = { + [TYPE_PCI1751] = { .name = "pci1751", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1751, @@ -349,7 +325,7 @@ static const struct dio_boardtype boardtypes[] = { .s8254[0] = { 3, PCI1751_CNT, 1, 0, }, .io_access = IO_8b, }, - [BOARD_PCI1752] = { + [TYPE_PCI1752] = { .name = "pci1752", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1752, @@ -359,15 +335,15 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, }, - [BOARD_PCI1753] = { -#ifndef USE_PCI1753E_BOARDINFO + [TYPE_PCI1753] = { .name = "pci1753", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753, .nsubdevs = 4, .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .io_access = IO_8b, -#else + }, + [TYPE_PCI1753E] = { .name = "pci1753e", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1753E, @@ -375,9 +351,8 @@ static const struct dio_boardtype boardtypes[] = { .sdio[0] = { 96, PCI1753_DIO, 4, 0, }, .sdio[1] = { 96, PCI1753E_DIO, 4, 0, }, .io_access = IO_8b, -#endif }, - [BOARD_PCI1754] = { + [TYPE_PCI1754] = { .name = "pci1754", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1754, @@ -387,7 +362,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, }, - [BOARD_PCI1756] = { + [TYPE_PCI1756] = { .name = "pci1756", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1756, @@ -397,7 +372,7 @@ static const struct dio_boardtype boardtypes[] = { .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, }, .io_access = IO_16b, }, - [BOARD_PCI1760] = { + [TYPE_PCI1760] = { /* This card has its own 'attach' */ .name = "pci1760", .main_pci_region = 0, @@ -405,7 +380,7 @@ static const struct dio_boardtype boardtypes[] = { .nsubdevs = 4, .io_access = IO_8b, }, - [BOARD_PCI1762] = { + [TYPE_PCI1762] = { .name = "pci1762", .main_pci_region = PCIDIO_MAINREG, .cardtype = TYPE_PCI1762, @@ -1083,6 +1058,39 @@ static int pci_dio_add_8254(struct comedi_device *dev, return 0; } +static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev, + unsigned long cardtype) +{ + /* + * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion + * board available. Need to enable PCI device and request the main + * registers PCI BAR temporarily to perform the test. + */ + if (cardtype != TYPE_PCI1753) + return cardtype; + if (pci_enable_device(pcidev) < 0) + return cardtype; + if (pci_request_region(pcidev, PCIDIO_MAINREG, "adv_pci_dio") == 0) { + /* + * This test is based on Advantech's "advdaq" driver source + * (which declares its module licence as "GPL" although the + * driver source does not include a "COPYING" file). + */ + unsigned long reg = + pci_resource_start(pcidev, PCIDIO_MAINREG) + 53; + + outb(0x05, reg); + if ((inb(reg) & 0x07) == 0x02) { + outb(0x02, reg); + if ((inb(reg) & 0x07) == 0x05) + cardtype = TYPE_PCI1753E; + } + pci_release_region(pcidev, PCIDIO_MAINREG); + } + pci_disable_device(pcidev); + return cardtype; +} + static int pci_dio_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -1193,25 +1201,27 @@ static struct comedi_driver adv_pci_dio_driver = { static int adv_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &adv_pci_dio_driver, - id->driver_data); + unsigned long cardtype; + + cardtype = pci_dio_override_cardtype(dev, id->driver_data); + return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype); } static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { - { PCI_VDEVICE(ADVANTECH, 0x1730), BOARD_PCI1730 }, - { PCI_VDEVICE(ADVANTECH, 0x1733), BOARD_PCI1733 }, - { PCI_VDEVICE(ADVANTECH, 0x1734), BOARD_PCI1734 }, - { PCI_VDEVICE(ADVANTECH, 0x1735), BOARD_PCI1735 }, - { PCI_VDEVICE(ADVANTECH, 0x1736), BOARD_PCI1736 }, - { PCI_VDEVICE(ADVANTECH, 0x1739), BOARD_PCI1739 }, - { PCI_VDEVICE(ADVANTECH, 0x1750), BOARD_PCI1750 }, - { PCI_VDEVICE(ADVANTECH, 0x1751), BOARD_PCI1751 }, - { PCI_VDEVICE(ADVANTECH, 0x1752), BOARD_PCI1752 }, - { PCI_VDEVICE(ADVANTECH, 0x1753), BOARD_PCI1753 }, - { PCI_VDEVICE(ADVANTECH, 0x1754), BOARD_PCI1754 }, - { PCI_VDEVICE(ADVANTECH, 0x1756), BOARD_PCI1756 }, - { PCI_VDEVICE(ADVANTECH, 0x1760), BOARD_PCI1760 }, - { PCI_VDEVICE(ADVANTECH, 0x1762), BOARD_PCI1762 }, + { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 }, + { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 }, + { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 }, + { PCI_VDEVICE(ADVANTECH, 0x1735), TYPE_PCI1735 }, + { PCI_VDEVICE(ADVANTECH, 0x1736), TYPE_PCI1736 }, + { PCI_VDEVICE(ADVANTECH, 0x1739), TYPE_PCI1739 }, + { PCI_VDEVICE(ADVANTECH, 0x1750), TYPE_PCI1750 }, + { PCI_VDEVICE(ADVANTECH, 0x1751), TYPE_PCI1751 }, + { PCI_VDEVICE(ADVANTECH, 0x1752), TYPE_PCI1752 }, + { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 }, + { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 }, + { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 }, + { PCI_VDEVICE(ADVANTECH, 0x1760), TYPE_PCI1760 }, + { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 }, { 0 } }; MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table); -- cgit From 71d92face4d7c0f292b089f0806bceddd6a1768e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 11:16:35 +0000 Subject: staging: comedi: ni_660x: reformat driver description comment Convert to preferred block comment style. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 40 +++++++++++++++----------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index f97a668143d8..0b6547ef7268 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -18,27 +18,25 @@ */ /* -Driver: ni_660x -Description: National Instruments 660x counter/timer boards -Devices: -[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, - PXI-6608 -Author: J.P. Mellor , - Herman.Bruyninckx@mech.kuleuven.ac.be, - Wim.Meeussen@mech.kuleuven.ac.be, - Klaas.Gadeyne@mech.kuleuven.ac.be, - Frank Mori Hess -Updated: Thu Oct 18 12:56:06 EDT 2007 -Status: experimental - -Encoders work. PulseGeneration (both single pulse and pulse train) -works. Buffered commands work for input but not output. - -References: -DAQ 660x Register-Level Programmer Manual (NI 370505A-01) -DAQ 6601/6602 User Manual (NI 322137B-01) - -*/ + * Driver: ni_660x + * Description: National Instruments 660x counter/timer boards + * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, + * PXI-6608 + * Author: J.P. Mellor , + * Herman.Bruyninckx@mech.kuleuven.ac.be, + * Wim.Meeussen@mech.kuleuven.ac.be, + * Klaas.Gadeyne@mech.kuleuven.ac.be, + * Frank Mori Hess + * Updated: Thu Oct 18 12:56:06 EDT 2007 + * Status: experimental + * + * Encoders work. PulseGeneration (both single pulse and pulse train) + * works. Buffered commands work for input but not output. + * + * References: + * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) + * DAQ 6601/6602 User Manual (NI 322137B-01) + */ #include #include -- cgit From 8bdfefb7849c563e05aa60a4649cf4d0987b97b4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 11:16:36 +0000 Subject: staging: comedi: ni_660x: support NI PXI-6624 Florent Boudet reports success using a NI PXI-6624 board with a trivially modified version of the "ni_660x" driver (addition to the PCI device ID table and comedi board table). He did this with the out-of-tree Comedi drivers at www.comedi.org, but it applies equally to the in-tree "staging" drivers. He reports the PXI-6624 is basically the same as the PXI-6602, but with isolated channels and external voltage source. Add support for NI PXI-6224 to the "ni_660x" driver. (Maybe the driver should be renamed to "ni_66xx"?) Signed-off-by: Ian Abbott Cc: Florent Boudet Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 109168ca9c36..7841399bf1b3 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -993,7 +993,7 @@ config COMEDI_NI_660X select COMEDI_NI_TIOCMD ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, - PXI-6602 and PXI-6608. + PXI-6602, PXI-6608 and PXI-6624. To compile this driver as a module, choose M here: the module will be called ni_660x. diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 0b6547ef7268..43b7ea8970a6 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -21,13 +21,13 @@ * Driver: ni_660x * Description: National Instruments 660x counter/timer boards * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, - * PXI-6608 + * PXI-6608, PXI-6624 * Author: J.P. Mellor , * Herman.Bruyninckx@mech.kuleuven.ac.be, * Wim.Meeussen@mech.kuleuven.ac.be, * Klaas.Gadeyne@mech.kuleuven.ac.be, * Frank Mori Hess - * Updated: Thu Oct 18 12:56:06 EDT 2007 + * Updated: Fri, 15 Mar 2013 10:47:56 +0000 * Status: experimental * * Encoders work. PulseGeneration (both single pulse and pulse train) @@ -392,6 +392,7 @@ enum ni_660x_boardid { BOARD_PCI6602, BOARD_PXI6602, BOARD_PXI6608, + BOARD_PXI6624 }; struct ni_660x_board { @@ -416,6 +417,10 @@ static const struct ni_660x_board ni_660x_boards[] = { .name = "PXI-6608", .n_chips = 2, }, + [BOARD_PXI6624] = { + .name = "PXI-6624", + .n_chips = 2, + }, }; #define NI_660X_MAX_NUM_CHIPS 2 @@ -1326,6 +1331,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 }, + { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 }, { 0 } }; MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); -- cgit From a7401cddcdf739d3cb9598c9b3787a732fc87809 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 13:15:33 +0000 Subject: staging: comedi: make 'dev->attached' a bool bit-field Change the `attached` member of `struct comedi_device` to a 1-bit bit-field of type `bool`. Change assigned values to `true` and `false` and replace or remove comparison operations with simple boolean tests. We'll put some extra bit-fields in the gap later to save space. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 +- drivers/staging/comedi/drivers.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/das16.c | 2 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/das1800.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_at_a2150.c | 2 +- drivers/staging/comedi/drivers/ni_labpc.c | 2 +- drivers/staging/comedi/drivers/ni_mio_common.c | 2 +- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index f638381fe424..bdd2936e509b 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -207,7 +207,7 @@ struct comedi_device { const char *board_name; const void *board_ptr; - int attached; + bool attached:1; spinlock_t spinlock; struct mutex mutex; int in_request_module; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 64be7c5e891e..87052735d91c 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -120,7 +120,7 @@ static void cleanup_device(struct comedi_device *dev) static void __comedi_device_detach(struct comedi_device *dev) { - dev->attached = 0; + dev->attached = false; if (dev->driver) dev->driver->detach(dev); else @@ -290,7 +290,7 @@ static int comedi_device_postconfig(struct comedi_device *dev) dev->board_name = "BUG"; } smp_wmb(); - dev->attached = 1; + dev->attached = true; return 0; } diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 7a23d56645e7..c19e4b2004f8 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1341,7 +1341,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) static const int timeout = 10000; unsigned long flags; - if (dev->attached == 0) + if (!dev->attached) return IRQ_NONE; async = s->async; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 46b6af4c517d..6988f5b7fd70 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3113,7 +3113,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ - if (dev->attached == 0) { + if (!dev->attached) { DEBUG_PRINT("premature interrupt, ignoring\n"); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index f238a1fbccbf..caeaee8d4840 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -876,7 +876,7 @@ static void das16_interrupt(struct comedi_device *dev) int num_bytes, residue; int buffer_index; - if (dev->attached == 0) { + if (!dev->attached) { comedi_error(dev, "premature interrupt"); return; } diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index b0a861a779bd..7ba8fc7a02f6 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -499,7 +499,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d) int status; struct comedi_device *dev = d; - if (dev->attached == 0) { + if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 7900f959555d..d01e140885d8 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -731,7 +731,7 @@ static irqreturn_t das1800_interrupt(int irq, void *d) struct comedi_device *dev = d; unsigned int status; - if (dev->attached == 0) { + if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 43b7ea8970a6..440cfd17ee3a 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -887,7 +887,7 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) unsigned i; unsigned long flags; - if (dev->attached == 0) + if (!dev->attached) return IRQ_NONE; /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&devpriv->interrupt_lock, flags); diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 06de25bb2f56..2a4a7a472142 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -204,7 +204,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) short dpnt; static const int sample_size = sizeof(devpriv->dma_buffer[0]); - if (dev->attached == 0) { + if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 78f01709e222..d2edaad4ddbe 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1367,7 +1367,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) struct comedi_async *async; struct comedi_cmd *cmd; - if (dev->attached == 0) { + if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 208fa24295ae..ca52b759fb9e 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -847,7 +847,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) struct mite_struct *mite = devpriv->mite; #endif - if (dev->attached == 0) + if (!dev->attached) return IRQ_NONE; smp_mb(); /* make sure dev->attached is checked before handler does anything else. */ diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 2298d6ee12ef..3e3a03c49681 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -420,7 +420,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) unsigned int m_status = 0; /* interrupcions parasites */ - if (dev->attached == 0) { + if (!dev->attached) { /* assume it's from another card */ return IRQ_NONE; } diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index cd164ee3a5e1..d1560524fc14 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -758,7 +758,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) uint8_t group; uint16_t irqbit; - if (dev->attached == 0) + if (!dev->attached) return IRQ_NONE; /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&dev->spinlock, flags); -- cgit From 13f12b5aea501bce146cdf213d1819083aadc847 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 13:15:34 +0000 Subject: staging: comedi: make 'in_request_module' a bool bit-field Change the `in_request_module` member of `struct comedi_device` to a 1-bit bit-field of type `bool` and move it into a suitable hole in the data type to save a few bytes. Change the assigned values to `true` and `false`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 12 ++++++------ drivers/staging/comedi/comedidev.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e336b281b847..6bcbb52510ef 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2067,12 +2067,12 @@ static int comedi_open(struct inode *inode, struct file *file) /* This is slightly hacky, but we want module autoloading * to work for root. * case: user opens device, attached -> ok - * case: user opens device, unattached, in_request_module=0 -> autoload - * case: user opens device, unattached, in_request_module=1 -> fail + * case: user opens device, unattached, !in_request_module -> autoload + * case: user opens device, unattached, in_request_module -> fail * case: root opens device, attached -> ok - * case: root opens device, unattached, in_request_module=1 -> ok + * case: root opens device, unattached, in_request_module -> ok * (typically called from modprobe) - * case: root opens device, unattached, in_request_module=0 -> autoload + * case: root opens device, unattached, !in_request_module -> autoload * * The last could be changed to "-> ok", which would deny root * autoloading. @@ -2088,7 +2088,7 @@ static int comedi_open(struct inode *inode, struct file *file) if (capable(CAP_NET_ADMIN) && dev->in_request_module) goto ok; - dev->in_request_module = 1; + dev->in_request_module = true; #ifdef CONFIG_KMOD mutex_unlock(&dev->mutex); @@ -2096,7 +2096,7 @@ static int comedi_open(struct inode *inode, struct file *file) mutex_lock(&dev->mutex); #endif - dev->in_request_module = 0; + dev->in_request_module = false; if (!dev->attached && !capable(CAP_NET_ADMIN)) { DPRINTK("not attached and not CAP_NET_ADMIN\n"); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index bdd2936e509b..86de4ff9501a 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -208,9 +208,9 @@ struct comedi_device { const char *board_name; const void *board_ptr; bool attached:1; + bool in_request_module:1; spinlock_t spinlock; struct mutex mutex; - int in_request_module; int n_subdevices; struct comedi_subdevice *subdevices; -- cgit From 00ca6884186f18a758eae37e94f7c3c0527f8f30 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 13:15:35 +0000 Subject: staging: comedi: add 'ioenabled' flag to device Add 1-bit bit-field member `ioenabled` of type `bool` to `struct comedi_device`. Use this to keep track of whether a PCI device and its BARs have been successfully enabled by `comedi_pci_enable()`. This avoids overloading the meaning of the `iobase` member which is used by several drivers to hold the base port I/O address of a board's "main" registers. Other drivers using MMIO use `iobase` as a flag to indicate that the preceding call to `comedi_pci_enable()` was successful. They no longer need to do that. The name `ioenabled` is intended to be PCI-agnostic so it can be used for similar purposes by non-PCI drivers. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_pci.c | 5 ++++- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index b164b0353ebe..6f3cdf88f05e 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -55,6 +55,8 @@ int comedi_pci_enable(struct comedi_device *dev) : dev->driver->driver_name); if (rc < 0) pci_disable_device(pcidev); + else + dev->ioenabled = true; return rc; } @@ -68,10 +70,11 @@ void comedi_pci_disable(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (pcidev && dev->iobase) { + if (pcidev && dev->ioenabled) { pci_release_regions(pcidev); pci_disable_device(pcidev); } + dev->ioenabled = false; } EXPORT_SYMBOL_GPL(comedi_pci_disable); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 86de4ff9501a..9c8662a051dc 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -209,6 +209,7 @@ struct comedi_device { const void *board_ptr; bool attached:1; bool in_request_module:1; + bool ioenabled:1; spinlock_t spinlock; struct mutex mutex; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 87052735d91c..4724f275830c 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -110,6 +110,7 @@ static void cleanup_device(struct comedi_device *dev) dev->board_name = NULL; dev->board_ptr = NULL; dev->iobase = 0; + dev->ioenabled = false; dev->irq = 0; dev->read_subdev = NULL; dev->write_subdev = NULL; -- cgit From 84b44d08993ffe762d9a86ee2243239350b871a4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 13:15:36 +0000 Subject: staging: comedi: remove unneeded settings of `dev->iobase` Some PCI drivers use the "spare" `iobase` member of `struct comedi_device` as a flag to indicate that the call to `comedi_pci_enable()` was successful. This is no longer necessary now that `comedi_pci_enable()` and `comedi_pci_disable()` use the `ioenabled` member of `struct comedi_device` themselves to keep track of what needs to be done. Remove the unnecessary assignments to the `iobase` member in the relevant drivers. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 1 - drivers/staging/comedi/drivers/daqboard2000.c | 1 - drivers/staging/comedi/drivers/dt3000.c | 1 - drivers/staging/comedi/drivers/gsc_hpdi.c | 1 - drivers/staging/comedi/drivers/jr3_pci.c | 1 - drivers/staging/comedi/drivers/me_daq.c | 1 - drivers/staging/comedi/drivers/ni_6527.c | 1 - drivers/staging/comedi/drivers/ni_65xx.c | 1 - drivers/staging/comedi/drivers/ni_660x.c | 1 - drivers/staging/comedi/drivers/ni_670x.c | 1 - drivers/staging/comedi/drivers/ni_labpc.c | 1 - drivers/staging/comedi/drivers/ni_pcidio.c | 1 - drivers/staging/comedi/drivers/ni_pcimio.c | 1 - drivers/staging/comedi/drivers/rtd520.c | 1 - drivers/staging/comedi/drivers/s626.c | 1 - 15 files changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index c19e4b2004f8..cdbeb0833d0b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1458,7 +1458,6 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv->s5933_config = pci_resource_start(pcidev, 0); devpriv->control_status = pci_resource_start(pcidev, 1); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 7c549eb442f8..a0ec8bd5c01d 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -712,7 +712,6 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, result = comedi_pci_enable(dev); if (result) return result; - dev->iobase = 1; /* the "detach" needs this */ devpriv->plx = ioremap(pci_resource_start(pcidev, 0), pci_resource_len(pcidev, 0)); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index edbcd89aff9d..909656ba51b5 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -738,7 +738,6 @@ static int dt3000_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret < 0) return ret; - dev->iobase = 1; /* the "detach" needs this */ pci_base = pci_resource_start(pcidev, 0); devpriv->io_addr = ioremap(pci_base, DT3000_SIZE); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 16b4cc050d35..ba44d0375c20 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -502,7 +502,6 @@ static int hpdi_auto_attach(struct comedi_device *dev, retval = comedi_pci_enable(dev); if (retval) return retval; - dev->iobase = 1; /* the "detach" needs this */ pci_set_master(pcidev); devpriv->plx9080_iobase = diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 36659e500f40..f21ebb536a2d 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -705,7 +705,6 @@ static int jr3_pci_auto_attach(struct comedi_device *dev, result = comedi_pci_enable(dev); if (result) return result; - dev->iobase = 1; /* the "detach" needs this */ devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), offsetof(struct jr3_t, diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index fbbac1259ebd..5df4f55dbaea 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -514,7 +514,6 @@ static int me_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; /* detach needs this */ dev_private->plx_regbase = ioremap(pci_resource_start(pcidev, 0), pci_resource_len(pcidev, 0)); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 65dd1c68721a..d10f777b7f17 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -339,7 +339,6 @@ static int ni6527_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index eec712e5e138..013392cfe2a1 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -603,7 +603,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 440cfd17ee3a..5cdda7fe97a7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1180,7 +1180,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; ret = ni_660x_allocate_private(dev); if (ret < 0) diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 524f6cd72687..e9d486238c85 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -211,7 +211,6 @@ static int ni_670x_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index d2edaad4ddbe..62ec39dea97d 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -711,7 +711,6 @@ static int labpc_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 3e3a03c49681..b5f340c186ec 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1115,7 +1115,6 @@ static int nidio_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 098c398f2bea..bc83df53872e 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1491,7 +1491,6 @@ static int pcimio_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; ret = ni_alloc_private(dev); if (ret) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index c0935d4a89c1..b1d888eb61f7 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1286,7 +1286,6 @@ static int rtd_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; /* the "detach" needs this */ devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2), pci_resource_len(pcidev, 2)); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index d1560524fc14..7d009463b92d 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2676,7 +2676,6 @@ static int s626_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; /* detach needs this */ devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0), pci_resource_len(pcidev, 0)); -- cgit From a14592896023adcab12307774c89284ce0744ce2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 15 Mar 2013 13:39:52 +0000 Subject: staging: comedi: ni_labpc: fix common detach `labpc_common_detach()` calls `comedi_pci_disable()` unconditionally. That's okay for PCI devices and harmless for ISA devices (as the `hw_dev` member will be NULL so `comedi_to_pci_dev()` will return NULL and `comedi_pci_disable()` checks for that), but it is disastrous for PCMCIA devices. Those are managed by the "ni_labpc_cs" module but it calls this `labpc_common_detach()` and the `hw_dev` member will be pointing to the `struct device` embedded in a `struct pcmcia_device` in that case. That's enough to confuse `comedi_pci_disable()` into thinking it's a valid PCI device to be disabled. Use the private board information (`thisboard`) to make sure it is a PCI device before calling `comedi_pci_disable()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 62ec39dea97d..152dc844fa96 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -804,7 +804,8 @@ void labpc_common_detach(struct comedi_device *dev) mite_unsetup(devpriv->mite); mite_free(devpriv->mite); } - comedi_pci_disable(dev); + if (thisboard->bustype == pci_bustype) + comedi_pci_disable(dev); #endif }; EXPORT_SYMBOL_GPL(labpc_common_detach); -- cgit From 8f46baaa7ec6cd0851794020b31958e64679dd26 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 20 Feb 2013 10:31:42 +0200 Subject: base: core: WARN() about bogus permissions on device attributes Whenever a struct device_attribute is registered with mismatched permissions - read permission without a show routine or write permission without store routine - we will issue a big warning so we catch those early enough. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 56536f4b0f6b..a7391a30cb29 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -563,8 +563,15 @@ int device_create_file(struct device *dev, const struct device_attribute *attr) { int error = 0; - if (dev) + + if (dev) { + WARN(((attr->attr.mode & S_IWUGO) && !attr->store), + "Write permission without 'store'\n"); + WARN(((attr->attr.mode & S_IRUGO) && !attr->show), + "Read permission without 'show'\n"); error = sysfs_create_file(&dev->kobj, &attr->attr); + } + return error; } -- cgit From c8c8d080ed94cea6757f2d781b6e360a74b256fd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 11 Mar 2013 18:27:02 +0200 Subject: mei: revamp mei_data2slots 1. Move the mei_data2slots to mei_dev.h as it will be used by the all supported HW. 2. Change return value from u8 to u32 to catch possible overflows 3. Eliminate computing the slots number twice in the same function Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 11 +++++----- drivers/misc/mei/hw-me.c | 3 ++- drivers/misc/mei/hw-me.h | 6 ------ drivers/misc/mei/interrupt.c | 50 +++++++++++++++++++++++++------------------- drivers/misc/mei/mei_dev.h | 11 ++++++++++ 5 files changed, 47 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index c86d7e3839a4..9a5e8c72628b 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -449,7 +449,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; - size_t msg_slots = mei_data2slots(len); + u32 msg_slots = mei_data2slots(len); mei_hdr.host_addr = cl->host_client_id; mei_hdr.me_addr = cl->me_client_id; @@ -566,12 +566,13 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, */ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) { + u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); - if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) - + sizeof(struct hbm_flow_control))) { + if (*slots < msg_slots) return -EMSGSIZE; - } - *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); + + *slots -= msg_slots; + if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); return -EIO; diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 45ea7185c003..d21e5a761f2c 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -295,10 +295,11 @@ static int mei_me_write_message(struct mei_device *dev, unsigned char *buf) { struct mei_me_hw *hw = to_me_hw(dev); - unsigned long rem, dw_cnt; + unsigned long rem; unsigned long length = header->length; u32 *reg_buf = (u32 *)buf; u32 hcsr; + u32 dw_cnt; int i; int empty_slots; diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 8518d3eeb838..80bd829fbd9a 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -36,12 +36,6 @@ struct mei_me_hw { struct mei_device *mei_me_dev_init(struct pci_dev *pdev); -/* get slots (dwords) from a message length + header (bytes) */ -static inline unsigned char mei_data2slots(size_t length) -{ - return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); -} - irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id); irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 3535b2676c97..14c70b8815d8 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -153,25 +153,27 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request))) - return -EBADMSG; + u32 msg_slots = + mei_data2slots(sizeof(struct hbm_client_connect_request)); - *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); + if (*slots < msg_slots) + return -EMSGSIZE; + + *slots -= msg_slots; if (mei_hbm_cl_disconnect_req(dev, cl)) { cl->status = 0; cb_pos->buf_idx = 0; list_move_tail(&cb_pos->list, &cmpl_list->list); - return -EMSGSIZE; - } else { - cl->state = MEI_FILE_DISCONNECTING; - cl->status = 0; - cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); - cl->timer_count = MEI_CONNECT_TIMEOUT; + return -EIO; } + cl->state = MEI_FILE_DISCONNECTING; + cl->status = 0; + cb_pos->buf_idx = 0; + list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); + cl->timer_count = MEI_CONNECT_TIMEOUT; + return 0; } @@ -192,14 +194,15 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control))) { + u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); + + if (*slots < msg_slots) { /* return the cancel routine */ list_del(&cb_pos->list); - return -EBADMSG; + return -EMSGSIZE; } - *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); + *slots -= msg_slots; if (mei_hbm_cl_flow_control_req(dev, cl)) { cl->status = -ENODEV; @@ -229,15 +232,19 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_cl_cb *cmpl_list) { - if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request))) { + u32 msg_slots = + mei_data2slots(sizeof(struct hbm_client_connect_request)); + + if (*slots < msg_slots) { /* return the cancel routine */ list_del(&cb_pos->list); - return -EBADMSG; + return -EMSGSIZE; } + *slots -= msg_slots; + cl->state = MEI_FILE_CONNECTING; - *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); + if (mei_hbm_cl_connect_req(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; @@ -266,7 +273,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, struct mei_msg_hdr mei_hdr; struct mei_cl *cl = cb->cl; size_t len = cb->request_buffer.size - cb->buf_idx; - size_t msg_slots = mei_data2slots(len); + u32 msg_slots = mei_data2slots(len); mei_hdr.host_addr = cl->host_client_id; mei_hdr.me_addr = cl->me_client_id; @@ -419,8 +426,7 @@ end: * * returns 0 on success, <0 on failure. */ -int mei_irq_write_handler(struct mei_device *dev, - struct mei_cl_cb *cmpl_list) +int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) { struct mei_cl *cl; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index cb80166161f0..09a2af4294a6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -374,6 +374,17 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) return msecs_to_jiffies(sec * MSEC_PER_SEC); } +/** + * mei_data2slots - get slots - number of (dwords) from a message length + * + size of the mei header + * @length - size of the messages in bytes + * returns - number of slots + */ +static inline u32 mei_data2slots(size_t length) +{ + return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4); +} + /* * mei init function prototypes -- cgit From aafae7ecd80181983403de13db0b4895acdc233d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 11 Mar 2013 18:27:03 +0200 Subject: mei: add hw start callback This callback wraps up hardware dependent details of the hardware initialization. This callback also contains host ready setting so we can remove host_set_ready callback In ME we switch to waiting on event so we can streamline the initialization flow. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 45 ++++++++++++++++++++++++++++++++++++--------- drivers/misc/mei/init.c | 16 ++++++++++++++++ drivers/misc/mei/mei_dev.h | 16 ++++++++++------ 3 files changed, 62 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index d21e5a761f2c..df9b43d81eea 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -222,6 +222,38 @@ static bool mei_me_hw_is_ready(struct mei_device *dev) return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; } +static int mei_me_hw_ready_wait(struct mei_device *dev) +{ + int err; + if (mei_me_hw_is_ready(dev)) + return 0; + + mutex_unlock(&dev->device_lock); + err = wait_event_interruptible_timeout(dev->wait_hw_ready, + dev->recvd_hw_ready, MEI_INTEROP_TIMEOUT); + mutex_lock(&dev->device_lock); + if (!err && !dev->recvd_hw_ready) { + dev_err(&dev->pdev->dev, + "wait hw ready failed. status = 0x%x\n", err); + return -ETIMEDOUT; + } + + dev->recvd_hw_ready = false; + return 0; +} + +static int mei_me_hw_start(struct mei_device *dev) +{ + int ret = mei_me_hw_ready_wait(dev); + if (ret) + return ret; + dev_dbg(&dev->pdev->dev, "hw is ready\n"); + + mei_me_host_set_ready(dev); + return ret; +} + + /** * mei_hbuf_filled_slots - gets number of device filled buffer slots * @@ -456,14 +488,9 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) if (mei_hw_is_ready(dev)) { dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); - mei_host_set_ready(dev); - - dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); - /* link is established * start sending messages. */ - - dev->dev_state = MEI_DEV_INIT_CLIENTS; + dev->recvd_hw_ready = true; + wake_up_interruptible(&dev->wait_hw_ready); - mei_hbm_start_req(dev); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } else { @@ -521,12 +548,12 @@ end: } static const struct mei_hw_ops mei_me_hw_ops = { - .host_set_ready = mei_me_host_set_ready, .host_is_ready = mei_me_host_is_ready, .hw_is_ready = mei_me_hw_is_ready, .hw_reset = mei_me_hw_reset, - .hw_config = mei_me_hw_config, + .hw_config = mei_me_hw_config, + .hw_start = mei_me_hw_start, .intr_clear = mei_me_intr_clear, .intr_enable = mei_me_intr_enable, diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 6ec530168afb..fc3d97ce8300 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -22,6 +22,7 @@ #include #include "mei_dev.h" +#include "hbm.h" #include "client.h" const char *mei_dev_state_str(int state) @@ -47,6 +48,7 @@ void mei_device_init(struct mei_device *dev) /* setup our list array */ INIT_LIST_HEAD(&dev->file_list); mutex_init(&dev->device_lock); + init_waitqueue_head(&dev->wait_hw_ready); init_waitqueue_head(&dev->wait_recvd_msg); init_waitqueue_head(&dev->wait_stop_wd); dev->dev_state = MEI_DEV_INITIALIZING; @@ -176,6 +178,20 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", mei_dev_state_str(dev->dev_state)); + if (!interrupts_enabled) { + dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n"); + return; + } + + mei_hw_start(dev); + + dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); + /* link is established * start sending messages. */ + + dev->dev_state = MEI_DEV_INIT_CLIENTS; + + mei_hbm_start_req(dev); + /* wake up all readings so they can be interrupted */ mei_cl_all_read_wakeup(dev); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 09a2af4294a6..5c30857e91d5 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -213,11 +213,11 @@ struct mei_cl { /** struct mei_hw_ops * - * @host_set_ready - notify FW that host side is ready * @host_is_ready - query for host readiness * @hw_is_ready - query if hw is ready * @hw_reset - reset hw + * @hw_start - start hw after reset * @hw_config - configure hw * @intr_clear - clear pending interrupts @@ -237,11 +237,11 @@ struct mei_cl { */ struct mei_hw_ops { - void (*host_set_ready) (struct mei_device *dev); bool (*host_is_ready) (struct mei_device *dev); bool (*hw_is_ready) (struct mei_device *dev); void (*hw_reset) (struct mei_device *dev, bool enable); + int (*hw_start) (struct mei_device *dev); void (*hw_config) (struct mei_device *dev); void (*intr_clear) (struct mei_device *dev); @@ -296,11 +296,14 @@ struct mei_device { */ struct mutex device_lock; /* device lock */ struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ + + bool recvd_hw_ready; bool recvd_msg; /* * waiting queue for receive message from FW */ + wait_queue_head_t wait_hw_ready; wait_queue_head_t wait_recvd_msg; wait_queue_head_t wait_stop_wd; @@ -465,6 +468,11 @@ static inline void mei_hw_reset(struct mei_device *dev, bool enable) dev->ops->hw_reset(dev, enable); } +static inline void mei_hw_start(struct mei_device *dev) +{ + dev->ops->hw_start(dev); +} + static inline void mei_clear_interrupts(struct mei_device *dev) { dev->ops->intr_clear(dev); @@ -480,10 +488,6 @@ static inline void mei_disable_interrupts(struct mei_device *dev) dev->ops->intr_disable(dev); } -static inline void mei_host_set_ready(struct mei_device *dev) -{ - dev->ops->host_set_ready(dev); -} static inline bool mei_host_is_ready(struct mei_device *dev) { return dev->ops->host_is_ready(dev); -- cgit From 9f7345b7a7cbf4c78a8161cba21de1772d5ad56e Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Thu, 14 Mar 2013 11:12:10 +0200 Subject: memory: tegra30: Fix build error w/o PM Make this depend on CONFIG_PM. Signed-off-by: Hiroshi Doyu Reviewed-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/memory/tegra30-mc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c index 0b975986777d..f4ae074badc3 100644 --- a/drivers/memory/tegra30-mc.c +++ b/drivers/memory/tegra30-mc.c @@ -268,6 +268,7 @@ static const u32 tegra30_mc_ctx[] = { MC_INTMASK, }; +#ifdef CONFIG_PM static int tegra30_mc_suspend(struct device *dev) { int i; @@ -291,6 +292,7 @@ static int tegra30_mc_resume(struct device *dev) mc_readl(mc, MC_TIMING_CONTROL); return 0; } +#endif static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm, tegra30_mc_suspend, -- cgit From 0c75948249a05ebfa3214aaf5b8247ec919c30ac Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 5 Mar 2013 11:02:21 +0900 Subject: misc: arm-charlcd: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Acked-by: Linus Walleij Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/arm-charlcd.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c index fe8616a8d287..48651ef0028c 100644 --- a/drivers/misc/arm-charlcd.c +++ b/drivers/misc/arm-charlcd.c @@ -378,18 +378,7 @@ static struct platform_driver charlcd_driver = { .remove = __exit_p(charlcd_remove), }; -static int __init charlcd_init(void) -{ - return platform_driver_probe(&charlcd_driver, charlcd_probe); -} - -static void __exit charlcd_exit(void) -{ - platform_driver_unregister(&charlcd_driver); -} - -module_init(charlcd_init); -module_exit(charlcd_exit); +module_platform_driver_probe(charlcd_driver, charlcd_probe); MODULE_AUTHOR("Linus Walleij "); MODULE_DESCRIPTION("ARM Character LCD Driver"); -- cgit From 4022ed5a7222a400f813cfecfa5ecca40c708f69 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 5 Mar 2013 11:03:18 +0900 Subject: misc: atmel_pwm: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/atmel_pwm.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c index 28f5aaa19d4a..494d0500bda6 100644 --- a/drivers/misc/atmel_pwm.c +++ b/drivers/misc/atmel_pwm.c @@ -393,17 +393,7 @@ static struct platform_driver atmel_pwm_driver = { */ }; -static int __init pwm_init(void) -{ - return platform_driver_probe(&atmel_pwm_driver, pwm_probe); -} -module_init(pwm_init); - -static void __exit pwm_exit(void) -{ - platform_driver_unregister(&atmel_pwm_driver); -} -module_exit(pwm_exit); +module_platform_driver_probe(atmel_pwm_driver, pwm_probe); MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module"); MODULE_LICENSE("GPL"); -- cgit From ead050dec6b0765357e45287f02ef8e51f69c3ed Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 5 Mar 2013 11:04:07 +0900 Subject: misc: ep93xx_pwm: use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ep93xx_pwm.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c index 16d7179e2f9b..96787ec15cad 100644 --- a/drivers/misc/ep93xx_pwm.c +++ b/drivers/misc/ep93xx_pwm.c @@ -365,18 +365,7 @@ static struct platform_driver ep93xx_pwm_driver = { .remove = __exit_p(ep93xx_pwm_remove), }; -static int __init ep93xx_pwm_init(void) -{ - return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe); -} - -static void __exit ep93xx_pwm_exit(void) -{ - platform_driver_unregister(&ep93xx_pwm_driver); -} - -module_init(ep93xx_pwm_init); -module_exit(ep93xx_pwm_exit); +module_platform_driver_probe(ep93xx_pwm_driver, ep93xx_pwm_probe); MODULE_AUTHOR("Matthieu Crapet , " "H Hartley Sweeten "); -- cgit From d87c3f057922e616c0449aac518da200355c84e9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 27 Feb 2013 11:41:41 -0800 Subject: misc/vmw_vmci: Add dependency on CONFIG_NET Building the vmw_vmci driver with CONFIG_NET undefined results in: drivers/built-in.o: In function `__qp_memcpy_from_queue.isra.13': vmci_queue_pair.c:(.text+0x1671a8): undefined reference to `memcpy_toiovec' drivers/built-in.o: In function `__qp_memcpy_to_queue.isra.14': vmci_queue_pair.c:(.text+0x167341): undefined reference to `memcpy_fromiovec' make[1]: [vmlinux] Error 1 (ignored) since memcpy_toiovec and memcpy_fromiovec are defined in the networking code. Add the missing dependency. Signed-off-by: Guenter Roeck Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/vmw_vmci/Kconfig b/drivers/misc/vmw_vmci/Kconfig index 39c2ecadb273..ea98f7e9ccd1 100644 --- a/drivers/misc/vmw_vmci/Kconfig +++ b/drivers/misc/vmw_vmci/Kconfig @@ -4,7 +4,7 @@ config VMWARE_VMCI tristate "VMware VMCI Driver" - depends on X86 && PCI + depends on X86 && PCI && NET help This is VMware's Virtual Machine Communication Interface. It enables high-speed communication between host and guest in a virtual -- cgit From ff9c351f96168a90d5a8239c350b565059e68be1 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 27 Feb 2013 13:56:16 +0800 Subject: drivers/misc: beautify code: chip->lux_calib is u16 which will never more than APDS_RANGE APDS_RANGE is 65535, chip->lux_calib is u16 (never more than APDS_RANGE). Signed-off-by: Chen Gang Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds990x.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 0e67f8263cd8..1efb6a4ea397 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -700,9 +700,6 @@ static ssize_t apds990x_lux_calib_store(struct device *dev, if (strict_strtoul(buf, 0, &value)) return -EINVAL; - if (chip->lux_calib > APDS_RANGE) - return -EINVAL; - chip->lux_calib = value; return len; -- cgit From 61084d992733e8f87f7278c71cdb93869fad9c17 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 15 Mar 2013 16:24:10 +0100 Subject: misc: Remove max8997-muic.o Makefile line again Commit 20259849bb1ac1ffb0156eb359810e8b99cb644d ("VMCI: Some header and config files.") readded this Makefile line. Remove it again. Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 35a1463c72d9..3e2faa0939b2 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,6 +49,5 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI) += mei/ -obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o -- cgit From 7a4541a6591d8b0f6d095ffd94c8ebae75ea57d7 Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Thu, 14 Mar 2013 18:09:35 +0100 Subject: drivers: memory: use module_platform_driver_probe() This patch converts the drivers to use the module_platform_driver_probe() macro which makes the code smaller and a bit simpler. Signed-off-by: Fabio Porcedda Cc: Benoit Cousson Cc: Aneesh V Signed-off-by: Greg Kroah-Hartman --- drivers/memory/emif.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index df0873694858..ecbc1a996eb6 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c @@ -1841,18 +1841,8 @@ static struct platform_driver emif_driver = { }, }; -static int __init_or_module emif_register(void) -{ - return platform_driver_probe(&emif_driver, emif_probe); -} - -static void __exit emif_unregister(void) -{ - platform_driver_unregister(&emif_driver); -} +module_platform_driver_probe(emif_driver, emif_probe); -module_init(emif_register); -module_exit(emif_unregister); MODULE_DESCRIPTION("TI EMIF SDRAM Controller Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:emif"); -- cgit From 3334948428c6370d664099cdcdfd4b487191293d Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:10:40 +0800 Subject: driver: hv: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 731158910c1e..ae4923756d98 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -289,9 +289,8 @@ void hv_synic_init(void *arg) /* Check the version */ rdmsrl(HV_X64_MSR_SVERSION, version); - hv_context.event_dpc[cpu] = (struct tasklet_struct *) - kmalloc(sizeof(struct tasklet_struct), - GFP_ATOMIC); + hv_context.event_dpc[cpu] = kmalloc(sizeof(struct tasklet_struct), + GFP_ATOMIC); if (hv_context.event_dpc[cpu] == NULL) { pr_err("Unable to allocate event dpc\n"); goto cleanup; -- cgit From 302beda9830f656c98afb25e26e94602b7a83fea Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Feb 2013 12:25:14 -0300 Subject: usb: chipidea: usbmisc_imx6q: Staticize usbmisc_imx6q_drv_init/exit() Staticize usbmisc_imx6q_drv_init/exit() to fix the following sparse warnings: drivers/usb/chipidea/usbmisc_imx6q.c:147:12: warning: symbol 'usbmisc_imx6q_drv_init' was not declared. Should it be static? drivers/usb/chipidea/usbmisc_imx6q.c:153:13: warning: symbol 'usbmisc_imx6q_drv_exit' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx6q.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c index a1bce391e825..113fcea77bdf 100644 --- a/drivers/usb/chipidea/usbmisc_imx6q.c +++ b/drivers/usb/chipidea/usbmisc_imx6q.c @@ -144,13 +144,13 @@ static struct platform_driver usbmisc_imx6q_driver = { }, }; -int __init usbmisc_imx6q_drv_init(void) +static int __init usbmisc_imx6q_drv_init(void) { return platform_driver_register(&usbmisc_imx6q_driver); } subsys_initcall(usbmisc_imx6q_drv_init); -void __exit usbmisc_imx6q_drv_exit(void) +static void __exit usbmisc_imx6q_drv_exit(void) { platform_driver_unregister(&usbmisc_imx6q_driver); } -- cgit From 9143b771f1ec2d677e536cdcdb732ef96d649d21 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Feb 2013 16:52:25 -0300 Subject: usb: host: ehci-mxc: Remove unneeded header file Since commit c0304996b (USB: ehci-mxc: remove Efika MX-specific CHRGVBUS hack) there is no need to include , so remove it. Signed-off-by: Fabio Estevam Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index e9301fb97eaa..18c30af69b16 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -28,11 +28,7 @@ #include #include #include - #include - -#include - #include "ehci.h" #define DRIVER_DESC "Freescale On-Chip EHCI Host driver" -- cgit From f1bffc8ca61853dad54da592aadfd28882c00a9e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Feb 2013 16:52:26 -0300 Subject: usb: host: ehci-mxc: Remove dev_info on probe It is not very useful to indicate the the driver is about to be probed. Quoting Alan Stern [1]: "Plenty of drivers don't include any message like this at all. You might as well get rid of it entirely." Remove such dev_info(). [1] http://marc.info/?l=linux-usb&m=136138896132433&w=2 Signed-off-by: Fabio Estevam Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 18c30af69b16..b5b7be45e301 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -57,8 +57,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ehci_hcd *ehci; - dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); - if (!pdata) { dev_err(dev, "No platform data given, bailing out.\n"); return -EINVAL; -- cgit From 77189df43114e85b563d039d0b7f23d4f8f71d79 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 13 Mar 2013 12:04:30 +0100 Subject: bluetooth: btmrvl_sdio: look for sd8688 firmware in proper location The firmware images are shared with libertas_sdio WiFi chip and used to be in libertas/ subtree in linux-firmware. As btmrvl_sdio used to look into the linux-firmware root, it ended up being unsuccessful. Since the firmware files are not specific to the libertas hardware, they're being moved into mrvl/ now. Signed-off-by: Lubomir Rintel Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- drivers/bluetooth/btmrvl_sdio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 9959d4cb23dc..1cb51839912d 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { }; static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { - .helper = "sd8688_helper.bin", - .firmware = "sd8688.bin", + .helper = "mrvl/sd8688_helper.bin", + .firmware = "mrvl/sd8688.bin", .reg = &btmrvl_reg_8688, .sd_blksz_fw_dl = 64, }; @@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE("sd8688_helper.bin"); -MODULE_FIRMWARE("sd8688.bin"); +MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); +MODULE_FIRMWARE("mrvl/sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); -- cgit From 8a7298d361827a1f244415dde62b1b07688d6a3a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 23 Feb 2013 10:11:35 -0500 Subject: usb/serial: Remove unnecessary check for console The tty port ops shutdown() routine is not called for console ports; remove extra check. Signed-off-by: Peter Hurley Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a19ed74d770d..8424478e0b76 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -256,22 +256,18 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * serial_down - shut down hardware * @tport: tty port to shut down * - * Shut down a USB serial port unless it is the console. We never - * shut down the console hardware as it will always be in use. Serialized - * against activate by the tport mutex and kept to matching open/close pairs + * Shut down a USB serial port. Serialized against activate by the + * tport mutex and kept to matching open/close pairs * of calls by the ASYNCB_INITIALIZED flag. + * + * Not called if tty is console. */ static void serial_down(struct tty_port *tport) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); struct usb_serial_driver *drv = port->serial->type; - /* - * The console is magical. Do not hang up the console hardware - * or there will be tears. - */ - if (port->port.console) - return; + if (drv->close) drv->close(port); } -- cgit From 39d35681d5380b403855202dcd75575a8d5b0ec1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 24 Feb 2013 00:55:07 -0800 Subject: USB: remove incorrect __exit markups Even if bus is not hot-pluggable, the devices can be unbound from the driver via sysfs, so we should not be using __exit annotations on remove() methods. The only exception is drivers registered with platform_driver_probe() which specifically disables sysfs bind/unbind attributes. Signed-off-by: Dmitry Torokhov Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 2 +- drivers/usb/host/ehci-orion.c | 4 ++-- drivers/usb/host/ehci-sh.c | 4 ++-- drivers/usb/otg/isp1301_omap.c | 4 ++-- drivers/usb/otg/twl4030-usb.c | 4 ++-- drivers/usb/otg/twl6030-usb.c | 4 ++-- drivers/usb/phy/mv_u3d_phy.c | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index b5b7be45e301..a38c8c8e5b0d 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -172,7 +172,7 @@ err_alloc: return ret; } -static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) +static int ehci_mxc_drv_remove(struct platform_device *pdev) { struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 914a3ecfb5d3..38c45fb3357e 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -305,7 +305,7 @@ err1: return err; } -static int __exit ehci_orion_drv_remove(struct platform_device *pdev) +static int ehci_orion_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct clk *clk; @@ -333,7 +333,7 @@ MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids); static struct platform_driver ehci_orion_driver = { .probe = ehci_orion_drv_probe, - .remove = __exit_p(ehci_orion_drv_remove), + .remove = ehci_orion_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "orion-ehci", diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 3565a300f401..e30e39672027 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -170,7 +170,7 @@ fail_create_hcd: return ret; } -static int __exit ehci_hcd_sh_remove(struct platform_device *pdev) +static int ehci_hcd_sh_remove(struct platform_device *pdev) { struct ehci_sh_priv *priv = platform_get_drvdata(pdev); struct usb_hcd *hcd = priv->hcd; @@ -196,7 +196,7 @@ static void ehci_hcd_sh_shutdown(struct platform_device *pdev) static struct platform_driver ehci_hcd_sh_driver = { .probe = ehci_hcd_sh_probe, - .remove = __exit_p(ehci_hcd_sh_remove), + .remove = ehci_hcd_sh_remove .shutdown = ehci_hcd_sh_shutdown, .driver = { .name = "sh_ehci", diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index af9cb11626b2..8b9de9581319 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1212,7 +1212,7 @@ static void isp1301_release(struct device *dev) static struct isp1301 *the_transceiver; -static int __exit isp1301_remove(struct i2c_client *i2c) +static int isp1301_remove(struct i2c_client *i2c) { struct isp1301 *isp; @@ -1634,7 +1634,7 @@ static struct i2c_driver isp1301_driver = { .name = "isp1301_omap", }, .probe = isp1301_probe, - .remove = __exit_p(isp1301_remove), + .remove = isp1301_remove, .id_table = isp1301_id, }; diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index a994715a3101..24d573a134b1 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -658,7 +658,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) return 0; } -static int __exit twl4030_usb_remove(struct platform_device *pdev) +static int twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; @@ -702,7 +702,7 @@ MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); static struct platform_driver twl4030_usb_driver = { .probe = twl4030_usb_probe, - .remove = __exit_p(twl4030_usb_remove), + .remove = twl4030_usb_remove, .driver = { .name = "twl4030_usb", .owner = THIS_MODULE, diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 8cd6cf49bdbd..7f3c5b0e3f66 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -393,7 +393,7 @@ static int twl6030_usb_probe(struct platform_device *pdev) return 0; } -static int __exit twl6030_usb_remove(struct platform_device *pdev) +static int twl6030_usb_remove(struct platform_device *pdev) { struct twl6030_usb *twl = platform_get_drvdata(pdev); @@ -420,7 +420,7 @@ MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); static struct platform_driver twl6030_usb_driver = { .probe = twl6030_usb_probe, - .remove = __exit_p(twl6030_usb_remove), + .remove = twl6030_usb_remove, .driver = { .name = "twl6030_usb", .owner = THIS_MODULE, diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c index 9d8599122aa9..bafd67f1f134 100644 --- a/drivers/usb/phy/mv_u3d_phy.c +++ b/drivers/usb/phy/mv_u3d_phy.c @@ -313,7 +313,7 @@ err: return ret; } -static int __exit mv_u3d_phy_remove(struct platform_device *pdev) +static int mv_u3d_phy_remove(struct platform_device *pdev) { struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev); -- cgit From bba90aedb00906a2f0d34325610729a1ee016f43 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 1 Mar 2013 08:14:19 +0300 Subject: usb: storage: onetouch: tighten a range check Smatch complains because we only allocate ONETOUCH_PKT_LEN (2) bytes but later when we call usb_fill_int_urb() we assume maxp can be up to 8 bytes. I talked to the maintainer and maxp should be capped at ONETOUCH_PKT_LEN. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/onetouch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index cb79de61f4c8..26964895c88b 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -195,6 +195,7 @@ static int onetouch_connect_input(struct us_data *ss) pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); + maxp = min(maxp, ONETOUCH_PKT_LEN); onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); input_dev = input_allocate_device(); @@ -245,8 +246,7 @@ static int onetouch_connect_input(struct us_data *ss) input_dev->open = usb_onetouch_open; input_dev->close = usb_onetouch_close; - usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, - (maxp > 8 ? 8 : maxp), + usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, maxp, usb_onetouch_irq, onetouch, endpoint->bInterval); onetouch->irq->transfer_dma = onetouch->data_dma; onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -- cgit From ae8d4879667949fb49f0862b11ba680f671b2185 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Thu, 7 Mar 2013 01:51:12 +0530 Subject: usb: serial: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 809fb329eca5..107ff9e3ddad 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1252,8 +1252,7 @@ static void mos7840_close(struct usb_serial_port *port) if (mos7840_port->write_urb) { /* if this urb had a transfer buffer already (old tx) free it */ - if (mos7840_port->write_urb->transfer_buffer != NULL) - kfree(mos7840_port->write_urb->transfer_buffer); + kfree(mos7840_port->write_urb->transfer_buffer); usb_free_urb(mos7840_port->write_urb); } -- cgit From a4dee9c9fdda7a3ebcb76f5e6280508530f67b76 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Mar 2013 12:57:58 +0100 Subject: USB: cdc-acm: Remove obsolete predefined speeds array Modern speed handling has been introduced in 2009 by commit 9b80fee149a875a6292b2556ab2c64dc7ab7d6f5 (cdc_acm: Fix to use modern speed interfaces) and the acm_tty_speed array has been unused since. Signed-off-by: Samuel Tardieu Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8ac25adf31b4..d003c8ca00bc 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -840,14 +840,6 @@ static int acm_tty_ioctl(struct tty_struct *tty, return rv; } -static const __u32 acm_tty_speed[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, - 1200, 1800, 2400, 4800, 9600, 19200, 38400, - 57600, 115200, 230400, 460800, 500000, 576000, - 921600, 1000000, 1152000, 1500000, 2000000, - 2500000, 3000000, 3500000, 4000000 -}; - static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) { -- cgit From 07cd29d76532acc6a9148074c3915c02cdd709d9 Mon Sep 17 00:00:00 2001 From: Paul Vlase Date: Sun, 10 Mar 2013 15:52:02 +0200 Subject: usb: Use resource_size function Signed-off-by: Paul Vlase Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 3065809546b1..5cd9f96ed92d 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -225,7 +225,7 @@ static int mv_ehci_probe(struct platform_device *pdev) (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); hcd->rsrc_start = r->start; - hcd->rsrc_len = r->end - r->start + 1; + hcd->rsrc_len = resource_size(r); hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); -- cgit From 8244ac043c5334012006d542d1cd5c1e3fe2f32a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 23:23:23 +0800 Subject: USB: misc: usb3503: use module_i2c_driver to simplify the code Use the module_i2c_driver() macro to make the code smaller and a bit simpler. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb3503.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index f713f6aeb6e5..d3a1cce1bf9c 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -307,18 +307,7 @@ static struct i2c_driver usb3503_driver = { .id_table = usb3503_id, }; -static int __init usb3503_init(void) -{ - return i2c_add_driver(&usb3503_driver); -} - -static void __exit usb3503_exit(void) -{ - i2c_del_driver(&usb3503_driver); -} - -module_init(usb3503_init); -module_exit(usb3503_exit); +module_i2c_driver(usb3503_driver); MODULE_AUTHOR("Dongjin Kim "); MODULE_DESCRIPTION("USB3503 USB HUB driver"); -- cgit From 5b2750d5b5a25c9c8b842e22fb2a7015dc798455 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:33:27 +0800 Subject: driver: usb: storage: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Matthew Dharm Cc: Greg Kroah-Hartman Cc: Andrew Morton Cc: linux-usb@vger.kernel.org Cc: usb-storage@lists.one-eyed-alien.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/isd200.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index ecea47877364..06a3d22db685 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1457,8 +1457,7 @@ static int isd200_init_info(struct us_data *us) retStatus = ISD200_ERROR; else { info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL); - info->RegsBuf = (unsigned char *) - kmalloc(sizeof(info->ATARegs), GFP_KERNEL); + info->RegsBuf = kmalloc(sizeof(info->ATARegs), GFP_KERNEL); info->srb.sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) { -- cgit From a1645eefc8358d0a9dbeba254e51aa89de4d80a4 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 15 Mar 2013 17:14:57 +0000 Subject: usb: misc: sisusbvga: Avoid NULL pointer dereference from sisusb A failed kzalloc() is reported with a dev_err that dereferences the null sisusb, this will cause a NULL pointer deference error. Instead, pass dev->dev to the dev_err() rather than &sisusb->sisusb_dev->dev Smatch analysis: drivers/usb/misc/sisusbvga/sisusb.c:3087 sisusb_probe() error: potential null dereference 'sisusb'. (kzalloc returns null) Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index dd573abd2d1e..c21386ec5d35 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3084,7 +3084,7 @@ static int sisusb_probe(struct usb_interface *intf, /* Allocate memory for our private */ if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { - dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for private data\n"); + dev_err(&dev->dev, "Failed to allocate memory for private data\n"); return -ENOMEM; } kref_init(&sisusb->kref); -- cgit From 54a419668b0f27b7982807fb2376d237e0a0ce05 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 12 Mar 2013 12:44:39 +0200 Subject: USB: EHCI: split ehci-omap out to a separate driver This patch (as1645) converts ehci-omap over to the new "ehci-hcd is a library" approach, so that it can coexist peacefully with other EHCI platform drivers and can make use of the private area allocated at the end of struct ehci_hcd. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-hcd.c | 6 +--- drivers/usb/host/ehci-omap.c | 76 ++++++++++++++++++++------------------------ 4 files changed, 37 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index c59a1126926f..62f4e9a38557 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -155,7 +155,7 @@ config USB_EHCI_MXC Variation of ARC USB block used in some Freescale chips. config USB_EHCI_HCD_OMAP - bool "EHCI support for OMAP3 and later chips" + tristate "EHCI support for OMAP3 and later chips" depends on USB_EHCI_HCD && ARCH_OMAP default y ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 001fbff2fdef..56de4106c8b3 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o +obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b416a3fc9959..303b0222cd6d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1252,11 +1252,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_sh_driver #endif -#ifdef CONFIG_USB_EHCI_HCD_OMAP -#include "ehci-omap.c" -#define PLATFORM_DRIVER ehci_hcd_omap_driver -#endif - #ifdef CONFIG_PPC_PS3 #include "ehci-ps3.c" #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver @@ -1346,6 +1341,7 @@ MODULE_LICENSE ("GPL"); !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \ !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \ !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && \ !defined(OF_PLATFORM_DRIVER) && \ diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 0555ee42d7cb..fa667577d9b9 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -36,6 +36,9 @@ * - convert to use hwmod and runtime PM */ +#include +#include +#include #include #include #include @@ -43,6 +46,10 @@ #include #include #include +#include +#include + +#include "ehci.h" #include @@ -57,9 +64,11 @@ #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 -/*-------------------------------------------------------------------------*/ +#define DRIVER_DESC "OMAP-EHCI Host Controller driver" -static const struct hc_driver ehci_omap_hc_driver; +static const char hcd_name[] = "ehci-omap"; + +/*-------------------------------------------------------------------------*/ static inline void ehci_write(void __iomem *base, u32 reg, u32 val) @@ -166,6 +175,12 @@ static void disable_put_regulator( /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ +static struct hc_driver __read_mostly ehci_omap_hc_driver; + +static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { + .reset = omap_ehci_init, +}; + /** * ehci_hcd_omap_probe - initialize TI-based HCDs * @@ -315,56 +330,33 @@ static struct platform_driver ehci_hcd_omap_driver = { /*.suspend = ehci_hcd_omap_suspend, */ /*.resume = ehci_hcd_omap_resume, */ .driver = { - .name = "ehci-omap", + .name = hcd_name, } }; /*-------------------------------------------------------------------------*/ -static const struct hc_driver ehci_omap_hc_driver = { - .description = hcd_name, - .product_desc = "OMAP-EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = omap_ehci_init, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, +static int __init ehci_omap_init(void) +{ + if (usb_disabled()) + return -ENODEV; - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, + pr_info("%s: " DRIVER_DESC "\n", hcd_name); - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, + ehci_init_driver(&ehci_omap_hc_driver, &ehci_omap_overrides); + return platform_driver_register(&ehci_hcd_omap_driver); +} +module_init(ehci_omap_init); - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; +static void __exit ehci_omap_cleanup(void) +{ + platform_driver_unregister(&ehci_hcd_omap_driver); +} +module_exit(ehci_omap_cleanup); MODULE_ALIAS("platform:ehci-omap"); MODULE_AUTHOR("Texas Instruments, Inc."); MODULE_AUTHOR("Felipe Balbi "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); -- cgit From 18c2bb1b8c1571f4c1fa33cc1f4525b282059455 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:40 +0200 Subject: USB: ehci-omap: Use devm_ioremap_resource() Make use of devm_ioremap_resource() and correct comment. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index fa667577d9b9..70e8e6f33d42 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -216,23 +216,15 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); - if (!res) { - dev_err(dev, "UHH EHCI get resource failed\n"); - return -ENODEV; - } - - regs = ioremap(res->start, resource_size(res)); - if (!regs) { - dev_err(dev, "UHH EHCI ioremap failed\n"); - return -ENOMEM; - } + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, dev_name(dev)); if (!hcd) { - dev_err(dev, "failed to create hcd with err %d\n", ret); - ret = -ENOMEM; - goto err_io; + dev_err(dev, "Failed to create HCD\n"); + return -ENOMEM; } hcd->rsrc_start = res->start; @@ -285,8 +277,6 @@ err_pm_runtime: pm_runtime_put_sync(dev); usb_put_hcd(hcd); -err_io: - iounmap(regs); return ret; } @@ -306,7 +296,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); - iounmap(hcd->regs); usb_put_hcd(hcd); pm_runtime_put_sync(dev); -- cgit From dcd64063fd917b5c79f99cae218e1df3ed1b62a2 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:41 +0200 Subject: USB: ehci-omap: Use PHY APIs to get the PHY device and put it out of suspend For each port that is in PHY mode we obtain a PHY device using the USB PHY library and put it out of suspend. It is up to platform code to associate the PHY to the controller's port and it is up to the PHY driver to manage the PHY's resources. Also remove weird spacing around declarations we come across. Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 76 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 70e8e6f33d42..6b8b7e5358a6 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -4,10 +4,11 @@ * Bus Glue for the EHCI controllers in OMAP3/4 * Tested on several OMAP3 boards, and OMAP4 Pandaboard * - * Copyright (C) 2007-2011 Texas Instruments, Inc. + * Copyright (C) 2007-2013 Texas Instruments, Inc. * Author: Vikram Pandita * Author: Anand Gadiyar * Author: Keshava Munegowda + * Author: Roger Quadros * * Copyright (C) 2009 Nokia Corporation * Contact: Felipe Balbi @@ -70,6 +71,10 @@ static const char hcd_name[] = "ehci-omap"; /*-------------------------------------------------------------------------*/ +struct omap_hcd { + struct usb_phy *phy[OMAP3_HS_USB_PORTS]; /* one PHY for each port */ + int nports; +}; static inline void ehci_write(void __iomem *base, u32 reg, u32 val) { @@ -178,7 +183,8 @@ static void disable_put_regulator( static struct hc_driver __read_mostly ehci_omap_hc_driver; static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { - .reset = omap_ehci_init, + .reset = omap_ehci_init, + .extra_priv_size = sizeof(struct omap_hcd), }; /** @@ -190,15 +196,16 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { */ static int ehci_hcd_omap_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usbhs_omap_platform_data *pdata = dev->platform_data; - struct resource *res; - struct usb_hcd *hcd; - void __iomem *regs; - int ret = -ENODEV; - int irq; - int i; - char supply[7]; + struct device *dev = &pdev->dev; + struct usbhs_omap_platform_data *pdata = dev->platform_data; + struct resource *res; + struct usb_hcd *hcd; + void __iomem *regs; + int ret = -ENODEV; + int irq; + int i; + char supply[7]; + struct omap_hcd *omap; if (usb_disabled()) return -ENODEV; @@ -231,6 +238,33 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) hcd->rsrc_len = resource_size(res); hcd->regs = regs; + omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv; + omap->nports = pdata->nports; + + platform_set_drvdata(pdev, hcd); + + /* get the PHY devices if needed */ + for (i = 0 ; i < omap->nports ; i++) { + struct usb_phy *phy; + + if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) + continue; + + /* get the PHY device */ + phy = devm_usb_get_phy_dev(dev, i); + if (IS_ERR(phy) || !phy) { + ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; + dev_err(dev, "Can't get PHY device for port %d: %d\n", + i, ret); + goto err_phy; + } + + omap->phy[i] = phy; + usb_phy_init(omap->phy[i]); + /* bring PHY out of suspend */ + usb_phy_set_suspend(omap->phy[i], 0); + } + /* get ehci regulator and enable */ for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { @@ -275,6 +309,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) err_pm_runtime: disable_put_regulator(pdata); pm_runtime_put_sync(dev); + +err_phy: + for (i = 0; i < omap->nports; i++) { + if (omap->phy[i]) + usb_phy_shutdown(omap->phy[i]); + } + usb_put_hcd(hcd); return ret; @@ -291,13 +332,20 @@ err_pm_runtime: */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usb_hcd *hcd = dev_get_drvdata(dev); + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv; + int i; usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); - usb_put_hcd(hcd); + for (i = 0; i < omap->nports; i++) { + if (omap->phy[i]) + usb_phy_shutdown(omap->phy[i]); + } + + usb_put_hcd(hcd); pm_runtime_put_sync(dev); pm_runtime_disable(dev); -- cgit From 87425ad36330e4ee2806f19c7d14524c43a02210 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:42 +0200 Subject: USB: ehci-omap: Remove PHY reset handling code Reset GPIO handling for the PHY must be done in the PHY driver. We use the PHY helpers instead to reset the PHY. Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 72 ++++++-------------------------------------- 1 file changed, 10 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 6b8b7e5358a6..0bbfdc1ee557 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -86,79 +86,27 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) return __raw_readl(base + reg); } - -static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(1000); - unsigned reg = 0; - - reg = ULPI_FUNC_CTRL_RESET - /* FUNCTION_CTRL_SET register */ - | (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT) - /* Write */ - | (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) - /* PORTn */ - | ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) - /* start ULPI access*/ - | (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT); - - ehci_write(hcd->regs, EHCI_INSNREG05_ULPI, reg); - - /* Wait for ULPI access completion */ - while ((ehci_read(hcd->regs, EHCI_INSNREG05_ULPI) - & (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) { - dev_dbg(hcd->self.controller, - "phy reset operation timed out\n"); - break; - } - } -} - static int omap_ehci_init(struct usb_hcd *hcd) { - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int rc; - struct usbhs_omap_platform_data *pdata; - - pdata = hcd->self.controller->platform_data; + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct omap_hcd *omap = (struct omap_hcd *)ehci->priv; + int rc, i; /* Hold PHYs in reset while initializing EHCI controller */ - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); + for (i = 0; i < omap->nports; i++) { + if (omap->phy[i]) + usb_phy_shutdown(omap->phy[i]); } - /* Soft reset the PHY using PHY reset command over ULPI */ - if (pdata->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY) - omap_ehci_soft_phy_reset(hcd, 0); - if (pdata->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY) - omap_ehci_soft_phy_reset(hcd, 1); - /* we know this is the memory we want, no need to ioremap again */ ehci->caps = hcd->regs; rc = ehci_setup(hcd); - if (pdata->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value_cansleep(pdata->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); + /* Bring PHYs out of reset */ + for (i = 0; i < omap->nports; i++) { + if (omap->phy[i]) + usb_phy_init(omap->phy[i]); } return rc; -- cgit From 218a214723d75f5692660d4f4eb4f524b0dfabec Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:43 +0200 Subject: USB: ehci-omap: Remove PHY regulator handling code PHY regulator handling must be done in the PHY driver Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 0bbfdc1ee557..57fe98548116 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -112,19 +111,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) return rc; } -static void disable_put_regulator( - struct usbhs_omap_platform_data *pdata) -{ - int i; - - for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (pdata->regulator[i]) { - regulator_disable(pdata->regulator[i]); - regulator_put(pdata->regulator[i]); - } - } -} - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -152,7 +138,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) int ret = -ENODEV; int irq; int i; - char supply[7]; struct omap_hcd *omap; if (usb_disabled()) @@ -213,23 +198,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) usb_phy_set_suspend(omap->phy[i], 0); } - /* get ehci regulator and enable */ - for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { - pdata->regulator[i] = NULL; - continue; - } - snprintf(supply, sizeof(supply), "hsusb%d", i); - pdata->regulator[i] = regulator_get(dev, supply); - if (IS_ERR(pdata->regulator[i])) { - pdata->regulator[i] = NULL; - dev_dbg(dev, - "failed to get ehci port%d regulator\n", i); - } else { - regulator_enable(pdata->regulator[i]); - } - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -255,7 +223,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) return 0; err_pm_runtime: - disable_put_regulator(pdata); pm_runtime_put_sync(dev); err_phy: @@ -286,7 +253,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) int i; usb_remove_hcd(hcd); - disable_put_regulator(dev->platform_data); for (i = 0; i < omap->nports; i++) { if (omap->phy[i]) -- cgit From dfdf9ad92aa90d2a5de732dbd5e23bb17501ac67 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:44 +0200 Subject: USB: ehci-omap: Select NOP USB transceiver driver In PHY mode we need to have the nop-usb-xceiv transceiver driver to operate, so select it in Kconfig. Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 62f4e9a38557..2f682219e257 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -157,6 +157,7 @@ config USB_EHCI_MXC config USB_EHCI_HCD_OMAP tristate "EHCI support for OMAP3 and later chips" depends on USB_EHCI_HCD && ARCH_OMAP + select NOP_USB_XCEIV default y ---help--- Enables support for the on-chip EHCI controller on -- cgit From 3414211b914464113ba3cd19726e44b5e416087d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:45 +0200 Subject: USB: ehci-omap: Get platform resources by index rather than by name Since there is only one resource per type we don't really need to use resource name to obtain it. This also also makes it easier for device tree adaptation. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 57fe98548116..7d05cce62037 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -148,14 +148,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) return -ENODEV; } - irq = platform_get_irq_byname(pdev, "ehci-irq"); + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "EHCI irq failed\n"); return -ENODEV; } - res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "ehci"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) return PTR_ERR(regs); -- cgit From 8c3ec38550a6b880738c8b1982f9207d0fd5a339 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:46 +0200 Subject: USB: ohci-omap3: Get platform resources by index rather than by name Since there is only one resource per type we don't really need to use resource name to obtain it. This also also makes it easier for device tree adaptation. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-omap3.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index eb35d9630237..5ed28c5af759 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -141,14 +141,13 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev) return -ENODEV; } - irq = platform_get_irq_byname(pdev, "ohci-irq"); + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "OHCI irq failed\n"); return -ENODEV; } - res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "ohci"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "UHH OHCI get resource failed\n"); return -ENOMEM; -- cgit From 5867320dec346c2dc26f224f876d780111ca149d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:47 +0200 Subject: USB: ohci-omap3: Add device tree support and binding information Allows the OHCI controller found in OMAP3 and later chips to be specified via device tree. Signed-off-by: Roger Quadros Reviewed-by: Mark Rutland Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/ohci-omap3.txt | 15 +++++++++++++++ drivers/usb/host/ohci-omap3.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ohci-omap3.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/ohci-omap3.txt b/Documentation/devicetree/bindings/usb/ohci-omap3.txt new file mode 100644 index 000000000000..14ab42812a8e --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ohci-omap3.txt @@ -0,0 +1,15 @@ +OMAP HS USB OHCI controller (OMAP3 and later) + +Required properties: + +- compatible: should be "ti,ohci-omap3" +- reg: should contain one register range i.e. start and length +- interrupts: description of the interrupt line + +Example for OMAP4: + +usbhsohci: ohci@4a064800 { + compatible = "ti,ohci-omap3", "usb-ohci"; + reg = <0x4a064800 0x400>; + interrupts = <0 76 0x4>; +}; diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 5ed28c5af759..ddfc31427bc0 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -31,6 +31,8 @@ #include #include +#include +#include /*-------------------------------------------------------------------------*/ @@ -112,6 +114,8 @@ static const struct hc_driver ohci_omap3_hc_driver = { /*-------------------------------------------------------------------------*/ +static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32); + /* * configure so an HC device and id are always provided * always called with process context; sleeping is OK @@ -159,6 +163,13 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev) return -ENOMEM; } + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &omap_ohci_dma_mask; hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev, dev_name(dev)); @@ -228,12 +239,20 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } +static const struct of_device_id omap_ohci_dt_ids[] = { + { .compatible = "ti,ohci-omap3" }, + { } +}; + +MODULE_DEVICE_TABLE(of, omap_ohci_dt_ids); + static struct platform_driver ohci_hcd_omap3_driver = { .probe = ohci_hcd_omap3_probe, .remove = ohci_hcd_omap3_remove, .shutdown = ohci_hcd_omap3_shutdown, .driver = { .name = "ohci-omap3", + .of_match_table = of_match_ptr(omap_ohci_dt_ids), }, }; -- cgit From a1ae0affee119e6deb937d157aa8b43319c1d6f3 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:48 +0200 Subject: USB: ehci-omap: Add device tree support and binding information Allows the OMAP EHCI controller to be specified via device tree. Signed-off-by: Roger Quadros Reviewed-by: Mark Rutland Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/ehci-omap.txt | 32 +++++++++++++++++++ drivers/usb/host/ehci-omap.c | 37 +++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/usb/ehci-omap.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/ehci-omap.txt b/Documentation/devicetree/bindings/usb/ehci-omap.txt new file mode 100644 index 000000000000..485a9a1efa7a --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ehci-omap.txt @@ -0,0 +1,32 @@ +OMAP HS USB EHCI controller + +This device is usually the child of the omap-usb-host +Documentation/devicetree/bindings/mfd/omap-usb-host.txt + +Required properties: + +- compatible: should be "ti,ehci-omap" +- reg: should contain one register range i.e. start and length +- interrupts: description of the interrupt line + +Optional properties: + +- phys: list of phandles to PHY nodes. + This property is required if at least one of the ports are in + PHY mode i.e. OMAP_EHCI_PORT_MODE_PHY + +To specify the port mode, see +Documentation/devicetree/bindings/mfd/omap-usb-host.txt + +Example for OMAP4: + +usbhsehci: ehci@4a064c00 { + compatible = "ti,ehci-omap", "usb-ehci"; + reg = <0x4a064c00 0x400>; + interrupts = <0 77 0x4>; +}; + +&usbhsehci { + phys = <&hsusb1_phy 0 &hsusb3_phy>; +}; + diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 7d05cce62037..45cd01e29252 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include "ehci.h" @@ -121,6 +123,8 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { .extra_priv_size = sizeof(struct omap_hcd), }; +static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32); + /** * ehci_hcd_omap_probe - initialize TI-based HCDs * @@ -148,6 +152,17 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) return -ENODEV; } + /* For DT boot, get platform data from parent. i.e. usbhshost */ + if (dev->of_node) { + pdata = dev->parent->platform_data; + dev->platform_data = pdata; + } + + if (!pdata) { + dev_err(dev, "Missing platform data\n"); + return -ENODEV; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "EHCI irq failed\n"); @@ -159,6 +174,14 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &omap_ehci_dma_mask; + hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, dev_name(dev)); if (!hcd) { @@ -183,7 +206,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) continue; /* get the PHY device */ - phy = devm_usb_get_phy_dev(dev, i); + if (dev->of_node) + phy = devm_usb_get_phy_by_phandle(dev, "phys", i); + else + phy = devm_usb_get_phy_dev(dev, i); if (IS_ERR(phy) || !phy) { ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; dev_err(dev, "Can't get PHY device for port %d: %d\n", @@ -273,6 +299,13 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } +static const struct of_device_id omap_ehci_dt_ids[] = { + { .compatible = "ti,ehci-omap" }, + { } +}; + +MODULE_DEVICE_TABLE(of, omap_ehci_dt_ids); + static struct platform_driver ehci_hcd_omap_driver = { .probe = ehci_hcd_omap_probe, .remove = ehci_hcd_omap_remove, @@ -281,6 +314,7 @@ static struct platform_driver ehci_hcd_omap_driver = { /*.resume = ehci_hcd_omap_resume, */ .driver = { .name = hcd_name, + .of_match_table = of_match_ptr(omap_ehci_dt_ids), } }; @@ -307,6 +341,7 @@ module_exit(ehci_omap_cleanup); MODULE_ALIAS("platform:ehci-omap"); MODULE_AUTHOR("Texas Instruments, Inc."); MODULE_AUTHOR("Felipe Balbi "); +MODULE_AUTHOR("Roger Quadros "); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -- cgit From a2f450ca88a394e282f09e5e16f9de60cd487f80 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 12:44:49 +0200 Subject: USB: ehci-omap: Try to get PHY even if not in PHY mode Even when not in PHY mode, the USB device on the port (e.g. HUB) might need resources like RESET which can be modelled as a PHY device. So try to get the PHY device in any case. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 45cd01e29252..1ba1df89a436 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -202,15 +202,16 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) for (i = 0 ; i < omap->nports ; i++) { struct usb_phy *phy; - if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) - continue; - /* get the PHY device */ if (dev->of_node) phy = devm_usb_get_phy_by_phandle(dev, "phys", i); else phy = devm_usb_get_phy_dev(dev, i); if (IS_ERR(phy) || !phy) { + /* Don't bail out if PHY is not absolutely necessary */ + if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) + continue; + ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; dev_err(dev, "Can't get PHY device for port %d: %d\n", i, ret); -- cgit From 49f092198f4fd2c70847de7151d33df08929af51 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 13 Mar 2013 15:14:43 +0200 Subject: USB: ehci-omap: Fix detection in HSIC mode Move PHY initialization until after EHCI initialization is complete, instead of initializing the PHYs first, shutting them down again, and then initializing them a second time. This fixes HSIC device detection. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 1ba1df89a436..755b428019a1 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -90,26 +90,13 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) static int omap_ehci_init(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct omap_hcd *omap = (struct omap_hcd *)ehci->priv; - int rc, i; - - /* Hold PHYs in reset while initializing EHCI controller */ - for (i = 0; i < omap->nports; i++) { - if (omap->phy[i]) - usb_phy_shutdown(omap->phy[i]); - } + int rc; /* we know this is the memory we want, no need to ioremap again */ ehci->caps = hcd->regs; rc = ehci_setup(hcd); - /* Bring PHYs out of reset */ - for (i = 0; i < omap->nports; i++) { - if (omap->phy[i]) - usb_phy_init(omap->phy[i]); - } - return rc; } @@ -219,9 +206,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } omap->phy[i] = phy; - usb_phy_init(omap->phy[i]); - /* bring PHY out of suspend */ - usb_phy_set_suspend(omap->phy[i], 0); } pm_runtime_enable(dev); @@ -245,6 +229,20 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) goto err_pm_runtime; } + /* + * Bring PHYs out of reset. + * Even though HSIC mode is a PHY-less mode, the reset + * line exists between the chips and can be modelled + * as a PHY device for reset control. + */ + for (i = 0; i < omap->nports; i++) { + if (!omap->phy[i]) + continue; + + usb_phy_init(omap->phy[i]); + /* bring PHY out of suspend */ + usb_phy_set_suspend(omap->phy[i], 0); + } return 0; -- cgit From 413fd1e9aa3e0441e64ed4703ce1bba164e135c0 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 13 Mar 2013 15:16:03 +0200 Subject: USB: ehci-omap: Get rid of omap_ehci_init() As it does almost nothing, get rid of omap_ehci_init() and move the ehci->caps initialization part into probe(). Also remove the outdated TODO list from header. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 755b428019a1..5de3e43ded50 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -29,12 +29,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * TODO (last updated Feb 27, 2010): - * - add kernel-doc - * - enable AUTOIDLE - * - add suspend/resume - * - add HSIC and TLL support - * - convert to use hwmod and runtime PM */ #include @@ -87,26 +81,12 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) return __raw_readl(base + reg); } -static int omap_ehci_init(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int rc; - - /* we know this is the memory we want, no need to ioremap again */ - ehci->caps = hcd->regs; - - rc = ehci_setup(hcd); - - return rc; -} - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ static struct hc_driver __read_mostly ehci_omap_hc_driver; static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { - .reset = omap_ehci_init, .extra_priv_size = sizeof(struct omap_hcd), }; @@ -179,6 +159,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = regs; + hcd_to_ehci(hcd)->caps = regs; omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv; omap->nports = pdata->nports; -- cgit From 7a64b864a0989302b5f6869f8b65b630b10bd9db Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:39 -0700 Subject: Drivers: hv: balloon: Do not request completion notification There is no need to request completion notification; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 37873213e24f..7fb72dd05ba2 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -962,8 +962,7 @@ static int balloon_probe(struct hv_device *dev, ret = vmbus_sendpacket(dev->channel, &version_req, sizeof(struct dm_version_request), (unsigned long)NULL, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VM_PKT_DATA_INBAND, 0); if (ret) goto probe_error2; @@ -1009,8 +1008,7 @@ static int balloon_probe(struct hv_device *dev, ret = vmbus_sendpacket(dev->channel, &cap_msg, sizeof(struct dm_capabilities), (unsigned long)NULL, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VM_PKT_DATA_INBAND, 0); if (ret) goto probe_error2; -- cgit From 6571b2dab4eb6c7061160490db984dbc01e5626d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:40 -0700 Subject: Drivers: hv: balloon: Execute balloon inflation in a separate context Execute the balloon inflation operation in a separate work context. This allows us to decouple the pressure reporting activity from the ballooning activity. Testing has shown that this decoupling makes the guest more reponsive. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 7fb72dd05ba2..8dc406ccf10f 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -412,6 +412,11 @@ struct dm_info_msg { * End protocol definitions. */ +struct balloon_state { + __u32 num_pages; + struct work_struct wrk; +}; + static bool hot_add; static bool do_hot_add; /* @@ -459,7 +464,12 @@ struct hv_dynmem_device { unsigned int num_pages_ballooned; /* - * This thread handles both balloon/hot-add + * State to manage the ballooning (up) operation. + */ + struct balloon_state balloon_wrk; + + /* + * This thread handles hot-add * requests from the host as well as notifying * the host with regards to memory pressure in * the guest. @@ -657,9 +667,9 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages, -static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) +static void balloon_up(struct work_struct *dummy) { - int num_pages = req->num_pages; + int num_pages = dm_device.balloon_wrk.num_pages; int num_ballooned = 0; struct dm_balloon_response *bl_resp; int alloc_unit; @@ -684,14 +694,14 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) num_pages -= num_ballooned; - num_ballooned = alloc_balloon_pages(dm, num_pages, + num_ballooned = alloc_balloon_pages(&dm_device, num_pages, bl_resp, alloc_unit, &alloc_error); if ((alloc_error) || (num_ballooned == num_pages)) { bl_resp->more_pages = 0; done = true; - dm->state = DM_INITIALIZED; + dm_device.state = DM_INITIALIZED; } /* @@ -719,7 +729,7 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) pr_info("Balloon response failed\n"); for (i = 0; i < bl_resp->range_count; i++) - free_balloon_pages(dm, + free_balloon_pages(&dm_device, &bl_resp->range_array[i]); done = true; @@ -775,9 +785,6 @@ static int dm_thread_func(void *dm_dev) scan_start = jiffies; switch (dm->state) { - case DM_BALLOON_UP: - balloon_up(dm, (struct dm_balloon *)recv_buffer); - break; case DM_HOT_ADD: hot_add_req(dm, (struct dm_hot_add *)recv_buffer); @@ -861,6 +868,7 @@ static void balloon_onchannelcallback(void *context) struct dm_message *dm_msg; struct dm_header *dm_hdr; struct hv_dynmem_device *dm = hv_get_drvdata(dev); + struct dm_balloon *bal_msg; memset(recv_buffer, 0, sizeof(recv_buffer)); vmbus_recvpacket(dev->channel, recv_buffer, @@ -882,8 +890,12 @@ static void balloon_onchannelcallback(void *context) break; case DM_BALLOON_REQUEST: + if (dm->state == DM_BALLOON_UP) + pr_warn("Currently ballooning\n"); + bal_msg = (struct dm_balloon *)recv_buffer; dm->state = DM_BALLOON_UP; - complete(&dm->config_event); + dm_device.balloon_wrk.num_pages = bal_msg->num_pages; + schedule_work(&dm_device.balloon_wrk.wrk); break; case DM_UNBALLOON_REQUEST: @@ -937,6 +949,7 @@ static int balloon_probe(struct hv_device *dev, dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; init_completion(&dm_device.host_event); init_completion(&dm_device.config_event); + INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up); dm_device.thread = kthread_run(dm_thread_func, &dm_device, "hv_balloon"); @@ -1048,6 +1061,7 @@ static int balloon_remove(struct hv_device *dev) if (dm->num_pages_ballooned != 0) pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); + cancel_work_sync(&dm->balloon_wrk.wrk); vmbus_close(dev->channel); kthread_stop(dm->thread); kfree(send_buffer); -- cgit From c51af826cf062af3c49a99a05a33236d93c57e72 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:41 -0700 Subject: Drivers: hv: balloon: Execute hot-add code in a separate context Execute the hot-add operation in a separate work context. This allows us to decouple the pressure reporting activity from the "hot-add" activity. Testing has shown that this makes the guest more responsive to hot add requests. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 8dc406ccf10f..13fda3807bfb 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -417,6 +417,11 @@ struct balloon_state { struct work_struct wrk; }; +struct hot_add_wrk { + union dm_mem_page_range ha_page_range; + struct work_struct wrk; +}; + static bool hot_add; static bool do_hot_add; /* @@ -468,6 +473,11 @@ struct hv_dynmem_device { */ struct balloon_state balloon_wrk; + /* + * State to execute the "hot-add" operation. + */ + struct hot_add_wrk ha_wrk; + /* * This thread handles hot-add * requests from the host as well as notifying @@ -486,7 +496,7 @@ struct hv_dynmem_device { static struct hv_dynmem_device dm_device; -static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) +static void hot_add_req(struct work_struct *dummy) { struct dm_hot_add_response resp; @@ -509,8 +519,8 @@ static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) resp.page_count = 0; resp.result = 0; - dm->state = DM_INITIALIZED; - vmbus_sendpacket(dm->dev->channel, &resp, + dm_device.state = DM_INITIALIZED; + vmbus_sendpacket(dm_device.dev->channel, &resp, sizeof(struct dm_hot_add_response), (unsigned long)NULL, VM_PKT_DATA_INBAND, 0); @@ -771,7 +781,6 @@ static int dm_thread_func(void *dm_dev) { struct hv_dynmem_device *dm = dm_dev; int t; - unsigned long scan_start; while (!kthread_should_stop()) { t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ); @@ -783,19 +792,6 @@ static int dm_thread_func(void *dm_dev) if (t == 0) post_status(dm); - scan_start = jiffies; - switch (dm->state) { - - case DM_HOT_ADD: - hot_add_req(dm, (struct dm_hot_add *)recv_buffer); - break; - default: - break; - } - - if (!time_in_range(jiffies, scan_start, scan_start + HZ)) - post_status(dm); - } return 0; @@ -869,6 +865,8 @@ static void balloon_onchannelcallback(void *context) struct dm_header *dm_hdr; struct hv_dynmem_device *dm = hv_get_drvdata(dev); struct dm_balloon *bal_msg; + struct dm_hot_add *ha_msg; + union dm_mem_page_range *ha_pg_range; memset(recv_buffer, 0, sizeof(recv_buffer)); vmbus_recvpacket(dev->channel, recv_buffer, @@ -905,8 +903,13 @@ static void balloon_onchannelcallback(void *context) break; case DM_MEM_HOT_ADD_REQUEST: + if (dm->state == DM_HOT_ADD) + pr_warn("Currently hot-adding\n"); dm->state = DM_HOT_ADD; - complete(&dm->config_event); + ha_msg = (struct dm_hot_add *)recv_buffer; + ha_pg_range = &ha_msg->range; + dm_device.ha_wrk.ha_page_range = *ha_pg_range; + schedule_work(&dm_device.ha_wrk.wrk); break; case DM_INFO_MESSAGE: @@ -950,6 +953,7 @@ static int balloon_probe(struct hv_device *dev, init_completion(&dm_device.host_event); init_completion(&dm_device.config_event); INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up); + INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req); dm_device.thread = kthread_run(dm_thread_func, &dm_device, "hv_balloon"); @@ -1062,6 +1066,7 @@ static int balloon_remove(struct hv_device *dev) pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); cancel_work_sync(&dm->balloon_wrk.wrk); + cancel_work_sync(&dm->ha_wrk.wrk); vmbus_close(dev->channel); kthread_stop(dm->thread); kfree(send_buffer); -- cgit From 0cf40a3e661b09c0dda795a77ccc0402c3153859 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:42 -0700 Subject: Drivers: hv: balloon: Make the balloon driver not unloadable The balloon driver is stateful. For instance, it needs to keep track of pages that have been ballooned out to properly post pressure reports. This state cannot be re-constructed if the driver were to be unloaded and subsequently loaded. Furthermore, as we support memory hot-add as part of this driver, this driver becomes even more stateful and this state cannot be re-created. Make the balloon driver unloadable to deal with this issue. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 13fda3807bfb..4743db9e5f34 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -1096,14 +1096,7 @@ static int __init init_balloon_drv(void) return vmbus_driver_register(&balloon_drv); } -static void exit_balloon_drv(void) -{ - - vmbus_driver_unregister(&balloon_drv); -} - module_init(init_balloon_drv); -module_exit(exit_balloon_drv); MODULE_DESCRIPTION("Hyper-V Balloon"); MODULE_VERSION(HV_DRV_VERSION); -- cgit From 1cac8cd4d146b60a7c70d778b5be928281b3b551 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:43 -0700 Subject: Drivers: hv: balloon: Implement hot-add functionality Implement the memory hot-add functionality. With this, Linux guests can fully participate in the Dynamic Memory protocol implemented in the Windows hosts. In this version of the patch, based Olaf Herring's feedback, I have gotten rid of the module level dependency on MEMORY_HOTPLUG. Instead the code within the driver that depends on MEMORY_HOTPLUG has the appropriate compilation switches. This would allow this driver to support pure ballooning in cases where the kernel does not support memory hotplug. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 408 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 387 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 4743db9e5f34..2cf7d4e964bd 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -412,6 +412,27 @@ struct dm_info_msg { * End protocol definitions. */ +/* + * State to manage hot adding memory into the guest. + * The range start_pfn : end_pfn specifies the range + * that the host has asked us to hot add. The range + * start_pfn : ha_end_pfn specifies the range that we have + * currently hot added. We hot add in multiples of 128M + * chunks; it is possible that we may not be able to bring + * online all the pages in the region. The range + * covered_start_pfn : covered_end_pfn defines the pages that can + * be brough online. + */ + +struct hv_hotadd_state { + struct list_head list; + unsigned long start_pfn; + unsigned long covered_start_pfn; + unsigned long covered_end_pfn; + unsigned long ha_end_pfn; + unsigned long end_pfn; +}; + struct balloon_state { __u32 num_pages; struct work_struct wrk; @@ -419,16 +440,17 @@ struct balloon_state { struct hot_add_wrk { union dm_mem_page_range ha_page_range; + union dm_mem_page_range ha_region_range; struct work_struct wrk; }; -static bool hot_add; +static bool hot_add = true; static bool do_hot_add; /* * Delay reporting memory pressure by * the specified number of seconds. */ -static uint pressure_report_delay = 30; +static uint pressure_report_delay = 45; module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); @@ -456,6 +478,7 @@ enum hv_dm_state { static __u8 recv_buffer[PAGE_SIZE]; static __u8 *send_buffer; #define PAGES_IN_2M 512 +#define HA_CHUNK (32 * 1024) struct hv_dynmem_device { struct hv_device *dev; @@ -478,6 +501,17 @@ struct hv_dynmem_device { */ struct hot_add_wrk ha_wrk; + /* + * This state tracks if the host has specified a hot-add + * region. + */ + bool host_specified_ha_region; + + /* + * State to synchronize hot-add. + */ + struct completion ol_waitevent; + bool ha_waiting; /* * This thread handles hot-add * requests from the host as well as notifying @@ -486,6 +520,11 @@ struct hv_dynmem_device { */ struct task_struct *thread; + /* + * A list of hot-add regions. + */ + struct list_head ha_region_list; + /* * We start with the highest version we can support * and downgrade based on the host; we save here the @@ -496,35 +535,329 @@ struct hv_dynmem_device { static struct hv_dynmem_device dm_device; -static void hot_add_req(struct work_struct *dummy) +#ifdef CONFIG_MEMORY_HOTPLUG + +void hv_bring_pgs_online(unsigned long start_pfn, unsigned long size) { + int i; - struct dm_hot_add_response resp; + for (i = 0; i < size; i++) { + struct page *pg; + pg = pfn_to_page(start_pfn + i); + __online_page_set_limits(pg); + __online_page_increment_counters(pg); + __online_page_free(pg); + } +} + +static void hv_mem_hot_add(unsigned long start, unsigned long size, + unsigned long pfn_count, + struct hv_hotadd_state *has) +{ + int ret = 0; + int i, nid, t; + unsigned long start_pfn; + unsigned long processed_pfn; + unsigned long total_pfn = pfn_count; + + for (i = 0; i < (size/HA_CHUNK); i++) { + start_pfn = start + (i * HA_CHUNK); + has->ha_end_pfn += HA_CHUNK; + + if (total_pfn > HA_CHUNK) { + processed_pfn = HA_CHUNK; + total_pfn -= HA_CHUNK; + } else { + processed_pfn = total_pfn; + total_pfn = 0; + } + + has->covered_end_pfn += processed_pfn; - if (do_hot_add) { + init_completion(&dm_device.ol_waitevent); + dm_device.ha_waiting = true; - pr_info("Memory hot add not supported\n"); + nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn)); + ret = add_memory(nid, PFN_PHYS((start_pfn)), + (HA_CHUNK << PAGE_SHIFT)); + + if (ret) { + pr_info("hot_add memory failed error is %d\n", ret); + has->ha_end_pfn -= HA_CHUNK; + has->covered_end_pfn -= processed_pfn; + break; + } /* - * Currently we do not support hot add. - * Just fail the request. + * Wait for the memory block to be onlined. */ + t = wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ); + if (t == 0) { + pr_info("hot_add memory timedout\n"); + has->ha_end_pfn -= HA_CHUNK; + has->covered_end_pfn -= processed_pfn; + break; + } + } + return; +} + +static void hv_online_page(struct page *pg) +{ + struct list_head *cur; + struct hv_hotadd_state *has; + unsigned long cur_start_pgp; + unsigned long cur_end_pgp; + + if (dm_device.ha_waiting) { + dm_device.ha_waiting = false; + complete(&dm_device.ol_waitevent); + } + + list_for_each(cur, &dm_device.ha_region_list) { + has = list_entry(cur, struct hv_hotadd_state, list); + cur_start_pgp = (unsigned long) + pfn_to_page(has->covered_start_pfn); + cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn); + + if (((unsigned long)pg >= cur_start_pgp) && + ((unsigned long)pg < cur_end_pgp)) { + /* + * This frame is currently backed; online the + * page. + */ + __online_page_set_limits(pg); + __online_page_increment_counters(pg); + __online_page_free(pg); + has->covered_start_pfn++; + } + } +} + +static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) +{ + struct list_head *cur; + struct hv_hotadd_state *has; + unsigned long residual, new_inc; + + if (list_empty(&dm_device.ha_region_list)) + return false; + + list_for_each(cur, &dm_device.ha_region_list) { + has = list_entry(cur, struct hv_hotadd_state, list); + + /* + * If the pfn range we are dealing with is not in the current + * "hot add block", move on. + */ + if ((start_pfn >= has->end_pfn)) + continue; + /* + * If the current hot add-request extends beyond + * our current limit; extend it. + */ + if ((start_pfn + pfn_cnt) > has->end_pfn) { + residual = (start_pfn + pfn_cnt - has->end_pfn); + /* + * Extend the region by multiples of HA_CHUNK. + */ + new_inc = (residual / HA_CHUNK) * HA_CHUNK; + if (residual % HA_CHUNK) + new_inc += HA_CHUNK; + + has->end_pfn += new_inc; + } + + /* + * If the current start pfn is not where the covered_end + * is, update it. + */ + + if (has->covered_end_pfn != start_pfn) { + has->covered_end_pfn = start_pfn; + has->covered_start_pfn = start_pfn; + } + return true; + + } + + return false; +} + +static unsigned long handle_pg_range(unsigned long pg_start, + unsigned long pg_count) +{ + unsigned long start_pfn = pg_start; + unsigned long pfn_cnt = pg_count; + unsigned long size; + struct list_head *cur; + struct hv_hotadd_state *has; + unsigned long pgs_ol = 0; + unsigned long old_covered_state; + + if (list_empty(&dm_device.ha_region_list)) + return 0; + + list_for_each(cur, &dm_device.ha_region_list) { + has = list_entry(cur, struct hv_hotadd_state, list); + + /* + * If the pfn range we are dealing with is not in the current + * "hot add block", move on. + */ + if ((start_pfn >= has->end_pfn)) + continue; + + old_covered_state = has->covered_end_pfn; + + if (start_pfn < has->ha_end_pfn) { + /* + * This is the case where we are backing pages + * in an already hot added region. Bring + * these pages online first. + */ + pgs_ol = has->ha_end_pfn - start_pfn; + if (pgs_ol > pfn_cnt) + pgs_ol = pfn_cnt; + hv_bring_pgs_online(start_pfn, pgs_ol); + has->covered_end_pfn += pgs_ol; + has->covered_start_pfn += pgs_ol; + pfn_cnt -= pgs_ol; + } + + if ((has->ha_end_pfn < has->end_pfn) && (pfn_cnt > 0)) { + /* + * We have some residual hot add range + * that needs to be hot added; hot add + * it now. Hot add a multiple of + * of HA_CHUNK that fully covers the pages + * we have. + */ + size = (has->end_pfn - has->ha_end_pfn); + if (pfn_cnt <= size) { + size = ((pfn_cnt / HA_CHUNK) * HA_CHUNK); + if (pfn_cnt % HA_CHUNK) + size += HA_CHUNK; + } else { + pfn_cnt = size; + } + hv_mem_hot_add(has->ha_end_pfn, size, pfn_cnt, has); + } + /* + * If we managed to online any pages that were given to us, + * we declare success. + */ + return has->covered_end_pfn - old_covered_state; + + } + + return 0; +} + +static unsigned long process_hot_add(unsigned long pg_start, + unsigned long pfn_cnt, + unsigned long rg_start, + unsigned long rg_size) +{ + struct hv_hotadd_state *ha_region = NULL; + + if (pfn_cnt == 0) + return 0; + + if (!dm_device.host_specified_ha_region) + if (pfn_covered(pg_start, pfn_cnt)) + goto do_pg_range; + + /* + * If the host has specified a hot-add range; deal with it first. + */ + + if ((rg_size != 0) && (!dm_device.host_specified_ha_region)) { + ha_region = kzalloc(sizeof(struct hv_hotadd_state), GFP_KERNEL); + if (!ha_region) + return 0; + + INIT_LIST_HEAD(&ha_region->list); + + list_add_tail(&ha_region->list, &dm_device.ha_region_list); + ha_region->start_pfn = rg_start; + ha_region->ha_end_pfn = rg_start; + ha_region->covered_start_pfn = pg_start; + ha_region->covered_end_pfn = pg_start; + ha_region->end_pfn = rg_start + rg_size; + } + +do_pg_range: + /* + * Process the page range specified; bringing them + * online if possible. + */ + return handle_pg_range(pg_start, pfn_cnt); +} + +#endif + +static void hot_add_req(struct work_struct *dummy) +{ + struct dm_hot_add_response resp; +#ifdef CONFIG_MEMORY_HOTPLUG + unsigned long pg_start, pfn_cnt; + unsigned long rg_start, rg_sz; +#endif + struct hv_dynmem_device *dm = &dm_device; + memset(&resp, 0, sizeof(struct dm_hot_add_response)); resp.hdr.type = DM_MEM_HOT_ADD_RESPONSE; resp.hdr.size = sizeof(struct dm_hot_add_response); resp.hdr.trans_id = atomic_inc_return(&trans_id); - resp.page_count = 0; - resp.result = 0; +#ifdef CONFIG_MEMORY_HOTPLUG + pg_start = dm->ha_wrk.ha_page_range.finfo.start_page; + pfn_cnt = dm->ha_wrk.ha_page_range.finfo.page_cnt; - dm_device.state = DM_INITIALIZED; - vmbus_sendpacket(dm_device.dev->channel, &resp, + rg_start = dm->ha_wrk.ha_region_range.finfo.start_page; + rg_sz = dm->ha_wrk.ha_region_range.finfo.page_cnt; + + if ((rg_start == 0) && (!dm->host_specified_ha_region)) { + unsigned long region_size; + unsigned long region_start; + + /* + * The host has not specified the hot-add region. + * Based on the hot-add page range being specified, + * compute a hot-add region that can cover the pages + * that need to be hot-added while ensuring the alignment + * and size requirements of Linux as it relates to hot-add. + */ + region_start = pg_start; + region_size = (pfn_cnt / HA_CHUNK) * HA_CHUNK; + if (pfn_cnt % HA_CHUNK) + region_size += HA_CHUNK; + + region_start = (pg_start / HA_CHUNK) * HA_CHUNK; + + rg_start = region_start; + rg_sz = region_size; + } + + resp.page_count = process_hot_add(pg_start, pfn_cnt, + rg_start, rg_sz); +#endif + if (resp.page_count > 0) + resp.result = 1; + else + resp.result = 0; + + if (!do_hot_add || (resp.page_count == 0)) + pr_info("Memory hot add failed\n"); + + dm->state = DM_INITIALIZED; + vmbus_sendpacket(dm->dev->channel, &resp, sizeof(struct dm_hot_add_response), (unsigned long)NULL, VM_PKT_DATA_INBAND, 0); - } static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) @@ -867,6 +1200,7 @@ static void balloon_onchannelcallback(void *context) struct dm_balloon *bal_msg; struct dm_hot_add *ha_msg; union dm_mem_page_range *ha_pg_range; + union dm_mem_page_range *ha_region; memset(recv_buffer, 0, sizeof(recv_buffer)); vmbus_recvpacket(dev->channel, recv_buffer, @@ -907,8 +1241,26 @@ static void balloon_onchannelcallback(void *context) pr_warn("Currently hot-adding\n"); dm->state = DM_HOT_ADD; ha_msg = (struct dm_hot_add *)recv_buffer; - ha_pg_range = &ha_msg->range; - dm_device.ha_wrk.ha_page_range = *ha_pg_range; + if (ha_msg->hdr.size == sizeof(struct dm_hot_add)) { + /* + * This is a normal hot-add request specifying + * hot-add memory. + */ + ha_pg_range = &ha_msg->range; + dm->ha_wrk.ha_page_range = *ha_pg_range; + dm->ha_wrk.ha_region_range.page_range = 0; + } else { + /* + * Host is specifying that we first hot-add + * a region and then partially populate this + * region. + */ + dm->host_specified_ha_region = true; + ha_pg_range = &ha_msg->range; + ha_region = &ha_pg_range[1]; + dm->ha_wrk.ha_page_range = *ha_pg_range; + dm->ha_wrk.ha_region_range = *ha_region; + } schedule_work(&dm_device.ha_wrk.wrk); break; @@ -952,8 +1304,10 @@ static int balloon_probe(struct hv_device *dev, dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; init_completion(&dm_device.host_event); init_completion(&dm_device.config_event); + INIT_LIST_HEAD(&dm_device.ha_region_list); INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up); INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req); + dm_device.host_specified_ha_region = false; dm_device.thread = kthread_run(dm_thread_func, &dm_device, "hv_balloon"); @@ -962,6 +1316,10 @@ static int balloon_probe(struct hv_device *dev, goto probe_error1; } +#ifdef CONFIG_MEMORY_HOTPLUG + set_online_page_callback(&hv_online_page); +#endif + hv_set_drvdata(dev, &dm_device); /* * Initiate the hand shake with the host and negotiate @@ -1006,12 +1364,6 @@ static int balloon_probe(struct hv_device *dev, cap_msg.hdr.trans_id = atomic_inc_return(&trans_id); cap_msg.caps.cap_bits.balloon = 1; - /* - * While we currently don't support hot-add, - * we still advertise this capability since the - * host requires that guests partcipating in the - * dynamic memory protocol support hot add. - */ cap_msg.caps.cap_bits.hot_add = 1; /* @@ -1049,6 +1401,9 @@ static int balloon_probe(struct hv_device *dev, return 0; probe_error2: +#ifdef CONFIG_MEMORY_HOTPLUG + restore_online_page_callback(&hv_online_page); +#endif kthread_stop(dm_device.thread); probe_error1: @@ -1061,15 +1416,26 @@ probe_error0: static int balloon_remove(struct hv_device *dev) { struct hv_dynmem_device *dm = hv_get_drvdata(dev); + struct list_head *cur, *tmp; + struct hv_hotadd_state *has; if (dm->num_pages_ballooned != 0) pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); cancel_work_sync(&dm->balloon_wrk.wrk); cancel_work_sync(&dm->ha_wrk.wrk); + vmbus_close(dev->channel); kthread_stop(dm->thread); kfree(send_buffer); +#ifdef CONFIG_MEMORY_HOTPLUG + restore_online_page_callback(&hv_online_page); +#endif + list_for_each_safe(cur, tmp, &dm->ha_region_list) { + has = list_entry(cur, struct hv_hotadd_state, list); + list_del(&has->list); + kfree(has); + } return 0; } -- cgit From c87059793dd02390b504b0292bdb024ffd68b822 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:25:44 -0700 Subject: Drivers: hv: vmbus: Handle channel rescind message correctly Properly cleanup the channel state on receipt of the "offer rescind" message. Starting with ws2012, the host requires that the channel "relid" be properly cleaned up when the offer is rescinded. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index ff1be167eb04..bad8128b283a 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -165,8 +165,19 @@ static void vmbus_process_rescind_offer(struct work_struct *work) struct vmbus_channel *channel = container_of(work, struct vmbus_channel, work); + unsigned long flags; + struct vmbus_channel_relid_released msg; vmbus_device_unregister(channel->device_obj); + memset(&msg, 0, sizeof(struct vmbus_channel_relid_released)); + msg.child_relid = channel->offermsg.child_relid; + msg.header.msgtype = CHANNELMSG_RELID_RELEASED; + vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); + + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + list_del(&channel->listentry); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); + free_channel(channel); } void vmbus_free_channels(void) -- cgit From 96dd86fa588169b745a71aedf2070e80f4943623 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 15 Mar 2013 12:30:06 -0700 Subject: Drivers: hv: Add a new driver to support host initiated backup This driver supports host initiated backup of the guest. On Windows guests, the host can generate application consistent backups using the Windows VSS framework. On Linux, we ensure that the backup will be file system consistent. This driver allows the host to initiate a "Freeze" operation on all the mounted file systems in the guest. Once the mounted file systems in the guest are frozen, the host snapshots the guest's file systems. Once this is done, the guest's file systems are "thawed". This driver has a user-level component (daemon) that invokes the appropriate operation on all the mounted file systems in response to the requests from the host. The duration for which the guest is frozen is very short - a few seconds. During this interval, the diff disk is comitted. In this version of the patch I have addressed the feedback from Olaf Herring. Also, some of the connector related issues have been fixed. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Cc: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/hv/Makefile | 2 +- drivers/hv/hv_snapshot.c | 287 +++++++++++++++++++++++++++++++++++++++++ drivers/hv/hv_util.c | 10 ++ include/linux/hyperv.h | 69 ++++++++++ include/uapi/linux/connector.h | 5 +- tools/hv/hv_vss_daemon.c | 220 +++++++++++++++++++++++++++++++ 6 files changed, 591 insertions(+), 2 deletions(-) create mode 100644 drivers/hv/hv_snapshot.c create mode 100644 tools/hv/hv_vss_daemon.c (limited to 'drivers') diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile index e6abfa02d8b7..0a74b5661186 100644 --- a/drivers/hv/Makefile +++ b/drivers/hv/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o -hv_utils-y := hv_util.o hv_kvp.o +hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c new file mode 100644 index 000000000000..8ad5653ce447 --- /dev/null +++ b/drivers/hv/hv_snapshot.c @@ -0,0 +1,287 @@ +/* + * An implementation of host initiated guest snapshot. + * + * + * Copyright (C) 2013, Microsoft, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + + + +/* + * Global state maintained for transaction that is being processed. + * Note that only one transaction can be active at any point in time. + * + * This state is set when we receive a request from the host; we + * cleanup this state when the transaction is completed - when we respond + * to the host with the key value. + */ + +static struct { + bool active; /* transaction status - active or not */ + int recv_len; /* number of bytes received. */ + struct vmbus_channel *recv_channel; /* chn we got the request */ + u64 recv_req_id; /* request ID. */ + struct hv_vss_msg *msg; /* current message */ +} vss_transaction; + + +static void vss_respond_to_host(int error); + +static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL }; +static const char vss_name[] = "vss_kernel_module"; +static __u8 *recv_buffer; + +static void vss_send_op(struct work_struct *dummy); +static DECLARE_WORK(vss_send_op_work, vss_send_op); + +/* + * Callback when data is received from user mode. + */ + +static void +vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) +{ + struct hv_vss_msg *vss_msg; + + vss_msg = (struct hv_vss_msg *)msg->data; + + if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { + pr_info("VSS daemon registered\n"); + vss_transaction.active = false; + if (vss_transaction.recv_channel != NULL) + hv_vss_onchannelcallback(vss_transaction.recv_channel); + return; + + } + vss_respond_to_host(vss_msg->error); +} + + +static void vss_send_op(struct work_struct *dummy) +{ + int op = vss_transaction.msg->vss_hdr.operation; + struct cn_msg *msg; + struct hv_vss_msg *vss_msg; + + msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC); + if (!msg) + return; + + vss_msg = (struct hv_vss_msg *)msg->data; + + msg->id.idx = CN_VSS_IDX; + msg->id.val = CN_VSS_VAL; + + vss_msg->vss_hdr.operation = op; + msg->len = sizeof(struct hv_vss_msg); + + cn_netlink_send(msg, 0, GFP_ATOMIC); + kfree(msg); + + return; +} + +/* + * Send a response back to the host. + */ + +static void +vss_respond_to_host(int error) +{ + struct icmsg_hdr *icmsghdrp; + u32 buf_len; + struct vmbus_channel *channel; + u64 req_id; + + /* + * If a transaction is not active; log and return. + */ + + if (!vss_transaction.active) { + /* + * This is a spurious call! + */ + pr_warn("VSS: Transaction not active\n"); + return; + } + /* + * Copy the global state for completing the transaction. Note that + * only one transaction can be active at a time. + */ + + buf_len = vss_transaction.recv_len; + channel = vss_transaction.recv_channel; + req_id = vss_transaction.recv_req_id; + vss_transaction.active = false; + + icmsghdrp = (struct icmsg_hdr *) + &recv_buffer[sizeof(struct vmbuspipe_hdr)]; + + if (channel->onchannel_callback == NULL) + /* + * We have raced with util driver being unloaded; + * silently return. + */ + return; + + icmsghdrp->status = error; + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, + VM_PKT_DATA_INBAND, 0); + +} + +/* + * This callback is invoked when we get a VSS message from the host. + * The host ensures that only one VSS transaction can be active at a time. + */ + +void hv_vss_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u32 recvlen; + u64 requestid; + struct hv_vss_msg *vss_msg; + + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + if (vss_transaction.active) { + /* + * We will defer processing this callback once + * the current transaction is complete. + */ + vss_transaction.recv_channel = channel; + return; + } + + vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, + &requestid); + + if (recvlen > 0) { + icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + vmbus_prep_negotiate_resp(icmsghdrp, negop, + recv_buffer, MAX_SRV_VER, MAX_SRV_VER); + /* + * We currently negotiate the highest number the + * host has presented. If this version is not + * atleast 5.0, reject. + */ + negop = (struct icmsg_negotiate *)&recv_buffer[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + if (negop->icversion_data[1].major < 5) + negop->icframe_vercnt = 0; + } else { + vss_msg = (struct hv_vss_msg *)&recv_buffer[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + /* + * Stash away this global state for completing the + * transaction; note transactions are serialized. + */ + + vss_transaction.recv_len = recvlen; + vss_transaction.recv_channel = channel; + vss_transaction.recv_req_id = requestid; + vss_transaction.active = true; + vss_transaction.msg = (struct hv_vss_msg *)vss_msg; + + switch (vss_msg->vss_hdr.operation) { + /* + * Initiate a "freeze/thaw" + * operation in the guest. + * We respond to the host once + * the operation is complete. + * + * We send the message to the + * user space daemon and the + * operation is performed in + * the daemon. + */ + case VSS_OP_FREEZE: + case VSS_OP_THAW: + schedule_work(&vss_send_op_work); + return; + + case VSS_OP_HOT_BACKUP: + vss_msg->vss_cf.flags = + VSS_HBU_NO_AUTO_RECOVERY; + vss_respond_to_host(0); + return; + + case VSS_OP_GET_DM_INFO: + vss_msg->dm_info.flags = 0; + vss_respond_to_host(0); + return; + + default: + vss_respond_to_host(0); + return; + + } + + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, recv_buffer, + recvlen, requestid, + VM_PKT_DATA_INBAND, 0); + } + +} + +int +hv_vss_init(struct hv_util_service *srv) +{ + int err; + + err = cn_add_callback(&vss_id, vss_name, vss_cn_callback); + if (err) + return err; + recv_buffer = srv->recv_buffer; + + /* + * When this driver loads, the user level daemon that + * processes the host requests may not yet be running. + * Defer processing channel callbacks until the daemon + * has registered. + */ + vss_transaction.active = true; + return 0; +} + +void hv_vss_deinit(void) +{ + cn_del_callback(&vss_id); + cancel_work_sync(&vss_send_op_work); +} diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 1d4cbd8e8261..2f561c5dfe24 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -49,6 +49,12 @@ static struct hv_util_service util_kvp = { .util_deinit = hv_kvp_deinit, }; +static struct hv_util_service util_vss = { + .util_cb = hv_vss_onchannelcallback, + .util_init = hv_vss_init, + .util_deinit = hv_vss_deinit, +}; + static void perform_shutdown(struct work_struct *dummy) { orderly_poweroff(true); @@ -339,6 +345,10 @@ static const struct hv_vmbus_device_id id_table[] = { { HV_KVP_GUID, .driver_data = (unsigned long)&util_kvp }, + /* VSS GUID */ + { HV_VSS_GUID, + .driver_data = (unsigned long)&util_vss + }, { }, }; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index df77ba9a8166..95d0850584da 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -27,6 +27,63 @@ #include + +/* + * Implementation of host controlled snapshot of the guest. + */ + +#define VSS_OP_REGISTER 128 + +enum hv_vss_op { + VSS_OP_CREATE = 0, + VSS_OP_DELETE, + VSS_OP_HOT_BACKUP, + VSS_OP_GET_DM_INFO, + VSS_OP_BU_COMPLETE, + /* + * Following operations are only supported with IC version >= 5.0 + */ + VSS_OP_FREEZE, /* Freeze the file systems in the VM */ + VSS_OP_THAW, /* Unfreeze the file systems */ + VSS_OP_AUTO_RECOVER, + VSS_OP_COUNT /* Number of operations, must be last */ +}; + + +/* + * Header for all VSS messages. + */ +struct hv_vss_hdr { + __u8 operation; + __u8 reserved[7]; +} __attribute__((packed)); + + +/* + * Flag values for the hv_vss_check_feature. Linux supports only + * one value. + */ +#define VSS_HBU_NO_AUTO_RECOVERY 0x00000005 + +struct hv_vss_check_feature { + __u32 flags; +} __attribute__((packed)); + +struct hv_vss_check_dm_info { + __u32 flags; +} __attribute__((packed)); + +struct hv_vss_msg { + union { + struct hv_vss_hdr vss_hdr; + int error; + }; + union { + struct hv_vss_check_feature vss_cf; + struct hv_vss_check_dm_info dm_info; + }; +} __attribute__((packed)); + /* * An implementation of HyperV key value pair (KVP) functionality for Linux. * @@ -1252,6 +1309,14 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver); 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \ } +/* + * VSS (Backup/Restore) GUID + */ +#define HV_VSS_GUID \ + .guid = { \ + 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ + 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ + } /* * Common header for Hyper-V ICs */ @@ -1356,6 +1421,10 @@ int hv_kvp_init(struct hv_util_service *); void hv_kvp_deinit(void); void hv_kvp_onchannelcallback(void *); +int hv_vss_init(struct hv_util_service *); +void hv_vss_deinit(void); +void hv_vss_onchannelcallback(void *); + /* * Negotiated version with the Host. */ diff --git a/include/uapi/linux/connector.h b/include/uapi/linux/connector.h index 8761a0349c74..4cb283505e45 100644 --- a/include/uapi/linux/connector.h +++ b/include/uapi/linux/connector.h @@ -44,8 +44,11 @@ #define CN_VAL_DRBD 0x1 #define CN_KVP_IDX 0x9 /* HyperV KVP */ #define CN_KVP_VAL 0x1 /* queries from the kernel */ +#define CN_VSS_IDX 0xA /* HyperV VSS */ +#define CN_VSS_VAL 0x1 /* queries from the kernel */ -#define CN_NETLINK_USERS 10 /* Highest index + 1 */ + +#define CN_NETLINK_USERS 11 /* Highest index + 1 */ /* * Maximum connector's message size. diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c new file mode 100644 index 000000000000..95269952aa92 --- /dev/null +++ b/tools/hv/hv_vss_daemon.c @@ -0,0 +1,220 @@ +/* + * An implementation of the host initiated guest snapshot for Hyper-V. + * + * + * Copyright (C) 2013, Microsoft, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char vss_recv_buffer[4096]; +static char vss_send_buffer[4096]; +static struct sockaddr_nl addr; + +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + + +static int vss_operate(int operation) +{ + char *fs_op; + char cmd[512]; + char buf[512]; + FILE *file; + char *p; + char *x; + int error; + + switch (operation) { + case VSS_OP_FREEZE: + fs_op = "-f "; + break; + case VSS_OP_THAW: + fs_op = "-u "; + break; + } + + file = popen("mount | awk '/^\/dev\// { print $3}'", "r"); + if (file == NULL) + return; + + while ((p = fgets(buf, sizeof(buf), file)) != NULL) { + x = strchr(p, '\n'); + *x = '\0'; + if (!strncmp(p, "/", sizeof("/"))) + continue; + + sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, p); + syslog(LOG_INFO, "VSS cmd is %s\n", cmd); + error = system(cmd); + } + pclose(file); + + sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, "/"); + syslog(LOG_INFO, "VSS cmd is %s\n", cmd); + error = system(cmd); + + return error; +} + +static int netlink_send(int fd, struct cn_msg *msg) +{ + struct nlmsghdr *nlh; + unsigned int size; + struct msghdr message; + char buffer[64]; + struct iovec iov[2]; + + size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); + + nlh = (struct nlmsghdr *)buffer; + nlh->nlmsg_seq = 0; + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = NLMSG_DONE; + nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh)); + nlh->nlmsg_flags = 0; + + iov[0].iov_base = nlh; + iov[0].iov_len = sizeof(*nlh); + + iov[1].iov_base = msg; + iov[1].iov_len = size; + + memset(&message, 0, sizeof(message)); + message.msg_name = &addr; + message.msg_namelen = sizeof(addr); + message.msg_iov = iov; + message.msg_iovlen = 2; + + return sendmsg(fd, &message, 0); +} + +int main(void) +{ + int fd, len, nl_group; + int error; + struct cn_msg *message; + struct pollfd pfd; + struct nlmsghdr *incoming_msg; + struct cn_msg *incoming_cn_msg; + int op; + struct hv_vss_msg *vss_msg; + + daemon(1, 0); + openlog("Hyper-V VSS", 0, LOG_USER); + syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); + + fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); + if (fd < 0) { + syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd); + exit(EXIT_FAILURE); + } + addr.nl_family = AF_NETLINK; + addr.nl_pad = 0; + addr.nl_pid = 0; + addr.nl_groups = 0; + + + error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (error < 0) { + syslog(LOG_ERR, "bind failed; error:%d", error); + close(fd); + exit(EXIT_FAILURE); + } + nl_group = CN_VSS_IDX; + setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)); + /* + * Register ourselves with the kernel. + */ + message = (struct cn_msg *)vss_send_buffer; + message->id.idx = CN_VSS_IDX; + message->id.val = CN_VSS_VAL; + message->ack = 0; + vss_msg = (struct hv_vss_msg *)message->data; + vss_msg->vss_hdr.operation = VSS_OP_REGISTER; + + message->len = sizeof(struct hv_vss_msg); + + len = netlink_send(fd, message); + if (len < 0) { + syslog(LOG_ERR, "netlink_send failed; error:%d", len); + close(fd); + exit(EXIT_FAILURE); + } + + pfd.fd = fd; + + while (1) { + struct sockaddr *addr_p = (struct sockaddr *) &addr; + socklen_t addr_l = sizeof(addr); + pfd.events = POLLIN; + pfd.revents = 0; + poll(&pfd, 1, -1); + + len = recvfrom(fd, vss_recv_buffer, sizeof(vss_recv_buffer), 0, + addr_p, &addr_l); + + if (len < 0 || addr.nl_pid) { + syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", + addr.nl_pid, errno, strerror(errno)); + close(fd); + return -1; + } + + incoming_msg = (struct nlmsghdr *)vss_recv_buffer; + + if (incoming_msg->nlmsg_type != NLMSG_DONE) + continue; + + incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); + vss_msg = (struct hv_vss_msg *)incoming_cn_msg->data; + op = vss_msg->vss_hdr.operation; + error = HV_S_OK; + + switch (op) { + case VSS_OP_FREEZE: + case VSS_OP_THAW: + error = vss_operate(op); + if (error) + error = HV_E_FAIL; + break; + default: + syslog(LOG_ERR, "Illegal op:%d\n", op); + } + vss_msg->error = error; + len = netlink_send(fd, incoming_cn_msg); + if (len < 0) { + syslog(LOG_ERR, "net_link send failed; error:%d", len); + exit(EXIT_FAILURE); + } + } + +} -- cgit From aceca2854498de7384ee7b44d8eb7820fd4c7f16 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Fri, 15 Mar 2013 14:20:25 -0400 Subject: w1: ds2408: make value read-back check a Kconfig option De-activating this reading back will effectively half the time required for a write to the output register. Acked-by: Evgeniy Polyakov Signed-off-by: Jean-Francois Dagenais Signed-off-by: Greg Kroah-Hartman --- drivers/w1/slaves/Kconfig | 10 ++++++++++ drivers/w1/slaves/w1_ds2408.c | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 762561fbabbf..5e6a3c9e510b 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -22,6 +22,16 @@ config W1_SLAVE_DS2408 Say Y here if you want to use a 1-wire DS2408 8-Channel Addressable Switch device support +config W1_SLAVE_DS2408_READBACK + bool "Read-back values written to DS2408's output register" + depends on W1_SLAVE_DS2408 + default y + help + Enabling this will cause the driver to read back the values written + to the chip's output register in order to detect errors. + + This is slower but useful when debugging chips and/or busses. + config W1_SLAVE_DS2413 tristate "Dual Channel Addressable Switch 0x3a family support (DS2413)" help diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 441ad3a3b586..25a5168ab522 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -178,6 +178,15 @@ static ssize_t w1_f29_write_output( w1_write_block(sl->master, w1_buf, 3); readBack = w1_read_8(sl->master); + + if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) { + if (w1_reset_resume_command(sl->master)) + goto error; + /* try again, the slave is ready for a command */ + continue; + } + +#ifdef CONFIG_W1_SLAVE_DS2408_READBACK /* here the master could read another byte which would be the PIO reg (the actual pin logic state) since in this driver we don't know which pins are @@ -186,11 +195,6 @@ static ssize_t w1_f29_write_output( if (w1_reset_resume_command(sl->master)) goto error; - if (readBack != 0xAA) { - /* try again, the slave is ready for a command */ - continue; - } - /* go read back the output latches */ /* (the direct effect of the write above) */ w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; @@ -198,7 +202,9 @@ static ssize_t w1_f29_write_output( w1_buf[2] = 0; w1_write_block(sl->master, w1_buf, 3); /* read the result of the READ_PIO_REGS command */ - if (w1_read_8(sl->master) == *buf) { + if (w1_read_8(sl->master) == *buf) +#endif + { /* success! */ mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, -- cgit From 1116575d918a7d5fe6d1adf46c5bbdf11dcec51b Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Fri, 15 Mar 2013 14:20:26 -0400 Subject: w1: ds2408: use ARRAY_SIZE instead of hard-coded number Acked-by: Evgeniy Polyakov Signed-off-by: Jean-Francois Dagenais Signed-off-by: Greg Kroah-Hartman --- drivers/w1/slaves/w1_ds2408.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 25a5168ab522..e45eca1044bd 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -303,8 +303,7 @@ error: -#define NB_SYSFS_BIN_FILES 6 -static struct bin_attribute w1_f29_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { +static struct bin_attribute w1_f29_sysfs_bin_files[] = { { .attr = { .name = "state", @@ -363,7 +362,7 @@ static int w1_f29_add_slave(struct w1_slave *sl) int err = 0; int i; - for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) + for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i) err = sysfs_create_bin_file( &sl->dev.kobj, &(w1_f29_sysfs_bin_files[i])); @@ -377,7 +376,7 @@ static int w1_f29_add_slave(struct w1_slave *sl) static void w1_f29_remove_slave(struct w1_slave *sl) { int i; - for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i) + for (i = ARRAY_SIZE(w1_f29_sysfs_bin_files) - 1; i >= 0; --i) sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f29_sysfs_bin_files[i])); } -- cgit From d4cba7fa7e2b25b463e51006bdeab7110f96ec33 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Thu, 14 Mar 2013 11:12:10 +0200 Subject: memory: tegra30: Fix build error w/o PM Make this depend on CONFIG_PM. Signed-off-by: Hiroshi Doyu Reviewed-by: Thierry Reding Signed-off-by: Stephen Warren --- drivers/memory/tegra30-mc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c index 0b975986777d..f4ae074badc3 100644 --- a/drivers/memory/tegra30-mc.c +++ b/drivers/memory/tegra30-mc.c @@ -268,6 +268,7 @@ static const u32 tegra30_mc_ctx[] = { MC_INTMASK, }; +#ifdef CONFIG_PM static int tegra30_mc_suspend(struct device *dev) { int i; @@ -291,6 +292,7 @@ static int tegra30_mc_resume(struct device *dev) mc_readl(mc, MC_TIMING_CONTROL); return 0; } +#endif static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm, tegra30_mc_suspend, -- cgit From fa882867ae5f8543eb304a1667563f1c99514475 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 8 Mar 2013 09:21:46 +0100 Subject: ipack: add ipack_get_device() ipack_put_device() Prepare everything for later use. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/ipack.c | 12 ++++++++++++ include/linux/ipack.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 7ec6b208b1cb..4f913aa88971 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -461,6 +461,18 @@ void ipack_device_unregister(struct ipack_device *dev) } EXPORT_SYMBOL_GPL(ipack_device_unregister); +void ipack_get_device(struct ipack_device *dev) +{ + get_device(&dev->dev); +} +EXPORT_SYMBOL_GPL(ipack_get_device); + +void ipack_put_device(struct ipack_device *dev) +{ + put_device(&dev->dev); +} +EXPORT_SYMBOL_GPL(ipack_put_device); + static int __init ipack_init(void) { ida_init(&ipack_ida); diff --git a/include/linux/ipack.h b/include/linux/ipack.h index fea12cbb2aeb..def91fd996f4 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -221,6 +221,9 @@ void ipack_driver_unregister(struct ipack_driver *edrv); int ipack_device_register(struct ipack_device *dev); void ipack_device_unregister(struct ipack_device *dev); +void ipack_get_device(struct ipack_device *dev); +void ipack_put_device(struct ipack_device *dev); + /** * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table * @_table: device table name -- cgit From e926301b39a07f587ff8c66354a2e2ee4c29162c Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 8 Mar 2013 09:21:47 +0100 Subject: ipack: split ipack_device_register() in several functions One function is ipack_device_init(). If it fails, the caller should execute ipack_put_device(). The second function is ipack_device_add that only adds the device. If it fails, the caller should execute ipack_put_device(). Then the device is removed with refcount = 0, as device_register() kernel documentation says. ipack_device_del() is added to remove the device. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/carriers/tpci200.c | 14 +++++++++++++- drivers/ipack/ipack.c | 24 ++++++++++++++---------- include/linux/ipack.h | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index 0246b1fddffe..c276fde318e5 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -480,6 +480,7 @@ static void tpci200_release_device(struct ipack_device *dev) static int tpci200_create_device(struct tpci200_board *tpci200, int i) { + int ret; enum ipack_space space; struct ipack_device *dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); @@ -495,7 +496,18 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i) + tpci200_space_interval[space] * i; dev->region[space].size = tpci200_space_size[space]; } - return ipack_device_register(dev); + + ret = ipack_device_init(dev); + if (ret < 0) { + ipack_put_device(dev); + return ret; + } + + ret = ipack_device_add(dev); + if (ret < 0) + ipack_put_device(dev); + + return ret; } static int tpci200_pci_probe(struct pci_dev *pdev, diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 4f913aa88971..6e066c53acce 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -227,7 +227,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data) struct ipack_bus_device *bus = data; if (idev->bus == bus) - ipack_device_unregister(idev); + ipack_device_del(idev); return 1; } @@ -419,7 +419,7 @@ out: return ret; } -int ipack_device_register(struct ipack_device *dev) +int ipack_device_init(struct ipack_device *dev) { int ret; @@ -428,6 +428,7 @@ int ipack_device_register(struct ipack_device *dev) dev->dev.parent = dev->bus->parent; dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); + device_initialize(&dev->dev); if (dev->bus->ops->set_clockrate(dev, 8)) dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); @@ -447,19 +448,22 @@ int ipack_device_register(struct ipack_device *dev) dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); } - ret = device_register(&dev->dev); - if (ret < 0) - kfree(dev->id); + return 0; +} +EXPORT_SYMBOL_GPL(ipack_device_init); - return ret; +int ipack_device_add(struct ipack_device *dev) +{ + return device_add(&dev->dev); } -EXPORT_SYMBOL_GPL(ipack_device_register); +EXPORT_SYMBOL_GPL(ipack_device_add); -void ipack_device_unregister(struct ipack_device *dev) +void ipack_device_del(struct ipack_device *dev) { - device_unregister(&dev->dev); + device_del(&dev->dev); + ipack_put_device(dev); } -EXPORT_SYMBOL_GPL(ipack_device_unregister); +EXPORT_SYMBOL_GPL(ipack_device_del); void ipack_get_device(struct ipack_device *dev) { diff --git a/include/linux/ipack.h b/include/linux/ipack.h index def91fd996f4..1888e06ddf64 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -207,19 +207,38 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, void ipack_driver_unregister(struct ipack_driver *edrv); /** - * ipack_device_register -- register an IPack device with the kernel - * @dev: the new device to register. + * ipack_device_init -- initialize an IPack device + * @dev: the new device to initialize. * - * Register a new IPack device ("module" in IndustryPack jargon). The call - * is done by the carrier driver. The carrier should populate the fields - * bus and slot as well as the region array of @dev prior to calling this - * function. The rest of the fields will be allocated and populated - * during registration. + * Initialize a new IPack device ("module" in IndustryPack jargon). The call + * is done by the carrier driver. The carrier should populate the fields + * bus and slot as well as the region array of @dev prior to calling this + * function. The rest of the fields will be allocated and populated + * during initalization. * - * Return zero on success or error code on failure. + * Return zero on success or error code on failure. + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use ipack_put_device() to give up the + * reference initialized in this function instead. + */ +int ipack_device_init(struct ipack_device *dev); + +/** + * ipack_device_add -- Add an IPack device + * @dev: the new device to add. + * + * Add a new IPack device. The call is done by the carrier driver + * after calling ipack_device_init(). + * + * Return zero on success or error code on failure. + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use ipack_put_device() to give up the + * reference initialized in this function instead. */ -int ipack_device_register(struct ipack_device *dev); -void ipack_device_unregister(struct ipack_device *dev); +int ipack_device_add(struct ipack_device *dev); +void ipack_device_del(struct ipack_device *dev); void ipack_get_device(struct ipack_device *dev); void ipack_put_device(struct ipack_device *dev); -- cgit From 2154e0a4f43e0c811737e391e7981d331e450d42 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 1 Mar 2013 23:31:46 +0300 Subject: applicom: use correct array offset We're iterating through abps[] printing information, but here we use the wrong array index. IndexCard comes from the user and in this case it was specifically not range checked because we didn't expect to use it. Signed-off-by: Dan Carpenter Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/char/applicom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 25373df1dcf8..974321a2508d 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -804,8 +804,8 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) printk(KERN_INFO "Prom version board %d ....... V%d.%d %s", i+1, - (int)(readb(apbs[IndexCard].RamIO + VERS) >> 4), - (int)(readb(apbs[IndexCard].RamIO + VERS) & 0xF), + (int)(readb(apbs[i].RamIO + VERS) >> 4), + (int)(readb(apbs[i].RamIO + VERS) & 0xF), boardname); -- cgit From e7c2199ff300fcf88673a1cf6d7229e6c3da09de Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Thu, 14 Mar 2013 18:09:33 +0100 Subject: drivers: char: use module_platform_driver_probe() This patch converts the drivers to use the module_platform_driver_probe() macro which makes the code smaller and a bit simpler. Signed-off-by: Fabio Porcedda Cc: Matt Mackall Cc: Herbert Xu Cc: Fabio Estevam Cc: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/char/hw_random/mxc-rnga.c | 13 +------------ drivers/char/hw_random/tx4939-rng.c | 13 +------------ 2 files changed, 2 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index f05d85713fd3..895d0b8fb9ab 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c @@ -228,18 +228,7 @@ static struct platform_driver mxc_rnga_driver = { .remove = __exit_p(mxc_rnga_remove), }; -static int __init mod_init(void) -{ - return platform_driver_probe(&mxc_rnga_driver, mxc_rnga_probe); -} - -static void __exit mod_exit(void) -{ - platform_driver_unregister(&mxc_rnga_driver); -} - -module_init(mod_init); -module_exit(mod_exit); +module_platform_driver_probe(mxc_rnga_driver, mxc_rnga_probe); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("H/W RNGA driver for i.MX"); diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 30991989d65b..d34a24a0d484 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c @@ -166,18 +166,7 @@ static struct platform_driver tx4939_rng_driver = { .remove = tx4939_rng_remove, }; -static int __init tx4939rng_init(void) -{ - return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe); -} - -static void __exit tx4939rng_exit(void) -{ - platform_driver_unregister(&tx4939_rng_driver); -} - -module_init(tx4939rng_init); -module_exit(tx4939rng_exit); +module_platform_driver_probe(tx4939_rng_driver, tx4939_rng_probe); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939"); MODULE_LICENSE("GPL"); -- cgit From 460604850a0cfcdb124fa627f56ca91529fb6c59 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:25:44 -0700 Subject: drivers/ata: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/ata/pata_pcmcia.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 958238dda8fc..40254f4df584 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -387,21 +387,9 @@ static struct pcmcia_driver pcmcia_driver = { .probe = pcmcia_init_one, .remove = pcmcia_remove_one, }; - -static int __init pcmcia_init(void) -{ - return pcmcia_register_driver(&pcmcia_driver); -} - -static void __exit pcmcia_exit(void) -{ - pcmcia_unregister_driver(&pcmcia_driver); -} +module_pcmcia_driver(pcmcia_driver); MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for PCMCIA ATA"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(pcmcia_init); -module_exit(pcmcia_exit); -- cgit From e0c005f4b9fe8bb2bceb5ce9f69eaa61383f41db Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:26:24 -0700 Subject: drivers/bluetooth: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/bluecard_cs.c | 15 +-------------- drivers/bluetooth/bt3c_cs.c | 15 +-------------- drivers/bluetooth/btuart_cs.c | 15 +-------------- drivers/bluetooth/dtl1_cs.c | 15 +-------------- 4 files changed, 4 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 0d26851d6e49..6c3e3d43c718 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -934,17 +934,4 @@ static struct pcmcia_driver bluecard_driver = { .remove = bluecard_detach, .id_table = bluecard_ids, }; - -static int __init init_bluecard_cs(void) -{ - return pcmcia_register_driver(&bluecard_driver); -} - - -static void __exit exit_bluecard_cs(void) -{ - pcmcia_unregister_driver(&bluecard_driver); -} - -module_init(init_bluecard_cs); -module_exit(exit_bluecard_cs); +module_pcmcia_driver(bluecard_driver); diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 7ffd3f407144..a1aaa3ba2a4b 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -760,17 +760,4 @@ static struct pcmcia_driver bt3c_driver = { .remove = bt3c_detach, .id_table = bt3c_ids, }; - -static int __init init_bt3c_cs(void) -{ - return pcmcia_register_driver(&bt3c_driver); -} - - -static void __exit exit_bt3c_cs(void) -{ - pcmcia_unregister_driver(&bt3c_driver); -} - -module_init(init_bt3c_cs); -module_exit(exit_bt3c_cs); +module_pcmcia_driver(bt3c_driver); diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 35a553a90616..beb262f2dc4d 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -688,17 +688,4 @@ static struct pcmcia_driver btuart_driver = { .remove = btuart_detach, .id_table = btuart_ids, }; - -static int __init init_btuart_cs(void) -{ - return pcmcia_register_driver(&btuart_driver); -} - - -static void __exit exit_btuart_cs(void) -{ - pcmcia_unregister_driver(&btuart_driver); -} - -module_init(init_btuart_cs); -module_exit(exit_btuart_cs); +module_pcmcia_driver(btuart_driver); diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 036cb366fe6e..33f3a6950c0e 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -628,17 +628,4 @@ static struct pcmcia_driver dtl1_driver = { .remove = dtl1_detach, .id_table = dtl1_ids, }; - -static int __init init_dtl1_cs(void) -{ - return pcmcia_register_driver(&dtl1_driver); -} - - -static void __exit exit_dtl1_cs(void) -{ - pcmcia_unregister_driver(&dtl1_driver); -} - -module_init(init_dtl1_cs); -module_exit(exit_dtl1_cs); +module_pcmcia_driver(dtl1_driver); -- cgit From 0aae9c6a913483b69b5cb703329cbf1ed3efbfcb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:26:50 -0700 Subject: drivers/isdn: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/hardware/avm/avm_cs.c | 14 +------------- drivers/isdn/hisax/avma1_cs.c | 14 +------------- drivers/isdn/hisax/elsa_cs.c | 14 +------------- drivers/isdn/hisax/sedlbauer_cs.c | 14 +------------- drivers/isdn/hisax/teles_cs.c | 14 +------------- 5 files changed, 5 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index c21353d8e915..62b8030ee331 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -163,16 +163,4 @@ static struct pcmcia_driver avmcs_driver = { .remove = avmcs_detach, .id_table = avmcs_ids, }; - -static int __init avmcs_init(void) -{ - return pcmcia_register_driver(&avmcs_driver); -} - -static void __exit avmcs_exit(void) -{ - pcmcia_unregister_driver(&avmcs_driver); -} - -module_init(avmcs_init); -module_exit(avmcs_exit); +module_pcmcia_driver(avmcs_driver); diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 4e676bcf8506..baad94ec1f4a 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -159,16 +159,4 @@ static struct pcmcia_driver avma1cs_driver = { .remove = avma1cs_detach, .id_table = avma1cs_ids, }; - -static int __init init_avma1_cs(void) -{ - return pcmcia_register_driver(&avma1cs_driver); -} - -static void __exit exit_avma1_cs(void) -{ - pcmcia_unregister_driver(&avma1cs_driver); -} - -module_init(init_avma1_cs); -module_exit(exit_avma1_cs); +module_pcmcia_driver(avma1cs_driver); diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index ebe56918f6fc..40f6fad79de3 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -215,16 +215,4 @@ static struct pcmcia_driver elsa_cs_driver = { .suspend = elsa_suspend, .resume = elsa_resume, }; - -static int __init init_elsa_cs(void) -{ - return pcmcia_register_driver(&elsa_cs_driver); -} - -static void __exit exit_elsa_cs(void) -{ - pcmcia_unregister_driver(&elsa_cs_driver); -} - -module_init(init_elsa_cs); -module_exit(exit_elsa_cs); +module_pcmcia_driver(elsa_cs_driver); diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 90f81291641b..92ef62d4caf4 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -206,16 +206,4 @@ static struct pcmcia_driver sedlbauer_driver = { .suspend = sedlbauer_suspend, .resume = sedlbauer_resume, }; - -static int __init init_sedlbauer_cs(void) -{ - return pcmcia_register_driver(&sedlbauer_driver); -} - -static void __exit exit_sedlbauer_cs(void) -{ - pcmcia_unregister_driver(&sedlbauer_driver); -} - -module_init(init_sedlbauer_cs); -module_exit(exit_sedlbauer_cs); +module_pcmcia_driver(sedlbauer_driver); diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index f2476ffb04fd..b8dd14958757 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -197,16 +197,4 @@ static struct pcmcia_driver teles_cs_driver = { .suspend = teles_suspend, .resume = teles_resume, }; - -static int __init init_teles_cs(void) -{ - return pcmcia_register_driver(&teles_cs_driver); -} - -static void __exit exit_teles_cs(void) -{ - pcmcia_unregister_driver(&teles_cs_driver); -} - -module_init(init_teles_cs); -module_exit(exit_teles_cs); +module_pcmcia_driver(teles_cs_driver); -- cgit From fe141149bffeaaaae214b6fbb98b592d3c516fb5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:27:15 -0700 Subject: drivers/mmc: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdricoh_cs.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 7009f17ad6cd..50adbd155f35 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -543,25 +543,7 @@ static struct pcmcia_driver sdricoh_driver = { .suspend = sdricoh_pcmcia_suspend, .resume = sdricoh_pcmcia_resume, }; - -/*****************************************************************************\ - * * - * Driver init/exit * - * * -\*****************************************************************************/ - -static int __init sdricoh_drv_init(void) -{ - return pcmcia_register_driver(&sdricoh_driver); -} - -static void __exit sdricoh_drv_exit(void) -{ - pcmcia_unregister_driver(&sdricoh_driver); -} - -module_init(sdricoh_drv_init); -module_exit(sdricoh_drv_exit); +module_pcmcia_driver(sdricoh_driver); module_param(switchlocked, uint, 0444); -- cgit From f23e79688c1469b13ac33420efbc974b6772564f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:28:04 -0700 Subject: drivers/parport: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_cs.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 067ad517c1f5..e9b52e4a4648 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -193,16 +193,4 @@ static struct pcmcia_driver parport_cs_driver = { .remove = parport_detach, .id_table = parport_ids, }; - -static int __init init_parport_cs(void) -{ - return pcmcia_register_driver(&parport_cs_driver); -} - -static void __exit exit_parport_cs(void) -{ - pcmcia_unregister_driver(&parport_cs_driver); -} - -module_init(init_parport_cs); -module_exit(exit_parport_cs); +module_pcmcia_driver(parport_cs_driver); -- cgit From 3e13ea450b6a4714ee05ba4d61e5b32821cde550 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:28:29 -0700 Subject: drivers/scsi: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/pcmcia/aha152x_stub.c | 14 +------------- drivers/scsi/pcmcia/fdomain_stub.c | 14 +------------- drivers/scsi/pcmcia/nsp_cs.c | 17 +---------------- drivers/scsi/pcmcia/qlogic_stub.c | 13 +------------ drivers/scsi/pcmcia/sym53c500_cs.c | 16 +--------------- 5 files changed, 5 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 7d1609fa233c..df82a349e969 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -220,16 +220,4 @@ static struct pcmcia_driver aha152x_cs_driver = { .id_table = aha152x_ids, .resume = aha152x_resume, }; - -static int __init init_aha152x_cs(void) -{ - return pcmcia_register_driver(&aha152x_cs_driver); -} - -static void __exit exit_aha152x_cs(void) -{ - pcmcia_unregister_driver(&aha152x_cs_driver); -} - -module_init(init_aha152x_cs); -module_exit(exit_aha152x_cs); +module_pcmcia_driver(aha152x_cs_driver); diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 714b248f5d5e..ba84769e849f 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -194,16 +194,4 @@ static struct pcmcia_driver fdomain_cs_driver = { .id_table = fdomain_ids, .resume = fdomain_resume, }; - -static int __init init_fdomain_cs(void) -{ - return pcmcia_register_driver(&fdomain_cs_driver); -} - -static void __exit exit_fdomain_cs(void) -{ - pcmcia_unregister_driver(&fdomain_cs_driver); -} - -module_init(init_fdomain_cs); -module_exit(exit_fdomain_cs); +module_pcmcia_driver(fdomain_cs_driver); diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index b61a753eb896..76ca00cbc11e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1773,19 +1773,4 @@ static struct pcmcia_driver nsp_driver = { .suspend = nsp_cs_suspend, .resume = nsp_cs_resume, }; - -static int __init nsp_cs_init(void) -{ - return pcmcia_register_driver(&nsp_driver); -} - -static void __exit nsp_cs_exit(void) -{ - pcmcia_unregister_driver(&nsp_driver); -} - - -module_init(nsp_cs_init) -module_exit(nsp_cs_exit) - -/* end */ +module_pcmcia_driver(nsp_driver); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index bcaf89fe0c9e..8d4fdc292242 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -300,19 +300,8 @@ static struct pcmcia_driver qlogic_cs_driver = { .id_table = qlogic_ids, .resume = qlogic_resume, }; - -static int __init init_qlogic_cs(void) -{ - return pcmcia_register_driver(&qlogic_cs_driver); -} - -static void __exit exit_qlogic_cs(void) -{ - pcmcia_unregister_driver(&qlogic_cs_driver); -} +module_pcmcia_driver(qlogic_cs_driver); MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); MODULE_DESCRIPTION("Driver for the PCMCIA Qlogic FAS SCSI controllers"); MODULE_LICENSE("GPL"); -module_init(init_qlogic_cs); -module_exit(exit_qlogic_cs); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index f5b52731abd9..55b0b2b38a65 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -881,18 +881,4 @@ static struct pcmcia_driver sym53c500_cs_driver = { .id_table = sym53c500_ids, .resume = sym53c500_resume, }; - -static int __init -init_sym53c500_cs(void) -{ - return pcmcia_register_driver(&sym53c500_cs_driver); -} - -static void __exit -exit_sym53c500_cs(void) -{ - pcmcia_unregister_driver(&sym53c500_cs_driver); -} - -module_init(init_sym53c500_cs); -module_exit(exit_sym53c500_cs); +module_pcmcia_driver(sym53c500_cs_driver); -- cgit From 5339102c778bab379b4ec6348a184481dc7ad614 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:28:53 -0700 Subject: drivers/tty: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/serial_cs.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index b7d48b346393..1b74b88e1e1e 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -852,18 +852,6 @@ static struct pcmcia_driver serial_cs_driver = { .suspend = serial_suspend, .resume = serial_resume, }; - -static int __init init_serial_cs(void) -{ - return pcmcia_register_driver(&serial_cs_driver); -} - -static void __exit exit_serial_cs(void) -{ - pcmcia_unregister_driver(&serial_cs_driver); -} - -module_init(init_serial_cs); -module_exit(exit_serial_cs); +module_pcmcia_driver(serial_cs_driver); MODULE_LICENSE("GPL"); -- cgit From 4c7a45fb1bf683357e5222e664aaee80390051f4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:29:17 -0700 Subject: drivers/usb: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/sl811_cs.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 3b6f50eaec91..469564e57a52 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -200,17 +200,4 @@ static struct pcmcia_driver sl811_cs_driver = { .remove = sl811_cs_detach, .id_table = sl811_ids, }; - -/*====================================================================*/ - -static int __init init_sl811_cs(void) -{ - return pcmcia_register_driver(&sl811_cs_driver); -} -module_init(init_sl811_cs); - -static void __exit exit_sl811_cs(void) -{ - pcmcia_unregister_driver(&sl811_cs_driver); -} -module_exit(exit_sl811_cs); +module_pcmcia_driver(sl811_cs_driver); -- cgit From fdd3f29eddd1b7c26b3b42e3633afcb22a28fcb3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Mar 2013 11:27:43 -0700 Subject: drivers/net: use module_pcmcia_driver() in pcmcia drivers Use the new module_pcmcia_driver() macro to remove the boilerplate module init/exit code in the pcmcia drivers. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/net/arcnet/com20020_cs.c | 14 +------------- drivers/net/can/sja1000/ems_pcmcia.c | 13 +------------ drivers/net/can/sja1000/peak_pcmcia.c | 13 +------------ drivers/net/ethernet/3com/3c574_cs.c | 14 +------------- drivers/net/ethernet/3com/3c589_cs.c | 14 +------------- drivers/net/ethernet/8390/axnet_cs.c | 14 +------------- drivers/net/ethernet/8390/pcnet_cs.c | 14 +------------- drivers/net/ethernet/amd/nmclan_cs.c | 14 +------------- drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 14 +------------- drivers/net/ethernet/smsc/smc91c92_cs.c | 14 +------------- drivers/net/ethernet/xircom/xirc2ps_cs.c | 16 +--------------- drivers/net/wireless/airo_cs.c | 14 +------------- drivers/net/wireless/atmel_cs.c | 14 +------------- drivers/net/wireless/b43/pcmcia.c | 4 ++++ drivers/net/wireless/hostap/hostap_cs.c | 15 +-------------- drivers/net/wireless/libertas/if_cs.c | 25 +------------------------ drivers/net/wireless/orinoco/orinoco_cs.c | 16 +--------------- drivers/net/wireless/orinoco/spectrum_cs.c | 16 +--------------- drivers/net/wireless/wl3501_cs.c | 14 +------------- 19 files changed, 22 insertions(+), 250 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c index 5bed4c4e2508..74dc1875f9cd 100644 --- a/drivers/net/arcnet/com20020_cs.c +++ b/drivers/net/arcnet/com20020_cs.c @@ -333,16 +333,4 @@ static struct pcmcia_driver com20020_cs_driver = { .suspend = com20020_suspend, .resume = com20020_resume, }; - -static int __init init_com20020_cs(void) -{ - return pcmcia_register_driver(&com20020_cs_driver); -} - -static void __exit exit_com20020_cs(void) -{ - pcmcia_unregister_driver(&com20020_cs_driver); -} - -module_init(init_com20020_cs); -module_exit(exit_com20020_cs); +module_pcmcia_driver(com20020_cs_driver); diff --git a/drivers/net/can/sja1000/ems_pcmcia.c b/drivers/net/can/sja1000/ems_pcmcia.c index 5c2f3fbbf5ae..321c27e1c7fc 100644 --- a/drivers/net/can/sja1000/ems_pcmcia.c +++ b/drivers/net/can/sja1000/ems_pcmcia.c @@ -316,15 +316,4 @@ static struct pcmcia_driver ems_pcmcia_driver = { .remove = ems_pcmcia_remove, .id_table = ems_pcmcia_tbl, }; - -static int __init ems_pcmcia_init(void) -{ - return pcmcia_register_driver(&ems_pcmcia_driver); -} -module_init(ems_pcmcia_init); - -static void __exit ems_pcmcia_exit(void) -{ - pcmcia_unregister_driver(&ems_pcmcia_driver); -} -module_exit(ems_pcmcia_exit); +module_pcmcia_driver(ems_pcmcia_driver); diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c index 1a7020ba37f5..0a707f70661c 100644 --- a/drivers/net/can/sja1000/peak_pcmcia.c +++ b/drivers/net/can/sja1000/peak_pcmcia.c @@ -740,15 +740,4 @@ static struct pcmcia_driver pcan_driver = { .remove = pcan_remove, .id_table = pcan_table, }; - -static int __init pcan_init(void) -{ - return pcmcia_register_driver(&pcan_driver); -} -module_init(pcan_init); - -static void __exit pcan_exit(void) -{ - pcmcia_unregister_driver(&pcan_driver); -} -module_exit(pcan_exit); +module_pcmcia_driver(pcan_driver); diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c index ffd8de28a76a..6fc994fa4abe 100644 --- a/drivers/net/ethernet/3com/3c574_cs.c +++ b/drivers/net/ethernet/3com/3c574_cs.c @@ -1165,16 +1165,4 @@ static struct pcmcia_driver tc574_driver = { .suspend = tc574_suspend, .resume = tc574_resume, }; - -static int __init init_tc574(void) -{ - return pcmcia_register_driver(&tc574_driver); -} - -static void __exit exit_tc574(void) -{ - pcmcia_unregister_driver(&tc574_driver); -} - -module_init(init_tc574); -module_exit(exit_tc574); +module_pcmcia_driver(tc574_driver); diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c index a556c01e011b..078480aaa168 100644 --- a/drivers/net/ethernet/3com/3c589_cs.c +++ b/drivers/net/ethernet/3com/3c589_cs.c @@ -928,16 +928,4 @@ static struct pcmcia_driver tc589_driver = { .suspend = tc589_suspend, .resume = tc589_resume, }; - -static int __init init_tc589(void) -{ - return pcmcia_register_driver(&tc589_driver); -} - -static void __exit exit_tc589(void) -{ - pcmcia_unregister_driver(&tc589_driver); -} - -module_init(init_tc589); -module_exit(exit_tc589); +module_pcmcia_driver(tc589_driver); diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c index e1b3941bd149..d801c1410fb0 100644 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ b/drivers/net/ethernet/8390/axnet_cs.c @@ -728,19 +728,7 @@ static struct pcmcia_driver axnet_cs_driver = { .suspend = axnet_suspend, .resume = axnet_resume, }; - -static int __init init_axnet_cs(void) -{ - return pcmcia_register_driver(&axnet_cs_driver); -} - -static void __exit exit_axnet_cs(void) -{ - pcmcia_unregister_driver(&axnet_cs_driver); -} - -module_init(init_axnet_cs); -module_exit(exit_axnet_cs); +module_pcmcia_driver(axnet_cs_driver); /*====================================================================*/ diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c index de1af0bfed4c..46c5aadaca8e 100644 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ b/drivers/net/ethernet/8390/pcnet_cs.c @@ -1694,16 +1694,4 @@ static struct pcmcia_driver pcnet_driver = { .suspend = pcnet_suspend, .resume = pcnet_resume, }; - -static int __init init_pcnet_cs(void) -{ - return pcmcia_register_driver(&pcnet_driver); -} - -static void __exit exit_pcnet_cs(void) -{ - pcmcia_unregister_driver(&pcnet_driver); -} - -module_init(init_pcnet_cs); -module_exit(exit_pcnet_cs); +module_pcmcia_driver(pcnet_driver); diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 9f59bf63514b..d4ed89130c52 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c @@ -1508,16 +1508,4 @@ static struct pcmcia_driver nmclan_cs_driver = { .suspend = nmclan_suspend, .resume = nmclan_resume, }; - -static int __init init_nmclan_cs(void) -{ - return pcmcia_register_driver(&nmclan_cs_driver); -} - -static void __exit exit_nmclan_cs(void) -{ - pcmcia_unregister_driver(&nmclan_cs_driver); -} - -module_init(init_nmclan_cs); -module_exit(exit_nmclan_cs); +module_pcmcia_driver(nmclan_cs_driver); diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index 2418faf2251a..ab98b77df309 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -705,19 +705,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = { .suspend = fmvj18x_suspend, .resume = fmvj18x_resume, }; - -static int __init init_fmvj18x_cs(void) -{ - return pcmcia_register_driver(&fmvj18x_cs_driver); -} - -static void __exit exit_fmvj18x_cs(void) -{ - pcmcia_unregister_driver(&fmvj18x_cs_driver); -} - -module_init(init_fmvj18x_cs); -module_exit(exit_fmvj18x_cs); +module_pcmcia_driver(fmvj18x_cs_driver); /*====================================================================*/ diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c index 04393b5fef71..656d2e2ebfc9 100644 --- a/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c @@ -2054,16 +2054,4 @@ static struct pcmcia_driver smc91c92_cs_driver = { .suspend = smc91c92_suspend, .resume = smc91c92_resume, }; - -static int __init init_smc91c92_cs(void) -{ - return pcmcia_register_driver(&smc91c92_cs_driver); -} - -static void __exit exit_smc91c92_cs(void) -{ - pcmcia_unregister_driver(&smc91c92_cs_driver); -} - -module_init(init_smc91c92_cs); -module_exit(exit_smc91c92_cs); +module_pcmcia_driver(smc91c92_cs_driver); diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index 98e09d0d3ce2..1025b4e937d2 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -1775,21 +1775,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = { .suspend = xirc2ps_suspend, .resume = xirc2ps_resume, }; - -static int __init -init_xirc2ps_cs(void) -{ - return pcmcia_register_driver(&xirc2ps_cs_driver); -} - -static void __exit -exit_xirc2ps_cs(void) -{ - pcmcia_unregister_driver(&xirc2ps_cs_driver); -} - -module_init(init_xirc2ps_cs); -module_exit(exit_xirc2ps_cs); +module_pcmcia_driver(xirc2ps_cs_driver); #ifndef MODULE static int __init setup_xirc2ps_cs(char *str) diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index 956024a636e6..14128fd265ac 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -180,16 +180,7 @@ static struct pcmcia_driver airo_driver = { .suspend = airo_suspend, .resume = airo_resume, }; - -static int __init airo_cs_init(void) -{ - return pcmcia_register_driver(&airo_driver); -} - -static void __exit airo_cs_cleanup(void) -{ - pcmcia_unregister_driver(&airo_driver); -} +module_pcmcia_driver(airo_driver); /* This program is free software; you can redistribute it and/or @@ -229,6 +220,3 @@ static void __exit airo_cs_cleanup(void) IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -module_init(airo_cs_init); -module_exit(airo_cs_cleanup); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index b42930f457c2..522572219217 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -245,16 +245,7 @@ static struct pcmcia_driver atmel_driver = { .suspend = atmel_suspend, .resume = atmel_resume, }; - -static int __init atmel_cs_init(void) -{ - return pcmcia_register_driver(&atmel_driver); -} - -static void __exit atmel_cs_cleanup(void) -{ - pcmcia_unregister_driver(&atmel_driver); -} +module_pcmcia_driver(atmel_driver); /* This program is free software; you can redistribute it and/or @@ -294,6 +285,3 @@ static void __exit atmel_cs_cleanup(void) IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -module_init(atmel_cs_init); -module_exit(atmel_cs_cleanup); diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index f2ea2ceec8a9..55f2bd7f8f74 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -130,6 +130,10 @@ static struct pcmcia_driver b43_pcmcia_driver = { .resume = b43_pcmcia_resume, }; +/* + * These are not module init/exit functions! + * The module_pcmcia_driver() helper cannot be used here. + */ int b43_pcmcia_init(void) { return pcmcia_register_driver(&b43_pcmcia_driver); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 89e9d3a78c3c..56cd01ca8ad0 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -709,17 +709,4 @@ static struct pcmcia_driver hostap_driver = { .suspend = hostap_cs_suspend, .resume = hostap_cs_resume, }; - -static int __init init_prism2_pccard(void) -{ - return pcmcia_register_driver(&hostap_driver); -} - -static void __exit exit_prism2_pccard(void) -{ - pcmcia_unregister_driver(&hostap_driver); -} - - -module_init(init_prism2_pccard); -module_exit(exit_prism2_pccard); +module_pcmcia_driver(hostap_driver); diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 16beaf39dc53..c94dd6802672 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -999,7 +999,6 @@ static const struct pcmcia_device_id if_cs_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); - static struct pcmcia_driver lbs_driver = { .owner = THIS_MODULE, .name = DRV_NAME, @@ -1007,26 +1006,4 @@ static struct pcmcia_driver lbs_driver = { .remove = if_cs_detach, .id_table = if_cs_ids, }; - - -static int __init if_cs_init(void) -{ - int ret; - - lbs_deb_enter(LBS_DEB_CS); - ret = pcmcia_register_driver(&lbs_driver); - lbs_deb_leave(LBS_DEB_CS); - return ret; -} - - -static void __exit if_cs_exit(void) -{ - lbs_deb_enter(LBS_DEB_CS); - pcmcia_unregister_driver(&lbs_driver); - lbs_deb_leave(LBS_DEB_CS); -} - - -module_init(if_cs_init); -module_exit(if_cs_exit); +module_pcmcia_driver(lbs_driver); diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index d7dbc00bcfbe..d21d95939316 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -338,18 +338,4 @@ static struct pcmcia_driver orinoco_driver = { .suspend = orinoco_cs_suspend, .resume = orinoco_cs_resume, }; - -static int __init -init_orinoco_cs(void) -{ - return pcmcia_register_driver(&orinoco_driver); -} - -static void __exit -exit_orinoco_cs(void) -{ - pcmcia_unregister_driver(&orinoco_driver); -} - -module_init(init_orinoco_cs); -module_exit(exit_orinoco_cs); +module_pcmcia_driver(orinoco_driver); diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 6e28ee4e9c52..e2264bc12ebf 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -318,18 +318,4 @@ static struct pcmcia_driver orinoco_driver = { .resume = spectrum_cs_resume, .id_table = spectrum_cs_ids, }; - -static int __init -init_spectrum_cs(void) -{ - return pcmcia_register_driver(&orinoco_driver); -} - -static void __exit -exit_spectrum_cs(void) -{ - pcmcia_unregister_driver(&orinoco_driver); -} - -module_init(init_spectrum_cs); -module_exit(exit_spectrum_cs); +module_pcmcia_driver(orinoco_driver); diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 730186d0449b..38d2089f338a 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -2013,19 +2013,7 @@ static struct pcmcia_driver wl3501_driver = { .suspend = wl3501_suspend, .resume = wl3501_resume, }; - -static int __init wl3501_init_module(void) -{ - return pcmcia_register_driver(&wl3501_driver); -} - -static void __exit wl3501_exit_module(void) -{ - pcmcia_unregister_driver(&wl3501_driver); -} - -module_init(wl3501_init_module); -module_exit(wl3501_exit_module); +module_pcmcia_driver(wl3501_driver); MODULE_AUTHOR("Fox Chen , " "Arnaldo Carvalho de Melo ," -- cgit From 7fced565e55be83a18a3b7bb64995515c61edd53 Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 7 Mar 2013 13:25:53 +0100 Subject: softingcs: initialize spinlock with macro Signed-off-by: Kurt Van Dijck Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/softing/softing_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c index c2c0a5bb0b21..77620543cd91 100644 --- a/drivers/net/can/softing/softing_cs.c +++ b/drivers/net/can/softing/softing_cs.c @@ -27,7 +27,7 @@ #include "softing_platform.h" static int softingcs_index; -static spinlock_t softingcs_index_lock; +static DEFINE_SPINLOCK(softingcs_index_lock); static int softingcs_reset(struct platform_device *pdev, int v); static int softingcs_enable_irq(struct platform_device *pdev, int v); @@ -342,7 +342,6 @@ static struct pcmcia_driver softingcs_driver = { static int __init softingcs_start(void) { - spin_lock_init(&softingcs_index_lock); return pcmcia_register_driver(&softingcs_driver); } -- cgit From a750fa4edd9e5d840a1ada4a272601c82e56a83a Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Thu, 7 Mar 2013 13:28:18 +0100 Subject: softingcs: use module_pcmcia_driver Signed-off-by: Kurt Van Dijck Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/softing/softing_cs.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c index 77620543cd91..738355c12744 100644 --- a/drivers/net/can/softing/softing_cs.c +++ b/drivers/net/can/softing/softing_cs.c @@ -340,18 +340,7 @@ static struct pcmcia_driver softingcs_driver = { .remove = softingcs_remove, }; -static int __init softingcs_start(void) -{ - return pcmcia_register_driver(&softingcs_driver); -} - -static void __exit softingcs_stop(void) -{ - pcmcia_unregister_driver(&softingcs_driver); -} - -module_init(softingcs_start); -module_exit(softingcs_stop); +module_pcmcia_driver(&softingcs_driver); MODULE_DESCRIPTION("softing CANcard driver" ", links PCMCIA card to softing driver"); -- cgit From 19ffd68f816878aed456d5e87697f43bd9e3bd2b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Tue, 5 Feb 2013 16:08:50 -0500 Subject: pty: Remove redundant itty reset port->itty has already been reset by release_tty() before pty_cleanup() is called. Call stack: release_tty() tty_kref_put() queue_release_one_tty() release_one_tty() : workqueue tty->ops->cleanup() pty_cleanup() Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index c24b4db243b9..71e456aa6367 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -413,7 +413,6 @@ static void pty_unix98_shutdown(struct tty_struct *tty) static void pty_cleanup(struct tty_struct *tty) { - tty->port->itty = NULL; tty_port_put(tty->port); } -- cgit From 84e819220468e989a0dde33bf1121888c5e749b1 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 09:59:00 +0530 Subject: serial: tegra: Convert to devm_ioremap_resource() Use the newly introduced devm_ioremap_resource() instead of devm_request_and_ioremap() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages; so all explicit error messages can be removed from the failure code paths. Signed-off-by: Sachin Kamat Reviewed-by: Thierry Reding Cc: Laxman Dewangan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 372de8ade76a..9799d043a9bd 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1301,11 +1302,9 @@ static int tegra_uart_probe(struct platform_device *pdev) } u->mapbase = resource->start; - u->membase = devm_request_and_ioremap(&pdev->dev, resource); - if (!u->membase) { - dev_err(&pdev->dev, "memregion/iomap address req failed\n"); - return -EADDRNOTAVAIL; - } + u->membase = devm_ioremap_resource(&pdev->dev, resource); + if (IS_ERR(u->membase)) + return PTR_ERR(u->membase); tup->uart_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tup->uart_clk)) { -- cgit From 82b231323e419dcd61de9ff38d66dd7e82564594 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 14:24:39 +0530 Subject: serial: vt8500_serial: Convert to devm_ioremap_resource() Use the newly introduced devm_ioremap_resource() instead of devm_request_and_ioremap() which provides more consistent error handling. Signed-off-by: Sachin Kamat Acked-by: Tony Prisk Reviewed-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index a3f9dd5c9dff..f15f53f18ca9 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -35,6 +35,7 @@ #include #include #include +#include /* * UART Register offsets @@ -585,9 +586,9 @@ static int vt8500_serial_probe(struct platform_device *pdev) if (!vt8500_port) return -ENOMEM; - vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres); - if (!vt8500_port->uart.membase) - return -EADDRNOTAVAIL; + vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres); + if (IS_ERR(vt8500_port->uart.membase)) + return PTR_ERR(vt8500_port->uart.membase); vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); if (IS_ERR(vt8500_port->clk)) { -- cgit From fec6bee367357d9dd3ab3a7c56293214e49c371c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 5 Mar 2013 12:29:20 +0900 Subject: TTY: amiserial, use module_platform_driver_probe() This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index fc700342d43f..083710e02367 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1798,19 +1798,7 @@ static struct platform_driver amiga_serial_driver = { }, }; -static int __init amiga_serial_init(void) -{ - return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe); -} - -module_init(amiga_serial_init); - -static void __exit amiga_serial_exit(void) -{ - platform_driver_unregister(&amiga_serial_driver); -} - -module_exit(amiga_serial_exit); +module_platform_driver_probe(amiga_serial_driver, amiga_serial_probe); #if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) -- cgit From ef44d28c4fd94166ec6be054359ae26ba73b0291 Mon Sep 17 00:00:00 2001 From: Liang Li Date: Tue, 5 Mar 2013 22:30:38 +0800 Subject: serial: pch_uart: add console poll support Implement console poll for pch_uart, this could enable KGDBoC when on pch-uart console. Signed-off-by: Liang Li Acked-by: Jason Wessel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 103 ++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 7a6c989924b3..21a7e179edf3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1493,29 +1493,6 @@ static int pch_uart_verify_port(struct uart_port *port, return 0; } -static struct uart_ops pch_uart_ops = { - .tx_empty = pch_uart_tx_empty, - .set_mctrl = pch_uart_set_mctrl, - .get_mctrl = pch_uart_get_mctrl, - .stop_tx = pch_uart_stop_tx, - .start_tx = pch_uart_start_tx, - .stop_rx = pch_uart_stop_rx, - .enable_ms = pch_uart_enable_ms, - .break_ctl = pch_uart_break_ctl, - .startup = pch_uart_startup, - .shutdown = pch_uart_shutdown, - .set_termios = pch_uart_set_termios, -/* .pm = pch_uart_pm, Not supported yet */ -/* .set_wake = pch_uart_set_wake, Not supported yet */ - .type = pch_uart_type, - .release_port = pch_uart_release_port, - .request_port = pch_uart_request_port, - .config_port = pch_uart_config_port, - .verify_port = pch_uart_verify_port -}; - -#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE - /* * Wait for transmitter & holding register to empty */ @@ -1547,6 +1524,84 @@ static void wait_for_xmitr(struct eg20t_port *up, int bits) } } +#ifdef CONFIG_CONSOLE_POLL +/* + * Console polling routines for communicate via uart while + * in an interrupt or debug context. + */ +static int pch_uart_get_poll_char(struct uart_port *port) +{ + struct eg20t_port *priv = + container_of(port, struct eg20t_port, port); + u8 lsr = ioread8(priv->membase + UART_LSR); + + if (!(lsr & UART_LSR_DR)) + return NO_POLL_CHAR; + + return ioread8(priv->membase + PCH_UART_RBR); +} + + +static void pch_uart_put_poll_char(struct uart_port *port, + unsigned char c) +{ + unsigned int ier; + struct eg20t_port *priv = + container_of(port, struct eg20t_port, port); + + /* + * First save the IER then disable the interrupts + */ + ier = ioread8(priv->membase + UART_IER); + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); + + wait_for_xmitr(priv, UART_LSR_THRE); + /* + * Send the character out. + * If a LF, also do CR... + */ + iowrite8(c, priv->membase + PCH_UART_THR); + if (c == 10) { + wait_for_xmitr(priv, UART_LSR_THRE); + iowrite8(13, priv->membase + PCH_UART_THR); + } + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(priv, BOTH_EMPTY); + iowrite8(ier, priv->membase + UART_IER); +} +#endif /* CONFIG_CONSOLE_POLL */ + +static struct uart_ops pch_uart_ops = { + .tx_empty = pch_uart_tx_empty, + .set_mctrl = pch_uart_set_mctrl, + .get_mctrl = pch_uart_get_mctrl, + .stop_tx = pch_uart_stop_tx, + .start_tx = pch_uart_start_tx, + .stop_rx = pch_uart_stop_rx, + .enable_ms = pch_uart_enable_ms, + .break_ctl = pch_uart_break_ctl, + .startup = pch_uart_startup, + .shutdown = pch_uart_shutdown, + .set_termios = pch_uart_set_termios, +/* .pm = pch_uart_pm, Not supported yet */ +/* .set_wake = pch_uart_set_wake, Not supported yet */ + .type = pch_uart_type, + .release_port = pch_uart_release_port, + .request_port = pch_uart_request_port, + .config_port = pch_uart_config_port, + .verify_port = pch_uart_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = pch_uart_get_poll_char, + .poll_put_char = pch_uart_put_poll_char, +#endif +}; + +#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE + static void pch_console_putchar(struct uart_port *port, int ch) { struct eg20t_port *priv = @@ -1655,7 +1710,7 @@ static struct console pch_console = { #define PCH_CONSOLE (&pch_console) #else #define PCH_CONSOLE NULL -#endif +#endif /* CONFIG_SERIAL_PCH_UART_CONSOLE */ static struct uart_driver pch_uart_driver = { .owner = THIS_MODULE, -- cgit From f3c8279d694a5c2c455cdcb3323e2349b40c542f Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Wed, 6 Mar 2013 01:03:22 +0530 Subject: tty: ipwireless: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/hardware.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index 97a511f4185d..2c14842541dd 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1732,8 +1732,7 @@ void ipwireless_hardware_free(struct ipw_hardware *hw) flush_work(&hw->work_rx); for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) - if (hw->packet_assembler[i] != NULL) - kfree(hw->packet_assembler[i]); + kfree(hw->packet_assembler[i]); for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) { -- cgit From ea648a47e83d7cda0832f96de215464e2c35b2c2 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 07:20:53 -0500 Subject: tty: Refactor session leader SIGHUP from __tty_hangup() Reduce complexity of __tty_hangup(); separate SIGHUP signalling into tty_signal_session_leader(). Signed-off-by: Peter Hurley Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 81 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 05400acbc456..706c23b9cb95 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -532,6 +532,51 @@ void tty_wakeup(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_wakeup); +/** + * tty_signal_session_leader - sends SIGHUP to session leader + * + * Send SIGHUP and SIGCONT to the session leader and its + * process group. + * + * Returns the number of processes in the session with this tty + * as their controlling terminal. This value is used to drop + * tty references for those processes. + */ +static int tty_signal_session_leader(struct tty_struct *tty) +{ + struct task_struct *p; + unsigned long flags; + int refs = 0; + + read_lock(&tasklist_lock); + if (tty->session) { + do_each_pid_task(tty->session, PIDTYPE_SID, p) { + spin_lock_irq(&p->sighand->siglock); + if (p->signal->tty == tty) { + p->signal->tty = NULL; + /* We defer the dereferences outside fo + the tasklist lock */ + refs++; + } + if (!p->signal->leader) { + spin_unlock_irq(&p->sighand->siglock); + continue; + } + __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); + __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); + put_pid(p->signal->tty_old_pgrp); /* A noop */ + spin_lock_irqsave(&tty->ctrl_lock, flags); + if (tty->pgrp) + p->signal->tty_old_pgrp = get_pid(tty->pgrp); + spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_unlock_irq(&p->sighand->siglock); + } while_each_pid_task(tty->session, PIDTYPE_SID, p); + } + read_unlock(&tasklist_lock); + + return refs; +} + /** * __tty_hangup - actual handler for hangup events * @work: tty device @@ -558,11 +603,10 @@ static void __tty_hangup(struct tty_struct *tty) { struct file *cons_filp = NULL; struct file *filp, *f = NULL; - struct task_struct *p; struct tty_file_private *priv; int closecount = 0, n; unsigned long flags; - int refs = 0; + int refs; if (!tty) return; @@ -605,31 +649,10 @@ static void __tty_hangup(struct tty_struct *tty) */ tty_ldisc_hangup(tty); - read_lock(&tasklist_lock); - if (tty->session) { - do_each_pid_task(tty->session, PIDTYPE_SID, p) { - spin_lock_irq(&p->sighand->siglock); - if (p->signal->tty == tty) { - p->signal->tty = NULL; - /* We defer the dereferences outside fo - the tasklist lock */ - refs++; - } - if (!p->signal->leader) { - spin_unlock_irq(&p->sighand->siglock); - continue; - } - __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); - __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); - put_pid(p->signal->tty_old_pgrp); /* A noop */ - spin_lock_irqsave(&tty->ctrl_lock, flags); - if (tty->pgrp) - p->signal->tty_old_pgrp = get_pid(tty->pgrp); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); - spin_unlock_irq(&p->sighand->siglock); - } while_each_pid_task(tty->session, PIDTYPE_SID, p); - } - read_unlock(&tasklist_lock); + refs = tty_signal_session_leader(tty); + /* Account for the p->signal references we killed */ + while (refs--) + tty_kref_put(tty); spin_lock_irqsave(&tty->ctrl_lock, flags); clear_bit(TTY_THROTTLED, &tty->flags); @@ -642,10 +665,6 @@ static void __tty_hangup(struct tty_struct *tty) tty->ctrl_status = 0; spin_unlock_irqrestore(&tty->ctrl_lock, flags); - /* Account for the p->signal references we killed */ - while (refs--) - tty_kref_put(tty); - /* * If one of the devices matches a console pointer, we * cannot just call hangup() because that will cause -- cgit From 20cc225bab6709408840e4400cd1a5c2b28c7a52 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 07:20:54 -0500 Subject: tty: Fix spinlock flavor in non-atomic __tty_hangup() __tty_hangup() and tty_vhangup() cannot be called from atomic context, so locks do not need to preserve the interrupt state (although, still disable interrupts). Signed-off-by: Peter Hurley Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 706c23b9cb95..fb50442fd2a4 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -605,7 +605,6 @@ static void __tty_hangup(struct tty_struct *tty) struct file *filp, *f = NULL; struct tty_file_private *priv; int closecount = 0, n; - unsigned long flags; int refs; if (!tty) @@ -654,7 +653,7 @@ static void __tty_hangup(struct tty_struct *tty) while (refs--) tty_kref_put(tty); - spin_lock_irqsave(&tty->ctrl_lock, flags); + spin_lock_irq(&tty->ctrl_lock); clear_bit(TTY_THROTTLED, &tty->flags); clear_bit(TTY_PUSH, &tty->flags); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); @@ -663,7 +662,7 @@ static void __tty_hangup(struct tty_struct *tty) tty->session = NULL; tty->pgrp = NULL; tty->ctrl_status = 0; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_unlock_irq(&tty->ctrl_lock); /* * If one of the devices matches a console pointer, we -- cgit From bc30c3b23bb953fc6eb59e7ac6ecb48d92962bb0 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 07:20:55 -0500 Subject: tty: Use spin_lock() inside existing critical region The interrupt state does not need to be saved, disabled and restored here; interrupts are already off because this lock is bracketed by spin_lock_irq/spin_unlock_irq. Signed-off-by: Peter Hurley Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fb50442fd2a4..2661e86a2272 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -545,7 +545,6 @@ EXPORT_SYMBOL_GPL(tty_wakeup); static int tty_signal_session_leader(struct tty_struct *tty) { struct task_struct *p; - unsigned long flags; int refs = 0; read_lock(&tasklist_lock); @@ -565,10 +564,10 @@ static int tty_signal_session_leader(struct tty_struct *tty) __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); put_pid(p->signal->tty_old_pgrp); /* A noop */ - spin_lock_irqsave(&tty->ctrl_lock, flags); + spin_lock(&tty->ctrl_lock); if (tty->pgrp) p->signal->tty_old_pgrp = get_pid(tty->pgrp); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_unlock(&tty->ctrl_lock); spin_unlock_irq(&p->sighand->siglock); } while_each_pid_task(tty->session, PIDTYPE_SID, p); } -- cgit From f91e2590410bd992e3f065d17c55329bdaa51b1d Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 07:20:56 -0500 Subject: tty: Signal foreground group processes in hangup When the session leader is exiting, signal the foreground group processes as part of the hangup sequence, instead of after the hangup is complete. This prepares for hanging up the line discipline _after_ signalling processes which may be blocking on ldisc i/o. Parameterize __tty_hangup() to distinguish between when the session leader is exiting and all other hangups; signal the foreground group after signalling the session leader and its process group, which preserves the original signal order. Signed-off-by: Peter Hurley Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 65 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 2661e86a2272..3feca406dc36 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -534,18 +534,21 @@ EXPORT_SYMBOL_GPL(tty_wakeup); /** * tty_signal_session_leader - sends SIGHUP to session leader + * @tty controlling tty + * @exit_session if non-zero, signal all foreground group processes * - * Send SIGHUP and SIGCONT to the session leader and its - * process group. + * Send SIGHUP and SIGCONT to the session leader and its process group. + * Optionally, signal all processes in the foreground process group. * * Returns the number of processes in the session with this tty * as their controlling terminal. This value is used to drop * tty references for those processes. */ -static int tty_signal_session_leader(struct tty_struct *tty) +static int tty_signal_session_leader(struct tty_struct *tty, int exit_session) { struct task_struct *p; int refs = 0; + struct pid *tty_pgrp = NULL; read_lock(&tasklist_lock); if (tty->session) { @@ -565,6 +568,7 @@ static int tty_signal_session_leader(struct tty_struct *tty) __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); put_pid(p->signal->tty_old_pgrp); /* A noop */ spin_lock(&tty->ctrl_lock); + tty_pgrp = get_pid(tty->pgrp); if (tty->pgrp) p->signal->tty_old_pgrp = get_pid(tty->pgrp); spin_unlock(&tty->ctrl_lock); @@ -573,6 +577,12 @@ static int tty_signal_session_leader(struct tty_struct *tty) } read_unlock(&tasklist_lock); + if (tty_pgrp) { + if (exit_session) + kill_pgrp(tty_pgrp, SIGHUP, exit_session); + put_pid(tty_pgrp); + } + return refs; } @@ -598,7 +608,7 @@ static int tty_signal_session_leader(struct tty_struct *tty) * tasklist_lock to walk task list for hangup event * ->siglock to protect ->signal/->sighand */ -static void __tty_hangup(struct tty_struct *tty) +static void __tty_hangup(struct tty_struct *tty, int exit_session) { struct file *cons_filp = NULL; struct file *filp, *f = NULL; @@ -647,7 +657,7 @@ static void __tty_hangup(struct tty_struct *tty) */ tty_ldisc_hangup(tty); - refs = tty_signal_session_leader(tty); + refs = tty_signal_session_leader(tty, exit_session); /* Account for the p->signal references we killed */ while (refs--) tty_kref_put(tty); @@ -696,7 +706,7 @@ static void do_tty_hangup(struct work_struct *work) struct tty_struct *tty = container_of(work, struct tty_struct, hangup_work); - __tty_hangup(tty); + __tty_hangup(tty, 0); } /** @@ -734,7 +744,7 @@ void tty_vhangup(struct tty_struct *tty) printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); #endif - __tty_hangup(tty); + __tty_hangup(tty, 0); } EXPORT_SYMBOL(tty_vhangup); @@ -757,6 +767,27 @@ void tty_vhangup_self(void) } } +/** + * tty_vhangup_session - hangup session leader exit + * @tty: tty to hangup + * + * The session leader is exiting and hanging up its controlling terminal. + * Every process in the foreground process group is signalled SIGHUP. + * + * We do this synchronously so that when the syscall returns the process + * is complete. That guarantee is necessary for security reasons. + */ + +void tty_vhangup_session(struct tty_struct *tty) +{ +#ifdef TTY_DEBUG_HANGUP + char buf[64]; + + printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf)); +#endif + __tty_hangup(tty, 1); +} + /** * tty_hung_up_p - was tty hung up * @filp: file pointer of tty @@ -814,18 +845,18 @@ void disassociate_ctty(int on_exit) tty = get_current_tty(); if (tty) { - struct pid *tty_pgrp = get_pid(tty->pgrp); - if (on_exit) { - if (tty->driver->type != TTY_DRIVER_TYPE_PTY) - tty_vhangup(tty); - } - tty_kref_put(tty); - if (tty_pgrp) { - kill_pgrp(tty_pgrp, SIGHUP, on_exit); - if (!on_exit) + if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) { + tty_vhangup_session(tty); + } else { + struct pid *tty_pgrp = tty_get_pgrp(tty); + if (tty_pgrp) { + kill_pgrp(tty_pgrp, SIGHUP, on_exit); kill_pgrp(tty_pgrp, SIGCONT, on_exit); - put_pid(tty_pgrp); + put_pid(tty_pgrp); + } } + tty_kref_put(tty); + } else if (on_exit) { struct pid *old_pgrp; spin_lock_irq(¤t->sighand->siglock); -- cgit From 25fdf2435139542759df2eeb59e4998923c13403 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 07:20:57 -0500 Subject: tty: Signal SIGHUP before hanging up ldisc An exiting session leader can hang if a foreground process is blocking for line discipline i/o, eg. in n_tty_read(). This happens because the blocking reader is holding an ldisc reference (indicating the line discipline is in-use) which prevents __tty_hangup() from recycling the line discipline. Although waiters are woken before attempting to gain exclusive access for changing the ldisc, the blocking reader in this case will not exit the i/o loop since it has not yet received SIGHUP (because it has not been sent). Instead, perform signalling first, then recycle the line discipline. Fixes: INFO: task init:1 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. init D 00000000001d7180 2688 1 0 0x00000002 ffff8800b9acfba8 0000000000000002 00000000001d7180 ffff8800b9b10048 ffff8800b94cb000 ffff8800b9b10000 00000000001d7180 00000000001d7180 ffff8800b9b10000 ffff8800b9acffd8 00000000001d7180 00000000001d7180 Call Trace: [] __schedule+0x2e9/0x3b0 [] schedule+0x55/0x60 [] schedule_timeout+0x3a/0x370 [] ? mark_held_locks+0xf9/0x130 [] ? down_failed+0x108/0x200 [] ? _raw_spin_unlock_irq+0x2b/0x80 [] ? trace_hardirqs_on_caller+0x128/0x160 [] down_failed+0x131/0x200 [] ? tty_ldisc_lock_pair_timeout+0xcd/0x120 [] ldsem_down_write+0xd3/0x113 [] ? tty_ldisc_lock_pair_timeout+0xcd/0x120 [] ? trace_hardirqs_on+0xd/0x10 [] tty_ldisc_lock_pair_timeout+0xcd/0x120 [] tty_ldisc_hangup+0xd0/0x220 [] __tty_hangup+0x137/0x4f0 [] disassociate_ctty+0x6c/0x230 [] do_exit+0x41c/0x590 [] ? syscall_trace_enter+0x24/0x2e0 [] do_group_exit+0x8a/0xc0 [] sys_exit_group+0x12/0x20 [] tracesys+0xe1/0xe6 1 lock held by init/1: #0: (&tty->ldisc_sem){++++++}, at: [] tty_ldisc_lock_pair_timeout+0xcd/0x120 Reported-by: Sasha Levin Signed-off-by: Peter Hurley Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3feca406dc36..d3ddb31e363e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -651,17 +651,17 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) } spin_unlock(&tty_files_lock); + refs = tty_signal_session_leader(tty, exit_session); + /* Account for the p->signal references we killed */ + while (refs--) + tty_kref_put(tty); + /* * it drops BTM and thus races with reopen * we protect the race by TTY_HUPPING */ tty_ldisc_hangup(tty); - refs = tty_signal_session_leader(tty, exit_session); - /* Account for the p->signal references we killed */ - while (refs--) - tty_kref_put(tty); - spin_lock_irq(&tty->ctrl_lock); clear_bit(TTY_THROTTLED, &tty->flags); clear_bit(TTY_PUSH, &tty->flags); -- cgit From afa80ccb4c7d39702dfb0832ce02a054848191a8 Mon Sep 17 00:00:00 2001 From: "zhangwei(Jovi)" Date: Thu, 7 Mar 2013 17:00:02 +0800 Subject: sysrq: fix inconstistent help message of sysrq key Currently help message of /proc/sysrq-trigger highlight its upper-case characters, like below: SysRq : HELP : loglevel(0-9) reBoot Crash terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) ... this would confuse user trigger sysrq by upper-case character, which is inconsistent with the real lower-case character registed key. This inconsistent help message will also lead more confused when 26 upper-case letters put into use in future. This patch fix it. Thanks the comments from Andrew and Randy. Signed-off-by: zhangwei(Jovi) Cc: Andrew Morton Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 3687f0cad642..0a0de333c765 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -101,7 +101,7 @@ static void sysrq_handle_SAK(int key) } static struct sysrq_key_op sysrq_SAK_op = { .handler = sysrq_handle_SAK, - .help_msg = "saK", + .help_msg = "sak(k)", .action_msg = "SAK", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; @@ -117,7 +117,7 @@ static void sysrq_handle_unraw(int key) static struct sysrq_key_op sysrq_unraw_op = { .handler = sysrq_handle_unraw, - .help_msg = "unRaw", + .help_msg = "unraw(r)", .action_msg = "Keyboard mode set to system default", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; @@ -135,7 +135,7 @@ static void sysrq_handle_crash(int key) } static struct sysrq_key_op sysrq_crash_op = { .handler = sysrq_handle_crash, - .help_msg = "Crash", + .help_msg = "crash(c)", .action_msg = "Trigger a crash", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -148,7 +148,7 @@ static void sysrq_handle_reboot(int key) } static struct sysrq_key_op sysrq_reboot_op = { .handler = sysrq_handle_reboot, - .help_msg = "reBoot", + .help_msg = "reboot(b)", .action_msg = "Resetting", .enable_mask = SYSRQ_ENABLE_BOOT, }; @@ -159,7 +159,7 @@ static void sysrq_handle_sync(int key) } static struct sysrq_key_op sysrq_sync_op = { .handler = sysrq_handle_sync, - .help_msg = "Sync", + .help_msg = "sync(s)", .action_msg = "Emergency Sync", .enable_mask = SYSRQ_ENABLE_SYNC, }; @@ -171,7 +171,7 @@ static void sysrq_handle_show_timers(int key) static struct sysrq_key_op sysrq_show_timers_op = { .handler = sysrq_handle_show_timers, - .help_msg = "show-all-timers(Q)", + .help_msg = "show-all-timers(q)", .action_msg = "Show clockevent devices & pending hrtimers (no others)", }; @@ -181,7 +181,7 @@ static void sysrq_handle_mountro(int key) } static struct sysrq_key_op sysrq_mountro_op = { .handler = sysrq_handle_mountro, - .help_msg = "Unmount", + .help_msg = "unmount(u)", .action_msg = "Emergency Remount R/O", .enable_mask = SYSRQ_ENABLE_REMOUNT, }; @@ -194,7 +194,7 @@ static void sysrq_handle_showlocks(int key) static struct sysrq_key_op sysrq_showlocks_op = { .handler = sysrq_handle_showlocks, - .help_msg = "show-all-locks(D)", + .help_msg = "show-all-locks(d)", .action_msg = "Show Locks Held", }; #else @@ -245,7 +245,7 @@ static void sysrq_handle_showallcpus(int key) static struct sysrq_key_op sysrq_showallcpus_op = { .handler = sysrq_handle_showallcpus, - .help_msg = "show-backtrace-all-active-cpus(L)", + .help_msg = "show-backtrace-all-active-cpus(l)", .action_msg = "Show backtrace of all active CPUs", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -260,7 +260,7 @@ static void sysrq_handle_showregs(int key) } static struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, - .help_msg = "show-registers(P)", + .help_msg = "show-registers(p)", .action_msg = "Show Regs", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -271,7 +271,7 @@ static void sysrq_handle_showstate(int key) } static struct sysrq_key_op sysrq_showstate_op = { .handler = sysrq_handle_showstate, - .help_msg = "show-task-states(T)", + .help_msg = "show-task-states(t)", .action_msg = "Show State", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -282,7 +282,7 @@ static void sysrq_handle_showstate_blocked(int key) } static struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, - .help_msg = "show-blocked-tasks(W)", + .help_msg = "show-blocked-tasks(w)", .action_msg = "Show Blocked State", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -296,7 +296,7 @@ static void sysrq_ftrace_dump(int key) } static struct sysrq_key_op sysrq_ftrace_dump_op = { .handler = sysrq_ftrace_dump, - .help_msg = "dump-ftrace-buffer(Z)", + .help_msg = "dump-ftrace-buffer(z)", .action_msg = "Dump ftrace buffer", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -310,7 +310,7 @@ static void sysrq_handle_showmem(int key) } static struct sysrq_key_op sysrq_showmem_op = { .handler = sysrq_handle_showmem, - .help_msg = "show-memory-usage(M)", + .help_msg = "show-memory-usage(m)", .action_msg = "Show Memory", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -341,7 +341,7 @@ static void sysrq_handle_term(int key) } static struct sysrq_key_op sysrq_term_op = { .handler = sysrq_handle_term, - .help_msg = "terminate-all-tasks(E)", + .help_msg = "terminate-all-tasks(e)", .action_msg = "Terminate All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; @@ -360,7 +360,7 @@ static void sysrq_handle_moom(int key) } static struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, - .help_msg = "memory-full-oom-kill(F)", + .help_msg = "memory-full-oom-kill(f)", .action_msg = "Manual OOM execution", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; @@ -372,7 +372,7 @@ static void sysrq_handle_thaw(int key) } static struct sysrq_key_op sysrq_thaw_op = { .handler = sysrq_handle_thaw, - .help_msg = "thaw-filesystems(J)", + .help_msg = "thaw-filesystems(j)", .action_msg = "Emergency Thaw of all frozen filesystems", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; @@ -385,7 +385,7 @@ static void sysrq_handle_kill(int key) } static struct sysrq_key_op sysrq_kill_op = { .handler = sysrq_handle_kill, - .help_msg = "kill-all-tasks(I)", + .help_msg = "kill-all-tasks(i)", .action_msg = "Kill All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; @@ -396,7 +396,7 @@ static void sysrq_handle_unrt(int key) } static struct sysrq_key_op sysrq_unrt_op = { .handler = sysrq_handle_unrt, - .help_msg = "nice-all-RT-tasks(N)", + .help_msg = "nice-all-RT-tasks(n)", .action_msg = "Nice All RT Tasks", .enable_mask = SYSRQ_ENABLE_RTNICE, }; -- cgit From cddc1424f39e7c04045a6431eaf13a003fb8335a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Feb 2013 13:38:00 +0000 Subject: staging:iio: Remove adt7410 driver The adt7410 hwmon driver is feature wise more or less on par with the IIO driver. So we can finally remove the IIO driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Kconfig | 7 - drivers/staging/iio/adc/Makefile | 1 - drivers/staging/iio/adc/adt7410.c | 1102 ------------------------------------- 3 files changed, 1110 deletions(-) delete mode 100644 drivers/staging/iio/adc/adt7410.c (limited to 'drivers') diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 7b2a01d64f5e..d990829008ff 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -90,13 +90,6 @@ config AD7192 To compile this driver as a module, choose M here: the module will be called ad7192. -config ADT7410 - tristate "Analog Devices ADT7310/ADT7410 temperature sensor driver" - depends on I2C || SPI_MASTER - help - Say yes here to build support for Analog Devices ADT7310/ADT7410 - temperature sensors. - config AD7280 tristate "Analog Devices AD7280A Lithium Ion Battery Monitoring System" depends on SPI diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index d285596272a0..3e9fb143d25b 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_AD7192) += ad7192.o -obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c deleted file mode 100644 index 35455e160945..000000000000 --- a/drivers/staging/iio/adc/adt7410.c +++ /dev/null @@ -1,1102 +0,0 @@ -/* - * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410 - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * ADT7410 registers definition - */ - -#define ADT7410_TEMPERATURE 0 -#define ADT7410_STATUS 2 -#define ADT7410_CONFIG 3 -#define ADT7410_T_ALARM_HIGH 4 -#define ADT7410_T_ALARM_LOW 6 -#define ADT7410_T_CRIT 8 -#define ADT7410_T_HYST 0xA -#define ADT7410_ID 0xB -#define ADT7410_RESET 0x2F - -/* - * ADT7310 registers definition - */ - -#define ADT7310_STATUS 0 -#define ADT7310_CONFIG 1 -#define ADT7310_TEMPERATURE 2 -#define ADT7310_ID 3 -#define ADT7310_T_CRIT 4 -#define ADT7310_T_HYST 5 -#define ADT7310_T_ALARM_HIGH 6 -#define ADT7310_T_ALARM_LOW 7 - -/* - * ADT7410 status - */ -#define ADT7410_STAT_T_LOW 0x10 -#define ADT7410_STAT_T_HIGH 0x20 -#define ADT7410_STAT_T_CRIT 0x40 -#define ADT7410_STAT_NOT_RDY 0x80 - -/* - * ADT7410 config - */ -#define ADT7410_FAULT_QUEUE_MASK 0x3 -#define ADT7410_CT_POLARITY 0x4 -#define ADT7410_INT_POLARITY 0x8 -#define ADT7410_EVENT_MODE 0x10 -#define ADT7410_MODE_MASK 0x60 -#define ADT7410_ONESHOT 0x20 -#define ADT7410_SPS 0x40 -#define ADT7410_PD 0x60 -#define ADT7410_RESOLUTION 0x80 - -/* - * ADT7410 masks - */ -#define ADT7410_T16_VALUE_SIGN 0x8000 -#define ADT7410_T16_VALUE_FLOAT_OFFSET 7 -#define ADT7410_T16_VALUE_FLOAT_MASK 0x7F -#define ADT7410_T13_VALUE_SIGN 0x1000 -#define ADT7410_T13_VALUE_OFFSET 3 -#define ADT7410_T13_VALUE_FLOAT_OFFSET 4 -#define ADT7410_T13_VALUE_FLOAT_MASK 0xF -#define ADT7410_T_HYST_MASK 0xF -#define ADT7410_DEVICE_ID_MASK 0xF -#define ADT7410_MANUFACTORY_ID_MASK 0xF0 -#define ADT7410_MANUFACTORY_ID_OFFSET 4 - - -#define ADT7310_CMD_REG_MASK 0x28 -#define ADT7310_CMD_REG_OFFSET 3 -#define ADT7310_CMD_READ 0x40 -#define ADT7310_CMD_CON_READ 0x4 - -#define ADT7410_IRQS 2 - -/* - * struct adt7410_chip_info - chip specifc information - */ - -struct adt7410_chip_info; - -struct adt7410_ops { - int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data); - int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data); - int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data); - int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data); -}; - -struct adt7410_chip_info { - struct device *dev; - u8 config; - - const struct adt7410_ops *ops; -}; - -static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) -{ - return chip->ops->read_word(chip, reg, data); -} - -static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) -{ - return chip->ops->write_word(chip, reg, data); -} - -static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) -{ - return chip->ops->read_byte(chip, reg, data); -} - -static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) -{ - return chip->ops->write_byte(chip, reg, data); -} - -static ssize_t adt7410_show_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u8 config; - - config = chip->config & ADT7410_MODE_MASK; - - switch (config) { - case ADT7410_PD: - return sprintf(buf, "power-down\n"); - case ADT7410_ONESHOT: - return sprintf(buf, "one-shot\n"); - case ADT7410_SPS: - return sprintf(buf, "sps\n"); - default: - return sprintf(buf, "full\n"); - } -} - -static ssize_t adt7410_store_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u16 config; - int ret; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & (~ADT7410_MODE_MASK); - if (strcmp(buf, "power-down")) - config |= ADT7410_PD; - else if (strcmp(buf, "one-shot")) - config |= ADT7410_ONESHOT; - else if (strcmp(buf, "sps")) - config |= ADT7410_SPS; - - ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, - adt7410_show_mode, - adt7410_store_mode, - 0); - -static ssize_t adt7410_show_available_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "full\none-shot\nsps\npower-down\n"); -} - -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0); - -static ssize_t adt7410_show_resolution(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - int ret; - int bits; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - if (chip->config & ADT7410_RESOLUTION) - bits = 16; - else - bits = 13; - - return sprintf(buf, "%d bits\n", bits); -} - -static ssize_t adt7410_store_resolution(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - unsigned long data; - u16 config; - int ret; - - ret = strict_strtoul(buf, 10, &data); - if (ret) - return -EINVAL; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & (~ADT7410_RESOLUTION); - if (data) - config |= ADT7410_RESOLUTION; - - ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, - adt7410_show_resolution, - adt7410_store_resolution, - 0); - -static ssize_t adt7410_show_id(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u8 id; - int ret; - - ret = adt7410_read_byte(chip, ADT7410_ID, &id); - if (ret) - return -EIO; - - return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", - id & ADT7410_DEVICE_ID_MASK, - (id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET); -} - -static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, - adt7410_show_id, - NULL, - 0); - -static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip, - u16 data, char *buf) -{ - char sign = ' '; - - if (!(chip->config & ADT7410_RESOLUTION)) - data &= ~0x7; - - if (data & ADT7410_T16_VALUE_SIGN) { - /* convert supplement to positive value */ - data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data); - sign = '-'; - } - return sprintf(buf, "%c%d.%.7d\n", sign, - (data >> ADT7410_T16_VALUE_FLOAT_OFFSET), - (data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125); -} - -static ssize_t adt7410_show_value(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u8 status; - u16 data; - int ret, i = 0; - - do { - ret = adt7410_read_byte(chip, ADT7410_STATUS, &status); - if (ret) - return -EIO; - i++; - if (i == 10000) - return -EIO; - } while (status & ADT7410_STAT_NOT_RDY); - - ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data); - if (ret) - return -EIO; - - return adt7410_convert_temperature(chip, data, buf); -} - -static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0); - -static struct attribute *adt7410_attributes[] = { - &iio_dev_attr_available_modes.dev_attr.attr, - &iio_dev_attr_mode.dev_attr.attr, - &iio_dev_attr_resolution.dev_attr.attr, - &iio_dev_attr_id.dev_attr.attr, - &iio_dev_attr_value.dev_attr.attr, - NULL, -}; - -static const struct attribute_group adt7410_attribute_group = { - .attrs = adt7410_attributes, -}; - -static irqreturn_t adt7410_event_handler(int irq, void *private) -{ - struct iio_dev *indio_dev = private; - struct adt7410_chip_info *chip = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); - u8 status; - - if (adt7410_read_byte(chip, ADT7410_STATUS, &status)) - return IRQ_HANDLED; - - if (status & ADT7410_STAT_T_HIGH) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - timestamp); - if (status & ADT7410_STAT_T_LOW) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_FALLING), - timestamp); - if (status & ADT7410_STAT_T_CRIT) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - timestamp); - - return IRQ_HANDLED; -} - -static ssize_t adt7410_show_event_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - int ret; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - if (chip->config & ADT7410_EVENT_MODE) - return sprintf(buf, "interrupt\n"); - else - return sprintf(buf, "comparator\n"); -} - -static ssize_t adt7410_set_event_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u16 config; - int ret; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config &= ~ADT7410_EVENT_MODE; - if (strcmp(buf, "comparator") != 0) - config |= ADT7410_EVENT_MODE; - - ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return ret; -} - -static ssize_t adt7410_show_available_event_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "comparator\ninterrupt\n"); -} - -static ssize_t adt7410_show_fault_queue(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - int ret; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK); -} - -static ssize_t adt7410_set_fault_queue(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - unsigned long data; - int ret; - u8 config; - - ret = strict_strtoul(buf, 10, &data); - if (ret || data > 3) - return -EINVAL; - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & ~ADT7410_FAULT_QUEUE_MASK; - config |= data; - ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return ret; -} - -static inline ssize_t adt7410_show_t_bound(struct device *dev, - struct device_attribute *attr, - u8 bound_reg, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - u16 data; - int ret; - - ret = adt7410_read_word(chip, bound_reg, &data); - if (ret) - return -EIO; - - return adt7410_convert_temperature(chip, data, buf); -} - -static inline ssize_t adt7410_set_t_bound(struct device *dev, - struct device_attribute *attr, - u8 bound_reg, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - long tmp1, tmp2; - u16 data; - char *pos; - int ret; - - pos = strchr(buf, '.'); - - ret = strict_strtol(buf, 10, &tmp1); - - if (ret || tmp1 > 127 || tmp1 < -128) - return -EINVAL; - - if (pos) { - len = strlen(pos); - - if (chip->config & ADT7410_RESOLUTION) { - if (len > ADT7410_T16_VALUE_FLOAT_OFFSET) - len = ADT7410_T16_VALUE_FLOAT_OFFSET; - pos[len] = 0; - ret = strict_strtol(pos, 10, &tmp2); - - if (!ret) - tmp2 = (tmp2 / 78125) * 78125; - } else { - if (len > ADT7410_T13_VALUE_FLOAT_OFFSET) - len = ADT7410_T13_VALUE_FLOAT_OFFSET; - pos[len] = 0; - ret = strict_strtol(pos, 10, &tmp2); - - if (!ret) - tmp2 = (tmp2 / 625) * 625; - } - } - - if (tmp1 < 0) - data = (u16)(-tmp1); - else - data = (u16)tmp1; - - if (chip->config & ADT7410_RESOLUTION) { - data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) | - (tmp2 & ADT7410_T16_VALUE_FLOAT_MASK); - - if (tmp1 < 0) - /* convert positive value to supplyment */ - data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data); - } else { - data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) | - (tmp2 & ADT7410_T13_VALUE_FLOAT_MASK); - - if (tmp1 < 0) - /* convert positive value to supplyment */ - data = (ADT7410_T13_VALUE_SIGN << 1) - data; - data <<= ADT7410_T13_VALUE_OFFSET; - } - - ret = adt7410_write_word(chip, bound_reg, data); - if (ret) - return -EIO; - - return ret; -} - -static ssize_t adt7410_show_t_alarm_high(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7410_show_t_bound(dev, attr, - ADT7410_T_ALARM_HIGH, buf); -} - -static inline ssize_t adt7410_set_t_alarm_high(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7410_set_t_bound(dev, attr, - ADT7410_T_ALARM_HIGH, buf, len); -} - -static ssize_t adt7410_show_t_alarm_low(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7410_show_t_bound(dev, attr, - ADT7410_T_ALARM_LOW, buf); -} - -static inline ssize_t adt7410_set_t_alarm_low(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7410_set_t_bound(dev, attr, - ADT7410_T_ALARM_LOW, buf, len); -} - -static ssize_t adt7410_show_t_crit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7410_show_t_bound(dev, attr, - ADT7410_T_CRIT, buf); -} - -static inline ssize_t adt7410_set_t_crit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7410_set_t_bound(dev, attr, - ADT7410_T_CRIT, buf, len); -} - -static ssize_t adt7410_show_t_hyst(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - int ret; - u8 t_hyst; - - ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst); - if (ret) - return -EIO; - - return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK); -} - -static inline ssize_t adt7410_set_t_hyst(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7410_chip_info *chip = iio_priv(dev_info); - int ret; - unsigned long data; - u8 t_hyst; - - ret = strict_strtol(buf, 10, &data); - - if (ret || data > ADT7410_T_HYST_MASK) - return -EINVAL; - - t_hyst = (u8)data; - - ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst); - if (ret) - return -EIO; - - return ret; -} - -static IIO_DEVICE_ATTR(event_mode, - S_IRUGO | S_IWUSR, - adt7410_show_event_mode, adt7410_set_event_mode, 0); -static IIO_DEVICE_ATTR(available_event_modes, - S_IRUGO, - adt7410_show_available_event_modes, NULL, 0); -static IIO_DEVICE_ATTR(fault_queue, - S_IRUGO | S_IWUSR, - adt7410_show_fault_queue, adt7410_set_fault_queue, 0); -static IIO_DEVICE_ATTR(t_alarm_high, - S_IRUGO | S_IWUSR, - adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0); -static IIO_DEVICE_ATTR(t_alarm_low, - S_IRUGO | S_IWUSR, - adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0); -static IIO_DEVICE_ATTR(t_crit, - S_IRUGO | S_IWUSR, - adt7410_show_t_crit, adt7410_set_t_crit, 0); -static IIO_DEVICE_ATTR(t_hyst, - S_IRUGO | S_IWUSR, - adt7410_show_t_hyst, adt7410_set_t_hyst, 0); - -static struct attribute *adt7410_event_int_attributes[] = { - &iio_dev_attr_event_mode.dev_attr.attr, - &iio_dev_attr_available_event_modes.dev_attr.attr, - &iio_dev_attr_fault_queue.dev_attr.attr, - &iio_dev_attr_t_alarm_high.dev_attr.attr, - &iio_dev_attr_t_alarm_low.dev_attr.attr, - &iio_dev_attr_t_crit.dev_attr.attr, - &iio_dev_attr_t_hyst.dev_attr.attr, - NULL, -}; - -static struct attribute_group adt7410_event_attribute_group = { - .attrs = adt7410_event_int_attributes, - .name = "events", -}; - -static const struct iio_info adt7410_info = { - .attrs = &adt7410_attribute_group, - .event_attrs = &adt7410_event_attribute_group, - .driver_module = THIS_MODULE, -}; - -/* - * device probe and remove - */ - -static int adt7410_probe(struct device *dev, int irq, - const char *name, const struct adt7410_ops *ops) -{ - unsigned long *adt7410_platform_data = dev->platform_data; - unsigned long local_pdata[] = {0, 0}; - struct adt7410_chip_info *chip; - struct iio_dev *indio_dev; - int ret = 0; - - indio_dev = iio_device_alloc(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, indio_dev); - - chip->dev = dev; - chip->ops = ops; - - indio_dev->name = name; - indio_dev->dev.parent = dev; - indio_dev->info = &adt7410_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - if (!adt7410_platform_data) - adt7410_platform_data = local_pdata; - - /* CT critcal temperature event. line 0 */ - if (irq) { - ret = request_threaded_irq(irq, - NULL, - &adt7410_event_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - name, - indio_dev); - if (ret) - goto error_free_dev; - } - - /* INT bound temperature alarm event. line 1 */ - if (adt7410_platform_data[0]) { - ret = request_threaded_irq(adt7410_platform_data[0], - NULL, - &adt7410_event_handler, - adt7410_platform_data[1] | - IRQF_ONESHOT, - name, - indio_dev); - if (ret) - goto error_unreg_ct_irq; - } - - ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } - - chip->config |= ADT7410_RESOLUTION; - - if (irq && adt7410_platform_data[0]) { - - /* set irq polarity low level */ - chip->config &= ~ADT7410_CT_POLARITY; - - if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH) - chip->config |= ADT7410_INT_POLARITY; - else - chip->config &= ~ADT7410_INT_POLARITY; - } - - ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } - ret = iio_device_register(indio_dev); - if (ret) - goto error_unreg_int_irq; - - dev_info(dev, "%s temperature sensor registered.\n", - name); - - return 0; - -error_unreg_int_irq: - free_irq(adt7410_platform_data[0], indio_dev); -error_unreg_ct_irq: - free_irq(irq, indio_dev); -error_free_dev: - iio_device_free(indio_dev); -error_ret: - return ret; -} - -static int adt7410_remove(struct device *dev, int irq) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - unsigned long *adt7410_platform_data = dev->platform_data; - - iio_device_unregister(indio_dev); - if (adt7410_platform_data[0]) - free_irq(adt7410_platform_data[0], indio_dev); - if (irq) - free_irq(irq, indio_dev); - iio_device_free(indio_dev); - - return 0; -} - -#if IS_ENABLED(CONFIG_I2C) - -static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, - u16 *data) -{ - struct i2c_client *client = to_i2c_client(chip->dev); - int ret = 0; - - ret = i2c_smbus_read_word_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "I2C read error\n"); - return ret; - } - - *data = swab16((u16)ret); - - return 0; -} - -static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, - u16 data) -{ - struct i2c_client *client = to_i2c_client(chip->dev); - int ret = 0; - - ret = i2c_smbus_write_word_data(client, reg, swab16(data)); - if (ret < 0) - dev_err(&client->dev, "I2C write error\n"); - - return ret; -} - -static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, - u8 *data) -{ - struct i2c_client *client = to_i2c_client(chip->dev); - int ret = 0; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "I2C read error\n"); - return ret; - } - - *data = (u8)ret; - - return 0; -} - -static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, - u8 data) -{ - struct i2c_client *client = to_i2c_client(chip->dev); - int ret = 0; - - ret = i2c_smbus_write_byte_data(client, reg, data); - if (ret < 0) - dev_err(&client->dev, "I2C write error\n"); - - return ret; -} - -static const struct adt7410_ops adt7410_i2c_ops = { - .read_word = adt7410_i2c_read_word, - .write_word = adt7410_i2c_write_word, - .read_byte = adt7410_i2c_read_byte, - .write_byte = adt7410_i2c_write_byte, -}; - -static int adt7410_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - return adt7410_probe(&client->dev, client->irq, id->name, - &adt7410_i2c_ops); -} - -static int adt7410_i2c_remove(struct i2c_client *client) -{ - return adt7410_remove(&client->dev, client->irq); -} - -static const struct i2c_device_id adt7410_id[] = { - { "adt7410", 0 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, adt7410_id); - -static struct i2c_driver adt7410_driver = { - .driver = { - .name = "adt7410", - }, - .probe = adt7410_i2c_probe, - .remove = adt7410_i2c_remove, - .id_table = adt7410_id, -}; - -static int __init adt7410_i2c_init(void) -{ - return i2c_add_driver(&adt7410_driver); -} - -static void __exit adt7410_i2c_exit(void) -{ - i2c_del_driver(&adt7410_driver); -} - -#else - -static int __init adt7410_i2c_init(void) { return 0; }; -static void __exit adt7410_i2c_exit(void) {}; - -#endif - -#if IS_ENABLED(CONFIG_SPI_MASTER) - -static const u8 adt7371_reg_table[] = { - [ADT7410_TEMPERATURE] = ADT7310_TEMPERATURE, - [ADT7410_STATUS] = ADT7310_STATUS, - [ADT7410_CONFIG] = ADT7310_CONFIG, - [ADT7410_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH, - [ADT7410_T_ALARM_LOW] = ADT7310_T_ALARM_LOW, - [ADT7410_T_CRIT] = ADT7310_T_CRIT, - [ADT7410_T_HYST] = ADT7310_T_HYST, - [ADT7410_ID] = ADT7310_ID, -}; - -#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET) - -static int adt7310_spi_read_word(struct adt7410_chip_info *chip, - u8 reg, u16 *data) -{ - struct spi_device *spi = to_spi_device(chip->dev); - u8 command = AD7310_COMMAND(reg); - int ret = 0; - - command |= ADT7310_CMD_READ; - ret = spi_write(spi, &command, sizeof(command)); - if (ret < 0) { - dev_err(&spi->dev, "SPI write command error\n"); - return ret; - } - - ret = spi_read(spi, (u8 *)data, sizeof(*data)); - if (ret < 0) { - dev_err(&spi->dev, "SPI read word error\n"); - return ret; - } - - *data = be16_to_cpu(*data); - - return 0; -} - -static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg, - u16 data) -{ - struct spi_device *spi = to_spi_device(chip->dev); - u8 buf[3]; - int ret = 0; - - buf[0] = AD7310_COMMAND(reg); - buf[1] = (u8)(data >> 8); - buf[2] = (u8)(data & 0xFF); - - ret = spi_write(spi, buf, 3); - if (ret < 0) { - dev_err(&spi->dev, "SPI write word error\n"); - return ret; - } - - return ret; -} - -static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg, - u8 *data) -{ - struct spi_device *spi = to_spi_device(chip->dev); - u8 command = AD7310_COMMAND(reg); - int ret = 0; - - command |= ADT7310_CMD_READ; - ret = spi_write(spi, &command, sizeof(command)); - if (ret < 0) { - dev_err(&spi->dev, "SPI write command error\n"); - return ret; - } - - ret = spi_read(spi, data, sizeof(*data)); - if (ret < 0) { - dev_err(&spi->dev, "SPI read byte error\n"); - return ret; - } - - return 0; -} - -static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg, - u8 data) -{ - struct spi_device *spi = to_spi_device(chip->dev); - u8 buf[2]; - int ret = 0; - - buf[0] = AD7310_COMMAND(reg); - buf[1] = data; - - ret = spi_write(spi, buf, 2); - if (ret < 0) { - dev_err(&spi->dev, "SPI write byte error\n"); - return ret; - } - - return ret; -} - -static const struct adt7410_ops adt7310_spi_ops = { - .read_word = adt7310_spi_read_word, - .write_word = adt7310_spi_write_word, - .read_byte = adt7310_spi_read_byte, - .write_byte = adt7310_spi_write_byte, -}; - -static int adt7310_spi_probe(struct spi_device *spi) -{ - return adt7410_probe(&spi->dev, spi->irq, - spi_get_device_id(spi)->name, &adt7310_spi_ops); -} - -static int adt7310_spi_remove(struct spi_device *spi) -{ - return adt7410_remove(&spi->dev, spi->irq); -} - -static const struct spi_device_id adt7310_id[] = { - { "adt7310", 0 }, - {} -}; -MODULE_DEVICE_TABLE(spi, adt7310_id); - -static struct spi_driver adt7310_driver = { - .driver = { - .name = "adt7310", - .owner = THIS_MODULE, - }, - .probe = adt7310_spi_probe, - .remove = adt7310_spi_remove, - .id_table = adt7310_id, -}; - -static int __init adt7310_spi_init(void) -{ - return spi_register_driver(&adt7310_driver); -} - -static void adt7310_spi_exit(void) -{ - spi_unregister_driver(&adt7310_driver); -} - -#else - -static int __init adt7310_spi_init(void) { return 0; }; -static void adt7310_spi_exit(void) {}; - -#endif - -static int __init adt7410_init(void) -{ - int ret; - - ret = adt7310_spi_init(); - if (ret) - return ret; - - ret = adt7410_i2c_init(); - if (ret) - adt7310_spi_exit(); - - return ret; -} -module_init(adt7410_init); - -static void __exit adt7410_exit(void) -{ - adt7410_i2c_exit(); - adt7310_spi_exit(); -} -module_exit(adt7410_exit); - -MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver"); -MODULE_LICENSE("GPL v2"); -- cgit From 17d82b47a215ded05ee3fb8d93b7c1269dbe0083 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 7 Feb 2013 17:09:00 +0000 Subject: iio: Add OF support Provide bindings and parse OF data during initialization. Signed-off-by: Guenter Roeck Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/iio-bindings.txt | 97 ++++++++++++ drivers/iio/iio_core.h | 1 + drivers/iio/industrialio-core.c | 8 +- drivers/iio/inkern.c | 171 +++++++++++++++++++++ 4 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/iio-bindings.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/iio/iio-bindings.txt b/Documentation/devicetree/bindings/iio/iio-bindings.txt new file mode 100644 index 000000000000..0b447d9ad196 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/iio-bindings.txt @@ -0,0 +1,97 @@ +This binding is derived from clock bindings, and based on suggestions +from Lars-Peter Clausen [1]. + +Sources of IIO channels can be represented by any node in the device +tree. Those nodes are designated as IIO providers. IIO consumer +nodes use a phandle and IIO specifier pair to connect IIO provider +outputs to IIO inputs. Similar to the gpio specifiers, an IIO +specifier is an array of one or more cells identifying the IIO +output on a device. The length of an IIO specifier is defined by the +value of a #io-channel-cells property in the IIO provider node. + +[1] http://marc.info/?l=linux-iio&m=135902119507483&w=2 + +==IIO providers== + +Required properties: +#io-channel-cells: Number of cells in an IIO specifier; Typically 0 for nodes + with a single IIO output and 1 for nodes with multiple + IIO outputs. + +Example for a simple configuration with no trigger: + + adc: voltage-sensor@35 { + compatible = "maxim,max1139"; + reg = <0x35>; + #io-channel-cells = <1>; + }; + +Example for a configuration with trigger: + + adc@35 { + compatible = "some-vendor,some-adc"; + reg = <0x35>; + + adc1: iio-device@0 { + #io-channel-cells = <1>; + /* other properties */ + }; + adc2: iio-device@1 { + #io-channel-cells = <1>; + /* other properties */ + }; + }; + +==IIO consumers== + +Required properties: +io-channels: List of phandle and IIO specifier pairs, one pair + for each IIO input to the device. Note: if the + IIO provider specifies '0' for #io-channel-cells, + then only the phandle portion of the pair will appear. + +Optional properties: +io-channel-names: + List of IIO input name strings sorted in the same + order as the io-channels property. Consumers drivers + will use io-channel-names to match IIO input names + with IIO specifiers. +io-channel-ranges: + Empty property indicating that child nodes can inherit named + IIO channels from this node. Useful for bus nodes to provide + and IIO channel to their children. + +For example: + + device { + io-channels = <&adc 1>, <&ref 0>; + io-channel-names = "vcc", "vdd"; + }; + +This represents a device with two IIO inputs, named "vcc" and "vdd". +The vcc channel is connected to output 1 of the &adc device, and the +vdd channel is connected to output 0 of the &ref device. + +==Example== + + adc: max1139@35 { + compatible = "maxim,max1139"; + reg = <0x35>; + #io-channel-cells = <1>; + }; + + ... + + iio_hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, + <&adc 3>, <&adc 4>, <&adc 5>, + <&adc 6>, <&adc 7>, <&adc 8>, + <&adc 9>; + }; + + some_consumer { + compatible = "some-consumer"; + io-channels = <&adc 10>, <&adc 11>; + io-channel-names = "adc1", "adc2"; + }; diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index f652e6ae5a35..05c1b74502a3 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -18,6 +18,7 @@ struct iio_chan_spec; struct iio_dev; +extern struct device_type iio_device_type; int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan, diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 8848f16c547b..6d8b02785647 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -847,7 +847,7 @@ static void iio_dev_release(struct device *device) kfree(indio_dev); } -static struct device_type iio_dev_type = { +struct device_type iio_device_type = { .name = "iio_device", .release = iio_dev_release, }; @@ -869,7 +869,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) if (dev) { dev->dev.groups = dev->groups; - dev->dev.type = &iio_dev_type; + dev->dev.type = &iio_device_type; dev->dev.bus = &iio_bus_type; device_initialize(&dev->dev); dev_set_drvdata(&dev->dev, (void *)dev); @@ -960,6 +960,10 @@ int iio_device_register(struct iio_dev *indio_dev) { int ret; + /* If the calling driver did not initialize of_node, do it here */ + if (!indio_dev->dev.of_node && indio_dev->dev.parent) + indio_dev->dev.of_node = indio_dev->dev.parent->of_node; + /* configure elements for the chrdev */ indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b289915b8469..795d100b4c36 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "iio_core.h" @@ -92,6 +93,164 @@ static const struct iio_chan_spec return chan; } +#ifdef CONFIG_OF + +static int iio_dev_node_match(struct device *dev, void *data) +{ + return dev->of_node == data && dev->type == &iio_device_type; +} + +static int __of_iio_channel_get(struct iio_channel *channel, + struct device_node *np, int index) +{ + struct device *idev; + struct iio_dev *indio_dev; + int err; + struct of_phandle_args iiospec; + + err = of_parse_phandle_with_args(np, "io-channels", + "#io-channel-cells", + index, &iiospec); + if (err) + return err; + + idev = bus_find_device(&iio_bus_type, NULL, iiospec.np, + iio_dev_node_match); + of_node_put(iiospec.np); + if (idev == NULL) + return -EPROBE_DEFER; + + indio_dev = dev_to_iio_dev(idev); + channel->indio_dev = indio_dev; + index = iiospec.args_count ? iiospec.args[0] : 0; + if (index >= indio_dev->num_channels) { + return -EINVAL; + goto err_put; + } + channel->channel = &indio_dev->channels[index]; + + return 0; + +err_put: + iio_device_put(indio_dev); + return err; +} + +static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) +{ + struct iio_channel *channel; + int err; + + if (index < 0) + return ERR_PTR(-EINVAL); + + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (channel == NULL) + return ERR_PTR(-ENOMEM); + + err = __of_iio_channel_get(channel, np, index); + if (err) + goto err_free_channel; + + return channel; + +err_free_channel: + kfree(channel); + return ERR_PTR(err); +} + +static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, + const char *name) +{ + struct iio_channel *chan = NULL; + + /* Walk up the tree of devices looking for a matching iio channel */ + while (np) { + int index = 0; + + /* + * For named iio channels, first look up the name in the + * "io-channel-names" property. If it cannot be found, the + * index will be an error code, and of_iio_channel_get() + * will fail. + */ + if (name) + index = of_property_match_string(np, "io-channel-names", + name); + chan = of_iio_channel_get(np, index); + if (!IS_ERR(chan)) + break; + else if (name && index >= 0) { + pr_err("ERROR: could not get IIO channel %s:%s(%i)\n", + np->full_name, name ? name : "", index); + return chan; + } + + /* + * No matching IIO channel found on this node. + * If the parent node has a "io-channel-ranges" property, + * then we can try one of its channels. + */ + np = np->parent; + if (np && !of_get_property(np, "io-channel-ranges", NULL)) + break; + } + return chan; +} + +static struct iio_channel *of_iio_channel_get_all(struct device *dev) +{ + struct iio_channel *chans; + int i, mapind, nummaps = 0; + int ret; + + do { + ret = of_parse_phandle_with_args(dev->of_node, + "io-channels", + "#io-channel-cells", + nummaps, NULL); + if (ret < 0) + break; + } while (++nummaps); + + if (nummaps == 0) /* no error, return NULL to search map table */ + return NULL; + + /* NULL terminated array to save passing size */ + chans = kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); + if (chans == NULL) + return ERR_PTR(-ENOMEM); + + /* Search for OF matches */ + for (mapind = 0; mapind < nummaps; mapind++) { + ret = __of_iio_channel_get(&chans[mapind], dev->of_node, + mapind); + if (ret) + goto error_free_chans; + } + return chans; + +error_free_chans: + for (i = 0; i < mapind; i++) + iio_device_put(chans[i].indio_dev); + kfree(chans); + return ERR_PTR(ret); +} + +#else /* CONFIG_OF */ + +static inline struct iio_channel * +of_iio_channel_get_by_name(struct device_node *np, const char *name) +{ + return NULL; +} + +static inline struct iio_channel *of_iio_channel_get_all(struct device *dev) +{ + return NULL; +} + +#endif /* CONFIG_OF */ static struct iio_channel *iio_channel_get_sys(const char *name, const char *channel_name) @@ -150,7 +309,14 @@ struct iio_channel *iio_channel_get(struct device *dev, const char *channel_name) { const char *name = dev ? dev_name(dev) : NULL; + struct iio_channel *channel; + if (dev) { + channel = of_iio_channel_get_by_name(dev->of_node, + channel_name); + if (channel != NULL) + return channel; + } return iio_channel_get_sys(name, channel_name); } EXPORT_SYMBOL_GPL(iio_channel_get); @@ -173,6 +339,11 @@ struct iio_channel *iio_channel_get_all(struct device *dev) if (dev == NULL) return ERR_PTR(-EINVAL); + + chans = of_iio_channel_get_all(dev); + if (chans) + return chans; + name = dev_name(dev); mutex_lock(&iio_map_list_lock); -- cgit From 0eac259db28fde88767cab5fd0380f4024e08c02 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Wed, 13 Feb 2013 06:47:00 +0000 Subject: IIO ADC support for AD7923 This patch adds support for Analog Devices AD7923 ADC in the IIO Subsystem. Signed-off-by: Patrick Vasseur Signed-off-by: Christophe Leroy Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 12 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7923.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 311 insertions(+) create mode 100644 drivers/iio/adc/ad7923.c (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index e372257a8494..00213eaf8aa9 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -30,6 +30,18 @@ config AD7298 To compile this driver as a module, choose M here: the module will be called ad7298. +config AD7923 + tristate "Analog Devices AD7923 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices AD7923 + 4 Channel ADC with temperature sensor. + + To compile this driver as a module, choose M here: the + module will be called ad7923. + config AD7791 tristate "Analog Devices AD7791 ADC driver" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 2d5f10080d8d..ab910ba4664c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AD7298) += ad7298.o +obj-$(CONFIG_AD7923) += ad7923.o obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7793) += ad7793.o diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c new file mode 100644 index 000000000000..28b2bda8f0ec --- /dev/null +++ b/drivers/iio/adc/ad7923.c @@ -0,0 +1,298 @@ +/* + * AD7923 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc (from AD7923 Driver) + * Copyright 2012 CS Systemes d'Information + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define AD7923_WRITE_CR (1 << 11) /* write control register */ +#define AD7923_RANGE (1 << 1) /* range to REFin */ +#define AD7923_CODING (1 << 0) /* coding is straight binary */ +#define AD7923_PM_MODE_AS (1) /* auto shutdown */ +#define AD7923_PM_MODE_FS (2) /* full shutdown */ +#define AD7923_PM_MODE_OPS (3) /* normal operation */ +#define AD7923_CHANNEL_0 (0) /* analog input 0 */ +#define AD7923_CHANNEL_1 (1) /* analog input 1 */ +#define AD7923_CHANNEL_2 (2) /* analog input 2 */ +#define AD7923_CHANNEL_3 (3) /* analog input 3 */ +#define AD7923_SEQUENCE_OFF (0) /* no sequence fonction */ +#define AD7923_SEQUENCE_PROTECT (2) /* no interrupt write cycle */ +#define AD7923_SEQUENCE_ON (3) /* continuous sequence */ + +#define AD7923_MAX_CHAN 4 + +#define AD7923_PM_MODE_WRITE(mode) (mode << 4) /* write mode */ +#define AD7923_CHANNEL_WRITE(channel) (channel << 6) /* write channel */ +#define AD7923_SEQUENCE_WRITE(sequence) (((sequence & 1) << 3) \ + + ((sequence & 2) << 9)) + /* write sequence fonction */ +/* left shift for CR : bit 11 transmit in first */ +#define AD7923_SHIFT_REGISTER 4 + +/* val = value, dec = left shift, bits = number of bits of the mask */ +#define EXTRACT(val, dec, bits) ((val >> dec) & ((1 << bits) - 1)) + +struct ad7923_state { + struct spi_device *spi; + struct spi_transfer ring_xfer[5]; + struct spi_transfer scan_single_xfer[2]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be16 rx_buf[4] ____cacheline_aligned; + __be16 tx_buf[4]; +}; + +#define AD7923_V_CHAN(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ + } + +static const struct iio_chan_spec ad7923_channels[] = { + AD7923_V_CHAN(0), + AD7923_V_CHAN(1), + AD7923_V_CHAN(2), + AD7923_V_CHAN(3), + IIO_CHAN_SOFT_TIMESTAMP(4), +}; + +/** + * ad7923_update_scan_mode() setup the spi transfer buffer for the new scan mask + **/ +static int ad7923_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad7923_state *st = iio_priv(indio_dev); + int i, cmd, len; + + len = 0; + for_each_set_bit(i, active_scan_mask, AD7923_MAX_CHAN) { + cmd = AD7923_WRITE_CR | AD7923_CODING | AD7923_RANGE | + AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS) | + AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) | + AD7923_CHANNEL_WRITE(i); + cmd <<= AD7923_SHIFT_REGISTER; + st->tx_buf[len++] = cpu_to_be16(cmd); + } + /* build spi ring message */ + st->ring_xfer[0].tx_buf = &st->tx_buf[0]; + st->ring_xfer[0].len = len; + st->ring_xfer[0].cs_change = 1; + + spi_message_init(&st->ring_msg); + spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); + + for (i = 0; i < len; i++) { + st->ring_xfer[i + 1].rx_buf = &st->rx_buf[i]; + st->ring_xfer[i + 1].len = 2; + st->ring_xfer[i + 1].cs_change = 1; + spi_message_add_tail(&st->ring_xfer[i + 1], &st->ring_msg); + } + /* make sure last transfer cs_change is not set */ + st->ring_xfer[i + 1].cs_change = 0; + + return 0; +} + +/** + * ad7923_trigger_handler() bh of trigger launched polling to ring buffer + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + **/ +static irqreturn_t ad7923_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7923_state *st = iio_priv(indio_dev); + s64 time_ns = 0; + int b_sent; + + b_sent = spi_sync(st->spi, &st->ring_msg); + if (b_sent) + goto done; + + if (indio_dev->scan_timestamp) { + time_ns = iio_get_time_ns(); + memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), + &time_ns, sizeof(time_ns)); + } + + iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); + +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch) +{ + int ret, cmd; + + cmd = AD7923_WRITE_CR | AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS) | + AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) | AD7923_CODING | + AD7923_CHANNEL_WRITE(ch) | AD7923_RANGE; + cmd <<= AD7923_SHIFT_REGISTER; + st->tx_buf[0] = cpu_to_be16(cmd); + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret) + return ret; + + return be16_to_cpu(st->rx_buf[0]); +} + +static int ad7923_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7923_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) + ret = -EBUSY; + else + ret = ad7923_scan_direct(st, chan->address); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + if (chan->address == EXTRACT(ret, 12, 4)) + *val = EXTRACT(ret, 0, 12); + + return IIO_VAL_INT; + } + return -EINVAL; +} + +static const struct iio_info ad7923_info = { + .read_raw = &ad7923_read_raw, + .update_scan_mode = ad7923_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static int ad7923_probe(struct spi_device *spi) +{ + struct ad7923_state *st; + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad7923_channels; + indio_dev->num_channels = ARRAY_SIZE(ad7923_channels); + indio_dev->info = &ad7923_info; + + /* Setup default message */ + + st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[0].len = 2; + st->scan_single_xfer[0].cs_change = 1; + st->scan_single_xfer[1].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[1].len = 2; + + spi_message_init(&st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ad7923_trigger_handler, NULL); + if (ret) + goto error_free; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_cleanup_ring; + + return 0; + +error_cleanup_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int ad7923_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7923_id[] = { + {"ad7923", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7923_id); + +static struct spi_driver ad7923_driver = { + .driver = { + .name = "ad7923", + .owner = THIS_MODULE, + }, + .probe = ad7923_probe, + .remove = ad7923_remove, + .id_table = ad7923_id, +}; +module_spi_driver(ad7923_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Patrick Vasseur "); +MODULE_DESCRIPTION("Analog Devices AD7923 ADC"); +MODULE_LICENSE("GPL v2"); -- cgit From 43bb786ad2886ea38364e57924c19e9d29f37201 Mon Sep 17 00:00:00 2001 From: Denis Ciocca Date: Sat, 9 Feb 2013 16:08:00 +0000 Subject: iio:common: Use spi_sync_transfer() in STMicroelectronics common library Use the new spi_sync_transfer() helper function instead of open-coding it. Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_spi.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c index f0aa2f105222..251baf6abc25 100644 --- a/drivers/iio/common/st_sensors/st_sensors_spi.c +++ b/drivers/iio/common/st_sensors/st_sensors_spi.c @@ -29,7 +29,6 @@ static unsigned int st_sensors_spi_get_irq(struct iio_dev *indio_dev) static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb, struct device *dev, u8 reg_addr, int len, u8 *data, bool multiread_bit) { - struct spi_message msg; int err; struct spi_transfer xfers[] = { @@ -51,10 +50,7 @@ static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb, else tb->tx_buf[0] = reg_addr | ST_SENSORS_SPI_READ; - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - err = spi_sync(to_spi_device(dev), &msg); + err = spi_sync_transfer(to_spi_device(dev), xfers, ARRAY_SIZE(xfers)); if (err) goto acc_spi_read_error; @@ -83,7 +79,6 @@ static int st_sensors_spi_read_multiple_byte( static int st_sensors_spi_write_byte(struct st_sensor_transfer_buffer *tb, struct device *dev, u8 reg_addr, u8 data) { - struct spi_message msg; int err; struct spi_transfer xfers = { @@ -96,9 +91,7 @@ static int st_sensors_spi_write_byte(struct st_sensor_transfer_buffer *tb, tb->tx_buf[0] = reg_addr; tb->tx_buf[1] = data; - spi_message_init(&msg); - spi_message_add_tail(&xfers, &msg); - err = spi_sync(to_spi_device(dev), &msg); + err = spi_sync_transfer(to_spi_device(dev), &xfers, 1); mutex_unlock(&tb->buf_lock); return err; -- cgit From 10f5b14811023df0ba1a936b14880eabb6d9c199 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Fri, 15 Feb 2013 06:56:00 +0000 Subject: iio: adc: add exynos adc driver under iio framwork This patch adds New driver to support: 1. Supports ADC IF found on EXYNOS4412/EXYNOS5250 and future SoCs from Samsung 2. Add ADC driver under iio/adc framework 3. Also adds the Documentation for device tree bindings Signed-off-by: Naveen Krishna Chatradhi Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/arm/samsung/exynos-adc.txt | 52 +++ drivers/iio/adc/Kconfig | 7 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/exynos_adc.c | 440 +++++++++++++++++++++ 4 files changed, 500 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt create mode 100644 drivers/iio/adc/exynos_adc.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt new file mode 100644 index 000000000000..f68637861b05 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt @@ -0,0 +1,52 @@ +Samsung Exynos Analog to Digital Converter bindings + +This devicetree binding are for the new adc driver written fori +Exynos4 and upward SoCs from Samsung. + +New driver handles the following +1. Supports ADC IF found on EXYNOS4412/EXYNOS5250 + and future SoCs from Samsung +2. Add ADC driver under iio/adc framework +3. Also adds the Documentation for device tree bindings + +Required properties: +- compatible: Must be "samsung,exynos-adc-v1" + for exynos4412/5250 controllers. + Must be "samsung,exynos-adc-v2" for + future controllers. +- reg: Contains ADC register address range (base address and + length). +- interrupts: Contains the interrupt information for the timer. The + format is being dependent on which interrupt controller + the Samsung device uses. +- #io-channel-cells = <1>; As ADC has multiple outputs + +Note: child nodes can be added for auto probing from device tree. + +Example: adding device info in dtsi file + +adc: adc@12D10000 { + compatible = "samsung,exynos-adc-v1"; + reg = <0x12D10000 0x100>; + interrupts = <0 106 0>; + #io-channel-cells = <1>; + io-channel-ranges; +}; + + +Example: Adding child nodes in dts file + +adc@12D10000 { + + /* NTC thermistor is a hwmon device */ + ncp15wb473@0 { + compatible = "ntc,ncp15wb473"; + pullup-uV = <1800000>; + pullup-ohm = <47000>; + pulldown-ohm = <0>; + io-channels = <&adc 4>; + }; +}; + +Note: Does not apply to ADC driver under arch/arm/plat-samsung/ +Note: The child node can be added under the adc node or seperately. diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 00213eaf8aa9..a40d3c29f0cb 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -103,6 +103,13 @@ config AT91_ADC help Say yes here to build support for Atmel AT91 ADC. +config EXYNOS_ADC + bool "Exynos ADC driver support" + help + Core support for the ADC block found in the Samsung EXYNOS series + of SoCs for drivers such as the touchscreen and hwmon to use to share + this resource. + config LP8788_ADC bool "LP8788 ADC driver" depends on MFD_LP8788 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index ab910ba4664c..0a825bed43f6 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7793) += ad7793.o obj-$(CONFIG_AD7887) += ad7887.o obj-$(CONFIG_AT91_ADC) += at91_adc.o +obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c new file mode 100644 index 000000000000..ed6fdd7e5212 --- /dev/null +++ b/drivers/iio/adc/exynos_adc.c @@ -0,0 +1,440 @@ +/* + * exynos_adc.c - Support for ADC in EXYNOS SoCs + * + * 8 ~ 10 channel, 10/12-bit ADC + * + * Copyright (C) 2013 Naveen Krishna Chatradhi + * + * 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 + +enum adc_version { + ADC_V1, + ADC_V2 +}; + +/* EXYNOS4412/5250 ADC_V1 registers definitions */ +#define ADC_V1_CON(x) ((x) + 0x00) +#define ADC_V1_DLY(x) ((x) + 0x08) +#define ADC_V1_DATX(x) ((x) + 0x0C) +#define ADC_V1_INTCLR(x) ((x) + 0x18) +#define ADC_V1_MUX(x) ((x) + 0x1c) + +/* Future ADC_V2 registers definitions */ +#define ADC_V2_CON1(x) ((x) + 0x00) +#define ADC_V2_CON2(x) ((x) + 0x04) +#define ADC_V2_STAT(x) ((x) + 0x08) +#define ADC_V2_INT_EN(x) ((x) + 0x10) +#define ADC_V2_INT_ST(x) ((x) + 0x14) +#define ADC_V2_VER(x) ((x) + 0x20) + +/* Bit definitions for ADC_V1 */ +#define ADC_V1_CON_RES (1u << 16) +#define ADC_V1_CON_PRSCEN (1u << 14) +#define ADC_V1_CON_PRSCLV(x) (((x) & 0xFF) << 6) +#define ADC_V1_CON_STANDBY (1u << 2) + +/* Bit definitions for ADC_V2 */ +#define ADC_V2_CON1_SOFT_RESET (1u << 2) + +#define ADC_V2_CON2_OSEL (1u << 10) +#define ADC_V2_CON2_ESEL (1u << 9) +#define ADC_V2_CON2_HIGHF (1u << 8) +#define ADC_V2_CON2_C_TIME(x) (((x) & 7) << 4) +#define ADC_V2_CON2_ACH_SEL(x) (((x) & 0xF) << 0) +#define ADC_V2_CON2_ACH_MASK 0xF + +#define MAX_ADC_V2_CHANNELS 10 +#define MAX_ADC_V1_CHANNELS 8 + +/* Bit definitions common for ADC_V1 and ADC_V2 */ +#define ADC_CON_EN_START (1u << 0) +#define ADC_DATX_MASK 0xFFF + +#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(1000)) + +struct exynos_adc { + void __iomem *regs; + struct clk *clk; + unsigned int irq; + struct regulator *vdd; + + struct completion completion; + + u32 value; + unsigned int version; +}; + +static const struct of_device_id exynos_adc_match[] = { + { .compatible = "samsung,exynos-adc-v1", .data = (void *)ADC_V1 }, + { .compatible = "samsung,exynos-adc-v2", .data = (void *)ADC_V2 }, + {}, +}; +MODULE_DEVICE_TABLE(of, exynos_adc_match); + +static inline unsigned int exynos_adc_get_version(struct platform_device *pdev) +{ + const struct of_device_id *match; + + match = of_match_node(exynos_adc_match, pdev->dev.of_node); + return (unsigned int)match->data; +} + +static int exynos_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct exynos_adc *info = iio_priv(indio_dev); + unsigned long timeout; + u32 con1, con2; + + if (mask != IIO_CHAN_INFO_RAW) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + + /* Select the channel to be used and Trigger conversion */ + if (info->version == ADC_V2) { + con2 = readl(ADC_V2_CON2(info->regs)); + con2 &= ~ADC_V2_CON2_ACH_MASK; + con2 |= ADC_V2_CON2_ACH_SEL(chan->address); + writel(con2, ADC_V2_CON2(info->regs)); + + con1 = readl(ADC_V2_CON1(info->regs)); + writel(con1 | ADC_CON_EN_START, + ADC_V2_CON1(info->regs)); + } else { + writel(chan->address, ADC_V1_MUX(info->regs)); + + con1 = readl(ADC_V1_CON(info->regs)); + writel(con1 | ADC_CON_EN_START, + ADC_V1_CON(info->regs)); + } + + timeout = wait_for_completion_interruptible_timeout + (&info->completion, EXYNOS_ADC_TIMEOUT); + *val = info->value; + + mutex_unlock(&indio_dev->mlock); + + if (timeout == 0) + return -ETIMEDOUT; + + return IIO_VAL_INT; +} + +static irqreturn_t exynos_adc_isr(int irq, void *dev_id) +{ + struct exynos_adc *info = (struct exynos_adc *)dev_id; + + /* Read value */ + info->value = readl(ADC_V1_DATX(info->regs)) & + ADC_DATX_MASK; + /* clear irq */ + if (info->version == ADC_V2) + writel(1, ADC_V2_INT_ST(info->regs)); + else + writel(1, ADC_V1_INTCLR(info->regs)); + + complete(&info->completion); + + return IRQ_HANDLED; +} + +static int exynos_adc_reg_access(struct iio_dev *indio_dev, + unsigned reg, unsigned writeval, + unsigned *readval) +{ + struct exynos_adc *info = iio_priv(indio_dev); + + if (readval == NULL) + return -EINVAL; + + *readval = readl(info->regs + reg); + + return 0; +} + +static const struct iio_info exynos_adc_iio_info = { + .read_raw = &exynos_read_raw, + .debugfs_reg_access = &exynos_adc_reg_access, + .driver_module = THIS_MODULE, +}; + +#define ADC_CHANNEL(_index, _id) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .address = _index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .datasheet_name = _id, \ +} + +static const struct iio_chan_spec exynos_adc_iio_channels[] = { + ADC_CHANNEL(0, "adc0"), + ADC_CHANNEL(1, "adc1"), + ADC_CHANNEL(2, "adc2"), + ADC_CHANNEL(3, "adc3"), + ADC_CHANNEL(4, "adc4"), + ADC_CHANNEL(5, "adc5"), + ADC_CHANNEL(6, "adc6"), + ADC_CHANNEL(7, "adc7"), + ADC_CHANNEL(8, "adc8"), + ADC_CHANNEL(9, "adc9"), +}; + +static int exynos_adc_remove_devices(struct device *dev, void *c) +{ + struct platform_device *pdev = to_platform_device(dev); + + platform_device_unregister(pdev); + + return 0; +} + +static void exynos_adc_hw_init(struct exynos_adc *info) +{ + u32 con1, con2; + + if (info->version == ADC_V2) { + con1 = ADC_V2_CON1_SOFT_RESET; + writel(con1, ADC_V2_CON1(info->regs)); + + con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL | + ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0); + writel(con2, ADC_V2_CON2(info->regs)); + + /* Enable interrupts */ + writel(1, ADC_V2_INT_EN(info->regs)); + } else { + /* set default prescaler values and Enable prescaler */ + con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN; + + /* Enable 12-bit ADC resolution */ + con1 |= ADC_V1_CON_RES; + writel(con1, ADC_V1_CON(info->regs)); + } +} + +static int exynos_adc_probe(struct platform_device *pdev) +{ + struct exynos_adc *info = NULL; + struct device_node *np = pdev->dev.of_node; + struct iio_dev *indio_dev = NULL; + struct resource *mem; + int ret = -ENODEV; + int irq; + + if (!np) + return ret; + + indio_dev = iio_device_alloc(sizeof(struct exynos_adc)); + if (!indio_dev) { + dev_err(&pdev->dev, "failed allocating iio device\n"); + return -ENOMEM; + } + + info = iio_priv(indio_dev); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + info->regs = devm_request_and_ioremap(&pdev->dev, mem); + if (!info->regs) { + ret = -ENOMEM; + goto err_iio; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + ret = irq; + goto err_iio; + } + + info->irq = irq; + + init_completion(&info->completion); + + ret = request_irq(info->irq, exynos_adc_isr, + 0, dev_name(&pdev->dev), info); + if (ret < 0) { + dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", + info->irq); + goto err_iio; + } + + info->clk = devm_clk_get(&pdev->dev, "adc"); + if (IS_ERR(info->clk)) { + dev_err(&pdev->dev, "failed getting clock, err = %ld\n", + PTR_ERR(info->clk)); + ret = PTR_ERR(info->clk); + goto err_irq; + } + + info->vdd = devm_regulator_get(&pdev->dev, "vdd"); + if (IS_ERR(info->vdd)) { + dev_err(&pdev->dev, "failed getting regulator, err = %ld\n", + PTR_ERR(info->vdd)); + ret = PTR_ERR(info->vdd); + goto err_irq; + } + + info->version = exynos_adc_get_version(pdev); + + platform_set_drvdata(pdev, indio_dev); + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->dev.of_node = pdev->dev.of_node; + indio_dev->info = &exynos_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = exynos_adc_iio_channels; + + if (info->version == ADC_V1) + indio_dev->num_channels = MAX_ADC_V1_CHANNELS; + else + indio_dev->num_channels = MAX_ADC_V2_CHANNELS; + + ret = iio_device_register(indio_dev); + if (ret) + goto err_irq; + + ret = regulator_enable(info->vdd); + if (ret) + goto err_iio_dev; + + clk_prepare_enable(info->clk); + + exynos_adc_hw_init(info); + + ret = of_platform_populate(np, exynos_adc_match, NULL, &pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "failed adding child nodes\n"); + goto err_of_populate; + } + + return 0; + +err_of_populate: + device_for_each_child(&pdev->dev, NULL, + exynos_adc_remove_devices); + regulator_disable(info->vdd); + clk_disable_unprepare(info->clk); +err_iio_dev: + iio_device_unregister(indio_dev); +err_irq: + free_irq(info->irq, info); +err_iio: + iio_device_free(indio_dev); + return ret; +} + +static int exynos_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct exynos_adc *info = iio_priv(indio_dev); + + device_for_each_child(&pdev->dev, NULL, + exynos_adc_remove_devices); + regulator_disable(info->vdd); + clk_disable_unprepare(info->clk); + iio_device_unregister(indio_dev); + free_irq(info->irq, info); + iio_device_free(indio_dev); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int exynos_adc_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct exynos_adc *info = platform_get_drvdata(pdev); + u32 con; + + if (info->version == ADC_V2) { + con = readl(ADC_V2_CON1(info->regs)); + con &= ~ADC_CON_EN_START; + writel(con, ADC_V2_CON1(info->regs)); + } else { + con = readl(ADC_V1_CON(info->regs)); + con |= ADC_V1_CON_STANDBY; + writel(con, ADC_V1_CON(info->regs)); + } + + clk_disable_unprepare(info->clk); + regulator_disable(info->vdd); + + return 0; +} + +static int exynos_adc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct exynos_adc *info = platform_get_drvdata(pdev); + int ret; + + ret = regulator_enable(info->vdd); + if (ret) + return ret; + + clk_prepare_enable(info->clk); + + exynos_adc_hw_init(info); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(exynos_adc_pm_ops, + exynos_adc_suspend, + exynos_adc_resume); + +static struct platform_driver exynos_adc_driver = { + .probe = exynos_adc_probe, + .remove = exynos_adc_remove, + .driver = { + .name = "exynos-adc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(exynos_adc_match), + .pm = &exynos_adc_pm_ops, + }, +}; + +module_platform_driver(exynos_adc_driver); + +MODULE_AUTHOR("Naveen Krishna Chatradhi "); +MODULE_DESCRIPTION("Samsung EXYNOS5 ADC driver"); +MODULE_LICENSE("GPL v2"); -- cgit From 7a875903389f3492d4cb06faa1d55a1630e77c11 Mon Sep 17 00:00:00 2001 From: Erwan Yvin Date: Mon, 11 Mar 2013 03:13:03 +0000 Subject: caif: remove caif_shm caif_shm is an old implementation caif_shm will be replaced by caif_virtio [ As explained by Linus Walleij: "U5500 used this, but was cancelled and the silicon did not reach anyone outside ST-Ericsson. Then for the next platforms, we have gone for the leaner & cleaner approach of using virtio, rpmesg and rproc." ] Signed-off-by: Erwan Yvin Acked-by: Linus Walleij Acked-by: Sjur Brendeland Signed-off-by: David S. Miller --- drivers/net/caif/Kconfig | 7 - drivers/net/caif/Makefile | 4 - drivers/net/caif/caif_shm_u5500.c | 128 ------- drivers/net/caif/caif_shmcore.c | 744 -------------------------------------- include/net/caif/caif_shm.h | 26 -- 5 files changed, 909 deletions(-) delete mode 100644 drivers/net/caif/caif_shm_u5500.c delete mode 100644 drivers/net/caif/caif_shmcore.c delete mode 100644 include/net/caif/caif_shm.h (limited to 'drivers') diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 60c2142373c9..a966128c2a7a 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig @@ -32,13 +32,6 @@ config CAIF_SPI_SYNC help to synchronize to the next transfer in case of over or under-runs. This option also needs to be enabled on the modem. -config CAIF_SHM - tristate "CAIF shared memory protocol driver" - depends on CAIF && U5500_MBOX - default n - ---help--- - The CAIF shared memory protocol driver for the STE UX5500 platform. - config CAIF_HSI tristate "CAIF HSI transport driver" depends on CAIF diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile index 91dff861560f..15a9d2fc753d 100644 --- a/drivers/net/caif/Makefile +++ b/drivers/net/caif/Makefile @@ -7,9 +7,5 @@ obj-$(CONFIG_CAIF_TTY) += caif_serial.o cfspi_slave-objs := caif_spi.o caif_spi_slave.o obj-$(CONFIG_CAIF_SPI_SLAVE) += cfspi_slave.o -# Shared memory -caif_shm-objs := caif_shmcore.o caif_shm_u5500.o -obj-$(CONFIG_CAIF_SHM) += caif_shm.o - # HSI interface obj-$(CONFIG_CAIF_HSI) += caif_hsi.o diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c deleted file mode 100644 index 89d76b7b325a..000000000000 --- a/drivers/net/caif/caif_shm_u5500.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) ST-Ericsson AB 2010 - * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com - * Author: Amarnath Revanna / amarnath.bangalore.revanna@stericsson.com - * License terms: GNU General Public License (GPL) version 2 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt - -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("CAIF Shared Memory protocol driver"); - -#define MAX_SHM_INSTANCES 1 - -enum { - MBX_ACC0, - MBX_ACC1, - MBX_DSP -}; - -static struct shmdev_layer shmdev_lyr[MAX_SHM_INSTANCES]; - -static unsigned int shm_start; -static unsigned int shm_size; - -module_param(shm_size, uint , 0440); -MODULE_PARM_DESC(shm_total_size, "Start of SHM shared memory"); - -module_param(shm_start, uint , 0440); -MODULE_PARM_DESC(shm_total_start, "Total Size of SHM shared memory"); - -static int shmdev_send_msg(u32 dev_id, u32 mbx_msg) -{ - /* Always block until msg is written successfully */ - mbox_send(shmdev_lyr[dev_id].hmbx, mbx_msg, true); - return 0; -} - -static int shmdev_mbx_setup(void *pshmdrv_cb, struct shmdev_layer *pshm_dev, - void *pshm_drv) -{ - /* - * For UX5500, we have only 1 SHM instance which uses MBX0 - * for communication with the peer modem - */ - pshm_dev->hmbx = mbox_setup(MBX_ACC0, pshmdrv_cb, pshm_drv); - - if (!pshm_dev->hmbx) - return -ENODEV; - else - return 0; -} - -static int __init caif_shmdev_init(void) -{ - int i, result; - - /* Loop is currently overkill, there is only one instance */ - for (i = 0; i < MAX_SHM_INSTANCES; i++) { - - shmdev_lyr[i].shm_base_addr = shm_start; - shmdev_lyr[i].shm_total_sz = shm_size; - - if (((char *)shmdev_lyr[i].shm_base_addr == NULL) - || (shmdev_lyr[i].shm_total_sz <= 0)) { - pr_warn("ERROR," - "Shared memory Address and/or Size incorrect" - ", Bailing out ...\n"); - result = -EINVAL; - goto clean; - } - - pr_info("SHM AREA (instance %d) STARTS" - " AT %p\n", i, (char *)shmdev_lyr[i].shm_base_addr); - - shmdev_lyr[i].shm_id = i; - shmdev_lyr[i].pshmdev_mbxsend = shmdev_send_msg; - shmdev_lyr[i].pshmdev_mbxsetup = shmdev_mbx_setup; - - /* - * Finally, CAIF core module is called with details in place: - * 1. SHM base address - * 2. SHM size - * 3. MBX handle - */ - result = caif_shmcore_probe(&shmdev_lyr[i]); - if (result) { - pr_warn("ERROR[%d]," - "Could not probe SHM core (instance %d)" - " Bailing out ...\n", result, i); - goto clean; - } - } - - return 0; - -clean: - /* - * For now, we assume that even if one instance of SHM fails, we bail - * out of the driver support completely. For this, we need to release - * any memory allocated and unregister any instance of SHM net device. - */ - for (i = 0; i < MAX_SHM_INSTANCES; i++) { - if (shmdev_lyr[i].pshm_netdev) - unregister_netdev(shmdev_lyr[i].pshm_netdev); - } - return result; -} - -static void __exit caif_shmdev_exit(void) -{ - int i; - - for (i = 0; i < MAX_SHM_INSTANCES; i++) { - caif_shmcore_remove(shmdev_lyr[i].pshm_netdev); - kfree((void *)shmdev_lyr[i].shm_base_addr); - } - -} - -module_init(caif_shmdev_init); -module_exit(caif_shmdev_exit); diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c deleted file mode 100644 index cca2afc945af..000000000000 --- a/drivers/net/caif/caif_shmcore.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * Copyright (C) ST-Ericsson AB 2010 - * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com - * Authors: Amarnath Revanna / amarnath.bangalore.revanna@stericsson.com, - * Daniel Martensson / daniel.martensson@stericsson.com - * License terms: GNU General Public License (GPL) version 2 - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NR_TX_BUF 6 -#define NR_RX_BUF 6 -#define TX_BUF_SZ 0x2000 -#define RX_BUF_SZ 0x2000 - -#define CAIF_NEEDED_HEADROOM 32 - -#define CAIF_FLOW_ON 1 -#define CAIF_FLOW_OFF 0 - -#define LOW_WATERMARK 3 -#define HIGH_WATERMARK 4 - -/* Maximum number of CAIF buffers per shared memory buffer. */ -#define SHM_MAX_FRMS_PER_BUF 10 - -/* - * Size in bytes of the descriptor area - * (With end of descriptor signalling) - */ -#define SHM_CAIF_DESC_SIZE ((SHM_MAX_FRMS_PER_BUF + 1) * \ - sizeof(struct shm_pck_desc)) - -/* - * Offset to the first CAIF frame within a shared memory buffer. - * Aligned on 32 bytes. - */ -#define SHM_CAIF_FRM_OFS (SHM_CAIF_DESC_SIZE + (SHM_CAIF_DESC_SIZE % 32)) - -/* Number of bytes for CAIF shared memory header. */ -#define SHM_HDR_LEN 1 - -/* Number of padding bytes for the complete CAIF frame. */ -#define SHM_FRM_PAD_LEN 4 - -#define CAIF_MAX_MTU 4096 - -#define SHM_SET_FULL(x) (((x+1) & 0x0F) << 0) -#define SHM_GET_FULL(x) (((x >> 0) & 0x0F) - 1) - -#define SHM_SET_EMPTY(x) (((x+1) & 0x0F) << 4) -#define SHM_GET_EMPTY(x) (((x >> 4) & 0x0F) - 1) - -#define SHM_FULL_MASK (0x0F << 0) -#define SHM_EMPTY_MASK (0x0F << 4) - -struct shm_pck_desc { - /* - * Offset from start of shared memory area to start of - * shared memory CAIF frame. - */ - u32 frm_ofs; - u32 frm_len; -}; - -struct buf_list { - unsigned char *desc_vptr; - u32 phy_addr; - u32 index; - u32 len; - u32 frames; - u32 frm_ofs; - struct list_head list; -}; - -struct shm_caif_frm { - /* Number of bytes of padding before the CAIF frame. */ - u8 hdr_ofs; -}; - -struct shmdrv_layer { - /* caif_dev_common must always be first in the structure*/ - struct caif_dev_common cfdev; - - u32 shm_tx_addr; - u32 shm_rx_addr; - u32 shm_base_addr; - u32 tx_empty_available; - spinlock_t lock; - - struct list_head tx_empty_list; - struct list_head tx_pend_list; - struct list_head tx_full_list; - struct list_head rx_empty_list; - struct list_head rx_pend_list; - struct list_head rx_full_list; - - struct workqueue_struct *pshm_tx_workqueue; - struct workqueue_struct *pshm_rx_workqueue; - - struct work_struct shm_tx_work; - struct work_struct shm_rx_work; - - struct sk_buff_head sk_qhead; - struct shmdev_layer *pshm_dev; -}; - -static int shm_netdev_open(struct net_device *shm_netdev) -{ - netif_wake_queue(shm_netdev); - return 0; -} - -static int shm_netdev_close(struct net_device *shm_netdev) -{ - netif_stop_queue(shm_netdev); - return 0; -} - -int caif_shmdrv_rx_cb(u32 mbx_msg, void *priv) -{ - struct buf_list *pbuf; - struct shmdrv_layer *pshm_drv; - struct list_head *pos; - u32 avail_emptybuff = 0; - unsigned long flags = 0; - - pshm_drv = priv; - - /* Check for received buffers. */ - if (mbx_msg & SHM_FULL_MASK) { - int idx; - - spin_lock_irqsave(&pshm_drv->lock, flags); - - /* Check whether we have any outstanding buffers. */ - if (list_empty(&pshm_drv->rx_empty_list)) { - - /* Release spin lock. */ - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* We print even in IRQ context... */ - pr_warn("No empty Rx buffers to fill: " - "mbx_msg:%x\n", mbx_msg); - - /* Bail out. */ - goto err_sync; - } - - pbuf = - list_entry(pshm_drv->rx_empty_list.next, - struct buf_list, list); - idx = pbuf->index; - - /* Check buffer synchronization. */ - if (idx != SHM_GET_FULL(mbx_msg)) { - - /* We print even in IRQ context... */ - pr_warn( - "phyif_shm_mbx_msg_cb: RX full out of sync:" - " idx:%d, msg:%x SHM_GET_FULL(mbx_msg):%x\n", - idx, mbx_msg, SHM_GET_FULL(mbx_msg)); - - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* Bail out. */ - goto err_sync; - } - - list_del_init(&pbuf->list); - list_add_tail(&pbuf->list, &pshm_drv->rx_full_list); - - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* Schedule RX work queue. */ - if (!work_pending(&pshm_drv->shm_rx_work)) - queue_work(pshm_drv->pshm_rx_workqueue, - &pshm_drv->shm_rx_work); - } - - /* Check for emptied buffers. */ - if (mbx_msg & SHM_EMPTY_MASK) { - int idx; - - spin_lock_irqsave(&pshm_drv->lock, flags); - - /* Check whether we have any outstanding buffers. */ - if (list_empty(&pshm_drv->tx_full_list)) { - - /* We print even in IRQ context... */ - pr_warn("No TX to empty: msg:%x\n", mbx_msg); - - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* Bail out. */ - goto err_sync; - } - - pbuf = - list_entry(pshm_drv->tx_full_list.next, - struct buf_list, list); - idx = pbuf->index; - - /* Check buffer synchronization. */ - if (idx != SHM_GET_EMPTY(mbx_msg)) { - - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* We print even in IRQ context... */ - pr_warn("TX empty " - "out of sync:idx:%d, msg:%x\n", idx, mbx_msg); - - /* Bail out. */ - goto err_sync; - } - list_del_init(&pbuf->list); - - /* Reset buffer parameters. */ - pbuf->frames = 0; - pbuf->frm_ofs = SHM_CAIF_FRM_OFS; - - list_add_tail(&pbuf->list, &pshm_drv->tx_empty_list); - - /* Check the available no. of buffers in the empty list */ - list_for_each(pos, &pshm_drv->tx_empty_list) - avail_emptybuff++; - - /* Check whether we have to wake up the transmitter. */ - if ((avail_emptybuff > HIGH_WATERMARK) && - (!pshm_drv->tx_empty_available)) { - pshm_drv->tx_empty_available = 1; - spin_unlock_irqrestore(&pshm_drv->lock, flags); - pshm_drv->cfdev.flowctrl - (pshm_drv->pshm_dev->pshm_netdev, - CAIF_FLOW_ON); - - - /* Schedule the work queue. if required */ - if (!work_pending(&pshm_drv->shm_tx_work)) - queue_work(pshm_drv->pshm_tx_workqueue, - &pshm_drv->shm_tx_work); - } else - spin_unlock_irqrestore(&pshm_drv->lock, flags); - } - - return 0; - -err_sync: - return -EIO; -} - -static void shm_rx_work_func(struct work_struct *rx_work) -{ - struct shmdrv_layer *pshm_drv; - struct buf_list *pbuf; - unsigned long flags = 0; - struct sk_buff *skb; - char *p; - int ret; - - pshm_drv = container_of(rx_work, struct shmdrv_layer, shm_rx_work); - - while (1) { - - struct shm_pck_desc *pck_desc; - - spin_lock_irqsave(&pshm_drv->lock, flags); - - /* Check for received buffers. */ - if (list_empty(&pshm_drv->rx_full_list)) { - spin_unlock_irqrestore(&pshm_drv->lock, flags); - break; - } - - pbuf = - list_entry(pshm_drv->rx_full_list.next, struct buf_list, - list); - list_del_init(&pbuf->list); - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - /* Retrieve pointer to start of the packet descriptor area. */ - pck_desc = (struct shm_pck_desc *) pbuf->desc_vptr; - - /* - * Check whether descriptor contains a CAIF shared memory - * frame. - */ - while (pck_desc->frm_ofs) { - unsigned int frm_buf_ofs; - unsigned int frm_pck_ofs; - unsigned int frm_pck_len; - /* - * Check whether offset is within buffer limits - * (lower). - */ - if (pck_desc->frm_ofs < - (pbuf->phy_addr - pshm_drv->shm_base_addr)) - break; - /* - * Check whether offset is within buffer limits - * (higher). - */ - if (pck_desc->frm_ofs > - ((pbuf->phy_addr - pshm_drv->shm_base_addr) + - pbuf->len)) - break; - - /* Calculate offset from start of buffer. */ - frm_buf_ofs = - pck_desc->frm_ofs - (pbuf->phy_addr - - pshm_drv->shm_base_addr); - - /* - * Calculate offset and length of CAIF packet while - * taking care of the shared memory header. - */ - frm_pck_ofs = - frm_buf_ofs + SHM_HDR_LEN + - (*(pbuf->desc_vptr + frm_buf_ofs)); - frm_pck_len = - (pck_desc->frm_len - SHM_HDR_LEN - - (*(pbuf->desc_vptr + frm_buf_ofs))); - - /* Check whether CAIF packet is within buffer limits */ - if ((frm_pck_ofs + pck_desc->frm_len) > pbuf->len) - break; - - /* Get a suitable CAIF packet and copy in data. */ - skb = netdev_alloc_skb(pshm_drv->pshm_dev->pshm_netdev, - frm_pck_len + 1); - if (skb == NULL) - break; - - p = skb_put(skb, frm_pck_len); - memcpy(p, pbuf->desc_vptr + frm_pck_ofs, frm_pck_len); - - skb->protocol = htons(ETH_P_CAIF); - skb_reset_mac_header(skb); - skb->dev = pshm_drv->pshm_dev->pshm_netdev; - - /* Push received packet up the stack. */ - ret = netif_rx_ni(skb); - - if (!ret) { - pshm_drv->pshm_dev->pshm_netdev->stats. - rx_packets++; - pshm_drv->pshm_dev->pshm_netdev->stats. - rx_bytes += pck_desc->frm_len; - } else - ++pshm_drv->pshm_dev->pshm_netdev->stats. - rx_dropped; - /* Move to next packet descriptor. */ - pck_desc++; - } - - spin_lock_irqsave(&pshm_drv->lock, flags); - list_add_tail(&pbuf->list, &pshm_drv->rx_pend_list); - - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - } - - /* Schedule the work queue. if required */ - if (!work_pending(&pshm_drv->shm_tx_work)) - queue_work(pshm_drv->pshm_tx_workqueue, &pshm_drv->shm_tx_work); - -} - -static void shm_tx_work_func(struct work_struct *tx_work) -{ - u32 mbox_msg; - unsigned int frmlen, avail_emptybuff, append = 0; - unsigned long flags = 0; - struct buf_list *pbuf = NULL; - struct shmdrv_layer *pshm_drv; - struct shm_caif_frm *frm; - struct sk_buff *skb; - struct shm_pck_desc *pck_desc; - struct list_head *pos; - - pshm_drv = container_of(tx_work, struct shmdrv_layer, shm_tx_work); - - do { - /* Initialize mailbox message. */ - mbox_msg = 0x00; - avail_emptybuff = 0; - - spin_lock_irqsave(&pshm_drv->lock, flags); - - /* Check for pending receive buffers. */ - if (!list_empty(&pshm_drv->rx_pend_list)) { - - pbuf = list_entry(pshm_drv->rx_pend_list.next, - struct buf_list, list); - - list_del_init(&pbuf->list); - list_add_tail(&pbuf->list, &pshm_drv->rx_empty_list); - /* - * Value index is never changed, - * so read access should be safe. - */ - mbox_msg |= SHM_SET_EMPTY(pbuf->index); - } - - skb = skb_peek(&pshm_drv->sk_qhead); - - if (skb == NULL) - goto send_msg; - /* Check the available no. of buffers in the empty list */ - list_for_each(pos, &pshm_drv->tx_empty_list) - avail_emptybuff++; - - if ((avail_emptybuff < LOW_WATERMARK) && - pshm_drv->tx_empty_available) { - /* Update blocking condition. */ - pshm_drv->tx_empty_available = 0; - spin_unlock_irqrestore(&pshm_drv->lock, flags); - pshm_drv->cfdev.flowctrl - (pshm_drv->pshm_dev->pshm_netdev, - CAIF_FLOW_OFF); - spin_lock_irqsave(&pshm_drv->lock, flags); - } - /* - * We simply return back to the caller if we do not have space - * either in Tx pending list or Tx empty list. In this case, - * we hold the received skb in the skb list, waiting to - * be transmitted once Tx buffers become available - */ - if (list_empty(&pshm_drv->tx_empty_list)) - goto send_msg; - - /* Get the first free Tx buffer. */ - pbuf = list_entry(pshm_drv->tx_empty_list.next, - struct buf_list, list); - do { - if (append) { - skb = skb_peek(&pshm_drv->sk_qhead); - if (skb == NULL) - break; - } - - frm = (struct shm_caif_frm *) - (pbuf->desc_vptr + pbuf->frm_ofs); - - frm->hdr_ofs = 0; - frmlen = 0; - frmlen += SHM_HDR_LEN + frm->hdr_ofs + skb->len; - - /* Add tail padding if needed. */ - if (frmlen % SHM_FRM_PAD_LEN) - frmlen += SHM_FRM_PAD_LEN - - (frmlen % SHM_FRM_PAD_LEN); - - /* - * Verify that packet, header and additional padding - * can fit within the buffer frame area. - */ - if (frmlen >= (pbuf->len - pbuf->frm_ofs)) - break; - - if (!append) { - list_del_init(&pbuf->list); - append = 1; - } - - skb = skb_dequeue(&pshm_drv->sk_qhead); - if (skb == NULL) - break; - /* Copy in CAIF frame. */ - skb_copy_bits(skb, 0, pbuf->desc_vptr + - pbuf->frm_ofs + SHM_HDR_LEN + - frm->hdr_ofs, skb->len); - - pshm_drv->pshm_dev->pshm_netdev->stats.tx_packets++; - pshm_drv->pshm_dev->pshm_netdev->stats.tx_bytes += - frmlen; - dev_kfree_skb_irq(skb); - - /* Fill in the shared memory packet descriptor area. */ - pck_desc = (struct shm_pck_desc *) (pbuf->desc_vptr); - /* Forward to current frame. */ - pck_desc += pbuf->frames; - pck_desc->frm_ofs = (pbuf->phy_addr - - pshm_drv->shm_base_addr) + - pbuf->frm_ofs; - pck_desc->frm_len = frmlen; - /* Terminate packet descriptor area. */ - pck_desc++; - pck_desc->frm_ofs = 0; - /* Update buffer parameters. */ - pbuf->frames++; - pbuf->frm_ofs += frmlen + (frmlen % 32); - - } while (pbuf->frames < SHM_MAX_FRMS_PER_BUF); - - /* Assign buffer as full. */ - list_add_tail(&pbuf->list, &pshm_drv->tx_full_list); - append = 0; - mbox_msg |= SHM_SET_FULL(pbuf->index); -send_msg: - spin_unlock_irqrestore(&pshm_drv->lock, flags); - - if (mbox_msg) - pshm_drv->pshm_dev->pshmdev_mbxsend - (pshm_drv->pshm_dev->shm_id, mbox_msg); - } while (mbox_msg); -} - -static int shm_netdev_tx(struct sk_buff *skb, struct net_device *shm_netdev) -{ - struct shmdrv_layer *pshm_drv; - - pshm_drv = netdev_priv(shm_netdev); - - skb_queue_tail(&pshm_drv->sk_qhead, skb); - - /* Schedule Tx work queue. for deferred processing of skbs*/ - if (!work_pending(&pshm_drv->shm_tx_work)) - queue_work(pshm_drv->pshm_tx_workqueue, &pshm_drv->shm_tx_work); - - return 0; -} - -static const struct net_device_ops netdev_ops = { - .ndo_open = shm_netdev_open, - .ndo_stop = shm_netdev_close, - .ndo_start_xmit = shm_netdev_tx, -}; - -static void shm_netdev_setup(struct net_device *pshm_netdev) -{ - struct shmdrv_layer *pshm_drv; - pshm_netdev->netdev_ops = &netdev_ops; - - pshm_netdev->mtu = CAIF_MAX_MTU; - pshm_netdev->type = ARPHRD_CAIF; - pshm_netdev->hard_header_len = CAIF_NEEDED_HEADROOM; - pshm_netdev->tx_queue_len = 0; - pshm_netdev->destructor = free_netdev; - - pshm_drv = netdev_priv(pshm_netdev); - - /* Initialize structures in a clean state. */ - memset(pshm_drv, 0, sizeof(struct shmdrv_layer)); - - pshm_drv->cfdev.link_select = CAIF_LINK_LOW_LATENCY; -} - -int caif_shmcore_probe(struct shmdev_layer *pshm_dev) -{ - int result, j; - struct shmdrv_layer *pshm_drv = NULL; - - pshm_dev->pshm_netdev = alloc_netdev(sizeof(struct shmdrv_layer), - "cfshm%d", shm_netdev_setup); - if (!pshm_dev->pshm_netdev) - return -ENOMEM; - - pshm_drv = netdev_priv(pshm_dev->pshm_netdev); - pshm_drv->pshm_dev = pshm_dev; - - /* - * Initialization starts with the verification of the - * availability of MBX driver by calling its setup function. - * MBX driver must be available by this time for proper - * functioning of SHM driver. - */ - if ((pshm_dev->pshmdev_mbxsetup - (caif_shmdrv_rx_cb, pshm_dev, pshm_drv)) != 0) { - pr_warn("Could not config. SHM Mailbox," - " Bailing out.....\n"); - free_netdev(pshm_dev->pshm_netdev); - return -ENODEV; - } - - skb_queue_head_init(&pshm_drv->sk_qhead); - - pr_info("SHM DEVICE[%d] PROBED BY DRIVER, NEW SHM DRIVER" - " INSTANCE AT pshm_drv =0x%p\n", - pshm_drv->pshm_dev->shm_id, pshm_drv); - - if (pshm_dev->shm_total_sz < - (NR_TX_BUF * TX_BUF_SZ + NR_RX_BUF * RX_BUF_SZ)) { - - pr_warn("ERROR, Amount of available" - " Phys. SHM cannot accommodate current SHM " - "driver configuration, Bailing out ...\n"); - free_netdev(pshm_dev->pshm_netdev); - return -ENOMEM; - } - - pshm_drv->shm_base_addr = pshm_dev->shm_base_addr; - pshm_drv->shm_tx_addr = pshm_drv->shm_base_addr; - - if (pshm_dev->shm_loopback) - pshm_drv->shm_rx_addr = pshm_drv->shm_tx_addr; - else - pshm_drv->shm_rx_addr = pshm_dev->shm_base_addr + - (NR_TX_BUF * TX_BUF_SZ); - - spin_lock_init(&pshm_drv->lock); - INIT_LIST_HEAD(&pshm_drv->tx_empty_list); - INIT_LIST_HEAD(&pshm_drv->tx_pend_list); - INIT_LIST_HEAD(&pshm_drv->tx_full_list); - - INIT_LIST_HEAD(&pshm_drv->rx_empty_list); - INIT_LIST_HEAD(&pshm_drv->rx_pend_list); - INIT_LIST_HEAD(&pshm_drv->rx_full_list); - - INIT_WORK(&pshm_drv->shm_tx_work, shm_tx_work_func); - INIT_WORK(&pshm_drv->shm_rx_work, shm_rx_work_func); - - pshm_drv->pshm_tx_workqueue = - create_singlethread_workqueue("shm_tx_work"); - pshm_drv->pshm_rx_workqueue = - create_singlethread_workqueue("shm_rx_work"); - - for (j = 0; j < NR_TX_BUF; j++) { - struct buf_list *tx_buf = - kmalloc(sizeof(struct buf_list), GFP_KERNEL); - - if (tx_buf == NULL) { - free_netdev(pshm_dev->pshm_netdev); - return -ENOMEM; - } - tx_buf->index = j; - tx_buf->phy_addr = pshm_drv->shm_tx_addr + (TX_BUF_SZ * j); - tx_buf->len = TX_BUF_SZ; - tx_buf->frames = 0; - tx_buf->frm_ofs = SHM_CAIF_FRM_OFS; - - if (pshm_dev->shm_loopback) - tx_buf->desc_vptr = (unsigned char *)tx_buf->phy_addr; - else - /* - * FIXME: the result of ioremap is not a pointer - arnd - */ - tx_buf->desc_vptr = - ioremap(tx_buf->phy_addr, TX_BUF_SZ); - - list_add_tail(&tx_buf->list, &pshm_drv->tx_empty_list); - } - - for (j = 0; j < NR_RX_BUF; j++) { - struct buf_list *rx_buf = - kmalloc(sizeof(struct buf_list), GFP_KERNEL); - - if (rx_buf == NULL) { - free_netdev(pshm_dev->pshm_netdev); - return -ENOMEM; - } - rx_buf->index = j; - rx_buf->phy_addr = pshm_drv->shm_rx_addr + (RX_BUF_SZ * j); - rx_buf->len = RX_BUF_SZ; - - if (pshm_dev->shm_loopback) - rx_buf->desc_vptr = (unsigned char *)rx_buf->phy_addr; - else - rx_buf->desc_vptr = - ioremap(rx_buf->phy_addr, RX_BUF_SZ); - list_add_tail(&rx_buf->list, &pshm_drv->rx_empty_list); - } - - pshm_drv->tx_empty_available = 1; - result = register_netdev(pshm_dev->pshm_netdev); - if (result) - pr_warn("ERROR[%d], SHM could not, " - "register with NW FRMWK Bailing out ...\n", result); - - return result; -} - -void caif_shmcore_remove(struct net_device *pshm_netdev) -{ - struct buf_list *pbuf; - struct shmdrv_layer *pshm_drv = NULL; - - pshm_drv = netdev_priv(pshm_netdev); - - while (!(list_empty(&pshm_drv->tx_pend_list))) { - pbuf = - list_entry(pshm_drv->tx_pend_list.next, - struct buf_list, list); - - list_del(&pbuf->list); - kfree(pbuf); - } - - while (!(list_empty(&pshm_drv->tx_full_list))) { - pbuf = - list_entry(pshm_drv->tx_full_list.next, - struct buf_list, list); - list_del(&pbuf->list); - kfree(pbuf); - } - - while (!(list_empty(&pshm_drv->tx_empty_list))) { - pbuf = - list_entry(pshm_drv->tx_empty_list.next, - struct buf_list, list); - list_del(&pbuf->list); - kfree(pbuf); - } - - while (!(list_empty(&pshm_drv->rx_full_list))) { - pbuf = - list_entry(pshm_drv->tx_full_list.next, - struct buf_list, list); - list_del(&pbuf->list); - kfree(pbuf); - } - - while (!(list_empty(&pshm_drv->rx_pend_list))) { - pbuf = - list_entry(pshm_drv->tx_pend_list.next, - struct buf_list, list); - list_del(&pbuf->list); - kfree(pbuf); - } - - while (!(list_empty(&pshm_drv->rx_empty_list))) { - pbuf = - list_entry(pshm_drv->rx_empty_list.next, - struct buf_list, list); - list_del(&pbuf->list); - kfree(pbuf); - } - - /* Destroy work queues. */ - destroy_workqueue(pshm_drv->pshm_tx_workqueue); - destroy_workqueue(pshm_drv->pshm_rx_workqueue); - - unregister_netdev(pshm_netdev); -} diff --git a/include/net/caif/caif_shm.h b/include/net/caif/caif_shm.h deleted file mode 100644 index 5bcce55438cf..000000000000 --- a/include/net/caif/caif_shm.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) ST-Ericsson AB 2010 - * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com - * Author: Amarnath Revanna / amarnath.bangalore.revanna@stericsson.com - * License terms: GNU General Public License (GPL) version 2 - */ - -#ifndef CAIF_SHM_H_ -#define CAIF_SHM_H_ - -struct shmdev_layer { - u32 shm_base_addr; - u32 shm_total_sz; - u32 shm_id; - u32 shm_loopback; - void *hmbx; - int (*pshmdev_mbxsend) (u32 shm_id, u32 mbx_msg); - int (*pshmdev_mbxsetup) (void *pshmdrv_cb, - struct shmdev_layer *pshm_dev, void *pshm_drv); - struct net_device *pshm_netdev; -}; - -extern int caif_shmcore_probe(struct shmdev_layer *pshm_dev); -extern void caif_shmcore_remove(struct net_device *pshm_netdev); - -#endif -- cgit From 6681712d67eef14c4ce793561c3231659153a320 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Fri, 15 Mar 2013 04:35:51 +0000 Subject: vxlan: generalize forwarding tables This patch generalizes VXLAN forwarding table entries allowing an administrator to: 1) specify multiple destinations for a given MAC 2) specify alternate vni's in the VXLAN header 3) specify alternate destination UDP ports 4) use multicast MAC addresses as fdb lookup keys 5) specify multicast destinations 6) specify the outgoing interface for forwarded packets The combination allows configuration of more complex topologies using VXLAN encapsulation. Changes since v1: rebase to 3.9.0-rc2 Signed-Off-By: David L Stevens Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 263 ++++++++++++++++++++++++++++++++--------- include/uapi/linux/neighbour.h | 3 + net/core/rtnetlink.c | 2 +- 3 files changed, 210 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index db0df07c18dc..33427fd62515 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -81,13 +81,22 @@ struct vxlan_net { struct hlist_head vni_list[VNI_HASH_SIZE]; }; +struct vxlan_rdst { + struct rcu_head rcu; + __be32 remote_ip; + __be16 remote_port; + u32 remote_vni; + u32 remote_ifindex; + struct vxlan_rdst *remote_next; +}; + /* Forwarding table entry */ struct vxlan_fdb { struct hlist_node hlist; /* linked list of entries */ struct rcu_head rcu; unsigned long updated; /* jiffies */ unsigned long used; - __be32 remote_ip; + struct vxlan_rdst remote; u16 state; /* see ndm_state */ u8 eth_addr[ETH_ALEN]; }; @@ -157,7 +166,8 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id) /* Fill in neighbour message in skbuff. */ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, const struct vxlan_fdb *fdb, - u32 portid, u32 seq, int type, unsigned int flags) + u32 portid, u32 seq, int type, unsigned int flags, + const struct vxlan_rdst *rdst) { unsigned long now = jiffies; struct nda_cacheinfo ci; @@ -176,7 +186,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, if (type == RTM_GETNEIGH) { ndm->ndm_family = AF_INET; - send_ip = fdb->remote_ip != 0; + send_ip = rdst->remote_ip != htonl(INADDR_ANY); send_eth = !is_zero_ether_addr(fdb->eth_addr); } else ndm->ndm_family = AF_BRIDGE; @@ -188,7 +198,17 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr)) goto nla_put_failure; - if (send_ip && nla_put_be32(skb, NDA_DST, fdb->remote_ip)) + if (send_ip && nla_put_be32(skb, NDA_DST, rdst->remote_ip)) + goto nla_put_failure; + + if (rdst->remote_port && rdst->remote_port != vxlan_port && + nla_put_be16(skb, NDA_PORT, rdst->remote_port)) + goto nla_put_failure; + if (rdst->remote_vni != vxlan->vni && + nla_put_be32(skb, NDA_VNI, rdst->remote_vni)) + goto nla_put_failure; + if (rdst->remote_ifindex && + nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex)) goto nla_put_failure; ci.ndm_used = jiffies_to_clock_t(now - fdb->used); @@ -211,6 +231,9 @@ static inline size_t vxlan_nlmsg_size(void) return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN) /* NDA_LLADDR */ + nla_total_size(sizeof(__be32)) /* NDA_DST */ + + nla_total_size(sizeof(__be32)) /* NDA_PORT */ + + nla_total_size(sizeof(__be32)) /* NDA_VNI */ + + nla_total_size(sizeof(__u32)) /* NDA_IFINDEX */ + nla_total_size(sizeof(struct nda_cacheinfo)); } @@ -225,7 +248,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan, if (skb == NULL) goto errout; - err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0); + err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, &fdb->remote); if (err < 0) { /* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); @@ -247,7 +270,8 @@ static void vxlan_ip_miss(struct net_device *dev, __be32 ipa) memset(&f, 0, sizeof f); f.state = NUD_STALE; - f.remote_ip = ipa; /* goes to NDA_DST */ + f.remote.remote_ip = ipa; /* goes to NDA_DST */ + f.remote.remote_vni = VXLAN_N_VID; vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH); } @@ -300,10 +324,38 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, return NULL; } +/* Add/update destinations for multicast */ +static int vxlan_fdb_append(struct vxlan_fdb *f, + __be32 ip, __u32 port, __u32 vni, __u32 ifindex) +{ + struct vxlan_rdst *rd_prev, *rd; + + rd_prev = NULL; + for (rd = &f->remote; rd; rd = rd->remote_next) { + if (rd->remote_ip == ip && + rd->remote_port == port && + rd->remote_vni == vni && + rd->remote_ifindex == ifindex) + return 0; + rd_prev = rd; + } + rd = kmalloc(sizeof(*rd), GFP_ATOMIC); + if (rd == NULL) + return -ENOBUFS; + rd->remote_ip = ip; + rd->remote_port = port; + rd->remote_vni = vni; + rd->remote_ifindex = ifindex; + rd->remote_next = NULL; + rd_prev->remote_next = rd; + return 1; +} + /* Add new entry to forwarding table -- assumes lock held */ static int vxlan_fdb_create(struct vxlan_dev *vxlan, const u8 *mac, __be32 ip, - __u16 state, __u16 flags) + __u16 state, __u16 flags, + __u32 port, __u32 vni, __u32 ifindex) { struct vxlan_fdb *f; int notify = 0; @@ -320,6 +372,14 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, f->updated = jiffies; notify = 1; } + if ((flags & NLM_F_APPEND) && + is_multicast_ether_addr(f->eth_addr)) { + int rc = vxlan_fdb_append(f, ip, port, vni, ifindex); + + if (rc < 0) + return rc; + notify |= rc; + } } else { if (!(flags & NLM_F_CREATE)) return -ENOENT; @@ -333,7 +393,11 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, return -ENOMEM; notify = 1; - f->remote_ip = ip; + f->remote.remote_ip = ip; + f->remote.remote_port = port; + f->remote.remote_vni = vni; + f->remote.remote_ifindex = ifindex; + f->remote.remote_next = NULL; f->state = state; f->updated = f->used = jiffies; memcpy(f->eth_addr, mac, ETH_ALEN); @@ -349,6 +413,19 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, return 0; } +void vxlan_fdb_free(struct rcu_head *head) +{ + struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu); + + while (f->remote.remote_next) { + struct vxlan_rdst *rd = f->remote.remote_next; + + f->remote.remote_next = rd->remote_next; + kfree(rd); + } + kfree(f); +} + static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f) { netdev_dbg(vxlan->dev, @@ -358,7 +435,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f) vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH); hlist_del_rcu(&f->hlist); - kfree_rcu(f, rcu); + call_rcu(&f->rcu, vxlan_fdb_free); } /* Add static entry (via netlink) */ @@ -367,7 +444,9 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], const unsigned char *addr, u16 flags) { struct vxlan_dev *vxlan = netdev_priv(dev); + struct net *net = dev_net(vxlan->dev); __be32 ip; + u32 port, vni, ifindex; int err; if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) { @@ -384,8 +463,36 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], ip = nla_get_be32(tb[NDA_DST]); + if (tb[NDA_PORT]) { + if (nla_len(tb[NDA_PORT]) != sizeof(u32)) + return -EINVAL; + port = nla_get_u32(tb[NDA_PORT]); + } else + port = vxlan_port; + + if (tb[NDA_VNI]) { + if (nla_len(tb[NDA_VNI]) != sizeof(u32)) + return -EINVAL; + vni = nla_get_u32(tb[NDA_VNI]); + } else + vni = vxlan->vni; + + if (tb[NDA_IFINDEX]) { + struct net_device *dev; + + if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32)) + return -EINVAL; + ifindex = nla_get_u32(tb[NDA_IFINDEX]); + dev = dev_get_by_index(net, ifindex); + if (!dev) + return -EADDRNOTAVAIL; + dev_put(dev); + } else + ifindex = 0; + spin_lock_bh(&vxlan->hash_lock); - err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags); + err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags, port, + vni, ifindex); spin_unlock_bh(&vxlan->hash_lock); return err; @@ -423,18 +530,21 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, int err; hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) { - if (idx < cb->args[0]) - goto skip; - - err = vxlan_fdb_info(skb, vxlan, f, - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, - RTM_NEWNEIGH, - NLM_F_MULTI); - if (err < 0) - break; + struct vxlan_rdst *rd; + for (rd = &f->remote; rd; rd = rd->remote_next) { + if (idx < cb->args[0]) + goto skip; + + err = vxlan_fdb_info(skb, vxlan, f, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWNEIGH, + NLM_F_MULTI, rd); + if (err < 0) + break; skip: - ++idx; + ++idx; + } } } @@ -454,22 +564,23 @@ static void vxlan_snoop(struct net_device *dev, f = vxlan_find_mac(vxlan, src_mac); if (likely(f)) { f->used = jiffies; - if (likely(f->remote_ip == src_ip)) + if (likely(f->remote.remote_ip == src_ip)) return; if (net_ratelimit()) netdev_info(dev, "%pM migrated from %pI4 to %pI4\n", - src_mac, &f->remote_ip, &src_ip); + src_mac, &f->remote.remote_ip, &src_ip); - f->remote_ip = src_ip; + f->remote.remote_ip = src_ip; f->updated = jiffies; } else { /* learned new entry */ spin_lock(&vxlan->hash_lock); err = vxlan_fdb_create(vxlan, src_mac, src_ip, NUD_REACHABLE, - NLM_F_EXCL|NLM_F_CREATE); + NLM_F_EXCL|NLM_F_CREATE, + vxlan_port, vxlan->vni, 0); spin_unlock(&vxlan->hash_lock); } } @@ -701,7 +812,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb) } f = vxlan_find_mac(vxlan, n->ha); - if (f && f->remote_ip == 0) { + if (f && f->remote.remote_ip == htonl(INADDR_ANY)) { /* bridge-local neighbor */ neigh_release(n); goto out; @@ -834,47 +945,26 @@ static int handle_offloads(struct sk_buff *skb) return 0; } -/* Transmit local packets over Vxlan - * - * Outer IP header inherits ECN and DF from inner header. - * Outer UDP destination is the VXLAN assigned port. - * source port is based on hash of flow - */ -static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + struct vxlan_rdst *rdst, bool did_rsc) { struct vxlan_dev *vxlan = netdev_priv(dev); struct rtable *rt; const struct iphdr *old_iph; - struct ethhdr *eth; struct iphdr *iph; struct vxlanhdr *vxh; struct udphdr *uh; struct flowi4 fl4; unsigned int pkt_len = skb->len; __be32 dst; - __u16 src_port; + __u16 src_port, dst_port; + u32 vni; __be16 df = 0; __u8 tos, ttl; - bool did_rsc = false; - const struct vxlan_fdb *f; - - skb_reset_mac_header(skb); - eth = eth_hdr(skb); - - if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP) - return arp_reduce(dev, skb); - else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP) - did_rsc = route_shortcircuit(dev, skb); - f = vxlan_find_mac(vxlan, eth->h_dest); - if (f == NULL) { - did_rsc = false; - dst = vxlan->gaddr; - if (!dst && (vxlan->flags & VXLAN_F_L2MISS) && - !is_multicast_ether_addr(eth->h_dest)) - vxlan_fdb_miss(vxlan, eth->h_dest); - } else - dst = f->remote_ip; + dst_port = rdst->remote_port ? rdst->remote_port : vxlan_port; + vni = rdst->remote_vni; + dst = rdst->remote_ip; if (!dst) { if (did_rsc) { @@ -922,7 +1012,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) src_port = vxlan_src_port(vxlan, skb); memset(&fl4, 0, sizeof(fl4)); - fl4.flowi4_oif = vxlan->link; + fl4.flowi4_oif = rdst->remote_ifindex; fl4.flowi4_tos = RT_TOS(tos); fl4.daddr = dst; fl4.saddr = vxlan->saddr; @@ -949,13 +1039,13 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); vxh->vx_flags = htonl(VXLAN_FLAGS); - vxh->vx_vni = htonl(vxlan->vni << 8); + vxh->vx_vni = htonl(vni << 8); __skb_push(skb, sizeof(*uh)); skb_reset_transport_header(skb); uh = udp_hdr(skb); - uh->dest = htons(vxlan_port); + uh->dest = htons(dst_port); uh->source = htons(src_port); uh->len = htons(skb->len); @@ -995,6 +1085,64 @@ tx_free: return NETDEV_TX_OK; } +/* Transmit local packets over Vxlan + * + * Outer IP header inherits ECN and DF from inner header. + * Outer UDP destination is the VXLAN assigned port. + * source port is based on hash of flow + */ +static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct vxlan_dev *vxlan = netdev_priv(dev); + struct ethhdr *eth; + bool did_rsc = false; + struct vxlan_rdst group, *rdst0, *rdst; + struct vxlan_fdb *f; + int rc1, rc; + + skb_reset_mac_header(skb); + eth = eth_hdr(skb); + + if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP) + return arp_reduce(dev, skb); + else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP) + did_rsc = route_shortcircuit(dev, skb); + + f = vxlan_find_mac(vxlan, eth->h_dest); + if (f == NULL) { + did_rsc = false; + group.remote_port = vxlan_port; + group.remote_vni = vxlan->vni; + group.remote_ip = vxlan->gaddr; + group.remote_ifindex = vxlan->link; + group.remote_next = 0; + rdst0 = &group; + + if (group.remote_ip == htonl(INADDR_ANY) && + (vxlan->flags & VXLAN_F_L2MISS) && + !is_multicast_ether_addr(eth->h_dest)) + vxlan_fdb_miss(vxlan, eth->h_dest); + } else + rdst0 = &f->remote; + + rc = NETDEV_TX_OK; + + /* if there are multiple destinations, send copies */ + for (rdst = rdst0->remote_next; rdst; rdst = rdst->remote_next) { + struct sk_buff *skb1; + + skb1 = skb_clone(skb, GFP_ATOMIC); + rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc); + if (rc == NETDEV_TX_OK) + rc = rc1; + } + + rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc); + if (rc == NETDEV_TX_OK) + rc = rc1; + return rc; +} + /* Walk the forwarding table and purge stale entries */ static void vxlan_cleanup(unsigned long arg) { @@ -1558,6 +1706,7 @@ static void __exit vxlan_cleanup_module(void) { rtnl_link_unregister(&vxlan_link_ops); unregister_pernet_device(&vxlan_net_ops); + rcu_barrier(); } module_exit(vxlan_cleanup_module); diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h index adb068c53c4e..f175212420ab 100644 --- a/include/uapi/linux/neighbour.h +++ b/include/uapi/linux/neighbour.h @@ -21,6 +21,9 @@ enum { NDA_CACHEINFO, NDA_PROBES, NDA_VLAN, + NDA_PORT, + NDA_VNI, + NDA_IFINDEX, __NDA_MAX }; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 55b5624a4b00..0e86baf8f809 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2112,7 +2112,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } addr = nla_data(tb[NDA_LLADDR]); - if (!is_valid_ether_addr(addr)) { + if (is_zero_ether_addr(addr)) { pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n"); return -EINVAL; } -- cgit From 1f9061d27d3d2028805549c4a306324a48209057 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 15 Mar 2013 07:23:58 +0000 Subject: drivers:net: dma_alloc_coherent: use __GFP_ZERO instead of memset(, 0) Reduce the number of calls required to alloc a zeroed block of memory. Trivially reduces overall object size. Other changes around these removals o Neaten call argument alignment o Remove an unnecessary OOM message after dma_alloc_coherent failure o Remove unnecessary gfp_t stack variable Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/aeroflex/greth.c | 8 ++------ drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++---- drivers/net/ethernet/broadcom/bnx2.c | 5 ++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 9 +++------ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 14 ++++++------- drivers/net/ethernet/broadcom/tg3.c | 11 +++-------- drivers/net/ethernet/brocade/bna/bnad.c | 5 ++--- drivers/net/ethernet/emulex/benet/be_main.c | 14 ++++++------- drivers/net/ethernet/faraday/ftgmac100.c | 5 ++--- drivers/net/ethernet/faraday/ftmac100.c | 8 ++++---- drivers/net/ethernet/ibm/emac/mal.c | 3 +-- drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 6 ++---- drivers/net/ethernet/intel/igbvf/netdev.c | 2 -- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 3 +-- drivers/net/ethernet/marvell/pxa168_eth.c | 16 ++++++++------- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 3 +-- .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 11 +++++------ drivers/net/ethernet/pasemi/pasemi_mac.c | 5 ++--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 23 ++++++++-------------- drivers/net/ethernet/sfc/nic.c | 4 ++-- drivers/net/ethernet/sgi/meth.c | 5 +++-- drivers/net/ethernet/toshiba/spider_net.c | 3 +-- drivers/net/ethernet/tundra/tsi108_eth.c | 15 +++++--------- drivers/net/ethernet/xilinx/ll_temac_main.c | 6 ++---- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++---- drivers/net/fddi/defxx.c | 3 +-- drivers/net/irda/ali-ircc.c | 6 ++---- drivers/net/irda/nsc-ircc.c | 6 ++---- drivers/net/irda/pxaficp_ir.c | 4 ++-- drivers/net/irda/smsc-ircc2.c | 7 ++----- drivers/net/irda/via-ircc.c | 6 ++---- drivers/net/irda/w83977af_ir.c | 7 ++----- drivers/net/wireless/b43/dma.c | 9 ++------- drivers/net/wireless/b43legacy/dma.c | 3 +-- drivers/net/wireless/iwlegacy/4965-mac.c | 4 ++-- drivers/net/wireless/iwlegacy/common.c | 10 ++++------ drivers/net/wireless/iwlegacy/common.h | 5 ++--- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 +--- 38 files changed, 104 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 3a9fbacc3729..269295403fc4 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1466,25 +1466,21 @@ static int greth_of_probe(struct platform_device *ofdev) /* Allocate TX descriptor ring in coherent memory */ greth->tx_bd_base = dma_alloc_coherent(greth->dev, 1024, &greth->tx_bd_base_phys, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!greth->tx_bd_base) { err = -ENOMEM; goto error3; } - memset(greth->tx_bd_base, 0, 1024); - /* Allocate RX descriptor ring in coherent memory */ greth->rx_bd_base = dma_alloc_coherent(greth->dev, 1024, &greth->rx_bd_base_phys, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!greth->rx_bd_base) { err = -ENOMEM; goto error4; } - memset(greth->rx_bd_base, 0, 1024); - /* Get MAC address from: module param, OF property or ID prom */ for (i = 0; i < 6; i++) { if (macaddr[i] != 0) diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 79cf620ab449..0b3e23ec37f7 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -862,25 +862,25 @@ static int bcm_enet_open(struct net_device *dev) /* allocate rx dma ring */ size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); - p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL); + p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, + GFP_KERNEL | __GFP_ZERO); if (!p) { ret = -ENOMEM; goto out_freeirq_tx; } - memset(p, 0, size); priv->rx_desc_alloc_size = size; priv->rx_desc_cpu = p; /* allocate tx dma ring */ size = priv->tx_ring_size * sizeof(struct bcm_enet_desc); - p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL); + p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, + GFP_KERNEL | __GFP_ZERO); if (!p) { ret = -ENOMEM; goto out_free_rx_ring; } - memset(p, 0, size); priv->tx_desc_alloc_size = size; priv->tx_desc_cpu = p; diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 2f0ba8f2fd6c..e709296e3b85 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -854,12 +854,11 @@ bnx2_alloc_mem(struct bnx2 *bp) sizeof(struct statistics_block); status_blk = dma_alloc_coherent(&bp->pdev->dev, bp->status_stats_size, - &bp->status_blk_mapping, GFP_KERNEL); + &bp->status_blk_mapping, + GFP_KERNEL | __GFP_ZERO); if (status_blk == NULL) goto alloc_mem_err; - memset(status_blk, 0, bp->status_stats_size); - bnapi = &bp->bnx2_napi[0]; bnapi->status_blk.msi = status_blk; bnapi->hw_tx_cons_ptr = diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index f865ad5002f6..9e8d1955dfcf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1946,12 +1946,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, bool is_pf); -#define BNX2X_ILT_ZALLOC(x, y, size) \ - do { \ - x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ - if (x) \ - memset(x, 0, size); \ - } while (0) +#define BNX2X_ILT_ZALLOC(x, y, size) \ + x = dma_alloc_coherent(&bp->pdev->dev, size, y, \ + GFP_KERNEL | __GFP_ZERO) #define BNX2X_ILT_FREE(x, y, size) \ do { \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 4620fa5666e5..8f9637279f12 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -50,13 +50,13 @@ extern int int_mode; } \ } while (0) -#define BNX2X_PCI_ALLOC(x, y, size) \ - do { \ - x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ - if (x == NULL) \ - goto alloc_mem_err; \ - memset((void *)x, 0, size); \ - } while (0) +#define BNX2X_PCI_ALLOC(x, y, size) \ +do { \ + x = dma_alloc_coherent(&bp->pdev->dev, size, y, \ + GFP_KERNEL | __GFP_ZERO); \ + if (x == NULL) \ + goto alloc_mem_err; \ +} while (0) #define BNX2X_ALLOC(x, size) \ do { \ diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 0c1a2ef163a5..7794883f5973 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8172,11 +8172,9 @@ static int tg3_mem_rx_acquire(struct tg3 *tp) tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev, TG3_RX_RCB_RING_BYTES(tp), &tnapi->rx_rcb_mapping, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!tnapi->rx_rcb) goto err_out; - - memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); } return 0; @@ -8226,12 +8224,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), &tp->stats_mapping, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!tp->hw_stats) goto err_out; - memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); - for (i = 0; i < tp->irq_cnt; i++) { struct tg3_napi *tnapi = &tp->napi[i]; struct tg3_hw_status *sblk; @@ -8239,11 +8235,10 @@ static int tg3_alloc_consistent(struct tg3 *tp) tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE, &tnapi->status_mapping, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!tnapi->hw_status) goto err_out; - memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); sblk = tnapi->hw_status; if (tg3_flag(tp, ENABLE_RSS)) { diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 7cce42dc2f20..d588f842d557 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -1264,9 +1264,8 @@ bnad_mem_alloc(struct bnad *bnad, mem_info->mdl[i].len = mem_info->len; mem_info->mdl[i].kva = dma_alloc_coherent(&bnad->pcidev->dev, - mem_info->len, &dma_pa, - GFP_KERNEL); - + mem_info->len, &dma_pa, + GFP_KERNEL); if (mem_info->mdl[i].kva == NULL) goto err_return; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 2dfa205c5b99..536afa2fb94c 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -146,10 +146,9 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, q->entry_size = entry_size; mem->size = len * entry_size; mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!mem->va) return -ENOMEM; - memset(mem->va, 0, mem->size); return 0; } @@ -2569,10 +2568,9 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (cmd.va == NULL) return -1; - memset(cmd.va, 0, cmd.size); if (enable) { status = pci_write_config_dword(adapter->pdev, @@ -3794,12 +3792,13 @@ static int be_ctrl_init(struct be_adapter *adapter) rx_filter->size = sizeof(struct be_cmd_req_rx_filter); rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size, - &rx_filter->dma, GFP_KERNEL); + &rx_filter->dma, + GFP_KERNEL | __GFP_ZERO); if (rx_filter->va == NULL) { status = -ENOMEM; goto free_mbox; } - memset(rx_filter->va, 0, rx_filter->size); + mutex_init(&adapter->mbox_lock); spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); @@ -3841,10 +3840,9 @@ static int be_stats_init(struct be_adapter *adapter) cmd->size = sizeof(struct be_cmd_req_get_stats_v1); cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (cmd->va == NULL) return -1; - memset(cmd->va, 0, cmd->size); return 0; } diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 7c361d1db94c..0e817e6084e9 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -780,12 +780,11 @@ static int ftgmac100_alloc_buffers(struct ftgmac100 *priv) priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftgmac100_descs), - &priv->descs_dma_addr, GFP_KERNEL); + &priv->descs_dma_addr, + GFP_KERNEL | __GFP_ZERO); if (!priv->descs) return -ENOMEM; - memset(priv->descs, 0, sizeof(struct ftgmac100_descs)); - /* initialize RX ring */ ftgmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c index b5ea8fbd8a76..a6eda8d83138 100644 --- a/drivers/net/ethernet/faraday/ftmac100.c +++ b/drivers/net/ethernet/faraday/ftmac100.c @@ -732,13 +732,13 @@ static int ftmac100_alloc_buffers(struct ftmac100 *priv) { int i; - priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftmac100_descs), - &priv->descs_dma_addr, GFP_KERNEL); + priv->descs = dma_alloc_coherent(priv->dev, + sizeof(struct ftmac100_descs), + &priv->descs_dma_addr, + GFP_KERNEL | __GFP_ZERO); if (!priv->descs) return -ENOMEM; - memset(priv->descs, 0, sizeof(struct ftmac100_descs)); - /* initialize RX ring */ ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index cc2db5c04d9c..610ed223d1db 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -638,12 +638,11 @@ static int mal_probe(struct platform_device *ofdev) (NUM_TX_BUFF * mal->num_tx_chans + NUM_RX_BUFF * mal->num_rx_chans); mal->bd_virt = dma_alloc_coherent(&ofdev->dev, bd_size, &mal->bd_dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (mal->bd_virt == NULL) { err = -ENOMEM; goto fail_unmap; } - memset(mal->bd_virt, 0, bd_size); for (i = 0; i < mal->num_tx_chans; ++i) set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma + diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 43462d596a4e..a9f9c7906769 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1020,12 +1020,11 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) txdr->size = txdr->count * sizeof(struct e1000_tx_desc); txdr->size = ALIGN(txdr->size, 4096); txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!txdr->desc) { ret_val = 2; goto err_nomem; } - memset(txdr->desc, 0, txdr->size); txdr->next_to_use = txdr->next_to_clean = 0; ew32(TDBAL, ((u64)txdr->dma & 0x00000000FFFFFFFF)); @@ -1075,12 +1074,11 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!rxdr->desc) { ret_val = 5; goto err_nomem; } - memset(rxdr->desc, 0, rxdr->size); rxdr->next_to_use = rxdr->next_to_clean = 0; rctl = er32(RCTL); diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index d60cd4393415..bea46bb26061 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -447,7 +447,6 @@ int igbvf_setup_tx_resources(struct igbvf_adapter *adapter, tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, &tx_ring->dma, GFP_KERNEL); - if (!tx_ring->desc) goto err; @@ -488,7 +487,6 @@ int igbvf_setup_rx_resources(struct igbvf_adapter *adapter, rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); - if (!rx_ring->desc) goto err; diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index e23f0234cb27..74464c348454 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -717,12 +717,11 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) txdr->size = ALIGN(txdr->size, 4096); txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!txdr->desc) { vfree(txdr->buffer_info); return -ENOMEM; } - memset(txdr->desc, 0, txdr->size); txdr->next_to_use = 0; txdr->next_to_clean = 0; diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 3ae4c7f0834d..339bb323cb0c 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -584,12 +584,14 @@ static int init_hash_table(struct pxa168_eth_private *pep) */ if (pep->htpr == NULL) { pep->htpr = dma_alloc_coherent(pep->dev->dev.parent, - HASH_ADDR_TABLE_SIZE, - &pep->htpr_dma, GFP_KERNEL); + HASH_ADDR_TABLE_SIZE, + &pep->htpr_dma, + GFP_KERNEL | __GFP_ZERO); if (pep->htpr == NULL) return -ENOMEM; + } else { + memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); } - memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); wrl(pep, HTPR, pep->htpr_dma); return 0; } @@ -1023,11 +1025,11 @@ static int rxq_init(struct net_device *dev) size = pep->rx_ring_size * sizeof(struct rx_desc); pep->rx_desc_area_size = size; pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, - &pep->rx_desc_dma, GFP_KERNEL); + &pep->rx_desc_dma, + GFP_KERNEL | __GFP_ZERO); if (!pep->p_rx_desc_area) goto out; - memset((void *)pep->p_rx_desc_area, 0, size); /* initialize the next_desc_ptr links in the Rx descriptors ring */ p_rx_desc = pep->p_rx_desc_area; for (i = 0; i < rx_desc_num; i++) { @@ -1084,10 +1086,10 @@ static int txq_init(struct net_device *dev) size = pep->tx_ring_size * sizeof(struct tx_desc); pep->tx_desc_area_size = size; pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, - &pep->tx_desc_dma, GFP_KERNEL); + &pep->tx_desc_dma, + GFP_KERNEL | __GFP_ZERO); if (!pep->p_tx_desc_area) goto out; - memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); /* Initialize the next_desc_ptr links in the Tx descriptors ring */ p_tx_desc = pep->p_tx_desc_area; for (i = 0; i < tx_desc_num; i++) { diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 4f9937e026e5..d5ffdc8264eb 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3592,10 +3592,9 @@ static int myri10ge_alloc_slices(struct myri10ge_priv *mgp) bytes = mgp->max_intr_slots * sizeof(*ss->rx_done.entry); ss->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes, &ss->rx_done.bus, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (ss->rx_done.entry == NULL) goto abort; - memset(ss->rx_done.entry, 0, bytes); bytes = sizeof(*ss->fw_stats); ss->fw_stats = dma_alloc_coherent(&pdev->dev, bytes, &ss->fw_stats_bus, diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 4bdca9ec6a1a..abd5fba09b85 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1470,11 +1470,10 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter, size = rx_ring->count * bufsz + PCH_GBE_RESERVE_MEMORY; rx_ring->rx_buff_pool = dma_alloc_coherent(&pdev->dev, size, &rx_ring->rx_buff_pool_logic, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!rx_ring->rx_buff_pool) return -ENOMEM; - memset(rx_ring->rx_buff_pool, 0, size); rx_ring->rx_buff_pool_size = size; for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; @@ -1773,12 +1772,12 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, - &tx_ring->dma, GFP_KERNEL); + &tx_ring->dma, + GFP_KERNEL | __GFP_ZERO); if (!tx_ring->desc) { vfree(tx_ring->buffer_info); return -ENOMEM; } - memset(tx_ring->desc, 0, tx_ring->size); tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; @@ -1818,12 +1817,12 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, - &rx_ring->dma, GFP_KERNEL); + &rx_ring->dma, + GFP_KERNEL | __GFP_ZERO); if (!rx_ring->desc) { vfree(rx_ring->buffer_info); return -ENOMEM; } - memset(rx_ring->desc, 0, rx_ring->size); rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; for (desNo = 0; desNo < rx_ring->count; desNo++) { diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index b1cfbb75ff1e..a5f0b5da6149 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -441,12 +441,11 @@ static int pasemi_mac_setup_rx_resources(const struct net_device *dev) ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), - &ring->buf_dma, GFP_KERNEL); + &ring->buf_dma, + GFP_KERNEL | __GFP_ZERO); if (!ring->buffers) goto out_ring_desc; - memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64)); - write_dma_reg(PAS_DMA_RXCHAN_BASEL(chno), PAS_DMA_RXCHAN_BASEL_BRBL(ring->chan.ring_dma)); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index a0649ece8e0a..2d9c23fcec51 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -422,22 +422,20 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter, rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx); rq_addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size, - &rq_phys_addr, GFP_KERNEL); + &rq_phys_addr, GFP_KERNEL | __GFP_ZERO); if (!rq_addr) return -ENOMEM; rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx); rsp_addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size, - &rsp_phys_addr, GFP_KERNEL); + &rsp_phys_addr, GFP_KERNEL | __GFP_ZERO); if (!rsp_addr) { err = -ENOMEM; goto out_free_rq; } - memset(rq_addr, 0, rq_size); prq = rq_addr; - memset(rsp_addr, 0, rsp_size); prsp = rsp_addr; prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); @@ -744,10 +742,9 @@ int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter, size_t nic_size = sizeof(struct qlcnic_info_le); nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, - &nic_dma_t, GFP_KERNEL); + &nic_dma_t, GFP_KERNEL | __GFP_ZERO); if (!nic_info_addr) return -ENOMEM; - memset(nic_info_addr, 0, nic_size); nic_info = nic_info_addr; @@ -795,11 +792,10 @@ int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter, return err; nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, - &nic_dma_t, GFP_KERNEL); + &nic_dma_t, GFP_KERNEL | __GFP_ZERO); if (!nic_info_addr) return -ENOMEM; - memset(nic_info_addr, 0, nic_size); nic_info = nic_info_addr; nic_info->pci_func = cpu_to_le16(nic->pci_func); @@ -845,10 +841,10 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size, - &pci_info_dma_t, GFP_KERNEL); + &pci_info_dma_t, + GFP_KERNEL | __GFP_ZERO); if (!pci_info_addr) return -ENOMEM; - memset(pci_info_addr, 0, pci_size); npar = pci_info_addr; qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO); @@ -940,12 +936,10 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, } stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, - &stats_dma_t, GFP_KERNEL); + &stats_dma_t, GFP_KERNEL | __GFP_ZERO); if (!stats_addr) return -ENOMEM; - memset(stats_addr, 0, stats_size); - arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; arg1 |= rx_tx << 15 | stats_size << 16; @@ -993,11 +987,10 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, return -ENOMEM; stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, - &stats_dma_t, GFP_KERNEL); + &stats_dma_t, GFP_KERNEL | __GFP_ZERO); if (!stats_addr) return -ENOMEM; - memset(stats_addr, 0, stats_size); qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS); cmd.req.arg[1] = stats_size << 16; cmd.req.arg[2] = MSD(stats_dma_t); diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index f9f5df8b51fe..7b87798409cc 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -305,11 +305,11 @@ int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer, unsigned int len) { buffer->addr = dma_alloc_coherent(&efx->pci_dev->dev, len, - &buffer->dma_addr, GFP_ATOMIC); + &buffer->dma_addr, + GFP_ATOMIC | __GFP_ZERO); if (!buffer->addr) return -ENOMEM; buffer->len = len; - memset(buffer->addr, 0, len); return 0; } diff --git a/drivers/net/ethernet/sgi/meth.c b/drivers/net/ethernet/sgi/meth.c index 79ad9c94a21b..4bdbaad9932d 100644 --- a/drivers/net/ethernet/sgi/meth.c +++ b/drivers/net/ethernet/sgi/meth.c @@ -213,10 +213,11 @@ static int meth_init_tx_ring(struct meth_private *priv) { /* Init TX ring */ priv->tx_ring = dma_alloc_coherent(NULL, TX_RING_BUFFER_SIZE, - &priv->tx_ring_dma, GFP_ATOMIC); + &priv->tx_ring_dma, + GFP_ATOMIC | __GFP_ZERO); if (!priv->tx_ring) return -ENOMEM; - memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE); + priv->tx_count = priv->tx_read = priv->tx_write = 0; mace->eth.tx_ring_base = priv->tx_ring_dma; /* Now init skb save area */ diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c index f1b91fd7e41c..fef6b59e69c9 100644 --- a/drivers/net/ethernet/toshiba/spider_net.c +++ b/drivers/net/ethernet/toshiba/spider_net.c @@ -352,8 +352,7 @@ spider_net_init_chain(struct spider_net_card *card, alloc_size = chain->num_desc * sizeof(struct spider_net_hw_descr); chain->hwring = dma_alloc_coherent(&card->pdev->dev, alloc_size, - &chain->dma_addr, GFP_KERNEL); - + &chain->dma_addr, GFP_KERNEL); if (!chain->hwring) return -ENOMEM; diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 99fe3c6eea31..3c69a0460832 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1308,21 +1308,16 @@ static int tsi108_open(struct net_device *dev) data->id, dev->irq, dev->name); } - data->rxring = dma_alloc_coherent(NULL, rxring_size, - &data->rxdma, GFP_KERNEL); - if (!data->rxring) { + data->rxring = dma_alloc_coherent(NULL, rxring_size, &data->rxdma, + GFP_KERNEL | __GFP_ZERO); + if (!data->rxring) return -ENOMEM; - } else { - memset(data->rxring, 0, rxring_size); - } - data->txring = dma_alloc_coherent(NULL, txring_size, - &data->txdma, GFP_KERNEL); + data->txring = dma_alloc_coherent(NULL, txring_size, &data->txdma, + GFP_KERNEL | __GFP_ZERO); if (!data->txring) { pci_free_consistent(0, rxring_size, data->rxring, data->rxdma); return -ENOMEM; - } else { - memset(data->txring, 0, txring_size); } for (i = 0; i < TSI108_RXRING_LEN; i++) { diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index a64a6d74a5c8..4a7c60f4c83d 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -245,23 +245,21 @@ static int temac_dma_bd_init(struct net_device *ndev) /* returns a virtual address and a physical address. */ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->tx_bd_v) * TX_BD_NUM, - &lp->tx_bd_p, GFP_KERNEL); + &lp->tx_bd_p, GFP_KERNEL | __GFP_ZERO); if (!lp->tx_bd_v) goto out; lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->rx_bd_v) * RX_BD_NUM, - &lp->rx_bd_p, GFP_KERNEL); + &lp->rx_bd_p, GFP_KERNEL | __GFP_ZERO); if (!lp->rx_bd_v) goto out; - memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); for (i = 0; i < TX_BD_NUM; i++) { lp->tx_bd_v[i].next = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); } - memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); for (i = 0; i < RX_BD_NUM; i++) { lp->rx_bd_v[i].next = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index c238f980e28e..24748e8367a1 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -204,25 +204,23 @@ static int axienet_dma_bd_init(struct net_device *ndev) lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->tx_bd_v) * TX_BD_NUM, &lp->tx_bd_p, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!lp->tx_bd_v) goto out; lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->rx_bd_v) * RX_BD_NUM, &lp->rx_bd_p, - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!lp->rx_bd_v) goto out; - memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); for (i = 0; i < TX_BD_NUM; i++) { lp->tx_bd_v[i].next = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); } - memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); for (i = 0; i < RX_BD_NUM; i++) { lp->rx_bd_v[i].next = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index f116e51e3865..4c8ddc944d51 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -1070,11 +1070,10 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name, (PI_ALIGN_K_DESC_BLK - 1); bp->kmalloced = top_v = dma_alloc_coherent(bp->bus_dev, alloc_size, &bp->kmalloced_dma, - GFP_ATOMIC); + GFP_ATOMIC | __GFP_ZERO); if (top_v == NULL) return DFX_K_FAILURE; - memset(top_v, 0, alloc_size); /* zero out memory before continuing */ top_p = bp->kmalloced_dma; /* get physical address of buffer */ /* diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 9cea451a6081..3adb43ce138f 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -352,21 +352,19 @@ static int ali_ircc_open(int i, chipio_t *info) /* Allocate memory if needed */ self->rx_buff.head = dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + &self->rx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + &self->tx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 2a4f2f153244..9cf836b57c49 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -431,22 +431,20 @@ static int __init nsc_ircc_open(chipio_t *info) /* Allocate memory if needed */ self->rx_buff.head = dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + &self->rx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + &self->tx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 858de05bdb7d..964b116a0ab7 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -700,12 +700,12 @@ static int pxa_irda_start(struct net_device *dev) err = -ENOMEM; si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, - &si->dma_rx_buff_phy, GFP_KERNEL ); + &si->dma_rx_buff_phy, GFP_KERNEL); if (!si->dma_rx_buff) goto err_dma_rx_buff; si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, - &si->dma_tx_buff_phy, GFP_KERNEL ); + &si->dma_tx_buff_phy, GFP_KERNEL); if (!si->dma_tx_buff) goto err_dma_tx_buff; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 59b45c10adbc..aa05dad75335 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -563,19 +563,16 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, self->rx_buff.head = dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + &self->rx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->rx_buff.head == NULL) goto err_out2; self->tx_buff.head = dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + &self->tx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->tx_buff.head == NULL) goto err_out3; - memset(self->rx_buff.head, 0, self->rx_buff.truesize); - memset(self->tx_buff.head, 0, self->tx_buff.truesize); - self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; self->tx_buff.data = self->tx_buff.head; diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index f9033c6a888c..51f2bc376101 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -364,21 +364,19 @@ static int via_ircc_open(struct pci_dev *pdev, chipio_t *info, unsigned int id) /* Allocate memory if needed */ self->rx_buff.head = dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + &self->rx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + &self->tx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index f5bb92f15880..bb8857a158a6 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -216,22 +216,19 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, /* Allocate memory if needed */ self->rx_buff.head = dma_alloc_coherent(NULL, self->rx_buff.truesize, - &self->rx_buff_dma, GFP_KERNEL); + &self->rx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out1; } - memset(self->rx_buff.head, 0, self->rx_buff.truesize); - self->tx_buff.head = dma_alloc_coherent(NULL, self->tx_buff.truesize, - &self->tx_buff_dma, GFP_KERNEL); + &self->tx_buff_dma, GFP_KERNEL | __GFP_ZERO); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } - memset(self->tx_buff.head, 0, self->tx_buff.truesize); self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 38bc5a7997ff..f73cbb512f7c 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -419,8 +419,6 @@ static inline static int alloc_ringmemory(struct b43_dmaring *ring) { - gfp_t flags = GFP_KERNEL; - /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K * alignment and 8K buffers for 64-bit DMA with 8K alignment. * In practice we could use smaller buffers for the latter, but the @@ -435,12 +433,9 @@ static int alloc_ringmemory(struct b43_dmaring *ring) ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, ring_mem_size, &(ring->dmabase), - flags); - if (!ring->descbase) { - b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); + GFP_KERNEL | __GFP_ZERO); + if (!ring->descbase) return -ENOMEM; - } - memset(ring->descbase, 0, ring_mem_size); return 0; } diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 07d7e928eac7..faeafe219c57 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -334,10 +334,9 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, B43legacy_DMA_RINGMEMSIZE, &(ring->dmabase), - GFP_KERNEL); + GFP_KERNEL | __GFP_ZERO); if (!ring->descbase) return -ENOMEM; - memset(ring->descbase, 0, B43legacy_DMA_RINGMEMSIZE); return 0; } diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 7941eb3a0166..238f52874f16 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1921,8 +1921,8 @@ drop_unlock: static inline int il4965_alloc_dma_ptr(struct il_priv *il, struct il_dma_ptr *ptr, size_t size) { - ptr->addr = - dma_alloc_coherent(&il->pci_dev->dev, size, &ptr->dma, GFP_KERNEL); + ptr->addr = dma_alloc_coherent(&il->pci_dev->dev, size, &ptr->dma, + GFP_KERNEL); if (!ptr->addr) return -ENOMEM; ptr->size = size; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index bd4c18804709..db2187124032 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -2566,15 +2566,13 @@ il_rx_queue_alloc(struct il_priv *il) INIT_LIST_HEAD(&rxq->rx_used); /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = - dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, - GFP_KERNEL); + rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, + GFP_KERNEL); if (!rxq->bd) goto err_bd; - rxq->rb_stts = - dma_alloc_coherent(dev, sizeof(struct il_rb_status), - &rxq->rb_stts_dma, GFP_KERNEL); + rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct il_rb_status), + &rxq->rb_stts_dma, GFP_KERNEL); if (!rxq->rb_stts) goto err_rb; diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 96f2025d936e..458e699c63cd 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -2235,9 +2235,8 @@ il_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) return -EINVAL; } - desc->v_addr = - dma_alloc_coherent(&pci_dev->dev, desc->len, &desc->p_addr, - GFP_KERNEL); + desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, + &desc->p_addr, GFP_KERNEL); return (desc->v_addr != NULL) ? 0 : -ENOMEM; } diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index a0c8caef3b0a..696abed3e74b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -124,12 +124,10 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, */ addr = dma_alloc_coherent(rt2x00dev->dev, queue->limit * queue->desc_size, - &dma, GFP_KERNEL); + &dma, GFP_KERNEL | __GFP_ZERO); if (!addr) return -ENOMEM; - memset(addr, 0, queue->limit * queue->desc_size); - /* * Initialize all queue entries to contain valid addresses. */ -- cgit From 4e6bb70d7bb080714ae5f849c89f3fb37c1ed6db Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Wed, 13 Mar 2013 23:24:08 +0100 Subject: drm/gma500: Remove unused i8xx clock limits Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/psb_intel_display.c | 54 ++---------------------------- 1 file changed, 2 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 9edb1902a096..414df48e592b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -57,30 +57,6 @@ struct psb_intel_limit_t { struct psb_intel_p2_t p2; }; -#define I8XX_DOT_MIN 25000 -#define I8XX_DOT_MAX 350000 -#define I8XX_VCO_MIN 930000 -#define I8XX_VCO_MAX 1400000 -#define I8XX_N_MIN 3 -#define I8XX_N_MAX 16 -#define I8XX_M_MIN 96 -#define I8XX_M_MAX 140 -#define I8XX_M1_MIN 18 -#define I8XX_M1_MAX 26 -#define I8XX_M2_MIN 6 -#define I8XX_M2_MAX 16 -#define I8XX_P_MIN 4 -#define I8XX_P_MAX 128 -#define I8XX_P1_MIN 2 -#define I8XX_P1_MAX 33 -#define I8XX_P1_LVDS_MIN 1 -#define I8XX_P1_LVDS_MAX 6 -#define I8XX_P2_SLOW 4 -#define I8XX_P2_FAST 2 -#define I8XX_P2_LVDS_SLOW 14 -#define I8XX_P2_LVDS_FAST 14 /* No fast option */ -#define I8XX_P2_SLOW_LIMIT 165000 - #define I9XX_DOT_MIN 20000 #define I9XX_DOT_MAX 400000 #define I9XX_VCO_MIN 1400000 @@ -106,36 +82,10 @@ struct psb_intel_limit_t { #define I9XX_P2_LVDS_FAST 7 #define I9XX_P2_LVDS_SLOW_LIMIT 112000 -#define INTEL_LIMIT_I8XX_DVO_DAC 0 -#define INTEL_LIMIT_I8XX_LVDS 1 -#define INTEL_LIMIT_I9XX_SDVO_DAC 2 -#define INTEL_LIMIT_I9XX_LVDS 3 +#define INTEL_LIMIT_I9XX_SDVO_DAC 0 +#define INTEL_LIMIT_I9XX_LVDS 1 static const struct psb_intel_limit_t psb_intel_limits[] = { - { /* INTEL_LIMIT_I8XX_DVO_DAC */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST}, - }, - { /* INTEL_LIMIT_I8XX_LVDS */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST}, - }, { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, -- cgit From 1548060f48421f2faec75d431d447a090a30bf63 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Wed, 13 Mar 2013 23:32:36 +0100 Subject: drm/gma500: Calculate clock in one function instead of three identical i9xx_clock() and i8xx_clock() did the same calc and psb_intel_clock() just called i9xx_clock() so just move it all into psb_intel_clock(). The same calculation is duplicated in cdv_intel_display.c as well so maybe we can share it later on. Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/psb_intel_display.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 414df48e592b..b29be00832a7 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -127,19 +127,7 @@ static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc) return limit; } -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, struct psb_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; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock) +static void psb_intel_clock(int refclk, struct psb_intel_clock_t *clock) { clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); clock->p = clock->p1 * clock->p2; @@ -147,12 +135,6 @@ static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock) clock->dot = clock->vco / clock->p; } -static void psb_intel_clock(struct drm_device *dev, int refclk, - struct psb_intel_clock_t *clock) -{ - return i9xx_clock(refclk, clock); -} - /** * Returns whether any output on the specified pipe is of the specified type */ @@ -258,7 +240,7 @@ static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target, clock.p1++) { int this_err; - psb_intel_clock(dev, refclk, &clock); + psb_intel_clock(refclk, &clock); if (!psb_intel_PLL_is_valid (crtc, &clock)) @@ -1099,9 +1081,9 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev, if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) { /* XXX: might not be 66MHz */ - i8xx_clock(66000, &clock); + psb_intel_clock(66000, &clock); } else - i8xx_clock(48000, &clock); + psb_intel_clock(48000, &clock); } else { if (dpll & PLL_P1_DIVIDE_BY_TWO) clock.p1 = 2; @@ -1116,7 +1098,7 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev, else clock.p2 = 2; - i8xx_clock(48000, &clock); + psb_intel_clock(48000, &clock); } /* XXX: It would be nice to validate the clocks, but we can't reuse -- cgit From 06da4912ebfc3318f25d2401b137e17871fbebfa Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Thu, 14 Mar 2013 00:14:06 +0100 Subject: drm/gma500: Type clock limits directly into array and remove defines This makes it easier to read. We do the same for cdv so it becomes more consistent as well. Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/psb_intel_display.c | 66 +++++++++--------------------- 1 file changed, 20 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index b29be00832a7..28c2c2792445 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -57,62 +57,36 @@ struct psb_intel_limit_t { struct psb_intel_p2_t p2; }; -#define I9XX_DOT_MIN 20000 -#define I9XX_DOT_MAX 400000 -#define I9XX_VCO_MIN 1400000 -#define I9XX_VCO_MAX 2800000 -#define I9XX_N_MIN 1 -#define I9XX_N_MAX 6 -#define I9XX_M_MIN 70 -#define I9XX_M_MAX 120 -#define I9XX_M1_MIN 8 -#define I9XX_M1_MAX 18 -#define I9XX_M2_MIN 3 -#define I9XX_M2_MAX 7 -#define I9XX_P_SDVO_DAC_MIN 5 -#define I9XX_P_SDVO_DAC_MAX 80 -#define I9XX_P_LVDS_MIN 7 -#define I9XX_P_LVDS_MAX 98 -#define I9XX_P1_MIN 1 -#define I9XX_P1_MAX 8 -#define I9XX_P2_SDVO_DAC_SLOW 10 -#define I9XX_P2_SDVO_DAC_FAST 5 -#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 -#define I9XX_P2_LVDS_SLOW 14 -#define I9XX_P2_LVDS_FAST 7 -#define I9XX_P2_LVDS_SLOW_LIMIT 112000 - #define INTEL_LIMIT_I9XX_SDVO_DAC 0 #define INTEL_LIMIT_I9XX_LVDS 1 static const struct psb_intel_limit_t psb_intel_limits[] = { { /* INTEL_LIMIT_I9XX_SDVO_DAC */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, - .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = - I9XX_P2_SDVO_DAC_FAST}, + .dot = {.min = 20000, .max = 400000}, + .vco = {.min = 1400000, .max = 2800000}, + .n = {.min = 1, .max = 6}, + .m = {.min = 70, .max = 120}, + .m1 = {.min = 8, .max = 18}, + .m2 = {.min = 3, .max = 7}, + .p = {.min = 5, .max = 80}, + .p1 = {.min = 1, .max = 8}, + .p2 = {.dot_limit = 200000, + .p2_slow = 10, .p2_fast = 5}, }, { /* INTEL_LIMIT_I9XX_LVDS */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, + .dot = {.min = 20000, .max = 400000}, + .vco = {.min = 1400000, .max = 2800000}, + .n = {.min = 1, .max = 6}, + .m = {.min = 70, .max = 120}, + .m1 = {.min = 8, .max = 18}, + .m2 = {.min = 3, .max = 7}, + .p = {.min = 7, .max = 98}, + .p1 = {.min = 1, .max = 8}, /* The single-channel range is 25-112Mhz, and dual-channel * is 80-224Mhz. Prefer single channel as much as possible. */ - .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, + .p2 = {.dot_limit = 112000, + .p2_slow = 14, .p2_fast = 7}, }, }; -- cgit From 49ad8f54c02001d34856fb4cd00af02be75ab9be Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Thu, 14 Mar 2013 11:15:30 +0100 Subject: drm/gma500: Remove unnecessary function exposure psb_intel_crtc_gamma_set() and psb_intel_crtc_destroy() aren't used outside of psb_intel_display.c right now so no need to expose them. Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/psb_intel_display.c | 4 ++-- drivers/gpu/drm/gma500/psb_intel_display.h | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 28c2c2792445..ccc1c6bfd9b4 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -974,7 +974,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) return 0; } -void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, +static 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); @@ -1131,7 +1131,7 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, return mode; } -void psb_intel_crtc_destroy(struct drm_crtc *crtc) +static 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; diff --git a/drivers/gpu/drm/gma500/psb_intel_display.h b/drivers/gpu/drm/gma500/psb_intel_display.h index 535b49a5e409..3724b971e91c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.h +++ b/drivers/gpu/drm/gma500/psb_intel_display.h @@ -21,8 +21,5 @@ #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 -- cgit From 9e8e463609190562e69c83e59f50117a98e6e0be Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Thu, 14 Mar 2013 12:36:54 +0100 Subject: drm/gma500: Clean up various defines Remove unused defines that we'll never use and fix naming in some include guards Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/intel_bios.h | 6 +++--- drivers/gpu/drm/gma500/psb_intel_display.c | 2 -- drivers/gpu/drm/gma500/psb_intel_drv.h | 8 -------- drivers/gpu/drm/gma500/psb_intel_reg.h | 1 - drivers/gpu/drm/gma500/psb_irq.h | 6 +++--- 5 files changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h index c6267c98c9e7..978ae4b25e82 100644 --- a/drivers/gpu/drm/gma500/intel_bios.h +++ b/drivers/gpu/drm/gma500/intel_bios.h @@ -19,8 +19,8 @@ * */ -#ifndef _I830_BIOS_H_ -#define _I830_BIOS_H_ +#ifndef _INTEL_BIOS_H_ +#define _INTEL_BIOS_H_ #include #include @@ -618,4 +618,4 @@ extern void psb_intel_destroy_bios(struct drm_device *dev); #define PORT_IDPC 8 #define PORT_IDPD 9 -#endif /* _I830_BIOS_H_ */ +#endif /* _INTEL_BIOS_H_ */ diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index ccc1c6bfd9b4..6e8f42b61ff6 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -50,8 +50,6 @@ struct psb_intel_p2_t { int p2_slow, p2_fast; }; -#define INTEL_P2_NUM 2 - struct psb_intel_limit_t { struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; struct psb_intel_p2_t p2; diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index 90f2d11e686b..4dcae421a58d 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h @@ -32,9 +32,6 @@ /* maximum connectors per crtcs in the mode set */ #define INTELFB_CONN_LIMIT 4 -#define INTEL_I2C_BUS_DVO 1 -#define INTEL_I2C_BUS_SDVO 2 - /* Intel Pipe Clone Bit */ #define INTEL_HDMIB_CLONE_BIT 1 #define INTEL_HDMIC_CLONE_BIT 2 @@ -68,11 +65,6 @@ #define INTEL_OUTPUT_DISPLAYPORT 9 #define INTEL_OUTPUT_EDP 10 -#define INTEL_DVO_CHIP_NONE 0 -#define INTEL_DVO_CHIP_LVDS 1 -#define INTEL_DVO_CHIP_TMDS 2 -#define INTEL_DVO_CHIP_TVOUT 4 - #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h index d914719c4b60..0be30e4d146d 100644 --- a/drivers/gpu/drm/gma500/psb_intel_reg.h +++ b/drivers/gpu/drm/gma500/psb_intel_reg.h @@ -493,7 +493,6 @@ #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 diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h index 603045bee58a..debb7f190c06 100644 --- a/drivers/gpu/drm/gma500/psb_irq.h +++ b/drivers/gpu/drm/gma500/psb_irq.h @@ -21,8 +21,8 @@ * **************************************************************************/ -#ifndef _SYSIRQ_H_ -#define _SYSIRQ_H_ +#ifndef _PSB_IRQ_H_ +#define _PSB_IRQ_H_ #include @@ -44,4 +44,4 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); int mdfld_enable_te(struct drm_device *dev, int pipe); void mdfld_disable_te(struct drm_device *dev, int pipe); -#endif /* _SYSIRQ_H_ */ +#endif /* _PSB_IRQ_H_ */ -- cgit From debd0034de1f68585ab5d1d3d693d38f19d48e5d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Sat, 16 Mar 2013 06:57:51 +0000 Subject: sfc: make local functions static Trivial sparse detected functions that should be static. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/efx.c | 6 +++--- drivers/net/ethernet/sfc/rx.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 78c33249a21b..01b99206139a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -2950,8 +2950,8 @@ static const struct dev_pm_ops efx_pm_ops = { * At this point MMIO and DMA may be disabled. * Stop the software path and request a slot reset. */ -pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, - enum pci_channel_state state) +static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, + enum pci_channel_state state) { pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; struct efx_nic *efx = pci_get_drvdata(pdev); @@ -2986,7 +2986,7 @@ pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, } /* Fake a successfull reset, which will be performed later in efx_io_resume. */ -pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev) +static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev) { struct efx_nic *efx = pci_get_drvdata(pdev); pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index a948b36c1910..e73e30bac10e 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -666,8 +666,8 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) return rc; } -void efx_init_rx_recycle_ring(struct efx_nic *efx, - struct efx_rx_queue *rx_queue) +static void efx_init_rx_recycle_ring(struct efx_nic *efx, + struct efx_rx_queue *rx_queue) { unsigned int bufs_in_recycle_ring, page_ring_size; -- cgit From 94d8f2b133c9ff97105adc1233d1a35e16e1e7a6 Mon Sep 17 00:00:00 2001 From: Silviu-Mihai Popescu Date: Sat, 16 Mar 2013 21:03:46 +0000 Subject: drivers: net: irda: use resource_size() in au1k_ir.c This uses the resource_size() function instead of explicit computation. Signed-off-by: Silviu-Mihai Popescu Signed-off-by: David S. Miller --- drivers/net/irda/au1k_ir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index b5151e4ced61..56f1e6d6e4eb 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -882,12 +883,12 @@ static int au1k_irda_probe(struct platform_device *pdev) goto out; err = -EBUSY; - aup->ioarea = request_mem_region(r->start, r->end - r->start + 1, + aup->ioarea = request_mem_region(r->start, resource_size(r), pdev->name); if (!aup->ioarea) goto out; - aup->iobase = ioremap_nocache(r->start, r->end - r->start + 1); + aup->iobase = ioremap_nocache(r->start, resource_size(r)); if (!aup->iobase) goto out2; -- cgit From 1a2c6181c4a1922021b4d7df373bba612c3e5f04 Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Sun, 17 Mar 2013 08:23:34 +0000 Subject: tcp: Remove TCPCT TCPCT uses option-number 253, reserved for experimental use and should not be used in production environments. Further, TCPCT does not fully implement RFC 6013. As a nice side-effect, removing TCPCT increases TCP's performance for very short flows: Doing an apache-benchmark with -c 100 -n 100000, sending HTTP-requests for files of 1KB size. before this patch: average (among 7 runs) of 20845.5 Requests/Second after: average (among 7 runs) of 21403.6 Requests/Second Signed-off-by: Christoph Paasch Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 8 - drivers/infiniband/hw/cxgb4/cm.c | 2 +- include/linux/tcp.h | 10 -- include/net/request_sock.h | 8 +- include/net/tcp.h | 89 +---------- include/uapi/linux/tcp.h | 26 ---- net/dccp/ipv4.c | 5 +- net/dccp/ipv6.c | 5 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/syncookies.c | 3 +- net/ipv4/sysctl_net_ipv4.c | 7 - net/ipv4/tcp.c | 267 --------------------------------- net/ipv4/tcp_input.c | 69 +-------- net/ipv4/tcp_ipv4.c | 60 +------- net/ipv4/tcp_minisocks.c | 40 +---- net/ipv4/tcp_output.c | 219 +-------------------------- net/ipv6/syncookies.c | 3 +- net/ipv6/tcp_ipv6.c | 56 +------ 18 files changed, 38 insertions(+), 841 deletions(-) (limited to 'drivers') diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 18a24c405ac0..17953e2bc3e9 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -175,14 +175,6 @@ tcp_congestion_control - STRING is inherited. [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ] -tcp_cookie_size - INTEGER - Default size of TCP Cookie Transactions (TCPCT) option, that may be - overridden on a per socket basis by the TCPCT socket option. - Values greater than the maximum (16) are interpreted as the maximum. - Values greater than zero and less than the minimum (8) are interpreted - as the minimum. Odd values are interpreted as the next even value. - Default: 0 (off). - tcp_dsack - BOOLEAN Allows TCP to send "duplicate" SACKs. diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 8dcc84fd9d30..54fd31fcc332 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -2915,7 +2915,7 @@ static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos) */ memset(&tmp_opt, 0, sizeof(tmp_opt)); tcp_clear_options(&tmp_opt); - tcp_parse_options(skb, &tmp_opt, NULL, 0, NULL); + tcp_parse_options(skb, &tmp_opt, 0, NULL); req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 763c108ee03d..ed6a7456eecd 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -90,9 +90,6 @@ struct tcp_options_received { sack_ok : 4, /* SACK seen on SYN packet */ snd_wscale : 4, /* Window scaling received from sender */ rcv_wscale : 4; /* Window scaling to send to receiver */ - u8 cookie_plus:6, /* bytes in authenticator/cookie option */ - cookie_out_never:1, - cookie_in_always:1; u8 num_sacks; /* Number of SACK blocks */ u16 user_mss; /* mss requested by user in ioctl */ u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ @@ -102,7 +99,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) { rx_opt->tstamp_ok = rx_opt->sack_ok = 0; rx_opt->wscale_ok = rx_opt->snd_wscale = 0; - rx_opt->cookie_plus = 0; } /* This is the max number of SACKS that we'll generate and process. It's safe @@ -320,12 +316,6 @@ struct tcp_sock { struct tcp_md5sig_info __rcu *md5sig_info; #endif - /* When the cookie options are generated and exchanged, then this - * object holds a reference to them (cookie_values->kref). Also - * contains related tcp_cookie_transactions fields. - */ - struct tcp_cookie_values *cookie_values; - /* TCP fastopen related information */ struct tcp_fastopen_request *fastopen_req; /* fastopen_rsk points to request_sock that resulted in this big diff --git a/include/net/request_sock.h b/include/net/request_sock.h index a51dbd17c2de..9069e65c1c56 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -27,19 +27,13 @@ struct sk_buff; struct dst_entry; struct proto; -/* empty to "strongly type" an otherwise void parameter. - */ -struct request_values { -}; - struct request_sock_ops { int family; int obj_size; struct kmem_cache *slab; char *slab_name; int (*rtx_syn_ack)(struct sock *sk, - struct request_sock *req, - struct request_values *rvp); + struct request_sock *req); void (*send_ack)(struct sock *sk, struct sk_buff *skb, struct request_sock *req); void (*send_reset)(struct sock *sk, diff --git a/include/net/tcp.h b/include/net/tcp.h index ab9f947b118b..7f2f17198d75 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -179,7 +179,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ -#define TCPOPT_COOKIE 253 /* Cookie extension (experimental) */ #define TCPOPT_EXP 254 /* Experimental */ /* Magic number to be after the option value for sharing TCP * experimental options. See draft-ietf-tcpm-experimental-options-00.txt @@ -454,7 +453,7 @@ extern void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req); extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int flags, int *addr_len); extern void tcp_parse_options(const struct sk_buff *skb, - struct tcp_options_received *opt_rx, const u8 **hvpp, + struct tcp_options_received *opt_rx, int estab, struct tcp_fastopen_cookie *foc); extern const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); @@ -476,7 +475,6 @@ extern int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, extern int tcp_connect(struct sock *sk); extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct request_values *rvp, struct tcp_fastopen_cookie *foc); extern int tcp_disconnect(struct sock *sk, int flags); @@ -1589,91 +1587,6 @@ struct tcp_request_sock_ops { #endif }; -/* Using SHA1 for now, define some constants. - */ -#define COOKIE_DIGEST_WORDS (SHA_DIGEST_WORDS) -#define COOKIE_MESSAGE_WORDS (SHA_MESSAGE_BYTES / 4) -#define COOKIE_WORKSPACE_WORDS (COOKIE_DIGEST_WORDS + COOKIE_MESSAGE_WORDS) - -extern int tcp_cookie_generator(u32 *bakery); - -/** - * struct tcp_cookie_values - each socket needs extra space for the - * cookies, together with (optional) space for any SYN data. - * - * A tcp_sock contains a pointer to the current value, and this is - * cloned to the tcp_timewait_sock. - * - * @cookie_pair: variable data from the option exchange. - * - * @cookie_desired: user specified tcpct_cookie_desired. Zero - * indicates default (sysctl_tcp_cookie_size). - * After cookie sent, remembers size of cookie. - * Range 0, TCP_COOKIE_MIN to TCP_COOKIE_MAX. - * - * @s_data_desired: user specified tcpct_s_data_desired. When the - * constant payload is specified (@s_data_constant), - * holds its length instead. - * Range 0 to TCP_MSS_DESIRED. - * - * @s_data_payload: constant data that is to be included in the - * payload of SYN or SYNACK segments when the - * cookie option is present. - */ -struct tcp_cookie_values { - struct kref kref; - u8 cookie_pair[TCP_COOKIE_PAIR_SIZE]; - u8 cookie_pair_size; - u8 cookie_desired; - u16 s_data_desired:11, - s_data_constant:1, - s_data_in:1, - s_data_out:1, - s_data_unused:2; - u8 s_data_payload[0]; -}; - -static inline void tcp_cookie_values_release(struct kref *kref) -{ - kfree(container_of(kref, struct tcp_cookie_values, kref)); -} - -/* The length of constant payload data. Note that s_data_desired is - * overloaded, depending on s_data_constant: either the length of constant - * data (returned here) or the limit on variable data. - */ -static inline int tcp_s_data_size(const struct tcp_sock *tp) -{ - return (tp->cookie_values != NULL && tp->cookie_values->s_data_constant) - ? tp->cookie_values->s_data_desired - : 0; -} - -/** - * struct tcp_extend_values - tcp_ipv?.c to tcp_output.c workspace. - * - * As tcp_request_sock has already been extended in other places, the - * only remaining method is to pass stack values along as function - * parameters. These parameters are not needed after sending SYNACK. - * - * @cookie_bakery: cryptographic secret and message workspace. - * - * @cookie_plus: bytes in authenticator/cookie option, copied from - * struct tcp_options_received (above). - */ -struct tcp_extend_values { - struct request_values rv; - u32 cookie_bakery[COOKIE_WORKSPACE_WORDS]; - u8 cookie_plus:6, - cookie_out_never:1, - cookie_in_always:1; -}; - -static inline struct tcp_extend_values *tcp_xv(struct request_values *rvp) -{ - return (struct tcp_extend_values *)rvp; -} - extern void tcp_v4_init(void); extern void tcp_init(void); diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index 6b1ead0b0c9d..8d776ebc4829 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -102,7 +102,6 @@ enum { #define TCP_QUICKACK 12 /* Block/reenable quick acks */ #define TCP_CONGESTION 13 /* Congestion control algorithm */ #define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ -#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ #define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ #define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ #define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ @@ -199,29 +198,4 @@ struct tcp_md5sig { __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ }; -/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */ -#define TCP_COOKIE_MIN 8 /* 64-bits */ -#define TCP_COOKIE_MAX 16 /* 128-bits */ -#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX) - -/* Flags for both getsockopt and setsockopt */ -#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */ -#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies, - * supercedes everything. */ - -/* Flags for getsockopt */ -#define TCP_S_DATA_IN (1 << 2) /* Was data received? */ -#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */ - -/* TCP_COOKIE_TRANSACTIONS data */ -struct tcp_cookie_transactions { - __u16 tcpct_flags; /* see above */ - __u8 __tcpct_pad1; /* zero */ - __u8 tcpct_cookie_desired; /* bytes */ - __u16 tcpct_s_data_desired; /* bytes of variable data */ - __u16 tcpct_used; /* bytes in value */ - __u8 tcpct_value[TCP_MSS_DEFAULT]; -}; - - #endif /* _UAPI_LINUX_TCP_H */ diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 4f9f5eb478f1..ebc54fef85a5 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -500,8 +500,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, return &rt->dst; } -static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, - struct request_values *rv_unused) +static int dccp_v4_send_response(struct sock *sk, struct request_sock *req) { int err = -1; struct sk_buff *skb; @@ -658,7 +657,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) dreq->dreq_gss = dreq->dreq_iss; dreq->dreq_service = service; - if (dccp_v4_send_response(sk, req, NULL)) + if (dccp_v4_send_response(sk, req)) goto drop_and_free; inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6e05981f271e..9c61f9c02fdb 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -213,8 +213,7 @@ out: } -static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, - struct request_values *rv_unused) +static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) { struct inet6_request_sock *ireq6 = inet6_rsk(req); struct ipv6_pinfo *np = inet6_sk(sk); @@ -428,7 +427,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) dreq->dreq_gss = dreq->dreq_iss; dreq->dreq_service = service; - if (dccp_v6_send_response(sk, req, NULL)) + if (dccp_v6_send_response(sk, req)) goto drop_and_free; inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 786d97aee751..6acb541c9091 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -559,7 +559,7 @@ static inline void syn_ack_recalc(struct request_sock *req, const int thresh, int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req) { - int err = req->rsk_ops->rtx_syn_ack(parent, req, NULL); + int err = req->rsk_ops->rtx_syn_ack(parent, req); if (!err) req->num_retrans++; diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index ef54377fb11c..7f4a5cb8f8d0 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -267,7 +267,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt) { struct tcp_options_received tcp_opt; - const u8 *hash_location; struct inet_request_sock *ireq; struct tcp_request_sock *treq; struct tcp_sock *tp = tcp_sk(sk); @@ -294,7 +293,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, /* check for timestamp cookie support */ memset(&tcp_opt, 0, sizeof(tcp_opt)); - tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); + tcp_parse_options(skb, &tcp_opt, 0, NULL); if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) goto out; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index cca4550f4082..cb45062c8be0 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -732,13 +732,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, - { - .procname = "tcp_cookie_size", - .data = &sysctl_tcp_cookie_size, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, { .procname = "tcp_thin_linear_timeouts", .data = &sysctl_tcp_thin_linear_timeouts, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8d14573ade77..17a6810af5c8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -409,15 +409,6 @@ void tcp_init_sock(struct sock *sk) icsk->icsk_sync_mss = tcp_sync_mss; - /* TCP Cookie Transactions */ - if (sysctl_tcp_cookie_size > 0) { - /* Default, cookies without s_data_payload. */ - tp->cookie_values = - kzalloc(sizeof(*tp->cookie_values), - sk->sk_allocation); - if (tp->cookie_values != NULL) - kref_init(&tp->cookie_values->kref); - } /* Presumed zeroed, in order of appearance: * cookie_in_always, cookie_out_never, * s_data_constant, s_data_in, s_data_out @@ -2397,92 +2388,6 @@ static int do_tcp_setsockopt(struct sock *sk, int level, release_sock(sk); return err; } - case TCP_COOKIE_TRANSACTIONS: { - struct tcp_cookie_transactions ctd; - struct tcp_cookie_values *cvp = NULL; - - if (sizeof(ctd) > optlen) - return -EINVAL; - if (copy_from_user(&ctd, optval, sizeof(ctd))) - return -EFAULT; - - if (ctd.tcpct_used > sizeof(ctd.tcpct_value) || - ctd.tcpct_s_data_desired > TCP_MSS_DESIRED) - return -EINVAL; - - if (ctd.tcpct_cookie_desired == 0) { - /* default to global value */ - } else if ((0x1 & ctd.tcpct_cookie_desired) || - ctd.tcpct_cookie_desired > TCP_COOKIE_MAX || - ctd.tcpct_cookie_desired < TCP_COOKIE_MIN) { - return -EINVAL; - } - - if (TCP_COOKIE_OUT_NEVER & ctd.tcpct_flags) { - /* Supercedes all other values */ - lock_sock(sk); - if (tp->cookie_values != NULL) { - kref_put(&tp->cookie_values->kref, - tcp_cookie_values_release); - tp->cookie_values = NULL; - } - tp->rx_opt.cookie_in_always = 0; /* false */ - tp->rx_opt.cookie_out_never = 1; /* true */ - release_sock(sk); - return err; - } - - /* Allocate ancillary memory before locking. - */ - if (ctd.tcpct_used > 0 || - (tp->cookie_values == NULL && - (sysctl_tcp_cookie_size > 0 || - ctd.tcpct_cookie_desired > 0 || - ctd.tcpct_s_data_desired > 0))) { - cvp = kzalloc(sizeof(*cvp) + ctd.tcpct_used, - GFP_KERNEL); - if (cvp == NULL) - return -ENOMEM; - - kref_init(&cvp->kref); - } - lock_sock(sk); - tp->rx_opt.cookie_in_always = - (TCP_COOKIE_IN_ALWAYS & ctd.tcpct_flags); - tp->rx_opt.cookie_out_never = 0; /* false */ - - if (tp->cookie_values != NULL) { - if (cvp != NULL) { - /* Changed values are recorded by a changed - * pointer, ensuring the cookie will differ, - * without separately hashing each value later. - */ - kref_put(&tp->cookie_values->kref, - tcp_cookie_values_release); - } else { - cvp = tp->cookie_values; - } - } - - if (cvp != NULL) { - cvp->cookie_desired = ctd.tcpct_cookie_desired; - - if (ctd.tcpct_used > 0) { - memcpy(cvp->s_data_payload, ctd.tcpct_value, - ctd.tcpct_used); - cvp->s_data_desired = ctd.tcpct_used; - cvp->s_data_constant = 1; /* true */ - } else { - /* No constant payload data. */ - cvp->s_data_desired = ctd.tcpct_s_data_desired; - cvp->s_data_constant = 0; /* false */ - } - - tp->cookie_values = cvp; - } - release_sock(sk); - return err; - } default: /* fallthru */ break; @@ -2902,41 +2807,6 @@ static int do_tcp_getsockopt(struct sock *sk, int level, return -EFAULT; return 0; - case TCP_COOKIE_TRANSACTIONS: { - struct tcp_cookie_transactions ctd; - struct tcp_cookie_values *cvp = tp->cookie_values; - - if (get_user(len, optlen)) - return -EFAULT; - if (len < sizeof(ctd)) - return -EINVAL; - - memset(&ctd, 0, sizeof(ctd)); - ctd.tcpct_flags = (tp->rx_opt.cookie_in_always ? - TCP_COOKIE_IN_ALWAYS : 0) - | (tp->rx_opt.cookie_out_never ? - TCP_COOKIE_OUT_NEVER : 0); - - if (cvp != NULL) { - ctd.tcpct_flags |= (cvp->s_data_in ? - TCP_S_DATA_IN : 0) - | (cvp->s_data_out ? - TCP_S_DATA_OUT : 0); - - ctd.tcpct_cookie_desired = cvp->cookie_desired; - ctd.tcpct_s_data_desired = cvp->s_data_desired; - - memcpy(&ctd.tcpct_value[0], &cvp->cookie_pair[0], - cvp->cookie_pair_size); - ctd.tcpct_used = cvp->cookie_pair_size; - } - - if (put_user(sizeof(ctd), optlen)) - return -EFAULT; - if (copy_to_user(optval, &ctd, sizeof(ctd))) - return -EFAULT; - return 0; - } case TCP_THIN_LINEAR_TIMEOUTS: val = tp->thin_lto; break; @@ -3409,134 +3279,6 @@ EXPORT_SYMBOL(tcp_md5_hash_key); #endif -/* Each Responder maintains up to two secret values concurrently for - * efficient secret rollover. Each secret value has 4 states: - * - * Generating. (tcp_secret_generating != tcp_secret_primary) - * Generates new Responder-Cookies, but not yet used for primary - * verification. This is a short-term state, typically lasting only - * one round trip time (RTT). - * - * Primary. (tcp_secret_generating == tcp_secret_primary) - * Used both for generation and primary verification. - * - * Retiring. (tcp_secret_retiring != tcp_secret_secondary) - * Used for verification, until the first failure that can be - * verified by the newer Generating secret. At that time, this - * cookie's state is changed to Secondary, and the Generating - * cookie's state is changed to Primary. This is a short-term state, - * typically lasting only one round trip time (RTT). - * - * Secondary. (tcp_secret_retiring == tcp_secret_secondary) - * Used for secondary verification, after primary verification - * failures. This state lasts no more than twice the Maximum Segment - * Lifetime (2MSL). Then, the secret is discarded. - */ -struct tcp_cookie_secret { - /* The secret is divided into two parts. The digest part is the - * equivalent of previously hashing a secret and saving the state, - * and serves as an initialization vector (IV). The message part - * serves as the trailing secret. - */ - u32 secrets[COOKIE_WORKSPACE_WORDS]; - unsigned long expires; -}; - -#define TCP_SECRET_1MSL (HZ * TCP_PAWS_MSL) -#define TCP_SECRET_2MSL (HZ * TCP_PAWS_MSL * 2) -#define TCP_SECRET_LIFE (HZ * 600) - -static struct tcp_cookie_secret tcp_secret_one; -static struct tcp_cookie_secret tcp_secret_two; - -/* Essentially a circular list, without dynamic allocation. */ -static struct tcp_cookie_secret *tcp_secret_generating; -static struct tcp_cookie_secret *tcp_secret_primary; -static struct tcp_cookie_secret *tcp_secret_retiring; -static struct tcp_cookie_secret *tcp_secret_secondary; - -static DEFINE_SPINLOCK(tcp_secret_locker); - -/* Select a pseudo-random word in the cookie workspace. - */ -static inline u32 tcp_cookie_work(const u32 *ws, const int n) -{ - return ws[COOKIE_DIGEST_WORDS + ((COOKIE_MESSAGE_WORDS-1) & ws[n])]; -} - -/* Fill bakery[COOKIE_WORKSPACE_WORDS] with generator, updating as needed. - * Called in softirq context. - * Returns: 0 for success. - */ -int tcp_cookie_generator(u32 *bakery) -{ - unsigned long jiffy = jiffies; - - if (unlikely(time_after_eq(jiffy, tcp_secret_generating->expires))) { - spin_lock_bh(&tcp_secret_locker); - if (!time_after_eq(jiffy, tcp_secret_generating->expires)) { - /* refreshed by another */ - memcpy(bakery, - &tcp_secret_generating->secrets[0], - COOKIE_WORKSPACE_WORDS); - } else { - /* still needs refreshing */ - get_random_bytes(bakery, COOKIE_WORKSPACE_WORDS); - - /* The first time, paranoia assumes that the - * randomization function isn't as strong. But, - * this secret initialization is delayed until - * the last possible moment (packet arrival). - * Although that time is observable, it is - * unpredictably variable. Mash in the most - * volatile clock bits available, and expire the - * secret extra quickly. - */ - if (unlikely(tcp_secret_primary->expires == - tcp_secret_secondary->expires)) { - struct timespec tv; - - getnstimeofday(&tv); - bakery[COOKIE_DIGEST_WORDS+0] ^= - (u32)tv.tv_nsec; - - tcp_secret_secondary->expires = jiffy - + TCP_SECRET_1MSL - + (0x0f & tcp_cookie_work(bakery, 0)); - } else { - tcp_secret_secondary->expires = jiffy - + TCP_SECRET_LIFE - + (0xff & tcp_cookie_work(bakery, 1)); - tcp_secret_primary->expires = jiffy - + TCP_SECRET_2MSL - + (0x1f & tcp_cookie_work(bakery, 2)); - } - memcpy(&tcp_secret_secondary->secrets[0], - bakery, COOKIE_WORKSPACE_WORDS); - - rcu_assign_pointer(tcp_secret_generating, - tcp_secret_secondary); - rcu_assign_pointer(tcp_secret_retiring, - tcp_secret_primary); - /* - * Neither call_rcu() nor synchronize_rcu() needed. - * Retiring data is not freed. It is replaced after - * further (locked) pointer updates, and a quiet time - * (minimum 1MSL, maximum LIFE - 2MSL). - */ - } - spin_unlock_bh(&tcp_secret_locker); - } else { - rcu_read_lock_bh(); - memcpy(bakery, - &rcu_dereference(tcp_secret_generating)->secrets[0], - COOKIE_WORKSPACE_WORDS); - rcu_read_unlock_bh(); - } - return 0; -} -EXPORT_SYMBOL(tcp_cookie_generator); - void tcp_done(struct sock *sk) { struct request_sock *req = tcp_sk(sk)->fastopen_rsk; @@ -3591,7 +3333,6 @@ void __init tcp_init(void) unsigned long limit; int max_rshare, max_wshare, cnt; unsigned int i; - unsigned long jiffy = jiffies; BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); @@ -3667,13 +3408,5 @@ void __init tcp_init(void) tcp_register_congestion_control(&tcp_reno); - memset(&tcp_secret_one.secrets[0], 0, sizeof(tcp_secret_one.secrets)); - memset(&tcp_secret_two.secrets[0], 0, sizeof(tcp_secret_two.secrets)); - tcp_secret_one.expires = jiffy; /* past due */ - tcp_secret_two.expires = jiffy; /* past due */ - tcp_secret_generating = &tcp_secret_one; - tcp_secret_primary = &tcp_secret_one; - tcp_secret_retiring = &tcp_secret_two; - tcp_secret_secondary = &tcp_secret_two; tcp_tasklet_init(); } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 836d74dd0187..19f0149fb6a2 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3760,8 +3760,8 @@ old_ack: * But, this can also be called on packets in the established flow when * the fast version below fails. */ -void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *opt_rx, - const u8 **hvpp, int estab, +void tcp_parse_options(const struct sk_buff *skb, + struct tcp_options_received *opt_rx, int estab, struct tcp_fastopen_cookie *foc) { const unsigned char *ptr; @@ -3845,31 +3845,6 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o */ break; #endif - case TCPOPT_COOKIE: - /* This option is variable length. - */ - switch (opsize) { - case TCPOLEN_COOKIE_BASE: - /* not yet implemented */ - break; - case TCPOLEN_COOKIE_PAIR: - /* not yet implemented */ - break; - case TCPOLEN_COOKIE_MIN+0: - case TCPOLEN_COOKIE_MIN+2: - case TCPOLEN_COOKIE_MIN+4: - case TCPOLEN_COOKIE_MIN+6: - case TCPOLEN_COOKIE_MAX: - /* 16-bit multiple */ - opt_rx->cookie_plus = opsize; - *hvpp = ptr; - break; - default: - /* ignore option */ - break; - } - break; - case TCPOPT_EXP: /* Fast Open option shares code 254 using a * 16 bits magic number. It's valid only in @@ -3915,8 +3890,7 @@ static bool tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr * If it is wrong it falls back on tcp_parse_options(). */ static bool tcp_fast_parse_options(const struct sk_buff *skb, - const struct tcphdr *th, - struct tcp_sock *tp, const u8 **hvpp) + const struct tcphdr *th, struct tcp_sock *tp) { /* In the spirit of fast parsing, compare doff directly to constant * values. Because equality is used, short doff can be ignored here. @@ -3930,7 +3904,7 @@ static bool tcp_fast_parse_options(const struct sk_buff *skb, return true; } - tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL); + tcp_parse_options(skb, &tp->rx_opt, 1, NULL); if (tp->rx_opt.saw_tstamp) tp->rx_opt.rcv_tsecr -= tp->tsoffset; @@ -5311,12 +5285,10 @@ out: static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, int syn_inerr) { - const u8 *hash_location; struct tcp_sock *tp = tcp_sk(sk); /* RFC1323: H1. Apply PAWS check first. */ - if (tcp_fast_parse_options(skb, th, tp, &hash_location) && - tp->rx_opt.saw_tstamp && + if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && tcp_paws_discard(sk, skb)) { if (!th->rst) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); @@ -5670,12 +5642,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, if (mss == tp->rx_opt.user_mss) { struct tcp_options_received opt; - const u8 *hash_location; /* Get original SYNACK MSS value if user MSS sets mss_clamp */ tcp_clear_options(&opt); opt.user_mss = opt.mss_clamp = 0; - tcp_parse_options(synack, &opt, &hash_location, 0, NULL); + tcp_parse_options(synack, &opt, 0, NULL); mss = opt.mss_clamp; } @@ -5706,14 +5677,12 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len) { - const u8 *hash_location; struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); - struct tcp_cookie_values *cvp = tp->cookie_values; struct tcp_fastopen_cookie foc = { .len = -1 }; int saved_clamp = tp->rx_opt.mss_clamp; - tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, &foc); + tcp_parse_options(skb, &tp->rx_opt, 0, &foc); if (tp->rx_opt.saw_tstamp) tp->rx_opt.rcv_tsecr -= tp->tsoffset; @@ -5810,30 +5779,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, * is initialized. */ tp->copied_seq = tp->rcv_nxt; - if (cvp != NULL && - cvp->cookie_pair_size > 0 && - tp->rx_opt.cookie_plus > 0) { - int cookie_size = tp->rx_opt.cookie_plus - - TCPOLEN_COOKIE_BASE; - int cookie_pair_size = cookie_size - + cvp->cookie_desired; - - /* A cookie extension option was sent and returned. - * Note that each incoming SYNACK replaces the - * Responder cookie. The initial exchange is most - * fragile, as protection against spoofing relies - * entirely upon the sequence and timestamp (above). - * This replacement strategy allows the correct pair to - * pass through, while any others will be filtered via - * Responder verification later. - */ - if (sizeof(cvp->cookie_pair) >= cookie_pair_size) { - memcpy(&cvp->cookie_pair[cvp->cookie_desired], - hash_location, cookie_size); - cvp->cookie_pair_size = cookie_pair_size; - } - } - smp_mb(); tcp_finish_connect(sk, skb); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b7ab868c8284..b27c758ca23f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -838,7 +838,6 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, */ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct request_values *rvp, u16 queue_mapping, bool nocache) { @@ -851,7 +850,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) return -1; - skb = tcp_make_synack(sk, dst, req, rvp, NULL); + skb = tcp_make_synack(sk, dst, req, NULL); if (skb) { __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); @@ -868,10 +867,9 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, return err; } -static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, - struct request_values *rvp) +static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req) { - int res = tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); + int res = tcp_v4_send_synack(sk, NULL, req, 0, false); if (!res) TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); @@ -1371,8 +1369,7 @@ static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb, static int tcp_v4_conn_req_fastopen(struct sock *sk, struct sk_buff *skb, struct sk_buff *skb_synack, - struct request_sock *req, - struct request_values *rvp) + struct request_sock *req) { struct tcp_sock *tp = tcp_sk(sk); struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; @@ -1467,9 +1464,7 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { - struct tcp_extend_values tmp_ext; struct tcp_options_received tmp_opt; - const u8 *hash_location; struct request_sock *req; struct inet_request_sock *ireq; struct tcp_sock *tp = tcp_sk(sk); @@ -1519,42 +1514,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = TCP_MSS_DEFAULT; tmp_opt.user_mss = tp->rx_opt.user_mss; - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, - want_cookie ? NULL : &foc); - - if (tmp_opt.cookie_plus > 0 && - tmp_opt.saw_tstamp && - !tp->rx_opt.cookie_out_never && - (sysctl_tcp_cookie_size > 0 || - (tp->cookie_values != NULL && - tp->cookie_values->cookie_desired > 0))) { - u8 *c; - u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; - int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; - - if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) - goto drop_and_release; - - /* Secret recipe starts with IP addresses */ - *mess++ ^= (__force u32)daddr; - *mess++ ^= (__force u32)saddr; - - /* plus variable length Initiator Cookie */ - c = (u8 *)mess; - while (l-- > 0) - *c++ ^= *hash_location++; - - want_cookie = false; /* not our kind of cookie */ - tmp_ext.cookie_out_never = 0; /* false */ - tmp_ext.cookie_plus = tmp_opt.cookie_plus; - } else if (!tp->rx_opt.cookie_in_always) { - /* redundant indications, but ensure initialization. */ - tmp_ext.cookie_out_never = 1; /* true */ - tmp_ext.cookie_plus = 0; - } else { - goto drop_and_release; - } - tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; + tcp_parse_options(skb, &tmp_opt, 0, want_cookie ? NULL : &foc); if (want_cookie && !tmp_opt.saw_tstamp) tcp_clear_options(&tmp_opt); @@ -1636,7 +1596,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) * of tcp_v4_send_synack()->tcp_select_initial_window(). */ skb_synack = tcp_make_synack(sk, dst, req, - (struct request_values *)&tmp_ext, fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); if (skb_synack) { @@ -1660,8 +1619,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (fastopen_cookie_present(&foc) && foc.len != 0) NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL); - } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req, - (struct request_values *)&tmp_ext)) + } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req)) goto drop_and_free; return 0; @@ -2241,12 +2199,6 @@ void tcp_v4_destroy_sock(struct sock *sk) if (inet_csk(sk)->icsk_bind_hash) inet_put_port(sk); - /* TCP Cookie Transactions */ - if (tp->cookie_values != NULL) { - kref_put(&tp->cookie_values->kref, - tcp_cookie_values_release); - tp->cookie_values = NULL; - } BUG_ON(tp->fastopen_rsk != NULL); /* If socket is aborted during connect operation */ diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 4bdb09fca401..8f0234f8bb95 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -93,13 +93,12 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, const struct tcphdr *th) { struct tcp_options_received tmp_opt; - const u8 *hash_location; struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); bool paws_reject = false; tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); + tcp_parse_options(skb, &tmp_opt, 0, NULL); if (tmp_opt.saw_tstamp) { tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset; @@ -388,32 +387,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct tcp_request_sock *treq = tcp_rsk(req); struct inet_connection_sock *newicsk = inet_csk(newsk); struct tcp_sock *newtp = tcp_sk(newsk); - struct tcp_sock *oldtp = tcp_sk(sk); - struct tcp_cookie_values *oldcvp = oldtp->cookie_values; - - /* TCP Cookie Transactions require space for the cookie pair, - * as it differs for each connection. There is no need to - * copy any s_data_payload stored at the original socket. - * Failure will prevent resuming the connection. - * - * Presumed copied, in order of appearance: - * cookie_in_always, cookie_out_never - */ - if (oldcvp != NULL) { - struct tcp_cookie_values *newcvp = - kzalloc(sizeof(*newtp->cookie_values), - GFP_ATOMIC); - - if (newcvp != NULL) { - kref_init(&newcvp->kref); - newcvp->cookie_desired = - oldcvp->cookie_desired; - newtp->cookie_values = newcvp; - } else { - /* Not Yet Implemented */ - newtp->cookie_values = NULL; - } - } /* Now setup tcp_sock */ newtp->pred_flags = 0; @@ -422,8 +395,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, newtp->rcv_nxt = treq->rcv_isn + 1; newtp->snd_sml = newtp->snd_una = - newtp->snd_nxt = newtp->snd_up = - treq->snt_isn + 1 + tcp_s_data_size(oldtp); + newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1; tcp_prequeue_init(newtp); INIT_LIST_HEAD(&newtp->tsq_node); @@ -460,8 +432,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, tcp_set_ca_state(newsk, TCP_CA_Open); tcp_init_xmit_timers(newsk); skb_queue_head_init(&newtp->out_of_order_queue); - newtp->write_seq = newtp->pushed_seq = - treq->snt_isn + 1 + tcp_s_data_size(oldtp); + newtp->write_seq = newtp->pushed_seq = treq->snt_isn + 1; newtp->rx_opt.saw_tstamp = 0; @@ -538,7 +509,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, bool fastopen) { struct tcp_options_received tmp_opt; - const u8 *hash_location; struct sock *child; const struct tcphdr *th = tcp_hdr(skb); __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); @@ -548,7 +518,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(struct tcphdr)>>2)) { - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); + tcp_parse_options(skb, &tmp_opt, 0, NULL); if (tmp_opt.saw_tstamp) { tmp_opt.ts_recent = req->ts_recent; @@ -648,7 +618,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, */ if ((flg & TCP_FLAG_ACK) && !fastopen && (TCP_SKB_CB(skb)->ack_seq != - tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk)))) + tcp_rsk(req)->snt_isn + 1)) return sk; /* Also, it would be not so bad idea to check rcv_tsecr, which diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8e7742f0b5d2..ac5871ebe086 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -65,9 +65,6 @@ int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS; /* By default, RFC2861 behavior. */ int sysctl_tcp_slow_start_after_idle __read_mostly = 1; -int sysctl_tcp_cookie_size __read_mostly = 0; /* TCP_COOKIE_MAX */ -EXPORT_SYMBOL_GPL(sysctl_tcp_cookie_size); - static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, int push_one, gfp_t gfp); @@ -386,7 +383,6 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp) #define OPTION_TS (1 << 1) #define OPTION_MD5 (1 << 2) #define OPTION_WSCALE (1 << 3) -#define OPTION_COOKIE_EXTENSION (1 << 4) #define OPTION_FAST_OPEN_COOKIE (1 << 8) struct tcp_out_options { @@ -400,36 +396,6 @@ struct tcp_out_options { struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ }; -/* The sysctl int routines are generic, so check consistency here. - */ -static u8 tcp_cookie_size_check(u8 desired) -{ - int cookie_size; - - if (desired > 0) - /* previously specified */ - return desired; - - cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); - if (cookie_size <= 0) - /* no default specified */ - return 0; - - if (cookie_size <= TCP_COOKIE_MIN) - /* value too small, specify minimum */ - return TCP_COOKIE_MIN; - - if (cookie_size >= TCP_COOKIE_MAX) - /* value too large, specify maximum */ - return TCP_COOKIE_MAX; - - if (cookie_size & 1) - /* 8-bit multiple, illegal, fix it */ - cookie_size++; - - return (u8)cookie_size; -} - /* Write previously computed TCP options to the packet. * * Beware: Something in the Internet is very sensitive to the ordering of @@ -448,27 +414,9 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, { u16 options = opts->options; /* mungable copy */ - /* Having both authentication and cookies for security is redundant, - * and there's certainly not enough room. Instead, the cookie-less - * extension variant is proposed. - * - * Consider the pessimal case with authentication. The options - * could look like: - * COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40 - */ if (unlikely(OPTION_MD5 & options)) { - if (unlikely(OPTION_COOKIE_EXTENSION & options)) { - *ptr++ = htonl((TCPOPT_COOKIE << 24) | - (TCPOLEN_COOKIE_BASE << 16) | - (TCPOPT_MD5SIG << 8) | - TCPOLEN_MD5SIG); - } else { - *ptr++ = htonl((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_MD5SIG << 8) | - TCPOLEN_MD5SIG); - } - options &= ~OPTION_COOKIE_EXTENSION; + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); /* overload cookie hash location */ opts->hash_location = (__u8 *)ptr; ptr += 4; @@ -497,44 +445,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, *ptr++ = htonl(opts->tsecr); } - /* Specification requires after timestamp, so do it now. - * - * Consider the pessimal case without authentication. The options - * could look like: - * MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40 - */ - if (unlikely(OPTION_COOKIE_EXTENSION & options)) { - __u8 *cookie_copy = opts->hash_location; - u8 cookie_size = opts->hash_size; - - /* 8-bit multiple handled in tcp_cookie_size_check() above, - * and elsewhere. - */ - if (0x2 & cookie_size) { - __u8 *p = (__u8 *)ptr; - - /* 16-bit multiple */ - *p++ = TCPOPT_COOKIE; - *p++ = TCPOLEN_COOKIE_BASE + cookie_size; - *p++ = *cookie_copy++; - *p++ = *cookie_copy++; - ptr++; - cookie_size -= 2; - } else { - /* 32-bit multiple */ - *ptr++ = htonl(((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_COOKIE << 8) | - TCPOLEN_COOKIE_BASE) + - cookie_size); - } - - if (cookie_size > 0) { - memcpy(ptr, cookie_copy, cookie_size); - ptr += (cookie_size / 4); - } - } - if (unlikely(OPTION_SACK_ADVERTISE & options)) { *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | @@ -593,11 +503,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, struct tcp_md5sig_key **md5) { struct tcp_sock *tp = tcp_sk(sk); - struct tcp_cookie_values *cvp = tp->cookie_values; unsigned int remaining = MAX_TCP_OPTION_SPACE; - u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL) ? - tcp_cookie_size_check(cvp->cookie_desired) : - 0; struct tcp_fastopen_request *fastopen = tp->fastopen_req; #ifdef CONFIG_TCP_MD5SIG @@ -649,52 +555,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, tp->syn_fastopen = 1; } } - /* Note that timestamps are required by the specification. - * - * Odd numbers of bytes are prohibited by the specification, ensuring - * that the cookie is 16-bit aligned, and the resulting cookie pair is - * 32-bit aligned. - */ - if (*md5 == NULL && - (OPTION_TS & opts->options) && - cookie_size > 0) { - int need = TCPOLEN_COOKIE_BASE + cookie_size; - - if (0x2 & need) { - /* 32-bit multiple */ - need += 2; /* NOPs */ - - if (need > remaining) { - /* try shrinking cookie to fit */ - cookie_size -= 2; - need -= 4; - } - } - while (need > remaining && TCP_COOKIE_MIN <= cookie_size) { - cookie_size -= 4; - need -= 4; - } - if (TCP_COOKIE_MIN <= cookie_size) { - opts->options |= OPTION_COOKIE_EXTENSION; - opts->hash_location = (__u8 *)&cvp->cookie_pair[0]; - opts->hash_size = cookie_size; - - /* Remember for future incarnations. */ - cvp->cookie_desired = cookie_size; - - if (cvp->cookie_desired != cvp->cookie_pair_size) { - /* Currently use random bytes as a nonce, - * assuming these are completely unpredictable - * by hostile users of the same system. - */ - get_random_bytes(&cvp->cookie_pair[0], - cookie_size); - cvp->cookie_pair_size = cookie_size; - } - remaining -= need; - } - } return MAX_TCP_OPTION_SPACE - remaining; } @@ -704,14 +565,10 @@ static unsigned int tcp_synack_options(struct sock *sk, unsigned int mss, struct sk_buff *skb, struct tcp_out_options *opts, struct tcp_md5sig_key **md5, - struct tcp_extend_values *xvp, struct tcp_fastopen_cookie *foc) { struct inet_request_sock *ireq = inet_rsk(req); unsigned int remaining = MAX_TCP_OPTION_SPACE; - u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? - xvp->cookie_plus : - 0; #ifdef CONFIG_TCP_MD5SIG *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); @@ -759,28 +616,7 @@ static unsigned int tcp_synack_options(struct sock *sk, remaining -= need; } } - /* Similar rationale to tcp_syn_options() applies here, too. - * If the options fit, the same options should fit now! - */ - if (*md5 == NULL && - ireq->tstamp_ok && - cookie_plus > TCPOLEN_COOKIE_BASE) { - int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ - - if (0x2 & need) { - /* 32-bit multiple */ - need += 2; /* NOPs */ - } - if (need <= remaining) { - opts->options |= OPTION_COOKIE_EXTENSION; - opts->hash_size = cookie_plus - TCPOLEN_COOKIE_BASE; - remaining -= need; - } else { - /* There's no error return, so flag it. */ - xvp->cookie_out_never = 1; /* true */ - opts->hash_size = 0; - } - } + return MAX_TCP_OPTION_SPACE - remaining; } @@ -2802,32 +2638,24 @@ int tcp_send_synack(struct sock *sk) * sk: listener socket * dst: dst entry attached to the SYNACK * req: request_sock pointer - * rvp: request_values pointer * * Allocate one skb and build a SYNACK packet. * @dst is consumed : Caller should not use it again. */ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct request_values *rvp, struct tcp_fastopen_cookie *foc) { struct tcp_out_options opts; - struct tcp_extend_values *xvp = tcp_xv(rvp); struct inet_request_sock *ireq = inet_rsk(req); struct tcp_sock *tp = tcp_sk(sk); - const struct tcp_cookie_values *cvp = tp->cookie_values; struct tcphdr *th; struct sk_buff *skb; struct tcp_md5sig_key *md5; int tcp_header_size; int mss; - int s_data_desired = 0; - if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) - s_data_desired = cvp->s_data_desired; - skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired, - sk_gfp_atomic(sk, GFP_ATOMIC)); + skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC)); if (unlikely(!skb)) { dst_release(dst); return NULL; @@ -2869,9 +2697,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, else #endif TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_header_size = tcp_synack_options(sk, req, mss, - skb, &opts, &md5, xvp, foc) - + sizeof(*th); + tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, &md5, + foc) + sizeof(*th); skb_push(skb, tcp_header_size); skb_reset_transport_header(skb); @@ -2889,40 +2716,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn, TCPHDR_SYN | TCPHDR_ACK); - if (OPTION_COOKIE_EXTENSION & opts.options) { - if (s_data_desired) { - u8 *buf = skb_put(skb, s_data_desired); - - /* copy data directly from the listening socket. */ - memcpy(buf, cvp->s_data_payload, s_data_desired); - TCP_SKB_CB(skb)->end_seq += s_data_desired; - } - - if (opts.hash_size > 0) { - __u32 workspace[SHA_WORKSPACE_WORDS]; - u32 *mess = &xvp->cookie_bakery[COOKIE_DIGEST_WORDS]; - u32 *tail = &mess[COOKIE_MESSAGE_WORDS-1]; - - /* Secret recipe depends on the Timestamp, (future) - * Sequence and Acknowledgment Numbers, Initiator - * Cookie, and others handled by IP variant caller. - */ - *tail-- ^= opts.tsval; - *tail-- ^= tcp_rsk(req)->rcv_isn + 1; - *tail-- ^= TCP_SKB_CB(skb)->seq + 1; - - /* recommended */ - *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); - *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ - - sha_transform((__u32 *)&xvp->cookie_bakery[0], - (char *)mess, - &workspace[0]); - opts.hash_location = - (__u8 *)&xvp->cookie_bakery[0]; - } - } - th->seq = htonl(TCP_SKB_CB(skb)->seq); /* XXX data is queued and acked as is. No buffer/window check */ th->ack_seq = htonl(tcp_rsk(req)->rcv_nxt); diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 8a0848b60b35..d5dda20bd717 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -149,7 +149,6 @@ static inline int cookie_check(const struct sk_buff *skb, __u32 cookie) struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) { struct tcp_options_received tcp_opt; - const u8 *hash_location; struct inet_request_sock *ireq; struct inet6_request_sock *ireq6; struct tcp_request_sock *treq; @@ -177,7 +176,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) /* check for timestamp cookie support */ memset(&tcp_opt, 0, sizeof(tcp_opt)); - tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); + tcp_parse_options(skb, &tcp_opt, 0, NULL); if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) goto out; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9b6460055df5..0a97add2ab74 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -454,7 +454,6 @@ out: static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, struct flowi6 *fl6, struct request_sock *req, - struct request_values *rvp, u16 queue_mapping) { struct inet6_request_sock *treq = inet6_rsk(req); @@ -466,7 +465,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) goto done; - skb = tcp_make_synack(sk, dst, req, rvp, NULL); + skb = tcp_make_synack(sk, dst, req, NULL); if (skb) { __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); @@ -481,13 +480,12 @@ done: return err; } -static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, - struct request_values *rvp) +static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req) { struct flowi6 fl6; int res; - res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); + res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0); if (!res) TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); return res; @@ -940,9 +938,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) */ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) { - struct tcp_extend_values tmp_ext; struct tcp_options_received tmp_opt; - const u8 *hash_location; struct request_sock *req; struct inet6_request_sock *treq; struct ipv6_pinfo *np = inet6_sk(sk); @@ -980,50 +976,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); tmp_opt.user_mss = tp->rx_opt.user_mss; - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); - - if (tmp_opt.cookie_plus > 0 && - tmp_opt.saw_tstamp && - !tp->rx_opt.cookie_out_never && - (sysctl_tcp_cookie_size > 0 || - (tp->cookie_values != NULL && - tp->cookie_values->cookie_desired > 0))) { - u8 *c; - u32 *d; - u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; - int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; - - if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) - goto drop_and_free; - - /* Secret recipe starts with IP addresses */ - d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0]; - *mess++ ^= *d++; - *mess++ ^= *d++; - *mess++ ^= *d++; - *mess++ ^= *d++; - d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0]; - *mess++ ^= *d++; - *mess++ ^= *d++; - *mess++ ^= *d++; - *mess++ ^= *d++; - - /* plus variable length Initiator Cookie */ - c = (u8 *)mess; - while (l-- > 0) - *c++ ^= *hash_location++; - - want_cookie = false; /* not our kind of cookie */ - tmp_ext.cookie_out_never = 0; /* false */ - tmp_ext.cookie_plus = tmp_opt.cookie_plus; - } else if (!tp->rx_opt.cookie_in_always) { - /* redundant indications, but ensure initialization. */ - tmp_ext.cookie_out_never = 1; /* true */ - tmp_ext.cookie_plus = 0; - } else { - goto drop_and_free; - } - tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; + tcp_parse_options(skb, &tmp_opt, 0, NULL); if (want_cookie && !tmp_opt.saw_tstamp) tcp_clear_options(&tmp_opt); @@ -1101,7 +1054,6 @@ have_isn: goto drop_and_release; if (tcp_v6_send_synack(sk, dst, &fl6, req, - (struct request_values *)&tmp_ext, skb_get_queue_mapping(skb)) || want_cookie) goto drop_and_free; -- cgit From 8655cc490e83f66476de8c1294411860325c3531 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 19 Feb 2013 21:10:30 +0000 Subject: iio: Add broken out info_mask fields for shared_by_type and separate This simplifies the code, removes an extensive layer of 'helper' macros and gives us twice as much room to play with in these masks before we have any need to be clever. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/industrialio-core.c | 30 ++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 10 +++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 6d8b02785647..f05289f7b512 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -708,6 +708,36 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, goto error_ret; attrcount++; } + for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) { + ret = __iio_add_chan_devattr(iio_chan_info_postfix[i], + chan, + &iio_read_channel_info, + &iio_write_channel_info, + i, + 0, + &indio_dev->dev, + &indio_dev->channel_attr_list); + if (ret < 0) + goto error_ret; + attrcount++; + } + for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) { + ret = __iio_add_chan_devattr(iio_chan_info_postfix[i], + chan, + &iio_read_channel_info, + &iio_write_channel_info, + i, + 1, + &indio_dev->dev, + &indio_dev->channel_attr_list); + if (ret == -EBUSY) { + ret = 0; + continue; + } else if (ret < 0) { + goto error_ret; + } + attrcount++; + } if (chan->ext_info) { unsigned int i = 0; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index da8c776ba0bd..76976509d628 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -218,6 +218,10 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * endianness: little or big endian * @info_mask: What information is to be exported about this channel. * This includes calibbias, scale etc. + * @info_mask_separate: What information is to be exported that is specific to + * this channel. + * @info_mask_shared_by_type: What information is to be exported that is shared +* by all channels of the same type. * @event_mask: What events can this channel produce. * @ext_info: Array of extended info attributes for this channel. * The array is NULL terminated, the last element should @@ -253,6 +257,8 @@ struct iio_chan_spec { enum iio_endian endianness; } scan_type; long info_mask; + long info_mask_separate; + long info_mask_shared_by_type; long event_mask; const struct iio_chan_spec_ext_info *ext_info; const char *extend_name; @@ -275,7 +281,9 @@ struct iio_chan_spec { static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, enum iio_chan_info_enum type) { - return chan->info_mask & IIO_CHAN_INFO_BITS(type); + return (chan->info_mask & IIO_CHAN_INFO_BITS(type)) | + (chan->info_mask_separate & type) | + (chan->info_mask_shared_by_type & type); } #define IIO_ST(si, rb, sb, sh) \ -- cgit From f6e52e59c809c8d5f0fcdfe6f04fbce1013e2e50 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 19 Feb 2013 21:11:35 +0000 Subject: iio:adc:max1363 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron --- drivers/iio/adc/max1363.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 6c1cfb74bdfc..9e6da72ad823 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -427,15 +427,15 @@ static const enum max1363_modes max1363_mode_list[] = { #define MAX1363_EV_M \ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) -#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT) + #define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = num, \ .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .datasheet_name = "AIN"#num, \ .scan_type = { \ .sign = 'u', \ @@ -456,7 +456,8 @@ static const enum max1363_modes max1363_mode_list[] = { .channel = num, \ .channel2 = num2, \ .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .datasheet_name = "AIN"#num"-AIN"#num2, \ .scan_type = { \ .sign = 's', \ -- cgit From fa357a6a48420ff6dac6425b235830036ff3dc47 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 19 Feb 2013 21:12:21 +0000 Subject: staging:iio:dummy move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/iio_simple_dummy.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index aee76c710a3b..0193e1796b18 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -71,25 +71,25 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .indexed = 1, .channel = 0, /* What other information is available? */ - .info_mask = + .info_mask_separate = /* * in_voltage0_raw * Raw (unscaled no bias removal etc) measurement * from the device. */ - IIO_CHAN_INFO_RAW_SEPARATE_BIT | + BIT(IIO_CHAN_INFO_RAW) | /* * in_voltage0_offset * Offset for userspace to apply prior to scale * when converting to standard units (microvolts) */ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + BIT(IIO_CHAN_INFO_OFFSET) | /* * in_voltage0_scale * Multipler for userspace to apply post offset * when converting to standard units (microvolts) */ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + BIT(IIO_CHAN_INFO_SCALE), /* The ordering of elements in the buffer via an enum */ .scan_index = voltage0, .scan_type = { /* Description of storage in buffer */ @@ -118,19 +118,18 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .indexed = 1, .channel = 1, .channel2 = 2, - .info_mask = /* * in_voltage1-voltage2_raw * Raw (unscaled no bias removal etc) measurement * from the device. */ - IIO_CHAN_INFO_RAW_SEPARATE_BIT | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), /* * in_voltage-voltage_scale * Shared version of scale - shared by differential * input channels of type IIO_VOLTAGE. */ - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_index = diffvoltage1m2, .scan_type = { /* Description of storage in buffer */ .sign = 's', /* signed */ @@ -146,9 +145,8 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .indexed = 1, .channel = 3, .channel2 = 4, - .info_mask = - IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_index = diffvoltage3m4, .scan_type = { .sign = 's', @@ -166,15 +164,14 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .modified = 1, /* Channel 2 is use for modifiers */ .channel2 = IIO_MOD_X, - .info_mask = - IIO_CHAN_INFO_RAW_SEPARATE_BIT | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | /* * Internal bias correction value. Applied * by the hardware or driver prior to userspace * seeing the readings. Typically part of hardware * calibration. */ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + BIT(IIO_CHAN_INFO_CALIBBIAS), .scan_index = accelx, .scan_type = { /* Description of storage in buffer */ .sign = 's', /* signed */ @@ -191,7 +188,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = { /* DAC channel out_voltage0_raw */ { .type = IIO_VOLTAGE, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .output = 1, .indexed = 1, .channel = 0, @@ -204,8 +201,8 @@ static const struct iio_chan_spec iio_dummy_channels[] = { * @chan: the channel whose data is to be read * @val: first element of returned value (typically INT) * @val2: second element of returned value (typically MICRO) - * @mask: what we actually want to read. 0 is the channel, everything else - * is as per the info_mask in iio_chan_spec. + * @mask: what we actually want to read as per the info_mask_* + * in iio_chan_spec. */ static int iio_dummy_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -287,8 +284,8 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, * @chan: the channel whose data is to be written * @val: first element of value to set (typically INT) * @val2: second element of value to set (typically MICRO) - * @mask: what we actually want to write. 0 is the channel, everything else - * is as per the info_mask in iio_chan_spec. + * @mask: what we actually want to write as per the info_mask_* + * in iio_chan_spec. * * Note that all raw writes are assumed IIO_VAL_INT and info mask elements * are assumed to be IIO_INT_PLUS_MICRO unless the callback write_raw_get_fmt -- cgit From ecbe18f2c3428aa1412e1174196506e3655a7e82 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:03:04 +0000 Subject: iio:hid_sensors move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron --- drivers/iio/accel/hid-sensor-accel-3d.c | 24 ++++++++++++------------ drivers/iio/gyro/hid-sensor-gyro-3d.c | 24 ++++++++++++------------ drivers/iio/light/hid-sensor-als.c | 8 ++++---- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 24 ++++++++++++------------ 4 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index dd8ea4284934..bbcbd7101f33 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -60,28 +60,28 @@ static const struct iio_chan_spec accel_3d_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_X, }, { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Y, }, { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, } }; diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index fcfc83a9f861..bc943dd47da5 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -60,28 +60,28 @@ static const struct iio_chan_spec gyro_3d_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_X, }, { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Y, }, { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, } }; diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 3d7e8c9b4beb..80d68ff02d29 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -49,10 +49,10 @@ static const struct iio_chan_spec als_channels[] = { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_BOTH, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_ILLUM, } }; diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index d8d01265220b..99f4e494513b 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -60,28 +60,28 @@ static const struct iio_chan_spec magn_3d_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_X, }, { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Y, }, { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT | - IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, } }; -- cgit From 2f6bb53480b5cf02e39cd1ab0d1f3b97584550a2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:03:36 +0000 Subject: iio:accel:kxsd9 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxsd9.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c index c2229a521ab9..7229645bf1d7 100644 --- a/drivers/iio/accel/kxsd9.c +++ b/drivers/iio/accel/kxsd9.c @@ -177,8 +177,8 @@ error_ret: .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = KXSD9_REG_##axis, \ } @@ -186,7 +186,7 @@ static const struct iio_chan_spec kxsd9_channels[] = { KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z), { .type = IIO_VOLTAGE, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .indexed = 1, .address = KXSD9_REG_AUX, } -- cgit From 3234ac7e6a96046bd2c996ed93cf843057c3e627 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:04:03 +0000 Subject: iio:adc:ad7266 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/adc/ad7266.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index bbad9b94cd75..c2744a75c3b0 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -201,9 +201,9 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, .indexed = 1, \ .channel = (_chan), \ .address = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \ - | IIO_CHAN_INFO_SCALE_SHARED_BIT \ - | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET), \ .scan_index = (_chan), \ .scan_type = { \ .sign = (_sign), \ @@ -249,9 +249,9 @@ static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(s, 's'); .channel = (_chan) * 2, \ .channel2 = (_chan) * 2 + 1, \ .address = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT \ - | IIO_CHAN_INFO_SCALE_SHARED_BIT \ - | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_OFFSET), \ .scan_index = (_chan), \ .scan_type = { \ .sign = _sign, \ -- cgit From 40dd676d8f5254ababe31ea6bfe429458d98e8b6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:04:29 +0000 Subject: iio:adc:ad7298 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/adc/ad7298.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index b34d754994d5..03b77189dbfe 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -63,8 +63,8 @@ struct ad7298_state { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = index, \ .scan_index = index, \ .scan_type = { \ @@ -80,9 +80,9 @@ static const struct iio_chan_spec ad7298_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), .address = AD7298_CH_TEMP, .scan_index = -1, .scan_type = { -- cgit From 8c1033f733d85a3d5da82dea34ef6d989dd297f5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:05:34 +0000 Subject: iio:adc:ad7476 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/adc/ad7476.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 1491fa6debb2..2e98bef4af67 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -140,12 +140,12 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, return -EINVAL; } -#define _AD7476_CHAN(bits, _shift, _info_mask) \ +#define _AD7476_CHAN(bits, _shift, _info_mask_sep) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .info_mask = _info_mask | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = _info_mask_sep, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = { \ .sign = 'u', \ .realbits = (bits), \ @@ -156,9 +156,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, } #define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \ - IIO_CHAN_INFO_RAW_SEPARATE_BIT) + BIT(IIO_CHAN_INFO_RAW)) #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \ - IIO_CHAN_INFO_RAW_SEPARATE_BIT) + BIT(IIO_CHAN_INFO_RAW)) #define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0) static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { -- cgit From 16d186b1f9aebfc4baec419b89e61cf8e6ff5d40 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:05:59 +0000 Subject: iio:adc:ad7887 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/adc/ad7887.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index a33d5cd1a536..dd15a5b0f701 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -207,8 +207,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = 1, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), @@ -217,8 +217,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = 0, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), -- cgit From 01bdab667e3e4cfd72d664e223fcc964bb3564f9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:06:10 +0000 Subject: iio:adc:at91_adc move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Maxime Ripard --- drivers/iio/adc/at91_adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 83c836ba600f..92eb6a5b9e72 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -140,8 +140,8 @@ static int at91_adc_channel_init(struct iio_dev *idev) chan->scan_type.sign = 'u'; chan->scan_type.realbits = 10; chan->scan_type.storagebits = 16; - chan->info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_RAW_SEPARATE_BIT; + chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); idx++; } timestamp = chan_array + idx; -- cgit From fb45a1b344884846e543a964fa5f96ba5777967f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:06:24 +0000 Subject: iio:adc:lp8778_adc move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Milo(Woogyom) Kim --- drivers/iio/adc/lp8788_adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c index 763f57565ee4..62bc39e9c94f 100644 --- a/drivers/iio/adc/lp8788_adc.c +++ b/drivers/iio/adc/lp8788_adc.c @@ -132,8 +132,8 @@ static const struct iio_info lp8788_adc_info = { .type = _type, \ .indexed = 1, \ .channel = LPADC_##_id, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .datasheet_name = #_id, \ } -- cgit From c8fe38a7dda0ff73ec5f9453fcefdd6ab84fcf71 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:06:39 +0000 Subject: iio:adc:ti-adc081 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Thierry Reding --- drivers/iio/adc/ti-adc081c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index f4a46dd8f43b..2826faae706c 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -55,8 +55,8 @@ static int adc081c_read_raw(struct iio_dev *iio, static const struct iio_chan_spec adc081c_channel = { .type = IIO_VOLTAGE, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }; static const struct iio_info adc081c_info = { -- cgit From 6c572522030e15a4c9eadea3f86cf33a7fa335a2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:07:18 +0000 Subject: iio:adc:ti_am335x_adc move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Patil, Rachna --- drivers/iio/adc/ti_am335x_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index cd030e100c39..5f9a7e7d3135 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -89,7 +89,7 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) chan->type = IIO_VOLTAGE; chan->indexed = 1; chan->channel = i; - chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT; + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); } indio_dev->channels = chan_array; -- cgit From 9123972218112b6739686f4a1e7ba94af9a1879d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:07:39 +0000 Subject: iio:adc:viperboard_adc move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Lars Poeschel --- drivers/iio/adc/viperboard_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index ad0261533dee..56ac481c73c0 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -41,7 +41,7 @@ struct vprbrd_adc { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = _index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .scan_index = _index, \ .scan_type = { \ .sign = 'u', \ -- cgit From b34ec6f34797a91eb87a016ecdff1a52a566b711 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:08:08 +0000 Subject: iio:amplifiers:ad8366 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/iio/amplifiers/ad8366.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index d6c0af23a2a7..d354554b51b3 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -125,7 +125,7 @@ static const struct iio_info ad8366_info = { .output = 1, \ .indexed = 1, \ .channel = _channel, \ - .info_mask = IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT,\ + .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN),\ } static const struct iio_chan_spec ad8366_channels[] = { -- cgit From 20a0eddd58c7a3edf2861e53de62eef1b6682e30 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:08:37 +0000 Subject: iio:dac:ad5064 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5064.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 2fe1d4edcb2f..cbbfef5dd79e 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -297,8 +297,8 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = (chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = AD5064_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ .ext_info = ad5064_ext_info, \ -- cgit From 1727a301edcece0661b8c18b174b1998264aad36 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:08:52 +0000 Subject: iio:dac:ad5360 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5360.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 92771217f665..80923af424f2 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -102,11 +102,11 @@ enum ad5360_type { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ .scan_type = IIO_ST('u', (bits), 16, 16 - (bits)) \ } -- cgit From c69e1397654b223801248989441b66ea284416e6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:09:55 +0000 Subject: iio:dac:ad5380 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5380.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 483fc379a2da..bf2db02215c2 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -257,10 +257,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)), \ .ext_info = ad5380_ext_info, \ } -- cgit From 31311c2a471c5c051391b0ee33fa03723ddd5f76 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:10:22 +0000 Subject: iio:dac:ad5421 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5421.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 6b86a638dad0..98f24407c3ce 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -86,11 +86,11 @@ static const struct iio_chan_spec ad5421_channels[] = { .indexed = 1, .output = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), .scan_type = IIO_ST('u', 16, 16, 0), .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), -- cgit From 2f6a4a44217f2dde7c7976c23eef377e90bfb9c7 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:10:35 +0000 Subject: iio:dac:ad5446 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5446.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index f5583aedfb59..cae8f6056ac3 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -143,8 +143,8 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { .indexed = 1, \ .output = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = IIO_ST('u', (bits), (storage), (shift)), \ .ext_info = (ext), \ } -- cgit From f8c627138ba621ae5bdf4ec9c21a63deff3581cc Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:10:50 +0000 Subject: iio:dac:ad5449 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5449.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index c4731b7b577b..ba1c914b0399 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -206,8 +206,8 @@ static const struct iio_info ad5449_info = { .indexed = 1, \ .output = 1, \ .channel = (chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = (chan), \ .scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \ } -- cgit From f3ec5a2dd40c7e3697f3e3d64720e00d8f5cd7bf Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:11:04 +0000 Subject: iio:dac:ad5504 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5504.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index e5e59749f109..139206e84cb7 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -259,8 +259,8 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = AD5504_ADDR_DAC(_chan), \ .scan_type = IIO_ST('u', 12, 16, 0), \ .ext_info = ad5504_ext_info, \ -- cgit From 8b68634861906abff79170fa9f6ae45dd3e760dc Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:11:22 +0000 Subject: iio:dac:ad5624r move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5624r_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index f6e116627b71..bb298aaff321 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -174,8 +174,8 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (_chan), \ .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ .ext_info = ad5624r_ext_info, \ -- cgit From d87a1d78ad1fad5f1e0134fb3ae1ea2bef4911fc Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:27:41 +0000 Subject: iio:dac:ad5686 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5686.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 5e554af21703..06439b1af9b6 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -276,9 +276,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = AD5686_ADDR_DAC(chan), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ + .address = AD5686_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', bits, 16, shift), \ .ext_info = ad5686_ext_info, \ } -- cgit From 8ac1f3df0ebbbc4f123bf01ef1007d826a938a18 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:27:50 +0000 Subject: iio:dac:ad5755 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5755.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 71faabc6b14e..12bb315e55f8 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -393,11 +393,11 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { #define AD5755_CHANNEL(_bits) { \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ .ext_info = ad5755_ext_info, \ } -- cgit From f4d9df19938a570630d6c0534dd63c62118c3bdd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:28:00 +0000 Subject: iio:dac:ad5764 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5764.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index 5b7acd3a2c77..7a53f7d70dac 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -78,11 +78,11 @@ enum ad5764_type { .output = 1, \ .channel = (_chan), \ .address = (_chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET), \ .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)) \ } -- cgit From 7611294799af395c40ffc6fe2f2b003b2b95b3ec Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:28:12 +0000 Subject: iio:dac:ad5791 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/dac/ad5791.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 8dfd3da8a07b..97c1e5d780df 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -302,9 +302,9 @@ static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { .indexed = 1, \ .address = AD5791_ADDR_DAC0, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ .scan_type = IIO_ST('u', bits, 24, shift), \ .ext_info = ad5791_ext_info, \ } -- cgit From 040b837e718408436b79c2aaf68ed86b09682af4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:28:22 +0000 Subject: iio:dac:max517 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Roland Stigge --- drivers/iio/dac/max517.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 352abe2004a4..ebfaa4156246 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -146,8 +146,8 @@ static const struct iio_info max517_info = { .indexed = 1, \ .output = 1, \ .channel = (chan), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .scan_type = IIO_ST('u', 8, 8, 0), \ } -- cgit From 90b46374009371ed1c8d5b8817a64de76aa6dc17 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:28:38 +0000 Subject: iio:dac:mcp4725 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Peter Meerwald --- drivers/iio/dac/mcp4725.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 8f88cc4059a2..a612ec766d96 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -69,8 +69,8 @@ static const struct iio_chan_spec mcp4725_channel = { .indexed = 1, .output = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .scan_type = IIO_ST('u', 12, 16, 0), }; -- cgit From beacbaac9909d1b68887c01017d52bd14574d050 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:28:57 +0000 Subject: iio:freq:ad9523 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/frequency/ad9523.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 1ea132e239ea..92276deeb026 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -920,10 +920,10 @@ static int ad9523_setup(struct iio_dev *indio_dev) st->ad9523_channels[i].channel = chan->channel_num; st->ad9523_channels[i].extend_name = chan->extended_name; - st->ad9523_channels[i].info_mask = - IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_PHASE_SEPARATE_BIT | - IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT; + st->ad9523_channels[i].info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PHASE) | + BIT(IIO_CHAN_INFO_FREQUENCY); } } -- cgit From 89352e9638109f91ab6fc4be3a98f0c8d9789826 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:29:24 +0000 Subject: iio:gyro:adis16080 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/gyro/adis16080.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index 1861287911f1..e1bb5f994a54 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -136,32 +136,32 @@ static const struct iio_chan_spec adis16080_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .address = ADIS16080_DIN_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), .address = ADIS16080_DIN_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), .address = ADIS16080_DIN_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), .address = ADIS16080_DIN_TEMP, } }; -- cgit From 606f9067b573183035a0300c4595261ec9575c7d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:29:52 +0000 Subject: iio:gyro:adis16136 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/gyro/adis16136.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 8cb0bcbfd609..058e6d5c955f 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -357,10 +357,11 @@ static const struct iio_chan_spec adis16136_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .address = ADIS16136_REG_GYRO_OUT2, .scan_index = ADIS16136_SCAN_GYRO, .scan_type = { @@ -373,8 +374,8 @@ static const struct iio_chan_spec adis16136_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .address = ADIS16136_REG_TEMP_OUT, .scan_index = ADIS16136_SCAN_TEMP, .scan_type = { -- cgit From 98bfb6e3727bd11089ca4c126248a4481bbe07c2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:30:18 +0000 Subject: iio:gyro:adxrs450 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/gyro/adxrs450.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index 5b79953f7011..8bd72b490b7f 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -383,16 +383,16 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), } }, [ID_ADXRS453] = { @@ -400,15 +400,15 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW), }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), } }, }; -- cgit From e1865aa17049f168bf566d6648be851d40588a87 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:30:36 +0000 Subject: iio:gyro:itg3200_core move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Manuel Stahl --- drivers/iio/gyro/itg3200_core.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index df2e6aa5d73b..d66605d2629d 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -248,12 +248,6 @@ err_ret: return ret; } -#define ITG3200_TEMP_INFO_MASK (IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_RAW_SEPARATE_BIT) -#define ITG3200_GYRO_INFO_MASK (IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_RAW_SEPARATE_BIT) - #define ITG3200_ST \ { .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE } @@ -261,7 +255,8 @@ err_ret: .type = IIO_ANGL_VEL, \ .modified = 1, \ .channel2 = IIO_MOD_ ## _mod, \ - .info_mask = ITG3200_GYRO_INFO_MASK, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \ .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \ .scan_type = ITG3200_ST, \ @@ -271,7 +266,9 @@ static const struct iio_chan_spec itg3200_channels[] = { { .type = IIO_TEMP, .channel2 = IIO_NO_MOD, - .info_mask = ITG3200_TEMP_INFO_MASK, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), .address = ITG3200_REG_TEMP_OUT_H, .scan_index = ITG3200_SCAN_TEMP, .scan_type = ITG3200_ST, -- cgit From 19a7c88d99c94e232e8dacb585ca359f0f0d94b6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:31:17 +0000 Subject: iio:imu:adis16400 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/imu/adis16400_core.c | 49 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index b7f215eab5de..f60591f0b925 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -484,8 +484,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .indexed = 1, \ .channel = 0, \ .extend_name = name, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -507,10 +507,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .type = IIO_ANGL_VEL, \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .address = addr, \ .scan_index = ADIS16400_SCAN_GYRO_ ## mod, \ .scan_type = { \ @@ -526,10 +526,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .address = (addr), \ .scan_index = ADIS16400_SCAN_ACC_ ## mod, \ .scan_type = { \ @@ -545,9 +545,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .address = (addr), \ .scan_index = ADIS16400_SCAN_MAGN_ ## mod, \ .scan_type = { \ @@ -568,10 +568,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .indexed = 1, \ .channel = 0, \ .extend_name = ADIS16400_MOD_TEMP_NAME_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .address = (addr), \ .scan_index = ADIS16350_SCAN_TEMP_ ## mod, \ .scan_type = { \ @@ -587,9 +588,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .type = IIO_TEMP, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = ADIS16350_SCAN_TEMP_X, \ .scan_type = { \ @@ -605,8 +606,8 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, .type = IIO_INCLI, \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = ADIS16300_SCAN_INCLI_ ## mod, \ .scan_type = { \ @@ -646,8 +647,8 @@ static const struct iio_chan_spec adis16448_channels[] = { ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 16), { .type = IIO_PRESSURE, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = ADIS16448_BARO_OUT, .scan_index = ADIS16400_SCAN_BARO, .scan_type = IIO_ST('s', 16, 16, 0), -- cgit From 86b64c9da23e8bd08e303094db12042b293a9ca5 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:31:52 +0000 Subject: iio:imu:adis16480 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/imu/adis16480.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 8c26a5f7cd5d..b7db38376295 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -591,15 +591,15 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, } } -#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info, _bits) \ +#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info_sep, _bits) \ { \ .type = (_type), \ .modified = 1, \ .channel2 = (_mod), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - _info, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS) | \ + _info_sep, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (_address), \ .scan_index = (_si), \ .scan_type = { \ @@ -613,21 +613,21 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, #define ADIS16480_GYRO_CHANNEL(_mod) \ ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \ ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE), \ 32) #define ADIS16480_ACCEL_CHANNEL(_mod) \ ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \ ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE), \ 32) #define ADIS16480_MAGN_CHANNEL(_mod) \ ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \ ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 16) #define ADIS16480_PRESSURE_CHANNEL() \ @@ -635,9 +635,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, .type = IIO_PRESSURE, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = ADIS16480_REG_BAROM_OUT, \ .scan_index = ADIS16480_SCAN_BARO, \ .scan_type = { \ @@ -652,9 +652,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, .type = IIO_TEMP, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ .address = ADIS16480_REG_TEMP_OUT, \ .scan_index = ADIS16480_SCAN_TEMP, \ .scan_type = { \ -- cgit From 0b1f8da3ac885f16209b238239cd6158c4fa273e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:32:17 +0000 Subject: iio:imu:mpu6050 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Ge Gao --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 37ca05b47e4b..fe4c61e219f3 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -544,8 +544,8 @@ static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev, .type = _type, \ .modified = 1, \ .channel2 = _channel2, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT \ - | IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .scan_index = _index, \ .scan_type = { \ .sign = 's', \ @@ -564,9 +564,9 @@ static const struct iio_chan_spec inv_mpu_channels[] = { */ { .type = IIO_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT - | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT - | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) + | BIT(IIO_CHAN_INFO_OFFSET) + | BIT(IIO_CHAN_INFO_SCALE), .scan_index = -1, }, INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X), -- cgit From 0112f5218df22368060cdc3783e3f32e5319eb3e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:33:01 +0000 Subject: iio:light:adjd_s311 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Peter Meerwald --- drivers/iio/light/adjd_s311.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index d5b9d39d95b2..5f4749e60b04 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -207,8 +207,8 @@ static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = { .type = IIO_INTENSITY, \ .modified = 1, \ .address = (IDX_##_color), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ .channel2 = (IIO_MOD_LIGHT_##_color), \ .scan_index = (_scan_idx), \ .scan_type = IIO_ST('u', 10, 16, 0), \ -- cgit From d113de62bae0a42e903501ed034cb0d73e140bac Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:33:14 +0000 Subject: iio:light:lm3533 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Johan Hovold --- drivers/iio/light/lm3533-als.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 7503012ce933..5fa31a4ef82a 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -231,7 +231,7 @@ static int lm3533_als_read_raw(struct iio_dev *indio_dev, .channel = _channel, \ .indexed = true, \ .output = true, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ } static const struct iio_chan_spec lm3533_als_channels[] = { @@ -239,8 +239,8 @@ static const struct iio_chan_spec lm3533_als_channels[] = { .type = IIO_LIGHT, .channel = 0, .indexed = true, - .info_mask = (IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_RAW_SEPARATE_BIT), + .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) | + BIT(IIO_CHAN_INFO_RAW), }, CHANNEL_CURRENT(0), CHANNEL_CURRENT(1), -- cgit From d292ef8da38aed8e01531c76c66d7755406cf9b8 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:33:40 +0000 Subject: iio:light:tsl2563 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Jon Brenner --- drivers/iio/light/tsl2563.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index fd8be69b7d05..1f529f36f138 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -530,14 +530,14 @@ static const struct iio_chan_spec tsl2563_channels[] = { { .type = IIO_LIGHT, .indexed = 1, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .channel = 0, }, { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_BOTH, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, @@ -546,8 +546,8 @@ static const struct iio_chan_spec tsl2563_channels[] = { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_IR, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE), } }; -- cgit From bb7c5940248ac53fdb6c3684bbfc20f8a26f1acd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:33:55 +0000 Subject: iio:light:vcnl4000 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Peter Meerwald --- drivers/iio/light/vcnl4000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 2aa748fbdc0e..1014943d949a 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -93,11 +93,11 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, static const struct iio_chan_spec vcnl4000_channels[] = { { .type = IIO_LIGHT, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_PROXIMITY, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), } }; -- cgit From b841f8abc27466026ecf4e5590c6c737c2e86e7e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:35:55 +0000 Subject: staging:iio:accel:adis move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/accel/adis16201_core.c | 8 +++---- drivers/staging/iio/accel/adis16203_core.c | 2 +- drivers/staging/iio/accel/adis16204_core.c | 8 +++---- drivers/staging/iio/accel/adis16209_core.c | 4 ++-- drivers/staging/iio/accel/adis16240_core.c | 9 +++----- drivers/staging/iio/gyro/adis16260_core.c | 4 ++-- include/linux/iio/imu/adis.h | 34 +++++++++++++++--------------- 7 files changed, 32 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 9e5791ff2a04..ab8ec7af88b4 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -134,14 +134,14 @@ static const struct iio_chan_spec adis16201_channels[] = { ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12), ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12), ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12), ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), IIO_CHAN_SOFT_TIMESTAMP(7) }; diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 8c235273ff13..b08ac8fdeee2 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -102,7 +102,7 @@ static const struct iio_chan_spec adis16203_channels[] = { ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12), ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12), ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), /* Fixme: Not what it appears to be - see data sheet */ ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14), ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12), diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index f3592668e066..792ec25a50dc 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -140,13 +140,11 @@ static const struct iio_chan_spec adis16204_channels[] = { ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12), ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12), ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14), ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14), ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT, - ADIS16204_SCAN_ACC_XY, IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 14), IIO_CHAN_SOFT_TIMESTAMP(5), }; diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 69c50ee44ce3..323c169d699c 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -133,9 +133,9 @@ static const struct iio_chan_spec adis16209_channels[] = { ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14), ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12), ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + BIT(IIO_CHAN_INFO_CALIBBIAS), 14), ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12), ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14), ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14), diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index e97fa0b0233d..fd1f0fd0fba8 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -176,14 +176,11 @@ static const struct iio_chan_spec adis16240_channels[] = { ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10), ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10), ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10), ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10), ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z, - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10), ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10), IIO_CHAN_SOFT_TIMESTAMP(6) }; diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 6e80b8c768ae..620d63fd099b 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -124,8 +124,8 @@ static IIO_DEVICE_ATTR(sampling_frequency_available, #define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \ struct iio_chan_spec adis16260_channels_##axis[] = { \ ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, 14), \ + BIT(IIO_CHAN_INFO_CALIBBIAS) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE), 14), \ ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \ ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \ ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \ diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index ff781dca2e9a..b665dc7f017b 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -162,8 +162,8 @@ int adis_single_conversion(struct iio_dev *indio_dev, .indexed = 1, \ .channel = (chan), \ .extend_name = name, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -184,9 +184,9 @@ int adis_single_conversion(struct iio_dev *indio_dev, .type = IIO_TEMP, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -197,13 +197,13 @@ int adis_single_conversion(struct iio_dev *indio_dev, }, \ } -#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \ +#define ADIS_MOD_CHAN(_type, mod, addr, si, info_sep, bits) { \ .type = (_type), \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - info, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + info_sep, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -214,17 +214,17 @@ int adis_single_conversion(struct iio_dev *indio_dev, }, \ } -#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits) +#define ADIS_ACCEL_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info_sep, bits) -#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits) +#define ADIS_GYRO_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info_sep, bits) -#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits) +#define ADIS_INCLI_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info_sep, bits) -#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits) +#define ADIS_ROT_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info_sep, bits) #ifdef CONFIG_IIO_ADIS_LIB_BUFFER -- cgit From 542c809b2d28e747e067912d1b4fd65d65d840dc Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:36:17 +0000 Subject: staging:iio:accel:adis16220 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/accel/adis16220_core.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 370b01aa767a..0e72f795ed09 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -344,37 +344,37 @@ static const struct iio_chan_spec adis16220_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .address = in_supply, }, { .type = IIO_ACCEL, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_PEAK), .address = accel, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), .address = temp, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), .address = in_1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = in_2, } }; -- cgit From b1177167c774a016c3c16f5b14d3cdcc4d1021d0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:36:35 +0000 Subject: staging:iio:accel:lis3l02dq move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/lis3l02dq_core.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0e019306439c..1bfe5d81792b 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -501,12 +501,6 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) return IRQ_HANDLED; } -#define LIS3L02DQ_INFO_MASK \ - (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT) - #define LIS3L02DQ_EVENT_MASK \ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) @@ -516,7 +510,10 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = mod, \ - .info_mask = LIS3L02DQ_INFO_MASK, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = index, \ .scan_index = index, \ .scan_type = { \ -- cgit From a8b21c5ccf47ec4e1fffcbc06a52592bb165b582 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:36:45 +0000 Subject: staging:iio:accel:sca3000 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/sca3000_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 14683f583ccf..32950ad94857 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -419,8 +419,6 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); -#define SCA3000_INFO_MASK \ - IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT #define SCA3000_EVENT_MASK \ (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING)) @@ -429,7 +427,8 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = mod, \ - .info_mask = SCA3000_INFO_MASK, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ .address = index, \ .scan_index = index, \ .scan_type = { \ -- cgit From 4ff30e0a0c63670e1af7635dc0659bc74c2ffe13 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:37:07 +0000 Subject: staging:iio:adc:ad7280a move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/adc/ad7280a.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 1f190c1b12a6..2fd6ee3c1902 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -503,9 +503,10 @@ static int ad7280_channel_init(struct ad7280_state *st) st->channels[cnt].channel = (dev * 6) + ch - 6; } st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask = - IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT; + st->channels[cnt].info_mask_separate = + BIT(IIO_CHAN_INFO_RAW); + st->channels[cnt].info_mask_shared_by_type = + BIT(IIO_CHAN_INFO_SCALE); st->channels[cnt].address = AD7280A_DEVADDR(dev) << 8 | ch; st->channels[cnt].scan_index = cnt; @@ -521,9 +522,8 @@ static int ad7280_channel_init(struct ad7280_state *st) st->channels[cnt].channel2 = dev * 6; st->channels[cnt].address = AD7280A_ALL_CELLS; st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask = - IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT; + st->channels[cnt].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + st->channels[cnt].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); st->channels[cnt].scan_index = cnt; st->channels[cnt].scan_type.sign = 'u'; st->channels[cnt].scan_type.realbits = 32; -- cgit From 0325948ad8113257dab3b2a5fbbe7c53a3f57be8 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:37:16 +0000 Subject: staging:iio:adc:ad7291 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/adc/ad7291.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 6e58e36d242c..d088c662d5cd 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -536,8 +536,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev, #define AD7291_VOLTAGE_CHAN(_chan) \ { \ .type = IIO_VOLTAGE, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .indexed = 1, \ .channel = _chan, \ .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\ @@ -555,9 +555,9 @@ static const struct iio_chan_spec ad7291_channels[] = { AD7291_VOLTAGE_CHAN(7), { .type = IIO_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_AVERAGE_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .indexed = 1, .channel = 0, .event_mask = -- cgit From 7593908f8fd16ca02dc3c5362bb7981be93dd2ca Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:37:28 +0000 Subject: staging:iio:adc:ad7606 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/adc/ad7606_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index bae61cbe9212..d104b4378424 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -235,8 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } -- cgit From 202c7db091c759131b13e15f5ef9859ac6b7e2fb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:37:47 +0000 Subject: staging:iio:adc:ad799x move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/adc/ad799x_core.c | 76 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 077eedbd0a0c..40cc89abe3c3 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -467,7 +467,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -475,7 +475,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -483,7 +483,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -491,7 +491,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -507,7 +507,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -515,7 +515,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -523,7 +523,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -531,7 +531,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -547,7 +547,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -555,7 +555,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -563,7 +563,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -571,7 +571,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -587,7 +587,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -596,7 +596,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -614,7 +614,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -624,7 +624,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .indexed = 1, .channel = 1, .scan_index = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, }, @@ -632,7 +632,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -641,7 +641,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -659,7 +659,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -668,7 +668,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -677,7 +677,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -686,7 +686,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -704,7 +704,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -713,7 +713,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -722,7 +722,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -731,7 +731,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -740,7 +740,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 4, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -748,7 +748,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 5, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -756,7 +756,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 6, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -764,7 +764,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 7, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -781,7 +781,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -790,7 +790,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -799,7 +799,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -808,7 +808,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -817,7 +817,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 4, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -825,7 +825,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 5, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -833,7 +833,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 6, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -841,7 +841,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 7, .scan_type = IIO_ST('u', 12, 16, 0), }, -- cgit From 0221519534ac5060b55d7f5d0accdd30364b7997 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:37:59 +0000 Subject: staging:iio:cdc:ad7150 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/cdc/ad7150.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index 3c608c14dd99..687dd2c91437 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -429,8 +429,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_AVERAGE_RAW), .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | @@ -442,8 +442,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_AVERAGE_RAW), .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | -- cgit From c24e97b70d72262b6c76e6413ddc28400768f238 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:38:12 +0000 Subject: staging:iio:cdc:ad7152 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Acked-by: Lars-Peter Clausen --- drivers/staging/iio/cdc/ad7152.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index 3c92ba3722a8..1d7c5283a85c 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -436,38 +436,38 @@ static const struct iio_chan_spec ad7152_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_CAPACITANCE, .differential = 1, .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_CAPACITANCE, .differential = 1, .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), } }; /* -- cgit From a556d1722fb780a7c3339488190de4dbc849e3e7 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:38:26 +0000 Subject: staging:iio:cdc:ad7746 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Acked-by: Lars-Peter Clausen --- drivers/staging/iio/cdc/ad7746.c | 48 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 466b82ecfbe0..94f9ca726d1c 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -123,8 +123,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_VIN, }, @@ -133,8 +133,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_VDD_MON, }, @@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_INT_TEMP, }, @@ -150,7 +150,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_TEMP, }, @@ -158,11 +158,10 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_CAP_DATA_HIGH << 8, }, [CIN1_DIFF] = { @@ -171,11 +170,10 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_CAP_DATA_HIGH << 8 | AD7746_CAPSETUP_CAPDIFF }, @@ -183,11 +181,10 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_CAP_DATA_HIGH << 8 | AD7746_CAPSETUP_CIN2, }, @@ -197,11 +194,10 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD7746_REG_CAP_DATA_HIGH << 8 | AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2, } -- cgit From cdcb0eab5f30bb09dcf63b9cc6297c3fa559332a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:38:43 +0000 Subject: staging:iio:gyro:adis16060 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Acked-by: Lars-Peter Clausen --- drivers/staging/iio/gyro/adis16060_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 687c151f9847..c67d3a832aef 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -120,27 +120,26 @@ static const struct iio_chan_spec adis16060_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = ADIS16060_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = ADIS16060_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = ADIS16060_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), .address = ADIS16060_TEMP_OUT, } }; -- cgit From 37db3bf2e3e894f19a799f97d6d909bd00ef790a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:39:04 +0000 Subject: staging:iio:gyro:adis16130 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Acked-by: Lars-Peter Clausen --- drivers/staging/iio/gyro/adis16130_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 835801ee7e80..531b803cb2ac 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -100,13 +100,13 @@ static const struct iio_chan_spec adis16130_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = ADIS16130_RATEDATA, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .address = ADIS16130_TEMPDATA, } }; -- cgit From da200c2b812dddcad0041622f519de18e1a53551 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:39:28 +0000 Subject: staging:iio:impedance:ad5933 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Acked-by: Lars-Peter Clausen --- drivers/staging/iio/impedance-analyzer/ad5933.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 440e2261e8cb..6330af656a0f 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -113,7 +113,7 @@ static const struct iio_chan_spec ad5933_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .address = AD5933_REG_TEMP_DATA, .scan_type = { .sign = 's', @@ -125,8 +125,8 @@ static const struct iio_chan_spec ad5933_channels[] = { .indexed = 1, .channel = 0, .extend_name = "real_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD5933_REG_REAL_DATA, .scan_index = 0, .scan_type = { @@ -139,8 +139,8 @@ static const struct iio_chan_spec ad5933_channels[] = { .indexed = 1, .channel = 0, .extend_name = "imag_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), .address = AD5933_REG_IMAG_DATA, .scan_index = 1, .scan_type = { -- cgit From f7bd0978b1718ed20c356ae6888e0c951304dd8c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:39:40 +0000 Subject: staging:iio:light:isl29018 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Rhyland Klein --- drivers/staging/iio/light/isl29018.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index b0adac0bf5d5..82478a59e42e 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -412,17 +412,17 @@ static const struct iio_chan_spec isl29018_channels[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_CALIBSCALE), }, { .type = IIO_INTENSITY, .modified = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .channel2 = IIO_MOD_LIGHT_IR, }, { /* Unindexed in current ABI. But perhaps it should be. */ .type = IIO_PROXIMITY, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), } }; -- cgit From 93a9fdff2106f34747ec934812c89fa8b28b419f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:39:52 +0000 Subject: staging:iio:light:isl29028 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Laxman Dewangan --- drivers/staging/iio/light/isl29028.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index e52af77f7782..8bb0d03627f2 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -391,15 +391,15 @@ static const struct attribute_group isl29108_group = { static const struct iio_chan_spec isl29028_channels[] = { { .type = IIO_LIGHT, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_SCALE), }, { .type = IIO_INTENSITY, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .type = IIO_PROXIMITY, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), } }; -- cgit From cca9b7ff2a92af9624f68c5e64e6e0aa8407260a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:40:11 +0000 Subject: staging:iio:light:tsl2x7x move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Jon Brenner --- drivers/staging/iio/light/tsl2x7x_core.c | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index a58731e70bb9..d060f2572512 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1733,14 +1733,14 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }, { .type = IIO_INTENSITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), .event_mask = TSL2X7X_EVENT_MASK }, { .type = IIO_INTENSITY, @@ -1757,7 +1757,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .type = IIO_PROXIMITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .event_mask = TSL2X7X_EVENT_MASK }, }, @@ -1770,25 +1770,25 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) }, { .type = IIO_INTENSITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), .event_mask = TSL2X7X_EVENT_MASK }, { .type = IIO_INTENSITY, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .type = IIO_PROXIMITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .event_mask = TSL2X7X_EVENT_MASK }, }, @@ -1801,8 +1801,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .type = IIO_PROXIMITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_mask = TSL2X7X_EVENT_MASK }, }, @@ -1815,26 +1815,26 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }, { .type = IIO_INTENSITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), .event_mask = TSL2X7X_EVENT_MASK }, { .type = IIO_INTENSITY, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .type = IIO_PROXIMITY, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .event_mask = TSL2X7X_EVENT_MASK }, }, -- cgit From 3a0b442234f570bcbf406dd70ab6f941e243da94 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:40:48 +0000 Subject: staging:iio:mag:ak8975 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Andrew Chew --- drivers/staging/iio/magnetometer/ak8975.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 28f080e9eeee..b614da1b21f8 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -395,8 +395,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = index, \ } -- cgit From b3700970f07a74f7d248c81400258f3ab3cbbb27 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:40:58 +0000 Subject: staging:iio:magnetometer:hmc5843 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Shubhrajyoti D --- drivers/staging/iio/magnetometer/hmc5843.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 1a520ecfa3e2..86c6bf9d5dd8 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -564,8 +564,8 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = add \ } -- cgit From fda33186b500206dc3d35651b79cfe4fd0920c1e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:41:09 +0000 Subject: staging:iio:meter:ade7758 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/staging/iio/meter/ade7758_core.c | 60 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 53c68dcc4544..8f5bcfab3563 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -649,8 +649,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), .scan_index = 0, .scan_type = { @@ -663,8 +663,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), .scan_index = 1, .scan_type = { @@ -677,8 +677,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), .scan_index = 2, .scan_type = { @@ -691,8 +691,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), .scan_index = 3, .scan_type = { @@ -705,8 +705,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 0, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), .scan_index = 4, .scan_type = { @@ -719,8 +719,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), .scan_index = 5, .scan_type = { @@ -733,8 +733,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), .scan_index = 6, .scan_type = { @@ -747,8 +747,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), .scan_index = 7, .scan_type = { @@ -761,8 +761,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), .scan_index = 8, .scan_type = { @@ -775,8 +775,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 1, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), .scan_index = 9, .scan_type = { @@ -789,8 +789,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), .scan_index = 10, .scan_type = { @@ -803,8 +803,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), .scan_index = 11, .scan_type = { @@ -817,8 +817,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "apparent_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), .scan_index = 12, .scan_type = { @@ -831,8 +831,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "active_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), .scan_index = 13, .scan_type = { @@ -845,8 +845,8 @@ static const struct iio_chan_spec ade7758_channels[] = { .indexed = 1, .channel = 2, .extend_name = "reactive_raw", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), .scan_index = 14, .scan_type = { -- cgit From 910b51f388a36ebfe8d5ae3813b7d6e75413e295 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:41:20 +0000 Subject: staging:iio:resolver:ad2s1200 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/resolver/ad2s1200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 4fe349914f9a..71221161aa6b 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -85,12 +85,12 @@ static const struct iio_chan_spec ad2s1200_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), } }; -- cgit From 07d0f65491dec4733bcf0ba430cee7403f5174cb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:41:30 +0000 Subject: staging:iio:resolver:ad2s1210 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/resolver/ad2s1210.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 53110b6a3c74..0d3356d4b7d2 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -577,12 +577,12 @@ static const struct iio_chan_spec ad2s1210_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), } }; -- cgit From 3589ba994317ba10c4ceb72599ede23850df23fb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:41:51 +0000 Subject: staging:iio:resolver:ad2s90 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich --- drivers/staging/iio/resolver/ad2s90.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 0aecfbcdb992..40b825286d4a 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -55,7 +55,7 @@ static const struct iio_chan_spec ad2s90_chan = { .type = IIO_ANGL, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), }; static int ad2s90_probe(struct spi_device *spi) -- cgit From 0d23d328c01db48d87ce3a3c9cc13a47c37dab0c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 3 Mar 2013 12:25:30 +0000 Subject: iio:adc:exynos move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Naveen Krishna Chatradhi --- drivers/iio/adc/exynos_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index ed6fdd7e5212..6e968ae48c8a 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -198,7 +198,7 @@ static const struct iio_info exynos_adc_iio_info = { .indexed = 1, \ .channel = _index, \ .address = _index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .datasheet_name = _id, \ } -- cgit From 7657719f9396f54c689f04f1401a174e01ba855e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 3 Mar 2013 12:26:47 +0000 Subject: iio:adc:ad7923 move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen cc: Patrick Vasseur cc: Christophe Leroy --- drivers/iio/adc/ad7923.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 28b2bda8f0ec..766c74026be2 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -69,8 +69,8 @@ struct ad7923_state { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = index, \ .scan_index = index, \ .scan_type = { \ -- cgit From f1e067baa5ddd968285f67126d17ef0114e90e6a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 4 Mar 2013 21:06:04 +0000 Subject: staging:iio:adc:spear move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Acked-by: Stefan Roese --- drivers/staging/iio/adc/spear_adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 13052ceb2f2b..f45da4266950 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -180,8 +180,8 @@ static int spear_read_raw(struct iio_dev *indio_dev, #define SPEAR_ADC_CHAN(idx) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .channel = idx, \ .scan_type = { \ .sign = 'u', \ -- cgit From 78a5fa674cb1c22b2fd44357889075b78b27e9bc Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 4 Mar 2013 21:08:17 +0000 Subject: staging:iio:adc:mxs move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron Reviewed-by: Marek Vasut --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 55a459b61907..25a4359a92db 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -822,7 +822,7 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = { .type = (chan_type), \ .indexed = 1, \ .scan_index = (idx), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .channel = (idx), \ .scan_type = { \ .sign = 'u', \ -- cgit From 066f90512ebfa3c59492f377cbb78c3b7231737c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 4 Mar 2013 21:10:17 +0000 Subject: staging:iio:adc:lpc32xx move to info_mask_(shared_by_type/separate) The original info_mask is going away in favour of the broken out versions. Signed-off-by: Jonathan Cameron cc: Roland Stigge --- drivers/staging/iio/adc/lpc32xx_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 0bf2a6cc79e0..2f2f7fdd0691 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -103,7 +103,7 @@ static const struct iio_info lpc32xx_adc_iio_info = { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = _index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .address = AD_IN * _index, \ .scan_index = _index, \ } -- cgit From b9606e2aa97d3d831d1236c0e789a33a2f867a8a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 27 Feb 2013 19:43:52 +0000 Subject: iio:core drop info_mask from struct iio_info This has been replaced by the pair of masks info_mask_separate and info_mask_shared_by_type. Other variants may follow. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/industrialio-core.c | 17 ---------- include/linux/iio/iio.h | 73 +---------------------------------------- 2 files changed, 1 insertion(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index f05289f7b512..e145931ef1b8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -691,23 +691,6 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, if (chan->channel < 0) return 0; - for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { - ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], - chan, - &iio_read_channel_info, - &iio_write_channel_info, - i/2, - !(i%2), - &indio_dev->dev, - &indio_dev->channel_attr_list); - if (ret == -EBUSY && (i%2 == 0)) { - ret = 0; - continue; - } - if (ret < 0) - goto error_ret; - attrcount++; - } for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) { ret = __iio_add_chan_devattr(iio_chan_info_postfix[i], chan, diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 76976509d628..8d171f427632 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -38,76 +38,6 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_HYSTERESIS, }; -#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) -#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) -#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \ - IIO_CHAN_INFO_SEPARATE_BIT(type)) - -#define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) -#define IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PROCESSED) -#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_SCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_OFFSET_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAK_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) -#define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) -#define IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_FREQUENCY) -#define IIO_CHAN_INFO_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_FREQUENCY) -#define IIO_CHAN_INFO_PHASE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PHASE) -#define IIO_CHAN_INFO_PHASE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PHASE) -#define IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HARDWAREGAIN) -#define IIO_CHAN_INFO_HARDWAREGAIN_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HARDWAREGAIN) -#define IIO_CHAN_INFO_HYSTERESIS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HYSTERESIS) -#define IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HYSTERESIS) - enum iio_endian { IIO_CPU, IIO_BE, @@ -281,8 +211,7 @@ struct iio_chan_spec { static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, enum iio_chan_info_enum type) { - return (chan->info_mask & IIO_CHAN_INFO_BITS(type)) | - (chan->info_mask_separate & type) | + return (chan->info_mask_separate & type) | (chan->info_mask_shared_by_type & type); } -- cgit From 1b9dc91e41e07125ef2ce7d0a8dde93ce3eaf414 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 7 Mar 2013 19:53:00 +0000 Subject: iio: events: Make iio_push_event() IRQ context save Currently it is not save to call iio_push_event() from hard IRQ context since the IIO event code uses spin_lock()/spin_unlock() and it is not save to mix calls to spin_lock()/spin_unlock() from different contexts on the same lock. E.g. if the lock is being held in iio_event_chrdev_read() and an interrupts kicks in and the interrupt handler calls iio_push_event() we end uo with a deadlock. This patch updates iio_push_event() to use spin_lock_irqsave()/ spin_unlock_irqstrestore(), since it can be called from both IRQ and non-IRQ context. All other other users of the lock, which are always run in non-IRQ context, are updated to spin_lock_irq()/spin_unlock_irq(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-event.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 261cae00557e..10aa9ef86cec 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -46,10 +46,11 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) { struct iio_event_interface *ev_int = indio_dev->event_interface; struct iio_event_data ev; + unsigned long flags; int copied; /* Does anyone care? */ - spin_lock(&ev_int->wait.lock); + spin_lock_irqsave(&ev_int->wait.lock, flags); if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { ev.id = ev_code; @@ -59,7 +60,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) if (copied != 0) wake_up_locked_poll(&ev_int->wait, POLLIN); } - spin_unlock(&ev_int->wait.lock); + spin_unlock_irqrestore(&ev_int->wait.lock, flags); return 0; } @@ -76,10 +77,10 @@ static unsigned int iio_event_poll(struct file *filep, poll_wait(filep, &ev_int->wait, wait); - spin_lock(&ev_int->wait.lock); + spin_lock_irq(&ev_int->wait.lock); if (!kfifo_is_empty(&ev_int->det_events)) events = POLLIN | POLLRDNORM; - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); return events; } @@ -96,14 +97,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep, if (count < sizeof(struct iio_event_data)) return -EINVAL; - spin_lock(&ev_int->wait.lock); + spin_lock_irq(&ev_int->wait.lock); if (kfifo_is_empty(&ev_int->det_events)) { if (filep->f_flags & O_NONBLOCK) { ret = -EAGAIN; goto error_unlock; } /* Blocking on device; waiting for something to be there */ - ret = wait_event_interruptible_locked(ev_int->wait, + ret = wait_event_interruptible_locked_irq(ev_int->wait, !kfifo_is_empty(&ev_int->det_events)); if (ret) goto error_unlock; @@ -113,7 +114,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep, ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); error_unlock: - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); return ret ? ret : copied; } @@ -122,7 +123,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) { struct iio_event_interface *ev_int = filep->private_data; - spin_lock(&ev_int->wait.lock); + spin_lock_irq(&ev_int->wait.lock); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); /* * In order to maintain a clean state for reopening, @@ -130,7 +131,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) * any new __iio_push_event calls running. */ kfifo_reset_out(&ev_int->det_events); - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); return 0; } @@ -151,18 +152,18 @@ int iio_event_getfd(struct iio_dev *indio_dev) if (ev_int == NULL) return -ENODEV; - spin_lock(&ev_int->wait.lock); + spin_lock_irq(&ev_int->wait.lock); if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); return -EBUSY; } - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops, ev_int, O_RDONLY); if (fd < 0) { - spin_lock(&ev_int->wait.lock); + spin_lock_irq(&ev_int->wait.lock); __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - spin_unlock(&ev_int->wait.lock); + spin_unlock_irq(&ev_int->wait.lock); } return fd; } -- cgit From 039a9dce0d192196d40bd35d4bfebfbcade5d14e Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Fri, 15 Mar 2013 16:23:00 +0000 Subject: iio: adc: Kconfig: exynos_adc depends on CONFIG_OF As the exynos_adc driver only supports device tree registration. Making driver depend on CONFIG_OF solves possible errors during probe. Signed-off-by: Naveen Krishna Chatradhi Reported-by: Dan Carpenter Reviewed-by: Doug Anderson Cc: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a40d3c29f0cb..9c45c0f3f127 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -105,6 +105,7 @@ config AT91_ADC config EXYNOS_ADC bool "Exynos ADC driver support" + depends on OF help Core support for the ADC block found in the Samsung EXYNOS series of SoCs for drivers such as the touchscreen and hwmon to use to share -- cgit From 6c23811ecb24e077081d04c7af511d94746419ab Mon Sep 17 00:00:00 2001 From: Ge Gao Date: Mon, 4 Mar 2013 23:27:00 +0000 Subject: using kfifo_in_spinlocked instead of separate code. Signed-off-by: Ge Gao Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 331781ffbb15..7da0832f187b 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -105,9 +105,8 @@ irqreturn_t inv_mpu6050_irq_handler(int irq, void *p) s64 timestamp; timestamp = iio_get_time_ns(); - spin_lock(&st->time_stamp_lock); - kfifo_in(&st->timestamps, ×tamp, 1); - spin_unlock(&st->time_stamp_lock); + kfifo_in_spinlocked(&st->timestamps, ×tamp, 1, + &st->time_stamp_lock); return IRQ_WAKE_THREAD; } -- cgit From 135f06465d6842fdf1381f2610e27ff43e81f24d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Mar 2013 19:30:00 +0000 Subject: iio:ad7923: Return error if we didn't get the expected result Instead of leaving 'val' uninitialized return an error if the result's address did not match that of the channel we were trying to read. Signed-off-by: Lars-Peter Clausen Cc: Patrick Vasseur Cc: Christophe Leroy Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7923.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 766c74026be2..36eee248a9f6 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -199,6 +199,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, if (chan->address == EXTRACT(ret, 12, 4)) *val = EXTRACT(ret, 0, 12); + else + return -EIO; return IIO_VAL_INT; } -- cgit From ecf6ca2539bc3a36a14685b743fd7376707958ab Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Mar 2013 19:30:00 +0000 Subject: iio:ad7923: Implement scale reporting The driver already claims to support scale reporting in its channel spec, but doesn't actually implement this yet. This patch uses the regulator API to get the reference voltage and calculates the scale based on that. The patch also moves the global configuration bits into a field in the ad7923_state struct, since depending on the RANGE bit, the range goes either from 0 to VREF or from 0 to 2 * VREF. So we need to know the setting of the RANGE bit when calculating the scale. Signed-off-by: Lars-Peter Clausen Cc: Patrick Vasseur Cc: Christophe Leroy Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7923.c | 60 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 36eee248a9f6..11ccc42b25a6 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,11 @@ struct ad7923_state { struct spi_transfer scan_single_xfer[2]; struct spi_message ring_msg; struct spi_message scan_single_msg; + + struct regulator *reg; + + unsigned int settings; + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. @@ -100,10 +106,9 @@ static int ad7923_update_scan_mode(struct iio_dev *indio_dev, len = 0; for_each_set_bit(i, active_scan_mask, AD7923_MAX_CHAN) { - cmd = AD7923_WRITE_CR | AD7923_CODING | AD7923_RANGE | - AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS) | + cmd = AD7923_WRITE_CR | AD7923_CHANNEL_WRITE(i) | AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) | - AD7923_CHANNEL_WRITE(i); + st->settings; cmd <<= AD7923_SHIFT_REGISTER; st->tx_buf[len++] = cpu_to_be16(cmd); } @@ -163,9 +168,9 @@ static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch) { int ret, cmd; - cmd = AD7923_WRITE_CR | AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS) | - AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) | AD7923_CODING | - AD7923_CHANNEL_WRITE(ch) | AD7923_RANGE; + cmd = AD7923_WRITE_CR | AD7923_CHANNEL_WRITE(ch) | + AD7923_SEQUENCE_WRITE(AD7923_SEQUENCE_OFF) | + st->settings; cmd <<= AD7923_SHIFT_REGISTER; st->tx_buf[0] = cpu_to_be16(cmd); @@ -176,6 +181,22 @@ static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch) return be16_to_cpu(st->rx_buf[0]); } +static int ad7923_get_range(struct ad7923_state *st) +{ + int vref; + + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + + vref /= 1000; + + if (!(st->settings & AD7923_RANGE)) + vref *= 2; + + return vref; +} + static int ad7923_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -203,6 +224,13 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, return -EIO; return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + ret = ad7923_get_range(st); + if (ret < 0) + return ret; + *val = ret; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; } return -EINVAL; } @@ -227,6 +255,8 @@ static int ad7923_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); st->spi = spi; + st->settings = AD7923_CODING | AD7923_RANGE | + AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS); indio_dev->name = spi_get_device_id(spi)->name; indio_dev->dev.parent = &spi->dev; @@ -247,10 +277,19 @@ static int ad7923_probe(struct spi_device *spi) spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); + st->reg = regulator_get(&spi->dev, "refin"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + ret = iio_triggered_buffer_setup(indio_dev, NULL, &ad7923_trigger_handler, NULL); if (ret) - goto error_free; + goto error_disable_reg; ret = iio_device_register(indio_dev); if (ret) @@ -260,6 +299,10 @@ static int ad7923_probe(struct spi_device *spi) error_cleanup_ring: iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + regulator_disable(st->reg); +error_put_reg: + regulator_put(st->reg); error_free: iio_device_free(indio_dev); @@ -269,9 +312,12 @@ error_free: static int ad7923_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7923_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); + regulator_disable(st->reg); + regulator_put(st->reg); iio_device_free(indio_dev); return 0; -- cgit From f2f7a449707eade5d6876d48d48ddc79dd77d75f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 4 Mar 2013 19:30:00 +0000 Subject: iio:adc:ad7923: Add support for the ad7904/ad7914/ad7924 The ad7924 is software compatible with the ad7923. The ad7904 and ad7914 are the 8 and 10 bit version of the ad7924. While we are at it also drop the "with temperature sensor" from the Kconfig entry, since the chips do not have a temperature sensor. Signed-off-by: Lars-Peter Clausen Cc: Patrick Vasseur Cc: Christophe Leroy Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 6 ++--- drivers/iio/adc/ad7923.c | 63 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 9c45c0f3f127..ab0767e6727e 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -31,13 +31,13 @@ config AD7298 module will be called ad7298. config AD7923 - tristate "Analog Devices AD7923 ADC driver" + tristate "Analog Devices AD7923 and similar ADCs driver" depends on SPI select IIO_BUFFER select IIO_TRIGGERED_BUFFER help - Say yes here to build support for Analog Devices AD7923 - 4 Channel ADC with temperature sensor. + Say yes here to build support for Analog Devices + AD7904, AD7914, AD7923, AD7924 4 Channel ADCs. To compile this driver as a module, choose M here: the module will be called ad7923. diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 11ccc42b25a6..97fa0d3dc4aa 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -1,5 +1,5 @@ /* - * AD7923 SPI ADC driver + * AD7904/AD7914/AD7923/AD7924 SPI ADC driver * * Copyright 2011 Analog Devices Inc (from AD7923 Driver) * Copyright 2012 CS Systemes d'Information @@ -70,7 +70,18 @@ struct ad7923_state { __be16 tx_buf[4]; }; -#define AD7923_V_CHAN(index) \ +struct ad7923_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +enum ad7923_id { + AD7904, + AD7914, + AD7924, +}; + +#define AD7923_V_CHAN(index, bits) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -81,18 +92,38 @@ struct ad7923_state { .scan_index = index, \ .scan_type = { \ .sign = 'u', \ - .realbits = 12, \ + .realbits = (bits), \ .storagebits = 16, \ .endianness = IIO_BE, \ }, \ } -static const struct iio_chan_spec ad7923_channels[] = { - AD7923_V_CHAN(0), - AD7923_V_CHAN(1), - AD7923_V_CHAN(2), - AD7923_V_CHAN(3), - IIO_CHAN_SOFT_TIMESTAMP(4), +#define DECLARE_AD7923_CHANNELS(name, bits) \ +const struct iio_chan_spec name ## _channels[] = { \ + AD7923_V_CHAN(0, bits), \ + AD7923_V_CHAN(1, bits), \ + AD7923_V_CHAN(2, bits), \ + AD7923_V_CHAN(3, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + +static DECLARE_AD7923_CHANNELS(ad7904, 8); +static DECLARE_AD7923_CHANNELS(ad7914, 10); +static DECLARE_AD7923_CHANNELS(ad7924, 12); + +static const struct ad7923_chip_info ad7923_chip_info[] = { + [AD7904] = { + .channels = ad7904_channels, + .num_channels = ARRAY_SIZE(ad7904_channels), + }, + [AD7914] = { + .channels = ad7914_channels, + .num_channels = ARRAY_SIZE(ad7914_channels), + }, + [AD7924] = { + .channels = ad7924_channels, + .num_channels = ARRAY_SIZE(ad7924_channels), + }, }; /** @@ -245,6 +276,7 @@ static int ad7923_probe(struct spi_device *spi) { struct ad7923_state *st; struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + const struct ad7923_chip_info *info; int ret; if (indio_dev == NULL) @@ -258,11 +290,13 @@ static int ad7923_probe(struct spi_device *spi) st->settings = AD7923_CODING | AD7923_RANGE | AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS); + info = &ad7923_chip_info[spi_get_device_id(spi)->driver_data]; + indio_dev->name = spi_get_device_id(spi)->name; indio_dev->dev.parent = &spi->dev; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = ad7923_channels; - indio_dev->num_channels = ARRAY_SIZE(ad7923_channels); + indio_dev->channels = info->channels; + indio_dev->num_channels = info->num_channels; indio_dev->info = &ad7923_info; /* Setup default message */ @@ -324,7 +358,10 @@ static int ad7923_remove(struct spi_device *spi) } static const struct spi_device_id ad7923_id[] = { - {"ad7923", 0}, + {"ad7904", AD7904}, + {"ad7914", AD7914}, + {"ad7923", AD7924}, + {"ad7924", AD7924}, {} }; MODULE_DEVICE_TABLE(spi, ad7923_id); @@ -342,5 +379,5 @@ module_spi_driver(ad7923_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_AUTHOR("Patrick Vasseur "); -MODULE_DESCRIPTION("Analog Devices AD7923 ADC"); +MODULE_DESCRIPTION("Analog Devices AD7904/AD7914/AD7923/AD7924 ADC"); MODULE_LICENSE("GPL v2"); -- cgit From bb916ebbeabd18f7dc3c661275d2c9d343f4fa85 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 13 Mar 2013 20:40:00 +0000 Subject: iio: adc: Add dt support for turning on the phy in exynos-adc Without this change the exynos adc controller needed to have its phy enabled in some out-of-driver C code. Add support for specifying the phy enable register by listing it in the reg list. Signed-off-by: Doug Anderson Tested-by: Naveen Krishna Chatradhi Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/arm/samsung/exynos-adc.txt | 4 ++-- drivers/iio/adc/exynos_adc.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt index f68637861b05..05e9d95ede5c 100644 --- a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt @@ -15,7 +15,7 @@ Required properties: Must be "samsung,exynos-adc-v2" for future controllers. - reg: Contains ADC register address range (base address and - length). + length) and the address of the phy enable register. - interrupts: Contains the interrupt information for the timer. The format is being dependent on which interrupt controller the Samsung device uses. @@ -27,7 +27,7 @@ Example: adding device info in dtsi file adc: adc@12D10000 { compatible = "samsung,exynos-adc-v1"; - reg = <0x12D10000 0x100>; + reg = <0x12D10000 0x100>, <0x10040718 0x4>; interrupts = <0 106 0>; #io-channel-cells = <1>; io-channel-ranges; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 6e968ae48c8a..4a8a9a34228f 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -85,6 +85,7 @@ enum adc_version { struct exynos_adc { void __iomem *regs; + void __iomem *enable_reg; struct clk *clk; unsigned int irq; struct regulator *vdd; @@ -269,13 +270,19 @@ static int exynos_adc_probe(struct platform_device *pdev) info = iio_priv(indio_dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - info->regs = devm_request_and_ioremap(&pdev->dev, mem); if (!info->regs) { ret = -ENOMEM; goto err_iio; } + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + info->enable_reg = devm_request_and_ioremap(&pdev->dev, mem); + if (!info->enable_reg) { + ret = -ENOMEM; + goto err_iio; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq resource?\n"); @@ -295,6 +302,8 @@ static int exynos_adc_probe(struct platform_device *pdev) goto err_iio; } + writel(1, info->enable_reg); + info->clk = devm_clk_get(&pdev->dev, "adc"); if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed getting clock, err = %ld\n", @@ -370,6 +379,7 @@ static int exynos_adc_remove(struct platform_device *pdev) exynos_adc_remove_devices); regulator_disable(info->vdd); clk_disable_unprepare(info->clk); + writel(0, info->enable_reg); iio_device_unregister(indio_dev); free_irq(info->irq, info); iio_device_free(indio_dev); @@ -395,6 +405,7 @@ static int exynos_adc_suspend(struct device *dev) } clk_disable_unprepare(info->clk); + writel(0, info->enable_reg); regulator_disable(info->vdd); return 0; @@ -410,6 +421,7 @@ static int exynos_adc_resume(struct device *dev) if (ret) return ret; + writel(1, info->enable_reg); clk_prepare_enable(info->clk); exynos_adc_hw_init(info); -- cgit From ba52a7fc434bea7c4a5d0ac7c10bf131f5ac60e2 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:30:05 -0700 Subject: Input: tegra-kbc - convert to devm_ioremap_resource() Use the newly introduced devm_ioremap_resource() instead of devm_request_and_ioremap() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages; so all explicit error messages can be removed from the failure code paths. Signed-off-by: Sachin Kamat Reviewed-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tegra-kbc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 0e138ebcc768..68b2b65024d6 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -31,6 +31,7 @@ #include #include #include +#include #define KBC_MAX_GPIO 24 #define KBC_MAX_KPENT 8 @@ -608,11 +609,9 @@ static int tegra_kbc_probe(struct platform_device *pdev) setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc); - kbc->mmio = devm_request_and_ioremap(&pdev->dev, res); - if (!kbc->mmio) { - dev_err(&pdev->dev, "Cannot request memregion/iomap address\n"); - return -EBUSY; - } + kbc->mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(kbc->mmio)) + return PTR_ERR(kbc->mmio); kbc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(kbc->clk)) { -- cgit From 6b0bc60b8b87be28f00dc71e624bd693d830bf74 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:26:22 -0700 Subject: Input: davinci_keyscan - use module_platform_driver_probe macro module_platform_driver_probe() simplifies the code by eliminating boilerplate code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/davinci_keyscan.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 4e4e453ea15e..829753702b62 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -329,17 +329,7 @@ static struct platform_driver davinci_ks_driver = { .remove = davinci_ks_remove, }; -static int __init davinci_ks_init(void) -{ - return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); -} -module_init(davinci_ks_init); - -static void __exit davinci_ks_exit(void) -{ - platform_driver_unregister(&davinci_ks_driver); -} -module_exit(davinci_ks_exit); +module_platform_driver_probe(davinci_ks_driver, davinci_ks_probe); MODULE_AUTHOR("Miguel Aguilar"); MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); -- cgit From 8c0aafe07721a3807f08d2a30abc1b04f01aa48b Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:26:44 -0700 Subject: Input: twl4030-pwrbutton - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-pwrbutton.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index 27c2bc8aa890..b9a05fda03e4 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -114,18 +114,8 @@ static struct platform_driver twl4030_pwrbutton_driver = { }, }; -static int __init twl4030_pwrbutton_init(void) -{ - return platform_driver_probe(&twl4030_pwrbutton_driver, +module_platform_driver_probe(twl4030_pwrbutton_driver, twl4030_pwrbutton_probe); -} -module_init(twl4030_pwrbutton_init); - -static void __exit twl4030_pwrbutton_exit(void) -{ - platform_driver_unregister(&twl4030_pwrbutton_driver); -} -module_exit(twl4030_pwrbutton_exit); MODULE_ALIAS("platform:twl4030_pwrbutton"); MODULE_DESCRIPTION("Triton2 Power Button"); -- cgit From e67d541ff2574ea30b046642217ac3ed98826e13 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:27:11 -0700 Subject: Input: amikbd - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/amikbd.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 79172af164f2..ba0b36f7daea 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -260,18 +260,6 @@ static struct platform_driver amikbd_driver = { }, }; -static int __init amikbd_init(void) -{ - return platform_driver_probe(&amikbd_driver, amikbd_probe); -} - -module_init(amikbd_init); - -static void __exit amikbd_exit(void) -{ - platform_driver_unregister(&amikbd_driver); -} - -module_exit(amikbd_exit); +module_platform_driver_probe(amikbd_driver, amikbd_probe); MODULE_ALIAS("platform:amiga-keyboard"); -- cgit From 0442ce1cff6597ac36003342d31565f7358e75df Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:27:41 -0700 Subject: Input: nomadik-ske-keypad - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 0e6a8151fee3..c7d505cce72f 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -430,17 +430,7 @@ static struct platform_driver ske_keypad_driver = { .remove = ske_keypad_remove, }; -static int __init ske_keypad_init(void) -{ - return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe); -} -module_init(ske_keypad_init); - -static void __exit ske_keypad_exit(void) -{ - platform_driver_unregister(&ske_keypad_driver); -} -module_exit(ske_keypad_exit); +module_platform_driver_probe(ske_keypad_driver, ske_keypad_probe); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Naveen Kumar / Sundar Iyer "); -- cgit From e492fe2751dbb14e1a24f888e9b174bc9bafee21 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:28:00 -0700 Subject: Input: amimouse - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/amimouse.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 5fa99341a39d..b55d5af217a7 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -146,18 +146,6 @@ static struct platform_driver amimouse_driver = { }, }; -static int __init amimouse_init(void) -{ - return platform_driver_probe(&amimouse_driver, amimouse_probe); -} - -module_init(amimouse_init); - -static void __exit amimouse_exit(void) -{ - platform_driver_unregister(&amimouse_driver); -} - -module_exit(amimouse_exit); +module_platform_driver_probe(amimouse_driver, amimouse_probe); MODULE_ALIAS("platform:amiga-mouse"); -- cgit From 9e984cdd171c0feaaf81af1f35c15439c7798bb8 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:28:14 -0700 Subject: Input: at32psif - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/serio/at32psif.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 36e799c31f5e..190ce35af7df 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -359,18 +359,7 @@ static struct platform_driver psif_driver = { }, }; -static int __init psif_init(void) -{ - return platform_driver_probe(&psif_driver, psif_probe); -} - -static void __exit psif_exit(void) -{ - platform_driver_unregister(&psif_driver); -} - -module_init(psif_init); -module_exit(psif_exit); +module_platform_driver_probe(psif_driver, psif_probe); MODULE_AUTHOR("Hans-Christian Egtvedt "); MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); -- cgit From 07beda4f6d449e045baa776ee3f31979e37d6c64 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:28:28 -0700 Subject: Input: q40kbd - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/serio/q40kbd.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 70fe542839fb..436a3433f8e5 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -193,15 +193,4 @@ static struct platform_driver q40kbd_driver = { .remove = q40kbd_remove, }; -static int __init q40kbd_init(void) -{ - return platform_driver_probe(&q40kbd_driver, q40kbd_probe); -} - -static void __exit q40kbd_exit(void) -{ - platform_driver_unregister(&q40kbd_driver); -} - -module_init(q40kbd_init); -module_exit(q40kbd_exit); +module_platform_driver_probe(q40kbd_driver, q40kbd_probe); -- cgit From 8698a9382603faf64f045445b90f768522af28da Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sun, 17 Mar 2013 21:29:07 -0700 Subject: Input: atmel-wm97xx - use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel-wm97xx.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index c5c2dbb93869..2c1e46b7e45b 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c @@ -432,17 +432,7 @@ static struct platform_driver atmel_wm97xx_driver = { }, }; -static int __init atmel_wm97xx_init(void) -{ - return platform_driver_probe(&atmel_wm97xx_driver, atmel_wm97xx_probe); -} -module_init(atmel_wm97xx_init); - -static void __exit atmel_wm97xx_exit(void) -{ - platform_driver_unregister(&atmel_wm97xx_driver); -} -module_exit(atmel_wm97xx_exit); +module_platform_driver_probe(atmel_wm97xx_driver, atmel_wm97xx_probe); MODULE_AUTHOR("Hans-Christian Egtvedt "); MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); -- cgit From 38a46eb8cc0faec0345c27083fb26d1e7e02ccff Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Sun, 17 Mar 2013 21:31:03 -0700 Subject: Input: mc13783_ts - use module_platform_driver_probe() This patch converts the drivers to use the module_platform_driver_probe() macro which makes the code smaller and a bit simpler. Signed-off-by: Fabio Porcedda Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mc13783_ts.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index 02103b6abb39..89308fe38752 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c @@ -250,17 +250,7 @@ static struct platform_driver mc13783_ts_driver = { }, }; -static int __init mc13783_ts_init(void) -{ - return platform_driver_probe(&mc13783_ts_driver, &mc13783_ts_probe); -} -module_init(mc13783_ts_init); - -static void __exit mc13783_ts_exit(void) -{ - platform_driver_unregister(&mc13783_ts_driver); -} -module_exit(mc13783_ts_exit); +module_platform_driver_probe(mc13783_ts_driver, mc13783_ts_probe); MODULE_DESCRIPTION("MC13783 input touchscreen driver"); MODULE_AUTHOR("Sascha Hauer "); -- cgit From aabd6a8fa5a933bdf968cd86e34122745c1960e8 Mon Sep 17 00:00:00 2001 From: Sjur Brændeland Date: Mon, 18 Mar 2013 19:19:14 +1030 Subject: Revert "virtio_console: Initialize guest_connected=true for rproc_serial" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8078db789a92b10ff6e2d713231b5367e014c53b, and adds a lengthy comment explaining the problem area. The reverted patch caused opening of ports to fail for rproc_serial. In probe guest_connected was set to true, but port_fops_open() fails with -EMFILE if guest_connected already is true. Signed-off-by: Sjur Brændeland Acked-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e905d5f53051..e6ba6b7887e9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1436,7 +1436,7 @@ static int add_port(struct ports_device *portdev, u32 id) * rproc_serial does not want the console port, only * the generic port implementation. */ - port->host_connected = port->guest_connected = true; + port->host_connected = true; else if (!use_multiport(port->portdev)) { /* * If we're not using multiport support, @@ -1752,13 +1752,23 @@ static void in_intr(struct virtqueue *vq) port->inbuf = get_inbuf(port); /* - * Don't queue up data when port is closed. This condition + * Normally the port should not accept data when the port is + * closed. For generic serial ports, the host won't (shouldn't) + * send data till the guest is connected. But this condition * can be reached when a console port is not yet connected (no - * tty is spawned) and the host sends out data to console - * ports. For generic serial ports, the host won't - * (shouldn't) send data till the guest is connected. + * tty is spawned) and the other side sends out data over the + * vring, or when a remote devices start sending data before + * the ports are opened. + * + * A generic serial port will discard data if not connected, + * while console ports and rproc-serial ports accepts data at + * any time. rproc-serial is initiated with guest_connected to + * false because port_fops_open expects this. Console ports are + * hooked up with an HVC console and is initialized with + * guest_connected to true. */ - if (!port->guest_connected) + + if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags); -- cgit From e4d7dc6674efd798792adbd689986cde5422aa62 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:20 +0200 Subject: usb: phy: nop: use devm_kzalloc() Use resource managed kzalloc. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index a3ce24b94a73..af52870788ec 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -100,15 +100,14 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; - nop = kzalloc(sizeof *nop, GFP_KERNEL); + nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); if (!nop) return -ENOMEM; - nop->phy.otg = kzalloc(sizeof *nop->phy.otg, GFP_KERNEL); - if (!nop->phy.otg) { - kfree(nop); + nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), + GFP_KERNEL); + if (!nop->phy.otg) return -ENOMEM; - } if (pdata) type = pdata->type; @@ -127,7 +126,7 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); - goto exit; + return err; } platform_set_drvdata(pdev, nop); @@ -135,10 +134,6 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; -exit: - kfree(nop->phy.otg); - kfree(nop); - return err; } static int nop_usb_xceiv_remove(struct platform_device *pdev) @@ -148,8 +143,6 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev) usb_remove_phy(&nop->phy); platform_set_drvdata(pdev, NULL); - kfree(nop->phy.otg); - kfree(nop); return 0; } -- cgit From 2319fb88e16e56c64d4f3ab50af69ed6dadbc7b5 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:21 +0200 Subject: usb: phy: nop: Manage PHY clock If the PHY has a clock associated to it then manage the clock. We just enable the clock in .init() and disable it in .shutdown(). Add clk_rate parameter in platform data and configure the clock rate during probe if supplied. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 54 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index af52870788ec..17c174f18da7 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -32,10 +32,12 @@ #include #include #include +#include struct nop_usb_xceiv { struct usb_phy phy; struct device *dev; + struct clk *clk; }; static struct platform_device *pd; @@ -64,6 +66,24 @@ static int nop_set_suspend(struct usb_phy *x, int suspend) return 0; } +static int nop_init(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->clk)) + clk_enable(nop->clk); + + return 0; +} + +static void nop_shutdown(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->clk)) + clk_disable(nop->clk); +} + static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { if (!otg) @@ -112,10 +132,34 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (pdata) type = pdata->type; + nop->clk = devm_clk_get(&pdev->dev, "main_clk"); + if (IS_ERR(nop->clk)) { + dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", + PTR_ERR(nop->clk)); + } + + if (!IS_ERR(nop->clk) && pdata && pdata->clk_rate) { + err = clk_set_rate(nop->clk, pdata->clk_rate); + if (err) { + dev_err(&pdev->dev, "Error setting clock rate\n"); + return err; + } + } + + if (!IS_ERR(nop->clk)) { + err = clk_prepare(nop->clk); + if (err) { + dev_err(&pdev->dev, "Error preparing clock\n"); + return err; + } + } + nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; + nop->phy.init = nop_init; + nop->phy.shutdown = nop_shutdown; nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.otg->phy = &nop->phy; @@ -126,7 +170,7 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); - return err; + goto err_add; } platform_set_drvdata(pdev, nop); @@ -134,12 +178,20 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); return 0; + +err_add: + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + return err; } static int nop_usb_xceiv_remove(struct platform_device *pdev) { struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + usb_remove_phy(&nop->phy); platform_set_drvdata(pdev, NULL); -- cgit From 58f735fe4778d34d9d1e37bcdd59325d66a8793e Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:22 +0200 Subject: usb: phy: nop: Handle power supply regulator for the PHY We use "vcc" as the supply name for the PHY's power supply. The power supply will be enabled during .init() and disabled during .shutdown() Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 17c174f18da7..fbdcfef7169b 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -33,11 +33,13 @@ #include #include #include +#include struct nop_usb_xceiv { struct usb_phy phy; struct device *dev; struct clk *clk; + struct regulator *vcc; }; static struct platform_device *pd; @@ -70,6 +72,11 @@ static int nop_init(struct usb_phy *phy) { struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + if (!IS_ERR(nop->vcc)) { + if (regulator_enable(nop->vcc)) + dev_err(phy->dev, "Failed to enable power\n"); + } + if (!IS_ERR(nop->clk)) clk_enable(nop->clk); @@ -82,6 +89,11 @@ static void nop_shutdown(struct usb_phy *phy) if (!IS_ERR(nop->clk)) clk_disable(nop->clk); + + if (!IS_ERR(nop->vcc)) { + if (regulator_disable(nop->vcc)) + dev_err(phy->dev, "Failed to disable power\n"); + } } static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) @@ -154,6 +166,12 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) } } + nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); + if (IS_ERR(nop->vcc)) { + dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", + PTR_ERR(nop->vcc)); + } + nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; -- cgit From ad63ebfc3565bbdec87ee4e30e4d40d164c1d3b8 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:23 +0200 Subject: usb: phy: nop: Handle RESET for the PHY We expect the RESET line to be modeled as a regulator with supply name "reset". The regulator should be modeled such that enabling the regulator brings the PHY device out of RESET and disabling the regulator holds the device in RESET. They PHY will be held in RESET in .shutdown() and brought out of RESET in .init(). Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index fbdcfef7169b..6efc9b793333 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -40,6 +40,7 @@ struct nop_usb_xceiv { struct device *dev; struct clk *clk; struct regulator *vcc; + struct regulator *reset; }; static struct platform_device *pd; @@ -80,6 +81,12 @@ static int nop_init(struct usb_phy *phy) if (!IS_ERR(nop->clk)) clk_enable(nop->clk); + if (!IS_ERR(nop->reset)) { + /* De-assert RESET */ + if (regulator_enable(nop->reset)) + dev_err(phy->dev, "Failed to de-assert reset\n"); + } + return 0; } @@ -87,6 +94,12 @@ static void nop_shutdown(struct usb_phy *phy) { struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + if (!IS_ERR(nop->reset)) { + /* Assert RESET */ + if (regulator_disable(nop->reset)) + dev_err(phy->dev, "Failed to assert reset\n"); + } + if (!IS_ERR(nop->clk)) clk_disable(nop->clk); @@ -172,6 +185,12 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) PTR_ERR(nop->vcc)); } + nop->reset = devm_regulator_get(&pdev->dev, "reset"); + if (IS_ERR(nop->reset)) { + dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", + PTR_ERR(nop->reset)); + } + nop->dev = &pdev->dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; -- cgit From 90f4232f31f087f86667da03b1a4f3c90a32cb4a Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:24 +0200 Subject: usb: phy: nop: use new PHY API to register PHY We would need to support multiple PHYs of the same type so use the new PHY API usb_add_phy_dev() to register the PHY. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 6efc9b793333..fe7a46001854 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -198,12 +198,13 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) nop->phy.init = nop_init; nop->phy.shutdown = nop_shutdown; nop->phy.state = OTG_STATE_UNDEFINED; + nop->phy.type = type; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; - err = usb_add_phy(&nop->phy, type); + err = usb_add_phy_dev(&nop->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); -- cgit From 0eba387973f521e57f00584e5e840e5328a61dda Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:25 +0200 Subject: usb: phy: nop: Add device tree support and binding information The PHY clock, clock rate, VCC regulator and RESET regulator can now be provided via device tree. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/usb-nop-xceiv.txt | 34 +++++++++++++++++++++ drivers/usb/otg/nop-usb-xceiv.c | 35 +++++++++++++++++----- 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt new file mode 100644 index 000000000000..d7e272671c7e --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt @@ -0,0 +1,34 @@ +USB NOP PHY + +Required properties: +- compatible: should be usb-nop-xceiv + +Optional properties: +- clocks: phandle to the PHY clock. Use as per Documentation/devicetree + /bindings/clock/clock-bindings.txt + This property is required if clock-frequency is specified. + +- clock-names: Should be "main_clk" + +- clock-frequency: the clock frequency (in Hz) that the PHY clock must + be configured to. + +- vcc-supply: phandle to the regulator that provides RESET to the PHY. + +- reset-supply: phandle to the regulator that provides power to the PHY. + +Example: + + hsusb1_phy { + compatible = "usb-nop-xceiv"; + clock-frequency = <19200000>; + clocks = <&osc 0>; + clock-names = "main_clk"; + vcc-supply = <&hsusb1_vcc_regulator>; + reset-supply = <&hsusb1_reset_regulator>; + }; + +hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator +and expects that clock to be configured to 19.2MHz by the NOP PHY driver. +hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator +controls RESET. diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index fe7a46001854..b26b1c29194e 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -34,13 +34,14 @@ #include #include #include +#include struct nop_usb_xceiv { - struct usb_phy phy; - struct device *dev; - struct clk *clk; - struct regulator *vcc; - struct regulator *reset; + struct usb_phy phy; + struct device *dev; + struct clk *clk; + struct regulator *vcc; + struct regulator *reset; }; static struct platform_device *pd; @@ -140,10 +141,12 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) static int nop_usb_xceiv_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; struct nop_usb_xceiv *nop; enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; + u32 clk_rate = 0; nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); if (!nop) @@ -154,8 +157,16 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (!nop->phy.otg) return -ENOMEM; - if (pdata) + if (dev->of_node) { + struct device_node *node = dev->of_node; + + if (of_property_read_u32(node, "clock-frequency", &clk_rate)) + clk_rate = 0; + + } else if (pdata) { type = pdata->type; + clk_rate = pdata->clk_rate; + } nop->clk = devm_clk_get(&pdev->dev, "main_clk"); if (IS_ERR(nop->clk)) { @@ -163,8 +174,8 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) PTR_ERR(nop->clk)); } - if (!IS_ERR(nop->clk) && pdata && pdata->clk_rate) { - err = clk_set_rate(nop->clk, pdata->clk_rate); + if (!IS_ERR(nop->clk) && clk_rate) { + err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(&pdev->dev, "Error setting clock rate\n"); return err; @@ -237,12 +248,20 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id nop_xceiv_dt_ids[] = { + { .compatible = "usb-nop-xceiv" }, + { } +}; + +MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); + static struct platform_driver nop_usb_xceiv_driver = { .probe = nop_usb_xceiv_probe, .remove = nop_usb_xceiv_remove, .driver = { .name = "nop_usb_xceiv", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(nop_xceiv_dt_ids), }, }; -- cgit From b54b5f56531d9fcbb30908373ba842af4de6a26b Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Mar 2013 13:24:26 +0200 Subject: USB: phy: nop: Defer probe if device needs VCC/RESET Add 2 flags, needs_vcc and needs_reset to platform data. If the flag is set and the regulator couldn't be found then we bail out with -EPROBE_DEFER. For device tree boot we depend on presensce of vcc-supply/ reset-supply properties to decide if we should bail out with -EPROBE_DEFER or just continue in case the regulator can't be found. This is required for proper functionality in cases where the regulator is needed but is probed later than the PHY device. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/nop-usb-xceiv.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index b26b1c29194e..2b10cc969bbb 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -147,6 +147,8 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; u32 clk_rate = 0; + bool needs_vcc = false; + bool needs_reset = false; nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); if (!nop) @@ -163,9 +165,14 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; + needs_vcc = of_property_read_bool(node, "vcc-supply"); + needs_reset = of_property_read_bool(node, "reset-supply"); + } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; + needs_vcc = pdata->needs_vcc; + needs_reset = pdata->needs_reset; } nop->clk = devm_clk_get(&pdev->dev, "main_clk"); @@ -194,12 +201,16 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) if (IS_ERR(nop->vcc)) { dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); + if (needs_vcc) + return -EPROBE_DEFER; } nop->reset = devm_regulator_get(&pdev->dev, "reset"); if (IS_ERR(nop->reset)) { dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", PTR_ERR(nop->reset)); + if (needs_reset) + return -EPROBE_DEFER; } nop->dev = &pdev->dev; -- cgit From e36a0c870f7dbbfa7ed13cd83b79be00bcd00380 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 26 Feb 2013 20:03:27 +0530 Subject: usb: dwc3: omap: minor fixes to get dt working Includes few minor fixes in dwc3-omap like populating the compatible string in a correct way, extracting the utmi-mode property properly and changing the index of get_irq since irq of core is removed from hwmod entry. Also updated the documentation with dwc3-omap device tree binding information. Signed-off-by: Kishon Vijay Abraham I [ balbi@ti.com : fix a compile warning introduced by this commit ] Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/omap-usb.txt | 28 ++++++++++++++ drivers/usb/dwc3/dwc3-omap.c | 45 ++++++++++------------ 2 files changed, 49 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 1ef0ce71f8fa..1b9f55fd96c0 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -41,6 +41,34 @@ Board specific device node entry power = <50>; }; +OMAP DWC3 GLUE + - compatible : Should be "ti,dwc3" + - ti,hwmods : Should be "usb_otg_ss" + - reg : Address and length of the register set for the device. + - interrupts : The irq number of this device that is used to interrupt the + MPU + - #address-cells, #size-cells : Must be present if the device has sub-nodes + - utmi-mode : controls the source of UTMI/PIPE status for VBUS and OTG ID. + It should be set to "1" for HW mode and "2" for SW mode. + - ranges: the child address space are mapped 1:1 onto the parent address space + +Sub-nodes: +The dwc3 core should be added as subnode to omap dwc3 glue. +- dwc3 : + The binding details of dwc3 can be found in: + Documentation/devicetree/bindings/usb/dwc3.txt + +omap_dwc3 { + compatible = "ti,dwc3"; + ti,hwmods = "usb_otg_ss"; + reg = <0x4a020000 0x1ff>; + interrupts = <0 93 4>; + #address-cells = <1>; + #size-cells = <1>; + utmi-mode = <2>; + ranges; +}; + OMAP CONTROL USB Required properties: diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index afa05e3c9cf4..e1206b419932 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -316,11 +316,11 @@ static int dwc3_omap_probe(struct platform_device *pdev) struct resource *res; struct device *dev = &pdev->dev; - int size; int ret = -ENOMEM; int irq; - const u32 *utmi_mode; + int utmi_mode = 0; + u32 reg; void __iomem *base; @@ -334,13 +334,13 @@ static int dwc3_omap_probe(struct platform_device *pdev) platform_set_drvdata(pdev, omap); - irq = platform_get_irq(pdev, 1); + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory base resource\n"); return -EINVAL; @@ -387,25 +387,22 @@ static int dwc3_omap_probe(struct platform_device *pdev) reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); - utmi_mode = of_get_property(node, "utmi-mode", &size); - if (utmi_mode && size == sizeof(*utmi_mode)) { - reg |= *utmi_mode; - } else { - if (!pdata) { - dev_dbg(dev, "missing platform data\n"); - } else { - switch (pdata->utmi_mode) { - case DWC3_OMAP_UTMI_MODE_SW: - reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; - break; - case DWC3_OMAP_UTMI_MODE_HW: - reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; - break; - default: - dev_dbg(dev, "UNKNOWN utmi mode %d\n", - pdata->utmi_mode); - } - } + if (node) + of_property_read_u32(node, "utmi-mode", &utmi_mode); + else if (pdata) + utmi_mode = pdata->utmi_mode; + else + dev_dbg(dev, "missing platform data\n"); + + switch (utmi_mode) { + case DWC3_OMAP_UTMI_MODE_SW: + reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + break; + case DWC3_OMAP_UTMI_MODE_HW: + reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + break; + default: + dev_dbg(dev, "UNKNOWN utmi mode %d\n", utmi_mode); } dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg); @@ -465,7 +462,7 @@ static int dwc3_omap_remove(struct platform_device *pdev) static const struct of_device_id of_dwc3_match[] = { { - "ti,dwc3", + .compatible = "ti,dwc3" }, { }, }; -- cgit From 4495afcf713adb5bdb16504052952bdd0d11f90a Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 26 Feb 2013 20:03:28 +0530 Subject: usb: dwc3: omap: remove platform data associated with dwc3-omap omap5 is not going to have support for non-dt boot making the platform data associated with dwc3 useless. Removed it here. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 24 ++++++++++-------------- include/linux/platform_data/dwc3-omap.h | 4 ---- 2 files changed, 10 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index e1206b419932..43a248219aae 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -309,7 +309,6 @@ static int dwc3_omap_remove_core(struct device *dev, void *c) static int dwc3_omap_probe(struct platform_device *pdev) { - struct dwc3_omap_data *pdata = pdev->dev.platform_data; struct device_node *node = pdev->dev.of_node; struct dwc3_omap *omap; @@ -326,6 +325,11 @@ static int dwc3_omap_probe(struct platform_device *pdev) void __iomem *base; void *context; + if (!node) { + dev_err(dev, "device node not found\n"); + return -EINVAL; + } + omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL); if (!omap) { dev_err(dev, "not enough memory\n"); @@ -387,12 +391,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); - if (node) - of_property_read_u32(node, "utmi-mode", &utmi_mode); - else if (pdata) - utmi_mode = pdata->utmi_mode; - else - dev_dbg(dev, "missing platform data\n"); + of_property_read_u32(node, "utmi-mode", &utmi_mode); switch (utmi_mode) { case DWC3_OMAP_UTMI_MODE_SW: @@ -435,13 +434,10 @@ static int dwc3_omap_probe(struct platform_device *pdev) dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); - if (node) { - ret = of_platform_populate(node, NULL, NULL, dev); - if (ret) { - dev_err(&pdev->dev, - "failed to add create dwc3 core\n"); - return ret; - } + ret = of_platform_populate(node, NULL, NULL, dev); + if (ret) { + dev_err(&pdev->dev, "failed to create dwc3 core\n"); + return ret; } return 0; diff --git a/include/linux/platform_data/dwc3-omap.h b/include/linux/platform_data/dwc3-omap.h index ada401244e0b..1d36ca874cc8 100644 --- a/include/linux/platform_data/dwc3-omap.h +++ b/include/linux/platform_data/dwc3-omap.h @@ -41,7 +41,3 @@ enum dwc3_omap_utmi_mode { DWC3_OMAP_UTMI_MODE_HW, DWC3_OMAP_UTMI_MODE_SW, }; - -struct dwc3_omap_data { - enum dwc3_omap_utmi_mode utmi_mode; -}; -- cgit From 7eaf8f2a7da6506df0e6edc4fdb22678f0eb3602 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 26 Feb 2013 20:03:29 +0530 Subject: usb: dwc3: omap: stop using nop-usb-xceiv Now that we have drivers for omap-usb2 phy and omap-usb3 phy, stop using nop-usb-xceiv. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 67 -------------------------------------------- 1 file changed, 67 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 43a248219aae..3d343d92548a 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -52,7 +52,6 @@ #include #include -#include /* * All these registers belong to OMAP's Wrapper around the @@ -117,8 +116,6 @@ struct dwc3_omap { /* device lock */ spinlock_t lock; - struct platform_device *usb2_phy; - struct platform_device *usb3_phy; struct device *dev; int irq; @@ -193,60 +190,6 @@ void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) } EXPORT_SYMBOL_GPL(dwc3_omap_mailbox); -static int dwc3_omap_register_phys(struct dwc3_omap *omap) -{ - struct nop_usb_xceiv_platform_data pdata; - struct platform_device *pdev; - int ret; - - memset(&pdata, 0x00, sizeof(pdata)); - - pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); - if (!pdev) - return -ENOMEM; - - omap->usb2_phy = pdev; - pdata.type = USB_PHY_TYPE_USB2; - - ret = platform_device_add_data(omap->usb2_phy, &pdata, sizeof(pdata)); - if (ret) - goto err1; - - pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); - if (!pdev) { - ret = -ENOMEM; - goto err1; - } - - omap->usb3_phy = pdev; - pdata.type = USB_PHY_TYPE_USB3; - - ret = platform_device_add_data(omap->usb3_phy, &pdata, sizeof(pdata)); - if (ret) - goto err2; - - ret = platform_device_add(omap->usb2_phy); - if (ret) - goto err2; - - ret = platform_device_add(omap->usb3_phy); - if (ret) - goto err3; - - return 0; - -err3: - platform_device_del(omap->usb2_phy); - -err2: - platform_device_put(omap->usb3_phy); - -err1: - platform_device_put(omap->usb2_phy); - - return ret; -} - static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) { struct dwc3_omap *omap = _omap; @@ -356,12 +299,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) return -ENOMEM; } - ret = dwc3_omap_register_phys(omap); - if (ret) { - dev_err(dev, "couldn't register PHYs\n"); - return ret; - } - context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); if (!context) { dev_err(dev, "couldn't allocate dwc3 context memory\n"); @@ -445,10 +382,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) static int dwc3_omap_remove(struct platform_device *pdev) { - struct dwc3_omap *omap = platform_get_drvdata(pdev); - - platform_device_unregister(omap->usb2_phy); - platform_device_unregister(omap->usb3_phy); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); -- cgit From f07bd56bbdaa2340ebf46af9a37e7b2d1b4578e3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 14:52:24 +0200 Subject: usb: gadget: udc-core: allow udc class register gadget device Currently all UDC drivers are calling device_register() before calling usb_add_gadget_udc(). In order to avoid code duplication, we can allow udc-core.c register that device. However that would become a really large patch, so to cope with the meanwhile and allow us to write bite-sized patches, we're adding a flag which will be set by UDC driver once it removes the code for registering the gadget device. Once all are converted, the new flag will be removed. Reviewed-by: Tomasz Figa Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 23 +++++++++++++++++++---- include/linux/usb/gadget.h | 4 ++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 2a9cd369f71c..919505426ec1 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -173,6 +173,14 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) if (!udc) goto err1; + if (gadget->register_my_device) { + dev_set_name(&gadget->dev, "gadget"); + + ret = device_register(&gadget->dev); + if (ret) + goto err2; + } + device_initialize(&udc->dev); udc->dev.release = usb_udc_release; udc->dev.class = udc_class; @@ -180,7 +188,7 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) udc->dev.parent = parent; ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); if (ret) - goto err2; + goto err3; udc->gadget = gadget; @@ -189,18 +197,22 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) ret = device_add(&udc->dev); if (ret) - goto err3; + goto err4; mutex_unlock(&udc_lock); return 0; -err3: + +err4: list_del(&udc->list); mutex_unlock(&udc_lock); -err2: +err3: put_device(&udc->dev); +err2: + if (gadget->register_my_device) + put_device(&gadget->dev); err1: return ret; } @@ -254,6 +266,9 @@ found: kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); device_unregister(&udc->dev); + + if (gadget->register_my_device) + device_unregister(&gadget->dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 2e297e80d59a..fcd9ef8d3f70 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -494,6 +494,9 @@ struct usb_gadget_ops { * only supports HNP on a different root port. * @b_hnp_enable: OTG device feature flag, indicating that the A-Host * enabled HNP support. + * @register_my_device: Flag telling udc-core that UDC driver didn't + * register the gadget device to the driver model. Temporary until + * all UDC drivers are fixed up properly. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. @@ -531,6 +534,7 @@ struct usb_gadget { unsigned b_hnp_enable:1; unsigned a_hnp_support:1; unsigned a_alt_hnp_support:1; + unsigned register_my_device:1; const char *name; struct device dev; unsigned out_epnum; -- cgit From 1e1930bd3d9c6174eba1e3ca4135fd25ea3ad59c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 14:56:26 +0200 Subject: usb: dwc3: gadget: let udc-core manage gadget->dev We don't need to register that device ourselves if we simply set gadget->register_my_device. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 82e160e96fca..10bb161eec88 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2488,8 +2488,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err3; } - dev_set_name(&dwc->gadget.dev, "gadget"); - dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.max_speed = USB_SPEED_SUPER; dwc->gadget.speed = USB_SPEED_UNKNOWN; @@ -2501,6 +2499,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.dev.dma_parms = dwc->dev->dma_parms; dwc->gadget.dev.dma_mask = dwc->dev->dma_mask; dwc->gadget.dev.release = dwc3_gadget_release; + dwc->gadget.register_my_device = true; dwc->gadget.name = "dwc3-gadget"; /* @@ -2544,24 +2543,14 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc3_gadget_usb3_phy_suspend(dwc, false); } - ret = device_register(&dwc->gadget.dev); - if (ret) { - dev_err(dwc->dev, "failed to register gadget device\n"); - put_device(&dwc->gadget.dev); - goto err6; - } - ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err7; + goto err6; } return 0; -err7: - device_unregister(&dwc->gadget.dev); - err6: dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); free_irq(irq, dwc); @@ -2610,6 +2599,4 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), dwc->ctrl_req, dwc->ctrl_req_addr); - - device_unregister(&dwc->gadget.dev); } -- cgit From 5ed01c6400270dccb8c3574061ff3d163f0fe3fe Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 15:03:59 +0200 Subject: usb: musb: gadget: let udc-core manage gadget-dev By simply setting a flag, we can delete a little boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index be18537c5f14..cadb750921e9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1887,12 +1887,11 @@ int musb_gadget_setup(struct musb *musb) musb->g.speed = USB_SPEED_UNKNOWN; /* this "gadget" abstracts/virtualizes the controller */ - dev_set_name(&musb->g.dev, "gadget"); musb->g.dev.parent = musb->controller; musb->g.dev.dma_mask = musb->controller->dma_mask; musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; - + musb->g.register_my_device = true; musb->g.is_otg = 1; musb_g_init_endpoints(musb); @@ -1900,11 +1899,6 @@ int musb_gadget_setup(struct musb *musb) musb->is_active = 0; musb_platform_try_idle(musb, 0); - status = device_register(&musb->g.dev); - if (status != 0) { - put_device(&musb->g.dev); - return status; - } status = usb_add_gadget_udc(musb->controller, &musb->g); if (status) goto err; @@ -1919,8 +1913,6 @@ err: void musb_gadget_cleanup(struct musb *musb) { usb_del_gadget_udc(&musb->g); - if (musb->g.dev.parent) - device_unregister(&musb->g.dev); } /* -- cgit From 6dfc84fcb6eb32621c557e64f7520be27c0d636a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 15:07:29 +0200 Subject: usb: gadget: omap_udc: let udc-core manage gadget->dev By simply setting a flag, we drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index f8445653577f..c979272e7c86 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2632,10 +2632,9 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.max_speed = USB_SPEED_FULL; udc->gadget.name = driver_name; - device_initialize(&udc->gadget.dev); - dev_set_name(&udc->gadget.dev, "gadget"); udc->gadget.dev.release = omap_udc_release; udc->gadget.dev.parent = &odev->dev; + udc->gadget.register_my_device = true; if (use_dma) udc->gadget.dev.dma_mask = odev->dev.dma_mask; @@ -2912,14 +2911,12 @@ bad_on_1710: } create_proc_file(); - status = device_add(&udc->gadget.dev); + status = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (status) goto cleanup4; - status = usb_add_gadget_udc(&pdev->dev, &udc->gadget); - if (!status) - return status; - /* If fail, fall through */ + return 0; + cleanup4: remove_proc_file(); @@ -2990,7 +2987,6 @@ static int omap_udc_remove(struct platform_device *pdev) release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); - device_unregister(&udc->gadget.dev); wait_for_completion(&done); return 0; -- cgit From 12ad0fcaf2fbf3f48dd2b4dbaff372830aada8a2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 15:10:10 +0200 Subject: usb: gadget: amd5536udc: let udc-core manage gadget->dev By simply setting a flag, we drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 75973f33a4c8..eee01ea70f8c 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3080,7 +3080,6 @@ static void udc_pci_remove(struct pci_dev *pdev) if (dev->active) pci_disable_device(pdev); - device_unregister(&dev->gadget.dev); pci_set_drvdata(pdev, NULL); udc_remove(dev); @@ -3276,6 +3275,7 @@ static int udc_probe(struct udc *dev) dev->gadget.dev.release = gadget_release; dev->gadget.name = name; dev->gadget.max_speed = USB_SPEED_HIGH; + dev->gadget.register_my_device = true; /* init registers, interrupts, ... */ startup_registers(dev); @@ -3301,13 +3301,6 @@ static int udc_probe(struct udc *dev) if (retval) goto finished; - retval = device_register(&dev->gadget.dev); - if (retval) { - usb_del_gadget_udc(&dev->gadget); - put_device(&dev->gadget.dev); - goto finished; - } - /* timer init */ init_timer(&udc_timer); udc_timer.function = udc_timer_function; -- cgit From 2533beea9025254215be65cd1fca8da65019fd04 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 15:15:30 +0200 Subject: usb: gadget: at91_udc: let udc-core manage gadget->dev By simply setting a flag, we can remove some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/at91_udc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 45dd2929a671..47b7e58f8415 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1726,6 +1726,7 @@ static int at91udc_probe(struct platform_device *pdev) /* init software state */ udc = &controller; + udc->gadget.register_my_device = true; udc->gadget.dev.parent = dev; if (pdev->dev.of_node) at91udc_of_init(udc, pdev->dev.of_node); @@ -1780,13 +1781,7 @@ static int at91udc_probe(struct platform_device *pdev) DBG("clocks missing\n"); retval = -ENODEV; /* NOTE: we "know" here that refcounts on these are NOPs */ - goto fail0b; - } - - retval = device_register(&udc->gadget.dev); - if (retval < 0) { - put_device(&udc->gadget.dev); - goto fail0b; + goto fail1; } /* don't do anything until we have both gadget driver and VBUS */ @@ -1857,8 +1852,6 @@ fail3: fail2: free_irq(udc->udp_irq, udc); fail1: - device_unregister(&udc->gadget.dev); -fail0b: iounmap(udc->udp_baseaddr); fail0a: if (cpu_is_at91rm9200()) @@ -1892,8 +1885,6 @@ static int __exit at91udc_remove(struct platform_device *pdev) gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); - device_unregister(&udc->gadget.dev); - iounmap(udc->udp_baseaddr); if (cpu_is_at91rm9200()) -- cgit From 621c723eb71d2f02baafe20a3eaefc3a4dec7788 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 15:21:36 +0200 Subject: usb: gadget: atmel_usba_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index b66130c97269..2404d0c25668 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1900,9 +1900,9 @@ static int __init usba_udc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", (unsigned long)fifo->start, udc->fifo); - device_initialize(&udc->gadget.dev); udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; + udc->gadget.register_my_device = true; platform_set_drvdata(pdev, udc); @@ -1962,12 +1962,6 @@ static int __init usba_udc_probe(struct platform_device *pdev) } udc->irq = irq; - ret = device_add(&udc->gadget.dev); - if (ret) { - dev_dbg(&pdev->dev, "Could not add gadget: %d\n", ret); - goto err_device_add; - } - if (gpio_is_valid(pdata->vbus_pin)) { if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { udc->vbus_pin = pdata->vbus_pin; @@ -2007,9 +2001,6 @@ err_add_udc: gpio_free(udc->vbus_pin); } - device_unregister(&udc->gadget.dev); - -err_device_add: free_irq(irq, udc); err_request_irq: kfree(usba_ep); @@ -2053,8 +2044,6 @@ static int __exit usba_udc_remove(struct platform_device *pdev) clk_put(udc->hclk); clk_put(udc->pclk); - device_unregister(&udc->gadget.dev); - return 0; } -- cgit From 9b4ead05e7a3abf350d4ca1f7e0b71dc44f07f57 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:09:06 +0200 Subject: usb: gadget: bcm63xx_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/bcm63xx_udc.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 8cc8253f1100..c020b877219d 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2368,13 +2368,13 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) spin_lock_init(&udc->lock); INIT_WORK(&udc->ep0_wq, bcm63xx_ep0_process); - dev_set_name(&udc->gadget.dev, "gadget"); udc->gadget.ops = &bcm63xx_udc_ops; udc->gadget.name = dev_name(dev); udc->gadget.dev.parent = dev; udc->gadget.dev.release = bcm63xx_udc_gadget_release; udc->gadget.dev.dma_mask = dev->dma_mask; + udc->gadget.register_my_device = true; if (!pd->use_fullspeed && !use_fullspeed) udc->gadget.max_speed = USB_SPEED_HIGH; @@ -2414,17 +2414,12 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) } } - rc = device_register(&udc->gadget.dev); - if (rc) - goto out_uninit; - bcm63xx_udc_init_debugfs(udc); rc = usb_add_gadget_udc(dev, &udc->gadget); if (!rc) return 0; bcm63xx_udc_cleanup_debugfs(udc); - device_unregister(&udc->gadget.dev); out_uninit: bcm63xx_uninit_udc_hw(udc); return rc; @@ -2440,7 +2435,6 @@ static int bcm63xx_udc_remove(struct platform_device *pdev) bcm63xx_udc_cleanup_debugfs(udc); usb_del_gadget_udc(&udc->gadget); - device_unregister(&udc->gadget.dev); BUG_ON(udc->driver); platform_set_drvdata(pdev, NULL); -- cgit From 002cb13f4a6f3c28510575922a226a7a09ab6e91 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:10:16 +0200 Subject: usb: gadget: dummy_hcd: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 8cf0c0f6fa1f..a6950aa8f3be 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -983,16 +983,10 @@ static int dummy_udc_probe(struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; dum->gadget.max_speed = USB_SPEED_SUPER; + dum->gadget.register_my_device = true; - dev_set_name(&dum->gadget.dev, "gadget"); dum->gadget.dev.parent = &pdev->dev; dum->gadget.dev.release = dummy_gadget_release; - rc = device_register(&dum->gadget.dev); - if (rc < 0) { - put_device(&dum->gadget.dev); - return rc; - } - init_dummy_udc_hw(dum); rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget); @@ -1008,7 +1002,6 @@ static int dummy_udc_probe(struct platform_device *pdev) err_dev: usb_del_gadget_udc(&dum->gadget); err_udc: - device_unregister(&dum->gadget.dev); return rc; } @@ -1019,7 +1012,6 @@ static int dummy_udc_remove(struct platform_device *pdev) usb_del_gadget_udc(&dum->gadget); platform_set_drvdata(pdev, NULL); device_remove_file(&dum->gadget.dev, &dev_attr_function); - device_unregister(&dum->gadget.dev); return 0; } -- cgit From c07d1b63ac3c5f18f07739a8736633dd6998c944 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:11:38 +0200 Subject: usb: gadget: fsl_qe_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 034477ce77c6..0f78cd859d68 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2523,13 +2523,9 @@ static int qe_udc_probe(struct platform_device *ofdev) /* name: Identifies the controller hardware type. */ udc->gadget.name = driver_name; - - device_initialize(&udc->gadget.dev); - - dev_set_name(&udc->gadget.dev, "gadget"); - udc->gadget.dev.release = qe_udc_release; udc->gadget.dev.parent = &ofdev->dev; + udc->gadget.register_my_device = true; /* initialize qe_ep struct */ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) { @@ -2592,13 +2588,9 @@ static int qe_udc_probe(struct platform_device *ofdev) goto err5; } - ret = device_add(&udc->gadget.dev); - if (ret) - goto err6; - ret = usb_add_gadget_udc(&ofdev->dev, &udc->gadget); if (ret) - goto err7; + goto err6; dev_set_drvdata(&ofdev->dev, udc); dev_info(udc->dev, @@ -2606,8 +2598,6 @@ static int qe_udc_probe(struct platform_device *ofdev) (udc->soc_type == PORT_QE) ? "QE" : "CPM"); return 0; -err7: - device_unregister(&udc->gadget.dev); err6: free_irq(udc->usb_irq, udc); err5: @@ -2702,7 +2692,6 @@ static int qe_udc_remove(struct platform_device *ofdev) iounmap(udc->usb_regs); - device_unregister(&udc->gadget.dev); /* wait for release() of gadget.dev to free udc */ wait_for_completion(&done); -- cgit From eab35c4e6d952c91a413b408635ba6a9ec5fcf41 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:13:20 +0200 Subject: usb: gadget: fsl_udc_core: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 04d5fef1440c..9140a2daad87 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2524,9 +2524,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) udc_controller->gadget.dev.release = fsl_udc_release; udc_controller->gadget.dev.parent = &pdev->dev; udc_controller->gadget.dev.of_node = pdev->dev.of_node; - ret = device_register(&udc_controller->gadget.dev); - if (ret < 0) - goto err_free_irq; + udc_controller->gadget.register_my_device = true; if (!IS_ERR_OR_NULL(udc_controller->transceiver)) udc_controller->gadget.is_otg = 1; @@ -2559,7 +2557,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) DTD_ALIGNMENT, UDC_DMA_BOUNDARY); if (udc_controller->td_pool == NULL) { ret = -ENOMEM; - goto err_unregister; + goto err_free_irq; } ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget); @@ -2571,8 +2569,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) err_del_udc: dma_pool_destroy(udc_controller->td_pool); -err_unregister: - device_unregister(&udc_controller->gadget.dev); err_free_irq: free_irq(udc_controller->irq, udc_controller); err_iounmap: @@ -2622,7 +2618,6 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) if (pdata->operating_mode == FSL_USB2_DR_DEVICE) release_mem_region(res->start, resource_size(res)); - device_unregister(&udc_controller->gadget.dev); /* free udc --wait for the release() finished */ wait_for_completion(&done); -- cgit From fc84d2fbe776f5352c3a981a5250a3ad83789f72 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:14:45 +0200 Subject: usb: gadget: fusb300_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 066cb89376de..d29017218b01 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1422,15 +1422,12 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ops = &fusb300_gadget_ops; - device_initialize(&fusb300->gadget.dev); - - dev_set_name(&fusb300->gadget.dev, "gadget"); - fusb300->gadget.max_speed = USB_SPEED_HIGH; fusb300->gadget.dev.parent = &pdev->dev; fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; fusb300->gadget.dev.release = pdev->dev.release; fusb300->gadget.name = udc_name; + fusb300->gadget.register_my_device = true; fusb300->reg = reg; ret = request_irq(ires->start, fusb300_irq, IRQF_SHARED, @@ -1478,19 +1475,10 @@ static int __init fusb300_probe(struct platform_device *pdev) if (ret) goto err_add_udc; - ret = device_add(&fusb300->gadget.dev); - if (ret) { - pr_err("device_add error (%d)\n", ret); - goto err_add_device; - } - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); return 0; -err_add_device: - usb_del_gadget_udc(&fusb300->gadget); - err_add_udc: fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); -- cgit From 5637bf5b7a91804fe0230dff70024df078786090 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:17:45 +0200 Subject: usb: gadget: goku_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 10 +--------- drivers/usb/gadget/goku_udc.h | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 85742d4c67df..b4ea2cf465a6 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1716,8 +1716,6 @@ static void goku_remove(struct pci_dev *pdev) pci_resource_len (pdev, 0)); if (dev->enabled) pci_disable_device(pdev); - if (dev->registered) - device_unregister(&dev->gadget.dev); pci_set_drvdata(pdev, NULL); dev->regs = NULL; @@ -1756,11 +1754,11 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_FULL; /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&dev->gadget.dev, "gadget"); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; + dev->gadget.register_my_device = true; /* now all the pci goodies ... */ retval = pci_enable_device(pdev); @@ -1810,12 +1808,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); #endif - retval = device_register(&dev->gadget.dev); - if (retval) { - put_device(&dev->gadget.dev); - goto err; - } - dev->registered = 1; retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget); if (retval) goto err; diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h index b4470d2b1d86..86d2adafe149 100644 --- a/drivers/usb/gadget/goku_udc.h +++ b/drivers/usb/gadget/goku_udc.h @@ -250,8 +250,7 @@ struct goku_udc { got_region:1, req_config:1, configured:1, - enabled:1, - registered:1; + enabled:1; /* pci state used to access those endpoints */ struct pci_dev *pdev; -- cgit From 0b3702c62e41f3707cb8ba68bf46561597a6f0af Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:22:57 +0200 Subject: usb: gadget: imx_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/imx_udc.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 5bd930d779b9..435b20346ead 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1461,15 +1461,10 @@ static int __init imx_udc_probe(struct platform_device *pdev) imx_usb->clk = clk; imx_usb->dev = &pdev->dev; - device_initialize(&imx_usb->gadget.dev); - + imx_usb->gadget.register_my_device = true; imx_usb->gadget.dev.parent = &pdev->dev; imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask; - ret = device_add(&imx_usb->gadget.dev); - if (retval) - goto fail4; - platform_set_drvdata(pdev, imx_usb); usb_init_data(imx_usb); @@ -1481,11 +1476,9 @@ static int __init imx_udc_probe(struct platform_device *pdev) ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget); if (ret) - goto fail5; + goto fail4; return 0; -fail5: - device_unregister(&imx_usb->gadget.dev); fail4: for (i = 0; i < IMX_USB_NB_EP + 1; i++) free_irq(imx_usb->usbd_int[i], imx_usb); @@ -1509,7 +1502,6 @@ static int __exit imx_udc_remove(struct platform_device *pdev) int i; usb_del_gadget_udc(&imx_usb->gadget); - device_unregister(&imx_usb->gadget.dev); imx_udc_disable(imx_usb); del_timer(&imx_usb->timer); -- cgit From e0c9e4739a6f9217f35f1a59807a2f19a4cd7cdd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:26:46 +0200 Subject: usb: gadget: lpc32xx_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index aa04089d6899..329e1c5f0ef9 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3090,6 +3090,7 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) /* init software state */ udc->gadget.dev.parent = dev; + udc->gadget.register_my_device = true; udc->pdev = pdev; udc->dev = &pdev->dev; udc->enabled = 0; @@ -3248,12 +3249,6 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) udc_disable(udc); udc_reinit(udc); - retval = device_register(&udc->gadget.dev); - if (retval < 0) { - dev_err(udc->dev, "Device registration failure\n"); - goto dev_register_fail; - } - /* Request IRQs - low and high priority USB device IRQs are routed to * the same handler, while the DMA interrupt is routed elsewhere */ retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq, @@ -3320,8 +3315,6 @@ irq_dev_fail: irq_hp_fail: free_irq(udc->udp_irq[IRQ_USB_LP], udc); irq_lp_fail: - device_unregister(&udc->gadget.dev); -dev_register_fail: dma_pool_destroy(udc->dd_cache); dma_alloc_fail: dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, @@ -3376,8 +3369,6 @@ static int lpc32xx_udc_remove(struct platform_device *pdev) free_irq(udc->udp_irq[IRQ_USB_HP], udc); free_irq(udc->udp_irq[IRQ_USB_LP], udc); - device_unregister(&udc->gadget.dev); - clk_disable(udc->usb_otg_clk); clk_put(udc->usb_otg_clk); clk_disable(udc->usb_slv_clk); -- cgit From 96d20c32f68b058b4430a6f711124511a2d9b361 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:35:12 +0200 Subject: usb: gadget: m66592-udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index c1b8c2dd808d..43ad70dff74d 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1538,7 +1538,6 @@ static int __exit m66592_remove(struct platform_device *pdev) struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); usb_del_gadget_udc(&m66592->gadget); - device_del(&m66592->gadget.dev); del_timer_sync(&m66592->timer); iounmap(m66592->reg); @@ -1608,13 +1607,12 @@ static int __init m66592_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, m66592); m66592->gadget.ops = &m66592_gadget_ops; - device_initialize(&m66592->gadget.dev); - dev_set_name(&m66592->gadget.dev, "gadget"); m66592->gadget.max_speed = USB_SPEED_HIGH; m66592->gadget.dev.parent = &pdev->dev; m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; m66592->gadget.dev.release = pdev->dev.release; m66592->gadget.name = udc_name; + m66592->gadget.register_my_device = true; init_timer(&m66592->timer); m66592->timer.function = m66592_timer; @@ -1674,12 +1672,6 @@ static int __init m66592_probe(struct platform_device *pdev) init_controller(m66592); - ret = device_add(&m66592->gadget.dev); - if (ret) { - pr_err("device_add error (%d)\n", ret); - goto err_device_add; - } - ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); if (ret) goto err_add_udc; @@ -1688,9 +1680,6 @@ static int __init m66592_probe(struct platform_device *pdev) return 0; err_add_udc: - device_del(&m66592->gadget.dev); - -err_device_add: m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); clean_up3: -- cgit From 7a071890b467e3b820b6afb13f2a877a249ae8f9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:37:24 +0200 Subject: usb: gadget: mv_u3d_core: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index b5cea273c957..565addcd3956 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1792,8 +1792,6 @@ static int mv_u3d_remove(struct platform_device *dev) clk_put(u3d->clk); - device_unregister(&u3d->gadget.dev); - platform_set_drvdata(dev, NULL); kfree(u3d); @@ -1957,15 +1955,11 @@ static int mv_u3d_probe(struct platform_device *dev) u3d->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&u3d->gadget.dev, "gadget"); u3d->gadget.dev.parent = &dev->dev; u3d->gadget.dev.dma_mask = dev->dev.dma_mask; u3d->gadget.dev.release = mv_u3d_gadget_release; u3d->gadget.name = driver_name; /* gadget name */ - - retval = device_register(&u3d->gadget.dev); - if (retval) - goto err_register_gadget_device; + u3d->gadget.register_my_device = true; mv_u3d_eps_init(u3d); @@ -1991,8 +1985,6 @@ static int mv_u3d_probe(struct platform_device *dev) return 0; err_unregister: - device_unregister(&u3d->gadget.dev); -err_register_gadget_device: free_irq(u3d->irq, &dev->dev); err_request_irq: err_get_irq: -- cgit From 2cd807e7a8ee18d13fd06e84ef9f485a5c28a521 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:38:19 +0200 Subject: usb: gadget: mv_u3d_core: fix a compile warning Fix the following compile warning: mv_u3d_core.c:1766:12: warning: 'mv_u3d_remove' \ defined but not used [-Wunused-function] Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index 565addcd3956..734ade11505f 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -2072,7 +2072,7 @@ static void mv_u3d_shutdown(struct platform_device *dev) static struct platform_driver mv_u3d_driver = { .probe = mv_u3d_probe, - .remove = __exit_p(mv_u3d_remove), + .remove = mv_u3d_remove, .shutdown = mv_u3d_shutdown, .driver = { .owner = THIS_MODULE, -- cgit From 5dc7b773657d9e217eaacd51f74e9cea81260088 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:43:47 +0200 Subject: usb: gadget: mv_udc_core: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index c8cf959057fe..a7afdfb413b3 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2138,8 +2138,6 @@ static int mv_udc_remove(struct platform_device *pdev) mv_udc_disable(udc); - device_unregister(&udc->gadget.dev); - /* free dev, wait for the release() finished */ wait_for_completion(udc->done); @@ -2311,15 +2309,11 @@ static int mv_udc_probe(struct platform_device *pdev) udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&udc->gadget.dev, "gadget"); udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ - - retval = device_register(&udc->gadget.dev); - if (retval) - goto err_destroy_dma; + udc->gadget.register_my_device = true; eps_init(udc); @@ -2342,7 +2336,7 @@ static int mv_udc_probe(struct platform_device *pdev) if (!udc->qwork) { dev_err(&pdev->dev, "cannot create workqueue\n"); retval = -ENOMEM; - goto err_unregister; + goto err_destroy_dma; } INIT_WORK(&udc->vbus_work, mv_udc_vbus_work); @@ -2370,8 +2364,6 @@ static int mv_udc_probe(struct platform_device *pdev) err_create_workqueue: destroy_workqueue(udc->qwork); -err_unregister: - device_unregister(&udc->gadget.dev); err_destroy_dma: dma_pool_destroy(udc->dtd_pool); err_free_dma: -- cgit From c9f9c849ae873d592823d31c8e1dcade5c46fe14 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:48:12 +0200 Subject: usb: gadget: net2272: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index d226058e3b88..635248f42dcd 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2209,7 +2209,6 @@ net2272_remove(struct net2272 *dev) free_irq(dev->irq, dev); iounmap(dev->base_addr); - device_unregister(&dev->gadget.dev); device_remove_file(dev->dev, &dev_attr_registers); dev_info(dev->dev, "unbind\n"); @@ -2236,11 +2235,11 @@ static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq) ret->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&ret->gadget.dev, "gadget"); ret->gadget.dev.parent = dev; ret->gadget.dev.dma_mask = dev->dma_mask; ret->gadget.dev.release = net2272_gadget_release; ret->gadget.name = driver_name; + ret->gadget.register_my_device = true; return ret; } @@ -2275,12 +2274,9 @@ net2272_probe_fin(struct net2272 *dev, unsigned int irqflags) dma_mode_string()); dev_info(dev->dev, "version: %s\n", driver_vers); - ret = device_register(&dev->gadget.dev); - if (ret) - goto err_irq; ret = device_create_file(dev->dev, &dev_attr_registers); if (ret) - goto err_dev_reg; + goto err_irq; ret = usb_add_gadget_udc(dev->dev, &dev->gadget); if (ret) @@ -2290,8 +2286,6 @@ net2272_probe_fin(struct net2272 *dev, unsigned int irqflags) err_add_udc: device_remove_file(dev->dev, &dev_attr_registers); - err_dev_reg: - device_unregister(&dev->gadget.dev); err_irq: free_irq(dev->irq, dev); err: -- cgit From 654dfe4d2ab0d00573dcb0d7d7c957165dc4d9f2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:52:14 +0200 Subject: usb: gadget: net2280: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index a1b650e11339..c55af4293509 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2679,7 +2679,6 @@ static void net2280_remove (struct pci_dev *pdev) pci_resource_len (pdev, 0)); if (dev->enabled) pci_disable_device (pdev); - device_unregister (&dev->gadget.dev); device_remove_file (&pdev->dev, &dev_attr_registers); pci_set_drvdata (pdev, NULL); @@ -2711,11 +2710,11 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&dev->gadget.dev, "gadget"); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; + dev->gadget.register_my_device = true; /* now all the pci goodies ... */ if (pci_enable_device (pdev) < 0) { @@ -2823,8 +2822,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) use_dma ? (use_dma_chaining ? "chaining" : "enabled") : "disabled"); - retval = device_register (&dev->gadget.dev); - if (retval) goto done; retval = device_create_file (&pdev->dev, &dev_attr_registers); if (retval) goto done; -- cgit From 5a8a375714d007f556c81b739aa69e3c745d8015 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 16:56:35 +0200 Subject: usb: gadget: pch_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index a787a8ef672b..703214543dd4 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -358,7 +358,6 @@ struct pch_udc_dev { prot_stall:1, irq_registered:1, mem_region:1, - registered:1, suspended:1, connected:1, vbus_session:1, @@ -3078,8 +3077,6 @@ static void pch_udc_remove(struct pci_dev *pdev) pci_resource_len(pdev, PCH_UDC_PCI_BAR)); if (dev->active) pci_disable_device(pdev); - if (dev->registered) - device_unregister(&dev->gadget.dev); kfree(dev); pci_set_drvdata(pdev, NULL); } @@ -3196,17 +3193,12 @@ static int pch_udc_probe(struct pci_dev *pdev, if (retval) goto finished; - dev_set_name(&dev->gadget.dev, "gadget"); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = KBUILD_MODNAME; dev->gadget.max_speed = USB_SPEED_HIGH; - - retval = device_register(&dev->gadget.dev); - if (retval) - goto finished; - dev->registered = 1; + dev->gadget.register_my_device = true; /* Put the device in disconnected state till a driver is bound */ pch_udc_set_disconnect(dev); -- cgit From 80bf5343decf65d9e4141143d49e6ed381565cbf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:01:28 +0200 Subject: usb: gadget: r8a66597-udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/r8a66597-udc.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index f46a1b77ce3e..ae94c0eaf633 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1837,7 +1837,6 @@ static int __exit r8a66597_remove(struct platform_device *pdev) clk_put(r8a66597->clk); } - device_unregister(&r8a66597->gadget.dev); kfree(r8a66597); return 0; } @@ -1915,17 +1914,12 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; r8a66597->gadget.ops = &r8a66597_gadget_ops; - dev_set_name(&r8a66597->gadget.dev, "gadget"); r8a66597->gadget.max_speed = USB_SPEED_HIGH; r8a66597->gadget.dev.parent = &pdev->dev; r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; r8a66597->gadget.dev.release = pdev->dev.release; r8a66597->gadget.name = udc_name; - ret = device_register(&r8a66597->gadget.dev); - if (ret < 0) { - dev_err(&pdev->dev, "device_register failed\n"); - goto clean_up; - } + r8a66597->gadget.register_my_device = true; init_timer(&r8a66597->timer); r8a66597->timer.function = r8a66597_timer; @@ -1939,7 +1933,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); ret = PTR_ERR(r8a66597->clk); - goto clean_up_dev; + goto clean_up; } clk_enable(r8a66597->clk); } @@ -2007,8 +2001,6 @@ clean_up2: clk_disable(r8a66597->clk); clk_put(r8a66597->clk); } -clean_up_dev: - device_unregister(&r8a66597->gadget.dev); clean_up: if (r8a66597) { if (r8a66597->sudmac_reg) -- cgit From b8d833a327aaed6637398446ec8a3e555b3ddd11 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:03:10 +0200 Subject: usb: gadget: s3c-hsotg: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Reviewed-by: Tomasz Figa Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index c26564f29a2c..5fbd233eb6a0 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3567,17 +3567,13 @@ static int s3c_hsotg_probe(struct platform_device *pdev) dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); - device_initialize(&hsotg->gadget.dev); - - dev_set_name(&hsotg->gadget.dev, "gadget"); - hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); - hsotg->gadget.dev.parent = dev; hsotg->gadget.dev.dma_mask = dev->dma_mask; hsotg->gadget.dev.release = s3c_hsotg_release; + hsotg->gadget.register_my_device = true; /* reset the system */ @@ -3658,12 +3654,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) s3c_hsotg_phy_disable(hsotg); - ret = device_add(&hsotg->gadget.dev); - if (ret) { - put_device(&hsotg->gadget.dev); - goto err_ep_mem; - } - ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); if (ret) goto err_ep_mem; @@ -3702,10 +3692,8 @@ static int s3c_hsotg_remove(struct platform_device *pdev) } s3c_hsotg_phy_disable(hsotg); - clk_disable_unprepare(hsotg->clk); - device_unregister(&hsotg->gadget.dev); return 0; } -- cgit From 40ed30cff5957d15dcd2638c6f48fae839a3100a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:04:56 +0200 Subject: usb: gadget: s3c-hsudc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 458965a1b138..c4ff747f53fc 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1303,18 +1303,16 @@ static int s3c_hsudc_probe(struct platform_device *pdev) spin_lock_init(&hsudc->lock); - dev_set_name(&hsudc->gadget.dev, "gadget"); - hsudc->gadget.max_speed = USB_SPEED_HIGH; hsudc->gadget.ops = &s3c_hsudc_gadget_ops; hsudc->gadget.name = dev_name(dev); hsudc->gadget.dev.parent = dev; hsudc->gadget.dev.dma_mask = dev->dma_mask; hsudc->gadget.ep0 = &hsudc->ep[0].ep; - hsudc->gadget.is_otg = 0; hsudc->gadget.is_a_peripheral = 0; hsudc->gadget.speed = USB_SPEED_UNKNOWN; + hsudc->gadget.register_my_device = true; s3c_hsudc_setup_ep(hsudc); @@ -1345,12 +1343,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) disable_irq(hsudc->irq); local_irq_enable(); - ret = device_register(&hsudc->gadget.dev); - if (ret) { - put_device(&hsudc->gadget.dev); - goto err_add_device; - } - ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); if (ret) goto err_add_udc; @@ -1359,7 +1351,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) return 0; err_add_udc: - device_unregister(&hsudc->gadget.dev); err_add_device: clk_disable(hsudc->uclk); err_res: -- cgit From b1e1eaba2916427d25fbd411cd863052836560ff Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:06:42 +0200 Subject: usb: gadget: s3c2410_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 08f89652533b..c4134948dd9e 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1824,16 +1824,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev) goto err_mem; } - device_initialize(&udc->gadget.dev); udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - - /* Bind the driver */ - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); - goto err_device_add; - } + udc->gadget.register_my_device = true; the_controller = udc; platform_set_drvdata(pdev, udc); @@ -1923,8 +1916,6 @@ err_gpio_claim: err_int: free_irq(IRQ_USBD, udc); err_map: - device_unregister(&udc->gadget.dev); -err_device_add: iounmap(base_addr); err_mem: release_mem_region(rsrc_start, rsrc_len); @@ -1946,7 +1937,6 @@ static int s3c2410_udc_remove(struct platform_device *pdev) return -EBUSY; usb_del_gadget_udc(&udc->gadget); - device_unregister(&udc->gadget.dev); debugfs_remove(udc->regs_info); if (udc_info && !udc_info->udc_command && -- cgit From 0972ef71b4841a59fab6f998d6e6c2c684443583 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:08:01 +0200 Subject: usb: renesas_usbhs: gadget: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 78fca978b2d0..5d5fab0ad0d1 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -976,15 +976,12 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) /* * init gadget */ - dev_set_name(&gpriv->gadget.dev, "gadget"); gpriv->gadget.dev.parent = dev; gpriv->gadget.dev.release = usbhs_mod_gadget_release; gpriv->gadget.name = "renesas_usbhs_udc"; gpriv->gadget.ops = &usbhsg_gadget_ops; gpriv->gadget.max_speed = USB_SPEED_HIGH; - ret = device_register(&gpriv->gadget.dev); - if (ret < 0) - goto err_add_udc; + gpriv->gadget.register_my_device = true; INIT_LIST_HEAD(&gpriv->gadget.ep_list); @@ -1014,15 +1011,13 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ret = usb_add_gadget_udc(dev, &gpriv->gadget); if (ret) - goto err_register; + goto err_add_udc; dev_info(dev, "gadget probed\n"); return 0; -err_register: - device_unregister(&gpriv->gadget.dev); err_add_udc: kfree(gpriv->uep); @@ -1038,8 +1033,6 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv) usb_del_gadget_udc(&gpriv->gadget); - device_unregister(&gpriv->gadget.dev); - kfree(gpriv->uep); kfree(gpriv); } -- cgit From b73f5a2a0a2b2ff10d941e35c2ff08fcc04a9862 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:28:30 +0200 Subject: usb: gadget: pxa25x_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d0f37484b6b0..8996fcb053ef 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2138,16 +2138,9 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->timer.function = udc_watchdog; dev->timer.data = (unsigned long) dev; - device_initialize(&dev->gadget.dev); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - - retval = device_add(&dev->gadget.dev); - if (retval) { - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - goto err_device_add; - } + dev->gadget.register_my_device = true; the_controller = dev; platform_set_drvdata(pdev, dev); @@ -2199,8 +2192,6 @@ lubbock_fail0: free_irq(irq, dev); #endif err_irq1: - device_unregister(&dev->gadget.dev); - err_device_add: if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: @@ -2226,7 +2217,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) return -EBUSY; usb_del_gadget_udc(&dev->gadget); - device_unregister(&dev->gadget.dev); dev->pullup = 0; pullup(dev); -- cgit From 45f596a6d776532f03135d48f10a1164006f9466 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:29:39 +0200 Subject: usb: gadget: pxa27x_udc: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Acked-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 2fc867652ef5..1c5bfaafa6c8 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1871,7 +1871,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g, udc->driver = NULL; - if (!IS_ERR_OR_NULL(udc->transceiver)) return otg_set_peripheral(udc->transceiver->otg, NULL); return 0; @@ -2456,9 +2455,9 @@ static int __init pxa_udc_probe(struct platform_device *pdev) goto err_map; } - device_initialize(&udc->gadget.dev); udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = NULL; + udc->gadget.register_my_device = true; udc->vbus_sensed = 0; the_controller = udc; @@ -2475,12 +2474,6 @@ static int __init pxa_udc_probe(struct platform_device *pdev) goto err_irq; } - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(udc->dev, "device_add error %d\n", retval); - goto err_dev_add; - } - retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (retval) goto err_add_udc; @@ -2490,8 +2483,6 @@ static int __init pxa_udc_probe(struct platform_device *pdev) return 0; err_add_udc: - device_unregister(&udc->gadget.dev); -err_dev_add: free_irq(udc->irq, udc); err_irq: iounmap(udc->regs); @@ -2512,7 +2503,6 @@ static int __exit pxa_udc_remove(struct platform_device *_dev) int gpio = udc->mach->gpio_pullup; usb_del_gadget_udc(&udc->gadget); - device_del(&udc->gadget.dev); usb_gadget_unregister_driver(udc->driver); free_irq(udc->irq, udc); pxa_cleanup_debugfs(udc); -- cgit From dc9e2873b740331b186b8f315fd18bbc97108d2e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:36:39 +0200 Subject: usb: chipidea: let udc-core manage gadget->dev By simply setting a flag, we can drop some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f64fbea1cf20..e95e8bbde988 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1717,11 +1717,11 @@ static int udc_start(struct ci13xxx *ci) INIT_LIST_HEAD(&ci->gadget.ep_list); - dev_set_name(&ci->gadget.dev, "gadget"); ci->gadget.dev.dma_mask = dev->dma_mask; ci->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask; ci->gadget.dev.parent = dev; ci->gadget.dev.release = udc_release; + ci->gadget.register_my_device = true; /* alloc resources */ ci->qh_pool = dma_pool_create("ci13xxx_qh", dev, @@ -1761,15 +1761,9 @@ static int udc_start(struct ci13xxx *ci) hw_enable_vbus_intr(ci); } - retval = device_register(&ci->gadget.dev); - if (retval) { - put_device(&ci->gadget.dev); - goto put_transceiver; - } - retval = dbg_create_files(ci->dev); if (retval) - goto unreg_device; + goto put_transceiver; if (!IS_ERR_OR_NULL(ci->transceiver)) { retval = otg_set_peripheral(ci->transceiver->otg, @@ -1797,8 +1791,6 @@ remove_trans: dev_err(dev, "error = %i\n", retval); remove_dbg: dbg_remove_files(ci->dev); -unreg_device: - device_unregister(&ci->gadget.dev); put_transceiver: if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) usb_put_phy(ci->transceiver); @@ -1837,7 +1829,6 @@ static void udc_stop(struct ci13xxx *ci) usb_put_phy(ci->transceiver); } dbg_remove_files(ci->dev); - device_unregister(&ci->gadget.dev); /* my kobject is dynamic, I swear! */ memset(&ci->gadget, 0, sizeof(ci->gadget)); } -- cgit From 7bce401cc6db5508ef2517e45bd8caf7ce0a15ee Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:41:00 +0200 Subject: usb: gadget: drop now unnecessary flag We don't need the ->register_my_device flag anymore because all UDC drivers have been properly converted. Let's remove every history of it. Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 1 - drivers/usb/dwc3/gadget.c | 1 - drivers/usb/gadget/amd5536udc.c | 1 - drivers/usb/gadget/at91_udc.c | 1 - drivers/usb/gadget/atmel_usba_udc.c | 1 - drivers/usb/gadget/bcm63xx_udc.c | 1 - drivers/usb/gadget/dummy_hcd.c | 1 - drivers/usb/gadget/fsl_qe_udc.c | 1 - drivers/usb/gadget/fsl_udc_core.c | 1 - drivers/usb/gadget/fusb300_udc.c | 1 - drivers/usb/gadget/goku_udc.c | 1 - drivers/usb/gadget/imx_udc.c | 1 - drivers/usb/gadget/lpc32xx_udc.c | 1 - drivers/usb/gadget/m66592-udc.c | 1 - drivers/usb/gadget/mv_u3d_core.c | 1 - drivers/usb/gadget/mv_udc_core.c | 1 - drivers/usb/gadget/net2272.c | 1 - drivers/usb/gadget/net2280.c | 1 - drivers/usb/gadget/omap_udc.c | 1 - drivers/usb/gadget/pch_udc.c | 1 - drivers/usb/gadget/pxa25x_udc.c | 1 - drivers/usb/gadget/pxa27x_udc.c | 1 - drivers/usb/gadget/r8a66597-udc.c | 1 - drivers/usb/gadget/s3c-hsotg.c | 1 - drivers/usb/gadget/s3c-hsudc.c | 1 - drivers/usb/gadget/s3c2410_udc.c | 1 - drivers/usb/gadget/udc-core.c | 18 +++++++----------- drivers/usb/musb/musb_gadget.c | 1 - drivers/usb/renesas_usbhs/mod_gadget.c | 1 - include/linux/usb/gadget.h | 4 ---- 30 files changed, 7 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index e95e8bbde988..1b65ac8f3c9b 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1721,7 +1721,6 @@ static int udc_start(struct ci13xxx *ci) ci->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask; ci->gadget.dev.parent = dev; ci->gadget.dev.release = udc_release; - ci->gadget.register_my_device = true; /* alloc resources */ ci->qh_pool = dma_pool_create("ci13xxx_qh", dev, diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 10bb161eec88..65493b6cd5a6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2499,7 +2499,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.dev.dma_parms = dwc->dev->dma_parms; dwc->gadget.dev.dma_mask = dwc->dev->dma_mask; dwc->gadget.dev.release = dwc3_gadget_release; - dwc->gadget.register_my_device = true; dwc->gadget.name = "dwc3-gadget"; /* diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index eee01ea70f8c..eec4461fb45f 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3275,7 +3275,6 @@ static int udc_probe(struct udc *dev) dev->gadget.dev.release = gadget_release; dev->gadget.name = name; dev->gadget.max_speed = USB_SPEED_HIGH; - dev->gadget.register_my_device = true; /* init registers, interrupts, ... */ startup_registers(dev); diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 47b7e58f8415..9936de9bbe50 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1726,7 +1726,6 @@ static int at91udc_probe(struct platform_device *pdev) /* init software state */ udc = &controller; - udc->gadget.register_my_device = true; udc->gadget.dev.parent = dev; if (pdev->dev.of_node) at91udc_of_init(udc, pdev->dev.of_node); diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 2404d0c25668..41518e612808 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1902,7 +1902,6 @@ static int __init usba_udc_probe(struct platform_device *pdev) udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - udc->gadget.register_my_device = true; platform_set_drvdata(pdev, udc); diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index c020b877219d..d4f73e1b37e6 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2374,7 +2374,6 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) udc->gadget.dev.parent = dev; udc->gadget.dev.release = bcm63xx_udc_gadget_release; udc->gadget.dev.dma_mask = dev->dma_mask; - udc->gadget.register_my_device = true; if (!pd->use_fullspeed && !use_fullspeed) udc->gadget.max_speed = USB_SPEED_HIGH; diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a6950aa8f3be..c4f27d5a2b9c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -983,7 +983,6 @@ static int dummy_udc_probe(struct platform_device *pdev) dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; dum->gadget.max_speed = USB_SPEED_SUPER; - dum->gadget.register_my_device = true; dum->gadget.dev.parent = &pdev->dev; dum->gadget.dev.release = dummy_gadget_release; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 0f78cd859d68..0e7531bd33f4 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2525,7 +2525,6 @@ static int qe_udc_probe(struct platform_device *ofdev) udc->gadget.name = driver_name; udc->gadget.dev.release = qe_udc_release; udc->gadget.dev.parent = &ofdev->dev; - udc->gadget.register_my_device = true; /* initialize qe_ep struct */ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) { diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 9140a2daad87..f33b9005eeac 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2524,7 +2524,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) udc_controller->gadget.dev.release = fsl_udc_release; udc_controller->gadget.dev.parent = &pdev->dev; udc_controller->gadget.dev.of_node = pdev->dev.of_node; - udc_controller->gadget.register_my_device = true; if (!IS_ERR_OR_NULL(udc_controller->transceiver)) udc_controller->gadget.is_otg = 1; diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index d29017218b01..2d3c8b351f42 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1427,7 +1427,6 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; fusb300->gadget.dev.release = pdev->dev.release; fusb300->gadget.name = udc_name; - fusb300->gadget.register_my_device = true; fusb300->reg = reg; ret = request_irq(ires->start, fusb300_irq, IRQF_SHARED, diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index b4ea2cf465a6..8a6c66618bd3 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1758,7 +1758,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; - dev->gadget.register_my_device = true; /* now all the pci goodies ... */ retval = pci_enable_device(pdev); diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 435b20346ead..9c5b7451a7d1 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1461,7 +1461,6 @@ static int __init imx_udc_probe(struct platform_device *pdev) imx_usb->clk = clk; imx_usb->dev = &pdev->dev; - imx_usb->gadget.register_my_device = true; imx_usb->gadget.dev.parent = &pdev->dev; imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask; diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 329e1c5f0ef9..67c3ef9d9bed 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3090,7 +3090,6 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) /* init software state */ udc->gadget.dev.parent = dev; - udc->gadget.register_my_device = true; udc->pdev = pdev; udc->dev = &pdev->dev; udc->enabled = 0; diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 43ad70dff74d..eb61d0b54f21 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1612,7 +1612,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; m66592->gadget.dev.release = pdev->dev.release; m66592->gadget.name = udc_name; - m66592->gadget.register_my_device = true; init_timer(&m66592->timer); m66592->timer.function = m66592_timer; diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index 734ade11505f..e5735fc610de 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1959,7 +1959,6 @@ static int mv_u3d_probe(struct platform_device *dev) u3d->gadget.dev.dma_mask = dev->dev.dma_mask; u3d->gadget.dev.release = mv_u3d_gadget_release; u3d->gadget.name = driver_name; /* gadget name */ - u3d->gadget.register_my_device = true; mv_u3d_eps_init(u3d); diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index a7afdfb413b3..be35573f8703 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2313,7 +2313,6 @@ static int mv_udc_probe(struct platform_device *pdev) udc->gadget.dev.dma_mask = pdev->dev.dma_mask; udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ - udc->gadget.register_my_device = true; eps_init(udc); diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 635248f42dcd..78c8bb538332 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2239,7 +2239,6 @@ static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq) ret->gadget.dev.dma_mask = dev->dma_mask; ret->gadget.dev.release = net2272_gadget_release; ret->gadget.name = driver_name; - ret->gadget.register_my_device = true; return ret; } diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c55af4293509..2089d9b0058c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2714,7 +2714,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; - dev->gadget.register_my_device = true; /* now all the pci goodies ... */ if (pci_enable_device (pdev) < 0) { diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index c979272e7c86..b23c861e2a97 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2634,7 +2634,6 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.dev.release = omap_udc_release; udc->gadget.dev.parent = &odev->dev; - udc->gadget.register_my_device = true; if (use_dma) udc->gadget.dev.dma_mask = odev->dev.dma_mask; diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 703214543dd4..e8c9afd8fbf0 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -3198,7 +3198,6 @@ static int pch_udc_probe(struct pci_dev *pdev, dev->gadget.dev.release = gadget_release; dev->gadget.name = KBUILD_MODNAME; dev->gadget.max_speed = USB_SPEED_HIGH; - dev->gadget.register_my_device = true; /* Put the device in disconnected state till a driver is bound */ pch_udc_set_disconnect(dev); diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 8996fcb053ef..e29bb878b2d7 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2140,7 +2140,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - dev->gadget.register_my_device = true; the_controller = dev; platform_set_drvdata(pdev, dev); diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 1c5bfaafa6c8..07ce1477f911 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2457,7 +2457,6 @@ static int __init pxa_udc_probe(struct platform_device *pdev) udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = NULL; - udc->gadget.register_my_device = true; udc->vbus_sensed = 0; the_controller = udc; diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index ae94c0eaf633..a67d47708b98 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1919,7 +1919,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; r8a66597->gadget.dev.release = pdev->dev.release; r8a66597->gadget.name = udc_name; - r8a66597->gadget.register_my_device = true; init_timer(&r8a66597->timer); r8a66597->timer.function = r8a66597_timer; diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 5fbd233eb6a0..8ae0bd99ffde 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3573,7 +3573,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) hsotg->gadget.dev.parent = dev; hsotg->gadget.dev.dma_mask = dev->dma_mask; hsotg->gadget.dev.release = s3c_hsotg_release; - hsotg->gadget.register_my_device = true; /* reset the system */ diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index c4ff747f53fc..7fc3de537c9a 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1312,7 +1312,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) hsudc->gadget.is_otg = 0; hsudc->gadget.is_a_peripheral = 0; hsudc->gadget.speed = USB_SPEED_UNKNOWN; - hsudc->gadget.register_my_device = true; s3c_hsudc_setup_ep(hsudc); diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index c4134948dd9e..a669081bbb88 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1826,7 +1826,6 @@ static int s3c2410_udc_probe(struct platform_device *pdev) udc->gadget.dev.parent = &pdev->dev; udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - udc->gadget.register_my_device = true; the_controller = udc; platform_set_drvdata(pdev, udc); diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 919505426ec1..40b1d888d5a1 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -173,13 +173,11 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) if (!udc) goto err1; - if (gadget->register_my_device) { - dev_set_name(&gadget->dev, "gadget"); + dev_set_name(&gadget->dev, "gadget"); - ret = device_register(&gadget->dev); - if (ret) - goto err2; - } + ret = device_register(&gadget->dev); + if (ret) + goto err2; device_initialize(&udc->dev); udc->dev.release = usb_udc_release; @@ -211,8 +209,8 @@ err3: put_device(&udc->dev); err2: - if (gadget->register_my_device) - put_device(&gadget->dev); + put_device(&gadget->dev); + err1: return ret; } @@ -266,9 +264,7 @@ found: kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); device_unregister(&udc->dev); - - if (gadget->register_my_device) - device_unregister(&gadget->dev); + device_unregister(&gadget->dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index cadb750921e9..e363033f6754 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1891,7 +1891,6 @@ int musb_gadget_setup(struct musb *musb) musb->g.dev.dma_mask = musb->controller->dma_mask; musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; - musb->g.register_my_device = true; musb->g.is_otg = 1; musb_g_init_endpoints(musb); diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 5d5fab0ad0d1..6a3afa9b764c 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -981,7 +981,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) gpriv->gadget.name = "renesas_usbhs_udc"; gpriv->gadget.ops = &usbhsg_gadget_ops; gpriv->gadget.max_speed = USB_SPEED_HIGH; - gpriv->gadget.register_my_device = true; INIT_LIST_HEAD(&gpriv->gadget.ep_list); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index fcd9ef8d3f70..2e297e80d59a 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -494,9 +494,6 @@ struct usb_gadget_ops { * only supports HNP on a different root port. * @b_hnp_enable: OTG device feature flag, indicating that the A-Host * enabled HNP support. - * @register_my_device: Flag telling udc-core that UDC driver didn't - * register the gadget device to the driver model. Temporary until - * all UDC drivers are fixed up properly. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. @@ -534,7 +531,6 @@ struct usb_gadget { unsigned b_hnp_enable:1; unsigned a_hnp_support:1; unsigned a_alt_hnp_support:1; - unsigned register_my_device:1; const char *name; struct device dev; unsigned out_epnum; -- cgit From e58ebcd14210d3def22ba44d9d14daffbe2eb8e0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 14:48:36 +0200 Subject: usb: gadget: s3c-hsotg: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 46 +++++------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 8ae0bd99ffde..2812fa51e296 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -39,8 +39,6 @@ #include "s3c-hsotg.h" -#define DMA_ADDR_INVALID (~((dma_addr_t)0)) - static const char * const s3c_hsotg_supply_names[] = { "vusb_d", /* digital USB supply, 1.2V */ "vusb_a", /* analog USB supply, 1.1V */ @@ -405,7 +403,6 @@ static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, INIT_LIST_HEAD(&req->queue); - req->req.dma = DMA_ADDR_INVALID; return &req->req; } @@ -435,24 +432,12 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, struct s3c_hsotg_req *hs_req) { struct usb_request *req = &hs_req->req; - enum dma_data_direction dir; - - dir = hs_ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; /* ignore this if we're not moving any data */ if (hs_req->req.length == 0) return; - if (hs_req->mapped) { - /* we mapped this, so unmap and remove the dma */ - - dma_unmap_single(hsotg->dev, req->dma, req->length, dir); - - req->dma = DMA_ADDR_INVALID; - hs_req->mapped = 0; - } else { - dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir); - } + usb_gadget_unmap_request(&hsotg->gadget, hs_req, hs_ep->dir_in); } /** @@ -852,37 +837,16 @@ static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct usb_request *req) { - enum dma_data_direction dir; struct s3c_hsotg_req *hs_req = our_req(req); - - dir = hs_ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + int ret; /* if the length is zero, ignore the DMA data */ if (hs_req->req.length == 0) return 0; - if (req->dma == DMA_ADDR_INVALID) { - dma_addr_t dma; - - dma = dma_map_single(hsotg->dev, req->buf, req->length, dir); - - if (unlikely(dma_mapping_error(hsotg->dev, dma))) - goto dma_error; - - if (dma & 3) { - dev_err(hsotg->dev, "%s: unaligned dma buffer\n", - __func__); - - dma_unmap_single(hsotg->dev, dma, req->length, dir); - return -EINVAL; - } - - hs_req->mapped = 1; - req->dma = dma; - } else { - dma_sync_single_for_cpu(hsotg->dev, req->dma, req->length, dir); - hs_req->mapped = 0; - } + ret = usb_gadget_map_request(&hsotg->gadget, req, hs_ep->dir_in); + if (ret) + goto dma_error; return 0; -- cgit From 3be49f38d38a1a2c1cffc61579290c9ba6404446 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 14:51:34 +0200 Subject: usb: gadget: amd5536udc: remove unused structure member that member isn't used anywhere in the driver and be removed with no mercy. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h index f1bf32e6b8d8..6744d3b83109 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/amd5536udc.h @@ -472,7 +472,6 @@ struct udc_request { /* flags */ unsigned dma_going : 1, - dma_mapping : 1, dma_done : 1; /* phys. address */ dma_addr_t td_phys; -- cgit From 1bda9df8dd6d39ac369020594c82d3f70f3a4721 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 16:57:02 +0200 Subject: usb: gadget: atmel_usba_udc: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 41518e612808..94aeba84b21e 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -489,13 +489,8 @@ request_complete(struct usba_ep *ep, struct usba_request *req, int status) if (req->req.status == -EINPROGRESS) req->req.status = status; - if (req->mapped) { - dma_unmap_single( - &udc->pdev->dev, req->req.dma, req->req.length, - ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } + if (req->using_dma) + usb_gadget_unmap_request(&udc->gadget, &req->req, ep->is_in); DBG(DBG_GADGET | DBG_REQ, "%s: req %p complete: status %d, actual %u\n", @@ -684,7 +679,6 @@ usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) return NULL; INIT_LIST_HEAD(&req->queue); - req->req.dma = DMA_ADDR_INVALID; return &req->req; } @@ -717,20 +711,11 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, return -EINVAL; } - req->using_dma = 1; - - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single( - &udc->pdev->dev, req->req.buf, req->req.length, - ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device( - &udc->pdev->dev, req->req.dma, req->req.length, - ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - req->mapped = 0; - } + ret = usb_gadget_map_request(&udc->gadget, &req->req, ep->is_in); + if (ret) + return ret; + req->using_dma = 1; req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; -- cgit From 5f6da778578de6b7c43b943cf9cfba12289e9ff3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 17:03:21 +0200 Subject: usb: gadget: fsl_udc_core: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 51 ++++++++++----------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index f33b9005eeac..c948241c6507 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -185,20 +185,7 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status) dma_pool_free(udc->td_pool, curr_td, curr_td->td_dma); } - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_is_in(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_is_in(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); + usb_gadget_unmap_request(&ep->udc->gadget, &req->req, ep_is_in(ep)); if (status && (status != -ESHUTDOWN)) VDBG("complete %s req %p stat %d len %u/%u", @@ -888,6 +875,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) struct fsl_req *req = container_of(_req, struct fsl_req, req); struct fsl_udc *udc; unsigned long flags; + int ret; /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf @@ -910,22 +898,9 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->ep = ep; - /* map virtual address to hardware */ - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, - req->req.buf, - req->req.length, ep_is_in(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_is_in(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 0; - } + ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep)); + if (ret) + return ret; req->req.status = -EINPROGRESS; req->req.actual = 0; @@ -1290,6 +1265,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) { struct fsl_req *req = udc->status_req; struct fsl_ep *ep; + int ret; if (direction == EP_DIR_IN) udc->ep0_dir = USB_DIR_IN; @@ -1307,10 +1283,9 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) req->req.complete = NULL; req->dtd_count = 0; - req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, - req->req.buf, req->req.length, - ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - req->mapped = 1; + ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep)); + if (ret) + return ret; if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) fsl_queue_td(ep, req); @@ -1353,6 +1328,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, u16 tmp = 0; /* Status, cpu endian */ struct fsl_req *req; struct fsl_ep *ep; + int ret; ep = &udc->eps[0]; @@ -1390,10 +1366,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, req->req.complete = NULL; req->dtd_count = 0; - req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, - req->req.buf, req->req.length, - ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - req->mapped = 1; + ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep)); + if (ret) + goto stall; /* prime the data phase */ if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) -- cgit From 0324f25fc66cd94273d0aa67637ed260ff70f01e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 17:08:28 +0200 Subject: usb: gadget: fusb300: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 2d3c8b351f42..5c9dd064767f 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -938,25 +938,22 @@ IDMA_RESET: static void fusb300_set_idma(struct fusb300_ep *ep, struct fusb300_request *req) { - dma_addr_t d; + int ret; - d = dma_map_single(NULL, req->req.buf, req->req.length, DMA_TO_DEVICE); - - if (dma_mapping_error(NULL, d)) { - printk(KERN_DEBUG "dma_mapping_error\n"); + ret = usb_gadget_map_request(&ep->fusb300->gadget, + &req->req, DMA_TO_DEVICE); + if (ret) return; - } - - dma_sync_single_for_device(NULL, d, req->req.length, DMA_TO_DEVICE); fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER0, FUSB300_IGER0_EEPn_PRD_INT(ep->epnum)); - fusb300_fill_idma_prdtbl(ep, d, req->req.length); + fusb300_fill_idma_prdtbl(ep, req->req.dma, req->req.length); /* check idma is done */ fusb300_wait_idma_finished(ep); - dma_unmap_single(NULL, d, req->req.length, DMA_TO_DEVICE); + usb_gadget_unmap_request(&ep->fusb300->gadget, + &req->req, DMA_TO_DEVICE); } static void in_ep_fifo_handler(struct fusb300_ep *ep) -- cgit From 369ac9cb3e61ff9281dfec14e1e0ee4855c41352 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 17:13:27 +0200 Subject: usb: gadget: lpc32xx_udc: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 67c3ef9d9bed..147832783900 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -1469,23 +1469,7 @@ static void done(struct lpc32xx_ep *ep, struct lpc32xx_request *req, int status) status = req->req.status; if (ep->lep) { - enum dma_data_direction direction; - - if (ep->is_in) - direction = DMA_TO_DEVICE; - else - direction = DMA_FROM_DEVICE; - - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - direction); - req->req.dma = 0; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - direction); + usb_gadget_unmap_request(&udc->gadget, &req->req, ep->is_in); /* Free DDs */ udc_dd_free(udc, req->dd_desc_ptr); @@ -1841,26 +1825,11 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, } if (ep->lep) { - enum dma_data_direction direction; struct lpc32xx_usbd_dd_gad *dd; - /* Map DMA pointer */ - if (ep->is_in) - direction = DMA_TO_DEVICE; - else - direction = DMA_FROM_DEVICE; - - if (req->req.dma == 0) { - req->req.dma = dma_map_single( - ep->udc->gadget.dev.parent, - req->req.buf, req->req.length, direction); - req->mapped = 1; - } else { - dma_sync_single_for_device( - ep->udc->gadget.dev.parent, req->req.dma, - req->req.length, direction); - req->mapped = 0; - } + status = usb_gadget_map_request(&udc->gadget, _req, ep->is_in); + if (status) + return status; /* For the request, build a list of DDs */ dd = udc_dd_alloc(udc); -- cgit From 4c0c6d0085337549e1b4fc97d9616eae732049d6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Jan 2013 17:19:34 +0200 Subject: usb: gadget: mv_udc_core: switch over to usb_gadget_map/unmap_request() we have generic implementations for a reason, let's use them Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 53 +++++----------------------------------- 1 file changed, 6 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index be35573f8703..7f4d19d75578 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -237,18 +237,7 @@ static void done(struct mv_ep *ep, struct mv_req *req, int status) dma_pool_free(udc->dtd_pool, curr_td, curr_td->td_dma); } - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); + usb_gadget_unmap_request(&udc->gadget, &req->req, ep_dir(ep)); if (status && (status != -ESHUTDOWN)) dev_info(&udc->dev->dev, "complete %s req %p stat %d len %u/%u", @@ -732,21 +721,9 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->ep = ep; /* map virtual address to hardware */ - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, - req->req.buf, - req->req.length, ep_dir(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_dir(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 0; - } + retval = usb_gadget_map_request(&udc->gadget, _req, ep_dir(ep)); + if (retval) + return retval; req->req.status = -EINPROGRESS; req->req.actual = 0; @@ -780,18 +757,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return 0; err_unmap_dma: - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); + usb_gadget_unmap_request(&udc->gadget, _req, ep_dir(ep)); return retval; } @@ -1528,14 +1494,7 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) return 0; out: - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } + usb_gadget_unmap_request(&udc->gadget, &req->req, ep_dir(ep)); return retval; } -- cgit From f122d33e4b0045a42238b9a4c3943adf7e8313c1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Feb 2013 15:15:11 +0200 Subject: usb: dwc3: core: explicitly setup and cleanup event buffers Make the call to dwc3_event_buffers_setup() and dwc3_event_buffers_cleanup() explicit, so it's easier to implement PM. Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ffa6b004a84b..47435086058b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -337,12 +337,6 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GCTL, reg); - ret = dwc3_event_buffers_setup(dwc); - if (ret) { - dev_err(dwc->dev, "failed to setup event buffers\n"); - goto err0; - } - return 0; err0: @@ -351,8 +345,6 @@ err0: static void dwc3_core_exit(struct dwc3 *dwc) { - dwc3_event_buffers_cleanup(dwc); - usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); } @@ -480,6 +472,12 @@ static int dwc3_probe(struct platform_device *pdev) goto err0; } + ret = dwc3_event_buffers_setup(dwc); + if (ret) { + dev_err(dwc->dev, "failed to setup event buffers\n"); + goto err1; + } + mode = DWC3_MODE(dwc->hwparams.hwparams0); switch (mode) { @@ -488,7 +486,7 @@ static int dwc3_probe(struct platform_device *pdev) ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); - goto err1; + goto err2; } break; case DWC3_MODE_HOST: @@ -496,7 +494,7 @@ static int dwc3_probe(struct platform_device *pdev) ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); - goto err1; + goto err2; } break; case DWC3_MODE_DRD: @@ -504,32 +502,32 @@ static int dwc3_probe(struct platform_device *pdev) ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); - goto err1; + goto err2; } ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); - goto err1; + goto err2; } break; default: dev_err(dev, "Unsupported mode of operation %d\n", mode); - goto err1; + goto err2; } dwc->mode = mode; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); - goto err2; + goto err3; } pm_runtime_allow(dev); return 0; -err2: +err3: switch (mode) { case DWC3_MODE_DEVICE: dwc3_gadget_exit(dwc); @@ -546,6 +544,9 @@ err2: break; } +err2: + dwc3_event_buffers_cleanup(dwc); + err1: dwc3_core_exit(dwc); @@ -583,6 +584,7 @@ static int dwc3_remove(struct platform_device *pdev) break; } + dwc3_event_buffers_cleanup(dwc); dwc3_free_event_buffers(dwc); dwc3_core_exit(dwc); -- cgit From 8698e2acf3a5e8d6f260ca7675f94e5087df5ae8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Feb 2013 15:24:04 +0200 Subject: usb: dwc3: gadget: introduce and use enable/disable irq methods we don't need to enable IRQs until we have a gadget driver loaded and ready to work, so let's delay IRQ enable to ->udc_start() and IRQ disable to ->udc_stop(). While at that, also move the related use of request_irq() and free_irq(). Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 80 ++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 65493b6cd5a6..db2031725abc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1469,6 +1469,32 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) return ret; } +static void dwc3_gadget_enable_irq(struct dwc3 *dwc) +{ + u32 reg; + + /* Enable all but Start and End of Frame IRQs */ + reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | + DWC3_DEVTEN_EVNTOVERFLOWEN | + DWC3_DEVTEN_CMDCMPLTEN | + DWC3_DEVTEN_ERRTICERREN | + DWC3_DEVTEN_WKUPEVTEN | + DWC3_DEVTEN_ULSTCNGEN | + DWC3_DEVTEN_CONNECTDONEEN | + DWC3_DEVTEN_USBRSTEN | + DWC3_DEVTEN_DISCONNEVTEN); + + dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); +} + +static void dwc3_gadget_disable_irq(struct dwc3 *dwc) +{ + /* mask all interrupts */ + dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); +} + +static irqreturn_t dwc3_interrupt(int irq, void *_dwc); + static int dwc3_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { @@ -1476,6 +1502,7 @@ static int dwc3_gadget_start(struct usb_gadget *g, struct dwc3_ep *dep; unsigned long flags; int ret = 0; + int irq; u32 reg; spin_lock_irqsave(&dwc->lock, flags); @@ -1536,6 +1563,17 @@ static int dwc3_gadget_start(struct usb_gadget *g, dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_out_start(dwc); + irq = platform_get_irq(to_platform_device(dwc->dev), 0); + ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, + "dwc3", dwc); + if (ret) { + dev_err(dwc->dev, "failed to request irq #%d --> %d\n", + irq, ret); + goto err1; + } + + dwc3_gadget_enable_irq(dwc); + spin_unlock_irqrestore(&dwc->lock, flags); return 0; @@ -1554,9 +1592,14 @@ static int dwc3_gadget_stop(struct usb_gadget *g, { struct dwc3 *dwc = gadget_to_dwc(g); unsigned long flags; + int irq; spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_disable_irq(dwc); + irq = platform_get_irq(to_platform_device(dwc->dev), 0); + free_irq(irq, dwc); + __dwc3_gadget_ep_disable(dwc->eps[0]); __dwc3_gadget_ep_disable(dwc->eps[1]); @@ -2454,7 +2497,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) { u32 reg; int ret; - int irq; dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req), &dwc->ctrl_req_addr, GFP_KERNEL); @@ -2510,33 +2552,11 @@ int dwc3_gadget_init(struct dwc3 *dwc) if (ret) goto err4; - irq = platform_get_irq(to_platform_device(dwc->dev), 0); - - ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, - "dwc3", dwc); - if (ret) { - dev_err(dwc->dev, "failed to request irq #%d --> %d\n", - irq, ret); - goto err5; - } - reg = dwc3_readl(dwc->regs, DWC3_DCFG); reg |= DWC3_DCFG_LPM_CAP; dwc3_writel(dwc->regs, DWC3_DCFG, reg); - /* Enable all but Start and End of Frame IRQs */ - reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | - DWC3_DEVTEN_EVNTOVERFLOWEN | - DWC3_DEVTEN_CMDCMPLTEN | - DWC3_DEVTEN_ERRTICERREN | - DWC3_DEVTEN_WKUPEVTEN | - DWC3_DEVTEN_ULSTCNGEN | - DWC3_DEVTEN_CONNECTDONEEN | - DWC3_DEVTEN_USBRSTEN | - DWC3_DEVTEN_DISCONNEVTEN); - dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); - - /* automatic phy suspend only on recent versions */ + /* Enable USB2 LPM and automatic phy suspend only on recent versions */ if (dwc->revision >= DWC3_REVISION_194A) { dwc3_gadget_usb2_phy_suspend(dwc, false); dwc3_gadget_usb3_phy_suspend(dwc, false); @@ -2545,15 +2565,11 @@ int dwc3_gadget_init(struct dwc3 *dwc) ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err6; + goto err5; } return 0; -err6: - dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); - free_irq(irq, dwc); - err5: dwc3_gadget_free_endpoints(dwc); @@ -2578,13 +2594,7 @@ err0: void dwc3_gadget_exit(struct dwc3 *dwc) { - int irq; - usb_del_gadget_udc(&dwc->gadget); - irq = platform_get_irq(to_platform_device(dwc->dev), 0); - - dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); - free_irq(irq, dwc); dwc3_gadget_free_endpoints(dwc); -- cgit From 9fcb3bd8d12db29c101d3722d37ddef9d1915317 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Feb 2013 17:55:58 +0200 Subject: usb: dwc3: gadget: save state of pullups This will be used during resume to verify if we should reconnect our pullups or not. Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b41750660235..35e4d3c01ed0 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -704,6 +704,7 @@ struct dwc3 { unsigned delayed_status:1; unsigned needs_fifo_resize:1; unsigned resize_fifos:1; + unsigned pullups_connected:1; enum dwc3_ep0_next ep0_next_event; enum dwc3_ep0_state ep0state; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index db2031725abc..04e4812fe2f9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1425,8 +1425,10 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) if (dwc->revision >= DWC3_REVISION_194A) reg &= ~DWC3_DCTL_KEEP_CONNECT; reg |= DWC3_DCTL_RUN_STOP; + dwc->pullups_connected = true; } else { reg &= ~DWC3_DCTL_RUN_STOP; + dwc->pullups_connected = false; } dwc3_writel(dwc->regs, DWC3_DCTL, reg); -- cgit From 7415f17c9560c923ba61cd330c8dfcd5c3630b80 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 30 Apr 2012 14:56:33 +0300 Subject: usb: dwc3: core: add power management support Add support for basic power management on the dwc3 driver. While there is still lots to improve for full PM support, this minimal patch will already make sure that we survive suspend-to-ram and suspend-to-disk without major issues. Cc: Vikas C Sajjan Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 33 +++++++++++++ drivers/usb/dwc3/gadget.c | 61 ++++++++++++++++++++++++ 3 files changed, 212 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 47435086058b..75a9f88a5ad6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -591,6 +591,123 @@ static int dwc3_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int dwc3_prepare(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&dwc->lock, flags); + + switch (dwc->mode) { + case DWC3_MODE_DEVICE: + case DWC3_MODE_DRD: + dwc3_gadget_prepare(dwc); + /* FALLTHROUGH */ + case DWC3_MODE_HOST: + default: + dwc3_event_buffers_cleanup(dwc); + break; + } + + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; +} + +static void dwc3_complete(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&dwc->lock, flags); + + switch (dwc->mode) { + case DWC3_MODE_DEVICE: + case DWC3_MODE_DRD: + dwc3_gadget_complete(dwc); + /* FALLTHROUGH */ + case DWC3_MODE_HOST: + default: + dwc3_event_buffers_setup(dwc); + break; + } + + spin_unlock_irqrestore(&dwc->lock, flags); +} + +static int dwc3_suspend(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&dwc->lock, flags); + + switch (dwc->mode) { + case DWC3_MODE_DEVICE: + case DWC3_MODE_DRD: + dwc3_gadget_suspend(dwc); + /* FALLTHROUGH */ + case DWC3_MODE_HOST: + default: + /* do nothing */ + break; + } + + dwc->gctl = dwc3_readl(dwc->regs, DWC3_GCTL); + spin_unlock_irqrestore(&dwc->lock, flags); + + usb_phy_shutdown(dwc->usb3_phy); + usb_phy_shutdown(dwc->usb2_phy); + + return 0; +} + +static int dwc3_resume(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + + usb_phy_init(dwc->usb3_phy); + usb_phy_init(dwc->usb2_phy); + msleep(100); + + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl); + + switch (dwc->mode) { + case DWC3_MODE_DEVICE: + case DWC3_MODE_DRD: + dwc3_gadget_resume(dwc); + /* FALLTHROUGH */ + case DWC3_MODE_HOST: + default: + /* do nothing */ + break; + } + + spin_unlock_irqrestore(&dwc->lock, flags); + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} + +static const struct dev_pm_ops dwc3_dev_pm_ops = { + .prepare = dwc3_prepare, + .complete = dwc3_complete, + + SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) +}; + +#define DWC3_PM_OPS &(dwc3_dev_pm_ops) +#else +#define DWC3_PM_OPS NULL +#endif + #ifdef CONFIG_OF static const struct of_device_id of_dwc3_match[] = { { @@ -607,6 +724,7 @@ static struct platform_driver dwc3_driver = { .driver = { .name = "dwc3", .of_match_table = of_match_ptr(of_dwc3_match), + .pm = DWC3_PM_OPS, }, }; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 35e4d3c01ed0..52e48e21c82f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -626,6 +626,8 @@ struct dwc3_scratchpad_array { * @mode: mode of operation * @usb2_phy: pointer to USB2 PHY * @usb3_phy: pointer to USB3 PHY + * @dcfg: saved contents of DCFG register + * @gctl: saved contents of GCTL register * @is_selfpowered: true when we are selfpowered * @three_stage_setup: set if we perform a three phase setup * @ep0_bounced: true when we used bounce buffer @@ -675,6 +677,10 @@ struct dwc3 { void __iomem *regs; size_t regs_size; + /* used for suspend/resume */ + u32 dcfg; + u32 gctl; + u32 num_event_buffers; u32 u1u2; u32 maximum_speed; @@ -885,4 +891,31 @@ static inline void dwc3_gadget_exit(struct dwc3 *dwc) { } #endif +/* power management interface */ +#if !IS_ENABLED(CONFIG_USB_DWC3_HOST) +int dwc3_gadget_prepare(struct dwc3 *dwc); +void dwc3_gadget_complete(struct dwc3 *dwc); +int dwc3_gadget_suspend(struct dwc3 *dwc); +int dwc3_gadget_resume(struct dwc3 *dwc); +#else +static inline int dwc3_gadget_prepare(struct dwc3 *dwc) +{ + return 0; +} + +static inline void dwc3_gadget_complete(struct dwc3 *dwc) +{ +} + +static inline int dwc3_gadget_suspend(struct dwc3 *dwc) +{ + return 0; +} + +static inline int dwc3_gadget_resume(struct dwc3 *dwc) +{ + return 0; +} +#endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ + #endif /* __DRIVERS_USB_DWC3_CORE_H */ diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 04e4812fe2f9..73b0b7fc77f1 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2594,6 +2594,8 @@ err0: return ret; } +/* -------------------------------------------------------------------------- */ + void dwc3_gadget_exit(struct dwc3 *dwc) { usb_del_gadget_udc(&dwc->gadget); @@ -2611,3 +2613,62 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), dwc->ctrl_req, dwc->ctrl_req_addr); } + +int dwc3_gadget_prepare(struct dwc3 *dwc) +{ + if (dwc->pullups_connected) + dwc3_gadget_disable_irq(dwc); + + return 0; +} + +void dwc3_gadget_complete(struct dwc3 *dwc) +{ + if (dwc->pullups_connected) { + dwc3_gadget_enable_irq(dwc); + dwc3_gadget_run_stop(dwc, true); + } +} + +int dwc3_gadget_suspend(struct dwc3 *dwc) +{ + __dwc3_gadget_ep_disable(dwc->eps[0]); + __dwc3_gadget_ep_disable(dwc->eps[1]); + + dwc->dcfg = dwc3_readl(dwc->regs, DWC3_DCFG); + + return 0; +} + +int dwc3_gadget_resume(struct dwc3 *dwc) +{ + struct dwc3_ep *dep; + int ret; + + /* Start with SuperSpeed Default */ + dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); + + dep = dwc->eps[0]; + ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); + if (ret) + goto err0; + + dep = dwc->eps[1]; + ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); + if (ret) + goto err1; + + /* begin to receive SETUP packets */ + dwc->ep0state = EP0_SETUP_PHASE; + dwc3_ep0_out_start(dwc); + + dwc3_writel(dwc->regs, DWC3_DCFG, dwc->dcfg); + + return 0; + +err1: + __dwc3_gadget_ep_disable(dwc->eps[0]); + +err0: + return ret; +} -- cgit From 9a4b5dab91a8bfae46bfa572660cf43e9ebdc6c3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Feb 2013 11:03:59 +0200 Subject: usb: dwc3: omap: introduce enable/disable IRQ methods they will be re-used on suspend/resume implementation. Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 47 ++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 3d343d92548a..43d62053e158 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -250,6 +250,34 @@ static int dwc3_omap_remove_core(struct device *dev, void *c) return 0; } +static void dwc3_omap_enable_irqs(struct dwc3_omap *omap) +{ + u32 reg; + + /* enable all IRQs */ + reg = USBOTGSS_IRQO_COREIRQ_ST; + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg); + + reg = (USBOTGSS_IRQ1_OEVT | + USBOTGSS_IRQ1_DRVVBUS_RISE | + USBOTGSS_IRQ1_CHRGVBUS_RISE | + USBOTGSS_IRQ1_DISCHRGVBUS_RISE | + USBOTGSS_IRQ1_IDPULLUP_RISE | + USBOTGSS_IRQ1_DRVVBUS_FALL | + USBOTGSS_IRQ1_CHRGVBUS_FALL | + USBOTGSS_IRQ1_DISCHRGVBUS_FALL | + USBOTGSS_IRQ1_IDPULLUP_FALL); + + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); +} + +static void dwc3_omap_disable_irqs(struct dwc3_omap *omap) +{ + /* disable all IRQs */ + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, 0x00); + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, 0x00); +} + static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -355,21 +383,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) return ret; } - /* enable all IRQs */ - reg = USBOTGSS_IRQO_COREIRQ_ST; - dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg); - - reg = (USBOTGSS_IRQ1_OEVT | - USBOTGSS_IRQ1_DRVVBUS_RISE | - USBOTGSS_IRQ1_CHRGVBUS_RISE | - USBOTGSS_IRQ1_DISCHRGVBUS_RISE | - USBOTGSS_IRQ1_IDPULLUP_RISE | - USBOTGSS_IRQ1_DRVVBUS_FALL | - USBOTGSS_IRQ1_CHRGVBUS_FALL | - USBOTGSS_IRQ1_DISCHRGVBUS_FALL | - USBOTGSS_IRQ1_IDPULLUP_FALL); - - dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); + dwc3_omap_enable_irqs(omap); ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { @@ -382,6 +396,9 @@ static int dwc3_omap_probe(struct platform_device *pdev) static int dwc3_omap_remove(struct platform_device *pdev) { + struct dwc3_omap *omap = platform_get_drvdata(pdev); + + dwc3_omap_disable_irqs(omap); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); -- cgit From 1d9a00eeca1deeebf001047aa5e5e9d00e5588cf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Feb 2013 11:07:34 +0200 Subject: usb: dwc3: omap: remove unused fields from private structure we're not using those fields of the structure, might as well remove them. Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 43d62053e158..ed178c0fc426 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -121,9 +121,6 @@ struct dwc3_omap { int irq; void __iomem *base; - void *context; - u32 resource_size; - u32 dma_status:1; }; @@ -294,7 +291,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) u32 reg; void __iomem *base; - void *context; if (!node) { dev_err(dev, "device node not found\n"); @@ -327,16 +323,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) return -ENOMEM; } - context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); - if (!context) { - dev_err(dev, "couldn't allocate dwc3 context memory\n"); - return -ENOMEM; - } - spin_lock_init(&omap->lock); - omap->resource_size = resource_size(res); - omap->context = context; omap->dev = dev; omap->irq = irq; omap->base = base; -- cgit From f3e117f4437af5a2d1b72ae0fa1890dbf9bca72f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Feb 2013 11:12:02 +0200 Subject: usb: dwc3: omap: add basic suspend/resume support this patch implements basic suspend/resume functionality for the OMAP glue layer. Tested-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ed178c0fc426..35b9673b84df 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -121,6 +121,8 @@ struct dwc3_omap { int irq; void __iomem *base; + u32 utmi_otg_status; + u32 dma_status:1; }; @@ -402,12 +404,66 @@ static const struct of_device_id of_dwc3_match[] = { }; MODULE_DEVICE_TABLE(of, of_dwc3_match); +#ifdef CONFIG_PM +static int dwc3_omap_prepare(struct device *dev) +{ + struct dwc3_omap *omap = dev_get_drvdata(dev); + + dwc3_omap_disable_irqs(omap); + + return 0; +} + +static void dwc3_omap_complete(struct device *dev) +{ + struct dwc3_omap *omap = dev_get_drvdata(dev); + + dwc3_omap_enable_irqs(omap); +} + +static int dwc3_omap_suspend(struct device *dev) +{ + struct dwc3_omap *omap = dev_get_drvdata(dev); + + omap->utmi_otg_status = dwc3_omap_readl(omap->base, + USBOTGSS_UTMI_OTG_STATUS); + + return 0; +} + +static int dwc3_omap_resume(struct device *dev) +{ + struct dwc3_omap *omap = dev_get_drvdata(dev); + + dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, + omap->utmi_otg_status); + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} + +static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { + .prepare = dwc3_omap_prepare, + .complete = dwc3_omap_complete, + + SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume) +}; + +#define DEV_PM_OPS (&dwc3_omap_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + static struct platform_driver dwc3_omap_driver = { .probe = dwc3_omap_probe, .remove = dwc3_omap_remove, .driver = { .name = "omap-dwc3", .of_match_table = of_dwc3_match, + .pm = DEV_PM_OPS, }, }; -- cgit From 0646caf754aa3ce55ef978d7f4a3e3d0aab7a187 Mon Sep 17 00:00:00 2001 From: Vikas Sajjan Date: Tue, 16 Oct 2012 15:15:38 +0530 Subject: usb: dwc3: exynos: add basic suspend/resume support Adds suspend and resume callbacks to exynos dwc3 driver as part of power management support. This change does gating of dwc3 clock during suspend/resume cycles. Signed-off-by: Abhilash Kesavan Signed-off-by: Vikas C Sajjan CC: Doug Anderson Tested-by: Vivek Gautam [ balbi@ti.com : refreshed to current linus/master ] Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index b082bec7343e..e12e45248862 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -187,12 +187,46 @@ static const struct of_device_id exynos_dwc3_match[] = { MODULE_DEVICE_TABLE(of, exynos_dwc3_match); #endif +#ifdef CONFIG_PM +static int dwc3_exynos_suspend(struct device *dev) +{ + struct dwc3_exynos *exynos = dev_get_drvdata(dev); + + clk_disable(exynos->clk); + + return 0; +} + +static int dwc3_exynos_resume(struct device *dev) +{ + struct dwc3_exynos *exynos = dev_get_drvdata(dev); + + clk_enable(exynos->clk); + + /* runtime set active to reflect active state. */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} + +static const struct dev_pm_ops dwc3_exynos_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_exynos_suspend, dwc3_exynos_resume) +}; + +#define DEV_PM_OPS (&dwc3_exynos_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + static struct platform_driver dwc3_exynos_driver = { .probe = dwc3_exynos_probe, .remove = dwc3_exynos_remove, .driver = { .name = "exynos-dwc3", .of_match_table = of_match_ptr(exynos_dwc3_match), + .pm = DEV_PM_OPS, }, }; -- cgit From 68907a77431f405c0e8e7031aa77aae03383c69d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Feb 2013 11:36:22 +0200 Subject: usb: dwc3: pci: add basic suspend/resume support this patch adds basic PM support for the PCI glue layer. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index e8d77689a322..227d4a7acad7 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -212,11 +212,49 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = { }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); +#ifdef CONFIG_PM +static int dwc3_pci_suspend(struct device *dev) +{ + struct pci_dev *pci = to_pci_dev(dev); + + pci_disable_device(pci); + + return 0; +} + +static int dwc3_pci_resume(struct device *dev) +{ + struct pci_dev *pci = to_pci_dev(dev); + int ret; + + ret = pci_enable_device(pci); + if (ret) { + dev_err(dev, "can't re-enable device --> %d\n", ret); + return ret; + } + + pci_set_master(pci); + + return 0; +} + +static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) +}; + +#define DEV_PM_OPS (&dwc3_pci_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + static struct pci_driver dwc3_pci_driver = { .name = "dwc3-pci", .id_table = dwc3_pci_id_table, .probe = dwc3_pci_probe, .remove = dwc3_pci_remove, + .driver = { + .pm = DEV_PM_OPS, + }, }; MODULE_AUTHOR("Felipe Balbi "); -- cgit From 6110a7ebda18d103f28bec0eab65f7be01871233 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 1 Feb 2013 23:33:50 +0200 Subject: usb: musb: core: remove unnecessary pr_info() there's really no need for that message. It's been a while since it printed something useful. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index daec6e0f7e38..36b7a1e16e48 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2293,8 +2293,6 @@ static int __init musb_init(void) if (usb_disabled()) return 0; - pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n", - musb_driver_name); return platform_driver_register(&musb_driver); } module_init(musb_init); -- cgit From b42f7f3091de06f25abf59a26a3446f7b2fd0a50 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 4 Feb 2013 19:04:45 +0200 Subject: usb: musb: switch over to devm_ioremap_resource() this will make sure that request_memory_region() will be called and that we don't need to manually call iounmap() on ->remove(). Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 36b7a1e16e48..fad8571ed433 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2008,7 +2008,6 @@ static int musb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int irq = platform_get_irq_byname(pdev, "mc"); - int status; struct resource *iomem; void __iomem *base; @@ -2016,24 +2015,17 @@ static int musb_probe(struct platform_device *pdev) if (!iomem || irq <= 0) return -ENODEV; - base = ioremap(iomem->start, resource_size(iomem)); - if (!base) { - dev_err(dev, "ioremap failed\n"); - return -ENOMEM; - } + base = devm_ioremap_resource(dev, iomem); + if (IS_ERR(base)) + return PTR_ERR(base); - status = musb_init_controller(dev, irq, base); - if (status < 0) - iounmap(base); - - return status; + return musb_init_controller(dev, irq, base); } static int musb_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct musb *musb = dev_to_musb(dev); - void __iomem *ctrl_base = musb->ctrl_base; /* this gets called on rmmod. * - Host mode: host may still be active @@ -2044,7 +2036,6 @@ static int musb_remove(struct platform_device *pdev) musb_shutdown(pdev); musb_free(musb); - iounmap(ctrl_base); device_init_wakeup(dev, 0); #ifndef CONFIG_MUSB_PIO_ONLY dma_set_mask(dev, *dev->parent->dma_mask); -- cgit From 38c5df225692cde4d695e4c74eaa7d83546ebe53 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 4 Feb 2013 19:57:23 +0200 Subject: usb: musb: gadget: delete wrong comment Those comments haven't been updated for a long time, so much that they don't make sense anymore. Best to remove them. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 108 ----------------------------------------- 1 file changed, 108 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index e363033f6754..b47f66d32b40 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -46,48 +46,6 @@ #include "musb_core.h" -/* MUSB PERIPHERAL status 3-mar-2006: - * - * - EP0 seems solid. It passes both USBCV and usbtest control cases. - * Minor glitches: - * - * + remote wakeup to Linux hosts work, but saw USBCV failures; - * in one test run (operator error?) - * + endpoint halt tests -- in both usbtest and usbcv -- seem - * to break when dma is enabled ... is something wrongly - * clearing SENDSTALL? - * - * - Mass storage behaved ok when last tested. Network traffic patterns - * (with lots of short transfers etc) need retesting; they turn up the - * worst cases of the DMA, since short packets are typical but are not - * required. - * - * - TX/IN - * + both pio and dma behave in with network and g_zero tests - * + no cppi throughput issues other than no-hw-queueing - * + failed with FLAT_REG (DaVinci) - * + seems to behave with double buffering, PIO -and- CPPI - * + with gadgetfs + AIO, requests got lost? - * - * - RX/OUT - * + both pio and dma behave in with network and g_zero tests - * + dma is slow in typical case (short_not_ok is clear) - * + double buffering ok with PIO - * + double buffering *FAILS* with CPPI, wrong data bytes sometimes - * + request lossage observed with gadgetfs - * - * - ISO not tested ... might work, but only weakly isochronous - * - * - Gadget driver disabling of softconnect during bind() is ignored; so - * drivers can't hold off host requests until userspace is ready. - * (Workaround: they can turn it off later.) - * - * - PORTABILITY (assumes PIO works): - * + DaVinci, basically works with cppi dma - * + OMAP 2430, ditto with mentor dma - * + TUSB 6010, platform-specific dma in the works - */ - /* ----------------------------------------------------------------------- */ #define is_buffer_mapped(req) (is_dma_capable() && \ @@ -275,41 +233,6 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) return ep->packet_sz; } - -#ifdef CONFIG_USB_INVENTRA_DMA - -/* Peripheral tx (IN) using Mentor DMA works as follows: - Only mode 0 is used for transfers <= wPktSize, - mode 1 is used for larger transfers, - - One of the following happens: - - Host sends IN token which causes an endpoint interrupt - -> TxAvail - -> if DMA is currently busy, exit. - -> if queue is non-empty, txstate(). - - - Request is queued by the gadget driver. - -> if queue was previously empty, txstate() - - txstate() - -> start - /\ -> setup DMA - | (data is transferred to the FIFO, then sent out when - | IN token(s) are recd from Host. - | -> DMA interrupt on completion - | calls TxAvail. - | -> stop DMA, ~DMAENAB, - | -> set TxPktRdy for last short pkt or zlp - | -> Complete Request - | -> Continue next request (call txstate) - |___________________________________| - - * Non-Mentor DMA engines can of course work differently, such as by - * upleveling from irq-per-packet to irq-per-buffer. - */ - -#endif - /* * An endpoint is transmitting data. This can be called either from * the IRQ routine or from ep.queue() to kickstart a request on an @@ -616,37 +539,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) /* ------------------------------------------------------------ */ -#ifdef CONFIG_USB_INVENTRA_DMA - -/* Peripheral rx (OUT) using Mentor DMA works as follows: - - Only mode 0 is used. - - - Request is queued by the gadget class driver. - -> if queue was previously empty, rxstate() - - - Host sends OUT token which causes an endpoint interrupt - /\ -> RxReady - | -> if request queued, call rxstate - | /\ -> setup DMA - | | -> DMA interrupt on completion - | | -> RxReady - | | -> stop DMA - | | -> ack the read - | | -> if data recd = max expected - | | by the request, or host - | | sent a short packet, - | | complete the request, - | | and start the next one. - | |_____________________________________| - | else just wait for the host - | to send the next OUT token. - |__________________________________________________| - - * Non-Mentor DMA engines can of course work differently. - */ - -#endif - /* * Context: controller locked, IRQs blocked, endpoint selected */ -- cgit From 99b7856f3cec5db7ec71a8b4675a63e4bcadd63e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 09:22:47 +0200 Subject: usb: musb: force PIO-only if we're building multiplatform kernels MUSB still needs lots of work on the DMA part if we want to enable multiple DMA engines on a multiplatform kernel. Meanwhile, we're forcing PIO-only so that we, at least, have a working driver. Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 05e51432dd2f..39864e3184a6 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -67,6 +67,7 @@ endchoice choice prompt 'MUSB DMA mode' + default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM default USB_UX500_DMA if USB_MUSB_UX500 default USB_INVENTRA_DMA if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN default USB_TI_CPPI_DMA if USB_MUSB_DAVINCI -- cgit From 787f5627bec80094db487bfcb401e9744f181aed Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 09:24:55 +0200 Subject: usb: musb: make davinci and da8xx glues depend on BROKEN those two glues are still including headers and no active developement has been going on those glues for quite some time. Apparently, for da8xx glue, only initial commit 3ee076de (usb: musb: introduce DA8xx/OMAP-L1x glue layer) has been tested. All other patches seem to have been compile-tested only. For davinci glue layer, last real commit dates back from 2010, with commit f405387 (USB: MUSB: fix kernel WARNING/oops when unloading module in OTG mode). Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 39864e3184a6..de0fc884b6da 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -34,10 +34,12 @@ choice config USB_MUSB_DAVINCI tristate "DaVinci" depends on ARCH_DAVINCI_DMx + depends on BROKEN config USB_MUSB_DA8XX tristate "DA8xx/OMAP-L1x" depends on ARCH_DAVINCI_DA8XX + depends on BROKEN config USB_MUSB_TUSB6010 tristate "TUSB6010" -- cgit From 0f53e48132cd95b359fc79e0aa44db1c406b4eff Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 09:47:58 +0200 Subject: usb: musb: dsps: add missing include is the header defining SZ_4 and SZ_16M, we shouldn't depend on indirect inclusion so let's explicitly include it. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 1 + drivers/usb/musb/ux500_dma.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 6bb89715b637..dfaa0241c223 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 039e567dd3b6..12dd6ed7033c 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "musb_core.h" -- cgit From 6a3b003620f0bd31390422619092fcb87cf1069e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 09:53:01 +0200 Subject: usb: musb: ux500_dma: kill compile warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following compile warnings: drivers/usb/musb/ux500_dma.c: In function ‘ux500_configure_channel’: drivers/usb/musb/ux500_dma.c:96:2: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 6 has type ‘dma_addr_t’ [-Wformat] drivers/usb/musb/ux500_dma.c: In function ‘ux500_dma_is_compatible’: drivers/usb/musb/ux500_dma.c:195:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500_dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 12dd6ed7033c..c3a584cf01bb 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -94,8 +94,9 @@ static bool ux500_configure_channel(struct dma_channel *channel, struct musb *musb = ux500_channel->controller->private_data; dev_dbg(musb->controller, - "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n", - packet_sz, mode, dma_addr, len, ux500_channel->is_tx); + "packet_sz=%d, mode=%d, dma_addr=0x%llu, len=%d is_tx=%d\n", + packet_sz, mode, (unsigned long long) dma_addr, + len, ux500_channel->is_tx); ux500_channel->cur_len = len; @@ -192,7 +193,7 @@ static int ux500_dma_is_compatible(struct dma_channel *channel, u16 maxpacket, void *buf, u32 length) { if ((maxpacket & 0x3) || - ((int)buf & 0x3) || + ((unsigned long int) buf & 0x3) || (length < 512) || (length & 0x3)) return false; -- cgit From cc5060366b3c8cc20f0f4020a15fa5d39f4dc936 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 09:57:18 +0200 Subject: usb: musb: dsps: fix possible compile warning if CONFIG_OF is disabled, np will be unused and that will give us a compile warning. This patch just avoids it. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index dfaa0241c223..4b4987461adb 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -597,14 +597,13 @@ err0: static int dsps_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; const struct dsps_musb_wrapper *wrp; struct dsps_glue *glue; struct resource *iomem; int ret, i; - match = of_match_node(musb_dsps_of_match, np); + match = of_match_node(musb_dsps_of_match, pdev->dev.of_node); if (!match) { dev_err(&pdev->dev, "fail to get matching of_match struct\n"); ret = -EINVAL; -- cgit From 37730eccf214ec343b7b0e6cce31400f56ca09ff Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 10:19:15 +0200 Subject: usb: musb: gadget: fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following compile warning: drivers/usb/musb/musb_gadget.c: In function ‘rxstate’: drivers/usb/musb/musb_gadget.c:714:22: warning: comparison of distinct pointer types lacks a cast [enabled by default] Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b47f66d32b40..d35a375c6070 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -627,7 +627,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) struct dma_controller *c; struct dma_channel *channel; int use_dma = 0; - int transfer_size; + unsigned int transfer_size; c = musb->dma_controller; channel = musb_ep->dma; @@ -669,10 +669,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) csr | MUSB_RXCSR_DMAMODE); musb_writew(epio, MUSB_RXCSR, csr); - transfer_size = min(request->length - request->actual, + transfer_size = min_t(unsigned int, + request->length - + request->actual, channel->max_len); musb_ep->dma->desired_mode = 1; - } else { if (!musb_ep->hb_mult && musb_ep->hw_ep->rx_double_buffered) @@ -702,7 +703,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) struct dma_controller *c; struct dma_channel *channel; - int transfer_size = 0; + unsigned int transfer_size = 0; c = musb->dma_controller; channel = musb_ep->dma; @@ -711,11 +712,13 @@ static void rxstate(struct musb *musb, struct musb_request *req) if (fifo_count < musb_ep->packet_sz) transfer_size = fifo_count; else if (request->short_not_ok) - transfer_size = min(request->length - + transfer_size = min_t(unsigned int, + request->length - request->actual, channel->max_len); else - transfer_size = min(request->length - + transfer_size = min_t(unsigned int, + request->length - request->actual, (unsigned)fifo_count); -- cgit From a033f7ae607eb1d281448cda694c83f0c3f95e0d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Feb 2013 10:23:37 +0200 Subject: usb: musb: Kconfig: drop unnecessary dependencies those glues can build cleanly anywhere. Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index de0fc884b6da..d38cf9859abb 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -55,7 +55,6 @@ config USB_MUSB_AM35X config USB_MUSB_DSPS tristate "TI DSPS platforms" - depends on SOC_TI81XX || SOC_AM33XX config USB_MUSB_BLACKFIN tristate "Blackfin" @@ -63,7 +62,6 @@ config USB_MUSB_BLACKFIN config USB_MUSB_UX500 tristate "U8500 and U5500" - depends on (ARCH_U8500 && AB8500_USB) endchoice -- cgit From 9e86e71bcec99256fa29466d207b414919beb977 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 12:47:07 +0200 Subject: usb: dwc3: core: remove bogus comment to our structure that irq field has been removed already. This patch just removes its documentation. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 52e48e21c82f..80f763f92e04 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -618,7 +618,6 @@ struct dwc3_scratchpad_array { * @gadget_driver: pointer to the gadget driver * @regs: base address for our registers * @regs_size: address space size - * @irq: IRQ number * @num_event_buffers: calculated number of event buffers * @u1u2: only used on revisions <1.83a for workaround * @maximum_speed: maximum speed requested (mainly for testing purposes) -- cgit From abed411869770a0f6c31e66388d7566bae672c2c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 4 Jul 2011 20:20:04 +0300 Subject: usb: dwc3: add a flags field to event buffer that way we know if a particular event buffer has pending events, or not. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 80f763f92e04..e7b06798fb69 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -369,6 +369,8 @@ struct dwc3_trb; * @list: a list of event buffers * @buf: _THE_ buffer * @length: size of this buffer + * @lpos: event offset + * @flags: flags related to this event buffer * @dma: dma_addr_t * @dwc: pointer to DWC controller */ @@ -376,6 +378,9 @@ struct dwc3_event_buffer { void *buf; unsigned length; unsigned int lpos; + unsigned int flags; + +#define DWC3_EVENT_PENDING BIT(0) dma_addr_t dma; -- cgit From 60d04bbee0b729dc1e95d4dc669f68dea2a32570 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 4 Jul 2011 20:23:14 +0300 Subject: usb: dwc3: add count field to event buffer we can cache the last read value of the event buffer count register on this field, for later handling. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e7b06798fb69..cdd70cb78aa4 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -370,6 +370,7 @@ struct dwc3_trb; * @buf: _THE_ buffer * @length: size of this buffer * @lpos: event offset + * @count: cache of last read event count register * @flags: flags related to this event buffer * @dma: dma_addr_t * @dwc: pointer to DWC controller @@ -378,6 +379,7 @@ struct dwc3_event_buffer { void *buf; unsigned length; unsigned int lpos; + unsigned int count; unsigned int flags; #define DWC3_EVENT_PENDING BIT(0) -- cgit From b15a762f02acb4f1e695a17435f719350f9d5bc1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 30 Jun 2011 16:57:15 +0300 Subject: usb: dwc3: gadget: move to threaded IRQ by moving to threaded IRQs, we allow our IRQ priorities to be configurable when running with realtime patch. Also, since we're running in thread context, we can call functions which might sleep, such as sysfs_notify() without problems. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 86 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 73b0b7fc77f1..742eb8268e9a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1496,6 +1496,7 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc) } static irqreturn_t dwc3_interrupt(int irq, void *_dwc); +static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc); static int dwc3_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver) @@ -1566,8 +1567,8 @@ static int dwc3_gadget_start(struct usb_gadget *g, dwc3_ep0_out_start(dwc); irq = platform_get_irq(to_platform_device(dwc->dev), 0); - ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, - "dwc3", dwc); + ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, + IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); if (ret) { dev_err(dwc->dev, "failed to request irq #%d --> %d\n", irq, ret); @@ -2432,40 +2433,73 @@ static void dwc3_process_event_entry(struct dwc3 *dwc, } } +static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) +{ + struct dwc3 *dwc = _dwc; + unsigned long flags; + irqreturn_t ret = IRQ_NONE; + int i; + + spin_lock_irqsave(&dwc->lock, flags); + + for (i = 0; i < dwc->num_event_buffers; i++) { + struct dwc3_event_buffer *evt; + int left; + + evt = dwc->ev_buffs[i]; + left = evt->count; + + if (!(evt->flags & DWC3_EVENT_PENDING)) + continue; + + while (left > 0) { + union dwc3_event event; + + event.raw = *(u32 *) (evt->buf + evt->lpos); + + dwc3_process_event_entry(dwc, &event); + + /* + * FIXME we wrap around correctly to the next entry as + * almost all entries are 4 bytes in size. There is one + * entry which has 12 bytes which is a regular entry + * followed by 8 bytes data. ATM I don't know how + * things are organized if we get next to the a + * boundary so I worry about that once we try to handle + * that. + */ + evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; + left -= 4; + + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(i), 4); + } + + evt->count = 0; + evt->flags &= ~DWC3_EVENT_PENDING; + ret = IRQ_HANDLED; + } + + spin_unlock_irqrestore(&dwc->lock, flags); + + return ret; +} + static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) { struct dwc3_event_buffer *evt; - int left; u32 count; + evt = dwc->ev_buffs[buf]; + count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf)); count &= DWC3_GEVNTCOUNT_MASK; if (!count) return IRQ_NONE; - evt = dwc->ev_buffs[buf]; - left = count; - - while (left > 0) { - union dwc3_event event; - - event.raw = *(u32 *) (evt->buf + evt->lpos); - - dwc3_process_event_entry(dwc, &event); - /* - * XXX we wrap around correctly to the next entry as almost all - * entries are 4 bytes in size. There is one entry which has 12 - * bytes which is a regular entry followed by 8 bytes data. ATM - * I don't know how things are organized if were get next to the - * a boundary so I worry about that once we try to handle that. - */ - evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; - left -= 4; - - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4); - } + evt->count = count; + evt->flags |= DWC3_EVENT_PENDING; - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static irqreturn_t dwc3_interrupt(int irq, void *_dwc) @@ -2480,7 +2514,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) irqreturn_t status; status = dwc3_process_event_buf(dwc, i); - if (status == IRQ_HANDLED) + if (status == IRQ_WAKE_THREAD) ret = status; } -- cgit From d1e3d757f7aa91f15db347fc05ffd7ef7f413091 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 22:29:48 +0200 Subject: usb: common: introduce usb_state_string() this function will receive enum usb_device_state and return a human-readable string from it or, case an unknown value is passed as argument, the string "UNKNOWN". Signed-off-by: Felipe Balbi --- drivers/usb/usb-common.c | 21 +++++++++++++++++++++ include/linux/usb/ch9.h | 9 +++++++++ 2 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c index d29503e954ab..070b681e5d17 100644 --- a/drivers/usb/usb-common.c +++ b/drivers/usb/usb-common.c @@ -32,4 +32,25 @@ const char *usb_speed_string(enum usb_device_speed speed) } EXPORT_SYMBOL_GPL(usb_speed_string); +const char *usb_state_string(enum usb_device_state state) +{ + static const char *const names[] = { + [USB_STATE_NOTATTACHED] = "not attached", + [USB_STATE_ATTACHED] = "attached", + [USB_STATE_POWERED] = "powered", + [USB_STATE_RECONNECTING] = "reconnecting", + [USB_STATE_UNAUTHENTICATED] = "unauthenticated", + [USB_STATE_DEFAULT] = "default", + [USB_STATE_ADDRESS] = "addresssed", + [USB_STATE_CONFIGURED] = "configured", + [USB_STATE_SUSPENDED] = "suspended", + }; + + if (state < 0 || state >= ARRAY_SIZE(names)) + return "UNKNOWN"; + + return names[state]; +} +EXPORT_SYMBOL_GPL(usb_state_string); + MODULE_LICENSE("GPL"); diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 9c210f2283df..27603bcbb9b9 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -43,4 +43,13 @@ */ extern const char *usb_speed_string(enum usb_device_speed speed); + +/** + * usb_state_string - Returns human readable name for the state. + * @state: The state to return a human-readable name for. If it's not + * any of the states devices in usb_device_state_string enum, + * the string UNKNOWN will be returned. + */ +extern const char *usb_state_string(enum usb_device_state state); + #endif /* __LINUX_USB_CH9_H */ -- cgit From 49401f4169c0e5a1b38f1a676d6f12eecaf77485 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 19 Dec 2011 12:57:04 +0200 Subject: usb: gadget: introduce gadget state tracking that's useful information to expose to userland. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 23 +++++++++++++++++++++++ include/linux/usb/gadget.h | 9 +++++++++ 2 files changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 40b1d888d5a1..8a1eeb24ae6a 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -101,6 +101,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); /* ------------------------------------------------------------------------- */ +void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state) +{ + gadget->state = state; + sysfs_notify(&gadget->dev.kobj, NULL, "status"); +} +EXPORT_SYMBOL_GPL(usb_gadget_set_state); + +/* ------------------------------------------------------------------------- */ + /** * usb_gadget_udc_start - tells usb device controller to start up * @gadget: The gadget we want to get started @@ -197,6 +207,8 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) if (ret) goto err4; + usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); + mutex_unlock(&udc_lock); return 0; @@ -406,6 +418,16 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); +static ssize_t usb_gadget_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + struct usb_gadget *gadget = udc->gadget; + + return sprintf(buf, "%s\n", usb_state_string(gadget->state)); +} +static DEVICE_ATTR(state, S_IRUGO, usb_gadget_state_show, NULL); + #define USB_UDC_SPEED_ATTR(name, param) \ ssize_t usb_udc_##param##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -439,6 +461,7 @@ static USB_UDC_ATTR(a_alt_hnp_support); static struct attribute *usb_udc_attrs[] = { &dev_attr_srp.attr, &dev_attr_soft_connect.attr, + &dev_attr_state.attr, &dev_attr_current_speed.attr, &dev_attr_maximum_speed.attr, diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 2e297e80d59a..32b734d88d6b 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -482,6 +482,7 @@ struct usb_gadget_ops { * @speed: Speed of current connection to USB host. * @max_speed: Maximal speed the UDC can handle. UDC must support this * and all slower speeds. + * @state: the state we are now (attached, suspended, configured, etc) * @sg_supported: true if we can handle scatter-gather * @is_otg: True if the USB device port uses a Mini-AB jack, so that the * gadget driver must provide a USB OTG descriptor. @@ -525,6 +526,7 @@ struct usb_gadget { struct list_head ep_list; /* of usb_ep */ enum usb_device_speed speed; enum usb_device_speed max_speed; + enum usb_device_state state; unsigned sg_supported:1; unsigned is_otg:1; unsigned is_a_peripheral:1; @@ -959,6 +961,13 @@ extern void usb_gadget_unmap_request(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ +/* utility to set gadget state properly */ + +extern void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state); + +/*-------------------------------------------------------------------------*/ + /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, -- cgit From 14cd592f72ea1ce1a25d7a576a5ed6aa761456bc Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 19 Dec 2011 13:01:52 +0200 Subject: usb: dwc3: gadget: implement gadget state tracking make use of the previously introduced gadget->state field. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 15 ++++++++++++--- drivers/usb/dwc3/gadget.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 1d139ca05ef1..2a82b7145052 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -512,10 +512,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) reg |= DWC3_DCFG_DEVADDR(addr); dwc3_writel(dwc->regs, DWC3_DCFG, reg); - if (addr) + if (addr) { dwc->dev_state = DWC3_ADDRESS_STATE; - else + usb_gadget_set_state(&dwc->gadget, USB_STATE_ADDRESS); + } else { dwc->dev_state = DWC3_DEFAULT_STATE; + usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); + } return 0; } @@ -549,6 +552,9 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) /* if the cfg matches and the cfg is non zero */ if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { dwc->dev_state = DWC3_CONFIGURED_STATE; + usb_gadget_set_state(&dwc->gadget, + USB_STATE_CONFIGURED); + /* * Enable transition to U1/U2 state when * nothing is pending from application. @@ -564,8 +570,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) case DWC3_CONFIGURED_STATE: ret = dwc3_ep0_delegate_req(dwc, ctrl); - if (!cfg) + if (!cfg) { dwc->dev_state = DWC3_ADDRESS_STATE; + usb_gadget_set_state(&dwc->gadget, + USB_STATE_ADDRESS); + } break; default: ret = -EINVAL; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 742eb8268e9a..2686bf26ccaf 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2137,7 +2137,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) } /* after reset -> Default State */ - dwc->dev_state = DWC3_DEFAULT_STATE; + usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); /* Recent versions support automatic phy suspend and don't need this */ if (dwc->revision < DWC3_REVISION_194A) { -- cgit From fdba5aa54cfca795b73e50d45f617a0498a29af7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 25 Jan 2013 11:28:19 +0200 Subject: usb: dwc3: remove our homebrew state mechanism We can reuse the generic implementation via our struct usb_gadget. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 7 ------- drivers/usb/dwc3/ep0.c | 34 +++++++++++++++++----------------- 2 files changed, 17 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cdd70cb78aa4..d8c36fccce96 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -494,12 +494,6 @@ enum dwc3_link_state { DWC3_LINK_STATE_MASK = 0x0f, }; -enum dwc3_device_state { - DWC3_DEFAULT_STATE, - DWC3_ADDRESS_STATE, - DWC3_CONFIGURED_STATE, -}; - /* TRB Length, PCM and Status */ #define DWC3_TRB_SIZE_MASK (0x00ffffff) #define DWC3_TRB_SIZE_LENGTH(n) ((n) & DWC3_TRB_SIZE_MASK) @@ -721,7 +715,6 @@ struct dwc3 { enum dwc3_ep0_next ep0_next_event; enum dwc3_ep0_state ep0state; enum dwc3_link_state link_state; - enum dwc3_device_state dev_state; u16 isoch_delay; u16 u2sel; diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 2a82b7145052..5acbb948b704 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -394,10 +394,13 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, u32 wIndex; u32 reg; int ret; + enum usb_device_state state; wValue = le16_to_cpu(ctrl->wValue); wIndex = le16_to_cpu(ctrl->wIndex); recip = ctrl->bRequestType & USB_RECIP_MASK; + state = dwc->gadget.state; + switch (recip) { case USB_RECIP_DEVICE: @@ -409,7 +412,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, * default control pipe */ case USB_DEVICE_U1_ENABLE: - if (dwc->dev_state != DWC3_CONFIGURED_STATE) + if (state != USB_STATE_CONFIGURED) return -EINVAL; if (dwc->speed != DWC3_DSTS_SUPERSPEED) return -EINVAL; @@ -423,7 +426,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, break; case USB_DEVICE_U2_ENABLE: - if (dwc->dev_state != DWC3_CONFIGURED_STATE) + if (state != USB_STATE_CONFIGURED) return -EINVAL; if (dwc->speed != DWC3_DSTS_SUPERSPEED) return -EINVAL; @@ -493,6 +496,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) { + enum usb_device_state state = dwc->gadget.state; u32 addr; u32 reg; @@ -502,7 +506,7 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) return -EINVAL; } - if (dwc->dev_state == DWC3_CONFIGURED_STATE) { + if (state == USB_STATE_CONFIGURED) { dev_dbg(dwc->dev, "trying to set address when configured\n"); return -EINVAL; } @@ -512,13 +516,10 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) reg |= DWC3_DCFG_DEVADDR(addr); dwc3_writel(dwc->regs, DWC3_DCFG, reg); - if (addr) { - dwc->dev_state = DWC3_ADDRESS_STATE; + if (addr) usb_gadget_set_state(&dwc->gadget, USB_STATE_ADDRESS); - } else { - dwc->dev_state = DWC3_DEFAULT_STATE; + else usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); - } return 0; } @@ -535,6 +536,7 @@ static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) { + enum usb_device_state state = dwc->gadget.state; u32 cfg; int ret; u32 reg; @@ -542,16 +544,15 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) dwc->start_config_issued = false; cfg = le16_to_cpu(ctrl->wValue); - switch (dwc->dev_state) { - case DWC3_DEFAULT_STATE: + switch (state) { + case USB_STATE_DEFAULT: return -EINVAL; break; - case DWC3_ADDRESS_STATE: + case USB_STATE_ADDRESS: ret = dwc3_ep0_delegate_req(dwc, ctrl); /* if the cfg matches and the cfg is non zero */ if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { - dwc->dev_state = DWC3_CONFIGURED_STATE; usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); @@ -568,13 +569,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) } break; - case DWC3_CONFIGURED_STATE: + case USB_STATE_CONFIGURED: ret = dwc3_ep0_delegate_req(dwc, ctrl); - if (!cfg) { - dwc->dev_state = DWC3_ADDRESS_STATE; + if (!cfg) usb_gadget_set_state(&dwc->gadget, USB_STATE_ADDRESS); - } break; default: ret = -EINVAL; @@ -629,10 +628,11 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req) static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) { struct dwc3_ep *dep; + enum usb_device_state state = dwc->gadget.state; u16 wLength; u16 wValue; - if (dwc->dev_state == DWC3_DEFAULT_STATE) + if (state == USB_STATE_DEFAULT) return -EINVAL; wValue = le16_to_cpu(ctrl->wValue); -- cgit From 6b2a0eb854602b627a21b0256ae556506e91261e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 14:28:54 +0200 Subject: usb: dwc3: debugfs: add two missing Link States for Reset and Resume we were going to print "UNKNOWN" when we actually knew what those were. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 4a752e730c5f..c740c7643f43 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -577,6 +577,12 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) case DWC3_LINK_STATE_LPBK: seq_printf(s, "Loopback\n"); break; + case DWC3_LINK_STATE_RESET: + seq_printf(s, "Reset\n"); + break; + case DWC3_LINK_STATE_RESUME: + seq_printf(s, "Resume\n"); + break; default: seq_printf(s, "UNKNOWN %d\n", reg); } -- cgit From 5b9ec339e45916ee682b8402597d7f2c6a04da17 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 14:29:39 +0200 Subject: usb: dwc3: debugfs: when unknown, print only the state value whenever we grab an unknown link_state we were printing the entire register value as a integer but that's hardly useful; instead, let's print only the bogus state value. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index c740c7643f43..5512560e972b 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -584,7 +584,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) seq_printf(s, "Resume\n"); break; default: - seq_printf(s, "UNKNOWN %d\n", reg); + seq_printf(s, "UNKNOWN %d\n", state); } return 0; -- cgit From 4ec0ddb1b4fe3f7d93fdc862d2a7338cd354fe94 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 16:17:31 +0200 Subject: usb: dwc3: debugfs: mark our regset structure const nobody should be modifying that structure and debugfs has already being fixed to take const arguments, so we won't cause any new compile warnings. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 5512560e972b..a1bac9a07837 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -59,7 +59,7 @@ .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \ } -static struct debugfs_reg32 dwc3_regs[] = { +static const struct debugfs_reg32 dwc3_regs[] = { dump_register(GSBUSCFG0), dump_register(GSBUSCFG1), dump_register(GTXTHRCFG), -- cgit From dbfff05d7c9b982e364c90a699961fb7000c6181 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 16:24:49 +0200 Subject: usb: dwc3: debugfs: improve debugfs file creation when commit 388e5c5 (usb: dwc3: remove dwc3 dependency on host AND gadget.) changed the way debugfs files are created, it failed to note that 'mode' is necessary in Dual Role mode only while 'testmode' and 'link_state' are valid in Dual Role and Peripheral-only builds. Fix this while also converting pre- processor conditional to C conditionals. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index a1bac9a07837..8b23d0455b1c 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -667,28 +667,31 @@ int dwc3_debugfs_init(struct dwc3 *dwc) goto err1; } -#if IS_ENABLED(CONFIG_USB_DWC3_GADGET) - file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, - dwc, &dwc3_mode_fops); - if (!file) { - ret = -ENOMEM; - goto err1; + if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { + file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_mode_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } } - file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, - dwc, &dwc3_testmode_fops); - if (!file) { - ret = -ENOMEM; - goto err1; - } - - file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, - dwc, &dwc3_link_state_fops); - if (!file) { - ret = -ENOMEM; - goto err1; + if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) || + IS_ENABLED(CONFIG_USB_DWC3_GADGET)) { + file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_testmode_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } + + file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_link_state_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } } -#endif return 0; -- cgit From 67d0b500ebbe78e2ca50036721fef530dfd3d9c8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 22 Feb 2013 16:31:07 +0200 Subject: usb: dwc3: core: avoid checkpatch.pl warning trivial patch to avoid "over 80-chars" rule break. No functional changes. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 75a9f88a5ad6..b81b3357f007 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -140,7 +140,8 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc, * Returns a pointer to the allocated event buffer structure on success * otherwise ERR_PTR(errno). */ -static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) +static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, + unsigned length) { struct dwc3_event_buffer *evt; -- cgit From 756380e04276c9099f41716d279d24e5847b1030 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 09:46:18 +0200 Subject: usb: gadget: pxa27x_udc: drop ARCH_PXA dependency This driver can compile in any arch quite easily by just removing a few headers and dropping cpu_is_* check from module_init. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 1 - drivers/usb/gadget/pxa27x_udc.c | 11 ++--------- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5a0c541daf89..50586fffa9fb 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -258,7 +258,6 @@ config USB_RENESAS_USBHS_UDC config USB_PXA27X tristate "PXA 27x" - depends on ARCH_PXA && (PXA27x || PXA3xx) select USB_OTG_UTILS help Intel's PXA 27x series XScale ARM v5TE processors include diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 07ce1477f911..def73f2aa18b 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -24,14 +24,12 @@ #include #include #include - -#include -#include +#include +#include #include #include #include -#include #include "pxa27x_udc.h" @@ -2624,15 +2622,10 @@ static struct platform_driver udc_driver = { static int __init udc_init(void) { - if (!cpu_is_pxa27x() && !cpu_is_pxa3xx()) - return -ENODEV; - - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); return platform_driver_probe(&udc_driver, pxa_udc_probe); } module_init(udc_init); - static void __exit udc_exit(void) { platform_driver_unregister(&udc_driver); -- cgit From ef222cb5b575df57d8cd511965800519b90a6c31 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 09:47:50 +0200 Subject: usb: gadget: pxa27x_udc: switch over to module_platform_driver just removing some boilerplate code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index def73f2aa18b..3276a6d278fd 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2410,7 +2410,7 @@ static struct pxa_udc memory = { * Perform basic init : allocates udc clock, creates sysfs files, requests * irq. */ -static int __init pxa_udc_probe(struct platform_device *pdev) +static int pxa_udc_probe(struct platform_device *pdev) { struct resource *regs; struct pxa_udc *udc = &memory; @@ -2612,6 +2612,7 @@ static struct platform_driver udc_driver = { .name = "pxa27x-udc", .owner = THIS_MODULE, }, + .probe = pxa_udc_probe, .remove = __exit_p(pxa_udc_remove), .shutdown = pxa_udc_shutdown, #ifdef CONFIG_PM @@ -2620,17 +2621,7 @@ static struct platform_driver udc_driver = { #endif }; -static int __init udc_init(void) -{ - return platform_driver_probe(&udc_driver, pxa_udc_probe); -} -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); +module_platform_driver(udc_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Robert Jarzmik"); -- cgit From 658c8cf14dce1093e9f810f7e04a711ed79da6bd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:50:42 +0200 Subject: usb: gadget: udc-core: copy dma-related parameters from parent gadget's device pointer now is guaranteed to have valid dma_mask, dma_parms and coherent_dma_mask fields since we're always copying from our parent device. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 8a1eeb24ae6a..3e19a016c197 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -185,6 +185,10 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) dev_set_name(&gadget->dev, "gadget"); + dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask); + gadget->dev.dma_parms = parent->dma_parms; + gadget->dev.dma_mask = parent->dma_mask; + ret = device_register(&gadget->dev); if (ret) goto err2; -- cgit From 2ed14320f3fed9e5b774ef68bdf73a4f3e28844e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:59:41 +0200 Subject: usb: gadget: udc-core: initialize parent if udc-core always does it, we can delete some extra lines from all UDC drivers. Besides, it avoids mistakes from happening and propagating. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 3e19a016c197..447a1614736e 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -184,6 +184,7 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) goto err1; dev_set_name(&gadget->dev, "gadget"); + gadget->dev.parent = parent; dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask); gadget->dev.dma_parms = parent->dma_parms; -- cgit From 036804a4b7089bdff9e5c70805c09ce4133b4440 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:52:43 +0200 Subject: usb: gadget: chipidea: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 1b65ac8f3c9b..e303fd4b1b93 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1717,9 +1717,6 @@ static int udc_start(struct ci13xxx *ci) INIT_LIST_HEAD(&ci->gadget.ep_list); - ci->gadget.dev.dma_mask = dev->dma_mask; - ci->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask; - ci->gadget.dev.parent = dev; ci->gadget.dev.release = udc_release; /* alloc resources */ -- cgit From 6c39d90393a2feff052f9cb5e460a5c2b25d8214 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:53:40 +0200 Subject: usb: gadget: amd5536udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index eec4461fb45f..c9941222e4a7 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3244,8 +3244,6 @@ static int udc_pci_probe( dev->phys_addr = resource; dev->irq = pdev->irq; dev->pdev = pdev; - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; /* general probing */ if (udc_probe(dev) == 0) -- cgit From 442803d844315a96ec5f3ed981a427ed56d41835 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:54:46 +0200 Subject: usb: gadget: atmel_usba_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 94aeba84b21e..e85d50b75de3 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1885,9 +1885,6 @@ static int __init usba_udc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", (unsigned long)fifo->start, udc->fifo); - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - platform_set_drvdata(pdev, udc); /* Make sure we start from a clean slate */ -- cgit From 9d2d93d86de32b82939a32d6abe6c8c5d3cb97f2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 10:57:06 +0200 Subject: usb: gadget: bcm63xx_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/bcm63xx_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index d4f73e1b37e6..e7d2cd0b8f94 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2371,9 +2371,7 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) udc->gadget.ops = &bcm63xx_udc_ops; udc->gadget.name = dev_name(dev); - udc->gadget.dev.parent = dev; udc->gadget.dev.release = bcm63xx_udc_gadget_release; - udc->gadget.dev.dma_mask = dev->dma_mask; if (!pd->use_fullspeed && !use_fullspeed) udc->gadget.max_speed = USB_SPEED_HIGH; -- cgit From 9502d03c429860f83370615922bcb45050417ad8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:03:46 +0200 Subject: usb: gadget: fusb300_udc: remove unnecessary initializations udc-core nos sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 5c9dd064767f..7f48aa6a5d3f 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1420,8 +1420,6 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ops = &fusb300_gadget_ops; fusb300->gadget.max_speed = USB_SPEED_HIGH; - fusb300->gadget.dev.parent = &pdev->dev; - fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; fusb300->gadget.dev.release = pdev->dev.release; fusb300->gadget.name = udc_name; fusb300->reg = reg; -- cgit From 1a36315c976bb1e0f8aa6e18c149a951d685cc20 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:04:34 +0200 Subject: usb: gadget: goku_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 8a6c66618bd3..c02cbdd182c5 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1754,8 +1754,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_FULL; /* the "gadget" abstracts/virtualizes the controller */ - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; -- cgit From 975cbd49391822bc98f693e3a43d26754849948a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:05:19 +0200 Subject: usb: gadget: goku_udc: remove unused macro DMA_ADDR_INVALID isn't used anymore on goku_udc, we can just delete it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index c02cbdd182c5..1c070f4209f0 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -51,8 +51,6 @@ #define DRIVER_DESC "TC86C001 USB Device Controller" #define DRIVER_VERSION "30-Oct 2003" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - static const char driver_name [] = "goku_udc"; static const char driver_desc [] = DRIVER_DESC; @@ -275,7 +273,6 @@ goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) if (!req) return NULL; - req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); return &req->req; } -- cgit From 53fae098be09eeced37cf06419ae4e9c872cf0d0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:06:17 +0200 Subject: usb: gadget: imx_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/imx_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 9c5b7451a7d1..c29d9e81dae4 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1461,9 +1461,6 @@ static int __init imx_udc_probe(struct platform_device *pdev) imx_usb->clk = clk; imx_usb->dev = &pdev->dev; - imx_usb->gadget.dev.parent = &pdev->dev; - imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask; - platform_set_drvdata(pdev, imx_usb); usb_init_data(imx_usb); -- cgit From 859d02c2d84da10536d1e0f1cebfa9105023f8e6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:07:39 +0200 Subject: usb: gadget: m66592-udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index eb61d0b54f21..ae33e535c283 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1608,8 +1608,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->gadget.ops = &m66592_gadget_ops; m66592->gadget.max_speed = USB_SPEED_HIGH; - m66592->gadget.dev.parent = &pdev->dev; - m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; m66592->gadget.dev.release = pdev->dev.release; m66592->gadget.name = udc_name; -- cgit From 1048d83d5bfcbf1c71391fc1aae57326e940149c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:10:03 +0200 Subject: usb: dwc3: gadget: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2686bf26ccaf..322fb0bf6fce 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2569,13 +2569,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.max_speed = USB_SPEED_SUPER; dwc->gadget.speed = USB_SPEED_UNKNOWN; - dwc->gadget.dev.parent = dwc->dev; dwc->gadget.sg_supported = true; - - dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask); - - dwc->gadget.dev.dma_parms = dwc->dev->dma_parms; - dwc->gadget.dev.dma_mask = dwc->dev->dma_mask; dwc->gadget.dev.release = dwc3_gadget_release; dwc->gadget.name = "dwc3-gadget"; -- cgit From 2b5ced1a0cf2407e2bbe66e49687f6eb59d5df94 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:13:28 +0200 Subject: usb: gadget: mv_u3d_core: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index e5735fc610de..e6521b195449 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1955,8 +1955,6 @@ static int mv_u3d_probe(struct platform_device *dev) u3d->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ /* the "gadget" abstracts/virtualizes the controller */ - u3d->gadget.dev.parent = &dev->dev; - u3d->gadget.dev.dma_mask = dev->dev.dma_mask; u3d->gadget.dev.release = mv_u3d_gadget_release; u3d->gadget.name = driver_name; /* gadget name */ -- cgit From d606b356cd07ffa3daea6dfcbf50fc2cbf4ba9a3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:14:14 +0200 Subject: usb: gadget: mv_udc_core: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 7f4d19d75578..b3061112d13a 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2268,8 +2268,6 @@ static int mv_udc_probe(struct platform_device *pdev) udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ /* the "gadget" abstracts/virtualizes the controller */ - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = pdev->dev.dma_mask; udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ -- cgit From 162303f6d39c94d984d291fa4f13510093356404 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:14:54 +0200 Subject: usb: gadget: net2272: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 78c8bb538332..bfb55d382cf9 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2235,8 +2235,6 @@ static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq) ret->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - ret->gadget.dev.parent = dev; - ret->gadget.dev.dma_mask = dev->dma_mask; ret->gadget.dev.release = net2272_gadget_release; ret->gadget.name = driver_name; -- cgit From 2127ce0f2f11b2817e8ed8e3bd728731e06baac0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:15:29 +0200 Subject: usb: gadget: net2280: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 2089d9b0058c..6ce25133c14c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2710,8 +2710,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; -- cgit From 981e070fdde4316d5a8d0c9681db505ba6a833eb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:16:36 +0200 Subject: usb: gadget: omap_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b23c861e2a97..bda1abdd75d8 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2631,12 +2631,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.speed = USB_SPEED_UNKNOWN; udc->gadget.max_speed = USB_SPEED_FULL; udc->gadget.name = driver_name; - udc->gadget.dev.release = omap_udc_release; - udc->gadget.dev.parent = &odev->dev; - if (use_dma) - udc->gadget.dev.dma_mask = odev->dev.dma_mask; - udc->transceiver = xceiv; /* ep0 is special; put it right after the SETUP buffer */ -- cgit From 91497600e27abf38ca00ead504fe2fdffab7e5c4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:17:25 +0200 Subject: usb: gadget: pch_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index e8c9afd8fbf0..c1db902ebb7f 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -3193,8 +3193,6 @@ static int pch_udc_probe(struct pci_dev *pdev, if (retval) goto finished; - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; dev->gadget.dev.release = gadget_release; dev->gadget.name = KBUILD_MODNAME; dev->gadget.max_speed = USB_SPEED_HIGH; -- cgit From 6966fe8add4d47a2d55cab197925165e772f1197 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:19:56 +0200 Subject: usb: gadget: pxa25x_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index e29bb878b2d7..9fea05340689 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2138,9 +2138,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->timer.function = udc_watchdog; dev->timer.data = (unsigned long) dev; - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - the_controller = dev; platform_set_drvdata(pdev, dev); -- cgit From b372c9572c4513500f0811371f3bd09616a64eba Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:20:39 +0200 Subject: usb: gadget: pxa27x_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 3276a6d278fd..5fda425f263f 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2453,8 +2453,6 @@ static int pxa_udc_probe(struct platform_device *pdev) goto err_map; } - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = NULL; udc->vbus_sensed = 0; the_controller = udc; -- cgit From 71b0dd272d9c5d985c4174632a28d6b8c990093c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:21:35 +0200 Subject: usb: gadget: r8a66597-udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/r8a66597-udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index a67d47708b98..2de775dbd92c 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1915,8 +1915,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->gadget.ops = &r8a66597_gadget_ops; r8a66597->gadget.max_speed = USB_SPEED_HIGH; - r8a66597->gadget.dev.parent = &pdev->dev; - r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; r8a66597->gadget.dev.release = pdev->dev.release; r8a66597->gadget.name = udc_name; -- cgit From 2015760c2e626cc71ecd471648941b29789972bf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:23:05 +0200 Subject: usb: gadget: s3c-hsotg: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 2812fa51e296..9d2330de5fcf 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2927,7 +2927,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, hsotg->driver = driver; hsotg->gadget.dev.driver = &driver->driver; hsotg->gadget.dev.of_node = hsotg->dev->of_node; - hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; hsotg->gadget.speed = USB_SPEED_UNKNOWN; ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), @@ -3534,8 +3533,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); - hsotg->gadget.dev.parent = dev; - hsotg->gadget.dev.dma_mask = dev->dma_mask; hsotg->gadget.dev.release = s3c_hsotg_release; /* reset the system */ -- cgit From 4c422049bd0f373b79b3dfbb7f984958c80bc7aa Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:23:52 +0200 Subject: usb: gadget: s3c-hsudc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 7fc3de537c9a..8db7b10f3d07 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1306,8 +1306,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) hsudc->gadget.max_speed = USB_SPEED_HIGH; hsudc->gadget.ops = &s3c_hsudc_gadget_ops; hsudc->gadget.name = dev_name(dev); - hsudc->gadget.dev.parent = dev; - hsudc->gadget.dev.dma_mask = dev->dma_mask; hsudc->gadget.ep0 = &hsudc->ep[0].ep; hsudc->gadget.is_otg = 0; hsudc->gadget.is_a_peripheral = 0; -- cgit From 31bff47aa2147ceab5d88a12f115afa44cdf4449 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:24:30 +0200 Subject: usb: gadget: s3c2410_udc: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index a669081bbb88..e15d1bbc2ad9 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1824,9 +1824,6 @@ static int s3c2410_udc_probe(struct platform_device *pdev) goto err_mem; } - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = pdev->dev.dma_mask; - the_controller = udc; platform_set_drvdata(pdev, udc); -- cgit From 5e6e3d3814004a509c9023abfc86ddea6803f8e1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 11:25:21 +0200 Subject: usb: musb: gadget: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d35a375c6070..2dd952c330fd 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1782,8 +1782,6 @@ int musb_gadget_setup(struct musb *musb) musb->g.speed = USB_SPEED_UNKNOWN; /* this "gadget" abstracts/virtualizes the controller */ - musb->g.dev.parent = musb->controller; - musb->g.dev.dma_mask = musb->controller->dma_mask; musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; musb->g.is_otg = 1; -- cgit From 8a1c33075e5e42074397aa8478fc16481e306b31 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:59:40 +0200 Subject: usb: gadget: fsl_udc_core: remove unnecessary initializations udc-core now sets dma-related and parent fields for us, we don't need to do it ourselves. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index c948241c6507..acb176d54067 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2497,7 +2497,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) /* Setup gadget.dev and register with kernel */ dev_set_name(&udc_controller->gadget.dev, "gadget"); udc_controller->gadget.dev.release = fsl_udc_release; - udc_controller->gadget.dev.parent = &pdev->dev; udc_controller->gadget.dev.of_node = pdev->dev.of_node; if (!IS_ERR_OR_NULL(udc_controller->transceiver)) -- cgit From 70d3a49878cb3fc0e5ec0bd1e607c7ac63743f67 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 13:51:24 +0200 Subject: usb: gadget: udc-core: initialize gadget->dev.driver if we initialize gadget->dev.driver ourselves, UDC drivers won't have to do the same, so we can remove some duplicated code. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 447a1614736e..2423d024654f 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -247,6 +247,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) udc->driver = NULL; udc->dev.driver = NULL; + udc->gadget->dev.driver = NULL; } /** @@ -296,6 +297,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->driver = driver; udc->dev.driver = &driver->driver; + udc->gadget->dev.driver = &driver->driver; ret = driver->bind(udc->gadget, driver); if (ret) @@ -314,6 +316,7 @@ err1: udc->driver->function, ret); udc->driver = NULL; udc->dev.driver = NULL; + udc->gadget->dev.driver = NULL; return ret; } -- cgit From 180cc68ed82ced0c19f5a478f8d1cdd2024c1875 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:15:15 +0200 Subject: usb: dwc3: gadget: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 322fb0bf6fce..9339eb10508f 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1519,7 +1519,6 @@ static int dwc3_gadget_start(struct usb_gadget *g, } dwc->gadget_driver = driver; - dwc->gadget.dev.driver = &driver->driver; reg = dwc3_readl(dwc->regs, DWC3_DCFG); reg &= ~(DWC3_DCFG_SPEED_MASK); @@ -1607,7 +1606,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g, __dwc3_gadget_ep_disable(dwc->eps[1]); dwc->gadget_driver = NULL; - dwc->gadget.dev.driver = NULL; spin_unlock_irqrestore(&dwc->lock, flags); -- cgit From fd3682d9fd49210447c37085fe4e96e74061ae7f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:15:51 +0200 Subject: usb: gadget: amd5536udc: don't touch gadget.dev.driver udc-core handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index c9941222e4a7..a8ff93cf344d 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1922,7 +1922,6 @@ static int amd5536_udc_start(struct usb_gadget *g, driver->driver.bus = NULL; dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; /* Some gadget drivers use both ep0 directions. * NOTE: to gadget driver, ep0 is just one endpoint... @@ -1973,7 +1972,6 @@ static int amd5536_udc_stop(struct usb_gadget *g, shutdown(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - dev->gadget.dev.driver = NULL; dev->driver = NULL; /* set SD */ -- cgit From 8f3d7c86944ad03b2b45f1f4442577f087bb8591 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:16:21 +0200 Subject: usb: gadget: at91_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/at91_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 9936de9bbe50..a690d64217f4 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1631,7 +1631,6 @@ static int at91_start(struct usb_gadget *gadget, udc = container_of(gadget, struct at91_udc, gadget); udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; udc->gadget.dev.of_node = udc->pdev->dev.of_node; udc->enabled = 1; udc->selfpowered = 1; @@ -1652,7 +1651,6 @@ static int at91_stop(struct usb_gadget *gadget, at91_udp_write(udc, AT91_UDP_IDR, ~0); spin_unlock_irqrestore(&udc->lock, flags); - udc->gadget.dev.driver = NULL; udc->driver = NULL; DBG("unbound from %s\n", driver->driver.name); -- cgit From 1503a33932732dfbd880b905993e4122a7b53f53 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:34:17 +0200 Subject: usb: gadget: atmel_usba_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e85d50b75de3..f2a970f75bfa 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1784,7 +1784,6 @@ static int atmel_usba_start(struct usb_gadget *gadget, udc->devstatus = 1 << USB_DEVICE_SELF_POWERED; udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&udc->lock, flags); clk_enable(udc->pclk); @@ -1826,7 +1825,6 @@ static int atmel_usba_stop(struct usb_gadget *gadget, toggle_bias(0); usba_writel(udc, CTRL, USBA_DISABLE_MASK); - udc->gadget.dev.driver = NULL; udc->driver = NULL; clk_disable(udc->hclk); -- cgit From 155149e6724435eff47e0c6427b271b23815b40e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:34:33 +0200 Subject: usb: gadget: bcm63xx_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/bcm63xx_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index e7d2cd0b8f94..904d4746922d 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -1819,7 +1819,6 @@ static int bcm63xx_udc_start(struct usb_gadget *gadget, udc->driver = driver; driver->driver.bus = NULL; - udc->gadget.dev.driver = &driver->driver; udc->gadget.dev.of_node = udc->dev->of_node; spin_unlock_irqrestore(&udc->lock, flags); @@ -1841,7 +1840,6 @@ static int bcm63xx_udc_stop(struct usb_gadget *gadget, spin_lock_irqsave(&udc->lock, flags); udc->driver = NULL; - udc->gadget.dev.driver = NULL; /* * If we switch the PHY too abruptly after dropping D+, the host -- cgit From 42c82fb4d1658bb9630f6248178f79d8854c5bfd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:34:49 +0200 Subject: usb: gadget: dummy_hcd: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c4f27d5a2b9c..9d54c01cbf56 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -912,7 +912,6 @@ static int dummy_udc_start(struct usb_gadget *g, dum->devstatus = 0; dum->driver = driver; - dum->gadget.dev.driver = &driver->driver; dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); return 0; @@ -927,7 +926,6 @@ static int dummy_udc_stop(struct usb_gadget *g, dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", driver->driver.name); - dum->gadget.dev.driver = NULL; dum->driver = NULL; return 0; -- cgit From fc2dba950b27e6ec412efb932458cd6abfe77940 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:06 +0200 Subject: usb: gadget: fsl_qe_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 0e7531bd33f4..37feb62fa930 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2296,7 +2296,6 @@ static int fsl_qe_start(struct usb_gadget *gadget, driver->driver.bus = NULL; /* hook up the driver */ udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; udc->gadget.speed = driver->max_speed; /* Enable IRQ reg and Set usbcmd reg EN bit */ @@ -2338,7 +2337,6 @@ static int fsl_qe_stop(struct usb_gadget *gadget, nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc->lock, flags); - udc->gadget.dev.driver = NULL; udc->driver = NULL; dev_info(udc->dev, "unregistered gadget driver '%s'\r\n", -- cgit From a1827ef6ac81072e9f2894d0db8cfa956d1b2a8d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:15 +0200 Subject: usb: gadget: fsl_udc_core: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index acb176d54067..4d5ff236bed4 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1939,7 +1939,6 @@ static int fsl_udc_start(struct usb_gadget *g, driver->driver.bus = NULL; /* hook up the driver */ udc_controller->driver = driver; - udc_controller->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&udc_controller->lock, flags); if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { @@ -1955,7 +1954,6 @@ static int fsl_udc_start(struct usb_gadget *g, if (retval < 0) { ERR("can't bind to transceiver\n"); driver->unbind(&udc_controller->gadget); - udc_controller->gadget.dev.driver = 0; udc_controller->driver = 0; return retval; } @@ -1998,7 +1996,6 @@ static int fsl_udc_stop(struct usb_gadget *g, nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc_controller->lock, flags); - udc_controller->gadget.dev.driver = NULL; udc_controller->driver = NULL; return 0; -- cgit From 6a609129c2e4da76bc3607671d33d660faf52590 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:24 +0200 Subject: usb: gadget: fusb300_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 7f48aa6a5d3f..d69e840b101b 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1313,7 +1313,6 @@ static int fusb300_udc_start(struct usb_gadget *g, /* hook up the driver */ driver->driver.bus = NULL; fusb300->driver = driver; - fusb300->gadget.dev.driver = &driver->driver; return 0; } @@ -1324,7 +1323,6 @@ static int fusb300_udc_stop(struct usb_gadget *g, struct fusb300 *fusb300 = to_fusb300(g); driver->unbind(&fusb300->gadget); - fusb300->gadget.dev.driver = NULL; init_controller(fusb300); fusb300->driver = NULL; -- cgit From 88060d60b618cd71a5e109ac9d3d629556dcea25 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:31 +0200 Subject: usb: gadget: goku_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 1c070f4209f0..aa1976ee34e0 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1351,7 +1351,6 @@ static int goku_udc_start(struct usb_gadget *g, /* hook up the driver */ driver->driver.bus = NULL; dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; /* * then enable host detection and ep0; and we're ready @@ -1391,7 +1390,6 @@ static int goku_udc_stop(struct usb_gadget *g, dev->driver = NULL; stop_activity(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - dev->gadget.dev.driver = NULL; return 0; } -- cgit From 9fa4c960aa5ed69cde90283d8a0a750a2f36504c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:40 +0200 Subject: usb: gadget: imx_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/imx_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index c29d9e81dae4..b5cebd6b0d7a 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1338,7 +1338,6 @@ static int imx_udc_start(struct usb_gadget *gadget, imx_usb = container_of(gadget, struct imx_udc_struct, gadget); /* first hook up the driver ... */ imx_usb->driver = driver; - imx_usb->gadget.dev.driver = &driver->driver; D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n", __func__, driver->driver.name); @@ -1358,7 +1357,6 @@ static int imx_udc_stop(struct usb_gadget *gadget, imx_udc_disable(imx_usb); del_timer(&imx_usb->timer); - imx_usb->gadget.dev.driver = NULL; imx_usb->driver = NULL; D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n", -- cgit From ee4b47cf6b026d35528ecc78e7c82d2c5eae28be Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:48 +0200 Subject: usb: gadget: lpc32xx_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 147832783900..b943d8cdfbf7 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2946,7 +2946,6 @@ static int lpc32xx_start(struct usb_gadget *gadget, } udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; udc->gadget.dev.of_node = udc->dev->of_node; udc->enabled = 1; udc->selfpowered = 1; @@ -2995,7 +2994,6 @@ static int lpc32xx_stop(struct usb_gadget *gadget, } udc->enabled = 0; - udc->gadget.dev.driver = NULL; udc->driver = NULL; return 0; -- cgit From e3ee46f291875a18afe9debeeb676483953e22e7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:53 +0200 Subject: usb: gadget: m66592-udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index ae33e535c283..21a20a6ffb66 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1471,7 +1471,6 @@ static int m66592_udc_start(struct usb_gadget *g, /* hook up the driver */ driver->driver.bus = NULL; m66592->driver = driver; - m66592->gadget.dev.driver = &driver->driver; m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { @@ -1494,7 +1493,6 @@ static int m66592_udc_stop(struct usb_gadget *g, m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); driver->unbind(&m66592->gadget); - m66592->gadget.dev.driver = NULL; init_controller(m66592); disable_controller(m66592); -- cgit From 900b5817d874dd894ca05b2cd8df8acd63dfd64e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:35:59 +0200 Subject: usb: gadget: mv_u3d_core: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index e6521b195449..dc6445046da7 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1264,7 +1264,6 @@ static int mv_u3d_start(struct usb_gadget *g, /* hook up the driver ... */ driver->driver.bus = NULL; u3d->driver = driver; - u3d->gadget.dev.driver = &driver->driver; u3d->ep0_dir = USB_DIR_OUT; @@ -1302,7 +1301,6 @@ static int mv_u3d_stop(struct usb_gadget *g, spin_unlock_irqrestore(&u3d->lock, flags); - u3d->gadget.dev.driver = NULL; u3d->driver = NULL; return 0; -- cgit From 9ab7f79923f7ff2af798c42da104a03a936f704d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:05 +0200 Subject: usb: gadget: mv_udc_core: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index b3061112d13a..d1b243d76669 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -1352,7 +1352,6 @@ static int mv_udc_start(struct usb_gadget *gadget, /* hook up the driver ... */ driver->driver.bus = NULL; udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; udc->usb_state = USB_STATE_ATTACHED; udc->ep0_state = WAIT_FOR_SETUP; @@ -1367,7 +1366,6 @@ static int mv_udc_start(struct usb_gadget *gadget, dev_err(&udc->dev->dev, "unable to register peripheral to otg\n"); udc->driver = NULL; - udc->gadget.dev.driver = NULL; return retval; } } @@ -1403,7 +1401,6 @@ static int mv_udc_stop(struct usb_gadget *gadget, spin_unlock_irqrestore(&udc->lock, flags); /* unbind gadget driver */ - udc->gadget.dev.driver = NULL; udc->driver = NULL; return 0; -- cgit From 812abae5d66ce1a7a102afe1b3564df597687e79 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:14 +0200 Subject: usb: gadget: net2272: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index bfb55d382cf9..af99223e0126 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -1467,7 +1467,6 @@ static int net2272_start(struct usb_gadget *_gadget, dev->softconnect = 1; driver->driver.bus = NULL; dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. @@ -1510,7 +1509,6 @@ static int net2272_stop(struct usb_gadget *_gadget, stop_activity(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); - dev->gadget.dev.driver = NULL; dev->driver = NULL; dev_dbg(dev->dev, "unregistered driver '%s'\n", driver->driver.name); -- cgit From 68abc94f8de89ef885332a101654a0aef2db6d97 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:21 +0200 Subject: usb: gadget: net2280: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 6ce25133c14c..9e4f0a26108e 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -1896,7 +1896,6 @@ static int net2280_start(struct usb_gadget *_gadget, dev->softconnect = 1; driver->driver.bus = NULL; dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; retval = device_create_file (&dev->pdev->dev, &dev_attr_function); if (retval) goto err_unbind; @@ -1925,7 +1924,6 @@ err_func: device_remove_file (&dev->pdev->dev, &dev_attr_function); err_unbind: driver->unbind (&dev->gadget); - dev->gadget.dev.driver = NULL; dev->driver = NULL; return retval; } @@ -1961,7 +1959,6 @@ static int net2280_stop(struct usb_gadget *_gadget, stop_activity (dev, driver); spin_unlock_irqrestore (&dev->lock, flags); - dev->gadget.dev.driver = NULL; dev->driver = NULL; net2280_led_active (dev, 0); -- cgit From f6511d153eff9cd16e44ab54faa63149e2ddef75 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:26 +0200 Subject: usb: gadget: omap_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index bda1abdd75d8..19420ad128ce 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2067,7 +2067,6 @@ static int omap_udc_start(struct usb_gadget *g, /* hook up the driver */ driver->driver.bus = NULL; udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&udc->lock, flags); if (udc->dc_clk != NULL) @@ -2083,7 +2082,6 @@ static int omap_udc_start(struct usb_gadget *g, ERR("can't bind to transceiver\n"); if (driver->unbind) { driver->unbind(&udc->gadget); - udc->gadget.dev.driver = NULL; udc->driver = NULL; } goto done; @@ -2129,7 +2127,6 @@ static int omap_udc_stop(struct usb_gadget *g, udc_quiesce(udc); spin_unlock_irqrestore(&udc->lock, flags); - udc->gadget.dev.driver = NULL; udc->driver = NULL; if (udc->dc_clk != NULL) -- cgit From 37e337e1d3e20b101d6f3a6b55e7c7118a6d99a0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:40 +0200 Subject: usb: gadget: pch_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index c1db902ebb7f..79cf2966f634 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2988,7 +2988,6 @@ static int pch_udc_start(struct usb_gadget *g, driver->driver.bus = NULL; dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; /* get ready for ep0 traffic */ pch_udc_setup_ep0(dev); @@ -3009,7 +3008,6 @@ static int pch_udc_stop(struct usb_gadget *g, pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); /* Assures that there are no pending requests with this driver */ - dev->gadget.dev.driver = NULL; dev->driver = NULL; dev->connected = 0; -- cgit From 83a9adc9d815d12797df45a30c0f391c07c762bd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:47 +0200 Subject: usb: gadget: pxa25x_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 9fea05340689..ef47495dec8f 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1263,7 +1263,6 @@ static int pxa25x_udc_start(struct usb_gadget *g, /* first hook up the driver ... */ dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; dev->pullup = 1; /* ... then enable host detection and ep0; and we're ready @@ -1325,7 +1324,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g, if (!IS_ERR_OR_NULL(dev->transceiver)) (void) otg_set_peripheral(dev->transceiver->otg, NULL); - dev->gadget.dev.driver = NULL; dev->driver = NULL; dump_state(dev); -- cgit From 0280f4d99a1e9ff2883a3df20ad2c995110ed011 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:52 +0200 Subject: usb: gadget: pxa27x_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 5fda425f263f..ad954c49d061 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1809,7 +1809,6 @@ static int pxa27x_udc_start(struct usb_gadget *g, /* first hook up the driver ... */ udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; dplus_pullup(udc, 1); if (!IS_ERR_OR_NULL(udc->transceiver)) { @@ -1827,7 +1826,6 @@ static int pxa27x_udc_start(struct usb_gadget *g, fail: udc->driver = NULL; - udc->gadget.dev.driver = NULL; return retval; } -- cgit From 430e958e1d732b1d27d9ba31cdf79e5656b1a41b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:36:58 +0200 Subject: usb: gadget: s3c-hsotg: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 9d2330de5fcf..dfe72889c5b2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2925,7 +2925,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, driver->driver.bus = NULL; hsotg->driver = driver; - hsotg->gadget.dev.driver = &driver->driver; hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed = USB_SPEED_UNKNOWN; @@ -2942,7 +2941,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, err: hsotg->driver = NULL; - hsotg->gadget.dev.driver = NULL; return ret; } @@ -2977,7 +2975,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, hsotg->driver = NULL; hsotg->gadget.speed = USB_SPEED_UNKNOWN; - hsotg->gadget.dev.driver = NULL; spin_unlock_irqrestore(&hsotg->lock, flags); -- cgit From 492a39022ad5825d8edbbdca993e18bf3f37f5fc Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:37:04 +0200 Subject: usb: gadget: s3c-hsudc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 8db7b10f3d07..bfe79103abab 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1154,7 +1154,6 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, return -EBUSY; hsudc->driver = driver; - hsudc->gadget.dev.driver = &driver->driver; ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); @@ -1190,7 +1189,6 @@ err_otg: regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); err_supplies: hsudc->driver = NULL; - hsudc->gadget.dev.driver = NULL; return ret; } @@ -1208,7 +1206,6 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, spin_lock_irqsave(&hsudc->lock, flags); hsudc->driver = NULL; - hsudc->gadget.dev.driver = NULL; hsudc->gadget.speed = USB_SPEED_UNKNOWN; s3c_hsudc_uninit_phy(); -- cgit From bbdb72702e9268cad8136b6bd0d8862eed90535d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:37:12 +0200 Subject: usb: gadget: s3c2410_udc: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index e15d1bbc2ad9..d0e75e1b3ccb 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1674,7 +1674,6 @@ static int s3c2410_udc_start(struct usb_gadget *g, /* Hook the driver */ udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; /* Enable udc */ s3c2410_udc_enable(udc); -- cgit From 8707d5abbd96f7a124647357005511bee8d3ccdd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:37:17 +0200 Subject: usb: renesas: gadget: don't touch gadget.dev.driver udc-core now handles that for us, which means we can remove it from our driver. Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 6a3afa9b764c..883b0120b454 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -845,7 +845,6 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, /* first hook up the driver ... */ gpriv->driver = driver; - gpriv->gadget.dev.driver = &driver->driver; return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); } @@ -861,7 +860,6 @@ static int usbhsg_gadget_stop(struct usb_gadget *gadget, return -EINVAL; usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); - gpriv->gadget.dev.driver = NULL; gpriv->driver = NULL; return 0; -- cgit From 792bfcf7a1cd7913fa5d55f2b3a40e3275e98f6f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 14:47:44 +0200 Subject: usb: gadget: udc-core: introduce usb_add_gadget_udc_release() not all UDC drivers need a proper release function, for those which don't need it, we udc-core will provide a no-op release method so we can remove "redefinition" of such methods in almost every UDC driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 39 ++++++++++++++++++++++++++++++++++----- include/linux/usb/gadget.h | 2 ++ 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 2423d024654f..a50811e35bdb 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -166,15 +166,23 @@ static void usb_udc_release(struct device *dev) } static const struct attribute_group *usb_udc_attr_groups[]; + +static void usb_udc_nop_release(struct device *dev) +{ + dev_vdbg(dev, "%s\n", __func__); +} + /** - * usb_add_gadget_udc - adds a new gadget to the udc class driver list - * @parent: the parent device to this udc. Usually the controller - * driver's device. - * @gadget: the gadget to be added to the list + * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list + * @parent: the parent device to this udc. Usually the controller driver's + * device. + * @gadget: the gadget to be added to the list. + * @release: a gadget release function. * * Returns zero on success, negative errno otherwise. */ -int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) +int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, + void (*release)(struct device *dev)) { struct usb_udc *udc; int ret = -ENOMEM; @@ -190,6 +198,13 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) gadget->dev.dma_parms = parent->dma_parms; gadget->dev.dma_mask = parent->dma_mask; + if (release) { + gadget->dev.release = release; + } else { + if (!gadget->dev.release) + gadget->dev.release = usb_udc_nop_release; + } + ret = device_register(&gadget->dev); if (ret) goto err2; @@ -231,6 +246,20 @@ err2: err1: return ret; } +EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); + +/** + * usb_add_gadget_udc - adds a new gadget to the udc class driver list + * @parent: the parent device to this udc. Usually the controller + * driver's device. + * @gadget: the gadget to be added to the list + * + * Returns zero on success, negative errno otherwise. + */ +int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget) +{ + return usb_add_gadget_udc_release(parent, gadget, NULL); +} EXPORT_SYMBOL_GPL(usb_add_gadget_udc); static void usb_gadget_remove_driver(struct usb_udc *udc) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 32b734d88d6b..c454a88abf2e 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -874,6 +874,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver); */ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); +extern int usb_add_gadget_udc_release(struct device *parent, + struct usb_gadget *gadget, void (*release)(struct device *dev)); extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); extern int udc_attach_driver(const char *name, -- cgit From 79c7d849777bc24d995371a066ded2ab2b359a18 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:10:51 +0200 Subject: usb: chipidea: udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index e303fd4b1b93..9bddf3f633f1 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1688,16 +1688,6 @@ static irqreturn_t udc_irq(struct ci13xxx *ci) return retval; } -/** - * udc_release: driver release function - * @dev: device - * - * Currently does nothing - */ -static void udc_release(struct device *dev) -{ -} - /** * udc_start: initialize gadget role * @ci: chipidea controller @@ -1717,8 +1707,6 @@ static int udc_start(struct ci13xxx *ci) INIT_LIST_HEAD(&ci->gadget.ep_list); - ci->gadget.dev.release = udc_release; - /* alloc resources */ ci->qh_pool = dma_pool_create("ci13xxx_qh", dev, sizeof(struct ci13xxx_qh), -- cgit From e5caff6831d00d96b4618de939312570527ad54a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:11:05 +0200 Subject: usb: dwc3: gadget: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9339eb10508f..4ffec1aa2e25 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1690,12 +1690,8 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) } } -static void dwc3_gadget_release(struct device *dev) -{ - dev_dbg(dev, "%s\n", __func__); -} - /* -------------------------------------------------------------------------- */ + static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_request *req, struct dwc3_trb *trb, const struct dwc3_event_depevt *event, int status) @@ -2568,7 +2564,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.max_speed = USB_SPEED_SUPER; dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.sg_supported = true; - dwc->gadget.dev.release = dwc3_gadget_release; dwc->gadget.name = "dwc3-gadget"; /* -- cgit From e1f07ced2a27a7068786beaf23e0ac9fda6d8ca6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:25 +0200 Subject: usb: gadget: amd5536udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/amd5536udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index a8ff93cf344d..f52dcfe8f545 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3268,7 +3268,6 @@ static int udc_probe(struct udc *dev) dev->gadget.ops = &udc_ops; dev_set_name(&dev->gadget.dev, "gadget"); - dev->gadget.dev.release = gadget_release; dev->gadget.name = name; dev->gadget.max_speed = USB_SPEED_HIGH; @@ -3292,7 +3291,8 @@ static int udc_probe(struct udc *dev) "driver version: %s(for Geode5536 B1)\n", tmp); udc = dev; - retval = usb_add_gadget_udc(&udc->pdev->dev, &dev->gadget); + retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, + gadget_release); if (retval) goto finished; -- cgit From a995d9e2a50b30907814f178eeaa1f632a66c0cb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: bcm63xx_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/bcm63xx_udc.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 904d4746922d..6e6518264c42 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2303,17 +2303,6 @@ static void bcm63xx_udc_cleanup_debugfs(struct bcm63xx_udc *udc) * Driver init/exit ***********************************************************************/ -/** - * bcm63xx_udc_gadget_release - Called from device_release(). - * @dev: Unused. - * - * We get a warning if this function doesn't exist, but it's empty because - * we don't have to free any of the memory allocated with the devm_* APIs. - */ -static void bcm63xx_udc_gadget_release(struct device *dev) -{ -} - /** * bcm63xx_udc_probe - Initialize a new instance of the UDC. * @pdev: Platform device struct from the bcm63xx BSP code. @@ -2369,7 +2358,6 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) udc->gadget.ops = &bcm63xx_udc_ops; udc->gadget.name = dev_name(dev); - udc->gadget.dev.release = bcm63xx_udc_gadget_release; if (!pd->use_fullspeed && !use_fullspeed) udc->gadget.max_speed = USB_SPEED_HIGH; -- cgit From f7162e9e1cead8510e371f8273902539102670ac Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: dummy_hcd: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9d54c01cbf56..ce751555f6ba 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -935,11 +935,6 @@ static int dummy_udc_stop(struct usb_gadget *g, /* The gadget structure is stored inside the hcd structure and will be * released along with it. */ -static void dummy_gadget_release(struct device *dev) -{ - return; -} - static void init_dummy_udc_hw(struct dummy *dum) { int i; @@ -983,7 +978,6 @@ static int dummy_udc_probe(struct platform_device *pdev) dum->gadget.max_speed = USB_SPEED_SUPER; dum->gadget.dev.parent = &pdev->dev; - dum->gadget.dev.release = dummy_gadget_release; init_dummy_udc_hw(dum); rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget); -- cgit From 29e7dbf32967361fa67e99cf97ff9935b7292ac4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: fsl_qe_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_qe_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 37feb62fa930..9a7ee3347e4d 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2521,7 +2521,6 @@ static int qe_udc_probe(struct platform_device *ofdev) /* name: Identifies the controller hardware type. */ udc->gadget.name = driver_name; - udc->gadget.dev.release = qe_udc_release; udc->gadget.dev.parent = &ofdev->dev; /* initialize qe_ep struct */ @@ -2585,7 +2584,8 @@ static int qe_udc_probe(struct platform_device *ofdev) goto err5; } - ret = usb_add_gadget_udc(&ofdev->dev, &udc->gadget); + ret = usb_add_gadget_udc_release(&ofdev->dev, &udc->gadget, + qe_udc_release); if (ret) goto err6; -- cgit From 0e4d65e5292ed76578ff1571a1132e2f5f188261 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: fsl_udc_core: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 4d5ff236bed4..f22416986486 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2493,7 +2493,6 @@ static int __init fsl_udc_probe(struct platform_device *pdev) /* Setup gadget.dev and register with kernel */ dev_set_name(&udc_controller->gadget.dev, "gadget"); - udc_controller->gadget.dev.release = fsl_udc_release; udc_controller->gadget.dev.of_node = pdev->dev.of_node; if (!IS_ERR_OR_NULL(udc_controller->transceiver)) @@ -2530,7 +2529,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev) goto err_free_irq; } - ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget); + ret = usb_add_gadget_udc_release(&pdev->dev, &udc_controller->gadget, + fsl_udc_release); if (ret) goto err_del_udc; -- cgit From 509d986a37edd7d89cb706142b540c74c6fbab0e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: fusb300_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index d69e840b101b..d05355389dd6 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1418,7 +1418,6 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->gadget.ops = &fusb300_gadget_ops; fusb300->gadget.max_speed = USB_SPEED_HIGH; - fusb300->gadget.dev.release = pdev->dev.release; fusb300->gadget.name = udc_name; fusb300->reg = reg; -- cgit From 2ae837e4d83c5d1046f83b1bf3e3737126a6776a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: goku_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/goku_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index aa1976ee34e0..991aba390d9d 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1749,7 +1749,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_FULL; /* the "gadget" abstracts/virtualizes the controller */ - dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; /* now all the pci goodies ... */ @@ -1800,7 +1799,8 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); #endif - retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget); + retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, + gadget_release); if (retval) goto err; -- cgit From 4b282fbe97412cc06fd9f173b4318e69a90b3442 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:26 +0200 Subject: usb: gadget: m66592-udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 21a20a6ffb66..866ef0999247 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1606,7 +1606,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->gadget.ops = &m66592_gadget_ops; m66592->gadget.max_speed = USB_SPEED_HIGH; - m66592->gadget.dev.release = pdev->dev.release; m66592->gadget.name = udc_name; init_timer(&m66592->timer); -- cgit From 7c9c3c7e1855e28d35c8d70607e68690def85fed Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: mv_u3d_core: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index dc6445046da7..e91281d2aa21 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1756,11 +1756,6 @@ static irqreturn_t mv_u3d_irq(int irq, void *dev) return IRQ_HANDLED; } -static void mv_u3d_gadget_release(struct device *dev) -{ - dev_dbg(dev, "%s\n", __func__); -} - static int mv_u3d_remove(struct platform_device *dev) { struct mv_u3d *u3d = platform_get_drvdata(dev); @@ -1953,7 +1948,6 @@ static int mv_u3d_probe(struct platform_device *dev) u3d->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ /* the "gadget" abstracts/virtualizes the controller */ - u3d->gadget.dev.release = mv_u3d_gadget_release; u3d->gadget.name = driver_name; /* gadget name */ mv_u3d_eps_init(u3d); -- cgit From e861c768e57fd74ff947eadcf8ff86c01ba170d6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: mv_udc_core: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index d1b243d76669..d278e8f512c0 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2265,7 +2265,6 @@ static int mv_udc_probe(struct platform_device *pdev) udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ /* the "gadget" abstracts/virtualizes the controller */ - udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ eps_init(udc); @@ -2305,7 +2304,8 @@ static int mv_udc_probe(struct platform_device *pdev) else udc->vbus_active = 1; - retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); + retval = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, + gadget_release); if (retval) goto err_create_workqueue; -- cgit From 8efeeef61d4f253aaa1a566a8e0d01b635c216d9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: net2272: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index af99223e0126..8dcbe770e2d4 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2233,7 +2233,6 @@ static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq) ret->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - ret->gadget.dev.release = net2272_gadget_release; ret->gadget.name = driver_name; return ret; @@ -2273,7 +2272,8 @@ net2272_probe_fin(struct net2272 *dev, unsigned int irqflags) if (ret) goto err_irq; - ret = usb_add_gadget_udc(dev->dev, &dev->gadget); + ret = usb_add_gadget_udc_release(dev->dev, &dev->gadget, + net2272_gadget_release); if (ret) goto err_add_udc; -- cgit From 2901df68499d75cb43d37495797f7ca73fb548a4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: net2280: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 9e4f0a26108e..e5f2ef184367 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2707,7 +2707,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->gadget.max_speed = USB_SPEED_HIGH; /* the "gadget" abstracts/virtualizes the controller */ - dev->gadget.dev.release = gadget_release; dev->gadget.name = driver_name; /* now all the pci goodies ... */ @@ -2819,7 +2818,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) retval = device_create_file (&pdev->dev, &dev_attr_registers); if (retval) goto done; - retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget); + retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, + gadget_release); if (retval) goto done; return 0; -- cgit From 2fb29f215cc8f23eedabcc289cd4b5280a054aad Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: omap_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/omap_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 19420ad128ce..b8ed74a823cb 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2628,7 +2628,6 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) udc->gadget.speed = USB_SPEED_UNKNOWN; udc->gadget.max_speed = USB_SPEED_FULL; udc->gadget.name = driver_name; - udc->gadget.dev.release = omap_udc_release; udc->transceiver = xceiv; /* ep0 is special; put it right after the SETUP buffer */ @@ -2902,7 +2901,8 @@ bad_on_1710: } create_proc_file(); - status = usb_add_gadget_udc(&pdev->dev, &udc->gadget); + status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, + omap_udc_release); if (status) goto cleanup4; -- cgit From ef98f7465fe28a39800b07e14b1e4a43906bd77b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: pch_udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 79cf2966f634..44aacf7192ab 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -3191,13 +3191,13 @@ static int pch_udc_probe(struct pci_dev *pdev, if (retval) goto finished; - dev->gadget.dev.release = gadget_release; dev->gadget.name = KBUILD_MODNAME; dev->gadget.max_speed = USB_SPEED_HIGH; /* Put the device in disconnected state till a driver is bound */ pch_udc_set_disconnect(dev); - retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget); + retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget, + gadget_release); if (retval) goto finished; return 0; -- cgit From 59139706a0bc6950759c588ca3a28a732fa18d5f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:27 +0200 Subject: usb: gadget: r8a66597-udc: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/r8a66597-udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 2de775dbd92c..0b742d171843 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1915,7 +1915,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->gadget.ops = &r8a66597_gadget_ops; r8a66597->gadget.max_speed = USB_SPEED_HIGH; - r8a66597->gadget.dev.release = pdev->dev.release; r8a66597->gadget.name = udc_name; init_timer(&r8a66597->timer); -- cgit From ad8033fcd08ed9d0e2c262015baf7e22e1544db2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:28 +0200 Subject: usb: gadget: s3c-hsotg: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index dfe72889c5b2..f1ceabff7cce 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3443,16 +3443,6 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) debugfs_remove(hsotg->debug_root); } -/** - * s3c_hsotg_release - release callback for hsotg device - * @dev: Device to for which release is called - * - * Nothing to do as the resource is allocated using devm_ API. - */ -static void s3c_hsotg_release(struct device *dev) -{ -} - /** * s3c_hsotg_probe - probe function for hsotg driver * @pdev: The platform information for the driver @@ -3530,7 +3520,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); - hsotg->gadget.dev.release = s3c_hsotg_release; /* reset the system */ -- cgit From 07d83168278a73647e3a30fc33e274708418c52b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:28 +0200 Subject: usb: musb: gadget: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 2dd952c330fd..6101ebf803fd 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1691,13 +1691,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { * all peripheral ports are external... */ -static void musb_gadget_release(struct device *dev) -{ - /* kref_put(WHAT) */ - dev_dbg(dev, "%s\n", __func__); -} - - static void init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) { @@ -1782,7 +1775,6 @@ int musb_gadget_setup(struct musb *musb) musb->g.speed = USB_SPEED_UNKNOWN; /* this "gadget" abstracts/virtualizes the controller */ - musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; musb->g.is_otg = 1; -- cgit From 3920193d8e71d1f7e0d077aa71624b64fa3499ac Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:15:51 +0200 Subject: usb: renesas: gadget: don't assign gadget.dev.release directly udc-core provides a better way to handle release methods, let's use it. Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 883b0120b454..c2781bc9dabe 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -923,11 +923,6 @@ static int usbhsg_stop(struct usbhs_priv *priv) return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); } -static void usbhs_mod_gadget_release(struct device *pdev) -{ - /* do nothing */ -} - int usbhs_mod_gadget_probe(struct usbhs_priv *priv) { struct usbhsg_gpriv *gpriv; @@ -975,7 +970,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) * init gadget */ gpriv->gadget.dev.parent = dev; - gpriv->gadget.dev.release = usbhs_mod_gadget_release; gpriv->gadget.name = "renesas_usbhs_udc"; gpriv->gadget.ops = &usbhsg_gadget_ops; gpriv->gadget.max_speed = USB_SPEED_HIGH; -- cgit From ddf47ccbfebc12add813cf729ecfc2d5ab59ca19 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 15:25:41 +0200 Subject: usb: gadget: udc-core: remove protection when setting gadget.dev.release now that no UDC driver touches gadget.dev.release we can assign our release function to it without being afraid of breaking anything. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index a50811e35bdb..26e116bd6f59 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -198,12 +198,10 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, gadget->dev.dma_parms = parent->dma_parms; gadget->dev.dma_mask = parent->dma_mask; - if (release) { + if (release) gadget->dev.release = release; - } else { - if (!gadget->dev.release) - gadget->dev.release = usb_udc_nop_release; - } + else + gadget->dev.release = usb_udc_nop_release; ret = device_register(&gadget->dev); if (ret) -- cgit From a5fcb066d284d8e525e1e1a4799722e8616cfe76 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 26 Feb 2013 19:15:14 +0200 Subject: usb: gadget: udc-core: anywone can read 'speed' attributes current code only allows the file owner (usually root) to read current_speed and maximum_speed sysfs files. Let anyone read those. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 26e116bd6f59..7999cc656979 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -471,7 +471,7 @@ ssize_t usb_udc_##param##_show(struct device *dev, \ return snprintf(buf, PAGE_SIZE, "%s\n", \ usb_speed_string(udc->gadget->param)); \ } \ -static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL) +static DEVICE_ATTR(name, S_IRUGO, usb_udc_##param##_show, NULL) static USB_UDC_SPEED_ATTR(current_speed, speed); static USB_UDC_SPEED_ATTR(maximum_speed, max_speed); -- cgit From 7ac6a593d512de38e710591afea4c839626b3bd0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 18 Sep 2012 21:22:32 +0300 Subject: usb: dwc3: core: define more revisions Some new revisions of the DWC3 core have been released, let's add our defines to help implementing known erratas. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index d8c36fccce96..ad2ffac71500 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -700,6 +700,9 @@ struct dwc3 { #define DWC3_REVISION_202A 0x5533202a #define DWC3_REVISION_210A 0x5533210a #define DWC3_REVISION_220A 0x5533220a +#define DWC3_REVISION_230A 0x5533230a +#define DWC3_REVISION_240A 0x5533240a +#define DWC3_REVISION_250A 0x5533250a unsigned is_selfpowered:1; unsigned three_stage_setup:1; -- cgit From 0b0cc1cd31bed3e3147398e54530f1f819b27692 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 18 Sep 2012 21:39:24 +0300 Subject: usb: dwc3: workaround: unexpected transtion U3 -> RESUME In DWC3 versions < 2.50a configured without Hibernation mode enabled, there will be an extra link status change interrupt if device detects host-initiated U3 exit. In that case, core will generate an unnecessary U3 -> RESUME transition which should be ignored by the driver. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4ffec1aa2e25..8e53acc0e43e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2317,6 +2317,34 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { enum dwc3_link_state next = evtinfo & DWC3_LINK_STATE_MASK; + unsigned int pwropt; + + /* + * WORKAROUND: DWC3 < 2.50a have an issue when configured without + * Hibernation mode enabled which would show up when device detects + * host-initiated U3 exit. + * + * In that case, device will generate a Link State Change Interrupt + * from U3 to RESUME which is only necessary if Hibernation is + * configured in. + * + * There are no functional changes due to such spurious event and we + * just need to ignore it. + * + * Refers to: + * + * STAR#9000570034 RTL: SS Resume event generated in non-Hibernation + * operational mode + */ + pwropt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); + if ((dwc->revision < DWC3_REVISION_250A) && + (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { + if ((dwc->link_state == DWC3_LINK_STATE_U3) && + (next == DWC3_LINK_STATE_RESUME)) { + dev_vdbg(dwc->dev, "ignoring transition U3 -> Resume\n"); + return; + } + } /* * WORKAROUND: DWC3 Revisions <1.83a have an issue which, depending -- cgit From cedf8602373a3a5d02e49af7bebc401ffe3b38f3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 27 Feb 2013 15:16:28 +0100 Subject: usb: phy: move bulk of otg/otg.c to phy/phy.c Most of otg/otg.c is not otg specific, but phy specific, so move it to the phy directory. Tested-by: Steffen Trumtrar Reported-by: Kishon Vijay Abraham I Signed-off-by: Sascha Hauer Signed-off-by: Marc Kleine-Budde Signed-off-by: Felipe Balbi --- drivers/usb/otg/otg.c | 427 --------------------------------------------- drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy.c | 438 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 427 deletions(-) create mode 100644 drivers/usb/phy/phy.c (limited to 'drivers') diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 2bd03d261a50..358cfd9bce89 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -8,436 +8,9 @@ * 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 -static LIST_HEAD(phy_list); -static LIST_HEAD(phy_bind_list); -static DEFINE_SPINLOCK(phy_lock); - -static struct usb_phy *__usb_find_phy(struct list_head *list, - enum usb_phy_type type) -{ - struct usb_phy *phy = NULL; - - list_for_each_entry(phy, list, head) { - if (phy->type != type) - continue; - - return phy; - } - - return ERR_PTR(-ENODEV); -} - -static struct usb_phy *__usb_find_phy_dev(struct device *dev, - struct list_head *list, u8 index) -{ - struct usb_phy_bind *phy_bind = NULL; - - list_for_each_entry(phy_bind, list, list) { - if (!(strcmp(phy_bind->dev_name, dev_name(dev))) && - phy_bind->index == index) { - if (phy_bind->phy) - return phy_bind->phy; - else - return ERR_PTR(-EPROBE_DEFER); - } - } - - return ERR_PTR(-ENODEV); -} - -static struct usb_phy *__of_usb_find_phy(struct device_node *node) -{ - struct usb_phy *phy; - - list_for_each_entry(phy, &phy_list, head) { - if (node != phy->dev->of_node) - continue; - - return phy; - } - - return ERR_PTR(-ENODEV); -} - -static void devm_usb_phy_release(struct device *dev, void *res) -{ - struct usb_phy *phy = *(struct usb_phy **)res; - - usb_put_phy(phy); -} - -static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) -{ - return res == match_data; -} - -/** - * devm_usb_get_phy - find the USB PHY - * @dev - device that requests this phy - * @type - the type of the phy the controller requires - * - * Gets the phy using usb_get_phy(), and associates a device with it using - * devres. On driver detach, release function is invoked on the devres data, - * then, devres data is freed. - * - * For use by USB host and peripheral drivers. - */ -struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) -{ - struct usb_phy **ptr, *phy; - - ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - phy = usb_get_phy(type); - if (!IS_ERR(phy)) { - *ptr = phy; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return phy; -} -EXPORT_SYMBOL(devm_usb_get_phy); - -/** - * usb_get_phy - find the USB PHY - * @type - the type of the phy the controller requires - * - * Returns the phy driver, after getting a refcount to it; or - * -ENODEV if there is no such phy. The caller is responsible for - * calling usb_put_phy() to release that count. - * - * For use by USB host and peripheral drivers. - */ -struct usb_phy *usb_get_phy(enum usb_phy_type type) -{ - struct usb_phy *phy = NULL; - unsigned long flags; - - spin_lock_irqsave(&phy_lock, flags); - - phy = __usb_find_phy(&phy_list, type); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - pr_err("unable to find transceiver of type %s\n", - usb_phy_type_string(type)); - goto err0; - } - - get_device(phy->dev); - -err0: - spin_unlock_irqrestore(&phy_lock, flags); - - return phy; -} -EXPORT_SYMBOL(usb_get_phy); - - /** - * devm_usb_get_phy_by_phandle - find the USB PHY by phandle - * @dev - device that requests this phy - * @phandle - name of the property holding the phy phandle value - * @index - the index of the phy - * - * Returns the phy driver associated with the given phandle value, - * after getting a refcount to it, -ENODEV if there is no such phy or - * -EPROBE_DEFER if there is a phandle to the phy, but the device is - * not yet loaded. While at that, it also associates the device with - * the phy using devres. On driver detach, release function is invoked - * on the devres data, then, devres data is freed. - * - * For use by USB host and peripheral drivers. - */ -struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, - const char *phandle, u8 index) -{ - struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr; - unsigned long flags; - struct device_node *node; - - if (!dev->of_node) { - dev_dbg(dev, "device does not have a device node entry\n"); - return ERR_PTR(-EINVAL); - } - - node = of_parse_phandle(dev->of_node, phandle, index); - if (!node) { - dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, - dev->of_node->full_name); - return ERR_PTR(-ENODEV); - } - - ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) { - dev_dbg(dev, "failed to allocate memory for devres\n"); - goto err0; - } - - spin_lock_irqsave(&phy_lock, flags); - - phy = __of_usb_find_phy(node); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - phy = ERR_PTR(-EPROBE_DEFER); - devres_free(ptr); - goto err1; - } - - *ptr = phy; - devres_add(dev, ptr); - - get_device(phy->dev); - -err1: - spin_unlock_irqrestore(&phy_lock, flags); - -err0: - of_node_put(node); - - return phy; -} -EXPORT_SYMBOL(devm_usb_get_phy_by_phandle); - -/** - * usb_get_phy_dev - find the USB PHY - * @dev - device that requests this phy - * @index - the index of the phy - * - * Returns the phy driver, after getting a refcount to it; or - * -ENODEV if there is no such phy. The caller is responsible for - * calling usb_put_phy() to release that count. - * - * For use by USB host and peripheral drivers. - */ -struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) -{ - struct usb_phy *phy = NULL; - unsigned long flags; - - spin_lock_irqsave(&phy_lock, flags); - - phy = __usb_find_phy_dev(dev, &phy_bind_list, index); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - pr_err("unable to find transceiver\n"); - goto err0; - } - - get_device(phy->dev); - -err0: - spin_unlock_irqrestore(&phy_lock, flags); - - return phy; -} -EXPORT_SYMBOL(usb_get_phy_dev); - -/** - * devm_usb_get_phy_dev - find the USB PHY using device ptr and index - * @dev - device that requests this phy - * @index - the index of the phy - * - * Gets the phy using usb_get_phy_dev(), and associates a device with it using - * devres. On driver detach, release function is invoked on the devres data, - * then, devres data is freed. - * - * For use by USB host and peripheral drivers. - */ -struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) -{ - struct usb_phy **ptr, *phy; - - ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - phy = usb_get_phy_dev(dev, index); - if (!IS_ERR(phy)) { - *ptr = phy; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return phy; -} -EXPORT_SYMBOL(devm_usb_get_phy_dev); - -/** - * devm_usb_put_phy - release the USB PHY - * @dev - device that wants to release this phy - * @phy - the phy returned by devm_usb_get_phy() - * - * destroys the devres associated with this phy and invokes usb_put_phy - * to release the phy. - * - * For use by USB host and peripheral drivers. - */ -void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) -{ - int r; - - r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); - dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -} -EXPORT_SYMBOL(devm_usb_put_phy); - -/** - * usb_put_phy - release the USB PHY - * @x: the phy returned by usb_get_phy() - * - * Releases a refcount the caller received from usb_get_phy(). - * - * For use by USB host and peripheral drivers. - */ -void usb_put_phy(struct usb_phy *x) -{ - if (x) { - struct module *owner = x->dev->driver->owner; - - put_device(x->dev); - module_put(owner); - } -} -EXPORT_SYMBOL(usb_put_phy); - -/** - * usb_add_phy - declare the USB PHY - * @x: the USB phy to be used; or NULL - * @type - the type of this PHY - * - * This call is exclusively for use by phy drivers, which - * coordinate the activities of drivers for host and peripheral - * controllers, and in some cases for VBUS current regulation. - */ -int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) -{ - int ret = 0; - unsigned long flags; - struct usb_phy *phy; - - if (x->type != USB_PHY_TYPE_UNDEFINED) { - dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); - return -EINVAL; - } - - spin_lock_irqsave(&phy_lock, flags); - - list_for_each_entry(phy, &phy_list, head) { - if (phy->type == type) { - ret = -EBUSY; - dev_err(x->dev, "transceiver type %s already exists\n", - usb_phy_type_string(type)); - goto out; - } - } - - x->type = type; - list_add_tail(&x->head, &phy_list); - -out: - spin_unlock_irqrestore(&phy_lock, flags); - return ret; -} -EXPORT_SYMBOL(usb_add_phy); - -/** - * usb_add_phy_dev - declare the USB PHY - * @x: the USB phy to be used; or NULL - * - * This call is exclusively for use by phy drivers, which - * coordinate the activities of drivers for host and peripheral - * controllers, and in some cases for VBUS current regulation. - */ -int usb_add_phy_dev(struct usb_phy *x) -{ - struct usb_phy_bind *phy_bind; - unsigned long flags; - - if (!x->dev) { - dev_err(x->dev, "no device provided for PHY\n"); - return -EINVAL; - } - - spin_lock_irqsave(&phy_lock, flags); - list_for_each_entry(phy_bind, &phy_bind_list, list) - if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev)))) - phy_bind->phy = x; - - list_add_tail(&x->head, &phy_list); - - spin_unlock_irqrestore(&phy_lock, flags); - return 0; -} -EXPORT_SYMBOL(usb_add_phy_dev); - -/** - * usb_remove_phy - remove the OTG PHY - * @x: the USB OTG PHY to be removed; - * - * This reverts the effects of usb_add_phy - */ -void usb_remove_phy(struct usb_phy *x) -{ - unsigned long flags; - struct usb_phy_bind *phy_bind; - - spin_lock_irqsave(&phy_lock, flags); - if (x) { - list_for_each_entry(phy_bind, &phy_bind_list, list) - if (phy_bind->phy == x) - phy_bind->phy = NULL; - list_del(&x->head); - } - spin_unlock_irqrestore(&phy_lock, flags); -} -EXPORT_SYMBOL(usb_remove_phy); - -/** - * usb_bind_phy - bind the phy and the controller that uses the phy - * @dev_name: the device name of the device that will bind to the phy - * @index: index to specify the port number - * @phy_dev_name: the device name of the phy - * - * Fills the phy_bind structure with the dev_name and phy_dev_name. This will - * be used when the phy driver registers the phy and when the controller - * requests this phy. - * - * To be used by platform specific initialization code. - */ -int __init usb_bind_phy(const char *dev_name, u8 index, - const char *phy_dev_name) -{ - struct usb_phy_bind *phy_bind; - unsigned long flags; - - phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); - if (!phy_bind) { - pr_err("phy_bind(): No memory for phy_bind"); - return -ENOMEM; - } - - phy_bind->dev_name = dev_name; - phy_bind->phy_dev_name = phy_dev_name; - phy_bind->index = index; - - spin_lock_irqsave(&phy_lock, flags); - list_add_tail(&phy_bind->list, &phy_bind_list); - spin_unlock_irqrestore(&phy_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(usb_bind_phy); - const char *otg_state_string(enum usb_otg_state state) { switch (state) { diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index b13faa193e0c..9fa6327d4c52 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -4,6 +4,7 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG +obj-$(CONFIG_USB_OTG_UTILS) += phy.o obj-$(CONFIG_OMAP_USB2) += omap-usb2.o obj-$(CONFIG_OMAP_USB3) += omap-usb3.o obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c new file mode 100644 index 000000000000..bc1970c55df0 --- /dev/null +++ b/drivers/usb/phy/phy.c @@ -0,0 +1,438 @@ +/* + * phy.c -- USB phy handling + * + * Copyright (C) 2004-2013 Texas Instruments + * + * 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 + +static LIST_HEAD(phy_list); +static LIST_HEAD(phy_bind_list); +static DEFINE_SPINLOCK(phy_lock); + +static struct usb_phy *__usb_find_phy(struct list_head *list, + enum usb_phy_type type) +{ + struct usb_phy *phy = NULL; + + list_for_each_entry(phy, list, head) { + if (phy->type != type) + continue; + + return phy; + } + + return ERR_PTR(-ENODEV); +} + +static struct usb_phy *__usb_find_phy_dev(struct device *dev, + struct list_head *list, u8 index) +{ + struct usb_phy_bind *phy_bind = NULL; + + list_for_each_entry(phy_bind, list, list) { + if (!(strcmp(phy_bind->dev_name, dev_name(dev))) && + phy_bind->index == index) { + if (phy_bind->phy) + return phy_bind->phy; + else + return ERR_PTR(-EPROBE_DEFER); + } + } + + return ERR_PTR(-ENODEV); +} + +static struct usb_phy *__of_usb_find_phy(struct device_node *node) +{ + struct usb_phy *phy; + + list_for_each_entry(phy, &phy_list, head) { + if (node != phy->dev->of_node) + continue; + + return phy; + } + + return ERR_PTR(-ENODEV); +} + +static void devm_usb_phy_release(struct device *dev, void *res) +{ + struct usb_phy *phy = *(struct usb_phy **)res; + + usb_put_phy(phy); +} + +static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) +{ + return res == match_data; +} + +/** + * devm_usb_get_phy - find the USB PHY + * @dev - device that requests this phy + * @type - the type of the phy the controller requires + * + * Gets the phy using usb_get_phy(), and associates a device with it using + * devres. On driver detach, release function is invoked on the devres data, + * then, devres data is freed. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) +{ + struct usb_phy **ptr, *phy; + + ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + phy = usb_get_phy(type); + if (!IS_ERR(phy)) { + *ptr = phy; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return phy; +} +EXPORT_SYMBOL(devm_usb_get_phy); + +/** + * usb_get_phy - find the USB PHY + * @type - the type of the phy the controller requires + * + * Returns the phy driver, after getting a refcount to it; or + * -ENODEV if there is no such phy. The caller is responsible for + * calling usb_put_phy() to release that count. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *usb_get_phy(enum usb_phy_type type) +{ + struct usb_phy *phy = NULL; + unsigned long flags; + + spin_lock_irqsave(&phy_lock, flags); + + phy = __usb_find_phy(&phy_list, type); + if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { + pr_err("unable to find transceiver of type %s\n", + usb_phy_type_string(type)); + goto err0; + } + + get_device(phy->dev); + +err0: + spin_unlock_irqrestore(&phy_lock, flags); + + return phy; +} +EXPORT_SYMBOL(usb_get_phy); + + /** + * devm_usb_get_phy_by_phandle - find the USB PHY by phandle + * @dev - device that requests this phy + * @phandle - name of the property holding the phy phandle value + * @index - the index of the phy + * + * Returns the phy driver associated with the given phandle value, + * after getting a refcount to it, -ENODEV if there is no such phy or + * -EPROBE_DEFER if there is a phandle to the phy, but the device is + * not yet loaded. While at that, it also associates the device with + * the phy using devres. On driver detach, release function is invoked + * on the devres data, then, devres data is freed. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, + const char *phandle, u8 index) +{ + struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr; + unsigned long flags; + struct device_node *node; + + if (!dev->of_node) { + dev_dbg(dev, "device does not have a device node entry\n"); + return ERR_PTR(-EINVAL); + } + + node = of_parse_phandle(dev->of_node, phandle, index); + if (!node) { + dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, + dev->of_node->full_name); + return ERR_PTR(-ENODEV); + } + + ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) { + dev_dbg(dev, "failed to allocate memory for devres\n"); + goto err0; + } + + spin_lock_irqsave(&phy_lock, flags); + + phy = __of_usb_find_phy(node); + if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { + phy = ERR_PTR(-EPROBE_DEFER); + devres_free(ptr); + goto err1; + } + + *ptr = phy; + devres_add(dev, ptr); + + get_device(phy->dev); + +err1: + spin_unlock_irqrestore(&phy_lock, flags); + +err0: + of_node_put(node); + + return phy; +} +EXPORT_SYMBOL(devm_usb_get_phy_by_phandle); + +/** + * usb_get_phy_dev - find the USB PHY + * @dev - device that requests this phy + * @index - the index of the phy + * + * Returns the phy driver, after getting a refcount to it; or + * -ENODEV if there is no such phy. The caller is responsible for + * calling usb_put_phy() to release that count. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) +{ + struct usb_phy *phy = NULL; + unsigned long flags; + + spin_lock_irqsave(&phy_lock, flags); + + phy = __usb_find_phy_dev(dev, &phy_bind_list, index); + if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { + pr_err("unable to find transceiver\n"); + goto err0; + } + + get_device(phy->dev); + +err0: + spin_unlock_irqrestore(&phy_lock, flags); + + return phy; +} +EXPORT_SYMBOL(usb_get_phy_dev); + +/** + * devm_usb_get_phy_dev - find the USB PHY using device ptr and index + * @dev - device that requests this phy + * @index - the index of the phy + * + * Gets the phy using usb_get_phy_dev(), and associates a device with it using + * devres. On driver detach, release function is invoked on the devres data, + * then, devres data is freed. + * + * For use by USB host and peripheral drivers. + */ +struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) +{ + struct usb_phy **ptr, *phy; + + ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + phy = usb_get_phy_dev(dev, index); + if (!IS_ERR(phy)) { + *ptr = phy; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return phy; +} +EXPORT_SYMBOL(devm_usb_get_phy_dev); + +/** + * devm_usb_put_phy - release the USB PHY + * @dev - device that wants to release this phy + * @phy - the phy returned by devm_usb_get_phy() + * + * destroys the devres associated with this phy and invokes usb_put_phy + * to release the phy. + * + * For use by USB host and peripheral drivers. + */ +void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) +{ + int r; + + r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); + dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); +} +EXPORT_SYMBOL(devm_usb_put_phy); + +/** + * usb_put_phy - release the USB PHY + * @x: the phy returned by usb_get_phy() + * + * Releases a refcount the caller received from usb_get_phy(). + * + * For use by USB host and peripheral drivers. + */ +void usb_put_phy(struct usb_phy *x) +{ + if (x) { + struct module *owner = x->dev->driver->owner; + + put_device(x->dev); + module_put(owner); + } +} +EXPORT_SYMBOL(usb_put_phy); + +/** + * usb_add_phy - declare the USB PHY + * @x: the USB phy to be used; or NULL + * @type - the type of this PHY + * + * This call is exclusively for use by phy drivers, which + * coordinate the activities of drivers for host and peripheral + * controllers, and in some cases for VBUS current regulation. + */ +int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) +{ + int ret = 0; + unsigned long flags; + struct usb_phy *phy; + + if (x->type != USB_PHY_TYPE_UNDEFINED) { + dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); + return -EINVAL; + } + + spin_lock_irqsave(&phy_lock, flags); + + list_for_each_entry(phy, &phy_list, head) { + if (phy->type == type) { + ret = -EBUSY; + dev_err(x->dev, "transceiver type %s already exists\n", + usb_phy_type_string(type)); + goto out; + } + } + + x->type = type; + list_add_tail(&x->head, &phy_list); + +out: + spin_unlock_irqrestore(&phy_lock, flags); + return ret; +} +EXPORT_SYMBOL(usb_add_phy); + +/** + * usb_add_phy_dev - declare the USB PHY + * @x: the USB phy to be used; or NULL + * + * This call is exclusively for use by phy drivers, which + * coordinate the activities of drivers for host and peripheral + * controllers, and in some cases for VBUS current regulation. + */ +int usb_add_phy_dev(struct usb_phy *x) +{ + struct usb_phy_bind *phy_bind; + unsigned long flags; + + if (!x->dev) { + dev_err(x->dev, "no device provided for PHY\n"); + return -EINVAL; + } + + spin_lock_irqsave(&phy_lock, flags); + list_for_each_entry(phy_bind, &phy_bind_list, list) + if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev)))) + phy_bind->phy = x; + + list_add_tail(&x->head, &phy_list); + + spin_unlock_irqrestore(&phy_lock, flags); + return 0; +} +EXPORT_SYMBOL(usb_add_phy_dev); + +/** + * usb_remove_phy - remove the OTG PHY + * @x: the USB OTG PHY to be removed; + * + * This reverts the effects of usb_add_phy + */ +void usb_remove_phy(struct usb_phy *x) +{ + unsigned long flags; + struct usb_phy_bind *phy_bind; + + spin_lock_irqsave(&phy_lock, flags); + if (x) { + list_for_each_entry(phy_bind, &phy_bind_list, list) + if (phy_bind->phy == x) + phy_bind->phy = NULL; + list_del(&x->head); + } + spin_unlock_irqrestore(&phy_lock, flags); +} +EXPORT_SYMBOL(usb_remove_phy); + +/** + * usb_bind_phy - bind the phy and the controller that uses the phy + * @dev_name: the device name of the device that will bind to the phy + * @index: index to specify the port number + * @phy_dev_name: the device name of the phy + * + * Fills the phy_bind structure with the dev_name and phy_dev_name. This will + * be used when the phy driver registers the phy and when the controller + * requests this phy. + * + * To be used by platform specific initialization code. + */ +int __init usb_bind_phy(const char *dev_name, u8 index, + const char *phy_dev_name) +{ + struct usb_phy_bind *phy_bind; + unsigned long flags; + + phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); + if (!phy_bind) { + pr_err("phy_bind(): No memory for phy_bind"); + return -ENOMEM; + } + + phy_bind->dev_name = dev_name; + phy_bind->phy_dev_name = phy_dev_name; + phy_bind->index = index; + + spin_lock_irqsave(&phy_lock, flags); + list_add_tail(&phy_bind->list, &phy_bind_list); + spin_unlock_irqrestore(&phy_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(usb_bind_phy); -- cgit From 25df6397a6c063811154868b868e8bd10e5ae9b1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 27 Feb 2013 15:16:30 +0100 Subject: usb: phy: mxs-phy: register phy with framework We now have usb_add_phy_dev(), so use it to register with the framework to be able to find the phy from the USB driver. Tested-by: Steffen Trumtrar Reviewed-by: Kishon Vijay Abraham I Reviewed-by: Peter Chen Signed-off-by: Sascha Hauer Signed-off-by: Marc Kleine-Budde Signed-off-by: Felipe Balbi --- drivers/usb/otg/mxs-phy.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index b0d9f119c749..aa403256d4b6 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -127,6 +127,7 @@ static int mxs_phy_probe(struct platform_device *pdev) void __iomem *base; struct clk *clk; struct mxs_phy *mxs_phy; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -166,11 +167,19 @@ static int mxs_phy_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &mxs_phy->phy); + ret = usb_add_phy_dev(&mxs_phy->phy); + if (ret) + return ret; + return 0; } static int mxs_phy_remove(struct platform_device *pdev) { + struct mxs_phy *mxs_phy = platform_get_drvdata(pdev); + + usb_remove_phy(&mxs_phy->phy); + platform_set_drvdata(pdev, NULL); return 0; -- cgit From b5a726b30436ab332aea4133bbfa0484d1c658b3 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 28 Feb 2013 11:52:30 +0100 Subject: usb: phy: mxs: use readl(), writel() instead of the _relaxed() versions This patch converts the mxs-phy driver from readl_relaxed(), writel_relaxed() to the plain readl(), writel() functions, which are available on all platforms. This is done to enable compile time testing on non ARM platforms. Reported-by: Alexander Shishkin Signed-off-by: Marc Kleine-Budde Signed-off-by: Felipe Balbi --- drivers/usb/otg/mxs-phy.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index aa403256d4b6..9d4381e64d51 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -48,12 +48,12 @@ static void mxs_phy_hw_init(struct mxs_phy *mxs_phy) stmp_reset_block(base + HW_USBPHY_CTRL); /* Power up the PHY */ - writel_relaxed(0, base + HW_USBPHY_PWD); + writel(0, base + HW_USBPHY_PWD); /* enable FS/LS device */ - writel_relaxed(BM_USBPHY_CTRL_ENUTMILEVEL2 | - BM_USBPHY_CTRL_ENUTMILEVEL3, - base + HW_USBPHY_CTRL_SET); + writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | + BM_USBPHY_CTRL_ENUTMILEVEL3, + base + HW_USBPHY_CTRL_SET); } static int mxs_phy_init(struct usb_phy *phy) @@ -70,8 +70,8 @@ static void mxs_phy_shutdown(struct usb_phy *phy) { struct mxs_phy *mxs_phy = to_mxs_phy(phy); - writel_relaxed(BM_USBPHY_CTRL_CLKGATE, - phy->io_priv + HW_USBPHY_CTRL_SET); + writel(BM_USBPHY_CTRL_CLKGATE, + phy->io_priv + HW_USBPHY_CTRL_SET); clk_disable_unprepare(mxs_phy->clk); } @@ -81,15 +81,15 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) struct mxs_phy *mxs_phy = to_mxs_phy(x); if (suspend) { - writel_relaxed(0xffffffff, x->io_priv + HW_USBPHY_PWD); - writel_relaxed(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_SET); + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_SET); clk_disable_unprepare(mxs_phy->clk); } else { clk_prepare_enable(mxs_phy->clk); - writel_relaxed(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_CLR); - writel_relaxed(0, x->io_priv + HW_USBPHY_PWD); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_CLR); + writel(0, x->io_priv + HW_USBPHY_PWD); } return 0; @@ -102,8 +102,8 @@ static int mxs_phy_on_connect(struct usb_phy *phy, (speed == USB_SPEED_HIGH) ? "high" : "non-high"); if (speed == USB_SPEED_HIGH) - writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_SET); + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_SET); return 0; } @@ -115,8 +115,8 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, (speed == USB_SPEED_HIGH) ? "high" : "non-high"); if (speed == USB_SPEED_HIGH) - writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_CLR); + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_CLR); return 0; } -- cgit From cd051da2c81c8a86f331b4caa0c135c33d3ea3f6 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Sat, 2 Mar 2013 18:55:24 +0530 Subject: usb: dwc3: set 'mode' based on selected Kconfig choices Now that machines may select dwc3's working mode (HOST only, GADGET only or DUAL_ROLE) via Kconfig, let's set dwc3's mode based on that, rather than fixing it to whatever hardware says. This way we can skip initializing Gadget/Host in case we are using Host-only/Gadget-only mode respectively. Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b81b3357f007..c6a46e0efe4f 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -479,7 +479,12 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } - mode = DWC3_MODE(dwc->hwparams.hwparams0); + if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) + mode = DWC3_MODE_HOST; + else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) + mode = DWC3_MODE_DEVICE; + else + mode = DWC3_MODE_DRD; switch (mode) { case DWC3_MODE_DEVICE: -- cgit From d25ab3ece05c7cb740af155ecac87b6b36f16566 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 5 Mar 2013 09:42:15 +0530 Subject: usb: gadget: fsl_udc_core: Use module_platform_driver_probe macro module_platform_driver_probe() eliminates the boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Acked-by: Li Yang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index f22416986486..7c2a101d19ac 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2712,21 +2712,7 @@ static struct platform_driver udc_driver = { }, }; -static int __init udc_init(void) -{ - printk(KERN_INFO "%s (%s)\n", driver_desc, DRIVER_VERSION); - return platform_driver_probe(&udc_driver, fsl_udc_probe); -} - -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); - printk(KERN_WARNING "%s unregistered\n", driver_desc); -} - -module_exit(udc_exit); +module_platform_driver_probe(udc_driver, fsl_udc_probe); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR(DRIVER_AUTHOR); -- cgit From 2daf5966d140d23d1b5ba347b53d102eeb029d2c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 20 Feb 2013 09:53:39 +0100 Subject: usb: musb: drop dangling CONFIG_USB_MUSB_DEBUG CONFIG_USB_MUSB_DEBUG option was removed in 5c8a86e usb: musb: drop unneeded musb_debug trickery to cleanup the code from driver specific debug facilities. This patch drops the last references to the musb debug config option, unconditionally enabling all debug code paths, thus letting that code being dropped at compile time if not needed. Signed-off-by: Fabio Baltieri Signed-off-by: Felipe Balbi --- drivers/usb/musb/cppi_dma.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index f522000e8f06..9db211ee15b5 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -435,7 +435,6 @@ cppi_rndis_update(struct cppi_channel *c, int is_rx, } } -#ifdef CONFIG_USB_MUSB_DEBUG static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) { pr_debug("RXBD/%s %08x: " @@ -444,21 +443,16 @@ static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) bd->hw_next, bd->hw_bufp, bd->hw_off_len, bd->hw_options); } -#endif static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx) { -#ifdef CONFIG_USB_MUSB_DEBUG struct cppi_descriptor *bd; - if (!_dbg_level(level)) - return; cppi_dump_rx(level, rx, tag); if (rx->last_processed) cppi_dump_rxbd("last", rx->last_processed); for (bd = rx->head; bd; bd = bd->next) cppi_dump_rxbd("active", bd); -#endif } @@ -784,6 +778,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) void __iomem *tibase = musb->ctrl_base; int is_rndis = 0; struct cppi_rx_stateram __iomem *rx_ram = rx->state_ram; + struct cppi_descriptor *d; if (onepacket) { /* almost every USB driver, host or peripheral side */ @@ -897,14 +892,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) bd->hw_options |= CPPI_SOP_SET; tail->hw_options |= CPPI_EOP_SET; -#ifdef CONFIG_USB_MUSB_DEBUG - if (_dbg_level(5)) { - struct cppi_descriptor *d; - - for (d = rx->head; d; d = d->next) - cppi_dump_rxbd("S", d); - } -#endif + for (d = rx->head; d; d = d->next) + cppi_dump_rxbd("S", d); /* in case the preceding transfer left some state... */ tail = rx->last_processed; -- cgit From 5f71791947fcb1942df7d0df45520d420c2aee2b Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Wed, 6 Mar 2013 01:04:50 +0530 Subject: usb: otg: fsl_otg: remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Felipe Balbi --- drivers/usb/otg/fsl_otg.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index d16adb41eb21..37e8e1578316 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -361,28 +361,18 @@ int fsl_otg_init_timers(struct otg_fsm *fsm) void fsl_otg_uninit_timers(void) { /* FSM used timers */ - if (a_wait_vrise_tmr != NULL) - kfree(a_wait_vrise_tmr); - if (a_wait_bcon_tmr != NULL) - kfree(a_wait_bcon_tmr); - if (a_aidl_bdis_tmr != NULL) - kfree(a_aidl_bdis_tmr); - if (b_ase0_brst_tmr != NULL) - kfree(b_ase0_brst_tmr); - if (b_se0_srp_tmr != NULL) - kfree(b_se0_srp_tmr); - if (b_srp_fail_tmr != NULL) - kfree(b_srp_fail_tmr); - if (a_wait_enum_tmr != NULL) - kfree(a_wait_enum_tmr); + kfree(a_wait_vrise_tmr); + kfree(a_wait_bcon_tmr); + kfree(a_aidl_bdis_tmr); + kfree(b_ase0_brst_tmr); + kfree(b_se0_srp_tmr); + kfree(b_srp_fail_tmr); + kfree(a_wait_enum_tmr); /* device driver used timers */ - if (b_srp_wait_tmr != NULL) - kfree(b_srp_wait_tmr); - if (b_data_pulse_tmr != NULL) - kfree(b_data_pulse_tmr); - if (b_vbus_pulse_tmr != NULL) - kfree(b_vbus_pulse_tmr); + kfree(b_srp_wait_tmr); + kfree(b_data_pulse_tmr); + kfree(b_vbus_pulse_tmr); } /* Add timer to timer list */ -- cgit From 789451f6c698282d0745f265bde47173c9372867 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 5 May 2011 15:53:10 +0300 Subject: usb: dwc3: calculate the number of endpoints hwparams2 holds the number of endpoints which were selected during RTL generation, we can use that on our driver. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 13 +++++++++++++ drivers/usb/dwc3/core.h | 15 +++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c6a46e0efe4f..66c05725daf3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -260,6 +260,17 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) } } +static void dwc3_core_num_eps(struct dwc3 *dwc) +{ + struct dwc3_hwparams *parms = &dwc->hwparams; + + dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); + dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; + + dev_vdbg(dwc->dev, "found %d IN and %d OUT endpoints\n", + dwc->num_in_eps, dwc->num_out_eps); +} + static void dwc3_cache_hwparams(struct dwc3 *dwc) { struct dwc3_hwparams *parms = &dwc->hwparams; @@ -336,6 +347,8 @@ static int dwc3_core_init(struct dwc3 *dwc) if (dwc->revision < DWC3_REVISION_190A) reg |= DWC3_GCTL_U2RSTECN; + dwc3_core_num_eps(dwc); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); return 0; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ad2ffac71500..b42f71cb87dd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -575,6 +575,14 @@ struct dwc3_hwparams { /* HWPARAMS1 */ #define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) +/* HWPARAMS3 */ +#define DWC3_NUM_IN_EPS_MASK (0x1f << 18) +#define DWC3_NUM_EPS_MASK (0x3f << 12) +#define DWC3_NUM_EPS(p) (((p)->hwparams3 & \ + (DWC3_NUM_EPS_MASK)) >> 12) +#define DWC3_NUM_IN_EPS(p) (((p)->hwparams3 & \ + (DWC3_NUM_IN_EPS_MASK)) >> 18) + /* HWPARAMS7 */ #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff) @@ -641,6 +649,8 @@ struct dwc3_scratchpad_array { * @u2pel: parameter from Set SEL request. * @u1sel: parameter from Set SEL request. * @u1pel: parameter from Set SEL request. + * @num_out_eps: number of out endpoints + * @num_in_eps: number of in endpoints * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state @@ -658,8 +668,10 @@ struct dwc3 { dma_addr_t ep0_trb_addr; dma_addr_t ep0_bounce_addr; struct dwc3_request ep0_usb_req; + /* device lock */ spinlock_t lock; + struct device *dev; struct platform_device *xhci; @@ -727,6 +739,9 @@ struct dwc3 { u8 speed; + u8 num_out_eps; + u8 num_in_eps; + void *mem; struct dwc3_hwparams hwparams; -- cgit From 6a1e3ef45fb0c4d79cbb5190c8fc59263c630b0e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 5 May 2011 16:21:59 +0300 Subject: usb: dwc3: gadget: use num_(in|out)_eps from HW params that way we will only tell gadget framework about the endpoints we actually have. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8e53acc0e43e..2b6e7e001207 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1623,14 +1623,15 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { /* -------------------------------------------------------------------------- */ -static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) +static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, + u8 num, u32 direction) { struct dwc3_ep *dep; - u8 epnum; + u8 i; - INIT_LIST_HEAD(&dwc->gadget.ep_list); + for (i = 0; i < num; i++) { + u8 epnum = (i << 1) | (!!direction); - for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { dep = kzalloc(sizeof(*dep), GFP_KERNEL); if (!dep) { dev_err(dwc->dev, "can't allocate endpoint %d\n", @@ -1644,6 +1645,7 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, (epnum & 1) ? "in" : "out"); + dep->endpoint.name = dep->name; dep->direction = (epnum & 1); @@ -1674,6 +1676,27 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) return 0; } +static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) +{ + int ret; + + INIT_LIST_HEAD(&dwc->gadget.ep_list); + + ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); + if (ret < 0) { + dev_vdbg(dwc->dev, "failed to allocate OUT endpoints\n"); + return ret; + } + + ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); + if (ret < 0) { + dev_vdbg(dwc->dev, "failed to allocate IN endpoints\n"); + return ret; + } + + return 0; +} + static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) { struct dwc3_ep *dep; @@ -1681,6 +1704,9 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { dep = dwc->eps[epnum]; + if (!dep) + continue; + dwc3_free_trb_pool(dep); if (epnum != 0 && epnum != 1) @@ -2015,6 +2041,9 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc) struct dwc3_ep *dep; dep = dwc->eps[epnum]; + if (!dep) + continue; + if (!(dep->flags & DWC3_EP_ENABLED)) continue; @@ -2032,6 +2061,8 @@ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) int ret; dep = dwc->eps[epnum]; + if (!dep) + continue; if (!(dep->flags & DWC3_EP_STALL)) continue; -- cgit From 42c0bf1ce7c067bbc3e77d5626f102a16bc4fb6b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 10:39:57 +0200 Subject: usb: otg: prefix otg_state_string with usb_ all other functions under drivers/usb/ start with usb_, let's do the same thing. This patch is in preparation for moving otg_state_string to usb-common.c and deleting otg.c completely. Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 8 ++++---- drivers/usb/musb/blackfin.c | 6 +++--- drivers/usb/musb/da8xx.c | 8 ++++---- drivers/usb/musb/davinci.c | 4 ++-- drivers/usb/musb/musb_core.c | 39 ++++++++++++++++++++------------------- drivers/usb/musb/musb_dsps.c | 8 ++++---- drivers/usb/musb/musb_gadget.c | 8 ++++---- drivers/usb/musb/musb_host.c | 2 +- drivers/usb/musb/musb_virthub.c | 4 ++-- drivers/usb/musb/omap2430.c | 6 +++--- drivers/usb/musb/tusb6010.c | 14 +++++++------- drivers/usb/otg/fsl_otg.c | 2 +- drivers/usb/otg/isp1301_omap.c | 6 +++--- drivers/usb/otg/otg.c | 4 ++-- drivers/usb/otg/otg_fsm.c | 2 +- include/linux/usb/otg.h | 4 ++-- 16 files changed, 63 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 59eea219034a..2231850c0625 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -149,7 +149,7 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -195,7 +195,7 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) if (musb->is_active || (musb->a_wait_bcon == 0 && musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -208,7 +208,7 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -298,7 +298,7 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) /* NOTE: this must complete power-on within 100 ms. */ dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index dbb31b30c7fa..5e63b160db0c 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -280,13 +280,13 @@ static void musb_conn_timer_handler(unsigned long _musb) break; default: dev_dbg(musb->controller, "%s state not handled\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); break; } spin_unlock_irqrestore(&musb->lock, flags); dev_dbg(musb->controller, "state is %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } static void bfin_musb_enable(struct musb *musb) @@ -307,7 +307,7 @@ static void bfin_musb_set_vbus(struct musb *musb, int is_on) dev_dbg(musb->controller, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 7c71769d71ff..ea7e591093ee 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -198,7 +198,7 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -267,7 +267,7 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) if (musb->is_active || (musb->a_wait_bcon == 0 && musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -280,7 +280,7 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -360,7 +360,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e040d9103735..bea6cc35471c 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -215,7 +215,7 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "poll devctl %02x (%s)\n", devctl, - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -349,7 +349,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) davinci_musb_source_power(musb, drvvbus, 0); dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); retval = IRQ_HANDLED; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fad8571ed433..6bd879257e4c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -372,13 +372,13 @@ static void musb_otg_timer_func(unsigned long data) case OTG_STATE_A_SUSPEND: case OTG_STATE_A_WAIT_BCON: dev_dbg(musb->controller, "HNP: %s timeout\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); musb_platform_set_vbus(musb, 0); musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; break; default: dev_dbg(musb->controller, "HNP: Unhandled mode %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } musb->ignore_disconnect = 0; spin_unlock_irqrestore(&musb->lock, flags); @@ -393,13 +393,14 @@ void musb_hnp_stop(struct musb *musb) void __iomem *mbase = musb->mregs; u8 reg; - dev_dbg(musb->controller, "HNP: stop from %s\n", otg_state_string(musb->xceiv->state)); + dev_dbg(musb->controller, "HNP: stop from %s\n", + usb_otg_state_string(musb->xceiv->state)); switch (musb->xceiv->state) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); dev_dbg(musb->controller, "HNP: back to %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); break; case OTG_STATE_B_HOST: dev_dbg(musb->controller, "HNP: Disabling HR\n"); @@ -413,7 +414,7 @@ void musb_hnp_stop(struct musb *musb) break; default: dev_dbg(musb->controller, "HNP: Stopping in unknown state %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } /* @@ -451,7 +452,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ if (int_usb & MUSB_INTR_RESUME) { handled = IRQ_HANDLED; - dev_dbg(musb->controller, "RESUME (%s)\n", otg_state_string(musb->xceiv->state)); + dev_dbg(musb->controller, "RESUME (%s)\n", usb_otg_state_string(musb->xceiv->state)); if (devctl & MUSB_DEVCTL_HM) { void __iomem *mbase = musb->mregs; @@ -493,7 +494,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: WARNING("bogus %s RESUME (%s)\n", "host", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } else { switch (musb->xceiv->state) { @@ -522,7 +523,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: WARNING("bogus %s RESUME (%s)\n", "peripheral", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } } @@ -538,7 +539,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } dev_dbg(musb->controller, "SESSION_REQUEST (%s)\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); /* IRQ arrives from ID pin sense or (later, if VBUS power * is removed) SRP. responses are time critical: @@ -603,7 +604,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } dev_dbg(musb->controller, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), devctl, ({ char *s; switch (devctl & MUSB_DEVCTL_VBUS) { @@ -628,7 +629,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_SUSPEND) { dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n", - otg_state_string(musb->xceiv->state), devctl); + usb_otg_state_string(musb->xceiv->state), devctl); handled = IRQ_HANDLED; switch (musb->xceiv->state) { @@ -745,12 +746,12 @@ b_host: usb_hcd_resume_root_hub(hcd); dev_dbg(musb->controller, "CONNECT (%s) devctl %02x\n", - otg_state_string(musb->xceiv->state), devctl); + usb_otg_state_string(musb->xceiv->state), devctl); } if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) { dev_dbg(musb->controller, "DISCONNECT (%s) as %s, devctl %02x\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), MUSB_MODE(musb), devctl); handled = IRQ_HANDLED; @@ -787,7 +788,7 @@ b_host: break; default: WARNING("unhandled DISCONNECT transition (%s)\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); break; } } @@ -813,7 +814,7 @@ b_host: } } else { dev_dbg(musb->controller, "BUS RESET as %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); switch (musb->xceiv->state) { case OTG_STATE_A_SUSPEND: /* We need to ignore disconnect on suspend @@ -826,7 +827,7 @@ b_host: case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ /* never use invalid T(a_wait_bcon) */ dev_dbg(musb->controller, "HNP: in %s, %d msec timeout\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), TA_WAIT_BCON(musb)); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies(TA_WAIT_BCON(musb))); @@ -838,7 +839,7 @@ b_host: break; case OTG_STATE_B_WAIT_ACON: dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); musb->xceiv->state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); break; @@ -850,7 +851,7 @@ b_host: break; default: dev_dbg(musb->controller, "Unhandled BUS RESET as %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } } @@ -1632,7 +1633,7 @@ musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) int ret = -EINVAL; spin_lock_irqsave(&musb->lock, flags); - ret = sprintf(buf, "%s\n", otg_state_string(musb->xceiv->state)); + ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->state)); spin_unlock_irqrestore(&musb->lock, flags); return ret; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 4b4987461adb..1ea553d2b77f 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -225,7 +225,7 @@ static void otg_timer(unsigned long _musb) */ devctl = dsps_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -274,7 +274,7 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) if (musb->is_active || (musb->a_wait_bcon == 0 && musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); del_timer(&glue->timer[pdev->id]); glue->last_timer[pdev->id] = jiffies; return; @@ -289,7 +289,7 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) glue->last_timer[pdev->id] = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&glue->timer[pdev->id], timeout); } @@ -378,7 +378,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) /* NOTE: this must complete power-on within 100 ms. */ dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6101ebf803fd..e8408883ab0d 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1571,7 +1571,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) goto done; default: dev_dbg(musb->controller, "Unhandled wake: %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); goto done; } @@ -1970,7 +1970,7 @@ void musb_g_resume(struct musb *musb) break; default: WARNING("unhandled RESUME transition (%s)\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } @@ -2000,7 +2000,7 @@ void musb_g_suspend(struct musb *musb) * A_PERIPHERAL may need care too */ WARNING("unhandled SUSPEND transition (%s)\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } @@ -2034,7 +2034,7 @@ void musb_g_disconnect(struct musb *musb) switch (musb->xceiv->state) { default: dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); musb->xceiv->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); break; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 1ce1fcf3f3e7..51e9e8a38444 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2453,7 +2453,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (musb->is_active) { WARNING("trying to suspend as %s while active\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); return -EBUSY; } else return 0; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index f70579154ded..ef7d11045f56 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -95,7 +95,7 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) break; default: dev_dbg(musb->controller, "bogus rh suspend? %s\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } else if (power & MUSB_POWER_SUSPENDM) { power &= ~MUSB_POWER_SUSPENDM; @@ -203,7 +203,7 @@ void musb_root_disconnect(struct musb *musb) break; default: dev_dbg(musb->controller, "host disconnect (%s)\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 1a42a458f2c4..8ba9bb2a91a7 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -117,7 +117,7 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) if (musb->is_active || ((musb->a_wait_bcon == 0) && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { dev_dbg(musb->controller, "%s active, deleting timer\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -134,7 +134,7 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -200,7 +200,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) dev_dbg(musb->controller, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 464bd23cccda..7369ba33c94f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -423,7 +423,7 @@ static void musb_do_idle(unsigned long _musb) && (musb->idle_timeout == 0 || time_after(jiffies, musb->idle_timeout))) { dev_dbg(musb->controller, "Nothing connected %s, turning off VBUS\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); } /* FALLTHROUGH */ case OTG_STATE_A_IDLE: @@ -478,7 +478,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) if (musb->is_active || ((musb->a_wait_bcon == 0) && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { dev_dbg(musb->controller, "%s active, deleting timer\n", - otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -495,7 +495,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -571,7 +571,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); dev_dbg(musb->controller, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n", - otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL), musb_readl(tbase, TUSB_DEV_OTG_STAT), conf, prcm); @@ -678,13 +678,13 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) musb->is_active = 0; } dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", - otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->state), otg_stat); idle_timeout = jiffies + (1 * HZ); schedule_work(&musb->irq_work); } else /* A-dev state machine */ { dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", - otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->state), otg_stat); switch (musb->xceiv->state) { case OTG_STATE_A_IDLE: @@ -733,7 +733,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) u8 devctl; dev_dbg(musb->controller, "%s timer, %03x\n", - otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->state), otg_stat); switch (musb->xceiv->state) { case OTG_STATE_A_WAIT_VRISE: diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 37e8e1578316..72a2a00c2487 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -992,7 +992,7 @@ static int show_fsl_usb2_otg_state(struct device *dev, /* State */ t = scnprintf(next, size, "OTG state: %s\n\n", - otg_state_string(fsl_otg_dev->phy.state)); + usb_otg_state_string(fsl_otg_dev->phy.state)); size -= t; next += t; diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index af9cb11626b2..8fe0c3b95261 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -236,7 +236,7 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) static inline const char *state_name(struct isp1301 *isp) { - return otg_state_string(isp->phy.state); + return usb_otg_state_string(isp->phy.state); } /*-------------------------------------------------------------------------*/ @@ -481,7 +481,7 @@ static void check_state(struct isp1301 *isp, const char *tag) if (isp->phy.state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - otg_state_string(state), fsm, state_name(isp), + usb_otg_state_string(state), fsm, state_name(isp), omap_readl(OTG_CTRL)); } @@ -1077,7 +1077,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) if (state != isp->phy.state) pr_debug(" isp, %s -> %s\n", - otg_state_string(state), state_name(isp)); + usb_otg_state_string(state), state_name(isp)); #ifdef CONFIG_USB_OTG /* update the OTG controller state to match the isp1301; may diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 358cfd9bce89..fd9a4b7bebe7 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -11,7 +11,7 @@ #include #include -const char *otg_state_string(enum usb_otg_state state) +const char *usb_otg_state_string(enum usb_otg_state state) { switch (state) { case OTG_STATE_A_IDLE: @@ -44,4 +44,4 @@ const char *otg_state_string(enum usb_otg_state state) return "UNDEFINED"; } } -EXPORT_SYMBOL(otg_state_string); +EXPORT_SYMBOL(usb_otg_state_string); diff --git a/drivers/usb/otg/otg_fsm.c b/drivers/usb/otg/otg_fsm.c index ade131a8ae5e..1f729a15decb 100644 --- a/drivers/usb/otg/otg_fsm.c +++ b/drivers/usb/otg/otg_fsm.c @@ -119,7 +119,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) state_changed = 1; if (fsm->otg->phy->state == new_state) return 0; - VDBG("Set state: %s\n", otg_state_string(new_state)); + VDBG("Set state: %s\n", usb_otg_state_string(new_state)); otg_leave_state(fsm, fsm->otg->phy->state); switch (new_state) { case OTG_STATE_B_IDLE: diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index e8a5fe87c6bd..9f9fb3927b0a 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -37,9 +37,9 @@ struct usb_otg { }; #ifdef CONFIG_USB_OTG_UTILS -extern const char *otg_state_string(enum usb_otg_state state); +extern const char *usb_otg_state_string(enum usb_otg_state state); #else -static inline const char *otg_state_string(enum usb_otg_state state) +static inline const char *usb_otg_state_string(enum usb_otg_state state) { return NULL; } -- cgit From 7009bdd7f31ed6e769af0f76e2368bb6033be572 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 10:45:56 +0200 Subject: usb: otg: move usb_otg_state_string to usb-common.c otg.c only had a single function definition which might make more sense to be placed in usb-common.c. While doing that, we also delete otg.c since it's now empty. Signed-off-by: Felipe Balbi --- drivers/usb/otg/Makefile | 3 --- drivers/usb/otg/otg.c | 47 ----------------------------------------------- drivers/usb/usb-common.c | 26 ++++++++++++++++++++++++++ include/linux/usb/otg.h | 7 ------- 4 files changed, 26 insertions(+), 57 deletions(-) delete mode 100644 drivers/usb/otg/otg.c (limited to 'drivers') diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index a844b8d35d14..6abc45388e24 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -5,9 +5,6 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG -# infrastructure -obj-$(CONFIG_USB_OTG_UTILS) += otg.o - # transceiver drivers obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c deleted file mode 100644 index fd9a4b7bebe7..000000000000 --- a/drivers/usb/otg/otg.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * otg.c -- USB OTG utility code - * - * Copyright (C) 2004 Texas Instruments - * - * 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 - -const char *usb_otg_state_string(enum usb_otg_state state) -{ - switch (state) { - case OTG_STATE_A_IDLE: - return "a_idle"; - case OTG_STATE_A_WAIT_VRISE: - return "a_wait_vrise"; - case OTG_STATE_A_WAIT_BCON: - return "a_wait_bcon"; - case OTG_STATE_A_HOST: - return "a_host"; - case OTG_STATE_A_SUSPEND: - return "a_suspend"; - case OTG_STATE_A_PERIPHERAL: - return "a_peripheral"; - case OTG_STATE_A_WAIT_VFALL: - return "a_wait_vfall"; - case OTG_STATE_A_VBUS_ERR: - return "a_vbus_err"; - case OTG_STATE_B_IDLE: - return "b_idle"; - case OTG_STATE_B_SRP_INIT: - return "b_srp_init"; - case OTG_STATE_B_PERIPHERAL: - return "b_peripheral"; - case OTG_STATE_B_WAIT_ACON: - return "b_wait_acon"; - case OTG_STATE_B_HOST: - return "b_host"; - default: - return "UNDEFINED"; - } -} -EXPORT_SYMBOL(usb_otg_state_string); diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c index 070b681e5d17..0db0a919d72b 100644 --- a/drivers/usb/usb-common.c +++ b/drivers/usb/usb-common.c @@ -14,6 +14,32 @@ #include #include #include +#include + +const char *usb_otg_state_string(enum usb_otg_state state) +{ + static const char *const names[] = { + [OTG_STATE_A_IDLE] = "a_idle", + [OTG_STATE_A_WAIT_VRISE] = "a_wait_vrise", + [OTG_STATE_A_WAIT_BCON] = "a_wait_bcon", + [OTG_STATE_A_HOST] = "a_host", + [OTG_STATE_A_SUSPEND] = "a_suspend", + [OTG_STATE_A_PERIPHERAL] = "a_peripheral", + [OTG_STATE_A_WAIT_VFALL] = "a_wait_vfall", + [OTG_STATE_A_VBUS_ERR] = "a_vbus_err", + [OTG_STATE_B_IDLE] = "b_idle", + [OTG_STATE_B_SRP_INIT] = "b_srp_init", + [OTG_STATE_B_PERIPHERAL] = "b_peripheral", + [OTG_STATE_B_WAIT_ACON] = "b_wait_acon", + [OTG_STATE_B_HOST] = "b_host", + }; + + if (state < 0 || state >= ARRAY_SIZE(names)) + return "UNDEFINED"; + + return names[state]; +} +EXPORT_SYMBOL_GPL(usb_otg_state_string); const char *usb_speed_string(enum usb_device_speed speed) { diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 9f9fb3927b0a..291e01ba32e5 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -36,14 +36,7 @@ struct usb_otg { }; -#ifdef CONFIG_USB_OTG_UTILS extern const char *usb_otg_state_string(enum usb_otg_state state); -#else -static inline const char *usb_otg_state_string(enum usb_otg_state state) -{ - return NULL; -} -#endif /* Context: can sleep */ static inline int -- cgit From 110ff6d04162a8a3b288019eaf84dee0800270e0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 10:49:27 +0200 Subject: usb: phy: convert EXPORT_SYMBOL to EXPORT_SYMBOL_GPL we only want GPL users for our generic functions, so let's switch over to EXPORT_SYMBOL_GPL. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index bc1970c55df0..f52c006417ff 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -109,7 +109,7 @@ struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) return phy; } -EXPORT_SYMBOL(devm_usb_get_phy); +EXPORT_SYMBOL_GPL(devm_usb_get_phy); /** * usb_get_phy - find the USB PHY @@ -142,7 +142,7 @@ err0: return phy; } -EXPORT_SYMBOL(usb_get_phy); +EXPORT_SYMBOL_GPL(usb_get_phy); /** * devm_usb_get_phy_by_phandle - find the USB PHY by phandle @@ -206,7 +206,7 @@ err0: return phy; } -EXPORT_SYMBOL(devm_usb_get_phy_by_phandle); +EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle); /** * usb_get_phy_dev - find the USB PHY @@ -239,7 +239,7 @@ err0: return phy; } -EXPORT_SYMBOL(usb_get_phy_dev); +EXPORT_SYMBOL_GPL(usb_get_phy_dev); /** * devm_usb_get_phy_dev - find the USB PHY using device ptr and index @@ -269,7 +269,7 @@ struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) return phy; } -EXPORT_SYMBOL(devm_usb_get_phy_dev); +EXPORT_SYMBOL_GPL(devm_usb_get_phy_dev); /** * devm_usb_put_phy - release the USB PHY @@ -288,7 +288,7 @@ void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); } -EXPORT_SYMBOL(devm_usb_put_phy); +EXPORT_SYMBOL_GPL(devm_usb_put_phy); /** * usb_put_phy - release the USB PHY @@ -307,7 +307,7 @@ void usb_put_phy(struct usb_phy *x) module_put(owner); } } -EXPORT_SYMBOL(usb_put_phy); +EXPORT_SYMBOL_GPL(usb_put_phy); /** * usb_add_phy - declare the USB PHY @@ -347,7 +347,7 @@ out: spin_unlock_irqrestore(&phy_lock, flags); return ret; } -EXPORT_SYMBOL(usb_add_phy); +EXPORT_SYMBOL_GPL(usb_add_phy); /** * usb_add_phy_dev - declare the USB PHY @@ -377,7 +377,7 @@ int usb_add_phy_dev(struct usb_phy *x) spin_unlock_irqrestore(&phy_lock, flags); return 0; } -EXPORT_SYMBOL(usb_add_phy_dev); +EXPORT_SYMBOL_GPL(usb_add_phy_dev); /** * usb_remove_phy - remove the OTG PHY @@ -399,7 +399,7 @@ void usb_remove_phy(struct usb_phy *x) } spin_unlock_irqrestore(&phy_lock, flags); } -EXPORT_SYMBOL(usb_remove_phy); +EXPORT_SYMBOL_GPL(usb_remove_phy); /** * usb_bind_phy - bind the phy and the controller that uses the phy -- cgit From a0e631235a04f8a815a1ecec93ef418f7d1e6086 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:01:15 +0200 Subject: usb: phy: move all PHY drivers to drivers/usb/phy/ that's a much more reasonable location for those drivers. It helps us saving drivers/usb/otg/ for when we actually start adding generic OTG code. Also completely delete drivers/usb/otg/ as there's nothing left there. Signed-off-by: Felipe Balbi --- drivers/usb/Kconfig | 2 - drivers/usb/Makefile | 2 - drivers/usb/otg/Kconfig | 141 ---- drivers/usb/otg/Makefile | 21 - drivers/usb/otg/ab8500-usb.c | 596 ------------- drivers/usb/otg/fsl_otg.c | 1173 -------------------------- drivers/usb/otg/fsl_otg.h | 406 --------- drivers/usb/otg/gpio_vbus.c | 416 --------- drivers/usb/otg/isp1301_omap.c | 1656 ------------------------------------ drivers/usb/otg/msm_otg.c | 1762 --------------------------------------- drivers/usb/otg/mv_otg.c | 923 -------------------- drivers/usb/otg/mv_otg.h | 165 ---- drivers/usb/otg/mxs-phy.c | 220 ----- drivers/usb/otg/nop-usb-xceiv.c | 294 ------- drivers/usb/otg/otg_fsm.c | 348 -------- drivers/usb/otg/otg_fsm.h | 154 ---- drivers/usb/otg/twl4030-usb.c | 728 ---------------- drivers/usb/otg/twl6030-usb.c | 446 ---------- drivers/usb/otg/ulpi.c | 283 ------- drivers/usb/otg/ulpi_viewport.c | 80 -- drivers/usb/phy/Kconfig | 168 +++- drivers/usb/phy/Makefile | 24 +- drivers/usb/phy/ab8500-usb.c | 596 +++++++++++++ drivers/usb/phy/fsl_otg.c | 1173 ++++++++++++++++++++++++++ drivers/usb/phy/fsl_otg.h | 406 +++++++++ drivers/usb/phy/gpio_vbus.c | 416 +++++++++ drivers/usb/phy/isp1301_omap.c | 1656 ++++++++++++++++++++++++++++++++++++ drivers/usb/phy/msm_otg.c | 1762 +++++++++++++++++++++++++++++++++++++++ drivers/usb/phy/mv_otg.c | 923 ++++++++++++++++++++ drivers/usb/phy/mv_otg.h | 165 ++++ drivers/usb/phy/mxs-phy.c | 220 +++++ drivers/usb/phy/nop-usb-xceiv.c | 294 +++++++ drivers/usb/phy/otg_fsm.c | 348 ++++++++ drivers/usb/phy/otg_fsm.h | 154 ++++ drivers/usb/phy/twl4030-usb.c | 728 ++++++++++++++++ drivers/usb/phy/twl6030-usb.c | 446 ++++++++++ drivers/usb/phy/ulpi.c | 283 +++++++ drivers/usb/phy/ulpi_viewport.c | 80 ++ 38 files changed, 9821 insertions(+), 9837 deletions(-) delete mode 100644 drivers/usb/otg/Kconfig delete mode 100644 drivers/usb/otg/Makefile delete mode 100644 drivers/usb/otg/ab8500-usb.c delete mode 100644 drivers/usb/otg/fsl_otg.c delete mode 100644 drivers/usb/otg/fsl_otg.h delete mode 100644 drivers/usb/otg/gpio_vbus.c delete mode 100644 drivers/usb/otg/isp1301_omap.c delete mode 100644 drivers/usb/otg/msm_otg.c delete mode 100644 drivers/usb/otg/mv_otg.c delete mode 100644 drivers/usb/otg/mv_otg.h delete mode 100644 drivers/usb/otg/mxs-phy.c delete mode 100644 drivers/usb/otg/nop-usb-xceiv.c delete mode 100644 drivers/usb/otg/otg_fsm.c delete mode 100644 drivers/usb/otg/otg_fsm.h delete mode 100644 drivers/usb/otg/twl4030-usb.c delete mode 100644 drivers/usb/otg/twl6030-usb.c delete mode 100644 drivers/usb/otg/ulpi.c delete mode 100644 drivers/usb/otg/ulpi_viewport.c create mode 100644 drivers/usb/phy/ab8500-usb.c create mode 100644 drivers/usb/phy/fsl_otg.c create mode 100644 drivers/usb/phy/fsl_otg.h create mode 100644 drivers/usb/phy/gpio_vbus.c create mode 100644 drivers/usb/phy/isp1301_omap.c create mode 100644 drivers/usb/phy/msm_otg.c create mode 100644 drivers/usb/phy/mv_otg.c create mode 100644 drivers/usb/phy/mv_otg.h create mode 100644 drivers/usb/phy/mxs-phy.c create mode 100644 drivers/usb/phy/nop-usb-xceiv.c create mode 100644 drivers/usb/phy/otg_fsm.c create mode 100644 drivers/usb/phy/otg_fsm.h create mode 100644 drivers/usb/phy/twl4030-usb.c create mode 100644 drivers/usb/phy/twl6030-usb.c create mode 100644 drivers/usb/phy/ulpi.c create mode 100644 drivers/usb/phy/ulpi_viewport.c (limited to 'drivers') diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 640ae6c6d2d2..2c481b808276 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -186,6 +186,4 @@ source "drivers/usb/atm/Kconfig" source "drivers/usb/gadget/Kconfig" -source "drivers/usb/otg/Kconfig" - endif # USB_SUPPORT diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 8f5ebced5df0..860306b14392 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -6,8 +6,6 @@ obj-$(CONFIG_USB) += core/ -obj-$(CONFIG_USB_OTG_UTILS) += otg/ - obj-$(CONFIG_USB_DWC3) += dwc3/ obj-$(CONFIG_USB_MON) += mon/ diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig deleted file mode 100644 index 37962c99ff1e..000000000000 --- a/drivers/usb/otg/Kconfig +++ /dev/null @@ -1,141 +0,0 @@ -# -# USB OTG infrastructure may be needed for peripheral-only, host-only, -# or OTG-capable configurations when OTG transceivers or controllers -# are used. -# - -comment "OTG and related infrastructure" - -config USB_OTG_UTILS - bool - help - Select this to make sure the build includes objects from - the OTG infrastructure directory. - -if USB || USB_GADGET - -# -# USB Transceiver Drivers -# -config USB_GPIO_VBUS - tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" - depends on GENERIC_GPIO - select USB_OTG_UTILS - help - Provides simple GPIO VBUS sensing for controllers with an - internal transceiver via the usb_phy interface, and - optionally control of a D+ pullup GPIO as well as a VBUS - current limit regulator. - -config ISP1301_OMAP - tristate "Philips ISP1301 with OMAP OTG" - depends on I2C && ARCH_OMAP_OTG - select USB_OTG_UTILS - help - If you say yes here you get support for the Philips ISP1301 - USB-On-The-Go transceiver working with the OMAP OTG controller. - The ISP1301 is a full speed USB transceiver which is used in - products including H2, H3, and H4 development boards for Texas - Instruments OMAP processors. - - This driver can also be built as a module. If so, the module - will be called isp1301_omap. - -config USB_ULPI - bool "Generic ULPI Transceiver Driver" - depends on ARM - select USB_OTG_UTILS - help - Enable this to support ULPI connected USB OTG transceivers which - are likely found on embedded boards. - -config USB_ULPI_VIEWPORT - bool - depends on USB_ULPI - help - Provides read/write operations to the ULPI phy register set for - controllers with a viewport register (e.g. Chipidea/ARC controllers). - -config TWL4030_USB - tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS - select USB_OTG_UTILS - help - Enable this to support the USB OTG transceiver on TWL4030 - family chips (including the TWL5030 and TPS659x0 devices). - This transceiver supports high and full speed devices plus, - in host mode, low speed. - -config TWL6030_USB - tristate "TWL6030 USB Transceiver Driver" - depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS - select USB_OTG_UTILS - help - Enable this to support the USB OTG transceiver on TWL6030 - family chips. This TWL6030 transceiver has the VBUS and ID GND - and OTG SRP events capabilities. For all other transceiver functionality - UTMI PHY is embedded in OMAP4430. The internal PHY configurations APIs - are hooked to this driver through platform_data structure. - The definition of internal PHY APIs are in the mach-omap2 layer. - -config NOP_USB_XCEIV - tristate "NOP USB Transceiver Driver" - select USB_OTG_UTILS - help - This driver is to be used by all the usb transceiver which are either - built-in with usb ip or which are autonomous and doesn't require any - phy programming such as ISP1x04 etc. - -config USB_MSM_OTG - tristate "OTG support for Qualcomm on-chip USB controller" - depends on (USB || USB_GADGET) && ARCH_MSM - select USB_OTG_UTILS - help - Enable this to support the USB OTG transceiver on MSM chips. It - handles PHY initialization, clock management, and workarounds - required after resetting the hardware and power management. - This driver is required even for peripheral only or host only - mode configurations. - This driver is not supported on boards like trout which - has an external PHY. - -config AB8500_USB - tristate "AB8500 USB Transceiver Driver" - depends on AB8500_CORE - select USB_OTG_UTILS - help - Enable this to support the USB OTG transceiver in AB8500 chip. - This transceiver supports high and full speed devices plus, - in host mode, low speed. - -config FSL_USB2_OTG - bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND - select USB_OTG - select USB_OTG_UTILS - help - Enable this to support Freescale USB OTG transceiver. - -config USB_MXS_PHY - tristate "Freescale MXS USB PHY support" - depends on ARCH_MXC || ARCH_MXS - select STMP_DEVICE - select USB_OTG_UTILS - help - Enable this to support the Freescale MXS USB PHY. - - MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. - -config USB_MV_OTG - tristate "Marvell USB OTG support" - depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND - select USB_OTG - select USB_OTG_UTILS - help - Say Y here if you want to build Marvell USB OTG transciever - driver in kernel (including PXA and MMP series). This driver - implements role switch between EHCI host driver and gadget driver. - - To compile this driver as a module, choose M here. - -endif # USB || OTG diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile deleted file mode 100644 index 6abc45388e24..000000000000 --- a/drivers/usb/otg/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# OTG infrastructure and transceiver drivers -# - -ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG -ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG - -# transceiver drivers -obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o -obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o -obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o -obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o -obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o -obj-$(CONFIG_USB_ULPI) += ulpi.o -obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o -obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o -obj-$(CONFIG_AB8500_USB) += ab8500-usb.o -fsl_usb2_otg-objs := fsl_otg.o otg_fsm.o -obj-$(CONFIG_FSL_USB2_OTG) += fsl_usb2_otg.o -obj-$(CONFIG_USB_MXS_PHY) += mxs-phy.o -obj-$(CONFIG_USB_MV_OTG) += mv_otg.o diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c deleted file mode 100644 index 2d86f26a0183..000000000000 --- a/drivers/usb/otg/ab8500-usb.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * drivers/usb/otg/ab8500_usb.c - * - * USB transceiver driver for AB8500 chip - * - * Copyright (C) 2010 ST-Ericsson AB - * Mian Yousaf Kaukab - * - * 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 - -#define AB8500_MAIN_WD_CTRL_REG 0x01 -#define AB8500_USB_LINE_STAT_REG 0x80 -#define AB8500_USB_PHY_CTRL_REG 0x8A - -#define AB8500_BIT_OTG_STAT_ID (1 << 0) -#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) -#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) -#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) -#define AB8500_BIT_WD_CTRL_KICK (1 << 1) - -#define AB8500_V1x_LINK_STAT_WAIT (HZ/10) -#define AB8500_WD_KICK_DELAY_US 100 /* usec */ -#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ -#define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ - -/* Usb line status register */ -enum ab8500_usb_link_status { - USB_LINK_NOT_CONFIGURED = 0, - USB_LINK_STD_HOST_NC, - USB_LINK_STD_HOST_C_NS, - USB_LINK_STD_HOST_C_S, - USB_LINK_HOST_CHG_NM, - USB_LINK_HOST_CHG_HS, - USB_LINK_HOST_CHG_HS_CHIRP, - USB_LINK_DEDICATED_CHG, - USB_LINK_ACA_RID_A, - USB_LINK_ACA_RID_B, - USB_LINK_ACA_RID_C_NM, - USB_LINK_ACA_RID_C_HS, - USB_LINK_ACA_RID_C_HS_CHIRP, - USB_LINK_HM_IDGND, - USB_LINK_RESERVED, - USB_LINK_NOT_VALID_LINK -}; - -struct ab8500_usb { - struct usb_phy phy; - struct device *dev; - int irq_num_id_rise; - int irq_num_id_fall; - int irq_num_vbus_rise; - int irq_num_vbus_fall; - int irq_num_link_status; - unsigned vbus_draw; - struct delayed_work dwork; - struct work_struct phy_dis_work; - unsigned long link_status_wait; - int rev; -}; - -static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) -{ - return container_of(x, struct ab8500_usb, phy); -} - -static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) -{ - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - AB8500_BIT_WD_CTRL_ENABLE); - - udelay(AB8500_WD_KICK_DELAY_US); - - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - (AB8500_BIT_WD_CTRL_ENABLE - | AB8500_BIT_WD_CTRL_KICK)); - - if (ab->rev > 0x10) /* v1.1 v2.0 */ - udelay(AB8500_WD_V11_DISABLE_DELAY_US); - else /* v1.0 */ - msleep(AB8500_WD_V10_DISABLE_DELAY_MS); - - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - 0); -} - -static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, - bool enable) -{ - u8 ctrl_reg; - abx500_get_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_PHY_CTRL_REG, - &ctrl_reg); - if (sel_host) { - if (enable) - ctrl_reg |= AB8500_BIT_PHY_CTRL_HOST_EN; - else - ctrl_reg &= ~AB8500_BIT_PHY_CTRL_HOST_EN; - } else { - if (enable) - ctrl_reg |= AB8500_BIT_PHY_CTRL_DEVICE_EN; - else - ctrl_reg &= ~AB8500_BIT_PHY_CTRL_DEVICE_EN; - } - - abx500_set_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_PHY_CTRL_REG, - ctrl_reg); - - /* Needed to enable the phy.*/ - if (enable) - ab8500_usb_wd_workaround(ab); -} - -#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_ctrl(ab, true, true) -#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_ctrl(ab, true, false) -#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) -#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) - -static int ab8500_usb_link_status_update(struct ab8500_usb *ab) -{ - u8 reg; - enum ab8500_usb_link_status lsts; - void *v = NULL; - enum usb_phy_events event; - - abx500_get_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_LINE_STAT_REG, - ®); - - lsts = (reg >> 3) & 0x0F; - - switch (lsts) { - case USB_LINK_NOT_CONFIGURED: - case USB_LINK_RESERVED: - case USB_LINK_NOT_VALID_LINK: - /* TODO: Disable regulators. */ - ab8500_usb_host_phy_dis(ab); - ab8500_usb_peri_phy_dis(ab); - ab->phy.state = OTG_STATE_B_IDLE; - ab->phy.otg->default_a = false; - ab->vbus_draw = 0; - event = USB_EVENT_NONE; - break; - - case USB_LINK_STD_HOST_NC: - case USB_LINK_STD_HOST_C_NS: - case USB_LINK_STD_HOST_C_S: - case USB_LINK_HOST_CHG_NM: - case USB_LINK_HOST_CHG_HS: - case USB_LINK_HOST_CHG_HS_CHIRP: - if (ab->phy.otg->gadget) { - /* TODO: Enable regulators. */ - ab8500_usb_peri_phy_en(ab); - v = ab->phy.otg->gadget; - } - event = USB_EVENT_VBUS; - break; - - case USB_LINK_HM_IDGND: - if (ab->phy.otg->host) { - /* TODO: Enable regulators. */ - ab8500_usb_host_phy_en(ab); - v = ab->phy.otg->host; - } - ab->phy.state = OTG_STATE_A_IDLE; - ab->phy.otg->default_a = true; - event = USB_EVENT_ID; - break; - - case USB_LINK_ACA_RID_A: - case USB_LINK_ACA_RID_B: - /* TODO */ - case USB_LINK_ACA_RID_C_NM: - case USB_LINK_ACA_RID_C_HS: - case USB_LINK_ACA_RID_C_HS_CHIRP: - case USB_LINK_DEDICATED_CHG: - /* TODO: vbus_draw */ - event = USB_EVENT_CHARGER; - break; - } - - atomic_notifier_call_chain(&ab->phy.notifier, event, v); - - return 0; -} - -static void ab8500_usb_delayed_work(struct work_struct *work) -{ - struct ab8500_usb *ab = container_of(work, struct ab8500_usb, - dwork.work); - - ab8500_usb_link_status_update(ab); -} - -static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - -static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Link status will not be updated till phy is disabled. */ - ab8500_usb_peri_phy_dis(ab); - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - -static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - ab8500_usb_link_status_update(ab); - - return IRQ_HANDLED; -} - -static void ab8500_usb_phy_disable_work(struct work_struct *work) -{ - struct ab8500_usb *ab = container_of(work, struct ab8500_usb, - phy_dis_work); - - if (!ab->phy.otg->host) - ab8500_usb_host_phy_dis(ab); - - if (!ab->phy.otg->gadget) - ab8500_usb_peri_phy_dis(ab); -} - -static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) -{ - struct ab8500_usb *ab; - - if (!phy) - return -ENODEV; - - ab = phy_to_ab(phy); - - ab->vbus_draw = mA; - - if (mA) - atomic_notifier_call_chain(&ab->phy.notifier, - USB_EVENT_ENUMERATED, ab->phy.otg->gadget); - return 0; -} - -/* TODO: Implement some way for charging or other drivers to read - * ab->vbus_draw. - */ - -static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) -{ - /* TODO */ - return 0; -} - -static int ab8500_usb_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct ab8500_usb *ab; - - if (!otg) - return -ENODEV; - - ab = phy_to_ab(otg->phy); - - /* Some drivers call this function in atomic context. - * Do not update ab8500 registers directly till this - * is fixed. - */ - - if (!gadget) { - /* TODO: Disable regulators. */ - otg->gadget = NULL; - schedule_work(&ab->phy_dis_work); - } else { - otg->gadget = gadget; - otg->phy->state = OTG_STATE_B_IDLE; - - /* Phy will not be enabled if cable is already - * plugged-in. Schedule to enable phy. - * Use same delay to avoid any race condition. - */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - } - - return 0; -} - -static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct ab8500_usb *ab; - - if (!otg) - return -ENODEV; - - ab = phy_to_ab(otg->phy); - - /* Some drivers call this function in atomic context. - * Do not update ab8500 registers directly till this - * is fixed. - */ - - if (!host) { - /* TODO: Disable regulators. */ - otg->host = NULL; - schedule_work(&ab->phy_dis_work); - } else { - otg->host = host; - /* Phy will not be enabled if cable is already - * plugged-in. Schedule to enable phy. - * Use same delay to avoid any race condition. - */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - } - - return 0; -} - -static void ab8500_usb_irq_free(struct ab8500_usb *ab) -{ - if (ab->rev < 0x20) { - free_irq(ab->irq_num_id_rise, ab); - free_irq(ab->irq_num_id_fall, ab); - free_irq(ab->irq_num_vbus_rise, ab); - free_irq(ab->irq_num_vbus_fall, ab); - } else { - free_irq(ab->irq_num_link_status, ab); - } -} - -static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) -{ - int err; - - ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); - if (ab->irq_num_id_rise < 0) { - dev_err(&pdev->dev, "ID rise irq not found\n"); - return ab->irq_num_id_rise; - } - err = request_threaded_irq(ab->irq_num_id_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID rise irq\n"); - goto fail0; - } - - ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); - if (ab->irq_num_id_fall < 0) { - dev_err(&pdev->dev, "ID fall irq not found\n"); - return ab->irq_num_id_fall; - } - err = request_threaded_irq(ab->irq_num_id_fall, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID fall irq\n"); - goto fail1; - } - - ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); - if (ab->irq_num_vbus_rise < 0) { - dev_err(&pdev->dev, "VBUS rise irq not found\n"); - return ab->irq_num_vbus_rise; - } - err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); - goto fail2; - } - - ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); - if (ab->irq_num_vbus_fall < 0) { - dev_err(&pdev->dev, "VBUS fall irq not found\n"); - return ab->irq_num_vbus_fall; - } - err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, - ab8500_usb_v1x_vbus_fall_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); - goto fail3; - } - - return 0; -fail3: - free_irq(ab->irq_num_vbus_rise, ab); -fail2: - free_irq(ab->irq_num_id_fall, ab); -fail1: - free_irq(ab->irq_num_id_rise, ab); -fail0: - return err; -} - -static int ab8500_usb_v2_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) -{ - int err; - - ab->irq_num_link_status = platform_get_irq_byname(pdev, - "USB_LINK_STATUS"); - if (ab->irq_num_link_status < 0) { - dev_err(&pdev->dev, "Link status irq not found\n"); - return ab->irq_num_link_status; - } - - err = request_threaded_irq(ab->irq_num_link_status, NULL, - ab8500_usb_v20_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-link-status", ab); - if (err < 0) { - dev_err(ab->dev, - "request_irq failed for link status irq\n"); - return err; - } - - return 0; -} - -static int ab8500_usb_probe(struct platform_device *pdev) -{ - struct ab8500_usb *ab; - struct usb_otg *otg; - int err; - int rev; - - rev = abx500_get_chip_id(&pdev->dev); - if (rev < 0) { - dev_err(&pdev->dev, "Chip id read failed\n"); - return rev; - } else if (rev < 0x10) { - dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); - return -ENODEV; - } - - ab = kzalloc(sizeof *ab, GFP_KERNEL); - if (!ab) - return -ENOMEM; - - otg = kzalloc(sizeof *otg, GFP_KERNEL); - if (!otg) { - kfree(ab); - return -ENOMEM; - } - - ab->dev = &pdev->dev; - ab->rev = rev; - ab->phy.dev = ab->dev; - ab->phy.otg = otg; - ab->phy.label = "ab8500"; - ab->phy.set_suspend = ab8500_usb_set_suspend; - ab->phy.set_power = ab8500_usb_set_power; - ab->phy.state = OTG_STATE_UNDEFINED; - - otg->phy = &ab->phy; - otg->set_host = ab8500_usb_set_host; - otg->set_peripheral = ab8500_usb_set_peripheral; - - platform_set_drvdata(pdev, ab); - - ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); - - /* v1: Wait for link status to become stable. - * all: Updates form set_host and set_peripheral as they are atomic. - */ - INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); - - /* all: Disable phy when called from set_host and set_peripheral */ - INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); - - if (ab->rev < 0x20) { - err = ab8500_usb_v1x_res_setup(pdev, ab); - ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; - } else { - err = ab8500_usb_v2_res_setup(pdev, ab); - } - - if (err < 0) - goto fail0; - - err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); - if (err) { - dev_err(&pdev->dev, "Can't register transceiver\n"); - goto fail1; - } - - dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); - - return 0; -fail1: - ab8500_usb_irq_free(ab); -fail0: - kfree(otg); - kfree(ab); - return err; -} - -static int ab8500_usb_remove(struct platform_device *pdev) -{ - struct ab8500_usb *ab = platform_get_drvdata(pdev); - - ab8500_usb_irq_free(ab); - - cancel_delayed_work_sync(&ab->dwork); - - cancel_work_sync(&ab->phy_dis_work); - - usb_remove_phy(&ab->phy); - - ab8500_usb_host_phy_dis(ab); - ab8500_usb_peri_phy_dis(ab); - - platform_set_drvdata(pdev, NULL); - - kfree(ab->phy.otg); - kfree(ab); - - return 0; -} - -static struct platform_driver ab8500_usb_driver = { - .probe = ab8500_usb_probe, - .remove = ab8500_usb_remove, - .driver = { - .name = "ab8500-usb", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_usb_init(void) -{ - return platform_driver_register(&ab8500_usb_driver); -} -subsys_initcall(ab8500_usb_init); - -static void __exit ab8500_usb_exit(void) -{ - platform_driver_unregister(&ab8500_usb_driver); -} -module_exit(ab8500_usb_exit); - -MODULE_ALIAS("platform:ab8500_usb"); -MODULE_AUTHOR("ST-Ericsson AB"); -MODULE_DESCRIPTION("AB8500 usb transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c deleted file mode 100644 index 72a2a00c2487..000000000000 --- a/drivers/usb/otg/fsl_otg.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* - * Copyright (C) 2007,2008 Freescale semiconductor, Inc. - * - * Author: Li Yang - * Jerry Huang - * - * Initialization based on code from Shlomi Gridish. - * - * 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 "fsl_otg.h" - -#define DRIVER_VERSION "Rev. 1.55" -#define DRIVER_AUTHOR "Jerry Huang/Li Yang" -#define DRIVER_DESC "Freescale USB OTG Transceiver Driver" -#define DRIVER_INFO DRIVER_DESC " " DRIVER_VERSION - -static const char driver_name[] = "fsl-usb2-otg"; - -const pm_message_t otg_suspend_state = { - .event = 1, -}; - -#define HA_DATA_PULSE - -static struct usb_dr_mmap *usb_dr_regs; -static struct fsl_otg *fsl_otg_dev; -static int srp_wait_done; - -/* FSM timers */ -struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, - *b_ase0_brst_tmr, *b_se0_srp_tmr; - -/* Driver specific timers */ -struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, - *b_srp_wait_tmr, *a_wait_enum_tmr; - -static struct list_head active_timers; - -static struct fsl_otg_config fsl_otg_initdata = { - .otg_port = 1, -}; - -#ifdef CONFIG_PPC32 -static u32 _fsl_readl_be(const unsigned __iomem *p) -{ - return in_be32(p); -} - -static u32 _fsl_readl_le(const unsigned __iomem *p) -{ - return in_le32(p); -} - -static void _fsl_writel_be(u32 v, unsigned __iomem *p) -{ - out_be32(p, v); -} - -static void _fsl_writel_le(u32 v, unsigned __iomem *p) -{ - out_le32(p, v); -} - -static u32 (*_fsl_readl)(const unsigned __iomem *p); -static void (*_fsl_writel)(u32 v, unsigned __iomem *p); - -#define fsl_readl(p) (*_fsl_readl)((p)) -#define fsl_writel(v, p) (*_fsl_writel)((v), (p)) - -#else -#define fsl_readl(addr) readl(addr) -#define fsl_writel(val, addr) writel(val, addr) -#endif /* CONFIG_PPC32 */ - -/* Routines to access transceiver ULPI registers */ -u8 view_ulpi(u8 addr) -{ - u32 temp; - - temp = 0x40000000 | (addr << 16); - fsl_writel(temp, &usb_dr_regs->ulpiview); - udelay(1000); - while (temp & 0x40) - temp = fsl_readl(&usb_dr_regs->ulpiview); - return (le32_to_cpu(temp) & 0x0000ff00) >> 8; -} - -int write_ulpi(u8 addr, u8 data) -{ - u32 temp; - - temp = 0x60000000 | (addr << 16) | data; - fsl_writel(temp, &usb_dr_regs->ulpiview); - return 0; -} - -/* -------------------------------------------------------------*/ -/* Operations that will be called from OTG Finite State Machine */ - -/* Charge vbus for vbus pulsing in SRP */ -void fsl_otg_chrg_vbus(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - /* stop discharging, start charging */ - tmp = (tmp & ~OTGSC_CTRL_VBUS_DISCHARGE) | - OTGSC_CTRL_VBUS_CHARGE; - else - /* stop charging */ - tmp &= ~OTGSC_CTRL_VBUS_CHARGE; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* Discharge vbus through a resistor to ground */ -void fsl_otg_dischrg_vbus(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - /* stop charging, start discharging */ - tmp = (tmp & ~OTGSC_CTRL_VBUS_CHARGE) | - OTGSC_CTRL_VBUS_DISCHARGE; - else - /* stop discharging */ - tmp &= ~OTGSC_CTRL_VBUS_DISCHARGE; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* A-device driver vbus, controlled through PP bit in PORTSC */ -void fsl_otg_drv_vbus(int on) -{ - u32 tmp; - - if (on) { - tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; - fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); - } else { - tmp = fsl_readl(&usb_dr_regs->portsc) & - ~PORTSC_W1C_BITS & ~PORTSC_PORT_POWER; - fsl_writel(tmp, &usb_dr_regs->portsc); - } -} - -/* - * Pull-up D+, signalling connect by periperal. Also used in - * data-line pulsing in SRP - */ -void fsl_otg_loc_conn(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - tmp |= OTGSC_CTRL_DATA_PULSING; - else - tmp &= ~OTGSC_CTRL_DATA_PULSING; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* - * Generate SOF by host. This is controlled through suspend/resume the - * port. In host mode, controller will automatically send SOF. - * Suspend will block the data on the port. - */ -void fsl_otg_loc_sof(int on) -{ - u32 tmp; - - tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; - if (on) - tmp |= PORTSC_PORT_FORCE_RESUME; - else - tmp |= PORTSC_PORT_SUSPEND; - - fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); - -} - -/* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ -void fsl_otg_start_pulse(void) -{ - u32 tmp; - - srp_wait_done = 0; -#ifdef HA_DATA_PULSE - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - tmp |= OTGSC_HA_DATA_PULSE; - fsl_writel(tmp, &usb_dr_regs->otgsc); -#else - fsl_otg_loc_conn(1); -#endif - - fsl_otg_add_timer(b_data_pulse_tmr); -} - -void b_data_pulse_end(unsigned long foo) -{ -#ifdef HA_DATA_PULSE -#else - fsl_otg_loc_conn(0); -#endif - - /* Do VBUS pulse after data pulse */ - fsl_otg_pulse_vbus(); -} - -void fsl_otg_pulse_vbus(void) -{ - srp_wait_done = 0; - fsl_otg_chrg_vbus(1); - /* start the timer to end vbus charge */ - fsl_otg_add_timer(b_vbus_pulse_tmr); -} - -void b_vbus_pulse_end(unsigned long foo) -{ - fsl_otg_chrg_vbus(0); - - /* - * As USB3300 using the same a_sess_vld and b_sess_vld voltage - * we need to discharge the bus for a while to distinguish - * residual voltage of vbus pulsing and A device pull up - */ - fsl_otg_dischrg_vbus(1); - fsl_otg_add_timer(b_srp_wait_tmr); -} - -void b_srp_end(unsigned long foo) -{ - fsl_otg_dischrg_vbus(0); - srp_wait_done = 1; - - if ((fsl_otg_dev->phy.state == OTG_STATE_B_SRP_INIT) && - fsl_otg_dev->fsm.b_sess_vld) - fsl_otg_dev->fsm.b_srp_done = 1; -} - -/* - * Workaround for a_host suspending too fast. When a_bus_req=0, - * a_host will start by SRP. It needs to set b_hnp_enable before - * actually suspending to start HNP - */ -void a_wait_enum(unsigned long foo) -{ - VDBG("a_wait_enum timeout\n"); - if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) - fsl_otg_add_timer(a_wait_enum_tmr); - else - otg_statemachine(&fsl_otg_dev->fsm); -} - -/* The timeout callback function to set time out bit */ -void set_tmout(unsigned long indicator) -{ - *(int *)indicator = 1; -} - -/* Initialize timers */ -int fsl_otg_init_timers(struct otg_fsm *fsm) -{ - /* FSM used timers */ - a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, - (unsigned long)&fsm->a_wait_vrise_tmout); - if (!a_wait_vrise_tmr) - return -ENOMEM; - - a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, - (unsigned long)&fsm->a_wait_bcon_tmout); - if (!a_wait_bcon_tmr) - return -ENOMEM; - - a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, - (unsigned long)&fsm->a_aidl_bdis_tmout); - if (!a_aidl_bdis_tmr) - return -ENOMEM; - - b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, - (unsigned long)&fsm->b_ase0_brst_tmout); - if (!b_ase0_brst_tmr) - return -ENOMEM; - - b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, - (unsigned long)&fsm->b_se0_srp); - if (!b_se0_srp_tmr) - return -ENOMEM; - - b_srp_fail_tmr = otg_timer_initializer(&set_tmout, TB_SRP_FAIL, - (unsigned long)&fsm->b_srp_done); - if (!b_srp_fail_tmr) - return -ENOMEM; - - a_wait_enum_tmr = otg_timer_initializer(&a_wait_enum, 10, - (unsigned long)&fsm); - if (!a_wait_enum_tmr) - return -ENOMEM; - - /* device driver used timers */ - b_srp_wait_tmr = otg_timer_initializer(&b_srp_end, TB_SRP_WAIT, 0); - if (!b_srp_wait_tmr) - return -ENOMEM; - - b_data_pulse_tmr = otg_timer_initializer(&b_data_pulse_end, - TB_DATA_PLS, 0); - if (!b_data_pulse_tmr) - return -ENOMEM; - - b_vbus_pulse_tmr = otg_timer_initializer(&b_vbus_pulse_end, - TB_VBUS_PLS, 0); - if (!b_vbus_pulse_tmr) - return -ENOMEM; - - return 0; -} - -/* Uninitialize timers */ -void fsl_otg_uninit_timers(void) -{ - /* FSM used timers */ - kfree(a_wait_vrise_tmr); - kfree(a_wait_bcon_tmr); - kfree(a_aidl_bdis_tmr); - kfree(b_ase0_brst_tmr); - kfree(b_se0_srp_tmr); - kfree(b_srp_fail_tmr); - kfree(a_wait_enum_tmr); - - /* device driver used timers */ - kfree(b_srp_wait_tmr); - kfree(b_data_pulse_tmr); - kfree(b_vbus_pulse_tmr); -} - -/* Add timer to timer list */ -void fsl_otg_add_timer(void *gtimer) -{ - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer; - - /* - * Check if the timer is already in the active list, - * if so update timer count - */ - list_for_each_entry(tmp_timer, &active_timers, list) - if (tmp_timer == timer) { - timer->count = timer->expires; - return; - } - timer->count = timer->expires; - list_add_tail(&timer->list, &active_timers); -} - -/* Remove timer from the timer list; clear timeout status */ -void fsl_otg_del_timer(void *gtimer) -{ - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer, *del_tmp; - - list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) - if (tmp_timer == timer) - list_del(&timer->list); -} - -/* - * Reduce timer count by 1, and find timeout conditions. - * Called by fsl_otg 1ms timer interrupt - */ -int fsl_otg_tick_timer(void) -{ - struct fsl_otg_timer *tmp_timer, *del_tmp; - int expired = 0; - - list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { - tmp_timer->count--; - /* check if timer expires */ - if (!tmp_timer->count) { - list_del(&tmp_timer->list); - tmp_timer->function(tmp_timer->data); - expired = 1; - } - } - - return expired; -} - -/* Reset controller, not reset the bus */ -void otg_reset_controller(void) -{ - u32 command; - - command = fsl_readl(&usb_dr_regs->usbcmd); - command |= (1 << 1); - fsl_writel(command, &usb_dr_regs->usbcmd); - while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) - ; -} - -/* Call suspend/resume routines in host driver */ -int fsl_otg_start_host(struct otg_fsm *fsm, int on) -{ - struct usb_otg *otg = fsm->otg; - struct device *dev; - struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); - u32 retval = 0; - - if (!otg->host) - return -ENODEV; - dev = otg->host->controller; - - /* - * Update a_vbus_vld state as a_vbus_vld int is disabled - * in device mode - */ - fsm->a_vbus_vld = - !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); - if (on) { - /* start fsl usb host controller */ - if (otg_dev->host_working) - goto end; - else { - otg_reset_controller(); - VDBG("host on......\n"); - if (dev->driver->pm && dev->driver->pm->resume) { - retval = dev->driver->pm->resume(dev); - if (fsm->id) { - /* default-b */ - fsl_otg_drv_vbus(1); - /* - * Workaround: b_host can't driver - * vbus, but PP in PORTSC needs to - * be 1 for host to work. - * So we set drv_vbus bit in - * transceiver to 0 thru ULPI. - */ - write_ulpi(0x0c, 0x20); - } - } - - otg_dev->host_working = 1; - } - } else { - /* stop fsl usb host controller */ - if (!otg_dev->host_working) - goto end; - else { - VDBG("host off......\n"); - if (dev && dev->driver) { - if (dev->driver->pm && dev->driver->pm->suspend) - retval = dev->driver->pm->suspend(dev); - if (fsm->id) - /* default-b */ - fsl_otg_drv_vbus(0); - } - otg_dev->host_working = 0; - } - } -end: - return retval; -} - -/* - * Call suspend and resume function in udc driver - * to stop and start udc driver. - */ -int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) -{ - struct usb_otg *otg = fsm->otg; - struct device *dev; - - if (!otg->gadget || !otg->gadget->dev.parent) - return -ENODEV; - - VDBG("gadget %s\n", on ? "on" : "off"); - dev = otg->gadget->dev.parent; - - if (on) { - if (dev->driver->resume) - dev->driver->resume(dev); - } else { - if (dev->driver->suspend) - dev->driver->suspend(dev, otg_suspend_state); - } - - return 0; -} - -/* - * Called by initialization code of host driver. Register host controller - * to the OTG. Suspend host for OTG role detection. - */ -static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - otg->host = host; - - otg_dev->fsm.a_bus_drop = 0; - otg_dev->fsm.a_bus_req = 1; - - if (host) { - VDBG("host off......\n"); - - otg->host->otg_port = fsl_otg_initdata.otg_port; - otg->host->is_b_host = otg_dev->fsm.id; - /* - * must leave time for khubd to finish its thing - * before yanking the host driver out from under it, - * so suspend the host after a short delay. - */ - otg_dev->host_working = 1; - schedule_delayed_work(&otg_dev->otg_event, 100); - return 0; - } else { - /* host driver going away */ - if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & - OTGSC_STS_USB_ID)) { - /* Mini-A cable connected */ - struct otg_fsm *fsm = &otg_dev->fsm; - - otg->phy->state = OTG_STATE_UNDEFINED; - fsm->protocol = PROTO_UNDEF; - } - } - - otg_dev->host_working = 0; - - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* Called by initialization code of udc. Register udc to OTG. */ -static int fsl_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - VDBG("otg_dev 0x%x\n", (int)otg_dev); - VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - if (!gadget) { - if (!otg->default_a) - otg->gadget->ops->vbus_draw(otg->gadget, 0); - usb_gadget_vbus_disconnect(otg->gadget); - otg->gadget = 0; - otg_dev->fsm.b_bus_req = 0; - otg_statemachine(&otg_dev->fsm); - return 0; - } - - otg->gadget = gadget; - otg->gadget->is_a_peripheral = !otg_dev->fsm.id; - - otg_dev->fsm.b_bus_req = 1; - - /* start the gadget right away if the ID pin says Mini-B */ - DBG("ID pin=%d\n", otg_dev->fsm.id); - if (otg_dev->fsm.id == 1) { - fsl_otg_start_host(&otg_dev->fsm, 0); - otg_drv_vbus(&otg_dev->fsm, 0); - fsl_otg_start_gadget(&otg_dev->fsm, 1); - } - - return 0; -} - -/* Set OTG port power, only for B-device */ -static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA) -{ - if (!fsl_otg_dev) - return -ENODEV; - if (phy->state == OTG_STATE_B_PERIPHERAL) - pr_info("FSL OTG: Draw %d mA\n", mA); - - return 0; -} - -/* - * Delayed pin detect interrupt processing. - * - * When the Mini-A cable is disconnected from the board, - * the pin-detect interrupt happens before the disconnect - * interrupts for the connected device(s). In order to - * process the disconnect interrupt(s) prior to switching - * roles, the pin-detect interrupts are delayed, and handled - * by this routine. - */ -static void fsl_otg_event(struct work_struct *work) -{ - struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work); - struct otg_fsm *fsm = &og->fsm; - - if (fsm->id) { /* switch to gadget */ - fsl_otg_start_host(fsm, 0); - otg_drv_vbus(fsm, 0); - fsl_otg_start_gadget(fsm, 1); - } -} - -/* B-device start SRP */ -static int fsl_otg_start_srp(struct usb_otg *otg) -{ - struct fsl_otg *otg_dev; - - if (!otg || otg->phy->state != OTG_STATE_B_IDLE) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - otg_dev->fsm.b_bus_req = 1; - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* A_host suspend will call this function to start hnp */ -static int fsl_otg_start_hnp(struct usb_otg *otg) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - DBG("start_hnp...n"); - - /* clear a_bus_req to enter a_suspend state */ - otg_dev->fsm.a_bus_req = 0; - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* - * Interrupt handler. OTG/host/peripheral share the same int line. - * OTG driver clears OTGSC interrupts and leaves USB interrupts - * intact. It needs to have knowledge of some USB interrupts - * such as port change. - */ -irqreturn_t fsl_otg_isr(int irq, void *dev_id) -{ - struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; - struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; - u32 otg_int_src, otg_sc; - - otg_sc = fsl_readl(&usb_dr_regs->otgsc); - otg_int_src = otg_sc & OTGSC_INTSTS_MASK & (otg_sc >> 8); - - /* Only clear otg interrupts */ - fsl_writel(otg_sc, &usb_dr_regs->otgsc); - - /*FIXME: ID change not generate when init to 0 */ - fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; - otg->default_a = (fsm->id == 0); - - /* process OTG interrupts */ - if (otg_int_src) { - if (otg_int_src & OTGSC_INTSTS_USB_ID) { - fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; - otg->default_a = (fsm->id == 0); - /* clear conn information */ - if (fsm->id) - fsm->b_conn = 0; - else - fsm->a_conn = 0; - - if (otg->host) - otg->host->is_b_host = fsm->id; - if (otg->gadget) - otg->gadget->is_a_peripheral = !fsm->id; - VDBG("ID int (ID is %d)\n", fsm->id); - - if (fsm->id) { /* switch to gadget */ - schedule_delayed_work( - &((struct fsl_otg *)dev_id)->otg_event, - 100); - } else { /* switch to host */ - cancel_delayed_work(& - ((struct fsl_otg *)dev_id)-> - otg_event); - fsl_otg_start_gadget(fsm, 0); - otg_drv_vbus(fsm, 1); - fsl_otg_start_host(fsm, 1); - } - return IRQ_HANDLED; - } - } - return IRQ_NONE; -} - -static struct otg_fsm_ops fsl_otg_ops = { - .chrg_vbus = fsl_otg_chrg_vbus, - .drv_vbus = fsl_otg_drv_vbus, - .loc_conn = fsl_otg_loc_conn, - .loc_sof = fsl_otg_loc_sof, - .start_pulse = fsl_otg_start_pulse, - - .add_timer = fsl_otg_add_timer, - .del_timer = fsl_otg_del_timer, - - .start_host = fsl_otg_start_host, - .start_gadget = fsl_otg_start_gadget, -}; - -/* Initialize the global variable fsl_otg_dev and request IRQ for OTG */ -static int fsl_otg_conf(struct platform_device *pdev) -{ - struct fsl_otg *fsl_otg_tc; - int status; - - if (fsl_otg_dev) - return 0; - - /* allocate space to fsl otg device */ - fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); - if (!fsl_otg_tc) - return -ENOMEM; - - fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!fsl_otg_tc->phy.otg) { - kfree(fsl_otg_tc); - return -ENOMEM; - } - - INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); - - INIT_LIST_HEAD(&active_timers); - status = fsl_otg_init_timers(&fsl_otg_tc->fsm); - if (status) { - pr_info("Couldn't init OTG timers\n"); - goto err; - } - spin_lock_init(&fsl_otg_tc->fsm.lock); - - /* Set OTG state machine operations */ - fsl_otg_tc->fsm.ops = &fsl_otg_ops; - - /* initialize the otg structure */ - fsl_otg_tc->phy.label = DRIVER_DESC; - fsl_otg_tc->phy.set_power = fsl_otg_set_power; - - fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; - fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; - fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; - fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; - fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; - - fsl_otg_dev = fsl_otg_tc; - - /* Store the otg transceiver */ - status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); - if (status) { - pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); - goto err; - } - - return 0; -err: - fsl_otg_uninit_timers(); - kfree(fsl_otg_tc->phy.otg); - kfree(fsl_otg_tc); - return status; -} - -/* OTG Initialization */ -int usb_otg_start(struct platform_device *pdev) -{ - struct fsl_otg *p_otg; - struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); - struct otg_fsm *fsm; - int status; - struct resource *res; - u32 temp; - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - p_otg = container_of(otg_trans, struct fsl_otg, phy); - fsm = &p_otg->fsm; - - /* Initialize the state machine structure with default values */ - SET_OTG_STATE(otg_trans, OTG_STATE_UNDEFINED); - fsm->otg = p_otg->phy.otg; - - /* We don't require predefined MEM/IRQ resource index */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENXIO; - - /* We don't request_mem_region here to enable resource sharing - * with host/device */ - - usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); - p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; - pdata->regs = (void *)usb_dr_regs; - - if (pdata->init && pdata->init(pdev) != 0) - return -EINVAL; - - if (pdata->big_endian_mmio) { - _fsl_readl = _fsl_readl_be; - _fsl_writel = _fsl_writel_be; - } else { - _fsl_readl = _fsl_readl_le; - _fsl_writel = _fsl_writel_le; - } - - /* request irq */ - p_otg->irq = platform_get_irq(pdev, 0); - status = request_irq(p_otg->irq, fsl_otg_isr, - IRQF_SHARED, driver_name, p_otg); - if (status) { - dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", - p_otg->irq, status); - iounmap(p_otg->dr_mem_map); - kfree(p_otg->phy.otg); - kfree(p_otg); - return status; - } - - /* stop the controller */ - temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); - temp &= ~USB_CMD_RUN_STOP; - fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); - - /* reset the controller */ - temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); - temp |= USB_CMD_CTRL_RESET; - fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); - - /* wait reset completed */ - while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) - ; - - /* configure the VBUSHS as IDLE(both host and device) */ - temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); - fsl_writel(temp, &p_otg->dr_mem_map->usbmode); - - /* configure PHY interface */ - temp = fsl_readl(&p_otg->dr_mem_map->portsc); - temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); - switch (pdata->phy_mode) { - case FSL_USB2_PHY_ULPI: - temp |= PORTSC_PTS_ULPI; - break; - case FSL_USB2_PHY_UTMI_WIDE: - temp |= PORTSC_PTW_16BIT; - /* fall through */ - case FSL_USB2_PHY_UTMI: - temp |= PORTSC_PTS_UTMI; - /* fall through */ - default: - break; - } - fsl_writel(temp, &p_otg->dr_mem_map->portsc); - - if (pdata->have_sysif_regs) { - /* configure control enable IO output, big endian register */ - temp = __raw_readl(&p_otg->dr_mem_map->control); - temp |= USB_CTRL_IOENB; - __raw_writel(temp, &p_otg->dr_mem_map->control); - } - - /* disable all interrupt and clear all OTGSC status */ - temp = fsl_readl(&p_otg->dr_mem_map->otgsc); - temp &= ~OTGSC_INTERRUPT_ENABLE_BITS_MASK; - temp |= OTGSC_INTERRUPT_STATUS_BITS_MASK | OTGSC_CTRL_VBUS_DISCHARGE; - fsl_writel(temp, &p_otg->dr_mem_map->otgsc); - - /* - * The identification (id) input is FALSE when a Mini-A plug is inserted - * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. - * Also: record initial state of ID pin - */ - if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { - p_otg->phy.state = OTG_STATE_UNDEFINED; - p_otg->fsm.id = 1; - } else { - p_otg->phy.state = OTG_STATE_A_IDLE; - p_otg->fsm.id = 0; - } - - DBG("initial ID pin=%d\n", p_otg->fsm.id); - - /* enable OTG ID pin interrupt */ - temp = fsl_readl(&p_otg->dr_mem_map->otgsc); - temp |= OTGSC_INTR_USB_ID_EN; - temp &= ~(OTGSC_CTRL_VBUS_DISCHARGE | OTGSC_INTR_1MS_TIMER_EN); - fsl_writel(temp, &p_otg->dr_mem_map->otgsc); - - return 0; -} - -/* - * state file in sysfs - */ -static int show_fsl_usb2_otg_state(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct otg_fsm *fsm = &fsl_otg_dev->fsm; - char *next = buf; - unsigned size = PAGE_SIZE; - unsigned long flags; - int t; - - spin_lock_irqsave(&fsm->lock, flags); - - /* basic driver infomation */ - t = scnprintf(next, size, - DRIVER_DESC "\n" "fsl_usb2_otg version: %s\n\n", - DRIVER_VERSION); - size -= t; - next += t; - - /* Registers */ - t = scnprintf(next, size, - "OTGSC: 0x%08x\n" - "PORTSC: 0x%08x\n" - "USBMODE: 0x%08x\n" - "USBCMD: 0x%08x\n" - "USBSTS: 0x%08x\n" - "USBINTR: 0x%08x\n", - fsl_readl(&usb_dr_regs->otgsc), - fsl_readl(&usb_dr_regs->portsc), - fsl_readl(&usb_dr_regs->usbmode), - fsl_readl(&usb_dr_regs->usbcmd), - fsl_readl(&usb_dr_regs->usbsts), - fsl_readl(&usb_dr_regs->usbintr)); - size -= t; - next += t; - - /* State */ - t = scnprintf(next, size, - "OTG state: %s\n\n", - usb_otg_state_string(fsl_otg_dev->phy.state)); - size -= t; - next += t; - - /* State Machine Variables */ - t = scnprintf(next, size, - "a_bus_req: %d\n" - "b_bus_req: %d\n" - "a_bus_resume: %d\n" - "a_bus_suspend: %d\n" - "a_conn: %d\n" - "a_sess_vld: %d\n" - "a_srp_det: %d\n" - "a_vbus_vld: %d\n" - "b_bus_resume: %d\n" - "b_bus_suspend: %d\n" - "b_conn: %d\n" - "b_se0_srp: %d\n" - "b_sess_end: %d\n" - "b_sess_vld: %d\n" - "id: %d\n", - fsm->a_bus_req, - fsm->b_bus_req, - fsm->a_bus_resume, - fsm->a_bus_suspend, - fsm->a_conn, - fsm->a_sess_vld, - fsm->a_srp_det, - fsm->a_vbus_vld, - fsm->b_bus_resume, - fsm->b_bus_suspend, - fsm->b_conn, - fsm->b_se0_srp, - fsm->b_sess_end, - fsm->b_sess_vld, - fsm->id); - size -= t; - next += t; - - spin_unlock_irqrestore(&fsm->lock, flags); - - return PAGE_SIZE - size; -} - -static DEVICE_ATTR(fsl_usb2_otg_state, S_IRUGO, show_fsl_usb2_otg_state, NULL); - - -/* Char driver interface to control some OTG input */ - -/* - * Handle some ioctl command, such as get otg - * status and set host suspend - */ -static long fsl_otg_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - u32 retval = 0; - - switch (cmd) { - case GET_OTG_STATUS: - retval = fsl_otg_dev->host_working; - break; - - case SET_A_SUSPEND_REQ: - fsl_otg_dev->fsm.a_suspend_req = arg; - break; - - case SET_A_BUS_DROP: - fsl_otg_dev->fsm.a_bus_drop = arg; - break; - - case SET_A_BUS_REQ: - fsl_otg_dev->fsm.a_bus_req = arg; - break; - - case SET_B_BUS_REQ: - fsl_otg_dev->fsm.b_bus_req = arg; - break; - - default: - break; - } - - otg_statemachine(&fsl_otg_dev->fsm); - - return retval; -} - -static int fsl_otg_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int fsl_otg_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations otg_fops = { - .owner = THIS_MODULE, - .llseek = NULL, - .read = NULL, - .write = NULL, - .unlocked_ioctl = fsl_otg_ioctl, - .open = fsl_otg_open, - .release = fsl_otg_release, -}; - -static int fsl_otg_probe(struct platform_device *pdev) -{ - int ret; - - if (!pdev->dev.platform_data) - return -ENODEV; - - /* configure the OTG */ - ret = fsl_otg_conf(pdev); - if (ret) { - dev_err(&pdev->dev, "Couldn't configure OTG module\n"); - return ret; - } - - /* start OTG */ - ret = usb_otg_start(pdev); - if (ret) { - dev_err(&pdev->dev, "Can't init FSL OTG device\n"); - return ret; - } - - ret = register_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME, &otg_fops); - if (ret) { - dev_err(&pdev->dev, "unable to register FSL OTG device\n"); - return ret; - } - - ret = device_create_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); - if (ret) - dev_warn(&pdev->dev, "Can't register sysfs attribute\n"); - - return ret; -} - -static int fsl_otg_remove(struct platform_device *pdev) -{ - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - usb_remove_phy(&fsl_otg_dev->phy); - free_irq(fsl_otg_dev->irq, fsl_otg_dev); - - iounmap((void *)usb_dr_regs); - - fsl_otg_uninit_timers(); - kfree(fsl_otg_dev->phy.otg); - kfree(fsl_otg_dev); - - device_remove_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); - - unregister_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME); - - if (pdata->exit) - pdata->exit(pdev); - - return 0; -} - -struct platform_driver fsl_otg_driver = { - .probe = fsl_otg_probe, - .remove = fsl_otg_remove, - .driver = { - .name = driver_name, - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(fsl_otg_driver); - -MODULE_DESCRIPTION(DRIVER_INFO); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/fsl_otg.h b/drivers/usb/otg/fsl_otg.h deleted file mode 100644 index ca266280895d..000000000000 --- a/drivers/usb/otg/fsl_otg.h +++ /dev/null @@ -1,406 +0,0 @@ -/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * 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 "otg_fsm.h" -#include -#include - -/* USB Command Register Bit Masks */ -#define USB_CMD_RUN_STOP (0x1<<0) -#define USB_CMD_CTRL_RESET (0x1<<1) -#define USB_CMD_PERIODIC_SCHEDULE_EN (0x1<<4) -#define USB_CMD_ASYNC_SCHEDULE_EN (0x1<<5) -#define USB_CMD_INT_AA_DOORBELL (0x1<<6) -#define USB_CMD_ASP (0x3<<8) -#define USB_CMD_ASYNC_SCH_PARK_EN (0x1<<11) -#define USB_CMD_SUTW (0x1<<13) -#define USB_CMD_ATDTW (0x1<<14) -#define USB_CMD_ITC (0xFF<<16) - -/* bit 15,3,2 are frame list size */ -#define USB_CMD_FRAME_SIZE_1024 (0x0<<15 | 0x0<<2) -#define USB_CMD_FRAME_SIZE_512 (0x0<<15 | 0x1<<2) -#define USB_CMD_FRAME_SIZE_256 (0x0<<15 | 0x2<<2) -#define USB_CMD_FRAME_SIZE_128 (0x0<<15 | 0x3<<2) -#define USB_CMD_FRAME_SIZE_64 (0x1<<15 | 0x0<<2) -#define USB_CMD_FRAME_SIZE_32 (0x1<<15 | 0x1<<2) -#define USB_CMD_FRAME_SIZE_16 (0x1<<15 | 0x2<<2) -#define USB_CMD_FRAME_SIZE_8 (0x1<<15 | 0x3<<2) - -/* bit 9-8 are async schedule park mode count */ -#define USB_CMD_ASP_00 (0x0<<8) -#define USB_CMD_ASP_01 (0x1<<8) -#define USB_CMD_ASP_10 (0x2<<8) -#define USB_CMD_ASP_11 (0x3<<8) -#define USB_CMD_ASP_BIT_POS (8) - -/* bit 23-16 are interrupt threshold control */ -#define USB_CMD_ITC_NO_THRESHOLD (0x00<<16) -#define USB_CMD_ITC_1_MICRO_FRM (0x01<<16) -#define USB_CMD_ITC_2_MICRO_FRM (0x02<<16) -#define USB_CMD_ITC_4_MICRO_FRM (0x04<<16) -#define USB_CMD_ITC_8_MICRO_FRM (0x08<<16) -#define USB_CMD_ITC_16_MICRO_FRM (0x10<<16) -#define USB_CMD_ITC_32_MICRO_FRM (0x20<<16) -#define USB_CMD_ITC_64_MICRO_FRM (0x40<<16) -#define USB_CMD_ITC_BIT_POS (16) - -/* USB Status Register Bit Masks */ -#define USB_STS_INT (0x1<<0) -#define USB_STS_ERR (0x1<<1) -#define USB_STS_PORT_CHANGE (0x1<<2) -#define USB_STS_FRM_LST_ROLL (0x1<<3) -#define USB_STS_SYS_ERR (0x1<<4) -#define USB_STS_IAA (0x1<<5) -#define USB_STS_RESET_RECEIVED (0x1<<6) -#define USB_STS_SOF (0x1<<7) -#define USB_STS_DCSUSPEND (0x1<<8) -#define USB_STS_HC_HALTED (0x1<<12) -#define USB_STS_RCL (0x1<<13) -#define USB_STS_PERIODIC_SCHEDULE (0x1<<14) -#define USB_STS_ASYNC_SCHEDULE (0x1<<15) - -/* USB Interrupt Enable Register Bit Masks */ -#define USB_INTR_INT_EN (0x1<<0) -#define USB_INTR_ERR_INT_EN (0x1<<1) -#define USB_INTR_PC_DETECT_EN (0x1<<2) -#define USB_INTR_FRM_LST_ROLL_EN (0x1<<3) -#define USB_INTR_SYS_ERR_EN (0x1<<4) -#define USB_INTR_ASYN_ADV_EN (0x1<<5) -#define USB_INTR_RESET_EN (0x1<<6) -#define USB_INTR_SOF_EN (0x1<<7) -#define USB_INTR_DEVICE_SUSPEND (0x1<<8) - -/* Device Address bit masks */ -#define USB_DEVICE_ADDRESS_MASK (0x7F<<25) -#define USB_DEVICE_ADDRESS_BIT_POS (25) -/* PORTSC Register Bit Masks,Only one PORT in OTG mode*/ -#define PORTSC_CURRENT_CONNECT_STATUS (0x1<<0) -#define PORTSC_CONNECT_STATUS_CHANGE (0x1<<1) -#define PORTSC_PORT_ENABLE (0x1<<2) -#define PORTSC_PORT_EN_DIS_CHANGE (0x1<<3) -#define PORTSC_OVER_CURRENT_ACT (0x1<<4) -#define PORTSC_OVER_CUURENT_CHG (0x1<<5) -#define PORTSC_PORT_FORCE_RESUME (0x1<<6) -#define PORTSC_PORT_SUSPEND (0x1<<7) -#define PORTSC_PORT_RESET (0x1<<8) -#define PORTSC_LINE_STATUS_BITS (0x3<<10) -#define PORTSC_PORT_POWER (0x1<<12) -#define PORTSC_PORT_INDICTOR_CTRL (0x3<<14) -#define PORTSC_PORT_TEST_CTRL (0xF<<16) -#define PORTSC_WAKE_ON_CONNECT_EN (0x1<<20) -#define PORTSC_WAKE_ON_CONNECT_DIS (0x1<<21) -#define PORTSC_WAKE_ON_OVER_CURRENT (0x1<<22) -#define PORTSC_PHY_LOW_POWER_SPD (0x1<<23) -#define PORTSC_PORT_FORCE_FULL_SPEED (0x1<<24) -#define PORTSC_PORT_SPEED_MASK (0x3<<26) -#define PORTSC_TRANSCEIVER_WIDTH (0x1<<28) -#define PORTSC_PHY_TYPE_SEL (0x3<<30) -/* bit 11-10 are line status */ -#define PORTSC_LINE_STATUS_SE0 (0x0<<10) -#define PORTSC_LINE_STATUS_JSTATE (0x1<<10) -#define PORTSC_LINE_STATUS_KSTATE (0x2<<10) -#define PORTSC_LINE_STATUS_UNDEF (0x3<<10) -#define PORTSC_LINE_STATUS_BIT_POS (10) - -/* bit 15-14 are port indicator control */ -#define PORTSC_PIC_OFF (0x0<<14) -#define PORTSC_PIC_AMBER (0x1<<14) -#define PORTSC_PIC_GREEN (0x2<<14) -#define PORTSC_PIC_UNDEF (0x3<<14) -#define PORTSC_PIC_BIT_POS (14) - -/* bit 19-16 are port test control */ -#define PORTSC_PTC_DISABLE (0x0<<16) -#define PORTSC_PTC_JSTATE (0x1<<16) -#define PORTSC_PTC_KSTATE (0x2<<16) -#define PORTSC_PTC_SEQNAK (0x3<<16) -#define PORTSC_PTC_PACKET (0x4<<16) -#define PORTSC_PTC_FORCE_EN (0x5<<16) -#define PORTSC_PTC_BIT_POS (16) - -/* bit 27-26 are port speed */ -#define PORTSC_PORT_SPEED_FULL (0x0<<26) -#define PORTSC_PORT_SPEED_LOW (0x1<<26) -#define PORTSC_PORT_SPEED_HIGH (0x2<<26) -#define PORTSC_PORT_SPEED_UNDEF (0x3<<26) -#define PORTSC_SPEED_BIT_POS (26) - -/* bit 28 is parallel transceiver width for UTMI interface */ -#define PORTSC_PTW (0x1<<28) -#define PORTSC_PTW_8BIT (0x0<<28) -#define PORTSC_PTW_16BIT (0x1<<28) - -/* bit 31-30 are port transceiver select */ -#define PORTSC_PTS_UTMI (0x0<<30) -#define PORTSC_PTS_ULPI (0x2<<30) -#define PORTSC_PTS_FSLS_SERIAL (0x3<<30) -#define PORTSC_PTS_BIT_POS (30) - -#define PORTSC_W1C_BITS \ - (PORTSC_CONNECT_STATUS_CHANGE | \ - PORTSC_PORT_EN_DIS_CHANGE | \ - PORTSC_OVER_CUURENT_CHG) - -/* OTG Status Control Register Bit Masks */ -#define OTGSC_CTRL_VBUS_DISCHARGE (0x1<<0) -#define OTGSC_CTRL_VBUS_CHARGE (0x1<<1) -#define OTGSC_CTRL_OTG_TERMINATION (0x1<<3) -#define OTGSC_CTRL_DATA_PULSING (0x1<<4) -#define OTGSC_CTRL_ID_PULL_EN (0x1<<5) -#define OTGSC_HA_DATA_PULSE (0x1<<6) -#define OTGSC_HA_BA (0x1<<7) -#define OTGSC_STS_USB_ID (0x1<<8) -#define OTGSC_STS_A_VBUS_VALID (0x1<<9) -#define OTGSC_STS_A_SESSION_VALID (0x1<<10) -#define OTGSC_STS_B_SESSION_VALID (0x1<<11) -#define OTGSC_STS_B_SESSION_END (0x1<<12) -#define OTGSC_STS_1MS_TOGGLE (0x1<<13) -#define OTGSC_STS_DATA_PULSING (0x1<<14) -#define OTGSC_INTSTS_USB_ID (0x1<<16) -#define OTGSC_INTSTS_A_VBUS_VALID (0x1<<17) -#define OTGSC_INTSTS_A_SESSION_VALID (0x1<<18) -#define OTGSC_INTSTS_B_SESSION_VALID (0x1<<19) -#define OTGSC_INTSTS_B_SESSION_END (0x1<<20) -#define OTGSC_INTSTS_1MS (0x1<<21) -#define OTGSC_INTSTS_DATA_PULSING (0x1<<22) -#define OTGSC_INTR_USB_ID_EN (0x1<<24) -#define OTGSC_INTR_A_VBUS_VALID_EN (0x1<<25) -#define OTGSC_INTR_A_SESSION_VALID_EN (0x1<<26) -#define OTGSC_INTR_B_SESSION_VALID_EN (0x1<<27) -#define OTGSC_INTR_B_SESSION_END_EN (0x1<<28) -#define OTGSC_INTR_1MS_TIMER_EN (0x1<<29) -#define OTGSC_INTR_DATA_PULSING_EN (0x1<<30) -#define OTGSC_INTSTS_MASK (0x00ff0000) - -/* USB MODE Register Bit Masks */ -#define USB_MODE_CTRL_MODE_IDLE (0x0<<0) -#define USB_MODE_CTRL_MODE_DEVICE (0x2<<0) -#define USB_MODE_CTRL_MODE_HOST (0x3<<0) -#define USB_MODE_CTRL_MODE_RSV (0x1<<0) -#define USB_MODE_SETUP_LOCK_OFF (0x1<<3) -#define USB_MODE_STREAM_DISABLE (0x1<<4) -#define USB_MODE_ES (0x1<<2) /* Endian Select */ - -/* control Register Bit Masks */ -#define USB_CTRL_IOENB (0x1<<2) -#define USB_CTRL_ULPI_INT0EN (0x1<<0) - -/* BCSR5 */ -#define BCSR5_INT_USB (0x02) - -/* USB module clk cfg */ -#define SCCR_OFFS (0xA08) -#define SCCR_USB_CLK_DISABLE (0x00000000) /* USB clk disable */ -#define SCCR_USB_MPHCM_11 (0x00c00000) -#define SCCR_USB_MPHCM_01 (0x00400000) -#define SCCR_USB_MPHCM_10 (0x00800000) -#define SCCR_USB_DRCM_11 (0x00300000) -#define SCCR_USB_DRCM_01 (0x00100000) -#define SCCR_USB_DRCM_10 (0x00200000) - -#define SICRL_OFFS (0x114) -#define SICRL_USB0 (0x40000000) -#define SICRL_USB1 (0x20000000) - -#define SICRH_OFFS (0x118) -#define SICRH_USB_UTMI (0x00020000) - -/* OTG interrupt enable bit masks */ -#define OTGSC_INTERRUPT_ENABLE_BITS_MASK \ - (OTGSC_INTR_USB_ID_EN | \ - OTGSC_INTR_1MS_TIMER_EN | \ - OTGSC_INTR_A_VBUS_VALID_EN | \ - OTGSC_INTR_A_SESSION_VALID_EN | \ - OTGSC_INTR_B_SESSION_VALID_EN | \ - OTGSC_INTR_B_SESSION_END_EN | \ - OTGSC_INTR_DATA_PULSING_EN) - -/* OTG interrupt status bit masks */ -#define OTGSC_INTERRUPT_STATUS_BITS_MASK \ - (OTGSC_INTSTS_USB_ID | \ - OTGSC_INTR_1MS_TIMER_EN | \ - OTGSC_INTSTS_A_VBUS_VALID | \ - OTGSC_INTSTS_A_SESSION_VALID | \ - OTGSC_INTSTS_B_SESSION_VALID | \ - OTGSC_INTSTS_B_SESSION_END | \ - OTGSC_INTSTS_DATA_PULSING) - -/* - * A-DEVICE timing constants - */ - -/* Wait for VBUS Rise */ -#define TA_WAIT_VRISE (100) /* a_wait_vrise 100 ms, section: 6.6.5.1 */ - -/* Wait for B-Connect */ -#define TA_WAIT_BCON (10000) /* a_wait_bcon > 1 sec, section: 6.6.5.2 - * This is only used to get out of - * OTG_STATE_A_WAIT_BCON state if there was - * no connection for these many milliseconds - */ - -/* A-Idle to B-Disconnect */ -/* It is necessary for this timer to be more than 750 ms because of a bug in OPT - * test 5.4 in which B OPT disconnects after 750 ms instead of 75ms as stated - * in the test description - */ -#define TA_AIDL_BDIS (5000) /* a_suspend minimum 200 ms, section: 6.6.5.3 */ - -/* B-Idle to A-Disconnect */ -#define TA_BIDL_ADIS (12) /* 3 to 200 ms */ - -/* B-device timing constants */ - - -/* Data-Line Pulse Time*/ -#define TB_DATA_PLS (10) /* b_srp_init,continue 5~10ms, section:5.3.3 */ -#define TB_DATA_PLS_MIN (5) /* minimum 5 ms */ -#define TB_DATA_PLS_MAX (10) /* maximum 10 ms */ - -/* SRP Initiate Time */ -#define TB_SRP_INIT (100) /* b_srp_init,maximum 100 ms, section:5.3.8 */ - -/* SRP Fail Time */ -#define TB_SRP_FAIL (7000) /* b_srp_init,Fail time 5~30s, section:6.8.2.2*/ - -/* SRP result wait time */ -#define TB_SRP_WAIT (60) - -/* VBus time */ -#define TB_VBUS_PLS (30) /* time to keep vbus pulsing asserted */ - -/* Discharge time */ -/* This time should be less than 10ms. It varies from system to system. */ -#define TB_VBUS_DSCHRG (8) - -/* A-SE0 to B-Reset */ -#define TB_ASE0_BRST (20) /* b_wait_acon, mini 3.125 ms,section:6.8.2.4 */ - -/* A bus suspend timer before we can switch to b_wait_aconn */ -#define TB_A_SUSPEND (7) -#define TB_BUS_RESUME (12) - -/* SE0 Time Before SRP */ -#define TB_SE0_SRP (2) /* b_idle,minimum 2 ms, section:5.3.2 */ - -#define SET_OTG_STATE(otg_ptr, newstate) ((otg_ptr)->state = newstate) - -struct usb_dr_mmap { - /* Capability register */ - u8 res1[256]; - u16 caplength; /* Capability Register Length */ - u16 hciversion; /* Host Controller Interface Version */ - u32 hcsparams; /* Host Controller Structual Parameters */ - u32 hccparams; /* Host Controller Capability Parameters */ - u8 res2[20]; - u32 dciversion; /* Device Controller Interface Version */ - u32 dccparams; /* Device Controller Capability Parameters */ - u8 res3[24]; - /* Operation register */ - u32 usbcmd; /* USB Command Register */ - u32 usbsts; /* USB Status Register */ - u32 usbintr; /* USB Interrupt Enable Register */ - u32 frindex; /* Frame Index Register */ - u8 res4[4]; - u32 deviceaddr; /* Device Address */ - u32 endpointlistaddr; /* Endpoint List Address Register */ - u8 res5[4]; - u32 burstsize; /* Master Interface Data Burst Size Register */ - u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ - u8 res6[8]; - u32 ulpiview; /* ULPI register access */ - u8 res7[12]; - u32 configflag; /* Configure Flag Register */ - u32 portsc; /* Port 1 Status and Control Register */ - u8 res8[28]; - u32 otgsc; /* On-The-Go Status and Control */ - u32 usbmode; /* USB Mode Register */ - u32 endptsetupstat; /* Endpoint Setup Status Register */ - u32 endpointprime; /* Endpoint Initialization Register */ - u32 endptflush; /* Endpoint Flush Register */ - u32 endptstatus; /* Endpoint Status Register */ - u32 endptcomplete; /* Endpoint Complete Register */ - u32 endptctrl[6]; /* Endpoint Control Registers */ - u8 res9[552]; - u32 snoop1; - u32 snoop2; - u32 age_cnt_thresh; /* Age Count Threshold Register */ - u32 pri_ctrl; /* Priority Control Register */ - u32 si_ctrl; /* System Interface Control Register */ - u8 res10[236]; - u32 control; /* General Purpose Control Register */ -}; - -struct fsl_otg_timer { - unsigned long expires; /* Number of count increase to timeout */ - unsigned long count; /* Tick counter */ - void (*function)(unsigned long); /* Timeout function */ - unsigned long data; /* Data passed to function */ - struct list_head list; -}; - -inline struct fsl_otg_timer *otg_timer_initializer -(void (*function)(unsigned long), unsigned long expires, unsigned long data) -{ - struct fsl_otg_timer *timer; - - timer = kmalloc(sizeof(struct fsl_otg_timer), GFP_KERNEL); - if (!timer) - return NULL; - timer->function = function; - timer->expires = expires; - timer->data = data; - return timer; -} - -struct fsl_otg { - struct usb_phy phy; - struct otg_fsm fsm; - struct usb_dr_mmap *dr_mem_map; - struct delayed_work otg_event; - - /* used for usb host */ - struct work_struct work_wq; - u8 host_working; - - int irq; -}; - -struct fsl_otg_config { - u8 otg_port; -}; - -/* For SRP and HNP handle */ -#define FSL_OTG_MAJOR 240 -#define FSL_OTG_NAME "fsl-usb2-otg" -/* Command to OTG driver ioctl */ -#define OTG_IOCTL_MAGIC FSL_OTG_MAJOR -/* if otg work as host, it should return 1, otherwise return 0 */ -#define GET_OTG_STATUS _IOR(OTG_IOCTL_MAGIC, 1, int) -#define SET_A_SUSPEND_REQ _IOW(OTG_IOCTL_MAGIC, 2, int) -#define SET_A_BUS_DROP _IOW(OTG_IOCTL_MAGIC, 3, int) -#define SET_A_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 4, int) -#define SET_B_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 5, int) -#define GET_A_SUSPEND_REQ _IOR(OTG_IOCTL_MAGIC, 6, int) -#define GET_A_BUS_DROP _IOR(OTG_IOCTL_MAGIC, 7, int) -#define GET_A_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 8, int) -#define GET_B_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 9, int) - -void fsl_otg_add_timer(void *timer); -void fsl_otg_del_timer(void *timer); -void fsl_otg_pulse_vbus(void); diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c deleted file mode 100644 index a7d4ac591982..000000000000 --- a/drivers/usb/otg/gpio_vbus.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * gpio-vbus.c - simple GPIO VBUS sensing driver for B peripheral devices - * - * Copyright (c) 2008 Philipp Zabel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -/* - * A simple GPIO VBUS sensing driver for B peripheral only devices - * with internal transceivers. It can control a D+ pullup GPIO and - * a regulator to limit the current drawn from VBUS. - * - * Needs to be loaded before the UDC driver that will use it. - */ -struct gpio_vbus_data { - struct usb_phy phy; - struct device *dev; - struct regulator *vbus_draw; - int vbus_draw_enabled; - unsigned mA; - struct delayed_work work; - int vbus; - int irq; -}; - - -/* - * This driver relies on "both edges" triggering. VBUS has 100 msec to - * stabilize, so the peripheral controller driver may need to cope with - * some bouncing due to current surges (e.g. charging local capacitance) - * and contact chatter. - * - * REVISIT in desperate straits, toggling between rising and falling - * edges might be workable. - */ -#define VBUS_IRQ_FLAGS \ - (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) - - -/* interface to regulator framework */ -static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) -{ - struct regulator *vbus_draw = gpio_vbus->vbus_draw; - int enabled; - - if (!vbus_draw) - return; - - enabled = gpio_vbus->vbus_draw_enabled; - if (mA) { - regulator_set_current_limit(vbus_draw, 0, 1000 * mA); - if (!enabled) { - regulator_enable(vbus_draw); - gpio_vbus->vbus_draw_enabled = 1; - } - } else { - if (enabled) { - regulator_disable(vbus_draw); - gpio_vbus->vbus_draw_enabled = 0; - } - } - gpio_vbus->mA = mA; -} - -static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) -{ - int vbus; - - vbus = gpio_get_value(pdata->gpio_vbus); - if (pdata->gpio_vbus_inverted) - vbus = !vbus; - - return vbus; -} - -static void gpio_vbus_work(struct work_struct *work) -{ - struct gpio_vbus_data *gpio_vbus = - container_of(work, struct gpio_vbus_data, work.work); - struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; - int gpio, status, vbus; - - if (!gpio_vbus->phy.otg->gadget) - return; - - vbus = is_vbus_powered(pdata); - if ((vbus ^ gpio_vbus->vbus) == 0) - return; - gpio_vbus->vbus = vbus; - - /* Peripheral controllers which manage the pullup themselves won't have - * gpio_pullup configured here. If it's configured here, we'll do what - * isp1301_omap::b_peripheral() does and enable the pullup here... although - * that may complicate usb_gadget_{,dis}connect() support. - */ - gpio = pdata->gpio_pullup; - - if (vbus) { - status = USB_EVENT_VBUS; - gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; - gpio_vbus->phy.last_event = status; - usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); - - /* drawing a "unit load" is *always* OK, except for OTG */ - set_vbus_draw(gpio_vbus, 100); - - /* optionally enable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, !pdata->gpio_pullup_inverted); - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); - } else { - /* optionally disable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, pdata->gpio_pullup_inverted); - - set_vbus_draw(gpio_vbus, 0); - - usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); - status = USB_EVENT_NONE; - gpio_vbus->phy.state = OTG_STATE_B_IDLE; - gpio_vbus->phy.last_event = status; - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); - } -} - -/* VBUS change IRQ handler */ -static irqreturn_t gpio_vbus_irq(int irq, void *data) -{ - struct platform_device *pdev = data; - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); - struct usb_otg *otg = gpio_vbus->phy.otg; - - dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", - is_vbus_powered(pdata) ? "supplied" : "inactive", - otg->gadget ? otg->gadget->name : "none"); - - if (otg->gadget) - schedule_delayed_work(&gpio_vbus->work, msecs_to_jiffies(100)); - - return IRQ_HANDLED; -} - -/* OTG transceiver interface */ - -/* bind/unbind the peripheral controller */ -static int gpio_vbus_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct gpio_vbus_data *gpio_vbus; - struct gpio_vbus_mach_info *pdata; - struct platform_device *pdev; - int gpio; - - gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); - pdev = to_platform_device(gpio_vbus->dev); - pdata = gpio_vbus->dev->platform_data; - gpio = pdata->gpio_pullup; - - if (!gadget) { - dev_dbg(&pdev->dev, "unregistering gadget '%s'\n", - otg->gadget->name); - - /* optionally disable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, pdata->gpio_pullup_inverted); - - set_vbus_draw(gpio_vbus, 0); - - usb_gadget_vbus_disconnect(otg->gadget); - otg->phy->state = OTG_STATE_UNDEFINED; - - otg->gadget = NULL; - return 0; - } - - otg->gadget = gadget; - dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name); - - /* initialize connection state */ - gpio_vbus->vbus = 0; /* start with disconnected */ - gpio_vbus_irq(gpio_vbus->irq, pdev); - return 0; -} - -/* effective for B devices, ignored for A-peripheral */ -static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) -{ - struct gpio_vbus_data *gpio_vbus; - - gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - - if (phy->state == OTG_STATE_B_PERIPHERAL) - set_vbus_draw(gpio_vbus, mA); - return 0; -} - -/* for non-OTG B devices: set/clear transceiver suspend mode */ -static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) -{ - struct gpio_vbus_data *gpio_vbus; - - gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - - /* draw max 0 mA from vbus in suspend mode; or the previously - * recorded amount of current if not suspended - * - * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA - * if they're wake-enabled ... we don't handle that yet. - */ - return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); -} - -/* platform driver interface */ - -static int __init gpio_vbus_probe(struct platform_device *pdev) -{ - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - struct gpio_vbus_data *gpio_vbus; - struct resource *res; - int err, gpio, irq; - unsigned long irqflags; - - if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) - return -EINVAL; - gpio = pdata->gpio_vbus; - - gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); - if (!gpio_vbus) - return -ENOMEM; - - gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!gpio_vbus->phy.otg) { - kfree(gpio_vbus); - return -ENOMEM; - } - - platform_set_drvdata(pdev, gpio_vbus); - gpio_vbus->dev = &pdev->dev; - gpio_vbus->phy.label = "gpio-vbus"; - gpio_vbus->phy.set_power = gpio_vbus_set_power; - gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; - gpio_vbus->phy.state = OTG_STATE_UNDEFINED; - - gpio_vbus->phy.otg->phy = &gpio_vbus->phy; - gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; - - err = gpio_request(gpio, "vbus_detect"); - if (err) { - dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", - gpio, err); - goto err_gpio; - } - gpio_direction_input(gpio); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) { - irq = res->start; - irqflags = (res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; - } else { - irq = gpio_to_irq(gpio); - irqflags = VBUS_IRQ_FLAGS; - } - - gpio_vbus->irq = irq; - - /* if data line pullup is in use, initialize it to "not pulling up" */ - gpio = pdata->gpio_pullup; - if (gpio_is_valid(gpio)) { - err = gpio_request(gpio, "udc_pullup"); - if (err) { - dev_err(&pdev->dev, - "can't request pullup gpio %d, err: %d\n", - gpio, err); - gpio_free(pdata->gpio_vbus); - goto err_gpio; - } - gpio_direction_output(gpio, pdata->gpio_pullup_inverted); - } - - err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); - if (err) { - dev_err(&pdev->dev, "can't request irq %i, err: %d\n", - irq, err); - goto err_irq; - } - - ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); - - INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); - - gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); - if (IS_ERR(gpio_vbus->vbus_draw)) { - dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", - PTR_ERR(gpio_vbus->vbus_draw)); - gpio_vbus->vbus_draw = NULL; - } - - /* only active when a gadget is registered */ - err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); - goto err_otg; - } - - device_init_wakeup(&pdev->dev, pdata->wakeup); - - return 0; -err_otg: - regulator_put(gpio_vbus->vbus_draw); - free_irq(irq, pdev); -err_irq: - if (gpio_is_valid(pdata->gpio_pullup)) - gpio_free(pdata->gpio_pullup); - gpio_free(pdata->gpio_vbus); -err_gpio: - platform_set_drvdata(pdev, NULL); - kfree(gpio_vbus->phy.otg); - kfree(gpio_vbus); - return err; -} - -static int __exit gpio_vbus_remove(struct platform_device *pdev) -{ - struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - int gpio = pdata->gpio_vbus; - - device_init_wakeup(&pdev->dev, 0); - cancel_delayed_work_sync(&gpio_vbus->work); - regulator_put(gpio_vbus->vbus_draw); - - usb_remove_phy(&gpio_vbus->phy); - - free_irq(gpio_vbus->irq, pdev); - if (gpio_is_valid(pdata->gpio_pullup)) - gpio_free(pdata->gpio_pullup); - gpio_free(gpio); - platform_set_drvdata(pdev, NULL); - kfree(gpio_vbus->phy.otg); - kfree(gpio_vbus); - - return 0; -} - -#ifdef CONFIG_PM -static int gpio_vbus_pm_suspend(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static int gpio_vbus_pm_resume(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { - .suspend = gpio_vbus_pm_suspend, - .resume = gpio_vbus_pm_resume, -}; -#endif - -/* NOTE: the gpio-vbus device may *NOT* be hotplugged */ - -MODULE_ALIAS("platform:gpio-vbus"); - -static struct platform_driver gpio_vbus_driver = { - .driver = { - .name = "gpio-vbus", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &gpio_vbus_dev_pm_ops, -#endif - }, - .remove = __exit_p(gpio_vbus_remove), -}; - -module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe); - -MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); -MODULE_AUTHOR("Philipp Zabel"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c deleted file mode 100644 index 8fe0c3b95261..000000000000 --- a/drivers/usb/otg/isp1301_omap.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller - * - * Copyright (C) 2004 Texas Instruments - * Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#ifndef DEBUG -#undef VERBOSE -#endif - - -#define DRIVER_VERSION "24 August 2004" -#define DRIVER_NAME (isp1301_driver.driver.name) - -MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); -MODULE_LICENSE("GPL"); - -struct isp1301 { - struct usb_phy phy; - struct i2c_client *client; - void (*i2c_release)(struct device *dev); - - int irq_type; - - u32 last_otg_ctrl; - unsigned working:1; - - struct timer_list timer; - - /* use keventd context to change the state for us */ - struct work_struct work; - - unsigned long todo; -# define WORK_UPDATE_ISP 0 /* update ISP from OTG */ -# define WORK_UPDATE_OTG 1 /* update OTG from ISP */ -# define WORK_HOST_RESUME 4 /* resume host */ -# define WORK_TIMER 6 /* timer fired */ -# define WORK_STOP 7 /* don't resubmit */ -}; - - -/* bits in OTG_CTRL */ - -#define OTG_XCEIV_OUTPUTS \ - (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) -#define OTG_XCEIV_INPUTS \ - (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID) -#define OTG_CTRL_BITS \ - (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|OTG_B_HNPEN|OTG_BUSDROP) - /* and OTG_PULLUP is sometimes written */ - -#define OTG_CTRL_MASK (OTG_DRIVER_SEL| \ - OTG_XCEIV_OUTPUTS|OTG_XCEIV_INPUTS| \ - OTG_CTRL_BITS) - - -/*-------------------------------------------------------------------------*/ - -/* board-specific PM hooks */ - -#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) - -#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) - -#include - -#else - -static inline int tps65010_set_vbus_draw(unsigned mA) -{ - pr_debug("tps65010: draw %d mA (STUB)\n", mA); - return 0; -} - -#endif - -static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) -{ - int status = tps65010_set_vbus_draw(mA); - if (status < 0) - pr_debug(" VBUS %d mA error %d\n", mA, status); -} - -#else - -static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) -{ - /* H4 controls this by DIP switch S2.4; no soft control. - * ON means the charger is always enabled. Leave it OFF - * unless the OTG port is used only in B-peripheral mode. - */ -} - -#endif - -static void enable_vbus_source(struct isp1301 *isp) -{ - /* this board won't supply more than 8mA vbus power. - * some boards can switch a 100ma "unit load" (or more). - */ -} - - -/* products will deliver OTG messages with LEDs, GUI, etc */ -static inline void notresponding(struct isp1301 *isp) -{ - printk(KERN_NOTICE "OTG device not responding.\n"); -} - - -/*-------------------------------------------------------------------------*/ - -static struct i2c_driver isp1301_driver; - -/* smbus apis are used for portability */ - -static inline u8 -isp1301_get_u8(struct isp1301 *isp, u8 reg) -{ - return i2c_smbus_read_byte_data(isp->client, reg + 0); -} - -static inline int -isp1301_get_u16(struct isp1301 *isp, u8 reg) -{ - return i2c_smbus_read_word_data(isp->client, reg); -} - -static inline int -isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) -{ - return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); -} - -static inline int -isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) -{ - return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); -} - -/*-------------------------------------------------------------------------*/ - -/* identification */ -#define ISP1301_VENDOR_ID 0x00 /* u16 read */ -#define ISP1301_PRODUCT_ID 0x02 /* u16 read */ -#define ISP1301_BCD_DEVICE 0x14 /* u16 read */ - -#define I2C_VENDOR_ID_PHILIPS 0x04cc -#define I2C_PRODUCT_ID_PHILIPS_1301 0x1301 - -/* operational registers */ -#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ -# define MC1_SPEED (1 << 0) -# define MC1_SUSPEND (1 << 1) -# define MC1_DAT_SE0 (1 << 2) -# define MC1_TRANSPARENT (1 << 3) -# define MC1_BDIS_ACON_EN (1 << 4) -# define MC1_OE_INT_EN (1 << 5) -# define MC1_UART_EN (1 << 6) -# define MC1_MASK 0x7f -#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ -# define MC2_GLOBAL_PWR_DN (1 << 0) -# define MC2_SPD_SUSP_CTRL (1 << 1) -# define MC2_BI_DI (1 << 2) -# define MC2_TRANSP_BDIR0 (1 << 3) -# define MC2_TRANSP_BDIR1 (1 << 4) -# define MC2_AUDIO_EN (1 << 5) -# define MC2_PSW_EN (1 << 6) -# define MC2_EN2V7 (1 << 7) -#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ -# define OTG1_DP_PULLUP (1 << 0) -# define OTG1_DM_PULLUP (1 << 1) -# define OTG1_DP_PULLDOWN (1 << 2) -# define OTG1_DM_PULLDOWN (1 << 3) -# define OTG1_ID_PULLDOWN (1 << 4) -# define OTG1_VBUS_DRV (1 << 5) -# define OTG1_VBUS_DISCHRG (1 << 6) -# define OTG1_VBUS_CHRG (1 << 7) -#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ -# define OTG_B_SESS_END (1 << 6) -# define OTG_B_SESS_VLD (1 << 7) - -#define ISP1301_INTERRUPT_SOURCE 0x08 /* u8 read */ -#define ISP1301_INTERRUPT_LATCH 0x0A /* u8 read, set, +1 clear */ - -#define ISP1301_INTERRUPT_FALLING 0x0C /* u8 read, set, +1 clear */ -#define ISP1301_INTERRUPT_RISING 0x0E /* u8 read, set, +1 clear */ - -/* same bitfields in all interrupt registers */ -# define INTR_VBUS_VLD (1 << 0) -# define INTR_SESS_VLD (1 << 1) -# define INTR_DP_HI (1 << 2) -# define INTR_ID_GND (1 << 3) -# define INTR_DM_HI (1 << 4) -# define INTR_ID_FLOAT (1 << 5) -# define INTR_BDIS_ACON (1 << 6) -# define INTR_CR_INT (1 << 7) - -/*-------------------------------------------------------------------------*/ - -static inline const char *state_name(struct isp1301 *isp) -{ - return usb_otg_state_string(isp->phy.state); -} - -/*-------------------------------------------------------------------------*/ - -/* NOTE: some of this ISP1301 setup is specific to H2 boards; - * not everything is guarded by board-specific checks, or even using - * omap_usb_config data to deduce MC1_DAT_SE0 and MC2_BI_DI. - * - * ALSO: this currently doesn't use ISP1301 low-power modes - * while OTG is running. - */ - -static void power_down(struct isp1301 *isp) -{ - isp->phy.state = OTG_STATE_UNDEFINED; - - // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); - - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); -} - -static void power_up(struct isp1301 *isp) -{ - // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); - - /* do this only when cpu is driving transceiver, - * so host won't see a low speed device... - */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); -} - -#define NO_HOST_SUSPEND - -static int host_suspend(struct isp1301 *isp) -{ -#ifdef NO_HOST_SUSPEND - return 0; -#else - struct device *dev; - - if (!isp->phy.otg->host) - return -ENODEV; - - /* Currently ASSUMES only the OTG port matters; - * other ports could be active... - */ - dev = isp->phy.otg->host->controller; - return dev->driver->suspend(dev, 3, 0); -#endif -} - -static int host_resume(struct isp1301 *isp) -{ -#ifdef NO_HOST_SUSPEND - return 0; -#else - struct device *dev; - - if (!isp->phy.otg->host) - return -ENODEV; - - dev = isp->phy.otg->host->controller; - return dev->driver->resume(dev, 0); -#endif -} - -static int gadget_suspend(struct isp1301 *isp) -{ - isp->phy.otg->gadget->b_hnp_enable = 0; - isp->phy.otg->gadget->a_hnp_support = 0; - isp->phy.otg->gadget->a_alt_hnp_support = 0; - return usb_gadget_vbus_disconnect(isp->phy.otg->gadget); -} - -/*-------------------------------------------------------------------------*/ - -#define TIMER_MINUTES 10 -#define TIMER_JIFFIES (TIMER_MINUTES * 60 * HZ) - -/* Almost all our I2C messaging comes from a work queue's task context. - * NOTE: guaranteeing certain response times might mean we shouldn't - * share keventd's work queue; a realtime task might be safest. - */ -static void isp1301_defer_work(struct isp1301 *isp, int work) -{ - int status; - - if (isp && !test_and_set_bit(work, &isp->todo)) { - (void) get_device(&isp->client->dev); - status = schedule_work(&isp->work); - if (!status && !isp->working) - dev_vdbg(&isp->client->dev, - "work item %d may be lost\n", work); - } -} - -/* called from irq handlers */ -static void a_idle(struct isp1301 *isp, const char *tag) -{ - u32 l; - - if (isp->phy.state == OTG_STATE_A_IDLE) - return; - - isp->phy.otg->default_a = 1; - if (isp->phy.otg->host) { - isp->phy.otg->host->is_b_host = 0; - host_suspend(isp); - } - if (isp->phy.otg->gadget) { - isp->phy.otg->gadget->is_a_peripheral = 1; - gadget_suspend(isp); - } - isp->phy.state = OTG_STATE_A_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; - pr_debug(" --> %s/%s\n", state_name(isp), tag); -} - -/* called from irq handlers */ -static void b_idle(struct isp1301 *isp, const char *tag) -{ - u32 l; - - if (isp->phy.state == OTG_STATE_B_IDLE) - return; - - isp->phy.otg->default_a = 0; - if (isp->phy.otg->host) { - isp->phy.otg->host->is_b_host = 1; - host_suspend(isp); - } - if (isp->phy.otg->gadget) { - isp->phy.otg->gadget->is_a_peripheral = 0; - gadget_suspend(isp); - } - isp->phy.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; - pr_debug(" --> %s/%s\n", state_name(isp), tag); -} - -static void -dump_regs(struct isp1301 *isp, const char *label) -{ -#ifdef DEBUG - u8 ctrl = isp1301_get_u8(isp, ISP1301_OTG_CONTROL_1); - u8 status = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); - - pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", - omap_readl(OTG_CTRL), label, state_name(isp), - ctrl, status, src); - /* mode control and irq enables don't change much */ -#endif -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_USB_OTG - -/* - * The OMAP OTG controller handles most of the OTG state transitions. - * - * We translate isp1301 outputs (mostly voltage comparator status) into - * OTG inputs; OTG outputs (mostly pullup/pulldown controls) and HNP state - * flags into isp1301 inputs ... and infer state transitions. - */ - -#ifdef VERBOSE - -static void check_state(struct isp1301 *isp, const char *tag) -{ - enum usb_otg_state state = OTG_STATE_UNDEFINED; - u8 fsm = omap_readw(OTG_TEST) & 0x0ff; - unsigned extra = 0; - - switch (fsm) { - - /* default-b */ - case 0x0: - state = OTG_STATE_B_IDLE; - break; - case 0x3: - case 0x7: - extra = 1; - case 0x1: - state = OTG_STATE_B_PERIPHERAL; - break; - case 0x11: - state = OTG_STATE_B_SRP_INIT; - break; - - /* extra dual-role default-b states */ - case 0x12: - case 0x13: - case 0x16: - extra = 1; - case 0x17: - state = OTG_STATE_B_WAIT_ACON; - break; - case 0x34: - state = OTG_STATE_B_HOST; - break; - - /* default-a */ - case 0x36: - state = OTG_STATE_A_IDLE; - break; - case 0x3c: - state = OTG_STATE_A_WAIT_VFALL; - break; - case 0x7d: - state = OTG_STATE_A_VBUS_ERR; - break; - case 0x9e: - case 0x9f: - extra = 1; - case 0x89: - state = OTG_STATE_A_PERIPHERAL; - break; - case 0xb7: - state = OTG_STATE_A_WAIT_VRISE; - break; - case 0xb8: - state = OTG_STATE_A_WAIT_BCON; - break; - case 0xb9: - state = OTG_STATE_A_HOST; - break; - case 0xba: - state = OTG_STATE_A_SUSPEND; - break; - default: - break; - } - if (isp->phy.state == state && !extra) - return; - pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - usb_otg_state_string(state), fsm, state_name(isp), - omap_readl(OTG_CTRL)); -} - -#else - -static inline void check_state(struct isp1301 *isp, const char *tag) { } - -#endif - -/* outputs from ISP1301_INTERRUPT_SOURCE */ -static void update_otg1(struct isp1301 *isp, u8 int_src) -{ - u32 otg_ctrl; - - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); - - if (int_src & INTR_SESS_VLD) - otg_ctrl |= OTG_ASESSVLD; - else if (isp->phy.state == OTG_STATE_A_WAIT_VFALL) { - a_idle(isp, "vfall"); - otg_ctrl &= ~OTG_CTRL_BITS; - } - if (int_src & INTR_VBUS_VLD) - otg_ctrl |= OTG_VBUSVLD; - if (int_src & INTR_ID_GND) { /* default-A */ - if (isp->phy.state == OTG_STATE_B_IDLE - || isp->phy.state - == OTG_STATE_UNDEFINED) { - a_idle(isp, "init"); - return; - } - } else { /* default-B */ - otg_ctrl |= OTG_ID; - if (isp->phy.state == OTG_STATE_A_IDLE - || isp->phy.state == OTG_STATE_UNDEFINED) { - b_idle(isp, "init"); - return; - } - } - omap_writel(otg_ctrl, OTG_CTRL); -} - -/* outputs from ISP1301_OTG_STATUS */ -static void update_otg2(struct isp1301 *isp, u8 otg_status) -{ - u32 otg_ctrl; - - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); - if (otg_status & OTG_B_SESS_VLD) - otg_ctrl |= OTG_BSESSVLD; - else if (otg_status & OTG_B_SESS_END) - otg_ctrl |= OTG_BSESSEND; - omap_writel(otg_ctrl, OTG_CTRL); -} - -/* inputs going to ISP1301 */ -static void otg_update_isp(struct isp1301 *isp) -{ - u32 otg_ctrl, otg_change; - u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; - - otg_ctrl = omap_readl(OTG_CTRL); - otg_change = otg_ctrl ^ isp->last_otg_ctrl; - isp->last_otg_ctrl = otg_ctrl; - otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; - - switch (isp->phy.state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_SRP_INIT: - if (!(otg_ctrl & OTG_PULLUP)) { - // if (otg_ctrl & OTG_B_HNPEN) { - if (isp->phy.otg->gadget->b_hnp_enable) { - isp->phy.state = OTG_STATE_B_WAIT_ACON; - pr_debug(" --> b_wait_acon\n"); - } - goto pulldown; - } -pullup: - set |= OTG1_DP_PULLUP; - clr |= OTG1_DP_PULLDOWN; - break; - case OTG_STATE_A_SUSPEND: - case OTG_STATE_A_PERIPHERAL: - if (otg_ctrl & OTG_PULLUP) - goto pullup; - /* FALLTHROUGH */ - // case OTG_STATE_B_WAIT_ACON: - default: -pulldown: - set |= OTG1_DP_PULLDOWN; - clr |= OTG1_DP_PULLUP; - break; - } - -# define toggle(OTG,ISP) do { \ - if (otg_ctrl & OTG) set |= ISP; \ - else clr |= ISP; \ - } while (0) - - if (!(isp->phy.otg->host)) - otg_ctrl &= ~OTG_DRV_VBUS; - - switch (isp->phy.state) { - case OTG_STATE_A_SUSPEND: - if (otg_ctrl & OTG_DRV_VBUS) { - set |= OTG1_VBUS_DRV; - break; - } - /* HNP failed for some reason (A_AIDL_BDIS timeout) */ - notresponding(isp); - - /* FALLTHROUGH */ - case OTG_STATE_A_VBUS_ERR: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - pr_debug(" --> a_wait_vfall\n"); - /* FALLTHROUGH */ - case OTG_STATE_A_WAIT_VFALL: - /* FIXME usbcore thinks port power is still on ... */ - clr |= OTG1_VBUS_DRV; - break; - case OTG_STATE_A_IDLE: - if (otg_ctrl & OTG_DRV_VBUS) { - isp->phy.state = OTG_STATE_A_WAIT_VRISE; - pr_debug(" --> a_wait_vrise\n"); - } - /* FALLTHROUGH */ - default: - toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); - } - - toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); - toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); - -# undef toggle - - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); - - /* HNP switch to host or peripheral; and SRP */ - if (otg_change & OTG_PULLUP) { - u32 l; - - switch (isp->phy.state) { - case OTG_STATE_B_IDLE: - if (clr & OTG1_DP_PULLUP) - break; - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - break; - case OTG_STATE_A_SUSPEND: - if (clr & OTG1_DP_PULLUP) - break; - isp->phy.state = OTG_STATE_A_PERIPHERAL; - pr_debug(" --> a_peripheral\n"); - break; - default: - break; - } - l = omap_readl(OTG_CTRL); - l |= OTG_PULLUP; - omap_writel(l, OTG_CTRL); - } - - check_state(isp, __func__); - dump_regs(isp, "otg->isp1301"); -} - -static irqreturn_t omap_otg_irq(int irq, void *_isp) -{ - u16 otg_irq = omap_readw(OTG_IRQ_SRC); - u32 otg_ctrl; - int ret = IRQ_NONE; - struct isp1301 *isp = _isp; - struct usb_otg *otg = isp->phy.otg; - - /* update ISP1301 transceiver from OTG controller */ - if (otg_irq & OPRT_CHG) { - omap_writew(OPRT_CHG, OTG_IRQ_SRC); - isp1301_defer_work(isp, WORK_UPDATE_ISP); - ret = IRQ_HANDLED; - - /* SRP to become b_peripheral failed */ - } else if (otg_irq & B_SRP_TMROUT) { - pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); - notresponding(isp); - - /* gadget drivers that care should monitor all kinds of - * remote wakeup (SRP, normal) using their own timer - * to give "check cable and A-device" messages. - */ - if (isp->phy.state == OTG_STATE_B_SRP_INIT) - b_idle(isp, "srp_timeout"); - - omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* HNP to become b_host failed */ - } else if (otg_irq & B_HNP_FAIL) { - pr_debug("otg: %s B_HNP_FAIL, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); - notresponding(isp); - - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - - /* subset of b_peripheral()... */ - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - - omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* detect SRP from B-device ... */ - } else if (otg_irq & A_SRP_DETECT) { - pr_debug("otg: %s SRP_DETECT, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); - - isp1301_defer_work(isp, WORK_UPDATE_OTG); - switch (isp->phy.state) { - case OTG_STATE_A_IDLE: - if (!otg->host) - break; - isp1301_defer_work(isp, WORK_HOST_RESUME); - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_A_BUSREQ; - otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) - & ~OTG_XCEIV_INPUTS - & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - break; - default: - break; - } - - omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) - * we don't track them separately - */ - } else if (otg_irq & A_REQ_TMROUT) { - otg_ctrl = omap_readl(OTG_CTRL); - pr_info("otg: BCON_TMOUT from %s, %06x\n", - state_name(isp), otg_ctrl); - notresponding(isp); - - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - - omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* A-supplied voltage fell too low; overcurrent */ - } else if (otg_irq & A_VBUS_ERR) { - otg_ctrl = omap_readl(OTG_CTRL); - printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", - state_name(isp), otg_irq, otg_ctrl); - - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_VBUS_ERR; - - omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* switch driver; the transceiver code activates it, - * ungating the udc clock or resuming OHCI. - */ - } else if (otg_irq & DRIVER_SWITCH) { - int kick = 0; - - otg_ctrl = omap_readl(OTG_CTRL); - printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", - state_name(isp), - (otg_ctrl & OTG_DRIVER_SEL) - ? "gadget" : "host", - otg_ctrl); - isp1301_defer_work(isp, WORK_UPDATE_ISP); - - /* role is peripheral */ - if (otg_ctrl & OTG_DRIVER_SEL) { - switch (isp->phy.state) { - case OTG_STATE_A_IDLE: - b_idle(isp, __func__); - break; - default: - break; - } - isp1301_defer_work(isp, WORK_UPDATE_ISP); - - /* role is host */ - } else { - if (!(otg_ctrl & OTG_ID)) { - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); - } - - if (otg->host) { - switch (isp->phy.state) { - case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; - pr_debug(" --> b_host\n"); - kick = 1; - break; - case OTG_STATE_A_WAIT_BCON: - isp->phy.state = OTG_STATE_A_HOST; - pr_debug(" --> a_host\n"); - break; - case OTG_STATE_A_PERIPHERAL: - isp->phy.state = OTG_STATE_A_WAIT_BCON; - pr_debug(" --> a_wait_bcon\n"); - break; - default: - break; - } - isp1301_defer_work(isp, WORK_HOST_RESUME); - } - } - - omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - if (kick) - usb_bus_start_enum(otg->host, otg->host->otg_port); - } - - check_state(isp, __func__); - return ret; -} - -static struct platform_device *otg_dev; - -static int isp1301_otg_init(struct isp1301 *isp) -{ - u32 l; - - if (!otg_dev) - return -ENODEV; - - dump_regs(isp, __func__); - /* some of these values are board-specific... */ - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN - /* for B-device: */ - | SRP_GPDATA /* 9msec Bdev D+ pulse */ - | SRP_GPDVBUS /* discharge after VBUS pulse */ - // | (3 << 24) /* 2msec VBUS pulse */ - /* for A-device: */ - | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */ - | SRP_DPW /* detect 167+ns SRP pulses */ - | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ - ; - omap_writel(l, OTG_SYSCON_2); - - update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); - update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); - - check_state(isp, __func__); - pr_debug("otg: %s, %s %06x\n", - state_name(isp), __func__, omap_readl(OTG_CTRL)); - - omap_writew(DRIVER_SWITCH | OPRT_CHG - | B_SRP_TMROUT | B_HNP_FAIL - | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); - - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN; - omap_writel(l, OTG_SYSCON_2); - - return 0; -} - -static int otg_probe(struct platform_device *dev) -{ - // struct omap_usb_config *config = dev->platform_data; - - otg_dev = dev; - return 0; -} - -static int otg_remove(struct platform_device *dev) -{ - otg_dev = NULL; - return 0; -} - -static struct platform_driver omap_otg_driver = { - .probe = otg_probe, - .remove = otg_remove, - .driver = { - .owner = THIS_MODULE, - .name = "omap_otg", - }, -}; - -static int otg_bind(struct isp1301 *isp) -{ - int status; - - if (otg_dev) - return -EBUSY; - - status = platform_driver_register(&omap_otg_driver); - if (status < 0) - return status; - - if (otg_dev) - status = request_irq(otg_dev->resource[1].start, omap_otg_irq, - 0, DRIVER_NAME, isp); - else - status = -ENODEV; - - if (status < 0) - platform_driver_unregister(&omap_otg_driver); - return status; -} - -static void otg_unbind(struct isp1301 *isp) -{ - if (!otg_dev) - return; - free_irq(otg_dev->resource[1].start, isp); -} - -#else - -/* OTG controller isn't clocked */ - -#endif /* CONFIG_USB_OTG */ - -/*-------------------------------------------------------------------------*/ - -static void b_peripheral(struct isp1301 *isp) -{ - u32 l; - - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - - usb_gadget_vbus_connect(isp->phy.otg->gadget); - -#ifdef CONFIG_USB_OTG - enable_vbus_draw(isp, 8); - otg_update_isp(isp); -#else - enable_vbus_draw(isp, 100); - /* UDC driver just set OTG_BSESSVLD */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - dump_regs(isp, "2periph"); -#endif -} - -static void isp_update_otg(struct isp1301 *isp, u8 stat) -{ - struct usb_otg *otg = isp->phy.otg; - u8 isp_stat, isp_bstat; - enum usb_otg_state state = isp->phy.state; - - if (stat & INTR_BDIS_ACON) - pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); - - /* start certain state transitions right away */ - isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); - if (isp_stat & INTR_ID_GND) { - if (otg->default_a) { - switch (state) { - case OTG_STATE_B_IDLE: - a_idle(isp, "idle"); - /* FALLTHROUGH */ - case OTG_STATE_A_IDLE: - enable_vbus_source(isp); - /* FALLTHROUGH */ - case OTG_STATE_A_WAIT_VRISE: - /* we skip over OTG_STATE_A_WAIT_BCON, since - * the HC will transition to A_HOST (or - * A_SUSPEND!) without our noticing except - * when HNP is used. - */ - if (isp_stat & INTR_VBUS_VLD) - isp->phy.state = OTG_STATE_A_HOST; - break; - case OTG_STATE_A_WAIT_VFALL: - if (!(isp_stat & INTR_SESS_VLD)) - a_idle(isp, "vfell"); - break; - default: - if (!(isp_stat & INTR_VBUS_VLD)) - isp->phy.state = OTG_STATE_A_VBUS_ERR; - break; - } - isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - } else { - switch (state) { - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_HOST: - case OTG_STATE_B_WAIT_ACON: - usb_gadget_vbus_disconnect(otg->gadget); - break; - default: - break; - } - if (state != OTG_STATE_A_IDLE) - a_idle(isp, "id"); - if (otg->host && state == OTG_STATE_A_IDLE) - isp1301_defer_work(isp, WORK_HOST_RESUME); - isp_bstat = 0; - } - } else { - u32 l; - - /* if user unplugged mini-A end of cable, - * don't bypass A_WAIT_VFALL. - */ - if (otg->default_a) { - switch (state) { - default: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - break; - case OTG_STATE_A_WAIT_VFALL: - state = OTG_STATE_A_IDLE; - /* khubd may take a while to notice and - * handle this disconnect, so don't go - * to B_IDLE quite yet. - */ - break; - case OTG_STATE_A_IDLE: - host_suspend(isp); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_BDIS_ACON_EN); - isp->phy.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~OTG_CTRL_BITS; - omap_writel(l, OTG_CTRL); - break; - case OTG_STATE_B_IDLE: - break; - } - } - isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - - switch (isp->phy.state) { - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_WAIT_ACON: - case OTG_STATE_B_HOST: - if (likely(isp_bstat & OTG_B_SESS_VLD)) - break; - enable_vbus_draw(isp, 0); -#ifndef CONFIG_USB_OTG - /* UDC driver will clear OTG_BSESSVLD */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DP_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DP_PULLUP); - dump_regs(isp, __func__); -#endif - /* FALLTHROUGH */ - case OTG_STATE_B_SRP_INIT: - b_idle(isp, __func__); - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - /* FALLTHROUGH */ - case OTG_STATE_B_IDLE: - if (otg->gadget && (isp_bstat & OTG_B_SESS_VLD)) { -#ifdef CONFIG_USB_OTG - update_otg1(isp, isp_stat); - update_otg2(isp, isp_bstat); -#endif - b_peripheral(isp); - } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) - isp_bstat |= OTG_B_SESS_END; - break; - case OTG_STATE_A_WAIT_VFALL: - break; - default: - pr_debug("otg: unsupported b-device %s\n", - state_name(isp)); - break; - } - } - - if (state != isp->phy.state) - pr_debug(" isp, %s -> %s\n", - usb_otg_state_string(state), state_name(isp)); - -#ifdef CONFIG_USB_OTG - /* update the OTG controller state to match the isp1301; may - * trigger OPRT_CHG irqs for changes going to the isp1301. - */ - update_otg1(isp, isp_stat); - update_otg2(isp, isp_bstat); - check_state(isp, __func__); -#endif - - dump_regs(isp, "isp1301->otg"); -} - -/*-------------------------------------------------------------------------*/ - -static u8 isp1301_clear_latch(struct isp1301 *isp) -{ - u8 latch = isp1301_get_u8(isp, ISP1301_INTERRUPT_LATCH); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, latch); - return latch; -} - -static void -isp1301_work(struct work_struct *work) -{ - struct isp1301 *isp = container_of(work, struct isp1301, work); - int stop; - - /* implicit lock: we're the only task using this device */ - isp->working = 1; - do { - stop = test_bit(WORK_STOP, &isp->todo); - -#ifdef CONFIG_USB_OTG - /* transfer state from otg engine to isp1301 */ - if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { - otg_update_isp(isp); - put_device(&isp->client->dev); - } -#endif - /* transfer state from isp1301 to otg engine */ - if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { - u8 stat = isp1301_clear_latch(isp); - - isp_update_otg(isp, stat); - put_device(&isp->client->dev); - } - - if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { - u32 otg_ctrl; - - /* - * skip A_WAIT_VRISE; hc transitions invisibly - * skip A_WAIT_BCON; same. - */ - switch (isp->phy.state) { - case OTG_STATE_A_WAIT_BCON: - case OTG_STATE_A_WAIT_VRISE: - isp->phy.state = OTG_STATE_A_HOST; - pr_debug(" --> a_host\n"); - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_A_BUSREQ; - otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) - & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - break; - case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; - pr_debug(" --> b_host (acon)\n"); - break; - case OTG_STATE_B_HOST: - case OTG_STATE_B_IDLE: - case OTG_STATE_A_IDLE: - break; - default: - pr_debug(" host resume in %s\n", - state_name(isp)); - } - host_resume(isp); - // mdelay(10); - put_device(&isp->client->dev); - } - - if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { -#ifdef VERBOSE - dump_regs(isp, "timer"); - if (!stop) - mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); -#endif - put_device(&isp->client->dev); - } - - if (isp->todo) - dev_vdbg(&isp->client->dev, - "work done, todo = 0x%lx\n", - isp->todo); - if (stop) { - dev_dbg(&isp->client->dev, "stop\n"); - break; - } - } while (isp->todo); - isp->working = 0; -} - -static irqreturn_t isp1301_irq(int irq, void *isp) -{ - isp1301_defer_work(isp, WORK_UPDATE_OTG); - return IRQ_HANDLED; -} - -static void isp1301_timer(unsigned long _isp) -{ - isp1301_defer_work((void *)_isp, WORK_TIMER); -} - -/*-------------------------------------------------------------------------*/ - -static void isp1301_release(struct device *dev) -{ - struct isp1301 *isp; - - isp = dev_get_drvdata(dev); - - /* FIXME -- not with a "new style" driver, it doesn't!! */ - - /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ - if (isp->i2c_release) - isp->i2c_release(dev); - kfree(isp->phy.otg); - kfree (isp); -} - -static struct isp1301 *the_transceiver; - -static int __exit isp1301_remove(struct i2c_client *i2c) -{ - struct isp1301 *isp; - - isp = i2c_get_clientdata(i2c); - - isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - free_irq(i2c->irq, isp); -#ifdef CONFIG_USB_OTG - otg_unbind(isp); -#endif - if (machine_is_omap_h2()) - gpio_free(2); - - isp->timer.data = 0; - set_bit(WORK_STOP, &isp->todo); - del_timer_sync(&isp->timer); - flush_work(&isp->work); - - put_device(&i2c->dev); - the_transceiver = NULL; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* NOTE: three modes are possible here, only one of which - * will be standards-conformant on any given system: - * - * - OTG mode (dual-role), required if there's a Mini-AB connector - * - HOST mode, for when there's one or more A (host) connectors - * - DEVICE mode, for when there's a B/Mini-B (device) connector - * - * As a rule, you won't have an isp1301 chip unless it's there to - * support the OTG mode. Other modes help testing USB controllers - * in isolation from (full) OTG support, or maybe so later board - * revisions can help to support those feature. - */ - -#ifdef CONFIG_USB_OTG - -static int isp1301_otg_enable(struct isp1301 *isp) -{ - power_up(isp); - isp1301_otg_init(isp); - - /* NOTE: since we don't change this, this provides - * a few more interrupts than are strictly needed. - */ - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); - - dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); - - return 0; -} - -#endif - -/* add or disable the host device+driver */ -static int -isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - - if (!otg || isp != the_transceiver) - return -ENODEV; - - if (!host) { - omap_writew(0, OTG_IRQ_EN); - power_down(isp); - otg->host = NULL; - return 0; - } - -#ifdef CONFIG_USB_OTG - otg->host = host; - dev_dbg(&isp->client->dev, "registered host\n"); - host_suspend(isp); - if (otg->gadget) - return isp1301_otg_enable(isp); - return 0; - -#elif !defined(CONFIG_USB_GADGET_OMAP) - // FIXME update its refcount - otg->host = host; - - power_up(isp); - - if (machine_is_omap_h2()) - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); - - dev_info(&isp->client->dev, "A-Host sessions ok\n"); - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_ID_GND); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_ID_GND); - - /* If this has a Mini-AB connector, this mode is highly - * nonstandard ... but can be handy for testing, especially with - * the Mini-A end of an OTG cable. (Or something nonstandard - * like MiniB-to-StandardB, maybe built with a gender mender.) - */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); - - dump_regs(isp, __func__); - - return 0; - -#else - dev_dbg(&isp->client->dev, "host sessions not allowed\n"); - return -EINVAL; -#endif - -} - -static int -isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - - if (!otg || isp != the_transceiver) - return -ENODEV; - - if (!gadget) { - omap_writew(0, OTG_IRQ_EN); - if (!otg->default_a) - enable_vbus_draw(isp, 0); - usb_gadget_vbus_disconnect(otg->gadget); - otg->gadget = NULL; - power_down(isp); - return 0; - } - -#ifdef CONFIG_USB_OTG - otg->gadget = gadget; - dev_dbg(&isp->client->dev, "registered gadget\n"); - /* gadget driver may be suspended until vbus_connect () */ - if (otg->host) - return isp1301_otg_enable(isp); - return 0; - -#elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) - otg->gadget = gadget; - // FIXME update its refcount - - { - u32 l; - - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); - l |= OTG_ID; - omap_writel(l, OTG_CTRL); - } - - power_up(isp); - isp->phy.state = OTG_STATE_B_IDLE; - - if (machine_is_omap_h2() || machine_is_omap_h3()) - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); - - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_SESS_VLD); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD); - dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); - dump_regs(isp, __func__); - - /* If this has a Mini-AB connector, this mode is highly - * nonstandard ... but can be handy for testing, so long - * as you don't plug a Mini-A cable into the jack. - */ - if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) - b_peripheral(isp); - - return 0; - -#else - dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); - return -EINVAL; -#endif -} - - -/*-------------------------------------------------------------------------*/ - -static int -isp1301_set_power(struct usb_phy *dev, unsigned mA) -{ - if (!the_transceiver) - return -ENODEV; - if (dev->state == OTG_STATE_B_PERIPHERAL) - enable_vbus_draw(the_transceiver, mA); - return 0; -} - -static int -isp1301_start_srp(struct usb_otg *otg) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - u32 otg_ctrl; - - if (!otg || isp != the_transceiver - || isp->phy.state != OTG_STATE_B_IDLE) - return -ENODEV; - - otg_ctrl = omap_readl(OTG_CTRL); - if (!(otg_ctrl & OTG_BSESSEND)) - return -EINVAL; - - otg_ctrl |= OTG_B_BUSREQ; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_B_SRP_INIT; - - pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), - omap_readl(OTG_CTRL)); -#ifdef CONFIG_USB_OTG - check_state(isp, __func__); -#endif - return 0; -} - -static int -isp1301_start_hnp(struct usb_otg *otg) -{ -#ifdef CONFIG_USB_OTG - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - u32 l; - - if (!otg || isp != the_transceiver) - return -ENODEV; - if (otg->default_a && (otg->host == NULL || !otg->host->b_hnp_enable)) - return -ENOTCONN; - if (!otg->default_a && (otg->gadget == NULL - || !otg->gadget->b_hnp_enable)) - return -ENOTCONN; - - /* We want hardware to manage most HNP protocol timings. - * So do this part as early as possible... - */ - switch (isp->phy.state) { - case OTG_STATE_B_HOST: - isp->phy.state = OTG_STATE_B_PERIPHERAL; - /* caller will suspend next */ - break; - case OTG_STATE_A_HOST: -#if 0 - /* autoconnect mode avoids irq latency bugs */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_BDIS_ACON_EN); -#endif - /* caller must suspend then clear A_BUSREQ */ - usb_gadget_vbus_connect(otg->gadget); - l = omap_readl(OTG_CTRL); - l |= OTG_A_SETB_HNPEN; - omap_writel(l, OTG_CTRL); - - break; - case OTG_STATE_A_PERIPHERAL: - /* initiated by B-Host suspend */ - break; - default: - return -EILSEQ; - } - pr_debug("otg: HNP %s, %06x ...\n", - state_name(isp), omap_readl(OTG_CTRL)); - check_state(isp, __func__); - return 0; -#else - /* srp-only */ - return -EINVAL; -#endif -} - -/*-------------------------------------------------------------------------*/ - -static int -isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) -{ - int status; - struct isp1301 *isp; - - if (the_transceiver) - return 0; - - isp = kzalloc(sizeof *isp, GFP_KERNEL); - if (!isp) - return 0; - - isp->phy.otg = kzalloc(sizeof *isp->phy.otg, GFP_KERNEL); - if (!isp->phy.otg) { - kfree(isp); - return 0; - } - - INIT_WORK(&isp->work, isp1301_work); - init_timer(&isp->timer); - isp->timer.function = isp1301_timer; - isp->timer.data = (unsigned long) isp; - - i2c_set_clientdata(i2c, isp); - isp->client = i2c; - - /* verify the chip (shouldn't be necessary) */ - status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); - if (status != I2C_VENDOR_ID_PHILIPS) { - dev_dbg(&i2c->dev, "not philips id: %d\n", status); - goto fail; - } - status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); - if (status != I2C_PRODUCT_ID_PHILIPS_1301) { - dev_dbg(&i2c->dev, "not isp1301, %d\n", status); - goto fail; - } - isp->i2c_release = i2c->dev.release; - i2c->dev.release = isp1301_release; - - /* initial development used chiprev 2.00 */ - status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); - dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", - status >> 8, status & 0xff); - - /* make like power-on reset */ - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); - - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); - - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, - ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); - - isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - -#ifdef CONFIG_USB_OTG - status = otg_bind(isp); - if (status < 0) { - dev_dbg(&i2c->dev, "can't bind OTG\n"); - goto fail; - } -#endif - - if (machine_is_omap_h2()) { - /* full speed signaling by default */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_SPEED); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, - MC2_SPD_SUSP_CTRL); - - /* IRQ wired at M14 */ - omap_cfg_reg(M14_1510_GPIO2); - if (gpio_request(2, "isp1301") == 0) - gpio_direction_input(2); - isp->irq_type = IRQF_TRIGGER_FALLING; - } - - status = request_irq(i2c->irq, isp1301_irq, - isp->irq_type, DRIVER_NAME, isp); - if (status < 0) { - dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", - i2c->irq, status); - goto fail; - } - - isp->phy.dev = &i2c->dev; - isp->phy.label = DRIVER_NAME; - isp->phy.set_power = isp1301_set_power, - - isp->phy.otg->phy = &isp->phy; - isp->phy.otg->set_host = isp1301_set_host, - isp->phy.otg->set_peripheral = isp1301_set_peripheral, - isp->phy.otg->start_srp = isp1301_start_srp, - isp->phy.otg->start_hnp = isp1301_start_hnp, - - enable_vbus_draw(isp, 0); - power_down(isp); - the_transceiver = isp; - -#ifdef CONFIG_USB_OTG - update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); - update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); -#endif - - dump_regs(isp, __func__); - -#ifdef VERBOSE - mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); - dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); -#endif - - status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); - if (status < 0) - dev_err(&i2c->dev, "can't register transceiver, %d\n", - status); - - return 0; - -fail: - kfree(isp->phy.otg); - kfree(isp); - return -ENODEV; -} - -static const struct i2c_device_id isp1301_id[] = { - { "isp1301_omap", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, isp1301_id); - -static struct i2c_driver isp1301_driver = { - .driver = { - .name = "isp1301_omap", - }, - .probe = isp1301_probe, - .remove = __exit_p(isp1301_remove), - .id_table = isp1301_id, -}; - -/*-------------------------------------------------------------------------*/ - -static int __init isp_init(void) -{ - return i2c_add_driver(&isp1301_driver); -} -subsys_initcall(isp_init); - -static void __exit isp_exit(void) -{ - if (the_transceiver) - usb_remove_phy(&the_transceiver->phy); - i2c_del_driver(&isp1301_driver); -} -module_exit(isp_exit); - diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c deleted file mode 100644 index 749fbf41fb6f..000000000000 --- a/drivers/usb/otg/msm_otg.c +++ /dev/null @@ -1,1762 +0,0 @@ -/* Copyright (c) 2009-2011, 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 -#include -#include -#include - -#include - -#define MSM_USB_BASE (motg->regs) -#define DRIVER_NAME "msm_otg" - -#define ULPI_IO_TIMEOUT_USEC (10 * 1000) - -#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ -#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ -#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */ -#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */ -#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */ -#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ -#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ -#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ - -static struct regulator *hsusb_3p3; -static struct regulator *hsusb_1p8; -static struct regulator *hsusb_vddcx; - -static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) -{ - int ret = 0; - - if (init) { - hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); - if (IS_ERR(hsusb_vddcx)) { - dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); - return PTR_ERR(hsusb_vddcx); - } - - ret = regulator_set_voltage(hsusb_vddcx, - USB_PHY_VDD_DIG_VOL_MIN, - USB_PHY_VDD_DIG_VOL_MAX); - if (ret) { - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); - regulator_put(hsusb_vddcx); - return ret; - } - - ret = regulator_enable(hsusb_vddcx); - if (ret) { - dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - regulator_put(hsusb_vddcx); - } - } else { - ret = regulator_set_voltage(hsusb_vddcx, 0, - USB_PHY_VDD_DIG_VOL_MAX); - if (ret) - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); - ret = regulator_disable(hsusb_vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - - regulator_put(hsusb_vddcx); - } - - return ret; -} - -static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) -{ - int rc = 0; - - if (init) { - hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); - if (IS_ERR(hsusb_3p3)) { - dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); - return PTR_ERR(hsusb_3p3); - } - - rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, - USB_PHY_3P3_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 3p3\n"); - goto put_3p3; - } - rc = regulator_enable(hsusb_3p3); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); - goto put_3p3; - } - hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); - if (IS_ERR(hsusb_1p8)) { - dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); - rc = PTR_ERR(hsusb_1p8); - goto disable_3p3; - } - rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, - USB_PHY_1P8_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 1p8\n"); - goto put_1p8; - } - rc = regulator_enable(hsusb_1p8); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); - goto put_1p8; - } - - return 0; - } - - regulator_disable(hsusb_1p8); -put_1p8: - regulator_put(hsusb_1p8); -disable_3p3: - regulator_disable(hsusb_3p3); -put_3p3: - regulator_put(hsusb_3p3); - return rc; -} - -#ifdef CONFIG_PM_SLEEP -#define USB_PHY_SUSP_DIG_VOL 500000 -static int msm_hsusb_config_vddcx(int high) -{ - int max_vol = USB_PHY_VDD_DIG_VOL_MAX; - int min_vol; - int ret; - - if (high) - min_vol = USB_PHY_VDD_DIG_VOL_MIN; - else - min_vol = USB_PHY_SUSP_DIG_VOL; - - ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); - if (ret) { - pr_err("%s: unable to set the voltage for regulator " - "HSUSB_VDDCX\n", __func__); - return ret; - } - - pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); - - return ret; -} -#endif - -static int msm_hsusb_ldo_set_mode(int on) -{ - int ret = 0; - - if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { - pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); - return -ENODEV; - } - - if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { - pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); - return -ENODEV; - } - - if (on) { - ret = regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_HPM_LOAD); - if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_1p8\n", __func__); - return ret; - } - ret = regulator_set_optimum_mode(hsusb_3p3, - USB_PHY_3P3_HPM_LOAD); - if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_3p3\n", __func__); - regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_LPM_LOAD); - return ret; - } - } else { - ret = regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_LPM_LOAD); - if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_1p8\n", __func__); - ret = regulator_set_optimum_mode(hsusb_3p3, - USB_PHY_3P3_LPM_LOAD); - if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_3p3\n", __func__); - } - - pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); - return ret < 0 ? ret : 0; -} - -static int ulpi_read(struct usb_phy *phy, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate read operation */ - writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_read: timeout %08x\n", - readl(USB_ULPI_VIEWPORT)); - return -ETIMEDOUT; - } - return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); -} - -static int ulpi_write(struct usb_phy *phy, u32 val, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate write operation */ - writel(ULPI_RUN | ULPI_WRITE | - ULPI_ADDR(reg) | ULPI_DATA(val), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_write: timeout\n"); - return -ETIMEDOUT; - } - return 0; -} - -static struct usb_phy_io_ops msm_otg_io_ops = { - .read = ulpi_read, - .write = ulpi_write, -}; - -static void ulpi_init(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - int *seq = pdata->phy_init_seq; - - if (!seq) - return; - - while (seq[0] >= 0) { - dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", - seq[0], seq[1]); - ulpi_write(&motg->phy, seq[0], seq[1]); - seq += 2; - } -} - -static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) -{ - int ret; - - if (assert) { - ret = clk_reset(motg->clk, CLK_RESET_ASSERT); - if (ret) - dev_err(motg->phy.dev, "usb hs_clk assert failed\n"); - } else { - ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->phy.dev, "usb hs_clk deassert failed\n"); - } - return ret; -} - -static int msm_otg_phy_clk_reset(struct msm_otg *motg) -{ - int ret; - - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); - if (ret) { - dev_err(motg->phy.dev, "usb phy clk assert failed\n"); - return ret; - } - usleep_range(10000, 12000); - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->phy.dev, "usb phy clk deassert failed\n"); - return ret; -} - -static int msm_otg_phy_reset(struct msm_otg *motg) -{ - u32 val; - int ret; - int retries; - - ret = msm_otg_link_clk_reset(motg, 1); - if (ret) - return ret; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - ret = msm_otg_link_clk_reset(motg, 0); - if (ret) - return ret; - - val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_ULPI, USB_PORTSC); - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, - ULPI_CLR(ULPI_FUNC_CTRL)); - if (!ret) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - /* This reset calibrates the phy, if the above write succeeded */ - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_read(&motg->phy, ULPI_DEBUG); - if (ret != -ETIMEDOUT) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - dev_info(motg->phy.dev, "phy_reset: success\n"); - return 0; -} - -#define LINK_RESET_TIMEOUT_USEC (250 * 1000) -static int msm_otg_reset(struct usb_phy *phy) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - int ret; - u32 val = 0; - u32 ulpi_val = 0; - - ret = msm_otg_phy_reset(motg); - if (ret) { - dev_err(phy->dev, "phy_reset failed\n"); - return ret; - } - - ulpi_init(motg); - - writel(USBCMD_RESET, USB_USBCMD); - while (cnt < LINK_RESET_TIMEOUT_USEC) { - if (!(readl(USB_USBCMD) & USBCMD_RESET)) - break; - udelay(1); - cnt++; - } - if (cnt >= LINK_RESET_TIMEOUT_USEC) - return -ETIMEDOUT; - - /* select ULPI phy */ - writel(0x80000000, USB_PORTSC); - - msleep(100); - - writel(0x0, USB_AHBBURST); - writel(0x00, USB_AHBMODE); - - if (pdata->otg_control == OTG_PHY_CONTROL) { - val = readl(USB_OTGSC); - if (pdata->mode == USB_OTG) { - ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; - val |= OTGSC_IDIE | OTGSC_BSVIE; - } else if (pdata->mode == USB_PERIPHERAL) { - ulpi_val = ULPI_INT_SESS_VALID; - val |= OTGSC_BSVIE; - } - writel(val, USB_OTGSC); - ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_RISE); - ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); - } - - return 0; -} - -#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) -#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_suspend(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - struct usb_bus *bus = phy->otg->host; - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - - if (atomic_read(&motg->in_lpm)) - return 0; - - disable_irq(motg->irq); - /* - * Chipidea 45-nm PHY suspend sequence: - * - * Interrupt Latch Register auto-clear feature is not present - * in all PHY versions. Latch register is clear on read type. - * Clear latch register to avoid spurious wakeup from - * low power mode (LPM). - * - * PHY comparators are disabled when PHY enters into low power - * mode (LPM). Keep PHY comparators ON in LPM only when we expect - * VBUS/Id notifications from USB PHY. Otherwise turn off USB - * PHY comparators. This save significant amount of power. - * - * PLL is not turned off when PHY enters into low power mode (LPM). - * Disable PLL for maximum power savings. - */ - - if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) { - ulpi_read(phy, 0x14); - if (pdata->otg_control == OTG_PHY_CONTROL) - ulpi_write(phy, 0x01, 0x30); - ulpi_write(phy, 0x08, 0x09); - } - - /* - * PHY may take some time or even fail to enter into low power - * mode (LPM). Hence poll for 500 msec and reset the PHY and link - * in failure case. - */ - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { - dev_err(phy->dev, "Unable to suspend PHY\n"); - msm_otg_reset(phy); - enable_irq(motg->irq); - return -ETIMEDOUT; - } - - /* - * PHY has capability to generate interrupt asynchronously in low - * power mode (LPM). This interrupt is level triggered. So USB IRQ - * line must be disabled till async interrupt enable bit is cleared - * in USBCMD register. Assert STP (ULPI interface STOP signal) to - * block data communication from PHY. - */ - writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) - writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - - if (!IS_ERR(motg->pclk_src)) - clk_disable(motg->pclk_src); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(0); - msm_hsusb_config_vddcx(0); - } - - if (device_may_wakeup(phy->dev)) - enable_irq_wake(motg->irq); - if (bus) - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - atomic_set(&motg->in_lpm, 1); - enable_irq(motg->irq); - - dev_info(phy->dev, "USB in low power mode\n"); - - return 0; -} - -static int msm_otg_resume(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - struct usb_bus *bus = phy->otg->host; - int cnt = 0; - unsigned temp; - - if (!atomic_read(&motg->in_lpm)) - return 0; - - if (!IS_ERR(motg->pclk_src)) - clk_enable(motg->pclk_src); - - clk_enable(motg->pclk); - clk_enable(motg->clk); - if (motg->core_clk) - clk_enable(motg->core_clk); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(1); - msm_hsusb_config_vddcx(1); - writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); - } - - temp = readl(USB_USBCMD); - temp &= ~ASYNC_INTR_CTRL; - temp &= ~ULPI_STP_CTRL; - writel(temp, USB_USBCMD); - - /* - * PHY comes out of low power mode (LPM) in case of wakeup - * from asynchronous interrupt. - */ - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - goto skip_phy_resume; - - writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_RESUME_TIMEOUT_USEC) { - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_RESUME_TIMEOUT_USEC) { - /* - * This is a fatal error. Reset the link and - * PHY. USB state can not be restored. Re-insertion - * of USB cable is the only way to get USB working. - */ - dev_err(phy->dev, "Unable to resume USB." - "Re-plugin the cable\n"); - msm_otg_reset(phy); - } - -skip_phy_resume: - if (device_may_wakeup(phy->dev)) - disable_irq_wake(motg->irq); - if (bus) - set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - atomic_set(&motg->in_lpm, 0); - - if (motg->async_int) { - motg->async_int = 0; - pm_runtime_put(phy->dev); - enable_irq(motg->irq); - } - - dev_info(phy->dev, "USB exited from low power mode\n"); - - return 0; -} -#endif - -static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA) -{ - if (motg->cur_power == mA) - return; - - /* TODO: Notify PMIC about available current */ - dev_info(motg->phy.dev, "Avail curr from USB = %u\n", mA); - motg->cur_power = mA; -} - -static int msm_otg_set_power(struct usb_phy *phy, unsigned mA) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - - /* - * Gadget driver uses set_power method to notify about the - * available current based on suspend/configured states. - * - * IDEV_CHG can be drawn irrespective of suspend/un-configured - * states when CDP/ACA is connected. - */ - if (motg->chg_type == USB_SDP_CHARGER) - msm_otg_notify_charger(motg, mA); - - return 0; -} - -static void msm_otg_start_host(struct usb_phy *phy, int on) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - struct usb_hcd *hcd; - - if (!phy->otg->host) - return; - - hcd = bus_to_hcd(phy->otg->host); - - if (on) { - dev_dbg(phy->dev, "host on\n"); - - if (pdata->vbus_power) - pdata->vbus_power(1); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Enable internal - * HUB before kicking the host. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_A_HOST); -#ifdef CONFIG_USB - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); -#endif - } else { - dev_dbg(phy->dev, "host off\n"); - -#ifdef CONFIG_USB - usb_remove_hcd(hcd); -#endif - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - if (pdata->vbus_power) - pdata->vbus_power(0); - } -} - -static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); - struct usb_hcd *hcd; - - /* - * Fail host registration if this board can support - * only peripheral configuration. - */ - if (motg->pdata->mode == USB_PERIPHERAL) { - dev_info(otg->phy->dev, "Host mode is not supported\n"); - return -ENODEV; - } - - if (!host) { - if (otg->phy->state == OTG_STATE_A_HOST) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_host(otg->phy, 0); - otg->host = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->host = NULL; - } - - return 0; - } - - hcd = bus_to_hcd(host); - hcd->power_budget = motg->pdata->power_budget; - - otg->host = host; - dev_dbg(otg->phy->dev, "host driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if peripheral is not supported - * or peripheral is already registered with us. - */ - if (motg->pdata->mode == USB_HOST || otg->gadget) { - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -static void msm_otg_start_peripheral(struct usb_phy *phy, int on) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - - if (!phy->otg->gadget) - return; - - if (on) { - dev_dbg(phy->dev, "gadget on\n"); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Disable internal - * HUB before kicking the gadget. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); - usb_gadget_vbus_connect(phy->otg->gadget); - } else { - dev_dbg(phy->dev, "gadget off\n"); - usb_gadget_vbus_disconnect(phy->otg->gadget); - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - } - -} - -static int msm_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); - - /* - * Fail peripheral registration if this board can support - * only host configuration. - */ - if (motg->pdata->mode == USB_HOST) { - dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); - return -ENODEV; - } - - if (!gadget) { - if (otg->phy->state == OTG_STATE_B_PERIPHERAL) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_peripheral(otg->phy, 0); - otg->gadget = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->gadget = NULL; - } - - return 0; - } - otg->gadget = gadget; - dev_dbg(otg->phy->dev, "peripheral driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if host is not supported - * or host is already registered with us. - */ - if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -static bool msm_chg_check_secondary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - ret = chg_det & (1 << 4); - break; - case SNPS_28NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x87); - ret = chg_det & 1; - break; - default: - break; - } - return ret; -} - -static void msm_chg_enable_secondary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn off charger block */ - chg_det |= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - /* control chg block via ULPI */ - chg_det &= ~(1 << 3); - ulpi_write(phy, chg_det, 0x34); - /* put it in host mode for enabling D- source */ - chg_det &= ~(1 << 2); - ulpi_write(phy, chg_det, 0x34); - /* Turn on chg detect block */ - chg_det &= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - /* enable chg detection */ - chg_det &= ~(1 << 0); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* - * Configure DM as current source, DP as current sink - * and enable battery charging comparators. - */ - ulpi_write(phy, 0x8, 0x85); - ulpi_write(phy, 0x2, 0x85); - ulpi_write(phy, 0x1, 0x85); - break; - default: - break; - } -} - -static bool msm_chg_check_primary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - ret = chg_det & (1 << 4); - break; - case SNPS_28NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x87); - ret = chg_det & 1; - break; - default: - break; - } - return ret; -} - -static void msm_chg_enable_primary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* enable chg detection */ - chg_det &= ~(1 << 0); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* - * Configure DP as current source, DM as current sink - * and enable battery charging comparators. - */ - ulpi_write(phy, 0x2, 0x85); - ulpi_write(phy, 0x1, 0x85); - break; - default: - break; - } -} - -static bool msm_chg_check_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 line_state; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - line_state = ulpi_read(phy, 0x15); - ret = !(line_state & 1); - break; - case SNPS_28NM_INTEGRATED_PHY: - line_state = ulpi_read(phy, 0x87); - ret = line_state & 2; - break; - default: - break; - } - return ret; -} - -static void msm_chg_disable_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - chg_det &= ~(1 << 5); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - ulpi_write(phy, 0x10, 0x86); - break; - default: - break; - } -} - -static void msm_chg_enable_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn on D+ current source */ - chg_det |= (1 << 5); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Data contact detection enable */ - ulpi_write(phy, 0x10, 0x85); - break; - default: - break; - } -} - -static void msm_chg_block_on(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 func_ctrl, chg_det; - - /* put the controller in non-driving mode */ - func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); - func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; - func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* control chg block via ULPI */ - chg_det &= ~(1 << 3); - ulpi_write(phy, chg_det, 0x34); - /* Turn on chg detect block */ - chg_det &= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Clear charger detecting control bits */ - ulpi_write(phy, 0x3F, 0x86); - /* Clear alt interrupt latch and enable bits */ - ulpi_write(phy, 0x1F, 0x92); - ulpi_write(phy, 0x1F, 0x95); - udelay(100); - break; - default: - break; - } -} - -static void msm_chg_block_off(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 func_ctrl, chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn off charger block */ - chg_det |= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Clear charger detecting control bits */ - ulpi_write(phy, 0x3F, 0x86); - /* Clear alt interrupt latch and enable bits */ - ulpi_write(phy, 0x1F, 0x92); - ulpi_write(phy, 0x1F, 0x95); - break; - default: - break; - } - - /* put the controller in normal mode */ - func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); - func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; - func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; - ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); -} - -#define MSM_CHG_DCD_POLL_TIME (100 * HZ/1000) /* 100 msec */ -#define MSM_CHG_DCD_MAX_RETRIES 6 /* Tdcd_tmout = 6 * 100 msec */ -#define MSM_CHG_PRIMARY_DET_TIME (40 * HZ/1000) /* TVDPSRC_ON */ -#define MSM_CHG_SECONDARY_DET_TIME (40 * HZ/1000) /* TVDMSRC_ON */ -static void msm_chg_detect_work(struct work_struct *w) -{ - struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work); - struct usb_phy *phy = &motg->phy; - bool is_dcd, tmout, vout; - unsigned long delay; - - dev_dbg(phy->dev, "chg detection work\n"); - switch (motg->chg_state) { - case USB_CHG_STATE_UNDEFINED: - pm_runtime_get_sync(phy->dev); - msm_chg_block_on(motg); - msm_chg_enable_dcd(motg); - motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; - motg->dcd_retries = 0; - delay = MSM_CHG_DCD_POLL_TIME; - break; - case USB_CHG_STATE_WAIT_FOR_DCD: - is_dcd = msm_chg_check_dcd(motg); - tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES; - if (is_dcd || tmout) { - msm_chg_disable_dcd(motg); - msm_chg_enable_primary_det(motg); - delay = MSM_CHG_PRIMARY_DET_TIME; - motg->chg_state = USB_CHG_STATE_DCD_DONE; - } else { - delay = MSM_CHG_DCD_POLL_TIME; - } - break; - case USB_CHG_STATE_DCD_DONE: - vout = msm_chg_check_primary_det(motg); - if (vout) { - msm_chg_enable_secondary_det(motg); - delay = MSM_CHG_SECONDARY_DET_TIME; - motg->chg_state = USB_CHG_STATE_PRIMARY_DONE; - } else { - motg->chg_type = USB_SDP_CHARGER; - motg->chg_state = USB_CHG_STATE_DETECTED; - delay = 0; - } - break; - case USB_CHG_STATE_PRIMARY_DONE: - vout = msm_chg_check_secondary_det(motg); - if (vout) - motg->chg_type = USB_DCP_CHARGER; - else - motg->chg_type = USB_CDP_CHARGER; - motg->chg_state = USB_CHG_STATE_SECONDARY_DONE; - /* fall through */ - case USB_CHG_STATE_SECONDARY_DONE: - motg->chg_state = USB_CHG_STATE_DETECTED; - case USB_CHG_STATE_DETECTED: - msm_chg_block_off(motg); - dev_dbg(phy->dev, "charger = %d\n", motg->chg_type); - schedule_work(&motg->sm_work); - return; - default: - return; - } - - schedule_delayed_work(&motg->chg_work, delay); -} - -/* - * We support OTG, Peripheral only and Host only configurations. In case - * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen - * via Id pin status or user request (debugfs). Id/BSV interrupts are not - * enabled when switch is controlled by user and default mode is supplied - * by board file, which can be changed by userspace later. - */ -static void msm_otg_init_sm(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - u32 otgsc = readl(USB_OTGSC); - - switch (pdata->mode) { - case USB_OTG: - if (pdata->otg_control == OTG_PHY_CONTROL) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - } else if (pdata->otg_control == OTG_USER_CONTROL) { - if (pdata->default_mode == USB_HOST) { - clear_bit(ID, &motg->inputs); - } else if (pdata->default_mode == USB_PERIPHERAL) { - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - } else { - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - } - } - break; - case USB_HOST: - clear_bit(ID, &motg->inputs); - break; - case USB_PERIPHERAL: - set_bit(ID, &motg->inputs); - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - break; - } -} - -static void msm_otg_sm_work(struct work_struct *w) -{ - struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); - struct usb_otg *otg = motg->phy.otg; - - switch (otg->phy->state) { - case OTG_STATE_UNDEFINED: - dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); - msm_otg_reset(otg->phy); - msm_otg_init_sm(motg); - otg->phy->state = OTG_STATE_B_IDLE; - /* FALL THROUGH */ - case OTG_STATE_B_IDLE: - dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); - if (!test_bit(ID, &motg->inputs) && otg->host) { - /* disable BSV bit */ - writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); - msm_otg_start_host(otg->phy, 1); - otg->phy->state = OTG_STATE_A_HOST; - } else if (test_bit(B_SESS_VLD, &motg->inputs)) { - switch (motg->chg_state) { - case USB_CHG_STATE_UNDEFINED: - msm_chg_detect_work(&motg->chg_work.work); - break; - case USB_CHG_STATE_DETECTED: - switch (motg->chg_type) { - case USB_DCP_CHARGER: - msm_otg_notify_charger(motg, - IDEV_CHG_MAX); - break; - case USB_CDP_CHARGER: - msm_otg_notify_charger(motg, - IDEV_CHG_MAX); - msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state - = OTG_STATE_B_PERIPHERAL; - break; - case USB_SDP_CHARGER: - msm_otg_notify_charger(motg, IUNIT); - msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state - = OTG_STATE_B_PERIPHERAL; - break; - default: - break; - } - break; - default: - break; - } - } else { - /* - * If charger detection work is pending, decrement - * the pm usage counter to balance with the one that - * is incremented in charger detection work. - */ - if (cancel_delayed_work_sync(&motg->chg_work)) { - pm_runtime_put_sync(otg->phy->dev); - msm_otg_reset(otg->phy); - } - msm_otg_notify_charger(motg, 0); - motg->chg_state = USB_CHG_STATE_UNDEFINED; - motg->chg_type = USB_INVALID_CHARGER; - } - pm_runtime_put_sync(otg->phy->dev); - break; - case OTG_STATE_B_PERIPHERAL: - dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); - if (!test_bit(B_SESS_VLD, &motg->inputs) || - !test_bit(ID, &motg->inputs)) { - msm_otg_notify_charger(motg, 0); - msm_otg_start_peripheral(otg->phy, 0); - motg->chg_state = USB_CHG_STATE_UNDEFINED; - motg->chg_type = USB_INVALID_CHARGER; - otg->phy->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); - schedule_work(w); - } - break; - case OTG_STATE_A_HOST: - dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); - if (test_bit(ID, &motg->inputs)) { - msm_otg_start_host(otg->phy, 0); - otg->phy->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); - schedule_work(w); - } - break; - default: - break; - } -} - -static irqreturn_t msm_otg_irq(int irq, void *data) -{ - struct msm_otg *motg = data; - struct usb_phy *phy = &motg->phy; - u32 otgsc = 0; - - if (atomic_read(&motg->in_lpm)) { - disable_irq_nosync(irq); - motg->async_int = 1; - pm_runtime_get(phy->dev); - return IRQ_HANDLED; - } - - otgsc = readl(USB_OTGSC); - if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) - return IRQ_NONE; - - if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - dev_dbg(phy->dev, "ID set/clear\n"); - pm_runtime_get_noresume(phy->dev); - } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - dev_dbg(phy->dev, "BSV set/clear\n"); - pm_runtime_get_noresume(phy->dev); - } - - writel(otgsc, USB_OTGSC); - schedule_work(&motg->sm_work); - return IRQ_HANDLED; -} - -static int msm_otg_mode_show(struct seq_file *s, void *unused) -{ - struct msm_otg *motg = s->private; - struct usb_otg *otg = motg->phy.otg; - - switch (otg->phy->state) { - case OTG_STATE_A_HOST: - seq_printf(s, "host\n"); - break; - case OTG_STATE_B_PERIPHERAL: - seq_printf(s, "peripheral\n"); - break; - default: - seq_printf(s, "none\n"); - break; - } - - return 0; -} - -static int msm_otg_mode_open(struct inode *inode, struct file *file) -{ - return single_open(file, msm_otg_mode_show, inode->i_private); -} - -static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, - size_t count, loff_t *ppos) -{ - struct seq_file *s = file->private_data; - struct msm_otg *motg = s->private; - char buf[16]; - struct usb_otg *otg = motg->phy.otg; - int status = count; - enum usb_mode_type req_mode; - - memset(buf, 0x00, sizeof(buf)); - - if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { - status = -EFAULT; - goto out; - } - - if (!strncmp(buf, "host", 4)) { - req_mode = USB_HOST; - } else if (!strncmp(buf, "peripheral", 10)) { - req_mode = USB_PERIPHERAL; - } else if (!strncmp(buf, "none", 4)) { - req_mode = USB_NONE; - } else { - status = -EINVAL; - goto out; - } - - switch (req_mode) { - case USB_NONE: - switch (otg->phy->state) { - case OTG_STATE_A_HOST: - case OTG_STATE_B_PERIPHERAL: - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_PERIPHERAL: - switch (otg->phy->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_A_HOST: - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_HOST: - switch (otg->phy->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_B_PERIPHERAL: - clear_bit(ID, &motg->inputs); - break; - default: - goto out; - } - break; - default: - goto out; - } - - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); -out: - return status; -} - -const struct file_operations msm_otg_mode_fops = { - .open = msm_otg_mode_open, - .read = seq_read, - .write = msm_otg_mode_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct dentry *msm_otg_dbg_root; -static struct dentry *msm_otg_dbg_mode; - -static int msm_otg_debugfs_init(struct msm_otg *motg) -{ - msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); - - if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) - return -ENODEV; - - msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, - msm_otg_dbg_root, motg, &msm_otg_mode_fops); - if (!msm_otg_dbg_mode) { - debugfs_remove(msm_otg_dbg_root); - msm_otg_dbg_root = NULL; - return -ENODEV; - } - - return 0; -} - -static void msm_otg_debugfs_cleanup(void) -{ - debugfs_remove(msm_otg_dbg_mode); - debugfs_remove(msm_otg_dbg_root); -} - -static int __init msm_otg_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res; - struct msm_otg *motg; - struct usb_phy *phy; - - dev_info(&pdev->dev, "msm_otg probe\n"); - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "No platform data given. Bailing out\n"); - return -ENODEV; - } - - motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); - if (!motg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - return -ENOMEM; - } - - motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!motg->phy.otg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - return -ENOMEM; - } - - motg->pdata = pdev->dev.platform_data; - phy = &motg->phy; - phy->dev = &pdev->dev; - - motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); - if (IS_ERR(motg->phy_reset_clk)) { - dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); - ret = PTR_ERR(motg->phy_reset_clk); - goto free_motg; - } - - motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); - if (IS_ERR(motg->clk)) { - dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); - ret = PTR_ERR(motg->clk); - goto put_phy_reset_clk; - } - clk_set_rate(motg->clk, 60000000); - - /* - * If USB Core is running its protocol engine based on CORE CLK, - * CORE CLK must be running at >55Mhz for correct HSUSB - * operation and USB core cannot tolerate frequency changes on - * CORE CLK. For such USB cores, vote for maximum clk frequency - * on pclk source - */ - if (motg->pdata->pclk_src_name) { - motg->pclk_src = clk_get(&pdev->dev, - motg->pdata->pclk_src_name); - if (IS_ERR(motg->pclk_src)) - goto put_clk; - clk_set_rate(motg->pclk_src, INT_MAX); - clk_enable(motg->pclk_src); - } else - motg->pclk_src = ERR_PTR(-ENOENT); - - - motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); - if (IS_ERR(motg->pclk)) { - dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); - ret = PTR_ERR(motg->pclk); - goto put_pclk_src; - } - - /* - * USB core clock is not present on all MSM chips. This - * clock is introduced to remove the dependency on AXI - * bus frequency. - */ - motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); - if (IS_ERR(motg->core_clk)) - motg->core_clk = NULL; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get platform resource mem\n"); - ret = -ENODEV; - goto put_core_clk; - } - - motg->regs = ioremap(res->start, resource_size(res)); - if (!motg->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto put_core_clk; - } - dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); - - motg->irq = platform_get_irq(pdev, 0); - if (!motg->irq) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - ret = -ENODEV; - goto free_regs; - } - - clk_enable(motg->clk); - clk_enable(motg->pclk); - - ret = msm_hsusb_init_vddcx(motg, 1); - if (ret) { - dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); - goto free_regs; - } - - ret = msm_hsusb_ldo_init(motg, 1); - if (ret) { - dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); - goto vddcx_exit; - } - ret = msm_hsusb_ldo_set_mode(1); - if (ret) { - dev_err(&pdev->dev, "hsusb vreg enable failed\n"); - goto ldo_exit; - } - - if (motg->core_clk) - clk_enable(motg->core_clk); - - writel(0, USB_USBINTR); - writel(0, USB_OTGSC); - - INIT_WORK(&motg->sm_work, msm_otg_sm_work); - INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); - ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, - "msm_otg", motg); - if (ret) { - dev_err(&pdev->dev, "request irq failed\n"); - goto disable_clks; - } - - phy->init = msm_otg_reset; - phy->set_power = msm_otg_set_power; - - phy->io_ops = &msm_otg_io_ops; - - phy->otg->phy = &motg->phy; - phy->otg->set_host = msm_otg_set_host; - phy->otg->set_peripheral = msm_otg_set_peripheral; - - ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); - if (ret) { - dev_err(&pdev->dev, "usb_add_phy failed\n"); - goto free_irq; - } - - platform_set_drvdata(pdev, motg); - device_init_wakeup(&pdev->dev, 1); - - if (motg->pdata->mode == USB_OTG && - motg->pdata->otg_control == OTG_USER_CONTROL) { - ret = msm_otg_debugfs_init(motg); - if (ret) - dev_dbg(&pdev->dev, "mode debugfs file is" - "not available\n"); - } - - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - - return 0; -free_irq: - free_irq(motg->irq, motg); -disable_clks: - clk_disable(motg->pclk); - clk_disable(motg->clk); -ldo_exit: - msm_hsusb_ldo_init(motg, 0); -vddcx_exit: - msm_hsusb_init_vddcx(motg, 0); -free_regs: - iounmap(motg->regs); -put_core_clk: - if (motg->core_clk) - clk_put(motg->core_clk); - clk_put(motg->pclk); -put_pclk_src: - if (!IS_ERR(motg->pclk_src)) { - clk_disable(motg->pclk_src); - clk_put(motg->pclk_src); - } -put_clk: - clk_put(motg->clk); -put_phy_reset_clk: - clk_put(motg->phy_reset_clk); -free_motg: - kfree(motg->phy.otg); - kfree(motg); - return ret; -} - -static int msm_otg_remove(struct platform_device *pdev) -{ - struct msm_otg *motg = platform_get_drvdata(pdev); - struct usb_phy *phy = &motg->phy; - int cnt = 0; - - if (phy->otg->host || phy->otg->gadget) - return -EBUSY; - - msm_otg_debugfs_cleanup(); - cancel_delayed_work_sync(&motg->chg_work); - cancel_work_sync(&motg->sm_work); - - pm_runtime_resume(&pdev->dev); - - device_init_wakeup(&pdev->dev, 0); - pm_runtime_disable(&pdev->dev); - - usb_remove_phy(phy); - free_irq(motg->irq, motg); - - /* - * Put PHY in low power mode. - */ - ulpi_read(phy, 0x14); - ulpi_write(phy, 0x08, 0x09); - - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) - dev_err(phy->dev, "Unable to suspend PHY\n"); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) { - clk_disable(motg->pclk_src); - clk_put(motg->pclk_src); - } - msm_hsusb_ldo_init(motg, 0); - - iounmap(motg->regs); - pm_runtime_set_suspended(&pdev->dev); - - clk_put(motg->phy_reset_clk); - clk_put(motg->pclk); - clk_put(motg->clk); - if (motg->core_clk) - clk_put(motg->core_clk); - - kfree(motg->phy.otg); - kfree(motg); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME -static int msm_otg_runtime_idle(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - struct usb_otg *otg = motg->phy.otg; - - dev_dbg(dev, "OTG runtime idle\n"); - - /* - * It is observed some times that a spurious interrupt - * comes when PHY is put into LPM immediately after PHY reset. - * This 1 sec delay also prevents entering into LPM immediately - * after asynchronous interrupt. - */ - if (otg->phy->state != OTG_STATE_UNDEFINED) - pm_schedule_suspend(dev, 1000); - - return -EAGAIN; -} - -static int msm_otg_runtime_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_runtime_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime resume\n"); - return msm_otg_resume(motg); -} -#endif - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_pm_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG PM suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_pm_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - int ret; - - dev_dbg(dev, "OTG PM resume\n"); - - ret = msm_otg_resume(motg); - if (ret) - return ret; - - /* - * Runtime PM Documentation recommends bringing the - * device to full powered state upon resume. - */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - return 0; -} -#endif - -#ifdef CONFIG_PM -static const struct dev_pm_ops msm_otg_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) - SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, - msm_otg_runtime_idle) -}; -#endif - -static struct platform_driver msm_otg_driver = { - .remove = msm_otg_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &msm_otg_dev_pm_ops, -#endif - }, -}; - -module_platform_driver_probe(msm_otg_driver, msm_otg_probe); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c deleted file mode 100644 index b6a9be31133b..000000000000 --- a/drivers/usb/otg/mv_otg.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * Author: Chao Xie - * Neil Zhang - * - * 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 "mv_otg.h" - -#define DRIVER_DESC "Marvell USB OTG transceiver driver" -#define DRIVER_VERSION "Jan 20, 2010" - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -static const char driver_name[] = "mv-otg"; - -static char *state_string[] = { - "undefined", - "b_idle", - "b_srp_init", - "b_peripheral", - "b_wait_acon", - "b_host", - "a_idle", - "a_wait_vrise", - "a_wait_bcon", - "a_host", - "a_suspend", - "a_peripheral", - "a_wait_vfall", - "a_vbus_err" -}; - -static int mv_otg_set_vbus(struct usb_otg *otg, bool on) -{ - struct mv_otg *mvotg = container_of(otg->phy, struct mv_otg, phy); - if (mvotg->pdata->set_vbus == NULL) - return -ENODEV; - - return mvotg->pdata->set_vbus(on); -} - -static int mv_otg_set_host(struct usb_otg *otg, - struct usb_bus *host) -{ - otg->host = host; - - return 0; -} - -static int mv_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - otg->gadget = gadget; - - return 0; -} - -static void mv_otg_run_state_machine(struct mv_otg *mvotg, - unsigned long delay) -{ - dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n"); - if (!mvotg->qwork) - return; - - queue_delayed_work(mvotg->qwork, &mvotg->work, delay); -} - -static void mv_otg_timer_await_bcon(unsigned long data) -{ - struct mv_otg *mvotg = (struct mv_otg *) data; - - mvotg->otg_ctrl.a_wait_bcon_timeout = 1; - - dev_info(&mvotg->pdev->dev, "B Device No Response!\n"); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } -} - -static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id) -{ - struct timer_list *timer; - - if (id >= OTG_TIMER_NUM) - return -EINVAL; - - timer = &mvotg->otg_ctrl.timer[id]; - - if (timer_pending(timer)) - del_timer(timer); - - return 0; -} - -static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id, - unsigned long interval, - void (*callback) (unsigned long)) -{ - struct timer_list *timer; - - if (id >= OTG_TIMER_NUM) - return -EINVAL; - - timer = &mvotg->otg_ctrl.timer[id]; - if (timer_pending(timer)) { - dev_err(&mvotg->pdev->dev, "Timer%d is already running\n", id); - return -EBUSY; - } - - init_timer(timer); - timer->data = (unsigned long) mvotg; - timer->function = callback; - timer->expires = jiffies + interval; - add_timer(timer); - - return 0; -} - -static int mv_otg_reset(struct mv_otg *mvotg) -{ - unsigned int loops; - u32 tmp; - - /* Stop the controller */ - tmp = readl(&mvotg->op_regs->usbcmd); - tmp &= ~USBCMD_RUN_STOP; - writel(tmp, &mvotg->op_regs->usbcmd); - - /* Reset the controller to get default values */ - writel(USBCMD_CTRL_RESET, &mvotg->op_regs->usbcmd); - - loops = 500; - while (readl(&mvotg->op_regs->usbcmd) & USBCMD_CTRL_RESET) { - if (loops == 0) { - dev_err(&mvotg->pdev->dev, - "Wait for RESET completed TIMEOUT\n"); - return -ETIMEDOUT; - } - loops--; - udelay(20); - } - - writel(0x0, &mvotg->op_regs->usbintr); - tmp = readl(&mvotg->op_regs->usbsts); - writel(tmp, &mvotg->op_regs->usbsts); - - return 0; -} - -static void mv_otg_init_irq(struct mv_otg *mvotg) -{ - u32 otgsc; - - mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID - | OTGSC_INTR_A_VBUS_VALID; - mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID - | OTGSC_INTSTS_A_VBUS_VALID; - - if (mvotg->pdata->vbus == NULL) { - mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID - | OTGSC_INTR_B_SESSION_END; - mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID - | OTGSC_INTSTS_B_SESSION_END; - } - - if (mvotg->pdata->id == NULL) { - mvotg->irq_en |= OTGSC_INTR_USB_ID; - mvotg->irq_status |= OTGSC_INTSTS_USB_ID; - } - - otgsc = readl(&mvotg->op_regs->otgsc); - otgsc |= mvotg->irq_en; - writel(otgsc, &mvotg->op_regs->otgsc); -} - -static void mv_otg_start_host(struct mv_otg *mvotg, int on) -{ -#ifdef CONFIG_USB - struct usb_otg *otg = mvotg->phy.otg; - struct usb_hcd *hcd; - - if (!otg->host) - return; - - dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop"); - - hcd = bus_to_hcd(otg->host); - - if (on) - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); - else - usb_remove_hcd(hcd); -#endif /* CONFIG_USB */ -} - -static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) -{ - struct usb_otg *otg = mvotg->phy.otg; - - if (!otg->gadget) - return; - - dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off"); - - if (on) - usb_gadget_vbus_connect(otg->gadget); - else - usb_gadget_vbus_disconnect(otg->gadget); -} - -static void otg_clock_enable(struct mv_otg *mvotg) -{ - unsigned int i; - - for (i = 0; i < mvotg->clknum; i++) - clk_prepare_enable(mvotg->clk[i]); -} - -static void otg_clock_disable(struct mv_otg *mvotg) -{ - unsigned int i; - - for (i = 0; i < mvotg->clknum; i++) - clk_disable_unprepare(mvotg->clk[i]); -} - -static int mv_otg_enable_internal(struct mv_otg *mvotg) -{ - int retval = 0; - - if (mvotg->active) - return 0; - - dev_dbg(&mvotg->pdev->dev, "otg enabled\n"); - - otg_clock_enable(mvotg); - if (mvotg->pdata->phy_init) { - retval = mvotg->pdata->phy_init(mvotg->phy_regs); - if (retval) { - dev_err(&mvotg->pdev->dev, - "init phy error %d\n", retval); - otg_clock_disable(mvotg); - return retval; - } - } - mvotg->active = 1; - - return 0; - -} - -static int mv_otg_enable(struct mv_otg *mvotg) -{ - if (mvotg->clock_gating) - return mv_otg_enable_internal(mvotg); - - return 0; -} - -static void mv_otg_disable_internal(struct mv_otg *mvotg) -{ - if (mvotg->active) { - dev_dbg(&mvotg->pdev->dev, "otg disabled\n"); - if (mvotg->pdata->phy_deinit) - mvotg->pdata->phy_deinit(mvotg->phy_regs); - otg_clock_disable(mvotg); - mvotg->active = 0; - } -} - -static void mv_otg_disable(struct mv_otg *mvotg) -{ - if (mvotg->clock_gating) - mv_otg_disable_internal(mvotg); -} - -static void mv_otg_update_inputs(struct mv_otg *mvotg) -{ - struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - u32 otgsc; - - otgsc = readl(&mvotg->op_regs->otgsc); - - if (mvotg->pdata->vbus) { - if (mvotg->pdata->vbus->poll() == VBUS_HIGH) { - otg_ctrl->b_sess_vld = 1; - otg_ctrl->b_sess_end = 0; - } else { - otg_ctrl->b_sess_vld = 0; - otg_ctrl->b_sess_end = 1; - } - } else { - otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID); - otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END); - } - - if (mvotg->pdata->id) - otg_ctrl->id = !!mvotg->pdata->id->poll(); - else - otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); - - if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) - otg_ctrl->a_bus_req = 1; - - otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); - otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID); - - dev_dbg(&mvotg->pdev->dev, "%s: ", __func__); - dev_dbg(&mvotg->pdev->dev, "id %d\n", otg_ctrl->id); - dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n", otg_ctrl->b_sess_vld); - dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n", otg_ctrl->b_sess_end); - dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n", otg_ctrl->a_vbus_vld); - dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n", otg_ctrl->a_sess_vld); -} - -static void mv_otg_update_state(struct mv_otg *mvotg) -{ - struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - struct usb_phy *phy = &mvotg->phy; - int old_state = phy->state; - - switch (old_state) { - case OTG_STATE_UNDEFINED: - phy->state = OTG_STATE_B_IDLE; - /* FALL THROUGH */ - case OTG_STATE_B_IDLE: - if (otg_ctrl->id == 0) - phy->state = OTG_STATE_A_IDLE; - else if (otg_ctrl->b_sess_vld) - phy->state = OTG_STATE_B_PERIPHERAL; - break; - case OTG_STATE_B_PERIPHERAL: - if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) - phy->state = OTG_STATE_B_IDLE; - break; - case OTG_STATE_A_IDLE: - if (otg_ctrl->id) - phy->state = OTG_STATE_B_IDLE; - else if (!(otg_ctrl->a_bus_drop) && - (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) - phy->state = OTG_STATE_A_WAIT_VRISE; - break; - case OTG_STATE_A_WAIT_VRISE: - if (otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_WAIT_BCON; - break; - case OTG_STATE_A_WAIT_BCON: - if (otg_ctrl->id || otg_ctrl->a_bus_drop - || otg_ctrl->a_wait_bcon_timeout) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; - otg_ctrl->a_bus_req = 0; - } else if (!otg_ctrl->a_vbus_vld) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_VBUS_ERR; - } else if (otg_ctrl->b_conn) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_HOST; - } - break; - case OTG_STATE_A_HOST: - if (otg_ctrl->id || !otg_ctrl->b_conn - || otg_ctrl->a_bus_drop) - phy->state = OTG_STATE_A_WAIT_BCON; - else if (!otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_VBUS_ERR; - break; - case OTG_STATE_A_WAIT_VFALL: - if (otg_ctrl->id - || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) - || otg_ctrl->a_bus_req) - phy->state = OTG_STATE_A_IDLE; - break; - case OTG_STATE_A_VBUS_ERR: - if (otg_ctrl->id || otg_ctrl->a_clr_err - || otg_ctrl->a_bus_drop) { - otg_ctrl->a_clr_err = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; - } - break; - default: - break; - } -} - -static void mv_otg_work(struct work_struct *work) -{ - struct mv_otg *mvotg; - struct usb_phy *phy; - struct usb_otg *otg; - int old_state; - - mvotg = container_of(to_delayed_work(work), struct mv_otg, work); - -run: - /* work queue is single thread, or we need spin_lock to protect */ - phy = &mvotg->phy; - otg = phy->otg; - old_state = phy->state; - - if (!mvotg->active) - return; - - mv_otg_update_inputs(mvotg); - mv_otg_update_state(mvotg); - - if (old_state != phy->state) { - dev_info(&mvotg->pdev->dev, "change from state %s to %s\n", - state_string[old_state], - state_string[phy->state]); - - switch (phy->state) { - case OTG_STATE_B_IDLE: - otg->default_a = 0; - if (old_state == OTG_STATE_B_PERIPHERAL) - mv_otg_start_periphrals(mvotg, 0); - mv_otg_reset(mvotg); - mv_otg_disable(mvotg); - break; - case OTG_STATE_B_PERIPHERAL: - mv_otg_enable(mvotg); - mv_otg_start_periphrals(mvotg, 1); - break; - case OTG_STATE_A_IDLE: - otg->default_a = 1; - mv_otg_enable(mvotg); - if (old_state == OTG_STATE_A_WAIT_VFALL) - mv_otg_start_host(mvotg, 0); - mv_otg_reset(mvotg); - break; - case OTG_STATE_A_WAIT_VRISE: - mv_otg_set_vbus(otg, 1); - break; - case OTG_STATE_A_WAIT_BCON: - if (old_state != OTG_STATE_A_HOST) - mv_otg_start_host(mvotg, 1); - mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER, - T_A_WAIT_BCON, - mv_otg_timer_await_bcon); - /* - * Now, we directly enter A_HOST. So set b_conn = 1 - * here. In fact, it need host driver to notify us. - */ - mvotg->otg_ctrl.b_conn = 1; - break; - case OTG_STATE_A_HOST: - break; - case OTG_STATE_A_WAIT_VFALL: - /* - * Now, we has exited A_HOST. So set b_conn = 0 - * here. In fact, it need host driver to notify us. - */ - mvotg->otg_ctrl.b_conn = 0; - mv_otg_set_vbus(otg, 0); - break; - case OTG_STATE_A_VBUS_ERR: - break; - default: - break; - } - goto run; - } -} - -static irqreturn_t mv_otg_irq(int irq, void *dev) -{ - struct mv_otg *mvotg = dev; - u32 otgsc; - - otgsc = readl(&mvotg->op_regs->otgsc); - writel(otgsc, &mvotg->op_regs->otgsc); - - /* - * if we have vbus, then the vbus detection for B-device - * will be done by mv_otg_inputs_irq(). - */ - if (mvotg->pdata->vbus) - if ((otgsc & OTGSC_STS_USB_ID) && - !(otgsc & OTGSC_INTSTS_USB_ID)) - return IRQ_NONE; - - if ((otgsc & mvotg->irq_status) == 0) - return IRQ_NONE; - - mv_otg_run_state_machine(mvotg, 0); - - return IRQ_HANDLED; -} - -static irqreturn_t mv_otg_inputs_irq(int irq, void *dev) -{ - struct mv_otg *mvotg = dev; - - /* The clock may disabled at this time */ - if (!mvotg->active) { - mv_otg_enable(mvotg); - mv_otg_init_irq(mvotg); - } - - mv_otg_run_state_machine(mvotg, 0); - - return IRQ_HANDLED; -} - -static ssize_t -get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%d\n", - mvotg->otg_ctrl.a_bus_req); -} - -static ssize_t -set_a_bus_req(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - - if (count > 2) - return -1; - - /* We will use this interface to change to A device */ - if (mvotg->phy.state != OTG_STATE_B_IDLE - && mvotg->phy.state != OTG_STATE_A_IDLE) - return -1; - - /* The clock may disabled and we need to set irq for ID detected */ - mv_otg_enable(mvotg); - mv_otg_init_irq(mvotg); - - if (buf[0] == '1') { - mvotg->otg_ctrl.a_bus_req = 1; - mvotg->otg_ctrl.a_bus_drop = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_req = 1\n"); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - } - - return count; -} - -static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, - set_a_bus_req); - -static ssize_t -set_a_clr_err(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - if (!mvotg->phy.otg->default_a) - return -1; - - if (count > 2) - return -1; - - if (buf[0] == '1') { - mvotg->otg_ctrl.a_clr_err = 1; - dev_dbg(&mvotg->pdev->dev, - "User request: a_clr_err = 1\n"); - } - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - - return count; -} - -static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); - -static ssize_t -get_a_bus_drop(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%d\n", - mvotg->otg_ctrl.a_bus_drop); -} - -static ssize_t -set_a_bus_drop(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - if (!mvotg->phy.otg->default_a) - return -1; - - if (count > 2) - return -1; - - if (buf[0] == '0') { - mvotg->otg_ctrl.a_bus_drop = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_drop = 0\n"); - } else if (buf[0] == '1') { - mvotg->otg_ctrl.a_bus_drop = 1; - mvotg->otg_ctrl.a_bus_req = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_drop = 1\n"); - dev_dbg(&mvotg->pdev->dev, - "User request: and a_bus_req = 0\n"); - } - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - - return count; -} - -static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, - get_a_bus_drop, set_a_bus_drop); - -static struct attribute *inputs_attrs[] = { - &dev_attr_a_bus_req.attr, - &dev_attr_a_clr_err.attr, - &dev_attr_a_bus_drop.attr, - NULL, -}; - -static struct attribute_group inputs_attr_group = { - .name = "inputs", - .attrs = inputs_attrs, -}; - -int mv_otg_remove(struct platform_device *pdev) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - - sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); - - if (mvotg->qwork) { - flush_workqueue(mvotg->qwork); - destroy_workqueue(mvotg->qwork); - } - - mv_otg_disable(mvotg); - - usb_remove_phy(&mvotg->phy); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static int mv_otg_probe(struct platform_device *pdev) -{ - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; - struct mv_otg *mvotg; - struct usb_otg *otg; - struct resource *r; - int retval = 0, clk_i, i; - size_t size; - - if (pdata == NULL) { - dev_err(&pdev->dev, "failed to get platform data\n"); - return -ENODEV; - } - - size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; - mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!mvotg) { - dev_err(&pdev->dev, "failed to allocate memory!\n"); - return -ENOMEM; - } - - otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - platform_set_drvdata(pdev, mvotg); - - mvotg->pdev = pdev; - mvotg->pdata = pdata; - - mvotg->clknum = pdata->clknum; - for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { - mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, - pdata->clkname[clk_i]); - if (IS_ERR(mvotg->clk[clk_i])) { - retval = PTR_ERR(mvotg->clk[clk_i]); - return retval; - } - } - - mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); - if (!mvotg->qwork) { - dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); - return -ENOMEM; - } - - INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); - - /* OTG common part */ - mvotg->pdev = pdev; - mvotg->phy.dev = &pdev->dev; - mvotg->phy.otg = otg; - mvotg->phy.label = driver_name; - mvotg->phy.state = OTG_STATE_UNDEFINED; - - otg->phy = &mvotg->phy; - otg->set_host = mv_otg_set_host; - otg->set_peripheral = mv_otg_set_peripheral; - otg->set_vbus = mv_otg_set_vbus; - - for (i = 0; i < OTG_TIMER_NUM; i++) - init_timer(&mvotg->otg_ctrl.timer[i]); - - r = platform_get_resource_byname(mvotg->pdev, - IORESOURCE_MEM, "phyregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_destroy_workqueue; - } - - mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (mvotg->phy_regs == NULL) { - dev_err(&pdev->dev, "failed to map phy I/O memory\n"); - retval = -EFAULT; - goto err_destroy_workqueue; - } - - r = platform_get_resource_byname(mvotg->pdev, - IORESOURCE_MEM, "capregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_destroy_workqueue; - } - - mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (mvotg->cap_regs == NULL) { - dev_err(&pdev->dev, "failed to map I/O memory\n"); - retval = -EFAULT; - goto err_destroy_workqueue; - } - - /* we will acces controller register, so enable the udc controller */ - retval = mv_otg_enable_internal(mvotg); - if (retval) { - dev_err(&pdev->dev, "mv otg enable error %d\n", retval); - goto err_destroy_workqueue; - } - - mvotg->op_regs = - (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs - + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); - - if (pdata->id) { - retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, - NULL, mv_otg_inputs_irq, - IRQF_ONESHOT, "id", mvotg); - if (retval) { - dev_info(&pdev->dev, - "Failed to request irq for ID\n"); - pdata->id = NULL; - } - } - - if (pdata->vbus) { - mvotg->clock_gating = 1; - retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, - NULL, mv_otg_inputs_irq, - IRQF_ONESHOT, "vbus", mvotg); - if (retval) { - dev_info(&pdev->dev, - "Failed to request irq for VBUS, " - "disable clock gating\n"); - mvotg->clock_gating = 0; - pdata->vbus = NULL; - } - } - - if (pdata->disable_otg_clock_gating) - mvotg->clock_gating = 0; - - mv_otg_reset(mvotg); - mv_otg_init_irq(mvotg); - - r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); - if (r == NULL) { - dev_err(&pdev->dev, "no IRQ resource defined\n"); - retval = -ENODEV; - goto err_disable_clk; - } - - mvotg->irq = r->start; - if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, - driver_name, mvotg)) { - dev_err(&pdev->dev, "Request irq %d for OTG failed\n", - mvotg->irq); - mvotg->irq = 0; - retval = -ENODEV; - goto err_disable_clk; - } - - retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); - if (retval < 0) { - dev_err(&pdev->dev, "can't register transceiver, %d\n", - retval); - goto err_disable_clk; - } - - retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); - if (retval < 0) { - dev_dbg(&pdev->dev, - "Can't register sysfs attr group: %d\n", retval); - goto err_remove_phy; - } - - spin_lock_init(&mvotg->wq_lock); - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 2 * HZ); - spin_unlock(&mvotg->wq_lock); - } - - dev_info(&pdev->dev, - "successful probe OTG device %s clock gating.\n", - mvotg->clock_gating ? "with" : "without"); - - return 0; - -err_remove_phy: - usb_remove_phy(&mvotg->phy); -err_disable_clk: - mv_otg_disable_internal(mvotg); -err_destroy_workqueue: - flush_workqueue(mvotg->qwork); - destroy_workqueue(mvotg->qwork); - - platform_set_drvdata(pdev, NULL); - - return retval; -} - -#ifdef CONFIG_PM -static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - - if (mvotg->phy.state != OTG_STATE_B_IDLE) { - dev_info(&pdev->dev, - "OTG state is not B_IDLE, it is %d!\n", - mvotg->phy.state); - return -EAGAIN; - } - - if (!mvotg->clock_gating) - mv_otg_disable_internal(mvotg); - - return 0; -} - -static int mv_otg_resume(struct platform_device *pdev) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - u32 otgsc; - - if (!mvotg->clock_gating) { - mv_otg_enable_internal(mvotg); - - otgsc = readl(&mvotg->op_regs->otgsc); - otgsc |= mvotg->irq_en; - writel(otgsc, &mvotg->op_regs->otgsc); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - } - return 0; -} -#endif - -static struct platform_driver mv_otg_driver = { - .probe = mv_otg_probe, - .remove = __exit_p(mv_otg_remove), - .driver = { - .owner = THIS_MODULE, - .name = driver_name, - }, -#ifdef CONFIG_PM - .suspend = mv_otg_suspend, - .resume = mv_otg_resume, -#endif -}; -module_platform_driver(mv_otg_driver); diff --git a/drivers/usb/otg/mv_otg.h b/drivers/usb/otg/mv_otg.h deleted file mode 100644 index 8a9e351b36ba..000000000000 --- a/drivers/usb/otg/mv_otg.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. 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. - */ - -#ifndef __MV_USB_OTG_CONTROLLER__ -#define __MV_USB_OTG_CONTROLLER__ - -#include - -/* Command Register Bit Masks */ -#define USBCMD_RUN_STOP (0x00000001) -#define USBCMD_CTRL_RESET (0x00000002) - -/* otgsc Register Bit Masks */ -#define OTGSC_CTRL_VUSB_DISCHARGE 0x00000001 -#define OTGSC_CTRL_VUSB_CHARGE 0x00000002 -#define OTGSC_CTRL_OTG_TERM 0x00000008 -#define OTGSC_CTRL_DATA_PULSING 0x00000010 -#define OTGSC_STS_USB_ID 0x00000100 -#define OTGSC_STS_A_VBUS_VALID 0x00000200 -#define OTGSC_STS_A_SESSION_VALID 0x00000400 -#define OTGSC_STS_B_SESSION_VALID 0x00000800 -#define OTGSC_STS_B_SESSION_END 0x00001000 -#define OTGSC_STS_1MS_TOGGLE 0x00002000 -#define OTGSC_STS_DATA_PULSING 0x00004000 -#define OTGSC_INTSTS_USB_ID 0x00010000 -#define OTGSC_INTSTS_A_VBUS_VALID 0x00020000 -#define OTGSC_INTSTS_A_SESSION_VALID 0x00040000 -#define OTGSC_INTSTS_B_SESSION_VALID 0x00080000 -#define OTGSC_INTSTS_B_SESSION_END 0x00100000 -#define OTGSC_INTSTS_1MS 0x00200000 -#define OTGSC_INTSTS_DATA_PULSING 0x00400000 -#define OTGSC_INTR_USB_ID 0x01000000 -#define OTGSC_INTR_A_VBUS_VALID 0x02000000 -#define OTGSC_INTR_A_SESSION_VALID 0x04000000 -#define OTGSC_INTR_B_SESSION_VALID 0x08000000 -#define OTGSC_INTR_B_SESSION_END 0x10000000 -#define OTGSC_INTR_1MS_TIMER 0x20000000 -#define OTGSC_INTR_DATA_PULSING 0x40000000 - -#define CAPLENGTH_MASK (0xff) - -/* Timer's interval, unit 10ms */ -#define T_A_WAIT_VRISE 100 -#define T_A_WAIT_BCON 2000 -#define T_A_AIDL_BDIS 100 -#define T_A_BIDL_ADIS 20 -#define T_B_ASE0_BRST 400 -#define T_B_SE0_SRP 300 -#define T_B_SRP_FAIL 2000 -#define T_B_DATA_PLS 10 -#define T_B_SRP_INIT 100 -#define T_A_SRP_RSPNS 10 -#define T_A_DRV_RSM 5 - -enum otg_function { - OTG_B_DEVICE = 0, - OTG_A_DEVICE -}; - -enum mv_otg_timer { - A_WAIT_BCON_TIMER = 0, - OTG_TIMER_NUM -}; - -/* PXA OTG state machine */ -struct mv_otg_ctrl { - /* internal variables */ - u8 a_set_b_hnp_en; /* A-Device set b_hnp_en */ - u8 b_srp_done; - u8 b_hnp_en; - - /* OTG inputs */ - u8 a_bus_drop; - u8 a_bus_req; - u8 a_clr_err; - u8 a_bus_resume; - u8 a_bus_suspend; - u8 a_conn; - u8 a_sess_vld; - u8 a_srp_det; - u8 a_vbus_vld; - u8 b_bus_req; /* B-Device Require Bus */ - u8 b_bus_resume; - u8 b_bus_suspend; - u8 b_conn; - u8 b_se0_srp; - u8 b_sess_end; - u8 b_sess_vld; - u8 id; - u8 a_suspend_req; - - /*Timer event */ - u8 a_aidl_bdis_timeout; - u8 b_ase0_brst_timeout; - u8 a_bidl_adis_timeout; - u8 a_wait_bcon_timeout; - - struct timer_list timer[OTG_TIMER_NUM]; -}; - -#define VUSBHS_MAX_PORTS 8 - -struct mv_otg_regs { - u32 usbcmd; /* Command register */ - u32 usbsts; /* Status register */ - u32 usbintr; /* Interrupt enable */ - u32 frindex; /* Frame index */ - u32 reserved1[1]; - u32 deviceaddr; /* Device Address */ - u32 eplistaddr; /* Endpoint List Address */ - u32 ttctrl; /* HOST TT status and control */ - u32 burstsize; /* Programmable Burst Size */ - u32 txfilltuning; /* Host Transmit Pre-Buffer Packet Tuning */ - u32 reserved[4]; - u32 epnak; /* Endpoint NAK */ - u32 epnaken; /* Endpoint NAK Enable */ - u32 configflag; /* Configured Flag register */ - u32 portsc[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */ - u32 otgsc; - u32 usbmode; /* USB Host/Device mode */ - u32 epsetupstat; /* Endpoint Setup Status */ - u32 epprime; /* Endpoint Initialize */ - u32 epflush; /* Endpoint De-initialize */ - u32 epstatus; /* Endpoint Status */ - u32 epcomplete; /* Endpoint Interrupt On Complete */ - u32 epctrlx[16]; /* Endpoint Control, where x = 0.. 15 */ - u32 mcr; /* Mux Control */ - u32 isr; /* Interrupt Status */ - u32 ier; /* Interrupt Enable */ -}; - -struct mv_otg { - struct usb_phy phy; - struct mv_otg_ctrl otg_ctrl; - - /* base address */ - void __iomem *phy_regs; - void __iomem *cap_regs; - struct mv_otg_regs __iomem *op_regs; - - struct platform_device *pdev; - int irq; - u32 irq_status; - u32 irq_en; - - struct delayed_work work; - struct workqueue_struct *qwork; - - spinlock_t wq_lock; - - struct mv_usb_platform_data *pdata; - - unsigned int active; - unsigned int clock_gating; - unsigned int clknum; - struct clk *clk[0]; -}; - -#endif diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c deleted file mode 100644 index 9d4381e64d51..000000000000 --- a/drivers/usb/otg/mxs-phy.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Marek Vasut - * on behalf of DENX Software Engineering GmbH - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "mxs_phy" - -#define HW_USBPHY_PWD 0x00 -#define HW_USBPHY_CTRL 0x30 -#define HW_USBPHY_CTRL_SET 0x34 -#define HW_USBPHY_CTRL_CLR 0x38 - -#define BM_USBPHY_CTRL_SFTRST BIT(31) -#define BM_USBPHY_CTRL_CLKGATE BIT(30) -#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) -#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) -#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) - -struct mxs_phy { - struct usb_phy phy; - struct clk *clk; -}; - -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) - -static void mxs_phy_hw_init(struct mxs_phy *mxs_phy) -{ - void __iomem *base = mxs_phy->phy.io_priv; - - stmp_reset_block(base + HW_USBPHY_CTRL); - - /* Power up the PHY */ - writel(0, base + HW_USBPHY_PWD); - - /* enable FS/LS device */ - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | - BM_USBPHY_CTRL_ENUTMILEVEL3, - base + HW_USBPHY_CTRL_SET); -} - -static int mxs_phy_init(struct usb_phy *phy) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(phy); - - clk_prepare_enable(mxs_phy->clk); - mxs_phy_hw_init(mxs_phy); - - return 0; -} - -static void mxs_phy_shutdown(struct usb_phy *phy) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(phy); - - writel(BM_USBPHY_CTRL_CLKGATE, - phy->io_priv + HW_USBPHY_CTRL_SET); - - clk_disable_unprepare(mxs_phy->clk); -} - -static int mxs_phy_suspend(struct usb_phy *x, int suspend) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(x); - - if (suspend) { - writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); - writel(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_SET); - clk_disable_unprepare(mxs_phy->clk); - } else { - clk_prepare_enable(mxs_phy->clk); - writel(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_CLR); - writel(0, x->io_priv + HW_USBPHY_PWD); - } - - return 0; -} - -static int mxs_phy_on_connect(struct usb_phy *phy, - enum usb_device_speed speed) -{ - dev_dbg(phy->dev, "%s speed device has connected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - - if (speed == USB_SPEED_HIGH) - writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_SET); - - return 0; -} - -static int mxs_phy_on_disconnect(struct usb_phy *phy, - enum usb_device_speed speed) -{ - dev_dbg(phy->dev, "%s speed device has disconnected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - - if (speed == USB_SPEED_HIGH) - writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_CLR); - - return 0; -} - -static int mxs_phy_probe(struct platform_device *pdev) -{ - struct resource *res; - void __iomem *base; - struct clk *clk; - struct mxs_phy *mxs_phy; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "can't get device resources\n"); - return -ENOENT; - } - - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, - "can't get the clock, err=%ld", PTR_ERR(clk)); - return PTR_ERR(clk); - } - - mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); - if (!mxs_phy) { - dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); - return -ENOMEM; - } - - mxs_phy->phy.io_priv = base; - mxs_phy->phy.dev = &pdev->dev; - mxs_phy->phy.label = DRIVER_NAME; - mxs_phy->phy.init = mxs_phy_init; - mxs_phy->phy.shutdown = mxs_phy_shutdown; - mxs_phy->phy.set_suspend = mxs_phy_suspend; - mxs_phy->phy.notify_connect = mxs_phy_on_connect; - mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; - - ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); - - mxs_phy->clk = clk; - - platform_set_drvdata(pdev, &mxs_phy->phy); - - ret = usb_add_phy_dev(&mxs_phy->phy); - if (ret) - return ret; - - return 0; -} - -static int mxs_phy_remove(struct platform_device *pdev) -{ - struct mxs_phy *mxs_phy = platform_get_drvdata(pdev); - - usb_remove_phy(&mxs_phy->phy); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id mxs_phy_dt_ids[] = { - { .compatible = "fsl,imx23-usbphy", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); - -static struct platform_driver mxs_phy_driver = { - .probe = mxs_phy_probe, - .remove = mxs_phy_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = mxs_phy_dt_ids, - }, -}; - -static int __init mxs_phy_module_init(void) -{ - return platform_driver_register(&mxs_phy_driver); -} -postcore_initcall(mxs_phy_module_init); - -static void __exit mxs_phy_module_exit(void) -{ - platform_driver_unregister(&mxs_phy_driver); -} -module_exit(mxs_phy_module_exit); - -MODULE_ALIAS("platform:mxs-usb-phy"); -MODULE_AUTHOR("Marek Vasut "); -MODULE_AUTHOR("Richard Zhao "); -MODULE_DESCRIPTION("Freescale MXS USB PHY driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c deleted file mode 100644 index 2b10cc969bbb..000000000000 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * drivers/usb/otg/nop-usb-xceiv.c - * - * NOP USB transceiver for all USB transceiver which are either built-in - * into USB IP or which are mostly autonomous. - * - * Copyright (C) 2009 Texas Instruments Inc - * Author: Ajay Kumar Gupta - * - * 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. - * - * Current status: - * This provides a "nop" transceiver for PHYs which are - * autonomous such as isp1504, isp1707, etc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct nop_usb_xceiv { - struct usb_phy phy; - struct device *dev; - struct clk *clk; - struct regulator *vcc; - struct regulator *reset; -}; - -static struct platform_device *pd; - -void usb_nop_xceiv_register(void) -{ - if (pd) - return; - pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); - if (!pd) { - printk(KERN_ERR "Unable to register usb nop transceiver\n"); - return; - } -} -EXPORT_SYMBOL(usb_nop_xceiv_register); - -void usb_nop_xceiv_unregister(void) -{ - platform_device_unregister(pd); - pd = NULL; -} -EXPORT_SYMBOL(usb_nop_xceiv_unregister); - -static int nop_set_suspend(struct usb_phy *x, int suspend) -{ - return 0; -} - -static int nop_init(struct usb_phy *phy) -{ - struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); - - if (!IS_ERR(nop->vcc)) { - if (regulator_enable(nop->vcc)) - dev_err(phy->dev, "Failed to enable power\n"); - } - - if (!IS_ERR(nop->clk)) - clk_enable(nop->clk); - - if (!IS_ERR(nop->reset)) { - /* De-assert RESET */ - if (regulator_enable(nop->reset)) - dev_err(phy->dev, "Failed to de-assert reset\n"); - } - - return 0; -} - -static void nop_shutdown(struct usb_phy *phy) -{ - struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); - - if (!IS_ERR(nop->reset)) { - /* Assert RESET */ - if (regulator_disable(nop->reset)) - dev_err(phy->dev, "Failed to assert reset\n"); - } - - if (!IS_ERR(nop->clk)) - clk_disable(nop->clk); - - if (!IS_ERR(nop->vcc)) { - if (regulator_disable(nop->vcc)) - dev_err(phy->dev, "Failed to disable power\n"); - } -} - -static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) -{ - if (!otg) - return -ENODEV; - - if (!gadget) { - otg->gadget = NULL; - return -ENODEV; - } - - otg->gadget = gadget; - otg->phy->state = OTG_STATE_B_IDLE; - return 0; -} - -static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - if (!host) { - otg->host = NULL; - return -ENODEV; - } - - otg->host = host; - return 0; -} - -static int nop_usb_xceiv_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; - struct nop_usb_xceiv *nop; - enum usb_phy_type type = USB_PHY_TYPE_USB2; - int err; - u32 clk_rate = 0; - bool needs_vcc = false; - bool needs_reset = false; - - nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); - if (!nop) - return -ENOMEM; - - nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), - GFP_KERNEL); - if (!nop->phy.otg) - return -ENOMEM; - - if (dev->of_node) { - struct device_node *node = dev->of_node; - - if (of_property_read_u32(node, "clock-frequency", &clk_rate)) - clk_rate = 0; - - needs_vcc = of_property_read_bool(node, "vcc-supply"); - needs_reset = of_property_read_bool(node, "reset-supply"); - - } else if (pdata) { - type = pdata->type; - clk_rate = pdata->clk_rate; - needs_vcc = pdata->needs_vcc; - needs_reset = pdata->needs_reset; - } - - nop->clk = devm_clk_get(&pdev->dev, "main_clk"); - if (IS_ERR(nop->clk)) { - dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", - PTR_ERR(nop->clk)); - } - - if (!IS_ERR(nop->clk) && clk_rate) { - err = clk_set_rate(nop->clk, clk_rate); - if (err) { - dev_err(&pdev->dev, "Error setting clock rate\n"); - return err; - } - } - - if (!IS_ERR(nop->clk)) { - err = clk_prepare(nop->clk); - if (err) { - dev_err(&pdev->dev, "Error preparing clock\n"); - return err; - } - } - - nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); - if (IS_ERR(nop->vcc)) { - dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", - PTR_ERR(nop->vcc)); - if (needs_vcc) - return -EPROBE_DEFER; - } - - nop->reset = devm_regulator_get(&pdev->dev, "reset"); - if (IS_ERR(nop->reset)) { - dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", - PTR_ERR(nop->reset)); - if (needs_reset) - return -EPROBE_DEFER; - } - - nop->dev = &pdev->dev; - nop->phy.dev = nop->dev; - nop->phy.label = "nop-xceiv"; - nop->phy.set_suspend = nop_set_suspend; - nop->phy.init = nop_init; - nop->phy.shutdown = nop_shutdown; - nop->phy.state = OTG_STATE_UNDEFINED; - nop->phy.type = type; - - nop->phy.otg->phy = &nop->phy; - nop->phy.otg->set_host = nop_set_host; - nop->phy.otg->set_peripheral = nop_set_peripheral; - - err = usb_add_phy_dev(&nop->phy); - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); - goto err_add; - } - - platform_set_drvdata(pdev, nop); - - ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); - - return 0; - -err_add: - if (!IS_ERR(nop->clk)) - clk_unprepare(nop->clk); - return err; -} - -static int nop_usb_xceiv_remove(struct platform_device *pdev) -{ - struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); - - if (!IS_ERR(nop->clk)) - clk_unprepare(nop->clk); - - usb_remove_phy(&nop->phy); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id nop_xceiv_dt_ids[] = { - { .compatible = "usb-nop-xceiv" }, - { } -}; - -MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); - -static struct platform_driver nop_usb_xceiv_driver = { - .probe = nop_usb_xceiv_probe, - .remove = nop_usb_xceiv_remove, - .driver = { - .name = "nop_usb_xceiv", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(nop_xceiv_dt_ids), - }, -}; - -static int __init nop_usb_xceiv_init(void) -{ - return platform_driver_register(&nop_usb_xceiv_driver); -} -subsys_initcall(nop_usb_xceiv_init); - -static void __exit nop_usb_xceiv_exit(void) -{ - platform_driver_unregister(&nop_usb_xceiv_driver); -} -module_exit(nop_usb_xceiv_exit); - -MODULE_ALIAS("platform:nop_usb_xceiv"); -MODULE_AUTHOR("Texas Instruments Inc"); -MODULE_DESCRIPTION("NOP USB Transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/otg_fsm.c b/drivers/usb/otg/otg_fsm.c deleted file mode 100644 index 1f729a15decb..000000000000 --- a/drivers/usb/otg/otg_fsm.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * OTG Finite State Machine from OTG spec - * - * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * Author: Li Yang - * Jerry Huang - * - * 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 "otg_fsm.h" - -/* Change USB protocol when there is a protocol change */ -static int otg_set_protocol(struct otg_fsm *fsm, int protocol) -{ - int ret = 0; - - if (fsm->protocol != protocol) { - VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", - fsm->protocol, protocol); - /* stop old protocol */ - if (fsm->protocol == PROTO_HOST) - ret = fsm->ops->start_host(fsm, 0); - else if (fsm->protocol == PROTO_GADGET) - ret = fsm->ops->start_gadget(fsm, 0); - if (ret) - return ret; - - /* start new protocol */ - if (protocol == PROTO_HOST) - ret = fsm->ops->start_host(fsm, 1); - else if (protocol == PROTO_GADGET) - ret = fsm->ops->start_gadget(fsm, 1); - if (ret) - return ret; - - fsm->protocol = protocol; - return 0; - } - - return 0; -} - -static int state_changed; - -/* Called when leaving a state. Do state clean up jobs here */ -void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) -{ - switch (old_state) { - case OTG_STATE_B_IDLE: - otg_del_timer(fsm, b_se0_srp_tmr); - fsm->b_se0_srp = 0; - break; - case OTG_STATE_B_SRP_INIT: - fsm->b_srp_done = 0; - break; - case OTG_STATE_B_PERIPHERAL: - break; - case OTG_STATE_B_WAIT_ACON: - otg_del_timer(fsm, b_ase0_brst_tmr); - fsm->b_ase0_brst_tmout = 0; - break; - case OTG_STATE_B_HOST: - break; - case OTG_STATE_A_IDLE: - break; - case OTG_STATE_A_WAIT_VRISE: - otg_del_timer(fsm, a_wait_vrise_tmr); - fsm->a_wait_vrise_tmout = 0; - break; - case OTG_STATE_A_WAIT_BCON: - otg_del_timer(fsm, a_wait_bcon_tmr); - fsm->a_wait_bcon_tmout = 0; - break; - case OTG_STATE_A_HOST: - otg_del_timer(fsm, a_wait_enum_tmr); - break; - case OTG_STATE_A_SUSPEND: - otg_del_timer(fsm, a_aidl_bdis_tmr); - fsm->a_aidl_bdis_tmout = 0; - fsm->a_suspend_req = 0; - break; - case OTG_STATE_A_PERIPHERAL: - break; - case OTG_STATE_A_WAIT_VFALL: - otg_del_timer(fsm, a_wait_vrise_tmr); - break; - case OTG_STATE_A_VBUS_ERR: - break; - default: - break; - } -} - -/* Called when entering a state */ -int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) -{ - state_changed = 1; - if (fsm->otg->phy->state == new_state) - return 0; - VDBG("Set state: %s\n", usb_otg_state_string(new_state)); - otg_leave_state(fsm, fsm->otg->phy->state); - switch (new_state) { - case OTG_STATE_B_IDLE: - otg_drv_vbus(fsm, 0); - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_se0_srp_tmr); - break; - case OTG_STATE_B_SRP_INIT: - otg_start_pulse(fsm); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_srp_fail_tmr); - break; - case OTG_STATE_B_PERIPHERAL: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 1); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_GADGET); - break; - case OTG_STATE_B_WAIT_ACON: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, b_ase0_brst_tmr); - fsm->a_bus_suspend = 0; - break; - case OTG_STATE_B_HOST: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 1); - otg_set_protocol(fsm, PROTO_HOST); - usb_bus_start_enum(fsm->otg->host, - fsm->otg->host->otg_port); - break; - case OTG_STATE_A_IDLE: - otg_drv_vbus(fsm, 0); - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - break; - case OTG_STATE_A_WAIT_VRISE: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_vrise_tmr); - break; - case OTG_STATE_A_WAIT_BCON: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_bcon_tmr); - break; - case OTG_STATE_A_HOST: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 1); - otg_set_protocol(fsm, PROTO_HOST); - /* - * When HNP is triggered while a_bus_req = 0, a_host will - * suspend too fast to complete a_set_b_hnp_en - */ - if (!fsm->a_bus_req || fsm->a_suspend_req) - otg_add_timer(fsm, a_wait_enum_tmr); - break; - case OTG_STATE_A_SUSPEND: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_aidl_bdis_tmr); - - break; - case OTG_STATE_A_PERIPHERAL: - otg_loc_conn(fsm, 1); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_GADGET); - otg_drv_vbus(fsm, 1); - break; - case OTG_STATE_A_WAIT_VFALL: - otg_drv_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - break; - case OTG_STATE_A_VBUS_ERR: - otg_drv_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - break; - default: - break; - } - - fsm->otg->phy->state = new_state; - return 0; -} - -/* State change judgement */ -int otg_statemachine(struct otg_fsm *fsm) -{ - enum usb_otg_state state; - unsigned long flags; - - spin_lock_irqsave(&fsm->lock, flags); - - state = fsm->otg->phy->state; - state_changed = 0; - /* State machine state change judgement */ - - switch (state) { - case OTG_STATE_UNDEFINED: - VDBG("fsm->id = %d\n", fsm->id); - if (fsm->id) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else - otg_set_state(fsm, OTG_STATE_A_IDLE); - break; - case OTG_STATE_B_IDLE: - if (!fsm->id) - otg_set_state(fsm, OTG_STATE_A_IDLE); - else if (fsm->b_sess_vld && fsm->otg->gadget) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp) - otg_set_state(fsm, OTG_STATE_B_SRP_INIT); - break; - case OTG_STATE_B_SRP_INIT: - if (!fsm->id || fsm->b_srp_done) - otg_set_state(fsm, OTG_STATE_B_IDLE); - break; - case OTG_STATE_B_PERIPHERAL: - if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (fsm->b_bus_req && fsm->otg-> - gadget->b_hnp_enable && fsm->a_bus_suspend) - otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); - break; - case OTG_STATE_B_WAIT_ACON: - if (fsm->a_conn) - otg_set_state(fsm, OTG_STATE_B_HOST); - else if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { - fsm->b_ase0_brst_tmout = 0; - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - } - break; - case OTG_STATE_B_HOST: - if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (!fsm->b_bus_req || !fsm->a_conn) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - break; - case OTG_STATE_A_IDLE: - if (fsm->id) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) - otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); - break; - case OTG_STATE_A_WAIT_VRISE: - if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld || - fsm->a_wait_vrise_tmout) { - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - } - break; - case OTG_STATE_A_WAIT_BCON: - if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - else if (fsm->b_conn) - otg_set_state(fsm, OTG_STATE_A_HOST); - else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - break; - case OTG_STATE_A_HOST: - if ((!fsm->a_bus_req || fsm->a_suspend_req) && - fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_SUSPEND); - else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_SUSPEND: - if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); - else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (fsm->a_bus_req || fsm->b_bus_resume) - otg_set_state(fsm, OTG_STATE_A_HOST); - else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_PERIPHERAL: - if (fsm->id || fsm->a_bus_drop) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - else if (fsm->b_bus_suspend) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_WAIT_VFALL: - if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld && - !fsm->b_conn)) - otg_set_state(fsm, OTG_STATE_A_IDLE); - break; - case OTG_STATE_A_VBUS_ERR: - if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - break; - default: - break; - } - spin_unlock_irqrestore(&fsm->lock, flags); - - VDBG("quit statemachine, changed = %d\n", state_changed); - return state_changed; -} diff --git a/drivers/usb/otg/otg_fsm.h b/drivers/usb/otg/otg_fsm.h deleted file mode 100644 index c30a2e1d9e46..000000000000 --- a/drivers/usb/otg/otg_fsm.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * 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. - */ - -#undef DEBUG -#undef VERBOSE - -#ifdef DEBUG -#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt , \ - __func__, ## args) -#else -#define DBG(fmt, args...) do {} while (0) -#endif - -#ifdef VERBOSE -#define VDBG DBG -#else -#define VDBG(stuff...) do {} while (0) -#endif - -#ifdef VERBOSE -#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__) -#else -#define MPC_LOC do {} while (0) -#endif - -#define PROTO_UNDEF (0) -#define PROTO_HOST (1) -#define PROTO_GADGET (2) - -/* OTG state machine according to the OTG spec */ -struct otg_fsm { - /* Input */ - int a_bus_resume; - int a_bus_suspend; - int a_conn; - int a_sess_vld; - int a_srp_det; - int a_vbus_vld; - int b_bus_resume; - int b_bus_suspend; - int b_conn; - int b_se0_srp; - int b_sess_end; - int b_sess_vld; - int id; - - /* Internal variables */ - int a_set_b_hnp_en; - int b_srp_done; - int b_hnp_enable; - - /* Timeout indicator for timers */ - int a_wait_vrise_tmout; - int a_wait_bcon_tmout; - int a_aidl_bdis_tmout; - int b_ase0_brst_tmout; - - /* Informative variables */ - int a_bus_drop; - int a_bus_req; - int a_clr_err; - int a_suspend_req; - int b_bus_req; - - /* Output */ - int drv_vbus; - int loc_conn; - int loc_sof; - - struct otg_fsm_ops *ops; - struct usb_otg *otg; - - /* Current usb protocol used: 0:undefine; 1:host; 2:client */ - int protocol; - spinlock_t lock; -}; - -struct otg_fsm_ops { - void (*chrg_vbus)(int on); - void (*drv_vbus)(int on); - void (*loc_conn)(int on); - void (*loc_sof)(int on); - void (*start_pulse)(void); - void (*add_timer)(void *timer); - void (*del_timer)(void *timer); - int (*start_host)(struct otg_fsm *fsm, int on); - int (*start_gadget)(struct otg_fsm *fsm, int on); -}; - - -static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on) -{ - fsm->ops->chrg_vbus(on); -} - -static inline void otg_drv_vbus(struct otg_fsm *fsm, int on) -{ - if (fsm->drv_vbus != on) { - fsm->drv_vbus = on; - fsm->ops->drv_vbus(on); - } -} - -static inline void otg_loc_conn(struct otg_fsm *fsm, int on) -{ - if (fsm->loc_conn != on) { - fsm->loc_conn = on; - fsm->ops->loc_conn(on); - } -} - -static inline void otg_loc_sof(struct otg_fsm *fsm, int on) -{ - if (fsm->loc_sof != on) { - fsm->loc_sof = on; - fsm->ops->loc_sof(on); - } -} - -static inline void otg_start_pulse(struct otg_fsm *fsm) -{ - fsm->ops->start_pulse(); -} - -static inline void otg_add_timer(struct otg_fsm *fsm, void *timer) -{ - fsm->ops->add_timer(timer); -} - -static inline void otg_del_timer(struct otg_fsm *fsm, void *timer) -{ - fsm->ops->del_timer(timer); -} - -int otg_statemachine(struct otg_fsm *fsm); - -/* Defined by device specific driver, for different timer implementation */ -extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, - *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, - *a_wait_enum_tmr; diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c deleted file mode 100644 index a994715a3101..000000000000 --- a/drivers/usb/otg/twl4030-usb.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller - * - * Copyright (C) 2004-2007 Texas Instruments - * Copyright (C) 2008 Nokia Corporation - * Contact: Felipe Balbi - * - * 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. - * - * Current status: - * - HS USB ULPI mode works. - * - 3-pin mode support may be added in future. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register defines */ - -#define MCPC_CTRL 0x30 -#define MCPC_CTRL_RTSOL (1 << 7) -#define MCPC_CTRL_EXTSWR (1 << 6) -#define MCPC_CTRL_EXTSWC (1 << 5) -#define MCPC_CTRL_VOICESW (1 << 4) -#define MCPC_CTRL_OUT64K (1 << 3) -#define MCPC_CTRL_RTSCTSSW (1 << 2) -#define MCPC_CTRL_HS_UART (1 << 0) - -#define MCPC_IO_CTRL 0x33 -#define MCPC_IO_CTRL_MICBIASEN (1 << 5) -#define MCPC_IO_CTRL_CTS_NPU (1 << 4) -#define MCPC_IO_CTRL_RXD_PU (1 << 3) -#define MCPC_IO_CTRL_TXDTYP (1 << 2) -#define MCPC_IO_CTRL_CTSTYP (1 << 1) -#define MCPC_IO_CTRL_RTSTYP (1 << 0) - -#define MCPC_CTRL2 0x36 -#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) - -#define OTHER_FUNC_CTRL 0x80 -#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) -#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) - -#define OTHER_IFC_CTRL 0x83 -#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) -#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) -#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) -#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) -#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) -#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) - -#define OTHER_INT_EN_RISE 0x86 -#define OTHER_INT_EN_FALL 0x89 -#define OTHER_INT_STS 0x8C -#define OTHER_INT_LATCH 0x8D -#define OTHER_INT_VB_SESS_VLD (1 << 7) -#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ -#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ -#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ -#define OTHER_INT_MANU (1 << 1) -#define OTHER_INT_ABNORMAL_STRESS (1 << 0) - -#define ID_STATUS 0x96 -#define ID_RES_FLOAT (1 << 4) -#define ID_RES_440K (1 << 3) -#define ID_RES_200K (1 << 2) -#define ID_RES_102K (1 << 1) -#define ID_RES_GND (1 << 0) - -#define POWER_CTRL 0xAC -#define POWER_CTRL_OTG_ENAB (1 << 5) - -#define OTHER_IFC_CTRL2 0xAF -#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) -#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) -#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) - -#define REG_CTRL_EN 0xB2 -#define REG_CTRL_ERROR 0xB5 -#define ULPI_I2C_CONFLICT_INTEN (1 << 0) - -#define OTHER_FUNC_CTRL2 0xB8 -#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) - -/* following registers do not have separate _clr and _set registers */ -#define VBUS_DEBOUNCE 0xC0 -#define ID_DEBOUNCE 0xC1 -#define VBAT_TIMER 0xD3 -#define PHY_PWR_CTRL 0xFD -#define PHY_PWR_PHYPWD (1 << 0) -#define PHY_CLK_CTRL 0xFE -#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) -#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) -#define REQ_PHY_DPLL_CLK (1 << 0) -#define PHY_CLK_CTRL_STS 0xFF -#define PHY_DPLL_CLK (1 << 0) - -/* In module TWL_MODULE_PM_MASTER */ -#define STS_HW_CONDITIONS 0x0F - -/* In module TWL_MODULE_PM_RECEIVER */ -#define VUSB_DEDICATED1 0x7D -#define VUSB_DEDICATED2 0x7E -#define VUSB1V5_DEV_GRP 0x71 -#define VUSB1V5_TYPE 0x72 -#define VUSB1V5_REMAP 0x73 -#define VUSB1V8_DEV_GRP 0x74 -#define VUSB1V8_TYPE 0x75 -#define VUSB1V8_REMAP 0x76 -#define VUSB3V1_DEV_GRP 0x77 -#define VUSB3V1_TYPE 0x78 -#define VUSB3V1_REMAP 0x79 - -/* In module TWL4030_MODULE_INTBR */ -#define PMBR1 0x0D -#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) - -struct twl4030_usb { - struct usb_phy phy; - struct device *dev; - - /* TWL4030 internal USB regulator supplies */ - struct regulator *usb1v5; - struct regulator *usb1v8; - struct regulator *usb3v1; - - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - - /* pin configuration */ - enum twl4030_usb_mode usb_mode; - - int irq; - enum omap_musb_vbus_id_status linkstat; - bool vbus_supplied; - u8 asleep; - bool irq_enabled; -}; - -/* internal define on top of container_of */ -#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) - -/*-------------------------------------------------------------------------*/ - -static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, - u8 module, u8 data, u8 address) -{ - u8 check; - - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 1, module, address, check, data); - - /* Failed once: Try again */ - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 2, module, address, check, data); - - /* Failed again: Return error */ - return -EBUSY; -} - -#define twl4030_usb_write_verify(twl, address, data) \ - twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) - -static inline int twl4030_usb_write(struct twl4030_usb *twl, - u8 address, u8 data) -{ - int ret = 0; - - ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); - if (ret < 0) - dev_dbg(twl->dev, - "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); - return ret; -} - -static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) -{ - u8 data; - int ret = 0; - - ret = twl_i2c_read_u8(module, &data, address); - if (ret >= 0) - ret = data; - else - dev_dbg(twl->dev, - "TWL4030:readb[0x%x,0x%x] Error %d\n", - module, address, ret); - - return ret; -} - -static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) -{ - return twl4030_readb(twl, TWL_MODULE_USB, address); -} - -/*-------------------------------------------------------------------------*/ - -static inline int -twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_SET(reg), bits); -} - -static inline int -twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_CLR(reg), bits); -} - -/*-------------------------------------------------------------------------*/ - -static enum omap_musb_vbus_id_status - twl4030_usb_linkstat(struct twl4030_usb *twl) -{ - int status; - enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; - - twl->vbus_supplied = false; - - /* - * For ID/VBUS sensing, see manual section 15.4.8 ... - * except when using only battery backup power, two - * comparators produce VBUS_PRES and ID_PRES signals, - * which don't match docs elsewhere. But ... BIT(7) - * and BIT(2) of STS_HW_CONDITIONS, respectively, do - * seem to match up. If either is true the USB_PRES - * signal is active, the OTG module is activated, and - * its interrupt may be raised (may wake the system). - */ - status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); - if (status < 0) - dev_err(twl->dev, "USB link status err %d\n", status); - else if (status & (BIT(7) | BIT(2))) { - if (status & (BIT(7))) - twl->vbus_supplied = true; - - if (status & BIT(2)) - linkstat = OMAP_MUSB_ID_GROUND; - else - linkstat = OMAP_MUSB_VBUS_VALID; - } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) - linkstat = OMAP_MUSB_VBUS_OFF; - } - - dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", - status, status, linkstat); - - /* REVISIT this assumes host and peripheral controllers - * are registered, and that both are active... - */ - - spin_lock_irq(&twl->lock); - twl->linkstat = linkstat; - spin_unlock_irq(&twl->lock); - - return linkstat; -} - -static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) -{ - twl->usb_mode = mode; - - switch (mode) { - case T2_USB_MODE_ULPI: - twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, - ULPI_IFC_CTRL_CARKITMODE); - twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, - ULPI_FUNC_CTRL_XCVRSEL_MASK | - ULPI_FUNC_CTRL_OPMODE_MASK); - break; - case -1: - /* FIXME: power on defaults */ - break; - default: - dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", - mode); - break; - }; -} - -static void twl4030_i2c_access(struct twl4030_usb *twl, int on) -{ - unsigned long timeout; - int val = twl4030_usb_read(twl, PHY_CLK_CTRL); - - if (val >= 0) { - if (on) { - /* enable DPLL to access PHY registers over I2C */ - val |= REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - - timeout = jiffies + HZ; - while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK) - && time_before(jiffies, timeout)) - udelay(10); - if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK)) - dev_err(twl->dev, "Timeout setting T2 HSUSB " - "PHY DPLL clock\n"); - } else { - /* let ULPI control the DPLL clock */ - val &= ~REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - } - } -} - -static void __twl4030_phy_power(struct twl4030_usb *twl, int on) -{ - u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); - - if (on) - pwr &= ~PHY_PWR_PHYPWD; - else - pwr |= PHY_PWR_PHYPWD; - - WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); -} - -static void twl4030_phy_power(struct twl4030_usb *twl, int on) -{ - if (on) { - regulator_enable(twl->usb3v1); - regulator_enable(twl->usb1v8); - /* - * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP - * in twl4030) resets the VUSB_DEDICATED2 register. This reset - * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to - * SLEEP. We work around this by clearing the bit after usv3v1 - * is re-activated. This ensures that VUSB3V1 is really active. - */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); - regulator_enable(twl->usb1v5); - __twl4030_phy_power(twl, 1); - twl4030_usb_write(twl, PHY_CLK_CTRL, - twl4030_usb_read(twl, PHY_CLK_CTRL) | - (PHY_CLK_CTRL_CLOCKGATING_EN | - PHY_CLK_CTRL_CLK32K_EN)); - } else { - __twl4030_phy_power(twl, 0); - regulator_disable(twl->usb1v5); - regulator_disable(twl->usb1v8); - regulator_disable(twl->usb3v1); - } -} - -static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) -{ - if (twl->asleep) - return; - - twl4030_phy_power(twl, 0); - twl->asleep = 1; - dev_dbg(twl->dev, "%s\n", __func__); -} - -static void __twl4030_phy_resume(struct twl4030_usb *twl) -{ - twl4030_phy_power(twl, 1); - twl4030_i2c_access(twl, 1); - twl4030_usb_set_mode(twl, twl->usb_mode); - if (twl->usb_mode == T2_USB_MODE_ULPI) - twl4030_i2c_access(twl, 0); -} - -static void twl4030_phy_resume(struct twl4030_usb *twl) -{ - if (!twl->asleep) - return; - __twl4030_phy_resume(twl); - twl->asleep = 0; - dev_dbg(twl->dev, "%s\n", __func__); -} - -static int twl4030_usb_ldo_init(struct twl4030_usb *twl) -{ - /* Enable writing to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - - /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ - /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ - - /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); - - /* Initialize 3.1V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); - - twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); - if (IS_ERR(twl->usb3v1)) - return -ENODEV; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); - - /* Initialize 1.5V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); - - twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); - if (IS_ERR(twl->usb1v5)) - goto fail1; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); - - /* Initialize 1.8V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); - - twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); - if (IS_ERR(twl->usb1v8)) - goto fail2; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); - - /* disable access to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - - return 0; - -fail2: - regulator_put(twl->usb1v5); - twl->usb1v5 = NULL; -fail1: - regulator_put(twl->usb3v1); - twl->usb3v1 = NULL; - return -ENODEV; -} - -static ssize_t twl4030_usb_vbus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct twl4030_usb *twl = dev_get_drvdata(dev); - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&twl->lock, flags); - ret = sprintf(buf, "%s\n", - twl->vbus_supplied ? "on" : "off"); - spin_unlock_irqrestore(&twl->lock, flags); - - return ret; -} -static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); - -static irqreturn_t twl4030_usb_irq(int irq, void *_twl) -{ - struct twl4030_usb *twl = _twl; - enum omap_musb_vbus_id_status status; - - status = twl4030_usb_linkstat(twl); - if (status > 0) { - /* FIXME add a set_power() method so that B-devices can - * configure the charger appropriately. It's not always - * correct to consume VBUS power, and how much current to - * consume is a function of the USB configuration chosen - * by the host. - * - * REVISIT usb_gadget_vbus_connect(...) as needed, ditto - * its disconnect() sibling, when changing to/from the - * USB_LINK_VBUS state. musb_hdrc won't care until it - * starts to handle softconnect right. - */ - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) - twl4030_phy_suspend(twl, 0); - else - twl4030_phy_resume(twl); - - omap_musb_mailbox(twl->linkstat); - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); - - return IRQ_HANDLED; -} - -static void twl4030_usb_phy_init(struct twl4030_usb *twl) -{ - enum omap_musb_vbus_id_status status; - - status = twl4030_usb_linkstat(twl); - if (status > 0) { - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) { - __twl4030_phy_power(twl, 0); - twl->asleep = 1; - } else { - __twl4030_phy_resume(twl); - twl->asleep = 0; - } - - omap_musb_mailbox(twl->linkstat); - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -} - -static int twl4030_set_suspend(struct usb_phy *x, int suspend) -{ - struct twl4030_usb *twl = phy_to_twl(x); - - if (suspend) - twl4030_phy_suspend(twl, 1); - else - twl4030_phy_resume(twl); - - return 0; -} - -static int twl4030_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - if (!otg) - return -ENODEV; - - otg->gadget = gadget; - if (!gadget) - otg->phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - otg->host = host; - if (!host) - otg->phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int twl4030_usb_probe(struct platform_device *pdev) -{ - struct twl4030_usb_data *pdata = pdev->dev.platform_data; - struct twl4030_usb *twl; - int status, err; - struct usb_otg *otg; - struct device_node *np = pdev->dev.of_node; - - twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); - if (!twl) - return -ENOMEM; - - if (np) - of_property_read_u32(np, "usb_mode", - (enum twl4030_usb_mode *)&twl->usb_mode); - else if (pdata) - twl->usb_mode = pdata->usb_mode; - else { - dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); - return -EINVAL; - } - - otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); - if (!otg) - return -ENOMEM; - - twl->dev = &pdev->dev; - twl->irq = platform_get_irq(pdev, 0); - twl->vbus_supplied = false; - twl->asleep = 1; - twl->linkstat = OMAP_MUSB_UNKNOWN; - - twl->phy.dev = twl->dev; - twl->phy.label = "twl4030"; - twl->phy.otg = otg; - twl->phy.type = USB_PHY_TYPE_USB2; - twl->phy.set_suspend = twl4030_set_suspend; - - otg->phy = &twl->phy; - otg->set_host = twl4030_set_host; - otg->set_peripheral = twl4030_set_peripheral; - - /* init spinlock for workqueue */ - spin_lock_init(&twl->lock); - - err = twl4030_usb_ldo_init(twl); - if (err) { - dev_err(&pdev->dev, "ldo init failed\n"); - return err; - } - usb_add_phy_dev(&twl->phy); - - platform_set_drvdata(pdev, twl); - if (device_create_file(&pdev->dev, &dev_attr_vbus)) - dev_warn(&pdev->dev, "could not create sysfs file\n"); - - /* Our job is to use irqs and status from the power module - * to keep the transceiver disabled when nothing's connected. - * - * FIXME we actually shouldn't start enabling it until the - * USB controller drivers have said they're ready, by calling - * set_host() and/or set_peripheral() ... OTG_capable boards - * need both handles, otherwise just one suffices. - */ - twl->irq_enabled = true; - status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "twl4030_usb", twl); - if (status < 0) { - dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq, status); - return status; - } - - /* Power down phy or make it work according to - * current link state. - */ - twl4030_usb_phy_init(twl); - - dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); - return 0; -} - -static int __exit twl4030_usb_remove(struct platform_device *pdev) -{ - struct twl4030_usb *twl = platform_get_drvdata(pdev); - int val; - - free_irq(twl->irq, twl); - device_remove_file(twl->dev, &dev_attr_vbus); - - /* set transceiver mode to power on defaults */ - twl4030_usb_set_mode(twl, -1); - - /* autogate 60MHz ULPI clock, - * clear dpll clock request for i2c access, - * disable 32KHz - */ - val = twl4030_usb_read(twl, PHY_CLK_CTRL); - if (val >= 0) { - val |= PHY_CLK_CTRL_CLOCKGATING_EN; - val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); - twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); - } - - /* disable complete OTG block */ - twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - - if (!twl->asleep) - twl4030_phy_power(twl, 0); - regulator_put(twl->usb1v5); - regulator_put(twl->usb1v8); - regulator_put(twl->usb3v1); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id twl4030_usb_id_table[] = { - { .compatible = "ti,twl4030-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); -#endif - -static struct platform_driver twl4030_usb_driver = { - .probe = twl4030_usb_probe, - .remove = __exit_p(twl4030_usb_remove), - .driver = { - .name = "twl4030_usb", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(twl4030_usb_id_table), - }, -}; - -static int __init twl4030_usb_init(void) -{ - return platform_driver_register(&twl4030_usb_driver); -} -subsys_initcall(twl4030_usb_init); - -static void __exit twl4030_usb_exit(void) -{ - platform_driver_unregister(&twl4030_usb_driver); -} -module_exit(twl4030_usb_exit); - -MODULE_ALIAS("platform:twl4030_usb"); -MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); -MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c deleted file mode 100644 index 8cd6cf49bdbd..000000000000 --- a/drivers/usb/otg/twl6030-usb.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Hema HK - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 - -/* usb register definitions */ -#define USB_VENDOR_ID_LSB 0x00 -#define USB_VENDOR_ID_MSB 0x01 -#define USB_PRODUCT_ID_LSB 0x02 -#define USB_PRODUCT_ID_MSB 0x03 -#define USB_VBUS_CTRL_SET 0x04 -#define USB_VBUS_CTRL_CLR 0x05 -#define USB_ID_CTRL_SET 0x06 -#define USB_ID_CTRL_CLR 0x07 -#define USB_VBUS_INT_SRC 0x08 -#define USB_VBUS_INT_LATCH_SET 0x09 -#define USB_VBUS_INT_LATCH_CLR 0x0A -#define USB_VBUS_INT_EN_LO_SET 0x0B -#define USB_VBUS_INT_EN_LO_CLR 0x0C -#define USB_VBUS_INT_EN_HI_SET 0x0D -#define USB_VBUS_INT_EN_HI_CLR 0x0E -#define USB_ID_INT_SRC 0x0F -#define USB_ID_INT_LATCH_SET 0x10 -#define USB_ID_INT_LATCH_CLR 0x11 - -#define USB_ID_INT_EN_LO_SET 0x12 -#define USB_ID_INT_EN_LO_CLR 0x13 -#define USB_ID_INT_EN_HI_SET 0x14 -#define USB_ID_INT_EN_HI_CLR 0x15 -#define USB_OTG_ADP_CTRL 0x16 -#define USB_OTG_ADP_HIGH 0x17 -#define USB_OTG_ADP_LOW 0x18 -#define USB_OTG_ADP_RISE 0x19 -#define USB_OTG_REVISION 0x1A - -/* to be moved to LDO */ -#define TWL6030_MISC2 0xE5 -#define TWL6030_CFG_LDO_PD2 0xF5 -#define TWL6030_BACKUP_REG 0xFA - -#define STS_HW_CONDITIONS 0x21 - -/* In module TWL6030_MODULE_PM_MASTER */ -#define STS_HW_CONDITIONS 0x21 -#define STS_USB_ID BIT(2) - -/* In module TWL6030_MODULE_PM_RECEIVER */ -#define VUSB_CFG_TRANS 0x71 -#define VUSB_CFG_STATE 0x72 -#define VUSB_CFG_VOLTAGE 0x73 - -/* in module TWL6030_MODULE_MAIN_CHARGE */ - -#define CHARGERUSB_CTRL1 0x8 - -#define CONTROLLER_STAT1 0x03 -#define VBUS_DET BIT(2) - -struct twl6030_usb { - struct phy_companion comparator; - struct device *dev; - - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - - struct regulator *usb3v3; - - /* used to set vbus, in atomic path */ - struct work_struct set_vbus_work; - - int irq1; - int irq2; - enum omap_musb_vbus_id_status linkstat; - u8 asleep; - bool irq_enabled; - bool vbus_enable; - const char *regulator; -}; - -#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator) - -/*-------------------------------------------------------------------------*/ - -static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module, - u8 data, u8 address) -{ - int ret = 0; - - ret = twl_i2c_write_u8(module, data, address); - if (ret < 0) - dev_err(twl->dev, - "Write[0x%x] Error %d\n", address, ret); - return ret; -} - -static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address) -{ - u8 data, ret = 0; - - ret = twl_i2c_read_u8(module, &data, address); - if (ret >= 0) - ret = data; - else - dev_err(twl->dev, - "readb[0x%x,0x%x] Error %d\n", - module, address, ret); - return ret; -} - -static int twl6030_start_srp(struct phy_companion *comparator) -{ - struct twl6030_usb *twl = comparator_to_twl(comparator); - - twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); - twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); - - mdelay(100); - twl6030_writeb(twl, TWL_MODULE_USB, 0xa0, USB_VBUS_CTRL_CLR); - - return 0; -} - -static int twl6030_usb_ldo_init(struct twl6030_usb *twl) -{ - /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); - - /* Program CFG_LDO_PD2 register and set VUSB bit */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2); - - /* Program MISC2 register and set bit VUSB_IN_VBAT */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); - - twl->usb3v3 = regulator_get(twl->dev, twl->regulator); - if (IS_ERR(twl->usb3v3)) - return -ENODEV; - - /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ - twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); - - /* - * Program the USB_ID_CTRL_SET register to enable GND drive - * and the ID comparators - */ - twl6030_writeb(twl, TWL_MODULE_USB, 0x14, USB_ID_CTRL_SET); - - return 0; -} - -static ssize_t twl6030_usb_vbus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct twl6030_usb *twl = dev_get_drvdata(dev); - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&twl->lock, flags); - - switch (twl->linkstat) { - case OMAP_MUSB_VBUS_VALID: - ret = snprintf(buf, PAGE_SIZE, "vbus\n"); - break; - case OMAP_MUSB_ID_GROUND: - ret = snprintf(buf, PAGE_SIZE, "id\n"); - break; - case OMAP_MUSB_VBUS_OFF: - ret = snprintf(buf, PAGE_SIZE, "none\n"); - break; - default: - ret = snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); - } - spin_unlock_irqrestore(&twl->lock, flags); - - return ret; -} -static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); - -static irqreturn_t twl6030_usb_irq(int irq, void *_twl) -{ - struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; - u8 vbus_state, hw_state; - - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); - - vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, - CONTROLLER_STAT1); - if (!(hw_state & STS_USB_ID)) { - if (vbus_state & VBUS_DET) { - regulator_enable(twl->usb3v3); - twl->asleep = 1; - status = OMAP_MUSB_VBUS_VALID; - twl->linkstat = status; - omap_musb_mailbox(status); - } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) { - status = OMAP_MUSB_VBUS_OFF; - twl->linkstat = status; - omap_musb_mailbox(status); - if (twl->asleep) { - regulator_disable(twl->usb3v3); - twl->asleep = 0; - } - } - } - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); - - return IRQ_HANDLED; -} - -static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) -{ - struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; - u8 hw_state; - - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); - - if (hw_state & STS_USB_ID) { - - regulator_enable(twl->usb3v3); - twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); - status = OMAP_MUSB_ID_GROUND; - twl->linkstat = status; - omap_musb_mailbox(status); - } else { - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); - } - twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); - - return IRQ_HANDLED; -} - -static int twl6030_enable_irq(struct twl6030_usb *twl) -{ - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); - twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); - twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); - - twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, - REG_INT_MSK_LINE_C); - twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, - REG_INT_MSK_STS_C); - twl6030_usb_irq(twl->irq2, twl); - twl6030_usbotg_irq(twl->irq1, twl); - - return 0; -} - -static void otg_set_vbus_work(struct work_struct *data) -{ - struct twl6030_usb *twl = container_of(data, struct twl6030_usb, - set_vbus_work); - - /* - * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 - * register. This enables boost mode. - */ - - if (twl->vbus_enable) - twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, - CHARGERUSB_CTRL1); - else - twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, - CHARGERUSB_CTRL1); -} - -static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) -{ - struct twl6030_usb *twl = comparator_to_twl(comparator); - - twl->vbus_enable = enabled; - schedule_work(&twl->set_vbus_work); - - return 0; -} - -static int twl6030_usb_probe(struct platform_device *pdev) -{ - u32 ret; - struct twl6030_usb *twl; - int status, err; - struct device_node *np = pdev->dev.of_node; - struct device *dev = &pdev->dev; - struct twl4030_usb_data *pdata = dev->platform_data; - - twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); - if (!twl) - return -ENOMEM; - - twl->dev = &pdev->dev; - twl->irq1 = platform_get_irq(pdev, 0); - twl->irq2 = platform_get_irq(pdev, 1); - twl->linkstat = OMAP_MUSB_UNKNOWN; - - twl->comparator.set_vbus = twl6030_set_vbus; - twl->comparator.start_srp = twl6030_start_srp; - - ret = omap_usb2_set_comparator(&twl->comparator); - if (ret == -ENODEV) { - dev_info(&pdev->dev, "phy not ready, deferring probe"); - return -EPROBE_DEFER; - } - - if (np) { - twl->regulator = "usb"; - } else if (pdata) { - if (pdata->features & TWL6025_SUBCLASS) - twl->regulator = "ldousb"; - else - twl->regulator = "vusb"; - } else { - dev_err(&pdev->dev, "twl6030 initialized without pdata\n"); - return -EINVAL; - } - - /* init spinlock for workqueue */ - spin_lock_init(&twl->lock); - - err = twl6030_usb_ldo_init(twl); - if (err) { - dev_err(&pdev->dev, "ldo init failed\n"); - return err; - } - - platform_set_drvdata(pdev, twl); - if (device_create_file(&pdev->dev, &dev_attr_vbus)) - dev_warn(&pdev->dev, "could not create sysfs file\n"); - - INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); - - twl->irq_enabled = true; - status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "twl6030_usb", twl); - if (status < 0) { - dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq1, status); - device_remove_file(twl->dev, &dev_attr_vbus); - return status; - } - - status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "twl6030_usb", twl); - if (status < 0) { - dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq2, status); - free_irq(twl->irq1, twl); - device_remove_file(twl->dev, &dev_attr_vbus); - return status; - } - - twl->asleep = 0; - twl6030_enable_irq(twl); - dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); - - return 0; -} - -static int __exit twl6030_usb_remove(struct platform_device *pdev) -{ - struct twl6030_usb *twl = platform_get_drvdata(pdev); - - twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, - REG_INT_MSK_LINE_C); - twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, - REG_INT_MSK_STS_C); - free_irq(twl->irq1, twl); - free_irq(twl->irq2, twl); - regulator_put(twl->usb3v3); - device_remove_file(twl->dev, &dev_attr_vbus); - cancel_work_sync(&twl->set_vbus_work); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id twl6030_usb_id_table[] = { - { .compatible = "ti,twl6030-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); -#endif - -static struct platform_driver twl6030_usb_driver = { - .probe = twl6030_usb_probe, - .remove = __exit_p(twl6030_usb_remove), - .driver = { - .name = "twl6030_usb", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(twl6030_usb_id_table), - }, -}; - -static int __init twl6030_usb_init(void) -{ - return platform_driver_register(&twl6030_usb_driver); -} -subsys_initcall(twl6030_usb_init); - -static void __exit twl6030_usb_exit(void) -{ - platform_driver_unregister(&twl6030_usb_driver); -} -module_exit(twl6030_usb_exit); - -MODULE_ALIAS("platform:twl6030_usb"); -MODULE_AUTHOR("Hema HK "); -MODULE_DESCRIPTION("TWL6030 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c deleted file mode 100644 index 217339dd7a90..000000000000 --- a/drivers/usb/otg/ulpi.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Generic ULPI USB transceiver support - * - * Copyright (C) 2009 Daniel Mack - * - * Based on sources from - * - * Sascha Hauer - * Freescale Semiconductors - * - * 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 - - -struct ulpi_info { - unsigned int id; - char *name; -}; - -#define ULPI_ID(vendor, product) (((vendor) << 16) | (product)) -#define ULPI_INFO(_id, _name) \ - { \ - .id = (_id), \ - .name = (_name), \ - } - -/* ULPI hardcoded IDs, used for probing */ -static struct ulpi_info ulpi_ids[] = { - ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), - ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), -}; - -static int ulpi_set_otg_flags(struct usb_phy *phy) -{ - unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN | - ULPI_OTG_CTRL_DM_PULLDOWN; - - if (phy->flags & ULPI_OTG_ID_PULLUP) - flags |= ULPI_OTG_CTRL_ID_PULLUP; - - /* - * ULPI Specification rev.1.1 default - * for Dp/DmPulldown is enabled. - */ - if (phy->flags & ULPI_OTG_DP_PULLDOWN_DIS) - flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN; - - if (phy->flags & ULPI_OTG_DM_PULLDOWN_DIS) - flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN; - - if (phy->flags & ULPI_OTG_EXTVBUSIND) - flags |= ULPI_OTG_CTRL_EXTVBUSIND; - - return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); -} - -static int ulpi_set_fc_flags(struct usb_phy *phy) -{ - unsigned int flags = 0; - - /* - * ULPI Specification rev.1.1 default - * for XcvrSelect is Full Speed. - */ - if (phy->flags & ULPI_FC_HS) - flags |= ULPI_FUNC_CTRL_HIGH_SPEED; - else if (phy->flags & ULPI_FC_LS) - flags |= ULPI_FUNC_CTRL_LOW_SPEED; - else if (phy->flags & ULPI_FC_FS4LS) - flags |= ULPI_FUNC_CTRL_FS4LS; - else - flags |= ULPI_FUNC_CTRL_FULL_SPEED; - - if (phy->flags & ULPI_FC_TERMSEL) - flags |= ULPI_FUNC_CTRL_TERMSELECT; - - /* - * ULPI Specification rev.1.1 default - * for OpMode is Normal Operation. - */ - if (phy->flags & ULPI_FC_OP_NODRV) - flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - else if (phy->flags & ULPI_FC_OP_DIS_NRZI) - flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI; - else if (phy->flags & ULPI_FC_OP_NSYNC_NEOP) - flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP; - else - flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL; - - /* - * ULPI Specification rev.1.1 default - * for SuspendM is Powered. - */ - flags |= ULPI_FUNC_CTRL_SUSPENDM; - - return usb_phy_io_write(phy, flags, ULPI_FUNC_CTRL); -} - -static int ulpi_set_ic_flags(struct usb_phy *phy) -{ - unsigned int flags = 0; - - if (phy->flags & ULPI_IC_AUTORESUME) - flags |= ULPI_IFC_CTRL_AUTORESUME; - - if (phy->flags & ULPI_IC_EXTVBUS_INDINV) - flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS; - - if (phy->flags & ULPI_IC_IND_PASSTHRU) - flags |= ULPI_IFC_CTRL_PASSTHRU; - - if (phy->flags & ULPI_IC_PROTECT_DIS) - flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE; - - return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); -} - -static int ulpi_set_flags(struct usb_phy *phy) -{ - int ret; - - ret = ulpi_set_otg_flags(phy); - if (ret) - return ret; - - ret = ulpi_set_ic_flags(phy); - if (ret) - return ret; - - return ulpi_set_fc_flags(phy); -} - -static int ulpi_check_integrity(struct usb_phy *phy) -{ - int ret, i; - unsigned int val = 0x55; - - for (i = 0; i < 2; i++) { - ret = usb_phy_io_write(phy, val, ULPI_SCRATCH); - if (ret < 0) - return ret; - - ret = usb_phy_io_read(phy, ULPI_SCRATCH); - if (ret < 0) - return ret; - - if (ret != val) { - pr_err("ULPI integrity check: failed!"); - return -ENODEV; - } - val = val << 1; - } - - pr_info("ULPI integrity check: passed.\n"); - - return 0; -} - -static int ulpi_init(struct usb_phy *phy) -{ - int i, vid, pid, ret; - u32 ulpi_id = 0; - - for (i = 0; i < 4; i++) { - ret = usb_phy_io_read(phy, ULPI_PRODUCT_ID_HIGH - i); - if (ret < 0) - return ret; - ulpi_id = (ulpi_id << 8) | ret; - } - vid = ulpi_id & 0xffff; - pid = ulpi_id >> 16; - - pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); - - for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) { - if (ulpi_ids[i].id == ULPI_ID(vid, pid)) { - pr_info("Found %s ULPI transceiver.\n", - ulpi_ids[i].name); - break; - } - } - - ret = ulpi_check_integrity(phy); - if (ret) - return ret; - - return ulpi_set_flags(phy); -} - -static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct usb_phy *phy = otg->phy; - unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); - - if (!host) { - otg->host = NULL; - return 0; - } - - otg->host = host; - - flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE | - ULPI_IFC_CTRL_3_PIN_SERIAL_MODE | - ULPI_IFC_CTRL_CARKITMODE); - - if (phy->flags & ULPI_IC_6PIN_SERIAL) - flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE; - else if (phy->flags & ULPI_IC_3PIN_SERIAL) - flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE; - else if (phy->flags & ULPI_IC_CARKIT) - flags |= ULPI_IFC_CTRL_CARKITMODE; - - return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); -} - -static int ulpi_set_vbus(struct usb_otg *otg, bool on) -{ - struct usb_phy *phy = otg->phy; - unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); - - flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); - - if (on) { - if (phy->flags & ULPI_OTG_DRVVBUS) - flags |= ULPI_OTG_CTRL_DRVVBUS; - - if (phy->flags & ULPI_OTG_DRVVBUS_EXT) - flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; - } - - return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); -} - -struct usb_phy * -otg_ulpi_create(struct usb_phy_io_ops *ops, - unsigned int flags) -{ - struct usb_phy *phy; - struct usb_otg *otg; - - phy = kzalloc(sizeof(*phy), GFP_KERNEL); - if (!phy) - return NULL; - - otg = kzalloc(sizeof(*otg), GFP_KERNEL); - if (!otg) { - kfree(phy); - return NULL; - } - - phy->label = "ULPI"; - phy->flags = flags; - phy->io_ops = ops; - phy->otg = otg; - phy->init = ulpi_init; - - otg->phy = phy; - otg->set_host = ulpi_set_host; - otg->set_vbus = ulpi_set_vbus; - - return phy; -} -EXPORT_SYMBOL_GPL(otg_ulpi_create); - diff --git a/drivers/usb/otg/ulpi_viewport.c b/drivers/usb/otg/ulpi_viewport.c deleted file mode 100644 index c5ba7e5423fc..000000000000 --- a/drivers/usb/otg/ulpi_viewport.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011 Google, Inc. - * - * 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 - -#define ULPI_VIEW_WAKEUP (1 << 31) -#define ULPI_VIEW_RUN (1 << 30) -#define ULPI_VIEW_WRITE (1 << 29) -#define ULPI_VIEW_READ (0 << 29) -#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) -#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) -#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) - -static int ulpi_viewport_wait(void __iomem *view, u32 mask) -{ - unsigned long usec = 2000; - - while (usec--) { - if (!(readl(view) & mask)) - return 0; - - udelay(1); - }; - - return -ETIMEDOUT; -} - -static int ulpi_viewport_read(struct usb_phy *otg, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); - if (ret) - return ret; - - return ULPI_VIEW_DATA_READ(readl(view)); -} - -static int ulpi_viewport_write(struct usb_phy *otg, u32 val, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | - ULPI_VIEW_ADDR(reg), view); - - return ulpi_viewport_wait(view, ULPI_VIEW_RUN); -} - -struct usb_phy_io_ops ulpi_viewport_access_ops = { - .read = ulpi_viewport_read, - .write = ulpi_viewport_write, -}; diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 65217a590068..32ce740a9dd5 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -4,6 +4,73 @@ comment "USB Physical Layer drivers" depends on USB || USB_GADGET +config USB_OTG_UTILS + bool + help + Select this to make sure the build includes objects from + the OTG infrastructure directory. + +if USB || USB_GADGET + +# +# USB Transceiver Drivers +# +config AB8500_USB + tristate "AB8500 USB Transceiver Driver" + depends on AB8500_CORE + select USB_OTG_UTILS + help + Enable this to support the USB OTG transceiver in AB8500 chip. + This transceiver supports high and full speed devices plus, + in host mode, low speed. + +config FSL_USB2_OTG + bool "Freescale USB OTG Transceiver Driver" + depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND + select USB_OTG + select USB_OTG_UTILS + help + Enable this to support Freescale USB OTG transceiver. + +config ISP1301_OMAP + tristate "Philips ISP1301 with OMAP OTG" + depends on I2C && ARCH_OMAP_OTG + select USB_OTG_UTILS + help + If you say yes here you get support for the Philips ISP1301 + USB-On-The-Go transceiver working with the OMAP OTG controller. + The ISP1301 is a full speed USB transceiver which is used in + products including H2, H3, and H4 development boards for Texas + Instruments OMAP processors. + + This driver can also be built as a module. If so, the module + will be called isp1301_omap. + +config MV_U3D_PHY + bool "Marvell USB 3.0 PHY controller Driver" + depends on USB_MV_U3D + select USB_OTG_UTILS + help + Enable this to support Marvell USB 3.0 phy controller for Marvell + SoC. + +config NOP_USB_XCEIV + tristate "NOP USB Transceiver Driver" + select USB_OTG_UTILS + help + This driver is to be used by all the usb transceiver which are either + built-in with usb ip or which are autonomous and doesn't require any + phy programming such as ISP1x04 etc. + +config OMAP_CONTROL_USB + tristate "OMAP CONTROL USB Driver" + help + Enable this to add support for the USB part present in the control + module. This driver has API to power on the USB2 PHY and to write to + the mailbox. The mailbox is present only in omap4 and the register to + power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an + additional register to power on USB3 PHY. + config OMAP_USB2 tristate "OMAP USB2 PHY Driver" depends on ARCH_OMAP2PLUS @@ -25,14 +92,45 @@ config OMAP_USB3 This driver interacts with the "OMAP Control USB Driver" to power on/off the PHY. -config OMAP_CONTROL_USB - tristate "OMAP CONTROL USB Driver" +config SAMSUNG_USBPHY + bool "Samsung USB PHY controller Driver" + depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS + select USB_OTG_UTILS help - Enable this to add support for the USB part present in the control - module. This driver has API to power on the USB2 PHY and to write to - the mailbox. The mailbox is present only in omap4 and the register to - power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an - additional register to power on USB3 PHY. + Enable this to support Samsung USB phy controller for samsung + SoCs. + +config TWL4030_USB + tristate "TWL4030 USB Transceiver Driver" + depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS + select USB_OTG_UTILS + help + Enable this to support the USB OTG transceiver on TWL4030 + family chips (including the TWL5030 and TPS659x0 devices). + This transceiver supports high and full speed devices plus, + in host mode, low speed. + +config TWL6030_USB + tristate "TWL6030 USB Transceiver Driver" + depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS + select USB_OTG_UTILS + help + Enable this to support the USB OTG transceiver on TWL6030 + family chips. This TWL6030 transceiver has the VBUS and ID GND + and OTG SRP events capabilities. For all other transceiver functionality + UTMI PHY is embedded in OMAP4430. The internal PHY configurations APIs + are hooked to this driver through platform_data structure. + The definition of internal PHY APIs are in the mach-omap2 layer. + +config USB_GPIO_VBUS + tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" + depends on GENERIC_GPIO + select USB_OTG_UTILS + help + Provides simple GPIO VBUS sensing for controllers with an + internal transceiver via the usb_phy interface, and + optionally control of a D+ pullup GPIO as well as a VBUS + current limit regulator. config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" @@ -46,13 +144,40 @@ config USB_ISP1301 To compile this driver as a module, choose M here: the module will be called isp1301. -config MV_U3D_PHY - bool "Marvell USB 3.0 PHY controller Driver" - depends on USB_MV_U3D +config USB_MSM_OTG + tristate "OTG support for Qualcomm on-chip USB controller" + depends on (USB || USB_GADGET) && ARCH_MSM select USB_OTG_UTILS help - Enable this to support Marvell USB 3.0 phy controller for Marvell - SoC. + Enable this to support the USB OTG transceiver on MSM chips. It + handles PHY initialization, clock management, and workarounds + required after resetting the hardware and power management. + This driver is required even for peripheral only or host only + mode configurations. + This driver is not supported on boards like trout which + has an external PHY. + +config USB_MV_OTG + tristate "Marvell USB OTG support" + depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND + select USB_OTG + select USB_OTG_UTILS + help + Say Y here if you want to build Marvell USB OTG transciever + driver in kernel (including PXA and MMP series). This driver + implements role switch between EHCI host driver and gadget driver. + + To compile this driver as a module, choose M here. + +config USB_MXS_PHY + tristate "Freescale MXS USB PHY support" + depends on ARCH_MXC || ARCH_MXS + select STMP_DEVICE + select USB_OTG_UTILS + help + Enable this to support the Freescale MXS USB PHY. + + MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. config USB_RCAR_PHY tristate "Renesas R-Car USB phy support" @@ -66,10 +191,19 @@ config USB_RCAR_PHY To compile this driver as a module, choose M here: the module will be called rcar-phy. -config SAMSUNG_USBPHY - bool "Samsung USB PHY controller Driver" - depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS +config USB_ULPI + bool "Generic ULPI Transceiver Driver" + depends on ARM select USB_OTG_UTILS help - Enable this to support Samsung USB phy controller for samsung - SoCs. + Enable this to support ULPI connected USB OTG transceivers which + are likely found on embedded boards. + +config USB_ULPI_VIEWPORT + bool + depends on USB_ULPI + help + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + +endif # USB || OTG diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 9fa6327d4c52..34488ceef491 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -5,11 +5,27 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG obj-$(CONFIG_USB_OTG_UTILS) += phy.o + +# transceiver drivers, keep the list sorted + +obj-$(CONFIG_AB8500_USB) += ab8500-usb.o +fsl_usb2_otg-objs := fsl_otg.o otg_fsm.o +obj-$(CONFIG_FSL_USB2_OTG) += fsl_usb2_otg.o +obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o +obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o +obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o +obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o obj-$(CONFIG_OMAP_USB2) += omap-usb2.o obj-$(CONFIG_OMAP_USB3) += omap-usb3.o -obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o +obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o +obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o +obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o +obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o +obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_USB_ISP1301) += isp1301.o -obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o -obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o +obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o +obj-$(CONFIG_USB_MV_OTG) += mv_otg.o +obj-$(CONFIG_USB_MXS_PHY) += mxs-phy.o obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o -obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o +obj-$(CONFIG_USB_ULPI) += ulpi.o +obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o diff --git a/drivers/usb/phy/ab8500-usb.c b/drivers/usb/phy/ab8500-usb.c new file mode 100644 index 000000000000..2d86f26a0183 --- /dev/null +++ b/drivers/usb/phy/ab8500-usb.c @@ -0,0 +1,596 @@ +/* + * drivers/usb/otg/ab8500_usb.c + * + * USB transceiver driver for AB8500 chip + * + * Copyright (C) 2010 ST-Ericsson AB + * Mian Yousaf Kaukab + * + * 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 + +#define AB8500_MAIN_WD_CTRL_REG 0x01 +#define AB8500_USB_LINE_STAT_REG 0x80 +#define AB8500_USB_PHY_CTRL_REG 0x8A + +#define AB8500_BIT_OTG_STAT_ID (1 << 0) +#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) +#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) +#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) +#define AB8500_BIT_WD_CTRL_KICK (1 << 1) + +#define AB8500_V1x_LINK_STAT_WAIT (HZ/10) +#define AB8500_WD_KICK_DELAY_US 100 /* usec */ +#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ +#define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ + +/* Usb line status register */ +enum ab8500_usb_link_status { + USB_LINK_NOT_CONFIGURED = 0, + USB_LINK_STD_HOST_NC, + USB_LINK_STD_HOST_C_NS, + USB_LINK_STD_HOST_C_S, + USB_LINK_HOST_CHG_NM, + USB_LINK_HOST_CHG_HS, + USB_LINK_HOST_CHG_HS_CHIRP, + USB_LINK_DEDICATED_CHG, + USB_LINK_ACA_RID_A, + USB_LINK_ACA_RID_B, + USB_LINK_ACA_RID_C_NM, + USB_LINK_ACA_RID_C_HS, + USB_LINK_ACA_RID_C_HS_CHIRP, + USB_LINK_HM_IDGND, + USB_LINK_RESERVED, + USB_LINK_NOT_VALID_LINK +}; + +struct ab8500_usb { + struct usb_phy phy; + struct device *dev; + int irq_num_id_rise; + int irq_num_id_fall; + int irq_num_vbus_rise; + int irq_num_vbus_fall; + int irq_num_link_status; + unsigned vbus_draw; + struct delayed_work dwork; + struct work_struct phy_dis_work; + unsigned long link_status_wait; + int rev; +}; + +static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) +{ + return container_of(x, struct ab8500_usb, phy); +} + +static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) +{ + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + AB8500_BIT_WD_CTRL_ENABLE); + + udelay(AB8500_WD_KICK_DELAY_US); + + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + (AB8500_BIT_WD_CTRL_ENABLE + | AB8500_BIT_WD_CTRL_KICK)); + + if (ab->rev > 0x10) /* v1.1 v2.0 */ + udelay(AB8500_WD_V11_DISABLE_DELAY_US); + else /* v1.0 */ + msleep(AB8500_WD_V10_DISABLE_DELAY_MS); + + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + 0); +} + +static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, + bool enable) +{ + u8 ctrl_reg; + abx500_get_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_PHY_CTRL_REG, + &ctrl_reg); + if (sel_host) { + if (enable) + ctrl_reg |= AB8500_BIT_PHY_CTRL_HOST_EN; + else + ctrl_reg &= ~AB8500_BIT_PHY_CTRL_HOST_EN; + } else { + if (enable) + ctrl_reg |= AB8500_BIT_PHY_CTRL_DEVICE_EN; + else + ctrl_reg &= ~AB8500_BIT_PHY_CTRL_DEVICE_EN; + } + + abx500_set_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_PHY_CTRL_REG, + ctrl_reg); + + /* Needed to enable the phy.*/ + if (enable) + ab8500_usb_wd_workaround(ab); +} + +#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_ctrl(ab, true, true) +#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_ctrl(ab, true, false) +#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) +#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) + +static int ab8500_usb_link_status_update(struct ab8500_usb *ab) +{ + u8 reg; + enum ab8500_usb_link_status lsts; + void *v = NULL; + enum usb_phy_events event; + + abx500_get_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_LINE_STAT_REG, + ®); + + lsts = (reg >> 3) & 0x0F; + + switch (lsts) { + case USB_LINK_NOT_CONFIGURED: + case USB_LINK_RESERVED: + case USB_LINK_NOT_VALID_LINK: + /* TODO: Disable regulators. */ + ab8500_usb_host_phy_dis(ab); + ab8500_usb_peri_phy_dis(ab); + ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->default_a = false; + ab->vbus_draw = 0; + event = USB_EVENT_NONE; + break; + + case USB_LINK_STD_HOST_NC: + case USB_LINK_STD_HOST_C_NS: + case USB_LINK_STD_HOST_C_S: + case USB_LINK_HOST_CHG_NM: + case USB_LINK_HOST_CHG_HS: + case USB_LINK_HOST_CHG_HS_CHIRP: + if (ab->phy.otg->gadget) { + /* TODO: Enable regulators. */ + ab8500_usb_peri_phy_en(ab); + v = ab->phy.otg->gadget; + } + event = USB_EVENT_VBUS; + break; + + case USB_LINK_HM_IDGND: + if (ab->phy.otg->host) { + /* TODO: Enable regulators. */ + ab8500_usb_host_phy_en(ab); + v = ab->phy.otg->host; + } + ab->phy.state = OTG_STATE_A_IDLE; + ab->phy.otg->default_a = true; + event = USB_EVENT_ID; + break; + + case USB_LINK_ACA_RID_A: + case USB_LINK_ACA_RID_B: + /* TODO */ + case USB_LINK_ACA_RID_C_NM: + case USB_LINK_ACA_RID_C_HS: + case USB_LINK_ACA_RID_C_HS_CHIRP: + case USB_LINK_DEDICATED_CHG: + /* TODO: vbus_draw */ + event = USB_EVENT_CHARGER; + break; + } + + atomic_notifier_call_chain(&ab->phy.notifier, event, v); + + return 0; +} + +static void ab8500_usb_delayed_work(struct work_struct *work) +{ + struct ab8500_usb *ab = container_of(work, struct ab8500_usb, + dwork.work); + + ab8500_usb_link_status_update(ab); +} + +static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + /* Wait for link status to become stable. */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + + return IRQ_HANDLED; +} + +static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + /* Link status will not be updated till phy is disabled. */ + ab8500_usb_peri_phy_dis(ab); + + /* Wait for link status to become stable. */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + + return IRQ_HANDLED; +} + +static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + ab8500_usb_link_status_update(ab); + + return IRQ_HANDLED; +} + +static void ab8500_usb_phy_disable_work(struct work_struct *work) +{ + struct ab8500_usb *ab = container_of(work, struct ab8500_usb, + phy_dis_work); + + if (!ab->phy.otg->host) + ab8500_usb_host_phy_dis(ab); + + if (!ab->phy.otg->gadget) + ab8500_usb_peri_phy_dis(ab); +} + +static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) +{ + struct ab8500_usb *ab; + + if (!phy) + return -ENODEV; + + ab = phy_to_ab(phy); + + ab->vbus_draw = mA; + + if (mA) + atomic_notifier_call_chain(&ab->phy.notifier, + USB_EVENT_ENUMERATED, ab->phy.otg->gadget); + return 0; +} + +/* TODO: Implement some way for charging or other drivers to read + * ab->vbus_draw. + */ + +static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) +{ + /* TODO */ + return 0; +} + +static int ab8500_usb_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct ab8500_usb *ab; + + if (!otg) + return -ENODEV; + + ab = phy_to_ab(otg->phy); + + /* Some drivers call this function in atomic context. + * Do not update ab8500 registers directly till this + * is fixed. + */ + + if (!gadget) { + /* TODO: Disable regulators. */ + otg->gadget = NULL; + schedule_work(&ab->phy_dis_work); + } else { + otg->gadget = gadget; + otg->phy->state = OTG_STATE_B_IDLE; + + /* Phy will not be enabled if cable is already + * plugged-in. Schedule to enable phy. + * Use same delay to avoid any race condition. + */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + } + + return 0; +} + +static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct ab8500_usb *ab; + + if (!otg) + return -ENODEV; + + ab = phy_to_ab(otg->phy); + + /* Some drivers call this function in atomic context. + * Do not update ab8500 registers directly till this + * is fixed. + */ + + if (!host) { + /* TODO: Disable regulators. */ + otg->host = NULL; + schedule_work(&ab->phy_dis_work); + } else { + otg->host = host; + /* Phy will not be enabled if cable is already + * plugged-in. Schedule to enable phy. + * Use same delay to avoid any race condition. + */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + } + + return 0; +} + +static void ab8500_usb_irq_free(struct ab8500_usb *ab) +{ + if (ab->rev < 0x20) { + free_irq(ab->irq_num_id_rise, ab); + free_irq(ab->irq_num_id_fall, ab); + free_irq(ab->irq_num_vbus_rise, ab); + free_irq(ab->irq_num_vbus_fall, ab); + } else { + free_irq(ab->irq_num_link_status, ab); + } +} + +static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, + struct ab8500_usb *ab) +{ + int err; + + ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); + if (ab->irq_num_id_rise < 0) { + dev_err(&pdev->dev, "ID rise irq not found\n"); + return ab->irq_num_id_rise; + } + err = request_threaded_irq(ab->irq_num_id_rise, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-id-rise", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for ID rise irq\n"); + goto fail0; + } + + ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); + if (ab->irq_num_id_fall < 0) { + dev_err(&pdev->dev, "ID fall irq not found\n"); + return ab->irq_num_id_fall; + } + err = request_threaded_irq(ab->irq_num_id_fall, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-id-fall", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for ID fall irq\n"); + goto fail1; + } + + ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); + if (ab->irq_num_vbus_rise < 0) { + dev_err(&pdev->dev, "VBUS rise irq not found\n"); + return ab->irq_num_vbus_rise; + } + err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-vbus-rise", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); + goto fail2; + } + + ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); + if (ab->irq_num_vbus_fall < 0) { + dev_err(&pdev->dev, "VBUS fall irq not found\n"); + return ab->irq_num_vbus_fall; + } + err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, + ab8500_usb_v1x_vbus_fall_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-vbus-fall", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); + goto fail3; + } + + return 0; +fail3: + free_irq(ab->irq_num_vbus_rise, ab); +fail2: + free_irq(ab->irq_num_id_fall, ab); +fail1: + free_irq(ab->irq_num_id_rise, ab); +fail0: + return err; +} + +static int ab8500_usb_v2_res_setup(struct platform_device *pdev, + struct ab8500_usb *ab) +{ + int err; + + ab->irq_num_link_status = platform_get_irq_byname(pdev, + "USB_LINK_STATUS"); + if (ab->irq_num_link_status < 0) { + dev_err(&pdev->dev, "Link status irq not found\n"); + return ab->irq_num_link_status; + } + + err = request_threaded_irq(ab->irq_num_link_status, NULL, + ab8500_usb_v20_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-link-status", ab); + if (err < 0) { + dev_err(ab->dev, + "request_irq failed for link status irq\n"); + return err; + } + + return 0; +} + +static int ab8500_usb_probe(struct platform_device *pdev) +{ + struct ab8500_usb *ab; + struct usb_otg *otg; + int err; + int rev; + + rev = abx500_get_chip_id(&pdev->dev); + if (rev < 0) { + dev_err(&pdev->dev, "Chip id read failed\n"); + return rev; + } else if (rev < 0x10) { + dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); + return -ENODEV; + } + + ab = kzalloc(sizeof *ab, GFP_KERNEL); + if (!ab) + return -ENOMEM; + + otg = kzalloc(sizeof *otg, GFP_KERNEL); + if (!otg) { + kfree(ab); + return -ENOMEM; + } + + ab->dev = &pdev->dev; + ab->rev = rev; + ab->phy.dev = ab->dev; + ab->phy.otg = otg; + ab->phy.label = "ab8500"; + ab->phy.set_suspend = ab8500_usb_set_suspend; + ab->phy.set_power = ab8500_usb_set_power; + ab->phy.state = OTG_STATE_UNDEFINED; + + otg->phy = &ab->phy; + otg->set_host = ab8500_usb_set_host; + otg->set_peripheral = ab8500_usb_set_peripheral; + + platform_set_drvdata(pdev, ab); + + ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); + + /* v1: Wait for link status to become stable. + * all: Updates form set_host and set_peripheral as they are atomic. + */ + INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); + + /* all: Disable phy when called from set_host and set_peripheral */ + INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); + + if (ab->rev < 0x20) { + err = ab8500_usb_v1x_res_setup(pdev, ab); + ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; + } else { + err = ab8500_usb_v2_res_setup(pdev, ab); + } + + if (err < 0) + goto fail0; + + err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); + if (err) { + dev_err(&pdev->dev, "Can't register transceiver\n"); + goto fail1; + } + + dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); + + return 0; +fail1: + ab8500_usb_irq_free(ab); +fail0: + kfree(otg); + kfree(ab); + return err; +} + +static int ab8500_usb_remove(struct platform_device *pdev) +{ + struct ab8500_usb *ab = platform_get_drvdata(pdev); + + ab8500_usb_irq_free(ab); + + cancel_delayed_work_sync(&ab->dwork); + + cancel_work_sync(&ab->phy_dis_work); + + usb_remove_phy(&ab->phy); + + ab8500_usb_host_phy_dis(ab); + ab8500_usb_peri_phy_dis(ab); + + platform_set_drvdata(pdev, NULL); + + kfree(ab->phy.otg); + kfree(ab); + + return 0; +} + +static struct platform_driver ab8500_usb_driver = { + .probe = ab8500_usb_probe, + .remove = ab8500_usb_remove, + .driver = { + .name = "ab8500-usb", + .owner = THIS_MODULE, + }, +}; + +static int __init ab8500_usb_init(void) +{ + return platform_driver_register(&ab8500_usb_driver); +} +subsys_initcall(ab8500_usb_init); + +static void __exit ab8500_usb_exit(void) +{ + platform_driver_unregister(&ab8500_usb_driver); +} +module_exit(ab8500_usb_exit); + +MODULE_ALIAS("platform:ab8500_usb"); +MODULE_AUTHOR("ST-Ericsson AB"); +MODULE_DESCRIPTION("AB8500 usb transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/fsl_otg.c b/drivers/usb/phy/fsl_otg.c new file mode 100644 index 000000000000..72a2a00c2487 --- /dev/null +++ b/drivers/usb/phy/fsl_otg.c @@ -0,0 +1,1173 @@ +/* + * Copyright (C) 2007,2008 Freescale semiconductor, Inc. + * + * Author: Li Yang + * Jerry Huang + * + * Initialization based on code from Shlomi Gridish. + * + * 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 "fsl_otg.h" + +#define DRIVER_VERSION "Rev. 1.55" +#define DRIVER_AUTHOR "Jerry Huang/Li Yang" +#define DRIVER_DESC "Freescale USB OTG Transceiver Driver" +#define DRIVER_INFO DRIVER_DESC " " DRIVER_VERSION + +static const char driver_name[] = "fsl-usb2-otg"; + +const pm_message_t otg_suspend_state = { + .event = 1, +}; + +#define HA_DATA_PULSE + +static struct usb_dr_mmap *usb_dr_regs; +static struct fsl_otg *fsl_otg_dev; +static int srp_wait_done; + +/* FSM timers */ +struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, + *b_ase0_brst_tmr, *b_se0_srp_tmr; + +/* Driver specific timers */ +struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, + *b_srp_wait_tmr, *a_wait_enum_tmr; + +static struct list_head active_timers; + +static struct fsl_otg_config fsl_otg_initdata = { + .otg_port = 1, +}; + +#ifdef CONFIG_PPC32 +static u32 _fsl_readl_be(const unsigned __iomem *p) +{ + return in_be32(p); +} + +static u32 _fsl_readl_le(const unsigned __iomem *p) +{ + return in_le32(p); +} + +static void _fsl_writel_be(u32 v, unsigned __iomem *p) +{ + out_be32(p, v); +} + +static void _fsl_writel_le(u32 v, unsigned __iomem *p) +{ + out_le32(p, v); +} + +static u32 (*_fsl_readl)(const unsigned __iomem *p); +static void (*_fsl_writel)(u32 v, unsigned __iomem *p); + +#define fsl_readl(p) (*_fsl_readl)((p)) +#define fsl_writel(v, p) (*_fsl_writel)((v), (p)) + +#else +#define fsl_readl(addr) readl(addr) +#define fsl_writel(val, addr) writel(val, addr) +#endif /* CONFIG_PPC32 */ + +/* Routines to access transceiver ULPI registers */ +u8 view_ulpi(u8 addr) +{ + u32 temp; + + temp = 0x40000000 | (addr << 16); + fsl_writel(temp, &usb_dr_regs->ulpiview); + udelay(1000); + while (temp & 0x40) + temp = fsl_readl(&usb_dr_regs->ulpiview); + return (le32_to_cpu(temp) & 0x0000ff00) >> 8; +} + +int write_ulpi(u8 addr, u8 data) +{ + u32 temp; + + temp = 0x60000000 | (addr << 16) | data; + fsl_writel(temp, &usb_dr_regs->ulpiview); + return 0; +} + +/* -------------------------------------------------------------*/ +/* Operations that will be called from OTG Finite State Machine */ + +/* Charge vbus for vbus pulsing in SRP */ +void fsl_otg_chrg_vbus(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + /* stop discharging, start charging */ + tmp = (tmp & ~OTGSC_CTRL_VBUS_DISCHARGE) | + OTGSC_CTRL_VBUS_CHARGE; + else + /* stop charging */ + tmp &= ~OTGSC_CTRL_VBUS_CHARGE; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* Discharge vbus through a resistor to ground */ +void fsl_otg_dischrg_vbus(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + /* stop charging, start discharging */ + tmp = (tmp & ~OTGSC_CTRL_VBUS_CHARGE) | + OTGSC_CTRL_VBUS_DISCHARGE; + else + /* stop discharging */ + tmp &= ~OTGSC_CTRL_VBUS_DISCHARGE; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* A-device driver vbus, controlled through PP bit in PORTSC */ +void fsl_otg_drv_vbus(int on) +{ + u32 tmp; + + if (on) { + tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; + fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); + } else { + tmp = fsl_readl(&usb_dr_regs->portsc) & + ~PORTSC_W1C_BITS & ~PORTSC_PORT_POWER; + fsl_writel(tmp, &usb_dr_regs->portsc); + } +} + +/* + * Pull-up D+, signalling connect by periperal. Also used in + * data-line pulsing in SRP + */ +void fsl_otg_loc_conn(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + tmp |= OTGSC_CTRL_DATA_PULSING; + else + tmp &= ~OTGSC_CTRL_DATA_PULSING; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* + * Generate SOF by host. This is controlled through suspend/resume the + * port. In host mode, controller will automatically send SOF. + * Suspend will block the data on the port. + */ +void fsl_otg_loc_sof(int on) +{ + u32 tmp; + + tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; + if (on) + tmp |= PORTSC_PORT_FORCE_RESUME; + else + tmp |= PORTSC_PORT_SUSPEND; + + fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); + +} + +/* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ +void fsl_otg_start_pulse(void) +{ + u32 tmp; + + srp_wait_done = 0; +#ifdef HA_DATA_PULSE + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + tmp |= OTGSC_HA_DATA_PULSE; + fsl_writel(tmp, &usb_dr_regs->otgsc); +#else + fsl_otg_loc_conn(1); +#endif + + fsl_otg_add_timer(b_data_pulse_tmr); +} + +void b_data_pulse_end(unsigned long foo) +{ +#ifdef HA_DATA_PULSE +#else + fsl_otg_loc_conn(0); +#endif + + /* Do VBUS pulse after data pulse */ + fsl_otg_pulse_vbus(); +} + +void fsl_otg_pulse_vbus(void) +{ + srp_wait_done = 0; + fsl_otg_chrg_vbus(1); + /* start the timer to end vbus charge */ + fsl_otg_add_timer(b_vbus_pulse_tmr); +} + +void b_vbus_pulse_end(unsigned long foo) +{ + fsl_otg_chrg_vbus(0); + + /* + * As USB3300 using the same a_sess_vld and b_sess_vld voltage + * we need to discharge the bus for a while to distinguish + * residual voltage of vbus pulsing and A device pull up + */ + fsl_otg_dischrg_vbus(1); + fsl_otg_add_timer(b_srp_wait_tmr); +} + +void b_srp_end(unsigned long foo) +{ + fsl_otg_dischrg_vbus(0); + srp_wait_done = 1; + + if ((fsl_otg_dev->phy.state == OTG_STATE_B_SRP_INIT) && + fsl_otg_dev->fsm.b_sess_vld) + fsl_otg_dev->fsm.b_srp_done = 1; +} + +/* + * Workaround for a_host suspending too fast. When a_bus_req=0, + * a_host will start by SRP. It needs to set b_hnp_enable before + * actually suspending to start HNP + */ +void a_wait_enum(unsigned long foo) +{ + VDBG("a_wait_enum timeout\n"); + if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) + fsl_otg_add_timer(a_wait_enum_tmr); + else + otg_statemachine(&fsl_otg_dev->fsm); +} + +/* The timeout callback function to set time out bit */ +void set_tmout(unsigned long indicator) +{ + *(int *)indicator = 1; +} + +/* Initialize timers */ +int fsl_otg_init_timers(struct otg_fsm *fsm) +{ + /* FSM used timers */ + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, + (unsigned long)&fsm->a_wait_vrise_tmout); + if (!a_wait_vrise_tmr) + return -ENOMEM; + + a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, + (unsigned long)&fsm->a_wait_bcon_tmout); + if (!a_wait_bcon_tmr) + return -ENOMEM; + + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, + (unsigned long)&fsm->a_aidl_bdis_tmout); + if (!a_aidl_bdis_tmr) + return -ENOMEM; + + b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, + (unsigned long)&fsm->b_ase0_brst_tmout); + if (!b_ase0_brst_tmr) + return -ENOMEM; + + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, + (unsigned long)&fsm->b_se0_srp); + if (!b_se0_srp_tmr) + return -ENOMEM; + + b_srp_fail_tmr = otg_timer_initializer(&set_tmout, TB_SRP_FAIL, + (unsigned long)&fsm->b_srp_done); + if (!b_srp_fail_tmr) + return -ENOMEM; + + a_wait_enum_tmr = otg_timer_initializer(&a_wait_enum, 10, + (unsigned long)&fsm); + if (!a_wait_enum_tmr) + return -ENOMEM; + + /* device driver used timers */ + b_srp_wait_tmr = otg_timer_initializer(&b_srp_end, TB_SRP_WAIT, 0); + if (!b_srp_wait_tmr) + return -ENOMEM; + + b_data_pulse_tmr = otg_timer_initializer(&b_data_pulse_end, + TB_DATA_PLS, 0); + if (!b_data_pulse_tmr) + return -ENOMEM; + + b_vbus_pulse_tmr = otg_timer_initializer(&b_vbus_pulse_end, + TB_VBUS_PLS, 0); + if (!b_vbus_pulse_tmr) + return -ENOMEM; + + return 0; +} + +/* Uninitialize timers */ +void fsl_otg_uninit_timers(void) +{ + /* FSM used timers */ + kfree(a_wait_vrise_tmr); + kfree(a_wait_bcon_tmr); + kfree(a_aidl_bdis_tmr); + kfree(b_ase0_brst_tmr); + kfree(b_se0_srp_tmr); + kfree(b_srp_fail_tmr); + kfree(a_wait_enum_tmr); + + /* device driver used timers */ + kfree(b_srp_wait_tmr); + kfree(b_data_pulse_tmr); + kfree(b_vbus_pulse_tmr); +} + +/* Add timer to timer list */ +void fsl_otg_add_timer(void *gtimer) +{ + struct fsl_otg_timer *timer = gtimer; + struct fsl_otg_timer *tmp_timer; + + /* + * Check if the timer is already in the active list, + * if so update timer count + */ + list_for_each_entry(tmp_timer, &active_timers, list) + if (tmp_timer == timer) { + timer->count = timer->expires; + return; + } + timer->count = timer->expires; + list_add_tail(&timer->list, &active_timers); +} + +/* Remove timer from the timer list; clear timeout status */ +void fsl_otg_del_timer(void *gtimer) +{ + struct fsl_otg_timer *timer = gtimer; + struct fsl_otg_timer *tmp_timer, *del_tmp; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) + if (tmp_timer == timer) + list_del(&timer->list); +} + +/* + * Reduce timer count by 1, and find timeout conditions. + * Called by fsl_otg 1ms timer interrupt + */ +int fsl_otg_tick_timer(void) +{ + struct fsl_otg_timer *tmp_timer, *del_tmp; + int expired = 0; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { + tmp_timer->count--; + /* check if timer expires */ + if (!tmp_timer->count) { + list_del(&tmp_timer->list); + tmp_timer->function(tmp_timer->data); + expired = 1; + } + } + + return expired; +} + +/* Reset controller, not reset the bus */ +void otg_reset_controller(void) +{ + u32 command; + + command = fsl_readl(&usb_dr_regs->usbcmd); + command |= (1 << 1); + fsl_writel(command, &usb_dr_regs->usbcmd); + while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) + ; +} + +/* Call suspend/resume routines in host driver */ +int fsl_otg_start_host(struct otg_fsm *fsm, int on) +{ + struct usb_otg *otg = fsm->otg; + struct device *dev; + struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); + u32 retval = 0; + + if (!otg->host) + return -ENODEV; + dev = otg->host->controller; + + /* + * Update a_vbus_vld state as a_vbus_vld int is disabled + * in device mode + */ + fsm->a_vbus_vld = + !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); + if (on) { + /* start fsl usb host controller */ + if (otg_dev->host_working) + goto end; + else { + otg_reset_controller(); + VDBG("host on......\n"); + if (dev->driver->pm && dev->driver->pm->resume) { + retval = dev->driver->pm->resume(dev); + if (fsm->id) { + /* default-b */ + fsl_otg_drv_vbus(1); + /* + * Workaround: b_host can't driver + * vbus, but PP in PORTSC needs to + * be 1 for host to work. + * So we set drv_vbus bit in + * transceiver to 0 thru ULPI. + */ + write_ulpi(0x0c, 0x20); + } + } + + otg_dev->host_working = 1; + } + } else { + /* stop fsl usb host controller */ + if (!otg_dev->host_working) + goto end; + else { + VDBG("host off......\n"); + if (dev && dev->driver) { + if (dev->driver->pm && dev->driver->pm->suspend) + retval = dev->driver->pm->suspend(dev); + if (fsm->id) + /* default-b */ + fsl_otg_drv_vbus(0); + } + otg_dev->host_working = 0; + } + } +end: + return retval; +} + +/* + * Call suspend and resume function in udc driver + * to stop and start udc driver. + */ +int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) +{ + struct usb_otg *otg = fsm->otg; + struct device *dev; + + if (!otg->gadget || !otg->gadget->dev.parent) + return -ENODEV; + + VDBG("gadget %s\n", on ? "on" : "off"); + dev = otg->gadget->dev.parent; + + if (on) { + if (dev->driver->resume) + dev->driver->resume(dev); + } else { + if (dev->driver->suspend) + dev->driver->suspend(dev, otg_suspend_state); + } + + return 0; +} + +/* + * Called by initialization code of host driver. Register host controller + * to the OTG. Suspend host for OTG role detection. + */ +static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + otg->host = host; + + otg_dev->fsm.a_bus_drop = 0; + otg_dev->fsm.a_bus_req = 1; + + if (host) { + VDBG("host off......\n"); + + otg->host->otg_port = fsl_otg_initdata.otg_port; + otg->host->is_b_host = otg_dev->fsm.id; + /* + * must leave time for khubd to finish its thing + * before yanking the host driver out from under it, + * so suspend the host after a short delay. + */ + otg_dev->host_working = 1; + schedule_delayed_work(&otg_dev->otg_event, 100); + return 0; + } else { + /* host driver going away */ + if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & + OTGSC_STS_USB_ID)) { + /* Mini-A cable connected */ + struct otg_fsm *fsm = &otg_dev->fsm; + + otg->phy->state = OTG_STATE_UNDEFINED; + fsm->protocol = PROTO_UNDEF; + } + } + + otg_dev->host_working = 0; + + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* Called by initialization code of udc. Register udc to OTG. */ +static int fsl_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + VDBG("otg_dev 0x%x\n", (int)otg_dev); + VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + if (!gadget) { + if (!otg->default_a) + otg->gadget->ops->vbus_draw(otg->gadget, 0); + usb_gadget_vbus_disconnect(otg->gadget); + otg->gadget = 0; + otg_dev->fsm.b_bus_req = 0; + otg_statemachine(&otg_dev->fsm); + return 0; + } + + otg->gadget = gadget; + otg->gadget->is_a_peripheral = !otg_dev->fsm.id; + + otg_dev->fsm.b_bus_req = 1; + + /* start the gadget right away if the ID pin says Mini-B */ + DBG("ID pin=%d\n", otg_dev->fsm.id); + if (otg_dev->fsm.id == 1) { + fsl_otg_start_host(&otg_dev->fsm, 0); + otg_drv_vbus(&otg_dev->fsm, 0); + fsl_otg_start_gadget(&otg_dev->fsm, 1); + } + + return 0; +} + +/* Set OTG port power, only for B-device */ +static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA) +{ + if (!fsl_otg_dev) + return -ENODEV; + if (phy->state == OTG_STATE_B_PERIPHERAL) + pr_info("FSL OTG: Draw %d mA\n", mA); + + return 0; +} + +/* + * Delayed pin detect interrupt processing. + * + * When the Mini-A cable is disconnected from the board, + * the pin-detect interrupt happens before the disconnect + * interrupts for the connected device(s). In order to + * process the disconnect interrupt(s) prior to switching + * roles, the pin-detect interrupts are delayed, and handled + * by this routine. + */ +static void fsl_otg_event(struct work_struct *work) +{ + struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work); + struct otg_fsm *fsm = &og->fsm; + + if (fsm->id) { /* switch to gadget */ + fsl_otg_start_host(fsm, 0); + otg_drv_vbus(fsm, 0); + fsl_otg_start_gadget(fsm, 1); + } +} + +/* B-device start SRP */ +static int fsl_otg_start_srp(struct usb_otg *otg) +{ + struct fsl_otg *otg_dev; + + if (!otg || otg->phy->state != OTG_STATE_B_IDLE) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + otg_dev->fsm.b_bus_req = 1; + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* A_host suspend will call this function to start hnp */ +static int fsl_otg_start_hnp(struct usb_otg *otg) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + DBG("start_hnp...n"); + + /* clear a_bus_req to enter a_suspend state */ + otg_dev->fsm.a_bus_req = 0; + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* + * Interrupt handler. OTG/host/peripheral share the same int line. + * OTG driver clears OTGSC interrupts and leaves USB interrupts + * intact. It needs to have knowledge of some USB interrupts + * such as port change. + */ +irqreturn_t fsl_otg_isr(int irq, void *dev_id) +{ + struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; + struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; + u32 otg_int_src, otg_sc; + + otg_sc = fsl_readl(&usb_dr_regs->otgsc); + otg_int_src = otg_sc & OTGSC_INTSTS_MASK & (otg_sc >> 8); + + /* Only clear otg interrupts */ + fsl_writel(otg_sc, &usb_dr_regs->otgsc); + + /*FIXME: ID change not generate when init to 0 */ + fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; + otg->default_a = (fsm->id == 0); + + /* process OTG interrupts */ + if (otg_int_src) { + if (otg_int_src & OTGSC_INTSTS_USB_ID) { + fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; + otg->default_a = (fsm->id == 0); + /* clear conn information */ + if (fsm->id) + fsm->b_conn = 0; + else + fsm->a_conn = 0; + + if (otg->host) + otg->host->is_b_host = fsm->id; + if (otg->gadget) + otg->gadget->is_a_peripheral = !fsm->id; + VDBG("ID int (ID is %d)\n", fsm->id); + + if (fsm->id) { /* switch to gadget */ + schedule_delayed_work( + &((struct fsl_otg *)dev_id)->otg_event, + 100); + } else { /* switch to host */ + cancel_delayed_work(& + ((struct fsl_otg *)dev_id)-> + otg_event); + fsl_otg_start_gadget(fsm, 0); + otg_drv_vbus(fsm, 1); + fsl_otg_start_host(fsm, 1); + } + return IRQ_HANDLED; + } + } + return IRQ_NONE; +} + +static struct otg_fsm_ops fsl_otg_ops = { + .chrg_vbus = fsl_otg_chrg_vbus, + .drv_vbus = fsl_otg_drv_vbus, + .loc_conn = fsl_otg_loc_conn, + .loc_sof = fsl_otg_loc_sof, + .start_pulse = fsl_otg_start_pulse, + + .add_timer = fsl_otg_add_timer, + .del_timer = fsl_otg_del_timer, + + .start_host = fsl_otg_start_host, + .start_gadget = fsl_otg_start_gadget, +}; + +/* Initialize the global variable fsl_otg_dev and request IRQ for OTG */ +static int fsl_otg_conf(struct platform_device *pdev) +{ + struct fsl_otg *fsl_otg_tc; + int status; + + if (fsl_otg_dev) + return 0; + + /* allocate space to fsl otg device */ + fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); + if (!fsl_otg_tc) + return -ENOMEM; + + fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!fsl_otg_tc->phy.otg) { + kfree(fsl_otg_tc); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); + + INIT_LIST_HEAD(&active_timers); + status = fsl_otg_init_timers(&fsl_otg_tc->fsm); + if (status) { + pr_info("Couldn't init OTG timers\n"); + goto err; + } + spin_lock_init(&fsl_otg_tc->fsm.lock); + + /* Set OTG state machine operations */ + fsl_otg_tc->fsm.ops = &fsl_otg_ops; + + /* initialize the otg structure */ + fsl_otg_tc->phy.label = DRIVER_DESC; + fsl_otg_tc->phy.set_power = fsl_otg_set_power; + + fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; + fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; + fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; + fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; + fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; + + fsl_otg_dev = fsl_otg_tc; + + /* Store the otg transceiver */ + status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); + if (status) { + pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); + goto err; + } + + return 0; +err: + fsl_otg_uninit_timers(); + kfree(fsl_otg_tc->phy.otg); + kfree(fsl_otg_tc); + return status; +} + +/* OTG Initialization */ +int usb_otg_start(struct platform_device *pdev) +{ + struct fsl_otg *p_otg; + struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); + struct otg_fsm *fsm; + int status; + struct resource *res; + u32 temp; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + p_otg = container_of(otg_trans, struct fsl_otg, phy); + fsm = &p_otg->fsm; + + /* Initialize the state machine structure with default values */ + SET_OTG_STATE(otg_trans, OTG_STATE_UNDEFINED); + fsm->otg = p_otg->phy.otg; + + /* We don't require predefined MEM/IRQ resource index */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + /* We don't request_mem_region here to enable resource sharing + * with host/device */ + + usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); + p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; + pdata->regs = (void *)usb_dr_regs; + + if (pdata->init && pdata->init(pdev) != 0) + return -EINVAL; + + if (pdata->big_endian_mmio) { + _fsl_readl = _fsl_readl_be; + _fsl_writel = _fsl_writel_be; + } else { + _fsl_readl = _fsl_readl_le; + _fsl_writel = _fsl_writel_le; + } + + /* request irq */ + p_otg->irq = platform_get_irq(pdev, 0); + status = request_irq(p_otg->irq, fsl_otg_isr, + IRQF_SHARED, driver_name, p_otg); + if (status) { + dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", + p_otg->irq, status); + iounmap(p_otg->dr_mem_map); + kfree(p_otg->phy.otg); + kfree(p_otg); + return status; + } + + /* stop the controller */ + temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); + temp &= ~USB_CMD_RUN_STOP; + fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); + + /* reset the controller */ + temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); + temp |= USB_CMD_CTRL_RESET; + fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); + + /* wait reset completed */ + while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) + ; + + /* configure the VBUSHS as IDLE(both host and device) */ + temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); + fsl_writel(temp, &p_otg->dr_mem_map->usbmode); + + /* configure PHY interface */ + temp = fsl_readl(&p_otg->dr_mem_map->portsc); + temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); + switch (pdata->phy_mode) { + case FSL_USB2_PHY_ULPI: + temp |= PORTSC_PTS_ULPI; + break; + case FSL_USB2_PHY_UTMI_WIDE: + temp |= PORTSC_PTW_16BIT; + /* fall through */ + case FSL_USB2_PHY_UTMI: + temp |= PORTSC_PTS_UTMI; + /* fall through */ + default: + break; + } + fsl_writel(temp, &p_otg->dr_mem_map->portsc); + + if (pdata->have_sysif_regs) { + /* configure control enable IO output, big endian register */ + temp = __raw_readl(&p_otg->dr_mem_map->control); + temp |= USB_CTRL_IOENB; + __raw_writel(temp, &p_otg->dr_mem_map->control); + } + + /* disable all interrupt and clear all OTGSC status */ + temp = fsl_readl(&p_otg->dr_mem_map->otgsc); + temp &= ~OTGSC_INTERRUPT_ENABLE_BITS_MASK; + temp |= OTGSC_INTERRUPT_STATUS_BITS_MASK | OTGSC_CTRL_VBUS_DISCHARGE; + fsl_writel(temp, &p_otg->dr_mem_map->otgsc); + + /* + * The identification (id) input is FALSE when a Mini-A plug is inserted + * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. + * Also: record initial state of ID pin + */ + if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { + p_otg->phy.state = OTG_STATE_UNDEFINED; + p_otg->fsm.id = 1; + } else { + p_otg->phy.state = OTG_STATE_A_IDLE; + p_otg->fsm.id = 0; + } + + DBG("initial ID pin=%d\n", p_otg->fsm.id); + + /* enable OTG ID pin interrupt */ + temp = fsl_readl(&p_otg->dr_mem_map->otgsc); + temp |= OTGSC_INTR_USB_ID_EN; + temp &= ~(OTGSC_CTRL_VBUS_DISCHARGE | OTGSC_INTR_1MS_TIMER_EN); + fsl_writel(temp, &p_otg->dr_mem_map->otgsc); + + return 0; +} + +/* + * state file in sysfs + */ +static int show_fsl_usb2_otg_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct otg_fsm *fsm = &fsl_otg_dev->fsm; + char *next = buf; + unsigned size = PAGE_SIZE; + unsigned long flags; + int t; + + spin_lock_irqsave(&fsm->lock, flags); + + /* basic driver infomation */ + t = scnprintf(next, size, + DRIVER_DESC "\n" "fsl_usb2_otg version: %s\n\n", + DRIVER_VERSION); + size -= t; + next += t; + + /* Registers */ + t = scnprintf(next, size, + "OTGSC: 0x%08x\n" + "PORTSC: 0x%08x\n" + "USBMODE: 0x%08x\n" + "USBCMD: 0x%08x\n" + "USBSTS: 0x%08x\n" + "USBINTR: 0x%08x\n", + fsl_readl(&usb_dr_regs->otgsc), + fsl_readl(&usb_dr_regs->portsc), + fsl_readl(&usb_dr_regs->usbmode), + fsl_readl(&usb_dr_regs->usbcmd), + fsl_readl(&usb_dr_regs->usbsts), + fsl_readl(&usb_dr_regs->usbintr)); + size -= t; + next += t; + + /* State */ + t = scnprintf(next, size, + "OTG state: %s\n\n", + usb_otg_state_string(fsl_otg_dev->phy.state)); + size -= t; + next += t; + + /* State Machine Variables */ + t = scnprintf(next, size, + "a_bus_req: %d\n" + "b_bus_req: %d\n" + "a_bus_resume: %d\n" + "a_bus_suspend: %d\n" + "a_conn: %d\n" + "a_sess_vld: %d\n" + "a_srp_det: %d\n" + "a_vbus_vld: %d\n" + "b_bus_resume: %d\n" + "b_bus_suspend: %d\n" + "b_conn: %d\n" + "b_se0_srp: %d\n" + "b_sess_end: %d\n" + "b_sess_vld: %d\n" + "id: %d\n", + fsm->a_bus_req, + fsm->b_bus_req, + fsm->a_bus_resume, + fsm->a_bus_suspend, + fsm->a_conn, + fsm->a_sess_vld, + fsm->a_srp_det, + fsm->a_vbus_vld, + fsm->b_bus_resume, + fsm->b_bus_suspend, + fsm->b_conn, + fsm->b_se0_srp, + fsm->b_sess_end, + fsm->b_sess_vld, + fsm->id); + size -= t; + next += t; + + spin_unlock_irqrestore(&fsm->lock, flags); + + return PAGE_SIZE - size; +} + +static DEVICE_ATTR(fsl_usb2_otg_state, S_IRUGO, show_fsl_usb2_otg_state, NULL); + + +/* Char driver interface to control some OTG input */ + +/* + * Handle some ioctl command, such as get otg + * status and set host suspend + */ +static long fsl_otg_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + u32 retval = 0; + + switch (cmd) { + case GET_OTG_STATUS: + retval = fsl_otg_dev->host_working; + break; + + case SET_A_SUSPEND_REQ: + fsl_otg_dev->fsm.a_suspend_req = arg; + break; + + case SET_A_BUS_DROP: + fsl_otg_dev->fsm.a_bus_drop = arg; + break; + + case SET_A_BUS_REQ: + fsl_otg_dev->fsm.a_bus_req = arg; + break; + + case SET_B_BUS_REQ: + fsl_otg_dev->fsm.b_bus_req = arg; + break; + + default: + break; + } + + otg_statemachine(&fsl_otg_dev->fsm); + + return retval; +} + +static int fsl_otg_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int fsl_otg_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations otg_fops = { + .owner = THIS_MODULE, + .llseek = NULL, + .read = NULL, + .write = NULL, + .unlocked_ioctl = fsl_otg_ioctl, + .open = fsl_otg_open, + .release = fsl_otg_release, +}; + +static int fsl_otg_probe(struct platform_device *pdev) +{ + int ret; + + if (!pdev->dev.platform_data) + return -ENODEV; + + /* configure the OTG */ + ret = fsl_otg_conf(pdev); + if (ret) { + dev_err(&pdev->dev, "Couldn't configure OTG module\n"); + return ret; + } + + /* start OTG */ + ret = usb_otg_start(pdev); + if (ret) { + dev_err(&pdev->dev, "Can't init FSL OTG device\n"); + return ret; + } + + ret = register_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME, &otg_fops); + if (ret) { + dev_err(&pdev->dev, "unable to register FSL OTG device\n"); + return ret; + } + + ret = device_create_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); + if (ret) + dev_warn(&pdev->dev, "Can't register sysfs attribute\n"); + + return ret; +} + +static int fsl_otg_remove(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + usb_remove_phy(&fsl_otg_dev->phy); + free_irq(fsl_otg_dev->irq, fsl_otg_dev); + + iounmap((void *)usb_dr_regs); + + fsl_otg_uninit_timers(); + kfree(fsl_otg_dev->phy.otg); + kfree(fsl_otg_dev); + + device_remove_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); + + unregister_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME); + + if (pdata->exit) + pdata->exit(pdev); + + return 0; +} + +struct platform_driver fsl_otg_driver = { + .probe = fsl_otg_probe, + .remove = fsl_otg_remove, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(fsl_otg_driver); + +MODULE_DESCRIPTION(DRIVER_INFO); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/fsl_otg.h b/drivers/usb/phy/fsl_otg.h new file mode 100644 index 000000000000..ca266280895d --- /dev/null +++ b/drivers/usb/phy/fsl_otg.h @@ -0,0 +1,406 @@ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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 "otg_fsm.h" +#include +#include + +/* USB Command Register Bit Masks */ +#define USB_CMD_RUN_STOP (0x1<<0) +#define USB_CMD_CTRL_RESET (0x1<<1) +#define USB_CMD_PERIODIC_SCHEDULE_EN (0x1<<4) +#define USB_CMD_ASYNC_SCHEDULE_EN (0x1<<5) +#define USB_CMD_INT_AA_DOORBELL (0x1<<6) +#define USB_CMD_ASP (0x3<<8) +#define USB_CMD_ASYNC_SCH_PARK_EN (0x1<<11) +#define USB_CMD_SUTW (0x1<<13) +#define USB_CMD_ATDTW (0x1<<14) +#define USB_CMD_ITC (0xFF<<16) + +/* bit 15,3,2 are frame list size */ +#define USB_CMD_FRAME_SIZE_1024 (0x0<<15 | 0x0<<2) +#define USB_CMD_FRAME_SIZE_512 (0x0<<15 | 0x1<<2) +#define USB_CMD_FRAME_SIZE_256 (0x0<<15 | 0x2<<2) +#define USB_CMD_FRAME_SIZE_128 (0x0<<15 | 0x3<<2) +#define USB_CMD_FRAME_SIZE_64 (0x1<<15 | 0x0<<2) +#define USB_CMD_FRAME_SIZE_32 (0x1<<15 | 0x1<<2) +#define USB_CMD_FRAME_SIZE_16 (0x1<<15 | 0x2<<2) +#define USB_CMD_FRAME_SIZE_8 (0x1<<15 | 0x3<<2) + +/* bit 9-8 are async schedule park mode count */ +#define USB_CMD_ASP_00 (0x0<<8) +#define USB_CMD_ASP_01 (0x1<<8) +#define USB_CMD_ASP_10 (0x2<<8) +#define USB_CMD_ASP_11 (0x3<<8) +#define USB_CMD_ASP_BIT_POS (8) + +/* bit 23-16 are interrupt threshold control */ +#define USB_CMD_ITC_NO_THRESHOLD (0x00<<16) +#define USB_CMD_ITC_1_MICRO_FRM (0x01<<16) +#define USB_CMD_ITC_2_MICRO_FRM (0x02<<16) +#define USB_CMD_ITC_4_MICRO_FRM (0x04<<16) +#define USB_CMD_ITC_8_MICRO_FRM (0x08<<16) +#define USB_CMD_ITC_16_MICRO_FRM (0x10<<16) +#define USB_CMD_ITC_32_MICRO_FRM (0x20<<16) +#define USB_CMD_ITC_64_MICRO_FRM (0x40<<16) +#define USB_CMD_ITC_BIT_POS (16) + +/* USB Status Register Bit Masks */ +#define USB_STS_INT (0x1<<0) +#define USB_STS_ERR (0x1<<1) +#define USB_STS_PORT_CHANGE (0x1<<2) +#define USB_STS_FRM_LST_ROLL (0x1<<3) +#define USB_STS_SYS_ERR (0x1<<4) +#define USB_STS_IAA (0x1<<5) +#define USB_STS_RESET_RECEIVED (0x1<<6) +#define USB_STS_SOF (0x1<<7) +#define USB_STS_DCSUSPEND (0x1<<8) +#define USB_STS_HC_HALTED (0x1<<12) +#define USB_STS_RCL (0x1<<13) +#define USB_STS_PERIODIC_SCHEDULE (0x1<<14) +#define USB_STS_ASYNC_SCHEDULE (0x1<<15) + +/* USB Interrupt Enable Register Bit Masks */ +#define USB_INTR_INT_EN (0x1<<0) +#define USB_INTR_ERR_INT_EN (0x1<<1) +#define USB_INTR_PC_DETECT_EN (0x1<<2) +#define USB_INTR_FRM_LST_ROLL_EN (0x1<<3) +#define USB_INTR_SYS_ERR_EN (0x1<<4) +#define USB_INTR_ASYN_ADV_EN (0x1<<5) +#define USB_INTR_RESET_EN (0x1<<6) +#define USB_INTR_SOF_EN (0x1<<7) +#define USB_INTR_DEVICE_SUSPEND (0x1<<8) + +/* Device Address bit masks */ +#define USB_DEVICE_ADDRESS_MASK (0x7F<<25) +#define USB_DEVICE_ADDRESS_BIT_POS (25) +/* PORTSC Register Bit Masks,Only one PORT in OTG mode*/ +#define PORTSC_CURRENT_CONNECT_STATUS (0x1<<0) +#define PORTSC_CONNECT_STATUS_CHANGE (0x1<<1) +#define PORTSC_PORT_ENABLE (0x1<<2) +#define PORTSC_PORT_EN_DIS_CHANGE (0x1<<3) +#define PORTSC_OVER_CURRENT_ACT (0x1<<4) +#define PORTSC_OVER_CUURENT_CHG (0x1<<5) +#define PORTSC_PORT_FORCE_RESUME (0x1<<6) +#define PORTSC_PORT_SUSPEND (0x1<<7) +#define PORTSC_PORT_RESET (0x1<<8) +#define PORTSC_LINE_STATUS_BITS (0x3<<10) +#define PORTSC_PORT_POWER (0x1<<12) +#define PORTSC_PORT_INDICTOR_CTRL (0x3<<14) +#define PORTSC_PORT_TEST_CTRL (0xF<<16) +#define PORTSC_WAKE_ON_CONNECT_EN (0x1<<20) +#define PORTSC_WAKE_ON_CONNECT_DIS (0x1<<21) +#define PORTSC_WAKE_ON_OVER_CURRENT (0x1<<22) +#define PORTSC_PHY_LOW_POWER_SPD (0x1<<23) +#define PORTSC_PORT_FORCE_FULL_SPEED (0x1<<24) +#define PORTSC_PORT_SPEED_MASK (0x3<<26) +#define PORTSC_TRANSCEIVER_WIDTH (0x1<<28) +#define PORTSC_PHY_TYPE_SEL (0x3<<30) +/* bit 11-10 are line status */ +#define PORTSC_LINE_STATUS_SE0 (0x0<<10) +#define PORTSC_LINE_STATUS_JSTATE (0x1<<10) +#define PORTSC_LINE_STATUS_KSTATE (0x2<<10) +#define PORTSC_LINE_STATUS_UNDEF (0x3<<10) +#define PORTSC_LINE_STATUS_BIT_POS (10) + +/* bit 15-14 are port indicator control */ +#define PORTSC_PIC_OFF (0x0<<14) +#define PORTSC_PIC_AMBER (0x1<<14) +#define PORTSC_PIC_GREEN (0x2<<14) +#define PORTSC_PIC_UNDEF (0x3<<14) +#define PORTSC_PIC_BIT_POS (14) + +/* bit 19-16 are port test control */ +#define PORTSC_PTC_DISABLE (0x0<<16) +#define PORTSC_PTC_JSTATE (0x1<<16) +#define PORTSC_PTC_KSTATE (0x2<<16) +#define PORTSC_PTC_SEQNAK (0x3<<16) +#define PORTSC_PTC_PACKET (0x4<<16) +#define PORTSC_PTC_FORCE_EN (0x5<<16) +#define PORTSC_PTC_BIT_POS (16) + +/* bit 27-26 are port speed */ +#define PORTSC_PORT_SPEED_FULL (0x0<<26) +#define PORTSC_PORT_SPEED_LOW (0x1<<26) +#define PORTSC_PORT_SPEED_HIGH (0x2<<26) +#define PORTSC_PORT_SPEED_UNDEF (0x3<<26) +#define PORTSC_SPEED_BIT_POS (26) + +/* bit 28 is parallel transceiver width for UTMI interface */ +#define PORTSC_PTW (0x1<<28) +#define PORTSC_PTW_8BIT (0x0<<28) +#define PORTSC_PTW_16BIT (0x1<<28) + +/* bit 31-30 are port transceiver select */ +#define PORTSC_PTS_UTMI (0x0<<30) +#define PORTSC_PTS_ULPI (0x2<<30) +#define PORTSC_PTS_FSLS_SERIAL (0x3<<30) +#define PORTSC_PTS_BIT_POS (30) + +#define PORTSC_W1C_BITS \ + (PORTSC_CONNECT_STATUS_CHANGE | \ + PORTSC_PORT_EN_DIS_CHANGE | \ + PORTSC_OVER_CUURENT_CHG) + +/* OTG Status Control Register Bit Masks */ +#define OTGSC_CTRL_VBUS_DISCHARGE (0x1<<0) +#define OTGSC_CTRL_VBUS_CHARGE (0x1<<1) +#define OTGSC_CTRL_OTG_TERMINATION (0x1<<3) +#define OTGSC_CTRL_DATA_PULSING (0x1<<4) +#define OTGSC_CTRL_ID_PULL_EN (0x1<<5) +#define OTGSC_HA_DATA_PULSE (0x1<<6) +#define OTGSC_HA_BA (0x1<<7) +#define OTGSC_STS_USB_ID (0x1<<8) +#define OTGSC_STS_A_VBUS_VALID (0x1<<9) +#define OTGSC_STS_A_SESSION_VALID (0x1<<10) +#define OTGSC_STS_B_SESSION_VALID (0x1<<11) +#define OTGSC_STS_B_SESSION_END (0x1<<12) +#define OTGSC_STS_1MS_TOGGLE (0x1<<13) +#define OTGSC_STS_DATA_PULSING (0x1<<14) +#define OTGSC_INTSTS_USB_ID (0x1<<16) +#define OTGSC_INTSTS_A_VBUS_VALID (0x1<<17) +#define OTGSC_INTSTS_A_SESSION_VALID (0x1<<18) +#define OTGSC_INTSTS_B_SESSION_VALID (0x1<<19) +#define OTGSC_INTSTS_B_SESSION_END (0x1<<20) +#define OTGSC_INTSTS_1MS (0x1<<21) +#define OTGSC_INTSTS_DATA_PULSING (0x1<<22) +#define OTGSC_INTR_USB_ID_EN (0x1<<24) +#define OTGSC_INTR_A_VBUS_VALID_EN (0x1<<25) +#define OTGSC_INTR_A_SESSION_VALID_EN (0x1<<26) +#define OTGSC_INTR_B_SESSION_VALID_EN (0x1<<27) +#define OTGSC_INTR_B_SESSION_END_EN (0x1<<28) +#define OTGSC_INTR_1MS_TIMER_EN (0x1<<29) +#define OTGSC_INTR_DATA_PULSING_EN (0x1<<30) +#define OTGSC_INTSTS_MASK (0x00ff0000) + +/* USB MODE Register Bit Masks */ +#define USB_MODE_CTRL_MODE_IDLE (0x0<<0) +#define USB_MODE_CTRL_MODE_DEVICE (0x2<<0) +#define USB_MODE_CTRL_MODE_HOST (0x3<<0) +#define USB_MODE_CTRL_MODE_RSV (0x1<<0) +#define USB_MODE_SETUP_LOCK_OFF (0x1<<3) +#define USB_MODE_STREAM_DISABLE (0x1<<4) +#define USB_MODE_ES (0x1<<2) /* Endian Select */ + +/* control Register Bit Masks */ +#define USB_CTRL_IOENB (0x1<<2) +#define USB_CTRL_ULPI_INT0EN (0x1<<0) + +/* BCSR5 */ +#define BCSR5_INT_USB (0x02) + +/* USB module clk cfg */ +#define SCCR_OFFS (0xA08) +#define SCCR_USB_CLK_DISABLE (0x00000000) /* USB clk disable */ +#define SCCR_USB_MPHCM_11 (0x00c00000) +#define SCCR_USB_MPHCM_01 (0x00400000) +#define SCCR_USB_MPHCM_10 (0x00800000) +#define SCCR_USB_DRCM_11 (0x00300000) +#define SCCR_USB_DRCM_01 (0x00100000) +#define SCCR_USB_DRCM_10 (0x00200000) + +#define SICRL_OFFS (0x114) +#define SICRL_USB0 (0x40000000) +#define SICRL_USB1 (0x20000000) + +#define SICRH_OFFS (0x118) +#define SICRH_USB_UTMI (0x00020000) + +/* OTG interrupt enable bit masks */ +#define OTGSC_INTERRUPT_ENABLE_BITS_MASK \ + (OTGSC_INTR_USB_ID_EN | \ + OTGSC_INTR_1MS_TIMER_EN | \ + OTGSC_INTR_A_VBUS_VALID_EN | \ + OTGSC_INTR_A_SESSION_VALID_EN | \ + OTGSC_INTR_B_SESSION_VALID_EN | \ + OTGSC_INTR_B_SESSION_END_EN | \ + OTGSC_INTR_DATA_PULSING_EN) + +/* OTG interrupt status bit masks */ +#define OTGSC_INTERRUPT_STATUS_BITS_MASK \ + (OTGSC_INTSTS_USB_ID | \ + OTGSC_INTR_1MS_TIMER_EN | \ + OTGSC_INTSTS_A_VBUS_VALID | \ + OTGSC_INTSTS_A_SESSION_VALID | \ + OTGSC_INTSTS_B_SESSION_VALID | \ + OTGSC_INTSTS_B_SESSION_END | \ + OTGSC_INTSTS_DATA_PULSING) + +/* + * A-DEVICE timing constants + */ + +/* Wait for VBUS Rise */ +#define TA_WAIT_VRISE (100) /* a_wait_vrise 100 ms, section: 6.6.5.1 */ + +/* Wait for B-Connect */ +#define TA_WAIT_BCON (10000) /* a_wait_bcon > 1 sec, section: 6.6.5.2 + * This is only used to get out of + * OTG_STATE_A_WAIT_BCON state if there was + * no connection for these many milliseconds + */ + +/* A-Idle to B-Disconnect */ +/* It is necessary for this timer to be more than 750 ms because of a bug in OPT + * test 5.4 in which B OPT disconnects after 750 ms instead of 75ms as stated + * in the test description + */ +#define TA_AIDL_BDIS (5000) /* a_suspend minimum 200 ms, section: 6.6.5.3 */ + +/* B-Idle to A-Disconnect */ +#define TA_BIDL_ADIS (12) /* 3 to 200 ms */ + +/* B-device timing constants */ + + +/* Data-Line Pulse Time*/ +#define TB_DATA_PLS (10) /* b_srp_init,continue 5~10ms, section:5.3.3 */ +#define TB_DATA_PLS_MIN (5) /* minimum 5 ms */ +#define TB_DATA_PLS_MAX (10) /* maximum 10 ms */ + +/* SRP Initiate Time */ +#define TB_SRP_INIT (100) /* b_srp_init,maximum 100 ms, section:5.3.8 */ + +/* SRP Fail Time */ +#define TB_SRP_FAIL (7000) /* b_srp_init,Fail time 5~30s, section:6.8.2.2*/ + +/* SRP result wait time */ +#define TB_SRP_WAIT (60) + +/* VBus time */ +#define TB_VBUS_PLS (30) /* time to keep vbus pulsing asserted */ + +/* Discharge time */ +/* This time should be less than 10ms. It varies from system to system. */ +#define TB_VBUS_DSCHRG (8) + +/* A-SE0 to B-Reset */ +#define TB_ASE0_BRST (20) /* b_wait_acon, mini 3.125 ms,section:6.8.2.4 */ + +/* A bus suspend timer before we can switch to b_wait_aconn */ +#define TB_A_SUSPEND (7) +#define TB_BUS_RESUME (12) + +/* SE0 Time Before SRP */ +#define TB_SE0_SRP (2) /* b_idle,minimum 2 ms, section:5.3.2 */ + +#define SET_OTG_STATE(otg_ptr, newstate) ((otg_ptr)->state = newstate) + +struct usb_dr_mmap { + /* Capability register */ + u8 res1[256]; + u16 caplength; /* Capability Register Length */ + u16 hciversion; /* Host Controller Interface Version */ + u32 hcsparams; /* Host Controller Structual Parameters */ + u32 hccparams; /* Host Controller Capability Parameters */ + u8 res2[20]; + u32 dciversion; /* Device Controller Interface Version */ + u32 dccparams; /* Device Controller Capability Parameters */ + u8 res3[24]; + /* Operation register */ + u32 usbcmd; /* USB Command Register */ + u32 usbsts; /* USB Status Register */ + u32 usbintr; /* USB Interrupt Enable Register */ + u32 frindex; /* Frame Index Register */ + u8 res4[4]; + u32 deviceaddr; /* Device Address */ + u32 endpointlistaddr; /* Endpoint List Address Register */ + u8 res5[4]; + u32 burstsize; /* Master Interface Data Burst Size Register */ + u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ + u8 res6[8]; + u32 ulpiview; /* ULPI register access */ + u8 res7[12]; + u32 configflag; /* Configure Flag Register */ + u32 portsc; /* Port 1 Status and Control Register */ + u8 res8[28]; + u32 otgsc; /* On-The-Go Status and Control */ + u32 usbmode; /* USB Mode Register */ + u32 endptsetupstat; /* Endpoint Setup Status Register */ + u32 endpointprime; /* Endpoint Initialization Register */ + u32 endptflush; /* Endpoint Flush Register */ + u32 endptstatus; /* Endpoint Status Register */ + u32 endptcomplete; /* Endpoint Complete Register */ + u32 endptctrl[6]; /* Endpoint Control Registers */ + u8 res9[552]; + u32 snoop1; + u32 snoop2; + u32 age_cnt_thresh; /* Age Count Threshold Register */ + u32 pri_ctrl; /* Priority Control Register */ + u32 si_ctrl; /* System Interface Control Register */ + u8 res10[236]; + u32 control; /* General Purpose Control Register */ +}; + +struct fsl_otg_timer { + unsigned long expires; /* Number of count increase to timeout */ + unsigned long count; /* Tick counter */ + void (*function)(unsigned long); /* Timeout function */ + unsigned long data; /* Data passed to function */ + struct list_head list; +}; + +inline struct fsl_otg_timer *otg_timer_initializer +(void (*function)(unsigned long), unsigned long expires, unsigned long data) +{ + struct fsl_otg_timer *timer; + + timer = kmalloc(sizeof(struct fsl_otg_timer), GFP_KERNEL); + if (!timer) + return NULL; + timer->function = function; + timer->expires = expires; + timer->data = data; + return timer; +} + +struct fsl_otg { + struct usb_phy phy; + struct otg_fsm fsm; + struct usb_dr_mmap *dr_mem_map; + struct delayed_work otg_event; + + /* used for usb host */ + struct work_struct work_wq; + u8 host_working; + + int irq; +}; + +struct fsl_otg_config { + u8 otg_port; +}; + +/* For SRP and HNP handle */ +#define FSL_OTG_MAJOR 240 +#define FSL_OTG_NAME "fsl-usb2-otg" +/* Command to OTG driver ioctl */ +#define OTG_IOCTL_MAGIC FSL_OTG_MAJOR +/* if otg work as host, it should return 1, otherwise return 0 */ +#define GET_OTG_STATUS _IOR(OTG_IOCTL_MAGIC, 1, int) +#define SET_A_SUSPEND_REQ _IOW(OTG_IOCTL_MAGIC, 2, int) +#define SET_A_BUS_DROP _IOW(OTG_IOCTL_MAGIC, 3, int) +#define SET_A_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 4, int) +#define SET_B_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 5, int) +#define GET_A_SUSPEND_REQ _IOR(OTG_IOCTL_MAGIC, 6, int) +#define GET_A_BUS_DROP _IOR(OTG_IOCTL_MAGIC, 7, int) +#define GET_A_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 8, int) +#define GET_B_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 9, int) + +void fsl_otg_add_timer(void *timer); +void fsl_otg_del_timer(void *timer); +void fsl_otg_pulse_vbus(void); diff --git a/drivers/usb/phy/gpio_vbus.c b/drivers/usb/phy/gpio_vbus.c new file mode 100644 index 000000000000..a7d4ac591982 --- /dev/null +++ b/drivers/usb/phy/gpio_vbus.c @@ -0,0 +1,416 @@ +/* + * gpio-vbus.c - simple GPIO VBUS sensing driver for B peripheral devices + * + * Copyright (c) 2008 Philipp Zabel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +/* + * A simple GPIO VBUS sensing driver for B peripheral only devices + * with internal transceivers. It can control a D+ pullup GPIO and + * a regulator to limit the current drawn from VBUS. + * + * Needs to be loaded before the UDC driver that will use it. + */ +struct gpio_vbus_data { + struct usb_phy phy; + struct device *dev; + struct regulator *vbus_draw; + int vbus_draw_enabled; + unsigned mA; + struct delayed_work work; + int vbus; + int irq; +}; + + +/* + * This driver relies on "both edges" triggering. VBUS has 100 msec to + * stabilize, so the peripheral controller driver may need to cope with + * some bouncing due to current surges (e.g. charging local capacitance) + * and contact chatter. + * + * REVISIT in desperate straits, toggling between rising and falling + * edges might be workable. + */ +#define VBUS_IRQ_FLAGS \ + (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) + + +/* interface to regulator framework */ +static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) +{ + struct regulator *vbus_draw = gpio_vbus->vbus_draw; + int enabled; + + if (!vbus_draw) + return; + + enabled = gpio_vbus->vbus_draw_enabled; + if (mA) { + regulator_set_current_limit(vbus_draw, 0, 1000 * mA); + if (!enabled) { + regulator_enable(vbus_draw); + gpio_vbus->vbus_draw_enabled = 1; + } + } else { + if (enabled) { + regulator_disable(vbus_draw); + gpio_vbus->vbus_draw_enabled = 0; + } + } + gpio_vbus->mA = mA; +} + +static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) +{ + int vbus; + + vbus = gpio_get_value(pdata->gpio_vbus); + if (pdata->gpio_vbus_inverted) + vbus = !vbus; + + return vbus; +} + +static void gpio_vbus_work(struct work_struct *work) +{ + struct gpio_vbus_data *gpio_vbus = + container_of(work, struct gpio_vbus_data, work.work); + struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; + int gpio, status, vbus; + + if (!gpio_vbus->phy.otg->gadget) + return; + + vbus = is_vbus_powered(pdata); + if ((vbus ^ gpio_vbus->vbus) == 0) + return; + gpio_vbus->vbus = vbus; + + /* Peripheral controllers which manage the pullup themselves won't have + * gpio_pullup configured here. If it's configured here, we'll do what + * isp1301_omap::b_peripheral() does and enable the pullup here... although + * that may complicate usb_gadget_{,dis}connect() support. + */ + gpio = pdata->gpio_pullup; + + if (vbus) { + status = USB_EVENT_VBUS; + gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; + gpio_vbus->phy.last_event = status; + usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); + + /* drawing a "unit load" is *always* OK, except for OTG */ + set_vbus_draw(gpio_vbus, 100); + + /* optionally enable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, !pdata->gpio_pullup_inverted); + + atomic_notifier_call_chain(&gpio_vbus->phy.notifier, + status, gpio_vbus->phy.otg->gadget); + } else { + /* optionally disable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, pdata->gpio_pullup_inverted); + + set_vbus_draw(gpio_vbus, 0); + + usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); + status = USB_EVENT_NONE; + gpio_vbus->phy.state = OTG_STATE_B_IDLE; + gpio_vbus->phy.last_event = status; + + atomic_notifier_call_chain(&gpio_vbus->phy.notifier, + status, gpio_vbus->phy.otg->gadget); + } +} + +/* VBUS change IRQ handler */ +static irqreturn_t gpio_vbus_irq(int irq, void *data) +{ + struct platform_device *pdev = data; + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); + struct usb_otg *otg = gpio_vbus->phy.otg; + + dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", + is_vbus_powered(pdata) ? "supplied" : "inactive", + otg->gadget ? otg->gadget->name : "none"); + + if (otg->gadget) + schedule_delayed_work(&gpio_vbus->work, msecs_to_jiffies(100)); + + return IRQ_HANDLED; +} + +/* OTG transceiver interface */ + +/* bind/unbind the peripheral controller */ +static int gpio_vbus_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct gpio_vbus_data *gpio_vbus; + struct gpio_vbus_mach_info *pdata; + struct platform_device *pdev; + int gpio; + + gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); + pdev = to_platform_device(gpio_vbus->dev); + pdata = gpio_vbus->dev->platform_data; + gpio = pdata->gpio_pullup; + + if (!gadget) { + dev_dbg(&pdev->dev, "unregistering gadget '%s'\n", + otg->gadget->name); + + /* optionally disable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, pdata->gpio_pullup_inverted); + + set_vbus_draw(gpio_vbus, 0); + + usb_gadget_vbus_disconnect(otg->gadget); + otg->phy->state = OTG_STATE_UNDEFINED; + + otg->gadget = NULL; + return 0; + } + + otg->gadget = gadget; + dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name); + + /* initialize connection state */ + gpio_vbus->vbus = 0; /* start with disconnected */ + gpio_vbus_irq(gpio_vbus->irq, pdev); + return 0; +} + +/* effective for B devices, ignored for A-peripheral */ +static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) +{ + struct gpio_vbus_data *gpio_vbus; + + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); + + if (phy->state == OTG_STATE_B_PERIPHERAL) + set_vbus_draw(gpio_vbus, mA); + return 0; +} + +/* for non-OTG B devices: set/clear transceiver suspend mode */ +static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) +{ + struct gpio_vbus_data *gpio_vbus; + + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); + + /* draw max 0 mA from vbus in suspend mode; or the previously + * recorded amount of current if not suspended + * + * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA + * if they're wake-enabled ... we don't handle that yet. + */ + return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); +} + +/* platform driver interface */ + +static int __init gpio_vbus_probe(struct platform_device *pdev) +{ + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + struct gpio_vbus_data *gpio_vbus; + struct resource *res; + int err, gpio, irq; + unsigned long irqflags; + + if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) + return -EINVAL; + gpio = pdata->gpio_vbus; + + gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); + if (!gpio_vbus) + return -ENOMEM; + + gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!gpio_vbus->phy.otg) { + kfree(gpio_vbus); + return -ENOMEM; + } + + platform_set_drvdata(pdev, gpio_vbus); + gpio_vbus->dev = &pdev->dev; + gpio_vbus->phy.label = "gpio-vbus"; + gpio_vbus->phy.set_power = gpio_vbus_set_power; + gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; + gpio_vbus->phy.state = OTG_STATE_UNDEFINED; + + gpio_vbus->phy.otg->phy = &gpio_vbus->phy; + gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; + + err = gpio_request(gpio, "vbus_detect"); + if (err) { + dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", + gpio, err); + goto err_gpio; + } + gpio_direction_input(gpio); + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res) { + irq = res->start; + irqflags = (res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; + } else { + irq = gpio_to_irq(gpio); + irqflags = VBUS_IRQ_FLAGS; + } + + gpio_vbus->irq = irq; + + /* if data line pullup is in use, initialize it to "not pulling up" */ + gpio = pdata->gpio_pullup; + if (gpio_is_valid(gpio)) { + err = gpio_request(gpio, "udc_pullup"); + if (err) { + dev_err(&pdev->dev, + "can't request pullup gpio %d, err: %d\n", + gpio, err); + gpio_free(pdata->gpio_vbus); + goto err_gpio; + } + gpio_direction_output(gpio, pdata->gpio_pullup_inverted); + } + + err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); + if (err) { + dev_err(&pdev->dev, "can't request irq %i, err: %d\n", + irq, err); + goto err_irq; + } + + ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); + + INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); + + gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); + if (IS_ERR(gpio_vbus->vbus_draw)) { + dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", + PTR_ERR(gpio_vbus->vbus_draw)); + gpio_vbus->vbus_draw = NULL; + } + + /* only active when a gadget is registered */ + err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); + if (err) { + dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + err); + goto err_otg; + } + + device_init_wakeup(&pdev->dev, pdata->wakeup); + + return 0; +err_otg: + regulator_put(gpio_vbus->vbus_draw); + free_irq(irq, pdev); +err_irq: + if (gpio_is_valid(pdata->gpio_pullup)) + gpio_free(pdata->gpio_pullup); + gpio_free(pdata->gpio_vbus); +err_gpio: + platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); + kfree(gpio_vbus); + return err; +} + +static int __exit gpio_vbus_remove(struct platform_device *pdev) +{ + struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + int gpio = pdata->gpio_vbus; + + device_init_wakeup(&pdev->dev, 0); + cancel_delayed_work_sync(&gpio_vbus->work); + regulator_put(gpio_vbus->vbus_draw); + + usb_remove_phy(&gpio_vbus->phy); + + free_irq(gpio_vbus->irq, pdev); + if (gpio_is_valid(pdata->gpio_pullup)) + gpio_free(pdata->gpio_pullup); + gpio_free(gpio); + platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); + kfree(gpio_vbus); + + return 0; +} + +#ifdef CONFIG_PM +static int gpio_vbus_pm_suspend(struct device *dev) +{ + struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(gpio_vbus->irq); + + return 0; +} + +static int gpio_vbus_pm_resume(struct device *dev) +{ + struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(gpio_vbus->irq); + + return 0; +} + +static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { + .suspend = gpio_vbus_pm_suspend, + .resume = gpio_vbus_pm_resume, +}; +#endif + +/* NOTE: the gpio-vbus device may *NOT* be hotplugged */ + +MODULE_ALIAS("platform:gpio-vbus"); + +static struct platform_driver gpio_vbus_driver = { + .driver = { + .name = "gpio-vbus", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &gpio_vbus_dev_pm_ops, +#endif + }, + .remove = __exit_p(gpio_vbus_remove), +}; + +module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe); + +MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); +MODULE_AUTHOR("Philipp Zabel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/isp1301_omap.c b/drivers/usb/phy/isp1301_omap.c new file mode 100644 index 000000000000..8fe0c3b95261 --- /dev/null +++ b/drivers/usb/phy/isp1301_omap.c @@ -0,0 +1,1656 @@ +/* + * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller + * + * Copyright (C) 2004 Texas Instruments + * Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#ifndef DEBUG +#undef VERBOSE +#endif + + +#define DRIVER_VERSION "24 August 2004" +#define DRIVER_NAME (isp1301_driver.driver.name) + +MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); +MODULE_LICENSE("GPL"); + +struct isp1301 { + struct usb_phy phy; + struct i2c_client *client; + void (*i2c_release)(struct device *dev); + + int irq_type; + + u32 last_otg_ctrl; + unsigned working:1; + + struct timer_list timer; + + /* use keventd context to change the state for us */ + struct work_struct work; + + unsigned long todo; +# define WORK_UPDATE_ISP 0 /* update ISP from OTG */ +# define WORK_UPDATE_OTG 1 /* update OTG from ISP */ +# define WORK_HOST_RESUME 4 /* resume host */ +# define WORK_TIMER 6 /* timer fired */ +# define WORK_STOP 7 /* don't resubmit */ +}; + + +/* bits in OTG_CTRL */ + +#define OTG_XCEIV_OUTPUTS \ + (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) +#define OTG_XCEIV_INPUTS \ + (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID) +#define OTG_CTRL_BITS \ + (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|OTG_B_HNPEN|OTG_BUSDROP) + /* and OTG_PULLUP is sometimes written */ + +#define OTG_CTRL_MASK (OTG_DRIVER_SEL| \ + OTG_XCEIV_OUTPUTS|OTG_XCEIV_INPUTS| \ + OTG_CTRL_BITS) + + +/*-------------------------------------------------------------------------*/ + +/* board-specific PM hooks */ + +#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) + +#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) + +#include + +#else + +static inline int tps65010_set_vbus_draw(unsigned mA) +{ + pr_debug("tps65010: draw %d mA (STUB)\n", mA); + return 0; +} + +#endif + +static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) +{ + int status = tps65010_set_vbus_draw(mA); + if (status < 0) + pr_debug(" VBUS %d mA error %d\n", mA, status); +} + +#else + +static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) +{ + /* H4 controls this by DIP switch S2.4; no soft control. + * ON means the charger is always enabled. Leave it OFF + * unless the OTG port is used only in B-peripheral mode. + */ +} + +#endif + +static void enable_vbus_source(struct isp1301 *isp) +{ + /* this board won't supply more than 8mA vbus power. + * some boards can switch a 100ma "unit load" (or more). + */ +} + + +/* products will deliver OTG messages with LEDs, GUI, etc */ +static inline void notresponding(struct isp1301 *isp) +{ + printk(KERN_NOTICE "OTG device not responding.\n"); +} + + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver isp1301_driver; + +/* smbus apis are used for portability */ + +static inline u8 +isp1301_get_u8(struct isp1301 *isp, u8 reg) +{ + return i2c_smbus_read_byte_data(isp->client, reg + 0); +} + +static inline int +isp1301_get_u16(struct isp1301 *isp, u8 reg) +{ + return i2c_smbus_read_word_data(isp->client, reg); +} + +static inline int +isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) +{ + return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); +} + +static inline int +isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) +{ + return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); +} + +/*-------------------------------------------------------------------------*/ + +/* identification */ +#define ISP1301_VENDOR_ID 0x00 /* u16 read */ +#define ISP1301_PRODUCT_ID 0x02 /* u16 read */ +#define ISP1301_BCD_DEVICE 0x14 /* u16 read */ + +#define I2C_VENDOR_ID_PHILIPS 0x04cc +#define I2C_PRODUCT_ID_PHILIPS_1301 0x1301 + +/* operational registers */ +#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ +# define MC1_SPEED (1 << 0) +# define MC1_SUSPEND (1 << 1) +# define MC1_DAT_SE0 (1 << 2) +# define MC1_TRANSPARENT (1 << 3) +# define MC1_BDIS_ACON_EN (1 << 4) +# define MC1_OE_INT_EN (1 << 5) +# define MC1_UART_EN (1 << 6) +# define MC1_MASK 0x7f +#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ +# define MC2_GLOBAL_PWR_DN (1 << 0) +# define MC2_SPD_SUSP_CTRL (1 << 1) +# define MC2_BI_DI (1 << 2) +# define MC2_TRANSP_BDIR0 (1 << 3) +# define MC2_TRANSP_BDIR1 (1 << 4) +# define MC2_AUDIO_EN (1 << 5) +# define MC2_PSW_EN (1 << 6) +# define MC2_EN2V7 (1 << 7) +#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ +# define OTG1_DP_PULLUP (1 << 0) +# define OTG1_DM_PULLUP (1 << 1) +# define OTG1_DP_PULLDOWN (1 << 2) +# define OTG1_DM_PULLDOWN (1 << 3) +# define OTG1_ID_PULLDOWN (1 << 4) +# define OTG1_VBUS_DRV (1 << 5) +# define OTG1_VBUS_DISCHRG (1 << 6) +# define OTG1_VBUS_CHRG (1 << 7) +#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ +# define OTG_B_SESS_END (1 << 6) +# define OTG_B_SESS_VLD (1 << 7) + +#define ISP1301_INTERRUPT_SOURCE 0x08 /* u8 read */ +#define ISP1301_INTERRUPT_LATCH 0x0A /* u8 read, set, +1 clear */ + +#define ISP1301_INTERRUPT_FALLING 0x0C /* u8 read, set, +1 clear */ +#define ISP1301_INTERRUPT_RISING 0x0E /* u8 read, set, +1 clear */ + +/* same bitfields in all interrupt registers */ +# define INTR_VBUS_VLD (1 << 0) +# define INTR_SESS_VLD (1 << 1) +# define INTR_DP_HI (1 << 2) +# define INTR_ID_GND (1 << 3) +# define INTR_DM_HI (1 << 4) +# define INTR_ID_FLOAT (1 << 5) +# define INTR_BDIS_ACON (1 << 6) +# define INTR_CR_INT (1 << 7) + +/*-------------------------------------------------------------------------*/ + +static inline const char *state_name(struct isp1301 *isp) +{ + return usb_otg_state_string(isp->phy.state); +} + +/*-------------------------------------------------------------------------*/ + +/* NOTE: some of this ISP1301 setup is specific to H2 boards; + * not everything is guarded by board-specific checks, or even using + * omap_usb_config data to deduce MC1_DAT_SE0 and MC2_BI_DI. + * + * ALSO: this currently doesn't use ISP1301 low-power modes + * while OTG is running. + */ + +static void power_down(struct isp1301 *isp) +{ + isp->phy.state = OTG_STATE_UNDEFINED; + + // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); +} + +static void power_up(struct isp1301 *isp) +{ + // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + + /* do this only when cpu is driving transceiver, + * so host won't see a low speed device... + */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); +} + +#define NO_HOST_SUSPEND + +static int host_suspend(struct isp1301 *isp) +{ +#ifdef NO_HOST_SUSPEND + return 0; +#else + struct device *dev; + + if (!isp->phy.otg->host) + return -ENODEV; + + /* Currently ASSUMES only the OTG port matters; + * other ports could be active... + */ + dev = isp->phy.otg->host->controller; + return dev->driver->suspend(dev, 3, 0); +#endif +} + +static int host_resume(struct isp1301 *isp) +{ +#ifdef NO_HOST_SUSPEND + return 0; +#else + struct device *dev; + + if (!isp->phy.otg->host) + return -ENODEV; + + dev = isp->phy.otg->host->controller; + return dev->driver->resume(dev, 0); +#endif +} + +static int gadget_suspend(struct isp1301 *isp) +{ + isp->phy.otg->gadget->b_hnp_enable = 0; + isp->phy.otg->gadget->a_hnp_support = 0; + isp->phy.otg->gadget->a_alt_hnp_support = 0; + return usb_gadget_vbus_disconnect(isp->phy.otg->gadget); +} + +/*-------------------------------------------------------------------------*/ + +#define TIMER_MINUTES 10 +#define TIMER_JIFFIES (TIMER_MINUTES * 60 * HZ) + +/* Almost all our I2C messaging comes from a work queue's task context. + * NOTE: guaranteeing certain response times might mean we shouldn't + * share keventd's work queue; a realtime task might be safest. + */ +static void isp1301_defer_work(struct isp1301 *isp, int work) +{ + int status; + + if (isp && !test_and_set_bit(work, &isp->todo)) { + (void) get_device(&isp->client->dev); + status = schedule_work(&isp->work); + if (!status && !isp->working) + dev_vdbg(&isp->client->dev, + "work item %d may be lost\n", work); + } +} + +/* called from irq handlers */ +static void a_idle(struct isp1301 *isp, const char *tag) +{ + u32 l; + + if (isp->phy.state == OTG_STATE_A_IDLE) + return; + + isp->phy.otg->default_a = 1; + if (isp->phy.otg->host) { + isp->phy.otg->host->is_b_host = 0; + host_suspend(isp); + } + if (isp->phy.otg->gadget) { + isp->phy.otg->gadget->is_a_peripheral = 1; + gadget_suspend(isp); + } + isp->phy.state = OTG_STATE_A_IDLE; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; + pr_debug(" --> %s/%s\n", state_name(isp), tag); +} + +/* called from irq handlers */ +static void b_idle(struct isp1301 *isp, const char *tag) +{ + u32 l; + + if (isp->phy.state == OTG_STATE_B_IDLE) + return; + + isp->phy.otg->default_a = 0; + if (isp->phy.otg->host) { + isp->phy.otg->host->is_b_host = 1; + host_suspend(isp); + } + if (isp->phy.otg->gadget) { + isp->phy.otg->gadget->is_a_peripheral = 0; + gadget_suspend(isp); + } + isp->phy.state = OTG_STATE_B_IDLE; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; + pr_debug(" --> %s/%s\n", state_name(isp), tag); +} + +static void +dump_regs(struct isp1301 *isp, const char *label) +{ +#ifdef DEBUG + u8 ctrl = isp1301_get_u8(isp, ISP1301_OTG_CONTROL_1); + u8 status = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); + + pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", + omap_readl(OTG_CTRL), label, state_name(isp), + ctrl, status, src); + /* mode control and irq enables don't change much */ +#endif +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_USB_OTG + +/* + * The OMAP OTG controller handles most of the OTG state transitions. + * + * We translate isp1301 outputs (mostly voltage comparator status) into + * OTG inputs; OTG outputs (mostly pullup/pulldown controls) and HNP state + * flags into isp1301 inputs ... and infer state transitions. + */ + +#ifdef VERBOSE + +static void check_state(struct isp1301 *isp, const char *tag) +{ + enum usb_otg_state state = OTG_STATE_UNDEFINED; + u8 fsm = omap_readw(OTG_TEST) & 0x0ff; + unsigned extra = 0; + + switch (fsm) { + + /* default-b */ + case 0x0: + state = OTG_STATE_B_IDLE; + break; + case 0x3: + case 0x7: + extra = 1; + case 0x1: + state = OTG_STATE_B_PERIPHERAL; + break; + case 0x11: + state = OTG_STATE_B_SRP_INIT; + break; + + /* extra dual-role default-b states */ + case 0x12: + case 0x13: + case 0x16: + extra = 1; + case 0x17: + state = OTG_STATE_B_WAIT_ACON; + break; + case 0x34: + state = OTG_STATE_B_HOST; + break; + + /* default-a */ + case 0x36: + state = OTG_STATE_A_IDLE; + break; + case 0x3c: + state = OTG_STATE_A_WAIT_VFALL; + break; + case 0x7d: + state = OTG_STATE_A_VBUS_ERR; + break; + case 0x9e: + case 0x9f: + extra = 1; + case 0x89: + state = OTG_STATE_A_PERIPHERAL; + break; + case 0xb7: + state = OTG_STATE_A_WAIT_VRISE; + break; + case 0xb8: + state = OTG_STATE_A_WAIT_BCON; + break; + case 0xb9: + state = OTG_STATE_A_HOST; + break; + case 0xba: + state = OTG_STATE_A_SUSPEND; + break; + default: + break; + } + if (isp->phy.state == state && !extra) + return; + pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, + usb_otg_state_string(state), fsm, state_name(isp), + omap_readl(OTG_CTRL)); +} + +#else + +static inline void check_state(struct isp1301 *isp, const char *tag) { } + +#endif + +/* outputs from ISP1301_INTERRUPT_SOURCE */ +static void update_otg1(struct isp1301 *isp, u8 int_src) +{ + u32 otg_ctrl; + + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); + + if (int_src & INTR_SESS_VLD) + otg_ctrl |= OTG_ASESSVLD; + else if (isp->phy.state == OTG_STATE_A_WAIT_VFALL) { + a_idle(isp, "vfall"); + otg_ctrl &= ~OTG_CTRL_BITS; + } + if (int_src & INTR_VBUS_VLD) + otg_ctrl |= OTG_VBUSVLD; + if (int_src & INTR_ID_GND) { /* default-A */ + if (isp->phy.state == OTG_STATE_B_IDLE + || isp->phy.state + == OTG_STATE_UNDEFINED) { + a_idle(isp, "init"); + return; + } + } else { /* default-B */ + otg_ctrl |= OTG_ID; + if (isp->phy.state == OTG_STATE_A_IDLE + || isp->phy.state == OTG_STATE_UNDEFINED) { + b_idle(isp, "init"); + return; + } + } + omap_writel(otg_ctrl, OTG_CTRL); +} + +/* outputs from ISP1301_OTG_STATUS */ +static void update_otg2(struct isp1301 *isp, u8 otg_status) +{ + u32 otg_ctrl; + + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); + if (otg_status & OTG_B_SESS_VLD) + otg_ctrl |= OTG_BSESSVLD; + else if (otg_status & OTG_B_SESS_END) + otg_ctrl |= OTG_BSESSEND; + omap_writel(otg_ctrl, OTG_CTRL); +} + +/* inputs going to ISP1301 */ +static void otg_update_isp(struct isp1301 *isp) +{ + u32 otg_ctrl, otg_change; + u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; + + otg_ctrl = omap_readl(OTG_CTRL); + otg_change = otg_ctrl ^ isp->last_otg_ctrl; + isp->last_otg_ctrl = otg_ctrl; + otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; + + switch (isp->phy.state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_SRP_INIT: + if (!(otg_ctrl & OTG_PULLUP)) { + // if (otg_ctrl & OTG_B_HNPEN) { + if (isp->phy.otg->gadget->b_hnp_enable) { + isp->phy.state = OTG_STATE_B_WAIT_ACON; + pr_debug(" --> b_wait_acon\n"); + } + goto pulldown; + } +pullup: + set |= OTG1_DP_PULLUP; + clr |= OTG1_DP_PULLDOWN; + break; + case OTG_STATE_A_SUSPEND: + case OTG_STATE_A_PERIPHERAL: + if (otg_ctrl & OTG_PULLUP) + goto pullup; + /* FALLTHROUGH */ + // case OTG_STATE_B_WAIT_ACON: + default: +pulldown: + set |= OTG1_DP_PULLDOWN; + clr |= OTG1_DP_PULLUP; + break; + } + +# define toggle(OTG,ISP) do { \ + if (otg_ctrl & OTG) set |= ISP; \ + else clr |= ISP; \ + } while (0) + + if (!(isp->phy.otg->host)) + otg_ctrl &= ~OTG_DRV_VBUS; + + switch (isp->phy.state) { + case OTG_STATE_A_SUSPEND: + if (otg_ctrl & OTG_DRV_VBUS) { + set |= OTG1_VBUS_DRV; + break; + } + /* HNP failed for some reason (A_AIDL_BDIS timeout) */ + notresponding(isp); + + /* FALLTHROUGH */ + case OTG_STATE_A_VBUS_ERR: + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + pr_debug(" --> a_wait_vfall\n"); + /* FALLTHROUGH */ + case OTG_STATE_A_WAIT_VFALL: + /* FIXME usbcore thinks port power is still on ... */ + clr |= OTG1_VBUS_DRV; + break; + case OTG_STATE_A_IDLE: + if (otg_ctrl & OTG_DRV_VBUS) { + isp->phy.state = OTG_STATE_A_WAIT_VRISE; + pr_debug(" --> a_wait_vrise\n"); + } + /* FALLTHROUGH */ + default: + toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); + } + + toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); + toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); + +# undef toggle + + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); + + /* HNP switch to host or peripheral; and SRP */ + if (otg_change & OTG_PULLUP) { + u32 l; + + switch (isp->phy.state) { + case OTG_STATE_B_IDLE: + if (clr & OTG1_DP_PULLUP) + break; + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + break; + case OTG_STATE_A_SUSPEND: + if (clr & OTG1_DP_PULLUP) + break; + isp->phy.state = OTG_STATE_A_PERIPHERAL; + pr_debug(" --> a_peripheral\n"); + break; + default: + break; + } + l = omap_readl(OTG_CTRL); + l |= OTG_PULLUP; + omap_writel(l, OTG_CTRL); + } + + check_state(isp, __func__); + dump_regs(isp, "otg->isp1301"); +} + +static irqreturn_t omap_otg_irq(int irq, void *_isp) +{ + u16 otg_irq = omap_readw(OTG_IRQ_SRC); + u32 otg_ctrl; + int ret = IRQ_NONE; + struct isp1301 *isp = _isp; + struct usb_otg *otg = isp->phy.otg; + + /* update ISP1301 transceiver from OTG controller */ + if (otg_irq & OPRT_CHG) { + omap_writew(OPRT_CHG, OTG_IRQ_SRC); + isp1301_defer_work(isp, WORK_UPDATE_ISP); + ret = IRQ_HANDLED; + + /* SRP to become b_peripheral failed */ + } else if (otg_irq & B_SRP_TMROUT) { + pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); + notresponding(isp); + + /* gadget drivers that care should monitor all kinds of + * remote wakeup (SRP, normal) using their own timer + * to give "check cable and A-device" messages. + */ + if (isp->phy.state == OTG_STATE_B_SRP_INIT) + b_idle(isp, "srp_timeout"); + + omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* HNP to become b_host failed */ + } else if (otg_irq & B_HNP_FAIL) { + pr_debug("otg: %s B_HNP_FAIL, %06x\n", + state_name(isp), omap_readl(OTG_CTRL)); + notresponding(isp); + + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + + /* subset of b_peripheral()... */ + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + + omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* detect SRP from B-device ... */ + } else if (otg_irq & A_SRP_DETECT) { + pr_debug("otg: %s SRP_DETECT, %06x\n", + state_name(isp), omap_readl(OTG_CTRL)); + + isp1301_defer_work(isp, WORK_UPDATE_OTG); + switch (isp->phy.state) { + case OTG_STATE_A_IDLE: + if (!otg->host) + break; + isp1301_defer_work(isp, WORK_HOST_RESUME); + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_A_BUSREQ; + otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) + & ~OTG_XCEIV_INPUTS + & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + break; + default: + break; + } + + omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) + * we don't track them separately + */ + } else if (otg_irq & A_REQ_TMROUT) { + otg_ctrl = omap_readl(OTG_CTRL); + pr_info("otg: BCON_TMOUT from %s, %06x\n", + state_name(isp), otg_ctrl); + notresponding(isp); + + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + + omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* A-supplied voltage fell too low; overcurrent */ + } else if (otg_irq & A_VBUS_ERR) { + otg_ctrl = omap_readl(OTG_CTRL); + printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", + state_name(isp), otg_irq, otg_ctrl); + + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_A_VBUS_ERR; + + omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* switch driver; the transceiver code activates it, + * ungating the udc clock or resuming OHCI. + */ + } else if (otg_irq & DRIVER_SWITCH) { + int kick = 0; + + otg_ctrl = omap_readl(OTG_CTRL); + printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", + state_name(isp), + (otg_ctrl & OTG_DRIVER_SEL) + ? "gadget" : "host", + otg_ctrl); + isp1301_defer_work(isp, WORK_UPDATE_ISP); + + /* role is peripheral */ + if (otg_ctrl & OTG_DRIVER_SEL) { + switch (isp->phy.state) { + case OTG_STATE_A_IDLE: + b_idle(isp, __func__); + break; + default: + break; + } + isp1301_defer_work(isp, WORK_UPDATE_ISP); + + /* role is host */ + } else { + if (!(otg_ctrl & OTG_ID)) { + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); + } + + if (otg->host) { + switch (isp->phy.state) { + case OTG_STATE_B_WAIT_ACON: + isp->phy.state = OTG_STATE_B_HOST; + pr_debug(" --> b_host\n"); + kick = 1; + break; + case OTG_STATE_A_WAIT_BCON: + isp->phy.state = OTG_STATE_A_HOST; + pr_debug(" --> a_host\n"); + break; + case OTG_STATE_A_PERIPHERAL: + isp->phy.state = OTG_STATE_A_WAIT_BCON; + pr_debug(" --> a_wait_bcon\n"); + break; + default: + break; + } + isp1301_defer_work(isp, WORK_HOST_RESUME); + } + } + + omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + if (kick) + usb_bus_start_enum(otg->host, otg->host->otg_port); + } + + check_state(isp, __func__); + return ret; +} + +static struct platform_device *otg_dev; + +static int isp1301_otg_init(struct isp1301 *isp) +{ + u32 l; + + if (!otg_dev) + return -ENODEV; + + dump_regs(isp, __func__); + /* some of these values are board-specific... */ + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN + /* for B-device: */ + | SRP_GPDATA /* 9msec Bdev D+ pulse */ + | SRP_GPDVBUS /* discharge after VBUS pulse */ + // | (3 << 24) /* 2msec VBUS pulse */ + /* for A-device: */ + | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */ + | SRP_DPW /* detect 167+ns SRP pulses */ + | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ + ; + omap_writel(l, OTG_SYSCON_2); + + update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); + update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); + + check_state(isp, __func__); + pr_debug("otg: %s, %s %06x\n", + state_name(isp), __func__, omap_readl(OTG_CTRL)); + + omap_writew(DRIVER_SWITCH | OPRT_CHG + | B_SRP_TMROUT | B_HNP_FAIL + | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); + + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN; + omap_writel(l, OTG_SYSCON_2); + + return 0; +} + +static int otg_probe(struct platform_device *dev) +{ + // struct omap_usb_config *config = dev->platform_data; + + otg_dev = dev; + return 0; +} + +static int otg_remove(struct platform_device *dev) +{ + otg_dev = NULL; + return 0; +} + +static struct platform_driver omap_otg_driver = { + .probe = otg_probe, + .remove = otg_remove, + .driver = { + .owner = THIS_MODULE, + .name = "omap_otg", + }, +}; + +static int otg_bind(struct isp1301 *isp) +{ + int status; + + if (otg_dev) + return -EBUSY; + + status = platform_driver_register(&omap_otg_driver); + if (status < 0) + return status; + + if (otg_dev) + status = request_irq(otg_dev->resource[1].start, omap_otg_irq, + 0, DRIVER_NAME, isp); + else + status = -ENODEV; + + if (status < 0) + platform_driver_unregister(&omap_otg_driver); + return status; +} + +static void otg_unbind(struct isp1301 *isp) +{ + if (!otg_dev) + return; + free_irq(otg_dev->resource[1].start, isp); +} + +#else + +/* OTG controller isn't clocked */ + +#endif /* CONFIG_USB_OTG */ + +/*-------------------------------------------------------------------------*/ + +static void b_peripheral(struct isp1301 *isp) +{ + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + + usb_gadget_vbus_connect(isp->phy.otg->gadget); + +#ifdef CONFIG_USB_OTG + enable_vbus_draw(isp, 8); + otg_update_isp(isp); +#else + enable_vbus_draw(isp, 100); + /* UDC driver just set OTG_BSESSVLD */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + dump_regs(isp, "2periph"); +#endif +} + +static void isp_update_otg(struct isp1301 *isp, u8 stat) +{ + struct usb_otg *otg = isp->phy.otg; + u8 isp_stat, isp_bstat; + enum usb_otg_state state = isp->phy.state; + + if (stat & INTR_BDIS_ACON) + pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); + + /* start certain state transitions right away */ + isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); + if (isp_stat & INTR_ID_GND) { + if (otg->default_a) { + switch (state) { + case OTG_STATE_B_IDLE: + a_idle(isp, "idle"); + /* FALLTHROUGH */ + case OTG_STATE_A_IDLE: + enable_vbus_source(isp); + /* FALLTHROUGH */ + case OTG_STATE_A_WAIT_VRISE: + /* we skip over OTG_STATE_A_WAIT_BCON, since + * the HC will transition to A_HOST (or + * A_SUSPEND!) without our noticing except + * when HNP is used. + */ + if (isp_stat & INTR_VBUS_VLD) + isp->phy.state = OTG_STATE_A_HOST; + break; + case OTG_STATE_A_WAIT_VFALL: + if (!(isp_stat & INTR_SESS_VLD)) + a_idle(isp, "vfell"); + break; + default: + if (!(isp_stat & INTR_VBUS_VLD)) + isp->phy.state = OTG_STATE_A_VBUS_ERR; + break; + } + isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + } else { + switch (state) { + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_HOST: + case OTG_STATE_B_WAIT_ACON: + usb_gadget_vbus_disconnect(otg->gadget); + break; + default: + break; + } + if (state != OTG_STATE_A_IDLE) + a_idle(isp, "id"); + if (otg->host && state == OTG_STATE_A_IDLE) + isp1301_defer_work(isp, WORK_HOST_RESUME); + isp_bstat = 0; + } + } else { + u32 l; + + /* if user unplugged mini-A end of cable, + * don't bypass A_WAIT_VFALL. + */ + if (otg->default_a) { + switch (state) { + default: + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + break; + case OTG_STATE_A_WAIT_VFALL: + state = OTG_STATE_A_IDLE; + /* khubd may take a while to notice and + * handle this disconnect, so don't go + * to B_IDLE quite yet. + */ + break; + case OTG_STATE_A_IDLE: + host_suspend(isp); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_BDIS_ACON_EN); + isp->phy.state = OTG_STATE_B_IDLE; + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~OTG_CTRL_BITS; + omap_writel(l, OTG_CTRL); + break; + case OTG_STATE_B_IDLE: + break; + } + } + isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + + switch (isp->phy.state) { + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_WAIT_ACON: + case OTG_STATE_B_HOST: + if (likely(isp_bstat & OTG_B_SESS_VLD)) + break; + enable_vbus_draw(isp, 0); +#ifndef CONFIG_USB_OTG + /* UDC driver will clear OTG_BSESSVLD */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DP_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DP_PULLUP); + dump_regs(isp, __func__); +#endif + /* FALLTHROUGH */ + case OTG_STATE_B_SRP_INIT: + b_idle(isp, __func__); + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + /* FALLTHROUGH */ + case OTG_STATE_B_IDLE: + if (otg->gadget && (isp_bstat & OTG_B_SESS_VLD)) { +#ifdef CONFIG_USB_OTG + update_otg1(isp, isp_stat); + update_otg2(isp, isp_bstat); +#endif + b_peripheral(isp); + } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) + isp_bstat |= OTG_B_SESS_END; + break; + case OTG_STATE_A_WAIT_VFALL: + break; + default: + pr_debug("otg: unsupported b-device %s\n", + state_name(isp)); + break; + } + } + + if (state != isp->phy.state) + pr_debug(" isp, %s -> %s\n", + usb_otg_state_string(state), state_name(isp)); + +#ifdef CONFIG_USB_OTG + /* update the OTG controller state to match the isp1301; may + * trigger OPRT_CHG irqs for changes going to the isp1301. + */ + update_otg1(isp, isp_stat); + update_otg2(isp, isp_bstat); + check_state(isp, __func__); +#endif + + dump_regs(isp, "isp1301->otg"); +} + +/*-------------------------------------------------------------------------*/ + +static u8 isp1301_clear_latch(struct isp1301 *isp) +{ + u8 latch = isp1301_get_u8(isp, ISP1301_INTERRUPT_LATCH); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, latch); + return latch; +} + +static void +isp1301_work(struct work_struct *work) +{ + struct isp1301 *isp = container_of(work, struct isp1301, work); + int stop; + + /* implicit lock: we're the only task using this device */ + isp->working = 1; + do { + stop = test_bit(WORK_STOP, &isp->todo); + +#ifdef CONFIG_USB_OTG + /* transfer state from otg engine to isp1301 */ + if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { + otg_update_isp(isp); + put_device(&isp->client->dev); + } +#endif + /* transfer state from isp1301 to otg engine */ + if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { + u8 stat = isp1301_clear_latch(isp); + + isp_update_otg(isp, stat); + put_device(&isp->client->dev); + } + + if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { + u32 otg_ctrl; + + /* + * skip A_WAIT_VRISE; hc transitions invisibly + * skip A_WAIT_BCON; same. + */ + switch (isp->phy.state) { + case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_WAIT_VRISE: + isp->phy.state = OTG_STATE_A_HOST; + pr_debug(" --> a_host\n"); + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_A_BUSREQ; + otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) + & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + break; + case OTG_STATE_B_WAIT_ACON: + isp->phy.state = OTG_STATE_B_HOST; + pr_debug(" --> b_host (acon)\n"); + break; + case OTG_STATE_B_HOST: + case OTG_STATE_B_IDLE: + case OTG_STATE_A_IDLE: + break; + default: + pr_debug(" host resume in %s\n", + state_name(isp)); + } + host_resume(isp); + // mdelay(10); + put_device(&isp->client->dev); + } + + if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { +#ifdef VERBOSE + dump_regs(isp, "timer"); + if (!stop) + mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); +#endif + put_device(&isp->client->dev); + } + + if (isp->todo) + dev_vdbg(&isp->client->dev, + "work done, todo = 0x%lx\n", + isp->todo); + if (stop) { + dev_dbg(&isp->client->dev, "stop\n"); + break; + } + } while (isp->todo); + isp->working = 0; +} + +static irqreturn_t isp1301_irq(int irq, void *isp) +{ + isp1301_defer_work(isp, WORK_UPDATE_OTG); + return IRQ_HANDLED; +} + +static void isp1301_timer(unsigned long _isp) +{ + isp1301_defer_work((void *)_isp, WORK_TIMER); +} + +/*-------------------------------------------------------------------------*/ + +static void isp1301_release(struct device *dev) +{ + struct isp1301 *isp; + + isp = dev_get_drvdata(dev); + + /* FIXME -- not with a "new style" driver, it doesn't!! */ + + /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ + if (isp->i2c_release) + isp->i2c_release(dev); + kfree(isp->phy.otg); + kfree (isp); +} + +static struct isp1301 *the_transceiver; + +static int __exit isp1301_remove(struct i2c_client *i2c) +{ + struct isp1301 *isp; + + isp = i2c_get_clientdata(i2c); + + isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); + free_irq(i2c->irq, isp); +#ifdef CONFIG_USB_OTG + otg_unbind(isp); +#endif + if (machine_is_omap_h2()) + gpio_free(2); + + isp->timer.data = 0; + set_bit(WORK_STOP, &isp->todo); + del_timer_sync(&isp->timer); + flush_work(&isp->work); + + put_device(&i2c->dev); + the_transceiver = NULL; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* NOTE: three modes are possible here, only one of which + * will be standards-conformant on any given system: + * + * - OTG mode (dual-role), required if there's a Mini-AB connector + * - HOST mode, for when there's one or more A (host) connectors + * - DEVICE mode, for when there's a B/Mini-B (device) connector + * + * As a rule, you won't have an isp1301 chip unless it's there to + * support the OTG mode. Other modes help testing USB controllers + * in isolation from (full) OTG support, or maybe so later board + * revisions can help to support those feature. + */ + +#ifdef CONFIG_USB_OTG + +static int isp1301_otg_enable(struct isp1301 *isp) +{ + power_up(isp); + isp1301_otg_init(isp); + + /* NOTE: since we don't change this, this provides + * a few more interrupts than are strictly needed. + */ + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + + dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); + + return 0; +} + +#endif + +/* add or disable the host device+driver */ +static int +isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + + if (!otg || isp != the_transceiver) + return -ENODEV; + + if (!host) { + omap_writew(0, OTG_IRQ_EN); + power_down(isp); + otg->host = NULL; + return 0; + } + +#ifdef CONFIG_USB_OTG + otg->host = host; + dev_dbg(&isp->client->dev, "registered host\n"); + host_suspend(isp); + if (otg->gadget) + return isp1301_otg_enable(isp); + return 0; + +#elif !defined(CONFIG_USB_GADGET_OMAP) + // FIXME update its refcount + otg->host = host; + + power_up(isp); + + if (machine_is_omap_h2()) + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); + + dev_info(&isp->client->dev, "A-Host sessions ok\n"); + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_ID_GND); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_ID_GND); + + /* If this has a Mini-AB connector, this mode is highly + * nonstandard ... but can be handy for testing, especially with + * the Mini-A end of an OTG cable. (Or something nonstandard + * like MiniB-to-StandardB, maybe built with a gender mender.) + */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); + + dump_regs(isp, __func__); + + return 0; + +#else + dev_dbg(&isp->client->dev, "host sessions not allowed\n"); + return -EINVAL; +#endif + +} + +static int +isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + + if (!otg || isp != the_transceiver) + return -ENODEV; + + if (!gadget) { + omap_writew(0, OTG_IRQ_EN); + if (!otg->default_a) + enable_vbus_draw(isp, 0); + usb_gadget_vbus_disconnect(otg->gadget); + otg->gadget = NULL; + power_down(isp); + return 0; + } + +#ifdef CONFIG_USB_OTG + otg->gadget = gadget; + dev_dbg(&isp->client->dev, "registered gadget\n"); + /* gadget driver may be suspended until vbus_connect () */ + if (otg->host) + return isp1301_otg_enable(isp); + return 0; + +#elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) + otg->gadget = gadget; + // FIXME update its refcount + + { + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); + l |= OTG_ID; + omap_writel(l, OTG_CTRL); + } + + power_up(isp); + isp->phy.state = OTG_STATE_B_IDLE; + + if (machine_is_omap_h2() || machine_is_omap_h3()) + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); + + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_SESS_VLD); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_VBUS_VLD); + dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); + dump_regs(isp, __func__); + + /* If this has a Mini-AB connector, this mode is highly + * nonstandard ... but can be handy for testing, so long + * as you don't plug a Mini-A cable into the jack. + */ + if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) + b_peripheral(isp); + + return 0; + +#else + dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); + return -EINVAL; +#endif +} + + +/*-------------------------------------------------------------------------*/ + +static int +isp1301_set_power(struct usb_phy *dev, unsigned mA) +{ + if (!the_transceiver) + return -ENODEV; + if (dev->state == OTG_STATE_B_PERIPHERAL) + enable_vbus_draw(the_transceiver, mA); + return 0; +} + +static int +isp1301_start_srp(struct usb_otg *otg) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + u32 otg_ctrl; + + if (!otg || isp != the_transceiver + || isp->phy.state != OTG_STATE_B_IDLE) + return -ENODEV; + + otg_ctrl = omap_readl(OTG_CTRL); + if (!(otg_ctrl & OTG_BSESSEND)) + return -EINVAL; + + otg_ctrl |= OTG_B_BUSREQ; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_B_SRP_INIT; + + pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), + omap_readl(OTG_CTRL)); +#ifdef CONFIG_USB_OTG + check_state(isp, __func__); +#endif + return 0; +} + +static int +isp1301_start_hnp(struct usb_otg *otg) +{ +#ifdef CONFIG_USB_OTG + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + u32 l; + + if (!otg || isp != the_transceiver) + return -ENODEV; + if (otg->default_a && (otg->host == NULL || !otg->host->b_hnp_enable)) + return -ENOTCONN; + if (!otg->default_a && (otg->gadget == NULL + || !otg->gadget->b_hnp_enable)) + return -ENOTCONN; + + /* We want hardware to manage most HNP protocol timings. + * So do this part as early as possible... + */ + switch (isp->phy.state) { + case OTG_STATE_B_HOST: + isp->phy.state = OTG_STATE_B_PERIPHERAL; + /* caller will suspend next */ + break; + case OTG_STATE_A_HOST: +#if 0 + /* autoconnect mode avoids irq latency bugs */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_BDIS_ACON_EN); +#endif + /* caller must suspend then clear A_BUSREQ */ + usb_gadget_vbus_connect(otg->gadget); + l = omap_readl(OTG_CTRL); + l |= OTG_A_SETB_HNPEN; + omap_writel(l, OTG_CTRL); + + break; + case OTG_STATE_A_PERIPHERAL: + /* initiated by B-Host suspend */ + break; + default: + return -EILSEQ; + } + pr_debug("otg: HNP %s, %06x ...\n", + state_name(isp), omap_readl(OTG_CTRL)); + check_state(isp, __func__); + return 0; +#else + /* srp-only */ + return -EINVAL; +#endif +} + +/*-------------------------------------------------------------------------*/ + +static int +isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + int status; + struct isp1301 *isp; + + if (the_transceiver) + return 0; + + isp = kzalloc(sizeof *isp, GFP_KERNEL); + if (!isp) + return 0; + + isp->phy.otg = kzalloc(sizeof *isp->phy.otg, GFP_KERNEL); + if (!isp->phy.otg) { + kfree(isp); + return 0; + } + + INIT_WORK(&isp->work, isp1301_work); + init_timer(&isp->timer); + isp->timer.function = isp1301_timer; + isp->timer.data = (unsigned long) isp; + + i2c_set_clientdata(i2c, isp); + isp->client = i2c; + + /* verify the chip (shouldn't be necessary) */ + status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); + if (status != I2C_VENDOR_ID_PHILIPS) { + dev_dbg(&i2c->dev, "not philips id: %d\n", status); + goto fail; + } + status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); + if (status != I2C_PRODUCT_ID_PHILIPS_1301) { + dev_dbg(&i2c->dev, "not isp1301, %d\n", status); + goto fail; + } + isp->i2c_release = i2c->dev.release; + i2c->dev.release = isp1301_release; + + /* initial development used chiprev 2.00 */ + status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); + dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", + status >> 8, status & 0xff); + + /* make like power-on reset */ + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); + + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); + + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, + ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); + + isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); + +#ifdef CONFIG_USB_OTG + status = otg_bind(isp); + if (status < 0) { + dev_dbg(&i2c->dev, "can't bind OTG\n"); + goto fail; + } +#endif + + if (machine_is_omap_h2()) { + /* full speed signaling by default */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_SPEED); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, + MC2_SPD_SUSP_CTRL); + + /* IRQ wired at M14 */ + omap_cfg_reg(M14_1510_GPIO2); + if (gpio_request(2, "isp1301") == 0) + gpio_direction_input(2); + isp->irq_type = IRQF_TRIGGER_FALLING; + } + + status = request_irq(i2c->irq, isp1301_irq, + isp->irq_type, DRIVER_NAME, isp); + if (status < 0) { + dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", + i2c->irq, status); + goto fail; + } + + isp->phy.dev = &i2c->dev; + isp->phy.label = DRIVER_NAME; + isp->phy.set_power = isp1301_set_power, + + isp->phy.otg->phy = &isp->phy; + isp->phy.otg->set_host = isp1301_set_host, + isp->phy.otg->set_peripheral = isp1301_set_peripheral, + isp->phy.otg->start_srp = isp1301_start_srp, + isp->phy.otg->start_hnp = isp1301_start_hnp, + + enable_vbus_draw(isp, 0); + power_down(isp); + the_transceiver = isp; + +#ifdef CONFIG_USB_OTG + update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); + update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); +#endif + + dump_regs(isp, __func__); + +#ifdef VERBOSE + mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); + dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); +#endif + + status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); + if (status < 0) + dev_err(&i2c->dev, "can't register transceiver, %d\n", + status); + + return 0; + +fail: + kfree(isp->phy.otg); + kfree(isp); + return -ENODEV; +} + +static const struct i2c_device_id isp1301_id[] = { + { "isp1301_omap", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, isp1301_id); + +static struct i2c_driver isp1301_driver = { + .driver = { + .name = "isp1301_omap", + }, + .probe = isp1301_probe, + .remove = __exit_p(isp1301_remove), + .id_table = isp1301_id, +}; + +/*-------------------------------------------------------------------------*/ + +static int __init isp_init(void) +{ + return i2c_add_driver(&isp1301_driver); +} +subsys_initcall(isp_init); + +static void __exit isp_exit(void) +{ + if (the_transceiver) + usb_remove_phy(&the_transceiver->phy); + i2c_del_driver(&isp1301_driver); +} +module_exit(isp_exit); + diff --git a/drivers/usb/phy/msm_otg.c b/drivers/usb/phy/msm_otg.c new file mode 100644 index 000000000000..749fbf41fb6f --- /dev/null +++ b/drivers/usb/phy/msm_otg.c @@ -0,0 +1,1762 @@ +/* Copyright (c) 2009-2011, 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 +#include +#include +#include + +#include + +#define MSM_USB_BASE (motg->regs) +#define DRIVER_NAME "msm_otg" + +#define ULPI_IO_TIMEOUT_USEC (10 * 1000) + +#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ +#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ +#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */ +#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */ + +#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */ +#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */ +#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ +#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ + +#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ +#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ + +static struct regulator *hsusb_3p3; +static struct regulator *hsusb_1p8; +static struct regulator *hsusb_vddcx; + +static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) +{ + int ret = 0; + + if (init) { + hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); + if (IS_ERR(hsusb_vddcx)) { + dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); + return PTR_ERR(hsusb_vddcx); + } + + ret = regulator_set_voltage(hsusb_vddcx, + USB_PHY_VDD_DIG_VOL_MIN, + USB_PHY_VDD_DIG_VOL_MAX); + if (ret) { + dev_err(motg->phy.dev, "unable to set the voltage " + "for hsusb vddcx\n"); + regulator_put(hsusb_vddcx); + return ret; + } + + ret = regulator_enable(hsusb_vddcx); + if (ret) { + dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); + regulator_put(hsusb_vddcx); + } + } else { + ret = regulator_set_voltage(hsusb_vddcx, 0, + USB_PHY_VDD_DIG_VOL_MAX); + if (ret) + dev_err(motg->phy.dev, "unable to set the voltage " + "for hsusb vddcx\n"); + ret = regulator_disable(hsusb_vddcx); + if (ret) + dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); + + regulator_put(hsusb_vddcx); + } + + return ret; +} + +static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) +{ + int rc = 0; + + if (init) { + hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); + if (IS_ERR(hsusb_3p3)) { + dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); + return PTR_ERR(hsusb_3p3); + } + + rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, + USB_PHY_3P3_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "unable to set voltage level " + "for hsusb 3p3\n"); + goto put_3p3; + } + rc = regulator_enable(hsusb_3p3); + if (rc) { + dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); + goto put_3p3; + } + hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); + if (IS_ERR(hsusb_1p8)) { + dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); + rc = PTR_ERR(hsusb_1p8); + goto disable_3p3; + } + rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, + USB_PHY_1P8_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "unable to set voltage level " + "for hsusb 1p8\n"); + goto put_1p8; + } + rc = regulator_enable(hsusb_1p8); + if (rc) { + dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); + goto put_1p8; + } + + return 0; + } + + regulator_disable(hsusb_1p8); +put_1p8: + regulator_put(hsusb_1p8); +disable_3p3: + regulator_disable(hsusb_3p3); +put_3p3: + regulator_put(hsusb_3p3); + return rc; +} + +#ifdef CONFIG_PM_SLEEP +#define USB_PHY_SUSP_DIG_VOL 500000 +static int msm_hsusb_config_vddcx(int high) +{ + int max_vol = USB_PHY_VDD_DIG_VOL_MAX; + int min_vol; + int ret; + + if (high) + min_vol = USB_PHY_VDD_DIG_VOL_MIN; + else + min_vol = USB_PHY_SUSP_DIG_VOL; + + ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); + if (ret) { + pr_err("%s: unable to set the voltage for regulator " + "HSUSB_VDDCX\n", __func__); + return ret; + } + + pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); + + return ret; +} +#endif + +static int msm_hsusb_ldo_set_mode(int on) +{ + int ret = 0; + + if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { + pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); + return -ENODEV; + } + + if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { + pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); + return -ENODEV; + } + + if (on) { + ret = regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_HPM_LOAD); + if (ret < 0) { + pr_err("%s: Unable to set HPM of the regulator " + "HSUSB_1p8\n", __func__); + return ret; + } + ret = regulator_set_optimum_mode(hsusb_3p3, + USB_PHY_3P3_HPM_LOAD); + if (ret < 0) { + pr_err("%s: Unable to set HPM of the regulator " + "HSUSB_3p3\n", __func__); + regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_LPM_LOAD); + return ret; + } + } else { + ret = regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_LPM_LOAD); + if (ret < 0) + pr_err("%s: Unable to set LPM of the regulator " + "HSUSB_1p8\n", __func__); + ret = regulator_set_optimum_mode(hsusb_3p3, + USB_PHY_3P3_LPM_LOAD); + if (ret < 0) + pr_err("%s: Unable to set LPM of the regulator " + "HSUSB_3p3\n", __func__); + } + + pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); + return ret < 0 ? ret : 0; +} + +static int ulpi_read(struct usb_phy *phy, u32 reg) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + int cnt = 0; + + /* initiate read operation */ + writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(phy->dev, "ulpi_read: timeout %08x\n", + readl(USB_ULPI_VIEWPORT)); + return -ETIMEDOUT; + } + return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); +} + +static int ulpi_write(struct usb_phy *phy, u32 val, u32 reg) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + int cnt = 0; + + /* initiate write operation */ + writel(ULPI_RUN | ULPI_WRITE | + ULPI_ADDR(reg) | ULPI_DATA(val), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(phy->dev, "ulpi_write: timeout\n"); + return -ETIMEDOUT; + } + return 0; +} + +static struct usb_phy_io_ops msm_otg_io_ops = { + .read = ulpi_read, + .write = ulpi_write, +}; + +static void ulpi_init(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + int *seq = pdata->phy_init_seq; + + if (!seq) + return; + + while (seq[0] >= 0) { + dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", + seq[0], seq[1]); + ulpi_write(&motg->phy, seq[0], seq[1]); + seq += 2; + } +} + +static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) +{ + int ret; + + if (assert) { + ret = clk_reset(motg->clk, CLK_RESET_ASSERT); + if (ret) + dev_err(motg->phy.dev, "usb hs_clk assert failed\n"); + } else { + ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->phy.dev, "usb hs_clk deassert failed\n"); + } + return ret; +} + +static int msm_otg_phy_clk_reset(struct msm_otg *motg) +{ + int ret; + + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); + if (ret) { + dev_err(motg->phy.dev, "usb phy clk assert failed\n"); + return ret; + } + usleep_range(10000, 12000); + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->phy.dev, "usb phy clk deassert failed\n"); + return ret; +} + +static int msm_otg_phy_reset(struct msm_otg *motg) +{ + u32 val; + int ret; + int retries; + + ret = msm_otg_link_clk_reset(motg, 1); + if (ret) + return ret; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + ret = msm_otg_link_clk_reset(motg, 0); + if (ret) + return ret; + + val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; + writel(val | PORTSC_PTS_ULPI, USB_PORTSC); + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, + ULPI_CLR(ULPI_FUNC_CTRL)); + if (!ret) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + /* This reset calibrates the phy, if the above write succeeded */ + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_read(&motg->phy, ULPI_DEBUG); + if (ret != -ETIMEDOUT) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + dev_info(motg->phy.dev, "phy_reset: success\n"); + return 0; +} + +#define LINK_RESET_TIMEOUT_USEC (250 * 1000) +static int msm_otg_reset(struct usb_phy *phy) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + int ret; + u32 val = 0; + u32 ulpi_val = 0; + + ret = msm_otg_phy_reset(motg); + if (ret) { + dev_err(phy->dev, "phy_reset failed\n"); + return ret; + } + + ulpi_init(motg); + + writel(USBCMD_RESET, USB_USBCMD); + while (cnt < LINK_RESET_TIMEOUT_USEC) { + if (!(readl(USB_USBCMD) & USBCMD_RESET)) + break; + udelay(1); + cnt++; + } + if (cnt >= LINK_RESET_TIMEOUT_USEC) + return -ETIMEDOUT; + + /* select ULPI phy */ + writel(0x80000000, USB_PORTSC); + + msleep(100); + + writel(0x0, USB_AHBBURST); + writel(0x00, USB_AHBMODE); + + if (pdata->otg_control == OTG_PHY_CONTROL) { + val = readl(USB_OTGSC); + if (pdata->mode == USB_OTG) { + ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; + val |= OTGSC_IDIE | OTGSC_BSVIE; + } else if (pdata->mode == USB_PERIPHERAL) { + ulpi_val = ULPI_INT_SESS_VALID; + val |= OTGSC_BSVIE; + } + writel(val, USB_OTGSC); + ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_RISE); + ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); + } + + return 0; +} + +#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) +#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_suspend(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + struct usb_bus *bus = phy->otg->host; + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + + if (atomic_read(&motg->in_lpm)) + return 0; + + disable_irq(motg->irq); + /* + * Chipidea 45-nm PHY suspend sequence: + * + * Interrupt Latch Register auto-clear feature is not present + * in all PHY versions. Latch register is clear on read type. + * Clear latch register to avoid spurious wakeup from + * low power mode (LPM). + * + * PHY comparators are disabled when PHY enters into low power + * mode (LPM). Keep PHY comparators ON in LPM only when we expect + * VBUS/Id notifications from USB PHY. Otherwise turn off USB + * PHY comparators. This save significant amount of power. + * + * PLL is not turned off when PHY enters into low power mode (LPM). + * Disable PLL for maximum power savings. + */ + + if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) { + ulpi_read(phy, 0x14); + if (pdata->otg_control == OTG_PHY_CONTROL) + ulpi_write(phy, 0x01, 0x30); + ulpi_write(phy, 0x08, 0x09); + } + + /* + * PHY may take some time or even fail to enter into low power + * mode (LPM). Hence poll for 500 msec and reset the PHY and link + * in failure case. + */ + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { + dev_err(phy->dev, "Unable to suspend PHY\n"); + msm_otg_reset(phy); + enable_irq(motg->irq); + return -ETIMEDOUT; + } + + /* + * PHY has capability to generate interrupt asynchronously in low + * power mode (LPM). This interrupt is level triggered. So USB IRQ + * line must be disabled till async interrupt enable bit is cleared + * in USBCMD register. Assert STP (ULPI interface STOP signal) to + * block data communication from PHY. + */ + writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) + writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + + if (!IS_ERR(motg->pclk_src)) + clk_disable(motg->pclk_src); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(0); + msm_hsusb_config_vddcx(0); + } + + if (device_may_wakeup(phy->dev)) + enable_irq_wake(motg->irq); + if (bus) + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + atomic_set(&motg->in_lpm, 1); + enable_irq(motg->irq); + + dev_info(phy->dev, "USB in low power mode\n"); + + return 0; +} + +static int msm_otg_resume(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + struct usb_bus *bus = phy->otg->host; + int cnt = 0; + unsigned temp; + + if (!atomic_read(&motg->in_lpm)) + return 0; + + if (!IS_ERR(motg->pclk_src)) + clk_enable(motg->pclk_src); + + clk_enable(motg->pclk); + clk_enable(motg->clk); + if (motg->core_clk) + clk_enable(motg->core_clk); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(1); + msm_hsusb_config_vddcx(1); + writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); + } + + temp = readl(USB_USBCMD); + temp &= ~ASYNC_INTR_CTRL; + temp &= ~ULPI_STP_CTRL; + writel(temp, USB_USBCMD); + + /* + * PHY comes out of low power mode (LPM) in case of wakeup + * from asynchronous interrupt. + */ + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + goto skip_phy_resume; + + writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_RESUME_TIMEOUT_USEC) { + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_RESUME_TIMEOUT_USEC) { + /* + * This is a fatal error. Reset the link and + * PHY. USB state can not be restored. Re-insertion + * of USB cable is the only way to get USB working. + */ + dev_err(phy->dev, "Unable to resume USB." + "Re-plugin the cable\n"); + msm_otg_reset(phy); + } + +skip_phy_resume: + if (device_may_wakeup(phy->dev)) + disable_irq_wake(motg->irq); + if (bus) + set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + atomic_set(&motg->in_lpm, 0); + + if (motg->async_int) { + motg->async_int = 0; + pm_runtime_put(phy->dev); + enable_irq(motg->irq); + } + + dev_info(phy->dev, "USB exited from low power mode\n"); + + return 0; +} +#endif + +static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA) +{ + if (motg->cur_power == mA) + return; + + /* TODO: Notify PMIC about available current */ + dev_info(motg->phy.dev, "Avail curr from USB = %u\n", mA); + motg->cur_power = mA; +} + +static int msm_otg_set_power(struct usb_phy *phy, unsigned mA) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + + /* + * Gadget driver uses set_power method to notify about the + * available current based on suspend/configured states. + * + * IDEV_CHG can be drawn irrespective of suspend/un-configured + * states when CDP/ACA is connected. + */ + if (motg->chg_type == USB_SDP_CHARGER) + msm_otg_notify_charger(motg, mA); + + return 0; +} + +static void msm_otg_start_host(struct usb_phy *phy, int on) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + struct usb_hcd *hcd; + + if (!phy->otg->host) + return; + + hcd = bus_to_hcd(phy->otg->host); + + if (on) { + dev_dbg(phy->dev, "host on\n"); + + if (pdata->vbus_power) + pdata->vbus_power(1); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Enable internal + * HUB before kicking the host. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_A_HOST); +#ifdef CONFIG_USB + usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); +#endif + } else { + dev_dbg(phy->dev, "host off\n"); + +#ifdef CONFIG_USB + usb_remove_hcd(hcd); +#endif + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + if (pdata->vbus_power) + pdata->vbus_power(0); + } +} + +static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + struct usb_hcd *hcd; + + /* + * Fail host registration if this board can support + * only peripheral configuration. + */ + if (motg->pdata->mode == USB_PERIPHERAL) { + dev_info(otg->phy->dev, "Host mode is not supported\n"); + return -ENODEV; + } + + if (!host) { + if (otg->phy->state == OTG_STATE_A_HOST) { + pm_runtime_get_sync(otg->phy->dev); + msm_otg_start_host(otg->phy, 0); + otg->host = NULL; + otg->phy->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->host = NULL; + } + + return 0; + } + + hcd = bus_to_hcd(host); + hcd->power_budget = motg->pdata->power_budget; + + otg->host = host; + dev_dbg(otg->phy->dev, "host driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if peripheral is not supported + * or peripheral is already registered with us. + */ + if (motg->pdata->mode == USB_HOST || otg->gadget) { + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +static void msm_otg_start_peripheral(struct usb_phy *phy, int on) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + + if (!phy->otg->gadget) + return; + + if (on) { + dev_dbg(phy->dev, "gadget on\n"); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Disable internal + * HUB before kicking the gadget. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); + usb_gadget_vbus_connect(phy->otg->gadget); + } else { + dev_dbg(phy->dev, "gadget off\n"); + usb_gadget_vbus_disconnect(phy->otg->gadget); + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + } + +} + +static int msm_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + + /* + * Fail peripheral registration if this board can support + * only host configuration. + */ + if (motg->pdata->mode == USB_HOST) { + dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); + return -ENODEV; + } + + if (!gadget) { + if (otg->phy->state == OTG_STATE_B_PERIPHERAL) { + pm_runtime_get_sync(otg->phy->dev); + msm_otg_start_peripheral(otg->phy, 0); + otg->gadget = NULL; + otg->phy->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->gadget = NULL; + } + + return 0; + } + otg->gadget = gadget; + dev_dbg(otg->phy->dev, "peripheral driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if host is not supported + * or host is already registered with us. + */ + if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +static bool msm_chg_check_secondary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_secondary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(phy, chg_det, 0x34); + /* put it in host mode for enabling D- source */ + chg_det &= ~(1 << 2); + ulpi_write(phy, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DM as current source, DP as current sink + * and enable battery charging comparators. + */ + ulpi_write(phy, 0x8, 0x85); + ulpi_write(phy, 0x2, 0x85); + ulpi_write(phy, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_primary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_primary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DP as current source, DM as current sink + * and enable battery charging comparators. + */ + ulpi_write(phy, 0x2, 0x85); + ulpi_write(phy, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 line_state; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + line_state = ulpi_read(phy, 0x15); + ret = !(line_state & 1); + break; + case SNPS_28NM_INTEGRATED_PHY: + line_state = ulpi_read(phy, 0x87); + ret = line_state & 2; + break; + default: + break; + } + return ret; +} + +static void msm_chg_disable_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + chg_det &= ~(1 << 5); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + ulpi_write(phy, 0x10, 0x86); + break; + default: + break; + } +} + +static void msm_chg_enable_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn on D+ current source */ + chg_det |= (1 << 5); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Data contact detection enable */ + ulpi_write(phy, 0x10, 0x85); + break; + default: + break; + } +} + +static void msm_chg_block_on(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 func_ctrl, chg_det; + + /* put the controller in non-driving mode */ + func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(phy, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(phy, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(phy, 0x1F, 0x92); + ulpi_write(phy, 0x1F, 0x95); + udelay(100); + break; + default: + break; + } +} + +static void msm_chg_block_off(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 func_ctrl, chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(phy, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(phy, 0x1F, 0x92); + ulpi_write(phy, 0x1F, 0x95); + break; + default: + break; + } + + /* put the controller in normal mode */ + func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; + ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); +} + +#define MSM_CHG_DCD_POLL_TIME (100 * HZ/1000) /* 100 msec */ +#define MSM_CHG_DCD_MAX_RETRIES 6 /* Tdcd_tmout = 6 * 100 msec */ +#define MSM_CHG_PRIMARY_DET_TIME (40 * HZ/1000) /* TVDPSRC_ON */ +#define MSM_CHG_SECONDARY_DET_TIME (40 * HZ/1000) /* TVDMSRC_ON */ +static void msm_chg_detect_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work); + struct usb_phy *phy = &motg->phy; + bool is_dcd, tmout, vout; + unsigned long delay; + + dev_dbg(phy->dev, "chg detection work\n"); + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + pm_runtime_get_sync(phy->dev); + msm_chg_block_on(motg); + msm_chg_enable_dcd(motg); + motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; + motg->dcd_retries = 0; + delay = MSM_CHG_DCD_POLL_TIME; + break; + case USB_CHG_STATE_WAIT_FOR_DCD: + is_dcd = msm_chg_check_dcd(motg); + tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES; + if (is_dcd || tmout) { + msm_chg_disable_dcd(motg); + msm_chg_enable_primary_det(motg); + delay = MSM_CHG_PRIMARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_DCD_DONE; + } else { + delay = MSM_CHG_DCD_POLL_TIME; + } + break; + case USB_CHG_STATE_DCD_DONE: + vout = msm_chg_check_primary_det(motg); + if (vout) { + msm_chg_enable_secondary_det(motg); + delay = MSM_CHG_SECONDARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_PRIMARY_DONE; + } else { + motg->chg_type = USB_SDP_CHARGER; + motg->chg_state = USB_CHG_STATE_DETECTED; + delay = 0; + } + break; + case USB_CHG_STATE_PRIMARY_DONE: + vout = msm_chg_check_secondary_det(motg); + if (vout) + motg->chg_type = USB_DCP_CHARGER; + else + motg->chg_type = USB_CDP_CHARGER; + motg->chg_state = USB_CHG_STATE_SECONDARY_DONE; + /* fall through */ + case USB_CHG_STATE_SECONDARY_DONE: + motg->chg_state = USB_CHG_STATE_DETECTED; + case USB_CHG_STATE_DETECTED: + msm_chg_block_off(motg); + dev_dbg(phy->dev, "charger = %d\n", motg->chg_type); + schedule_work(&motg->sm_work); + return; + default: + return; + } + + schedule_delayed_work(&motg->chg_work, delay); +} + +/* + * We support OTG, Peripheral only and Host only configurations. In case + * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen + * via Id pin status or user request (debugfs). Id/BSV interrupts are not + * enabled when switch is controlled by user and default mode is supplied + * by board file, which can be changed by userspace later. + */ +static void msm_otg_init_sm(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + u32 otgsc = readl(USB_OTGSC); + + switch (pdata->mode) { + case USB_OTG: + if (pdata->otg_control == OTG_PHY_CONTROL) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + } else if (pdata->otg_control == OTG_USER_CONTROL) { + if (pdata->default_mode == USB_HOST) { + clear_bit(ID, &motg->inputs); + } else if (pdata->default_mode == USB_PERIPHERAL) { + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + } else { + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + } + } + break; + case USB_HOST: + clear_bit(ID, &motg->inputs); + break; + case USB_PERIPHERAL: + set_bit(ID, &motg->inputs); + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + break; + } +} + +static void msm_otg_sm_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); + struct usb_otg *otg = motg->phy.otg; + + switch (otg->phy->state) { + case OTG_STATE_UNDEFINED: + dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); + msm_otg_reset(otg->phy); + msm_otg_init_sm(motg); + otg->phy->state = OTG_STATE_B_IDLE; + /* FALL THROUGH */ + case OTG_STATE_B_IDLE: + dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); + if (!test_bit(ID, &motg->inputs) && otg->host) { + /* disable BSV bit */ + writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); + msm_otg_start_host(otg->phy, 1); + otg->phy->state = OTG_STATE_A_HOST; + } else if (test_bit(B_SESS_VLD, &motg->inputs)) { + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + msm_chg_detect_work(&motg->chg_work.work); + break; + case USB_CHG_STATE_DETECTED: + switch (motg->chg_type) { + case USB_DCP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + break; + case USB_CDP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + msm_otg_start_peripheral(otg->phy, 1); + otg->phy->state + = OTG_STATE_B_PERIPHERAL; + break; + case USB_SDP_CHARGER: + msm_otg_notify_charger(motg, IUNIT); + msm_otg_start_peripheral(otg->phy, 1); + otg->phy->state + = OTG_STATE_B_PERIPHERAL; + break; + default: + break; + } + break; + default: + break; + } + } else { + /* + * If charger detection work is pending, decrement + * the pm usage counter to balance with the one that + * is incremented in charger detection work. + */ + if (cancel_delayed_work_sync(&motg->chg_work)) { + pm_runtime_put_sync(otg->phy->dev); + msm_otg_reset(otg->phy); + } + msm_otg_notify_charger(motg, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; + } + pm_runtime_put_sync(otg->phy->dev); + break; + case OTG_STATE_B_PERIPHERAL: + dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); + if (!test_bit(B_SESS_VLD, &motg->inputs) || + !test_bit(ID, &motg->inputs)) { + msm_otg_notify_charger(motg, 0); + msm_otg_start_peripheral(otg->phy, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; + otg->phy->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg->phy); + schedule_work(w); + } + break; + case OTG_STATE_A_HOST: + dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); + if (test_bit(ID, &motg->inputs)) { + msm_otg_start_host(otg->phy, 0); + otg->phy->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg->phy); + schedule_work(w); + } + break; + default: + break; + } +} + +static irqreturn_t msm_otg_irq(int irq, void *data) +{ + struct msm_otg *motg = data; + struct usb_phy *phy = &motg->phy; + u32 otgsc = 0; + + if (atomic_read(&motg->in_lpm)) { + disable_irq_nosync(irq); + motg->async_int = 1; + pm_runtime_get(phy->dev); + return IRQ_HANDLED; + } + + otgsc = readl(USB_OTGSC); + if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) + return IRQ_NONE; + + if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + dev_dbg(phy->dev, "ID set/clear\n"); + pm_runtime_get_noresume(phy->dev); + } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + dev_dbg(phy->dev, "BSV set/clear\n"); + pm_runtime_get_noresume(phy->dev); + } + + writel(otgsc, USB_OTGSC); + schedule_work(&motg->sm_work); + return IRQ_HANDLED; +} + +static int msm_otg_mode_show(struct seq_file *s, void *unused) +{ + struct msm_otg *motg = s->private; + struct usb_otg *otg = motg->phy.otg; + + switch (otg->phy->state) { + case OTG_STATE_A_HOST: + seq_printf(s, "host\n"); + break; + case OTG_STATE_B_PERIPHERAL: + seq_printf(s, "peripheral\n"); + break; + default: + seq_printf(s, "none\n"); + break; + } + + return 0; +} + +static int msm_otg_mode_open(struct inode *inode, struct file *file) +{ + return single_open(file, msm_otg_mode_show, inode->i_private); +} + +static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct msm_otg *motg = s->private; + char buf[16]; + struct usb_otg *otg = motg->phy.otg; + int status = count; + enum usb_mode_type req_mode; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { + status = -EFAULT; + goto out; + } + + if (!strncmp(buf, "host", 4)) { + req_mode = USB_HOST; + } else if (!strncmp(buf, "peripheral", 10)) { + req_mode = USB_PERIPHERAL; + } else if (!strncmp(buf, "none", 4)) { + req_mode = USB_NONE; + } else { + status = -EINVAL; + goto out; + } + + switch (req_mode) { + case USB_NONE: + switch (otg->phy->state) { + case OTG_STATE_A_HOST: + case OTG_STATE_B_PERIPHERAL: + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_PERIPHERAL: + switch (otg->phy->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_A_HOST: + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_HOST: + switch (otg->phy->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_B_PERIPHERAL: + clear_bit(ID, &motg->inputs); + break; + default: + goto out; + } + break; + default: + goto out; + } + + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); +out: + return status; +} + +const struct file_operations msm_otg_mode_fops = { + .open = msm_otg_mode_open, + .read = seq_read, + .write = msm_otg_mode_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *msm_otg_dbg_root; +static struct dentry *msm_otg_dbg_mode; + +static int msm_otg_debugfs_init(struct msm_otg *motg) +{ + msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); + + if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) + return -ENODEV; + + msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, + msm_otg_dbg_root, motg, &msm_otg_mode_fops); + if (!msm_otg_dbg_mode) { + debugfs_remove(msm_otg_dbg_root); + msm_otg_dbg_root = NULL; + return -ENODEV; + } + + return 0; +} + +static void msm_otg_debugfs_cleanup(void) +{ + debugfs_remove(msm_otg_dbg_mode); + debugfs_remove(msm_otg_dbg_root); +} + +static int __init msm_otg_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + struct msm_otg *motg; + struct usb_phy *phy; + + dev_info(&pdev->dev, "msm_otg probe\n"); + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "No platform data given. Bailing out\n"); + return -ENODEV; + } + + motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); + if (!motg) { + dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + return -ENOMEM; + } + + motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!motg->phy.otg) { + dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + return -ENOMEM; + } + + motg->pdata = pdev->dev.platform_data; + phy = &motg->phy; + phy->dev = &pdev->dev; + + motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); + if (IS_ERR(motg->phy_reset_clk)) { + dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); + ret = PTR_ERR(motg->phy_reset_clk); + goto free_motg; + } + + motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); + if (IS_ERR(motg->clk)) { + dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); + ret = PTR_ERR(motg->clk); + goto put_phy_reset_clk; + } + clk_set_rate(motg->clk, 60000000); + + /* + * If USB Core is running its protocol engine based on CORE CLK, + * CORE CLK must be running at >55Mhz for correct HSUSB + * operation and USB core cannot tolerate frequency changes on + * CORE CLK. For such USB cores, vote for maximum clk frequency + * on pclk source + */ + if (motg->pdata->pclk_src_name) { + motg->pclk_src = clk_get(&pdev->dev, + motg->pdata->pclk_src_name); + if (IS_ERR(motg->pclk_src)) + goto put_clk; + clk_set_rate(motg->pclk_src, INT_MAX); + clk_enable(motg->pclk_src); + } else + motg->pclk_src = ERR_PTR(-ENOENT); + + + motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); + if (IS_ERR(motg->pclk)) { + dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); + ret = PTR_ERR(motg->pclk); + goto put_pclk_src; + } + + /* + * USB core clock is not present on all MSM chips. This + * clock is introduced to remove the dependency on AXI + * bus frequency. + */ + motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); + if (IS_ERR(motg->core_clk)) + motg->core_clk = NULL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get platform resource mem\n"); + ret = -ENODEV; + goto put_core_clk; + } + + motg->regs = ioremap(res->start, resource_size(res)); + if (!motg->regs) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -ENOMEM; + goto put_core_clk; + } + dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); + + motg->irq = platform_get_irq(pdev, 0); + if (!motg->irq) { + dev_err(&pdev->dev, "platform_get_irq failed\n"); + ret = -ENODEV; + goto free_regs; + } + + clk_enable(motg->clk); + clk_enable(motg->pclk); + + ret = msm_hsusb_init_vddcx(motg, 1); + if (ret) { + dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); + goto free_regs; + } + + ret = msm_hsusb_ldo_init(motg, 1); + if (ret) { + dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); + goto vddcx_exit; + } + ret = msm_hsusb_ldo_set_mode(1); + if (ret) { + dev_err(&pdev->dev, "hsusb vreg enable failed\n"); + goto ldo_exit; + } + + if (motg->core_clk) + clk_enable(motg->core_clk); + + writel(0, USB_USBINTR); + writel(0, USB_OTGSC); + + INIT_WORK(&motg->sm_work, msm_otg_sm_work); + INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); + ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, + "msm_otg", motg); + if (ret) { + dev_err(&pdev->dev, "request irq failed\n"); + goto disable_clks; + } + + phy->init = msm_otg_reset; + phy->set_power = msm_otg_set_power; + + phy->io_ops = &msm_otg_io_ops; + + phy->otg->phy = &motg->phy; + phy->otg->set_host = msm_otg_set_host; + phy->otg->set_peripheral = msm_otg_set_peripheral; + + ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); + if (ret) { + dev_err(&pdev->dev, "usb_add_phy failed\n"); + goto free_irq; + } + + platform_set_drvdata(pdev, motg); + device_init_wakeup(&pdev->dev, 1); + + if (motg->pdata->mode == USB_OTG && + motg->pdata->otg_control == OTG_USER_CONTROL) { + ret = msm_otg_debugfs_init(motg); + if (ret) + dev_dbg(&pdev->dev, "mode debugfs file is" + "not available\n"); + } + + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + return 0; +free_irq: + free_irq(motg->irq, motg); +disable_clks: + clk_disable(motg->pclk); + clk_disable(motg->clk); +ldo_exit: + msm_hsusb_ldo_init(motg, 0); +vddcx_exit: + msm_hsusb_init_vddcx(motg, 0); +free_regs: + iounmap(motg->regs); +put_core_clk: + if (motg->core_clk) + clk_put(motg->core_clk); + clk_put(motg->pclk); +put_pclk_src: + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } +put_clk: + clk_put(motg->clk); +put_phy_reset_clk: + clk_put(motg->phy_reset_clk); +free_motg: + kfree(motg->phy.otg); + kfree(motg); + return ret; +} + +static int msm_otg_remove(struct platform_device *pdev) +{ + struct msm_otg *motg = platform_get_drvdata(pdev); + struct usb_phy *phy = &motg->phy; + int cnt = 0; + + if (phy->otg->host || phy->otg->gadget) + return -EBUSY; + + msm_otg_debugfs_cleanup(); + cancel_delayed_work_sync(&motg->chg_work); + cancel_work_sync(&motg->sm_work); + + pm_runtime_resume(&pdev->dev); + + device_init_wakeup(&pdev->dev, 0); + pm_runtime_disable(&pdev->dev); + + usb_remove_phy(phy); + free_irq(motg->irq, motg); + + /* + * Put PHY in low power mode. + */ + ulpi_read(phy, 0x14); + ulpi_write(phy, 0x08, 0x09); + + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) + dev_err(phy->dev, "Unable to suspend PHY\n"); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } + msm_hsusb_ldo_init(motg, 0); + + iounmap(motg->regs); + pm_runtime_set_suspended(&pdev->dev); + + clk_put(motg->phy_reset_clk); + clk_put(motg->pclk); + clk_put(motg->clk); + if (motg->core_clk) + clk_put(motg->core_clk); + + kfree(motg->phy.otg); + kfree(motg); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int msm_otg_runtime_idle(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + struct usb_otg *otg = motg->phy.otg; + + dev_dbg(dev, "OTG runtime idle\n"); + + /* + * It is observed some times that a spurious interrupt + * comes when PHY is put into LPM immediately after PHY reset. + * This 1 sec delay also prevents entering into LPM immediately + * after asynchronous interrupt. + */ + if (otg->phy->state != OTG_STATE_UNDEFINED) + pm_schedule_suspend(dev, 1000); + + return -EAGAIN; +} + +static int msm_otg_runtime_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_runtime_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime resume\n"); + return msm_otg_resume(motg); +} +#endif + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_pm_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG PM suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_pm_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + int ret; + + dev_dbg(dev, "OTG PM resume\n"); + + ret = msm_otg_resume(motg); + if (ret) + return ret; + + /* + * Runtime PM Documentation recommends bringing the + * device to full powered state upon resume. + */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops msm_otg_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) + SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, + msm_otg_runtime_idle) +}; +#endif + +static struct platform_driver msm_otg_driver = { + .remove = msm_otg_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &msm_otg_dev_pm_ops, +#endif + }, +}; + +module_platform_driver_probe(msm_otg_driver, msm_otg_probe); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/drivers/usb/phy/mv_otg.c b/drivers/usb/phy/mv_otg.c new file mode 100644 index 000000000000..b6a9be31133b --- /dev/null +++ b/drivers/usb/phy/mv_otg.c @@ -0,0 +1,923 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. All rights reserved. + * Author: Chao Xie + * Neil Zhang + * + * 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 "mv_otg.h" + +#define DRIVER_DESC "Marvell USB OTG transceiver driver" +#define DRIVER_VERSION "Jan 20, 2010" + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static const char driver_name[] = "mv-otg"; + +static char *state_string[] = { + "undefined", + "b_idle", + "b_srp_init", + "b_peripheral", + "b_wait_acon", + "b_host", + "a_idle", + "a_wait_vrise", + "a_wait_bcon", + "a_host", + "a_suspend", + "a_peripheral", + "a_wait_vfall", + "a_vbus_err" +}; + +static int mv_otg_set_vbus(struct usb_otg *otg, bool on) +{ + struct mv_otg *mvotg = container_of(otg->phy, struct mv_otg, phy); + if (mvotg->pdata->set_vbus == NULL) + return -ENODEV; + + return mvotg->pdata->set_vbus(on); +} + +static int mv_otg_set_host(struct usb_otg *otg, + struct usb_bus *host) +{ + otg->host = host; + + return 0; +} + +static int mv_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + otg->gadget = gadget; + + return 0; +} + +static void mv_otg_run_state_machine(struct mv_otg *mvotg, + unsigned long delay) +{ + dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n"); + if (!mvotg->qwork) + return; + + queue_delayed_work(mvotg->qwork, &mvotg->work, delay); +} + +static void mv_otg_timer_await_bcon(unsigned long data) +{ + struct mv_otg *mvotg = (struct mv_otg *) data; + + mvotg->otg_ctrl.a_wait_bcon_timeout = 1; + + dev_info(&mvotg->pdev->dev, "B Device No Response!\n"); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } +} + +static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id) +{ + struct timer_list *timer; + + if (id >= OTG_TIMER_NUM) + return -EINVAL; + + timer = &mvotg->otg_ctrl.timer[id]; + + if (timer_pending(timer)) + del_timer(timer); + + return 0; +} + +static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id, + unsigned long interval, + void (*callback) (unsigned long)) +{ + struct timer_list *timer; + + if (id >= OTG_TIMER_NUM) + return -EINVAL; + + timer = &mvotg->otg_ctrl.timer[id]; + if (timer_pending(timer)) { + dev_err(&mvotg->pdev->dev, "Timer%d is already running\n", id); + return -EBUSY; + } + + init_timer(timer); + timer->data = (unsigned long) mvotg; + timer->function = callback; + timer->expires = jiffies + interval; + add_timer(timer); + + return 0; +} + +static int mv_otg_reset(struct mv_otg *mvotg) +{ + unsigned int loops; + u32 tmp; + + /* Stop the controller */ + tmp = readl(&mvotg->op_regs->usbcmd); + tmp &= ~USBCMD_RUN_STOP; + writel(tmp, &mvotg->op_regs->usbcmd); + + /* Reset the controller to get default values */ + writel(USBCMD_CTRL_RESET, &mvotg->op_regs->usbcmd); + + loops = 500; + while (readl(&mvotg->op_regs->usbcmd) & USBCMD_CTRL_RESET) { + if (loops == 0) { + dev_err(&mvotg->pdev->dev, + "Wait for RESET completed TIMEOUT\n"); + return -ETIMEDOUT; + } + loops--; + udelay(20); + } + + writel(0x0, &mvotg->op_regs->usbintr); + tmp = readl(&mvotg->op_regs->usbsts); + writel(tmp, &mvotg->op_regs->usbsts); + + return 0; +} + +static void mv_otg_init_irq(struct mv_otg *mvotg) +{ + u32 otgsc; + + mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID + | OTGSC_INTR_A_VBUS_VALID; + mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID + | OTGSC_INTSTS_A_VBUS_VALID; + + if (mvotg->pdata->vbus == NULL) { + mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID + | OTGSC_INTR_B_SESSION_END; + mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID + | OTGSC_INTSTS_B_SESSION_END; + } + + if (mvotg->pdata->id == NULL) { + mvotg->irq_en |= OTGSC_INTR_USB_ID; + mvotg->irq_status |= OTGSC_INTSTS_USB_ID; + } + + otgsc = readl(&mvotg->op_regs->otgsc); + otgsc |= mvotg->irq_en; + writel(otgsc, &mvotg->op_regs->otgsc); +} + +static void mv_otg_start_host(struct mv_otg *mvotg, int on) +{ +#ifdef CONFIG_USB + struct usb_otg *otg = mvotg->phy.otg; + struct usb_hcd *hcd; + + if (!otg->host) + return; + + dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop"); + + hcd = bus_to_hcd(otg->host); + + if (on) + usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); + else + usb_remove_hcd(hcd); +#endif /* CONFIG_USB */ +} + +static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) +{ + struct usb_otg *otg = mvotg->phy.otg; + + if (!otg->gadget) + return; + + dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off"); + + if (on) + usb_gadget_vbus_connect(otg->gadget); + else + usb_gadget_vbus_disconnect(otg->gadget); +} + +static void otg_clock_enable(struct mv_otg *mvotg) +{ + unsigned int i; + + for (i = 0; i < mvotg->clknum; i++) + clk_prepare_enable(mvotg->clk[i]); +} + +static void otg_clock_disable(struct mv_otg *mvotg) +{ + unsigned int i; + + for (i = 0; i < mvotg->clknum; i++) + clk_disable_unprepare(mvotg->clk[i]); +} + +static int mv_otg_enable_internal(struct mv_otg *mvotg) +{ + int retval = 0; + + if (mvotg->active) + return 0; + + dev_dbg(&mvotg->pdev->dev, "otg enabled\n"); + + otg_clock_enable(mvotg); + if (mvotg->pdata->phy_init) { + retval = mvotg->pdata->phy_init(mvotg->phy_regs); + if (retval) { + dev_err(&mvotg->pdev->dev, + "init phy error %d\n", retval); + otg_clock_disable(mvotg); + return retval; + } + } + mvotg->active = 1; + + return 0; + +} + +static int mv_otg_enable(struct mv_otg *mvotg) +{ + if (mvotg->clock_gating) + return mv_otg_enable_internal(mvotg); + + return 0; +} + +static void mv_otg_disable_internal(struct mv_otg *mvotg) +{ + if (mvotg->active) { + dev_dbg(&mvotg->pdev->dev, "otg disabled\n"); + if (mvotg->pdata->phy_deinit) + mvotg->pdata->phy_deinit(mvotg->phy_regs); + otg_clock_disable(mvotg); + mvotg->active = 0; + } +} + +static void mv_otg_disable(struct mv_otg *mvotg) +{ + if (mvotg->clock_gating) + mv_otg_disable_internal(mvotg); +} + +static void mv_otg_update_inputs(struct mv_otg *mvotg) +{ + struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; + u32 otgsc; + + otgsc = readl(&mvotg->op_regs->otgsc); + + if (mvotg->pdata->vbus) { + if (mvotg->pdata->vbus->poll() == VBUS_HIGH) { + otg_ctrl->b_sess_vld = 1; + otg_ctrl->b_sess_end = 0; + } else { + otg_ctrl->b_sess_vld = 0; + otg_ctrl->b_sess_end = 1; + } + } else { + otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID); + otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END); + } + + if (mvotg->pdata->id) + otg_ctrl->id = !!mvotg->pdata->id->poll(); + else + otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); + + if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) + otg_ctrl->a_bus_req = 1; + + otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); + otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID); + + dev_dbg(&mvotg->pdev->dev, "%s: ", __func__); + dev_dbg(&mvotg->pdev->dev, "id %d\n", otg_ctrl->id); + dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n", otg_ctrl->b_sess_vld); + dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n", otg_ctrl->b_sess_end); + dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n", otg_ctrl->a_vbus_vld); + dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n", otg_ctrl->a_sess_vld); +} + +static void mv_otg_update_state(struct mv_otg *mvotg) +{ + struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; + struct usb_phy *phy = &mvotg->phy; + int old_state = phy->state; + + switch (old_state) { + case OTG_STATE_UNDEFINED: + phy->state = OTG_STATE_B_IDLE; + /* FALL THROUGH */ + case OTG_STATE_B_IDLE: + if (otg_ctrl->id == 0) + phy->state = OTG_STATE_A_IDLE; + else if (otg_ctrl->b_sess_vld) + phy->state = OTG_STATE_B_PERIPHERAL; + break; + case OTG_STATE_B_PERIPHERAL: + if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) + phy->state = OTG_STATE_B_IDLE; + break; + case OTG_STATE_A_IDLE: + if (otg_ctrl->id) + phy->state = OTG_STATE_B_IDLE; + else if (!(otg_ctrl->a_bus_drop) && + (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) + phy->state = OTG_STATE_A_WAIT_VRISE; + break; + case OTG_STATE_A_WAIT_VRISE: + if (otg_ctrl->a_vbus_vld) + phy->state = OTG_STATE_A_WAIT_BCON; + break; + case OTG_STATE_A_WAIT_BCON: + if (otg_ctrl->id || otg_ctrl->a_bus_drop + || otg_ctrl->a_wait_bcon_timeout) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_WAIT_VFALL; + otg_ctrl->a_bus_req = 0; + } else if (!otg_ctrl->a_vbus_vld) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_VBUS_ERR; + } else if (otg_ctrl->b_conn) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_HOST; + } + break; + case OTG_STATE_A_HOST: + if (otg_ctrl->id || !otg_ctrl->b_conn + || otg_ctrl->a_bus_drop) + phy->state = OTG_STATE_A_WAIT_BCON; + else if (!otg_ctrl->a_vbus_vld) + phy->state = OTG_STATE_A_VBUS_ERR; + break; + case OTG_STATE_A_WAIT_VFALL: + if (otg_ctrl->id + || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) + || otg_ctrl->a_bus_req) + phy->state = OTG_STATE_A_IDLE; + break; + case OTG_STATE_A_VBUS_ERR: + if (otg_ctrl->id || otg_ctrl->a_clr_err + || otg_ctrl->a_bus_drop) { + otg_ctrl->a_clr_err = 0; + phy->state = OTG_STATE_A_WAIT_VFALL; + } + break; + default: + break; + } +} + +static void mv_otg_work(struct work_struct *work) +{ + struct mv_otg *mvotg; + struct usb_phy *phy; + struct usb_otg *otg; + int old_state; + + mvotg = container_of(to_delayed_work(work), struct mv_otg, work); + +run: + /* work queue is single thread, or we need spin_lock to protect */ + phy = &mvotg->phy; + otg = phy->otg; + old_state = phy->state; + + if (!mvotg->active) + return; + + mv_otg_update_inputs(mvotg); + mv_otg_update_state(mvotg); + + if (old_state != phy->state) { + dev_info(&mvotg->pdev->dev, "change from state %s to %s\n", + state_string[old_state], + state_string[phy->state]); + + switch (phy->state) { + case OTG_STATE_B_IDLE: + otg->default_a = 0; + if (old_state == OTG_STATE_B_PERIPHERAL) + mv_otg_start_periphrals(mvotg, 0); + mv_otg_reset(mvotg); + mv_otg_disable(mvotg); + break; + case OTG_STATE_B_PERIPHERAL: + mv_otg_enable(mvotg); + mv_otg_start_periphrals(mvotg, 1); + break; + case OTG_STATE_A_IDLE: + otg->default_a = 1; + mv_otg_enable(mvotg); + if (old_state == OTG_STATE_A_WAIT_VFALL) + mv_otg_start_host(mvotg, 0); + mv_otg_reset(mvotg); + break; + case OTG_STATE_A_WAIT_VRISE: + mv_otg_set_vbus(otg, 1); + break; + case OTG_STATE_A_WAIT_BCON: + if (old_state != OTG_STATE_A_HOST) + mv_otg_start_host(mvotg, 1); + mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER, + T_A_WAIT_BCON, + mv_otg_timer_await_bcon); + /* + * Now, we directly enter A_HOST. So set b_conn = 1 + * here. In fact, it need host driver to notify us. + */ + mvotg->otg_ctrl.b_conn = 1; + break; + case OTG_STATE_A_HOST: + break; + case OTG_STATE_A_WAIT_VFALL: + /* + * Now, we has exited A_HOST. So set b_conn = 0 + * here. In fact, it need host driver to notify us. + */ + mvotg->otg_ctrl.b_conn = 0; + mv_otg_set_vbus(otg, 0); + break; + case OTG_STATE_A_VBUS_ERR: + break; + default: + break; + } + goto run; + } +} + +static irqreturn_t mv_otg_irq(int irq, void *dev) +{ + struct mv_otg *mvotg = dev; + u32 otgsc; + + otgsc = readl(&mvotg->op_regs->otgsc); + writel(otgsc, &mvotg->op_regs->otgsc); + + /* + * if we have vbus, then the vbus detection for B-device + * will be done by mv_otg_inputs_irq(). + */ + if (mvotg->pdata->vbus) + if ((otgsc & OTGSC_STS_USB_ID) && + !(otgsc & OTGSC_INTSTS_USB_ID)) + return IRQ_NONE; + + if ((otgsc & mvotg->irq_status) == 0) + return IRQ_NONE; + + mv_otg_run_state_machine(mvotg, 0); + + return IRQ_HANDLED; +} + +static irqreturn_t mv_otg_inputs_irq(int irq, void *dev) +{ + struct mv_otg *mvotg = dev; + + /* The clock may disabled at this time */ + if (!mvotg->active) { + mv_otg_enable(mvotg); + mv_otg_init_irq(mvotg); + } + + mv_otg_run_state_machine(mvotg, 0); + + return IRQ_HANDLED; +} + +static ssize_t +get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%d\n", + mvotg->otg_ctrl.a_bus_req); +} + +static ssize_t +set_a_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + + if (count > 2) + return -1; + + /* We will use this interface to change to A device */ + if (mvotg->phy.state != OTG_STATE_B_IDLE + && mvotg->phy.state != OTG_STATE_A_IDLE) + return -1; + + /* The clock may disabled and we need to set irq for ID detected */ + mv_otg_enable(mvotg); + mv_otg_init_irq(mvotg); + + if (buf[0] == '1') { + mvotg->otg_ctrl.a_bus_req = 1; + mvotg->otg_ctrl.a_bus_drop = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_req = 1\n"); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + } + + return count; +} + +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, + set_a_bus_req); + +static ssize_t +set_a_clr_err(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + if (!mvotg->phy.otg->default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '1') { + mvotg->otg_ctrl.a_clr_err = 1; + dev_dbg(&mvotg->pdev->dev, + "User request: a_clr_err = 1\n"); + } + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + + return count; +} + +static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); + +static ssize_t +get_a_bus_drop(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%d\n", + mvotg->otg_ctrl.a_bus_drop); +} + +static ssize_t +set_a_bus_drop(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + if (!mvotg->phy.otg->default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '0') { + mvotg->otg_ctrl.a_bus_drop = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_drop = 0\n"); + } else if (buf[0] == '1') { + mvotg->otg_ctrl.a_bus_drop = 1; + mvotg->otg_ctrl.a_bus_req = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_drop = 1\n"); + dev_dbg(&mvotg->pdev->dev, + "User request: and a_bus_req = 0\n"); + } + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + + return count; +} + +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, + get_a_bus_drop, set_a_bus_drop); + +static struct attribute *inputs_attrs[] = { + &dev_attr_a_bus_req.attr, + &dev_attr_a_clr_err.attr, + &dev_attr_a_bus_drop.attr, + NULL, +}; + +static struct attribute_group inputs_attr_group = { + .name = "inputs", + .attrs = inputs_attrs, +}; + +int mv_otg_remove(struct platform_device *pdev) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + + sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); + + if (mvotg->qwork) { + flush_workqueue(mvotg->qwork); + destroy_workqueue(mvotg->qwork); + } + + mv_otg_disable(mvotg); + + usb_remove_phy(&mvotg->phy); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static int mv_otg_probe(struct platform_device *pdev) +{ + struct mv_usb_platform_data *pdata = pdev->dev.platform_data; + struct mv_otg *mvotg; + struct usb_otg *otg; + struct resource *r; + int retval = 0, clk_i, i; + size_t size; + + if (pdata == NULL) { + dev_err(&pdev->dev, "failed to get platform data\n"); + return -ENODEV; + } + + size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; + mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!mvotg) { + dev_err(&pdev->dev, "failed to allocate memory!\n"); + return -ENOMEM; + } + + otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + platform_set_drvdata(pdev, mvotg); + + mvotg->pdev = pdev; + mvotg->pdata = pdata; + + mvotg->clknum = pdata->clknum; + for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { + mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, + pdata->clkname[clk_i]); + if (IS_ERR(mvotg->clk[clk_i])) { + retval = PTR_ERR(mvotg->clk[clk_i]); + return retval; + } + } + + mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); + if (!mvotg->qwork) { + dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); + + /* OTG common part */ + mvotg->pdev = pdev; + mvotg->phy.dev = &pdev->dev; + mvotg->phy.otg = otg; + mvotg->phy.label = driver_name; + mvotg->phy.state = OTG_STATE_UNDEFINED; + + otg->phy = &mvotg->phy; + otg->set_host = mv_otg_set_host; + otg->set_peripheral = mv_otg_set_peripheral; + otg->set_vbus = mv_otg_set_vbus; + + for (i = 0; i < OTG_TIMER_NUM; i++) + init_timer(&mvotg->otg_ctrl.timer[i]); + + r = platform_get_resource_byname(mvotg->pdev, + IORESOURCE_MEM, "phyregs"); + if (r == NULL) { + dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); + retval = -ENODEV; + goto err_destroy_workqueue; + } + + mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (mvotg->phy_regs == NULL) { + dev_err(&pdev->dev, "failed to map phy I/O memory\n"); + retval = -EFAULT; + goto err_destroy_workqueue; + } + + r = platform_get_resource_byname(mvotg->pdev, + IORESOURCE_MEM, "capregs"); + if (r == NULL) { + dev_err(&pdev->dev, "no I/O memory resource defined\n"); + retval = -ENODEV; + goto err_destroy_workqueue; + } + + mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (mvotg->cap_regs == NULL) { + dev_err(&pdev->dev, "failed to map I/O memory\n"); + retval = -EFAULT; + goto err_destroy_workqueue; + } + + /* we will acces controller register, so enable the udc controller */ + retval = mv_otg_enable_internal(mvotg); + if (retval) { + dev_err(&pdev->dev, "mv otg enable error %d\n", retval); + goto err_destroy_workqueue; + } + + mvotg->op_regs = + (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs + + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); + + if (pdata->id) { + retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, + NULL, mv_otg_inputs_irq, + IRQF_ONESHOT, "id", mvotg); + if (retval) { + dev_info(&pdev->dev, + "Failed to request irq for ID\n"); + pdata->id = NULL; + } + } + + if (pdata->vbus) { + mvotg->clock_gating = 1; + retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, + NULL, mv_otg_inputs_irq, + IRQF_ONESHOT, "vbus", mvotg); + if (retval) { + dev_info(&pdev->dev, + "Failed to request irq for VBUS, " + "disable clock gating\n"); + mvotg->clock_gating = 0; + pdata->vbus = NULL; + } + } + + if (pdata->disable_otg_clock_gating) + mvotg->clock_gating = 0; + + mv_otg_reset(mvotg); + mv_otg_init_irq(mvotg); + + r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no IRQ resource defined\n"); + retval = -ENODEV; + goto err_disable_clk; + } + + mvotg->irq = r->start; + if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, + driver_name, mvotg)) { + dev_err(&pdev->dev, "Request irq %d for OTG failed\n", + mvotg->irq); + mvotg->irq = 0; + retval = -ENODEV; + goto err_disable_clk; + } + + retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); + if (retval < 0) { + dev_err(&pdev->dev, "can't register transceiver, %d\n", + retval); + goto err_disable_clk; + } + + retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); + if (retval < 0) { + dev_dbg(&pdev->dev, + "Can't register sysfs attr group: %d\n", retval); + goto err_remove_phy; + } + + spin_lock_init(&mvotg->wq_lock); + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 2 * HZ); + spin_unlock(&mvotg->wq_lock); + } + + dev_info(&pdev->dev, + "successful probe OTG device %s clock gating.\n", + mvotg->clock_gating ? "with" : "without"); + + return 0; + +err_remove_phy: + usb_remove_phy(&mvotg->phy); +err_disable_clk: + mv_otg_disable_internal(mvotg); +err_destroy_workqueue: + flush_workqueue(mvotg->qwork); + destroy_workqueue(mvotg->qwork); + + platform_set_drvdata(pdev, NULL); + + return retval; +} + +#ifdef CONFIG_PM +static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + + if (mvotg->phy.state != OTG_STATE_B_IDLE) { + dev_info(&pdev->dev, + "OTG state is not B_IDLE, it is %d!\n", + mvotg->phy.state); + return -EAGAIN; + } + + if (!mvotg->clock_gating) + mv_otg_disable_internal(mvotg); + + return 0; +} + +static int mv_otg_resume(struct platform_device *pdev) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + u32 otgsc; + + if (!mvotg->clock_gating) { + mv_otg_enable_internal(mvotg); + + otgsc = readl(&mvotg->op_regs->otgsc); + otgsc |= mvotg->irq_en; + writel(otgsc, &mvotg->op_regs->otgsc); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + } + return 0; +} +#endif + +static struct platform_driver mv_otg_driver = { + .probe = mv_otg_probe, + .remove = __exit_p(mv_otg_remove), + .driver = { + .owner = THIS_MODULE, + .name = driver_name, + }, +#ifdef CONFIG_PM + .suspend = mv_otg_suspend, + .resume = mv_otg_resume, +#endif +}; +module_platform_driver(mv_otg_driver); diff --git a/drivers/usb/phy/mv_otg.h b/drivers/usb/phy/mv_otg.h new file mode 100644 index 000000000000..8a9e351b36ba --- /dev/null +++ b/drivers/usb/phy/mv_otg.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. 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. + */ + +#ifndef __MV_USB_OTG_CONTROLLER__ +#define __MV_USB_OTG_CONTROLLER__ + +#include + +/* Command Register Bit Masks */ +#define USBCMD_RUN_STOP (0x00000001) +#define USBCMD_CTRL_RESET (0x00000002) + +/* otgsc Register Bit Masks */ +#define OTGSC_CTRL_VUSB_DISCHARGE 0x00000001 +#define OTGSC_CTRL_VUSB_CHARGE 0x00000002 +#define OTGSC_CTRL_OTG_TERM 0x00000008 +#define OTGSC_CTRL_DATA_PULSING 0x00000010 +#define OTGSC_STS_USB_ID 0x00000100 +#define OTGSC_STS_A_VBUS_VALID 0x00000200 +#define OTGSC_STS_A_SESSION_VALID 0x00000400 +#define OTGSC_STS_B_SESSION_VALID 0x00000800 +#define OTGSC_STS_B_SESSION_END 0x00001000 +#define OTGSC_STS_1MS_TOGGLE 0x00002000 +#define OTGSC_STS_DATA_PULSING 0x00004000 +#define OTGSC_INTSTS_USB_ID 0x00010000 +#define OTGSC_INTSTS_A_VBUS_VALID 0x00020000 +#define OTGSC_INTSTS_A_SESSION_VALID 0x00040000 +#define OTGSC_INTSTS_B_SESSION_VALID 0x00080000 +#define OTGSC_INTSTS_B_SESSION_END 0x00100000 +#define OTGSC_INTSTS_1MS 0x00200000 +#define OTGSC_INTSTS_DATA_PULSING 0x00400000 +#define OTGSC_INTR_USB_ID 0x01000000 +#define OTGSC_INTR_A_VBUS_VALID 0x02000000 +#define OTGSC_INTR_A_SESSION_VALID 0x04000000 +#define OTGSC_INTR_B_SESSION_VALID 0x08000000 +#define OTGSC_INTR_B_SESSION_END 0x10000000 +#define OTGSC_INTR_1MS_TIMER 0x20000000 +#define OTGSC_INTR_DATA_PULSING 0x40000000 + +#define CAPLENGTH_MASK (0xff) + +/* Timer's interval, unit 10ms */ +#define T_A_WAIT_VRISE 100 +#define T_A_WAIT_BCON 2000 +#define T_A_AIDL_BDIS 100 +#define T_A_BIDL_ADIS 20 +#define T_B_ASE0_BRST 400 +#define T_B_SE0_SRP 300 +#define T_B_SRP_FAIL 2000 +#define T_B_DATA_PLS 10 +#define T_B_SRP_INIT 100 +#define T_A_SRP_RSPNS 10 +#define T_A_DRV_RSM 5 + +enum otg_function { + OTG_B_DEVICE = 0, + OTG_A_DEVICE +}; + +enum mv_otg_timer { + A_WAIT_BCON_TIMER = 0, + OTG_TIMER_NUM +}; + +/* PXA OTG state machine */ +struct mv_otg_ctrl { + /* internal variables */ + u8 a_set_b_hnp_en; /* A-Device set b_hnp_en */ + u8 b_srp_done; + u8 b_hnp_en; + + /* OTG inputs */ + u8 a_bus_drop; + u8 a_bus_req; + u8 a_clr_err; + u8 a_bus_resume; + u8 a_bus_suspend; + u8 a_conn; + u8 a_sess_vld; + u8 a_srp_det; + u8 a_vbus_vld; + u8 b_bus_req; /* B-Device Require Bus */ + u8 b_bus_resume; + u8 b_bus_suspend; + u8 b_conn; + u8 b_se0_srp; + u8 b_sess_end; + u8 b_sess_vld; + u8 id; + u8 a_suspend_req; + + /*Timer event */ + u8 a_aidl_bdis_timeout; + u8 b_ase0_brst_timeout; + u8 a_bidl_adis_timeout; + u8 a_wait_bcon_timeout; + + struct timer_list timer[OTG_TIMER_NUM]; +}; + +#define VUSBHS_MAX_PORTS 8 + +struct mv_otg_regs { + u32 usbcmd; /* Command register */ + u32 usbsts; /* Status register */ + u32 usbintr; /* Interrupt enable */ + u32 frindex; /* Frame index */ + u32 reserved1[1]; + u32 deviceaddr; /* Device Address */ + u32 eplistaddr; /* Endpoint List Address */ + u32 ttctrl; /* HOST TT status and control */ + u32 burstsize; /* Programmable Burst Size */ + u32 txfilltuning; /* Host Transmit Pre-Buffer Packet Tuning */ + u32 reserved[4]; + u32 epnak; /* Endpoint NAK */ + u32 epnaken; /* Endpoint NAK Enable */ + u32 configflag; /* Configured Flag register */ + u32 portsc[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */ + u32 otgsc; + u32 usbmode; /* USB Host/Device mode */ + u32 epsetupstat; /* Endpoint Setup Status */ + u32 epprime; /* Endpoint Initialize */ + u32 epflush; /* Endpoint De-initialize */ + u32 epstatus; /* Endpoint Status */ + u32 epcomplete; /* Endpoint Interrupt On Complete */ + u32 epctrlx[16]; /* Endpoint Control, where x = 0.. 15 */ + u32 mcr; /* Mux Control */ + u32 isr; /* Interrupt Status */ + u32 ier; /* Interrupt Enable */ +}; + +struct mv_otg { + struct usb_phy phy; + struct mv_otg_ctrl otg_ctrl; + + /* base address */ + void __iomem *phy_regs; + void __iomem *cap_regs; + struct mv_otg_regs __iomem *op_regs; + + struct platform_device *pdev; + int irq; + u32 irq_status; + u32 irq_en; + + struct delayed_work work; + struct workqueue_struct *qwork; + + spinlock_t wq_lock; + + struct mv_usb_platform_data *pdata; + + unsigned int active; + unsigned int clock_gating; + unsigned int clknum; + struct clk *clk[0]; +}; + +#endif diff --git a/drivers/usb/phy/mxs-phy.c b/drivers/usb/phy/mxs-phy.c new file mode 100644 index 000000000000..9d4381e64d51 --- /dev/null +++ b/drivers/usb/phy/mxs-phy.c @@ -0,0 +1,220 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Marek Vasut + * on behalf of DENX Software Engineering GmbH + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "mxs_phy" + +#define HW_USBPHY_PWD 0x00 +#define HW_USBPHY_CTRL 0x30 +#define HW_USBPHY_CTRL_SET 0x34 +#define HW_USBPHY_CTRL_CLR 0x38 + +#define BM_USBPHY_CTRL_SFTRST BIT(31) +#define BM_USBPHY_CTRL_CLKGATE BIT(30) +#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) +#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) +#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) + +struct mxs_phy { + struct usb_phy phy; + struct clk *clk; +}; + +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) + +static void mxs_phy_hw_init(struct mxs_phy *mxs_phy) +{ + void __iomem *base = mxs_phy->phy.io_priv; + + stmp_reset_block(base + HW_USBPHY_CTRL); + + /* Power up the PHY */ + writel(0, base + HW_USBPHY_PWD); + + /* enable FS/LS device */ + writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | + BM_USBPHY_CTRL_ENUTMILEVEL3, + base + HW_USBPHY_CTRL_SET); +} + +static int mxs_phy_init(struct usb_phy *phy) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(phy); + + clk_prepare_enable(mxs_phy->clk); + mxs_phy_hw_init(mxs_phy); + + return 0; +} + +static void mxs_phy_shutdown(struct usb_phy *phy) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(phy); + + writel(BM_USBPHY_CTRL_CLKGATE, + phy->io_priv + HW_USBPHY_CTRL_SET); + + clk_disable_unprepare(mxs_phy->clk); +} + +static int mxs_phy_suspend(struct usb_phy *x, int suspend) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(x); + + if (suspend) { + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_SET); + clk_disable_unprepare(mxs_phy->clk); + } else { + clk_prepare_enable(mxs_phy->clk); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_CLR); + writel(0, x->io_priv + HW_USBPHY_PWD); + } + + return 0; +} + +static int mxs_phy_on_connect(struct usb_phy *phy, + enum usb_device_speed speed) +{ + dev_dbg(phy->dev, "%s speed device has connected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + + if (speed == USB_SPEED_HIGH) + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_SET); + + return 0; +} + +static int mxs_phy_on_disconnect(struct usb_phy *phy, + enum usb_device_speed speed) +{ + dev_dbg(phy->dev, "%s speed device has disconnected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + + if (speed == USB_SPEED_HIGH) + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_CLR); + + return 0; +} + +static int mxs_phy_probe(struct platform_device *pdev) +{ + struct resource *res; + void __iomem *base; + struct clk *clk; + struct mxs_phy *mxs_phy; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get device resources\n"); + return -ENOENT; + } + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, + "can't get the clock, err=%ld", PTR_ERR(clk)); + return PTR_ERR(clk); + } + + mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); + if (!mxs_phy) { + dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); + return -ENOMEM; + } + + mxs_phy->phy.io_priv = base; + mxs_phy->phy.dev = &pdev->dev; + mxs_phy->phy.label = DRIVER_NAME; + mxs_phy->phy.init = mxs_phy_init; + mxs_phy->phy.shutdown = mxs_phy_shutdown; + mxs_phy->phy.set_suspend = mxs_phy_suspend; + mxs_phy->phy.notify_connect = mxs_phy_on_connect; + mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; + + ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); + + mxs_phy->clk = clk; + + platform_set_drvdata(pdev, &mxs_phy->phy); + + ret = usb_add_phy_dev(&mxs_phy->phy); + if (ret) + return ret; + + return 0; +} + +static int mxs_phy_remove(struct platform_device *pdev) +{ + struct mxs_phy *mxs_phy = platform_get_drvdata(pdev); + + usb_remove_phy(&mxs_phy->phy); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mxs_phy_dt_ids[] = { + { .compatible = "fsl,imx23-usbphy", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); + +static struct platform_driver mxs_phy_driver = { + .probe = mxs_phy_probe, + .remove = mxs_phy_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mxs_phy_dt_ids, + }, +}; + +static int __init mxs_phy_module_init(void) +{ + return platform_driver_register(&mxs_phy_driver); +} +postcore_initcall(mxs_phy_module_init); + +static void __exit mxs_phy_module_exit(void) +{ + platform_driver_unregister(&mxs_phy_driver); +} +module_exit(mxs_phy_module_exit); + +MODULE_ALIAS("platform:mxs-usb-phy"); +MODULE_AUTHOR("Marek Vasut "); +MODULE_AUTHOR("Richard Zhao "); +MODULE_DESCRIPTION("Freescale MXS USB PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/nop-usb-xceiv.c b/drivers/usb/phy/nop-usb-xceiv.c new file mode 100644 index 000000000000..2b10cc969bbb --- /dev/null +++ b/drivers/usb/phy/nop-usb-xceiv.c @@ -0,0 +1,294 @@ +/* + * drivers/usb/otg/nop-usb-xceiv.c + * + * NOP USB transceiver for all USB transceiver which are either built-in + * into USB IP or which are mostly autonomous. + * + * Copyright (C) 2009 Texas Instruments Inc + * Author: Ajay Kumar Gupta + * + * 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. + * + * Current status: + * This provides a "nop" transceiver for PHYs which are + * autonomous such as isp1504, isp1707, etc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct nop_usb_xceiv { + struct usb_phy phy; + struct device *dev; + struct clk *clk; + struct regulator *vcc; + struct regulator *reset; +}; + +static struct platform_device *pd; + +void usb_nop_xceiv_register(void) +{ + if (pd) + return; + pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); + if (!pd) { + printk(KERN_ERR "Unable to register usb nop transceiver\n"); + return; + } +} +EXPORT_SYMBOL(usb_nop_xceiv_register); + +void usb_nop_xceiv_unregister(void) +{ + platform_device_unregister(pd); + pd = NULL; +} +EXPORT_SYMBOL(usb_nop_xceiv_unregister); + +static int nop_set_suspend(struct usb_phy *x, int suspend) +{ + return 0; +} + +static int nop_init(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->vcc)) { + if (regulator_enable(nop->vcc)) + dev_err(phy->dev, "Failed to enable power\n"); + } + + if (!IS_ERR(nop->clk)) + clk_enable(nop->clk); + + if (!IS_ERR(nop->reset)) { + /* De-assert RESET */ + if (regulator_enable(nop->reset)) + dev_err(phy->dev, "Failed to de-assert reset\n"); + } + + return 0; +} + +static void nop_shutdown(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->reset)) { + /* Assert RESET */ + if (regulator_disable(nop->reset)) + dev_err(phy->dev, "Failed to assert reset\n"); + } + + if (!IS_ERR(nop->clk)) + clk_disable(nop->clk); + + if (!IS_ERR(nop->vcc)) { + if (regulator_disable(nop->vcc)) + dev_err(phy->dev, "Failed to disable power\n"); + } +} + +static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) +{ + if (!otg) + return -ENODEV; + + if (!gadget) { + otg->gadget = NULL; + return -ENODEV; + } + + otg->gadget = gadget; + otg->phy->state = OTG_STATE_B_IDLE; + return 0; +} + +static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + if (!host) { + otg->host = NULL; + return -ENODEV; + } + + otg->host = host; + return 0; +} + +static int nop_usb_xceiv_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; + struct nop_usb_xceiv *nop; + enum usb_phy_type type = USB_PHY_TYPE_USB2; + int err; + u32 clk_rate = 0; + bool needs_vcc = false; + bool needs_reset = false; + + nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); + if (!nop) + return -ENOMEM; + + nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), + GFP_KERNEL); + if (!nop->phy.otg) + return -ENOMEM; + + if (dev->of_node) { + struct device_node *node = dev->of_node; + + if (of_property_read_u32(node, "clock-frequency", &clk_rate)) + clk_rate = 0; + + needs_vcc = of_property_read_bool(node, "vcc-supply"); + needs_reset = of_property_read_bool(node, "reset-supply"); + + } else if (pdata) { + type = pdata->type; + clk_rate = pdata->clk_rate; + needs_vcc = pdata->needs_vcc; + needs_reset = pdata->needs_reset; + } + + nop->clk = devm_clk_get(&pdev->dev, "main_clk"); + if (IS_ERR(nop->clk)) { + dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", + PTR_ERR(nop->clk)); + } + + if (!IS_ERR(nop->clk) && clk_rate) { + err = clk_set_rate(nop->clk, clk_rate); + if (err) { + dev_err(&pdev->dev, "Error setting clock rate\n"); + return err; + } + } + + if (!IS_ERR(nop->clk)) { + err = clk_prepare(nop->clk); + if (err) { + dev_err(&pdev->dev, "Error preparing clock\n"); + return err; + } + } + + nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); + if (IS_ERR(nop->vcc)) { + dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", + PTR_ERR(nop->vcc)); + if (needs_vcc) + return -EPROBE_DEFER; + } + + nop->reset = devm_regulator_get(&pdev->dev, "reset"); + if (IS_ERR(nop->reset)) { + dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", + PTR_ERR(nop->reset)); + if (needs_reset) + return -EPROBE_DEFER; + } + + nop->dev = &pdev->dev; + nop->phy.dev = nop->dev; + nop->phy.label = "nop-xceiv"; + nop->phy.set_suspend = nop_set_suspend; + nop->phy.init = nop_init; + nop->phy.shutdown = nop_shutdown; + nop->phy.state = OTG_STATE_UNDEFINED; + nop->phy.type = type; + + nop->phy.otg->phy = &nop->phy; + nop->phy.otg->set_host = nop_set_host; + nop->phy.otg->set_peripheral = nop_set_peripheral; + + err = usb_add_phy_dev(&nop->phy); + if (err) { + dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + err); + goto err_add; + } + + platform_set_drvdata(pdev, nop); + + ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); + + return 0; + +err_add: + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + return err; +} + +static int nop_usb_xceiv_remove(struct platform_device *pdev) +{ + struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); + + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + + usb_remove_phy(&nop->phy); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id nop_xceiv_dt_ids[] = { + { .compatible = "usb-nop-xceiv" }, + { } +}; + +MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); + +static struct platform_driver nop_usb_xceiv_driver = { + .probe = nop_usb_xceiv_probe, + .remove = nop_usb_xceiv_remove, + .driver = { + .name = "nop_usb_xceiv", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(nop_xceiv_dt_ids), + }, +}; + +static int __init nop_usb_xceiv_init(void) +{ + return platform_driver_register(&nop_usb_xceiv_driver); +} +subsys_initcall(nop_usb_xceiv_init); + +static void __exit nop_usb_xceiv_exit(void) +{ + platform_driver_unregister(&nop_usb_xceiv_driver); +} +module_exit(nop_usb_xceiv_exit); + +MODULE_ALIAS("platform:nop_usb_xceiv"); +MODULE_AUTHOR("Texas Instruments Inc"); +MODULE_DESCRIPTION("NOP USB Transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/otg_fsm.c b/drivers/usb/phy/otg_fsm.c new file mode 100644 index 000000000000..1f729a15decb --- /dev/null +++ b/drivers/usb/phy/otg_fsm.c @@ -0,0 +1,348 @@ +/* + * OTG Finite State Machine from OTG spec + * + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * Author: Li Yang + * Jerry Huang + * + * 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 "otg_fsm.h" + +/* Change USB protocol when there is a protocol change */ +static int otg_set_protocol(struct otg_fsm *fsm, int protocol) +{ + int ret = 0; + + if (fsm->protocol != protocol) { + VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", + fsm->protocol, protocol); + /* stop old protocol */ + if (fsm->protocol == PROTO_HOST) + ret = fsm->ops->start_host(fsm, 0); + else if (fsm->protocol == PROTO_GADGET) + ret = fsm->ops->start_gadget(fsm, 0); + if (ret) + return ret; + + /* start new protocol */ + if (protocol == PROTO_HOST) + ret = fsm->ops->start_host(fsm, 1); + else if (protocol == PROTO_GADGET) + ret = fsm->ops->start_gadget(fsm, 1); + if (ret) + return ret; + + fsm->protocol = protocol; + return 0; + } + + return 0; +} + +static int state_changed; + +/* Called when leaving a state. Do state clean up jobs here */ +void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) +{ + switch (old_state) { + case OTG_STATE_B_IDLE: + otg_del_timer(fsm, b_se0_srp_tmr); + fsm->b_se0_srp = 0; + break; + case OTG_STATE_B_SRP_INIT: + fsm->b_srp_done = 0; + break; + case OTG_STATE_B_PERIPHERAL: + break; + case OTG_STATE_B_WAIT_ACON: + otg_del_timer(fsm, b_ase0_brst_tmr); + fsm->b_ase0_brst_tmout = 0; + break; + case OTG_STATE_B_HOST: + break; + case OTG_STATE_A_IDLE: + break; + case OTG_STATE_A_WAIT_VRISE: + otg_del_timer(fsm, a_wait_vrise_tmr); + fsm->a_wait_vrise_tmout = 0; + break; + case OTG_STATE_A_WAIT_BCON: + otg_del_timer(fsm, a_wait_bcon_tmr); + fsm->a_wait_bcon_tmout = 0; + break; + case OTG_STATE_A_HOST: + otg_del_timer(fsm, a_wait_enum_tmr); + break; + case OTG_STATE_A_SUSPEND: + otg_del_timer(fsm, a_aidl_bdis_tmr); + fsm->a_aidl_bdis_tmout = 0; + fsm->a_suspend_req = 0; + break; + case OTG_STATE_A_PERIPHERAL: + break; + case OTG_STATE_A_WAIT_VFALL: + otg_del_timer(fsm, a_wait_vrise_tmr); + break; + case OTG_STATE_A_VBUS_ERR: + break; + default: + break; + } +} + +/* Called when entering a state */ +int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) +{ + state_changed = 1; + if (fsm->otg->phy->state == new_state) + return 0; + VDBG("Set state: %s\n", usb_otg_state_string(new_state)); + otg_leave_state(fsm, fsm->otg->phy->state); + switch (new_state) { + case OTG_STATE_B_IDLE: + otg_drv_vbus(fsm, 0); + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + otg_add_timer(fsm, b_se0_srp_tmr); + break; + case OTG_STATE_B_SRP_INIT: + otg_start_pulse(fsm); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + otg_add_timer(fsm, b_srp_fail_tmr); + break; + case OTG_STATE_B_PERIPHERAL: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 1); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_GADGET); + break; + case OTG_STATE_B_WAIT_ACON: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, b_ase0_brst_tmr); + fsm->a_bus_suspend = 0; + break; + case OTG_STATE_B_HOST: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 1); + otg_set_protocol(fsm, PROTO_HOST); + usb_bus_start_enum(fsm->otg->host, + fsm->otg->host->otg_port); + break; + case OTG_STATE_A_IDLE: + otg_drv_vbus(fsm, 0); + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + break; + case OTG_STATE_A_WAIT_VRISE: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_wait_vrise_tmr); + break; + case OTG_STATE_A_WAIT_BCON: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_wait_bcon_tmr); + break; + case OTG_STATE_A_HOST: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 1); + otg_set_protocol(fsm, PROTO_HOST); + /* + * When HNP is triggered while a_bus_req = 0, a_host will + * suspend too fast to complete a_set_b_hnp_en + */ + if (!fsm->a_bus_req || fsm->a_suspend_req) + otg_add_timer(fsm, a_wait_enum_tmr); + break; + case OTG_STATE_A_SUSPEND: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_aidl_bdis_tmr); + + break; + case OTG_STATE_A_PERIPHERAL: + otg_loc_conn(fsm, 1); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_GADGET); + otg_drv_vbus(fsm, 1); + break; + case OTG_STATE_A_WAIT_VFALL: + otg_drv_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + break; + case OTG_STATE_A_VBUS_ERR: + otg_drv_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + break; + default: + break; + } + + fsm->otg->phy->state = new_state; + return 0; +} + +/* State change judgement */ +int otg_statemachine(struct otg_fsm *fsm) +{ + enum usb_otg_state state; + unsigned long flags; + + spin_lock_irqsave(&fsm->lock, flags); + + state = fsm->otg->phy->state; + state_changed = 0; + /* State machine state change judgement */ + + switch (state) { + case OTG_STATE_UNDEFINED: + VDBG("fsm->id = %d\n", fsm->id); + if (fsm->id) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else + otg_set_state(fsm, OTG_STATE_A_IDLE); + break; + case OTG_STATE_B_IDLE: + if (!fsm->id) + otg_set_state(fsm, OTG_STATE_A_IDLE); + else if (fsm->b_sess_vld && fsm->otg->gadget) + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp) + otg_set_state(fsm, OTG_STATE_B_SRP_INIT); + break; + case OTG_STATE_B_SRP_INIT: + if (!fsm->id || fsm->b_srp_done) + otg_set_state(fsm, OTG_STATE_B_IDLE); + break; + case OTG_STATE_B_PERIPHERAL: + if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (fsm->b_bus_req && fsm->otg-> + gadget->b_hnp_enable && fsm->a_bus_suspend) + otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); + break; + case OTG_STATE_B_WAIT_ACON: + if (fsm->a_conn) + otg_set_state(fsm, OTG_STATE_B_HOST); + else if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { + fsm->b_ase0_brst_tmout = 0; + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + } + break; + case OTG_STATE_B_HOST: + if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (!fsm->b_bus_req || !fsm->a_conn) + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + break; + case OTG_STATE_A_IDLE: + if (fsm->id) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) + otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); + break; + case OTG_STATE_A_WAIT_VRISE: + if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld || + fsm->a_wait_vrise_tmout) { + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + } + break; + case OTG_STATE_A_WAIT_BCON: + if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + else if (fsm->b_conn) + otg_set_state(fsm, OTG_STATE_A_HOST); + else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + break; + case OTG_STATE_A_HOST: + if ((!fsm->a_bus_req || fsm->a_suspend_req) && + fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_SUSPEND); + else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_SUSPEND: + if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); + else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (fsm->a_bus_req || fsm->b_bus_resume) + otg_set_state(fsm, OTG_STATE_A_HOST); + else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_PERIPHERAL: + if (fsm->id || fsm->a_bus_drop) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + else if (fsm->b_bus_suspend) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_WAIT_VFALL: + if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld && + !fsm->b_conn)) + otg_set_state(fsm, OTG_STATE_A_IDLE); + break; + case OTG_STATE_A_VBUS_ERR: + if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + break; + default: + break; + } + spin_unlock_irqrestore(&fsm->lock, flags); + + VDBG("quit statemachine, changed = %d\n", state_changed); + return state_changed; +} diff --git a/drivers/usb/phy/otg_fsm.h b/drivers/usb/phy/otg_fsm.h new file mode 100644 index 000000000000..c30a2e1d9e46 --- /dev/null +++ b/drivers/usb/phy/otg_fsm.h @@ -0,0 +1,154 @@ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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. + */ + +#undef DEBUG +#undef VERBOSE + +#ifdef DEBUG +#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt , \ + __func__, ## args) +#else +#define DBG(fmt, args...) do {} while (0) +#endif + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(stuff...) do {} while (0) +#endif + +#ifdef VERBOSE +#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__) +#else +#define MPC_LOC do {} while (0) +#endif + +#define PROTO_UNDEF (0) +#define PROTO_HOST (1) +#define PROTO_GADGET (2) + +/* OTG state machine according to the OTG spec */ +struct otg_fsm { + /* Input */ + int a_bus_resume; + int a_bus_suspend; + int a_conn; + int a_sess_vld; + int a_srp_det; + int a_vbus_vld; + int b_bus_resume; + int b_bus_suspend; + int b_conn; + int b_se0_srp; + int b_sess_end; + int b_sess_vld; + int id; + + /* Internal variables */ + int a_set_b_hnp_en; + int b_srp_done; + int b_hnp_enable; + + /* Timeout indicator for timers */ + int a_wait_vrise_tmout; + int a_wait_bcon_tmout; + int a_aidl_bdis_tmout; + int b_ase0_brst_tmout; + + /* Informative variables */ + int a_bus_drop; + int a_bus_req; + int a_clr_err; + int a_suspend_req; + int b_bus_req; + + /* Output */ + int drv_vbus; + int loc_conn; + int loc_sof; + + struct otg_fsm_ops *ops; + struct usb_otg *otg; + + /* Current usb protocol used: 0:undefine; 1:host; 2:client */ + int protocol; + spinlock_t lock; +}; + +struct otg_fsm_ops { + void (*chrg_vbus)(int on); + void (*drv_vbus)(int on); + void (*loc_conn)(int on); + void (*loc_sof)(int on); + void (*start_pulse)(void); + void (*add_timer)(void *timer); + void (*del_timer)(void *timer); + int (*start_host)(struct otg_fsm *fsm, int on); + int (*start_gadget)(struct otg_fsm *fsm, int on); +}; + + +static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on) +{ + fsm->ops->chrg_vbus(on); +} + +static inline void otg_drv_vbus(struct otg_fsm *fsm, int on) +{ + if (fsm->drv_vbus != on) { + fsm->drv_vbus = on; + fsm->ops->drv_vbus(on); + } +} + +static inline void otg_loc_conn(struct otg_fsm *fsm, int on) +{ + if (fsm->loc_conn != on) { + fsm->loc_conn = on; + fsm->ops->loc_conn(on); + } +} + +static inline void otg_loc_sof(struct otg_fsm *fsm, int on) +{ + if (fsm->loc_sof != on) { + fsm->loc_sof = on; + fsm->ops->loc_sof(on); + } +} + +static inline void otg_start_pulse(struct otg_fsm *fsm) +{ + fsm->ops->start_pulse(); +} + +static inline void otg_add_timer(struct otg_fsm *fsm, void *timer) +{ + fsm->ops->add_timer(timer); +} + +static inline void otg_del_timer(struct otg_fsm *fsm, void *timer) +{ + fsm->ops->del_timer(timer); +} + +int otg_statemachine(struct otg_fsm *fsm); + +/* Defined by device specific driver, for different timer implementation */ +extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, + *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, + *a_wait_enum_tmr; diff --git a/drivers/usb/phy/twl4030-usb.c b/drivers/usb/phy/twl4030-usb.c new file mode 100644 index 000000000000..a994715a3101 --- /dev/null +++ b/drivers/usb/phy/twl4030-usb.c @@ -0,0 +1,728 @@ +/* + * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller + * + * Copyright (C) 2004-2007 Texas Instruments + * Copyright (C) 2008 Nokia Corporation + * Contact: Felipe Balbi + * + * 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. + * + * Current status: + * - HS USB ULPI mode works. + * - 3-pin mode support may be added in future. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register defines */ + +#define MCPC_CTRL 0x30 +#define MCPC_CTRL_RTSOL (1 << 7) +#define MCPC_CTRL_EXTSWR (1 << 6) +#define MCPC_CTRL_EXTSWC (1 << 5) +#define MCPC_CTRL_VOICESW (1 << 4) +#define MCPC_CTRL_OUT64K (1 << 3) +#define MCPC_CTRL_RTSCTSSW (1 << 2) +#define MCPC_CTRL_HS_UART (1 << 0) + +#define MCPC_IO_CTRL 0x33 +#define MCPC_IO_CTRL_MICBIASEN (1 << 5) +#define MCPC_IO_CTRL_CTS_NPU (1 << 4) +#define MCPC_IO_CTRL_RXD_PU (1 << 3) +#define MCPC_IO_CTRL_TXDTYP (1 << 2) +#define MCPC_IO_CTRL_CTSTYP (1 << 1) +#define MCPC_IO_CTRL_RTSTYP (1 << 0) + +#define MCPC_CTRL2 0x36 +#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) + +#define OTHER_FUNC_CTRL 0x80 +#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) +#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) + +#define OTHER_IFC_CTRL 0x83 +#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) +#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) +#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) +#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) +#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) +#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) + +#define OTHER_INT_EN_RISE 0x86 +#define OTHER_INT_EN_FALL 0x89 +#define OTHER_INT_STS 0x8C +#define OTHER_INT_LATCH 0x8D +#define OTHER_INT_VB_SESS_VLD (1 << 7) +#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ +#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ +#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ +#define OTHER_INT_MANU (1 << 1) +#define OTHER_INT_ABNORMAL_STRESS (1 << 0) + +#define ID_STATUS 0x96 +#define ID_RES_FLOAT (1 << 4) +#define ID_RES_440K (1 << 3) +#define ID_RES_200K (1 << 2) +#define ID_RES_102K (1 << 1) +#define ID_RES_GND (1 << 0) + +#define POWER_CTRL 0xAC +#define POWER_CTRL_OTG_ENAB (1 << 5) + +#define OTHER_IFC_CTRL2 0xAF +#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) +#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) +#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) + +#define REG_CTRL_EN 0xB2 +#define REG_CTRL_ERROR 0xB5 +#define ULPI_I2C_CONFLICT_INTEN (1 << 0) + +#define OTHER_FUNC_CTRL2 0xB8 +#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) + +/* following registers do not have separate _clr and _set registers */ +#define VBUS_DEBOUNCE 0xC0 +#define ID_DEBOUNCE 0xC1 +#define VBAT_TIMER 0xD3 +#define PHY_PWR_CTRL 0xFD +#define PHY_PWR_PHYPWD (1 << 0) +#define PHY_CLK_CTRL 0xFE +#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) +#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) +#define REQ_PHY_DPLL_CLK (1 << 0) +#define PHY_CLK_CTRL_STS 0xFF +#define PHY_DPLL_CLK (1 << 0) + +/* In module TWL_MODULE_PM_MASTER */ +#define STS_HW_CONDITIONS 0x0F + +/* In module TWL_MODULE_PM_RECEIVER */ +#define VUSB_DEDICATED1 0x7D +#define VUSB_DEDICATED2 0x7E +#define VUSB1V5_DEV_GRP 0x71 +#define VUSB1V5_TYPE 0x72 +#define VUSB1V5_REMAP 0x73 +#define VUSB1V8_DEV_GRP 0x74 +#define VUSB1V8_TYPE 0x75 +#define VUSB1V8_REMAP 0x76 +#define VUSB3V1_DEV_GRP 0x77 +#define VUSB3V1_TYPE 0x78 +#define VUSB3V1_REMAP 0x79 + +/* In module TWL4030_MODULE_INTBR */ +#define PMBR1 0x0D +#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) + +struct twl4030_usb { + struct usb_phy phy; + struct device *dev; + + /* TWL4030 internal USB regulator supplies */ + struct regulator *usb1v5; + struct regulator *usb1v8; + struct regulator *usb3v1; + + /* for vbus reporting with irqs disabled */ + spinlock_t lock; + + /* pin configuration */ + enum twl4030_usb_mode usb_mode; + + int irq; + enum omap_musb_vbus_id_status linkstat; + bool vbus_supplied; + u8 asleep; + bool irq_enabled; +}; + +/* internal define on top of container_of */ +#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) + +/*-------------------------------------------------------------------------*/ + +static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, + u8 module, u8 data, u8 address) +{ + u8 check; + + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && + (check == data)) + return 0; + dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", + 1, module, address, check, data); + + /* Failed once: Try again */ + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && + (check == data)) + return 0; + dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", + 2, module, address, check, data); + + /* Failed again: Return error */ + return -EBUSY; +} + +#define twl4030_usb_write_verify(twl, address, data) \ + twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) + +static inline int twl4030_usb_write(struct twl4030_usb *twl, + u8 address, u8 data) +{ + int ret = 0; + + ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); + if (ret < 0) + dev_dbg(twl->dev, + "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); + return ret; +} + +static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) +{ + u8 data; + int ret = 0; + + ret = twl_i2c_read_u8(module, &data, address); + if (ret >= 0) + ret = data; + else + dev_dbg(twl->dev, + "TWL4030:readb[0x%x,0x%x] Error %d\n", + module, address, ret); + + return ret; +} + +static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) +{ + return twl4030_readb(twl, TWL_MODULE_USB, address); +} + +/*-------------------------------------------------------------------------*/ + +static inline int +twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) +{ + return twl4030_usb_write(twl, ULPI_SET(reg), bits); +} + +static inline int +twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) +{ + return twl4030_usb_write(twl, ULPI_CLR(reg), bits); +} + +/*-------------------------------------------------------------------------*/ + +static enum omap_musb_vbus_id_status + twl4030_usb_linkstat(struct twl4030_usb *twl) +{ + int status; + enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; + + twl->vbus_supplied = false; + + /* + * For ID/VBUS sensing, see manual section 15.4.8 ... + * except when using only battery backup power, two + * comparators produce VBUS_PRES and ID_PRES signals, + * which don't match docs elsewhere. But ... BIT(7) + * and BIT(2) of STS_HW_CONDITIONS, respectively, do + * seem to match up. If either is true the USB_PRES + * signal is active, the OTG module is activated, and + * its interrupt may be raised (may wake the system). + */ + status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); + if (status < 0) + dev_err(twl->dev, "USB link status err %d\n", status); + else if (status & (BIT(7) | BIT(2))) { + if (status & (BIT(7))) + twl->vbus_supplied = true; + + if (status & BIT(2)) + linkstat = OMAP_MUSB_ID_GROUND; + else + linkstat = OMAP_MUSB_VBUS_VALID; + } else { + if (twl->linkstat != OMAP_MUSB_UNKNOWN) + linkstat = OMAP_MUSB_VBUS_OFF; + } + + dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", + status, status, linkstat); + + /* REVISIT this assumes host and peripheral controllers + * are registered, and that both are active... + */ + + spin_lock_irq(&twl->lock); + twl->linkstat = linkstat; + spin_unlock_irq(&twl->lock); + + return linkstat; +} + +static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) +{ + twl->usb_mode = mode; + + switch (mode) { + case T2_USB_MODE_ULPI: + twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, + ULPI_IFC_CTRL_CARKITMODE); + twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); + twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, + ULPI_FUNC_CTRL_XCVRSEL_MASK | + ULPI_FUNC_CTRL_OPMODE_MASK); + break; + case -1: + /* FIXME: power on defaults */ + break; + default: + dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", + mode); + break; + }; +} + +static void twl4030_i2c_access(struct twl4030_usb *twl, int on) +{ + unsigned long timeout; + int val = twl4030_usb_read(twl, PHY_CLK_CTRL); + + if (val >= 0) { + if (on) { + /* enable DPLL to access PHY registers over I2C */ + val |= REQ_PHY_DPLL_CLK; + WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, + (u8)val) < 0); + + timeout = jiffies + HZ; + while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & + PHY_DPLL_CLK) + && time_before(jiffies, timeout)) + udelay(10); + if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & + PHY_DPLL_CLK)) + dev_err(twl->dev, "Timeout setting T2 HSUSB " + "PHY DPLL clock\n"); + } else { + /* let ULPI control the DPLL clock */ + val &= ~REQ_PHY_DPLL_CLK; + WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, + (u8)val) < 0); + } + } +} + +static void __twl4030_phy_power(struct twl4030_usb *twl, int on) +{ + u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); + + if (on) + pwr &= ~PHY_PWR_PHYPWD; + else + pwr |= PHY_PWR_PHYPWD; + + WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); +} + +static void twl4030_phy_power(struct twl4030_usb *twl, int on) +{ + if (on) { + regulator_enable(twl->usb3v1); + regulator_enable(twl->usb1v8); + /* + * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP + * in twl4030) resets the VUSB_DEDICATED2 register. This reset + * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to + * SLEEP. We work around this by clearing the bit after usv3v1 + * is re-activated. This ensures that VUSB3V1 is really active. + */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); + regulator_enable(twl->usb1v5); + __twl4030_phy_power(twl, 1); + twl4030_usb_write(twl, PHY_CLK_CTRL, + twl4030_usb_read(twl, PHY_CLK_CTRL) | + (PHY_CLK_CTRL_CLOCKGATING_EN | + PHY_CLK_CTRL_CLK32K_EN)); + } else { + __twl4030_phy_power(twl, 0); + regulator_disable(twl->usb1v5); + regulator_disable(twl->usb1v8); + regulator_disable(twl->usb3v1); + } +} + +static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) +{ + if (twl->asleep) + return; + + twl4030_phy_power(twl, 0); + twl->asleep = 1; + dev_dbg(twl->dev, "%s\n", __func__); +} + +static void __twl4030_phy_resume(struct twl4030_usb *twl) +{ + twl4030_phy_power(twl, 1); + twl4030_i2c_access(twl, 1); + twl4030_usb_set_mode(twl, twl->usb_mode); + if (twl->usb_mode == T2_USB_MODE_ULPI) + twl4030_i2c_access(twl, 0); +} + +static void twl4030_phy_resume(struct twl4030_usb *twl) +{ + if (!twl->asleep) + return; + __twl4030_phy_resume(twl); + twl->asleep = 0; + dev_dbg(twl->dev, "%s\n", __func__); +} + +static int twl4030_usb_ldo_init(struct twl4030_usb *twl) +{ + /* Enable writing to power configuration registers */ + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, + TWL4030_PM_MASTER_PROTECT_KEY); + + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, + TWL4030_PM_MASTER_PROTECT_KEY); + + /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ + /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ + + /* input to VUSB3V1 LDO is from VBAT, not VBUS */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); + + /* Initialize 3.1V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); + + twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); + if (IS_ERR(twl->usb3v1)) + return -ENODEV; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); + + /* Initialize 1.5V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); + + twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); + if (IS_ERR(twl->usb1v5)) + goto fail1; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); + + /* Initialize 1.8V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); + + twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); + if (IS_ERR(twl->usb1v8)) + goto fail2; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); + + /* disable access to power configuration registers */ + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, + TWL4030_PM_MASTER_PROTECT_KEY); + + return 0; + +fail2: + regulator_put(twl->usb1v5); + twl->usb1v5 = NULL; +fail1: + regulator_put(twl->usb3v1); + twl->usb3v1 = NULL; + return -ENODEV; +} + +static ssize_t twl4030_usb_vbus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct twl4030_usb *twl = dev_get_drvdata(dev); + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&twl->lock, flags); + ret = sprintf(buf, "%s\n", + twl->vbus_supplied ? "on" : "off"); + spin_unlock_irqrestore(&twl->lock, flags); + + return ret; +} +static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); + +static irqreturn_t twl4030_usb_irq(int irq, void *_twl) +{ + struct twl4030_usb *twl = _twl; + enum omap_musb_vbus_id_status status; + + status = twl4030_usb_linkstat(twl); + if (status > 0) { + /* FIXME add a set_power() method so that B-devices can + * configure the charger appropriately. It's not always + * correct to consume VBUS power, and how much current to + * consume is a function of the USB configuration chosen + * by the host. + * + * REVISIT usb_gadget_vbus_connect(...) as needed, ditto + * its disconnect() sibling, when changing to/from the + * USB_LINK_VBUS state. musb_hdrc won't care until it + * starts to handle softconnect right. + */ + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) + twl4030_phy_suspend(twl, 0); + else + twl4030_phy_resume(twl); + + omap_musb_mailbox(twl->linkstat); + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); + + return IRQ_HANDLED; +} + +static void twl4030_usb_phy_init(struct twl4030_usb *twl) +{ + enum omap_musb_vbus_id_status status; + + status = twl4030_usb_linkstat(twl); + if (status > 0) { + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) { + __twl4030_phy_power(twl, 0); + twl->asleep = 1; + } else { + __twl4030_phy_resume(twl); + twl->asleep = 0; + } + + omap_musb_mailbox(twl->linkstat); + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); +} + +static int twl4030_set_suspend(struct usb_phy *x, int suspend) +{ + struct twl4030_usb *twl = phy_to_twl(x); + + if (suspend) + twl4030_phy_suspend(twl, 1); + else + twl4030_phy_resume(twl); + + return 0; +} + +static int twl4030_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + if (!otg) + return -ENODEV; + + otg->gadget = gadget; + if (!gadget) + otg->phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + otg->host = host; + if (!host) + otg->phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int twl4030_usb_probe(struct platform_device *pdev) +{ + struct twl4030_usb_data *pdata = pdev->dev.platform_data; + struct twl4030_usb *twl; + int status, err; + struct usb_otg *otg; + struct device_node *np = pdev->dev.of_node; + + twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); + if (!twl) + return -ENOMEM; + + if (np) + of_property_read_u32(np, "usb_mode", + (enum twl4030_usb_mode *)&twl->usb_mode); + else if (pdata) + twl->usb_mode = pdata->usb_mode; + else { + dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); + return -EINVAL; + } + + otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); + if (!otg) + return -ENOMEM; + + twl->dev = &pdev->dev; + twl->irq = platform_get_irq(pdev, 0); + twl->vbus_supplied = false; + twl->asleep = 1; + twl->linkstat = OMAP_MUSB_UNKNOWN; + + twl->phy.dev = twl->dev; + twl->phy.label = "twl4030"; + twl->phy.otg = otg; + twl->phy.type = USB_PHY_TYPE_USB2; + twl->phy.set_suspend = twl4030_set_suspend; + + otg->phy = &twl->phy; + otg->set_host = twl4030_set_host; + otg->set_peripheral = twl4030_set_peripheral; + + /* init spinlock for workqueue */ + spin_lock_init(&twl->lock); + + err = twl4030_usb_ldo_init(twl); + if (err) { + dev_err(&pdev->dev, "ldo init failed\n"); + return err; + } + usb_add_phy_dev(&twl->phy); + + platform_set_drvdata(pdev, twl); + if (device_create_file(&pdev->dev, &dev_attr_vbus)) + dev_warn(&pdev->dev, "could not create sysfs file\n"); + + /* Our job is to use irqs and status from the power module + * to keep the transceiver disabled when nothing's connected. + * + * FIXME we actually shouldn't start enabling it until the + * USB controller drivers have said they're ready, by calling + * set_host() and/or set_peripheral() ... OTG_capable boards + * need both handles, otherwise just one suffices. + */ + twl->irq_enabled = true; + status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT, "twl4030_usb", twl); + if (status < 0) { + dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq, status); + return status; + } + + /* Power down phy or make it work according to + * current link state. + */ + twl4030_usb_phy_init(twl); + + dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); + return 0; +} + +static int __exit twl4030_usb_remove(struct platform_device *pdev) +{ + struct twl4030_usb *twl = platform_get_drvdata(pdev); + int val; + + free_irq(twl->irq, twl); + device_remove_file(twl->dev, &dev_attr_vbus); + + /* set transceiver mode to power on defaults */ + twl4030_usb_set_mode(twl, -1); + + /* autogate 60MHz ULPI clock, + * clear dpll clock request for i2c access, + * disable 32KHz + */ + val = twl4030_usb_read(twl, PHY_CLK_CTRL); + if (val >= 0) { + val |= PHY_CLK_CTRL_CLOCKGATING_EN; + val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); + twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); + } + + /* disable complete OTG block */ + twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); + + if (!twl->asleep) + twl4030_phy_power(twl, 0); + regulator_put(twl->usb1v5); + regulator_put(twl->usb1v8); + regulator_put(twl->usb3v1); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id twl4030_usb_id_table[] = { + { .compatible = "ti,twl4030-usb" }, + {} +}; +MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); +#endif + +static struct platform_driver twl4030_usb_driver = { + .probe = twl4030_usb_probe, + .remove = __exit_p(twl4030_usb_remove), + .driver = { + .name = "twl4030_usb", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl4030_usb_id_table), + }, +}; + +static int __init twl4030_usb_init(void) +{ + return platform_driver_register(&twl4030_usb_driver); +} +subsys_initcall(twl4030_usb_init); + +static void __exit twl4030_usb_exit(void) +{ + platform_driver_unregister(&twl4030_usb_driver); +} +module_exit(twl4030_usb_exit); + +MODULE_ALIAS("platform:twl4030_usb"); +MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); +MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/twl6030-usb.c b/drivers/usb/phy/twl6030-usb.c new file mode 100644 index 000000000000..8cd6cf49bdbd --- /dev/null +++ b/drivers/usb/phy/twl6030-usb.c @@ -0,0 +1,446 @@ +/* + * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.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. + * + * Author: Hema HK + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 + +/* usb register definitions */ +#define USB_VENDOR_ID_LSB 0x00 +#define USB_VENDOR_ID_MSB 0x01 +#define USB_PRODUCT_ID_LSB 0x02 +#define USB_PRODUCT_ID_MSB 0x03 +#define USB_VBUS_CTRL_SET 0x04 +#define USB_VBUS_CTRL_CLR 0x05 +#define USB_ID_CTRL_SET 0x06 +#define USB_ID_CTRL_CLR 0x07 +#define USB_VBUS_INT_SRC 0x08 +#define USB_VBUS_INT_LATCH_SET 0x09 +#define USB_VBUS_INT_LATCH_CLR 0x0A +#define USB_VBUS_INT_EN_LO_SET 0x0B +#define USB_VBUS_INT_EN_LO_CLR 0x0C +#define USB_VBUS_INT_EN_HI_SET 0x0D +#define USB_VBUS_INT_EN_HI_CLR 0x0E +#define USB_ID_INT_SRC 0x0F +#define USB_ID_INT_LATCH_SET 0x10 +#define USB_ID_INT_LATCH_CLR 0x11 + +#define USB_ID_INT_EN_LO_SET 0x12 +#define USB_ID_INT_EN_LO_CLR 0x13 +#define USB_ID_INT_EN_HI_SET 0x14 +#define USB_ID_INT_EN_HI_CLR 0x15 +#define USB_OTG_ADP_CTRL 0x16 +#define USB_OTG_ADP_HIGH 0x17 +#define USB_OTG_ADP_LOW 0x18 +#define USB_OTG_ADP_RISE 0x19 +#define USB_OTG_REVISION 0x1A + +/* to be moved to LDO */ +#define TWL6030_MISC2 0xE5 +#define TWL6030_CFG_LDO_PD2 0xF5 +#define TWL6030_BACKUP_REG 0xFA + +#define STS_HW_CONDITIONS 0x21 + +/* In module TWL6030_MODULE_PM_MASTER */ +#define STS_HW_CONDITIONS 0x21 +#define STS_USB_ID BIT(2) + +/* In module TWL6030_MODULE_PM_RECEIVER */ +#define VUSB_CFG_TRANS 0x71 +#define VUSB_CFG_STATE 0x72 +#define VUSB_CFG_VOLTAGE 0x73 + +/* in module TWL6030_MODULE_MAIN_CHARGE */ + +#define CHARGERUSB_CTRL1 0x8 + +#define CONTROLLER_STAT1 0x03 +#define VBUS_DET BIT(2) + +struct twl6030_usb { + struct phy_companion comparator; + struct device *dev; + + /* for vbus reporting with irqs disabled */ + spinlock_t lock; + + struct regulator *usb3v3; + + /* used to set vbus, in atomic path */ + struct work_struct set_vbus_work; + + int irq1; + int irq2; + enum omap_musb_vbus_id_status linkstat; + u8 asleep; + bool irq_enabled; + bool vbus_enable; + const char *regulator; +}; + +#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator) + +/*-------------------------------------------------------------------------*/ + +static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module, + u8 data, u8 address) +{ + int ret = 0; + + ret = twl_i2c_write_u8(module, data, address); + if (ret < 0) + dev_err(twl->dev, + "Write[0x%x] Error %d\n", address, ret); + return ret; +} + +static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address) +{ + u8 data, ret = 0; + + ret = twl_i2c_read_u8(module, &data, address); + if (ret >= 0) + ret = data; + else + dev_err(twl->dev, + "readb[0x%x,0x%x] Error %d\n", + module, address, ret); + return ret; +} + +static int twl6030_start_srp(struct phy_companion *comparator) +{ + struct twl6030_usb *twl = comparator_to_twl(comparator); + + twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); + twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); + + mdelay(100); + twl6030_writeb(twl, TWL_MODULE_USB, 0xa0, USB_VBUS_CTRL_CLR); + + return 0; +} + +static int twl6030_usb_ldo_init(struct twl6030_usb *twl) +{ + /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); + + /* Program CFG_LDO_PD2 register and set VUSB bit */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2); + + /* Program MISC2 register and set bit VUSB_IN_VBAT */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); + + twl->usb3v3 = regulator_get(twl->dev, twl->regulator); + if (IS_ERR(twl->usb3v3)) + return -ENODEV; + + /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ + twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); + + /* + * Program the USB_ID_CTRL_SET register to enable GND drive + * and the ID comparators + */ + twl6030_writeb(twl, TWL_MODULE_USB, 0x14, USB_ID_CTRL_SET); + + return 0; +} + +static ssize_t twl6030_usb_vbus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct twl6030_usb *twl = dev_get_drvdata(dev); + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&twl->lock, flags); + + switch (twl->linkstat) { + case OMAP_MUSB_VBUS_VALID: + ret = snprintf(buf, PAGE_SIZE, "vbus\n"); + break; + case OMAP_MUSB_ID_GROUND: + ret = snprintf(buf, PAGE_SIZE, "id\n"); + break; + case OMAP_MUSB_VBUS_OFF: + ret = snprintf(buf, PAGE_SIZE, "none\n"); + break; + default: + ret = snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); + } + spin_unlock_irqrestore(&twl->lock, flags); + + return ret; +} +static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); + +static irqreturn_t twl6030_usb_irq(int irq, void *_twl) +{ + struct twl6030_usb *twl = _twl; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + u8 vbus_state, hw_state; + + hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); + + vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, + CONTROLLER_STAT1); + if (!(hw_state & STS_USB_ID)) { + if (vbus_state & VBUS_DET) { + regulator_enable(twl->usb3v3); + twl->asleep = 1; + status = OMAP_MUSB_VBUS_VALID; + twl->linkstat = status; + omap_musb_mailbox(status); + } else { + if (twl->linkstat != OMAP_MUSB_UNKNOWN) { + status = OMAP_MUSB_VBUS_OFF; + twl->linkstat = status; + omap_musb_mailbox(status); + if (twl->asleep) { + regulator_disable(twl->usb3v3); + twl->asleep = 0; + } + } + } + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); + + return IRQ_HANDLED; +} + +static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) +{ + struct twl6030_usb *twl = _twl; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + u8 hw_state; + + hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); + + if (hw_state & STS_USB_ID) { + + regulator_enable(twl->usb3v3); + twl->asleep = 1; + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); + status = OMAP_MUSB_ID_GROUND; + twl->linkstat = status; + omap_musb_mailbox(status); + } else { + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + } + twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); + + return IRQ_HANDLED; +} + +static int twl6030_enable_irq(struct twl6030_usb *twl) +{ + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); + twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); + + twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, + REG_INT_MSK_LINE_C); + twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, + REG_INT_MSK_STS_C); + twl6030_usb_irq(twl->irq2, twl); + twl6030_usbotg_irq(twl->irq1, twl); + + return 0; +} + +static void otg_set_vbus_work(struct work_struct *data) +{ + struct twl6030_usb *twl = container_of(data, struct twl6030_usb, + set_vbus_work); + + /* + * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 + * register. This enables boost mode. + */ + + if (twl->vbus_enable) + twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, + CHARGERUSB_CTRL1); + else + twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, + CHARGERUSB_CTRL1); +} + +static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) +{ + struct twl6030_usb *twl = comparator_to_twl(comparator); + + twl->vbus_enable = enabled; + schedule_work(&twl->set_vbus_work); + + return 0; +} + +static int twl6030_usb_probe(struct platform_device *pdev) +{ + u32 ret; + struct twl6030_usb *twl; + int status, err; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct twl4030_usb_data *pdata = dev->platform_data; + + twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); + if (!twl) + return -ENOMEM; + + twl->dev = &pdev->dev; + twl->irq1 = platform_get_irq(pdev, 0); + twl->irq2 = platform_get_irq(pdev, 1); + twl->linkstat = OMAP_MUSB_UNKNOWN; + + twl->comparator.set_vbus = twl6030_set_vbus; + twl->comparator.start_srp = twl6030_start_srp; + + ret = omap_usb2_set_comparator(&twl->comparator); + if (ret == -ENODEV) { + dev_info(&pdev->dev, "phy not ready, deferring probe"); + return -EPROBE_DEFER; + } + + if (np) { + twl->regulator = "usb"; + } else if (pdata) { + if (pdata->features & TWL6025_SUBCLASS) + twl->regulator = "ldousb"; + else + twl->regulator = "vusb"; + } else { + dev_err(&pdev->dev, "twl6030 initialized without pdata\n"); + return -EINVAL; + } + + /* init spinlock for workqueue */ + spin_lock_init(&twl->lock); + + err = twl6030_usb_ldo_init(twl); + if (err) { + dev_err(&pdev->dev, "ldo init failed\n"); + return err; + } + + platform_set_drvdata(pdev, twl); + if (device_create_file(&pdev->dev, &dev_attr_vbus)) + dev_warn(&pdev->dev, "could not create sysfs file\n"); + + INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); + + twl->irq_enabled = true; + status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "twl6030_usb", twl); + if (status < 0) { + dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq1, status); + device_remove_file(twl->dev, &dev_attr_vbus); + return status; + } + + status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "twl6030_usb", twl); + if (status < 0) { + dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq2, status); + free_irq(twl->irq1, twl); + device_remove_file(twl->dev, &dev_attr_vbus); + return status; + } + + twl->asleep = 0; + twl6030_enable_irq(twl); + dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); + + return 0; +} + +static int __exit twl6030_usb_remove(struct platform_device *pdev) +{ + struct twl6030_usb *twl = platform_get_drvdata(pdev); + + twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, + REG_INT_MSK_LINE_C); + twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, + REG_INT_MSK_STS_C); + free_irq(twl->irq1, twl); + free_irq(twl->irq2, twl); + regulator_put(twl->usb3v3); + device_remove_file(twl->dev, &dev_attr_vbus); + cancel_work_sync(&twl->set_vbus_work); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id twl6030_usb_id_table[] = { + { .compatible = "ti,twl6030-usb" }, + {} +}; +MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); +#endif + +static struct platform_driver twl6030_usb_driver = { + .probe = twl6030_usb_probe, + .remove = __exit_p(twl6030_usb_remove), + .driver = { + .name = "twl6030_usb", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl6030_usb_id_table), + }, +}; + +static int __init twl6030_usb_init(void) +{ + return platform_driver_register(&twl6030_usb_driver); +} +subsys_initcall(twl6030_usb_init); + +static void __exit twl6030_usb_exit(void) +{ + platform_driver_unregister(&twl6030_usb_driver); +} +module_exit(twl6030_usb_exit); + +MODULE_ALIAS("platform:twl6030_usb"); +MODULE_AUTHOR("Hema HK "); +MODULE_DESCRIPTION("TWL6030 USB transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/ulpi.c b/drivers/usb/phy/ulpi.c new file mode 100644 index 000000000000..217339dd7a90 --- /dev/null +++ b/drivers/usb/phy/ulpi.c @@ -0,0 +1,283 @@ +/* + * Generic ULPI USB transceiver support + * + * Copyright (C) 2009 Daniel Mack + * + * Based on sources from + * + * Sascha Hauer + * Freescale Semiconductors + * + * 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 + + +struct ulpi_info { + unsigned int id; + char *name; +}; + +#define ULPI_ID(vendor, product) (((vendor) << 16) | (product)) +#define ULPI_INFO(_id, _name) \ + { \ + .id = (_id), \ + .name = (_name), \ + } + +/* ULPI hardcoded IDs, used for probing */ +static struct ulpi_info ulpi_ids[] = { + ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), + ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), +}; + +static int ulpi_set_otg_flags(struct usb_phy *phy) +{ + unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN | + ULPI_OTG_CTRL_DM_PULLDOWN; + + if (phy->flags & ULPI_OTG_ID_PULLUP) + flags |= ULPI_OTG_CTRL_ID_PULLUP; + + /* + * ULPI Specification rev.1.1 default + * for Dp/DmPulldown is enabled. + */ + if (phy->flags & ULPI_OTG_DP_PULLDOWN_DIS) + flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN; + + if (phy->flags & ULPI_OTG_DM_PULLDOWN_DIS) + flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN; + + if (phy->flags & ULPI_OTG_EXTVBUSIND) + flags |= ULPI_OTG_CTRL_EXTVBUSIND; + + return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); +} + +static int ulpi_set_fc_flags(struct usb_phy *phy) +{ + unsigned int flags = 0; + + /* + * ULPI Specification rev.1.1 default + * for XcvrSelect is Full Speed. + */ + if (phy->flags & ULPI_FC_HS) + flags |= ULPI_FUNC_CTRL_HIGH_SPEED; + else if (phy->flags & ULPI_FC_LS) + flags |= ULPI_FUNC_CTRL_LOW_SPEED; + else if (phy->flags & ULPI_FC_FS4LS) + flags |= ULPI_FUNC_CTRL_FS4LS; + else + flags |= ULPI_FUNC_CTRL_FULL_SPEED; + + if (phy->flags & ULPI_FC_TERMSEL) + flags |= ULPI_FUNC_CTRL_TERMSELECT; + + /* + * ULPI Specification rev.1.1 default + * for OpMode is Normal Operation. + */ + if (phy->flags & ULPI_FC_OP_NODRV) + flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + else if (phy->flags & ULPI_FC_OP_DIS_NRZI) + flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI; + else if (phy->flags & ULPI_FC_OP_NSYNC_NEOP) + flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP; + else + flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL; + + /* + * ULPI Specification rev.1.1 default + * for SuspendM is Powered. + */ + flags |= ULPI_FUNC_CTRL_SUSPENDM; + + return usb_phy_io_write(phy, flags, ULPI_FUNC_CTRL); +} + +static int ulpi_set_ic_flags(struct usb_phy *phy) +{ + unsigned int flags = 0; + + if (phy->flags & ULPI_IC_AUTORESUME) + flags |= ULPI_IFC_CTRL_AUTORESUME; + + if (phy->flags & ULPI_IC_EXTVBUS_INDINV) + flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS; + + if (phy->flags & ULPI_IC_IND_PASSTHRU) + flags |= ULPI_IFC_CTRL_PASSTHRU; + + if (phy->flags & ULPI_IC_PROTECT_DIS) + flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE; + + return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); +} + +static int ulpi_set_flags(struct usb_phy *phy) +{ + int ret; + + ret = ulpi_set_otg_flags(phy); + if (ret) + return ret; + + ret = ulpi_set_ic_flags(phy); + if (ret) + return ret; + + return ulpi_set_fc_flags(phy); +} + +static int ulpi_check_integrity(struct usb_phy *phy) +{ + int ret, i; + unsigned int val = 0x55; + + for (i = 0; i < 2; i++) { + ret = usb_phy_io_write(phy, val, ULPI_SCRATCH); + if (ret < 0) + return ret; + + ret = usb_phy_io_read(phy, ULPI_SCRATCH); + if (ret < 0) + return ret; + + if (ret != val) { + pr_err("ULPI integrity check: failed!"); + return -ENODEV; + } + val = val << 1; + } + + pr_info("ULPI integrity check: passed.\n"); + + return 0; +} + +static int ulpi_init(struct usb_phy *phy) +{ + int i, vid, pid, ret; + u32 ulpi_id = 0; + + for (i = 0; i < 4; i++) { + ret = usb_phy_io_read(phy, ULPI_PRODUCT_ID_HIGH - i); + if (ret < 0) + return ret; + ulpi_id = (ulpi_id << 8) | ret; + } + vid = ulpi_id & 0xffff; + pid = ulpi_id >> 16; + + pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); + + for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) { + if (ulpi_ids[i].id == ULPI_ID(vid, pid)) { + pr_info("Found %s ULPI transceiver.\n", + ulpi_ids[i].name); + break; + } + } + + ret = ulpi_check_integrity(phy); + if (ret) + return ret; + + return ulpi_set_flags(phy); +} + +static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct usb_phy *phy = otg->phy; + unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); + + if (!host) { + otg->host = NULL; + return 0; + } + + otg->host = host; + + flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE | + ULPI_IFC_CTRL_3_PIN_SERIAL_MODE | + ULPI_IFC_CTRL_CARKITMODE); + + if (phy->flags & ULPI_IC_6PIN_SERIAL) + flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE; + else if (phy->flags & ULPI_IC_3PIN_SERIAL) + flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE; + else if (phy->flags & ULPI_IC_CARKIT) + flags |= ULPI_IFC_CTRL_CARKITMODE; + + return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); +} + +static int ulpi_set_vbus(struct usb_otg *otg, bool on) +{ + struct usb_phy *phy = otg->phy; + unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); + + flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); + + if (on) { + if (phy->flags & ULPI_OTG_DRVVBUS) + flags |= ULPI_OTG_CTRL_DRVVBUS; + + if (phy->flags & ULPI_OTG_DRVVBUS_EXT) + flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; + } + + return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); +} + +struct usb_phy * +otg_ulpi_create(struct usb_phy_io_ops *ops, + unsigned int flags) +{ + struct usb_phy *phy; + struct usb_otg *otg; + + phy = kzalloc(sizeof(*phy), GFP_KERNEL); + if (!phy) + return NULL; + + otg = kzalloc(sizeof(*otg), GFP_KERNEL); + if (!otg) { + kfree(phy); + return NULL; + } + + phy->label = "ULPI"; + phy->flags = flags; + phy->io_ops = ops; + phy->otg = otg; + phy->init = ulpi_init; + + otg->phy = phy; + otg->set_host = ulpi_set_host; + otg->set_vbus = ulpi_set_vbus; + + return phy; +} +EXPORT_SYMBOL_GPL(otg_ulpi_create); + diff --git a/drivers/usb/phy/ulpi_viewport.c b/drivers/usb/phy/ulpi_viewport.c new file mode 100644 index 000000000000..c5ba7e5423fc --- /dev/null +++ b/drivers/usb/phy/ulpi_viewport.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Google, Inc. + * + * 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 + +#define ULPI_VIEW_WAKEUP (1 << 31) +#define ULPI_VIEW_RUN (1 << 30) +#define ULPI_VIEW_WRITE (1 << 29) +#define ULPI_VIEW_READ (0 << 29) +#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) +#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) +#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) + +static int ulpi_viewport_wait(void __iomem *view, u32 mask) +{ + unsigned long usec = 2000; + + while (usec--) { + if (!(readl(view) & mask)) + return 0; + + udelay(1); + }; + + return -ETIMEDOUT; +} + +static int ulpi_viewport_read(struct usb_phy *otg, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); + if (ret) + return ret; + + return ULPI_VIEW_DATA_READ(readl(view)); +} + +static int ulpi_viewport_write(struct usb_phy *otg, u32 val, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | + ULPI_VIEW_ADDR(reg), view); + + return ulpi_viewport_wait(view, ULPI_VIEW_RUN); +} + +struct usb_phy_io_ops ulpi_viewport_access_ops = { + .read = ulpi_viewport_read, + .write = ulpi_viewport_write, +}; -- cgit From edc7cb2e955f222fe51cd44c1cf9c94d58017344 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:13:43 +0200 Subject: usb: phy: make it a menuconfig We already have a considerable amount of USB PHY drivers, making it a menuconfig just prevents us from adding too much churn to USB's menuconfig. While at that, also select USB_OTG_UTILS from this new menuconfig just to keep backwards compatibility until we manage to remove that symbol. Signed-off-by: Felipe Balbi --- drivers/Makefile | 2 +- drivers/usb/phy/Kconfig | 17 ++++++++++++----- drivers/usb/phy/Makefile | 2 +- include/linux/usb/phy.h | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index dce39a95fa71..3c200a243af0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -79,7 +79,7 @@ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_UWB) += uwb/ -obj-$(CONFIG_USB_OTG_UTILS) += usb/ +obj-$(CONFIG_USB_PHY) += usb/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_USB_GADGET) += usb/ diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 32ce740a9dd5..832cd694fb8b 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -1,8 +1,17 @@ # # Physical Layer USB driver configuration # -comment "USB Physical Layer drivers" - depends on USB || USB_GADGET +menuconfig USB_PHY + tristate "USB Physical Layer drivers" + select USB_OTG_UTILS + help + USB controllers (those which are host, device or DRD) need a + device to handle the physical layer signalling, commonly called + a PHY. + + The following drivers add support for such PHY devices. + +if USB_PHY config USB_OTG_UTILS bool @@ -10,8 +19,6 @@ config USB_OTG_UTILS Select this to make sure the build includes objects from the OTG infrastructure directory. -if USB || USB_GADGET - # # USB Transceiver Drivers # @@ -206,4 +213,4 @@ config USB_ULPI_VIEWPORT Provides read/write operations to the ULPI phy register set for controllers with a viewport register (e.g. Chipidea/ARC controllers). -endif # USB || OTG +endif # USB_PHY diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 34488ceef491..d10a8b387ffe 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -4,7 +4,7 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG -obj-$(CONFIG_USB_OTG_UTILS) += phy.o +obj-$(CONFIG_USB_PHY) += phy.o # transceiver drivers, keep the list sorted diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 15847cbdb512..b001dc3d6354 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -161,7 +161,7 @@ usb_phy_shutdown(struct usb_phy *x) } /* for usb host and peripheral controller drivers */ -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) extern struct usb_phy *usb_get_phy(enum usb_phy_type type); extern struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type); -- cgit From 820d08835d2688963607dbd08e50d89a20cb0442 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:23:50 +0200 Subject: usb: power: pda_power: check against CONFIG_USB_PHY CONFIG_USB_OTG_UTILS will be removed very soon, so we should check CONFIG_USB_PHY instead. Signed-off-by: Felipe Balbi --- drivers/power/pda_power.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 7df7c5facc10..0c52e2a0d90c 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -35,7 +35,7 @@ static struct timer_list supply_timer; static struct timer_list polling_timer; static int polling; -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) static struct usb_phy *transceiver; static struct notifier_block otg_nb; #endif @@ -218,7 +218,7 @@ static void polling_timer_func(unsigned long unused) jiffies + msecs_to_jiffies(pdata->polling_interval)); } -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) static int otg_is_usb_online(void) { return (transceiver->last_event == USB_EVENT_VBUS || @@ -315,7 +315,7 @@ static int pda_power_probe(struct platform_device *pdev) pda_psy_usb.num_supplicants = pdata->num_supplicants; } -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(transceiver)) { if (!pdata->is_usb_online) @@ -367,7 +367,7 @@ static int pda_power_probe(struct platform_device *pdev) } } -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (!IS_ERR_OR_NULL(transceiver) && pdata->use_otg_notifier) { otg_nb.notifier_call = otg_handle_notification; ret = usb_register_notifier(transceiver, &otg_nb); @@ -391,7 +391,7 @@ static int pda_power_probe(struct platform_device *pdev) return 0; -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) otg_reg_notifier_failed: if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_psy_usb); @@ -402,7 +402,7 @@ usb_irq_failed: usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_psy_ac); -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (!IS_ERR_OR_NULL(transceiver)) usb_put_phy(transceiver); #endif @@ -437,7 +437,7 @@ static int pda_power_remove(struct platform_device *pdev) power_supply_unregister(&pda_psy_usb); if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (!IS_ERR_OR_NULL(transceiver)) usb_put_phy(transceiver); #endif -- cgit From 1d3dbfc3a74f70750c8385dff36d4d46b6bd3a1a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:24:08 +0200 Subject: usb: gadget: mv_udc_core: check against CONFIG_USB_PHY CONFIG_USB_OTG_UTILS will be removed very soon, so we should check CONFIG_USB_PHY instead. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index d278e8f512c0..d550b2129133 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2127,7 +2127,7 @@ static int mv_udc_probe(struct platform_device *pdev) udc->dev = pdev; -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (pdata->mode == MV_USB_MODE_OTG) { udc->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); -- cgit From fcd12b9711816e7cb0a3eb1b47790979e4c14c58 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:24:32 +0200 Subject: usb: ehci: marvel: check against CONFIG_USB_PHY CONFIG_USB_OTG_UTILS will be removed very soon, so we should check CONFIG_USB_PHY instead. Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-mv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 3065809546b1..9751823395e1 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -240,7 +240,7 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) ehci_mv->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(ehci_mv->otg)) { dev_err(&pdev->dev, @@ -260,7 +260,7 @@ static int mv_ehci_probe(struct platform_device *pdev) mv_ehci_disable(ehci_mv); #else dev_info(&pdev->dev, "MV_USB_MODE_OTG " - "must have CONFIG_USB_OTG_UTILS enabled\n"); + "must have CONFIG_USB_PHY enabled\n"); goto err_disable_clk; #endif } else { -- cgit From a948712d2a064be5f928f37d137e9d14b48cc94f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:24:58 +0200 Subject: usb: ehci: tegra: check against CONFIG_USB_PHY CONFIG_USB_OTG_UTILS will be removed very soon, so we should check CONFIG_USB_PHY instead. Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-tegra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 568aecc7075b..fafbc819ab18 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -768,7 +768,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail; } -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (pdata->operating_mode == TEGRA_USB_OTG) { tegra->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); @@ -794,7 +794,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) return err; fail: -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, NULL); #endif @@ -815,7 +815,7 @@ static int tegra_ehci_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, NULL); #endif -- cgit From fd891498751f53dda3733d9e9ff8a1f6ea16c5e5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 11:31:18 +0200 Subject: usb: phy: remove CONFIG_USB_OTG_UTILS there are no more users of CONFIG_USB_OTG_UTILS left in tree, we can remove it just fine. [ kishon@ti.com : fixed a linking error due to original patch forgetting to change drivers/usb/Makefile ] Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/power/Kconfig | 2 +- drivers/usb/Makefile | 2 +- drivers/usb/dwc3/Kconfig | 1 - drivers/usb/gadget/Kconfig | 3 --- drivers/usb/host/Kconfig | 1 - drivers/usb/musb/Kconfig | 1 - drivers/usb/phy/Kconfig | 23 ----------------------- 7 files changed, 2 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 9e00c389e777..ffe02fb7cbc7 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -254,7 +254,7 @@ config BATTERY_RX51 config CHARGER_ISP1704 tristate "ISP1704 USB Charger Detection" - depends on USB_OTG_UTILS + depends on USB_PHY help Say Y to enable support for USB Charger Detection with ISP1707/ISP1704 USB transceivers. diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 860306b14392..c41feba8d5c0 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -44,7 +44,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB_OTG_UTILS) += phy/ +obj-$(CONFIG_USB_PHY) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 68e9a2c5a01a..ea5ee9c21c35 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -1,7 +1,6 @@ config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB || USB_GADGET) && GENERIC_HARDIRQS - select USB_OTG_UTILS select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD help Say Y or M here if your system has a Dual Role SuperSpeed diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 50586fffa9fb..7ad108a3555d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -195,7 +195,6 @@ config USB_OMAP tristate "OMAP USB Device Controller" depends on ARCH_OMAP1 select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG - select USB_OTG_UTILS if ARCH_OMAP help Many Texas Instruments OMAP processors have flexible full speed USB device controllers, with support for up to 30 @@ -210,7 +209,6 @@ config USB_OMAP config USB_PXA25X tristate "PXA 25x or IXP 4xx" depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX - select USB_OTG_UTILS help Intel's PXA 25x series XScale ARM-5TE processors include an integrated full speed USB 1.1 device controller. The @@ -258,7 +256,6 @@ config USB_RENESAS_USBHS_UDC config USB_PXA27X tristate "PXA 27x" - select USB_OTG_UTILS help Intel's PXA 27x series XScale ARM v5TE processors include an integrated full speed USB 1.1 device controller. diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index c59a1126926f..ba1347ccb9dd 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -300,7 +300,6 @@ config USB_OHCI_HCD tristate "OHCI HCD support" depends on USB && USB_ARCH_HAS_OHCI select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 - select USB_OTG_UTILS if ARCH_OMAP depends on USB_ISP1301 || !ARCH_LPC32XX ---help--- The Open Host Controller Interface (OHCI) is a standard for accessing diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index d38cf9859abb..47442d35b6fc 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -7,7 +7,6 @@ config USB_MUSB_HDRC tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' depends on USB && USB_GADGET - select USB_OTG_UTILS help Say Y here if your system has a dual role high speed USB controller based on the Mentor Graphics silicon IP. Then diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 832cd694fb8b..97de6de9b4b9 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -3,7 +3,6 @@ # menuconfig USB_PHY tristate "USB Physical Layer drivers" - select USB_OTG_UTILS help USB controllers (those which are host, device or DRD) need a device to handle the physical layer signalling, commonly called @@ -13,19 +12,12 @@ menuconfig USB_PHY if USB_PHY -config USB_OTG_UTILS - bool - help - Select this to make sure the build includes objects from - the OTG infrastructure directory. - # # USB Transceiver Drivers # config AB8500_USB tristate "AB8500 USB Transceiver Driver" depends on AB8500_CORE - select USB_OTG_UTILS help Enable this to support the USB OTG transceiver in AB8500 chip. This transceiver supports high and full speed devices plus, @@ -35,14 +27,12 @@ config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND select USB_OTG - select USB_OTG_UTILS help Enable this to support Freescale USB OTG transceiver. config ISP1301_OMAP tristate "Philips ISP1301 with OMAP OTG" depends on I2C && ARCH_OMAP_OTG - select USB_OTG_UTILS help If you say yes here you get support for the Philips ISP1301 USB-On-The-Go transceiver working with the OMAP OTG controller. @@ -56,14 +46,12 @@ config ISP1301_OMAP config MV_U3D_PHY bool "Marvell USB 3.0 PHY controller Driver" depends on USB_MV_U3D - select USB_OTG_UTILS help Enable this to support Marvell USB 3.0 phy controller for Marvell SoC. config NOP_USB_XCEIV tristate "NOP USB Transceiver Driver" - select USB_OTG_UTILS help This driver is to be used by all the usb transceiver which are either built-in with usb ip or which are autonomous and doesn't require any @@ -81,7 +69,6 @@ config OMAP_CONTROL_USB config OMAP_USB2 tristate "OMAP USB2 PHY Driver" depends on ARCH_OMAP2PLUS - select USB_OTG_UTILS select OMAP_CONTROL_USB help Enable this to support the transceiver that is part of SOC. This @@ -91,7 +78,6 @@ config OMAP_USB2 config OMAP_USB3 tristate "OMAP USB3 PHY Driver" - select USB_OTG_UTILS select OMAP_CONTROL_USB help Enable this to support the USB3 PHY that is part of SOC. This @@ -102,7 +88,6 @@ config OMAP_USB3 config SAMSUNG_USBPHY bool "Samsung USB PHY controller Driver" depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS - select USB_OTG_UTILS help Enable this to support Samsung USB phy controller for samsung SoCs. @@ -110,7 +95,6 @@ config SAMSUNG_USBPHY config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS - select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL4030 family chips (including the TWL5030 and TPS659x0 devices). @@ -120,7 +104,6 @@ config TWL4030_USB config TWL6030_USB tristate "TWL6030 USB Transceiver Driver" depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS - select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL6030 family chips. This TWL6030 transceiver has the VBUS and ID GND @@ -132,7 +115,6 @@ config TWL6030_USB config USB_GPIO_VBUS tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" depends on GENERIC_GPIO - select USB_OTG_UTILS help Provides simple GPIO VBUS sensing for controllers with an internal transceiver via the usb_phy interface, and @@ -154,7 +136,6 @@ config USB_ISP1301 config USB_MSM_OTG tristate "OTG support for Qualcomm on-chip USB controller" depends on (USB || USB_GADGET) && ARCH_MSM - select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on MSM chips. It handles PHY initialization, clock management, and workarounds @@ -168,7 +149,6 @@ config USB_MV_OTG tristate "Marvell USB OTG support" depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND select USB_OTG - select USB_OTG_UTILS help Say Y here if you want to build Marvell USB OTG transciever driver in kernel (including PXA and MMP series). This driver @@ -180,7 +160,6 @@ config USB_MXS_PHY tristate "Freescale MXS USB PHY support" depends on ARCH_MXC || ARCH_MXS select STMP_DEVICE - select USB_OTG_UTILS help Enable this to support the Freescale MXS USB PHY. @@ -189,7 +168,6 @@ config USB_MXS_PHY config USB_RCAR_PHY tristate "Renesas R-Car USB phy support" depends on USB || USB_GADGET - select USB_OTG_UTILS help Say Y here to add support for the Renesas R-Car USB phy driver. This chip is typically used as USB phy for USB host, gadget. @@ -201,7 +179,6 @@ config USB_RCAR_PHY config USB_ULPI bool "Generic ULPI Transceiver Driver" depends on ARM - select USB_OTG_UTILS help Enable this to support ULPI connected USB OTG transceivers which are likely found on embedded boards. -- cgit From 94ae98433a397dd4695652fc62ca7bc784b08216 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Mar 2013 17:37:59 +0200 Subject: usb: phy: rename all phy drivers to phy-$name-usb.c this will make sure that we have sensible names for all phy drivers. Current situation was already quite bad with too generic names being used. Signed-off-by: Felipe Balbi --- drivers/usb/phy/Makefile | 42 +- drivers/usb/phy/ab8500-usb.c | 596 ------------ drivers/usb/phy/fsl_otg.c | 1173 ----------------------- drivers/usb/phy/fsl_otg.h | 406 -------- drivers/usb/phy/gpio_vbus.c | 416 --------- drivers/usb/phy/isp1301.c | 71 -- drivers/usb/phy/isp1301_omap.c | 1656 -------------------------------- drivers/usb/phy/msm_otg.c | 1762 ----------------------------------- drivers/usb/phy/mv_otg.c | 923 ------------------ drivers/usb/phy/mv_otg.h | 165 ---- drivers/usb/phy/mv_u3d_phy.c | 343 ------- drivers/usb/phy/mv_u3d_phy.h | 105 --- drivers/usb/phy/mxs-phy.c | 220 ----- drivers/usb/phy/nop-usb-xceiv.c | 294 ------ drivers/usb/phy/omap-control-usb.c | 289 ------ drivers/usb/phy/omap-usb2.c | 273 ------ drivers/usb/phy/omap-usb3.c | 353 ------- drivers/usb/phy/otg_fsm.c | 348 ------- drivers/usb/phy/otg_fsm.h | 154 --- drivers/usb/phy/phy-ab8500-usb.c | 596 ++++++++++++ drivers/usb/phy/phy-fsl-usb.c | 1173 +++++++++++++++++++++++ drivers/usb/phy/phy-fsl-usb.h | 406 ++++++++ drivers/usb/phy/phy-fsm-usb.c | 348 +++++++ drivers/usb/phy/phy-fsm-usb.h | 154 +++ drivers/usb/phy/phy-gpio-vbus-usb.c | 416 +++++++++ drivers/usb/phy/phy-isp1301-omap.c | 1656 ++++++++++++++++++++++++++++++++ drivers/usb/phy/phy-isp1301.c | 71 ++ drivers/usb/phy/phy-msm-usb.c | 1762 +++++++++++++++++++++++++++++++++++ drivers/usb/phy/phy-mv-u3d-usb.c | 343 +++++++ drivers/usb/phy/phy-mv-u3d-usb.h | 105 +++ drivers/usb/phy/phy-mv-usb.c | 923 ++++++++++++++++++ drivers/usb/phy/phy-mv-usb.h | 165 ++++ drivers/usb/phy/phy-mxs-usb.c | 220 +++++ drivers/usb/phy/phy-nop.c | 294 ++++++ drivers/usb/phy/phy-omap-control.c | 289 ++++++ drivers/usb/phy/phy-omap-usb2.c | 273 ++++++ drivers/usb/phy/phy-omap-usb3.c | 353 +++++++ drivers/usb/phy/phy-rcar-usb.c | 220 +++++ drivers/usb/phy/phy-samsung-usb.c | 928 ++++++++++++++++++ drivers/usb/phy/phy-tegra-usb.c | 798 ++++++++++++++++ drivers/usb/phy/phy-twl4030-usb.c | 728 +++++++++++++++ drivers/usb/phy/phy-twl6030-usb.c | 446 +++++++++ drivers/usb/phy/phy-ulpi-viewport.c | 80 ++ drivers/usb/phy/phy-ulpi.c | 283 ++++++ drivers/usb/phy/rcar-phy.c | 220 ----- drivers/usb/phy/samsung-usbphy.c | 928 ------------------ drivers/usb/phy/tegra_usb_phy.c | 798 ---------------- drivers/usb/phy/twl4030-usb.c | 728 --------------- drivers/usb/phy/twl6030-usb.c | 446 --------- drivers/usb/phy/ulpi.c | 283 ------ drivers/usb/phy/ulpi_viewport.c | 80 -- 51 files changed, 13051 insertions(+), 13051 deletions(-) delete mode 100644 drivers/usb/phy/ab8500-usb.c delete mode 100644 drivers/usb/phy/fsl_otg.c delete mode 100644 drivers/usb/phy/fsl_otg.h delete mode 100644 drivers/usb/phy/gpio_vbus.c delete mode 100644 drivers/usb/phy/isp1301.c delete mode 100644 drivers/usb/phy/isp1301_omap.c delete mode 100644 drivers/usb/phy/msm_otg.c delete mode 100644 drivers/usb/phy/mv_otg.c delete mode 100644 drivers/usb/phy/mv_otg.h delete mode 100644 drivers/usb/phy/mv_u3d_phy.c delete mode 100644 drivers/usb/phy/mv_u3d_phy.h delete mode 100644 drivers/usb/phy/mxs-phy.c delete mode 100644 drivers/usb/phy/nop-usb-xceiv.c delete mode 100644 drivers/usb/phy/omap-control-usb.c delete mode 100644 drivers/usb/phy/omap-usb2.c delete mode 100644 drivers/usb/phy/omap-usb3.c delete mode 100644 drivers/usb/phy/otg_fsm.c delete mode 100644 drivers/usb/phy/otg_fsm.h create mode 100644 drivers/usb/phy/phy-ab8500-usb.c create mode 100644 drivers/usb/phy/phy-fsl-usb.c create mode 100644 drivers/usb/phy/phy-fsl-usb.h create mode 100644 drivers/usb/phy/phy-fsm-usb.c create mode 100644 drivers/usb/phy/phy-fsm-usb.h create mode 100644 drivers/usb/phy/phy-gpio-vbus-usb.c create mode 100644 drivers/usb/phy/phy-isp1301-omap.c create mode 100644 drivers/usb/phy/phy-isp1301.c create mode 100644 drivers/usb/phy/phy-msm-usb.c create mode 100644 drivers/usb/phy/phy-mv-u3d-usb.c create mode 100644 drivers/usb/phy/phy-mv-u3d-usb.h create mode 100644 drivers/usb/phy/phy-mv-usb.c create mode 100644 drivers/usb/phy/phy-mv-usb.h create mode 100644 drivers/usb/phy/phy-mxs-usb.c create mode 100644 drivers/usb/phy/phy-nop.c create mode 100644 drivers/usb/phy/phy-omap-control.c create mode 100644 drivers/usb/phy/phy-omap-usb2.c create mode 100644 drivers/usb/phy/phy-omap-usb3.c create mode 100644 drivers/usb/phy/phy-rcar-usb.c create mode 100644 drivers/usb/phy/phy-samsung-usb.c create mode 100644 drivers/usb/phy/phy-tegra-usb.c create mode 100644 drivers/usb/phy/phy-twl4030-usb.c create mode 100644 drivers/usb/phy/phy-twl6030-usb.c create mode 100644 drivers/usb/phy/phy-ulpi-viewport.c create mode 100644 drivers/usb/phy/phy-ulpi.c delete mode 100644 drivers/usb/phy/rcar-phy.c delete mode 100644 drivers/usb/phy/samsung-usbphy.c delete mode 100644 drivers/usb/phy/tegra_usb_phy.c delete mode 100644 drivers/usb/phy/twl4030-usb.c delete mode 100644 drivers/usb/phy/twl6030-usb.c delete mode 100644 drivers/usb/phy/ulpi.c delete mode 100644 drivers/usb/phy/ulpi_viewport.c (limited to 'drivers') diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index d10a8b387ffe..5fb4a5d55945 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -8,24 +8,24 @@ obj-$(CONFIG_USB_PHY) += phy.o # transceiver drivers, keep the list sorted -obj-$(CONFIG_AB8500_USB) += ab8500-usb.o -fsl_usb2_otg-objs := fsl_otg.o otg_fsm.o -obj-$(CONFIG_FSL_USB2_OTG) += fsl_usb2_otg.o -obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o -obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o -obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o -obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o -obj-$(CONFIG_OMAP_USB2) += omap-usb2.o -obj-$(CONFIG_OMAP_USB3) += omap-usb3.o -obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o -obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o -obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o -obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o -obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o -obj-$(CONFIG_USB_ISP1301) += isp1301.o -obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o -obj-$(CONFIG_USB_MV_OTG) += mv_otg.o -obj-$(CONFIG_USB_MXS_PHY) += mxs-phy.o -obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o -obj-$(CONFIG_USB_ULPI) += ulpi.o -obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o +obj-$(CONFIG_AB8500_USB) += phy-ab8500-usb.o +phy-fsl-usb2-objs := phy-fsl-usb.o phy-fsm-usb.o +obj-$(CONFIG_FSL_USB2_OTG) += phy-fsl-usb2.o +obj-$(CONFIG_ISP1301_OMAP) += phy-isp1301.omap.o +obj-$(CONFIG_MV_U3D_PHY) += phy-mv-u3d-usb.o +obj-$(CONFIG_NOP_USB_XCEIV) += phy-nop.o +obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o +obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o +obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o +obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o +obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o +obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o +obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o +obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o +obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o +obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o +obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o +obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o +obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o +obj-$(CONFIG_USB_ULPI) += phy-ulpi.o +obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o diff --git a/drivers/usb/phy/ab8500-usb.c b/drivers/usb/phy/ab8500-usb.c deleted file mode 100644 index 2d86f26a0183..000000000000 --- a/drivers/usb/phy/ab8500-usb.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * drivers/usb/otg/ab8500_usb.c - * - * USB transceiver driver for AB8500 chip - * - * Copyright (C) 2010 ST-Ericsson AB - * Mian Yousaf Kaukab - * - * 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 - -#define AB8500_MAIN_WD_CTRL_REG 0x01 -#define AB8500_USB_LINE_STAT_REG 0x80 -#define AB8500_USB_PHY_CTRL_REG 0x8A - -#define AB8500_BIT_OTG_STAT_ID (1 << 0) -#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) -#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) -#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) -#define AB8500_BIT_WD_CTRL_KICK (1 << 1) - -#define AB8500_V1x_LINK_STAT_WAIT (HZ/10) -#define AB8500_WD_KICK_DELAY_US 100 /* usec */ -#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ -#define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ - -/* Usb line status register */ -enum ab8500_usb_link_status { - USB_LINK_NOT_CONFIGURED = 0, - USB_LINK_STD_HOST_NC, - USB_LINK_STD_HOST_C_NS, - USB_LINK_STD_HOST_C_S, - USB_LINK_HOST_CHG_NM, - USB_LINK_HOST_CHG_HS, - USB_LINK_HOST_CHG_HS_CHIRP, - USB_LINK_DEDICATED_CHG, - USB_LINK_ACA_RID_A, - USB_LINK_ACA_RID_B, - USB_LINK_ACA_RID_C_NM, - USB_LINK_ACA_RID_C_HS, - USB_LINK_ACA_RID_C_HS_CHIRP, - USB_LINK_HM_IDGND, - USB_LINK_RESERVED, - USB_LINK_NOT_VALID_LINK -}; - -struct ab8500_usb { - struct usb_phy phy; - struct device *dev; - int irq_num_id_rise; - int irq_num_id_fall; - int irq_num_vbus_rise; - int irq_num_vbus_fall; - int irq_num_link_status; - unsigned vbus_draw; - struct delayed_work dwork; - struct work_struct phy_dis_work; - unsigned long link_status_wait; - int rev; -}; - -static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) -{ - return container_of(x, struct ab8500_usb, phy); -} - -static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) -{ - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - AB8500_BIT_WD_CTRL_ENABLE); - - udelay(AB8500_WD_KICK_DELAY_US); - - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - (AB8500_BIT_WD_CTRL_ENABLE - | AB8500_BIT_WD_CTRL_KICK)); - - if (ab->rev > 0x10) /* v1.1 v2.0 */ - udelay(AB8500_WD_V11_DISABLE_DELAY_US); - else /* v1.0 */ - msleep(AB8500_WD_V10_DISABLE_DELAY_MS); - - abx500_set_register_interruptible(ab->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WD_CTRL_REG, - 0); -} - -static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, - bool enable) -{ - u8 ctrl_reg; - abx500_get_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_PHY_CTRL_REG, - &ctrl_reg); - if (sel_host) { - if (enable) - ctrl_reg |= AB8500_BIT_PHY_CTRL_HOST_EN; - else - ctrl_reg &= ~AB8500_BIT_PHY_CTRL_HOST_EN; - } else { - if (enable) - ctrl_reg |= AB8500_BIT_PHY_CTRL_DEVICE_EN; - else - ctrl_reg &= ~AB8500_BIT_PHY_CTRL_DEVICE_EN; - } - - abx500_set_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_PHY_CTRL_REG, - ctrl_reg); - - /* Needed to enable the phy.*/ - if (enable) - ab8500_usb_wd_workaround(ab); -} - -#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_ctrl(ab, true, true) -#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_ctrl(ab, true, false) -#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) -#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) - -static int ab8500_usb_link_status_update(struct ab8500_usb *ab) -{ - u8 reg; - enum ab8500_usb_link_status lsts; - void *v = NULL; - enum usb_phy_events event; - - abx500_get_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_LINE_STAT_REG, - ®); - - lsts = (reg >> 3) & 0x0F; - - switch (lsts) { - case USB_LINK_NOT_CONFIGURED: - case USB_LINK_RESERVED: - case USB_LINK_NOT_VALID_LINK: - /* TODO: Disable regulators. */ - ab8500_usb_host_phy_dis(ab); - ab8500_usb_peri_phy_dis(ab); - ab->phy.state = OTG_STATE_B_IDLE; - ab->phy.otg->default_a = false; - ab->vbus_draw = 0; - event = USB_EVENT_NONE; - break; - - case USB_LINK_STD_HOST_NC: - case USB_LINK_STD_HOST_C_NS: - case USB_LINK_STD_HOST_C_S: - case USB_LINK_HOST_CHG_NM: - case USB_LINK_HOST_CHG_HS: - case USB_LINK_HOST_CHG_HS_CHIRP: - if (ab->phy.otg->gadget) { - /* TODO: Enable regulators. */ - ab8500_usb_peri_phy_en(ab); - v = ab->phy.otg->gadget; - } - event = USB_EVENT_VBUS; - break; - - case USB_LINK_HM_IDGND: - if (ab->phy.otg->host) { - /* TODO: Enable regulators. */ - ab8500_usb_host_phy_en(ab); - v = ab->phy.otg->host; - } - ab->phy.state = OTG_STATE_A_IDLE; - ab->phy.otg->default_a = true; - event = USB_EVENT_ID; - break; - - case USB_LINK_ACA_RID_A: - case USB_LINK_ACA_RID_B: - /* TODO */ - case USB_LINK_ACA_RID_C_NM: - case USB_LINK_ACA_RID_C_HS: - case USB_LINK_ACA_RID_C_HS_CHIRP: - case USB_LINK_DEDICATED_CHG: - /* TODO: vbus_draw */ - event = USB_EVENT_CHARGER; - break; - } - - atomic_notifier_call_chain(&ab->phy.notifier, event, v); - - return 0; -} - -static void ab8500_usb_delayed_work(struct work_struct *work) -{ - struct ab8500_usb *ab = container_of(work, struct ab8500_usb, - dwork.work); - - ab8500_usb_link_status_update(ab); -} - -static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - -static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Link status will not be updated till phy is disabled. */ - ab8500_usb_peri_phy_dis(ab); - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - -static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - ab8500_usb_link_status_update(ab); - - return IRQ_HANDLED; -} - -static void ab8500_usb_phy_disable_work(struct work_struct *work) -{ - struct ab8500_usb *ab = container_of(work, struct ab8500_usb, - phy_dis_work); - - if (!ab->phy.otg->host) - ab8500_usb_host_phy_dis(ab); - - if (!ab->phy.otg->gadget) - ab8500_usb_peri_phy_dis(ab); -} - -static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) -{ - struct ab8500_usb *ab; - - if (!phy) - return -ENODEV; - - ab = phy_to_ab(phy); - - ab->vbus_draw = mA; - - if (mA) - atomic_notifier_call_chain(&ab->phy.notifier, - USB_EVENT_ENUMERATED, ab->phy.otg->gadget); - return 0; -} - -/* TODO: Implement some way for charging or other drivers to read - * ab->vbus_draw. - */ - -static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) -{ - /* TODO */ - return 0; -} - -static int ab8500_usb_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct ab8500_usb *ab; - - if (!otg) - return -ENODEV; - - ab = phy_to_ab(otg->phy); - - /* Some drivers call this function in atomic context. - * Do not update ab8500 registers directly till this - * is fixed. - */ - - if (!gadget) { - /* TODO: Disable regulators. */ - otg->gadget = NULL; - schedule_work(&ab->phy_dis_work); - } else { - otg->gadget = gadget; - otg->phy->state = OTG_STATE_B_IDLE; - - /* Phy will not be enabled if cable is already - * plugged-in. Schedule to enable phy. - * Use same delay to avoid any race condition. - */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - } - - return 0; -} - -static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct ab8500_usb *ab; - - if (!otg) - return -ENODEV; - - ab = phy_to_ab(otg->phy); - - /* Some drivers call this function in atomic context. - * Do not update ab8500 registers directly till this - * is fixed. - */ - - if (!host) { - /* TODO: Disable regulators. */ - otg->host = NULL; - schedule_work(&ab->phy_dis_work); - } else { - otg->host = host; - /* Phy will not be enabled if cable is already - * plugged-in. Schedule to enable phy. - * Use same delay to avoid any race condition. - */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - } - - return 0; -} - -static void ab8500_usb_irq_free(struct ab8500_usb *ab) -{ - if (ab->rev < 0x20) { - free_irq(ab->irq_num_id_rise, ab); - free_irq(ab->irq_num_id_fall, ab); - free_irq(ab->irq_num_vbus_rise, ab); - free_irq(ab->irq_num_vbus_fall, ab); - } else { - free_irq(ab->irq_num_link_status, ab); - } -} - -static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) -{ - int err; - - ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); - if (ab->irq_num_id_rise < 0) { - dev_err(&pdev->dev, "ID rise irq not found\n"); - return ab->irq_num_id_rise; - } - err = request_threaded_irq(ab->irq_num_id_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID rise irq\n"); - goto fail0; - } - - ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); - if (ab->irq_num_id_fall < 0) { - dev_err(&pdev->dev, "ID fall irq not found\n"); - return ab->irq_num_id_fall; - } - err = request_threaded_irq(ab->irq_num_id_fall, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID fall irq\n"); - goto fail1; - } - - ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); - if (ab->irq_num_vbus_rise < 0) { - dev_err(&pdev->dev, "VBUS rise irq not found\n"); - return ab->irq_num_vbus_rise; - } - err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); - goto fail2; - } - - ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); - if (ab->irq_num_vbus_fall < 0) { - dev_err(&pdev->dev, "VBUS fall irq not found\n"); - return ab->irq_num_vbus_fall; - } - err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, - ab8500_usb_v1x_vbus_fall_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); - goto fail3; - } - - return 0; -fail3: - free_irq(ab->irq_num_vbus_rise, ab); -fail2: - free_irq(ab->irq_num_id_fall, ab); -fail1: - free_irq(ab->irq_num_id_rise, ab); -fail0: - return err; -} - -static int ab8500_usb_v2_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) -{ - int err; - - ab->irq_num_link_status = platform_get_irq_byname(pdev, - "USB_LINK_STATUS"); - if (ab->irq_num_link_status < 0) { - dev_err(&pdev->dev, "Link status irq not found\n"); - return ab->irq_num_link_status; - } - - err = request_threaded_irq(ab->irq_num_link_status, NULL, - ab8500_usb_v20_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-link-status", ab); - if (err < 0) { - dev_err(ab->dev, - "request_irq failed for link status irq\n"); - return err; - } - - return 0; -} - -static int ab8500_usb_probe(struct platform_device *pdev) -{ - struct ab8500_usb *ab; - struct usb_otg *otg; - int err; - int rev; - - rev = abx500_get_chip_id(&pdev->dev); - if (rev < 0) { - dev_err(&pdev->dev, "Chip id read failed\n"); - return rev; - } else if (rev < 0x10) { - dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); - return -ENODEV; - } - - ab = kzalloc(sizeof *ab, GFP_KERNEL); - if (!ab) - return -ENOMEM; - - otg = kzalloc(sizeof *otg, GFP_KERNEL); - if (!otg) { - kfree(ab); - return -ENOMEM; - } - - ab->dev = &pdev->dev; - ab->rev = rev; - ab->phy.dev = ab->dev; - ab->phy.otg = otg; - ab->phy.label = "ab8500"; - ab->phy.set_suspend = ab8500_usb_set_suspend; - ab->phy.set_power = ab8500_usb_set_power; - ab->phy.state = OTG_STATE_UNDEFINED; - - otg->phy = &ab->phy; - otg->set_host = ab8500_usb_set_host; - otg->set_peripheral = ab8500_usb_set_peripheral; - - platform_set_drvdata(pdev, ab); - - ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); - - /* v1: Wait for link status to become stable. - * all: Updates form set_host and set_peripheral as they are atomic. - */ - INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); - - /* all: Disable phy when called from set_host and set_peripheral */ - INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); - - if (ab->rev < 0x20) { - err = ab8500_usb_v1x_res_setup(pdev, ab); - ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; - } else { - err = ab8500_usb_v2_res_setup(pdev, ab); - } - - if (err < 0) - goto fail0; - - err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); - if (err) { - dev_err(&pdev->dev, "Can't register transceiver\n"); - goto fail1; - } - - dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); - - return 0; -fail1: - ab8500_usb_irq_free(ab); -fail0: - kfree(otg); - kfree(ab); - return err; -} - -static int ab8500_usb_remove(struct platform_device *pdev) -{ - struct ab8500_usb *ab = platform_get_drvdata(pdev); - - ab8500_usb_irq_free(ab); - - cancel_delayed_work_sync(&ab->dwork); - - cancel_work_sync(&ab->phy_dis_work); - - usb_remove_phy(&ab->phy); - - ab8500_usb_host_phy_dis(ab); - ab8500_usb_peri_phy_dis(ab); - - platform_set_drvdata(pdev, NULL); - - kfree(ab->phy.otg); - kfree(ab); - - return 0; -} - -static struct platform_driver ab8500_usb_driver = { - .probe = ab8500_usb_probe, - .remove = ab8500_usb_remove, - .driver = { - .name = "ab8500-usb", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_usb_init(void) -{ - return platform_driver_register(&ab8500_usb_driver); -} -subsys_initcall(ab8500_usb_init); - -static void __exit ab8500_usb_exit(void) -{ - platform_driver_unregister(&ab8500_usb_driver); -} -module_exit(ab8500_usb_exit); - -MODULE_ALIAS("platform:ab8500_usb"); -MODULE_AUTHOR("ST-Ericsson AB"); -MODULE_DESCRIPTION("AB8500 usb transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/fsl_otg.c b/drivers/usb/phy/fsl_otg.c deleted file mode 100644 index 72a2a00c2487..000000000000 --- a/drivers/usb/phy/fsl_otg.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* - * Copyright (C) 2007,2008 Freescale semiconductor, Inc. - * - * Author: Li Yang - * Jerry Huang - * - * Initialization based on code from Shlomi Gridish. - * - * 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 "fsl_otg.h" - -#define DRIVER_VERSION "Rev. 1.55" -#define DRIVER_AUTHOR "Jerry Huang/Li Yang" -#define DRIVER_DESC "Freescale USB OTG Transceiver Driver" -#define DRIVER_INFO DRIVER_DESC " " DRIVER_VERSION - -static const char driver_name[] = "fsl-usb2-otg"; - -const pm_message_t otg_suspend_state = { - .event = 1, -}; - -#define HA_DATA_PULSE - -static struct usb_dr_mmap *usb_dr_regs; -static struct fsl_otg *fsl_otg_dev; -static int srp_wait_done; - -/* FSM timers */ -struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, - *b_ase0_brst_tmr, *b_se0_srp_tmr; - -/* Driver specific timers */ -struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, - *b_srp_wait_tmr, *a_wait_enum_tmr; - -static struct list_head active_timers; - -static struct fsl_otg_config fsl_otg_initdata = { - .otg_port = 1, -}; - -#ifdef CONFIG_PPC32 -static u32 _fsl_readl_be(const unsigned __iomem *p) -{ - return in_be32(p); -} - -static u32 _fsl_readl_le(const unsigned __iomem *p) -{ - return in_le32(p); -} - -static void _fsl_writel_be(u32 v, unsigned __iomem *p) -{ - out_be32(p, v); -} - -static void _fsl_writel_le(u32 v, unsigned __iomem *p) -{ - out_le32(p, v); -} - -static u32 (*_fsl_readl)(const unsigned __iomem *p); -static void (*_fsl_writel)(u32 v, unsigned __iomem *p); - -#define fsl_readl(p) (*_fsl_readl)((p)) -#define fsl_writel(v, p) (*_fsl_writel)((v), (p)) - -#else -#define fsl_readl(addr) readl(addr) -#define fsl_writel(val, addr) writel(val, addr) -#endif /* CONFIG_PPC32 */ - -/* Routines to access transceiver ULPI registers */ -u8 view_ulpi(u8 addr) -{ - u32 temp; - - temp = 0x40000000 | (addr << 16); - fsl_writel(temp, &usb_dr_regs->ulpiview); - udelay(1000); - while (temp & 0x40) - temp = fsl_readl(&usb_dr_regs->ulpiview); - return (le32_to_cpu(temp) & 0x0000ff00) >> 8; -} - -int write_ulpi(u8 addr, u8 data) -{ - u32 temp; - - temp = 0x60000000 | (addr << 16) | data; - fsl_writel(temp, &usb_dr_regs->ulpiview); - return 0; -} - -/* -------------------------------------------------------------*/ -/* Operations that will be called from OTG Finite State Machine */ - -/* Charge vbus for vbus pulsing in SRP */ -void fsl_otg_chrg_vbus(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - /* stop discharging, start charging */ - tmp = (tmp & ~OTGSC_CTRL_VBUS_DISCHARGE) | - OTGSC_CTRL_VBUS_CHARGE; - else - /* stop charging */ - tmp &= ~OTGSC_CTRL_VBUS_CHARGE; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* Discharge vbus through a resistor to ground */ -void fsl_otg_dischrg_vbus(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - /* stop charging, start discharging */ - tmp = (tmp & ~OTGSC_CTRL_VBUS_CHARGE) | - OTGSC_CTRL_VBUS_DISCHARGE; - else - /* stop discharging */ - tmp &= ~OTGSC_CTRL_VBUS_DISCHARGE; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* A-device driver vbus, controlled through PP bit in PORTSC */ -void fsl_otg_drv_vbus(int on) -{ - u32 tmp; - - if (on) { - tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; - fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); - } else { - tmp = fsl_readl(&usb_dr_regs->portsc) & - ~PORTSC_W1C_BITS & ~PORTSC_PORT_POWER; - fsl_writel(tmp, &usb_dr_regs->portsc); - } -} - -/* - * Pull-up D+, signalling connect by periperal. Also used in - * data-line pulsing in SRP - */ -void fsl_otg_loc_conn(int on) -{ - u32 tmp; - - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - - if (on) - tmp |= OTGSC_CTRL_DATA_PULSING; - else - tmp &= ~OTGSC_CTRL_DATA_PULSING; - - fsl_writel(tmp, &usb_dr_regs->otgsc); -} - -/* - * Generate SOF by host. This is controlled through suspend/resume the - * port. In host mode, controller will automatically send SOF. - * Suspend will block the data on the port. - */ -void fsl_otg_loc_sof(int on) -{ - u32 tmp; - - tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; - if (on) - tmp |= PORTSC_PORT_FORCE_RESUME; - else - tmp |= PORTSC_PORT_SUSPEND; - - fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); - -} - -/* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ -void fsl_otg_start_pulse(void) -{ - u32 tmp; - - srp_wait_done = 0; -#ifdef HA_DATA_PULSE - tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; - tmp |= OTGSC_HA_DATA_PULSE; - fsl_writel(tmp, &usb_dr_regs->otgsc); -#else - fsl_otg_loc_conn(1); -#endif - - fsl_otg_add_timer(b_data_pulse_tmr); -} - -void b_data_pulse_end(unsigned long foo) -{ -#ifdef HA_DATA_PULSE -#else - fsl_otg_loc_conn(0); -#endif - - /* Do VBUS pulse after data pulse */ - fsl_otg_pulse_vbus(); -} - -void fsl_otg_pulse_vbus(void) -{ - srp_wait_done = 0; - fsl_otg_chrg_vbus(1); - /* start the timer to end vbus charge */ - fsl_otg_add_timer(b_vbus_pulse_tmr); -} - -void b_vbus_pulse_end(unsigned long foo) -{ - fsl_otg_chrg_vbus(0); - - /* - * As USB3300 using the same a_sess_vld and b_sess_vld voltage - * we need to discharge the bus for a while to distinguish - * residual voltage of vbus pulsing and A device pull up - */ - fsl_otg_dischrg_vbus(1); - fsl_otg_add_timer(b_srp_wait_tmr); -} - -void b_srp_end(unsigned long foo) -{ - fsl_otg_dischrg_vbus(0); - srp_wait_done = 1; - - if ((fsl_otg_dev->phy.state == OTG_STATE_B_SRP_INIT) && - fsl_otg_dev->fsm.b_sess_vld) - fsl_otg_dev->fsm.b_srp_done = 1; -} - -/* - * Workaround for a_host suspending too fast. When a_bus_req=0, - * a_host will start by SRP. It needs to set b_hnp_enable before - * actually suspending to start HNP - */ -void a_wait_enum(unsigned long foo) -{ - VDBG("a_wait_enum timeout\n"); - if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) - fsl_otg_add_timer(a_wait_enum_tmr); - else - otg_statemachine(&fsl_otg_dev->fsm); -} - -/* The timeout callback function to set time out bit */ -void set_tmout(unsigned long indicator) -{ - *(int *)indicator = 1; -} - -/* Initialize timers */ -int fsl_otg_init_timers(struct otg_fsm *fsm) -{ - /* FSM used timers */ - a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, - (unsigned long)&fsm->a_wait_vrise_tmout); - if (!a_wait_vrise_tmr) - return -ENOMEM; - - a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, - (unsigned long)&fsm->a_wait_bcon_tmout); - if (!a_wait_bcon_tmr) - return -ENOMEM; - - a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, - (unsigned long)&fsm->a_aidl_bdis_tmout); - if (!a_aidl_bdis_tmr) - return -ENOMEM; - - b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, - (unsigned long)&fsm->b_ase0_brst_tmout); - if (!b_ase0_brst_tmr) - return -ENOMEM; - - b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, - (unsigned long)&fsm->b_se0_srp); - if (!b_se0_srp_tmr) - return -ENOMEM; - - b_srp_fail_tmr = otg_timer_initializer(&set_tmout, TB_SRP_FAIL, - (unsigned long)&fsm->b_srp_done); - if (!b_srp_fail_tmr) - return -ENOMEM; - - a_wait_enum_tmr = otg_timer_initializer(&a_wait_enum, 10, - (unsigned long)&fsm); - if (!a_wait_enum_tmr) - return -ENOMEM; - - /* device driver used timers */ - b_srp_wait_tmr = otg_timer_initializer(&b_srp_end, TB_SRP_WAIT, 0); - if (!b_srp_wait_tmr) - return -ENOMEM; - - b_data_pulse_tmr = otg_timer_initializer(&b_data_pulse_end, - TB_DATA_PLS, 0); - if (!b_data_pulse_tmr) - return -ENOMEM; - - b_vbus_pulse_tmr = otg_timer_initializer(&b_vbus_pulse_end, - TB_VBUS_PLS, 0); - if (!b_vbus_pulse_tmr) - return -ENOMEM; - - return 0; -} - -/* Uninitialize timers */ -void fsl_otg_uninit_timers(void) -{ - /* FSM used timers */ - kfree(a_wait_vrise_tmr); - kfree(a_wait_bcon_tmr); - kfree(a_aidl_bdis_tmr); - kfree(b_ase0_brst_tmr); - kfree(b_se0_srp_tmr); - kfree(b_srp_fail_tmr); - kfree(a_wait_enum_tmr); - - /* device driver used timers */ - kfree(b_srp_wait_tmr); - kfree(b_data_pulse_tmr); - kfree(b_vbus_pulse_tmr); -} - -/* Add timer to timer list */ -void fsl_otg_add_timer(void *gtimer) -{ - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer; - - /* - * Check if the timer is already in the active list, - * if so update timer count - */ - list_for_each_entry(tmp_timer, &active_timers, list) - if (tmp_timer == timer) { - timer->count = timer->expires; - return; - } - timer->count = timer->expires; - list_add_tail(&timer->list, &active_timers); -} - -/* Remove timer from the timer list; clear timeout status */ -void fsl_otg_del_timer(void *gtimer) -{ - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer, *del_tmp; - - list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) - if (tmp_timer == timer) - list_del(&timer->list); -} - -/* - * Reduce timer count by 1, and find timeout conditions. - * Called by fsl_otg 1ms timer interrupt - */ -int fsl_otg_tick_timer(void) -{ - struct fsl_otg_timer *tmp_timer, *del_tmp; - int expired = 0; - - list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { - tmp_timer->count--; - /* check if timer expires */ - if (!tmp_timer->count) { - list_del(&tmp_timer->list); - tmp_timer->function(tmp_timer->data); - expired = 1; - } - } - - return expired; -} - -/* Reset controller, not reset the bus */ -void otg_reset_controller(void) -{ - u32 command; - - command = fsl_readl(&usb_dr_regs->usbcmd); - command |= (1 << 1); - fsl_writel(command, &usb_dr_regs->usbcmd); - while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) - ; -} - -/* Call suspend/resume routines in host driver */ -int fsl_otg_start_host(struct otg_fsm *fsm, int on) -{ - struct usb_otg *otg = fsm->otg; - struct device *dev; - struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); - u32 retval = 0; - - if (!otg->host) - return -ENODEV; - dev = otg->host->controller; - - /* - * Update a_vbus_vld state as a_vbus_vld int is disabled - * in device mode - */ - fsm->a_vbus_vld = - !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); - if (on) { - /* start fsl usb host controller */ - if (otg_dev->host_working) - goto end; - else { - otg_reset_controller(); - VDBG("host on......\n"); - if (dev->driver->pm && dev->driver->pm->resume) { - retval = dev->driver->pm->resume(dev); - if (fsm->id) { - /* default-b */ - fsl_otg_drv_vbus(1); - /* - * Workaround: b_host can't driver - * vbus, but PP in PORTSC needs to - * be 1 for host to work. - * So we set drv_vbus bit in - * transceiver to 0 thru ULPI. - */ - write_ulpi(0x0c, 0x20); - } - } - - otg_dev->host_working = 1; - } - } else { - /* stop fsl usb host controller */ - if (!otg_dev->host_working) - goto end; - else { - VDBG("host off......\n"); - if (dev && dev->driver) { - if (dev->driver->pm && dev->driver->pm->suspend) - retval = dev->driver->pm->suspend(dev); - if (fsm->id) - /* default-b */ - fsl_otg_drv_vbus(0); - } - otg_dev->host_working = 0; - } - } -end: - return retval; -} - -/* - * Call suspend and resume function in udc driver - * to stop and start udc driver. - */ -int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) -{ - struct usb_otg *otg = fsm->otg; - struct device *dev; - - if (!otg->gadget || !otg->gadget->dev.parent) - return -ENODEV; - - VDBG("gadget %s\n", on ? "on" : "off"); - dev = otg->gadget->dev.parent; - - if (on) { - if (dev->driver->resume) - dev->driver->resume(dev); - } else { - if (dev->driver->suspend) - dev->driver->suspend(dev, otg_suspend_state); - } - - return 0; -} - -/* - * Called by initialization code of host driver. Register host controller - * to the OTG. Suspend host for OTG role detection. - */ -static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - otg->host = host; - - otg_dev->fsm.a_bus_drop = 0; - otg_dev->fsm.a_bus_req = 1; - - if (host) { - VDBG("host off......\n"); - - otg->host->otg_port = fsl_otg_initdata.otg_port; - otg->host->is_b_host = otg_dev->fsm.id; - /* - * must leave time for khubd to finish its thing - * before yanking the host driver out from under it, - * so suspend the host after a short delay. - */ - otg_dev->host_working = 1; - schedule_delayed_work(&otg_dev->otg_event, 100); - return 0; - } else { - /* host driver going away */ - if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & - OTGSC_STS_USB_ID)) { - /* Mini-A cable connected */ - struct otg_fsm *fsm = &otg_dev->fsm; - - otg->phy->state = OTG_STATE_UNDEFINED; - fsm->protocol = PROTO_UNDEF; - } - } - - otg_dev->host_working = 0; - - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* Called by initialization code of udc. Register udc to OTG. */ -static int fsl_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - VDBG("otg_dev 0x%x\n", (int)otg_dev); - VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - if (!gadget) { - if (!otg->default_a) - otg->gadget->ops->vbus_draw(otg->gadget, 0); - usb_gadget_vbus_disconnect(otg->gadget); - otg->gadget = 0; - otg_dev->fsm.b_bus_req = 0; - otg_statemachine(&otg_dev->fsm); - return 0; - } - - otg->gadget = gadget; - otg->gadget->is_a_peripheral = !otg_dev->fsm.id; - - otg_dev->fsm.b_bus_req = 1; - - /* start the gadget right away if the ID pin says Mini-B */ - DBG("ID pin=%d\n", otg_dev->fsm.id); - if (otg_dev->fsm.id == 1) { - fsl_otg_start_host(&otg_dev->fsm, 0); - otg_drv_vbus(&otg_dev->fsm, 0); - fsl_otg_start_gadget(&otg_dev->fsm, 1); - } - - return 0; -} - -/* Set OTG port power, only for B-device */ -static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA) -{ - if (!fsl_otg_dev) - return -ENODEV; - if (phy->state == OTG_STATE_B_PERIPHERAL) - pr_info("FSL OTG: Draw %d mA\n", mA); - - return 0; -} - -/* - * Delayed pin detect interrupt processing. - * - * When the Mini-A cable is disconnected from the board, - * the pin-detect interrupt happens before the disconnect - * interrupts for the connected device(s). In order to - * process the disconnect interrupt(s) prior to switching - * roles, the pin-detect interrupts are delayed, and handled - * by this routine. - */ -static void fsl_otg_event(struct work_struct *work) -{ - struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work); - struct otg_fsm *fsm = &og->fsm; - - if (fsm->id) { /* switch to gadget */ - fsl_otg_start_host(fsm, 0); - otg_drv_vbus(fsm, 0); - fsl_otg_start_gadget(fsm, 1); - } -} - -/* B-device start SRP */ -static int fsl_otg_start_srp(struct usb_otg *otg) -{ - struct fsl_otg *otg_dev; - - if (!otg || otg->phy->state != OTG_STATE_B_IDLE) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - otg_dev->fsm.b_bus_req = 1; - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* A_host suspend will call this function to start hnp */ -static int fsl_otg_start_hnp(struct usb_otg *otg) -{ - struct fsl_otg *otg_dev; - - if (!otg) - return -ENODEV; - - otg_dev = container_of(otg->phy, struct fsl_otg, phy); - if (otg_dev != fsl_otg_dev) - return -ENODEV; - - DBG("start_hnp...n"); - - /* clear a_bus_req to enter a_suspend state */ - otg_dev->fsm.a_bus_req = 0; - otg_statemachine(&otg_dev->fsm); - - return 0; -} - -/* - * Interrupt handler. OTG/host/peripheral share the same int line. - * OTG driver clears OTGSC interrupts and leaves USB interrupts - * intact. It needs to have knowledge of some USB interrupts - * such as port change. - */ -irqreturn_t fsl_otg_isr(int irq, void *dev_id) -{ - struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; - struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; - u32 otg_int_src, otg_sc; - - otg_sc = fsl_readl(&usb_dr_regs->otgsc); - otg_int_src = otg_sc & OTGSC_INTSTS_MASK & (otg_sc >> 8); - - /* Only clear otg interrupts */ - fsl_writel(otg_sc, &usb_dr_regs->otgsc); - - /*FIXME: ID change not generate when init to 0 */ - fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; - otg->default_a = (fsm->id == 0); - - /* process OTG interrupts */ - if (otg_int_src) { - if (otg_int_src & OTGSC_INTSTS_USB_ID) { - fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; - otg->default_a = (fsm->id == 0); - /* clear conn information */ - if (fsm->id) - fsm->b_conn = 0; - else - fsm->a_conn = 0; - - if (otg->host) - otg->host->is_b_host = fsm->id; - if (otg->gadget) - otg->gadget->is_a_peripheral = !fsm->id; - VDBG("ID int (ID is %d)\n", fsm->id); - - if (fsm->id) { /* switch to gadget */ - schedule_delayed_work( - &((struct fsl_otg *)dev_id)->otg_event, - 100); - } else { /* switch to host */ - cancel_delayed_work(& - ((struct fsl_otg *)dev_id)-> - otg_event); - fsl_otg_start_gadget(fsm, 0); - otg_drv_vbus(fsm, 1); - fsl_otg_start_host(fsm, 1); - } - return IRQ_HANDLED; - } - } - return IRQ_NONE; -} - -static struct otg_fsm_ops fsl_otg_ops = { - .chrg_vbus = fsl_otg_chrg_vbus, - .drv_vbus = fsl_otg_drv_vbus, - .loc_conn = fsl_otg_loc_conn, - .loc_sof = fsl_otg_loc_sof, - .start_pulse = fsl_otg_start_pulse, - - .add_timer = fsl_otg_add_timer, - .del_timer = fsl_otg_del_timer, - - .start_host = fsl_otg_start_host, - .start_gadget = fsl_otg_start_gadget, -}; - -/* Initialize the global variable fsl_otg_dev and request IRQ for OTG */ -static int fsl_otg_conf(struct platform_device *pdev) -{ - struct fsl_otg *fsl_otg_tc; - int status; - - if (fsl_otg_dev) - return 0; - - /* allocate space to fsl otg device */ - fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); - if (!fsl_otg_tc) - return -ENOMEM; - - fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!fsl_otg_tc->phy.otg) { - kfree(fsl_otg_tc); - return -ENOMEM; - } - - INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); - - INIT_LIST_HEAD(&active_timers); - status = fsl_otg_init_timers(&fsl_otg_tc->fsm); - if (status) { - pr_info("Couldn't init OTG timers\n"); - goto err; - } - spin_lock_init(&fsl_otg_tc->fsm.lock); - - /* Set OTG state machine operations */ - fsl_otg_tc->fsm.ops = &fsl_otg_ops; - - /* initialize the otg structure */ - fsl_otg_tc->phy.label = DRIVER_DESC; - fsl_otg_tc->phy.set_power = fsl_otg_set_power; - - fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; - fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; - fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; - fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; - fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; - - fsl_otg_dev = fsl_otg_tc; - - /* Store the otg transceiver */ - status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); - if (status) { - pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); - goto err; - } - - return 0; -err: - fsl_otg_uninit_timers(); - kfree(fsl_otg_tc->phy.otg); - kfree(fsl_otg_tc); - return status; -} - -/* OTG Initialization */ -int usb_otg_start(struct platform_device *pdev) -{ - struct fsl_otg *p_otg; - struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); - struct otg_fsm *fsm; - int status; - struct resource *res; - u32 temp; - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - p_otg = container_of(otg_trans, struct fsl_otg, phy); - fsm = &p_otg->fsm; - - /* Initialize the state machine structure with default values */ - SET_OTG_STATE(otg_trans, OTG_STATE_UNDEFINED); - fsm->otg = p_otg->phy.otg; - - /* We don't require predefined MEM/IRQ resource index */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENXIO; - - /* We don't request_mem_region here to enable resource sharing - * with host/device */ - - usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); - p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; - pdata->regs = (void *)usb_dr_regs; - - if (pdata->init && pdata->init(pdev) != 0) - return -EINVAL; - - if (pdata->big_endian_mmio) { - _fsl_readl = _fsl_readl_be; - _fsl_writel = _fsl_writel_be; - } else { - _fsl_readl = _fsl_readl_le; - _fsl_writel = _fsl_writel_le; - } - - /* request irq */ - p_otg->irq = platform_get_irq(pdev, 0); - status = request_irq(p_otg->irq, fsl_otg_isr, - IRQF_SHARED, driver_name, p_otg); - if (status) { - dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", - p_otg->irq, status); - iounmap(p_otg->dr_mem_map); - kfree(p_otg->phy.otg); - kfree(p_otg); - return status; - } - - /* stop the controller */ - temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); - temp &= ~USB_CMD_RUN_STOP; - fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); - - /* reset the controller */ - temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); - temp |= USB_CMD_CTRL_RESET; - fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); - - /* wait reset completed */ - while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) - ; - - /* configure the VBUSHS as IDLE(both host and device) */ - temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); - fsl_writel(temp, &p_otg->dr_mem_map->usbmode); - - /* configure PHY interface */ - temp = fsl_readl(&p_otg->dr_mem_map->portsc); - temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); - switch (pdata->phy_mode) { - case FSL_USB2_PHY_ULPI: - temp |= PORTSC_PTS_ULPI; - break; - case FSL_USB2_PHY_UTMI_WIDE: - temp |= PORTSC_PTW_16BIT; - /* fall through */ - case FSL_USB2_PHY_UTMI: - temp |= PORTSC_PTS_UTMI; - /* fall through */ - default: - break; - } - fsl_writel(temp, &p_otg->dr_mem_map->portsc); - - if (pdata->have_sysif_regs) { - /* configure control enable IO output, big endian register */ - temp = __raw_readl(&p_otg->dr_mem_map->control); - temp |= USB_CTRL_IOENB; - __raw_writel(temp, &p_otg->dr_mem_map->control); - } - - /* disable all interrupt and clear all OTGSC status */ - temp = fsl_readl(&p_otg->dr_mem_map->otgsc); - temp &= ~OTGSC_INTERRUPT_ENABLE_BITS_MASK; - temp |= OTGSC_INTERRUPT_STATUS_BITS_MASK | OTGSC_CTRL_VBUS_DISCHARGE; - fsl_writel(temp, &p_otg->dr_mem_map->otgsc); - - /* - * The identification (id) input is FALSE when a Mini-A plug is inserted - * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. - * Also: record initial state of ID pin - */ - if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { - p_otg->phy.state = OTG_STATE_UNDEFINED; - p_otg->fsm.id = 1; - } else { - p_otg->phy.state = OTG_STATE_A_IDLE; - p_otg->fsm.id = 0; - } - - DBG("initial ID pin=%d\n", p_otg->fsm.id); - - /* enable OTG ID pin interrupt */ - temp = fsl_readl(&p_otg->dr_mem_map->otgsc); - temp |= OTGSC_INTR_USB_ID_EN; - temp &= ~(OTGSC_CTRL_VBUS_DISCHARGE | OTGSC_INTR_1MS_TIMER_EN); - fsl_writel(temp, &p_otg->dr_mem_map->otgsc); - - return 0; -} - -/* - * state file in sysfs - */ -static int show_fsl_usb2_otg_state(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct otg_fsm *fsm = &fsl_otg_dev->fsm; - char *next = buf; - unsigned size = PAGE_SIZE; - unsigned long flags; - int t; - - spin_lock_irqsave(&fsm->lock, flags); - - /* basic driver infomation */ - t = scnprintf(next, size, - DRIVER_DESC "\n" "fsl_usb2_otg version: %s\n\n", - DRIVER_VERSION); - size -= t; - next += t; - - /* Registers */ - t = scnprintf(next, size, - "OTGSC: 0x%08x\n" - "PORTSC: 0x%08x\n" - "USBMODE: 0x%08x\n" - "USBCMD: 0x%08x\n" - "USBSTS: 0x%08x\n" - "USBINTR: 0x%08x\n", - fsl_readl(&usb_dr_regs->otgsc), - fsl_readl(&usb_dr_regs->portsc), - fsl_readl(&usb_dr_regs->usbmode), - fsl_readl(&usb_dr_regs->usbcmd), - fsl_readl(&usb_dr_regs->usbsts), - fsl_readl(&usb_dr_regs->usbintr)); - size -= t; - next += t; - - /* State */ - t = scnprintf(next, size, - "OTG state: %s\n\n", - usb_otg_state_string(fsl_otg_dev->phy.state)); - size -= t; - next += t; - - /* State Machine Variables */ - t = scnprintf(next, size, - "a_bus_req: %d\n" - "b_bus_req: %d\n" - "a_bus_resume: %d\n" - "a_bus_suspend: %d\n" - "a_conn: %d\n" - "a_sess_vld: %d\n" - "a_srp_det: %d\n" - "a_vbus_vld: %d\n" - "b_bus_resume: %d\n" - "b_bus_suspend: %d\n" - "b_conn: %d\n" - "b_se0_srp: %d\n" - "b_sess_end: %d\n" - "b_sess_vld: %d\n" - "id: %d\n", - fsm->a_bus_req, - fsm->b_bus_req, - fsm->a_bus_resume, - fsm->a_bus_suspend, - fsm->a_conn, - fsm->a_sess_vld, - fsm->a_srp_det, - fsm->a_vbus_vld, - fsm->b_bus_resume, - fsm->b_bus_suspend, - fsm->b_conn, - fsm->b_se0_srp, - fsm->b_sess_end, - fsm->b_sess_vld, - fsm->id); - size -= t; - next += t; - - spin_unlock_irqrestore(&fsm->lock, flags); - - return PAGE_SIZE - size; -} - -static DEVICE_ATTR(fsl_usb2_otg_state, S_IRUGO, show_fsl_usb2_otg_state, NULL); - - -/* Char driver interface to control some OTG input */ - -/* - * Handle some ioctl command, such as get otg - * status and set host suspend - */ -static long fsl_otg_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - u32 retval = 0; - - switch (cmd) { - case GET_OTG_STATUS: - retval = fsl_otg_dev->host_working; - break; - - case SET_A_SUSPEND_REQ: - fsl_otg_dev->fsm.a_suspend_req = arg; - break; - - case SET_A_BUS_DROP: - fsl_otg_dev->fsm.a_bus_drop = arg; - break; - - case SET_A_BUS_REQ: - fsl_otg_dev->fsm.a_bus_req = arg; - break; - - case SET_B_BUS_REQ: - fsl_otg_dev->fsm.b_bus_req = arg; - break; - - default: - break; - } - - otg_statemachine(&fsl_otg_dev->fsm); - - return retval; -} - -static int fsl_otg_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int fsl_otg_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations otg_fops = { - .owner = THIS_MODULE, - .llseek = NULL, - .read = NULL, - .write = NULL, - .unlocked_ioctl = fsl_otg_ioctl, - .open = fsl_otg_open, - .release = fsl_otg_release, -}; - -static int fsl_otg_probe(struct platform_device *pdev) -{ - int ret; - - if (!pdev->dev.platform_data) - return -ENODEV; - - /* configure the OTG */ - ret = fsl_otg_conf(pdev); - if (ret) { - dev_err(&pdev->dev, "Couldn't configure OTG module\n"); - return ret; - } - - /* start OTG */ - ret = usb_otg_start(pdev); - if (ret) { - dev_err(&pdev->dev, "Can't init FSL OTG device\n"); - return ret; - } - - ret = register_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME, &otg_fops); - if (ret) { - dev_err(&pdev->dev, "unable to register FSL OTG device\n"); - return ret; - } - - ret = device_create_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); - if (ret) - dev_warn(&pdev->dev, "Can't register sysfs attribute\n"); - - return ret; -} - -static int fsl_otg_remove(struct platform_device *pdev) -{ - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - usb_remove_phy(&fsl_otg_dev->phy); - free_irq(fsl_otg_dev->irq, fsl_otg_dev); - - iounmap((void *)usb_dr_regs); - - fsl_otg_uninit_timers(); - kfree(fsl_otg_dev->phy.otg); - kfree(fsl_otg_dev); - - device_remove_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); - - unregister_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME); - - if (pdata->exit) - pdata->exit(pdev); - - return 0; -} - -struct platform_driver fsl_otg_driver = { - .probe = fsl_otg_probe, - .remove = fsl_otg_remove, - .driver = { - .name = driver_name, - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(fsl_otg_driver); - -MODULE_DESCRIPTION(DRIVER_INFO); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/fsl_otg.h b/drivers/usb/phy/fsl_otg.h deleted file mode 100644 index ca266280895d..000000000000 --- a/drivers/usb/phy/fsl_otg.h +++ /dev/null @@ -1,406 +0,0 @@ -/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * 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 "otg_fsm.h" -#include -#include - -/* USB Command Register Bit Masks */ -#define USB_CMD_RUN_STOP (0x1<<0) -#define USB_CMD_CTRL_RESET (0x1<<1) -#define USB_CMD_PERIODIC_SCHEDULE_EN (0x1<<4) -#define USB_CMD_ASYNC_SCHEDULE_EN (0x1<<5) -#define USB_CMD_INT_AA_DOORBELL (0x1<<6) -#define USB_CMD_ASP (0x3<<8) -#define USB_CMD_ASYNC_SCH_PARK_EN (0x1<<11) -#define USB_CMD_SUTW (0x1<<13) -#define USB_CMD_ATDTW (0x1<<14) -#define USB_CMD_ITC (0xFF<<16) - -/* bit 15,3,2 are frame list size */ -#define USB_CMD_FRAME_SIZE_1024 (0x0<<15 | 0x0<<2) -#define USB_CMD_FRAME_SIZE_512 (0x0<<15 | 0x1<<2) -#define USB_CMD_FRAME_SIZE_256 (0x0<<15 | 0x2<<2) -#define USB_CMD_FRAME_SIZE_128 (0x0<<15 | 0x3<<2) -#define USB_CMD_FRAME_SIZE_64 (0x1<<15 | 0x0<<2) -#define USB_CMD_FRAME_SIZE_32 (0x1<<15 | 0x1<<2) -#define USB_CMD_FRAME_SIZE_16 (0x1<<15 | 0x2<<2) -#define USB_CMD_FRAME_SIZE_8 (0x1<<15 | 0x3<<2) - -/* bit 9-8 are async schedule park mode count */ -#define USB_CMD_ASP_00 (0x0<<8) -#define USB_CMD_ASP_01 (0x1<<8) -#define USB_CMD_ASP_10 (0x2<<8) -#define USB_CMD_ASP_11 (0x3<<8) -#define USB_CMD_ASP_BIT_POS (8) - -/* bit 23-16 are interrupt threshold control */ -#define USB_CMD_ITC_NO_THRESHOLD (0x00<<16) -#define USB_CMD_ITC_1_MICRO_FRM (0x01<<16) -#define USB_CMD_ITC_2_MICRO_FRM (0x02<<16) -#define USB_CMD_ITC_4_MICRO_FRM (0x04<<16) -#define USB_CMD_ITC_8_MICRO_FRM (0x08<<16) -#define USB_CMD_ITC_16_MICRO_FRM (0x10<<16) -#define USB_CMD_ITC_32_MICRO_FRM (0x20<<16) -#define USB_CMD_ITC_64_MICRO_FRM (0x40<<16) -#define USB_CMD_ITC_BIT_POS (16) - -/* USB Status Register Bit Masks */ -#define USB_STS_INT (0x1<<0) -#define USB_STS_ERR (0x1<<1) -#define USB_STS_PORT_CHANGE (0x1<<2) -#define USB_STS_FRM_LST_ROLL (0x1<<3) -#define USB_STS_SYS_ERR (0x1<<4) -#define USB_STS_IAA (0x1<<5) -#define USB_STS_RESET_RECEIVED (0x1<<6) -#define USB_STS_SOF (0x1<<7) -#define USB_STS_DCSUSPEND (0x1<<8) -#define USB_STS_HC_HALTED (0x1<<12) -#define USB_STS_RCL (0x1<<13) -#define USB_STS_PERIODIC_SCHEDULE (0x1<<14) -#define USB_STS_ASYNC_SCHEDULE (0x1<<15) - -/* USB Interrupt Enable Register Bit Masks */ -#define USB_INTR_INT_EN (0x1<<0) -#define USB_INTR_ERR_INT_EN (0x1<<1) -#define USB_INTR_PC_DETECT_EN (0x1<<2) -#define USB_INTR_FRM_LST_ROLL_EN (0x1<<3) -#define USB_INTR_SYS_ERR_EN (0x1<<4) -#define USB_INTR_ASYN_ADV_EN (0x1<<5) -#define USB_INTR_RESET_EN (0x1<<6) -#define USB_INTR_SOF_EN (0x1<<7) -#define USB_INTR_DEVICE_SUSPEND (0x1<<8) - -/* Device Address bit masks */ -#define USB_DEVICE_ADDRESS_MASK (0x7F<<25) -#define USB_DEVICE_ADDRESS_BIT_POS (25) -/* PORTSC Register Bit Masks,Only one PORT in OTG mode*/ -#define PORTSC_CURRENT_CONNECT_STATUS (0x1<<0) -#define PORTSC_CONNECT_STATUS_CHANGE (0x1<<1) -#define PORTSC_PORT_ENABLE (0x1<<2) -#define PORTSC_PORT_EN_DIS_CHANGE (0x1<<3) -#define PORTSC_OVER_CURRENT_ACT (0x1<<4) -#define PORTSC_OVER_CUURENT_CHG (0x1<<5) -#define PORTSC_PORT_FORCE_RESUME (0x1<<6) -#define PORTSC_PORT_SUSPEND (0x1<<7) -#define PORTSC_PORT_RESET (0x1<<8) -#define PORTSC_LINE_STATUS_BITS (0x3<<10) -#define PORTSC_PORT_POWER (0x1<<12) -#define PORTSC_PORT_INDICTOR_CTRL (0x3<<14) -#define PORTSC_PORT_TEST_CTRL (0xF<<16) -#define PORTSC_WAKE_ON_CONNECT_EN (0x1<<20) -#define PORTSC_WAKE_ON_CONNECT_DIS (0x1<<21) -#define PORTSC_WAKE_ON_OVER_CURRENT (0x1<<22) -#define PORTSC_PHY_LOW_POWER_SPD (0x1<<23) -#define PORTSC_PORT_FORCE_FULL_SPEED (0x1<<24) -#define PORTSC_PORT_SPEED_MASK (0x3<<26) -#define PORTSC_TRANSCEIVER_WIDTH (0x1<<28) -#define PORTSC_PHY_TYPE_SEL (0x3<<30) -/* bit 11-10 are line status */ -#define PORTSC_LINE_STATUS_SE0 (0x0<<10) -#define PORTSC_LINE_STATUS_JSTATE (0x1<<10) -#define PORTSC_LINE_STATUS_KSTATE (0x2<<10) -#define PORTSC_LINE_STATUS_UNDEF (0x3<<10) -#define PORTSC_LINE_STATUS_BIT_POS (10) - -/* bit 15-14 are port indicator control */ -#define PORTSC_PIC_OFF (0x0<<14) -#define PORTSC_PIC_AMBER (0x1<<14) -#define PORTSC_PIC_GREEN (0x2<<14) -#define PORTSC_PIC_UNDEF (0x3<<14) -#define PORTSC_PIC_BIT_POS (14) - -/* bit 19-16 are port test control */ -#define PORTSC_PTC_DISABLE (0x0<<16) -#define PORTSC_PTC_JSTATE (0x1<<16) -#define PORTSC_PTC_KSTATE (0x2<<16) -#define PORTSC_PTC_SEQNAK (0x3<<16) -#define PORTSC_PTC_PACKET (0x4<<16) -#define PORTSC_PTC_FORCE_EN (0x5<<16) -#define PORTSC_PTC_BIT_POS (16) - -/* bit 27-26 are port speed */ -#define PORTSC_PORT_SPEED_FULL (0x0<<26) -#define PORTSC_PORT_SPEED_LOW (0x1<<26) -#define PORTSC_PORT_SPEED_HIGH (0x2<<26) -#define PORTSC_PORT_SPEED_UNDEF (0x3<<26) -#define PORTSC_SPEED_BIT_POS (26) - -/* bit 28 is parallel transceiver width for UTMI interface */ -#define PORTSC_PTW (0x1<<28) -#define PORTSC_PTW_8BIT (0x0<<28) -#define PORTSC_PTW_16BIT (0x1<<28) - -/* bit 31-30 are port transceiver select */ -#define PORTSC_PTS_UTMI (0x0<<30) -#define PORTSC_PTS_ULPI (0x2<<30) -#define PORTSC_PTS_FSLS_SERIAL (0x3<<30) -#define PORTSC_PTS_BIT_POS (30) - -#define PORTSC_W1C_BITS \ - (PORTSC_CONNECT_STATUS_CHANGE | \ - PORTSC_PORT_EN_DIS_CHANGE | \ - PORTSC_OVER_CUURENT_CHG) - -/* OTG Status Control Register Bit Masks */ -#define OTGSC_CTRL_VBUS_DISCHARGE (0x1<<0) -#define OTGSC_CTRL_VBUS_CHARGE (0x1<<1) -#define OTGSC_CTRL_OTG_TERMINATION (0x1<<3) -#define OTGSC_CTRL_DATA_PULSING (0x1<<4) -#define OTGSC_CTRL_ID_PULL_EN (0x1<<5) -#define OTGSC_HA_DATA_PULSE (0x1<<6) -#define OTGSC_HA_BA (0x1<<7) -#define OTGSC_STS_USB_ID (0x1<<8) -#define OTGSC_STS_A_VBUS_VALID (0x1<<9) -#define OTGSC_STS_A_SESSION_VALID (0x1<<10) -#define OTGSC_STS_B_SESSION_VALID (0x1<<11) -#define OTGSC_STS_B_SESSION_END (0x1<<12) -#define OTGSC_STS_1MS_TOGGLE (0x1<<13) -#define OTGSC_STS_DATA_PULSING (0x1<<14) -#define OTGSC_INTSTS_USB_ID (0x1<<16) -#define OTGSC_INTSTS_A_VBUS_VALID (0x1<<17) -#define OTGSC_INTSTS_A_SESSION_VALID (0x1<<18) -#define OTGSC_INTSTS_B_SESSION_VALID (0x1<<19) -#define OTGSC_INTSTS_B_SESSION_END (0x1<<20) -#define OTGSC_INTSTS_1MS (0x1<<21) -#define OTGSC_INTSTS_DATA_PULSING (0x1<<22) -#define OTGSC_INTR_USB_ID_EN (0x1<<24) -#define OTGSC_INTR_A_VBUS_VALID_EN (0x1<<25) -#define OTGSC_INTR_A_SESSION_VALID_EN (0x1<<26) -#define OTGSC_INTR_B_SESSION_VALID_EN (0x1<<27) -#define OTGSC_INTR_B_SESSION_END_EN (0x1<<28) -#define OTGSC_INTR_1MS_TIMER_EN (0x1<<29) -#define OTGSC_INTR_DATA_PULSING_EN (0x1<<30) -#define OTGSC_INTSTS_MASK (0x00ff0000) - -/* USB MODE Register Bit Masks */ -#define USB_MODE_CTRL_MODE_IDLE (0x0<<0) -#define USB_MODE_CTRL_MODE_DEVICE (0x2<<0) -#define USB_MODE_CTRL_MODE_HOST (0x3<<0) -#define USB_MODE_CTRL_MODE_RSV (0x1<<0) -#define USB_MODE_SETUP_LOCK_OFF (0x1<<3) -#define USB_MODE_STREAM_DISABLE (0x1<<4) -#define USB_MODE_ES (0x1<<2) /* Endian Select */ - -/* control Register Bit Masks */ -#define USB_CTRL_IOENB (0x1<<2) -#define USB_CTRL_ULPI_INT0EN (0x1<<0) - -/* BCSR5 */ -#define BCSR5_INT_USB (0x02) - -/* USB module clk cfg */ -#define SCCR_OFFS (0xA08) -#define SCCR_USB_CLK_DISABLE (0x00000000) /* USB clk disable */ -#define SCCR_USB_MPHCM_11 (0x00c00000) -#define SCCR_USB_MPHCM_01 (0x00400000) -#define SCCR_USB_MPHCM_10 (0x00800000) -#define SCCR_USB_DRCM_11 (0x00300000) -#define SCCR_USB_DRCM_01 (0x00100000) -#define SCCR_USB_DRCM_10 (0x00200000) - -#define SICRL_OFFS (0x114) -#define SICRL_USB0 (0x40000000) -#define SICRL_USB1 (0x20000000) - -#define SICRH_OFFS (0x118) -#define SICRH_USB_UTMI (0x00020000) - -/* OTG interrupt enable bit masks */ -#define OTGSC_INTERRUPT_ENABLE_BITS_MASK \ - (OTGSC_INTR_USB_ID_EN | \ - OTGSC_INTR_1MS_TIMER_EN | \ - OTGSC_INTR_A_VBUS_VALID_EN | \ - OTGSC_INTR_A_SESSION_VALID_EN | \ - OTGSC_INTR_B_SESSION_VALID_EN | \ - OTGSC_INTR_B_SESSION_END_EN | \ - OTGSC_INTR_DATA_PULSING_EN) - -/* OTG interrupt status bit masks */ -#define OTGSC_INTERRUPT_STATUS_BITS_MASK \ - (OTGSC_INTSTS_USB_ID | \ - OTGSC_INTR_1MS_TIMER_EN | \ - OTGSC_INTSTS_A_VBUS_VALID | \ - OTGSC_INTSTS_A_SESSION_VALID | \ - OTGSC_INTSTS_B_SESSION_VALID | \ - OTGSC_INTSTS_B_SESSION_END | \ - OTGSC_INTSTS_DATA_PULSING) - -/* - * A-DEVICE timing constants - */ - -/* Wait for VBUS Rise */ -#define TA_WAIT_VRISE (100) /* a_wait_vrise 100 ms, section: 6.6.5.1 */ - -/* Wait for B-Connect */ -#define TA_WAIT_BCON (10000) /* a_wait_bcon > 1 sec, section: 6.6.5.2 - * This is only used to get out of - * OTG_STATE_A_WAIT_BCON state if there was - * no connection for these many milliseconds - */ - -/* A-Idle to B-Disconnect */ -/* It is necessary for this timer to be more than 750 ms because of a bug in OPT - * test 5.4 in which B OPT disconnects after 750 ms instead of 75ms as stated - * in the test description - */ -#define TA_AIDL_BDIS (5000) /* a_suspend minimum 200 ms, section: 6.6.5.3 */ - -/* B-Idle to A-Disconnect */ -#define TA_BIDL_ADIS (12) /* 3 to 200 ms */ - -/* B-device timing constants */ - - -/* Data-Line Pulse Time*/ -#define TB_DATA_PLS (10) /* b_srp_init,continue 5~10ms, section:5.3.3 */ -#define TB_DATA_PLS_MIN (5) /* minimum 5 ms */ -#define TB_DATA_PLS_MAX (10) /* maximum 10 ms */ - -/* SRP Initiate Time */ -#define TB_SRP_INIT (100) /* b_srp_init,maximum 100 ms, section:5.3.8 */ - -/* SRP Fail Time */ -#define TB_SRP_FAIL (7000) /* b_srp_init,Fail time 5~30s, section:6.8.2.2*/ - -/* SRP result wait time */ -#define TB_SRP_WAIT (60) - -/* VBus time */ -#define TB_VBUS_PLS (30) /* time to keep vbus pulsing asserted */ - -/* Discharge time */ -/* This time should be less than 10ms. It varies from system to system. */ -#define TB_VBUS_DSCHRG (8) - -/* A-SE0 to B-Reset */ -#define TB_ASE0_BRST (20) /* b_wait_acon, mini 3.125 ms,section:6.8.2.4 */ - -/* A bus suspend timer before we can switch to b_wait_aconn */ -#define TB_A_SUSPEND (7) -#define TB_BUS_RESUME (12) - -/* SE0 Time Before SRP */ -#define TB_SE0_SRP (2) /* b_idle,minimum 2 ms, section:5.3.2 */ - -#define SET_OTG_STATE(otg_ptr, newstate) ((otg_ptr)->state = newstate) - -struct usb_dr_mmap { - /* Capability register */ - u8 res1[256]; - u16 caplength; /* Capability Register Length */ - u16 hciversion; /* Host Controller Interface Version */ - u32 hcsparams; /* Host Controller Structual Parameters */ - u32 hccparams; /* Host Controller Capability Parameters */ - u8 res2[20]; - u32 dciversion; /* Device Controller Interface Version */ - u32 dccparams; /* Device Controller Capability Parameters */ - u8 res3[24]; - /* Operation register */ - u32 usbcmd; /* USB Command Register */ - u32 usbsts; /* USB Status Register */ - u32 usbintr; /* USB Interrupt Enable Register */ - u32 frindex; /* Frame Index Register */ - u8 res4[4]; - u32 deviceaddr; /* Device Address */ - u32 endpointlistaddr; /* Endpoint List Address Register */ - u8 res5[4]; - u32 burstsize; /* Master Interface Data Burst Size Register */ - u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ - u8 res6[8]; - u32 ulpiview; /* ULPI register access */ - u8 res7[12]; - u32 configflag; /* Configure Flag Register */ - u32 portsc; /* Port 1 Status and Control Register */ - u8 res8[28]; - u32 otgsc; /* On-The-Go Status and Control */ - u32 usbmode; /* USB Mode Register */ - u32 endptsetupstat; /* Endpoint Setup Status Register */ - u32 endpointprime; /* Endpoint Initialization Register */ - u32 endptflush; /* Endpoint Flush Register */ - u32 endptstatus; /* Endpoint Status Register */ - u32 endptcomplete; /* Endpoint Complete Register */ - u32 endptctrl[6]; /* Endpoint Control Registers */ - u8 res9[552]; - u32 snoop1; - u32 snoop2; - u32 age_cnt_thresh; /* Age Count Threshold Register */ - u32 pri_ctrl; /* Priority Control Register */ - u32 si_ctrl; /* System Interface Control Register */ - u8 res10[236]; - u32 control; /* General Purpose Control Register */ -}; - -struct fsl_otg_timer { - unsigned long expires; /* Number of count increase to timeout */ - unsigned long count; /* Tick counter */ - void (*function)(unsigned long); /* Timeout function */ - unsigned long data; /* Data passed to function */ - struct list_head list; -}; - -inline struct fsl_otg_timer *otg_timer_initializer -(void (*function)(unsigned long), unsigned long expires, unsigned long data) -{ - struct fsl_otg_timer *timer; - - timer = kmalloc(sizeof(struct fsl_otg_timer), GFP_KERNEL); - if (!timer) - return NULL; - timer->function = function; - timer->expires = expires; - timer->data = data; - return timer; -} - -struct fsl_otg { - struct usb_phy phy; - struct otg_fsm fsm; - struct usb_dr_mmap *dr_mem_map; - struct delayed_work otg_event; - - /* used for usb host */ - struct work_struct work_wq; - u8 host_working; - - int irq; -}; - -struct fsl_otg_config { - u8 otg_port; -}; - -/* For SRP and HNP handle */ -#define FSL_OTG_MAJOR 240 -#define FSL_OTG_NAME "fsl-usb2-otg" -/* Command to OTG driver ioctl */ -#define OTG_IOCTL_MAGIC FSL_OTG_MAJOR -/* if otg work as host, it should return 1, otherwise return 0 */ -#define GET_OTG_STATUS _IOR(OTG_IOCTL_MAGIC, 1, int) -#define SET_A_SUSPEND_REQ _IOW(OTG_IOCTL_MAGIC, 2, int) -#define SET_A_BUS_DROP _IOW(OTG_IOCTL_MAGIC, 3, int) -#define SET_A_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 4, int) -#define SET_B_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 5, int) -#define GET_A_SUSPEND_REQ _IOR(OTG_IOCTL_MAGIC, 6, int) -#define GET_A_BUS_DROP _IOR(OTG_IOCTL_MAGIC, 7, int) -#define GET_A_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 8, int) -#define GET_B_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 9, int) - -void fsl_otg_add_timer(void *timer); -void fsl_otg_del_timer(void *timer); -void fsl_otg_pulse_vbus(void); diff --git a/drivers/usb/phy/gpio_vbus.c b/drivers/usb/phy/gpio_vbus.c deleted file mode 100644 index a7d4ac591982..000000000000 --- a/drivers/usb/phy/gpio_vbus.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * gpio-vbus.c - simple GPIO VBUS sensing driver for B peripheral devices - * - * Copyright (c) 2008 Philipp Zabel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -/* - * A simple GPIO VBUS sensing driver for B peripheral only devices - * with internal transceivers. It can control a D+ pullup GPIO and - * a regulator to limit the current drawn from VBUS. - * - * Needs to be loaded before the UDC driver that will use it. - */ -struct gpio_vbus_data { - struct usb_phy phy; - struct device *dev; - struct regulator *vbus_draw; - int vbus_draw_enabled; - unsigned mA; - struct delayed_work work; - int vbus; - int irq; -}; - - -/* - * This driver relies on "both edges" triggering. VBUS has 100 msec to - * stabilize, so the peripheral controller driver may need to cope with - * some bouncing due to current surges (e.g. charging local capacitance) - * and contact chatter. - * - * REVISIT in desperate straits, toggling between rising and falling - * edges might be workable. - */ -#define VBUS_IRQ_FLAGS \ - (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) - - -/* interface to regulator framework */ -static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) -{ - struct regulator *vbus_draw = gpio_vbus->vbus_draw; - int enabled; - - if (!vbus_draw) - return; - - enabled = gpio_vbus->vbus_draw_enabled; - if (mA) { - regulator_set_current_limit(vbus_draw, 0, 1000 * mA); - if (!enabled) { - regulator_enable(vbus_draw); - gpio_vbus->vbus_draw_enabled = 1; - } - } else { - if (enabled) { - regulator_disable(vbus_draw); - gpio_vbus->vbus_draw_enabled = 0; - } - } - gpio_vbus->mA = mA; -} - -static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) -{ - int vbus; - - vbus = gpio_get_value(pdata->gpio_vbus); - if (pdata->gpio_vbus_inverted) - vbus = !vbus; - - return vbus; -} - -static void gpio_vbus_work(struct work_struct *work) -{ - struct gpio_vbus_data *gpio_vbus = - container_of(work, struct gpio_vbus_data, work.work); - struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; - int gpio, status, vbus; - - if (!gpio_vbus->phy.otg->gadget) - return; - - vbus = is_vbus_powered(pdata); - if ((vbus ^ gpio_vbus->vbus) == 0) - return; - gpio_vbus->vbus = vbus; - - /* Peripheral controllers which manage the pullup themselves won't have - * gpio_pullup configured here. If it's configured here, we'll do what - * isp1301_omap::b_peripheral() does and enable the pullup here... although - * that may complicate usb_gadget_{,dis}connect() support. - */ - gpio = pdata->gpio_pullup; - - if (vbus) { - status = USB_EVENT_VBUS; - gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; - gpio_vbus->phy.last_event = status; - usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); - - /* drawing a "unit load" is *always* OK, except for OTG */ - set_vbus_draw(gpio_vbus, 100); - - /* optionally enable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, !pdata->gpio_pullup_inverted); - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); - } else { - /* optionally disable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, pdata->gpio_pullup_inverted); - - set_vbus_draw(gpio_vbus, 0); - - usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); - status = USB_EVENT_NONE; - gpio_vbus->phy.state = OTG_STATE_B_IDLE; - gpio_vbus->phy.last_event = status; - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); - } -} - -/* VBUS change IRQ handler */ -static irqreturn_t gpio_vbus_irq(int irq, void *data) -{ - struct platform_device *pdev = data; - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); - struct usb_otg *otg = gpio_vbus->phy.otg; - - dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", - is_vbus_powered(pdata) ? "supplied" : "inactive", - otg->gadget ? otg->gadget->name : "none"); - - if (otg->gadget) - schedule_delayed_work(&gpio_vbus->work, msecs_to_jiffies(100)); - - return IRQ_HANDLED; -} - -/* OTG transceiver interface */ - -/* bind/unbind the peripheral controller */ -static int gpio_vbus_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct gpio_vbus_data *gpio_vbus; - struct gpio_vbus_mach_info *pdata; - struct platform_device *pdev; - int gpio; - - gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); - pdev = to_platform_device(gpio_vbus->dev); - pdata = gpio_vbus->dev->platform_data; - gpio = pdata->gpio_pullup; - - if (!gadget) { - dev_dbg(&pdev->dev, "unregistering gadget '%s'\n", - otg->gadget->name); - - /* optionally disable D+ pullup */ - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, pdata->gpio_pullup_inverted); - - set_vbus_draw(gpio_vbus, 0); - - usb_gadget_vbus_disconnect(otg->gadget); - otg->phy->state = OTG_STATE_UNDEFINED; - - otg->gadget = NULL; - return 0; - } - - otg->gadget = gadget; - dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name); - - /* initialize connection state */ - gpio_vbus->vbus = 0; /* start with disconnected */ - gpio_vbus_irq(gpio_vbus->irq, pdev); - return 0; -} - -/* effective for B devices, ignored for A-peripheral */ -static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) -{ - struct gpio_vbus_data *gpio_vbus; - - gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - - if (phy->state == OTG_STATE_B_PERIPHERAL) - set_vbus_draw(gpio_vbus, mA); - return 0; -} - -/* for non-OTG B devices: set/clear transceiver suspend mode */ -static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) -{ - struct gpio_vbus_data *gpio_vbus; - - gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - - /* draw max 0 mA from vbus in suspend mode; or the previously - * recorded amount of current if not suspended - * - * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA - * if they're wake-enabled ... we don't handle that yet. - */ - return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); -} - -/* platform driver interface */ - -static int __init gpio_vbus_probe(struct platform_device *pdev) -{ - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - struct gpio_vbus_data *gpio_vbus; - struct resource *res; - int err, gpio, irq; - unsigned long irqflags; - - if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) - return -EINVAL; - gpio = pdata->gpio_vbus; - - gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); - if (!gpio_vbus) - return -ENOMEM; - - gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!gpio_vbus->phy.otg) { - kfree(gpio_vbus); - return -ENOMEM; - } - - platform_set_drvdata(pdev, gpio_vbus); - gpio_vbus->dev = &pdev->dev; - gpio_vbus->phy.label = "gpio-vbus"; - gpio_vbus->phy.set_power = gpio_vbus_set_power; - gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; - gpio_vbus->phy.state = OTG_STATE_UNDEFINED; - - gpio_vbus->phy.otg->phy = &gpio_vbus->phy; - gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; - - err = gpio_request(gpio, "vbus_detect"); - if (err) { - dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", - gpio, err); - goto err_gpio; - } - gpio_direction_input(gpio); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) { - irq = res->start; - irqflags = (res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; - } else { - irq = gpio_to_irq(gpio); - irqflags = VBUS_IRQ_FLAGS; - } - - gpio_vbus->irq = irq; - - /* if data line pullup is in use, initialize it to "not pulling up" */ - gpio = pdata->gpio_pullup; - if (gpio_is_valid(gpio)) { - err = gpio_request(gpio, "udc_pullup"); - if (err) { - dev_err(&pdev->dev, - "can't request pullup gpio %d, err: %d\n", - gpio, err); - gpio_free(pdata->gpio_vbus); - goto err_gpio; - } - gpio_direction_output(gpio, pdata->gpio_pullup_inverted); - } - - err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); - if (err) { - dev_err(&pdev->dev, "can't request irq %i, err: %d\n", - irq, err); - goto err_irq; - } - - ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); - - INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); - - gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); - if (IS_ERR(gpio_vbus->vbus_draw)) { - dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", - PTR_ERR(gpio_vbus->vbus_draw)); - gpio_vbus->vbus_draw = NULL; - } - - /* only active when a gadget is registered */ - err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); - goto err_otg; - } - - device_init_wakeup(&pdev->dev, pdata->wakeup); - - return 0; -err_otg: - regulator_put(gpio_vbus->vbus_draw); - free_irq(irq, pdev); -err_irq: - if (gpio_is_valid(pdata->gpio_pullup)) - gpio_free(pdata->gpio_pullup); - gpio_free(pdata->gpio_vbus); -err_gpio: - platform_set_drvdata(pdev, NULL); - kfree(gpio_vbus->phy.otg); - kfree(gpio_vbus); - return err; -} - -static int __exit gpio_vbus_remove(struct platform_device *pdev) -{ - struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); - struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; - int gpio = pdata->gpio_vbus; - - device_init_wakeup(&pdev->dev, 0); - cancel_delayed_work_sync(&gpio_vbus->work); - regulator_put(gpio_vbus->vbus_draw); - - usb_remove_phy(&gpio_vbus->phy); - - free_irq(gpio_vbus->irq, pdev); - if (gpio_is_valid(pdata->gpio_pullup)) - gpio_free(pdata->gpio_pullup); - gpio_free(gpio); - platform_set_drvdata(pdev, NULL); - kfree(gpio_vbus->phy.otg); - kfree(gpio_vbus); - - return 0; -} - -#ifdef CONFIG_PM -static int gpio_vbus_pm_suspend(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static int gpio_vbus_pm_resume(struct device *dev) -{ - struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(gpio_vbus->irq); - - return 0; -} - -static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { - .suspend = gpio_vbus_pm_suspend, - .resume = gpio_vbus_pm_resume, -}; -#endif - -/* NOTE: the gpio-vbus device may *NOT* be hotplugged */ - -MODULE_ALIAS("platform:gpio-vbus"); - -static struct platform_driver gpio_vbus_driver = { - .driver = { - .name = "gpio-vbus", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &gpio_vbus_dev_pm_ops, -#endif - }, - .remove = __exit_p(gpio_vbus_remove), -}; - -module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe); - -MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); -MODULE_AUTHOR("Philipp Zabel"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/isp1301.c b/drivers/usb/phy/isp1301.c deleted file mode 100644 index 18dbf7e37607..000000000000 --- a/drivers/usb/phy/isp1301.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * NXP ISP1301 USB transceiver driver - * - * Copyright (C) 2012 Roland Stigge - * - * Author: Roland Stigge - * - * 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 - -#define DRV_NAME "isp1301" - -static const struct i2c_device_id isp1301_id[] = { - { "isp1301", 0 }, - { } -}; - -static struct i2c_client *isp1301_i2c_client; - -static int isp1301_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) -{ - isp1301_i2c_client = client; - return 0; -} - -static int isp1301_remove(struct i2c_client *client) -{ - return 0; -} - -static struct i2c_driver isp1301_driver = { - .driver = { - .name = DRV_NAME, - }, - .probe = isp1301_probe, - .remove = isp1301_remove, - .id_table = isp1301_id, -}; - -module_i2c_driver(isp1301_driver); - -static int match(struct device *dev, void *data) -{ - struct device_node *node = (struct device_node *)data; - return (dev->of_node == node) && - (dev->driver == &isp1301_driver.driver); -} - -struct i2c_client *isp1301_get_client(struct device_node *node) -{ - if (node) { /* reference of ISP1301 I2C node via DT */ - struct device *dev = bus_find_device(&i2c_bus_type, NULL, - node, match); - if (!dev) - return NULL; - return to_i2c_client(dev); - } else { /* non-DT: only one ISP1301 chip supported */ - return isp1301_i2c_client; - } -} -EXPORT_SYMBOL_GPL(isp1301_get_client); - -MODULE_AUTHOR("Roland Stigge "); -MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/isp1301_omap.c b/drivers/usb/phy/isp1301_omap.c deleted file mode 100644 index 8fe0c3b95261..000000000000 --- a/drivers/usb/phy/isp1301_omap.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller - * - * Copyright (C) 2004 Texas Instruments - * Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#ifndef DEBUG -#undef VERBOSE -#endif - - -#define DRIVER_VERSION "24 August 2004" -#define DRIVER_NAME (isp1301_driver.driver.name) - -MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); -MODULE_LICENSE("GPL"); - -struct isp1301 { - struct usb_phy phy; - struct i2c_client *client; - void (*i2c_release)(struct device *dev); - - int irq_type; - - u32 last_otg_ctrl; - unsigned working:1; - - struct timer_list timer; - - /* use keventd context to change the state for us */ - struct work_struct work; - - unsigned long todo; -# define WORK_UPDATE_ISP 0 /* update ISP from OTG */ -# define WORK_UPDATE_OTG 1 /* update OTG from ISP */ -# define WORK_HOST_RESUME 4 /* resume host */ -# define WORK_TIMER 6 /* timer fired */ -# define WORK_STOP 7 /* don't resubmit */ -}; - - -/* bits in OTG_CTRL */ - -#define OTG_XCEIV_OUTPUTS \ - (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) -#define OTG_XCEIV_INPUTS \ - (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID) -#define OTG_CTRL_BITS \ - (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|OTG_B_HNPEN|OTG_BUSDROP) - /* and OTG_PULLUP is sometimes written */ - -#define OTG_CTRL_MASK (OTG_DRIVER_SEL| \ - OTG_XCEIV_OUTPUTS|OTG_XCEIV_INPUTS| \ - OTG_CTRL_BITS) - - -/*-------------------------------------------------------------------------*/ - -/* board-specific PM hooks */ - -#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) - -#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) - -#include - -#else - -static inline int tps65010_set_vbus_draw(unsigned mA) -{ - pr_debug("tps65010: draw %d mA (STUB)\n", mA); - return 0; -} - -#endif - -static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) -{ - int status = tps65010_set_vbus_draw(mA); - if (status < 0) - pr_debug(" VBUS %d mA error %d\n", mA, status); -} - -#else - -static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) -{ - /* H4 controls this by DIP switch S2.4; no soft control. - * ON means the charger is always enabled. Leave it OFF - * unless the OTG port is used only in B-peripheral mode. - */ -} - -#endif - -static void enable_vbus_source(struct isp1301 *isp) -{ - /* this board won't supply more than 8mA vbus power. - * some boards can switch a 100ma "unit load" (or more). - */ -} - - -/* products will deliver OTG messages with LEDs, GUI, etc */ -static inline void notresponding(struct isp1301 *isp) -{ - printk(KERN_NOTICE "OTG device not responding.\n"); -} - - -/*-------------------------------------------------------------------------*/ - -static struct i2c_driver isp1301_driver; - -/* smbus apis are used for portability */ - -static inline u8 -isp1301_get_u8(struct isp1301 *isp, u8 reg) -{ - return i2c_smbus_read_byte_data(isp->client, reg + 0); -} - -static inline int -isp1301_get_u16(struct isp1301 *isp, u8 reg) -{ - return i2c_smbus_read_word_data(isp->client, reg); -} - -static inline int -isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) -{ - return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); -} - -static inline int -isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) -{ - return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); -} - -/*-------------------------------------------------------------------------*/ - -/* identification */ -#define ISP1301_VENDOR_ID 0x00 /* u16 read */ -#define ISP1301_PRODUCT_ID 0x02 /* u16 read */ -#define ISP1301_BCD_DEVICE 0x14 /* u16 read */ - -#define I2C_VENDOR_ID_PHILIPS 0x04cc -#define I2C_PRODUCT_ID_PHILIPS_1301 0x1301 - -/* operational registers */ -#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ -# define MC1_SPEED (1 << 0) -# define MC1_SUSPEND (1 << 1) -# define MC1_DAT_SE0 (1 << 2) -# define MC1_TRANSPARENT (1 << 3) -# define MC1_BDIS_ACON_EN (1 << 4) -# define MC1_OE_INT_EN (1 << 5) -# define MC1_UART_EN (1 << 6) -# define MC1_MASK 0x7f -#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ -# define MC2_GLOBAL_PWR_DN (1 << 0) -# define MC2_SPD_SUSP_CTRL (1 << 1) -# define MC2_BI_DI (1 << 2) -# define MC2_TRANSP_BDIR0 (1 << 3) -# define MC2_TRANSP_BDIR1 (1 << 4) -# define MC2_AUDIO_EN (1 << 5) -# define MC2_PSW_EN (1 << 6) -# define MC2_EN2V7 (1 << 7) -#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ -# define OTG1_DP_PULLUP (1 << 0) -# define OTG1_DM_PULLUP (1 << 1) -# define OTG1_DP_PULLDOWN (1 << 2) -# define OTG1_DM_PULLDOWN (1 << 3) -# define OTG1_ID_PULLDOWN (1 << 4) -# define OTG1_VBUS_DRV (1 << 5) -# define OTG1_VBUS_DISCHRG (1 << 6) -# define OTG1_VBUS_CHRG (1 << 7) -#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ -# define OTG_B_SESS_END (1 << 6) -# define OTG_B_SESS_VLD (1 << 7) - -#define ISP1301_INTERRUPT_SOURCE 0x08 /* u8 read */ -#define ISP1301_INTERRUPT_LATCH 0x0A /* u8 read, set, +1 clear */ - -#define ISP1301_INTERRUPT_FALLING 0x0C /* u8 read, set, +1 clear */ -#define ISP1301_INTERRUPT_RISING 0x0E /* u8 read, set, +1 clear */ - -/* same bitfields in all interrupt registers */ -# define INTR_VBUS_VLD (1 << 0) -# define INTR_SESS_VLD (1 << 1) -# define INTR_DP_HI (1 << 2) -# define INTR_ID_GND (1 << 3) -# define INTR_DM_HI (1 << 4) -# define INTR_ID_FLOAT (1 << 5) -# define INTR_BDIS_ACON (1 << 6) -# define INTR_CR_INT (1 << 7) - -/*-------------------------------------------------------------------------*/ - -static inline const char *state_name(struct isp1301 *isp) -{ - return usb_otg_state_string(isp->phy.state); -} - -/*-------------------------------------------------------------------------*/ - -/* NOTE: some of this ISP1301 setup is specific to H2 boards; - * not everything is guarded by board-specific checks, or even using - * omap_usb_config data to deduce MC1_DAT_SE0 and MC2_BI_DI. - * - * ALSO: this currently doesn't use ISP1301 low-power modes - * while OTG is running. - */ - -static void power_down(struct isp1301 *isp) -{ - isp->phy.state = OTG_STATE_UNDEFINED; - - // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); - - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); -} - -static void power_up(struct isp1301 *isp) -{ - // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); - - /* do this only when cpu is driving transceiver, - * so host won't see a low speed device... - */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); -} - -#define NO_HOST_SUSPEND - -static int host_suspend(struct isp1301 *isp) -{ -#ifdef NO_HOST_SUSPEND - return 0; -#else - struct device *dev; - - if (!isp->phy.otg->host) - return -ENODEV; - - /* Currently ASSUMES only the OTG port matters; - * other ports could be active... - */ - dev = isp->phy.otg->host->controller; - return dev->driver->suspend(dev, 3, 0); -#endif -} - -static int host_resume(struct isp1301 *isp) -{ -#ifdef NO_HOST_SUSPEND - return 0; -#else - struct device *dev; - - if (!isp->phy.otg->host) - return -ENODEV; - - dev = isp->phy.otg->host->controller; - return dev->driver->resume(dev, 0); -#endif -} - -static int gadget_suspend(struct isp1301 *isp) -{ - isp->phy.otg->gadget->b_hnp_enable = 0; - isp->phy.otg->gadget->a_hnp_support = 0; - isp->phy.otg->gadget->a_alt_hnp_support = 0; - return usb_gadget_vbus_disconnect(isp->phy.otg->gadget); -} - -/*-------------------------------------------------------------------------*/ - -#define TIMER_MINUTES 10 -#define TIMER_JIFFIES (TIMER_MINUTES * 60 * HZ) - -/* Almost all our I2C messaging comes from a work queue's task context. - * NOTE: guaranteeing certain response times might mean we shouldn't - * share keventd's work queue; a realtime task might be safest. - */ -static void isp1301_defer_work(struct isp1301 *isp, int work) -{ - int status; - - if (isp && !test_and_set_bit(work, &isp->todo)) { - (void) get_device(&isp->client->dev); - status = schedule_work(&isp->work); - if (!status && !isp->working) - dev_vdbg(&isp->client->dev, - "work item %d may be lost\n", work); - } -} - -/* called from irq handlers */ -static void a_idle(struct isp1301 *isp, const char *tag) -{ - u32 l; - - if (isp->phy.state == OTG_STATE_A_IDLE) - return; - - isp->phy.otg->default_a = 1; - if (isp->phy.otg->host) { - isp->phy.otg->host->is_b_host = 0; - host_suspend(isp); - } - if (isp->phy.otg->gadget) { - isp->phy.otg->gadget->is_a_peripheral = 1; - gadget_suspend(isp); - } - isp->phy.state = OTG_STATE_A_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; - pr_debug(" --> %s/%s\n", state_name(isp), tag); -} - -/* called from irq handlers */ -static void b_idle(struct isp1301 *isp, const char *tag) -{ - u32 l; - - if (isp->phy.state == OTG_STATE_B_IDLE) - return; - - isp->phy.otg->default_a = 0; - if (isp->phy.otg->host) { - isp->phy.otg->host->is_b_host = 1; - host_suspend(isp); - } - if (isp->phy.otg->gadget) { - isp->phy.otg->gadget->is_a_peripheral = 0; - gadget_suspend(isp); - } - isp->phy.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; - pr_debug(" --> %s/%s\n", state_name(isp), tag); -} - -static void -dump_regs(struct isp1301 *isp, const char *label) -{ -#ifdef DEBUG - u8 ctrl = isp1301_get_u8(isp, ISP1301_OTG_CONTROL_1); - u8 status = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); - - pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", - omap_readl(OTG_CTRL), label, state_name(isp), - ctrl, status, src); - /* mode control and irq enables don't change much */ -#endif -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_USB_OTG - -/* - * The OMAP OTG controller handles most of the OTG state transitions. - * - * We translate isp1301 outputs (mostly voltage comparator status) into - * OTG inputs; OTG outputs (mostly pullup/pulldown controls) and HNP state - * flags into isp1301 inputs ... and infer state transitions. - */ - -#ifdef VERBOSE - -static void check_state(struct isp1301 *isp, const char *tag) -{ - enum usb_otg_state state = OTG_STATE_UNDEFINED; - u8 fsm = omap_readw(OTG_TEST) & 0x0ff; - unsigned extra = 0; - - switch (fsm) { - - /* default-b */ - case 0x0: - state = OTG_STATE_B_IDLE; - break; - case 0x3: - case 0x7: - extra = 1; - case 0x1: - state = OTG_STATE_B_PERIPHERAL; - break; - case 0x11: - state = OTG_STATE_B_SRP_INIT; - break; - - /* extra dual-role default-b states */ - case 0x12: - case 0x13: - case 0x16: - extra = 1; - case 0x17: - state = OTG_STATE_B_WAIT_ACON; - break; - case 0x34: - state = OTG_STATE_B_HOST; - break; - - /* default-a */ - case 0x36: - state = OTG_STATE_A_IDLE; - break; - case 0x3c: - state = OTG_STATE_A_WAIT_VFALL; - break; - case 0x7d: - state = OTG_STATE_A_VBUS_ERR; - break; - case 0x9e: - case 0x9f: - extra = 1; - case 0x89: - state = OTG_STATE_A_PERIPHERAL; - break; - case 0xb7: - state = OTG_STATE_A_WAIT_VRISE; - break; - case 0xb8: - state = OTG_STATE_A_WAIT_BCON; - break; - case 0xb9: - state = OTG_STATE_A_HOST; - break; - case 0xba: - state = OTG_STATE_A_SUSPEND; - break; - default: - break; - } - if (isp->phy.state == state && !extra) - return; - pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - usb_otg_state_string(state), fsm, state_name(isp), - omap_readl(OTG_CTRL)); -} - -#else - -static inline void check_state(struct isp1301 *isp, const char *tag) { } - -#endif - -/* outputs from ISP1301_INTERRUPT_SOURCE */ -static void update_otg1(struct isp1301 *isp, u8 int_src) -{ - u32 otg_ctrl; - - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); - - if (int_src & INTR_SESS_VLD) - otg_ctrl |= OTG_ASESSVLD; - else if (isp->phy.state == OTG_STATE_A_WAIT_VFALL) { - a_idle(isp, "vfall"); - otg_ctrl &= ~OTG_CTRL_BITS; - } - if (int_src & INTR_VBUS_VLD) - otg_ctrl |= OTG_VBUSVLD; - if (int_src & INTR_ID_GND) { /* default-A */ - if (isp->phy.state == OTG_STATE_B_IDLE - || isp->phy.state - == OTG_STATE_UNDEFINED) { - a_idle(isp, "init"); - return; - } - } else { /* default-B */ - otg_ctrl |= OTG_ID; - if (isp->phy.state == OTG_STATE_A_IDLE - || isp->phy.state == OTG_STATE_UNDEFINED) { - b_idle(isp, "init"); - return; - } - } - omap_writel(otg_ctrl, OTG_CTRL); -} - -/* outputs from ISP1301_OTG_STATUS */ -static void update_otg2(struct isp1301 *isp, u8 otg_status) -{ - u32 otg_ctrl; - - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); - if (otg_status & OTG_B_SESS_VLD) - otg_ctrl |= OTG_BSESSVLD; - else if (otg_status & OTG_B_SESS_END) - otg_ctrl |= OTG_BSESSEND; - omap_writel(otg_ctrl, OTG_CTRL); -} - -/* inputs going to ISP1301 */ -static void otg_update_isp(struct isp1301 *isp) -{ - u32 otg_ctrl, otg_change; - u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; - - otg_ctrl = omap_readl(OTG_CTRL); - otg_change = otg_ctrl ^ isp->last_otg_ctrl; - isp->last_otg_ctrl = otg_ctrl; - otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; - - switch (isp->phy.state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_SRP_INIT: - if (!(otg_ctrl & OTG_PULLUP)) { - // if (otg_ctrl & OTG_B_HNPEN) { - if (isp->phy.otg->gadget->b_hnp_enable) { - isp->phy.state = OTG_STATE_B_WAIT_ACON; - pr_debug(" --> b_wait_acon\n"); - } - goto pulldown; - } -pullup: - set |= OTG1_DP_PULLUP; - clr |= OTG1_DP_PULLDOWN; - break; - case OTG_STATE_A_SUSPEND: - case OTG_STATE_A_PERIPHERAL: - if (otg_ctrl & OTG_PULLUP) - goto pullup; - /* FALLTHROUGH */ - // case OTG_STATE_B_WAIT_ACON: - default: -pulldown: - set |= OTG1_DP_PULLDOWN; - clr |= OTG1_DP_PULLUP; - break; - } - -# define toggle(OTG,ISP) do { \ - if (otg_ctrl & OTG) set |= ISP; \ - else clr |= ISP; \ - } while (0) - - if (!(isp->phy.otg->host)) - otg_ctrl &= ~OTG_DRV_VBUS; - - switch (isp->phy.state) { - case OTG_STATE_A_SUSPEND: - if (otg_ctrl & OTG_DRV_VBUS) { - set |= OTG1_VBUS_DRV; - break; - } - /* HNP failed for some reason (A_AIDL_BDIS timeout) */ - notresponding(isp); - - /* FALLTHROUGH */ - case OTG_STATE_A_VBUS_ERR: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - pr_debug(" --> a_wait_vfall\n"); - /* FALLTHROUGH */ - case OTG_STATE_A_WAIT_VFALL: - /* FIXME usbcore thinks port power is still on ... */ - clr |= OTG1_VBUS_DRV; - break; - case OTG_STATE_A_IDLE: - if (otg_ctrl & OTG_DRV_VBUS) { - isp->phy.state = OTG_STATE_A_WAIT_VRISE; - pr_debug(" --> a_wait_vrise\n"); - } - /* FALLTHROUGH */ - default: - toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); - } - - toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); - toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); - -# undef toggle - - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); - - /* HNP switch to host or peripheral; and SRP */ - if (otg_change & OTG_PULLUP) { - u32 l; - - switch (isp->phy.state) { - case OTG_STATE_B_IDLE: - if (clr & OTG1_DP_PULLUP) - break; - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - break; - case OTG_STATE_A_SUSPEND: - if (clr & OTG1_DP_PULLUP) - break; - isp->phy.state = OTG_STATE_A_PERIPHERAL; - pr_debug(" --> a_peripheral\n"); - break; - default: - break; - } - l = omap_readl(OTG_CTRL); - l |= OTG_PULLUP; - omap_writel(l, OTG_CTRL); - } - - check_state(isp, __func__); - dump_regs(isp, "otg->isp1301"); -} - -static irqreturn_t omap_otg_irq(int irq, void *_isp) -{ - u16 otg_irq = omap_readw(OTG_IRQ_SRC); - u32 otg_ctrl; - int ret = IRQ_NONE; - struct isp1301 *isp = _isp; - struct usb_otg *otg = isp->phy.otg; - - /* update ISP1301 transceiver from OTG controller */ - if (otg_irq & OPRT_CHG) { - omap_writew(OPRT_CHG, OTG_IRQ_SRC); - isp1301_defer_work(isp, WORK_UPDATE_ISP); - ret = IRQ_HANDLED; - - /* SRP to become b_peripheral failed */ - } else if (otg_irq & B_SRP_TMROUT) { - pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); - notresponding(isp); - - /* gadget drivers that care should monitor all kinds of - * remote wakeup (SRP, normal) using their own timer - * to give "check cable and A-device" messages. - */ - if (isp->phy.state == OTG_STATE_B_SRP_INIT) - b_idle(isp, "srp_timeout"); - - omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* HNP to become b_host failed */ - } else if (otg_irq & B_HNP_FAIL) { - pr_debug("otg: %s B_HNP_FAIL, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); - notresponding(isp); - - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - - /* subset of b_peripheral()... */ - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - - omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* detect SRP from B-device ... */ - } else if (otg_irq & A_SRP_DETECT) { - pr_debug("otg: %s SRP_DETECT, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); - - isp1301_defer_work(isp, WORK_UPDATE_OTG); - switch (isp->phy.state) { - case OTG_STATE_A_IDLE: - if (!otg->host) - break; - isp1301_defer_work(isp, WORK_HOST_RESUME); - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_A_BUSREQ; - otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) - & ~OTG_XCEIV_INPUTS - & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - break; - default: - break; - } - - omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) - * we don't track them separately - */ - } else if (otg_irq & A_REQ_TMROUT) { - otg_ctrl = omap_readl(OTG_CTRL); - pr_info("otg: BCON_TMOUT from %s, %06x\n", - state_name(isp), otg_ctrl); - notresponding(isp); - - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - - omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* A-supplied voltage fell too low; overcurrent */ - } else if (otg_irq & A_VBUS_ERR) { - otg_ctrl = omap_readl(OTG_CTRL); - printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", - state_name(isp), otg_irq, otg_ctrl); - - otg_ctrl |= OTG_BUSDROP; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_VBUS_ERR; - - omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - /* switch driver; the transceiver code activates it, - * ungating the udc clock or resuming OHCI. - */ - } else if (otg_irq & DRIVER_SWITCH) { - int kick = 0; - - otg_ctrl = omap_readl(OTG_CTRL); - printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", - state_name(isp), - (otg_ctrl & OTG_DRIVER_SEL) - ? "gadget" : "host", - otg_ctrl); - isp1301_defer_work(isp, WORK_UPDATE_ISP); - - /* role is peripheral */ - if (otg_ctrl & OTG_DRIVER_SEL) { - switch (isp->phy.state) { - case OTG_STATE_A_IDLE: - b_idle(isp, __func__); - break; - default: - break; - } - isp1301_defer_work(isp, WORK_UPDATE_ISP); - - /* role is host */ - } else { - if (!(otg_ctrl & OTG_ID)) { - otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); - } - - if (otg->host) { - switch (isp->phy.state) { - case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; - pr_debug(" --> b_host\n"); - kick = 1; - break; - case OTG_STATE_A_WAIT_BCON: - isp->phy.state = OTG_STATE_A_HOST; - pr_debug(" --> a_host\n"); - break; - case OTG_STATE_A_PERIPHERAL: - isp->phy.state = OTG_STATE_A_WAIT_BCON; - pr_debug(" --> a_wait_bcon\n"); - break; - default: - break; - } - isp1301_defer_work(isp, WORK_HOST_RESUME); - } - } - - omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); - ret = IRQ_HANDLED; - - if (kick) - usb_bus_start_enum(otg->host, otg->host->otg_port); - } - - check_state(isp, __func__); - return ret; -} - -static struct platform_device *otg_dev; - -static int isp1301_otg_init(struct isp1301 *isp) -{ - u32 l; - - if (!otg_dev) - return -ENODEV; - - dump_regs(isp, __func__); - /* some of these values are board-specific... */ - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN - /* for B-device: */ - | SRP_GPDATA /* 9msec Bdev D+ pulse */ - | SRP_GPDVBUS /* discharge after VBUS pulse */ - // | (3 << 24) /* 2msec VBUS pulse */ - /* for A-device: */ - | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */ - | SRP_DPW /* detect 167+ns SRP pulses */ - | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ - ; - omap_writel(l, OTG_SYSCON_2); - - update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); - update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); - - check_state(isp, __func__); - pr_debug("otg: %s, %s %06x\n", - state_name(isp), __func__, omap_readl(OTG_CTRL)); - - omap_writew(DRIVER_SWITCH | OPRT_CHG - | B_SRP_TMROUT | B_HNP_FAIL - | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); - - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN; - omap_writel(l, OTG_SYSCON_2); - - return 0; -} - -static int otg_probe(struct platform_device *dev) -{ - // struct omap_usb_config *config = dev->platform_data; - - otg_dev = dev; - return 0; -} - -static int otg_remove(struct platform_device *dev) -{ - otg_dev = NULL; - return 0; -} - -static struct platform_driver omap_otg_driver = { - .probe = otg_probe, - .remove = otg_remove, - .driver = { - .owner = THIS_MODULE, - .name = "omap_otg", - }, -}; - -static int otg_bind(struct isp1301 *isp) -{ - int status; - - if (otg_dev) - return -EBUSY; - - status = platform_driver_register(&omap_otg_driver); - if (status < 0) - return status; - - if (otg_dev) - status = request_irq(otg_dev->resource[1].start, omap_otg_irq, - 0, DRIVER_NAME, isp); - else - status = -ENODEV; - - if (status < 0) - platform_driver_unregister(&omap_otg_driver); - return status; -} - -static void otg_unbind(struct isp1301 *isp) -{ - if (!otg_dev) - return; - free_irq(otg_dev->resource[1].start, isp); -} - -#else - -/* OTG controller isn't clocked */ - -#endif /* CONFIG_USB_OTG */ - -/*-------------------------------------------------------------------------*/ - -static void b_peripheral(struct isp1301 *isp) -{ - u32 l; - - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - - usb_gadget_vbus_connect(isp->phy.otg->gadget); - -#ifdef CONFIG_USB_OTG - enable_vbus_draw(isp, 8); - otg_update_isp(isp); -#else - enable_vbus_draw(isp, 100); - /* UDC driver just set OTG_BSESSVLD */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); - isp->phy.state = OTG_STATE_B_PERIPHERAL; - pr_debug(" --> b_peripheral\n"); - dump_regs(isp, "2periph"); -#endif -} - -static void isp_update_otg(struct isp1301 *isp, u8 stat) -{ - struct usb_otg *otg = isp->phy.otg; - u8 isp_stat, isp_bstat; - enum usb_otg_state state = isp->phy.state; - - if (stat & INTR_BDIS_ACON) - pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); - - /* start certain state transitions right away */ - isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); - if (isp_stat & INTR_ID_GND) { - if (otg->default_a) { - switch (state) { - case OTG_STATE_B_IDLE: - a_idle(isp, "idle"); - /* FALLTHROUGH */ - case OTG_STATE_A_IDLE: - enable_vbus_source(isp); - /* FALLTHROUGH */ - case OTG_STATE_A_WAIT_VRISE: - /* we skip over OTG_STATE_A_WAIT_BCON, since - * the HC will transition to A_HOST (or - * A_SUSPEND!) without our noticing except - * when HNP is used. - */ - if (isp_stat & INTR_VBUS_VLD) - isp->phy.state = OTG_STATE_A_HOST; - break; - case OTG_STATE_A_WAIT_VFALL: - if (!(isp_stat & INTR_SESS_VLD)) - a_idle(isp, "vfell"); - break; - default: - if (!(isp_stat & INTR_VBUS_VLD)) - isp->phy.state = OTG_STATE_A_VBUS_ERR; - break; - } - isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - } else { - switch (state) { - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_HOST: - case OTG_STATE_B_WAIT_ACON: - usb_gadget_vbus_disconnect(otg->gadget); - break; - default: - break; - } - if (state != OTG_STATE_A_IDLE) - a_idle(isp, "id"); - if (otg->host && state == OTG_STATE_A_IDLE) - isp1301_defer_work(isp, WORK_HOST_RESUME); - isp_bstat = 0; - } - } else { - u32 l; - - /* if user unplugged mini-A end of cable, - * don't bypass A_WAIT_VFALL. - */ - if (otg->default_a) { - switch (state) { - default: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; - break; - case OTG_STATE_A_WAIT_VFALL: - state = OTG_STATE_A_IDLE; - /* khubd may take a while to notice and - * handle this disconnect, so don't go - * to B_IDLE quite yet. - */ - break; - case OTG_STATE_A_IDLE: - host_suspend(isp); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_BDIS_ACON_EN); - isp->phy.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~OTG_CTRL_BITS; - omap_writel(l, OTG_CTRL); - break; - case OTG_STATE_B_IDLE: - break; - } - } - isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - - switch (isp->phy.state) { - case OTG_STATE_B_PERIPHERAL: - case OTG_STATE_B_WAIT_ACON: - case OTG_STATE_B_HOST: - if (likely(isp_bstat & OTG_B_SESS_VLD)) - break; - enable_vbus_draw(isp, 0); -#ifndef CONFIG_USB_OTG - /* UDC driver will clear OTG_BSESSVLD */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DP_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DP_PULLUP); - dump_regs(isp, __func__); -#endif - /* FALLTHROUGH */ - case OTG_STATE_B_SRP_INIT: - b_idle(isp, __func__); - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - /* FALLTHROUGH */ - case OTG_STATE_B_IDLE: - if (otg->gadget && (isp_bstat & OTG_B_SESS_VLD)) { -#ifdef CONFIG_USB_OTG - update_otg1(isp, isp_stat); - update_otg2(isp, isp_bstat); -#endif - b_peripheral(isp); - } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) - isp_bstat |= OTG_B_SESS_END; - break; - case OTG_STATE_A_WAIT_VFALL: - break; - default: - pr_debug("otg: unsupported b-device %s\n", - state_name(isp)); - break; - } - } - - if (state != isp->phy.state) - pr_debug(" isp, %s -> %s\n", - usb_otg_state_string(state), state_name(isp)); - -#ifdef CONFIG_USB_OTG - /* update the OTG controller state to match the isp1301; may - * trigger OPRT_CHG irqs for changes going to the isp1301. - */ - update_otg1(isp, isp_stat); - update_otg2(isp, isp_bstat); - check_state(isp, __func__); -#endif - - dump_regs(isp, "isp1301->otg"); -} - -/*-------------------------------------------------------------------------*/ - -static u8 isp1301_clear_latch(struct isp1301 *isp) -{ - u8 latch = isp1301_get_u8(isp, ISP1301_INTERRUPT_LATCH); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, latch); - return latch; -} - -static void -isp1301_work(struct work_struct *work) -{ - struct isp1301 *isp = container_of(work, struct isp1301, work); - int stop; - - /* implicit lock: we're the only task using this device */ - isp->working = 1; - do { - stop = test_bit(WORK_STOP, &isp->todo); - -#ifdef CONFIG_USB_OTG - /* transfer state from otg engine to isp1301 */ - if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { - otg_update_isp(isp); - put_device(&isp->client->dev); - } -#endif - /* transfer state from isp1301 to otg engine */ - if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { - u8 stat = isp1301_clear_latch(isp); - - isp_update_otg(isp, stat); - put_device(&isp->client->dev); - } - - if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { - u32 otg_ctrl; - - /* - * skip A_WAIT_VRISE; hc transitions invisibly - * skip A_WAIT_BCON; same. - */ - switch (isp->phy.state) { - case OTG_STATE_A_WAIT_BCON: - case OTG_STATE_A_WAIT_VRISE: - isp->phy.state = OTG_STATE_A_HOST; - pr_debug(" --> a_host\n"); - otg_ctrl = omap_readl(OTG_CTRL); - otg_ctrl |= OTG_A_BUSREQ; - otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) - & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - break; - case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; - pr_debug(" --> b_host (acon)\n"); - break; - case OTG_STATE_B_HOST: - case OTG_STATE_B_IDLE: - case OTG_STATE_A_IDLE: - break; - default: - pr_debug(" host resume in %s\n", - state_name(isp)); - } - host_resume(isp); - // mdelay(10); - put_device(&isp->client->dev); - } - - if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { -#ifdef VERBOSE - dump_regs(isp, "timer"); - if (!stop) - mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); -#endif - put_device(&isp->client->dev); - } - - if (isp->todo) - dev_vdbg(&isp->client->dev, - "work done, todo = 0x%lx\n", - isp->todo); - if (stop) { - dev_dbg(&isp->client->dev, "stop\n"); - break; - } - } while (isp->todo); - isp->working = 0; -} - -static irqreturn_t isp1301_irq(int irq, void *isp) -{ - isp1301_defer_work(isp, WORK_UPDATE_OTG); - return IRQ_HANDLED; -} - -static void isp1301_timer(unsigned long _isp) -{ - isp1301_defer_work((void *)_isp, WORK_TIMER); -} - -/*-------------------------------------------------------------------------*/ - -static void isp1301_release(struct device *dev) -{ - struct isp1301 *isp; - - isp = dev_get_drvdata(dev); - - /* FIXME -- not with a "new style" driver, it doesn't!! */ - - /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ - if (isp->i2c_release) - isp->i2c_release(dev); - kfree(isp->phy.otg); - kfree (isp); -} - -static struct isp1301 *the_transceiver; - -static int __exit isp1301_remove(struct i2c_client *i2c) -{ - struct isp1301 *isp; - - isp = i2c_get_clientdata(i2c); - - isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - free_irq(i2c->irq, isp); -#ifdef CONFIG_USB_OTG - otg_unbind(isp); -#endif - if (machine_is_omap_h2()) - gpio_free(2); - - isp->timer.data = 0; - set_bit(WORK_STOP, &isp->todo); - del_timer_sync(&isp->timer); - flush_work(&isp->work); - - put_device(&i2c->dev); - the_transceiver = NULL; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* NOTE: three modes are possible here, only one of which - * will be standards-conformant on any given system: - * - * - OTG mode (dual-role), required if there's a Mini-AB connector - * - HOST mode, for when there's one or more A (host) connectors - * - DEVICE mode, for when there's a B/Mini-B (device) connector - * - * As a rule, you won't have an isp1301 chip unless it's there to - * support the OTG mode. Other modes help testing USB controllers - * in isolation from (full) OTG support, or maybe so later board - * revisions can help to support those feature. - */ - -#ifdef CONFIG_USB_OTG - -static int isp1301_otg_enable(struct isp1301 *isp) -{ - power_up(isp); - isp1301_otg_init(isp); - - /* NOTE: since we don't change this, this provides - * a few more interrupts than are strictly needed. - */ - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); - - dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); - - return 0; -} - -#endif - -/* add or disable the host device+driver */ -static int -isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - - if (!otg || isp != the_transceiver) - return -ENODEV; - - if (!host) { - omap_writew(0, OTG_IRQ_EN); - power_down(isp); - otg->host = NULL; - return 0; - } - -#ifdef CONFIG_USB_OTG - otg->host = host; - dev_dbg(&isp->client->dev, "registered host\n"); - host_suspend(isp); - if (otg->gadget) - return isp1301_otg_enable(isp); - return 0; - -#elif !defined(CONFIG_USB_GADGET_OMAP) - // FIXME update its refcount - otg->host = host; - - power_up(isp); - - if (machine_is_omap_h2()) - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); - - dev_info(&isp->client->dev, "A-Host sessions ok\n"); - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_ID_GND); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_ID_GND); - - /* If this has a Mini-AB connector, this mode is highly - * nonstandard ... but can be handy for testing, especially with - * the Mini-A end of an OTG cable. (Or something nonstandard - * like MiniB-to-StandardB, maybe built with a gender mender.) - */ - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); - - dump_regs(isp, __func__); - - return 0; - -#else - dev_dbg(&isp->client->dev, "host sessions not allowed\n"); - return -EINVAL; -#endif - -} - -static int -isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - - if (!otg || isp != the_transceiver) - return -ENODEV; - - if (!gadget) { - omap_writew(0, OTG_IRQ_EN); - if (!otg->default_a) - enable_vbus_draw(isp, 0); - usb_gadget_vbus_disconnect(otg->gadget); - otg->gadget = NULL; - power_down(isp); - return 0; - } - -#ifdef CONFIG_USB_OTG - otg->gadget = gadget; - dev_dbg(&isp->client->dev, "registered gadget\n"); - /* gadget driver may be suspended until vbus_connect () */ - if (otg->host) - return isp1301_otg_enable(isp); - return 0; - -#elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) - otg->gadget = gadget; - // FIXME update its refcount - - { - u32 l; - - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); - l |= OTG_ID; - omap_writel(l, OTG_CTRL); - } - - power_up(isp); - isp->phy.state = OTG_STATE_B_IDLE; - - if (machine_is_omap_h2() || machine_is_omap_h3()) - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); - - isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, - INTR_SESS_VLD); - isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, - INTR_VBUS_VLD); - dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); - dump_regs(isp, __func__); - - /* If this has a Mini-AB connector, this mode is highly - * nonstandard ... but can be handy for testing, so long - * as you don't plug a Mini-A cable into the jack. - */ - if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) - b_peripheral(isp); - - return 0; - -#else - dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); - return -EINVAL; -#endif -} - - -/*-------------------------------------------------------------------------*/ - -static int -isp1301_set_power(struct usb_phy *dev, unsigned mA) -{ - if (!the_transceiver) - return -ENODEV; - if (dev->state == OTG_STATE_B_PERIPHERAL) - enable_vbus_draw(the_transceiver, mA); - return 0; -} - -static int -isp1301_start_srp(struct usb_otg *otg) -{ - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - u32 otg_ctrl; - - if (!otg || isp != the_transceiver - || isp->phy.state != OTG_STATE_B_IDLE) - return -ENODEV; - - otg_ctrl = omap_readl(OTG_CTRL); - if (!(otg_ctrl & OTG_BSESSEND)) - return -EINVAL; - - otg_ctrl |= OTG_B_BUSREQ; - otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_B_SRP_INIT; - - pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), - omap_readl(OTG_CTRL)); -#ifdef CONFIG_USB_OTG - check_state(isp, __func__); -#endif - return 0; -} - -static int -isp1301_start_hnp(struct usb_otg *otg) -{ -#ifdef CONFIG_USB_OTG - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); - u32 l; - - if (!otg || isp != the_transceiver) - return -ENODEV; - if (otg->default_a && (otg->host == NULL || !otg->host->b_hnp_enable)) - return -ENOTCONN; - if (!otg->default_a && (otg->gadget == NULL - || !otg->gadget->b_hnp_enable)) - return -ENOTCONN; - - /* We want hardware to manage most HNP protocol timings. - * So do this part as early as possible... - */ - switch (isp->phy.state) { - case OTG_STATE_B_HOST: - isp->phy.state = OTG_STATE_B_PERIPHERAL; - /* caller will suspend next */ - break; - case OTG_STATE_A_HOST: -#if 0 - /* autoconnect mode avoids irq latency bugs */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_BDIS_ACON_EN); -#endif - /* caller must suspend then clear A_BUSREQ */ - usb_gadget_vbus_connect(otg->gadget); - l = omap_readl(OTG_CTRL); - l |= OTG_A_SETB_HNPEN; - omap_writel(l, OTG_CTRL); - - break; - case OTG_STATE_A_PERIPHERAL: - /* initiated by B-Host suspend */ - break; - default: - return -EILSEQ; - } - pr_debug("otg: HNP %s, %06x ...\n", - state_name(isp), omap_readl(OTG_CTRL)); - check_state(isp, __func__); - return 0; -#else - /* srp-only */ - return -EINVAL; -#endif -} - -/*-------------------------------------------------------------------------*/ - -static int -isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) -{ - int status; - struct isp1301 *isp; - - if (the_transceiver) - return 0; - - isp = kzalloc(sizeof *isp, GFP_KERNEL); - if (!isp) - return 0; - - isp->phy.otg = kzalloc(sizeof *isp->phy.otg, GFP_KERNEL); - if (!isp->phy.otg) { - kfree(isp); - return 0; - } - - INIT_WORK(&isp->work, isp1301_work); - init_timer(&isp->timer); - isp->timer.function = isp1301_timer; - isp->timer.data = (unsigned long) isp; - - i2c_set_clientdata(i2c, isp); - isp->client = i2c; - - /* verify the chip (shouldn't be necessary) */ - status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); - if (status != I2C_VENDOR_ID_PHILIPS) { - dev_dbg(&i2c->dev, "not philips id: %d\n", status); - goto fail; - } - status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); - if (status != I2C_PRODUCT_ID_PHILIPS_1301) { - dev_dbg(&i2c->dev, "not isp1301, %d\n", status); - goto fail; - } - isp->i2c_release = i2c->dev.release; - i2c->dev.release = isp1301_release; - - /* initial development used chiprev 2.00 */ - status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); - dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", - status >> 8, status & 0xff); - - /* make like power-on reset */ - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); - - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); - - isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, - OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); - isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, - ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); - - isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); - isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - -#ifdef CONFIG_USB_OTG - status = otg_bind(isp); - if (status < 0) { - dev_dbg(&i2c->dev, "can't bind OTG\n"); - goto fail; - } -#endif - - if (machine_is_omap_h2()) { - /* full speed signaling by default */ - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, - MC1_SPEED); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, - MC2_SPD_SUSP_CTRL); - - /* IRQ wired at M14 */ - omap_cfg_reg(M14_1510_GPIO2); - if (gpio_request(2, "isp1301") == 0) - gpio_direction_input(2); - isp->irq_type = IRQF_TRIGGER_FALLING; - } - - status = request_irq(i2c->irq, isp1301_irq, - isp->irq_type, DRIVER_NAME, isp); - if (status < 0) { - dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", - i2c->irq, status); - goto fail; - } - - isp->phy.dev = &i2c->dev; - isp->phy.label = DRIVER_NAME; - isp->phy.set_power = isp1301_set_power, - - isp->phy.otg->phy = &isp->phy; - isp->phy.otg->set_host = isp1301_set_host, - isp->phy.otg->set_peripheral = isp1301_set_peripheral, - isp->phy.otg->start_srp = isp1301_start_srp, - isp->phy.otg->start_hnp = isp1301_start_hnp, - - enable_vbus_draw(isp, 0); - power_down(isp); - the_transceiver = isp; - -#ifdef CONFIG_USB_OTG - update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); - update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); -#endif - - dump_regs(isp, __func__); - -#ifdef VERBOSE - mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); - dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); -#endif - - status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); - if (status < 0) - dev_err(&i2c->dev, "can't register transceiver, %d\n", - status); - - return 0; - -fail: - kfree(isp->phy.otg); - kfree(isp); - return -ENODEV; -} - -static const struct i2c_device_id isp1301_id[] = { - { "isp1301_omap", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, isp1301_id); - -static struct i2c_driver isp1301_driver = { - .driver = { - .name = "isp1301_omap", - }, - .probe = isp1301_probe, - .remove = __exit_p(isp1301_remove), - .id_table = isp1301_id, -}; - -/*-------------------------------------------------------------------------*/ - -static int __init isp_init(void) -{ - return i2c_add_driver(&isp1301_driver); -} -subsys_initcall(isp_init); - -static void __exit isp_exit(void) -{ - if (the_transceiver) - usb_remove_phy(&the_transceiver->phy); - i2c_del_driver(&isp1301_driver); -} -module_exit(isp_exit); - diff --git a/drivers/usb/phy/msm_otg.c b/drivers/usb/phy/msm_otg.c deleted file mode 100644 index 749fbf41fb6f..000000000000 --- a/drivers/usb/phy/msm_otg.c +++ /dev/null @@ -1,1762 +0,0 @@ -/* Copyright (c) 2009-2011, 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 -#include -#include -#include - -#include - -#define MSM_USB_BASE (motg->regs) -#define DRIVER_NAME "msm_otg" - -#define ULPI_IO_TIMEOUT_USEC (10 * 1000) - -#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ -#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ -#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */ -#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */ -#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */ -#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ -#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ -#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ - -static struct regulator *hsusb_3p3; -static struct regulator *hsusb_1p8; -static struct regulator *hsusb_vddcx; - -static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) -{ - int ret = 0; - - if (init) { - hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); - if (IS_ERR(hsusb_vddcx)) { - dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); - return PTR_ERR(hsusb_vddcx); - } - - ret = regulator_set_voltage(hsusb_vddcx, - USB_PHY_VDD_DIG_VOL_MIN, - USB_PHY_VDD_DIG_VOL_MAX); - if (ret) { - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); - regulator_put(hsusb_vddcx); - return ret; - } - - ret = regulator_enable(hsusb_vddcx); - if (ret) { - dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - regulator_put(hsusb_vddcx); - } - } else { - ret = regulator_set_voltage(hsusb_vddcx, 0, - USB_PHY_VDD_DIG_VOL_MAX); - if (ret) - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); - ret = regulator_disable(hsusb_vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - - regulator_put(hsusb_vddcx); - } - - return ret; -} - -static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) -{ - int rc = 0; - - if (init) { - hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); - if (IS_ERR(hsusb_3p3)) { - dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); - return PTR_ERR(hsusb_3p3); - } - - rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, - USB_PHY_3P3_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 3p3\n"); - goto put_3p3; - } - rc = regulator_enable(hsusb_3p3); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); - goto put_3p3; - } - hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); - if (IS_ERR(hsusb_1p8)) { - dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); - rc = PTR_ERR(hsusb_1p8); - goto disable_3p3; - } - rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, - USB_PHY_1P8_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 1p8\n"); - goto put_1p8; - } - rc = regulator_enable(hsusb_1p8); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); - goto put_1p8; - } - - return 0; - } - - regulator_disable(hsusb_1p8); -put_1p8: - regulator_put(hsusb_1p8); -disable_3p3: - regulator_disable(hsusb_3p3); -put_3p3: - regulator_put(hsusb_3p3); - return rc; -} - -#ifdef CONFIG_PM_SLEEP -#define USB_PHY_SUSP_DIG_VOL 500000 -static int msm_hsusb_config_vddcx(int high) -{ - int max_vol = USB_PHY_VDD_DIG_VOL_MAX; - int min_vol; - int ret; - - if (high) - min_vol = USB_PHY_VDD_DIG_VOL_MIN; - else - min_vol = USB_PHY_SUSP_DIG_VOL; - - ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); - if (ret) { - pr_err("%s: unable to set the voltage for regulator " - "HSUSB_VDDCX\n", __func__); - return ret; - } - - pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); - - return ret; -} -#endif - -static int msm_hsusb_ldo_set_mode(int on) -{ - int ret = 0; - - if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { - pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); - return -ENODEV; - } - - if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { - pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); - return -ENODEV; - } - - if (on) { - ret = regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_HPM_LOAD); - if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_1p8\n", __func__); - return ret; - } - ret = regulator_set_optimum_mode(hsusb_3p3, - USB_PHY_3P3_HPM_LOAD); - if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_3p3\n", __func__); - regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_LPM_LOAD); - return ret; - } - } else { - ret = regulator_set_optimum_mode(hsusb_1p8, - USB_PHY_1P8_LPM_LOAD); - if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_1p8\n", __func__); - ret = regulator_set_optimum_mode(hsusb_3p3, - USB_PHY_3P3_LPM_LOAD); - if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_3p3\n", __func__); - } - - pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); - return ret < 0 ? ret : 0; -} - -static int ulpi_read(struct usb_phy *phy, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate read operation */ - writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_read: timeout %08x\n", - readl(USB_ULPI_VIEWPORT)); - return -ETIMEDOUT; - } - return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); -} - -static int ulpi_write(struct usb_phy *phy, u32 val, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate write operation */ - writel(ULPI_RUN | ULPI_WRITE | - ULPI_ADDR(reg) | ULPI_DATA(val), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_write: timeout\n"); - return -ETIMEDOUT; - } - return 0; -} - -static struct usb_phy_io_ops msm_otg_io_ops = { - .read = ulpi_read, - .write = ulpi_write, -}; - -static void ulpi_init(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - int *seq = pdata->phy_init_seq; - - if (!seq) - return; - - while (seq[0] >= 0) { - dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", - seq[0], seq[1]); - ulpi_write(&motg->phy, seq[0], seq[1]); - seq += 2; - } -} - -static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) -{ - int ret; - - if (assert) { - ret = clk_reset(motg->clk, CLK_RESET_ASSERT); - if (ret) - dev_err(motg->phy.dev, "usb hs_clk assert failed\n"); - } else { - ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->phy.dev, "usb hs_clk deassert failed\n"); - } - return ret; -} - -static int msm_otg_phy_clk_reset(struct msm_otg *motg) -{ - int ret; - - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); - if (ret) { - dev_err(motg->phy.dev, "usb phy clk assert failed\n"); - return ret; - } - usleep_range(10000, 12000); - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->phy.dev, "usb phy clk deassert failed\n"); - return ret; -} - -static int msm_otg_phy_reset(struct msm_otg *motg) -{ - u32 val; - int ret; - int retries; - - ret = msm_otg_link_clk_reset(motg, 1); - if (ret) - return ret; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - ret = msm_otg_link_clk_reset(motg, 0); - if (ret) - return ret; - - val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_ULPI, USB_PORTSC); - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, - ULPI_CLR(ULPI_FUNC_CTRL)); - if (!ret) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - /* This reset calibrates the phy, if the above write succeeded */ - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_read(&motg->phy, ULPI_DEBUG); - if (ret != -ETIMEDOUT) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - dev_info(motg->phy.dev, "phy_reset: success\n"); - return 0; -} - -#define LINK_RESET_TIMEOUT_USEC (250 * 1000) -static int msm_otg_reset(struct usb_phy *phy) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - int ret; - u32 val = 0; - u32 ulpi_val = 0; - - ret = msm_otg_phy_reset(motg); - if (ret) { - dev_err(phy->dev, "phy_reset failed\n"); - return ret; - } - - ulpi_init(motg); - - writel(USBCMD_RESET, USB_USBCMD); - while (cnt < LINK_RESET_TIMEOUT_USEC) { - if (!(readl(USB_USBCMD) & USBCMD_RESET)) - break; - udelay(1); - cnt++; - } - if (cnt >= LINK_RESET_TIMEOUT_USEC) - return -ETIMEDOUT; - - /* select ULPI phy */ - writel(0x80000000, USB_PORTSC); - - msleep(100); - - writel(0x0, USB_AHBBURST); - writel(0x00, USB_AHBMODE); - - if (pdata->otg_control == OTG_PHY_CONTROL) { - val = readl(USB_OTGSC); - if (pdata->mode == USB_OTG) { - ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; - val |= OTGSC_IDIE | OTGSC_BSVIE; - } else if (pdata->mode == USB_PERIPHERAL) { - ulpi_val = ULPI_INT_SESS_VALID; - val |= OTGSC_BSVIE; - } - writel(val, USB_OTGSC); - ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_RISE); - ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); - } - - return 0; -} - -#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) -#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_suspend(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - struct usb_bus *bus = phy->otg->host; - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - - if (atomic_read(&motg->in_lpm)) - return 0; - - disable_irq(motg->irq); - /* - * Chipidea 45-nm PHY suspend sequence: - * - * Interrupt Latch Register auto-clear feature is not present - * in all PHY versions. Latch register is clear on read type. - * Clear latch register to avoid spurious wakeup from - * low power mode (LPM). - * - * PHY comparators are disabled when PHY enters into low power - * mode (LPM). Keep PHY comparators ON in LPM only when we expect - * VBUS/Id notifications from USB PHY. Otherwise turn off USB - * PHY comparators. This save significant amount of power. - * - * PLL is not turned off when PHY enters into low power mode (LPM). - * Disable PLL for maximum power savings. - */ - - if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) { - ulpi_read(phy, 0x14); - if (pdata->otg_control == OTG_PHY_CONTROL) - ulpi_write(phy, 0x01, 0x30); - ulpi_write(phy, 0x08, 0x09); - } - - /* - * PHY may take some time or even fail to enter into low power - * mode (LPM). Hence poll for 500 msec and reset the PHY and link - * in failure case. - */ - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { - dev_err(phy->dev, "Unable to suspend PHY\n"); - msm_otg_reset(phy); - enable_irq(motg->irq); - return -ETIMEDOUT; - } - - /* - * PHY has capability to generate interrupt asynchronously in low - * power mode (LPM). This interrupt is level triggered. So USB IRQ - * line must be disabled till async interrupt enable bit is cleared - * in USBCMD register. Assert STP (ULPI interface STOP signal) to - * block data communication from PHY. - */ - writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) - writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - - if (!IS_ERR(motg->pclk_src)) - clk_disable(motg->pclk_src); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(0); - msm_hsusb_config_vddcx(0); - } - - if (device_may_wakeup(phy->dev)) - enable_irq_wake(motg->irq); - if (bus) - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - atomic_set(&motg->in_lpm, 1); - enable_irq(motg->irq); - - dev_info(phy->dev, "USB in low power mode\n"); - - return 0; -} - -static int msm_otg_resume(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - struct usb_bus *bus = phy->otg->host; - int cnt = 0; - unsigned temp; - - if (!atomic_read(&motg->in_lpm)) - return 0; - - if (!IS_ERR(motg->pclk_src)) - clk_enable(motg->pclk_src); - - clk_enable(motg->pclk); - clk_enable(motg->clk); - if (motg->core_clk) - clk_enable(motg->core_clk); - - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && - motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(1); - msm_hsusb_config_vddcx(1); - writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); - } - - temp = readl(USB_USBCMD); - temp &= ~ASYNC_INTR_CTRL; - temp &= ~ULPI_STP_CTRL; - writel(temp, USB_USBCMD); - - /* - * PHY comes out of low power mode (LPM) in case of wakeup - * from asynchronous interrupt. - */ - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - goto skip_phy_resume; - - writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_RESUME_TIMEOUT_USEC) { - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_RESUME_TIMEOUT_USEC) { - /* - * This is a fatal error. Reset the link and - * PHY. USB state can not be restored. Re-insertion - * of USB cable is the only way to get USB working. - */ - dev_err(phy->dev, "Unable to resume USB." - "Re-plugin the cable\n"); - msm_otg_reset(phy); - } - -skip_phy_resume: - if (device_may_wakeup(phy->dev)) - disable_irq_wake(motg->irq); - if (bus) - set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - atomic_set(&motg->in_lpm, 0); - - if (motg->async_int) { - motg->async_int = 0; - pm_runtime_put(phy->dev); - enable_irq(motg->irq); - } - - dev_info(phy->dev, "USB exited from low power mode\n"); - - return 0; -} -#endif - -static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA) -{ - if (motg->cur_power == mA) - return; - - /* TODO: Notify PMIC about available current */ - dev_info(motg->phy.dev, "Avail curr from USB = %u\n", mA); - motg->cur_power = mA; -} - -static int msm_otg_set_power(struct usb_phy *phy, unsigned mA) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - - /* - * Gadget driver uses set_power method to notify about the - * available current based on suspend/configured states. - * - * IDEV_CHG can be drawn irrespective of suspend/un-configured - * states when CDP/ACA is connected. - */ - if (motg->chg_type == USB_SDP_CHARGER) - msm_otg_notify_charger(motg, mA); - - return 0; -} - -static void msm_otg_start_host(struct usb_phy *phy, int on) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - struct usb_hcd *hcd; - - if (!phy->otg->host) - return; - - hcd = bus_to_hcd(phy->otg->host); - - if (on) { - dev_dbg(phy->dev, "host on\n"); - - if (pdata->vbus_power) - pdata->vbus_power(1); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Enable internal - * HUB before kicking the host. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_A_HOST); -#ifdef CONFIG_USB - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); -#endif - } else { - dev_dbg(phy->dev, "host off\n"); - -#ifdef CONFIG_USB - usb_remove_hcd(hcd); -#endif - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - if (pdata->vbus_power) - pdata->vbus_power(0); - } -} - -static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); - struct usb_hcd *hcd; - - /* - * Fail host registration if this board can support - * only peripheral configuration. - */ - if (motg->pdata->mode == USB_PERIPHERAL) { - dev_info(otg->phy->dev, "Host mode is not supported\n"); - return -ENODEV; - } - - if (!host) { - if (otg->phy->state == OTG_STATE_A_HOST) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_host(otg->phy, 0); - otg->host = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->host = NULL; - } - - return 0; - } - - hcd = bus_to_hcd(host); - hcd->power_budget = motg->pdata->power_budget; - - otg->host = host; - dev_dbg(otg->phy->dev, "host driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if peripheral is not supported - * or peripheral is already registered with us. - */ - if (motg->pdata->mode == USB_HOST || otg->gadget) { - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -static void msm_otg_start_peripheral(struct usb_phy *phy, int on) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; - - if (!phy->otg->gadget) - return; - - if (on) { - dev_dbg(phy->dev, "gadget on\n"); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Disable internal - * HUB before kicking the gadget. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); - usb_gadget_vbus_connect(phy->otg->gadget); - } else { - dev_dbg(phy->dev, "gadget off\n"); - usb_gadget_vbus_disconnect(phy->otg->gadget); - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - } - -} - -static int msm_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); - - /* - * Fail peripheral registration if this board can support - * only host configuration. - */ - if (motg->pdata->mode == USB_HOST) { - dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); - return -ENODEV; - } - - if (!gadget) { - if (otg->phy->state == OTG_STATE_B_PERIPHERAL) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_peripheral(otg->phy, 0); - otg->gadget = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->gadget = NULL; - } - - return 0; - } - otg->gadget = gadget; - dev_dbg(otg->phy->dev, "peripheral driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if host is not supported - * or host is already registered with us. - */ - if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -static bool msm_chg_check_secondary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - ret = chg_det & (1 << 4); - break; - case SNPS_28NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x87); - ret = chg_det & 1; - break; - default: - break; - } - return ret; -} - -static void msm_chg_enable_secondary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn off charger block */ - chg_det |= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - /* control chg block via ULPI */ - chg_det &= ~(1 << 3); - ulpi_write(phy, chg_det, 0x34); - /* put it in host mode for enabling D- source */ - chg_det &= ~(1 << 2); - ulpi_write(phy, chg_det, 0x34); - /* Turn on chg detect block */ - chg_det &= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - /* enable chg detection */ - chg_det &= ~(1 << 0); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* - * Configure DM as current source, DP as current sink - * and enable battery charging comparators. - */ - ulpi_write(phy, 0x8, 0x85); - ulpi_write(phy, 0x2, 0x85); - ulpi_write(phy, 0x1, 0x85); - break; - default: - break; - } -} - -static bool msm_chg_check_primary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - ret = chg_det & (1 << 4); - break; - case SNPS_28NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x87); - ret = chg_det & 1; - break; - default: - break; - } - return ret; -} - -static void msm_chg_enable_primary_det(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* enable chg detection */ - chg_det &= ~(1 << 0); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* - * Configure DP as current source, DM as current sink - * and enable battery charging comparators. - */ - ulpi_write(phy, 0x2, 0x85); - ulpi_write(phy, 0x1, 0x85); - break; - default: - break; - } -} - -static bool msm_chg_check_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 line_state; - bool ret = false; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - line_state = ulpi_read(phy, 0x15); - ret = !(line_state & 1); - break; - case SNPS_28NM_INTEGRATED_PHY: - line_state = ulpi_read(phy, 0x87); - ret = line_state & 2; - break; - default: - break; - } - return ret; -} - -static void msm_chg_disable_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - chg_det &= ~(1 << 5); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - ulpi_write(phy, 0x10, 0x86); - break; - default: - break; - } -} - -static void msm_chg_enable_dcd(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn on D+ current source */ - chg_det |= (1 << 5); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Data contact detection enable */ - ulpi_write(phy, 0x10, 0x85); - break; - default: - break; - } -} - -static void msm_chg_block_on(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 func_ctrl, chg_det; - - /* put the controller in non-driving mode */ - func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); - func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; - func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* control chg block via ULPI */ - chg_det &= ~(1 << 3); - ulpi_write(phy, chg_det, 0x34); - /* Turn on chg detect block */ - chg_det &= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - udelay(20); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Clear charger detecting control bits */ - ulpi_write(phy, 0x3F, 0x86); - /* Clear alt interrupt latch and enable bits */ - ulpi_write(phy, 0x1F, 0x92); - ulpi_write(phy, 0x1F, 0x95); - udelay(100); - break; - default: - break; - } -} - -static void msm_chg_block_off(struct msm_otg *motg) -{ - struct usb_phy *phy = &motg->phy; - u32 func_ctrl, chg_det; - - switch (motg->pdata->phy_type) { - case CI_45NM_INTEGRATED_PHY: - chg_det = ulpi_read(phy, 0x34); - /* Turn off charger block */ - chg_det |= ~(1 << 1); - ulpi_write(phy, chg_det, 0x34); - break; - case SNPS_28NM_INTEGRATED_PHY: - /* Clear charger detecting control bits */ - ulpi_write(phy, 0x3F, 0x86); - /* Clear alt interrupt latch and enable bits */ - ulpi_write(phy, 0x1F, 0x92); - ulpi_write(phy, 0x1F, 0x95); - break; - default: - break; - } - - /* put the controller in normal mode */ - func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); - func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; - func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; - ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); -} - -#define MSM_CHG_DCD_POLL_TIME (100 * HZ/1000) /* 100 msec */ -#define MSM_CHG_DCD_MAX_RETRIES 6 /* Tdcd_tmout = 6 * 100 msec */ -#define MSM_CHG_PRIMARY_DET_TIME (40 * HZ/1000) /* TVDPSRC_ON */ -#define MSM_CHG_SECONDARY_DET_TIME (40 * HZ/1000) /* TVDMSRC_ON */ -static void msm_chg_detect_work(struct work_struct *w) -{ - struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work); - struct usb_phy *phy = &motg->phy; - bool is_dcd, tmout, vout; - unsigned long delay; - - dev_dbg(phy->dev, "chg detection work\n"); - switch (motg->chg_state) { - case USB_CHG_STATE_UNDEFINED: - pm_runtime_get_sync(phy->dev); - msm_chg_block_on(motg); - msm_chg_enable_dcd(motg); - motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; - motg->dcd_retries = 0; - delay = MSM_CHG_DCD_POLL_TIME; - break; - case USB_CHG_STATE_WAIT_FOR_DCD: - is_dcd = msm_chg_check_dcd(motg); - tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES; - if (is_dcd || tmout) { - msm_chg_disable_dcd(motg); - msm_chg_enable_primary_det(motg); - delay = MSM_CHG_PRIMARY_DET_TIME; - motg->chg_state = USB_CHG_STATE_DCD_DONE; - } else { - delay = MSM_CHG_DCD_POLL_TIME; - } - break; - case USB_CHG_STATE_DCD_DONE: - vout = msm_chg_check_primary_det(motg); - if (vout) { - msm_chg_enable_secondary_det(motg); - delay = MSM_CHG_SECONDARY_DET_TIME; - motg->chg_state = USB_CHG_STATE_PRIMARY_DONE; - } else { - motg->chg_type = USB_SDP_CHARGER; - motg->chg_state = USB_CHG_STATE_DETECTED; - delay = 0; - } - break; - case USB_CHG_STATE_PRIMARY_DONE: - vout = msm_chg_check_secondary_det(motg); - if (vout) - motg->chg_type = USB_DCP_CHARGER; - else - motg->chg_type = USB_CDP_CHARGER; - motg->chg_state = USB_CHG_STATE_SECONDARY_DONE; - /* fall through */ - case USB_CHG_STATE_SECONDARY_DONE: - motg->chg_state = USB_CHG_STATE_DETECTED; - case USB_CHG_STATE_DETECTED: - msm_chg_block_off(motg); - dev_dbg(phy->dev, "charger = %d\n", motg->chg_type); - schedule_work(&motg->sm_work); - return; - default: - return; - } - - schedule_delayed_work(&motg->chg_work, delay); -} - -/* - * We support OTG, Peripheral only and Host only configurations. In case - * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen - * via Id pin status or user request (debugfs). Id/BSV interrupts are not - * enabled when switch is controlled by user and default mode is supplied - * by board file, which can be changed by userspace later. - */ -static void msm_otg_init_sm(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - u32 otgsc = readl(USB_OTGSC); - - switch (pdata->mode) { - case USB_OTG: - if (pdata->otg_control == OTG_PHY_CONTROL) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - } else if (pdata->otg_control == OTG_USER_CONTROL) { - if (pdata->default_mode == USB_HOST) { - clear_bit(ID, &motg->inputs); - } else if (pdata->default_mode == USB_PERIPHERAL) { - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - } else { - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - } - } - break; - case USB_HOST: - clear_bit(ID, &motg->inputs); - break; - case USB_PERIPHERAL: - set_bit(ID, &motg->inputs); - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - break; - } -} - -static void msm_otg_sm_work(struct work_struct *w) -{ - struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); - struct usb_otg *otg = motg->phy.otg; - - switch (otg->phy->state) { - case OTG_STATE_UNDEFINED: - dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); - msm_otg_reset(otg->phy); - msm_otg_init_sm(motg); - otg->phy->state = OTG_STATE_B_IDLE; - /* FALL THROUGH */ - case OTG_STATE_B_IDLE: - dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); - if (!test_bit(ID, &motg->inputs) && otg->host) { - /* disable BSV bit */ - writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); - msm_otg_start_host(otg->phy, 1); - otg->phy->state = OTG_STATE_A_HOST; - } else if (test_bit(B_SESS_VLD, &motg->inputs)) { - switch (motg->chg_state) { - case USB_CHG_STATE_UNDEFINED: - msm_chg_detect_work(&motg->chg_work.work); - break; - case USB_CHG_STATE_DETECTED: - switch (motg->chg_type) { - case USB_DCP_CHARGER: - msm_otg_notify_charger(motg, - IDEV_CHG_MAX); - break; - case USB_CDP_CHARGER: - msm_otg_notify_charger(motg, - IDEV_CHG_MAX); - msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state - = OTG_STATE_B_PERIPHERAL; - break; - case USB_SDP_CHARGER: - msm_otg_notify_charger(motg, IUNIT); - msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state - = OTG_STATE_B_PERIPHERAL; - break; - default: - break; - } - break; - default: - break; - } - } else { - /* - * If charger detection work is pending, decrement - * the pm usage counter to balance with the one that - * is incremented in charger detection work. - */ - if (cancel_delayed_work_sync(&motg->chg_work)) { - pm_runtime_put_sync(otg->phy->dev); - msm_otg_reset(otg->phy); - } - msm_otg_notify_charger(motg, 0); - motg->chg_state = USB_CHG_STATE_UNDEFINED; - motg->chg_type = USB_INVALID_CHARGER; - } - pm_runtime_put_sync(otg->phy->dev); - break; - case OTG_STATE_B_PERIPHERAL: - dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); - if (!test_bit(B_SESS_VLD, &motg->inputs) || - !test_bit(ID, &motg->inputs)) { - msm_otg_notify_charger(motg, 0); - msm_otg_start_peripheral(otg->phy, 0); - motg->chg_state = USB_CHG_STATE_UNDEFINED; - motg->chg_type = USB_INVALID_CHARGER; - otg->phy->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); - schedule_work(w); - } - break; - case OTG_STATE_A_HOST: - dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); - if (test_bit(ID, &motg->inputs)) { - msm_otg_start_host(otg->phy, 0); - otg->phy->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); - schedule_work(w); - } - break; - default: - break; - } -} - -static irqreturn_t msm_otg_irq(int irq, void *data) -{ - struct msm_otg *motg = data; - struct usb_phy *phy = &motg->phy; - u32 otgsc = 0; - - if (atomic_read(&motg->in_lpm)) { - disable_irq_nosync(irq); - motg->async_int = 1; - pm_runtime_get(phy->dev); - return IRQ_HANDLED; - } - - otgsc = readl(USB_OTGSC); - if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) - return IRQ_NONE; - - if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - dev_dbg(phy->dev, "ID set/clear\n"); - pm_runtime_get_noresume(phy->dev); - } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - dev_dbg(phy->dev, "BSV set/clear\n"); - pm_runtime_get_noresume(phy->dev); - } - - writel(otgsc, USB_OTGSC); - schedule_work(&motg->sm_work); - return IRQ_HANDLED; -} - -static int msm_otg_mode_show(struct seq_file *s, void *unused) -{ - struct msm_otg *motg = s->private; - struct usb_otg *otg = motg->phy.otg; - - switch (otg->phy->state) { - case OTG_STATE_A_HOST: - seq_printf(s, "host\n"); - break; - case OTG_STATE_B_PERIPHERAL: - seq_printf(s, "peripheral\n"); - break; - default: - seq_printf(s, "none\n"); - break; - } - - return 0; -} - -static int msm_otg_mode_open(struct inode *inode, struct file *file) -{ - return single_open(file, msm_otg_mode_show, inode->i_private); -} - -static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, - size_t count, loff_t *ppos) -{ - struct seq_file *s = file->private_data; - struct msm_otg *motg = s->private; - char buf[16]; - struct usb_otg *otg = motg->phy.otg; - int status = count; - enum usb_mode_type req_mode; - - memset(buf, 0x00, sizeof(buf)); - - if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { - status = -EFAULT; - goto out; - } - - if (!strncmp(buf, "host", 4)) { - req_mode = USB_HOST; - } else if (!strncmp(buf, "peripheral", 10)) { - req_mode = USB_PERIPHERAL; - } else if (!strncmp(buf, "none", 4)) { - req_mode = USB_NONE; - } else { - status = -EINVAL; - goto out; - } - - switch (req_mode) { - case USB_NONE: - switch (otg->phy->state) { - case OTG_STATE_A_HOST: - case OTG_STATE_B_PERIPHERAL: - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_PERIPHERAL: - switch (otg->phy->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_A_HOST: - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_HOST: - switch (otg->phy->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_B_PERIPHERAL: - clear_bit(ID, &motg->inputs); - break; - default: - goto out; - } - break; - default: - goto out; - } - - pm_runtime_get_sync(otg->phy->dev); - schedule_work(&motg->sm_work); -out: - return status; -} - -const struct file_operations msm_otg_mode_fops = { - .open = msm_otg_mode_open, - .read = seq_read, - .write = msm_otg_mode_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct dentry *msm_otg_dbg_root; -static struct dentry *msm_otg_dbg_mode; - -static int msm_otg_debugfs_init(struct msm_otg *motg) -{ - msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); - - if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) - return -ENODEV; - - msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, - msm_otg_dbg_root, motg, &msm_otg_mode_fops); - if (!msm_otg_dbg_mode) { - debugfs_remove(msm_otg_dbg_root); - msm_otg_dbg_root = NULL; - return -ENODEV; - } - - return 0; -} - -static void msm_otg_debugfs_cleanup(void) -{ - debugfs_remove(msm_otg_dbg_mode); - debugfs_remove(msm_otg_dbg_root); -} - -static int __init msm_otg_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res; - struct msm_otg *motg; - struct usb_phy *phy; - - dev_info(&pdev->dev, "msm_otg probe\n"); - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "No platform data given. Bailing out\n"); - return -ENODEV; - } - - motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); - if (!motg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - return -ENOMEM; - } - - motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!motg->phy.otg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - return -ENOMEM; - } - - motg->pdata = pdev->dev.platform_data; - phy = &motg->phy; - phy->dev = &pdev->dev; - - motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); - if (IS_ERR(motg->phy_reset_clk)) { - dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); - ret = PTR_ERR(motg->phy_reset_clk); - goto free_motg; - } - - motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); - if (IS_ERR(motg->clk)) { - dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); - ret = PTR_ERR(motg->clk); - goto put_phy_reset_clk; - } - clk_set_rate(motg->clk, 60000000); - - /* - * If USB Core is running its protocol engine based on CORE CLK, - * CORE CLK must be running at >55Mhz for correct HSUSB - * operation and USB core cannot tolerate frequency changes on - * CORE CLK. For such USB cores, vote for maximum clk frequency - * on pclk source - */ - if (motg->pdata->pclk_src_name) { - motg->pclk_src = clk_get(&pdev->dev, - motg->pdata->pclk_src_name); - if (IS_ERR(motg->pclk_src)) - goto put_clk; - clk_set_rate(motg->pclk_src, INT_MAX); - clk_enable(motg->pclk_src); - } else - motg->pclk_src = ERR_PTR(-ENOENT); - - - motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); - if (IS_ERR(motg->pclk)) { - dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); - ret = PTR_ERR(motg->pclk); - goto put_pclk_src; - } - - /* - * USB core clock is not present on all MSM chips. This - * clock is introduced to remove the dependency on AXI - * bus frequency. - */ - motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); - if (IS_ERR(motg->core_clk)) - motg->core_clk = NULL; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get platform resource mem\n"); - ret = -ENODEV; - goto put_core_clk; - } - - motg->regs = ioremap(res->start, resource_size(res)); - if (!motg->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto put_core_clk; - } - dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); - - motg->irq = platform_get_irq(pdev, 0); - if (!motg->irq) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - ret = -ENODEV; - goto free_regs; - } - - clk_enable(motg->clk); - clk_enable(motg->pclk); - - ret = msm_hsusb_init_vddcx(motg, 1); - if (ret) { - dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); - goto free_regs; - } - - ret = msm_hsusb_ldo_init(motg, 1); - if (ret) { - dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); - goto vddcx_exit; - } - ret = msm_hsusb_ldo_set_mode(1); - if (ret) { - dev_err(&pdev->dev, "hsusb vreg enable failed\n"); - goto ldo_exit; - } - - if (motg->core_clk) - clk_enable(motg->core_clk); - - writel(0, USB_USBINTR); - writel(0, USB_OTGSC); - - INIT_WORK(&motg->sm_work, msm_otg_sm_work); - INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); - ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, - "msm_otg", motg); - if (ret) { - dev_err(&pdev->dev, "request irq failed\n"); - goto disable_clks; - } - - phy->init = msm_otg_reset; - phy->set_power = msm_otg_set_power; - - phy->io_ops = &msm_otg_io_ops; - - phy->otg->phy = &motg->phy; - phy->otg->set_host = msm_otg_set_host; - phy->otg->set_peripheral = msm_otg_set_peripheral; - - ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); - if (ret) { - dev_err(&pdev->dev, "usb_add_phy failed\n"); - goto free_irq; - } - - platform_set_drvdata(pdev, motg); - device_init_wakeup(&pdev->dev, 1); - - if (motg->pdata->mode == USB_OTG && - motg->pdata->otg_control == OTG_USER_CONTROL) { - ret = msm_otg_debugfs_init(motg); - if (ret) - dev_dbg(&pdev->dev, "mode debugfs file is" - "not available\n"); - } - - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - - return 0; -free_irq: - free_irq(motg->irq, motg); -disable_clks: - clk_disable(motg->pclk); - clk_disable(motg->clk); -ldo_exit: - msm_hsusb_ldo_init(motg, 0); -vddcx_exit: - msm_hsusb_init_vddcx(motg, 0); -free_regs: - iounmap(motg->regs); -put_core_clk: - if (motg->core_clk) - clk_put(motg->core_clk); - clk_put(motg->pclk); -put_pclk_src: - if (!IS_ERR(motg->pclk_src)) { - clk_disable(motg->pclk_src); - clk_put(motg->pclk_src); - } -put_clk: - clk_put(motg->clk); -put_phy_reset_clk: - clk_put(motg->phy_reset_clk); -free_motg: - kfree(motg->phy.otg); - kfree(motg); - return ret; -} - -static int msm_otg_remove(struct platform_device *pdev) -{ - struct msm_otg *motg = platform_get_drvdata(pdev); - struct usb_phy *phy = &motg->phy; - int cnt = 0; - - if (phy->otg->host || phy->otg->gadget) - return -EBUSY; - - msm_otg_debugfs_cleanup(); - cancel_delayed_work_sync(&motg->chg_work); - cancel_work_sync(&motg->sm_work); - - pm_runtime_resume(&pdev->dev); - - device_init_wakeup(&pdev->dev, 0); - pm_runtime_disable(&pdev->dev); - - usb_remove_phy(phy); - free_irq(motg->irq, motg); - - /* - * Put PHY in low power mode. - */ - ulpi_read(phy, 0x14); - ulpi_write(phy, 0x08, 0x09); - - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) - dev_err(phy->dev, "Unable to suspend PHY\n"); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) { - clk_disable(motg->pclk_src); - clk_put(motg->pclk_src); - } - msm_hsusb_ldo_init(motg, 0); - - iounmap(motg->regs); - pm_runtime_set_suspended(&pdev->dev); - - clk_put(motg->phy_reset_clk); - clk_put(motg->pclk); - clk_put(motg->clk); - if (motg->core_clk) - clk_put(motg->core_clk); - - kfree(motg->phy.otg); - kfree(motg); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME -static int msm_otg_runtime_idle(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - struct usb_otg *otg = motg->phy.otg; - - dev_dbg(dev, "OTG runtime idle\n"); - - /* - * It is observed some times that a spurious interrupt - * comes when PHY is put into LPM immediately after PHY reset. - * This 1 sec delay also prevents entering into LPM immediately - * after asynchronous interrupt. - */ - if (otg->phy->state != OTG_STATE_UNDEFINED) - pm_schedule_suspend(dev, 1000); - - return -EAGAIN; -} - -static int msm_otg_runtime_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_runtime_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime resume\n"); - return msm_otg_resume(motg); -} -#endif - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_pm_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG PM suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_pm_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - int ret; - - dev_dbg(dev, "OTG PM resume\n"); - - ret = msm_otg_resume(motg); - if (ret) - return ret; - - /* - * Runtime PM Documentation recommends bringing the - * device to full powered state upon resume. - */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - return 0; -} -#endif - -#ifdef CONFIG_PM -static const struct dev_pm_ops msm_otg_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) - SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, - msm_otg_runtime_idle) -}; -#endif - -static struct platform_driver msm_otg_driver = { - .remove = msm_otg_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &msm_otg_dev_pm_ops, -#endif - }, -}; - -module_platform_driver_probe(msm_otg_driver, msm_otg_probe); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/drivers/usb/phy/mv_otg.c b/drivers/usb/phy/mv_otg.c deleted file mode 100644 index b6a9be31133b..000000000000 --- a/drivers/usb/phy/mv_otg.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * Author: Chao Xie - * Neil Zhang - * - * 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 "mv_otg.h" - -#define DRIVER_DESC "Marvell USB OTG transceiver driver" -#define DRIVER_VERSION "Jan 20, 2010" - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -static const char driver_name[] = "mv-otg"; - -static char *state_string[] = { - "undefined", - "b_idle", - "b_srp_init", - "b_peripheral", - "b_wait_acon", - "b_host", - "a_idle", - "a_wait_vrise", - "a_wait_bcon", - "a_host", - "a_suspend", - "a_peripheral", - "a_wait_vfall", - "a_vbus_err" -}; - -static int mv_otg_set_vbus(struct usb_otg *otg, bool on) -{ - struct mv_otg *mvotg = container_of(otg->phy, struct mv_otg, phy); - if (mvotg->pdata->set_vbus == NULL) - return -ENODEV; - - return mvotg->pdata->set_vbus(on); -} - -static int mv_otg_set_host(struct usb_otg *otg, - struct usb_bus *host) -{ - otg->host = host; - - return 0; -} - -static int mv_otg_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - otg->gadget = gadget; - - return 0; -} - -static void mv_otg_run_state_machine(struct mv_otg *mvotg, - unsigned long delay) -{ - dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n"); - if (!mvotg->qwork) - return; - - queue_delayed_work(mvotg->qwork, &mvotg->work, delay); -} - -static void mv_otg_timer_await_bcon(unsigned long data) -{ - struct mv_otg *mvotg = (struct mv_otg *) data; - - mvotg->otg_ctrl.a_wait_bcon_timeout = 1; - - dev_info(&mvotg->pdev->dev, "B Device No Response!\n"); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } -} - -static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id) -{ - struct timer_list *timer; - - if (id >= OTG_TIMER_NUM) - return -EINVAL; - - timer = &mvotg->otg_ctrl.timer[id]; - - if (timer_pending(timer)) - del_timer(timer); - - return 0; -} - -static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id, - unsigned long interval, - void (*callback) (unsigned long)) -{ - struct timer_list *timer; - - if (id >= OTG_TIMER_NUM) - return -EINVAL; - - timer = &mvotg->otg_ctrl.timer[id]; - if (timer_pending(timer)) { - dev_err(&mvotg->pdev->dev, "Timer%d is already running\n", id); - return -EBUSY; - } - - init_timer(timer); - timer->data = (unsigned long) mvotg; - timer->function = callback; - timer->expires = jiffies + interval; - add_timer(timer); - - return 0; -} - -static int mv_otg_reset(struct mv_otg *mvotg) -{ - unsigned int loops; - u32 tmp; - - /* Stop the controller */ - tmp = readl(&mvotg->op_regs->usbcmd); - tmp &= ~USBCMD_RUN_STOP; - writel(tmp, &mvotg->op_regs->usbcmd); - - /* Reset the controller to get default values */ - writel(USBCMD_CTRL_RESET, &mvotg->op_regs->usbcmd); - - loops = 500; - while (readl(&mvotg->op_regs->usbcmd) & USBCMD_CTRL_RESET) { - if (loops == 0) { - dev_err(&mvotg->pdev->dev, - "Wait for RESET completed TIMEOUT\n"); - return -ETIMEDOUT; - } - loops--; - udelay(20); - } - - writel(0x0, &mvotg->op_regs->usbintr); - tmp = readl(&mvotg->op_regs->usbsts); - writel(tmp, &mvotg->op_regs->usbsts); - - return 0; -} - -static void mv_otg_init_irq(struct mv_otg *mvotg) -{ - u32 otgsc; - - mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID - | OTGSC_INTR_A_VBUS_VALID; - mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID - | OTGSC_INTSTS_A_VBUS_VALID; - - if (mvotg->pdata->vbus == NULL) { - mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID - | OTGSC_INTR_B_SESSION_END; - mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID - | OTGSC_INTSTS_B_SESSION_END; - } - - if (mvotg->pdata->id == NULL) { - mvotg->irq_en |= OTGSC_INTR_USB_ID; - mvotg->irq_status |= OTGSC_INTSTS_USB_ID; - } - - otgsc = readl(&mvotg->op_regs->otgsc); - otgsc |= mvotg->irq_en; - writel(otgsc, &mvotg->op_regs->otgsc); -} - -static void mv_otg_start_host(struct mv_otg *mvotg, int on) -{ -#ifdef CONFIG_USB - struct usb_otg *otg = mvotg->phy.otg; - struct usb_hcd *hcd; - - if (!otg->host) - return; - - dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop"); - - hcd = bus_to_hcd(otg->host); - - if (on) - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); - else - usb_remove_hcd(hcd); -#endif /* CONFIG_USB */ -} - -static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) -{ - struct usb_otg *otg = mvotg->phy.otg; - - if (!otg->gadget) - return; - - dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off"); - - if (on) - usb_gadget_vbus_connect(otg->gadget); - else - usb_gadget_vbus_disconnect(otg->gadget); -} - -static void otg_clock_enable(struct mv_otg *mvotg) -{ - unsigned int i; - - for (i = 0; i < mvotg->clknum; i++) - clk_prepare_enable(mvotg->clk[i]); -} - -static void otg_clock_disable(struct mv_otg *mvotg) -{ - unsigned int i; - - for (i = 0; i < mvotg->clknum; i++) - clk_disable_unprepare(mvotg->clk[i]); -} - -static int mv_otg_enable_internal(struct mv_otg *mvotg) -{ - int retval = 0; - - if (mvotg->active) - return 0; - - dev_dbg(&mvotg->pdev->dev, "otg enabled\n"); - - otg_clock_enable(mvotg); - if (mvotg->pdata->phy_init) { - retval = mvotg->pdata->phy_init(mvotg->phy_regs); - if (retval) { - dev_err(&mvotg->pdev->dev, - "init phy error %d\n", retval); - otg_clock_disable(mvotg); - return retval; - } - } - mvotg->active = 1; - - return 0; - -} - -static int mv_otg_enable(struct mv_otg *mvotg) -{ - if (mvotg->clock_gating) - return mv_otg_enable_internal(mvotg); - - return 0; -} - -static void mv_otg_disable_internal(struct mv_otg *mvotg) -{ - if (mvotg->active) { - dev_dbg(&mvotg->pdev->dev, "otg disabled\n"); - if (mvotg->pdata->phy_deinit) - mvotg->pdata->phy_deinit(mvotg->phy_regs); - otg_clock_disable(mvotg); - mvotg->active = 0; - } -} - -static void mv_otg_disable(struct mv_otg *mvotg) -{ - if (mvotg->clock_gating) - mv_otg_disable_internal(mvotg); -} - -static void mv_otg_update_inputs(struct mv_otg *mvotg) -{ - struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - u32 otgsc; - - otgsc = readl(&mvotg->op_regs->otgsc); - - if (mvotg->pdata->vbus) { - if (mvotg->pdata->vbus->poll() == VBUS_HIGH) { - otg_ctrl->b_sess_vld = 1; - otg_ctrl->b_sess_end = 0; - } else { - otg_ctrl->b_sess_vld = 0; - otg_ctrl->b_sess_end = 1; - } - } else { - otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID); - otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END); - } - - if (mvotg->pdata->id) - otg_ctrl->id = !!mvotg->pdata->id->poll(); - else - otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); - - if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) - otg_ctrl->a_bus_req = 1; - - otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); - otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID); - - dev_dbg(&mvotg->pdev->dev, "%s: ", __func__); - dev_dbg(&mvotg->pdev->dev, "id %d\n", otg_ctrl->id); - dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n", otg_ctrl->b_sess_vld); - dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n", otg_ctrl->b_sess_end); - dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n", otg_ctrl->a_vbus_vld); - dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n", otg_ctrl->a_sess_vld); -} - -static void mv_otg_update_state(struct mv_otg *mvotg) -{ - struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - struct usb_phy *phy = &mvotg->phy; - int old_state = phy->state; - - switch (old_state) { - case OTG_STATE_UNDEFINED: - phy->state = OTG_STATE_B_IDLE; - /* FALL THROUGH */ - case OTG_STATE_B_IDLE: - if (otg_ctrl->id == 0) - phy->state = OTG_STATE_A_IDLE; - else if (otg_ctrl->b_sess_vld) - phy->state = OTG_STATE_B_PERIPHERAL; - break; - case OTG_STATE_B_PERIPHERAL: - if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) - phy->state = OTG_STATE_B_IDLE; - break; - case OTG_STATE_A_IDLE: - if (otg_ctrl->id) - phy->state = OTG_STATE_B_IDLE; - else if (!(otg_ctrl->a_bus_drop) && - (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) - phy->state = OTG_STATE_A_WAIT_VRISE; - break; - case OTG_STATE_A_WAIT_VRISE: - if (otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_WAIT_BCON; - break; - case OTG_STATE_A_WAIT_BCON: - if (otg_ctrl->id || otg_ctrl->a_bus_drop - || otg_ctrl->a_wait_bcon_timeout) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; - otg_ctrl->a_bus_req = 0; - } else if (!otg_ctrl->a_vbus_vld) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_VBUS_ERR; - } else if (otg_ctrl->b_conn) { - mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); - mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_HOST; - } - break; - case OTG_STATE_A_HOST: - if (otg_ctrl->id || !otg_ctrl->b_conn - || otg_ctrl->a_bus_drop) - phy->state = OTG_STATE_A_WAIT_BCON; - else if (!otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_VBUS_ERR; - break; - case OTG_STATE_A_WAIT_VFALL: - if (otg_ctrl->id - || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) - || otg_ctrl->a_bus_req) - phy->state = OTG_STATE_A_IDLE; - break; - case OTG_STATE_A_VBUS_ERR: - if (otg_ctrl->id || otg_ctrl->a_clr_err - || otg_ctrl->a_bus_drop) { - otg_ctrl->a_clr_err = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; - } - break; - default: - break; - } -} - -static void mv_otg_work(struct work_struct *work) -{ - struct mv_otg *mvotg; - struct usb_phy *phy; - struct usb_otg *otg; - int old_state; - - mvotg = container_of(to_delayed_work(work), struct mv_otg, work); - -run: - /* work queue is single thread, or we need spin_lock to protect */ - phy = &mvotg->phy; - otg = phy->otg; - old_state = phy->state; - - if (!mvotg->active) - return; - - mv_otg_update_inputs(mvotg); - mv_otg_update_state(mvotg); - - if (old_state != phy->state) { - dev_info(&mvotg->pdev->dev, "change from state %s to %s\n", - state_string[old_state], - state_string[phy->state]); - - switch (phy->state) { - case OTG_STATE_B_IDLE: - otg->default_a = 0; - if (old_state == OTG_STATE_B_PERIPHERAL) - mv_otg_start_periphrals(mvotg, 0); - mv_otg_reset(mvotg); - mv_otg_disable(mvotg); - break; - case OTG_STATE_B_PERIPHERAL: - mv_otg_enable(mvotg); - mv_otg_start_periphrals(mvotg, 1); - break; - case OTG_STATE_A_IDLE: - otg->default_a = 1; - mv_otg_enable(mvotg); - if (old_state == OTG_STATE_A_WAIT_VFALL) - mv_otg_start_host(mvotg, 0); - mv_otg_reset(mvotg); - break; - case OTG_STATE_A_WAIT_VRISE: - mv_otg_set_vbus(otg, 1); - break; - case OTG_STATE_A_WAIT_BCON: - if (old_state != OTG_STATE_A_HOST) - mv_otg_start_host(mvotg, 1); - mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER, - T_A_WAIT_BCON, - mv_otg_timer_await_bcon); - /* - * Now, we directly enter A_HOST. So set b_conn = 1 - * here. In fact, it need host driver to notify us. - */ - mvotg->otg_ctrl.b_conn = 1; - break; - case OTG_STATE_A_HOST: - break; - case OTG_STATE_A_WAIT_VFALL: - /* - * Now, we has exited A_HOST. So set b_conn = 0 - * here. In fact, it need host driver to notify us. - */ - mvotg->otg_ctrl.b_conn = 0; - mv_otg_set_vbus(otg, 0); - break; - case OTG_STATE_A_VBUS_ERR: - break; - default: - break; - } - goto run; - } -} - -static irqreturn_t mv_otg_irq(int irq, void *dev) -{ - struct mv_otg *mvotg = dev; - u32 otgsc; - - otgsc = readl(&mvotg->op_regs->otgsc); - writel(otgsc, &mvotg->op_regs->otgsc); - - /* - * if we have vbus, then the vbus detection for B-device - * will be done by mv_otg_inputs_irq(). - */ - if (mvotg->pdata->vbus) - if ((otgsc & OTGSC_STS_USB_ID) && - !(otgsc & OTGSC_INTSTS_USB_ID)) - return IRQ_NONE; - - if ((otgsc & mvotg->irq_status) == 0) - return IRQ_NONE; - - mv_otg_run_state_machine(mvotg, 0); - - return IRQ_HANDLED; -} - -static irqreturn_t mv_otg_inputs_irq(int irq, void *dev) -{ - struct mv_otg *mvotg = dev; - - /* The clock may disabled at this time */ - if (!mvotg->active) { - mv_otg_enable(mvotg); - mv_otg_init_irq(mvotg); - } - - mv_otg_run_state_machine(mvotg, 0); - - return IRQ_HANDLED; -} - -static ssize_t -get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%d\n", - mvotg->otg_ctrl.a_bus_req); -} - -static ssize_t -set_a_bus_req(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - - if (count > 2) - return -1; - - /* We will use this interface to change to A device */ - if (mvotg->phy.state != OTG_STATE_B_IDLE - && mvotg->phy.state != OTG_STATE_A_IDLE) - return -1; - - /* The clock may disabled and we need to set irq for ID detected */ - mv_otg_enable(mvotg); - mv_otg_init_irq(mvotg); - - if (buf[0] == '1') { - mvotg->otg_ctrl.a_bus_req = 1; - mvotg->otg_ctrl.a_bus_drop = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_req = 1\n"); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - } - - return count; -} - -static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, - set_a_bus_req); - -static ssize_t -set_a_clr_err(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - if (!mvotg->phy.otg->default_a) - return -1; - - if (count > 2) - return -1; - - if (buf[0] == '1') { - mvotg->otg_ctrl.a_clr_err = 1; - dev_dbg(&mvotg->pdev->dev, - "User request: a_clr_err = 1\n"); - } - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - - return count; -} - -static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); - -static ssize_t -get_a_bus_drop(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%d\n", - mvotg->otg_ctrl.a_bus_drop); -} - -static ssize_t -set_a_bus_drop(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct mv_otg *mvotg = dev_get_drvdata(dev); - if (!mvotg->phy.otg->default_a) - return -1; - - if (count > 2) - return -1; - - if (buf[0] == '0') { - mvotg->otg_ctrl.a_bus_drop = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_drop = 0\n"); - } else if (buf[0] == '1') { - mvotg->otg_ctrl.a_bus_drop = 1; - mvotg->otg_ctrl.a_bus_req = 0; - dev_dbg(&mvotg->pdev->dev, - "User request: a_bus_drop = 1\n"); - dev_dbg(&mvotg->pdev->dev, - "User request: and a_bus_req = 0\n"); - } - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - - return count; -} - -static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, - get_a_bus_drop, set_a_bus_drop); - -static struct attribute *inputs_attrs[] = { - &dev_attr_a_bus_req.attr, - &dev_attr_a_clr_err.attr, - &dev_attr_a_bus_drop.attr, - NULL, -}; - -static struct attribute_group inputs_attr_group = { - .name = "inputs", - .attrs = inputs_attrs, -}; - -int mv_otg_remove(struct platform_device *pdev) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - - sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); - - if (mvotg->qwork) { - flush_workqueue(mvotg->qwork); - destroy_workqueue(mvotg->qwork); - } - - mv_otg_disable(mvotg); - - usb_remove_phy(&mvotg->phy); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static int mv_otg_probe(struct platform_device *pdev) -{ - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; - struct mv_otg *mvotg; - struct usb_otg *otg; - struct resource *r; - int retval = 0, clk_i, i; - size_t size; - - if (pdata == NULL) { - dev_err(&pdev->dev, "failed to get platform data\n"); - return -ENODEV; - } - - size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; - mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!mvotg) { - dev_err(&pdev->dev, "failed to allocate memory!\n"); - return -ENOMEM; - } - - otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - platform_set_drvdata(pdev, mvotg); - - mvotg->pdev = pdev; - mvotg->pdata = pdata; - - mvotg->clknum = pdata->clknum; - for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { - mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, - pdata->clkname[clk_i]); - if (IS_ERR(mvotg->clk[clk_i])) { - retval = PTR_ERR(mvotg->clk[clk_i]); - return retval; - } - } - - mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); - if (!mvotg->qwork) { - dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); - return -ENOMEM; - } - - INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); - - /* OTG common part */ - mvotg->pdev = pdev; - mvotg->phy.dev = &pdev->dev; - mvotg->phy.otg = otg; - mvotg->phy.label = driver_name; - mvotg->phy.state = OTG_STATE_UNDEFINED; - - otg->phy = &mvotg->phy; - otg->set_host = mv_otg_set_host; - otg->set_peripheral = mv_otg_set_peripheral; - otg->set_vbus = mv_otg_set_vbus; - - for (i = 0; i < OTG_TIMER_NUM; i++) - init_timer(&mvotg->otg_ctrl.timer[i]); - - r = platform_get_resource_byname(mvotg->pdev, - IORESOURCE_MEM, "phyregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_destroy_workqueue; - } - - mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (mvotg->phy_regs == NULL) { - dev_err(&pdev->dev, "failed to map phy I/O memory\n"); - retval = -EFAULT; - goto err_destroy_workqueue; - } - - r = platform_get_resource_byname(mvotg->pdev, - IORESOURCE_MEM, "capregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_destroy_workqueue; - } - - mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (mvotg->cap_regs == NULL) { - dev_err(&pdev->dev, "failed to map I/O memory\n"); - retval = -EFAULT; - goto err_destroy_workqueue; - } - - /* we will acces controller register, so enable the udc controller */ - retval = mv_otg_enable_internal(mvotg); - if (retval) { - dev_err(&pdev->dev, "mv otg enable error %d\n", retval); - goto err_destroy_workqueue; - } - - mvotg->op_regs = - (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs - + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); - - if (pdata->id) { - retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, - NULL, mv_otg_inputs_irq, - IRQF_ONESHOT, "id", mvotg); - if (retval) { - dev_info(&pdev->dev, - "Failed to request irq for ID\n"); - pdata->id = NULL; - } - } - - if (pdata->vbus) { - mvotg->clock_gating = 1; - retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, - NULL, mv_otg_inputs_irq, - IRQF_ONESHOT, "vbus", mvotg); - if (retval) { - dev_info(&pdev->dev, - "Failed to request irq for VBUS, " - "disable clock gating\n"); - mvotg->clock_gating = 0; - pdata->vbus = NULL; - } - } - - if (pdata->disable_otg_clock_gating) - mvotg->clock_gating = 0; - - mv_otg_reset(mvotg); - mv_otg_init_irq(mvotg); - - r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); - if (r == NULL) { - dev_err(&pdev->dev, "no IRQ resource defined\n"); - retval = -ENODEV; - goto err_disable_clk; - } - - mvotg->irq = r->start; - if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, - driver_name, mvotg)) { - dev_err(&pdev->dev, "Request irq %d for OTG failed\n", - mvotg->irq); - mvotg->irq = 0; - retval = -ENODEV; - goto err_disable_clk; - } - - retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); - if (retval < 0) { - dev_err(&pdev->dev, "can't register transceiver, %d\n", - retval); - goto err_disable_clk; - } - - retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); - if (retval < 0) { - dev_dbg(&pdev->dev, - "Can't register sysfs attr group: %d\n", retval); - goto err_remove_phy; - } - - spin_lock_init(&mvotg->wq_lock); - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 2 * HZ); - spin_unlock(&mvotg->wq_lock); - } - - dev_info(&pdev->dev, - "successful probe OTG device %s clock gating.\n", - mvotg->clock_gating ? "with" : "without"); - - return 0; - -err_remove_phy: - usb_remove_phy(&mvotg->phy); -err_disable_clk: - mv_otg_disable_internal(mvotg); -err_destroy_workqueue: - flush_workqueue(mvotg->qwork); - destroy_workqueue(mvotg->qwork); - - platform_set_drvdata(pdev, NULL); - - return retval; -} - -#ifdef CONFIG_PM -static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - - if (mvotg->phy.state != OTG_STATE_B_IDLE) { - dev_info(&pdev->dev, - "OTG state is not B_IDLE, it is %d!\n", - mvotg->phy.state); - return -EAGAIN; - } - - if (!mvotg->clock_gating) - mv_otg_disable_internal(mvotg); - - return 0; -} - -static int mv_otg_resume(struct platform_device *pdev) -{ - struct mv_otg *mvotg = platform_get_drvdata(pdev); - u32 otgsc; - - if (!mvotg->clock_gating) { - mv_otg_enable_internal(mvotg); - - otgsc = readl(&mvotg->op_regs->otgsc); - otgsc |= mvotg->irq_en; - writel(otgsc, &mvotg->op_regs->otgsc); - - if (spin_trylock(&mvotg->wq_lock)) { - mv_otg_run_state_machine(mvotg, 0); - spin_unlock(&mvotg->wq_lock); - } - } - return 0; -} -#endif - -static struct platform_driver mv_otg_driver = { - .probe = mv_otg_probe, - .remove = __exit_p(mv_otg_remove), - .driver = { - .owner = THIS_MODULE, - .name = driver_name, - }, -#ifdef CONFIG_PM - .suspend = mv_otg_suspend, - .resume = mv_otg_resume, -#endif -}; -module_platform_driver(mv_otg_driver); diff --git a/drivers/usb/phy/mv_otg.h b/drivers/usb/phy/mv_otg.h deleted file mode 100644 index 8a9e351b36ba..000000000000 --- a/drivers/usb/phy/mv_otg.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. 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. - */ - -#ifndef __MV_USB_OTG_CONTROLLER__ -#define __MV_USB_OTG_CONTROLLER__ - -#include - -/* Command Register Bit Masks */ -#define USBCMD_RUN_STOP (0x00000001) -#define USBCMD_CTRL_RESET (0x00000002) - -/* otgsc Register Bit Masks */ -#define OTGSC_CTRL_VUSB_DISCHARGE 0x00000001 -#define OTGSC_CTRL_VUSB_CHARGE 0x00000002 -#define OTGSC_CTRL_OTG_TERM 0x00000008 -#define OTGSC_CTRL_DATA_PULSING 0x00000010 -#define OTGSC_STS_USB_ID 0x00000100 -#define OTGSC_STS_A_VBUS_VALID 0x00000200 -#define OTGSC_STS_A_SESSION_VALID 0x00000400 -#define OTGSC_STS_B_SESSION_VALID 0x00000800 -#define OTGSC_STS_B_SESSION_END 0x00001000 -#define OTGSC_STS_1MS_TOGGLE 0x00002000 -#define OTGSC_STS_DATA_PULSING 0x00004000 -#define OTGSC_INTSTS_USB_ID 0x00010000 -#define OTGSC_INTSTS_A_VBUS_VALID 0x00020000 -#define OTGSC_INTSTS_A_SESSION_VALID 0x00040000 -#define OTGSC_INTSTS_B_SESSION_VALID 0x00080000 -#define OTGSC_INTSTS_B_SESSION_END 0x00100000 -#define OTGSC_INTSTS_1MS 0x00200000 -#define OTGSC_INTSTS_DATA_PULSING 0x00400000 -#define OTGSC_INTR_USB_ID 0x01000000 -#define OTGSC_INTR_A_VBUS_VALID 0x02000000 -#define OTGSC_INTR_A_SESSION_VALID 0x04000000 -#define OTGSC_INTR_B_SESSION_VALID 0x08000000 -#define OTGSC_INTR_B_SESSION_END 0x10000000 -#define OTGSC_INTR_1MS_TIMER 0x20000000 -#define OTGSC_INTR_DATA_PULSING 0x40000000 - -#define CAPLENGTH_MASK (0xff) - -/* Timer's interval, unit 10ms */ -#define T_A_WAIT_VRISE 100 -#define T_A_WAIT_BCON 2000 -#define T_A_AIDL_BDIS 100 -#define T_A_BIDL_ADIS 20 -#define T_B_ASE0_BRST 400 -#define T_B_SE0_SRP 300 -#define T_B_SRP_FAIL 2000 -#define T_B_DATA_PLS 10 -#define T_B_SRP_INIT 100 -#define T_A_SRP_RSPNS 10 -#define T_A_DRV_RSM 5 - -enum otg_function { - OTG_B_DEVICE = 0, - OTG_A_DEVICE -}; - -enum mv_otg_timer { - A_WAIT_BCON_TIMER = 0, - OTG_TIMER_NUM -}; - -/* PXA OTG state machine */ -struct mv_otg_ctrl { - /* internal variables */ - u8 a_set_b_hnp_en; /* A-Device set b_hnp_en */ - u8 b_srp_done; - u8 b_hnp_en; - - /* OTG inputs */ - u8 a_bus_drop; - u8 a_bus_req; - u8 a_clr_err; - u8 a_bus_resume; - u8 a_bus_suspend; - u8 a_conn; - u8 a_sess_vld; - u8 a_srp_det; - u8 a_vbus_vld; - u8 b_bus_req; /* B-Device Require Bus */ - u8 b_bus_resume; - u8 b_bus_suspend; - u8 b_conn; - u8 b_se0_srp; - u8 b_sess_end; - u8 b_sess_vld; - u8 id; - u8 a_suspend_req; - - /*Timer event */ - u8 a_aidl_bdis_timeout; - u8 b_ase0_brst_timeout; - u8 a_bidl_adis_timeout; - u8 a_wait_bcon_timeout; - - struct timer_list timer[OTG_TIMER_NUM]; -}; - -#define VUSBHS_MAX_PORTS 8 - -struct mv_otg_regs { - u32 usbcmd; /* Command register */ - u32 usbsts; /* Status register */ - u32 usbintr; /* Interrupt enable */ - u32 frindex; /* Frame index */ - u32 reserved1[1]; - u32 deviceaddr; /* Device Address */ - u32 eplistaddr; /* Endpoint List Address */ - u32 ttctrl; /* HOST TT status and control */ - u32 burstsize; /* Programmable Burst Size */ - u32 txfilltuning; /* Host Transmit Pre-Buffer Packet Tuning */ - u32 reserved[4]; - u32 epnak; /* Endpoint NAK */ - u32 epnaken; /* Endpoint NAK Enable */ - u32 configflag; /* Configured Flag register */ - u32 portsc[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */ - u32 otgsc; - u32 usbmode; /* USB Host/Device mode */ - u32 epsetupstat; /* Endpoint Setup Status */ - u32 epprime; /* Endpoint Initialize */ - u32 epflush; /* Endpoint De-initialize */ - u32 epstatus; /* Endpoint Status */ - u32 epcomplete; /* Endpoint Interrupt On Complete */ - u32 epctrlx[16]; /* Endpoint Control, where x = 0.. 15 */ - u32 mcr; /* Mux Control */ - u32 isr; /* Interrupt Status */ - u32 ier; /* Interrupt Enable */ -}; - -struct mv_otg { - struct usb_phy phy; - struct mv_otg_ctrl otg_ctrl; - - /* base address */ - void __iomem *phy_regs; - void __iomem *cap_regs; - struct mv_otg_regs __iomem *op_regs; - - struct platform_device *pdev; - int irq; - u32 irq_status; - u32 irq_en; - - struct delayed_work work; - struct workqueue_struct *qwork; - - spinlock_t wq_lock; - - struct mv_usb_platform_data *pdata; - - unsigned int active; - unsigned int clock_gating; - unsigned int clknum; - struct clk *clk[0]; -}; - -#endif diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c deleted file mode 100644 index 9d8599122aa9..000000000000 --- a/drivers/usb/phy/mv_u3d_phy.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mv_u3d_phy.h" - -/* - * struct mv_u3d_phy - transceiver driver state - * @phy: transceiver structure - * @dev: The parent device supplied to the probe function - * @clk: usb phy clock - * @base: usb phy register memory base - */ -struct mv_u3d_phy { - struct usb_phy phy; - struct mv_usb_platform_data *plat; - struct device *dev; - struct clk *clk; - void __iomem *base; -}; - -static u32 mv_u3d_phy_read(void __iomem *base, u32 reg) -{ - void __iomem *addr, *data; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - return readl_relaxed(data); -} - -static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - u32 tmp; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); - tmp |= value; - writel_relaxed(tmp, data); -} - -static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - u32 tmp; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); - tmp &= ~value; - writel_relaxed(tmp, data); -} - -static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - writel_relaxed(value, data); -} - -void mv_u3d_phy_shutdown(struct usb_phy *phy) -{ - struct mv_u3d_phy *mv_u3d_phy; - void __iomem *base; - u32 val; - - mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); - base = mv_u3d_phy->base; - - /* Power down Reference Analog current, bit 15 - * Power down PLL, bit 14 - * Power down Receiver, bit 13 - * Power down Transmitter, bit 12 - * of USB3_POWER_PLL_CONTROL register - */ - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_PU); - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - - if (mv_u3d_phy->clk) - clk_disable(mv_u3d_phy->clk); -} - -static int mv_u3d_phy_init(struct usb_phy *phy) -{ - struct mv_u3d_phy *mv_u3d_phy; - void __iomem *base; - u32 val, count; - - /* enable usb3 phy */ - mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); - - if (mv_u3d_phy->clk) - clk_enable(mv_u3d_phy->clk); - - base = mv_u3d_phy->base; - - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_PU_MASK); - val |= 0xF << USB3_POWER_PLL_CONTROL_PU_SHIFT; - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - udelay(100); - - mv_u3d_phy_write(base, USB3_RESET_CONTROL, - USB3_RESET_CONTROL_RESET_PIPE); - udelay(100); - - mv_u3d_phy_write(base, USB3_RESET_CONTROL, - USB3_RESET_CONTROL_RESET_PIPE - | USB3_RESET_CONTROL_RESET_PHY); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK - | USB3_POWER_PLL_CONTROL_PHY_MODE_MASK); - val |= (USB3_PLL_25MHZ << USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT) - | (0x5 << USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT); - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - udelay(100); - - mv_u3d_phy_clear(base, USB3_KVCO_CALI_CONTROL, - USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_SQUELCH_FFE); - val &= ~(USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK - | USB3_SQUELCH_FFE_FFE_RES_SEL_MASK - | USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK); - val |= ((0xD << USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT) - | (0x7 << USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT) - | (0x8 << USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT)); - mv_u3d_phy_write(base, USB3_SQUELCH_FFE, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN1_SET0); - val &= ~USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK; - val |= 1 << USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT; - mv_u3d_phy_write(base, USB3_GEN1_SET0, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN2_SET0); - val &= ~(USB3_GEN2_SET0_G2_TX_AMP_MASK - | USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK - | USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK); - val |= ((0x14 << USB3_GEN2_SET0_G2_TX_AMP_SHIFT) - | (1 << USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT) - | (0xA << USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT) - | (1 << USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT)); - mv_u3d_phy_write(base, USB3_GEN2_SET0, val); - udelay(100); - - mv_u3d_phy_read(base, USB3_TX_EMPPH); - val &= ~(USB3_TX_EMPPH_AMP_MASK - | USB3_TX_EMPPH_EN_MASK - | USB3_TX_EMPPH_AMP_FORCE_MASK - | USB3_TX_EMPPH_PAR1_MASK - | USB3_TX_EMPPH_PAR2_MASK); - val |= ((0xB << USB3_TX_EMPPH_AMP_SHIFT) - | (1 << USB3_TX_EMPPH_EN_SHIFT) - | (1 << USB3_TX_EMPPH_AMP_FORCE_SHIFT) - | (0x1C << USB3_TX_EMPPH_PAR1_SHIFT) - | (1 << USB3_TX_EMPPH_PAR2_SHIFT)); - - mv_u3d_phy_write(base, USB3_TX_EMPPH, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN2_SET1); - val &= ~(USB3_GEN2_SET1_G2_RX_SELMUPI_MASK - | USB3_GEN2_SET1_G2_RX_SELMUPF_MASK - | USB3_GEN2_SET1_G2_RX_SELMUFI_MASK - | USB3_GEN2_SET1_G2_RX_SELMUFF_MASK); - val |= ((1 << USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT)); - mv_u3d_phy_write(base, USB3_GEN2_SET1, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_DIGITAL_LOOPBACK_EN); - val &= ~USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK; - val |= 1 << USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT; - mv_u3d_phy_write(base, USB3_DIGITAL_LOOPBACK_EN, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_IMPEDANCE_TX_SSC); - val &= ~USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK; - val |= 0xC << USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT; - mv_u3d_phy_write(base, USB3_IMPEDANCE_TX_SSC, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_IMPEDANCE_CALI_CTRL); - val &= ~USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK; - val |= 0x4 << USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT; - mv_u3d_phy_write(base, USB3_IMPEDANCE_CALI_CTRL, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_PHY_ISOLATION_MODE); - val &= ~(USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK - | USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK - | USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK); - val |= ((1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT) - | (1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT)); - mv_u3d_phy_write(base, USB3_PHY_ISOLATION_MODE, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_TXDETRX); - val &= ~(USB3_TXDETRX_VTHSEL_MASK); - val |= 0x1 << USB3_TXDETRX_VTHSEL_SHIFT; - mv_u3d_phy_write(base, USB3_TXDETRX, val); - udelay(100); - - dev_dbg(mv_u3d_phy->dev, "start calibration\n"); - -calstart: - /* Perform Manual Calibration */ - mv_u3d_phy_set(base, USB3_KVCO_CALI_CONTROL, - 1 << USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT); - - mdelay(1); - - count = 0; - while (1) { - val = mv_u3d_phy_read(base, USB3_KVCO_CALI_CONTROL); - if (val & (1 << USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT)) - break; - else if (count > 50) { - dev_dbg(mv_u3d_phy->dev, "calibration failure, retry...\n"); - goto calstart; - } - count++; - mdelay(1); - } - - /* active PIPE interface */ - mv_u3d_phy_write(base, USB3_PIPE_SM_CTRL, - 1 << USB3_PIPE_SM_CTRL_PHY_INIT_DONE); - - return 0; -} - -static int mv_u3d_phy_probe(struct platform_device *pdev) -{ - struct mv_u3d_phy *mv_u3d_phy; - struct mv_usb_platform_data *pdata; - struct device *dev = &pdev->dev; - struct resource *res; - void __iomem *phy_base; - int ret; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "%s: no platform data defined\n", __func__); - return -EINVAL; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing mem resource\n"); - return -ENODEV; - } - - phy_base = devm_ioremap_resource(dev, res); - if (IS_ERR(phy_base)) - return PTR_ERR(phy_base); - - mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL); - if (!mv_u3d_phy) - return -ENOMEM; - - mv_u3d_phy->dev = &pdev->dev; - mv_u3d_phy->plat = pdata; - mv_u3d_phy->base = phy_base; - mv_u3d_phy->phy.dev = mv_u3d_phy->dev; - mv_u3d_phy->phy.label = "mv-u3d-phy"; - mv_u3d_phy->phy.init = mv_u3d_phy_init; - mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown; - - ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3); - if (ret) - goto err; - - if (!mv_u3d_phy->clk) - mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy"); - - platform_set_drvdata(pdev, mv_u3d_phy); - - dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n"); -err: - return ret; -} - -static int __exit mv_u3d_phy_remove(struct platform_device *pdev) -{ - struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev); - - usb_remove_phy(&mv_u3d_phy->phy); - - if (mv_u3d_phy->clk) { - clk_put(mv_u3d_phy->clk); - mv_u3d_phy->clk = NULL; - } - - return 0; -} - -static struct platform_driver mv_u3d_phy_driver = { - .probe = mv_u3d_phy_probe, - .remove = mv_u3d_phy_remove, - .driver = { - .name = "mv-u3d-phy", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(mv_u3d_phy_driver); -MODULE_DESCRIPTION("Marvell USB 3.0 PHY controller"); -MODULE_AUTHOR("Yu Xu "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mv-u3d-phy"); diff --git a/drivers/usb/phy/mv_u3d_phy.h b/drivers/usb/phy/mv_u3d_phy.h deleted file mode 100644 index 2a658cb9a527..000000000000 --- a/drivers/usb/phy/mv_u3d_phy.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. 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. - */ - -#ifndef __MV_U3D_PHY_H -#define __MV_U3D_PHY_H - -#define USB3_POWER_PLL_CONTROL 0x1 -#define USB3_KVCO_CALI_CONTROL 0x2 -#define USB3_IMPEDANCE_CALI_CTRL 0x3 -#define USB3_IMPEDANCE_TX_SSC 0x4 -#define USB3_SQUELCH_FFE 0x6 -#define USB3_GEN1_SET0 0xD -#define USB3_GEN2_SET0 0xF -#define USB3_GEN2_SET1 0x10 -#define USB3_DIGITAL_LOOPBACK_EN 0x23 -#define USB3_PHY_ISOLATION_MODE 0x26 -#define USB3_TXDETRX 0x48 -#define USB3_TX_EMPPH 0x5E -#define USB3_RESET_CONTROL 0x90 -#define USB3_PIPE_SM_CTRL 0x91 - -#define USB3_RESET_CONTROL_RESET_PIPE 0x1 -#define USB3_RESET_CONTROL_RESET_PHY 0x2 - -#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK (0x1F << 0) -#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT 0 -#define USB3_PLL_25MHZ 0x2 -#define USB3_PLL_26MHZ 0x5 -#define USB3_POWER_PLL_CONTROL_PHY_MODE_MASK (0x7 << 5) -#define USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT 5 -#define USB3_POWER_PLL_CONTROL_PU_MASK (0xF << 12) -#define USB3_POWER_PLL_CONTROL_PU_SHIFT 12 -#define USB3_POWER_PLL_CONTROL_PU (0xF << 12) - -#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK (0x1 << 12) -#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_SHIFT 12 -#define USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT 14 -#define USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT 15 - -#define USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK 0xF -#define USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT 0 -#define USB3_SQUELCH_FFE_FFE_RES_SEL_MASK (0x7 << 4) -#define USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT 4 -#define USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK (0x1F << 8) -#define USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT 8 - -#define USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK (0x1 << 15) -#define USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT 11 - -#define USB3_GEN2_SET0_G2_TX_AMP_MASK (0x1F << 1) -#define USB3_GEN2_SET0_G2_TX_AMP_SHIFT 1 -#define USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT 6 -#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK (0xF << 7) -#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT 7 -#define USB3_GEN2_SET0_G2_TX_EMPH_EN_MASK (0x1 << 11) -#define USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT 11 -#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK (0x1 << 15) -#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_SHIFT 15 - -#define USB3_GEN2_SET1_G2_RX_SELMUPI_MASK (0x7 << 0) -#define USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT 0 -#define USB3_GEN2_SET1_G2_RX_SELMUPF_MASK (0x7 << 3) -#define USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT 3 -#define USB3_GEN2_SET1_G2_RX_SELMUFI_MASK (0x3 << 6) -#define USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT 6 -#define USB3_GEN2_SET1_G2_RX_SELMUFF_MASK (0x3 << 8) -#define USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT 8 - -#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK (0x3 << 10) -#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT 10 - -#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK (0x7 << 12) -#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT 12 - -#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK (0x3F << 0) -#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT 0 - -#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK 0xF -#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT 0 -#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK (0xF << 4) -#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT 4 -#define USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK (0x1 << 8) - -#define USB3_TXDETRX_VTHSEL_MASK (0x3 << 4) -#define USB3_TXDETRX_VTHSEL_SHIFT 4 - -#define USB3_TX_EMPPH_AMP_MASK (0xF << 0) -#define USB3_TX_EMPPH_AMP_SHIFT 0 -#define USB3_TX_EMPPH_EN_MASK (0x1 << 6) -#define USB3_TX_EMPPH_EN_SHIFT 6 -#define USB3_TX_EMPPH_AMP_FORCE_MASK (0x1 << 7) -#define USB3_TX_EMPPH_AMP_FORCE_SHIFT 7 -#define USB3_TX_EMPPH_PAR1_MASK (0x1F << 8) -#define USB3_TX_EMPPH_PAR1_SHIFT 8 -#define USB3_TX_EMPPH_PAR2_MASK (0x1 << 13) -#define USB3_TX_EMPPH_PAR2_SHIFT 13 - -#define USB3_PIPE_SM_CTRL_PHY_INIT_DONE 15 - -#endif /* __MV_U3D_PHY_H */ diff --git a/drivers/usb/phy/mxs-phy.c b/drivers/usb/phy/mxs-phy.c deleted file mode 100644 index 9d4381e64d51..000000000000 --- a/drivers/usb/phy/mxs-phy.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Marek Vasut - * on behalf of DENX Software Engineering GmbH - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "mxs_phy" - -#define HW_USBPHY_PWD 0x00 -#define HW_USBPHY_CTRL 0x30 -#define HW_USBPHY_CTRL_SET 0x34 -#define HW_USBPHY_CTRL_CLR 0x38 - -#define BM_USBPHY_CTRL_SFTRST BIT(31) -#define BM_USBPHY_CTRL_CLKGATE BIT(30) -#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) -#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) -#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) - -struct mxs_phy { - struct usb_phy phy; - struct clk *clk; -}; - -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) - -static void mxs_phy_hw_init(struct mxs_phy *mxs_phy) -{ - void __iomem *base = mxs_phy->phy.io_priv; - - stmp_reset_block(base + HW_USBPHY_CTRL); - - /* Power up the PHY */ - writel(0, base + HW_USBPHY_PWD); - - /* enable FS/LS device */ - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | - BM_USBPHY_CTRL_ENUTMILEVEL3, - base + HW_USBPHY_CTRL_SET); -} - -static int mxs_phy_init(struct usb_phy *phy) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(phy); - - clk_prepare_enable(mxs_phy->clk); - mxs_phy_hw_init(mxs_phy); - - return 0; -} - -static void mxs_phy_shutdown(struct usb_phy *phy) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(phy); - - writel(BM_USBPHY_CTRL_CLKGATE, - phy->io_priv + HW_USBPHY_CTRL_SET); - - clk_disable_unprepare(mxs_phy->clk); -} - -static int mxs_phy_suspend(struct usb_phy *x, int suspend) -{ - struct mxs_phy *mxs_phy = to_mxs_phy(x); - - if (suspend) { - writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); - writel(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_SET); - clk_disable_unprepare(mxs_phy->clk); - } else { - clk_prepare_enable(mxs_phy->clk); - writel(BM_USBPHY_CTRL_CLKGATE, - x->io_priv + HW_USBPHY_CTRL_CLR); - writel(0, x->io_priv + HW_USBPHY_PWD); - } - - return 0; -} - -static int mxs_phy_on_connect(struct usb_phy *phy, - enum usb_device_speed speed) -{ - dev_dbg(phy->dev, "%s speed device has connected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - - if (speed == USB_SPEED_HIGH) - writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_SET); - - return 0; -} - -static int mxs_phy_on_disconnect(struct usb_phy *phy, - enum usb_device_speed speed) -{ - dev_dbg(phy->dev, "%s speed device has disconnected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - - if (speed == USB_SPEED_HIGH) - writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_CLR); - - return 0; -} - -static int mxs_phy_probe(struct platform_device *pdev) -{ - struct resource *res; - void __iomem *base; - struct clk *clk; - struct mxs_phy *mxs_phy; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "can't get device resources\n"); - return -ENOENT; - } - - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, - "can't get the clock, err=%ld", PTR_ERR(clk)); - return PTR_ERR(clk); - } - - mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); - if (!mxs_phy) { - dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); - return -ENOMEM; - } - - mxs_phy->phy.io_priv = base; - mxs_phy->phy.dev = &pdev->dev; - mxs_phy->phy.label = DRIVER_NAME; - mxs_phy->phy.init = mxs_phy_init; - mxs_phy->phy.shutdown = mxs_phy_shutdown; - mxs_phy->phy.set_suspend = mxs_phy_suspend; - mxs_phy->phy.notify_connect = mxs_phy_on_connect; - mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; - - ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); - - mxs_phy->clk = clk; - - platform_set_drvdata(pdev, &mxs_phy->phy); - - ret = usb_add_phy_dev(&mxs_phy->phy); - if (ret) - return ret; - - return 0; -} - -static int mxs_phy_remove(struct platform_device *pdev) -{ - struct mxs_phy *mxs_phy = platform_get_drvdata(pdev); - - usb_remove_phy(&mxs_phy->phy); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id mxs_phy_dt_ids[] = { - { .compatible = "fsl,imx23-usbphy", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); - -static struct platform_driver mxs_phy_driver = { - .probe = mxs_phy_probe, - .remove = mxs_phy_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = mxs_phy_dt_ids, - }, -}; - -static int __init mxs_phy_module_init(void) -{ - return platform_driver_register(&mxs_phy_driver); -} -postcore_initcall(mxs_phy_module_init); - -static void __exit mxs_phy_module_exit(void) -{ - platform_driver_unregister(&mxs_phy_driver); -} -module_exit(mxs_phy_module_exit); - -MODULE_ALIAS("platform:mxs-usb-phy"); -MODULE_AUTHOR("Marek Vasut "); -MODULE_AUTHOR("Richard Zhao "); -MODULE_DESCRIPTION("Freescale MXS USB PHY driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/nop-usb-xceiv.c b/drivers/usb/phy/nop-usb-xceiv.c deleted file mode 100644 index 2b10cc969bbb..000000000000 --- a/drivers/usb/phy/nop-usb-xceiv.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * drivers/usb/otg/nop-usb-xceiv.c - * - * NOP USB transceiver for all USB transceiver which are either built-in - * into USB IP or which are mostly autonomous. - * - * Copyright (C) 2009 Texas Instruments Inc - * Author: Ajay Kumar Gupta - * - * 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. - * - * Current status: - * This provides a "nop" transceiver for PHYs which are - * autonomous such as isp1504, isp1707, etc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct nop_usb_xceiv { - struct usb_phy phy; - struct device *dev; - struct clk *clk; - struct regulator *vcc; - struct regulator *reset; -}; - -static struct platform_device *pd; - -void usb_nop_xceiv_register(void) -{ - if (pd) - return; - pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); - if (!pd) { - printk(KERN_ERR "Unable to register usb nop transceiver\n"); - return; - } -} -EXPORT_SYMBOL(usb_nop_xceiv_register); - -void usb_nop_xceiv_unregister(void) -{ - platform_device_unregister(pd); - pd = NULL; -} -EXPORT_SYMBOL(usb_nop_xceiv_unregister); - -static int nop_set_suspend(struct usb_phy *x, int suspend) -{ - return 0; -} - -static int nop_init(struct usb_phy *phy) -{ - struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); - - if (!IS_ERR(nop->vcc)) { - if (regulator_enable(nop->vcc)) - dev_err(phy->dev, "Failed to enable power\n"); - } - - if (!IS_ERR(nop->clk)) - clk_enable(nop->clk); - - if (!IS_ERR(nop->reset)) { - /* De-assert RESET */ - if (regulator_enable(nop->reset)) - dev_err(phy->dev, "Failed to de-assert reset\n"); - } - - return 0; -} - -static void nop_shutdown(struct usb_phy *phy) -{ - struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); - - if (!IS_ERR(nop->reset)) { - /* Assert RESET */ - if (regulator_disable(nop->reset)) - dev_err(phy->dev, "Failed to assert reset\n"); - } - - if (!IS_ERR(nop->clk)) - clk_disable(nop->clk); - - if (!IS_ERR(nop->vcc)) { - if (regulator_disable(nop->vcc)) - dev_err(phy->dev, "Failed to disable power\n"); - } -} - -static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) -{ - if (!otg) - return -ENODEV; - - if (!gadget) { - otg->gadget = NULL; - return -ENODEV; - } - - otg->gadget = gadget; - otg->phy->state = OTG_STATE_B_IDLE; - return 0; -} - -static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - if (!host) { - otg->host = NULL; - return -ENODEV; - } - - otg->host = host; - return 0; -} - -static int nop_usb_xceiv_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; - struct nop_usb_xceiv *nop; - enum usb_phy_type type = USB_PHY_TYPE_USB2; - int err; - u32 clk_rate = 0; - bool needs_vcc = false; - bool needs_reset = false; - - nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); - if (!nop) - return -ENOMEM; - - nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), - GFP_KERNEL); - if (!nop->phy.otg) - return -ENOMEM; - - if (dev->of_node) { - struct device_node *node = dev->of_node; - - if (of_property_read_u32(node, "clock-frequency", &clk_rate)) - clk_rate = 0; - - needs_vcc = of_property_read_bool(node, "vcc-supply"); - needs_reset = of_property_read_bool(node, "reset-supply"); - - } else if (pdata) { - type = pdata->type; - clk_rate = pdata->clk_rate; - needs_vcc = pdata->needs_vcc; - needs_reset = pdata->needs_reset; - } - - nop->clk = devm_clk_get(&pdev->dev, "main_clk"); - if (IS_ERR(nop->clk)) { - dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", - PTR_ERR(nop->clk)); - } - - if (!IS_ERR(nop->clk) && clk_rate) { - err = clk_set_rate(nop->clk, clk_rate); - if (err) { - dev_err(&pdev->dev, "Error setting clock rate\n"); - return err; - } - } - - if (!IS_ERR(nop->clk)) { - err = clk_prepare(nop->clk); - if (err) { - dev_err(&pdev->dev, "Error preparing clock\n"); - return err; - } - } - - nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); - if (IS_ERR(nop->vcc)) { - dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", - PTR_ERR(nop->vcc)); - if (needs_vcc) - return -EPROBE_DEFER; - } - - nop->reset = devm_regulator_get(&pdev->dev, "reset"); - if (IS_ERR(nop->reset)) { - dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", - PTR_ERR(nop->reset)); - if (needs_reset) - return -EPROBE_DEFER; - } - - nop->dev = &pdev->dev; - nop->phy.dev = nop->dev; - nop->phy.label = "nop-xceiv"; - nop->phy.set_suspend = nop_set_suspend; - nop->phy.init = nop_init; - nop->phy.shutdown = nop_shutdown; - nop->phy.state = OTG_STATE_UNDEFINED; - nop->phy.type = type; - - nop->phy.otg->phy = &nop->phy; - nop->phy.otg->set_host = nop_set_host; - nop->phy.otg->set_peripheral = nop_set_peripheral; - - err = usb_add_phy_dev(&nop->phy); - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); - goto err_add; - } - - platform_set_drvdata(pdev, nop); - - ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); - - return 0; - -err_add: - if (!IS_ERR(nop->clk)) - clk_unprepare(nop->clk); - return err; -} - -static int nop_usb_xceiv_remove(struct platform_device *pdev) -{ - struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); - - if (!IS_ERR(nop->clk)) - clk_unprepare(nop->clk); - - usb_remove_phy(&nop->phy); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static const struct of_device_id nop_xceiv_dt_ids[] = { - { .compatible = "usb-nop-xceiv" }, - { } -}; - -MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); - -static struct platform_driver nop_usb_xceiv_driver = { - .probe = nop_usb_xceiv_probe, - .remove = nop_usb_xceiv_remove, - .driver = { - .name = "nop_usb_xceiv", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(nop_xceiv_dt_ids), - }, -}; - -static int __init nop_usb_xceiv_init(void) -{ - return platform_driver_register(&nop_usb_xceiv_driver); -} -subsys_initcall(nop_usb_xceiv_init); - -static void __exit nop_usb_xceiv_exit(void) -{ - platform_driver_unregister(&nop_usb_xceiv_driver); -} -module_exit(nop_usb_xceiv_exit); - -MODULE_ALIAS("platform:nop_usb_xceiv"); -MODULE_AUTHOR("Texas Instruments Inc"); -MODULE_DESCRIPTION("NOP USB Transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/omap-control-usb.c b/drivers/usb/phy/omap-control-usb.c deleted file mode 100644 index 1419ceda9759..000000000000 --- a/drivers/usb/phy/omap-control-usb.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * omap-control-usb.c - The USB part of control module. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT 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 - -static struct omap_control_usb *control_usb; - -/** - * omap_get_control_dev - returns the device pointer for this control device - * - * This API should be called to get the device pointer for this control - * module device. This device pointer should be used for called other - * exported API's in this driver. - * - * To be used by PHY driver and glue driver. - */ -struct device *omap_get_control_dev(void) -{ - if (!control_usb) - return ERR_PTR(-ENODEV); - - return control_usb->dev; -} -EXPORT_SYMBOL_GPL(omap_get_control_dev); - -/** - * omap_control_usb3_phy_power - power on/off the serializer using control - * module - * @dev: the control module device - * @on: 0 to off and 1 to on based on powering on or off the PHY - * - * usb3 PHY driver should call this API to power on or off the PHY. - */ -void omap_control_usb3_phy_power(struct device *dev, bool on) -{ - u32 val; - unsigned long rate; - struct omap_control_usb *control_usb = dev_get_drvdata(dev); - - if (control_usb->type != OMAP_CTRL_DEV_TYPE2) - return; - - rate = clk_get_rate(control_usb->sys_clk); - rate = rate/1000000; - - val = readl(control_usb->phy_power); - - if (on) { - val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | - OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); - val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << - OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; - val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; - } else { - val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; - val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << - OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; - } - - writel(val, control_usb->phy_power); -} -EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power); - -/** - * omap_control_usb_phy_power - power on/off the phy using control module reg - * @dev: the control module device - * @on: 0 or 1, based on powering on or off the PHY - */ -void omap_control_usb_phy_power(struct device *dev, int on) -{ - u32 val; - struct omap_control_usb *control_usb = dev_get_drvdata(dev); - - val = readl(control_usb->dev_conf); - - if (on) - val &= ~OMAP_CTRL_DEV_PHY_PD; - else - val |= OMAP_CTRL_DEV_PHY_PD; - - writel(val, control_usb->dev_conf); -} -EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); - -/** - * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded - * @ctrl_usb: struct omap_control_usb * - * - * Writes to the mailbox register to notify the usb core that a usb - * device has been connected. - */ -static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb) -{ - u32 val; - - val = readl(ctrl_usb->otghs_control); - val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); - val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; - writel(val, ctrl_usb->otghs_control); -} - -/** - * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high - * impedance - * @ctrl_usb: struct omap_control_usb * - * - * Writes to the mailbox register to notify the usb core that it has been - * connected to a usb host. - */ -static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb) -{ - u32 val; - - val = readl(ctrl_usb->otghs_control); - val &= ~OMAP_CTRL_DEV_SESSEND; - val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | - OMAP_CTRL_DEV_VBUSVALID; - writel(val, ctrl_usb->otghs_control); -} - -/** - * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high - * impedance - * @ctrl_usb: struct omap_control_usb * - * - * Writes to the mailbox register to notify the usb core it's now in - * disconnected state. - */ -static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) -{ - u32 val; - - val = readl(ctrl_usb->otghs_control); - val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); - val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; - writel(val, ctrl_usb->otghs_control); -} - -/** - * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode - * or device mode or to denote disconnected state - * @dev: the control module device - * @mode: The mode to which usb should be configured - * - * This is an API to write to the mailbox register to notify the usb core that - * a usb device has been connected. - */ -void omap_control_usb_set_mode(struct device *dev, - enum omap_control_usb_mode mode) -{ - struct omap_control_usb *ctrl_usb; - - if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1) - return; - - ctrl_usb = dev_get_drvdata(dev); - - switch (mode) { - case USB_MODE_HOST: - omap_control_usb_host_mode(ctrl_usb); - break; - case USB_MODE_DEVICE: - omap_control_usb_device_mode(ctrl_usb); - break; - case USB_MODE_DISCONNECT: - omap_control_usb_set_sessionend(ctrl_usb); - break; - default: - dev_vdbg(dev, "invalid omap control usb mode\n"); - } -} -EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); - -static int omap_control_usb_probe(struct platform_device *pdev) -{ - struct resource *res; - struct device_node *np = pdev->dev.of_node; - struct omap_control_usb_platform_data *pdata = pdev->dev.platform_data; - - control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), - GFP_KERNEL); - if (!control_usb) { - dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); - return -ENOMEM; - } - - if (np) { - of_property_read_u32(np, "ti,type", &control_usb->type); - } else if (pdata) { - control_usb->type = pdata->type; - } else { - dev_err(&pdev->dev, "no pdata present\n"); - return -EINVAL; - } - - control_usb->dev = &pdev->dev; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "control_dev_conf"); - control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(control_usb->dev_conf)) - return PTR_ERR(control_usb->dev_conf); - - if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "otghs_control"); - control_usb->otghs_control = devm_ioremap_resource( - &pdev->dev, res); - if (IS_ERR(control_usb->otghs_control)) - return PTR_ERR(control_usb->otghs_control); - } - - if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "phy_power_usb"); - control_usb->phy_power = devm_ioremap_resource( - &pdev->dev, res); - if (IS_ERR(control_usb->phy_power)) - return PTR_ERR(control_usb->phy_power); - - control_usb->sys_clk = devm_clk_get(control_usb->dev, - "sys_clkin"); - if (IS_ERR(control_usb->sys_clk)) { - pr_err("%s: unable to get sys_clkin\n", __func__); - return -EINVAL; - } - } - - - dev_set_drvdata(control_usb->dev, control_usb); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id omap_control_usb_id_table[] = { - { .compatible = "ti,omap-control-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); -#endif - -static struct platform_driver omap_control_usb_driver = { - .probe = omap_control_usb_probe, - .driver = { - .name = "omap-control-usb", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(omap_control_usb_id_table), - }, -}; - -static int __init omap_control_usb_init(void) -{ - return platform_driver_register(&omap_control_usb_driver); -} -subsys_initcall(omap_control_usb_init); - -static void __exit omap_control_usb_exit(void) -{ - platform_driver_unregister(&omap_control_usb_driver); -} -module_exit(omap_control_usb_exit); - -MODULE_ALIAS("platform: omap_control_usb"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("OMAP Control Module USB Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c deleted file mode 100644 index 844ab68f08d0..000000000000 --- a/drivers/usb/phy/omap-usb2.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * omap-usb2.c - USB PHY, talking to musb controller in OMAP. - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * omap_usb2_set_comparator - links the comparator present in the sytem with - * this phy - * @comparator - the companion phy(comparator) for this phy - * - * The phy companion driver should call this API passing the phy_companion - * filled with set_vbus and start_srp to be used by usb phy. - * - * For use by phy companion driver - */ -int omap_usb2_set_comparator(struct phy_companion *comparator) -{ - struct omap_usb *phy; - struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2); - - if (IS_ERR(x)) - return -ENODEV; - - phy = phy_to_omapusb(x); - phy->comparator = comparator; - return 0; -} -EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); - -static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) -{ - struct omap_usb *phy = phy_to_omapusb(otg->phy); - - if (!phy->comparator) - return -ENODEV; - - return phy->comparator->set_vbus(phy->comparator, enabled); -} - -static int omap_usb_start_srp(struct usb_otg *otg) -{ - struct omap_usb *phy = phy_to_omapusb(otg->phy); - - if (!phy->comparator) - return -ENODEV; - - return phy->comparator->start_srp(phy->comparator); -} - -static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct usb_phy *phy = otg->phy; - - otg->host = host; - if (!host) - phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int omap_usb_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - struct usb_phy *phy = otg->phy; - - otg->gadget = gadget; - if (!gadget) - phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int omap_usb2_suspend(struct usb_phy *x, int suspend) -{ - u32 ret; - struct omap_usb *phy = phy_to_omapusb(x); - - if (suspend && !phy->is_suspended) { - omap_control_usb_phy_power(phy->control_dev, 0); - pm_runtime_put_sync(phy->dev); - phy->is_suspended = 1; - } else if (!suspend && phy->is_suspended) { - ret = pm_runtime_get_sync(phy->dev); - if (ret < 0) { - dev_err(phy->dev, "get_sync failed with err %d\n", - ret); - return ret; - } - omap_control_usb_phy_power(phy->control_dev, 1); - phy->is_suspended = 0; - } - - return 0; -} - -static int omap_usb2_probe(struct platform_device *pdev) -{ - struct omap_usb *phy; - struct usb_otg *otg; - - phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); - if (!phy) { - dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); - return -ENOMEM; - } - - otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); - if (!otg) { - dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); - return -ENOMEM; - } - - phy->dev = &pdev->dev; - - phy->phy.dev = phy->dev; - phy->phy.label = "omap-usb2"; - phy->phy.set_suspend = omap_usb2_suspend; - phy->phy.otg = otg; - phy->phy.type = USB_PHY_TYPE_USB2; - - phy->control_dev = omap_get_control_dev(); - if (IS_ERR(phy->control_dev)) { - dev_dbg(&pdev->dev, "Failed to get control device\n"); - return -ENODEV; - } - - phy->is_suspended = 1; - omap_control_usb_phy_power(phy->control_dev, 0); - - otg->set_host = omap_usb_set_host; - otg->set_peripheral = omap_usb_set_peripheral; - otg->set_vbus = omap_usb_set_vbus; - otg->start_srp = omap_usb_start_srp; - otg->phy = &phy->phy; - - phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); - if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); - return PTR_ERR(phy->wkupclk); - } - clk_prepare(phy->wkupclk); - - phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); - if (IS_ERR(phy->optclk)) - dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); - else - clk_prepare(phy->optclk); - - usb_add_phy_dev(&phy->phy); - - platform_set_drvdata(pdev, phy); - - pm_runtime_enable(phy->dev); - - return 0; -} - -static int omap_usb2_remove(struct platform_device *pdev) -{ - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_unprepare(phy->wkupclk); - if (!IS_ERR(phy->optclk)) - clk_unprepare(phy->optclk); - usb_remove_phy(&phy->phy); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME - -static int omap_usb2_runtime_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_disable(phy->wkupclk); - if (!IS_ERR(phy->optclk)) - clk_disable(phy->optclk); - - return 0; -} - -static int omap_usb2_runtime_resume(struct device *dev) -{ - u32 ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - - ret = clk_enable(phy->wkupclk); - if (ret < 0) { - dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); - goto err0; - } - - if (!IS_ERR(phy->optclk)) { - ret = clk_enable(phy->optclk); - if (ret < 0) { - dev_err(phy->dev, "Failed to enable optclk %d\n", ret); - goto err1; - } - } - - return 0; - -err1: - clk_disable(phy->wkupclk); - -err0: - return ret; -} - -static const struct dev_pm_ops omap_usb2_pm_ops = { - SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, - NULL) -}; - -#define DEV_PM_OPS (&omap_usb2_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif - -#ifdef CONFIG_OF -static const struct of_device_id omap_usb2_id_table[] = { - { .compatible = "ti,omap-usb2" }, - {} -}; -MODULE_DEVICE_TABLE(of, omap_usb2_id_table); -#endif - -static struct platform_driver omap_usb2_driver = { - .probe = omap_usb2_probe, - .remove = omap_usb2_remove, - .driver = { - .name = "omap-usb2", - .owner = THIS_MODULE, - .pm = DEV_PM_OPS, - .of_match_table = of_match_ptr(omap_usb2_id_table), - }, -}; - -module_platform_driver(omap_usb2_driver); - -MODULE_ALIAS("platform: omap_usb2"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("OMAP USB2 phy driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c deleted file mode 100644 index a6e60b1e102e..000000000000 --- a/drivers/usb/phy/omap-usb3.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_SYS_CLKS 5 -#define PLL_STATUS 0x00000004 -#define PLL_GO 0x00000008 -#define PLL_CONFIGURATION1 0x0000000C -#define PLL_CONFIGURATION2 0x00000010 -#define PLL_CONFIGURATION3 0x00000014 -#define PLL_CONFIGURATION4 0x00000020 - -#define PLL_REGM_MASK 0x001FFE00 -#define PLL_REGM_SHIFT 0x9 -#define PLL_REGM_F_MASK 0x0003FFFF -#define PLL_REGM_F_SHIFT 0x0 -#define PLL_REGN_MASK 0x000001FE -#define PLL_REGN_SHIFT 0x1 -#define PLL_SELFREQDCO_MASK 0x0000000E -#define PLL_SELFREQDCO_SHIFT 0x1 -#define PLL_SD_MASK 0x0003FC00 -#define PLL_SD_SHIFT 0x9 -#define SET_PLL_GO 0x1 -#define PLL_TICOPWDN 0x10000 -#define PLL_LOCK 0x2 -#define PLL_IDLE 0x1 - -/* - * This is an Empirical value that works, need to confirm the actual - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status - * to be correctly reflected in the USB3PHY_PLL_STATUS register. - */ -# define PLL_IDLE_TIME 100; - -enum sys_clk_rate { - CLK_RATE_UNDEFINED = -1, - CLK_RATE_12MHZ, - CLK_RATE_16MHZ, - CLK_RATE_19MHZ, - CLK_RATE_26MHZ, - CLK_RATE_38MHZ -}; - -static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = { - {1250, 5, 4, 20, 0}, /* 12 MHz */ - {3125, 20, 4, 20, 0}, /* 16.8 MHz */ - {1172, 8, 4, 20, 65537}, /* 19.2 MHz */ - {1250, 12, 4, 20, 0}, /* 26 MHz */ - {3125, 47, 4, 20, 92843}, /* 38.4 MHz */ -}; - -static int omap_usb3_suspend(struct usb_phy *x, int suspend) -{ - struct omap_usb *phy = phy_to_omapusb(x); - int val; - int timeout = PLL_IDLE_TIME; - - if (suspend && !phy->is_suspended) { - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - val |= PLL_IDLE; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - - do { - val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); - if (val & PLL_TICOPWDN) - break; - udelay(1); - } while (--timeout); - - omap_control_usb3_phy_power(phy->control_dev, 0); - - phy->is_suspended = 1; - } else if (!suspend && phy->is_suspended) { - phy->is_suspended = 0; - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - val &= ~PLL_IDLE; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - - do { - val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); - if (!(val & PLL_TICOPWDN)) - break; - udelay(1); - } while (--timeout); - } - - return 0; -} - -static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate) -{ - switch (rate) { - case 12000000: - return CLK_RATE_12MHZ; - case 16800000: - return CLK_RATE_16MHZ; - case 19200000: - return CLK_RATE_19MHZ; - case 26000000: - return CLK_RATE_26MHZ; - case 38400000: - return CLK_RATE_38MHZ; - default: - return CLK_RATE_UNDEFINED; - } -} - -static void omap_usb_dpll_relock(struct omap_usb *phy) -{ - u32 val; - unsigned long timeout; - - omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); - - timeout = jiffies + msecs_to_jiffies(20); - do { - val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); - if (val & PLL_LOCK) - break; - } while (!WARN_ON(time_after(jiffies, timeout))); -} - -static int omap_usb_dpll_lock(struct omap_usb *phy) -{ - u32 val; - unsigned long rate; - enum sys_clk_rate clk_index; - - rate = clk_get_rate(phy->sys_clk); - clk_index = __get_sys_clk_index(rate); - - if (clk_index == CLK_RATE_UNDEFINED) { - pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate); - return -EINVAL; - } - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); - val &= ~PLL_REGN_MASK; - val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - val &= ~PLL_SELFREQDCO_MASK; - val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); - val &= ~PLL_REGM_MASK; - val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); - val &= ~PLL_REGM_F_MASK; - val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); - - val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); - val &= ~PLL_SD_MASK; - val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT; - omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); - - omap_usb_dpll_relock(phy); - - return 0; -} - -static int omap_usb3_init(struct usb_phy *x) -{ - struct omap_usb *phy = phy_to_omapusb(x); - - omap_usb_dpll_lock(phy); - omap_control_usb3_phy_power(phy->control_dev, 1); - - return 0; -} - -static int omap_usb3_probe(struct platform_device *pdev) -{ - struct omap_usb *phy; - struct resource *res; - - phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); - if (!phy) { - dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); - return -ENOMEM; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(phy->pll_ctrl_base)) - return PTR_ERR(phy->pll_ctrl_base); - - phy->dev = &pdev->dev; - - phy->phy.dev = phy->dev; - phy->phy.label = "omap-usb3"; - phy->phy.init = omap_usb3_init; - phy->phy.set_suspend = omap_usb3_suspend; - phy->phy.type = USB_PHY_TYPE_USB3; - - phy->is_suspended = 1; - phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); - if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); - return PTR_ERR(phy->wkupclk); - } - clk_prepare(phy->wkupclk); - - phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); - if (IS_ERR(phy->optclk)) { - dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); - return PTR_ERR(phy->optclk); - } - clk_prepare(phy->optclk); - - phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); - if (IS_ERR(phy->sys_clk)) { - pr_err("%s: unable to get sys_clkin\n", __func__); - return -EINVAL; - } - - phy->control_dev = omap_get_control_dev(); - if (IS_ERR(phy->control_dev)) { - dev_dbg(&pdev->dev, "Failed to get control device\n"); - return -ENODEV; - } - - omap_control_usb3_phy_power(phy->control_dev, 0); - usb_add_phy_dev(&phy->phy); - - platform_set_drvdata(pdev, phy); - - pm_runtime_enable(phy->dev); - pm_runtime_get(&pdev->dev); - - return 0; -} - -static int omap_usb3_remove(struct platform_device *pdev) -{ - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_unprepare(phy->wkupclk); - clk_unprepare(phy->optclk); - usb_remove_phy(&phy->phy); - if (!pm_runtime_suspended(&pdev->dev)) - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME - -static int omap_usb3_runtime_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_disable(phy->wkupclk); - clk_disable(phy->optclk); - - return 0; -} - -static int omap_usb3_runtime_resume(struct device *dev) -{ - u32 ret = 0; - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - - ret = clk_enable(phy->optclk); - if (ret) { - dev_err(phy->dev, "Failed to enable optclk %d\n", ret); - goto err1; - } - - ret = clk_enable(phy->wkupclk); - if (ret) { - dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); - goto err2; - } - - return 0; - -err2: - clk_disable(phy->optclk); - -err1: - return ret; -} - -static const struct dev_pm_ops omap_usb3_pm_ops = { - SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume, - NULL) -}; - -#define DEV_PM_OPS (&omap_usb3_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif - -#ifdef CONFIG_OF -static const struct of_device_id omap_usb3_id_table[] = { - { .compatible = "ti,omap-usb3" }, - {} -}; -MODULE_DEVICE_TABLE(of, omap_usb3_id_table); -#endif - -static struct platform_driver omap_usb3_driver = { - .probe = omap_usb3_probe, - .remove = omap_usb3_remove, - .driver = { - .name = "omap-usb3", - .owner = THIS_MODULE, - .pm = DEV_PM_OPS, - .of_match_table = of_match_ptr(omap_usb3_id_table), - }, -}; - -module_platform_driver(omap_usb3_driver); - -MODULE_ALIAS("platform: omap_usb3"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("OMAP USB3 phy driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/otg_fsm.c b/drivers/usb/phy/otg_fsm.c deleted file mode 100644 index 1f729a15decb..000000000000 --- a/drivers/usb/phy/otg_fsm.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * OTG Finite State Machine from OTG spec - * - * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * Author: Li Yang - * Jerry Huang - * - * 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 "otg_fsm.h" - -/* Change USB protocol when there is a protocol change */ -static int otg_set_protocol(struct otg_fsm *fsm, int protocol) -{ - int ret = 0; - - if (fsm->protocol != protocol) { - VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", - fsm->protocol, protocol); - /* stop old protocol */ - if (fsm->protocol == PROTO_HOST) - ret = fsm->ops->start_host(fsm, 0); - else if (fsm->protocol == PROTO_GADGET) - ret = fsm->ops->start_gadget(fsm, 0); - if (ret) - return ret; - - /* start new protocol */ - if (protocol == PROTO_HOST) - ret = fsm->ops->start_host(fsm, 1); - else if (protocol == PROTO_GADGET) - ret = fsm->ops->start_gadget(fsm, 1); - if (ret) - return ret; - - fsm->protocol = protocol; - return 0; - } - - return 0; -} - -static int state_changed; - -/* Called when leaving a state. Do state clean up jobs here */ -void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) -{ - switch (old_state) { - case OTG_STATE_B_IDLE: - otg_del_timer(fsm, b_se0_srp_tmr); - fsm->b_se0_srp = 0; - break; - case OTG_STATE_B_SRP_INIT: - fsm->b_srp_done = 0; - break; - case OTG_STATE_B_PERIPHERAL: - break; - case OTG_STATE_B_WAIT_ACON: - otg_del_timer(fsm, b_ase0_brst_tmr); - fsm->b_ase0_brst_tmout = 0; - break; - case OTG_STATE_B_HOST: - break; - case OTG_STATE_A_IDLE: - break; - case OTG_STATE_A_WAIT_VRISE: - otg_del_timer(fsm, a_wait_vrise_tmr); - fsm->a_wait_vrise_tmout = 0; - break; - case OTG_STATE_A_WAIT_BCON: - otg_del_timer(fsm, a_wait_bcon_tmr); - fsm->a_wait_bcon_tmout = 0; - break; - case OTG_STATE_A_HOST: - otg_del_timer(fsm, a_wait_enum_tmr); - break; - case OTG_STATE_A_SUSPEND: - otg_del_timer(fsm, a_aidl_bdis_tmr); - fsm->a_aidl_bdis_tmout = 0; - fsm->a_suspend_req = 0; - break; - case OTG_STATE_A_PERIPHERAL: - break; - case OTG_STATE_A_WAIT_VFALL: - otg_del_timer(fsm, a_wait_vrise_tmr); - break; - case OTG_STATE_A_VBUS_ERR: - break; - default: - break; - } -} - -/* Called when entering a state */ -int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) -{ - state_changed = 1; - if (fsm->otg->phy->state == new_state) - return 0; - VDBG("Set state: %s\n", usb_otg_state_string(new_state)); - otg_leave_state(fsm, fsm->otg->phy->state); - switch (new_state) { - case OTG_STATE_B_IDLE: - otg_drv_vbus(fsm, 0); - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_se0_srp_tmr); - break; - case OTG_STATE_B_SRP_INIT: - otg_start_pulse(fsm); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - otg_add_timer(fsm, b_srp_fail_tmr); - break; - case OTG_STATE_B_PERIPHERAL: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 1); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_GADGET); - break; - case OTG_STATE_B_WAIT_ACON: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, b_ase0_brst_tmr); - fsm->a_bus_suspend = 0; - break; - case OTG_STATE_B_HOST: - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 1); - otg_set_protocol(fsm, PROTO_HOST); - usb_bus_start_enum(fsm->otg->host, - fsm->otg->host->otg_port); - break; - case OTG_STATE_A_IDLE: - otg_drv_vbus(fsm, 0); - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - break; - case OTG_STATE_A_WAIT_VRISE: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_vrise_tmr); - break; - case OTG_STATE_A_WAIT_BCON: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_wait_bcon_tmr); - break; - case OTG_STATE_A_HOST: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 1); - otg_set_protocol(fsm, PROTO_HOST); - /* - * When HNP is triggered while a_bus_req = 0, a_host will - * suspend too fast to complete a_set_b_hnp_en - */ - if (!fsm->a_bus_req || fsm->a_suspend_req) - otg_add_timer(fsm, a_wait_enum_tmr); - break; - case OTG_STATE_A_SUSPEND: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - otg_add_timer(fsm, a_aidl_bdis_tmr); - - break; - case OTG_STATE_A_PERIPHERAL: - otg_loc_conn(fsm, 1); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_GADGET); - otg_drv_vbus(fsm, 1); - break; - case OTG_STATE_A_WAIT_VFALL: - otg_drv_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); - break; - case OTG_STATE_A_VBUS_ERR: - otg_drv_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); - break; - default: - break; - } - - fsm->otg->phy->state = new_state; - return 0; -} - -/* State change judgement */ -int otg_statemachine(struct otg_fsm *fsm) -{ - enum usb_otg_state state; - unsigned long flags; - - spin_lock_irqsave(&fsm->lock, flags); - - state = fsm->otg->phy->state; - state_changed = 0; - /* State machine state change judgement */ - - switch (state) { - case OTG_STATE_UNDEFINED: - VDBG("fsm->id = %d\n", fsm->id); - if (fsm->id) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else - otg_set_state(fsm, OTG_STATE_A_IDLE); - break; - case OTG_STATE_B_IDLE: - if (!fsm->id) - otg_set_state(fsm, OTG_STATE_A_IDLE); - else if (fsm->b_sess_vld && fsm->otg->gadget) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp) - otg_set_state(fsm, OTG_STATE_B_SRP_INIT); - break; - case OTG_STATE_B_SRP_INIT: - if (!fsm->id || fsm->b_srp_done) - otg_set_state(fsm, OTG_STATE_B_IDLE); - break; - case OTG_STATE_B_PERIPHERAL: - if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (fsm->b_bus_req && fsm->otg-> - gadget->b_hnp_enable && fsm->a_bus_suspend) - otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); - break; - case OTG_STATE_B_WAIT_ACON: - if (fsm->a_conn) - otg_set_state(fsm, OTG_STATE_B_HOST); - else if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { - fsm->b_ase0_brst_tmout = 0; - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - } - break; - case OTG_STATE_B_HOST: - if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (!fsm->b_bus_req || !fsm->a_conn) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - break; - case OTG_STATE_A_IDLE: - if (fsm->id) - otg_set_state(fsm, OTG_STATE_B_IDLE); - else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) - otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); - break; - case OTG_STATE_A_WAIT_VRISE: - if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld || - fsm->a_wait_vrise_tmout) { - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - } - break; - case OTG_STATE_A_WAIT_BCON: - if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - else if (fsm->b_conn) - otg_set_state(fsm, OTG_STATE_A_HOST); - else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - break; - case OTG_STATE_A_HOST: - if ((!fsm->a_bus_req || fsm->a_suspend_req) && - fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_SUSPEND); - else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_SUSPEND: - if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); - else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (fsm->a_bus_req || fsm->b_bus_resume) - otg_set_state(fsm, OTG_STATE_A_HOST); - else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_PERIPHERAL: - if (fsm->id || fsm->a_bus_drop) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - else if (fsm->b_bus_suspend) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_WAIT_VFALL: - if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld && - !fsm->b_conn)) - otg_set_state(fsm, OTG_STATE_A_IDLE); - break; - case OTG_STATE_A_VBUS_ERR: - if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - break; - default: - break; - } - spin_unlock_irqrestore(&fsm->lock, flags); - - VDBG("quit statemachine, changed = %d\n", state_changed); - return state_changed; -} diff --git a/drivers/usb/phy/otg_fsm.h b/drivers/usb/phy/otg_fsm.h deleted file mode 100644 index c30a2e1d9e46..000000000000 --- a/drivers/usb/phy/otg_fsm.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * 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. - */ - -#undef DEBUG -#undef VERBOSE - -#ifdef DEBUG -#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt , \ - __func__, ## args) -#else -#define DBG(fmt, args...) do {} while (0) -#endif - -#ifdef VERBOSE -#define VDBG DBG -#else -#define VDBG(stuff...) do {} while (0) -#endif - -#ifdef VERBOSE -#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__) -#else -#define MPC_LOC do {} while (0) -#endif - -#define PROTO_UNDEF (0) -#define PROTO_HOST (1) -#define PROTO_GADGET (2) - -/* OTG state machine according to the OTG spec */ -struct otg_fsm { - /* Input */ - int a_bus_resume; - int a_bus_suspend; - int a_conn; - int a_sess_vld; - int a_srp_det; - int a_vbus_vld; - int b_bus_resume; - int b_bus_suspend; - int b_conn; - int b_se0_srp; - int b_sess_end; - int b_sess_vld; - int id; - - /* Internal variables */ - int a_set_b_hnp_en; - int b_srp_done; - int b_hnp_enable; - - /* Timeout indicator for timers */ - int a_wait_vrise_tmout; - int a_wait_bcon_tmout; - int a_aidl_bdis_tmout; - int b_ase0_brst_tmout; - - /* Informative variables */ - int a_bus_drop; - int a_bus_req; - int a_clr_err; - int a_suspend_req; - int b_bus_req; - - /* Output */ - int drv_vbus; - int loc_conn; - int loc_sof; - - struct otg_fsm_ops *ops; - struct usb_otg *otg; - - /* Current usb protocol used: 0:undefine; 1:host; 2:client */ - int protocol; - spinlock_t lock; -}; - -struct otg_fsm_ops { - void (*chrg_vbus)(int on); - void (*drv_vbus)(int on); - void (*loc_conn)(int on); - void (*loc_sof)(int on); - void (*start_pulse)(void); - void (*add_timer)(void *timer); - void (*del_timer)(void *timer); - int (*start_host)(struct otg_fsm *fsm, int on); - int (*start_gadget)(struct otg_fsm *fsm, int on); -}; - - -static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on) -{ - fsm->ops->chrg_vbus(on); -} - -static inline void otg_drv_vbus(struct otg_fsm *fsm, int on) -{ - if (fsm->drv_vbus != on) { - fsm->drv_vbus = on; - fsm->ops->drv_vbus(on); - } -} - -static inline void otg_loc_conn(struct otg_fsm *fsm, int on) -{ - if (fsm->loc_conn != on) { - fsm->loc_conn = on; - fsm->ops->loc_conn(on); - } -} - -static inline void otg_loc_sof(struct otg_fsm *fsm, int on) -{ - if (fsm->loc_sof != on) { - fsm->loc_sof = on; - fsm->ops->loc_sof(on); - } -} - -static inline void otg_start_pulse(struct otg_fsm *fsm) -{ - fsm->ops->start_pulse(); -} - -static inline void otg_add_timer(struct otg_fsm *fsm, void *timer) -{ - fsm->ops->add_timer(timer); -} - -static inline void otg_del_timer(struct otg_fsm *fsm, void *timer) -{ - fsm->ops->del_timer(timer); -} - -int otg_statemachine(struct otg_fsm *fsm); - -/* Defined by device specific driver, for different timer implementation */ -extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, - *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, - *a_wait_enum_tmr; diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c new file mode 100644 index 000000000000..2d86f26a0183 --- /dev/null +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -0,0 +1,596 @@ +/* + * drivers/usb/otg/ab8500_usb.c + * + * USB transceiver driver for AB8500 chip + * + * Copyright (C) 2010 ST-Ericsson AB + * Mian Yousaf Kaukab + * + * 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 + +#define AB8500_MAIN_WD_CTRL_REG 0x01 +#define AB8500_USB_LINE_STAT_REG 0x80 +#define AB8500_USB_PHY_CTRL_REG 0x8A + +#define AB8500_BIT_OTG_STAT_ID (1 << 0) +#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) +#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) +#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) +#define AB8500_BIT_WD_CTRL_KICK (1 << 1) + +#define AB8500_V1x_LINK_STAT_WAIT (HZ/10) +#define AB8500_WD_KICK_DELAY_US 100 /* usec */ +#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ +#define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ + +/* Usb line status register */ +enum ab8500_usb_link_status { + USB_LINK_NOT_CONFIGURED = 0, + USB_LINK_STD_HOST_NC, + USB_LINK_STD_HOST_C_NS, + USB_LINK_STD_HOST_C_S, + USB_LINK_HOST_CHG_NM, + USB_LINK_HOST_CHG_HS, + USB_LINK_HOST_CHG_HS_CHIRP, + USB_LINK_DEDICATED_CHG, + USB_LINK_ACA_RID_A, + USB_LINK_ACA_RID_B, + USB_LINK_ACA_RID_C_NM, + USB_LINK_ACA_RID_C_HS, + USB_LINK_ACA_RID_C_HS_CHIRP, + USB_LINK_HM_IDGND, + USB_LINK_RESERVED, + USB_LINK_NOT_VALID_LINK +}; + +struct ab8500_usb { + struct usb_phy phy; + struct device *dev; + int irq_num_id_rise; + int irq_num_id_fall; + int irq_num_vbus_rise; + int irq_num_vbus_fall; + int irq_num_link_status; + unsigned vbus_draw; + struct delayed_work dwork; + struct work_struct phy_dis_work; + unsigned long link_status_wait; + int rev; +}; + +static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) +{ + return container_of(x, struct ab8500_usb, phy); +} + +static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) +{ + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + AB8500_BIT_WD_CTRL_ENABLE); + + udelay(AB8500_WD_KICK_DELAY_US); + + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + (AB8500_BIT_WD_CTRL_ENABLE + | AB8500_BIT_WD_CTRL_KICK)); + + if (ab->rev > 0x10) /* v1.1 v2.0 */ + udelay(AB8500_WD_V11_DISABLE_DELAY_US); + else /* v1.0 */ + msleep(AB8500_WD_V10_DISABLE_DELAY_MS); + + abx500_set_register_interruptible(ab->dev, + AB8500_SYS_CTRL2_BLOCK, + AB8500_MAIN_WD_CTRL_REG, + 0); +} + +static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, + bool enable) +{ + u8 ctrl_reg; + abx500_get_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_PHY_CTRL_REG, + &ctrl_reg); + if (sel_host) { + if (enable) + ctrl_reg |= AB8500_BIT_PHY_CTRL_HOST_EN; + else + ctrl_reg &= ~AB8500_BIT_PHY_CTRL_HOST_EN; + } else { + if (enable) + ctrl_reg |= AB8500_BIT_PHY_CTRL_DEVICE_EN; + else + ctrl_reg &= ~AB8500_BIT_PHY_CTRL_DEVICE_EN; + } + + abx500_set_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_PHY_CTRL_REG, + ctrl_reg); + + /* Needed to enable the phy.*/ + if (enable) + ab8500_usb_wd_workaround(ab); +} + +#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_ctrl(ab, true, true) +#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_ctrl(ab, true, false) +#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) +#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) + +static int ab8500_usb_link_status_update(struct ab8500_usb *ab) +{ + u8 reg; + enum ab8500_usb_link_status lsts; + void *v = NULL; + enum usb_phy_events event; + + abx500_get_register_interruptible(ab->dev, + AB8500_USB, + AB8500_USB_LINE_STAT_REG, + ®); + + lsts = (reg >> 3) & 0x0F; + + switch (lsts) { + case USB_LINK_NOT_CONFIGURED: + case USB_LINK_RESERVED: + case USB_LINK_NOT_VALID_LINK: + /* TODO: Disable regulators. */ + ab8500_usb_host_phy_dis(ab); + ab8500_usb_peri_phy_dis(ab); + ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->default_a = false; + ab->vbus_draw = 0; + event = USB_EVENT_NONE; + break; + + case USB_LINK_STD_HOST_NC: + case USB_LINK_STD_HOST_C_NS: + case USB_LINK_STD_HOST_C_S: + case USB_LINK_HOST_CHG_NM: + case USB_LINK_HOST_CHG_HS: + case USB_LINK_HOST_CHG_HS_CHIRP: + if (ab->phy.otg->gadget) { + /* TODO: Enable regulators. */ + ab8500_usb_peri_phy_en(ab); + v = ab->phy.otg->gadget; + } + event = USB_EVENT_VBUS; + break; + + case USB_LINK_HM_IDGND: + if (ab->phy.otg->host) { + /* TODO: Enable regulators. */ + ab8500_usb_host_phy_en(ab); + v = ab->phy.otg->host; + } + ab->phy.state = OTG_STATE_A_IDLE; + ab->phy.otg->default_a = true; + event = USB_EVENT_ID; + break; + + case USB_LINK_ACA_RID_A: + case USB_LINK_ACA_RID_B: + /* TODO */ + case USB_LINK_ACA_RID_C_NM: + case USB_LINK_ACA_RID_C_HS: + case USB_LINK_ACA_RID_C_HS_CHIRP: + case USB_LINK_DEDICATED_CHG: + /* TODO: vbus_draw */ + event = USB_EVENT_CHARGER; + break; + } + + atomic_notifier_call_chain(&ab->phy.notifier, event, v); + + return 0; +} + +static void ab8500_usb_delayed_work(struct work_struct *work) +{ + struct ab8500_usb *ab = container_of(work, struct ab8500_usb, + dwork.work); + + ab8500_usb_link_status_update(ab); +} + +static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + /* Wait for link status to become stable. */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + + return IRQ_HANDLED; +} + +static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + /* Link status will not be updated till phy is disabled. */ + ab8500_usb_peri_phy_dis(ab); + + /* Wait for link status to become stable. */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + + return IRQ_HANDLED; +} + +static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + + ab8500_usb_link_status_update(ab); + + return IRQ_HANDLED; +} + +static void ab8500_usb_phy_disable_work(struct work_struct *work) +{ + struct ab8500_usb *ab = container_of(work, struct ab8500_usb, + phy_dis_work); + + if (!ab->phy.otg->host) + ab8500_usb_host_phy_dis(ab); + + if (!ab->phy.otg->gadget) + ab8500_usb_peri_phy_dis(ab); +} + +static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) +{ + struct ab8500_usb *ab; + + if (!phy) + return -ENODEV; + + ab = phy_to_ab(phy); + + ab->vbus_draw = mA; + + if (mA) + atomic_notifier_call_chain(&ab->phy.notifier, + USB_EVENT_ENUMERATED, ab->phy.otg->gadget); + return 0; +} + +/* TODO: Implement some way for charging or other drivers to read + * ab->vbus_draw. + */ + +static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) +{ + /* TODO */ + return 0; +} + +static int ab8500_usb_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct ab8500_usb *ab; + + if (!otg) + return -ENODEV; + + ab = phy_to_ab(otg->phy); + + /* Some drivers call this function in atomic context. + * Do not update ab8500 registers directly till this + * is fixed. + */ + + if (!gadget) { + /* TODO: Disable regulators. */ + otg->gadget = NULL; + schedule_work(&ab->phy_dis_work); + } else { + otg->gadget = gadget; + otg->phy->state = OTG_STATE_B_IDLE; + + /* Phy will not be enabled if cable is already + * plugged-in. Schedule to enable phy. + * Use same delay to avoid any race condition. + */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + } + + return 0; +} + +static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct ab8500_usb *ab; + + if (!otg) + return -ENODEV; + + ab = phy_to_ab(otg->phy); + + /* Some drivers call this function in atomic context. + * Do not update ab8500 registers directly till this + * is fixed. + */ + + if (!host) { + /* TODO: Disable regulators. */ + otg->host = NULL; + schedule_work(&ab->phy_dis_work); + } else { + otg->host = host; + /* Phy will not be enabled if cable is already + * plugged-in. Schedule to enable phy. + * Use same delay to avoid any race condition. + */ + schedule_delayed_work(&ab->dwork, ab->link_status_wait); + } + + return 0; +} + +static void ab8500_usb_irq_free(struct ab8500_usb *ab) +{ + if (ab->rev < 0x20) { + free_irq(ab->irq_num_id_rise, ab); + free_irq(ab->irq_num_id_fall, ab); + free_irq(ab->irq_num_vbus_rise, ab); + free_irq(ab->irq_num_vbus_fall, ab); + } else { + free_irq(ab->irq_num_link_status, ab); + } +} + +static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, + struct ab8500_usb *ab) +{ + int err; + + ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); + if (ab->irq_num_id_rise < 0) { + dev_err(&pdev->dev, "ID rise irq not found\n"); + return ab->irq_num_id_rise; + } + err = request_threaded_irq(ab->irq_num_id_rise, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-id-rise", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for ID rise irq\n"); + goto fail0; + } + + ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); + if (ab->irq_num_id_fall < 0) { + dev_err(&pdev->dev, "ID fall irq not found\n"); + return ab->irq_num_id_fall; + } + err = request_threaded_irq(ab->irq_num_id_fall, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-id-fall", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for ID fall irq\n"); + goto fail1; + } + + ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); + if (ab->irq_num_vbus_rise < 0) { + dev_err(&pdev->dev, "VBUS rise irq not found\n"); + return ab->irq_num_vbus_rise; + } + err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, + ab8500_usb_v1x_common_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-vbus-rise", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); + goto fail2; + } + + ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); + if (ab->irq_num_vbus_fall < 0) { + dev_err(&pdev->dev, "VBUS fall irq not found\n"); + return ab->irq_num_vbus_fall; + } + err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, + ab8500_usb_v1x_vbus_fall_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-vbus-fall", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); + goto fail3; + } + + return 0; +fail3: + free_irq(ab->irq_num_vbus_rise, ab); +fail2: + free_irq(ab->irq_num_id_fall, ab); +fail1: + free_irq(ab->irq_num_id_rise, ab); +fail0: + return err; +} + +static int ab8500_usb_v2_res_setup(struct platform_device *pdev, + struct ab8500_usb *ab) +{ + int err; + + ab->irq_num_link_status = platform_get_irq_byname(pdev, + "USB_LINK_STATUS"); + if (ab->irq_num_link_status < 0) { + dev_err(&pdev->dev, "Link status irq not found\n"); + return ab->irq_num_link_status; + } + + err = request_threaded_irq(ab->irq_num_link_status, NULL, + ab8500_usb_v20_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, + "usb-link-status", ab); + if (err < 0) { + dev_err(ab->dev, + "request_irq failed for link status irq\n"); + return err; + } + + return 0; +} + +static int ab8500_usb_probe(struct platform_device *pdev) +{ + struct ab8500_usb *ab; + struct usb_otg *otg; + int err; + int rev; + + rev = abx500_get_chip_id(&pdev->dev); + if (rev < 0) { + dev_err(&pdev->dev, "Chip id read failed\n"); + return rev; + } else if (rev < 0x10) { + dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); + return -ENODEV; + } + + ab = kzalloc(sizeof *ab, GFP_KERNEL); + if (!ab) + return -ENOMEM; + + otg = kzalloc(sizeof *otg, GFP_KERNEL); + if (!otg) { + kfree(ab); + return -ENOMEM; + } + + ab->dev = &pdev->dev; + ab->rev = rev; + ab->phy.dev = ab->dev; + ab->phy.otg = otg; + ab->phy.label = "ab8500"; + ab->phy.set_suspend = ab8500_usb_set_suspend; + ab->phy.set_power = ab8500_usb_set_power; + ab->phy.state = OTG_STATE_UNDEFINED; + + otg->phy = &ab->phy; + otg->set_host = ab8500_usb_set_host; + otg->set_peripheral = ab8500_usb_set_peripheral; + + platform_set_drvdata(pdev, ab); + + ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); + + /* v1: Wait for link status to become stable. + * all: Updates form set_host and set_peripheral as they are atomic. + */ + INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); + + /* all: Disable phy when called from set_host and set_peripheral */ + INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); + + if (ab->rev < 0x20) { + err = ab8500_usb_v1x_res_setup(pdev, ab); + ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; + } else { + err = ab8500_usb_v2_res_setup(pdev, ab); + } + + if (err < 0) + goto fail0; + + err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); + if (err) { + dev_err(&pdev->dev, "Can't register transceiver\n"); + goto fail1; + } + + dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); + + return 0; +fail1: + ab8500_usb_irq_free(ab); +fail0: + kfree(otg); + kfree(ab); + return err; +} + +static int ab8500_usb_remove(struct platform_device *pdev) +{ + struct ab8500_usb *ab = platform_get_drvdata(pdev); + + ab8500_usb_irq_free(ab); + + cancel_delayed_work_sync(&ab->dwork); + + cancel_work_sync(&ab->phy_dis_work); + + usb_remove_phy(&ab->phy); + + ab8500_usb_host_phy_dis(ab); + ab8500_usb_peri_phy_dis(ab); + + platform_set_drvdata(pdev, NULL); + + kfree(ab->phy.otg); + kfree(ab); + + return 0; +} + +static struct platform_driver ab8500_usb_driver = { + .probe = ab8500_usb_probe, + .remove = ab8500_usb_remove, + .driver = { + .name = "ab8500-usb", + .owner = THIS_MODULE, + }, +}; + +static int __init ab8500_usb_init(void) +{ + return platform_driver_register(&ab8500_usb_driver); +} +subsys_initcall(ab8500_usb_init); + +static void __exit ab8500_usb_exit(void) +{ + platform_driver_unregister(&ab8500_usb_driver); +} +module_exit(ab8500_usb_exit); + +MODULE_ALIAS("platform:ab8500_usb"); +MODULE_AUTHOR("ST-Ericsson AB"); +MODULE_DESCRIPTION("AB8500 usb transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c new file mode 100644 index 000000000000..97b9308507c3 --- /dev/null +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -0,0 +1,1173 @@ +/* + * Copyright (C) 2007,2008 Freescale semiconductor, Inc. + * + * Author: Li Yang + * Jerry Huang + * + * Initialization based on code from Shlomi Gridish. + * + * 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 "phy-fsl-usb.h" + +#define DRIVER_VERSION "Rev. 1.55" +#define DRIVER_AUTHOR "Jerry Huang/Li Yang" +#define DRIVER_DESC "Freescale USB OTG Transceiver Driver" +#define DRIVER_INFO DRIVER_DESC " " DRIVER_VERSION + +static const char driver_name[] = "fsl-usb2-otg"; + +const pm_message_t otg_suspend_state = { + .event = 1, +}; + +#define HA_DATA_PULSE + +static struct usb_dr_mmap *usb_dr_regs; +static struct fsl_otg *fsl_otg_dev; +static int srp_wait_done; + +/* FSM timers */ +struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, *a_aidl_bdis_tmr, + *b_ase0_brst_tmr, *b_se0_srp_tmr; + +/* Driver specific timers */ +struct fsl_otg_timer *b_data_pulse_tmr, *b_vbus_pulse_tmr, *b_srp_fail_tmr, + *b_srp_wait_tmr, *a_wait_enum_tmr; + +static struct list_head active_timers; + +static struct fsl_otg_config fsl_otg_initdata = { + .otg_port = 1, +}; + +#ifdef CONFIG_PPC32 +static u32 _fsl_readl_be(const unsigned __iomem *p) +{ + return in_be32(p); +} + +static u32 _fsl_readl_le(const unsigned __iomem *p) +{ + return in_le32(p); +} + +static void _fsl_writel_be(u32 v, unsigned __iomem *p) +{ + out_be32(p, v); +} + +static void _fsl_writel_le(u32 v, unsigned __iomem *p) +{ + out_le32(p, v); +} + +static u32 (*_fsl_readl)(const unsigned __iomem *p); +static void (*_fsl_writel)(u32 v, unsigned __iomem *p); + +#define fsl_readl(p) (*_fsl_readl)((p)) +#define fsl_writel(v, p) (*_fsl_writel)((v), (p)) + +#else +#define fsl_readl(addr) readl(addr) +#define fsl_writel(val, addr) writel(val, addr) +#endif /* CONFIG_PPC32 */ + +/* Routines to access transceiver ULPI registers */ +u8 view_ulpi(u8 addr) +{ + u32 temp; + + temp = 0x40000000 | (addr << 16); + fsl_writel(temp, &usb_dr_regs->ulpiview); + udelay(1000); + while (temp & 0x40) + temp = fsl_readl(&usb_dr_regs->ulpiview); + return (le32_to_cpu(temp) & 0x0000ff00) >> 8; +} + +int write_ulpi(u8 addr, u8 data) +{ + u32 temp; + + temp = 0x60000000 | (addr << 16) | data; + fsl_writel(temp, &usb_dr_regs->ulpiview); + return 0; +} + +/* -------------------------------------------------------------*/ +/* Operations that will be called from OTG Finite State Machine */ + +/* Charge vbus for vbus pulsing in SRP */ +void fsl_otg_chrg_vbus(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + /* stop discharging, start charging */ + tmp = (tmp & ~OTGSC_CTRL_VBUS_DISCHARGE) | + OTGSC_CTRL_VBUS_CHARGE; + else + /* stop charging */ + tmp &= ~OTGSC_CTRL_VBUS_CHARGE; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* Discharge vbus through a resistor to ground */ +void fsl_otg_dischrg_vbus(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + /* stop charging, start discharging */ + tmp = (tmp & ~OTGSC_CTRL_VBUS_CHARGE) | + OTGSC_CTRL_VBUS_DISCHARGE; + else + /* stop discharging */ + tmp &= ~OTGSC_CTRL_VBUS_DISCHARGE; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* A-device driver vbus, controlled through PP bit in PORTSC */ +void fsl_otg_drv_vbus(int on) +{ + u32 tmp; + + if (on) { + tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; + fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); + } else { + tmp = fsl_readl(&usb_dr_regs->portsc) & + ~PORTSC_W1C_BITS & ~PORTSC_PORT_POWER; + fsl_writel(tmp, &usb_dr_regs->portsc); + } +} + +/* + * Pull-up D+, signalling connect by periperal. Also used in + * data-line pulsing in SRP + */ +void fsl_otg_loc_conn(int on) +{ + u32 tmp; + + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + + if (on) + tmp |= OTGSC_CTRL_DATA_PULSING; + else + tmp &= ~OTGSC_CTRL_DATA_PULSING; + + fsl_writel(tmp, &usb_dr_regs->otgsc); +} + +/* + * Generate SOF by host. This is controlled through suspend/resume the + * port. In host mode, controller will automatically send SOF. + * Suspend will block the data on the port. + */ +void fsl_otg_loc_sof(int on) +{ + u32 tmp; + + tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; + if (on) + tmp |= PORTSC_PORT_FORCE_RESUME; + else + tmp |= PORTSC_PORT_SUSPEND; + + fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); + +} + +/* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ +void fsl_otg_start_pulse(void) +{ + u32 tmp; + + srp_wait_done = 0; +#ifdef HA_DATA_PULSE + tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; + tmp |= OTGSC_HA_DATA_PULSE; + fsl_writel(tmp, &usb_dr_regs->otgsc); +#else + fsl_otg_loc_conn(1); +#endif + + fsl_otg_add_timer(b_data_pulse_tmr); +} + +void b_data_pulse_end(unsigned long foo) +{ +#ifdef HA_DATA_PULSE +#else + fsl_otg_loc_conn(0); +#endif + + /* Do VBUS pulse after data pulse */ + fsl_otg_pulse_vbus(); +} + +void fsl_otg_pulse_vbus(void) +{ + srp_wait_done = 0; + fsl_otg_chrg_vbus(1); + /* start the timer to end vbus charge */ + fsl_otg_add_timer(b_vbus_pulse_tmr); +} + +void b_vbus_pulse_end(unsigned long foo) +{ + fsl_otg_chrg_vbus(0); + + /* + * As USB3300 using the same a_sess_vld and b_sess_vld voltage + * we need to discharge the bus for a while to distinguish + * residual voltage of vbus pulsing and A device pull up + */ + fsl_otg_dischrg_vbus(1); + fsl_otg_add_timer(b_srp_wait_tmr); +} + +void b_srp_end(unsigned long foo) +{ + fsl_otg_dischrg_vbus(0); + srp_wait_done = 1; + + if ((fsl_otg_dev->phy.state == OTG_STATE_B_SRP_INIT) && + fsl_otg_dev->fsm.b_sess_vld) + fsl_otg_dev->fsm.b_srp_done = 1; +} + +/* + * Workaround for a_host suspending too fast. When a_bus_req=0, + * a_host will start by SRP. It needs to set b_hnp_enable before + * actually suspending to start HNP + */ +void a_wait_enum(unsigned long foo) +{ + VDBG("a_wait_enum timeout\n"); + if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) + fsl_otg_add_timer(a_wait_enum_tmr); + else + otg_statemachine(&fsl_otg_dev->fsm); +} + +/* The timeout callback function to set time out bit */ +void set_tmout(unsigned long indicator) +{ + *(int *)indicator = 1; +} + +/* Initialize timers */ +int fsl_otg_init_timers(struct otg_fsm *fsm) +{ + /* FSM used timers */ + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, + (unsigned long)&fsm->a_wait_vrise_tmout); + if (!a_wait_vrise_tmr) + return -ENOMEM; + + a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, + (unsigned long)&fsm->a_wait_bcon_tmout); + if (!a_wait_bcon_tmr) + return -ENOMEM; + + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, + (unsigned long)&fsm->a_aidl_bdis_tmout); + if (!a_aidl_bdis_tmr) + return -ENOMEM; + + b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, + (unsigned long)&fsm->b_ase0_brst_tmout); + if (!b_ase0_brst_tmr) + return -ENOMEM; + + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, + (unsigned long)&fsm->b_se0_srp); + if (!b_se0_srp_tmr) + return -ENOMEM; + + b_srp_fail_tmr = otg_timer_initializer(&set_tmout, TB_SRP_FAIL, + (unsigned long)&fsm->b_srp_done); + if (!b_srp_fail_tmr) + return -ENOMEM; + + a_wait_enum_tmr = otg_timer_initializer(&a_wait_enum, 10, + (unsigned long)&fsm); + if (!a_wait_enum_tmr) + return -ENOMEM; + + /* device driver used timers */ + b_srp_wait_tmr = otg_timer_initializer(&b_srp_end, TB_SRP_WAIT, 0); + if (!b_srp_wait_tmr) + return -ENOMEM; + + b_data_pulse_tmr = otg_timer_initializer(&b_data_pulse_end, + TB_DATA_PLS, 0); + if (!b_data_pulse_tmr) + return -ENOMEM; + + b_vbus_pulse_tmr = otg_timer_initializer(&b_vbus_pulse_end, + TB_VBUS_PLS, 0); + if (!b_vbus_pulse_tmr) + return -ENOMEM; + + return 0; +} + +/* Uninitialize timers */ +void fsl_otg_uninit_timers(void) +{ + /* FSM used timers */ + kfree(a_wait_vrise_tmr); + kfree(a_wait_bcon_tmr); + kfree(a_aidl_bdis_tmr); + kfree(b_ase0_brst_tmr); + kfree(b_se0_srp_tmr); + kfree(b_srp_fail_tmr); + kfree(a_wait_enum_tmr); + + /* device driver used timers */ + kfree(b_srp_wait_tmr); + kfree(b_data_pulse_tmr); + kfree(b_vbus_pulse_tmr); +} + +/* Add timer to timer list */ +void fsl_otg_add_timer(void *gtimer) +{ + struct fsl_otg_timer *timer = gtimer; + struct fsl_otg_timer *tmp_timer; + + /* + * Check if the timer is already in the active list, + * if so update timer count + */ + list_for_each_entry(tmp_timer, &active_timers, list) + if (tmp_timer == timer) { + timer->count = timer->expires; + return; + } + timer->count = timer->expires; + list_add_tail(&timer->list, &active_timers); +} + +/* Remove timer from the timer list; clear timeout status */ +void fsl_otg_del_timer(void *gtimer) +{ + struct fsl_otg_timer *timer = gtimer; + struct fsl_otg_timer *tmp_timer, *del_tmp; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) + if (tmp_timer == timer) + list_del(&timer->list); +} + +/* + * Reduce timer count by 1, and find timeout conditions. + * Called by fsl_otg 1ms timer interrupt + */ +int fsl_otg_tick_timer(void) +{ + struct fsl_otg_timer *tmp_timer, *del_tmp; + int expired = 0; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { + tmp_timer->count--; + /* check if timer expires */ + if (!tmp_timer->count) { + list_del(&tmp_timer->list); + tmp_timer->function(tmp_timer->data); + expired = 1; + } + } + + return expired; +} + +/* Reset controller, not reset the bus */ +void otg_reset_controller(void) +{ + u32 command; + + command = fsl_readl(&usb_dr_regs->usbcmd); + command |= (1 << 1); + fsl_writel(command, &usb_dr_regs->usbcmd); + while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) + ; +} + +/* Call suspend/resume routines in host driver */ +int fsl_otg_start_host(struct otg_fsm *fsm, int on) +{ + struct usb_otg *otg = fsm->otg; + struct device *dev; + struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); + u32 retval = 0; + + if (!otg->host) + return -ENODEV; + dev = otg->host->controller; + + /* + * Update a_vbus_vld state as a_vbus_vld int is disabled + * in device mode + */ + fsm->a_vbus_vld = + !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); + if (on) { + /* start fsl usb host controller */ + if (otg_dev->host_working) + goto end; + else { + otg_reset_controller(); + VDBG("host on......\n"); + if (dev->driver->pm && dev->driver->pm->resume) { + retval = dev->driver->pm->resume(dev); + if (fsm->id) { + /* default-b */ + fsl_otg_drv_vbus(1); + /* + * Workaround: b_host can't driver + * vbus, but PP in PORTSC needs to + * be 1 for host to work. + * So we set drv_vbus bit in + * transceiver to 0 thru ULPI. + */ + write_ulpi(0x0c, 0x20); + } + } + + otg_dev->host_working = 1; + } + } else { + /* stop fsl usb host controller */ + if (!otg_dev->host_working) + goto end; + else { + VDBG("host off......\n"); + if (dev && dev->driver) { + if (dev->driver->pm && dev->driver->pm->suspend) + retval = dev->driver->pm->suspend(dev); + if (fsm->id) + /* default-b */ + fsl_otg_drv_vbus(0); + } + otg_dev->host_working = 0; + } + } +end: + return retval; +} + +/* + * Call suspend and resume function in udc driver + * to stop and start udc driver. + */ +int fsl_otg_start_gadget(struct otg_fsm *fsm, int on) +{ + struct usb_otg *otg = fsm->otg; + struct device *dev; + + if (!otg->gadget || !otg->gadget->dev.parent) + return -ENODEV; + + VDBG("gadget %s\n", on ? "on" : "off"); + dev = otg->gadget->dev.parent; + + if (on) { + if (dev->driver->resume) + dev->driver->resume(dev); + } else { + if (dev->driver->suspend) + dev->driver->suspend(dev, otg_suspend_state); + } + + return 0; +} + +/* + * Called by initialization code of host driver. Register host controller + * to the OTG. Suspend host for OTG role detection. + */ +static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + otg->host = host; + + otg_dev->fsm.a_bus_drop = 0; + otg_dev->fsm.a_bus_req = 1; + + if (host) { + VDBG("host off......\n"); + + otg->host->otg_port = fsl_otg_initdata.otg_port; + otg->host->is_b_host = otg_dev->fsm.id; + /* + * must leave time for khubd to finish its thing + * before yanking the host driver out from under it, + * so suspend the host after a short delay. + */ + otg_dev->host_working = 1; + schedule_delayed_work(&otg_dev->otg_event, 100); + return 0; + } else { + /* host driver going away */ + if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & + OTGSC_STS_USB_ID)) { + /* Mini-A cable connected */ + struct otg_fsm *fsm = &otg_dev->fsm; + + otg->phy->state = OTG_STATE_UNDEFINED; + fsm->protocol = PROTO_UNDEF; + } + } + + otg_dev->host_working = 0; + + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* Called by initialization code of udc. Register udc to OTG. */ +static int fsl_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + VDBG("otg_dev 0x%x\n", (int)otg_dev); + VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + if (!gadget) { + if (!otg->default_a) + otg->gadget->ops->vbus_draw(otg->gadget, 0); + usb_gadget_vbus_disconnect(otg->gadget); + otg->gadget = 0; + otg_dev->fsm.b_bus_req = 0; + otg_statemachine(&otg_dev->fsm); + return 0; + } + + otg->gadget = gadget; + otg->gadget->is_a_peripheral = !otg_dev->fsm.id; + + otg_dev->fsm.b_bus_req = 1; + + /* start the gadget right away if the ID pin says Mini-B */ + DBG("ID pin=%d\n", otg_dev->fsm.id); + if (otg_dev->fsm.id == 1) { + fsl_otg_start_host(&otg_dev->fsm, 0); + otg_drv_vbus(&otg_dev->fsm, 0); + fsl_otg_start_gadget(&otg_dev->fsm, 1); + } + + return 0; +} + +/* Set OTG port power, only for B-device */ +static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA) +{ + if (!fsl_otg_dev) + return -ENODEV; + if (phy->state == OTG_STATE_B_PERIPHERAL) + pr_info("FSL OTG: Draw %d mA\n", mA); + + return 0; +} + +/* + * Delayed pin detect interrupt processing. + * + * When the Mini-A cable is disconnected from the board, + * the pin-detect interrupt happens before the disconnect + * interrupts for the connected device(s). In order to + * process the disconnect interrupt(s) prior to switching + * roles, the pin-detect interrupts are delayed, and handled + * by this routine. + */ +static void fsl_otg_event(struct work_struct *work) +{ + struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work); + struct otg_fsm *fsm = &og->fsm; + + if (fsm->id) { /* switch to gadget */ + fsl_otg_start_host(fsm, 0); + otg_drv_vbus(fsm, 0); + fsl_otg_start_gadget(fsm, 1); + } +} + +/* B-device start SRP */ +static int fsl_otg_start_srp(struct usb_otg *otg) +{ + struct fsl_otg *otg_dev; + + if (!otg || otg->phy->state != OTG_STATE_B_IDLE) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + otg_dev->fsm.b_bus_req = 1; + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* A_host suspend will call this function to start hnp */ +static int fsl_otg_start_hnp(struct usb_otg *otg) +{ + struct fsl_otg *otg_dev; + + if (!otg) + return -ENODEV; + + otg_dev = container_of(otg->phy, struct fsl_otg, phy); + if (otg_dev != fsl_otg_dev) + return -ENODEV; + + DBG("start_hnp...n"); + + /* clear a_bus_req to enter a_suspend state */ + otg_dev->fsm.a_bus_req = 0; + otg_statemachine(&otg_dev->fsm); + + return 0; +} + +/* + * Interrupt handler. OTG/host/peripheral share the same int line. + * OTG driver clears OTGSC interrupts and leaves USB interrupts + * intact. It needs to have knowledge of some USB interrupts + * such as port change. + */ +irqreturn_t fsl_otg_isr(int irq, void *dev_id) +{ + struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; + struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; + u32 otg_int_src, otg_sc; + + otg_sc = fsl_readl(&usb_dr_regs->otgsc); + otg_int_src = otg_sc & OTGSC_INTSTS_MASK & (otg_sc >> 8); + + /* Only clear otg interrupts */ + fsl_writel(otg_sc, &usb_dr_regs->otgsc); + + /*FIXME: ID change not generate when init to 0 */ + fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; + otg->default_a = (fsm->id == 0); + + /* process OTG interrupts */ + if (otg_int_src) { + if (otg_int_src & OTGSC_INTSTS_USB_ID) { + fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; + otg->default_a = (fsm->id == 0); + /* clear conn information */ + if (fsm->id) + fsm->b_conn = 0; + else + fsm->a_conn = 0; + + if (otg->host) + otg->host->is_b_host = fsm->id; + if (otg->gadget) + otg->gadget->is_a_peripheral = !fsm->id; + VDBG("ID int (ID is %d)\n", fsm->id); + + if (fsm->id) { /* switch to gadget */ + schedule_delayed_work( + &((struct fsl_otg *)dev_id)->otg_event, + 100); + } else { /* switch to host */ + cancel_delayed_work(& + ((struct fsl_otg *)dev_id)-> + otg_event); + fsl_otg_start_gadget(fsm, 0); + otg_drv_vbus(fsm, 1); + fsl_otg_start_host(fsm, 1); + } + return IRQ_HANDLED; + } + } + return IRQ_NONE; +} + +static struct otg_fsm_ops fsl_otg_ops = { + .chrg_vbus = fsl_otg_chrg_vbus, + .drv_vbus = fsl_otg_drv_vbus, + .loc_conn = fsl_otg_loc_conn, + .loc_sof = fsl_otg_loc_sof, + .start_pulse = fsl_otg_start_pulse, + + .add_timer = fsl_otg_add_timer, + .del_timer = fsl_otg_del_timer, + + .start_host = fsl_otg_start_host, + .start_gadget = fsl_otg_start_gadget, +}; + +/* Initialize the global variable fsl_otg_dev and request IRQ for OTG */ +static int fsl_otg_conf(struct platform_device *pdev) +{ + struct fsl_otg *fsl_otg_tc; + int status; + + if (fsl_otg_dev) + return 0; + + /* allocate space to fsl otg device */ + fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); + if (!fsl_otg_tc) + return -ENOMEM; + + fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!fsl_otg_tc->phy.otg) { + kfree(fsl_otg_tc); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); + + INIT_LIST_HEAD(&active_timers); + status = fsl_otg_init_timers(&fsl_otg_tc->fsm); + if (status) { + pr_info("Couldn't init OTG timers\n"); + goto err; + } + spin_lock_init(&fsl_otg_tc->fsm.lock); + + /* Set OTG state machine operations */ + fsl_otg_tc->fsm.ops = &fsl_otg_ops; + + /* initialize the otg structure */ + fsl_otg_tc->phy.label = DRIVER_DESC; + fsl_otg_tc->phy.set_power = fsl_otg_set_power; + + fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; + fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; + fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; + fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; + fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; + + fsl_otg_dev = fsl_otg_tc; + + /* Store the otg transceiver */ + status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); + if (status) { + pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); + goto err; + } + + return 0; +err: + fsl_otg_uninit_timers(); + kfree(fsl_otg_tc->phy.otg); + kfree(fsl_otg_tc); + return status; +} + +/* OTG Initialization */ +int usb_otg_start(struct platform_device *pdev) +{ + struct fsl_otg *p_otg; + struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); + struct otg_fsm *fsm; + int status; + struct resource *res; + u32 temp; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + p_otg = container_of(otg_trans, struct fsl_otg, phy); + fsm = &p_otg->fsm; + + /* Initialize the state machine structure with default values */ + SET_OTG_STATE(otg_trans, OTG_STATE_UNDEFINED); + fsm->otg = p_otg->phy.otg; + + /* We don't require predefined MEM/IRQ resource index */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + /* We don't request_mem_region here to enable resource sharing + * with host/device */ + + usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); + p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; + pdata->regs = (void *)usb_dr_regs; + + if (pdata->init && pdata->init(pdev) != 0) + return -EINVAL; + + if (pdata->big_endian_mmio) { + _fsl_readl = _fsl_readl_be; + _fsl_writel = _fsl_writel_be; + } else { + _fsl_readl = _fsl_readl_le; + _fsl_writel = _fsl_writel_le; + } + + /* request irq */ + p_otg->irq = platform_get_irq(pdev, 0); + status = request_irq(p_otg->irq, fsl_otg_isr, + IRQF_SHARED, driver_name, p_otg); + if (status) { + dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", + p_otg->irq, status); + iounmap(p_otg->dr_mem_map); + kfree(p_otg->phy.otg); + kfree(p_otg); + return status; + } + + /* stop the controller */ + temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); + temp &= ~USB_CMD_RUN_STOP; + fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); + + /* reset the controller */ + temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); + temp |= USB_CMD_CTRL_RESET; + fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); + + /* wait reset completed */ + while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) + ; + + /* configure the VBUSHS as IDLE(both host and device) */ + temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); + fsl_writel(temp, &p_otg->dr_mem_map->usbmode); + + /* configure PHY interface */ + temp = fsl_readl(&p_otg->dr_mem_map->portsc); + temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); + switch (pdata->phy_mode) { + case FSL_USB2_PHY_ULPI: + temp |= PORTSC_PTS_ULPI; + break; + case FSL_USB2_PHY_UTMI_WIDE: + temp |= PORTSC_PTW_16BIT; + /* fall through */ + case FSL_USB2_PHY_UTMI: + temp |= PORTSC_PTS_UTMI; + /* fall through */ + default: + break; + } + fsl_writel(temp, &p_otg->dr_mem_map->portsc); + + if (pdata->have_sysif_regs) { + /* configure control enable IO output, big endian register */ + temp = __raw_readl(&p_otg->dr_mem_map->control); + temp |= USB_CTRL_IOENB; + __raw_writel(temp, &p_otg->dr_mem_map->control); + } + + /* disable all interrupt and clear all OTGSC status */ + temp = fsl_readl(&p_otg->dr_mem_map->otgsc); + temp &= ~OTGSC_INTERRUPT_ENABLE_BITS_MASK; + temp |= OTGSC_INTERRUPT_STATUS_BITS_MASK | OTGSC_CTRL_VBUS_DISCHARGE; + fsl_writel(temp, &p_otg->dr_mem_map->otgsc); + + /* + * The identification (id) input is FALSE when a Mini-A plug is inserted + * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. + * Also: record initial state of ID pin + */ + if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { + p_otg->phy.state = OTG_STATE_UNDEFINED; + p_otg->fsm.id = 1; + } else { + p_otg->phy.state = OTG_STATE_A_IDLE; + p_otg->fsm.id = 0; + } + + DBG("initial ID pin=%d\n", p_otg->fsm.id); + + /* enable OTG ID pin interrupt */ + temp = fsl_readl(&p_otg->dr_mem_map->otgsc); + temp |= OTGSC_INTR_USB_ID_EN; + temp &= ~(OTGSC_CTRL_VBUS_DISCHARGE | OTGSC_INTR_1MS_TIMER_EN); + fsl_writel(temp, &p_otg->dr_mem_map->otgsc); + + return 0; +} + +/* + * state file in sysfs + */ +static int show_fsl_usb2_otg_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct otg_fsm *fsm = &fsl_otg_dev->fsm; + char *next = buf; + unsigned size = PAGE_SIZE; + unsigned long flags; + int t; + + spin_lock_irqsave(&fsm->lock, flags); + + /* basic driver infomation */ + t = scnprintf(next, size, + DRIVER_DESC "\n" "fsl_usb2_otg version: %s\n\n", + DRIVER_VERSION); + size -= t; + next += t; + + /* Registers */ + t = scnprintf(next, size, + "OTGSC: 0x%08x\n" + "PORTSC: 0x%08x\n" + "USBMODE: 0x%08x\n" + "USBCMD: 0x%08x\n" + "USBSTS: 0x%08x\n" + "USBINTR: 0x%08x\n", + fsl_readl(&usb_dr_regs->otgsc), + fsl_readl(&usb_dr_regs->portsc), + fsl_readl(&usb_dr_regs->usbmode), + fsl_readl(&usb_dr_regs->usbcmd), + fsl_readl(&usb_dr_regs->usbsts), + fsl_readl(&usb_dr_regs->usbintr)); + size -= t; + next += t; + + /* State */ + t = scnprintf(next, size, + "OTG state: %s\n\n", + usb_otg_state_string(fsl_otg_dev->phy.state)); + size -= t; + next += t; + + /* State Machine Variables */ + t = scnprintf(next, size, + "a_bus_req: %d\n" + "b_bus_req: %d\n" + "a_bus_resume: %d\n" + "a_bus_suspend: %d\n" + "a_conn: %d\n" + "a_sess_vld: %d\n" + "a_srp_det: %d\n" + "a_vbus_vld: %d\n" + "b_bus_resume: %d\n" + "b_bus_suspend: %d\n" + "b_conn: %d\n" + "b_se0_srp: %d\n" + "b_sess_end: %d\n" + "b_sess_vld: %d\n" + "id: %d\n", + fsm->a_bus_req, + fsm->b_bus_req, + fsm->a_bus_resume, + fsm->a_bus_suspend, + fsm->a_conn, + fsm->a_sess_vld, + fsm->a_srp_det, + fsm->a_vbus_vld, + fsm->b_bus_resume, + fsm->b_bus_suspend, + fsm->b_conn, + fsm->b_se0_srp, + fsm->b_sess_end, + fsm->b_sess_vld, + fsm->id); + size -= t; + next += t; + + spin_unlock_irqrestore(&fsm->lock, flags); + + return PAGE_SIZE - size; +} + +static DEVICE_ATTR(fsl_usb2_otg_state, S_IRUGO, show_fsl_usb2_otg_state, NULL); + + +/* Char driver interface to control some OTG input */ + +/* + * Handle some ioctl command, such as get otg + * status and set host suspend + */ +static long fsl_otg_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + u32 retval = 0; + + switch (cmd) { + case GET_OTG_STATUS: + retval = fsl_otg_dev->host_working; + break; + + case SET_A_SUSPEND_REQ: + fsl_otg_dev->fsm.a_suspend_req = arg; + break; + + case SET_A_BUS_DROP: + fsl_otg_dev->fsm.a_bus_drop = arg; + break; + + case SET_A_BUS_REQ: + fsl_otg_dev->fsm.a_bus_req = arg; + break; + + case SET_B_BUS_REQ: + fsl_otg_dev->fsm.b_bus_req = arg; + break; + + default: + break; + } + + otg_statemachine(&fsl_otg_dev->fsm); + + return retval; +} + +static int fsl_otg_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int fsl_otg_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations otg_fops = { + .owner = THIS_MODULE, + .llseek = NULL, + .read = NULL, + .write = NULL, + .unlocked_ioctl = fsl_otg_ioctl, + .open = fsl_otg_open, + .release = fsl_otg_release, +}; + +static int fsl_otg_probe(struct platform_device *pdev) +{ + int ret; + + if (!pdev->dev.platform_data) + return -ENODEV; + + /* configure the OTG */ + ret = fsl_otg_conf(pdev); + if (ret) { + dev_err(&pdev->dev, "Couldn't configure OTG module\n"); + return ret; + } + + /* start OTG */ + ret = usb_otg_start(pdev); + if (ret) { + dev_err(&pdev->dev, "Can't init FSL OTG device\n"); + return ret; + } + + ret = register_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME, &otg_fops); + if (ret) { + dev_err(&pdev->dev, "unable to register FSL OTG device\n"); + return ret; + } + + ret = device_create_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); + if (ret) + dev_warn(&pdev->dev, "Can't register sysfs attribute\n"); + + return ret; +} + +static int fsl_otg_remove(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + usb_remove_phy(&fsl_otg_dev->phy); + free_irq(fsl_otg_dev->irq, fsl_otg_dev); + + iounmap((void *)usb_dr_regs); + + fsl_otg_uninit_timers(); + kfree(fsl_otg_dev->phy.otg); + kfree(fsl_otg_dev); + + device_remove_file(&pdev->dev, &dev_attr_fsl_usb2_otg_state); + + unregister_chrdev(FSL_OTG_MAJOR, FSL_OTG_NAME); + + if (pdata->exit) + pdata->exit(pdev); + + return 0; +} + +struct platform_driver fsl_otg_driver = { + .probe = fsl_otg_probe, + .remove = fsl_otg_remove, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(fsl_otg_driver); + +MODULE_DESCRIPTION(DRIVER_INFO); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h new file mode 100644 index 000000000000..ca266280895d --- /dev/null +++ b/drivers/usb/phy/phy-fsl-usb.h @@ -0,0 +1,406 @@ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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 "otg_fsm.h" +#include +#include + +/* USB Command Register Bit Masks */ +#define USB_CMD_RUN_STOP (0x1<<0) +#define USB_CMD_CTRL_RESET (0x1<<1) +#define USB_CMD_PERIODIC_SCHEDULE_EN (0x1<<4) +#define USB_CMD_ASYNC_SCHEDULE_EN (0x1<<5) +#define USB_CMD_INT_AA_DOORBELL (0x1<<6) +#define USB_CMD_ASP (0x3<<8) +#define USB_CMD_ASYNC_SCH_PARK_EN (0x1<<11) +#define USB_CMD_SUTW (0x1<<13) +#define USB_CMD_ATDTW (0x1<<14) +#define USB_CMD_ITC (0xFF<<16) + +/* bit 15,3,2 are frame list size */ +#define USB_CMD_FRAME_SIZE_1024 (0x0<<15 | 0x0<<2) +#define USB_CMD_FRAME_SIZE_512 (0x0<<15 | 0x1<<2) +#define USB_CMD_FRAME_SIZE_256 (0x0<<15 | 0x2<<2) +#define USB_CMD_FRAME_SIZE_128 (0x0<<15 | 0x3<<2) +#define USB_CMD_FRAME_SIZE_64 (0x1<<15 | 0x0<<2) +#define USB_CMD_FRAME_SIZE_32 (0x1<<15 | 0x1<<2) +#define USB_CMD_FRAME_SIZE_16 (0x1<<15 | 0x2<<2) +#define USB_CMD_FRAME_SIZE_8 (0x1<<15 | 0x3<<2) + +/* bit 9-8 are async schedule park mode count */ +#define USB_CMD_ASP_00 (0x0<<8) +#define USB_CMD_ASP_01 (0x1<<8) +#define USB_CMD_ASP_10 (0x2<<8) +#define USB_CMD_ASP_11 (0x3<<8) +#define USB_CMD_ASP_BIT_POS (8) + +/* bit 23-16 are interrupt threshold control */ +#define USB_CMD_ITC_NO_THRESHOLD (0x00<<16) +#define USB_CMD_ITC_1_MICRO_FRM (0x01<<16) +#define USB_CMD_ITC_2_MICRO_FRM (0x02<<16) +#define USB_CMD_ITC_4_MICRO_FRM (0x04<<16) +#define USB_CMD_ITC_8_MICRO_FRM (0x08<<16) +#define USB_CMD_ITC_16_MICRO_FRM (0x10<<16) +#define USB_CMD_ITC_32_MICRO_FRM (0x20<<16) +#define USB_CMD_ITC_64_MICRO_FRM (0x40<<16) +#define USB_CMD_ITC_BIT_POS (16) + +/* USB Status Register Bit Masks */ +#define USB_STS_INT (0x1<<0) +#define USB_STS_ERR (0x1<<1) +#define USB_STS_PORT_CHANGE (0x1<<2) +#define USB_STS_FRM_LST_ROLL (0x1<<3) +#define USB_STS_SYS_ERR (0x1<<4) +#define USB_STS_IAA (0x1<<5) +#define USB_STS_RESET_RECEIVED (0x1<<6) +#define USB_STS_SOF (0x1<<7) +#define USB_STS_DCSUSPEND (0x1<<8) +#define USB_STS_HC_HALTED (0x1<<12) +#define USB_STS_RCL (0x1<<13) +#define USB_STS_PERIODIC_SCHEDULE (0x1<<14) +#define USB_STS_ASYNC_SCHEDULE (0x1<<15) + +/* USB Interrupt Enable Register Bit Masks */ +#define USB_INTR_INT_EN (0x1<<0) +#define USB_INTR_ERR_INT_EN (0x1<<1) +#define USB_INTR_PC_DETECT_EN (0x1<<2) +#define USB_INTR_FRM_LST_ROLL_EN (0x1<<3) +#define USB_INTR_SYS_ERR_EN (0x1<<4) +#define USB_INTR_ASYN_ADV_EN (0x1<<5) +#define USB_INTR_RESET_EN (0x1<<6) +#define USB_INTR_SOF_EN (0x1<<7) +#define USB_INTR_DEVICE_SUSPEND (0x1<<8) + +/* Device Address bit masks */ +#define USB_DEVICE_ADDRESS_MASK (0x7F<<25) +#define USB_DEVICE_ADDRESS_BIT_POS (25) +/* PORTSC Register Bit Masks,Only one PORT in OTG mode*/ +#define PORTSC_CURRENT_CONNECT_STATUS (0x1<<0) +#define PORTSC_CONNECT_STATUS_CHANGE (0x1<<1) +#define PORTSC_PORT_ENABLE (0x1<<2) +#define PORTSC_PORT_EN_DIS_CHANGE (0x1<<3) +#define PORTSC_OVER_CURRENT_ACT (0x1<<4) +#define PORTSC_OVER_CUURENT_CHG (0x1<<5) +#define PORTSC_PORT_FORCE_RESUME (0x1<<6) +#define PORTSC_PORT_SUSPEND (0x1<<7) +#define PORTSC_PORT_RESET (0x1<<8) +#define PORTSC_LINE_STATUS_BITS (0x3<<10) +#define PORTSC_PORT_POWER (0x1<<12) +#define PORTSC_PORT_INDICTOR_CTRL (0x3<<14) +#define PORTSC_PORT_TEST_CTRL (0xF<<16) +#define PORTSC_WAKE_ON_CONNECT_EN (0x1<<20) +#define PORTSC_WAKE_ON_CONNECT_DIS (0x1<<21) +#define PORTSC_WAKE_ON_OVER_CURRENT (0x1<<22) +#define PORTSC_PHY_LOW_POWER_SPD (0x1<<23) +#define PORTSC_PORT_FORCE_FULL_SPEED (0x1<<24) +#define PORTSC_PORT_SPEED_MASK (0x3<<26) +#define PORTSC_TRANSCEIVER_WIDTH (0x1<<28) +#define PORTSC_PHY_TYPE_SEL (0x3<<30) +/* bit 11-10 are line status */ +#define PORTSC_LINE_STATUS_SE0 (0x0<<10) +#define PORTSC_LINE_STATUS_JSTATE (0x1<<10) +#define PORTSC_LINE_STATUS_KSTATE (0x2<<10) +#define PORTSC_LINE_STATUS_UNDEF (0x3<<10) +#define PORTSC_LINE_STATUS_BIT_POS (10) + +/* bit 15-14 are port indicator control */ +#define PORTSC_PIC_OFF (0x0<<14) +#define PORTSC_PIC_AMBER (0x1<<14) +#define PORTSC_PIC_GREEN (0x2<<14) +#define PORTSC_PIC_UNDEF (0x3<<14) +#define PORTSC_PIC_BIT_POS (14) + +/* bit 19-16 are port test control */ +#define PORTSC_PTC_DISABLE (0x0<<16) +#define PORTSC_PTC_JSTATE (0x1<<16) +#define PORTSC_PTC_KSTATE (0x2<<16) +#define PORTSC_PTC_SEQNAK (0x3<<16) +#define PORTSC_PTC_PACKET (0x4<<16) +#define PORTSC_PTC_FORCE_EN (0x5<<16) +#define PORTSC_PTC_BIT_POS (16) + +/* bit 27-26 are port speed */ +#define PORTSC_PORT_SPEED_FULL (0x0<<26) +#define PORTSC_PORT_SPEED_LOW (0x1<<26) +#define PORTSC_PORT_SPEED_HIGH (0x2<<26) +#define PORTSC_PORT_SPEED_UNDEF (0x3<<26) +#define PORTSC_SPEED_BIT_POS (26) + +/* bit 28 is parallel transceiver width for UTMI interface */ +#define PORTSC_PTW (0x1<<28) +#define PORTSC_PTW_8BIT (0x0<<28) +#define PORTSC_PTW_16BIT (0x1<<28) + +/* bit 31-30 are port transceiver select */ +#define PORTSC_PTS_UTMI (0x0<<30) +#define PORTSC_PTS_ULPI (0x2<<30) +#define PORTSC_PTS_FSLS_SERIAL (0x3<<30) +#define PORTSC_PTS_BIT_POS (30) + +#define PORTSC_W1C_BITS \ + (PORTSC_CONNECT_STATUS_CHANGE | \ + PORTSC_PORT_EN_DIS_CHANGE | \ + PORTSC_OVER_CUURENT_CHG) + +/* OTG Status Control Register Bit Masks */ +#define OTGSC_CTRL_VBUS_DISCHARGE (0x1<<0) +#define OTGSC_CTRL_VBUS_CHARGE (0x1<<1) +#define OTGSC_CTRL_OTG_TERMINATION (0x1<<3) +#define OTGSC_CTRL_DATA_PULSING (0x1<<4) +#define OTGSC_CTRL_ID_PULL_EN (0x1<<5) +#define OTGSC_HA_DATA_PULSE (0x1<<6) +#define OTGSC_HA_BA (0x1<<7) +#define OTGSC_STS_USB_ID (0x1<<8) +#define OTGSC_STS_A_VBUS_VALID (0x1<<9) +#define OTGSC_STS_A_SESSION_VALID (0x1<<10) +#define OTGSC_STS_B_SESSION_VALID (0x1<<11) +#define OTGSC_STS_B_SESSION_END (0x1<<12) +#define OTGSC_STS_1MS_TOGGLE (0x1<<13) +#define OTGSC_STS_DATA_PULSING (0x1<<14) +#define OTGSC_INTSTS_USB_ID (0x1<<16) +#define OTGSC_INTSTS_A_VBUS_VALID (0x1<<17) +#define OTGSC_INTSTS_A_SESSION_VALID (0x1<<18) +#define OTGSC_INTSTS_B_SESSION_VALID (0x1<<19) +#define OTGSC_INTSTS_B_SESSION_END (0x1<<20) +#define OTGSC_INTSTS_1MS (0x1<<21) +#define OTGSC_INTSTS_DATA_PULSING (0x1<<22) +#define OTGSC_INTR_USB_ID_EN (0x1<<24) +#define OTGSC_INTR_A_VBUS_VALID_EN (0x1<<25) +#define OTGSC_INTR_A_SESSION_VALID_EN (0x1<<26) +#define OTGSC_INTR_B_SESSION_VALID_EN (0x1<<27) +#define OTGSC_INTR_B_SESSION_END_EN (0x1<<28) +#define OTGSC_INTR_1MS_TIMER_EN (0x1<<29) +#define OTGSC_INTR_DATA_PULSING_EN (0x1<<30) +#define OTGSC_INTSTS_MASK (0x00ff0000) + +/* USB MODE Register Bit Masks */ +#define USB_MODE_CTRL_MODE_IDLE (0x0<<0) +#define USB_MODE_CTRL_MODE_DEVICE (0x2<<0) +#define USB_MODE_CTRL_MODE_HOST (0x3<<0) +#define USB_MODE_CTRL_MODE_RSV (0x1<<0) +#define USB_MODE_SETUP_LOCK_OFF (0x1<<3) +#define USB_MODE_STREAM_DISABLE (0x1<<4) +#define USB_MODE_ES (0x1<<2) /* Endian Select */ + +/* control Register Bit Masks */ +#define USB_CTRL_IOENB (0x1<<2) +#define USB_CTRL_ULPI_INT0EN (0x1<<0) + +/* BCSR5 */ +#define BCSR5_INT_USB (0x02) + +/* USB module clk cfg */ +#define SCCR_OFFS (0xA08) +#define SCCR_USB_CLK_DISABLE (0x00000000) /* USB clk disable */ +#define SCCR_USB_MPHCM_11 (0x00c00000) +#define SCCR_USB_MPHCM_01 (0x00400000) +#define SCCR_USB_MPHCM_10 (0x00800000) +#define SCCR_USB_DRCM_11 (0x00300000) +#define SCCR_USB_DRCM_01 (0x00100000) +#define SCCR_USB_DRCM_10 (0x00200000) + +#define SICRL_OFFS (0x114) +#define SICRL_USB0 (0x40000000) +#define SICRL_USB1 (0x20000000) + +#define SICRH_OFFS (0x118) +#define SICRH_USB_UTMI (0x00020000) + +/* OTG interrupt enable bit masks */ +#define OTGSC_INTERRUPT_ENABLE_BITS_MASK \ + (OTGSC_INTR_USB_ID_EN | \ + OTGSC_INTR_1MS_TIMER_EN | \ + OTGSC_INTR_A_VBUS_VALID_EN | \ + OTGSC_INTR_A_SESSION_VALID_EN | \ + OTGSC_INTR_B_SESSION_VALID_EN | \ + OTGSC_INTR_B_SESSION_END_EN | \ + OTGSC_INTR_DATA_PULSING_EN) + +/* OTG interrupt status bit masks */ +#define OTGSC_INTERRUPT_STATUS_BITS_MASK \ + (OTGSC_INTSTS_USB_ID | \ + OTGSC_INTR_1MS_TIMER_EN | \ + OTGSC_INTSTS_A_VBUS_VALID | \ + OTGSC_INTSTS_A_SESSION_VALID | \ + OTGSC_INTSTS_B_SESSION_VALID | \ + OTGSC_INTSTS_B_SESSION_END | \ + OTGSC_INTSTS_DATA_PULSING) + +/* + * A-DEVICE timing constants + */ + +/* Wait for VBUS Rise */ +#define TA_WAIT_VRISE (100) /* a_wait_vrise 100 ms, section: 6.6.5.1 */ + +/* Wait for B-Connect */ +#define TA_WAIT_BCON (10000) /* a_wait_bcon > 1 sec, section: 6.6.5.2 + * This is only used to get out of + * OTG_STATE_A_WAIT_BCON state if there was + * no connection for these many milliseconds + */ + +/* A-Idle to B-Disconnect */ +/* It is necessary for this timer to be more than 750 ms because of a bug in OPT + * test 5.4 in which B OPT disconnects after 750 ms instead of 75ms as stated + * in the test description + */ +#define TA_AIDL_BDIS (5000) /* a_suspend minimum 200 ms, section: 6.6.5.3 */ + +/* B-Idle to A-Disconnect */ +#define TA_BIDL_ADIS (12) /* 3 to 200 ms */ + +/* B-device timing constants */ + + +/* Data-Line Pulse Time*/ +#define TB_DATA_PLS (10) /* b_srp_init,continue 5~10ms, section:5.3.3 */ +#define TB_DATA_PLS_MIN (5) /* minimum 5 ms */ +#define TB_DATA_PLS_MAX (10) /* maximum 10 ms */ + +/* SRP Initiate Time */ +#define TB_SRP_INIT (100) /* b_srp_init,maximum 100 ms, section:5.3.8 */ + +/* SRP Fail Time */ +#define TB_SRP_FAIL (7000) /* b_srp_init,Fail time 5~30s, section:6.8.2.2*/ + +/* SRP result wait time */ +#define TB_SRP_WAIT (60) + +/* VBus time */ +#define TB_VBUS_PLS (30) /* time to keep vbus pulsing asserted */ + +/* Discharge time */ +/* This time should be less than 10ms. It varies from system to system. */ +#define TB_VBUS_DSCHRG (8) + +/* A-SE0 to B-Reset */ +#define TB_ASE0_BRST (20) /* b_wait_acon, mini 3.125 ms,section:6.8.2.4 */ + +/* A bus suspend timer before we can switch to b_wait_aconn */ +#define TB_A_SUSPEND (7) +#define TB_BUS_RESUME (12) + +/* SE0 Time Before SRP */ +#define TB_SE0_SRP (2) /* b_idle,minimum 2 ms, section:5.3.2 */ + +#define SET_OTG_STATE(otg_ptr, newstate) ((otg_ptr)->state = newstate) + +struct usb_dr_mmap { + /* Capability register */ + u8 res1[256]; + u16 caplength; /* Capability Register Length */ + u16 hciversion; /* Host Controller Interface Version */ + u32 hcsparams; /* Host Controller Structual Parameters */ + u32 hccparams; /* Host Controller Capability Parameters */ + u8 res2[20]; + u32 dciversion; /* Device Controller Interface Version */ + u32 dccparams; /* Device Controller Capability Parameters */ + u8 res3[24]; + /* Operation register */ + u32 usbcmd; /* USB Command Register */ + u32 usbsts; /* USB Status Register */ + u32 usbintr; /* USB Interrupt Enable Register */ + u32 frindex; /* Frame Index Register */ + u8 res4[4]; + u32 deviceaddr; /* Device Address */ + u32 endpointlistaddr; /* Endpoint List Address Register */ + u8 res5[4]; + u32 burstsize; /* Master Interface Data Burst Size Register */ + u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ + u8 res6[8]; + u32 ulpiview; /* ULPI register access */ + u8 res7[12]; + u32 configflag; /* Configure Flag Register */ + u32 portsc; /* Port 1 Status and Control Register */ + u8 res8[28]; + u32 otgsc; /* On-The-Go Status and Control */ + u32 usbmode; /* USB Mode Register */ + u32 endptsetupstat; /* Endpoint Setup Status Register */ + u32 endpointprime; /* Endpoint Initialization Register */ + u32 endptflush; /* Endpoint Flush Register */ + u32 endptstatus; /* Endpoint Status Register */ + u32 endptcomplete; /* Endpoint Complete Register */ + u32 endptctrl[6]; /* Endpoint Control Registers */ + u8 res9[552]; + u32 snoop1; + u32 snoop2; + u32 age_cnt_thresh; /* Age Count Threshold Register */ + u32 pri_ctrl; /* Priority Control Register */ + u32 si_ctrl; /* System Interface Control Register */ + u8 res10[236]; + u32 control; /* General Purpose Control Register */ +}; + +struct fsl_otg_timer { + unsigned long expires; /* Number of count increase to timeout */ + unsigned long count; /* Tick counter */ + void (*function)(unsigned long); /* Timeout function */ + unsigned long data; /* Data passed to function */ + struct list_head list; +}; + +inline struct fsl_otg_timer *otg_timer_initializer +(void (*function)(unsigned long), unsigned long expires, unsigned long data) +{ + struct fsl_otg_timer *timer; + + timer = kmalloc(sizeof(struct fsl_otg_timer), GFP_KERNEL); + if (!timer) + return NULL; + timer->function = function; + timer->expires = expires; + timer->data = data; + return timer; +} + +struct fsl_otg { + struct usb_phy phy; + struct otg_fsm fsm; + struct usb_dr_mmap *dr_mem_map; + struct delayed_work otg_event; + + /* used for usb host */ + struct work_struct work_wq; + u8 host_working; + + int irq; +}; + +struct fsl_otg_config { + u8 otg_port; +}; + +/* For SRP and HNP handle */ +#define FSL_OTG_MAJOR 240 +#define FSL_OTG_NAME "fsl-usb2-otg" +/* Command to OTG driver ioctl */ +#define OTG_IOCTL_MAGIC FSL_OTG_MAJOR +/* if otg work as host, it should return 1, otherwise return 0 */ +#define GET_OTG_STATUS _IOR(OTG_IOCTL_MAGIC, 1, int) +#define SET_A_SUSPEND_REQ _IOW(OTG_IOCTL_MAGIC, 2, int) +#define SET_A_BUS_DROP _IOW(OTG_IOCTL_MAGIC, 3, int) +#define SET_A_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 4, int) +#define SET_B_BUS_REQ _IOW(OTG_IOCTL_MAGIC, 5, int) +#define GET_A_SUSPEND_REQ _IOR(OTG_IOCTL_MAGIC, 6, int) +#define GET_A_BUS_DROP _IOR(OTG_IOCTL_MAGIC, 7, int) +#define GET_A_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 8, int) +#define GET_B_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 9, int) + +void fsl_otg_add_timer(void *timer); +void fsl_otg_del_timer(void *timer); +void fsl_otg_pulse_vbus(void); diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c new file mode 100644 index 000000000000..c520b3548e7c --- /dev/null +++ b/drivers/usb/phy/phy-fsm-usb.c @@ -0,0 +1,348 @@ +/* + * OTG Finite State Machine from OTG spec + * + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * Author: Li Yang + * Jerry Huang + * + * 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 "phy-otg-fsm.h" + +/* Change USB protocol when there is a protocol change */ +static int otg_set_protocol(struct otg_fsm *fsm, int protocol) +{ + int ret = 0; + + if (fsm->protocol != protocol) { + VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", + fsm->protocol, protocol); + /* stop old protocol */ + if (fsm->protocol == PROTO_HOST) + ret = fsm->ops->start_host(fsm, 0); + else if (fsm->protocol == PROTO_GADGET) + ret = fsm->ops->start_gadget(fsm, 0); + if (ret) + return ret; + + /* start new protocol */ + if (protocol == PROTO_HOST) + ret = fsm->ops->start_host(fsm, 1); + else if (protocol == PROTO_GADGET) + ret = fsm->ops->start_gadget(fsm, 1); + if (ret) + return ret; + + fsm->protocol = protocol; + return 0; + } + + return 0; +} + +static int state_changed; + +/* Called when leaving a state. Do state clean up jobs here */ +void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) +{ + switch (old_state) { + case OTG_STATE_B_IDLE: + otg_del_timer(fsm, b_se0_srp_tmr); + fsm->b_se0_srp = 0; + break; + case OTG_STATE_B_SRP_INIT: + fsm->b_srp_done = 0; + break; + case OTG_STATE_B_PERIPHERAL: + break; + case OTG_STATE_B_WAIT_ACON: + otg_del_timer(fsm, b_ase0_brst_tmr); + fsm->b_ase0_brst_tmout = 0; + break; + case OTG_STATE_B_HOST: + break; + case OTG_STATE_A_IDLE: + break; + case OTG_STATE_A_WAIT_VRISE: + otg_del_timer(fsm, a_wait_vrise_tmr); + fsm->a_wait_vrise_tmout = 0; + break; + case OTG_STATE_A_WAIT_BCON: + otg_del_timer(fsm, a_wait_bcon_tmr); + fsm->a_wait_bcon_tmout = 0; + break; + case OTG_STATE_A_HOST: + otg_del_timer(fsm, a_wait_enum_tmr); + break; + case OTG_STATE_A_SUSPEND: + otg_del_timer(fsm, a_aidl_bdis_tmr); + fsm->a_aidl_bdis_tmout = 0; + fsm->a_suspend_req = 0; + break; + case OTG_STATE_A_PERIPHERAL: + break; + case OTG_STATE_A_WAIT_VFALL: + otg_del_timer(fsm, a_wait_vrise_tmr); + break; + case OTG_STATE_A_VBUS_ERR: + break; + default: + break; + } +} + +/* Called when entering a state */ +int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) +{ + state_changed = 1; + if (fsm->otg->phy->state == new_state) + return 0; + VDBG("Set state: %s\n", usb_otg_state_string(new_state)); + otg_leave_state(fsm, fsm->otg->phy->state); + switch (new_state) { + case OTG_STATE_B_IDLE: + otg_drv_vbus(fsm, 0); + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + otg_add_timer(fsm, b_se0_srp_tmr); + break; + case OTG_STATE_B_SRP_INIT: + otg_start_pulse(fsm); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + otg_add_timer(fsm, b_srp_fail_tmr); + break; + case OTG_STATE_B_PERIPHERAL: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 1); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_GADGET); + break; + case OTG_STATE_B_WAIT_ACON: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, b_ase0_brst_tmr); + fsm->a_bus_suspend = 0; + break; + case OTG_STATE_B_HOST: + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 1); + otg_set_protocol(fsm, PROTO_HOST); + usb_bus_start_enum(fsm->otg->host, + fsm->otg->host->otg_port); + break; + case OTG_STATE_A_IDLE: + otg_drv_vbus(fsm, 0); + otg_chrg_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + break; + case OTG_STATE_A_WAIT_VRISE: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_wait_vrise_tmr); + break; + case OTG_STATE_A_WAIT_BCON: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_wait_bcon_tmr); + break; + case OTG_STATE_A_HOST: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 1); + otg_set_protocol(fsm, PROTO_HOST); + /* + * When HNP is triggered while a_bus_req = 0, a_host will + * suspend too fast to complete a_set_b_hnp_en + */ + if (!fsm->a_bus_req || fsm->a_suspend_req) + otg_add_timer(fsm, a_wait_enum_tmr); + break; + case OTG_STATE_A_SUSPEND: + otg_drv_vbus(fsm, 1); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + otg_add_timer(fsm, a_aidl_bdis_tmr); + + break; + case OTG_STATE_A_PERIPHERAL: + otg_loc_conn(fsm, 1); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_GADGET); + otg_drv_vbus(fsm, 1); + break; + case OTG_STATE_A_WAIT_VFALL: + otg_drv_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_HOST); + break; + case OTG_STATE_A_VBUS_ERR: + otg_drv_vbus(fsm, 0); + otg_loc_conn(fsm, 0); + otg_loc_sof(fsm, 0); + otg_set_protocol(fsm, PROTO_UNDEF); + break; + default: + break; + } + + fsm->otg->phy->state = new_state; + return 0; +} + +/* State change judgement */ +int otg_statemachine(struct otg_fsm *fsm) +{ + enum usb_otg_state state; + unsigned long flags; + + spin_lock_irqsave(&fsm->lock, flags); + + state = fsm->otg->phy->state; + state_changed = 0; + /* State machine state change judgement */ + + switch (state) { + case OTG_STATE_UNDEFINED: + VDBG("fsm->id = %d\n", fsm->id); + if (fsm->id) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else + otg_set_state(fsm, OTG_STATE_A_IDLE); + break; + case OTG_STATE_B_IDLE: + if (!fsm->id) + otg_set_state(fsm, OTG_STATE_A_IDLE); + else if (fsm->b_sess_vld && fsm->otg->gadget) + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp) + otg_set_state(fsm, OTG_STATE_B_SRP_INIT); + break; + case OTG_STATE_B_SRP_INIT: + if (!fsm->id || fsm->b_srp_done) + otg_set_state(fsm, OTG_STATE_B_IDLE); + break; + case OTG_STATE_B_PERIPHERAL: + if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (fsm->b_bus_req && fsm->otg-> + gadget->b_hnp_enable && fsm->a_bus_suspend) + otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); + break; + case OTG_STATE_B_WAIT_ACON: + if (fsm->a_conn) + otg_set_state(fsm, OTG_STATE_B_HOST); + else if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { + fsm->b_ase0_brst_tmout = 0; + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + } + break; + case OTG_STATE_B_HOST: + if (!fsm->id || !fsm->b_sess_vld) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (!fsm->b_bus_req || !fsm->a_conn) + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); + break; + case OTG_STATE_A_IDLE: + if (fsm->id) + otg_set_state(fsm, OTG_STATE_B_IDLE); + else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) + otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); + break; + case OTG_STATE_A_WAIT_VRISE: + if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld || + fsm->a_wait_vrise_tmout) { + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + } + break; + case OTG_STATE_A_WAIT_BCON: + if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + else if (fsm->b_conn) + otg_set_state(fsm, OTG_STATE_A_HOST); + else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + break; + case OTG_STATE_A_HOST: + if ((!fsm->a_bus_req || fsm->a_suspend_req) && + fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_SUSPEND); + else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_SUSPEND: + if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); + else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (fsm->a_bus_req || fsm->b_bus_resume) + otg_set_state(fsm, OTG_STATE_A_HOST); + else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_PERIPHERAL: + if (fsm->id || fsm->a_bus_drop) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + else if (fsm->b_bus_suspend) + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); + else if (!fsm->a_vbus_vld) + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); + break; + case OTG_STATE_A_WAIT_VFALL: + if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld && + !fsm->b_conn)) + otg_set_state(fsm, OTG_STATE_A_IDLE); + break; + case OTG_STATE_A_VBUS_ERR: + if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); + break; + default: + break; + } + spin_unlock_irqrestore(&fsm->lock, flags); + + VDBG("quit statemachine, changed = %d\n", state_changed); + return state_changed; +} diff --git a/drivers/usb/phy/phy-fsm-usb.h b/drivers/usb/phy/phy-fsm-usb.h new file mode 100644 index 000000000000..c30a2e1d9e46 --- /dev/null +++ b/drivers/usb/phy/phy-fsm-usb.h @@ -0,0 +1,154 @@ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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. + */ + +#undef DEBUG +#undef VERBOSE + +#ifdef DEBUG +#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt , \ + __func__, ## args) +#else +#define DBG(fmt, args...) do {} while (0) +#endif + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(stuff...) do {} while (0) +#endif + +#ifdef VERBOSE +#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__) +#else +#define MPC_LOC do {} while (0) +#endif + +#define PROTO_UNDEF (0) +#define PROTO_HOST (1) +#define PROTO_GADGET (2) + +/* OTG state machine according to the OTG spec */ +struct otg_fsm { + /* Input */ + int a_bus_resume; + int a_bus_suspend; + int a_conn; + int a_sess_vld; + int a_srp_det; + int a_vbus_vld; + int b_bus_resume; + int b_bus_suspend; + int b_conn; + int b_se0_srp; + int b_sess_end; + int b_sess_vld; + int id; + + /* Internal variables */ + int a_set_b_hnp_en; + int b_srp_done; + int b_hnp_enable; + + /* Timeout indicator for timers */ + int a_wait_vrise_tmout; + int a_wait_bcon_tmout; + int a_aidl_bdis_tmout; + int b_ase0_brst_tmout; + + /* Informative variables */ + int a_bus_drop; + int a_bus_req; + int a_clr_err; + int a_suspend_req; + int b_bus_req; + + /* Output */ + int drv_vbus; + int loc_conn; + int loc_sof; + + struct otg_fsm_ops *ops; + struct usb_otg *otg; + + /* Current usb protocol used: 0:undefine; 1:host; 2:client */ + int protocol; + spinlock_t lock; +}; + +struct otg_fsm_ops { + void (*chrg_vbus)(int on); + void (*drv_vbus)(int on); + void (*loc_conn)(int on); + void (*loc_sof)(int on); + void (*start_pulse)(void); + void (*add_timer)(void *timer); + void (*del_timer)(void *timer); + int (*start_host)(struct otg_fsm *fsm, int on); + int (*start_gadget)(struct otg_fsm *fsm, int on); +}; + + +static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on) +{ + fsm->ops->chrg_vbus(on); +} + +static inline void otg_drv_vbus(struct otg_fsm *fsm, int on) +{ + if (fsm->drv_vbus != on) { + fsm->drv_vbus = on; + fsm->ops->drv_vbus(on); + } +} + +static inline void otg_loc_conn(struct otg_fsm *fsm, int on) +{ + if (fsm->loc_conn != on) { + fsm->loc_conn = on; + fsm->ops->loc_conn(on); + } +} + +static inline void otg_loc_sof(struct otg_fsm *fsm, int on) +{ + if (fsm->loc_sof != on) { + fsm->loc_sof = on; + fsm->ops->loc_sof(on); + } +} + +static inline void otg_start_pulse(struct otg_fsm *fsm) +{ + fsm->ops->start_pulse(); +} + +static inline void otg_add_timer(struct otg_fsm *fsm, void *timer) +{ + fsm->ops->add_timer(timer); +} + +static inline void otg_del_timer(struct otg_fsm *fsm, void *timer) +{ + fsm->ops->del_timer(timer); +} + +int otg_statemachine(struct otg_fsm *fsm); + +/* Defined by device specific driver, for different timer implementation */ +extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, + *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, + *a_wait_enum_tmr; diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c new file mode 100644 index 000000000000..a7d4ac591982 --- /dev/null +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -0,0 +1,416 @@ +/* + * gpio-vbus.c - simple GPIO VBUS sensing driver for B peripheral devices + * + * Copyright (c) 2008 Philipp Zabel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +/* + * A simple GPIO VBUS sensing driver for B peripheral only devices + * with internal transceivers. It can control a D+ pullup GPIO and + * a regulator to limit the current drawn from VBUS. + * + * Needs to be loaded before the UDC driver that will use it. + */ +struct gpio_vbus_data { + struct usb_phy phy; + struct device *dev; + struct regulator *vbus_draw; + int vbus_draw_enabled; + unsigned mA; + struct delayed_work work; + int vbus; + int irq; +}; + + +/* + * This driver relies on "both edges" triggering. VBUS has 100 msec to + * stabilize, so the peripheral controller driver may need to cope with + * some bouncing due to current surges (e.g. charging local capacitance) + * and contact chatter. + * + * REVISIT in desperate straits, toggling between rising and falling + * edges might be workable. + */ +#define VBUS_IRQ_FLAGS \ + (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) + + +/* interface to regulator framework */ +static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) +{ + struct regulator *vbus_draw = gpio_vbus->vbus_draw; + int enabled; + + if (!vbus_draw) + return; + + enabled = gpio_vbus->vbus_draw_enabled; + if (mA) { + regulator_set_current_limit(vbus_draw, 0, 1000 * mA); + if (!enabled) { + regulator_enable(vbus_draw); + gpio_vbus->vbus_draw_enabled = 1; + } + } else { + if (enabled) { + regulator_disable(vbus_draw); + gpio_vbus->vbus_draw_enabled = 0; + } + } + gpio_vbus->mA = mA; +} + +static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) +{ + int vbus; + + vbus = gpio_get_value(pdata->gpio_vbus); + if (pdata->gpio_vbus_inverted) + vbus = !vbus; + + return vbus; +} + +static void gpio_vbus_work(struct work_struct *work) +{ + struct gpio_vbus_data *gpio_vbus = + container_of(work, struct gpio_vbus_data, work.work); + struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; + int gpio, status, vbus; + + if (!gpio_vbus->phy.otg->gadget) + return; + + vbus = is_vbus_powered(pdata); + if ((vbus ^ gpio_vbus->vbus) == 0) + return; + gpio_vbus->vbus = vbus; + + /* Peripheral controllers which manage the pullup themselves won't have + * gpio_pullup configured here. If it's configured here, we'll do what + * isp1301_omap::b_peripheral() does and enable the pullup here... although + * that may complicate usb_gadget_{,dis}connect() support. + */ + gpio = pdata->gpio_pullup; + + if (vbus) { + status = USB_EVENT_VBUS; + gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; + gpio_vbus->phy.last_event = status; + usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); + + /* drawing a "unit load" is *always* OK, except for OTG */ + set_vbus_draw(gpio_vbus, 100); + + /* optionally enable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, !pdata->gpio_pullup_inverted); + + atomic_notifier_call_chain(&gpio_vbus->phy.notifier, + status, gpio_vbus->phy.otg->gadget); + } else { + /* optionally disable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, pdata->gpio_pullup_inverted); + + set_vbus_draw(gpio_vbus, 0); + + usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); + status = USB_EVENT_NONE; + gpio_vbus->phy.state = OTG_STATE_B_IDLE; + gpio_vbus->phy.last_event = status; + + atomic_notifier_call_chain(&gpio_vbus->phy.notifier, + status, gpio_vbus->phy.otg->gadget); + } +} + +/* VBUS change IRQ handler */ +static irqreturn_t gpio_vbus_irq(int irq, void *data) +{ + struct platform_device *pdev = data; + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); + struct usb_otg *otg = gpio_vbus->phy.otg; + + dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", + is_vbus_powered(pdata) ? "supplied" : "inactive", + otg->gadget ? otg->gadget->name : "none"); + + if (otg->gadget) + schedule_delayed_work(&gpio_vbus->work, msecs_to_jiffies(100)); + + return IRQ_HANDLED; +} + +/* OTG transceiver interface */ + +/* bind/unbind the peripheral controller */ +static int gpio_vbus_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct gpio_vbus_data *gpio_vbus; + struct gpio_vbus_mach_info *pdata; + struct platform_device *pdev; + int gpio; + + gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); + pdev = to_platform_device(gpio_vbus->dev); + pdata = gpio_vbus->dev->platform_data; + gpio = pdata->gpio_pullup; + + if (!gadget) { + dev_dbg(&pdev->dev, "unregistering gadget '%s'\n", + otg->gadget->name); + + /* optionally disable D+ pullup */ + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, pdata->gpio_pullup_inverted); + + set_vbus_draw(gpio_vbus, 0); + + usb_gadget_vbus_disconnect(otg->gadget); + otg->phy->state = OTG_STATE_UNDEFINED; + + otg->gadget = NULL; + return 0; + } + + otg->gadget = gadget; + dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name); + + /* initialize connection state */ + gpio_vbus->vbus = 0; /* start with disconnected */ + gpio_vbus_irq(gpio_vbus->irq, pdev); + return 0; +} + +/* effective for B devices, ignored for A-peripheral */ +static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) +{ + struct gpio_vbus_data *gpio_vbus; + + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); + + if (phy->state == OTG_STATE_B_PERIPHERAL) + set_vbus_draw(gpio_vbus, mA); + return 0; +} + +/* for non-OTG B devices: set/clear transceiver suspend mode */ +static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) +{ + struct gpio_vbus_data *gpio_vbus; + + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); + + /* draw max 0 mA from vbus in suspend mode; or the previously + * recorded amount of current if not suspended + * + * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA + * if they're wake-enabled ... we don't handle that yet. + */ + return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); +} + +/* platform driver interface */ + +static int __init gpio_vbus_probe(struct platform_device *pdev) +{ + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + struct gpio_vbus_data *gpio_vbus; + struct resource *res; + int err, gpio, irq; + unsigned long irqflags; + + if (!pdata || !gpio_is_valid(pdata->gpio_vbus)) + return -EINVAL; + gpio = pdata->gpio_vbus; + + gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL); + if (!gpio_vbus) + return -ENOMEM; + + gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!gpio_vbus->phy.otg) { + kfree(gpio_vbus); + return -ENOMEM; + } + + platform_set_drvdata(pdev, gpio_vbus); + gpio_vbus->dev = &pdev->dev; + gpio_vbus->phy.label = "gpio-vbus"; + gpio_vbus->phy.set_power = gpio_vbus_set_power; + gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; + gpio_vbus->phy.state = OTG_STATE_UNDEFINED; + + gpio_vbus->phy.otg->phy = &gpio_vbus->phy; + gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; + + err = gpio_request(gpio, "vbus_detect"); + if (err) { + dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n", + gpio, err); + goto err_gpio; + } + gpio_direction_input(gpio); + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res) { + irq = res->start; + irqflags = (res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; + } else { + irq = gpio_to_irq(gpio); + irqflags = VBUS_IRQ_FLAGS; + } + + gpio_vbus->irq = irq; + + /* if data line pullup is in use, initialize it to "not pulling up" */ + gpio = pdata->gpio_pullup; + if (gpio_is_valid(gpio)) { + err = gpio_request(gpio, "udc_pullup"); + if (err) { + dev_err(&pdev->dev, + "can't request pullup gpio %d, err: %d\n", + gpio, err); + gpio_free(pdata->gpio_vbus); + goto err_gpio; + } + gpio_direction_output(gpio, pdata->gpio_pullup_inverted); + } + + err = request_irq(irq, gpio_vbus_irq, irqflags, "vbus_detect", pdev); + if (err) { + dev_err(&pdev->dev, "can't request irq %i, err: %d\n", + irq, err); + goto err_irq; + } + + ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); + + INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work); + + gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); + if (IS_ERR(gpio_vbus->vbus_draw)) { + dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", + PTR_ERR(gpio_vbus->vbus_draw)); + gpio_vbus->vbus_draw = NULL; + } + + /* only active when a gadget is registered */ + err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); + if (err) { + dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + err); + goto err_otg; + } + + device_init_wakeup(&pdev->dev, pdata->wakeup); + + return 0; +err_otg: + regulator_put(gpio_vbus->vbus_draw); + free_irq(irq, pdev); +err_irq: + if (gpio_is_valid(pdata->gpio_pullup)) + gpio_free(pdata->gpio_pullup); + gpio_free(pdata->gpio_vbus); +err_gpio: + platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); + kfree(gpio_vbus); + return err; +} + +static int __exit gpio_vbus_remove(struct platform_device *pdev) +{ + struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); + struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; + int gpio = pdata->gpio_vbus; + + device_init_wakeup(&pdev->dev, 0); + cancel_delayed_work_sync(&gpio_vbus->work); + regulator_put(gpio_vbus->vbus_draw); + + usb_remove_phy(&gpio_vbus->phy); + + free_irq(gpio_vbus->irq, pdev); + if (gpio_is_valid(pdata->gpio_pullup)) + gpio_free(pdata->gpio_pullup); + gpio_free(gpio); + platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); + kfree(gpio_vbus); + + return 0; +} + +#ifdef CONFIG_PM +static int gpio_vbus_pm_suspend(struct device *dev) +{ + struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(gpio_vbus->irq); + + return 0; +} + +static int gpio_vbus_pm_resume(struct device *dev) +{ + struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(gpio_vbus->irq); + + return 0; +} + +static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { + .suspend = gpio_vbus_pm_suspend, + .resume = gpio_vbus_pm_resume, +}; +#endif + +/* NOTE: the gpio-vbus device may *NOT* be hotplugged */ + +MODULE_ALIAS("platform:gpio-vbus"); + +static struct platform_driver gpio_vbus_driver = { + .driver = { + .name = "gpio-vbus", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &gpio_vbus_dev_pm_ops, +#endif + }, + .remove = __exit_p(gpio_vbus_remove), +}; + +module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe); + +MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); +MODULE_AUTHOR("Philipp Zabel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c new file mode 100644 index 000000000000..8fe0c3b95261 --- /dev/null +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -0,0 +1,1656 @@ +/* + * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller + * + * Copyright (C) 2004 Texas Instruments + * Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#ifndef DEBUG +#undef VERBOSE +#endif + + +#define DRIVER_VERSION "24 August 2004" +#define DRIVER_NAME (isp1301_driver.driver.name) + +MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver"); +MODULE_LICENSE("GPL"); + +struct isp1301 { + struct usb_phy phy; + struct i2c_client *client; + void (*i2c_release)(struct device *dev); + + int irq_type; + + u32 last_otg_ctrl; + unsigned working:1; + + struct timer_list timer; + + /* use keventd context to change the state for us */ + struct work_struct work; + + unsigned long todo; +# define WORK_UPDATE_ISP 0 /* update ISP from OTG */ +# define WORK_UPDATE_OTG 1 /* update OTG from ISP */ +# define WORK_HOST_RESUME 4 /* resume host */ +# define WORK_TIMER 6 /* timer fired */ +# define WORK_STOP 7 /* don't resubmit */ +}; + + +/* bits in OTG_CTRL */ + +#define OTG_XCEIV_OUTPUTS \ + (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) +#define OTG_XCEIV_INPUTS \ + (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID) +#define OTG_CTRL_BITS \ + (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|OTG_B_HNPEN|OTG_BUSDROP) + /* and OTG_PULLUP is sometimes written */ + +#define OTG_CTRL_MASK (OTG_DRIVER_SEL| \ + OTG_XCEIV_OUTPUTS|OTG_XCEIV_INPUTS| \ + OTG_CTRL_BITS) + + +/*-------------------------------------------------------------------------*/ + +/* board-specific PM hooks */ + +#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) + +#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) + +#include + +#else + +static inline int tps65010_set_vbus_draw(unsigned mA) +{ + pr_debug("tps65010: draw %d mA (STUB)\n", mA); + return 0; +} + +#endif + +static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) +{ + int status = tps65010_set_vbus_draw(mA); + if (status < 0) + pr_debug(" VBUS %d mA error %d\n", mA, status); +} + +#else + +static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) +{ + /* H4 controls this by DIP switch S2.4; no soft control. + * ON means the charger is always enabled. Leave it OFF + * unless the OTG port is used only in B-peripheral mode. + */ +} + +#endif + +static void enable_vbus_source(struct isp1301 *isp) +{ + /* this board won't supply more than 8mA vbus power. + * some boards can switch a 100ma "unit load" (or more). + */ +} + + +/* products will deliver OTG messages with LEDs, GUI, etc */ +static inline void notresponding(struct isp1301 *isp) +{ + printk(KERN_NOTICE "OTG device not responding.\n"); +} + + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver isp1301_driver; + +/* smbus apis are used for portability */ + +static inline u8 +isp1301_get_u8(struct isp1301 *isp, u8 reg) +{ + return i2c_smbus_read_byte_data(isp->client, reg + 0); +} + +static inline int +isp1301_get_u16(struct isp1301 *isp, u8 reg) +{ + return i2c_smbus_read_word_data(isp->client, reg); +} + +static inline int +isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) +{ + return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); +} + +static inline int +isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) +{ + return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); +} + +/*-------------------------------------------------------------------------*/ + +/* identification */ +#define ISP1301_VENDOR_ID 0x00 /* u16 read */ +#define ISP1301_PRODUCT_ID 0x02 /* u16 read */ +#define ISP1301_BCD_DEVICE 0x14 /* u16 read */ + +#define I2C_VENDOR_ID_PHILIPS 0x04cc +#define I2C_PRODUCT_ID_PHILIPS_1301 0x1301 + +/* operational registers */ +#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ +# define MC1_SPEED (1 << 0) +# define MC1_SUSPEND (1 << 1) +# define MC1_DAT_SE0 (1 << 2) +# define MC1_TRANSPARENT (1 << 3) +# define MC1_BDIS_ACON_EN (1 << 4) +# define MC1_OE_INT_EN (1 << 5) +# define MC1_UART_EN (1 << 6) +# define MC1_MASK 0x7f +#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */ +# define MC2_GLOBAL_PWR_DN (1 << 0) +# define MC2_SPD_SUSP_CTRL (1 << 1) +# define MC2_BI_DI (1 << 2) +# define MC2_TRANSP_BDIR0 (1 << 3) +# define MC2_TRANSP_BDIR1 (1 << 4) +# define MC2_AUDIO_EN (1 << 5) +# define MC2_PSW_EN (1 << 6) +# define MC2_EN2V7 (1 << 7) +#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */ +# define OTG1_DP_PULLUP (1 << 0) +# define OTG1_DM_PULLUP (1 << 1) +# define OTG1_DP_PULLDOWN (1 << 2) +# define OTG1_DM_PULLDOWN (1 << 3) +# define OTG1_ID_PULLDOWN (1 << 4) +# define OTG1_VBUS_DRV (1 << 5) +# define OTG1_VBUS_DISCHRG (1 << 6) +# define OTG1_VBUS_CHRG (1 << 7) +#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */ +# define OTG_B_SESS_END (1 << 6) +# define OTG_B_SESS_VLD (1 << 7) + +#define ISP1301_INTERRUPT_SOURCE 0x08 /* u8 read */ +#define ISP1301_INTERRUPT_LATCH 0x0A /* u8 read, set, +1 clear */ + +#define ISP1301_INTERRUPT_FALLING 0x0C /* u8 read, set, +1 clear */ +#define ISP1301_INTERRUPT_RISING 0x0E /* u8 read, set, +1 clear */ + +/* same bitfields in all interrupt registers */ +# define INTR_VBUS_VLD (1 << 0) +# define INTR_SESS_VLD (1 << 1) +# define INTR_DP_HI (1 << 2) +# define INTR_ID_GND (1 << 3) +# define INTR_DM_HI (1 << 4) +# define INTR_ID_FLOAT (1 << 5) +# define INTR_BDIS_ACON (1 << 6) +# define INTR_CR_INT (1 << 7) + +/*-------------------------------------------------------------------------*/ + +static inline const char *state_name(struct isp1301 *isp) +{ + return usb_otg_state_string(isp->phy.state); +} + +/*-------------------------------------------------------------------------*/ + +/* NOTE: some of this ISP1301 setup is specific to H2 boards; + * not everything is guarded by board-specific checks, or even using + * omap_usb_config data to deduce MC1_DAT_SE0 and MC2_BI_DI. + * + * ALSO: this currently doesn't use ISP1301 low-power modes + * while OTG is running. + */ + +static void power_down(struct isp1301 *isp) +{ + isp->phy.state = OTG_STATE_UNDEFINED; + + // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); +} + +static void power_up(struct isp1301 *isp) +{ + // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + + /* do this only when cpu is driving transceiver, + * so host won't see a low speed device... + */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); +} + +#define NO_HOST_SUSPEND + +static int host_suspend(struct isp1301 *isp) +{ +#ifdef NO_HOST_SUSPEND + return 0; +#else + struct device *dev; + + if (!isp->phy.otg->host) + return -ENODEV; + + /* Currently ASSUMES only the OTG port matters; + * other ports could be active... + */ + dev = isp->phy.otg->host->controller; + return dev->driver->suspend(dev, 3, 0); +#endif +} + +static int host_resume(struct isp1301 *isp) +{ +#ifdef NO_HOST_SUSPEND + return 0; +#else + struct device *dev; + + if (!isp->phy.otg->host) + return -ENODEV; + + dev = isp->phy.otg->host->controller; + return dev->driver->resume(dev, 0); +#endif +} + +static int gadget_suspend(struct isp1301 *isp) +{ + isp->phy.otg->gadget->b_hnp_enable = 0; + isp->phy.otg->gadget->a_hnp_support = 0; + isp->phy.otg->gadget->a_alt_hnp_support = 0; + return usb_gadget_vbus_disconnect(isp->phy.otg->gadget); +} + +/*-------------------------------------------------------------------------*/ + +#define TIMER_MINUTES 10 +#define TIMER_JIFFIES (TIMER_MINUTES * 60 * HZ) + +/* Almost all our I2C messaging comes from a work queue's task context. + * NOTE: guaranteeing certain response times might mean we shouldn't + * share keventd's work queue; a realtime task might be safest. + */ +static void isp1301_defer_work(struct isp1301 *isp, int work) +{ + int status; + + if (isp && !test_and_set_bit(work, &isp->todo)) { + (void) get_device(&isp->client->dev); + status = schedule_work(&isp->work); + if (!status && !isp->working) + dev_vdbg(&isp->client->dev, + "work item %d may be lost\n", work); + } +} + +/* called from irq handlers */ +static void a_idle(struct isp1301 *isp, const char *tag) +{ + u32 l; + + if (isp->phy.state == OTG_STATE_A_IDLE) + return; + + isp->phy.otg->default_a = 1; + if (isp->phy.otg->host) { + isp->phy.otg->host->is_b_host = 0; + host_suspend(isp); + } + if (isp->phy.otg->gadget) { + isp->phy.otg->gadget->is_a_peripheral = 1; + gadget_suspend(isp); + } + isp->phy.state = OTG_STATE_A_IDLE; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; + pr_debug(" --> %s/%s\n", state_name(isp), tag); +} + +/* called from irq handlers */ +static void b_idle(struct isp1301 *isp, const char *tag) +{ + u32 l; + + if (isp->phy.state == OTG_STATE_B_IDLE) + return; + + isp->phy.otg->default_a = 0; + if (isp->phy.otg->host) { + isp->phy.otg->host->is_b_host = 1; + host_suspend(isp); + } + if (isp->phy.otg->gadget) { + isp->phy.otg->gadget->is_a_peripheral = 0; + gadget_suspend(isp); + } + isp->phy.state = OTG_STATE_B_IDLE; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; + pr_debug(" --> %s/%s\n", state_name(isp), tag); +} + +static void +dump_regs(struct isp1301 *isp, const char *label) +{ +#ifdef DEBUG + u8 ctrl = isp1301_get_u8(isp, ISP1301_OTG_CONTROL_1); + u8 status = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); + + pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", + omap_readl(OTG_CTRL), label, state_name(isp), + ctrl, status, src); + /* mode control and irq enables don't change much */ +#endif +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_USB_OTG + +/* + * The OMAP OTG controller handles most of the OTG state transitions. + * + * We translate isp1301 outputs (mostly voltage comparator status) into + * OTG inputs; OTG outputs (mostly pullup/pulldown controls) and HNP state + * flags into isp1301 inputs ... and infer state transitions. + */ + +#ifdef VERBOSE + +static void check_state(struct isp1301 *isp, const char *tag) +{ + enum usb_otg_state state = OTG_STATE_UNDEFINED; + u8 fsm = omap_readw(OTG_TEST) & 0x0ff; + unsigned extra = 0; + + switch (fsm) { + + /* default-b */ + case 0x0: + state = OTG_STATE_B_IDLE; + break; + case 0x3: + case 0x7: + extra = 1; + case 0x1: + state = OTG_STATE_B_PERIPHERAL; + break; + case 0x11: + state = OTG_STATE_B_SRP_INIT; + break; + + /* extra dual-role default-b states */ + case 0x12: + case 0x13: + case 0x16: + extra = 1; + case 0x17: + state = OTG_STATE_B_WAIT_ACON; + break; + case 0x34: + state = OTG_STATE_B_HOST; + break; + + /* default-a */ + case 0x36: + state = OTG_STATE_A_IDLE; + break; + case 0x3c: + state = OTG_STATE_A_WAIT_VFALL; + break; + case 0x7d: + state = OTG_STATE_A_VBUS_ERR; + break; + case 0x9e: + case 0x9f: + extra = 1; + case 0x89: + state = OTG_STATE_A_PERIPHERAL; + break; + case 0xb7: + state = OTG_STATE_A_WAIT_VRISE; + break; + case 0xb8: + state = OTG_STATE_A_WAIT_BCON; + break; + case 0xb9: + state = OTG_STATE_A_HOST; + break; + case 0xba: + state = OTG_STATE_A_SUSPEND; + break; + default: + break; + } + if (isp->phy.state == state && !extra) + return; + pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, + usb_otg_state_string(state), fsm, state_name(isp), + omap_readl(OTG_CTRL)); +} + +#else + +static inline void check_state(struct isp1301 *isp, const char *tag) { } + +#endif + +/* outputs from ISP1301_INTERRUPT_SOURCE */ +static void update_otg1(struct isp1301 *isp, u8 int_src) +{ + u32 otg_ctrl; + + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); + + if (int_src & INTR_SESS_VLD) + otg_ctrl |= OTG_ASESSVLD; + else if (isp->phy.state == OTG_STATE_A_WAIT_VFALL) { + a_idle(isp, "vfall"); + otg_ctrl &= ~OTG_CTRL_BITS; + } + if (int_src & INTR_VBUS_VLD) + otg_ctrl |= OTG_VBUSVLD; + if (int_src & INTR_ID_GND) { /* default-A */ + if (isp->phy.state == OTG_STATE_B_IDLE + || isp->phy.state + == OTG_STATE_UNDEFINED) { + a_idle(isp, "init"); + return; + } + } else { /* default-B */ + otg_ctrl |= OTG_ID; + if (isp->phy.state == OTG_STATE_A_IDLE + || isp->phy.state == OTG_STATE_UNDEFINED) { + b_idle(isp, "init"); + return; + } + } + omap_writel(otg_ctrl, OTG_CTRL); +} + +/* outputs from ISP1301_OTG_STATUS */ +static void update_otg2(struct isp1301 *isp, u8 otg_status) +{ + u32 otg_ctrl; + + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); + if (otg_status & OTG_B_SESS_VLD) + otg_ctrl |= OTG_BSESSVLD; + else if (otg_status & OTG_B_SESS_END) + otg_ctrl |= OTG_BSESSEND; + omap_writel(otg_ctrl, OTG_CTRL); +} + +/* inputs going to ISP1301 */ +static void otg_update_isp(struct isp1301 *isp) +{ + u32 otg_ctrl, otg_change; + u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; + + otg_ctrl = omap_readl(OTG_CTRL); + otg_change = otg_ctrl ^ isp->last_otg_ctrl; + isp->last_otg_ctrl = otg_ctrl; + otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; + + switch (isp->phy.state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_SRP_INIT: + if (!(otg_ctrl & OTG_PULLUP)) { + // if (otg_ctrl & OTG_B_HNPEN) { + if (isp->phy.otg->gadget->b_hnp_enable) { + isp->phy.state = OTG_STATE_B_WAIT_ACON; + pr_debug(" --> b_wait_acon\n"); + } + goto pulldown; + } +pullup: + set |= OTG1_DP_PULLUP; + clr |= OTG1_DP_PULLDOWN; + break; + case OTG_STATE_A_SUSPEND: + case OTG_STATE_A_PERIPHERAL: + if (otg_ctrl & OTG_PULLUP) + goto pullup; + /* FALLTHROUGH */ + // case OTG_STATE_B_WAIT_ACON: + default: +pulldown: + set |= OTG1_DP_PULLDOWN; + clr |= OTG1_DP_PULLUP; + break; + } + +# define toggle(OTG,ISP) do { \ + if (otg_ctrl & OTG) set |= ISP; \ + else clr |= ISP; \ + } while (0) + + if (!(isp->phy.otg->host)) + otg_ctrl &= ~OTG_DRV_VBUS; + + switch (isp->phy.state) { + case OTG_STATE_A_SUSPEND: + if (otg_ctrl & OTG_DRV_VBUS) { + set |= OTG1_VBUS_DRV; + break; + } + /* HNP failed for some reason (A_AIDL_BDIS timeout) */ + notresponding(isp); + + /* FALLTHROUGH */ + case OTG_STATE_A_VBUS_ERR: + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + pr_debug(" --> a_wait_vfall\n"); + /* FALLTHROUGH */ + case OTG_STATE_A_WAIT_VFALL: + /* FIXME usbcore thinks port power is still on ... */ + clr |= OTG1_VBUS_DRV; + break; + case OTG_STATE_A_IDLE: + if (otg_ctrl & OTG_DRV_VBUS) { + isp->phy.state = OTG_STATE_A_WAIT_VRISE; + pr_debug(" --> a_wait_vrise\n"); + } + /* FALLTHROUGH */ + default: + toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); + } + + toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); + toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); + +# undef toggle + + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); + + /* HNP switch to host or peripheral; and SRP */ + if (otg_change & OTG_PULLUP) { + u32 l; + + switch (isp->phy.state) { + case OTG_STATE_B_IDLE: + if (clr & OTG1_DP_PULLUP) + break; + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + break; + case OTG_STATE_A_SUSPEND: + if (clr & OTG1_DP_PULLUP) + break; + isp->phy.state = OTG_STATE_A_PERIPHERAL; + pr_debug(" --> a_peripheral\n"); + break; + default: + break; + } + l = omap_readl(OTG_CTRL); + l |= OTG_PULLUP; + omap_writel(l, OTG_CTRL); + } + + check_state(isp, __func__); + dump_regs(isp, "otg->isp1301"); +} + +static irqreturn_t omap_otg_irq(int irq, void *_isp) +{ + u16 otg_irq = omap_readw(OTG_IRQ_SRC); + u32 otg_ctrl; + int ret = IRQ_NONE; + struct isp1301 *isp = _isp; + struct usb_otg *otg = isp->phy.otg; + + /* update ISP1301 transceiver from OTG controller */ + if (otg_irq & OPRT_CHG) { + omap_writew(OPRT_CHG, OTG_IRQ_SRC); + isp1301_defer_work(isp, WORK_UPDATE_ISP); + ret = IRQ_HANDLED; + + /* SRP to become b_peripheral failed */ + } else if (otg_irq & B_SRP_TMROUT) { + pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); + notresponding(isp); + + /* gadget drivers that care should monitor all kinds of + * remote wakeup (SRP, normal) using their own timer + * to give "check cable and A-device" messages. + */ + if (isp->phy.state == OTG_STATE_B_SRP_INIT) + b_idle(isp, "srp_timeout"); + + omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* HNP to become b_host failed */ + } else if (otg_irq & B_HNP_FAIL) { + pr_debug("otg: %s B_HNP_FAIL, %06x\n", + state_name(isp), omap_readl(OTG_CTRL)); + notresponding(isp); + + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + + /* subset of b_peripheral()... */ + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + + omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* detect SRP from B-device ... */ + } else if (otg_irq & A_SRP_DETECT) { + pr_debug("otg: %s SRP_DETECT, %06x\n", + state_name(isp), omap_readl(OTG_CTRL)); + + isp1301_defer_work(isp, WORK_UPDATE_OTG); + switch (isp->phy.state) { + case OTG_STATE_A_IDLE: + if (!otg->host) + break; + isp1301_defer_work(isp, WORK_HOST_RESUME); + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_A_BUSREQ; + otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) + & ~OTG_XCEIV_INPUTS + & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + break; + default: + break; + } + + omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) + * we don't track them separately + */ + } else if (otg_irq & A_REQ_TMROUT) { + otg_ctrl = omap_readl(OTG_CTRL); + pr_info("otg: BCON_TMOUT from %s, %06x\n", + state_name(isp), otg_ctrl); + notresponding(isp); + + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + + omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* A-supplied voltage fell too low; overcurrent */ + } else if (otg_irq & A_VBUS_ERR) { + otg_ctrl = omap_readl(OTG_CTRL); + printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", + state_name(isp), otg_irq, otg_ctrl); + + otg_ctrl |= OTG_BUSDROP; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_A_VBUS_ERR; + + omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + /* switch driver; the transceiver code activates it, + * ungating the udc clock or resuming OHCI. + */ + } else if (otg_irq & DRIVER_SWITCH) { + int kick = 0; + + otg_ctrl = omap_readl(OTG_CTRL); + printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", + state_name(isp), + (otg_ctrl & OTG_DRIVER_SEL) + ? "gadget" : "host", + otg_ctrl); + isp1301_defer_work(isp, WORK_UPDATE_ISP); + + /* role is peripheral */ + if (otg_ctrl & OTG_DRIVER_SEL) { + switch (isp->phy.state) { + case OTG_STATE_A_IDLE: + b_idle(isp, __func__); + break; + default: + break; + } + isp1301_defer_work(isp, WORK_UPDATE_ISP); + + /* role is host */ + } else { + if (!(otg_ctrl & OTG_ID)) { + otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; + omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); + } + + if (otg->host) { + switch (isp->phy.state) { + case OTG_STATE_B_WAIT_ACON: + isp->phy.state = OTG_STATE_B_HOST; + pr_debug(" --> b_host\n"); + kick = 1; + break; + case OTG_STATE_A_WAIT_BCON: + isp->phy.state = OTG_STATE_A_HOST; + pr_debug(" --> a_host\n"); + break; + case OTG_STATE_A_PERIPHERAL: + isp->phy.state = OTG_STATE_A_WAIT_BCON; + pr_debug(" --> a_wait_bcon\n"); + break; + default: + break; + } + isp1301_defer_work(isp, WORK_HOST_RESUME); + } + } + + omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); + ret = IRQ_HANDLED; + + if (kick) + usb_bus_start_enum(otg->host, otg->host->otg_port); + } + + check_state(isp, __func__); + return ret; +} + +static struct platform_device *otg_dev; + +static int isp1301_otg_init(struct isp1301 *isp) +{ + u32 l; + + if (!otg_dev) + return -ENODEV; + + dump_regs(isp, __func__); + /* some of these values are board-specific... */ + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN + /* for B-device: */ + | SRP_GPDATA /* 9msec Bdev D+ pulse */ + | SRP_GPDVBUS /* discharge after VBUS pulse */ + // | (3 << 24) /* 2msec VBUS pulse */ + /* for A-device: */ + | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */ + | SRP_DPW /* detect 167+ns SRP pulses */ + | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ + ; + omap_writel(l, OTG_SYSCON_2); + + update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); + update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); + + check_state(isp, __func__); + pr_debug("otg: %s, %s %06x\n", + state_name(isp), __func__, omap_readl(OTG_CTRL)); + + omap_writew(DRIVER_SWITCH | OPRT_CHG + | B_SRP_TMROUT | B_HNP_FAIL + | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); + + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN; + omap_writel(l, OTG_SYSCON_2); + + return 0; +} + +static int otg_probe(struct platform_device *dev) +{ + // struct omap_usb_config *config = dev->platform_data; + + otg_dev = dev; + return 0; +} + +static int otg_remove(struct platform_device *dev) +{ + otg_dev = NULL; + return 0; +} + +static struct platform_driver omap_otg_driver = { + .probe = otg_probe, + .remove = otg_remove, + .driver = { + .owner = THIS_MODULE, + .name = "omap_otg", + }, +}; + +static int otg_bind(struct isp1301 *isp) +{ + int status; + + if (otg_dev) + return -EBUSY; + + status = platform_driver_register(&omap_otg_driver); + if (status < 0) + return status; + + if (otg_dev) + status = request_irq(otg_dev->resource[1].start, omap_otg_irq, + 0, DRIVER_NAME, isp); + else + status = -ENODEV; + + if (status < 0) + platform_driver_unregister(&omap_otg_driver); + return status; +} + +static void otg_unbind(struct isp1301 *isp) +{ + if (!otg_dev) + return; + free_irq(otg_dev->resource[1].start, isp); +} + +#else + +/* OTG controller isn't clocked */ + +#endif /* CONFIG_USB_OTG */ + +/*-------------------------------------------------------------------------*/ + +static void b_peripheral(struct isp1301 *isp) +{ + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + + usb_gadget_vbus_connect(isp->phy.otg->gadget); + +#ifdef CONFIG_USB_OTG + enable_vbus_draw(isp, 8); + otg_update_isp(isp); +#else + enable_vbus_draw(isp, 100); + /* UDC driver just set OTG_BSESSVLD */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); + isp->phy.state = OTG_STATE_B_PERIPHERAL; + pr_debug(" --> b_peripheral\n"); + dump_regs(isp, "2periph"); +#endif +} + +static void isp_update_otg(struct isp1301 *isp, u8 stat) +{ + struct usb_otg *otg = isp->phy.otg; + u8 isp_stat, isp_bstat; + enum usb_otg_state state = isp->phy.state; + + if (stat & INTR_BDIS_ACON) + pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); + + /* start certain state transitions right away */ + isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); + if (isp_stat & INTR_ID_GND) { + if (otg->default_a) { + switch (state) { + case OTG_STATE_B_IDLE: + a_idle(isp, "idle"); + /* FALLTHROUGH */ + case OTG_STATE_A_IDLE: + enable_vbus_source(isp); + /* FALLTHROUGH */ + case OTG_STATE_A_WAIT_VRISE: + /* we skip over OTG_STATE_A_WAIT_BCON, since + * the HC will transition to A_HOST (or + * A_SUSPEND!) without our noticing except + * when HNP is used. + */ + if (isp_stat & INTR_VBUS_VLD) + isp->phy.state = OTG_STATE_A_HOST; + break; + case OTG_STATE_A_WAIT_VFALL: + if (!(isp_stat & INTR_SESS_VLD)) + a_idle(isp, "vfell"); + break; + default: + if (!(isp_stat & INTR_VBUS_VLD)) + isp->phy.state = OTG_STATE_A_VBUS_ERR; + break; + } + isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + } else { + switch (state) { + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_HOST: + case OTG_STATE_B_WAIT_ACON: + usb_gadget_vbus_disconnect(otg->gadget); + break; + default: + break; + } + if (state != OTG_STATE_A_IDLE) + a_idle(isp, "id"); + if (otg->host && state == OTG_STATE_A_IDLE) + isp1301_defer_work(isp, WORK_HOST_RESUME); + isp_bstat = 0; + } + } else { + u32 l; + + /* if user unplugged mini-A end of cable, + * don't bypass A_WAIT_VFALL. + */ + if (otg->default_a) { + switch (state) { + default: + isp->phy.state = OTG_STATE_A_WAIT_VFALL; + break; + case OTG_STATE_A_WAIT_VFALL: + state = OTG_STATE_A_IDLE; + /* khubd may take a while to notice and + * handle this disconnect, so don't go + * to B_IDLE quite yet. + */ + break; + case OTG_STATE_A_IDLE: + host_suspend(isp); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_BDIS_ACON_EN); + isp->phy.state = OTG_STATE_B_IDLE; + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~OTG_CTRL_BITS; + omap_writel(l, OTG_CTRL); + break; + case OTG_STATE_B_IDLE: + break; + } + } + isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); + + switch (isp->phy.state) { + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_WAIT_ACON: + case OTG_STATE_B_HOST: + if (likely(isp_bstat & OTG_B_SESS_VLD)) + break; + enable_vbus_draw(isp, 0); +#ifndef CONFIG_USB_OTG + /* UDC driver will clear OTG_BSESSVLD */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DP_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DP_PULLUP); + dump_regs(isp, __func__); +#endif + /* FALLTHROUGH */ + case OTG_STATE_B_SRP_INIT: + b_idle(isp, __func__); + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + /* FALLTHROUGH */ + case OTG_STATE_B_IDLE: + if (otg->gadget && (isp_bstat & OTG_B_SESS_VLD)) { +#ifdef CONFIG_USB_OTG + update_otg1(isp, isp_stat); + update_otg2(isp, isp_bstat); +#endif + b_peripheral(isp); + } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) + isp_bstat |= OTG_B_SESS_END; + break; + case OTG_STATE_A_WAIT_VFALL: + break; + default: + pr_debug("otg: unsupported b-device %s\n", + state_name(isp)); + break; + } + } + + if (state != isp->phy.state) + pr_debug(" isp, %s -> %s\n", + usb_otg_state_string(state), state_name(isp)); + +#ifdef CONFIG_USB_OTG + /* update the OTG controller state to match the isp1301; may + * trigger OPRT_CHG irqs for changes going to the isp1301. + */ + update_otg1(isp, isp_stat); + update_otg2(isp, isp_bstat); + check_state(isp, __func__); +#endif + + dump_regs(isp, "isp1301->otg"); +} + +/*-------------------------------------------------------------------------*/ + +static u8 isp1301_clear_latch(struct isp1301 *isp) +{ + u8 latch = isp1301_get_u8(isp, ISP1301_INTERRUPT_LATCH); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, latch); + return latch; +} + +static void +isp1301_work(struct work_struct *work) +{ + struct isp1301 *isp = container_of(work, struct isp1301, work); + int stop; + + /* implicit lock: we're the only task using this device */ + isp->working = 1; + do { + stop = test_bit(WORK_STOP, &isp->todo); + +#ifdef CONFIG_USB_OTG + /* transfer state from otg engine to isp1301 */ + if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { + otg_update_isp(isp); + put_device(&isp->client->dev); + } +#endif + /* transfer state from isp1301 to otg engine */ + if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { + u8 stat = isp1301_clear_latch(isp); + + isp_update_otg(isp, stat); + put_device(&isp->client->dev); + } + + if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { + u32 otg_ctrl; + + /* + * skip A_WAIT_VRISE; hc transitions invisibly + * skip A_WAIT_BCON; same. + */ + switch (isp->phy.state) { + case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_WAIT_VRISE: + isp->phy.state = OTG_STATE_A_HOST; + pr_debug(" --> a_host\n"); + otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl |= OTG_A_BUSREQ; + otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) + & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + break; + case OTG_STATE_B_WAIT_ACON: + isp->phy.state = OTG_STATE_B_HOST; + pr_debug(" --> b_host (acon)\n"); + break; + case OTG_STATE_B_HOST: + case OTG_STATE_B_IDLE: + case OTG_STATE_A_IDLE: + break; + default: + pr_debug(" host resume in %s\n", + state_name(isp)); + } + host_resume(isp); + // mdelay(10); + put_device(&isp->client->dev); + } + + if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { +#ifdef VERBOSE + dump_regs(isp, "timer"); + if (!stop) + mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); +#endif + put_device(&isp->client->dev); + } + + if (isp->todo) + dev_vdbg(&isp->client->dev, + "work done, todo = 0x%lx\n", + isp->todo); + if (stop) { + dev_dbg(&isp->client->dev, "stop\n"); + break; + } + } while (isp->todo); + isp->working = 0; +} + +static irqreturn_t isp1301_irq(int irq, void *isp) +{ + isp1301_defer_work(isp, WORK_UPDATE_OTG); + return IRQ_HANDLED; +} + +static void isp1301_timer(unsigned long _isp) +{ + isp1301_defer_work((void *)_isp, WORK_TIMER); +} + +/*-------------------------------------------------------------------------*/ + +static void isp1301_release(struct device *dev) +{ + struct isp1301 *isp; + + isp = dev_get_drvdata(dev); + + /* FIXME -- not with a "new style" driver, it doesn't!! */ + + /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ + if (isp->i2c_release) + isp->i2c_release(dev); + kfree(isp->phy.otg); + kfree (isp); +} + +static struct isp1301 *the_transceiver; + +static int __exit isp1301_remove(struct i2c_client *i2c) +{ + struct isp1301 *isp; + + isp = i2c_get_clientdata(i2c); + + isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); + free_irq(i2c->irq, isp); +#ifdef CONFIG_USB_OTG + otg_unbind(isp); +#endif + if (machine_is_omap_h2()) + gpio_free(2); + + isp->timer.data = 0; + set_bit(WORK_STOP, &isp->todo); + del_timer_sync(&isp->timer); + flush_work(&isp->work); + + put_device(&i2c->dev); + the_transceiver = NULL; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* NOTE: three modes are possible here, only one of which + * will be standards-conformant on any given system: + * + * - OTG mode (dual-role), required if there's a Mini-AB connector + * - HOST mode, for when there's one or more A (host) connectors + * - DEVICE mode, for when there's a B/Mini-B (device) connector + * + * As a rule, you won't have an isp1301 chip unless it's there to + * support the OTG mode. Other modes help testing USB controllers + * in isolation from (full) OTG support, or maybe so later board + * revisions can help to support those feature. + */ + +#ifdef CONFIG_USB_OTG + +static int isp1301_otg_enable(struct isp1301 *isp) +{ + power_up(isp); + isp1301_otg_init(isp); + + /* NOTE: since we don't change this, this provides + * a few more interrupts than are strictly needed. + */ + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); + + dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); + + return 0; +} + +#endif + +/* add or disable the host device+driver */ +static int +isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + + if (!otg || isp != the_transceiver) + return -ENODEV; + + if (!host) { + omap_writew(0, OTG_IRQ_EN); + power_down(isp); + otg->host = NULL; + return 0; + } + +#ifdef CONFIG_USB_OTG + otg->host = host; + dev_dbg(&isp->client->dev, "registered host\n"); + host_suspend(isp); + if (otg->gadget) + return isp1301_otg_enable(isp); + return 0; + +#elif !defined(CONFIG_USB_GADGET_OMAP) + // FIXME update its refcount + otg->host = host; + + power_up(isp); + + if (machine_is_omap_h2()) + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); + + dev_info(&isp->client->dev, "A-Host sessions ok\n"); + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_ID_GND); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_ID_GND); + + /* If this has a Mini-AB connector, this mode is highly + * nonstandard ... but can be handy for testing, especially with + * the Mini-A end of an OTG cable. (Or something nonstandard + * like MiniB-to-StandardB, maybe built with a gender mender.) + */ + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); + + dump_regs(isp, __func__); + + return 0; + +#else + dev_dbg(&isp->client->dev, "host sessions not allowed\n"); + return -EINVAL; +#endif + +} + +static int +isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + + if (!otg || isp != the_transceiver) + return -ENODEV; + + if (!gadget) { + omap_writew(0, OTG_IRQ_EN); + if (!otg->default_a) + enable_vbus_draw(isp, 0); + usb_gadget_vbus_disconnect(otg->gadget); + otg->gadget = NULL; + power_down(isp); + return 0; + } + +#ifdef CONFIG_USB_OTG + otg->gadget = gadget; + dev_dbg(&isp->client->dev, "registered gadget\n"); + /* gadget driver may be suspended until vbus_connect () */ + if (otg->host) + return isp1301_otg_enable(isp); + return 0; + +#elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) + otg->gadget = gadget; + // FIXME update its refcount + + { + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); + l |= OTG_ID; + omap_writel(l, OTG_CTRL); + } + + power_up(isp); + isp->phy.state = OTG_STATE_B_IDLE; + + if (machine_is_omap_h2() || machine_is_omap_h3()) + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); + + isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, + INTR_SESS_VLD); + isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, + INTR_VBUS_VLD); + dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); + dump_regs(isp, __func__); + + /* If this has a Mini-AB connector, this mode is highly + * nonstandard ... but can be handy for testing, so long + * as you don't plug a Mini-A cable into the jack. + */ + if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) + b_peripheral(isp); + + return 0; + +#else + dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); + return -EINVAL; +#endif +} + + +/*-------------------------------------------------------------------------*/ + +static int +isp1301_set_power(struct usb_phy *dev, unsigned mA) +{ + if (!the_transceiver) + return -ENODEV; + if (dev->state == OTG_STATE_B_PERIPHERAL) + enable_vbus_draw(the_transceiver, mA); + return 0; +} + +static int +isp1301_start_srp(struct usb_otg *otg) +{ + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + u32 otg_ctrl; + + if (!otg || isp != the_transceiver + || isp->phy.state != OTG_STATE_B_IDLE) + return -ENODEV; + + otg_ctrl = omap_readl(OTG_CTRL); + if (!(otg_ctrl & OTG_BSESSEND)) + return -EINVAL; + + otg_ctrl |= OTG_B_BUSREQ; + otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; + omap_writel(otg_ctrl, OTG_CTRL); + isp->phy.state = OTG_STATE_B_SRP_INIT; + + pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), + omap_readl(OTG_CTRL)); +#ifdef CONFIG_USB_OTG + check_state(isp, __func__); +#endif + return 0; +} + +static int +isp1301_start_hnp(struct usb_otg *otg) +{ +#ifdef CONFIG_USB_OTG + struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + u32 l; + + if (!otg || isp != the_transceiver) + return -ENODEV; + if (otg->default_a && (otg->host == NULL || !otg->host->b_hnp_enable)) + return -ENOTCONN; + if (!otg->default_a && (otg->gadget == NULL + || !otg->gadget->b_hnp_enable)) + return -ENOTCONN; + + /* We want hardware to manage most HNP protocol timings. + * So do this part as early as possible... + */ + switch (isp->phy.state) { + case OTG_STATE_B_HOST: + isp->phy.state = OTG_STATE_B_PERIPHERAL; + /* caller will suspend next */ + break; + case OTG_STATE_A_HOST: +#if 0 + /* autoconnect mode avoids irq latency bugs */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_BDIS_ACON_EN); +#endif + /* caller must suspend then clear A_BUSREQ */ + usb_gadget_vbus_connect(otg->gadget); + l = omap_readl(OTG_CTRL); + l |= OTG_A_SETB_HNPEN; + omap_writel(l, OTG_CTRL); + + break; + case OTG_STATE_A_PERIPHERAL: + /* initiated by B-Host suspend */ + break; + default: + return -EILSEQ; + } + pr_debug("otg: HNP %s, %06x ...\n", + state_name(isp), omap_readl(OTG_CTRL)); + check_state(isp, __func__); + return 0; +#else + /* srp-only */ + return -EINVAL; +#endif +} + +/*-------------------------------------------------------------------------*/ + +static int +isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + int status; + struct isp1301 *isp; + + if (the_transceiver) + return 0; + + isp = kzalloc(sizeof *isp, GFP_KERNEL); + if (!isp) + return 0; + + isp->phy.otg = kzalloc(sizeof *isp->phy.otg, GFP_KERNEL); + if (!isp->phy.otg) { + kfree(isp); + return 0; + } + + INIT_WORK(&isp->work, isp1301_work); + init_timer(&isp->timer); + isp->timer.function = isp1301_timer; + isp->timer.data = (unsigned long) isp; + + i2c_set_clientdata(i2c, isp); + isp->client = i2c; + + /* verify the chip (shouldn't be necessary) */ + status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); + if (status != I2C_VENDOR_ID_PHILIPS) { + dev_dbg(&i2c->dev, "not philips id: %d\n", status); + goto fail; + } + status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); + if (status != I2C_PRODUCT_ID_PHILIPS_1301) { + dev_dbg(&i2c->dev, "not isp1301, %d\n", status); + goto fail; + } + isp->i2c_release = i2c->dev.release; + i2c->dev.release = isp1301_release; + + /* initial development used chiprev 2.00 */ + status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE); + dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n", + status >> 8, status & 0xff); + + /* make like power-on reset */ + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK); + + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI); + + isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, + OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); + isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, + ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); + + isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); + isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); + +#ifdef CONFIG_USB_OTG + status = otg_bind(isp); + if (status < 0) { + dev_dbg(&i2c->dev, "can't bind OTG\n"); + goto fail; + } +#endif + + if (machine_is_omap_h2()) { + /* full speed signaling by default */ + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, + MC1_SPEED); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, + MC2_SPD_SUSP_CTRL); + + /* IRQ wired at M14 */ + omap_cfg_reg(M14_1510_GPIO2); + if (gpio_request(2, "isp1301") == 0) + gpio_direction_input(2); + isp->irq_type = IRQF_TRIGGER_FALLING; + } + + status = request_irq(i2c->irq, isp1301_irq, + isp->irq_type, DRIVER_NAME, isp); + if (status < 0) { + dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", + i2c->irq, status); + goto fail; + } + + isp->phy.dev = &i2c->dev; + isp->phy.label = DRIVER_NAME; + isp->phy.set_power = isp1301_set_power, + + isp->phy.otg->phy = &isp->phy; + isp->phy.otg->set_host = isp1301_set_host, + isp->phy.otg->set_peripheral = isp1301_set_peripheral, + isp->phy.otg->start_srp = isp1301_start_srp, + isp->phy.otg->start_hnp = isp1301_start_hnp, + + enable_vbus_draw(isp, 0); + power_down(isp); + the_transceiver = isp; + +#ifdef CONFIG_USB_OTG + update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); + update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); +#endif + + dump_regs(isp, __func__); + +#ifdef VERBOSE + mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); + dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); +#endif + + status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); + if (status < 0) + dev_err(&i2c->dev, "can't register transceiver, %d\n", + status); + + return 0; + +fail: + kfree(isp->phy.otg); + kfree(isp); + return -ENODEV; +} + +static const struct i2c_device_id isp1301_id[] = { + { "isp1301_omap", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, isp1301_id); + +static struct i2c_driver isp1301_driver = { + .driver = { + .name = "isp1301_omap", + }, + .probe = isp1301_probe, + .remove = __exit_p(isp1301_remove), + .id_table = isp1301_id, +}; + +/*-------------------------------------------------------------------------*/ + +static int __init isp_init(void) +{ + return i2c_add_driver(&isp1301_driver); +} +subsys_initcall(isp_init); + +static void __exit isp_exit(void) +{ + if (the_transceiver) + usb_remove_phy(&the_transceiver->phy); + i2c_del_driver(&isp1301_driver); +} +module_exit(isp_exit); + diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c new file mode 100644 index 000000000000..18dbf7e37607 --- /dev/null +++ b/drivers/usb/phy/phy-isp1301.c @@ -0,0 +1,71 @@ +/* + * NXP ISP1301 USB transceiver driver + * + * Copyright (C) 2012 Roland Stigge + * + * Author: Roland Stigge + * + * 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 + +#define DRV_NAME "isp1301" + +static const struct i2c_device_id isp1301_id[] = { + { "isp1301", 0 }, + { } +}; + +static struct i2c_client *isp1301_i2c_client; + +static int isp1301_probe(struct i2c_client *client, + const struct i2c_device_id *i2c_id) +{ + isp1301_i2c_client = client; + return 0; +} + +static int isp1301_remove(struct i2c_client *client) +{ + return 0; +} + +static struct i2c_driver isp1301_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = isp1301_probe, + .remove = isp1301_remove, + .id_table = isp1301_id, +}; + +module_i2c_driver(isp1301_driver); + +static int match(struct device *dev, void *data) +{ + struct device_node *node = (struct device_node *)data; + return (dev->of_node == node) && + (dev->driver == &isp1301_driver.driver); +} + +struct i2c_client *isp1301_get_client(struct device_node *node) +{ + if (node) { /* reference of ISP1301 I2C node via DT */ + struct device *dev = bus_find_device(&i2c_bus_type, NULL, + node, match); + if (!dev) + return NULL; + return to_i2c_client(dev); + } else { /* non-DT: only one ISP1301 chip supported */ + return isp1301_i2c_client; + } +} +EXPORT_SYMBOL_GPL(isp1301_get_client); + +MODULE_AUTHOR("Roland Stigge "); +MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c new file mode 100644 index 000000000000..749fbf41fb6f --- /dev/null +++ b/drivers/usb/phy/phy-msm-usb.c @@ -0,0 +1,1762 @@ +/* Copyright (c) 2009-2011, 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 +#include +#include +#include + +#include + +#define MSM_USB_BASE (motg->regs) +#define DRIVER_NAME "msm_otg" + +#define ULPI_IO_TIMEOUT_USEC (10 * 1000) + +#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ +#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ +#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */ +#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */ + +#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */ +#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */ +#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ +#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ + +#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ +#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ + +static struct regulator *hsusb_3p3; +static struct regulator *hsusb_1p8; +static struct regulator *hsusb_vddcx; + +static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) +{ + int ret = 0; + + if (init) { + hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); + if (IS_ERR(hsusb_vddcx)) { + dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); + return PTR_ERR(hsusb_vddcx); + } + + ret = regulator_set_voltage(hsusb_vddcx, + USB_PHY_VDD_DIG_VOL_MIN, + USB_PHY_VDD_DIG_VOL_MAX); + if (ret) { + dev_err(motg->phy.dev, "unable to set the voltage " + "for hsusb vddcx\n"); + regulator_put(hsusb_vddcx); + return ret; + } + + ret = regulator_enable(hsusb_vddcx); + if (ret) { + dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); + regulator_put(hsusb_vddcx); + } + } else { + ret = regulator_set_voltage(hsusb_vddcx, 0, + USB_PHY_VDD_DIG_VOL_MAX); + if (ret) + dev_err(motg->phy.dev, "unable to set the voltage " + "for hsusb vddcx\n"); + ret = regulator_disable(hsusb_vddcx); + if (ret) + dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); + + regulator_put(hsusb_vddcx); + } + + return ret; +} + +static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) +{ + int rc = 0; + + if (init) { + hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); + if (IS_ERR(hsusb_3p3)) { + dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); + return PTR_ERR(hsusb_3p3); + } + + rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, + USB_PHY_3P3_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "unable to set voltage level " + "for hsusb 3p3\n"); + goto put_3p3; + } + rc = regulator_enable(hsusb_3p3); + if (rc) { + dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); + goto put_3p3; + } + hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); + if (IS_ERR(hsusb_1p8)) { + dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); + rc = PTR_ERR(hsusb_1p8); + goto disable_3p3; + } + rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, + USB_PHY_1P8_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "unable to set voltage level " + "for hsusb 1p8\n"); + goto put_1p8; + } + rc = regulator_enable(hsusb_1p8); + if (rc) { + dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); + goto put_1p8; + } + + return 0; + } + + regulator_disable(hsusb_1p8); +put_1p8: + regulator_put(hsusb_1p8); +disable_3p3: + regulator_disable(hsusb_3p3); +put_3p3: + regulator_put(hsusb_3p3); + return rc; +} + +#ifdef CONFIG_PM_SLEEP +#define USB_PHY_SUSP_DIG_VOL 500000 +static int msm_hsusb_config_vddcx(int high) +{ + int max_vol = USB_PHY_VDD_DIG_VOL_MAX; + int min_vol; + int ret; + + if (high) + min_vol = USB_PHY_VDD_DIG_VOL_MIN; + else + min_vol = USB_PHY_SUSP_DIG_VOL; + + ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); + if (ret) { + pr_err("%s: unable to set the voltage for regulator " + "HSUSB_VDDCX\n", __func__); + return ret; + } + + pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); + + return ret; +} +#endif + +static int msm_hsusb_ldo_set_mode(int on) +{ + int ret = 0; + + if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { + pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); + return -ENODEV; + } + + if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { + pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); + return -ENODEV; + } + + if (on) { + ret = regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_HPM_LOAD); + if (ret < 0) { + pr_err("%s: Unable to set HPM of the regulator " + "HSUSB_1p8\n", __func__); + return ret; + } + ret = regulator_set_optimum_mode(hsusb_3p3, + USB_PHY_3P3_HPM_LOAD); + if (ret < 0) { + pr_err("%s: Unable to set HPM of the regulator " + "HSUSB_3p3\n", __func__); + regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_LPM_LOAD); + return ret; + } + } else { + ret = regulator_set_optimum_mode(hsusb_1p8, + USB_PHY_1P8_LPM_LOAD); + if (ret < 0) + pr_err("%s: Unable to set LPM of the regulator " + "HSUSB_1p8\n", __func__); + ret = regulator_set_optimum_mode(hsusb_3p3, + USB_PHY_3P3_LPM_LOAD); + if (ret < 0) + pr_err("%s: Unable to set LPM of the regulator " + "HSUSB_3p3\n", __func__); + } + + pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); + return ret < 0 ? ret : 0; +} + +static int ulpi_read(struct usb_phy *phy, u32 reg) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + int cnt = 0; + + /* initiate read operation */ + writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(phy->dev, "ulpi_read: timeout %08x\n", + readl(USB_ULPI_VIEWPORT)); + return -ETIMEDOUT; + } + return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); +} + +static int ulpi_write(struct usb_phy *phy, u32 val, u32 reg) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + int cnt = 0; + + /* initiate write operation */ + writel(ULPI_RUN | ULPI_WRITE | + ULPI_ADDR(reg) | ULPI_DATA(val), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(phy->dev, "ulpi_write: timeout\n"); + return -ETIMEDOUT; + } + return 0; +} + +static struct usb_phy_io_ops msm_otg_io_ops = { + .read = ulpi_read, + .write = ulpi_write, +}; + +static void ulpi_init(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + int *seq = pdata->phy_init_seq; + + if (!seq) + return; + + while (seq[0] >= 0) { + dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", + seq[0], seq[1]); + ulpi_write(&motg->phy, seq[0], seq[1]); + seq += 2; + } +} + +static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) +{ + int ret; + + if (assert) { + ret = clk_reset(motg->clk, CLK_RESET_ASSERT); + if (ret) + dev_err(motg->phy.dev, "usb hs_clk assert failed\n"); + } else { + ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->phy.dev, "usb hs_clk deassert failed\n"); + } + return ret; +} + +static int msm_otg_phy_clk_reset(struct msm_otg *motg) +{ + int ret; + + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); + if (ret) { + dev_err(motg->phy.dev, "usb phy clk assert failed\n"); + return ret; + } + usleep_range(10000, 12000); + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->phy.dev, "usb phy clk deassert failed\n"); + return ret; +} + +static int msm_otg_phy_reset(struct msm_otg *motg) +{ + u32 val; + int ret; + int retries; + + ret = msm_otg_link_clk_reset(motg, 1); + if (ret) + return ret; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + ret = msm_otg_link_clk_reset(motg, 0); + if (ret) + return ret; + + val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; + writel(val | PORTSC_PTS_ULPI, USB_PORTSC); + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, + ULPI_CLR(ULPI_FUNC_CTRL)); + if (!ret) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + /* This reset calibrates the phy, if the above write succeeded */ + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_read(&motg->phy, ULPI_DEBUG); + if (ret != -ETIMEDOUT) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + dev_info(motg->phy.dev, "phy_reset: success\n"); + return 0; +} + +#define LINK_RESET_TIMEOUT_USEC (250 * 1000) +static int msm_otg_reset(struct usb_phy *phy) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + int ret; + u32 val = 0; + u32 ulpi_val = 0; + + ret = msm_otg_phy_reset(motg); + if (ret) { + dev_err(phy->dev, "phy_reset failed\n"); + return ret; + } + + ulpi_init(motg); + + writel(USBCMD_RESET, USB_USBCMD); + while (cnt < LINK_RESET_TIMEOUT_USEC) { + if (!(readl(USB_USBCMD) & USBCMD_RESET)) + break; + udelay(1); + cnt++; + } + if (cnt >= LINK_RESET_TIMEOUT_USEC) + return -ETIMEDOUT; + + /* select ULPI phy */ + writel(0x80000000, USB_PORTSC); + + msleep(100); + + writel(0x0, USB_AHBBURST); + writel(0x00, USB_AHBMODE); + + if (pdata->otg_control == OTG_PHY_CONTROL) { + val = readl(USB_OTGSC); + if (pdata->mode == USB_OTG) { + ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; + val |= OTGSC_IDIE | OTGSC_BSVIE; + } else if (pdata->mode == USB_PERIPHERAL) { + ulpi_val = ULPI_INT_SESS_VALID; + val |= OTGSC_BSVIE; + } + writel(val, USB_OTGSC); + ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_RISE); + ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); + } + + return 0; +} + +#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) +#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_suspend(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + struct usb_bus *bus = phy->otg->host; + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + + if (atomic_read(&motg->in_lpm)) + return 0; + + disable_irq(motg->irq); + /* + * Chipidea 45-nm PHY suspend sequence: + * + * Interrupt Latch Register auto-clear feature is not present + * in all PHY versions. Latch register is clear on read type. + * Clear latch register to avoid spurious wakeup from + * low power mode (LPM). + * + * PHY comparators are disabled when PHY enters into low power + * mode (LPM). Keep PHY comparators ON in LPM only when we expect + * VBUS/Id notifications from USB PHY. Otherwise turn off USB + * PHY comparators. This save significant amount of power. + * + * PLL is not turned off when PHY enters into low power mode (LPM). + * Disable PLL for maximum power savings. + */ + + if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) { + ulpi_read(phy, 0x14); + if (pdata->otg_control == OTG_PHY_CONTROL) + ulpi_write(phy, 0x01, 0x30); + ulpi_write(phy, 0x08, 0x09); + } + + /* + * PHY may take some time or even fail to enter into low power + * mode (LPM). Hence poll for 500 msec and reset the PHY and link + * in failure case. + */ + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { + dev_err(phy->dev, "Unable to suspend PHY\n"); + msm_otg_reset(phy); + enable_irq(motg->irq); + return -ETIMEDOUT; + } + + /* + * PHY has capability to generate interrupt asynchronously in low + * power mode (LPM). This interrupt is level triggered. So USB IRQ + * line must be disabled till async interrupt enable bit is cleared + * in USBCMD register. Assert STP (ULPI interface STOP signal) to + * block data communication from PHY. + */ + writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) + writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + + if (!IS_ERR(motg->pclk_src)) + clk_disable(motg->pclk_src); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(0); + msm_hsusb_config_vddcx(0); + } + + if (device_may_wakeup(phy->dev)) + enable_irq_wake(motg->irq); + if (bus) + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + atomic_set(&motg->in_lpm, 1); + enable_irq(motg->irq); + + dev_info(phy->dev, "USB in low power mode\n"); + + return 0; +} + +static int msm_otg_resume(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + struct usb_bus *bus = phy->otg->host; + int cnt = 0; + unsigned temp; + + if (!atomic_read(&motg->in_lpm)) + return 0; + + if (!IS_ERR(motg->pclk_src)) + clk_enable(motg->pclk_src); + + clk_enable(motg->pclk); + clk_enable(motg->clk); + if (motg->core_clk) + clk_enable(motg->core_clk); + + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(1); + msm_hsusb_config_vddcx(1); + writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); + } + + temp = readl(USB_USBCMD); + temp &= ~ASYNC_INTR_CTRL; + temp &= ~ULPI_STP_CTRL; + writel(temp, USB_USBCMD); + + /* + * PHY comes out of low power mode (LPM) in case of wakeup + * from asynchronous interrupt. + */ + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + goto skip_phy_resume; + + writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_RESUME_TIMEOUT_USEC) { + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_RESUME_TIMEOUT_USEC) { + /* + * This is a fatal error. Reset the link and + * PHY. USB state can not be restored. Re-insertion + * of USB cable is the only way to get USB working. + */ + dev_err(phy->dev, "Unable to resume USB." + "Re-plugin the cable\n"); + msm_otg_reset(phy); + } + +skip_phy_resume: + if (device_may_wakeup(phy->dev)) + disable_irq_wake(motg->irq); + if (bus) + set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + atomic_set(&motg->in_lpm, 0); + + if (motg->async_int) { + motg->async_int = 0; + pm_runtime_put(phy->dev); + enable_irq(motg->irq); + } + + dev_info(phy->dev, "USB exited from low power mode\n"); + + return 0; +} +#endif + +static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA) +{ + if (motg->cur_power == mA) + return; + + /* TODO: Notify PMIC about available current */ + dev_info(motg->phy.dev, "Avail curr from USB = %u\n", mA); + motg->cur_power = mA; +} + +static int msm_otg_set_power(struct usb_phy *phy, unsigned mA) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + + /* + * Gadget driver uses set_power method to notify about the + * available current based on suspend/configured states. + * + * IDEV_CHG can be drawn irrespective of suspend/un-configured + * states when CDP/ACA is connected. + */ + if (motg->chg_type == USB_SDP_CHARGER) + msm_otg_notify_charger(motg, mA); + + return 0; +} + +static void msm_otg_start_host(struct usb_phy *phy, int on) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + struct usb_hcd *hcd; + + if (!phy->otg->host) + return; + + hcd = bus_to_hcd(phy->otg->host); + + if (on) { + dev_dbg(phy->dev, "host on\n"); + + if (pdata->vbus_power) + pdata->vbus_power(1); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Enable internal + * HUB before kicking the host. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_A_HOST); +#ifdef CONFIG_USB + usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); +#endif + } else { + dev_dbg(phy->dev, "host off\n"); + +#ifdef CONFIG_USB + usb_remove_hcd(hcd); +#endif + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + if (pdata->vbus_power) + pdata->vbus_power(0); + } +} + +static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + struct usb_hcd *hcd; + + /* + * Fail host registration if this board can support + * only peripheral configuration. + */ + if (motg->pdata->mode == USB_PERIPHERAL) { + dev_info(otg->phy->dev, "Host mode is not supported\n"); + return -ENODEV; + } + + if (!host) { + if (otg->phy->state == OTG_STATE_A_HOST) { + pm_runtime_get_sync(otg->phy->dev); + msm_otg_start_host(otg->phy, 0); + otg->host = NULL; + otg->phy->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->host = NULL; + } + + return 0; + } + + hcd = bus_to_hcd(host); + hcd->power_budget = motg->pdata->power_budget; + + otg->host = host; + dev_dbg(otg->phy->dev, "host driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if peripheral is not supported + * or peripheral is already registered with us. + */ + if (motg->pdata->mode == USB_HOST || otg->gadget) { + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +static void msm_otg_start_peripheral(struct usb_phy *phy, int on) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + + if (!phy->otg->gadget) + return; + + if (on) { + dev_dbg(phy->dev, "gadget on\n"); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Disable internal + * HUB before kicking the gadget. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); + usb_gadget_vbus_connect(phy->otg->gadget); + } else { + dev_dbg(phy->dev, "gadget off\n"); + usb_gadget_vbus_disconnect(phy->otg->gadget); + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + } + +} + +static int msm_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + + /* + * Fail peripheral registration if this board can support + * only host configuration. + */ + if (motg->pdata->mode == USB_HOST) { + dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); + return -ENODEV; + } + + if (!gadget) { + if (otg->phy->state == OTG_STATE_B_PERIPHERAL) { + pm_runtime_get_sync(otg->phy->dev); + msm_otg_start_peripheral(otg->phy, 0); + otg->gadget = NULL; + otg->phy->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->gadget = NULL; + } + + return 0; + } + otg->gadget = gadget; + dev_dbg(otg->phy->dev, "peripheral driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if host is not supported + * or host is already registered with us. + */ + if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +static bool msm_chg_check_secondary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_secondary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(phy, chg_det, 0x34); + /* put it in host mode for enabling D- source */ + chg_det &= ~(1 << 2); + ulpi_write(phy, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DM as current source, DP as current sink + * and enable battery charging comparators. + */ + ulpi_write(phy, 0x8, 0x85); + ulpi_write(phy, 0x2, 0x85); + ulpi_write(phy, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_primary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_primary_det(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DP as current source, DM as current sink + * and enable battery charging comparators. + */ + ulpi_write(phy, 0x2, 0x85); + ulpi_write(phy, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 line_state; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + line_state = ulpi_read(phy, 0x15); + ret = !(line_state & 1); + break; + case SNPS_28NM_INTEGRATED_PHY: + line_state = ulpi_read(phy, 0x87); + ret = line_state & 2; + break; + default: + break; + } + return ret; +} + +static void msm_chg_disable_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + chg_det &= ~(1 << 5); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + ulpi_write(phy, 0x10, 0x86); + break; + default: + break; + } +} + +static void msm_chg_enable_dcd(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn on D+ current source */ + chg_det |= (1 << 5); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Data contact detection enable */ + ulpi_write(phy, 0x10, 0x85); + break; + default: + break; + } +} + +static void msm_chg_block_on(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 func_ctrl, chg_det; + + /* put the controller in non-driving mode */ + func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(phy, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + udelay(20); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(phy, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(phy, 0x1F, 0x92); + ulpi_write(phy, 0x1F, 0x95); + udelay(100); + break; + default: + break; + } +} + +static void msm_chg_block_off(struct msm_otg *motg) +{ + struct usb_phy *phy = &motg->phy; + u32 func_ctrl, chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(phy, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(phy, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(phy, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(phy, 0x1F, 0x92); + ulpi_write(phy, 0x1F, 0x95); + break; + default: + break; + } + + /* put the controller in normal mode */ + func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; + ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL); +} + +#define MSM_CHG_DCD_POLL_TIME (100 * HZ/1000) /* 100 msec */ +#define MSM_CHG_DCD_MAX_RETRIES 6 /* Tdcd_tmout = 6 * 100 msec */ +#define MSM_CHG_PRIMARY_DET_TIME (40 * HZ/1000) /* TVDPSRC_ON */ +#define MSM_CHG_SECONDARY_DET_TIME (40 * HZ/1000) /* TVDMSRC_ON */ +static void msm_chg_detect_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work); + struct usb_phy *phy = &motg->phy; + bool is_dcd, tmout, vout; + unsigned long delay; + + dev_dbg(phy->dev, "chg detection work\n"); + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + pm_runtime_get_sync(phy->dev); + msm_chg_block_on(motg); + msm_chg_enable_dcd(motg); + motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; + motg->dcd_retries = 0; + delay = MSM_CHG_DCD_POLL_TIME; + break; + case USB_CHG_STATE_WAIT_FOR_DCD: + is_dcd = msm_chg_check_dcd(motg); + tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES; + if (is_dcd || tmout) { + msm_chg_disable_dcd(motg); + msm_chg_enable_primary_det(motg); + delay = MSM_CHG_PRIMARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_DCD_DONE; + } else { + delay = MSM_CHG_DCD_POLL_TIME; + } + break; + case USB_CHG_STATE_DCD_DONE: + vout = msm_chg_check_primary_det(motg); + if (vout) { + msm_chg_enable_secondary_det(motg); + delay = MSM_CHG_SECONDARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_PRIMARY_DONE; + } else { + motg->chg_type = USB_SDP_CHARGER; + motg->chg_state = USB_CHG_STATE_DETECTED; + delay = 0; + } + break; + case USB_CHG_STATE_PRIMARY_DONE: + vout = msm_chg_check_secondary_det(motg); + if (vout) + motg->chg_type = USB_DCP_CHARGER; + else + motg->chg_type = USB_CDP_CHARGER; + motg->chg_state = USB_CHG_STATE_SECONDARY_DONE; + /* fall through */ + case USB_CHG_STATE_SECONDARY_DONE: + motg->chg_state = USB_CHG_STATE_DETECTED; + case USB_CHG_STATE_DETECTED: + msm_chg_block_off(motg); + dev_dbg(phy->dev, "charger = %d\n", motg->chg_type); + schedule_work(&motg->sm_work); + return; + default: + return; + } + + schedule_delayed_work(&motg->chg_work, delay); +} + +/* + * We support OTG, Peripheral only and Host only configurations. In case + * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen + * via Id pin status or user request (debugfs). Id/BSV interrupts are not + * enabled when switch is controlled by user and default mode is supplied + * by board file, which can be changed by userspace later. + */ +static void msm_otg_init_sm(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + u32 otgsc = readl(USB_OTGSC); + + switch (pdata->mode) { + case USB_OTG: + if (pdata->otg_control == OTG_PHY_CONTROL) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + } else if (pdata->otg_control == OTG_USER_CONTROL) { + if (pdata->default_mode == USB_HOST) { + clear_bit(ID, &motg->inputs); + } else if (pdata->default_mode == USB_PERIPHERAL) { + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + } else { + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + } + } + break; + case USB_HOST: + clear_bit(ID, &motg->inputs); + break; + case USB_PERIPHERAL: + set_bit(ID, &motg->inputs); + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + break; + } +} + +static void msm_otg_sm_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); + struct usb_otg *otg = motg->phy.otg; + + switch (otg->phy->state) { + case OTG_STATE_UNDEFINED: + dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); + msm_otg_reset(otg->phy); + msm_otg_init_sm(motg); + otg->phy->state = OTG_STATE_B_IDLE; + /* FALL THROUGH */ + case OTG_STATE_B_IDLE: + dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); + if (!test_bit(ID, &motg->inputs) && otg->host) { + /* disable BSV bit */ + writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); + msm_otg_start_host(otg->phy, 1); + otg->phy->state = OTG_STATE_A_HOST; + } else if (test_bit(B_SESS_VLD, &motg->inputs)) { + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + msm_chg_detect_work(&motg->chg_work.work); + break; + case USB_CHG_STATE_DETECTED: + switch (motg->chg_type) { + case USB_DCP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + break; + case USB_CDP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + msm_otg_start_peripheral(otg->phy, 1); + otg->phy->state + = OTG_STATE_B_PERIPHERAL; + break; + case USB_SDP_CHARGER: + msm_otg_notify_charger(motg, IUNIT); + msm_otg_start_peripheral(otg->phy, 1); + otg->phy->state + = OTG_STATE_B_PERIPHERAL; + break; + default: + break; + } + break; + default: + break; + } + } else { + /* + * If charger detection work is pending, decrement + * the pm usage counter to balance with the one that + * is incremented in charger detection work. + */ + if (cancel_delayed_work_sync(&motg->chg_work)) { + pm_runtime_put_sync(otg->phy->dev); + msm_otg_reset(otg->phy); + } + msm_otg_notify_charger(motg, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; + } + pm_runtime_put_sync(otg->phy->dev); + break; + case OTG_STATE_B_PERIPHERAL: + dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); + if (!test_bit(B_SESS_VLD, &motg->inputs) || + !test_bit(ID, &motg->inputs)) { + msm_otg_notify_charger(motg, 0); + msm_otg_start_peripheral(otg->phy, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; + otg->phy->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg->phy); + schedule_work(w); + } + break; + case OTG_STATE_A_HOST: + dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); + if (test_bit(ID, &motg->inputs)) { + msm_otg_start_host(otg->phy, 0); + otg->phy->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg->phy); + schedule_work(w); + } + break; + default: + break; + } +} + +static irqreturn_t msm_otg_irq(int irq, void *data) +{ + struct msm_otg *motg = data; + struct usb_phy *phy = &motg->phy; + u32 otgsc = 0; + + if (atomic_read(&motg->in_lpm)) { + disable_irq_nosync(irq); + motg->async_int = 1; + pm_runtime_get(phy->dev); + return IRQ_HANDLED; + } + + otgsc = readl(USB_OTGSC); + if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) + return IRQ_NONE; + + if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + dev_dbg(phy->dev, "ID set/clear\n"); + pm_runtime_get_noresume(phy->dev); + } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + dev_dbg(phy->dev, "BSV set/clear\n"); + pm_runtime_get_noresume(phy->dev); + } + + writel(otgsc, USB_OTGSC); + schedule_work(&motg->sm_work); + return IRQ_HANDLED; +} + +static int msm_otg_mode_show(struct seq_file *s, void *unused) +{ + struct msm_otg *motg = s->private; + struct usb_otg *otg = motg->phy.otg; + + switch (otg->phy->state) { + case OTG_STATE_A_HOST: + seq_printf(s, "host\n"); + break; + case OTG_STATE_B_PERIPHERAL: + seq_printf(s, "peripheral\n"); + break; + default: + seq_printf(s, "none\n"); + break; + } + + return 0; +} + +static int msm_otg_mode_open(struct inode *inode, struct file *file) +{ + return single_open(file, msm_otg_mode_show, inode->i_private); +} + +static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct msm_otg *motg = s->private; + char buf[16]; + struct usb_otg *otg = motg->phy.otg; + int status = count; + enum usb_mode_type req_mode; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { + status = -EFAULT; + goto out; + } + + if (!strncmp(buf, "host", 4)) { + req_mode = USB_HOST; + } else if (!strncmp(buf, "peripheral", 10)) { + req_mode = USB_PERIPHERAL; + } else if (!strncmp(buf, "none", 4)) { + req_mode = USB_NONE; + } else { + status = -EINVAL; + goto out; + } + + switch (req_mode) { + case USB_NONE: + switch (otg->phy->state) { + case OTG_STATE_A_HOST: + case OTG_STATE_B_PERIPHERAL: + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_PERIPHERAL: + switch (otg->phy->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_A_HOST: + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_HOST: + switch (otg->phy->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_B_PERIPHERAL: + clear_bit(ID, &motg->inputs); + break; + default: + goto out; + } + break; + default: + goto out; + } + + pm_runtime_get_sync(otg->phy->dev); + schedule_work(&motg->sm_work); +out: + return status; +} + +const struct file_operations msm_otg_mode_fops = { + .open = msm_otg_mode_open, + .read = seq_read, + .write = msm_otg_mode_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *msm_otg_dbg_root; +static struct dentry *msm_otg_dbg_mode; + +static int msm_otg_debugfs_init(struct msm_otg *motg) +{ + msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); + + if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) + return -ENODEV; + + msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, + msm_otg_dbg_root, motg, &msm_otg_mode_fops); + if (!msm_otg_dbg_mode) { + debugfs_remove(msm_otg_dbg_root); + msm_otg_dbg_root = NULL; + return -ENODEV; + } + + return 0; +} + +static void msm_otg_debugfs_cleanup(void) +{ + debugfs_remove(msm_otg_dbg_mode); + debugfs_remove(msm_otg_dbg_root); +} + +static int __init msm_otg_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + struct msm_otg *motg; + struct usb_phy *phy; + + dev_info(&pdev->dev, "msm_otg probe\n"); + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "No platform data given. Bailing out\n"); + return -ENODEV; + } + + motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); + if (!motg) { + dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + return -ENOMEM; + } + + motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!motg->phy.otg) { + dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + return -ENOMEM; + } + + motg->pdata = pdev->dev.platform_data; + phy = &motg->phy; + phy->dev = &pdev->dev; + + motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); + if (IS_ERR(motg->phy_reset_clk)) { + dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); + ret = PTR_ERR(motg->phy_reset_clk); + goto free_motg; + } + + motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); + if (IS_ERR(motg->clk)) { + dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); + ret = PTR_ERR(motg->clk); + goto put_phy_reset_clk; + } + clk_set_rate(motg->clk, 60000000); + + /* + * If USB Core is running its protocol engine based on CORE CLK, + * CORE CLK must be running at >55Mhz for correct HSUSB + * operation and USB core cannot tolerate frequency changes on + * CORE CLK. For such USB cores, vote for maximum clk frequency + * on pclk source + */ + if (motg->pdata->pclk_src_name) { + motg->pclk_src = clk_get(&pdev->dev, + motg->pdata->pclk_src_name); + if (IS_ERR(motg->pclk_src)) + goto put_clk; + clk_set_rate(motg->pclk_src, INT_MAX); + clk_enable(motg->pclk_src); + } else + motg->pclk_src = ERR_PTR(-ENOENT); + + + motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); + if (IS_ERR(motg->pclk)) { + dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); + ret = PTR_ERR(motg->pclk); + goto put_pclk_src; + } + + /* + * USB core clock is not present on all MSM chips. This + * clock is introduced to remove the dependency on AXI + * bus frequency. + */ + motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); + if (IS_ERR(motg->core_clk)) + motg->core_clk = NULL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get platform resource mem\n"); + ret = -ENODEV; + goto put_core_clk; + } + + motg->regs = ioremap(res->start, resource_size(res)); + if (!motg->regs) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -ENOMEM; + goto put_core_clk; + } + dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); + + motg->irq = platform_get_irq(pdev, 0); + if (!motg->irq) { + dev_err(&pdev->dev, "platform_get_irq failed\n"); + ret = -ENODEV; + goto free_regs; + } + + clk_enable(motg->clk); + clk_enable(motg->pclk); + + ret = msm_hsusb_init_vddcx(motg, 1); + if (ret) { + dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); + goto free_regs; + } + + ret = msm_hsusb_ldo_init(motg, 1); + if (ret) { + dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); + goto vddcx_exit; + } + ret = msm_hsusb_ldo_set_mode(1); + if (ret) { + dev_err(&pdev->dev, "hsusb vreg enable failed\n"); + goto ldo_exit; + } + + if (motg->core_clk) + clk_enable(motg->core_clk); + + writel(0, USB_USBINTR); + writel(0, USB_OTGSC); + + INIT_WORK(&motg->sm_work, msm_otg_sm_work); + INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); + ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, + "msm_otg", motg); + if (ret) { + dev_err(&pdev->dev, "request irq failed\n"); + goto disable_clks; + } + + phy->init = msm_otg_reset; + phy->set_power = msm_otg_set_power; + + phy->io_ops = &msm_otg_io_ops; + + phy->otg->phy = &motg->phy; + phy->otg->set_host = msm_otg_set_host; + phy->otg->set_peripheral = msm_otg_set_peripheral; + + ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); + if (ret) { + dev_err(&pdev->dev, "usb_add_phy failed\n"); + goto free_irq; + } + + platform_set_drvdata(pdev, motg); + device_init_wakeup(&pdev->dev, 1); + + if (motg->pdata->mode == USB_OTG && + motg->pdata->otg_control == OTG_USER_CONTROL) { + ret = msm_otg_debugfs_init(motg); + if (ret) + dev_dbg(&pdev->dev, "mode debugfs file is" + "not available\n"); + } + + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + return 0; +free_irq: + free_irq(motg->irq, motg); +disable_clks: + clk_disable(motg->pclk); + clk_disable(motg->clk); +ldo_exit: + msm_hsusb_ldo_init(motg, 0); +vddcx_exit: + msm_hsusb_init_vddcx(motg, 0); +free_regs: + iounmap(motg->regs); +put_core_clk: + if (motg->core_clk) + clk_put(motg->core_clk); + clk_put(motg->pclk); +put_pclk_src: + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } +put_clk: + clk_put(motg->clk); +put_phy_reset_clk: + clk_put(motg->phy_reset_clk); +free_motg: + kfree(motg->phy.otg); + kfree(motg); + return ret; +} + +static int msm_otg_remove(struct platform_device *pdev) +{ + struct msm_otg *motg = platform_get_drvdata(pdev); + struct usb_phy *phy = &motg->phy; + int cnt = 0; + + if (phy->otg->host || phy->otg->gadget) + return -EBUSY; + + msm_otg_debugfs_cleanup(); + cancel_delayed_work_sync(&motg->chg_work); + cancel_work_sync(&motg->sm_work); + + pm_runtime_resume(&pdev->dev); + + device_init_wakeup(&pdev->dev, 0); + pm_runtime_disable(&pdev->dev); + + usb_remove_phy(phy); + free_irq(motg->irq, motg); + + /* + * Put PHY in low power mode. + */ + ulpi_read(phy, 0x14); + ulpi_write(phy, 0x08, 0x09); + + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) + dev_err(phy->dev, "Unable to suspend PHY\n"); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } + msm_hsusb_ldo_init(motg, 0); + + iounmap(motg->regs); + pm_runtime_set_suspended(&pdev->dev); + + clk_put(motg->phy_reset_clk); + clk_put(motg->pclk); + clk_put(motg->clk); + if (motg->core_clk) + clk_put(motg->core_clk); + + kfree(motg->phy.otg); + kfree(motg); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int msm_otg_runtime_idle(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + struct usb_otg *otg = motg->phy.otg; + + dev_dbg(dev, "OTG runtime idle\n"); + + /* + * It is observed some times that a spurious interrupt + * comes when PHY is put into LPM immediately after PHY reset. + * This 1 sec delay also prevents entering into LPM immediately + * after asynchronous interrupt. + */ + if (otg->phy->state != OTG_STATE_UNDEFINED) + pm_schedule_suspend(dev, 1000); + + return -EAGAIN; +} + +static int msm_otg_runtime_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_runtime_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime resume\n"); + return msm_otg_resume(motg); +} +#endif + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_pm_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG PM suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_pm_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + int ret; + + dev_dbg(dev, "OTG PM resume\n"); + + ret = msm_otg_resume(motg); + if (ret) + return ret; + + /* + * Runtime PM Documentation recommends bringing the + * device to full powered state upon resume. + */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops msm_otg_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) + SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, + msm_otg_runtime_idle) +}; +#endif + +static struct platform_driver msm_otg_driver = { + .remove = msm_otg_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &msm_otg_dev_pm_ops, +#endif + }, +}; + +module_platform_driver_probe(msm_otg_driver, msm_otg_probe); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/drivers/usb/phy/phy-mv-u3d-usb.c b/drivers/usb/phy/phy-mv-u3d-usb.c new file mode 100644 index 000000000000..cb7e70f17709 --- /dev/null +++ b/drivers/usb/phy/phy-mv-u3d-usb.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-mv-u3d-usb.h" + +/* + * struct mv_u3d_phy - transceiver driver state + * @phy: transceiver structure + * @dev: The parent device supplied to the probe function + * @clk: usb phy clock + * @base: usb phy register memory base + */ +struct mv_u3d_phy { + struct usb_phy phy; + struct mv_usb_platform_data *plat; + struct device *dev; + struct clk *clk; + void __iomem *base; +}; + +static u32 mv_u3d_phy_read(void __iomem *base, u32 reg) +{ + void __iomem *addr, *data; + + addr = base; + data = base + 0x4; + + writel_relaxed(reg, addr); + return readl_relaxed(data); +} + +static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value) +{ + void __iomem *addr, *data; + u32 tmp; + + addr = base; + data = base + 0x4; + + writel_relaxed(reg, addr); + tmp = readl_relaxed(data); + tmp |= value; + writel_relaxed(tmp, data); +} + +static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value) +{ + void __iomem *addr, *data; + u32 tmp; + + addr = base; + data = base + 0x4; + + writel_relaxed(reg, addr); + tmp = readl_relaxed(data); + tmp &= ~value; + writel_relaxed(tmp, data); +} + +static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value) +{ + void __iomem *addr, *data; + + addr = base; + data = base + 0x4; + + writel_relaxed(reg, addr); + writel_relaxed(value, data); +} + +void mv_u3d_phy_shutdown(struct usb_phy *phy) +{ + struct mv_u3d_phy *mv_u3d_phy; + void __iomem *base; + u32 val; + + mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); + base = mv_u3d_phy->base; + + /* Power down Reference Analog current, bit 15 + * Power down PLL, bit 14 + * Power down Receiver, bit 13 + * Power down Transmitter, bit 12 + * of USB3_POWER_PLL_CONTROL register + */ + val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); + val &= ~(USB3_POWER_PLL_CONTROL_PU); + mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); + + if (mv_u3d_phy->clk) + clk_disable(mv_u3d_phy->clk); +} + +static int mv_u3d_phy_init(struct usb_phy *phy) +{ + struct mv_u3d_phy *mv_u3d_phy; + void __iomem *base; + u32 val, count; + + /* enable usb3 phy */ + mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); + + if (mv_u3d_phy->clk) + clk_enable(mv_u3d_phy->clk); + + base = mv_u3d_phy->base; + + val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); + val &= ~(USB3_POWER_PLL_CONTROL_PU_MASK); + val |= 0xF << USB3_POWER_PLL_CONTROL_PU_SHIFT; + mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); + udelay(100); + + mv_u3d_phy_write(base, USB3_RESET_CONTROL, + USB3_RESET_CONTROL_RESET_PIPE); + udelay(100); + + mv_u3d_phy_write(base, USB3_RESET_CONTROL, + USB3_RESET_CONTROL_RESET_PIPE + | USB3_RESET_CONTROL_RESET_PHY); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); + val &= ~(USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK + | USB3_POWER_PLL_CONTROL_PHY_MODE_MASK); + val |= (USB3_PLL_25MHZ << USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT) + | (0x5 << USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT); + mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); + udelay(100); + + mv_u3d_phy_clear(base, USB3_KVCO_CALI_CONTROL, + USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_SQUELCH_FFE); + val &= ~(USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK + | USB3_SQUELCH_FFE_FFE_RES_SEL_MASK + | USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK); + val |= ((0xD << USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT) + | (0x7 << USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT) + | (0x8 << USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT)); + mv_u3d_phy_write(base, USB3_SQUELCH_FFE, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_GEN1_SET0); + val &= ~USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK; + val |= 1 << USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT; + mv_u3d_phy_write(base, USB3_GEN1_SET0, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_GEN2_SET0); + val &= ~(USB3_GEN2_SET0_G2_TX_AMP_MASK + | USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK + | USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK); + val |= ((0x14 << USB3_GEN2_SET0_G2_TX_AMP_SHIFT) + | (1 << USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT) + | (0xA << USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT) + | (1 << USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT)); + mv_u3d_phy_write(base, USB3_GEN2_SET0, val); + udelay(100); + + mv_u3d_phy_read(base, USB3_TX_EMPPH); + val &= ~(USB3_TX_EMPPH_AMP_MASK + | USB3_TX_EMPPH_EN_MASK + | USB3_TX_EMPPH_AMP_FORCE_MASK + | USB3_TX_EMPPH_PAR1_MASK + | USB3_TX_EMPPH_PAR2_MASK); + val |= ((0xB << USB3_TX_EMPPH_AMP_SHIFT) + | (1 << USB3_TX_EMPPH_EN_SHIFT) + | (1 << USB3_TX_EMPPH_AMP_FORCE_SHIFT) + | (0x1C << USB3_TX_EMPPH_PAR1_SHIFT) + | (1 << USB3_TX_EMPPH_PAR2_SHIFT)); + + mv_u3d_phy_write(base, USB3_TX_EMPPH, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_GEN2_SET1); + val &= ~(USB3_GEN2_SET1_G2_RX_SELMUPI_MASK + | USB3_GEN2_SET1_G2_RX_SELMUPF_MASK + | USB3_GEN2_SET1_G2_RX_SELMUFI_MASK + | USB3_GEN2_SET1_G2_RX_SELMUFF_MASK); + val |= ((1 << USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT) + | (1 << USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT) + | (1 << USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT) + | (1 << USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT)); + mv_u3d_phy_write(base, USB3_GEN2_SET1, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_DIGITAL_LOOPBACK_EN); + val &= ~USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK; + val |= 1 << USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT; + mv_u3d_phy_write(base, USB3_DIGITAL_LOOPBACK_EN, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_IMPEDANCE_TX_SSC); + val &= ~USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK; + val |= 0xC << USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT; + mv_u3d_phy_write(base, USB3_IMPEDANCE_TX_SSC, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_IMPEDANCE_CALI_CTRL); + val &= ~USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK; + val |= 0x4 << USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT; + mv_u3d_phy_write(base, USB3_IMPEDANCE_CALI_CTRL, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_PHY_ISOLATION_MODE); + val &= ~(USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK + | USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK + | USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK); + val |= ((1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT) + | (1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT)); + mv_u3d_phy_write(base, USB3_PHY_ISOLATION_MODE, val); + udelay(100); + + val = mv_u3d_phy_read(base, USB3_TXDETRX); + val &= ~(USB3_TXDETRX_VTHSEL_MASK); + val |= 0x1 << USB3_TXDETRX_VTHSEL_SHIFT; + mv_u3d_phy_write(base, USB3_TXDETRX, val); + udelay(100); + + dev_dbg(mv_u3d_phy->dev, "start calibration\n"); + +calstart: + /* Perform Manual Calibration */ + mv_u3d_phy_set(base, USB3_KVCO_CALI_CONTROL, + 1 << USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT); + + mdelay(1); + + count = 0; + while (1) { + val = mv_u3d_phy_read(base, USB3_KVCO_CALI_CONTROL); + if (val & (1 << USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT)) + break; + else if (count > 50) { + dev_dbg(mv_u3d_phy->dev, "calibration failure, retry...\n"); + goto calstart; + } + count++; + mdelay(1); + } + + /* active PIPE interface */ + mv_u3d_phy_write(base, USB3_PIPE_SM_CTRL, + 1 << USB3_PIPE_SM_CTRL_PHY_INIT_DONE); + + return 0; +} + +static int mv_u3d_phy_probe(struct platform_device *pdev) +{ + struct mv_u3d_phy *mv_u3d_phy; + struct mv_usb_platform_data *pdata; + struct device *dev = &pdev->dev; + struct resource *res; + void __iomem *phy_base; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "%s: no platform data defined\n", __func__); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing mem resource\n"); + return -ENODEV; + } + + phy_base = devm_ioremap_resource(dev, res); + if (IS_ERR(phy_base)) + return PTR_ERR(phy_base); + + mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL); + if (!mv_u3d_phy) + return -ENOMEM; + + mv_u3d_phy->dev = &pdev->dev; + mv_u3d_phy->plat = pdata; + mv_u3d_phy->base = phy_base; + mv_u3d_phy->phy.dev = mv_u3d_phy->dev; + mv_u3d_phy->phy.label = "mv-u3d-phy"; + mv_u3d_phy->phy.init = mv_u3d_phy_init; + mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown; + + ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3); + if (ret) + goto err; + + if (!mv_u3d_phy->clk) + mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy"); + + platform_set_drvdata(pdev, mv_u3d_phy); + + dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n"); +err: + return ret; +} + +static int __exit mv_u3d_phy_remove(struct platform_device *pdev) +{ + struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev); + + usb_remove_phy(&mv_u3d_phy->phy); + + if (mv_u3d_phy->clk) { + clk_put(mv_u3d_phy->clk); + mv_u3d_phy->clk = NULL; + } + + return 0; +} + +static struct platform_driver mv_u3d_phy_driver = { + .probe = mv_u3d_phy_probe, + .remove = mv_u3d_phy_remove, + .driver = { + .name = "mv-u3d-phy", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(mv_u3d_phy_driver); +MODULE_DESCRIPTION("Marvell USB 3.0 PHY controller"); +MODULE_AUTHOR("Yu Xu "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mv-u3d-phy"); diff --git a/drivers/usb/phy/phy-mv-u3d-usb.h b/drivers/usb/phy/phy-mv-u3d-usb.h new file mode 100644 index 000000000000..2a658cb9a527 --- /dev/null +++ b/drivers/usb/phy/phy-mv-u3d-usb.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. 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. + */ + +#ifndef __MV_U3D_PHY_H +#define __MV_U3D_PHY_H + +#define USB3_POWER_PLL_CONTROL 0x1 +#define USB3_KVCO_CALI_CONTROL 0x2 +#define USB3_IMPEDANCE_CALI_CTRL 0x3 +#define USB3_IMPEDANCE_TX_SSC 0x4 +#define USB3_SQUELCH_FFE 0x6 +#define USB3_GEN1_SET0 0xD +#define USB3_GEN2_SET0 0xF +#define USB3_GEN2_SET1 0x10 +#define USB3_DIGITAL_LOOPBACK_EN 0x23 +#define USB3_PHY_ISOLATION_MODE 0x26 +#define USB3_TXDETRX 0x48 +#define USB3_TX_EMPPH 0x5E +#define USB3_RESET_CONTROL 0x90 +#define USB3_PIPE_SM_CTRL 0x91 + +#define USB3_RESET_CONTROL_RESET_PIPE 0x1 +#define USB3_RESET_CONTROL_RESET_PHY 0x2 + +#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK (0x1F << 0) +#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT 0 +#define USB3_PLL_25MHZ 0x2 +#define USB3_PLL_26MHZ 0x5 +#define USB3_POWER_PLL_CONTROL_PHY_MODE_MASK (0x7 << 5) +#define USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT 5 +#define USB3_POWER_PLL_CONTROL_PU_MASK (0xF << 12) +#define USB3_POWER_PLL_CONTROL_PU_SHIFT 12 +#define USB3_POWER_PLL_CONTROL_PU (0xF << 12) + +#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK (0x1 << 12) +#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_SHIFT 12 +#define USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT 14 +#define USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT 15 + +#define USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK 0xF +#define USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT 0 +#define USB3_SQUELCH_FFE_FFE_RES_SEL_MASK (0x7 << 4) +#define USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT 4 +#define USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK (0x1F << 8) +#define USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT 8 + +#define USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK (0x1 << 15) +#define USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT 11 + +#define USB3_GEN2_SET0_G2_TX_AMP_MASK (0x1F << 1) +#define USB3_GEN2_SET0_G2_TX_AMP_SHIFT 1 +#define USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT 6 +#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK (0xF << 7) +#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT 7 +#define USB3_GEN2_SET0_G2_TX_EMPH_EN_MASK (0x1 << 11) +#define USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT 11 +#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK (0x1 << 15) +#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_SHIFT 15 + +#define USB3_GEN2_SET1_G2_RX_SELMUPI_MASK (0x7 << 0) +#define USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT 0 +#define USB3_GEN2_SET1_G2_RX_SELMUPF_MASK (0x7 << 3) +#define USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT 3 +#define USB3_GEN2_SET1_G2_RX_SELMUFI_MASK (0x3 << 6) +#define USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT 6 +#define USB3_GEN2_SET1_G2_RX_SELMUFF_MASK (0x3 << 8) +#define USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT 8 + +#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK (0x3 << 10) +#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT 10 + +#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK (0x7 << 12) +#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT 12 + +#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK (0x3F << 0) +#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT 0 + +#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK 0xF +#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT 0 +#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK (0xF << 4) +#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT 4 +#define USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK (0x1 << 8) + +#define USB3_TXDETRX_VTHSEL_MASK (0x3 << 4) +#define USB3_TXDETRX_VTHSEL_SHIFT 4 + +#define USB3_TX_EMPPH_AMP_MASK (0xF << 0) +#define USB3_TX_EMPPH_AMP_SHIFT 0 +#define USB3_TX_EMPPH_EN_MASK (0x1 << 6) +#define USB3_TX_EMPPH_EN_SHIFT 6 +#define USB3_TX_EMPPH_AMP_FORCE_MASK (0x1 << 7) +#define USB3_TX_EMPPH_AMP_FORCE_SHIFT 7 +#define USB3_TX_EMPPH_PAR1_MASK (0x1F << 8) +#define USB3_TX_EMPPH_PAR1_SHIFT 8 +#define USB3_TX_EMPPH_PAR2_MASK (0x1 << 13) +#define USB3_TX_EMPPH_PAR2_SHIFT 13 + +#define USB3_PIPE_SM_CTRL_PHY_INIT_DONE 15 + +#endif /* __MV_U3D_PHY_H */ diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c new file mode 100644 index 000000000000..6872bf0a3681 --- /dev/null +++ b/drivers/usb/phy/phy-mv-usb.c @@ -0,0 +1,923 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. All rights reserved. + * Author: Chao Xie + * Neil Zhang + * + * 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 "phy-mv-usb.h" + +#define DRIVER_DESC "Marvell USB OTG transceiver driver" +#define DRIVER_VERSION "Jan 20, 2010" + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static const char driver_name[] = "mv-otg"; + +static char *state_string[] = { + "undefined", + "b_idle", + "b_srp_init", + "b_peripheral", + "b_wait_acon", + "b_host", + "a_idle", + "a_wait_vrise", + "a_wait_bcon", + "a_host", + "a_suspend", + "a_peripheral", + "a_wait_vfall", + "a_vbus_err" +}; + +static int mv_otg_set_vbus(struct usb_otg *otg, bool on) +{ + struct mv_otg *mvotg = container_of(otg->phy, struct mv_otg, phy); + if (mvotg->pdata->set_vbus == NULL) + return -ENODEV; + + return mvotg->pdata->set_vbus(on); +} + +static int mv_otg_set_host(struct usb_otg *otg, + struct usb_bus *host) +{ + otg->host = host; + + return 0; +} + +static int mv_otg_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + otg->gadget = gadget; + + return 0; +} + +static void mv_otg_run_state_machine(struct mv_otg *mvotg, + unsigned long delay) +{ + dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n"); + if (!mvotg->qwork) + return; + + queue_delayed_work(mvotg->qwork, &mvotg->work, delay); +} + +static void mv_otg_timer_await_bcon(unsigned long data) +{ + struct mv_otg *mvotg = (struct mv_otg *) data; + + mvotg->otg_ctrl.a_wait_bcon_timeout = 1; + + dev_info(&mvotg->pdev->dev, "B Device No Response!\n"); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } +} + +static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id) +{ + struct timer_list *timer; + + if (id >= OTG_TIMER_NUM) + return -EINVAL; + + timer = &mvotg->otg_ctrl.timer[id]; + + if (timer_pending(timer)) + del_timer(timer); + + return 0; +} + +static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id, + unsigned long interval, + void (*callback) (unsigned long)) +{ + struct timer_list *timer; + + if (id >= OTG_TIMER_NUM) + return -EINVAL; + + timer = &mvotg->otg_ctrl.timer[id]; + if (timer_pending(timer)) { + dev_err(&mvotg->pdev->dev, "Timer%d is already running\n", id); + return -EBUSY; + } + + init_timer(timer); + timer->data = (unsigned long) mvotg; + timer->function = callback; + timer->expires = jiffies + interval; + add_timer(timer); + + return 0; +} + +static int mv_otg_reset(struct mv_otg *mvotg) +{ + unsigned int loops; + u32 tmp; + + /* Stop the controller */ + tmp = readl(&mvotg->op_regs->usbcmd); + tmp &= ~USBCMD_RUN_STOP; + writel(tmp, &mvotg->op_regs->usbcmd); + + /* Reset the controller to get default values */ + writel(USBCMD_CTRL_RESET, &mvotg->op_regs->usbcmd); + + loops = 500; + while (readl(&mvotg->op_regs->usbcmd) & USBCMD_CTRL_RESET) { + if (loops == 0) { + dev_err(&mvotg->pdev->dev, + "Wait for RESET completed TIMEOUT\n"); + return -ETIMEDOUT; + } + loops--; + udelay(20); + } + + writel(0x0, &mvotg->op_regs->usbintr); + tmp = readl(&mvotg->op_regs->usbsts); + writel(tmp, &mvotg->op_regs->usbsts); + + return 0; +} + +static void mv_otg_init_irq(struct mv_otg *mvotg) +{ + u32 otgsc; + + mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID + | OTGSC_INTR_A_VBUS_VALID; + mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID + | OTGSC_INTSTS_A_VBUS_VALID; + + if (mvotg->pdata->vbus == NULL) { + mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID + | OTGSC_INTR_B_SESSION_END; + mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID + | OTGSC_INTSTS_B_SESSION_END; + } + + if (mvotg->pdata->id == NULL) { + mvotg->irq_en |= OTGSC_INTR_USB_ID; + mvotg->irq_status |= OTGSC_INTSTS_USB_ID; + } + + otgsc = readl(&mvotg->op_regs->otgsc); + otgsc |= mvotg->irq_en; + writel(otgsc, &mvotg->op_regs->otgsc); +} + +static void mv_otg_start_host(struct mv_otg *mvotg, int on) +{ +#ifdef CONFIG_USB + struct usb_otg *otg = mvotg->phy.otg; + struct usb_hcd *hcd; + + if (!otg->host) + return; + + dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop"); + + hcd = bus_to_hcd(otg->host); + + if (on) + usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); + else + usb_remove_hcd(hcd); +#endif /* CONFIG_USB */ +} + +static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) +{ + struct usb_otg *otg = mvotg->phy.otg; + + if (!otg->gadget) + return; + + dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off"); + + if (on) + usb_gadget_vbus_connect(otg->gadget); + else + usb_gadget_vbus_disconnect(otg->gadget); +} + +static void otg_clock_enable(struct mv_otg *mvotg) +{ + unsigned int i; + + for (i = 0; i < mvotg->clknum; i++) + clk_prepare_enable(mvotg->clk[i]); +} + +static void otg_clock_disable(struct mv_otg *mvotg) +{ + unsigned int i; + + for (i = 0; i < mvotg->clknum; i++) + clk_disable_unprepare(mvotg->clk[i]); +} + +static int mv_otg_enable_internal(struct mv_otg *mvotg) +{ + int retval = 0; + + if (mvotg->active) + return 0; + + dev_dbg(&mvotg->pdev->dev, "otg enabled\n"); + + otg_clock_enable(mvotg); + if (mvotg->pdata->phy_init) { + retval = mvotg->pdata->phy_init(mvotg->phy_regs); + if (retval) { + dev_err(&mvotg->pdev->dev, + "init phy error %d\n", retval); + otg_clock_disable(mvotg); + return retval; + } + } + mvotg->active = 1; + + return 0; + +} + +static int mv_otg_enable(struct mv_otg *mvotg) +{ + if (mvotg->clock_gating) + return mv_otg_enable_internal(mvotg); + + return 0; +} + +static void mv_otg_disable_internal(struct mv_otg *mvotg) +{ + if (mvotg->active) { + dev_dbg(&mvotg->pdev->dev, "otg disabled\n"); + if (mvotg->pdata->phy_deinit) + mvotg->pdata->phy_deinit(mvotg->phy_regs); + otg_clock_disable(mvotg); + mvotg->active = 0; + } +} + +static void mv_otg_disable(struct mv_otg *mvotg) +{ + if (mvotg->clock_gating) + mv_otg_disable_internal(mvotg); +} + +static void mv_otg_update_inputs(struct mv_otg *mvotg) +{ + struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; + u32 otgsc; + + otgsc = readl(&mvotg->op_regs->otgsc); + + if (mvotg->pdata->vbus) { + if (mvotg->pdata->vbus->poll() == VBUS_HIGH) { + otg_ctrl->b_sess_vld = 1; + otg_ctrl->b_sess_end = 0; + } else { + otg_ctrl->b_sess_vld = 0; + otg_ctrl->b_sess_end = 1; + } + } else { + otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID); + otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END); + } + + if (mvotg->pdata->id) + otg_ctrl->id = !!mvotg->pdata->id->poll(); + else + otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); + + if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) + otg_ctrl->a_bus_req = 1; + + otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); + otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID); + + dev_dbg(&mvotg->pdev->dev, "%s: ", __func__); + dev_dbg(&mvotg->pdev->dev, "id %d\n", otg_ctrl->id); + dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n", otg_ctrl->b_sess_vld); + dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n", otg_ctrl->b_sess_end); + dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n", otg_ctrl->a_vbus_vld); + dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n", otg_ctrl->a_sess_vld); +} + +static void mv_otg_update_state(struct mv_otg *mvotg) +{ + struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; + struct usb_phy *phy = &mvotg->phy; + int old_state = phy->state; + + switch (old_state) { + case OTG_STATE_UNDEFINED: + phy->state = OTG_STATE_B_IDLE; + /* FALL THROUGH */ + case OTG_STATE_B_IDLE: + if (otg_ctrl->id == 0) + phy->state = OTG_STATE_A_IDLE; + else if (otg_ctrl->b_sess_vld) + phy->state = OTG_STATE_B_PERIPHERAL; + break; + case OTG_STATE_B_PERIPHERAL: + if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) + phy->state = OTG_STATE_B_IDLE; + break; + case OTG_STATE_A_IDLE: + if (otg_ctrl->id) + phy->state = OTG_STATE_B_IDLE; + else if (!(otg_ctrl->a_bus_drop) && + (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) + phy->state = OTG_STATE_A_WAIT_VRISE; + break; + case OTG_STATE_A_WAIT_VRISE: + if (otg_ctrl->a_vbus_vld) + phy->state = OTG_STATE_A_WAIT_BCON; + break; + case OTG_STATE_A_WAIT_BCON: + if (otg_ctrl->id || otg_ctrl->a_bus_drop + || otg_ctrl->a_wait_bcon_timeout) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_WAIT_VFALL; + otg_ctrl->a_bus_req = 0; + } else if (!otg_ctrl->a_vbus_vld) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_VBUS_ERR; + } else if (otg_ctrl->b_conn) { + mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); + mvotg->otg_ctrl.a_wait_bcon_timeout = 0; + phy->state = OTG_STATE_A_HOST; + } + break; + case OTG_STATE_A_HOST: + if (otg_ctrl->id || !otg_ctrl->b_conn + || otg_ctrl->a_bus_drop) + phy->state = OTG_STATE_A_WAIT_BCON; + else if (!otg_ctrl->a_vbus_vld) + phy->state = OTG_STATE_A_VBUS_ERR; + break; + case OTG_STATE_A_WAIT_VFALL: + if (otg_ctrl->id + || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) + || otg_ctrl->a_bus_req) + phy->state = OTG_STATE_A_IDLE; + break; + case OTG_STATE_A_VBUS_ERR: + if (otg_ctrl->id || otg_ctrl->a_clr_err + || otg_ctrl->a_bus_drop) { + otg_ctrl->a_clr_err = 0; + phy->state = OTG_STATE_A_WAIT_VFALL; + } + break; + default: + break; + } +} + +static void mv_otg_work(struct work_struct *work) +{ + struct mv_otg *mvotg; + struct usb_phy *phy; + struct usb_otg *otg; + int old_state; + + mvotg = container_of(to_delayed_work(work), struct mv_otg, work); + +run: + /* work queue is single thread, or we need spin_lock to protect */ + phy = &mvotg->phy; + otg = phy->otg; + old_state = phy->state; + + if (!mvotg->active) + return; + + mv_otg_update_inputs(mvotg); + mv_otg_update_state(mvotg); + + if (old_state != phy->state) { + dev_info(&mvotg->pdev->dev, "change from state %s to %s\n", + state_string[old_state], + state_string[phy->state]); + + switch (phy->state) { + case OTG_STATE_B_IDLE: + otg->default_a = 0; + if (old_state == OTG_STATE_B_PERIPHERAL) + mv_otg_start_periphrals(mvotg, 0); + mv_otg_reset(mvotg); + mv_otg_disable(mvotg); + break; + case OTG_STATE_B_PERIPHERAL: + mv_otg_enable(mvotg); + mv_otg_start_periphrals(mvotg, 1); + break; + case OTG_STATE_A_IDLE: + otg->default_a = 1; + mv_otg_enable(mvotg); + if (old_state == OTG_STATE_A_WAIT_VFALL) + mv_otg_start_host(mvotg, 0); + mv_otg_reset(mvotg); + break; + case OTG_STATE_A_WAIT_VRISE: + mv_otg_set_vbus(otg, 1); + break; + case OTG_STATE_A_WAIT_BCON: + if (old_state != OTG_STATE_A_HOST) + mv_otg_start_host(mvotg, 1); + mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER, + T_A_WAIT_BCON, + mv_otg_timer_await_bcon); + /* + * Now, we directly enter A_HOST. So set b_conn = 1 + * here. In fact, it need host driver to notify us. + */ + mvotg->otg_ctrl.b_conn = 1; + break; + case OTG_STATE_A_HOST: + break; + case OTG_STATE_A_WAIT_VFALL: + /* + * Now, we has exited A_HOST. So set b_conn = 0 + * here. In fact, it need host driver to notify us. + */ + mvotg->otg_ctrl.b_conn = 0; + mv_otg_set_vbus(otg, 0); + break; + case OTG_STATE_A_VBUS_ERR: + break; + default: + break; + } + goto run; + } +} + +static irqreturn_t mv_otg_irq(int irq, void *dev) +{ + struct mv_otg *mvotg = dev; + u32 otgsc; + + otgsc = readl(&mvotg->op_regs->otgsc); + writel(otgsc, &mvotg->op_regs->otgsc); + + /* + * if we have vbus, then the vbus detection for B-device + * will be done by mv_otg_inputs_irq(). + */ + if (mvotg->pdata->vbus) + if ((otgsc & OTGSC_STS_USB_ID) && + !(otgsc & OTGSC_INTSTS_USB_ID)) + return IRQ_NONE; + + if ((otgsc & mvotg->irq_status) == 0) + return IRQ_NONE; + + mv_otg_run_state_machine(mvotg, 0); + + return IRQ_HANDLED; +} + +static irqreturn_t mv_otg_inputs_irq(int irq, void *dev) +{ + struct mv_otg *mvotg = dev; + + /* The clock may disabled at this time */ + if (!mvotg->active) { + mv_otg_enable(mvotg); + mv_otg_init_irq(mvotg); + } + + mv_otg_run_state_machine(mvotg, 0); + + return IRQ_HANDLED; +} + +static ssize_t +get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%d\n", + mvotg->otg_ctrl.a_bus_req); +} + +static ssize_t +set_a_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + + if (count > 2) + return -1; + + /* We will use this interface to change to A device */ + if (mvotg->phy.state != OTG_STATE_B_IDLE + && mvotg->phy.state != OTG_STATE_A_IDLE) + return -1; + + /* The clock may disabled and we need to set irq for ID detected */ + mv_otg_enable(mvotg); + mv_otg_init_irq(mvotg); + + if (buf[0] == '1') { + mvotg->otg_ctrl.a_bus_req = 1; + mvotg->otg_ctrl.a_bus_drop = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_req = 1\n"); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + } + + return count; +} + +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, + set_a_bus_req); + +static ssize_t +set_a_clr_err(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + if (!mvotg->phy.otg->default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '1') { + mvotg->otg_ctrl.a_clr_err = 1; + dev_dbg(&mvotg->pdev->dev, + "User request: a_clr_err = 1\n"); + } + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + + return count; +} + +static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); + +static ssize_t +get_a_bus_drop(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%d\n", + mvotg->otg_ctrl.a_bus_drop); +} + +static ssize_t +set_a_bus_drop(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mv_otg *mvotg = dev_get_drvdata(dev); + if (!mvotg->phy.otg->default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '0') { + mvotg->otg_ctrl.a_bus_drop = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_drop = 0\n"); + } else if (buf[0] == '1') { + mvotg->otg_ctrl.a_bus_drop = 1; + mvotg->otg_ctrl.a_bus_req = 0; + dev_dbg(&mvotg->pdev->dev, + "User request: a_bus_drop = 1\n"); + dev_dbg(&mvotg->pdev->dev, + "User request: and a_bus_req = 0\n"); + } + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + + return count; +} + +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, + get_a_bus_drop, set_a_bus_drop); + +static struct attribute *inputs_attrs[] = { + &dev_attr_a_bus_req.attr, + &dev_attr_a_clr_err.attr, + &dev_attr_a_bus_drop.attr, + NULL, +}; + +static struct attribute_group inputs_attr_group = { + .name = "inputs", + .attrs = inputs_attrs, +}; + +int mv_otg_remove(struct platform_device *pdev) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + + sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); + + if (mvotg->qwork) { + flush_workqueue(mvotg->qwork); + destroy_workqueue(mvotg->qwork); + } + + mv_otg_disable(mvotg); + + usb_remove_phy(&mvotg->phy); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static int mv_otg_probe(struct platform_device *pdev) +{ + struct mv_usb_platform_data *pdata = pdev->dev.platform_data; + struct mv_otg *mvotg; + struct usb_otg *otg; + struct resource *r; + int retval = 0, clk_i, i; + size_t size; + + if (pdata == NULL) { + dev_err(&pdev->dev, "failed to get platform data\n"); + return -ENODEV; + } + + size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; + mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!mvotg) { + dev_err(&pdev->dev, "failed to allocate memory!\n"); + return -ENOMEM; + } + + otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + platform_set_drvdata(pdev, mvotg); + + mvotg->pdev = pdev; + mvotg->pdata = pdata; + + mvotg->clknum = pdata->clknum; + for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { + mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, + pdata->clkname[clk_i]); + if (IS_ERR(mvotg->clk[clk_i])) { + retval = PTR_ERR(mvotg->clk[clk_i]); + return retval; + } + } + + mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); + if (!mvotg->qwork) { + dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); + + /* OTG common part */ + mvotg->pdev = pdev; + mvotg->phy.dev = &pdev->dev; + mvotg->phy.otg = otg; + mvotg->phy.label = driver_name; + mvotg->phy.state = OTG_STATE_UNDEFINED; + + otg->phy = &mvotg->phy; + otg->set_host = mv_otg_set_host; + otg->set_peripheral = mv_otg_set_peripheral; + otg->set_vbus = mv_otg_set_vbus; + + for (i = 0; i < OTG_TIMER_NUM; i++) + init_timer(&mvotg->otg_ctrl.timer[i]); + + r = platform_get_resource_byname(mvotg->pdev, + IORESOURCE_MEM, "phyregs"); + if (r == NULL) { + dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); + retval = -ENODEV; + goto err_destroy_workqueue; + } + + mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (mvotg->phy_regs == NULL) { + dev_err(&pdev->dev, "failed to map phy I/O memory\n"); + retval = -EFAULT; + goto err_destroy_workqueue; + } + + r = platform_get_resource_byname(mvotg->pdev, + IORESOURCE_MEM, "capregs"); + if (r == NULL) { + dev_err(&pdev->dev, "no I/O memory resource defined\n"); + retval = -ENODEV; + goto err_destroy_workqueue; + } + + mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (mvotg->cap_regs == NULL) { + dev_err(&pdev->dev, "failed to map I/O memory\n"); + retval = -EFAULT; + goto err_destroy_workqueue; + } + + /* we will acces controller register, so enable the udc controller */ + retval = mv_otg_enable_internal(mvotg); + if (retval) { + dev_err(&pdev->dev, "mv otg enable error %d\n", retval); + goto err_destroy_workqueue; + } + + mvotg->op_regs = + (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs + + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); + + if (pdata->id) { + retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, + NULL, mv_otg_inputs_irq, + IRQF_ONESHOT, "id", mvotg); + if (retval) { + dev_info(&pdev->dev, + "Failed to request irq for ID\n"); + pdata->id = NULL; + } + } + + if (pdata->vbus) { + mvotg->clock_gating = 1; + retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, + NULL, mv_otg_inputs_irq, + IRQF_ONESHOT, "vbus", mvotg); + if (retval) { + dev_info(&pdev->dev, + "Failed to request irq for VBUS, " + "disable clock gating\n"); + mvotg->clock_gating = 0; + pdata->vbus = NULL; + } + } + + if (pdata->disable_otg_clock_gating) + mvotg->clock_gating = 0; + + mv_otg_reset(mvotg); + mv_otg_init_irq(mvotg); + + r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no IRQ resource defined\n"); + retval = -ENODEV; + goto err_disable_clk; + } + + mvotg->irq = r->start; + if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, + driver_name, mvotg)) { + dev_err(&pdev->dev, "Request irq %d for OTG failed\n", + mvotg->irq); + mvotg->irq = 0; + retval = -ENODEV; + goto err_disable_clk; + } + + retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); + if (retval < 0) { + dev_err(&pdev->dev, "can't register transceiver, %d\n", + retval); + goto err_disable_clk; + } + + retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); + if (retval < 0) { + dev_dbg(&pdev->dev, + "Can't register sysfs attr group: %d\n", retval); + goto err_remove_phy; + } + + spin_lock_init(&mvotg->wq_lock); + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 2 * HZ); + spin_unlock(&mvotg->wq_lock); + } + + dev_info(&pdev->dev, + "successful probe OTG device %s clock gating.\n", + mvotg->clock_gating ? "with" : "without"); + + return 0; + +err_remove_phy: + usb_remove_phy(&mvotg->phy); +err_disable_clk: + mv_otg_disable_internal(mvotg); +err_destroy_workqueue: + flush_workqueue(mvotg->qwork); + destroy_workqueue(mvotg->qwork); + + platform_set_drvdata(pdev, NULL); + + return retval; +} + +#ifdef CONFIG_PM +static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + + if (mvotg->phy.state != OTG_STATE_B_IDLE) { + dev_info(&pdev->dev, + "OTG state is not B_IDLE, it is %d!\n", + mvotg->phy.state); + return -EAGAIN; + } + + if (!mvotg->clock_gating) + mv_otg_disable_internal(mvotg); + + return 0; +} + +static int mv_otg_resume(struct platform_device *pdev) +{ + struct mv_otg *mvotg = platform_get_drvdata(pdev); + u32 otgsc; + + if (!mvotg->clock_gating) { + mv_otg_enable_internal(mvotg); + + otgsc = readl(&mvotg->op_regs->otgsc); + otgsc |= mvotg->irq_en; + writel(otgsc, &mvotg->op_regs->otgsc); + + if (spin_trylock(&mvotg->wq_lock)) { + mv_otg_run_state_machine(mvotg, 0); + spin_unlock(&mvotg->wq_lock); + } + } + return 0; +} +#endif + +static struct platform_driver mv_otg_driver = { + .probe = mv_otg_probe, + .remove = __exit_p(mv_otg_remove), + .driver = { + .owner = THIS_MODULE, + .name = driver_name, + }, +#ifdef CONFIG_PM + .suspend = mv_otg_suspend, + .resume = mv_otg_resume, +#endif +}; +module_platform_driver(mv_otg_driver); diff --git a/drivers/usb/phy/phy-mv-usb.h b/drivers/usb/phy/phy-mv-usb.h new file mode 100644 index 000000000000..8a9e351b36ba --- /dev/null +++ b/drivers/usb/phy/phy-mv-usb.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 Marvell International Ltd. 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. + */ + +#ifndef __MV_USB_OTG_CONTROLLER__ +#define __MV_USB_OTG_CONTROLLER__ + +#include + +/* Command Register Bit Masks */ +#define USBCMD_RUN_STOP (0x00000001) +#define USBCMD_CTRL_RESET (0x00000002) + +/* otgsc Register Bit Masks */ +#define OTGSC_CTRL_VUSB_DISCHARGE 0x00000001 +#define OTGSC_CTRL_VUSB_CHARGE 0x00000002 +#define OTGSC_CTRL_OTG_TERM 0x00000008 +#define OTGSC_CTRL_DATA_PULSING 0x00000010 +#define OTGSC_STS_USB_ID 0x00000100 +#define OTGSC_STS_A_VBUS_VALID 0x00000200 +#define OTGSC_STS_A_SESSION_VALID 0x00000400 +#define OTGSC_STS_B_SESSION_VALID 0x00000800 +#define OTGSC_STS_B_SESSION_END 0x00001000 +#define OTGSC_STS_1MS_TOGGLE 0x00002000 +#define OTGSC_STS_DATA_PULSING 0x00004000 +#define OTGSC_INTSTS_USB_ID 0x00010000 +#define OTGSC_INTSTS_A_VBUS_VALID 0x00020000 +#define OTGSC_INTSTS_A_SESSION_VALID 0x00040000 +#define OTGSC_INTSTS_B_SESSION_VALID 0x00080000 +#define OTGSC_INTSTS_B_SESSION_END 0x00100000 +#define OTGSC_INTSTS_1MS 0x00200000 +#define OTGSC_INTSTS_DATA_PULSING 0x00400000 +#define OTGSC_INTR_USB_ID 0x01000000 +#define OTGSC_INTR_A_VBUS_VALID 0x02000000 +#define OTGSC_INTR_A_SESSION_VALID 0x04000000 +#define OTGSC_INTR_B_SESSION_VALID 0x08000000 +#define OTGSC_INTR_B_SESSION_END 0x10000000 +#define OTGSC_INTR_1MS_TIMER 0x20000000 +#define OTGSC_INTR_DATA_PULSING 0x40000000 + +#define CAPLENGTH_MASK (0xff) + +/* Timer's interval, unit 10ms */ +#define T_A_WAIT_VRISE 100 +#define T_A_WAIT_BCON 2000 +#define T_A_AIDL_BDIS 100 +#define T_A_BIDL_ADIS 20 +#define T_B_ASE0_BRST 400 +#define T_B_SE0_SRP 300 +#define T_B_SRP_FAIL 2000 +#define T_B_DATA_PLS 10 +#define T_B_SRP_INIT 100 +#define T_A_SRP_RSPNS 10 +#define T_A_DRV_RSM 5 + +enum otg_function { + OTG_B_DEVICE = 0, + OTG_A_DEVICE +}; + +enum mv_otg_timer { + A_WAIT_BCON_TIMER = 0, + OTG_TIMER_NUM +}; + +/* PXA OTG state machine */ +struct mv_otg_ctrl { + /* internal variables */ + u8 a_set_b_hnp_en; /* A-Device set b_hnp_en */ + u8 b_srp_done; + u8 b_hnp_en; + + /* OTG inputs */ + u8 a_bus_drop; + u8 a_bus_req; + u8 a_clr_err; + u8 a_bus_resume; + u8 a_bus_suspend; + u8 a_conn; + u8 a_sess_vld; + u8 a_srp_det; + u8 a_vbus_vld; + u8 b_bus_req; /* B-Device Require Bus */ + u8 b_bus_resume; + u8 b_bus_suspend; + u8 b_conn; + u8 b_se0_srp; + u8 b_sess_end; + u8 b_sess_vld; + u8 id; + u8 a_suspend_req; + + /*Timer event */ + u8 a_aidl_bdis_timeout; + u8 b_ase0_brst_timeout; + u8 a_bidl_adis_timeout; + u8 a_wait_bcon_timeout; + + struct timer_list timer[OTG_TIMER_NUM]; +}; + +#define VUSBHS_MAX_PORTS 8 + +struct mv_otg_regs { + u32 usbcmd; /* Command register */ + u32 usbsts; /* Status register */ + u32 usbintr; /* Interrupt enable */ + u32 frindex; /* Frame index */ + u32 reserved1[1]; + u32 deviceaddr; /* Device Address */ + u32 eplistaddr; /* Endpoint List Address */ + u32 ttctrl; /* HOST TT status and control */ + u32 burstsize; /* Programmable Burst Size */ + u32 txfilltuning; /* Host Transmit Pre-Buffer Packet Tuning */ + u32 reserved[4]; + u32 epnak; /* Endpoint NAK */ + u32 epnaken; /* Endpoint NAK Enable */ + u32 configflag; /* Configured Flag register */ + u32 portsc[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */ + u32 otgsc; + u32 usbmode; /* USB Host/Device mode */ + u32 epsetupstat; /* Endpoint Setup Status */ + u32 epprime; /* Endpoint Initialize */ + u32 epflush; /* Endpoint De-initialize */ + u32 epstatus; /* Endpoint Status */ + u32 epcomplete; /* Endpoint Interrupt On Complete */ + u32 epctrlx[16]; /* Endpoint Control, where x = 0.. 15 */ + u32 mcr; /* Mux Control */ + u32 isr; /* Interrupt Status */ + u32 ier; /* Interrupt Enable */ +}; + +struct mv_otg { + struct usb_phy phy; + struct mv_otg_ctrl otg_ctrl; + + /* base address */ + void __iomem *phy_regs; + void __iomem *cap_regs; + struct mv_otg_regs __iomem *op_regs; + + struct platform_device *pdev; + int irq; + u32 irq_status; + u32 irq_en; + + struct delayed_work work; + struct workqueue_struct *qwork; + + spinlock_t wq_lock; + + struct mv_usb_platform_data *pdata; + + unsigned int active; + unsigned int clock_gating; + unsigned int clknum; + struct clk *clk[0]; +}; + +#endif diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c new file mode 100644 index 000000000000..9d4381e64d51 --- /dev/null +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -0,0 +1,220 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2012 Marek Vasut + * on behalf of DENX Software Engineering GmbH + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "mxs_phy" + +#define HW_USBPHY_PWD 0x00 +#define HW_USBPHY_CTRL 0x30 +#define HW_USBPHY_CTRL_SET 0x34 +#define HW_USBPHY_CTRL_CLR 0x38 + +#define BM_USBPHY_CTRL_SFTRST BIT(31) +#define BM_USBPHY_CTRL_CLKGATE BIT(30) +#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) +#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) +#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) + +struct mxs_phy { + struct usb_phy phy; + struct clk *clk; +}; + +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) + +static void mxs_phy_hw_init(struct mxs_phy *mxs_phy) +{ + void __iomem *base = mxs_phy->phy.io_priv; + + stmp_reset_block(base + HW_USBPHY_CTRL); + + /* Power up the PHY */ + writel(0, base + HW_USBPHY_PWD); + + /* enable FS/LS device */ + writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | + BM_USBPHY_CTRL_ENUTMILEVEL3, + base + HW_USBPHY_CTRL_SET); +} + +static int mxs_phy_init(struct usb_phy *phy) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(phy); + + clk_prepare_enable(mxs_phy->clk); + mxs_phy_hw_init(mxs_phy); + + return 0; +} + +static void mxs_phy_shutdown(struct usb_phy *phy) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(phy); + + writel(BM_USBPHY_CTRL_CLKGATE, + phy->io_priv + HW_USBPHY_CTRL_SET); + + clk_disable_unprepare(mxs_phy->clk); +} + +static int mxs_phy_suspend(struct usb_phy *x, int suspend) +{ + struct mxs_phy *mxs_phy = to_mxs_phy(x); + + if (suspend) { + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_SET); + clk_disable_unprepare(mxs_phy->clk); + } else { + clk_prepare_enable(mxs_phy->clk); + writel(BM_USBPHY_CTRL_CLKGATE, + x->io_priv + HW_USBPHY_CTRL_CLR); + writel(0, x->io_priv + HW_USBPHY_PWD); + } + + return 0; +} + +static int mxs_phy_on_connect(struct usb_phy *phy, + enum usb_device_speed speed) +{ + dev_dbg(phy->dev, "%s speed device has connected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + + if (speed == USB_SPEED_HIGH) + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_SET); + + return 0; +} + +static int mxs_phy_on_disconnect(struct usb_phy *phy, + enum usb_device_speed speed) +{ + dev_dbg(phy->dev, "%s speed device has disconnected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + + if (speed == USB_SPEED_HIGH) + writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_CLR); + + return 0; +} + +static int mxs_phy_probe(struct platform_device *pdev) +{ + struct resource *res; + void __iomem *base; + struct clk *clk; + struct mxs_phy *mxs_phy; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get device resources\n"); + return -ENOENT; + } + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, + "can't get the clock, err=%ld", PTR_ERR(clk)); + return PTR_ERR(clk); + } + + mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); + if (!mxs_phy) { + dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); + return -ENOMEM; + } + + mxs_phy->phy.io_priv = base; + mxs_phy->phy.dev = &pdev->dev; + mxs_phy->phy.label = DRIVER_NAME; + mxs_phy->phy.init = mxs_phy_init; + mxs_phy->phy.shutdown = mxs_phy_shutdown; + mxs_phy->phy.set_suspend = mxs_phy_suspend; + mxs_phy->phy.notify_connect = mxs_phy_on_connect; + mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; + + ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); + + mxs_phy->clk = clk; + + platform_set_drvdata(pdev, &mxs_phy->phy); + + ret = usb_add_phy_dev(&mxs_phy->phy); + if (ret) + return ret; + + return 0; +} + +static int mxs_phy_remove(struct platform_device *pdev) +{ + struct mxs_phy *mxs_phy = platform_get_drvdata(pdev); + + usb_remove_phy(&mxs_phy->phy); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mxs_phy_dt_ids[] = { + { .compatible = "fsl,imx23-usbphy", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); + +static struct platform_driver mxs_phy_driver = { + .probe = mxs_phy_probe, + .remove = mxs_phy_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mxs_phy_dt_ids, + }, +}; + +static int __init mxs_phy_module_init(void) +{ + return platform_driver_register(&mxs_phy_driver); +} +postcore_initcall(mxs_phy_module_init); + +static void __exit mxs_phy_module_exit(void) +{ + platform_driver_unregister(&mxs_phy_driver); +} +module_exit(mxs_phy_module_exit); + +MODULE_ALIAS("platform:mxs-usb-phy"); +MODULE_AUTHOR("Marek Vasut "); +MODULE_AUTHOR("Richard Zhao "); +MODULE_DESCRIPTION("Freescale MXS USB PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-nop.c b/drivers/usb/phy/phy-nop.c new file mode 100644 index 000000000000..2b10cc969bbb --- /dev/null +++ b/drivers/usb/phy/phy-nop.c @@ -0,0 +1,294 @@ +/* + * drivers/usb/otg/nop-usb-xceiv.c + * + * NOP USB transceiver for all USB transceiver which are either built-in + * into USB IP or which are mostly autonomous. + * + * Copyright (C) 2009 Texas Instruments Inc + * Author: Ajay Kumar Gupta + * + * 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. + * + * Current status: + * This provides a "nop" transceiver for PHYs which are + * autonomous such as isp1504, isp1707, etc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct nop_usb_xceiv { + struct usb_phy phy; + struct device *dev; + struct clk *clk; + struct regulator *vcc; + struct regulator *reset; +}; + +static struct platform_device *pd; + +void usb_nop_xceiv_register(void) +{ + if (pd) + return; + pd = platform_device_register_simple("nop_usb_xceiv", -1, NULL, 0); + if (!pd) { + printk(KERN_ERR "Unable to register usb nop transceiver\n"); + return; + } +} +EXPORT_SYMBOL(usb_nop_xceiv_register); + +void usb_nop_xceiv_unregister(void) +{ + platform_device_unregister(pd); + pd = NULL; +} +EXPORT_SYMBOL(usb_nop_xceiv_unregister); + +static int nop_set_suspend(struct usb_phy *x, int suspend) +{ + return 0; +} + +static int nop_init(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->vcc)) { + if (regulator_enable(nop->vcc)) + dev_err(phy->dev, "Failed to enable power\n"); + } + + if (!IS_ERR(nop->clk)) + clk_enable(nop->clk); + + if (!IS_ERR(nop->reset)) { + /* De-assert RESET */ + if (regulator_enable(nop->reset)) + dev_err(phy->dev, "Failed to de-assert reset\n"); + } + + return 0; +} + +static void nop_shutdown(struct usb_phy *phy) +{ + struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev); + + if (!IS_ERR(nop->reset)) { + /* Assert RESET */ + if (regulator_disable(nop->reset)) + dev_err(phy->dev, "Failed to assert reset\n"); + } + + if (!IS_ERR(nop->clk)) + clk_disable(nop->clk); + + if (!IS_ERR(nop->vcc)) { + if (regulator_disable(nop->vcc)) + dev_err(phy->dev, "Failed to disable power\n"); + } +} + +static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) +{ + if (!otg) + return -ENODEV; + + if (!gadget) { + otg->gadget = NULL; + return -ENODEV; + } + + otg->gadget = gadget; + otg->phy->state = OTG_STATE_B_IDLE; + return 0; +} + +static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + if (!host) { + otg->host = NULL; + return -ENODEV; + } + + otg->host = host; + return 0; +} + +static int nop_usb_xceiv_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; + struct nop_usb_xceiv *nop; + enum usb_phy_type type = USB_PHY_TYPE_USB2; + int err; + u32 clk_rate = 0; + bool needs_vcc = false; + bool needs_reset = false; + + nop = devm_kzalloc(&pdev->dev, sizeof(*nop), GFP_KERNEL); + if (!nop) + return -ENOMEM; + + nop->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*nop->phy.otg), + GFP_KERNEL); + if (!nop->phy.otg) + return -ENOMEM; + + if (dev->of_node) { + struct device_node *node = dev->of_node; + + if (of_property_read_u32(node, "clock-frequency", &clk_rate)) + clk_rate = 0; + + needs_vcc = of_property_read_bool(node, "vcc-supply"); + needs_reset = of_property_read_bool(node, "reset-supply"); + + } else if (pdata) { + type = pdata->type; + clk_rate = pdata->clk_rate; + needs_vcc = pdata->needs_vcc; + needs_reset = pdata->needs_reset; + } + + nop->clk = devm_clk_get(&pdev->dev, "main_clk"); + if (IS_ERR(nop->clk)) { + dev_dbg(&pdev->dev, "Can't get phy clock: %ld\n", + PTR_ERR(nop->clk)); + } + + if (!IS_ERR(nop->clk) && clk_rate) { + err = clk_set_rate(nop->clk, clk_rate); + if (err) { + dev_err(&pdev->dev, "Error setting clock rate\n"); + return err; + } + } + + if (!IS_ERR(nop->clk)) { + err = clk_prepare(nop->clk); + if (err) { + dev_err(&pdev->dev, "Error preparing clock\n"); + return err; + } + } + + nop->vcc = devm_regulator_get(&pdev->dev, "vcc"); + if (IS_ERR(nop->vcc)) { + dev_dbg(&pdev->dev, "Error getting vcc regulator: %ld\n", + PTR_ERR(nop->vcc)); + if (needs_vcc) + return -EPROBE_DEFER; + } + + nop->reset = devm_regulator_get(&pdev->dev, "reset"); + if (IS_ERR(nop->reset)) { + dev_dbg(&pdev->dev, "Error getting reset regulator: %ld\n", + PTR_ERR(nop->reset)); + if (needs_reset) + return -EPROBE_DEFER; + } + + nop->dev = &pdev->dev; + nop->phy.dev = nop->dev; + nop->phy.label = "nop-xceiv"; + nop->phy.set_suspend = nop_set_suspend; + nop->phy.init = nop_init; + nop->phy.shutdown = nop_shutdown; + nop->phy.state = OTG_STATE_UNDEFINED; + nop->phy.type = type; + + nop->phy.otg->phy = &nop->phy; + nop->phy.otg->set_host = nop_set_host; + nop->phy.otg->set_peripheral = nop_set_peripheral; + + err = usb_add_phy_dev(&nop->phy); + if (err) { + dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + err); + goto err_add; + } + + platform_set_drvdata(pdev, nop); + + ATOMIC_INIT_NOTIFIER_HEAD(&nop->phy.notifier); + + return 0; + +err_add: + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + return err; +} + +static int nop_usb_xceiv_remove(struct platform_device *pdev) +{ + struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); + + if (!IS_ERR(nop->clk)) + clk_unprepare(nop->clk); + + usb_remove_phy(&nop->phy); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id nop_xceiv_dt_ids[] = { + { .compatible = "usb-nop-xceiv" }, + { } +}; + +MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); + +static struct platform_driver nop_usb_xceiv_driver = { + .probe = nop_usb_xceiv_probe, + .remove = nop_usb_xceiv_remove, + .driver = { + .name = "nop_usb_xceiv", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(nop_xceiv_dt_ids), + }, +}; + +static int __init nop_usb_xceiv_init(void) +{ + return platform_driver_register(&nop_usb_xceiv_driver); +} +subsys_initcall(nop_usb_xceiv_init); + +static void __exit nop_usb_xceiv_exit(void) +{ + platform_driver_unregister(&nop_usb_xceiv_driver); +} +module_exit(nop_usb_xceiv_exit); + +MODULE_ALIAS("platform:nop_usb_xceiv"); +MODULE_AUTHOR("Texas Instruments Inc"); +MODULE_DESCRIPTION("NOP USB Transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/usb/phy/phy-omap-control.c new file mode 100644 index 000000000000..1419ceda9759 --- /dev/null +++ b/drivers/usb/phy/phy-omap-control.c @@ -0,0 +1,289 @@ +/* + * omap-control-usb.c - The USB part of control module. + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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. + * + * Author: Kishon Vijay Abraham I + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT 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 + +static struct omap_control_usb *control_usb; + +/** + * omap_get_control_dev - returns the device pointer for this control device + * + * This API should be called to get the device pointer for this control + * module device. This device pointer should be used for called other + * exported API's in this driver. + * + * To be used by PHY driver and glue driver. + */ +struct device *omap_get_control_dev(void) +{ + if (!control_usb) + return ERR_PTR(-ENODEV); + + return control_usb->dev; +} +EXPORT_SYMBOL_GPL(omap_get_control_dev); + +/** + * omap_control_usb3_phy_power - power on/off the serializer using control + * module + * @dev: the control module device + * @on: 0 to off and 1 to on based on powering on or off the PHY + * + * usb3 PHY driver should call this API to power on or off the PHY. + */ +void omap_control_usb3_phy_power(struct device *dev, bool on) +{ + u32 val; + unsigned long rate; + struct omap_control_usb *control_usb = dev_get_drvdata(dev); + + if (control_usb->type != OMAP_CTRL_DEV_TYPE2) + return; + + rate = clk_get_rate(control_usb->sys_clk); + rate = rate/1000000; + + val = readl(control_usb->phy_power); + + if (on) { + val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | + OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); + val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << + OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; + val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; + } else { + val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; + val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << + OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; + } + + writel(val, control_usb->phy_power); +} +EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power); + +/** + * omap_control_usb_phy_power - power on/off the phy using control module reg + * @dev: the control module device + * @on: 0 or 1, based on powering on or off the PHY + */ +void omap_control_usb_phy_power(struct device *dev, int on) +{ + u32 val; + struct omap_control_usb *control_usb = dev_get_drvdata(dev); + + val = readl(control_usb->dev_conf); + + if (on) + val &= ~OMAP_CTRL_DEV_PHY_PD; + else + val |= OMAP_CTRL_DEV_PHY_PD; + + writel(val, control_usb->dev_conf); +} +EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); + +/** + * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded + * @ctrl_usb: struct omap_control_usb * + * + * Writes to the mailbox register to notify the usb core that a usb + * device has been connected. + */ +static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb) +{ + u32 val; + + val = readl(ctrl_usb->otghs_control); + val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); + val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; + writel(val, ctrl_usb->otghs_control); +} + +/** + * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high + * impedance + * @ctrl_usb: struct omap_control_usb * + * + * Writes to the mailbox register to notify the usb core that it has been + * connected to a usb host. + */ +static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb) +{ + u32 val; + + val = readl(ctrl_usb->otghs_control); + val &= ~OMAP_CTRL_DEV_SESSEND; + val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | + OMAP_CTRL_DEV_VBUSVALID; + writel(val, ctrl_usb->otghs_control); +} + +/** + * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high + * impedance + * @ctrl_usb: struct omap_control_usb * + * + * Writes to the mailbox register to notify the usb core it's now in + * disconnected state. + */ +static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) +{ + u32 val; + + val = readl(ctrl_usb->otghs_control); + val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); + val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; + writel(val, ctrl_usb->otghs_control); +} + +/** + * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode + * or device mode or to denote disconnected state + * @dev: the control module device + * @mode: The mode to which usb should be configured + * + * This is an API to write to the mailbox register to notify the usb core that + * a usb device has been connected. + */ +void omap_control_usb_set_mode(struct device *dev, + enum omap_control_usb_mode mode) +{ + struct omap_control_usb *ctrl_usb; + + if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1) + return; + + ctrl_usb = dev_get_drvdata(dev); + + switch (mode) { + case USB_MODE_HOST: + omap_control_usb_host_mode(ctrl_usb); + break; + case USB_MODE_DEVICE: + omap_control_usb_device_mode(ctrl_usb); + break; + case USB_MODE_DISCONNECT: + omap_control_usb_set_sessionend(ctrl_usb); + break; + default: + dev_vdbg(dev, "invalid omap control usb mode\n"); + } +} +EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); + +static int omap_control_usb_probe(struct platform_device *pdev) +{ + struct resource *res; + struct device_node *np = pdev->dev.of_node; + struct omap_control_usb_platform_data *pdata = pdev->dev.platform_data; + + control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), + GFP_KERNEL); + if (!control_usb) { + dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); + return -ENOMEM; + } + + if (np) { + of_property_read_u32(np, "ti,type", &control_usb->type); + } else if (pdata) { + control_usb->type = pdata->type; + } else { + dev_err(&pdev->dev, "no pdata present\n"); + return -EINVAL; + } + + control_usb->dev = &pdev->dev; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "control_dev_conf"); + control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(control_usb->dev_conf)) + return PTR_ERR(control_usb->dev_conf); + + if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "otghs_control"); + control_usb->otghs_control = devm_ioremap_resource( + &pdev->dev, res); + if (IS_ERR(control_usb->otghs_control)) + return PTR_ERR(control_usb->otghs_control); + } + + if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "phy_power_usb"); + control_usb->phy_power = devm_ioremap_resource( + &pdev->dev, res); + if (IS_ERR(control_usb->phy_power)) + return PTR_ERR(control_usb->phy_power); + + control_usb->sys_clk = devm_clk_get(control_usb->dev, + "sys_clkin"); + if (IS_ERR(control_usb->sys_clk)) { + pr_err("%s: unable to get sys_clkin\n", __func__); + return -EINVAL; + } + } + + + dev_set_drvdata(control_usb->dev, control_usb); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id omap_control_usb_id_table[] = { + { .compatible = "ti,omap-control-usb" }, + {} +}; +MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); +#endif + +static struct platform_driver omap_control_usb_driver = { + .probe = omap_control_usb_probe, + .driver = { + .name = "omap-control-usb", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(omap_control_usb_id_table), + }, +}; + +static int __init omap_control_usb_init(void) +{ + return platform_driver_register(&omap_control_usb_driver); +} +subsys_initcall(omap_control_usb_init); + +static void __exit omap_control_usb_exit(void) +{ + platform_driver_unregister(&omap_control_usb_driver); +} +module_exit(omap_control_usb_exit); + +MODULE_ALIAS("platform: omap_control_usb"); +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("OMAP Control Module USB Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c new file mode 100644 index 000000000000..844ab68f08d0 --- /dev/null +++ b/drivers/usb/phy/phy-omap-usb2.c @@ -0,0 +1,273 @@ +/* + * omap-usb2.c - USB PHY, talking to musb controller in OMAP. + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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. + * + * Author: Kishon Vijay Abraham I + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * omap_usb2_set_comparator - links the comparator present in the sytem with + * this phy + * @comparator - the companion phy(comparator) for this phy + * + * The phy companion driver should call this API passing the phy_companion + * filled with set_vbus and start_srp to be used by usb phy. + * + * For use by phy companion driver + */ +int omap_usb2_set_comparator(struct phy_companion *comparator) +{ + struct omap_usb *phy; + struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(x)) + return -ENODEV; + + phy = phy_to_omapusb(x); + phy->comparator = comparator; + return 0; +} +EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); + +static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) +{ + struct omap_usb *phy = phy_to_omapusb(otg->phy); + + if (!phy->comparator) + return -ENODEV; + + return phy->comparator->set_vbus(phy->comparator, enabled); +} + +static int omap_usb_start_srp(struct usb_otg *otg) +{ + struct omap_usb *phy = phy_to_omapusb(otg->phy); + + if (!phy->comparator) + return -ENODEV; + + return phy->comparator->start_srp(phy->comparator); +} + +static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct usb_phy *phy = otg->phy; + + otg->host = host; + if (!host) + phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int omap_usb_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + struct usb_phy *phy = otg->phy; + + otg->gadget = gadget; + if (!gadget) + phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int omap_usb2_suspend(struct usb_phy *x, int suspend) +{ + u32 ret; + struct omap_usb *phy = phy_to_omapusb(x); + + if (suspend && !phy->is_suspended) { + omap_control_usb_phy_power(phy->control_dev, 0); + pm_runtime_put_sync(phy->dev); + phy->is_suspended = 1; + } else if (!suspend && phy->is_suspended) { + ret = pm_runtime_get_sync(phy->dev); + if (ret < 0) { + dev_err(phy->dev, "get_sync failed with err %d\n", + ret); + return ret; + } + omap_control_usb_phy_power(phy->control_dev, 1); + phy->is_suspended = 0; + } + + return 0; +} + +static int omap_usb2_probe(struct platform_device *pdev) +{ + struct omap_usb *phy; + struct usb_otg *otg; + + phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); + if (!phy) { + dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); + return -ENOMEM; + } + + otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); + if (!otg) { + dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); + return -ENOMEM; + } + + phy->dev = &pdev->dev; + + phy->phy.dev = phy->dev; + phy->phy.label = "omap-usb2"; + phy->phy.set_suspend = omap_usb2_suspend; + phy->phy.otg = otg; + phy->phy.type = USB_PHY_TYPE_USB2; + + phy->control_dev = omap_get_control_dev(); + if (IS_ERR(phy->control_dev)) { + dev_dbg(&pdev->dev, "Failed to get control device\n"); + return -ENODEV; + } + + phy->is_suspended = 1; + omap_control_usb_phy_power(phy->control_dev, 0); + + otg->set_host = omap_usb_set_host; + otg->set_peripheral = omap_usb_set_peripheral; + otg->set_vbus = omap_usb_set_vbus; + otg->start_srp = omap_usb_start_srp; + otg->phy = &phy->phy; + + phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); + if (IS_ERR(phy->wkupclk)) { + dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); + return PTR_ERR(phy->wkupclk); + } + clk_prepare(phy->wkupclk); + + phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); + if (IS_ERR(phy->optclk)) + dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); + else + clk_prepare(phy->optclk); + + usb_add_phy_dev(&phy->phy); + + platform_set_drvdata(pdev, phy); + + pm_runtime_enable(phy->dev); + + return 0; +} + +static int omap_usb2_remove(struct platform_device *pdev) +{ + struct omap_usb *phy = platform_get_drvdata(pdev); + + clk_unprepare(phy->wkupclk); + if (!IS_ERR(phy->optclk)) + clk_unprepare(phy->optclk); + usb_remove_phy(&phy->phy); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME + +static int omap_usb2_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_usb *phy = platform_get_drvdata(pdev); + + clk_disable(phy->wkupclk); + if (!IS_ERR(phy->optclk)) + clk_disable(phy->optclk); + + return 0; +} + +static int omap_usb2_runtime_resume(struct device *dev) +{ + u32 ret = 0; + struct platform_device *pdev = to_platform_device(dev); + struct omap_usb *phy = platform_get_drvdata(pdev); + + ret = clk_enable(phy->wkupclk); + if (ret < 0) { + dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); + goto err0; + } + + if (!IS_ERR(phy->optclk)) { + ret = clk_enable(phy->optclk); + if (ret < 0) { + dev_err(phy->dev, "Failed to enable optclk %d\n", ret); + goto err1; + } + } + + return 0; + +err1: + clk_disable(phy->wkupclk); + +err0: + return ret; +} + +static const struct dev_pm_ops omap_usb2_pm_ops = { + SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, + NULL) +}; + +#define DEV_PM_OPS (&omap_usb2_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +#ifdef CONFIG_OF +static const struct of_device_id omap_usb2_id_table[] = { + { .compatible = "ti,omap-usb2" }, + {} +}; +MODULE_DEVICE_TABLE(of, omap_usb2_id_table); +#endif + +static struct platform_driver omap_usb2_driver = { + .probe = omap_usb2_probe, + .remove = omap_usb2_remove, + .driver = { + .name = "omap-usb2", + .owner = THIS_MODULE, + .pm = DEV_PM_OPS, + .of_match_table = of_match_ptr(omap_usb2_id_table), + }, +}; + +module_platform_driver(omap_usb2_driver); + +MODULE_ALIAS("platform: omap_usb2"); +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("OMAP USB2 phy driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c new file mode 100644 index 000000000000..a6e60b1e102e --- /dev/null +++ b/drivers/usb/phy/phy-omap-usb3.c @@ -0,0 +1,353 @@ +/* + * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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. + * + * Author: Kishon Vijay Abraham I + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_SYS_CLKS 5 +#define PLL_STATUS 0x00000004 +#define PLL_GO 0x00000008 +#define PLL_CONFIGURATION1 0x0000000C +#define PLL_CONFIGURATION2 0x00000010 +#define PLL_CONFIGURATION3 0x00000014 +#define PLL_CONFIGURATION4 0x00000020 + +#define PLL_REGM_MASK 0x001FFE00 +#define PLL_REGM_SHIFT 0x9 +#define PLL_REGM_F_MASK 0x0003FFFF +#define PLL_REGM_F_SHIFT 0x0 +#define PLL_REGN_MASK 0x000001FE +#define PLL_REGN_SHIFT 0x1 +#define PLL_SELFREQDCO_MASK 0x0000000E +#define PLL_SELFREQDCO_SHIFT 0x1 +#define PLL_SD_MASK 0x0003FC00 +#define PLL_SD_SHIFT 0x9 +#define SET_PLL_GO 0x1 +#define PLL_TICOPWDN 0x10000 +#define PLL_LOCK 0x2 +#define PLL_IDLE 0x1 + +/* + * This is an Empirical value that works, need to confirm the actual + * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status + * to be correctly reflected in the USB3PHY_PLL_STATUS register. + */ +# define PLL_IDLE_TIME 100; + +enum sys_clk_rate { + CLK_RATE_UNDEFINED = -1, + CLK_RATE_12MHZ, + CLK_RATE_16MHZ, + CLK_RATE_19MHZ, + CLK_RATE_26MHZ, + CLK_RATE_38MHZ +}; + +static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = { + {1250, 5, 4, 20, 0}, /* 12 MHz */ + {3125, 20, 4, 20, 0}, /* 16.8 MHz */ + {1172, 8, 4, 20, 65537}, /* 19.2 MHz */ + {1250, 12, 4, 20, 0}, /* 26 MHz */ + {3125, 47, 4, 20, 92843}, /* 38.4 MHz */ +}; + +static int omap_usb3_suspend(struct usb_phy *x, int suspend) +{ + struct omap_usb *phy = phy_to_omapusb(x); + int val; + int timeout = PLL_IDLE_TIME; + + if (suspend && !phy->is_suspended) { + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val |= PLL_IDLE; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + do { + val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); + if (val & PLL_TICOPWDN) + break; + udelay(1); + } while (--timeout); + + omap_control_usb3_phy_power(phy->control_dev, 0); + + phy->is_suspended = 1; + } else if (!suspend && phy->is_suspended) { + phy->is_suspended = 0; + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val &= ~PLL_IDLE; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + do { + val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); + if (!(val & PLL_TICOPWDN)) + break; + udelay(1); + } while (--timeout); + } + + return 0; +} + +static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate) +{ + switch (rate) { + case 12000000: + return CLK_RATE_12MHZ; + case 16800000: + return CLK_RATE_16MHZ; + case 19200000: + return CLK_RATE_19MHZ; + case 26000000: + return CLK_RATE_26MHZ; + case 38400000: + return CLK_RATE_38MHZ; + default: + return CLK_RATE_UNDEFINED; + } +} + +static void omap_usb_dpll_relock(struct omap_usb *phy) +{ + u32 val; + unsigned long timeout; + + omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); + + timeout = jiffies + msecs_to_jiffies(20); + do { + val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); + if (val & PLL_LOCK) + break; + } while (!WARN_ON(time_after(jiffies, timeout))); +} + +static int omap_usb_dpll_lock(struct omap_usb *phy) +{ + u32 val; + unsigned long rate; + enum sys_clk_rate clk_index; + + rate = clk_get_rate(phy->sys_clk); + clk_index = __get_sys_clk_index(rate); + + if (clk_index == CLK_RATE_UNDEFINED) { + pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate); + return -EINVAL; + } + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGN_MASK; + val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val &= ~PLL_SELFREQDCO_MASK; + val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGM_MASK; + val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); + val &= ~PLL_REGM_F_MASK; + val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); + + val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); + val &= ~PLL_SD_MASK; + val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT; + omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); + + omap_usb_dpll_relock(phy); + + return 0; +} + +static int omap_usb3_init(struct usb_phy *x) +{ + struct omap_usb *phy = phy_to_omapusb(x); + + omap_usb_dpll_lock(phy); + omap_control_usb3_phy_power(phy->control_dev, 1); + + return 0; +} + +static int omap_usb3_probe(struct platform_device *pdev) +{ + struct omap_usb *phy; + struct resource *res; + + phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); + if (!phy) { + dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); + return -ENOMEM; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); + phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(phy->pll_ctrl_base)) + return PTR_ERR(phy->pll_ctrl_base); + + phy->dev = &pdev->dev; + + phy->phy.dev = phy->dev; + phy->phy.label = "omap-usb3"; + phy->phy.init = omap_usb3_init; + phy->phy.set_suspend = omap_usb3_suspend; + phy->phy.type = USB_PHY_TYPE_USB3; + + phy->is_suspended = 1; + phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); + if (IS_ERR(phy->wkupclk)) { + dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); + return PTR_ERR(phy->wkupclk); + } + clk_prepare(phy->wkupclk); + + phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); + if (IS_ERR(phy->optclk)) { + dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); + return PTR_ERR(phy->optclk); + } + clk_prepare(phy->optclk); + + phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); + if (IS_ERR(phy->sys_clk)) { + pr_err("%s: unable to get sys_clkin\n", __func__); + return -EINVAL; + } + + phy->control_dev = omap_get_control_dev(); + if (IS_ERR(phy->control_dev)) { + dev_dbg(&pdev->dev, "Failed to get control device\n"); + return -ENODEV; + } + + omap_control_usb3_phy_power(phy->control_dev, 0); + usb_add_phy_dev(&phy->phy); + + platform_set_drvdata(pdev, phy); + + pm_runtime_enable(phy->dev); + pm_runtime_get(&pdev->dev); + + return 0; +} + +static int omap_usb3_remove(struct platform_device *pdev) +{ + struct omap_usb *phy = platform_get_drvdata(pdev); + + clk_unprepare(phy->wkupclk); + clk_unprepare(phy->optclk); + usb_remove_phy(&phy->phy); + if (!pm_runtime_suspended(&pdev->dev)) + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME + +static int omap_usb3_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_usb *phy = platform_get_drvdata(pdev); + + clk_disable(phy->wkupclk); + clk_disable(phy->optclk); + + return 0; +} + +static int omap_usb3_runtime_resume(struct device *dev) +{ + u32 ret = 0; + struct platform_device *pdev = to_platform_device(dev); + struct omap_usb *phy = platform_get_drvdata(pdev); + + ret = clk_enable(phy->optclk); + if (ret) { + dev_err(phy->dev, "Failed to enable optclk %d\n", ret); + goto err1; + } + + ret = clk_enable(phy->wkupclk); + if (ret) { + dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); + goto err2; + } + + return 0; + +err2: + clk_disable(phy->optclk); + +err1: + return ret; +} + +static const struct dev_pm_ops omap_usb3_pm_ops = { + SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume, + NULL) +}; + +#define DEV_PM_OPS (&omap_usb3_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +#ifdef CONFIG_OF +static const struct of_device_id omap_usb3_id_table[] = { + { .compatible = "ti,omap-usb3" }, + {} +}; +MODULE_DEVICE_TABLE(of, omap_usb3_id_table); +#endif + +static struct platform_driver omap_usb3_driver = { + .probe = omap_usb3_probe, + .remove = omap_usb3_remove, + .driver = { + .name = "omap-usb3", + .owner = THIS_MODULE, + .pm = DEV_PM_OPS, + .of_match_table = of_match_ptr(omap_usb3_id_table), + }, +}; + +module_platform_driver(omap_usb3_driver); + +MODULE_ALIAS("platform: omap_usb3"); +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("OMAP USB3 phy driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c new file mode 100644 index 000000000000..a35681b0c501 --- /dev/null +++ b/drivers/usb/phy/phy-rcar-usb.c @@ -0,0 +1,220 @@ +/* + * Renesas R-Car USB phy driver + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +/* USBH common register */ +#define USBPCTRL0 0x0800 +#define USBPCTRL1 0x0804 +#define USBST 0x0808 +#define USBEH0 0x080C +#define USBOH0 0x081C +#define USBCTL0 0x0858 +#define EIIBC1 0x0094 +#define EIIBC2 0x009C + +/* USBPCTRL1 */ +#define PHY_RST (1 << 2) +#define PLL_ENB (1 << 1) +#define PHY_ENB (1 << 0) + +/* USBST */ +#define ST_ACT (1 << 31) +#define ST_PLL (1 << 30) + +struct rcar_usb_phy_priv { + struct usb_phy phy; + spinlock_t lock; + + void __iomem *reg0; + void __iomem *reg1; + int counter; +}; + +#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy) + + +/* + * USB initial/install operation. + * + * This function setup USB phy. + * The used value and setting order came from + * [USB :: Initial setting] on datasheet. + */ +static int rcar_usb_phy_init(struct usb_phy *phy) +{ + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); + struct device *dev = phy->dev; + void __iomem *reg0 = priv->reg0; + void __iomem *reg1 = priv->reg1; + int i; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->counter++ == 0) { + + /* + * USB phy start-up + */ + + /* (1) USB-PHY standby release */ + iowrite32(PHY_ENB, (reg0 + USBPCTRL1)); + + /* (2) start USB-PHY internal PLL */ + iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); + + /* (3) USB module status check */ + for (i = 0; i < 1024; i++) { + udelay(10); + val = ioread32(reg0 + USBST); + if (val == (ST_ACT | ST_PLL)) + break; + } + + if (val != (ST_ACT | ST_PLL)) { + dev_err(dev, "USB phy not ready\n"); + goto phy_init_end; + } + + /* (4) USB-PHY reset clear */ + iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); + + /* set platform specific port settings */ + iowrite32(0x00000000, (reg0 + USBPCTRL0)); + + /* + * EHCI IP internal buffer setting + * EHCI IP internal buffer enable + * + * These are recommended value of a datasheet + * see [USB :: EHCI internal buffer setting] + */ + iowrite32(0x00ff0040, (reg0 + EIIBC1)); + iowrite32(0x00ff0040, (reg1 + EIIBC1)); + + iowrite32(0x00000001, (reg0 + EIIBC2)); + iowrite32(0x00000001, (reg1 + EIIBC2)); + + /* + * Bus alignment settings + */ + + /* (1) EHCI bus alignment (little endian) */ + iowrite32(0x00000000, (reg0 + USBEH0)); + + /* (1) OHCI bus alignment (little endian) */ + iowrite32(0x00000000, (reg0 + USBOH0)); + } + +phy_init_end: + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static void rcar_usb_phy_shutdown(struct usb_phy *phy) +{ + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); + void __iomem *reg0 = priv->reg0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->counter-- == 1) { /* last user */ + iowrite32(0x00000000, (reg0 + USBPCTRL0)); + iowrite32(0x00000000, (reg0 + USBPCTRL1)); + } + + spin_unlock_irqrestore(&priv->lock, flags); +} + +static int rcar_usb_phy_probe(struct platform_device *pdev) +{ + struct rcar_usb_phy_priv *priv; + struct resource *res0, *res1; + struct device *dev = &pdev->dev; + void __iomem *reg0, *reg1; + int ret; + + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res0 || !res1) { + dev_err(dev, "Not enough platform resources\n"); + return -EINVAL; + } + + /* + * CAUTION + * + * Because this phy address is also mapped under OHCI/EHCI address area, + * this driver can't use devm_request_and_ioremap(dev, res) here + */ + reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0)); + reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1)); + if (!reg0 || !reg1) { + dev_err(dev, "ioremap error\n"); + return -ENOMEM; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(dev, "priv data allocation error\n"); + return -ENOMEM; + } + + priv->reg0 = reg0; + priv->reg1 = reg1; + priv->counter = 0; + priv->phy.dev = dev; + priv->phy.label = dev_name(dev); + priv->phy.init = rcar_usb_phy_init; + priv->phy.shutdown = rcar_usb_phy_shutdown; + spin_lock_init(&priv->lock); + + ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); + if (ret < 0) { + dev_err(dev, "usb phy addition error\n"); + return ret; + } + + platform_set_drvdata(pdev, priv); + + return ret; +} + +static int rcar_usb_phy_remove(struct platform_device *pdev) +{ + struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev); + + usb_remove_phy(&priv->phy); + + return 0; +} + +static struct platform_driver rcar_usb_phy_driver = { + .driver = { + .name = "rcar_usb_phy", + }, + .probe = rcar_usb_phy_probe, + .remove = rcar_usb_phy_remove, +}; + +module_platform_driver(rcar_usb_phy_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Renesas R-Car USB phy"); +MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c new file mode 100644 index 000000000000..967101ec15fd --- /dev/null +++ b/drivers/usb/phy/phy-samsung-usb.c @@ -0,0 +1,928 @@ +/* linux/drivers/usb/phy/samsung-usbphy.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Praveen Paneri + * + * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and + * OHCI-EXYNOS controllers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ + +#define SAMSUNG_PHYPWR (0x00) + +#define PHYPWR_NORMAL_MASK (0x19 << 0) +#define PHYPWR_OTG_DISABLE (0x1 << 4) +#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) +#define PHYPWR_FORCE_SUSPEND (0x1 << 1) +/* For Exynos4 */ +#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0) +#define PHYPWR_SLEEP_PHY0 (0x1 << 5) + +#define SAMSUNG_PHYCLK (0x04) + +#define PHYCLK_MODE_USB11 (0x1 << 6) +#define PHYCLK_EXT_OSC (0x1 << 5) +#define PHYCLK_COMMON_ON_N (0x1 << 4) +#define PHYCLK_ID_PULL (0x1 << 2) +#define PHYCLK_CLKSEL_MASK (0x3 << 0) +#define PHYCLK_CLKSEL_48M (0x0 << 0) +#define PHYCLK_CLKSEL_12M (0x2 << 0) +#define PHYCLK_CLKSEL_24M (0x3 << 0) + +#define SAMSUNG_RSTCON (0x08) + +#define RSTCON_PHYLINK_SWRST (0x1 << 2) +#define RSTCON_HLINK_SWRST (0x1 << 1) +#define RSTCON_SWRST (0x1 << 0) + +/* EXYNOS5 */ +#define EXYNOS5_PHY_HOST_CTRL0 (0x00) + +#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) + +#define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) +#define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) +#define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) +#define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) + +#define HOST_CTRL0_FSEL_MASK (0x7 << 16) +#define HOST_CTRL0_FSEL(_x) ((_x) << 16) + +#define FSEL_CLKSEL_50M (0x7) +#define FSEL_CLKSEL_24M (0x5) +#define FSEL_CLKSEL_20M (0x4) +#define FSEL_CLKSEL_19200K (0x3) +#define FSEL_CLKSEL_12M (0x2) +#define FSEL_CLKSEL_10M (0x1) +#define FSEL_CLKSEL_9600K (0x0) + +#define HOST_CTRL0_TESTBURNIN (0x1 << 11) +#define HOST_CTRL0_RETENABLE (0x1 << 10) +#define HOST_CTRL0_COMMONON_N (0x1 << 9) +#define HOST_CTRL0_SIDDQ (0x1 << 6) +#define HOST_CTRL0_FORCESLEEP (0x1 << 5) +#define HOST_CTRL0_FORCESUSPEND (0x1 << 4) +#define HOST_CTRL0_WORDINTERFACE (0x1 << 3) +#define HOST_CTRL0_UTMISWRST (0x1 << 2) +#define HOST_CTRL0_LINKSWRST (0x1 << 1) +#define HOST_CTRL0_PHYSWRST (0x1 << 0) + +#define EXYNOS5_PHY_HOST_TUNE0 (0x04) + +#define EXYNOS5_PHY_HSIC_CTRL1 (0x10) + +#define EXYNOS5_PHY_HSIC_TUNE1 (0x14) + +#define EXYNOS5_PHY_HSIC_CTRL2 (0x20) + +#define EXYNOS5_PHY_HSIC_TUNE2 (0x24) + +#define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) +#define HSIC_CTRL_REFCLKSEL (0x2 << 23) + +#define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) +#define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) +#define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) +#define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16) +#define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) +#define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) +#define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) + +#define HSIC_CTRL_SIDDQ (0x1 << 6) +#define HSIC_CTRL_FORCESLEEP (0x1 << 5) +#define HSIC_CTRL_FORCESUSPEND (0x1 << 4) +#define HSIC_CTRL_WORDINTERFACE (0x1 << 3) +#define HSIC_CTRL_UTMISWRST (0x1 << 2) +#define HSIC_CTRL_PHYSWRST (0x1 << 0) + +#define EXYNOS5_PHY_HOST_EHCICTRL (0x30) + +#define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) +#define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) +#define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) +#define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) + +#define EXYNOS5_PHY_HOST_OHCICTRL (0x34) + +#define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) +#define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) +#define HOST_OHCICTRL_CNTSEL (0x1 << 1) +#define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) + +#define EXYNOS5_PHY_OTG_SYS (0x38) + +#define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) +#define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) +#define OTG_SYS_PHY0_SWRST (0x1 << 12) + +#define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) +#define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) +#define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) +#define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) + +#define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) +#define OTG_SYS_COMMON_ON (0x1 << 7) + +#define OTG_SYS_FSEL_MASK (0x7 << 4) +#define OTG_SYS_FSEL(_x) ((_x) << 4) + +#define OTG_SYS_FORCESLEEP (0x1 << 3) +#define OTG_SYS_OTGDISABLE (0x1 << 2) +#define OTG_SYS_SIDDQ_UOTG (0x1 << 1) +#define OTG_SYS_FORCESUSPEND (0x1 << 0) + +#define EXYNOS5_PHY_OTG_TUNE (0x40) + +#ifndef MHZ +#define MHZ (1000*1000) +#endif + +#ifndef KHZ +#define KHZ (1000) +#endif + +#define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4) +#define S3C64XX_USBPHY_ENABLE (0x1 << 16) +#define EXYNOS_USBPHY_ENABLE (0x1 << 0) +#define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0) + +enum samsung_cpu_type { + TYPE_S3C64XX, + TYPE_EXYNOS4210, + TYPE_EXYNOS5250, +}; + +/* + * struct samsung_usbphy_drvdata - driver data for various SoC variants + * @cpu_type: machine identifier + * @devphy_en_mask: device phy enable mask for PHY CONTROL register + * @hostphy_en_mask: host phy enable mask for PHY CONTROL register + * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from + * mapped address of system controller. + * @hostphy_reg_offset: offset to HOST PHY CONTROL register from + * mapped address of system controller. + * + * Here we have a separate mask for device type phy. + * Having different masks for host and device type phy helps + * in setting independent masks in case of SoCs like S5PV210, + * in which PHY0 and PHY1 enable bits belong to same register + * placed at position 0 and 1 respectively. + * Although for newer SoCs like exynos these bits belong to + * different registers altogether placed at position 0. + */ +struct samsung_usbphy_drvdata { + int cpu_type; + int devphy_en_mask; + int hostphy_en_mask; + u32 devphy_reg_offset; + u32 hostphy_reg_offset; +}; + +/* + * struct samsung_usbphy - transceiver driver state + * @phy: transceiver structure + * @plat: platform data + * @dev: The parent device supplied to the probe function + * @clk: usb phy clock + * @regs: usb phy controller registers memory base + * @pmuregs: USB device PHY_CONTROL register memory base + * @sysreg: USB2.0 PHY_CFG register memory base + * @ref_clk_freq: reference clock frequency selection + * @drv_data: driver data available for different SoCs + * @phy_type: Samsung SoCs specific phy types: #HOST + * #DEVICE + * @phy_usage: usage count for phy + * @lock: lock for phy operations + */ +struct samsung_usbphy { + struct usb_phy phy; + struct samsung_usbphy_data *plat; + struct device *dev; + struct clk *clk; + void __iomem *regs; + void __iomem *pmuregs; + void __iomem *sysreg; + int ref_clk_freq; + const struct samsung_usbphy_drvdata *drv_data; + enum samsung_usb_phy_type phy_type; + atomic_t phy_usage; + spinlock_t lock; +}; + +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy) + +int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + if (!otg->host) + otg->host = host; + + return 0; +} + +static int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy) +{ + struct device_node *usbphy_sys; + + /* Getting node for system controller interface for usb-phy */ + usbphy_sys = of_get_child_by_name(sphy->dev->of_node, "usbphy-sys"); + if (!usbphy_sys) { + dev_err(sphy->dev, "No sys-controller interface for usb-phy\n"); + return -ENODEV; + } + + sphy->pmuregs = of_iomap(usbphy_sys, 0); + + if (sphy->pmuregs == NULL) { + dev_err(sphy->dev, "Can't get usb-phy pmu control register\n"); + goto err0; + } + + sphy->sysreg = of_iomap(usbphy_sys, 1); + + /* + * Not returning error code here, since this situation is not fatal. + * Few SoCs may not have this switch available + */ + if (sphy->sysreg == NULL) + dev_warn(sphy->dev, "Can't get usb-phy sysreg cfg register\n"); + + of_node_put(usbphy_sys); + + return 0; + +err0: + of_node_put(usbphy_sys); + return -ENXIO; +} + +/* + * Set isolation here for phy. + * Here 'on = true' would mean USB PHY block is isolated, hence + * de-activated and vice-versa. + */ +static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) +{ + void __iomem *reg = NULL; + u32 reg_val; + u32 en_mask = 0; + + if (!sphy->pmuregs) { + dev_warn(sphy->dev, "Can't set pmu isolation\n"); + return; + } + + switch (sphy->drv_data->cpu_type) { + case TYPE_S3C64XX: + /* + * Do nothing: We will add here once S3C64xx goes for DT support + */ + break; + case TYPE_EXYNOS4210: + /* + * Fall through since exynos4210 and exynos5250 have similar + * register architecture: two separate registers for host and + * device phy control with enable bit at position 0. + */ + case TYPE_EXYNOS5250: + if (sphy->phy_type == USB_PHY_TYPE_DEVICE) { + reg = sphy->pmuregs + + sphy->drv_data->devphy_reg_offset; + en_mask = sphy->drv_data->devphy_en_mask; + } else if (sphy->phy_type == USB_PHY_TYPE_HOST) { + reg = sphy->pmuregs + + sphy->drv_data->hostphy_reg_offset; + en_mask = sphy->drv_data->hostphy_en_mask; + } + break; + default: + dev_err(sphy->dev, "Invalid SoC type\n"); + return; + } + + reg_val = readl(reg); + + if (on) + reg_val &= ~en_mask; + else + reg_val |= en_mask; + + writel(reg_val, reg); +} + +/* + * Configure the mode of working of usb-phy here: HOST/DEVICE. + */ +static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) +{ + u32 reg; + + if (!sphy->sysreg) { + dev_warn(sphy->dev, "Can't configure specified phy mode\n"); + return; + } + + reg = readl(sphy->sysreg); + + if (sphy->phy_type == USB_PHY_TYPE_DEVICE) + reg &= ~EXYNOS_USB20PHY_CFG_HOST_LINK; + else if (sphy->phy_type == USB_PHY_TYPE_HOST) + reg |= EXYNOS_USB20PHY_CFG_HOST_LINK; + + writel(reg, sphy->sysreg); +} + +/* + * PHYs are different for USB Device and USB Host. + * This make sure that correct PHY type is selected before + * any operation on PHY. + */ +static int samsung_usbphy_set_type(struct usb_phy *phy, + enum samsung_usb_phy_type phy_type) +{ + struct samsung_usbphy *sphy = phy_to_sphy(phy); + + sphy->phy_type = phy_type; + + return 0; +} + +/* + * Returns reference clock frequency selection value + */ +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) +{ + struct clk *ref_clk; + int refclk_freq = 0; + + /* + * In exynos5250 USB host and device PHY use + * external crystal clock XXTI + */ + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) + ref_clk = clk_get(sphy->dev, "ext_xtal"); + else + ref_clk = clk_get(sphy->dev, "xusbxti"); + if (IS_ERR(ref_clk)) { + dev_err(sphy->dev, "Failed to get reference clock\n"); + return PTR_ERR(ref_clk); + } + + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) { + /* set clock frequency for PLL */ + switch (clk_get_rate(ref_clk)) { + case 9600 * KHZ: + refclk_freq = FSEL_CLKSEL_9600K; + break; + case 10 * MHZ: + refclk_freq = FSEL_CLKSEL_10M; + break; + case 12 * MHZ: + refclk_freq = FSEL_CLKSEL_12M; + break; + case 19200 * KHZ: + refclk_freq = FSEL_CLKSEL_19200K; + break; + case 20 * MHZ: + refclk_freq = FSEL_CLKSEL_20M; + break; + case 50 * MHZ: + refclk_freq = FSEL_CLKSEL_50M; + break; + case 24 * MHZ: + default: + /* default reference clock */ + refclk_freq = FSEL_CLKSEL_24M; + break; + } + } else { + switch (clk_get_rate(ref_clk)) { + case 12 * MHZ: + refclk_freq = PHYCLK_CLKSEL_12M; + break; + case 24 * MHZ: + refclk_freq = PHYCLK_CLKSEL_24M; + break; + case 48 * MHZ: + refclk_freq = PHYCLK_CLKSEL_48M; + break; + default: + if (sphy->drv_data->cpu_type == TYPE_S3C64XX) + refclk_freq = PHYCLK_CLKSEL_48M; + else + refclk_freq = PHYCLK_CLKSEL_24M; + break; + } + } + clk_put(ref_clk); + + return refclk_freq; +} + +static bool exynos5_phyhost_is_on(void *regs) +{ + u32 reg; + + reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + + return !(reg & HOST_CTRL0_SIDDQ); +} + +static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phyclk = sphy->ref_clk_freq; + u32 phyhost; + u32 phyotg; + u32 phyhsic; + u32 ehcictrl; + u32 ohcictrl; + + /* + * phy_usage helps in keeping usage count for phy + * so that the first consumer enabling the phy is also + * the last consumer to disable it. + */ + + atomic_inc(&sphy->phy_usage); + + if (exynos5_phyhost_is_on(regs)) { + dev_info(sphy->dev, "Already power on PHY\n"); + return; + } + + /* Host configuration */ + phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + + /* phy reference clock configuration */ + phyhost &= ~HOST_CTRL0_FSEL_MASK; + phyhost |= HOST_CTRL0_FSEL(phyclk); + + /* host phy reset */ + phyhost &= ~(HOST_CTRL0_PHYSWRST | + HOST_CTRL0_PHYSWRSTALL | + HOST_CTRL0_SIDDQ | + /* Enable normal mode of operation */ + HOST_CTRL0_FORCESUSPEND | + HOST_CTRL0_FORCESLEEP); + + /* Link reset */ + phyhost |= (HOST_CTRL0_LINKSWRST | + HOST_CTRL0_UTMISWRST | + /* COMMON Block configuration during suspend */ + HOST_CTRL0_COMMONON_N); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + udelay(10); + phyhost &= ~(HOST_CTRL0_LINKSWRST | + HOST_CTRL0_UTMISWRST); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + + /* OTG configuration */ + phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); + + /* phy reference clock configuration */ + phyotg &= ~OTG_SYS_FSEL_MASK; + phyotg |= OTG_SYS_FSEL(phyclk); + + /* Enable normal mode of operation */ + phyotg &= ~(OTG_SYS_FORCESUSPEND | + OTG_SYS_SIDDQ_UOTG | + OTG_SYS_FORCESLEEP | + OTG_SYS_REFCLKSEL_MASK | + /* COMMON Block configuration during suspend */ + OTG_SYS_COMMON_ON); + + /* OTG phy & link reset */ + phyotg |= (OTG_SYS_PHY0_SWRST | + OTG_SYS_LINKSWRST_UOTG | + OTG_SYS_PHYLINK_SWRESET | + OTG_SYS_OTGDISABLE | + /* Set phy refclk */ + OTG_SYS_REFCLKSEL_CLKCORE); + + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); + udelay(10); + phyotg &= ~(OTG_SYS_PHY0_SWRST | + OTG_SYS_LINKSWRST_UOTG | + OTG_SYS_PHYLINK_SWRESET); + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); + + /* HSIC phy configuration */ + phyhsic = (HSIC_CTRL_REFCLKDIV_12 | + HSIC_CTRL_REFCLKSEL | + HSIC_CTRL_PHYSWRST); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + udelay(10); + phyhsic &= ~HSIC_CTRL_PHYSWRST; + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + + udelay(80); + + /* enable EHCI DMA burst */ + ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL); + ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN | + HOST_EHCICTRL_ENAINCR4 | + HOST_EHCICTRL_ENAINCR8 | + HOST_EHCICTRL_ENAINCR16); + writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL); + + /* set ohci_suspend_on_n */ + ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL); + ohcictrl |= HOST_OHCICTRL_SUSPLGCY; + writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL); +} + +static void samsung_usbphy_enable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phypwr; + u32 phyclk; + u32 rstcon; + + /* set clock frequency for PLL */ + phyclk = sphy->ref_clk_freq; + phypwr = readl(regs + SAMSUNG_PHYPWR); + rstcon = readl(regs + SAMSUNG_RSTCON); + + switch (sphy->drv_data->cpu_type) { + case TYPE_S3C64XX: + phyclk &= ~PHYCLK_COMMON_ON_N; + phypwr &= ~PHYPWR_NORMAL_MASK; + rstcon |= RSTCON_SWRST; + break; + case TYPE_EXYNOS4210: + phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; + rstcon |= RSTCON_SWRST; + default: + break; + } + + writel(phyclk, regs + SAMSUNG_PHYCLK); + /* Configure PHY0 for normal operation*/ + writel(phypwr, regs + SAMSUNG_PHYPWR); + /* reset all ports of PHY and Link */ + writel(rstcon, regs + SAMSUNG_RSTCON); + udelay(10); + rstcon &= ~RSTCON_SWRST; + writel(rstcon, regs + SAMSUNG_RSTCON); +} + +static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phyhost; + u32 phyotg; + u32 phyhsic; + + if (atomic_dec_return(&sphy->phy_usage) > 0) { + dev_info(sphy->dev, "still being used\n"); + return; + } + + phyhsic = (HSIC_CTRL_REFCLKDIV_12 | + HSIC_CTRL_REFCLKSEL | + HSIC_CTRL_SIDDQ | + HSIC_CTRL_FORCESLEEP | + HSIC_CTRL_FORCESUSPEND); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + + phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + phyhost |= (HOST_CTRL0_SIDDQ | + HOST_CTRL0_FORCESUSPEND | + HOST_CTRL0_FORCESLEEP | + HOST_CTRL0_PHYSWRST | + HOST_CTRL0_PHYSWRSTALL); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + + phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); + phyotg |= (OTG_SYS_FORCESUSPEND | + OTG_SYS_SIDDQ_UOTG | + OTG_SYS_FORCESLEEP); + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); +} + +static void samsung_usbphy_disable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phypwr; + + phypwr = readl(regs + SAMSUNG_PHYPWR); + + switch (sphy->drv_data->cpu_type) { + case TYPE_S3C64XX: + phypwr |= PHYPWR_NORMAL_MASK; + break; + case TYPE_EXYNOS4210: + phypwr |= PHYPWR_NORMAL_MASK_PHY0; + default: + break; + } + + /* Disable analog and otg block power */ + writel(phypwr, regs + SAMSUNG_PHYPWR); +} + +/* + * The function passed to the usb driver for phy initialization + */ +static int samsung_usbphy_init(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + struct usb_bus *host = NULL; + unsigned long flags; + int ret = 0; + + sphy = phy_to_sphy(phy); + + host = phy->otg->host; + + /* Enable the phy clock */ + ret = clk_prepare_enable(sphy->clk); + if (ret) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return ret; + } + + spin_lock_irqsave(&sphy->lock, flags); + + if (host) { + /* setting default phy-type for USB 2.0 */ + if (!strstr(dev_name(host->controller), "ehci") || + !strstr(dev_name(host->controller), "ohci")) + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); + } else { + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + } + + /* Disable phy isolation */ + if (sphy->plat && sphy->plat->pmu_isolation) + sphy->plat->pmu_isolation(false); + else + samsung_usbphy_set_isolation(sphy, false); + + /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ + samsung_usbphy_cfg_sel(sphy); + + /* Initialize usb phy registers */ + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) + samsung_exynos5_usbphy_enable(sphy); + else + samsung_usbphy_enable(sphy); + + spin_unlock_irqrestore(&sphy->lock, flags); + + /* Disable the phy clock */ + clk_disable_unprepare(sphy->clk); + + return ret; +} + +/* + * The function passed to the usb driver for phy shutdown + */ +static void samsung_usbphy_shutdown(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + struct usb_bus *host = NULL; + unsigned long flags; + + sphy = phy_to_sphy(phy); + + host = phy->otg->host; + + if (clk_prepare_enable(sphy->clk)) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return; + } + + spin_lock_irqsave(&sphy->lock, flags); + + if (host) { + /* setting default phy-type for USB 2.0 */ + if (!strstr(dev_name(host->controller), "ehci") || + !strstr(dev_name(host->controller), "ohci")) + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); + } else { + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + } + + /* De-initialize usb phy registers */ + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) + samsung_exynos5_usbphy_disable(sphy); + else + samsung_usbphy_disable(sphy); + + /* Enable phy isolation */ + if (sphy->plat && sphy->plat->pmu_isolation) + sphy->plat->pmu_isolation(true); + else + samsung_usbphy_set_isolation(sphy, true); + + spin_unlock_irqrestore(&sphy->lock, flags); + + clk_disable_unprepare(sphy->clk); +} + +static const struct of_device_id samsung_usbphy_dt_match[]; + +static inline const struct samsung_usbphy_drvdata +*samsung_usbphy_get_driver_data(struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(samsung_usbphy_dt_match, + pdev->dev.of_node); + return match->data; + } + + return (struct samsung_usbphy_drvdata *) + platform_get_device_id(pdev)->driver_data; +} + +static int samsung_usbphy_probe(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy; + struct usb_otg *otg; + struct samsung_usbphy_data *pdata = pdev->dev.platform_data; + const struct samsung_usbphy_drvdata *drv_data; + struct device *dev = &pdev->dev; + struct resource *phy_mem; + void __iomem *phy_base; + struct clk *clk; + int ret; + + phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!phy_mem) { + dev_err(dev, "%s: missing mem resource\n", __func__); + return -ENODEV; + } + + phy_base = devm_ioremap_resource(dev, phy_mem); + if (IS_ERR(phy_base)) + return PTR_ERR(phy_base); + + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); + if (!sphy) + return -ENOMEM; + + otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + drv_data = samsung_usbphy_get_driver_data(pdev); + + if (drv_data->cpu_type == TYPE_EXYNOS5250) + clk = devm_clk_get(dev, "usbhost"); + else + clk = devm_clk_get(dev, "otg"); + + if (IS_ERR(clk)) { + dev_err(dev, "Failed to get otg clock\n"); + return PTR_ERR(clk); + } + + sphy->dev = dev; + + if (dev->of_node) { + ret = samsung_usbphy_parse_dt(sphy); + if (ret < 0) + return ret; + } else { + if (!pdata) { + dev_err(dev, "no platform data specified\n"); + return -EINVAL; + } + } + + sphy->plat = pdata; + sphy->regs = phy_base; + sphy->clk = clk; + sphy->drv_data = drv_data; + sphy->phy.dev = sphy->dev; + sphy->phy.label = "samsung-usbphy"; + sphy->phy.init = samsung_usbphy_init; + sphy->phy.shutdown = samsung_usbphy_shutdown; + sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); + + sphy->phy.otg = otg; + sphy->phy.otg->phy = &sphy->phy; + sphy->phy.otg->set_host = samsung_usbphy_set_host; + + spin_lock_init(&sphy->lock); + + platform_set_drvdata(pdev, sphy); + + return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); +} + +static int samsung_usbphy_remove(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy = platform_get_drvdata(pdev); + + usb_remove_phy(&sphy->phy); + + if (sphy->pmuregs) + iounmap(sphy->pmuregs); + if (sphy->sysreg) + iounmap(sphy->sysreg); + + return 0; +} + +static const struct samsung_usbphy_drvdata usbphy_s3c64xx = { + .cpu_type = TYPE_S3C64XX, + .devphy_en_mask = S3C64XX_USBPHY_ENABLE, +}; + +static const struct samsung_usbphy_drvdata usbphy_exynos4 = { + .cpu_type = TYPE_EXYNOS4210, + .devphy_en_mask = EXYNOS_USBPHY_ENABLE, + .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, +}; + +static struct samsung_usbphy_drvdata usbphy_exynos5 = { + .cpu_type = TYPE_EXYNOS5250, + .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, + .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, +}; + +#ifdef CONFIG_OF +static const struct of_device_id samsung_usbphy_dt_match[] = { + { + .compatible = "samsung,s3c64xx-usbphy", + .data = &usbphy_s3c64xx, + }, { + .compatible = "samsung,exynos4210-usbphy", + .data = &usbphy_exynos4, + }, { + .compatible = "samsung,exynos5250-usbphy", + .data = &usbphy_exynos5 + }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); +#endif + +static struct platform_device_id samsung_usbphy_driver_ids[] = { + { + .name = "s3c64xx-usbphy", + .driver_data = (unsigned long)&usbphy_s3c64xx, + }, { + .name = "exynos4210-usbphy", + .driver_data = (unsigned long)&usbphy_exynos4, + }, { + .name = "exynos5250-usbphy", + .driver_data = (unsigned long)&usbphy_exynos5, + }, + {}, +}; + +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); + +static struct platform_driver samsung_usbphy_driver = { + .probe = samsung_usbphy_probe, + .remove = samsung_usbphy_remove, + .id_table = samsung_usbphy_driver_ids, + .driver = { + .name = "samsung-usbphy", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(samsung_usbphy_dt_match), + }, +}; + +module_platform_driver(samsung_usbphy_driver); + +MODULE_DESCRIPTION("Samsung USB phy controller"); +MODULE_AUTHOR("Praveen Paneri "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-usbphy"); diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c new file mode 100644 index 000000000000..5487d38481af --- /dev/null +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -0,0 +1,798 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Erik Gilling + * Benoit Goby + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEGRA_USB_BASE 0xC5000000 +#define TEGRA_USB_SIZE SZ_16K + +#define ULPI_VIEWPORT 0x170 + +#define USB_SUSP_CTRL 0x400 +#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) +#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) +#define USB_SUSP_CLR (1 << 5) +#define USB_PHY_CLK_VALID (1 << 7) +#define UTMIP_RESET (1 << 11) +#define UHSIC_RESET (1 << 11) +#define UTMIP_PHY_ENABLE (1 << 12) +#define ULPI_PHY_ENABLE (1 << 13) +#define USB_SUSP_SET (1 << 14) +#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) + +#define USB1_LEGACY_CTRL 0x410 +#define USB1_NO_LEGACY_MODE (1 << 0) +#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) +#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) +#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ + (1 << 1) +#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) +#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) + +#define ULPI_TIMING_CTRL_0 0x424 +#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) +#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) + +#define ULPI_TIMING_CTRL_1 0x428 +#define ULPI_DATA_TRIMMER_LOAD (1 << 0) +#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) +#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) +#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) +#define ULPI_DIR_TRIMMER_LOAD (1 << 24) +#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) + +#define UTMIP_PLL_CFG1 0x804 +#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) + +#define UTMIP_XCVR_CFG0 0x808 +#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) +#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) +#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) + +#define UTMIP_BIAS_CFG0 0x80c +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) + +#define UTMIP_HSRX_CFG0 0x810 +#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) +#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) + +#define UTMIP_HSRX_CFG1 0x814 +#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) + +#define UTMIP_TX_CFG0 0x820 +#define UTMIP_FS_PREABMLE_J (1 << 19) +#define UTMIP_HS_DISCON_DISABLE (1 << 8) + +#define UTMIP_MISC_CFG0 0x824 +#define UTMIP_DPDM_OBSERVE (1 << 26) +#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) +#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) +#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) +#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) + +#define UTMIP_MISC_CFG1 0x828 +#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) +#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) + +#define UTMIP_DEBOUNCE_CFG0 0x82c +#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) + +#define UTMIP_BAT_CHRG_CFG0 0x830 +#define UTMIP_PD_CHRG (1 << 0) + +#define UTMIP_SPARE_CFG0 0x834 +#define FUSE_SETUP_SEL (1 << 3) + +#define UTMIP_XCVR_CFG1 0x838 +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) +#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) + +#define UTMIP_BIAS_CFG1 0x83c +#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) + +static DEFINE_SPINLOCK(utmip_pad_lock); +static int utmip_pad_count; + +struct tegra_xtal_freq { + int freq; + u8 enable_delay; + u8 stable_count; + u8 active_delay; + u8 xtal_freq_count; + u16 debounce; +}; + +static const struct tegra_xtal_freq tegra_freq_table[] = { + { + .freq = 12000000, + .enable_delay = 0x02, + .stable_count = 0x2F, + .active_delay = 0x04, + .xtal_freq_count = 0x76, + .debounce = 0x7530, + }, + { + .freq = 13000000, + .enable_delay = 0x02, + .stable_count = 0x33, + .active_delay = 0x05, + .xtal_freq_count = 0x7F, + .debounce = 0x7EF4, + }, + { + .freq = 19200000, + .enable_delay = 0x03, + .stable_count = 0x4B, + .active_delay = 0x06, + .xtal_freq_count = 0xBB, + .debounce = 0xBB80, + }, + { + .freq = 26000000, + .enable_delay = 0x04, + .stable_count = 0x66, + .active_delay = 0x09, + .xtal_freq_count = 0xFE, + .debounce = 0xFDE8, + }, +}; + +static struct tegra_utmip_config utmip_default[] = { + [0] = { + .hssync_start_delay = 9, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 9, + .xcvr_lsfslew = 1, + .xcvr_lsrslew = 1, + }, + [2] = { + .hssync_start_delay = 9, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 9, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, +}; + +static int utmip_pad_open(struct tegra_usb_phy *phy) +{ + phy->pad_clk = clk_get_sys("utmip-pad", NULL); + if (IS_ERR(phy->pad_clk)) { + pr_err("%s: can't get utmip pad clock\n", __func__); + return PTR_ERR(phy->pad_clk); + } + + if (phy->is_legacy_phy) { + phy->pad_regs = phy->regs; + } else { + phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); + if (!phy->pad_regs) { + pr_err("%s: can't remap usb registers\n", __func__); + clk_put(phy->pad_clk); + return -ENOMEM; + } + } + return 0; +} + +static void utmip_pad_close(struct tegra_usb_phy *phy) +{ + if (!phy->is_legacy_phy) + iounmap(phy->pad_regs); + clk_put(phy->pad_clk); +} + +static void utmip_pad_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *base = phy->pad_regs; + + clk_prepare_enable(phy->pad_clk); + + spin_lock_irqsave(&utmip_pad_lock, flags); + + if (utmip_pad_count++ == 0) { + val = readl(base + UTMIP_BIAS_CFG0); + val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); + writel(val, base + UTMIP_BIAS_CFG0); + } + + spin_unlock_irqrestore(&utmip_pad_lock, flags); + + clk_disable_unprepare(phy->pad_clk); +} + +static int utmip_pad_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val, flags; + void __iomem *base = phy->pad_regs; + + if (!utmip_pad_count) { + pr_err("%s: utmip pad already powered off\n", __func__); + return -EINVAL; + } + + clk_prepare_enable(phy->pad_clk); + + spin_lock_irqsave(&utmip_pad_lock, flags); + + if (--utmip_pad_count == 0) { + val = readl(base + UTMIP_BIAS_CFG0); + val |= UTMIP_OTGPD | UTMIP_BIASPD; + writel(val, base + UTMIP_BIAS_CFG0); + } + + spin_unlock_irqrestore(&utmip_pad_lock, flags); + + clk_disable_unprepare(phy->pad_clk); + + return 0; +} + +static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result) +{ + unsigned long timeout = 2000; + do { + if ((readl(reg) & mask) == result) + return 0; + udelay(1); + timeout--; + } while (timeout); + return -1; +} + +static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + if (phy->is_legacy_phy) { + val = readl(base + USB_SUSP_CTRL); + val |= USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + + udelay(10); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + } else + tegra_ehci_set_phcd(&phy->u_phy, true); + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); +} + +static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + if (phy->is_legacy_phy) { + val = readl(base + USB_SUSP_CTRL); + val |= USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + + udelay(10); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + } else + tegra_ehci_set_phcd(&phy->u_phy, false); + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID)) + pr_err("%s: timeout waiting for phy to stabilize\n", __func__); +} + +static int utmi_phy_power_on(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_utmip_config *config = phy->config; + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + if (phy->is_legacy_phy) { + val = readl(base + USB1_LEGACY_CTRL); + val |= USB1_NO_LEGACY_MODE; + writel(val, base + USB1_LEGACY_CTRL); + } + + val = readl(base + UTMIP_TX_CFG0); + val &= ~UTMIP_FS_PREABMLE_J; + writel(val, base + UTMIP_TX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG0); + val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); + val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); + val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); + writel(val, base + UTMIP_HSRX_CFG0); + + val = readl(base + UTMIP_HSRX_CFG1); + val &= ~UTMIP_HS_SYNC_START_DLY(~0); + val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); + writel(val, base + UTMIP_HSRX_CFG1); + + val = readl(base + UTMIP_DEBOUNCE_CFG0); + val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); + val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); + writel(val, base + UTMIP_DEBOUNCE_CFG0); + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; + writel(val, base + UTMIP_MISC_CFG0); + + val = readl(base + UTMIP_MISC_CFG1); + val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0)); + val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) | + UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count); + writel(val, base + UTMIP_MISC_CFG1); + + val = readl(base + UTMIP_PLL_CFG1); + val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); + val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | + UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); + writel(val, base + UTMIP_PLL_CFG1); + + if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { + val = readl(base + USB_SUSP_CTRL); + val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); + writel(val, base + USB_SUSP_CTRL); + } + + utmip_pad_power_on(phy); + + val = readl(base + UTMIP_XCVR_CFG0); + val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | + UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) | + UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) | + UTMIP_XCVR_HSSLEW_MSB(~0)); + val |= UTMIP_XCVR_SETUP(config->xcvr_setup); + val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); + val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); + writel(val, base + UTMIP_XCVR_CFG0); + + val = readl(base + UTMIP_XCVR_CFG1); + val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); + val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); + writel(val, base + UTMIP_XCVR_CFG1); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val &= ~UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + val = readl(base + UTMIP_BIAS_CFG1); + val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); + val |= UTMIP_BIAS_PDTRK_COUNT(0x5); + writel(val, base + UTMIP_BIAS_CFG1); + + if (phy->is_legacy_phy) { + val = readl(base + UTMIP_SPARE_CFG0); + if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) + val &= ~FUSE_SETUP_SEL; + else + val |= FUSE_SETUP_SEL; + writel(val, base + UTMIP_SPARE_CFG0); + } else { + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + } + + val = readl(base + USB_SUSP_CTRL); + val &= ~UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + if (phy->is_legacy_phy) { + val = readl(base + USB1_LEGACY_CTRL); + val &= ~USB1_VBUS_SENSE_CTL_MASK; + val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; + writel(val, base + USB1_LEGACY_CTRL); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_SET; + writel(val, base + USB_SUSP_CTRL); + } + + utmi_phy_clk_enable(phy); + + if (!phy->is_legacy_phy) + tegra_ehci_set_pts(&phy->u_phy, 0); + + return 0; +} + +static int utmi_phy_power_off(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + utmi_phy_clk_disable(phy); + + if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); + val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); + writel(val, base + USB_SUSP_CTRL); + } + + val = readl(base + USB_SUSP_CTRL); + val |= UTMIP_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + UTMIP_BAT_CHRG_CFG0); + val |= UTMIP_PD_CHRG; + writel(val, base + UTMIP_BAT_CHRG_CFG0); + + val = readl(base + UTMIP_XCVR_CFG0); + val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | + UTMIP_FORCE_PDZI_POWERDOWN; + writel(val, base + UTMIP_XCVR_CFG0); + + val = readl(base + UTMIP_XCVR_CFG1); + val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN; + writel(val, base + UTMIP_XCVR_CFG1); + + return utmip_pad_power_off(phy); +} + +static void utmi_phy_preresume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_TX_CFG0); + val |= UTMIP_HS_DISCON_DISABLE; + writel(val, base + UTMIP_TX_CFG0); +} + +static void utmi_phy_postresume(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_TX_CFG0); + val &= ~UTMIP_HS_DISCON_DISABLE; + writel(val, base + UTMIP_TX_CFG0); +} + +static void utmi_phy_restore_start(struct tegra_usb_phy *phy, + enum tegra_usb_phy_port_speed port_speed) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); + if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) + val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; + else + val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; + writel(val, base + UTMIP_MISC_CFG0); + udelay(1); + + val = readl(base + UTMIP_MISC_CFG0); + val |= UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + +static void utmi_phy_restore_end(struct tegra_usb_phy *phy) +{ + unsigned long val; + void __iomem *base = phy->regs; + + val = readl(base + UTMIP_MISC_CFG0); + val &= ~UTMIP_DPDM_OBSERVE; + writel(val, base + UTMIP_MISC_CFG0); + udelay(10); +} + +static int ulpi_phy_power_on(struct tegra_usb_phy *phy) +{ + int ret; + unsigned long val; + void __iomem *base = phy->regs; + struct tegra_ulpi_config *config = phy->config; + + gpio_direction_output(config->reset_gpio, 0); + msleep(5); + gpio_direction_output(config->reset_gpio, 1); + + clk_prepare_enable(phy->clk); + msleep(1); + + val = readl(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel(val, base + USB_SUSP_CTRL); + + val = readl(base + ULPI_TIMING_CTRL_0); + val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; + writel(val, base + ULPI_TIMING_CTRL_0); + + val = readl(base + USB_SUSP_CTRL); + val |= ULPI_PHY_ENABLE; + writel(val, base + USB_SUSP_CTRL); + + val = 0; + writel(val, base + ULPI_TIMING_CTRL_1); + + val |= ULPI_DATA_TRIMMER_SEL(4); + val |= ULPI_STPDIRNXT_TRIMMER_SEL(4); + val |= ULPI_DIR_TRIMMER_SEL(4); + writel(val, base + ULPI_TIMING_CTRL_1); + udelay(10); + + val |= ULPI_DATA_TRIMMER_LOAD; + val |= ULPI_STPDIRNXT_TRIMMER_LOAD; + val |= ULPI_DIR_TRIMMER_LOAD; + writel(val, base + ULPI_TIMING_CTRL_1); + + /* Fix VbusInvalid due to floating VBUS */ + ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08); + if (ret) { + pr_err("%s: ulpi write failed\n", __func__); + return ret; + } + + ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B); + if (ret) { + pr_err("%s: ulpi write failed\n", __func__); + return ret; + } + + val = readl(base + USB_SUSP_CTRL); + val |= USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + udelay(100); + + val = readl(base + USB_SUSP_CTRL); + val &= ~USB_SUSP_CLR; + writel(val, base + USB_SUSP_CTRL); + + return 0; +} + +static int ulpi_phy_power_off(struct tegra_usb_phy *phy) +{ + struct tegra_ulpi_config *config = phy->config; + + clk_disable(phy->clk); + return gpio_direction_output(config->reset_gpio, 0); +} + +static int tegra_phy_init(struct usb_phy *x) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + struct tegra_ulpi_config *ulpi_config; + int err; + + if (phy->is_ulpi_phy) { + ulpi_config = phy->config; + phy->clk = clk_get_sys(NULL, ulpi_config->clk); + if (IS_ERR(phy->clk)) { + pr_err("%s: can't get ulpi clock\n", __func__); + err = -ENXIO; + goto err1; + } + if (!gpio_is_valid(ulpi_config->reset_gpio)) + ulpi_config->reset_gpio = + of_get_named_gpio(phy->dev->of_node, + "nvidia,phy-reset-gpio", 0); + if (!gpio_is_valid(ulpi_config->reset_gpio)) { + pr_err("%s: invalid reset gpio: %d\n", __func__, + ulpi_config->reset_gpio); + err = -EINVAL; + goto err1; + } + gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); + gpio_direction_output(ulpi_config->reset_gpio, 0); + phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); + phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT; + } else { + err = utmip_pad_open(phy); + if (err < 0) + goto err1; + } + return 0; +err1: + clk_disable_unprepare(phy->pll_u); + clk_put(phy->pll_u); + return err; +} + +static void tegra_usb_phy_close(struct usb_phy *x) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + + if (phy->is_ulpi_phy) + clk_put(phy->clk); + else + utmip_pad_close(phy); + clk_disable_unprepare(phy->pll_u); + clk_put(phy->pll_u); + kfree(phy); +} + +static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) +{ + if (phy->is_ulpi_phy) + return ulpi_phy_power_on(phy); + else + return utmi_phy_power_on(phy); +} + +static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) +{ + if (phy->is_ulpi_phy) + return ulpi_phy_power_off(phy); + else + return utmi_phy_power_off(phy); +} + +static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + if (suspend) + return tegra_usb_phy_power_off(phy); + else + return tegra_usb_phy_power_on(phy); +} + +struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, + void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode) +{ + struct tegra_usb_phy *phy; + unsigned long parent_rate; + int i; + int err; + struct device_node *np = dev->of_node; + + phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); + if (!phy) + return ERR_PTR(-ENOMEM); + + phy->instance = instance; + phy->regs = regs; + phy->config = config; + phy->mode = phy_mode; + phy->dev = dev; + phy->is_legacy_phy = + of_property_read_bool(np, "nvidia,has-legacy-mode"); + err = of_property_match_string(np, "phy_type", "ulpi"); + if (err < 0) + phy->is_ulpi_phy = false; + else + phy->is_ulpi_phy = true; + + if (!phy->config) { + if (phy->is_ulpi_phy) { + pr_err("%s: ulpi phy configuration missing", __func__); + err = -EINVAL; + goto err0; + } else { + phy->config = &utmip_default[instance]; + } + } + + phy->pll_u = clk_get_sys(NULL, "pll_u"); + if (IS_ERR(phy->pll_u)) { + pr_err("Can't get pll_u clock\n"); + err = PTR_ERR(phy->pll_u); + goto err0; + } + clk_prepare_enable(phy->pll_u); + + parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); + for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { + if (tegra_freq_table[i].freq == parent_rate) { + phy->freq = &tegra_freq_table[i]; + break; + } + } + if (!phy->freq) { + pr_err("invalid pll_u parent rate %ld\n", parent_rate); + err = -EINVAL; + goto err1; + } + + phy->u_phy.init = tegra_phy_init; + phy->u_phy.shutdown = tegra_usb_phy_close; + phy->u_phy.set_suspend = tegra_usb_phy_suspend; + + return phy; + +err1: + clk_disable_unprepare(phy->pll_u); + clk_put(phy->pll_u); +err0: + kfree(phy); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(tegra_usb_phy_open); + +void tegra_usb_phy_preresume(struct usb_phy *x) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + + if (!phy->is_ulpi_phy) + utmi_phy_preresume(phy); +} +EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); + +void tegra_usb_phy_postresume(struct usb_phy *x) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + + if (!phy->is_ulpi_phy) + utmi_phy_postresume(phy); +} +EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); + +void tegra_ehci_phy_restore_start(struct usb_phy *x, + enum tegra_usb_phy_port_speed port_speed) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + + if (!phy->is_ulpi_phy) + utmi_phy_restore_start(phy, port_speed); +} +EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); + +void tegra_ehci_phy_restore_end(struct usb_phy *x) +{ + struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); + + if (!phy->is_ulpi_phy) + utmi_phy_restore_end(phy); +} +EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); + diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c new file mode 100644 index 000000000000..a994715a3101 --- /dev/null +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -0,0 +1,728 @@ +/* + * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller + * + * Copyright (C) 2004-2007 Texas Instruments + * Copyright (C) 2008 Nokia Corporation + * Contact: Felipe Balbi + * + * 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. + * + * Current status: + * - HS USB ULPI mode works. + * - 3-pin mode support may be added in future. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register defines */ + +#define MCPC_CTRL 0x30 +#define MCPC_CTRL_RTSOL (1 << 7) +#define MCPC_CTRL_EXTSWR (1 << 6) +#define MCPC_CTRL_EXTSWC (1 << 5) +#define MCPC_CTRL_VOICESW (1 << 4) +#define MCPC_CTRL_OUT64K (1 << 3) +#define MCPC_CTRL_RTSCTSSW (1 << 2) +#define MCPC_CTRL_HS_UART (1 << 0) + +#define MCPC_IO_CTRL 0x33 +#define MCPC_IO_CTRL_MICBIASEN (1 << 5) +#define MCPC_IO_CTRL_CTS_NPU (1 << 4) +#define MCPC_IO_CTRL_RXD_PU (1 << 3) +#define MCPC_IO_CTRL_TXDTYP (1 << 2) +#define MCPC_IO_CTRL_CTSTYP (1 << 1) +#define MCPC_IO_CTRL_RTSTYP (1 << 0) + +#define MCPC_CTRL2 0x36 +#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) + +#define OTHER_FUNC_CTRL 0x80 +#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) +#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) + +#define OTHER_IFC_CTRL 0x83 +#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) +#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) +#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) +#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) +#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) +#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) + +#define OTHER_INT_EN_RISE 0x86 +#define OTHER_INT_EN_FALL 0x89 +#define OTHER_INT_STS 0x8C +#define OTHER_INT_LATCH 0x8D +#define OTHER_INT_VB_SESS_VLD (1 << 7) +#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ +#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ +#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ +#define OTHER_INT_MANU (1 << 1) +#define OTHER_INT_ABNORMAL_STRESS (1 << 0) + +#define ID_STATUS 0x96 +#define ID_RES_FLOAT (1 << 4) +#define ID_RES_440K (1 << 3) +#define ID_RES_200K (1 << 2) +#define ID_RES_102K (1 << 1) +#define ID_RES_GND (1 << 0) + +#define POWER_CTRL 0xAC +#define POWER_CTRL_OTG_ENAB (1 << 5) + +#define OTHER_IFC_CTRL2 0xAF +#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) +#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) +#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) +#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) + +#define REG_CTRL_EN 0xB2 +#define REG_CTRL_ERROR 0xB5 +#define ULPI_I2C_CONFLICT_INTEN (1 << 0) + +#define OTHER_FUNC_CTRL2 0xB8 +#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) + +/* following registers do not have separate _clr and _set registers */ +#define VBUS_DEBOUNCE 0xC0 +#define ID_DEBOUNCE 0xC1 +#define VBAT_TIMER 0xD3 +#define PHY_PWR_CTRL 0xFD +#define PHY_PWR_PHYPWD (1 << 0) +#define PHY_CLK_CTRL 0xFE +#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) +#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) +#define REQ_PHY_DPLL_CLK (1 << 0) +#define PHY_CLK_CTRL_STS 0xFF +#define PHY_DPLL_CLK (1 << 0) + +/* In module TWL_MODULE_PM_MASTER */ +#define STS_HW_CONDITIONS 0x0F + +/* In module TWL_MODULE_PM_RECEIVER */ +#define VUSB_DEDICATED1 0x7D +#define VUSB_DEDICATED2 0x7E +#define VUSB1V5_DEV_GRP 0x71 +#define VUSB1V5_TYPE 0x72 +#define VUSB1V5_REMAP 0x73 +#define VUSB1V8_DEV_GRP 0x74 +#define VUSB1V8_TYPE 0x75 +#define VUSB1V8_REMAP 0x76 +#define VUSB3V1_DEV_GRP 0x77 +#define VUSB3V1_TYPE 0x78 +#define VUSB3V1_REMAP 0x79 + +/* In module TWL4030_MODULE_INTBR */ +#define PMBR1 0x0D +#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) + +struct twl4030_usb { + struct usb_phy phy; + struct device *dev; + + /* TWL4030 internal USB regulator supplies */ + struct regulator *usb1v5; + struct regulator *usb1v8; + struct regulator *usb3v1; + + /* for vbus reporting with irqs disabled */ + spinlock_t lock; + + /* pin configuration */ + enum twl4030_usb_mode usb_mode; + + int irq; + enum omap_musb_vbus_id_status linkstat; + bool vbus_supplied; + u8 asleep; + bool irq_enabled; +}; + +/* internal define on top of container_of */ +#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) + +/*-------------------------------------------------------------------------*/ + +static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, + u8 module, u8 data, u8 address) +{ + u8 check; + + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && + (check == data)) + return 0; + dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", + 1, module, address, check, data); + + /* Failed once: Try again */ + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && + (check == data)) + return 0; + dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", + 2, module, address, check, data); + + /* Failed again: Return error */ + return -EBUSY; +} + +#define twl4030_usb_write_verify(twl, address, data) \ + twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) + +static inline int twl4030_usb_write(struct twl4030_usb *twl, + u8 address, u8 data) +{ + int ret = 0; + + ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); + if (ret < 0) + dev_dbg(twl->dev, + "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); + return ret; +} + +static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) +{ + u8 data; + int ret = 0; + + ret = twl_i2c_read_u8(module, &data, address); + if (ret >= 0) + ret = data; + else + dev_dbg(twl->dev, + "TWL4030:readb[0x%x,0x%x] Error %d\n", + module, address, ret); + + return ret; +} + +static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) +{ + return twl4030_readb(twl, TWL_MODULE_USB, address); +} + +/*-------------------------------------------------------------------------*/ + +static inline int +twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) +{ + return twl4030_usb_write(twl, ULPI_SET(reg), bits); +} + +static inline int +twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) +{ + return twl4030_usb_write(twl, ULPI_CLR(reg), bits); +} + +/*-------------------------------------------------------------------------*/ + +static enum omap_musb_vbus_id_status + twl4030_usb_linkstat(struct twl4030_usb *twl) +{ + int status; + enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; + + twl->vbus_supplied = false; + + /* + * For ID/VBUS sensing, see manual section 15.4.8 ... + * except when using only battery backup power, two + * comparators produce VBUS_PRES and ID_PRES signals, + * which don't match docs elsewhere. But ... BIT(7) + * and BIT(2) of STS_HW_CONDITIONS, respectively, do + * seem to match up. If either is true the USB_PRES + * signal is active, the OTG module is activated, and + * its interrupt may be raised (may wake the system). + */ + status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); + if (status < 0) + dev_err(twl->dev, "USB link status err %d\n", status); + else if (status & (BIT(7) | BIT(2))) { + if (status & (BIT(7))) + twl->vbus_supplied = true; + + if (status & BIT(2)) + linkstat = OMAP_MUSB_ID_GROUND; + else + linkstat = OMAP_MUSB_VBUS_VALID; + } else { + if (twl->linkstat != OMAP_MUSB_UNKNOWN) + linkstat = OMAP_MUSB_VBUS_OFF; + } + + dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", + status, status, linkstat); + + /* REVISIT this assumes host and peripheral controllers + * are registered, and that both are active... + */ + + spin_lock_irq(&twl->lock); + twl->linkstat = linkstat; + spin_unlock_irq(&twl->lock); + + return linkstat; +} + +static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) +{ + twl->usb_mode = mode; + + switch (mode) { + case T2_USB_MODE_ULPI: + twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, + ULPI_IFC_CTRL_CARKITMODE); + twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); + twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, + ULPI_FUNC_CTRL_XCVRSEL_MASK | + ULPI_FUNC_CTRL_OPMODE_MASK); + break; + case -1: + /* FIXME: power on defaults */ + break; + default: + dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", + mode); + break; + }; +} + +static void twl4030_i2c_access(struct twl4030_usb *twl, int on) +{ + unsigned long timeout; + int val = twl4030_usb_read(twl, PHY_CLK_CTRL); + + if (val >= 0) { + if (on) { + /* enable DPLL to access PHY registers over I2C */ + val |= REQ_PHY_DPLL_CLK; + WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, + (u8)val) < 0); + + timeout = jiffies + HZ; + while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & + PHY_DPLL_CLK) + && time_before(jiffies, timeout)) + udelay(10); + if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & + PHY_DPLL_CLK)) + dev_err(twl->dev, "Timeout setting T2 HSUSB " + "PHY DPLL clock\n"); + } else { + /* let ULPI control the DPLL clock */ + val &= ~REQ_PHY_DPLL_CLK; + WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, + (u8)val) < 0); + } + } +} + +static void __twl4030_phy_power(struct twl4030_usb *twl, int on) +{ + u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); + + if (on) + pwr &= ~PHY_PWR_PHYPWD; + else + pwr |= PHY_PWR_PHYPWD; + + WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); +} + +static void twl4030_phy_power(struct twl4030_usb *twl, int on) +{ + if (on) { + regulator_enable(twl->usb3v1); + regulator_enable(twl->usb1v8); + /* + * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP + * in twl4030) resets the VUSB_DEDICATED2 register. This reset + * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to + * SLEEP. We work around this by clearing the bit after usv3v1 + * is re-activated. This ensures that VUSB3V1 is really active. + */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); + regulator_enable(twl->usb1v5); + __twl4030_phy_power(twl, 1); + twl4030_usb_write(twl, PHY_CLK_CTRL, + twl4030_usb_read(twl, PHY_CLK_CTRL) | + (PHY_CLK_CTRL_CLOCKGATING_EN | + PHY_CLK_CTRL_CLK32K_EN)); + } else { + __twl4030_phy_power(twl, 0); + regulator_disable(twl->usb1v5); + regulator_disable(twl->usb1v8); + regulator_disable(twl->usb3v1); + } +} + +static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) +{ + if (twl->asleep) + return; + + twl4030_phy_power(twl, 0); + twl->asleep = 1; + dev_dbg(twl->dev, "%s\n", __func__); +} + +static void __twl4030_phy_resume(struct twl4030_usb *twl) +{ + twl4030_phy_power(twl, 1); + twl4030_i2c_access(twl, 1); + twl4030_usb_set_mode(twl, twl->usb_mode); + if (twl->usb_mode == T2_USB_MODE_ULPI) + twl4030_i2c_access(twl, 0); +} + +static void twl4030_phy_resume(struct twl4030_usb *twl) +{ + if (!twl->asleep) + return; + __twl4030_phy_resume(twl); + twl->asleep = 0; + dev_dbg(twl->dev, "%s\n", __func__); +} + +static int twl4030_usb_ldo_init(struct twl4030_usb *twl) +{ + /* Enable writing to power configuration registers */ + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, + TWL4030_PM_MASTER_PROTECT_KEY); + + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, + TWL4030_PM_MASTER_PROTECT_KEY); + + /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ + /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ + + /* input to VUSB3V1 LDO is from VBAT, not VBUS */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); + + /* Initialize 3.1V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); + + twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); + if (IS_ERR(twl->usb3v1)) + return -ENODEV; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); + + /* Initialize 1.5V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); + + twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); + if (IS_ERR(twl->usb1v5)) + goto fail1; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); + + /* Initialize 1.8V regulator */ + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); + + twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); + if (IS_ERR(twl->usb1v8)) + goto fail2; + + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); + + /* disable access to power configuration registers */ + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, + TWL4030_PM_MASTER_PROTECT_KEY); + + return 0; + +fail2: + regulator_put(twl->usb1v5); + twl->usb1v5 = NULL; +fail1: + regulator_put(twl->usb3v1); + twl->usb3v1 = NULL; + return -ENODEV; +} + +static ssize_t twl4030_usb_vbus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct twl4030_usb *twl = dev_get_drvdata(dev); + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&twl->lock, flags); + ret = sprintf(buf, "%s\n", + twl->vbus_supplied ? "on" : "off"); + spin_unlock_irqrestore(&twl->lock, flags); + + return ret; +} +static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); + +static irqreturn_t twl4030_usb_irq(int irq, void *_twl) +{ + struct twl4030_usb *twl = _twl; + enum omap_musb_vbus_id_status status; + + status = twl4030_usb_linkstat(twl); + if (status > 0) { + /* FIXME add a set_power() method so that B-devices can + * configure the charger appropriately. It's not always + * correct to consume VBUS power, and how much current to + * consume is a function of the USB configuration chosen + * by the host. + * + * REVISIT usb_gadget_vbus_connect(...) as needed, ditto + * its disconnect() sibling, when changing to/from the + * USB_LINK_VBUS state. musb_hdrc won't care until it + * starts to handle softconnect right. + */ + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) + twl4030_phy_suspend(twl, 0); + else + twl4030_phy_resume(twl); + + omap_musb_mailbox(twl->linkstat); + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); + + return IRQ_HANDLED; +} + +static void twl4030_usb_phy_init(struct twl4030_usb *twl) +{ + enum omap_musb_vbus_id_status status; + + status = twl4030_usb_linkstat(twl); + if (status > 0) { + if (status == OMAP_MUSB_VBUS_OFF || + status == OMAP_MUSB_ID_FLOAT) { + __twl4030_phy_power(twl, 0); + twl->asleep = 1; + } else { + __twl4030_phy_resume(twl); + twl->asleep = 0; + } + + omap_musb_mailbox(twl->linkstat); + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); +} + +static int twl4030_set_suspend(struct usb_phy *x, int suspend) +{ + struct twl4030_usb *twl = phy_to_twl(x); + + if (suspend) + twl4030_phy_suspend(twl, 1); + else + twl4030_phy_resume(twl); + + return 0; +} + +static int twl4030_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) +{ + if (!otg) + return -ENODEV; + + otg->gadget = gadget; + if (!gadget) + otg->phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + otg->host = host; + if (!host) + otg->phy->state = OTG_STATE_UNDEFINED; + + return 0; +} + +static int twl4030_usb_probe(struct platform_device *pdev) +{ + struct twl4030_usb_data *pdata = pdev->dev.platform_data; + struct twl4030_usb *twl; + int status, err; + struct usb_otg *otg; + struct device_node *np = pdev->dev.of_node; + + twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); + if (!twl) + return -ENOMEM; + + if (np) + of_property_read_u32(np, "usb_mode", + (enum twl4030_usb_mode *)&twl->usb_mode); + else if (pdata) + twl->usb_mode = pdata->usb_mode; + else { + dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); + return -EINVAL; + } + + otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); + if (!otg) + return -ENOMEM; + + twl->dev = &pdev->dev; + twl->irq = platform_get_irq(pdev, 0); + twl->vbus_supplied = false; + twl->asleep = 1; + twl->linkstat = OMAP_MUSB_UNKNOWN; + + twl->phy.dev = twl->dev; + twl->phy.label = "twl4030"; + twl->phy.otg = otg; + twl->phy.type = USB_PHY_TYPE_USB2; + twl->phy.set_suspend = twl4030_set_suspend; + + otg->phy = &twl->phy; + otg->set_host = twl4030_set_host; + otg->set_peripheral = twl4030_set_peripheral; + + /* init spinlock for workqueue */ + spin_lock_init(&twl->lock); + + err = twl4030_usb_ldo_init(twl); + if (err) { + dev_err(&pdev->dev, "ldo init failed\n"); + return err; + } + usb_add_phy_dev(&twl->phy); + + platform_set_drvdata(pdev, twl); + if (device_create_file(&pdev->dev, &dev_attr_vbus)) + dev_warn(&pdev->dev, "could not create sysfs file\n"); + + /* Our job is to use irqs and status from the power module + * to keep the transceiver disabled when nothing's connected. + * + * FIXME we actually shouldn't start enabling it until the + * USB controller drivers have said they're ready, by calling + * set_host() and/or set_peripheral() ... OTG_capable boards + * need both handles, otherwise just one suffices. + */ + twl->irq_enabled = true; + status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | + IRQF_ONESHOT, "twl4030_usb", twl); + if (status < 0) { + dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq, status); + return status; + } + + /* Power down phy or make it work according to + * current link state. + */ + twl4030_usb_phy_init(twl); + + dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); + return 0; +} + +static int __exit twl4030_usb_remove(struct platform_device *pdev) +{ + struct twl4030_usb *twl = platform_get_drvdata(pdev); + int val; + + free_irq(twl->irq, twl); + device_remove_file(twl->dev, &dev_attr_vbus); + + /* set transceiver mode to power on defaults */ + twl4030_usb_set_mode(twl, -1); + + /* autogate 60MHz ULPI clock, + * clear dpll clock request for i2c access, + * disable 32KHz + */ + val = twl4030_usb_read(twl, PHY_CLK_CTRL); + if (val >= 0) { + val |= PHY_CLK_CTRL_CLOCKGATING_EN; + val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); + twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); + } + + /* disable complete OTG block */ + twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); + + if (!twl->asleep) + twl4030_phy_power(twl, 0); + regulator_put(twl->usb1v5); + regulator_put(twl->usb1v8); + regulator_put(twl->usb3v1); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id twl4030_usb_id_table[] = { + { .compatible = "ti,twl4030-usb" }, + {} +}; +MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); +#endif + +static struct platform_driver twl4030_usb_driver = { + .probe = twl4030_usb_probe, + .remove = __exit_p(twl4030_usb_remove), + .driver = { + .name = "twl4030_usb", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl4030_usb_id_table), + }, +}; + +static int __init twl4030_usb_init(void) +{ + return platform_driver_register(&twl4030_usb_driver); +} +subsys_initcall(twl4030_usb_init); + +static void __exit twl4030_usb_exit(void) +{ + platform_driver_unregister(&twl4030_usb_driver); +} +module_exit(twl4030_usb_exit); + +MODULE_ALIAS("platform:twl4030_usb"); +MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); +MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c new file mode 100644 index 000000000000..8cd6cf49bdbd --- /dev/null +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -0,0 +1,446 @@ +/* + * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.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. + * + * Author: Hema HK + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 + +/* usb register definitions */ +#define USB_VENDOR_ID_LSB 0x00 +#define USB_VENDOR_ID_MSB 0x01 +#define USB_PRODUCT_ID_LSB 0x02 +#define USB_PRODUCT_ID_MSB 0x03 +#define USB_VBUS_CTRL_SET 0x04 +#define USB_VBUS_CTRL_CLR 0x05 +#define USB_ID_CTRL_SET 0x06 +#define USB_ID_CTRL_CLR 0x07 +#define USB_VBUS_INT_SRC 0x08 +#define USB_VBUS_INT_LATCH_SET 0x09 +#define USB_VBUS_INT_LATCH_CLR 0x0A +#define USB_VBUS_INT_EN_LO_SET 0x0B +#define USB_VBUS_INT_EN_LO_CLR 0x0C +#define USB_VBUS_INT_EN_HI_SET 0x0D +#define USB_VBUS_INT_EN_HI_CLR 0x0E +#define USB_ID_INT_SRC 0x0F +#define USB_ID_INT_LATCH_SET 0x10 +#define USB_ID_INT_LATCH_CLR 0x11 + +#define USB_ID_INT_EN_LO_SET 0x12 +#define USB_ID_INT_EN_LO_CLR 0x13 +#define USB_ID_INT_EN_HI_SET 0x14 +#define USB_ID_INT_EN_HI_CLR 0x15 +#define USB_OTG_ADP_CTRL 0x16 +#define USB_OTG_ADP_HIGH 0x17 +#define USB_OTG_ADP_LOW 0x18 +#define USB_OTG_ADP_RISE 0x19 +#define USB_OTG_REVISION 0x1A + +/* to be moved to LDO */ +#define TWL6030_MISC2 0xE5 +#define TWL6030_CFG_LDO_PD2 0xF5 +#define TWL6030_BACKUP_REG 0xFA + +#define STS_HW_CONDITIONS 0x21 + +/* In module TWL6030_MODULE_PM_MASTER */ +#define STS_HW_CONDITIONS 0x21 +#define STS_USB_ID BIT(2) + +/* In module TWL6030_MODULE_PM_RECEIVER */ +#define VUSB_CFG_TRANS 0x71 +#define VUSB_CFG_STATE 0x72 +#define VUSB_CFG_VOLTAGE 0x73 + +/* in module TWL6030_MODULE_MAIN_CHARGE */ + +#define CHARGERUSB_CTRL1 0x8 + +#define CONTROLLER_STAT1 0x03 +#define VBUS_DET BIT(2) + +struct twl6030_usb { + struct phy_companion comparator; + struct device *dev; + + /* for vbus reporting with irqs disabled */ + spinlock_t lock; + + struct regulator *usb3v3; + + /* used to set vbus, in atomic path */ + struct work_struct set_vbus_work; + + int irq1; + int irq2; + enum omap_musb_vbus_id_status linkstat; + u8 asleep; + bool irq_enabled; + bool vbus_enable; + const char *regulator; +}; + +#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator) + +/*-------------------------------------------------------------------------*/ + +static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module, + u8 data, u8 address) +{ + int ret = 0; + + ret = twl_i2c_write_u8(module, data, address); + if (ret < 0) + dev_err(twl->dev, + "Write[0x%x] Error %d\n", address, ret); + return ret; +} + +static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address) +{ + u8 data, ret = 0; + + ret = twl_i2c_read_u8(module, &data, address); + if (ret >= 0) + ret = data; + else + dev_err(twl->dev, + "readb[0x%x,0x%x] Error %d\n", + module, address, ret); + return ret; +} + +static int twl6030_start_srp(struct phy_companion *comparator) +{ + struct twl6030_usb *twl = comparator_to_twl(comparator); + + twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); + twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); + + mdelay(100); + twl6030_writeb(twl, TWL_MODULE_USB, 0xa0, USB_VBUS_CTRL_CLR); + + return 0; +} + +static int twl6030_usb_ldo_init(struct twl6030_usb *twl) +{ + /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); + + /* Program CFG_LDO_PD2 register and set VUSB bit */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2); + + /* Program MISC2 register and set bit VUSB_IN_VBAT */ + twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); + + twl->usb3v3 = regulator_get(twl->dev, twl->regulator); + if (IS_ERR(twl->usb3v3)) + return -ENODEV; + + /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ + twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); + + /* + * Program the USB_ID_CTRL_SET register to enable GND drive + * and the ID comparators + */ + twl6030_writeb(twl, TWL_MODULE_USB, 0x14, USB_ID_CTRL_SET); + + return 0; +} + +static ssize_t twl6030_usb_vbus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct twl6030_usb *twl = dev_get_drvdata(dev); + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&twl->lock, flags); + + switch (twl->linkstat) { + case OMAP_MUSB_VBUS_VALID: + ret = snprintf(buf, PAGE_SIZE, "vbus\n"); + break; + case OMAP_MUSB_ID_GROUND: + ret = snprintf(buf, PAGE_SIZE, "id\n"); + break; + case OMAP_MUSB_VBUS_OFF: + ret = snprintf(buf, PAGE_SIZE, "none\n"); + break; + default: + ret = snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); + } + spin_unlock_irqrestore(&twl->lock, flags); + + return ret; +} +static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); + +static irqreturn_t twl6030_usb_irq(int irq, void *_twl) +{ + struct twl6030_usb *twl = _twl; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + u8 vbus_state, hw_state; + + hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); + + vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, + CONTROLLER_STAT1); + if (!(hw_state & STS_USB_ID)) { + if (vbus_state & VBUS_DET) { + regulator_enable(twl->usb3v3); + twl->asleep = 1; + status = OMAP_MUSB_VBUS_VALID; + twl->linkstat = status; + omap_musb_mailbox(status); + } else { + if (twl->linkstat != OMAP_MUSB_UNKNOWN) { + status = OMAP_MUSB_VBUS_OFF; + twl->linkstat = status; + omap_musb_mailbox(status); + if (twl->asleep) { + regulator_disable(twl->usb3v3); + twl->asleep = 0; + } + } + } + } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); + + return IRQ_HANDLED; +} + +static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) +{ + struct twl6030_usb *twl = _twl; + enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; + u8 hw_state; + + hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); + + if (hw_state & STS_USB_ID) { + + regulator_enable(twl->usb3v3); + twl->asleep = 1; + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); + status = OMAP_MUSB_ID_GROUND; + twl->linkstat = status; + omap_musb_mailbox(status); + } else { + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + } + twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); + + return IRQ_HANDLED; +} + +static int twl6030_enable_irq(struct twl6030_usb *twl) +{ + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); + twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); + twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); + + twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, + REG_INT_MSK_LINE_C); + twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, + REG_INT_MSK_STS_C); + twl6030_usb_irq(twl->irq2, twl); + twl6030_usbotg_irq(twl->irq1, twl); + + return 0; +} + +static void otg_set_vbus_work(struct work_struct *data) +{ + struct twl6030_usb *twl = container_of(data, struct twl6030_usb, + set_vbus_work); + + /* + * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 + * register. This enables boost mode. + */ + + if (twl->vbus_enable) + twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, + CHARGERUSB_CTRL1); + else + twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, + CHARGERUSB_CTRL1); +} + +static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) +{ + struct twl6030_usb *twl = comparator_to_twl(comparator); + + twl->vbus_enable = enabled; + schedule_work(&twl->set_vbus_work); + + return 0; +} + +static int twl6030_usb_probe(struct platform_device *pdev) +{ + u32 ret; + struct twl6030_usb *twl; + int status, err; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct twl4030_usb_data *pdata = dev->platform_data; + + twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); + if (!twl) + return -ENOMEM; + + twl->dev = &pdev->dev; + twl->irq1 = platform_get_irq(pdev, 0); + twl->irq2 = platform_get_irq(pdev, 1); + twl->linkstat = OMAP_MUSB_UNKNOWN; + + twl->comparator.set_vbus = twl6030_set_vbus; + twl->comparator.start_srp = twl6030_start_srp; + + ret = omap_usb2_set_comparator(&twl->comparator); + if (ret == -ENODEV) { + dev_info(&pdev->dev, "phy not ready, deferring probe"); + return -EPROBE_DEFER; + } + + if (np) { + twl->regulator = "usb"; + } else if (pdata) { + if (pdata->features & TWL6025_SUBCLASS) + twl->regulator = "ldousb"; + else + twl->regulator = "vusb"; + } else { + dev_err(&pdev->dev, "twl6030 initialized without pdata\n"); + return -EINVAL; + } + + /* init spinlock for workqueue */ + spin_lock_init(&twl->lock); + + err = twl6030_usb_ldo_init(twl); + if (err) { + dev_err(&pdev->dev, "ldo init failed\n"); + return err; + } + + platform_set_drvdata(pdev, twl); + if (device_create_file(&pdev->dev, &dev_attr_vbus)) + dev_warn(&pdev->dev, "could not create sysfs file\n"); + + INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); + + twl->irq_enabled = true; + status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "twl6030_usb", twl); + if (status < 0) { + dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq1, status); + device_remove_file(twl->dev, &dev_attr_vbus); + return status; + } + + status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "twl6030_usb", twl); + if (status < 0) { + dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", + twl->irq2, status); + free_irq(twl->irq1, twl); + device_remove_file(twl->dev, &dev_attr_vbus); + return status; + } + + twl->asleep = 0; + twl6030_enable_irq(twl); + dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); + + return 0; +} + +static int __exit twl6030_usb_remove(struct platform_device *pdev) +{ + struct twl6030_usb *twl = platform_get_drvdata(pdev); + + twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, + REG_INT_MSK_LINE_C); + twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, + REG_INT_MSK_STS_C); + free_irq(twl->irq1, twl); + free_irq(twl->irq2, twl); + regulator_put(twl->usb3v3); + device_remove_file(twl->dev, &dev_attr_vbus); + cancel_work_sync(&twl->set_vbus_work); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id twl6030_usb_id_table[] = { + { .compatible = "ti,twl6030-usb" }, + {} +}; +MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); +#endif + +static struct platform_driver twl6030_usb_driver = { + .probe = twl6030_usb_probe, + .remove = __exit_p(twl6030_usb_remove), + .driver = { + .name = "twl6030_usb", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl6030_usb_id_table), + }, +}; + +static int __init twl6030_usb_init(void) +{ + return platform_driver_register(&twl6030_usb_driver); +} +subsys_initcall(twl6030_usb_init); + +static void __exit twl6030_usb_exit(void) +{ + platform_driver_unregister(&twl6030_usb_driver); +} +module_exit(twl6030_usb_exit); + +MODULE_ALIAS("platform:twl6030_usb"); +MODULE_AUTHOR("Hema HK "); +MODULE_DESCRIPTION("TWL6030 USB transceiver driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-ulpi-viewport.c b/drivers/usb/phy/phy-ulpi-viewport.c new file mode 100644 index 000000000000..c5ba7e5423fc --- /dev/null +++ b/drivers/usb/phy/phy-ulpi-viewport.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Google, Inc. + * + * 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 + +#define ULPI_VIEW_WAKEUP (1 << 31) +#define ULPI_VIEW_RUN (1 << 30) +#define ULPI_VIEW_WRITE (1 << 29) +#define ULPI_VIEW_READ (0 << 29) +#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) +#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) +#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) + +static int ulpi_viewport_wait(void __iomem *view, u32 mask) +{ + unsigned long usec = 2000; + + while (usec--) { + if (!(readl(view) & mask)) + return 0; + + udelay(1); + }; + + return -ETIMEDOUT; +} + +static int ulpi_viewport_read(struct usb_phy *otg, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); + if (ret) + return ret; + + return ULPI_VIEW_DATA_READ(readl(view)); +} + +static int ulpi_viewport_write(struct usb_phy *otg, u32 val, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | + ULPI_VIEW_ADDR(reg), view); + + return ulpi_viewport_wait(view, ULPI_VIEW_RUN); +} + +struct usb_phy_io_ops ulpi_viewport_access_ops = { + .read = ulpi_viewport_read, + .write = ulpi_viewport_write, +}; diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c new file mode 100644 index 000000000000..217339dd7a90 --- /dev/null +++ b/drivers/usb/phy/phy-ulpi.c @@ -0,0 +1,283 @@ +/* + * Generic ULPI USB transceiver support + * + * Copyright (C) 2009 Daniel Mack + * + * Based on sources from + * + * Sascha Hauer + * Freescale Semiconductors + * + * 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 + + +struct ulpi_info { + unsigned int id; + char *name; +}; + +#define ULPI_ID(vendor, product) (((vendor) << 16) | (product)) +#define ULPI_INFO(_id, _name) \ + { \ + .id = (_id), \ + .name = (_name), \ + } + +/* ULPI hardcoded IDs, used for probing */ +static struct ulpi_info ulpi_ids[] = { + ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), + ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), +}; + +static int ulpi_set_otg_flags(struct usb_phy *phy) +{ + unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN | + ULPI_OTG_CTRL_DM_PULLDOWN; + + if (phy->flags & ULPI_OTG_ID_PULLUP) + flags |= ULPI_OTG_CTRL_ID_PULLUP; + + /* + * ULPI Specification rev.1.1 default + * for Dp/DmPulldown is enabled. + */ + if (phy->flags & ULPI_OTG_DP_PULLDOWN_DIS) + flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN; + + if (phy->flags & ULPI_OTG_DM_PULLDOWN_DIS) + flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN; + + if (phy->flags & ULPI_OTG_EXTVBUSIND) + flags |= ULPI_OTG_CTRL_EXTVBUSIND; + + return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); +} + +static int ulpi_set_fc_flags(struct usb_phy *phy) +{ + unsigned int flags = 0; + + /* + * ULPI Specification rev.1.1 default + * for XcvrSelect is Full Speed. + */ + if (phy->flags & ULPI_FC_HS) + flags |= ULPI_FUNC_CTRL_HIGH_SPEED; + else if (phy->flags & ULPI_FC_LS) + flags |= ULPI_FUNC_CTRL_LOW_SPEED; + else if (phy->flags & ULPI_FC_FS4LS) + flags |= ULPI_FUNC_CTRL_FS4LS; + else + flags |= ULPI_FUNC_CTRL_FULL_SPEED; + + if (phy->flags & ULPI_FC_TERMSEL) + flags |= ULPI_FUNC_CTRL_TERMSELECT; + + /* + * ULPI Specification rev.1.1 default + * for OpMode is Normal Operation. + */ + if (phy->flags & ULPI_FC_OP_NODRV) + flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + else if (phy->flags & ULPI_FC_OP_DIS_NRZI) + flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI; + else if (phy->flags & ULPI_FC_OP_NSYNC_NEOP) + flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP; + else + flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL; + + /* + * ULPI Specification rev.1.1 default + * for SuspendM is Powered. + */ + flags |= ULPI_FUNC_CTRL_SUSPENDM; + + return usb_phy_io_write(phy, flags, ULPI_FUNC_CTRL); +} + +static int ulpi_set_ic_flags(struct usb_phy *phy) +{ + unsigned int flags = 0; + + if (phy->flags & ULPI_IC_AUTORESUME) + flags |= ULPI_IFC_CTRL_AUTORESUME; + + if (phy->flags & ULPI_IC_EXTVBUS_INDINV) + flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS; + + if (phy->flags & ULPI_IC_IND_PASSTHRU) + flags |= ULPI_IFC_CTRL_PASSTHRU; + + if (phy->flags & ULPI_IC_PROTECT_DIS) + flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE; + + return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); +} + +static int ulpi_set_flags(struct usb_phy *phy) +{ + int ret; + + ret = ulpi_set_otg_flags(phy); + if (ret) + return ret; + + ret = ulpi_set_ic_flags(phy); + if (ret) + return ret; + + return ulpi_set_fc_flags(phy); +} + +static int ulpi_check_integrity(struct usb_phy *phy) +{ + int ret, i; + unsigned int val = 0x55; + + for (i = 0; i < 2; i++) { + ret = usb_phy_io_write(phy, val, ULPI_SCRATCH); + if (ret < 0) + return ret; + + ret = usb_phy_io_read(phy, ULPI_SCRATCH); + if (ret < 0) + return ret; + + if (ret != val) { + pr_err("ULPI integrity check: failed!"); + return -ENODEV; + } + val = val << 1; + } + + pr_info("ULPI integrity check: passed.\n"); + + return 0; +} + +static int ulpi_init(struct usb_phy *phy) +{ + int i, vid, pid, ret; + u32 ulpi_id = 0; + + for (i = 0; i < 4; i++) { + ret = usb_phy_io_read(phy, ULPI_PRODUCT_ID_HIGH - i); + if (ret < 0) + return ret; + ulpi_id = (ulpi_id << 8) | ret; + } + vid = ulpi_id & 0xffff; + pid = ulpi_id >> 16; + + pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); + + for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) { + if (ulpi_ids[i].id == ULPI_ID(vid, pid)) { + pr_info("Found %s ULPI transceiver.\n", + ulpi_ids[i].name); + break; + } + } + + ret = ulpi_check_integrity(phy); + if (ret) + return ret; + + return ulpi_set_flags(phy); +} + +static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + struct usb_phy *phy = otg->phy; + unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); + + if (!host) { + otg->host = NULL; + return 0; + } + + otg->host = host; + + flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE | + ULPI_IFC_CTRL_3_PIN_SERIAL_MODE | + ULPI_IFC_CTRL_CARKITMODE); + + if (phy->flags & ULPI_IC_6PIN_SERIAL) + flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE; + else if (phy->flags & ULPI_IC_3PIN_SERIAL) + flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE; + else if (phy->flags & ULPI_IC_CARKIT) + flags |= ULPI_IFC_CTRL_CARKITMODE; + + return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); +} + +static int ulpi_set_vbus(struct usb_otg *otg, bool on) +{ + struct usb_phy *phy = otg->phy; + unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); + + flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); + + if (on) { + if (phy->flags & ULPI_OTG_DRVVBUS) + flags |= ULPI_OTG_CTRL_DRVVBUS; + + if (phy->flags & ULPI_OTG_DRVVBUS_EXT) + flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; + } + + return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); +} + +struct usb_phy * +otg_ulpi_create(struct usb_phy_io_ops *ops, + unsigned int flags) +{ + struct usb_phy *phy; + struct usb_otg *otg; + + phy = kzalloc(sizeof(*phy), GFP_KERNEL); + if (!phy) + return NULL; + + otg = kzalloc(sizeof(*otg), GFP_KERNEL); + if (!otg) { + kfree(phy); + return NULL; + } + + phy->label = "ULPI"; + phy->flags = flags; + phy->io_ops = ops; + phy->otg = otg; + phy->init = ulpi_init; + + otg->phy = phy; + otg->set_host = ulpi_set_host; + otg->set_vbus = ulpi_set_vbus; + + return phy; +} +EXPORT_SYMBOL_GPL(otg_ulpi_create); + diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c deleted file mode 100644 index a35681b0c501..000000000000 --- a/drivers/usb/phy/rcar-phy.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Renesas R-Car USB phy driver - * - * Copyright (C) 2012 Renesas Solutions Corp. - * Kuninori Morimoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -/* USBH common register */ -#define USBPCTRL0 0x0800 -#define USBPCTRL1 0x0804 -#define USBST 0x0808 -#define USBEH0 0x080C -#define USBOH0 0x081C -#define USBCTL0 0x0858 -#define EIIBC1 0x0094 -#define EIIBC2 0x009C - -/* USBPCTRL1 */ -#define PHY_RST (1 << 2) -#define PLL_ENB (1 << 1) -#define PHY_ENB (1 << 0) - -/* USBST */ -#define ST_ACT (1 << 31) -#define ST_PLL (1 << 30) - -struct rcar_usb_phy_priv { - struct usb_phy phy; - spinlock_t lock; - - void __iomem *reg0; - void __iomem *reg1; - int counter; -}; - -#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy) - - -/* - * USB initial/install operation. - * - * This function setup USB phy. - * The used value and setting order came from - * [USB :: Initial setting] on datasheet. - */ -static int rcar_usb_phy_init(struct usb_phy *phy) -{ - struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); - struct device *dev = phy->dev; - void __iomem *reg0 = priv->reg0; - void __iomem *reg1 = priv->reg1; - int i; - u32 val; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (priv->counter++ == 0) { - - /* - * USB phy start-up - */ - - /* (1) USB-PHY standby release */ - iowrite32(PHY_ENB, (reg0 + USBPCTRL1)); - - /* (2) start USB-PHY internal PLL */ - iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); - - /* (3) USB module status check */ - for (i = 0; i < 1024; i++) { - udelay(10); - val = ioread32(reg0 + USBST); - if (val == (ST_ACT | ST_PLL)) - break; - } - - if (val != (ST_ACT | ST_PLL)) { - dev_err(dev, "USB phy not ready\n"); - goto phy_init_end; - } - - /* (4) USB-PHY reset clear */ - iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); - - /* set platform specific port settings */ - iowrite32(0x00000000, (reg0 + USBPCTRL0)); - - /* - * EHCI IP internal buffer setting - * EHCI IP internal buffer enable - * - * These are recommended value of a datasheet - * see [USB :: EHCI internal buffer setting] - */ - iowrite32(0x00ff0040, (reg0 + EIIBC1)); - iowrite32(0x00ff0040, (reg1 + EIIBC1)); - - iowrite32(0x00000001, (reg0 + EIIBC2)); - iowrite32(0x00000001, (reg1 + EIIBC2)); - - /* - * Bus alignment settings - */ - - /* (1) EHCI bus alignment (little endian) */ - iowrite32(0x00000000, (reg0 + USBEH0)); - - /* (1) OHCI bus alignment (little endian) */ - iowrite32(0x00000000, (reg0 + USBOH0)); - } - -phy_init_end: - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static void rcar_usb_phy_shutdown(struct usb_phy *phy) -{ - struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); - void __iomem *reg0 = priv->reg0; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->counter-- == 1) { /* last user */ - iowrite32(0x00000000, (reg0 + USBPCTRL0)); - iowrite32(0x00000000, (reg0 + USBPCTRL1)); - } - - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int rcar_usb_phy_probe(struct platform_device *pdev) -{ - struct rcar_usb_phy_priv *priv; - struct resource *res0, *res1; - struct device *dev = &pdev->dev; - void __iomem *reg0, *reg1; - int ret; - - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); - res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res0 || !res1) { - dev_err(dev, "Not enough platform resources\n"); - return -EINVAL; - } - - /* - * CAUTION - * - * Because this phy address is also mapped under OHCI/EHCI address area, - * this driver can't use devm_request_and_ioremap(dev, res) here - */ - reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0)); - reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1)); - if (!reg0 || !reg1) { - dev_err(dev, "ioremap error\n"); - return -ENOMEM; - } - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "priv data allocation error\n"); - return -ENOMEM; - } - - priv->reg0 = reg0; - priv->reg1 = reg1; - priv->counter = 0; - priv->phy.dev = dev; - priv->phy.label = dev_name(dev); - priv->phy.init = rcar_usb_phy_init; - priv->phy.shutdown = rcar_usb_phy_shutdown; - spin_lock_init(&priv->lock); - - ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); - if (ret < 0) { - dev_err(dev, "usb phy addition error\n"); - return ret; - } - - platform_set_drvdata(pdev, priv); - - return ret; -} - -static int rcar_usb_phy_remove(struct platform_device *pdev) -{ - struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev); - - usb_remove_phy(&priv->phy); - - return 0; -} - -static struct platform_driver rcar_usb_phy_driver = { - .driver = { - .name = "rcar_usb_phy", - }, - .probe = rcar_usb_phy_probe, - .remove = rcar_usb_phy_remove, -}; - -module_platform_driver(rcar_usb_phy_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Renesas R-Car USB phy"); -MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c deleted file mode 100644 index 967101ec15fd..000000000000 --- a/drivers/usb/phy/samsung-usbphy.c +++ /dev/null @@ -1,928 +0,0 @@ -/* linux/drivers/usb/phy/samsung-usbphy.c - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Author: Praveen Paneri - * - * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and - * OHCI-EXYNOS controllers. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register definitions */ - -#define SAMSUNG_PHYPWR (0x00) - -#define PHYPWR_NORMAL_MASK (0x19 << 0) -#define PHYPWR_OTG_DISABLE (0x1 << 4) -#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) -#define PHYPWR_FORCE_SUSPEND (0x1 << 1) -/* For Exynos4 */ -#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0) -#define PHYPWR_SLEEP_PHY0 (0x1 << 5) - -#define SAMSUNG_PHYCLK (0x04) - -#define PHYCLK_MODE_USB11 (0x1 << 6) -#define PHYCLK_EXT_OSC (0x1 << 5) -#define PHYCLK_COMMON_ON_N (0x1 << 4) -#define PHYCLK_ID_PULL (0x1 << 2) -#define PHYCLK_CLKSEL_MASK (0x3 << 0) -#define PHYCLK_CLKSEL_48M (0x0 << 0) -#define PHYCLK_CLKSEL_12M (0x2 << 0) -#define PHYCLK_CLKSEL_24M (0x3 << 0) - -#define SAMSUNG_RSTCON (0x08) - -#define RSTCON_PHYLINK_SWRST (0x1 << 2) -#define RSTCON_HLINK_SWRST (0x1 << 1) -#define RSTCON_SWRST (0x1 << 0) - -/* EXYNOS5 */ -#define EXYNOS5_PHY_HOST_CTRL0 (0x00) - -#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) - -#define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) -#define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) -#define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) -#define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) - -#define HOST_CTRL0_FSEL_MASK (0x7 << 16) -#define HOST_CTRL0_FSEL(_x) ((_x) << 16) - -#define FSEL_CLKSEL_50M (0x7) -#define FSEL_CLKSEL_24M (0x5) -#define FSEL_CLKSEL_20M (0x4) -#define FSEL_CLKSEL_19200K (0x3) -#define FSEL_CLKSEL_12M (0x2) -#define FSEL_CLKSEL_10M (0x1) -#define FSEL_CLKSEL_9600K (0x0) - -#define HOST_CTRL0_TESTBURNIN (0x1 << 11) -#define HOST_CTRL0_RETENABLE (0x1 << 10) -#define HOST_CTRL0_COMMONON_N (0x1 << 9) -#define HOST_CTRL0_SIDDQ (0x1 << 6) -#define HOST_CTRL0_FORCESLEEP (0x1 << 5) -#define HOST_CTRL0_FORCESUSPEND (0x1 << 4) -#define HOST_CTRL0_WORDINTERFACE (0x1 << 3) -#define HOST_CTRL0_UTMISWRST (0x1 << 2) -#define HOST_CTRL0_LINKSWRST (0x1 << 1) -#define HOST_CTRL0_PHYSWRST (0x1 << 0) - -#define EXYNOS5_PHY_HOST_TUNE0 (0x04) - -#define EXYNOS5_PHY_HSIC_CTRL1 (0x10) - -#define EXYNOS5_PHY_HSIC_TUNE1 (0x14) - -#define EXYNOS5_PHY_HSIC_CTRL2 (0x20) - -#define EXYNOS5_PHY_HSIC_TUNE2 (0x24) - -#define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) -#define HSIC_CTRL_REFCLKSEL (0x2 << 23) - -#define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) -#define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) -#define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) -#define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16) -#define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) -#define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) -#define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) - -#define HSIC_CTRL_SIDDQ (0x1 << 6) -#define HSIC_CTRL_FORCESLEEP (0x1 << 5) -#define HSIC_CTRL_FORCESUSPEND (0x1 << 4) -#define HSIC_CTRL_WORDINTERFACE (0x1 << 3) -#define HSIC_CTRL_UTMISWRST (0x1 << 2) -#define HSIC_CTRL_PHYSWRST (0x1 << 0) - -#define EXYNOS5_PHY_HOST_EHCICTRL (0x30) - -#define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) -#define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) -#define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) -#define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) - -#define EXYNOS5_PHY_HOST_OHCICTRL (0x34) - -#define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) -#define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) -#define HOST_OHCICTRL_CNTSEL (0x1 << 1) -#define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) - -#define EXYNOS5_PHY_OTG_SYS (0x38) - -#define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) -#define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) -#define OTG_SYS_PHY0_SWRST (0x1 << 12) - -#define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) -#define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) -#define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) -#define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) - -#define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) -#define OTG_SYS_COMMON_ON (0x1 << 7) - -#define OTG_SYS_FSEL_MASK (0x7 << 4) -#define OTG_SYS_FSEL(_x) ((_x) << 4) - -#define OTG_SYS_FORCESLEEP (0x1 << 3) -#define OTG_SYS_OTGDISABLE (0x1 << 2) -#define OTG_SYS_SIDDQ_UOTG (0x1 << 1) -#define OTG_SYS_FORCESUSPEND (0x1 << 0) - -#define EXYNOS5_PHY_OTG_TUNE (0x40) - -#ifndef MHZ -#define MHZ (1000*1000) -#endif - -#ifndef KHZ -#define KHZ (1000) -#endif - -#define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4) -#define S3C64XX_USBPHY_ENABLE (0x1 << 16) -#define EXYNOS_USBPHY_ENABLE (0x1 << 0) -#define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0) - -enum samsung_cpu_type { - TYPE_S3C64XX, - TYPE_EXYNOS4210, - TYPE_EXYNOS5250, -}; - -/* - * struct samsung_usbphy_drvdata - driver data for various SoC variants - * @cpu_type: machine identifier - * @devphy_en_mask: device phy enable mask for PHY CONTROL register - * @hostphy_en_mask: host phy enable mask for PHY CONTROL register - * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from - * mapped address of system controller. - * @hostphy_reg_offset: offset to HOST PHY CONTROL register from - * mapped address of system controller. - * - * Here we have a separate mask for device type phy. - * Having different masks for host and device type phy helps - * in setting independent masks in case of SoCs like S5PV210, - * in which PHY0 and PHY1 enable bits belong to same register - * placed at position 0 and 1 respectively. - * Although for newer SoCs like exynos these bits belong to - * different registers altogether placed at position 0. - */ -struct samsung_usbphy_drvdata { - int cpu_type; - int devphy_en_mask; - int hostphy_en_mask; - u32 devphy_reg_offset; - u32 hostphy_reg_offset; -}; - -/* - * struct samsung_usbphy - transceiver driver state - * @phy: transceiver structure - * @plat: platform data - * @dev: The parent device supplied to the probe function - * @clk: usb phy clock - * @regs: usb phy controller registers memory base - * @pmuregs: USB device PHY_CONTROL register memory base - * @sysreg: USB2.0 PHY_CFG register memory base - * @ref_clk_freq: reference clock frequency selection - * @drv_data: driver data available for different SoCs - * @phy_type: Samsung SoCs specific phy types: #HOST - * #DEVICE - * @phy_usage: usage count for phy - * @lock: lock for phy operations - */ -struct samsung_usbphy { - struct usb_phy phy; - struct samsung_usbphy_data *plat; - struct device *dev; - struct clk *clk; - void __iomem *regs; - void __iomem *pmuregs; - void __iomem *sysreg; - int ref_clk_freq; - const struct samsung_usbphy_drvdata *drv_data; - enum samsung_usb_phy_type phy_type; - atomic_t phy_usage; - spinlock_t lock; -}; - -#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy) - -int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - if (!otg->host) - otg->host = host; - - return 0; -} - -static int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy) -{ - struct device_node *usbphy_sys; - - /* Getting node for system controller interface for usb-phy */ - usbphy_sys = of_get_child_by_name(sphy->dev->of_node, "usbphy-sys"); - if (!usbphy_sys) { - dev_err(sphy->dev, "No sys-controller interface for usb-phy\n"); - return -ENODEV; - } - - sphy->pmuregs = of_iomap(usbphy_sys, 0); - - if (sphy->pmuregs == NULL) { - dev_err(sphy->dev, "Can't get usb-phy pmu control register\n"); - goto err0; - } - - sphy->sysreg = of_iomap(usbphy_sys, 1); - - /* - * Not returning error code here, since this situation is not fatal. - * Few SoCs may not have this switch available - */ - if (sphy->sysreg == NULL) - dev_warn(sphy->dev, "Can't get usb-phy sysreg cfg register\n"); - - of_node_put(usbphy_sys); - - return 0; - -err0: - of_node_put(usbphy_sys); - return -ENXIO; -} - -/* - * Set isolation here for phy. - * Here 'on = true' would mean USB PHY block is isolated, hence - * de-activated and vice-versa. - */ -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) -{ - void __iomem *reg = NULL; - u32 reg_val; - u32 en_mask = 0; - - if (!sphy->pmuregs) { - dev_warn(sphy->dev, "Can't set pmu isolation\n"); - return; - } - - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - /* - * Do nothing: We will add here once S3C64xx goes for DT support - */ - break; - case TYPE_EXYNOS4210: - /* - * Fall through since exynos4210 and exynos5250 have similar - * register architecture: two separate registers for host and - * device phy control with enable bit at position 0. - */ - case TYPE_EXYNOS5250: - if (sphy->phy_type == USB_PHY_TYPE_DEVICE) { - reg = sphy->pmuregs + - sphy->drv_data->devphy_reg_offset; - en_mask = sphy->drv_data->devphy_en_mask; - } else if (sphy->phy_type == USB_PHY_TYPE_HOST) { - reg = sphy->pmuregs + - sphy->drv_data->hostphy_reg_offset; - en_mask = sphy->drv_data->hostphy_en_mask; - } - break; - default: - dev_err(sphy->dev, "Invalid SoC type\n"); - return; - } - - reg_val = readl(reg); - - if (on) - reg_val &= ~en_mask; - else - reg_val |= en_mask; - - writel(reg_val, reg); -} - -/* - * Configure the mode of working of usb-phy here: HOST/DEVICE. - */ -static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) -{ - u32 reg; - - if (!sphy->sysreg) { - dev_warn(sphy->dev, "Can't configure specified phy mode\n"); - return; - } - - reg = readl(sphy->sysreg); - - if (sphy->phy_type == USB_PHY_TYPE_DEVICE) - reg &= ~EXYNOS_USB20PHY_CFG_HOST_LINK; - else if (sphy->phy_type == USB_PHY_TYPE_HOST) - reg |= EXYNOS_USB20PHY_CFG_HOST_LINK; - - writel(reg, sphy->sysreg); -} - -/* - * PHYs are different for USB Device and USB Host. - * This make sure that correct PHY type is selected before - * any operation on PHY. - */ -static int samsung_usbphy_set_type(struct usb_phy *phy, - enum samsung_usb_phy_type phy_type) -{ - struct samsung_usbphy *sphy = phy_to_sphy(phy); - - sphy->phy_type = phy_type; - - return 0; -} - -/* - * Returns reference clock frequency selection value - */ -static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) -{ - struct clk *ref_clk; - int refclk_freq = 0; - - /* - * In exynos5250 USB host and device PHY use - * external crystal clock XXTI - */ - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - ref_clk = clk_get(sphy->dev, "ext_xtal"); - else - ref_clk = clk_get(sphy->dev, "xusbxti"); - if (IS_ERR(ref_clk)) { - dev_err(sphy->dev, "Failed to get reference clock\n"); - return PTR_ERR(ref_clk); - } - - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) { - /* set clock frequency for PLL */ - switch (clk_get_rate(ref_clk)) { - case 9600 * KHZ: - refclk_freq = FSEL_CLKSEL_9600K; - break; - case 10 * MHZ: - refclk_freq = FSEL_CLKSEL_10M; - break; - case 12 * MHZ: - refclk_freq = FSEL_CLKSEL_12M; - break; - case 19200 * KHZ: - refclk_freq = FSEL_CLKSEL_19200K; - break; - case 20 * MHZ: - refclk_freq = FSEL_CLKSEL_20M; - break; - case 50 * MHZ: - refclk_freq = FSEL_CLKSEL_50M; - break; - case 24 * MHZ: - default: - /* default reference clock */ - refclk_freq = FSEL_CLKSEL_24M; - break; - } - } else { - switch (clk_get_rate(ref_clk)) { - case 12 * MHZ: - refclk_freq = PHYCLK_CLKSEL_12M; - break; - case 24 * MHZ: - refclk_freq = PHYCLK_CLKSEL_24M; - break; - case 48 * MHZ: - refclk_freq = PHYCLK_CLKSEL_48M; - break; - default: - if (sphy->drv_data->cpu_type == TYPE_S3C64XX) - refclk_freq = PHYCLK_CLKSEL_48M; - else - refclk_freq = PHYCLK_CLKSEL_24M; - break; - } - } - clk_put(ref_clk); - - return refclk_freq; -} - -static bool exynos5_phyhost_is_on(void *regs) -{ - u32 reg; - - reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - - return !(reg & HOST_CTRL0_SIDDQ); -} - -static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phyclk = sphy->ref_clk_freq; - u32 phyhost; - u32 phyotg; - u32 phyhsic; - u32 ehcictrl; - u32 ohcictrl; - - /* - * phy_usage helps in keeping usage count for phy - * so that the first consumer enabling the phy is also - * the last consumer to disable it. - */ - - atomic_inc(&sphy->phy_usage); - - if (exynos5_phyhost_is_on(regs)) { - dev_info(sphy->dev, "Already power on PHY\n"); - return; - } - - /* Host configuration */ - phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - - /* phy reference clock configuration */ - phyhost &= ~HOST_CTRL0_FSEL_MASK; - phyhost |= HOST_CTRL0_FSEL(phyclk); - - /* host phy reset */ - phyhost &= ~(HOST_CTRL0_PHYSWRST | - HOST_CTRL0_PHYSWRSTALL | - HOST_CTRL0_SIDDQ | - /* Enable normal mode of operation */ - HOST_CTRL0_FORCESUSPEND | - HOST_CTRL0_FORCESLEEP); - - /* Link reset */ - phyhost |= (HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST | - /* COMMON Block configuration during suspend */ - HOST_CTRL0_COMMONON_N); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - udelay(10); - phyhost &= ~(HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - - /* OTG configuration */ - phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); - - /* phy reference clock configuration */ - phyotg &= ~OTG_SYS_FSEL_MASK; - phyotg |= OTG_SYS_FSEL(phyclk); - - /* Enable normal mode of operation */ - phyotg &= ~(OTG_SYS_FORCESUSPEND | - OTG_SYS_SIDDQ_UOTG | - OTG_SYS_FORCESLEEP | - OTG_SYS_REFCLKSEL_MASK | - /* COMMON Block configuration during suspend */ - OTG_SYS_COMMON_ON); - - /* OTG phy & link reset */ - phyotg |= (OTG_SYS_PHY0_SWRST | - OTG_SYS_LINKSWRST_UOTG | - OTG_SYS_PHYLINK_SWRESET | - OTG_SYS_OTGDISABLE | - /* Set phy refclk */ - OTG_SYS_REFCLKSEL_CLKCORE); - - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); - udelay(10); - phyotg &= ~(OTG_SYS_PHY0_SWRST | - OTG_SYS_LINKSWRST_UOTG | - OTG_SYS_PHYLINK_SWRESET); - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); - - /* HSIC phy configuration */ - phyhsic = (HSIC_CTRL_REFCLKDIV_12 | - HSIC_CTRL_REFCLKSEL | - HSIC_CTRL_PHYSWRST); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - udelay(10); - phyhsic &= ~HSIC_CTRL_PHYSWRST; - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - - udelay(80); - - /* enable EHCI DMA burst */ - ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL); - ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN | - HOST_EHCICTRL_ENAINCR4 | - HOST_EHCICTRL_ENAINCR8 | - HOST_EHCICTRL_ENAINCR16); - writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL); - - /* set ohci_suspend_on_n */ - ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL); - ohcictrl |= HOST_OHCICTRL_SUSPLGCY; - writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL); -} - -static void samsung_usbphy_enable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phypwr; - u32 phyclk; - u32 rstcon; - - /* set clock frequency for PLL */ - phyclk = sphy->ref_clk_freq; - phypwr = readl(regs + SAMSUNG_PHYPWR); - rstcon = readl(regs + SAMSUNG_RSTCON); - - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - phyclk &= ~PHYCLK_COMMON_ON_N; - phypwr &= ~PHYPWR_NORMAL_MASK; - rstcon |= RSTCON_SWRST; - break; - case TYPE_EXYNOS4210: - phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; - rstcon |= RSTCON_SWRST; - default: - break; - } - - writel(phyclk, regs + SAMSUNG_PHYCLK); - /* Configure PHY0 for normal operation*/ - writel(phypwr, regs + SAMSUNG_PHYPWR); - /* reset all ports of PHY and Link */ - writel(rstcon, regs + SAMSUNG_RSTCON); - udelay(10); - rstcon &= ~RSTCON_SWRST; - writel(rstcon, regs + SAMSUNG_RSTCON); -} - -static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phyhost; - u32 phyotg; - u32 phyhsic; - - if (atomic_dec_return(&sphy->phy_usage) > 0) { - dev_info(sphy->dev, "still being used\n"); - return; - } - - phyhsic = (HSIC_CTRL_REFCLKDIV_12 | - HSIC_CTRL_REFCLKSEL | - HSIC_CTRL_SIDDQ | - HSIC_CTRL_FORCESLEEP | - HSIC_CTRL_FORCESUSPEND); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - - phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - phyhost |= (HOST_CTRL0_SIDDQ | - HOST_CTRL0_FORCESUSPEND | - HOST_CTRL0_FORCESLEEP | - HOST_CTRL0_PHYSWRST | - HOST_CTRL0_PHYSWRSTALL); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - - phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); - phyotg |= (OTG_SYS_FORCESUSPEND | - OTG_SYS_SIDDQ_UOTG | - OTG_SYS_FORCESLEEP); - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); -} - -static void samsung_usbphy_disable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phypwr; - - phypwr = readl(regs + SAMSUNG_PHYPWR); - - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - phypwr |= PHYPWR_NORMAL_MASK; - break; - case TYPE_EXYNOS4210: - phypwr |= PHYPWR_NORMAL_MASK_PHY0; - default: - break; - } - - /* Disable analog and otg block power */ - writel(phypwr, regs + SAMSUNG_PHYPWR); -} - -/* - * The function passed to the usb driver for phy initialization - */ -static int samsung_usbphy_init(struct usb_phy *phy) -{ - struct samsung_usbphy *sphy; - struct usb_bus *host = NULL; - unsigned long flags; - int ret = 0; - - sphy = phy_to_sphy(phy); - - host = phy->otg->host; - - /* Enable the phy clock */ - ret = clk_prepare_enable(sphy->clk); - if (ret) { - dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); - return ret; - } - - spin_lock_irqsave(&sphy->lock, flags); - - if (host) { - /* setting default phy-type for USB 2.0 */ - if (!strstr(dev_name(host->controller), "ehci") || - !strstr(dev_name(host->controller), "ohci")) - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); - } else { - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); - } - - /* Disable phy isolation */ - if (sphy->plat && sphy->plat->pmu_isolation) - sphy->plat->pmu_isolation(false); - else - samsung_usbphy_set_isolation(sphy, false); - - /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ - samsung_usbphy_cfg_sel(sphy); - - /* Initialize usb phy registers */ - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - samsung_exynos5_usbphy_enable(sphy); - else - samsung_usbphy_enable(sphy); - - spin_unlock_irqrestore(&sphy->lock, flags); - - /* Disable the phy clock */ - clk_disable_unprepare(sphy->clk); - - return ret; -} - -/* - * The function passed to the usb driver for phy shutdown - */ -static void samsung_usbphy_shutdown(struct usb_phy *phy) -{ - struct samsung_usbphy *sphy; - struct usb_bus *host = NULL; - unsigned long flags; - - sphy = phy_to_sphy(phy); - - host = phy->otg->host; - - if (clk_prepare_enable(sphy->clk)) { - dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); - return; - } - - spin_lock_irqsave(&sphy->lock, flags); - - if (host) { - /* setting default phy-type for USB 2.0 */ - if (!strstr(dev_name(host->controller), "ehci") || - !strstr(dev_name(host->controller), "ohci")) - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); - } else { - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); - } - - /* De-initialize usb phy registers */ - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - samsung_exynos5_usbphy_disable(sphy); - else - samsung_usbphy_disable(sphy); - - /* Enable phy isolation */ - if (sphy->plat && sphy->plat->pmu_isolation) - sphy->plat->pmu_isolation(true); - else - samsung_usbphy_set_isolation(sphy, true); - - spin_unlock_irqrestore(&sphy->lock, flags); - - clk_disable_unprepare(sphy->clk); -} - -static const struct of_device_id samsung_usbphy_dt_match[]; - -static inline const struct samsung_usbphy_drvdata -*samsung_usbphy_get_driver_data(struct platform_device *pdev) -{ - if (pdev->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(samsung_usbphy_dt_match, - pdev->dev.of_node); - return match->data; - } - - return (struct samsung_usbphy_drvdata *) - platform_get_device_id(pdev)->driver_data; -} - -static int samsung_usbphy_probe(struct platform_device *pdev) -{ - struct samsung_usbphy *sphy; - struct usb_otg *otg; - struct samsung_usbphy_data *pdata = pdev->dev.platform_data; - const struct samsung_usbphy_drvdata *drv_data; - struct device *dev = &pdev->dev; - struct resource *phy_mem; - void __iomem *phy_base; - struct clk *clk; - int ret; - - phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!phy_mem) { - dev_err(dev, "%s: missing mem resource\n", __func__); - return -ENODEV; - } - - phy_base = devm_ioremap_resource(dev, phy_mem); - if (IS_ERR(phy_base)) - return PTR_ERR(phy_base); - - sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); - if (!sphy) - return -ENOMEM; - - otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - drv_data = samsung_usbphy_get_driver_data(pdev); - - if (drv_data->cpu_type == TYPE_EXYNOS5250) - clk = devm_clk_get(dev, "usbhost"); - else - clk = devm_clk_get(dev, "otg"); - - if (IS_ERR(clk)) { - dev_err(dev, "Failed to get otg clock\n"); - return PTR_ERR(clk); - } - - sphy->dev = dev; - - if (dev->of_node) { - ret = samsung_usbphy_parse_dt(sphy); - if (ret < 0) - return ret; - } else { - if (!pdata) { - dev_err(dev, "no platform data specified\n"); - return -EINVAL; - } - } - - sphy->plat = pdata; - sphy->regs = phy_base; - sphy->clk = clk; - sphy->drv_data = drv_data; - sphy->phy.dev = sphy->dev; - sphy->phy.label = "samsung-usbphy"; - sphy->phy.init = samsung_usbphy_init; - sphy->phy.shutdown = samsung_usbphy_shutdown; - sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); - - sphy->phy.otg = otg; - sphy->phy.otg->phy = &sphy->phy; - sphy->phy.otg->set_host = samsung_usbphy_set_host; - - spin_lock_init(&sphy->lock); - - platform_set_drvdata(pdev, sphy); - - return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); -} - -static int samsung_usbphy_remove(struct platform_device *pdev) -{ - struct samsung_usbphy *sphy = platform_get_drvdata(pdev); - - usb_remove_phy(&sphy->phy); - - if (sphy->pmuregs) - iounmap(sphy->pmuregs); - if (sphy->sysreg) - iounmap(sphy->sysreg); - - return 0; -} - -static const struct samsung_usbphy_drvdata usbphy_s3c64xx = { - .cpu_type = TYPE_S3C64XX, - .devphy_en_mask = S3C64XX_USBPHY_ENABLE, -}; - -static const struct samsung_usbphy_drvdata usbphy_exynos4 = { - .cpu_type = TYPE_EXYNOS4210, - .devphy_en_mask = EXYNOS_USBPHY_ENABLE, - .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, -}; - -static struct samsung_usbphy_drvdata usbphy_exynos5 = { - .cpu_type = TYPE_EXYNOS5250, - .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, - .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, -}; - -#ifdef CONFIG_OF -static const struct of_device_id samsung_usbphy_dt_match[] = { - { - .compatible = "samsung,s3c64xx-usbphy", - .data = &usbphy_s3c64xx, - }, { - .compatible = "samsung,exynos4210-usbphy", - .data = &usbphy_exynos4, - }, { - .compatible = "samsung,exynos5250-usbphy", - .data = &usbphy_exynos5 - }, - {}, -}; -MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); -#endif - -static struct platform_device_id samsung_usbphy_driver_ids[] = { - { - .name = "s3c64xx-usbphy", - .driver_data = (unsigned long)&usbphy_s3c64xx, - }, { - .name = "exynos4210-usbphy", - .driver_data = (unsigned long)&usbphy_exynos4, - }, { - .name = "exynos5250-usbphy", - .driver_data = (unsigned long)&usbphy_exynos5, - }, - {}, -}; - -MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); - -static struct platform_driver samsung_usbphy_driver = { - .probe = samsung_usbphy_probe, - .remove = samsung_usbphy_remove, - .id_table = samsung_usbphy_driver_ids, - .driver = { - .name = "samsung-usbphy", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(samsung_usbphy_dt_match), - }, -}; - -module_platform_driver(samsung_usbphy_driver); - -MODULE_DESCRIPTION("Samsung USB phy controller"); -MODULE_AUTHOR("Praveen Paneri "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-usbphy"); diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c deleted file mode 100644 index 5487d38481af..000000000000 --- a/drivers/usb/phy/tegra_usb_phy.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Erik Gilling - * Benoit Goby - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEGRA_USB_BASE 0xC5000000 -#define TEGRA_USB_SIZE SZ_16K - -#define ULPI_VIEWPORT 0x170 - -#define USB_SUSP_CTRL 0x400 -#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) -#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) -#define USB_SUSP_CLR (1 << 5) -#define USB_PHY_CLK_VALID (1 << 7) -#define UTMIP_RESET (1 << 11) -#define UHSIC_RESET (1 << 11) -#define UTMIP_PHY_ENABLE (1 << 12) -#define ULPI_PHY_ENABLE (1 << 13) -#define USB_SUSP_SET (1 << 14) -#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) - -#define USB1_LEGACY_CTRL 0x410 -#define USB1_NO_LEGACY_MODE (1 << 0) -#define USB1_VBUS_SENSE_CTL_MASK (3 << 1) -#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \ - (1 << 1) -#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1) -#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1) - -#define ULPI_TIMING_CTRL_0 0x424 -#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) -#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) - -#define ULPI_TIMING_CTRL_1 0x428 -#define ULPI_DATA_TRIMMER_LOAD (1 << 0) -#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) -#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) -#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) -#define ULPI_DIR_TRIMMER_LOAD (1 << 24) -#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) - -#define UTMIP_PLL_CFG1 0x804 -#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) -#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) - -#define UTMIP_XCVR_CFG0 0x808 -#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0) -#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8) -#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10) -#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) -#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) -#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) -#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) - -#define UTMIP_BIAS_CFG0 0x80c -#define UTMIP_OTGPD (1 << 11) -#define UTMIP_BIASPD (1 << 10) - -#define UTMIP_HSRX_CFG0 0x810 -#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) -#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15) - -#define UTMIP_HSRX_CFG1 0x814 -#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) - -#define UTMIP_TX_CFG0 0x820 -#define UTMIP_FS_PREABMLE_J (1 << 19) -#define UTMIP_HS_DISCON_DISABLE (1 << 8) - -#define UTMIP_MISC_CFG0 0x824 -#define UTMIP_DPDM_OBSERVE (1 << 26) -#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27) -#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf) -#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd) -#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc) -#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) - -#define UTMIP_MISC_CFG1 0x828 -#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18) -#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6) - -#define UTMIP_DEBOUNCE_CFG0 0x82c -#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0) - -#define UTMIP_BAT_CHRG_CFG0 0x830 -#define UTMIP_PD_CHRG (1 << 0) - -#define UTMIP_SPARE_CFG0 0x834 -#define FUSE_SETUP_SEL (1 << 3) - -#define UTMIP_XCVR_CFG1 0x838 -#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) -#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) -#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) -#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18) - -#define UTMIP_BIAS_CFG1 0x83c -#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) - -static DEFINE_SPINLOCK(utmip_pad_lock); -static int utmip_pad_count; - -struct tegra_xtal_freq { - int freq; - u8 enable_delay; - u8 stable_count; - u8 active_delay; - u8 xtal_freq_count; - u16 debounce; -}; - -static const struct tegra_xtal_freq tegra_freq_table[] = { - { - .freq = 12000000, - .enable_delay = 0x02, - .stable_count = 0x2F, - .active_delay = 0x04, - .xtal_freq_count = 0x76, - .debounce = 0x7530, - }, - { - .freq = 13000000, - .enable_delay = 0x02, - .stable_count = 0x33, - .active_delay = 0x05, - .xtal_freq_count = 0x7F, - .debounce = 0x7EF4, - }, - { - .freq = 19200000, - .enable_delay = 0x03, - .stable_count = 0x4B, - .active_delay = 0x06, - .xtal_freq_count = 0xBB, - .debounce = 0xBB80, - }, - { - .freq = 26000000, - .enable_delay = 0x04, - .stable_count = 0x66, - .active_delay = 0x09, - .xtal_freq_count = 0xFE, - .debounce = 0xFDE8, - }, -}; - -static struct tegra_utmip_config utmip_default[] = { - [0] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_lsfslew = 1, - .xcvr_lsrslew = 1, - }, - [2] = { - .hssync_start_delay = 9, - .idle_wait_delay = 17, - .elastic_limit = 16, - .term_range_adj = 6, - .xcvr_setup = 9, - .xcvr_lsfslew = 2, - .xcvr_lsrslew = 2, - }, -}; - -static int utmip_pad_open(struct tegra_usb_phy *phy) -{ - phy->pad_clk = clk_get_sys("utmip-pad", NULL); - if (IS_ERR(phy->pad_clk)) { - pr_err("%s: can't get utmip pad clock\n", __func__); - return PTR_ERR(phy->pad_clk); - } - - if (phy->is_legacy_phy) { - phy->pad_regs = phy->regs; - } else { - phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); - if (!phy->pad_regs) { - pr_err("%s: can't remap usb registers\n", __func__); - clk_put(phy->pad_clk); - return -ENOMEM; - } - } - return 0; -} - -static void utmip_pad_close(struct tegra_usb_phy *phy) -{ - if (!phy->is_legacy_phy) - iounmap(phy->pad_regs); - clk_put(phy->pad_clk); -} - -static void utmip_pad_power_on(struct tegra_usb_phy *phy) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - clk_prepare_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - if (utmip_pad_count++ == 0) { - val = readl(base + UTMIP_BIAS_CFG0); - val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); - writel(val, base + UTMIP_BIAS_CFG0); - } - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable_unprepare(phy->pad_clk); -} - -static int utmip_pad_power_off(struct tegra_usb_phy *phy) -{ - unsigned long val, flags; - void __iomem *base = phy->pad_regs; - - if (!utmip_pad_count) { - pr_err("%s: utmip pad already powered off\n", __func__); - return -EINVAL; - } - - clk_prepare_enable(phy->pad_clk); - - spin_lock_irqsave(&utmip_pad_lock, flags); - - if (--utmip_pad_count == 0) { - val = readl(base + UTMIP_BIAS_CFG0); - val |= UTMIP_OTGPD | UTMIP_BIASPD; - writel(val, base + UTMIP_BIAS_CFG0); - } - - spin_unlock_irqrestore(&utmip_pad_lock, flags); - - clk_disable_unprepare(phy->pad_clk); - - return 0; -} - -static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result) -{ - unsigned long timeout = 2000; - do { - if ((readl(reg) & mask) == result) - return 0; - udelay(1); - timeout--; - } while (timeout); - return -1; -} - -static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->is_legacy_phy) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - } else - tegra_ehci_set_phcd(&phy->u_phy, true); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - if (phy->is_legacy_phy) { - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - udelay(10); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - } else - tegra_ehci_set_phcd(&phy->u_phy, false); - - if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, - USB_PHY_CLK_VALID)) - pr_err("%s: timeout waiting for phy to stabilize\n", __func__); -} - -static int utmi_phy_power_on(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_utmip_config *config = phy->config; - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - if (phy->is_legacy_phy) { - val = readl(base + USB1_LEGACY_CTRL); - val |= USB1_NO_LEGACY_MODE; - writel(val, base + USB1_LEGACY_CTRL); - } - - val = readl(base + UTMIP_TX_CFG0); - val &= ~UTMIP_FS_PREABMLE_J; - writel(val, base + UTMIP_TX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG0); - val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0)); - val |= UTMIP_IDLE_WAIT(config->idle_wait_delay); - val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit); - writel(val, base + UTMIP_HSRX_CFG0); - - val = readl(base + UTMIP_HSRX_CFG1); - val &= ~UTMIP_HS_SYNC_START_DLY(~0); - val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay); - writel(val, base + UTMIP_HSRX_CFG1); - - val = readl(base + UTMIP_DEBOUNCE_CFG0); - val &= ~UTMIP_BIAS_DEBOUNCE_A(~0); - val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce); - writel(val, base + UTMIP_DEBOUNCE_CFG0); - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE; - writel(val, base + UTMIP_MISC_CFG0); - - val = readl(base + UTMIP_MISC_CFG1); - val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0)); - val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) | - UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count); - writel(val, base + UTMIP_MISC_CFG1); - - val = readl(base + UTMIP_PLL_CFG1); - val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); - val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | - UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); - writel(val, base + UTMIP_PLL_CFG1); - - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV); - writel(val, base + USB_SUSP_CTRL); - } - - utmip_pad_power_on(phy); - - val = readl(base + UTMIP_XCVR_CFG0); - val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | - UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) | - UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) | - UTMIP_XCVR_HSSLEW_MSB(~0)); - val |= UTMIP_XCVR_SETUP(config->xcvr_setup); - val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); - val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); - writel(val, base + UTMIP_XCVR_CFG0); - - val = readl(base + UTMIP_XCVR_CFG1); - val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0)); - val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj); - writel(val, base + UTMIP_XCVR_CFG1); - - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val &= ~UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - val = readl(base + UTMIP_BIAS_CFG1); - val &= ~UTMIP_BIAS_PDTRK_COUNT(~0); - val |= UTMIP_BIAS_PDTRK_COUNT(0x5); - writel(val, base + UTMIP_BIAS_CFG1); - - if (phy->is_legacy_phy) { - val = readl(base + UTMIP_SPARE_CFG0); - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) - val &= ~FUSE_SETUP_SEL; - else - val |= FUSE_SETUP_SEL; - writel(val, base + UTMIP_SPARE_CFG0); - } else { - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - } - - val = readl(base + USB_SUSP_CTRL); - val &= ~UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - if (phy->is_legacy_phy) { - val = readl(base + USB1_LEGACY_CTRL); - val &= ~USB1_VBUS_SENSE_CTL_MASK; - val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; - writel(val, base + USB1_LEGACY_CTRL); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_SET; - writel(val, base + USB_SUSP_CTRL); - } - - utmi_phy_clk_enable(phy); - - if (!phy->is_legacy_phy) - tegra_ehci_set_pts(&phy->u_phy, 0); - - return 0; -} - -static int utmi_phy_power_off(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - utmi_phy_clk_disable(phy); - - if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) { - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0); - val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5); - writel(val, base + USB_SUSP_CTRL); - } - - val = readl(base + USB_SUSP_CTRL); - val |= UTMIP_RESET; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + UTMIP_BAT_CHRG_CFG0); - val |= UTMIP_PD_CHRG; - writel(val, base + UTMIP_BAT_CHRG_CFG0); - - val = readl(base + UTMIP_XCVR_CFG0); - val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | - UTMIP_FORCE_PDZI_POWERDOWN; - writel(val, base + UTMIP_XCVR_CFG0); - - val = readl(base + UTMIP_XCVR_CFG1); - val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | - UTMIP_FORCE_PDDR_POWERDOWN; - writel(val, base + UTMIP_XCVR_CFG1); - - return utmip_pad_power_off(phy); -} - -static void utmi_phy_preresume(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_TX_CFG0); - val |= UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); -} - -static void utmi_phy_postresume(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_TX_CFG0); - val &= ~UTMIP_HS_DISCON_DISABLE; - writel(val, base + UTMIP_TX_CFG0); -} - -static void utmi_phy_restore_start(struct tegra_usb_phy *phy, - enum tegra_usb_phy_port_speed port_speed) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE_SEL(~0); - if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= UTMIP_DPDM_OBSERVE_SEL_FS_K; - else - val |= UTMIP_DPDM_OBSERVE_SEL_FS_J; - writel(val, base + UTMIP_MISC_CFG0); - udelay(1); - - val = readl(base + UTMIP_MISC_CFG0); - val |= UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -} - -static void utmi_phy_restore_end(struct tegra_usb_phy *phy) -{ - unsigned long val; - void __iomem *base = phy->regs; - - val = readl(base + UTMIP_MISC_CFG0); - val &= ~UTMIP_DPDM_OBSERVE; - writel(val, base + UTMIP_MISC_CFG0); - udelay(10); -} - -static int ulpi_phy_power_on(struct tegra_usb_phy *phy) -{ - int ret; - unsigned long val; - void __iomem *base = phy->regs; - struct tegra_ulpi_config *config = phy->config; - - gpio_direction_output(config->reset_gpio, 0); - msleep(5); - gpio_direction_output(config->reset_gpio, 1); - - clk_prepare_enable(phy->clk); - msleep(1); - - val = readl(base + USB_SUSP_CTRL); - val |= UHSIC_RESET; - writel(val, base + USB_SUSP_CTRL); - - val = readl(base + ULPI_TIMING_CTRL_0); - val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP; - writel(val, base + ULPI_TIMING_CTRL_0); - - val = readl(base + USB_SUSP_CTRL); - val |= ULPI_PHY_ENABLE; - writel(val, base + USB_SUSP_CTRL); - - val = 0; - writel(val, base + ULPI_TIMING_CTRL_1); - - val |= ULPI_DATA_TRIMMER_SEL(4); - val |= ULPI_STPDIRNXT_TRIMMER_SEL(4); - val |= ULPI_DIR_TRIMMER_SEL(4); - writel(val, base + ULPI_TIMING_CTRL_1); - udelay(10); - - val |= ULPI_DATA_TRIMMER_LOAD; - val |= ULPI_STPDIRNXT_TRIMMER_LOAD; - val |= ULPI_DIR_TRIMMER_LOAD; - writel(val, base + ULPI_TIMING_CTRL_1); - - /* Fix VbusInvalid due to floating VBUS */ - ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; - } - - ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B); - if (ret) { - pr_err("%s: ulpi write failed\n", __func__); - return ret; - } - - val = readl(base + USB_SUSP_CTRL); - val |= USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - udelay(100); - - val = readl(base + USB_SUSP_CTRL); - val &= ~USB_SUSP_CLR; - writel(val, base + USB_SUSP_CTRL); - - return 0; -} - -static int ulpi_phy_power_off(struct tegra_usb_phy *phy) -{ - struct tegra_ulpi_config *config = phy->config; - - clk_disable(phy->clk); - return gpio_direction_output(config->reset_gpio, 0); -} - -static int tegra_phy_init(struct usb_phy *x) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - struct tegra_ulpi_config *ulpi_config; - int err; - - if (phy->is_ulpi_phy) { - ulpi_config = phy->config; - phy->clk = clk_get_sys(NULL, ulpi_config->clk); - if (IS_ERR(phy->clk)) { - pr_err("%s: can't get ulpi clock\n", __func__); - err = -ENXIO; - goto err1; - } - if (!gpio_is_valid(ulpi_config->reset_gpio)) - ulpi_config->reset_gpio = - of_get_named_gpio(phy->dev->of_node, - "nvidia,phy-reset-gpio", 0); - if (!gpio_is_valid(ulpi_config->reset_gpio)) { - pr_err("%s: invalid reset gpio: %d\n", __func__, - ulpi_config->reset_gpio); - err = -EINVAL; - goto err1; - } - gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); - gpio_direction_output(ulpi_config->reset_gpio, 0); - phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); - phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT; - } else { - err = utmip_pad_open(phy); - if (err < 0) - goto err1; - } - return 0; -err1: - clk_disable_unprepare(phy->pll_u); - clk_put(phy->pll_u); - return err; -} - -static void tegra_usb_phy_close(struct usb_phy *x) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - - if (phy->is_ulpi_phy) - clk_put(phy->clk); - else - utmip_pad_close(phy); - clk_disable_unprepare(phy->pll_u); - clk_put(phy->pll_u); - kfree(phy); -} - -static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) -{ - if (phy->is_ulpi_phy) - return ulpi_phy_power_on(phy); - else - return utmi_phy_power_on(phy); -} - -static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) -{ - if (phy->is_ulpi_phy) - return ulpi_phy_power_off(phy); - else - return utmi_phy_power_off(phy); -} - -static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - if (suspend) - return tegra_usb_phy_power_off(phy); - else - return tegra_usb_phy_power_on(phy); -} - -struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, - void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode) -{ - struct tegra_usb_phy *phy; - unsigned long parent_rate; - int i; - int err; - struct device_node *np = dev->of_node; - - phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); - if (!phy) - return ERR_PTR(-ENOMEM); - - phy->instance = instance; - phy->regs = regs; - phy->config = config; - phy->mode = phy_mode; - phy->dev = dev; - phy->is_legacy_phy = - of_property_read_bool(np, "nvidia,has-legacy-mode"); - err = of_property_match_string(np, "phy_type", "ulpi"); - if (err < 0) - phy->is_ulpi_phy = false; - else - phy->is_ulpi_phy = true; - - if (!phy->config) { - if (phy->is_ulpi_phy) { - pr_err("%s: ulpi phy configuration missing", __func__); - err = -EINVAL; - goto err0; - } else { - phy->config = &utmip_default[instance]; - } - } - - phy->pll_u = clk_get_sys(NULL, "pll_u"); - if (IS_ERR(phy->pll_u)) { - pr_err("Can't get pll_u clock\n"); - err = PTR_ERR(phy->pll_u); - goto err0; - } - clk_prepare_enable(phy->pll_u); - - parent_rate = clk_get_rate(clk_get_parent(phy->pll_u)); - for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) { - if (tegra_freq_table[i].freq == parent_rate) { - phy->freq = &tegra_freq_table[i]; - break; - } - } - if (!phy->freq) { - pr_err("invalid pll_u parent rate %ld\n", parent_rate); - err = -EINVAL; - goto err1; - } - - phy->u_phy.init = tegra_phy_init; - phy->u_phy.shutdown = tegra_usb_phy_close; - phy->u_phy.set_suspend = tegra_usb_phy_suspend; - - return phy; - -err1: - clk_disable_unprepare(phy->pll_u); - clk_put(phy->pll_u); -err0: - kfree(phy); - return ERR_PTR(err); -} -EXPORT_SYMBOL_GPL(tegra_usb_phy_open); - -void tegra_usb_phy_preresume(struct usb_phy *x) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - - if (!phy->is_ulpi_phy) - utmi_phy_preresume(phy); -} -EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); - -void tegra_usb_phy_postresume(struct usb_phy *x) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - - if (!phy->is_ulpi_phy) - utmi_phy_postresume(phy); -} -EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); - -void tegra_ehci_phy_restore_start(struct usb_phy *x, - enum tegra_usb_phy_port_speed port_speed) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - - if (!phy->is_ulpi_phy) - utmi_phy_restore_start(phy, port_speed); -} -EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); - -void tegra_ehci_phy_restore_end(struct usb_phy *x) -{ - struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); - - if (!phy->is_ulpi_phy) - utmi_phy_restore_end(phy); -} -EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); - diff --git a/drivers/usb/phy/twl4030-usb.c b/drivers/usb/phy/twl4030-usb.c deleted file mode 100644 index a994715a3101..000000000000 --- a/drivers/usb/phy/twl4030-usb.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller - * - * Copyright (C) 2004-2007 Texas Instruments - * Copyright (C) 2008 Nokia Corporation - * Contact: Felipe Balbi - * - * 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. - * - * Current status: - * - HS USB ULPI mode works. - * - 3-pin mode support may be added in future. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register defines */ - -#define MCPC_CTRL 0x30 -#define MCPC_CTRL_RTSOL (1 << 7) -#define MCPC_CTRL_EXTSWR (1 << 6) -#define MCPC_CTRL_EXTSWC (1 << 5) -#define MCPC_CTRL_VOICESW (1 << 4) -#define MCPC_CTRL_OUT64K (1 << 3) -#define MCPC_CTRL_RTSCTSSW (1 << 2) -#define MCPC_CTRL_HS_UART (1 << 0) - -#define MCPC_IO_CTRL 0x33 -#define MCPC_IO_CTRL_MICBIASEN (1 << 5) -#define MCPC_IO_CTRL_CTS_NPU (1 << 4) -#define MCPC_IO_CTRL_RXD_PU (1 << 3) -#define MCPC_IO_CTRL_TXDTYP (1 << 2) -#define MCPC_IO_CTRL_CTSTYP (1 << 1) -#define MCPC_IO_CTRL_RTSTYP (1 << 0) - -#define MCPC_CTRL2 0x36 -#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) - -#define OTHER_FUNC_CTRL 0x80 -#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) -#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) - -#define OTHER_IFC_CTRL 0x83 -#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) -#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) -#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) -#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) -#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) -#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) - -#define OTHER_INT_EN_RISE 0x86 -#define OTHER_INT_EN_FALL 0x89 -#define OTHER_INT_STS 0x8C -#define OTHER_INT_LATCH 0x8D -#define OTHER_INT_VB_SESS_VLD (1 << 7) -#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ -#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ -#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ -#define OTHER_INT_MANU (1 << 1) -#define OTHER_INT_ABNORMAL_STRESS (1 << 0) - -#define ID_STATUS 0x96 -#define ID_RES_FLOAT (1 << 4) -#define ID_RES_440K (1 << 3) -#define ID_RES_200K (1 << 2) -#define ID_RES_102K (1 << 1) -#define ID_RES_GND (1 << 0) - -#define POWER_CTRL 0xAC -#define POWER_CTRL_OTG_ENAB (1 << 5) - -#define OTHER_IFC_CTRL2 0xAF -#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) -#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) -#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) - -#define REG_CTRL_EN 0xB2 -#define REG_CTRL_ERROR 0xB5 -#define ULPI_I2C_CONFLICT_INTEN (1 << 0) - -#define OTHER_FUNC_CTRL2 0xB8 -#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) - -/* following registers do not have separate _clr and _set registers */ -#define VBUS_DEBOUNCE 0xC0 -#define ID_DEBOUNCE 0xC1 -#define VBAT_TIMER 0xD3 -#define PHY_PWR_CTRL 0xFD -#define PHY_PWR_PHYPWD (1 << 0) -#define PHY_CLK_CTRL 0xFE -#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) -#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) -#define REQ_PHY_DPLL_CLK (1 << 0) -#define PHY_CLK_CTRL_STS 0xFF -#define PHY_DPLL_CLK (1 << 0) - -/* In module TWL_MODULE_PM_MASTER */ -#define STS_HW_CONDITIONS 0x0F - -/* In module TWL_MODULE_PM_RECEIVER */ -#define VUSB_DEDICATED1 0x7D -#define VUSB_DEDICATED2 0x7E -#define VUSB1V5_DEV_GRP 0x71 -#define VUSB1V5_TYPE 0x72 -#define VUSB1V5_REMAP 0x73 -#define VUSB1V8_DEV_GRP 0x74 -#define VUSB1V8_TYPE 0x75 -#define VUSB1V8_REMAP 0x76 -#define VUSB3V1_DEV_GRP 0x77 -#define VUSB3V1_TYPE 0x78 -#define VUSB3V1_REMAP 0x79 - -/* In module TWL4030_MODULE_INTBR */ -#define PMBR1 0x0D -#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) - -struct twl4030_usb { - struct usb_phy phy; - struct device *dev; - - /* TWL4030 internal USB regulator supplies */ - struct regulator *usb1v5; - struct regulator *usb1v8; - struct regulator *usb3v1; - - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - - /* pin configuration */ - enum twl4030_usb_mode usb_mode; - - int irq; - enum omap_musb_vbus_id_status linkstat; - bool vbus_supplied; - u8 asleep; - bool irq_enabled; -}; - -/* internal define on top of container_of */ -#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) - -/*-------------------------------------------------------------------------*/ - -static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, - u8 module, u8 data, u8 address) -{ - u8 check; - - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 1, module, address, check, data); - - /* Failed once: Try again */ - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 2, module, address, check, data); - - /* Failed again: Return error */ - return -EBUSY; -} - -#define twl4030_usb_write_verify(twl, address, data) \ - twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) - -static inline int twl4030_usb_write(struct twl4030_usb *twl, - u8 address, u8 data) -{ - int ret = 0; - - ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); - if (ret < 0) - dev_dbg(twl->dev, - "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); - return ret; -} - -static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) -{ - u8 data; - int ret = 0; - - ret = twl_i2c_read_u8(module, &data, address); - if (ret >= 0) - ret = data; - else - dev_dbg(twl->dev, - "TWL4030:readb[0x%x,0x%x] Error %d\n", - module, address, ret); - - return ret; -} - -static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) -{ - return twl4030_readb(twl, TWL_MODULE_USB, address); -} - -/*-------------------------------------------------------------------------*/ - -static inline int -twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_SET(reg), bits); -} - -static inline int -twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_CLR(reg), bits); -} - -/*-------------------------------------------------------------------------*/ - -static enum omap_musb_vbus_id_status - twl4030_usb_linkstat(struct twl4030_usb *twl) -{ - int status; - enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; - - twl->vbus_supplied = false; - - /* - * For ID/VBUS sensing, see manual section 15.4.8 ... - * except when using only battery backup power, two - * comparators produce VBUS_PRES and ID_PRES signals, - * which don't match docs elsewhere. But ... BIT(7) - * and BIT(2) of STS_HW_CONDITIONS, respectively, do - * seem to match up. If either is true the USB_PRES - * signal is active, the OTG module is activated, and - * its interrupt may be raised (may wake the system). - */ - status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); - if (status < 0) - dev_err(twl->dev, "USB link status err %d\n", status); - else if (status & (BIT(7) | BIT(2))) { - if (status & (BIT(7))) - twl->vbus_supplied = true; - - if (status & BIT(2)) - linkstat = OMAP_MUSB_ID_GROUND; - else - linkstat = OMAP_MUSB_VBUS_VALID; - } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) - linkstat = OMAP_MUSB_VBUS_OFF; - } - - dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", - status, status, linkstat); - - /* REVISIT this assumes host and peripheral controllers - * are registered, and that both are active... - */ - - spin_lock_irq(&twl->lock); - twl->linkstat = linkstat; - spin_unlock_irq(&twl->lock); - - return linkstat; -} - -static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) -{ - twl->usb_mode = mode; - - switch (mode) { - case T2_USB_MODE_ULPI: - twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, - ULPI_IFC_CTRL_CARKITMODE); - twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, - ULPI_FUNC_CTRL_XCVRSEL_MASK | - ULPI_FUNC_CTRL_OPMODE_MASK); - break; - case -1: - /* FIXME: power on defaults */ - break; - default: - dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", - mode); - break; - }; -} - -static void twl4030_i2c_access(struct twl4030_usb *twl, int on) -{ - unsigned long timeout; - int val = twl4030_usb_read(twl, PHY_CLK_CTRL); - - if (val >= 0) { - if (on) { - /* enable DPLL to access PHY registers over I2C */ - val |= REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - - timeout = jiffies + HZ; - while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK) - && time_before(jiffies, timeout)) - udelay(10); - if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK)) - dev_err(twl->dev, "Timeout setting T2 HSUSB " - "PHY DPLL clock\n"); - } else { - /* let ULPI control the DPLL clock */ - val &= ~REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - } - } -} - -static void __twl4030_phy_power(struct twl4030_usb *twl, int on) -{ - u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); - - if (on) - pwr &= ~PHY_PWR_PHYPWD; - else - pwr |= PHY_PWR_PHYPWD; - - WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); -} - -static void twl4030_phy_power(struct twl4030_usb *twl, int on) -{ - if (on) { - regulator_enable(twl->usb3v1); - regulator_enable(twl->usb1v8); - /* - * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP - * in twl4030) resets the VUSB_DEDICATED2 register. This reset - * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to - * SLEEP. We work around this by clearing the bit after usv3v1 - * is re-activated. This ensures that VUSB3V1 is really active. - */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); - regulator_enable(twl->usb1v5); - __twl4030_phy_power(twl, 1); - twl4030_usb_write(twl, PHY_CLK_CTRL, - twl4030_usb_read(twl, PHY_CLK_CTRL) | - (PHY_CLK_CTRL_CLOCKGATING_EN | - PHY_CLK_CTRL_CLK32K_EN)); - } else { - __twl4030_phy_power(twl, 0); - regulator_disable(twl->usb1v5); - regulator_disable(twl->usb1v8); - regulator_disable(twl->usb3v1); - } -} - -static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) -{ - if (twl->asleep) - return; - - twl4030_phy_power(twl, 0); - twl->asleep = 1; - dev_dbg(twl->dev, "%s\n", __func__); -} - -static void __twl4030_phy_resume(struct twl4030_usb *twl) -{ - twl4030_phy_power(twl, 1); - twl4030_i2c_access(twl, 1); - twl4030_usb_set_mode(twl, twl->usb_mode); - if (twl->usb_mode == T2_USB_MODE_ULPI) - twl4030_i2c_access(twl, 0); -} - -static void twl4030_phy_resume(struct twl4030_usb *twl) -{ - if (!twl->asleep) - return; - __twl4030_phy_resume(twl); - twl->asleep = 0; - dev_dbg(twl->dev, "%s\n", __func__); -} - -static int twl4030_usb_ldo_init(struct twl4030_usb *twl) -{ - /* Enable writing to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - - /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ - /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ - - /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); - - /* Initialize 3.1V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); - - twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); - if (IS_ERR(twl->usb3v1)) - return -ENODEV; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); - - /* Initialize 1.5V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); - - twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); - if (IS_ERR(twl->usb1v5)) - goto fail1; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); - - /* Initialize 1.8V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); - - twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); - if (IS_ERR(twl->usb1v8)) - goto fail2; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); - - /* disable access to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - - return 0; - -fail2: - regulator_put(twl->usb1v5); - twl->usb1v5 = NULL; -fail1: - regulator_put(twl->usb3v1); - twl->usb3v1 = NULL; - return -ENODEV; -} - -static ssize_t twl4030_usb_vbus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct twl4030_usb *twl = dev_get_drvdata(dev); - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&twl->lock, flags); - ret = sprintf(buf, "%s\n", - twl->vbus_supplied ? "on" : "off"); - spin_unlock_irqrestore(&twl->lock, flags); - - return ret; -} -static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); - -static irqreturn_t twl4030_usb_irq(int irq, void *_twl) -{ - struct twl4030_usb *twl = _twl; - enum omap_musb_vbus_id_status status; - - status = twl4030_usb_linkstat(twl); - if (status > 0) { - /* FIXME add a set_power() method so that B-devices can - * configure the charger appropriately. It's not always - * correct to consume VBUS power, and how much current to - * consume is a function of the USB configuration chosen - * by the host. - * - * REVISIT usb_gadget_vbus_connect(...) as needed, ditto - * its disconnect() sibling, when changing to/from the - * USB_LINK_VBUS state. musb_hdrc won't care until it - * starts to handle softconnect right. - */ - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) - twl4030_phy_suspend(twl, 0); - else - twl4030_phy_resume(twl); - - omap_musb_mailbox(twl->linkstat); - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); - - return IRQ_HANDLED; -} - -static void twl4030_usb_phy_init(struct twl4030_usb *twl) -{ - enum omap_musb_vbus_id_status status; - - status = twl4030_usb_linkstat(twl); - if (status > 0) { - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) { - __twl4030_phy_power(twl, 0); - twl->asleep = 1; - } else { - __twl4030_phy_resume(twl); - twl->asleep = 0; - } - - omap_musb_mailbox(twl->linkstat); - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -} - -static int twl4030_set_suspend(struct usb_phy *x, int suspend) -{ - struct twl4030_usb *twl = phy_to_twl(x); - - if (suspend) - twl4030_phy_suspend(twl, 1); - else - twl4030_phy_resume(twl); - - return 0; -} - -static int twl4030_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - if (!otg) - return -ENODEV; - - otg->gadget = gadget; - if (!gadget) - otg->phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - otg->host = host; - if (!host) - otg->phy->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int twl4030_usb_probe(struct platform_device *pdev) -{ - struct twl4030_usb_data *pdata = pdev->dev.platform_data; - struct twl4030_usb *twl; - int status, err; - struct usb_otg *otg; - struct device_node *np = pdev->dev.of_node; - - twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); - if (!twl) - return -ENOMEM; - - if (np) - of_property_read_u32(np, "usb_mode", - (enum twl4030_usb_mode *)&twl->usb_mode); - else if (pdata) - twl->usb_mode = pdata->usb_mode; - else { - dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); - return -EINVAL; - } - - otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); - if (!otg) - return -ENOMEM; - - twl->dev = &pdev->dev; - twl->irq = platform_get_irq(pdev, 0); - twl->vbus_supplied = false; - twl->asleep = 1; - twl->linkstat = OMAP_MUSB_UNKNOWN; - - twl->phy.dev = twl->dev; - twl->phy.label = "twl4030"; - twl->phy.otg = otg; - twl->phy.type = USB_PHY_TYPE_USB2; - twl->phy.set_suspend = twl4030_set_suspend; - - otg->phy = &twl->phy; - otg->set_host = twl4030_set_host; - otg->set_peripheral = twl4030_set_peripheral; - - /* init spinlock for workqueue */ - spin_lock_init(&twl->lock); - - err = twl4030_usb_ldo_init(twl); - if (err) { - dev_err(&pdev->dev, "ldo init failed\n"); - return err; - } - usb_add_phy_dev(&twl->phy); - - platform_set_drvdata(pdev, twl); - if (device_create_file(&pdev->dev, &dev_attr_vbus)) - dev_warn(&pdev->dev, "could not create sysfs file\n"); - - /* Our job is to use irqs and status from the power module - * to keep the transceiver disabled when nothing's connected. - * - * FIXME we actually shouldn't start enabling it until the - * USB controller drivers have said they're ready, by calling - * set_host() and/or set_peripheral() ... OTG_capable boards - * need both handles, otherwise just one suffices. - */ - twl->irq_enabled = true; - status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "twl4030_usb", twl); - if (status < 0) { - dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq, status); - return status; - } - - /* Power down phy or make it work according to - * current link state. - */ - twl4030_usb_phy_init(twl); - - dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); - return 0; -} - -static int __exit twl4030_usb_remove(struct platform_device *pdev) -{ - struct twl4030_usb *twl = platform_get_drvdata(pdev); - int val; - - free_irq(twl->irq, twl); - device_remove_file(twl->dev, &dev_attr_vbus); - - /* set transceiver mode to power on defaults */ - twl4030_usb_set_mode(twl, -1); - - /* autogate 60MHz ULPI clock, - * clear dpll clock request for i2c access, - * disable 32KHz - */ - val = twl4030_usb_read(twl, PHY_CLK_CTRL); - if (val >= 0) { - val |= PHY_CLK_CTRL_CLOCKGATING_EN; - val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); - twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); - } - - /* disable complete OTG block */ - twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - - if (!twl->asleep) - twl4030_phy_power(twl, 0); - regulator_put(twl->usb1v5); - regulator_put(twl->usb1v8); - regulator_put(twl->usb3v1); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id twl4030_usb_id_table[] = { - { .compatible = "ti,twl4030-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); -#endif - -static struct platform_driver twl4030_usb_driver = { - .probe = twl4030_usb_probe, - .remove = __exit_p(twl4030_usb_remove), - .driver = { - .name = "twl4030_usb", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(twl4030_usb_id_table), - }, -}; - -static int __init twl4030_usb_init(void) -{ - return platform_driver_register(&twl4030_usb_driver); -} -subsys_initcall(twl4030_usb_init); - -static void __exit twl4030_usb_exit(void) -{ - platform_driver_unregister(&twl4030_usb_driver); -} -module_exit(twl4030_usb_exit); - -MODULE_ALIAS("platform:twl4030_usb"); -MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); -MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/twl6030-usb.c b/drivers/usb/phy/twl6030-usb.c deleted file mode 100644 index 8cd6cf49bdbd..000000000000 --- a/drivers/usb/phy/twl6030-usb.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.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. - * - * Author: Hema HK - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You 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 - -/* usb register definitions */ -#define USB_VENDOR_ID_LSB 0x00 -#define USB_VENDOR_ID_MSB 0x01 -#define USB_PRODUCT_ID_LSB 0x02 -#define USB_PRODUCT_ID_MSB 0x03 -#define USB_VBUS_CTRL_SET 0x04 -#define USB_VBUS_CTRL_CLR 0x05 -#define USB_ID_CTRL_SET 0x06 -#define USB_ID_CTRL_CLR 0x07 -#define USB_VBUS_INT_SRC 0x08 -#define USB_VBUS_INT_LATCH_SET 0x09 -#define USB_VBUS_INT_LATCH_CLR 0x0A -#define USB_VBUS_INT_EN_LO_SET 0x0B -#define USB_VBUS_INT_EN_LO_CLR 0x0C -#define USB_VBUS_INT_EN_HI_SET 0x0D -#define USB_VBUS_INT_EN_HI_CLR 0x0E -#define USB_ID_INT_SRC 0x0F -#define USB_ID_INT_LATCH_SET 0x10 -#define USB_ID_INT_LATCH_CLR 0x11 - -#define USB_ID_INT_EN_LO_SET 0x12 -#define USB_ID_INT_EN_LO_CLR 0x13 -#define USB_ID_INT_EN_HI_SET 0x14 -#define USB_ID_INT_EN_HI_CLR 0x15 -#define USB_OTG_ADP_CTRL 0x16 -#define USB_OTG_ADP_HIGH 0x17 -#define USB_OTG_ADP_LOW 0x18 -#define USB_OTG_ADP_RISE 0x19 -#define USB_OTG_REVISION 0x1A - -/* to be moved to LDO */ -#define TWL6030_MISC2 0xE5 -#define TWL6030_CFG_LDO_PD2 0xF5 -#define TWL6030_BACKUP_REG 0xFA - -#define STS_HW_CONDITIONS 0x21 - -/* In module TWL6030_MODULE_PM_MASTER */ -#define STS_HW_CONDITIONS 0x21 -#define STS_USB_ID BIT(2) - -/* In module TWL6030_MODULE_PM_RECEIVER */ -#define VUSB_CFG_TRANS 0x71 -#define VUSB_CFG_STATE 0x72 -#define VUSB_CFG_VOLTAGE 0x73 - -/* in module TWL6030_MODULE_MAIN_CHARGE */ - -#define CHARGERUSB_CTRL1 0x8 - -#define CONTROLLER_STAT1 0x03 -#define VBUS_DET BIT(2) - -struct twl6030_usb { - struct phy_companion comparator; - struct device *dev; - - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - - struct regulator *usb3v3; - - /* used to set vbus, in atomic path */ - struct work_struct set_vbus_work; - - int irq1; - int irq2; - enum omap_musb_vbus_id_status linkstat; - u8 asleep; - bool irq_enabled; - bool vbus_enable; - const char *regulator; -}; - -#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator) - -/*-------------------------------------------------------------------------*/ - -static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module, - u8 data, u8 address) -{ - int ret = 0; - - ret = twl_i2c_write_u8(module, data, address); - if (ret < 0) - dev_err(twl->dev, - "Write[0x%x] Error %d\n", address, ret); - return ret; -} - -static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address) -{ - u8 data, ret = 0; - - ret = twl_i2c_read_u8(module, &data, address); - if (ret >= 0) - ret = data; - else - dev_err(twl->dev, - "readb[0x%x,0x%x] Error %d\n", - module, address, ret); - return ret; -} - -static int twl6030_start_srp(struct phy_companion *comparator) -{ - struct twl6030_usb *twl = comparator_to_twl(comparator); - - twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); - twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); - - mdelay(100); - twl6030_writeb(twl, TWL_MODULE_USB, 0xa0, USB_VBUS_CTRL_CLR); - - return 0; -} - -static int twl6030_usb_ldo_init(struct twl6030_usb *twl) -{ - /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); - - /* Program CFG_LDO_PD2 register and set VUSB bit */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2); - - /* Program MISC2 register and set bit VUSB_IN_VBAT */ - twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); - - twl->usb3v3 = regulator_get(twl->dev, twl->regulator); - if (IS_ERR(twl->usb3v3)) - return -ENODEV; - - /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ - twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); - - /* - * Program the USB_ID_CTRL_SET register to enable GND drive - * and the ID comparators - */ - twl6030_writeb(twl, TWL_MODULE_USB, 0x14, USB_ID_CTRL_SET); - - return 0; -} - -static ssize_t twl6030_usb_vbus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct twl6030_usb *twl = dev_get_drvdata(dev); - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&twl->lock, flags); - - switch (twl->linkstat) { - case OMAP_MUSB_VBUS_VALID: - ret = snprintf(buf, PAGE_SIZE, "vbus\n"); - break; - case OMAP_MUSB_ID_GROUND: - ret = snprintf(buf, PAGE_SIZE, "id\n"); - break; - case OMAP_MUSB_VBUS_OFF: - ret = snprintf(buf, PAGE_SIZE, "none\n"); - break; - default: - ret = snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); - } - spin_unlock_irqrestore(&twl->lock, flags); - - return ret; -} -static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); - -static irqreturn_t twl6030_usb_irq(int irq, void *_twl) -{ - struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; - u8 vbus_state, hw_state; - - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); - - vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, - CONTROLLER_STAT1); - if (!(hw_state & STS_USB_ID)) { - if (vbus_state & VBUS_DET) { - regulator_enable(twl->usb3v3); - twl->asleep = 1; - status = OMAP_MUSB_VBUS_VALID; - twl->linkstat = status; - omap_musb_mailbox(status); - } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) { - status = OMAP_MUSB_VBUS_OFF; - twl->linkstat = status; - omap_musb_mailbox(status); - if (twl->asleep) { - regulator_disable(twl->usb3v3); - twl->asleep = 0; - } - } - } - } - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); - - return IRQ_HANDLED; -} - -static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) -{ - struct twl6030_usb *twl = _twl; - enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; - u8 hw_state; - - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); - - if (hw_state & STS_USB_ID) { - - regulator_enable(twl->usb3v3); - twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); - status = OMAP_MUSB_ID_GROUND; - twl->linkstat = status; - omap_musb_mailbox(status); - } else { - twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); - } - twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); - - return IRQ_HANDLED; -} - -static int twl6030_enable_irq(struct twl6030_usb *twl) -{ - twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); - twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); - twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); - - twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, - REG_INT_MSK_LINE_C); - twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, - REG_INT_MSK_STS_C); - twl6030_usb_irq(twl->irq2, twl); - twl6030_usbotg_irq(twl->irq1, twl); - - return 0; -} - -static void otg_set_vbus_work(struct work_struct *data) -{ - struct twl6030_usb *twl = container_of(data, struct twl6030_usb, - set_vbus_work); - - /* - * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 - * register. This enables boost mode. - */ - - if (twl->vbus_enable) - twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, - CHARGERUSB_CTRL1); - else - twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, - CHARGERUSB_CTRL1); -} - -static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) -{ - struct twl6030_usb *twl = comparator_to_twl(comparator); - - twl->vbus_enable = enabled; - schedule_work(&twl->set_vbus_work); - - return 0; -} - -static int twl6030_usb_probe(struct platform_device *pdev) -{ - u32 ret; - struct twl6030_usb *twl; - int status, err; - struct device_node *np = pdev->dev.of_node; - struct device *dev = &pdev->dev; - struct twl4030_usb_data *pdata = dev->platform_data; - - twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); - if (!twl) - return -ENOMEM; - - twl->dev = &pdev->dev; - twl->irq1 = platform_get_irq(pdev, 0); - twl->irq2 = platform_get_irq(pdev, 1); - twl->linkstat = OMAP_MUSB_UNKNOWN; - - twl->comparator.set_vbus = twl6030_set_vbus; - twl->comparator.start_srp = twl6030_start_srp; - - ret = omap_usb2_set_comparator(&twl->comparator); - if (ret == -ENODEV) { - dev_info(&pdev->dev, "phy not ready, deferring probe"); - return -EPROBE_DEFER; - } - - if (np) { - twl->regulator = "usb"; - } else if (pdata) { - if (pdata->features & TWL6025_SUBCLASS) - twl->regulator = "ldousb"; - else - twl->regulator = "vusb"; - } else { - dev_err(&pdev->dev, "twl6030 initialized without pdata\n"); - return -EINVAL; - } - - /* init spinlock for workqueue */ - spin_lock_init(&twl->lock); - - err = twl6030_usb_ldo_init(twl); - if (err) { - dev_err(&pdev->dev, "ldo init failed\n"); - return err; - } - - platform_set_drvdata(pdev, twl); - if (device_create_file(&pdev->dev, &dev_attr_vbus)) - dev_warn(&pdev->dev, "could not create sysfs file\n"); - - INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); - - twl->irq_enabled = true; - status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "twl6030_usb", twl); - if (status < 0) { - dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq1, status); - device_remove_file(twl->dev, &dev_attr_vbus); - return status; - } - - status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "twl6030_usb", twl); - if (status < 0) { - dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq2, status); - free_irq(twl->irq1, twl); - device_remove_file(twl->dev, &dev_attr_vbus); - return status; - } - - twl->asleep = 0; - twl6030_enable_irq(twl); - dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); - - return 0; -} - -static int __exit twl6030_usb_remove(struct platform_device *pdev) -{ - struct twl6030_usb *twl = platform_get_drvdata(pdev); - - twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, - REG_INT_MSK_LINE_C); - twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, - REG_INT_MSK_STS_C); - free_irq(twl->irq1, twl); - free_irq(twl->irq2, twl); - regulator_put(twl->usb3v3); - device_remove_file(twl->dev, &dev_attr_vbus); - cancel_work_sync(&twl->set_vbus_work); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id twl6030_usb_id_table[] = { - { .compatible = "ti,twl6030-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); -#endif - -static struct platform_driver twl6030_usb_driver = { - .probe = twl6030_usb_probe, - .remove = __exit_p(twl6030_usb_remove), - .driver = { - .name = "twl6030_usb", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(twl6030_usb_id_table), - }, -}; - -static int __init twl6030_usb_init(void) -{ - return platform_driver_register(&twl6030_usb_driver); -} -subsys_initcall(twl6030_usb_init); - -static void __exit twl6030_usb_exit(void) -{ - platform_driver_unregister(&twl6030_usb_driver); -} -module_exit(twl6030_usb_exit); - -MODULE_ALIAS("platform:twl6030_usb"); -MODULE_AUTHOR("Hema HK "); -MODULE_DESCRIPTION("TWL6030 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/ulpi.c b/drivers/usb/phy/ulpi.c deleted file mode 100644 index 217339dd7a90..000000000000 --- a/drivers/usb/phy/ulpi.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Generic ULPI USB transceiver support - * - * Copyright (C) 2009 Daniel Mack - * - * Based on sources from - * - * Sascha Hauer - * Freescale Semiconductors - * - * 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 - - -struct ulpi_info { - unsigned int id; - char *name; -}; - -#define ULPI_ID(vendor, product) (((vendor) << 16) | (product)) -#define ULPI_INFO(_id, _name) \ - { \ - .id = (_id), \ - .name = (_name), \ - } - -/* ULPI hardcoded IDs, used for probing */ -static struct ulpi_info ulpi_ids[] = { - ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), - ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), -}; - -static int ulpi_set_otg_flags(struct usb_phy *phy) -{ - unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN | - ULPI_OTG_CTRL_DM_PULLDOWN; - - if (phy->flags & ULPI_OTG_ID_PULLUP) - flags |= ULPI_OTG_CTRL_ID_PULLUP; - - /* - * ULPI Specification rev.1.1 default - * for Dp/DmPulldown is enabled. - */ - if (phy->flags & ULPI_OTG_DP_PULLDOWN_DIS) - flags &= ~ULPI_OTG_CTRL_DP_PULLDOWN; - - if (phy->flags & ULPI_OTG_DM_PULLDOWN_DIS) - flags &= ~ULPI_OTG_CTRL_DM_PULLDOWN; - - if (phy->flags & ULPI_OTG_EXTVBUSIND) - flags |= ULPI_OTG_CTRL_EXTVBUSIND; - - return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); -} - -static int ulpi_set_fc_flags(struct usb_phy *phy) -{ - unsigned int flags = 0; - - /* - * ULPI Specification rev.1.1 default - * for XcvrSelect is Full Speed. - */ - if (phy->flags & ULPI_FC_HS) - flags |= ULPI_FUNC_CTRL_HIGH_SPEED; - else if (phy->flags & ULPI_FC_LS) - flags |= ULPI_FUNC_CTRL_LOW_SPEED; - else if (phy->flags & ULPI_FC_FS4LS) - flags |= ULPI_FUNC_CTRL_FS4LS; - else - flags |= ULPI_FUNC_CTRL_FULL_SPEED; - - if (phy->flags & ULPI_FC_TERMSEL) - flags |= ULPI_FUNC_CTRL_TERMSELECT; - - /* - * ULPI Specification rev.1.1 default - * for OpMode is Normal Operation. - */ - if (phy->flags & ULPI_FC_OP_NODRV) - flags |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - else if (phy->flags & ULPI_FC_OP_DIS_NRZI) - flags |= ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI; - else if (phy->flags & ULPI_FC_OP_NSYNC_NEOP) - flags |= ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP; - else - flags |= ULPI_FUNC_CTRL_OPMODE_NORMAL; - - /* - * ULPI Specification rev.1.1 default - * for SuspendM is Powered. - */ - flags |= ULPI_FUNC_CTRL_SUSPENDM; - - return usb_phy_io_write(phy, flags, ULPI_FUNC_CTRL); -} - -static int ulpi_set_ic_flags(struct usb_phy *phy) -{ - unsigned int flags = 0; - - if (phy->flags & ULPI_IC_AUTORESUME) - flags |= ULPI_IFC_CTRL_AUTORESUME; - - if (phy->flags & ULPI_IC_EXTVBUS_INDINV) - flags |= ULPI_IFC_CTRL_EXTERNAL_VBUS; - - if (phy->flags & ULPI_IC_IND_PASSTHRU) - flags |= ULPI_IFC_CTRL_PASSTHRU; - - if (phy->flags & ULPI_IC_PROTECT_DIS) - flags |= ULPI_IFC_CTRL_PROTECT_IFC_DISABLE; - - return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); -} - -static int ulpi_set_flags(struct usb_phy *phy) -{ - int ret; - - ret = ulpi_set_otg_flags(phy); - if (ret) - return ret; - - ret = ulpi_set_ic_flags(phy); - if (ret) - return ret; - - return ulpi_set_fc_flags(phy); -} - -static int ulpi_check_integrity(struct usb_phy *phy) -{ - int ret, i; - unsigned int val = 0x55; - - for (i = 0; i < 2; i++) { - ret = usb_phy_io_write(phy, val, ULPI_SCRATCH); - if (ret < 0) - return ret; - - ret = usb_phy_io_read(phy, ULPI_SCRATCH); - if (ret < 0) - return ret; - - if (ret != val) { - pr_err("ULPI integrity check: failed!"); - return -ENODEV; - } - val = val << 1; - } - - pr_info("ULPI integrity check: passed.\n"); - - return 0; -} - -static int ulpi_init(struct usb_phy *phy) -{ - int i, vid, pid, ret; - u32 ulpi_id = 0; - - for (i = 0; i < 4; i++) { - ret = usb_phy_io_read(phy, ULPI_PRODUCT_ID_HIGH - i); - if (ret < 0) - return ret; - ulpi_id = (ulpi_id << 8) | ret; - } - vid = ulpi_id & 0xffff; - pid = ulpi_id >> 16; - - pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); - - for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) { - if (ulpi_ids[i].id == ULPI_ID(vid, pid)) { - pr_info("Found %s ULPI transceiver.\n", - ulpi_ids[i].name); - break; - } - } - - ret = ulpi_check_integrity(phy); - if (ret) - return ret; - - return ulpi_set_flags(phy); -} - -static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - struct usb_phy *phy = otg->phy; - unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); - - if (!host) { - otg->host = NULL; - return 0; - } - - otg->host = host; - - flags &= ~(ULPI_IFC_CTRL_6_PIN_SERIAL_MODE | - ULPI_IFC_CTRL_3_PIN_SERIAL_MODE | - ULPI_IFC_CTRL_CARKITMODE); - - if (phy->flags & ULPI_IC_6PIN_SERIAL) - flags |= ULPI_IFC_CTRL_6_PIN_SERIAL_MODE; - else if (phy->flags & ULPI_IC_3PIN_SERIAL) - flags |= ULPI_IFC_CTRL_3_PIN_SERIAL_MODE; - else if (phy->flags & ULPI_IC_CARKIT) - flags |= ULPI_IFC_CTRL_CARKITMODE; - - return usb_phy_io_write(phy, flags, ULPI_IFC_CTRL); -} - -static int ulpi_set_vbus(struct usb_otg *otg, bool on) -{ - struct usb_phy *phy = otg->phy; - unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); - - flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); - - if (on) { - if (phy->flags & ULPI_OTG_DRVVBUS) - flags |= ULPI_OTG_CTRL_DRVVBUS; - - if (phy->flags & ULPI_OTG_DRVVBUS_EXT) - flags |= ULPI_OTG_CTRL_DRVVBUS_EXT; - } - - return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL); -} - -struct usb_phy * -otg_ulpi_create(struct usb_phy_io_ops *ops, - unsigned int flags) -{ - struct usb_phy *phy; - struct usb_otg *otg; - - phy = kzalloc(sizeof(*phy), GFP_KERNEL); - if (!phy) - return NULL; - - otg = kzalloc(sizeof(*otg), GFP_KERNEL); - if (!otg) { - kfree(phy); - return NULL; - } - - phy->label = "ULPI"; - phy->flags = flags; - phy->io_ops = ops; - phy->otg = otg; - phy->init = ulpi_init; - - otg->phy = phy; - otg->set_host = ulpi_set_host; - otg->set_vbus = ulpi_set_vbus; - - return phy; -} -EXPORT_SYMBOL_GPL(otg_ulpi_create); - diff --git a/drivers/usb/phy/ulpi_viewport.c b/drivers/usb/phy/ulpi_viewport.c deleted file mode 100644 index c5ba7e5423fc..000000000000 --- a/drivers/usb/phy/ulpi_viewport.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011 Google, Inc. - * - * 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 - -#define ULPI_VIEW_WAKEUP (1 << 31) -#define ULPI_VIEW_RUN (1 << 30) -#define ULPI_VIEW_WRITE (1 << 29) -#define ULPI_VIEW_READ (0 << 29) -#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) -#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) -#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) - -static int ulpi_viewport_wait(void __iomem *view, u32 mask) -{ - unsigned long usec = 2000; - - while (usec--) { - if (!(readl(view) & mask)) - return 0; - - udelay(1); - }; - - return -ETIMEDOUT; -} - -static int ulpi_viewport_read(struct usb_phy *otg, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); - if (ret) - return ret; - - return ULPI_VIEW_DATA_READ(readl(view)); -} - -static int ulpi_viewport_write(struct usb_phy *otg, u32 val, u32 reg) -{ - int ret; - void __iomem *view = otg->io_priv; - - writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); - ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); - if (ret) - return ret; - - writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | - ULPI_VIEW_ADDR(reg), view); - - return ulpi_viewport_wait(view, ULPI_VIEW_RUN); -} - -struct usb_phy_io_ops ulpi_viewport_access_ops = { - .read = ulpi_viewport_read, - .write = ulpi_viewport_write, -}; -- cgit From 790d3a5ab6e36fb06e99339afe35ecdec4d3b2cb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Mar 2013 13:01:40 +0200 Subject: usb: phy: isp1301: give it a context structure this patch is a small preparation to fix isp1301 driver so that other platforms can use it. We're defining our private data structure to represent this device and adding the PHY to the PHY list. Later patches will come implementing proper PHY API and removing bogus code from ohci_nxp and lpc32xx_udc drivers. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-isp1301.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 18dbf7e37607..5e0f14369145 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -11,10 +11,19 @@ */ #include +#include #include +#include #define DRV_NAME "isp1301" +struct isp1301 { + struct usb_phy phy; + struct mutex mutex; + + struct i2c_client *client; +}; + static const struct i2c_device_id isp1301_id[] = { { "isp1301", 0 }, { } @@ -25,12 +34,35 @@ static struct i2c_client *isp1301_i2c_client; static int isp1301_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { + struct isp1301 *isp; + struct usb_phy *phy; + + isp = devm_kzalloc(&client->dev, sizeof(*isp), GFP_KERNEL); + if (!isp) + return -ENOMEM; + + isp->client = client; + mutex_init(&isp->mutex); + + phy = &isp->phy; + phy->label = DRV_NAME; + phy->type = USB_PHY_TYPE_USB2; + + i2c_set_clientdata(client, isp); + usb_add_phy_dev(phy); + isp1301_i2c_client = client; + return 0; } static int isp1301_remove(struct i2c_client *client) { + struct isp1301 *isp = i2c_get_clientdata(client); + + usb_remove_phy(&isp->phy); + isp1301_i2c_client = NULL; + return 0; } -- cgit From c38a4f3f508d47e51c3f28e8946b1482ebf47fee Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Mar 2013 13:25:18 +0200 Subject: usb: phy: isp1301: implement PHY API this patch implements ->init() and ->set_vbus() methods for isp1301 transceiver driver. Later patches can now come in order to remove the hackery from ohci-nxp and lpc32xx udc drivers. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-isp1301.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 5e0f14369145..225ae6c97eeb 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -14,6 +14,7 @@ #include #include #include +#include #define DRV_NAME "isp1301" @@ -24,6 +25,8 @@ struct isp1301 { struct i2c_client *client; }; +#define phy_to_isp(p) (container_of((p), struct isp1301, phy)) + static const struct i2c_device_id isp1301_id[] = { { "isp1301", 0 }, { } @@ -31,6 +34,60 @@ static const struct i2c_device_id isp1301_id[] = { static struct i2c_client *isp1301_i2c_client; +static int __isp1301_write(struct isp1301 *isp, u8 reg, u8 value, u8 clear) +{ + return i2c_smbus_write_byte_data(isp->client, reg | clear, value); +} + +static int isp1301_write(struct isp1301 *isp, u8 reg, u8 value) +{ + return __isp1301_write(isp, reg, value, 0); +} + +static int isp1301_clear(struct isp1301 *isp, u8 reg, u8 value) +{ + return __isp1301_write(isp, reg, value, ISP1301_I2C_REG_CLEAR_ADDR); +} + +static int isp1301_phy_init(struct usb_phy *phy) +{ + struct isp1301 *isp = phy_to_isp(phy); + + /* Disable transparent UART mode first */ + isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_UART_EN); + isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, ~MC1_SPEED_REG); + isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG); + isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_2, ~0); + isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_PSW_EN + | MC2_SPD_SUSP_CTRL)); + + isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, ~0); + isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0); + isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLDOWN + | OTG1_DP_PULLDOWN)); + isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLUP + | OTG1_DP_PULLUP)); + + /* mask all interrupts */ + isp1301_clear(isp, ISP1301_I2C_INTERRUPT_LATCH, ~0); + isp1301_clear(isp, ISP1301_I2C_INTERRUPT_FALLING, ~0); + isp1301_clear(isp, ISP1301_I2C_INTERRUPT_RISING, ~0); + + return 0; +} + +static int isp1301_phy_set_vbus(struct usb_phy *phy, int on) +{ + struct isp1301 *isp = phy_to_isp(phy); + + if (on) + isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV); + else + isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV); + + return 0; +} + static int isp1301_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { @@ -46,6 +103,8 @@ static int isp1301_probe(struct i2c_client *client, phy = &isp->phy; phy->label = DRV_NAME; + phy->init = isp1301_phy_init; + phy->set_vbus = isp1301_phy_set_vbus; phy->type = USB_PHY_TYPE_USB2; i2c_set_clientdata(client, isp); -- cgit From 38678f25689c6ee90b443407dba04fb8c0297db3 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Mon, 11 Mar 2013 18:28:02 +0800 Subject: usb: gadget: s3c-hsudc: delete outdated comment since commit d93e260 (usb: gadget: s3c-hsudc: use udc_start and udc_stop functions) the 'driver' parameter has been deleted from s3c_hsudc_stop_activity() but its documentation was left outdated. This patch deletes the comment since it makes no sense anymore. Signed-off-by: Chen Gang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index bfe79103abab..b1f0771fbd3d 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -283,7 +283,6 @@ static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status) /** * s3c_hsudc_stop_activity - Stop activity on all endpoints. * @hsudc: Device controller for which EP activity is to be stopped. - * @driver: Reference to the gadget driver which is currently active. * * All the endpoints are stopped and any pending transfer requests if any on * the endpoint are terminated. -- cgit From 662e9469cbd736e9e0cd72468f3d62e75b159464 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 10:45:02 +0200 Subject: usb: gadget: atmel: remove unused DMA_ADDR_INVALID DMA_ADDR_INVALID isn't (and shouldn't) be used anymore, let's remove it. Acked-by: Nicolas Ferre Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index 9791259cbda7..d65a61851d3d 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h @@ -216,12 +216,6 @@ #define EP0_EPT_SIZE USBA_EPT_SIZE_64 #define EP0_NR_BANKS 1 -/* - * REVISIT: Try to eliminate this value. Can we rely on req->mapped to - * provide this information? - */ -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - #define FIFO_IOMEM_ID 0 #define CTRL_IOMEM_ID 1 -- cgit From c36cbfc045bf6e812fa3b9e898603ff45316f369 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 10:45:42 +0200 Subject: usb: gadget: net2272: remove unused DMA_ADDR_INVALID DMA_ADDR_INVALID isn't used anymore, it's safe to remove it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 8dcbe770e2d4..03e41049ed30 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -58,7 +58,6 @@ static const char * const ep_name[] = { "ep-a", "ep-b", "ep-c", }; -#define DMA_ADDR_INVALID (~(dma_addr_t)0) #ifdef CONFIG_USB_GADGET_NET2272_DMA /* * use_dma: the NET2272 can use an external DMA controller. @@ -341,7 +340,6 @@ net2272_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) if (!req) return NULL; - req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); return &req->req; -- cgit From 853f97b5f3886012d293257db74d65b14f958940 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 10:46:19 +0200 Subject: usb: gadget: net2280: remove unused DMA_ADDR_INVALID DMA_ADDR_INVALID isn't used anymore, it's safe to remove it. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index e5f2ef184367..691cc658ddf9 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -65,7 +65,6 @@ #define DRIVER_DESC "PLX NET228x USB Peripheral Controller" #define DRIVER_VERSION "2005 Sept 27" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ #define USE_RDK_LEDS /* GPIO pins control three LEDs */ @@ -406,7 +405,6 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) if (!req) return NULL; - req->req.dma = DMA_ADDR_INVALID; INIT_LIST_HEAD (&req->queue); /* this dma descriptor may be swapped with the previous dummy */ @@ -420,7 +418,6 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) return NULL; } td->dmacount = 0; /* not VALID */ - td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); td->dmadesc = td->dmaaddr; req->td = td; } @@ -2788,7 +2785,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) goto done; } td->dmacount = 0; /* not VALID */ - td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); td->dmadesc = td->dmaaddr; dev->ep [i].dummy = td; } -- cgit From 482ef1d2fec5e5d44d97f7e20b4ccf3d3604aaae Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 10:48:02 +0200 Subject: usb: gadget: uvc: remove references to DMA_ADDR_INVALID gadget drivers shouldn't touch req->dma at all, since UDC drivers are the ones required to handle mapping and unmapping of the request buffer. Remove references to DMA_ADDR_INVALID so we don't creat false expectations to gadget driver writers. Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc.h | 2 -- drivers/usb/gadget/uvc_v4l2.c | 1 - drivers/usb/gadget/uvc_video.c | 1 - 3 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index 93b0c1191115..7e90b1d12d09 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -98,8 +98,6 @@ extern unsigned int uvc_gadget_trace_param; #define DRIVER_VERSION "0.1.0" #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - #define UVC_NUM_REQUESTS 4 #define UVC_MAX_REQUEST_SIZE 64 #define UVC_MAX_EVENTS 4 diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2ca9386d655b..0080d073bd5e 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -41,7 +41,6 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) req->length = min_t(unsigned int, uvc->event_length, data->length); req->zero = data->length < uvc->event_length; - req->dma = DMA_ADDR_INVALID; memcpy(req->buf, data->data, data->length); diff --git a/drivers/usb/gadget/uvc_video.c b/drivers/usb/gadget/uvc_video.c index b0e53a8ea4f7..885c393ee470 100644 --- a/drivers/usb/gadget/uvc_video.c +++ b/drivers/usb/gadget/uvc_video.c @@ -245,7 +245,6 @@ uvc_video_alloc_requests(struct uvc_video *video) video->req[i]->buf = video->req_buffer[i]; video->req[i]->length = 0; - video->req[i]->dma = DMA_ADDR_INVALID; video->req[i]->complete = uvc_video_complete; video->req[i]->context = video; -- cgit From 40b8156f9426db48d5d648cdc95bd0789981e9f4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 10:49:13 +0200 Subject: usb: renesas: remove unused DMA_ADDR_INVALID DMA_ADDR_INVALID isn't used anymore, it's safe to remove it. Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 1 - drivers/usb/renesas_usbhs/fifo.h | 2 -- 2 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 9538f0feafe2..45b94019aec8 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -32,7 +32,6 @@ */ void usbhs_pkt_init(struct usbhs_pkt *pkt) { - pkt->dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&pkt->node); } diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index c31731a843d1..a168a1760fce 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h @@ -23,8 +23,6 @@ #include #include "pipe.h" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - struct usbhs_fifo { char *name; u32 port; /* xFIFO */ -- cgit From d4436c3a6e4ea3000b794eb61e0fc1db46d14175 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Thu, 14 Mar 2013 16:05:24 +0530 Subject: usb: dwc3: core: fix wrong OTG event regitser offset This patch fixes the wrong OTG_EVT,OTG_EVTEN and OTG_STS register offsets. While at that, also add a missing register to debugfs regdump utility. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 5 +++-- drivers/usb/dwc3/debugfs.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b42f71cb87dd..b69d322e3cab 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -154,8 +154,9 @@ /* OTG Registers */ #define DWC3_OCFG 0xcc00 #define DWC3_OCTL 0xcc04 -#define DWC3_OEVTEN 0xcc08 -#define DWC3_OSTS 0xcc0C +#define DWC3_OEVT 0xcc08 +#define DWC3_OEVTEN 0xcc0C +#define DWC3_OSTS 0xcc10 /* Bit fields */ diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 8b23d0455b1c..9e9f122162f2 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -372,6 +372,7 @@ static const struct debugfs_reg32 dwc3_regs[] = { dump_register(OCFG), dump_register(OCTL), + dump_register(OEVT), dump_register(OEVTEN), dump_register(OSTS), }; -- cgit From ddff14f1ab9b55b73ba59126ef4a10966725fc9d Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 7 Mar 2013 18:51:43 +0530 Subject: usb: dwc3: set dma_mask for dwc3_omap device *dma_mask* is not set for devices created from dt data. So filled dma_mask for dwc3_omap device here. And dwc3 core will copy the dma_mask from its parent. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 4 ++++ drivers/usb/dwc3/dwc3-omap.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 66c05725daf3..c845e7087069 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -454,6 +454,10 @@ static int dwc3_probe(struct platform_device *pdev) dwc->regs_size = resource_size(res); dwc->dev = dev; + dev->dma_mask = dev->parent->dma_mask; + dev->dma_parms = dev->parent->dma_parms; + dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); + if (!strncmp("super", maximum_speed, 5)) dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; else if (!strncmp("high", maximum_speed, 4)) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 35b9673b84df..546f1fd84920 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -277,6 +277,8 @@ static void dwc3_omap_disable_irqs(struct dwc3_omap *omap) dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, 0x00); } +static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32); + static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -330,6 +332,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) omap->dev = dev; omap->irq = irq; omap->base = base; + dev->dma_mask = &dwc3_omap_dma_mask; /* * REVISIT if we ever have two instances of the wrapper, we will be -- cgit From 2ba7943af0f0cca5a069cd3aff807815bc76fff1 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 7 Mar 2013 18:51:44 +0530 Subject: usb: dwc3: dwc3-omap: return -EPROBE_DEFER if probe has not yet executed return -EPROBE_DEFER from dwc3_omap_mailbox in dwc3-omap.c, if the probe of dwc3-omap has not yet been executed or failed. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 7 +++++-- include/linux/usb/dwc3-omap.h | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 546f1fd84920..2fe9723ff1df 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -138,11 +138,14 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) writel(value, base + offset); } -void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) +int dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) { u32 val; struct dwc3_omap *omap = _omap; + if (!omap) + return -EPROBE_DEFER; + switch (status) { case OMAP_DWC3_ID_GROUND: dev_dbg(omap->dev, "ID GND\n"); @@ -185,7 +188,7 @@ void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) dev_dbg(omap->dev, "ID float\n"); } - return; + return 0; } EXPORT_SYMBOL_GPL(dwc3_omap_mailbox); diff --git a/include/linux/usb/dwc3-omap.h b/include/linux/usb/dwc3-omap.h index 51eae14477f7..5615f4d82724 100644 --- a/include/linux/usb/dwc3-omap.h +++ b/include/linux/usb/dwc3-omap.h @@ -19,11 +19,11 @@ enum omap_dwc3_vbus_id_status { }; #if (defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_DWC3_MODULE)) -extern void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status); +extern int dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status); #else -static inline void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) +static inline int dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) { - return; + return -ENODEV; } #endif -- cgit From dc2377d0b0a298ec9d7d232c0d757f462dedcca2 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 14 Mar 2013 15:59:10 +0530 Subject: usb: phy: samsung: Common out the generic stuff Moving register and structure definitions to header file, and keeping the generic functions to be used across multiple PHYs in common phy helper driver under SAMSUNG_USBPHY, and moving USB 2.0 PHY driver under SAMSUNG_USB2PHY. Also allowing samsung PHY drivers be built as modules. Signed-off-by: Vivek Gautam Acked-by: Kukjin Kim Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/samsung-usbphy.txt | 22 +- drivers/usb/phy/Kconfig | 15 +- drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy-samsung-usb.c | 726 +-------------------- drivers/usb/phy/phy-samsung-usb.h | 247 +++++++ drivers/usb/phy/phy-samsung-usb2.c | 509 +++++++++++++++ 6 files changed, 800 insertions(+), 720 deletions(-) create mode 100644 drivers/usb/phy/phy-samsung-usb.h create mode 100644 drivers/usb/phy/phy-samsung-usb2.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt index 033194934f64..96940abe9a57 100644 --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt @@ -1,20 +1,25 @@ -* Samsung's usb phy transceiver +SAMSUNG USB-PHY controllers -The Samsung's phy transceiver is used for controlling usb phy for -s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers -across Samsung SOCs. +** Samsung's usb 2.0 phy transceiver + +The Samsung's usb 2.0 phy transceiver is used for controlling +usb 2.0 phy for s3c-hsotg as well as ehci-s5p and ohci-exynos +usb controllers across Samsung SOCs. TODO: Adding the PHY binding with controller(s) according to the under developement generic PHY driver. Required properties: Exynos4210: -- compatible : should be "samsung,exynos4210-usbphy" +- compatible : should be "samsung,exynos4210-usb2phy" - reg : base physical address of the phy registers and length of memory mapped region. +- clocks: Clock IDs array as required by the controller. +- clock-names: names of clock correseponding IDs clock property as requested + by the controller driver. Exynos5250: -- compatible : should be "samsung,exynos5250-usbphy" +- compatible : should be "samsung,exynos5250-usb2phy" - reg : base physical address of the phy registers and length of memory mapped region. @@ -44,10 +49,13 @@ Example: usbphy@125B0000 { #address-cells = <1>; #size-cells = <1>; - compatible = "samsung,exynos4210-usbphy"; + compatible = "samsung,exynos4210-usb2phy"; reg = <0x125B0000 0x100>; ranges; + clocks = <&clock 2>, <&clock 305>; + clock-names = "xusbxti", "otg"; + usbphy-sys { /* USB device and host PHY_CONTROL registers */ reg = <0x10020704 0x8>; diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 97de6de9b4b9..e8cd52ac5c05 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -86,11 +86,18 @@ config OMAP_USB3 on/off the PHY. config SAMSUNG_USBPHY - bool "Samsung USB PHY controller Driver" - depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS + tristate "Samsung USB PHY Driver" help - Enable this to support Samsung USB phy controller for samsung - SoCs. + Enable this to support Samsung USB phy helper driver for Samsung SoCs. + This driver provides common interface to interact, for Samsung USB 2.0 PHY + driver and later for Samsung USB 3.0 PHY driver. + +config SAMSUNG_USB2PHY + tristate "Samsung USB 2.0 PHY controller Driver" + select SAMSUNG_USBPHY + help + Enable this to support Samsung USB 2.0 (High Speed) PHY controller + driver for Samsung SoCs. config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 5fb4a5d55945..8cd355f051f6 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o +obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c index 967101ec15fd..7b118ee5f5e4 100644 --- a/drivers/usb/phy/phy-samsung-usb.c +++ b/drivers/usb/phy/phy-samsung-usb.c @@ -1,12 +1,13 @@ -/* linux/drivers/usb/phy/samsung-usbphy.c +/* linux/drivers/usb/phy/phy-samsung-usb.c * * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * * Author: Praveen Paneri * - * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and - * OHCI-EXYNOS controllers. + * Samsung USB-PHY helper driver with common function calls; + * interacts with Samsung USB 2.0 PHY controller driver and later + * with Samsung USB 3.0 PHY driver. * * 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 @@ -21,233 +22,16 @@ #include #include #include -#include #include #include #include #include #include -#include #include -#include -/* Register definitions */ +#include "phy-samsung-usb.h" -#define SAMSUNG_PHYPWR (0x00) - -#define PHYPWR_NORMAL_MASK (0x19 << 0) -#define PHYPWR_OTG_DISABLE (0x1 << 4) -#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) -#define PHYPWR_FORCE_SUSPEND (0x1 << 1) -/* For Exynos4 */ -#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0) -#define PHYPWR_SLEEP_PHY0 (0x1 << 5) - -#define SAMSUNG_PHYCLK (0x04) - -#define PHYCLK_MODE_USB11 (0x1 << 6) -#define PHYCLK_EXT_OSC (0x1 << 5) -#define PHYCLK_COMMON_ON_N (0x1 << 4) -#define PHYCLK_ID_PULL (0x1 << 2) -#define PHYCLK_CLKSEL_MASK (0x3 << 0) -#define PHYCLK_CLKSEL_48M (0x0 << 0) -#define PHYCLK_CLKSEL_12M (0x2 << 0) -#define PHYCLK_CLKSEL_24M (0x3 << 0) - -#define SAMSUNG_RSTCON (0x08) - -#define RSTCON_PHYLINK_SWRST (0x1 << 2) -#define RSTCON_HLINK_SWRST (0x1 << 1) -#define RSTCON_SWRST (0x1 << 0) - -/* EXYNOS5 */ -#define EXYNOS5_PHY_HOST_CTRL0 (0x00) - -#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) - -#define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) -#define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) -#define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) -#define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) - -#define HOST_CTRL0_FSEL_MASK (0x7 << 16) -#define HOST_CTRL0_FSEL(_x) ((_x) << 16) - -#define FSEL_CLKSEL_50M (0x7) -#define FSEL_CLKSEL_24M (0x5) -#define FSEL_CLKSEL_20M (0x4) -#define FSEL_CLKSEL_19200K (0x3) -#define FSEL_CLKSEL_12M (0x2) -#define FSEL_CLKSEL_10M (0x1) -#define FSEL_CLKSEL_9600K (0x0) - -#define HOST_CTRL0_TESTBURNIN (0x1 << 11) -#define HOST_CTRL0_RETENABLE (0x1 << 10) -#define HOST_CTRL0_COMMONON_N (0x1 << 9) -#define HOST_CTRL0_SIDDQ (0x1 << 6) -#define HOST_CTRL0_FORCESLEEP (0x1 << 5) -#define HOST_CTRL0_FORCESUSPEND (0x1 << 4) -#define HOST_CTRL0_WORDINTERFACE (0x1 << 3) -#define HOST_CTRL0_UTMISWRST (0x1 << 2) -#define HOST_CTRL0_LINKSWRST (0x1 << 1) -#define HOST_CTRL0_PHYSWRST (0x1 << 0) - -#define EXYNOS5_PHY_HOST_TUNE0 (0x04) - -#define EXYNOS5_PHY_HSIC_CTRL1 (0x10) - -#define EXYNOS5_PHY_HSIC_TUNE1 (0x14) - -#define EXYNOS5_PHY_HSIC_CTRL2 (0x20) - -#define EXYNOS5_PHY_HSIC_TUNE2 (0x24) - -#define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) -#define HSIC_CTRL_REFCLKSEL (0x2 << 23) - -#define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) -#define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) -#define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) -#define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16) -#define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) -#define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) -#define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) - -#define HSIC_CTRL_SIDDQ (0x1 << 6) -#define HSIC_CTRL_FORCESLEEP (0x1 << 5) -#define HSIC_CTRL_FORCESUSPEND (0x1 << 4) -#define HSIC_CTRL_WORDINTERFACE (0x1 << 3) -#define HSIC_CTRL_UTMISWRST (0x1 << 2) -#define HSIC_CTRL_PHYSWRST (0x1 << 0) - -#define EXYNOS5_PHY_HOST_EHCICTRL (0x30) - -#define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) -#define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) -#define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) -#define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) - -#define EXYNOS5_PHY_HOST_OHCICTRL (0x34) - -#define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) -#define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) -#define HOST_OHCICTRL_CNTSEL (0x1 << 1) -#define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) - -#define EXYNOS5_PHY_OTG_SYS (0x38) - -#define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) -#define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) -#define OTG_SYS_PHY0_SWRST (0x1 << 12) - -#define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) -#define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) -#define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) -#define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) - -#define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) -#define OTG_SYS_COMMON_ON (0x1 << 7) - -#define OTG_SYS_FSEL_MASK (0x7 << 4) -#define OTG_SYS_FSEL(_x) ((_x) << 4) - -#define OTG_SYS_FORCESLEEP (0x1 << 3) -#define OTG_SYS_OTGDISABLE (0x1 << 2) -#define OTG_SYS_SIDDQ_UOTG (0x1 << 1) -#define OTG_SYS_FORCESUSPEND (0x1 << 0) - -#define EXYNOS5_PHY_OTG_TUNE (0x40) - -#ifndef MHZ -#define MHZ (1000*1000) -#endif - -#ifndef KHZ -#define KHZ (1000) -#endif - -#define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4) -#define S3C64XX_USBPHY_ENABLE (0x1 << 16) -#define EXYNOS_USBPHY_ENABLE (0x1 << 0) -#define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0) - -enum samsung_cpu_type { - TYPE_S3C64XX, - TYPE_EXYNOS4210, - TYPE_EXYNOS5250, -}; - -/* - * struct samsung_usbphy_drvdata - driver data for various SoC variants - * @cpu_type: machine identifier - * @devphy_en_mask: device phy enable mask for PHY CONTROL register - * @hostphy_en_mask: host phy enable mask for PHY CONTROL register - * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from - * mapped address of system controller. - * @hostphy_reg_offset: offset to HOST PHY CONTROL register from - * mapped address of system controller. - * - * Here we have a separate mask for device type phy. - * Having different masks for host and device type phy helps - * in setting independent masks in case of SoCs like S5PV210, - * in which PHY0 and PHY1 enable bits belong to same register - * placed at position 0 and 1 respectively. - * Although for newer SoCs like exynos these bits belong to - * different registers altogether placed at position 0. - */ -struct samsung_usbphy_drvdata { - int cpu_type; - int devphy_en_mask; - int hostphy_en_mask; - u32 devphy_reg_offset; - u32 hostphy_reg_offset; -}; - -/* - * struct samsung_usbphy - transceiver driver state - * @phy: transceiver structure - * @plat: platform data - * @dev: The parent device supplied to the probe function - * @clk: usb phy clock - * @regs: usb phy controller registers memory base - * @pmuregs: USB device PHY_CONTROL register memory base - * @sysreg: USB2.0 PHY_CFG register memory base - * @ref_clk_freq: reference clock frequency selection - * @drv_data: driver data available for different SoCs - * @phy_type: Samsung SoCs specific phy types: #HOST - * #DEVICE - * @phy_usage: usage count for phy - * @lock: lock for phy operations - */ -struct samsung_usbphy { - struct usb_phy phy; - struct samsung_usbphy_data *plat; - struct device *dev; - struct clk *clk; - void __iomem *regs; - void __iomem *pmuregs; - void __iomem *sysreg; - int ref_clk_freq; - const struct samsung_usbphy_drvdata *drv_data; - enum samsung_usb_phy_type phy_type; - atomic_t phy_usage; - spinlock_t lock; -}; - -#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy) - -int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - if (!otg->host) - otg->host = host; - - return 0; -} - -static int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy) +int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy) { struct device_node *usbphy_sys; @@ -282,13 +66,14 @@ err0: of_node_put(usbphy_sys); return -ENXIO; } +EXPORT_SYMBOL_GPL(samsung_usbphy_parse_dt); /* * Set isolation here for phy. * Here 'on = true' would mean USB PHY block is isolated, hence * de-activated and vice-versa. */ -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) +void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) { void __iomem *reg = NULL; u32 reg_val; @@ -336,11 +121,12 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) writel(reg_val, reg); } +EXPORT_SYMBOL_GPL(samsung_usbphy_set_isolation); /* * Configure the mode of working of usb-phy here: HOST/DEVICE. */ -static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) +void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) { u32 reg; @@ -358,13 +144,14 @@ static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) writel(reg, sphy->sysreg); } +EXPORT_SYMBOL_GPL(samsung_usbphy_cfg_sel); /* * PHYs are different for USB Device and USB Host. * This make sure that correct PHY type is selected before * any operation on PHY. */ -static int samsung_usbphy_set_type(struct usb_phy *phy, +int samsung_usbphy_set_type(struct usb_phy *phy, enum samsung_usb_phy_type phy_type) { struct samsung_usbphy *sphy = phy_to_sphy(phy); @@ -373,11 +160,12 @@ static int samsung_usbphy_set_type(struct usb_phy *phy, return 0; } +EXPORT_SYMBOL_GPL(samsung_usbphy_set_type); /* * Returns reference clock frequency selection value */ -static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) +int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) { struct clk *ref_clk; int refclk_freq = 0; @@ -387,9 +175,9 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) * external crystal clock XXTI */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - ref_clk = clk_get(sphy->dev, "ext_xtal"); + ref_clk = devm_clk_get(sphy->dev, "ext_xtal"); else - ref_clk = clk_get(sphy->dev, "xusbxti"); + ref_clk = devm_clk_get(sphy->dev, "xusbxti"); if (IS_ERR(ref_clk)) { dev_err(sphy->dev, "Failed to get reference clock\n"); return PTR_ERR(ref_clk); @@ -445,484 +233,4 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) return refclk_freq; } - -static bool exynos5_phyhost_is_on(void *regs) -{ - u32 reg; - - reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - - return !(reg & HOST_CTRL0_SIDDQ); -} - -static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phyclk = sphy->ref_clk_freq; - u32 phyhost; - u32 phyotg; - u32 phyhsic; - u32 ehcictrl; - u32 ohcictrl; - - /* - * phy_usage helps in keeping usage count for phy - * so that the first consumer enabling the phy is also - * the last consumer to disable it. - */ - - atomic_inc(&sphy->phy_usage); - - if (exynos5_phyhost_is_on(regs)) { - dev_info(sphy->dev, "Already power on PHY\n"); - return; - } - - /* Host configuration */ - phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - - /* phy reference clock configuration */ - phyhost &= ~HOST_CTRL0_FSEL_MASK; - phyhost |= HOST_CTRL0_FSEL(phyclk); - - /* host phy reset */ - phyhost &= ~(HOST_CTRL0_PHYSWRST | - HOST_CTRL0_PHYSWRSTALL | - HOST_CTRL0_SIDDQ | - /* Enable normal mode of operation */ - HOST_CTRL0_FORCESUSPEND | - HOST_CTRL0_FORCESLEEP); - - /* Link reset */ - phyhost |= (HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST | - /* COMMON Block configuration during suspend */ - HOST_CTRL0_COMMONON_N); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - udelay(10); - phyhost &= ~(HOST_CTRL0_LINKSWRST | - HOST_CTRL0_UTMISWRST); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - - /* OTG configuration */ - phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); - - /* phy reference clock configuration */ - phyotg &= ~OTG_SYS_FSEL_MASK; - phyotg |= OTG_SYS_FSEL(phyclk); - - /* Enable normal mode of operation */ - phyotg &= ~(OTG_SYS_FORCESUSPEND | - OTG_SYS_SIDDQ_UOTG | - OTG_SYS_FORCESLEEP | - OTG_SYS_REFCLKSEL_MASK | - /* COMMON Block configuration during suspend */ - OTG_SYS_COMMON_ON); - - /* OTG phy & link reset */ - phyotg |= (OTG_SYS_PHY0_SWRST | - OTG_SYS_LINKSWRST_UOTG | - OTG_SYS_PHYLINK_SWRESET | - OTG_SYS_OTGDISABLE | - /* Set phy refclk */ - OTG_SYS_REFCLKSEL_CLKCORE); - - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); - udelay(10); - phyotg &= ~(OTG_SYS_PHY0_SWRST | - OTG_SYS_LINKSWRST_UOTG | - OTG_SYS_PHYLINK_SWRESET); - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); - - /* HSIC phy configuration */ - phyhsic = (HSIC_CTRL_REFCLKDIV_12 | - HSIC_CTRL_REFCLKSEL | - HSIC_CTRL_PHYSWRST); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - udelay(10); - phyhsic &= ~HSIC_CTRL_PHYSWRST; - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - - udelay(80); - - /* enable EHCI DMA burst */ - ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL); - ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN | - HOST_EHCICTRL_ENAINCR4 | - HOST_EHCICTRL_ENAINCR8 | - HOST_EHCICTRL_ENAINCR16); - writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL); - - /* set ohci_suspend_on_n */ - ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL); - ohcictrl |= HOST_OHCICTRL_SUSPLGCY; - writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL); -} - -static void samsung_usbphy_enable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phypwr; - u32 phyclk; - u32 rstcon; - - /* set clock frequency for PLL */ - phyclk = sphy->ref_clk_freq; - phypwr = readl(regs + SAMSUNG_PHYPWR); - rstcon = readl(regs + SAMSUNG_RSTCON); - - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - phyclk &= ~PHYCLK_COMMON_ON_N; - phypwr &= ~PHYPWR_NORMAL_MASK; - rstcon |= RSTCON_SWRST; - break; - case TYPE_EXYNOS4210: - phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; - rstcon |= RSTCON_SWRST; - default: - break; - } - - writel(phyclk, regs + SAMSUNG_PHYCLK); - /* Configure PHY0 for normal operation*/ - writel(phypwr, regs + SAMSUNG_PHYPWR); - /* reset all ports of PHY and Link */ - writel(rstcon, regs + SAMSUNG_RSTCON); - udelay(10); - rstcon &= ~RSTCON_SWRST; - writel(rstcon, regs + SAMSUNG_RSTCON); -} - -static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phyhost; - u32 phyotg; - u32 phyhsic; - - if (atomic_dec_return(&sphy->phy_usage) > 0) { - dev_info(sphy->dev, "still being used\n"); - return; - } - - phyhsic = (HSIC_CTRL_REFCLKDIV_12 | - HSIC_CTRL_REFCLKSEL | - HSIC_CTRL_SIDDQ | - HSIC_CTRL_FORCESLEEP | - HSIC_CTRL_FORCESUSPEND); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); - writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); - - phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); - phyhost |= (HOST_CTRL0_SIDDQ | - HOST_CTRL0_FORCESUSPEND | - HOST_CTRL0_FORCESLEEP | - HOST_CTRL0_PHYSWRST | - HOST_CTRL0_PHYSWRSTALL); - writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); - - phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); - phyotg |= (OTG_SYS_FORCESUSPEND | - OTG_SYS_SIDDQ_UOTG | - OTG_SYS_FORCESLEEP); - writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); -} - -static void samsung_usbphy_disable(struct samsung_usbphy *sphy) -{ - void __iomem *regs = sphy->regs; - u32 phypwr; - - phypwr = readl(regs + SAMSUNG_PHYPWR); - - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - phypwr |= PHYPWR_NORMAL_MASK; - break; - case TYPE_EXYNOS4210: - phypwr |= PHYPWR_NORMAL_MASK_PHY0; - default: - break; - } - - /* Disable analog and otg block power */ - writel(phypwr, regs + SAMSUNG_PHYPWR); -} - -/* - * The function passed to the usb driver for phy initialization - */ -static int samsung_usbphy_init(struct usb_phy *phy) -{ - struct samsung_usbphy *sphy; - struct usb_bus *host = NULL; - unsigned long flags; - int ret = 0; - - sphy = phy_to_sphy(phy); - - host = phy->otg->host; - - /* Enable the phy clock */ - ret = clk_prepare_enable(sphy->clk); - if (ret) { - dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); - return ret; - } - - spin_lock_irqsave(&sphy->lock, flags); - - if (host) { - /* setting default phy-type for USB 2.0 */ - if (!strstr(dev_name(host->controller), "ehci") || - !strstr(dev_name(host->controller), "ohci")) - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); - } else { - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); - } - - /* Disable phy isolation */ - if (sphy->plat && sphy->plat->pmu_isolation) - sphy->plat->pmu_isolation(false); - else - samsung_usbphy_set_isolation(sphy, false); - - /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ - samsung_usbphy_cfg_sel(sphy); - - /* Initialize usb phy registers */ - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - samsung_exynos5_usbphy_enable(sphy); - else - samsung_usbphy_enable(sphy); - - spin_unlock_irqrestore(&sphy->lock, flags); - - /* Disable the phy clock */ - clk_disable_unprepare(sphy->clk); - - return ret; -} - -/* - * The function passed to the usb driver for phy shutdown - */ -static void samsung_usbphy_shutdown(struct usb_phy *phy) -{ - struct samsung_usbphy *sphy; - struct usb_bus *host = NULL; - unsigned long flags; - - sphy = phy_to_sphy(phy); - - host = phy->otg->host; - - if (clk_prepare_enable(sphy->clk)) { - dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); - return; - } - - spin_lock_irqsave(&sphy->lock, flags); - - if (host) { - /* setting default phy-type for USB 2.0 */ - if (!strstr(dev_name(host->controller), "ehci") || - !strstr(dev_name(host->controller), "ohci")) - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); - } else { - samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); - } - - /* De-initialize usb phy registers */ - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - samsung_exynos5_usbphy_disable(sphy); - else - samsung_usbphy_disable(sphy); - - /* Enable phy isolation */ - if (sphy->plat && sphy->plat->pmu_isolation) - sphy->plat->pmu_isolation(true); - else - samsung_usbphy_set_isolation(sphy, true); - - spin_unlock_irqrestore(&sphy->lock, flags); - - clk_disable_unprepare(sphy->clk); -} - -static const struct of_device_id samsung_usbphy_dt_match[]; - -static inline const struct samsung_usbphy_drvdata -*samsung_usbphy_get_driver_data(struct platform_device *pdev) -{ - if (pdev->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(samsung_usbphy_dt_match, - pdev->dev.of_node); - return match->data; - } - - return (struct samsung_usbphy_drvdata *) - platform_get_device_id(pdev)->driver_data; -} - -static int samsung_usbphy_probe(struct platform_device *pdev) -{ - struct samsung_usbphy *sphy; - struct usb_otg *otg; - struct samsung_usbphy_data *pdata = pdev->dev.platform_data; - const struct samsung_usbphy_drvdata *drv_data; - struct device *dev = &pdev->dev; - struct resource *phy_mem; - void __iomem *phy_base; - struct clk *clk; - int ret; - - phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!phy_mem) { - dev_err(dev, "%s: missing mem resource\n", __func__); - return -ENODEV; - } - - phy_base = devm_ioremap_resource(dev, phy_mem); - if (IS_ERR(phy_base)) - return PTR_ERR(phy_base); - - sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); - if (!sphy) - return -ENOMEM; - - otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - drv_data = samsung_usbphy_get_driver_data(pdev); - - if (drv_data->cpu_type == TYPE_EXYNOS5250) - clk = devm_clk_get(dev, "usbhost"); - else - clk = devm_clk_get(dev, "otg"); - - if (IS_ERR(clk)) { - dev_err(dev, "Failed to get otg clock\n"); - return PTR_ERR(clk); - } - - sphy->dev = dev; - - if (dev->of_node) { - ret = samsung_usbphy_parse_dt(sphy); - if (ret < 0) - return ret; - } else { - if (!pdata) { - dev_err(dev, "no platform data specified\n"); - return -EINVAL; - } - } - - sphy->plat = pdata; - sphy->regs = phy_base; - sphy->clk = clk; - sphy->drv_data = drv_data; - sphy->phy.dev = sphy->dev; - sphy->phy.label = "samsung-usbphy"; - sphy->phy.init = samsung_usbphy_init; - sphy->phy.shutdown = samsung_usbphy_shutdown; - sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); - - sphy->phy.otg = otg; - sphy->phy.otg->phy = &sphy->phy; - sphy->phy.otg->set_host = samsung_usbphy_set_host; - - spin_lock_init(&sphy->lock); - - platform_set_drvdata(pdev, sphy); - - return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); -} - -static int samsung_usbphy_remove(struct platform_device *pdev) -{ - struct samsung_usbphy *sphy = platform_get_drvdata(pdev); - - usb_remove_phy(&sphy->phy); - - if (sphy->pmuregs) - iounmap(sphy->pmuregs); - if (sphy->sysreg) - iounmap(sphy->sysreg); - - return 0; -} - -static const struct samsung_usbphy_drvdata usbphy_s3c64xx = { - .cpu_type = TYPE_S3C64XX, - .devphy_en_mask = S3C64XX_USBPHY_ENABLE, -}; - -static const struct samsung_usbphy_drvdata usbphy_exynos4 = { - .cpu_type = TYPE_EXYNOS4210, - .devphy_en_mask = EXYNOS_USBPHY_ENABLE, - .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, -}; - -static struct samsung_usbphy_drvdata usbphy_exynos5 = { - .cpu_type = TYPE_EXYNOS5250, - .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, - .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, -}; - -#ifdef CONFIG_OF -static const struct of_device_id samsung_usbphy_dt_match[] = { - { - .compatible = "samsung,s3c64xx-usbphy", - .data = &usbphy_s3c64xx, - }, { - .compatible = "samsung,exynos4210-usbphy", - .data = &usbphy_exynos4, - }, { - .compatible = "samsung,exynos5250-usbphy", - .data = &usbphy_exynos5 - }, - {}, -}; -MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); -#endif - -static struct platform_device_id samsung_usbphy_driver_ids[] = { - { - .name = "s3c64xx-usbphy", - .driver_data = (unsigned long)&usbphy_s3c64xx, - }, { - .name = "exynos4210-usbphy", - .driver_data = (unsigned long)&usbphy_exynos4, - }, { - .name = "exynos5250-usbphy", - .driver_data = (unsigned long)&usbphy_exynos5, - }, - {}, -}; - -MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); - -static struct platform_driver samsung_usbphy_driver = { - .probe = samsung_usbphy_probe, - .remove = samsung_usbphy_remove, - .id_table = samsung_usbphy_driver_ids, - .driver = { - .name = "samsung-usbphy", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(samsung_usbphy_dt_match), - }, -}; - -module_platform_driver(samsung_usbphy_driver); - -MODULE_DESCRIPTION("Samsung USB phy controller"); -MODULE_AUTHOR("Praveen Paneri "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-usbphy"); +EXPORT_SYMBOL_GPL(samsung_usbphy_get_refclk_freq); diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h new file mode 100644 index 000000000000..481737d743d5 --- /dev/null +++ b/drivers/usb/phy/phy-samsung-usb.h @@ -0,0 +1,247 @@ +/* linux/drivers/usb/phy/phy-samsung-usb.h + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and + * OHCI-EXYNOS controllers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +/* Register definitions */ + +#define SAMSUNG_PHYPWR (0x00) + +#define PHYPWR_NORMAL_MASK (0x19 << 0) +#define PHYPWR_OTG_DISABLE (0x1 << 4) +#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) +#define PHYPWR_FORCE_SUSPEND (0x1 << 1) +/* For Exynos4 */ +#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0) +#define PHYPWR_SLEEP_PHY0 (0x1 << 5) + +#define SAMSUNG_PHYCLK (0x04) + +#define PHYCLK_MODE_USB11 (0x1 << 6) +#define PHYCLK_EXT_OSC (0x1 << 5) +#define PHYCLK_COMMON_ON_N (0x1 << 4) +#define PHYCLK_ID_PULL (0x1 << 2) +#define PHYCLK_CLKSEL_MASK (0x3 << 0) +#define PHYCLK_CLKSEL_48M (0x0 << 0) +#define PHYCLK_CLKSEL_12M (0x2 << 0) +#define PHYCLK_CLKSEL_24M (0x3 << 0) + +#define SAMSUNG_RSTCON (0x08) + +#define RSTCON_PHYLINK_SWRST (0x1 << 2) +#define RSTCON_HLINK_SWRST (0x1 << 1) +#define RSTCON_SWRST (0x1 << 0) + +/* EXYNOS5 */ +#define EXYNOS5_PHY_HOST_CTRL0 (0x00) + +#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) + +#define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) +#define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) +#define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) +#define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) + +#define HOST_CTRL0_FSEL_MASK (0x7 << 16) +#define HOST_CTRL0_FSEL(_x) ((_x) << 16) + +#define FSEL_CLKSEL_50M (0x7) +#define FSEL_CLKSEL_24M (0x5) +#define FSEL_CLKSEL_20M (0x4) +#define FSEL_CLKSEL_19200K (0x3) +#define FSEL_CLKSEL_12M (0x2) +#define FSEL_CLKSEL_10M (0x1) +#define FSEL_CLKSEL_9600K (0x0) + +#define HOST_CTRL0_TESTBURNIN (0x1 << 11) +#define HOST_CTRL0_RETENABLE (0x1 << 10) +#define HOST_CTRL0_COMMONON_N (0x1 << 9) +#define HOST_CTRL0_SIDDQ (0x1 << 6) +#define HOST_CTRL0_FORCESLEEP (0x1 << 5) +#define HOST_CTRL0_FORCESUSPEND (0x1 << 4) +#define HOST_CTRL0_WORDINTERFACE (0x1 << 3) +#define HOST_CTRL0_UTMISWRST (0x1 << 2) +#define HOST_CTRL0_LINKSWRST (0x1 << 1) +#define HOST_CTRL0_PHYSWRST (0x1 << 0) + +#define EXYNOS5_PHY_HOST_TUNE0 (0x04) + +#define EXYNOS5_PHY_HSIC_CTRL1 (0x10) + +#define EXYNOS5_PHY_HSIC_TUNE1 (0x14) + +#define EXYNOS5_PHY_HSIC_CTRL2 (0x20) + +#define EXYNOS5_PHY_HSIC_TUNE2 (0x24) + +#define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) +#define HSIC_CTRL_REFCLKSEL (0x2 << 23) + +#define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) +#define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) +#define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) +#define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16) +#define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) +#define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) +#define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) + +#define HSIC_CTRL_SIDDQ (0x1 << 6) +#define HSIC_CTRL_FORCESLEEP (0x1 << 5) +#define HSIC_CTRL_FORCESUSPEND (0x1 << 4) +#define HSIC_CTRL_WORDINTERFACE (0x1 << 3) +#define HSIC_CTRL_UTMISWRST (0x1 << 2) +#define HSIC_CTRL_PHYSWRST (0x1 << 0) + +#define EXYNOS5_PHY_HOST_EHCICTRL (0x30) + +#define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) +#define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) +#define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) +#define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) + +#define EXYNOS5_PHY_HOST_OHCICTRL (0x34) + +#define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) +#define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) +#define HOST_OHCICTRL_CNTSEL (0x1 << 1) +#define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) + +#define EXYNOS5_PHY_OTG_SYS (0x38) + +#define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) +#define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) +#define OTG_SYS_PHY0_SWRST (0x1 << 12) + +#define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) +#define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) +#define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) +#define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) + +#define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) +#define OTG_SYS_COMMON_ON (0x1 << 7) + +#define OTG_SYS_FSEL_MASK (0x7 << 4) +#define OTG_SYS_FSEL(_x) ((_x) << 4) + +#define OTG_SYS_FORCESLEEP (0x1 << 3) +#define OTG_SYS_OTGDISABLE (0x1 << 2) +#define OTG_SYS_SIDDQ_UOTG (0x1 << 1) +#define OTG_SYS_FORCESUSPEND (0x1 << 0) + +#define EXYNOS5_PHY_OTG_TUNE (0x40) + +#ifndef MHZ +#define MHZ (1000*1000) +#endif + +#ifndef KHZ +#define KHZ (1000) +#endif + +#define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4) +#define S3C64XX_USBPHY_ENABLE (0x1 << 16) +#define EXYNOS_USBPHY_ENABLE (0x1 << 0) +#define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0) + +enum samsung_cpu_type { + TYPE_S3C64XX, + TYPE_EXYNOS4210, + TYPE_EXYNOS5250, +}; + +/* + * struct samsung_usbphy_drvdata - driver data for various SoC variants + * @cpu_type: machine identifier + * @devphy_en_mask: device phy enable mask for PHY CONTROL register + * @hostphy_en_mask: host phy enable mask for PHY CONTROL register + * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from + * mapped address of system controller. + * @hostphy_reg_offset: offset to HOST PHY CONTROL register from + * mapped address of system controller. + * + * Here we have a separate mask for device type phy. + * Having different masks for host and device type phy helps + * in setting independent masks in case of SoCs like S5PV210, + * in which PHY0 and PHY1 enable bits belong to same register + * placed at position 0 and 1 respectively. + * Although for newer SoCs like exynos these bits belong to + * different registers altogether placed at position 0. + */ +struct samsung_usbphy_drvdata { + int cpu_type; + int devphy_en_mask; + int hostphy_en_mask; + u32 devphy_reg_offset; + u32 hostphy_reg_offset; +}; + +/* + * struct samsung_usbphy - transceiver driver state + * @phy: transceiver structure + * @plat: platform data + * @dev: The parent device supplied to the probe function + * @clk: usb phy clock + * @regs: usb phy controller registers memory base + * @pmuregs: USB device PHY_CONTROL register memory base + * @sysreg: USB2.0 PHY_CFG register memory base + * @ref_clk_freq: reference clock frequency selection + * @drv_data: driver data available for different SoCs + * @phy_type: Samsung SoCs specific phy types: #HOST + * #DEVICE + * @phy_usage: usage count for phy + * @lock: lock for phy operations + */ +struct samsung_usbphy { + struct usb_phy phy; + struct samsung_usbphy_data *plat; + struct device *dev; + struct clk *clk; + void __iomem *regs; + void __iomem *pmuregs; + void __iomem *sysreg; + int ref_clk_freq; + const struct samsung_usbphy_drvdata *drv_data; + enum samsung_usb_phy_type phy_type; + atomic_t phy_usage; + spinlock_t lock; +}; + +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy) + +static const struct of_device_id samsung_usbphy_dt_match[]; + +static inline const struct samsung_usbphy_drvdata +*samsung_usbphy_get_driver_data(struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(samsung_usbphy_dt_match, + pdev->dev.of_node); + return match->data; + } + + return (struct samsung_usbphy_drvdata *) + platform_get_device_id(pdev)->driver_data; +} + +extern int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy); +extern void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on); +extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy); +extern int samsung_usbphy_set_type(struct usb_phy *phy, + enum samsung_usb_phy_type phy_type); +extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy); diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c new file mode 100644 index 000000000000..dce968151505 --- /dev/null +++ b/drivers/usb/phy/phy-samsung-usb2.c @@ -0,0 +1,509 @@ +/* linux/drivers/usb/phy/phy-samsung-usb2.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Praveen Paneri + * + * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and + * OHCI-EXYNOS controllers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-samsung-usb.h" + +static int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) +{ + if (!otg) + return -ENODEV; + + if (!otg->host) + otg->host = host; + + return 0; +} + +static bool exynos5_phyhost_is_on(void *regs) +{ + u32 reg; + + reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + + return !(reg & HOST_CTRL0_SIDDQ); +} + +static void samsung_exynos5_usb2phy_enable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phyclk = sphy->ref_clk_freq; + u32 phyhost; + u32 phyotg; + u32 phyhsic; + u32 ehcictrl; + u32 ohcictrl; + + /* + * phy_usage helps in keeping usage count for phy + * so that the first consumer enabling the phy is also + * the last consumer to disable it. + */ + + atomic_inc(&sphy->phy_usage); + + if (exynos5_phyhost_is_on(regs)) { + dev_info(sphy->dev, "Already power on PHY\n"); + return; + } + + /* Host configuration */ + phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + + /* phy reference clock configuration */ + phyhost &= ~HOST_CTRL0_FSEL_MASK; + phyhost |= HOST_CTRL0_FSEL(phyclk); + + /* host phy reset */ + phyhost &= ~(HOST_CTRL0_PHYSWRST | + HOST_CTRL0_PHYSWRSTALL | + HOST_CTRL0_SIDDQ | + /* Enable normal mode of operation */ + HOST_CTRL0_FORCESUSPEND | + HOST_CTRL0_FORCESLEEP); + + /* Link reset */ + phyhost |= (HOST_CTRL0_LINKSWRST | + HOST_CTRL0_UTMISWRST | + /* COMMON Block configuration during suspend */ + HOST_CTRL0_COMMONON_N); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + udelay(10); + phyhost &= ~(HOST_CTRL0_LINKSWRST | + HOST_CTRL0_UTMISWRST); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + + /* OTG configuration */ + phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); + + /* phy reference clock configuration */ + phyotg &= ~OTG_SYS_FSEL_MASK; + phyotg |= OTG_SYS_FSEL(phyclk); + + /* Enable normal mode of operation */ + phyotg &= ~(OTG_SYS_FORCESUSPEND | + OTG_SYS_SIDDQ_UOTG | + OTG_SYS_FORCESLEEP | + OTG_SYS_REFCLKSEL_MASK | + /* COMMON Block configuration during suspend */ + OTG_SYS_COMMON_ON); + + /* OTG phy & link reset */ + phyotg |= (OTG_SYS_PHY0_SWRST | + OTG_SYS_LINKSWRST_UOTG | + OTG_SYS_PHYLINK_SWRESET | + OTG_SYS_OTGDISABLE | + /* Set phy refclk */ + OTG_SYS_REFCLKSEL_CLKCORE); + + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); + udelay(10); + phyotg &= ~(OTG_SYS_PHY0_SWRST | + OTG_SYS_LINKSWRST_UOTG | + OTG_SYS_PHYLINK_SWRESET); + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); + + /* HSIC phy configuration */ + phyhsic = (HSIC_CTRL_REFCLKDIV_12 | + HSIC_CTRL_REFCLKSEL | + HSIC_CTRL_PHYSWRST); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + udelay(10); + phyhsic &= ~HSIC_CTRL_PHYSWRST; + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + + udelay(80); + + /* enable EHCI DMA burst */ + ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL); + ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN | + HOST_EHCICTRL_ENAINCR4 | + HOST_EHCICTRL_ENAINCR8 | + HOST_EHCICTRL_ENAINCR16); + writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL); + + /* set ohci_suspend_on_n */ + ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL); + ohcictrl |= HOST_OHCICTRL_SUSPLGCY; + writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL); +} + +static void samsung_usb2phy_enable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phypwr; + u32 phyclk; + u32 rstcon; + + /* set clock frequency for PLL */ + phyclk = sphy->ref_clk_freq; + phypwr = readl(regs + SAMSUNG_PHYPWR); + rstcon = readl(regs + SAMSUNG_RSTCON); + + switch (sphy->drv_data->cpu_type) { + case TYPE_S3C64XX: + phyclk &= ~PHYCLK_COMMON_ON_N; + phypwr &= ~PHYPWR_NORMAL_MASK; + rstcon |= RSTCON_SWRST; + break; + case TYPE_EXYNOS4210: + phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; + rstcon |= RSTCON_SWRST; + default: + break; + } + + writel(phyclk, regs + SAMSUNG_PHYCLK); + /* Configure PHY0 for normal operation*/ + writel(phypwr, regs + SAMSUNG_PHYPWR); + /* reset all ports of PHY and Link */ + writel(rstcon, regs + SAMSUNG_RSTCON); + udelay(10); + rstcon &= ~RSTCON_SWRST; + writel(rstcon, regs + SAMSUNG_RSTCON); +} + +static void samsung_exynos5_usb2phy_disable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phyhost; + u32 phyotg; + u32 phyhsic; + + if (atomic_dec_return(&sphy->phy_usage) > 0) { + dev_info(sphy->dev, "still being used\n"); + return; + } + + phyhsic = (HSIC_CTRL_REFCLKDIV_12 | + HSIC_CTRL_REFCLKSEL | + HSIC_CTRL_SIDDQ | + HSIC_CTRL_FORCESLEEP | + HSIC_CTRL_FORCESUSPEND); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); + writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); + + phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); + phyhost |= (HOST_CTRL0_SIDDQ | + HOST_CTRL0_FORCESUSPEND | + HOST_CTRL0_FORCESLEEP | + HOST_CTRL0_PHYSWRST | + HOST_CTRL0_PHYSWRSTALL); + writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); + + phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); + phyotg |= (OTG_SYS_FORCESUSPEND | + OTG_SYS_SIDDQ_UOTG | + OTG_SYS_FORCESLEEP); + writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); +} + +static void samsung_usb2phy_disable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phypwr; + + phypwr = readl(regs + SAMSUNG_PHYPWR); + + switch (sphy->drv_data->cpu_type) { + case TYPE_S3C64XX: + phypwr |= PHYPWR_NORMAL_MASK; + break; + case TYPE_EXYNOS4210: + phypwr |= PHYPWR_NORMAL_MASK_PHY0; + default: + break; + } + + /* Disable analog and otg block power */ + writel(phypwr, regs + SAMSUNG_PHYPWR); +} + +/* + * The function passed to the usb driver for phy initialization + */ +static int samsung_usb2phy_init(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + struct usb_bus *host = NULL; + unsigned long flags; + int ret = 0; + + sphy = phy_to_sphy(phy); + + host = phy->otg->host; + + /* Enable the phy clock */ + ret = clk_prepare_enable(sphy->clk); + if (ret) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return ret; + } + + spin_lock_irqsave(&sphy->lock, flags); + + if (host) { + /* setting default phy-type for USB 2.0 */ + if (!strstr(dev_name(host->controller), "ehci") || + !strstr(dev_name(host->controller), "ohci")) + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); + } else { + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + } + + /* Disable phy isolation */ + if (sphy->plat && sphy->plat->pmu_isolation) + sphy->plat->pmu_isolation(false); + else + samsung_usbphy_set_isolation(sphy, false); + + /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ + samsung_usbphy_cfg_sel(sphy); + + /* Initialize usb phy registers */ + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) + samsung_exynos5_usb2phy_enable(sphy); + else + samsung_usb2phy_enable(sphy); + + spin_unlock_irqrestore(&sphy->lock, flags); + + /* Disable the phy clock */ + clk_disable_unprepare(sphy->clk); + + return ret; +} + +/* + * The function passed to the usb driver for phy shutdown + */ +static void samsung_usb2phy_shutdown(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + struct usb_bus *host = NULL; + unsigned long flags; + + sphy = phy_to_sphy(phy); + + host = phy->otg->host; + + if (clk_prepare_enable(sphy->clk)) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return; + } + + spin_lock_irqsave(&sphy->lock, flags); + + if (host) { + /* setting default phy-type for USB 2.0 */ + if (!strstr(dev_name(host->controller), "ehci") || + !strstr(dev_name(host->controller), "ohci")) + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); + } else { + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + } + + /* De-initialize usb phy registers */ + if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) + samsung_exynos5_usb2phy_disable(sphy); + else + samsung_usb2phy_disable(sphy); + + /* Enable phy isolation */ + if (sphy->plat && sphy->plat->pmu_isolation) + sphy->plat->pmu_isolation(true); + else + samsung_usbphy_set_isolation(sphy, true); + + spin_unlock_irqrestore(&sphy->lock, flags); + + clk_disable_unprepare(sphy->clk); +} + +static int samsung_usb2phy_probe(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy; + struct usb_otg *otg; + struct samsung_usbphy_data *pdata = pdev->dev.platform_data; + const struct samsung_usbphy_drvdata *drv_data; + struct device *dev = &pdev->dev; + struct resource *phy_mem; + void __iomem *phy_base; + struct clk *clk; + int ret; + + phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!phy_mem) { + dev_err(dev, "%s: missing mem resource\n", __func__); + return -ENODEV; + } + + phy_base = devm_ioremap_resource(dev, phy_mem); + if (IS_ERR(phy_base)) + return PTR_ERR(phy_base); + + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); + if (!sphy) + return -ENOMEM; + + otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + drv_data = samsung_usbphy_get_driver_data(pdev); + + if (drv_data->cpu_type == TYPE_EXYNOS5250) + clk = devm_clk_get(dev, "usbhost"); + else + clk = devm_clk_get(dev, "otg"); + + if (IS_ERR(clk)) { + dev_err(dev, "Failed to get otg clock\n"); + return PTR_ERR(clk); + } + + sphy->dev = dev; + + if (dev->of_node) { + ret = samsung_usbphy_parse_dt(sphy); + if (ret < 0) + return ret; + } else { + if (!pdata) { + dev_err(dev, "no platform data specified\n"); + return -EINVAL; + } + } + + sphy->plat = pdata; + sphy->regs = phy_base; + sphy->clk = clk; + sphy->drv_data = drv_data; + sphy->phy.dev = sphy->dev; + sphy->phy.label = "samsung-usb2phy"; + sphy->phy.init = samsung_usb2phy_init; + sphy->phy.shutdown = samsung_usb2phy_shutdown; + sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); + + sphy->phy.otg = otg; + sphy->phy.otg->phy = &sphy->phy; + sphy->phy.otg->set_host = samsung_usbphy_set_host; + + spin_lock_init(&sphy->lock); + + platform_set_drvdata(pdev, sphy); + + return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); +} + +static int samsung_usb2phy_remove(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy = platform_get_drvdata(pdev); + + usb_remove_phy(&sphy->phy); + + if (sphy->pmuregs) + iounmap(sphy->pmuregs); + if (sphy->sysreg) + iounmap(sphy->sysreg); + + return 0; +} + +static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = { + .cpu_type = TYPE_S3C64XX, + .devphy_en_mask = S3C64XX_USBPHY_ENABLE, +}; + +static const struct samsung_usbphy_drvdata usb2phy_exynos4 = { + .cpu_type = TYPE_EXYNOS4210, + .devphy_en_mask = EXYNOS_USBPHY_ENABLE, + .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, +}; + +static struct samsung_usbphy_drvdata usb2phy_exynos5 = { + .cpu_type = TYPE_EXYNOS5250, + .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, + .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, +}; + +#ifdef CONFIG_OF +static const struct of_device_id samsung_usbphy_dt_match[] = { + { + .compatible = "samsung,s3c64xx-usb2phy", + .data = &usb2phy_s3c64xx, + }, { + .compatible = "samsung,exynos4210-usb2phy", + .data = &usb2phy_exynos4, + }, { + .compatible = "samsung,exynos5250-usb2phy", + .data = &usb2phy_exynos5 + }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); +#endif + +static struct platform_device_id samsung_usbphy_driver_ids[] = { + { + .name = "s3c64xx-usb2phy", + .driver_data = (unsigned long)&usb2phy_s3c64xx, + }, { + .name = "exynos4210-usb2phy", + .driver_data = (unsigned long)&usb2phy_exynos4, + }, { + .name = "exynos5250-usb2phy", + .driver_data = (unsigned long)&usb2phy_exynos5, + }, + {}, +}; + +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); + +static struct platform_driver samsung_usb2phy_driver = { + .probe = samsung_usb2phy_probe, + .remove = samsung_usb2phy_remove, + .id_table = samsung_usbphy_driver_ids, + .driver = { + .name = "samsung-usb2phy", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(samsung_usbphy_dt_match), + }, +}; + +module_platform_driver(samsung_usb2phy_driver); + +MODULE_DESCRIPTION("Samsung USB 2.0 phy controller"); +MODULE_AUTHOR("Praveen Paneri "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-usb2phy"); -- cgit From b52767581765d3d1a1ba7106674791e540574704 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 14 Mar 2013 15:59:11 +0530 Subject: usb: phy: samsung: Add PHY support for USB 3.0 controller Adding PHY driver support for USB 3.0 controller for Samsung's SoCs. Signed-off-by: Vivek Gautam Acked-by: Kukjin Kim Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/samsung-usbphy.txt | 54 ++++ drivers/usb/phy/Kconfig | 7 + drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy-samsung-usb.h | 80 +++++ drivers/usb/phy/phy-samsung-usb3.c | 349 +++++++++++++++++++++ 5 files changed, 491 insertions(+) create mode 100644 drivers/usb/phy/phy-samsung-usb3.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt index 96940abe9a57..f575302e5173 100644 --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt @@ -61,3 +61,57 @@ Example: reg = <0x10020704 0x8>; }; }; + + +** Samsung's usb 3.0 phy transceiver + +Starting exynso5250, Samsung's SoC have usb 3.0 phy transceiver +which is used for controlling usb 3.0 phy for dwc3-exynos usb 3.0 +controllers across Samsung SOCs. + +Required properties: + +Exynos5250: +- compatible : should be "samsung,exynos5250-usb3phy" +- reg : base physical address of the phy registers and length of memory mapped + region. +- clocks: Clock IDs array as required by the controller. +- clock-names: names of clocks correseponding to IDs in the clock property + as requested by the controller driver. + +Optional properties: +- #address-cells: should be '1' when usbphy node has a child node with 'reg' + property. +- #size-cells: should be '1' when usbphy node has a child node with 'reg' + property. +- ranges: allows valid translation between child's address space and parent's + address space. + +- The child node 'usbphy-sys' to the node 'usbphy' is for the system controller + interface for usb-phy. It should provide the following information required by + usb-phy controller to control phy. + - reg : base physical address of PHY_CONTROL registers. + The size of this register is the total sum of size of all PHY_CONTROL + registers that the SoC has. For example, the size will be + '0x4' in case we have only one PHY_CONTROL register (e.g. + OTHERS register in S3C64XX or USB_PHY_CONTROL register in S5PV210) + and, '0x8' in case we have two PHY_CONTROL registers (e.g. + USBDEVICE_PHY_CONTROL and USBHOST_PHY_CONTROL registers in exynos4x). + and so on. + +Example: + usbphy@12100000 { + compatible = "samsung,exynos5250-usb3phy"; + reg = <0x12100000 0x100>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&clock 1>, <&clock 286>; + clock-names = "ext_xtal", "usbdrd30"; + + usbphy-sys { + /* USB device and host PHY_CONTROL registers */ + reg = <0x10040704 0x8>; + }; + }; diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index e8cd52ac5c05..7e8fe0f0b8c6 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -99,6 +99,13 @@ config SAMSUNG_USB2PHY Enable this to support Samsung USB 2.0 (High Speed) PHY controller driver for Samsung SoCs. +config SAMSUNG_USB3PHY + tristate "Samsung USB 3.0 PHY controller Driver" + select SAMSUNG_USBPHY + help + Enable this to support Samsung USB 3.0 (Super Speed) phy controller + for samsung SoCs. + config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 8cd355f051f6..33863c09f3dc 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o +obj-$(CONFIG_SAMSUNG_USB3PHY) += phy-samsung-usb3.o obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h index 481737d743d5..70a9cae5e37f 100644 --- a/drivers/usb/phy/phy-samsung-usb.h +++ b/drivers/usb/phy/phy-samsung-usb.h @@ -145,6 +145,86 @@ #define EXYNOS5_PHY_OTG_TUNE (0x40) +/* EXYNOS5: USB 3.0 DRD */ +#define EXYNOS5_DRD_LINKSYSTEM (0x04) + +#define LINKSYSTEM_FLADJ_MASK (0x3f << 1) +#define LINKSYSTEM_FLADJ(_x) ((_x) << 1) +#define LINKSYSTEM_XHCI_VERSION_CONTROL (0x1 << 27) + +#define EXYNOS5_DRD_PHYUTMI (0x08) + +#define PHYUTMI_OTGDISABLE (0x1 << 6) +#define PHYUTMI_FORCESUSPEND (0x1 << 1) +#define PHYUTMI_FORCESLEEP (0x1 << 0) + +#define EXYNOS5_DRD_PHYPIPE (0x0c) + +#define EXYNOS5_DRD_PHYCLKRST (0x10) + +#define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) +#define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) + +#define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) +#define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) + +#define PHYCLKRST_SSC_EN (0x1 << 20) +#define PHYCLKRST_REF_SSP_EN (0x1 << 19) +#define PHYCLKRST_REF_CLKDIV2 (0x1 << 18) + +#define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) +#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) +#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x02 << 11) +#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) +#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) +#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) + +#define PHYCLKRST_FSEL_MASK (0x3f << 5) +#define PHYCLKRST_FSEL(_x) ((_x) << 5) +#define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) +#define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) +#define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) +#define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) + +#define PHYCLKRST_RETENABLEN (0x1 << 4) + +#define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) +#define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) +#define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) + +#define PHYCLKRST_PORTRESET (0x1 << 1) +#define PHYCLKRST_COMMONONN (0x1 << 0) + +#define EXYNOS5_DRD_PHYREG0 (0x14) +#define EXYNOS5_DRD_PHYREG1 (0x18) + +#define EXYNOS5_DRD_PHYPARAM0 (0x1c) + +#define PHYPARAM0_REF_USE_PAD (0x1 << 31) +#define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) +#define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) + +#define EXYNOS5_DRD_PHYPARAM1 (0x20) + +#define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) +#define PHYPARAM1_PCS_TXDEEMPH (0x1c) + +#define EXYNOS5_DRD_PHYTERM (0x24) + +#define EXYNOS5_DRD_PHYTEST (0x28) + +#define PHYTEST_POWERDOWN_SSP (0x1 << 3) +#define PHYTEST_POWERDOWN_HSP (0x1 << 2) + +#define EXYNOS5_DRD_PHYADP (0x2c) + +#define EXYNOS5_DRD_PHYBATCHG (0x30) + +#define PHYBATCHG_UTMI_CLKSEL (0x1 << 2) + +#define EXYNOS5_DRD_PHYRESUME (0x34) +#define EXYNOS5_DRD_LINKPORT (0x44) + #ifndef MHZ #define MHZ (1000*1000) #endif diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c new file mode 100644 index 000000000000..54f641860f9e --- /dev/null +++ b/drivers/usb/phy/phy-samsung-usb3.c @@ -0,0 +1,349 @@ +/* linux/drivers/usb/phy/phy-samsung-usb3.c + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Vivek Gautam + * + * Samsung USB 3.0 PHY transceiver; talks to DWC3 controller. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-samsung-usb.h" + +/* + * Sets the phy clk as EXTREFCLK (XXTI) which is internal clock from clock core. + */ +static u32 samsung_usb3phy_set_refclk(struct samsung_usbphy *sphy) +{ + u32 reg; + u32 refclk; + + refclk = sphy->ref_clk_freq; + + reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK | + PHYCLKRST_FSEL(refclk); + + switch (refclk) { + case FSEL_CLKSEL_50M: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | + PHYCLKRST_SSC_REFCLKSEL(0x00)); + break; + case FSEL_CLKSEL_20M: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF | + PHYCLKRST_SSC_REFCLKSEL(0x00)); + break; + case FSEL_CLKSEL_19200K: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF | + PHYCLKRST_SSC_REFCLKSEL(0x88)); + break; + case FSEL_CLKSEL_24M: + default: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF | + PHYCLKRST_SSC_REFCLKSEL(0x88)); + break; + } + + return reg; +} + +static int samsung_exynos5_usb3phy_enable(struct samsung_usbphy *sphy) +{ + void __iomem *regs = sphy->regs; + u32 phyparam0; + u32 phyparam1; + u32 linksystem; + u32 phybatchg; + u32 phytest; + u32 phyclkrst; + + /* Reset USB 3.0 PHY */ + writel(0x0, regs + EXYNOS5_DRD_PHYREG0); + + phyparam0 = readl(regs + EXYNOS5_DRD_PHYPARAM0); + /* Select PHY CLK source */ + phyparam0 &= ~PHYPARAM0_REF_USE_PAD; + /* Set Loss-of-Signal Detector sensitivity */ + phyparam0 &= ~PHYPARAM0_REF_LOSLEVEL_MASK; + phyparam0 |= PHYPARAM0_REF_LOSLEVEL; + writel(phyparam0, regs + EXYNOS5_DRD_PHYPARAM0); + + writel(0x0, regs + EXYNOS5_DRD_PHYRESUME); + + /* + * Setting the Frame length Adj value[6:1] to default 0x20 + * See xHCI 1.0 spec, 5.2.4 + */ + linksystem = LINKSYSTEM_XHCI_VERSION_CONTROL | + LINKSYSTEM_FLADJ(0x20); + writel(linksystem, regs + EXYNOS5_DRD_LINKSYSTEM); + + phyparam1 = readl(regs + EXYNOS5_DRD_PHYPARAM1); + /* Set Tx De-Emphasis level */ + phyparam1 &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; + phyparam1 |= PHYPARAM1_PCS_TXDEEMPH; + writel(phyparam1, regs + EXYNOS5_DRD_PHYPARAM1); + + phybatchg = readl(regs + EXYNOS5_DRD_PHYBATCHG); + phybatchg |= PHYBATCHG_UTMI_CLKSEL; + writel(phybatchg, regs + EXYNOS5_DRD_PHYBATCHG); + + /* PHYTEST POWERDOWN Control */ + phytest = readl(regs + EXYNOS5_DRD_PHYTEST); + phytest &= ~(PHYTEST_POWERDOWN_SSP | + PHYTEST_POWERDOWN_HSP); + writel(phytest, regs + EXYNOS5_DRD_PHYTEST); + + /* UTMI Power Control */ + writel(PHYUTMI_OTGDISABLE, regs + EXYNOS5_DRD_PHYUTMI); + + phyclkrst = samsung_usb3phy_set_refclk(sphy); + + phyclkrst |= PHYCLKRST_PORTRESET | + /* Digital power supply in normal operating mode */ + PHYCLKRST_RETENABLEN | + /* Enable ref clock for SS function */ + PHYCLKRST_REF_SSP_EN | + /* Enable spread spectrum */ + PHYCLKRST_SSC_EN | + /* Power down HS Bias and PLL blocks in suspend mode */ + PHYCLKRST_COMMONONN; + + writel(phyclkrst, regs + EXYNOS5_DRD_PHYCLKRST); + + udelay(10); + + phyclkrst &= ~(PHYCLKRST_PORTRESET); + writel(phyclkrst, regs + EXYNOS5_DRD_PHYCLKRST); + + return 0; +} + +static void samsung_exynos5_usb3phy_disable(struct samsung_usbphy *sphy) +{ + u32 phyutmi; + u32 phyclkrst; + u32 phytest; + void __iomem *regs = sphy->regs; + + phyutmi = PHYUTMI_OTGDISABLE | + PHYUTMI_FORCESUSPEND | + PHYUTMI_FORCESLEEP; + writel(phyutmi, regs + EXYNOS5_DRD_PHYUTMI); + + /* Resetting the PHYCLKRST enable bits to reduce leakage current */ + phyclkrst = readl(regs + EXYNOS5_DRD_PHYCLKRST); + phyclkrst &= ~(PHYCLKRST_REF_SSP_EN | + PHYCLKRST_SSC_EN | + PHYCLKRST_COMMONONN); + writel(phyclkrst, regs + EXYNOS5_DRD_PHYCLKRST); + + /* Control PHYTEST to remove leakage current */ + phytest = readl(regs + EXYNOS5_DRD_PHYTEST); + phytest |= (PHYTEST_POWERDOWN_SSP | + PHYTEST_POWERDOWN_HSP); + writel(phytest, regs + EXYNOS5_DRD_PHYTEST); +} + +static int samsung_usb3phy_init(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + unsigned long flags; + int ret = 0; + + sphy = phy_to_sphy(phy); + + /* Enable the phy clock */ + ret = clk_prepare_enable(sphy->clk); + if (ret) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return ret; + } + + spin_lock_irqsave(&sphy->lock, flags); + + /* setting default phy-type for USB 3.0 */ + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + + /* Disable phy isolation */ + samsung_usbphy_set_isolation(sphy, false); + + /* Initialize usb phy registers */ + samsung_exynos5_usb3phy_enable(sphy); + + spin_unlock_irqrestore(&sphy->lock, flags); + + /* Disable the phy clock */ + clk_disable_unprepare(sphy->clk); + + return ret; +} + +/* + * The function passed to the usb driver for phy shutdown + */ +static void samsung_usb3phy_shutdown(struct usb_phy *phy) +{ + struct samsung_usbphy *sphy; + unsigned long flags; + + sphy = phy_to_sphy(phy); + + if (clk_prepare_enable(sphy->clk)) { + dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); + return; + } + + spin_lock_irqsave(&sphy->lock, flags); + + /* setting default phy-type for USB 3.0 */ + samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); + + /* De-initialize usb phy registers */ + samsung_exynos5_usb3phy_disable(sphy); + + /* Enable phy isolation */ + samsung_usbphy_set_isolation(sphy, true); + + spin_unlock_irqrestore(&sphy->lock, flags); + + clk_disable_unprepare(sphy->clk); +} + +static int samsung_usb3phy_probe(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy; + struct samsung_usbphy_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct resource *phy_mem; + void __iomem *phy_base; + struct clk *clk; + int ret; + + phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!phy_mem) { + dev_err(dev, "%s: missing mem resource\n", __func__); + return -ENODEV; + } + + phy_base = devm_request_and_ioremap(dev, phy_mem); + if (!phy_base) { + dev_err(dev, "%s: register mapping failed\n", __func__); + return -ENXIO; + } + + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); + if (!sphy) + return -ENOMEM; + + clk = devm_clk_get(dev, "usbdrd30"); + if (IS_ERR(clk)) { + dev_err(dev, "Failed to get device clock\n"); + return PTR_ERR(clk); + } + + sphy->dev = dev; + + if (dev->of_node) { + ret = samsung_usbphy_parse_dt(sphy); + if (ret < 0) + return ret; + } else { + if (!pdata) { + dev_err(dev, "no platform data specified\n"); + return -EINVAL; + } + } + + sphy->plat = pdata; + sphy->regs = phy_base; + sphy->clk = clk; + sphy->phy.dev = sphy->dev; + sphy->phy.label = "samsung-usb3phy"; + sphy->phy.init = samsung_usb3phy_init; + sphy->phy.shutdown = samsung_usb3phy_shutdown; + sphy->drv_data = samsung_usbphy_get_driver_data(pdev); + sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); + + spin_lock_init(&sphy->lock); + + platform_set_drvdata(pdev, sphy); + + return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB3); +} + +static int samsung_usb3phy_remove(struct platform_device *pdev) +{ + struct samsung_usbphy *sphy = platform_get_drvdata(pdev); + + usb_remove_phy(&sphy->phy); + + if (sphy->pmuregs) + iounmap(sphy->pmuregs); + if (sphy->sysreg) + iounmap(sphy->sysreg); + + return 0; +} + +static struct samsung_usbphy_drvdata usb3phy_exynos5 = { + .cpu_type = TYPE_EXYNOS5250, + .devphy_en_mask = EXYNOS_USBPHY_ENABLE, +}; + +#ifdef CONFIG_OF +static const struct of_device_id samsung_usbphy_dt_match[] = { + { + .compatible = "samsung,exynos5250-usb3phy", + .data = &usb3phy_exynos5 + }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); +#endif + +static struct platform_device_id samsung_usbphy_driver_ids[] = { + { + .name = "exynos5250-usb3phy", + .driver_data = (unsigned long)&usb3phy_exynos5, + }, + {}, +}; + +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); + +static struct platform_driver samsung_usb3phy_driver = { + .probe = samsung_usb3phy_probe, + .remove = samsung_usb3phy_remove, + .id_table = samsung_usbphy_driver_ids, + .driver = { + .name = "samsung-usb3phy", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(samsung_usbphy_dt_match), + }, +}; + +module_platform_driver(samsung_usb3phy_driver); + +MODULE_DESCRIPTION("Samsung USB 3.0 phy controller"); +MODULE_AUTHOR("Vivek Gautam "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-usb3phy"); -- cgit From adcf20dcd2629112c467f30a2c057479979ae64c Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 14 Mar 2013 18:09:49 +0530 Subject: usb: dwc3: exynos: Use of_platform API to create dwc3 core pdev Used of_platform_populate() to create dwc3 core platform_device from device tree data. Additionally some cleanup is also done. Signed-off-by: Vivek Gautam CC: Felipe Balbi CC: Kukjin Kim Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 56 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index e12e45248862..f77ec75e2d1e 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -22,9 +22,9 @@ #include #include #include +#include struct dwc3_exynos { - struct platform_device *dwc3; struct platform_device *usb2_phy; struct platform_device *usb3_phy; struct device *dev; @@ -86,21 +86,30 @@ err1: return ret; } +static int dwc3_exynos_remove_child(struct device *dev, void *unused) +{ + struct platform_device *pdev = to_platform_device(dev); + + platform_device_unregister(pdev); + + return 0; +} + static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32); static int dwc3_exynos_probe(struct platform_device *pdev) { - struct platform_device *dwc3; struct dwc3_exynos *exynos; struct clk *clk; struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; int ret = -ENOMEM; exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); if (!exynos) { dev_err(dev, "not enough memory\n"); - return -ENOMEM; + goto err1; } /* @@ -108,21 +117,15 @@ static int dwc3_exynos_probe(struct platform_device *pdev) * Since shared usb code relies on it, set it here for now. * Once we move to full device tree support this will vanish off. */ - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &dwc3_exynos_dma_mask; + if (!dev->dma_mask) + dev->dma_mask = &dwc3_exynos_dma_mask; platform_set_drvdata(pdev, exynos); ret = dwc3_exynos_register_phys(exynos); if (ret) { dev_err(dev, "couldn't register PHYs\n"); - return ret; - } - - dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); - if (!dwc3) { - dev_err(dev, "couldn't allocate dwc3 device\n"); - return -ENOMEM; + goto err1; } clk = devm_clk_get(dev, "usbdrd30"); @@ -132,27 +135,20 @@ static int dwc3_exynos_probe(struct platform_device *pdev) goto err1; } - dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); - - dwc3->dev.parent = dev; - dwc3->dev.dma_mask = dev->dma_mask; - dwc3->dev.dma_parms = dev->dma_parms; - exynos->dwc3 = dwc3; exynos->dev = dev; exynos->clk = clk; clk_enable(exynos->clk); - ret = platform_device_add_resources(dwc3, pdev->resource, - pdev->num_resources); - if (ret) { - dev_err(dev, "couldn't add resources to dwc3 device\n"); - goto err2; - } - - ret = platform_device_add(dwc3); - if (ret) { - dev_err(dev, "failed to register dwc3 device\n"); + if (node) { + ret = of_platform_populate(node, NULL, NULL, dev); + if (ret) { + dev_err(dev, "failed to add dwc3 core\n"); + goto err2; + } + } else { + dev_err(dev, "no device node, failed to add dwc3 core\n"); + ret = -ENODEV; goto err2; } @@ -161,8 +157,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev) err2: clk_disable(clk); err1: - platform_device_put(dwc3); - return ret; } @@ -170,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev) { struct dwc3_exynos *exynos = platform_get_drvdata(pdev); - platform_device_unregister(exynos->dwc3); platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); + device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); clk_disable(exynos->clk); -- cgit From ddb5147cea10308fac7d4ea44cbd164929199e03 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 14 Mar 2013 16:14:58 +0530 Subject: usb: dwc3: exynos: use clk_prepare_enable and clk_disable_unprepare Convert clk_enable/clk_disable to clk_prepare_enable/clk_disable_unprepare calls as required by common clock framework. Signed-off-by: Vivek Gautam CC: Kukjin Kim Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index f77ec75e2d1e..1ea7bd8af6ae 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -138,7 +138,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) exynos->dev = dev; exynos->clk = clk; - clk_enable(exynos->clk); + clk_prepare_enable(exynos->clk); if (node) { ret = of_platform_populate(node, NULL, NULL, dev); @@ -155,7 +155,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) return 0; err2: - clk_disable(clk); + clk_disable_unprepare(clk); err1: return ret; } @@ -168,7 +168,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) platform_device_unregister(exynos->usb3_phy); device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); - clk_disable(exynos->clk); + clk_disable_unprepare(exynos->clk); return 0; } -- cgit From f9e612002fc50b3ae7cd1349eb2387e5430b44d9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:22 +0100 Subject: usb: gadget: uvc: clarify comment about string descriptors The comment that describes string descriptors allocation isn't clear, fix it. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 92efd6ec48af..dd372ce9f3e2 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -800,7 +800,10 @@ uvc_bind_config(struct usb_configuration *c, uvc->desc.hs_streaming = hs_streaming; uvc->desc.ss_streaming = ss_streaming; - /* Allocate string descriptor numbers. */ + /* String descriptors are global, we only need to allocate string IDs + * for the first UVC function. UVC functions beyond the first (if any) + * will reuse the same IDs. + */ if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings); if (ret) -- cgit From 912ca429fc87ceb63ae9ae00eff08212aad890c5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:23 +0100 Subject: usb: gadget: uvc: Rename STATUS_BYTECOUNT to UVC_STATUS_MAX_PACKET_SIZE Descriptive names make the code more readable. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index dd372ce9f3e2..1851490c67cd 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -79,7 +79,7 @@ static struct usb_gadget_strings *uvc_function_strings[] = { #define UVC_INTF_VIDEO_CONTROL 0 #define UVC_INTF_VIDEO_STREAMING 1 -#define STATUS_BYTECOUNT 16 /* 16 bytes status */ +#define UVC_STATUS_MAX_PACKET_SIZE 16 /* 16 bytes status */ static struct usb_interface_assoc_descriptor uvc_iad __initdata = { .bLength = sizeof(uvc_iad), @@ -109,7 +109,7 @@ static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), + .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), .bInterval = 8, }; @@ -117,7 +117,7 @@ static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = { .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, .bDescriptorType = USB_DT_CS_ENDPOINT, .bDescriptorSubType = UVC_EP_INTERRUPT, - .wMaxTransferSize = cpu_to_le16(STATUS_BYTECOUNT), + .wMaxTransferSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), }; static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { @@ -169,7 +169,7 @@ static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), + .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), .bInterval = 8, }; @@ -180,7 +180,7 @@ static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { /* the following 3 values can be tweaked if necessary */ /* .bMaxBurst = 0, */ /* .bmAttributes = 0, */ - .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT), + .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), }; static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { -- cgit From ee6a4d870b722a57aa57abe7f12539bac9c01555 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:24 +0100 Subject: usb: gadget: uvc: Fix coding style issues introduced by SS support Let's keep the code consistent, people might want to read it. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 58 +++++++++++++++++++++++----------------------- drivers/usb/gadget/f_uvc.h | 12 +++++----- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 1851490c67cd..c13b8b07c791 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -164,43 +164,43 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { /* super speed support */ static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), - .bInterval = 8, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), + .bInterval = 8, }; static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { - .bLength = sizeof uvc_ss_control_comp, - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + .bLength = sizeof(uvc_ss_control_comp), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, /* the following 3 values can be tweaked if necessary */ - /* .bMaxBurst = 0, */ - /* .bmAttributes = 0, */ - .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), + .bMaxBurst = 0, + .bmAttributes = 0, + .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), }; static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = cpu_to_le16(1024), - .bInterval = 4, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .wMaxPacketSize = cpu_to_le16(1024), + .bInterval = 4, }; static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { - .bLength = sizeof uvc_ss_streaming_comp, - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + .bLength = sizeof(uvc_ss_streaming_comp), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, /* the following 3 values can be tweaked if necessary */ - .bMaxBurst = 0, - .bmAttributes = 0, - .wBytesPerInterval = cpu_to_le16(1024), + .bMaxBurst = 0, + .bmAttributes = 0, + .wBytesPerInterval = cpu_to_le16(1024), }; static const struct usb_descriptor_header * const uvc_fs_streaming[] = { @@ -514,13 +514,13 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) } for (src = (const struct usb_descriptor_header **)uvc_control_desc; - *src; ++src) { + *src; ++src) { control_size += (*src)->bLength; bytes += (*src)->bLength; n_desc++; } for (src = (const struct usb_descriptor_header **)uvc_streaming_cls; - *src; ++src) { + *src; ++src) { streaming_size += (*src)->bLength; bytes += (*src)->bLength; n_desc++; @@ -775,23 +775,23 @@ uvc_bind_config(struct usb_configuration *c, /* Validate the descriptors. */ if (fs_control == NULL || fs_control[0] == NULL || - fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) + fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) goto error; if (ss_control == NULL || ss_control[0] == NULL || - ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) + ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) goto error; if (fs_streaming == NULL || fs_streaming[0] == NULL || - fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; if (hs_streaming == NULL || hs_streaming[0] == NULL || - hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; if (ss_streaming == NULL || ss_streaming[0] == NULL || - ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) + ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) goto error; uvc->desc.fs_control = fs_control; diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h index c3d258d30188..ec52752f7326 100644 --- a/drivers/usb/gadget/f_uvc.h +++ b/drivers/usb/gadget/f_uvc.h @@ -16,12 +16,12 @@ #include #include -extern int uvc_bind_config(struct usb_configuration *c, - const struct uvc_descriptor_header * const *fs_control, - const struct uvc_descriptor_header * const *hs_control, - const struct uvc_descriptor_header * const *fs_streaming, - const struct uvc_descriptor_header * const *hs_streaming, - const struct uvc_descriptor_header * const *ss_streaming); +int uvc_bind_config(struct usb_configuration *c, + const struct uvc_descriptor_header * const *fs_control, + const struct uvc_descriptor_header * const *hs_control, + const struct uvc_descriptor_header * const *fs_streaming, + const struct uvc_descriptor_header * const *hs_streaming, + const struct uvc_descriptor_header * const *ss_streaming); #endif /* _F_UVC_H_ */ -- cgit From 48eee0b41a1c6e979e4b47d75bb3f2493c1b5fb9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:25 +0100 Subject: usb: gadget: uvc: Merge the SS/HS/FS control endpoint descriptors The descriptors are identical, there's no need to have several copies of them. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 52 ++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index c13b8b07c791..8e4827c3afb5 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -104,7 +104,7 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = { .iInterface = 0, }; -static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { +static struct usb_endpoint_descriptor uvc_control_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -113,6 +113,15 @@ static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { .bInterval = 8, }; +static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { + .bLength = sizeof(uvc_ss_control_comp), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* The following 3 values can be tweaked if necessary. */ + .bMaxBurst = 0, + .bmAttributes = 0, + .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), +}; + static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = { .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, .bDescriptorType = USB_DT_CS_ENDPOINT, @@ -144,7 +153,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = { .iInterface = 0, }; -static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { +static struct usb_endpoint_descriptor uvc_fs_streaming_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -153,7 +162,7 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { .bInterval = 1, }; -static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { +static struct usb_endpoint_descriptor uvc_hs_streaming_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -162,27 +171,6 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { .bInterval = 1, }; -/* super speed support */ -static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), - .bInterval = 8, -}; - -static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { - .bLength = sizeof(uvc_ss_control_comp), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /* the following 3 values can be tweaked if necessary */ - .bMaxBurst = 0, - .bmAttributes = 0, - .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE), -}; - static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -193,11 +181,10 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { .bInterval = 4, }; -static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { +static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp __initdata = { .bLength = sizeof(uvc_ss_streaming_comp), .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /* the following 3 values can be tweaked if necessary */ + /* The following 3 values can be tweaked if necessary. */ .bMaxBurst = 0, .bmAttributes = 0, .wBytesPerInterval = cpu_to_le16(1024), @@ -454,7 +441,6 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) const struct uvc_descriptor_header * const *uvc_streaming_cls; const struct usb_descriptor_header * const *uvc_streaming_std; const struct usb_descriptor_header * const *src; - static struct usb_endpoint_descriptor *uvc_control_ep; struct usb_descriptor_header **dst; struct usb_descriptor_header **hdr; unsigned int control_size; @@ -468,14 +454,12 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) uvc_control_desc = uvc->desc.ss_control; uvc_streaming_cls = uvc->desc.ss_streaming; uvc_streaming_std = uvc_ss_streaming; - uvc_control_ep = &uvc_ss_control_ep; break; case USB_SPEED_HIGH: uvc_control_desc = uvc->desc.fs_control; uvc_streaming_cls = uvc->desc.hs_streaming; uvc_streaming_std = uvc_hs_streaming; - uvc_control_ep = &uvc_fs_control_ep; break; case USB_SPEED_FULL: @@ -483,7 +467,6 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) uvc_control_desc = uvc->desc.fs_control; uvc_streaming_cls = uvc->desc.fs_streaming; uvc_streaming_std = uvc_fs_streaming; - uvc_control_ep = &uvc_fs_control_ep; break; } @@ -494,6 +477,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) * Class-specific UVC control descriptors * uvc_control_ep * uvc_control_cs_ep + * uvc_ss_control_comp (for SS only) * uvc_streaming_intf_alt0 * Class-specific UVC streaming descriptors * uvc_{fs|hs}_streaming @@ -503,7 +487,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) control_size = 0; streaming_size = 0; bytes = uvc_iad.bLength + uvc_control_intf.bLength - + uvc_control_ep->bLength + uvc_control_cs_ep.bLength + + uvc_control_ep.bLength + uvc_control_cs_ep.bLength + uvc_streaming_intf_alt0.bLength; if (speed == USB_SPEED_SUPER) { @@ -549,7 +533,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) uvc_control_header->bInCollection = 1; uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; - UVC_COPY_DESCRIPTOR(mem, dst, uvc_control_ep); + UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep); if (speed == USB_SPEED_SUPER) UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp); @@ -619,7 +603,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc_fs_streaming_ep.bInterval = streaming_interval; /* Allocate endpoints. */ - ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep); + ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); if (!ep) { INFO(cdev, "Unable to allocate control EP\n"); goto error; -- cgit From 20777dde026eb4b915ce577f830231c00c3f9292 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:26 +0100 Subject: usb: gadget: uvc: Merge the streaming maxpacket and mult parameters Compute the multiplier from the maximum packet size based on the speed. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 120 ++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 8e4827c3afb5..7189dbe20014 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -33,19 +33,15 @@ unsigned int uvc_gadget_trace_param; /*-------------------------------------------------------------------------*/ /* module parameters specific to the Video streaming endpoint */ -static unsigned streaming_interval = 1; +static unsigned int streaming_interval = 1; module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(streaming_interval, "1 - 16"); -static unsigned streaming_maxpacket = 1024; +static unsigned int streaming_maxpacket = 1024; module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(streaming_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); +MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)"); -static unsigned streaming_mult; -module_param(streaming_mult, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(streaming_mult, "0 - 2 (hs/ss only)"); - -static unsigned streaming_maxburst; +static unsigned int streaming_maxburst; module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); @@ -158,8 +154,11 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep __initdata = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = cpu_to_le16(512), - .bInterval = 1, + /* The wMaxPacketSize and bInterval values will be initialized from + * module parameters. + */ + .wMaxPacketSize = 0, + .bInterval = 0, }; static struct usb_endpoint_descriptor uvc_hs_streaming_ep __initdata = { @@ -167,8 +166,11 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep __initdata = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = cpu_to_le16(1024), - .bInterval = 1, + /* The wMaxPacketSize and bInterval values will be initialized from + * module parameters. + */ + .wMaxPacketSize = 0, + .bInterval = 0, }; static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { @@ -177,8 +179,11 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = cpu_to_le16(1024), - .bInterval = 4, + /* The wMaxPacketSize and bInterval values will be initialized from + * module parameters. + */ + .wMaxPacketSize = 0, + .bInterval = 0, }; static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp __initdata = { @@ -579,29 +584,50 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct uvc_device *uvc = to_uvc(f); + unsigned int max_packet_mult; + unsigned int max_packet_size; struct usb_ep *ep; int ret = -EINVAL; INFO(cdev, "uvc_function_bind\n"); - /* sanity check the streaming endpoint module parameters */ - if (streaming_interval < 1) - streaming_interval = 1; - if (streaming_interval > 16) - streaming_interval = 16; - if (streaming_mult > 2) - streaming_mult = 2; - if (streaming_maxburst > 15) - streaming_maxburst = 15; - - /* - * fill in the FS video streaming specific descriptors from the - * module parameters + /* Sanity check the streaming endpoint module parameters. + */ + streaming_interval = clamp(streaming_interval, 1U, 16U); + streaming_maxpacket = clamp(streaming_maxpacket, 1U, 3072U); + streaming_maxburst = min(streaming_maxburst, 15U); + + /* Fill in the FS/HS/SS Video Streaming specific descriptors from the + * module parameters. + * + * NOTE: We assume that the user knows what they are doing and won't + * give parameters that their UDC doesn't support. */ - uvc_fs_streaming_ep.wMaxPacketSize = streaming_maxpacket > 1023 ? - 1023 : streaming_maxpacket; + if (streaming_maxpacket <= 1024) { + max_packet_mult = 1; + max_packet_size = streaming_maxpacket; + } else if (streaming_maxpacket <= 2048) { + max_packet_mult = 2; + max_packet_size = streaming_maxpacket / 2; + } else { + max_packet_mult = 3; + max_packet_size = streaming_maxpacket / 3; + } + + uvc_fs_streaming_ep.wMaxPacketSize = min(streaming_maxpacket, 1023U); uvc_fs_streaming_ep.bInterval = streaming_interval; + uvc_hs_streaming_ep.wMaxPacketSize = max_packet_size; + uvc_hs_streaming_ep.wMaxPacketSize |= ((max_packet_mult - 1) << 11); + uvc_hs_streaming_ep.bInterval = streaming_interval; + + uvc_ss_streaming_ep.wMaxPacketSize = max_packet_size; + uvc_ss_streaming_ep.bInterval = streaming_interval; + uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1; + uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; + uvc_ss_streaming_comp.wBytesPerInterval = + max_packet_size * max_packet_mult * streaming_maxburst; + /* Allocate endpoints. */ ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); if (!ep) { @@ -619,6 +645,11 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc->video.ep = ep; ep->driver_data = uvc; + uvc_hs_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; + uvc_ss_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; + /* Allocate interface IDs. */ if ((ret = usb_interface_id(c, f)) < 0) goto error; @@ -632,37 +663,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc_streaming_intf_alt1.bInterfaceNumber = ret; uvc->streaming_intf = ret; - /* sanity check the streaming endpoint module parameters */ - if (streaming_maxpacket > 1024) - streaming_maxpacket = 1024; - /* - * Fill in the HS descriptors from the module parameters for the Video - * Streaming endpoint. - * NOTE: We assume that the user knows what they are doing and won't - * give parameters that their UDC doesn't support. - */ - uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket; - uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11; - uvc_hs_streaming_ep.bInterval = streaming_interval; - uvc_hs_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; - - /* - * Fill in the SS descriptors from the module parameters for the Video - * Streaming endpoint. - * NOTE: We assume that the user knows what they are doing and won't - * give parameters that their UDC doesn't support. - */ - uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket; - uvc_ss_streaming_ep.bInterval = streaming_interval; - uvc_ss_streaming_comp.bmAttributes = streaming_mult; - uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; - uvc_ss_streaming_comp.wBytesPerInterval = - streaming_maxpacket * (streaming_mult + 1) * - (streaming_maxburst + 1); - uvc_ss_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; - /* Copy descriptors */ f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); if (gadget_is_dualspeed(cdev->gadget)) -- cgit From 0485ec0d3ba9ce96ab5064b05a06e672c9d2c973 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Mar 2013 20:46:27 +0100 Subject: usb: gadget: uvc: Configure the streaming endpoint based on the speed Call the appropriate usb_ep_autoconf*() function depending on the device speed, and pass it the corresponding streaming endpoint. Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 7189dbe20014..87b5306d1255 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -549,8 +549,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) UVC_COPY_DESCRIPTORS(mem, dst, (const struct usb_descriptor_header**)uvc_streaming_cls); uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); - uvc_streaming_header->bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; + uvc_streaming_header->bEndpointAddress = uvc->video.ep->address; UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); @@ -637,7 +636,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc->control_ep = ep; ep->driver_data = uvc; - ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); + if (gadget_is_superspeed(c->cdev->gadget)) + ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, + &uvc_ss_streaming_comp); + else if (gadget_is_dualspeed(cdev->gadget)) + ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep); + else + ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); + if (!ep) { INFO(cdev, "Unable to allocate streaming EP\n"); goto error; @@ -645,10 +651,9 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvc->video.ep = ep; ep->driver_data = uvc; - uvc_hs_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; - uvc_ss_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; + uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; + uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; + uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; /* Allocate interface IDs. */ if ((ret = usb_interface_id(c, f)) < 0) -- cgit From 609a0532a4d713819092a9311ffe89faa6bac617 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Mar 2013 20:46:28 +0100 Subject: usb: gadget: uvc: Add fix for UVC compliance test suite assertion 6.3.90 failure As per UVC compliance test specification's assertion number 6.3.90 related to 'Standard VS Isochronous Video Data Endpoint Descriptor Assertions', the bits D3..2 of 'bmAttributes' field of Standard VS Isochronous Video Data Endpoint Descriptor should be 01 (binary) to indicate that the synchronization type is ASYNCHRONOUS. This mandatory requirement has been captured in section 3.10.1.1 of the UVC Video Class Specification version 1.1 This patch adds a fix for the same. Signed-off-by: Bhupesh Sharma Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 87b5306d1255..76ec10fa5f2b 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -153,7 +153,8 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .bmAttributes = USB_ENDPOINT_SYNC_ASYNC + | USB_ENDPOINT_XFER_ISOC, /* The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ @@ -165,7 +166,8 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .bmAttributes = USB_ENDPOINT_SYNC_ASYNC + | USB_ENDPOINT_XFER_ISOC, /* The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ @@ -178,7 +180,8 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .bmAttributes = USB_ENDPOINT_SYNC_ASYNC + | USB_ENDPOINT_XFER_ISOC, /* The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ -- cgit From 43ff05e20c6e2428fe2deb1dc0fed008743e66a3 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Mar 2013 20:46:29 +0100 Subject: usb: gadget: uvc: Add fix for UVC compliance test suite's assertion 6.1.25 failure As per the UVC compliance test suite's assertion 6.1.25, the `iFunction` field of the Interface Association Descriptor (IAD) should the match the `iInterface` field of the standard Video Control (VC) Interface Descriptor for this Video Interface Collection (VIC). This mandatory case is captured in section 3.11 of the USB Video Class Compliance specification revision 1.1 This patch fixes this test assertion's failure and has been tested on Linux FC16, WinXP, WIN7 and WIN8 High speed and Super Speed hosts for successful enumeration. Signed-off-by: Bhupesh Sharma [Merged the association and control string descriptors] Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 76ec10fa5f2b..49939e44ed74 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -51,13 +51,11 @@ MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); /* string IDs are assigned dynamically */ -#define UVC_STRING_ASSOCIATION_IDX 0 -#define UVC_STRING_CONTROL_IDX 1 -#define UVC_STRING_STREAMING_IDX 2 +#define UVC_STRING_CONTROL_IDX 0 +#define UVC_STRING_STREAMING_IDX 1 static struct usb_string uvc_en_us_strings[] = { - [UVC_STRING_ASSOCIATION_IDX].s = "UVC Camera", - [UVC_STRING_CONTROL_IDX].s = "Video Control", + [UVC_STRING_CONTROL_IDX].s = "UVC Camera", [UVC_STRING_STREAMING_IDX].s = "Video Streaming", { } }; @@ -572,7 +570,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) uvc->control_ep->driver_data = NULL; uvc->video.ep->driver_data = NULL; - uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = 0; + uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = 0; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); @@ -796,12 +794,12 @@ uvc_bind_config(struct usb_configuration *c, * for the first UVC function. UVC functions beyond the first (if any) * will reuse the same IDs. */ - if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { + if (uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id == 0) { ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings); if (ret) goto error; uvc_iad.iFunction = - uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id; + uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id; uvc_control_intf.iInterface = uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id; ret = uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id; -- cgit From 41837c352fd8d804dbe978c29e57ec8217df1d51 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Mar 2013 20:46:30 +0100 Subject: usb: gadget: uvc: Delay the status stage when setting alternate setting 1 This patch adds the support in UVC webcam gadget design for providing USB_GADGET_DELAYED_STATUS in response to a set_interface(alt setting 1) command issue by the Host. The current UVC webcam gadget design generates a STREAMON event corresponding to a set_interface(alt setting 1) command from the Host. This STREAMON event will eventually be routed to a real V4L2 device. To start video streaming, it may be required to perform some register writes to a camera sensor device over slow external busses like I2C or SPI. So, it makes sense to ensure that we delay the STATUS stage of the set_interface (alt setting 1) command. Otherwise, a lot of ISOC IN tokens sent by the Host will be replied to by zero-length packets by the webcam device. On certain Hosts this may even lead to ISOC URBs been cancelled from the Host side. So, as soon as we finish doing all the "streaming" related stuff on the real V4L2 device, we call a STREAMON ioctl on the UVC side and from here we call the 'usb_composite_setup_continue' function to complete the status stage of the set_interface(alt setting 1) command. Further, we need to ensure that we queue no video buffers on the UVC webcam gadget, until we de-queue a video buffer from the V4L2 device. So, the application should call the STREAMON on UVC side only when it has dequeued sufficient buffers from the V4L2 side and queued them to the UVC gadget. Signed-off-by: Bhupesh Sharma Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 15 +++++++++------ drivers/usb/gadget/uvc.h | 1 + drivers/usb/gadget/uvc_v4l2.c | 14 +++++++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 49939e44ed74..38dcedddc52c 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -266,6 +266,13 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) return 0; } +void uvc_function_setup_continue(struct uvc_device *uvc) +{ + struct usb_composite_dev *cdev = uvc->func.config->cdev; + + usb_composite_setup_continue(cdev); +} + static int uvc_function_get_alt(struct usb_function *f, unsigned interface) { @@ -328,7 +335,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) v4l2_event_queue(uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_CONNECTED; - break; + return 0; case 1: if (uvc->state != UVC_STATE_CONNECTED) @@ -345,15 +352,11 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; v4l2_event_queue(uvc->vdev, &v4l2_event); - - uvc->state = UVC_STATE_STREAMING; - break; + return USB_GADGET_DELAYED_STATUS; default: return -EINVAL; } - - return 0; } static void diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index 7e90b1d12d09..817e9e19cecf 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -188,6 +188,7 @@ struct uvc_file_handle * Functions */ +extern void uvc_function_setup_continue(struct uvc_device *uvc); extern void uvc_endpoint_stream(struct uvc_device *dev); extern void uvc_function_connect(struct uvc_device *uvc); diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 0080d073bd5e..2bb5af8d2b23 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -253,7 +253,19 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (*type != video->queue.type) return -EINVAL; - return uvc_video_enable(video, 1); + /* Enable UVC video. */ + ret = uvc_video_enable(video, 1); + if (ret < 0) + return ret; + + /* + * Complete the alternate setting selection setup phase now that + * userspace is ready to provide video frames. + */ + uvc_function_setup_continue(uvc); + uvc->state = UVC_STATE_STREAMING; + + return 0; } case VIDIOC_STREAMOFF: -- cgit From 326b0e613bc858434198120a17d34308f82c27a8 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Fri, 1 Mar 2013 20:46:31 +0100 Subject: usb: gadget: uvc: Make video streaming buffer size comply with USB3.0 SS As per the USB3.0 specs, the bandwidth requirements of a UVC's video streaming endpoint will change to support super-speed. These changes will be dependent on whether the UVC video streaming endpoint is Bulk or Isochronous: - If video streaming endpoint is Isochronous: As per Section 4.4.8.2 (Isochronous Transfer Bandwidth Requirements) of the USB3.0 specs: A SuperSpeed isochronous endpoint can move up to three burst transactions of up to 16 maximum sized packets (3 * 16 * 1024 bytes) per service interval. - If video streaming endpoint is Bulk: As per 4.4.6.1 (Bulk Transfer Data Packet Size) of the USB3.0 specs: An endpoint for bulk transfers shall set the maximum data packet payload size in its endpoint descriptor to 1024 bytes. It also specifies the burst size that the endpoint can accept from or transmit on the SuperSpeed bus. The allowable burst size for a bulk endpoint shall be in the range of 1 to 16. So, in the Isochronous case, we can define the USB request's buffer to be equal to = (Maximum packet size) * (bMaxBurst + 1) * (Mult + 1), so that the UDC driver can try to send out this buffer in one Isochronous service interval. The same computation will hold good for the Bulk case as the Mult value is 0 here and we can have a USB request buffer of maximum 16 * 1024 bytes size, which can be sent out by the UDC driver as per the Bulk bandwidth allocation on the USB3 bus. This patch adds the above-mentioned support and is also USB2.0 backward compliant. Signed-off-by: Bhupesh Sharma Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_video.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_video.c b/drivers/usb/gadget/uvc_video.c index 885c393ee470..fac99a97b782 100644 --- a/drivers/usb/gadget/uvc_video.c +++ b/drivers/usb/gadget/uvc_video.c @@ -229,13 +229,18 @@ uvc_video_free_requests(struct uvc_video *video) static int uvc_video_alloc_requests(struct uvc_video *video) { + unsigned int req_size; unsigned int i; int ret = -ENOMEM; BUG_ON(video->req_size); + req_size = video->ep->maxpacket + * max_t(unsigned int, video->ep->maxburst, 1) + * (video->ep->mult + 1); + for (i = 0; i < UVC_NUM_REQUESTS; ++i) { - video->req_buffer[i] = kmalloc(video->ep->maxpacket, GFP_KERNEL); + video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL); if (video->req_buffer[i] == NULL) goto error; @@ -251,7 +256,8 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&video->req[i]->list, &video->req_free); } - video->req_size = video->ep->maxpacket; + video->req_size = req_size; + return 0; error: -- cgit From 6854bcdc6ff92e3a9c24940a3c5ebb446950c974 Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Fri, 1 Mar 2013 20:46:32 +0100 Subject: usb: gadget: uvc: Use GFP_ATOMIC under spin lock Found using the following semantic patch: @@ @@ spin_lock_irqsave(...); ... when != spin_unlock_irqrestore(...); * GFP_KERNEL Signed-off-by: Cyril Roelandt Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_video.c b/drivers/usb/gadget/uvc_video.c index fac99a97b782..ec4bcc4a2290 100644 --- a/drivers/usb/gadget/uvc_video.c +++ b/drivers/usb/gadget/uvc_video.c @@ -314,7 +314,8 @@ uvc_video_pump(struct uvc_video *video) video->encode(req, video, buf); /* Queue the USB request */ - if ((ret = usb_ep_queue(video->ep, req, GFP_KERNEL)) < 0) { + ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); + if (ret < 0) { printk(KERN_INFO "Failed to queue request (%d)\n", ret); usb_ep_set_halt(video->ep); spin_unlock_irqrestore(&video->queue.irqlock, flags); -- cgit From c3ec830d8925d904f8826d52227d7dfb5dee922c Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Fri, 1 Mar 2013 20:46:33 +0100 Subject: usb: gadget: uvc: Use strlcpy instead of strncpy For NULL terminated string, better notice '\0' in the end. Signed-off-by: Chen Gang Signed-off-by: Laurent Pinchart Tested-by: Bhupesh Sharma Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_v4l2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2bb5af8d2b23..a6c728ab6aba 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -177,9 +177,9 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_capability *cap = arg; memset(cap, 0, sizeof *cap); - strncpy(cap->driver, "g_uvc", sizeof(cap->driver)); - strncpy(cap->card, cdev->gadget->name, sizeof(cap->card)); - strncpy(cap->bus_info, dev_name(&cdev->gadget->dev), + strlcpy(cap->driver, "g_uvc", sizeof(cap->driver)); + strlcpy(cap->card, cdev->gadget->name, sizeof(cap->card)); + strlcpy(cap->bus_info, dev_name(&cdev->gadget->dev), sizeof cap->bus_info); cap->version = DRIVER_VERSION_NUMBER; cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; -- cgit From eee44da0453cfe9125f4297e4244fe1d6fb1c653 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 7 Mar 2013 18:51:46 +0530 Subject: usb: musb: omap2430: replace *_* with *-* in property names No functional change. Replace *_* with *-* in property names of otg to follow the general convention. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/omap-usb.txt | 12 ++++++------ drivers/usb/musb/omap2430.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 1b9f55fd96c0..662f0f1d2315 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -8,10 +8,10 @@ OMAP MUSB GLUE and disconnect. - multipoint : Should be "1" indicating the musb controller supports multipoint. This is a MUSB configuration-specific setting. - - num_eps : Specifies the number of endpoints. This is also a + - num-eps : Specifies the number of endpoints. This is also a MUSB configuration-specific setting. Should be set to "16" - - ram_bits : Specifies the ram address size. Should be set to "12" - - interface_type : This is a board specific setting to describe the type of + - ram-bits : Specifies the ram address size. Should be set to "12" + - interface-type : This is a board specific setting to describe the type of interface between the controller and the phy. It should be "0" or "1" specifying ULPI and UTMI respectively. - mode : Should be "3" to represent OTG. "1" signifies HOST and "2" @@ -29,14 +29,14 @@ usb_otg_hs: usb_otg_hs@4a0ab000 { ti,hwmods = "usb_otg_hs"; ti,has-mailbox; multipoint = <1>; - num_eps = <16>; - ram_bits = <12>; + num-eps = <16>; + ram-bits = <12>; ctrl-module = <&omap_control_usb>; }; Board specific device node entry &usb_otg_hs { - interface_type = <1>; + interface-type = <1>; mode = <3>; power = <50>; }; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 8ba9bb2a91a7..e7b5eae5a141 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -526,10 +526,10 @@ static int omap2430_probe(struct platform_device *pdev) } of_property_read_u32(np, "mode", (u32 *)&pdata->mode); - of_property_read_u32(np, "interface_type", + of_property_read_u32(np, "interface-type", (u32 *)&data->interface_type); - of_property_read_u32(np, "num_eps", (u32 *)&config->num_eps); - of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); + of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); + of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); of_property_read_u32(np, "power", (u32 *)&pdata->power); config->multipoint = of_property_read_bool(np, "multipoint"); pdata->has_mailbox = of_property_read_bool(np, -- cgit From a33bb2120851407b5703343596d5c2181cfc75b4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Mar 2013 16:00:58 +0200 Subject: usb: dwc3: omap: fix sparse warning our global '_omap' pointer wasn't marked static. This patch solves the following sparse warning: warning: symbol '_omap' was not declared. \ Should it be static? Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 2fe9723ff1df..6de734f494bd 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -126,7 +126,7 @@ struct dwc3_omap { u32 dma_status:1; }; -struct dwc3_omap *_omap; +static struct dwc3_omap *_omap; static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) { -- cgit From a5eaaa1f33e771fa1651a4a7652b8a5f9fa7f6c1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Mar 2013 11:01:05 +0300 Subject: usb: gadget: uvc: use capped length value "req->length" is a capped version of "data->length". Signed-off-by: Dan Carpenter Acked-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index a6c728ab6aba..bb140dd93164 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -42,7 +42,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) req->length = min_t(unsigned int, uvc->event_length, data->length); req->zero = data->length < uvc->event_length; - memcpy(req->buf, data->data, data->length); + memcpy(req->buf, data->data, req->length); return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL); } -- cgit From bb467cf5693b59c76c22b73dd383920a87f37b16 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 14 Mar 2013 11:53:56 +0530 Subject: usb: musb: omap: remove the check before calling otg_set_vbus No functional change. otg_set_vbus is already protected so removed the check before calling otg_set_vbus. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index e7b5eae5a141..018373d1c2c4 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -174,8 +174,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) } } - if (otg->set_vbus) - otg_set_vbus(otg, 1); + otg_set_vbus(otg, 1); } else { musb->is_active = 1; otg->default_a = 1; @@ -296,10 +295,9 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) pm_runtime_put_autosuspend(dev); } - if (data->interface_type == MUSB_INTERFACE_UTMI) { - if (musb->xceiv->otg->set_vbus) - otg_set_vbus(musb->xceiv->otg, 0); - } + if (data->interface_type == MUSB_INTERFACE_UTMI) + otg_set_vbus(musb->xceiv->otg, 0); + omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DISCONNECT); break; -- cgit From 3bf6db9bbe4ad7b08b714c1857a703c1ef1b1e83 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 14 Mar 2013 11:53:58 +0530 Subject: usb: musb: omap: add usb_phy_init in omap2430_musb_init Some PHYs load too early (twl4030) making omap glue to miss cable connect events if the board is booted with cable connected. So adding usb_phy_init in omap2430_musb_init lets PHYs to report events once glue is ready. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 018373d1c2c4..ec460eaed842 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -391,6 +391,8 @@ static int omap2430_musb_init(struct musb *musb) if (glue->status != OMAP_MUSB_UNKNOWN) omap_musb_set_mailbox(glue); + usb_phy_init(musb->xceiv); + pm_runtime_put_noidle(musb->controller); return 0; -- cgit From 9166902c435b4847c1987188294407b24e76d9e6 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 15 Mar 2013 18:58:51 +0530 Subject: usb: phy: twl4030: use devres API for regulator get and request irq Used devres APIs devm_request_threaded_irq and devm_regulator_get for requesting irq and for getting regulator respectively. Signed-off-by: Kishon Vijay Abraham I Tested-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index a994715a3101..e14b03e7ad70 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -432,7 +432,7 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl) /* Initialize 3.1V regulator */ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); - twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); + twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1"); if (IS_ERR(twl->usb3v1)) return -ENODEV; @@ -441,18 +441,18 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl) /* Initialize 1.5V regulator */ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); - twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); + twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5"); if (IS_ERR(twl->usb1v5)) - goto fail1; + return -ENODEV; twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); /* Initialize 1.8V regulator */ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); - twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); + twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8"); if (IS_ERR(twl->usb1v8)) - goto fail2; + return -ENODEV; twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); @@ -461,14 +461,6 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl) TWL4030_PM_MASTER_PROTECT_KEY); return 0; - -fail2: - regulator_put(twl->usb1v5); - twl->usb1v5 = NULL; -fail1: - regulator_put(twl->usb3v1); - twl->usb3v1 = NULL; - return -ENODEV; } static ssize_t twl4030_usb_vbus_show(struct device *dev, @@ -640,9 +632,9 @@ static int twl4030_usb_probe(struct platform_device *pdev) * need both handles, otherwise just one suffices. */ twl->irq_enabled = true; - status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT, "twl4030_usb", twl); + status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, + twl4030_usb_irq, IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); @@ -663,7 +655,6 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; - free_irq(twl->irq, twl); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ @@ -685,9 +676,6 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) if (!twl->asleep) twl4030_phy_power(twl, 0); - regulator_put(twl->usb1v5); - regulator_put(twl->usb1v8); - regulator_put(twl->usb3v1); return 0; } -- cgit From 817e5f33d0c12f24bdfebe88c96ca2e968756da4 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 15 Mar 2013 18:58:52 +0530 Subject: usb: phy: twl4030: fix cold plug on OMAP3 Having twl4030_usb_phy_init() (detects if a cable is connected before twl4030 is probed) in twl4030 probe makes cable connect events to be missed by musb glue, since it gets loaded after twl4030. Having twl4030_usb_phy_init as a usb_phy ops lets twl4030_usb_phy_init to be called when glue is ready. Signed-off-by: Kishon Vijay Abraham I Tested-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index e14b03e7ad70..1986c782346f 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -510,8 +510,9 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) return IRQ_HANDLED; } -static void twl4030_usb_phy_init(struct twl4030_usb *twl) +static int twl4030_usb_phy_init(struct usb_phy *phy) { + struct twl4030_usb *twl = phy_to_twl(phy); enum omap_musb_vbus_id_status status; status = twl4030_usb_linkstat(twl); @@ -528,6 +529,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) omap_musb_mailbox(twl->linkstat); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); + return 0; } static int twl4030_set_suspend(struct usb_phy *x, int suspend) @@ -604,6 +606,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) twl->phy.otg = otg; twl->phy.type = USB_PHY_TYPE_USB2; twl->phy.set_suspend = twl4030_set_suspend; + twl->phy.init = twl4030_usb_phy_init; otg->phy = &twl->phy; otg->set_host = twl4030_set_host; @@ -641,11 +644,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) return status; } - /* Power down phy or make it work according to - * current link state. - */ - twl4030_usb_phy_init(twl); - dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); return 0; } -- cgit From d105e7f86f890a530cdefc2a715121345de30dc2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 10:52:08 +0200 Subject: usb: dwc3: fix PHY error handling PHY layer no longer returns NULL. It will return -ENXIO when PHY layer isn't enabled and we can use that to bail out instead of request a probe deferral. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c845e7087069..e2325adf9c14 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -434,12 +434,32 @@ static int dwc3_probe(struct platform_device *pdev) dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } - if (IS_ERR_OR_NULL(dwc->usb2_phy)) { + if (IS_ERR(dwc->usb2_phy)) { + ret = PTR_ERR(dwc->usb2_phy); + + /* + * if -ENXIO is returned, it means PHY layer wasn't + * enabled, so it makes no sense to return -EPROBE_DEFER + * in that case, since no PHY driver will ever probe. + */ + if (ret == -ENXIO) + return ret; + dev_err(dev, "no usb2 phy configured\n"); return -EPROBE_DEFER; } - if (IS_ERR_OR_NULL(dwc->usb3_phy)) { + if (IS_ERR(dwc->usb3_phy)) { + ret = PTR_ERR(dwc->usb2_phy); + + /* + * if -ENXIO is returned, it means PHY layer wasn't + * enabled, so it makes no sense to return -EPROBE_DEFER + * in that case, since no PHY driver will ever probe. + */ + if (ret == -ENXIO) + return ret; + dev_err(dev, "no usb3 phy configured\n"); return -EPROBE_DEFER; } -- cgit From 4dbb71612505de1d3d69d011199554f86273c5e9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 10:54:59 +0200 Subject: usb: gadget: mv_udc_core: fix PHY error handling PHY layer no longer returns NULL. It will return -ENXIO when PHY layer isn't enabled and we can use that to bail out instead of request a probe deferral. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index d550b2129133..9a68c051a5a8 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2127,16 +2127,19 @@ static int mv_udc_probe(struct platform_device *pdev) udc->dev = pdev; -#if IS_ENABLED(CONFIG_USB_PHY) if (pdata->mode == MV_USB_MODE_OTG) { udc->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(udc->transceiver)) { + if (IS_ERR(udc->transceiver)) { + retval = PTR_ERR(udc->transceiver); + + if (retval == -ENXIO) + return retval; + udc->transceiver = NULL; - return -ENODEV; + return -EPROBE_DEFER; } } -#endif udc->clknum = pdata->clknum; for (clk_i = 0; clk_i < udc->clknum; clk_i++) { -- cgit From f4f5ba5e7d9e087f044fe87f5a5421761274aa48 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 10:56:19 +0200 Subject: usb: gadget: s3c-hsotg: fix PHY error handling PHY laye rno longer return NULL. We need to switch over from IS_ERR_OR_NULL() to IS_ERR(). Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f1ceabff7cce..a3cdc32115d5 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3467,7 +3467,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) } phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(phy)) { + if (IS_ERR(phy)) { /* Fallback for pdata */ plat = pdev->dev.platform_data; if (!plat) { -- cgit From a90199bb947856c24d7bf78845d24f802e09db0a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 10:57:40 +0200 Subject: usb: musb: omap2430: fix PHY error handling PHY layer no longer returns NULL. It will return -ENXIO when PHY layer isn't enabled and we can use that to bail out instead of request a probe deferral. Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index ec460eaed842..798e029e3db0 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -353,7 +353,12 @@ static int omap2430_musb_init(struct musb *musb) else musb->xceiv = devm_usb_get_phy_dev(dev, 0); - if (IS_ERR_OR_NULL(musb->xceiv)) { + if (IS_ERR(musb->xceiv)) { + status = PTR_ERR(musb->xceiv); + + if (status == -ENXIO) + return status; + pr_err("HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER; } -- cgit From e299bd93e4fb8e3fa426d30e0a0796b99052a572 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 11:02:56 +0200 Subject: usb: host: ehci-msm: fix PHY error handling PHY layer no longer returns NULL. We must switch from IS_ERR_OR_NULL() to IS_ERR(). Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 88a49c87e748..ebf410311957 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -145,7 +145,7 @@ static int ehci_msm_probe(struct platform_device *pdev) * management. */ phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(phy)) { + if (IS_ERR(phy)) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; goto put_hcd; -- cgit From 6f3ed4ec182d191d1ba48fbf5aed021d2d00dd37 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 11:03:30 +0200 Subject: usb: host: ehci-mv: fix PHY error handling PHY layer no longer returns NULL. We must switch from IS_ERR_OR_NULL() to IS_ERR(). Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-mv.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 9751823395e1..38048200977c 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -240,12 +240,16 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { -#if IS_ENABLED(CONFIG_USB_PHY) ehci_mv->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(ehci_mv->otg)) { - dev_err(&pdev->dev, - "unable to find transceiver\n"); - retval = -ENODEV; + if (IS_ERR(ehci_mv->otg)) { + retval = PTR_ERR(ehci_mv->otg); + + if (retval == -ENXIO) + dev_info(&pdev->dev, "MV_USB_MODE_OTG " + "must have CONFIG_USB_PHY enabled\n"); + else + dev_err(&pdev->dev, + "unable to find transceiver\n"); goto err_disable_clk; } @@ -258,11 +262,6 @@ static int mv_ehci_probe(struct platform_device *pdev) } /* otg will enable clock before use as host */ mv_ehci_disable(ehci_mv); -#else - dev_info(&pdev->dev, "MV_USB_MODE_OTG " - "must have CONFIG_USB_PHY enabled\n"); - goto err_disable_clk; -#endif } else { if (pdata->set_vbus) pdata->set_vbus(1); -- cgit From a16283e11d4443430b826c7b131a244e494ac53c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 11:04:15 +0200 Subject: usb: host: ehci-s5p: fix PHY error handling PHY layer no longer returns NULL. We must switch from IS_ERR_OR_NULL() to IS_ERR(). Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-s5p.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 20ebf6a8b7f4..867a92390ef9 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -139,7 +139,7 @@ static int s5p_ehci_probe(struct platform_device *pdev) return -ENOMEM; phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(phy)) { + if (IS_ERR(phy)) { /* Fallback to pdata */ if (!pdata) { dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); -- cgit From 806b2139db236e0cbd0b5833ab0ce139f0196bcd Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 15 Mar 2013 12:59:30 +0100 Subject: sfc: Fix Kconfig typo "----help---" Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/net/ethernet/sfc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 435b4f1e3488..4136ccc4a954 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -24,7 +24,7 @@ config SFC_MCDI_MON bool "Solarflare SFC9000-family hwmon support" depends on SFC && HWMON && !(SFC=y && HWMON=m) default y - ----help--- + ---help--- This exposes the on-board firmware-managed sensors as a hardware monitor device. config SFC_SRIOV -- cgit From bb64469af5908d89766b116d91c0691fe3c9237a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Mar 2013 23:07:02 +0800 Subject: HID: steelseries: use module_hid_driver() to simplify the code module_hid_driver() makes the code simpler by eliminating boilerplate code.. Signed-off-by: Wei Yongjun Signed-off-by: Jiri Kosina --- drivers/hid/hid-steelseries.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c index 2ed995cda44a..136d156d0a44 100644 --- a/drivers/hid/hid-steelseries.c +++ b/drivers/hid/hid-steelseries.c @@ -378,16 +378,5 @@ static struct hid_driver steelseries_srws1_driver = { .report_fixup = steelseries_srws1_report_fixup }; -static int __init steelseries_srws1_init(void) -{ - return hid_register_driver(&steelseries_srws1_driver); -} - -static void __exit steelseries_srws1_exit(void) -{ - hid_unregister_driver(&steelseries_srws1_driver); -} - -module_init(steelseries_srws1_init); -module_exit(steelseries_srws1_exit); +module_hid_driver(steelseries_srws1_driver); MODULE_LICENSE("GPL"); -- cgit From e72c27464cce59be432e6322a407a4d94626f8df Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Wed, 6 Mar 2013 08:56:06 +0200 Subject: ath6kl: print firmware capabilities Printin the firmware capabilities during the first firmware boot makes it easier to find out what features firmware supports. Obligatory screenshot: [21025.678481] ath6kl: ar6003 hw 2.1.1 sdio fw 3.2.0.144 api 3 [21025.678667] ath6kl: firmware supports: sched-scan,sta-p2pdev-duplex,rsn-cap-override Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 072a2295eff8..3e45adc4a5c2 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1549,10 +1549,81 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type) return NULL; } + +static const struct fw_capa_str_map { + int id; + const char *name; +} fw_capa_map[] = { + { ATH6KL_FW_CAPABILITY_HOST_P2P, "host-p2p" }, + { ATH6KL_FW_CAPABILITY_SCHED_SCAN, "sched-scan" }, + { ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, "sta-p2pdev-duplex" }, + { ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, "inactivity-timeout" }, + { ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, "rsn-cap-override" }, + { ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, "wow-mc-filter" }, + { ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, "bmiss-enhance" }, + { ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, "sscan-match-list" }, + { ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, "rssi-scan-thold" }, + { ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, "custom-mac-addr" }, + { ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, "tx-err-notify" }, + { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" }, + { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" }, + { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" }, +}; + +static const char *ath6kl_init_get_fw_capa_name(unsigned int id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fw_capa_map); i++) { + if (fw_capa_map[i].id == id) + return fw_capa_map[i].name; + } + + return ""; +} + +static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len) +{ + u8 *data = (u8 *) ar->fw_capabilities; + size_t trunc_len, len = 0; + int i, index, bit; + char *trunc = "..."; + + for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) { + index = i / 8; + bit = i % 8; + + if (index >= sizeof(ar->fw_capabilities) * 4) + break; + + if (buf_len - len < 4) { + ath6kl_warn("firmware capability buffer too small!\n"); + + /* add "..." to the end of string */ + trunc_len = strlen(trunc) + 1; + strncpy(buf + buf_len - trunc_len, trunc, trunc_len); + + return; + } + + if (data[index] & (1 << bit)) { + len += scnprintf(buf + len, buf_len - len, "%s,", + ath6kl_init_get_fw_capa_name(i)); + } + } + + /* overwrite the last comma */ + if (len > 0) + len--; + + buf[len] = '\0'; +} + static int __ath6kl_init_hw_start(struct ath6kl *ar) { long timeleft; int ret, i; + char buf[200]; ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n"); @@ -1615,6 +1686,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) ar->wiphy->fw_version, ar->fw_api, test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); + ath6kl_init_get_fwcaps(ar, buf, sizeof(buf)); + ath6kl_info("firmware supports: %s\n", buf); } if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { -- cgit From ec1461dc30feb422af65ee849137f56e7f87f55e Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sat, 9 Mar 2013 12:01:35 +0200 Subject: ath6kl: cleanup ath6kl_reset_device() Move it to init.c, make it static, remove all useless checks and force it to always do cold reset. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 2 -- drivers/net/wireless/ath/ath6kl/init.c | 12 +++++++++--- drivers/net/wireless/ath/ath6kl/main.c | 33 -------------------------------- drivers/net/wireless/ath/ath6kl/target.h | 2 +- 4 files changed, 10 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 1c9ed40358d8..26b0f92424e1 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -935,8 +935,6 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, u8 win_sz); void ath6kl_wakeup_event(void *dev); -void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, - bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 3e45adc4a5c2..ae1e477ec0d2 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1619,6 +1619,14 @@ static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len) buf[len] = '\0'; } +static int ath6kl_init_hw_reset(struct ath6kl *ar) +{ + ath6kl_dbg(ATH6KL_DBG_BOOT, "cold resetting the device"); + + return ath6kl_diag_write32(ar, RESET_CONTROL_ADDRESS, + cpu_to_le32(RESET_CONTROL_COLD_RST)); +} + static int __ath6kl_init_hw_start(struct ath6kl *ar) { long timeleft; @@ -1836,9 +1844,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar) * Try to reset the device if we can. The driver may have been * configure NOT to reset the target during a debug session. */ - ath6kl_dbg(ATH6KL_DBG_TRC, - "attempting to reset target on instance destroy\n"); - ath6kl_reset_device(ar, ar->target_type, true, true); + ath6kl_init_hw_reset(ar); up(&ar->sem); } diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index bd50b6b7b492..bad62b3357b9 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -345,39 +345,6 @@ out: return ret; } -/* FIXME: move to a better place, target.h? */ -#define AR6003_RESET_CONTROL_ADDRESS 0x00004000 -#define AR6004_RESET_CONTROL_ADDRESS 0x00004000 - -void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, - bool wait_fot_compltn, bool cold_reset) -{ - int status = 0; - u32 address; - __le32 data; - - if (target_type != TARGET_TYPE_AR6003 && - target_type != TARGET_TYPE_AR6004) - return; - - data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) : - cpu_to_le32(RESET_CONTROL_MBOX_RST); - - switch (target_type) { - case TARGET_TYPE_AR6003: - address = AR6003_RESET_CONTROL_ADDRESS; - break; - case TARGET_TYPE_AR6004: - address = AR6004_RESET_CONTROL_ADDRESS; - break; - } - - status = ath6kl_diag_write32(ar, address, data); - - if (status) - ath6kl_err("failed to reset target\n"); -} - static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) { u8 index; diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index a98c12ba70c1..a580a629a0da 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -25,7 +25,7 @@ #define AR6004_BOARD_DATA_SZ 6144 #define AR6004_BOARD_EXT_DATA_SZ 0 -#define RESET_CONTROL_ADDRESS 0x00000000 +#define RESET_CONTROL_ADDRESS 0x00004000 #define RESET_CONTROL_COLD_RST 0x00000100 #define RESET_CONTROL_MBOX_RST 0x00000004 -- cgit From 4e1609c9eec2bf9971004fce8b65c0877d5ae600 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sat, 9 Mar 2013 12:01:43 +0200 Subject: ath6kl: fix usb related error handling and warnings It was annoying to debug usb warm reboot initialisation problems as many usb related functions just ignored errors and it wasn't obvious from the kernel logs what was failing. Fix all that so that error messages are printed and errors are handled properly. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 10 ++++----- drivers/net/wireless/ath/ath6kl/init.c | 10 +++++---- drivers/net/wireless/ath/ath6kl/usb.c | 34 +++++++++++++++++++----------- 3 files changed, 33 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index 9adb56741bc3..c02d9d34f74d 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -1167,7 +1167,7 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target) } if (count <= 0) { - ath6kl_dbg(ATH6KL_DBG_HTC, "%s: Timeout!\n", __func__); + ath6kl_warn("htc pipe control receive timeout!\n"); return -ECOMM; } @@ -1581,16 +1581,16 @@ static int ath6kl_htc_pipe_wait_target(struct htc_target *target) return status; if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) { - ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg len:%d!\n", - target->pipe.ctrl_response_len); + ath6kl_warn("invalid htc pipe ready msg len: %d\n", + target->pipe.ctrl_response_len); return -ECOMM; } ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf; if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) { - ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg : 0x%X !\n", - ready_msg->ver2_0_info.msg_id); + ath6kl_warn("invalid htc pipe ready msg: 0x%x\n", + ready_msg->ver2_0_info.msg_id); return -ECOMM; } diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index ae1e477ec0d2..8b01ec3d2b8c 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1657,13 +1657,15 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) * driver layer has to init BMI in order to set the host block * size. */ - if (ath6kl_htc_wait_target(ar->htc_target)) { - ret = -EIO; + ret = ath6kl_htc_wait_target(ar->htc_target); + if (ret) { + ath6kl_err("htc wait target failed: %d\n", ret); goto err_power_off; } - if (ath6kl_init_service_ep(ar)) { - ret = -EIO; + ret = ath6kl_init_service_ep(ar); + if (ret) { + ath6kl_err("Endpoint service initilisation failed: %d\n", ret); goto err_cleanup_scatter; } diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 5fcd342762de..63948f6c9f17 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -872,8 +872,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, size, 1000); if (ret < 0) { - ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", - __func__, ret); + ath6kl_warn("Failed to submit usb control message: %d\n", ret); + kfree(buf); + return ret; } kfree(buf); @@ -903,8 +904,9 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, size, 2 * HZ); if (ret < 0) { - ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", - __func__, ret); + ath6kl_warn("Failed to read usb control message: %d\n", ret); + kfree(buf); + return ret; } memcpy((u8 *) data, buf, size); @@ -961,8 +963,10 @@ static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) ATH6KL_USB_CONTROL_REQ_DIAG_RESP, ar_usb->diag_resp_buffer, &resp_len); - if (ret) + if (ret) { + ath6kl_warn("diag read32 failed: %d\n", ret); return ret; + } resp = (struct ath6kl_usb_ctrl_diag_resp_read *) ar_usb->diag_resp_buffer; @@ -976,6 +980,7 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) { struct ath6kl_usb *ar_usb = ar->hif_priv; struct ath6kl_usb_ctrl_diag_cmd_write *cmd; + int ret; cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; @@ -984,12 +989,17 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) cmd->address = cpu_to_le32(address); cmd->value = data; - return ath6kl_usb_ctrl_msg_exchange(ar_usb, - ATH6KL_USB_CONTROL_REQ_DIAG_CMD, - (u8 *) cmd, - sizeof(*cmd), - 0, NULL, NULL); + ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(*cmd), + 0, NULL, NULL); + if (ret) { + ath6kl_warn("diag_write32 failed: %d\n", ret); + return ret; + } + return 0; } static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) @@ -1001,7 +1011,7 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) ret = ath6kl_usb_submit_ctrl_in(ar_usb, ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, 0, 0, buf, len); - if (ret != 0) { + if (ret) { ath6kl_err("Unable to read the bmi data from the device: %d\n", ret); return ret; @@ -1019,7 +1029,7 @@ static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) ret = ath6kl_usb_submit_ctrl_out(ar_usb, ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, 0, 0, buf, len); - if (ret != 0) { + if (ret) { ath6kl_err("unable to send the bmi data to the device: %d\n", ret); return ret; -- cgit From 44af34428dfdce0472cb229b013c72710285d2db Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sat, 9 Mar 2013 12:01:50 +0200 Subject: ath6kl: cold reset target after host warm boot Julien reported that ar6004 usb device fails to initialise after host has been rebooted and power is still on for the ar6004 device. He found out that doing a cold reset fixes the issue. I wasn't sure what would be the best way to detect if target needs a reset so I settled on checking a timeout from htc_wait_recv_ctrl_message(). Reported-by: Julien Massot Tested-by: Julien Massot Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 2 +- drivers/net/wireless/ath/ath6kl/init.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index c02d9d34f74d..67aa924ed8b3 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -1168,7 +1168,7 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target) if (count <= 0) { ath6kl_warn("htc pipe control receive timeout!\n"); - return -ECOMM; + return -ETIMEDOUT; } return 0; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 8b01ec3d2b8c..4ad45bb3cf55 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1658,7 +1658,18 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) * size. */ ret = ath6kl_htc_wait_target(ar->htc_target); - if (ret) { + + if (ret == -ETIMEDOUT) { + /* + * Most likely USB target is in odd state after reboot and + * needs a reset. A cold reset makes the whole device + * disappear from USB bus and initialisation starts from + * beginning. + */ + ath6kl_warn("htc wait target timed out, resetting device\n"); + ath6kl_init_hw_reset(ar); + goto err_power_off; + } else if (ret) { ath6kl_err("htc wait target failed: %d\n", ret); goto err_power_off; } -- cgit From fe9ab00f8354a4c388e30301859c5741590c3809 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 14 Mar 2013 13:21:00 +0000 Subject: dell-laptop: Fix krealloc() misuse in parse_da_table() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If krealloc() returns NULL, it *doesn't* free the original. So any code of the form 'foo = krealloc(foo, …);' is almost certainly a bug. Signed-off-by: David Woodhouse --- drivers/platform/x86/dell-laptop.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index fa3ee6209572..1134119521ac 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -284,6 +284,7 @@ static void __init parse_da_table(const struct dmi_header *dm) { /* Final token is a terminator, so we don't want to copy it */ int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1; + struct calling_interface_token *new_da_tokens; struct calling_interface_structure *table = container_of(dm, struct calling_interface_structure, header); @@ -296,12 +297,13 @@ static void __init parse_da_table(const struct dmi_header *dm) da_command_address = table->cmdIOAddress; da_command_code = table->cmdIOCode; - da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) * - sizeof(struct calling_interface_token), - GFP_KERNEL); + new_da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) * + sizeof(struct calling_interface_token), + GFP_KERNEL); - if (!da_tokens) + if (!new_da_tokens) return; + da_tokens = new_da_tokens; memcpy(da_tokens+da_num_tokens, table->tokens, sizeof(struct calling_interface_token) * tokens); -- cgit From 416cf0b49e67254676b4762d1bab88df5130f909 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:20 +0200 Subject: ath6kl: add tracing support and tracing points for wmi packets Add basic tracing infrastructure support to ath6kl and which can be enabled with CONFIG_ATH6KL_TRACING. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Kconfig | 9 ++++ drivers/net/wireless/ath/ath6kl/Makefile | 5 ++ drivers/net/wireless/ath/ath6kl/trace.c | 18 +++++++ drivers/net/wireless/ath/ath6kl/trace.h | 87 ++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/txrx.c | 3 ++ drivers/net/wireless/ath/ath6kl/wmi.c | 3 ++ 6 files changed, 125 insertions(+) create mode 100644 drivers/net/wireless/ath/ath6kl/trace.c create mode 100644 drivers/net/wireless/ath/ath6kl/trace.h (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index 26c4b7220859..6971b7a395fe 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -31,6 +31,15 @@ config ATH6KL_DEBUG ---help--- Enables debug support +config ATH6KL_TRACING + bool "Atheros ath6kl tracing support" + depends on ATH6KL + depends on EVENT_TRACING + ---help--- + Select this to ath6kl use tracing infrastructure. + + If unsure, say Y to make it easier to debug problems. + config ATH6KL_REGDOMAIN bool "Atheros ath6kl regdomain support" depends on ATH6KL diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index cab0ec0d5380..dc2b3b46781e 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -35,10 +35,15 @@ ath6kl_core-y += txrx.o ath6kl_core-y += wmi.o ath6kl_core-y += core.o ath6kl_core-y += recovery.o + ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o +ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o ath6kl_sdio-y += sdio.o obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o ath6kl_usb-y += usb.o + +# for tracing framework to find trace.h +CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/ath/ath6kl/trace.c b/drivers/net/wireless/ath/ath6kl/trace.c new file mode 100644 index 000000000000..4118a29500c1 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/trace.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * + * 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. + */ + +#define CREATE_TRACE_POINTS +#include "trace.h" diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h new file mode 100644 index 000000000000..07876190ce05 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -0,0 +1,87 @@ +#if !defined(_ATH6KL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) + +#include +#include +#include +#include "wmi.h" + +#if !defined(_ATH6KL_TRACE_H) +static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len) +{ + struct wmi_cmd_hdr *hdr = buf; + + if (buf_len < sizeof(*hdr)) + return 0; + + return le16_to_cpu(hdr->cmd_id); +} +#endif /* __ATH6KL_TRACE_H */ + +#define _ATH6KL_TRACE_H + +/* create empty functions when tracing is disabled */ +#if !defined(CONFIG_ATH6KL_TRACING) +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, ...) \ +static inline void trace_ ## name(proto) {} +#endif /* !CONFIG_ATH6KL_TRACING || __CHECKER__ */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ath6kl + +TRACE_EVENT(ath6kl_wmi_cmd, + TP_PROTO(void *buf, size_t buf_len), + + TP_ARGS(buf, buf_len), + + TP_STRUCT__entry( + __field(unsigned int, id) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->id = ath6kl_get_wmi_id(buf, buf_len); + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "id %d len %d", + __entry->id, __entry->buf_len + ) +); + +TRACE_EVENT(ath6kl_wmi_event, + TP_PROTO(void *buf, size_t buf_len), + + TP_ARGS(buf, buf_len), + + TP_STRUCT__entry( + __field(unsigned int, id) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->id = ath6kl_get_wmi_id(buf, buf_len); + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "id %d len %d", + __entry->id, __entry->buf_len + ) +); + +#endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ + +/* we don't want to use include/trace/events */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +/* This part must be outside protection */ +#include diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 78b369286579..43dbdaadf577 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -20,6 +20,7 @@ #include "core.h" #include "debug.h" #include "htc-ops.h" +#include "trace.h" /* * tid - tid_mux0..tid_mux3 @@ -288,6 +289,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, int status = 0; struct ath6kl_cookie *cookie = NULL; + trace_ath6kl_wmi_cmd(skb->data, skb->len); + if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { dev_kfree_skb(skb); return -EACCES; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index d76b5bd81a0d..31a308103f4c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -20,6 +20,7 @@ #include "core.h" #include "debug.h" #include "testmode.h" +#include "trace.h" #include "../regd.h" #include "../regd_common.h" @@ -4086,6 +4087,8 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) return -EINVAL; } + trace_ath6kl_wmi_event(skb->data, skb->len); + return ath6kl_wmi_proc_events(wmi, skb); } -- cgit From e60c81543fd4edabe5b6fd2ea68d2db6f6204177 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:20 +0200 Subject: ath6kl: add tracing points for sdio transfers Add tracing points for sdio transfers, just dump the address, flags and the buffer. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 10 ++++ drivers/net/wireless/ath/ath6kl/trace.c | 5 ++ drivers/net/wireless/ath/ath6kl/trace.h | 90 +++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 0bd8ff69461a..fb141454c6d2 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -28,6 +28,7 @@ #include "target.h" #include "debug.h" #include "cfg80211.h" +#include "trace.h" struct ath6kl_sdio { struct sdio_func *func; @@ -179,6 +180,8 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr, request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len); ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len); + trace_ath6kl_sdio(addr, request, buf, len); + return ret; } @@ -309,6 +312,13 @@ static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio, sdio_claim_host(ar_sdio->func); mmc_set_data_timeout(&data, ar_sdio->func->card); + + trace_ath6kl_sdio_scat(scat_req->addr, + scat_req->req, + scat_req->len, + scat_req->scat_entries, + scat_req->scat_list); + /* synchronous call to process request */ mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req); diff --git a/drivers/net/wireless/ath/ath6kl/trace.c b/drivers/net/wireless/ath/ath6kl/trace.c index 4118a29500c1..e7d64b1285cb 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.c +++ b/drivers/net/wireless/ath/ath6kl/trace.c @@ -14,5 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #define CREATE_TRACE_POINTS #include "trace.h" + +EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio); +EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio_scat); diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index 07876190ce05..9db616c2ac96 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -4,6 +4,7 @@ #include #include #include "wmi.h" +#include "hif.h" #if !defined(_ATH6KL_TRACE_H) static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len) @@ -75,6 +76,95 @@ TRACE_EVENT(ath6kl_wmi_event, ) ); +TRACE_EVENT(ath6kl_sdio, + TP_PROTO(unsigned int addr, int flags, + void *buf, size_t buf_len), + + TP_ARGS(addr, flags, buf, buf_len), + + TP_STRUCT__entry( + __field(unsigned int, tx) + __field(unsigned int, addr) + __field(int, flags) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->addr = addr; + __entry->flags = flags; + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + + if (flags & HIF_WRITE) + __entry->tx = 1; + else + __entry->tx = 0; + ), + + TP_printk( + "%s addr 0x%x flags 0x%x len %d\n", + __entry->tx ? "tx" : "rx", + __entry->addr, + __entry->flags, + __entry->buf_len + ) +); + +TRACE_EVENT(ath6kl_sdio_scat, + TP_PROTO(unsigned int addr, int flags, unsigned int total_len, + unsigned int entries, struct hif_scatter_item *list), + + TP_ARGS(addr, flags, total_len, entries, list), + + TP_STRUCT__entry( + __field(unsigned int, tx) + __field(unsigned int, addr) + __field(int, flags) + __field(unsigned int, entries) + __field(size_t, total_len) + __dynamic_array(unsigned int, len_array, entries) + __dynamic_array(u8, data, total_len) + ), + + TP_fast_assign( + unsigned int *len_array; + int i, offset = 0; + size_t len; + + __entry->addr = addr; + __entry->flags = flags; + __entry->entries = entries; + __entry->total_len = total_len; + + if (flags & HIF_WRITE) + __entry->tx = 1; + else + __entry->tx = 0; + + len_array = __get_dynamic_array(len_array); + + for (i = 0; i < entries; i++) { + len = list[i].len; + + memcpy((u8 *) __get_dynamic_array(data) + offset, + list[i].buf, len); + + len_array[i] = len; + offset += len; + } + ), + + TP_printk( + "%s addr 0x%x flags 0x%x entries %d total_len %d\n", + __entry->tx ? "tx" : "rx", + __entry->addr, + __entry->flags, + __entry->entries, + __entry->total_len + ) +); + #endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- cgit From d57f093aababe358c9c9248fffb554722c15e837 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:21 +0200 Subject: ath6kl: add tracing point for hif irqs Add a tracing point for hif irq and dump the register content to user space. This is in hif.c as we could use the same code also with SPI but, as ath6kl doesn't SPI and most likely never will be, this is used just by SDIO so name the trace point as ath6kl_sdio_irq to make it easier to manage filters. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/hif.c | 3 +++ drivers/net/wireless/ath/ath6kl/trace.h | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index a6b614421fa4..fea7709b5dda 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -22,6 +22,7 @@ #include "target.h" #include "hif-ops.h" #include "debug.h" +#include "trace.h" #define MAILBOX_FOR_BLOCK_SIZE 1 @@ -436,6 +437,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) ath6kl_dump_registers(dev, &dev->irq_proc_reg, &dev->irq_en_reg); + trace_ath6kl_sdio_irq(&dev->irq_en_reg, + sizeof(dev->irq_en_reg)); /* Update only those registers that are enabled */ host_int_status = dev->irq_proc_reg.host_int_status & diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index 9db616c2ac96..541729b3d4c3 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -165,6 +165,26 @@ TRACE_EVENT(ath6kl_sdio_scat, ) ); +TRACE_EVENT(ath6kl_sdio_irq, + TP_PROTO(void *buf, size_t buf_len), + + TP_ARGS(buf, buf_len), + + TP_STRUCT__entry( + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "irq len %d\n", __entry->buf_len + ) +); + #endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- cgit From 4771979aab5ef964ef12803793fbb7884829944d Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:21 +0200 Subject: ath6kl: adding tracing points for htc_mbox Add tracing points for htc layer, just dumping the packets to user space. I wasn't really sure what to do with the status value, it might not always be accurate, but I included it anyway. I skipped htc_pipe (and usb) implementation for now. Need to add those tracepoints later. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc_mbox.c | 21 ++++++++++- drivers/net/wireless/ath/ath6kl/trace.h | 56 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index fbb78dfe078f..65e5b719093d 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -19,6 +19,8 @@ #include "hif.h" #include "debug.h" #include "hif-ops.h" +#include "trace.h" + #include #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) @@ -537,6 +539,8 @@ static int ath6kl_htc_tx_issue(struct htc_target *target, packet->buf, padded_len, HIF_WR_ASYNC_BLOCK_INC, packet); + trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len); + return status; } @@ -757,7 +761,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, { struct htc_target *target = endpoint->target; struct hif_scatter_req *scat_req = NULL; - int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; + int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0, i; + struct htc_packet *packet; int status; u32 txb_mask; u8 ac = WMM_NUM_AC; @@ -832,6 +837,13 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx scatter bytes %d entries %d\n", scat_req->len, scat_req->scat_entries); + + for (i = 0; i < scat_req->scat_entries; i++) { + packet = scat_req->scat_list[i].packet; + trace_ath6kl_htc_tx(packet->status, packet->endpoint, + packet->buf, packet->act_len); + } + ath6kl_hif_submit_scat_req(target->dev, scat_req, false); if (status) @@ -1903,6 +1915,7 @@ static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint, ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx complete ep %d packet 0x%p\n", endpoint->eid, packet); + endpoint->ep_cb.rx(endpoint->target, packet); } @@ -2011,6 +2024,9 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target, list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) { ep = &target->endpoint[packet->endpoint]; + trace_ath6kl_htc_rx(packet->status, packet->endpoint, + packet->buf, packet->act_len); + /* process header for each of the recv packet */ status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds, n_lk_ahd); @@ -2291,6 +2307,9 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target) if (ath6kl_htc_rx_packet(target, packet, packet->act_len)) goto fail_ctrl_rx; + trace_ath6kl_htc_rx(packet->status, packet->endpoint, + packet->buf, packet->act_len); + /* process receive header */ packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL); diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index 541729b3d4c3..306d58d89cc8 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -185,6 +185,62 @@ TRACE_EVENT(ath6kl_sdio_irq, ) ); +TRACE_EVENT(ath6kl_htc_rx, + TP_PROTO(int status, int endpoint, void *buf, + size_t buf_len), + + TP_ARGS(status, endpoint, buf, buf_len), + + TP_STRUCT__entry( + __field(int, status) + __field(int, endpoint) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->status = status; + __entry->endpoint = endpoint; + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "status %d endpoint %d len %d\n", + __entry->status, + __entry->endpoint, + __entry->buf_len + ) +); + +TRACE_EVENT(ath6kl_htc_tx, + TP_PROTO(int status, int endpoint, void *buf, + size_t buf_len), + + TP_ARGS(status, endpoint, buf, buf_len), + + TP_STRUCT__entry( + __field(int, status) + __field(int, endpoint) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __entry->status = status; + __entry->endpoint = endpoint; + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "status %d endpoint %d len %d\n", + __entry->status, + __entry->endpoint, + __entry->buf_len + ) +); + #endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- cgit From d470b4bcc18a8209972f85a257631e96c3cad3a4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:21 +0200 Subject: ath6kl: convert ath6kl_info/err/warn macros to real functions After this it's cleaner to add trace calls. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 51 +++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/debug.h | 10 ++----- 2 files changed, 54 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 15cfe30e54fd..2e248fac8523 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -56,6 +56,57 @@ int ath6kl_printk(const char *level, const char *fmt, ...) } EXPORT_SYMBOL(ath6kl_printk); +int ath6kl_info(const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + int ret; + + va_start(args, fmt); + vaf.va = &args; + ret = ath6kl_printk(KERN_INFO, "%pV", &vaf); + va_end(args); + + return ret; +} +EXPORT_SYMBOL(ath6kl_info); + +int ath6kl_err(const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + int ret; + + va_start(args, fmt); + vaf.va = &args; + ret = ath6kl_printk(KERN_ERR, "%pV", &vaf); + va_end(args); + + return ret; +} +EXPORT_SYMBOL(ath6kl_err); + +int ath6kl_warn(const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + int ret; + + va_start(args, fmt); + vaf.va = &args; + ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf); + va_end(args); + + return ret; +} +EXPORT_SYMBOL(ath6kl_warn); + #ifdef CONFIG_ATH6KL_DEBUG void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index f97cd4ead543..c6ca781900da 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -51,13 +51,9 @@ enum ATH6K_DEBUG_MASK { extern unsigned int debug_mask; extern __printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); - -#define ath6kl_info(fmt, ...) \ - ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__) -#define ath6kl_err(fmt, ...) \ - ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__) -#define ath6kl_warn(fmt, ...) \ - ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__) +extern __printf(1, 2) int ath6kl_info(const char *fmt, ...); +extern __printf(1, 2) int ath6kl_err(const char *fmt, ...); +extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...); enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, -- cgit From da01d53cfb8a7e23121572004336723d64d3ace6 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:22 +0200 Subject: ath6kl: add tracing support to log functions All log messages are now sent through tracing interface as well if ATH6KL_TRACING is enabled. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 3 +++ drivers/net/wireless/ath/ath6kl/debug.h | 1 + drivers/net/wireless/ath/ath6kl/trace.h | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 2e248fac8523..80f23e398acd 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -67,6 +67,7 @@ int ath6kl_info(const char *fmt, ...) va_start(args, fmt); vaf.va = &args; ret = ath6kl_printk(KERN_INFO, "%pV", &vaf); + trace_ath6kl_log_info(&vaf); va_end(args); return ret; @@ -84,6 +85,7 @@ int ath6kl_err(const char *fmt, ...) va_start(args, fmt); vaf.va = &args; ret = ath6kl_printk(KERN_ERR, "%pV", &vaf); + trace_ath6kl_log_err(&vaf); va_end(args); return ret; @@ -101,6 +103,7 @@ int ath6kl_warn(const char *fmt, ...) va_start(args, fmt); vaf.va = &args; ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf); + trace_ath6kl_log_warn(&vaf); va_end(args); return ret; diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index c6ca781900da..74369de00fb5 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -19,6 +19,7 @@ #define DEBUG_H #include "hif.h" +#include "trace.h" enum ATH6K_DEBUG_MASK { ATH6KL_DBG_CREDIT = BIT(0), diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index 306d58d89cc8..ea55b2abbdb3 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -25,6 +25,11 @@ static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len) #undef TRACE_EVENT #define TRACE_EVENT(name, proto, ...) \ static inline void trace_ ## name(proto) {} +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(...) +#undef DEFINE_EVENT +#define DEFINE_EVENT(evt_class, name, proto, ...) \ +static inline void trace_ ## name(proto) {} #endif /* !CONFIG_ATH6KL_TRACING || __CHECKER__ */ #undef TRACE_SYSTEM @@ -241,6 +246,38 @@ TRACE_EVENT(ath6kl_htc_tx, ) ); +#define ATH6KL_MSG_MAX 200 + +DECLARE_EVENT_CLASS(ath6kl_log_event, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf), + TP_STRUCT__entry( + __dynamic_array(char, msg, ATH6KL_MSG_MAX) + ), + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + ATH6KL_MSG_MAX, + vaf->fmt, + *vaf->va) >= ATH6KL_MSG_MAX); + ), + TP_printk("%s", __get_str(msg)) +); + +DEFINE_EVENT(ath6kl_log_event, ath6kl_log_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(ath6kl_log_event, ath6kl_log_warn, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(ath6kl_log_event, ath6kl_log_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + #endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- cgit From aa8705fc65a395d79bdc8bb82a89bcf9abe9f3a4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 18 Mar 2013 13:42:22 +0200 Subject: ath6kl: add tracing support to debug message macros Now all log messages are sent through the tracing infrastruture as well. Tracing point doesn't follow debug_mask module parameter, instead it sends all debug messages, so once you enable ath6kl_log_dbg tracing point you will get a lot of messages. Needs to be discussed if this is sensible or not. The overhead should be small enough and we anyway include debug level as well so it's easy to filter in user space. I wasn't really sure what to do with ath6kl_dbg_dump() and for now decided that it also sends the buffer to user space. But most likely in the future ath6kl_dbg_dump() should go away in favor of using proper tracing points, but we will see. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 12 ++++++---- drivers/net/wireless/ath/ath6kl/trace.h | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 80f23e398acd..42a887d06ba2 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -117,15 +117,15 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) struct va_format vaf; va_list args; - if (!(debug_mask & mask)) - return; - va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - ath6kl_printk(KERN_DEBUG, "%pV", &vaf); + if (debug_mask & mask) + ath6kl_printk(KERN_DEBUG, "%pV", &vaf); + + trace_ath6kl_log_dbg(mask, &vaf); va_end(args); } @@ -141,6 +141,10 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); } + + /* tracing code doesn't like null strings :/ */ + trace_ath6kl_log_dbg_dump(msg ? msg : "", prefix ? prefix : "", + buf, len); } EXPORT_SYMBOL(ath6kl_dbg_dump); diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index ea55b2abbdb3..6af6fa038312 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -278,6 +278,48 @@ DEFINE_EVENT(ath6kl_log_event, ath6kl_log_info, TP_ARGS(vaf) ); +TRACE_EVENT(ath6kl_log_dbg, + TP_PROTO(unsigned int level, struct va_format *vaf), + TP_ARGS(level, vaf), + TP_STRUCT__entry( + __field(unsigned int, level) + __dynamic_array(char, msg, ATH6KL_MSG_MAX) + ), + TP_fast_assign( + __entry->level = level; + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + ATH6KL_MSG_MAX, + vaf->fmt, + *vaf->va) >= ATH6KL_MSG_MAX); + ), + TP_printk("%s", __get_str(msg)) +); + +TRACE_EVENT(ath6kl_log_dbg_dump, + TP_PROTO(const char *msg, const char *prefix, + const void *buf, size_t buf_len), + + TP_ARGS(msg, prefix, buf, buf_len), + + TP_STRUCT__entry( + __string(msg, msg) + __string(prefix, prefix) + __field(size_t, buf_len) + __dynamic_array(u8, buf, buf_len) + ), + + TP_fast_assign( + __assign_str(msg, msg); + __assign_str(prefix, prefix); + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(buf), buf, buf_len); + ), + + TP_printk( + "%s/%s\n", __get_str(prefix), __get_str(msg) + ) +); + #endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- cgit From 99089ab756a26c8f1be5942178bf9b3fa9ae54d6 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 10 Mar 2013 07:51:29 +0200 Subject: ath6kl: add an extra band check to ath6kl_wmi_beginscan_cmd() Dan reported that smatch found a possible issue in ath6kl_wmi_beginscan_cmd() where we might access sc->supp_rates beyond the end. It shouldn't happen as ar->wiphy->bands always have just the first two bands set, but add an extra check just to be sure. Reported-by: Dan Carpenter Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/wmi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 31a308103f4c..87aefb4c4c23 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2029,6 +2029,9 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, if (!sband) continue; + if (WARN_ON(band >= ATH6KL_NUM_BANDS)) + break; + ratemask = rates[band]; supp_rates = sc->supp_rates[band].rates; num_rates = 0; -- cgit From 15ac0778a65322c8c39eb2a6636218554d348690 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 10 Mar 2013 07:51:39 +0200 Subject: ath6kl: remove false check from ath6kl_rx() Dan found a check from ath6kl_rx() which doesn't make any sense at all: " 1327 if (status || !(skb->data + HTC_HDR_LENGTH)) { ^^^^^^^^^^^^^^^^^^^^^^^^^^ skb->data is a pointer. This pointer math is always going to be false. Should it be testing "packet->act_len < HTC_HDR_LENGTH" or something?" I don't know what the check really was supposed to do, but I think Dan's guess is right. Fix it accordingly. Reported-by: Dan Carpenter Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 43dbdaadf577..ebb24045a8ae 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1327,7 +1327,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) __func__, ar, ept, skb, packet->buf, packet->act_len, status); - if (status || !(skb->data + HTC_HDR_LENGTH)) { + if (status || packet->act_len < HTC_HDR_LENGTH) { dev_kfree_skb(skb); return; } -- cgit From 6a3e4e06a1a2238d5a2668d4a5bad58fc92c7a77 Mon Sep 17 00:00:00 2001 From: Myoungje Kim Date: Sun, 10 Mar 2013 08:16:05 +0200 Subject: ath6kl: Fix the byte alignment rule to avoid loss of bytes in a TCP segment Either first 3 bytes of the first received tcp segment or last one over MTU size file can be loss due to the byte alignment problem. Although ATH6KL_HTC_ALIGN_BYTES was defined for 'extra bytes for htc header alignment' in the patch "Fix buffer alignment for scatter-gather I/O"(1df94a857), there exists the bytes loss issue which means that it will be truncated 3 bytes in the transmitted file contents if a file which has over MTU size is transferred through TCP/IP stack. It doesn't look like TCP/IP stack bug of 3.5 or the latest version of kernel but the byte alignment issue. This patch is to use the roundup() function for the byte alignment rather than the predefined ATH6KL_HTC_ALIGN_BYTES. kvalo: fixed indentation Signed-off-by: Myoungje Kim Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 4 ++-- drivers/net/wireless/ath/ath6kl/main.c | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 4ad45bb3cf55..40ffee6184fd 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -201,8 +201,8 @@ struct sk_buff *ath6kl_buf_alloc(int size) u16 reserved; /* Add chacheline space at front and back of buffer */ - reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET + - sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES; + reserved = roundup((2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET + + sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES, 4); skb = dev_alloc_skb(size + reserved); if (skb) diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index bad62b3357b9..d4fcfcad57d0 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1294,9 +1294,11 @@ void init_netdev(struct net_device *dev) dev->watchdog_timeo = ATH6KL_TX_TIMEOUT; dev->needed_headroom = ETH_HLEN; - dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) + - sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH - + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; + dev->needed_headroom += roundup(sizeof(struct ath6kl_llc_snap_hdr) + + sizeof(struct wmi_data_hdr) + + HTC_HDR_LENGTH + + WMI_MAX_TX_META_SZ + + ATH6KL_HTC_ALIGN_BYTES, 4); dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; -- cgit From a41d9a91e35f0ca7a55ecf3b6de5901e24d9e7ae Mon Sep 17 00:00:00 2001 From: Andrei Epure Date: Sun, 10 Mar 2013 14:39:58 +0200 Subject: ath: changed kmalloc to kmemdup Signed-off-by: Andrei Epure Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 63948f6c9f17..bed0d337712d 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -856,11 +856,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, int ret; if (size > 0) { - buf = kmalloc(size, GFP_KERNEL); + buf = kmemdup(data, size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - - memcpy(buf, data, size); } /* note: if successful returns number of bytes transfered */ -- cgit From 243c028099c467186d126859848bdac3bbfe8da0 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 12 Mar 2013 22:03:03 +0530 Subject: ath6kl: Fix a debugfs crash for USB devices Credit distribution stats is currently implemented only for SDIO. This fixes a crash in debugfs for USB interface. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] read_file_credit_dist_stats+0x38/0x330 [ath6kl_core] *pde = b62bd067 Oops: 0000 [#1] SMP EIP: 0060:[] EFLAGS: 00210246 CPU: 0 EIP is at read_file_credit_dist_stats+0x38/0x330 [ath6kl_core] EAX: 00000000 EBX: e6f7a9c0 ECX: e7b148b8 EDX: 00000000 ESI: 000000c8 EDI: e7b14000 EBP: e6e09f64 ESP: e6e09f30 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process cat (pid: 4058, ti=e6e08000 task=e50cf230 task.ti=e6e08000) Stack: 00008000 00000000 e6e09f64 c1132d3c 00004e71 e50cf230 00008000 089e4000 e7b148b8 00000000 e6f7a9c0 00008000 089e4000 e6e09f8c c11331fc e6e09f98 00000001 e6e09f7c f91c2010 e6e09fac e6f7a9c0 089e4877 089e4000 e6e09fac Call Trace: [] ? rw_verify_area+0x6c/0x120 [] vfs_read+0x8c/0x160 [] ? read_file_war_stats+0x130/0x130 [ath6kl_core] [] sys_read+0x3d/0x70 [] syscall_call+0x7/0xb [] ? fill_powernow_table_pstate+0x127/0x127 Cc: Ryan Hsu Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 42a887d06ba2..fe38b836cb26 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1810,8 +1810,10 @@ int ath6kl_debug_init_fs(struct ath6kl *ar) debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_tgt_stats); - debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, - &fops_credit_dist_stats); + if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO) + debugfs_create_file("credit_dist_stats", S_IRUSR, + ar->debugfs_phy, ar, + &fops_credit_dist_stats); debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, &fops_endpoint_stats); -- cgit From 443580486e3b96578928c1c91e8fbdcf0c9c9c7f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 18 Feb 2013 23:28:34 +0900 Subject: irqchip: Renesas INTC External IRQ pin driver This patch adds a driver for external IRQ pins connected to the INTC block on recent SoCs from Renesas. The INTC hardware block usually contains a rather wide range of features ranging from external IRQ pin handling to legacy interrupt controller support. On older SoCs the INTC is used as a general purpose interrupt controller both for external IRQ pins and on-chip devices. On more recent ARM based SoCs with Cortex-A9 the main interrupt controller is the GIC, but IRQ trigger setup still need to happen in the INTC hardware block. This driver implements the glue code needed to configure IRQ trigger and also handle mask/unmask and demux of external IRQ pins hooked up from the INTC to the GIC. Tested on sh73a0 and r8a7779. The hardware varies quite a bit with SoC model, for instance register width and bitfield widths vary wildly. The driver requires one GIC SPI per external IRQ pin to operate. Each driver instance will handle up to 8 external IRQ pins. The SoCs using this driver are currently mainly used together with regular platform devices so this driver allows configuration via platform data to support things like static interrupt base address. DT support will be added incrementally in the not so distant future. Signed-off-by: Magnus Damm Acked-by: Thomas Gleixner Signed-off-by: Simon Horman --- drivers/irqchip/Kconfig | 4 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-renesas-intc-irqpin.c | 464 +++++++++++++++++++++ .../linux/platform_data/irq-renesas-intc-irqpin.h | 10 + 4 files changed, 479 insertions(+) create mode 100644 drivers/irqchip/irq-renesas-intc-irqpin.c create mode 100644 include/linux/platform_data/irq-renesas-intc-irqpin.h (limited to 'drivers') diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index a350969e5efe..0f5f1c3825bc 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -25,6 +25,10 @@ config ARM_VIC_NR The maximum number of VICs available in the system, for power management. +config RENESAS_INTC_IRQPIN + bool + select IRQ_DOMAIN + config VERSATILE_FPGA_IRQ bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 98e3b87bdf1b..1aaa4073ab60 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o +obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c new file mode 100644 index 000000000000..1e5058a56517 --- /dev/null +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -0,0 +1,464 @@ +/* + * Renesas INTC External IRQ Pin Driver + * + * Copyright (C) 2013 Magnus Damm + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */ + +#define INTC_IRQPIN_REG_SENSE 0 /* ICRn */ +#define INTC_IRQPIN_REG_PRIO 1 /* INTPRInn */ +#define INTC_IRQPIN_REG_SOURCE 2 /* INTREQnn */ +#define INTC_IRQPIN_REG_MASK 3 /* INTMSKnn */ +#define INTC_IRQPIN_REG_CLEAR 4 /* INTMSKCLRnn */ +#define INTC_IRQPIN_REG_NR 5 + +/* INTC external IRQ PIN hardware register access: + * + * SENSE is read-write 32-bit with 2-bits or 4-bits per IRQ (*) + * PRIO is read-write 32-bit with 4-bits per IRQ (**) + * SOURCE is read-only 32-bit or 8-bit with 1-bit per IRQ (***) + * MASK is write-only 32-bit or 8-bit with 1-bit per IRQ (***) + * CLEAR is write-only 32-bit or 8-bit with 1-bit per IRQ (***) + * + * (*) May be accessed by more than one driver instance - lock needed + * (**) Read-modify-write access by one driver instance - lock needed + * (***) Accessed by one driver instance only - no locking needed + */ + +struct intc_irqpin_iomem { + void __iomem *iomem; + unsigned long (*read)(void __iomem *iomem); + void (*write)(void __iomem *iomem, unsigned long data); + int width; +}; + +struct intc_irqpin_irq { + int hw_irq; + int irq; + struct intc_irqpin_priv *p; +}; + +struct intc_irqpin_priv { + struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; + struct intc_irqpin_irq irq[INTC_IRQPIN_MAX]; + struct renesas_intc_irqpin_config config; + unsigned int number_of_irqs; + struct platform_device *pdev; + struct irq_chip irq_chip; + struct irq_domain *irq_domain; +}; + +static unsigned long intc_irqpin_read32(void __iomem *iomem) +{ + return ioread32(iomem); +} + +static unsigned long intc_irqpin_read8(void __iomem *iomem) +{ + return ioread8(iomem); +} + +static void intc_irqpin_write32(void __iomem *iomem, unsigned long data) +{ + iowrite32(data, iomem); +} + +static void intc_irqpin_write8(void __iomem *iomem, unsigned long data) +{ + iowrite8(data, iomem); +} + +static inline unsigned long intc_irqpin_read(struct intc_irqpin_priv *p, + int reg) +{ + struct intc_irqpin_iomem *i = &p->iomem[reg]; + return i->read(i->iomem); +} + +static inline void intc_irqpin_write(struct intc_irqpin_priv *p, + int reg, unsigned long data) +{ + struct intc_irqpin_iomem *i = &p->iomem[reg]; + i->write(i->iomem, data); +} + +static inline unsigned long intc_irqpin_hwirq_mask(struct intc_irqpin_priv *p, + int reg, int hw_irq) +{ + return BIT((p->iomem[reg].width - 1) - hw_irq); +} + +static inline void intc_irqpin_irq_write_hwirq(struct intc_irqpin_priv *p, + int reg, int hw_irq) +{ + intc_irqpin_write(p, reg, intc_irqpin_hwirq_mask(p, reg, hw_irq)); +} + +static DEFINE_RAW_SPINLOCK(intc_irqpin_lock); /* only used by slow path */ + +static void intc_irqpin_read_modify_write(struct intc_irqpin_priv *p, + int reg, int shift, + int width, int value) +{ + unsigned long flags; + unsigned long tmp; + + raw_spin_lock_irqsave(&intc_irqpin_lock, flags); + + tmp = intc_irqpin_read(p, reg); + tmp &= ~(((1 << width) - 1) << shift); + tmp |= value << shift; + intc_irqpin_write(p, reg, tmp); + + raw_spin_unlock_irqrestore(&intc_irqpin_lock, flags); +} + +static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p, + int irq, int do_mask) +{ + int bitfield_width = 4; /* PRIO assumed to have fixed bitfield width */ + int shift = (7 - irq) * bitfield_width; /* PRIO assumed to be 32-bit */ + + intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_PRIO, + shift, bitfield_width, + do_mask ? 0 : (1 << bitfield_width) - 1); +} + +static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value) +{ + int bitfield_width = p->config.sense_bitfield_width; + int shift = (7 - irq) * bitfield_width; /* SENSE assumed to be 32-bit */ + + dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value); + + if (value >= (1 << bitfield_width)) + return -EINVAL; + + intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_SENSE, shift, + bitfield_width, value); + return 0; +} + +static void intc_irqpin_dbg(struct intc_irqpin_irq *i, char *str) +{ + dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", + str, i->irq, i->hw_irq, + irq_find_mapping(i->p->irq_domain, i->hw_irq)); +} + +static void intc_irqpin_irq_enable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "enable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_CLEAR, hw_irq); +} + +static void intc_irqpin_irq_disable(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + intc_irqpin_dbg(&p->irq[hw_irq], "disable"); + intc_irqpin_irq_write_hwirq(p, INTC_IRQPIN_REG_MASK, hw_irq); +} + +static void intc_irqpin_irq_enable_force(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int irq = p->irq[irqd_to_hwirq(d)].irq; + + intc_irqpin_irq_enable(d); + irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq)); +} + +static void intc_irqpin_irq_disable_force(struct irq_data *d) +{ + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + int irq = p->irq[irqd_to_hwirq(d)].irq; + + irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq)); + intc_irqpin_irq_disable(d); +} + +#define INTC_IRQ_SENSE_VALID 0x10 +#define INTC_IRQ_SENSE(x) (x + INTC_IRQ_SENSE_VALID) + +static unsigned char intc_irqpin_sense[IRQ_TYPE_SENSE_MASK + 1] = { + [IRQ_TYPE_EDGE_FALLING] = INTC_IRQ_SENSE(0x00), + [IRQ_TYPE_EDGE_RISING] = INTC_IRQ_SENSE(0x01), + [IRQ_TYPE_LEVEL_LOW] = INTC_IRQ_SENSE(0x02), + [IRQ_TYPE_LEVEL_HIGH] = INTC_IRQ_SENSE(0x03), + [IRQ_TYPE_EDGE_BOTH] = INTC_IRQ_SENSE(0x04), +}; + +static int intc_irqpin_irq_set_type(struct irq_data *d, unsigned int type) +{ + unsigned char value = intc_irqpin_sense[type & IRQ_TYPE_SENSE_MASK]; + struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); + + if (!(value & INTC_IRQ_SENSE_VALID)) + return -EINVAL; + + return intc_irqpin_set_sense(p, irqd_to_hwirq(d), + value ^ INTC_IRQ_SENSE_VALID); +} + +static irqreturn_t intc_irqpin_irq_handler(int irq, void *dev_id) +{ + struct intc_irqpin_irq *i = dev_id; + struct intc_irqpin_priv *p = i->p; + unsigned long bit; + + intc_irqpin_dbg(i, "demux1"); + bit = intc_irqpin_hwirq_mask(p, INTC_IRQPIN_REG_SOURCE, i->hw_irq); + + if (intc_irqpin_read(p, INTC_IRQPIN_REG_SOURCE) & bit) { + intc_irqpin_write(p, INTC_IRQPIN_REG_SOURCE, ~bit); + intc_irqpin_dbg(i, "demux2"); + generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq)); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct intc_irqpin_priv *p = h->host_data; + + intc_irqpin_dbg(&p->irq[hw], "map"); + irq_set_chip_data(virq, h->host_data); + irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); /* kill me now */ + return 0; +} + +static struct irq_domain_ops intc_irqpin_irq_domain_ops = { + .map = intc_irqpin_irq_domain_map, +}; + +static int intc_irqpin_probe(struct platform_device *pdev) +{ + struct renesas_intc_irqpin_config *pdata = pdev->dev.platform_data; + struct intc_irqpin_priv *p; + struct intc_irqpin_iomem *i; + struct resource *io[INTC_IRQPIN_REG_NR]; + struct resource *irq; + struct irq_chip *irq_chip; + void (*enable_fn)(struct irq_data *d); + void (*disable_fn)(struct irq_data *d); + const char *name = dev_name(&pdev->dev); + int ret; + int k; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + ret = -ENOMEM; + goto err0; + } + + /* deal with driver instance configuration */ + if (pdata) + memcpy(&p->config, pdata, sizeof(*pdata)); + if (!p->config.sense_bitfield_width) + p->config.sense_bitfield_width = 4; /* default to 4 bits */ + + p->pdev = pdev; + platform_set_drvdata(pdev, p); + + /* get hold of manadatory IOMEM */ + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { + io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k); + if (!io[k]) { + dev_err(&pdev->dev, "not enough IOMEM resources\n"); + ret = -EINVAL; + goto err1; + } + } + + /* allow any number of IRQs between 1 and INTC_IRQPIN_MAX */ + for (k = 0; k < INTC_IRQPIN_MAX; k++) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, k); + if (!irq) + break; + + p->irq[k].hw_irq = k; + p->irq[k].p = p; + p->irq[k].irq = irq->start; + } + + p->number_of_irqs = k; + if (p->number_of_irqs < 1) { + dev_err(&pdev->dev, "not enough IRQ resources\n"); + ret = -EINVAL; + goto err1; + } + + /* ioremap IOMEM and setup read/write callbacks */ + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) { + i = &p->iomem[k]; + + switch (resource_size(io[k])) { + case 1: + i->width = 8; + i->read = intc_irqpin_read8; + i->write = intc_irqpin_write8; + break; + case 4: + i->width = 32; + i->read = intc_irqpin_read32; + i->write = intc_irqpin_write32; + break; + default: + dev_err(&pdev->dev, "IOMEM size mismatch\n"); + ret = -EINVAL; + goto err2; + } + + i->iomem = ioremap_nocache(io[k]->start, resource_size(io[k])); + if (!i->iomem) { + dev_err(&pdev->dev, "failed to remap IOMEM\n"); + ret = -ENXIO; + goto err2; + } + } + + /* mask all interrupts using priority */ + for (k = 0; k < p->number_of_irqs; k++) + intc_irqpin_mask_unmask_prio(p, k, 1); + + /* use more severe masking method if requested */ + if (p->config.control_parent) { + enable_fn = intc_irqpin_irq_enable_force; + disable_fn = intc_irqpin_irq_disable_force; + } else { + enable_fn = intc_irqpin_irq_enable; + disable_fn = intc_irqpin_irq_disable; + } + + irq_chip = &p->irq_chip; + irq_chip->name = name; + irq_chip->irq_mask = disable_fn; + irq_chip->irq_unmask = enable_fn; + irq_chip->irq_enable = enable_fn; + irq_chip->irq_disable = disable_fn; + irq_chip->irq_set_type = intc_irqpin_irq_set_type; + irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; + + p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, + p->number_of_irqs, + p->config.irq_base, + &intc_irqpin_irq_domain_ops, p); + if (!p->irq_domain) { + ret = -ENXIO; + dev_err(&pdev->dev, "cannot initialize irq domain\n"); + goto err2; + } + + /* request and set priority on interrupts one by one */ + for (k = 0; k < p->number_of_irqs; k++) { + if (request_irq(p->irq[k].irq, intc_irqpin_irq_handler, + 0, name, &p->irq[k])) { + dev_err(&pdev->dev, "failed to request low IRQ\n"); + ret = -ENOENT; + goto err3; + } + intc_irqpin_mask_unmask_prio(p, k, 0); + } + + dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); + + /* warn in case of mismatch if irq base is specified */ + if (p->config.irq_base) { + k = irq_find_mapping(p->irq_domain, 0); + if (p->config.irq_base != k) + dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", + p->config.irq_base, k); + } + + return 0; + +err3: + for (; k >= 0; k--) + free_irq(p->irq[k - 1].irq, &p->irq[k - 1]); + + irq_domain_remove(p->irq_domain); +err2: + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) + iounmap(p->iomem[k].iomem); +err1: + kfree(p); +err0: + return ret; +} + +static int intc_irqpin_remove(struct platform_device *pdev) +{ + struct intc_irqpin_priv *p = platform_get_drvdata(pdev); + int k; + + for (k = 0; k < p->number_of_irqs; k++) + free_irq(p->irq[k].irq, &p->irq[k]); + + irq_domain_remove(p->irq_domain); + + for (k = 0; k < INTC_IRQPIN_REG_NR; k++) + iounmap(p->iomem[k].iomem); + + kfree(p); + return 0; +} + +static struct platform_driver intc_irqpin_device_driver = { + .probe = intc_irqpin_probe, + .remove = intc_irqpin_remove, + .driver = { + .name = "renesas_intc_irqpin", + } +}; + +static int __init intc_irqpin_init(void) +{ + return platform_driver_register(&intc_irqpin_device_driver); +} +postcore_initcall(intc_irqpin_init); + +static void __exit intc_irqpin_exit(void) +{ + platform_driver_unregister(&intc_irqpin_device_driver); +} +module_exit(intc_irqpin_exit); + +MODULE_AUTHOR("Magnus Damm"); +MODULE_DESCRIPTION("Renesas INTC External IRQ Pin Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/irq-renesas-intc-irqpin.h b/include/linux/platform_data/irq-renesas-intc-irqpin.h new file mode 100644 index 000000000000..00ccac34dac8 --- /dev/null +++ b/include/linux/platform_data/irq-renesas-intc-irqpin.h @@ -0,0 +1,10 @@ +#ifndef __IRQ_RENESAS_INTC_IRQPIN_H__ +#define __IRQ_RENESAS_INTC_IRQPIN_H__ + +struct renesas_intc_irqpin_config { + unsigned int sense_bitfield_width; + unsigned int irq_base; + bool control_parent; +}; + +#endif /* __IRQ_RENESAS_INTC_IRQPIN_H__ */ -- cgit From 341eb5465f67437ad37ef2f6302b581beda4614a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 12:01:09 +0900 Subject: ARM: shmobile: INTC External IRQ pin driver on sh73a0 Adjust the sh73a0 IRQ code to make use of the INTC External IRQ pin driver for external interrupt pins IRQ0 -> IRQ31. This removes quite a bit of special-case code in intc-sh73a0.c but the number of lines get replaced with platform device information in setup-sh73a0.c. The PFC code is also adjusted to make gpio_to_irq() return the correct interrupt number. At this point the DT reference implementations are not covered. In the future such code shall tie in the INTC External IRQ pin driver via DT, so this kind of verbose code is not needed for the long term DT case. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Kconfig | 1 + arch/arm/mach-shmobile/board-kzm9g.c | 14 ++-- arch/arm/mach-shmobile/intc-sh73a0.c | 117 ------------------------------- arch/arm/mach-shmobile/setup-sh73a0.c | 126 ++++++++++++++++++++++++++++++++++ drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 6 +- 5 files changed, 137 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 9255546e7bf6..f964accbce24 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -16,6 +16,7 @@ config ARCH_SH73A0 select CPU_V7 select I2C select SH_CLK_CPG + select RENESAS_INTC_IRQPIN config ARCH_R8A7740 bool "R-Mobile A1 (R8A77400)" diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7f3a6b7e7b7c..d34d12ae496b 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -81,7 +81,7 @@ static struct resource smsc9221_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = intcs_evt2irq(0x260), /* IRQ3 */ + .start = irq_pin(3), /* IRQ3 */ .flags = IORESOURCE_IRQ, }, }; @@ -115,7 +115,7 @@ static struct resource usb_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = intcs_evt2irq(0x220), /* IRQ1 */ + .start = irq_pin(1), /* IRQ1 */ .flags = IORESOURCE_IRQ, }, }; @@ -138,7 +138,7 @@ struct usbhs_private { struct renesas_usbhs_platform_info info; }; -#define IRQ15 intcs_evt2irq(0x03e0) +#define IRQ15 irq_pin(15) #define USB_PHY_MODE (1 << 4) #define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) #define USB_PHY_ON (1 << 1) @@ -563,25 +563,25 @@ static struct i2c_board_info i2c0_devices[] = { }, { I2C_BOARD_INFO("ak8975", 0x0c), - .irq = intcs_evt2irq(0x3380), /* IRQ28 */ + .irq = irq_pin(28), /* IRQ28 */ }, { I2C_BOARD_INFO("adxl34x", 0x1d), - .irq = intcs_evt2irq(0x3340), /* IRQ26 */ + .irq = irq_pin(26), /* IRQ26 */ }, }; static struct i2c_board_info i2c1_devices[] = { { I2C_BOARD_INFO("st1232-ts", 0x55), - .irq = intcs_evt2irq(0x300), /* IRQ8 */ + .irq = irq_pin(8), /* IRQ8 */ }, }; static struct i2c_board_info i2c3_devices[] = { { I2C_BOARD_INFO("pcf8575", 0x20), - .irq = intcs_evt2irq(0x3260), /* IRQ19 */ + .irq = irq_pin(19), /* IRQ19 */ .platform_data = &pcf8575_pdata, }, }; diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index a81a1d804e2e..19a26f4579b3 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -260,108 +260,6 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on) return 0; /* always allow wakeup */ } -#define RELOC_BASE 0x1200 - -/* INTCA IRQ pins at INTCS + RELOC_BASE to make space for GIC+INTC handling */ -#define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE) - -INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000, - INTCS_VECT_RELOC, "sh73a0-intca-irq-pins"); - -static int to_gic_irq(struct irq_data *data) -{ - unsigned int vect = irq2evt(data->irq) - INTCS_VECT_BASE; - - if (vect >= 0x3200) - vect -= 0x3000; - else - vect -= 0x0200; - - return gic_spi((vect >> 5) + 1); -} - -static int to_intca_reloc_irq(struct irq_data *data) -{ - return data->irq + (RELOC_BASE >> 5); -} - -#define irq_cb(cb, irq) irq_get_chip(irq)->cb(irq_get_irq_data(irq)) -#define irq_cbp(cb, irq, p...) irq_get_chip(irq)->cb(irq_get_irq_data(irq), p) - -static void intca_gic_enable(struct irq_data *data) -{ - irq_cb(irq_unmask, to_intca_reloc_irq(data)); - irq_cb(irq_unmask, to_gic_irq(data)); -} - -static void intca_gic_disable(struct irq_data *data) -{ - irq_cb(irq_mask, to_gic_irq(data)); - irq_cb(irq_mask, to_intca_reloc_irq(data)); -} - -static void intca_gic_mask_ack(struct irq_data *data) -{ - irq_cb(irq_mask, to_gic_irq(data)); - irq_cb(irq_mask_ack, to_intca_reloc_irq(data)); -} - -static void intca_gic_eoi(struct irq_data *data) -{ - irq_cb(irq_eoi, to_gic_irq(data)); -} - -static int intca_gic_set_type(struct irq_data *data, unsigned int type) -{ - return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type); -} - -#ifdef CONFIG_SMP -static int intca_gic_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, - bool force) -{ - return irq_cbp(irq_set_affinity, to_gic_irq(data), cpumask, force); -} -#endif - -struct irq_chip intca_gic_irq_chip = { - .name = "INTCA-GIC", - .irq_mask = intca_gic_disable, - .irq_unmask = intca_gic_enable, - .irq_mask_ack = intca_gic_mask_ack, - .irq_eoi = intca_gic_eoi, - .irq_enable = intca_gic_enable, - .irq_disable = intca_gic_disable, - .irq_shutdown = intca_gic_disable, - .irq_set_type = intca_gic_set_type, - .irq_set_wake = sh73a0_set_wake, -#ifdef CONFIG_SMP - .irq_set_affinity = intca_gic_set_affinity, -#endif -}; - -static int to_intc_vect(int irq) -{ - unsigned int irq_pin = irq - gic_spi(1); - unsigned int offs; - - if (irq_pin < 16) - offs = 0x0200; - else - offs = 0x3000; - - return offs + (irq_pin << 5); -} - -static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id) -{ - generic_handle_irq(intcs_evt2irq(to_intc_vect(irq))); - return IRQ_HANDLED; -} - -static struct irqaction sh73a0_irq_pin_cascade[32]; - #define PINTER0_PHYS 0xe69000a0 #define PINTER1_PHYS 0xe69000a4 #define PINTER0_VIRT IOMEM(0xe69000a0) @@ -422,13 +320,11 @@ void __init sh73a0_init_irq(void) void __iomem *gic_dist_base = IOMEM(0xf0001000); void __iomem *gic_cpu_base = IOMEM(0xf0000100); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); - int k, n; gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_arch_extn.irq_set_wake = sh73a0_set_wake; register_intc_controller(&intcs_desc); - register_intc_controller(&intca_irq_pins_desc); register_intc_controller(&intc_pint0_desc); register_intc_controller(&intc_pint1_desc); @@ -438,19 +334,6 @@ void __init sh73a0_init_irq(void) sh73a0_intcs_cascade.dev_id = intevtsa; setup_irq(gic_spi(50), &sh73a0_intcs_cascade); - /* IRQ pins require special handling through INTCA and GIC */ - for (k = 0; k < 32; k++) { - sh73a0_irq_pin_cascade[k].name = "INTCA-GIC cascade"; - sh73a0_irq_pin_cascade[k].handler = sh73a0_irq_pin_demux; - setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]); - - n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k))); - WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n); - irq_set_chip_and_handler_name(n, &intca_gic_irq_chip, - handle_level_irq, "level"); - set_irq_flags(n, IRQF_VALID); /* yuck */ - } - /* PINT pins are sanely tied to the GIC as SPI */ sh73a0_pint0_cascade.name = "PINT0 cascade"; sh73a0_pint0_cascade.handler = sh73a0_pint0_demux; diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 2257a915746d..638735f78e36 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -811,6 +812,127 @@ static struct platform_device ipmmu_device = { .num_resources = ARRAY_SIZE(ipmmu_resources), }; +struct renesas_intc_irqpin_config irqpin0_platform_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */ +}; + +static struct resource irqpin0_resources[] = { + DEFINE_RES_MEM(0xe6900000, 4), /* ICR1A */ + DEFINE_RES_MEM(0xe6900010, 4), /* INTPRI00A */ + DEFINE_RES_MEM(0xe6900020, 1), /* INTREQ00A */ + DEFINE_RES_MEM(0xe6900040, 1), /* INTMSK00A */ + DEFINE_RES_MEM(0xe6900060, 1), /* INTMSKCLR00A */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(4)), /* IRQ3 */ + DEFINE_RES_IRQ(gic_spi(5)), /* IRQ4 */ + DEFINE_RES_IRQ(gic_spi(6)), /* IRQ5 */ + DEFINE_RES_IRQ(gic_spi(7)), /* IRQ6 */ + DEFINE_RES_IRQ(gic_spi(8)), /* IRQ7 */ +}; + +static struct platform_device irqpin0_device = { + .name = "renesas_intc_irqpin", + .id = 0, + .resource = irqpin0_resources, + .num_resources = ARRAY_SIZE(irqpin0_resources), + .dev = { + .platform_data = &irqpin0_platform_data, + }, +}; + +struct renesas_intc_irqpin_config irqpin1_platform_data = { + .irq_base = irq_pin(8), /* IRQ8 -> IRQ15 */ + .control_parent = true, /* Disable spurious IRQ10 */ +}; + +static struct resource irqpin1_resources[] = { + DEFINE_RES_MEM(0xe6900004, 4), /* ICR2A */ + DEFINE_RES_MEM(0xe6900014, 4), /* INTPRI10A */ + DEFINE_RES_MEM(0xe6900024, 1), /* INTREQ10A */ + DEFINE_RES_MEM(0xe6900044, 1), /* INTMSK10A */ + DEFINE_RES_MEM(0xe6900064, 1), /* INTMSKCLR10A */ + DEFINE_RES_IRQ(gic_spi(9)), /* IRQ8 */ + DEFINE_RES_IRQ(gic_spi(10)), /* IRQ9 */ + DEFINE_RES_IRQ(gic_spi(11)), /* IRQ10 */ + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ11 */ + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ12 */ + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ13 */ + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ14 */ + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ15 */ +}; + +static struct platform_device irqpin1_device = { + .name = "renesas_intc_irqpin", + .id = 1, + .resource = irqpin1_resources, + .num_resources = ARRAY_SIZE(irqpin1_resources), + .dev = { + .platform_data = &irqpin1_platform_data, + }, +}; + +struct renesas_intc_irqpin_config irqpin2_platform_data = { + .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */ +}; + +static struct resource irqpin2_resources[] = { + DEFINE_RES_MEM(0xe6900008, 4), /* ICR3A */ + DEFINE_RES_MEM(0xe6900018, 4), /* INTPRI20A */ + DEFINE_RES_MEM(0xe6900028, 1), /* INTREQ20A */ + DEFINE_RES_MEM(0xe6900048, 1), /* INTMSK20A */ + DEFINE_RES_MEM(0xe6900068, 1), /* INTMSKCLR20A */ + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ16 */ + DEFINE_RES_IRQ(gic_spi(18)), /* IRQ17 */ + DEFINE_RES_IRQ(gic_spi(19)), /* IRQ18 */ + DEFINE_RES_IRQ(gic_spi(20)), /* IRQ19 */ + DEFINE_RES_IRQ(gic_spi(21)), /* IRQ20 */ + DEFINE_RES_IRQ(gic_spi(22)), /* IRQ21 */ + DEFINE_RES_IRQ(gic_spi(23)), /* IRQ22 */ + DEFINE_RES_IRQ(gic_spi(24)), /* IRQ23 */ +}; + +static struct platform_device irqpin2_device = { + .name = "renesas_intc_irqpin", + .id = 2, + .resource = irqpin2_resources, + .num_resources = ARRAY_SIZE(irqpin2_resources), + .dev = { + .platform_data = &irqpin2_platform_data, + }, +}; + +struct renesas_intc_irqpin_config irqpin3_platform_data = { + .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */ +}; + +static struct resource irqpin3_resources[] = { + DEFINE_RES_MEM(0xe690000c, 4), /* ICR4A */ + DEFINE_RES_MEM(0xe690001c, 4), /* INTPRI30A */ + DEFINE_RES_MEM(0xe690002c, 1), /* INTREQ30A */ + DEFINE_RES_MEM(0xe690004c, 1), /* INTMSK30A */ + DEFINE_RES_MEM(0xe690006c, 1), /* INTMSKCLR30A */ + DEFINE_RES_IRQ(gic_spi(25)), /* IRQ24 */ + DEFINE_RES_IRQ(gic_spi(26)), /* IRQ25 */ + DEFINE_RES_IRQ(gic_spi(27)), /* IRQ26 */ + DEFINE_RES_IRQ(gic_spi(28)), /* IRQ27 */ + DEFINE_RES_IRQ(gic_spi(29)), /* IRQ28 */ + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ29 */ + DEFINE_RES_IRQ(gic_spi(31)), /* IRQ30 */ + DEFINE_RES_IRQ(gic_spi(32)), /* IRQ31 */ +}; + +static struct platform_device irqpin3_device = { + .name = "renesas_intc_irqpin", + .id = 3, + .resource = irqpin3_resources, + .num_resources = ARRAY_SIZE(irqpin3_resources), + .dev = { + .platform_data = &irqpin3_platform_data, + }, +}; + static struct platform_device *sh73a0_devices_dt[] __initdata = { &scif0_device, &scif1_device, @@ -839,6 +961,10 @@ static struct platform_device *sh73a0_late_devices[] __initdata = { &dma0_device, &mpdma0_device, &pmu_device, + &irqpin0_device, + &irqpin1_device, + &irqpin2_device, + &irqpin3_device, }; #define SRCR2 IOMEM(0xe61580b0) diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 709008e94124..6f15c03077a0 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -2733,9 +2733,9 @@ static struct pinmux_data_reg pinmux_data_regs[] = { { }, }; -/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */ -#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5)) -#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) +/* External IRQ pins mapped at IRQPIN_BASE */ +#define EXT_IRQ16L(n) irq_pin(n) +#define EXT_IRQ16H(n) irq_pin(n) static struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0), -- cgit From 862d309883c69d67e1a2095e6f9e8ef35bf72dd6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 20:58:44 +0900 Subject: irqchip: intc-irqpin: Whitespace fixes Remove whitespace damage and add newline between variables and code. Signed-off-by: Magnus Damm Reviewed-by: Thomas Gleixner Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-intc-irqpin.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 1e5058a56517..4b5933fc0e3d 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -57,13 +57,13 @@ struct intc_irqpin_iomem { unsigned long (*read)(void __iomem *iomem); void (*write)(void __iomem *iomem, unsigned long data); int width; -}; +}; struct intc_irqpin_irq { int hw_irq; int irq; struct intc_irqpin_priv *p; -}; +}; struct intc_irqpin_priv { struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; @@ -99,6 +99,7 @@ static inline unsigned long intc_irqpin_read(struct intc_irqpin_priv *p, int reg) { struct intc_irqpin_iomem *i = &p->iomem[reg]; + return i->read(i->iomem); } @@ -106,6 +107,7 @@ static inline void intc_irqpin_write(struct intc_irqpin_priv *p, int reg, unsigned long data) { struct intc_irqpin_iomem *i = &p->iomem[reg]; + i->write(i->iomem, data); } @@ -405,7 +407,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", p->config.irq_base, k); } - + return 0; err3: -- cgit From 33f958f2a71c44164698d1cae5463c0b85296a2c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 20:58:54 +0900 Subject: irqchip: intc-irqpin: Cache mapped IRQ Cache IRQ in domain_irq variable instead of making use of irq_find_mapping(). While at it rename the irq variable to requested_irq. Signed-off-by: Magnus Damm Reviewed-by: Thomas Gleixner Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-intc-irqpin.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 4b5933fc0e3d..0ac2bf683378 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -61,7 +61,8 @@ struct intc_irqpin_iomem { struct intc_irqpin_irq { int hw_irq; - int irq; + int requested_irq; + int domain_irq; struct intc_irqpin_priv *p; }; @@ -171,8 +172,7 @@ static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value) static void intc_irqpin_dbg(struct intc_irqpin_irq *i, char *str) { dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", - str, i->irq, i->hw_irq, - irq_find_mapping(i->p->irq_domain, i->hw_irq)); + str, i->requested_irq, i->hw_irq, i->domain_irq); } static void intc_irqpin_irq_enable(struct irq_data *d) @@ -196,7 +196,7 @@ static void intc_irqpin_irq_disable(struct irq_data *d) static void intc_irqpin_irq_enable_force(struct irq_data *d) { struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); - int irq = p->irq[irqd_to_hwirq(d)].irq; + int irq = p->irq[irqd_to_hwirq(d)].requested_irq; intc_irqpin_irq_enable(d); irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq)); @@ -205,7 +205,7 @@ static void intc_irqpin_irq_enable_force(struct irq_data *d) static void intc_irqpin_irq_disable_force(struct irq_data *d) { struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); - int irq = p->irq[irqd_to_hwirq(d)].irq; + int irq = p->irq[irqd_to_hwirq(d)].requested_irq; irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq)); intc_irqpin_irq_disable(d); @@ -246,7 +246,7 @@ static irqreturn_t intc_irqpin_irq_handler(int irq, void *dev_id) if (intc_irqpin_read(p, INTC_IRQPIN_REG_SOURCE) & bit) { intc_irqpin_write(p, INTC_IRQPIN_REG_SOURCE, ~bit); intc_irqpin_dbg(i, "demux2"); - generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq)); + generic_handle_irq(i->domain_irq); return IRQ_HANDLED; } return IRQ_NONE; @@ -257,6 +257,9 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, { struct intc_irqpin_priv *p = h->host_data; + p->irq[hw].domain_irq = virq; + p->irq[hw].hw_irq = hw; + intc_irqpin_dbg(&p->irq[hw], "map"); irq_set_chip_data(virq, h->host_data); irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); @@ -314,9 +317,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) if (!irq) break; - p->irq[k].hw_irq = k; p->irq[k].p = p; - p->irq[k].irq = irq->start; + p->irq[k].requested_irq = irq->start; } p->number_of_irqs = k; @@ -389,7 +391,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) /* request and set priority on interrupts one by one */ for (k = 0; k < p->number_of_irqs; k++) { - if (request_irq(p->irq[k].irq, intc_irqpin_irq_handler, + if (request_irq(p->irq[k].requested_irq, + intc_irqpin_irq_handler, 0, name, &p->irq[k])) { dev_err(&pdev->dev, "failed to request low IRQ\n"); ret = -ENOENT; @@ -402,17 +405,16 @@ static int intc_irqpin_probe(struct platform_device *pdev) /* warn in case of mismatch if irq base is specified */ if (p->config.irq_base) { - k = irq_find_mapping(p->irq_domain, 0); - if (p->config.irq_base != k) + if (p->config.irq_base != p->irq[0].domain_irq) dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", - p->config.irq_base, k); + p->config.irq_base, p->irq[0].domain_irq); } return 0; err3: for (; k >= 0; k--) - free_irq(p->irq[k - 1].irq, &p->irq[k - 1]); + free_irq(p->irq[k - 1].requested_irq, &p->irq[k - 1]); irq_domain_remove(p->irq_domain); err2: @@ -430,7 +432,7 @@ static int intc_irqpin_remove(struct platform_device *pdev) int k; for (k = 0; k < p->number_of_irqs; k++) - free_irq(p->irq[k].irq, &p->irq[k]); + free_irq(p->irq[k].requested_irq, &p->irq[k]); irq_domain_remove(p->irq_domain); -- cgit From d1b6aecde4ab146d115abcaf3bb1940d8e980b5a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 20:59:04 +0900 Subject: irqchip: intc-irqpin: Add force comments Add comments to describe the special case for "force" versions of enable and disable functions. Signed-off-by: Magnus Damm Reviewed-by: Thomas Gleixner Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-intc-irqpin.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 0ac2bf683378..59c0cbccf212 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -199,6 +199,11 @@ static void intc_irqpin_irq_enable_force(struct irq_data *d) int irq = p->irq[irqd_to_hwirq(d)].requested_irq; intc_irqpin_irq_enable(d); + + /* enable interrupt through parent interrupt controller, + * assumes non-shared interrupt with 1:1 mapping + * needed for busted IRQs on some SoCs like sh73a0 + */ irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq)); } @@ -207,6 +212,10 @@ static void intc_irqpin_irq_disable_force(struct irq_data *d) struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d); int irq = p->irq[irqd_to_hwirq(d)].requested_irq; + /* disable interrupt through parent interrupt controller, + * assumes non-shared interrupt with 1:1 mapping + * needed for busted IRQs on some SoCs like sh73a0 + */ irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq)); intc_irqpin_irq_disable(d); } -- cgit From 08eba5ba4f321c4b1806ecad0e626904f89263a1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2013 20:59:13 +0900 Subject: irqchip: intc-irqpin: Make use of devm functions Use devm_kzalloc(), devm_ioremap_nocache() and devm_request_irq() to simplify error handling. Signed-off-by: Magnus Damm Reviewed-by: Thomas Gleixner Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-intc-irqpin.c | 41 ++++++++++--------------------- 1 file changed, 13 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 59c0cbccf212..21f46027f39a 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -294,7 +294,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) int ret; int k; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); if (!p) { dev_err(&pdev->dev, "failed to allocate driver data\n"); ret = -ENOMEM; @@ -316,7 +316,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) if (!io[k]) { dev_err(&pdev->dev, "not enough IOMEM resources\n"); ret = -EINVAL; - goto err1; + goto err0; } } @@ -334,7 +334,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) if (p->number_of_irqs < 1) { dev_err(&pdev->dev, "not enough IRQ resources\n"); ret = -EINVAL; - goto err1; + goto err0; } /* ioremap IOMEM and setup read/write callbacks */ @@ -355,14 +355,15 @@ static int intc_irqpin_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "IOMEM size mismatch\n"); ret = -EINVAL; - goto err2; + goto err0; } - i->iomem = ioremap_nocache(io[k]->start, resource_size(io[k])); + i->iomem = devm_ioremap_nocache(&pdev->dev, io[k]->start, + resource_size(io[k])); if (!i->iomem) { dev_err(&pdev->dev, "failed to remap IOMEM\n"); ret = -ENXIO; - goto err2; + goto err0; } } @@ -395,17 +396,17 @@ static int intc_irqpin_probe(struct platform_device *pdev) if (!p->irq_domain) { ret = -ENXIO; dev_err(&pdev->dev, "cannot initialize irq domain\n"); - goto err2; + goto err0; } /* request and set priority on interrupts one by one */ for (k = 0; k < p->number_of_irqs; k++) { - if (request_irq(p->irq[k].requested_irq, - intc_irqpin_irq_handler, - 0, name, &p->irq[k])) { + if (devm_request_irq(&pdev->dev, p->irq[k].requested_irq, + intc_irqpin_irq_handler, + 0, name, &p->irq[k])) { dev_err(&pdev->dev, "failed to request low IRQ\n"); ret = -ENOENT; - goto err3; + goto err1; } intc_irqpin_mask_unmask_prio(p, k, 0); } @@ -421,16 +422,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) return 0; -err3: - for (; k >= 0; k--) - free_irq(p->irq[k - 1].requested_irq, &p->irq[k - 1]); - - irq_domain_remove(p->irq_domain); -err2: - for (k = 0; k < INTC_IRQPIN_REG_NR; k++) - iounmap(p->iomem[k].iomem); err1: - kfree(p); + irq_domain_remove(p->irq_domain); err0: return ret; } @@ -438,17 +431,9 @@ err0: static int intc_irqpin_remove(struct platform_device *pdev) { struct intc_irqpin_priv *p = platform_get_drvdata(pdev); - int k; - - for (k = 0; k < p->number_of_irqs; k++) - free_irq(p->irq[k].requested_irq, &p->irq[k]); irq_domain_remove(p->irq_domain); - for (k = 0; k < INTC_IRQPIN_REG_NR; k++) - iounmap(p->iomem[k].iomem); - - kfree(p); return 0; } -- cgit From fbc83b7f59dd8ed1154286b6de00b6d03c24a3c4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 27 Feb 2013 17:15:01 +0900 Subject: irqchip: Renesas IRQC driver This patch adds a driver for external IRQ pins connected to the IRQC hardware block on recent SoCs from Renesas. The IRQC hardware block is used together with more recent ARM based SoCs using the GIC. As usual the GIC requires external IRQ trigger setup somewhere else which in this particular case happens to be IRQC. This driver implements the glue code needed to configure IRQ trigger and also handle mask/unmask and demux of external IRQ pins hooked up from the IRQC to the GIC. Tested on r8a73a4 but is designed to work with a wide range of SoCs. The driver requires one GIC SPI per external IRQ pin to operate. Each driver instance will handle up to 32 external IRQ pins. The SoCs using this driver are currently mainly used together with regular platform devices so this driver allows configuration via platform data to support things like static interrupt base address. DT support will be added incrementally in the not so distant future. Signed-off-by: Magnus Damm Tested-by: Guennadi Liakhovetski Signed-off-by: Simon Horman --- drivers/irqchip/Kconfig | 4 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-renesas-irqc.c | 298 +++++++++++++++++++++++++ include/linux/platform_data/irq-renesas-irqc.h | 27 +++ 4 files changed, 330 insertions(+) create mode 100644 drivers/irqchip/irq-renesas-irqc.c create mode 100644 include/linux/platform_data/irq-renesas-irqc.h (limited to 'drivers') diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 0f5f1c3825bc..4a33351c25dc 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -29,6 +29,10 @@ config RENESAS_INTC_IRQPIN bool select IRQ_DOMAIN +config RENESAS_IRQC + bool + select IRQ_DOMAIN + config VERSATILE_FPGA_IRQ bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 1aaa4073ab60..e41ceb9bec22 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o +obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c new file mode 100644 index 000000000000..95d69bfac982 --- /dev/null +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -0,0 +1,298 @@ +/* + * Renesas IRQC Driver + * + * Copyright (C) 2013 Magnus Damm + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ + +#define IRQC_REQ_STS 0x00 +#define IRQC_EN_STS 0x04 +#define IRQC_EN_SET 0x08 +#define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) +#define DETECT_STATUS 0x100 +#define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) + +struct irqc_irq { + int hw_irq; + int requested_irq; + int domain_irq; + struct irqc_priv *p; +}; + +struct irqc_priv { + void __iomem *iomem; + void __iomem *cpu_int_base; + struct irqc_irq irq[IRQC_IRQ_MAX]; + struct renesas_irqc_config config; + unsigned int number_of_irqs; + struct platform_device *pdev; + struct irq_chip irq_chip; + struct irq_domain *irq_domain; +}; + +static void irqc_dbg(struct irqc_irq *i, char *str) +{ + dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", + str, i->requested_irq, i->hw_irq, i->domain_irq); +} + +static void irqc_irq_enable(struct irq_data *d) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + irqc_dbg(&p->irq[hw_irq], "enable"); + iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_SET); +} + +static void irqc_irq_disable(struct irq_data *d) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + + irqc_dbg(&p->irq[hw_irq], "disable"); + iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_STS); +} + +#define INTC_IRQ_SENSE_VALID 0x10 +#define INTC_IRQ_SENSE(x) (x + INTC_IRQ_SENSE_VALID) + +static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { + [IRQ_TYPE_LEVEL_LOW] = INTC_IRQ_SENSE(0x01), + [IRQ_TYPE_LEVEL_HIGH] = INTC_IRQ_SENSE(0x02), + [IRQ_TYPE_EDGE_FALLING] = INTC_IRQ_SENSE(0x04), /* Synchronous */ + [IRQ_TYPE_EDGE_RISING] = INTC_IRQ_SENSE(0x08), /* Synchronous */ + [IRQ_TYPE_EDGE_BOTH] = INTC_IRQ_SENSE(0x0c), /* Synchronous */ +}; + +static int irqc_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct irqc_priv *p = irq_data_get_irq_chip_data(d); + int hw_irq = irqd_to_hwirq(d); + unsigned char value = irqc_sense[type & IRQ_TYPE_SENSE_MASK]; + unsigned long tmp; + + irqc_dbg(&p->irq[hw_irq], "sense"); + + if (!(value & INTC_IRQ_SENSE_VALID)) + return -EINVAL; + + tmp = ioread32(p->iomem + IRQC_CONFIG(hw_irq)); + tmp &= ~0x3f; + tmp |= value ^ INTC_IRQ_SENSE_VALID; + iowrite32(tmp, p->iomem + IRQC_CONFIG(hw_irq)); + return 0; +} + +static irqreturn_t irqc_irq_handler(int irq, void *dev_id) +{ + struct irqc_irq *i = dev_id; + struct irqc_priv *p = i->p; + unsigned long bit = BIT(i->hw_irq); + + irqc_dbg(i, "demux1"); + + if (ioread32(p->iomem + DETECT_STATUS) & bit) { + iowrite32(bit, p->iomem + DETECT_STATUS); + irqc_dbg(i, "demux2"); + generic_handle_irq(i->domain_irq); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct irqc_priv *p = h->host_data; + + p->irq[hw].domain_irq = virq; + p->irq[hw].hw_irq = hw; + + irqc_dbg(&p->irq[hw], "map"); + irq_set_chip_data(virq, h->host_data); + irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); /* kill me now */ + return 0; +} + +static struct irq_domain_ops irqc_irq_domain_ops = { + .map = irqc_irq_domain_map, +}; + +static int irqc_probe(struct platform_device *pdev) +{ + struct renesas_irqc_config *pdata = pdev->dev.platform_data; + struct irqc_priv *p; + struct resource *io; + struct resource *irq; + struct irq_chip *irq_chip; + const char *name = dev_name(&pdev->dev); + int ret; + int k; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + ret = -ENOMEM; + goto err0; + } + + /* deal with driver instance configuration */ + if (pdata) + memcpy(&p->config, pdata, sizeof(*pdata)); + + p->pdev = pdev; + platform_set_drvdata(pdev, p); + + /* get hold of manadatory IOMEM */ + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!io) { + dev_err(&pdev->dev, "not enough IOMEM resources\n"); + ret = -EINVAL; + goto err1; + } + + /* allow any number of IRQs between 1 and IRQC_IRQ_MAX */ + for (k = 0; k < IRQC_IRQ_MAX; k++) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, k); + if (!irq) + break; + + p->irq[k].p = p; + p->irq[k].requested_irq = irq->start; + } + + p->number_of_irqs = k; + if (p->number_of_irqs < 1) { + dev_err(&pdev->dev, "not enough IRQ resources\n"); + ret = -EINVAL; + goto err1; + } + + /* ioremap IOMEM and setup read/write callbacks */ + p->iomem = ioremap_nocache(io->start, resource_size(io)); + if (!p->iomem) { + dev_err(&pdev->dev, "failed to remap IOMEM\n"); + ret = -ENXIO; + goto err2; + } + + p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */ + + irq_chip = &p->irq_chip; + irq_chip->name = name; + irq_chip->irq_mask = irqc_irq_disable; + irq_chip->irq_unmask = irqc_irq_enable; + irq_chip->irq_enable = irqc_irq_enable; + irq_chip->irq_disable = irqc_irq_disable; + irq_chip->irq_set_type = irqc_irq_set_type; + irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; + + p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, + p->number_of_irqs, + p->config.irq_base, + &irqc_irq_domain_ops, p); + if (!p->irq_domain) { + ret = -ENXIO; + dev_err(&pdev->dev, "cannot initialize irq domain\n"); + goto err2; + } + + /* request interrupts one by one */ + for (k = 0; k < p->number_of_irqs; k++) { + if (request_irq(p->irq[k].requested_irq, irqc_irq_handler, + 0, name, &p->irq[k])) { + dev_err(&pdev->dev, "failed to request IRQ\n"); + ret = -ENOENT; + goto err3; + } + } + + dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); + + /* warn in case of mismatch if irq base is specified */ + if (p->config.irq_base) { + if (p->config.irq_base != p->irq[0].domain_irq) + dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n", + p->config.irq_base, p->irq[0].domain_irq); + } + + return 0; +err3: + for (; k >= 0; k--) + free_irq(p->irq[k - 1].requested_irq, &p->irq[k - 1]); + + irq_domain_remove(p->irq_domain); +err2: + iounmap(p->iomem); +err1: + kfree(p); +err0: + return ret; +} + +static int irqc_remove(struct platform_device *pdev) +{ + struct irqc_priv *p = platform_get_drvdata(pdev); + int k; + + for (k = 0; k < p->number_of_irqs; k++) + free_irq(p->irq[k].requested_irq, &p->irq[k]); + + irq_domain_remove(p->irq_domain); + iounmap(p->iomem); + kfree(p); + return 0; +} + +static struct platform_driver irqc_device_driver = { + .probe = irqc_probe, + .remove = irqc_remove, + .driver = { + .name = "renesas_irqc", + } +}; + +static int __init irqc_init(void) +{ + return platform_driver_register(&irqc_device_driver); +} +postcore_initcall(irqc_init); + +static void __exit irqc_exit(void) +{ + platform_driver_unregister(&irqc_device_driver); +} +module_exit(irqc_exit); + +MODULE_AUTHOR("Magnus Damm"); +MODULE_DESCRIPTION("Renesas IRQC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/irq-renesas-irqc.h b/include/linux/platform_data/irq-renesas-irqc.h new file mode 100644 index 000000000000..3ae17b3e00ed --- /dev/null +++ b/include/linux/platform_data/irq-renesas-irqc.h @@ -0,0 +1,27 @@ +/* + * Renesas IRQC Driver + * + * Copyright (C) 2013 Magnus Damm + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 __IRQ_RENESAS_IRQC_H__ +#define __IRQ_RENESAS_IRQC_H__ + +struct renesas_irqc_config { + unsigned int irq_base; +}; + +#endif /* __IRQ_RENESAS_IRQC_H__ */ -- cgit From 9d833bbe49953a9a07f9ebd7a9ad170c308bd692 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Mar 2013 15:16:08 +0900 Subject: irqchip: intc-irqpin: Initial DT support Add initial DT support to the INTC External IRQ Pin driver. At this point only hardware with 4-bit wide sense registers is supported via DT. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-intc-irqpin.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 21f46027f39a..fd5dabc2235d 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -278,6 +278,7 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, static struct irq_domain_ops intc_irqpin_irq_domain_ops = { .map = intc_irqpin_irq_domain_map, + .xlate = irq_domain_xlate_twocell, }; static int intc_irqpin_probe(struct platform_device *pdev) @@ -437,11 +438,19 @@ static int intc_irqpin_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id intc_irqpin_dt_ids[] = { + { .compatible = "renesas,intc-irqpin", }, + {}, +}; +MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); + static struct platform_driver intc_irqpin_device_driver = { .probe = intc_irqpin_probe, .remove = intc_irqpin_remove, .driver = { .name = "renesas_intc_irqpin", + .of_match_table = intc_irqpin_dt_ids, + .owner = THIS_MODULE, } }; -- cgit From 3b8dfa7c2f8af7613dae28ac0f3419bf75ead5d0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Mar 2013 15:23:39 +0900 Subject: irqchip: irqc: Add DT support Add DT support to the IRQC External IRQ Pin driver. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- drivers/irqchip/irq-renesas-irqc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 95d69bfac982..927bff373aac 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -145,6 +145,7 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, static struct irq_domain_ops irqc_irq_domain_ops = { .map = irqc_irq_domain_map, + .xlate = irq_domain_xlate_twocell, }; static int irqc_probe(struct platform_device *pdev) @@ -273,11 +274,19 @@ static int irqc_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id irqc_dt_ids[] = { + { .compatible = "renesas,irqc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, irqc_dt_ids); + static struct platform_driver irqc_device_driver = { .probe = irqc_probe, .remove = irqc_remove, .driver = { .name = "renesas_irqc", + .of_match_table = irqc_dt_ids, + .owner = THIS_MODULE, } }; -- cgit From 9ee1c7fbeab5b671d3b63f2dd33ad48235efcfe8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Mar 2013 11:05:03 +0200 Subject: usb: host: ohci-exynos: fix PHY error handling PHY layer no longer returns NULL. We must switch from IS_ERR_OR_NULL() to IS_ERR(). Signed-off-by: Felipe Balbi --- drivers/usb/host/ohci-exynos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index e3b7e85120e4..4b469e050208 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -128,7 +128,7 @@ static int exynos_ohci_probe(struct platform_device *pdev) return -ENOMEM; phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(phy)) { + if (IS_ERR(phy)) { /* Fallback to pdata */ if (!pdata) { dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); -- cgit From 399e0f4f00adbfdea2122c1daec0d4015f56cc7a Mon Sep 17 00:00:00 2001 From: Virupax Sadashivpetimath Date: Fri, 8 Mar 2013 10:27:05 +0800 Subject: usb: musb: ux500_dma: add missing MEM resource check Fix dma_controller_create() fail path in case memory resource is missing. Acked-by: Linus Walleij Signed-off-by: Virupax Sadashivpetimath Signed-off-by: Fabio Baltieri Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500_dma.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index c3a584cf01bb..2df9b7d1ddc6 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -374,12 +374,17 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba controller = kzalloc(sizeof(*controller), GFP_KERNEL); if (!controller) - return NULL; + goto kzalloc_fail; controller->private_data = musb; /* Save physical address for DMA controller. */ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { + dev_err(musb->controller, "no memory resource defined\n"); + goto plat_get_fail; + } + controller->phy_base = (dma_addr_t) iomem->start; controller->controller.start = ux500_dma_controller_start; @@ -391,4 +396,9 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba controller->controller.is_compatible = ux500_dma_is_compatible; return &controller->controller; + +plat_get_fail: + kfree(controller); +kzalloc_fail: + return NULL; } -- cgit From 996a9d26d37c7dca27b7e9830a49daa74a2603b7 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Mar 2013 10:27:06 +0800 Subject: usb: musb: ux500: implement musb_set_vbus Add ux500_musb_set_vbus() implementation for ux500. This is based on the version originally developed inside ST-Ericsson. Acked-by: Linus Walleij Signed-off-by: Fabio Baltieri [ balbi@ti.com: fix a build error due to missing otg_state_string() ] Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 13a392913769..0332fcd286f7 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -36,6 +36,68 @@ struct ux500_glue { }; #define glue_to_musb(g) platform_get_drvdata(g->musb) +static void ux500_musb_set_vbus(struct musb *musb, int is_on) +{ + u8 devctl; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + /* HDRC controls CPEN, but beware current surges during device + * connect. They can trigger transient overcurrent conditions + * that must be ignored. + */ + + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + + if (is_on) { + if (musb->xceiv->state == OTG_STATE_A_IDLE) { + /* start the session */ + devctl |= MUSB_DEVCTL_SESSION; + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); + /* + * Wait for the musb to set as A device to enable the + * VBUS + */ + while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { + + if (time_after(jiffies, timeout)) { + dev_err(musb->controller, + "configured as A device timeout"); + break; + } + } + + } else { + musb->is_active = 1; + musb->xceiv->otg->default_a = 1; + musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + devctl |= MUSB_DEVCTL_SESSION; + MUSB_HST_MODE(musb); + } + } else { + musb->is_active = 0; + + /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping + * right to B_IDLE... + */ + musb->xceiv->otg->default_a = 0; + devctl &= ~MUSB_DEVCTL_SESSION; + MUSB_DEV_MODE(musb); + } + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); + + /* + * Devctl values will be updated after vbus goes below + * session_valid. The time taken depends on the capacitance + * on VBUS line. The max discharge time can be upto 1 sec + * as per the spec. Typically on our platform, it is 200ms + */ + if (!is_on) + mdelay(200); + + dev_dbg(musb->controller, "VBUS %s, devctl %02x\n", + usb_otg_state_string(musb->xceiv->state), + musb_readb(musb->mregs, MUSB_DEVCTL)); +} + static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) { unsigned long flags; @@ -79,6 +141,8 @@ static int ux500_musb_exit(struct musb *musb) static const struct musb_platform_ops ux500_ops = { .init = ux500_musb_init, .exit = ux500_musb_exit, + + .set_vbus = ux500_musb_set_vbus, }; static int ux500_probe(struct platform_device *pdev) -- cgit From 0135522c48982cf1d456d863272e911fdf8a17da Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Mar 2013 10:27:07 +0800 Subject: usb: musb: ux500: add otg notifier support Add transceiver notifier event handling to the ux500 driver to set vbus on specific transceiver events. Acked-by: Linus Walleij Signed-off-by: Fabio Baltieri [ balbi@ti.com: fix build error due to missing otg_state_string() ] Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 0332fcd286f7..0ae9472a68a8 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -98,6 +98,37 @@ static void ux500_musb_set_vbus(struct musb *musb, int is_on) musb_readb(musb->mregs, MUSB_DEVCTL)); } +static int musb_otg_notifications(struct notifier_block *nb, + unsigned long event, void *unused) +{ + struct musb *musb = container_of(nb, struct musb, nb); + + dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n", + event, usb_otg_state_string(musb->xceiv->state)); + + switch (event) { + case USB_EVENT_ID: + dev_dbg(musb->controller, "ID GND\n"); + ux500_musb_set_vbus(musb, 1); + break; + case USB_EVENT_VBUS: + dev_dbg(musb->controller, "VBUS Connect\n"); + ux500_musb_set_vbus(musb, 0); + break; + case USB_EVENT_NONE: + dev_dbg(musb->controller, "VBUS Disconnect\n"); + if (is_host_active(musb)) + ux500_musb_set_vbus(musb, 0); + else + musb->xceiv->state = OTG_STATE_B_IDLE; + break; + default: + dev_dbg(musb->controller, "ID float\n"); + return NOTIFY_DONE; + } + return NOTIFY_OK; +} + static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) { unsigned long flags; @@ -120,12 +151,21 @@ static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) static int ux500_musb_init(struct musb *musb) { + int status; + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { pr_err("HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER; } + musb->nb.notifier_call = musb_otg_notifications; + status = usb_register_notifier(musb->xceiv, &musb->nb); + if (status < 0) { + dev_dbg(musb->controller, "notification register failed\n"); + return status; + } + musb->isr = ux500_musb_interrupt; return 0; @@ -133,6 +173,8 @@ static int ux500_musb_init(struct musb *musb) static int ux500_musb_exit(struct musb *musb) { + usb_unregister_notifier(musb->xceiv, &musb->nb); + usb_put_phy(musb->xceiv); return 0; -- cgit From 73f226cbd79adb5f3f25ee14c18900bb4a9acd15 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Mar 2013 10:27:08 +0800 Subject: usb: otg: ab8500-usb: drop support for ab8500 pre v2.0 AB8500 versions preceding 2.0 were only used internally by ST-Ericsson and are not supported anymore. This patch drops all v1.0 and v1.1 support code. Acked-by: Linus Walleij Signed-off-by: Fabio Baltieri Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-ab8500-usb.c | 139 ++++----------------------------------- 1 file changed, 11 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 2d86f26a0183..9f5e0e4ab02a 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -42,10 +42,8 @@ #define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) #define AB8500_BIT_WD_CTRL_KICK (1 << 1) -#define AB8500_V1x_LINK_STAT_WAIT (HZ/10) #define AB8500_WD_KICK_DELAY_US 100 /* usec */ #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ -#define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ /* Usb line status register */ enum ab8500_usb_link_status { @@ -70,16 +68,12 @@ enum ab8500_usb_link_status { struct ab8500_usb { struct usb_phy phy; struct device *dev; - int irq_num_id_rise; - int irq_num_id_fall; - int irq_num_vbus_rise; - int irq_num_vbus_fall; + struct ab8500 *ab8500; int irq_num_link_status; unsigned vbus_draw; struct delayed_work dwork; struct work_struct phy_dis_work; unsigned long link_status_wait; - int rev; }; static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) @@ -102,10 +96,7 @@ static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) (AB8500_BIT_WD_CTRL_ENABLE | AB8500_BIT_WD_CTRL_KICK)); - if (ab->rev > 0x10) /* v1.1 v2.0 */ - udelay(AB8500_WD_V11_DISABLE_DELAY_US); - else /* v1.0 */ - msleep(AB8500_WD_V10_DISABLE_DELAY_MS); + udelay(AB8500_WD_V11_DISABLE_DELAY_US); abx500_set_register_interruptible(ab->dev, AB8500_SYS_CTRL2_BLOCK, @@ -225,29 +216,6 @@ static void ab8500_usb_delayed_work(struct work_struct *work) ab8500_usb_link_status_update(ab); } -static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - -static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) -{ - struct ab8500_usb *ab = (struct ab8500_usb *) data; - - /* Link status will not be updated till phy is disabled. */ - ab8500_usb_peri_phy_dis(ab); - - /* Wait for link status to become stable. */ - schedule_delayed_work(&ab->dwork, ab->link_status_wait); - - return IRQ_HANDLED; -} - static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) { struct ab8500_usb *ab = (struct ab8500_usb *) data; @@ -361,86 +329,7 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) static void ab8500_usb_irq_free(struct ab8500_usb *ab) { - if (ab->rev < 0x20) { - free_irq(ab->irq_num_id_rise, ab); - free_irq(ab->irq_num_id_fall, ab); - free_irq(ab->irq_num_vbus_rise, ab); - free_irq(ab->irq_num_vbus_fall, ab); - } else { - free_irq(ab->irq_num_link_status, ab); - } -} - -static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) -{ - int err; - - ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); - if (ab->irq_num_id_rise < 0) { - dev_err(&pdev->dev, "ID rise irq not found\n"); - return ab->irq_num_id_rise; - } - err = request_threaded_irq(ab->irq_num_id_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID rise irq\n"); - goto fail0; - } - - ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); - if (ab->irq_num_id_fall < 0) { - dev_err(&pdev->dev, "ID fall irq not found\n"); - return ab->irq_num_id_fall; - } - err = request_threaded_irq(ab->irq_num_id_fall, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-id-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for ID fall irq\n"); - goto fail1; - } - - ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); - if (ab->irq_num_vbus_rise < 0) { - dev_err(&pdev->dev, "VBUS rise irq not found\n"); - return ab->irq_num_vbus_rise; - } - err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, - ab8500_usb_v1x_common_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-rise", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); - goto fail2; - } - - ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); - if (ab->irq_num_vbus_fall < 0) { - dev_err(&pdev->dev, "VBUS fall irq not found\n"); - return ab->irq_num_vbus_fall; - } - err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, - ab8500_usb_v1x_vbus_fall_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-vbus-fall", ab); - if (err < 0) { - dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); - goto fail3; - } - - return 0; -fail3: - free_irq(ab->irq_num_vbus_rise, ab); -fail2: - free_irq(ab->irq_num_id_fall, ab); -fail1: - free_irq(ab->irq_num_id_rise, ab); -fail0: - return err; + free_irq(ab->irq_num_link_status, ab); } static int ab8500_usb_v2_res_setup(struct platform_device *pdev, @@ -471,16 +360,16 @@ static int ab8500_usb_v2_res_setup(struct platform_device *pdev, static int ab8500_usb_probe(struct platform_device *pdev) { struct ab8500_usb *ab; + struct ab8500 *ab8500; struct usb_otg *otg; int err; int rev; + ab8500 = dev_get_drvdata(pdev->dev.parent); rev = abx500_get_chip_id(&pdev->dev); - if (rev < 0) { - dev_err(&pdev->dev, "Chip id read failed\n"); - return rev; - } else if (rev < 0x10) { - dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); + + if (is_ab8500_1p1_or_earlier(ab8500)) { + dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); return -ENODEV; } @@ -495,7 +384,7 @@ static int ab8500_usb_probe(struct platform_device *pdev) } ab->dev = &pdev->dev; - ab->rev = rev; + ab->ab8500 = ab8500; ab->phy.dev = ab->dev; ab->phy.otg = otg; ab->phy.label = "ab8500"; @@ -519,13 +408,7 @@ static int ab8500_usb_probe(struct platform_device *pdev) /* all: Disable phy when called from set_host and set_peripheral */ INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); - if (ab->rev < 0x20) { - err = ab8500_usb_v1x_res_setup(pdev, ab); - ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; - } else { - err = ab8500_usb_v2_res_setup(pdev, ab); - } - + err = ab8500_usb_v2_res_setup(pdev, ab); if (err < 0) goto fail0; @@ -535,7 +418,7 @@ static int ab8500_usb_probe(struct platform_device *pdev) goto fail1; } - dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); + dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); return 0; fail1: -- cgit From af6882be363d3a7bf0f72dd17ac2a639c4da0059 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 8 Mar 2013 10:27:09 +0800 Subject: usb: phy: ab8500-usb: update irq handling code Update irq handling code to notify all possible link status changes of AB8500 and AB8505 to the ux500-musb glue driver. The additional event codes will be used for pm-runtime implementation, and are defined in a separate ux500-specific header. This also modify the irq registration code to use devm_* helpers and drop all non necessary fail path code. Acked-by: Linus Walleij Signed-off-by: Fabio Baltieri Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 7 +- drivers/usb/phy/phy-ab8500-usb.c | 440 ++++++++++++++++++++++++++++++--------- include/linux/usb/musb-ux500.h | 31 +++ 3 files changed, 382 insertions(+), 96 deletions(-) create mode 100644 include/linux/usb/musb-ux500.h (limited to 'drivers') diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 0ae9472a68a8..88795f532370 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "musb_core.h" @@ -107,15 +108,15 @@ static int musb_otg_notifications(struct notifier_block *nb, event, usb_otg_state_string(musb->xceiv->state)); switch (event) { - case USB_EVENT_ID: + case UX500_MUSB_ID: dev_dbg(musb->controller, "ID GND\n"); ux500_musb_set_vbus(musb, 1); break; - case USB_EVENT_VBUS: + case UX500_MUSB_VBUS: dev_dbg(musb->controller, "VBUS Connect\n"); ux500_musb_set_vbus(musb, 0); break; - case USB_EVENT_NONE: + case UX500_MUSB_NONE: dev_dbg(musb->controller, "VBUS Disconnect\n"); if (is_host_active(musb)) ux500_musb_set_vbus(musb, 0); diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 9f5e0e4ab02a..351b0369a611 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -31,9 +31,11 @@ #include #include #include +#include #define AB8500_MAIN_WD_CTRL_REG 0x01 #define AB8500_USB_LINE_STAT_REG 0x80 +#define AB8505_USB_LINE_STAT_REG 0x94 #define AB8500_USB_PHY_CTRL_REG 0x8A #define AB8500_BIT_OTG_STAT_ID (1 << 0) @@ -44,36 +46,76 @@ #define AB8500_WD_KICK_DELAY_US 100 /* usec */ #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ +#define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ /* Usb line status register */ enum ab8500_usb_link_status { - USB_LINK_NOT_CONFIGURED = 0, - USB_LINK_STD_HOST_NC, - USB_LINK_STD_HOST_C_NS, - USB_LINK_STD_HOST_C_S, - USB_LINK_HOST_CHG_NM, - USB_LINK_HOST_CHG_HS, - USB_LINK_HOST_CHG_HS_CHIRP, - USB_LINK_DEDICATED_CHG, - USB_LINK_ACA_RID_A, - USB_LINK_ACA_RID_B, - USB_LINK_ACA_RID_C_NM, - USB_LINK_ACA_RID_C_HS, - USB_LINK_ACA_RID_C_HS_CHIRP, - USB_LINK_HM_IDGND, - USB_LINK_RESERVED, - USB_LINK_NOT_VALID_LINK + USB_LINK_NOT_CONFIGURED_8500 = 0, + USB_LINK_STD_HOST_NC_8500, + USB_LINK_STD_HOST_C_NS_8500, + USB_LINK_STD_HOST_C_S_8500, + USB_LINK_HOST_CHG_NM_8500, + USB_LINK_HOST_CHG_HS_8500, + USB_LINK_HOST_CHG_HS_CHIRP_8500, + USB_LINK_DEDICATED_CHG_8500, + USB_LINK_ACA_RID_A_8500, + USB_LINK_ACA_RID_B_8500, + USB_LINK_ACA_RID_C_NM_8500, + USB_LINK_ACA_RID_C_HS_8500, + USB_LINK_ACA_RID_C_HS_CHIRP_8500, + USB_LINK_HM_IDGND_8500, + USB_LINK_RESERVED_8500, + USB_LINK_NOT_VALID_LINK_8500, +}; + +enum ab8505_usb_link_status { + USB_LINK_NOT_CONFIGURED_8505 = 0, + USB_LINK_STD_HOST_NC_8505, + USB_LINK_STD_HOST_C_NS_8505, + USB_LINK_STD_HOST_C_S_8505, + USB_LINK_CDP_8505, + USB_LINK_RESERVED0_8505, + USB_LINK_RESERVED1_8505, + USB_LINK_DEDICATED_CHG_8505, + USB_LINK_ACA_RID_A_8505, + USB_LINK_ACA_RID_B_8505, + USB_LINK_ACA_RID_C_NM_8505, + USB_LINK_RESERVED2_8505, + USB_LINK_RESERVED3_8505, + USB_LINK_HM_IDGND_8505, + USB_LINK_CHARGERPORT_NOT_OK_8505, + USB_LINK_CHARGER_DM_HIGH_8505, + USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, + USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, + USB_LINK_STD_UPSTREAM_8505, + USB_LINK_CHARGER_SE1_8505, + USB_LINK_CARKIT_CHGR_1_8505, + USB_LINK_CARKIT_CHGR_2_8505, + USB_LINK_ACA_DOCK_CHGR_8505, + USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, + USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, + USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, + USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, + USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, +}; + +enum ab8500_usb_mode { + USB_IDLE = 0, + USB_PERIPHERAL, + USB_HOST, + USB_DEDICATED_CHG }; struct ab8500_usb { struct usb_phy phy; struct device *dev; struct ab8500 *ab8500; - int irq_num_link_status; unsigned vbus_draw; struct delayed_work dwork; struct work_struct phy_dis_work; unsigned long link_status_wait; + enum ab8500_usb_mode mode; + int previous_link_status_state; }; static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) @@ -104,6 +146,17 @@ static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) 0); } +static void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) +{ + /* Workaround for v2.0 bug # 31952 */ + if (is_ab8500_2p0(ab->ab8500)) { + abx500_mask_and_set_register_interruptible(ab->dev, + AB8500_USB, AB8500_USB_PHY_CTRL_REG, + bit, bit); + udelay(AB8500_V20_31952_DISABLE_DELAY_US); + } +} + static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, bool enable) { @@ -139,92 +192,276 @@ static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, #define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) #define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) -static int ab8500_usb_link_status_update(struct ab8500_usb *ab) +static int ab8505_usb_link_status_update(struct ab8500_usb *ab, + enum ab8505_usb_link_status lsts) { - u8 reg; - enum ab8500_usb_link_status lsts; - void *v = NULL; - enum usb_phy_events event; + enum ux500_musb_vbus_id_status event = 0; - abx500_get_register_interruptible(ab->dev, - AB8500_USB, - AB8500_USB_LINE_STAT_REG, - ®); + dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); - lsts = (reg >> 3) & 0x0F; + /* + * Spurious link_status interrupts are seen at the time of + * disconnection of a device in RIDA state + */ + if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && + (lsts == USB_LINK_STD_HOST_NC_8505)) + return 0; + + ab->previous_link_status_state = lsts; switch (lsts) { - case USB_LINK_NOT_CONFIGURED: - case USB_LINK_RESERVED: - case USB_LINK_NOT_VALID_LINK: - /* TODO: Disable regulators. */ - ab8500_usb_host_phy_dis(ab); - ab8500_usb_peri_phy_dis(ab); - ab->phy.state = OTG_STATE_B_IDLE; + case USB_LINK_ACA_RID_B_8505: + event = UX500_MUSB_RIDB; + case USB_LINK_NOT_CONFIGURED_8505: + case USB_LINK_RESERVED0_8505: + case USB_LINK_RESERVED1_8505: + case USB_LINK_RESERVED2_8505: + case USB_LINK_RESERVED3_8505: + ab->mode = USB_IDLE; ab->phy.otg->default_a = false; ab->vbus_draw = 0; - event = USB_EVENT_NONE; + if (event != UX500_MUSB_RIDB) + event = UX500_MUSB_NONE; + /* + * Fallback to default B_IDLE as nothing + * is connected + */ + ab->phy.state = OTG_STATE_B_IDLE; break; - case USB_LINK_STD_HOST_NC: - case USB_LINK_STD_HOST_C_NS: - case USB_LINK_STD_HOST_C_S: - case USB_LINK_HOST_CHG_NM: - case USB_LINK_HOST_CHG_HS: - case USB_LINK_HOST_CHG_HS_CHIRP: - if (ab->phy.otg->gadget) { - /* TODO: Enable regulators. */ + case USB_LINK_ACA_RID_C_NM_8505: + event = UX500_MUSB_RIDC; + case USB_LINK_STD_HOST_NC_8505: + case USB_LINK_STD_HOST_C_NS_8505: + case USB_LINK_STD_HOST_C_S_8505: + case USB_LINK_CDP_8505: + if (ab->mode == USB_IDLE) { + ab->mode = USB_PERIPHERAL; ab8500_usb_peri_phy_en(ab); - v = ab->phy.otg->gadget; + atomic_notifier_call_chain(&ab->phy.notifier, + UX500_MUSB_PREPARE, &ab->vbus_draw); } - event = USB_EVENT_VBUS; + if (event != UX500_MUSB_RIDC) + event = UX500_MUSB_VBUS; break; - case USB_LINK_HM_IDGND: - if (ab->phy.otg->host) { - /* TODO: Enable regulators. */ + case USB_LINK_ACA_RID_A_8505: + case USB_LINK_ACA_DOCK_CHGR_8505: + event = UX500_MUSB_RIDA; + case USB_LINK_HM_IDGND_8505: + if (ab->mode == USB_IDLE) { + ab->mode = USB_HOST; ab8500_usb_host_phy_en(ab); - v = ab->phy.otg->host; + atomic_notifier_call_chain(&ab->phy.notifier, + UX500_MUSB_PREPARE, &ab->vbus_draw); } - ab->phy.state = OTG_STATE_A_IDLE; ab->phy.otg->default_a = true; - event = USB_EVENT_ID; + if (event != UX500_MUSB_RIDA) + event = UX500_MUSB_ID; + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); break; - case USB_LINK_ACA_RID_A: - case USB_LINK_ACA_RID_B: - /* TODO */ - case USB_LINK_ACA_RID_C_NM: - case USB_LINK_ACA_RID_C_HS: - case USB_LINK_ACA_RID_C_HS_CHIRP: - case USB_LINK_DEDICATED_CHG: - /* TODO: vbus_draw */ - event = USB_EVENT_CHARGER; + case USB_LINK_DEDICATED_CHG_8505: + ab->mode = USB_DEDICATED_CHG; + event = UX500_MUSB_CHARGER; + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); + break; + + default: break; } - atomic_notifier_call_chain(&ab->phy.notifier, event, v); + return 0; +} + +static int ab8500_usb_link_status_update(struct ab8500_usb *ab, + enum ab8500_usb_link_status lsts) +{ + enum ux500_musb_vbus_id_status event = 0; + + dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); + + /* + * Spurious link_status interrupts are seen in case of a + * disconnection of a device in IDGND and RIDA stage + */ + if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && + (lsts == USB_LINK_STD_HOST_C_NS_8500 || + lsts == USB_LINK_STD_HOST_NC_8500)) + return 0; + + if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && + lsts == USB_LINK_STD_HOST_NC_8500) + return 0; + + ab->previous_link_status_state = lsts; + + switch (lsts) { + case USB_LINK_ACA_RID_B_8500: + event = UX500_MUSB_RIDB; + case USB_LINK_NOT_CONFIGURED_8500: + case USB_LINK_NOT_VALID_LINK_8500: + ab->mode = USB_IDLE; + ab->phy.otg->default_a = false; + ab->vbus_draw = 0; + if (event != UX500_MUSB_RIDB) + event = UX500_MUSB_NONE; + /* Fallback to default B_IDLE as nothing is connected */ + ab->phy.state = OTG_STATE_B_IDLE; + break; + + case USB_LINK_ACA_RID_C_NM_8500: + case USB_LINK_ACA_RID_C_HS_8500: + case USB_LINK_ACA_RID_C_HS_CHIRP_8500: + event = UX500_MUSB_RIDC; + case USB_LINK_STD_HOST_NC_8500: + case USB_LINK_STD_HOST_C_NS_8500: + case USB_LINK_STD_HOST_C_S_8500: + case USB_LINK_HOST_CHG_NM_8500: + case USB_LINK_HOST_CHG_HS_8500: + case USB_LINK_HOST_CHG_HS_CHIRP_8500: + if (ab->mode == USB_IDLE) { + ab->mode = USB_PERIPHERAL; + ab8500_usb_peri_phy_en(ab); + atomic_notifier_call_chain(&ab->phy.notifier, + UX500_MUSB_PREPARE, &ab->vbus_draw); + } + if (event != UX500_MUSB_RIDC) + event = UX500_MUSB_VBUS; + break; + + case USB_LINK_ACA_RID_A_8500: + event = UX500_MUSB_RIDA; + case USB_LINK_HM_IDGND_8500: + if (ab->mode == USB_IDLE) { + ab->mode = USB_HOST; + ab8500_usb_host_phy_en(ab); + atomic_notifier_call_chain(&ab->phy.notifier, + UX500_MUSB_PREPARE, &ab->vbus_draw); + } + ab->phy.otg->default_a = true; + if (event != UX500_MUSB_RIDA) + event = UX500_MUSB_ID; + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); + break; + + case USB_LINK_DEDICATED_CHG_8500: + ab->mode = USB_DEDICATED_CHG; + event = UX500_MUSB_CHARGER; + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); + break; + + case USB_LINK_RESERVED_8500: + break; + } return 0; } -static void ab8500_usb_delayed_work(struct work_struct *work) +/* + * Connection Sequence: + * 1. Link Status Interrupt + * 2. Enable AB clock + * 3. Enable AB regulators + * 4. Enable USB phy + * 5. Reset the musb controller + * 6. Switch the ULPI GPIO pins to fucntion mode + * 7. Enable the musb Peripheral5 clock + * 8. Restore MUSB context + */ +static int abx500_usb_link_status_update(struct ab8500_usb *ab) { - struct ab8500_usb *ab = container_of(work, struct ab8500_usb, - dwork.work); + u8 reg; + int ret = 0; + + if (is_ab8500(ab->ab8500)) { + enum ab8500_usb_link_status lsts; + + abx500_get_register_interruptible(ab->dev, + AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); + lsts = (reg >> 3) & 0x0F; + ret = ab8500_usb_link_status_update(ab, lsts); + } else if (is_ab8505(ab->ab8500)) { + enum ab8505_usb_link_status lsts; + + abx500_get_register_interruptible(ab->dev, + AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); + lsts = (reg >> 3) & 0x1F; + ret = ab8505_usb_link_status_update(ab, lsts); + } + + return ret; +} + +/* + * Disconnection Sequence: + * 1. Disconect Interrupt + * 2. Disable regulators + * 3. Disable AB clock + * 4. Disable the Phy + * 5. Link Status Interrupt + * 6. Disable Musb Clock + */ +static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) +{ + struct ab8500_usb *ab = (struct ab8500_usb *) data; + enum usb_phy_events event = UX500_MUSB_NONE; + + /* Link status will not be updated till phy is disabled. */ + if (ab->mode == USB_HOST) { + ab->phy.otg->default_a = false; + ab->vbus_draw = 0; + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); + ab8500_usb_host_phy_dis(ab); + ab->mode = USB_IDLE; + } + + if (ab->mode == USB_PERIPHERAL) { + atomic_notifier_call_chain(&ab->phy.notifier, + event, &ab->vbus_draw); + ab8500_usb_peri_phy_dis(ab); + atomic_notifier_call_chain(&ab->phy.notifier, + UX500_MUSB_CLEAN, &ab->vbus_draw); + ab->mode = USB_IDLE; + ab->phy.otg->default_a = false; + ab->vbus_draw = 0; + } + + if (is_ab8500_2p0(ab->ab8500)) { + if (ab->mode == USB_DEDICATED_CHG) { + ab8500_usb_wd_linkstatus(ab, + AB8500_BIT_PHY_CTRL_DEVICE_EN); + abx500_mask_and_set_register_interruptible(ab->dev, + AB8500_USB, AB8500_USB_PHY_CTRL_REG, + AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); + } + } - ab8500_usb_link_status_update(ab); + return IRQ_HANDLED; } -static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) +static irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) { struct ab8500_usb *ab = (struct ab8500_usb *) data; - ab8500_usb_link_status_update(ab); + abx500_usb_link_status_update(ab); return IRQ_HANDLED; } +static void ab8500_usb_delayed_work(struct work_struct *work) +{ + struct ab8500_usb *ab = container_of(work, struct ab8500_usb, + dwork.work); + + abx500_usb_link_status_update(ab); +} + static void ab8500_usb_phy_disable_work(struct work_struct *work) { struct ab8500_usb *ab = container_of(work, struct ab8500_usb, @@ -250,7 +487,7 @@ static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) if (mA) atomic_notifier_call_chain(&ab->phy.notifier, - USB_EVENT_ENUMERATED, ab->phy.otg->gadget); + UX500_MUSB_ENUMERATED, ab->phy.otg->gadget); return 0; } @@ -327,30 +564,48 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } -static void ab8500_usb_irq_free(struct ab8500_usb *ab) -{ - free_irq(ab->irq_num_link_status, ab); -} - -static int ab8500_usb_v2_res_setup(struct platform_device *pdev, - struct ab8500_usb *ab) +static int ab8500_usb_irq_setup(struct platform_device *pdev, + struct ab8500_usb *ab) { int err; + int irq; - ab->irq_num_link_status = platform_get_irq_byname(pdev, - "USB_LINK_STATUS"); - if (ab->irq_num_link_status < 0) { + irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); + if (irq < 0) { dev_err(&pdev->dev, "Link status irq not found\n"); - return ab->irq_num_link_status; + return irq; + } + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, + ab8500_usb_link_status_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for link status irq\n"); + return err; } - err = request_threaded_irq(ab->irq_num_link_status, NULL, - ab8500_usb_v20_irq, - IRQF_NO_SUSPEND | IRQF_SHARED, - "usb-link-status", ab); + irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); + if (irq < 0) { + dev_err(&pdev->dev, "ID fall irq not found\n"); + return irq; + } + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, + ab8500_usb_disconnect_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); if (err < 0) { - dev_err(ab->dev, - "request_irq failed for link status irq\n"); + dev_err(ab->dev, "request_irq failed for ID fall irq\n"); + return err; + } + + irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); + if (irq < 0) { + dev_err(&pdev->dev, "VBUS fall irq not found\n"); + return irq; + } + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, + ab8500_usb_disconnect_irq, + IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); + if (err < 0) { + dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); return err; } @@ -408,22 +663,23 @@ static int ab8500_usb_probe(struct platform_device *pdev) /* all: Disable phy when called from set_host and set_peripheral */ INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); - err = ab8500_usb_v2_res_setup(pdev, ab); + err = ab8500_usb_irq_setup(pdev, ab); if (err < 0) - goto fail0; + goto fail; err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); if (err) { dev_err(&pdev->dev, "Can't register transceiver\n"); - goto fail1; + goto fail; } + /* Needed to enable ID detection. */ + ab8500_usb_wd_workaround(ab); + dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); return 0; -fail1: - ab8500_usb_irq_free(ab); -fail0: +fail: kfree(otg); kfree(ab); return err; @@ -433,8 +689,6 @@ static int ab8500_usb_remove(struct platform_device *pdev) { struct ab8500_usb *ab = platform_get_drvdata(pdev); - ab8500_usb_irq_free(ab); - cancel_delayed_work_sync(&ab->dwork); cancel_work_sync(&ab->phy_dis_work); diff --git a/include/linux/usb/musb-ux500.h b/include/linux/usb/musb-ux500.h new file mode 100644 index 000000000000..1e2c7130f6e1 --- /dev/null +++ b/include/linux/usb/musb-ux500.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 ST-Ericsson AB + * + * 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. + */ + +#ifndef __MUSB_UX500_H__ +#define __MUSB_UX500_H__ + +enum ux500_musb_vbus_id_status { + UX500_MUSB_NONE = 0, + UX500_MUSB_VBUS, + UX500_MUSB_ID, + UX500_MUSB_CHARGER, + UX500_MUSB_ENUMERATED, + UX500_MUSB_RIDA, + UX500_MUSB_RIDB, + UX500_MUSB_RIDC, + UX500_MUSB_PREPARE, + UX500_MUSB_CLEAN, +}; + +#endif /* __MUSB_UX500_H__ */ -- cgit From a53640c3f2d11a15d7834844d06554a6b1d2dce3 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:10:40 +0800 Subject: driver: hv: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Andrew Morton Cc: devel@linuxdriverproject.org Signed-off-by: Jiri Kosina --- drivers/hv/hv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 731158910c1e..ae4923756d98 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -289,9 +289,8 @@ void hv_synic_init(void *arg) /* Check the version */ rdmsrl(HV_X64_MSR_SVERSION, version); - hv_context.event_dpc[cpu] = (struct tasklet_struct *) - kmalloc(sizeof(struct tasklet_struct), - GFP_ATOMIC); + hv_context.event_dpc[cpu] = kmalloc(sizeof(struct tasklet_struct), + GFP_ATOMIC); if (hv_context.event_dpc[cpu] == NULL) { pr_err("Unable to allocate event dpc\n"); goto cleanup; -- cgit From eb2c560f9f2b126e1d0ebcd35709c5b37c28c817 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:29:32 +0800 Subject: driver: tty: vt: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Andrew Morton Signed-off-by: Jiri Kosina --- drivers/tty/vt/consolemap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 248381b30722..2978ca596a7f 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -194,8 +194,7 @@ static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int q = p->inverse_translations[i]; if (!q) { - q = p->inverse_translations[i] = (unsigned char *) - kmalloc(MAX_GLYPH, GFP_KERNEL); + q = p->inverse_translations[i] = kmalloc(MAX_GLYPH, GFP_KERNEL); if (!q) return; } memset(q, 0, MAX_GLYPH); -- cgit From c03117574726750ea01508b7b89fe058eabe2251 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:07:37 +0800 Subject: driver: gpu: drm: i915: remove cast for kzalloc return value remove cast for kzalloc return value. Signed-off-by: Zhang Yanfei Cc: Andrew Morton Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Jiri Kosina --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d07a8cdf998e..78413ec623c9 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -451,7 +451,7 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, int i, ret = true; /* Would be simpler to allocate both in one go ? */ - buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); + buf = kzalloc(args_len * 2 + 2, GFP_KERNEL); if (!buf) return false; -- cgit From 99c4d538854833c1be1e7449605de2f39519299e Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:27:29 +0800 Subject: driver: tty: serial: remove cast for kzalloc return value remove cast for kzalloc return value. Signed-off-by: Zhang Yanfei Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Andrew Morton Cc: linux-serial@vger.kernel.org Signed-off-by: Jiri Kosina --- drivers/tty/serial/icom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index bc9e6b017b05..18ed5aebb166 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1415,8 +1415,7 @@ static int icom_alloc_adapter(struct icom_adapter struct icom_adapter *cur_adapter_entry; struct list_head *tmp; - icom_adapter = (struct icom_adapter *) - kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); + icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); if (!icom_adapter) { return -ENOMEM; -- cgit From 53140e062bcabef33dddafd09132f5d62de90144 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:33:27 +0800 Subject: driver: usb: storage: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Matthew Dharm Cc: Greg Kroah-Hartman Cc: Andrew Morton Cc: linux-usb@vger.kernel.org Cc: usb-storage@lists.one-eyed-alien.net Signed-off-by: Jiri Kosina --- drivers/usb/storage/isd200.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index ecea47877364..06a3d22db685 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1457,8 +1457,7 @@ static int isd200_init_info(struct us_data *us) retStatus = ISD200_ERROR; else { info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL); - info->RegsBuf = (unsigned char *) - kmalloc(sizeof(info->ATARegs), GFP_KERNEL); + info->RegsBuf = kmalloc(sizeof(info->ATARegs), GFP_KERNEL); info->srb.sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) { -- cgit From ce03cb20640b94d6124decec36db4d84ee30c83c Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 27 Feb 2013 17:16:12 +0800 Subject: drivers/isdn: delete 'break' after 'return' delete 'break' statement after 'return' statement Signed-off-by: Chen Gang Signed-off-by: Jiri Kosina --- drivers/isdn/i4l/isdn_tty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index d8a7d8323414..925a7ed4a852 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -3425,7 +3425,6 @@ isdn_tty_parse_at(modem_info *info) p++; isdn_tty_cmd_ATA(info); return; - break; case 'D': /* D - Dial */ if (info->msr & UART_MSR_DCD) -- cgit From cf2fbdd26f80046725a11a80683a03baf27fae82 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 16 Mar 2013 20:53:05 +0900 Subject: treewide: Fix typos in printk and comment Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- arch/arc/plat-arcfpga/Kconfig | 2 +- arch/blackfin/include/asm/bfin_sport3.h | 2 +- arch/s390/kernel/irq.c | 2 +- arch/s390/kvm/trace.h | 2 +- drivers/crypto/caam/ctrl.c | 2 +- drivers/gpu/drm/radeon/radeon_irq_kms.c | 2 +- drivers/i2c/busses/i2c-puv3.c | 2 +- drivers/scsi/qla4xxx/ql4_nx.c | 2 +- drivers/usb/misc/uss720.c | 2 +- include/trace/events/timer.h | 10 +++++----- sound/pci/mixart/mixart.c | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/arch/arc/plat-arcfpga/Kconfig b/arch/arc/plat-arcfpga/Kconfig index b41e786cdbc0..295cefeb25d3 100644 --- a/arch/arc/plat-arcfpga/Kconfig +++ b/arch/arc/plat-arcfpga/Kconfig @@ -53,7 +53,7 @@ menuconfig ARC_HAS_BVCI_LAT_UNIT bool "BVCI Bus Latency Unit" depends on ARC_BOARD_ML509 || ARC_BOARD_ANGEL4 help - IP to add artifical latency to BVCI Bus Based FPGA builds. + IP to add artificial latency to BVCI Bus Based FPGA builds. The default latency (even worst case) for FPGA is non-realistic (~10 SDRAM, ~5 SSRAM). diff --git a/arch/blackfin/include/asm/bfin_sport3.h b/arch/blackfin/include/asm/bfin_sport3.h index 03c00220d69b..d82f5fa0ad9f 100644 --- a/arch/blackfin/include/asm/bfin_sport3.h +++ b/arch/blackfin/include/asm/bfin_sport3.h @@ -41,7 +41,7 @@ #define SPORT_CTL_LAFS 0x00020000 /* Late Transmit frame select */ #define SPORT_CTL_RJUST 0x00040000 /* Right Justified mode select */ #define SPORT_CTL_FSED 0x00080000 /* External frame sync edge select */ -#define SPORT_CTL_TFIEN 0x00100000 /* Transmit finish interrrupt enable select */ +#define SPORT_CTL_TFIEN 0x00100000 /* Transmit finish interrupt enable select */ #define SPORT_CTL_GCLKEN 0x00200000 /* Gated clock mode select */ #define SPORT_CTL_SPENSEC 0x01000000 /* Enable secondary channel */ #define SPORT_CTL_SPTRAN 0x02000000 /* Data direction control */ diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 1630f439cd2a..4f5ef62934a4 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -33,7 +33,7 @@ struct irq_class { }; /* - * The list of "main" irq classes on s390. This is the list of interrrupts + * The list of "main" irq classes on s390. This is the list of interrupts * that appear both in /proc/stat ("intr" line) and /proc/interrupts. * Historically only external and I/O interrupts have been part of /proc/stat. * We can't add the split external and I/O sub classes since the first field diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h index 2b29e62351d3..747898805359 100644 --- a/arch/s390/kvm/trace.h +++ b/arch/s390/kvm/trace.h @@ -67,7 +67,7 @@ TRACE_EVENT(kvm_s390_sie_fault, #define sie_intercept_code \ {0x04, "Instruction"}, \ {0x08, "Program interruption"}, \ - {0x0C, "Instruction and program interuption"}, \ + {0x0C, "Instruction and program interruption"}, \ {0x10, "External request"}, \ {0x14, "External interruption"}, \ {0x18, "I/O request"}, \ diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 1c56f63524f2..8acf00490fd5 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -66,7 +66,7 @@ static void build_instantiation_desc(u32 *desc) /* * load 1 to clear written reg: - * resets the done interrrupt and returns the RNG to idle. + * resets the done interrupt and returns the RNG to idle. */ append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 90374dd77960..8c8a7f0d982e 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -270,7 +270,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) } /** - * radeon_irq_kms_fini - tear down driver interrrupt info + * radeon_irq_kms_fini - tear down driver interrupt info * * @rdev: radeon device pointer * diff --git a/drivers/i2c/busses/i2c-puv3.c b/drivers/i2c/busses/i2c-puv3.c index 261d7db437e2..8acef657abf3 100644 --- a/drivers/i2c/busses/i2c-puv3.c +++ b/drivers/i2c/busses/i2c-puv3.c @@ -199,7 +199,7 @@ static int puv3_i2c_probe(struct platform_device *pdev) adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); if (adapter == NULL) { - dev_err(&pdev->dev, "can't allocate inteface!\n"); + dev_err(&pdev->dev, "can't allocate interface!\n"); rc = -ENOMEM; goto fail_nomem; } diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 71d3d234f526..9299400d3c9e 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -2089,7 +2089,7 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha, if (r_addr & 0xf) { DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: Read addr 0x%x not 16 bytes alligned\n", + "[%s]: Read addr 0x%x not 16 bytes aligned\n", __func__, r_addr)); return QLA_ERROR; } diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 29cad9e0a7a9..e129cf661223 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -705,7 +705,7 @@ static int uss720_probe(struct usb_interface *intf, return -ENODEV; } i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); - dev_dbg(&intf->dev, "set inteface result %d\n", i); + dev_dbg(&intf->dev, "set interface result %d\n", i); interface = intf->cur_altsetting; diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 425bcfe56c62..8d219470624f 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -123,7 +123,7 @@ DEFINE_EVENT(timer_class, timer_cancel, /** * hrtimer_init - called when the hrtimer is initialized - * @timer: pointer to struct hrtimer + * @hrtimer: pointer to struct hrtimer * @clockid: the hrtimers clock * @mode: the hrtimers mode */ @@ -155,7 +155,7 @@ TRACE_EVENT(hrtimer_init, /** * hrtimer_start - called when the hrtimer is started - * @timer: pointer to struct hrtimer + * @hrtimer: pointer to struct hrtimer */ TRACE_EVENT(hrtimer_start, @@ -186,8 +186,8 @@ TRACE_EVENT(hrtimer_start, ); /** - * htimmer_expire_entry - called immediately before the hrtimer callback - * @timer: pointer to struct hrtimer + * hrtimer_expire_entry - called immediately before the hrtimer callback + * @hrtimer: pointer to struct hrtimer * @now: pointer to variable which contains current time of the * timers base. * @@ -234,7 +234,7 @@ DECLARE_EVENT_CLASS(hrtimer_class, /** * hrtimer_expire_exit - called immediately after the hrtimer callback returns - * @timer: pointer to struct hrtimer + * @hrtimer: pointer to struct hrtimer * * When used in combination with the hrtimer_expire_entry tracepoint we can * determine the runtime of the callback function. diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 01f7f37a8410..934dec98e2ce 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1175,7 +1175,7 @@ static void snd_mixart_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, "\tstreaming : %d\n", streaming); snd_iprintf(buffer, "\tmailbox : %d\n", mailbox); - snd_iprintf(buffer, "\tinterrups handling : %d\n\n", interr); + snd_iprintf(buffer, "\tinterrupts handling : %d\n\n", interr); } } /* endif elf loaded */ } -- cgit From 9a18dd15e2ec934d8265009d3882955dcc059a49 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Sun, 17 Mar 2013 22:34:48 +0000 Subject: net: neterion: replace ip_fast_csum with csum_replace2 replace ip_fast_csum with csum_replace2 to save cpu cycles Signed-off-by: Li RongQing Signed-off-by: David S. Miller --- drivers/net/ethernet/neterion/s2io.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index bfd887382e19..3371ff41bb34 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -8337,16 +8338,13 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) { struct iphdr *ip = lro->iph; struct tcphdr *tcp = lro->tcph; - __sum16 nchk; struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__); /* Update L3 header */ + csum_replace2(&ip->check, ip->tot_len, htons(lro->total_len)); ip->tot_len = htons(lro->total_len); - ip->check = 0; - nchk = ip_fast_csum((u8 *)lro->iph, ip->ihl); - ip->check = nchk; /* Update L4 header */ tcp->ack_seq = lro->tcp_ack; -- cgit From a8f9c3e4c9826fb277453ed02d059591d6b6ebae Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Mar 2013 01:50:46 +0000 Subject: net: dm9000: Use module_platform_driver() module_platform_driver macro removes some boilerplate and makes the code simpler. Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/ethernet/davicom/dm9000.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 8cdf02503d13..f38f677f8420 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1687,22 +1687,7 @@ static struct platform_driver dm9000_driver = { .remove = dm9000_drv_remove, }; -static int __init -dm9000_init(void) -{ - printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION); - - return platform_driver_register(&dm9000_driver); -} - -static void __exit -dm9000_cleanup(void) -{ - platform_driver_unregister(&dm9000_driver); -} - -module_init(dm9000_init); -module_exit(dm9000_cleanup); +module_platform_driver(dm9000_driver); MODULE_AUTHOR("Sascha Hauer, Ben Dooks"); MODULE_DESCRIPTION("Davicom DM9000 network driver"); -- cgit From e827c122992127de6bc8de34d5d113fe34c382fb Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Mar 2013 01:50:47 +0000 Subject: net: ep93xx_eth: Use module_platform_driver() module_platform_driver macro removes some boilerplate and makes the code simpler. Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/ethernet/cirrus/ep93xx_eth.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c index 354cbb78ed50..67b0388b6e68 100644 --- a/drivers/net/ethernet/cirrus/ep93xx_eth.c +++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c @@ -887,18 +887,7 @@ static struct platform_driver ep93xx_eth_driver = { }, }; -static int __init ep93xx_eth_init_module(void) -{ - printk(KERN_INFO DRV_MODULE_NAME " version " DRV_MODULE_VERSION " loading\n"); - return platform_driver_register(&ep93xx_eth_driver); -} - -static void __exit ep93xx_eth_cleanup_module(void) -{ - platform_driver_unregister(&ep93xx_eth_driver); -} +module_platform_driver(ep93xx_eth_driver); -module_init(ep93xx_eth_init_module); -module_exit(ep93xx_eth_cleanup_module); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:ep93xx-eth"); -- cgit From 14f645d0deb4d189612e139c4270a4e82ce8a2db Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Mar 2013 01:50:48 +0000 Subject: net: ftgmac100: Use module_platform_driver() module_platform_driver macro removes some boilerplate and makes the code simpler. Signed-off-by: Sachin Kamat Cc: Po-Yu Chuang Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 0e817e6084e9..21b85fb7d05f 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1349,22 +1349,7 @@ static struct platform_driver ftgmac100_driver = { }, }; -/****************************************************************************** - * initialization / finalization - *****************************************************************************/ -static int __init ftgmac100_init(void) -{ - pr_info("Loading version " DRV_VERSION " ...\n"); - return platform_driver_register(&ftgmac100_driver); -} - -static void __exit ftgmac100_exit(void) -{ - platform_driver_unregister(&ftgmac100_driver); -} - -module_init(ftgmac100_init); -module_exit(ftgmac100_exit); +module_platform_driver(ftgmac100_driver); MODULE_AUTHOR("Po-Yu Chuang "); MODULE_DESCRIPTION("FTGMAC100 driver"); -- cgit From a848ade408b6bfab59d575d6c246efb20afe88e3 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 18 Mar 2013 06:51:03 +0000 Subject: bnx2x: add CSUM and TSO support for encapsulation protocols The patch utilizes FW offload capabilities for encapsulation protocols. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 29 ++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 196 +++++++++++++++++++++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 + 3 files changed, 204 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 9e8d1955dfcf..a4729c73ab80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -612,9 +612,10 @@ struct bnx2x_fastpath { * START_BD - describes packed * START_BD(splitted) - includes unpaged data segment for GSO * PARSING_BD - for TSO and CSUM data + * PARSING_BD2 - for encapsulation data * Frag BDs - decribes pages for frags */ -#define BDS_PER_TX_PKT 3 +#define BDS_PER_TX_PKT 4 #define MAX_BDS_PER_TX_PKT (MAX_SKB_FRAGS + BDS_PER_TX_PKT) /* max BDs per tx packet including next pages */ #define MAX_DESC_PER_TX_PKT (MAX_BDS_PER_TX_PKT + \ @@ -731,16 +732,22 @@ struct bnx2x_fastpath { #define pbd_tcp_flags(tcp_hdr) (ntohl(tcp_flag_word(tcp_hdr))>>16 & 0xff) -#define XMIT_PLAIN 0 -#define XMIT_CSUM_V4 0x1 -#define XMIT_CSUM_V6 0x2 -#define XMIT_CSUM_TCP 0x4 -#define XMIT_GSO_V4 0x8 -#define XMIT_GSO_V6 0x10 - -#define XMIT_CSUM (XMIT_CSUM_V4 | XMIT_CSUM_V6) -#define XMIT_GSO (XMIT_GSO_V4 | XMIT_GSO_V6) - +#define XMIT_PLAIN 0 +#define XMIT_CSUM_V4 (1 << 0) +#define XMIT_CSUM_V6 (1 << 1) +#define XMIT_CSUM_TCP (1 << 2) +#define XMIT_GSO_V4 (1 << 3) +#define XMIT_GSO_V6 (1 << 4) +#define XMIT_CSUM_ENC_V4 (1 << 5) +#define XMIT_CSUM_ENC_V6 (1 << 6) +#define XMIT_GSO_ENC_V4 (1 << 7) +#define XMIT_GSO_ENC_V6 (1 << 8) + +#define XMIT_CSUM_ENC (XMIT_CSUM_ENC_V4 | XMIT_CSUM_ENC_V6) +#define XMIT_GSO_ENC (XMIT_GSO_ENC_V4 | XMIT_GSO_ENC_V6) + +#define XMIT_CSUM (XMIT_CSUM_V4 | XMIT_CSUM_V6 | XMIT_CSUM_ENC) +#define XMIT_GSO (XMIT_GSO_V4 | XMIT_GSO_V6 | XMIT_GSO_ENC) /* stuff added to make the code fit 80Col */ #define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9f7a3793590b..8091de70a539 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3148,27 +3148,44 @@ static __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) { u32 rc; + __u8 prot = 0; + __be16 protocol; if (skb->ip_summed != CHECKSUM_PARTIAL) - rc = XMIT_PLAIN; + return XMIT_PLAIN; - else { - if (vlan_get_protocol(skb) == htons(ETH_P_IPV6)) { - rc = XMIT_CSUM_V6; - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - rc |= XMIT_CSUM_TCP; + protocol = vlan_get_protocol(skb); + if (protocol == htons(ETH_P_IPV6)) { + rc = XMIT_CSUM_V6; + prot = ipv6_hdr(skb)->nexthdr; + } else { + rc = XMIT_CSUM_V4; + prot = ip_hdr(skb)->protocol; + } + if (!CHIP_IS_E1x(bp) && skb->encapsulation) { + if (inner_ip_hdr(skb)->version == 6) { + rc |= XMIT_CSUM_ENC_V6; + if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + rc |= XMIT_CSUM_TCP; } else { - rc = XMIT_CSUM_V4; - if (ip_hdr(skb)->protocol == IPPROTO_TCP) + rc |= XMIT_CSUM_ENC_V4; + if (inner_ip_hdr(skb)->protocol == IPPROTO_TCP) rc |= XMIT_CSUM_TCP; } } + if (prot == IPPROTO_TCP) + rc |= XMIT_CSUM_TCP; - if (skb_is_gso_v6(skb)) - rc |= XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6; - else if (skb_is_gso(skb)) - rc |= XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP; + if (skb_is_gso_v6(skb)) { + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V6; + } else if (skb_is_gso(skb)) { + rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); + if (rc & XMIT_CSUM_ENC) + rc |= XMIT_GSO_ENC_V4; + } return rc; } @@ -3256,11 +3273,20 @@ exit_lbl: static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, u32 xmit_type) { + struct ipv6hdr *ipv6; + *parsing_data |= (skb_shinfo(skb)->gso_size << ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & ETH_TX_PARSE_BD_E2_LSO_MSS; - if ((xmit_type & XMIT_GSO_V6) && - (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) + + if (xmit_type & XMIT_GSO_ENC_V6) + ipv6 = inner_ipv6_hdr(skb); + else if (xmit_type & XMIT_GSO_V6) + ipv6 = ipv6_hdr(skb); + else + ipv6 = NULL; + + if (ipv6 && ipv6->nexthdr == NEXTHDR_IPV6) *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; } @@ -3296,6 +3322,40 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb, cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN); } +/** + * bnx2x_set_pbd_csum_enc - update PBD with checksum and return header length + * + * @bp: driver handle + * @skb: packet skb + * @parsing_data: data to be updated + * @xmit_type: xmit flags + * + * 57712/578xx related, when skb has encapsulation + */ +static u8 bnx2x_set_pbd_csum_enc(struct bnx2x *bp, struct sk_buff *skb, + u32 *parsing_data, u32 xmit_type) +{ + *parsing_data |= + ((((u8 *)skb_inner_transport_header(skb) - skb->data) >> 1) << + ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W; + + if (xmit_type & XMIT_CSUM_TCP) { + *parsing_data |= ((inner_tcp_hdrlen(skb) / 4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; + + return skb_inner_transport_header(skb) + + inner_tcp_hdrlen(skb) - skb->data; + } + + /* We support checksum offload for TCP and UDP only. + * No need to pass the UDP header length - it's a constant. + */ + return skb_inner_transport_header(skb) + + sizeof(struct udphdr) - skb->data; +} + /** * bnx2x_set_pbd_csum_e2 - update PBD with checksum and return header length * @@ -3327,13 +3387,14 @@ static u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, return skb_transport_header(skb) + sizeof(struct udphdr) - skb->data; } +/* set FW indication according to inner or outer protocols if tunneled */ static void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, struct eth_tx_start_bd *tx_start_bd, u32 xmit_type) { tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - if (xmit_type & XMIT_CSUM_V6) + if (xmit_type & (XMIT_CSUM_ENC_V6 | XMIT_CSUM_V6)) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6; if (!(xmit_type & XMIT_CSUM_TCP)) @@ -3396,6 +3457,72 @@ static u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, return hlen; } +static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd_e2, + struct eth_tx_parse_2nd_bd *pbd2, + u16 *global_data, + u32 xmit_type) +{ + u16 inner_hlen_w = 0; + u8 outerip_off, outerip_len = 0; + + /* IP len */ + inner_hlen_w = (skb_inner_transport_header(skb) - + skb_inner_network_header(skb)) >> 1; + + /* transport len */ + if (xmit_type & XMIT_CSUM_TCP) + inner_hlen_w += inner_tcp_hdrlen(skb) >> 1; + else + inner_hlen_w += sizeof(struct udphdr) >> 1; + + pbd2->fw_ip_hdr_to_payload_w = inner_hlen_w; + + if (xmit_type & XMIT_CSUM_ENC_V4) { + struct iphdr *iph = inner_ip_hdr(skb); + + pbd2->fw_ip_csum_wo_len_flags_frag = + bswab16(csum_fold((~iph->check) - + iph->tot_len - iph->frag_off)); + } else { + pbd2->fw_ip_hdr_to_payload_w = + inner_hlen_w - ((sizeof(struct ipv6hdr)) >> 1); + } + + pbd2->tcp_send_seq = bswab32(inner_tcp_hdr(skb)->seq); + + pbd2->tcp_flags = pbd_tcp_flags(inner_tcp_hdr(skb)); + + if (xmit_type & XMIT_GSO_V4) { + pbd2->hw_ip_id = bswab16(ip_hdr(skb)->id); + + pbd_e2->data.tunnel_data.pseudo_csum = + bswab16(~csum_tcpudp_magic( + inner_ip_hdr(skb)->saddr, + inner_ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + outerip_len = ip_hdr(skb)->ihl << 1; + } else { + pbd_e2->data.tunnel_data.pseudo_csum = + bswab16(~csum_ipv6_magic( + &inner_ipv6_hdr(skb)->saddr, + &inner_ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + } + + outerip_off = (skb_network_header(skb) - skb->data) >> 1; + + *global_data |= + outerip_off | + (!!(xmit_type & XMIT_CSUM_V6) << + ETH_TX_PARSE_2ND_BD_IP_HDR_TYPE_OUTER_SHIFT) | + (outerip_len << + ETH_TX_PARSE_2ND_BD_IP_HDR_LEN_OUTER_W_SHIFT) | + ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << + ETH_TX_PARSE_2ND_BD_LLC_SNAP_EN_SHIFT); +} + /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -3411,6 +3538,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; + struct eth_tx_parse_2nd_bd *pbd2 = NULL; u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; int nbd, txq_index; @@ -3567,12 +3695,46 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!CHIP_IS_E1x(bp)) { pbd_e2 = &txdata->tx_desc_ring[bd_prod].parse_bd_e2; memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); - /* Set PBD in checksum offload case */ - if (xmit_type & XMIT_CSUM) + + if (xmit_type & XMIT_CSUM_ENC) { + u16 global_data = 0; + + /* Set PBD in enc checksum offload case */ + hlen = bnx2x_set_pbd_csum_enc(bp, skb, + &pbd_e2_parsing_data, + xmit_type); + + /* turn on 2nd parsing and get a BD */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + + pbd2 = &txdata->tx_desc_ring[bd_prod].parse_2nd_bd; + + memset(pbd2, 0, sizeof(*pbd2)); + + pbd_e2->data.tunnel_data.ip_hdr_start_inner_w = + (skb_inner_network_header(skb) - + skb->data) >> 1; + + if (xmit_type & XMIT_GSO_ENC) + bnx2x_update_pbds_gso_enc(skb, pbd_e2, pbd2, + &global_data, + xmit_type); + + pbd2->global_data = cpu_to_le16(global_data); + + /* add addition parse BD indication to start BD */ + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_PARSE_NBDS, 1); + /* set encapsulation flag in start BD */ + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_TUNNEL_EXIST, 1); + nbd++; + } else if (xmit_type & XMIT_CSUM) { /* Set PBD in checksum offload case w/o encapsulation */ hlen = bnx2x_set_pbd_csum_e2(bp, skb, &pbd_e2_parsing_data, xmit_type); + } /* Add the macs to the parsing BD this is a vf */ if (IS_VF(bp)) { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 04d123ff11a2..4902d1eb3d1e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11965,6 +11965,13 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_RXHASH | NETIF_F_HW_VLAN_TX; + if (!CHIP_IS_E1x(bp)) { + dev->hw_features |= NETIF_F_GSO_GRE; + dev->hw_enc_features = + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | + NETIF_F_GSO_GRE; + } dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA; -- cgit From 1bc277f79260ae6f0888b1234942b6aedfff1289 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 18 Mar 2013 06:51:04 +0000 Subject: bnx2x: add RSS capability for GRE traffic The patch drives FW to perform RSS for GRE traffic, based on inner headers. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 3 +++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 23 ++++++++++++----------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 9 +++++++++ 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 8f9637279f12..f9098d8fc25b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -973,6 +973,9 @@ static inline int bnx2x_func_start(struct bnx2x *bp) else /* CHIP_IS_E1X */ start_params->network_cos_mode = FW_WRR; + start_params->gre_tunnel_mode = IPGRE_TUNNEL; + start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; + return bnx2x_func_state_change(bp, &func_params); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 66ab25908086..5bdc1d6dcf89 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5679,17 +5679,18 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, memset(rdata, 0, sizeof(*rdata)); /* Fill the ramrod data with provided parameters */ - rdata->function_mode = (u8)start_params->mf_mode; - rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); - rdata->path_id = BP_PATH(bp); - rdata->network_cos_mode = start_params->network_cos_mode; - - /* - * No need for an explicit memory barrier here as long we would - * need to ensure the ordering of writing to the SPQ element - * and updating of the SPQ producer which involves a memory - * read and we will have to put a full memory barrier there - * (inside bnx2x_sp_post()). + rdata->function_mode = (u8)start_params->mf_mode; + rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); + rdata->path_id = BP_PATH(bp); + rdata->network_cos_mode = start_params->network_cos_mode; + rdata->gre_tunnel_mode = start_params->gre_tunnel_mode; + rdata->gre_tunnel_rss = start_params->gre_tunnel_rss; + + /* No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). */ return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 064dba24610d..35479da11f84 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -1123,6 +1123,15 @@ struct bnx2x_func_start_params { /* Function cos mode */ u8 network_cos_mode; + + /* NVGRE classification enablement */ + u8 nvgre_clss_en; + + /* NO_GRE_TUNNEL/NVGRE_TUNNEL/L2GRE_TUNNEL/IPGRE_TUNNEL */ + u8 gre_tunnel_mode; + + /* GRE_OUTER_HEADERS_RSS/GRE_INNER_HEADERS_RSS/NVGRE_KEY_ENTROPY_RSS */ + u8 gre_tunnel_rss; }; struct bnx2x_func_switch_update_params { -- cgit From 39ecc01d1bbe3de2cf5f01a81e176ea5160d3b95 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Feb 2013 12:11:00 +0100 Subject: mac80211: pass queue bitmap to flush operation There are a number of situations in which mac80211 only really needs to flush queues for one virtual interface, and in fact during this frames might be transmitted on other virtual interfaces. Calculate and pass a queue bitmap to the driver so it knows which queues to flush. Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ar5523/ar5523.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 2 +- drivers/net/wireless/ath/carl9170/main.c | 2 +- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 2 +- drivers/net/wireless/iwlegacy/common.c | 3 +-- drivers/net/wireless/iwlegacy/common.h | 2 +- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/mac80211_hwsim.c | 2 +- drivers/net/wireless/p54/main.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- drivers/net/wireless/rtlwifi/core.c | 2 +- drivers/net/wireless/ti/wlcore/main.c | 2 +- include/net/mac80211.h | 9 +++++--- net/mac80211/driver-ops.h | 7 +++--- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 2 +- net/mac80211/mlme.c | 8 +++---- net/mac80211/offchannel.c | 4 ++-- net/mac80211/pm.c | 2 +- net/mac80211/scan.c | 4 ++-- net/mac80211/trace.h | 11 ++++++---- net/mac80211/util.c | 25 ++++++++++++++++++++++ 23 files changed, 67 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 7157f7d311c5..afd1e36d308f 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1091,7 +1091,7 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) return ret; } -static void ar5523_flush(struct ieee80211_hw *hw, bool drop) +static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct ar5523 *ar = hw->priv; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6e66f9c6782b..24650fd41694 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1745,7 +1745,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_unlock(&sc->mutex); } -static void ath9k_flush(struct ieee80211_hw *hw, bool drop) +static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index f293b3ff4756..08b193199946 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1703,7 +1703,7 @@ found: return 0; } -static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) +static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct ar9170 *ar = hw->priv; unsigned int vid; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c6451c61407a..aa5f43fee5ed 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -723,7 +723,7 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl) return result; } -static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) +static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct brcms_info *wl = hw->priv; int ret; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index e006ea831320..722bfb57cfd5 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4704,8 +4704,7 @@ out: } EXPORT_SYMBOL(il_mac_change_interface); -void -il_mac_flush(struct ieee80211_hw *hw, bool drop) +void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct il_priv *il = hw->priv; unsigned long timeout = jiffies + msecs_to_jiffies(500); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 73bd3ef316c8..728aa1306ab8 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1720,7 +1720,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); -void il_mac_flush(struct ieee80211_hw *hw, bool drop); +void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); int il_alloc_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il); diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c7cd2dffa5cd..a7294fa4d7e5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1100,7 +1100,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } -static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) +static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7490c4fc7177..3466f1a8a8d3 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1389,7 +1389,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, return 0; } -static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) +static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { /* Not implemented, queues only on kernel side */ } diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index aadda99989c0..ee654a691f38 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -670,7 +670,7 @@ static unsigned int p54_flush_count(struct p54_common *priv) return total; } -static void p54_flush(struct ieee80211_hw *dev, bool drop) +static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop) { struct p54_common *priv = dev->priv; unsigned int total, i; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 086abb403a4f..041b392f4f47 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1360,7 +1360,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); -void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); +void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 20c6eccce5aa..9161c02d8ff9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -748,7 +748,7 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); -void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) +void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct rt2x00_dev *rt2x00dev = hw->priv; struct data_queue *queue; diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d3ce9fbef00e..b5a7a260bf63 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1166,7 +1166,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) * before switch channle or power save, or tx buffer packet * maybe send after offchannel or rf sleep, this may cause * dis-association by AP */ -static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) +static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index d7e306333f6c..a9f7041c7192 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4946,7 +4946,7 @@ out: mutex_unlock(&wl->mutex); } -static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop) +static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) { struct wl1271 *wl = hw->priv; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0b912d22f82d..4158da74e11b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2438,8 +2438,11 @@ enum ieee80211_roc_type { * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. * * @flush: Flush all pending frames from the hardware queue, making sure - * that the hardware queues are empty. If the parameter @drop is set - * to %true, pending frames may be dropped. The callback can sleep. + * that the hardware queues are empty. The @queues parameter is a bitmap + * of queues to flush, which is useful if different virtual interfaces + * use different hardware queues; it may also indicate all queues. + * If the parameter @drop is set to %true, pending frames may be dropped. + * The callback can sleep. * * @channel_switch: Drivers that need (or want) to offload the channel * switch operation for CSAs received from the AP may implement this @@ -2687,7 +2690,7 @@ struct ieee80211_ops { struct netlink_callback *cb, void *data, int len); #endif - void (*flush)(struct ieee80211_hw *hw, bool drop); + void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch); int (*napi_poll)(struct ieee80211_hw *hw, int budget); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 7b9ff53bd2e9..169664c122e2 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -720,13 +720,14 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local) local->ops->rfkill_poll(&local->hw); } -static inline void drv_flush(struct ieee80211_local *local, bool drop) +static inline void drv_flush(struct ieee80211_local *local, + u32 queues, bool drop) { might_sleep(); - trace_drv_flush(local, drop); + trace_drv_flush(local, queues, drop); if (local->ops->flush) - local->ops->flush(&local->hw, drop); + local->ops->flush(&local->hw, queues, drop); trace_drv_return_void(local); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d6e920609823..b96c0e977752 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1540,6 +1540,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, { ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); } +void ieee80211_flush_queues(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, u16 status, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 80e838bc875d..d646e12e55a6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -92,7 +92,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) if (local->hw.conf.flags & IEEE80211_CONF_IDLE) return 0; - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); local->hw.conf.flags |= IEEE80211_CONF_IDLE; return IEEE80211_CONF_CHANGE_IDLE; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fdc06e381c10..65b38e13eb0c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1436,7 +1436,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) else { ieee80211_send_nullfunc(local, sdata, 1); /* Flush to get the tx status of nullfunc frame */ - drv_flush(local, false); + ieee80211_flush_queues(local, sdata); } } @@ -1767,7 +1767,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ if (tx) - drv_flush(local, false); + ieee80211_flush_queues(local, sdata); /* deauthenticate/disassociate now */ if (tx || frame_buf) @@ -1776,7 +1776,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, /* flush out frame */ if (tx) - drv_flush(local, false); + ieee80211_flush_queues(local, sdata); /* clear bssid only after building the needed mgmt frames */ memset(ifmgd->bssid, 0, ETH_ALEN); @@ -1948,7 +1948,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); run_again(ifmgd, ifmgd->probe_timeout); if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) - drv_flush(sdata->local, false); + ieee80211_flush_queues(sdata->local, sdata); } static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index db547fceaeb9..d32f514074b9 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -120,7 +120,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) */ ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); mutex_lock(&local->iflist_mtx); list_for_each_entry(sdata, &local->interfaces, list) { @@ -373,7 +373,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) ieee80211_roc_notify_destroy(roc); if (started) { - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); local->tmp_channel = NULL; ieee80211_hw_config(local, 0); diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index b471a67f224d..497f21a0d116 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -35,7 +35,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* flush out all packets */ synchronize_net(); - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); local->quiescing = true; /* make quiescing visible to timers everywhere */ diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5dc17c623f72..cb34cbbaa20c 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -332,7 +332,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) ieee80211_offchannel_stop_vifs(local); /* ensure nullfunc is transmitted before leaving operating channel */ - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); ieee80211_configure_filter(local); @@ -668,7 +668,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local, ieee80211_offchannel_stop_vifs(local); if (local->ops->flush) { - drv_flush(local, false); + ieee80211_flush_queues(local, NULL); *next_delay = 0; } else *next_delay = HZ / 10; diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index d97e4305cf1e..c5899797a8d4 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -964,23 +964,26 @@ TRACE_EVENT(drv_get_survey, ); TRACE_EVENT(drv_flush, - TP_PROTO(struct ieee80211_local *local, bool drop), + TP_PROTO(struct ieee80211_local *local, + u32 queues, bool drop), - TP_ARGS(local, drop), + TP_ARGS(local, queues, drop), TP_STRUCT__entry( LOCAL_ENTRY __field(bool, drop) + __field(u32, queues) ), TP_fast_assign( LOCAL_ASSIGN; __entry->drop = drop; + __entry->queues = queues; ), TP_printk( - LOCAL_PR_FMT " drop:%d", - LOCAL_PR_ARG, __entry->drop + LOCAL_PR_FMT " queues:0x%x drop:%d", + LOCAL_PR_ARG, __entry->queues, __entry->drop ) ); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b7a856e3281b..f978ddd1bb43 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -511,6 +511,31 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw) } EXPORT_SYMBOL(ieee80211_wake_queues); +void ieee80211_flush_queues(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + u32 queues; + + if (!local->ops->flush) + return; + + if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { + int ac; + + queues = 0; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + queues |= BIT(sdata->vif.hw_queue[ac]); + if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE) + queues |= BIT(sdata->vif.cab_queue); + } else { + /* all queues */ + queues = BIT(local->hw.queues) - 1; + } + + drv_flush(local, queues, false); +} + void ieee80211_iterate_active_interfaces( struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, -- cgit From 06f950f43f29eb0b5631c6d037d78319649ac3b0 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Sun, 24 Feb 2013 18:47:18 -0300 Subject: [media] lmedm04: Fix possible NULL pointer dereference Check for (adap == NULL) has to done before accessing adap. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index f30c58cecbba..96804be0fffe 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -1241,10 +1241,13 @@ static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, struct usb_data_stream_properties *stream) { struct dvb_usb_adapter *adap = fe_to_adap(fe); - struct dvb_usb_device *d = adap_to_d(adap); + struct dvb_usb_device *d; if (adap == NULL) return 0; + + d = adap_to_d(adap); + /* Turn PID filter on the fly by module option */ if (pid_filter == 2) { adap->pid_filtering = 1; -- cgit From 972b072a83316e0d5a1fd0cb78eb99a57a305dce Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Sun, 24 Feb 2013 18:49:43 -0300 Subject: [media] hdpvr: Fix memory leak This patch fixes the print_buf leaking. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/hdpvr/hdpvr-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 5c6193536399..73195fe7871c 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -196,6 +196,7 @@ static int device_authorization(struct hdpvr_device *dev) hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", print_buf); + kfree(print_buf); #endif msleep(100); -- cgit From acb0549acc270c8206ecfdd35d34fc349c3457a0 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 13:01:48 -0300 Subject: [media] dvb_usb_v2: locked versions of USB bulk IO functions Implement: dvb_usbv2_generic_rw_locked() dvb_usbv2_generic_write_locked() Caller must hold device lock when locked versions are called. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 4 ++++ drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c | 38 ++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 3cac8bd0b116..42801f8ecaa8 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -400,5 +400,9 @@ extern int dvb_usbv2_reset_resume(struct usb_interface *); /* the generic read/write method for device control */ extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16); extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16); +/* caller must hold lock when locked versions are called */ +extern int dvb_usbv2_generic_rw_locked(struct dvb_usb_device *, + u8 *, u16, u8 *, u16); +extern int dvb_usbv2_generic_write_locked(struct dvb_usb_device *, u8 *, u16); #endif diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c index 5716662b4834..74c911fa1fe6 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c @@ -21,8 +21,8 @@ #include "dvb_usb_common.h" -int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, - u16 rlen) +int dvb_usb_v2_generic_io(struct dvb_usb_device *d, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { int ret, actual_length; @@ -32,8 +32,6 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, return -EINVAL; } - mutex_lock(&d->usb_mutex); - dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf); ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, @@ -63,13 +61,43 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, actual_length, rbuf); } + return ret; +} + +int dvb_usbv2_generic_rw(struct dvb_usb_device *d, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + int ret; + + mutex_lock(&d->usb_mutex); + ret = dvb_usb_v2_generic_io(d, wbuf, wlen, rbuf, rlen); mutex_unlock(&d->usb_mutex); + return ret; } EXPORT_SYMBOL(dvb_usbv2_generic_rw); int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) { - return dvb_usbv2_generic_rw(d, buf, len, NULL, 0); + int ret; + + mutex_lock(&d->usb_mutex); + ret = dvb_usb_v2_generic_io(d, buf, len, NULL, 0); + mutex_unlock(&d->usb_mutex); + + return ret; } EXPORT_SYMBOL(dvb_usbv2_generic_write); + +int dvb_usbv2_generic_rw_locked(struct dvb_usb_device *d, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + return dvb_usb_v2_generic_io(d, wbuf, wlen, rbuf, rlen); +} +EXPORT_SYMBOL(dvb_usbv2_generic_rw_locked); + +int dvb_usbv2_generic_write_locked(struct dvb_usb_device *d, u8 *buf, u16 len) +{ + return dvb_usb_v2_generic_io(d, buf, len, NULL, 0); +} +EXPORT_SYMBOL(dvb_usbv2_generic_write_locked); -- cgit From aff8c2d475cb660ee246099dd15f269e9ebb7b1d Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 13:25:19 -0300 Subject: [media] af9015: do not use buffers from stack for usb_bulk_msg() WARNING: at lib/dma-debug.c:947 check_for_stack+0xa7/0xf0() ehci-pci 0000:00:04.1: DMA-API: device driver maps memory fromstack Reported-by: poma Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9015.c | 39 +++++++++++++++++++---------------- drivers/media/usb/dvb-usb-v2/af9015.h | 2 ++ 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index b86d0f27a398..2fa7c6ee5a70 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -30,22 +30,22 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) { -#define BUF_LEN 63 #define REQ_HDR_LEN 8 /* send header size */ #define ACK_HDR_LEN 2 /* rece header size */ struct af9015_state *state = d_to_priv(d); int ret, wlen, rlen; - u8 buf[BUF_LEN]; u8 write = 1; - buf[0] = req->cmd; - buf[1] = state->seq++; - buf[2] = req->i2c_addr; - buf[3] = req->addr >> 8; - buf[4] = req->addr & 0xff; - buf[5] = req->mbox; - buf[6] = req->addr_len; - buf[7] = req->data_len; + mutex_lock(&d->usb_mutex); + + state->buf[0] = req->cmd; + state->buf[1] = state->seq++; + state->buf[2] = req->i2c_addr; + state->buf[3] = req->addr >> 8; + state->buf[4] = req->addr & 0xff; + state->buf[5] = req->mbox; + state->buf[6] = req->addr_len; + state->buf[7] = req->data_len; switch (req->cmd) { case GET_CONFIG: @@ -55,14 +55,14 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) break; case READ_I2C: write = 0; - buf[2] |= 0x01; /* set I2C direction */ + state->buf[2] |= 0x01; /* set I2C direction */ case WRITE_I2C: - buf[0] = READ_WRITE_I2C; + state->buf[0] = READ_WRITE_I2C; break; case WRITE_MEMORY: if (((req->addr & 0xff00) == 0xff00) || ((req->addr & 0xff00) == 0xae00)) - buf[0] = WRITE_VIRTUAL_MEMORY; + state->buf[0] = WRITE_VIRTUAL_MEMORY; case WRITE_VIRTUAL_MEMORY: case COPY_FIRMWARE: case DOWNLOAD_FIRMWARE: @@ -90,7 +90,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) rlen = ACK_HDR_LEN; if (write) { wlen += req->data_len; - memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len); + memcpy(&state->buf[REQ_HDR_LEN], req->data, req->data_len); } else { rlen += req->data_len; } @@ -99,22 +99,25 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) rlen = 0; - ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen); + ret = dvb_usbv2_generic_rw_locked(d, + state->buf, wlen, state->buf, rlen); if (ret) goto error; /* check status */ - if (rlen && buf[1]) { + if (rlen && state->buf[1]) { dev_err(&d->udev->dev, "%s: command failed=%d\n", - KBUILD_MODNAME, buf[1]); + KBUILD_MODNAME, state->buf[1]); ret = -EIO; goto error; } /* read request, copy returned data to return buf */ if (!write) - memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len); + memcpy(req->data, &state->buf[ACK_HDR_LEN], req->data_len); error: + mutex_unlock(&d->usb_mutex); + return ret; } diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h index 533637dedd23..3a6f3ad1eadb 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.h +++ b/drivers/media/usb/dvb-usb-v2/af9015.h @@ -115,7 +115,9 @@ enum af9015_ir_mode { AF9015_IR_MODE_POLLING, /* just guess */ }; +#define BUF_LEN 63 struct af9015_state { + u8 buf[BUF_LEN]; /* bulk USB control message */ u8 ir_mode; u8 rc_repeat; u32 rc_keycode; -- cgit From 3484d37a66bb45dc9b4f70868b68739262bf6832 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 13:56:34 -0300 Subject: [media] af9035: do not use buffers from stack for usb_bulk_msg() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 44 +++++++++++++++++------------------ drivers/media/usb/dvb-usb-v2/af9035.h | 2 ++ 2 files changed, 24 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index d3cb8d55febc..66f65197c40d 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -41,43 +41,45 @@ static u16 af9035_checksum(const u8 *buf, size_t len) static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) { -#define BUF_LEN 64 #define REQ_HDR_LEN 4 /* send header size */ #define ACK_HDR_LEN 3 /* rece header size */ #define CHECKSUM_LEN 2 #define USB_TIMEOUT 2000 struct state *state = d_to_priv(d); int ret, wlen, rlen; - u8 buf[BUF_LEN]; u16 checksum, tmp_checksum; + mutex_lock(&d->usb_mutex); + /* buffer overflow check */ if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) || req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) { dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n", __func__, req->wlen, req->rlen); - return -EINVAL; + ret = -EINVAL; + goto err; } - buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1; - buf[1] = req->mbox; - buf[2] = req->cmd; - buf[3] = state->seq++; - memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen); + state->buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1; + state->buf[1] = req->mbox; + state->buf[2] = req->cmd; + state->buf[3] = state->seq++; + memcpy(&state->buf[REQ_HDR_LEN], req->wbuf, req->wlen); wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN; rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN; /* calc and add checksum */ - checksum = af9035_checksum(buf, buf[0] - 1); - buf[buf[0] - 1] = (checksum >> 8); - buf[buf[0] - 0] = (checksum & 0xff); + checksum = af9035_checksum(state->buf, state->buf[0] - 1); + state->buf[state->buf[0] - 1] = (checksum >> 8); + state->buf[state->buf[0] - 0] = (checksum & 0xff); /* no ack for these packets */ if (req->cmd == CMD_FW_DL) rlen = 0; - ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen); + ret = dvb_usbv2_generic_rw_locked(d, + state->buf, wlen, state->buf, rlen); if (ret) goto err; @@ -86,8 +88,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) goto exit; /* verify checksum */ - checksum = af9035_checksum(buf, rlen - 2); - tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1]; + checksum = af9035_checksum(state->buf, rlen - 2); + tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1]; if (tmp_checksum != checksum) { dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \ "(%04x != %04x)\n", KBUILD_MODNAME, req->cmd, @@ -97,23 +99,21 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req) } /* check status */ - if (buf[2]) { + if (state->buf[2]) { dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n", - __func__, req->cmd, buf[2]); + __func__, req->cmd, state->buf[2]); ret = -EIO; goto err; } /* read request, copy returned data to return buf */ if (req->rlen) - memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen); - + memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen); exit: - return 0; - err: - dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); - + mutex_unlock(&d->usb_mutex); + if (ret) + dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; } diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index 29f3eec22c2c..6d098a93d5ab 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -52,6 +52,8 @@ struct usb_req { }; struct state { +#define BUF_LEN 64 + u8 buf[BUF_LEN]; u8 seq; /* packet sequence number */ bool dual_mode; struct af9033_config af9033_config[2]; -- cgit From 6c604e8e8611385d48cd9dea8926b2a309ed85c0 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 14:13:41 -0300 Subject: [media] anysee: do not use buffers from stack for usb_bulk_msg() Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/anysee.c | 27 ++++++++++++--------------- drivers/media/usb/dvb-usb-v2/anysee.h | 3 ++- 2 files changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index a20d691d0b63..85ba24650f01 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -45,25 +45,24 @@ #include "cxd2820r.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static DEFINE_MUTEX(anysee_usb_mutex); static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) { struct anysee_state *state = d_to_priv(d); int act_len, ret, i; - u8 buf[64]; - memcpy(&buf[0], sbuf, slen); - buf[60] = state->seq++; + mutex_lock(&d->usb_mutex); - mutex_lock(&anysee_usb_mutex); + memcpy(&state->buf[0], sbuf, slen); + state->buf[60] = state->seq++; - dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, slen, buf); + dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, slen, state->buf); /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ - ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf)); + ret = dvb_usbv2_generic_rw_locked(d, state->buf, sizeof(state->buf), + state->buf, sizeof(state->buf)); if (ret) goto error_unlock; @@ -82,17 +81,16 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, for (i = 0; i < 3; i++) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, - d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf), - &act_len, 2000); - + d->props->generic_bulk_ctrl_endpoint), + state->buf, sizeof(state->buf), &act_len, 2000); if (ret) { dev_dbg(&d->udev->dev, "%s: recv bulk message " \ "failed=%d\n", __func__, ret); } else { dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__, - rlen, buf); + rlen, state->buf); - if (buf[63] != 0x4f) + if (state->buf[63] != 0x4f) dev_dbg(&d->udev->dev, "%s: cmd failed\n", __func__); @@ -109,11 +107,10 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, /* read request, copy returned data to return buf */ if (rbuf && rlen) - memcpy(rbuf, buf, rlen); + memcpy(rbuf, state->buf, rlen); error_unlock: - mutex_unlock(&anysee_usb_mutex); - + mutex_unlock(&d->usb_mutex); return ret; } diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h index c1a4273f14ff..8f426d9fc6e1 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.h +++ b/drivers/media/usb/dvb-usb-v2/anysee.h @@ -52,8 +52,9 @@ enum cmd { }; struct anysee_state { - u8 hw; /* PCB ID */ + u8 buf[64]; u8 seq; + u8 hw; /* PCB ID */ u8 fe_id:1; /* frondend ID */ u8 has_ci:1; u8 ci_attached:1; -- cgit From 4458a54c5edce2a9bdf826273ceb7f4b3b7278c6 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 26 Feb 2013 14:18:13 -0300 Subject: [media] anysee: coding style changes I did what I liked to do. Also corrected two long log writings as checkpatch.pl was complaining about those. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/anysee.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index 85ba24650f01..2e762742a4c7 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -46,8 +46,8 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, - u8 *rbuf, u8 rlen) +static int anysee_ctrl_msg(struct dvb_usb_device *d, + u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) { struct anysee_state *state = d_to_priv(d); int act_len, ret, i; @@ -84,16 +84,16 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, d->props->generic_bulk_ctrl_endpoint), state->buf, sizeof(state->buf), &act_len, 2000); if (ret) { - dev_dbg(&d->udev->dev, "%s: recv bulk message " \ - "failed=%d\n", __func__, ret); + dev_dbg(&d->udev->dev, + "%s: recv bulk message failed=%d\n", + __func__, ret); } else { dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__, rlen, state->buf); if (state->buf[63] != 0x4f) - dev_dbg(&d->udev->dev, "%s: cmd failed\n", - __func__); - + dev_dbg(&d->udev->dev, + "%s: cmd failed\n", __func__); break; } } @@ -881,9 +881,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (!adap->fe[0]) { /* we have no frontend :-( */ ret = -ENODEV; - dev_err(&d->udev->dev, "%s: Unsupported Anysee version. " \ - "Please report the " \ - ".\n", + dev_err(&d->udev->dev, + "%s: Unsupported Anysee version. Please report the .\n", KBUILD_MODNAME); } error: -- cgit From bf30690029a3b8572a6fc2facb77fbde86992988 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 26 Feb 2013 03:17:27 -0300 Subject: [media] Media: remove incorrect __init/__exit markups Even if bus is not hot-pluggable, the devices can be unbound from the driver via sysfs, so we should not be using __exit annotations on remove() methods. The only exception is drivers registered with platform_driver_probe() which specifically disables sysfs bind/unbind attributes. Similarly probe() methods should not be marked __init unless platform_driver_probe() is used. Signed-off-by: Dmitry Torokhov Acked-by: Guennadi Liakhovetski Acked-by: Sakari Ailus Acked-by: Timo Kokkonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adp1653.c | 4 ++-- drivers/media/i2c/smiapp/smiapp-core.c | 4 ++-- drivers/media/platform/soc_camera/omap1_camera.c | 6 +++--- drivers/media/radio/radio-si4713.c | 4 ++-- drivers/media/rc/ir-rx51.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index df163800c8e1..ef75abe5984c 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -447,7 +447,7 @@ free_and_quit: return ret; } -static int __exit adp1653_remove(struct i2c_client *client) +static int adp1653_remove(struct i2c_client *client) { struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct adp1653_flash *flash = to_adp1653_flash(subdev); @@ -476,7 +476,7 @@ static struct i2c_driver adp1653_i2c_driver = { .pm = &adp1653_pm_ops, }, .probe = adp1653_probe, - .remove = __exit_p(adp1653_remove), + .remove = adp1653_remove, .id_table = adp1653_id_table, }; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 83c7ed7ffcc2..cae4f4683851 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2833,7 +2833,7 @@ static int smiapp_probe(struct i2c_client *client, sensor->src->pads, 0); } -static int __exit smiapp_remove(struct i2c_client *client) +static int smiapp_remove(struct i2c_client *client) { struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); @@ -2881,7 +2881,7 @@ static struct i2c_driver smiapp_i2c_driver = { .pm = &smiapp_pm_ops, }, .probe = smiapp_probe, - .remove = __exit_p(smiapp_remove), + .remove = smiapp_remove, .id_table = smiapp_id_table, }; diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 2547bf88f79f..9689a6e89b7f 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1546,7 +1546,7 @@ static struct soc_camera_host_ops omap1_host_ops = { .poll = omap1_cam_poll, }; -static int __init omap1_cam_probe(struct platform_device *pdev) +static int omap1_cam_probe(struct platform_device *pdev) { struct omap1_cam_dev *pcdev; struct resource *res; @@ -1677,7 +1677,7 @@ exit: return err; } -static int __exit omap1_cam_remove(struct platform_device *pdev) +static int omap1_cam_remove(struct platform_device *pdev) { struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); struct omap1_cam_dev *pcdev = container_of(soc_host, @@ -1709,7 +1709,7 @@ static struct platform_driver omap1_cam_driver = { .name = DRIVER_NAME, }, .probe = omap1_cam_probe, - .remove = __exit_p(omap1_cam_remove), + .remove = omap1_cam_remove, }; module_platform_driver(omap1_cam_driver); diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 1507c9d508d7..8ae8442d6f97 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -328,7 +328,7 @@ exit: } /* radio_si4713_pdriver_remove - remove the device */ -static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev) +static int radio_si4713_pdriver_remove(struct platform_device *pdev) { struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); struct radio_si4713_device *rsdev = container_of(v4l2_dev, @@ -350,7 +350,7 @@ static struct platform_driver radio_si4713_pdriver = { .name = "radio-si4713", }, .probe = radio_si4713_pdriver_probe, - .remove = __exit_p(radio_si4713_pdriver_remove), + .remove = radio_si4713_pdriver_remove, }; module_platform_driver(radio_si4713_pdriver); diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c index 8ead492d03aa..31b955bf7664 100644 --- a/drivers/media/rc/ir-rx51.c +++ b/drivers/media/rc/ir-rx51.c @@ -464,14 +464,14 @@ static int lirc_rx51_probe(struct platform_device *dev) return 0; } -static int __exit lirc_rx51_remove(struct platform_device *dev) +static int lirc_rx51_remove(struct platform_device *dev) { return lirc_unregister_driver(lirc_rx51_driver.minor); } struct platform_driver lirc_rx51_platform_driver = { .probe = lirc_rx51_probe, - .remove = __exit_p(lirc_rx51_remove), + .remove = lirc_rx51_remove, .suspend = lirc_rx51_suspend, .resume = lirc_rx51_resume, .driver = { -- cgit From 2da8eab97544266020a8cddb2936237abbb93859 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Tue, 26 Feb 2013 15:24:56 -0300 Subject: [media] siano: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 1842e64e6338..9565dcc8381f 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -719,8 +719,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); - if (coredev->fw_buf != NULL) - kfree(coredev->fw_buf); + kfree(coredev->fw_buf); list_del(&coredev->entry); kfree(coredev); -- cgit From 18552ea1322e218b43f7692d9358c930a6d81df1 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Tue, 26 Feb 2013 15:28:15 -0300 Subject: [media] media: ivtv: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtvfb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 05b94aa8ba32..9ff1230192e8 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1171,8 +1171,7 @@ static void ivtvfb_release_buffers (struct ivtv *itv) fb_dealloc_cmap(&oi->ivtvfb_info.cmap); /* Release pseudo palette */ - if (oi->ivtvfb_info.pseudo_palette) - kfree(oi->ivtvfb_info.pseudo_palette); + kfree(oi->ivtvfb_info.pseudo_palette); #ifdef CONFIG_MTRR if (oi->fb_end_aligned_physaddr) { -- cgit From f1065c964869aecd5af04291476c358fd5ab9a8f Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Tue, 26 Feb 2013 15:30:45 -0300 Subject: [media] media: tuners: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tuner-xc2028.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 09451737c77e..878d2c4d9e8e 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1378,8 +1378,7 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) * For the firmware name, keep a local copy of the string, * in order to avoid troubles during device release. */ - if (priv->ctrl.fname) - kfree(priv->ctrl.fname); + kfree(priv->ctrl.fname); memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); if (p->fname) { priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); -- cgit From 33cef283af68522dc0f0b398662885193048c7d0 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Tue, 26 Feb 2013 15:35:01 -0300 Subject: [media] dvb-usb: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cinergyT2-fe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c index 1efc028a76c9..c890fe46acd3 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c @@ -300,8 +300,7 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) static void cinergyt2_fe_release(struct dvb_frontend *fe) { struct cinergyt2_fe_state *state = fe->demodulator_priv; - if (state != NULL) - kfree(state); + kfree(state); } static struct dvb_frontend_ops cinergyt2_fe_ops; -- cgit From a2262508cba04587dbb0793ddf23be57f86dc583 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 28 Feb 2013 03:08:02 -0300 Subject: [media] drivers/staging/media/as102: using ccflags-y instead of EXTRA_FLAGS in Makefile need using ccflags-y instead of EXTRA_CFLAGS can reference scripts/checkpatch.pl (1755..1766) when make EXTRA_CFLAGS=-W, the compiling issue will be occured. Signed-off-by: Chen Gang Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/as102/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile index d8dfb757f1e2..8916d8a909bc 100644 --- a/drivers/staging/media/as102/Makefile +++ b/drivers/staging/media/as102/Makefile @@ -3,4 +3,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \ obj-$(CONFIG_DVB_AS102) += dvb-as102.o -EXTRA_CFLAGS += -Idrivers/media/dvb-core +ccflags-y += -Idrivers/media/dvb-core -- cgit From 3ead1ba31b24cb521a7256e19e6243f951f46ec8 Mon Sep 17 00:00:00 2001 From: Matt Gomboc Date: Fri, 1 Mar 2013 19:53:30 -0300 Subject: [media] cx231xx : Add support for OTG102 aka EZGrabber2 Thanks for the response, I have done as you suggested. Below is an updated patch for the OTG102 device against http://git.linuxtv.org/hverkuil/media_tree.git/shortlog/refs/heads/cx231xx, kernel version 3.8. With further testing it appears the extra clauses in cx231xx-cards.c were not necessary (in static in cx231xx_init_dev and static int cx231xx_usb_probe), so those have been also been removed. Signed-off-by: Matt Gomboc Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 2 ++ drivers/media/usb/cx231xx/cx231xx-cards.c | 35 ++++++++++++++++++++++++++++++ drivers/media/usb/cx231xx/cx231xx.h | 1 + 3 files changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 2e51fb9fd21c..235ba657d52e 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -357,6 +357,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: + case CX231XX_BOARD_OTG102: if (avmode == POLARIS_AVMODE_ANALOGT_TV) { while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | FLD_PWRDN_ENABLE_PLL)) { @@ -1720,6 +1721,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) case CX231XX_BOARD_CNXT_RDU_250: case CX231XX_BOARD_CNXT_VIDEO_GRABBER: case CX231XX_BOARD_HAUPPAUGE_EXETER: + case CX231XX_BOARD_OTG102: func_mode = 0x03; break; case CX231XX_BOARD_CNXT_RDE_253S: diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index b7b1acd7e7b0..13249e5a7891 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -634,6 +634,39 @@ struct cx231xx_board cx231xx_boards[] = { .gpio = NULL, } }, }, + [CX231XX_BOARD_OTG102] = { + .name = "Geniatech OTG102", + .tuner_type = TUNER_ABSENT, + .decoder = CX231XX_AVDECODER, + .output_mode = OUT_MODE_VIP11, + .ctl_pin_status_mask = 0xFFFFFFC4, + .agc_analog_digital_select_gpio = 0x0c, + /* According with PV CxPlrCAP.inf file */ + .gpio_pin_status_mask = 0x4001000, + .norm = V4L2_STD_NTSC, + .no_alt_vanc = 1, + .external_av = 1, + .dont_use_port_3 = 1, + /*.has_417 = 1, */ + /* This board is believed to have a hardware encoding chip + * supporting mpeg1/2/4, but as the 417 is apparently not + * working for the reference board it is not here either. */ + + .input = {{ + .type = CX231XX_VMUX_COMPOSITE1, + .vmux = CX231XX_VIN_2_1, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_SVIDEO, + .vmux = CX231XX_VIN_1_1 | + (CX231XX_VIN_1_2 << 8) | + CX25840_SVIDEO_ON, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + } + }, + }, }; const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); @@ -675,6 +708,8 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_ICONBIT_U100}, {USB_DEVICE(0x0fd9, 0x0037), .driver_info = CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2}, + {USB_DEVICE(0x1f4d, 0x0102), + .driver_info = CX231XX_BOARD_OTG102}, {}, }; diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index a8e50d2d491c..dff3f1d73f28 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -71,6 +71,7 @@ #define CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL 14 #define CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC 15 #define CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2 16 +#define CX231XX_BOARD_OTG102 17 /* Limits minimum and default number of buffers */ #define CX231XX_MIN_BUF 4 -- cgit From 95a75544cfb1410af721911cd8accdbc1a080b40 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 2 Mar 2013 06:41:02 -0300 Subject: [media] s5p-mfc: Staticize some symbols in s5p_mfc_cmd_v6.c Since these symbols are used only in this file, they can be made static. Signed-off-by: Sachin Kamat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c index 754bfbcb1c43..5708fc3d9b4d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c @@ -17,7 +17,7 @@ #include "s5p_mfc_intr.h" #include "s5p_mfc_opr.h" -int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, +static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, struct s5p_mfc_cmd_args *args) { mfc_debug(2, "Issue the command: %d\n", cmd); @@ -32,7 +32,7 @@ int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, return 0; } -int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; @@ -44,7 +44,7 @@ int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev) &h2r_args); } -int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; @@ -53,7 +53,7 @@ int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev) &h2r_args); } -int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; @@ -63,7 +63,7 @@ int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev) } /* Open a new instance and get its number */ -int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_cmd_args h2r_args; @@ -121,7 +121,7 @@ int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) } /* Close instance */ -int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_cmd_args h2r_args; -- cgit From 4294dcf7e335da72fe81538c46b4a8e83037ea20 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 2 Mar 2013 07:50:12 -0300 Subject: [media] s5p-mfc: Staticize some symbols in s5p_mfc_cmd_v5.c These symbols are used only in this file and can be made static. Signed-off-by: Sachin Kamat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c index 138778083c63..ad4f1df0a18e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c @@ -16,7 +16,7 @@ #include "s5p_mfc_debug.h" /* This function is used to send a command to the MFC */ -int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd, +static int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd, struct s5p_mfc_cmd_args *args) { int cur_cmd; @@ -41,7 +41,7 @@ int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd, } /* Initialize the MFC */ -int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; @@ -52,7 +52,7 @@ int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev) } /* Suspend the MFC hardware */ -int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; @@ -61,7 +61,7 @@ int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev) } /* Wake up the MFC hardware */ -int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; @@ -71,7 +71,7 @@ int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev) } -int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_cmd_args h2r_args; @@ -124,7 +124,7 @@ int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) return ret; } -int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_cmd_args h2r_args; -- cgit From b9571a577b570b24c4fa2ed79dade612294584d3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 2 Mar 2013 07:50:13 -0300 Subject: [media] s5p-mfc: Staticize symbols in s5p_mfc_opr_v6.c Symbols used only in this file should be made static. Signed-off-by: Sachin Kamat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 112 ++++++++++++------------ 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index beb6dbacebd9..33de88b8e9d0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -49,7 +49,7 @@ #define OFFSETB(x) (((x) - dev->port_b) >> S5P_FIMV_MEM_OFFSET) /* Allocate temporary buffers for decoding */ -int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) { /* NOP */ @@ -57,19 +57,19 @@ int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) } /* Release temproary buffers for decoding */ -void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) { /* NOP */ } -int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) { /* NOP */ return -1; } /* Allocate codec buffers */ -int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; unsigned int mb_width, mb_height; @@ -203,13 +203,13 @@ int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) } /* Release buffers allocated for codec */ -void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) { s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); } /* Allocate memory for instance data buffer */ -int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; @@ -258,13 +258,13 @@ int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) } /* Release instance buffer */ -void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) { s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); } /* Allocate context buffers for SYS_INIT */ -int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; int ret; @@ -287,7 +287,7 @@ int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) } /* Release context buffers for SYS_INIT */ -void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev) +static void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev) { s5p_mfc_release_priv_buf(dev->mem_dev_l, &dev->ctx_buf); } @@ -306,7 +306,7 @@ static int calc_plane(int width, int height) (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6); } -void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) { ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6); ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6); @@ -326,7 +326,7 @@ void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) } } -void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) { unsigned int mb_width, mb_height; @@ -339,8 +339,9 @@ void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) } /* Set registers for decoding stream buffer */ -int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, int buf_addr, - unsigned int start_num_byte, unsigned int strm_size) +static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, + int buf_addr, unsigned int start_num_byte, + unsigned int strm_size) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; @@ -359,7 +360,7 @@ int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, int buf_addr, } /* Set decoding frame buffer */ -int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) { unsigned int frame_size, i; unsigned int frame_size_ch, frame_size_mv; @@ -440,7 +441,7 @@ int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) } /* Set registers for encoding stream buffer */ -int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, +static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, unsigned long addr, unsigned int size) { struct s5p_mfc_dev *dev = ctx->dev; @@ -454,7 +455,7 @@ int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, return 0; } -void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, +static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, unsigned long y_addr, unsigned long c_addr) { struct s5p_mfc_dev *dev = ctx->dev; @@ -466,7 +467,7 @@ void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr); } -void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, +static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, unsigned long *y_addr, unsigned long *c_addr) { struct s5p_mfc_dev *dev = ctx->dev; @@ -483,7 +484,7 @@ void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, } /* Set encoding ref & codec buffer */ -int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; size_t buf_addr1; @@ -1147,7 +1148,7 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) } /* Initialize decoding */ -int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; unsigned int reg = 0; @@ -1215,7 +1216,7 @@ static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) } /* Decode a single frame */ -int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, +static int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, enum s5p_mfc_decode_arg last_frame) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1244,7 +1245,7 @@ int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, return 0; } -int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1267,7 +1268,7 @@ int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) return 0; } -int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_enc_params *p = &ctx->enc_params; @@ -1283,7 +1284,7 @@ int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) } /* Encode a single frame */ -int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1540,7 +1541,7 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) } /* Try running an operation on hardware */ -void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) +static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_ctx *ctx; int new_ctx; @@ -1663,7 +1664,7 @@ void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) } -void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq) +static void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq) { struct s5p_mfc_buf *b; int i; @@ -1677,13 +1678,13 @@ void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq) } } -void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) +static void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) { mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); mfc_write(dev, 0, S5P_FIMV_RISC2HOST_INT_V6); } -void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, +static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, unsigned int ofs) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1693,7 +1694,8 @@ void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, s5p_mfc_clock_off(); } -unsigned int s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) +static unsigned int +s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) { struct s5p_mfc_dev *dev = ctx->dev; int ret; @@ -1705,140 +1707,140 @@ unsigned int s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) return ret; } -int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); } -int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); } -int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6); } -int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6); } -int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DECODED_FRAME_TYPE_V6) & S5P_FIMV_DECODE_FRAME_MASK_V6; } -int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) { return mfc_read(ctx->dev, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6) & S5P_FIMV_DECODE_FRAME_MASK_V6; } -int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DECODED_NAL_SIZE_V6); } -int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_RISC2HOST_CMD_V6) & S5P_FIMV_RISC2HOST_CMD_MASK; } -int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_ERROR_CODE_V6); } -int s5p_mfc_err_dec_v6(unsigned int err) +static int s5p_mfc_err_dec_v6(unsigned int err) { return (err & S5P_FIMV_ERR_DEC_MASK_V6) >> S5P_FIMV_ERR_DEC_SHIFT_V6; } -int s5p_mfc_err_dspl_v6(unsigned int err) +static int s5p_mfc_err_dspl_v6(unsigned int err) { return (err & S5P_FIMV_ERR_DSPL_MASK_V6) >> S5P_FIMV_ERR_DSPL_SHIFT_V6; } -int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6); } -int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6); } -int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_MIN_NUM_DPB_V6); } -int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_MIN_NUM_MV_V6); } -int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_RET_INSTANCE_ID_V6); } -int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_E_NUM_DPB_V6); } -int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_E_STREAM_SIZE_V6); } -int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_E_SLICE_TYPE_V6); } -int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_E_PICTURE_COUNT_V6); } -int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) { return mfc_read(ctx->dev, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6); } -int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_MVC_NUM_VIEWS_V6); } -int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_D_MVC_VIEW_ID_V6); } -unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v6(ctx, PIC_TIME_TOP_V6); } -unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v6(ctx, PIC_TIME_BOT_V6); } -unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v6(ctx, CROP_INFO_H_V6); } -unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v6(ctx, CROP_INFO_V_V6); } -- cgit From 3c75a2e1cfcabe01e5914a92e949188720918933 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 2 Mar 2013 07:50:14 -0300 Subject: [media] s5p-mfc: Staticize symbols in s5p_mfc_opr_v5.c Some symbols are used only in this file. Make them static. Signed-off-by: Sachin Kamat Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 103 ++++++++++++------------ 1 file changed, 52 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index f61dba837899..c7ad329ca889 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -34,7 +34,7 @@ #define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT) /* Allocate temporary buffers for decoding */ -int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; @@ -55,13 +55,13 @@ int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) /* Release temporary buffers for decoding */ -void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) { s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->dsc); } /* Allocate codec buffers */ -int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; unsigned int enc_ref_y_size = 0; @@ -193,14 +193,14 @@ int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) } /* Release buffers allocated for codec */ -void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) { s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); s5p_mfc_release_priv_buf(ctx->dev->mem_dev_r, &ctx->bank2); } /* Allocate memory for instance data buffer */ -int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; @@ -241,20 +241,20 @@ int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) } /* Release instance buffer */ -void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) { s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->shm); } -int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev) { /* NOP */ return 0; } -void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev) +static void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev) { /* NOP */ } @@ -273,7 +273,7 @@ static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, return readl(ctx->shm.virt + ofs); } -void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) { unsigned int guard_width, guard_height; @@ -315,7 +315,7 @@ void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) } } -void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) +static void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) { if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN); @@ -361,8 +361,9 @@ static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx) } /* Set registers for decoding stream buffer */ -int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, int buf_addr, - unsigned int start_num_byte, unsigned int buf_size) +static int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, + int buf_addr, unsigned int start_num_byte, + unsigned int buf_size) { struct s5p_mfc_dev *dev = ctx->dev; @@ -374,7 +375,7 @@ int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, int buf_addr, } /* Set decoding frame buffer */ -int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx) { unsigned int frame_size, i; unsigned int frame_size_ch, frame_size_mv; @@ -506,7 +507,7 @@ int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx) } /* Set registers for encoding stream buffer */ -int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx, +static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx, unsigned long addr, unsigned int size) { struct s5p_mfc_dev *dev = ctx->dev; @@ -516,7 +517,7 @@ int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx, return 0; } -void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, +static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, unsigned long y_addr, unsigned long c_addr) { struct s5p_mfc_dev *dev = ctx->dev; @@ -525,7 +526,7 @@ void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR); } -void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, +static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, unsigned long *y_addr, unsigned long *c_addr) { struct s5p_mfc_dev *dev = ctx->dev; @@ -537,7 +538,7 @@ void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, } /* Set encoding ref & codec buffer */ -int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; size_t buf_addr1, buf_addr2; @@ -1041,7 +1042,7 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) } /* Initialize decoding */ -int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1077,7 +1078,7 @@ static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) } /* Decode a single frame */ -int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx, +static int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx, enum s5p_mfc_decode_arg last_frame) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1106,7 +1107,7 @@ int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx, return 0; } -int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; @@ -1128,7 +1129,7 @@ int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx) } /* Encode a single frame */ -int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; int cmd; @@ -1353,7 +1354,7 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) } /* Try running an operation on hardware */ -void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) +static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) { struct s5p_mfc_ctx *ctx; int new_ctx; @@ -1469,7 +1470,7 @@ void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) } -void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq) +static void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq) { struct s5p_mfc_buf *b; int i; @@ -1483,52 +1484,52 @@ void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq) } } -void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev) +static void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev) { mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT); mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD); mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID); } -int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_DISPLAY_Y_ADR) << MFC_OFFSET_SHIFT; } -int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_DECODE_Y_ADR) << MFC_OFFSET_SHIFT; } -int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_DISPLAY_STATUS); } -int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_DECODE_STATUS); } -int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_DECODE_FRAME_TYPE) & S5P_FIMV_DECODE_FRAME_MASK; } -int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx) { return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >> S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) & S5P_FIMV_DECODE_FRAME_MASK; } -int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_CONSUMED_BYTES); } -int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev) { int reason; reason = mfc_read(dev, S5P_FIMV_RISC2HOST_CMD) & @@ -1576,98 +1577,98 @@ int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev) return reason; } -int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG2); } -int s5p_mfc_err_dec_v5(unsigned int err) +static int s5p_mfc_err_dec_v5(unsigned int err) { return (err & S5P_FIMV_ERR_DEC_MASK) >> S5P_FIMV_ERR_DEC_SHIFT; } -int s5p_mfc_err_dspl_v5(unsigned int err) +static int s5p_mfc_err_dspl_v5(unsigned int err) { return (err & S5P_FIMV_ERR_DSPL_MASK) >> S5P_FIMV_ERR_DSPL_SHIFT; } -int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_HRESOL); } -int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_VRESOL); } -int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_SI_BUF_NUMBER); } -int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev) { /* NOP */ return -1; } -int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG1); } -int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_ENC_SI_STRM_SIZE); } -int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_ENC_SI_SLICE_TYPE); } -int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev) { return -1; } -int s5p_mfc_get_enc_pic_count_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_enc_pic_count_v5(struct s5p_mfc_dev *dev) { return mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT); } -int s5p_mfc_get_sei_avail_status_v5(struct s5p_mfc_ctx *ctx) +static int s5p_mfc_get_sei_avail_status_v5(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v5(ctx, FRAME_PACK_SEI_AVAIL); } -int s5p_mfc_get_mvc_num_views_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mvc_num_views_v5(struct s5p_mfc_dev *dev) { return -1; } -int s5p_mfc_get_mvc_view_id_v5(struct s5p_mfc_dev *dev) +static int s5p_mfc_get_mvc_view_id_v5(struct s5p_mfc_dev *dev) { return -1; } -unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP); } -unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT); } -unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v5(ctx, CROP_INFO_H); } -unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx) +static unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx) { return s5p_mfc_read_info_v5(ctx, CROP_INFO_V); } -- cgit From b78a1f372210ae8c19426cb3ae708bf85aa70124 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 4 Mar 2013 09:43:20 -0300 Subject: [media] m920x: let GCC see 'ret' is used initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 7543f344e9b06afe86b55a2620f5c11b38bd5642 ("[media] m920x: factor out a m920x_write_seq() function") building m920x.o triggers this GCC warning: drivers/media/usb/dvb-usb/m920x.c: In function ‘m920x_probe’: drivers/media/usb/dvb-usb/m920x.c:91:6: warning: ‘ret’ may be used uninitialized in this function [-Wuninitialized] This warning is caused by m920x_write_seq(), which is apparently inlined into m920x_probe(). It is clear why GCC thinks 'ret' may be used uninitialized. But in practice the first seq->address will always be non-zero when this function is called. That means we can change the while()-do{} loop into a do{}-while() loop. And that suffices to make GCC see that 'ret' will not be used uninitialized. Signed-off-by: Paul Bolle Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/m920x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index 92afeb20650f..79b31ae66a9c 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -68,13 +68,13 @@ static inline int m920x_write_seq(struct usb_device *udev, u8 request, struct m920x_inits *seq) { int ret; - while (seq->address) { + do { ret = m920x_write(udev, request, seq->data, seq->address); if (ret != 0) return ret; seq++; - } + } while (seq->address); return ret; } -- cgit From 43283febfdd6ce2ca9e76982c459a03524ef9755 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 13 Mar 2013 18:32:47 -0700 Subject: mwifiex: cleanup VHT cap Firmware returned VHT cap has the same format that cfg80211 expects. There is no need to parse the vht cap from the firmware and then set it to ieee80211_sta_vht_cap. Just copying is sufficient. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 58 +-------------------------------- drivers/net/wireless/mwifiex/fw.h | 28 ---------------- 2 files changed, 1 insertion(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c9bc5f5ba6e1..dbf5b1289516 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1932,66 +1932,10 @@ static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info, struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; - u32 vht_cap = 0, cap = adapter->hw_dot_11ac_dev_cap; vht_info->vht_supported = true; - switch (GET_VHTCAP_MAXMPDULEN(cap)) { - case 0x00: - vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; - break; - case 0x01: - vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; - break; - case 0x10: - vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; - break; - default: - dev_err(adapter->dev, "unsupported MAX MPDU len\n"); - break; - } - - if (ISSUPP_11ACVHTHTCVHT(cap)) - vht_cap |= IEEE80211_VHT_CAP_HTC_VHT; - - if (ISSUPP_11ACVHTTXOPPS(cap)) - vht_cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS; - - if (ISSUPP_11ACMURXBEAMFORMEE(cap)) - vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; - - if (ISSUPP_11ACMUTXBEAMFORMEE(cap)) - vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; - - if (ISSUPP_11ACSUBEAMFORMER(cap)) - vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; - - if (ISSUPP_11ACSUBEAMFORMEE(cap)) - vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; - - if (ISSUPP_11ACRXSTBC(cap)) - vht_cap |= IEEE80211_VHT_CAP_RXSTBC_1; - - if (ISSUPP_11ACTXSTBC(cap)) - vht_cap |= IEEE80211_VHT_CAP_TXSTBC; - - if (ISSUPP_11ACSGI160(cap)) - vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_160; - - if (ISSUPP_11ACSGI80(cap)) - vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_80; - - if (ISSUPP_11ACLDPC(cap)) - vht_cap |= IEEE80211_VHT_CAP_RXLDPC; - - if (ISSUPP_11ACBW8080(cap)) - vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; - - if (ISSUPP_11ACBW160(cap)) - vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; - - vht_info->cap = vht_cap; - + vht_info->cap = adapter->hw_dot_11ac_dev_cap; /* Update MCS support for VHT */ vht_info->vht_mcs.rx_mcs_map = cpu_to_le16( adapter->hw_dot_11ac_mcs_support & 0xFFFF); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6d6e5ae71eaa..57c5defe1f9d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -230,40 +230,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14))) -#define GET_VHTCAP_MAXMPDULEN(vht_cap_info) (vht_cap_info & 0x3) #define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3) #define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3) #define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \ (2 * (nss - 1))) #define NO_NSS_SUPPORT 0x3 -/* HW_SPEC: HTC-VHT supported */ -#define ISSUPP_11ACVHTHTCVHT(Dot11acDevCap) (Dot11acDevCap & BIT(22)) -/* HW_SPEC: VHT TXOP PS support */ -#define ISSUPP_11ACVHTTXOPPS(Dot11acDevCap) (Dot11acDevCap & BIT(21)) -/* HW_SPEC: MU RX beamformee support */ -#define ISSUPP_11ACMURXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(20)) -/* HW_SPEC: MU TX beamformee support */ -#define ISSUPP_11ACMUTXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(19)) -/* HW_SPEC: SU Beamformee support */ -#define ISSUPP_11ACSUBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(10)) -/* HW_SPEC: SU Beamformer support */ -#define ISSUPP_11ACSUBEAMFORMER(Dot11acDevCap) (Dot11acDevCap & BIT(9)) -/* HW_SPEC: Rx STBC support */ -#define ISSUPP_11ACRXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(8)) -/* HW_SPEC: Tx STBC support */ -#define ISSUPP_11ACTXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(7)) -/* HW_SPEC: Short GI support for 160MHz BW */ -#define ISSUPP_11ACSGI160(Dot11acDevCap) (Dot11acDevCap & BIT(6)) -/* HW_SPEC: Short GI support for 80MHz BW */ -#define ISSUPP_11ACSGI80(Dot11acDevCap) (Dot11acDevCap & BIT(5)) -/* HW_SPEC: LDPC coding support */ -#define ISSUPP_11ACLDPC(Dot11acDevCap) (Dot11acDevCap & BIT(4)) -/* HW_SPEC: Channel BW 20/40/80/160/80+80 MHz support */ -#define ISSUPP_11ACBW8080(Dot11acDevCap) (Dot11acDevCap & BIT(3)) -/* HW_SPEC: Channel BW 20/40/80/160 MHz support */ -#define ISSUPP_11ACBW160(Dot11acDevCap) (Dot11acDevCap & BIT(2)) - #define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16) #define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF) -- cgit From 1dd0dbb30eb8e5d3e855bc864e54b745d1b96fd6 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 15 Mar 2013 09:57:56 +0100 Subject: rt2x00: Revert "rt2x00: remove unused argument" This reverts commit db36f792370959ff26458f80942cf98fe8249d95 since I'm going to use the data pointer that was removed in a follow up patch. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 10 ++++++---- drivers/net/wireless/rt2x00/rt2x00queue.h | 5 ++++- drivers/net/wireless/rt2x00/rt2x00usb.c | 20 +++++++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4d91795dc6a2..952a0490eb17 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -832,7 +832,9 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - bool (*fn)(struct queue_entry *entry)) + void *data, + bool (*fn)(struct queue_entry *entry, + void *data)) { unsigned long irqflags; unsigned int index_start; @@ -863,17 +865,17 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue, */ if (index_start < index_end) { for (i = index_start; i < index_end; i++) { - if (fn(&queue->entries[i])) + if (fn(&queue->entries[i], data)) return true; } } else { for (i = index_start; i < queue->limit; i++) { - if (fn(&queue->entries[i])) + if (fn(&queue->entries[i], data)) return true; } for (i = 0; i < index_end; i++) { - if (fn(&queue->entries[i])) + if (fn(&queue->entries[i], data)) return true; } } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 9b8c10a86dee..5f1392c72673 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -584,6 +584,7 @@ struct data_queue_desc { * @queue: Pointer to @data_queue * @start: &enum queue_index Pointer to start index * @end: &enum queue_index Pointer to end index + * @data: Data to pass to the callback function * @fn: The function to call for each &struct queue_entry * * This will walk through all entries in the queue, in chronological @@ -596,7 +597,9 @@ struct data_queue_desc { bool rt2x00queue_for_each_entry(struct data_queue *queue, enum queue_index start, enum queue_index end, - bool (*fn)(struct queue_entry *entry)); + void *data, + bool (*fn)(struct queue_entry *entry, + void *data)); /** * rt2x00queue_empty - Check if the queue is empty. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 40ea80725a96..5e50d4ff9d21 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -285,7 +285,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } -static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry) +static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -390,7 +390,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); } -static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry) +static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -427,12 +427,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_AC_BE: case QID_AC_BK: if (!rt2x00queue_empty(queue)) - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00queue_for_each_entry(queue, + Q_INDEX_DONE, + Q_INDEX, + NULL, rt2x00usb_kick_tx_entry); break; case QID_RX: if (!rt2x00queue_full(queue)) - rt2x00queue_for_each_entry(queue, Q_INDEX, Q_INDEX_DONE, + rt2x00queue_for_each_entry(queue, + Q_INDEX, + Q_INDEX_DONE, + NULL, rt2x00usb_kick_rx_entry); break; default: @@ -441,7 +447,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); -static bool rt2x00usb_flush_entry(struct queue_entry *entry) +static bool rt2x00usb_flush_entry(struct queue_entry *entry, void *data) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv = entry->priv_data; @@ -468,7 +474,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) unsigned int i; if (drop) - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, rt2x00usb_flush_entry); /* @@ -559,7 +565,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) entry->flags = 0; if (entry->queue->qid == QID_RX) - rt2x00usb_kick_rx_entry(entry); + rt2x00usb_kick_rx_entry(entry, NULL); } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); -- cgit From 8857d6dc77e4e3afeee2f33c49597010130ed858 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 15 Mar 2013 09:57:57 +0100 Subject: rt2x00: Fix tx status reporting for reordered frames in rt2800pci rt2800 hardware sometimes reorders tx frames when transmitting to multiple BA enabled STAs concurrently. For example a tx queue [ STA1 | STA2 | STA1 | STA2 ] can result in the tx status reports [ STA1 | STA1 | STA2 | STA2 ] when the hw decides to put the frames for STA1 in one AMPDU. To mitigate this effect associate the currently processed tx status to the first frame in the tx queue with a matching wcid. This patch fixes several problems related to incorrect tx status reporting. Furthermore the tx rate selection is much more stable when communicating with multiple STAs. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 111 +++++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2x00queue.h | 4 ++ 2 files changed, 112 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index ded73da4de0b..80cf8d745c6f 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -742,10 +742,90 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } +static bool rt2800pci_txdone_entry_check(struct queue_entry *entry, u32 status) +{ + __le32 *txwi; + u32 word; + int wcid, tx_wcid; + + wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); + + txwi = rt2800_drv_get_txwi(entry); + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + + return (tx_wcid == wcid); +} + +static bool rt2800pci_txdone_find_entry(struct queue_entry *entry, void *data) +{ + u32 status = *(u32 *)data; + + /* + * rt2800pci hardware might reorder frames when exchanging traffic + * with multiple BA enabled STAs. + * + * For example, a tx queue + * [ STA1 | STA2 | STA1 | STA2 ] + * can result in tx status reports + * [ STA1 | STA1 | STA2 | STA2 ] + * when the hw decides to aggregate the frames for STA1 into one AMPDU. + * + * To mitigate this effect, associate the tx status to the first frame + * in the tx queue with a matching wcid. + */ + if (rt2800pci_txdone_entry_check(entry, status) && + !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + /* + * Got a matching frame, associate the tx status with + * the frame + */ + entry->status = status; + set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); + return true; + } + + /* Check the next frame */ + return false; +} + +static bool rt2800pci_txdone_match_first(struct queue_entry *entry, void *data) +{ + u32 status = *(u32 *)data; + + /* + * Find the first frame without tx status and assign this status to it + * regardless if it matches or not. + */ + if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + /* + * Got a matching frame, associate the tx status with + * the frame + */ + entry->status = status; + set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); + return true; + } + + /* Check the next frame */ + return false; +} +static bool rt2800pci_txdone_release_entries(struct queue_entry *entry, + void *data) +{ + if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + rt2800_txdone_entry(entry, entry->status, + rt2800pci_get_txwi(entry)); + return false; + } + + /* No more frames to release */ + return true; +} + static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - struct queue_entry *entry; u32 status; u8 qid; int max_tx_done = 16; @@ -783,8 +863,33 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) break; } - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry)); + /* + * Let's associate this tx status with the first + * matching frame. + */ + if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, &status, + rt2800pci_txdone_find_entry)) { + /* + * We cannot match the tx status to any frame, so just + * use the first one. + */ + if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, &status, + rt2800pci_txdone_match_first)) { + WARNING(rt2x00dev, "No frame found for TX " + "status on queue %u, dropping\n", + qid); + break; + } + } + + /* + * Release all frames with a valid tx status. + */ + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, NULL, + rt2800pci_txdone_release_entries); if (--max_tx_done == 0) break; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 5f1392c72673..3d0137193da0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -359,6 +359,7 @@ enum queue_entry_flags { ENTRY_DATA_PENDING, ENTRY_DATA_IO_FAILED, ENTRY_DATA_STATUS_PENDING, + ENTRY_DATA_STATUS_SET, }; /** @@ -372,6 +373,7 @@ enum queue_entry_flags { * @entry_idx: The entry index number. * @priv_data: Private data belonging to this queue entry. The pointer * points to data specific to a particular driver and queue type. + * @status: Device specific status */ struct queue_entry { unsigned long flags; @@ -383,6 +385,8 @@ struct queue_entry { unsigned int entry_idx; + u32 status; + void *priv_data; }; -- cgit From 53216d6a9a2dd3b0a65203e540b7739c36351d55 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:29 +0100 Subject: rt2800: do not crash if spec->channels is NULL In case the spec->channels was not specified, print warning instead of hard crash the kernel. Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a658b4bc7da2..182e598017ec 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -5213,6 +5213,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels = rf_vals_3x; } + if (WARN_ON_ONCE(!spec->channels)) + return -ENODEV; + /* * Initialize HT information. */ -- cgit From b8863f8bcc3579f4bd2df43d84ae8d1ed528c204 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:30 +0100 Subject: rt2800: 5592: early defines Add basic defines for 5592 chip. It can not be enabled until CONFIG_RT2800USB_RT55XX configuration option will be provided in the Kconfig. Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 2 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ drivers/net/wireless/rt2x00/rt2800usb.c | 3 +++ drivers/net/wireless/rt2x00/rt2x00.h | 1 + 4 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 4db1088a847f..58c01648809c 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -51,6 +51,7 @@ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) + * RF5592 2.4G/5G 2T2R * RF5360 2.4G 1T1R * RF5370 2.4G 1T1R * RF5390 2.4G 1T1R @@ -68,6 +69,7 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3053 0x000d +#define RF5592 0x000f #define RF3290 0x3290 #define RF5360 0x5360 #define RF5370 0x5370 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 182e598017ec..45f58c945526 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4863,6 +4863,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RT3572: case RT5390: case RT5392: + case RT5592: break; default: ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt); @@ -4887,6 +4888,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF5372: case RF5390: case RF5392: + case RF5592: break; default: ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 098613ed93fb..f9ca79503252 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1200,6 +1200,9 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x5370) }, { USB_DEVICE(0x148f, 0x5372) }, #endif +#ifdef CONFIG_RT2800USB_RT55XX + { USB_DEVICE(0x148f, 0x5572) }, +#endif #ifdef CONFIG_RT2800USB_UNKNOWN /* * Unclear what kind of devices these are (they aren't supported by the diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 086abb403a4f..425183570f35 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -193,6 +193,7 @@ struct rt2x00_chip { #define RT3883 0x3883 /* WSOC */ #define RT5390 0x5390 /* 2.4GHz */ #define RT5392 0x5392 /* 2.4GHz */ +#define RT5592 0x5592 u16 rf; u16 rev; -- cgit From 7848b2313148c3d77b4f982a4c45aee036b3fcc6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:31 +0100 Subject: rt2800: 5592: add channels table Based on: RT5592_ChipSwitchChannel() RT5592_Frequency_Plan_Xtal20M[] RT5592_Frequency_Plan_Xtal40M[] from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 6 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 144 ++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 58c01648809c..b72f71ddbf79 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -691,6 +691,12 @@ #define GPIO_SWITCH_6 FIELD32(0x00000040) #define GPIO_SWITCH_7 FIELD32(0x00000080) +/* + * FIXME: where the DEBUG_INDEX name come from? + */ +#define MAC_DEBUG_INDEX 0x05e8 +#define MAC_DEBUG_INDEX_XTAL FIELD32(0x80000000) + /* * MAC Control/Status Registers(CSR). * Some values are set in TU, whereas 1 TU == 1024 us. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 45f58c945526..45f033842ab9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -5124,6 +5124,138 @@ static const struct rf_channel rf_vals_3x[] = { {173, 0x61, 0, 9}, }; +static const struct rf_channel rf_vals_5592_xtal20[] = { + /* Channel, N, K, mod, R */ + {1, 482, 4, 10, 3}, + {2, 483, 4, 10, 3}, + {3, 484, 4, 10, 3}, + {4, 485, 4, 10, 3}, + {5, 486, 4, 10, 3}, + {6, 487, 4, 10, 3}, + {7, 488, 4, 10, 3}, + {8, 489, 4, 10, 3}, + {9, 490, 4, 10, 3}, + {10, 491, 4, 10, 3}, + {11, 492, 4, 10, 3}, + {12, 493, 4, 10, 3}, + {13, 494, 4, 10, 3}, + {14, 496, 8, 10, 3}, + {36, 172, 8, 12, 1}, + {38, 173, 0, 12, 1}, + {40, 173, 4, 12, 1}, + {42, 173, 8, 12, 1}, + {44, 174, 0, 12, 1}, + {46, 174, 4, 12, 1}, + {48, 174, 8, 12, 1}, + {50, 175, 0, 12, 1}, + {52, 175, 4, 12, 1}, + {54, 175, 8, 12, 1}, + {56, 176, 0, 12, 1}, + {58, 176, 4, 12, 1}, + {60, 176, 8, 12, 1}, + {62, 177, 0, 12, 1}, + {64, 177, 4, 12, 1}, + {100, 183, 4, 12, 1}, + {102, 183, 8, 12, 1}, + {104, 184, 0, 12, 1}, + {106, 184, 4, 12, 1}, + {108, 184, 8, 12, 1}, + {110, 185, 0, 12, 1}, + {112, 185, 4, 12, 1}, + {114, 185, 8, 12, 1}, + {116, 186, 0, 12, 1}, + {118, 186, 4, 12, 1}, + {120, 186, 8, 12, 1}, + {122, 187, 0, 12, 1}, + {124, 187, 4, 12, 1}, + {126, 187, 8, 12, 1}, + {128, 188, 0, 12, 1}, + {130, 188, 4, 12, 1}, + {132, 188, 8, 12, 1}, + {134, 189, 0, 12, 1}, + {136, 189, 4, 12, 1}, + {138, 189, 8, 12, 1}, + {140, 190, 0, 12, 1}, + {149, 191, 6, 12, 1}, + {151, 191, 10, 12, 1}, + {153, 192, 2, 12, 1}, + {155, 192, 6, 12, 1}, + {157, 192, 10, 12, 1}, + {159, 193, 2, 12, 1}, + {161, 193, 6, 12, 1}, + {165, 194, 2, 12, 1}, + {184, 164, 0, 12, 1}, + {188, 164, 4, 12, 1}, + {192, 165, 8, 12, 1}, + {196, 166, 0, 12, 1}, +}; + +static const struct rf_channel rf_vals_5592_xtal40[] = { + /* Channel, N, K, mod, R */ + {1, 241, 2, 10, 3}, + {2, 241, 7, 10, 3}, + {3, 242, 2, 10, 3}, + {4, 242, 7, 10, 3}, + {5, 243, 2, 10, 3}, + {6, 243, 7, 10, 3}, + {7, 244, 2, 10, 3}, + {8, 244, 7, 10, 3}, + {9, 245, 2, 10, 3}, + {10, 245, 7, 10, 3}, + {11, 246, 2, 10, 3}, + {12, 246, 7, 10, 3}, + {13, 247, 2, 10, 3}, + {14, 248, 4, 10, 3}, + {36, 86, 4, 12, 1}, + {38, 86, 6, 12, 1}, + {40, 86, 8, 12, 1}, + {42, 86, 10, 12, 1}, + {44, 87, 0, 12, 1}, + {46, 87, 2, 12, 1}, + {48, 87, 4, 12, 1}, + {50, 87, 6, 12, 1}, + {52, 87, 8, 12, 1}, + {54, 87, 10, 12, 1}, + {56, 88, 0, 12, 1}, + {58, 88, 2, 12, 1}, + {60, 88, 4, 12, 1}, + {62, 88, 6, 12, 1}, + {64, 88, 8, 12, 1}, + {100, 91, 8, 12, 1}, + {102, 91, 10, 12, 1}, + {104, 92, 0, 12, 1}, + {106, 92, 2, 12, 1}, + {108, 92, 4, 12, 1}, + {110, 92, 6, 12, 1}, + {112, 92, 8, 12, 1}, + {114, 92, 10, 12, 1}, + {116, 93, 0, 12, 1}, + {118, 93, 2, 12, 1}, + {120, 93, 4, 12, 1}, + {122, 93, 6, 12, 1}, + {124, 93, 8, 12, 1}, + {126, 93, 10, 12, 1}, + {128, 94, 0, 12, 1}, + {130, 94, 2, 12, 1}, + {132, 94, 4, 12, 1}, + {134, 94, 6, 12, 1}, + {136, 94, 8, 12, 1}, + {138, 94, 10, 12, 1}, + {140, 95, 0, 12, 1}, + {149, 95, 9, 12, 1}, + {151, 95, 11, 12, 1}, + {153, 96, 1, 12, 1}, + {155, 96, 3, 12, 1}, + {157, 96, 5, 12, 1}, + {159, 96, 7, 12, 1}, + {161, 96, 9, 12, 1}, + {165, 97, 1, 12, 1}, + {184, 82, 0, 12, 1}, + {188, 82, 4, 12, 1}, + {192, 82, 8, 12, 1}, + {196, 83, 0, 12, 1}, +}; + static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; @@ -5132,6 +5264,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) char *default_power2; unsigned int i; u16 eeprom; + u32 reg; /* * Disable powersaving as default on PCI devices. @@ -5213,6 +5346,17 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->supported_bands |= SUPPORT_BAND_5GHZ; spec->num_channels = ARRAY_SIZE(rf_vals_3x); spec->channels = rf_vals_3x; + } else if (rt2x00_rf(rt2x00dev, RF5592)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; + + rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); + if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { + spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40); + spec->channels = rf_vals_5592_xtal40; + } else { + spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20); + spec->channels = rf_vals_5592_xtal20; + } } if (WARN_ON_ONCE(!spec->channels)) -- cgit From 8f821098ce59a261feaad9488e50ab6e60c7d4dd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:32 +0100 Subject: rt2800: 5592: channel config stub Based on: RT5592_ChipSwitchChannel() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 11 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 255 ++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index b72f71ddbf79..acb5e62b2a81 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2029,10 +2029,19 @@ struct mac_iveiv_entry { #define RFCSR7_BIT5 FIELD8(0x20) #define RFCSR7_BITS67 FIELD8(0xc0) +/* + * RFCSR 9: + */ +#define RFCSR9_K FIELD8(0x0f) +#define RFCSR9_N FIELD8(0x10) +#define RFCSR9_UNKNOWN FIELD8(0x60) +#define RFCSR9_MOD FIELD8(0x80) + /* * RFCSR 11: */ #define RFCSR11_R FIELD8(0x03) +#define RFCSR11_MOD FIELD8(0xc0) /* * RFCSR 12: @@ -2138,11 +2147,13 @@ struct mac_iveiv_entry { * RFCSR 49: */ #define RFCSR49_TX FIELD8(0x3f) +#define RFCSR49_EP FIELD8(0xc0) /* * RFCSR 50: */ #define RFCSR50_TX FIELD8(0x3f) +#define RFCSR50_EP FIELD8(0xc0) /* * RF registers diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 45f033842ab9..079086b0da0e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1988,6 +1988,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, } #define POWER_BOUND 0x27 +#define POWER_BOUND_5G 0x2b #define FREQ_OFFSET_BOUND 0x5f static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, @@ -2184,6 +2185,257 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, } } +static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr, ep_reg; + int power_bound; + + /* TODO */ + const bool is_11b = false; + const bool is_type_ep = false; + + + /* Order of values on rf_channel entry: N, K, mod, R */ + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1 & 0xff); + + rt2800_rfcsr_read(rt2x00dev, 9, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR9_K, rf->rf2 & 0xf); + rt2x00_set_field8(&rfcsr, RFCSR9_N, (rf->rf1 & 0x100) >> 8); + rt2x00_set_field8(&rfcsr, RFCSR9_MOD, ((rf->rf3 - 8) & 0x4) >> 2); + rt2800_rfcsr_write(rt2x00dev, 9, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf4 - 1); + rt2x00_set_field8(&rfcsr, RFCSR11_MOD, (rf->rf3 - 8) & 0x3); + rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); + + if (rf->channel <= 14) { + rt2800_rfcsr_write(rt2x00dev, 10, 0x90); + /* FIXME: RF11 owerwrite ? */ + rt2800_rfcsr_write(rt2x00dev, 11, 0x4A); + rt2800_rfcsr_write(rt2x00dev, 12, 0x52); + rt2800_rfcsr_write(rt2x00dev, 13, 0x42); + rt2800_rfcsr_write(rt2x00dev, 22, 0x40); + rt2800_rfcsr_write(rt2x00dev, 24, 0x4A); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 27, 0x42); + rt2800_rfcsr_write(rt2x00dev, 36, 0x80); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x89); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1B); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0D); + rt2800_rfcsr_write(rt2x00dev, 41, 0x9B); + rt2800_rfcsr_write(rt2x00dev, 42, 0xD5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x72); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0E); + rt2800_rfcsr_write(rt2x00dev, 45, 0xA2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x6B); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 51, 0x3E); + rt2800_rfcsr_write(rt2x00dev, 52, 0x48); + rt2800_rfcsr_write(rt2x00dev, 54, 0x38); + rt2800_rfcsr_write(rt2x00dev, 56, 0xA1); + rt2800_rfcsr_write(rt2x00dev, 57, 0x00); + rt2800_rfcsr_write(rt2x00dev, 58, 0x39); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0x91); + rt2800_rfcsr_write(rt2x00dev, 62, 0x39); + + /* TODO RF27 <- tssi */ + + rfcsr = rf->channel <= 10 ? 0x07 : 0x06; + rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); + rt2800_rfcsr_write(rt2x00dev, 59, rfcsr); + + if (is_11b) { + /* CCK */ + rt2800_rfcsr_write(rt2x00dev, 31, 0xF8); + rt2800_rfcsr_write(rt2x00dev, 32, 0xC0); + if (is_type_ep) + rt2800_rfcsr_write(rt2x00dev, 55, 0x06); + else + rt2800_rfcsr_write(rt2x00dev, 55, 0x47); + } else { + /* OFDM */ + if (is_type_ep) + rt2800_rfcsr_write(rt2x00dev, 55, 0x03); + else + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + } + + power_bound = POWER_BOUND; + ep_reg = 0x2; + } else { + rt2800_rfcsr_write(rt2x00dev, 10, 0x97); + /* FIMXE: RF11 overwrite */ + rt2800_rfcsr_write(rt2x00dev, 11, 0x40); + rt2800_rfcsr_write(rt2x00dev, 25, 0xBF); + rt2800_rfcsr_write(rt2x00dev, 27, 0x42); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x04); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 40, 0x42); + rt2800_rfcsr_write(rt2x00dev, 41, 0xBB); + rt2800_rfcsr_write(rt2x00dev, 42, 0xD7); + rt2800_rfcsr_write(rt2x00dev, 45, 0x41); + rt2800_rfcsr_write(rt2x00dev, 48, 0x00); + rt2800_rfcsr_write(rt2x00dev, 57, 0x77); + rt2800_rfcsr_write(rt2x00dev, 60, 0x05); + rt2800_rfcsr_write(rt2x00dev, 61, 0x01); + + /* TODO RF27 <- tssi */ + + if (rf->channel >= 36 && rf->channel <= 64) { + + rt2800_rfcsr_write(rt2x00dev, 12, 0x2E); + rt2800_rfcsr_write(rt2x00dev, 13, 0x22); + rt2800_rfcsr_write(rt2x00dev, 22, 0x60); + rt2800_rfcsr_write(rt2x00dev, 23, 0x7F); + if (rf->channel <= 50) + rt2800_rfcsr_write(rt2x00dev, 24, 0x09); + else if (rf->channel >= 52) + rt2800_rfcsr_write(rt2x00dev, 24, 0x07); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1C); + rt2800_rfcsr_write(rt2x00dev, 43, 0x5B); + rt2800_rfcsr_write(rt2x00dev, 44, 0X40); + rt2800_rfcsr_write(rt2x00dev, 46, 0X00); + rt2800_rfcsr_write(rt2x00dev, 51, 0xFE); + rt2800_rfcsr_write(rt2x00dev, 52, 0x0C); + rt2800_rfcsr_write(rt2x00dev, 54, 0xF8); + if (rf->channel <= 50) { + rt2800_rfcsr_write(rt2x00dev, 55, 0x06), + rt2800_rfcsr_write(rt2x00dev, 56, 0xD3); + } else if (rf->channel >= 52) { + rt2800_rfcsr_write(rt2x00dev, 55, 0x04); + rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); + } + + rt2800_rfcsr_write(rt2x00dev, 58, 0x15); + rt2800_rfcsr_write(rt2x00dev, 59, 0x7F); + rt2800_rfcsr_write(rt2x00dev, 62, 0x15); + + } else if (rf->channel >= 100 && rf->channel <= 165) { + + rt2800_rfcsr_write(rt2x00dev, 12, 0x0E); + rt2800_rfcsr_write(rt2x00dev, 13, 0x42); + rt2800_rfcsr_write(rt2x00dev, 22, 0x40); + if (rf->channel <= 153) { + rt2800_rfcsr_write(rt2x00dev, 23, 0x3C); + rt2800_rfcsr_write(rt2x00dev, 24, 0x06); + } else if (rf->channel >= 155) { + rt2800_rfcsr_write(rt2x00dev, 23, 0x38); + rt2800_rfcsr_write(rt2x00dev, 24, 0x05); + } + if (rf->channel <= 138) { + rt2800_rfcsr_write(rt2x00dev, 39, 0x1A); + rt2800_rfcsr_write(rt2x00dev, 43, 0x3B); + rt2800_rfcsr_write(rt2x00dev, 44, 0x20); + rt2800_rfcsr_write(rt2x00dev, 46, 0x18); + } else if (rf->channel >= 140) { + rt2800_rfcsr_write(rt2x00dev, 39, 0x18); + rt2800_rfcsr_write(rt2x00dev, 43, 0x1B); + rt2800_rfcsr_write(rt2x00dev, 44, 0x10); + rt2800_rfcsr_write(rt2x00dev, 46, 0X08); + } + if (rf->channel <= 124) + rt2800_rfcsr_write(rt2x00dev, 51, 0xFC); + else if (rf->channel >= 126) + rt2800_rfcsr_write(rt2x00dev, 51, 0xEC); + if (rf->channel <= 138) + rt2800_rfcsr_write(rt2x00dev, 52, 0x06); + else if (rf->channel >= 140) + rt2800_rfcsr_write(rt2x00dev, 52, 0x06); + rt2800_rfcsr_write(rt2x00dev, 54, 0xEB); + if (rf->channel <= 138) + rt2800_rfcsr_write(rt2x00dev, 55, 0x01); + else if (rf->channel >= 140) + rt2800_rfcsr_write(rt2x00dev, 55, 0x00); + if (rf->channel <= 128) + rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); + else if (rf->channel >= 130) + rt2800_rfcsr_write(rt2x00dev, 56, 0xAB); + if (rf->channel <= 116) + rt2800_rfcsr_write(rt2x00dev, 58, 0x1D); + else if (rf->channel >= 118) + rt2800_rfcsr_write(rt2x00dev, 58, 0x15); + if (rf->channel <= 138) + rt2800_rfcsr_write(rt2x00dev, 59, 0x3F); + else if (rf->channel >= 140) + rt2800_rfcsr_write(rt2x00dev, 59, 0x7C); + if (rf->channel <= 116) + rt2800_rfcsr_write(rt2x00dev, 62, 0x1D); + else if (rf->channel >= 118) + rt2800_rfcsr_write(rt2x00dev, 62, 0x15); + } + + power_bound = POWER_BOUND_5G; + ep_reg = 0x3; + } + + rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); + if (info->default_power1 > power_bound) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, power_bound); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); + if (is_type_ep) + rt2x00_set_field8(&rfcsr, RFCSR49_EP, ep_reg); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); + if (info->default_power1 > power_bound) + rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); + else + rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); + if (is_type_ep) + rt2x00_set_field8(&rfcsr, RFCSR50_EP, ep_reg); + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); + + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, + rt2x00dev->default_ant.tx_chain_num >= 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, + rt2x00dev->default_ant.tx_chain_num == 2); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); + + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, + rt2x00dev->default_ant.rx_chain_num >= 1); + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, + rt2x00dev->default_ant.rx_chain_num == 2); + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + rt2800_rfcsr_write(rt2x00dev, 6, 0xe4); + + if (conf_is_ht40(conf)) + rt2800_rfcsr_write(rt2x00dev, 30, 0x16); + else + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + + if (!is_11b) { + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + } + + /* TODO proper frequency adjustment */ + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + /* TODO merge with others */ + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); +} + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -2225,6 +2477,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF5392: rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); break; + case RF5592: + rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); + break; default: rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); } -- cgit From 7641328d5b379daf94cfe125c9b03f0206340a49 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:33 +0100 Subject: rt2800: 5592: MAC registers initalization Based on: NICInitRT5592MacRegisters() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c On vendor driver we do not initialize TX_SW_CFG{1,2}. However the same difference is between rt2x00 and vendor driver for 5390 chip. Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 079086b0da0e..a35bce4bf044 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3377,7 +3377,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT5592)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); @@ -3557,7 +3558,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0); rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); - rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); + reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); -- cgit From a7bbbe5cac174ddddb1b093cd84f8ed9a69cff00 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:34 +0100 Subject: rt2800: 5592: BBP registers initialization Based on: NICInitRT5592BbpRegisters() NICInitBBP() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c DPO_RT5572_LinuxSTA_2.6.1.3_20121022/common/rtmp_init.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 24 +++++-- drivers/net/wireless/rt2x00/rt2800lib.c | 110 ++++++++++++++++++++++++++++++-- 2 files changed, 125 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index acb5e62b2a81..9d18d5384be7 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -90,11 +90,8 @@ #define REV_RT3390E 0x0211 #define REV_RT5390F 0x0502 #define REV_RT5390R 0x1502 +#define REV_RT5592C 0x0221 -/* - * Signal information. - * Default offset is required for RSSI <-> dBm conversion. - */ #define DEFAULT_RSSI_OFFSET 120 /* @@ -1955,6 +1952,20 @@ struct mac_iveiv_entry { */ #define BBP49_UPDATE_FLAG FIELD8(0x01) +/* + * BBP 105: + * - bit0: detect SIG on primary channel only (on 40MHz bandwidth) + * - bit1: FEQ (Feed Forward Compensation) for independend streams + * - bit2: MLD (Maximum Likehood Detection) for 2 streams (reserved on single + * stream) + * - bit4: channel estimation updates based on remodulation of + * L-SIG and HT-SIG symbols + */ +#define BBP105_DETECT_SIG_ON_PRIMARY FIELD8(0x01) +#define BBP105_FEQ FIELD8(0x02) +#define BBP105_MLD FIELD8(0x04) +#define BBP105_SIG_REMODULATION FIELD8(0x08) + /* * BBP 109 */ @@ -1974,6 +1985,11 @@ struct mac_iveiv_entry { */ #define BBP152_RX_DEFAULT_ANT FIELD8(0x80) +/* + * BBP 254: unknown + */ +#define BBP254_BIT7 FIELD8(0x80) + /* * RFCSR registers * The wordsize of the RFCSR is 8 bits. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a35bce4bf044..16e4200ec9e6 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3744,6 +3744,104 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) return -EACCES; } +static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev) +{ + u8 value; + + rt2800_bbp_read(rt2x00dev, 4, &value); + rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); + rt2800_bbp_write(rt2x00dev, 4, value); +} + +static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) +{ + const u8 glrt_table[] = { + 0xE0, 0x1F, 0X38, 0x32, 0x08, 0x28, 0x19, 0x0A, 0xFF, 0x00, /* 128 ~ 137 */ + 0x16, 0x10, 0x10, 0x0B, 0x36, 0x2C, 0x26, 0x24, 0x42, 0x36, /* 138 ~ 147 */ + 0x30, 0x2D, 0x4C, 0x46, 0x3D, 0x40, 0x3E, 0x42, 0x3D, 0x40, /* 148 ~ 157 */ + 0X3C, 0x34, 0x2C, 0x2F, 0x3C, 0x35, 0x2E, 0x2A, 0x49, 0x41, /* 158 ~ 167 */ + 0x36, 0x31, 0x30, 0x30, 0x0E, 0x0D, 0x28, 0x21, 0x1C, 0x16, /* 168 ~ 177 */ + 0x50, 0x4A, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, /* 178 ~ 187 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 ~ 197 */ + 0x00, 0x00, 0x7D, 0x14, 0x32, 0x2C, 0x36, 0x4C, 0x43, 0x2C, /* 198 ~ 207 */ + 0x2E, 0x36, 0x30, 0x6E, /* 208 ~ 211 */ + }; + int i; + + for (i = 0; i < ARRAY_SIZE(glrt_table); i++) { + rt2800_bbp_write(rt2x00dev, 195, 128 + i); + rt2800_bbp_write(rt2x00dev, 196, glrt_table[i]); + } +}; + +static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) +{ + int ant, div_mode; + u16 eeprom; + u8 value; + + rt2800_bbp_read(rt2x00dev, 105, &value); + rt2x00_set_field8(&value, BBP105_MLD, + rt2x00dev->default_ant.rx_chain_num == 2); + rt2800_bbp_write(rt2x00dev, 105, value); + + rt2800_bbp4_mac_if_ctrl(rt2x00dev); + + rt2800_bbp_write(rt2x00dev, 20, 0x06); + rt2800_bbp_write(rt2x00dev, 31, 0x08); + rt2800_bbp_write(rt2x00dev, 65, 0x2C); + rt2800_bbp_write(rt2x00dev, 68, 0xDD); + rt2800_bbp_write(rt2x00dev, 69, 0x1A); + rt2800_bbp_write(rt2x00dev, 70, 0x05); + rt2800_bbp_write(rt2x00dev, 73, 0x13); + rt2800_bbp_write(rt2x00dev, 74, 0x0F); + rt2800_bbp_write(rt2x00dev, 75, 0x4F); + rt2800_bbp_write(rt2x00dev, 76, 0x28); + rt2800_bbp_write(rt2x00dev, 77, 0x59); + rt2800_bbp_write(rt2x00dev, 84, 0x9A); + rt2800_bbp_write(rt2x00dev, 86, 0x38); + rt2800_bbp_write(rt2x00dev, 88, 0x90); + rt2800_bbp_write(rt2x00dev, 91, 0x04); + rt2800_bbp_write(rt2x00dev, 92, 0x02); + rt2800_bbp_write(rt2x00dev, 95, 0x9a); + rt2800_bbp_write(rt2x00dev, 98, 0x12); + rt2800_bbp_write(rt2x00dev, 103, 0xC0); + rt2800_bbp_write(rt2x00dev, 104, 0x92); + /* FIXME BBP105 owerwrite */ + rt2800_bbp_write(rt2x00dev, 105, 0x3C); + rt2800_bbp_write(rt2x00dev, 106, 0x35); + rt2800_bbp_write(rt2x00dev, 128, 0x12); + rt2800_bbp_write(rt2x00dev, 134, 0xD0); + rt2800_bbp_write(rt2x00dev, 135, 0xF6); + rt2800_bbp_write(rt2x00dev, 137, 0x0F); + + /* Initialize GLRT (Generalized Likehood Radio Test) */ + rt2800_init_bbp_5592_glrt(rt2x00dev); + + rt2800_bbp4_mac_if_ctrl(rt2x00dev); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); + ant = (div_mode == 3) ? 1 : 0; + rt2800_bbp_read(rt2x00dev, 152, &value); + if (ant == 0) { + /* Main antenna */ + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); + } else { + /* Auxiliary antenna */ + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); + } + rt2800_bbp_write(rt2x00dev, 152, value); + + if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) { + rt2800_bbp_read(rt2x00dev, 254, &value); + rt2x00_set_field8(&value, BBP254_BIT7, 1); + rt2800_bbp_write(rt2x00dev, 254, value); + } + + rt2800_bbp_write(rt2x00dev, 84, 0x19); +} + static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; @@ -3755,6 +3853,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; + if (rt2x00_rt(rt2x00dev, RT5592)) { + rt2800_init_bbp_5592(rt2x00dev); + return 0; + } + if (rt2x00_rt(rt2x00dev, RT3352)) { rt2800_bbp_write(rt2x00dev, 3, 0x00); rt2800_bbp_write(rt2x00dev, 4, 0x50); @@ -3762,11 +3865,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { - rt2800_bbp_read(rt2x00dev, 4, &value); - rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); - rt2800_bbp_write(rt2x00dev, 4, value); - } + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp4_mac_if_ctrl(rt2x00dev); if (rt2800_is_305x_soc(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290) || -- cgit From a4969d0d81215b153a76bdea4f242f0abd738e18 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:35 +0100 Subject: rt2800: 5592: common BBP initialization Add BBP registers initialization common with other chipsets, but for now performed only for 5592. Based on: NICInitBBP() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/common/rtmp_init.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 16e4200ec9e6..9ac6f202d102 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3774,12 +3774,34 @@ static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) } }; +static void rt2800_init_bbb_early(struct rt2x00_dev *rt2x00dev) +{ + rt2800_bbp_write(rt2x00dev, 65, 0x2C); + rt2800_bbp_write(rt2x00dev, 66, 0x38); + rt2800_bbp_write(rt2x00dev, 68, 0x0B); + rt2800_bbp_write(rt2x00dev, 69, 0x12); + rt2800_bbp_write(rt2x00dev, 70, 0x0a); + rt2800_bbp_write(rt2x00dev, 73, 0x10); + rt2800_bbp_write(rt2x00dev, 81, 0x37); + rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 83, 0x6A); + rt2800_bbp_write(rt2x00dev, 84, 0x99); + rt2800_bbp_write(rt2x00dev, 86, 0x00); + rt2800_bbp_write(rt2x00dev, 91, 0x04); + rt2800_bbp_write(rt2x00dev, 92, 0x00); + rt2800_bbp_write(rt2x00dev, 103, 0x00); + rt2800_bbp_write(rt2x00dev, 105, 0x05); + rt2800_bbp_write(rt2x00dev, 106, 0x35); +} + static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) { int ant, div_mode; u16 eeprom; u8 value; + rt2800_init_bbb_early(rt2x00dev); + rt2800_bbp_read(rt2x00dev, 105, &value); rt2x00_set_field8(&value, BBP105_MLD, rt2x00dev->default_ant.rx_chain_num == 2); -- cgit From 0c9e5fb9190ac484627c2a5afae81379f19af6ac Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:36 +0100 Subject: rt2800: 5592: RF early registers initialization Based on: NICInitRT5592RFRegisters() RF5592Reg_2G_5G[] from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c This patch also merge common frequency adjustment (RF_R17 settings) code. Further work is needed, to setup more RF/BBP/MAC registers after that. Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 76 ++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9ac6f202d102..57afd6b58bbd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1991,6 +1991,18 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, #define POWER_BOUND_5G 0x2b #define FREQ_OFFSET_BOUND 0x5f +static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev) +{ + u8 rfcsr; + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); +} + static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -2011,12 +2023,7 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + rt2800_adjust_freq_offset(rt2x00dev); if (rf->channel <= 14) { if (rf->channel == 6) @@ -2057,13 +2064,7 @@ static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev, else rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2); - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + rt2800_adjust_freq_offset(rt2x00dev); rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); @@ -2128,12 +2129,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + rt2800_adjust_freq_offset(rt2x00dev); if (rf->channel <= 14) { int idx = rf->channel-1; @@ -2423,12 +2419,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, } /* TODO proper frequency adjustment */ - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + rt2800_adjust_freq_offset(rt2x00dev); /* TODO merge with others */ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); @@ -4638,6 +4629,37 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 63, 0x07); } +static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) +{ + rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x4D); + rt2800_rfcsr_write(rt2x00dev, 20, 0x10); + rt2800_rfcsr_write(rt2x00dev, 21, 0x8D); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0C); + rt2800_rfcsr_write(rt2x00dev, 53, 0x22); + rt2800_rfcsr_write(rt2x00dev, 63, 0x07); + + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + msleep(1); + + rt2800_adjust_freq_offset(rt2x00dev); +} + static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; @@ -4655,6 +4677,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && !rt2x00_rt(rt2x00dev, RT5392) && + !rt2x00_rt(rt2x00dev, RT5392) && !rt2800_is_305x_soc(rt2x00dev)) return 0; @@ -4709,6 +4732,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) case RT5392: rt2800_init_rfcsr_5392(rt2x00dev); break; + case RT5592: + rt2800_init_rfcsr_5592(rt2x00dev); + break; } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { -- cgit From d8bbf90a6251953df09773dd232fcd6337c88d7a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:37 +0100 Subject: rt2800: 5592: initalize RF_R27 on older revisions Based on: NICInitRT5592RFRegisters() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 57afd6b58bbd..e6d2b14adea1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4832,7 +4832,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) + rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C)) rt2800_rfcsr_write(rt2x00dev, 27, 0x03); rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); -- cgit From 6e04f2530f6bd0274980f4992bf57952d3e0b17b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:38 +0100 Subject: rt2800: 5592: initalize BBP_R103 register on new revisions Based on: NICInitRT5592RFRegisters() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e6d2b14adea1..554bd9b5e1b8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3853,6 +3853,8 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) } rt2800_bbp_write(rt2x00dev, 84, 0x19); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) + rt2800_bbp_write(rt2x00dev, 103, 0xc0); } static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) -- cgit From a630afe4f8467d9b0c9f85a4ef2b839f1c5ba53c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:39 +0100 Subject: rt2800: 5592: initialize BBP_R138 register Based on: RT5592LoadRFNormalModeSetup() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 554bd9b5e1b8..12e43136fe3a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4859,7 +4859,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); } - if (rt2x00_rt(rt2x00dev, RT3090)) { + if (rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT5592)) { rt2800_bbp_read(rt2x00dev, 138, &bbp); /* Turn off unused DAC1 and ADC1 to reduce power consumption */ -- cgit From cf084c6ae078759b3d65d37b34de824500fc0623 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:40 +0100 Subject: rt2800: 5592: initialize RF_38/39/30 registers Based on: RT5592LoadRFNormalModeSetup() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 12e43136fe3a..54d9089f83ca 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4916,7 +4916,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) } if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT5592)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); -- cgit From c267548755a184ef97301071300c1739a564e135 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:41 +0100 Subject: rt2800: 5592: init frequency calibration Based on: InitFrequencyCalibrationMode() RT5592_ChipCap from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/common/frq_cal.c DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 54d9089f83ca..93b9def5f08a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3744,6 +3744,12 @@ static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 4, value); } +static void rt2800_init_freq_calibration(struct rt2x00_dev *rt2x00dev) +{ + rt2800_bbp_write(rt2x00dev, 142, 1); + rt2800_bbp_write(rt2x00dev, 143, 57); +} + static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) { const u8 glrt_table[] = { @@ -3852,6 +3858,8 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 254, value); } + rt2800_init_freq_calibration(rt2x00dev); + rt2800_bbp_write(rt2x00dev, 84, 0x19); if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); @@ -4155,9 +4163,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); rt2800_bbp_write(rt2x00dev, 152, value); - /* Init frequency calibration */ - rt2800_bbp_write(rt2x00dev, 142, 1); - rt2800_bbp_write(rt2x00dev, 143, 57); + rt2800_init_freq_calibration(rt2x00dev); } for (i = 0; i < EEPROM_BBP_SIZE; i++) { -- cgit From d5ae7a6bd09792ddf0e9dfaf97ad34b9ad6dc146 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:42 +0100 Subject: rt2800: 5592: setup LDO_CFG0 when configuring channel Based on: RT5592_ChipSwitchChannel() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 93b9def5f08a..189c8809009c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2187,12 +2187,17 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, struct channel_info *info) { u8 rfcsr, ep_reg; + u32 reg; int power_bound; /* TODO */ const bool is_11b = false; const bool is_type_ep = false; + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, + (rf->channel > 14 || conf_is_ht40(conf)) ? 5 : 0); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); /* Order of values on rf_channel entry: N, K, mod, R */ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1 & 0xff); -- cgit From 4bc618fdd1dfc990883a3aeb68b399d24cab1d24 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:43 +0100 Subject: rt2800: 5592: enable rf init Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 189c8809009c..1650cf434920 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4691,6 +4691,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT5390) && !rt2x00_rt(rt2x00dev, RT5392) && !rt2x00_rt(rt2x00dev, RT5392) && + !rt2x00_rt(rt2x00dev, RT5592) && !rt2800_is_305x_soc(rt2x00dev)) return 0; -- cgit From 6803141b4fe53ab88683d70c1612e0f450c0cb1d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:44 +0100 Subject: rt2800: 5592: more channel switch registers settings (BBP & GLRT) Based on: RT5592_ChipSwitchChannel() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 1650cf434920..c990ab8b1d24 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2430,6 +2430,30 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + + /* BBP settings */ + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + + rt2800_bbp_write(rt2x00dev, 79, (rf->channel <= 14) ? 0x1C : 0x18); + rt2800_bbp_write(rt2x00dev, 80, (rf->channel <= 14) ? 0x0E : 0x08); + rt2800_bbp_write(rt2x00dev, 81, (rf->channel <= 14) ? 0x3A : 0x38); + rt2800_bbp_write(rt2x00dev, 82, (rf->channel <= 14) ? 0x62 : 0x92); + + /* GLRT band configuration */ + rt2800_bbp_write(rt2x00dev, 195, 128); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0xE0 : 0xF0); + rt2800_bbp_write(rt2x00dev, 195, 129); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x1F : 0x1E); + rt2800_bbp_write(rt2x00dev, 195, 130); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x38 : 0x28); + rt2800_bbp_write(rt2x00dev, 195, 131); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x32 : 0x20); + rt2800_bbp_write(rt2x00dev, 195, 133); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x28 : 0x7F); + rt2800_bbp_write(rt2x00dev, 195, 124); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, @@ -2577,6 +2601,14 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rt2x00_rt(rt2x00dev, RT3572)) rt2800_rfcsr_write(rt2x00dev, 8, 0x80); + if (rt2x00_rt(rt2x00dev, RT5592)) { + rt2800_bbp_write(rt2x00dev, 195, 141); + rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); + + /* TODO AGC adjust */ + /* TODO IQ calibration */ + } + rt2800_bbp_read(rt2x00dev, 4, &bbp); rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); rt2800_bbp_write(rt2x00dev, 4, bbp); -- cgit From 8756130bf3fb9e4adc96bb6bc4774573e261c5b7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:45 +0100 Subject: rt2800: 5592: add iq calibration Based on: GetIQCalibration() IQCalibration() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rtmp_chip.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 55 +++++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 41 ++++++++++++++++++++++-- drivers/net/wireless/rt2x00/rt2x00.h | 9 ++++-- 3 files changed, 101 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9d18d5384be7..25c94b596e93 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2531,6 +2531,61 @@ struct mac_iveiv_entry { #define EEPROM_BBP_VALUE FIELD16(0x00ff) #define EEPROM_BBP_REG_ID FIELD16(0xff00) +/* + * EEPROM IQ Calibration, unlike other entries those are byte addresses. + */ + +#define EEPROM_IQ_GAIN_CAL_TX0_2G 0x130 +#define EEPROM_IQ_PHASE_CAL_TX0_2G 0x131 +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_2G 0x132 +#define EEPROM_IQ_GAIN_CAL_TX1_2G 0x133 +#define EEPROM_IQ_PHASE_CAL_TX1_2G 0x134 +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_2G 0x135 +#define EEPROM_IQ_GAIN_CAL_RX0_2G 0x136 +#define EEPROM_IQ_PHASE_CAL_RX0_2G 0x137 +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_2G 0x138 +#define EEPROM_IQ_GAIN_CAL_RX1_2G 0x139 +#define EEPROM_IQ_PHASE_CAL_RX1_2G 0x13A +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_2G 0x13B +#define EEPROM_RF_IQ_COMPENSATION_CONTROL 0x13C +#define EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL 0x13D +#define EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G 0x144 +#define EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G 0x145 +#define EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G 0X146 +#define EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G 0x147 +#define EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G 0x148 +#define EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G 0x149 +#define EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G 0x14A +#define EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G 0x14B +#define EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G 0X14C +#define EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G 0x14D +#define EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G 0x14E +#define EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G 0x14F +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH36_TO_CH64_5G 0x150 +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH36_TO_CH64_5G 0x151 +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH100_TO_CH138_5G 0x152 +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH100_TO_CH138_5G 0x153 +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH140_TO_CH165_5G 0x154 +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH140_TO_CH165_5G 0x155 +#define EEPROM_IQ_GAIN_CAL_RX0_CH36_TO_CH64_5G 0x156 +#define EEPROM_IQ_PHASE_CAL_RX0_CH36_TO_CH64_5G 0x157 +#define EEPROM_IQ_GAIN_CAL_RX0_CH100_TO_CH138_5G 0X158 +#define EEPROM_IQ_PHASE_CAL_RX0_CH100_TO_CH138_5G 0x159 +#define EEPROM_IQ_GAIN_CAL_RX0_CH140_TO_CH165_5G 0x15A +#define EEPROM_IQ_PHASE_CAL_RX0_CH140_TO_CH165_5G 0x15B +#define EEPROM_IQ_GAIN_CAL_RX1_CH36_TO_CH64_5G 0x15C +#define EEPROM_IQ_PHASE_CAL_RX1_CH36_TO_CH64_5G 0x15D +#define EEPROM_IQ_GAIN_CAL_RX1_CH100_TO_CH138_5G 0X15E +#define EEPROM_IQ_PHASE_CAL_RX1_CH100_TO_CH138_5G 0x15F +#define EEPROM_IQ_GAIN_CAL_RX1_CH140_TO_CH165_5G 0x160 +#define EEPROM_IQ_PHASE_CAL_RX1_CH140_TO_CH165_5G 0x161 +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH36_TO_CH64_5G 0x162 +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH36_TO_CH64_5G 0x163 +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH100_TO_CH138_5G 0x164 +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH100_TO_CH138_5G 0x165 +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH140_TO_CH165_5G 0x166 +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH140_TO_CH165_5G 0x167 + /* * MCU mailbox commands. * MCU_SLEEP - go to power-save mode. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c990ab8b1d24..e96ea3298c7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -527,8 +527,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); - if (rt2x00_is_usb(rt2x00dev)) + if (rt2x00_is_usb(rt2x00dev)) { rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + } msleep(1); return 0; @@ -2456,6 +2458,41 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); } +static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel) +{ + u8 cal; + + /* TODO */ + if (WARN_ON_ONCE(channel > 14)) + return; + + rt2800_bbp_write(rt2x00dev, 158, 0x2c); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX0_2G); + rt2800_bbp_write(rt2x00dev, 159, cal); + + rt2800_bbp_write(rt2x00dev, 158, 0x2d); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX0_2G); + rt2800_bbp_write(rt2x00dev, 159, cal); + + rt2800_bbp_write(rt2x00dev, 158, 0x4a); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX1_2G); + rt2800_bbp_write(rt2x00dev, 159, cal); + + rt2800_bbp_write(rt2x00dev, 158, 0x4b); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX1_2G); + rt2800_bbp_write(rt2x00dev, 159, cal); + + /* RF IQ compensation control */ + rt2800_bbp_write(rt2x00dev, 158, 0x04); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_COMPENSATION_CONTROL); + rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); + + /* RF IQ imbalance compensation control */ + rt2800_bbp_write(rt2x00dev, 158, 0x03); + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL); + rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); +} + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -2606,7 +2643,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); /* TODO AGC adjust */ - /* TODO IQ calibration */ + rt2800_iq_calibrate(rt2x00dev, rf->channel); } rt2800_bbp_read(rt2x00dev, 4, &bbp); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 425183570f35..51922cc179de 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1065,8 +1065,7 @@ static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, } /* - * Generic EEPROM access. - * The EEPROM is being accessed by word index. + * Generic EEPROM access. The EEPROM is being accessed by word or byte index. */ static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, const unsigned int word) @@ -1086,6 +1085,12 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, rt2x00dev->eeprom[word] = cpu_to_le16(data); } +static inline u8 rt2x00_eeprom_byte(struct rt2x00_dev *rt2x00dev, + const unsigned int byte) +{ + return *(((u8 *)rt2x00dev->eeprom) + byte); +} + /* * Chipset handlers */ -- cgit From c630ccf1a127578421a928489d51e99c05037054 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:46 +0100 Subject: rt2800: rearrange bbp/rfcsr initialization This makes order of initialization of various registers similar like on vendor driver. Based on: NICInitializeAsic() RT5592LoadRFNormalModeSetup() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/common/rtmp_init.c DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chip/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 50 +++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e96ea3298c7c..e36cf4a233fe 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4713,6 +4713,9 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) { + u8 reg; + u16 eeprom; + rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); rt2800_rfcsr_write(rt2x00dev, 3, 0x08); rt2800_rfcsr_write(rt2x00dev, 3, 0x08); @@ -4740,6 +4743,35 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) msleep(1); rt2800_adjust_freq_offset(rt2x00dev); + + rt2800_bbp_read(rt2x00dev, 138, ®); + + /* Turn off unused DAC1 and ADC1 to reduce power consumption */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) + rt2x00_set_field8(®, BBP138_RX_ADC1, 0); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) + rt2x00_set_field8(®, BBP138_TX_DAC1, 1); + + rt2800_bbp_write(rt2x00dev, 138, reg); + + /* Enable DC filter */ + if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + + rt2800_rfcsr_read(rt2x00dev, 38, ®); + rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 38, reg); + + rt2800_rfcsr_read(rt2x00dev, 39, ®); + rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 39, reg); + + rt2800_bbp4_mac_if_ctrl(rt2x00dev); + + rt2800_rfcsr_read(rt2x00dev, 30, ®); + rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); + rt2800_rfcsr_write(rt2x00dev, 30, reg); } static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) @@ -4817,7 +4849,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) break; case RT5592: rt2800_init_rfcsr_5592(rt2x00dev); - break; + return 0; } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -5024,15 +5056,23 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) * Initialize all registers. */ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800_init_registers(rt2x00dev) || - rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + rt2800_init_registers(rt2x00dev))) return -EIO; /* * Send signal to firmware during boot time. */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); + rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + if (rt2x00_is_usb(rt2x00dev)) { + rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + } + msleep(1); + + if (unlikely(rt2800_init_bbp(rt2x00dev) || + rt2800_init_rfcsr(rt2x00dev))) + return -EIO; if (rt2x00_is_usb(rt2x00dev) && (rt2x00_rt(rt2x00dev, RT3070) || -- cgit From 5bc2dd0646106181f3591fa18d9a6881c6fe6edf Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:47 +0100 Subject: rt2800: add write_with_rx_chain function Based on: AsicBBPWriteWithRxChain() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rtmp_chip.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 3 +++ drivers/net/wireless/rt2x00/rt2800lib.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 25c94b596e93..6105243f215f 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1939,6 +1939,9 @@ struct mac_iveiv_entry { #define BBP4_BANDWIDTH FIELD8(0x18) #define BBP4_MAC_IF_CTRL FIELD8(0x40) +/* BBP27 */ +#define BBP27_RX_CHAIN_SEL FIELD8(0x60) + /* * BBP 47: Bandwidth */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e36cf4a233fe..9fa10b035968 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2458,6 +2458,22 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); } +static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, + const unsigned int word, + const u8 value) +{ + u8 chain, reg; + + for (chain = 0; chain < rt2x00dev->default_ant.rx_chain_num; chain++) { + rt2800_bbp_read(rt2x00dev, 27, ®); + rt2x00_set_field8(®, BBP27_RX_CHAIN_SEL, chain); + rt2800_bbp_write(rt2x00dev, 27, reg); + + rt2800_bbp_write(rt2x00dev, word, value); + } +} + + static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel) { u8 cal; -- cgit From 8ba0ebf330a27d3b390ed46866455cd122d636f1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:48 +0100 Subject: rt2800: 5592: add AGC init Based on: RT5592_RTMPAGCInit() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9fa10b035968..f2446ded2a04 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2658,7 +2658,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 195, 141); rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); - /* TODO AGC adjust */ + /* AGC init */ + reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain; + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); + rt2800_iq_calibrate(rt2x00dev, rf->channel); } -- cgit From 3d81535ea5940446510a8a5cee1c6ad23c90c753 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:49 +0100 Subject: rt2800: 5592: add chip specific vgc calculations Based on: RT5592_ChipAGCAdjust() from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/chips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index f2446ded2a04..5adb92b387dc 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3277,13 +3277,16 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT5592)) vgc = 0x1c + (2 * rt2x00dev->lna_gain); else vgc = 0x2e + rt2x00dev->lna_gain; } else { /* 5GHZ band */ if (rt2x00_rt(rt2x00dev, RT3572)) vgc = 0x22 + (rt2x00dev->lna_gain * 5) / 3; + else if (rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x24 + (2 * rt2x00dev->lna_gain); else { if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) vgc = 0x32 + (rt2x00dev->lna_gain * 5) / 3; @@ -3299,7 +3302,11 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, u8 vgc_level) { if (qual->vgc_level != vgc_level) { - rt2800_bbp_write(rt2x00dev, 66, vgc_level); + if (rt2x00_rt(rt2x00dev, RT5592)) { + rt2800_bbp_write(rt2x00dev, 83, qual->rssi > -65 ? 0x4a : 0x7a); + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); + } else + rt2800_bbp_write(rt2x00dev, 66, vgc_level); qual->vgc_level = vgc_level; qual->vgc_level_reg = vgc_level; } @@ -3314,15 +3321,23 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner); void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count) { + u8 vgc; + if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) return; - /* - * When RSSI is better then -80 increase VGC level with 0x10 + * When RSSI is better then -80 increase VGC level with 0x10, except + * for rt5592 chip. */ - rt2800_set_vgc(rt2x00dev, qual, - rt2800_get_default_vgc(rt2x00dev) + - ((qual->rssi > -80) * 0x10)); + + vgc = rt2800_get_default_vgc(rt2x00dev); + + if (rt2x00_rt(rt2x00dev, RT5592) && qual->rssi > -65) + vgc += 0x20; + else if (qual->rssi > -80) + vgc += 0x10; + + rt2800_set_vgc(rt2x00dev, qual, vgc); } EXPORT_SYMBOL_GPL(rt2800_link_tuner); -- cgit From 613c75fc4ee854e84f737ea8906a94104879c4c4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:50 +0100 Subject: rt2800: 5592: TXWI & RXWI descriptors size Based on: TXWI_STRUC RXWI_STRUC from: DPO_RT5572_LinuxSTA_2.6.1.3_20121022/include/chip/rtmp_mac.h Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 2 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ---- drivers/net/wireless/rt2x00/rt2800pci.c | 5 ++++ drivers/net/wireless/rt2x00/rt2800usb.c | 53 +++++++++++++++++++++++++++++++-- 4 files changed, 58 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 6105243f215f..a7630d5ec892 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2628,6 +2628,8 @@ struct mac_iveiv_entry { #define TXWI_DESC_SIZE (4 * sizeof(__le32)) #define RXWI_DESC_SIZE (4 * sizeof(__le32)) +#define TXWI_DESC_SIZE_5592 (5 * sizeof(__le32)) +#define RXWI_DESC_SIZE_5592 (6 * sizeof(__le32)) /* * TX WI structure */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5adb92b387dc..9b1f293b4833 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -676,11 +676,6 @@ void rt2800_process_rxwi(struct queue_entry *entry, * Convert descriptor AGC value to RSSI value. */ rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); - - /* - * Remove RXWI descriptor from start of buffer. - */ - skb_pull(entry->skb, RXWI_DESC_SIZE); } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 80cf8d745c6f..f732ded8f1ba 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -729,6 +729,11 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure that is at the start of the buffer. */ rt2800_process_rxwi(entry, rxdesc); + + /* + * Remove RXWI descriptor from start of buffer. + */ + skb_pull(entry->skb, RXWI_DESC_SIZE); } /* diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f9ca79503252..9b1ca672f6ca 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -485,7 +485,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, */ skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = txi; - skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; + skbdesc->desc_len = entry->queue->desc_size; } /* @@ -730,6 +730,11 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure. */ rt2800_process_rxwi(entry, rxdesc); + + /* + * Remove RXWI descriptor from start of buffer. + */ + skb_pull(entry->skb, entry->queue->desc_size - RXINFO_DESC_SIZE); } /* @@ -890,6 +895,47 @@ static const struct rt2x00_ops rt2800usb_ops = { #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ }; +static const struct data_queue_desc rt2800usb_queue_rx_5592 = { + .entry_num = 128, + .data_size = AGGREGATION_SIZE, + .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE_5592, + .priv_size = sizeof(struct queue_entry_priv_usb), +}; + +static const struct data_queue_desc rt2800usb_queue_tx_5592 = { + .entry_num = 16, + .data_size = AGGREGATION_SIZE, + .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, + .priv_size = sizeof(struct queue_entry_priv_usb), +}; + +static const struct data_queue_desc rt2800usb_queue_bcn_5592 = { + .entry_num = 8, + .data_size = MGMT_FRAME_SIZE, + .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, + .priv_size = sizeof(struct queue_entry_priv_usb), +}; + + +static const struct rt2x00_ops rt2800usb_ops_5592 = { + .name = KBUILD_MODNAME, + .drv_data_size = sizeof(struct rt2800_drv_data), + .max_ap_intf = 8, + .eeprom_size = EEPROM_SIZE, + .rf_size = RF_SIZE, + .tx_queues = NUM_TX_QUEUES, + .extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, + .rx = &rt2800usb_queue_rx_5592, + .tx = &rt2800usb_queue_tx_5592, + .bcn = &rt2800usb_queue_bcn_5592, + .lib = &rt2800usb_rt2x00_ops, + .drv = &rt2800usb_rt2800_ops, + .hw = &rt2800usb_mac80211_ops, +#ifdef CONFIG_RT2X00_LIB_DEBUGFS + .debugfs = &rt2800_rt2x00debug, +#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ +}; + /* * rt2800usb module information. */ @@ -1201,7 +1247,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x5372) }, #endif #ifdef CONFIG_RT2800USB_RT55XX - { USB_DEVICE(0x148f, 0x5572) }, + { USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 }, #endif #ifdef CONFIG_RT2800USB_UNKNOWN /* @@ -1306,6 +1352,9 @@ MODULE_LICENSE("GPL"); static int rt2800usb_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { + if (id->driver_info == 5592) + return rt2x00usb_probe(usb_intf, &rt2800usb_ops_5592); + return rt2x00usb_probe(usb_intf, &rt2800usb_ops); } -- cgit From 939ec51dc7d055bb2cb8977a4c026d9dc85438dd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:51 +0100 Subject: rt2800: 5592: add Kconfig Enable support to 5592 chip. Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 2bf4efa33186..ffe61d53e3fe 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -169,6 +169,13 @@ config RT2800USB_RT53XX rt2800usb driver. Supported chips: RT5370 +config RT2800USB_RT55XX + bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)" + ---help--- + This adds support for rt55xx wireless chipset family to the + rt2800usb driver. + Supported chips: RT5572 + config RT2800USB_UNKNOWN bool "rt2800usb - Include support for unknown (USB) devices" default n -- cgit From 415e3f2f7bf8bff1a22446c22a7e384c6f429d2a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:52 +0100 Subject: rt2800: 5592: iq calibration for 5GHz Based on: RT5592_IQCalibration() DPO_RT5572_LinuxSTA_2.6.1.3_20121022/cips/rt5592.c Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 70 ++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9b1f293b4833..f08a0424fe4d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2468,31 +2468,80 @@ static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, } } - static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel) { u8 cal; - /* TODO */ - if (WARN_ON_ONCE(channel > 14)) - return; - + /* TX0 IQ Gain */ rt2800_bbp_write(rt2x00dev, 158, 0x2c); - cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX0_2G); + if (channel <= 14) + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX0_2G); + else if (channel >= 36 && channel <= 64) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G); + else if (channel >= 100 && channel <= 138) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G); + else if (channel >= 140 && channel <= 165) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G); + else + cal = 0; rt2800_bbp_write(rt2x00dev, 159, cal); + /* TX0 IQ Phase */ rt2800_bbp_write(rt2x00dev, 158, 0x2d); - cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX0_2G); + if (channel <= 14) + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX0_2G); + else if (channel >= 36 && channel <= 64) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G); + else if (channel >= 100 && channel <= 138) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G); + else if (channel >= 140 && channel <= 165) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G); + else + cal = 0; rt2800_bbp_write(rt2x00dev, 159, cal); + /* TX1 IQ Gain */ rt2800_bbp_write(rt2x00dev, 158, 0x4a); - cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX1_2G); + if (channel <= 14) + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX1_2G); + else if (channel >= 36 && channel <= 64) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G); + else if (channel >= 100 && channel <= 138) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G); + else if (channel >= 140 && channel <= 165) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G); + else + cal = 0; rt2800_bbp_write(rt2x00dev, 159, cal); + /* TX1 IQ Phase */ rt2800_bbp_write(rt2x00dev, 158, 0x4b); - cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX1_2G); + if (channel <= 14) + cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX1_2G); + else if (channel >= 36 && channel <= 64) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G); + else if (channel >= 100 && channel <= 138) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G); + else if (channel >= 140 && channel <= 165) + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G); + else + cal = 0; rt2800_bbp_write(rt2x00dev, 159, cal); + /* FIXME: possible RX0, RX1 callibration ? */ + /* RF IQ compensation control */ rt2800_bbp_write(rt2x00dev, 158, 0x04); cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_COMPENSATION_CONTROL); @@ -2500,7 +2549,8 @@ static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel) /* RF IQ imbalance compensation control */ rt2800_bbp_write(rt2x00dev, 158, 0x03); - cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL); + cal = rt2x00_eeprom_byte(rt2x00dev, + EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL); rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); } -- cgit From 856a850afdd778fad7ded4240d333a8c3b05b136 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 16 Mar 2013 19:19:53 +0100 Subject: rt2800: 5592: add more USB devices IDs Reported-by: Xose Vazquez Perez Signed-off-by: Stanislaw Gruszka Tested-by: Wanlong Gao Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9b1ca672f6ca..f32282009146 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1247,6 +1247,15 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x5372) }, #endif #ifdef CONFIG_RT2800USB_RT55XX + /* Arcadyan */ + { USB_DEVICE(0x043e, 0x7a32), .driver_info = 5592 }, + /* AVM GmbH */ + { USB_DEVICE(0x057c, 0x8501), .driver_info = 5592 }, + /* D-Link DWA-160-B2 */ + { USB_DEVICE(0x2001, 0x3c1a), .driver_info = 5592 }, + /* Proware */ + { USB_DEVICE(0x043e, 0x7a13), .driver_info = 5592 }, + /* Ralink */ { USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 }, #endif #ifdef CONFIG_RT2800USB_UNKNOWN -- cgit From da508f5799659241a359e2d07abb8af905f6291c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 4 Mar 2013 16:52:36 -0300 Subject: [media] media/v4l2: VIDEOBUF2_DMA_CONTIG should depend on HAS_DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit m68k/sun3: drivers/media/v4l2-core/videobuf2-dma-contig.c: In function ‘vb2_dc_mmap’: drivers/media/v4l2-core/videobuf2-dma-contig.c:204: error: implicit declaration of function ‘dma_mmap_coherent’ drivers/media/v4l2-core/videobuf2-dma-contig.c: In function ‘vb2_dc_get_base_sgt’: drivers/media/v4l2-core/videobuf2-dma-contig.c:387: error: implicit declaration of function ‘dma_get_sgtable’ Make VIDEOBUF2_DMA_CONTIG and VIDEO_SH_VEU (which selects the former and doesn't have a platform dependency) depend on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 2 +- drivers/media/v4l2-core/Kconfig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 05d7b6333461..42c62aa33e11 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" - depends on VIDEO_DEV && VIDEO_V4L2 + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 976d029e9925..8c05565a240e 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -67,6 +67,7 @@ config VIDEOBUF2_MEMOPS config VIDEOBUF2_DMA_CONTIG tristate + depends on HAS_DMA select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS select DMA_SHARED_BUFFER -- cgit From c7a45e5b4f8c2f96cd242ae1b1c06e7fb19a08d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Mar 2013 06:55:26 -0300 Subject: [media] em28xx: Prepare to support 2 different I2C buses Newer em28xx devices have 2 buses. Change the logic to allow using both buses. This patch was generated by this small script: for i in drivers/media/usb/em28xx/*.c; do sed 's,->i2c_adap,->i2c_adap[dev->def_i2c_bus],g;s,->i2c_client,->i2c_client[dev->def_i2c_bus],' done Of course, em28xx.h needed manual edit. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 32 ++++++------ drivers/media/usb/em28xx/em28xx-dvb.c | 86 ++++++++++++++++----------------- drivers/media/usb/em28xx/em28xx-i2c.c | 30 ++++++------ drivers/media/usb/em28xx/em28xx-input.c | 5 +- drivers/media/usb/em28xx/em28xx.h | 10 +++- 5 files changed, 85 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 4dcef9d6d561..d81f7ee94c41 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2249,7 +2249,7 @@ static int em28xx_initialize_mt9m111(struct em28xx *dev) }; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, ®s[i][0], 3); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], ®s[i][0], 3); return 0; } @@ -2276,7 +2276,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev) }; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, ®s[i][0], 3); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], ®s[i][0], 3); return 0; } @@ -2294,10 +2294,10 @@ static int em28xx_hint_sensor(struct em28xx *dev) u16 version; /* Micron sensor detection */ - dev->i2c_client.addr = 0xba >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0xba >> 1; cmd = 0; - i2c_master_send(&dev->i2c_client, &cmd, 1); - rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], &cmd, 1); + rc = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], (char *)&version_be, 2); if (rc != 2) return -EINVAL; @@ -2748,8 +2748,8 @@ static void em28xx_card_setup(struct em28xx *dev) #endif /* Call first TVeeprom */ - dev->i2c_client.addr = 0xa0 >> 1; - tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); + dev->i2c_client[dev->def_i2c_bus].addr = 0xa0 >> 1; + tveeprom_hauppauge_analog(&dev->i2c_client[dev->def_i2c_bus], &tv, dev->eedata); dev->tuner_type = tv.tuner_type; @@ -2841,15 +2841,15 @@ static void em28xx_card_setup(struct em28xx *dev) /* request some modules */ if (dev->board.has_msp34xx) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "msp3400", 0, msp3400_addrs); if (dev->board.decoder == EM28XX_SAA711X) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "saa7115_auto", 0, saa711x_addrs); if (dev->board.decoder == EM28XX_TVP5150) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "tvp5150", 0, tvp5150_addrs); if (dev->em28xx_sensor == EM28XX_MT9V011) { @@ -2861,25 +2861,25 @@ static void em28xx_card_setup(struct em28xx *dev) }; pdata.xtal = dev->sensor_xtal; - v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], &mt9v011_info, NULL); } if (dev->board.adecoder == EM28XX_TVAUDIO) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "tvaudio", dev->board.tvaudio_addr, NULL); if (dev->board.tuner_type != TUNER_ABSENT) { int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); if (dev->board.radio.type) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "tuner", dev->board.radio_addr, NULL); if (has_demod) v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, "tuner", + &dev->i2c_adap[dev->def_i2c_bus], "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (dev->tuner_addr == 0) { enum v4l2_i2c_tuner_type type = @@ -2887,13 +2887,13 @@ static void em28xx_card_setup(struct em28xx *dev) struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, "tuner", + &dev->i2c_adap[dev->def_i2c_bus], "tuner", 0, v4l2_i2c_tuner_addrs(type)); if (sd) dev->tuner_addr = v4l2_i2c_subdev_addr(sd); } else { - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, + v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], "tuner", dev->tuner_addr, NULL); } } diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 7200dfe59ef9..98b95be3be6e 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -463,10 +463,10 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); msleep(10); - dev->i2c_client.addr = 0x82 >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); em28xx_gpio_set(dev, hauppauge_hvr930c_end); msleep(100); @@ -520,10 +520,10 @@ static void terratec_h5_init(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); msleep(10); - dev->i2c_client.addr = 0x82 >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_h5_end); }; @@ -573,10 +573,10 @@ static void terratec_htc_stick_init(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); msleep(10); - dev->i2c_client.addr = 0x82 >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_htc_stick_end); }; @@ -631,10 +631,10 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); msleep(10); - dev->i2c_client.addr = 0x82 >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); em28xx_gpio_set(dev, terratec_htc_usb_xs_end); }; @@ -660,10 +660,10 @@ static void pctv_520e_init(struct em28xx *dev) {{ 0x01, 0x00, 0x73, 0xaf }, 4}, }; - dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */ + dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; /* 0x41 */ for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); }; static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) @@ -777,7 +777,7 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) struct xc2028_config cfg; memset(&cfg, 0, sizeof(cfg)); - cfg.i2c_adap = &dev->i2c_adap; + cfg.i2c_adap = &dev->i2c_adap[dev->def_i2c_bus]; cfg.i2c_addr = addr; if (!dev->dvb->fe[0]) { @@ -960,7 +960,7 @@ static int em28xx_dvb_init(struct em28xx *dev) switch (dev->model) { case EM2874_BOARD_LEADERSHIP_ISDBT: dvb->fe[0] = dvb_attach(s921_attach, - &sharp_isdbt, &dev->i2c_adap); + &sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; @@ -974,7 +974,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -983,7 +983,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_KWORLD_DVB_310U: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -994,7 +994,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1007,13 +1007,13 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2882_BOARD_KWORLD_VS_DVBT: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] == NULL) { /* This board could have either a zl10353 or a mt352. If the chip id isn't for zl10353, try mt352 */ dvb->fe[0] = dvb_attach(mt352_attach, &terratec_xs_mt352_cfg, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); } if (em28xx_attach_xc3028(0x61, dev) < 0) { @@ -1024,16 +1024,16 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2870_BOARD_KWORLD_355U: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_no_i2c_gate_dev, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) dvb_attach(qt1010_attach, dvb->fe[0], - &dev->i2c_adap, &em28xx_qt1010_config); + &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config); break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->fe[0] = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1042,10 +1042,10 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2882_BOARD_KWORLD_ATSC_315U: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], - &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { + &dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } @@ -1054,7 +1054,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, - &dev->i2c_adap, &dev->udev->dev); + &dev->i2c_adap[dev->def_i2c_bus], &dev->udev->dev); if (em28xx_attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; @@ -1064,10 +1064,10 @@ static int em28xx_dvb_init(struct em28xx *dev) /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ dvb->fe[0] = dvb_attach(tda10023_attach, &em28xx_tda10023_config, - &dev->i2c_adap, 0x48); + &dev->i2c_adap[dev->def_i2c_bus], 0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], - &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { + &dev->i2c_adap[dev->def_i2c_bus], 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } @@ -1076,10 +1076,10 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2870_BOARD_KWORLD_A340: dvb->fe[0] = dvb_attach(lgdt3305_attach, &em2870_lgdt3304_dev, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, &kworld_a340_config); + &dev->i2c_adap[dev->def_i2c_bus], &kworld_a340_config); break; case EM28174_BOARD_PCTV_290E: /* set default GPIO0 for LNA, used if GPIOLIB is undefined */ @@ -1087,14 +1087,14 @@ static int em28xx_dvb_init(struct em28xx *dev) CXD2820R_GPIO_L; dvb->fe[0] = dvb_attach(cxd2820r_attach, &em28xx_cxd2820r_config, - &dev->i2c_adap, + &dev->i2c_adap[dev->def_i2c_bus], &dvb->lna_gpio); if (dvb->fe[0]) { /* FE 0 attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, + &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[0]); @@ -1124,7 +1124,7 @@ static int em28xx_dvb_init(struct em28xx *dev) hauppauge_hvr930c_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, - &hauppauge_930c_drxk, &dev->i2c_adap); + &hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1142,7 +1142,7 @@ static int em28xx_dvb_init(struct em28xx *dev) if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); - if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, + if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], &cfg)) { result = -EINVAL; goto out_free; @@ -1155,7 +1155,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); - dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap); + dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1169,7 +1169,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* Attach tda18271 to DVB-C frontend */ if (dvb->fe[0]->ops.i2c_gate_ctrl) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); - if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap, 0x60)) { + if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { result = -EINVAL; goto out_free; } @@ -1180,17 +1180,17 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM28174_BOARD_PCTV_460E: /* attach demod */ dvb->fe[0] = dvb_attach(tda10071_attach, - &em28xx_tda10071_config, &dev->i2c_adap); + &em28xx_tda10071_config, &dev->i2c_adap[dev->def_i2c_bus]); /* attach SEC */ if (dvb->fe[0]) - dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap, + dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], &em28xx_a8293_config); break; case EM2874_BOARD_MAXMEDIA_UB425_TC: /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* disable I2C-gate */ @@ -1198,7 +1198,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach tuner */ if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], - &dev->i2c_adap, 0x60)) { + &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; @@ -1216,12 +1216,12 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { /* attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, + &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; @@ -1234,7 +1234,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1242,7 +1242,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, + &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { result = -EINVAL; goto out_free; @@ -1253,7 +1253,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach demodulator */ dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, - &dev->i2c_adap); + &dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; @@ -1261,7 +1261,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, + &dev->i2c_adap[dev->def_i2c_bus], &em28xx_cxd2820r_tda18271_config)) { result = -EINVAL; goto out_free; diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 6152423bef76..9086e57914e6 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -384,7 +384,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, /* Select address */ buf[0] = addr >> 8; buf[1] = addr & 0xff; - ret = i2c_master_send(&dev->i2c_client, buf + !addr_w16, 1 + addr_w16); + ret = i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], buf + !addr_w16, 1 + addr_w16); if (ret < 0) return ret; /* Read data */ @@ -398,7 +398,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, else rsize = remain; - ret = i2c_master_recv(&dev->i2c_client, data, rsize); + ret = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], data, rsize); if (ret < 0) return ret; @@ -422,10 +422,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) *eedata = NULL; *eedata_len = 0; - dev->i2c_client.addr = 0xa0 >> 1; + dev->i2c_client[dev->def_i2c_bus].addr = 0xa0 >> 1; /* Check if board has eeprom */ - err = i2c_master_recv(&dev->i2c_client, &buf, 0); + err = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], &buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); return -ENODEV; @@ -652,8 +652,8 @@ void em28xx_do_i2c_scan(struct em28xx *dev) memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { - dev->i2c_client.addr = i; - rc = i2c_master_recv(&dev->i2c_client, &buf, 0); + dev->i2c_client[dev->def_i2c_bus].addr = i; + rc = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], &buf, 0); if (rc < 0) continue; i2c_devicelist[i] = i; @@ -675,21 +675,21 @@ int em28xx_i2c_register(struct em28xx *dev) BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); - dev->i2c_adap = em28xx_adap_template; - dev->i2c_adap.dev.parent = &dev->udev->dev; - strcpy(dev->i2c_adap.name, dev->name); - dev->i2c_adap.algo_data = dev; - i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); + dev->i2c_adap[dev->def_i2c_bus] = em28xx_adap_template; + dev->i2c_adap[dev->def_i2c_bus].dev.parent = &dev->udev->dev; + strcpy(dev->i2c_adap[dev->def_i2c_bus].name, dev->name); + dev->i2c_adap[dev->def_i2c_bus].algo_data = dev; + i2c_set_adapdata(&dev->i2c_adap[dev->def_i2c_bus], &dev->v4l2_dev); - retval = i2c_add_adapter(&dev->i2c_adap); + retval = i2c_add_adapter(&dev->i2c_adap[dev->def_i2c_bus]); if (retval < 0) { em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", __func__, retval); return retval; } - dev->i2c_client = em28xx_client_template; - dev->i2c_client.adapter = &dev->i2c_adap; + dev->i2c_client[dev->def_i2c_bus] = em28xx_client_template; + dev->i2c_client[dev->def_i2c_bus].adapter = &dev->i2c_adap[dev->def_i2c_bus]; retval = em28xx_i2c_eeprom(dev, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { @@ -711,6 +711,6 @@ int em28xx_i2c_register(struct em28xx *dev) */ int em28xx_i2c_unregister(struct em28xx *dev) { - i2c_del_adapter(&dev->i2c_adap); + i2c_del_adapter(&dev->i2c_adap[dev->def_i2c_bus]); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 1bef990b3f18..466b19d0d767 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -280,11 +280,12 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) { + struct em28xx *dev = ir->dev; static u32 ir_key; int rc; struct i2c_client client; - client.adapter = &ir->dev->i2c_adap; + client.adapter = &ir->dev->i2c_adap[dev->def_i2c_bus]; client.addr = ir->i2c_dev_addr; rc = ir->get_key_i2c(&client, &ir_key); @@ -461,7 +462,7 @@ static int em28xx_probe_i2c_ir(struct em28xx *dev) }; while (addr_list[i] != I2C_CLIENT_END) { - if (i2c_probe_func_quick_read(&dev->i2c_adap, addr_list[i]) == 1) + if (i2c_probe_func_quick_read(&dev->i2c_adap[dev->def_i2c_bus], addr_list[i]) == 1) return addr_list[i]; i++; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 2d6d31ace733..5de7b6c93857 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -157,6 +157,9 @@ #define EM28XX_NUM_BUFS 5 #define EM28XX_DVB_NUM_BUFS 5 +/* max number of I2C buses on em28xx devices */ +#define NUM_I2C_BUSES 2 + /* isoc transfers: number of packets for each buffer windows requests only 64 packets .. so we better do the same this is what I found out for all alternate numbers there! @@ -507,10 +510,13 @@ struct em28xx { int tuner_type; /* type of the tuner */ int tuner_addr; /* tuner address */ int tda9887_conf; + /* i2c i/o */ - struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; + struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; + struct i2c_client i2c_client[NUM_I2C_BUSES]; unsigned char eeprom_addrwidth_16bit:1; + int def_i2c_bus; /* Default I2C bus */ + /* video for linux */ int users; /* user count for exclusive use */ int streaming_users; /* Number of actively streaming users */ -- cgit From 3eb92f6a3948c4358eb8ad1c0905490ddd2fc0ab Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Mar 2013 22:13:18 +0100 Subject: mac80211_hwsim: assign CAB queue properly on interface type change When an interface change type, the CAB queue must be reassigned, do this in hwsim to avoid warnings/crashes. Reported-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 3466f1a8a8d3..0064d38276bf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -964,6 +964,12 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, newtype, vif->addr); hwsim_check_magic(vif); + /* + * interface may change from non-AP to AP in + * which case this needs to be set up again + */ + vif->cab_queue = 0; + return 0; } -- cgit From 3aa2b3b9cc7cf58d044f30dcad849bff037abd25 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Mar 2013 06:55:27 -0300 Subject: [media] em28xx: Add a separate config dir for secondary bus Prepare to register a separate bus for the second bus. For now, just add a new field. A latter patch will add the bits to make it work. This patch was generated by this script: perl -e 'while (<>) { if (s/EM2874_I2C_SECONDARY_BUS_SELECT.*\n//) { printf "\t\t.def_i2c_bus = 1,\n"; $found = 1; print $_ } else { if ($found) { s/^\s+// }; $found = 0; print $_; } }' \ drivers/media/usb/em28xx/em28xx-cards.c >a && mv a drivers/media/usb/em28xx/em28xx-cards.c Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 43 ++++++++++++++++++--------------- drivers/media/usb/em28xx/em28xx.h | 1 + 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index d81f7ee94c41..16ab4d7780b3 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -958,8 +958,8 @@ struct em28xx_board em28xx_boards[] = { #else .tuner_type = TUNER_ABSENT, #endif - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { @@ -974,8 +974,8 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_ABSENT, #endif .ir_codes = RC_MAP_HAUPPAUGE, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, [EM2884_BOARD_CINERGY_HTC_STICK] = { @@ -983,8 +983,8 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, .tuner_type = TUNER_ABSENT, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { @@ -1404,8 +1404,8 @@ struct em28xx_board em28xx_boards[] = { }, [EM2874_BOARD_LEADERSHIP_ISDBT] = { - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, .xclk = EM28XX_XCLK_FREQUENCY_10MHZ, .name = "EM2874 Leadership ISDBT", @@ -1917,8 +1917,8 @@ struct em28xx_board em28xx_boards[] = { * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */ [EM28174_BOARD_PCTV_290E] = { .name = "PCTV nanoStick T2 290e", - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_290e, .has_dvb = 1, @@ -1927,8 +1927,8 @@ struct em28xx_board em28xx_boards[] = { /* 2013:024f PCTV DVB-S2 Stick 460e * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */ [EM28174_BOARD_PCTV_460E] = { - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, .name = "PCTV DVB-S2 Stick (460e)", .tuner_type = TUNER_ABSENT, .tuner_gpio = pctv_460e, @@ -1958,8 +1958,8 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_ABSENT, .tuner_gpio = maxmedia_ub425_tc, .has_dvb = 1, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, /* 2304:0242 PCTV QuatroStick (510e) @@ -1970,8 +1970,8 @@ struct em28xx_board em28xx_boards[] = { .tuner_gpio = pctv_510e, .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, /* 2013:0251 PCTV QuatroStick nano (520e) @@ -1982,8 +1982,8 @@ struct em28xx_board em28xx_boards[] = { .tuner_gpio = pctv_520e, .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, [EM2884_BOARD_TERRATEC_HTC_USB_XS] = { @@ -1991,8 +1991,8 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, .tuner_type = TUNER_ABSENT, - .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | - EM28XX_I2C_CLK_WAIT_ENABLE | + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, }; @@ -2234,6 +2234,9 @@ static inline void em28xx_set_model(struct em28xx *dev) if (!dev->board.i2c_speed) dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ; + + if (dev->board.def_i2c_bus == 1) + dev->board.i2c_speed |= EM2874_I2C_SECONDARY_BUS_SELECT; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 5de7b6c93857..43eb1c69e3f2 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -375,6 +375,7 @@ struct em28xx_board { int vchannels; int tuner_type; int tuner_addr; + int def_i2c_bus; /* Default I2C bus */ /* i2c flags */ unsigned int tda9887_conf; -- cgit From aab3125c43d8fecc7134e5f1e729fabf4dd196da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Mar 2013 06:55:28 -0300 Subject: [media] em28xx: add support for registering multiple i2c buses Register both buses 0 and 1 via I2C API. For now, bus 0 is used only by eeprom on all known devices. Later patches will be needed if this changes in the future. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 31 ++++++--- drivers/media/usb/em28xx/em28xx-i2c.c | 119 ++++++++++++++++++++++---------- drivers/media/usb/em28xx/em28xx.h | 21 ++++-- 3 files changed, 120 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 16ab4d7780b3..6e62b72376b0 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2235,8 +2235,8 @@ static inline void em28xx_set_model(struct em28xx *dev) dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ; - if (dev->board.def_i2c_bus == 1) - dev->board.i2c_speed |= EM2874_I2C_SECONDARY_BUS_SELECT; + /* Should be initialized early, for I2C to work */ + dev->def_i2c_bus = dev->board.def_i2c_bus; } @@ -2642,7 +2642,7 @@ static int em28xx_hint_board(struct em28xx *dev) /* user did not request i2c scanning => do it now */ if (!dev->i2c_hash) - em28xx_do_i2c_scan(dev); + em28xx_do_i2c_scan(dev, dev->def_i2c_bus); for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) { if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { @@ -2953,7 +2953,9 @@ void em28xx_release_resources(struct em28xx *dev) em28xx_release_analog_resources(dev); - em28xx_i2c_unregister(dev); + if (dev->def_i2c_bus) + em28xx_i2c_unregister(dev, 1); + em28xx_i2c_unregister(dev, 0); v4l2_ctrl_handler_free(&dev->ctrl_handler); @@ -3109,14 +3111,25 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, v4l2_ctrl_handler_init(hdl, 8); dev->v4l2_dev.ctrl_handler = hdl; - /* register i2c bus */ - retval = em28xx_i2c_register(dev); + rt_mutex_init(&dev->i2c_bus_lock); + + /* register i2c bus 0 */ + retval = em28xx_i2c_register(dev, 0); if (retval < 0) { - em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n", + em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); goto unregister_dev; } + if (dev->def_i2c_bus) { + retval = em28xx_i2c_register(dev, 1); + if (retval < 0) { + em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n", + __func__, retval); + goto unregister_dev; + } + } + /* * Default format, used for tvp5150 or saa711x output formats */ @@ -3186,7 +3199,9 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, return 0; fail: - em28xx_i2c_unregister(dev); + if (dev->def_i2c_bus) + em28xx_i2c_unregister(dev, 1); + em28xx_i2c_unregister(dev, 0); v4l2_ctrl_handler_free(&dev->ctrl_handler); unregister_dev: diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 9086e57914e6..d4a48cb1202e 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -280,11 +280,29 @@ static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr) static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { - struct em28xx *dev = i2c_adap->algo_data; + struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; + struct em28xx *dev = i2c_bus->dev; + unsigned bus = i2c_bus->bus; int addr, rc, i, byte; - if (num <= 0) + rc = rt_mutex_trylock(&dev->i2c_bus_lock); + if (rc < 0) + return rc; + + /* Switch I2C bus if needed */ + if (bus != dev->cur_i2c_bus) { + if (bus == 1) + dev->cur_i2c_bus |= EM2874_I2C_SECONDARY_BUS_SELECT; + else + dev->cur_i2c_bus &= ~EM2874_I2C_SECONDARY_BUS_SELECT; + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->cur_i2c_bus); + dev->cur_i2c_bus = bus; + } + + if (num <= 0) { + rt_mutex_unlock(&dev->i2c_bus_lock); return 0; + } for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; if (i2c_debug) @@ -301,6 +319,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, if (rc == -ENODEV) { if (i2c_debug) printk(" no device\n"); + rt_mutex_unlock(&dev->i2c_bus_lock); return rc; } } else if (msgs[i].flags & I2C_M_RD) { @@ -336,12 +355,14 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, if (rc < 0) { if (i2c_debug) printk(" ERROR: %i\n", rc); + rt_mutex_unlock(&dev->i2c_bus_lock); return rc; } if (i2c_debug) printk("\n"); } + rt_mutex_unlock(&dev->i2c_bus_lock); return num; } @@ -372,8 +393,8 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) /* Helper function to read data blocks from i2c clients with 8 or 16 bit * address width, 8 bit register width and auto incrementation been activated */ -static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, - u16 len, u8 *data) +static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, + bool addr_w16, u16 len, u8 *data) { int remain = len, rsize, rsize_max, ret; u8 buf[2]; @@ -384,7 +405,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, /* Select address */ buf[0] = addr >> 8; buf[1] = addr & 0xff; - ret = i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], buf + !addr_w16, 1 + addr_w16); + ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); if (ret < 0) return ret; /* Read data */ @@ -398,7 +419,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, else rsize = remain; - ret = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], data, rsize); + ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize); if (ret < 0) return ret; @@ -409,7 +430,8 @@ static int em28xx_i2c_read_block(struct em28xx *dev, u16 addr, bool addr_w16, return len; } -static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) +static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, + u8 **eedata, u16 *eedata_len) { const u16 len = 256; /* FIXME common length/size for bytes to read, to display, hash @@ -422,10 +444,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) *eedata = NULL; *eedata_len = 0; - dev->i2c_client[dev->def_i2c_bus].addr = 0xa0 >> 1; + /* EEPROM is always on i2c bus 0 on all known devices. */ + + dev->i2c_client[bus].addr = 0xa0 >> 1; /* Check if board has eeprom */ - err = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], &buf, 0); + err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); if (err < 0) { em28xx_info("board has no eeprom\n"); return -ENODEV; @@ -436,7 +460,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) return -ENOMEM; /* Read EEPROM content */ - err = em28xx_i2c_read_block(dev, 0x0000, dev->eeprom_addrwidth_16bit, + err = em28xx_i2c_read_block(dev, bus, 0x0000, + dev->eeprom_addrwidth_16bit, len, data); if (err != len) { em28xx_errdev("failed to read eeprom (err=%d)\n", err); @@ -485,7 +510,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) /* Read hardware config dataset offset from address * (microcode start + 46) */ - err = em28xx_i2c_read_block(dev, mc_start + 46, 1, 2, data); + err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, + data); if (err != 2) { em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", err); @@ -501,7 +527,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, u8 **eedata, u16 *eedata_len) * the old eeprom and not longer than 256 bytes. * tveeprom is currently also limited to 256 bytes. */ - err = em28xx_i2c_read_block(dev, hwconf_offset, 1, len, data); + err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, + data); if (err != len) { em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", err); @@ -590,9 +617,11 @@ error: /* * functionality() */ -static u32 functionality(struct i2c_adapter *adap) +static u32 functionality(struct i2c_adapter *i2c_adap) { - struct em28xx *dev = adap->algo_data; + struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; + struct em28xx *dev = i2c_bus->dev; + u32 func_flags = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; if (dev->board.is_em2800) func_flags &= ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; @@ -643,7 +672,7 @@ static char *i2c_devs[128] = { * do_i2c_scan() * check i2c address range for devices */ -void em28xx_do_i2c_scan(struct em28xx *dev) +void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) { u8 i2c_devicelist[128]; unsigned char buf; @@ -652,55 +681,66 @@ void em28xx_do_i2c_scan(struct em28xx *dev) memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { - dev->i2c_client[dev->def_i2c_bus].addr = i; - rc = i2c_master_recv(&dev->i2c_client[dev->def_i2c_bus], &buf, 0); + dev->i2c_client[bus].addr = i; + rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); if (rc < 0) continue; i2c_devicelist[i] = i; - em28xx_info("found i2c device @ 0x%x [%s]\n", - i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + em28xx_info("found i2c device @ 0x%x on bus %d [%s]\n", + i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); } - dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, - ARRAY_SIZE(i2c_devicelist), 32); + if (bus == dev->def_i2c_bus) + dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, + ARRAY_SIZE(i2c_devicelist), 32); } /* * em28xx_i2c_register() * register i2c bus */ -int em28xx_i2c_register(struct em28xx *dev) +int em28xx_i2c_register(struct em28xx *dev, unsigned bus) { int retval; BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); - dev->i2c_adap[dev->def_i2c_bus] = em28xx_adap_template; - dev->i2c_adap[dev->def_i2c_bus].dev.parent = &dev->udev->dev; - strcpy(dev->i2c_adap[dev->def_i2c_bus].name, dev->name); - dev->i2c_adap[dev->def_i2c_bus].algo_data = dev; - i2c_set_adapdata(&dev->i2c_adap[dev->def_i2c_bus], &dev->v4l2_dev); - retval = i2c_add_adapter(&dev->i2c_adap[dev->def_i2c_bus]); + if (bus >= NUM_I2C_BUSES) + return -ENODEV; + + dev->i2c_adap[bus] = em28xx_adap_template; + dev->i2c_adap[bus].dev.parent = &dev->udev->dev; + strcpy(dev->i2c_adap[bus].name, dev->name); + + dev->i2c_bus[bus].bus = bus; + dev->i2c_bus[bus].dev = dev; + dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; + i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); + + retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", __func__, retval); return retval; } - dev->i2c_client[dev->def_i2c_bus] = em28xx_client_template; - dev->i2c_client[dev->def_i2c_bus].adapter = &dev->i2c_adap[dev->def_i2c_bus]; + dev->i2c_client[bus] = em28xx_client_template; + dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; - retval = em28xx_i2c_eeprom(dev, &dev->eedata, &dev->eedata_len); - if ((retval < 0) && (retval != -ENODEV)) { - em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", - __func__, retval); + /* Up to now, all eeproms are at bus 0 */ + if (!bus) { + retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); + if ((retval < 0) && (retval != -ENODEV)) { + em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", + __func__, retval); - return retval; + return retval; + } } if (i2c_scan) - em28xx_do_i2c_scan(dev); + em28xx_do_i2c_scan(dev, bus); return 0; } @@ -709,8 +749,11 @@ int em28xx_i2c_register(struct em28xx *dev) * em28xx_i2c_unregister() * unregister i2c_bus */ -int em28xx_i2c_unregister(struct em28xx *dev) +int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) { - i2c_del_adapter(&dev->i2c_adap[dev->def_i2c_bus]); + if (bus >= NUM_I2C_BUSES) + return -ENODEV; + + i2c_del_adapter(&dev->i2c_adap[bus]); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 43eb1c69e3f2..f6ac1df83816 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -375,7 +375,7 @@ struct em28xx_board { int vchannels; int tuner_type; int tuner_addr; - int def_i2c_bus; /* Default I2C bus */ + unsigned def_i2c_bus; /* Default I2C bus */ /* i2c flags */ unsigned int tda9887_conf; @@ -460,6 +460,13 @@ struct em28xx_fh { enum v4l2_buf_type type; }; +struct em28xx_i2c_bus { + struct em28xx *dev; + + unsigned bus; +}; + + /* main device struct */ struct em28xx { /* generic device properties */ @@ -515,8 +522,12 @@ struct em28xx { /* i2c i/o */ struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; struct i2c_client i2c_client[NUM_I2C_BUSES]; + struct em28xx_i2c_bus i2c_bus[NUM_I2C_BUSES]; + unsigned char eeprom_addrwidth_16bit:1; - int def_i2c_bus; /* Default I2C bus */ + unsigned def_i2c_bus; /* Default I2C bus */ + unsigned cur_i2c_bus; /* Current I2C bus */ + struct rt_mutex i2c_bus_lock; /* video for linux */ int users; /* user count for exclusive use */ @@ -638,9 +649,9 @@ struct em28xx_ops { }; /* Provided by em28xx-i2c.c */ -void em28xx_do_i2c_scan(struct em28xx *dev); -int em28xx_i2c_register(struct em28xx *dev); -int em28xx_i2c_unregister(struct em28xx *dev); +void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus); +int em28xx_i2c_register(struct em28xx *dev, unsigned bus); +int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus); /* Provided by em28xx-core.c */ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, -- cgit From 6d5df8976266d8e40603601f7695537f9f3dc9e2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 18 Mar 2013 12:04:54 -0400 Subject: USB: EHCI: decrease schedule-status poll timeout This patch (as1657) decreases the timeout used by ehci-hcd for polling the async and periodic schedule statuses. The timeout is currently set to 20 ms, which is much too high. Controllers should always update the schedule status within one or two ms of being told to do so; if they don't then something is wrong. Furthermore, bug reports have shown that sometimes controllers (particularly those made by VIA) don't update the status bit at all, even when the schedule does change state. When this happens, polling for 20 ms would cause an unnecessarily long delay. The delay is reduced to somewhere between 2 and 4 ms, depending on the slop allowed by the kernel's high-res timers. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-timer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 20dbdcbe9b0f..cc9ad5892d19 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -113,8 +113,8 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci) if (want != actual) { - /* Poll again later, but give up after about 20 ms */ - if (ehci->ASS_poll_count++ < 20) { + /* Poll again later, but give up after about 2-4 ms */ + if (ehci->ASS_poll_count++ < 2) { ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); return; } @@ -159,8 +159,8 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci) if (want != actual) { - /* Poll again later, but give up after about 20 ms */ - if (ehci->PSS_poll_count++ < 20) { + /* Poll again later, but give up after about 2-4 ms */ + if (ehci->PSS_poll_count++ < 2) { ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); return; } -- cgit From 4dd405a4b0969bfec4dc9959050b46d818b6549b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 18 Mar 2013 12:05:08 -0400 Subject: USB: EHCI: improve use of per-port status-change bits This patch (as1634) simplifies some of the code associated with the per-port change bits added in EHCI-1.1, and in particular it fixes a bug in the logic of ehci_hub_status_data(). Even if the change bit doesn't indicate anything happened on a particular port, we still have to notify the core about changes to the suspend or reset status. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 4 ++-- drivers/usb/host/ehci-hub.c | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 303b0222cd6d..fcf8b940e867 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -758,7 +758,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* remote wakeup [4.3.1] */ if (status & STS_PCD) { unsigned i = HCS_N_PORTS (ehci->hcs_params); - u32 ppcd = 0; + u32 ppcd = ~0; /* kick root hub later */ pcd_status = status; @@ -775,7 +775,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) int pstatus; /* leverage per-port change bits feature */ - if (ehci->has_ppcd && !(ppcd & (1 << i))) + if (!(ppcd & (1 << i))) continue; pstatus = ehci_readl(ehci, &ehci->regs->port_status[i]); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4d3b294f203e..576b735f49b6 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -590,7 +590,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) u32 mask; int ports, i, retval = 1; unsigned long flags; - u32 ppcd = 0; + u32 ppcd = ~0; /* init status to no-changes */ buf [0] = 0; @@ -628,9 +628,10 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) for (i = 0; i < ports; i++) { /* leverage per-port change bits feature */ - if (ehci->has_ppcd && !(ppcd & (1 << i))) - continue; - temp = ehci_readl(ehci, &ehci->regs->port_status [i]); + if (ppcd & (1 << i)) + temp = ehci_readl(ehci, &ehci->regs->port_status[i]); + else + temp = 0; /* * Return status information even for ports with OWNER set. -- cgit From 60fd4aa742a0c4f01dafeb0d125fed54e91e3657 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 18 Mar 2013 12:05:19 -0400 Subject: USB: EHCI: reorganize ehci_iaa_watchdog() This patch (as1635) rearranges the control-flow logic in ehci_iaa_watchdog() slightly to agree better with the comments. It also changes a verbose-debug message to a regular debug message. Expiration of the IAA watchdog is an unusual event and can lead to problems; we need to know about it if it happens during debugging. It should not be necessary to set a "verbose" compilation option. No behavioral changes other than the debug message. Lots of apparent changes to the source text, though, because the indentation level was decreased. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-timer.c | 53 ++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index cc9ad5892d19..97815d0fc97c 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -295,8 +295,7 @@ static void end_free_itds(struct ehci_hcd *ehci) /* Handle lost (or very late) IAA interrupts */ static void ehci_iaa_watchdog(struct ehci_hcd *ehci) { - if (ehci->rh_state != EHCI_RH_RUNNING) - return; + u32 cmd, status; /* * Lost IAA irqs wedge things badly; seen first with a vt8235. @@ -304,34 +303,32 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci) * (a) SMP races against real IAA firing and retriggering, and * (b) clean HC shutdown, when IAA watchdog was pending. */ - if (ehci->async_iaa) { - u32 cmd, status; - - /* If we get here, IAA is *REALLY* late. It's barely - * conceivable that the system is so busy that CMD_IAAD - * is still legitimately set, so let's be sure it's - * clear before we read STS_IAA. (The HC should clear - * CMD_IAAD when it sets STS_IAA.) - */ - cmd = ehci_readl(ehci, &ehci->regs->command); - - /* - * If IAA is set here it either legitimately triggered - * after the watchdog timer expired (_way_ late, so we'll - * still count it as lost) ... or a silicon erratum: - * - VIA seems to set IAA without triggering the IRQ; - * - IAAD potentially cleared without setting IAA. - */ - status = ehci_readl(ehci, &ehci->regs->status); - if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { - COUNT(ehci->stats.lost_iaa); - ehci_writel(ehci, STS_IAA, &ehci->regs->status); - } + if (!ehci->async_iaa || ehci->rh_state != EHCI_RH_RUNNING) + return; + + /* If we get here, IAA is *REALLY* late. It's barely + * conceivable that the system is so busy that CMD_IAAD + * is still legitimately set, so let's be sure it's + * clear before we read STS_IAA. (The HC should clear + * CMD_IAAD when it sets STS_IAA.) + */ + cmd = ehci_readl(ehci, &ehci->regs->command); - ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", - status, cmd); - end_unlink_async(ehci); + /* + * If IAA is set here it either legitimately triggered + * after the watchdog timer expired (_way_ late, so we'll + * still count it as lost) ... or a silicon erratum: + * - VIA seems to set IAA without triggering the IRQ; + * - IAAD potentially cleared without setting IAA. + */ + status = ehci_readl(ehci, &ehci->regs->status); + if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { + COUNT(ehci->stats.lost_iaa); + ehci_writel(ehci, STS_IAA, &ehci->regs->status); } + + ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); + end_unlink_async(ehci); } -- cgit From 24b90814fb133bb7971aef8ea5e642d9f9bc4b0b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 18 Mar 2013 12:05:42 -0400 Subject: USB: EHCI: don't turn on PORT_SUSPEND during port resume This patch (as1637) cleans up the way ehci-hcd handles end-of-resume port signalling. When the PORT_RESUME bit in the port's status and control register is cleared, we shouldn't be setting the PORT_SUSPEND bit at the same time. Not doing this doesn't seem to have hurt so far, but we might as well do the right thing. Also, the patch replaces an estimated value for what the port status should be following a resume with the actual register value. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 576b735f49b6..0df45d933a10 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -464,7 +464,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) while (i--) { temp = ehci_readl(ehci, &ehci->regs->port_status [i]); if (test_bit(i, &resume_needed)) { - temp &= ~(PORT_RWC_BITS | PORT_RESUME); + temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME); ehci_writel(ehci, temp, &ehci->regs->port_status [i]); ehci_vdbg (ehci, "resumed port %d\n", i + 1); } @@ -871,10 +871,9 @@ static int ehci_hub_control ( usb_hcd_end_port_resume(&hcd->self, wIndex); /* stop resume signaling */ - temp = ehci_readl(ehci, status_reg); - ehci_writel(ehci, - temp & ~(PORT_RWC_BITS | PORT_RESUME), - status_reg); + temp &= ~(PORT_RWC_BITS | + PORT_SUSPEND | PORT_RESUME); + ehci_writel(ehci, temp, status_reg); clear_bit(wIndex, &ehci->resuming_ports); retval = handshake(ehci, status_reg, PORT_RESUME, 0, 2000 /* 2msec */); @@ -884,7 +883,7 @@ static int ehci_hub_control ( wIndex + 1, retval); goto error; } - temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); + temp = ehci_readl(ehci, status_reg); } } -- cgit From 3f3b55bf7833d81d00c793d722e2af58d3b12963 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Thu, 14 Mar 2013 20:15:37 -0700 Subject: usb: ehci-s5p: Use devm for requesting ehci_vbus_gpio The ehci_vbus_gpio is requested but never freed. This can cause problems with deferred probes and would cause problems if s5p_ehci_remove was ever called. Use devm to fix this. Signed-off-by: Doug Anderson Acked-by: Jingoo Han Tested-by: Vivek Gautam Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-s5p.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 20ebf6a8b7f4..738490e6d429 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -92,20 +92,21 @@ static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci) static void s5p_setup_vbus_gpio(struct platform_device *pdev) { + struct device *dev = &pdev->dev; int err; int gpio; - if (!pdev->dev.of_node) + if (!dev->of_node) return; - gpio = of_get_named_gpio(pdev->dev.of_node, - "samsung,vbus-gpio", 0); + gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0); if (!gpio_is_valid(gpio)) return; - err = gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "ehci_vbus_gpio"); + err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH, + "ehci_vbus_gpio"); if (err) - dev_err(&pdev->dev, "can't request ehci vbus gpio %d", gpio); + dev_err(dev, "can't request ehci vbus gpio %d", gpio); } static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32); -- cgit From c828f679eed393d6925a2b44a4c3fb80a8d657cb Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 08:20:51 -0500 Subject: n_tty: Inline check_unthrottle() at lone call site 2-line function check_unthrottle() is now only called from n_tty_read(); merge into caller. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 05e72bea9b07..7fbad56db7c9 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -188,21 +188,6 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) raw_spin_unlock_irqrestore(&ldata->read_lock, flags); } -/** - * check_unthrottle - allow new receive data - * @tty; tty device - * - * Check whether to call the driver unthrottle functions - * - * Can sleep, may be called under the atomic_read_lock mutex but - * this is not guaranteed. - */ -static void check_unthrottle(struct tty_struct *tty) -{ - if (tty->count) - tty_unthrottle(tty); -} - /** * reset_buffer_flags - reset buffer state * @tty: terminal to reset @@ -1961,7 +1946,8 @@ do_it_again: */ if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { n_tty_set_room(tty); - check_unthrottle(tty); + if (tty->count) + tty_unthrottle(tty); } if (b - buf >= minimum) -- cgit From 70bc126471af30bb115e635512dcf6d86fe6e29a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 08:20:52 -0500 Subject: tty: Add safe tty throttle/unthrottle functions The tty driver can become stuck throttled due to race conditions between throttle and unthrottle, when the decision to throttle or unthrottle is conditional. The following example helps to illustrate the race: CPU 0 | CPU 1 | if (condition A) | | | if (!condition A) | unthrottle() throttle() | | Note the converse is also possible; ie., CPU 0 | CPU 1 | | if (!condition A) | if (condition A) | throttle() | | unthrottle() | Add new throttle/unthrottle functions based on the familiar model of task state and schedule/wake. For example, while (1) { tty_set_flow_change(tty, TTY_THROTTLE_SAFE); if (!condition) break; if (!tty_throttle_safe(tty)) break; } __tty_set_flow_change(tty, 0); In this example, if an unthrottle occurs after the condition is evaluated but before tty_throttle_safe(), then tty_throttle_safe() will return non-zero, looping and forcing the re-evaluation of condition. Reported-by: Vincent Pillet Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/tty.h | 18 ++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d58b92cc187c..132d452578bb 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -106,6 +106,7 @@ void tty_throttle(struct tty_struct *tty) if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && tty->ops->throttle) tty->ops->throttle(tty); + tty->flow_change = 0; mutex_unlock(&tty->termios_mutex); } EXPORT_SYMBOL(tty_throttle); @@ -129,10 +130,73 @@ void tty_unthrottle(struct tty_struct *tty) if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && tty->ops->unthrottle) tty->ops->unthrottle(tty); + tty->flow_change = 0; mutex_unlock(&tty->termios_mutex); } EXPORT_SYMBOL(tty_unthrottle); +/** + * tty_throttle_safe - flow control + * @tty: terminal + * + * Similar to tty_throttle() but will only attempt throttle + * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental + * throttle due to race conditions when throttling is conditional + * on factors evaluated prior to throttling. + * + * Returns 0 if tty is throttled (or was already throttled) + */ + +int tty_throttle_safe(struct tty_struct *tty) +{ + int ret = 0; + + mutex_lock(&tty->termios_mutex); + if (!test_bit(TTY_THROTTLED, &tty->flags)) { + if (tty->flow_change != TTY_THROTTLE_SAFE) + ret = 1; + else { + __set_bit(TTY_THROTTLED, &tty->flags); + if (tty->ops->throttle) + tty->ops->throttle(tty); + } + } + mutex_unlock(&tty->termios_mutex); + + return ret; +} + +/** + * tty_unthrottle_safe - flow control + * @tty: terminal + * + * Similar to tty_unthrottle() but will only attempt unthrottle + * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental + * unthrottle due to race conditions when unthrottling is conditional + * on factors evaluated prior to unthrottling. + * + * Returns 0 if tty is unthrottled (or was already unthrottled) + */ + +int tty_unthrottle_safe(struct tty_struct *tty) +{ + int ret = 0; + + mutex_lock(&tty->termios_mutex); + if (test_bit(TTY_THROTTLED, &tty->flags)) { + if (tty->flow_change != TTY_UNTHROTTLE_SAFE) + ret = 1; + else { + __clear_bit(TTY_THROTTLED, &tty->flags); + if (tty->ops->unthrottle) + tty->ops->unthrottle(tty); + } + } + mutex_unlock(&tty->termios_mutex); + + return ret; +} + /** * tty_wait_until_sent - wait for I/O to finish * @tty: tty we are waiting for diff --git a/include/linux/tty.h b/include/linux/tty.h index c75d886b0307..189ca80494d1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -258,6 +258,7 @@ struct tty_struct { unsigned char warned:1; unsigned char ctrl_status; /* ctrl_lock */ unsigned int receive_room; /* Bytes free for queue */ + int flow_change; struct tty_struct *link; struct fasync_struct *fasync; @@ -318,6 +319,21 @@ struct tty_file_private { #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) +/* Values for tty->flow_change */ +#define TTY_THROTTLE_SAFE 1 +#define TTY_UNTHROTTLE_SAFE 2 + +static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; +} + +static inline void tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; + smp_mb(); +} + #ifdef CONFIG_TTY extern void console_init(void); extern void tty_kref_put(struct tty_struct *tty); @@ -400,6 +416,8 @@ extern int tty_write_room(struct tty_struct *tty); extern void tty_driver_flush_buffer(struct tty_struct *tty); extern void tty_throttle(struct tty_struct *tty); extern void tty_unthrottle(struct tty_struct *tty); +extern int tty_throttle_safe(struct tty_struct *tty); +extern int tty_unthrottle_safe(struct tty_struct *tty); extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); extern void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty); -- cgit From e91e52e42814b130c20d17bc1e2adf813c50db11 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 08:20:53 -0500 Subject: n_tty: Fix stuck throttled driver As noted in the following comment: /* FIXME: there is a tiny race here if the receive room check runs before the other work executes and empties the buffer (upping the receiving room and unthrottling. We then throttle and get stuck. This has been observed and traced down by Vincent Pillet/ We need to address this when we sort out out the rx path locking */ Use new safe throttle/unthrottle functions to re-evaluate conditions if interrupted by the complement flow control function. Reported-by: Vincent Pillet Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 7fbad56db7c9..e3a9321f7f89 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1468,14 +1468,14 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, * mode. We don't want to throttle the driver if we're in * canonical mode and don't have a newline yet! */ - if (tty->receive_room < TTY_THRESHOLD_THROTTLE) - tty_throttle(tty); - - /* FIXME: there is a tiny race here if the receive room check runs - before the other work executes and empties the buffer (upping - the receiving room and unthrottling. We then throttle and get - stuck. This has been observed and traced down by Vincent Pillet/ - We need to address this when we sort out out the rx path locking */ + while (1) { + tty_set_flow_change(tty, TTY_THROTTLE_SAFE); + if (tty->receive_room >= TTY_THRESHOLD_THROTTLE) + break; + if (!tty_throttle_safe(tty)) + break; + } + __tty_set_flow_change(tty, 0); } int is_ignored(int sig) @@ -1944,11 +1944,17 @@ do_it_again: * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { + while (1) { + tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); + if (n_tty_chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) + break; + if (!tty->count) + break; n_tty_set_room(tty); - if (tty->count) - tty_unthrottle(tty); + if (!tty_unthrottle_safe(tty)) + break; } + __tty_set_flow_change(tty, 0); if (b - buf >= minimum) break; -- cgit From 8c985d18b136c5d511445d15f0c6650003a8946b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 08:38:19 -0500 Subject: n_tty: Fix unsafe driver-side signals An ldisc reference is insufficient guarantee the foreground process group is not in the process of being signalled from a hangup. 1) Reads of tty->pgrp must be locked with ctrl_lock 2) The group pid must be referenced for the duration of signalling. Because the driver-side is not process-context, a pid reference must be acquired. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index e3a9321f7f89..61f1bc97ccd9 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1017,23 +1017,19 @@ static void eraser(unsigned char c, struct tty_struct *tty) * isig - handle the ISIG optio * @sig: signal * @tty: terminal - * @flush: force flush * - * Called when a signal is being sent due to terminal input. This - * may caus terminal flushing to take place according to the termios - * settings and character used. Called from the driver receive_buf - * path so serialized. + * Called when a signal is being sent due to terminal input. + * Called from the driver receive_buf path so serialized. * - * Locking: ctrl_lock, read_lock (both via flush buffer) + * Locking: ctrl_lock */ -static inline void isig(int sig, struct tty_struct *tty, int flush) +static inline void isig(int sig, struct tty_struct *tty) { - if (tty->pgrp) - kill_pgrp(tty->pgrp, sig, 1); - if (flush || !L_NOFLSH(tty)) { - n_tty_flush_buffer(tty); - tty_driver_flush_buffer(tty); + struct pid *tty_pgrp = tty_get_pgrp(tty); + if (tty_pgrp) { + kill_pgrp(tty_pgrp, sig, 1); + put_pid(tty_pgrp); } } @@ -1054,7 +1050,11 @@ static inline void n_tty_receive_break(struct tty_struct *tty) if (I_IGNBRK(tty)) return; if (I_BRKINT(tty)) { - isig(SIGINT, tty, 1); + isig(SIGINT, tty); + if (!L_NOFLSH(tty)) { + n_tty_flush_buffer(tty); + tty_driver_flush_buffer(tty); + } return; } if (I_PARMRK(tty)) { @@ -1221,11 +1221,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) signal = SIGTSTP; if (c == SUSP_CHAR(tty)) { send_signal: - /* - * Note that we do not use isig() here because we want - * the order to be: - * 1) flush, 2) echo, 3) signal - */ if (!L_NOFLSH(tty)) { n_tty_flush_buffer(tty); tty_driver_flush_buffer(tty); @@ -1236,8 +1231,7 @@ send_signal: echo_char(c, tty); process_echoes(tty); } - if (tty->pgrp) - kill_pgrp(tty->pgrp, signal, 1); + isig(signal, tty); return; } } -- cgit From 01a5e440c91dc6065cf3dbc38aa7276fc4ce2f26 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 6 Mar 2013 08:38:20 -0500 Subject: n_tty: Lock access to tty->pgrp for POSIX job control Concurrent access to tty->pgrp must be protected with tty->ctrl_lock. Also, as noted in the comments, reading current->signal->tty is safe because either, 1) current->signal->tty is assigned by current, or 2) current->signal->tty is set to NULL. NB: for reference, tty_check_change() implements a similar POSIX check for the ioctls corresponding to tcflush(), tcdrain(), tcsetattr(), tcsetpgrp(), tcflow() and tcsendbreak(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 61f1bc97ccd9..68865d9af8a0 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1719,10 +1719,9 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *, * and if appropriate send any needed signals and return a negative * error code if action should be taken. * - * FIXME: - * Locking: None - redirected write test is safe, testing - * current->signal should possibly lock current->sighand - * pgrp locking ? + * Locking: redirected write test is safe + * current->signal->tty check is safe + * ctrl_lock to safely reference tty->pgrp */ static int job_control(struct tty_struct *tty, struct file *file) @@ -1732,19 +1731,22 @@ static int job_control(struct tty_struct *tty, struct file *file) /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (file->f_op->write != redirected_tty_write && - current->signal->tty == tty) { - if (!tty->pgrp) - printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); - else if (task_pgrp(current) != tty->pgrp) { - if (is_ignored(SIGTTIN) || - is_current_pgrp_orphaned()) - return -EIO; - kill_pgrp(task_pgrp(current), SIGTTIN, 1); - set_thread_flag(TIF_SIGPENDING); - return -ERESTARTSYS; - } + if (file->f_op->write == redirected_tty_write || + current->signal->tty != tty) + return 0; + + spin_lock_irq(&tty->ctrl_lock); + if (!tty->pgrp) + printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); + else if (task_pgrp(current) != tty->pgrp) { + spin_unlock_irq(&tty->ctrl_lock); + if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) + return -EIO; + kill_pgrp(task_pgrp(current), SIGTTIN, 1); + set_thread_flag(TIF_SIGPENDING); + return -ERESTARTSYS; } + spin_unlock_irq(&tty->ctrl_lock); return 0; } -- cgit From b09753ec80914424527955147c359e9ac3a87682 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 19 Mar 2013 00:16:15 +0100 Subject: ACPI / hotplug: Make acpi_hotplug_profile_ktype static The acpi_hotplug_profile_ktype object should be static, so make that be the case. Reported-by: Fengguang Wu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 83db3a68a7ee..fcae5fa2e1b3 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -750,7 +750,7 @@ static struct attribute *hotplug_profile_attrs[] = { NULL }; -struct kobj_type acpi_hotplug_profile_ktype = { +static struct kobj_type acpi_hotplug_profile_ktype = { .sysfs_ops = &kobj_sysfs_ops, .default_attrs = hotplug_profile_attrs, }; -- cgit From 195281d0dc6a2fc1824d5da9abd2924bce0fa698 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sat, 9 Mar 2013 06:53:01 -0300 Subject: [media] em28xx: set the timestamp type for video and vbi vb2_queues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The em28xx driver obtains the timestamps using function v4l2_get_timestamp(), which produces a montonic timestamp. Fixes the warnings appearing in the system log since commit 6aa69f99 "[media] vb2: Add support for non monotonic timestamps" Signed-off-by: Frank Schäfer Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 93fc6204df6c..d585c19a5d9c 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -700,6 +700,7 @@ int em28xx_vb2_setup(struct em28xx *dev) q = &dev->vb_vidq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->drv_priv = dev; q->buf_struct_size = sizeof(struct em28xx_buffer); q->ops = &em28xx_video_qops; @@ -713,6 +714,7 @@ int em28xx_vb2_setup(struct em28xx *dev) q = &dev->vb_vbiq; q->type = V4L2_BUF_TYPE_VBI_CAPTURE; q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR; + q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->drv_priv = dev; q->buf_struct_size = sizeof(struct em28xx_buffer); q->ops = &em28xx_vbi_qops; -- cgit From b1622e0ac1b18632cff1e9af807fcdcb2397071b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:25 +0100 Subject: TTY: jsm, remove superfluous check data_len in jsm_input cannot be zero as we would jump out early in the function. It also cannot be negative because it is an int and we do bitwise and with 8192. So remove the check. Signed-off-by: Jiri Slaby Cc: Lucas Tavares Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_tty.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 00f250ae14c5..27bb75070c96 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -596,12 +596,6 @@ void jsm_input(struct jsm_channel *ch) jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); - if (data_len <= 0) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - jsm_dbg(READ, &ch->ch_bd->pci_dev, "jsm_input 1\n"); - return; - } - len = tty_buffer_request_room(port, data_len); n = len; -- cgit From 049b539b39977fc9343056435eba568fc7779970 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:26 +0100 Subject: TTY: synclink, remove superfluous check info is obtained by container_of. It can never be NULL. So do not test that. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 8983276aa35e..72d607101f90 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -1058,9 +1058,6 @@ static void mgsl_bh_handler(struct work_struct *work) container_of(work, struct mgsl_struct, task); int action; - if (!info) - return; - if ( debug_level >= DEBUG_LEVEL_BH ) printk( "%s(%d):mgsl_bh_handler(%s) entry\n", __FILE__,__LINE__,info->device_name); -- cgit From 7f6301d1257505d35e87ef1cb8eeee268e63a123 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Sun, 10 Mar 2013 07:25:25 -0300 Subject: [media] em28xx-i2c: relax error check in em28xx_i2c_recv_bytes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turned out that some devices return less bytes then requested via i2c when ALL of the following 3 conditions are met: - i2c bus B is used - there was no attempt to write to the specified slave address before - no device present at the specified slave address With the current code, this triggers an -EIO error and prints a message to the system log. Because it can happen very often during device probing, it is better to ignore this error and bail out silently after the follwing i2c transaction success check with -ENODEV. [mchehab@redhat.com: a small CodingStyle fix] Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index d4a48cb1202e..de9b2086ab2d 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -227,18 +227,18 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) /* Read data from i2c device */ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); - if (ret != len) { - if (ret < 0) { - em28xx_warn("reading from i2c device at 0x%x failed " - "(error=%i)\n", addr, ret); - return ret; - } else { - em28xx_warn("%i bytes requested from i2c device at " - "0x%x, but %i bytes received\n", - len, addr, ret); - return -EIO; - } + if (ret < 0) { + em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", + addr, ret); + return ret; } + /* NOTE: some devices with two i2c busses have the bad habit to return 0 + * bytes if we are on bus B AND there was no write attempt to the + * specified slave address before AND no device is present at the + * requested slave address. + * Anyway, the next check will fail with -ENODEV in this case, so avoid + * spamming the system log on device probing and do nothing here. + */ /* Check success of the i2c operation */ ret = dev->em28xx_read_reg(dev, 0x05); -- cgit From 6865ff222ccab371c04afce17aec1f7d70b17dbc Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:27 +0100 Subject: TTY: do not warn about setting speed via SPD_* The warning is there since 2.1.69 and we have not seen anybody reporting it in the past decade. Remove the warning now. tty_get_baud_rate can now be inline. This gives us one less EXPORT_SYMBOL. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 28 ---------------------------- include/linux/tty.h | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 132d452578bb..28715e48b2f7 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -478,34 +478,6 @@ void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) } EXPORT_SYMBOL_GPL(tty_encode_baud_rate); -/** - * tty_get_baud_rate - get tty bit rates - * @tty: tty to query - * - * Returns the baud rate as an integer for this terminal. The - * termios lock must be held by the caller and the terminal bit - * flags may be updated. - * - * Locking: none - */ - -speed_t tty_get_baud_rate(struct tty_struct *tty) -{ - speed_t baud = tty_termios_baud_rate(&tty->termios); - - if (baud == 38400 && tty->alt_speed) { - if (!tty->warned) { - printk(KERN_WARNING "Use of setserial/setrocket to " - "set SPD_* flags is deprecated\n"); - tty->warned = 1; - } - baud = tty->alt_speed; - } - - return baud; -} -EXPORT_SYMBOL(tty_get_baud_rate); - /** * tty_termios_copy_hw - copy hardware settings * @new: New termios diff --git a/include/linux/tty.h b/include/linux/tty.h index 189ca80494d1..63b62865c8e9 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -255,7 +255,6 @@ struct tty_struct { int count; struct winsize winsize; /* termios mutex */ unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; - unsigned char warned:1; unsigned char ctrl_status; /* ctrl_lock */ unsigned int receive_room; /* Bytes free for queue */ int flow_change; @@ -437,13 +436,28 @@ extern void tty_flush_to_ldisc(struct tty_struct *tty); extern void tty_buffer_free_all(struct tty_port *port); extern void tty_buffer_flush(struct tty_struct *tty); extern void tty_buffer_init(struct tty_port *port); -extern speed_t tty_get_baud_rate(struct tty_struct *tty); extern speed_t tty_termios_baud_rate(struct ktermios *termios); extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); + +/** + * tty_get_baud_rate - get tty bit rates + * @tty: tty to query + * + * Returns the baud rate as an integer for this terminal. The + * termios lock must be held by the caller and the terminal bit + * flags may be updated. + * + * Locking: none + */ +static inline speed_t tty_get_baud_rate(struct tty_struct *tty) +{ + return tty_termios_baud_rate(&tty->termios); +} + extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); -- cgit From 6982a398426a22166eaf049b79544536fdd6429f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:28 +0100 Subject: TTY: msm_smd_tty, clean up activate/shutdown Do not dig struct smd_tty_info out of tty_struct using tty_port_tty_get. It is unnecessarily too complicated, use simple container_of instead. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_smd_tty.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index e722ff163d91..1238ac370bff 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c @@ -90,13 +90,13 @@ static void smd_tty_notify(void *priv, unsigned event) static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) { + struct smd_tty_info *info = container_of(tport, struct smd_tty_info, + port); int i, res = 0; - int n = tty->index; const char *name = NULL; - struct smd_tty_info *info = smd_tty + n; for (i = 0; i < smd_tty_channels_len; i++) { - if (smd_tty_channels[i].id == n) { + if (smd_tty_channels[i].id == tty->index) { name = smd_tty_channels[i].name; break; } @@ -117,17 +117,13 @@ static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) static void smd_tty_port_shutdown(struct tty_port *tport) { - struct smd_tty_info *info; - struct tty_struct *tty = tty_port_tty_get(tport); + struct smd_tty_info *info = container_of(tport, struct smd_tty_info, + port); - info = tty->driver_data; if (info->ch) { smd_close(info->ch); info->ch = 0; } - - tty->driver_data = 0; - tty_kref_put(tty); } static int smd_tty_open(struct tty_struct *tty, struct file *f) -- cgit From 6aad04f21374633bd8cecf25024553d1e11a9522 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:29 +0100 Subject: TTY: add tty_port_tty_wakeup helper It allows for cleaning up on a considerable amount of places. They did port_get, wakeup, kref_put. Now the only thing needed is to call tty_port_tty_wakeup which does exactly that. One exception is ifx6x60 where tty_wakeup was open-coded. We now call tty_wakeup properly there. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/um/drivers/line.c | 8 +------- drivers/isdn/capi/capi.c | 7 +------ drivers/isdn/gigaset/interface.c | 6 +----- drivers/net/usb/hso.c | 13 ++----------- drivers/s390/char/sclp_tty.c | 9 ++------- drivers/s390/char/sclp_vt220.c | 8 +------- drivers/staging/fwserial/fwserial.c | 10 ++-------- drivers/staging/serqt_usb2/serqt_usb2.c | 7 +------ drivers/tty/ehv_bytechan.c | 6 +----- drivers/tty/hvc/hvsi.c | 7 +------ drivers/tty/nozomi.c | 6 +----- drivers/tty/serial/ifx6x60.c | 33 ++------------------------------- drivers/tty/tty_port.c | 16 ++++++++++++++++ drivers/usb/class/cdc-acm.c | 7 +------ drivers/usb/serial/digi_acceleport.c | 17 +++-------------- drivers/usb/serial/io_edgeport.c | 28 +++++----------------------- drivers/usb/serial/keyspan_pda.c | 6 ++---- drivers/usb/serial/mos7720.c | 8 ++------ drivers/usb/serial/mos7840.c | 7 ++----- drivers/usb/serial/ti_usb_3410_5052.c | 7 ++----- drivers/usb/serial/usb-serial.c | 10 +--------- include/linux/tty.h | 1 + 22 files changed, 51 insertions(+), 176 deletions(-) (limited to 'drivers') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index f1b38571f94e..cc206eda245c 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -248,7 +248,6 @@ static irqreturn_t line_write_interrupt(int irq, void *data) { struct chan *chan = data; struct line *line = chan->line; - struct tty_struct *tty; int err; /* @@ -267,12 +266,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) } spin_unlock(&line->lock); - tty = tty_port_tty_get(&line->port); - if (tty == NULL) - return IRQ_NONE; - - tty_wakeup(tty); - tty_kref_put(tty); + tty_port_tty_wakeup(&line->port); return IRQ_HANDLED; } diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 89562a845f6a..ac6f72b455d1 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -569,7 +569,6 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) { struct capidev *cdev = ap->private; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE - struct tty_struct *tty; struct capiminor *mp; u16 datahandle; struct capincci *np; @@ -627,11 +626,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2)); kfree_skb(skb); capiminor_del_ack(mp, datahandle); - tty = tty_port_tty_get(&mp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&mp->port); handle_minor_send(mp); } else { diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index e2b539675b66..600c79b030cd 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -487,12 +487,8 @@ static const struct tty_operations if_ops = { static void if_wake(unsigned long data) { struct cardstate *cs = (struct cardstate *)data; - struct tty_struct *tty = tty_port_tty_get(&cs->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&cs->port); } /*** interface to common ***/ diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e2dd3249b6bd..a7714b4f29ad 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1925,7 +1925,6 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) { struct hso_serial *serial = urb->context; int status = urb->status; - struct tty_struct *tty; /* sanity check */ if (!serial) { @@ -1941,11 +1940,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) return; } hso_put_activity(serial->parent); - tty = tty_port_tty_get(&serial->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&serial->port); hso_kick_transmit(serial); D1(" "); @@ -2008,12 +2003,8 @@ static void ctrl_callback(struct urb *urb) put_rxbuf_data_and_resubmit_ctrl_urb(serial); spin_unlock(&serial->serial_lock); } else { - struct tty_struct *tty = tty_port_tty_get(&serial->port); hso_put_activity(serial->parent); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&serial->port); /* response to a write command */ hso_kick_transmit(serial); } diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 14b4cb8abcc8..7ed7a5987816 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -107,7 +107,6 @@ sclp_tty_write_room (struct tty_struct *tty) static void sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) { - struct tty_struct *tty; unsigned long flags; void *page; @@ -125,12 +124,8 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) struct sclp_buffer, list); spin_unlock_irqrestore(&sclp_tty_lock, flags); } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); - /* check if the tty needs a wake up call */ - tty = tty_port_tty_get(&sclp_port); - if (tty != NULL) { - tty_wakeup(tty); - tty_kref_put(tty); - } + + tty_port_tty_wakeup(&sclp_port); } static inline void diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 6c92f62623be..5aaaa2ec8df4 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -114,7 +114,6 @@ static struct sclp_register sclp_vt220_register = { static void sclp_vt220_process_queue(struct sclp_vt220_request *request) { - struct tty_struct *tty; unsigned long flags; void *page; @@ -139,12 +138,7 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request) } while (__sclp_vt220_emit(request)); if (request == NULL && sclp_vt220_flush_later) sclp_vt220_emit_current(); - /* Check if the tty needs a wake up call */ - tty = tty_port_tty_get(&sclp_vt220_port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&sclp_vt220_port); } #define SCLP_BUFFER_MAX_RETRY 1 diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 5a6fb44f38a8..5c64e3a35b28 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -744,7 +744,6 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, struct fwtty_transaction *txn) { struct fwtty_port *port = txn->port; - struct tty_struct *tty; int len; fwtty_dbg(port, "rcode: %d", rcode); @@ -769,13 +768,8 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, port->stats.dropped += txn->dma_pended.len; } - if (len < WAKEUP_CHARS) { - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } + if (len < WAKEUP_CHARS) + tty_port_tty_wakeup(&port->port); } static int fwtty_tx(struct fwtty_port *port, bool drain) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index b1bb1a6abe81..8a6e5ea476e1 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -264,7 +264,6 @@ static void ProcessRxChar(struct usb_serial_port *port, unsigned char data) static void qt_write_bulk_callback(struct urb *urb) { - struct tty_struct *tty; int status; struct quatech_port *quatech_port; @@ -278,11 +277,7 @@ static void qt_write_bulk_callback(struct urb *urb) quatech_port = urb->context; - tty = tty_port_tty_get(&quatech_port->port->port); - - if (tty) - tty_wakeup(tty); - tty_kref_put(tty); + tty_port_tty_wakeup(&quatech_port->port->port); } static void qt_interrupt_callback(struct urb *urb) diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index ed92622b8949..6d0c27cd03da 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -472,13 +472,9 @@ static void ehv_bc_tx_dequeue(struct ehv_bc_data *bc) static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) { struct ehv_bc_data *bc = data; - struct tty_struct *ttys = tty_port_tty_get(&bc->port); ehv_bc_tx_dequeue(bc); - if (ttys) { - tty_wakeup(ttys); - tty_kref_put(ttys); - } + tty_port_tty_wakeup(&bc->port); return IRQ_HANDLED; } diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index ef95a154854a..41901997c0d6 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -861,7 +861,6 @@ static void hvsi_write_worker(struct work_struct *work) { struct hvsi_struct *hp = container_of(work, struct hvsi_struct, writer.work); - struct tty_struct *tty; unsigned long flags; #ifdef DEBUG static long start_j = 0; @@ -895,11 +894,7 @@ static void hvsi_write_worker(struct work_struct *work) start_j = 0; #endif /* DEBUG */ wake_up_all(&hp->emptyq); - tty = tty_port_tty_get(&hp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&hp->port); } out: diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 2dff19796157..2e5bbdc09e1c 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -791,7 +791,6 @@ static int send_data(enum port_type index, struct nozomi *dc) const u8 toggle = port->toggle_ul; void __iomem *addr = port->ul_addr[toggle]; const u32 ul_size = port->ul_size[toggle]; - struct tty_struct *tty = tty_port_tty_get(&port->port); /* Get data from tty and place in buf for now */ size = kfifo_out(&port->fifo_ul, dc->send_buf, @@ -799,7 +798,6 @@ static int send_data(enum port_type index, struct nozomi *dc) if (size == 0) { DBG4("No more data to send, disable link:"); - tty_kref_put(tty); return 0; } @@ -809,10 +807,8 @@ static int send_data(enum port_type index, struct nozomi *dc) write_mem32(addr, (u32 *) &size, 4); write_mem32(addr + 4, (u32 *) dc->send_buf, size); - if (tty) - tty_wakeup(tty); + tty_port_tty_wakeup(&port->port); - tty_kref_put(tty); return 1; } diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 68d7ce997ede..d723d4193b90 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -442,25 +442,6 @@ static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count, txbuffer[1] |= (more << IFX_SPI_MORE_BIT) & IFX_SPI_MORE_MASK; } -/** - * ifx_spi_wakeup_serial - SPI space made - * @port_data: our SPI device - * - * We have emptied the FIFO enough that we want to get more data - * queued into it. Poke the line discipline via tty_wakeup so that - * it will feed us more bits - */ -static void ifx_spi_wakeup_serial(struct ifx_spi_device *ifx_dev) -{ - struct tty_struct *tty; - - tty = tty_port_tty_get(&ifx_dev->tty_port); - if (!tty) - return; - tty_wakeup(tty); - tty_kref_put(tty); -} - /** * ifx_spi_prepare_tx_buffer - prepare transmit frame * @ifx_dev: our SPI device @@ -506,7 +487,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) tx_count += temp_count; if (temp_count == queue_length) /* poke port to get more data */ - ifx_spi_wakeup_serial(ifx_dev); + tty_port_tty_wakeup(&ifx_dev->tty_port); else /* more data in port, use next SPI message */ ifx_dev->spi_more = 1; } @@ -683,8 +664,6 @@ static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, static void ifx_spi_complete(void *ctx) { struct ifx_spi_device *ifx_dev = ctx; - struct tty_struct *tty; - struct tty_ldisc *ldisc = NULL; int length; int actual_length; unsigned char more; @@ -762,15 +741,7 @@ complete_exit: */ ifx_spi_power_state_clear(ifx_dev, IFX_SPI_POWER_DATA_PENDING); - tty = tty_port_tty_get(&ifx_dev->tty_port); - if (tty) { - ldisc = tty_ldisc_ref(tty); - if (ldisc) { - ldisc->ops->write_wakeup(tty); - tty_ldisc_deref(ldisc); - } - tty_kref_put(tty); - } + tty_port_tty_wakeup(&ifx_dev->tty_port); } } } diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index b7ff59d3db88..8bb757c62ee2 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -232,6 +232,22 @@ void tty_port_hangup(struct tty_port *port) } EXPORT_SYMBOL(tty_port_hangup); +/** + * tty_port_tty_wakeup - helper to wake up a tty + * + * @port: tty port + */ +void tty_port_tty_wakeup(struct tty_port *port) +{ + struct tty_struct *tty = tty_port_tty_get(port); + + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } +} +EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); + /** * tty_port_carrier_raised - carrier raised check * @port: tty port diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8ac25adf31b4..755766e4b756 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -475,15 +475,10 @@ static void acm_write_bulk(struct urb *urb) static void acm_softint(struct work_struct *work) { struct acm *acm = container_of(work, struct acm, work); - struct tty_struct *tty; dev_vdbg(&acm->data->dev, "%s\n", __func__); - tty = tty_port_tty_get(&acm->port); - if (!tty) - return; - tty_wakeup(tty); - tty_kref_put(tty); + tty_port_tty_wakeup(&acm->port); } /* diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ebe45fa0ed50..31191581060c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -210,7 +210,6 @@ struct digi_port { /* Local Function Declarations */ -static void digi_wakeup_write(struct usb_serial_port *port); static void digi_wakeup_write_lock(struct work_struct *work); static int digi_write_oob_command(struct usb_serial_port *port, unsigned char *buf, int count, int interruptible); @@ -374,20 +373,10 @@ static void digi_wakeup_write_lock(struct work_struct *work) unsigned long flags; spin_lock_irqsave(&priv->dp_port_lock, flags); - digi_wakeup_write(port); + tty_port_tty_wakeup(&port->port); spin_unlock_irqrestore(&priv->dp_port_lock, flags); } -static void digi_wakeup_write(struct usb_serial_port *port) -{ - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } -} - - /* * Digi Write OOB Command * @@ -1044,7 +1033,7 @@ static void digi_write_bulk_callback(struct urb *urb) } } /* wake up processes sleeping on writes immediately */ - digi_wakeup_write(port); + tty_port_tty_wakeup(&port->port); /* also queue up a wakeup at scheduler time, in case we */ /* lost the race in write_chan(). */ schedule_work(&priv->dp_wakeup_work); @@ -1522,7 +1511,7 @@ static int digi_read_oob_callback(struct urb *urb) /* port must be open to use tty struct */ if (rts) { tty->hw_stopped = 0; - digi_wakeup_write(port); + tty_port_tty_wakeup(&port->port); } } else { priv->dp_modem_signals &= ~TIOCM_CTS; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index b00e5cbf741f..44e5208f7c61 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -565,7 +565,6 @@ static void edge_interrupt_callback(struct urb *urb) struct device *dev; struct edgeport_port *edge_port; struct usb_serial_port *port; - struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int length = urb->actual_length; int bytes_avail; @@ -644,12 +643,7 @@ static void edge_interrupt_callback(struct urb *urb) /* tell the tty driver that something has changed */ - tty = tty_port_tty_get( - &edge_port->port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_port_tty_wakeup(&edge_port->port->port); /* Since we have more credit, check if more data can be sent */ send_more_port_data(edge_serial, @@ -738,7 +732,6 @@ static void edge_bulk_in_callback(struct urb *urb) static void edge_bulk_out_data_callback(struct urb *urb) { struct edgeport_port *edge_port = urb->context; - struct tty_struct *tty; int status = urb->status; if (status) { @@ -747,14 +740,8 @@ static void edge_bulk_out_data_callback(struct urb *urb) __func__, status); } - tty = tty_port_tty_get(&edge_port->port->port); - - if (tty && edge_port->open) { - /* let the tty driver wakeup if it has a special - write_wakeup function */ - tty_wakeup(tty); - } - tty_kref_put(tty); + if (edge_port->open) + tty_port_tty_wakeup(&edge_port->port->port); /* Release the Write URB */ edge_port->write_in_progress = false; @@ -773,7 +760,6 @@ static void edge_bulk_out_data_callback(struct urb *urb) static void edge_bulk_out_cmd_callback(struct urb *urb) { struct edgeport_port *edge_port = urb->context; - struct tty_struct *tty; int status = urb->status; atomic_dec(&CmdUrbs); @@ -794,13 +780,9 @@ static void edge_bulk_out_cmd_callback(struct urb *urb) return; } - /* Get pointer to tty */ - tty = tty_port_tty_get(&edge_port->port->port); - /* tell the tty driver that something has changed */ - if (tty && edge_port->open) - tty_wakeup(tty); - tty_kref_put(tty); + if (edge_port->open) + tty_port_tty_wakeup(&edge_port->port->port); /* we have completed the command */ edge_port->commandPending = false; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 3b17d5d13dc8..2230223978ca 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -104,10 +104,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) struct keyspan_pda_private *priv = container_of(work, struct keyspan_pda_private, wakeup_work); struct usb_serial_port *port = priv->port; - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) - tty_wakeup(tty); - tty_kref_put(tty); + + tty_port_tty_wakeup(&port->port); } static void keyspan_pda_request_unthrottle(struct work_struct *work) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e0ebec3b5d6a..e956eae198fd 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -932,7 +932,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) static void mos7720_bulk_out_data_callback(struct urb *urb) { struct moschip_port *mos7720_port; - struct tty_struct *tty; int status = urb->status; if (status) { @@ -946,11 +945,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) return ; } - tty = tty_port_tty_get(&mos7720_port->port->port); - - if (tty && mos7720_port->open) - tty_wakeup(tty); - tty_kref_put(tty); + if (mos7720_port->open) + tty_port_tty_wakeup(&mos7720_port->port->port); } /* diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 809fb329eca5..08284d28e84b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -814,7 +814,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) { struct moschip_port *mos7840_port; struct usb_serial_port *port; - struct tty_struct *tty; int status = urb->status; int i; @@ -837,10 +836,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) if (mos7840_port_paranoia_check(port, __func__)) return; - tty = tty_port_tty_get(&port->port); - if (tty && mos7840_port->open) - tty_wakeup(tty); - tty_kref_put(tty); + if (mos7840_port->open) + tty_port_tty_wakeup(&port->port); } diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 39cb9b807c3c..437f2d579cde 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1227,7 +1227,6 @@ static void ti_send(struct ti_port *tport) { int count, result; struct usb_serial_port *port = tport->tp_port; - struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */ unsigned long flags; spin_lock_irqsave(&tport->tp_lock, flags); @@ -1268,14 +1267,12 @@ static void ti_send(struct ti_port *tport) } /* more room in the buffer for new writes, wakeup */ - if (tty) - tty_wakeup(tty); - tty_kref_put(tty); + tty_port_tty_wakeup(&port->port); + wake_up_interruptible(&tport->tp_write_wait); return; unlock: spin_unlock_irqrestore(&tport->tp_lock, flags); - tty_kref_put(tty); return; } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a19ed74d770d..2df84845bafb 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -541,16 +541,8 @@ static void usb_serial_port_work(struct work_struct *work) { struct usb_serial_port *port = container_of(work, struct usb_serial_port, work); - struct tty_struct *tty; - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - - tty_wakeup(tty); - tty_kref_put(tty); + tty_port_tty_wakeup(&port->port); } static void kill_traffic(struct usb_serial_port *port) diff --git a/include/linux/tty.h b/include/linux/tty.h index 63b62865c8e9..b6e890a87eb1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -534,6 +534,7 @@ extern int tty_port_carrier_raised(struct tty_port *port); extern void tty_port_raise_dtr_rts(struct tty_port *port); extern void tty_port_lower_dtr_rts(struct tty_port *port); extern void tty_port_hangup(struct tty_port *port); +extern void tty_port_tty_wakeup(struct tty_port *port); extern int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp); extern int tty_port_close_start(struct tty_port *port, -- cgit From e4408ce3c23f8451eff7a2954694598fb8fce833 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:31 +0100 Subject: TTY: quatech2, remove unneeded is_open tty->ops->break_ctl cannot be called outside the gap between open and close. So there is no need to check whether the port is open in break_ctl in quatech2. Remove the check and also that member completely. Signed-off-by: Jiri Slaby Cc: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/quatech2.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 00e6c9bac8a3..d8531047b41a 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -116,7 +116,6 @@ struct qt2_serial_private { }; struct qt2_port_private { - bool is_open; u8 device_port; spinlock_t urb_lock; @@ -398,7 +397,6 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) return status; } - port_priv->is_open = true; port_priv->device_port = (u8) device_port; if (tty) @@ -418,8 +416,6 @@ static void qt2_close(struct usb_serial_port *port) serial = port->serial; port_priv = usb_get_serial_port_data(port); - port_priv->is_open = false; - spin_lock_irqsave(&port_priv->urb_lock, flags); usb_kill_urb(port_priv->write_urb); port_priv->urb_in_use = false; @@ -905,12 +901,6 @@ static void qt2_break_ctl(struct tty_struct *tty, int break_state) port_priv = usb_get_serial_port_data(port); - if (!port_priv->is_open) { - dev_err(&port->dev, - "%s - port is not open\n", __func__); - return; - } - val = (break_state == -1) ? 1 : 0; status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL, -- cgit From aa27a094e2c2e0cc59914e56113b860f524f4479 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:30 +0100 Subject: TTY: add tty_port_tty_hangup helper It allows for cleaning up on a considerable amount of places. They did port_get, hangup, kref_put. Now the only thing needed is to call tty_port_tty_hangup which does exactly that. And they can also decide whether to consider CLOCAL or completely ignore that. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/um/drivers/chan_kern.c | 6 +----- drivers/mmc/card/sdio_uart.c | 13 ++--------- drivers/net/usb/hso.c | 7 +----- drivers/tty/cyclades.c | 10 ++------- drivers/tty/moxa.c | 19 ++++++---------- drivers/tty/n_gsm.c | 6 +----- drivers/tty/nozomi.c | 9 +++----- drivers/tty/rocket.c | 7 +----- drivers/tty/serial/ifx6x60.c | 21 ++---------------- drivers/tty/tty_port.c | 17 +++++++++++++++ drivers/usb/class/cdc-acm.c | 24 ++++++--------------- drivers/usb/serial/keyspan.c | 43 +++++++++---------------------------- drivers/usb/serial/option.c | 9 ++------ drivers/usb/serial/sierra.c | 8 ++----- include/linux/tty.h | 1 + net/irda/ircomm/ircomm_tty_attach.c | 6 +----- 16 files changed, 58 insertions(+), 148 deletions(-) (limited to 'drivers') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 15c553c239a1..bf42825ba54f 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq) reactivate_fd(chan->fd, irq); if (err == -EIO) { if (chan->primary) { - struct tty_struct *tty = tty_port_tty_get(&line->port); - if (tty != NULL) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&line->port, false); if (line->chan_out != chan) close_one_chan(line->chan_out, 1); } diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index c931dfe6a59c..f093cea0d060 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -134,7 +134,6 @@ static void sdio_uart_port_put(struct sdio_uart_port *port) static void sdio_uart_port_remove(struct sdio_uart_port *port) { struct sdio_func *func; - struct tty_struct *tty; BUG_ON(sdio_uart_table[port->index] != port); @@ -155,12 +154,8 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port) sdio_claim_host(func); port->func = NULL; mutex_unlock(&port->func_lock); - tty = tty_port_tty_get(&port->port); /* tty_hangup is async so is this safe as is ?? */ - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&port->port, false); mutex_unlock(&port->port.mutex); sdio_release_irq(func); sdio_disable_func(func); @@ -492,11 +487,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) wake_up_interruptible(&port->port.open_wait); else { /* DCD drop - hang up if tty attached */ - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&port->port, false); } } if (status & UART_MSR_DCTS) { diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index a7714b4f29ad..cba1d46e672e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -3124,18 +3124,13 @@ static void hso_serial_ref_free(struct kref *ref) static void hso_free_interface(struct usb_interface *interface) { struct hso_serial *hso_dev; - struct tty_struct *tty; int i; for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { if (serial_table[i] && (serial_table[i]->interface == interface)) { hso_dev = dev2ser(serial_table[i]); - tty = tty_port_tty_get(&hso_dev->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&hso_dev->port, false); mutex_lock(&hso_dev->parent->mutex); hso_dev->parent->usb_gone = 1; mutex_unlock(&hso_dev->parent->mutex); diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 345bd0e0884e..33f83fee9fae 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -1124,14 +1124,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) readl(&info->u.cyz.ch_ctrl->rs_status); if (dcd & C_RS_DCD) wake_up_interruptible(&info->port.open_wait); - else { - struct tty_struct *tty; - tty = tty_port_tty_get(&info->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } + else + tty_port_tty_hangup(&info->port, false); } break; case C_CM_MCTS: diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index adeac255e526..1deaca4674e4 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -913,16 +913,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) /* pci hot-un-plug support */ for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { - struct tty_struct *tty = tty_port_tty_get( - &brd->ports[a].port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } + if (brd->ports[a].port.flags & ASYNC_INITIALIZED) + tty_port_tty_hangup(&brd->ports[a].port, false); + for (a = 0; a < MAX_PORTS_PER_BOARD; a++) tty_port_destroy(&brd->ports[a].port); + while (1) { opened = 0; for (a = 0; a < brd->numPorts; a++) @@ -1365,7 +1361,6 @@ static void moxa_hangup(struct tty_struct *tty) static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) { - struct tty_struct *tty; unsigned long flags; dcd = !!dcd; @@ -1373,10 +1368,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) if (dcd != p->DCDState) { p->DCDState = dcd; spin_unlock_irqrestore(&p->port.lock, flags); - tty = tty_port_tty_get(&p->port); - if (tty && !C_CLOCAL(tty) && !dcd) - tty_hangup(tty); - tty_kref_put(tty); + if (!dcd) + tty_port_tty_hangup(&p->port, true); } else spin_unlock_irqrestore(&p->port.lock, flags); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 4a43ef5d7962..74d9a0258d7c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1418,11 +1418,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) pr_debug("DLCI %d goes closed.\n", dlci->addr); dlci->state = DLCI_CLOSED; if (dlci->addr != 0) { - struct tty_struct *tty = tty_port_tty_get(&dlci->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&dlci->port, false); kfifo_reset(dlci->fifo); } else dlci->gsm->dead = 1; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 2e5bbdc09e1c..d6080c3831ef 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1501,12 +1501,9 @@ static void tty_exit(struct nozomi *dc) DBG1(" "); - for (i = 0; i < MAX_PORT; ++i) { - struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); - if (tty && list_empty(&tty->hangup_work.entry)) - tty_hangup(tty); - tty_kref_put(tty); - } + for (i = 0; i < MAX_PORT; ++i) + tty_port_tty_hangup(&dc->port[i].port, false); + /* Racy below - surely should wait for scheduled work to be done or complete off a hangup method ? */ while (dc->open_ttys) diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 1d270034bfc3..bbffd7a431e9 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -521,15 +521,10 @@ static void rp_handle_port(struct r_port *info) (ChanStatus & CD_ACT) ? "on" : "off"); #endif if (!(ChanStatus & CD_ACT) && info->cd_status) { - struct tty_struct *tty; #ifdef ROCKET_DEBUG_HANGUP printk(KERN_INFO "CD drop, calling hangup.\n"); #endif - tty = tty_port_tty_get(&info->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&info->port, false); } info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; wake_up_interruptible(&info->port.open_wait); diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index d723d4193b90..2c77fed31a72 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -269,23 +269,6 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev) mrdy_set_high(ifx_dev); } -/** - * ifx_spi_hangup - hang up an IFX device - * @ifx_dev: our SPI device - * - * Hang up the tty attached to the IFX device if one is currently - * open. If not take no action - */ -static void ifx_spi_ttyhangup(struct ifx_spi_device *ifx_dev) -{ - struct tty_port *pport = &ifx_dev->tty_port; - struct tty_struct *tty = tty_port_tty_get(pport); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } -} - /** * ifx_spi_timeout - SPI timeout * @arg: our SPI device @@ -298,7 +281,7 @@ static void ifx_spi_timeout(unsigned long arg) struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); - ifx_spi_ttyhangup(ifx_dev); + tty_port_tty_hangup(&ifx_dev->tty_port, false); mrdy_set_low(ifx_dev); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); } @@ -933,7 +916,7 @@ static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev) set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); if (!solreset) { /* unsolicited reset */ - ifx_spi_ttyhangup(ifx_dev); + tty_port_tty_hangup(&ifx_dev->tty_port, false); } } else { /* exited reset */ diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 8bb757c62ee2..7f38eeaafac3 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -232,6 +232,23 @@ void tty_port_hangup(struct tty_port *port) } EXPORT_SYMBOL(tty_port_hangup); +/** + * tty_port_tty_hangup - helper to hang up a tty + * + * @port: tty port + * @check_clocal: hang only ttys with CLOCAL unset? + */ +void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) +{ + struct tty_struct *tty = tty_port_tty_get(port); + + if (tty && (!check_clocal || !C_CLOCAL(tty))) { + tty_hangup(tty); + tty_kref_put(tty); + } +} +EXPORT_SYMBOL_GPL(tty_port_tty_hangup); + /** * tty_port_tty_wakeup - helper to wake up a tty * diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 755766e4b756..27a18743275e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -292,7 +292,6 @@ static void acm_ctrl_irq(struct urb *urb) { struct acm *acm = urb->context; struct usb_cdc_notification *dr = urb->transfer_buffer; - struct tty_struct *tty; unsigned char *data; int newctrl; int retval; @@ -327,17 +326,12 @@ static void acm_ctrl_irq(struct urb *urb) break; case USB_CDC_NOTIFY_SERIAL_STATE: - tty = tty_port_tty_get(&acm->port); newctrl = get_unaligned_le16(data); - if (tty) { - if (!acm->clocal && - (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { - dev_dbg(&acm->control->dev, - "%s - calling hangup\n", __func__); - tty_hangup(tty); - } - tty_kref_put(tty); + if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { + dev_dbg(&acm->control->dev, "%s - calling hangup\n", + __func__); + tty_port_tty_hangup(&acm->port, false); } acm->ctrlin = newctrl; @@ -1498,15 +1492,9 @@ err_out: static int acm_reset_resume(struct usb_interface *intf) { struct acm *acm = usb_get_intfdata(intf); - struct tty_struct *tty; - if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { - tty = tty_port_tty_get(&acm->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } + if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) + tty_port_tty_hangup(&acm->port, false); return acm_resume(intf); } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 1fd1935c8316..b011478d2e5f 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -378,7 +378,6 @@ static void usa26_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state, err; int status = urb->status; @@ -421,12 +420,8 @@ static void usa26_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state != p_priv->dcd_state) + tty_port_tty_hangup(&port->port, true); /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); @@ -510,7 +505,6 @@ static void usa28_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state; int status = urb->status; @@ -551,12 +545,8 @@ static void usa28_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) + tty_port_tty_hangup(&port->port, true); /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); @@ -642,12 +632,8 @@ static void usa49_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) + tty_port_tty_hangup(&port->port, true); /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); @@ -851,7 +837,6 @@ static void usa90_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state, err; int status = urb->status; @@ -880,12 +865,8 @@ static void usa90_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) + tty_port_tty_hangup(&port->port, true); /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); @@ -953,12 +934,8 @@ static void usa67_instat_callback(struct urb *urb) p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) + tty_port_tty_hangup(&port->port, true); /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f7d339d8187b..602d1f389a3b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1532,13 +1532,8 @@ static void option_instat_callback(struct urb *urb) portdata->dsr_state = ((signals & 0x02) ? 1 : 0); portdata->ri_state = ((signals & 0x08) ? 1 : 0); - if (old_dcd_state && !portdata->dcd_state) { - struct tty_struct *tty = - tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (old_dcd_state && !portdata->dcd_state) + tty_port_tty_hangup(&port->port, true); } else { dev_dbg(dev, "%s: type %x req %x\n", __func__, req_pkt->bRequestType, req_pkt->bRequest); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index c13f6e747748..d66148a17fe3 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -628,7 +628,6 @@ static void sierra_instat_callback(struct urb *urb) unsigned char signals = *((unsigned char *) urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); - struct tty_struct *tty; dev_dbg(&port->dev, "%s: signal x%x\n", __func__, signals); @@ -639,11 +638,8 @@ static void sierra_instat_callback(struct urb *urb) portdata->dsr_state = ((signals & 0x02) ? 1 : 0); portdata->ri_state = ((signals & 0x08) ? 1 : 0); - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty) && - old_dcd_state && !portdata->dcd_state) - tty_hangup(tty); - tty_kref_put(tty); + if (old_dcd_state && !portdata->dcd_state) + tty_port_tty_hangup(&port->port, true); } else { dev_dbg(&port->dev, "%s: type %x req %x\n", __func__, req_pkt->bRequestType, diff --git a/include/linux/tty.h b/include/linux/tty.h index b6e890a87eb1..d3548f871968 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -534,6 +534,7 @@ extern int tty_port_carrier_raised(struct tty_port *port); extern void tty_port_raise_dtr_rts(struct tty_port *port); extern void tty_port_lower_dtr_rts(struct tty_port *port); extern void tty_port_hangup(struct tty_port *port); +extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); extern void tty_port_tty_wakeup(struct tty_port *port); extern int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp); diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index edab393e0c82..a2a508f5f268 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c @@ -997,12 +997,8 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, self->settings.dce = IRCOMM_DELTA_CD; ircomm_tty_check_modem_status(self); } else { - struct tty_struct *tty = tty_port_tty_get(&self->port); IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + tty_port_tty_hangup(&self->port, false); } break; default: -- cgit From e99c33b9d3abfbba5ff34a16579a8e0a9e3211c4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:32 +0100 Subject: TTY: serial/bfin_uart, unbreak build with KGDB enabled There are no (and never were any) kgdb fields in uart_ops. Setting them produces a build error: drivers/tty/serial/bfin_uart.c:1054:2: error: unknown field 'kgdboc_port_startup' specified in initializer drivers/tty/serial/bfin_uart.c:1054:2: warning: initialization from incompatible pointer type [enabled by default] drivers/tty/serial/bfin_uart.c:1054:2: warning: (near initialization for 'bfin_serial_pops.ioctl') [enabled by default] drivers/tty/serial/bfin_uart.c:1055:2: error: unknown field 'kgdboc_port_shutdown' specified in initializer drivers/tty/serial/bfin_uart.c:1055:2: warning: initialization from incompatible pointer type [enabled by default] drivers/tty/serial/bfin_uart.c:1055:2: warning: (near initialization for 'bfin_serial_pops.poll_init') [enabled by default] Remove them. Signed-off-by: Jiri Slaby Acked-by: Sonic Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bfin_uart.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 12dceda9db33..26a3be7ced7d 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -1011,24 +1011,6 @@ static int bfin_serial_poll_get_char(struct uart_port *port) } #endif -#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ - defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) -static void bfin_kgdboc_port_shutdown(struct uart_port *port) -{ - if (kgdboc_break_enabled) { - kgdboc_break_enabled = 0; - bfin_serial_shutdown(port); - } -} - -static int bfin_kgdboc_port_startup(struct uart_port *port) -{ - kgdboc_port_line = port->line; - kgdboc_break_enabled = !bfin_serial_startup(port); - return 0; -} -#endif - static struct uart_ops bfin_serial_pops = { .tx_empty = bfin_serial_tx_empty, .set_mctrl = bfin_serial_set_mctrl, @@ -1047,11 +1029,6 @@ static struct uart_ops bfin_serial_pops = { .request_port = bfin_serial_request_port, .config_port = bfin_serial_config_port, .verify_port = bfin_serial_verify_port, -#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ - defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) - .kgdboc_port_startup = bfin_kgdboc_port_startup, - .kgdboc_port_shutdown = bfin_kgdboc_port_shutdown, -#endif #ifdef CONFIG_CONSOLE_POLL .poll_put_char = bfin_serial_poll_put_char, .poll_get_char = bfin_serial_poll_get_char, -- cgit From 4d29994ddb4cc97e19a533834df2e0fdb1c1d8a8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:33 +0100 Subject: TTY: serial/msm_serial_hs, remove unused tty Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial_hs.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 4a942c78347e..4ca2f64861e6 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -907,7 +907,6 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, unsigned int error_f = 0; unsigned long flags; unsigned int flush; - struct tty_struct *tty; struct tty_port *port; struct uart_port *uport; struct msm_hs_port *msm_uport; @@ -919,7 +918,6 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, clk_enable(msm_uport->clk); port = &uport->state->port; - tty = port->tty; msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); -- cgit From ee7970690568b0c875467f475d9c957ec0d9e099 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:34 +0100 Subject: TTY: cleanup tty->hw_stopped uses tty->hw_stopped is set only by drivers to remember HW state. If it is never set to 1 in a particular driver, there is no need to check it in the driver at all. Remove such checks. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/ia64/hp/sim/simserial.c | 16 +++------------- drivers/isdn/i4l/isdn_tty.c | 3 --- drivers/net/caif/caif_serial.c | 1 - drivers/tty/rocket.c | 19 ++++++++----------- drivers/tty/serial/68328serial.c | 9 +++------ drivers/tty/serial/arc_uart.c | 2 +- drivers/tty/serial/crisv10.c | 12 ++---------- 7 files changed, 17 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index da2f319fb71d..e70cadec7ce6 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -142,8 +142,7 @@ static void transmit_chars(struct tty_struct *tty, struct serial_state *info, goto out; } - if (info->xmit.head == info->xmit.tail || tty->stopped || - tty->hw_stopped) { + if (info->xmit.head == info->xmit.tail || tty->stopped) { #ifdef SIMSERIAL_DEBUG printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", info->xmit.head, info->xmit.tail, tty->stopped); @@ -181,7 +180,7 @@ static void rs_flush_chars(struct tty_struct *tty) struct serial_state *info = tty->driver_data; if (info->xmit.head == info->xmit.tail || tty->stopped || - tty->hw_stopped || !info->xmit.buf) + !info->xmit.buf) return; transmit_chars(tty, info, NULL); @@ -217,7 +216,7 @@ static int rs_write(struct tty_struct * tty, * Hey, we transmit directly from here in our case */ if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && - !tty->stopped && !tty->hw_stopped) + !tty->stopped) transmit_chars(tty, info, NULL); return ret; @@ -325,14 +324,6 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) -static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios.c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - } -} /* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. @@ -481,7 +472,6 @@ static const struct tty_operations hp_ops = { .throttle = rs_throttle, .unthrottle = rs_unthrottle, .send_xchar = rs_send_xchar, - .set_termios = rs_set_termios, .hangup = rs_hangup, .proc_fops = &rs_proc_fops, }; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index d8a7d8323414..221076628585 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1470,9 +1470,6 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) tty->termios.c_ospeed == old_termios->c_ospeed) return; isdn_tty_change_speed(info); - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios.c_cflag & CRTSCTS)) - tty->hw_stopped = 0; } } diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 666891a9a248..d1bf0ff93ae0 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -88,7 +88,6 @@ static inline void update_tty_status(struct ser_device *ser) { ser->tty_status = ser->tty->stopped << 5 | - ser->tty->hw_stopped << 4 | ser->tty->flow_stopped << 3 | ser->tty->packet << 2 | ser->tty->port->low_latency << 1 | diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index bbffd7a431e9..f5abc2888821 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -449,7 +449,7 @@ static void rp_do_transmit(struct r_port *info) /* Loop sending data to FIFO until done or FIFO full */ while (1) { - if (tty->stopped || tty->hw_stopped) + if (tty->stopped) break; c = min(info->xmit_fifo_room, info->xmit_cnt); c = min(c, XMIT_BUF_SIZE - info->xmit_tail); @@ -1106,15 +1106,12 @@ static void rp_set_termios(struct tty_struct *tty, /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { - if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS)) - sSetRTS(cp); + sSetRTS(cp); sSetDTR(cp); } - if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; + if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) rp_start(tty); - } } static int rp_break(struct tty_struct *tty, int break_state) @@ -1570,10 +1567,10 @@ static int rp_put_char(struct tty_struct *tty, unsigned char ch) spin_lock_irqsave(&info->slock, flags); cp = &info->channel; - if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0) + if (!tty->stopped && info->xmit_fifo_room == 0) info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); - if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { + if (tty->stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { info->xmit_buf[info->xmit_head++] = ch; info->xmit_head &= XMIT_BUF_SIZE - 1; info->xmit_cnt++; @@ -1614,14 +1611,14 @@ static int rp_write(struct tty_struct *tty, #endif cp = &info->channel; - if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count) + if (!tty->stopped && info->xmit_fifo_room < count) info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); /* * If the write queue for the port is empty, and there is FIFO space, stuff bytes * into FIFO. Use the write queue for temp storage. */ - if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { + if (!tty->stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { c = min(count, info->xmit_fifo_room); b = buf; @@ -1669,7 +1666,7 @@ static int rp_write(struct tty_struct *tty, retval += c; } - if ((retval > 0) && !tty->stopped && !tty->hw_stopped) + if ((retval > 0) && !tty->stopped) set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); end: diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 49399470794d..ef2e08e9b590 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -630,8 +630,7 @@ static void rs_flush_chars(struct tty_struct *tty) /* Enable transmitter */ local_irq_save(flags); - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) { + if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf) { local_irq_restore(flags); return; } @@ -697,7 +696,7 @@ static int rs_write(struct tty_struct * tty, total += c; } - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + if (info->xmit_cnt && !tty->stopped) { /* Enable transmitter */ local_irq_disable(); #ifndef USE_INTS @@ -978,10 +977,8 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) change_speed(info, tty); if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios.c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; + !(tty->termios.c_cflag & CRTSCTS)) rs_start(tty); - } } diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index d97e194b6bc5..cbf1d155b7b2 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -162,7 +162,7 @@ static unsigned int arc_serial_tx_empty(struct uart_port *port) /* * Driver internal routine, used by both tty(serial core) as well as tx-isr * -Called under spinlock in either cases - * -also tty->stopped / tty->hw_stopped has already been checked + * -also tty->stopped has already been checked * = by uart_start( ) before calling us * = tx_ist checks that too before calling */ diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 5f37c31e32bc..50f56f39d436 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -2534,8 +2534,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) } /* Normal char-by-char interrupt */ if (info->xmit.head == info->xmit.tail - || info->port.tty->stopped - || info->port.tty->hw_stopped) { + || info->port.tty->stopped) { DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->port.tty->stopped)); e100_disable_serial_tx_ready_irq(info); @@ -3098,7 +3097,6 @@ rs_flush_chars(struct tty_struct *tty) if (info->tr_running || info->xmit.head == info->xmit.tail || tty->stopped || - tty->hw_stopped || !info->xmit.buf) return; @@ -3176,7 +3174,6 @@ static int rs_raw_write(struct tty_struct *tty, if (info->xmit.head != info->xmit.tail && !tty->stopped && - !tty->hw_stopped && !info->tr_running) { start_transmit(info); } @@ -3733,10 +3730,8 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios.c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; + !(tty->termios.c_cflag & CRTSCTS)) rs_start(tty); - } } @@ -4256,9 +4251,6 @@ static void seq_line_info(struct seq_file *m, struct e100_serial *info) if (info->port.tty->stopped) seq_printf(m, " stopped:%i", (int)info->port.tty->stopped); - if (info->port.tty->hw_stopped) - seq_printf(m, " hw_stopped:%i", - (int)info->port.tty->hw_stopped); } { -- cgit From b1d984cf7d6b7d4e395f1aa6a0a4d3d1ecf21495 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:36 +0100 Subject: crisv10: use flags from tty_port First, remove STD_FLAGS as the value, or its subvalues (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) is not tested anywhere -- there is no point to initialize flags to that. Second, use flags member from tty_port when we have it now. So that we do not waste space. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.c | 64 ++++++++++++++++++++------------------------ drivers/tty/serial/crisv10.h | 2 -- 2 files changed, 29 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 50f56f39d436..2ae378cc65b6 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -169,7 +169,6 @@ static int get_lsr_info(struct e100_serial *info, unsigned int *value); #define DEF_BAUD 115200 /* 115.2 kbit/s */ -#define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) #define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ #define DEF_TX 0x80 /* or SERIAL_CTRL_B */ @@ -246,7 +245,6 @@ static struct e100_serial rs_table[] = { .ifirstadr = R_DMA_CH7_FIRST, .icmdadr = R_DMA_CH7_CMD, .idescradr = R_DMA_CH7_DESCR, - .flags = STD_FLAGS, .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 2, @@ -300,7 +298,6 @@ static struct e100_serial rs_table[] = { .ifirstadr = R_DMA_CH9_FIRST, .icmdadr = R_DMA_CH9_CMD, .idescradr = R_DMA_CH9_DESCR, - .flags = STD_FLAGS, .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 3, @@ -356,7 +353,6 @@ static struct e100_serial rs_table[] = { .ifirstadr = R_DMA_CH3_FIRST, .icmdadr = R_DMA_CH3_CMD, .idescradr = R_DMA_CH3_DESCR, - .flags = STD_FLAGS, .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 0, @@ -410,7 +406,6 @@ static struct e100_serial rs_table[] = { .ifirstadr = R_DMA_CH5_FIRST, .icmdadr = R_DMA_CH5_CMD, .idescradr = R_DMA_CH5_DESCR, - .flags = STD_FLAGS, .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 1, @@ -2721,7 +2716,7 @@ startup(struct e100_serial * info) /* if it was already initialized, skip this */ - if (info->flags & ASYNC_INITIALIZED) { + if (info->port.flags & ASYNC_INITIALIZED) { local_irq_restore(flags); free_page(xmit_page); return 0; @@ -2846,7 +2841,7 @@ startup(struct e100_serial * info) #endif /* CONFIG_SVINTO_SIM */ - info->flags |= ASYNC_INITIALIZED; + info->port.flags |= ASYNC_INITIALIZED; local_irq_restore(flags); return 0; @@ -2891,7 +2886,7 @@ shutdown(struct e100_serial * info) #endif /* CONFIG_SVINTO_SIM */ - if (!(info->flags & ASYNC_INITIALIZED)) + if (!(info->port.flags & ASYNC_INITIALIZED)) return; #ifdef SERIAL_DEBUG_OPEN @@ -2922,7 +2917,7 @@ shutdown(struct e100_serial * info) if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->flags &= ~ASYNC_INITIALIZED; + info->port.flags &= ~ASYNC_INITIALIZED; local_irq_restore(flags); } @@ -2947,7 +2942,7 @@ change_speed(struct e100_serial *info) /* possibly, the tx/rx should be disabled first to do this safely */ /* change baud-rate and write it to the hardware */ - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { + if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { /* Special baudrate */ u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ unsigned long alt_source = @@ -3397,7 +3392,7 @@ get_serial_info(struct e100_serial * info, tmp.line = info->line; tmp.port = (int)info->ioport; tmp.irq = info->irq; - tmp.flags = info->flags; + tmp.flags = info->port.flags; tmp.baud_base = info->baud_base; tmp.close_delay = info->close_delay; tmp.closing_wait = info->closing_wait; @@ -3424,9 +3419,9 @@ set_serial_info(struct e100_serial *info, if ((new_serial.type != info->type) || (new_serial.close_delay != info->close_delay) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (info->flags & ~ASYNC_USR_MASK))) + (info->port.flags & ~ASYNC_USR_MASK))) return -EPERM; - info->flags = ((info->flags & ~ASYNC_USR_MASK) | + info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); goto check_and_exit; } @@ -3440,16 +3435,16 @@ set_serial_info(struct e100_serial *info, */ info->baud_base = new_serial.baud_base; - info->flags = ((info->flags & ~ASYNC_FLAGS) | + info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); info->custom_divisor = new_serial.custom_divisor; info->type = new_serial.type; info->close_delay = new_serial.close_delay; info->closing_wait = new_serial.closing_wait; - info->port.low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: - if (info->flags & ASYNC_INITIALIZED) { + if (info->port.flags & ASYNC_INITIALIZED) { change_speed(info); } else retval = startup(info); @@ -3789,12 +3784,12 @@ rs_close(struct tty_struct *tty, struct file * filp) local_irq_restore(flags); return; } - info->flags |= ASYNC_CLOSING; + info->port.flags |= ASYNC_CLOSING; /* * Save the termios structure, since this port may have * separate termios for callout and dialin. */ - if (info->flags & ASYNC_NORMAL_ACTIVE) + if (info->port.flags & ASYNC_NORMAL_ACTIVE) info->normal_termios = tty->termios; /* * Now we wait for the transmit buffer to clear; and we notify @@ -3815,7 +3810,7 @@ rs_close(struct tty_struct *tty, struct file * filp) e100_disable_rx(info); e100_disable_rx_irq(info); - if (info->flags & ASYNC_INITIALIZED) { + if (info->port.flags & ASYNC_INITIALIZED) { /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially @@ -3836,7 +3831,7 @@ rs_close(struct tty_struct *tty, struct file * filp) schedule_timeout_interruptible(info->close_delay); wake_up_interruptible(&info->open_wait); } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); + info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); local_irq_restore(flags); @@ -3931,7 +3926,7 @@ rs_hangup(struct tty_struct *tty) shutdown(info); info->event = 0; info->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; + info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; wake_up_interruptible(&info->open_wait); } @@ -3955,11 +3950,11 @@ block_til_ready(struct tty_struct *tty, struct file * filp, * until it's done, and then try again. */ if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { + (info->port.flags & ASYNC_CLOSING)) { wait_event_interruptible_tty(tty, info->close_wait, - !(info->flags & ASYNC_CLOSING)); + !(info->port.flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) + if (info->port.flags & ASYNC_HUP_NOTIFY) return -EAGAIN; else return -ERESTARTSYS; @@ -3974,7 +3969,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, */ if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { - info->flags |= ASYNC_NORMAL_ACTIVE; + info->port.flags |= ASYNC_NORMAL_ACTIVE; return 0; } @@ -4010,9 +4005,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, local_irq_restore(flags); set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { + !(info->port.flags & ASYNC_INITIALIZED)) { #ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) + if (info->port.flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else retval = -ERESTARTSYS; @@ -4021,7 +4016,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, #endif break; } - if (!(info->flags & ASYNC_CLOSING) && do_clocal) + if (!(info->port.flags & ASYNC_CLOSING) && do_clocal) /* && (do_clocal || DCD_IS_ASSERTED) */ break; if (signal_pending(current)) { @@ -4047,7 +4042,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, #endif if (retval) return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; + info->port.flags |= ASYNC_NORMAL_ACTIVE; return 0; } @@ -4088,17 +4083,17 @@ rs_open(struct tty_struct *tty, struct file * filp) tty->driver_data = info; info->port.tty = tty; - info->port.low_latency = !!(info->flags & ASYNC_LOW_LATENCY); + info->port.low_latency = !!(info->port.flags & ASYNC_LOW_LATENCY); /* * If the port is in the middle of closing, bail out now */ if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { + (info->port.flags & ASYNC_CLOSING)) { wait_event_interruptible_tty(tty, info->close_wait, - !(info->flags & ASYNC_CLOSING)); + !(info->port.flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? + return ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); #else return -EAGAIN; @@ -4198,7 +4193,7 @@ rs_open(struct tty_struct *tty, struct file * filp) return retval; } - if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { + if ((info->count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) { tty->termios = info->normal_termios; change_speed(info); } @@ -4447,7 +4442,6 @@ static int __init rs_init(void) info->forced_eop = 0; info->baud_base = DEF_BAUD_BASE; info->custom_divisor = 0; - info->flags = 0; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; info->x_char = 0; diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index ea0beb46a10d..7146ed29d508 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -53,8 +53,6 @@ struct e100_serial { volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ - int flags; /* defined in tty.h */ - u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ u8 iseteop; /* bit number for R_SET_EOP for the input dma */ -- cgit From 12aad550f005fef2dd0ad40e4978549f64f8f296 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:35 +0100 Subject: crisv10: stop returning info from handle_ser_rx_interrupt The return value is not used anywhere, so no need to return anything. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 2ae378cc65b6..ec2dcc726385 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -2258,8 +2258,7 @@ TODO: The break will be delayed until an F or V character is received. */ -static -struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) +static void handle_ser_rx_interrupt_no_dma(struct e100_serial *info) { unsigned long data_read; @@ -2365,10 +2364,9 @@ more_data: } tty_flip_buffer_push(&info->port); - return info; } -static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) +static void handle_ser_rx_interrupt(struct e100_serial *info) { unsigned char rstat; @@ -2377,7 +2375,8 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) #endif /* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ if (!info->uses_dma_in) { - return handle_ser_rx_interrupt_no_dma(info); + handle_ser_rx_interrupt_no_dma(info); + return; } /* DMA is used */ rstat = info->ioport[REG_STATUS]; @@ -2484,7 +2483,6 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) /* Restarting the DMA never hurts */ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); START_FLUSH_FAST_TIMER(info, "ser_int"); - return info; } /* handle_ser_rx_interrupt */ static void handle_ser_tx_interrupt(struct e100_serial *info) -- cgit From 82c3b87b7e0153c5a05ac994cd5586df41264cb6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:37 +0100 Subject: crisv10: remove unused members Well, all those are unused. They were perhaps copied from generic serial structure ages ago. Remove them for good. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index 7146ed29d508..59f70c4cc860 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -86,15 +86,10 @@ struct e100_serial { volatile int tr_running; /* 1 if output is running */ - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; int x_char; /* xon/xoff character */ int close_delay; unsigned short closing_wait; - unsigned short closing_wait2; unsigned long event; - unsigned long last_active; int line; int type; /* PORT_ETRAX */ int count; /* # of fd on device */ @@ -108,7 +103,6 @@ struct e100_serial { struct work_struct work; struct async_icount icount; /* error-statistics etc.*/ struct ktermios normal_termios; - struct ktermios callout_termios; wait_queue_head_t open_wait; wait_queue_head_t close_wait; -- cgit From 892c7cfc16f4379e04983f2b58cdfc35f486d269 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:38 +0100 Subject: crisv10: use close delays from tty_port The same as flags, convert to using close delays from tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.c | 20 +++++++++----------- drivers/tty/serial/crisv10.h | 2 -- 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index ec2dcc726385..0e75ec331c05 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3392,8 +3392,8 @@ get_serial_info(struct e100_serial * info, tmp.irq = info->irq; tmp.flags = info->port.flags; tmp.baud_base = info->baud_base; - tmp.close_delay = info->close_delay; - tmp.closing_wait = info->closing_wait; + tmp.close_delay = info->port.close_delay; + tmp.closing_wait = info->port.closing_wait; tmp.custom_divisor = info->custom_divisor; if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; @@ -3415,7 +3415,7 @@ set_serial_info(struct e100_serial *info, if (!capable(CAP_SYS_ADMIN)) { if ((new_serial.type != info->type) || - (new_serial.close_delay != info->close_delay) || + (new_serial.close_delay != info->port.close_delay) || ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) return -EPERM; @@ -3437,8 +3437,8 @@ set_serial_info(struct e100_serial *info, (new_serial.flags & ASYNC_FLAGS)); info->custom_divisor = new_serial.custom_divisor; info->type = new_serial.type; - info->close_delay = new_serial.close_delay; - info->closing_wait = new_serial.closing_wait; + info->port.close_delay = new_serial.close_delay; + info->port.closing_wait = new_serial.closing_wait; info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: @@ -3794,8 +3794,8 @@ rs_close(struct tty_struct *tty, struct file * filp) * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); + if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->port.closing_wait); /* * At this point we stop accepting input. To do this, we * disable the serial receiver and the DMA receive interrupt. @@ -3825,8 +3825,8 @@ rs_close(struct tty_struct *tty, struct file * filp) info->event = 0; info->port.tty = NULL; if (info->blocked_open) { - if (info->close_delay) - schedule_timeout_interruptible(info->close_delay); + if (info->port.close_delay) + schedule_timeout_interruptible(info->port.close_delay); wake_up_interruptible(&info->open_wait); } info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); @@ -4440,8 +4440,6 @@ static int __init rs_init(void) info->forced_eop = 0; info->baud_base = DEF_BAUD_BASE; info->custom_divisor = 0; - info->close_delay = 5*HZ/10; - info->closing_wait = 30*HZ; info->x_char = 0; info->event = 0; info->count = 0; diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index 59f70c4cc860..a05c36b1a2af 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -87,8 +87,6 @@ struct e100_serial { volatile int tr_running; /* 1 if output is running */ int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; unsigned long event; int line; int type; /* PORT_ETRAX */ -- cgit From 4aeaeb0c39c6d0cca78d829c4fe2042e0d8d595d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:39 +0100 Subject: crisv10: use *_wait from tty_port The same as flags, convert to using *_wait queues from tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.c | 16 +++++++--------- drivers/tty/serial/crisv10.h | 2 -- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 0e75ec331c05..ef5bca118425 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3827,10 +3827,10 @@ rs_close(struct tty_struct *tty, struct file * filp) if (info->blocked_open) { if (info->port.close_delay) schedule_timeout_interruptible(info->port.close_delay); - wake_up_interruptible(&info->open_wait); + wake_up_interruptible(&info->port.open_wait); } info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); + wake_up_interruptible(&info->port.close_wait); local_irq_restore(flags); /* port closed */ @@ -3926,7 +3926,7 @@ rs_hangup(struct tty_struct *tty) info->count = 0; info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; - wake_up_interruptible(&info->open_wait); + wake_up_interruptible(&info->port.open_wait); } /* @@ -3949,7 +3949,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, */ if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(tty, info->close_wait, + wait_event_interruptible_tty(tty, info->port.close_wait, !(info->port.flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART if (info->port.flags & ASYNC_HUP_NOTIFY) @@ -3983,7 +3983,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, * exit, either normal or abnormal. */ retval = 0; - add_wait_queue(&info->open_wait, &wait); + add_wait_queue(&info->port.open_wait, &wait); #ifdef SERIAL_DEBUG_OPEN printk("block_til_ready before block: ttyS%d, count = %d\n", info->line, info->count); @@ -4030,7 +4030,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, tty_lock(tty); } set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); + remove_wait_queue(&info->port.open_wait, &wait); if (extra_count) info->count++; info->blocked_open--; @@ -4088,7 +4088,7 @@ rs_open(struct tty_struct *tty, struct file * filp) */ if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(tty, info->close_wait, + wait_event_interruptible_tty(tty, info->port.close_wait, !(info->port.flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART return ((info->port.flags & ASYNC_HUP_NOTIFY) ? @@ -4445,8 +4445,6 @@ static int __init rs_init(void) info->count = 0; info->blocked_open = 0; info->normal_termios = driver->init_termios; - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); info->xmit.buf = NULL; info->xmit.tail = info->xmit.head = 0; info->first_recv_buffer = info->last_recv_buffer = NULL; diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index a05c36b1a2af..1cd22998e6bf 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -101,8 +101,6 @@ struct e100_serial { struct work_struct work; struct async_icount icount; /* error-statistics etc.*/ struct ktermios normal_termios; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; unsigned long char_time_usec; /* The time for 1 char, in usecs */ unsigned long flush_time_usec; /* How often we should flush */ -- cgit From b12d8dc2dbe2d2d1d6eec314d586b1eed75756dc Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 7 Mar 2013 13:12:40 +0100 Subject: crisv10: use counts from tty_port The same as flags, convert to using open/close counts from tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/crisv10.c | 48 +++++++++++++++++++++----------------------- drivers/tty/serial/crisv10.h | 2 -- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index ef5bca118425..477f22f773fc 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3424,7 +3424,7 @@ set_serial_info(struct e100_serial *info, goto check_and_exit; } - if (info->count > 1) + if (info->port.count > 1) return -EBUSY; /* @@ -3760,7 +3760,7 @@ rs_close(struct tty_struct *tty, struct file * filp) printk("[%d] rs_close ttyS%d, count = %d\n", current->pid, info->line, info->count); #endif - if ((tty->count == 1) && (info->count != 1)) { + if ((tty->count == 1) && (info->port.count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always @@ -3770,15 +3770,15 @@ rs_close(struct tty_struct *tty, struct file * filp) */ printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; + "info->count is %d\n", info->port.count); + info->port.count = 1; } - if (--info->count < 0) { + if (--info->port.count < 0) { printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n", - info->line, info->count); - info->count = 0; + info->line, info->port.count); + info->port.count = 0; } - if (info->count) { + if (info->port.count) { local_irq_restore(flags); return; } @@ -3824,7 +3824,7 @@ rs_close(struct tty_struct *tty, struct file * filp) tty->closing = 0; info->event = 0; info->port.tty = NULL; - if (info->blocked_open) { + if (info->port.blocked_open) { if (info->port.close_delay) schedule_timeout_interruptible(info->port.close_delay); wake_up_interruptible(&info->port.open_wait); @@ -3923,7 +3923,7 @@ rs_hangup(struct tty_struct *tty) rs_flush_buffer(tty); shutdown(info); info->event = 0; - info->count = 0; + info->port.count = 0; info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; wake_up_interruptible(&info->port.open_wait); @@ -3978,7 +3978,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, /* * 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 + * this loop, info->port.count is dropped by one, so that * rs_close() knows when to free things. We restore it upon * exit, either normal or abnormal. */ @@ -3986,15 +3986,15 @@ block_til_ready(struct tty_struct *tty, struct file * filp, add_wait_queue(&info->port.open_wait, &wait); #ifdef SERIAL_DEBUG_OPEN printk("block_til_ready before block: ttyS%d, count = %d\n", - info->line, info->count); + info->line, info->port.count); #endif local_irq_save(flags); if (!tty_hung_up_p(filp)) { extra_count++; - info->count--; + info->port.count--; } local_irq_restore(flags); - info->blocked_open++; + info->port.blocked_open++; while (1) { local_irq_save(flags); /* assert RTS and DTR */ @@ -4023,7 +4023,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, } #ifdef SERIAL_DEBUG_OPEN printk("block_til_ready blocking: ttyS%d, count = %d\n", - info->line, info->count); + info->line, info->port.count); #endif tty_unlock(tty); schedule(); @@ -4032,11 +4032,11 @@ block_til_ready(struct tty_struct *tty, struct file * filp, set_current_state(TASK_RUNNING); remove_wait_queue(&info->port.open_wait, &wait); if (extra_count) - info->count++; - info->blocked_open--; + info->port.count++; + info->port.blocked_open--; #ifdef SERIAL_DEBUG_OPEN printk("block_til_ready after blocking: ttyS%d, count = %d\n", - info->line, info->count); + info->line, info->port.count); #endif if (retval) return retval; @@ -4074,10 +4074,10 @@ rs_open(struct tty_struct *tty, struct file * filp) #ifdef SERIAL_DEBUG_OPEN printk("[%d] rs_open %s, count = %d\n", current->pid, tty->name, - info->count); + info->port.count); #endif - info->count++; + info->port.count++; tty->driver_data = info; info->port.tty = tty; @@ -4101,7 +4101,7 @@ rs_open(struct tty_struct *tty, struct file * filp) /* * If DMA is enabled try to allocate the irq's. */ - if (info->count == 1) { + if (info->port.count == 1) { allocated_resources = 1; if (info->dma_in_enabled) { if (request_irq(info->dma_in_irq_nbr, @@ -4174,7 +4174,7 @@ rs_open(struct tty_struct *tty, struct file * filp) if (allocated_resources) deinit_port(info); - /* FIXME Decrease count info->count here too? */ + /* FIXME Decrease count info->port.count here too? */ return retval; } @@ -4191,7 +4191,7 @@ rs_open(struct tty_struct *tty, struct file * filp) return retval; } - if ((info->count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) { + if ((info->port.count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) { tty->termios = info->normal_termios; change_speed(info); } @@ -4442,8 +4442,6 @@ static int __init rs_init(void) info->custom_divisor = 0; info->x_char = 0; info->event = 0; - info->count = 0; - info->blocked_open = 0; info->normal_termios = driver->init_termios; info->xmit.buf = NULL; info->xmit.tail = info->xmit.head = 0; diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index 1cd22998e6bf..7599014ae03f 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -90,8 +90,6 @@ struct e100_serial { unsigned long event; int line; int type; /* PORT_ETRAX */ - int count; /* # of fd on device */ - int blocked_open; /* # of blocked opens */ struct circ_buf xmit; struct etrax_recv_buffer *first_recv_buffer; struct etrax_recv_buffer *last_recv_buffer; -- cgit From 8bde9658a0e6a7098dcda1ce6ea6b278029644b4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:48 +0100 Subject: TTY: clean up port shutdown Untangle port-shutdown logic and make sure the initialised flag is always cleared for non-console ports. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 7f38eeaafac3..2aea2f91e271 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -199,9 +199,14 @@ EXPORT_SYMBOL(tty_port_tty_set); static void tty_port_shutdown(struct tty_port *port) { mutex_lock(&port->mutex); - if (port->ops->shutdown && !port->console && - test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) + if (port->console) + goto out; + + if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (port->ops->shutdown) port->ops->shutdown(port); + } +out: mutex_unlock(&port->mutex); } -- cgit From 31ca020b57f7c08da187613cf20becd664c467fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:49 +0100 Subject: TTY: wake up processes last at hangup Move wake up of processes on blocked-open and modem-status wait queues to after port shutdown at hangup. This way the woken up processes can use the ASYNC_INITIALIZED flag to detect port shutdown. Note that this is the order currently used by serial-core. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 2aea2f91e271..73bc1d989d32 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -231,9 +231,9 @@ void tty_port_hangup(struct tty_port *port) } port->tty = NULL; spin_unlock_irqrestore(&port->lock, flags); + tty_port_shutdown(port); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); - tty_port_shutdown(port); } EXPORT_SYMBOL(tty_port_hangup); -- cgit From e584a02cf517537a3d13c7f85ced45fd07ab85cd Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:50 +0100 Subject: TTY: fix DTR being raised on hang up Make sure to check ASYNC_INITIALISED before raising DTR when waking up from blocked open in tty_port_block_til_ready. Currently DTR could get raised at hang up as a blocked process would raise DTR unconditionally before checking for hang up and returning. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 73bc1d989d32..7e3eaf4eb9fe 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -388,7 +388,7 @@ int tty_port_block_til_ready(struct tty_port *port, while (1) { /* Indicate we are open */ - if (tty->termios.c_cflag & CBAUD) + if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) tty_port_raise_dtr_rts(port); prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); -- cgit From 957dacaee56d18e5c2cbe722429de5a746a3cf44 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:51 +0100 Subject: TTY: fix DTR not being dropped on hang up Move HUPCL handling to port shutdown so that DTR is dropped also on hang up (tty_port_close is a noop for hung-up ports). Also do not try to drop DTR for uninitialised ports where it has never been raised (e.g. after a failed open). Note that this is also the current behaviour of serial-core. Nine drivers currently call tty_port_close_start directly (rather than through tty_port_close) and seven of them lower DTR as part of their close (if the port has been initialised). Fixup the remaining two drivers so that it continues to be lowered also on normal (non-HUP) close. [ Note that most of those other seven drivers did not expect DTR to have been dropped by tty_port_close_start in the first place. ] Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 4 ++++ drivers/tty/n_gsm.c | 4 ++++ drivers/tty/tty_port.c | 27 +++++++++++++++------------ 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 484b6a3c9b03..d996038eacfd 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1084,6 +1084,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) mutex_lock(&port->mutex); mxser_close_port(port); mxser_flush_buffer(tty); + if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (C_HUPCL(tty)) + tty_port_lower_dtr_rts(port); + } mxser_shutdown_port(port); clear_bit(ASYNCB_INITIALIZED, &port->flags); mutex_unlock(&port->mutex); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 74d9a0258d7c..642239015b46 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2964,6 +2964,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) if (tty_port_close_start(&dlci->port, tty, filp) == 0) goto out; gsm_dlci_begin_close(dlci); + if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { + if (C_HUPCL(tty)) + tty_port_lower_dtr_rts(&dlci->port); + } tty_port_close_end(&dlci->port, tty); tty_port_tty_set(&dlci->port, NULL); out: diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 7e3eaf4eb9fe..0af8d9aa5b02 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -196,13 +196,20 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) } EXPORT_SYMBOL(tty_port_tty_set); -static void tty_port_shutdown(struct tty_port *port) +static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) { mutex_lock(&port->mutex); if (port->console) goto out; if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { + /* + * Drop DTR/RTS if HUPCL is set. This causes any attached + * modem to hang up the line. + */ + if (tty && C_HUPCL(tty)) + tty_port_lower_dtr_rts(port); + if (port->ops->shutdown) port->ops->shutdown(port); } @@ -220,18 +227,19 @@ out: void tty_port_hangup(struct tty_port *port) { + struct tty_struct *tty; unsigned long flags; spin_lock_irqsave(&port->lock, flags); port->count = 0; port->flags &= ~ASYNC_NORMAL_ACTIVE; - if (port->tty) { - set_bit(TTY_IO_ERROR, &port->tty->flags); - tty_kref_put(port->tty); - } + tty = port->tty; + if (tty) + set_bit(TTY_IO_ERROR, &tty->flags); port->tty = NULL; spin_unlock_irqrestore(&port->lock, flags); - tty_port_shutdown(port); + tty_port_shutdown(port, tty); + tty_kref_put(tty); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); } @@ -485,11 +493,6 @@ int tty_port_close_start(struct tty_port *port, /* Flush the ldisc buffering */ tty_ldisc_flush(tty); - /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to - hang up the line */ - if (tty->termios.c_cflag & HUPCL) - tty_port_lower_dtr_rts(port); - /* Don't call port->drop for the last reference. Callers will want to drop the last active reference in ->shutdown() or the tty shutdown path */ @@ -524,7 +527,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty, { if (tty_port_close_start(port, tty, filp) == 0) return; - tty_port_shutdown(port); + tty_port_shutdown(port, tty); set_bit(TTY_IO_ERROR, &tty->flags); tty_port_close_end(port, tty); tty_port_tty_set(port, NULL); -- cgit From b74414f5f3227d9db309bfaaea3ae889af01430a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:52 +0100 Subject: TTY: clean up port drain-delay handling Move port drain-delay handling to a separate function. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 0af8d9aa5b02..20426ccbd58b 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -441,6 +441,20 @@ int tty_port_block_til_ready(struct tty_port *port, } EXPORT_SYMBOL(tty_port_block_til_ready); +static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty) +{ + unsigned int bps = tty_get_baud_rate(tty); + long timeout; + + if (bps > 1200) { + timeout = (HZ * 10 * port->drain_delay) / bps; + timeout = max_t(long, timeout, HZ / 10); + } else { + timeout = 2 * HZ; + } + schedule_timeout_interruptible(timeout); +} + int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) { @@ -479,17 +493,8 @@ int tty_port_close_start(struct tty_port *port, if (test_bit(ASYNCB_INITIALIZED, &port->flags) && port->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent_from_close(tty, port->closing_wait); - if (port->drain_delay) { - unsigned int bps = tty_get_baud_rate(tty); - long timeout; - - if (bps > 1200) - timeout = max_t(long, - (HZ * 10 * port->drain_delay) / bps, HZ / 10); - else - timeout = 2 * HZ; - schedule_timeout_interruptible(timeout); - } + if (port->drain_delay) + tty_port_drain_delay(port, tty); /* Flush the ldisc buffering */ tty_ldisc_flush(tty); -- cgit From 0b2588cadf9f131614cb251e34f7be1f4e1a2e08 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Mar 2013 15:55:53 +0100 Subject: TTY: fix close of uninitialised ports Make sure we do not make tty-driver callbacks or wait for port to drain on uninitialised ports (e.g. when open failed) in tty_port_close_start(). No callback, such as flush_buffer or wait_until_sent, needs to be made on a port that has never been opened. Neither does it make much sense to add drain delay for an uninitialised port. Currently a drain delay of up to two seconds could be added when a tty fails to open. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 20426ccbd58b..969c3e675a76 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -487,14 +487,16 @@ int tty_port_close_start(struct tty_port *port, set_bit(ASYNCB_CLOSING, &port->flags); tty->closing = 1; spin_unlock_irqrestore(&port->lock, flags); - /* Don't block on a stalled port, just pull the chain */ - if (tty->flow_stopped) - tty_driver_flush_buffer(tty); - if (test_bit(ASYNCB_INITIALIZED, &port->flags) && - port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent_from_close(tty, port->closing_wait); - if (port->drain_delay) - tty_port_drain_delay(port, tty); + + if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { + /* Don't block on a stalled port, just pull the chain */ + if (tty->flow_stopped) + tty_driver_flush_buffer(tty); + if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent_from_close(tty, port->closing_wait); + if (port->drain_delay) + tty_port_drain_delay(port, tty); + } /* Flush the ldisc buffering */ tty_ldisc_flush(tty); -- cgit From c47ddc26db389e046c1414c78ac4a6016c7df500 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Mar 2013 18:44:49 +0100 Subject: tty: max3100: Use dev_pm_ops Use dev_pm_ops instead of the deprecated legacy suspend/resume for the max3100 driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max3100.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 32517d4bceab..57da9bbaaab5 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -849,11 +849,11 @@ static int max3100_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP -static int max3100_suspend(struct spi_device *spi, pm_message_t state) +static int max3100_suspend(struct device *dev) { - struct max3100_port *s = dev_get_drvdata(&spi->dev); + struct max3100_port *s = dev_get_drvdata(dev); dev_dbg(&s->spi->dev, "%s\n", __func__); @@ -874,9 +874,9 @@ static int max3100_suspend(struct spi_device *spi, pm_message_t state) return 0; } -static int max3100_resume(struct spi_device *spi) +static int max3100_resume(struct device *dev) { - struct max3100_port *s = dev_get_drvdata(&spi->dev); + struct max3100_port *s = dev_get_drvdata(dev); dev_dbg(&s->spi->dev, "%s\n", __func__); @@ -894,21 +894,21 @@ static int max3100_resume(struct spi_device *spi) return 0; } +static SIMPLE_DEV_PM_OPS(max3100_pm_ops, max3100_suspend, max3100_resume); +#define MAX3100_PM_OPS (&max3100_pm_ops) + #else -#define max3100_suspend NULL -#define max3100_resume NULL +#define MAX3100_PM_OPS NULL #endif static struct spi_driver max3100_driver = { .driver = { .name = "max3100", .owner = THIS_MODULE, + .pm = MAX3100_PM_OPS, }, - .probe = max3100_probe, .remove = max3100_remove, - .suspend = max3100_suspend, - .resume = max3100_resume, }; module_spi_driver(max3100_driver); -- cgit From b7df719db7326d51a3145bb0cfc277aeb50763c3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Mar 2013 18:44:50 +0100 Subject: tty: max310x: Use dev_pm_ops Use dev_pm_ops instead of the deprecated legacy suspend/resume for the max310x driver. Cc: Alexander Shiyan Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 0c2422cb04ea..8941e6418942 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -881,12 +881,14 @@ static struct uart_ops max310x_ops = { .verify_port = max310x_verify_port, }; -static int max310x_suspend(struct spi_device *spi, pm_message_t state) +#ifdef CONFIG_PM_SLEEP + +static int max310x_suspend(struct device *dev) { int ret; - struct max310x_port *s = dev_get_drvdata(&spi->dev); + struct max310x_port *s = dev_get_drvdata(dev); - dev_dbg(&spi->dev, "Suspend\n"); + dev_dbg(dev, "Suspend\n"); ret = uart_suspend_port(&s->uart, &s->port); @@ -905,11 +907,11 @@ static int max310x_suspend(struct spi_device *spi, pm_message_t state) return ret; } -static int max310x_resume(struct spi_device *spi) +static int max310x_resume(struct device *dev) { - struct max310x_port *s = dev_get_drvdata(&spi->dev); + struct max310x_port *s = dev_get_drvdata(dev); - dev_dbg(&spi->dev, "Resume\n"); + dev_dbg(dev, "Resume\n"); if (s->pdata->suspend) s->pdata->suspend(0); @@ -928,6 +930,13 @@ static int max310x_resume(struct spi_device *spi) return uart_resume_port(&s->uart, &s->port); } +static SIMPLE_DEV_PM_OPS(max310x_pm_ops, max310x_suspend, max310x_resume); +#define MAX310X_PM_OPS (&max310x_pm_ops) + +#else +#define MAX310X_PM_OPS NULL +#endif + #ifdef CONFIG_GPIOLIB static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset) { @@ -1242,11 +1251,10 @@ static struct spi_driver max310x_driver = { .driver = { .name = "max310x", .owner = THIS_MODULE, + .pm = MAX310X_PM_OPS, }, .probe = max310x_probe, .remove = max310x_remove, - .suspend = max310x_suspend, - .resume = max310x_resume, .id_table = max310x_id_table, }; module_spi_driver(max310x_driver); -- cgit From c2ee91bd6644324160ba9e090e3a017d62abc0b4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Mar 2013 18:44:51 +0100 Subject: tty: mrst_max3110: Use dev_pm_ops Use dev_pm_ops instead of the deprecated legacy suspend/resume for the mrst_max3110 driver. Cc: Alan Cox Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mrst_max3110.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index f641c232beca..9b6ef20420c0 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -743,9 +743,10 @@ static struct uart_driver serial_m3110_reg = { .cons = &serial_m3110_console, }; -#ifdef CONFIG_PM -static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int serial_m3110_suspend(struct device *dev) { + struct spi_device *spi = to_spi_device(dev); struct uart_max3110 *max = spi_get_drvdata(spi); disable_irq(max->irq); @@ -754,8 +755,9 @@ static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) return 0; } -static int serial_m3110_resume(struct spi_device *spi) +static int serial_m3110_resume(struct device *dev) { + struct spi_device *spi = to_spi_device(dev); struct uart_max3110 *max = spi_get_drvdata(spi); max3110_out(max, max->cur_conf); @@ -763,9 +765,13 @@ static int serial_m3110_resume(struct spi_device *spi) enable_irq(max->irq); return 0; } + +static SIMPLE_DEV_PM_OPS(serial_m3110_pm_ops, serial_m3110_suspend, + serial_m3110_resume); +#define SERIAL_M3110_PM_OPS (&serial_m3110_pm_ops) + #else -#define serial_m3110_suspend NULL -#define serial_m3110_resume NULL +#define SERIAL_M3110_PM_OPS NULL #endif static int serial_m3110_probe(struct spi_device *spi) @@ -872,11 +878,10 @@ static struct spi_driver uart_max3110_driver = { .driver = { .name = "spi_max3111", .owner = THIS_MODULE, + .pm = SERIAL_M3110_PM_OPS, }, .probe = serial_m3110_probe, .remove = serial_m3110_remove, - .suspend = serial_m3110_suspend, - .resume = serial_m3110_resume, }; static int __init serial_m3110_init(void) -- cgit From 91debb0383d6564e0dc8ae76181f6daf8e24717a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Mar 2013 18:44:52 +0100 Subject: tty: ifx6x60: Remove unused suspend/resume callbacks The ifx6x60 driver implements both legacy suspend/resume callbacks and dev_pm_ops. The SPI core is going to ignore legacy suspend/resume callbacks if a driver implements dev_pm_ops. Since the legacy suspend/resume callbacks are empty in this case it is safe to just remove them. Cc: Bi Chao Cc: Chen Jun Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 2c77fed31a72..8b1534c424af 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -1278,30 +1278,6 @@ static void ifx_spi_spi_shutdown(struct spi_device *spi) * no hardware to save state for */ -/** - * ifx_spi_spi_suspend - suspend SPI on system suspend - * @dev: device being suspended - * - * Suspend the SPI side. No action needed on Intel MID platforms, may - * need extending for other systems. - */ -static int ifx_spi_spi_suspend(struct spi_device *spi, pm_message_t msg) -{ - return 0; -} - -/** - * ifx_spi_spi_resume - resume SPI side on system resume - * @dev: device being suspended - * - * Suspend the SPI side. No action needed on Intel MID platforms, may - * need extending for other systems. - */ -static int ifx_spi_spi_resume(struct spi_device *spi) -{ - return 0; -} - /** * ifx_spi_pm_suspend - suspend modem on system suspend * @dev: device being suspended @@ -1391,8 +1367,6 @@ static struct spi_driver ifx_spi_driver = { .probe = ifx_spi_spi_probe, .shutdown = ifx_spi_spi_shutdown, .remove = ifx_spi_spi_remove, - .suspend = ifx_spi_spi_suspend, - .resume = ifx_spi_spi_resume, .id_table = ifx_id_table }; -- cgit From be431b16c6bd22020abc5f5f30a89f1e2934de8e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Mar 2013 15:25:36 -0300 Subject: [media] dvb-frontend: split set_delivery_system() This function is complex, and has different workflows, one for DVBv3 calls, and another one for DVBv5 calls. Break it into 3 functions, in order to make easier to understand what each block does. No functional changes so far. A few comments got improved. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 294 +++++++++++++++++++--------------- 1 file changed, 165 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 6e50a7581568..d0d193d1404a 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1509,132 +1509,12 @@ static bool is_dvbv3_delsys(u32 delsys) return status; } -static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) +static int emulate_delivery_system(struct dvb_frontend *fe, + enum dvbv3_emulation_type type, + u32 delsys, u32 desired_system) { - int ncaps, i; - u32 delsys = SYS_UNDEFINED; + int i; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - enum dvbv3_emulation_type type; - - /* - * It was reported that some old DVBv5 applications were - * filling delivery_system with SYS_UNDEFINED. If this happens, - * assume that the application wants to use the first supported - * delivery system. - */ - if (c->delivery_system == SYS_UNDEFINED) - c->delivery_system = fe->ops.delsys[0]; - - if (desired_system == SYS_UNDEFINED) { - /* - * A DVBv3 call doesn't know what's the desired system. - * Also, DVBv3 applications don't know that ops.info->type - * could be changed, and they simply dies when it doesn't - * match. - * So, don't change the current delivery system, as it - * may be trying to do the wrong thing, like setting an - * ISDB-T frontend as DVB-T. Instead, find the closest - * DVBv3 system that matches the delivery system. - */ - if (is_dvbv3_delsys(c->delivery_system)) { - dev_dbg(fe->dvb->device, - "%s: Using delivery system to %d\n", - __func__, c->delivery_system); - return 0; - } - type = dvbv3_type(c->delivery_system); - switch (type) { - case DVBV3_QPSK: - desired_system = SYS_DVBS; - break; - case DVBV3_QAM: - desired_system = SYS_DVBC_ANNEX_A; - break; - case DVBV3_ATSC: - desired_system = SYS_ATSC; - break; - case DVBV3_OFDM: - desired_system = SYS_DVBT; - break; - default: - dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n", - __func__); - return -EINVAL; - } - /* - * Get a delivery system that is compatible with DVBv3 - * NOTE: in order for this to work with softwares like Kaffeine that - * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to - * DVB-S, drivers that support both should put the SYS_DVBS entry - * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. - * The real fix is that userspace applications should not use DVBv3 - * and not trust on calling FE_SET_FRONTEND to switch the delivery - * system. - */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - delsys = desired_system; - break; - } - ncaps++; - } - if (delsys == SYS_UNDEFINED) { - dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n", - __func__, desired_system); - } - } else { - /* - * This is a DVBv5 call. So, it likely knows the supported - * delivery systems. - */ - - /* Check if the desired delivery system is supported */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - c->delivery_system = desired_system; - dev_dbg(fe->dvb->device, - "%s: Changing delivery system to %d\n", - __func__, desired_system); - return 0; - } - ncaps++; - } - type = dvbv3_type(desired_system); - - /* - * The delivery system is not supported. See if it can be - * emulated. - * The emulation only works if the desired system is one of the - * DVBv3 delivery systems - */ - if (!is_dvbv3_delsys(desired_system)) { - dev_dbg(fe->dvb->device, - "%s: can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n", - __func__); - return -EINVAL; - } - - /* - * Get the last non-DVBv3 delivery system that has the same type - * of the desired system - */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) && - !is_dvbv3_delsys(fe->ops.delsys[ncaps])) - delsys = fe->ops.delsys[ncaps]; - ncaps++; - } - /* There's nothing compatible with the desired delivery system */ - if (delsys == SYS_UNDEFINED) { - dev_dbg(fe->dvb->device, - "%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n", - __func__); - return -EINVAL; - } - } c->delivery_system = delsys; @@ -1648,8 +1528,8 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) * delivery system is the last one at the ops.delsys[] array */ dev_dbg(fe->dvb->device, - "%s: Using delivery system %d emulated as if it were a %d\n", - __func__, delsys, desired_system); + "%s: Using delivery system %d emulated as if it were a %d\n", + __func__, delsys, desired_system); /* * For now, handles ISDB-T calls. More code may be needed here for the @@ -1684,6 +1564,162 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) return 0; } +static int dvbv5_set_delivery_system(struct dvb_frontend *fe, + u32 desired_system) +{ + int ncaps; + u32 delsys = SYS_UNDEFINED; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + enum dvbv3_emulation_type type; + + /* + * It was reported that some old DVBv5 applications were + * filling delivery_system with SYS_UNDEFINED. If this happens, + * assume that the application wants to use the first supported + * delivery system. + */ + if (c->delivery_system == SYS_UNDEFINED) + c->delivery_system = fe->ops.delsys[0]; + + /* + * This is a DVBv5 call. So, it likely knows the supported + * delivery systems. + */ + + /* Check if the desired delivery system is supported */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if (fe->ops.delsys[ncaps] == desired_system) { + c->delivery_system = desired_system; + dev_dbg(fe->dvb->device, + "%s: Changing delivery system to %d\n", + __func__, desired_system); + return 0; + } + ncaps++; + } + + /* + * Need to emulate a delivery system + */ + + type = dvbv3_type(desired_system); + + /* + * The delivery system is not supported. See if it can be + * emulated. + * The emulation only works if the desired system is one of the + * DVBv3 delivery systems + */ + if (!is_dvbv3_delsys(desired_system)) { + dev_dbg(fe->dvb->device, + "%s: can't use a DVBv3 FE_SET_FRONTEND call for this frontend\n", + __func__); + return -EINVAL; + } + + /* + * Get the last non-DVBv3 delivery system that has the same type + * of the desired system + */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) && + !is_dvbv3_delsys(fe->ops.delsys[ncaps])) + delsys = fe->ops.delsys[ncaps]; + ncaps++; + } + /* There's nothing compatible with the desired delivery system */ + if (delsys == SYS_UNDEFINED) { + dev_dbg(fe->dvb->device, + "%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n", + __func__); + return -EINVAL; + } + + return emulate_delivery_system(fe, type, delsys, desired_system); +} + +static int dvbv3_set_delivery_system(struct dvb_frontend *fe) +{ + int ncaps; + u32 desired_system; + u32 delsys = SYS_UNDEFINED; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + enum dvbv3_emulation_type type; + + /* If not set yet, defaults to the first supported delivery system */ + if (c->delivery_system == SYS_UNDEFINED) + c->delivery_system = fe->ops.delsys[0]; + + /* + * A DVBv3 call doesn't know what's the desired system. + * Also, DVBv3 applications don't know that ops.info->type + * could be changed, and they simply don't tune when it doesn't + * match. + * So, don't change the current delivery system, as it + * may be trying to do the wrong thing, like setting an + * ISDB-T frontend as DVB-T. Instead, find the closest + * DVBv3 system that matches the delivery system. + */ + + /* + * Trivial case: just use the current one, if it already a DVBv3 + * delivery system + */ + if (is_dvbv3_delsys(c->delivery_system)) { + dev_dbg(fe->dvb->device, + "%s: Using delivery system to %d\n", + __func__, c->delivery_system); + return 0; + } + + /* Convert from DVBv3 into DVBv5 namespace */ + type = dvbv3_type(c->delivery_system); + switch (type) { + case DVBV3_QPSK: + desired_system = SYS_DVBS; + break; + case DVBV3_QAM: + desired_system = SYS_DVBC_ANNEX_A; + break; + case DVBV3_ATSC: + desired_system = SYS_ATSC; + break; + case DVBV3_OFDM: + desired_system = SYS_DVBT; + break; + default: + dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n", + __func__); + return -EINVAL; + } + + /* + * Get a delivery system that is compatible with DVBv3 + * NOTE: in order for this to work with softwares like Kaffeine that + * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to + * DVB-S, drivers that support both should put the SYS_DVBS entry + * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. + * The real fix is that userspace applications should not use DVBv3 + * and not trust on calling FE_SET_FRONTEND to switch the delivery + * system. + */ + ncaps = 0; + while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { + if (fe->ops.delsys[ncaps] == desired_system) { + delsys = desired_system; + break; + } + ncaps++; + } + if (delsys == SYS_UNDEFINED) { + dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n", + __func__, desired_system); + } + return emulate_delivery_system(fe, type, delsys, desired_system); +} + static int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, struct file *file) @@ -1742,7 +1778,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, c->rolloff = tvp->u.data; break; case DTV_DELIVERY_SYSTEM: - r = set_delivery_system(fe, tvp->u.data); + r = dvbv5_set_delivery_system(fe, tvp->u.data); break; case DTV_VOLTAGE: c->voltage = tvp->u.data; @@ -2335,7 +2371,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, break; case FE_SET_FRONTEND: - err = set_delivery_system(fe, SYS_UNDEFINED); + err = dvbv3_set_delivery_system(fe); if (err) break; @@ -2594,7 +2630,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, * first supported delivery system (ops->delsys[0]) */ - fe->dtv_property_cache.delivery_system = fe->ops.delsys[0]; + fe->dtv_property_cache.delivery_system = fe->ops.delsys[0]; dvb_frontend_clear_cache(fe); mutex_unlock(&frontend_mutex); -- cgit From 21622939fc452c7fb739464b8e49368c3ceaa0ee Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:21 -0400 Subject: tty: Add diagnostic for halted line discipline Flip buffer work must not be scheduled by the line discipline after the line discipline has been halted; issue warning. Note: drivers can still schedule flip buffer work. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 8 ++++++++ drivers/tty/tty_ldisc.c | 7 ++++++- include/linux/tty.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 68865d9af8a0..16793eccc6ae 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -153,6 +153,12 @@ static void n_tty_set_room(struct tty_struct *tty) if (left && !old_left) { WARN_RATELIMIT(tty->port->itty == NULL, "scheduling with invalid itty\n"); + /* see if ldisc has been killed - if so, this means that + * even though the ldisc has been halted and ->buf.work + * cancelled, ->buf.work is about to be rescheduled + */ + WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), + "scheduling buffer work for halted ldisc\n"); schedule_work(&tty->port->buf.work); } } @@ -1624,6 +1630,8 @@ static int n_tty_open(struct tty_struct *tty) goto err_free_bufs; tty->disc_data = ldata; + /* indicate buffer work may resume */ + clear_bit(TTY_LDISC_HALTED, &tty->flags); reset_buffer_flags(tty); tty_unthrottle(tty); ldata->column = 0; diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d794087c327e..c641321b9404 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -375,6 +375,7 @@ static inline void tty_ldisc_put(struct tty_ldisc *ld) void tty_ldisc_enable(struct tty_struct *tty) { + clear_bit(TTY_LDISC_HALTED, &tty->flags); set_bit(TTY_LDISC, &tty->flags); clear_bit(TTY_LDISC_CHANGING, &tty->flags); wake_up(&tty_ldisc_wait); @@ -513,8 +514,11 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) static int tty_ldisc_halt(struct tty_struct *tty) { + int scheduled; clear_bit(TTY_LDISC, &tty->flags); - return cancel_work_sync(&tty->port->buf.work); + scheduled = cancel_work_sync(&tty->port->buf.work); + set_bit(TTY_LDISC_HALTED, &tty->flags); + return scheduled; } /** @@ -820,6 +824,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) clear_bit(TTY_LDISC, &tty->flags); tty_unlock(tty); cancel_work_sync(&tty->port->buf.work); + set_bit(TTY_LDISC_HALTED, &tty->flags); mutex_unlock(&tty->ldisc_mutex); retry: tty_lock(tty); diff --git a/include/linux/tty.h b/include/linux/tty.h index d3548f871968..66ae020e8a98 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -315,6 +315,7 @@ struct tty_file_private { #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_HUPPING 21 /* ->hangup() in progress */ +#define TTY_LDISC_HALTED 22 /* Line discipline is halted */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) -- cgit From a30737ab7d99f27810b254787e5e62a6c92cb355 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:22 -0400 Subject: n_tty: Factor packet mode status change for reuse Factor the packet mode status change from n_tty_flush_buffer for use by follow-on patch. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 16793eccc6ae..7e7f6514fb53 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -223,6 +223,18 @@ static void reset_buffer_flags(struct tty_struct *tty) n_tty_set_room(tty); } +static void n_tty_packet_mode_flush(struct tty_struct *tty) +{ + unsigned long flags; + + spin_lock_irqsave(&tty->ctrl_lock, flags); + if (tty->link->packet) { + tty->ctrl_status |= TIOCPKT_FLUSHREAD; + wake_up_interruptible(&tty->link->read_wait); + } + spin_unlock_irqrestore(&tty->ctrl_lock, flags); +} + /** * n_tty_flush_buffer - clean input queue * @tty: terminal device @@ -237,19 +249,11 @@ static void reset_buffer_flags(struct tty_struct *tty) static void n_tty_flush_buffer(struct tty_struct *tty) { - unsigned long flags; /* clear everything and unthrottle the driver */ reset_buffer_flags(tty); - if (!tty->link) - return; - - spin_lock_irqsave(&tty->ctrl_lock, flags); - if (tty->link->packet) { - tty->ctrl_status |= TIOCPKT_FLUSHREAD; - wake_up_interruptible(&tty->link->read_wait); - } - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (tty->link) + n_tty_packet_mode_flush(tty); } /** -- cgit From 79901317ce80c43a0249ccc6e3fea9d0968e159e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:23 -0400 Subject: n_tty: Don't flush buffer when closing ldisc A buffer flush is both undesirable and unnecessary when the ldisc is closing. A buffer flush performs the following: 1. resets ldisc data fields to their initial state 2. resets tty->receive_room to indicate more data can be sent 3. schedules buffer work to receive more data 4. signals a buffer flush has happened to linked pty in packet mode Since the ldisc has been halted and the tty may soon be destructed, buffer work must not be scheduled as that work might access an invalid tty and ldisc state. Also, the ldisc read buffer is about to be freed, so that's pointless. Resetting the ldisc data fields is pointless as well since that structure is about to be freed. Resetting tty->receive_room is unnecessary, as it will be properly reset if a new ldisc is reopened. Besides, resetting the original receive_room value would be wrong since the read buffer will be gone. Since the packet mode flush is observable from userspace, this behavior has been preserved. The test jig originally authored by Ilya Zykov and signed off by him is included below. The test jig prompts the following warnings which this patch fixes. [ 38.051111] ------------[ cut here ]------------ [ 38.052113] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room.part.6+0x8b/0xa0() [ 38.053916] Hardware name: Bochs [ 38.054819] Modules linked in: netconsole configfs bnep rfcomm bluetooth parport_pc ppdev snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq psmouse snd_timer serio_raw mac_hid snd_seq_device snd microcode lp parport virtio_balloon soundcore i2c_piix4 snd_page_alloc floppy 8139too 8139cp [ 38.059704] Pid: 1564, comm: pty_kill Tainted: G W 3.7.0-next-20121130+ttydebug-xeon #20121130+ttydebug [ 38.061578] Call Trace: [ 38.062491] [] warn_slowpath_common+0x7f/0xc0 [ 38.063448] [] warn_slowpath_null+0x1a/0x20 [ 38.064439] [] n_tty_set_room.part.6+0x8b/0xa0 [ 38.065381] [] n_tty_set_room+0x42/0x80 [ 38.066323] [] reset_buffer_flags+0x102/0x160 [ 38.077508] [] n_tty_flush_buffer+0x1d/0x90 [ 38.078782] [] ? default_spin_lock_flags+0x9/0x10 [ 38.079734] [] n_tty_close+0x24/0x60 [ 38.080730] [] tty_ldisc_close.isra.2+0x41/0x60 [ 38.081680] [] tty_ldisc_kill+0x3b/0x80 [ 38.082618] [] tty_ldisc_release+0x77/0xe0 [ 38.083549] [] tty_release+0x451/0x4d0 [ 38.084525] [] __fput+0xae/0x230 [ 38.085472] [] ____fput+0xe/0x10 [ 38.086401] [] task_work_run+0xc8/0xf0 [ 38.087334] [] do_exit+0x196/0x4b0 [ 38.088304] [] ? __dequeue_signal+0x6b/0xb0 [ 38.089240] [] do_group_exit+0x44/0xa0 [ 38.090182] [] get_signal_to_deliver+0x20d/0x4e0 [ 38.091125] [] do_signal+0x29/0x130 [ 38.092096] [] ? tty_ldisc_deref+0xe/0x10 [ 38.093030] [] ? tty_write+0xb7/0xf0 [ 38.093976] [] ? vfs_write+0xb3/0x180 [ 38.094904] [] do_notify_resume+0x80/0xc0 [ 38.095830] [] int_signal+0x12/0x17 [ 38.096788] ---[ end trace 5f6f7a9651cd999b ]--- [ 2730.570602] ------------[ cut here ]------------ [ 2730.572130] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0x107/0x140() [ 2730.574904] scheduling buffer work for halted ldisc [ 2730.578303] Pid: 9691, comm: trinity-child15 Tainted: G W 3.7.0-rc8-next-20121205-sasha-00023-g59f0d85 #207 [ 2730.588694] Call Trace: [ 2730.590486] [] ? n_tty_set_room+0x107/0x140 [ 2730.592559] [] warn_slowpath_common+0x87/0xb0 [ 2730.595317] [] warn_slowpath_fmt+0x41/0x50 [ 2730.599186] [] n_tty_set_room+0x107/0x140 [ 2730.603141] [] reset_buffer_flags+0x137/0x150 [ 2730.607166] [] n_tty_flush_buffer+0x18/0x90 [ 2730.610123] [] n_tty_close+0x1f/0x60 [ 2730.612068] [] tty_ldisc_close.isra.4+0x52/0x60 [ 2730.614078] [] tty_ldisc_reinit+0x3b/0x70 [ 2730.615891] [] tty_ldisc_hangup+0x102/0x1e0 [ 2730.617780] [] __tty_hangup+0x137/0x440 [ 2730.619547] [] tty_vhangup+0x9/0x10 [ 2730.621266] [] pty_close+0x14c/0x160 [ 2730.622952] [] tty_release+0xd5/0x490 [ 2730.624674] [] __fput+0x122/0x250 [ 2730.626195] [] ____fput+0x9/0x10 [ 2730.627758] [] task_work_run+0xb2/0xf0 [ 2730.629491] [] do_exit+0x36d/0x580 [ 2730.631159] [] do_group_exit+0x8a/0xc0 [ 2730.632819] [] get_signal_to_deliver+0x501/0x5b0 [ 2730.634758] [] do_signal+0x24/0x100 [ 2730.636412] [] ? user_exit+0xa5/0xd0 [ 2730.638078] [] ? trace_hardirqs_on_caller+0x118/0x140 [ 2730.640279] [] ? trace_hardirqs_on+0xd/0x10 [ 2730.642164] [] do_notify_resume+0x48/0xa0 [ 2730.643966] [] int_signal+0x12/0x17 [ 2730.645672] ---[ end trace a40d53149c07fce0 ]--- /* * pty_thrash.c * * Based on original test jig by Ilya Zykov * * Signed-off-by: Peter Hurley * Signed-off-by: Ilya Zykov */ static int fd; static void error_exit(char *f, ...) { va_list va; va_start(va, f); vprintf(f, va); printf(": %s\n", strerror(errno)); va_end(va); if (fd >= 0) close(fd); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int parent; char pts_name[24]; int ptn, unlock; while (1) { fd = open("/dev/ptmx", O_RDWR); if (fd < 0) error_exit("opening pty master"); unlock = 0; if (ioctl(fd, TIOCSPTLCK, &unlock) < 0) error_exit("unlocking pty pair"); if (ioctl(fd, TIOCGPTN, &ptn) < 0) error_exit("getting pty #"); snprintf(pts_name, sizeof(pts_name), "/dev/pts/%d", ptn); child_id = fork(); if (child_id == -1) error_exit("forking child"); if (parent) { int err, id, status; char buf[128]; int n; n = read(fd, buf, sizeof(buf)); if (n < 0) error_exit("master reading"); printf("%.*s\n", n-1, buf); close(fd); err = kill(child_id, SIGKILL); if (err < 0) error_exit("killing child"); id = waitpid(child_id, &status, 0); if (id < 0 || id != child_id) error_exit("waiting for child"); } else { /* Child */ close(fd); printf("Test cycle on slave pty %s\n", pts_name); fd = open(pts_name, O_RDWR); if (fd < 0) error_exit("opening pty slave"); while (1) { char pattern[] = "test\n"; if (write(fd, pattern, strlen(pattern)) < 0) error_exit("slave writing"); } } } /* never gets here */ return 0; } Reported-by: Sasha Levin Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 7e7f6514fb53..15f7195f4b4c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1596,7 +1596,9 @@ static void n_tty_close(struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; - n_tty_flush_buffer(tty); + if (tty->link) + n_tty_packet_mode_flush(tty); + kfree(ldata->read_buf); kfree(ldata->echo_buf); kfree(ldata); -- cgit From 168942c9fa01916173a7b72ac67e1d218d571013 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:24 -0400 Subject: tty: Refactor wait for ldisc refs out of tty_ldisc_hangup() Refactor tty_ldisc_hangup() to extract standalone function, tty_ldisc_hangup_wait_idle(), to wait for ldisc references to be released. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 54 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index c641321b9404..c5b848a78e49 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -550,6 +550,41 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) return ret > 0 ? 0 : -EBUSY; } +/** + * tty_ldisc_hangup_wait_idle - wait for the ldisc to become idle + * @tty: tty to wait for + * + * Wait for the line discipline to become idle. The discipline must + * have been halted for this to guarantee it remains idle. + * + * Caller must hold legacy and ->ldisc_mutex. + */ +static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty) +{ + while (tty->ldisc) { /* Not yet closed */ + if (atomic_read(&tty->ldisc->users) != 1) { + char cur_n[TASK_COMM_LEN], tty_n[64]; + long timeout = 3 * HZ; + tty_unlock(tty); + + while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { + timeout = MAX_SCHEDULE_TIMEOUT; + printk_ratelimited(KERN_WARNING + "%s: waiting (%s) for %s took too long, but we keep waiting...\n", + __func__, get_task_comm(cur_n, current), + tty_name(tty, tty_n)); + } + /* must reacquire both locks and preserve lock order */ + mutex_unlock(&tty->ldisc_mutex); + tty_lock(tty); + mutex_lock(&tty->ldisc_mutex); + continue; + } + break; + } + return !!tty->ldisc; +} + /** * tty_set_ldisc - set line discipline * @tty: the terminal to set @@ -826,7 +861,6 @@ void tty_ldisc_hangup(struct tty_struct *tty) cancel_work_sync(&tty->port->buf.work); set_bit(TTY_LDISC_HALTED, &tty->flags); mutex_unlock(&tty->ldisc_mutex); -retry: tty_lock(tty); mutex_lock(&tty->ldisc_mutex); @@ -834,23 +868,7 @@ retry: reopen it. We could defer this to the next open but it means auditing a lot of other paths so this is a FIXME */ - if (tty->ldisc) { /* Not yet closed */ - if (atomic_read(&tty->ldisc->users) != 1) { - char cur_n[TASK_COMM_LEN], tty_n[64]; - long timeout = 3 * HZ; - tty_unlock(tty); - - while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { - timeout = MAX_SCHEDULE_TIMEOUT; - printk_ratelimited(KERN_WARNING - "%s: waiting (%s) for %s took too long, but we keep waiting...\n", - __func__, get_task_comm(cur_n, current), - tty_name(tty, tty_n)); - } - mutex_unlock(&tty->ldisc_mutex); - goto retry; - } - + if (tty_ldisc_hangup_wait_idle(tty)) { if (reset == 0) { if (!tty_ldisc_reinit(tty, tty->termios.c_line)) -- cgit From 2276ad9765b395577442d6ddf748f72c329234ae Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:25 -0400 Subject: tty: Remove unnecessary re-test of ldisc ref count Since the tty->ldisc is prevented from being changed by tty_set_ldisc() when a tty is being hung up, re-testing the ldisc user count is unnecessary -- ie, it cannot be a different ldisc and the user count cannot have increased (assuming the caller meets the precondition that TTY_LDISC flag is cleared) Removal of the 'early-out' locking optimization is necessary for the subsequent patch 'tty: Fix ldisc halt sequence on hangup'. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index c5b848a78e49..fa0170e1b082 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -558,29 +558,29 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) * have been halted for this to guarantee it remains idle. * * Caller must hold legacy and ->ldisc_mutex. + * + * NB: tty_set_ldisc() is prevented from changing the ldisc concurrently + * with this function by checking the TTY_HUPPING flag. */ static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty) { - while (tty->ldisc) { /* Not yet closed */ - if (atomic_read(&tty->ldisc->users) != 1) { - char cur_n[TASK_COMM_LEN], tty_n[64]; - long timeout = 3 * HZ; - tty_unlock(tty); - - while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { - timeout = MAX_SCHEDULE_TIMEOUT; - printk_ratelimited(KERN_WARNING - "%s: waiting (%s) for %s took too long, but we keep waiting...\n", - __func__, get_task_comm(cur_n, current), - tty_name(tty, tty_n)); - } - /* must reacquire both locks and preserve lock order */ - mutex_unlock(&tty->ldisc_mutex); - tty_lock(tty); - mutex_lock(&tty->ldisc_mutex); - continue; + char cur_n[TASK_COMM_LEN], tty_n[64]; + long timeout = 3 * HZ; + + if (tty->ldisc) { /* Not yet closed */ + tty_unlock(tty); + + while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { + timeout = MAX_SCHEDULE_TIMEOUT; + printk_ratelimited(KERN_WARNING + "%s: waiting (%s) for %s took too long, but we keep waiting...\n", + __func__, get_task_comm(cur_n, current), + tty_name(tty, tty_n)); } - break; + /* must reacquire both locks and preserve lock order */ + mutex_unlock(&tty->ldisc_mutex); + tty_lock(tty); + mutex_lock(&tty->ldisc_mutex); } return !!tty->ldisc; } -- cgit From 76bc35e78fdf1065ffa2bb62fabe3e8423d378c8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:26 -0400 Subject: tty: Fix ldisc halt sequence on hangup Flip buffer work cannot be cancelled until all outstanding ldisc references have been released. Convert the ldisc ref wait into a full ldisc halt with buffer work cancellation. Note that the legacy mutex is not held while cancelling. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index fa0170e1b082..15667c0fd645 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -551,22 +551,30 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) } /** - * tty_ldisc_hangup_wait_idle - wait for the ldisc to become idle - * @tty: tty to wait for - * - * Wait for the line discipline to become idle. The discipline must - * have been halted for this to guarantee it remains idle. + * tty_ldisc_hangup_halt - halt the line discipline for hangup + * @tty: tty being hung up * + * Shut down the line discipline and work queue for the tty device + * being hungup. Clear the TTY_LDISC flag to ensure no further + * references can be obtained, wait for remaining references to be + * released, and cancel pending buffer work to ensure no more + * data is fed to this ldisc. * Caller must hold legacy and ->ldisc_mutex. * * NB: tty_set_ldisc() is prevented from changing the ldisc concurrently * with this function by checking the TTY_HUPPING flag. + * + * NB: if tty->ldisc is NULL then buffer work does not need to be + * cancelled because it must already have done as a precondition + * of closing the ldisc and setting tty->ldisc to NULL */ -static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty) +static bool tty_ldisc_hangup_halt(struct tty_struct *tty) { char cur_n[TASK_COMM_LEN], tty_n[64]; long timeout = 3 * HZ; + clear_bit(TTY_LDISC, &tty->flags); + if (tty->ldisc) { /* Not yet closed */ tty_unlock(tty); @@ -577,6 +585,10 @@ static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty) __func__, get_task_comm(cur_n, current), tty_name(tty, tty_n)); } + + cancel_work_sync(&tty->port->buf.work); + set_bit(TTY_LDISC_HALTED, &tty->flags); + /* must reacquire both locks and preserve lock order */ mutex_unlock(&tty->ldisc_mutex); tty_lock(tty); @@ -851,24 +863,11 @@ void tty_ldisc_hangup(struct tty_struct *tty) */ mutex_lock(&tty->ldisc_mutex); - /* - * this is like tty_ldisc_halt, but we need to give up - * the BTM before calling cancel_work_sync, which may - * need to wait for another function taking the BTM - */ - clear_bit(TTY_LDISC, &tty->flags); - tty_unlock(tty); - cancel_work_sync(&tty->port->buf.work); - set_bit(TTY_LDISC_HALTED, &tty->flags); - mutex_unlock(&tty->ldisc_mutex); - tty_lock(tty); - mutex_lock(&tty->ldisc_mutex); - /* At this point we have a closed ldisc and we want to reopen it. We could defer this to the next open but it means auditing a lot of other paths so this is a FIXME */ - if (tty_ldisc_hangup_wait_idle(tty)) { + if (tty_ldisc_hangup_halt(tty)) { if (reset == 0) { if (!tty_ldisc_reinit(tty, tty->termios.c_line)) -- cgit From 52dee392f491e166cef21c787d1736f052a902cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Mar 2013 15:25:37 -0300 Subject: [media] dvb_frontend: Simplify the emulation logic The current logic was broken and too complex; while it works fine for DVB-S2/DVB-S, it is broken for ISDB-T. Make the logic simpler, fixes it for ISDB-T and make it clearer. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 219 +++++++++++++++++----------------- 1 file changed, 109 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index d0d193d1404a..eaa0a74e6a87 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1509,9 +1509,17 @@ static bool is_dvbv3_delsys(u32 delsys) return status; } -static int emulate_delivery_system(struct dvb_frontend *fe, - enum dvbv3_emulation_type type, - u32 delsys, u32 desired_system) +/** + * emulate_delivery_system - emulate a DVBv5 delivery system with a DVBv3 type + * @fe: struct frontend; + * @delsys: DVBv5 type that will be used for emulation + * + * Provides emulation for delivery systems that are compatible with the old + * DVBv3 call. Among its usages, it provices support for ISDB-T, and allows + * using a DVB-S2 only frontend just like it were a DVB-S, if the frontent + * parameters are compatible with DVB-S spec. + */ +static int emulate_delivery_system(struct dvb_frontend *fe, u32 delsys) { int i; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1519,51 +1527,52 @@ static int emulate_delivery_system(struct dvb_frontend *fe, c->delivery_system = delsys; /* - * The DVBv3 or DVBv5 call is requesting a different system. So, - * emulation is needed. - * - * Emulate newer delivery systems like ISDBT, DVBT and DTMB - * for older DVBv5 applications. The emulation will try to use - * the auto mode for most things, and will assume that the desired - * delivery system is the last one at the ops.delsys[] array + * If the call is for ISDB-T, put it into full-seg, auto mode, TV */ - dev_dbg(fe->dvb->device, - "%s: Using delivery system %d emulated as if it were a %d\n", - __func__, delsys, desired_system); + if (c->delivery_system == SYS_ISDBT) { + dev_dbg(fe->dvb->device, + "%s: Using defaults for SYS_ISDBT\n", + __func__); - /* - * For now, handles ISDB-T calls. More code may be needed here for the - * other emulated stuff - */ - if (type == DVBV3_OFDM) { - if (c->delivery_system == SYS_ISDBT) { - dev_dbg(fe->dvb->device, - "%s: Using defaults for SYS_ISDBT\n", - __func__); - - if (!c->bandwidth_hz) - c->bandwidth_hz = 6000000; - - c->isdbt_partial_reception = 0; - c->isdbt_sb_mode = 0; - c->isdbt_sb_subchannel = 0; - c->isdbt_sb_segment_idx = 0; - c->isdbt_sb_segment_count = 0; - c->isdbt_layer_enabled = 0; - for (i = 0; i < 3; i++) { - c->layer[i].fec = FEC_AUTO; - c->layer[i].modulation = QAM_AUTO; - c->layer[i].interleaving = 0; - c->layer[i].segment_count = 0; - } + if (!c->bandwidth_hz) + c->bandwidth_hz = 6000000; + + c->isdbt_partial_reception = 0; + c->isdbt_sb_mode = 0; + c->isdbt_sb_subchannel = 0; + c->isdbt_sb_segment_idx = 0; + c->isdbt_sb_segment_count = 0; + c->isdbt_layer_enabled = 7; + for (i = 0; i < 3; i++) { + c->layer[i].fec = FEC_AUTO; + c->layer[i].modulation = QAM_AUTO; + c->layer[i].interleaving = 0; + c->layer[i].segment_count = 0; } } dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n", - __func__, c->delivery_system); + __func__, c->delivery_system); return 0; } +/** + * dvbv5_set_delivery_system - Sets the delivery system for a DVBv5 API call + * @fe: frontend struct + * @desired_system: delivery system requested by the user + * + * A DVBv5 call know what's the desired system it wants. So, set it. + * + * There are, however, a few known issues with early DVBv5 applications that + * are also handled by this logic: + * + * 1) Some early apps use SYS_UNDEFINED as the desired delivery system. + * This is an API violation, but, as we don't want to break userspace, + * convert it to the first supported delivery system. + * 2) Some apps might be using a DVBv5 call in a wrong way, passing, for + * example, SYS_DVBT instead of SYS_ISDBT. This is because early usage of + * ISDB-T provided backward compat with DVB-T. + */ static int dvbv5_set_delivery_system(struct dvb_frontend *fe, u32 desired_system) { @@ -1578,15 +1587,14 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe, * assume that the application wants to use the first supported * delivery system. */ - if (c->delivery_system == SYS_UNDEFINED) - c->delivery_system = fe->ops.delsys[0]; + if (desired_system == SYS_UNDEFINED) + desired_system = fe->ops.delsys[0]; /* - * This is a DVBv5 call. So, it likely knows the supported - * delivery systems. - */ - - /* Check if the desired delivery system is supported */ + * This is a DVBv5 call. So, it likely knows the supported + * delivery systems. So, check if the desired delivery system is + * supported + */ ncaps = 0; while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { if (fe->ops.delsys[ncaps] == desired_system) { @@ -1600,69 +1608,85 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe, } /* - * Need to emulate a delivery system + * The requested delivery system isn't supported. Maybe userspace + * is requesting a DVBv3 compatible delivery system. + * + * The emulation only works if the desired system is one of the + * delivery systems supported by DVBv3 API */ - - type = dvbv3_type(desired_system); - - /* - * The delivery system is not supported. See if it can be - * emulated. - * The emulation only works if the desired system is one of the - * DVBv3 delivery systems - */ if (!is_dvbv3_delsys(desired_system)) { dev_dbg(fe->dvb->device, - "%s: can't use a DVBv3 FE_SET_FRONTEND call for this frontend\n", - __func__); + "%s: Delivery system %d not supported.\n", + __func__, desired_system); return -EINVAL; } + type = dvbv3_type(desired_system); + /* * Get the last non-DVBv3 delivery system that has the same type * of the desired system */ ncaps = 0; while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) && - !is_dvbv3_delsys(fe->ops.delsys[ncaps])) + if (dvbv3_type(fe->ops.delsys[ncaps]) == type) delsys = fe->ops.delsys[ncaps]; ncaps++; } + /* There's nothing compatible with the desired delivery system */ if (delsys == SYS_UNDEFINED) { dev_dbg(fe->dvb->device, - "%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n", - __func__); + "%s: Delivery system %d not supported on emulation mode.\n", + __func__, desired_system); return -EINVAL; } - return emulate_delivery_system(fe, type, delsys, desired_system); + dev_dbg(fe->dvb->device, + "%s: Using delivery system %d emulated as if it were %d\n", + __func__, delsys, desired_system); + + return emulate_delivery_system(fe, desired_system); } +/** + * dvbv3_set_delivery_system - Sets the delivery system for a DVBv3 API call + * @fe: frontend struct + * + * A DVBv3 call doesn't know what's the desired system it wants. It also + * doesn't allow to switch between different types. Due to that, userspace + * should use DVBv5 instead. + * However, in order to avoid breaking userspace API, limited backward + * compatibility support is provided. + * + * There are some delivery systems that are incompatible with DVBv3 calls. + * + * This routine should work fine for frontends that support just one delivery + * system. + * + * For frontends that support multiple frontends: + * 1) It defaults to use the first supported delivery system. There's an + * userspace application that allows changing it at runtime; + * + * 2) If the current delivery system is not compatible with DVBv3, it gets + * the first one that it is compatible. + * + * NOTE: in order for this to work with applications like Kaffeine that + * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to + * DVB-S, drivers that support both DVB-S and DVB-S2 should have the + * SYS_DVBS entry before the SYS_DVBS2, otherwise it won't switch back + * to DVB-S. + */ static int dvbv3_set_delivery_system(struct dvb_frontend *fe) { int ncaps; - u32 desired_system; u32 delsys = SYS_UNDEFINED; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - enum dvbv3_emulation_type type; /* If not set yet, defaults to the first supported delivery system */ if (c->delivery_system == SYS_UNDEFINED) c->delivery_system = fe->ops.delsys[0]; - /* - * A DVBv3 call doesn't know what's the desired system. - * Also, DVBv3 applications don't know that ops.info->type - * could be changed, and they simply don't tune when it doesn't - * match. - * So, don't change the current delivery system, as it - * may be trying to do the wrong thing, like setting an - * ISDB-T frontend as DVB-T. Instead, find the closest - * DVBv3 system that matches the delivery system. - */ - /* * Trivial case: just use the current one, if it already a DVBv3 * delivery system @@ -1674,50 +1698,25 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe) return 0; } - /* Convert from DVBv3 into DVBv5 namespace */ - type = dvbv3_type(c->delivery_system); - switch (type) { - case DVBV3_QPSK: - desired_system = SYS_DVBS; - break; - case DVBV3_QAM: - desired_system = SYS_DVBC_ANNEX_A; - break; - case DVBV3_ATSC: - desired_system = SYS_ATSC; - break; - case DVBV3_OFDM: - desired_system = SYS_DVBT; - break; - default: - dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n", - __func__); - return -EINVAL; - } - /* - * Get a delivery system that is compatible with DVBv3 - * NOTE: in order for this to work with softwares like Kaffeine that - * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to - * DVB-S, drivers that support both should put the SYS_DVBS entry - * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. - * The real fix is that userspace applications should not use DVBv3 - * and not trust on calling FE_SET_FRONTEND to switch the delivery - * system. + * Seek for the first delivery system that it is compatible with a + * DVBv3 standard */ ncaps = 0; while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - delsys = desired_system; + if (dvbv3_type(fe->ops.delsys[ncaps]) != DVBV3_UNKNOWN) { + delsys = fe->ops.delsys[ncaps]; break; } ncaps++; } if (delsys == SYS_UNDEFINED) { - dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n", - __func__, desired_system); + dev_dbg(fe->dvb->device, + "%s: Couldn't find a delivery system that works with FE_SET_FRONTEND\n", + __func__); + return -EINVAL; } - return emulate_delivery_system(fe, type, delsys, desired_system); + return emulate_delivery_system(fe, delsys); } static int dtv_property_process_set(struct dvb_frontend *fe, -- cgit From cab3e1ffbe1b9c7a607506338f590dc1e6ca9909 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Mon, 17 Sep 2012 04:04:58 -0300 Subject: [media] cx25821: Cleanup filename assignment code I'm pasting the original code and my proposal on the commit message for make it easy to compare the two versions. Line 62 of cx25821-audio-upstream.h contains: char *_defaultAudioName = "/root/audioGOOD.wav"; Original code after replace kmemdup for kstrdup, and after fix return error code: if (dev->input_audiofilename) { dev->_audiofilename = kstrdup(dev->input_audiofilename, GFP_KERNEL); if (!dev->_audiofilename) { err = -ENOMEM; goto error; } /* Default if filename is empty string */ if (strcmp(dev->input_audiofilename, "") == 0) dev->_audiofilename = "/root/audioGOOD.wav"; } else { dev->_audiofilename = kstrdup(_defaultAudioName, GFP_KERNEL); if (!dev->_audiofilename) { err = -ENOMEM; goto error; } } Code proposed in this patch: if ((dev->input_audiofilename) && (strcmp(dev->input_audiofilename, "") != 0)) dev->_audiofilename = kstrdup(dev->input_audiofilename, GFP_KERNEL); else dev->_audiofilename = kstrdup(_defaultAudioName, GFP_KERNEL); if (!dev->_audiofilename) { err = -ENOMEM; goto error; } Signed-off-by: Peter Senna Tschudin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-audio-upstream.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c index 87491ca05ee5..ea973202a66c 100644 --- a/drivers/media/pci/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c @@ -728,26 +728,17 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER; _line_size = AUDIO_LINE_SIZE; - if (dev->input_audiofilename) { + if ((dev->input_audiofilename) && + (strcmp(dev->input_audiofilename, "") != 0)) dev->_audiofilename = kstrdup(dev->input_audiofilename, GFP_KERNEL); - - if (!dev->_audiofilename) { - err = -ENOMEM; - goto error; - } - - /* Default if filename is empty string */ - if (strcmp(dev->input_audiofilename, "") == 0) - dev->_audiofilename = "/root/audioGOOD.wav"; - } else { + else dev->_audiofilename = kstrdup(_defaultAudioName, GFP_KERNEL); - if (!dev->_audiofilename) { - err = -ENOMEM; - goto error; - } + if (!dev->_audiofilename) { + err = -ENOMEM; + goto error; } cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, -- cgit From 11cf48eab21887a120f7f47c67b44a829e3c371d Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:27 -0400 Subject: tty: Relocate tty_ldisc_halt() to avoid forward declaration tty_ldisc_halt() will use the file-scoped function, tty_ldisc_wait_idle(), in the following patch. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 15667c0fd645..f691c7604d9a 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -498,29 +498,6 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) } } -/** - * tty_ldisc_halt - shut down the line discipline - * @tty: tty device - * - * Shut down the line discipline and work queue for this tty device. - * The TTY_LDISC flag being cleared ensures no further references can - * be obtained while the delayed work queue halt ensures that no more - * data is fed to the ldisc. - * - * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) - * in order to make sure any currently executing ldisc work is also - * flushed. - */ - -static int tty_ldisc_halt(struct tty_struct *tty) -{ - int scheduled; - clear_bit(TTY_LDISC, &tty->flags); - scheduled = cancel_work_sync(&tty->port->buf.work); - set_bit(TTY_LDISC_HALTED, &tty->flags); - return scheduled; -} - /** * tty_ldisc_flush_works - flush all works of a tty * @tty: tty device to flush works for @@ -550,6 +527,29 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) return ret > 0 ? 0 : -EBUSY; } +/** + * tty_ldisc_halt - shut down the line discipline + * @tty: tty device + * + * Shut down the line discipline and work queue for this tty device. + * The TTY_LDISC flag being cleared ensures no further references can + * be obtained while the delayed work queue halt ensures that no more + * data is fed to the ldisc. + * + * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) + * in order to make sure any currently executing ldisc work is also + * flushed. + */ + +static int tty_ldisc_halt(struct tty_struct *tty) +{ + int scheduled; + clear_bit(TTY_LDISC, &tty->flags); + scheduled = cancel_work_sync(&tty->port->buf.work); + set_bit(TTY_LDISC_HALTED, &tty->flags); + return scheduled; +} + /** * tty_ldisc_hangup_halt - halt the line discipline for hangup * @tty: tty being hung up -- cgit From cf5284765862ac65e4a3e5b34652e593ffda2bdf Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:28 -0400 Subject: tty: Strengthen no-subsequent-use guarantee of tty_ldisc_halt() In preparation for destructing and freeing the tty, the line discipline must first be brought to an inactive state before it can be destructed. This line discipline shutdown must: - disallow new users of the ldisc - wait for existing ldisc users to finish - only then, cancel/flush their pending/running work Factor tty_ldisc_wait_idle() from tty_set_ldisc() and tty_ldisc_kill() to ensure this shutdown order. Failure to provide this guarantee can result in scheduled work running after the tty has already been freed, as indicated in the following log message: [ 88.331234] WARNING: at drivers/tty/tty_buffer.c:435 flush_to_ldisc+0x194/0x1d0() [ 88.334505] Hardware name: Bochs [ 88.335618] tty is bad=-1 [ 88.335703] Modules linked in: netconsole configfs bnep rfcomm bluetooth ...... [ 88.345272] Pid: 39, comm: kworker/1:1 Tainted: G W 3.7.0-next-20121129+ttydebug-xeon #20121129+ttydebug [ 88.347736] Call Trace: [ 88.349024] [] warn_slowpath_common+0x7f/0xc0 [ 88.350383] [] warn_slowpath_fmt+0x46/0x50 [ 88.351745] [] flush_to_ldisc+0x194/0x1d0 [ 88.353047] [] ? _raw_spin_unlock_irq+0x21/0x50 [ 88.354190] [] ? finish_task_switch+0x49/0xe0 [ 88.355436] [] process_one_work+0x121/0x490 [ 88.357674] [] ? __tty_buffer_flush+0x90/0x90 [ 88.358954] [] worker_thread+0x164/0x3e0 [ 88.360247] [] ? manage_workers+0x120/0x120 [ 88.361282] [] kthread+0xc0/0xd0 [ 88.362284] [] ? cmos_do_probe+0x2eb/0x3bf [ 88.363391] [] ? flush_kthread_worker+0xb0/0xb0 [ 88.364797] [] ret_from_fork+0x7c/0xb0 [ 88.366087] [] ? flush_kthread_worker+0xb0/0xb0 [ 88.367266] ---[ end trace 453a7c9f38fbfec0 ]--- Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index f691c7604d9a..525ee535c10d 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -530,24 +530,38 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) /** * tty_ldisc_halt - shut down the line discipline * @tty: tty device + * @pending: returns true if work was scheduled when cancelled + * (can be set to NULL) + * @timeout: # of jiffies to wait for ldisc refs to be released * * Shut down the line discipline and work queue for this tty device. * The TTY_LDISC flag being cleared ensures no further references can * be obtained while the delayed work queue halt ensures that no more * data is fed to the ldisc. * + * Furthermore, guarantee that existing ldisc references have been + * released, which in turn, guarantees that no future buffer work + * can be rescheduled. + * * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) * in order to make sure any currently executing ldisc work is also * flushed. */ -static int tty_ldisc_halt(struct tty_struct *tty) +static int tty_ldisc_halt(struct tty_struct *tty, int *pending, long timeout) { - int scheduled; + int scheduled, retval; + clear_bit(TTY_LDISC, &tty->flags); + retval = tty_ldisc_wait_idle(tty, timeout); + if (retval) + return retval; + scheduled = cancel_work_sync(&tty->port->buf.work); set_bit(TTY_LDISC_HALTED, &tty->flags); - return scheduled; + if (pending) + *pending = scheduled; + return 0; } /** @@ -688,9 +702,9 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) * parallel to the change and re-referencing the tty. */ - work = tty_ldisc_halt(tty); - if (o_tty) - o_work = tty_ldisc_halt(o_tty); + retval = tty_ldisc_halt(tty, &work, 5 * HZ); + if (!retval && o_tty) + retval = tty_ldisc_halt(o_tty, &o_work, 5 * HZ); /* * Wait for ->hangup_work and ->buf.work handlers to terminate. @@ -701,8 +715,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_flush_works(tty); - retval = tty_ldisc_wait_idle(tty, 5 * HZ); - tty_lock(tty); mutex_lock(&tty->ldisc_mutex); @@ -921,11 +933,6 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) static void tty_ldisc_kill(struct tty_struct *tty) { - /* There cannot be users from userspace now. But there still might be - * drivers holding a reference via tty_ldisc_ref. Do not steal them the - * ldisc until they are done. */ - tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT); - mutex_lock(&tty->ldisc_mutex); /* * Now kill off the ldisc @@ -958,13 +965,12 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) * race with the set_ldisc code path. */ - tty_ldisc_halt(tty); - if (o_tty) - tty_ldisc_halt(o_tty); - + tty_ldisc_halt(tty, NULL, MAX_SCHEDULE_TIMEOUT); tty_ldisc_flush_works(tty); - if (o_tty) + if (o_tty) { + tty_ldisc_halt(o_tty, NULL, MAX_SCHEDULE_TIMEOUT); tty_ldisc_flush_works(o_tty); + } tty_lock_pair(tty, o_tty); /* This will need doing differently if we need to lock */ -- cgit From f4cf7a384587c16c59565dd6930dd763f243dba4 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:29 -0400 Subject: tty: Halt both ldiscs concurrently The pty driver does not obtain an ldisc reference to the linked tty when writing. When the ldiscs are sequentially halted, it is possible for one ldisc to be halted, and before the second ldisc can be halted, a concurrent write schedules buffer work on the first ldisc. This can lead to an access-after-free error when the scheduled buffer work starts on the closed ldisc. Prevent subsequent use after halt by performing each stage of the halt on both ttys. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 525ee535c10d..77120911e016 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -530,14 +530,17 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) /** * tty_ldisc_halt - shut down the line discipline * @tty: tty device + * @o_tty: paired pty device (can be NULL) * @pending: returns true if work was scheduled when cancelled * (can be set to NULL) + * @o_pending: returns true if work was scheduled when cancelled + * (can be set to NULL) * @timeout: # of jiffies to wait for ldisc refs to be released * - * Shut down the line discipline and work queue for this tty device. - * The TTY_LDISC flag being cleared ensures no further references can - * be obtained while the delayed work queue halt ensures that no more - * data is fed to the ldisc. + * Shut down the line discipline and work queue for this tty device and + * its paired pty (if exists). Clearing the TTY_LDISC flag ensures + * no further references can be obtained while the work queue halt + * ensures that no more data is fed to the ldisc. * * Furthermore, guarantee that existing ldisc references have been * released, which in turn, guarantees that no future buffer work @@ -548,19 +551,32 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) * flushed. */ -static int tty_ldisc_halt(struct tty_struct *tty, int *pending, long timeout) +static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty, + int *pending, int *o_pending, long timeout) { - int scheduled, retval; + int scheduled, o_scheduled, retval; clear_bit(TTY_LDISC, &tty->flags); + if (o_tty) + clear_bit(TTY_LDISC, &o_tty->flags); + retval = tty_ldisc_wait_idle(tty, timeout); + if (!retval && o_tty) + retval = tty_ldisc_wait_idle(o_tty, timeout); if (retval) return retval; scheduled = cancel_work_sync(&tty->port->buf.work); set_bit(TTY_LDISC_HALTED, &tty->flags); + if (o_tty) { + o_scheduled = cancel_work_sync(&o_tty->port->buf.work); + set_bit(TTY_LDISC_HALTED, &o_tty->flags); + } + if (pending) *pending = scheduled; + if (o_tty && o_pending) + *o_pending = o_scheduled; return 0; } @@ -702,9 +718,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) * parallel to the change and re-referencing the tty. */ - retval = tty_ldisc_halt(tty, &work, 5 * HZ); - if (!retval && o_tty) - retval = tty_ldisc_halt(o_tty, &o_work, 5 * HZ); + retval = tty_ldisc_halt(tty, o_tty, &work, &o_work, 5 * HZ); /* * Wait for ->hangup_work and ->buf.work handlers to terminate. @@ -965,12 +979,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) * race with the set_ldisc code path. */ - tty_ldisc_halt(tty, NULL, MAX_SCHEDULE_TIMEOUT); + tty_ldisc_halt(tty, o_tty, NULL, NULL, MAX_SCHEDULE_TIMEOUT); tty_ldisc_flush_works(tty); - if (o_tty) { - tty_ldisc_halt(o_tty, NULL, MAX_SCHEDULE_TIMEOUT); + if (o_tty) tty_ldisc_flush_works(o_tty); - } tty_lock_pair(tty, o_tty); /* This will need doing differently if we need to lock */ -- cgit From 977066e7587b1b57023a048c0ba754955ea3e7bc Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:30 -0400 Subject: tty: Wait for SAK work before waiting for hangup work SAK work may schedule hangup work (if TTY_SOFT_SAK is defined), thus SAK work must be flushed before hangup work. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 77120911e016..37671fcc7e4c 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -506,8 +506,8 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) */ static void tty_ldisc_flush_works(struct tty_struct *tty) { - flush_work(&tty->hangup_work); flush_work(&tty->SAK_work); + flush_work(&tty->hangup_work); flush_work(&tty->port->buf.work); } -- cgit From 25518c68b334aa977d857dd71dd53f694ffb11e8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:31 -0400 Subject: n_tty: Correct unthrottle-with-buffer-flush comments The driver is no longer unthrottled on buffer reset, so remove comments that claim it is. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 15f7195f4b4c..0d3f715de7d2 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -198,9 +198,8 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) * reset_buffer_flags - reset buffer state * @tty: terminal to reset * - * Reset the read buffer counters, clear the flags, - * and make sure the driver is unthrottled. Called - * from n_tty_open() and n_tty_flush_buffer(). + * Reset the read buffer counters and clear the flags. + * Called from n_tty_open() and n_tty_flush_buffer(). * * Locking: tty_read_lock for read fields. */ @@ -239,17 +238,15 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) * n_tty_flush_buffer - clean input queue * @tty: terminal device * - * Flush the input buffer. Called when the line discipline is - * being closed, when the tty layer wants the buffer flushed (eg - * at hangup) or when the N_TTY line discipline internally has to - * clean the pending queue (for example some signals). + * Flush the input buffer. Called when the tty layer wants the + * buffer flushed (eg at hangup) or when the N_TTY line discipline + * internally has to clean the pending queue (for example some signals). * * Locking: ctrl_lock, read_lock. */ static void n_tty_flush_buffer(struct tty_struct *tty) { - /* clear everything and unthrottle the driver */ reset_buffer_flags(tty); if (tty->link) -- cgit From b66f4fa509153ca9d313075806d5c6425dfa43c5 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:32 -0400 Subject: n_tty: Fully initialize ldisc before restarting buffer work Buffer work may already be pending when the n_tty ldisc is re-opened, eg., when setting the ldisc (via TIOCSETD ioctl) and when hanging up the tty. Since n_tty_set_room() may restart buffer work, first ensure the ldisc is completely initialized. Factor n_tty_set_room() out of reset_buffer_flags() (only 2 callers) and reorganize n_tty_open() to set termios last; buffer work will be restarted there if necessary, after the char_map is properly initialized. Fixes this WARNING: [ 549.561769] ------------[ cut here ]------------ [ 549.598755] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0xff/0x130() [ 549.604058] scheduling buffer work for halted ldisc [ 549.607741] Pid: 9417, comm: trinity-child28 Tainted: G D W 3.7.0-next-20121217-sasha-00023-g8689ef9 #219 [ 549.652580] Call Trace: [ 549.662754] [] ? n_tty_set_room+0xff/0x130 [ 549.665458] [] warn_slowpath_common+0x87/0xb0 [ 549.668257] [] warn_slowpath_fmt+0x41/0x50 [ 549.671007] [] n_tty_set_room+0xff/0x130 [ 549.673268] [] reset_buffer_flags+0x137/0x150 [ 549.675607] [] n_tty_open+0x131/0x1c0 [ 549.677699] [] tty_ldisc_open.isra.5+0x54/0x70 [ 549.680147] [] tty_ldisc_hangup+0x11f/0x1e0 [ 549.682409] [] __tty_hangup+0x137/0x440 [ 549.684634] [] tty_vhangup+0x9/0x10 [ 549.686443] [] pty_close+0x14c/0x160 [ 549.688446] [] tty_release+0xd5/0x490 [ 549.690460] [] __fput+0x122/0x250 [ 549.692577] [] ____fput+0x9/0x10 [ 549.694534] [] task_work_run+0xb2/0xf0 [ 549.696349] [] do_exit+0x36d/0x580 [ 549.698286] [] ? syscall_trace_enter+0x24/0x2e0 [ 549.702729] [] do_group_exit+0x8a/0xc0 [ 549.706775] [] sys_exit_group+0x12/0x20 [ 549.711088] [] tracesys+0xe1/0xe6 [ 549.728001] ---[ end trace 73eb41728f11f87e ]--- Reported-by: Sasha Levin Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0d3f715de7d2..d655416087b7 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -204,9 +204,8 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) * Locking: tty_read_lock for read fields. */ -static void reset_buffer_flags(struct tty_struct *tty) +static void reset_buffer_flags(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; unsigned long flags; raw_spin_lock_irqsave(&ldata->read_lock, flags); @@ -219,7 +218,6 @@ static void reset_buffer_flags(struct tty_struct *tty) ldata->canon_head = ldata->canon_data = ldata->erasing = 0; bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); - n_tty_set_room(tty); } static void n_tty_packet_mode_flush(struct tty_struct *tty) @@ -247,7 +245,8 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) static void n_tty_flush_buffer(struct tty_struct *tty) { - reset_buffer_flags(tty); + reset_buffer_flags(tty->disc_data); + n_tty_set_room(tty); if (tty->link) n_tty_packet_mode_flush(tty); @@ -1633,14 +1632,14 @@ static int n_tty_open(struct tty_struct *tty) goto err_free_bufs; tty->disc_data = ldata; - /* indicate buffer work may resume */ - clear_bit(TTY_LDISC_HALTED, &tty->flags); - reset_buffer_flags(tty); - tty_unthrottle(tty); + reset_buffer_flags(tty->disc_data); ldata->column = 0; - n_tty_set_termios(tty, NULL); tty->minimum_to_wake = 1; tty->closing = 0; + /* indicate buffer work may resume */ + clear_bit(TTY_LDISC_HALTED, &tty->flags); + n_tty_set_termios(tty, NULL); + tty_unthrottle(tty); return 0; err_free_bufs: -- cgit From d912156605b0eb3b3070dc7eabc43db6379aa43b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:33 -0400 Subject: tty: Don't reenable already enabled ldisc tty_ldisc_hangup() guarantees the ldisc is enabled (or that there is no ldisc). Since __tty_hangup() was the only user, re-define tty_ldisc_enable() in file-scope. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 1 - drivers/tty/tty_ldisc.c | 2 +- include/linux/tty.h | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d3ddb31e363e..e6ee0f459a20 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -693,7 +693,6 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) */ set_bit(TTY_HUPPED, &tty->flags); clear_bit(TTY_HUPPING, &tty->flags); - tty_ldisc_enable(tty); tty_unlock(tty); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 37671fcc7e4c..9c727da59fac 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -373,7 +373,7 @@ static inline void tty_ldisc_put(struct tty_ldisc *ld) * Clearing directly is allowed. */ -void tty_ldisc_enable(struct tty_struct *tty) +static void tty_ldisc_enable(struct tty_struct *tty) { clear_bit(TTY_LDISC_HALTED, &tty->flags); set_bit(TTY_LDISC, &tty->flags); diff --git a/include/linux/tty.h b/include/linux/tty.h index 66ae020e8a98..367a9dfc4ea2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -561,8 +561,6 @@ extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); extern void tty_ldisc_init(struct tty_struct *tty); extern void tty_ldisc_deinit(struct tty_struct *tty); extern void tty_ldisc_begin(void); -/* This last one is just for the tty layer internals and shouldn't be used elsewhere */ -extern void tty_ldisc_enable(struct tty_struct *tty); /* n_tty.c */ -- cgit From 4f98d4675166fc1991dbad7dd2af634df7c14061 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:34 -0400 Subject: tty: Complete ownership transfer of flip buffers Waiting for buffer work to complete is not required for safely performing changes to the line discipline, once the line discipline is halted. The buffer work routine, flush_to_ldisc(), will be unable to acquire an ldisc ref and all existing references were waited until released (so it can't already have one). Ensure running buffer work which may reference the soon-to-be-gone tty completes and any buffer work running after this point retrieves a NULL tty. Also, ensure all buffer work is cancelled on port destruction. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 1 + drivers/tty/tty_ldisc.c | 47 ++++++++++++----------------------------------- drivers/tty/tty_port.c | 1 + 3 files changed, 14 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e6ee0f459a20..458763418701 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1595,6 +1595,7 @@ static void release_tty(struct tty_struct *tty, int idx) tty_free_termios(tty); tty_driver_remove_tty(tty->driver, tty); tty->port->itty = NULL; + cancel_work_sync(&tty->port->buf.work); if (tty->link) tty_kref_put(tty->link); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 9c727da59fac..cbb945b03cdb 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -508,7 +508,6 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) { flush_work(&tty->SAK_work); flush_work(&tty->hangup_work); - flush_work(&tty->port->buf.work); } /** @@ -531,20 +530,12 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) * tty_ldisc_halt - shut down the line discipline * @tty: tty device * @o_tty: paired pty device (can be NULL) - * @pending: returns true if work was scheduled when cancelled - * (can be set to NULL) - * @o_pending: returns true if work was scheduled when cancelled - * (can be set to NULL) * @timeout: # of jiffies to wait for ldisc refs to be released * * Shut down the line discipline and work queue for this tty device and * its paired pty (if exists). Clearing the TTY_LDISC flag ensures - * no further references can be obtained while the work queue halt - * ensures that no more data is fed to the ldisc. - * - * Furthermore, guarantee that existing ldisc references have been - * released, which in turn, guarantees that no future buffer work - * can be rescheduled. + * no further references can be obtained, while waiting for existing + * references to be released ensures no more data is fed to the ldisc. * * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) * in order to make sure any currently executing ldisc work is also @@ -552,9 +543,9 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) */ static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty, - int *pending, int *o_pending, long timeout) + long timeout) { - int scheduled, o_scheduled, retval; + int retval; clear_bit(TTY_LDISC, &tty->flags); if (o_tty) @@ -566,17 +557,10 @@ static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty, if (retval) return retval; - scheduled = cancel_work_sync(&tty->port->buf.work); set_bit(TTY_LDISC_HALTED, &tty->flags); - if (o_tty) { - o_scheduled = cancel_work_sync(&o_tty->port->buf.work); + if (o_tty) set_bit(TTY_LDISC_HALTED, &o_tty->flags); - } - if (pending) - *pending = scheduled; - if (o_tty && o_pending) - *o_pending = o_scheduled; return 0; } @@ -586,17 +570,12 @@ static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty, * * Shut down the line discipline and work queue for the tty device * being hungup. Clear the TTY_LDISC flag to ensure no further - * references can be obtained, wait for remaining references to be - * released, and cancel pending buffer work to ensure no more - * data is fed to this ldisc. + * references can be obtained and wait for remaining references to be + * released to ensure no more data is fed to this ldisc. * Caller must hold legacy and ->ldisc_mutex. * * NB: tty_set_ldisc() is prevented from changing the ldisc concurrently * with this function by checking the TTY_HUPPING flag. - * - * NB: if tty->ldisc is NULL then buffer work does not need to be - * cancelled because it must already have done as a precondition - * of closing the ldisc and setting tty->ldisc to NULL */ static bool tty_ldisc_hangup_halt(struct tty_struct *tty) { @@ -616,7 +595,6 @@ static bool tty_ldisc_hangup_halt(struct tty_struct *tty) tty_name(tty, tty_n)); } - cancel_work_sync(&tty->port->buf.work); set_bit(TTY_LDISC_HALTED, &tty->flags); /* must reacquire both locks and preserve lock order */ @@ -644,7 +622,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) { int retval; struct tty_ldisc *o_ldisc, *new_ldisc; - int work, o_work = 0; struct tty_struct *o_tty; new_ldisc = tty_ldisc_get(ldisc); @@ -718,7 +695,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) * parallel to the change and re-referencing the tty. */ - retval = tty_ldisc_halt(tty, o_tty, &work, &o_work, 5 * HZ); + retval = tty_ldisc_halt(tty, o_tty, 5 * HZ); /* * Wait for ->hangup_work and ->buf.work handlers to terminate. @@ -782,10 +759,10 @@ enable: /* Restart the work queue in case no characters kick it off. Safe if already running */ - if (work) - schedule_work(&tty->port->buf.work); - if (o_work) + schedule_work(&tty->port->buf.work); + if (o_tty) schedule_work(&o_tty->port->buf.work); + mutex_unlock(&tty->ldisc_mutex); tty_unlock(tty); return retval; @@ -979,7 +956,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) * race with the set_ldisc code path. */ - tty_ldisc_halt(tty, o_tty, NULL, NULL, MAX_SCHEDULE_TIMEOUT); + tty_ldisc_halt(tty, o_tty, MAX_SCHEDULE_TIMEOUT); tty_ldisc_flush_works(tty); if (o_tty) tty_ldisc_flush_works(o_tty); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 969c3e675a76..121aeb9393e1 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -132,6 +132,7 @@ EXPORT_SYMBOL(tty_port_free_xmit_buf); */ void tty_port_destroy(struct tty_port *port) { + cancel_work_sync(&port->buf.work); tty_buffer_free_all(port); } EXPORT_SYMBOL(tty_port_destroy); -- cgit From a2965b7bee00a01731ae79de34c26e146cbd08cf Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:35 -0400 Subject: tty: Make core responsible for synchronizing its work The tty core relies on the ldisc layer for synchronizing destruction of the tty. Instead, the final tty release must wait for any pending tty work to complete prior to tty destruction. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 17 +++++++++++++++++ drivers/tty/tty_ldisc.c | 24 ++++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 458763418701..95e97128e2ee 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1510,6 +1510,17 @@ void tty_free_termios(struct tty_struct *tty) } EXPORT_SYMBOL(tty_free_termios); +/** + * tty_flush_works - flush all works of a tty + * @tty: tty device to flush works for + * + * Sync flush all works belonging to @tty. + */ +static void tty_flush_works(struct tty_struct *tty) +{ + flush_work(&tty->SAK_work); + flush_work(&tty->hangup_work); +} /** * release_one_tty - release tty structure memory @@ -1831,6 +1842,12 @@ int tty_release(struct inode *inode, struct file *filp) * Ask the line discipline code to release its structures */ tty_ldisc_release(tty, o_tty); + + /* Wait for pending work before tty destruction commmences */ + tty_flush_works(tty); + if (o_tty) + tty_flush_works(o_tty); + /* * The release_tty function takes care of the details of clearing * the slots and preserving the termios structure. The tty_unlock_pair diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index cbb945b03cdb..7f7e1a3d3825 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -498,18 +498,6 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) } } -/** - * tty_ldisc_flush_works - flush all works of a tty - * @tty: tty device to flush works for - * - * Sync flush all works belonging to @tty. - */ -static void tty_ldisc_flush_works(struct tty_struct *tty) -{ - flush_work(&tty->SAK_work); - flush_work(&tty->hangup_work); -} - /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for @@ -698,13 +686,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) retval = tty_ldisc_halt(tty, o_tty, 5 * HZ); /* - * Wait for ->hangup_work and ->buf.work handlers to terminate. + * Wait for hangup to complete, if pending. * We must drop the mutex here in case a hangup is also in process. */ mutex_unlock(&tty->ldisc_mutex); - tty_ldisc_flush_works(tty); + flush_work(&tty->hangup_work); tty_lock(tty); mutex_lock(&tty->ldisc_mutex); @@ -951,15 +939,11 @@ static void tty_ldisc_kill(struct tty_struct *tty) void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) { /* - * Prevent flush_to_ldisc() from rescheduling the work for later. Then - * kill any delayed work. As this is the final close it does not - * race with the set_ldisc code path. + * Shutdown this line discipline. As this is the final close, + * it does not race with the set_ldisc code path. */ tty_ldisc_halt(tty, o_tty, MAX_SCHEDULE_TIMEOUT); - tty_ldisc_flush_works(tty); - if (o_tty) - tty_ldisc_flush_works(o_tty); tty_lock_pair(tty, o_tty); /* This will need doing differently if we need to lock */ -- cgit From c8785241741d4bc3ee6da2ff415a9a1b3df2b4cb Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:36 -0400 Subject: tty: Fix 'deferred reopen' ldisc comment This comment is a victim of code migration from "tty: Fix the ldisc hangup race"; re-parent it. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 7f7e1a3d3825..0030d556b9b3 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -854,11 +854,12 @@ void tty_ldisc_hangup(struct tty_struct *tty) */ mutex_lock(&tty->ldisc_mutex); - /* At this point we have a closed ldisc and we want to - reopen it. We could defer this to the next open but - it means auditing a lot of other paths so this is - a FIXME */ if (tty_ldisc_hangup_halt(tty)) { + + /* At this point we have a halted ldisc; we want to close it and + reopen a new ldisc. We could defer the reopen to the next + open but it means auditing a lot of other paths so this is + a FIXME */ if (reset == 0) { if (!tty_ldisc_reinit(tty, tty->termios.c_line)) -- cgit From c6c1d50b51e76b57fbf0651d38a7ae0c3fb9d5cc Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 22 Jan 2013 12:27:55 -0300 Subject: [media] media: Add 64--32 bit compat ioctl handler Provide an ioctl handler for 32-bit binaries on 64-bit systems. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Tested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-devnode.c | 31 ++++++++++++++++++++++++++++--- include/media/media-devnode.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c index 023b2a1cbb9b..fb0f0469fad7 100644 --- a/drivers/media/media-devnode.c +++ b/drivers/media/media-devnode.c @@ -116,19 +116,41 @@ static unsigned int media_poll(struct file *filp, return mdev->fops->poll(filp, poll); } -static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +static long +__media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, + long (*ioctl_func)(struct file *filp, unsigned int cmd, + unsigned long arg)) { struct media_devnode *mdev = media_devnode_data(filp); - if (!mdev->fops->ioctl) + if (!ioctl_func) return -ENOTTY; if (!media_devnode_is_registered(mdev)) return -EIO; - return mdev->fops->ioctl(filp, cmd, arg); + return ioctl_func(filp, cmd, arg); +} + +static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct media_devnode *mdev = media_devnode_data(filp); + + return __media_ioctl(filp, cmd, arg, mdev->fops->ioctl); } +#ifdef CONFIG_COMPAT + +static long media_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct media_devnode *mdev = media_devnode_data(filp); + + return __media_ioctl(filp, cmd, arg, mdev->fops->compat_ioctl); +} + +#endif /* CONFIG_COMPAT */ + /* Override for the open function */ static int media_open(struct inode *inode, struct file *filp) { @@ -188,6 +210,9 @@ static const struct file_operations media_devnode_fops = { .write = media_write, .open = media_open, .unlocked_ioctl = media_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = media_compat_ioctl, +#endif /* CONFIG_COMPAT */ .release = media_release, .poll = media_poll, .llseek = no_llseek, diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index f6caafc874cb..3446af279fca 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -46,6 +46,7 @@ struct media_file_operations { ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*ioctl) (struct file *, unsigned int, unsigned long); + long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*open) (struct file *); int (*release) (struct file *); }; -- cgit From b0a1f2a8420782ccb83fb4f68df37af642790560 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 22 Jan 2013 12:27:56 -0300 Subject: [media] media: implement 32-on-64 bit compat IOCTL handling Use the same handlers where the structs are the same. Implement a new handler for link enumeration since struct media_links_enum is different on 32-bit and 64-bit systems. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Tested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 102 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index d01fcb7e87c2..99b80b6f7f67 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -20,10 +20,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include +#include #include #include -#include +#include #include #include @@ -124,35 +125,31 @@ static void media_device_kpad_to_upad(const struct media_pad *kpad, upad->flags = kpad->flags; } -static long media_device_enum_links(struct media_device *mdev, - struct media_links_enum __user *ulinks) +static long __media_device_enum_links(struct media_device *mdev, + struct media_links_enum *links) { struct media_entity *entity; - struct media_links_enum links; - if (copy_from_user(&links, ulinks, sizeof(links))) - return -EFAULT; - - entity = find_entity(mdev, links.entity); + entity = find_entity(mdev, links->entity); if (entity == NULL) return -EINVAL; - if (links.pads) { + if (links->pads) { unsigned int p; for (p = 0; p < entity->num_pads; p++) { struct media_pad_desc pad; media_device_kpad_to_upad(&entity->pads[p], &pad); - if (copy_to_user(&links.pads[p], &pad, sizeof(pad))) + if (copy_to_user(&links->pads[p], &pad, sizeof(pad))) return -EFAULT; } } - if (links.links) { + if (links->links) { struct media_link_desc __user *ulink; unsigned int l; - for (l = 0, ulink = links.links; l < entity->num_links; l++) { + for (l = 0, ulink = links->links; l < entity->num_links; l++) { struct media_link_desc link; /* Ignore backlinks. */ @@ -169,8 +166,26 @@ static long media_device_enum_links(struct media_device *mdev, ulink++; } } + + return 0; +} + +static long media_device_enum_links(struct media_device *mdev, + struct media_links_enum __user *ulinks) +{ + struct media_links_enum links; + int rval; + + if (copy_from_user(&links, ulinks, sizeof(links))) + return -EFAULT; + + rval = __media_device_enum_links(mdev, &links); + if (rval < 0) + return rval; + if (copy_to_user(ulinks, &links, sizeof(*ulinks))) return -EFAULT; + return 0; } @@ -251,10 +266,71 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, return ret; } +#ifdef CONFIG_COMPAT + +struct media_links_enum32 { + __u32 entity; + compat_uptr_t pads; /* struct media_pad_desc * */ + compat_uptr_t links; /* struct media_link_desc * */ + __u32 reserved[4]; +}; + +static long media_device_enum_links32(struct media_device *mdev, + struct media_links_enum32 __user *ulinks) +{ + struct media_links_enum links; + compat_uptr_t pads_ptr, links_ptr; + + memset(&links, 0, sizeof(links)); + + if (get_user(links.entity, &ulinks->entity) + || get_user(pads_ptr, &ulinks->pads) + || get_user(links_ptr, &ulinks->links)) + return -EFAULT; + + links.pads = compat_ptr(pads_ptr); + links.links = compat_ptr(links_ptr); + + return __media_device_enum_links(mdev, &links); +} + +#define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32) + +static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct media_devnode *devnode = media_devnode_data(filp); + struct media_device *dev = to_media_device(devnode); + long ret; + + switch (cmd) { + case MEDIA_IOC_DEVICE_INFO: + case MEDIA_IOC_ENUM_ENTITIES: + case MEDIA_IOC_SETUP_LINK: + return media_device_ioctl(filp, cmd, arg); + + case MEDIA_IOC_ENUM_LINKS32: + mutex_lock(&dev->graph_mutex); + ret = media_device_enum_links32(dev, + (struct media_links_enum32 __user *)arg); + mutex_unlock(&dev->graph_mutex); + break; + + default: + ret = -ENOIOCTLCMD; + } + + return ret; +} +#endif /* CONFIG_COMPAT */ + static const struct media_file_operations media_device_fops = { .owner = THIS_MODULE, .open = media_device_open, .ioctl = media_device_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = media_device_compat_ioctl, +#endif /* CONFIG_COMPAT */ .release = media_device_close, }; -- cgit From 96433d104a4b39c43dd6f57776f9fcb765111a56 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:37 -0400 Subject: tty: Bracket ldisc release with TTY_DEBUG_HANGUP messages Expected typical log output: [ 2.437211] tty_open: opening pts1... [ 2.443376] tty_open: opening pts5... [ 2.447830] tty_release: ptm0 (tty count=1)... [ 2.447849] pts0 vhangup... [ 2.447865] tty_release: ptm0: final close [ 2.447876] tty_release: ptm0: freeing structure... [ 2.451634] tty_release: tty1 (tty count=1)... [ 2.451638] tty_release: tty1: final close [ 2.451654] tty_release: tty1: freeing structure... [ 2.452505] tty_release: pts5 (tty count=2)... [ 2.453029] tty_open: opening pts0... Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 95e97128e2ee..f6ce2c5fbe5b 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1836,7 +1836,7 @@ int tty_release(struct inode *inode, struct file *filp) return 0; #ifdef TTY_DEBUG_HANGUP - printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); + printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf)); #endif /* * Ask the line discipline code to release its structures @@ -1848,6 +1848,9 @@ int tty_release(struct inode *inode, struct file *filp) if (o_tty) tty_flush_works(o_tty); +#ifdef TTY_DEBUG_HANGUP + printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); +#endif /* * The release_tty function takes care of the details of clearing * the slots and preserving the termios structure. The tty_unlock_pair -- cgit From fc575ee6eadbcac757e3216e230b6fab1ba5b140 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:38 -0400 Subject: tty: Add ldisc hangup debug messages Expected typical debug log: [ 582.721965] tty_open: opening pts3... [ 582.721970] tty_open: opening pts3... [ 582.721977] tty_release: pts3 (tty count=3)... [ 582.721980] tty_release: ptm3 (tty count=1)... [ 582.722015] pts3 vhangup... [ 582.722020] tty_ldisc_hangup: pts3: closing ldisc: ffff88007a920540 [ 582.724128] tty_release: pts3 (tty count=2)... [ 582.724217] tty_ldisc_hangup: pts3: re-opened ldisc: ffff88007a920580 [ 582.724221] tty_release: ptm3: final close [ 582.724234] tty_ldisc_release: ptm3: closing ldisc: ffff88007a920a80 [ 582.724238] tty_ldisc_release: ptm3: ldisc closed [ 582.724241] tty_release: ptm3: freeing structure... [ 582.724741] tty_open: opening pts3... Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 0030d556b9b3..328ff5b544a5 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -20,6 +20,17 @@ #include #include +#undef LDISC_DEBUG_HANGUP + +#ifdef LDISC_DEBUG_HANGUP +#define tty_ldisc_debug(tty, f, args...) ({ \ + char __b[64]; \ + printk(KERN_DEBUG "%s: %s: " f, __func__, tty_name(tty, __b), ##args); \ +}) +#else +#define tty_ldisc_debug(tty, f, args...) +#endif + /* * This guards the refcounted line discipline lists. The lock * must be taken with irqs off because there are hangup path @@ -822,6 +833,8 @@ void tty_ldisc_hangup(struct tty_struct *tty) int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; int err = 0; + tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); + /* * FIXME! What are the locking issues here? This may me overdoing * things... This question is especially important now that we've @@ -878,6 +891,8 @@ void tty_ldisc_hangup(struct tty_struct *tty) mutex_unlock(&tty->ldisc_mutex); if (reset) tty_reset_termios(tty); + + tty_ldisc_debug(tty, "re-opened ldisc: %p\n", tty->ldisc); } /** @@ -944,6 +959,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) * it does not race with the set_ldisc code path. */ + tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); + tty_ldisc_halt(tty, o_tty, MAX_SCHEDULE_TIMEOUT); tty_lock_pair(tty, o_tty); @@ -955,6 +972,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) tty_unlock_pair(tty, o_tty); /* And the memory resources remaining (buffers, termios) will be disposed of when the kref hits zero */ + + tty_ldisc_debug(tty, "ldisc closed\n"); } /** -- cgit From 8842dda2366d3d0c97646102768831f9b0ffd712 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:39 -0400 Subject: tty: Don't protect atomic operation with mutex test_bit() is already atomic; drop mutex lock/unlock. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index f6ce2c5fbe5b..6afca98fae21 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1391,9 +1391,7 @@ static int tty_reopen(struct tty_struct *tty) } tty->count++; - mutex_lock(&tty->ldisc_mutex); WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); - mutex_unlock(&tty->ldisc_mutex); return 0; } -- cgit From f1a0569be680a1bfb9d624cc4893cba0c6ad4172 Mon Sep 17 00:00:00 2001 From: John Sheu Date: Wed, 6 Feb 2013 20:03:00 -0300 Subject: [media] v4l2-mem2mem: use CAPTURE queue lock In v4l2_m2m_try_schedule(), use the CAPTURE queue lock when accessing the CAPTURE queue, instead of relying on just holding the OUTPUT queue lock. Signed-off-by: John Sheu Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index da99cf727162..27ddb3d15251 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -230,12 +230,15 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) dprintk("No input buffers available\n"); return; } + spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); dprintk("No output buffers available\n"); return; } + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); if (m2m_dev->m2m_ops->job_ready -- cgit From ebc9baed42e42f9b51cf61672b7afb72f068d523 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:40 -0400 Subject: tty: Separate release semantics of ldisc reference tty_ldisc_ref()/tty_ldisc_unref() have usage semantics equivalent to down_read_trylock()/up_read(). Only callers of tty_ldisc_put() are performing the additional operations necessary for proper ldisc teardown, and then only after ensuring no outstanding 'read lock' remains. Thus, tty_ldisc_unref() should never be the last reference; WARN if it is. Conversely, tty_ldisc_put() should never be destructing if the use count != 1. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 69 +++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 328ff5b544a5..9362a1030c95 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -49,37 +49,6 @@ static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld) return ld; } -static void put_ldisc(struct tty_ldisc *ld) -{ - unsigned long flags; - - if (WARN_ON_ONCE(!ld)) - return; - - /* - * If this is the last user, free the ldisc, and - * release the ldisc ops. - * - * We really want an "atomic_dec_and_raw_lock_irqsave()", - * but we don't have it, so this does it by hand. - */ - raw_spin_lock_irqsave(&tty_ldisc_lock, flags); - if (atomic_dec_and_test(&ld->users)) { - struct tty_ldisc_ops *ldo = ld->ops; - - ldo->refcount--; - module_put(ldo->owner); - raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); - - kfree(ld); - return; - } - raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); - - if (waitqueue_active(&ld->wq_idle)) - wake_up(&ld->wq_idle); -} - /** * tty_register_ldisc - install a line discipline * @disc: ldisc number @@ -363,13 +332,45 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref); void tty_ldisc_deref(struct tty_ldisc *ld) { - put_ldisc(ld); + unsigned long flags; + + if (WARN_ON_ONCE(!ld)) + return; + + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); + /* + * WARNs if one-too-many reader references were released + * - the last reference must be released with tty_ldisc_put + */ + WARN_ON(atomic_dec_and_test(&ld->users)); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); + + if (waitqueue_active(&ld->wq_idle)) + wake_up(&ld->wq_idle); } EXPORT_SYMBOL_GPL(tty_ldisc_deref); +/** + * tty_ldisc_put - release the ldisc + * + * Complement of tty_ldisc_get(). + */ static inline void tty_ldisc_put(struct tty_ldisc *ld) { - put_ldisc(ld); + unsigned long flags; + + if (WARN_ON_ONCE(!ld)) + return; + + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); + + /* unreleased reader reference(s) will cause this WARN */ + WARN_ON(!atomic_dec_and_test(&ld->users)); + + ld->ops->refcount--; + module_put(ld->ops->owner); + kfree(ld); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); } /** @@ -1001,7 +1002,7 @@ void tty_ldisc_init(struct tty_struct *tty) */ void tty_ldisc_deinit(struct tty_struct *tty) { - put_ldisc(tty->ldisc); + tty_ldisc_put(tty->ldisc); tty_ldisc_assign(tty, NULL); } -- cgit From 16759f6cd8c590fa23cb2956fdf32fe23a67e482 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:41 -0400 Subject: tty: Document unsafe ldisc reference acquire Merge get_ldisc() into its only call site. Note how, after merging, the unsafe acquire of an ldisc reference is obvious. CPU 0 in tty_ldisc_try() | CPU 1 in tty_ldisc_halt() | test_bit(TTY_LDISC, &tty_flags) | if (true) | clear_bit(TTY_LDISC, &tty_flags) tty->ldisc != 0? | atomic_read(&tty->ldisc->users) if (true) | ret_val == 1? atomic_inc(&tty->ldisc->users) | if (false) | wait | | | The spin lock in tty_ldisc_try() does nothing wrt synchronizing the ldisc halt since it's not acquired as part of halting. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 9362a1030c95..5ee0b2be7d72 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -42,13 +42,6 @@ static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; -static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld) -{ - if (ld) - atomic_inc(&ld->users); - return ld; -} - /** * tty_register_ldisc - install a line discipline * @disc: ldisc number @@ -269,10 +262,13 @@ static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty) unsigned long flags; struct tty_ldisc *ld; + /* FIXME: this allows reference acquire after TTY_LDISC is cleared */ raw_spin_lock_irqsave(&tty_ldisc_lock, flags); ld = NULL; - if (test_bit(TTY_LDISC, &tty->flags)) - ld = get_ldisc(tty->ldisc); + if (test_bit(TTY_LDISC, &tty->flags) && tty->ldisc) { + ld = tty->ldisc; + atomic_inc(&ld->users); + } raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ld; } -- cgit From f48070457c728a1ff8f327240e70483cebabf83b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:42 -0400 Subject: tty: Fold one-line assign function into callers Now that tty_ldisc_assign() is a one-line file-scoped function, remove it and perform the simple assignment at its call sites. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 5ee0b2be7d72..f26ef1ace4f1 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -227,24 +227,6 @@ const struct file_operations tty_ldiscs_proc_fops = { .release = seq_release, }; -/** - * tty_ldisc_assign - set ldisc on a tty - * @tty: tty to assign - * @ld: line discipline - * - * Install an instance of a line discipline into a tty structure. The - * ldisc must have a reference count above zero to ensure it remains. - * The tty instance refcount starts at zero. - * - * Locking: - * Caller must hold references - */ - -static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) -{ - tty->ldisc = ld; -} - /** * tty_ldisc_try - internal helper * @tty: the tty @@ -488,7 +470,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) /* There is an outstanding reference here so this is safe */ old = tty_ldisc_get(old->ops->num); WARN_ON(IS_ERR(old)); - tty_ldisc_assign(tty, old); + tty->ldisc = old; tty_set_termios_ldisc(tty, old->ops->num); if (tty_ldisc_open(tty, old) < 0) { tty_ldisc_put(old); @@ -496,7 +478,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) new_ldisc = tty_ldisc_get(N_TTY); if (IS_ERR(new_ldisc)) panic("n_tty: get"); - tty_ldisc_assign(tty, new_ldisc); + tty->ldisc = new_ldisc; tty_set_termios_ldisc(tty, N_TTY); r = tty_ldisc_open(tty, new_ldisc); if (r < 0) @@ -725,7 +707,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_close(tty, o_ldisc); /* Now set up the new line discipline. */ - tty_ldisc_assign(tty, new_ldisc); + tty->ldisc = new_ldisc; tty_set_termios_ldisc(tty, ldisc); retval = tty_ldisc_open(tty, new_ldisc); @@ -799,11 +781,10 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); - tty->ldisc = NULL; /* * Switch the line discipline back */ - tty_ldisc_assign(tty, ld); + tty->ldisc = ld; tty_set_termios_ldisc(tty, ldisc); return 0; @@ -986,7 +967,7 @@ void tty_ldisc_init(struct tty_struct *tty) struct tty_ldisc *ld = tty_ldisc_get(N_TTY); if (IS_ERR(ld)) panic("n_tty: init_tty"); - tty_ldisc_assign(tty, ld); + tty->ldisc = ld; } /** @@ -999,7 +980,7 @@ void tty_ldisc_init(struct tty_struct *tty) void tty_ldisc_deinit(struct tty_struct *tty) { tty_ldisc_put(tty->ldisc); - tty_ldisc_assign(tty, NULL); + tty->ldisc = NULL; } void tty_ldisc_begin(void) -- cgit From 734de249fbe2fbf594c30202a343f0772b6d18fe Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:43 -0400 Subject: tty: Locate get/put ldisc functions together Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index f26ef1ace4f1..4e46c1721b9d 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -179,6 +179,29 @@ static struct tty_ldisc *tty_ldisc_get(int disc) return ld; } +/** + * tty_ldisc_put - release the ldisc + * + * Complement of tty_ldisc_get(). + */ +static inline void tty_ldisc_put(struct tty_ldisc *ld) +{ + unsigned long flags; + + if (WARN_ON_ONCE(!ld)) + return; + + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); + + /* unreleased reader reference(s) will cause this WARN */ + WARN_ON(!atomic_dec_and_test(&ld->users)); + + ld->ops->refcount--; + module_put(ld->ops->owner); + kfree(ld); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); +} + static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) { return (*pos < NR_LDISCS) ? pos : NULL; @@ -328,29 +351,6 @@ void tty_ldisc_deref(struct tty_ldisc *ld) } EXPORT_SYMBOL_GPL(tty_ldisc_deref); -/** - * tty_ldisc_put - release the ldisc - * - * Complement of tty_ldisc_get(). - */ -static inline void tty_ldisc_put(struct tty_ldisc *ld) -{ - unsigned long flags; - - if (WARN_ON_ONCE(!ld)) - return; - - raw_spin_lock_irqsave(&tty_ldisc_lock, flags); - - /* unreleased reader reference(s) will cause this WARN */ - WARN_ON(!atomic_dec_and_test(&ld->users)); - - ld->ops->refcount--; - module_put(ld->ops->owner); - kfree(ld); - raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); -} - /** * tty_ldisc_enable - allow ldisc use * @tty: terminal to activate ldisc on -- cgit From be3971166d93a401105952672dab2eac6542cb57 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:44 -0400 Subject: tty: Remove redundant tty_wait_until_sent() tty_ioctl() already waits until sent. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 4e46c1721b9d..1afe192bef6a 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -625,15 +625,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) return 0; } - tty_unlock(tty); - /* - * Problem: What do we do if this blocks ? - * We could deadlock here - */ - - tty_wait_until_sent(tty, 0); - - tty_lock(tty); mutex_lock(&tty->ldisc_mutex); /* -- cgit From e7f3880cd9b98c5bf9391ae7acdec82b75403776 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:45 -0400 Subject: tty: Fix recursive deadlock in tty_perform_flush() tty_perform_flush() can deadlock when called while holding a line discipline reference. By definition, all ldisc drivers hold a ldisc reference, so calls originating from ldisc drivers must not block for a ldisc reference. The deadlock can occur when: CPU 0 | CPU 1 | tty_ldisc_ref(tty) | .... | tty_ldisc_ref_wait(tty) | | CPU 0 cannot progess because it cannot obtain an ldisc reference with the line discipline has been halted (thus no new references are granted). CPU 1 cannot progress because an outstanding ldisc reference has not been released. An in-tree call-tree audit of tty_perform_flush() [1] shows 5 ldisc drivers calling tty_perform_flush() indirectly via n_tty_ioctl_helper() and 2 ldisc drivers calling directly. A single tty driver safely uses the function. [1] Recursive usage: /* These functions are line discipline ioctls and thus * recursive wrt line discipline references */ tty_perform_flush() - ./drivers/tty/tty_ioctl.c n_tty_ioctl_helper() hci_uart_tty_ioctl(default) - drivers/bluetooth/hci_ldisc.c (N_HCI) n_hdlc_tty_ioctl(default) - drivers/tty/n_hdlc.c (N_HDLC) gsmld_ioctl(default) - drivers/tty/n_gsm.c (N_GSM0710) n_tty_ioctl(default) - drivers/tty/n_tty.c (N_TTY) gigaset_tty_ioctl(default) - drivers/isdn/gigaset/ser-gigaset.c (N_GIGASET_M101) ppp_synctty_ioctl(TCFLSH) - drivers/net/ppp/pps_synctty.c ppp_asynctty_ioctl(TCFLSH) - drivers/net/ppp/ppp_async.c Non-recursive use: tty_perform_flush() - drivers/tty/tty_ioctl.c ipw_ioctl(TCFLSH) - drivers/tty/ipwireless/tty.c /* This function is a tty i/o ioctl method, which * is invoked by tty_ioctl() */ Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/net/ppp/ppp_async.c | 2 +- drivers/net/ppp/ppp_synctty.c | 2 +- drivers/tty/tty_ioctl.c | 28 +++++++++++++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index a031f6b456b4..9c889e0303dd 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -314,7 +314,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, /* flush our buffers and the serial port's buffer */ if (arg == TCIOFLUSH || arg == TCOFLUSH) ppp_async_flush_output(ap); - err = tty_perform_flush(tty, arg); + err = n_tty_ioctl_helper(tty, file, cmd, arg); break; case FIONREAD: diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 1a12033d2efa..bdf3b13a71a8 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -355,7 +355,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file, /* flush our buffers and the serial port's buffer */ if (arg == TCIOFLUSH || arg == TCOFLUSH) ppp_sync_flush_output(ap); - err = tty_perform_flush(tty, arg); + err = n_tty_ioctl_helper(tty, file, cmd, arg); break; case FIONREAD: diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 28715e48b2f7..d119034877de 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -1122,14 +1122,12 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, } EXPORT_SYMBOL_GPL(tty_mode_ioctl); -int tty_perform_flush(struct tty_struct *tty, unsigned long arg) + +/* Caller guarantees ldisc reference is held */ +static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) { - struct tty_ldisc *ld; - int retval = tty_check_change(tty); - if (retval) - return retval; + struct tty_ldisc *ld = tty->ldisc; - ld = tty_ldisc_ref_wait(tty); switch (arg) { case TCIFLUSH: if (ld && ld->ops->flush_buffer) { @@ -1147,12 +1145,24 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) tty_driver_flush_buffer(tty); break; default: - tty_ldisc_deref(ld); return -EINVAL; } - tty_ldisc_deref(ld); return 0; } + +int tty_perform_flush(struct tty_struct *tty, unsigned long arg) +{ + struct tty_ldisc *ld; + int retval = tty_check_change(tty); + if (retval) + return retval; + + ld = tty_ldisc_ref_wait(tty); + retval = __tty_perform_flush(tty, arg); + if (ld) + tty_ldisc_deref(ld); + return retval; +} EXPORT_SYMBOL_GPL(tty_perform_flush); int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, @@ -1191,7 +1201,7 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, } return 0; case TCFLSH: - return tty_perform_flush(tty, arg); + return __tty_perform_flush(tty, arg); default: /* Try the mode commands */ return tty_mode_ioctl(tty, file, cmd, arg); -- cgit From 7bbe08d6b89fce09ae4e6a7ce62ccd3c279a31ce Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 14 Mar 2013 00:30:34 +0100 Subject: TTY: serial, stop accessing potential NULLs The following commits: * 6732c8bb8671acbdac6cdc93dd72ddd581dd5e25 (TTY: switch tty_schedule_flip) * 2e124b4a390ca85325fae75764bef92f0547fa25 (TTY: switch tty_flip_buffer_push) * 05c7cd39907184328f48d3e7899f9cdd653ad336 (TTY: switch tty_insert_flip_string) * 92a19f9cec9a80ad93c06e115822deb729e2c6ad (TTY: switch tty_insert_flip_char) * 227434f8986c3827a1faedd1feb437acd6285315 (TTY: switch tty_buffer_request_room to tty_port) introduced a potential NULL dereference to some drivers. In particular, when the device is used as a console, incoming bytes can kill the box. This is caused by removed checks for TTY against NULL. It happened because it was unclear to me why the checks were there. I assumed them superfluous because the interrupts were unbound or otherwise stopped. But this is not the case for consoles for these drivers, as was pointed out by David Miller. Now, this patch re-introduces the checks (at this point we check port->state, not the tty proper, as we do not care about tty pointers anymore). For both of the drivers, we place the check below the handling of break signal so that sysrq can actually work. (One needs to issue a break and then sysrq key within the following 5 seconds.) We do not change sc26xx, sunhv, and sunsu here because they behave the same as before. People having that hardware should fix the driver eventually, however. They always could unconditionally dereference tty in receive_chars, port->state in uart_handle_dcd_change, and up->port.state->port.tty. There is perhaps more to fix in all those drivers, but they are at least in a state they were before. Signed-off-by: Jiri Slaby Cc: "David S. Miller" Cc: Grant Likely Cc: Rob Herring Cc: sparclinux@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsab.c | 2 +- drivers/tty/serial/sunzilog.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 8de2213664e0..a422c8b55a47 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -203,7 +203,7 @@ receive_chars(struct uart_sunsab_port *up, flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch) || !port) continue; if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 27669ff3d446..813ef8eb8eff 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -388,7 +388,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, else if (r1 & CRC_ERR) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch) || !port) continue; if (up->port.ignore_status_mask == 0xff || -- cgit From b9a129f4813ef5dea8da4670e100f8ba89abebea Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:27:29 +0800 Subject: driver: tty: serial: remove cast for kzalloc return value remove cast for kzalloc return value. Signed-off-by: Zhang Yanfei Cc: Jiri Slaby Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/icom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index bc9e6b017b05..18ed5aebb166 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1415,8 +1415,7 @@ static int icom_alloc_adapter(struct icom_adapter struct icom_adapter *cur_adapter_entry; struct list_head *tmp; - icom_adapter = (struct icom_adapter *) - kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); + icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); if (!icom_adapter) { return -ENOMEM; -- cgit From 8358f6242dd447a4f694c7bc949bbfc842ca5db1 Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Tue, 12 Mar 2013 13:29:32 +0800 Subject: driver: tty: vt: remove cast for kmalloc return value remove cast for kmalloc return value. Signed-off-by: Zhang Yanfei Cc: Jiri Slaby Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/consolemap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 248381b30722..2978ca596a7f 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -194,8 +194,7 @@ static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int q = p->inverse_translations[i]; if (!q) { - q = p->inverse_translations[i] = (unsigned char *) - kmalloc(MAX_GLYPH, GFP_KERNEL); + q = p->inverse_translations[i] = kmalloc(MAX_GLYPH, GFP_KERNEL); if (!q) return; } memset(q, 0, MAX_GLYPH); -- cgit From d74e97699ad43ca5674eff20ba281ce5fd1bdae9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:34 -0700 Subject: staging:vt6655:80211hdr: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211hdr.h | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h index c4d2349260ea..0295a0444257 100644 --- a/drivers/staging/vt6655/80211hdr.h +++ b/drivers/staging/vt6655/80211hdr.h @@ -288,42 +288,42 @@ #define IEEE_ADDR_GROUP 0x01 typedef struct { - unsigned char abyAddr[6]; + unsigned char abyAddr[6]; } IEEE_ADDR, *PIEEE_ADDR; /* 802.11 Header Format */ typedef struct tagWLAN_80211HDR_A2 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; + unsigned short wFrameCtl; + unsigned short wDurationID; + unsigned char abyAddr1[WLAN_ADDR_LEN]; + unsigned char abyAddr2[WLAN_ADDR_LEN]; } __attribute__ ((__packed__)) WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; typedef struct tagWLAN_80211HDR_A3 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; + unsigned short wFrameCtl; + unsigned short wDurationID; + unsigned char abyAddr1[WLAN_ADDR_LEN]; + unsigned char abyAddr2[WLAN_ADDR_LEN]; + unsigned char abyAddr3[WLAN_ADDR_LEN]; + unsigned short wSeqCtl; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A3, *PWLAN_80211HDR_A3; typedef struct tagWLAN_80211HDR_A4 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[WLAN_ADDR_LEN]; + unsigned short wFrameCtl; + unsigned short wDurationID; + unsigned char abyAddr1[WLAN_ADDR_LEN]; + unsigned char abyAddr2[WLAN_ADDR_LEN]; + unsigned char abyAddr3[WLAN_ADDR_LEN]; + unsigned short wSeqCtl; + unsigned char abyAddr4[WLAN_ADDR_LEN]; } __attribute__ ((__packed__)) WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; @@ -331,9 +331,9 @@ WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; typedef union tagUWLAN_80211HDR { - WLAN_80211HDR_A2 sA2; - WLAN_80211HDR_A3 sA3; - WLAN_80211HDR_A4 sA4; + WLAN_80211HDR_A2 sA2; + WLAN_80211HDR_A3 sA3; + WLAN_80211HDR_A4 sA4; } UWLAN_80211HDR, *PUWLAN_80211HDR; -- cgit From ab4622cca5fb9667b8bacc36cd59e4b2eea3aacd Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:35 -0700 Subject: staging:vt6655:80211mgr: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 1122 ++++++++++++++++++------------------- drivers/staging/vt6655/80211mgr.h | 640 ++++++++++----------- 2 files changed, 881 insertions(+), 881 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index 1ed0f260b162..90686c438d6e 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -67,7 +67,7 @@ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Functions --------------------------*/ @@ -87,26 +87,26 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: * None. * --*/ + -*/ void vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame - ) + PWLAN_FR_BEACON pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_CAPINFO); + // Fixed Fields + pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_TS); + pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_BCN_INT); + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_CAPINFO); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID; + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID; - return; + return; } /*+ @@ -118,115 +118,115 @@ vMgrEncodeBeacon( * Return Value: * None. * --*/ + -*/ void vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame - ) + PWLAN_FR_BEACON pFrame +) { - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_BEACON_OFF_CAPINFO); - - // Information elements - pItem = (PWLAN_IE)((unsigned char *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) - + WLAN_BEACON_OFF_SSID); - while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ){ - - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - //pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; - break; - case WLAN_EID_TIM: - if (pFrame->pTIM == NULL) - pFrame->pTIM = (PWLAN_IE_TIM)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) { - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - } - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; - } - break; - - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: //7 - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: //32 - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: //37 - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: //40 - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID); - break; - - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } - - return; + PWLAN_IE pItem; + + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_TS); + pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_BCN_INT); + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_BEACON_OFF_CAPINFO); + + // Information elements + pItem = (PWLAN_IE)((unsigned char *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) + + WLAN_BEACON_OFF_SSID); + while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { + + switch (pItem->byElementID) { + case WLAN_EID_SSID: + if (pFrame->pSSID == NULL) + pFrame->pSSID = (PWLAN_IE_SSID)pItem; + break; + case WLAN_EID_SUPP_RATES: + if (pFrame->pSuppRates == NULL) + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + case WLAN_EID_FH_PARMS: + //pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; + break; + case WLAN_EID_DS_PARMS: + if (pFrame->pDSParms == NULL) + pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; + break; + case WLAN_EID_CF_PARMS: + if (pFrame->pCFParms == NULL) + pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; + break; + case WLAN_EID_IBSS_PARMS: + if (pFrame->pIBSSParms == NULL) + pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; + break; + case WLAN_EID_TIM: + if (pFrame->pTIM == NULL) + pFrame->pTIM = (PWLAN_IE_TIM)pItem; + break; + + case WLAN_EID_RSN: + if (pFrame->pRSN == NULL) { + pFrame->pRSN = (PWLAN_IE_RSN)pItem; + } + break; + case WLAN_EID_RSN_WPA: + if (pFrame->pRSNWPA == NULL) { + if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) + pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; + } + break; + + case WLAN_EID_ERP: + if (pFrame->pERP == NULL) + pFrame->pERP = (PWLAN_IE_ERP)pItem; + break; + case WLAN_EID_EXTSUPP_RATES: + if (pFrame->pExtSuppRates == NULL) + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + + case WLAN_EID_COUNTRY: //7 + if (pFrame->pIE_Country == NULL) + pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; + break; + + case WLAN_EID_PWR_CONSTRAINT: //32 + if (pFrame->pIE_PowerConstraint == NULL) + pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem; + break; + + case WLAN_EID_CH_SWITCH: //37 + if (pFrame->pIE_CHSW == NULL) + pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; + break; + + case WLAN_EID_QUIET: //40 + if (pFrame->pIE_Quiet == NULL) + pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; + break; + + case WLAN_EID_IBSS_DFS: + if (pFrame->pIE_IBSSDFS == NULL) + pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; + break; + + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID); + break; + + } + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + } + + return; } @@ -239,18 +239,18 @@ vMgrDecodeBeacon( * Return Value: * None. * --*/ + -*/ void vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame - ) + PWLAN_FR_IBSSATIM pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->len = WLAN_HDR_ADDR3_LEN; - return; + return; } @@ -263,16 +263,16 @@ vMgrEncodeIBSSATIM( * Return Value: * None. * --*/ + -*/ void vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame - ) + PWLAN_FR_IBSSATIM pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - return; + return; } @@ -285,22 +285,22 @@ vMgrDecodeIBSSATIM( * Return Value: * None. * --*/ + -*/ void vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame - ) + PWLAN_FR_DISASSOC pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_DISASSOC_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason)); + // Fixed Fields + pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_DISASSOC_OFF_REASON); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason)); - return; + return; } @@ -313,20 +313,20 @@ vMgrEncodeDisassociation( * Return Value: * None. * --*/ + -*/ void vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame - ) + PWLAN_FR_DISASSOC pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_DISASSOC_OFF_REASON); + // Fixed Fields + pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_DISASSOC_OFF_REASON); - return; + return; } /*+ @@ -338,22 +338,22 @@ vMgrDecodeDisassociation( * Return Value: * None. * --*/ + -*/ void vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame - ) + PWLAN_FR_ASSOCREQ pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_LISTEN_INT); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval)); - return; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCREQ_OFF_CAP_INFO); + pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCREQ_OFF_LISTEN_INT); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval)); + return; } @@ -366,61 +366,61 @@ vMgrEncodeAssocRequest( * Return Value: * None. * --*/ + -*/ void vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame - ) + PWLAN_FR_ASSOCREQ pFrame +) { - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_LISTEN_INT); - - // Information elements - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID){ - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) { - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - } - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; - } - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } - return; + PWLAN_IE pItem; + + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCREQ_OFF_CAP_INFO); + pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCREQ_OFF_LISTEN_INT); + + // Information elements + pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCREQ_OFF_SSID); + + while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { + switch (pItem->byElementID) { + case WLAN_EID_SSID: + if (pFrame->pSSID == NULL) + pFrame->pSSID = (PWLAN_IE_SSID)pItem; + break; + case WLAN_EID_SUPP_RATES: + if (pFrame->pSuppRates == NULL) + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + + case WLAN_EID_RSN: + if (pFrame->pRSN == NULL) { + pFrame->pRSN = (PWLAN_IE_RSN)pItem; + } + break; + case WLAN_EID_RSN_WPA: + if (pFrame->pRSNWPA == NULL) { + if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) + pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; + } + break; + case WLAN_EID_EXTSUPP_RATES: + if (pFrame->pExtSuppRates == NULL) + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n", + pItem->byElementID); + break; + } + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + } + return; } /*+ @@ -432,26 +432,26 @@ vMgrDecodeAssocRequest( * Return Value: * None. * --*/ + -*/ void vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame - ) + PWLAN_FR_ASSOCRESP pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_AID); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID - + sizeof(*(pFrame->pwAid)); - - return; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_CAP_INFO); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_STATUS); + pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_AID); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID + + sizeof(*(pFrame->pwAid)); + + return; } @@ -464,41 +464,41 @@ vMgrEncodeAssocResponse( * Return Value: * None. * --*/ + -*/ void vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame - ) + PWLAN_FR_ASSOCRESP pFrame +) { - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_AID); - - // Information elements - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem); - } - else { - pFrame->pExtSuppRates = NULL; - } - return; + PWLAN_IE pItem; + + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_CAP_INFO); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_STATUS); + pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_AID); + + // Information elements + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_ASSOCRESP_OFF_SUPP_RATES); + + pItem = (PWLAN_IE)(pFrame->pSuppRates); + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + + if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && + (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem); + } + else { + pFrame->pExtSuppRates = NULL; + } + return; } @@ -511,25 +511,25 @@ vMgrDecodeAssocResponse( * Return Value: * None. * --*/ + -*/ void vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame - ) + PWLAN_FR_REASSOCREQ pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_CURR_AP); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP)); - - return; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_CAP_INFO); + pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_LISTEN_INT); + pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_CURR_AP); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP)); + + return; } @@ -542,65 +542,65 @@ vMgrEncodeReassocRequest( * Return Value: * None. * --*/ + -*/ void vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame - ) + PWLAN_FR_REASSOCREQ pFrame +) { - PWLAN_IE pItem; - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_CURR_AP); - - // Information elements - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_SSID); - - while(((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - - switch (pItem->byElementID){ - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) { - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - } - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; - } - break; - - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } - return; + PWLAN_IE pItem; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_CAP_INFO); + pFrame->pwListenInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_LISTEN_INT); + pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_CURR_AP); + + // Information elements + pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCREQ_OFF_SSID); + + while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { + + switch (pItem->byElementID) { + case WLAN_EID_SSID: + if (pFrame->pSSID == NULL) + pFrame->pSSID = (PWLAN_IE_SSID)pItem; + break; + case WLAN_EID_SUPP_RATES: + if (pFrame->pSuppRates == NULL) + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + + case WLAN_EID_RSN: + if (pFrame->pRSN == NULL) { + pFrame->pRSN = (PWLAN_IE_RSN)pItem; + } + break; + case WLAN_EID_RSN_WPA: + if (pFrame->pRSNWPA == NULL) { + if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) + pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; + } + break; + + case WLAN_EID_EXTSUPP_RATES: + if (pFrame->pExtSuppRates == NULL) + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n", + pItem->byElementID); + break; + } + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + } + return; } @@ -614,17 +614,17 @@ vMgrDecodeReassocRequest( * Return Value: * None. * --*/ + -*/ void vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame - ) + PWLAN_FR_PROBEREQ pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; - return; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->len = WLAN_HDR_ADDR3_LEN; + return; } /*+ @@ -636,46 +636,46 @@ vMgrEncodeProbeRequest( * Return Value: * None. * --*/ + -*/ void vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame - ) + PWLAN_FR_PROBEREQ pFrame +) { - PWLAN_IE pItem; + PWLAN_IE pItem; - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Information elements - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))); + // Information elements + pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))); - while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ) { + while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; + switch (pItem->byElementID) { + case WLAN_EID_SSID: + if (pFrame->pSSID == NULL) + pFrame->pSSID = (PWLAN_IE_SSID)pItem; + break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; + case WLAN_EID_SUPP_RATES: + if (pFrame->pSuppRates == NULL) + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; + case WLAN_EID_EXTSUPP_RATES: + if (pFrame->pExtSuppRates == NULL) + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID); - break; - } + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID); + break; + } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } - return; + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + } + return; } @@ -688,28 +688,28 @@ vMgrDecodeProbeRequest( * Return Value: * None. * --*/ + -*/ void vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame - ) + PWLAN_FR_PROBERESP pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_CAP_INFO); + // Fixed Fields + pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_TS); + pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_BCN_INT); + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_CAP_INFO); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO + - sizeof(*(pFrame->pwCapInfo)); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO + + sizeof(*(pFrame->pwCapInfo)); - return; + return; } @@ -723,108 +723,108 @@ vMgrEncodeProbeResponse( * Return Value: * None. * --*/ + -*/ void vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame - ) + PWLAN_FR_PROBERESP pFrame +) { - PWLAN_IE pItem; - - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_CAP_INFO); - - // Information elements - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_SSID); - - while( ((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) ) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) { - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - } - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; - } - break; - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: //7 - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: //32 - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: //37 - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: //40 - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID); - break; - } - - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } - return; + PWLAN_IE pItem; + + + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_TS); + pFrame->pwBeaconInterval = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_BCN_INT); + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_CAP_INFO); + + // Information elements + pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_PROBERESP_OFF_SSID); + + while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { + switch (pItem->byElementID) { + case WLAN_EID_SSID: + if (pFrame->pSSID == NULL) + pFrame->pSSID = (PWLAN_IE_SSID)pItem; + break; + case WLAN_EID_SUPP_RATES: + if (pFrame->pSuppRates == NULL) + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + case WLAN_EID_FH_PARMS: + break; + case WLAN_EID_DS_PARMS: + if (pFrame->pDSParms == NULL) + pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; + break; + case WLAN_EID_CF_PARMS: + if (pFrame->pCFParms == NULL) + pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; + break; + case WLAN_EID_IBSS_PARMS: + if (pFrame->pIBSSParms == NULL) + pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; + break; + + case WLAN_EID_RSN: + if (pFrame->pRSN == NULL) { + pFrame->pRSN = (PWLAN_IE_RSN)pItem; + } + break; + case WLAN_EID_RSN_WPA: + if (pFrame->pRSNWPA == NULL) { + if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) + pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem; + } + break; + case WLAN_EID_ERP: + if (pFrame->pERP == NULL) + pFrame->pERP = (PWLAN_IE_ERP)pItem; + break; + case WLAN_EID_EXTSUPP_RATES: + if (pFrame->pExtSuppRates == NULL) + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + break; + + case WLAN_EID_COUNTRY: //7 + if (pFrame->pIE_Country == NULL) + pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; + break; + + case WLAN_EID_PWR_CONSTRAINT: //32 + if (pFrame->pIE_PowerConstraint == NULL) + pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem; + break; + + case WLAN_EID_CH_SWITCH: //37 + if (pFrame->pIE_CHSW == NULL) + pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; + break; + + case WLAN_EID_QUIET: //40 + if (pFrame->pIE_Quiet == NULL) + pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; + break; + + case WLAN_EID_IBSS_DFS: + if (pFrame->pIE_IBSSDFS == NULL) + pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; + break; + + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID); + break; + } + + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + } + return; } @@ -837,25 +837,25 @@ vMgrDecodeProbeResponse( * Return Value: * None. * --*/ + -*/ void vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame - ) + PWLAN_FR_AUTHEN pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_STATUS); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus)); - - return; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_AUTH_ALG); + pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_AUTH_SEQ); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_STATUS); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus)); + + return; } @@ -868,34 +868,34 @@ vMgrEncodeAuthen( * Return Value: * None. * --*/ + -*/ void vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame - ) + PWLAN_FR_AUTHEN pFrame +) { - PWLAN_IE pItem; + PWLAN_IE pItem; - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_STATUS); + // Fixed Fields + pFrame->pwAuthAlgorithm = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_AUTH_ALG); + pFrame->pwAuthSequence = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_AUTH_SEQ); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_STATUS); - // Information elements - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_CHALLENGE); + // Information elements + pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_AUTHEN_OFF_CHALLENGE); - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) { - pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem; - } + if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) { + pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem; + } - return; + return; } @@ -908,21 +908,21 @@ vMgrDecodeAuthen( * Return Value: * None. * --*/ + -*/ void vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame - ) + PWLAN_FR_DEAUTHEN pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_DEAUTHEN_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason)); + // Fixed Fields + pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_DEAUTHEN_OFF_REASON); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason)); - return; + return; } @@ -935,20 +935,20 @@ vMgrEncodeDeauthen( * Return Value: * None. * --*/ + -*/ void vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame - ) + PWLAN_FR_DEAUTHEN pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_DEAUTHEN_OFF_REASON); + // Fixed Fields + pFrame->pwReason = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_DEAUTHEN_OFF_REASON); - return; + return; } @@ -961,26 +961,26 @@ vMgrDecodeDeauthen( * Return Value: * None. * --*/ + -*/ void vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame - ) + PWLAN_FR_REASSOCRESP pFrame +) { - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_AID); + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_CAP_INFO); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_STATUS); + pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_AID); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid)); + pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid)); - return; + return; } @@ -993,36 +993,36 @@ vMgrEncodeReassocResponse( * Return Value: * None. * --*/ + -*/ void vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame - ) + PWLAN_FR_REASSOCRESP pFrame +) { - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - // Fixed Fields - pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_AID); - - //Information elements - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - } - return; + PWLAN_IE pItem; + + pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; + + // Fixed Fields + pFrame->pwCapInfo = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_CAP_INFO); + pFrame->pwStatus = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_STATUS); + pFrame->pwAid = (unsigned short *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_AID); + + //Information elements + pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + + WLAN_REASSOCRESP_OFF_SUPP_RATES); + + pItem = (PWLAN_IE)(pFrame->pSuppRates); + pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); + + if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && + (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { + pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; + } + return; } diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index 65780f28db41..8429b261c27b 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -230,29 +230,29 @@ #pragma pack(1) typedef struct tagWLAN_IE { - unsigned char byElementID; - unsigned char len; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; +} __attribute__ ((__packed__)) WLAN_IE, *PWLAN_IE; // Service Set Identity (SSID) #pragma pack(1) typedef struct tagWLAN_IE_SSID { - unsigned char byElementID; - unsigned char len; - unsigned char abySSID[1]; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char abySSID[1]; +} __attribute__ ((__packed__)) WLAN_IE_SSID, *PWLAN_IE_SSID; // Supported Rates #pragma pack(1) typedef struct tagWLAN_IE_SUPP_RATES { - unsigned char byElementID; - unsigned char len; - unsigned char abyRates[1]; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char abyRates[1]; +} __attribute__ ((__packed__)) WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; @@ -260,231 +260,231 @@ WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; // FH Parameter Set #pragma pack(1) typedef struct _WLAN_IE_FH_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wDwellTime; - unsigned char byHopSet; - unsigned char byHopPattern; - unsigned char byHopIndex; + unsigned char byElementID; + unsigned char len; + unsigned short wDwellTime; + unsigned char byHopSet; + unsigned char byHopPattern; + unsigned char byHopIndex; } WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS; // DS Parameter Set #pragma pack(1) typedef struct tagWLAN_IE_DS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCurrChannel; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char byCurrChannel; +} __attribute__ ((__packed__)) WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS; // CF Parameter Set #pragma pack(1) typedef struct tagWLAN_IE_CF_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCFPCount; - unsigned char byCFPPeriod; - unsigned short wCFPMaxDuration; - unsigned short wCFPDurRemaining; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char byCFPCount; + unsigned char byCFPPeriod; + unsigned short wCFPMaxDuration; + unsigned short wCFPDurRemaining; +} __attribute__ ((__packed__)) WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS; // TIM #pragma pack(1) typedef struct tagWLAN_IE_TIM { - unsigned char byElementID; - unsigned char len; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - unsigned char byBitMapCtl; - unsigned char byVirtBitMap[1]; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char byDTIMCount; + unsigned char byDTIMPeriod; + unsigned char byBitMapCtl; + unsigned char byVirtBitMap[1]; +} __attribute__ ((__packed__)) WLAN_IE_TIM, *PWLAN_IE_TIM; // IBSS Parameter Set #pragma pack(1) typedef struct tagWLAN_IE_IBSS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wATIMWindow; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned short wATIMWindow; +} __attribute__ ((__packed__)) WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; // Challenge Text #pragma pack(1) typedef struct tagWLAN_IE_CHALLENGE { - unsigned char byElementID; - unsigned char len; - unsigned char abyChallenge[1]; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char abyChallenge[1]; +} __attribute__ ((__packed__)) WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE; #pragma pack(1) typedef struct tagWLAN_IE_RSN_EXT { - unsigned char byElementID; - unsigned char len; - unsigned char abyOUI[4]; - unsigned short wVersion; - unsigned char abyMulticast[4]; - unsigned short wPKCount; - struct { - unsigned char abyOUI[4]; - } PKSList[1]; // the rest is variable so need to - // overlay ieauth structure + unsigned char byElementID; + unsigned char len; + unsigned char abyOUI[4]; + unsigned short wVersion; + unsigned char abyMulticast[4]; + unsigned short wPKCount; + struct { + unsigned char abyOUI[4]; + } PKSList[1]; // the rest is variable so need to + // overlay ieauth structure } WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT; #pragma pack(1) typedef struct tagWLAN_IE_RSN_AUTH { - unsigned short wAuthCount; - struct { - unsigned char abyOUI[4]; - } AuthKSList[1]; + unsigned short wAuthCount; + struct { + unsigned char abyOUI[4]; + } AuthKSList[1]; } WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH; // RSN Identity #pragma pack(1) typedef struct tagWLAN_IE_RSN { - unsigned char byElementID; - unsigned char len; - unsigned short wVersion; - unsigned char abyRSN[WLAN_MIN_ARRAY]; + unsigned char byElementID; + unsigned char len; + unsigned short wVersion; + unsigned char abyRSN[WLAN_MIN_ARRAY]; } WLAN_IE_RSN, *PWLAN_IE_RSN; // ERP #pragma pack(1) typedef struct tagWLAN_IE_ERP { - unsigned char byElementID; - unsigned char len; - unsigned char byContext; -}__attribute__ ((__packed__)) + unsigned char byElementID; + unsigned char len; + unsigned char byContext; +} __attribute__ ((__packed__)) WLAN_IE_ERP, *PWLAN_IE_ERP; #pragma pack(1) typedef struct _MEASEURE_REQ { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; + unsigned char byChannel; + unsigned char abyStartTime[8]; + unsigned char abyDuration[2]; } MEASEURE_REQ, *PMEASEURE_REQ, - MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC, - MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA, - MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI; + MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC, + MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA, + MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI; typedef struct _MEASEURE_REP_BASIC { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byMap; + unsigned char byChannel; + unsigned char abyStartTime[8]; + unsigned char abyDuration[2]; + unsigned char byMap; } MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC; typedef struct _MEASEURE_REP_CCA { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byCCABusyFraction; + unsigned char byChannel; + unsigned char abyStartTime[8]; + unsigned char abyDuration[2]; + unsigned char byCCABusyFraction; } MEASEURE_REP_CCA, *PMEASEURE_REP_CCA; typedef struct _MEASEURE_REP_RPI { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char abyRPIdensity[8]; + unsigned char byChannel; + unsigned char abyStartTime[8]; + unsigned char abyDuration[2]; + unsigned char abyRPIdensity[8]; } MEASEURE_REP_RPI, *PMEASEURE_REP_RPI; typedef union _MEASEURE_REP { - MEASEURE_REP_BASIC sBasic; - MEASEURE_REP_CCA sCCA; - MEASEURE_REP_RPI sRPI; + MEASEURE_REP_BASIC sBasic; + MEASEURE_REP_CCA sCCA; + MEASEURE_REP_RPI sRPI; } MEASEURE_REP, *PMEASEURE_REP; typedef struct _WLAN_IE_MEASURE_REQ { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REQ sReq; + unsigned char byElementID; + unsigned char len; + unsigned char byToken; + unsigned char byMode; + unsigned char byType; + MEASEURE_REQ sReq; } WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ; typedef struct _WLAN_IE_MEASURE_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REP sRep; + unsigned char byElementID; + unsigned char len; + unsigned char byToken; + unsigned char byMode; + unsigned char byType; + MEASEURE_REP sRep; } WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP; typedef struct _WLAN_IE_CH_SW { - unsigned char byElementID; - unsigned char len; - unsigned char byMode; - unsigned char byChannel; - unsigned char byCount; + unsigned char byElementID; + unsigned char len; + unsigned char byMode; + unsigned char byChannel; + unsigned char byCount; } WLAN_IE_CH_SW, *PWLAN_IE_CH_SW; typedef struct _WLAN_IE_QUIET { - unsigned char byElementID; - unsigned char len; - unsigned char byQuietCount; - unsigned char byQuietPeriod; - unsigned char abyQuietDuration[2]; - unsigned char abyQuietOffset[2]; + unsigned char byElementID; + unsigned char len; + unsigned char byQuietCount; + unsigned char byQuietPeriod; + unsigned char abyQuietDuration[2]; + unsigned char abyQuietOffset[2]; } WLAN_IE_QUIET, *PWLAN_IE_QUIET; typedef struct _WLAN_IE_COUNTRY { - unsigned char byElementID; - unsigned char len; - unsigned char abyCountryString[3]; - unsigned char abyCountryInfo[3]; + unsigned char byElementID; + unsigned char len; + unsigned char abyCountryString[3]; + unsigned char abyCountryInfo[3]; } WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY; typedef struct _WLAN_IE_PW_CONST { - unsigned char byElementID; - unsigned char len; - unsigned char byPower; + unsigned char byElementID; + unsigned char len; + unsigned char byPower; } WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST; typedef struct _WLAN_IE_PW_CAP { - unsigned char byElementID; - unsigned char len; - unsigned char byMinPower; - unsigned char byMaxPower; + unsigned char byElementID; + unsigned char len; + unsigned char byMinPower; + unsigned char byMaxPower; } WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP; typedef struct _WLAN_IE_SUPP_CH { - unsigned char byElementID; - unsigned char len; - unsigned char abyChannelTuple[2]; + unsigned char byElementID; + unsigned char len; + unsigned char abyChannelTuple[2]; } WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH; typedef struct _WLAN_IE_TPC_REQ { - unsigned char byElementID; - unsigned char len; + unsigned char byElementID; + unsigned char len; } WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ; typedef struct _WLAN_IE_TPC_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byTxPower; - unsigned char byLinkMargin; + unsigned char byElementID; + unsigned char len; + unsigned char byTxPower; + unsigned char byLinkMargin; } WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP; typedef struct _WLAN_IE_IBSS_DFS { - unsigned char byElementID; - unsigned char len; - unsigned char abyDFSOwner[6]; - unsigned char byDFSRecovery; - unsigned char abyChannelMap[2]; + unsigned char byElementID; + unsigned char len; + unsigned char abyDFSOwner[6]; + unsigned char byDFSRecovery; + unsigned char abyChannelMap[2]; } WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS; #pragma pack() @@ -495,41 +495,41 @@ typedef struct _WLAN_IE_IBSS_DFS { // prototype structure, all mgmt frame types will start with these members typedef struct tagWLAN_FR_MGMT { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; } WLAN_FR_MGMT, *PWLAN_FR_MGMT; // Beacon frame typedef struct tagWLAN_FR_BEACON { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - // fixed fields - PQWORD pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - /*-- info elements ----------*/ - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + // fixed fields + PQWORD pqwTimestamp; + unsigned short *pwBeaconInterval; + unsigned short *pwCapInfo; + /*-- info elements ----------*/ + PWLAN_IE_SSID pSSID; + PWLAN_IE_SUPP_RATES pSuppRates; // PWLAN_IE_FH_PARMS pFHParms; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_TIM pTIM; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; + PWLAN_IE_DS_PARMS pDSParms; + PWLAN_IE_CF_PARMS pCFParms; + PWLAN_IE_TIM pTIM; + PWLAN_IE_IBSS_PARMS pIBSSParms; + PWLAN_IE_RSN pRSN; + PWLAN_IE_RSN_EXT pRSNWPA; + PWLAN_IE_ERP pERP; + PWLAN_IE_SUPP_RATES pExtSuppRates; + PWLAN_IE_COUNTRY pIE_Country; + PWLAN_IE_PW_CONST pIE_PowerConstraint; + PWLAN_IE_CH_SW pIE_CHSW; + PWLAN_IE_IBSS_DFS pIE_IBSSDFS; + PWLAN_IE_QUIET pIE_Quiet; } WLAN_FR_BEACON, *PWLAN_FR_BEACON; @@ -537,178 +537,178 @@ typedef struct tagWLAN_FR_BEACON { // IBSS ATIM frame typedef struct tagWLAN_FR_IBSSATIM { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; - // fixed fields - // info elements - // this frame type has a null body + // fixed fields + // info elements + // this frame type has a null body } WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM; // Disassociation typedef struct tagWLAN_FR_DISASSOC { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwReason; - /*-- info elements ----------*/ + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwReason; + /*-- info elements ----------*/ } WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC; // Association Request typedef struct tagWLAN_FR_ASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - /*-- info elements ----------*/ - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_PW_CAP pCurrPowerCap; - PWLAN_IE_SUPP_CH pCurrSuppCh; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwCapInfo; + unsigned short *pwListenInterval; + /*-- info elements ----------*/ + PWLAN_IE_SSID pSSID; + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_RSN pRSN; + PWLAN_IE_RSN_EXT pRSNWPA; + PWLAN_IE_SUPP_RATES pExtSuppRates; + PWLAN_IE_PW_CAP pCurrPowerCap; + PWLAN_IE_SUPP_CH pCurrSuppCh; } WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ; // Association Response typedef struct tagWLAN_FR_ASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - /*-- info elements ----------*/ - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwCapInfo; + unsigned short *pwStatus; + unsigned short *pwAid; + /*-- info elements ----------*/ + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_SUPP_RATES pExtSuppRates; } WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP; // Reassociation Request typedef struct tagWLAN_FR_REASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - PIEEE_ADDR pAddrCurrAP; + /*-- fixed fields -----------*/ + unsigned short *pwCapInfo; + unsigned short *pwListenInterval; + PIEEE_ADDR pAddrCurrAP; - /*-- info elements ----------*/ - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; + /*-- info elements ----------*/ + PWLAN_IE_SSID pSSID; + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_RSN pRSN; + PWLAN_IE_RSN_EXT pRSNWPA; + PWLAN_IE_SUPP_RATES pExtSuppRates; } WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ; // Reassociation Response typedef struct tagWLAN_FR_REASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - /*-- info elements ----------*/ - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwCapInfo; + unsigned short *pwStatus; + unsigned short *pwAid; + /*-- info elements ----------*/ + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_SUPP_RATES pExtSuppRates; } WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP; // Probe Request typedef struct tagWLAN_FR_PROBEREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - /*-- info elements ----------*/ - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + PWLAN_IE_SSID pSSID; + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_SUPP_RATES pExtSuppRates; } WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ; // Probe Response typedef struct tagWLAN_FR_PROBERESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - PQWORD pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - /*-- info elements ----------*/ - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + PQWORD pqwTimestamp; + unsigned short *pwBeaconInterval; + unsigned short *pwCapInfo; + /*-- info elements ----------*/ + PWLAN_IE_SSID pSSID; + PWLAN_IE_SUPP_RATES pSuppRates; + PWLAN_IE_DS_PARMS pDSParms; + PWLAN_IE_CF_PARMS pCFParms; + PWLAN_IE_IBSS_PARMS pIBSSParms; + PWLAN_IE_RSN pRSN; + PWLAN_IE_RSN_EXT pRSNWPA; + PWLAN_IE_ERP pERP; + PWLAN_IE_SUPP_RATES pExtSuppRates; + PWLAN_IE_COUNTRY pIE_Country; + PWLAN_IE_PW_CONST pIE_PowerConstraint; + PWLAN_IE_CH_SW pIE_CHSW; + PWLAN_IE_IBSS_DFS pIE_IBSSDFS; + PWLAN_IE_QUIET pIE_Quiet; } WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP; // Authentication typedef struct tagWLAN_FR_AUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwAuthAlgorithm; - unsigned short *pwAuthSequence; - unsigned short *pwStatus; - /*-- info elements ----------*/ - PWLAN_IE_CHALLENGE pChallenge; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwAuthAlgorithm; + unsigned short *pwAuthSequence; + unsigned short *pwStatus; + /*-- info elements ----------*/ + PWLAN_IE_CHALLENGE pChallenge; } WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN; // Deauthenication typedef struct tagWLAN_FR_DEAUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - /*-- fixed fields -----------*/ - unsigned short *pwReason; + unsigned int uType; + unsigned int len; + unsigned char *pBuf; + PUWLAN_80211HDR pHdr; + /*-- fixed fields -----------*/ + unsigned short *pwReason; - /*-- info elements ----------*/ + /*-- info elements ----------*/ } WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN; @@ -716,112 +716,112 @@ typedef struct tagWLAN_FR_DEAUTHEN { void vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame - ); + PWLAN_FR_BEACON pFrame +); void vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame - ); + PWLAN_FR_BEACON pFrame +); void vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame - ); + PWLAN_FR_IBSSATIM pFrame +); void vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame - ); + PWLAN_FR_IBSSATIM pFrame +); void vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame - ); + PWLAN_FR_DISASSOC pFrame +); void vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame - ); + PWLAN_FR_DISASSOC pFrame +); void vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame - ); + PWLAN_FR_ASSOCREQ pFrame +); void vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame - ); + PWLAN_FR_ASSOCREQ pFrame +); void vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame - ); + PWLAN_FR_ASSOCRESP pFrame +); void vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame - ); + PWLAN_FR_ASSOCRESP pFrame +); void vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame - ); + PWLAN_FR_REASSOCREQ pFrame +); void vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame - ); + PWLAN_FR_REASSOCREQ pFrame +); void vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame - ); + PWLAN_FR_PROBEREQ pFrame +); void vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame - ); + PWLAN_FR_PROBEREQ pFrame +); void vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame - ); + PWLAN_FR_PROBERESP pFrame +); void vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame - ); + PWLAN_FR_PROBERESP pFrame +); void vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame - ); + PWLAN_FR_AUTHEN pFrame +); void vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame - ); + PWLAN_FR_AUTHEN pFrame +); void vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame - ); + PWLAN_FR_DEAUTHEN pFrame +); void vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame - ); + PWLAN_FR_DEAUTHEN pFrame +); void vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame - ); + PWLAN_FR_REASSOCRESP pFrame +); void vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame - ); + PWLAN_FR_REASSOCRESP pFrame +); #endif// __80211MGR_H__ -- cgit From b7760002277a32d427d0bf8167c45ecbbe1260d9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:36 -0700 Subject: staging:vt6655:IEEE11h: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/IEEE11h.c | 104 +++++++++++++++++++-------------------- drivers/staging/vt6655/IEEE11h.h | 6 +-- 2 files changed, 55 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c index cf7364d65263..841761eda38c 100644 --- a/drivers/staging/vt6655/IEEE11h.c +++ b/drivers/staging/vt6655/IEEE11h.c @@ -99,7 +99,7 @@ typedef struct _WLAN_FRAME_TPCREP { /*--------------------- Static Functions --------------------------*/ static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, - unsigned int uLength) + unsigned int uLength) { size_t uNumOfEIDs = 0; bool bResult = true; @@ -107,16 +107,16 @@ static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, if (uLength <= WLAN_A3FR_MAXLEN) memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength); uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, - sMSRReqEIDs))/ - (sizeof(WLAN_IE_MEASURE_REQ))); + sMSRReqEIDs))/ + (sizeof(WLAN_IE_MEASURE_REQ))); pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) - (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); + (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); pMgmt->uLengthOfRepEIDs = 0; bResult = CARDbStartMeasure(pMgmt->pAdapter, - ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, - uNumOfEIDs - ); + ((PWLAN_FRAME_MSRREQ) + (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, + uNumOfEIDs +); return bResult; } @@ -132,29 +132,29 @@ static bool s_bRxTPCReq(PSMgmtObject pMgmt, pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + -sizeof(STxMgmtPacket)); + sizeof(STxMgmtPacket)); pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + -sizeof(STxMgmtPacket)); + sizeof(STxMgmtPacket)); pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) - ); + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) +); memcpy(pFrame->Header.abyAddr1, - pTPCReq->Header.abyAddr2, - WLAN_ADDR_LEN); + pTPCReq->Header.abyAddr2, + WLAN_ADDR_LEN); memcpy(pFrame->Header.abyAddr2, - CARDpGetCurrentAddress(pMgmt->pAdapter), - WLAN_ADDR_LEN); + CARDpGetCurrentAddress(pMgmt->pAdapter), + WLAN_ADDR_LEN); memcpy(pFrame->Header.abyAddr3, - pMgmt->abyCurrBSSID, - WLAN_BSSID_LEN); + pMgmt->abyCurrBSSID, + WLAN_BSSID_LEN); pFrame->byCategory = 0; pFrame->byAction = 3; pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) -(pMgmt->abyCurrentMSRReq))->byDialogToken; + (pMgmt->abyCurrentMSRReq))->byDialogToken; pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP; pFrame->sTPCRepEIDs.len = 2; @@ -185,16 +185,16 @@ sizeof(STxMgmtPacket)); default: pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI; break; -} + } pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP); pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - -WLAN_HDR_ADDR3_LEN; + WLAN_HDR_ADDR3_LEN; if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) return false; return true; /* return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, -sizeof(WLAN_FRAME_TPCREP))); */ + sizeof(WLAN_FRAME_TPCREP))); */ } @@ -218,7 +218,7 @@ sizeof(WLAN_FRAME_TPCREP))); */ * * Return Value: None. * --*/ + -*/ bool IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket) { @@ -233,54 +233,54 @@ IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket) return false; pAction = (PWLAN_FRAME_ACTION) -(((PSRxMgmtPacket)pRxPacket)->p80211Header); + (((PSRxMgmtPacket)pRxPacket)->p80211Header); if (pAction->byCategory == 0) { switch (pAction->byAction) { case ACTION_MSRREQ: return s_bRxMSRReq(pMgmt, - (PWLAN_FRAME_MSRREQ) - pAction, - uLength); + (PWLAN_FRAME_MSRREQ) + pAction, + uLength); break; case ACTION_MSRREP: break; case ACTION_TPCREQ: return s_bRxTPCReq(pMgmt, - (PWLAN_FRAME_TPCREQ) pAction, - ((PSRxMgmtPacket)pRxPacket)->byRxRate, - (unsigned char) - ((PSRxMgmtPacket)pRxPacket)->uRSSI); + (PWLAN_FRAME_TPCREQ) pAction, + ((PSRxMgmtPacket)pRxPacket)->byRxRate, + (unsigned char) + ((PSRxMgmtPacket)pRxPacket)->uRSSI); break; case ACTION_TPCREP: break; case ACTION_CHSW: pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars); if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) - && (pChannelSwitch->len == 3)) { + && (pChannelSwitch->len == 3)) { /* valid element id */ CARDbChannelSwitch(pMgmt->pAdapter, - pChannelSwitch->byMode, - get_channel_mapping(pMgmt->pAdapter, - pChannelSwitch->byChannel, - pMgmt->eCurrentPHYMode), - pChannelSwitch->byCount); + pChannelSwitch->byMode, + get_channel_mapping(pMgmt->pAdapter, + pChannelSwitch->byChannel, + pMgmt->eCurrentPHYMode), + pChannelSwitch->byCount); } break; default: DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO"Unknown Action = %d\n", + KERN_INFO "Unknown Action = %d\n", pAction->byAction); break; } } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", -pAction->byCategory); - pAction->byCategory |= 0x80; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown Category = %d\n", + pAction->byCategory); + pAction->byCategory |= 0x80; - /*return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, -uLength));*/ - return true; + /*return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, + uLength));*/ + return true; } return true; } @@ -290,29 +290,29 @@ bool IEEE11hbMSRRepTx(void *pMgmtHandle) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) -(pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); + (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); size_t uLength = 0; PSTxMgmtPacket pTxPacket = NULL; pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + -sizeof(STxMgmtPacket)); + sizeof(STxMgmtPacket)); pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) - ); + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) +); memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); + (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); memcpy(pMSRRep->Header.abyAddr2, - CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); + CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); pMSRRep->byCategory = 0; pMSRRep->byAction = 1; pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->byDialogToken; + (pMgmt->abyCurrentMSRReq))->byDialogToken; uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs); @@ -323,7 +323,7 @@ sizeof(STxMgmtPacket)); return false; return true; /* return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, -uLength)); */ + uLength)); */ } diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h index 542340b96e38..8819fa1563b7 100644 --- a/drivers/staging/vt6655/IEEE11h.h +++ b/drivers/staging/vt6655/IEEE11h.h @@ -45,8 +45,8 @@ /*--------------------- Export Functions --------------------------*/ -bool IEEE11hbMSRRepTx ( - void *pMgmtHandle - ); +bool IEEE11hbMSRRepTx( + void *pMgmtHandle +); #endif // __IEEE11h_H__ -- cgit From 659b4d97fff5c9acb8596d85777ae0023e2539b8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:37 -0700 Subject: staging:vt6655:aes_ccmp: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/aes_ccmp.c | 566 +++++++++++++++++++------------------- 1 file changed, 283 insertions(+), 283 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c index e30168f2da2f..77aece56c601 100644 --- a/drivers/staging/vt6655/aes_ccmp.c +++ b/drivers/staging/vt6655/aes_ccmp.c @@ -48,60 +48,60 @@ unsigned char sbox_table[256] = { -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; unsigned char dot2_table[256] = { -0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, -0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, -0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, -0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, -0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, -0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, -0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, -0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, -0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, -0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, -0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, -0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, -0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, -0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, -0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, -0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 }; unsigned char dot3_table[256] = { -0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, -0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, -0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, -0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, -0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, -0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, -0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, -0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, -0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, -0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, -0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, -0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, -0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, -0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, -0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, -0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a }; /*--------------------- Static Functions --------------------------*/ @@ -112,120 +112,120 @@ unsigned char dot3_table[256] = { void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) { -unsigned long *dwPtrA = (unsigned long *) a; -unsigned long *dwPtrB = (unsigned long *) b; -unsigned long *dwPtrOut =(unsigned long *) out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + unsigned long *dwPtrA = (unsigned long *)a; + unsigned long *dwPtrB = (unsigned long *)b; + unsigned long *dwPtrOut = (unsigned long *)out; + + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } void xor_32(unsigned char *a, unsigned char *b, unsigned char *out) { -unsigned long *dwPtrA = (unsigned long *) a; -unsigned long *dwPtrB = (unsigned long *) b; -unsigned long *dwPtrOut =(unsigned long *) out; + unsigned long *dwPtrA = (unsigned long *)a; + unsigned long *dwPtrB = (unsigned long *)b; + unsigned long *dwPtrOut = (unsigned long *)out; - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } void AddRoundKey(unsigned char *key, int round) { -unsigned char sbox_key[4]; -unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + unsigned char sbox_key[4]; + unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - sbox_key[0] = sbox_table[key[13]]; - sbox_key[1] = sbox_table[key[14]]; - sbox_key[2] = sbox_table[key[15]]; - sbox_key[3] = sbox_table[key[12]]; + sbox_key[0] = sbox_table[key[13]]; + sbox_key[1] = sbox_table[key[14]]; + sbox_key[2] = sbox_table[key[15]]; + sbox_key[3] = sbox_table[key[12]]; - key[0] = key[0] ^ rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon_table[round]; + xor_32(&key[0], sbox_key, &key[0]); - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); } void SubBytes(unsigned char *in, unsigned char *out) { -int i; + int i; - for (i=0; i< 16; i++) - { - out[i] = sbox_table[in[i]]; - } + for (i = 0; i < 16; i++) + { + out[i] = sbox_table[in[i]]; + } } void ShiftRows(unsigned char *in, unsigned char *out) { - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; } void MixColumns(unsigned char *in, unsigned char *out) { - out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; - out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; - out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; - out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; + out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; + out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; + out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; + out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; } void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext) { -int i; -int round; -unsigned char TmpdataA[16]; -unsigned char TmpdataB[16]; -unsigned char abyRoundKey[16]; - - for(i=0; i<16; i++) - abyRoundKey[i] = key[i]; - - for (round = 0; round < 11; round++) - { - if (round == 0) - { - xor_128(abyRoundKey, data, ciphertext); - AddRoundKey(abyRoundKey, round); - } - else if (round == 10) - { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - xor_128(TmpdataB, abyRoundKey, ciphertext); - } - else // round 1 ~ 9 - { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - MixColumns(&TmpdataB[0], &TmpdataA[0]); - MixColumns(&TmpdataB[4], &TmpdataA[4]); - MixColumns(&TmpdataB[8], &TmpdataA[8]); - MixColumns(&TmpdataB[12], &TmpdataA[12]); - xor_128(TmpdataA, abyRoundKey, ciphertext); - AddRoundKey(abyRoundKey, round); - } - } + int i; + int round; + unsigned char TmpdataA[16]; + unsigned char TmpdataB[16]; + unsigned char abyRoundKey[16]; + + for (i = 0; i < 16; i++) + abyRoundKey[i] = key[i]; + + for (round = 0; round < 11; round++) + { + if (round == 0) + { + xor_128(abyRoundKey, data, ciphertext); + AddRoundKey(abyRoundKey, round); + } + else if (round == 10) + { + SubBytes(ciphertext, TmpdataA); + ShiftRows(TmpdataA, TmpdataB); + xor_128(TmpdataB, abyRoundKey, ciphertext); + } + else // round 1 ~ 9 + { + SubBytes(ciphertext, TmpdataA); + ShiftRows(TmpdataA, TmpdataB); + MixColumns(&TmpdataB[0], &TmpdataA[0]); + MixColumns(&TmpdataB[4], &TmpdataA[4]); + MixColumns(&TmpdataB[8], &TmpdataA[8]); + MixColumns(&TmpdataB[12], &TmpdataA[12]); + xor_128(TmpdataA, abyRoundKey, ciphertext); + AddRoundKey(abyRoundKey, round); + } + } } @@ -245,158 +245,158 @@ unsigned char abyRoundKey[16]; */ bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize) { -unsigned char abyNonce[13]; -unsigned char MIC_IV[16]; -unsigned char MIC_HDR1[16]; -unsigned char MIC_HDR2[16]; -unsigned char abyMIC[16]; -unsigned char abyCTRPLD[16]; -unsigned char abyTmp[16]; -unsigned char abyPlainText[16]; -unsigned char abyLastCipher[16]; - -PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; -unsigned char *pbyIV; -unsigned char *pbyPayload; -unsigned short wHLen = 22; -unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC -bool bA4 = false; -unsigned char byTmp; -unsigned short wCnt; -int ii,jj,kk; - - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) { - bA4 = true; - pbyIV += 6; // 6 is 802.11 address4 - wHLen += 6; - wPayloadSize -= 6; - } - pbyPayload = pbyIV + 8; //IV-length - - abyNonce[0] = 0x00; //now is 0, if Qos here will be priority - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); - abyNonce[7] = pbyIV[7]; - abyNonce[8] = pbyIV[6]; - abyNonce[9] = pbyIV[5]; - abyNonce[10] = pbyIV[4]; - abyNonce[11] = pbyIV[1]; - abyNonce[12] = pbyIV[0]; - - //MIC_IV - MIC_IV[0] = 0x59; - memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); - MIC_IV[14] = (unsigned char)(wPayloadSize >> 8); - MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff); - - //MIC_HDR1 - MIC_HDR1[0] = (unsigned char)(wHLen >> 8); - MIC_HDR1[1] = (unsigned char)(wHLen & 0xff); - byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff); - MIC_HDR1[2] = byTmp & 0x8f; - byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8); - byTmp &= 0x87; - MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); - - //MIC_HDR2 - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); - byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff); - MIC_HDR2[6] = byTmp & 0x0f; - MIC_HDR2[7] = 0; - if ( bA4 ) { - memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); - } else { - MIC_HDR2[8] = 0x00; - MIC_HDR2[9] = 0x00; - MIC_HDR2[10] = 0x00; - MIC_HDR2[11] = 0x00; - MIC_HDR2[12] = 0x00; - MIC_HDR2[13] = 0x00; - } - MIC_HDR2[14] = 0x00; - MIC_HDR2[15] = 0x00; - - //CCMP - AESv128(pbyRxKey,MIC_IV,abyMIC); - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - wCnt = 1; - abyCTRPLD[0] = 0x01; - memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); - - for(jj=wPayloadSize; jj>16; jj=jj-16) { - - abyCTRPLD[14] = (unsigned char) (wCnt >> 8); - abyCTRPLD[15] = (unsigned char) (wCnt & 0xff); - - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - - for ( kk=0; kk<16; kk++ ) { - abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; - } - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - memcpy(pbyPayload, abyPlainText, 16); - wCnt++; - pbyPayload += 16; - } //for wPayloadSize - - //last payload - memcpy(&(abyLastCipher[0]), pbyPayload, jj); - for ( ii=jj; ii<16; ii++ ) { - abyLastCipher[ii] = 0x00; - } - - abyCTRPLD[14] = (unsigned char) (wCnt >> 8); - abyCTRPLD[15] = (unsigned char) (wCnt & 0xff); - - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - for ( kk=0; kk<16; kk++ ) { - abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; - } - memcpy(pbyPayload, abyPlainText, jj); - pbyPayload += jj; - - //for MIC calculation - for ( ii=jj; ii<16; ii++ ) { - abyPlainText[ii] = 0x00; - } - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - //=>above is the calculate MIC - //-------------------------------------------- - - wCnt = 0; - abyCTRPLD[14] = (unsigned char) (wCnt >> 8); - abyCTRPLD[15] = (unsigned char) (wCnt & 0xff); - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - for ( kk=0; kk<8; kk++ ) { - abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; - } - //=>above is the dec-MIC from packet - //-------------------------------------------- - - if ( !memcmp(abyMIC,abyTmp,8) ) { - return true; - } else { - return false; - } + unsigned char abyNonce[13]; + unsigned char MIC_IV[16]; + unsigned char MIC_HDR1[16]; + unsigned char MIC_HDR2[16]; + unsigned char abyMIC[16]; + unsigned char abyCTRPLD[16]; + unsigned char abyTmp[16]; + unsigned char abyPlainText[16]; + unsigned char abyLastCipher[16]; + + PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; + unsigned char *pbyIV; + unsigned char *pbyPayload; + unsigned short wHLen = 22; + unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC + bool bA4 = false; + unsigned char byTmp; + unsigned short wCnt; + int ii, jj, kk; + + + pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; + if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && + WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { + bA4 = true; + pbyIV += 6; // 6 is 802.11 address4 + wHLen += 6; + wPayloadSize -= 6; + } + pbyPayload = pbyIV + 8; //IV-length + + abyNonce[0] = 0x00; //now is 0, if Qos here will be priority + memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); + abyNonce[7] = pbyIV[7]; + abyNonce[8] = pbyIV[6]; + abyNonce[9] = pbyIV[5]; + abyNonce[10] = pbyIV[4]; + abyNonce[11] = pbyIV[1]; + abyNonce[12] = pbyIV[0]; + + //MIC_IV + MIC_IV[0] = 0x59; + memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); + MIC_IV[14] = (unsigned char)(wPayloadSize >> 8); + MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff); + + //MIC_HDR1 + MIC_HDR1[0] = (unsigned char)(wHLen >> 8); + MIC_HDR1[1] = (unsigned char)(wHLen & 0xff); + byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff); + MIC_HDR1[2] = byTmp & 0x8f; + byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8); + byTmp &= 0x87; + MIC_HDR1[3] = byTmp | 0x40; + memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); + memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); + + //MIC_HDR2 + memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); + byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff); + MIC_HDR2[6] = byTmp & 0x0f; + MIC_HDR2[7] = 0; + if (bA4) { + memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); + } else { + MIC_HDR2[8] = 0x00; + MIC_HDR2[9] = 0x00; + MIC_HDR2[10] = 0x00; + MIC_HDR2[11] = 0x00; + MIC_HDR2[12] = 0x00; + MIC_HDR2[13] = 0x00; + } + MIC_HDR2[14] = 0x00; + MIC_HDR2[15] = 0x00; + + //CCMP + AESv128(pbyRxKey, MIC_IV, abyMIC); + for (kk = 0; kk < 16; kk++) { + abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; + } + AESv128(pbyRxKey, abyTmp, abyMIC); + for (kk = 0; kk < 16; kk++) { + abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; + } + AESv128(pbyRxKey, abyTmp, abyMIC); + + wCnt = 1; + abyCTRPLD[0] = 0x01; + memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); + + for (jj = wPayloadSize; jj > 16; jj = jj - 16) { + + abyCTRPLD[14] = (unsigned char)(wCnt >> 8); + abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); + + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + + for (kk = 0; kk < 16; kk++) { + abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; + } + for (kk = 0; kk < 16; kk++) { + abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; + } + AESv128(pbyRxKey, abyTmp, abyMIC); + + memcpy(pbyPayload, abyPlainText, 16); + wCnt++; + pbyPayload += 16; + } //for wPayloadSize + + //last payload + memcpy(&(abyLastCipher[0]), pbyPayload, jj); + for (ii = jj; ii < 16; ii++) { + abyLastCipher[ii] = 0x00; + } + + abyCTRPLD[14] = (unsigned char)(wCnt >> 8); + abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); + + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + for (kk = 0; kk < 16; kk++) { + abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; + } + memcpy(pbyPayload, abyPlainText, jj); + pbyPayload += jj; + + //for MIC calculation + for (ii = jj; ii < 16; ii++) { + abyPlainText[ii] = 0x00; + } + for (kk = 0; kk < 16; kk++) { + abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; + } + AESv128(pbyRxKey, abyTmp, abyMIC); + + //=>above is the calculate MIC + //-------------------------------------------- + + wCnt = 0; + abyCTRPLD[14] = (unsigned char)(wCnt >> 8); + abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + for (kk = 0; kk < 8; kk++) { + abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; + } + //=>above is the dec-MIC from packet + //-------------------------------------------- + + if (!memcmp(abyMIC, abyTmp, 8)) { + return true; + } else { + return false; + } } -- cgit From 375293671a130f212f92e6524fae399988df263c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:38 -0700 Subject: staging:vt6655:baseband: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 4810 ++++++++++++++++++------------------- drivers/staging/vt6655/baseband.h | 56 +- 2 files changed, 2433 insertions(+), 2433 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 8d2c6a789ab2..6f33e94dc16e 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -58,7 +58,7 @@ /*--------------------- Static Definitions -------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ @@ -78,1174 +78,1174 @@ static int msglevel =MSG_LEVEL_INFO; #define CB_VT3253_INIT_FOR_RFMD 446 unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = { - {0x00, 0x30}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x00}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x70}, - {0x09, 0x45}, - {0x0a, 0x2a}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x01}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x9d}, - {0x1c, 0x05}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0xa8}, - {0x2e, 0x1a}, - {0x2f, 0x0c}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x00}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x0d}, - {0x3e, 0x51}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x06}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x08}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x80}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x14}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0x44}, - {0x61, 0x04}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x04}, - {0x67, 0xb7}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x0b}, - {0x81, 0x00}, - {0x82, 0x3c}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x08}, - {0x8b, 0xa6}, - {0x8c, 0x84}, - {0x8d, 0x47}, - {0x8e, 0xbb}, - {0x8f, 0x02}, - {0x90, 0x21}, - {0x91, 0x0c}, - {0x92, 0x04}, - {0x93, 0x22}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x04}, - {0xa8, 0x10}, - {0xa9, 0x00}, - {0xaa, 0x8f}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x80}, - {0xb0, 0x38}, - {0xb1, 0x00}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0xee}, - {0xb5, 0xff}, - {0xb6, 0x10}, - {0xb7, 0x00}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x00}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x10}, - {0xc2, 0x18}, - {0xc3, 0x20}, - {0xc4, 0x10}, - {0xc5, 0x00}, - {0xc6, 0x22}, - {0xc7, 0x14}, - {0xc8, 0x0f}, - {0xc9, 0x08}, - {0xca, 0xa4}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x20}, - {0xcf, 0x00}, - {0xd0, 0x00}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x33}, - {0xd6, 0x70}, - {0xd7, 0x01}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0x00}, - {0xe2, 0xcc}, - {0xe3, 0x04}, - {0xe4, 0x08}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x0e}, - {0xe8, 0x88}, - {0xe9, 0xd4}, - {0xea, 0x05}, - {0xeb, 0xf0}, - {0xec, 0x79}, - {0xed, 0x0f}, - {0xee, 0x04}, - {0xef, 0x04}, - {0xf0, 0x00}, - {0xf1, 0x00}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xF0, 0x00}, - {0xF1, 0xF8}, - {0xF0, 0x80}, - {0xF0, 0x00}, - {0xF1, 0xF4}, - {0xF0, 0x81}, - {0xF0, 0x01}, - {0xF1, 0xF0}, - {0xF0, 0x82}, - {0xF0, 0x02}, - {0xF1, 0xEC}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0xE8}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0xE4}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0xE0}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0xDC}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0xD8}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0xD4}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0xD0}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0xCC}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0xC8}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0xC4}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0xC0}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0xBC}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0xB8}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0xB4}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0xB0}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0xAC}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0xA8}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0xA4}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0xA0}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x9C}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x98}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x94}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x90}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x8C}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x88}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x84}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x80}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x7C}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x78}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x74}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x70}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x6C}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x68}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x64}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x60}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x5C}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x58}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x54}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x50}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x4C}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x48}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x44}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x40}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x3C}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x38}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x34}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x30}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x2C}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x28}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x24}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x20}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x1C}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x18}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x14}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x10}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x0C}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x08}, - {0xF0, 0x00}, - {0xF0, 0x3C}, - {0xF1, 0x04}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x00}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x00}, - {0xF0, 0xBF}, - {0xF0, 0x3F}, - {0xF1, 0x00}, - {0xF0, 0xC0}, - {0xF0, 0x00}, + {0x00, 0x30}, + {0x01, 0x00}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x00}, + {0x05, 0x00}, + {0x06, 0x00}, + {0x07, 0x00}, + {0x08, 0x70}, + {0x09, 0x45}, + {0x0a, 0x2a}, + {0x0b, 0x76}, + {0x0c, 0x00}, + {0x0d, 0x01}, + {0x0e, 0x80}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x9d}, + {0x1c, 0x05}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x4a}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0xa8}, + {0x2e, 0x1a}, + {0x2f, 0x0c}, + {0x30, 0x26}, + {0x31, 0x5b}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0xaa}, + {0x37, 0xaa}, + {0x38, 0xff}, + {0x39, 0xff}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x0d}, + {0x3e, 0x51}, + {0x3f, 0x04}, + {0x40, 0x00}, + {0x41, 0x08}, + {0x42, 0x00}, + {0x43, 0x08}, + {0x44, 0x06}, + {0x45, 0x14}, + {0x46, 0x05}, + {0x47, 0x08}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x09}, + {0x4d, 0x80}, + {0x4e, 0x00}, + {0x4f, 0xc5}, + {0x50, 0x14}, + {0x51, 0x19}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0xb0}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x44}, + {0x61, 0x04}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x04}, + {0x67, 0xb7}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x03}, + {0x6e, 0x01}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x80, 0x0b}, + {0x81, 0x00}, + {0x82, 0x3c}, + {0x83, 0x00}, + {0x84, 0x00}, + {0x85, 0x00}, + {0x86, 0x00}, + {0x87, 0x00}, + {0x88, 0x08}, + {0x89, 0x00}, + {0x8a, 0x08}, + {0x8b, 0xa6}, + {0x8c, 0x84}, + {0x8d, 0x47}, + {0x8e, 0xbb}, + {0x8f, 0x02}, + {0x90, 0x21}, + {0x91, 0x0c}, + {0x92, 0x04}, + {0x93, 0x22}, + {0x94, 0x00}, + {0x95, 0x00}, + {0x96, 0x00}, + {0x97, 0xeb}, + {0x98, 0x00}, + {0x99, 0x00}, + {0x9a, 0x00}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x00}, + {0x9e, 0x00}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x00}, + {0xa2, 0x00}, + {0xa3, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x10}, + {0xa7, 0x04}, + {0xa8, 0x10}, + {0xa9, 0x00}, + {0xaa, 0x8f}, + {0xab, 0x00}, + {0xac, 0x00}, + {0xad, 0x00}, + {0xae, 0x00}, + {0xaf, 0x80}, + {0xb0, 0x38}, + {0xb1, 0x00}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0xee}, + {0xb5, 0xff}, + {0xb6, 0x10}, + {0xb7, 0x00}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x03}, + {0xbc, 0x00}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc0, 0x10}, + {0xc1, 0x10}, + {0xc2, 0x18}, + {0xc3, 0x20}, + {0xc4, 0x10}, + {0xc5, 0x00}, + {0xc6, 0x22}, + {0xc7, 0x14}, + {0xc8, 0x0f}, + {0xc9, 0x08}, + {0xca, 0xa4}, + {0xcb, 0xa7}, + {0xcc, 0x3c}, + {0xcd, 0x10}, + {0xce, 0x20}, + {0xcf, 0x00}, + {0xd0, 0x00}, + {0xd1, 0x10}, + {0xd2, 0x00}, + {0xd3, 0x00}, + {0xd4, 0x10}, + {0xd5, 0x33}, + {0xd6, 0x70}, + {0xd7, 0x01}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xdc, 0x00}, + {0xdd, 0x00}, + {0xde, 0x00}, + {0xdf, 0x00}, + {0xe0, 0x00}, + {0xe1, 0x00}, + {0xe2, 0xcc}, + {0xe3, 0x04}, + {0xe4, 0x08}, + {0xe5, 0x10}, + {0xe6, 0x00}, + {0xe7, 0x0e}, + {0xe8, 0x88}, + {0xe9, 0xd4}, + {0xea, 0x05}, + {0xeb, 0xf0}, + {0xec, 0x79}, + {0xed, 0x0f}, + {0xee, 0x04}, + {0xef, 0x04}, + {0xf0, 0x00}, + {0xf1, 0x00}, + {0xf2, 0x00}, + {0xf3, 0x00}, + {0xf4, 0x00}, + {0xf5, 0x00}, + {0xf6, 0x00}, + {0xf7, 0x00}, + {0xf8, 0x00}, + {0xf9, 0x00}, + {0xF0, 0x00}, + {0xF1, 0xF8}, + {0xF0, 0x80}, + {0xF0, 0x00}, + {0xF1, 0xF4}, + {0xF0, 0x81}, + {0xF0, 0x01}, + {0xF1, 0xF0}, + {0xF0, 0x82}, + {0xF0, 0x02}, + {0xF1, 0xEC}, + {0xF0, 0x83}, + {0xF0, 0x03}, + {0xF1, 0xE8}, + {0xF0, 0x84}, + {0xF0, 0x04}, + {0xF1, 0xE4}, + {0xF0, 0x85}, + {0xF0, 0x05}, + {0xF1, 0xE0}, + {0xF0, 0x86}, + {0xF0, 0x06}, + {0xF1, 0xDC}, + {0xF0, 0x87}, + {0xF0, 0x07}, + {0xF1, 0xD8}, + {0xF0, 0x88}, + {0xF0, 0x08}, + {0xF1, 0xD4}, + {0xF0, 0x89}, + {0xF0, 0x09}, + {0xF1, 0xD0}, + {0xF0, 0x8A}, + {0xF0, 0x0A}, + {0xF1, 0xCC}, + {0xF0, 0x8B}, + {0xF0, 0x0B}, + {0xF1, 0xC8}, + {0xF0, 0x8C}, + {0xF0, 0x0C}, + {0xF1, 0xC4}, + {0xF0, 0x8D}, + {0xF0, 0x0D}, + {0xF1, 0xC0}, + {0xF0, 0x8E}, + {0xF0, 0x0E}, + {0xF1, 0xBC}, + {0xF0, 0x8F}, + {0xF0, 0x0F}, + {0xF1, 0xB8}, + {0xF0, 0x90}, + {0xF0, 0x10}, + {0xF1, 0xB4}, + {0xF0, 0x91}, + {0xF0, 0x11}, + {0xF1, 0xB0}, + {0xF0, 0x92}, + {0xF0, 0x12}, + {0xF1, 0xAC}, + {0xF0, 0x93}, + {0xF0, 0x13}, + {0xF1, 0xA8}, + {0xF0, 0x94}, + {0xF0, 0x14}, + {0xF1, 0xA4}, + {0xF0, 0x95}, + {0xF0, 0x15}, + {0xF1, 0xA0}, + {0xF0, 0x96}, + {0xF0, 0x16}, + {0xF1, 0x9C}, + {0xF0, 0x97}, + {0xF0, 0x17}, + {0xF1, 0x98}, + {0xF0, 0x98}, + {0xF0, 0x18}, + {0xF1, 0x94}, + {0xF0, 0x99}, + {0xF0, 0x19}, + {0xF1, 0x90}, + {0xF0, 0x9A}, + {0xF0, 0x1A}, + {0xF1, 0x8C}, + {0xF0, 0x9B}, + {0xF0, 0x1B}, + {0xF1, 0x88}, + {0xF0, 0x9C}, + {0xF0, 0x1C}, + {0xF1, 0x84}, + {0xF0, 0x9D}, + {0xF0, 0x1D}, + {0xF1, 0x80}, + {0xF0, 0x9E}, + {0xF0, 0x1E}, + {0xF1, 0x7C}, + {0xF0, 0x9F}, + {0xF0, 0x1F}, + {0xF1, 0x78}, + {0xF0, 0xA0}, + {0xF0, 0x20}, + {0xF1, 0x74}, + {0xF0, 0xA1}, + {0xF0, 0x21}, + {0xF1, 0x70}, + {0xF0, 0xA2}, + {0xF0, 0x22}, + {0xF1, 0x6C}, + {0xF0, 0xA3}, + {0xF0, 0x23}, + {0xF1, 0x68}, + {0xF0, 0xA4}, + {0xF0, 0x24}, + {0xF1, 0x64}, + {0xF0, 0xA5}, + {0xF0, 0x25}, + {0xF1, 0x60}, + {0xF0, 0xA6}, + {0xF0, 0x26}, + {0xF1, 0x5C}, + {0xF0, 0xA7}, + {0xF0, 0x27}, + {0xF1, 0x58}, + {0xF0, 0xA8}, + {0xF0, 0x28}, + {0xF1, 0x54}, + {0xF0, 0xA9}, + {0xF0, 0x29}, + {0xF1, 0x50}, + {0xF0, 0xAA}, + {0xF0, 0x2A}, + {0xF1, 0x4C}, + {0xF0, 0xAB}, + {0xF0, 0x2B}, + {0xF1, 0x48}, + {0xF0, 0xAC}, + {0xF0, 0x2C}, + {0xF1, 0x44}, + {0xF0, 0xAD}, + {0xF0, 0x2D}, + {0xF1, 0x40}, + {0xF0, 0xAE}, + {0xF0, 0x2E}, + {0xF1, 0x3C}, + {0xF0, 0xAF}, + {0xF0, 0x2F}, + {0xF1, 0x38}, + {0xF0, 0xB0}, + {0xF0, 0x30}, + {0xF1, 0x34}, + {0xF0, 0xB1}, + {0xF0, 0x31}, + {0xF1, 0x30}, + {0xF0, 0xB2}, + {0xF0, 0x32}, + {0xF1, 0x2C}, + {0xF0, 0xB3}, + {0xF0, 0x33}, + {0xF1, 0x28}, + {0xF0, 0xB4}, + {0xF0, 0x34}, + {0xF1, 0x24}, + {0xF0, 0xB5}, + {0xF0, 0x35}, + {0xF1, 0x20}, + {0xF0, 0xB6}, + {0xF0, 0x36}, + {0xF1, 0x1C}, + {0xF0, 0xB7}, + {0xF0, 0x37}, + {0xF1, 0x18}, + {0xF0, 0xB8}, + {0xF0, 0x38}, + {0xF1, 0x14}, + {0xF0, 0xB9}, + {0xF0, 0x39}, + {0xF1, 0x10}, + {0xF0, 0xBA}, + {0xF0, 0x3A}, + {0xF1, 0x0C}, + {0xF0, 0xBB}, + {0xF0, 0x3B}, + {0xF1, 0x08}, + {0xF0, 0x00}, + {0xF0, 0x3C}, + {0xF1, 0x04}, + {0xF0, 0xBD}, + {0xF0, 0x3D}, + {0xF1, 0x00}, + {0xF0, 0xBE}, + {0xF0, 0x3E}, + {0xF1, 0x00}, + {0xF0, 0xBF}, + {0xF0, 0x3F}, + {0xF1, 0x00}, + {0xF0, 0xC0}, + {0xF0, 0x00}, }; #define CB_VT3253B0_INIT_FOR_RFMD 256 unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x81}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x38}, - {0x09, 0x45}, - {0x0a, 0x2a}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8e}, - {0x1c, 0x06}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x34}, - {0x2e, 0x18}, - {0x2f, 0x0c}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0xf8}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x09}, - {0x3e, 0x0d}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x08}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x80}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x14}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0x39}, - {0x61, 0x83}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0xc0}, - {0x67, 0x49}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x89}, - {0x81, 0x00}, - {0x82, 0x0e}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0e}, - {0x8b, 0xa7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x23}, - {0x91, 0x0c}, - {0x92, 0x06}, - {0x93, 0x08}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0xcd}, - {0xa4, 0x07}, - {0xa5, 0x33}, - {0xa6, 0x18}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x28}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x38}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0x00}, - {0xb5, 0x00}, - {0xb6, 0x84}, - {0xb7, 0xfd}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x00}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x20}, - {0xc2, 0x18}, - {0xc3, 0x20}, - {0xc4, 0x10}, - {0xc5, 0x2c}, - {0xc6, 0x1e}, - {0xc7, 0x10}, - {0xc8, 0x12}, - {0xc9, 0x01}, - {0xca, 0x6f}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x00}, - {0xcf, 0x22}, - {0xd0, 0x00}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x33}, - {0xd6, 0x80}, - {0xd7, 0x21}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xB3}, - {0xe2, 0x00}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x18}, - {0xe8, 0x08}, - {0xe9, 0xd4}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x10}, - {0xee, 0x30}, - {0xef, 0x02}, - {0xf0, 0x00}, - {0xf1, 0x09}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, + {0x00, 0x31}, + {0x01, 0x00}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x00}, + {0x05, 0x81}, + {0x06, 0x00}, + {0x07, 0x00}, + {0x08, 0x38}, + {0x09, 0x45}, + {0x0a, 0x2a}, + {0x0b, 0x76}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x80}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x8e}, + {0x1c, 0x06}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x4a}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x34}, + {0x2e, 0x18}, + {0x2f, 0x0c}, + {0x30, 0x26}, + {0x31, 0x5b}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0xaa}, + {0x37, 0xaa}, + {0x38, 0xff}, + {0x39, 0xff}, + {0x3a, 0xf8}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x09}, + {0x3e, 0x0d}, + {0x3f, 0x04}, + {0x40, 0x00}, + {0x41, 0x08}, + {0x42, 0x00}, + {0x43, 0x08}, + {0x44, 0x08}, + {0x45, 0x14}, + {0x46, 0x05}, + {0x47, 0x08}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x09}, + {0x4d, 0x80}, + {0x4e, 0x00}, + {0x4f, 0xc5}, + {0x50, 0x14}, + {0x51, 0x19}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0xb0}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x39}, + {0x61, 0x83}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0xc0}, + {0x67, 0x49}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x03}, + {0x6e, 0x01}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x80, 0x89}, + {0x81, 0x00}, + {0x82, 0x0e}, + {0x83, 0x00}, + {0x84, 0x00}, + {0x85, 0x00}, + {0x86, 0x00}, + {0x87, 0x00}, + {0x88, 0x08}, + {0x89, 0x00}, + {0x8a, 0x0e}, + {0x8b, 0xa7}, + {0x8c, 0x88}, + {0x8d, 0x47}, + {0x8e, 0xaa}, + {0x8f, 0x02}, + {0x90, 0x23}, + {0x91, 0x0c}, + {0x92, 0x06}, + {0x93, 0x08}, + {0x94, 0x00}, + {0x95, 0x00}, + {0x96, 0x00}, + {0x97, 0xeb}, + {0x98, 0x00}, + {0x99, 0x00}, + {0x9a, 0x00}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x00}, + {0x9e, 0x00}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x00}, + {0xa2, 0x00}, + {0xa3, 0xcd}, + {0xa4, 0x07}, + {0xa5, 0x33}, + {0xa6, 0x18}, + {0xa7, 0x00}, + {0xa8, 0x18}, + {0xa9, 0x00}, + {0xaa, 0x28}, + {0xab, 0x00}, + {0xac, 0x00}, + {0xad, 0x00}, + {0xae, 0x00}, + {0xaf, 0x18}, + {0xb0, 0x38}, + {0xb1, 0x30}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0x00}, + {0xb5, 0x00}, + {0xb6, 0x84}, + {0xb7, 0xfd}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x03}, + {0xbc, 0x00}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc0, 0x10}, + {0xc1, 0x20}, + {0xc2, 0x18}, + {0xc3, 0x20}, + {0xc4, 0x10}, + {0xc5, 0x2c}, + {0xc6, 0x1e}, + {0xc7, 0x10}, + {0xc8, 0x12}, + {0xc9, 0x01}, + {0xca, 0x6f}, + {0xcb, 0xa7}, + {0xcc, 0x3c}, + {0xcd, 0x10}, + {0xce, 0x00}, + {0xcf, 0x22}, + {0xd0, 0x00}, + {0xd1, 0x10}, + {0xd2, 0x00}, + {0xd3, 0x00}, + {0xd4, 0x10}, + {0xd5, 0x33}, + {0xd6, 0x80}, + {0xd7, 0x21}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xdc, 0x00}, + {0xdd, 0x00}, + {0xde, 0x00}, + {0xdf, 0x00}, + {0xe0, 0x00}, + {0xe1, 0xB3}, + {0xe2, 0x00}, + {0xe3, 0x00}, + {0xe4, 0x00}, + {0xe5, 0x10}, + {0xe6, 0x00}, + {0xe7, 0x18}, + {0xe8, 0x08}, + {0xe9, 0xd4}, + {0xea, 0x00}, + {0xeb, 0xff}, + {0xec, 0x79}, + {0xed, 0x10}, + {0xee, 0x30}, + {0xef, 0x02}, + {0xf0, 0x00}, + {0xf1, 0x09}, + {0xf2, 0x00}, + {0xf3, 0x00}, + {0xf4, 0x00}, + {0xf5, 0x00}, + {0xf6, 0x00}, + {0xf7, 0x00}, + {0xf8, 0x00}, + {0xf9, 0x00}, + {0xfa, 0x00}, + {0xfb, 0x00}, + {0xfc, 0x00}, + {0xfd, 0x00}, + {0xfe, 0x00}, + {0xff, 0x00}, }; #define CB_VT3253B0_AGC_FOR_RFMD2959 195 // For RFMD2959 unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { - {0xF0, 0x00}, - {0xF1, 0x3E}, - {0xF0, 0x80}, - {0xF0, 0x00}, - {0xF1, 0x3E}, - {0xF0, 0x81}, - {0xF0, 0x01}, - {0xF1, 0x3E}, - {0xF0, 0x82}, - {0xF0, 0x02}, - {0xF1, 0x3E}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0x3B}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0x39}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0x38}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0x37}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0x36}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0x35}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0x35}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0x34}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0x34}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0x33}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0x32}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0x31}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0x30}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0x2F}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0x2F}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0x2E}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0x2D}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0x2C}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0x2B}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x2B}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x2A}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x29}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x28}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x27}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x26}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x25}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x24}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x24}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x23}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x22}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x21}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x20}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x20}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x1F}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x1E}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x1D}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x1C}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x1B}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x1B}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x1A}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x1A}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x19}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x18}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x17}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x16}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x15}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x15}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x15}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x14}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x13}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x12}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x11}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x10}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x0F}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x0E}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x0D}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x0C}, - {0xF0, 0xBC}, - {0xF0, 0x3C}, - {0xF1, 0x0B}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x0B}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x0A}, - {0xF0, 0xBF}, - {0xF0, 0x3F}, - {0xF1, 0x09}, - {0xF0, 0x00}, + {0xF0, 0x00}, + {0xF1, 0x3E}, + {0xF0, 0x80}, + {0xF0, 0x00}, + {0xF1, 0x3E}, + {0xF0, 0x81}, + {0xF0, 0x01}, + {0xF1, 0x3E}, + {0xF0, 0x82}, + {0xF0, 0x02}, + {0xF1, 0x3E}, + {0xF0, 0x83}, + {0xF0, 0x03}, + {0xF1, 0x3B}, + {0xF0, 0x84}, + {0xF0, 0x04}, + {0xF1, 0x39}, + {0xF0, 0x85}, + {0xF0, 0x05}, + {0xF1, 0x38}, + {0xF0, 0x86}, + {0xF0, 0x06}, + {0xF1, 0x37}, + {0xF0, 0x87}, + {0xF0, 0x07}, + {0xF1, 0x36}, + {0xF0, 0x88}, + {0xF0, 0x08}, + {0xF1, 0x35}, + {0xF0, 0x89}, + {0xF0, 0x09}, + {0xF1, 0x35}, + {0xF0, 0x8A}, + {0xF0, 0x0A}, + {0xF1, 0x34}, + {0xF0, 0x8B}, + {0xF0, 0x0B}, + {0xF1, 0x34}, + {0xF0, 0x8C}, + {0xF0, 0x0C}, + {0xF1, 0x33}, + {0xF0, 0x8D}, + {0xF0, 0x0D}, + {0xF1, 0x32}, + {0xF0, 0x8E}, + {0xF0, 0x0E}, + {0xF1, 0x31}, + {0xF0, 0x8F}, + {0xF0, 0x0F}, + {0xF1, 0x30}, + {0xF0, 0x90}, + {0xF0, 0x10}, + {0xF1, 0x2F}, + {0xF0, 0x91}, + {0xF0, 0x11}, + {0xF1, 0x2F}, + {0xF0, 0x92}, + {0xF0, 0x12}, + {0xF1, 0x2E}, + {0xF0, 0x93}, + {0xF0, 0x13}, + {0xF1, 0x2D}, + {0xF0, 0x94}, + {0xF0, 0x14}, + {0xF1, 0x2C}, + {0xF0, 0x95}, + {0xF0, 0x15}, + {0xF1, 0x2B}, + {0xF0, 0x96}, + {0xF0, 0x16}, + {0xF1, 0x2B}, + {0xF0, 0x97}, + {0xF0, 0x17}, + {0xF1, 0x2A}, + {0xF0, 0x98}, + {0xF0, 0x18}, + {0xF1, 0x29}, + {0xF0, 0x99}, + {0xF0, 0x19}, + {0xF1, 0x28}, + {0xF0, 0x9A}, + {0xF0, 0x1A}, + {0xF1, 0x27}, + {0xF0, 0x9B}, + {0xF0, 0x1B}, + {0xF1, 0x26}, + {0xF0, 0x9C}, + {0xF0, 0x1C}, + {0xF1, 0x25}, + {0xF0, 0x9D}, + {0xF0, 0x1D}, + {0xF1, 0x24}, + {0xF0, 0x9E}, + {0xF0, 0x1E}, + {0xF1, 0x24}, + {0xF0, 0x9F}, + {0xF0, 0x1F}, + {0xF1, 0x23}, + {0xF0, 0xA0}, + {0xF0, 0x20}, + {0xF1, 0x22}, + {0xF0, 0xA1}, + {0xF0, 0x21}, + {0xF1, 0x21}, + {0xF0, 0xA2}, + {0xF0, 0x22}, + {0xF1, 0x20}, + {0xF0, 0xA3}, + {0xF0, 0x23}, + {0xF1, 0x20}, + {0xF0, 0xA4}, + {0xF0, 0x24}, + {0xF1, 0x1F}, + {0xF0, 0xA5}, + {0xF0, 0x25}, + {0xF1, 0x1E}, + {0xF0, 0xA6}, + {0xF0, 0x26}, + {0xF1, 0x1D}, + {0xF0, 0xA7}, + {0xF0, 0x27}, + {0xF1, 0x1C}, + {0xF0, 0xA8}, + {0xF0, 0x28}, + {0xF1, 0x1B}, + {0xF0, 0xA9}, + {0xF0, 0x29}, + {0xF1, 0x1B}, + {0xF0, 0xAA}, + {0xF0, 0x2A}, + {0xF1, 0x1A}, + {0xF0, 0xAB}, + {0xF0, 0x2B}, + {0xF1, 0x1A}, + {0xF0, 0xAC}, + {0xF0, 0x2C}, + {0xF1, 0x19}, + {0xF0, 0xAD}, + {0xF0, 0x2D}, + {0xF1, 0x18}, + {0xF0, 0xAE}, + {0xF0, 0x2E}, + {0xF1, 0x17}, + {0xF0, 0xAF}, + {0xF0, 0x2F}, + {0xF1, 0x16}, + {0xF0, 0xB0}, + {0xF0, 0x30}, + {0xF1, 0x15}, + {0xF0, 0xB1}, + {0xF0, 0x31}, + {0xF1, 0x15}, + {0xF0, 0xB2}, + {0xF0, 0x32}, + {0xF1, 0x15}, + {0xF0, 0xB3}, + {0xF0, 0x33}, + {0xF1, 0x14}, + {0xF0, 0xB4}, + {0xF0, 0x34}, + {0xF1, 0x13}, + {0xF0, 0xB5}, + {0xF0, 0x35}, + {0xF1, 0x12}, + {0xF0, 0xB6}, + {0xF0, 0x36}, + {0xF1, 0x11}, + {0xF0, 0xB7}, + {0xF0, 0x37}, + {0xF1, 0x10}, + {0xF0, 0xB8}, + {0xF0, 0x38}, + {0xF1, 0x0F}, + {0xF0, 0xB9}, + {0xF0, 0x39}, + {0xF1, 0x0E}, + {0xF0, 0xBA}, + {0xF0, 0x3A}, + {0xF1, 0x0D}, + {0xF0, 0xBB}, + {0xF0, 0x3B}, + {0xF1, 0x0C}, + {0xF0, 0xBC}, + {0xF0, 0x3C}, + {0xF1, 0x0B}, + {0xF0, 0xBD}, + {0xF0, 0x3D}, + {0xF1, 0x0B}, + {0xF0, 0xBE}, + {0xF0, 0x3E}, + {0xF1, 0x0A}, + {0xF0, 0xBF}, + {0xF0, 0x3F}, + {0xF1, 0x09}, + {0xF0, 0x00}, }; #define CB_VT3253B0_INIT_FOR_AIROHA2230 256 // For AIROHA unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x80}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x70}, - {0x09, 0x41}, - {0x0a, 0x2A}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8f}, - {0x1c, 0x09}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x4a}, - {0x2e, 0x00}, - {0x2f, 0x0a}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x79}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x0b}, - {0x3e, 0x48}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x09}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x73}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x15}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0xe4}, - {0x61, 0x80}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x98}, - {0x67, 0x0a}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - //{0x6c, 0x80}, - {0x6c, 0x00}, //RobertYu:20050125, request by JJSue - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x8c}, - {0x81, 0x01}, - {0x82, 0x09}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0f}, - {0x8b, 0xb7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x22}, - {0x91, 0x00}, - {0x92, 0x00}, - {0x93, 0x00}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x01}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x00}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x38}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0xff}, - {0xb5, 0x0f}, - {0xb6, 0xe4}, - {0xb7, 0xe2}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x01}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x18}, - {0xc1, 0x20}, - {0xc2, 0x07}, - {0xc3, 0x18}, - {0xc4, 0xff}, - {0xc5, 0x2c}, - {0xc6, 0x0c}, - {0xc7, 0x0a}, - {0xc8, 0x0e}, - {0xc9, 0x01}, - {0xca, 0x68}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x00}, - {0xcf, 0x25}, - {0xd0, 0x40}, - {0xd1, 0x12}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x28}, - {0xd6, 0x80}, - {0xd7, 0x2A}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xB3}, - {0xe2, 0x00}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x1C}, - {0xe8, 0x00}, - {0xe9, 0xf4}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x20}, - {0xee, 0x30}, - {0xef, 0x01}, - {0xf0, 0x00}, - {0xf1, 0x3e}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, + {0x00, 0x31}, + {0x01, 0x00}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x00}, + {0x05, 0x80}, + {0x06, 0x00}, + {0x07, 0x00}, + {0x08, 0x70}, + {0x09, 0x41}, + {0x0a, 0x2A}, + {0x0b, 0x76}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x80}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x8f}, + {0x1c, 0x09}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x4a}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x4a}, + {0x2e, 0x00}, + {0x2f, 0x0a}, + {0x30, 0x26}, + {0x31, 0x5b}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0xaa}, + {0x37, 0xaa}, + {0x38, 0xff}, + {0x39, 0xff}, + {0x3a, 0x79}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x0b}, + {0x3e, 0x48}, + {0x3f, 0x04}, + {0x40, 0x00}, + {0x41, 0x08}, + {0x42, 0x00}, + {0x43, 0x08}, + {0x44, 0x08}, + {0x45, 0x14}, + {0x46, 0x05}, + {0x47, 0x09}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x09}, + {0x4d, 0x73}, + {0x4e, 0x00}, + {0x4f, 0xc5}, + {0x50, 0x15}, + {0x51, 0x19}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0xb0}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0xe4}, + {0x61, 0x80}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x98}, + {0x67, 0x0a}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + //{0x6c, 0x80}, + {0x6c, 0x00}, //RobertYu:20050125, request by JJSue + {0x6d, 0x03}, + {0x6e, 0x01}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x80, 0x8c}, + {0x81, 0x01}, + {0x82, 0x09}, + {0x83, 0x00}, + {0x84, 0x00}, + {0x85, 0x00}, + {0x86, 0x00}, + {0x87, 0x00}, + {0x88, 0x08}, + {0x89, 0x00}, + {0x8a, 0x0f}, + {0x8b, 0xb7}, + {0x8c, 0x88}, + {0x8d, 0x47}, + {0x8e, 0xaa}, + {0x8f, 0x02}, + {0x90, 0x22}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x00}, + {0x96, 0x00}, + {0x97, 0xeb}, + {0x98, 0x00}, + {0x99, 0x00}, + {0x9a, 0x00}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x00}, + {0x9e, 0x00}, + {0x9f, 0x01}, + {0xa0, 0x00}, + {0xa1, 0x00}, + {0xa2, 0x00}, + {0xa3, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x10}, + {0xa7, 0x00}, + {0xa8, 0x18}, + {0xa9, 0x00}, + {0xaa, 0x00}, + {0xab, 0x00}, + {0xac, 0x00}, + {0xad, 0x00}, + {0xae, 0x00}, + {0xaf, 0x18}, + {0xb0, 0x38}, + {0xb1, 0x30}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0xff}, + {0xb5, 0x0f}, + {0xb6, 0xe4}, + {0xb7, 0xe2}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x03}, + {0xbc, 0x01}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc0, 0x18}, + {0xc1, 0x20}, + {0xc2, 0x07}, + {0xc3, 0x18}, + {0xc4, 0xff}, + {0xc5, 0x2c}, + {0xc6, 0x0c}, + {0xc7, 0x0a}, + {0xc8, 0x0e}, + {0xc9, 0x01}, + {0xca, 0x68}, + {0xcb, 0xa7}, + {0xcc, 0x3c}, + {0xcd, 0x10}, + {0xce, 0x00}, + {0xcf, 0x25}, + {0xd0, 0x40}, + {0xd1, 0x12}, + {0xd2, 0x00}, + {0xd3, 0x00}, + {0xd4, 0x10}, + {0xd5, 0x28}, + {0xd6, 0x80}, + {0xd7, 0x2A}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xdc, 0x00}, + {0xdd, 0x00}, + {0xde, 0x00}, + {0xdf, 0x00}, + {0xe0, 0x00}, + {0xe1, 0xB3}, + {0xe2, 0x00}, + {0xe3, 0x00}, + {0xe4, 0x00}, + {0xe5, 0x10}, + {0xe6, 0x00}, + {0xe7, 0x1C}, + {0xe8, 0x00}, + {0xe9, 0xf4}, + {0xea, 0x00}, + {0xeb, 0xff}, + {0xec, 0x79}, + {0xed, 0x20}, + {0xee, 0x30}, + {0xef, 0x01}, + {0xf0, 0x00}, + {0xf1, 0x3e}, + {0xf2, 0x00}, + {0xf3, 0x00}, + {0xf4, 0x00}, + {0xf5, 0x00}, + {0xf6, 0x00}, + {0xf7, 0x00}, + {0xf8, 0x00}, + {0xf9, 0x00}, + {0xfa, 0x00}, + {0xfb, 0x00}, + {0xfc, 0x00}, + {0xfd, 0x00}, + {0xfe, 0x00}, + {0xff, 0x00}, }; @@ -1253,461 +1253,461 @@ unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { #define CB_VT3253B0_INIT_FOR_UW2451 256 //For UW2451 unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x81}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x38}, - {0x09, 0x45}, - {0x0a, 0x28}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8f}, - {0x1c, 0x0f}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x18}, - {0x2e, 0x00}, - {0x2f, 0x0a}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x00}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x03}, - {0x3e, 0x1d}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x09}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x90}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x15}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0xb3}, - {0x61, 0x81}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x57}, - {0x67, 0x6c}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - //{0x6c, 0x80}, - {0x6c, 0x00}, //RobertYu:20050125, request by JJSue - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x8c}, - {0x81, 0x00}, - {0x82, 0x0e}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0e}, - {0x8b, 0xa7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x00}, - {0x91, 0x00}, - {0x92, 0x00}, - {0x93, 0x00}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xe3}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x00}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x18}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0x00}, - {0xb5, 0x00}, - {0xb6, 0x00}, - {0xb7, 0x00}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x01}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x20}, - {0xc2, 0x00}, - {0xc3, 0x20}, - {0xc4, 0x00}, - {0xc5, 0x2c}, - {0xc6, 0x1c}, - {0xc7, 0x10}, - {0xc8, 0x10}, - {0xc9, 0x01}, - {0xca, 0x68}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x09}, - {0xce, 0x00}, - {0xcf, 0x20}, - {0xd0, 0x40}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x20}, - {0xd5, 0x28}, - {0xd6, 0xa0}, - {0xd7, 0x2a}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xd3}, - {0xe2, 0xc0}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x12}, - {0xe8, 0x12}, - {0xe9, 0x34}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x20}, - {0xee, 0x30}, - {0xef, 0x01}, - {0xf0, 0x00}, - {0xf1, 0x3e}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, + {0x00, 0x31}, + {0x01, 0x00}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x00}, + {0x05, 0x81}, + {0x06, 0x00}, + {0x07, 0x00}, + {0x08, 0x38}, + {0x09, 0x45}, + {0x0a, 0x28}, + {0x0b, 0x76}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x80}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x8f}, + {0x1c, 0x0f}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x4a}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x18}, + {0x2e, 0x00}, + {0x2f, 0x0a}, + {0x30, 0x26}, + {0x31, 0x5b}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0xaa}, + {0x37, 0xaa}, + {0x38, 0xff}, + {0x39, 0xff}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x03}, + {0x3e, 0x1d}, + {0x3f, 0x04}, + {0x40, 0x00}, + {0x41, 0x08}, + {0x42, 0x00}, + {0x43, 0x08}, + {0x44, 0x08}, + {0x45, 0x14}, + {0x46, 0x05}, + {0x47, 0x09}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x09}, + {0x4d, 0x90}, + {0x4e, 0x00}, + {0x4f, 0xc5}, + {0x50, 0x15}, + {0x51, 0x19}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0xb0}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0xb3}, + {0x61, 0x81}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x57}, + {0x67, 0x6c}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + //{0x6c, 0x80}, + {0x6c, 0x00}, //RobertYu:20050125, request by JJSue + {0x6d, 0x03}, + {0x6e, 0x01}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x80, 0x8c}, + {0x81, 0x00}, + {0x82, 0x0e}, + {0x83, 0x00}, + {0x84, 0x00}, + {0x85, 0x00}, + {0x86, 0x00}, + {0x87, 0x00}, + {0x88, 0x08}, + {0x89, 0x00}, + {0x8a, 0x0e}, + {0x8b, 0xa7}, + {0x8c, 0x88}, + {0x8d, 0x47}, + {0x8e, 0xaa}, + {0x8f, 0x02}, + {0x90, 0x00}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x00}, + {0x96, 0x00}, + {0x97, 0xe3}, + {0x98, 0x00}, + {0x99, 0x00}, + {0x9a, 0x00}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x00}, + {0x9e, 0x00}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x00}, + {0xa2, 0x00}, + {0xa3, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x10}, + {0xa7, 0x00}, + {0xa8, 0x18}, + {0xa9, 0x00}, + {0xaa, 0x00}, + {0xab, 0x00}, + {0xac, 0x00}, + {0xad, 0x00}, + {0xae, 0x00}, + {0xaf, 0x18}, + {0xb0, 0x18}, + {0xb1, 0x30}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0x00}, + {0xb5, 0x00}, + {0xb6, 0x00}, + {0xb7, 0x00}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x03}, + {0xbc, 0x01}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc0, 0x10}, + {0xc1, 0x20}, + {0xc2, 0x00}, + {0xc3, 0x20}, + {0xc4, 0x00}, + {0xc5, 0x2c}, + {0xc6, 0x1c}, + {0xc7, 0x10}, + {0xc8, 0x10}, + {0xc9, 0x01}, + {0xca, 0x68}, + {0xcb, 0xa7}, + {0xcc, 0x3c}, + {0xcd, 0x09}, + {0xce, 0x00}, + {0xcf, 0x20}, + {0xd0, 0x40}, + {0xd1, 0x10}, + {0xd2, 0x00}, + {0xd3, 0x00}, + {0xd4, 0x20}, + {0xd5, 0x28}, + {0xd6, 0xa0}, + {0xd7, 0x2a}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xdc, 0x00}, + {0xdd, 0x00}, + {0xde, 0x00}, + {0xdf, 0x00}, + {0xe0, 0x00}, + {0xe1, 0xd3}, + {0xe2, 0xc0}, + {0xe3, 0x00}, + {0xe4, 0x00}, + {0xe5, 0x10}, + {0xe6, 0x00}, + {0xe7, 0x12}, + {0xe8, 0x12}, + {0xe9, 0x34}, + {0xea, 0x00}, + {0xeb, 0xff}, + {0xec, 0x79}, + {0xed, 0x20}, + {0xee, 0x30}, + {0xef, 0x01}, + {0xf0, 0x00}, + {0xf1, 0x3e}, + {0xf2, 0x00}, + {0xf3, 0x00}, + {0xf4, 0x00}, + {0xf5, 0x00}, + {0xf6, 0x00}, + {0xf7, 0x00}, + {0xf8, 0x00}, + {0xf9, 0x00}, + {0xfa, 0x00}, + {0xfb, 0x00}, + {0xfc, 0x00}, + {0xfd, 0x00}, + {0xfe, 0x00}, + {0xff, 0x00}, }; #define CB_VT3253B0_AGC 193 // For AIROHA unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = { - {0xF0, 0x00}, - {0xF1, 0x00}, - {0xF0, 0x80}, - {0xF0, 0x01}, - {0xF1, 0x00}, - {0xF0, 0x81}, - {0xF0, 0x02}, - {0xF1, 0x02}, - {0xF0, 0x82}, - {0xF0, 0x03}, - {0xF1, 0x04}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0x04}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0x06}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0x06}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0x06}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0x08}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0x08}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0x0A}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0x0A}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0x0C}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0x0C}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0x0E}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0x0E}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0x10}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0x10}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0x12}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0x12}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0x14}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0x14}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0x16}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x16}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x18}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x18}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x1A}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x1A}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x1C}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x1C}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x1E}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x1E}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x20}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x20}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x22}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x22}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x24}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x24}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x26}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x26}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x28}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x28}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x2A}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x2A}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x2C}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x2C}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x2E}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x2E}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x30}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x30}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x32}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x32}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x34}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x34}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x36}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x36}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x38}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x38}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x3A}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x3A}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x3C}, - {0xF0, 0xBC}, - {0xF0, 0x3C}, - {0xF1, 0x3C}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x3E}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x3E}, - {0xF0, 0xBF}, - {0xF0, 0x00}, + {0xF0, 0x00}, + {0xF1, 0x00}, + {0xF0, 0x80}, + {0xF0, 0x01}, + {0xF1, 0x00}, + {0xF0, 0x81}, + {0xF0, 0x02}, + {0xF1, 0x02}, + {0xF0, 0x82}, + {0xF0, 0x03}, + {0xF1, 0x04}, + {0xF0, 0x83}, + {0xF0, 0x03}, + {0xF1, 0x04}, + {0xF0, 0x84}, + {0xF0, 0x04}, + {0xF1, 0x06}, + {0xF0, 0x85}, + {0xF0, 0x05}, + {0xF1, 0x06}, + {0xF0, 0x86}, + {0xF0, 0x06}, + {0xF1, 0x06}, + {0xF0, 0x87}, + {0xF0, 0x07}, + {0xF1, 0x08}, + {0xF0, 0x88}, + {0xF0, 0x08}, + {0xF1, 0x08}, + {0xF0, 0x89}, + {0xF0, 0x09}, + {0xF1, 0x0A}, + {0xF0, 0x8A}, + {0xF0, 0x0A}, + {0xF1, 0x0A}, + {0xF0, 0x8B}, + {0xF0, 0x0B}, + {0xF1, 0x0C}, + {0xF0, 0x8C}, + {0xF0, 0x0C}, + {0xF1, 0x0C}, + {0xF0, 0x8D}, + {0xF0, 0x0D}, + {0xF1, 0x0E}, + {0xF0, 0x8E}, + {0xF0, 0x0E}, + {0xF1, 0x0E}, + {0xF0, 0x8F}, + {0xF0, 0x0F}, + {0xF1, 0x10}, + {0xF0, 0x90}, + {0xF0, 0x10}, + {0xF1, 0x10}, + {0xF0, 0x91}, + {0xF0, 0x11}, + {0xF1, 0x12}, + {0xF0, 0x92}, + {0xF0, 0x12}, + {0xF1, 0x12}, + {0xF0, 0x93}, + {0xF0, 0x13}, + {0xF1, 0x14}, + {0xF0, 0x94}, + {0xF0, 0x14}, + {0xF1, 0x14}, + {0xF0, 0x95}, + {0xF0, 0x15}, + {0xF1, 0x16}, + {0xF0, 0x96}, + {0xF0, 0x16}, + {0xF1, 0x16}, + {0xF0, 0x97}, + {0xF0, 0x17}, + {0xF1, 0x18}, + {0xF0, 0x98}, + {0xF0, 0x18}, + {0xF1, 0x18}, + {0xF0, 0x99}, + {0xF0, 0x19}, + {0xF1, 0x1A}, + {0xF0, 0x9A}, + {0xF0, 0x1A}, + {0xF1, 0x1A}, + {0xF0, 0x9B}, + {0xF0, 0x1B}, + {0xF1, 0x1C}, + {0xF0, 0x9C}, + {0xF0, 0x1C}, + {0xF1, 0x1C}, + {0xF0, 0x9D}, + {0xF0, 0x1D}, + {0xF1, 0x1E}, + {0xF0, 0x9E}, + {0xF0, 0x1E}, + {0xF1, 0x1E}, + {0xF0, 0x9F}, + {0xF0, 0x1F}, + {0xF1, 0x20}, + {0xF0, 0xA0}, + {0xF0, 0x20}, + {0xF1, 0x20}, + {0xF0, 0xA1}, + {0xF0, 0x21}, + {0xF1, 0x22}, + {0xF0, 0xA2}, + {0xF0, 0x22}, + {0xF1, 0x22}, + {0xF0, 0xA3}, + {0xF0, 0x23}, + {0xF1, 0x24}, + {0xF0, 0xA4}, + {0xF0, 0x24}, + {0xF1, 0x24}, + {0xF0, 0xA5}, + {0xF0, 0x25}, + {0xF1, 0x26}, + {0xF0, 0xA6}, + {0xF0, 0x26}, + {0xF1, 0x26}, + {0xF0, 0xA7}, + {0xF0, 0x27}, + {0xF1, 0x28}, + {0xF0, 0xA8}, + {0xF0, 0x28}, + {0xF1, 0x28}, + {0xF0, 0xA9}, + {0xF0, 0x29}, + {0xF1, 0x2A}, + {0xF0, 0xAA}, + {0xF0, 0x2A}, + {0xF1, 0x2A}, + {0xF0, 0xAB}, + {0xF0, 0x2B}, + {0xF1, 0x2C}, + {0xF0, 0xAC}, + {0xF0, 0x2C}, + {0xF1, 0x2C}, + {0xF0, 0xAD}, + {0xF0, 0x2D}, + {0xF1, 0x2E}, + {0xF0, 0xAE}, + {0xF0, 0x2E}, + {0xF1, 0x2E}, + {0xF0, 0xAF}, + {0xF0, 0x2F}, + {0xF1, 0x30}, + {0xF0, 0xB0}, + {0xF0, 0x30}, + {0xF1, 0x30}, + {0xF0, 0xB1}, + {0xF0, 0x31}, + {0xF1, 0x32}, + {0xF0, 0xB2}, + {0xF0, 0x32}, + {0xF1, 0x32}, + {0xF0, 0xB3}, + {0xF0, 0x33}, + {0xF1, 0x34}, + {0xF0, 0xB4}, + {0xF0, 0x34}, + {0xF1, 0x34}, + {0xF0, 0xB5}, + {0xF0, 0x35}, + {0xF1, 0x36}, + {0xF0, 0xB6}, + {0xF0, 0x36}, + {0xF1, 0x36}, + {0xF0, 0xB7}, + {0xF0, 0x37}, + {0xF1, 0x38}, + {0xF0, 0xB8}, + {0xF0, 0x38}, + {0xF1, 0x38}, + {0xF0, 0xB9}, + {0xF0, 0x39}, + {0xF1, 0x3A}, + {0xF0, 0xBA}, + {0xF0, 0x3A}, + {0xF1, 0x3A}, + {0xF0, 0xBB}, + {0xF0, 0x3B}, + {0xF1, 0x3C}, + {0xF0, 0xBC}, + {0xF0, 0x3C}, + {0xF1, 0x3C}, + {0xF0, 0xBD}, + {0xF0, 0x3D}, + {0xF1, 0x3E}, + {0xF0, 0xBE}, + {0xF0, 0x3E}, + {0xF1, 0x3E}, + {0xF0, 0xBF}, + {0xF0, 0x00}, }; const unsigned short awcFrameTime[MAX_RATE] = @@ -1723,39 +1723,39 @@ s_ulGetRatio(PSDevice pDevice); static void s_vChangeAntenna( - PSDevice pDevice - ); + PSDevice pDevice +); static void -s_vChangeAntenna ( - PSDevice pDevice - ) +s_vChangeAntenna( + PSDevice pDevice +) { #ifdef PLICE_DEBUG //printk("Enter s_vChangeAntenna:original RxMode is %d,TxMode is %d\n",pDevice->byRxAntennaMode,pDevice->byTxAntennaMode); #endif - if ( pDevice->dwRxAntennaSel == 0) { - pDevice->dwRxAntennaSel=1; - if (pDevice->bTxRxAntInv == true) - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); - else - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); - } else { - pDevice->dwRxAntennaSel=0; - if (pDevice->bTxRxAntInv == true) - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); - else - BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); - } - if ( pDevice->dwTxAntennaSel == 0) { - pDevice->dwTxAntennaSel=1; - BBvSetTxAntennaMode(pDevice->PortOffset, ANT_B); - } else { - pDevice->dwTxAntennaSel=0; - BBvSetTxAntennaMode(pDevice->PortOffset, ANT_A); - } + if (pDevice->dwRxAntennaSel == 0) { + pDevice->dwRxAntennaSel = 1; + if (pDevice->bTxRxAntInv == true) + BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); + else + BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); + } else { + pDevice->dwRxAntennaSel = 0; + if (pDevice->bTxRxAntInv == true) + BBvSetRxAntennaMode(pDevice->PortOffset, ANT_B); + else + BBvSetRxAntennaMode(pDevice->PortOffset, ANT_A); + } + if (pDevice->dwTxAntennaSel == 0) { + pDevice->dwTxAntennaSel = 1; + BBvSetTxAntennaMode(pDevice->PortOffset, ANT_B); + } else { + pDevice->dwTxAntennaSel = 0; + BBvSetTxAntennaMode(pDevice->PortOffset, ANT_A); + } } @@ -1775,54 +1775,54 @@ s_vChangeAntenna ( * */ unsigned int -BBuGetFrameTime ( - unsigned char byPreambleType, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate - ) +BBuGetFrameTime( + unsigned char byPreambleType, + unsigned char byPktType, + unsigned int cbFrameLength, + unsigned short wRate +) { - unsigned int uFrameTime; - unsigned int uPreamble; - unsigned int uTmp; - unsigned int uRateIdx = (unsigned int) wRate; - unsigned int uRate = 0; - - - if (uRateIdx > RATE_54M) { - ASSERT(0); - return 0; - } - - uRate = (unsigned int) awcFrameTime[uRateIdx]; - - if (uRateIdx <= 3) { //CCK mode - - if (byPreambleType == 1) {//Short - uPreamble = 96; - } else { - uPreamble = 192; - } - uFrameTime = (cbFrameLength * 80) / uRate; //????? - uTmp = (uFrameTime * uRate) / 80; - if (cbFrameLength != uTmp) { - uFrameTime ++; - } - - return (uPreamble + uFrameTime); - } - else { - uFrameTime = (cbFrameLength * 8 + 22) / uRate; //???????? - uTmp = ((uFrameTime * uRate) - 22) / 8; - if(cbFrameLength != uTmp) { - uFrameTime ++; - } - uFrameTime = uFrameTime * 4; //??????? - if(byPktType != PK_TYPE_11A) { - uFrameTime += 6; //?????? - } - return (20 + uFrameTime); //?????? - } + unsigned int uFrameTime; + unsigned int uPreamble; + unsigned int uTmp; + unsigned int uRateIdx = (unsigned int) wRate; + unsigned int uRate = 0; + + + if (uRateIdx > RATE_54M) { + ASSERT(0); + return 0; + } + + uRate = (unsigned int)awcFrameTime[uRateIdx]; + + if (uRateIdx <= 3) { //CCK mode + + if (byPreambleType == 1) {//Short + uPreamble = 96; + } else { + uPreamble = 192; + } + uFrameTime = (cbFrameLength * 80) / uRate; //????? + uTmp = (uFrameTime * uRate) / 80; + if (cbFrameLength != uTmp) { + uFrameTime++; + } + + return (uPreamble + uFrameTime); + } + else { + uFrameTime = (cbFrameLength * 8 + 22) / uRate; //???????? + uTmp = ((uFrameTime * uRate) - 22) / 8; + if (cbFrameLength != uTmp) { + uFrameTime++; + } + uFrameTime = uFrameTime * 4; //??????? + if (byPktType != PK_TYPE_11A) { + uFrameTime += 6; //?????? + } + return (20 + uFrameTime); //?????? + } } /* @@ -1842,162 +1842,162 @@ BBuGetFrameTime ( * */ void -BBvCalculateParameter ( - PSDevice pDevice, - unsigned int cbFrameLength, - unsigned short wRate, - unsigned char byPacketType, - unsigned short *pwPhyLen, - unsigned char *pbyPhySrv, - unsigned char *pbyPhySgn - ) +BBvCalculateParameter( + PSDevice pDevice, + unsigned int cbFrameLength, + unsigned short wRate, + unsigned char byPacketType, + unsigned short *pwPhyLen, + unsigned char *pbyPhySrv, + unsigned char *pbyPhySgn +) { - unsigned int cbBitCount; - unsigned int cbUsCount = 0; - unsigned int cbTmp; - bool bExtBit; - unsigned char byPreambleType = pDevice->byPreambleType; - bool bCCK = pDevice->bCCK; - - cbBitCount = cbFrameLength * 8; - bExtBit = false; - - switch (wRate) { - case RATE_1M : - cbUsCount = cbBitCount; - *pbyPhySgn = 0x00; - break; - - case RATE_2M : - cbUsCount = cbBitCount / 2; - if (byPreambleType == 1) - *pbyPhySgn = 0x09; - else // long preamble - *pbyPhySgn = 0x01; - break; - - case RATE_5M : - if (bCCK == false) - cbBitCount ++; - cbUsCount = (cbBitCount * 10) / 55; - cbTmp = (cbUsCount * 55) / 10; - if (cbTmp != cbBitCount) - cbUsCount ++; - if (byPreambleType == 1) - *pbyPhySgn = 0x0a; - else // long preamble - *pbyPhySgn = 0x02; - break; - - case RATE_11M : - - if (bCCK == false) - cbBitCount ++; - cbUsCount = cbBitCount / 11; - cbTmp = cbUsCount * 11; - if (cbTmp != cbBitCount) { - cbUsCount ++; - if ((cbBitCount - cbTmp) <= 3) - bExtBit = true; - } - if (byPreambleType == 1) - *pbyPhySgn = 0x0b; - else // long preamble - *pbyPhySgn = 0x03; - break; - - case RATE_6M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9B; //1001 1011 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8B; //1000 1011 - } - break; - - case RATE_9M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9F; //1001 1111 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8F; //1000 1111 - } - break; - - case RATE_12M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9A; //1001 1010 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8A; //1000 1010 - } - break; - - case RATE_18M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9E; //1001 1110 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8E; //1000 1110 - } - break; - - case RATE_24M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x99; //1001 1001 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x89; //1000 1001 - } - break; - - case RATE_36M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9D; //1001 1101 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8D; //1000 1101 - } - break; - - case RATE_48M : - if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x98; //1001 1000 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x88; //1000 1000 - } - break; - - case RATE_54M : - if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9C; //1001 1100 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8C; //1000 1100 - } - break; - - default : - if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ - *pbyPhySgn = 0x9C; //1001 1100 - } - else {//11g, 2.4GHZ - *pbyPhySgn = 0x8C; //1000 1100 - } - break; - } - - if (byPacketType == PK_TYPE_11B) { - *pbyPhySrv = 0x00; - if (bExtBit) - *pbyPhySrv = *pbyPhySrv | 0x80; - *pwPhyLen = (unsigned short)cbUsCount; - } - else { - *pbyPhySrv = 0x00; - *pwPhyLen = (unsigned short)cbFrameLength; - } + unsigned int cbBitCount; + unsigned int cbUsCount = 0; + unsigned int cbTmp; + bool bExtBit; + unsigned char byPreambleType = pDevice->byPreambleType; + bool bCCK = pDevice->bCCK; + + cbBitCount = cbFrameLength * 8; + bExtBit = false; + + switch (wRate) { + case RATE_1M: + cbUsCount = cbBitCount; + *pbyPhySgn = 0x00; + break; + + case RATE_2M: + cbUsCount = cbBitCount / 2; + if (byPreambleType == 1) + *pbyPhySgn = 0x09; + else // long preamble + *pbyPhySgn = 0x01; + break; + + case RATE_5M: + if (bCCK == false) + cbBitCount++; + cbUsCount = (cbBitCount * 10) / 55; + cbTmp = (cbUsCount * 55) / 10; + if (cbTmp != cbBitCount) + cbUsCount++; + if (byPreambleType == 1) + *pbyPhySgn = 0x0a; + else // long preamble + *pbyPhySgn = 0x02; + break; + + case RATE_11M: + + if (bCCK == false) + cbBitCount++; + cbUsCount = cbBitCount / 11; + cbTmp = cbUsCount * 11; + if (cbTmp != cbBitCount) { + cbUsCount++; + if ((cbBitCount - cbTmp) <= 3) + bExtBit = true; + } + if (byPreambleType == 1) + *pbyPhySgn = 0x0b; + else // long preamble + *pbyPhySgn = 0x03; + break; + + case RATE_6M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9B; //1001 1011 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8B; //1000 1011 + } + break; + + case RATE_9M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9F; //1001 1111 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8F; //1000 1111 + } + break; + + case RATE_12M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9A; //1001 1010 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8A; //1000 1010 + } + break; + + case RATE_18M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9E; //1001 1110 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8E; //1000 1110 + } + break; + + case RATE_24M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x99; //1001 1001 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x89; //1000 1001 + } + break; + + case RATE_36M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9D; //1001 1101 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8D; //1000 1101 + } + break; + + case RATE_48M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x98; //1001 1000 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x88; //1000 1000 + } + break; + + case RATE_54M: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9C; //1001 1100 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8C; //1000 1100 + } + break; + + default: + if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ + *pbyPhySgn = 0x9C; //1001 1100 + } + else {//11g, 2.4GHZ + *pbyPhySgn = 0x8C; //1000 1100 + } + break; + } + + if (byPacketType == PK_TYPE_11B) { + *pbyPhySrv = 0x00; + if (bExtBit) + *pbyPhySrv = *pbyPhySrv | 0x80; + *pwPhyLen = (unsigned short)cbUsCount; + } + else { + *pbyPhySrv = 0x00; + *pwPhyLen = (unsigned short)cbFrameLength; + } } /* @@ -2013,32 +2013,32 @@ BBvCalculateParameter ( * Return Value: true if succeeded; false if failed. * */ -bool BBbReadEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) +bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) { - unsigned short ww; - unsigned char byValue; - - // BB reg offset - VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr); - - // turn on REGR - MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGR); - // W_MAX_TIMEOUT is the timeout period - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue); - if (byValue & BBREGCTL_DONE) - break; - } - - // get BB data - VNSvInPortB(dwIoBase + MAC_REG_BBREGDATA, pbyData); - - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x30); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x30)\n"); - return false; - } - return true; + unsigned short ww; + unsigned char byValue; + + // BB reg offset + VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr); + + // turn on REGR + MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGR); + // W_MAX_TIMEOUT is the timeout period + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue); + if (byValue & BBREGCTL_DONE) + break; + } + + // get BB data + VNSvInPortB(dwIoBase + MAC_REG_BBREGDATA, pbyData); + + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x30); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x30)\n"); + return false; + } + return true; } @@ -2056,31 +2056,31 @@ bool BBbReadEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned c * Return Value: true if succeeded; false if failed. * */ -bool BBbWriteEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData) +bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData) { - unsigned short ww; - unsigned char byValue; - - // BB reg offset - VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr); - // set BB data - VNSvOutPortB(dwIoBase + MAC_REG_BBREGDATA, byData); - - // turn on BBREGCTL_REGW - MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGW); - // W_MAX_TIMEOUT is the timeout period - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue); - if (byValue & BBREGCTL_DONE) - break; - } - - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x31); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x31)\n"); - return false; - } - return true; + unsigned short ww; + unsigned char byValue; + + // BB reg offset + VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr); + // set BB data + VNSvOutPortB(dwIoBase + MAC_REG_BBREGDATA, byData); + + // turn on BBREGCTL_REGW + MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGW); + // W_MAX_TIMEOUT is the timeout period + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue); + if (byValue & BBREGCTL_DONE) + break; + } + + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x31); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x31)\n"); + return false; + } + return true; } @@ -2098,12 +2098,12 @@ bool BBbWriteEmbedded (unsigned long dwIoBase, unsigned char byBBAddr, unsigned * Return Value: true if all TestBits are set; false otherwise. * */ -bool BBbIsRegBitsOn (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) +bool BBbIsRegBitsOn(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) { - unsigned char byOrgData; + unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); - return (byOrgData & byTestBits) == byTestBits; + BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); + return (byOrgData & byTestBits) == byTestBits; } @@ -2121,12 +2121,12 @@ bool BBbIsRegBitsOn (unsigned long dwIoBase, unsigned char byBBAddr, unsigned ch * Return Value: true if all TestBits are clear; false otherwise. * */ -bool BBbIsRegBitsOff (unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) +bool BBbIsRegBitsOff(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits) { - unsigned char byOrgData; + unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); - return (byOrgData & byTestBits) == 0; + BBbReadEmbedded(dwIoBase, byBBAddr, &byOrgData); + return (byOrgData & byTestBits) == 0; } /* @@ -2144,164 +2144,164 @@ bool BBbIsRegBitsOff (unsigned long dwIoBase, unsigned char byBBAddr, unsigned c * */ -bool BBbVT3253Init (PSDevice pDevice) +bool BBbVT3253Init(PSDevice pDevice) { - bool bResult = true; - int ii; - unsigned long dwIoBase = pDevice->PortOffset; - unsigned char byRFType = pDevice->byRFType; - unsigned char byLocalID = pDevice->byLocalID; - - if (byRFType == RF_RFMD2959) { - if (byLocalID <= REV_ID_VT3253_A1) { - for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253InitTab_RFMD[ii][0],byVT3253InitTab_RFMD[ii][1]); - } - } else { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_RFMD[ii][0],byVT3253B0_RFMD[ii][1]); - } - for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC4_RFMD2959[ii][0],byVT3253B0_AGC4_RFMD2959[ii][1]); - } - VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); - } - pDevice->abyBBVGA[0] = 0x18; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S) ) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); - } - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); - } - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - } else if (byRFType == RF_UW2451) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); - } - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); - } - VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); - - pDevice->abyBBVGA[0] = 0x14; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -60; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - } else if (byRFType == RF_UW2452) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_UW2451[ii][0],byVT3253B0_UW2451[ii][1]); - } - // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); - // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); - // Select VC1/VC2, CR215 = 0x02->0x06 - bResult &= BBbWriteEmbedded(dwIoBase,0xd7,0x06); - - //{{RobertYu:20050125, request by Jack - bResult &= BBbWriteEmbedded(dwIoBase,0x90,0x20); - bResult &= BBbWriteEmbedded(dwIoBase,0x97,0xeb); - //}} - - //{{RobertYu:20050221, request by Jack - bResult &= BBbWriteEmbedded(dwIoBase,0xa6,0x00); - bResult &= BBbWriteEmbedded(dwIoBase,0xa8,0x30); - //}} - bResult &= BBbWriteEmbedded(dwIoBase,0xb0,0x58); - - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); - } - //VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); // RobertYu: 20050104, 20050131 disable PA_Delay - //MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); // RobertYu: 20050104, 20050131 disable PA_Delay - - pDevice->abyBBVGA[0] = 0x14; - pDevice->abyBBVGA[1] = 0x0A; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -60; - pDevice->ldBmThreshold[1] = -50; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - //}} RobertYu - - } else if (byRFType == RF_VT3226) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); - } - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); - } - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - // Fix VT3226 DFC system timing issue - MACvSetRFLE_LatchBase(dwIoBase); - //{{ RobertYu: 20050104 - } else if (byRFType == RF_AIROHA7230) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AIROHA2230[ii][0],byVT3253B0_AIROHA2230[ii][1]); - } - - //{{ RobertYu:20050223, request by JerryChung - // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); - // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); - // Select VC1/VC2, CR215 = 0x02->0x06 - bResult &= BBbWriteEmbedded(dwIoBase,0xd7,0x06); - //}} - - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { - bResult &= BBbWriteEmbedded(dwIoBase,byVT3253B0_AGC[ii][0],byVT3253B0_AGC[ii][1]); - } - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - //}} RobertYu - } else { - // No VGA Table now - pDevice->bUpdateBBVGA = false; - pDevice->abyBBVGA[0] = 0x1C; - } - - if (byLocalID > REV_ID_VT3253_A1) { - BBbWriteEmbedded(dwIoBase, 0x04, 0x7F); - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); - } - - return bResult; + bool bResult = true; + int ii; + unsigned long dwIoBase = pDevice->PortOffset; + unsigned char byRFType = pDevice->byRFType; + unsigned char byLocalID = pDevice->byLocalID; + + if (byRFType == RF_RFMD2959) { + if (byLocalID <= REV_ID_VT3253_A1) { + for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253InitTab_RFMD[ii][0], byVT3253InitTab_RFMD[ii][1]); + } + } else { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_RFMD[ii][0], byVT3253B0_RFMD[ii][1]); + } + for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); + } + VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); + } + pDevice->abyBBVGA[0] = 0x18; + pDevice->abyBBVGA[1] = 0x0A; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -70; + pDevice->ldBmThreshold[1] = -50; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S)) { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + } + for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + } + pDevice->abyBBVGA[0] = 0x1C; + pDevice->abyBBVGA[1] = 0x10; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -70; + pDevice->ldBmThreshold[1] = -48; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + } else if (byRFType == RF_UW2451) { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + } + for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + } + VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); + + pDevice->abyBBVGA[0] = 0x14; + pDevice->abyBBVGA[1] = 0x0A; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -60; + pDevice->ldBmThreshold[1] = -50; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + } else if (byRFType == RF_UW2452) { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + } + // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) + //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); + // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) + //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); + // Select VC1/VC2, CR215 = 0x02->0x06 + bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + + //{{RobertYu:20050125, request by Jack + bResult &= BBbWriteEmbedded(dwIoBase, 0x90, 0x20); + bResult &= BBbWriteEmbedded(dwIoBase, 0x97, 0xeb); + //}} + + //{{RobertYu:20050221, request by Jack + bResult &= BBbWriteEmbedded(dwIoBase, 0xa6, 0x00); + bResult &= BBbWriteEmbedded(dwIoBase, 0xa8, 0x30); + //}} + bResult &= BBbWriteEmbedded(dwIoBase, 0xb0, 0x58); + + for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + } + //VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); // RobertYu: 20050104, 20050131 disable PA_Delay + //MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); // RobertYu: 20050104, 20050131 disable PA_Delay + + pDevice->abyBBVGA[0] = 0x14; + pDevice->abyBBVGA[1] = 0x0A; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -60; + pDevice->ldBmThreshold[1] = -50; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + //}} RobertYu + + } else if (byRFType == RF_VT3226) { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + } + for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + } + pDevice->abyBBVGA[0] = 0x1C; + pDevice->abyBBVGA[1] = 0x10; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -70; + pDevice->ldBmThreshold[1] = -48; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + // Fix VT3226 DFC system timing issue + MACvSetRFLE_LatchBase(dwIoBase); + //{{ RobertYu: 20050104 + } else if (byRFType == RF_AIROHA7230) { + for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + } + + //{{ RobertYu:20050223, request by JerryChung + // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) + //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41); + // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) + //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28); + // Select VC1/VC2, CR215 = 0x02->0x06 + bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + //}} + + for (ii = 0; ii < CB_VT3253B0_AGC; ii++) { + bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + } + pDevice->abyBBVGA[0] = 0x1C; + pDevice->abyBBVGA[1] = 0x10; + pDevice->abyBBVGA[2] = 0x0; + pDevice->abyBBVGA[3] = 0x0; + pDevice->ldBmThreshold[0] = -70; + pDevice->ldBmThreshold[1] = -48; + pDevice->ldBmThreshold[2] = 0; + pDevice->ldBmThreshold[3] = 0; + //}} RobertYu + } else { + // No VGA Table now + pDevice->bUpdateBBVGA = false; + pDevice->abyBBVGA[0] = 0x1C; + } + + if (byLocalID > REV_ID_VT3253_A1) { + BBbWriteEmbedded(dwIoBase, 0x04, 0x7F); + BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); + } + + return bResult; } @@ -2319,14 +2319,14 @@ bool BBbVT3253Init (PSDevice pDevice) * Return Value: none * */ -void BBvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyBBRegs) +void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs) { - int ii; - unsigned char byBase = 1; - for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) { - BBbReadEmbedded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs); - pbyBBRegs += byBase; - } + int ii; + unsigned char byBase = 1; + for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) { + BBbReadEmbedded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs); + pbyBBRegs += byBase; + } } /* @@ -2344,45 +2344,45 @@ void BBvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyBBRegs) */ -void BBvLoopbackOn (PSDevice pDevice) +void BBvLoopbackOn(PSDevice pDevice) { - unsigned char byData; - unsigned long dwIoBase = pDevice->PortOffset; - - //CR C9 = 0x00 - BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201 - BBbWriteEmbedded(dwIoBase, 0xC9, 0); - BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77 - BBbWriteEmbedded(dwIoBase, 0x4D, 0x90); - - //CR 88 = 0x02(CCK), 0x03(OFDM) - BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136 - - if (pDevice->uConnectionRate <= RATE_11M) { //CCK - // Enable internal digital loopback: CR33 |= 0000 0001 - BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 - BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33 - // CR154 = 0x00 - BBbWriteEmbedded(dwIoBase, 0x9A, 0); //CR154 - - BBbWriteEmbedded(dwIoBase, 0x88, 0x02);//CR239 - } - else { //OFDM - // Enable internal digital loopback:CR154 |= 0000 0001 - BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 - BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154 - // CR33 = 0x00 - BBbWriteEmbedded(dwIoBase, 0x21, 0); //CR33 - - BBbWriteEmbedded(dwIoBase, 0x88, 0x03);//CR239 - } - - //CR14 = 0x00 - BBbWriteEmbedded(dwIoBase, 0x0E, 0);//CR14 - - // Disable TX_IQUN - BBbReadEmbedded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09); - BBbWriteEmbedded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE)); + unsigned char byData; + unsigned long dwIoBase = pDevice->PortOffset; + + //CR C9 = 0x00 + BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201 + BBbWriteEmbedded(dwIoBase, 0xC9, 0); + BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77 + BBbWriteEmbedded(dwIoBase, 0x4D, 0x90); + + //CR 88 = 0x02(CCK), 0x03(OFDM) + BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136 + + if (pDevice->uConnectionRate <= RATE_11M) { //CCK + // Enable internal digital loopback: CR33 |= 0000 0001 + BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 + BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33 + // CR154 = 0x00 + BBbWriteEmbedded(dwIoBase, 0x9A, 0); //CR154 + + BBbWriteEmbedded(dwIoBase, 0x88, 0x02);//CR239 + } + else { //OFDM + // Enable internal digital loopback:CR154 |= 0000 0001 + BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 + BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154 + // CR33 = 0x00 + BBbWriteEmbedded(dwIoBase, 0x21, 0); //CR33 + + BBbWriteEmbedded(dwIoBase, 0x88, 0x03);//CR239 + } + + //CR14 = 0x00 + BBbWriteEmbedded(dwIoBase, 0x0E, 0);//CR14 + + // Disable TX_IQUN + BBbReadEmbedded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09); + BBbWriteEmbedded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE)); } /* @@ -2398,27 +2398,27 @@ void BBvLoopbackOn (PSDevice pDevice) * Return Value: none * */ -void BBvLoopbackOff (PSDevice pDevice) +void BBvLoopbackOff(PSDevice pDevice) { - unsigned char byData; - unsigned long dwIoBase = pDevice->PortOffset; - - BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201 - BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136 - BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136 - BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77 - - if (pDevice->uConnectionRate <= RATE_11M) { // CCK - // Set the CR33 Bit2 to disable internal Loopback. - BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 - BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33 - } - else { // OFDM - BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 - BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154 - } - BBbReadEmbedded(dwIoBase, 0x0E, &byData);//CR14 - BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14 + unsigned char byData; + unsigned long dwIoBase = pDevice->PortOffset; + + BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201 + BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136 + BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136 + BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77 + + if (pDevice->uConnectionRate <= RATE_11M) { // CCK + // Set the CR33 Bit2 to disable internal Loopback. + BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33 + BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33 + } + else { // OFDM + BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154 + BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154 + } + BBbReadEmbedded(dwIoBase, 0x0E, &byData);//CR14 + BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14 } @@ -2437,46 +2437,46 @@ void BBvLoopbackOff (PSDevice pDevice) * */ void -BBvSetShortSlotTime (PSDevice pDevice) +BBvSetShortSlotTime(PSDevice pDevice) { - unsigned char byBBRxConf=0; - unsigned char byBBVGA=0; + unsigned char byBBRxConf = 0; + unsigned char byBBVGA = 0; - BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 + BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 - if (pDevice->bShortSlotTime) { - byBBRxConf &= 0xDF;//1101 1111 - } else { - byBBRxConf |= 0x20;//0010 0000 - } + if (pDevice->bShortSlotTime) { + byBBRxConf &= 0xDF;//1101 1111 + } else { + byBBRxConf |= 0x20;//0010 0000 + } - // patch for 3253B0 Baseband with Cardbus module - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byBBVGA); - if (byBBVGA == pDevice->abyBBVGA[0]) { - byBBRxConf |= 0x20;//0010 0000 - } + // patch for 3253B0 Baseband with Cardbus module + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byBBVGA); + if (byBBVGA == pDevice->abyBBVGA[0]) { + byBBRxConf |= 0x20;//0010 0000 + } - BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 + BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 } void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) { - unsigned char byBBRxConf=0; - - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, byData); - - BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 - // patch for 3253B0 Baseband with Cardbus module - if (byData == pDevice->abyBBVGA[0]) { - byBBRxConf |= 0x20;//0010 0000 - } else if (pDevice->bShortSlotTime) { - byBBRxConf &= 0xDF;//1101 1111 - } else { - byBBRxConf |= 0x20;//0010 0000 - } - pDevice->byBBVGACurrent = byData; - BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 + unsigned char byBBRxConf = 0; + + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, byData); + + BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10 + // patch for 3253B0 Baseband with Cardbus module + if (byData == pDevice->abyBBVGA[0]) { + byBBRxConf |= 0x20;//0010 0000 + } else if (pDevice->bShortSlotTime) { + byBBRxConf &= 0xDF;//1101 1111 + } else { + byBBRxConf |= 0x20;//0010 0000 + } + pDevice->byBBVGACurrent = byData; + BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10 } @@ -2493,12 +2493,12 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) * */ void -BBvSoftwareReset (unsigned long dwIoBase) +BBvSoftwareReset(unsigned long dwIoBase) { - BBbWriteEmbedded(dwIoBase, 0x50, 0x40); - BBbWriteEmbedded(dwIoBase, 0x50, 0); - BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); - BBbWriteEmbedded(dwIoBase, 0x9C, 0); + BBbWriteEmbedded(dwIoBase, 0x50, 0x40); + BBbWriteEmbedded(dwIoBase, 0x50, 0); + BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); + BBbWriteEmbedded(dwIoBase, 0x9C, 0); } /* @@ -2514,13 +2514,13 @@ BBvSoftwareReset (unsigned long dwIoBase) * */ void -BBvPowerSaveModeON (unsigned long dwIoBase) +BBvPowerSaveModeON(unsigned long dwIoBase) { - unsigned char byOrgData; + unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData |= BIT0; - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); + byOrgData |= BIT0; + BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } /* @@ -2536,13 +2536,13 @@ BBvPowerSaveModeON (unsigned long dwIoBase) * */ void -BBvPowerSaveModeOFF (unsigned long dwIoBase) +BBvPowerSaveModeOFF(unsigned long dwIoBase) { - unsigned char byOrgData; + unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData &= ~(BIT0); - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); + byOrgData &= ~(BIT0); + BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } /* @@ -2560,28 +2560,28 @@ BBvPowerSaveModeOFF (unsigned long dwIoBase) */ void -BBvSetTxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) +BBvSetTxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode) { - unsigned char byBBTxConf; + unsigned char byBBTxConf; #ifdef PLICE_DEBUG //printk("Enter BBvSetTxAntennaMode\n"); #endif - BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf);//CR09 - if (byAntennaMode == ANT_DIVERSITY) { - // bit 1 is diversity - byBBTxConf |= 0x02; - } else if (byAntennaMode == ANT_A) { - // bit 2 is ANTSEL - byBBTxConf &= 0xF9; // 1111 1001 - } else if (byAntennaMode == ANT_B) { + BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf);//CR09 + if (byAntennaMode == ANT_DIVERSITY) { + // bit 1 is diversity + byBBTxConf |= 0x02; + } else if (byAntennaMode == ANT_A) { + // bit 2 is ANTSEL + byBBTxConf &= 0xF9; // 1111 1001 + } else if (byAntennaMode == ANT_B) { #ifdef PLICE_DEBUG - //printk("BBvSetTxAntennaMode:ANT_B\n"); + //printk("BBvSetTxAntennaMode:ANT_B\n"); #endif - byBBTxConf &= 0xFD; // 1111 1101 - byBBTxConf |= 0x04; - } - BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf);//CR09 + byBBTxConf &= 0xFD; // 1111 1101 + byBBTxConf |= 0x04; + } + BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf);//CR09 } @@ -2602,21 +2602,21 @@ BBvSetTxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) */ void -BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) +BBvSetRxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode) { - unsigned char byBBRxConf; - - BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf);//CR10 - if (byAntennaMode == ANT_DIVERSITY) { - byBBRxConf |= 0x01; - - } else if (byAntennaMode == ANT_A) { - byBBRxConf &= 0xFC; // 1111 1100 - } else if (byAntennaMode == ANT_B) { - byBBRxConf &= 0xFE; // 1111 1110 - byBBRxConf |= 0x02; - } - BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf);//CR10 + unsigned char byBBRxConf; + + BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf);//CR10 + if (byAntennaMode == ANT_DIVERSITY) { + byBBRxConf |= 0x01; + + } else if (byAntennaMode == ANT_A) { + byBBRxConf &= 0xFC; // 1111 1100 + } else if (byAntennaMode == ANT_B) { + byBBRxConf &= 0xFE; // 1111 1110 + byBBRxConf |= 0x02; + } + BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf);//CR10 } @@ -2633,139 +2633,139 @@ BBvSetRxAntennaMode (unsigned long dwIoBase, unsigned char byAntennaMode) * */ void -BBvSetDeepSleep (unsigned long dwIoBase, unsigned char byLocalID) +BBvSetDeepSleep(unsigned long dwIoBase, unsigned char byLocalID) { - BBbWriteEmbedded(dwIoBase, 0x0C, 0x17);//CR12 - BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9);//CR13 + BBbWriteEmbedded(dwIoBase, 0x0C, 0x17);//CR12 + BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9);//CR13 } void -BBvExitDeepSleep (unsigned long dwIoBase, unsigned char byLocalID) +BBvExitDeepSleep(unsigned long dwIoBase, unsigned char byLocalID) { - BBbWriteEmbedded(dwIoBase, 0x0C, 0x00);//CR12 - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01);//CR13 + BBbWriteEmbedded(dwIoBase, 0x0C, 0x00);//CR12 + BBbWriteEmbedded(dwIoBase, 0x0D, 0x01);//CR13 } static unsigned long -s_ulGetRatio (PSDevice pDevice) +s_ulGetRatio(PSDevice pDevice) { -unsigned long ulRatio = 0; -unsigned long ulMaxPacket; -unsigned long ulPacketNum; - - //This is a thousand-ratio - ulMaxPacket = pDevice->uNumSQ3[RATE_54M]; - if ( pDevice->uNumSQ3[RATE_54M] != 0 ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_54M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_54M; - } - if ( pDevice->uNumSQ3[RATE_48M] > ulMaxPacket ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_48M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_48M; - ulMaxPacket = pDevice->uNumSQ3[RATE_48M]; - } - if ( pDevice->uNumSQ3[RATE_36M] > ulMaxPacket ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_36M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_36M; - ulMaxPacket = pDevice->uNumSQ3[RATE_36M]; - } - if ( pDevice->uNumSQ3[RATE_24M] > ulMaxPacket ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_24M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_24M; - ulMaxPacket = pDevice->uNumSQ3[RATE_24M]; - } - if ( pDevice->uNumSQ3[RATE_18M] > ulMaxPacket ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + - pDevice->uNumSQ3[RATE_18M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_18M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_18M; - ulMaxPacket = pDevice->uNumSQ3[RATE_18M]; - } - if ( pDevice->uNumSQ3[RATE_12M] > ulMaxPacket ) { - ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + - pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + - pDevice->uNumSQ3[RATE_18M] + pDevice->uNumSQ3[RATE_12M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_12M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_12M; - ulMaxPacket = pDevice->uNumSQ3[RATE_12M]; - } - if ( pDevice->uNumSQ3[RATE_11M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - - pDevice->uNumSQ3[RATE_6M] - pDevice->uNumSQ3[RATE_9M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_11M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_11M; - ulMaxPacket = pDevice->uNumSQ3[RATE_11M]; - } - if ( pDevice->uNumSQ3[RATE_9M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - - pDevice->uNumSQ3[RATE_6M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_9M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_9M; - ulMaxPacket = pDevice->uNumSQ3[RATE_9M]; - } - if ( pDevice->uNumSQ3[RATE_6M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_6M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_6M; - ulMaxPacket = pDevice->uNumSQ3[RATE_6M]; - } - if ( pDevice->uNumSQ3[RATE_5M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - - pDevice->uNumSQ3[RATE_2M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_5M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_55M; - ulMaxPacket = pDevice->uNumSQ3[RATE_5M]; - } - if ( pDevice->uNumSQ3[RATE_2M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M]; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_2M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_2M; - ulMaxPacket = pDevice->uNumSQ3[RATE_2M]; - } - if ( pDevice->uNumSQ3[RATE_1M] > ulMaxPacket ) { - ulPacketNum = pDevice->uDiversityCnt; - ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); - //ulRatio = (pDevice->uNumSQ3[RATE_1M] * 1000 / pDevice->uDiversityCnt); - ulRatio += TOP_RATE_1M; - } - - return ulRatio; + unsigned long ulRatio = 0; + unsigned long ulMaxPacket; + unsigned long ulPacketNum; + + //This is a thousand-ratio + ulMaxPacket = pDevice->uNumSQ3[RATE_54M]; + if (pDevice->uNumSQ3[RATE_54M] != 0) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_54M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_54M; + } + if (pDevice->uNumSQ3[RATE_48M] > ulMaxPacket) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_48M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_48M; + ulMaxPacket = pDevice->uNumSQ3[RATE_48M]; + } + if (pDevice->uNumSQ3[RATE_36M] > ulMaxPacket) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + + pDevice->uNumSQ3[RATE_36M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_36M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_36M; + ulMaxPacket = pDevice->uNumSQ3[RATE_36M]; + } + if (pDevice->uNumSQ3[RATE_24M] > ulMaxPacket) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + + pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_24M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_24M; + ulMaxPacket = pDevice->uNumSQ3[RATE_24M]; + } + if (pDevice->uNumSQ3[RATE_18M] > ulMaxPacket) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + + pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + + pDevice->uNumSQ3[RATE_18M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_18M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_18M; + ulMaxPacket = pDevice->uNumSQ3[RATE_18M]; + } + if (pDevice->uNumSQ3[RATE_12M] > ulMaxPacket) { + ulPacketNum = pDevice->uNumSQ3[RATE_54M] + pDevice->uNumSQ3[RATE_48M] + + pDevice->uNumSQ3[RATE_36M] + pDevice->uNumSQ3[RATE_24M] + + pDevice->uNumSQ3[RATE_18M] + pDevice->uNumSQ3[RATE_12M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_12M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_12M; + ulMaxPacket = pDevice->uNumSQ3[RATE_12M]; + } + if (pDevice->uNumSQ3[RATE_11M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - + pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - + pDevice->uNumSQ3[RATE_6M] - pDevice->uNumSQ3[RATE_9M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_11M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_11M; + ulMaxPacket = pDevice->uNumSQ3[RATE_11M]; + } + if (pDevice->uNumSQ3[RATE_9M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - + pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M] - + pDevice->uNumSQ3[RATE_6M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_9M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_9M; + ulMaxPacket = pDevice->uNumSQ3[RATE_9M]; + } + if (pDevice->uNumSQ3[RATE_6M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - + pDevice->uNumSQ3[RATE_2M] - pDevice->uNumSQ3[RATE_5M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_6M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_6M; + ulMaxPacket = pDevice->uNumSQ3[RATE_6M]; + } + if (pDevice->uNumSQ3[RATE_5M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M] - + pDevice->uNumSQ3[RATE_2M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_5M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_55M; + ulMaxPacket = pDevice->uNumSQ3[RATE_5M]; + } + if (pDevice->uNumSQ3[RATE_2M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt - pDevice->uNumSQ3[RATE_1M]; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_2M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_2M; + ulMaxPacket = pDevice->uNumSQ3[RATE_2M]; + } + if (pDevice->uNumSQ3[RATE_1M] > ulMaxPacket) { + ulPacketNum = pDevice->uDiversityCnt; + ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt); + //ulRatio = (pDevice->uNumSQ3[RATE_1M] * 1000 / pDevice->uDiversityCnt); + ulRatio += TOP_RATE_1M; + } + + return ulRatio; } void -BBvClearAntDivSQ3Value (PSDevice pDevice) +BBvClearAntDivSQ3Value(PSDevice pDevice) { - unsigned int ii; + unsigned int ii; - pDevice->uDiversityCnt = 0; - for (ii = 0; ii < MAX_RATE; ii++) { - pDevice->uNumSQ3[ii] = 0; - } + pDevice->uDiversityCnt = 0; + for (ii = 0; ii < MAX_RATE; ii++) { + pDevice->uNumSQ3[ii] = 0; + } } @@ -2785,79 +2785,79 @@ BBvClearAntDivSQ3Value (PSDevice pDevice) */ void -BBvAntennaDiversity (PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3) +BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3) { - if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) { - return; - } - pDevice->uDiversityCnt++; - // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt); + if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) { + return; + } + pDevice->uDiversityCnt++; + // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt); - pDevice->uNumSQ3[byRxRate]++; + pDevice->uNumSQ3[byRxRate]++; - if (pDevice->byAntennaState == 0) { + if (pDevice->byAntennaState == 0) { - if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n", - (int)pDevice->ulDiversityNValue, (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]); + if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ulDiversityNValue=[%d],54M-[%d]\n", + (int)pDevice->ulDiversityNValue, (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]); - if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) { + if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) { - pDevice->ulRatio_State0 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0); + pDevice->ulRatio_State0 = s_ulGetRatio(pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0); - if ( pDevice->byTMax == 0 ) - return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1.[%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + if (pDevice->byTMax == 0) + return; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1.[%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); #ifdef PLICE_DEBUG - //printk("BBvAntennaDiversity1:call s_vChangeAntenna\n"); + //printk("BBvAntennaDiversity1:call s_vChangeAntenna\n"); #endif - s_vChangeAntenna(pDevice); - pDevice->byAntennaState = 1; - del_timer(&pDevice->TimerSQ3Tmax3); - del_timer(&pDevice->TimerSQ3Tmax2); - pDevice->TimerSQ3Tmax1.expires = RUN_AT(pDevice->byTMax * HZ); - add_timer(&pDevice->TimerSQ3Tmax1); + s_vChangeAntenna(pDevice); + pDevice->byAntennaState = 1; + del_timer(&pDevice->TimerSQ3Tmax3); + del_timer(&pDevice->TimerSQ3Tmax2); + pDevice->TimerSQ3Tmax1.expires = RUN_AT(pDevice->byTMax * HZ); + add_timer(&pDevice->TimerSQ3Tmax1); - } else { + } else { - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - } - BBvClearAntDivSQ3Value(pDevice); + pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); + add_timer(&pDevice->TimerSQ3Tmax3); + } + BBvClearAntDivSQ3Value(pDevice); - } - } else { //byAntennaState == 1 + } + } else { //byAntennaState == 1 - if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) { + if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) { - del_timer(&pDevice->TimerSQ3Tmax1); + del_timer(&pDevice->TimerSQ3Tmax1); - pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1); + pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n", + (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1); - if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, + (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); #ifdef PLICE_DEBUG - //printk("BBvAntennaDiversity2:call s_vChangeAntenna\n"); + //printk("BBvAntennaDiversity2:call s_vChangeAntenna\n"); #endif s_vChangeAntenna(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); - } - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); - } - } //byAntennaState + pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); + pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); + add_timer(&pDevice->TimerSQ3Tmax3); + add_timer(&pDevice->TimerSQ3Tmax2); + } + pDevice->byAntennaState = 0; + BBvClearAntDivSQ3Value(pDevice); + } + } //byAntennaState } /*+ @@ -2872,35 +2872,35 @@ BBvAntennaDiversity (PSDevice pDevice, unsigned char byRxRate, unsigned char byS * * Return Value: none * --*/ + -*/ void -TimerSQ3CallBack ( - void *hDeviceContext - ) +TimerSQ3CallBack( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack..."); - spin_lock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerSQ3CallBack..."); + spin_lock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.[%08x][%08x], %d\n",(int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.[%08x][%08x], %d\n", (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt); #ifdef PLICE_DEBUG - //printk("TimerSQ3CallBack1:call s_vChangeAntenna\n"); + //printk("TimerSQ3CallBack1:call s_vChangeAntenna\n"); #endif - s_vChangeAntenna(pDevice); - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); + s_vChangeAntenna(pDevice); + pDevice->byAntennaState = 0; + BBvClearAntDivSQ3Value(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); + pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); + pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); + add_timer(&pDevice->TimerSQ3Tmax3); + add_timer(&pDevice->TimerSQ3Tmax2); - spin_unlock_irq(&pDevice->lock); - return; + spin_unlock_irq(&pDevice->lock); + return; } @@ -2920,54 +2920,54 @@ TimerSQ3CallBack ( * * Return Value: none * --*/ + -*/ void -TimerState1CallBack ( - void *hDeviceContext - ) +TimerState1CallBack( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerState1CallBack..."); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerState1CallBack..."); - spin_lock_irq(&pDevice->lock); - if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) { + spin_lock_irq(&pDevice->lock); + if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) { #ifdef PLICE_DEBUG //printk("TimerSQ3CallBack2:call s_vChangeAntenna\n"); #endif s_vChangeAntenna(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); - } else { - pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1); - - if ( pDevice->ulRatio_State1 < pDevice->ulRatio_State0 ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); + pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); + add_timer(&pDevice->TimerSQ3Tmax3); + add_timer(&pDevice->TimerSQ3Tmax2); + } else { + pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SQ3_State1, rate0 = %08x,rate1 = %08x\n", + (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1); + + if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, + (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); #ifdef PLICE_DEBUG - //printk("TimerSQ3CallBack3:call s_vChangeAntenna\n"); + //printk("TimerSQ3CallBack3:call s_vChangeAntenna\n"); #endif s_vChangeAntenna(pDevice); - pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); - pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); - add_timer(&pDevice->TimerSQ3Tmax3); - add_timer(&pDevice->TimerSQ3Tmax2); - } - } - pDevice->byAntennaState = 0; - BBvClearAntDivSQ3Value(pDevice); - spin_unlock_irq(&pDevice->lock); - - return; + pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); + pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); + add_timer(&pDevice->TimerSQ3Tmax3); + add_timer(&pDevice->TimerSQ3Tmax2); + } + } + pDevice->byAntennaState = 0; + BBvClearAntDivSQ3Value(pDevice); + spin_unlock_irq(&pDevice->lock); + + return; } diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 9b5bc9c58d9f..c9e947d63f92 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -71,15 +71,15 @@ /*--------------------- Export Macros ------------------------------*/ -#define BBvClearFOE(dwIoBase) \ -{ \ - BBbWriteEmbedded(dwIoBase, 0xB1, 0); \ -} +#define BBvClearFOE(dwIoBase) \ + { \ + BBbWriteEmbedded(dwIoBase, 0xB1, 0); \ + } -#define BBvSetFOE(dwIoBase) \ -{ \ - BBbWriteEmbedded(dwIoBase, 0xB1, 0x0C); \ -} +#define BBvSetFOE(dwIoBase) \ + { \ + BBbWriteEmbedded(dwIoBase, 0xB1, 0x0C); \ + } /*--------------------- Export Classes ----------------------------*/ @@ -90,22 +90,22 @@ unsigned int BBuGetFrameTime( - unsigned char byPreambleType, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate - ); + unsigned char byPreambleType, + unsigned char byPktType, + unsigned int cbFrameLength, + unsigned short wRate +); void -BBvCalculateParameter ( - PSDevice pDevice, - unsigned int cbFrameLength, - unsigned short wRate, - unsigned char byPacketType, - unsigned short *pwPhyLen, - unsigned char *pbyPhySrv, - unsigned char *pbyPhySgn - ); +BBvCalculateParameter( + PSDevice pDevice, + unsigned int cbFrameLength, + unsigned short wRate, + unsigned char byPacketType, + unsigned short *pwPhyLen, + unsigned char *pbyPhySrv, + unsigned char *pbyPhySgn +); bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData); @@ -131,17 +131,17 @@ void BBvExitDeepSleep(unsigned long dwIoBase, unsigned char byLocalID); // timer for antenna diversity void -TimerSQ3CallBack ( - void *hDeviceContext - ); +TimerSQ3CallBack( + void *hDeviceContext +); void TimerState1CallBack( - void *hDeviceContext - ); + void *hDeviceContext +); void BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3); void -BBvClearAntDivSQ3Value (PSDevice pDevice); +BBvClearAntDivSQ3Value(PSDevice pDevice); #endif // __BASEBAND_H__ -- cgit From e1c775793803e53b9c0dfd7d85ccc57630b7afa8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:39 -0700 Subject: staging:vt6655:bssdb: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/bssdb.c | 2648 ++++++++++++++++++++-------------------- drivers/staging/vt6655/bssdb.h | 396 +++--- 2 files changed, 1522 insertions(+), 1522 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index fe57fb880a8f..3bb3e7fa82e8 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -66,44 +66,44 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; const unsigned short awHWRetry0[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, - {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, - {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} - }; + {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, + {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, + {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} +}; const unsigned short awHWRetry1[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} - }; + {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} +}; /*--------------------- Static Functions --------------------------*/ void s_vCheckSensitivity( - void *hDeviceContext - ); + void *hDeviceContext +); #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - void *hDeviceContext - ); + void *hDeviceContext +); #endif void s_vCheckPreEDThreshold( - void *hDeviceContext - ); + void *hDeviceContext +); /*--------------------- Export Variables --------------------------*/ @@ -121,149 +121,149 @@ void s_vCheckPreEDThreshold( * Return Value: * PTR to KnownBSS or NULL * --*/ + -*/ PKnownBSS BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType - ) + void *hDeviceContext, + unsigned char *pbyDesireBSSID, + unsigned char *pbyDesireSSID, + CARD_PHY_TYPE ePhyType +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char *pbyBSSID = NULL; - PWLAN_IE_SSID pSSID = NULL; - PKnownBSS pCurrBSS = NULL; - PKnownBSS pSelect = NULL; - unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; - unsigned int ii = 0; - - if (pbyDesireBSSID != NULL) { + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned char *pbyBSSID = NULL; + PWLAN_IE_SSID pSSID = NULL; + PKnownBSS pCurrBSS = NULL; + PKnownBSS pSelect = NULL; + unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned int ii = 0; + + if (pbyDesireBSSID != NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); - if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && - (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){ - pbyBSSID = pbyDesireBSSID; - } - } - if (pbyDesireSSID != NULL) { - if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) { - pSSID = (PWLAN_IE_SSID) pbyDesireSSID; - } - } - - if (pbyBSSID != NULL) { - // match BSSID first - for (ii = 0; ii sBSSList[ii]); -if(pDevice->bLinkPass==false) pCurrBSS->bSelected = false; - if ((pCurrBSS->bActive) && - (pCurrBSS->bSelected == false)) { - if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) { - if (pSSID != NULL) { - // compare ssid - if ( !memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len)) { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) - ) { - pCurrBSS->bSelected = true; - return(pCurrBSS); - } - } - } else { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) - ) { - pCurrBSS->bSelected = true; - return(pCurrBSS); - } - } - } - } - } - } else { - // ignore BSSID - for (ii = 0; ii sBSSList[ii]); - //2007-0721-01by MikeLiu - pCurrBSS->bSelected = false; - if (pCurrBSS->bActive) { - - if (pSSID != NULL) { - // matched SSID - if (! !memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len) || - (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) { - // SSID not match skip this BSS - continue; - } - } - if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) - ){ - // Type not match skip this BSS - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo); - continue; - } - - if (ePhyType != PHY_TYPE_AUTO) { - if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) || - ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) { - // PhyType not match skip this BSS - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse); - continue; - } - } + if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && + (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) { + pbyBSSID = pbyDesireBSSID; + } + } + if (pbyDesireSSID != NULL) { + if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) { + pSSID = (PWLAN_IE_SSID) pbyDesireSSID; + } + } + + if (pbyBSSID != NULL) { + // match BSSID first + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pCurrBSS = &(pMgmt->sBSSList[ii]); + if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false; + if ((pCurrBSS->bActive) && + (pCurrBSS->bSelected == false)) { + if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) { + if (pSSID != NULL) { + // compare ssid + if (!memcmp(pSSID->abySSID, + ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, + pSSID->len)) { + if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || + ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || + ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) +) { + pCurrBSS->bSelected = true; + return(pCurrBSS); + } + } + } else { + if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || + ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || + ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) +) { + pCurrBSS->bSelected = true; + return(pCurrBSS); + } + } + } + } + } + } else { + // ignore BSSID + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pCurrBSS = &(pMgmt->sBSSList[ii]); + //2007-0721-01by MikeLiu + pCurrBSS->bSelected = false; + if (pCurrBSS->bActive) { + + if (pSSID != NULL) { + // matched SSID + if (!!memcmp(pSSID->abySSID, + ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, + pSSID->len) || + (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) { + // SSID not match skip this BSS + continue; + } + } + if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) || + ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) +) { + // Type not match skip this BSS + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo); + continue; + } + + if (ePhyType != PHY_TYPE_AUTO) { + if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) || + ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) { + // PhyType not match skip this BSS + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse); + continue; + } + } /* - if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) { - if (pCurrBSS->bWPAValid == true) { - // WPA AP will reject connection of station without WPA enable. - continue; - } - } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { - if (pCurrBSS->bWPAValid == false) { - // station with WPA enable can't join NonWPA AP. - continue; - } - } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if (pCurrBSS->bWPA2Valid == false) { - // station with WPA2 enable can't join NonWPA2 AP. - continue; - } - } + if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) { + if (pCurrBSS->bWPAValid == true) { + // WPA AP will reject connection of station without WPA enable. + continue; + } + } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { + if (pCurrBSS->bWPAValid == false) { + // station with WPA enable can't join NonWPA AP. + continue; + } + } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { + if (pCurrBSS->bWPA2Valid == false) { + // station with WPA2 enable can't join NonWPA2 AP. + continue; + } + } */ - if (pSelect == NULL) { - pSelect = pCurrBSS; - } else { - // compare RSSI, select signal strong one - if (pCurrBSS->uRSSI < pSelect->uRSSI) { - pSelect = pCurrBSS; - } - } - } - } - if (pSelect != NULL) { - pSelect->bSelected = true; + if (pSelect == NULL) { + pSelect = pCurrBSS; + } else { + // compare RSSI, select signal strong one + if (pCurrBSS->uRSSI < pSelect->uRSSI) { + pSelect = pCurrBSS; + } + } + } + } + if (pSelect != NULL) { + pSelect->bSelected = true; /* - if (pDevice->bRoaming == false) { - // Einsn Add @20070907 - memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ; - }*/ + if (pDevice->bRoaming == false) { + // Einsn Add @20070907 + memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + }*/ - return(pSelect); - } - } - return(NULL); + return(pSelect); + } + } + return(NULL); } @@ -276,39 +276,39 @@ if(pDevice->bLinkPass==false) pCurrBSS->bSelected = false; * Return Value: * None. * --*/ + -*/ void BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID - ) + void *hDeviceContext, + bool bKeepCurrBSSID +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (bKeepCurrBSSID) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) { - // bKeepCurrBSSID = false; - continue; - } - } - - if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) { - pMgmt->sBSSList[ii].uClearCount ++; - continue; - } - - pMgmt->sBSSList[ii].bActive = false; - memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS)); - } - BSSvClearAnyBSSJoinRecord(pDevice); - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int ii; + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (bKeepCurrBSSID) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) { + // bKeepCurrBSSID = false; + continue; + } + } + + if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) { + pMgmt->sBSSList[ii].uClearCount++; + continue; + } + + pMgmt->sBSSList[ii].bActive = false; + memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS)); + } + BSSvClearAnyBSSJoinRecord(pDevice); + + return; } @@ -321,36 +321,36 @@ BSSvClearBSSList( * Return Value: * true if found. * --*/ + -*/ PKnownBSS BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID - ) + void *hDeviceContext, + unsigned char *abyBSSID, + PWLAN_IE_SSID pSSID +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pBSSList = NULL; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = &(pMgmt->sBSSList[ii]); - if (pBSSList->bActive) { - if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) { + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PKnownBSS pBSSList = NULL; + unsigned int ii; + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pBSSList = &(pMgmt->sBSSList[ii]); + if (pBSSList->bActive) { + if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) { // if (pSSID == NULL) // return pBSSList; - if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){ - if (memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID, - pSSID->len) == 0) - return pBSSList; - } - } - } - } - - return NULL; + if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) { + if (memcmp(pSSID->abySSID, + ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID, + pSSID->len) == 0) + return pBSSList; + } + } + } + } + + return NULL; }; @@ -363,210 +363,210 @@ BSSpAddrIsInBSSList( * Return Value: * true if success. * --*/ + -*/ bool -BSSbInsertToBSSList ( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - QWORD qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext - ) +BSSbInsertToBSSList( + void *hDeviceContext, + unsigned char *abyBSSIDAddr, + QWORD qwTimestamp, + unsigned short wBeaconInterval, + unsigned short wCapInfo, + unsigned char byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + unsigned int uIELength, + unsigned char *pbyIEs, + void *pRxPacketContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - PKnownBSS pBSSList = NULL; - unsigned int ii; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - - - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]); - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]); - if (!pBSSList->bActive) - break; - } - - if (ii == MAX_BSS_NUM){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n"); - return false; - } - // save the BSS info - pBSSList->bActive = true; - memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); - HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); - LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - memcpy( pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - - pBSSList->uChannel = byCurrChannel; - - if (pSuppRates->len > WLAN_RATES_MAXLEN) - pSuppRates->len = WLAN_RATES_MAXLEN; - memcpy( pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) { - if (pExtSuppRates->len > WLAN_RATES_MAXLEN) - pExtSuppRates->len = WLAN_RATES_MAXLEN; - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len); - - } else { - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - } - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - // Check if BSS is 802.11a/b/g - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist == true) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - } else { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // assoc with BSS - if (pBSSList == pMgmt->pCurrBSS) { - bParsingQuiet = true; - } - } - - WPA_ClearRSN(pBSSList); - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) { - - PSKeyItem pTransmitKey = NULL; - bool bIs802_1x = false; - - for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii ++) { - if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) { - bIs802_1x = true; - break; - } - } - if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && - ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - - bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); - - if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) || - (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) { - pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList; - pDevice->gsPMKIDCandidate.Version = 1; - - } - - } - } - } - - if (pDevice->bUpdateBBVGA) { - // Moniter if RSSI is too strong. - pBSSList->byRSSIStatCnt = 0; - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); - pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; - for (ii = 1; ii < RSSI_STAT_COUNT; ii++) - pBSSList->ldBmAverage[ii] = 0; - } - - if ((pIE_Country != NULL) && - (pMgmt->b11hEnable == true)) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - // valid EID - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet( pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet( pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if ((bParsingQuiet == true) && - (pQuiet != NULL)) { - CARDbStartQuiet(pMgmt->pAdapter); - } - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; + PKnownBSS pBSSList = NULL; + unsigned int ii; + bool bParsingQuiet = false; + PWLAN_IE_QUIET pQuiet = NULL; + + + + pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]); + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]); + if (!pBSSList->bActive) + break; + } + + if (ii == MAX_BSS_NUM) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n"); + return false; + } + // save the BSS info + pBSSList->bActive = true; + memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); + HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); + LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); + pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); + pBSSList->wCapInfo = cpu_to_le16(wCapInfo); + pBSSList->uClearCount = 0; + + if (pSSID->len > WLAN_SSID_MAXLEN) + pSSID->len = WLAN_SSID_MAXLEN; + memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); + + pBSSList->uChannel = byCurrChannel; + + if (pSuppRates->len > WLAN_RATES_MAXLEN) + pSuppRates->len = WLAN_RATES_MAXLEN; + memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); + + if (pExtSuppRates != NULL) { + if (pExtSuppRates->len > WLAN_RATES_MAXLEN) + pExtSuppRates->len = WLAN_RATES_MAXLEN; + memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len); + + } else { + memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + } + pBSSList->sERP.byERP = psERP->byERP; + pBSSList->sERP.bERPExist = psERP->bERPExist; + + // Check if BSS is 802.11a/b/g + if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; + } else { + if (pBSSList->sERP.bERPExist == true) { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; + } else { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; + } + } + + pBSSList->byRxRate = pRxPacket->byRxRate; + pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; + pBSSList->uRSSI = pRxPacket->uRSSI; + pBSSList->bySQ = pRxPacket->bySQ; + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + // assoc with BSS + if (pBSSList == pMgmt->pCurrBSS) { + bParsingQuiet = true; + } + } + + WPA_ClearRSN(pBSSList); + + if (pRSNWPA != NULL) { + unsigned int uLen = pRSNWPA->len + 2; + + if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { + pBSSList->wWPALen = uLen; + memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); + WPA_ParseRSN(pBSSList, pRSNWPA); + } + } + + WPA2_ClearRSN(pBSSList); + + if (pRSN != NULL) { + unsigned int uLen = pRSN->len + 2; + if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { + pBSSList->wRSNLen = uLen; + memcpy(pBSSList->byRSNIE, pRSN, uLen); + WPA2vParseRSN(pBSSList, pRSN); + } + } + + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) { + + PSKeyItem pTransmitKey = NULL; + bool bIs802_1x = false; + + for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii++) { + if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) { + bIs802_1x = true; + break; + } + } + if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && + (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { + + bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); + + if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) || + (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) { + pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList; + pDevice->gsPMKIDCandidate.Version = 1; + + } + + } + } + } + + if (pDevice->bUpdateBBVGA) { + // Moniter if RSSI is too strong. + pBSSList->byRSSIStatCnt = 0; + RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); + pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; + for (ii = 1; ii < RSSI_STAT_COUNT; ii++) + pBSSList->ldBmAverage[ii] = 0; + } + + if ((pIE_Country != NULL) && + (pMgmt->b11hEnable == true)) { + set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, + pIE_Country); + } + + if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { + if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && + (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { + // valid EID + if (pQuiet == NULL) { + pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; + CARDbSetQuiet(pMgmt->pAdapter, + true, + pQuiet->byQuietCount, + pQuiet->byQuietPeriod, + *((unsigned short *)pQuiet->abyQuietDuration), + *((unsigned short *)pQuiet->abyQuietOffset) +); + } else { + pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; + CARDbSetQuiet(pMgmt->pAdapter, + false, + pQuiet->byQuietCount, + pQuiet->byQuietPeriod, + *((unsigned short *)pQuiet->abyQuietDuration), + *((unsigned short *)pQuiet->abyQuietOffset) + ); + } + } + } + + if ((bParsingQuiet == true) && + (pQuiet != NULL)) { + CARDbStartQuiet(pMgmt->pAdapter); + } + + pBSSList->uIELength = uIELength; + if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) + pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; + memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); + + return true; } @@ -578,171 +578,171 @@ BSSbInsertToBSSList ( * Return Value: * true if success. * --*/ + -*/ // TODO: input structure modify bool -BSSbUpdateToBSSList ( - void *hDeviceContext, - QWORD qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext - ) +BSSbUpdateToBSSList( + void *hDeviceContext, + QWORD qwTimestamp, + unsigned short wBeaconInterval, + unsigned short wCapInfo, + unsigned char byCurrChannel, + bool bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + unsigned int uIELength, + unsigned char *pbyIEs, + void *pRxPacketContext +) { - int ii; - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - long ldBm; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - - - if (pBSSList == NULL) - return false; - - - HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); - LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - pBSSList->uChannel = byCurrChannel; -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel); - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - - if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0)) - memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - memcpy(pBSSList->abySuppRates, pSuppRates,pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) { - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,pExtSuppRates->len + WLAN_IEHDR_LEN); - } else { - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - } - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - // Check if BSS is 802.11a/b/g - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist == true) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - } else { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - if(bChannelHit) - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // assoc with BSS - if (pBSSList == pMgmt->pCurrBSS) { - bParsingQuiet = true; - } - } - - WPA_ClearRSN(pBSSList); //mike update - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); //mike update - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if (pRxPacket->uRSSI != 0) { - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm); - // Moniter if RSSI is too strong. - pBSSList->byRSSIStatCnt++; - pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; - pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; - for(ii=0;iildBmAverage[ii] != 0) { - pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm); - } - } - } - - if ((pIE_Country != NULL) && - (pMgmt->b11hEnable == true)) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - // valid EID - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet( pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet( pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if ((bParsingQuiet == true) && - (pQuiet != NULL)) { - CARDbStartQuiet(pMgmt->pAdapter); - } - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; + int ii; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; + long ldBm; + bool bParsingQuiet = false; + PWLAN_IE_QUIET pQuiet = NULL; + + + + if (pBSSList == NULL) + return false; + + + HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); + LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); + pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); + pBSSList->wCapInfo = cpu_to_le16(wCapInfo); + pBSSList->uClearCount = 0; + pBSSList->uChannel = byCurrChannel; +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel); + + if (pSSID->len > WLAN_SSID_MAXLEN) + pSSID->len = WLAN_SSID_MAXLEN; + + if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0)) + memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); + memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); + + if (pExtSuppRates != NULL) { + memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); + } else { + memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + } + pBSSList->sERP.byERP = psERP->byERP; + pBSSList->sERP.bERPExist = psERP->bERPExist; + + // Check if BSS is 802.11a/b/g + if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; + } else { + if (pBSSList->sERP.bERPExist == true) { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; + } else { + pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; + } + } + + pBSSList->byRxRate = pRxPacket->byRxRate; + pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; + if (bChannelHit) + pBSSList->uRSSI = pRxPacket->uRSSI; + pBSSList->bySQ = pRxPacket->bySQ; + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + // assoc with BSS + if (pBSSList == pMgmt->pCurrBSS) { + bParsingQuiet = true; + } + } + + WPA_ClearRSN(pBSSList); //mike update + + if (pRSNWPA != NULL) { + unsigned int uLen = pRSNWPA->len + 2; + if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { + pBSSList->wWPALen = uLen; + memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); + WPA_ParseRSN(pBSSList, pRSNWPA); + } + } + + WPA2_ClearRSN(pBSSList); //mike update + + if (pRSN != NULL) { + unsigned int uLen = pRSN->len + 2; + if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { + pBSSList->wRSNLen = uLen; + memcpy(pBSSList->byRSNIE, pRSN, uLen); + WPA2vParseRSN(pBSSList, pRSN); + } + } + + if (pRxPacket->uRSSI != 0) { + RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm); + // Moniter if RSSI is too strong. + pBSSList->byRSSIStatCnt++; + pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; + pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; + for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { + if (pBSSList->ldBmAverage[ii] != 0) { + pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm); + } + } + } + + if ((pIE_Country != NULL) && + (pMgmt->b11hEnable == true)) { + set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, + pIE_Country); + } + + if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { + if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && + (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { + // valid EID + if (pQuiet == NULL) { + pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; + CARDbSetQuiet(pMgmt->pAdapter, + true, + pQuiet->byQuietCount, + pQuiet->byQuietPeriod, + *((unsigned short *)pQuiet->abyQuietDuration), + *((unsigned short *)pQuiet->abyQuietOffset) +); + } else { + pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; + CARDbSetQuiet(pMgmt->pAdapter, + false, + pQuiet->byQuietCount, + pQuiet->byQuietPeriod, + *((unsigned short *)pQuiet->abyQuietDuration), + *((unsigned short *)pQuiet->abyQuietOffset) + ); + } + } + } + + if ((bParsingQuiet == true) && + (pQuiet != NULL)) { + CARDbStartQuiet(pMgmt->pAdapter); + } + + pBSSList->uIELength = uIELength; + if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) + pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; + memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); + + return true; } @@ -757,26 +757,26 @@ BSSbUpdateToBSSList ( * Return Value: * None * --*/ + -*/ bool BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, - unsigned int *puNodeIndex) + unsigned int *puNodeIndex) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned int ii; - - // Index = 0 reserved for AP Node - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) { - *puNodeIndex = ii; - return true; - } - } - } - - return false; + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + unsigned int ii; + + // Index = 0 reserved for AP Node + for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { + if (pMgmt->sNodeDBTable[ii].bActive) { + if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) { + *puNodeIndex = ii; + return true; + } + } + } + + return false; }; @@ -790,55 +790,55 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, * Return Value: * None * --*/ + -*/ void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - unsigned int BigestCount = 0; - unsigned int SelectIndex; - struct sk_buff *skb; - // Index = 0 reserved for AP Node (In STA mode) - // Index = 0 reserved for Broadcast/MultiCast (In AP mode) - SelectIndex = 1; - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) { - BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount; - SelectIndex = ii; - } - } - else { - break; - } - } - - // if not found replace uInActiveCount is largest one. - if ( ii == (MAX_NODE_NUM + 1)) { - *puNodeIndex = SelectIndex; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex); - // clear ps buffer - if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - } - } - else { - *puNodeIndex = ii; - } - - memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB)); - pMgmt->sNodeDBTable[*puNodeIndex].bActive = true; - pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND; - // for AP mode PS queue - skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); - pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; - pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii); - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int ii; + unsigned int BigestCount = 0; + unsigned int SelectIndex; + struct sk_buff *skb; + // Index = 0 reserved for AP Node (In STA mode) + // Index = 0 reserved for Broadcast/MultiCast (In AP mode) + SelectIndex = 1; + for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { + if (pMgmt->sNodeDBTable[ii].bActive) { + if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) { + BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount; + SelectIndex = ii; + } + } + else { + break; + } + } + + // if not found replace uInActiveCount is largest one. + if (ii == (MAX_NODE_NUM + 1)) { + *puNodeIndex = SelectIndex; + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex); + // clear ps buffer + if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) { + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL) + dev_kfree_skb(skb); + } + } + else { + *puNodeIndex = ii; + } + + memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB)); + pMgmt->sNodeDBTable[*puNodeIndex].bActive = true; + pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND; + // for AP mode PS queue + skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); + pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; + pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii); + return; }; @@ -852,28 +852,28 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) * Return Value: * None * --*/ + -*/ void BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex - ) + void *hDeviceContext, + unsigned int uNodeIndex +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + struct sk_buff *skb; - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - // clear context - memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB)); - // clear tx bit map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7]; + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL) + dev_kfree_skb(skb); + // clear context + memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB)); + // clear tx bit map + pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7]; - return; + return; }; /*+ * @@ -884,52 +884,52 @@ BSSvRemoveOneNode( * Return Value: * None * --*/ + -*/ void BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates - ) + void *hDeviceContext, + unsigned short *pwCapInfo, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - - pMgmt->sNodeDBTable[0].bActive = true; - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - uRateLen = WLAN_RATES_MAXLEN_11B; - } - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) - ); - memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate; - pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo); - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int uRateLen = WLAN_RATES_MAXLEN; + + memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); + + pMgmt->sNodeDBTable[0].bActive = true; + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + uRateLen = WLAN_RATES_MAXLEN_11B; + } + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + uRateLen); + pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + uRateLen); + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + true, + &(pMgmt->sNodeDBTable[0].wMaxBasicRate), + &(pMgmt->sNodeDBTable[0].wMaxSuppRate), + &(pMgmt->sNodeDBTable[0].wSuppRate), + &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) +); + memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate; + pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo); + pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; #ifdef PLICE_DEBUG - printk("BSSvUpdateAPNode:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate); + printk("BSSvUpdateAPNode:MaxSuppRate is %d\n", pMgmt->sNodeDBTable[0].wMaxSuppRate); #endif - // Auto rate fallback function initiation. - // RATEbInit(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate); + // Auto rate fallback function initiation. + // RATEbInit(pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate); }; @@ -946,38 +946,38 @@ BSSvUpdateAPNode( * Return Value: * None * --*/ + -*/ void BSSvAddMulticastNode( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (!pDevice->bEnableHostWEP) - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].bPSEnable = false; - skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) - ); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + + if (!pDevice->bEnableHostWEP) + memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); + memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN); + pMgmt->sNodeDBTable[0].bActive = true; + pMgmt->sNodeDBTable[0].bPSEnable = false; + skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + true, + &(pMgmt->sNodeDBTable[0].wMaxBasicRate), + &(pMgmt->sNodeDBTable[0].wMaxSuppRate), + &(pMgmt->sNodeDBTable[0].wSuppRate), + &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) +); + pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate; #ifdef PLICE_DEBUG - printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate); + printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); #endif - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; + pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; }; @@ -996,369 +996,369 @@ BSSvAddMulticastNode( * Return Value: * none. * --*/ - //2008-4-14 by chester for led issue - #ifdef FOR_LED_ON_NOTEBOOK -bool cc=false; + -*/ +//2008-4-14 by chester for led issue +#ifdef FOR_LED_ON_NOTEBOOK +bool cc = false; unsigned int status; #endif void BSSvSecondCallBack( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - PWLAN_IE_SSID pItemSSID, pCurrSSID; - unsigned int uSleepySTACnt = 0; - unsigned int uNonShortSlotSTACnt = 0; - unsigned int uLongPreambleSTACnt = 0; - viawget_wpa_header* wpahdr; //DavidWang - - spin_lock_irq(&pDevice->lock); - - pDevice->uAssocCount = 0; - - pDevice->byERPFlag &= - ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1)); - //2008-4-14 by chester for led issue + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int ii; + PWLAN_IE_SSID pItemSSID, pCurrSSID; + unsigned int uSleepySTACnt = 0; + unsigned int uNonShortSlotSTACnt = 0; + unsigned int uLongPreambleSTACnt = 0; + viawget_wpa_header *wpahdr; //DavidWang + + spin_lock_irq(&pDevice->lock); + + pDevice->uAssocCount = 0; + + pDevice->byERPFlag &= + ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1)); + //2008-4-14 by chester for led issue #ifdef FOR_LED_ON_NOTEBOOK -MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); -if ((( !(pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == false))||((pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == true)))&&(cc==false)){ -cc=true; -} -else if(cc==true){ - -if(pDevice->bHWRadioOff == true){ - if ( !(pDevice->byGPIO & GPIO0_DATA)) -//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) -{if(status==1) goto start; -status=1; -CARDbRadioPowerOff(pDevice); - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - //netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - -} - if (pDevice->byGPIO &GPIO0_DATA) -//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) -{if(status==2) goto start; -status=2; -CARDbRadioPowerOn(pDevice); -} } -else{ - if (pDevice->byGPIO & GPIO0_DATA) -//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) -{if(status==3) goto start; -status=3; -CARDbRadioPowerOff(pDevice); - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - //netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - -} - if ( !(pDevice->byGPIO & GPIO0_DATA)) -//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) -{if(status==4) goto start; -status=4; -CARDbRadioPowerOn(pDevice); -} } -} + MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); + if (((!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == false)) || ((pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == true))) && (cc == false)) { + cc = true; + } + else if (cc == true) { + + if (pDevice->bHWRadioOff == true) { + if (!(pDevice->byGPIO & GPIO0_DATA)) +//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) + { if (status == 1) goto start; + status = 1; + CARDbRadioPowerOff(pDevice); + pMgmt->sNodeDBTable[0].bActive = false; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + //netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + + } + if (pDevice->byGPIO & GPIO0_DATA) +//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) + {if (status == 2) goto start; + status = 2; + CARDbRadioPowerOn(pDevice); + } } + else{ + if (pDevice->byGPIO & GPIO0_DATA) +//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) + {if (status == 3) goto start; + status = 3; + CARDbRadioPowerOff(pDevice); + pMgmt->sNodeDBTable[0].bActive = false; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + //netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + + } + if (!(pDevice->byGPIO & GPIO0_DATA)) +//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) + {if (status == 4) goto start; + status = 4; + CARDbRadioPowerOn(pDevice); + } } + } start: #endif - if (pDevice->wUseProtectCntDown > 0) { - pDevice->wUseProtectCntDown --; - } - else { - // disable protect mode - pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1)); - } - -{ - pDevice->byReAssocCount++; - if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) { //10 sec timeout - printk("Re-association timeout!!!\n"); - pDevice->byReAssocCount = 0; - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - #endif - } - else if(pDevice->bLinkPass == true) - pDevice->byReAssocCount = 0; -} + if (pDevice->wUseProtectCntDown > 0) { + pDevice->wUseProtectCntDown--; + } + else { + // disable protect mode + pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1)); + } + + { + pDevice->byReAssocCount++; + if ((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) { //10 sec timeout + printk("Re-association timeout!!!\n"); + pDevice->byReAssocCount = 0; +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + // if (pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif + } + else if (pDevice->bLinkPass == true) + pDevice->byReAssocCount = 0; + } #ifdef Calcu_LinkQual - s_uCalculateLinkQual((void *)pDevice); + s_uCalculateLinkQual((void *)pDevice); #endif - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - - if (pMgmt->sNodeDBTable[ii].bActive) { - // Increase in-activity counter - pMgmt->sNodeDBTable[ii].uInActiveCount++; + for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - if (ii > 0) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) { - BSSvRemoveOneNode(pDevice, ii); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii); - continue; - } + if (pMgmt->sNodeDBTable[ii].bActive) { + // Increase in-activity counter + pMgmt->sNodeDBTable[ii].uInActiveCount++; - if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) { - - pDevice->uAssocCount++; + if (ii > 0) { + if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) { + BSSvRemoveOneNode(pDevice, ii); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii); + continue; + } - // check if Non ERP exist - if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) { - if (!pMgmt->sNodeDBTable[ii].bShortPreamble) { - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - uLongPreambleSTACnt ++; - } - if (!pMgmt->sNodeDBTable[ii].bERPExist) { - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - } - if (!pMgmt->sNodeDBTable[ii].bShortSlotTime) - uNonShortSlotSTACnt++; - } - } + if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) { + + pDevice->uAssocCount++; + + // check if Non ERP exist + if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) { + if (!pMgmt->sNodeDBTable[ii].bShortPreamble) { + pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); + uLongPreambleSTACnt++; + } + if (!pMgmt->sNodeDBTable[ii].bERPExist) { + pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); + pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); + } + if (!pMgmt->sNodeDBTable[ii].bShortSlotTime) + uNonShortSlotSTACnt++; + } + } - // check if any STA in PS mode - if (pMgmt->sNodeDBTable[ii].bPSEnable) - uSleepySTACnt++; + // check if any STA in PS mode + if (pMgmt->sNodeDBTable[ii].bPSEnable) + uSleepySTACnt++; - } + } - // Rate fallback check - if (!pDevice->bFixRate) { + // Rate fallback check + if (!pDevice->bFixRate) { /* - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0)) - RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii])); + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0)) + RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii])); */ - if (ii > 0) { - // ii = 0 for multicast node (AP & Adhoc) - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); - } - else { - // ii = 0 reserved for unicast AP node (Infra STA) - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) + if (ii > 0) { + // ii = 0 for multicast node (AP & Adhoc) + RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); + } + else { + // ii = 0 reserved for unicast AP node (Infra STA) + if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) #ifdef PLICE_DEBUG - printk("SecondCallback:Before:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate); + printk("SecondCallback:Before:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); #endif - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); + RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); #ifdef PLICE_DEBUG - printk("SecondCallback:After:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate); + printk("SecondCallback:After:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); #endif + } + + } + + // check if pending PS queue + if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n", + ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); + if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { + BSSvRemoveOneNode(pDevice, ii); + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii); + continue; + } + } + } + + } + + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) { + + // on/off protect mode + if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { + if (!pDevice->bProtectMode) { + MACvEnableProtectMD(pDevice->PortOffset); + pDevice->bProtectMode = true; + } + } + else { + if (pDevice->bProtectMode) { + MACvDisableProtectMD(pDevice->PortOffset); + pDevice->bProtectMode = false; + } + } + // on/off short slot time + + if (uNonShortSlotSTACnt > 0) { + if (pDevice->bShortSlotTime) { + pDevice->bShortSlotTime = false; + BBvSetShortSlotTime(pDevice); + vUpdateIFS((void *)pDevice); + } + } + else { + if (!pDevice->bShortSlotTime) { + pDevice->bShortSlotTime = true; + BBvSetShortSlotTime(pDevice); + vUpdateIFS((void *)pDevice); + } + } + + // on/off barker long preamble mode + + if (uLongPreambleSTACnt > 0) { + if (!pDevice->bBarkerPreambleMd) { + MACvEnableBarkerPreambleMd(pDevice->PortOffset); + pDevice->bBarkerPreambleMd = true; + } + } + else { + if (pDevice->bBarkerPreambleMd) { + MACvDisableBarkerPreambleMd(pDevice->PortOffset); + pDevice->bBarkerPreambleMd = false; + } + } + + } + + + // Check if any STA in PS mode, enable DTIM multicast deliver + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (uSleepySTACnt > 0) + pMgmt->sNodeDBTable[0].bPSEnable = true; + else + pMgmt->sNodeDBTable[0].bPSEnable = false; + } + + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + + if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || + (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { + + if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS + // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount); + //if (pDevice->bUpdateBBVGA) { + // s_vCheckSensitivity((void *) pDevice); + //} + + if (pDevice->bUpdateBBVGA) { + // s_vCheckSensitivity((void *) pDevice); + s_vCheckPreEDThreshold((void *)pDevice); + } + + if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && + (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) { + pDevice->byBBVGANew = pDevice->abyBBVGA[0]; + bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + } + + if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { + pMgmt->sNodeDBTable[0].bActive = false; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + pDevice->bRoaming = true; + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount); + if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + wpahdr->type = VIAWGET_DISASSOC_MSG; + wpahdr->resp_ie_len = 0; + wpahdr->req_ie_len = 0; + skb_put(pDevice->skb, sizeof(viawget_wpa_header)); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + // if (pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif + } + } + else if (pItemSSID->len != 0) { + if (pDevice->uAutoReConnectTime < 10) { + pDevice->uAutoReConnectTime++; +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + //network manager support need not do Roaming scan??? + if (pDevice->bWPASuppWextEnabled == true) + pDevice->uAutoReConnectTime = 0; +#endif + } + else { + //mike use old encryption status for wpa reauthen + if (pDevice->bWPADEVUp) + pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n"); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + pDevice->uAutoReConnectTime = 0; + } + } + } + + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + // if adhoc started which essid is NULL string, rescanning. + if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) { + if (pDevice->uAutoReConnectTime < 10) { + pDevice->uAutoReConnectTime++; + } + else { + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n"); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); + pDevice->uAutoReConnectTime = 0; + }; } + if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { + + if (pDevice->bUpdateBBVGA) { + //s_vCheckSensitivity((void *) pDevice); + s_vCheckPreEDThreshold((void *)pDevice); + } + if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) { + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + pMgmt->eCurrState = WMAC_STATE_STARTED; + netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + } + } + } + + spin_unlock_irq(&pDevice->lock); - } - - // check if pending PS queue - if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n", - ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); - if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { - BSSvRemoveOneNode(pDevice, ii); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii); - continue; - } - } - } - - } - - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) { - - // on/off protect mode - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } - else { - if (pDevice->bProtectMode) { - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = false; - } - } - // on/off short slot time - - if (uNonShortSlotSTACnt > 0) { - if (pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = false; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } - else { - if (!pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = true; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } - - // on/off barker long preamble mode - - if (uLongPreambleSTACnt > 0) { - if (!pDevice->bBarkerPreambleMd) { - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = true; - } - } - else { - if (pDevice->bBarkerPreambleMd) { - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - } - } - - } - - - // Check if any STA in PS mode, enable DTIM multicast deliver - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (uSleepySTACnt > 0) - pMgmt->sNodeDBTable[0].bPSEnable = true; - else - pMgmt->sNodeDBTable[0].bPSEnable = false; - } - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { - - if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS - // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount); - //if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((void *) pDevice); - //} - - if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((void *) pDevice); - s_vCheckPreEDThreshold((void *)pDevice); - } - - if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && - (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) { - pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); - } - - if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - pDevice->bRoaming = true; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount); - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - #endif - } - } - else if (pItemSSID->len != 0) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //network manager support need not do Roaming scan??? - if(pDevice->bWPASuppWextEnabled ==true) - pDevice->uAutoReConnectTime = 0; - #endif - } - else { - //mike use old encryption status for wpa reauthen - if(pDevice->bWPADEVUp) - pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n"); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - pDevice->uAutoReConnectTime = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // if adhoc started which essid is NULL string, rescanning. - if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; - } - else { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n"); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); - pDevice->uAutoReConnectTime = 0; - }; - } - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - - if (pDevice->bUpdateBBVGA) { - //s_vCheckSensitivity((void *) pDevice); - s_vCheckPreEDThreshold((void *)pDevice); - } - if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - pMgmt->eCurrState = WMAC_STATE_STARTED; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - } - - spin_unlock_irq(&pDevice->lock); - - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - add_timer(&pMgmt->sTimerSecondCallback); - return; + pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); + add_timer(&pMgmt->sTimerSecondCallback); + return; } @@ -1375,177 +1375,177 @@ start: * Return Value: * none. * --*/ + -*/ void BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize - ) + void *hDeviceContext, + unsigned char byTsr0, + unsigned char byTsr1, + unsigned char *pbyBuffer, + unsigned int uFIFOHeaderSize +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex = 0; - unsigned char byTxRetry = (byTsr0 & TSR0_NCR); - PSTxBufHead pTxBufHead; - PS802_11Header pMACHeader; - unsigned short wRate; - unsigned short wFallBackRate = RATE_1M; - unsigned char byFallBack; - unsigned int ii; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int uNodeIndex = 0; + unsigned char byTxRetry = (byTsr0 & TSR0_NCR); + PSTxBufHead pTxBufHead; + PS802_11Header pMACHeader; + unsigned short wRate; + unsigned short wFallBackRate = RATE_1M; + unsigned char byFallBack; + unsigned int ii; // unsigned int txRetryTemp; //PLICE_DEBUG-> //txRetryTemp = byTxRetry; //if (txRetryTemp== 8) //txRetryTemp -=3; //PLICE_DEBUG <- - pTxBufHead = (PSTxBufHead) pbyBuffer; - if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) { - byFallBack = AUTO_FB_0; - } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) { - byFallBack = AUTO_FB_1; - } else { - byFallBack = AUTO_FB_NONE; - } - wRate = pTxBufHead->wReserved; //?wRate - //printk("BSSvUpdateNodeTxCounter:byTxRetry is %d\n",byTxRetry); + pTxBufHead = (PSTxBufHead) pbyBuffer; + if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) { + byFallBack = AUTO_FB_0; + } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) { + byFallBack = AUTO_FB_1; + } else { + byFallBack = AUTO_FB_NONE; + } + wRate = pTxBufHead->wReserved; //?wRate + //printk("BSSvUpdateNodeTxCounter:byTxRetry is %d\n",byTxRetry); //printk("BSSvUpdateNodeTx:wRate is %d,byFallback is %d\n",wRate,byFallBack); //#ifdef PLICE_DEBUG //printk("BSSvUpdateNodeTx: wRate is %d\n",wRate); ////#endif - // Only Unicast using support rates - if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - pMgmt->sNodeDBTable[0].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - // transmit success, TxAttempts at least plus one - pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++; - if ( (byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M) ) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { + // Only Unicast using support rates + if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1); + if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { + pMgmt->sNodeDBTable[0].uTxAttempts += 1; + if ((byTsr1 & TSR1_TERR) == 0) { + // transmit success, TxAttempts at least plus one + pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++; + if ((byFallBack == AUTO_FB_NONE) || + (wRate < RATE_18M)) { + wFallBackRate = wRate; + } else if (byFallBack == AUTO_FB_0) { //PLICE_DEBUG - if (byTxRetry < 5) - //if (txRetryTemp < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry]; - //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[0].uTxFailures ++; - } - pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE]+=byTxRetry; - if ( (byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M) ) { - pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry; - } else if (byFallBack == AUTO_FB_0) { + if (byTxRetry < 5) + //if (txRetryTemp < 5) + wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; + //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry]; + //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1; + else + wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; + //wFallBackRate = awHWRetry0[wRate-RATE_12M][4]; + } else if (byFallBack == AUTO_FB_1) { + if (byTxRetry < 5) + wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; + else + wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; + } + pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++; + } else { + pMgmt->sNodeDBTable[0].uTxFailures++; + } + pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry; + if (byTxRetry != 0) { + pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE] += byTxRetry; + if ((byFallBack == AUTO_FB_NONE) || + (wRate < RATE_18M)) { + pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry; + } else if (byFallBack == AUTO_FB_0) { //PLICE_DEBUG - for(ii=0;iisNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for(ii=0;iisNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } - } - } - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - - pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize); - - if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)){ - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - // transmit success, TxAttempts at least plus one - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - if ( (byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M) ) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures ++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE]+=byTxRetry; - if ( (byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M) ) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry; - } else if (byFallBack == AUTO_FB_0) { - for(ii=0;iisNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for(ii=0;iisNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } - } - } - } - } - - return; + } + } else if (byFallBack == AUTO_FB_1) { + for (ii = 0; ii < byTxRetry; ii++) { + if (ii < 5) + wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; + else + wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; + pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; + } + } + } + } + + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || + (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { + + pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize); + + if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)) { + pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; + if ((byTsr1 & TSR1_TERR) == 0) { + // transmit success, TxAttempts at least plus one + pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; + if ((byFallBack == AUTO_FB_NONE) || + (wRate < RATE_18M)) { + wFallBackRate = wRate; + } else if (byFallBack == AUTO_FB_0) { + if (byTxRetry < 5) + wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; + else + wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; + } else if (byFallBack == AUTO_FB_1) { + if (byTxRetry < 5) + wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; + else + wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; + } + pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++; + } else { + pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; + } + pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry; + if (byTxRetry != 0) { + pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE] += byTxRetry; + if ((byFallBack == AUTO_FB_NONE) || + (wRate < RATE_18M)) { + pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate] += byTxRetry; + } else if (byFallBack == AUTO_FB_0) { + for (ii = 0; ii < byTxRetry; ii++) { + if (ii < 5) + wFallBackRate = awHWRetry0[wRate - RATE_18M][ii]; + else + wFallBackRate = awHWRetry0[wRate - RATE_18M][4]; + pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; + } + } else if (byFallBack == AUTO_FB_1) { + for (ii = 0; ii < byTxRetry; ii++) { + if (ii < 5) + wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; + else + wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; + pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; + } + } + } + } + } + } + + return; } @@ -1569,167 +1569,167 @@ BSSvUpdateNodeTxCounter( * Return Value: * None. * --*/ + -*/ void BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex - ) + void *hDeviceContext, + unsigned int uStartIndex +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - struct sk_buff *skb; - unsigned int ii; - - for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - // check if sTxPSQueue has been initial - if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii); - dev_kfree_skb(skb); - } - } - memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB)); - } - } - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + struct sk_buff *skb; + unsigned int ii; + + for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { + if (pMgmt->sNodeDBTable[ii].bActive) { + // check if sTxPSQueue has been initial + if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii); + dev_kfree_skb(skb); + } + } + memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB)); + } + } + + return; }; void s_vCheckSensitivity( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) && - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - return; - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) { - // Updata BB Reg if RSSI is too strong. - long LocalldBmAverage = 0; - long uNumofdBm = 0; - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) { - uNumofdBm ++; - LocalldBmAverage += pBSSList->ldBmAverage[ii]; - } - } - if (uNumofdBm > 0) { - LocalldBmAverage = LocalldBmAverage/uNumofdBm; - for (ii=0;iildBmThreshold[ii], pDevice->abyBBVGA[ii]); - if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) { - pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; - break; - } - } - if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { - pDevice->uBBVGADiffCount++; - if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) - bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); - } else { - pDevice->uBBVGADiffCount = 0; - } - } - } - } + PSDevice pDevice = (PSDevice)hDeviceContext; + PKnownBSS pBSSList = NULL; + PSMgmtObject pMgmt = pDevice->pMgmt; + int ii; + + if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) && + (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { + return; + } + + if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || + ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { + pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); + if (pBSSList != NULL) { + // Updata BB Reg if RSSI is too strong. + long LocalldBmAverage = 0; + long uNumofdBm = 0; + for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { + if (pBSSList->ldBmAverage[ii] != 0) { + uNumofdBm++; + LocalldBmAverage += pBSSList->ldBmAverage[ii]; + } + } + if (uNumofdBm > 0) { + LocalldBmAverage = LocalldBmAverage/uNumofdBm; + for (ii = 0; ii < BB_VGA_LEVEL; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]); + if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) { + pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; + break; + } + } + if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { + pDevice->uBBVGADiffCount++; + if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) + bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + } else { + pDevice->uBBVGADiffCount = 0; + } + } + } + } } void -BSSvClearAnyBSSJoinRecord ( - void *hDeviceContext - ) +BSSvClearAnyBSSJoinRecord( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pMgmt->sBSSList[ii].bSelected = false; - } - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int ii; + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pMgmt->sBSSList[ii].bSelected = false; + } + return; } #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - unsigned long TxOkRatio, TxCnt; - unsigned long RxOkRatio,RxCnt; - unsigned long RssiRatio; - long ldBm; - -TxCnt = pDevice->scStatistic.TxNoRetryOkCount + - pDevice->scStatistic.TxRetryOkCount + - pDevice->scStatistic.TxFailCount; -RxCnt = pDevice->scStatistic.RxFcsErrCnt + - pDevice->scStatistic.RxOkCnt; -TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); -RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); + PSDevice pDevice = (PSDevice)hDeviceContext; + unsigned long TxOkRatio, TxCnt; + unsigned long RxOkRatio, RxCnt; + unsigned long RssiRatio; + long ldBm; + + TxCnt = pDevice->scStatistic.TxNoRetryOkCount + + pDevice->scStatistic.TxRetryOkCount + + pDevice->scStatistic.TxFailCount; + RxCnt = pDevice->scStatistic.RxFcsErrCnt + + pDevice->scStatistic.RxOkCnt; + TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); + RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); //decide link quality -if(pDevice->bLinkPass !=true) -{ - // printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n"); - pDevice->scStatistic.LinkQuality = 0; - pDevice->scStatistic.SignalStren = 0; -} -else -{ - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - if(-ldBm < 50) { - RssiRatio = 4000; - } - else if(-ldBm > 90) { - RssiRatio = 0; - } - else { - RssiRatio = (40-(-ldBm-50))*4000/40; - } - pDevice->scStatistic.SignalStren = RssiRatio/40; - pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; -} - pDevice->scStatistic.RxFcsErrCnt = 0; - pDevice->scStatistic.RxOkCnt = 0; - pDevice->scStatistic.TxFailCount = 0; - pDevice->scStatistic.TxNoRetryOkCount = 0; - pDevice->scStatistic.TxRetryOkCount = 0; - return; + if (pDevice->bLinkPass != true) + { + // printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n"); + pDevice->scStatistic.LinkQuality = 0; + pDevice->scStatistic.SignalStren = 0; + } + else + { + RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); + if (-ldBm < 50) { + RssiRatio = 4000; + } + else if (-ldBm > 90) { + RssiRatio = 0; + } + else { + RssiRatio = (40-(-ldBm-50))*4000/40; + } + pDevice->scStatistic.SignalStren = RssiRatio/40; + pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; + } + pDevice->scStatistic.RxFcsErrCnt = 0; + pDevice->scStatistic.RxOkCnt = 0; + pDevice->scStatistic.TxFailCount = 0; + pDevice->scStatistic.TxNoRetryOkCount = 0; + pDevice->scStatistic.TxRetryOkCount = 0; + return; } #endif void s_vCheckPreEDThreshold( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) { - pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1); - //BBvUpdatePreEDThreshold(pDevice, false); - } - } - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PKnownBSS pBSSList = NULL; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + + if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || + ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { + pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); + if (pBSSList != NULL) { + pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1); + //BBvUpdatePreEDThreshold(pDevice, false); + } + } + return; } diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index 0af421186122..178748d0dad4 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -39,7 +39,7 @@ #define MAX_NODE_NUM 64 #define MAX_BSS_NUM 42 -#define LOST_BEACON_COUNT 10 // 10 sec, XP defined +#define LOST_BEACON_COUNT 10 // 10 sec, XP defined #define MAX_PS_TX_BUF 32 // sta max power saving tx buf #define ADHOC_LOST_BEACON_COUNT 30 // 30 sec, beacon lost for adhoc only #define MAX_INACTIVE_COUNT 300 // 300 sec, inactive STA node refresh @@ -81,159 +81,159 @@ typedef enum _NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound } NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; typedef struct tagSERPObject { - bool bERPExist; - unsigned char byERP; -}ERPObject, *PERPObject; + bool bERPExist; + unsigned char byERP; +} ERPObject, *PERPObject; typedef struct tagSRSNCapObject { - bool bRSNCapExist; - unsigned short wRSNCap; -}SRSNCapObject, *PSRSNCapObject; + bool bRSNCapExist; + unsigned short wRSNCap; +} SRSNCapObject, *PSRSNCapObject; // BSS info(AP) #pragma pack(1) typedef struct tagKnownBSS { - // BSS info - bool bActive; - unsigned char abyBSSID[WLAN_BSSID_LEN]; - unsigned int uChannel; - unsigned char abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned int uRSSI; - unsigned char bySQ; - unsigned short wBeaconInterval; - unsigned short wCapInfo; - unsigned char abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char byRxRate; + // BSS info + bool bActive; + unsigned char abyBSSID[WLAN_BSSID_LEN]; + unsigned int uChannel; + unsigned char abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned int uRSSI; + unsigned char bySQ; + unsigned short wBeaconInterval; + unsigned short wCapInfo; + unsigned char abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned char byRxRate; // unsigned short wATIMWindow; - unsigned char byRSSIStatCnt; - long ldBmMAX; - long ldBmAverage[RSSI_STAT_COUNT]; - long ldBmAverRange; - //For any BSSID selection improvment - bool bSelected; - - //++ WPA informations - bool bWPAValid; - unsigned char byGKType; - unsigned char abyPKType[4]; - unsigned short wPKCount; - unsigned char abyAuthType[4]; - unsigned short wAuthCount; - unsigned char byDefaultK_as_PK; - unsigned char byReplayIdx; - //-- - - //++ WPA2 informations - bool bWPA2Valid; - unsigned char byCSSGK; - unsigned short wCSSPKCount; - unsigned char abyCSSPK[4]; - unsigned short wAKMSSAuthCount; - unsigned char abyAKMSSAuthType[4]; - - //++ wpactl - unsigned char byWPAIE[MAX_WPA_IE_LEN]; - unsigned char byRSNIE[MAX_WPA_IE_LEN]; - unsigned short wWPALen; - unsigned short wRSNLen; - - // Clear count - unsigned int uClearCount; + unsigned char byRSSIStatCnt; + long ldBmMAX; + long ldBmAverage[RSSI_STAT_COUNT]; + long ldBmAverRange; + //For any BSSID selection improvment + bool bSelected; + + //++ WPA informations + bool bWPAValid; + unsigned char byGKType; + unsigned char abyPKType[4]; + unsigned short wPKCount; + unsigned char abyAuthType[4]; + unsigned short wAuthCount; + unsigned char byDefaultK_as_PK; + unsigned char byReplayIdx; + //-- + + //++ WPA2 informations + bool bWPA2Valid; + unsigned char byCSSGK; + unsigned short wCSSPKCount; + unsigned char abyCSSPK[4]; + unsigned short wAKMSSAuthCount; + unsigned char abyAKMSSAuthType[4]; + + //++ wpactl + unsigned char byWPAIE[MAX_WPA_IE_LEN]; + unsigned char byRSNIE[MAX_WPA_IE_LEN]; + unsigned short wWPALen; + unsigned short wRSNLen; + + // Clear count + unsigned int uClearCount; // unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN]; - unsigned int uIELength; - QWORD qwBSSTimestamp; - QWORD qwLocalTSF; // local TSF timer + unsigned int uIELength; + QWORD qwBSSTimestamp; + QWORD qwLocalTSF; // local TSF timer // NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - CARD_PHY_TYPE eNetworkTypeInUse; + CARD_PHY_TYPE eNetworkTypeInUse; - ERPObject sERP; - SRSNCapObject sRSNCapObj; - unsigned char abyIEs[1024]; // don't move this field !! + ERPObject sERP; + SRSNCapObject sRSNCapObj; + unsigned char abyIEs[1024]; // don't move this field !! -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) KnownBSS , *PKnownBSS; //2006-1116-01, by NomadZhao #pragma pack() typedef enum tagNODE_STATE { - NODE_FREE, - NODE_AGED, - NODE_KNOWN, - NODE_AUTH, - NODE_ASSOC + NODE_FREE, + NODE_AGED, + NODE_KNOWN, + NODE_AUTH, + NODE_ASSOC } NODE_STATE, *PNODE_STATE; // STA node info typedef struct tagKnownNodeDB { - // STA info - bool bActive; - unsigned char abyMACAddr[WLAN_ADDR_LEN]; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned short wTxDataRate; - bool bShortPreamble; - bool bERPExist; - bool bShortSlotTime; - unsigned int uInActiveCount; - unsigned short wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. - unsigned short wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. - unsigned short wSuppRate; - unsigned char byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode - unsigned char byTopCCKBasicRate; //Records the highest basic rate in CCK mode - - // For AP mode - struct sk_buff_head sTxPSQueue; - unsigned short wCapInfo; - unsigned short wListenInterval; - unsigned short wAID; - NODE_STATE eNodeState; - bool bPSEnable; - bool bRxPSPoll; - unsigned char byAuthSequence; - unsigned long ulLastRxJiffer; - unsigned char bySuppRate; - unsigned long dwFlags; - unsigned short wEnQueueCnt; - - bool bOnFly; - unsigned long long KeyRSC; - unsigned char byKeyIndex; - unsigned long dwKeyIndex; - unsigned char byCipherSuite; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned int uWepKeyLength; - unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN]; - // - // Auto rate fallback vars - bool bIsInFallback; - unsigned int uAverageRSSI; - unsigned int uRateRecoveryTimeout; - unsigned int uRatePollTimeout; - unsigned int uTxFailures; - unsigned int uTxAttempts; - - unsigned int uTxRetry; - unsigned int uFailureRatio; - unsigned int uRetryRatio; - unsigned int uTxOk[MAX_RATE+1]; - unsigned int uTxFail[MAX_RATE+1]; - unsigned int uTimeCount; + // STA info + bool bActive; + unsigned char abyMACAddr[WLAN_ADDR_LEN]; + unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; + unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; + unsigned short wTxDataRate; + bool bShortPreamble; + bool bERPExist; + bool bShortSlotTime; + unsigned int uInActiveCount; + unsigned short wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. + unsigned short wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. + unsigned short wSuppRate; + unsigned char byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode + unsigned char byTopCCKBasicRate; //Records the highest basic rate in CCK mode + + // For AP mode + struct sk_buff_head sTxPSQueue; + unsigned short wCapInfo; + unsigned short wListenInterval; + unsigned short wAID; + NODE_STATE eNodeState; + bool bPSEnable; + bool bRxPSPoll; + unsigned char byAuthSequence; + unsigned long ulLastRxJiffer; + unsigned char bySuppRate; + unsigned long dwFlags; + unsigned short wEnQueueCnt; + + bool bOnFly; + unsigned long long KeyRSC; + unsigned char byKeyIndex; + unsigned long dwKeyIndex; + unsigned char byCipherSuite; + unsigned long dwTSC47_16; + unsigned short wTSC15_0; + unsigned int uWepKeyLength; + unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN]; + // + // Auto rate fallback vars + bool bIsInFallback; + unsigned int uAverageRSSI; + unsigned int uRateRecoveryTimeout; + unsigned int uRatePollTimeout; + unsigned int uTxFailures; + unsigned int uTxAttempts; + + unsigned int uTxRetry; + unsigned int uFailureRatio; + unsigned int uRetryRatio; + unsigned int uTxOk[MAX_RATE+1]; + unsigned int uTxFail[MAX_RATE+1]; + unsigned int uTimeCount; } KnownNodeDB, *PKnownNodeDB; @@ -244,122 +244,122 @@ typedef struct tagKnownNodeDB { PKnownBSS BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType - ); + void *hDeviceContext, + unsigned char *pbyDesireBSSID, + unsigned char *pbyDesireSSID, + CARD_PHY_TYPE ePhyType +); PKnownBSS BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID - ); + void *hDeviceContext, + unsigned char *abyBSSID, + PWLAN_IE_SSID pSSID +); void BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID - ); + void *hDeviceContext, + bool bKeepCurrBSSID +); bool BSSbInsertToBSSList( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - QWORD qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext - ); + void *hDeviceContext, + unsigned char *abyBSSIDAddr, + QWORD qwTimestamp, + unsigned short wBeaconInterval, + unsigned short wCapInfo, + unsigned char byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + unsigned int uIELength, + unsigned char *pbyIEs, + void *pRxPacketContext +); bool BSSbUpdateToBSSList( - void *hDeviceContext, - QWORD qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext - ); + void *hDeviceContext, + QWORD qwTimestamp, + unsigned short wBeaconInterval, + unsigned short wCapInfo, + unsigned char byCurrChannel, + bool bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + unsigned int uIELength, + unsigned char *pbyIEs, + void *pRxPacketContext +); bool BSSDBbIsSTAInNodeDB(void *hDeviceContext, unsigned char *abyDstAddr, - unsigned int *puNodeIndex); + unsigned int *puNodeIndex); void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex); void BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pExtSuppRates - ); + void *hDeviceContext, + unsigned short *pwCapInfo, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pExtSuppRates +); void BSSvSecondCallBack( - void *hDeviceContext - ); + void *hDeviceContext +); void BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize - ); + void *hDeviceContext, + unsigned char byTsr0, + unsigned char byTsr1, + unsigned char *pbyBuffer, + unsigned int uFIFOHeaderSize +); void BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex - ); + void *hDeviceContext, + unsigned int uNodeIndex +); void BSSvAddMulticastNode( - void *hDeviceContext - ); + void *hDeviceContext +); void BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex - ); + void *hDeviceContext, + unsigned int uStartIndex +); void BSSvClearAnyBSSJoinRecord( - void *hDeviceContext - ); + void *hDeviceContext +); #endif //__BSSDB_H__ -- cgit From d4945f09dd81d4d7166d1f1285571d09db2187b9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:40 -0700 Subject: staging:vt6655:card: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 2792 ++++++++++++++++++++--------------------- drivers/staging/vt6655/card.h | 130 +- 2 files changed, 1461 insertions(+), 1461 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 319ca482f003..fd10abe34aea 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -61,7 +61,7 @@ /*--------------------- Static Definitions -------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; #define C_SIFS_A 16 // micro sec. #define C_SIFS_BG 10 @@ -79,13 +79,13 @@ static int msglevel =MSG_LEVEL_INFO; #define WAIT_BEACON_TX_DOWN_TMO 3 // Times - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M +//1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - //6M, 9M, 12M, 48M +//6M, 9M, 12M, 48M static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M +//6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - //1M, 2M, 5M, 11M, +//1M, 2M, 5M, 11M, static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; @@ -101,11 +101,11 @@ const unsigned short cwRXBCNTSFOff[MAX_RATE] = static void s_vCalculateOFDMRParameter( - unsigned char byRate, - CARD_PHY_TYPE ePHYType, - unsigned char *pbyTxRate, - unsigned char *pbyRsvTime - ); + unsigned char byRate, + CARD_PHY_TYPE ePHYType, + unsigned char *pbyTxRate, + unsigned char *pbyRsvTime +); /*--------------------- Export Functions --------------------------*/ @@ -126,103 +126,103 @@ s_vCalculateOFDMRParameter( */ static void -s_vCalculateOFDMRParameter ( - unsigned char byRate, - CARD_PHY_TYPE ePHYType, - unsigned char *pbyTxRate, - unsigned char *pbyRsvTime - ) +s_vCalculateOFDMRParameter( + unsigned char byRate, + CARD_PHY_TYPE ePHYType, + unsigned char *pbyTxRate, + unsigned char *pbyRsvTime +) { - switch (byRate) { - case RATE_6M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9B; - *pbyRsvTime = 44; - } - else { - *pbyTxRate = 0x8B; - *pbyRsvTime = 50; - } - break; - - case RATE_9M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9F; - *pbyRsvTime = 36; - } - else { - *pbyTxRate = 0x8F; - *pbyRsvTime = 42; - } - break; - - case RATE_12M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9A; - *pbyRsvTime = 32; - } - else { - *pbyTxRate = 0x8A; - *pbyRsvTime = 38; - } - break; - - case RATE_18M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9E; - *pbyRsvTime = 28; - } - else { - *pbyTxRate = 0x8E; - *pbyRsvTime = 34; - } - break; - - case RATE_36M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9D; - *pbyRsvTime = 24; - } - else { - *pbyTxRate = 0x8D; - *pbyRsvTime = 30; - } - break; - - case RATE_48M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x98; - *pbyRsvTime = 24; - } - else { - *pbyTxRate = 0x88; - *pbyRsvTime = 30; - } - break; - - case RATE_54M : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x9C; - *pbyRsvTime = 24; - } - else { - *pbyTxRate = 0x8C; - *pbyRsvTime = 30; - } - break; - - case RATE_24M : - default : - if (ePHYType == PHY_TYPE_11A) {//5GHZ - *pbyTxRate = 0x99; - *pbyRsvTime = 28; - } - else { - *pbyTxRate = 0x89; - *pbyRsvTime = 34; - } - break; - } + switch (byRate) { + case RATE_6M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9B; + *pbyRsvTime = 44; + } + else { + *pbyTxRate = 0x8B; + *pbyRsvTime = 50; + } + break; + + case RATE_9M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9F; + *pbyRsvTime = 36; + } + else { + *pbyTxRate = 0x8F; + *pbyRsvTime = 42; + } + break; + + case RATE_12M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9A; + *pbyRsvTime = 32; + } + else { + *pbyTxRate = 0x8A; + *pbyRsvTime = 38; + } + break; + + case RATE_18M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9E; + *pbyRsvTime = 28; + } + else { + *pbyTxRate = 0x8E; + *pbyRsvTime = 34; + } + break; + + case RATE_36M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9D; + *pbyRsvTime = 24; + } + else { + *pbyTxRate = 0x8D; + *pbyRsvTime = 30; + } + break; + + case RATE_48M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x98; + *pbyRsvTime = 24; + } + else { + *pbyTxRate = 0x88; + *pbyRsvTime = 30; + } + break; + + case RATE_54M: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x9C; + *pbyRsvTime = 24; + } + else { + *pbyTxRate = 0x8C; + *pbyRsvTime = 30; + } + break; + + case RATE_24M: + default: + if (ePHYType == PHY_TYPE_11A) {//5GHZ + *pbyTxRate = 0x99; + *pbyRsvTime = 28; + } + else { + *pbyTxRate = 0x89; + *pbyRsvTime = 34; + } + break; + } } @@ -241,114 +241,114 @@ s_vCalculateOFDMRParameter ( */ static void -s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs) +s_vSetRSPINF(PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs) { - unsigned char byServ = 0, bySignal = 0; // For CCK - unsigned short wLen = 0; - unsigned char byTxRate = 0, byRsvTime = 0; // For OFDM - - //Set to Page1 - MACvSelectPage1(pDevice->PortOffset); - - //RSPINF_b_1 - BBvCalculateParameter(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - ///RSPINF_b_2 - BBvCalculateParameter(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_b_5 - BBvCalculateParameter(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_b_11 - BBvCalculateParameter(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_a_6 - s_vCalculateOFDMRParameter(RATE_6M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_9 - s_vCalculateOFDMRParameter(RATE_9M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_12 - s_vCalculateOFDMRParameter(RATE_12M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_18 - s_vCalculateOFDMRParameter(RATE_18M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_24 - s_vCalculateOFDMRParameter(RATE_24M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_36 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_48 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_54 - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_72 - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate,byRsvTime)); - //Set to Page0 - MACvSelectPage0(pDevice->PortOffset); + unsigned char byServ = 0, bySignal = 0; // For CCK + unsigned short wLen = 0; + unsigned char byTxRate = 0, byRsvTime = 0; // For OFDM + + //Set to Page1 + MACvSelectPage1(pDevice->PortOffset); + + //RSPINF_b_1 + BBvCalculateParameter(pDevice, + 14, + VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + ///RSPINF_b_2 + BBvCalculateParameter(pDevice, + 14, + VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_b_5 + BBvCalculateParameter(pDevice, + 14, + VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_b_11 + BBvCalculateParameter(pDevice, + 14, + VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_a_6 + s_vCalculateOFDMRParameter(RATE_6M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_9 + s_vCalculateOFDMRParameter(RATE_9M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_12 + s_vCalculateOFDMRParameter(RATE_12M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_18 + s_vCalculateOFDMRParameter(RATE_18M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_24 + s_vCalculateOFDMRParameter(RATE_24M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_36 + s_vCalculateOFDMRParameter( + VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_48 + s_vCalculateOFDMRParameter( + VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_54 + s_vCalculateOFDMRParameter( + VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_72 + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); + //Set to Page0 + MACvSelectPage0(pDevice->PortOffset); } /*--------------------- Export Functions --------------------------*/ @@ -369,19 +369,19 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, * */ /* -bool CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, unsigned int uLength) -{ - PSDevice pDevice = (PSDevice) pDeviceHandler; - if (ePktType == PKT_TYPE_802_11_MNG) { - return TXbTD0Send(pDevice, pPacket, uLength); - } else if (ePktType == PKT_TYPE_802_11_BCN) { - return TXbBeaconSend(pDevice, pPacket, uLength); - } if (ePktType == PKT_TYPE_802_11_DATA) { - return TXbTD1Send(pDevice, pPacket, uLength); - } - - return (true); -} + bool CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, unsigned int uLength) + { + PSDevice pDevice = (PSDevice) pDeviceHandler; + if (ePktType == PKT_TYPE_802_11_MNG) { + return TXbTD0Send(pDevice, pPacket, uLength); + } else if (ePktType == PKT_TYPE_802_11_BCN) { + return TXbBeaconSend(pDevice, pPacket, uLength); + } if (ePktType == PKT_TYPE_802_11_DATA) { + return TXbTD1Send(pDevice, pPacket, uLength); + } + + return (true); + } */ @@ -397,13 +397,13 @@ bool CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktTyp * Return Value: true if short preamble; otherwise false * */ -bool CARDbIsShortPreamble (void *pDeviceHandler) +bool CARDbIsShortPreamble(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - if (pDevice->byPreambleType == 0) { - return(false); - } - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + if (pDevice->byPreambleType == 0) { + return(false); + } + return(true); } /* @@ -418,10 +418,10 @@ bool CARDbIsShortPreamble (void *pDeviceHandler) * Return Value: true if short slot time; otherwise false * */ -bool CARDbIsShorSlotTime (void *pDeviceHandler) +bool CARDbIsShorSlotTime(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - return(pDevice->bShortSlotTime); + PSDevice pDevice = (PSDevice) pDeviceHandler; + return(pDevice->bShortSlotTime); } @@ -437,175 +437,175 @@ bool CARDbIsShorSlotTime (void *pDeviceHandler) * Return Value: None. * */ -bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs) +bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned char byCWMaxMin = 0; - unsigned char bySlot = 0; - unsigned char bySIFS = 0; - unsigned char byDIFS = 0; - unsigned char byData; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned char byCWMaxMin = 0; + unsigned char bySlot = 0; + unsigned char bySIFS = 0; + unsigned char byDIFS = 0; + unsigned char byData; // PWLAN_IE_SUPP_RATES pRates = NULL; - PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs; - PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs; - - - //Set SIFS, DIFS, EIFS, SlotTime, CwMin - if (ePHYType == PHY_TYPE_11A) { - if (pSupportRates == NULL) { - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA; - } - if (pDevice->byRFType == RF_AIROHA7230) { - // AL7230 use single PAPE and connect to PAPE_2.4G - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); - pDevice->abyBBVGA[0] = 0x20; - pDevice->abyBBVGA[2] = 0x10; - pDevice->abyBBVGA[3] = 0x10; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x1C) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - } - } else if (pDevice->byRFType == RF_UW2452) { - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); - pDevice->abyBBVGA[0] = 0x18; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x14) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57); - } - } else { - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); - } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03); - bySlot = C_SLOT_SHORT; - bySIFS = C_SIFS_A; - byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; - byCWMaxMin = 0xA4; - } else if (ePHYType == PHY_TYPE_11B) { - if (pSupportRates == NULL) { - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB; - } - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B); - if (pDevice->byRFType == RF_AIROHA7230) { - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[2] = 0x00; - pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x20) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - } - } else if (pDevice->byRFType == RF_UW2452) { - pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); - } - } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02); - bySlot = C_SLOT_LONG; - bySIFS = C_SIFS_BG; - byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; - byCWMaxMin = 0xA5; - } else {// PK_TYPE_11GA & PK_TYPE_11GB - if (pSupportRates == NULL) { - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG; - pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG; - } - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); - if (pDevice->byRFType == RF_AIROHA7230) { - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[2] = 0x00; - pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x20) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - } - } else if (pDevice->byRFType == RF_UW2452) { - pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); - if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); - } - } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); - bySIFS = C_SIFS_BG; - if(VNTWIFIbIsShortSlotTime(wCapInfo)) { - bySlot = C_SLOT_SHORT; - byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT; - } else { - bySlot = C_SLOT_LONG; - byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; - } - if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) { - byCWMaxMin = 0xA4; - } else { - byCWMaxMin = 0xA5; - } - if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) { - pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField); - if (pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - } else { - MACvDisableProtectMD(pDevice->PortOffset); - } - } - if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) { - pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField); - if (pDevice->bBarkerPreambleMd) { - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - } else { - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - } - } - } - - if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us - // hardware's processing time here is 2 us. - bySIFS -= 3; - byDIFS -= 3; - //{{ RobertYu: 20041202 - //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput - //// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us. - } - - if (pDevice->bySIFS != bySIFS) { - pDevice->bySIFS = bySIFS; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, pDevice->bySIFS); - } - if (pDevice->byDIFS != byDIFS) { - pDevice->byDIFS = byDIFS; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, pDevice->byDIFS); - } - if (pDevice->byEIFS != C_EIFS) { - pDevice->byEIFS = C_EIFS; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, pDevice->byEIFS); - } - if (pDevice->bySlot != bySlot) { - pDevice->bySlot = bySlot; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot); - if (pDevice->bySlot == C_SLOT_SHORT) { - pDevice->bShortSlotTime = true; - } else { - pDevice->bShortSlotTime = false; - } - BBvSetShortSlotTime(pDevice); - } - if (pDevice->byCWMaxMin != byCWMaxMin) { - pDevice->byCWMaxMin = byCWMaxMin; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); - } - if (VNTWIFIbIsShortPreamble(wCapInfo)) { - pDevice->byPreambleType = pDevice->byShortPreamble; - } else { - pDevice->byPreambleType = 0; - } - s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates); - pDevice->eCurrentPHYType = ePHYType; - // set for NDIS OID_802_11SUPPORTED_RATES - return (true); + PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs; + PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs; + + + //Set SIFS, DIFS, EIFS, SlotTime, CwMin + if (ePHYType == PHY_TYPE_11A) { + if (pSupportRates == NULL) { + pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA; + } + if (pDevice->byRFType == RF_AIROHA7230) { + // AL7230 use single PAPE and connect to PAPE_2.4G + MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); + pDevice->abyBBVGA[0] = 0x20; + pDevice->abyBBVGA[2] = 0x10; + pDevice->abyBBVGA[3] = 0x10; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x1C) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + } + } else if (pDevice->byRFType == RF_UW2452) { + MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); + pDevice->abyBBVGA[0] = 0x18; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x14) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57); + } + } else { + MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); + } + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03); + bySlot = C_SLOT_SHORT; + bySIFS = C_SIFS_A; + byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; + byCWMaxMin = 0xA4; + } else if (ePHYType == PHY_TYPE_11B) { + if (pSupportRates == NULL) { + pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB; + } + MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B); + if (pDevice->byRFType == RF_AIROHA7230) { + pDevice->abyBBVGA[0] = 0x1C; + pDevice->abyBBVGA[2] = 0x00; + pDevice->abyBBVGA[3] = 0x00; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x20) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + } + } else if (pDevice->byRFType == RF_UW2452) { + pDevice->abyBBVGA[0] = 0x14; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x18) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + } + } + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02); + bySlot = C_SLOT_LONG; + bySIFS = C_SIFS_BG; + byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; + byCWMaxMin = 0xA5; + } else {// PK_TYPE_11GA & PK_TYPE_11GB + if (pSupportRates == NULL) { + pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG; + pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG; + } + MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); + if (pDevice->byRFType == RF_AIROHA7230) { + pDevice->abyBBVGA[0] = 0x1C; + pDevice->abyBBVGA[2] = 0x00; + pDevice->abyBBVGA[3] = 0x00; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x20) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + } + } else if (pDevice->byRFType == RF_UW2452) { + pDevice->abyBBVGA[0] = 0x14; + BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + if (byData == 0x18) { + BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + } + } + BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); + bySIFS = C_SIFS_BG; + if (VNTWIFIbIsShortSlotTime(wCapInfo)) { + bySlot = C_SLOT_SHORT; + byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT; + } else { + bySlot = C_SLOT_LONG; + byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; + } + if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) { + byCWMaxMin = 0xA4; + } else { + byCWMaxMin = 0xA5; + } + if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) { + pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField); + if (pDevice->bProtectMode) { + MACvEnableProtectMD(pDevice->PortOffset); + } else { + MACvDisableProtectMD(pDevice->PortOffset); + } + } + if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) { + pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField); + if (pDevice->bBarkerPreambleMd) { + MACvEnableBarkerPreambleMd(pDevice->PortOffset); + } else { + MACvDisableBarkerPreambleMd(pDevice->PortOffset); + } + } + } + + if (pDevice->byRFType == RF_RFMD2959) { + // bcs TX_PE will reserve 3 us + // hardware's processing time here is 2 us. + bySIFS -= 3; + byDIFS -= 3; + //{{ RobertYu: 20041202 + //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput + //// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us. + } + + if (pDevice->bySIFS != bySIFS) { + pDevice->bySIFS = bySIFS; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, pDevice->bySIFS); + } + if (pDevice->byDIFS != byDIFS) { + pDevice->byDIFS = byDIFS; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, pDevice->byDIFS); + } + if (pDevice->byEIFS != C_EIFS) { + pDevice->byEIFS = C_EIFS; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, pDevice->byEIFS); + } + if (pDevice->bySlot != bySlot) { + pDevice->bySlot = bySlot; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot); + if (pDevice->bySlot == C_SLOT_SHORT) { + pDevice->bShortSlotTime = true; + } else { + pDevice->bShortSlotTime = false; + } + BBvSetShortSlotTime(pDevice); + } + if (pDevice->byCWMaxMin != byCWMaxMin) { + pDevice->byCWMaxMin = byCWMaxMin; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); + } + if (VNTWIFIbIsShortPreamble(wCapInfo)) { + pDevice->byPreambleType = pDevice->byShortPreamble; + } else { + pDevice->byPreambleType = 0; + } + s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates); + pDevice->eCurrentPHYType = ePHYType; + // set for NDIS OID_802_11SUPPORTED_RATES + return (true); } /* @@ -624,24 +624,24 @@ bool CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigne * Return Value: none * */ -bool CARDbUpdateTSF (void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF) +bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - QWORD qwTSFOffset; - - HIDWORD(qwTSFOffset) = 0; - LODWORD(qwTSFOffset) = 0; - - if ((HIDWORD(qwBSSTimestamp) != HIDWORD(qwLocalTSF)) || - (LODWORD(qwBSSTimestamp) != LODWORD(qwLocalTSF))) { - qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); - // adjust TSF - // HW's TSF add TSF Offset reg - VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, LODWORD(qwTSFOffset)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset)); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); - } - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + QWORD qwTSFOffset; + + HIDWORD(qwTSFOffset) = 0; + LODWORD(qwTSFOffset) = 0; + + if ((HIDWORD(qwBSSTimestamp) != HIDWORD(qwLocalTSF)) || + (LODWORD(qwBSSTimestamp) != LODWORD(qwLocalTSF))) { + qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); + // adjust TSF + // HW's TSF add TSF Offset reg + VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, LODWORD(qwTSFOffset)); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset)); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); + } + return(true); } @@ -659,43 +659,43 @@ bool CARDbUpdateTSF (void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTi * Return Value: true if succeed; otherwise false * */ -bool CARDbSetBeaconPeriod (void *pDeviceHandler, unsigned short wBeaconInterval) +bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int uBeaconInterval = 0; - unsigned int uLowNextTBTT = 0; - unsigned int uHighRemain = 0; - unsigned int uLowRemain = 0; - QWORD qwNextTBTT; - - HIDWORD(qwNextTBTT) = 0; - LODWORD(qwNextTBTT) = 0; - CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter - uBeaconInterval = wBeaconInterval * 1024; - // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval - uLowNextTBTT = (LODWORD(qwNextTBTT) >> 10) << 10; - uLowRemain = (uLowNextTBTT) % uBeaconInterval; - // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwNextTBTT)) - % uBeaconInterval; - uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; - uLowRemain = uBeaconInterval - uLowRemain; - - // check if carry when add one beacon interval - if ((~uLowNextTBTT) < uLowRemain) { - HIDWORD(qwNextTBTT) ++ ; - } - LODWORD(qwNextTBTT) = uLowNextTBTT + uLowRemain; - - // set HW beacon interval - VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); - pDevice->wBeaconInterval = wBeaconInterval; - // Set NextTBTT - VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int uBeaconInterval = 0; + unsigned int uLowNextTBTT = 0; + unsigned int uHighRemain = 0; + unsigned int uLowRemain = 0; + QWORD qwNextTBTT; + + HIDWORD(qwNextTBTT) = 0; + LODWORD(qwNextTBTT) = 0; + CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter + uBeaconInterval = wBeaconInterval * 1024; + // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval + uLowNextTBTT = (LODWORD(qwNextTBTT) >> 10) << 10; + uLowRemain = (uLowNextTBTT) % uBeaconInterval; + // high dword (mod) bcn + uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwNextTBTT)) + % uBeaconInterval; + uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; + uLowRemain = uBeaconInterval - uLowRemain; + + // check if carry when add one beacon interval + if ((~uLowNextTBTT) < uLowRemain) { + HIDWORD(qwNextTBTT)++; + } + LODWORD(qwNextTBTT) = uLowNextTBTT + uLowRemain; + + // set HW beacon interval + VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); + pDevice->wBeaconInterval = wBeaconInterval; + // Set NextTBTT + VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); + + return(true); } @@ -713,48 +713,48 @@ bool CARDbSetBeaconPeriod (void *pDeviceHandler, unsigned short wBeaconInterval) * Return Value: true if all data packet complete; otherwise false. * */ -bool CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) +bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = true; - pDevice->bStopTx0Pkt = true; - pDevice->bStopDataPkt = true; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = true; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = true; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = true; - } - - if (pDevice->bStopBeacon == true) { - if (pDevice->bIsBeaconBufReadySet == true) { - if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) { - pDevice->cbBeaconBufReadySetCnt ++; - return(false); - } - } - pDevice->bIsBeaconBufReadySet = false; - pDevice->cbBeaconBufReadySetCnt = 0; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - // wait all TD0 complete - if (pDevice->bStopTx0Pkt == true) { - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - return(false); - } - } - // wait all Data TD complete - if (pDevice->bStopDataPkt == true) { - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){ - return(false); - } - } - - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + + + if (ePktType == PKT_TYPE_802_11_ALL) { + pDevice->bStopBeacon = true; + pDevice->bStopTx0Pkt = true; + pDevice->bStopDataPkt = true; + } else if (ePktType == PKT_TYPE_802_11_BCN) { + pDevice->bStopBeacon = true; + } else if (ePktType == PKT_TYPE_802_11_MNG) { + pDevice->bStopTx0Pkt = true; + } else if (ePktType == PKT_TYPE_802_11_DATA) { + pDevice->bStopDataPkt = true; + } + + if (pDevice->bStopBeacon == true) { + if (pDevice->bIsBeaconBufReadySet == true) { + if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) { + pDevice->cbBeaconBufReadySetCnt++; + return(false); + } + } + pDevice->bIsBeaconBufReadySet = false; + pDevice->cbBeaconBufReadySetCnt = 0; + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + } + // wait all TD0 complete + if (pDevice->bStopTx0Pkt == true) { + if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { + return(false); + } + } + // wait all Data TD complete + if (pDevice->bStopDataPkt == true) { + if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { + return(false); + } + } + + return(true); } @@ -771,30 +771,30 @@ bool CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) * Return Value: true if success; false if failed. * */ -bool CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) +bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = false; - pDevice->bStopTx0Pkt = false; - pDevice->bStopDataPkt = false; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = false; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = false; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = false; - } - - if ((pDevice->bStopBeacon == false) && - (pDevice->bBeaconBufReady == true) && - (pDevice->eOPMode == OP_MODE_ADHOC)) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + + + if (ePktType == PKT_TYPE_802_11_ALL) { + pDevice->bStopBeacon = false; + pDevice->bStopTx0Pkt = false; + pDevice->bStopDataPkt = false; + } else if (ePktType == PKT_TYPE_802_11_BCN) { + pDevice->bStopBeacon = false; + } else if (ePktType == PKT_TYPE_802_11_MNG) { + pDevice->bStopTx0Pkt = false; + } else if (ePktType == PKT_TYPE_802_11_DATA) { + pDevice->bStopDataPkt = false; + } + + if ((pDevice->bStopBeacon == false) && + (pDevice->bBeaconBufReady == true) && + (pDevice->eOPMode == OP_MODE_ADHOC)) { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + } + + return(true); } @@ -815,36 +815,36 @@ bool CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) */ bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - - MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID); - memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN); - if (eOPMode == OP_MODE_ADHOC) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - } else { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - } - if (eOPMode == OP_MODE_AP) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - } else { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - } - if (eOPMode == OP_MODE_UNKNOWN) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = false; - pDevice->byRxMode &= ~RCR_BSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode ); - } else { - if (is_zero_ether_addr(pDevice->abyBSSID) == false) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = true; - pDevice->byRxMode |= RCR_BSSID; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode ); - } - // Adopt BSS state in Adapter Device Object - pDevice->eOPMode = eOPMode; - return(true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + + MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID); + memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN); + if (eOPMode == OP_MODE_ADHOC) { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); + } else { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); + } + if (eOPMode == OP_MODE_AP) { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); + } else { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); + } + if (eOPMode == OP_MODE_UNKNOWN) { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); + pDevice->bBSSIDFilter = false; + pDevice->byRxMode &= ~RCR_BSSID; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); + } else { + if (is_zero_ether_addr(pDevice->abyBSSID) == false) { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); + pDevice->bBSSIDFilter = true; + pDevice->byRxMode |= RCR_BSSID; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode); + } + // Adopt BSS state in Adapter Device Object + pDevice->eOPMode = eOPMode; + return(true); } @@ -883,14 +883,14 @@ bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE e * */ bool CARDbSetTxDataRate( - void *pDeviceHandler, - unsigned short wDataRate - ) + void *pDeviceHandler, + unsigned short wDataRate +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + PSDevice pDevice = (PSDevice) pDeviceHandler; - pDevice->wCurrentRate = wDataRate; - return(true); + pDevice->wCurrentRate = wDataRate; + return(true); } /*+ @@ -906,32 +906,32 @@ bool CARDbSetTxDataRate( * * Return Value: true if power down success; otherwise false * --*/ + -*/ bool CARDbPowerDown( - void *pDeviceHandler - ) + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice)pDeviceHandler; - unsigned int uIdx; + PSDevice pDevice = (PSDevice)pDeviceHandler; + unsigned int uIdx; - // check if already in Doze mode - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; + // check if already in Doze mode + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) + return true; - // Froce PSEN on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); + // Froce PSEN on + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - // check if all TD are empty, + // check if all TD are empty, - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } + for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { + if (pDevice->iTDUsed[uIdx] != 0) + return false; + } - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); + return true; } /* @@ -946,40 +946,40 @@ CARDbPowerDown( * Return Value: true if success; otherwise false * */ -bool CARDbRadioPowerOff (void *pDeviceHandler) +bool CARDbRadioPowerOff(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - bool bResult = true; + PSDevice pDevice = (PSDevice)pDeviceHandler; + bool bResult = true; - if (pDevice->bRadioOff == true) - return true; + if (pDevice->bRadioOff == true) + return true; - switch (pDevice->byRFType) { + switch (pDevice->byRFType) { - case RF_RFMD2959: - MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); - MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); - break; + case RF_RFMD2959: + MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); + MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); + break; - case RF_AIROHA: - case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 - MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2); - MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - break; + case RF_AIROHA: + case RF_AL2230S: + case RF_AIROHA7230: //RobertYu:20050104 + MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2); + MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + break; - } + } - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); - BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID); - pDevice->bRadioOff = true; - //2007-0409-03, by chester -printk("chester power off\n"); -MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue - return bResult; + pDevice->bRadioOff = true; + //2007-0409-03, by chester + printk("chester power off\n"); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + return bResult; } @@ -995,56 +995,56 @@ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue * Return Value: true if success; otherwise false * */ -bool CARDbRadioPowerOn (void *pDeviceHandler) +bool CARDbRadioPowerOn(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - bool bResult = true; -printk("chester power on\n"); - if (pDevice->bRadioControlOff == true){ -if (pDevice->bHWRadioOff == true) printk("chester bHWRadioOff\n"); -if (pDevice->bRadioControlOff == true) printk("chester bRadioControlOff\n"); - return false;} + PSDevice pDevice = (PSDevice) pDeviceHandler; + bool bResult = true; + printk("chester power on\n"); + if (pDevice->bRadioControlOff == true) { + if (pDevice->bHWRadioOff == true) printk("chester bHWRadioOff\n"); + if (pDevice->bRadioControlOff == true) printk("chester bRadioControlOff\n"); + return false; } - if (pDevice->bRadioOff == false) - { -printk("chester pbRadioOff\n"); -return true;} + if (pDevice->bRadioOff == false) + { + printk("chester pbRadioOff\n"); + return true; } - BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); - switch (pDevice->byRFType) { + switch (pDevice->byRFType) { - case RF_RFMD2959: - MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); - MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); - break; + case RF_RFMD2959: + MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); + MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1); + break; - case RF_AIROHA: - case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 - MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPE3)); - break; + case RF_AIROHA: + case RF_AL2230S: + case RF_AIROHA7230: //RobertYu:20050104 + MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | + SOFTPWRCTL_SWPE3)); + break; - } + } - pDevice->bRadioOff = false; + pDevice->bRadioOff = false; // 2007-0409-03, by chester -printk("chester power on\n"); -MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue - return bResult; + printk("chester power on\n"); + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + return bResult; } -bool CARDbRemoveKey (void *pDeviceHandler, unsigned char *pbyBSSID) +bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + PSDevice pDevice = (PSDevice) pDeviceHandler; - KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset); - return (true); + KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset); + return (true); } @@ -1063,66 +1063,66 @@ bool CARDbRemoveKey (void *pDeviceHandler, unsigned char *pbyBSSID) * * Return Value: none. * --*/ + -*/ bool -CARDbAdd_PMKID_Candidate ( - void *pDeviceHandler, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap - ) +CARDbAdd_PMKID_Candidate( + void *pDeviceHandler, + unsigned char *pbyBSSID, + bool bRSNCapExist, + unsigned short wRSNCap +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - PPMKID_CANDIDATE pCandidateList; - unsigned int ii = 0; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 3\n"); - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); - } - - for (ii = 0; ii < 6; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02X ", *(pbyBSSID + ii)); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - - // Update Old Candidate - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - } else { - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - } - return true; - } - } - - // New Candidate - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - } else { - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - } - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); - pDevice->gsPMKIDCandidate.NumCandidates++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; + PSDevice pDevice = (PSDevice) pDeviceHandler; + PPMKID_CANDIDATE pCandidateList; + unsigned int ii = 0; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + + if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 3\n"); + memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); + } + + for (ii = 0; ii < 6; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02X ", *(pbyBSSID + ii)); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + + // Update Old Candidate + for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { + pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; + if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { + if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { + pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; + } else { + pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); + } + return true; + } + } + + // New Candidate + pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; + if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { + pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; + } else { + pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); + } + memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); + pDevice->gsPMKIDCandidate.NumCandidates++; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + return true; } void * -CARDpGetCurrentAddress ( - void *pDeviceHandler - ) +CARDpGetCurrentAddress( + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + PSDevice pDevice = (PSDevice) pDeviceHandler; - return (pDevice->abyCurrentNetAddr); + return (pDevice->abyCurrentNetAddr); } /* @@ -1138,117 +1138,117 @@ CARDpGetCurrentAddress ( * * Return Value: none. * --*/ + -*/ bool -CARDbStartMeasure ( - void *pDeviceHandler, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs - ) +CARDbStartMeasure( + void *pDeviceHandler, + void *pvMeasureEIDs, + unsigned int uNumOfMeasureEIDs +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; - QWORD qwCurrTSF; - QWORD qwStartTSF; - bool bExpired = true; - unsigned short wDuration = 0; - - if ((pEID == NULL) || - (uNumOfMeasureEIDs == 0)) { - return (true); - } - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - if (pDevice->bMeasureInProgress == true) { - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs; - - do { - pDevice->pCurrMeasureEID = pEID; - pEID++; - pDevice->uNumOfMeasureEIDs--; - - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime))); - LODWORD(qwStartTSF) = LODWORD(*((PQWORD) (pDevice->pCurrMeasureEID->sReq.abyStartTime))); - wDuration = *((unsigned short *) (pDevice->pCurrMeasureEID->sReq.abyDuration)); - wDuration += 1; // 1 TU for channel switching - - if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) { - // start immediately by setting start TSF == current TSF + 2 TU - LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048; - HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF); - if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) { - HIDWORD(qwStartTSF)++; - } - bExpired = false; - break; - } else { - // start at setting start TSF - 1TU(for channel switching) - if (LODWORD(qwStartTSF) < 1024) { - HIDWORD(qwStartTSF)--; - } - LODWORD(qwStartTSF) -= 1024; - } - - if ((HIDWORD(qwCurrTSF) < HIDWORD(qwStartTSF)) || - ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) && - (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF))) - ) { - bExpired = false; - break; - } - VNTWIFIbMeasureReport( pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_LATE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - // hardware do not support measure - VNTWIFIbMeasureReport( pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_INCAPABLE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - } while (pDevice->uNumOfMeasureEIDs != 0); - - if (bExpired == false) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF)); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - } else { - // all measure start time expired we should complete action - VNTWIFIbMeasureReport( pDevice->pMgmt, - true, - NULL, - 0, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - return (true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; + QWORD qwCurrTSF; + QWORD qwStartTSF; + bool bExpired = true; + unsigned short wDuration = 0; + + if ((pEID == NULL) || + (uNumOfMeasureEIDs == 0)) { + return (true); + } + CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); + if (pDevice->bMeasureInProgress == true) { + pDevice->bMeasureInProgress = false; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); + // clear measure control + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); + MACvSelectPage0(pDevice->PortOffset); + set_channel(pDevice, pDevice->byOrgChannel); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + } + pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs; + + do { + pDevice->pCurrMeasureEID = pEID; + pEID++; + pDevice->uNumOfMeasureEIDs--; + + if (pDevice->byLocalID > REV_ID_VT3253_B1) { + HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime))); + LODWORD(qwStartTSF) = LODWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime))); + wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); + wDuration += 1; // 1 TU for channel switching + + if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) { + // start immediately by setting start TSF == current TSF + 2 TU + LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048; + HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF); + if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) { + HIDWORD(qwStartTSF)++; + } + bExpired = false; + break; + } else { + // start at setting start TSF - 1TU(for channel switching) + if (LODWORD(qwStartTSF) < 1024) { + HIDWORD(qwStartTSF)--; + } + LODWORD(qwStartTSF) -= 1024; + } + + if ((HIDWORD(qwCurrTSF) < HIDWORD(qwStartTSF)) || + ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) && + (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF))) +) { + bExpired = false; + break; + } + VNTWIFIbMeasureReport(pDevice->pMgmt, + false, + pDevice->pCurrMeasureEID, + MEASURE_MODE_LATE, + pDevice->byBasicMap, + pDevice->byCCAFraction, + pDevice->abyRPIs + ); + } else { + // hardware do not support measure + VNTWIFIbMeasureReport(pDevice->pMgmt, + false, + pDevice->pCurrMeasureEID, + MEASURE_MODE_INCAPABLE, + pDevice->byBasicMap, + pDevice->byCCAFraction, + pDevice->abyRPIs + ); + } + } while (pDevice->uNumOfMeasureEIDs != 0); + + if (bExpired == false) { + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF)); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF)); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); + MACvSelectPage0(pDevice->PortOffset); + } else { + // all measure start time expired we should complete action + VNTWIFIbMeasureReport(pDevice->pMgmt, + true, + NULL, + 0, + pDevice->byBasicMap, + pDevice->byCCAFraction, + pDevice->abyRPIs + ); + } + return (true); } @@ -1265,33 +1265,33 @@ CARDbStartMeasure ( * * Return Value: none. * --*/ + -*/ bool -CARDbChannelSwitch ( - void *pDeviceHandler, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount - ) +CARDbChannelSwitch( + void *pDeviceHandler, + unsigned char byMode, + unsigned char byNewChannel, + unsigned char byCount +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - bool bResult = true; - - if (byCount == 0) { - bResult = set_channel(pDevice, byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - return(bResult); - } - pDevice->byChannelSwitchCount = byCount; - pDevice->byNewChannel = byNewChannel; - pDevice->bChannelSwitch = true; - if (byMode == 1) { - bResult=CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL); - } - return (bResult); + PSDevice pDevice = (PSDevice) pDeviceHandler; + bool bResult = true; + + if (byCount == 0) { + bResult = set_channel(pDevice, byNewChannel); + VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + return(bResult); + } + pDevice->byChannelSwitchCount = byCount; + pDevice->byNewChannel = byNewChannel; + pDevice->bChannelSwitch = true; + if (byMode == 1) { + bResult = CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL); + } + return (bResult); } @@ -1308,53 +1308,53 @@ CARDbChannelSwitch ( * * Return Value: none. * --*/ + -*/ bool -CARDbSetQuiet ( - void *pDeviceHandler, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset - ) +CARDbSetQuiet( + void *pDeviceHandler, + bool bResetQuiet, + unsigned char byQuietCount, + unsigned char byQuietPeriod, + unsigned short wQuietDuration, + unsigned short wQuietOffset +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int ii = 0; - - if (bResetQuiet == true) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - for(ii=0;iisQuiet[ii].bEnable = false; - } - pDevice->uQuietEnqueue = 0; - pDevice->bEnableFirstQuiet = false; - pDevice->bQuietEnable = false; - pDevice->byQuietStartCount = byQuietCount; - } - if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) { - pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true; - pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod; - pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset; - pDevice->uQuietEnqueue++; - pDevice->uQuietEnqueue %= MAX_QUIET_COUNT; - if (pDevice->byQuietStartCount < byQuietCount) { - pDevice->byQuietStartCount = byQuietCount; - } - } else { - // we can not handle Quiet EID more - } - return (true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int ii = 0; + + if (bResetQuiet == true) { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); + for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { + pDevice->sQuiet[ii].bEnable = false; + } + pDevice->uQuietEnqueue = 0; + pDevice->bEnableFirstQuiet = false; + pDevice->bQuietEnable = false; + pDevice->byQuietStartCount = byQuietCount; + } + if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) { + pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true; + pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod; + pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration; + pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount; + pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval; + pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset; + pDevice->uQuietEnqueue++; + pDevice->uQuietEnqueue %= MAX_QUIET_COUNT; + if (pDevice->byQuietStartCount < byQuietCount) { + pDevice->byQuietStartCount = byQuietCount; + } + } else { + // we can not handle Quiet EID more + } + return (true); } /* * * Description: - * Do Quiet, It will be called by either ISR(after start) + * Do Quiet, It will be called by either ISR(after start) * or VNTWIFI(before start) so we do not need a SPINLOCK * * Parameters: @@ -1365,91 +1365,91 @@ CARDbSetQuiet ( * * Return Value: none. * --*/ + -*/ bool -CARDbStartQuiet ( - void *pDeviceHandler - ) +CARDbStartQuiet( + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int ii = 0; - unsigned long dwStartTime = 0xFFFFFFFF; - unsigned int uCurrentQuietIndex = 0; - unsigned long dwNextTime = 0; - unsigned long dwGap = 0; - unsigned long dwDuration = 0; - - for(ii=0;iisQuiet[ii].bEnable == true) && - (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) { - dwStartTime = pDevice->sQuiet[ii].dwStartTime; - uCurrentQuietIndex = ii; - } - } - if (dwStartTime == 0xFFFFFFFF) { - // no more quiet - pDevice->bQuietEnable = false; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - if (pDevice->bQuietEnable == false) { - // first quiet - pDevice->byQuietStartCount--; - dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - dwNextTime %= pDevice->wBeaconInterval; - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration); - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - pDevice->bEnableFirstQuiet = true; - } - MACvSelectPage0(pDevice->PortOffset); - } else { - if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) { - // overlap with previous Quiet - dwGap = pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) { - // return false to indicate next quiet expired, should call this function again - return (false); - } - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap; - dwGap = 0; - } else { - dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime; - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration; - } - // set GAP and Next duration - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->bQuietEnable = true; - pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration; - if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) { - // not period disable current quiet element - pDevice->sQuiet[uCurrentQuietIndex].bEnable = false; - } else { - // set next period start time - dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod; - dwNextTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime; - } - if (pDevice->dwCurrentQuietEndTime > 0x80010000) { - // decreament all time to avoid wrap around - for(ii=0;iisQuiet[ii].bEnable == true) { - pDevice->sQuiet[ii].dwStartTime -= 0x80000000; - } - } - pDevice->dwCurrentQuietEndTime -= 0x80000000; - } - } - return (true); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int ii = 0; + unsigned long dwStartTime = 0xFFFFFFFF; + unsigned int uCurrentQuietIndex = 0; + unsigned long dwNextTime = 0; + unsigned long dwGap = 0; + unsigned long dwDuration = 0; + + for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { + if ((pDevice->sQuiet[ii].bEnable == true) && + (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) { + dwStartTime = pDevice->sQuiet[ii].dwStartTime; + uCurrentQuietIndex = ii; + } + } + if (dwStartTime == 0xFFFFFFFF) { + // no more quiet + pDevice->bQuietEnable = false; + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); + } else { + if (pDevice->bQuietEnable == false) { + // first quiet + pDevice->byQuietStartCount--; + dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; + dwNextTime %= pDevice->wBeaconInterval; + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration); + if (pDevice->byQuietStartCount == 0) { + pDevice->bEnableFirstQuiet = false; + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); + } else { + pDevice->bEnableFirstQuiet = true; + } + MACvSelectPage0(pDevice->PortOffset); + } else { + if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) { + // overlap with previous Quiet + dwGap = pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; + if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) { + // return false to indicate next quiet expired, should call this function again + return (false); + } + dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap; + dwGap = 0; + } else { + dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime; + dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration; + } + // set GAP and Next duration + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT); + MACvSelectPage0(pDevice->PortOffset); + } + pDevice->bQuietEnable = true; + pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; + pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration; + if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) { + // not period disable current quiet element + pDevice->sQuiet[uCurrentQuietIndex].bEnable = false; + } else { + // set next period start time + dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod; + dwNextTime *= pDevice->wBeaconInterval; + pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime; + } + if (pDevice->dwCurrentQuietEndTime > 0x80010000) { + // decreament all time to avoid wrap around + for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { + if (pDevice->sQuiet[ii].bEnable == true) { + pDevice->sQuiet[ii].dwStartTime -= 0x80000000; + } + } + pDevice->dwCurrentQuietEndTime -= 0x80000000; + } + } + return (true); } /* @@ -1465,25 +1465,25 @@ CARDbStartQuiet ( * * Return Value: none. * --*/ + -*/ void -CARDvSetPowerConstraint ( - void *pDeviceHandler, - unsigned char byChannel, - char byPower - ) +CARDvSetPowerConstraint( + void *pDeviceHandler, + unsigned char byChannel, + char byPower +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - - if (byChannel > CB_MAX_CHANNEL_24G) { - if (pDevice->bCountryInfo5G == true) { - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - } - } else { - if (pDevice->bCountryInfo24G == true) { - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - } - } + PSDevice pDevice = (PSDevice) pDeviceHandler; + + if (byChannel > CB_MAX_CHANNEL_24G) { + if (pDevice->bCountryInfo5G == true) { + pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; + } + } else { + if (pDevice->bCountryInfo24G == true) { + pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; + } + } } @@ -1500,26 +1500,26 @@ CARDvSetPowerConstraint ( * * Return Value: none. * --*/ + -*/ void -CARDvGetPowerCapability ( - void *pDeviceHandler, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower - ) +CARDvGetPowerCapability( + void *pDeviceHandler, + unsigned char *pbyMinPower, + unsigned char *pbyMaxPower +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned char byDec = 0; - - *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh]; - byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh]; - if (pDevice->byRFType == RF_UW2452) { - byDec *= 3; - byDec >>= 1; - } else { - byDec <<= 1; - } - *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned char byDec = 0; + + *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh]; + byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh]; + if (pDevice->byRFType == RF_UW2452) { + byDec *= 3; + byDec >>= 1; + } else { + byDec <<= 1; + } + *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec; } /* @@ -1537,53 +1537,53 @@ CARDvGetPowerCapability ( * */ char -CARDbyGetTransmitPower ( - void *pDeviceHandler - ) +CARDbyGetTransmitPower( + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + PSDevice pDevice = (PSDevice) pDeviceHandler; - return (pDevice->byCurPwrdBm); + return (pDevice->byCurPwrdBm); } //xxx void -CARDvSafeResetTx ( - void *pDeviceHandler - ) +CARDvSafeResetTx( + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int uu; - PSTxDesc pCurrTD; - - // initialize TD index - pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); - pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); - - for (uu = 0; uu < TYPE_MAXTD; uu ++) - pDevice->iTDUsed[uu] = 0; - - for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) { - pCurrTD = &(pDevice->apTD0Rings[uu]); - pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL - } - for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) { - pCurrTD = &(pDevice->apTD1Rings[uu]); - pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL - } - - // set MAC TD pointer - MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset, - (pDevice->td0_pool_dma)); - - MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset, - (pDevice->td1_pool_dma)); - - // set MAC Beacon TX pointer - MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, - (pDevice->tx_beacon_dma)); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int uu; + PSTxDesc pCurrTD; + + // initialize TD index + pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); + pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); + + for (uu = 0; uu < TYPE_MAXTD; uu++) + pDevice->iTDUsed[uu] = 0; + + for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) { + pCurrTD = &(pDevice->apTD0Rings[uu]); + pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; + // init all Tx Packet pointer to NULL + } + for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) { + pCurrTD = &(pDevice->apTD1Rings[uu]); + pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; + // init all Tx Packet pointer to NULL + } + + // set MAC TD pointer + MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset, + (pDevice->td0_pool_dma)); + + MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset, + (pDevice->td1_pool_dma)); + + // set MAC Beacon TX pointer + MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, + (pDevice->tx_beacon_dma)); } @@ -1602,50 +1602,50 @@ CARDvSafeResetTx ( * * Return Value: none * --*/ + -*/ void -CARDvSafeResetRx ( - void *pDeviceHandler - ) +CARDvSafeResetRx( + void *pDeviceHandler +) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int uu; - PSRxDesc pDesc; - - - - // initialize RD index - pDevice->pCurrRD[0]=&(pDevice->aRD0Ring[0]); - pDevice->pCurrRD[1]=&(pDevice->aRD1Ring[0]); - - // init state, all RD is chip's - for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) { - pDesc =&(pDevice->aRD0Ring[uu]); - pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); - pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC; - pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); - } - - // init state, all RD is chip's - for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) { - pDesc =&(pDevice->aRD1Ring[uu]); - pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); - pDesc->m_rd0RD0.f1Owner=OWNED_BY_NIC; - pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); - } - - pDevice->cbDFCB = CB_MAX_RX_FRAG; - pDevice->cbFreeDFCB = pDevice->cbDFCB; - - // set perPkt mode - MACvRx0PerPktMode(pDevice->PortOffset); - MACvRx1PerPktMode(pDevice->PortOffset); - // set MAC RD pointer - MACvSetCurrRx0DescAddr(pDevice->PortOffset, - pDevice->rd0_pool_dma); - - MACvSetCurrRx1DescAddr(pDevice->PortOffset, - pDevice->rd1_pool_dma); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int uu; + PSRxDesc pDesc; + + + + // initialize RD index + pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); + pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); + + // init state, all RD is chip's + for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) { + pDesc = &(pDevice->aRD0Ring[uu]); + pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); + pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC; + pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); + } + + // init state, all RD is chip's + for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) { + pDesc = &(pDevice->aRD1Ring[uu]); + pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); + pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC; + pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); + } + + pDevice->cbDFCB = CB_MAX_RX_FRAG; + pDevice->cbFreeDFCB = pDevice->cbDFCB; + + // set perPkt mode + MACvRx0PerPktMode(pDevice->PortOffset); + MACvRx1PerPktMode(pDevice->PortOffset); + // set MAC RD pointer + MACvSetCurrRx0DescAddr(pDevice->PortOffset, + pDevice->rd0_pool_dma); + + MACvSetCurrRx1DescAddr(pDevice->PortOffset, + pDevice->rd1_pool_dma); } @@ -1666,16 +1666,16 @@ CARDvSafeResetRx ( */ unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int ui = (unsigned int) wRateIdx; - - while (ui > RATE_1M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { - return (unsigned short)ui; - } - ui --; - } - return (unsigned short)RATE_1M; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int ui = (unsigned int) wRateIdx; + + while (ui > RATE_1M) { + if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { + return (unsigned short)ui; + } + ui--; + } + return (unsigned short)RATE_1M; } /* @@ -1691,28 +1691,28 @@ unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRate * Return Value: response Control frame rate * */ -unsigned short CARDwGetOFDMControlRate (void *pDeviceHandler, unsigned short wRateIdx) +unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int ui = (unsigned int) wRateIdx; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate); - - if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); - if (wRateIdx > RATE_24M) - wRateIdx = RATE_24M; - return wRateIdx; - } - while (ui > RATE_11M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate : %d\n", ui); - return (unsigned short)ui; - } - ui --; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate: 6M\n"); - return (unsigned short)RATE_24M; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int ui = (unsigned int) wRateIdx; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BASIC RATE: %X\n", pDevice->wBasicRate); + + if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); + if (wRateIdx > RATE_24M) + wRateIdx = RATE_24M; + return wRateIdx; + } + while (ui > RATE_11M) { + if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate : %d\n", ui); + return (unsigned short)ui; + } + ui--; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate: 6M\n"); + return (unsigned short)RATE_24M; } @@ -1728,117 +1728,117 @@ unsigned short CARDwGetOFDMControlRate (void *pDeviceHandler, unsigned short wRa * Return Value: None. * */ -void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) +void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned char byServ = 0x00, bySignal = 0x00; //For CCK - unsigned short wLen = 0x0000; - unsigned char byTxRate, byRsvTime; //For OFDM - - //Set to Page1 - MACvSelectPage1(pDevice->PortOffset); - - //RSPINF_b_1 - BBvCalculateParameter(pDevice, - 14, - CARDwGetCCKControlRate((void *)pDevice, RATE_1M), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - ///RSPINF_b_2 - BBvCalculateParameter(pDevice, - 14, - CARDwGetCCKControlRate((void *)pDevice, RATE_2M), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_b_5 - BBvCalculateParameter(pDevice, - 14, - CARDwGetCCKControlRate((void *)pDevice, RATE_5M), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_b_11 - BBvCalculateParameter(pDevice, - 14, - CARDwGetCCKControlRate((void *)pDevice, RATE_11M), - PK_TYPE_11B, - &wLen, - &byServ, - &bySignal - ); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen,MAKEWORD(bySignal,byServ))); - //RSPINF_a_6 - s_vCalculateOFDMRParameter(RATE_6M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_9 - s_vCalculateOFDMRParameter(RATE_9M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_12 - s_vCalculateOFDMRParameter(RATE_12M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_18 - s_vCalculateOFDMRParameter(RATE_18M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_24 - s_vCalculateOFDMRParameter(RATE_24M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_36 - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_48 - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime)); - //RSPINF_a_54 - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime)); - - //RSPINF_a_72 - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate,byRsvTime)); - //Set to Page0 - MACvSelectPage0(pDevice->PortOffset); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned char byServ = 0x00, bySignal = 0x00; //For CCK + unsigned short wLen = 0x0000; + unsigned char byTxRate, byRsvTime; //For OFDM + + //Set to Page1 + MACvSelectPage1(pDevice->PortOffset); + + //RSPINF_b_1 + BBvCalculateParameter(pDevice, + 14, + CARDwGetCCKControlRate((void *)pDevice, RATE_1M), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + ///RSPINF_b_2 + BBvCalculateParameter(pDevice, + 14, + CARDwGetCCKControlRate((void *)pDevice, RATE_2M), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_b_5 + BBvCalculateParameter(pDevice, + 14, + CARDwGetCCKControlRate((void *)pDevice, RATE_5M), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_b_11 + BBvCalculateParameter(pDevice, + 14, + CARDwGetCCKControlRate((void *)pDevice, RATE_11M), + PK_TYPE_11B, + &wLen, + &byServ, + &bySignal +); + + VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ))); + //RSPINF_a_6 + s_vCalculateOFDMRParameter(RATE_6M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_9 + s_vCalculateOFDMRParameter(RATE_9M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_12 + s_vCalculateOFDMRParameter(RATE_12M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_18 + s_vCalculateOFDMRParameter(RATE_18M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_24 + s_vCalculateOFDMRParameter(RATE_24M, + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_36 + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_48 + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); + //RSPINF_a_54 + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); + + //RSPINF_a_72 + s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), + ePHYType, + &byTxRate, + &byRsvTime); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); + //Set to Page0 + MACvSelectPage0(pDevice->PortOffset); } /* @@ -1853,84 +1853,84 @@ void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) * Return Value: None. * */ -void vUpdateIFS (void *pDeviceHandler) +void vUpdateIFS(void *pDeviceHandler) { - //Set SIFS, DIFS, EIFS, SlotTime, CwMin - PSDevice pDevice = (PSDevice) pDeviceHandler; - - unsigned char byMaxMin = 0; - if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a - pDevice->uSlot = C_SLOT_SHORT; - pDevice->uSIFS = C_SIFS_A; - pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT; - pDevice->uCwMin = C_CWMIN_A; - byMaxMin = 4; - } - else if (pDevice->byPacketType==PK_TYPE_11B) {//0000 0001 0000 0000,11b - pDevice->uSlot = C_SLOT_LONG; - pDevice->uSIFS = C_SIFS_BG; - pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG; - pDevice->uCwMin = C_CWMIN_B; - byMaxMin = 5; - } - else { // PK_TYPE_11GA & PK_TYPE_11GB - pDevice->uSIFS = C_SIFS_BG; - if (pDevice->bShortSlotTime) { - pDevice->uSlot = C_SLOT_SHORT; - } else { - pDevice->uSlot = C_SLOT_LONG; - } - pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot; - if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M - pDevice->uCwMin = C_CWMIN_A; - byMaxMin = 4; - } - else { - pDevice->uCwMin = C_CWMIN_B; - byMaxMin = 5; - } - } - - pDevice->uCwMax = C_CWMAX; - pDevice->uEIFS = C_EIFS; - if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3)); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3)); - } else { - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)pDevice->uSIFS); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)pDevice->uDIFS); - } - VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot); - byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023 - VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin); + //Set SIFS, DIFS, EIFS, SlotTime, CwMin + PSDevice pDevice = (PSDevice) pDeviceHandler; + + unsigned char byMaxMin = 0; + if (pDevice->byPacketType == PK_TYPE_11A) {//0000 0000 0000 0000,11a + pDevice->uSlot = C_SLOT_SHORT; + pDevice->uSIFS = C_SIFS_A; + pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT; + pDevice->uCwMin = C_CWMIN_A; + byMaxMin = 4; + } + else if (pDevice->byPacketType == PK_TYPE_11B) {//0000 0001 0000 0000,11b + pDevice->uSlot = C_SLOT_LONG; + pDevice->uSIFS = C_SIFS_BG; + pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG; + pDevice->uCwMin = C_CWMIN_B; + byMaxMin = 5; + } + else { // PK_TYPE_11GA & PK_TYPE_11GB + pDevice->uSIFS = C_SIFS_BG; + if (pDevice->bShortSlotTime) { + pDevice->uSlot = C_SLOT_SHORT; + } else { + pDevice->uSlot = C_SLOT_LONG; + } + pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot; + if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M + pDevice->uCwMin = C_CWMIN_A; + byMaxMin = 4; + } + else { + pDevice->uCwMin = C_CWMIN_B; + byMaxMin = 5; + } + } + + pDevice->uCwMax = C_CWMAX; + pDevice->uEIFS = C_EIFS; + if (pDevice->byRFType == RF_RFMD2959) { + // bcs TX_PE will reserve 3 us + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3)); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3)); + } else { + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)pDevice->uSIFS); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)pDevice->uDIFS); + } + VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot); + byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023 + VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin); } -void CARDvUpdateBasicTopRate (void *pDeviceHandler) +void CARDvUpdateBasicTopRate(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; - unsigned char ii; - - //Determines the highest basic rate. - for (ii = RATE_54M; ii >= RATE_6M; ii --) { - if ( (pDevice->wBasicRate) & ((unsigned short)(1<byTopOFDMBasicRate = byTopOFDM; - - for (ii = RATE_11M;; ii --) { - if ( (pDevice->wBasicRate) & ((unsigned short)(1<byTopCCKBasicRate = byTopCCK; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; + unsigned char ii; + + //Determines the highest basic rate. + for (ii = RATE_54M; ii >= RATE_6M; ii--) { + if ((pDevice->wBasicRate) & ((unsigned short)(1<byTopOFDMBasicRate = byTopOFDM; + + for (ii = RATE_11M;; ii--) { + if ((pDevice->wBasicRate) & ((unsigned short)(1<byTopCCKBasicRate = byTopCCK; } @@ -1947,44 +1947,44 @@ void CARDvUpdateBasicTopRate (void *pDeviceHandler) * Return Value: true if succeeded; false if failed. * */ -bool CARDbAddBasicRate (void *pDeviceHandler, unsigned short wRateIdx) +bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned short wRate = (unsigned short)(1<wBasicRate |= wRate; + pDevice->wBasicRate |= wRate; - //Determines the highest basic rate. - CARDvUpdateBasicTopRate((void *)pDevice); + //Determines the highest basic rate. + CARDvUpdateBasicTopRate((void *)pDevice); - return(true); + return(true); } -bool CARDbIsOFDMinBasicRate (void *pDeviceHandler) +bool CARDbIsOFDMinBasicRate(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - int ii; - - for (ii = RATE_54M; ii >= RATE_6M; ii --) { - if ((pDevice->wBasicRate) & ((unsigned short)(1<= RATE_6M; ii--) { + if ((pDevice->wBasicRate) & ((unsigned short)(1 << ii))) + return true; + } + return false; } -unsigned char CARDbyGetPktType (void *pDeviceHandler) +unsigned char CARDbyGetPktType(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; - - if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) { - return (unsigned char)pDevice->byBBType; - } - else if (CARDbIsOFDMinBasicRate((void *)pDevice)) { - return PK_TYPE_11GA; - } - else { - return PK_TYPE_11GB; - } + PSDevice pDevice = (PSDevice) pDeviceHandler; + + if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) { + return (unsigned char)pDevice->byBBType; + } + else if (CARDbIsOFDMinBasicRate((void *)pDevice)) { + return PK_TYPE_11GA; + } + else { + return PK_TYPE_11GB; + } } /* @@ -2000,20 +2000,20 @@ unsigned char CARDbyGetPktType (void *pDeviceHandler) * Return Value: none * */ -void CARDvSetLoopbackMode (unsigned long dwIoBase, unsigned short wLoopbackMode) +void CARDvSetLoopbackMode(unsigned long dwIoBase, unsigned short wLoopbackMode) { - switch(wLoopbackMode) { - case CARD_LB_NONE: - case CARD_LB_MAC: - case CARD_LB_PHY: - break; - default: - ASSERT(false); - break; - } - // set MAC loopback - MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode)); - // set Baseband loopback + switch (wLoopbackMode) { + case CARD_LB_NONE: + case CARD_LB_MAC: + case CARD_LB_PHY: + break; + default: + ASSERT(false); + break; + } + // set MAC loopback + MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode)); + // set Baseband loopback } @@ -2029,15 +2029,15 @@ void CARDvSetLoopbackMode (unsigned long dwIoBase, unsigned short wLoopbackMode) * Return Value: none * */ -bool CARDbSoftwareReset (void *pDeviceHandler) +bool CARDbSoftwareReset(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + PSDevice pDevice = (PSDevice) pDeviceHandler; - // reset MAC - if (!MACbSafeSoftwareReset(pDevice->PortOffset)) - return false; + // reset MAC + if (!MACbSafeSoftwareReset(pDevice->PortOffset)) + return false; - return true; + return true; } @@ -2056,27 +2056,27 @@ bool CARDbSoftwareReset (void *pDeviceHandler) * Return Value: TSF Offset value * */ -QWORD CARDqGetTSFOffset (unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) +QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) { - QWORD qwTSFOffset; - unsigned short wRxBcnTSFOffst= 0; - - HIDWORD(qwTSFOffset) = 0; - LODWORD(qwTSFOffset) = 0; - wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE]; - (qwTSF2).u.dwLowDword += (unsigned long)(wRxBcnTSFOffst); - if ((qwTSF2).u.dwLowDword < (unsigned long)(wRxBcnTSFOffst)) { - (qwTSF2).u.dwHighDword++; - } - LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2); - if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) { - // if borrow needed - HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1 ; - } - else { - HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2); - }; - return (qwTSFOffset); + QWORD qwTSFOffset; + unsigned short wRxBcnTSFOffst = 0; + + HIDWORD(qwTSFOffset) = 0; + LODWORD(qwTSFOffset) = 0; + wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE]; + (qwTSF2).u.dwLowDword += (unsigned long)(wRxBcnTSFOffst); + if ((qwTSF2).u.dwLowDword < (unsigned long)(wRxBcnTSFOffst)) { + (qwTSF2).u.dwHighDword++; + } + LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2); + if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) { + // if borrow needed + HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1; + } + else { + HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2); + }; + return (qwTSFOffset); } @@ -2093,23 +2093,23 @@ QWORD CARDqGetTSFOffset (unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) * Return Value: true if success; otherwise false * */ -bool CARDbGetCurrentTSF (unsigned long dwIoBase, PQWORD pqwCurrTSF) +bool CARDbGetCurrentTSF(unsigned long dwIoBase, PQWORD pqwCurrTSF) { - unsigned short ww; - unsigned char byData; - - MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData); - if ( !(byData & TFTCTL_TSFCNTRRD)) - break; - } - if (ww == W_MAX_TIMEOUT) - return(false); - VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF)); - VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF)); - - return(true); + unsigned short ww; + unsigned char byData; + + MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData); + if (!(byData & TFTCTL_TSFCNTRRD)) + break; + } + if (ww == W_MAX_TIMEOUT) + return(false); + VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF)); + VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF)); + + return(true); } @@ -2127,33 +2127,33 @@ bool CARDbGetCurrentTSF (unsigned long dwIoBase, PQWORD pqwCurrTSF) * Return Value: TSF value of next Beacon * */ -QWORD CARDqGetNextTBTT (QWORD qwTSF, unsigned short wBeaconInterval) +QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval) { - unsigned int uLowNextTBTT; - unsigned int uHighRemain, uLowRemain; - unsigned int uBeaconInterval; + unsigned int uLowNextTBTT; + unsigned int uHighRemain, uLowRemain; + unsigned int uBeaconInterval; - uBeaconInterval = wBeaconInterval * 1024; - // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval - uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10; - // low dword (mod) bcn - uLowRemain = (uLowNextTBTT) % uBeaconInterval; + uBeaconInterval = wBeaconInterval * 1024; + // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval + uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10; + // low dword (mod) bcn + uLowRemain = (uLowNextTBTT) % uBeaconInterval; // uHighRemain = ((0x80000000 % uBeaconInterval)* 2 * HIDWORD(qwTSF)) // % uBeaconInterval; - // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwTSF)) - % uBeaconInterval; - uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; - uLowRemain = uBeaconInterval - uLowRemain; + // high dword (mod) bcn + uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwTSF)) + % uBeaconInterval; + uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; + uLowRemain = uBeaconInterval - uLowRemain; - // check if carry when add one beacon interval - if ((~uLowNextTBTT) < uLowRemain) - HIDWORD(qwTSF) ++ ; + // check if carry when add one beacon interval + if ((~uLowNextTBTT) < uLowRemain) + HIDWORD(qwTSF)++; - LODWORD(qwTSF) = uLowNextTBTT + uLowRemain; + LODWORD(qwTSF) = uLowNextTBTT + uLowRemain; - return (qwTSF); + return (qwTSF); } @@ -2171,21 +2171,21 @@ QWORD CARDqGetNextTBTT (QWORD qwTSF, unsigned short wBeaconInterval) * Return Value: none * */ -void CARDvSetFirstNextTBTT (unsigned long dwIoBase, unsigned short wBeaconInterval) +void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterval) { - QWORD qwNextTBTT; - - HIDWORD(qwNextTBTT) = 0; - LODWORD(qwNextTBTT) = 0; - CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter - qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); - // Set NextTBTT - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); - MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT)); - return; + QWORD qwNextTBTT; + + HIDWORD(qwNextTBTT) = 0; + LODWORD(qwNextTBTT) = 0; + CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter + qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); + // Set NextTBTT + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); + MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT)); + return; } @@ -2204,18 +2204,18 @@ void CARDvSetFirstNextTBTT (unsigned long dwIoBase, unsigned short wBeaconInterv * Return Value: none * */ -void CARDvUpdateNextTBTT (unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval) +void CARDvUpdateNextTBTT(unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval) { - qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); - // Set NextTBTT - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF)); - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF)); - MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n", - (unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF)); + qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); + // Set NextTBTT + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF)); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF)); + MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8xh:%8xh] \n", + (unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF)); - return; + return; } diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index e0836e1d5116..e45b2ce58cbe 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -53,30 +53,30 @@ #define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G) typedef enum _CARD_PHY_TYPE { - PHY_TYPE_AUTO, - PHY_TYPE_11B, - PHY_TYPE_11G, - PHY_TYPE_11A + PHY_TYPE_AUTO, + PHY_TYPE_11B, + PHY_TYPE_11G, + PHY_TYPE_11A } CARD_PHY_TYPE, *PCARD_PHY_TYPE; typedef enum _CARD_PKT_TYPE { - PKT_TYPE_802_11_BCN, - PKT_TYPE_802_11_MNG, - PKT_TYPE_802_11_DATA, - PKT_TYPE_802_11_ALL + PKT_TYPE_802_11_BCN, + PKT_TYPE_802_11_MNG, + PKT_TYPE_802_11_DATA, + PKT_TYPE_802_11_ALL } CARD_PKT_TYPE, *PCARD_PKT_TYPE; typedef enum _CARD_STATUS_TYPE { - CARD_STATUS_MEDIA_CONNECT, - CARD_STATUS_MEDIA_DISCONNECT, - CARD_STATUS_PMKID + CARD_STATUS_MEDIA_CONNECT, + CARD_STATUS_MEDIA_DISCONNECT, + CARD_STATUS_PMKID } CARD_STATUS_TYPE, *PCARD_STATUS_TYPE; typedef enum _CARD_OP_MODE { - OP_MODE_INFRASTRUCTURE, - OP_MODE_ADHOC, - OP_MODE_AP, - OP_MODE_UNKNOWN + OP_MODE_INFRASTRUCTURE, + OP_MODE_ADHOC, + OP_MODE_AP, + OP_MODE_UNKNOWN } CARD_OP_MODE, *PCARD_OP_MODE; @@ -119,78 +119,78 @@ bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE e bool CARDbPowerDown( - void *pDeviceHandler - ); + void *pDeviceHandler +); bool CARDbSetTxDataRate( - void *pDeviceHandler, - unsigned short wDataRate - ); + void *pDeviceHandler, + unsigned short wDataRate +); -bool CARDbRemoveKey (void *pDeviceHandler, unsigned char *pbyBSSID); +bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID); bool -CARDbAdd_PMKID_Candidate ( - void *pDeviceHandler, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap - ); +CARDbAdd_PMKID_Candidate( + void *pDeviceHandler, + unsigned char *pbyBSSID, + bool bRSNCapExist, + unsigned short wRSNCap +); void * -CARDpGetCurrentAddress ( - void *pDeviceHandler - ); +CARDpGetCurrentAddress( + void *pDeviceHandler +); bool -CARDbStartMeasure ( - void *pDeviceHandler, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs - ); +CARDbStartMeasure( + void *pDeviceHandler, + void *pvMeasureEIDs, + unsigned int uNumOfMeasureEIDs +); bool -CARDbChannelSwitch ( - void *pDeviceHandler, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount - ); +CARDbChannelSwitch( + void *pDeviceHandler, + unsigned char byMode, + unsigned char byNewChannel, + unsigned char byCount +); bool -CARDbSetQuiet ( - void *pDeviceHandler, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset - ); +CARDbSetQuiet( + void *pDeviceHandler, + bool bResetQuiet, + unsigned char byQuietCount, + unsigned char byQuietPeriod, + unsigned short wQuietDuration, + unsigned short wQuietOffset +); bool -CARDbStartQuiet ( - void *pDeviceHandler - ); +CARDbStartQuiet( + void *pDeviceHandler +); void -CARDvSetPowerConstraint ( - void *pDeviceHandler, - unsigned char byChannel, - char byPower - ); +CARDvSetPowerConstraint( + void *pDeviceHandler, + unsigned char byChannel, + char byPower +); void -CARDvGetPowerCapability ( - void *pDeviceHandler, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower - ); +CARDvGetPowerCapability( + void *pDeviceHandler, + unsigned char *pbyMinPower, + unsigned char *pbyMaxPower +); char -CARDbyGetTransmitPower ( - void *pDeviceHandler - ); +CARDbyGetTransmitPower( + void *pDeviceHandler +); #endif // __CARD_H__ -- cgit From 86fcb55d073ce3a3a990a1cffe930cd127db7a66 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:41 -0700 Subject: staging:vt6655:channel: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 730 +++++++++++++++++++-------------------- drivers/staging/vt6655/channel.h | 14 +- 2 files changed, 372 insertions(+), 372 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index aa76e39a46f4..569c648f481d 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -37,63 +37,63 @@ static int msglevel = MSG_LEVEL_INFO; static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL + 1] = { - {0, 0, false, 0}, - {1, 2412, true, 0}, - {2, 2417, true, 0}, - {3, 2422, true, 0}, - {4, 2427, true, 0}, - {5, 2432, true, 0}, - {6, 2437, true, 0}, - {7, 2442, true, 0}, - {8, 2447, true, 0}, - {9, 2452, true, 0}, - {10, 2457, true, 0}, - {11, 2462, true, 0}, - {12, 2467, true, 0}, - {13, 2472, true, 0}, - {14, 2484, true, 0}, - {183, 4915, true, 0}, - {184, 4920, true, 0}, - {185, 4925, true, 0}, - {187, 4935, true, 0}, - {188, 4940, true, 0}, - {189, 4945, true, 0}, - {192, 4960, true, 0}, - {196, 4980, true, 0}, - {7, 5035, true, 0}, - {8, 5040, true, 0}, - {9, 5045, true, 0}, - {11, 5055, true, 0}, - {12, 5060, true, 0}, - {16, 5080, true, 0}, - {34, 5170, true, 0}, - {36, 5180, true, 0}, - {38, 5190, true, 0}, - {40, 5200, true, 0}, - {42, 5210, true, 0}, - {44, 5220, true, 0}, - {46, 5230, true, 0}, - {48, 5240, true, 0}, - {52, 5260, true, 0}, - {56, 5280, true, 0}, - {60, 5300, true, 0}, - {64, 5320, true, 0}, - {100, 5500, true, 0}, - {104, 5520, true, 0}, - {108, 5540, true, 0}, - {112, 5560, true, 0}, - {116, 5580, true, 0}, - {120, 5600, true, 0}, - {124, 5620, true, 0}, - {128, 5640, true, 0}, - {132, 5660, true, 0}, - {136, 5680, true, 0}, - {140, 5700, true, 0}, - {149, 5745, true, 0}, - {153, 5765, true, 0}, - {157, 5785, true, 0}, - {161, 5805, true, 0}, - {165, 5825, true, 0} + {0, 0, false, 0}, + {1, 2412, true, 0}, + {2, 2417, true, 0}, + {3, 2422, true, 0}, + {4, 2427, true, 0}, + {5, 2432, true, 0}, + {6, 2437, true, 0}, + {7, 2442, true, 0}, + {8, 2447, true, 0}, + {9, 2452, true, 0}, + {10, 2457, true, 0}, + {11, 2462, true, 0}, + {12, 2467, true, 0}, + {13, 2472, true, 0}, + {14, 2484, true, 0}, + {183, 4915, true, 0}, + {184, 4920, true, 0}, + {185, 4925, true, 0}, + {187, 4935, true, 0}, + {188, 4940, true, 0}, + {189, 4945, true, 0}, + {192, 4960, true, 0}, + {196, 4980, true, 0}, + {7, 5035, true, 0}, + {8, 5040, true, 0}, + {9, 5045, true, 0}, + {11, 5055, true, 0}, + {12, 5060, true, 0}, + {16, 5080, true, 0}, + {34, 5170, true, 0}, + {36, 5180, true, 0}, + {38, 5190, true, 0}, + {40, 5200, true, 0}, + {42, 5210, true, 0}, + {44, 5220, true, 0}, + {46, 5230, true, 0}, + {48, 5240, true, 0}, + {52, 5260, true, 0}, + {56, 5280, true, 0}, + {60, 5300, true, 0}, + {64, 5320, true, 0}, + {100, 5500, true, 0}, + {104, 5520, true, 0}, + {108, 5540, true, 0}, + {112, 5560, true, 0}, + {116, 5580, true, 0}, + {120, 5600, true, 0}, + {124, 5620, true, 0}, + {128, 5640, true, 0}, + {132, 5660, true, 0}, + {136, 5680, true, 0}, + {140, 5700, true, 0}, + {149, 5745, true, 0}, + {153, 5765, true, 0}, + {157, 5785, true, 0}, + {161, 5805, true, 0}, + {165, 5825, true, 0} }; /************************************************************************ @@ -112,244 +112,244 @@ static struct ************************************************************************/ /* Country Available channels, ended with 0 */ /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ -{CCODE_FCC, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_TELEC, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_ETSI, {'E','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_RESV3, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV4, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV5, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV6, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV7, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV8, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESV9, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESVa, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESVb, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESVc, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESVd, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_RESVe, {' ',' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_ALLBAND, {' ',' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_ALBANIA, {'A','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_ALGERIA, {'D','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_ARGENTINA, {'A','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, -{CCODE_ARMENIA, {'A','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_AUSTRALIA, {'A','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_AUSTRIA, {'A','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_AZERBAIJAN, {'A','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_BAHRAIN, {'B','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_BELARUS, {'B','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_BELGIUM, {'B','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_BELIZE, {'B','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_BOLIVIA, {'B','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_BRAZIL, {'B','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_BRUNEI_DARUSSALAM, {'B','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_BULGARIA, {'B','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} }, -{CCODE_CANADA, {'C','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_CHILE, {'C','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} }, -{CCODE_CHINA, {'C','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_COLOMBIA, {'C','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_COSTA_RICA, {'C','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_CROATIA, {'H','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_CYPRUS, {'C','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_CZECH, {'C','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_DENMARK, {'D','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_DOMINICAN_REPUBLIC, {'D','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_ECUADOR, {'E','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_EGYPT, {'E','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_EL_SALVADOR, {'S','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_ESTONIA, {'E','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_FINLAND, {'F','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_FRANCE, {'F','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_GERMANY, {'D','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_GREECE, {'G','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_GEORGIA, {'G','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_GUATEMALA, {'G','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_HONDURAS, {'H','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_HONG_KONG, {'H','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_HUNGARY, {'H','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_ICELAND, {'I','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_INDIA, {'I','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_INDONESIA, {'I','D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_IRAN, {'I','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_IRELAND, {'I','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_ITALY, {'I','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_ISRAEL, {'I','L'}, { 0, 0, 0, 0, 1, 1, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_JAPAN, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_JORDAN, {'J','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_KAZAKHSTAN, {'K','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_KUWAIT, {'K','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_LATVIA, {'L','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_LEBANON, {'L','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_LEICHTENSTEIN, {'L','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_LITHUANIA, {'L','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_LUXEMBURG, {'L','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_MACAU, {'M','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_MACEDONIA, {'M','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_MALTA, {'M','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, -{CCODE_MALAYSIA, {'M','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_MEXICO, {'M','X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_MONACO, {'M','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_MOROCCO, {'M','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_NETHERLANDS, {'N','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_NEW_ZEALAND, {'N','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_NORTH_KOREA, {'K','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, -{CCODE_NORWAY, {'N','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_OMAN, {'O','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_PAKISTAN, {'P','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_PANAMA, {'P','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_PERU, {'P','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_PHILIPPINES, {'P','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_POLAND, {'P','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_PORTUGAL, {'P','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_PUERTO_RICO, {'P','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_QATAR, {'Q','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_ROMANIA, {'R','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_RUSSIA, {'R','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_SAUDI_ARABIA, {'S','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_SINGAPORE, {'S','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} }, -{CCODE_SLOVAKIA, {'S','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, -{CCODE_SLOVENIA, {'S','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_SOUTH_AFRICA, {'Z','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_SOUTH_KOREA, {'K','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, -{CCODE_SPAIN, {'E','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, -{CCODE_SWEDEN, {'S','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_SWITZERLAND, {'C','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_SYRIA, {'S','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_TAIWAN, {'T','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, -{CCODE_THAILAND, {'T','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, -{CCODE_TRINIDAD_TOBAGO, {'T','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_TUNISIA, {'T','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_TURKEY, {'T','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_UK, {'G','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, -{CCODE_UKRAINE, {'U','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_UNITED_ARAB_EMIRATES, {'A','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_UNITED_STATES, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, -{CCODE_URUGUAY, {'U','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, -{CCODE_UZBEKISTAN, {'U','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0, 0, 0} }, -{CCODE_VENEZUELA, {'V','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, -{CCODE_VIETNAM, {'V','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_YEMEN, {'Y','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_ZIMBABWE, {'Z','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, -{CCODE_JAPAN_W52_W53, {'J','J'}, { 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0} }, -{CCODE_MAX, {'U','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } + {CCODE_FCC, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_TELEC, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_ETSI, {'E' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_RESV3, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV4, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV5, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV6, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV7, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV8, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESV9, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESVa, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESVb, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESVc, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESVd, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_RESVe, {' ' , ' '}, { 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_ALLBAND, {' ' , ' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + , { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_ALBANIA, {'A' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_ALGERIA, {'D' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_ARGENTINA, {'A' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, + {CCODE_ARMENIA, {'A' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_AUSTRALIA, {'A' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_AUSTRIA, {'A' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_AZERBAIJAN, {'A' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_BAHRAIN, {'B' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_BELARUS, {'B' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_BELGIUM, {'B' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_BELIZE, {'B' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_BOLIVIA, {'B' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_BRAZIL, {'B' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_BRUNEI_DARUSSALAM, {'B' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_BULGARIA, {'B' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} }, + {CCODE_CANADA, {'C' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_CHILE, {'C' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} }, + {CCODE_CHINA, {'C' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_COLOMBIA, {'C' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_COSTA_RICA, {'C' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_CROATIA, {'H' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_CYPRUS, {'C' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_CZECH, {'C' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_DENMARK, {'D' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_DOMINICAN_REPUBLIC, {'D' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_ECUADOR, {'E' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_EGYPT, {'E' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_EL_SALVADOR, {'S' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_ESTONIA, {'E' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_FINLAND, {'F' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_FRANCE, {'F' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_GERMANY, {'D' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_GREECE, {'G' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_GEORGIA, {'G' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_GUATEMALA, {'G' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_HONDURAS, {'H' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_HONG_KONG, {'H' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_HUNGARY, {'H' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_ICELAND, {'I' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_INDIA, {'I' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_INDONESIA, {'I' , 'D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_IRAN, {'I' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_IRELAND, {'I' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_ITALY, {'I' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_ISRAEL, {'I' , 'L'}, { 0, 0, 0, 0, 1, 1, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_JAPAN, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_JORDAN, {'J' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_KAZAKHSTAN, {'K' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_KUWAIT, {'K' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_LATVIA, {'L' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_LEBANON, {'L' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_LEICHTENSTEIN, {'L' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_LITHUANIA, {'L' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_LUXEMBURG, {'L' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_MACAU, {'M' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_MACEDONIA, {'M' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_MALTA, {'M' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, + {CCODE_MALAYSIA, {'M' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_MEXICO, {'M' , 'X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_MONACO, {'M' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_MOROCCO, {'M' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_NETHERLANDS, {'N' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_NEW_ZEALAND, {'N' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_NORTH_KOREA, {'K' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, + {CCODE_NORWAY, {'N' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_OMAN, {'O' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_PAKISTAN, {'P' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_PANAMA, {'P' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_PERU, {'P' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_PHILIPPINES, {'P' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_POLAND, {'P' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_PORTUGAL, {'P' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_PUERTO_RICO, {'P' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_QATAR, {'Q' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_ROMANIA, {'R' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_RUSSIA, {'R' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_SAUDI_ARABIA, {'S' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_SINGAPORE, {'S' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} }, + {CCODE_SLOVAKIA, {'S' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, + {CCODE_SLOVENIA, {'S' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_SOUTH_AFRICA, {'Z' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_SOUTH_KOREA, {'K' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, + {CCODE_SPAIN, {'E' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, + {CCODE_SWEDEN, {'S' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_SWITZERLAND, {'C' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_SYRIA, {'S' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_TAIWAN, {'T' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, + {CCODE_THAILAND, {'T' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, + {CCODE_TRINIDAD_TOBAGO, {'T' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_TUNISIA, {'T' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_TURKEY, {'T' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_UK, {'G' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, + {CCODE_UKRAINE, {'U' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_UNITED_ARAB_EMIRATES, {'A' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_UNITED_STATES, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} + , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, + {CCODE_URUGUAY, {'U' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, + {CCODE_UZBEKISTAN, {'U' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0, 0, 0} }, + {CCODE_VENEZUELA, {'V' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} + , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, + {CCODE_VIETNAM, {'V' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_YEMEN, {'Y' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_ZIMBABWE, {'Z' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 0, 0, 0} }, + {CCODE_JAPAN_W52_W53, {'J' , 'J'}, { 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0} }, + {CCODE_MAX, {'U' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + , { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ }; @@ -382,7 +382,7 @@ bool is_channel_valid(unsigned int ChannelIndex) * If Channel Index is invalid, return invalid */ if ((ChannelIndex > CB_MAX_CHANNEL) || - (ChannelIndex == 0)) + (ChannelIndex == 0)) { bValid = false; goto exit; @@ -423,75 +423,75 @@ void init_channel_table(void *pDeviceHandler) bool bMultiBand = false; unsigned int ii; - for(ii = 1 ; ii<=CARD_MAX_CHANNEL_TBL ; ii++) { + for (ii = 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) { sChannelTbl[ii].bValid = false; } switch (pDevice->byRFType) { - case RF_RFMD2959 : - case RF_AIROHA : - case RF_AL2230S: - case RF_UW2451 : - case RF_VT3226 : - //printk("chester-false\n"); - bMultiBand = false; - break; - case RF_AIROHA7230 : - case RF_UW2452 : - case RF_NOTHING : - default : - bMultiBand = true; - break; + case RF_RFMD2959: + case RF_AIROHA: + case RF_AL2230S: + case RF_UW2451: + case RF_VT3226: + //printk("chester-false\n"); + bMultiBand = false; + break; + case RF_AIROHA7230: + case RF_UW2452: + case RF_NOTHING: + default: + bMultiBand = true; + break; } if ((pDevice->dwDiagRefCount != 0) || (pDevice->b11hEnable == true)) { if (bMultiBand == true) { - for(ii = 0 ; iiabyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1]; - pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1]; + for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { + sChannelTbl[ii + 1].bValid = true; + pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; + pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; } - for(ii = 0 ; iiabyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1]; - pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1]; + for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { + pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; + pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; } } else { - for(ii = 0 ; ii by chester if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii+1].bValid = true; - pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1]; - pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1]; + sChannelTbl[ii + 1].bValid = true; + pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; + pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; } } } } else if (pDevice->byZoneType <= CCODE_MAX) { if (bMultiBand == true) { - for(ii = 0 ; iibyZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii+1].bValid = true; - pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; + sChannelTbl[ii + 1].bValid = true; + pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; + pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; } } } else { - for(ii = 0 ; iibyZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii+1].bValid = true; - pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; + sChannelTbl[ii + 1].bValid = true; + pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; + pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; } } } } - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]); + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Zone=[%d][%c][%c]!!\n", pDevice->byZoneType, ChannelRuleTab[pDevice->byZoneType].chCountryCode[0], ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]); - for(ii = 0 ; iiabyRegPwr[ii+1] == 0) - pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1]; - if (pDevice->abyLocalPwr[ii+1] == 0) - pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1]; + for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { + if (pDevice->abyRegPwr[ii + 1] == 0) + pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; + if (pDevice->abyLocalPwr[ii + 1] == 0) + pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; } } @@ -502,7 +502,7 @@ unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelN if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G)) return (byChannelNumber); - for(ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL; ) { + for (ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL;) { if (sChannelTbl[ii].byChannelNumber == byChannelNumber) return ((unsigned char) ii); ii++; @@ -525,7 +525,7 @@ unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIn * Return Value: true if succeeded; false if failed. * */ -bool set_channel (void *pDeviceHandler, unsigned int uConnectionChannel) +bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) { PSDevice pDevice = (PSDevice) pDeviceHandler; bool bResult = true; @@ -540,10 +540,10 @@ bool set_channel (void *pDeviceHandler, unsigned int uConnectionChannel) } if ((uConnectionChannel > CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType != PHY_TYPE_11A)) { + (pDevice->eCurrentPHYType != PHY_TYPE_11A)) { CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL); } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType == PHY_TYPE_11A)) { + (pDevice->eCurrentPHYType == PHY_TYPE_11A)) { CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL); } // clear NAV @@ -552,7 +552,7 @@ bool set_channel (void *pDeviceHandler, unsigned int uConnectionChannel) //{{ RobertYu: 20041202 //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput - if ( pDevice->byRFType == RF_AIROHA7230 ) + if (pDevice->byRFType == RF_AIROHA7230) { RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (unsigned char)uConnectionChannel); } @@ -567,7 +567,7 @@ bool set_channel (void *pDeviceHandler, unsigned int uConnectionChannel) RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (unsigned char)uConnectionChannel); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDbSetMediaChannel: %d\n", (unsigned char)uConnectionChannel); BBvSoftwareReset(pDevice->PortOffset); if (pDevice->byLocalID > REV_ID_VT3253_B1) { @@ -618,13 +618,13 @@ void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) if (ePHYType == PHY_TYPE_11A) { pDevice->bCountryInfo5G = true; - for(ii = CB_MAX_CHANNEL_24G + 1 ; ii <= CARD_MAX_CHANNEL_TBL ; ii++) { + for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) { sChannelTbl[ii].bValid = false; } step = 4; } else { pDevice->bCountryInfo24G = true; - for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) { + for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { sChannelTbl[ii].bValid = false; } step = 1; @@ -633,8 +633,8 @@ void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1]; pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2]; - for(ii = 0 ; ii < uNumOfCountryInfo ; ii++) { - for(uu = 0 ; uu < pIE_Country->abyCountryInfo[ii*3+1] ; uu++) { + for (ii = 0; ii < uNumOfCountryInfo; ii++) { + for (uu = 0; uu < pIE_Country->abyCountryInfo[ii*3+1]; uu++) { byCh = get_channel_mapping(pDevice, (unsigned char)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType); sChannelTbl[byCh].bValid = true; pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2]; @@ -669,7 +669,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) // lower band byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == true) { - for (ii = 28 ; ii < 36 ; ii+= 2) { + for (ii = 28; ii < 36; ii += 2) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) { byCount++; } @@ -678,7 +678,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) *pbyChTupple++ = byCount; byLen += 2; } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == true) { - for (ii = 29 ; ii < 36 ; ii+= 2) { + for (ii = 29; ii < 36; ii += 2) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) { byCount++; } @@ -690,7 +690,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) // middle band byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == true) { - for (ii = 36 ; ii < 40 ; ii++) { + for (ii = 36; ii < 40; ii++) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) { byCount++; } @@ -702,7 +702,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) // higher band byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == true) { - for (ii = 40 ; ii < 51 ; ii++) { + for (ii = 40; ii < 51; ii++) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) { byCount++; } @@ -711,7 +711,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) *pbyChTupple++ = byCount; byLen += 2; } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == true) { - for (ii = 51 ; ii < 56 ; ii++) { + for (ii = 51; ii < 56; ii++) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) { byCount++; } @@ -735,9 +735,9 @@ void set_country_IE(void *pDeviceHandler, void *pIE) pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0]; pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]; pIECountry->abyCountryString[2] = ' '; - for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++ ) { + for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii+1].byChannelNumber; + pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii + 1].byChannelNumber; pIECountry->abyCountryInfo[pIECountry->len++] = 1; pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; } @@ -746,7 +746,7 @@ void set_country_IE(void *pDeviceHandler, void *pIE) } bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap) + unsigned char *pbyChannelNumber, unsigned char *pbyMap) { if (uChannelIndex > CB_MAX_CHANNEL) @@ -758,7 +758,7 @@ bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, } void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap) + unsigned char byMap) { if (uChannelIndex > CB_MAX_CHANNEL) @@ -779,40 +779,40 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) { unsigned int ii = 0; unsigned char byOptionChannel = 0; - int aiWeight[CB_MAX_CHANNEL_24G+1] = {-1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + int aiWeight[CB_MAX_CHANNEL_24G + 1] = {-1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; if (ePHYType == PHY_TYPE_11A) { - for(ii = CB_MAX_CHANNEL_24G + 1 ; ii <= CB_MAX_CHANNEL ; ii++) { + for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { if (sChannelTbl[ii].bValid == true) { if (byOptionChannel == 0) { byOptionChannel = (unsigned char) ii; } if (sChannelTbl[ii].byMAP == 0) { return ((unsigned char) ii); - } else if ( !(sChannelTbl[ii].byMAP & 0x08)) { + } else if (!(sChannelTbl[ii].byMAP & 0x08)) { byOptionChannel = (unsigned char) ii; } } } } else { byOptionChannel = 0; - for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) { + for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { if (sChannelTbl[ii].bValid == true) { if (sChannelTbl[ii].byMAP == 0) { aiWeight[ii] += 100; } else if (sChannelTbl[ii].byMAP & 0x01) { if (ii > 3) { - aiWeight[ii-3] -= 10; + aiWeight[ii - 3] -= 10; } if (ii > 2) { - aiWeight[ii-2] -= 20; + aiWeight[ii - 2] -= 20; } if (ii > 1) { - aiWeight[ii-1] -= 40; + aiWeight[ii - 1] -= 40; } aiWeight[ii] -= 80; if (ii < CB_MAX_CHANNEL_24G) { - aiWeight[ii+1] -= 40; + aiWeight[ii + 1] -= 40; } if (ii < (CB_MAX_CHANNEL_24G - 1)) { aiWeight[ii+2] -= 20; @@ -823,9 +823,9 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) } } } - for(ii = 1 ; ii <= CB_MAX_CHANNEL_24G ; ii++) { + for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { if ((sChannelTbl[ii].bValid == true) && - (aiWeight[ii] > aiWeight[byOptionChannel])) { + (aiWeight[ii] > aiWeight[byOptionChannel])) { byOptionChannel = (unsigned char) ii; } } diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 7038f0d3bde9..f4435a33d44f 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -29,11 +29,11 @@ /*--------------------- Export Classes ----------------------------*/ typedef struct tagSChannelTblElement { - unsigned char byChannelNumber; - unsigned int uFrequency; - bool bValid; - unsigned char byMAP; -}SChannelTblElement, *PSChannelTblElement; + unsigned char byChannelNumber; + unsigned int uFrequency; + bool bValid; + unsigned char byMAP; +} SChannelTblElement, *PSChannelTblElement; /*--------------------- Export Functions --------------------------*/ @@ -48,9 +48,9 @@ void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE); unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs); void set_country_IE(void *pDeviceHandler, void *pIE); bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap); + unsigned char *pbyChannelNumber, unsigned char *pbyMap); void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap); + unsigned char byMap); void clear_channel_map_info(void *pDeviceHandler); unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType); -- cgit From 9aa69c9ad0e1d74c54ae08be3b01026b2f1c0ed3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:42 -0700 Subject: staging:vt6655:country: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/country.h | 238 +++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h index 05fda4104200..415e7672aa32 100644 --- a/drivers/staging/vt6655/country.h +++ b/drivers/staging/vt6655/country.h @@ -38,125 +38,125 @@ * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf ************************************************************************/ typedef enum _COUNTRY_CODE { - CCODE_FCC = 0, - CCODE_TELEC, - CCODE_ETSI, - CCODE_RESV3, - CCODE_RESV4, - CCODE_RESV5, - CCODE_RESV6, - CCODE_RESV7, - CCODE_RESV8, - CCODE_RESV9, - CCODE_RESVa, - CCODE_RESVb, - CCODE_RESVc, - CCODE_RESVd, - CCODE_RESVe, - CCODE_ALLBAND, - CCODE_ALBANIA, - CCODE_ALGERIA, - CCODE_ARGENTINA, - CCODE_ARMENIA, - CCODE_AUSTRALIA, - CCODE_AUSTRIA, - CCODE_AZERBAIJAN, - CCODE_BAHRAIN, - CCODE_BELARUS, - CCODE_BELGIUM, - CCODE_BELIZE, - CCODE_BOLIVIA, - CCODE_BRAZIL, - CCODE_BRUNEI_DARUSSALAM, - CCODE_BULGARIA, - CCODE_CANADA, - CCODE_CHILE, - CCODE_CHINA, - CCODE_COLOMBIA, - CCODE_COSTA_RICA, - CCODE_CROATIA, - CCODE_CYPRUS, - CCODE_CZECH, - CCODE_DENMARK, - CCODE_DOMINICAN_REPUBLIC, - CCODE_ECUADOR, - CCODE_EGYPT, - CCODE_EL_SALVADOR, - CCODE_ESTONIA, - CCODE_FINLAND, - CCODE_FRANCE, - CCODE_GERMANY, - CCODE_GREECE, - CCODE_GEORGIA, - CCODE_GUATEMALA, - CCODE_HONDURAS, - CCODE_HONG_KONG, - CCODE_HUNGARY, - CCODE_ICELAND, - CCODE_INDIA, - CCODE_INDONESIA, - CCODE_IRAN, - CCODE_IRELAND, - CCODE_ITALY, - CCODE_ISRAEL, - CCODE_JAPAN, - CCODE_JORDAN, - CCODE_KAZAKHSTAN, - CCODE_KUWAIT, - CCODE_LATVIA, - CCODE_LEBANON, - CCODE_LEICHTENSTEIN, - CCODE_LITHUANIA, - CCODE_LUXEMBURG, - CCODE_MACAU, - CCODE_MACEDONIA, - CCODE_MALTA, - CCODE_MALAYSIA, - CCODE_MEXICO, - CCODE_MONACO, - CCODE_MOROCCO, - CCODE_NETHERLANDS, - CCODE_NEW_ZEALAND, - CCODE_NORTH_KOREA, - CCODE_NORWAY, - CCODE_OMAN, - CCODE_PAKISTAN, - CCODE_PANAMA, - CCODE_PERU, - CCODE_PHILIPPINES, - CCODE_POLAND, - CCODE_PORTUGAL, - CCODE_PUERTO_RICO, - CCODE_QATAR, - CCODE_ROMANIA, - CCODE_RUSSIA, - CCODE_SAUDI_ARABIA, - CCODE_SINGAPORE, - CCODE_SLOVAKIA, - CCODE_SLOVENIA, - CCODE_SOUTH_AFRICA, - CCODE_SOUTH_KOREA, - CCODE_SPAIN, - CCODE_SWEDEN, - CCODE_SWITZERLAND, - CCODE_SYRIA, - CCODE_TAIWAN, - CCODE_THAILAND, - CCODE_TRINIDAD_TOBAGO, - CCODE_TUNISIA, - CCODE_TURKEY, - CCODE_UK, - CCODE_UKRAINE, - CCODE_UNITED_ARAB_EMIRATES, - CCODE_UNITED_STATES, - CCODE_URUGUAY, - CCODE_UZBEKISTAN, - CCODE_VENEZUELA, - CCODE_VIETNAM, - CCODE_YEMEN, - CCODE_ZIMBABWE, - CCODE_JAPAN_W52_W53, - CCODE_MAX + CCODE_FCC = 0, + CCODE_TELEC, + CCODE_ETSI, + CCODE_RESV3, + CCODE_RESV4, + CCODE_RESV5, + CCODE_RESV6, + CCODE_RESV7, + CCODE_RESV8, + CCODE_RESV9, + CCODE_RESVa, + CCODE_RESVb, + CCODE_RESVc, + CCODE_RESVd, + CCODE_RESVe, + CCODE_ALLBAND, + CCODE_ALBANIA, + CCODE_ALGERIA, + CCODE_ARGENTINA, + CCODE_ARMENIA, + CCODE_AUSTRALIA, + CCODE_AUSTRIA, + CCODE_AZERBAIJAN, + CCODE_BAHRAIN, + CCODE_BELARUS, + CCODE_BELGIUM, + CCODE_BELIZE, + CCODE_BOLIVIA, + CCODE_BRAZIL, + CCODE_BRUNEI_DARUSSALAM, + CCODE_BULGARIA, + CCODE_CANADA, + CCODE_CHILE, + CCODE_CHINA, + CCODE_COLOMBIA, + CCODE_COSTA_RICA, + CCODE_CROATIA, + CCODE_CYPRUS, + CCODE_CZECH, + CCODE_DENMARK, + CCODE_DOMINICAN_REPUBLIC, + CCODE_ECUADOR, + CCODE_EGYPT, + CCODE_EL_SALVADOR, + CCODE_ESTONIA, + CCODE_FINLAND, + CCODE_FRANCE, + CCODE_GERMANY, + CCODE_GREECE, + CCODE_GEORGIA, + CCODE_GUATEMALA, + CCODE_HONDURAS, + CCODE_HONG_KONG, + CCODE_HUNGARY, + CCODE_ICELAND, + CCODE_INDIA, + CCODE_INDONESIA, + CCODE_IRAN, + CCODE_IRELAND, + CCODE_ITALY, + CCODE_ISRAEL, + CCODE_JAPAN, + CCODE_JORDAN, + CCODE_KAZAKHSTAN, + CCODE_KUWAIT, + CCODE_LATVIA, + CCODE_LEBANON, + CCODE_LEICHTENSTEIN, + CCODE_LITHUANIA, + CCODE_LUXEMBURG, + CCODE_MACAU, + CCODE_MACEDONIA, + CCODE_MALTA, + CCODE_MALAYSIA, + CCODE_MEXICO, + CCODE_MONACO, + CCODE_MOROCCO, + CCODE_NETHERLANDS, + CCODE_NEW_ZEALAND, + CCODE_NORTH_KOREA, + CCODE_NORWAY, + CCODE_OMAN, + CCODE_PAKISTAN, + CCODE_PANAMA, + CCODE_PERU, + CCODE_PHILIPPINES, + CCODE_POLAND, + CCODE_PORTUGAL, + CCODE_PUERTO_RICO, + CCODE_QATAR, + CCODE_ROMANIA, + CCODE_RUSSIA, + CCODE_SAUDI_ARABIA, + CCODE_SINGAPORE, + CCODE_SLOVAKIA, + CCODE_SLOVENIA, + CCODE_SOUTH_AFRICA, + CCODE_SOUTH_KOREA, + CCODE_SPAIN, + CCODE_SWEDEN, + CCODE_SWITZERLAND, + CCODE_SYRIA, + CCODE_TAIWAN, + CCODE_THAILAND, + CCODE_TRINIDAD_TOBAGO, + CCODE_TUNISIA, + CCODE_TURKEY, + CCODE_UK, + CCODE_UKRAINE, + CCODE_UNITED_ARAB_EMIRATES, + CCODE_UNITED_STATES, + CCODE_URUGUAY, + CCODE_UZBEKISTAN, + CCODE_VENEZUELA, + CCODE_VIETNAM, + CCODE_YEMEN, + CCODE_ZIMBABWE, + CCODE_JAPAN_W52_W53, + CCODE_MAX } COUNTRY_CODE; #endif /* __COUNTRY_H__ */ -- cgit From b8314cfc885e157dd0405ea195d5682f7f0debd5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:43 -0700 Subject: staging:vt6655:datarate: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/datarate.c | 456 +++++++++++++++++++------------------- drivers/staging/vt6655/datarate.h | 42 ++-- 2 files changed, 249 insertions(+), 249 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index b86ec1b6d187..32e4d4a116eb 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -51,10 +51,10 @@ /*--------------------- Static Classes ----------------------------*/ - extern unsigned short TxRate_iwconfig; //2008-5-8 by chester +extern unsigned short TxRate_iwconfig; //2008-5-8 by chester /*--------------------- Static Variables --------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; const unsigned char acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; @@ -64,24 +64,24 @@ const unsigned char acbyIERate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ -void s_vResetCounter ( - PKnownNodeDB psNodeDBTable - ); +void s_vResetCounter( + PKnownNodeDB psNodeDBTable +); void -s_vResetCounter ( - PKnownNodeDB psNodeDBTable - ) +s_vResetCounter( + PKnownNodeDB psNodeDBTable +) { - unsigned char ii; + unsigned char ii; - // clear statistic counter for auto_rate - for(ii=0;ii<=MAX_RATE;ii++) { - psNodeDBTable->uTxOk[ii] = 0; - psNodeDBTable->uTxFail[ii] = 0; - } + // clear statistic counter for auto_rate + for (ii = 0; ii <= MAX_RATE; ii++) { + psNodeDBTable->uTxOk[ii] = 0; + psNodeDBTable->uTxFail[ii] = 0; + } } /*--------------------- Export Variables --------------------------*/ @@ -103,22 +103,22 @@ s_vResetCounter ( * * Return Value: RateIdx * --*/ + -*/ unsigned char -DATARATEbyGetRateIdx ( - unsigned char byRate - ) +DATARATEbyGetRateIdx( + unsigned char byRate +) { - unsigned char ii; + unsigned char ii; - //Erase basicRate flag. - byRate = byRate & 0x7F;//0111 1111 + //Erase basicRate flag. + byRate = byRate & 0x7F;//0111 1111 - for (ii = 0; ii < MAX_RATE; ii ++) { - if (acbyIERate[ii] == byRate) - return ii; - } - return 0; + for (ii = 0; ii < MAX_RATE; ii++) { + if (acbyIERate[ii] == byRate) + return ii; + } + return 0; } @@ -137,7 +137,7 @@ DATARATEbyGetRateIdx ( * * Return Value: none * --*/ + -*/ #define AUTORATE_TXCNT_THRESHOLD 20 #define AUTORATE_INC_THRESHOLD 30 @@ -157,22 +157,22 @@ DATARATEbyGetRateIdx ( * * Return Value: RateIdx * --*/ + -*/ unsigned short wGetRateIdx( - unsigned char byRate - ) + unsigned char byRate +) { - unsigned short ii; + unsigned short ii; - //Erase basicRate flag. - byRate = byRate & 0x7F;//0111 1111 + //Erase basicRate flag. + byRate = byRate & 0x7F;//0111 1111 - for (ii = 0; ii < MAX_RATE; ii ++) { - if (acbyIERate[ii] == byRate) - return ii; - } - return 0; + for (ii = 0; ii < MAX_RATE; ii++) { + if (acbyIERate[ii] == byRate) + return ii; + } + return 0; } /*+ @@ -193,99 +193,99 @@ wGetRateIdx( * * Return Value: none * --*/ + -*/ void -RATEvParseMaxRate ( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate - ) +RATEvParseMaxRate( + void *pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + bool bUpdateBasicRate, + unsigned short *pwMaxBasicRate, + unsigned short *pwMaxSuppRate, + unsigned short *pwSuppRate, + unsigned char *pbyTopCCKRate, + unsigned char *pbyTopOFDMRate +) { -PSDevice pDevice = (PSDevice) pDeviceHandler; -unsigned int ii; -unsigned char byHighSuppRate = 0; -unsigned char byRate = 0; -unsigned short wOldBasicRate = pDevice->wBasicRate; -unsigned int uRateLen; - - - if (pItemRates == NULL) - return; - - *pwSuppRate = 0; - uRateLen = pItemRates->len; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen); - if (pDevice->eCurrentPHYType != PHY_TYPE_11B) { - if (uRateLen > WLAN_RATES_MAXLEN) - uRateLen = WLAN_RATES_MAXLEN; - } else { - if (uRateLen > WLAN_RATES_MAXLEN_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - } - - for (ii = 0; ii < uRateLen; ii++) { - byRate = (unsigned char)(pItemRates->abyRates[ii]); - if (WLAN_MGMT_IS_BASICRATE(byRate) && - (bUpdateBasicRate == true)) { - // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<byElementID == WLAN_EID_EXTSUPP_RATES) && - (pDevice->eCurrentPHYType != PHY_TYPE_11B)) { - - unsigned int uExtRateLen = pItemExtRates->len; - - if (uExtRateLen > WLAN_RATES_MAXLEN) - uExtRateLen = WLAN_RATES_MAXLEN; - - for (ii = 0; ii < uExtRateLen ; ii++) { - byRate = (unsigned char)(pItemExtRates->abyRates[ii]); - // select highest basic rate - if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { - // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice)) { - pDevice->byPacketType = PK_TYPE_11GA; - } - - *pbyTopCCKRate = pDevice->byTopCCKBasicRate; - *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate; - *pwMaxSuppRate = wGetRateIdx(byHighSuppRate); - if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB)) - *pwMaxBasicRate = pDevice->byTopCCKBasicRate; - else - *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; - if (wOldBasicRate != pDevice->wBasicRate) - CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n"); + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned int ii; + unsigned char byHighSuppRate = 0; + unsigned char byRate = 0; + unsigned short wOldBasicRate = pDevice->wBasicRate; + unsigned int uRateLen; + + + if (pItemRates == NULL) + return; + + *pwSuppRate = 0; + uRateLen = pItemRates->len; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate Len: %d\n", uRateLen); + if (pDevice->eCurrentPHYType != PHY_TYPE_11B) { + if (uRateLen > WLAN_RATES_MAXLEN) + uRateLen = WLAN_RATES_MAXLEN; + } else { + if (uRateLen > WLAN_RATES_MAXLEN_11B) + uRateLen = WLAN_RATES_MAXLEN_11B; + } + + for (ii = 0; ii < uRateLen; ii++) { + byRate = (unsigned char)(pItemRates->abyRates[ii]); + if (WLAN_MGMT_IS_BASICRATE(byRate) && + (bUpdateBasicRate == true)) { + // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate + CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); + } + byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F); + if (byHighSuppRate == 0) + byHighSuppRate = byRate; + if (byRate > byHighSuppRate) + byHighSuppRate = byRate; + *pwSuppRate |= (1<byElementID == WLAN_EID_EXTSUPP_RATES) && + (pDevice->eCurrentPHYType != PHY_TYPE_11B)) { + + unsigned int uExtRateLen = pItemExtRates->len; + + if (uExtRateLen > WLAN_RATES_MAXLEN) + uExtRateLen = WLAN_RATES_MAXLEN; + + for (ii = 0; ii < uExtRateLen; ii++) { + byRate = (unsigned char)(pItemExtRates->abyRates[ii]); + // select highest basic rate + if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { + // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate + CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); + } + byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F); + if (byHighSuppRate == 0) + byHighSuppRate = byRate; + if (byRate > byHighSuppRate) + byHighSuppRate = byRate; + *pwSuppRate |= (1<byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice)) { + pDevice->byPacketType = PK_TYPE_11GA; + } + + *pbyTopCCKRate = pDevice->byTopCCKBasicRate; + *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate; + *pwMaxSuppRate = wGetRateIdx(byHighSuppRate); + if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB)) + *pwMaxBasicRate = pDevice->byTopCCKBasicRate; + else + *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; + if (wOldBasicRate != pDevice->wBasicRate) + CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Exit ParseMaxRate\n"); } @@ -303,96 +303,96 @@ unsigned int uRateLen; * * Return Value: none * --*/ + -*/ #define AUTORATE_TXCNT_THRESHOLD 20 #define AUTORATE_INC_THRESHOLD 30 void -RATEvTxRateFallBack ( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable - ) +RATEvTxRateFallBack( + void *pDeviceHandler, + PKnownNodeDB psNodeDBTable +) { -PSDevice pDevice = (PSDevice) pDeviceHandler; -unsigned short wIdxDownRate = 0; -unsigned int ii; + PSDevice pDevice = (PSDevice) pDeviceHandler; + unsigned short wIdxDownRate = 0; + unsigned int ii; //unsigned long dwRateTable[MAX_RATE] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; -bool bAutoRate[MAX_RATE] = {true,true,true,true,false,false,true,true,true,true,true,true}; + bool bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true, true, true, true, true, true}; unsigned long dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540}; unsigned long dwThroughput = 0; unsigned short wIdxUpRate = 0; unsigned long dwTxDiff = 0; - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { - // Don't do Fallback when scanning Channel - return; - } - - psNodeDBTable->uTimeCount ++; - - if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE]) - dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE]; - - if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) && - (dwTxDiff < AUTORATE_TXFAIL_CNT) && - (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) { - return; - } - - if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) { - psNodeDBTable->uTimeCount = 0; - } - - - for(ii=0;iiwSuppRate & (0x0001<wTxDataRate;ii++) { - if ( (psNodeDBTable->uTxOk[ii] != 0) || - (psNodeDBTable->uTxFail[ii] != 0) ) { - dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii]; - if (ii < RATE_11M) { - psNodeDBTable->uTxFail[ii] *= 4; - } - dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]); - } -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n", + if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { + // Don't do Fallback when scanning Channel + return; + } + + psNodeDBTable->uTimeCount++; + + if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE]) + dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE]; + + if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) && + (dwTxDiff < AUTORATE_TXFAIL_CNT) && + (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) { + return; + } + + if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) { + psNodeDBTable->uTimeCount = 0; + } + + + for (ii = 0; ii < MAX_RATE; ii++) { + if (psNodeDBTable->wSuppRate & (0x0001<wTxDataRate; ii++) { + if ((psNodeDBTable->uTxOk[ii] != 0) || + (psNodeDBTable->uTxFail[ii] != 0)) { + dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii]; + if (ii < RATE_11M) { + psNodeDBTable->uTxFail[ii] *= 4; + } + dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]); + } +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rate %d,Ok: %d, Fail:%d, Throughput:%d\n", // ii, psNodeDBTable->uTxOk[ii], psNodeDBTable->uTxFail[ii], dwThroughputTbl[ii]); - } - dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate]; - - wIdxDownRate = psNodeDBTable->wTxDataRate; - for(ii = psNodeDBTable->wTxDataRate; ii > 0;) { - ii--; - if ( (dwThroughputTbl[ii] > dwThroughput) && - (bAutoRate[ii]==true) ) { - dwThroughput = dwThroughputTbl[ii]; - wIdxDownRate = (unsigned short) ii; - } - } - psNodeDBTable->wTxDataRate = wIdxDownRate; - if (psNodeDBTable->uTxOk[MAX_RATE]) { - if (psNodeDBTable->uTxOk[MAX_RATE] > - (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) { - psNodeDBTable->wTxDataRate = wIdxUpRate; - } - }else { // adhoc, if uTxOk =0 & uTxFail = 0 - if (psNodeDBTable->uTxFail[MAX_RATE] == 0) - psNodeDBTable->wTxDataRate = wIdxUpRate; - } + } + dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate]; + + wIdxDownRate = psNodeDBTable->wTxDataRate; + for (ii = psNodeDBTable->wTxDataRate; ii > 0;) { + ii--; + if ((dwThroughputTbl[ii] > dwThroughput) && + (bAutoRate[ii] == true)) { + dwThroughput = dwThroughputTbl[ii]; + wIdxDownRate = (unsigned short) ii; + } + } + psNodeDBTable->wTxDataRate = wIdxDownRate; + if (psNodeDBTable->uTxOk[MAX_RATE]) { + if (psNodeDBTable->uTxOk[MAX_RATE] > + (psNodeDBTable->uTxFail[MAX_RATE] * 4)) { + psNodeDBTable->wTxDataRate = wIdxUpRate; + } + } else { // adhoc, if uTxOk =0 & uTxFail = 0 + if (psNodeDBTable->uTxFail[MAX_RATE] == 0) + psNodeDBTable->wTxDataRate = wIdxUpRate; + } //2008-5-8 by chester -TxRate_iwconfig=psNodeDBTable->wTxDataRate; - s_vResetCounter(psNodeDBTable); -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", psNodeDBTable->wTxDataRate, wIdxUpRate, wIdxDownRate); + TxRate_iwconfig = psNodeDBTable->wTxDataRate; + s_vResetCounter(psNodeDBTable); +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rate: %d, U:%d, D:%d\n", psNodeDBTable->wTxDataRate, wIdxUpRate, wIdxDownRate); - return; + return; } @@ -408,30 +408,30 @@ TxRate_iwconfig=psNodeDBTable->wTxDataRate; * * Return Value: None * --*/ + -*/ unsigned char -RATEuSetIE ( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen - ) +RATEuSetIE( + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + unsigned int uRateLen +) { - unsigned int ii, uu, uRateCnt = 0; - - if ((pSrcRates == NULL) || (pDstRates == NULL)) - return 0; - - if (pSrcRates->len == 0) - return 0; - - for (ii = 0; ii < uRateLen; ii++) { - for (uu = 0; uu < pSrcRates->len; uu++) { - if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) { - pDstRates->abyRates[uRateCnt ++] = pSrcRates->abyRates[uu]; - break; - } - } - } - return (unsigned char)uRateCnt; + unsigned int ii, uu, uRateCnt = 0; + + if ((pSrcRates == NULL) || (pDstRates == NULL)) + return 0; + + if (pSrcRates->len == 0) + return 0; + + for (ii = 0; ii < uRateLen; ii++) { + for (uu = 0; uu < pSrcRates->len; uu++) { + if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) { + pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu]; + break; + } + } + } + return (unsigned char)uRateCnt; } diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index 4f8ea0b0532d..d508f56e6699 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -56,40 +56,40 @@ void RATEvParseMaxRate( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate - ); + void *pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + bool bUpdateBasicRate, + unsigned short *pwMaxBasicRate, + unsigned short *pwMaxSuppRate, + unsigned short *pwSuppRate, + unsigned char *pbyTopCCKRate, + unsigned char *pbyTopOFDMRate +); void RATEvTxRateFallBack( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable - ); + void *pDeviceHandler, + PKnownNodeDB psNodeDBTable +); unsigned char RATEuSetIE( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen - ); + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + unsigned int uRateLen +); unsigned short wGetRateIdx( - unsigned char byRate - ); + unsigned char byRate +); unsigned char DATARATEbyGetRateIdx( - unsigned char byRate - ); + unsigned char byRate +); #endif //__DATARATE_H__ -- cgit From 78a717d8275c20c56b3f197ebaf2f377e72929fe Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:44 -0700 Subject: staging:vt6655:desc: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 482 +++++++++++++++++++++--------------------- 1 file changed, 241 insertions(+), 241 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 084a1a5566ad..0358386c42f3 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -89,7 +89,7 @@ // max transmit or receive buffer size #define CB_MAX_BUF_SIZE 2900U // max buffer size - // NOTE: must be multiple of 4 + // NOTE: must be multiple of 4 #define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE // max Tx buffer size #define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE // max Rx buffer size when not use Multi-RD @@ -101,10 +101,10 @@ #define CB_MIN_TX_DESC 16 // min # of tx descriptor #define CB_MAX_RECEIVED_PACKETS 16 // max # of received packets at one time - // limit our receive routine to indicating - // this many at a time for 2 reasons: - // 1. driver flow control to protocol layer - // 2. limit the time used in ISR routine + // limit our receive routine to indicating + // this many at a time for 2 reasons: + // 1. driver flow control to protocol layer + // 2. limit the time used in ISR routine #define CB_EXTRA_RD_NUM 32 // default # of Extra RD #define CB_RD_NUM 32 // default # of RD @@ -213,28 +213,28 @@ // may link to older skb that leads error. typedef struct tagDEVICE_RD_INFO { - struct sk_buff* skb; - dma_addr_t skb_dma; - dma_addr_t curr_desc; + struct sk_buff *skb; + dma_addr_t skb_dma; + dma_addr_t curr_desc; } DEVICE_RD_INFO, *PDEVICE_RD_INFO; /* -static inline PDEVICE_RD_INFO alloc_rd_info(void) { - PDEVICE_RD_INFO ptr; - ptr = kmalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC); - if (ptr == NULL) - return NULL; - else { - memset(ptr,0,sizeof(DEVICE_RD_INFO)); - return ptr; - } -} + static inline PDEVICE_RD_INFO alloc_rd_info(void) { + PDEVICE_RD_INFO ptr; + ptr = kmalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC); + if (ptr == NULL) + return NULL; + else { + memset(ptr,0,sizeof(DEVICE_RD_INFO)); + return ptr; + } + } */ /* -typedef struct tagRDES0 { - unsigned short wResCount; - unsigned short wf1Owner ; + typedef struct tagRDES0 { + unsigned short wResCount; + unsigned short wf1Owner; // unsigned short f15Reserved : 15; // unsigned short f1Owner : 1; } __attribute__ ((__packed__)) @@ -244,11 +244,11 @@ SRDES0; #ifdef __BIG_ENDIAN typedef struct tagRDES0 { - volatile unsigned short wResCount; + volatile unsigned short wResCount; union { volatile u16 f15Reserved; struct { - volatile u8 f8Reserved1; + volatile u8 f8Reserved1; volatile u8 f1Owner:1; volatile u8 f7Reserved:7; } __attribute__ ((__packed__)); @@ -259,9 +259,9 @@ SRDES0, *PSRDES0; #else typedef struct tagRDES0 { - unsigned short wResCount; - unsigned short f15Reserved : 15; - unsigned short f1Owner : 1; + unsigned short wResCount; + unsigned short f15Reserved:15; + unsigned short f1Owner:1; } __attribute__ ((__packed__)) SRDES0; @@ -269,8 +269,8 @@ SRDES0; #endif typedef struct tagRDES1 { - unsigned short wReqCount; - unsigned short wReserved; + unsigned short wReqCount; + unsigned short wReserved; } __attribute__ ((__packed__)) SRDES1; @@ -278,13 +278,13 @@ SRDES1; // Rx descriptor // typedef struct tagSRxDesc { - volatile SRDES0 m_rd0RD0; - volatile SRDES1 m_rd1RD1; - volatile u32 buff_addr; - volatile u32 next_desc; - struct tagSRxDesc *next;//4 bytes - volatile PDEVICE_RD_INFO pRDInfo;//4 bytes - volatile u32 Reserved[2];//8 bytes + volatile SRDES0 m_rd0RD0; + volatile SRDES1 m_rd1RD1; + volatile u32 buff_addr; + volatile u32 next_desc; + struct tagSRxDesc *next;//4 bytes + volatile PDEVICE_RD_INFO pRDInfo;//4 bytes + volatile u32 Reserved[2];//8 bytes } __attribute__ ((__packed__)) SRxDesc, *PSRxDesc; typedef const SRxDesc *PCSRxDesc; @@ -292,10 +292,10 @@ typedef const SRxDesc *PCSRxDesc; #ifdef __BIG_ENDIAN /* -typedef struct tagTDES0 { - volatile unsigned char byTSR0; - volatile unsigned char byTSR1; - volatile unsigned short wOwner_Txtime; + typedef struct tagTDES0 { + volatile unsigned char byTSR0; + volatile unsigned char byTSR1; + volatile unsigned short wOwner_Txtime; // volatile unsigned short f15Txtime : 15; // volatile unsigned short f1Owner:1; } __attribute__ ((__packed__)) @@ -303,12 +303,12 @@ STDES0; */ typedef struct tagTDES0 { - volatile unsigned char byTSR0; - volatile unsigned char byTSR1; + volatile unsigned char byTSR0; + volatile unsigned char byTSR1; union { volatile u16 f15Txtime; struct { - volatile u8 f8Reserved1; + volatile u8 f8Reserved1; volatile u8 f1Owner:1; volatile u8 f7Reserved:7; } __attribute__ ((__packed__)); @@ -319,10 +319,10 @@ STDES0, PSTDES0; #else typedef struct tagTDES0 { - volatile unsigned char byTSR0; - volatile unsigned char byTSR1; - volatile unsigned short f15Txtime : 15; - volatile unsigned short f1Owner:1; + volatile unsigned char byTSR0; + volatile unsigned char byTSR1; + volatile unsigned short f15Txtime:15; + volatile unsigned short f1Owner:1; } __attribute__ ((__packed__)) STDES0; @@ -330,63 +330,63 @@ STDES0; typedef struct tagTDES1 { - volatile unsigned short wReqCount; - volatile unsigned char byTCR; - volatile unsigned char byReserved; + volatile unsigned short wReqCount; + volatile unsigned char byTCR; + volatile unsigned char byReserved; } __attribute__ ((__packed__)) STDES1; -typedef struct tagDEVICE_TD_INFO{ - struct sk_buff* skb; - unsigned char *buf; - dma_addr_t skb_dma; - dma_addr_t buf_dma; - dma_addr_t curr_desc; - unsigned long dwReqCount; - unsigned long dwHeaderLength; - unsigned char byFlags; +typedef struct tagDEVICE_TD_INFO { + struct sk_buff *skb; + unsigned char *buf; + dma_addr_t skb_dma; + dma_addr_t buf_dma; + dma_addr_t curr_desc; + unsigned long dwReqCount; + unsigned long dwHeaderLength; + unsigned char byFlags; } DEVICE_TD_INFO, *PDEVICE_TD_INFO; /* -static inline PDEVICE_TD_INFO alloc_td_info(void) { - PDEVICE_TD_INFO ptr; - ptr = kmalloc(sizeof(DEVICE_TD_INFO),GFP_ATOMIC); - if (ptr == NULL) - return NULL; - else { - memset(ptr,0,sizeof(DEVICE_TD_INFO)); - return ptr; - } -} + static inline PDEVICE_TD_INFO alloc_td_info(void) { + PDEVICE_TD_INFO ptr; + ptr = kmalloc(sizeof(DEVICE_TD_INFO),GFP_ATOMIC); + if (ptr == NULL) + return NULL; + else { + memset(ptr,0,sizeof(DEVICE_TD_INFO)); + return ptr; + } + } */ // // transmit descriptor // typedef struct tagSTxDesc { - volatile STDES0 m_td0TD0; - volatile STDES1 m_td1TD1; - volatile u32 buff_addr; - volatile u32 next_desc; - struct tagSTxDesc* next; //4 bytes - volatile PDEVICE_TD_INFO pTDInfo;//4 bytes - volatile u32 Reserved[2];//8 bytes + volatile STDES0 m_td0TD0; + volatile STDES1 m_td1TD1; + volatile u32 buff_addr; + volatile u32 next_desc; + struct tagSTxDesc *next; //4 bytes + volatile PDEVICE_TD_INFO pTDInfo;//4 bytes + volatile u32 Reserved[2];//8 bytes } __attribute__ ((__packed__)) STxDesc, *PSTxDesc; typedef const STxDesc *PCSTxDesc; typedef struct tagSTxSyncDesc { - volatile STDES0 m_td0TD0; - volatile STDES1 m_td1TD1; - volatile u32 buff_addr; // pointer to logical buffer - volatile u32 next_desc; // pointer to next logical descriptor - volatile unsigned short m_wFIFOCtl; - volatile unsigned short m_wTimeStamp; - struct tagSTxSyncDesc* next; //4 bytes - volatile PDEVICE_TD_INFO pTDInfo;//4 bytes - volatile u32 m_dwReserved2; + volatile STDES0 m_td0TD0; + volatile STDES1 m_td1TD1; + volatile u32 buff_addr; // pointer to logical buffer + volatile u32 next_desc; // pointer to next logical descriptor + volatile unsigned short m_wFIFOCtl; + volatile unsigned short m_wTimeStamp; + struct tagSTxSyncDesc *next; //4 bytes + volatile PDEVICE_TD_INFO pTDInfo;//4 bytes + volatile u32 m_dwReserved2; } __attribute__ ((__packed__)) STxSyncDesc, *PSTxSyncDesc; typedef const STxSyncDesc *PCSTxSyncDesc; @@ -396,36 +396,36 @@ typedef const STxSyncDesc *PCSTxSyncDesc; // RsvTime buffer header // typedef struct tagSRrvTime_gRTS { - unsigned short wRTSTxRrvTime_ba; - unsigned short wRTSTxRrvTime_aa; - unsigned short wRTSTxRrvTime_bb; - unsigned short wReserved; - unsigned short wTxRrvTime_b; - unsigned short wTxRrvTime_a; -}__attribute__ ((__packed__)) + unsigned short wRTSTxRrvTime_ba; + unsigned short wRTSTxRrvTime_aa; + unsigned short wRTSTxRrvTime_bb; + unsigned short wReserved; + unsigned short wTxRrvTime_b; + unsigned short wTxRrvTime_a; +} __attribute__ ((__packed__)) SRrvTime_gRTS, *PSRrvTime_gRTS; typedef const SRrvTime_gRTS *PCSRrvTime_gRTS; typedef struct tagSRrvTime_gCTS { - unsigned short wCTSTxRrvTime_ba; - unsigned short wReserved; - unsigned short wTxRrvTime_b; - unsigned short wTxRrvTime_a; -}__attribute__ ((__packed__)) + unsigned short wCTSTxRrvTime_ba; + unsigned short wReserved; + unsigned short wTxRrvTime_b; + unsigned short wTxRrvTime_a; +} __attribute__ ((__packed__)) SRrvTime_gCTS, *PSRrvTime_gCTS; typedef const SRrvTime_gCTS *PCSRrvTime_gCTS; typedef struct tagSRrvTime_ab { - unsigned short wRTSTxRrvTime; - unsigned short wTxRrvTime; -}__attribute__ ((__packed__)) + unsigned short wRTSTxRrvTime; + unsigned short wTxRrvTime; +} __attribute__ ((__packed__)) SRrvTime_ab, *PSRrvTime_ab; typedef const SRrvTime_ab *PCSRrvTime_ab; typedef struct tagSRrvTime_atim { - unsigned short wCTSTxRrvTime_ba; - unsigned short wTxRrvTime_a; -}__attribute__ ((__packed__)) + unsigned short wCTSTxRrvTime_ba; + unsigned short wTxRrvTime_a; +} __attribute__ ((__packed__)) SRrvTime_atim, *PSRrvTime_atim; typedef const SRrvTime_atim *PCSRrvTime_atim; @@ -433,74 +433,74 @@ typedef const SRrvTime_atim *PCSRrvTime_atim; // RTS buffer header // typedef struct tagSRTSData { - unsigned short wFrameControl; - unsigned short wDurationID; - unsigned char abyRA[ETH_ALEN]; - unsigned char abyTA[ETH_ALEN]; -}__attribute__ ((__packed__)) + unsigned short wFrameControl; + unsigned short wDurationID; + unsigned char abyRA[ETH_ALEN]; + unsigned char abyTA[ETH_ALEN]; +} __attribute__ ((__packed__)) SRTSData, *PSRTSData; typedef const SRTSData *PCSRTSData; typedef struct tagSRTS_g { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned char bySignalField_a; - unsigned char byServiceField_a; - unsigned short wTransmitLength_a; - unsigned short wDuration_ba; - unsigned short wDuration_aa; - unsigned short wDuration_bb; - unsigned short wReserved; - SRTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned char bySignalField_a; + unsigned char byServiceField_a; + unsigned short wTransmitLength_a; + unsigned short wDuration_ba; + unsigned short wDuration_aa; + unsigned short wDuration_bb; + unsigned short wReserved; + SRTSData Data; +} __attribute__ ((__packed__)) SRTS_g, *PSRTS_g; typedef const SRTS_g *PCSRTS_g; typedef struct tagSRTS_g_FB { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned char bySignalField_a; - unsigned char byServiceField_a; - unsigned short wTransmitLength_a; - unsigned short wDuration_ba; - unsigned short wDuration_aa; - unsigned short wDuration_bb; - unsigned short wReserved; - unsigned short wRTSDuration_ba_f0; - unsigned short wRTSDuration_aa_f0; - unsigned short wRTSDuration_ba_f1; - unsigned short wRTSDuration_aa_f1; - SRTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned char bySignalField_a; + unsigned char byServiceField_a; + unsigned short wTransmitLength_a; + unsigned short wDuration_ba; + unsigned short wDuration_aa; + unsigned short wDuration_bb; + unsigned short wReserved; + unsigned short wRTSDuration_ba_f0; + unsigned short wRTSDuration_aa_f0; + unsigned short wRTSDuration_ba_f1; + unsigned short wRTSDuration_aa_f1; + SRTSData Data; +} __attribute__ ((__packed__)) SRTS_g_FB, *PSRTS_g_FB; typedef const SRTS_g_FB *PCSRTS_g_FB; typedef struct tagSRTS_ab { - unsigned char bySignalField; - unsigned char byServiceField; - unsigned short wTransmitLength; - unsigned short wDuration; - unsigned short wReserved; - SRTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField; + unsigned char byServiceField; + unsigned short wTransmitLength; + unsigned short wDuration; + unsigned short wReserved; + SRTSData Data; +} __attribute__ ((__packed__)) SRTS_ab, *PSRTS_ab; typedef const SRTS_ab *PCSRTS_ab; typedef struct tagSRTS_a_FB { - unsigned char bySignalField; - unsigned char byServiceField; - unsigned short wTransmitLength; - unsigned short wDuration; - unsigned short wReserved; - unsigned short wRTSDuration_f0; - unsigned short wRTSDuration_f1; - SRTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField; + unsigned char byServiceField; + unsigned short wTransmitLength; + unsigned short wDuration; + unsigned short wReserved; + unsigned short wRTSDuration_f0; + unsigned short wRTSDuration_f1; + SRTSData Data; +} __attribute__ ((__packed__)) SRTS_a_FB, *PSRTS_a_FB; typedef const SRTS_a_FB *PCSRTS_a_FB; @@ -509,34 +509,34 @@ typedef const SRTS_a_FB *PCSRTS_a_FB; // CTS buffer header // typedef struct tagSCTSData { - unsigned short wFrameControl; - unsigned short wDurationID; - unsigned char abyRA[ETH_ALEN]; - unsigned short wReserved; -}__attribute__ ((__packed__)) + unsigned short wFrameControl; + unsigned short wDurationID; + unsigned char abyRA[ETH_ALEN]; + unsigned short wReserved; +} __attribute__ ((__packed__)) SCTSData, *PSCTSData; typedef struct tagSCTS { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned short wDuration_ba; - unsigned short wReserved; - SCTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned short wDuration_ba; + unsigned short wReserved; + SCTSData Data; +} __attribute__ ((__packed__)) SCTS, *PSCTS; typedef const SCTS *PCSCTS; typedef struct tagSCTS_FB { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned short wDuration_ba; - unsigned short wReserved; - unsigned short wCTSDuration_ba_f0; - unsigned short wCTSDuration_ba_f1; - SCTSData Data; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned short wDuration_ba; + unsigned short wReserved; + unsigned short wCTSDuration_ba_f0; + unsigned short wCTSDuration_ba_f1; + SCTSData Data; +} __attribute__ ((__packed__)) SCTS_FB, *PSCTS_FB; typedef const SCTS_FB *PCSCTS_FB; @@ -545,20 +545,20 @@ typedef const SCTS_FB *PCSCTS_FB; // Tx FIFO header // typedef struct tagSTxBufHead { - u32 adwTxKey[4]; - unsigned short wFIFOCtl; - unsigned short wTimeStamp; - unsigned short wFragCtl; - unsigned char byTxPower; - unsigned char wReserved; -}__attribute__ ((__packed__)) + u32 adwTxKey[4]; + unsigned short wFIFOCtl; + unsigned short wTimeStamp; + unsigned short wFragCtl; + unsigned char byTxPower; + unsigned char wReserved; +} __attribute__ ((__packed__)) STxBufHead, *PSTxBufHead; typedef const STxBufHead *PCSTxBufHead; typedef struct tagSTxShortBufHead { - unsigned short wFIFOCtl; - unsigned short wTimeStamp; -}__attribute__ ((__packed__)) + unsigned short wFIFOCtl; + unsigned short wTimeStamp; +} __attribute__ ((__packed__)) STxShortBufHead, *PSTxShortBufHead; typedef const STxShortBufHead *PCSTxShortBufHead; @@ -566,58 +566,58 @@ typedef const STxShortBufHead *PCSTxShortBufHead; // Tx data header // typedef struct tagSTxDataHead_g { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned char bySignalField_a; - unsigned char byServiceField_a; - unsigned short wTransmitLength_a; - unsigned short wDuration_b; - unsigned short wDuration_a; - unsigned short wTimeStampOff_b; - unsigned short wTimeStampOff_a; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned char bySignalField_a; + unsigned char byServiceField_a; + unsigned short wTransmitLength_a; + unsigned short wDuration_b; + unsigned short wDuration_a; + unsigned short wTimeStampOff_b; + unsigned short wTimeStampOff_a; +} __attribute__ ((__packed__)) STxDataHead_g, *PSTxDataHead_g; typedef const STxDataHead_g *PCSTxDataHead_g; typedef struct tagSTxDataHead_g_FB { - unsigned char bySignalField_b; - unsigned char byServiceField_b; - unsigned short wTransmitLength_b; - unsigned char bySignalField_a; - unsigned char byServiceField_a; - unsigned short wTransmitLength_a; - unsigned short wDuration_b; - unsigned short wDuration_a; - unsigned short wDuration_a_f0; - unsigned short wDuration_a_f1; - unsigned short wTimeStampOff_b; - unsigned short wTimeStampOff_a; -}__attribute__ ((__packed__)) + unsigned char bySignalField_b; + unsigned char byServiceField_b; + unsigned short wTransmitLength_b; + unsigned char bySignalField_a; + unsigned char byServiceField_a; + unsigned short wTransmitLength_a; + unsigned short wDuration_b; + unsigned short wDuration_a; + unsigned short wDuration_a_f0; + unsigned short wDuration_a_f1; + unsigned short wTimeStampOff_b; + unsigned short wTimeStampOff_a; +} __attribute__ ((__packed__)) STxDataHead_g_FB, *PSTxDataHead_g_FB; typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB; typedef struct tagSTxDataHead_ab { - unsigned char bySignalField; - unsigned char byServiceField; - unsigned short wTransmitLength; - unsigned short wDuration; - unsigned short wTimeStampOff; -}__attribute__ ((__packed__)) + unsigned char bySignalField; + unsigned char byServiceField; + unsigned short wTransmitLength; + unsigned short wDuration; + unsigned short wTimeStampOff; +} __attribute__ ((__packed__)) STxDataHead_ab, *PSTxDataHead_ab; typedef const STxDataHead_ab *PCSTxDataHead_ab; typedef struct tagSTxDataHead_a_FB { - unsigned char bySignalField; - unsigned char byServiceField; - unsigned short wTransmitLength; - unsigned short wDuration; - unsigned short wTimeStampOff; - unsigned short wDuration_f0; - unsigned short wDuration_f1; -}__attribute__ ((__packed__)) + unsigned char bySignalField; + unsigned char byServiceField; + unsigned short wTransmitLength; + unsigned short wDuration; + unsigned short wTimeStampOff; + unsigned short wDuration_f0; + unsigned short wDuration_f1; +} __attribute__ ((__packed__)) STxDataHead_a_FB, *PSTxDataHead_a_FB; typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB; @@ -625,38 +625,38 @@ typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB; // MICHDR data header // typedef struct tagSMICHDRHead { - u32 adwHDR0[4]; - u32 adwHDR1[4]; - u32 adwHDR2[4]; -}__attribute__ ((__packed__)) + u32 adwHDR0[4]; + u32 adwHDR1[4]; + u32 adwHDR2[4]; +} __attribute__ ((__packed__)) SMICHDRHead, *PSMICHDRHead; typedef const SMICHDRHead *PCSMICHDRHead; typedef struct tagSBEACONCtl { - u32 BufReady : 1; - u32 TSF : 15; - u32 BufLen : 11; - u32 Reserved : 5; -}__attribute__ ((__packed__)) + u32 BufReady:1; + u32 TSF:15; + u32 BufLen:11; + u32 Reserved:5; +} __attribute__ ((__packed__)) SBEACONCtl; typedef struct tagSSecretKey { - u32 dwLowDword; - unsigned char byHighByte; -}__attribute__ ((__packed__)) + u32 dwLowDword; + unsigned char byHighByte; +} __attribute__ ((__packed__)) SSecretKey; typedef struct tagSKeyEntry { - unsigned char abyAddrHi[2]; - unsigned short wKCTL; - unsigned char abyAddrLo[4]; - u32 dwKey0[4]; - u32 dwKey1[4]; - u32 dwKey2[4]; - u32 dwKey3[4]; - u32 dwKey4[4]; -}__attribute__ ((__packed__)) + unsigned char abyAddrHi[2]; + unsigned short wKCTL; + unsigned char abyAddrLo[4]; + u32 dwKey0[4]; + u32 dwKey1[4]; + u32 dwKey2[4]; + u32 dwKey3[4]; + u32 dwKey4[4]; +} __attribute__ ((__packed__)) SKeyEntry; /*--------------------- Export Macros ------------------------------*/ -- cgit From 4ec4aa4ae079d0a495a29c8e7ba5936a666a0bfb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:45 -0700 Subject: staging:vt6655:device: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 902 ++++++++++++++++++++-------------------- 1 file changed, 451 insertions(+), 451 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index e27244ce383e..0d9b0ddc0183 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -146,7 +146,7 @@ // BUILD OBJ mode -#define AVAIL_TD(p,q) ((p)->sOpts.nTxDescs[(q)]-((p)->iTDUsed[(q)])) +#define AVAIL_TD(p, q) ((p)->sOpts.nTxDescs[(q)] - ((p)->iTDUsed[(q)])) //PLICE_DEBUG -> #define NUM 64 @@ -159,39 +159,39 @@ /*--------------------- Export Types ------------------------------*/ -#define DBG_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);} -#define PRINT_K(p, args...) {if (PRIVATE_Message) printk( p ,##args);} +#define DBG_PRT(l, p, args...) { if (l <= msglevel) printk(p, ##args); } +#define PRINT_K(p, args...) { if (PRIVATE_Message) printk(p, ##args); } //0:11A 1:11B 2:11G typedef enum _VIA_BB_TYPE { - BB_TYPE_11A=0, - BB_TYPE_11B, - BB_TYPE_11G + BB_TYPE_11A = 0, + BB_TYPE_11B, + BB_TYPE_11G } VIA_BB_TYPE, *PVIA_BB_TYPE; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) typedef enum _VIA_PKT_TYPE { - PK_TYPE_11A=0, - PK_TYPE_11B, - PK_TYPE_11GB, - PK_TYPE_11GA + PK_TYPE_11A = 0, + PK_TYPE_11B, + PK_TYPE_11GB, + PK_TYPE_11GA } VIA_PKT_TYPE, *PVIA_PKT_TYPE; typedef enum __device_msg_level { - MSG_LEVEL_ERR=0, //Errors that will cause abnormal operation. - MSG_LEVEL_NOTICE=1, //Some errors need users to be notified. - MSG_LEVEL_INFO=2, //Normal message. - MSG_LEVEL_VERBOSE=3, //Will report all trival errors. - MSG_LEVEL_DEBUG=4 //Only for debug purpose. + MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation. + MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified. + MSG_LEVEL_INFO = 2, //Normal message. + MSG_LEVEL_VERBOSE = 3, //Will report all trival errors. + MSG_LEVEL_DEBUG = 4 //Only for debug purpose. } DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL; typedef enum __device_init_type { - DEVICE_INIT_COLD=0, // cold init - DEVICE_INIT_RESET, // reset init or Dx to D0 power remain init - DEVICE_INIT_DXPL // Dx to D0 power lost init + DEVICE_INIT_COLD = 0, // cold init + DEVICE_INIT_RESET, // reset init or Dx to D0 power remain init + DEVICE_INIT_DXPL // Dx to D0 power lost init } DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE; @@ -208,54 +208,54 @@ typedef unsigned char NDIS_802_11_PMKID_VALUE[16]; typedef enum _NDIS_802_11_WEP_STATUS { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent } NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, - NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; typedef enum _NDIS_802_11_STATUS_TYPE { - Ndis802_11StatusType_Authentication, - Ndis802_11StatusType_MediaStreamMode, - Ndis802_11StatusType_PMKID_CandidateList, - Ndis802_11StatusTypeMax // not a real type, defined as an upper bound + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound } NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; //Added new types for PMKID Candidate lists. typedef struct _PMKID_CANDIDATE { - NDIS_802_11_MAC_ADDRESS BSSID; - unsigned long Flags; + NDIS_802_11_MAC_ADDRESS BSSID; + unsigned long Flags; } PMKID_CANDIDATE, *PPMKID_CANDIDATE; typedef struct _BSSID_INFO { - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_PMKID_VALUE PMKID; + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_PMKID_VALUE PMKID; } BSSID_INFO, *PBSSID_INFO; typedef struct tagSPMKID { - unsigned long Length; - unsigned long BSSIDInfoCount; - BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID]; + unsigned long Length; + unsigned long BSSIDInfoCount; + BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID]; } SPMKID, *PSPMKID; typedef struct tagSPMKIDCandidateEvent { - NDIS_802_11_STATUS_TYPE StatusType; - unsigned long Version; // Version of the structure - unsigned long NumCandidates; // No. of pmkid candidates - PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST]; + NDIS_802_11_STATUS_TYPE StatusType; + unsigned long Version; // Version of the structure + unsigned long NumCandidates; // No. of pmkid candidates + PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST]; } SPMKIDCandidateEvent, *PSPMKIDCandidateEvent; //-- @@ -264,54 +264,54 @@ typedef struct tagSPMKIDCandidateEvent { #define MAX_QUIET_COUNT 8 typedef struct tagSQuietControl { - bool bEnable; - unsigned long dwStartTime; - unsigned char byPeriod; - unsigned short wDuration; + bool bEnable; + unsigned long dwStartTime; + unsigned char byPeriod; + unsigned short wDuration; } SQuietControl, *PSQuietControl; //-- -typedef struct __chip_info_tbl{ - CHIP_TYPE chip_id; - char* name; - int io_size; - int nTxQueue; - u32 flags; +typedef struct __chip_info_tbl { + CHIP_TYPE chip_id; + char *name; + int io_size; + int nTxQueue; + u32 flags; } CHIP_INFO, *PCHIP_INFO; typedef enum { - OWNED_BY_HOST=0, - OWNED_BY_NIC=1 + OWNED_BY_HOST = 0, + OWNED_BY_NIC = 1 } DEVICE_OWNER_TYPE, *PDEVICE_OWNER_TYPE; // The receive duplicate detection cache entry -typedef struct tagSCacheEntry{ - unsigned short wFmSequence; - unsigned char abyAddr2[ETH_ALEN]; +typedef struct tagSCacheEntry { + unsigned short wFmSequence; + unsigned char abyAddr2[ETH_ALEN]; } SCacheEntry, *PSCacheEntry; -typedef struct tagSCache{ +typedef struct tagSCache { /* The receive cache is updated circularly. The next entry to be written is * indexed by the "InPtr". -*/ - unsigned int uInPtr; // Place to use next - SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; + */ + unsigned int uInPtr; // Place to use next + SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; } SCache, *PSCache; #define CB_MAX_RX_FRAG 64 // DeFragment Control Block, used for collecting fragments prior to reassembly typedef struct tagSDeFragControlBlock { - unsigned short wSequence; - unsigned short wFragNum; - unsigned char abyAddr2[ETH_ALEN]; - unsigned int uLifetime; - struct sk_buff* skb; - unsigned char *pbyRxBuffer; - unsigned int cbFrameLength; - bool bInUse; + unsigned short wSequence; + unsigned short wFragNum; + unsigned char abyAddr2[ETH_ALEN]; + unsigned int uLifetime; + struct sk_buff *skb; + unsigned char *pbyRxBuffer; + unsigned int cbFrameLength; + bool bInUse; } SDeFragControlBlock, *PSDeFragControlBlock; @@ -350,9 +350,9 @@ typedef struct tagSDeFragControlBlock typedef struct _RxManagementQueue { int packet_num; - int head,tail; + int head, tail; PSRxMgmtPacket Q[NUM]; -} RxManagementQueue,*PSRxManagementQueue; +} RxManagementQueue, *PSRxManagementQueue; @@ -360,452 +360,452 @@ typedef struct _RxManagementQueue typedef struct __device_opt { - int nRxDescs0; //Number of RX descriptors0 - int nRxDescs1; //Number of RX descriptors1 - int nTxDescs[2]; //Number of TX descriptors 0, 1 - int int_works; //interrupt limits - int rts_thresh; //rts threshold - int frag_thresh; - int data_rate; - int channel_num; - int short_retry; - int long_retry; - int bbp_type; - u32 flags; + int nRxDescs0; //Number of RX descriptors0 + int nRxDescs1; //Number of RX descriptors1 + int nTxDescs[2]; //Number of TX descriptors 0, 1 + int int_works; //interrupt limits + int rts_thresh; //rts threshold + int frag_thresh; + int data_rate; + int channel_num; + int short_retry; + int long_retry; + int bbp_type; + u32 flags; } OPTIONS, *POPTIONS; typedef struct __device_info { - struct __device_info* next; - struct __device_info* prev; + struct __device_info *next; + struct __device_info *prev; - struct pci_dev* pcid; + struct pci_dev *pcid; #ifdef CONFIG_PM - u32 pci_state[16]; + u32 pci_state[16]; #endif // netdev - struct net_device* dev; - struct net_device* next_module; - struct net_device_stats stats; + struct net_device *dev; + struct net_device *next_module; + struct net_device_stats stats; //dma addr, rx/tx pool - dma_addr_t pool_dma; - dma_addr_t rd0_pool_dma; - dma_addr_t rd1_pool_dma; + dma_addr_t pool_dma; + dma_addr_t rd0_pool_dma; + dma_addr_t rd1_pool_dma; - dma_addr_t td0_pool_dma; - dma_addr_t td1_pool_dma; + dma_addr_t td0_pool_dma; + dma_addr_t td1_pool_dma; - dma_addr_t tx_bufs_dma0; - dma_addr_t tx_bufs_dma1; - dma_addr_t tx_beacon_dma; + dma_addr_t tx_bufs_dma0; + dma_addr_t tx_bufs_dma1; + dma_addr_t tx_beacon_dma; - unsigned char *tx0_bufs; - unsigned char *tx1_bufs; - unsigned char *tx_beacon_bufs; + unsigned char *tx0_bufs; + unsigned char *tx1_bufs; + unsigned char *tx_beacon_bufs; - CHIP_TYPE chip_id; + CHIP_TYPE chip_id; - unsigned long PortOffset; - unsigned long dwIsr; - u32 memaddr; - u32 ioaddr; - u32 io_size; + unsigned long PortOffset; + unsigned long dwIsr; + u32 memaddr; + u32 ioaddr; + u32 io_size; - unsigned char byRevId; - unsigned short SubSystemID; - unsigned short SubVendorID; + unsigned char byRevId; + unsigned short SubSystemID; + unsigned short SubVendorID; - int nTxQueues; - volatile int iTDUsed[TYPE_MAXTD]; + int nTxQueues; + volatile int iTDUsed[TYPE_MAXTD]; - volatile PSTxDesc apCurrTD[TYPE_MAXTD]; - volatile PSTxDesc apTailTD[TYPE_MAXTD]; + volatile PSTxDesc apCurrTD[TYPE_MAXTD]; + volatile PSTxDesc apTailTD[TYPE_MAXTD]; - volatile PSTxDesc apTD0Rings; - volatile PSTxDesc apTD1Rings; + volatile PSTxDesc apTD0Rings; + volatile PSTxDesc apTD1Rings; - volatile PSRxDesc aRD0Ring; - volatile PSRxDesc aRD1Ring; - volatile PSRxDesc pCurrRD[TYPE_MAXRD]; - SCache sDupRxCache; + volatile PSRxDesc aRD0Ring; + volatile PSRxDesc aRD1Ring; + volatile PSRxDesc pCurrRD[TYPE_MAXRD]; + SCache sDupRxCache; - SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG]; - unsigned int cbDFCB; - unsigned int cbFreeDFCB; - unsigned int uCurrentDFCBIdx; + SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG]; + unsigned int cbDFCB; + unsigned int cbFreeDFCB; + unsigned int uCurrentDFCBIdx; - OPTIONS sOpts; + OPTIONS sOpts; - u32 flags; + u32 flags; - u32 rx_buf_sz; - int multicast_limit; - unsigned char byRxMode; + u32 rx_buf_sz; + int multicast_limit; + unsigned char byRxMode; - spinlock_t lock; + spinlock_t lock; //PLICE_DEBUG-> - struct tasklet_struct RxMngWorkItem; + struct tasklet_struct RxMngWorkItem; RxManagementQueue rxManeQueue; //PLICE_DEBUG<- //PLICE_DEBUG -> - pid_t MLMEThr_pid; - struct completion notify; - struct semaphore mlme_semaphore; + pid_t MLMEThr_pid; + struct completion notify; + struct semaphore mlme_semaphore; //PLICE_DEBUG <- - u32 rx_bytes; - - // Version control - unsigned char byLocalID; - unsigned char byRFType; - - unsigned char byMaxPwrLevel; - unsigned char byZoneType; - bool bZoneRegExist; - unsigned char byOriginalZonetype; - unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; - bool bLinkPass; // link status: OK or fail - unsigned char abyCurrentNetAddr[ETH_ALEN]; - - // Adapter statistics - SStatCounter scStatistic; - // 802.11 counter - SDot11Counters s802_11Counter; - - - // 802.11 management - PSMgmtObject pMgmt; - SMgmtObject sMgmtObj; - - // 802.11 MAC specific - unsigned int uCurrRSSI; - unsigned char byCurrSQ; - - unsigned long dwTxAntennaSel; - unsigned long dwRxAntennaSel; - unsigned char byAntennaCount; - unsigned char byRxAntennaMode; - unsigned char byTxAntennaMode; - bool bTxRxAntInv; - - unsigned char *pbyTmpBuff; - unsigned int uSIFS; //Current SIFS - unsigned int uDIFS; //Current DIFS - unsigned int uEIFS; //Current EIFS - unsigned int uSlot; //Current SlotTime - unsigned int uCwMin; //Current CwMin - unsigned int uCwMax; //CwMax is fixed on 1023. - // PHY parameter - unsigned char bySIFS; - unsigned char byDIFS; - unsigned char byEIFS; - unsigned char bySlot; - unsigned char byCWMaxMin; - CARD_PHY_TYPE eCurrentPHYType; - - - VIA_BB_TYPE byBBType; //0: 11A, 1:11B, 2:11G - VIA_PKT_TYPE byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) - unsigned short wBasicRate; - unsigned char byACKRate; - unsigned char byTopOFDMBasicRate; - unsigned char byTopCCKBasicRate; - - unsigned char byMinChannel; - unsigned char byMaxChannel; - unsigned int uConnectionRate; - - unsigned char byPreambleType; - unsigned char byShortPreamble; - - unsigned short wCurrentRate; - unsigned short wRTSThreshold; - unsigned short wFragmentationThreshold; - unsigned char byShortRetryLimit; - unsigned char byLongRetryLimit; - CARD_OP_MODE eOPMode; - unsigned char byOpMode; - bool bBSSIDFilter; - unsigned short wMaxTransmitMSDULifetime; - unsigned char abyBSSID[ETH_ALEN]; - unsigned char abyDesireBSSID[ETH_ALEN]; - unsigned short wCTSDuration; // update while speed change - unsigned short wACKDuration; // update while speed change - unsigned short wRTSTransmitLen; // update while speed change - unsigned char byRTSServiceField; // update while speed change - unsigned char byRTSSignalField; // update while speed change - - unsigned long dwMaxReceiveLifetime; // dot11MaxReceiveLifetime - - bool bCCK; - bool bEncryptionEnable; - bool bLongHeader; - bool bShortSlotTime; - bool bProtectMode; - bool bNonERPPresent; - bool bBarkerPreambleMd; - - unsigned char byERPFlag; - unsigned short wUseProtectCntDown; - - bool bRadioControlOff; - bool bRadioOff; - bool bEnablePSMode; - unsigned short wListenInterval; - bool bPWBitOn; - WMAC_POWER_MODE ePSMode; - - - // GPIO Radio Control - unsigned char byRadioCtl; - unsigned char byGPIO; - bool bHWRadioOff; - bool bPrvActive4RadioOFF; - bool bGPIOBlockRead; - - // Beacon related - unsigned short wSeqCounter; - unsigned short wBCNBufLen; - bool bBeaconBufReady; - bool bBeaconSent; - bool bIsBeaconBufReadySet; - unsigned int cbBeaconBufReadySetCnt; - bool bFixRate; - unsigned char byCurrentCh; - unsigned int uScanTime; - - CMD_STATE eCommandState; - - CMD_CODE eCommand; - bool bBeaconTx; - - bool bStopBeacon; - bool bStopDataPkt; - bool bStopTx0Pkt; - unsigned int uAutoReConnectTime; - - // 802.11 counter - - CMD_ITEM eCmdQueue[CMD_Q_SIZE]; - unsigned int uCmdDequeueIdx; - unsigned int uCmdEnqueueIdx; - unsigned int cbFreeCmdQueue; - bool bCmdRunning; - bool bCmdClear; - - - - bool bRoaming; - //WOW - unsigned char abyIPAddr[4]; - - unsigned long ulTxPower; - NDIS_802_11_WEP_STATUS eEncryptionStatus; - bool bTransmitKey; + u32 rx_bytes; + + // Version control + unsigned char byLocalID; + unsigned char byRFType; + + unsigned char byMaxPwrLevel; + unsigned char byZoneType; + bool bZoneRegExist; + unsigned char byOriginalZonetype; + unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; + bool bLinkPass; // link status: OK or fail + unsigned char abyCurrentNetAddr[ETH_ALEN]; + + // Adapter statistics + SStatCounter scStatistic; + // 802.11 counter + SDot11Counters s802_11Counter; + + + // 802.11 management + PSMgmtObject pMgmt; + SMgmtObject sMgmtObj; + + // 802.11 MAC specific + unsigned int uCurrRSSI; + unsigned char byCurrSQ; + + unsigned long dwTxAntennaSel; + unsigned long dwRxAntennaSel; + unsigned char byAntennaCount; + unsigned char byRxAntennaMode; + unsigned char byTxAntennaMode; + bool bTxRxAntInv; + + unsigned char *pbyTmpBuff; + unsigned int uSIFS; //Current SIFS + unsigned int uDIFS; //Current DIFS + unsigned int uEIFS; //Current EIFS + unsigned int uSlot; //Current SlotTime + unsigned int uCwMin; //Current CwMin + unsigned int uCwMax; //CwMax is fixed on 1023. + // PHY parameter + unsigned char bySIFS; + unsigned char byDIFS; + unsigned char byEIFS; + unsigned char bySlot; + unsigned char byCWMaxMin; + CARD_PHY_TYPE eCurrentPHYType; + + + VIA_BB_TYPE byBBType; //0: 11A, 1:11B, 2:11G + VIA_PKT_TYPE byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) + unsigned short wBasicRate; + unsigned char byACKRate; + unsigned char byTopOFDMBasicRate; + unsigned char byTopCCKBasicRate; + + unsigned char byMinChannel; + unsigned char byMaxChannel; + unsigned int uConnectionRate; + + unsigned char byPreambleType; + unsigned char byShortPreamble; + + unsigned short wCurrentRate; + unsigned short wRTSThreshold; + unsigned short wFragmentationThreshold; + unsigned char byShortRetryLimit; + unsigned char byLongRetryLimit; + CARD_OP_MODE eOPMode; + unsigned char byOpMode; + bool bBSSIDFilter; + unsigned short wMaxTransmitMSDULifetime; + unsigned char abyBSSID[ETH_ALEN]; + unsigned char abyDesireBSSID[ETH_ALEN]; + unsigned short wCTSDuration; // update while speed change + unsigned short wACKDuration; // update while speed change + unsigned short wRTSTransmitLen; // update while speed change + unsigned char byRTSServiceField; // update while speed change + unsigned char byRTSSignalField; // update while speed change + + unsigned long dwMaxReceiveLifetime; // dot11MaxReceiveLifetime + + bool bCCK; + bool bEncryptionEnable; + bool bLongHeader; + bool bShortSlotTime; + bool bProtectMode; + bool bNonERPPresent; + bool bBarkerPreambleMd; + + unsigned char byERPFlag; + unsigned short wUseProtectCntDown; + + bool bRadioControlOff; + bool bRadioOff; + bool bEnablePSMode; + unsigned short wListenInterval; + bool bPWBitOn; + WMAC_POWER_MODE ePSMode; + + + // GPIO Radio Control + unsigned char byRadioCtl; + unsigned char byGPIO; + bool bHWRadioOff; + bool bPrvActive4RadioOFF; + bool bGPIOBlockRead; + + // Beacon related + unsigned short wSeqCounter; + unsigned short wBCNBufLen; + bool bBeaconBufReady; + bool bBeaconSent; + bool bIsBeaconBufReadySet; + unsigned int cbBeaconBufReadySetCnt; + bool bFixRate; + unsigned char byCurrentCh; + unsigned int uScanTime; + + CMD_STATE eCommandState; + + CMD_CODE eCommand; + bool bBeaconTx; + + bool bStopBeacon; + bool bStopDataPkt; + bool bStopTx0Pkt; + unsigned int uAutoReConnectTime; + + // 802.11 counter + + CMD_ITEM eCmdQueue[CMD_Q_SIZE]; + unsigned int uCmdDequeueIdx; + unsigned int uCmdEnqueueIdx; + unsigned int cbFreeCmdQueue; + bool bCmdRunning; + bool bCmdClear; + + + + bool bRoaming; + //WOW + unsigned char abyIPAddr[4]; + + unsigned long ulTxPower; + NDIS_802_11_WEP_STATUS eEncryptionStatus; + bool bTransmitKey; //2007-0925-01by MikeLiu //mike add :save old Encryption - NDIS_802_11_WEP_STATUS eOldEncryptionStatus; + NDIS_802_11_WEP_STATUS eOldEncryptionStatus; - SKeyManagement sKey; - unsigned long dwIVCounter; + SKeyManagement sKey; + unsigned long dwIVCounter; - QWORD qwPacketNumber; //For CCMP and TKIP as TSC(6 bytes) - unsigned int uCurrentWEPMode; + QWORD qwPacketNumber; //For CCMP and TKIP as TSC(6 bytes) + unsigned int uCurrentWEPMode; - RC4Ext SBox; - unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3]; - unsigned char byKeyIndex; - unsigned int uKeyLength; - unsigned char abyKey[WLAN_WEP232_KEYLEN]; + RC4Ext SBox; + unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3]; + unsigned char byKeyIndex; + unsigned int uKeyLength; + unsigned char abyKey[WLAN_WEP232_KEYLEN]; - bool bAES; - unsigned char byCntMeasure; + bool bAES; + unsigned char byCntMeasure; - // for AP mode - unsigned int uAssocCount; - bool bMoreData; + // for AP mode + unsigned int uAssocCount; + bool bMoreData; - // QoS - bool bGrpAckPolicy; + // QoS + bool bGrpAckPolicy; - // for OID_802_11_ASSOCIATION_INFORMATION - bool bAssocInfoSet; + // for OID_802_11_ASSOCIATION_INFORMATION + bool bAssocInfoSet; - unsigned char byAutoFBCtrl; + unsigned char byAutoFBCtrl; - bool bTxMICFail; - bool bRxMICFail; + bool bTxMICFail; + bool bRxMICFail; - unsigned int uRATEIdx; + unsigned int uRATEIdx; - // For Update BaseBand VGA Gain Offset - bool bUpdateBBVGA; - unsigned int uBBVGADiffCount; - unsigned char byBBVGANew; - unsigned char byBBVGACurrent; - unsigned char abyBBVGA[BB_VGA_LEVEL]; - long ldBmThreshold[BB_VGA_LEVEL]; + // For Update BaseBand VGA Gain Offset + bool bUpdateBBVGA; + unsigned int uBBVGADiffCount; + unsigned char byBBVGANew; + unsigned char byBBVGACurrent; + unsigned char abyBBVGA[BB_VGA_LEVEL]; + long ldBmThreshold[BB_VGA_LEVEL]; - unsigned char byBBPreEDRSSI; - unsigned char byBBPreEDIndex; + unsigned char byBBPreEDRSSI; + unsigned char byBBPreEDIndex; - bool bRadioCmd; - unsigned long dwDiagRefCount; + bool bRadioCmd; + unsigned long dwDiagRefCount; - // For FOE Tuning - unsigned char byFOETuning; + // For FOE Tuning + unsigned char byFOETuning; - // For Auto Power Tunning + // For Auto Power Tunning - unsigned char byAutoPwrTunning; - short sPSetPointCCK; - short sPSetPointOFDMG; - short sPSetPointOFDMA; - long lPFormulaOffset; - short sPThreshold; - char cAdjustStep; - char cMinTxAGC; + unsigned char byAutoPwrTunning; + short sPSetPointCCK; + short sPSetPointOFDMG; + short sPSetPointOFDMA; + long lPFormulaOffset; + short sPThreshold; + char cAdjustStep; + char cMinTxAGC; - // For RF Power table - unsigned char byCCKPwr; - unsigned char byOFDMPwrG; - unsigned char byCurPwr; - char byCurPwrdBm; - unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G+1]; - unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL+1]; - char abyCCKDefaultPwr[CB_MAX_CHANNEL_24G+1]; - char abyOFDMDefaultPwr[CB_MAX_CHANNEL+1]; - char abyRegPwr[CB_MAX_CHANNEL+1]; - char abyLocalPwr[CB_MAX_CHANNEL+1]; + // For RF Power table + unsigned char byCCKPwr; + unsigned char byOFDMPwrG; + unsigned char byCurPwr; + char byCurPwrdBm; + unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G+1]; + unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL+1]; + char abyCCKDefaultPwr[CB_MAX_CHANNEL_24G+1]; + char abyOFDMDefaultPwr[CB_MAX_CHANNEL+1]; + char abyRegPwr[CB_MAX_CHANNEL+1]; + char abyLocalPwr[CB_MAX_CHANNEL+1]; - // BaseBand Loopback Use - unsigned char byBBCR4d; - unsigned char byBBCRc9; - unsigned char byBBCR88; - unsigned char byBBCR09; + // BaseBand Loopback Use + unsigned char byBBCR4d; + unsigned char byBBCRc9; + unsigned char byBBCR88; + unsigned char byBBCR09; - // command timer - struct timer_list sTimerCommand; + // command timer + struct timer_list sTimerCommand; #ifdef TxInSleep - struct timer_list sTimerTxData; - unsigned long nTxDataTimeCout; - bool fTxDataInSleep; - bool IsTxDataTrigger; + struct timer_list sTimerTxData; + unsigned long nTxDataTimeCout; + bool fTxDataInSleep; + bool IsTxDataTrigger; #endif #ifdef WPA_SM_Transtatus - bool fWPA_Authened; //is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? + bool fWPA_Authened; //is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? #endif - unsigned char byReAssocCount; //mike add:re-association retry times! - unsigned char byLinkWaitCount; + unsigned char byReAssocCount; //mike add:re-association retry times! + unsigned char byLinkWaitCount; - unsigned char abyNodeName[17]; + unsigned char abyNodeName[17]; - bool bDiversityRegCtlON; - bool bDiversityEnable; - unsigned long ulDiversityNValue; - unsigned long ulDiversityMValue; - unsigned char byTMax; - unsigned char byTMax2; - unsigned char byTMax3; - unsigned long ulSQ3TH; + bool bDiversityRegCtlON; + bool bDiversityEnable; + unsigned long ulDiversityNValue; + unsigned long ulDiversityMValue; + unsigned char byTMax; + unsigned char byTMax2; + unsigned char byTMax3; + unsigned long ulSQ3TH; // ANT diversity - unsigned long uDiversityCnt; - unsigned char byAntennaState; - unsigned long ulRatio_State0; - unsigned long ulRatio_State1; - - //SQ3 functions for antenna diversity - struct timer_list TimerSQ3Tmax1; - struct timer_list TimerSQ3Tmax2; - struct timer_list TimerSQ3Tmax3; - - - unsigned long uNumSQ3[MAX_RATE]; - unsigned short wAntDiversityMaxRate; - - - SEthernetHeader sTxEthHeader; - SEthernetHeader sRxEthHeader; - unsigned char abyBroadcastAddr[ETH_ALEN]; - unsigned char abySNAP_RFC1042[ETH_ALEN]; - unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; - unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; //unsigned long alignment - // Pre-Authentication & PMK cache - SPMKID gsPMKID; - SPMKIDCandidateEvent gsPMKIDCandidate; - - - // for 802.11h - bool b11hEnable; - unsigned char abyCountryCode[3]; - // for 802.11h DFS - unsigned int uNumOfMeasureEIDs; - PWLAN_IE_MEASURE_REQ pCurrMeasureEID; - bool bMeasureInProgress; - unsigned char byOrgChannel; - unsigned char byOrgRCR; - unsigned long dwOrgMAR0; - unsigned long dwOrgMAR4; - unsigned char byBasicMap; - unsigned char byCCAFraction; - unsigned char abyRPIs[8]; - unsigned long dwRPIs[8]; - bool bChannelSwitch; - unsigned char byNewChannel; - unsigned char byChannelSwitchCount; - bool bQuietEnable; - bool bEnableFirstQuiet; - unsigned char byQuietStartCount; - unsigned int uQuietEnqueue; - unsigned long dwCurrentQuietEndTime; - SQuietControl sQuiet[MAX_QUIET_COUNT]; - // for 802.11h TPC - bool bCountryInfo5G; - bool bCountryInfo24G; - - unsigned short wBeaconInterval; - - //WPA supplicant deamon + unsigned long uDiversityCnt; + unsigned char byAntennaState; + unsigned long ulRatio_State0; + unsigned long ulRatio_State1; + + //SQ3 functions for antenna diversity + struct timer_list TimerSQ3Tmax1; + struct timer_list TimerSQ3Tmax2; + struct timer_list TimerSQ3Tmax3; + + + unsigned long uNumSQ3[MAX_RATE]; + unsigned short wAntDiversityMaxRate; + + + SEthernetHeader sTxEthHeader; + SEthernetHeader sRxEthHeader; + unsigned char abyBroadcastAddr[ETH_ALEN]; + unsigned char abySNAP_RFC1042[ETH_ALEN]; + unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; + unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; //unsigned long alignment + // Pre-Authentication & PMK cache + SPMKID gsPMKID; + SPMKIDCandidateEvent gsPMKIDCandidate; + + + // for 802.11h + bool b11hEnable; + unsigned char abyCountryCode[3]; + // for 802.11h DFS + unsigned int uNumOfMeasureEIDs; + PWLAN_IE_MEASURE_REQ pCurrMeasureEID; + bool bMeasureInProgress; + unsigned char byOrgChannel; + unsigned char byOrgRCR; + unsigned long dwOrgMAR0; + unsigned long dwOrgMAR4; + unsigned char byBasicMap; + unsigned char byCCAFraction; + unsigned char abyRPIs[8]; + unsigned long dwRPIs[8]; + bool bChannelSwitch; + unsigned char byNewChannel; + unsigned char byChannelSwitchCount; + bool bQuietEnable; + bool bEnableFirstQuiet; + unsigned char byQuietStartCount; + unsigned int uQuietEnqueue; + unsigned long dwCurrentQuietEndTime; + SQuietControl sQuiet[MAX_QUIET_COUNT]; + // for 802.11h TPC + bool bCountryInfo5G; + bool bCountryInfo24G; + + unsigned short wBeaconInterval; + + //WPA supplicant deamon struct net_device *wpadev; bool bWPADEVUp; - struct sk_buff *skb; + struct sk_buff *skb; #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT /* - bool bwextstep0; - bool bwextstep1; - bool bwextstep2; - bool bwextstep3; - */ - unsigned int bwextcount; - bool bWPASuppWextEnabled; + bool bwextstep0; + bool bwextstep1; + bool bwextstep2; + bool bwextstep3; +*/ + unsigned int bwextcount; + bool bWPASuppWextEnabled; #endif - //-- + //-- #ifdef HOSTAP - // user space daemon: hostapd, is used for HOSTAP + // user space daemon: hostapd, is used for HOSTAP bool bEnableHostapd; bool bEnable8021x; bool bEnableHostWEP; struct net_device *apdev; int (*tx_80211)(struct sk_buff *skb, struct net_device *dev); #endif - unsigned int uChannel; - bool bMACSuspend; + unsigned int uChannel; + bool bMACSuspend; struct iw_statistics wstats; // wireless stats - bool bCommit; + bool bCommit; } DEVICE_INFO, *PSDevice; @@ -813,17 +813,17 @@ typedef struct __device_info { //PLICE_DEBUG-> - inline static void EnQueue (PSDevice pDevice,PSRxMgmtPacket pRxMgmtPacket) +inline static void EnQueue(PSDevice pDevice, PSRxMgmtPacket pRxMgmtPacket) { //printk("Enter EnQueue:tail is %d\n",pDevice->rxManeQueue.tail); if ((pDevice->rxManeQueue.tail+1) % NUM == pDevice->rxManeQueue.head) { //printk("Queue is Full,tail is %d\n",pDevice->rxManeQueue.tail); - return ; + return; } else { - pDevice->rxManeQueue.tail = (pDevice->rxManeQueue.tail+1)% NUM; + pDevice->rxManeQueue.tail = (pDevice->rxManeQueue.tail + 1) % NUM; pDevice->rxManeQueue.Q[pDevice->rxManeQueue.tail] = pRxMgmtPacket; pDevice->rxManeQueue.packet_num++; //printk("packet num is %d\n",pDevice->rxManeQueue.packet_num); @@ -833,7 +833,7 @@ typedef struct __device_info { - inline static PSRxMgmtPacket DeQueue (PSDevice pDevice) +inline static PSRxMgmtPacket DeQueue(PSDevice pDevice) { PSRxMgmtPacket pRxMgmtPacket; if (pDevice->rxManeQueue.tail == pDevice->rxManeQueue.head) @@ -866,17 +866,17 @@ void InitRxManagementQueue(PSDevice pDevice); inline static bool device_get_ip(PSDevice pInfo) { - struct in_device* in_dev=(struct in_device*) pInfo->dev->ip_ptr; - struct in_ifaddr* ifa; - - if (in_dev!=NULL) { - ifa=(struct in_ifaddr*) in_dev->ifa_list; - if (ifa!=NULL) { - memcpy(pInfo->abyIPAddr,&ifa->ifa_address,4); - return true; - } - } - return false; + struct in_device *in_dev = (struct in_device *)pInfo->dev->ip_ptr; + struct in_ifaddr *ifa; + + if (in_dev != NULL) { + ifa = (struct in_ifaddr *)in_dev->ifa_list; + if (ifa != NULL) { + memcpy(pInfo->abyIPAddr, &ifa->ifa_address, 4); + return true; + } + } + return false; } -- cgit From 74533af4b6867bd4cc38bffec4e8ff7247dd89c8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:46 -0700 Subject: staging:vt6655:device_cfg: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_cfg.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h index 408edc27075f..145457ba768d 100644 --- a/drivers/staging/vt6655/device_cfg.h +++ b/drivers/staging/vt6655/device_cfg.h @@ -34,9 +34,9 @@ typedef struct _version { - unsigned char major; - unsigned char minor; - unsigned char build; + unsigned char major; + unsigned char minor; + unsigned char build; } version_t, *pversion_t; #define VID_TABLE_SIZE 64 @@ -76,20 +76,20 @@ struct _version { -typedef enum _chip_type{ - VT3253=1 +typedef enum _chip_type { + VT3253 = 1 } CHIP_TYPE, *PCHIP_TYPE; #ifdef VIAWET_DEBUG -#define ASSERT(x) { \ - if (!(x)) { \ - printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\ - __FUNCTION__, __LINE__);\ - *(int*) 0=0;\ - }\ -} +#define ASSERT(x) { \ + if (!(x)) { \ + printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x, \ + __FUNCTION__, __LINE__); \ + *(int *)0 = 0; \ + } \ + } #define DBG_PORT80(value) outb(value, 0x80) #else #define ASSERT(x) -- cgit From 915006cddc7979263a0fe1c6cb1369962bfe68f5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:47 -0700 Subject: staging:vt6655:device_main: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4882 +++++++++++++++++----------------- 1 file changed, 2441 insertions(+), 2441 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 453c83d7fe8c..10d675e9e084 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -98,52 +98,52 @@ MODULE_AUTHOR("VIA Networking Technologies, Inc., "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver"); - static int mlme_kill; - //static struct task_struct * mlme_task; +static int mlme_kill; +//static struct task_struct * mlme_task; -#define DEVICE_PARAM(N,D) +#define DEVICE_PARAM(N, D) /* - static const int N[MAX_UINTS]=OPTION_DEFAULT;\ - MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UINTS) "i");\ - MODULE_PARM_DESC(N, D); + static const int N[MAX_UINTS]=OPTION_DEFAULT;\ + MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UINTS) "i");\ + MODULE_PARM_DESC(N, D); */ #define RX_DESC_MIN0 16 #define RX_DESC_MAX0 128 #define RX_DESC_DEF0 32 -DEVICE_PARAM(RxDescriptors0,"Number of receive descriptors0"); +DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0"); #define RX_DESC_MIN1 16 #define RX_DESC_MAX1 128 #define RX_DESC_DEF1 32 -DEVICE_PARAM(RxDescriptors1,"Number of receive descriptors1"); +DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1"); #define TX_DESC_MIN0 16 #define TX_DESC_MAX0 128 #define TX_DESC_DEF0 32 -DEVICE_PARAM(TxDescriptors0,"Number of transmit descriptors0"); +DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0"); #define TX_DESC_MIN1 16 #define TX_DESC_MAX1 128 #define TX_DESC_DEF1 64 -DEVICE_PARAM(TxDescriptors1,"Number of transmit descriptors1"); +DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1"); #define IP_ALIG_DEF 0 /* IP_byte_align[] is used for IP header unsigned long byte aligned 0: indicate the IP header won't be unsigned long byte aligned.(Default) . 1: indicate the IP header will be unsigned long byte aligned. - In some environment, the IP header should be unsigned long byte aligned, - or the packet will be droped when we receive it. (eg: IPVS) + In some environment, the IP header should be unsigned long byte aligned, + or the packet will be droped when we receive it. (eg: IPVS) */ -DEVICE_PARAM(IP_byte_align,"Enable IP header dword aligned"); +DEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned"); #define INT_WORKS_DEF 20 #define INT_WORKS_MIN 10 #define INT_WORKS_MAX 64 -DEVICE_PARAM(int_works,"Number of packets per interrupt services"); +DEVICE_PARAM(int_works, "Number of packets per interrupt services"); #define CHANNEL_MIN 1 #define CHANNEL_MAX 14 @@ -190,10 +190,10 @@ DEVICE_PARAM(FragThreshold, "Fragmentation threshold"); 7: indicate 18 Mbps 0x24 8: indicate 24 Mbps 0x30 9: indicate 36 Mbps 0x48 - 10: indicate 48 Mbps 0x60 - 11: indicate 54 Mbps 0x6c - 12: indicate 72 Mbps 0x90 - 13: indicate auto rate + 10: indicate 48 Mbps 0x60 + 11: indicate 54 Mbps 0x6c + 12: indicate 72 Mbps 0x90 + 13: indicate auto rate */ DEVICE_PARAM(ConnectionRate, "Connection data rate"); @@ -271,14 +271,14 @@ DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode"); // -static int device_nics =0; -static PSDevice pDevice_Infos =NULL; +static int device_nics = 0; +static PSDevice pDevice_Infos = NULL; static struct net_device *root_device_dev = NULL; -static CHIP_INFO chip_info_table[]= { - { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ", - 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN }, - {0,NULL} +static CHIP_INFO chip_info_table[] = { + { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ", + 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN }, + {0, NULL} }; DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = { @@ -290,15 +290,15 @@ DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = { static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent); -static void vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO); +static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, PCHIP_INFO); static void device_free_info(PSDevice pDevice); -static bool device_get_pci_info(PSDevice, struct pci_dev* pcid); +static bool device_get_pci_info(PSDevice, struct pci_dev *pcid); static void device_print_info(PSDevice pDevice); static struct net_device_stats *device_get_stats(struct net_device *dev); static void device_init_diversity_timer(PSDevice pDevice); static int device_open(struct net_device *dev); static int device_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t device_intr(int irq, void*dev_instance); +static irqreturn_t device_intr(int irq, void *dev_instance); static void device_set_multi(struct net_device *dev); static int device_close(struct net_device *dev); static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -338,7 +338,7 @@ static void device_free_rd1_ring(PSDevice pDevice); static void device_free_rings(PSDevice pDevice); static void device_free_frag_buf(PSDevice pDevice); static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source); + unsigned char *dest, unsigned char *source); /*--------------------- Export Variables --------------------------*/ @@ -347,7 +347,7 @@ static int Config_FileGetParameter(unsigned char *string, -static char* get_chip_name(int chip_id) +static char *get_chip_name(int chip_id) { int i; for (i = 0; chip_info_table[i].name != NULL; i++) @@ -367,38 +367,38 @@ static void vt6655_remove(struct pci_dev *pcid) } /* -static void -device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char* devname) { - if (val==-1) - *opt=def; - else if (valmax) { - DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" , - devname,name, min,max); - *opt=def; - } else { - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n", - devname, name, val); - *opt=val; - } -} + static void + device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char* devname) { + if (val==-1) + *opt=def; + else if (valmax) { + DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" , + devname,name, min,max); + *opt=def; + } else { + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n", + devname, name, val); + *opt=val; + } + } -static void -device_set_bool_opt(unsigned int *opt, int val,bool def,u32 flag, char* name,char* devname) { - (*opt)&=(~flag); - if (val==-1) - *opt|=(def ? flag : 0); - else if (val<0 || val>1) { - DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE - "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",devname,name); - *opt|=(def ? flag : 0); - } else { - DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n", - devname,name , val ? "true" : "false"); - *opt|=(val ? flag : 0); - } -} + static void + device_set_bool_opt(unsigned int *opt, int val,bool def,u32 flag, char* name,char* devname) { + (*opt)&=(~flag); + if (val==-1) + *opt|=(def ? flag : 0); + else if (val<0 || val>1) { + DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE + "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",devname,name); + *opt|=(def ? flag : 0); + } else { + DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n", + devname,name , val ? "true" : "false"); + *opt|=(val ? flag : 0); + } + } */ -static void device_get_options(PSDevice pDevice, int index, char* devname) +static void device_get_options(PSDevice pDevice, int index, char *devname) { POPTIONS pOpts = &(pDevice->sOpts); @@ -426,91 +426,91 @@ static void device_get_options(PSDevice pDevice, int index, char* devname) static void device_set_options(PSDevice pDevice) { - unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - - - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); - - pDevice->uChannel = pDevice->sOpts.channel_num; - pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh; - pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh; - pDevice->byShortRetryLimit = pDevice->sOpts.short_retry; - pDevice->byLongRetryLimit = pDevice->sOpts.long_retry; - pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME; - pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0; - pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0; - pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0; - pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0; - pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0; - pDevice->uConnectionRate = pDevice->sOpts.data_rate; - if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true; - pDevice->byBBType = pDevice->sOpts.bbp_type; - pDevice->byPacketType = pDevice->byBBType; + unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; + + + memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); + memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); + memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); + + pDevice->uChannel = pDevice->sOpts.channel_num; + pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh; + pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh; + pDevice->byShortRetryLimit = pDevice->sOpts.short_retry; + pDevice->byLongRetryLimit = pDevice->sOpts.long_retry; + pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME; + pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0; + pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0; + pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0; + pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0; + pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0; + pDevice->uConnectionRate = pDevice->sOpts.data_rate; + if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true; + pDevice->byBBType = pDevice->sOpts.bbp_type; + pDevice->byPacketType = pDevice->byBBType; //PLICE_DEBUG-> pDevice->byAutoFBCtrl = AUTO_FB_0; //pDevice->byAutoFBCtrl = AUTO_FB_1; //PLICE_DEBUG<- -pDevice->bUpdateBBVGA = true; - pDevice->byFOETuning = 0; - pDevice->wCTSDuration = 0; - pDevice->byPreambleType = 0; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(int)pDevice->uChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(int)pDevice->byOpMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(int)pDevice->ePSMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(int)pDevice->wRTSThreshold); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(int)pDevice->byShortRetryLimit); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(int)pDevice->byLongRetryLimit); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(int)pDevice->byPreambleType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(int)pDevice->byShortPreamble); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(int)pDevice->uConnectionRate); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(int)pDevice->byBBType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(int)pDevice->b11hEnable); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(int)pDevice->bDiversityRegCtlON); + pDevice->bUpdateBBVGA = true; + pDevice->byFOETuning = 0; + pDevice->wCTSDuration = 0; + pDevice->byPreambleType = 0; + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uChannel= %d\n", (int)pDevice->uChannel); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byOpMode= %d\n", (int)pDevice->byOpMode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ePSMode= %d\n", (int)pDevice->ePSMode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byPreambleType= %d\n", (int)pDevice->byPreambleType); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortPreamble= %d\n", (int)pDevice->byShortPreamble); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uConnectionRate= %d\n", (int)pDevice->uConnectionRate); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byBBType= %d\n", (int)pDevice->byBBType); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON); } -static void s_vCompleteCurrentMeasure (PSDevice pDevice, unsigned char byResult) +static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult) { - unsigned int ii; - unsigned long dwDuration = 0; - unsigned char byRPI0 = 0; - - for(ii=1;ii<8;ii++) { - pDevice->dwRPIs[ii] *= 255; - dwDuration |= *((unsigned short *) (pDevice->pCurrMeasureEID->sReq.abyDuration)); - dwDuration <<= 10; - pDevice->dwRPIs[ii] /= dwDuration; - pDevice->abyRPIs[ii] = (unsigned char) pDevice->dwRPIs[ii]; - byRPI0 += pDevice->abyRPIs[ii]; - } - pDevice->abyRPIs[0] = (0xFF - byRPI0); - - if (pDevice->uNumOfMeasureEIDs == 0) { - VNTWIFIbMeasureReport( pDevice->pMgmt, - true, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - VNTWIFIbMeasureReport( pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - CARDbStartMeasure (pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs); - } + unsigned int ii; + unsigned long dwDuration = 0; + unsigned char byRPI0 = 0; + + for (ii = 1; ii < 8; ii++) { + pDevice->dwRPIs[ii] *= 255; + dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); + dwDuration <<= 10; + pDevice->dwRPIs[ii] /= dwDuration; + pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii]; + byRPI0 += pDevice->abyRPIs[ii]; + } + pDevice->abyRPIs[0] = (0xFF - byRPI0); + + if (pDevice->uNumOfMeasureEIDs == 0) { + VNTWIFIbMeasureReport(pDevice->pMgmt, + true, + pDevice->pCurrMeasureEID, + byResult, + pDevice->byBasicMap, + pDevice->byCCAFraction, + pDevice->abyRPIs + ); + } else { + VNTWIFIbMeasureReport(pDevice->pMgmt, + false, + pDevice->pCurrMeasureEID, + byResult, + pDevice->byBasicMap, + pDevice->byCCAFraction, + pDevice->abyRPIs + ); + CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs); + } } @@ -522,316 +522,316 @@ static void s_vCompleteCurrentMeasure (PSDevice pDevice, unsigned char byResult) static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) { - unsigned int ii; - unsigned char byValue; - unsigned char byValue1; - unsigned char byCCKPwrdBm = 0; - unsigned char byOFDMPwrdBm = 0; - int zonetype=0; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - MACbShutdown(pDevice->PortOffset); - BBvSoftwareReset(pDevice->PortOffset); - - if ((InitType == DEVICE_INIT_COLD) || - (InitType == DEVICE_INIT_DXPL)) { - // Do MACbSoftwareReset in MACvInitialize - MACbSoftwareReset(pDevice->PortOffset); - // force CCK - pDevice->bCCK = true; - pDevice->bAES = false; - pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE - pDevice->bNonERPPresent = false; - pDevice->bBarkerPreambleMd = false; - pDevice->wCurrentRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_24M; - pDevice->byTopCCKBasicRate = RATE_1M; - - pDevice->byRevId = 0; //Target to IF pin while programming to RF chip. - - // init MAC - MACvInitialize(pDevice->PortOffset); - - // Get Local ID - VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID)); - - spin_lock_irq(&pDevice->lock); - SROMvReadAllContents(pDevice->PortOffset,pDevice->abyEEPROM); - - spin_unlock_irq(&pDevice->lock); - - // Get Channel range - - pDevice->byMinChannel = 1; - pDevice->byMaxChannel = CB_MAX_CHANNEL; - - // Get Antena - byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); - if (byValue & EEP_ANTINV) - pDevice->bTxRxAntInv = true; - else - pDevice->bTxRxAntInv = false; + unsigned int ii; + unsigned char byValue; + unsigned char byValue1; + unsigned char byCCKPwrdBm = 0; + unsigned char byOFDMPwrdBm = 0; + int zonetype = 0; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + MACbShutdown(pDevice->PortOffset); + BBvSoftwareReset(pDevice->PortOffset); + + if ((InitType == DEVICE_INIT_COLD) || + (InitType == DEVICE_INIT_DXPL)) { + // Do MACbSoftwareReset in MACvInitialize + MACbSoftwareReset(pDevice->PortOffset); + // force CCK + pDevice->bCCK = true; + pDevice->bAES = false; + pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE + pDevice->bNonERPPresent = false; + pDevice->bBarkerPreambleMd = false; + pDevice->wCurrentRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_24M; + pDevice->byTopCCKBasicRate = RATE_1M; + + pDevice->byRevId = 0; //Target to IF pin while programming to RF chip. + + // init MAC + MACvInitialize(pDevice->PortOffset); + + // Get Local ID + VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID)); + + spin_lock_irq(&pDevice->lock); + SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM); + + spin_unlock_irq(&pDevice->lock); + + // Get Channel range + + pDevice->byMinChannel = 1; + pDevice->byMaxChannel = CB_MAX_CHANNEL; + + // Get Antena + byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); + if (byValue & EEP_ANTINV) + pDevice->bTxRxAntInv = true; + else + pDevice->bTxRxAntInv = false; #ifdef PLICE_DEBUG - //printk("init_register:TxRxAntInv is %d,byValue is %d\n",pDevice->bTxRxAntInv,byValue); + //printk("init_register:TxRxAntInv is %d,byValue is %d\n",pDevice->bTxRxAntInv,byValue); #endif - byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - if (byValue == 0) // if not set default is All - byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); + byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); + if (byValue == 0) // if not set default is All + byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); #ifdef PLICE_DEBUG - //printk("init_register:byValue is %d\n",byValue); + //printk("init_register:byValue is %d\n",byValue); #endif - pDevice->ulDiversityNValue = 100*260;//100*SROMbyReadEmbedded(pDevice->PortOffset, 0x51); - pDevice->ulDiversityMValue = 100*16;//SROMbyReadEmbedded(pDevice->PortOffset, 0x52); - pDevice->byTMax = 1;//SROMbyReadEmbedded(pDevice->PortOffset, 0x53); - pDevice->byTMax2 = 4;//SROMbyReadEmbedded(pDevice->PortOffset, 0x54); - pDevice->ulSQ3TH = 0;//(unsigned long) SROMbyReadEmbedded(pDevice->PortOffset, 0x55); - pDevice->byTMax3 = 64;//SROMbyReadEmbedded(pDevice->PortOffset, 0x56); - - if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { - pDevice->byAntennaCount = 2; - pDevice->byTxAntennaMode = ANT_B; - pDevice->dwTxAntennaSel = 1; - pDevice->dwRxAntennaSel = 1; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_A; - else - pDevice->byRxAntennaMode = ANT_B; - // chester for antenna -byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); - // if (pDevice->bDiversityRegCtlON) - if((byValue1&0x08)==0) - pDevice->bDiversityEnable = false;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50); - else - pDevice->bDiversityEnable = true; + pDevice->ulDiversityNValue = 100*260;//100*SROMbyReadEmbedded(pDevice->PortOffset, 0x51); + pDevice->ulDiversityMValue = 100*16;//SROMbyReadEmbedded(pDevice->PortOffset, 0x52); + pDevice->byTMax = 1;//SROMbyReadEmbedded(pDevice->PortOffset, 0x53); + pDevice->byTMax2 = 4;//SROMbyReadEmbedded(pDevice->PortOffset, 0x54); + pDevice->ulSQ3TH = 0;//(unsigned long) SROMbyReadEmbedded(pDevice->PortOffset, 0x55); + pDevice->byTMax3 = 64;//SROMbyReadEmbedded(pDevice->PortOffset, 0x56); + + if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { + pDevice->byAntennaCount = 2; + pDevice->byTxAntennaMode = ANT_B; + pDevice->dwTxAntennaSel = 1; + pDevice->dwRxAntennaSel = 1; + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_A; + else + pDevice->byRxAntennaMode = ANT_B; + // chester for antenna + byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); + // if (pDevice->bDiversityRegCtlON) + if ((byValue1 & 0x08) == 0) + pDevice->bDiversityEnable = false;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50); + else + pDevice->bDiversityEnable = true; #ifdef PLICE_DEBUG - //printk("aux |main antenna: RxAntennaMode is %d\n",pDevice->byRxAntennaMode); + //printk("aux |main antenna: RxAntennaMode is %d\n",pDevice->byRxAntennaMode); #endif - } else { - pDevice->bDiversityEnable = false; - pDevice->byAntennaCount = 1; - pDevice->dwTxAntennaSel = 0; - pDevice->dwRxAntennaSel = 0; - if (byValue & EEP_ANTENNA_AUX) { - pDevice->byTxAntennaMode = ANT_A; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_B; - else - pDevice->byRxAntennaMode = ANT_A; - } else { - pDevice->byTxAntennaMode = ANT_B; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_A; - else - pDevice->byRxAntennaMode = ANT_B; - } - } + } else { + pDevice->bDiversityEnable = false; + pDevice->byAntennaCount = 1; + pDevice->dwTxAntennaSel = 0; + pDevice->dwRxAntennaSel = 0; + if (byValue & EEP_ANTENNA_AUX) { + pDevice->byTxAntennaMode = ANT_A; + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_B; + else + pDevice->byRxAntennaMode = ANT_A; + } else { + pDevice->byTxAntennaMode = ANT_B; + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_A; + else + pDevice->byRxAntennaMode = ANT_B; + } + } #ifdef PLICE_DEBUG - //printk("init registers: TxAntennaMode is %d\n",pDevice->byTxAntennaMode); + //printk("init registers: TxAntennaMode is %d\n",pDevice->byTxAntennaMode); #endif - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n", - pDevice->bDiversityEnable,(int)pDevice->ulDiversityNValue,(int)pDevice->ulDiversityMValue,pDevice->byTMax,pDevice->byTMax2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n", + pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2); //#ifdef ZoneType_DefaultSetting //2008-8-4 by chester //zonetype initial - pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - zonetype = Config_FileOperation(pDevice,false,NULL); - if (zonetype >= 0) { //read zonetype file ok! - if ((zonetype == 0)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){ //for USA - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n"); - } - else if((zonetype == 1)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){ //for Japan - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - } - else if((zonetype == 2)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){ //for Europe - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n"); - } + pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; + zonetype = Config_FileOperation(pDevice, false, NULL); + if (zonetype >= 0) { //read zonetype file ok! + if ((zonetype == 0) && + (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { //for USA + pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; + pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n"); + } + else if ((zonetype == 1) && + (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { //for Japan + pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; + pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; + } + else if ((zonetype == 2) && + (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { //for Europe + pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; + pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n"); + } -else -{ - if(zonetype!=pDevice->abyEEPROM[EEP_OFS_ZONETYPE]) - printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",zonetype,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]); - else - printk("Read Zonetype file success,use default zonetype setting[%02x]\n",zonetype); - } - } - else - printk("Read Zonetype file fail,use default zonetype setting[%02x]\n",SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE)); - - // Get RFType - pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); - - if ((pDevice->byRFType & RF_EMU) != 0) { - // force change RevID for VT3253 emu - pDevice->byRevId = 0x80; - } - - pDevice->byRFType &= RF_MASK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType); - - if (pDevice->bZoneRegExist == false) { - pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType); - - //Init RF module - RFbInit(pDevice); - - //Get Desire Power Value - pDevice->byCurPwr = 0xFF; - pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK); - pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG); - //byCCKPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_CCK_PWR_dBm); - - //byOFDMPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_OFDM_PWR_dBm); + else + { + if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE]) + printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", zonetype, pDevice->abyEEPROM[EEP_OFS_ZONETYPE]); + else + printk("Read Zonetype file success,use default zonetype setting[%02x]\n", zonetype); + } + } + else + printk("Read Zonetype file fail,use default zonetype setting[%02x]\n", SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE)); + + // Get RFType + pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); + + if ((pDevice->byRFType & RF_EMU) != 0) { + // force change RevID for VT3253 emu + pDevice->byRevId = 0x80; + } + + pDevice->byRFType &= RF_MASK; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType); + + if (pDevice->bZoneRegExist == false) { + pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType); + + //Init RF module + RFbInit(pDevice); + + //Get Desire Power Value + pDevice->byCurPwr = 0xFF; + pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK); + pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG); + //byCCKPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_CCK_PWR_dBm); + + //byOFDMPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_OFDM_PWR_dBm); //printk("CCKPwrdBm is 0x%x,byOFDMPwrdBm is 0x%x\n",byCCKPwrdBm,byOFDMPwrdBm); // Load power Table - for (ii=0;iiabyCCKPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL)); - if (pDevice->abyCCKPwrTbl[ii+1] == 0) { - pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr; - } - pDevice->abyOFDMPwrTbl[ii+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL)); - if (pDevice->abyOFDMPwrTbl[ii+1] == 0) { - pDevice->abyOFDMPwrTbl[ii+1] = pDevice->byOFDMPwrG; - } - pDevice->abyCCKDefaultPwr[ii+1] = byCCKPwrdBm; - pDevice->abyOFDMDefaultPwr[ii+1] = byOFDMPwrdBm; - } + for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) { + pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL)); + if (pDevice->abyCCKPwrTbl[ii + 1] == 0) { + pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr; + } + pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL)); + if (pDevice->abyOFDMPwrTbl[ii + 1] == 0) { + pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG; + } + pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm; + pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm; + } //2008-8-4 by chester - //recover 12,13 ,14channel for EUROPE by 11 channel - if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&& - (pDevice->byOriginalZonetype == ZoneType_USA)) { - for(ii=11;ii<14;ii++) { - pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; - pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; + //recover 12,13 ,14channel for EUROPE by 11 channel + if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || + (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) && + (pDevice->byOriginalZonetype == ZoneType_USA)) { + for (ii = 11; ii < 14; ii++) { + pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; + pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; - } - } + } + } - // Load OFDM A Power Table - for (ii=0;iiabyOFDMPwrTbl[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL)); - pDevice->abyOFDMDefaultPwr[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); - } - init_channel_table((void *)pDevice); + // Load OFDM A Power Table + for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL + pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL)); + pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); + } + init_channel_table((void *)pDevice); - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN)); - MACvSelectPage0(pDevice->PortOffset); - } + if (pDevice->byLocalID > REV_ID_VT3253_B1) { + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN)); + MACvSelectPage0(pDevice->PortOffset); + } - // use relative tx timeout and 802.11i D4 - MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT)); + // use relative tx timeout and 802.11i D4 + MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT)); - // set performance parameter by registry - MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit); - MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit); + // set performance parameter by registry + MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit); + MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit); - // reset TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + // reset TSF counter + VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); + // enable TSF counter + VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - // initialize BBP registers - BBbVT3253Init(pDevice); + // initialize BBP registers + BBbVT3253Init(pDevice); - if (pDevice->bUpdateBBVGA) { - pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; - pDevice->byBBVGANew = pDevice->byBBVGACurrent; - BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); - } + if (pDevice->bUpdateBBVGA) { + pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; + pDevice->byBBVGANew = pDevice->byBBVGACurrent; + BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); + } #ifdef PLICE_DEBUG - //printk("init registers:RxAntennaMode is %x,TxAntennaMode is %x\n",pDevice->byRxAntennaMode,pDevice->byTxAntennaMode); + //printk("init registers:RxAntennaMode is %x,TxAntennaMode is %x\n",pDevice->byRxAntennaMode,pDevice->byTxAntennaMode); #endif - BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode); - BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode); + BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode); + BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode); - pDevice->byCurrentCh = 0; + pDevice->byCurrentCh = 0; - //pDevice->NetworkType = Ndis802_11Automode; - // Set BB and packet type at the same time. - // Set Short Slot Time, xIFS, and RSPINF. - if (pDevice->uConnectionRate == RATE_AUTO) { - pDevice->wCurrentRate = RATE_54M; - } else { - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } + //pDevice->NetworkType = Ndis802_11Automode; + // Set BB and packet type at the same time. + // Set Short Slot Time, xIFS, and RSPINF. + if (pDevice->uConnectionRate == RATE_AUTO) { + pDevice->wCurrentRate = RATE_54M; + } else { + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } - // default G Mode - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G); - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO); + // default G Mode + VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G); + VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO); - pDevice->bRadioOff = false; + pDevice->bRadioOff = false; - pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL); - pDevice->bHWRadioOff = false; + pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL); + pDevice->bHWRadioOff = false; - if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) { - // Get GPIO - MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); + if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) { + // Get GPIO + MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); //2008-4-14 by chester for led issue - #ifdef FOR_LED_ON_NOTEBOOK -if (pDevice->byGPIO & GPIO0_DATA){pDevice->bHWRadioOff = true;} -if ( !(pDevice->byGPIO & GPIO0_DATA)){pDevice->bHWRadioOff = false;} - - } - if ( (pDevice->bRadioControlOff == true)) { - CARDbRadioPowerOff(pDevice); - } -else CARDbRadioPowerOn(pDevice); +#ifdef FOR_LED_ON_NOTEBOOK + if (pDevice->byGPIO & GPIO0_DATA) { pDevice->bHWRadioOff = true; } + if (!(pDevice->byGPIO & GPIO0_DATA)) { pDevice->bHWRadioOff = false; } + + } + if ((pDevice->bRadioControlOff == true)) { + CARDbRadioPowerOff(pDevice); + } + else CARDbRadioPowerOn(pDevice); #else - if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) || - ( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) { - pDevice->bHWRadioOff = true; - } - } - if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) { - CARDbRadioPowerOff(pDevice); - } + if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) || + (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) { + pDevice->bHWRadioOff = true; + } + } + if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) { + CARDbRadioPowerOff(pDevice); + } #endif - } - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - // get Permanent network address - SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n", - pDevice->abyCurrentNetAddr); - - // reset Tx pointer - CARDvSafeResetRx(pDevice); - // reset Rx pointer - CARDvSafeResetTx(pDevice); - - if (pDevice->byLocalID <= REV_ID_VT3253_A1) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR); - } +} +pMgmt->eScanType = WMAC_SCAN_PASSIVE; +// get Permanent network address +SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); +DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n", + pDevice->abyCurrentNetAddr); + +// reset Tx pointer +CARDvSafeResetRx(pDevice); +// reset Rx pointer +CARDvSafeResetTx(pDevice); + +if (pDevice->byLocalID <= REV_ID_VT3253_A1) { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR); +} - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; +pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - // Turn On Rx DMA - MACvReceive0(pDevice->PortOffset); - MACvReceive1(pDevice->PortOffset); +// Turn On Rx DMA +MACvReceive0(pDevice->PortOffset); +MACvReceive1(pDevice->PortOffset); - // start the adapter - MACvStart(pDevice->PortOffset); +// start the adapter +MACvStart(pDevice->PortOffset); - netif_stop_queue(pDevice->dev); +netif_stop_queue(pDevice->dev); } @@ -840,57 +840,57 @@ else CARDbRadioPowerOn(pDevice); static void device_init_diversity_timer(PSDevice pDevice) { - init_timer(&pDevice->TimerSQ3Tmax1); - pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; - pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ); + init_timer(&pDevice->TimerSQ3Tmax1); + pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice; + pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ); - init_timer(&pDevice->TimerSQ3Tmax2); - pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack; - pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ); + init_timer(&pDevice->TimerSQ3Tmax2); + pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice; + pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ); - init_timer(&pDevice->TimerSQ3Tmax3); - pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack; - pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); + init_timer(&pDevice->TimerSQ3Tmax3); + pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice; + pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack; + pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); - return; + return; } static bool device_release_WPADEV(PSDevice pDevice) { - viawget_wpa_header *wpahdr; - int ii=0; - // wait_queue_head_t Set_wait; - //send device close to wpa_supplicnat layer - if (pDevice->bWPADEVUp==true) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DEVICECLOSE_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - - //wait release WPADEV - // init_waitqueue_head(&Set_wait); - // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait - while((pDevice->bWPADEVUp==true)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout (HZ/20); //wait 50ms - ii++; - if(ii>20) - break; - } - } - return true; + viawget_wpa_header *wpahdr; + int ii = 0; + // wait_queue_head_t Set_wait; + //send device close to wpa_supplicnat layer + if (pDevice->bWPADEVUp == true) { + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + wpahdr->type = VIAWGET_DEVICECLOSE_MSG; + wpahdr->resp_ie_len = 0; + wpahdr->req_ie_len = 0; + skb_put(pDevice->skb, sizeof(viawget_wpa_header)); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + + //wait release WPADEV + // init_waitqueue_head(&Set_wait); + // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait + while ((pDevice->bWPADEVUp == true)) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 20); //wait 50ms + ii++; + if (ii > 20) + break; + } + } + return true; } static const struct net_device_ops device_netdev_ops = { @@ -905,90 +905,90 @@ static const struct net_device_ops device_netdev_ops = { static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) { - static bool bFirst = true; - struct net_device* dev = NULL; - PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; - PSDevice pDevice; - int rc; - if (device_nics ++>= MAX_UINTS) { - printk(KERN_NOTICE DEVICE_NAME ": already found %d NICs\n", device_nics); - return -ENODEV; - } - - - dev = alloc_etherdev(sizeof(DEVICE_INFO)); - - pDevice = (PSDevice) netdev_priv(dev); - - if (dev == NULL) { - printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n"); - return -ENOMEM; - } - - // Chain it all together - // SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pcid->dev); - - if (bFirst) { - printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); - bFirst=false; - } - - vt6655_init_info(pcid, &pDevice, pChip_info); - pDevice->dev = dev; - pDevice->next_module = root_device_dev; - root_device_dev = dev; - - if (pci_enable_device(pcid)) { - device_free_info(pDevice); - return -ENODEV; - } - dev->irq = pcid->irq; + static bool bFirst = true; + struct net_device *dev = NULL; + PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; + PSDevice pDevice; + int rc; + if (device_nics++ >= MAX_UINTS) { + printk(KERN_NOTICE DEVICE_NAME ": already found %d NICs\n", device_nics); + return -ENODEV; + } + + + dev = alloc_etherdev(sizeof(DEVICE_INFO)); + + pDevice = (PSDevice) netdev_priv(dev); + + if (dev == NULL) { + printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n"); + return -ENOMEM; + } + + // Chain it all together + // SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pcid->dev); + + if (bFirst) { + printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); + printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); + bFirst = false; + } + + vt6655_init_info(pcid, &pDevice, pChip_info); + pDevice->dev = dev; + pDevice->next_module = root_device_dev; + root_device_dev = dev; + + if (pci_enable_device(pcid)) { + device_free_info(pDevice); + return -ENODEV; + } + dev->irq = pcid->irq; #ifdef DEBUG - printk("Before get pci_info memaddr is %x\n",pDevice->memaddr); + printk("Before get pci_info memaddr is %x\n", pDevice->memaddr); #endif - if (device_get_pci_info(pDevice,pcid) == false) { - printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n"); - device_free_info(pDevice); - return -ENODEV; - } + if (device_get_pci_info(pDevice, pcid) == false) { + printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n"); + device_free_info(pDevice); + return -ENODEV; + } #if 1 #ifdef DEBUG //pci_read_config_byte(pcid, PCI_BASE_ADDRESS_0, &pDevice->byRevId); - printk("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n",pDevice->memaddr,pDevice->ioaddr,pDevice->io_size); + printk("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size); { int i; - u32 bar,len; + u32 bar, len; u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0}; - for (i=0;address[i];i++) + PCI_BASE_ADDRESS_0, + PCI_BASE_ADDRESS_1, + PCI_BASE_ADDRESS_2, + PCI_BASE_ADDRESS_3, + PCI_BASE_ADDRESS_4, + PCI_BASE_ADDRESS_5, + 0}; + for (i = 0; address[i]; i++) { //pci_write_config_dword(pcid,address[i], 0xFFFFFFFF); pci_read_config_dword(pcid, address[i], &bar); - printk("bar %d is %x\n",i,bar); + printk("bar %d is %x\n", i, bar); if (!bar) { - printk("bar %d not implemented\n",i); + printk("bar %d not implemented\n", i); continue; } if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ + /* This is IO */ - len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); + len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); + len = len & ~(len - 1); - printk("IO space: len in IO %x, BAR %d\n", len, i); + printk("IO space: len in IO %x, BAR %d\n", len, i); } else { @@ -1005,163 +1005,163 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) #endif #ifdef DEBUG - //return 0 ; + //return 0; #endif - pDevice->PortOffset = (unsigned long)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size); + pDevice->PortOffset = (unsigned long)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size); //pDevice->PortOffset = (unsigned long)ioremap(pDevice->ioaddr & PCI_BASE_ADDRESS_IO_MASK, pDevice->io_size); - if(pDevice->PortOffset == 0) { - printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n"); - device_free_info(pDevice); - return -ENODEV; - } + if (pDevice->PortOffset == 0) { + printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n"); + device_free_info(pDevice); + return -ENODEV; + } - rc = pci_request_regions(pcid, DEVICE_NAME); - if (rc) { - printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n"); - device_free_info(pDevice); - return -ENODEV; - } + rc = pci_request_regions(pcid, DEVICE_NAME); + if (rc) { + printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n"); + device_free_info(pDevice); + return -ENODEV; + } - dev->base_addr = pDevice->ioaddr; + dev->base_addr = pDevice->ioaddr; #ifdef PLICE_DEBUG - unsigned char value; + unsigned char value; VNSvInPortB(pDevice->PortOffset+0x4F, &value); - printk("Before write: value is %x\n",value); + printk("Before write: value is %x\n", value); //VNSvInPortB(pDevice->PortOffset+0x3F, 0x00); - VNSvOutPortB(pDevice->PortOffset,value); + VNSvOutPortB(pDevice->PortOffset, value); VNSvInPortB(pDevice->PortOffset+0x4F, &value); - printk("After write: value is %x\n",value); + printk("After write: value is %x\n", value); #endif #ifdef IO_MAP - pDevice->PortOffset = pDevice->ioaddr; + pDevice->PortOffset = pDevice->ioaddr; #endif - // do reset - if (!MACbSoftwareReset(pDevice->PortOffset)) { - printk(KERN_ERR DEVICE_NAME ": Failed to access MAC hardware..\n"); - device_free_info(pDevice); - return -ENODEV; - } - // initial to reload eeprom - MACvInitialize(pDevice->PortOffset); - MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr); - - device_get_options(pDevice, device_nics-1, dev->name); - device_set_options(pDevice); - //Mask out the options cannot be set to the chip - pDevice->sOpts.flags &= pChip_info->flags; - - //Enable the chip specified capabilities - pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); - pDevice->tx_80211 = device_dma0_tx_80211; - pDevice->sMgmtObj.pAdapter = (void *)pDevice; - pDevice->pMgmt = &(pDevice->sMgmtObj); - - dev->irq = pcid->irq; - dev->netdev_ops = &device_netdev_ops; + // do reset + if (!MACbSoftwareReset(pDevice->PortOffset)) { + printk(KERN_ERR DEVICE_NAME ": Failed to access MAC hardware..\n"); + device_free_info(pDevice); + return -ENODEV; + } + // initial to reload eeprom + MACvInitialize(pDevice->PortOffset); + MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr); + + device_get_options(pDevice, device_nics-1, dev->name); + device_set_options(pDevice); + //Mask out the options cannot be set to the chip + pDevice->sOpts.flags &= pChip_info->flags; + + //Enable the chip specified capabilities + pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); + pDevice->tx_80211 = device_dma0_tx_80211; + pDevice->sMgmtObj.pAdapter = (void *)pDevice; + pDevice->pMgmt = &(pDevice->sMgmtObj); + + dev->irq = pcid->irq; + dev->netdev_ops = &device_netdev_ops; dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def; - rc = register_netdev(dev); - if (rc) - { - printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n"); - device_free_info(pDevice); - return -ENODEV; - } - device_print_info(pDevice); - pci_set_drvdata(pcid, pDevice); - return 0; + rc = register_netdev(dev); + if (rc) + { + printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n"); + device_free_info(pDevice); + return -ENODEV; + } + device_print_info(pDevice); + pci_set_drvdata(pcid, pDevice); + return 0; } static void device_print_info(PSDevice pDevice) { - struct net_device* dev=pDevice->dev; + struct net_device *dev = pDevice->dev; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id)); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id)); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr); #ifdef IO_MAP - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx ",(unsigned long) pDevice->ioaddr); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx ", (unsigned long)pDevice->ioaddr); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq); #else - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ", - (unsigned long) pDevice->ioaddr,(unsigned long) pDevice->PortOffset); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ", + (unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq); #endif } -static void vt6655_init_info(struct pci_dev* pcid, PSDevice* ppDevice, - PCHIP_INFO pChip_info) { +static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, + PCHIP_INFO pChip_info) { - PSDevice p; + PSDevice p; - memset(*ppDevice,0,sizeof(DEVICE_INFO)); + memset(*ppDevice, 0, sizeof(DEVICE_INFO)); - if (pDevice_Infos == NULL) { - pDevice_Infos =*ppDevice; - } - else { - for (p=pDevice_Infos;p->next!=NULL;p=p->next) - do {} while (0); - p->next = *ppDevice; - (*ppDevice)->prev = p; - } + if (pDevice_Infos == NULL) { + pDevice_Infos = *ppDevice; + } + else { + for (p = pDevice_Infos; p->next != NULL; p = p->next) + do {} while (0); + p->next = *ppDevice; + (*ppDevice)->prev = p; + } - (*ppDevice)->pcid = pcid; - (*ppDevice)->chip_id = pChip_info->chip_id; - (*ppDevice)->io_size = pChip_info->io_size; - (*ppDevice)->nTxQueues = pChip_info->nTxQueue; - (*ppDevice)->multicast_limit =32; + (*ppDevice)->pcid = pcid; + (*ppDevice)->chip_id = pChip_info->chip_id; + (*ppDevice)->io_size = pChip_info->io_size; + (*ppDevice)->nTxQueues = pChip_info->nTxQueue; + (*ppDevice)->multicast_limit = 32; - spin_lock_init(&((*ppDevice)->lock)); + spin_lock_init(&((*ppDevice)->lock)); } -static bool device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) { +static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) { - u16 pci_cmd; - u8 b; - unsigned int cis_addr; + u16 pci_cmd; + u8 b; + unsigned int cis_addr; #ifdef PLICE_DEBUG unsigned char pci_config[256]; - unsigned char value =0x00; - int ii,j; - u16 max_lat=0x0000; - memset(pci_config,0x00,256); + unsigned char value = 0x00; + int ii, j; + u16 max_lat = 0x0000; + memset(pci_config, 0x00, 256); #endif - pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId); - pci_read_config_word(pcid, PCI_SUBSYSTEM_ID,&pDevice->SubSystemID); - pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID); - pci_read_config_word(pcid, PCI_COMMAND, (u16 *) & (pci_cmd)); + pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId); + pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pDevice->SubSystemID); + pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID); + pci_read_config_word(pcid, PCI_COMMAND, (u16 *)&(pci_cmd)); - pci_set_master(pcid); + pci_set_master(pcid); - pDevice->memaddr = pci_resource_start(pcid,0); - pDevice->ioaddr = pci_resource_start(pcid,1); + pDevice->memaddr = pci_resource_start(pcid, 0); + pDevice->ioaddr = pci_resource_start(pcid, 1); #ifdef DEBUG // pDevice->ioaddr = pci_resource_start(pcid, 0); // pDevice->memaddr = pci_resource_start(pcid,1); #endif - cis_addr = pci_resource_start(pcid,2); + cis_addr = pci_resource_start(pcid, 2); - pDevice->pcid = pcid; + pDevice->pcid = pcid; - pci_read_config_byte(pcid, PCI_COMMAND, &b); - pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER)); + pci_read_config_byte(pcid, PCI_COMMAND, &b); + pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER)); #ifdef PLICE_DEBUG - //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat); + //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat); //printk("max lat is %x,SubSystemID is %x\n",max_lat,pDevice->SubSystemID); //for (ii=0;ii<0xFF;ii++) //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat); @@ -1170,399 +1170,399 @@ static bool device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) { //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat); //printk("max lat is %x\n",max_lat); - for (ii=0;ii<0xFF;ii++) + for (ii = 0; ii < 0xFF; ii++) { - pci_read_config_byte(pcid,ii,&value); + pci_read_config_byte(pcid, ii, &value); pci_config[ii] = value; } - for (ii=0,j=1;ii<0x100;ii++,j++) + for (ii = 0, j = 1; ii < 0x100; ii++, j++) { - if (j %16 == 0) + if (j % 16 == 0) { - printk("%x:",pci_config[ii]); + printk("%x:", pci_config[ii]); printk("\n"); } else { - printk("%x:",pci_config[ii]); + printk("%x:", pci_config[ii]); } } #endif - return true; + return true; } static void device_free_info(PSDevice pDevice) { - PSDevice ptr; - struct net_device* dev=pDevice->dev; + PSDevice ptr; + struct net_device *dev = pDevice->dev; - ASSERT(pDevice); + ASSERT(pDevice); //2008-0714-01by chester -device_release_WPADEV(pDevice); + device_release_WPADEV(pDevice); //2008-07-21-01by MikeLiu //unregister wpadev - if(wpa_set_wpadev(pDevice, 0)!=0) - printk("unregister wpadev fail?\n"); - - if (pDevice_Infos==NULL) - return; - - for (ptr=pDevice_Infos;ptr && (ptr!=pDevice);ptr=ptr->next) - do {} while (0); - - if (ptr==pDevice) { - if (ptr==pDevice_Infos) - pDevice_Infos=ptr->next; - else - ptr->prev->next=ptr->next; - } - else { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n"); - return; - } + if (wpa_set_wpadev(pDevice, 0) != 0) + printk("unregister wpadev fail?\n"); + + if (pDevice_Infos == NULL) + return; + + for (ptr = pDevice_Infos; ptr && (ptr != pDevice); ptr = ptr->next) + do {} while (0); + + if (ptr == pDevice) { + if (ptr == pDevice_Infos) + pDevice_Infos = ptr->next; + else + ptr->prev->next = ptr->next; + } + else { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n"); + return; + } #ifdef HOSTAP - if (dev) - vt6655_hostap_set_hostapd(pDevice, 0, 0); + if (dev) + vt6655_hostap_set_hostapd(pDevice, 0, 0); #endif - if (dev) - unregister_netdev(dev); + if (dev) + unregister_netdev(dev); - if (pDevice->PortOffset) - iounmap((void *)pDevice->PortOffset); + if (pDevice->PortOffset) + iounmap((void *)pDevice->PortOffset); - if (pDevice->pcid) - pci_release_regions(pDevice->pcid); - if (dev) - free_netdev(dev); + if (pDevice->pcid) + pci_release_regions(pDevice->pcid); + if (dev) + free_netdev(dev); - if (pDevice->pcid) { - pci_set_drvdata(pDevice->pcid,NULL); - } + if (pDevice->pcid) { + pci_set_drvdata(pDevice->pcid, NULL); + } } static bool device_init_rings(PSDevice pDevice) { - void* vir_pool; - - - /*allocate all RD/TD rings a single pool*/ - vir_pool = pci_alloc_consistent(pDevice->pcid, - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + - pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + - pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + - pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc), - &pDevice->pool_dma); + void *vir_pool; - if (vir_pool == NULL) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name); - return false; - } - memset(vir_pool, 0, - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + - pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + - pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + - pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc) - ); + /*allocate all RD/TD rings a single pool*/ + vir_pool = pci_alloc_consistent(pDevice->pcid, + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + + pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc), + &pDevice->pool_dma); - pDevice->aRD0Ring = vir_pool; - pDevice->aRD1Ring = vir_pool + - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc); - - - pDevice->rd0_pool_dma = pDevice->pool_dma; - pDevice->rd1_pool_dma = pDevice->rd0_pool_dma + - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc); - - pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid, - pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + - pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + - CB_BEACON_BUF_SIZE + - CB_MAX_BUF_SIZE, - &pDevice->tx_bufs_dma0); + if (vir_pool == NULL) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name); + return false; + } - if (pDevice->tx0_bufs == NULL) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name); - pci_free_consistent(pDevice->pcid, - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + - pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + - pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + - pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc), - vir_pool, pDevice->pool_dma - ); - return false; - } + memset(vir_pool, 0, + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + + pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc) + ); + + pDevice->aRD0Ring = vir_pool; + pDevice->aRD1Ring = vir_pool + + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc); + + + pDevice->rd0_pool_dma = pDevice->pool_dma; + pDevice->rd1_pool_dma = pDevice->rd0_pool_dma + + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc); + + pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid, + pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + + pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + + CB_BEACON_BUF_SIZE + + CB_MAX_BUF_SIZE, + &pDevice->tx_bufs_dma0); + + if (pDevice->tx0_bufs == NULL) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name); + pci_free_consistent(pDevice->pcid, + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + + pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc), + vir_pool, pDevice->pool_dma + ); + return false; + } - memset(pDevice->tx0_bufs, 0, - pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + - pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + - CB_BEACON_BUF_SIZE + - CB_MAX_BUF_SIZE - ); + memset(pDevice->tx0_bufs, 0, + pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + + pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + + CB_BEACON_BUF_SIZE + + CB_MAX_BUF_SIZE + ); - pDevice->td0_pool_dma = pDevice->rd1_pool_dma + - pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc); + pDevice->td0_pool_dma = pDevice->rd1_pool_dma + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc); - pDevice->td1_pool_dma = pDevice->td0_pool_dma + - pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc); + pDevice->td1_pool_dma = pDevice->td0_pool_dma + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc); - // vir_pool: pvoid type - pDevice->apTD0Rings = vir_pool - + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) - + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc); + // vir_pool: pvoid type + pDevice->apTD0Rings = vir_pool + + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc); - pDevice->apTD1Rings = vir_pool - + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) - + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) - + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc); + pDevice->apTD1Rings = vir_pool + + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc); - pDevice->tx1_bufs = pDevice->tx0_bufs + - pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ; + pDevice->tx1_bufs = pDevice->tx0_bufs + + pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ; - pDevice->tx_beacon_bufs = pDevice->tx1_bufs + - pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ; + pDevice->tx_beacon_bufs = pDevice->tx1_bufs + + pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ; - pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs + - CB_BEACON_BUF_SIZE; + pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs + + CB_BEACON_BUF_SIZE; - pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 + - pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ; + pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 + + pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ; - pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 + - pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ; + pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 + + pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ; - return true; + return true; } static void device_free_rings(PSDevice pDevice) { - pci_free_consistent(pDevice->pcid, - pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + - pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + - pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + - pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc) - , - pDevice->aRD0Ring, pDevice->pool_dma - ); - - if (pDevice->tx0_bufs) - pci_free_consistent(pDevice->pcid, - pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + - pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + - CB_BEACON_BUF_SIZE + - CB_MAX_BUF_SIZE, - pDevice->tx0_bufs, pDevice->tx_bufs_dma0 - ); + pci_free_consistent(pDevice->pcid, + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) + + pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc) + , + pDevice->aRD0Ring, pDevice->pool_dma + ); + + if (pDevice->tx0_bufs) + pci_free_consistent(pDevice->pcid, + pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ + + pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ + + CB_BEACON_BUF_SIZE + + CB_MAX_BUF_SIZE, + pDevice->tx0_bufs, pDevice->tx_bufs_dma0 + ); } static void device_init_rd0_ring(PSDevice pDevice) { - int i; - dma_addr_t curr = pDevice->rd0_pool_dma; - PSRxDesc pDesc; - - /* Init the RD0 ring entries */ - for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) { - pDesc = &(pDevice->aRD0Ring[i]); - pDesc->pRDInfo = alloc_rd_info(); - ASSERT(pDesc->pRDInfo); - if (!device_alloc_rx_buf(pDevice, pDesc)) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n", - pDevice->dev->name); - } - pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]); - pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); - pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc)); - } - - if (i > 0) - pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma); - pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); + int i; + dma_addr_t curr = pDevice->rd0_pool_dma; + PSRxDesc pDesc; + + /* Init the RD0 ring entries */ + for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) { + pDesc = &(pDevice->aRD0Ring[i]); + pDesc->pRDInfo = alloc_rd_info(); + ASSERT(pDesc->pRDInfo); + if (!device_alloc_rx_buf(pDevice, pDesc)) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n", + pDevice->dev->name); + } + pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]); + pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); + pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc)); + } + + if (i > 0) + pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma); + pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); } static void device_init_rd1_ring(PSDevice pDevice) { - int i; - dma_addr_t curr = pDevice->rd1_pool_dma; - PSRxDesc pDesc; - - /* Init the RD1 ring entries */ - for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) { - pDesc = &(pDevice->aRD1Ring[i]); - pDesc->pRDInfo = alloc_rd_info(); - ASSERT(pDesc->pRDInfo); - if (!device_alloc_rx_buf(pDevice, pDesc)) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n", - pDevice->dev->name); - } - pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]); - pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); - pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc)); - } - - if (i > 0) - pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma); - pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); + int i; + dma_addr_t curr = pDevice->rd1_pool_dma; + PSRxDesc pDesc; + + /* Init the RD1 ring entries */ + for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) { + pDesc = &(pDevice->aRD1Ring[i]); + pDesc->pRDInfo = alloc_rd_info(); + ASSERT(pDesc->pRDInfo); + if (!device_alloc_rx_buf(pDevice, pDesc)) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n", + pDevice->dev->name); + } + pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]); + pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); + pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc)); + } + + if (i > 0) + pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma); + pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); } static void device_init_defrag_cb(PSDevice pDevice) { - int i; - PSDeFragControlBlock pDeF; - - /* Init the fragment ctl entries */ - for (i = 0; i < CB_MAX_RX_FRAG; i++) { - pDeF = &(pDevice->sRxDFCB[i]); - if (!device_alloc_frag_buf(pDevice, pDeF)) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n", - pDevice->dev->name); - } - } - pDevice->cbDFCB = CB_MAX_RX_FRAG; - pDevice->cbFreeDFCB = pDevice->cbDFCB; + int i; + PSDeFragControlBlock pDeF; + + /* Init the fragment ctl entries */ + for (i = 0; i < CB_MAX_RX_FRAG; i++) { + pDeF = &(pDevice->sRxDFCB[i]); + if (!device_alloc_frag_buf(pDevice, pDeF)) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc frag bufs\n", + pDevice->dev->name); + } + } + pDevice->cbDFCB = CB_MAX_RX_FRAG; + pDevice->cbFreeDFCB = pDevice->cbDFCB; } static void device_free_rd0_ring(PSDevice pDevice) { - int i; + int i; - for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) { - PSRxDesc pDesc =&(pDevice->aRD0Ring[i]); - PDEVICE_RD_INFO pRDInfo =pDesc->pRDInfo; + for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) { + PSRxDesc pDesc = &(pDevice->aRD0Ring[i]); + PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo; - pci_unmap_single(pDevice->pcid,pRDInfo->skb_dma, - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); - dev_kfree_skb(pRDInfo->skb); + dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); - } + kfree((void *)pDesc->pRDInfo); + } } static void device_free_rd1_ring(PSDevice pDevice) { - int i; + int i; - for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) { - PSRxDesc pDesc=&(pDevice->aRD1Ring[i]); - PDEVICE_RD_INFO pRDInfo=pDesc->pRDInfo; + for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) { + PSRxDesc pDesc = &(pDevice->aRD1Ring[i]); + PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo; - pci_unmap_single(pDevice->pcid,pRDInfo->skb_dma, - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); - dev_kfree_skb(pRDInfo->skb); + dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); - } + kfree((void *)pDesc->pRDInfo); + } } static void device_free_frag_buf(PSDevice pDevice) { - PSDeFragControlBlock pDeF; - int i; + PSDeFragControlBlock pDeF; + int i; - for (i = 0; i < CB_MAX_RX_FRAG; i++) { + for (i = 0; i < CB_MAX_RX_FRAG; i++) { - pDeF = &(pDevice->sRxDFCB[i]); + pDeF = &(pDevice->sRxDFCB[i]); - if (pDeF->skb) - dev_kfree_skb(pDeF->skb); + if (pDeF->skb) + dev_kfree_skb(pDeF->skb); - } + } } static void device_init_td0_ring(PSDevice pDevice) { - int i; - dma_addr_t curr; - PSTxDesc pDesc; - - curr = pDevice->td0_pool_dma; - for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) { - pDesc = &(pDevice->apTD0Rings[i]); - pDesc->pTDInfo = alloc_td_info(); - ASSERT(pDesc->pTDInfo); - if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) { - pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ; - pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ; - } - pDesc->next =&(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]); - pDesc->pTDInfo->curr_desc = cpu_to_le32(curr); - pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc)); - } - - if (i > 0) - pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma); - pDevice->apTailTD[0] = pDevice->apCurrTD[0] =&(pDevice->apTD0Rings[0]); + int i; + dma_addr_t curr; + PSTxDesc pDesc; + + curr = pDevice->td0_pool_dma; + for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) { + pDesc = &(pDevice->apTD0Rings[i]); + pDesc->pTDInfo = alloc_td_info(); + ASSERT(pDesc->pTDInfo); + if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) { + pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ; + pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ; + } + pDesc->next = &(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]); + pDesc->pTDInfo->curr_desc = cpu_to_le32(curr); + pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc)); + } + + if (i > 0) + pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma); + pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); } static void device_init_td1_ring(PSDevice pDevice) { - int i; - dma_addr_t curr; - PSTxDesc pDesc; - - /* Init the TD ring entries */ - curr=pDevice->td1_pool_dma; - for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr+=sizeof(STxDesc)) { - pDesc=&(pDevice->apTD1Rings[i]); - pDesc->pTDInfo = alloc_td_info(); - ASSERT(pDesc->pTDInfo); - if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) { - pDesc->pTDInfo->buf=pDevice->tx1_bufs+(i)*PKT_BUF_SZ; - pDesc->pTDInfo->buf_dma=pDevice->tx_bufs_dma1+(i)*PKT_BUF_SZ; - } - pDesc->next=&(pDevice->apTD1Rings[(i+1) % pDevice->sOpts.nTxDescs[1]]); - pDesc->pTDInfo->curr_desc = cpu_to_le32(curr); - pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc)); - } - - if (i > 0) - pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma); - pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); + int i; + dma_addr_t curr; + PSTxDesc pDesc; + + /* Init the TD ring entries */ + curr = pDevice->td1_pool_dma; + for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr += sizeof(STxDesc)) { + pDesc = &(pDevice->apTD1Rings[i]); + pDesc->pTDInfo = alloc_td_info(); + ASSERT(pDesc->pTDInfo); + if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) { + pDesc->pTDInfo->buf = pDevice->tx1_bufs + (i) * PKT_BUF_SZ; + pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma1 + (i) * PKT_BUF_SZ; + } + pDesc->next = &(pDevice->apTD1Rings[(i + 1) % pDevice->sOpts.nTxDescs[1]]); + pDesc->pTDInfo->curr_desc = cpu_to_le32(curr); + pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc)); + } + + if (i > 0) + pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma); + pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); } static void device_free_td0_ring(PSDevice pDevice) { - int i; - for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) { - PSTxDesc pDesc=&(pDevice->apTD0Rings[i]); - PDEVICE_TD_INFO pTDInfo=pDesc->pTDInfo; + int i; + for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) { + PSTxDesc pDesc = &(pDevice->apTD0Rings[i]); + PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo; - if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) - pci_unmap_single(pDevice->pcid,pTDInfo->skb_dma, - pTDInfo->skb->len, PCI_DMA_TODEVICE); + if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) + pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, + pTDInfo->skb->len, PCI_DMA_TODEVICE); - if (pTDInfo->skb) - dev_kfree_skb(pTDInfo->skb); + if (pTDInfo->skb) + dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); - } + kfree((void *)pDesc->pTDInfo); + } } static void device_free_td1_ring(PSDevice pDevice) { - int i; + int i; - for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) { - PSTxDesc pDesc=&(pDevice->apTD1Rings[i]); - PDEVICE_TD_INFO pTDInfo=pDesc->pTDInfo; + for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) { + PSTxDesc pDesc = &(pDevice->apTD1Rings[i]); + PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo; - if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) - pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, - pTDInfo->skb->len, PCI_DMA_TODEVICE); + if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) + pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, + pTDInfo->skb->len, PCI_DMA_TODEVICE); - if (pTDInfo->skb) - dev_kfree_skb(pTDInfo->skb); + if (pTDInfo->skb) + dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); - } + kfree((void *)pDesc->pTDInfo); + } } @@ -1571,239 +1571,239 @@ static void device_free_td1_ring(PSDevice pDevice) { /*-----------------------------------------------------------------*/ static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) { - PSRxDesc pRD; - int works = 0; + PSRxDesc pRD; + int works = 0; - for (pRD = pDevice->pCurrRD[uIdx]; - pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST; - pRD = pRD->next) { + for (pRD = pDevice->pCurrRD[uIdx]; + pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST; + pRD = pRD->next) { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->pCurrRD = %x, works = %d\n", pRD, works); - if (works++>15) - break; - if (device_receive_frame(pDevice, pRD)) { - if (!device_alloc_rx_buf(pDevice,pRD)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR - "%s: can not allocate rx buf\n", pDevice->dev->name); - break; - } - } - pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; - pDevice->dev->last_rx = jiffies; - } - - pDevice->pCurrRD[uIdx]=pRD; - - return works; + if (works++ > 15) + break; + if (device_receive_frame(pDevice, pRD)) { + if (!device_alloc_rx_buf(pDevice, pRD)) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR + "%s: can not allocate rx buf\n", pDevice->dev->name); + break; + } + } + pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; + pDevice->dev->last_rx = jiffies; + } + + pDevice->pCurrRD[uIdx] = pRD; + + return works; } static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) { - PDEVICE_RD_INFO pRDInfo=pRD->pRDInfo; + PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo; - pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); #ifdef PLICE_DEBUG //printk("device_alloc_rx_buf:skb is %x\n",pRDInfo->skb); #endif - if (pRDInfo->skb==NULL) - return false; - ASSERT(pRDInfo->skb); - pRDInfo->skb->dev = pDevice->dev; - pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb), - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); - *((unsigned int *) &(pRD->m_rd0RD0)) = 0; /* FIX cast */ - - pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz); - pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; - pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz); - pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma); - - return true; + if (pRDInfo->skb == NULL) + return false; + ASSERT(pRDInfo->skb); + pRDInfo->skb->dev = pDevice->dev; + pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb), + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */ + + pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz); + pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; + pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz); + pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma); + + return true; } bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) { - pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - if (pDeF->skb == NULL) - return false; - ASSERT(pDeF->skb); - pDeF->skb->dev = pDevice->dev; + pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + if (pDeF->skb == NULL) + return false; + ASSERT(pDeF->skb); + pDeF->skb->dev = pDevice->dev; - return true; + return true; } static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) { - PSTxDesc pTD; - bool bFull=false; - int works = 0; - unsigned char byTsr0; - unsigned char byTsr1; - unsigned int uFrameSize, uFIFOHeaderSize; - PSTxBufHead pTxBufHead; - struct net_device_stats* pStats = &pDevice->stats; - struct sk_buff* skb; - unsigned int uNodeIndex; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] >0; pTD = pTD->next) { - - if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC) - break; - if (works++>15) - break; - - byTsr0 = pTD->m_td0TD0.byTSR0; - byTsr1 = pTD->m_td0TD0.byTSR1; - - //Only the status of first TD in the chain is correct - if (pTD->m_td1TD1.byTCR & TCR_STP) { - - if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { - uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength; - uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize; - pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf); - // Update the statistics based on the Transmit status - // now, we DONT check TSR0_CDH - - STAvUpdateTDStatCounter(&pDevice->scStatistic, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize), - uFrameSize, uIdx); - - - BSSvUpdateNodeTxCounter(pDevice, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf), - uFIFOHeaderSize - ); - - if ( !(byTsr1 & TSR1_TERR)) { - if (byTsr0 != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); - } - if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) { - pDevice->s802_11Counter.TransmittedFragmentCount ++; - } - pStats->tx_packets++; - pStats->tx_bytes += pTD->pTDInfo->skb->len; - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); - pStats->tx_errors++; - pStats->tx_dropped++; - } - } - - if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { - if (pDevice->bEnableHostapd) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n"); - skb = pTD->pTDInfo->skb; - skb->dev = pDevice->apdev; - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - //skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - } - } - - if (byTsr1 & TSR1_TERR) { - if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); - } - -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n", + PSTxDesc pTD; + bool bFull = false; + int works = 0; + unsigned char byTsr0; + unsigned char byTsr1; + unsigned int uFrameSize, uFIFOHeaderSize; + PSTxBufHead pTxBufHead; + struct net_device_stats *pStats = &pDevice->stats; + struct sk_buff *skb; + unsigned int uNodeIndex; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) { + + if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC) + break; + if (works++ > 15) + break; + + byTsr0 = pTD->m_td0TD0.byTSR0; + byTsr1 = pTD->m_td0TD0.byTSR1; + + //Only the status of first TD in the chain is correct + if (pTD->m_td1TD1.byTCR & TCR_STP) { + + if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { + uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength; + uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize; + pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf); + // Update the statistics based on the Transmit status + // now, we DONT check TSR0_CDH + + STAvUpdateTDStatCounter(&pDevice->scStatistic, + byTsr0, byTsr1, + (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize), + uFrameSize, uIdx); + + + BSSvUpdateNodeTxCounter(pDevice, + byTsr0, byTsr1, + (unsigned char *)(pTD->pTDInfo->buf), + uFIFOHeaderSize + ); + + if (!(byTsr1 & TSR1_TERR)) { + if (byTsr0 != 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n", + (int)uIdx, byTsr1, byTsr0); + } + if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) { + pDevice->s802_11Counter.TransmittedFragmentCount++; + } + pStats->tx_packets++; + pStats->tx_bytes += pTD->pTDInfo->skb->len; + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n", + (int)uIdx, byTsr1, byTsr0); + pStats->tx_errors++; + pStats->tx_dropped++; + } + } + + if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { + if (pDevice->bEnableHostapd) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n"); + skb = pTD->pTDInfo->skb; + skb->dev = pDevice->apdev; + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_OTHERHOST; + //skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); + } + } + + if (byTsr1 & TSR1_TERR) { + if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n", + (int)uIdx, byTsr1, byTsr0); + } + +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n", // (int)uIdx, byTsr1, byTsr0); - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && - (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) { - unsigned short wAID; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - - skb = pTD->pTDInfo->skb; - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n" - ,(int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt); - pStats->tx_errors--; - pStats->tx_dropped--; - } - } - } - } - device_free_tx_buf(pDevice,pTD); - pDevice->iTDUsed[uIdx]--; - } - } - - - if (uIdx == TYPE_AC0DMA) { - // RESERV_AC0DMA reserved for relay - - if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) { - bFull = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]); - } - if (netif_queue_stopped(pDevice->dev) && (bFull==false)){ - netif_wake_queue(pDevice->dev); - } - } - - - pDevice->apTailTD[uIdx] = pTD; - - return works; + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && + (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) { + unsigned short wAID; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + + skb = pTD->pTDInfo->skb; + if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { + if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { + skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); + pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; + // set tx map + wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; + pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; + pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n" + , (int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt); + pStats->tx_errors--; + pStats->tx_dropped--; + } + } + } + } + device_free_tx_buf(pDevice, pTD); + pDevice->iTDUsed[uIdx]--; + } + } + + + if (uIdx == TYPE_AC0DMA) { + // RESERV_AC0DMA reserved for relay + + if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) { + bFull = true; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]); + } + if (netif_queue_stopped(pDevice->dev) && (bFull == false)) { + netif_wake_queue(pDevice->dev); + } + } + + + pDevice->apTailTD[uIdx] = pTD; + + return works; } static void device_error(PSDevice pDevice, unsigned short status) { - if (status & ISR_FETALERR) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR - "%s: Hardware fatal error.\n", - pDevice->dev->name); - netif_stop_queue(pDevice->dev); - del_timer(&pDevice->sTimerCommand); - del_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - return; - } + if (status & ISR_FETALERR) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR + "%s: Hardware fatal error.\n", + pDevice->dev->name); + netif_stop_queue(pDevice->dev); + del_timer(&pDevice->sTimerCommand); + del_timer(&(pDevice->pMgmt->sTimerSecondCallback)); + pDevice->bCmdRunning = false; + MACbShutdown(pDevice->PortOffset); + return; + } } static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) { - PDEVICE_TD_INFO pTDInfo=pDesc->pTDInfo; - struct sk_buff* skb=pTDInfo->skb; + PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo; + struct sk_buff *skb = pTDInfo->skb; - // pre-allocated buf_dma can't be unmapped. - if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) { - pci_unmap_single(pDevice->pcid,pTDInfo->skb_dma,skb->len, - PCI_DMA_TODEVICE); - } + // pre-allocated buf_dma can't be unmapped. + if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) { + pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len, + PCI_DMA_TODEVICE); + } - if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) - dev_kfree_skb_irq(skb); + if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) + dev_kfree_skb_irq(skb); - pTDInfo->skb_dma = 0; - pTDInfo->skb = 0; - pTDInfo->byFlags = 0; + pTDInfo->skb_dma = 0; + pTDInfo->skb = 0; + pTDInfo->byFlags = 0; } @@ -1822,11 +1822,11 @@ void InitRxManagementQueue(PSDevice pDevice) //PLICE_DEBUG -> int MlmeThread( - void * Context) + void *Context) { PSDevice pDevice = (PSDevice) Context; PSRxMgmtPacket pRxMgmtPacket; - // int i ; + // int i; //complete(&pDevice->notify); //printk("Enter MngWorkItem,Queue packet num is %d\n",pDevice->rxManeQueue.packet_num); @@ -1836,31 +1836,31 @@ int MlmeThread( while (1) { - //printk("DDDD\n"); - //down(&pDevice->mlme_semaphore); - // pRxMgmtPacket = DeQueue(pDevice); + //printk("DDDD\n"); + //down(&pDevice->mlme_semaphore); + // pRxMgmtPacket = DeQueue(pDevice); #if 1 spin_lock_irq(&pDevice->lock); - while(pDevice->rxManeQueue.packet_num != 0) - { - pRxMgmtPacket = DeQueue(pDevice); - //pDevice; - //DequeueManageObject(pDevice->FirstRecvMngList, pDevice->LastRecvMngList); + while (pDevice->rxManeQueue.packet_num != 0) + { + pRxMgmtPacket = DeQueue(pDevice); + //pDevice; + //DequeueManageObject(pDevice->FirstRecvMngList, pDevice->LastRecvMngList); vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket); //printk("packet_num is %d\n",pDevice->rxManeQueue.packet_num); - } + } spin_unlock_irq(&pDevice->lock); if (mlme_kill == 0) - break; + break; //udelay(200); #endif - //printk("Before schedule thread jiffies is %x\n",jiffies); - schedule(); - //printk("after schedule thread jiffies is %x\n",jiffies); - if (mlme_kill == 0) - break; - //printk("i is %d\n",i); + //printk("Before schedule thread jiffies is %x\n",jiffies); + schedule(); + //printk("after schedule thread jiffies is %x\n",jiffies); + if (mlme_kill == 0) + break; + //printk("i is %d\n",i); } #endif @@ -1871,52 +1871,52 @@ int MlmeThread( static int device_open(struct net_device *dev) { - PSDevice pDevice=(PSDevice) netdev_priv(dev); - int i; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + int i; #ifdef WPA_SM_Transtatus - extern SWPAResult wpa_Result; + extern SWPAResult wpa_Result; #endif - pDevice->rx_buf_sz = PKT_BUF_SZ; - if (!device_init_rings(pDevice)) { - return -ENOMEM; - } + pDevice->rx_buf_sz = PKT_BUF_SZ; + if (!device_init_rings(pDevice)) { + return -ENOMEM; + } //2008-5-13 by chester - i=request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev); - if (i) - return i; + i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev); + if (i) + return i; //printk("DEBUG1\n"); #ifdef WPA_SM_Transtatus - memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname)); - wpa_Result.proto = 0; - wpa_Result.key_mgmt = 0; - wpa_Result.eap_type = 0; - wpa_Result.authenticated = false; - pDevice->fWPA_Authened = false; + memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); + wpa_Result.proto = 0; + wpa_Result.key_mgmt = 0; + wpa_Result.eap_type = 0; + wpa_Result.authenticated = false; + pDevice->fWPA_Authened = false; #endif -DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n"); -device_init_rd0_ring(pDevice); - device_init_rd1_ring(pDevice); - device_init_defrag_cb(pDevice); - device_init_td0_ring(pDevice); - device_init_td1_ring(pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n"); + device_init_rd0_ring(pDevice); + device_init_rd1_ring(pDevice); + device_init_defrag_cb(pDevice); + device_init_td0_ring(pDevice); + device_init_td1_ring(pDevice); // VNTWIFIvSet11h(pDevice->pMgmt, pDevice->b11hEnable); - if (pDevice->bDiversityRegCtlON) { - device_init_diversity_timer(pDevice); - } - vMgrObjectInit(pDevice); - vMgrTimerInit(pDevice); + if (pDevice->bDiversityRegCtlON) { + device_init_diversity_timer(pDevice); + } + vMgrObjectInit(pDevice); + vMgrTimerInit(pDevice); //PLICE_DEBUG-> #ifdef TASK_LET - tasklet_init (&pDevice->RxMngWorkItem,(void *)MngWorkItem,(unsigned long )pDevice); + tasklet_init(&pDevice->RxMngWorkItem, (void *)MngWorkItem, (unsigned long)pDevice); #endif #ifdef THREAD InitRxManagementQueue(pDevice); mlme_kill = 0; - mlme_task = kthread_run(MlmeThread,(void *) pDevice, "MLME"); + mlme_task = kthread_run(MlmeThread, (void *)pDevice, "MLME"); if (IS_ERR(mlme_task)) { printk("thread create fail\n"); return -1; @@ -1934,1155 +1934,1155 @@ device_init_rd0_ring(pDevice); - // if (( SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL)&0x06)==0x04) - // return -ENOMEM; -DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n"); + // if ((SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL)&0x06)==0x04) + // return -ENOMEM; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n"); device_init_registers(pDevice, DEVICE_INIT_COLD); - MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); - device_set_multi(pDevice->dev); + MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); + memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); + device_set_multi(pDevice->dev); - // Init for Key Management - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - add_timer(&(pDevice->pMgmt->sTimerSecondCallback)); + // Init for Key Management + KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); + add_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT /* - pDevice->bwextstep0 = false; - pDevice->bwextstep1 = false; - pDevice->bwextstep2 = false; - pDevice->bwextstep3 = false; - */ - pDevice->bwextcount=0; - pDevice->bWPASuppWextEnabled = false; + pDevice->bwextstep0 = false; + pDevice->bwextstep1 = false; + pDevice->bwextstep2 = false; + pDevice->bwextstep3 = false; + */ + pDevice->bwextcount = 0; + pDevice->bWPASuppWextEnabled = false; #endif - pDevice->byReAssocCount = 0; - pDevice->bWPADEVUp = false; - // Patch: if WEP key already set by iwconfig but device not yet open - if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) { - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(pDevice->byKeyIndex | (1 << 31)), - pDevice->uKeyLength, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID - ); - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } + pDevice->byReAssocCount = 0; + pDevice->bWPADEVUp = false; + // Patch: if WEP key already set by iwconfig but device not yet open + if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) { + KeybSetDefaultKey(&(pDevice->sKey), + (unsigned long)(pDevice->byKeyIndex | (1 << 31)), + pDevice->uKeyLength, + NULL, + pDevice->abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID + ); + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + } //printk("DEBUG2\n"); -DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n"); MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); + if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { + bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); } else { - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - } - pDevice->flags |=DEVICE_FLAGS_OPENED; + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); + } + pDevice->flags |= DEVICE_FLAGS_OPENED; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n"); - return 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n"); + return 0; } static int device_close(struct net_device *dev) { - PSDevice pDevice=(PSDevice) netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; - //PLICE_DEBUG-> + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = pDevice->pMgmt; + //PLICE_DEBUG-> #ifdef THREAD mlme_kill = 0; #endif //PLICE_DEBUG<- //2007-1121-02by EinsnLiu - if (pDevice->bLinkPass) { - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - mdelay(30); - } + if (pDevice->bLinkPass) { + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + mdelay(30); + } #ifdef TxInSleep - del_timer(&pDevice->sTimerTxData); + del_timer(&pDevice->sTimerTxData); #endif - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - if (pDevice->bDiversityRegCtlON) { - del_timer(&pDevice->TimerSQ3Tmax1); - del_timer(&pDevice->TimerSQ3Tmax2); - del_timer(&pDevice->TimerSQ3Tmax3); - } + del_timer(&pDevice->sTimerCommand); + del_timer(&pMgmt->sTimerSecondCallback); + if (pDevice->bDiversityRegCtlON) { + del_timer(&pDevice->TimerSQ3Tmax1); + del_timer(&pDevice->TimerSQ3Tmax2); + del_timer(&pDevice->TimerSQ3Tmax3); + } #ifdef TASK_LET tasklet_kill(&pDevice->RxMngWorkItem); #endif - netif_stop_queue(dev); - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACbSoftwareReset(pDevice->PortOffset); - CARDbRadioPowerOff(pDevice); - - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - device_free_td0_ring(pDevice); - device_free_td1_ring(pDevice); - device_free_rd0_ring(pDevice); - device_free_rd1_ring(pDevice); - device_free_frag_buf(pDevice); - device_free_rings(pDevice); - BSSvClearNodeDBTable(pDevice, 0); - free_irq(dev->irq, dev); - pDevice->flags &=(~DEVICE_FLAGS_OPENED); + netif_stop_queue(dev); + pDevice->bCmdRunning = false; + MACbShutdown(pDevice->PortOffset); + MACbSoftwareReset(pDevice->PortOffset); + CARDbRadioPowerOff(pDevice); + + pDevice->bLinkPass = false; + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + device_free_td0_ring(pDevice); + device_free_td1_ring(pDevice); + device_free_rd0_ring(pDevice); + device_free_rd1_ring(pDevice); + device_free_frag_buf(pDevice); + device_free_rings(pDevice); + BSSvClearNodeDBTable(pDevice, 0); + free_irq(dev->irq, dev); + pDevice->flags &= (~DEVICE_FLAGS_OPENED); //2008-0714-01by chester -device_release_WPADEV(pDevice); + device_release_WPADEV(pDevice); //PLICE_DEBUG-> //tasklet_kill(&pDevice->RxMngWorkItem); //PLICE_DEBUG<- - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n"); - return 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n"); + return 0; } static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) { - PSDevice pDevice=netdev_priv(dev); - unsigned char *pbMPDU; - unsigned int cbMPDULen = 0; + PSDevice pDevice = netdev_priv(dev); + unsigned char *pbMPDU; + unsigned int cbMPDULen = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n"); - spin_lock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n"); + spin_lock_irq(&pDevice->lock); - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } + if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n"); + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } - if (pDevice->bStopTx0Pkt == true) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } + if (pDevice->bStopTx0Pkt == true) { + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } - cbMPDULen = skb->len; - pbMPDU = skb->data; + cbMPDULen = skb->len; + pbMPDU = skb->data; - vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen); + vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irq(&pDevice->lock); - return 0; + return 0; } bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex) { - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum; - unsigned char byPktType; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; - unsigned int ii; - SKeyItem STempKey; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSTxDesc pHeadTD, pLastTD; + unsigned int cbFrameBodySize; + unsigned int uMACfragNum; + unsigned char byPktType; + bool bNeedEncryption = false; + PSKeyItem pTransmitKey = NULL; + unsigned int cbHeaderSize; + unsigned int ii; + SKeyItem STempKey; // unsigned char byKeyIndex = 0; - if (pDevice->bStopTx0Pkt == true) { - dev_kfree_skb_irq(skb); - return false; - } - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - dev_kfree_skb_irq(skb); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n"); - return false; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n"); - return false; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { - cbFrameBodySize += 8; - } - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if ( uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) { - dev_kfree_skb_irq(skb); - return false; - } - byPktType = (unsigned char)pDevice->byPacketType; - - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) { - pDevice->wCurrentRate = RATE_11M; - } else { - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } - else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - //preamble type - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { - pDevice->byPreambleType = pDevice->byShortPreamble; - } - else { - pDevice->byPreambleType = PREAMBLE_LONG; - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate); - - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode == true) { - byPktType = PK_TYPE_11GB; - } else { - byPktType = PK_TYPE_11GA; - } - } - - if (pDevice->bEncryptionEnable == true) - bNeedEncryption = true; - - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_TXDMA0, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; - - pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD; - - MACvTransmit0(pDevice->PortOffset); - - - return true; -} + if (pDevice->bStopTx0Pkt == true) { + dev_kfree_skb_irq(skb); + return false; + } -//TYPE_AC0DMA data tx -static int device_xmit(struct sk_buff *skb, struct net_device *dev) { - PSDevice pDevice=netdev_priv(dev); - - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int uNodeIndex = 0; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - unsigned int uMACfragNum = 1; - unsigned int cbFrameBodySize; - unsigned char byPktType; - unsigned int cbHeaderSize; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - SKeyItem STempKey; - unsigned int ii; - bool bTKIP_UseGTK = false; - bool bNeedDeAuth = false; - unsigned char *pbyBSSID; - bool bNodeExist = false; - - - - spin_lock_irq(&pDevice->lock); - if (pDevice->bLinkPass == false) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pDevice->bStopDataPkt) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - if (is_multicast_ether_addr((unsigned char *)(skb->data))) { - uNodeIndex = 0; - bNodeExist = true; - if (pMgmt->sNodeDBTable[0].bPSEnable) { - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb); - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - spin_unlock_irq(&pDevice->lock); - return 0; - } -}else { - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n", - (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { - pDevice->byPreambleType = pDevice->byShortPreamble; - - }else { - pDevice->byPreambleType = PREAMBLE_LONG; - } - bNodeExist = true; - - } - } - - if (bNodeExist == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { - cbFrameBodySize += 8; - } - - - if (pDevice->bEncryptionEnable == true) { - bNeedEncryption = true; - // get Transmit key - do { - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); - break; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n"); - break; - } - }else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - - pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n"); - for (ii = 0; ii< 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n"); - - // get pairwise key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) - break; - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); - } - else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); - } else { - bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); - } - } while(false); - } - - if (pDevice->bEnableHostWEP) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex); - if (pDevice->bEncryptionEnable == true) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - } - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pTransmitKey != NULL) { - if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) && - (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) { - uMACfragNum = 1; //WEP256 doesn't support fragment - } - } - - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { -#ifdef PLICE_DEBUG - printk("Fix Rate: PhyType is %d,ConnectionRate is %d\n",pDevice->eCurrentPHYType,pDevice->uConnectionRate); -#endif + if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { + dev_kfree_skb_irq(skb); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n"); + return false; + } - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) { - pDevice->wCurrentRate = RATE_11M; - } else { - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - - } - } - pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - else { - //auto rate - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - pDevice->wCurrentRate = RATE_1M; - pDevice->byACKRate = RATE_1M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - pDevice->wCurrentRate = RATE_6M; - pDevice->byACKRate = RATE_6M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - } - else { - VNTWIFIvGetTxRate( pDevice->pMgmt, - pDevice->sTxEthHeader.abyDstAddr, - &(pDevice->wCurrentRate), - &(pDevice->byACKRate), - &(pDevice->byTopCCKBasicRate), - &(pDevice->byTopOFDMBasicRate)); - - - } - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (pDevice->uAssocCount == 0) { + dev_kfree_skb_irq(skb); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n"); + return false; + } + } -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate); + pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0]; - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode == true) { - byPktType = PK_TYPE_11GB; - } else { - byPktType = PK_TYPE_11GA; - } - } + pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); -//#ifdef PLICE_DEBUG -// printk("FIX RATE:CurrentRate is %d"); -//#endif + memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); + cbFrameBodySize = skb->len - ETH_HLEN; - if (bNeedEncryption == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); - if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { - bNeedEncryption = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (pTransmitKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n"); - } - else { - if (bTKIP_UseGTK == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } - - if (pDevice->byCntMeasure == 2) { - bNeedDeAuth = true; - pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++; - } - - if (pDevice->bEnableHostWEP) { - if ((uNodeIndex != 0) && - (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } - else { - if (pTransmitKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - } + // 802.1H + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { + cbFrameBodySize += 8; + } + uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); + if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) { + dev_kfree_skb_irq(skb); + return false; + } + byPktType = (unsigned char)pDevice->byPacketType; -#ifdef PLICE_DEBUG - //if (skb->len == 98) - //{ - // printk("ping:len is %d\n"); - //} -#endif - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_AC0DMA, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC; - wmb(); - if (ii == uMACfragNum - 1) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; -#ifdef TxInSleep - pDevice->nTxDataTimeCout=0; //2008-8-21 chester for send null packet - #endif - if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) { - netif_stop_queue(dev); - } - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; -//#ifdef PLICE_DEBUG - if (pDevice->bFixRate) - { - printk("FixRate:Rate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr); + if (pDevice->bFixRate) { + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + if (pDevice->uConnectionRate >= RATE_11M) { + pDevice->wCurrentRate = RATE_11M; + } else { + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } + } else { + if (pDevice->uConnectionRate >= RATE_54M) + pDevice->wCurrentRate = RATE_54M; + else + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } } - else - { - //printk("Auto Rate:Rate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr); + else { + pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; } -//#endif - -{ - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication - unsigned char Descriptor_type; - unsigned short Key_info; -bool bTxeapol_key = false; - Protocol_Version = skb->data[ETH_HLEN]; - Packet_Type = skb->data[ETH_HLEN+1]; - Descriptor_type = skb->data[ETH_HLEN+1+1+2]; - Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if(((Protocol_Version==1) ||(Protocol_Version==2)) && - (Packet_Type==3)) { //802.1x OR eapol-key challenge frame transfer - bTxeapol_key = true; - if((Descriptor_type==254)||(Descriptor_type==2)) { //WPA or RSN - if(!(Key_info & BIT3) && //group-key challenge - (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key - pDevice->fWPA_Authened = true; - if(Descriptor_type==254) - printk("WPA "); - else - printk("WPA2 "); - printk("Authentication completed!!\n"); - } - } - } - } -} - - MACvTransmitAC0(pDevice->PortOffset); -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD); - dev->trans_start = jiffies; + //preamble type + if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { + pDevice->byPreambleType = pDevice->byShortPreamble; + } + else { + pDevice->byPreambleType = PREAMBLE_LONG; + } - spin_unlock_irq(&pDevice->lock); - return 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate); -} -static irqreturn_t device_intr(int irq, void *dev_instance) { - struct net_device* dev=dev_instance; - PSDevice pDevice=(PSDevice) netdev_priv(dev); - - int max_count=0; - unsigned long dwMIBCounter=0; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char byOrgPageSel=0; - int handled = 0; - unsigned char byData = 0; - int ii= 0; -// unsigned char byRSSI; + if (pDevice->wCurrentRate <= RATE_11M) { + byPktType = PK_TYPE_11B; + } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + byPktType = PK_TYPE_11A; + } else { + if (pDevice->bProtectMode == true) { + byPktType = PK_TYPE_11GB; + } else { + byPktType = PK_TYPE_11GA; + } + } + if (pDevice->bEncryptionEnable == true) + bNeedEncryption = true; + + if (pDevice->bEnableHostWEP) { + pTransmitKey = &STempKey; + pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; + pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; + pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; + pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; + pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; + memcpy(pTransmitKey->abyKey, + &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], + pTransmitKey->uKeyLength + ); + } + vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, + cbFrameBodySize, TYPE_TXDMA0, pHeadTD, + &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, + &uMACfragNum, + &cbHeaderSize + ); + + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { + // Disable PS + MACbPSWakeup(pDevice->PortOffset); + } - MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); - - if (pDevice->dwIsr == 0) - return IRQ_RETVAL(handled); - - if (pDevice->dwIsr == 0xffffffff) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n"); - return IRQ_RETVAL(handled); - } - /* - // 2008-05-21 by Richardtai, we can't read RSSI here, because no packet bound with RSSI - - if ((pDevice->dwIsr & ISR_RXDMA0) && - (pDevice->byLocalID != REV_ID_VT3253_B0) && - (pDevice->bBSSIDFilter == true)) { - // update RSSI - //BBbReadEmbedded(pDevice->PortOffset, 0x3E, &byRSSI); - //pDevice->uCurrRSSI = byRSSI; - } - */ - - handled = 1; - MACvIntDisable(pDevice->PortOffset); - spin_lock_irq(&pDevice->lock); - - //Make sure current page is 0 - VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel); - if (byOrgPageSel == 1) { - MACvSelectPage0(pDevice->PortOffset); - } - else - byOrgPageSel = 0; - - MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter); - // TBD.... - // Must do this after doing rx/tx, cause ISR bit is slow - // than RD/TD write back - // update ISR counter - STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter); - while (pDevice->dwIsr != 0) { - - STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); - MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); - - if (pDevice->dwIsr & ISR_FETALERR){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n"); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); - device_error(pDevice, pDevice->dwIsr); - } - - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - - if (pDevice->dwIsr & ISR_MEASURESTART) { - // 802.11h measure start - pDevice->byOrgChannel = pDevice->byCurrentCh; - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR)); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR)); - MACvSelectPage1(pDevice->PortOffset); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0)); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4)); - MACvSelectPage0(pDevice->PortOffset); - //xxxx - // WCMDbFlushCommandQueue(pDevice->pMgmt, true); - if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) { - pDevice->bMeasureInProgress = true; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byBasicMap = 0; - pDevice->byCCAFraction = 0; - for(ii=0;ii<8;ii++) { - pDevice->dwRPIs[ii] = 0; - } - } else { - // can not measure because set channel fail - // WCMDbResetCommandQueue(pDevice->pMgmt); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - } - if (pDevice->dwIsr & ISR_MEASUREEND) { - // 802.11h measure end - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData); - pDevice->byBasicMap |= (byData >> 4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - // WCMDbResetCommandQueue(pDevice->pMgmt); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - if (byData & MSRCTL_FINISH) { - // measure success - s_vCompleteCurrentMeasure(pDevice, 0); - } else { - // can not measure because not ready before end of measure time - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE); - } - } - if (pDevice->dwIsr & ISR_QUIETSTART) { - do { - ; - } while (CARDbStartQuiet(pDevice) == false); - } - } - - if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->bEnableFirstQuiet == true) { - pDevice->byQuietStartCount--; - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - MACvSelectPage0(pDevice->PortOffset); - } - } - if ((pDevice->bChannelSwitch == true) && - (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - - } - } - if (pDevice->eOPMode == OP_MODE_ADHOC) { - //pDevice->bBeaconSent = false; - } else { - if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) { - long ldBm; - - RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm); - for (ii=0;iildBmThreshold[ii]) { - pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; - break; - } - } - if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { - pDevice->uBBVGADiffCount++; - if (pDevice->uBBVGADiffCount == 1) { - // first VGA diff gain - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); - } - if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); - } - } else { - pDevice->uBBVGADiffCount = 1; - } - } - } - - pDevice->bBeaconSent = false; - if (pDevice->bEnablePSMode) { - PSbIsNextTBTTWakeUp((void *)pDevice); - } - - if ((pDevice->eOPMode == OP_MODE_AP) || - (pDevice->eOPMode == OP_MODE_ADHOC)) { - - MACvOneShotTimer1MicroSec(pDevice->PortOffset, - (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10); - } - - if (pDevice->eOPMode == OP_MODE_ADHOC && pDevice->pMgmt->wCurrATIMWindow > 0) { - // todo adhoc PS mode - } - - } - - if (pDevice->dwIsr & ISR_BNTX) { - - if (pDevice->eOPMode == OP_MODE_ADHOC) { - pDevice->bIsBeaconBufReadySet = false; - pDevice->cbBeaconBufReadySetCnt = 0; - } - - if (pDevice->eOPMode == OP_MODE_AP) { - if(pMgmt->byDTIMCount > 0) { - pMgmt->byDTIMCount --; - pMgmt->sNodeDBTable[0].bRxPSPoll = false; - } - else { - if(pMgmt->byDTIMCount == 0) { - // check if mutltcast tx bufferring - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - } - } - } - pDevice->bBeaconSent = true; - - if (pDevice->bChannelSwitch == true) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - //VNTWIFIbSendBeacon(pDevice->pMgmt); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - } - } - - } - - if (pDevice->dwIsr & ISR_RXDMA0) { - max_count += device_rx_srv(pDevice, TYPE_RXDMA0); - } - if (pDevice->dwIsr & ISR_RXDMA1) { - max_count += device_rx_srv(pDevice, TYPE_RXDMA1); - } - if (pDevice->dwIsr & ISR_TXDMA0){ - max_count += device_tx_srv(pDevice, TYPE_TXDMA0); - } - if (pDevice->dwIsr & ISR_AC0DMA){ - max_count += device_tx_srv(pDevice, TYPE_AC0DMA); - } - if (pDevice->dwIsr & ISR_SOFTTIMER) { - - } - if (pDevice->dwIsr & ISR_SOFTTIMER1) { - if (pDevice->eOPMode == OP_MODE_AP) { - if (pDevice->bShortSlotTime) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - else - pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)); - } - bMgrPrepareBeaconToSend(pDevice, pMgmt); - pDevice->byCntMeasure = 0; - } - - MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); - - MACvReceive0(pDevice->PortOffset); - MACvReceive1(pDevice->PortOffset); - - if (max_count>pDevice->sOpts.int_works) - break; - } - - if (byOrgPageSel == 1) { - MACvSelectPage1(pDevice->PortOffset); - } - - spin_unlock_irq(&pDevice->lock); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - - return IRQ_RETVAL(handled); -} + pDevice->bPWBitOn = false; + + pLastTD = pHeadTD; + for (ii = 0; ii < uMACfragNum; ii++) { + // Poll Transmit the adapter + wmb(); + pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); + if (ii == (uMACfragNum - 1)) + pLastTD = pHeadTD; + pHeadTD = pHeadTD->next; + } + // Save the information needed by the tx interrupt handler + // to complete the Send request + pLastTD->pTDInfo->skb = skb; + pLastTD->pTDInfo->byFlags = 0; + pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; -static unsigned const ethernet_polynomial = 0x04c11db7U; -static inline u32 ether_crc(int length, unsigned char *data) -{ - int crc = -1; - - while(--length >= 0) { - unsigned char current_octet = *data++; - int bit; - for (bit = 0; bit < 8; bit++, current_octet >>= 1) { - crc = (crc << 1) ^ - ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); - } - } - return crc; -} + pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD; -//2008-8-4 by chester -static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source) -{ - unsigned char buf1[100]; - int source_len = strlen(source); + MACvTransmit0(pDevice->PortOffset); - memset(buf1,0,100); - strcat(buf1, string); - strcat(buf1, "="); - source+=strlen(buf1); - memcpy(dest,source,source_len-strlen(buf1)); - return true; + return true; } -int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter) { - unsigned char *config_path = CONFIG_PATH; - unsigned char *buffer = NULL; - unsigned char tmpbuffer[20]; - struct file *filp=NULL; - mm_segment_t old_fs = get_fs(); - //int oldfsuid=0,oldfsgid=0; - int result=0; - - set_fs (KERNEL_DS); - - /* Can't do this anymore, so we rely on correct filesystem permissions: - //Make sure a caller can read or write power as root - oldfsuid=current->cred->fsuid; - oldfsgid=current->cred->fsgid; - current->cred->fsuid = 0; - current->cred->fsgid = 0; - */ - - //open file - filp = filp_open(config_path, O_RDWR, 0); - if (IS_ERR(filp)) { - printk("Config_FileOperation:open file fail?\n"); - result=-1; - goto error2; - } - - if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) { - printk("file %s cann't readable or writable?\n",config_path); - result = -1; - goto error1; - } - -buffer = kmalloc(1024, GFP_KERNEL); -if(buffer==NULL) { - printk("allocate mem for file fail?\n"); - result = -1; - goto error1; -} +//TYPE_AC0DMA data tx +static int device_xmit(struct sk_buff *skb, struct net_device *dev) { + PSDevice pDevice = netdev_priv(dev); + + PSMgmtObject pMgmt = pDevice->pMgmt; + PSTxDesc pHeadTD, pLastTD; + unsigned int uNodeIndex = 0; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + unsigned short wAID; + unsigned int uMACfragNum = 1; + unsigned int cbFrameBodySize; + unsigned char byPktType; + unsigned int cbHeaderSize; + bool bNeedEncryption = false; + PSKeyItem pTransmitKey = NULL; + SKeyItem STempKey; + unsigned int ii; + bool bTKIP_UseGTK = false; + bool bNeedDeAuth = false; + unsigned char *pbyBSSID; + bool bNodeExist = false; + + + + spin_lock_irq(&pDevice->lock); + if (pDevice->bLinkPass == false) { + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } -if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) { - printk("read file error?\n"); - result = -1; - goto error1; -} + if (pDevice->bStopDataPkt) { + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } -if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) { - printk("get parameter error?\n"); - result = -1; - goto error1; -} -if(memcmp(tmpbuffer,"USA",3)==0) { - result=ZoneType_USA; + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (pDevice->uAssocCount == 0) { + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } + if (is_multicast_ether_addr((unsigned char *)(skb->data))) { + uNodeIndex = 0; + bNodeExist = true; + if (pMgmt->sNodeDBTable[0].bPSEnable) { + skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb); + pMgmt->sNodeDBTable[0].wEnQueueCnt++; + // set tx map + pMgmt->abyPSTxMap[0] |= byMask[0]; + spin_unlock_irq(&pDevice->lock); + return 0; + } + } else { + if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { + if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { + skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); + pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; + // set tx map + wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; + pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n", + (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); + spin_unlock_irq(&pDevice->lock); + return 0; + } + + if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { + pDevice->byPreambleType = pDevice->byShortPreamble; + + } else { + pDevice->byPreambleType = PREAMBLE_LONG; + } + bNodeExist = true; + + } + } + + if (bNodeExist == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB \n"); + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } + } + + pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; + + pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); + + + memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); + cbFrameBodySize = skb->len - ETH_HLEN; + // 802.1H + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { + cbFrameBodySize += 8; + } + + + if (pDevice->bEncryptionEnable == true) { + bNeedEncryption = true; + // get Transmit key + do { + if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + pbyBSSID = pDevice->abyBSSID; + // get pairwise key + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { + // get group key + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { + bTKIP_UseGTK = true; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + break; + } + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get PTK.\n"); + break; + } + } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + + pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key: \n"); + for (ii = 0; ii < 6; ii++) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x \n", *(pbyBSSID+ii)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n"); + + // get pairwise key + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) + break; + } + // get group key + pbyBSSID = pDevice->abyBroadcastAddr; + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { + pTransmitKey = NULL; + if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); + } + else + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); + } else { + bTKIP_UseGTK = true; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + } + } while (false); + } + + if (pDevice->bEnableHostWEP) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex); + if (pDevice->bEncryptionEnable == true) { + pTransmitKey = &STempKey; + pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; + pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; + pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; + pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; + pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; + memcpy(pTransmitKey->abyKey, + &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], + pTransmitKey->uKeyLength + ); + } + } + + uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); + + if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { + DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum); + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } + + if (pTransmitKey != NULL) { + if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) && + (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) { + uMACfragNum = 1; //WEP256 doesn't support fragment + } + } + + byPktType = (unsigned char)pDevice->byPacketType; + + if (pDevice->bFixRate) { +#ifdef PLICE_DEBUG + printk("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate); +#endif + + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + if (pDevice->uConnectionRate >= RATE_11M) { + pDevice->wCurrentRate = RATE_11M; + } else { + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } + } else { + if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && + (pDevice->uConnectionRate <= RATE_6M)) { + pDevice->wCurrentRate = RATE_6M; + } else { + if (pDevice->uConnectionRate >= RATE_54M) + pDevice->wCurrentRate = RATE_54M; + else + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + + } + } + pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate; + pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_6M; + } + else { + //auto rate + if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { + if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { + pDevice->wCurrentRate = RATE_1M; + pDevice->byACKRate = RATE_1M; + pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_6M; + } else { + pDevice->wCurrentRate = RATE_6M; + pDevice->byACKRate = RATE_6M; + pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_6M; + } + } + else { + VNTWIFIvGetTxRate(pDevice->pMgmt, + pDevice->sTxEthHeader.abyDstAddr, + &(pDevice->wCurrentRate), + &(pDevice->byACKRate), + &(pDevice->byTopCCKBasicRate), + &(pDevice->byTopOFDMBasicRate)); + + + } + } + +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate); + + if (pDevice->wCurrentRate <= RATE_11M) { + byPktType = PK_TYPE_11B; + } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + byPktType = PK_TYPE_11A; + } else { + if (pDevice->bProtectMode == true) { + byPktType = PK_TYPE_11GB; + } else { + byPktType = PK_TYPE_11GA; + } + } + +//#ifdef PLICE_DEBUG +// printk("FIX RATE:CurrentRate is %d"); +//#endif + + if (bNeedEncryption == true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); + if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { + bNeedEncryption = false; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); + if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + if (pTransmitKey == NULL) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n"); + } + else { + if (bTKIP_UseGTK == true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + bNeedEncryption = true; + } + } + } + + if (pDevice->byCntMeasure == 2) { + bNeedDeAuth = true; + pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++; + } + + if (pDevice->bEnableHostWEP) { + if ((uNodeIndex != 0) && + (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + bNeedEncryption = true; + } + } + } + else { + if (pTransmitKey == NULL) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return no tx key\n"); + dev_kfree_skb_irq(skb); + spin_unlock_irq(&pDevice->lock); + return 0; + } + } + } + + +#ifdef PLICE_DEBUG + //if (skb->len == 98) + //{ + // printk("ping:len is %d\n"); + //} +#endif + vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, + cbFrameBodySize, TYPE_AC0DMA, pHeadTD, + &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, + &uMACfragNum, + &cbHeaderSize + ); + + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { + // Disable PS + MACbPSWakeup(pDevice->PortOffset); + } + pDevice->bPWBitOn = false; + + pLastTD = pHeadTD; + for (ii = 0; ii < uMACfragNum; ii++) { + // Poll Transmit the adapter + wmb(); + pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); + if (ii == uMACfragNum - 1) + pLastTD = pHeadTD; + pHeadTD = pHeadTD->next; + } + + // Save the information needed by the tx interrupt handler + // to complete the Send request + pLastTD->pTDInfo->skb = skb; + pLastTD->pTDInfo->byFlags = 0; + pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; +#ifdef TxInSleep + pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet +#endif + if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) { + netif_stop_queue(dev); + } + + pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; +//#ifdef PLICE_DEBUG + if (pDevice->bFixRate) + { + printk("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr); + } + else + { + //printk("Auto Rate:Rate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr); + } +//#endif + + { + unsigned char Protocol_Version; //802.1x Authentication + unsigned char Packet_Type; //802.1x Authentication + unsigned char Descriptor_type; + unsigned short Key_info; + bool bTxeapol_key = false; + Protocol_Version = skb->data[ETH_HLEN]; + Packet_Type = skb->data[ETH_HLEN+1]; + Descriptor_type = skb->data[ETH_HLEN+1+1+2]; + Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); + if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { + if (((Protocol_Version == 1) || (Protocol_Version == 2)) && + (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer + bTxeapol_key = true; + if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN + if (!(Key_info & BIT3) && //group-key challenge + (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key + pDevice->fWPA_Authened = true; + if (Descriptor_type == 254) + printk("WPA "); + else + printk("WPA2 "); + printk("Authentication completed!!\n"); + } + } + } + } + } + + MACvTransmitAC0(pDevice->PortOffset); +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD); + + dev->trans_start = jiffies; + + spin_unlock_irq(&pDevice->lock); + return 0; + } -else if(memcmp(tmpbuffer,"JAPAN",5)==0) { - result=ZoneType_Japan; + +static irqreturn_t device_intr(int irq, void *dev_instance) { + struct net_device *dev = dev_instance; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + + int max_count = 0; + unsigned long dwMIBCounter = 0; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned char byOrgPageSel = 0; + int handled = 0; + unsigned char byData = 0; + int ii = 0; +// unsigned char byRSSI; + + + MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); + + if (pDevice->dwIsr == 0) + return IRQ_RETVAL(handled); + + if (pDevice->dwIsr == 0xffffffff) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n"); + return IRQ_RETVAL(handled); + } + /* + // 2008-05-21 by Richardtai, we can't read RSSI here, because no packet bound with RSSI + + if ((pDevice->dwIsr & ISR_RXDMA0) && + (pDevice->byLocalID != REV_ID_VT3253_B0) && + (pDevice->bBSSIDFilter == true)) { + // update RSSI + //BBbReadEmbedded(pDevice->PortOffset, 0x3E, &byRSSI); + //pDevice->uCurrRSSI = byRSSI; + } + */ + + handled = 1; + MACvIntDisable(pDevice->PortOffset); + spin_lock_irq(&pDevice->lock); + + //Make sure current page is 0 + VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel); + if (byOrgPageSel == 1) { + MACvSelectPage0(pDevice->PortOffset); + } + else + byOrgPageSel = 0; + + MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter); + // TBD.... + // Must do this after doing rx/tx, cause ISR bit is slow + // than RD/TD write back + // update ISR counter + STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter); + while (pDevice->dwIsr != 0) { + + STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); + MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); + + if (pDevice->dwIsr & ISR_FETALERR) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n"); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); + device_error(pDevice, pDevice->dwIsr); + } + + if (pDevice->byLocalID > REV_ID_VT3253_B1) { + + if (pDevice->dwIsr & ISR_MEASURESTART) { + // 802.11h measure start + pDevice->byOrgChannel = pDevice->byCurrentCh; + VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR)); + VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR)); + MACvSelectPage1(pDevice->PortOffset); + VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0)); + VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4)); + MACvSelectPage0(pDevice->PortOffset); + //xxxx + // WCMDbFlushCommandQueue(pDevice->pMgmt, true); + if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) { + pDevice->bMeasureInProgress = true; + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY); + MACvSelectPage0(pDevice->PortOffset); + pDevice->byBasicMap = 0; + pDevice->byCCAFraction = 0; + for (ii = 0; ii < 8; ii++) { + pDevice->dwRPIs[ii] = 0; + } + } else { + // can not measure because set channel fail + // WCMDbResetCommandQueue(pDevice->pMgmt); + // clear measure control + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); + s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + } + } + if (pDevice->dwIsr & ISR_MEASUREEND) { + // 802.11h measure end + pDevice->bMeasureInProgress = false; + VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); + VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData); + pDevice->byBasicMap |= (byData >> 4); + VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction); + VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData); + // clear measure control + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); + MACvSelectPage0(pDevice->PortOffset); + set_channel(pDevice, pDevice->byOrgChannel); + // WCMDbResetCommandQueue(pDevice->pMgmt); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + if (byData & MSRCTL_FINISH) { + // measure success + s_vCompleteCurrentMeasure(pDevice, 0); + } else { + // can not measure because not ready before end of measure time + s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE); + } + } + if (pDevice->dwIsr & ISR_QUIETSTART) { + do { + ; + } while (CARDbStartQuiet(pDevice) == false); + } + } + + if (pDevice->dwIsr & ISR_TBTT) { + if (pDevice->bEnableFirstQuiet == true) { + pDevice->byQuietStartCount--; + if (pDevice->byQuietStartCount == 0) { + pDevice->bEnableFirstQuiet = false; + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); + MACvSelectPage0(pDevice->PortOffset); + } + } + if ((pDevice->bChannelSwitch == true) && + (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) { + pDevice->byChannelSwitchCount--; + if (pDevice->byChannelSwitchCount == 0) { + pDevice->bChannelSwitch = false; + set_channel(pDevice, pDevice->byNewChannel); + VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); + + } + } + if (pDevice->eOPMode == OP_MODE_ADHOC) { + //pDevice->bBeaconSent = false; + } else { + if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) { + long ldBm; + + RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm); + for (ii = 0; ii < BB_VGA_LEVEL; ii++) { + if (ldBm < pDevice->ldBmThreshold[ii]) { + pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; + break; + } + } + if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { + pDevice->uBBVGADiffCount++; + if (pDevice->uBBVGADiffCount == 1) { + // first VGA diff gain + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", + (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); + } + if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", + (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); + } + } else { + pDevice->uBBVGADiffCount = 1; + } + } + } + + pDevice->bBeaconSent = false; + if (pDevice->bEnablePSMode) { + PSbIsNextTBTTWakeUp((void *)pDevice); + } + + if ((pDevice->eOPMode == OP_MODE_AP) || + (pDevice->eOPMode == OP_MODE_ADHOC)) { + + MACvOneShotTimer1MicroSec(pDevice->PortOffset, + (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10); + } + + if (pDevice->eOPMode == OP_MODE_ADHOC && pDevice->pMgmt->wCurrATIMWindow > 0) { + // todo adhoc PS mode + } + + } + + if (pDevice->dwIsr & ISR_BNTX) { + + if (pDevice->eOPMode == OP_MODE_ADHOC) { + pDevice->bIsBeaconBufReadySet = false; + pDevice->cbBeaconBufReadySetCnt = 0; + } + + if (pDevice->eOPMode == OP_MODE_AP) { + if (pMgmt->byDTIMCount > 0) { + pMgmt->byDTIMCount--; + pMgmt->sNodeDBTable[0].bRxPSPoll = false; + } + else { + if (pMgmt->byDTIMCount == 0) { + // check if mutltcast tx bufferring + pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; + pMgmt->sNodeDBTable[0].bRxPSPoll = true; + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + } + } + } + pDevice->bBeaconSent = true; + + if (pDevice->bChannelSwitch == true) { + pDevice->byChannelSwitchCount--; + if (pDevice->byChannelSwitchCount == 0) { + pDevice->bChannelSwitch = false; + set_channel(pDevice, pDevice->byNewChannel); + VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); + MACvSelectPage1(pDevice->PortOffset); + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); + MACvSelectPage0(pDevice->PortOffset); + //VNTWIFIbSendBeacon(pDevice->pMgmt); + CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); + } + } + + } + + if (pDevice->dwIsr & ISR_RXDMA0) { + max_count += device_rx_srv(pDevice, TYPE_RXDMA0); + } + if (pDevice->dwIsr & ISR_RXDMA1) { + max_count += device_rx_srv(pDevice, TYPE_RXDMA1); + } + if (pDevice->dwIsr & ISR_TXDMA0) { + max_count += device_tx_srv(pDevice, TYPE_TXDMA0); + } + if (pDevice->dwIsr & ISR_AC0DMA) { + max_count += device_tx_srv(pDevice, TYPE_AC0DMA); + } + if (pDevice->dwIsr & ISR_SOFTTIMER) { + + } + if (pDevice->dwIsr & ISR_SOFTTIMER1) { + if (pDevice->eOPMode == OP_MODE_AP) { + if (pDevice->bShortSlotTime) + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); + else + pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)); + } + bMgrPrepareBeaconToSend(pDevice, pMgmt); + pDevice->byCntMeasure = 0; + } + + MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); + + MACvReceive0(pDevice->PortOffset); + MACvReceive1(pDevice->PortOffset); + + if (max_count > pDevice->sOpts.int_works) + break; + } + + if (byOrgPageSel == 1) { + MACvSelectPage1(pDevice->PortOffset); + } + + spin_unlock_irq(&pDevice->lock); + MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); + + return IRQ_RETVAL(handled); } -else if(memcmp(tmpbuffer,"EUROPE",5)==0) { - result=ZoneType_Europe; + + +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while (--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) { + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + } + return crc; } -else { - result = -1; - printk("Unknown Zonetype[%s]?\n",tmpbuffer); + +//2008-8-4 by chester +static int Config_FileGetParameter(unsigned char *string, + unsigned char *dest, unsigned char *source) +{ + unsigned char buf1[100]; + int source_len = strlen(source); + + memset(buf1, 0, 100); + strcat(buf1, string); + strcat(buf1, "="); + source += strlen(buf1); + + memcpy(dest, source, source_len - strlen(buf1)); + return true; } +int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter) { + unsigned char *config_path = CONFIG_PATH; + unsigned char *buffer = NULL; + unsigned char tmpbuffer[20]; + struct file *filp = NULL; + mm_segment_t old_fs = get_fs(); + //int oldfsuid=0,oldfsgid=0; + int result = 0; + + set_fs(KERNEL_DS); + + /* Can't do this anymore, so we rely on correct filesystem permissions: + //Make sure a caller can read or write power as root + oldfsuid=current->cred->fsuid; + oldfsgid=current->cred->fsgid; + current->cred->fsuid = 0; + current->cred->fsgid = 0; + */ + + //open file + filp = filp_open(config_path, O_RDWR, 0); + if (IS_ERR(filp)) { + printk("Config_FileOperation:open file fail?\n"); + result = -1; + goto error2; + } + + if (!(filp->f_op) || !(filp->f_op->read) || !(filp->f_op->write)) { + printk("file %s cann't readable or writable?\n", config_path); + result = -1; + goto error1; + } + + buffer = kmalloc(1024, GFP_KERNEL); + if (buffer == NULL) { + printk("allocate mem for file fail?\n"); + result = -1; + goto error1; + } + + if (filp->f_op->read(filp, buffer, 1024, &filp->f_pos) < 0) { + printk("read file error?\n"); + result = -1; + goto error1; + } + + if (Config_FileGetParameter("ZONETYPE", tmpbuffer, buffer) != true) { + printk("get parameter error?\n"); + result = -1; + goto error1; + } + + if (memcmp(tmpbuffer, "USA", 3) == 0) { + result = ZoneType_USA; + } + else if (memcmp(tmpbuffer, "JAPAN", 5) == 0) { + result = ZoneType_Japan; + } + else if (memcmp(tmpbuffer, "EUROPE", 5) == 0) { + result = ZoneType_Europe; + } + else { + result = -1; + printk("Unknown Zonetype[%s]?\n", tmpbuffer); + } + error1: - kfree(buffer); + kfree(buffer); - if(filp_close(filp,NULL)) - printk("Config_FileOperation:close file fail\n"); + if (filp_close(filp, NULL)) + printk("Config_FileOperation:close file fail\n"); error2: - set_fs (old_fs); + set_fs(old_fs); - /* - current->cred->fsuid=oldfsuid; - current->cred->fsgid=oldfsgid; - */ + /* + current->cred->fsuid=oldfsuid; + current->cred->fsgid=oldfsgid; + */ - return result; + return result; } static void device_set_multi(struct net_device *dev) { - PSDevice pDevice = (PSDevice) netdev_priv(dev); - - PSMgmtObject pMgmt = pDevice->pMgmt; - u32 mc_filter[2]; - struct netdev_hw_addr *ha; - - - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); - - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); - /* Unconditionally log net taps. */ - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST); - } - else if ((netdev_mc_count(dev) > pDevice->multicast_limit) - || (dev->flags & IFF_ALLMULTI)) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - } - else { - memset(mc_filter, 0, sizeof(mc_filter)); - netdev_for_each_mc_addr(ha, dev) { - int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; - mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); - } - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode &= ~(RCR_UNICAST); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - } - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac. - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - pDevice->byRxMode &= ~(RCR_UNICAST); - } - - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode ); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + + PSMgmtObject pMgmt = pDevice->pMgmt; + u32 mc_filter[2]; + struct netdev_hw_addr *ha; + + + VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); + + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + /* Unconditionally log net taps. */ + pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST); + } + else if ((netdev_mc_count(dev) > pDevice->multicast_limit) + || (dev->flags & IFF_ALLMULTI)) { + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff); + MACvSelectPage0(pDevice->PortOffset); + pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); + } + else { + memset(mc_filter, 0, sizeof(mc_filter)); + netdev_for_each_mc_addr(ha, dev) { + int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); + } + MACvSelectPage1(pDevice->PortOffset); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]); + VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]); + MACvSelectPage0(pDevice->PortOffset); + pDevice->byRxMode &= ~(RCR_UNICAST); + pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); + } + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac. + pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); + pDevice->byRxMode &= ~(RCR_UNICAST); + } + + VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode); } static struct net_device_stats *device_get_stats(struct net_device *dev) { - PSDevice pDevice=(PSDevice) netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); - return &pDevice->stats; + return &pDevice->stats; } @@ -3090,18 +3090,18 @@ static struct net_device_stats *device_get_stats(struct net_device *dev) { static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - struct iwreq *wrq = (struct iwreq *) rq; - int rc =0; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSCmdRequest pReq; + struct iwreq *wrq = (struct iwreq *)rq; + int rc = 0; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSCmdRequest pReq; - if (pMgmt == NULL) { - rc = -EFAULT; - return rc; - } + if (pMgmt == NULL) { + rc = -EFAULT; + return rc; + } - switch(cmd) { + switch (cmd) { case SIOCGIWNAME: rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL); @@ -3113,7 +3113,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set frequency/channel case SIOCSIWFREQ: - rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL); + rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL); break; // Get frequency/channel @@ -3124,37 +3124,37 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set desired network name (ESSID) case SIOCSIWESSID: - { - char essid[IW_ESSID_MAX_SIZE+1]; - if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) { - rc = -E2BIG; - break; - } - if (copy_from_user(essid, wrq->u.essid.pointer, - wrq->u.essid.length)) { - rc = -EFAULT; - break; - } - rc = iwctl_siwessid(dev, NULL, - &(wrq->u.essid), essid); + { + char essid[IW_ESSID_MAX_SIZE+1]; + if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) { + rc = -E2BIG; + break; } - break; + if (copy_from_user(essid, wrq->u.essid.pointer, + wrq->u.essid.length)) { + rc = -EFAULT; + break; + } + rc = iwctl_siwessid(dev, NULL, + &(wrq->u.essid), essid); + } + break; - // Get current network name (ESSID) + // Get current network name (ESSID) case SIOCGIWESSID: - { - char essid[IW_ESSID_MAX_SIZE+1]; - if (wrq->u.essid.pointer) - rc = iwctl_giwessid(dev, NULL, - &(wrq->u.essid), essid); - if (copy_to_user(wrq->u.essid.pointer, - essid, - wrq->u.essid.length) ) - rc = -EFAULT; - } - break; + { + char essid[IW_ESSID_MAX_SIZE+1]; + if (wrq->u.essid.pointer) + rc = iwctl_giwessid(dev, NULL, + &(wrq->u.essid), essid); + if (copy_to_user(wrq->u.essid.pointer, + essid, + wrq->u.essid.length)) + rc = -EFAULT; + } + break; case SIOCSIWAP: @@ -3170,14 +3170,14 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set desired station name case SIOCSIWNICKN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n"); - rc = -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n"); + rc = -EOPNOTSUPP; break; // Get current station name case SIOCGIWNICKN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n"); - rc = -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n"); + rc = -EOPNOTSUPP; break; // Set the desired bit-rate @@ -3185,19 +3185,19 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL); break; - // Get the current bit-rate + // Get the current bit-rate case SIOCGIWRATE: rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL); break; - // Set the desired RTS threshold + // Set the desired RTS threshold case SIOCSIWRTS: rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL); break; - // Get the current RTS threshold + // Get the current RTS threshold case SIOCGIWRTS: rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL); @@ -3207,9 +3207,9 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { case SIOCSIWFRAG: rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL); - break; + break; - // Get the current fragmentation threshold + // Get the current fragmentation threshold case SIOCGIWFRAG: rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL); @@ -3217,7 +3217,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set mode of operation case SIOCSIWMODE: - rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL); + rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL); break; // Get mode of operation @@ -3227,32 +3227,32 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set WEP keys and mode case SIOCSIWENCODE: - { - char abyKey[WLAN_WEP232_KEYLEN]; + { + char abyKey[WLAN_WEP232_KEYLEN]; - if (wrq->u.encoding.pointer) { + if (wrq->u.encoding.pointer) { - if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) { - rc = -E2BIG; - break; - } - memset(abyKey, 0, WLAN_WEP232_KEYLEN); - if (copy_from_user(abyKey, - wrq->u.encoding.pointer, - wrq->u.encoding.length)) { - rc = -EFAULT; - break; - } - } else if (wrq->u.encoding.length != 0) { - rc = -EINVAL; + if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) { + rc = -E2BIG; + break; + } + memset(abyKey, 0, WLAN_WEP232_KEYLEN); + if (copy_from_user(abyKey, + wrq->u.encoding.pointer, + wrq->u.encoding.length)) { + rc = -EFAULT; break; } - rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey); + } else if (wrq->u.encoding.length != 0) { + rc = -EINVAL; + break; } - break; + rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey); + } + break; - // Get the WEP keys and mode + // Get the WEP keys and mode case SIOCGIWENCODE: if (!capable(CAP_NET_ADMIN)) { @@ -3260,14 +3260,14 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { break; } { - char abyKey[WLAN_WEP232_KEYLEN]; + char abyKey[WLAN_WEP232_KEYLEN]; - rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey); - if (rc != 0) break; + rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey); + if (rc != 0) break; if (wrq->u.encoding.pointer) { if (copy_to_user(wrq->u.encoding.pointer, - abyKey, - wrq->u.encoding.length)) + abyKey, + wrq->u.encoding.length)) rc = -EFAULT; } } @@ -3275,13 +3275,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Get the current Tx-Power case SIOCGIWTXPOW: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n"); - rc = -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n"); + rc = -EOPNOTSUPP; break; case SIOCSIWTXPOW: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW \n"); - rc = -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW \n"); + rc = -EOPNOTSUPP; break; case SIOCSIWRETRY: @@ -3297,15 +3297,15 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Get range of parameters case SIOCGIWRANGE: - { - struct iw_range range; + { + struct iw_range range; - rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range); - if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) - rc = -EFAULT; - } + rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range); + if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) + rc = -EFAULT; + } - break; + break; case SIOCGIWPOWER: @@ -3321,67 +3321,67 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { case SIOCGIWSENS: - rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL); + rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL); break; case SIOCSIWSENS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n"); rc = -EOPNOTSUPP; break; case SIOCGIWAPLIST: - { - char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))]; - - if (wrq->u.data.pointer) { - rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); - if (rc == 0) { - if (copy_to_user(wrq->u.data.pointer, - buffer, - (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality))) - )) - rc = -EFAULT; - } - } - } - break; + { + char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))]; + + if (wrq->u.data.pointer) { + rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); + if (rc == 0) { + if (copy_to_user(wrq->u.data.pointer, + buffer, + (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality))) + )) + rc = -EFAULT; + } + } + } + break; #ifdef WIRELESS_SPY - // Set the spy list + // Set the spy list case SIOCSIWSPY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n"); rc = -EOPNOTSUPP; break; // Get the spy list case SIOCGIWSPY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY \n"); rc = -EOPNOTSUPP; break; #endif // WIRELESS_SPY case SIOCGIWPRIV: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n"); rc = -EOPNOTSUPP; /* - if(wrq->u.data.pointer) { - wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]); + if (wrq->u.data.pointer) { + wrq->u.data.length = sizeof(iwctl_private_args) / sizeof(iwctl_private_args[0]); - if(copy_to_user(wrq->u.data.pointer, - (u_char *) iwctl_private_args, - sizeof(iwctl_private_args))) - rc = -EFAULT; - } + if (copy_to_user(wrq->u.data.pointer, + (u_char *) iwctl_private_args, + sizeof(iwctl_private_args))) + rc = -EFAULT; + } */ break; //2008-0409-07, by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT case SIOCSIWAUTH: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL); @@ -3403,26 +3403,26 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { break; case SIOCSIWENCODEEXT: - { - char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n"); - if(wrq->u.encoding.pointer){ - memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1); - if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){ - rc = -E2BIG; - break; - } - if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){ - rc = -EFAULT; - break; - } - }else if(wrq->u.encoding.length != 0){ - rc = -EINVAL; + { + char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1]; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n"); + if (wrq->u.encoding.pointer) { + memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1); + if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) { + rc = -E2BIG; + break; + } + if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) { + rc = -EFAULT; break; } - rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra); + } else if (wrq->u.encoding.length != 0) { + rc = -EINVAL; + break; } - break; + rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra); + } + break; case SIOCGIWENCODEEXT: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n"); @@ -3437,89 +3437,89 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //End Add -- //2008-0409-07, by Einsn Liu - case IOCTL_CMD_TEST: + case IOCTL_CMD_TEST: if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EFAULT; - break; + rc = -EFAULT; + break; } else { - rc = 0; + rc = 0; } - pReq = (PSCmdRequest)rq; - pReq->wResult = MAGIC_CODE; - break; + pReq = (PSCmdRequest)rq; + pReq->wResult = MAGIC_CODE; + break; - case IOCTL_CMD_SET: + case IOCTL_CMD_SET: - #ifdef SndEvt_ToAPI - if((((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_EVT) && - !(pDevice->flags & DEVICE_FLAGS_OPENED)) - #else - if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && - (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA)) - #endif - { - rc = -EFAULT; - break; - } else { - rc = 0; - } +#ifdef SndEvt_ToAPI + if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) && + !(pDevice->flags & DEVICE_FLAGS_OPENED)) +#else + if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && + (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA)) +#endif + { + rc = -EFAULT; + break; + } else { + rc = 0; + } - if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) { - return -EBUSY; - } - rc = private_ioctl(pDevice, rq); - clear_bit( 0, (void*)&(pMgmt->uCmdBusy)); - break; + if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy))) { + return -EBUSY; + } + rc = private_ioctl(pDevice, rq); + clear_bit(0, (void *)&(pMgmt->uCmdBusy)); + break; - case IOCTL_CMD_HOSTAPD: + case IOCTL_CMD_HOSTAPD: - rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data); - break; + rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data); + break; - case IOCTL_CMD_WPA: + case IOCTL_CMD_WPA: - rc = wpa_ioctl(pDevice, &wrq->u.data); - break; + rc = wpa_ioctl(pDevice, &wrq->u.data); + break; case SIOCETHTOOL: - return ethtool_ioctl(dev, (void *) rq->ifr_data); - // All other calls are currently unsupported + return ethtool_ioctl(dev, (void *)rq->ifr_data); + // All other calls are currently unsupported default: rc = -EOPNOTSUPP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd); - - - } - - if (pDevice->bCommit) { - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - spin_unlock_irq(&pDevice->lock); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n"); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - if(pDevice->bWPASuppWextEnabled !=true) - #endif - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - pDevice->bCommit = false; - } - - return rc; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd); + + + } + + if (pDevice->bCommit) { + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + netif_stop_queue(pDevice->dev); + spin_lock_irq(&pDevice->lock); + bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); + spin_unlock_irq(&pDevice->lock); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n"); + spin_lock_irq(&pDevice->lock); + pDevice->bLinkPass = false; + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + netif_stop_queue(pDevice->dev); +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + if (pDevice->bWPASuppWextEnabled != true) +#endif + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); + spin_unlock_irq(&pDevice->lock); + } + pDevice->bCommit = false; + } + + return rc; } @@ -3530,7 +3530,7 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr) if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; - switch (ethcmd) { + switch (ethcmd) { case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1); @@ -3540,7 +3540,7 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr) return 0; } - } + } return -EOPNOTSUPP; } @@ -3562,18 +3562,18 @@ static struct pci_driver device_driver = { static int __init vt6655_init_module(void) { - int ret; + int ret; // ret=pci_module_init(&device_driver); //ret = pcie_port_service_register(&device_driver); ret = pci_register_driver(&device_driver); #ifdef CONFIG_PM - if(ret >= 0) - register_reboot_notifier(&device_notifier); + if (ret >= 0) + register_reboot_notifier(&device_notifier); #endif - return ret; + return ret; } static void __exit vt6655_cleanup_module(void) @@ -3581,9 +3581,9 @@ static void __exit vt6655_cleanup_module(void) #ifdef CONFIG_PM - unregister_reboot_notifier(&device_notifier); + unregister_reboot_notifier(&device_notifier); #endif - pci_unregister_driver(&device_driver); + pci_unregister_driver(&device_driver); } @@ -3595,85 +3595,85 @@ module_exit(vt6655_cleanup_module); static int device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) { - struct pci_dev *pdev = NULL; - switch(event) { - case SYS_DOWN: - case SYS_HALT: - case SYS_POWER_OFF: - for_each_pci_dev(pdev) { - if(pci_dev_driver(pdev) == &device_driver) { - if (pci_get_drvdata(pdev)) - viawget_suspend(pdev, PMSG_HIBERNATE); - } - } - } - return NOTIFY_DONE; + struct pci_dev *pdev = NULL; + switch (event) { + case SYS_DOWN: + case SYS_HALT: + case SYS_POWER_OFF: + for_each_pci_dev(pdev) { + if (pci_dev_driver(pdev) == &device_driver) { + if (pci_get_drvdata(pdev)) + viawget_suspend(pdev, PMSG_HIBERNATE); + } + } + } + return NOTIFY_DONE; } static int viawget_suspend(struct pci_dev *pcid, pm_message_t state) { - int power_status; // to silence the compiler - - PSDevice pDevice=pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - pci_save_state(pcid); - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pci_disable_device(pcid); - power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); - spin_unlock_irq(&pDevice->lock); - return 0; + int power_status; // to silence the compiler + + PSDevice pDevice = pci_get_drvdata(pcid); + PSMgmtObject pMgmt = pDevice->pMgmt; + + netif_stop_queue(pDevice->dev); + spin_lock_irq(&pDevice->lock); + pci_save_state(pcid); + del_timer(&pDevice->sTimerCommand); + del_timer(&pMgmt->sTimerSecondCallback); + pDevice->cbFreeCmdQueue = CMD_Q_SIZE; + pDevice->uCmdDequeueIdx = 0; + pDevice->uCmdEnqueueIdx = 0; + pDevice->bCmdRunning = false; + MACbShutdown(pDevice->PortOffset); + MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext); + pDevice->bLinkPass = false; + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + pci_disable_device(pcid); + power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); + spin_unlock_irq(&pDevice->lock); + return 0; } static int viawget_resume(struct pci_dev *pcid) { - PSDevice pDevice=pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - int power_status; // to silence the compiler - - - power_status = pci_set_power_state(pcid, 0); - power_status = pci_enable_wake(pcid, 0, 0); - pci_restore_state(pcid); - if (netif_running(pDevice->dev)) { - spin_lock_irq(&pDevice->lock); - MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext); - device_init_registers(pDevice, DEVICE_INIT_DXPL); - if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS - pMgmt->sNodeDBTable[0].bActive = false; - pDevice->bLinkPass = false; - if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // In Adhoc, BSS state set back to started. - pMgmt->eCurrState = WMAC_STATE_STARTED; - } - else { - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - } - init_timer(&pMgmt->sTimerSecondCallback); - init_timer(&pDevice->sTimerCommand); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - return 0; + PSDevice pDevice = pci_get_drvdata(pcid); + PSMgmtObject pMgmt = pDevice->pMgmt; + int power_status; // to silence the compiler + + + power_status = pci_set_power_state(pcid, 0); + power_status = pci_enable_wake(pcid, 0, 0); + pci_restore_state(pcid); + if (netif_running(pDevice->dev)) { + spin_lock_irq(&pDevice->lock); + MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext); + device_init_registers(pDevice, DEVICE_INIT_DXPL); + if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS + pMgmt->sNodeDBTable[0].bActive = false; + pDevice->bLinkPass = false; + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + // In Adhoc, BSS state set back to started. + pMgmt->eCurrState = WMAC_STATE_STARTED; + } + else { + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + } + } + init_timer(&pMgmt->sTimerSecondCallback); + init_timer(&pDevice->sTimerCommand); + MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); + spin_unlock_irq(&pDevice->lock); + } + return 0; } #endif -- cgit From 22c5291e70ba66880c6a6acffbd8200a623c4556 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:48 -0700 Subject: staging:vt6655:dpc: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 2440 +++++++++++++++++++++--------------------- drivers/staging/vt6655/dpc.h | 8 +- 2 files changed, 1224 insertions(+), 1224 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 373e9e4fc87d..f96f9c17e8fe 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -63,7 +63,7 @@ /*--------------------- Static Variables --------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; const unsigned char acbyRxRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; @@ -80,57 +80,57 @@ static unsigned char s_byGetRateIdx(unsigned char byRate); static void s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, - PSEthernetHeader psEthHeader); + PSEthernetHeader psEthHeader); static void s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize); + unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, + unsigned int *pcbHeadSize); static bool s_bAPModeRxCtl( - PSDevice pDevice, - unsigned char *pbyFrame, - int iSANodeIndex - ); + PSDevice pDevice, + unsigned char *pbyFrame, + int iSANodeIndex +); -static bool s_bAPModeRxData ( - PSDevice pDevice, - struct sk_buff* skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex - ); +static bool s_bAPModeRxData( + PSDevice pDevice, + struct sk_buff *skb, + unsigned int FrameSize, + unsigned int cbHeaderOffset, + int iSANodeIndex, + int iDANodeIndex +); static bool s_bHandleRxEncryption( - PSDevice pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 - ); + PSDevice pDevice, + unsigned char *pbyFrame, + unsigned int FrameSize, + unsigned char *pbyRsr, + unsigned char *pbyNewRsr, + PSKeyItem *pKeyOut, + bool *pbExtIV, + unsigned short *pwRxTSC15_0, + unsigned long *pdwRxTSC47_16 +); static bool s_bHostWepRxEncryption( - PSDevice pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 + PSDevice pDevice, + unsigned char *pbyFrame, + unsigned int FrameSize, + unsigned char *pbyRsr, + bool bOnFly, + PSKeyItem pKey, + unsigned char *pbyNewRsr, + bool *pbExtIV, + unsigned short *pwRxTSC15_0, + unsigned long *pdwRxTSC47_16 - ); +); /*--------------------- Export Variables --------------------------*/ @@ -150,142 +150,142 @@ static bool s_bHostWepRxEncryption( * * Return Value: None * --*/ + -*/ static void s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize) + unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, + unsigned int *pcbHeadSize) { - unsigned char *pbyRxBuffer; - unsigned int cbHeaderSize = 0; - unsigned short *pwType; - PS802_11Header pMACHeader; - int ii; - - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); - - if (bIsWEP) { - if (bExtIV) { - // strip IV&ExtIV , add 8 byte - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); - } else { - // strip IV , add 4 byte - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); - } - } - else { - cbHeaderSize += WLAN_HDR_ADDR3_LEN; - }; - - pbyRxBuffer = (unsigned char *) (pbyRxBufferAddr + cbHeaderSize); - if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) { - cbHeaderSize += 6; - } - else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { - cbHeaderSize += 6; - pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize); - if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) { - } - else { - cbHeaderSize -= 8; - pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV - } - } - else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - } - else { - cbHeaderSize -= 2; - pwType = (unsigned short *) (pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV - } - } - else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - - cbHeaderSize -= (ETH_ALEN * 2); - pbyRxBuffer = (unsigned char *) (pbyRxBufferAddr + cbHeaderSize); - for(ii=0;iisRxEthHeader.abyDstAddr[ii]; - for(ii=0;iisRxEthHeader.abySrcAddr[ii]; - - *pcbHeadSize = cbHeaderSize; + unsigned char *pbyRxBuffer; + unsigned int cbHeaderSize = 0; + unsigned short *pwType; + PS802_11Header pMACHeader; + int ii; + + + pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); + + s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); + + if (bIsWEP) { + if (bExtIV) { + // strip IV&ExtIV , add 8 byte + cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); + } else { + // strip IV , add 4 byte + cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); + } + } + else { + cbHeaderSize += WLAN_HDR_ADDR3_LEN; + }; + + pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); + if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) { + cbHeaderSize += 6; + } + else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { + cbHeaderSize += 6; + pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); + if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) { + } + else { + cbHeaderSize -= 8; + pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); + if (bIsWEP) { + if (bExtIV) { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV + } else { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV + } + } + else { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); + } + } + } + else { + cbHeaderSize -= 2; + pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); + if (bIsWEP) { + if (bExtIV) { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV + } else { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV + } + } + else { + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); + } + } + + cbHeaderSize -= (ETH_ALEN * 2); + pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); + for (ii = 0; ii < ETH_ALEN; ii++) + *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii]; + for (ii = 0; ii < ETH_ALEN; ii++) + *pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii]; + + *pcbHeadSize = cbHeaderSize; } -static unsigned char s_byGetRateIdx (unsigned char byRate) +static unsigned char s_byGetRateIdx(unsigned char byRate) { - unsigned char byRateIdx; + unsigned char byRateIdx; - for (byRateIdx = 0; byRateIdx wFrameCtl & FC_TODS) == 0) { - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; - } - } - else { - // IBSS mode - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } - else { - // Is AP mode.. - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; - cbHeaderSize += 6; - } - } - else { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - }; - *pcbHeaderSize = cbHeaderSize; + unsigned int cbHeaderSize = 0; + PS802_11Header pMACHeader; + int ii; + + pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); + + if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { + if (pMACHeader->wFrameCtl & FC_FROMDS) { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; + psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; + } + } + else { + // IBSS mode + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; + psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; + } + } + } + else { + // Is AP mode.. + if (pMACHeader->wFrameCtl & FC_FROMDS) { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; + psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; + cbHeaderSize += 6; + } + } + else { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; + psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; + } + } + }; + *pcbHeaderSize = cbHeaderSize; } @@ -299,10 +299,10 @@ void MngWorkItem(void *Context) PSDevice pDevice = (PSDevice) Context; //printk("Enter MngWorkItem,Queue packet num is %d\n",pDevice->rxManeQueue.packet_num); spin_lock_irq(&pDevice->lock); - while(pDevice->rxManeQueue.packet_num != 0) - { - pRxMgmtPacket = DeQueue(pDevice); - vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket); + while (pDevice->rxManeQueue.packet_num != 0) + { + pRxMgmtPacket = DeQueue(pDevice); + vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket); } spin_unlock_irq(&pDevice->lock); } @@ -313,531 +313,531 @@ void MngWorkItem(void *Context) bool -device_receive_frame ( - PSDevice pDevice, - PSRxDesc pCurrRD - ) +device_receive_frame( + PSDevice pDevice, + PSRxDesc pCurrRD +) { - PDEVICE_RD_INFO pRDInfo = pCurrRD->pRDInfo; + PDEVICE_RD_INFO pRDInfo = pCurrRD->pRDInfo; #ifdef PLICE_DEBUG //printk("device_receive_frame:pCurrRD is %x,pRDInfo is %x\n",pCurrRD,pCurrRD->pRDInfo); #endif - struct net_device_stats* pStats=&pDevice->stats; - struct sk_buff* skb; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = &(pDevice->pMgmt->sRxPacket); - PS802_11Header p802_11Header; - unsigned char *pbyRsr; - unsigned char *pbyNewRsr; - unsigned char *pbyRSSI; - PQWORD pqwTSFTime; - unsigned short *pwFrameSize; - unsigned char *pbyFrame; - bool bDeFragRx = false; - bool bIsWEP = false; - unsigned int cbHeaderOffset; - unsigned int FrameSize; - unsigned short wEtherType = 0; - int iSANodeIndex = -1; - int iDANodeIndex = -1; - unsigned int ii; - unsigned int cbIVOffset; - bool bExtIV = false; - unsigned char *pbyRxSts; - unsigned char *pbyRxRate; - unsigned char *pbySQ; - unsigned int cbHeaderSize; - PSKeyItem pKey = NULL; - unsigned short wRxTSC15_0 = 0; - unsigned long dwRxTSC47_16 = 0; - SKeyItem STempKey; - // 802.11h RPI - unsigned long dwDuration = 0; - long ldBm = 0; - long ldBmThreshold = 0; - PS802_11Header pMACHeader; - bool bRxeapol_key = false; - -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n"); - - skb = pRDInfo->skb; + struct net_device_stats *pStats = &pDevice->stats; + struct sk_buff *skb; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSRxMgmtPacket pRxPacket = &(pDevice->pMgmt->sRxPacket); + PS802_11Header p802_11Header; + unsigned char *pbyRsr; + unsigned char *pbyNewRsr; + unsigned char *pbyRSSI; + PQWORD pqwTSFTime; + unsigned short *pwFrameSize; + unsigned char *pbyFrame; + bool bDeFragRx = false; + bool bIsWEP = false; + unsigned int cbHeaderOffset; + unsigned int FrameSize; + unsigned short wEtherType = 0; + int iSANodeIndex = -1; + int iDANodeIndex = -1; + unsigned int ii; + unsigned int cbIVOffset; + bool bExtIV = false; + unsigned char *pbyRxSts; + unsigned char *pbyRxRate; + unsigned char *pbySQ; + unsigned int cbHeaderSize; + PSKeyItem pKey = NULL; + unsigned short wRxTSC15_0 = 0; + unsigned long dwRxTSC47_16 = 0; + SKeyItem STempKey; + // 802.11h RPI + unsigned long dwDuration = 0; + long ldBm = 0; + long ldBmThreshold = 0; + PS802_11Header pMACHeader; + bool bRxeapol_key = false; + +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- device_receive_frame---\n"); + + skb = pRDInfo->skb; //PLICE_DEBUG-> #if 1 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); #endif //PLICE_DEBUG<- - pwFrameSize = (unsigned short *)(skb->data + 2); - FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); - - // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - if ((FrameSize > 2364)||(FrameSize <= 32)) { - // Frame Size error drop this packet. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n"); - return false; - } - - pbyRxSts = (unsigned char *) (skb->data); - pbyRxRate = (unsigned char *) (skb->data + 1); - pbyRsr = (unsigned char *) (skb->data + FrameSize - 1); - pbyRSSI = (unsigned char *) (skb->data + FrameSize - 2); - pbyNewRsr = (unsigned char *) (skb->data + FrameSize - 3); - pbySQ = (unsigned char *) (skb->data + FrameSize - 4); - pqwTSFTime = (PQWORD) (skb->data + FrameSize - 12); - pbyFrame = (unsigned char *)(skb->data + 4); - - // get packet size - FrameSize = cpu_to_le16(*pwFrameSize); - - if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC - // Min: 14 bytes ACK - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n"); - return false; - } + pwFrameSize = (unsigned short *)(skb->data + 2); + FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); + + // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR + // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR + if ((FrameSize > 2364) || (FrameSize <= 32)) { + // Frame Size error drop this packet. + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1 \n"); + return false; + } + + pbyRxSts = (unsigned char *)(skb->data); + pbyRxRate = (unsigned char *)(skb->data + 1); + pbyRsr = (unsigned char *)(skb->data + FrameSize - 1); + pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2); + pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3); + pbySQ = (unsigned char *)(skb->data + FrameSize - 4); + pqwTSFTime = (PQWORD)(skb->data + FrameSize - 12); + pbyFrame = (unsigned char *)(skb->data + 4); + + // get packet size + FrameSize = cpu_to_le16(*pwFrameSize); + + if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC + // Min: 14 bytes ACK + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2 \n"); + return false; + } //PLICE_DEBUG-> #if 1 // update receive statistic counter - STAvUpdateRDStatCounter(&pDevice->scStatistic, - *pbyRsr, - *pbyNewRsr, - *pbyRxRate, - pbyFrame, - FrameSize); + STAvUpdateRDStatCounter(&pDevice->scStatistic, + *pbyRsr, + *pbyNewRsr, + *pbyRxRate, + pbyFrame, + FrameSize); #endif - pMACHeader=(PS802_11Header)((unsigned char *) (skb->data)+8); + pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8); //PLICE_DEBUG<- if (pDevice->bMeasureInProgress == true) { - if ((*pbyRsr & RSR_CRCOK) != 0) { - pDevice->byBasicMap |= 0x01; - } - dwDuration = (FrameSize << 4); - dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; - if (*pbyRxRate <= RATE_11M) { - if (*pbyRxSts & 0x01) { - // long preamble - dwDuration += 192; - } else { - // short preamble - dwDuration += 96; - } - } else { - dwDuration += 16; - } - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - ldBmThreshold = -57; - for (ii = 7; ii > 0;) { - if (ldBm > ldBmThreshold) { - break; - } - ldBmThreshold -= 5; - ii--; - } - pDevice->dwRPIs[ii] += dwDuration; - return false; - } - - if (!is_multicast_ether_addr(pbyFrame)) { - if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) (skb->data + 4))) { - pDevice->s802_11Counter.FrameDuplicateCount++; - return false; - } - } - - - // Use for TKIP MIC - s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); - - // filter packet send from myself - if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr)) - return false; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - p802_11Header = (PS802_11Header) (pbyFrame); - // get SA NodeIndex - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { - pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; - pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) { - return false; - } - } - - - if (IS_FC_WEP(pbyFrame)) { - bool bRxDecryOK = false; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n"); - bIsWEP = true; - if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { - pKey = &STempKey; - pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; - pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; - pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; - pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; - pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; - memcpy(pKey->abyKey, - &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], - pKey->uKeyLength - ); - - bRxDecryOK = s_bHostWepRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, - pKey, - pbyNewRsr, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } else { - bRxDecryOK = s_bHandleRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pbyNewRsr, - &pKey, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } - - if (bRxDecryOK) { - if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n"); - if ( (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - pDevice->s802_11Counter.TKIPICVErrors++; - } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) { - pDevice->s802_11Counter.CCMPDecryptErrors++; - } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) { + if ((*pbyRsr & RSR_CRCOK) != 0) { + pDevice->byBasicMap |= 0x01; + } + dwDuration = (FrameSize << 4); + dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; + if (*pbyRxRate <= RATE_11M) { + if (*pbyRxSts & 0x01) { + // long preamble + dwDuration += 192; + } else { + // short preamble + dwDuration += 96; + } + } else { + dwDuration += 16; + } + RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); + ldBmThreshold = -57; + for (ii = 7; ii > 0;) { + if (ldBm > ldBmThreshold) { + break; + } + ldBmThreshold -= 5; + ii--; + } + pDevice->dwRPIs[ii] += dwDuration; + return false; + } + + if (!is_multicast_ether_addr(pbyFrame)) { + if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) { + pDevice->s802_11Counter.FrameDuplicateCount++; + return false; + } + } + + + // Use for TKIP MIC + s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); + + // filter packet send from myself + if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr)) + return false; + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { + if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { + p802_11Header = (PS802_11Header)(pbyFrame); + // get SA NodeIndex + if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { + pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; + pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; + } + } + } + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) { + return false; + } + } + + + if (IS_FC_WEP(pbyFrame)) { + bool bRxDecryOK = false; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx WEP pkt\n"); + bIsWEP = true; + if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { + pKey = &STempKey; + pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; + pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; + pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; + pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; + pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; + memcpy(pKey->abyKey, + &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], + pKey->uKeyLength +); + + bRxDecryOK = s_bHostWepRxEncryption(pDevice, + pbyFrame, + FrameSize, + pbyRsr, + pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, + pKey, + pbyNewRsr, + &bExtIV, + &wRxTSC15_0, + &dwRxTSC47_16); + } else { + bRxDecryOK = s_bHandleRxEncryption(pDevice, + pbyFrame, + FrameSize, + pbyRsr, + pbyNewRsr, + &pKey, + &bExtIV, + &wRxTSC15_0, + &dwRxTSC47_16); + } + + if (bRxDecryOK) { + if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV Fail\n"); + if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || + (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || + (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || + (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { + + if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { + pDevice->s802_11Counter.TKIPICVErrors++; + } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) { + pDevice->s802_11Counter.CCMPDecryptErrors++; + } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) { // pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++; - } - } - return false; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n"); - return false; - } - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - FrameSize -= 8; // Message Integrity Code - else - FrameSize -= 4; // 4 is ICV - } - - - // - // RX OK - // - //remove the CRC length - FrameSize -= ETH_FCS_LEN; - - if (( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address - (IS_FRAGMENT_PKT((skb->data+4))) - ) { - // defragment - bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (skb->data+4), FrameSize, bIsWEP, bExtIV); - pDevice->s802_11Counter.ReceivedFragmentCount++; - if (bDeFragRx) { - // defrag complete - skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; - FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; - - } - else { - return false; - } - } + } + } + return false; + } + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP Func Fail\n"); + return false; + } + if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) + FrameSize -= 8; // Message Integrity Code + else + FrameSize -= 4; // 4 is ICV + } + + + // + // RX OK + // + //remove the CRC length + FrameSize -= ETH_FCS_LEN; + + if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address + (IS_FRAGMENT_PKT((skb->data+4))) +) { + // defragment + bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV); + pDevice->s802_11Counter.ReceivedFragmentCount++; + if (bDeFragRx) { + // defrag complete + skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; + FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; + + } + else { + return false; + } + } // Management & Control frame Handle - if ((IS_TYPE_DATA((skb->data+4))) == false) { - // Handle Control & Manage Frame - - if (IS_TYPE_MGMT((skb->data+4))) { - unsigned char *pbyData1; - unsigned char *pbyData2; - - pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4); - pRxPacket->cbMPDULen = FrameSize; - pRxPacket->uRSSI = *pbyRSSI; - pRxPacket->bySQ = *pbySQ; - HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime)); - LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime)); - if (bIsWEP) { - // strip IV - pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); - pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; - for (ii = 0; ii < (FrameSize - 4); ii++) { - *pbyData1 = *pbyData2; - pbyData1++; - pbyData2++; - } - } - pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); - pRxPacket->byRxChannel = (*pbyRxSts) >> 2; + if ((IS_TYPE_DATA((skb->data+4))) == false) { + // Handle Control & Manage Frame + + if (IS_TYPE_MGMT((skb->data+4))) { + unsigned char *pbyData1; + unsigned char *pbyData2; + + pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4); + pRxPacket->cbMPDULen = FrameSize; + pRxPacket->uRSSI = *pbyRSSI; + pRxPacket->bySQ = *pbySQ; + HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime)); + LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime)); + if (bIsWEP) { + // strip IV + pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); + pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; + for (ii = 0; ii < (FrameSize - 4); ii++) { + *pbyData1 = *pbyData2; + pbyData1++; + pbyData2++; + } + } + pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); + pRxPacket->byRxChannel = (*pbyRxSts) >> 2; //PLICE_DEBUG-> //EnQueue(pDevice,pRxPacket); #ifdef THREAD - EnQueue(pDevice,pRxPacket); + EnQueue(pDevice, pRxPacket); - //printk("enque time is %x\n",jiffies); - //up(&pDevice->mlme_semaphore); + //printk("enque time is %x\n",jiffies); + //up(&pDevice->mlme_semaphore); //Enque (pDevice->FirstRecvMngList,pDevice->LastRecvMngList,pMgmt); #else #ifdef TASK_LET - EnQueue(pDevice,pRxPacket); - tasklet_schedule(&pDevice->RxMngWorkItem); + EnQueue(pDevice, pRxPacket); + tasklet_schedule(&pDevice->RxMngWorkItem); #else //printk("RxMan\n"); - vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); - //tasklet_schedule(&pDevice->RxMngWorkItem); + vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); + //tasklet_schedule(&pDevice->RxMngWorkItem); #endif #endif //PLICE_DEBUG<- //vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); - // hostap Deamon handle 802.11 management - if (pDevice->bEnableHostapd) { - skb->dev = pDevice->apdev; - skb->data += 4; - skb->tail += 4; - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; - } - } - else { - // Control Frame - }; - return false; - } - else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. - if ( !(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } - else { - // discard DATA packet while not associate || BSSID error - if ((pDevice->bLinkPass == false) || - !(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - //mike add:station mode check eapol-key challenge---> - { - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | - skb->data[cbIVOffset + 8 + 24 + 6 + 1]; - Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1]; - Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1]; - if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header - if(((Protocol_Version==1) ||(Protocol_Version==2)) && - (Packet_Type==3)) { //802.1x OR eapol-key challenge frame receive - bRxeapol_key = true; - } - } - } - //mike add:station mode check eapol-key challenge<--- - } - } + // hostap Deamon handle 802.11 management + if (pDevice->bEnableHostapd) { + skb->dev = pDevice->apdev; + skb->data += 4; + skb->tail += 4; + skb_put(skb, FrameSize); + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); + return true; + } + } + else { + // Control Frame + }; + return false; + } + else { + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. + if (!(*pbyRsr & RSR_BSSIDOK)) { + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + return false; + } + } + else { + // discard DATA packet while not associate || BSSID error + if ((pDevice->bLinkPass == false) || + !(*pbyRsr & RSR_BSSIDOK)) { + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + return false; + } + //mike add:station mode check eapol-key challenge---> + { + unsigned char Protocol_Version; //802.1x Authentication + unsigned char Packet_Type; //802.1x Authentication + if (bIsWEP) + cbIVOffset = 8; + else + cbIVOffset = 0; + wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | + skb->data[cbIVOffset + 8 + 24 + 6 + 1]; + Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1]; + Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1]; + if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header + if (((Protocol_Version == 1) || (Protocol_Version == 2)) && + (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame receive + bRxeapol_key = true; + } + } + } + //mike add:station mode check eapol-key challenge<--- + } + } // Data frame Handle - if (pDevice->bEnablePSMode) { - if (IS_FC_MOREDATA((skb->data+4))) { - if (*pbyRsr & RSR_ADDROK) { - //PSbSendPSPOLL((PSDevice)pDevice); - } - } - else { - if (pDevice->pMgmt->bInTIMWake == true) { - pDevice->pMgmt->bInTIMWake = false; - } - } - } - - // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps - if (pDevice->bDiversityEnable && (FrameSize>50) && - (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && - (pDevice->bLinkPass == true)) { - //printk("device_receive_frame: RxRate is %d\n",*pbyRxRate); + if (pDevice->bEnablePSMode) { + if (IS_FC_MOREDATA((skb->data+4))) { + if (*pbyRsr & RSR_ADDROK) { + //PSbSendPSPOLL((PSDevice)pDevice); + } + } + else { + if (pDevice->pMgmt->bInTIMWake == true) { + pDevice->pMgmt->bInTIMWake = false; + } + } + } + + // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps + if (pDevice->bDiversityEnable && (FrameSize > 50) && + (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && + (pDevice->bLinkPass == true)) { + //printk("device_receive_frame: RxRate is %d\n",*pbyRxRate); BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); - } - - - if (pDevice->byLocalID != REV_ID_VT3253_B1) { - pDevice->uCurrRSSI = *pbyRSSI; - } - pDevice->byCurrSQ = *pbySQ; - - if ((*pbyRSSI != 0) && - (pMgmt->pCurrBSS!=NULL)) { - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - // Monitor if RSSI is too strong. - pMgmt->pCurrBSS->byRSSIStatCnt++; - pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; - pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; - for(ii=0;iipCurrBSS->ldBmAverage[ii] != 0) { - pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); - } - } - } - - // ----------------------------------------------- - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)){ - unsigned char abyMacHdr[24]; - - // Only 802.1x packet incoming allowed - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) | - skb->data[cbIVOffset + 4 + 24 + 6 + 1]; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType); - if (wEtherType == ETH_P_PAE) { - skb->dev = pDevice->apdev; - - if (bIsWEP == true) { - // strip IV header(8) - memcpy(&abyMacHdr[0], (skb->data + 4), 24); - memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); - } - skb->data += (cbIVOffset + 4); - skb->tail += (cbIVOffset + 4); - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; + } -} - // check if 802.1x authorized - if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) - return false; - } - - - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) { - FrameSize -= 8; //MIC - } - } - - //-------------------------------------------------------------------------------- - // Soft MIC - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) { - unsigned long *pdwMIC_L; - unsigned long *pdwMIC_R; - unsigned long dwMIC_Priority; - unsigned long dwMICKey0 = 0, dwMICKey1 = 0; - unsigned long dwLocalMIC_L = 0; - unsigned long dwLocalMIC_R = 0; - viawget_wpa_header *wpahdr; - - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28])); - } - else { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20])); - } else if ((pKey->dwKeyIndex & BIT28) == 0) { - dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20])); - } else { - dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28])); - } - } - - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. - MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8), - FrameSize - WLAN_HDR_ADDR3_LEN - 8); - MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); - MIC_vUnInit(); - - pdwMIC_L = (unsigned long *)(skb->data + 4 + FrameSize); - pdwMIC_R = (unsigned long *)(skb->data + 4 + FrameSize + 4); - //DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R)); - //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R)); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1); - - - if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || - (pDevice->bRxMICFail == true)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n"); - pDevice->bRxMICFail = false; - //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++; - pDevice->s802_11Counter.TKIPLocalMICFailures++; - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - //2008-0409-07, by Einsn Liu - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + + if (pDevice->byLocalID != REV_ID_VT3253_B1) { + pDevice->uCurrRSSI = *pbyRSSI; + } + pDevice->byCurrSQ = *pbySQ; + + if ((*pbyRSSI != 0) && + (pMgmt->pCurrBSS != NULL)) { + RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); + // Monitor if RSSI is too strong. + pMgmt->pCurrBSS->byRSSIStatCnt++; + pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; + pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; + for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { + if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) { + pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); + } + } + } + + // ----------------------------------------------- + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)) { + unsigned char abyMacHdr[24]; + + // Only 802.1x packet incoming allowed + if (bIsWEP) + cbIVOffset = 8; + else + cbIVOffset = 0; + wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) | + skb->data[cbIVOffset + 4 + 24 + 6 + 1]; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wEtherType = %04x \n", wEtherType); + if (wEtherType == ETH_P_PAE) { + skb->dev = pDevice->apdev; + + if (bIsWEP == true) { + // strip IV header(8) + memcpy(&abyMacHdr[0], (skb->data + 4), 24); + memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); + } + skb->data += (cbIVOffset + 4); + skb->tail += (cbIVOffset + 4); + skb_put(skb, FrameSize); + skb_reset_mac_header(skb); + + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); + return true; + + } + // check if 802.1x authorized + if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) + return false; + } + + + if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { + if (bIsWEP) { + FrameSize -= 8; //MIC + } + } + + //-------------------------------------------------------------------------------- + // Soft MIC + if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { + if (bIsWEP) { + unsigned long *pdwMIC_L; + unsigned long *pdwMIC_R; + unsigned long dwMIC_Priority; + unsigned long dwMICKey0 = 0, dwMICKey1 = 0; + unsigned long dwLocalMIC_L = 0; + unsigned long dwLocalMIC_R = 0; + viawget_wpa_header *wpahdr; + + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24])); + dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28])); + } + else { + if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16])); + dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20])); + } else if ((pKey->dwKeyIndex & BIT28) == 0) { + dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16])); + dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20])); + } else { + dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24])); + dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28])); + } + } + + MIC_vInit(dwMICKey0, dwMICKey1); + MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); + dwMIC_Priority = 0; + MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); + // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. + MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8), + FrameSize - WLAN_HDR_ADDR3_LEN - 8); + MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); + MIC_vUnInit(); + + pdwMIC_L = (unsigned long *)(skb->data + 4 + FrameSize); + pdwMIC_R = (unsigned long *)(skb->data + 4 + FrameSize + 4); + //DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R)); + //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R)); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1); + + + if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || + (pDevice->bRxMICFail == true)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC comparison is fail!\n"); + pDevice->bRxMICFail = false; + //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++; + pDevice->s802_11Counter.TKIPLocalMICFailures++; + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + //2008-0409-07, by Einsn Liu +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //send event to wpa_supplicant - //if(pDevice->bWPADevEnable == true) + //if (pDevice->bWPADevEnable == true) { union iwreq_data wrqu; struct iw_michaelmicfailure ev; @@ -845,8 +845,8 @@ device_receive_frame ( memset(&ev, 0, sizeof(ev)); ev.flags = keyidx & IW_MICFAILURE_KEY_ID; if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { + (pMgmt->eCurrState == WMAC_STATE_ASSOC) && + (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { ev.flags |= IW_MICFAILURE_PAIRWISE; } else { ev.flags |= IW_MICFAILURE_GROUP; @@ -859,633 +859,633 @@ device_receive_frame ( wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); } - #endif - - - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { - //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR; - wpahdr->type = VIAWGET_PTK_MIC_MSG; - } else { - //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR; - wpahdr->type = VIAWGET_GTK_MIC_MSG; - } - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - - return false; - - } - } - } //---end of SOFT MIC----------------------------------------------------------------------- - - // ++++++++++ Reply Counter Check +++++++++++++ - - if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || - (pKey->byCipherSuite == KEY_CTL_CCMP))) { - if (bIsWEP) { - unsigned short wLocalTSC15_0 = 0; - unsigned long dwLocalTSC47_16 = 0; - unsigned long long RSC = 0; - // endian issues - RSC = *((unsigned long long *) &(pKey->KeyRSC)); - wLocalTSC15_0 = (unsigned short) RSC; - dwLocalTSC47_16 = (unsigned long) (RSC>>16); - - RSC = dwRxTSC47_16; - RSC <<= 16; - RSC += wRxTSC15_0; - memcpy(&(pKey->KeyRSC), &RSC, sizeof(QWORD)); - - if ( (pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { - // check RSC - if ( (wRxTSC15_0 < wLocalTSC15_0) && - (dwRxTSC47_16 <= dwLocalTSC47_16) && - !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n "); - if (pKey->byCipherSuite == KEY_CTL_TKIP) - //pDevice->s802_11Counter.TKIPReplays.QuadPart++; - pDevice->s802_11Counter.TKIPReplays++; - else - //pDevice->s802_11Counter.CCMPReplays.QuadPart++; - pDevice->s802_11Counter.CCMPReplays++; - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } - } - } // ----- End of Reply Counter Check -------------------------- - - - - if ((pKey != NULL) && (bIsWEP)) { +#endif + + + if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) && + (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { + //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR; + wpahdr->type = VIAWGET_PTK_MIC_MSG; + } else { + //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR; + wpahdr->type = VIAWGET_GTK_MIC_MSG; + } + wpahdr->resp_ie_len = 0; + wpahdr->req_ie_len = 0; + skb_put(pDevice->skb, sizeof(viawget_wpa_header)); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } + + return false; + + } + } + } //---end of SOFT MIC----------------------------------------------------------------------- + + // ++++++++++ Reply Counter Check +++++++++++++ + + if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || + (pKey->byCipherSuite == KEY_CTL_CCMP))) { + if (bIsWEP) { + unsigned short wLocalTSC15_0 = 0; + unsigned long dwLocalTSC47_16 = 0; + unsigned long long RSC = 0; + // endian issues + RSC = *((unsigned long long *)&(pKey->KeyRSC)); + wLocalTSC15_0 = (unsigned short)RSC; + dwLocalTSC47_16 = (unsigned long)(RSC>>16); + + RSC = dwRxTSC47_16; + RSC <<= 16; + RSC += wRxTSC15_0; + memcpy(&(pKey->KeyRSC), &RSC, sizeof(QWORD)); + + if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && + (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { + // check RSC + if ((wRxTSC15_0 < wLocalTSC15_0) && + (dwRxTSC47_16 <= dwLocalTSC47_16) && + !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC is illegal~~!\n "); + if (pKey->byCipherSuite == KEY_CTL_TKIP) + //pDevice->s802_11Counter.TKIPReplays.QuadPart++; + pDevice->s802_11Counter.TKIPReplays++; + else + //pDevice->s802_11Counter.CCMPReplays.QuadPart++; + pDevice->s802_11Counter.CCMPReplays++; + + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + return false; + } + } + } + } // ----- End of Reply Counter Check -------------------------- + + + + if ((pKey != NULL) && (bIsWEP)) { // pDevice->s802_11Counter.DecryptSuccessCount.QuadPart++; - } - - - s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); - FrameSize -= cbHeaderOffset; - cbHeaderOffset += 4; // 4 is Rcv buffer header - - // Null data, framesize = 14 - if (FrameSize < 15) - return false; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxData(pDevice, - skb, - FrameSize, - cbHeaderOffset, - iSANodeIndex, - iDANodeIndex - ) == false) { - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - -// if(pDevice->bRxMICFail == false) { + } + + + s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); + FrameSize -= cbHeaderOffset; + cbHeaderOffset += 4; // 4 is Rcv buffer header + + // Null data, framesize = 14 + if (FrameSize < 15) + return false; + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (s_bAPModeRxData(pDevice, + skb, + FrameSize, + cbHeaderOffset, + iSANodeIndex, + iDANodeIndex +) == false) { + + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + return false; + } + +// if (pDevice->bRxMICFail == false) { // for (ii =0; ii < 100; ii++) // printk(" %02x", *(skb->data + ii)); // printk("\n"); // } - } + } skb->data += cbHeaderOffset; skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb->protocol=eth_type_trans(skb, skb->dev); + skb_put(skb, FrameSize); + skb->protocol = eth_type_trans(skb, skb->dev); //drop frame not met IEEE 802.3 /* - if (pDevice->flags & DEVICE_FLAGS_VAL_PKT_LEN) { - if ((skb->protocol==htons(ETH_P_802_3)) && - (skb->len!=htons(skb->mac.ethernet->h_proto))) { - pStats->rx_length_errors++; - pStats->rx_dropped++; - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } + if (pDevice->flags & DEVICE_FLAGS_VAL_PKT_LEN) { + if ((skb->protocol==htons(ETH_P_802_3)) && + (skb->len!=htons(skb->mac.ethernet->h_proto))) { + pStats->rx_length_errors++; + pStats->rx_dropped++; + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + } + return false; + } + } */ - skb->ip_summed=CHECKSUM_NONE; - pStats->rx_bytes +=skb->len; - pStats->rx_packets++; - netif_rx(skb); + skb->ip_summed = CHECKSUM_NONE; + pStats->rx_bytes += skb->len; + pStats->rx_packets++; + netif_rx(skb); - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - return false; - } + if (bDeFragRx) { + if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { + DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", + pDevice->dev->name); + } + return false; + } - return true; + return true; } -static bool s_bAPModeRxCtl ( - PSDevice pDevice, - unsigned char *pbyFrame, - int iSANodeIndex - ) +static bool s_bAPModeRxCtl( + PSDevice pDevice, + unsigned char *pbyFrame, + int iSANodeIndex +) { - PS802_11Header p802_11Header; - CMD_STATUS Status; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - - p802_11Header = (PS802_11Header) (pbyFrame); - if (!IS_TYPE_MGMT(pbyFrame)) { - - // Data & PS-Poll packet - // check frame class - if (iSANodeIndex > 0) { - // frame class 3 fliter & checking - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n"); - return true; - } - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { - // send deassoc notification - // reason = (7) class 3 received from nonassoc sta - vMgrDisassocBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS3_NONASSOC), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n"); - return true; - } - - if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { - // delcare received ps-poll event - if (IS_CTL_PSPOLL(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); - } - else { - // check Data PS state - // if PW bit off, send out all PS bufferring packets. - if (!IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); - } - } - } - else { - if (IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; - // Once if STA in PS state, enable multicast bufferring - pMgmt->sNodeDBTable[0].bPSEnable = true; - } - else { - // clear all pending PS frame. - if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); - - } - } - } - } - else { - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", - p802_11Header->abyAddr3); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", - p802_11Header->abyAddr2); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", - p802_11Header->abyAddr1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl ); - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode ); - return true; - } - } - } - return false; + PS802_11Header p802_11Header; + CMD_STATUS Status; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { + + p802_11Header = (PS802_11Header)(pbyFrame); + if (!IS_TYPE_MGMT(pbyFrame)) { + + // Data & PS-Poll packet + // check frame class + if (iSANodeIndex > 0) { + // frame class 3 fliter & checking + if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { + // send deauth notification + // reason = (6) class 2 received from nonauth sta + vMgrDeAuthenBeginSta(pDevice, + pMgmt, + (unsigned char *)(p802_11Header->abyAddr2), + (WLAN_MGMT_REASON_CLASS2_NONAUTH), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n"); + return true; + } + if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { + // send deassoc notification + // reason = (7) class 3 received from nonassoc sta + vMgrDisassocBeginSta(pDevice, + pMgmt, + (unsigned char *)(p802_11Header->abyAddr2), + (WLAN_MGMT_REASON_CLASS3_NONASSOC), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n"); + return true; + } + + if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { + // delcare received ps-poll event + if (IS_CTL_PSPOLL(pbyFrame)) { + pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); + } + else { + // check Data PS state + // if PW bit off, send out all PS bufferring packets. + if (!IS_FC_POWERMGT(pbyFrame)) { + pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; + pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); + } + } + } + else { + if (IS_FC_POWERMGT(pbyFrame)) { + pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; + // Once if STA in PS state, enable multicast bufferring + pMgmt->sNodeDBTable[0].bPSEnable = true; + } + else { + // clear all pending PS frame. + if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { + pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; + pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); + + } + } + } + } + else { + vMgrDeAuthenBeginSta(pDevice, + pMgmt, + (unsigned char *)(p802_11Header->abyAddr2), + (WLAN_MGMT_REASON_CLASS2_NONAUTH), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", + p802_11Header->abyAddr3); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", + p802_11Header->abyAddr2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", + p802_11Header->abyAddr1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl); + VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode); + return true; + } + } + } + return false; } -static bool s_bHandleRxEncryption ( - PSDevice pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 - ) +static bool s_bHandleRxEncryption( + PSDevice pDevice, + unsigned char *pbyFrame, + unsigned int FrameSize, + unsigned char *pbyRsr, + unsigned char *pbyNewRsr, + PSKeyItem *pKeyOut, + bool *pbExtIV, + unsigned short *pwRxTSC15_0, + unsigned long *pdwRxTSC47_16 +) { - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - PSKeyItem pKey = NULL; - unsigned char byDecMode = KEY_CTL_WEP; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) { - pbyIV += 6; // 6 is 802.11 address4 - PayloadLen -= 6; - } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx); - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && - (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { - // unicast pkt use pairwise key - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n"); - if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { - if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey); - } else { - // use group key - KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey); - } - } - // our WEP only support Default Key - if (pKey == NULL) { - // use default group key - KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - *pKeyOut = pKey; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); - - if (pKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n"); - if (byDecMode == KEY_CTL_WEP) { + unsigned int PayloadLen = FrameSize; + unsigned char *pbyIV; + unsigned char byKeyIdx; + PSKeyItem pKey = NULL; + unsigned char byDecMode = KEY_CTL_WEP; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + *pwRxTSC15_0 = 0; + *pdwRxTSC47_16 = 0; + + pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; + if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && + WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { + pbyIV += 6; // 6 is 802.11 address4 + PayloadLen -= 6; + } + byKeyIdx = (*(pbyIV+3) & 0xc0); + byKeyIdx >>= 6; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx); + + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { + if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && + (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { + // unicast pkt use pairwise key + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt\n"); + if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { + if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP) + byDecMode = KEY_CTL_TKIP; + else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP) + byDecMode = KEY_CTL_CCMP; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt: %d, %p\n", byDecMode, pKey); + } else { + // use group key + KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); + if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) + byDecMode = KEY_CTL_TKIP; + else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) + byDecMode = KEY_CTL_CCMP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey); + } + } + // our WEP only support Default Key + if (pKey == NULL) { + // use default group key + KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); + if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) + byDecMode = KEY_CTL_TKIP; + else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) + byDecMode = KEY_CTL_CCMP; + } + *pKeyOut = pKey; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); + + if (pKey == NULL) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey == NULL\n"); + if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass == true) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; - } - return false; - } - if (byDecMode != pKey->byCipherSuite) { - if (byDecMode == KEY_CTL_WEP) { + } + return false; + } + if (byDecMode != pKey->byCipherSuite) { + if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass == true) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; - } - *pKeyOut = NULL; - return false; - } - if (byDecMode == KEY_CTL_WEP) { - // handle WEP - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { - // Software WEP - // 1. 3253A - // 2. WEP 256 - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); - - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - } - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); - if (byDecMode == KEY_CTL_TKIP) { - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); - } else { - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); - - if ((byDecMode == KEY_CTL_TKIP) && - (pDevice->byLocalID <= REV_ID_VT3253_A1)) { - // Software TKIP - // 1. 3253 A - PS802_11Header pMACHeader = (PS802_11Header) (pbyFrame); - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n"); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen); - } - } - }// end of TKIP/AES - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; - return true; + } + *pKeyOut = NULL; + return false; + } + if (byDecMode == KEY_CTL_WEP) { + // handle WEP + if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || + (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { + // Software WEP + // 1. 3253A + // 2. WEP 256 + + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc + memcpy(pDevice->abyPRNG, pbyIV, 3); + memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); + rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); + rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); + + if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { + *pbyNewRsr |= NEWRSR_DECRYPTOK; + } + } + } else if ((byDecMode == KEY_CTL_TKIP) || + (byDecMode == KEY_CTL_CCMP)) { + // TKIP/AES + + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc + *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16); + if (byDecMode == KEY_CTL_TKIP) { + *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV + 2), *pbyIV)); + } else { + *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0); + + if ((byDecMode == KEY_CTL_TKIP) && + (pDevice->byLocalID <= REV_ID_VT3253_A1)) { + // Software TKIP + // 1. 3253 A + PS802_11Header pMACHeader = (PS802_11Header)(pbyFrame); + TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); + rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); + rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); + if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { + *pbyNewRsr |= NEWRSR_DECRYPTOK; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n"); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen); + } + } + }// end of TKIP/AES + + if ((*(pbyIV+3) & 0x20) != 0) + *pbExtIV = true; + return true; } -static bool s_bHostWepRxEncryption ( - PSDevice pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 - ) +static bool s_bHostWepRxEncryption( + PSDevice pDevice, + unsigned char *pbyFrame, + unsigned int FrameSize, + unsigned char *pbyRsr, + bool bOnFly, + PSKeyItem pKey, + unsigned char *pbyNewRsr, + bool *pbExtIV, + unsigned short *pwRxTSC15_0, + unsigned long *pdwRxTSC47_16 +) { - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - unsigned char byDecMode = KEY_CTL_WEP; - PS802_11Header pMACHeader; + unsigned int PayloadLen = FrameSize; + unsigned char *pbyIV; + unsigned char byKeyIdx; + unsigned char byDecMode = KEY_CTL_WEP; + PS802_11Header pMACHeader; - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; + *pwRxTSC15_0 = 0; + *pdwRxTSC47_16 = 0; - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame) ) { - pbyIV += 6; // 6 is 802.11 address4 - PayloadLen -= 6; - } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx); + pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; + if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && + WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { + pbyIV += 6; // 6 is 802.11 address4 + PayloadLen -= 6; + } + byKeyIdx = (*(pbyIV+3) & 0xc0); + byKeyIdx >>= 6; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; + if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) + byDecMode = KEY_CTL_TKIP; + else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) + byDecMode = KEY_CTL_CCMP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); - if (byDecMode != pKey->byCipherSuite) { - if (byDecMode == KEY_CTL_WEP) { + if (byDecMode != pKey->byCipherSuite) { + if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass == true) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; - } - return false; - } - - if (byDecMode == KEY_CTL_WEP) { - // handle WEP - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n"); - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || - (bOnFly == false)) { - // Software WEP - // 1. 3253A - // 2. WEP 256 - // 3. NotOnFly - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); - - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - } - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); - - if (byDecMode == KEY_CTL_TKIP) { - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); - } else { - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); - - if (byDecMode == KEY_CTL_TKIP) { - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) { - // Software TKIP - // 1. 3253 A - // 2. NotOnFly - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n"); - pMACHeader = (PS802_11Header) (pbyFrame); - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n"); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen); - } - } - } - - if (byDecMode == KEY_CTL_CCMP) { - if (bOnFly == false) { - // Software CCMP - // NotOnFly - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n"); - if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n"); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n"); - } - } - } - - }// end of TKIP/AES - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; - return true; + } + return false; + } + + if (byDecMode == KEY_CTL_WEP) { + // handle WEP + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP \n"); + if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || + (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || + (bOnFly == false)) { + // Software WEP + // 1. 3253A + // 2. WEP 256 + // 3. NotOnFly + + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc + memcpy(pDevice->abyPRNG, pbyIV, 3); + memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); + rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); + rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); + + if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { + *pbyNewRsr |= NEWRSR_DECRYPTOK; + } + } + } else if ((byDecMode == KEY_CTL_TKIP) || + (byDecMode == KEY_CTL_CCMP)) { + // TKIP/AES + + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc + *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16); + + if (byDecMode == KEY_CTL_TKIP) { + *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); + } else { + *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0); + + if (byDecMode == KEY_CTL_TKIP) { + + if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) { + // Software TKIP + // 1. 3253 A + // 2. NotOnFly + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_TKIP \n"); + pMACHeader = (PS802_11Header)(pbyFrame); + TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); + rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); + rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); + if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { + *pbyNewRsr |= NEWRSR_DECRYPTOK; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n"); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen); + } + } + } + + if (byDecMode == KEY_CTL_CCMP) { + if (bOnFly == false) { + // Software CCMP + // NotOnFly + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_CCMP\n"); + if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { + *pbyNewRsr |= NEWRSR_DECRYPTOK; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC compare OK!\n"); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC fail!\n"); + } + } + } + + }// end of TKIP/AES + + if ((*(pbyIV+3) & 0x20) != 0) + *pbExtIV = true; + return true; } -static bool s_bAPModeRxData ( - PSDevice pDevice, - struct sk_buff* skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex - ) +static bool s_bAPModeRxData( + PSDevice pDevice, + struct sk_buff *skb, + unsigned int FrameSize, + unsigned int cbHeaderOffset, + int iSANodeIndex, + int iDANodeIndex +) { - PSMgmtObject pMgmt = pDevice->pMgmt; - bool bRelayAndForward = false; - bool bRelayOnly = false; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - - - struct sk_buff* skbcpy = NULL; - - if (FrameSize > CB_MAX_BUF_SIZE) - return false; - // check DA - if(is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) { - if (pMgmt->sNodeDBTable[0].bPSEnable) { - - skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); - - // if any node in PS mode, buffer packet until DTIM. - if (skbcpy == NULL) { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n"); - } - else { - skbcpy->dev = pDevice->dev; - skbcpy->len = FrameSize; - memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize); - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); - - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - } - } - else { - bRelayAndForward = true; - } - } - else { - // check if relay - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { - if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { - if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { - // queue this skb until next PS tx, and then release. - - skb->data += cbHeaderOffset; - skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; - wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", - iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); - return true; - } - else { - bRelayOnly = true; - } - } - } - } - - if (bRelayOnly || bRelayAndForward) { - // relay this packet right now - if (bRelayAndForward) - iDANodeIndex = 0; - - if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) { - ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex); - } - - if (bRelayOnly) - return false; - } - // none associate, don't forward - if (pDevice->uAssocCount == 0) - return false; - - return true; + PSMgmtObject pMgmt = pDevice->pMgmt; + bool bRelayAndForward = false; + bool bRelayOnly = false; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + unsigned short wAID; + + + struct sk_buff *skbcpy = NULL; + + if (FrameSize > CB_MAX_BUF_SIZE) + return false; + // check DA + if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) { + if (pMgmt->sNodeDBTable[0].bPSEnable) { + + skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); + + // if any node in PS mode, buffer packet until DTIM. + if (skbcpy == NULL) { + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n"); + } + else { + skbcpy->dev = pDevice->dev; + skbcpy->len = FrameSize; + memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize); + skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); + + pMgmt->sNodeDBTable[0].wEnQueueCnt++; + // set tx map + pMgmt->abyPSTxMap[0] |= byMask[0]; + } + } + else { + bRelayAndForward = true; + } + } + else { + // check if relay + if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { + if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { + if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { + // queue this skb until next PS tx, and then release. + + skb->data += cbHeaderOffset; + skb->tail += cbHeaderOffset; + skb_put(skb, FrameSize); + skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb); + pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; + wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; + pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", + iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); + return true; + } + else { + bRelayOnly = true; + } + } + } + } + + if (bRelayOnly || bRelayAndForward) { + // relay this packet right now + if (bRelayAndForward) + iDANodeIndex = 0; + + if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) { + ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex); + } + + if (bRelayOnly) + return false; + } + // none associate, don't forward + if (pDevice->uAssocCount == 0) + return false; + + return true; } diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index c1b6e76a421f..9b34176d9c12 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -42,10 +42,10 @@ /*--------------------- Export Functions --------------------------*/ bool -device_receive_frame ( - PSDevice pDevice, - PSRxDesc pCurrRD - ); +device_receive_frame( + PSDevice pDevice, + PSRxDesc pCurrRD +); void MngWorkItem(void *Context); -- cgit From 4b61d809a58a5a918b515570e46197b5496648c9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:49 -0700 Subject: staging:vt6655:hostap: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/hostap.c | 666 ++++++++++++++++++++-------------------- 1 file changed, 333 insertions(+), 333 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 5f13890cf124..0d42159a7045 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -49,7 +49,7 @@ /*--------------------- Static Variables --------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ @@ -75,21 +75,21 @@ static int msglevel =MSG_LEVEL_INFO; static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) { - PSDevice apdev_priv; + PSDevice apdev_priv; struct net_device *dev = pDevice->dev; int ret; const struct net_device_ops apdev_netdev_ops = { .ndo_start_xmit = pDevice->tx_80211, }; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL); if (pDevice->apdev == NULL) return -ENOMEM; - apdev_priv = netdev_priv(pDevice->apdev); - *apdev_priv = *pDevice; + apdev_priv = netdev_priv(pDevice->apdev); + *apdev_priv = *pDevice; memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN); pDevice->apdev->netdev_ops = &apdev_netdev_ops; @@ -107,14 +107,14 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) ret = register_netdev(pDevice->apdev); if (ret) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n", - dev->name); + dev->name); return -1; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n", - dev->name, pDevice->apdev->name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n", + dev->name, pDevice->apdev->name); - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); + KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); return 0; } @@ -136,27 +136,27 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name); - if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) { + if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) { if (rtnl_locked) unregister_netdevice(pDevice->apdev); else unregister_netdev(pDevice->apdev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->apdev->name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", + pDevice->dev->name, pDevice->apdev->name); } kfree(pDevice->apdev); pDevice->apdev = NULL; - pDevice->bEnable8021x = false; - pDevice->bEnableHostWEP = false; - pDevice->bEncryptionEnable = false; + pDevice->bEnable8021x = false; + pDevice->bEnableHostWEP = false; + pDevice->bEncryptionEnable = false; //4.2007-0118-03, by EinsnLiu //execute some clear work -pDevice->pMgmt->byCSSPK=KEY_CTL_NONE; -pDevice->pMgmt->byCSSGK=KEY_CTL_NONE; -KeyvInitTable(&pDevice->sKey,pDevice->PortOffset); + pDevice->pMgmt->byCSSPK = KEY_CTL_NONE; + pDevice->pMgmt->byCSSGK = KEY_CTL_NONE; + KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); return 0; } @@ -207,17 +207,17 @@ int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) * */ static int hostap_remove_sta(PSDevice pDevice, - struct viawget_hostapd_param *param) + struct viawget_hostapd_param *param) { unsigned int uNodeIndex; - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) { - BSSvRemoveOneNode(pDevice, uNodeIndex); - } - else { - return -ENOENT; - } + if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) { + BSSvRemoveOneNode(pDevice, uNodeIndex); + } + else { + return -ENOENT; + } return 0; } @@ -235,47 +235,47 @@ static int hostap_remove_sta(PSDevice pDevice, * */ static int hostap_add_sta(PSDevice pDevice, - struct viawget_hostapd_param *param) + struct viawget_hostapd_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; - if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); - } - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; + if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { + BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); + } + memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; + pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; // TODO listenInterval // pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1; - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - // set max basic rate - pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; - // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); - - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid; - - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", - param->sta_addr[0], - param->sta_addr[1], - param->sta_addr[2], - param->sta_addr[3], - param->sta_addr[4], - param->sta_addr[5] - ) ; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); + pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false; + pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; + + // set max tx rate + pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; + // set max basic rate + pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; + // Todo: check sta preamble, if ap can't support, set status code + pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = + WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); + + pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid; + + pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", + param->sta_addr[0], + param->sta_addr[1], + param->sta_addr[2], + param->sta_addr[3], + param->sta_addr[4], + param->sta_addr[5] + ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n", + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); return 0; } @@ -295,19 +295,19 @@ static int hostap_add_sta(PSDevice pDevice, */ static int hostap_get_info_sta(PSDevice pDevice, - struct viawget_hostapd_param *param) + struct viawget_hostapd_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - param->u.get_info_sta.inactive_sec = - (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; + if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { + param->u.get_info_sta.inactive_sec = + (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; - //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts; + //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts; } else { - return -ENOENT; + return -ENOENT; } return 0; @@ -328,21 +328,21 @@ static int hostap_get_info_sta(PSDevice pDevice, * */ /* -static int hostap_reset_txexc_sta(PSDevice pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0; - } - else { - return -ENOENT; - } - - return 0; -} + static int hostap_reset_txexc_sta(PSDevice pDevice, + struct viawget_hostapd_param *param) + { + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int uNodeIndex; + + if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { + pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0; + } + else { + return -ENOENT; + } + + return 0; + } */ /* @@ -359,19 +359,19 @@ static int hostap_reset_txexc_sta(PSDevice pDevice, * */ static int hostap_set_flags_sta(PSDevice pDevice, - struct viawget_hostapd_param *param) + struct viawget_hostapd_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { + if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n", - (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); + (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { - return -ENOENT; + return -ENOENT; } return 0; @@ -393,34 +393,34 @@ static int hostap_set_flags_sta(PSDevice pDevice, * */ static int hostap_set_generic_element(PSDevice pDevice, - struct viawget_hostapd_param *param) + struct viawget_hostapd_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; - memcpy( pMgmt->abyWPAIE, - param->u.generic_elem.data, - param->u.generic_elem.len - ); + memcpy(pMgmt->abyWPAIE, + param->u.generic_elem.data, + param->u.generic_elem.len + ); - pMgmt->wWPAIELen = param->u.generic_elem.len; + pMgmt->wWPAIELen = param->u.generic_elem.len; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); - // disable wpa - if (pMgmt->wWPAIELen == 0) { - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; + // disable wpa + if (pMgmt->wWPAIELen == 0) { + pMgmt->eAuthenMode = WMAC_AUTH_OPEN; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n"); - } else { - // enable wpa - if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) || - (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) { - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n"); - } else - return -EINVAL; - } + } else { + // enable wpa + if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) || + (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) { + pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n"); + } else + return -EINVAL; + } return 0; } @@ -440,11 +440,11 @@ static int hostap_set_generic_element(PSDevice pDevice, static void hostap_flush_sta(PSDevice pDevice) { - // reserved node index =0 for multicast node. - BSSvClearNodeDBTable(pDevice, 1); - pDevice->uAssocCount = 0; + // reserved node index =0 for multicast node. + BSSvClearNodeDBTable(pDevice, 1); + pDevice->uAssocCount = 0; - return; + return; } /* @@ -461,15 +461,15 @@ static void hostap_flush_sta(PSDevice pDevice) * */ static int hostap_set_encryption(PSDevice pDevice, - struct viawget_hostapd_param *param, - int param_len) + struct viawget_hostapd_param *param, + int param_len) { - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - NDIS_802_11_KEY_RSC KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned long dwKeyIndex = 0; + unsigned char abyKey[MAX_KEY_LEN]; + unsigned char abySeq[MAX_KEY_LEN]; + NDIS_802_11_KEY_RSC KeyRSC; + unsigned char byKeyDecMode = KEY_CTL_WEP; int ret = 0; int iNodeIndex = -1; int ii; @@ -479,10 +479,10 @@ static int hostap_set_encryption(PSDevice pDevice, param->u.crypt.err = 0; /* - if (param_len != - (int) ((char *) param->u.crypt.key - (char *) param) + - param->u.crypt.key_len) - return -EINVAL; + if (param_len != + (int) ((char *) param->u.crypt.key - (char *) param) + + param->u.crypt.key_len) + return -EINVAL; */ if (param->u.crypt.alg > WPA_ALG_CCMP) @@ -498,105 +498,105 @@ static int hostap_set_encryption(PSDevice pDevice, if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= MAX_GROUP_KEY) return -EINVAL; - iNodeIndex = 0; + iNodeIndex = 0; } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } + if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { + param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); + return -EINVAL; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); if (param->u.crypt.alg == WPA_ALG_NONE) { - if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) { - if (KeybRemoveKey(&(pDevice->sKey), - param->sta_addr, - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, - pDevice->PortOffset) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); - } - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - } - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; - pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; - memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - 0, - MAX_KEY_LEN - ); - - return ret; + if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) { + if (KeybRemoveKey(&(pDevice->sKey), + param->sta_addr, + pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, + pDevice->PortOffset) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); + } + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; + } + pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; + pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; + pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; + pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; + pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; + pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; + pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; + memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], + 0, + MAX_KEY_LEN +); + + return ret; } - memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); - // copy to node key tbl - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; - memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - param->u.crypt.key, - param->u.crypt.key_len - ); - - dwKeyIndex = (unsigned long)(param->u.crypt.idx); - if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } + memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); + // copy to node key tbl + pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; + pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; + memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], + param->u.crypt.key, + param->u.crypt.key_len +); + + dwKeyIndex = (unsigned long)(param->u.crypt.idx); + if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { + pDevice->byKeyIndex = (unsigned char)dwKeyIndex; + pDevice->bTransmitKey = true; + dwKeyIndex |= (1 << 31); + } if (param->u.crypt.alg == WPA_ALG_WEP) { - if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.crypt.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } else { - // 8021x enable, individual key - dwKeyIndex |= (1 << 30); // set pairwise key - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex & ~(USE_KEYRSC), - param->u.crypt.key_len, - (PQWORD) &(KeyRSC), - (unsigned char *)abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID) == true) { - - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - // Key Table Full - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - } - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - return ret; + if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { + KeybSetDefaultKey(&(pDevice->sKey), + dwKeyIndex & ~(BIT30 | USE_KEYRSC), + param->u.crypt.key_len, + NULL, + abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID); + + } else { + // 8021x enable, individual key + dwKeyIndex |= (1 << 30); // set pairwise key + if (KeybSetKey(&(pDevice->sKey), + ¶m->sta_addr[0], + dwKeyIndex & ~(USE_KEYRSC), + param->u.crypt.key_len, + (PQWORD) &(KeyRSC), + (unsigned char *)abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID) == true) { + + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; + + } else { + // Key Table Full + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; + bKeyTableFull = true; + } + } + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + pDevice->bEncryptionEnable = true; + pMgmt->byCSSPK = KEY_CTL_WEP; + pMgmt->byCSSGK = KEY_CTL_WEP; + pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; + pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; + return ret; } if (param->u.crypt.seq) { - memcpy(&abySeq, param->u.crypt.seq, 8); - for (ii = 0 ; ii < 8 ; ii++) + memcpy(&abySeq, param->u.crypt.seq, 8); + for (ii = 0; ii < 8; ii++) KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); dwKeyIndex |= 1 << 29; @@ -604,85 +604,85 @@ static int hostap_set_encryption(PSDevice pDevice, } if (param->u.crypt.alg == WPA_ALG_TKIP) { - if (param->u.crypt.key_len != MAX_KEY_LEN) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - byKeyDecMode = KEY_CTL_TKIP; - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; + if (param->u.crypt.key_len != MAX_KEY_LEN) + return -EINVAL; + pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; + byKeyDecMode = KEY_CTL_TKIP; + pMgmt->byCSSPK = KEY_CTL_TKIP; + pMgmt->byCSSGK = KEY_CTL_TKIP; } if (param->u.crypt.alg == WPA_ALG_CCMP) { - if ((param->u.crypt.key_len != AES_KEY_LEN) || - (pDevice->byLocalID <= REV_ID_VT3253_A1)) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - byKeyDecMode = KEY_CTL_CCMP; - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } - - - if (iNodeIndex == 0) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.crypt.key_len, - (PQWORD) &(KeyRSC), - abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID); - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - dwKeyIndex |= (1 << 30); // set pairwise key - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex, - param->u.crypt.key_len, - (PQWORD) &(KeyRSC), - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) == true) { - - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - // Key Table Full - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); - } - - } - - if (bKeyTableFull == true) { - wKeyCtl &= 0x7F00; // clear all key control filed - wKeyCtl |= (byKeyDecMode << 4); - wKeyCtl |= (byKeyDecMode); - wKeyCtl |= 0x0044; // use group key for all address - wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int - MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx, - param->u.crypt.key_len ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] - ); + if ((param->u.crypt.key_len != AES_KEY_LEN) || + (pDevice->byLocalID <= REV_ID_VT3253_A1)) + return -EINVAL; + pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; + byKeyDecMode = KEY_CTL_CCMP; + pMgmt->byCSSPK = KEY_CTL_CCMP; + pMgmt->byCSSGK = KEY_CTL_CCMP; + } + + + if (iNodeIndex == 0) { + KeybSetDefaultKey(&(pDevice->sKey), + dwKeyIndex, + param->u.crypt.key_len, + (PQWORD) &(KeyRSC), + abyKey, + byKeyDecMode, + pDevice->PortOffset, + pDevice->byLocalID); + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; + + } else { + dwKeyIndex |= (1 << 30); // set pairwise key + if (KeybSetKey(&(pDevice->sKey), + ¶m->sta_addr[0], + dwKeyIndex, + param->u.crypt.key_len, + (PQWORD) &(KeyRSC), + (unsigned char *)abyKey, + byKeyDecMode, + pDevice->PortOffset, + pDevice->byLocalID) == true) { + + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; + + } else { + // Key Table Full + pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; + bKeyTableFull = true; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); + } + + } + + if (bKeyTableFull == true) { + wKeyCtl &= 0x7F00; // clear all key control filed + wKeyCtl |= (byKeyDecMode << 4); + wKeyCtl |= (byKeyDecMode); + wKeyCtl |= 0x0044; // use group key for all address + wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int + MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx, + param->u.crypt.key_len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] +); // set wep key - pDevice->bEncryptionEnable = true; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; + pDevice->bEncryptionEnable = true; + pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; + pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; + pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; + pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; return ret; } @@ -703,31 +703,31 @@ static int hostap_set_encryption(PSDevice pDevice, * */ static int hostap_get_encryption(PSDevice pDevice, - struct viawget_hostapd_param *param, - int param_len) + struct viawget_hostapd_param *param, + int param_len) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; int ret = 0; int ii; - int iNodeIndex =0; + int iNodeIndex = 0; param->u.crypt.err = 0; if (is_broadcast_ether_addr(param->sta_addr)) { - iNodeIndex = 0; + iNodeIndex = 0; } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } + if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { + param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); + return -EINVAL; + } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); - memset(param->u.crypt.seq, 0, 8); - for (ii = 0 ; ii < 8 ; ii++) { - param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); - } + memset(param->u.crypt.seq, 0, 8); + for (ii = 0; ii < 8; ii++) { + param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); + } return ret; } @@ -768,75 +768,75 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) switch (param->cmd) { case VIAWGET_HOSTAPD_SET_ENCRYPTION: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n"); - spin_lock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n"); + spin_lock_irq(&pDevice->lock); ret = hostap_set_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_HOSTAPD_GET_ENCRYPTION: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n"); - spin_lock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n"); + spin_lock_irq(&pDevice->lock); ret = hostap_get_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n"); return -EOPNOTSUPP; break; case VIAWGET_HOSTAPD_FLUSH: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n"); - spin_lock_irq(&pDevice->lock); - hostap_flush_sta(pDevice); - spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n"); + spin_lock_irq(&pDevice->lock); + hostap_flush_sta(pDevice); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_HOSTAPD_ADD_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_add_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n"); + spin_lock_irq(&pDevice->lock); + ret = hostap_add_sta(pDevice, param); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_HOSTAPD_REMOVE_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_remove_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n"); + spin_lock_irq(&pDevice->lock); + ret = hostap_remove_sta(pDevice, param); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_HOSTAPD_GET_INFO_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n"); - ret = hostap_get_info_sta(pDevice, param); - ap_ioctl = 1; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n"); + ret = hostap_get_info_sta(pDevice, param); + ap_ioctl = 1; break; /* case VIAWGET_HOSTAPD_RESET_TXEXC_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n"); - ret = hostap_reset_txexc_sta(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n"); + ret = hostap_reset_txexc_sta(pDevice, param); break; */ case VIAWGET_HOSTAPD_SET_FLAGS_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n"); - ret = hostap_set_flags_sta(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n"); + ret = hostap_set_flags_sta(pDevice, param); break; case VIAWGET_HOSTAPD_MLME: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n"); - return -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n"); + return -EOPNOTSUPP; case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n"); ret = hostap_set_generic_element(pDevice, param); break; case VIAWGET_HOSTAPD_SCAN_REQ: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n"); - return -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n"); + return -EOPNOTSUPP; case VIAWGET_HOSTAPD_STA_CLEAR_STATS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n"); - return -EOPNOTSUPP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n"); + return -EOPNOTSUPP; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n", - (int)param->cmd); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n", + (int)param->cmd); return -EOPNOTSUPP; break; } @@ -849,7 +849,7 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) } } - out: +out: kfree(param); return ret; -- cgit From 5f256874a5b462e53479d3270bc747966f57d679 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:50 -0700 Subject: staging:vt6655:iocmd: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iocmd.h | 200 ++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h index 166351bb71a6..68df79131c97 100644 --- a/drivers/staging/vt6655/iocmd.h +++ b/drivers/staging/vt6655/iocmd.h @@ -48,34 +48,34 @@ typedef enum tagWMAC_CMD { - WLAN_CMD_BSS_SCAN, - WLAN_CMD_BSS_JOIN, - WLAN_CMD_DISASSOC, - WLAN_CMD_SET_WEP, - WLAN_CMD_GET_LINK, - WLAN_CMD_GET_LISTLEN, - WLAN_CMD_GET_LIST, - WLAN_CMD_GET_MIB, - WLAN_CMD_GET_STAT, - WLAN_CMD_STOP_MAC, - WLAN_CMD_START_MAC, - WLAN_CMD_AP_START, - WLAN_CMD_SET_HOSTAPD, - WLAN_CMD_SET_HOSTAPD_STA, - WLAN_CMD_SET_802_1X, - WLAN_CMD_SET_HOST_WEP, - WLAN_CMD_SET_WPA, - WLAN_CMD_GET_NODE_CNT, - WLAN_CMD_ZONETYPE_SET, - WLAN_CMD_GET_NODE_LIST + WLAN_CMD_BSS_SCAN, + WLAN_CMD_BSS_JOIN, + WLAN_CMD_DISASSOC, + WLAN_CMD_SET_WEP, + WLAN_CMD_GET_LINK, + WLAN_CMD_GET_LISTLEN, + WLAN_CMD_GET_LIST, + WLAN_CMD_GET_MIB, + WLAN_CMD_GET_STAT, + WLAN_CMD_STOP_MAC, + WLAN_CMD_START_MAC, + WLAN_CMD_AP_START, + WLAN_CMD_SET_HOSTAPD, + WLAN_CMD_SET_HOSTAPD_STA, + WLAN_CMD_SET_802_1X, + WLAN_CMD_SET_HOST_WEP, + WLAN_CMD_SET_WPA, + WLAN_CMD_GET_NODE_CNT, + WLAN_CMD_ZONETYPE_SET, + WLAN_CMD_GET_NODE_LIST } WMAC_CMD, *PWMAC_CMD; typedef enum tagWZONETYPE { - ZoneType_USA=0, - ZoneType_Japan=1, - ZoneType_Europe=2 -}WZONETYPE; + ZoneType_USA = 0, + ZoneType_Japan = 1, + ZoneType_Europe = 2 +} WZONETYPE; #define ADHOC 0 #define INFRA 1 @@ -86,7 +86,7 @@ typedef enum tagWZONETYPE { #define ADHOC_JOINTED 2 -#define PHY80211a 0 +#define PHY80211a 0 #define PHY80211b 1 #define PHY80211g 2 @@ -127,12 +127,12 @@ typedef struct tagSCmdScan { typedef struct tagSCmdBSSJoin { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - bool bPSEnable; - bool bShareKeyAuth; + u16 wBSSType; + u16 wBBPType; + u8 ssid[SSID_MAXLEN + 2]; + u32 uChannel; + bool bPSEnable; + bool bShareKeyAuth; } SCmdBSSJoin, *PSCmdBSSJoin; @@ -142,41 +142,41 @@ typedef struct tagSCmdBSSJoin { typedef struct tagSCmdZoneTypeSet { - bool bWrite; - WZONETYPE ZoneType; + bool bWrite; + WZONETYPE ZoneType; } SCmdZoneTypeSet, *PSCmdZoneTypeSet; #ifdef WPA_SM_Transtatus typedef struct tagSWPAResult { - char ifname[100]; - u8 proto; - u8 key_mgmt; - u8 eap_type; - bool authenticated; + char ifname[100]; + u8 proto; + u8 key_mgmt; + u8 eap_type; + bool authenticated; } SWPAResult, *PSWPAResult; #endif typedef struct tagSCmdStartAP { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uBeaconInt; - bool bShareKeyAuth; - u8 byBasicRate; + u16 wBSSType; + u16 wBBPType; + u8 ssid[SSID_MAXLEN + 2]; + u32 uChannel; + u32 uBeaconInt; + bool bShareKeyAuth; + u8 byBasicRate; } SCmdStartAP, *PSCmdStartAP; typedef struct tagSCmdSetWEP { - bool bEnableWep; - u8 byKeyIndex; - u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; - bool bWepKeyAvailable[WEP_NKEYS]; - u32 auWepKeyLength[WEP_NKEYS]; + bool bEnableWep; + u8 byKeyIndex; + u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; + bool bWepKeyAvailable[WEP_NKEYS]; + u32 auWepKeyLength[WEP_NKEYS]; } SCmdSetWEP, *PSCmdSetWEP; @@ -185,18 +185,18 @@ typedef struct tagSCmdSetWEP { typedef struct tagSBSSIDItem { u32 uChannel; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 1]; - //2006-1116-01, by NomadZhao - //u16 wBeaconInterval; - //u16 wCapInfo; - //u8 byNetType; - u8 byNetType; - u16 wBeaconInterval; - u16 wCapInfo; // for address of byNetType at align 4 - - bool bWEPOn; - u32 uRSSI; + u8 abyBSSID[BSSID_LEN]; + u8 abySSID[SSID_MAXLEN + 1]; + //2006-1116-01, by NomadZhao + //u16 wBeaconInterval; + //u16 wCapInfo; + //u8 byNetType; + u8 byNetType; + u16 wBeaconInterval; + u16 wCapInfo; // for address of byNetType at align 4 + + bool bWEPOn; + u32 uRSSI; } SBSSIDItem; @@ -210,13 +210,13 @@ typedef struct tagSBSSIDList { typedef struct tagSCmdLinkStatus { - bool bLink; + bool bLink; u16 wBSSType; u8 byState; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uLinkRate; + u8 abyBSSID[BSSID_LEN]; + u8 abySSID[SSID_MAXLEN + 2]; + u32 uChannel; + u32 uLinkRate; } SCmdLinkStatus, *PSCmdLinkStatus; @@ -244,9 +244,9 @@ typedef struct tagSDot11MIBCount { // statistic counter // typedef struct tagSStatMIBCount { - // - // ISR status count - // + // + // ISR status count + // u32 dwIsrTx0OK; u32 dwIsrTx1OK; u32 dwIsrBeaconTxOK; @@ -256,12 +256,12 @@ typedef struct tagSStatMIBCount { u32 dwIsrUnrecoverableError; u32 dwIsrSoftInterrupt; u32 dwIsrRxNoBuf; - ///////////////////////////////////// + ///////////////////////////////////// u32 dwIsrUnknown; // unknown interrupt count - // RSR status count - // + // RSR status count + // u32 dwRsrFrmAlgnErr; u32 dwRsrErr; u32 dwRsrCRCErr; @@ -282,10 +282,10 @@ typedef struct tagSStatMIBCount { u32 dwRsrBroadcast; u32 dwRsrMulticast; u32 dwRsrDirected; - // 64-bit OID + // 64-bit OID u32 ullRsrOK; - // for some optional OIDs (64 bits) and DMI support + // for some optional OIDs (64 bits) and DMI support u32 ullRxBroadcastBytes; u32 ullRxMulticastBytes; u32 ullRxDirectedBytes; @@ -301,13 +301,13 @@ typedef struct tagSStatMIBCount { u32 dwRsrRxFrmLen512_1023; u32 dwRsrRxFrmLen1024_1518; - // TSR0,1 status count - // + // TSR0,1 status count + // u32 dwTsrTotalRetry[2]; // total collision retry count u32 dwTsrOnceRetry[2]; // this packet only occur one collision u32 dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision u32 dwTsrRetry[2]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) + // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) u32 dwTsrACKData[2]; u32 dwTsrErr[2]; u32 dwAllTsrOK[2]; @@ -320,23 +320,23 @@ typedef struct tagSStatMIBCount { u32 dwTsrMulticast[2]; u32 dwTsrDirected[2]; - // RD/TD count + // RD/TD count u32 dwCntRxFrmLength; u32 dwCntTxBufLength; u8 abyCntRxPattern[16]; u8 abyCntTxPattern[16]; - // Software check.... + // Software check.... u32 dwCntRxDataErr; // rx buffer data software compare CRC err count u32 dwCntDecryptErr; // rx buffer data software compare CRC err count u32 dwCntRxICVErr; // rx buffer data software compare CRC err count u32 idxRxErrorDesc; // index for rx data error RD - // 64-bit OID + // 64-bit OID u32 ullTsrOK[2]; - // for some optional OIDs (64 bits) and DMI support + // for some optional OIDs (64 bits) and DMI support u32 ullTxBroadcastFrames[2]; u32 ullTxMulticastFrames[2]; u32 ullTxDirectedFrames[2]; @@ -347,22 +347,22 @@ typedef struct tagSStatMIBCount { typedef struct tagSNodeItem { - // STA info - u16 wAID; - u8 abyMACAddr[6]; - u16 wTxDataRate; - u16 wInActiveCount; - u16 wEnQueueCnt; - u16 wFlags; - bool bPWBitOn; - u8 byKeyIndex; - u16 wWepKeyLength; - u8 abyWepKey[WEP_KEYMAXLEN]; - // Auto rate fallback vars - bool bIsInFallback; - u32 uTxFailures; - u32 uTxAttempts; - u16 wFailureRatio; + // STA info + u16 wAID; + u8 abyMACAddr[6]; + u16 wTxDataRate; + u16 wInActiveCount; + u16 wEnQueueCnt; + u16 wFlags; + bool bPWBitOn; + u8 byKeyIndex; + u16 wWepKeyLength; + u8 abyWepKey[WEP_KEYMAXLEN]; + // Auto rate fallback vars + bool bIsInFallback; + u32 uTxFailures; + u32 uTxAttempts; + u16 wFailureRatio; } SNodeItem; @@ -405,8 +405,8 @@ enum { }; -#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ -((int) (&((struct viawget_hostapd_param *) 0)->u.generic_elem.data)) +#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ + ((int)(&((struct viawget_hostapd_param *)0)->u.generic_elem.data)) // Maximum length for algorithm names (-1 for nul termination) used in ioctl() -- cgit From 281c7462f18c6de0c33440b88d2bddbc5abddb09 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:51 -0700 Subject: staging:vt6655:ioctl: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.c | 16 ++++++++-------- drivers/staging/vt6655/ioctl.h | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index afed6e33dfc7..2ae8116869eb 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -41,7 +41,7 @@ static int msglevel = MSG_LEVEL_INFO; #ifdef WPA_SM_Transtatus - SWPAResult wpa_Result; +SWPAResult wpa_Result; #endif int private_ioctl(PSDevice pDevice, struct ifreq *rq) @@ -104,9 +104,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); if (pItemSSID->len != 0) - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); else - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -202,8 +202,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -267,7 +267,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success!\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Link Success!\n"); } else { sLinkStatus.bLink = false; sLinkStatus.uLinkRate = 0; @@ -311,7 +311,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } pList->uItem = sList.uItem; pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { + for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { pBSS = &(pMgmt->sBSSList[jj]); if (pBSS->bActive) { pList->sBSSIDList[ii].uChannel = pBSS->uChannel; @@ -540,7 +540,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n", - 4, pMgmt->abyIBSSSuppRates + 2); + 4, pMgmt->abyIBSSSuppRates + 2); netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h index ba85015c11b6..d26a8daa3111 100644 --- a/drivers/staging/vt6655/ioctl.h +++ b/drivers/staging/vt6655/ioctl.h @@ -43,12 +43,12 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq); /* -void vConfigWEPKey ( - PSDevice pDevice, - unsigned long dwKeyIndex, - unsigned char *pbyKey, - unsigned long uKeyLength - ); + void vConfigWEPKey( + PSDevice pDevice, + unsigned long dwKeyIndex, + unsigned char *pbyKey, + unsigned long uKeyLength +); */ #endif // __IOCTL_H__ -- cgit From 722bf5eef72c71d6892678e1b0bd5e745a7c3ae5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:52 -0700 Subject: staging:vt6655:iowpa: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iowpa.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h index 33ae054478dc..1e260022d36a 100644 --- a/drivers/staging/vt6655/iowpa.h +++ b/drivers/staging/vt6655/iowpa.h @@ -37,11 +37,11 @@ //WPA related /* -typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; -typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, - CIPHER_WEP104 } wpa_cipher; -typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, - KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt; + typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; + typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, + CIPHER_WEP104 } wpa_cipher; + typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, + KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt; */ enum { @@ -54,7 +54,7 @@ enum { VIAWGET_SET_DROP_UNENCRYPT = 7, VIAWGET_SET_DEAUTHENTICATE = 8, VIAWGET_SET_ASSOCIATE = 9, - VIAWGET_SET_DISASSOCIATE= 10 + VIAWGET_SET_DISASSOCIATE = 10 }; @@ -88,27 +88,27 @@ struct viawget_wpa_param { } generic_elem; struct { - u8 bssid[6]; + u8 bssid[6]; u8 ssid[32]; u8 ssid_len; - u8 *wpa_ie; - u16 wpa_ie_len; - int pairwise_suite; - int group_suite; - int key_mgmt_suite; - int auth_alg; - int mode; + u8 *wpa_ie; + u16 wpa_ie_len; + int pairwise_suite; + int group_suite; + int key_mgmt_suite; + int auth_alg; + int mode; } wpa_associate; struct { - int alg_name; - u16 key_index; - u16 set_tx; - u8 *seq; - u16 seq_len; - u8 *key; - u16 key_len; + int alg_name; + u16 key_index; + u16 set_tx; + u8 *seq; + u16 seq_len; + u8 *key; + u16 key_len; } wpa_key; struct { -- cgit From 6da16f96554e5003fd8f3ffdf2caf21335c43623 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:53 -0700 Subject: staging:vt6655:iwctl: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iwctl.c | 2170 ++++++++++++++++++++-------------------- drivers/staging/vt6655/iwctl.h | 200 ++-- 2 files changed, 1185 insertions(+), 1185 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 5cdda8dab854..5b70209a2adb 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -57,19 +57,19 @@ extern unsigned short TxRate_iwconfig;//2008-5-8 by chester #endif static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, - 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, - 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, - 5700, 5745, 5765, 5785, 5805, 5825 - }; + 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, + 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, + 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, + 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, + 5700, 5745, 5765, 5785, 5805, 5825 +}; /*--------------------- Static Classes ----------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ @@ -83,13 +83,13 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) long ldBm; pDevice->wstats.status = pDevice->eOPMode; - #ifdef Calcu_LinkQual - if(pDevice->scStatistic.LinkQuality > 100) - pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual =(unsigned char) pDevice->scStatistic.LinkQuality; - #else +#ifdef Calcu_LinkQual + if (pDevice->scStatistic.LinkQuality > 100) + pDevice->scStatistic.LinkQuality = 100; + pDevice->wstats.qual.qual = (unsigned char)pDevice->scStatistic.LinkQuality; +#else pDevice->wstats.qual.qual = pDevice->byCurrSQ; - #endif +#endif RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI; @@ -111,11 +111,11 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) static int iwctl_commit(struct net_device *dev, - struct iw_request_info *info, - void *wrq, - char *extra) + struct iw_request_info *info, + void *wrq, + char *extra) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n"); return 0; @@ -125,9 +125,9 @@ static int iwctl_commit(struct net_device *dev, */ int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra) + struct iw_request_info *info, + char *wrq, + char *extra) { strcpy(wrq, "802.11-a/b/g"); return 0; @@ -138,62 +138,62 @@ int iwctl_giwname(struct net_device *dev, */ int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_scan_req *req = (struct iw_scan_req *)extra; unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - PWLAN_IE_SSID pItemSSID=NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n"); + PWLAN_IE_SSID pItemSSID = NULL; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n"); -if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! + if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! //send scan event to wpa_Supplicant - union iwreq_data wrqu; - PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - return 0; -} + union iwreq_data wrqu; + PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); + return 0; + } spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); //mike add: active scan OR passive scan OR desire_ssid scan - if(wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)abyScanSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); - if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if(req->essid_len>0) - pItemSSID->len = req->essid_len - 1; - } - else - pItemSSID->len = req->essid_len; - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, - ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - spin_unlock_irq(&pDevice->lock); + if (wrq->length == sizeof(struct iw_scan_req)) { + if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan + memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + pItemSSID = (PWLAN_IE_SSID)abyScanSSID; + pItemSSID->byElementID = WLAN_EID_SSID; + memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); + if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { + if (req->essid_len > 0) + pItemSSID->len = req->essid_len - 1; + } + else + pItemSSID->len = req->essid_len; + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID, + ((PWLAN_IE_SSID)abyScanSSID)->len); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + spin_unlock_irq(&pDevice->lock); + + return 0; + } + else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + } + } + else { //active scan + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + } - return 0; - } - else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - } - } - else { //active scan - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - } - - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n"); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n"); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); return 0; @@ -205,16 +205,16 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! */ int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - int ii, jj, kk; + int ii, jj, kk; PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PKnownBSS pBSS; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PKnownBSS pBSS; + PWLAN_IE_SSID pItemSSID; + PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; char *current_ev = extra; char *end_buf = extra + IW_SCAN_MAX_DATA; char *current_val = NULL; @@ -223,133 +223,133 @@ int iwctl_giwscan(struct net_device *dev, char buf[MAX_WPA_IE_LEN * 2 + 30]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n"); - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. + if (pMgmt->eScanState == WMAC_IS_SCANNING) { + // In scanning.. return -EAGAIN; } pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { + for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { if (current_ev >= end_buf) break; - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - //ADD mac address - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + pBSS = &(pMgmt->sBSSList[jj]); + if (pBSS->bActive) { + //ADD mac address + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); - //ADD ssid - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - iwe.u.data.length = pItemSSID->len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); - //ADD mode - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { - iwe.u.mode = IW_MODE_INFRA; - } - else { - iwe.u.mode = IW_MODE_ADHOC; - } - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - //ADD frequency - pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; - pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = pBSS->uChannel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); - //2008-0409-04, by Einsn Liu + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + //ADD ssid + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; + iwe.u.data.length = pItemSSID->len; + iwe.u.data.flags = 1; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); + //ADD mode + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { + iwe.u.mode = IW_MODE_INFRA; + } + else { + iwe.u.mode = IW_MODE_ADHOC; + } + iwe.len = IW_EV_UINT_LEN; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + //ADD frequency + pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; + pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = pBSS->uChannel; + iwe.u.freq.e = 0; + iwe.u.freq.i = 0; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + //2008-0409-04, by Einsn Liu { - int f = (int)pBSS->uChannel - 1; - if(f < 0)f = 0; - iwe.u.freq.m = frequency_list[f] * 100000; - iwe.u.freq.e = 1; + int f = (int)pBSS->uChannel - 1; + if (f < 0)f = 0; + iwe.u.freq.m = frequency_list[f] * 100000; + iwe.u.freq.e = 1; } - current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); - //ADD quality - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); - iwe.u.qual.level = ldBm; - iwe.u.qual.noise = 0; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + //ADD quality + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); + iwe.u.qual.level = ldBm; + iwe.u.qual.noise = 0; //2008-0409-01, by Einsn Liu - if(-ldBm<50){ + if (-ldBm < 50) { iwe.u.qual.qual = 100; - }else if(-ldBm > 90) { - iwe.u.qual.qual = 0; - }else { - iwe.u.qual.qual=(40-(-ldBm-50))*100/40; + } else if (-ldBm > 90) { + iwe.u.qual.qual = 0; + } else { + iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; } - iwe.u.qual.updated=7; - - // iwe.u.qual.qual = 0; - current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - iwe.u.data.length = 0; - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { - iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - }else { - iwe.u.data.flags = IW_ENCODE_DISABLED; - } - current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - current_val = current_ev + IW_EV_LCP_LEN; - - for (kk = 0 ; kk < 12 ; kk++) { - if (pSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + iwe.u.qual.updated = 7; + + // iwe.u.qual.qual = 0; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWENCODE; + iwe.u.data.length = 0; + if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + } else { + iwe.u.data.flags = IW_ENCODE_DISABLED; + } + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + current_val = current_ev + IW_EV_LCP_LEN; + + for (kk = 0; kk < 12; kk++) { + if (pSuppRates->abyRates[kk] == 0) + break; + // Bit rate given in 500 kb/s units (+ 0x80) + iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); + current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + } + for (kk = 0; kk < 8; kk++) { + if (pExtSuppRates->abyRates[kk] == 0) + break; + // Bit rate given in 500 kb/s units (+ 0x80) + iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); + current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + } + + if ((current_val - current_ev) > IW_EV_LCP_LEN) + current_ev = current_val; + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); + iwe.u.data.length = strlen(buf); + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf); + + if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pBSS->wWPALen; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE); + } + + if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = pBSS->wRSNLen; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE); + } + } - for (kk = 0 ; kk < 8 ; kk++) { - if (pExtSuppRates->abyRates[kk] == 0) - break; - // Bit rate given in 500 kb/s units (+ 0x80) - iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - - if((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); - - if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wWPALen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); - } - - if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wRSNLen; - current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); - } - - } - }// for + }// for wrq->length = current_ev - extra; return 0; @@ -362,41 +362,41 @@ int iwctl_giwscan(struct net_device *dev, */ int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) + struct iw_request_info *info, + struct iw_freq *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); // If setting by frequency, convert to a channel - if((wrq->e == 1) && - (wrq->m >= (int) 2.412e8) && - (wrq->m <= (int) 2.487e8)) { + if ((wrq->e == 1) && + (wrq->m >= (int) 2.412e8) && + (wrq->m <= (int) 2.487e8)) { int f = wrq->m / 100000; int c = 0; - while((c < 14) && (f != frequency_list[c])) + while ((c < 14) && (f != frequency_list[c])) c++; wrq->e = 0; wrq->m = c + 1; } // Setting by channel number - if((wrq->m > 14) || (wrq->e > 0)) + if ((wrq->m > 14) || (wrq->e > 0)) rc = -EOPNOTSUPP; else { int channel = wrq->m; - if((channel < 1) || (channel > 14)) { + if ((channel < 1) || (channel > 14)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); rc = -EINVAL; } else { - // Yes ! We can set it !!! - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); - pDevice->uChannel = channel; - //2007-0207-04, by EinsnLiu - //Make change effect at once - pDevice->bCommit = true; + // Yes ! We can set it !!! + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); + pDevice->uChannel = channel; + //2007-0207-04, by EinsnLiu + //Make change effect at once + pDevice->bCommit = true; } } @@ -408,14 +408,14 @@ int iwctl_siwfreq(struct net_device *dev, */ int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) + struct iw_request_info *info, + struct iw_freq *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); #ifdef WEXT_USECHANNELS wrq->m = (int)pMgmt->uCurrChannel; @@ -423,8 +423,8 @@ int iwctl_giwfreq(struct net_device *dev, #else { int f = (int)pMgmt->uCurrChannel - 1; - if(f < 0) - f = 0; + if (f < 0) + f = 0; wrq->m = frequency_list[f] * 100000; wrq->e = 1; } @@ -438,59 +438,59 @@ int iwctl_giwfreq(struct net_device *dev, */ int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) + struct iw_request_info *info, + __u32 *wmode, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n"); - return rc; - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Can't set operation mode, hostapd is running \n"); + return rc; + } - switch(*wmode) { + switch (*wmode) { case IW_MODE_ADHOC: - if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = true; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { + pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = true; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); break; case IW_MODE_AUTO: case IW_MODE_INFRA: - if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = true; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = true; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); break; case IW_MODE_MASTER: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; rc = -EOPNOTSUPP; break; - if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = true; - } + if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { + pMgmt->eConfigMode = WMAC_CONFIG_AP; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = true; + } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); break; case IW_MODE_REPEAT: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; rc = -EOPNOTSUPP; break; default: @@ -505,22 +505,22 @@ int iwctl_siwmode(struct net_device *dev, */ int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) + struct iw_request_info *info, + __u32 *wmode, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); // If not managed, assume it's ad-hoc switch (pMgmt->eConfigMode) { case WMAC_CONFIG_ESS_STA: *wmode = IW_MODE_INFRA; break; case WMAC_CONFIG_IBSS_STA: - *wmode = IW_MODE_ADHOC; + *wmode = IW_MODE_ADHOC; break; case WMAC_CONFIG_AUTO: *wmode = IW_MODE_INFRA; @@ -541,16 +541,16 @@ int iwctl_giwmode(struct net_device *dev, */ int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - struct iw_range *range = (struct iw_range *) extra; - int i,k; - unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + struct iw_range *range = (struct iw_range *)extra; + int i, k; + unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n"); if (wrq->pointer) { wrq->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); @@ -560,25 +560,25 @@ int iwctl_giwrange(struct net_device *dev, // Should be based on cap_rid.country to give only // what the current card support k = 0; - for(i = 0; i < 14; i++) { + for (i = 0; i < 14; i++) { range->freq[k].i = i + 1; // List index range->freq[k].m = frequency_list[i] * 100000; range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10 } range->num_frequency = k; // Hum... Should put the right values there - #ifdef Calcu_LinkQual - range->max_qual.qual = 100; - #else +#ifdef Calcu_LinkQual + range->max_qual.qual = 100; +#else range->max_qual.qual = 255; - #endif +#endif range->max_qual.level = 0; range->max_qual.noise = 0; range->sensitivity = 255; - for(i = 0 ; i < 13 ; i++) { + for (i = 0; i < 13; i++) { range->bitrate[i] = abySupportedRates[i] * 500000; - if(range->bitrate[i] == 0) + if (range->bitrate[i] == 0) break; } range->num_bitrates = i; @@ -586,7 +586,7 @@ int iwctl_giwrange(struct net_device *dev, // Set an indication of the max TCP throughput // in bit/s that we can expect using this interface. // May be use for QoS stuff... Jean II - if(i > 2) + if (i > 2) range->throughput = 5 * 1000 * 1000; else range->throughput = 1.5 * 1000 * 1000; @@ -597,19 +597,19 @@ int iwctl_giwrange(struct net_device *dev, range->max_frag = 2312; - // the encoding capabilities - range->num_encoding_sizes = 3; - // 64(40) bits WEP - range->encoding_size[0] = 5; - // 128(104) bits WEP - range->encoding_size[1] = 13; - // 256 bits for WPA-PSK - range->encoding_size[2] = 32; - // 4 keys are allowed - range->max_encoding_tokens = 4; + // the encoding capabilities + range->num_encoding_sizes = 3; + // 64(40) bits WEP + range->encoding_size[0] = 5; + // 128(104) bits WEP + range->encoding_size[1] = 13; + // 256 bits for WPA-PSK + range->encoding_size[2] = 32; + // 4 keys are allowed + range->max_encoding_tokens = 4; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; range->min_pmp = 0; range->max_pmp = 1000000;// 1 secs @@ -621,7 +621,7 @@ int iwctl_giwrange(struct net_device *dev, // Transmit Power - values are in mW - range->txpower[0] = 100; + range->txpower[0] = 100; range->num_txpower = 1; range->txpower_capa = IW_TXPOW_MWATT; range->we_version_source = SUPPORTED_WIRELESS_EXT; @@ -651,55 +651,55 @@ int iwctl_giwrange(struct net_device *dev, */ int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) + struct iw_request_info *info, + struct sockaddr *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n"); -if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - printk("SIOCSIWAP(??)-->In scanning...\n"); - // return -EAGAIN; - } + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; + unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n"); + if (pMgmt->eScanState == WMAC_IS_SCANNING) { + // In scanning.. + printk("SIOCSIWAP(??)-->In scanning...\n"); + // return -EAGAIN; + } if (wrq->sa_family != ARPHRD_ETHER) rc = -EINVAL; else { memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //2008-0409-05, by Einsn Liu - if((pDevice->bLinkPass == true) && - (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6)== 0)){ + //2008-0409-05, by Einsn Liu + if ((pDevice->bLinkPass == true) && + (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6) == 0)) { + return rc; + } + //mike :add + if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || + (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) { + PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); return rc; + } + //mike add: if desired AP is hidden ssid(there are two same BSSID in list), + // then ignore,because you don't known which one to be connect with?? + { + unsigned int ii, uSameBssidNum = 0; + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) { + uSameBssidNum++; + } + } + if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); + return rc; } - //mike :add - if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || - (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ - PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); - return rc; - } - //mike add: if desired AP is hidden ssid(there are two same BSSID in list), - // then ignore,because you don't known which one to be connect with?? - { - unsigned int ii , uSameBssidNum=0; - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) { - uSameBssidNum++; - } - } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); - return rc; - } - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = true; - } + } + + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = true; + } } return rc; } @@ -709,24 +709,24 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { */ int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) + struct iw_request_info *info, + struct sockaddr *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - //2008-0410, by Einsn Liu - if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) - memset(wrq->sa_data, 0, 6); + memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); + //2008-0410, by Einsn Liu + if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) + memset(wrq->sa_data, 0, 6); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); + } wrq->sa_family = ARPHRD_ETHER; @@ -740,18 +740,18 @@ int iwctl_giwap(struct net_device *dev, */ int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - int ii,jj, rc = 0; + int ii, jj, rc = 0; struct sockaddr sock[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); // Only super-user can see AP list if (!capable(CAP_NET_ADMIN)) { @@ -763,12 +763,12 @@ int iwctl_giwaplist(struct net_device *dev, PKnownBSS pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - if ( jj >= IW_MAX_AP) - break; + for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { + pBSS = &(pMgmt->sBSSList[ii]); + if (!pBSS->bActive) + continue; + if (jj >= IW_MAX_AP) + break; memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6); sock[jj].sa_family = ARPHRD_ETHER; qual[jj].level = pBSS->uRSSI; @@ -792,112 +792,112 @@ int iwctl_giwaplist(struct net_device *dev, */ int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - //2008-0409-05, by Einsn Liu - unsigned char len; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n"); - pDevice->fWPA_Authened = false; -if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. - printk("SIOCSIWESSID(??)-->In scanning...\n"); - // return -EAGAIN; - } + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PWLAN_IE_SSID pItemSSID; + //2008-0409-05, by Einsn Liu + unsigned char len; + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n"); + pDevice->fWPA_Authened = false; + if (pMgmt->eScanState == WMAC_IS_SCANNING) { + // In scanning.. + printk("SIOCSIWESSID(??)-->In scanning...\n"); + // return -EAGAIN; + } // Check if we asked for `any' - if(wrq->flags == 0) { + if (wrq->flags == 0) { // Just send an empty SSID list memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memset(pMgmt->abyDesireBSSID, 0xFF,6); - PRINT_K("set essid to 'any' \n"); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Unknown desired AP,so here need not associate?? - //if(pDevice->bWPASuppWextEnabled == true) { - return 0; - // } - #endif + memset(pMgmt->abyDesireBSSID, 0xFF, 6); + PRINT_K("set essid to 'any' \n"); +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + //Unknown desired AP,so here need not associate?? + //if (pDevice->bWPASuppWextEnabled == true) { + return 0; + // } +#endif } else { // Set the SSID memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSID->byElementID = WLAN_EID_SSID; memcpy(pItemSSID->abySSID, extra, wrq->length); - if (pItemSSID->abySSID[wrq->length - 1] == '\0') { - if(wrq->length>0) - pItemSSID->len = wrq->length - 1; - } - else - pItemSSID->len = wrq->length; - printk("set essid to %s \n",pItemSSID->abySSID); + if (pItemSSID->abySSID[wrq->length - 1] == '\0') { + if (wrq->length > 0) + pItemSSID->len = wrq->length - 1; + } + else + pItemSSID->len = wrq->length; + printk("set essid to %s \n", pItemSSID->abySSID); //2008-0409-05, by Einsn Liu - len=(pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)?pItemSSID->len:((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; - if((pDevice->bLinkPass == true) && - (memcmp(pItemSSID->abySSID,((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,len)==0)) - return 0; - - //mike:need clear desiredBSSID - if(pItemSSID->len==0) { - memset(pMgmt->abyDesireBSSID, 0xFF,6); - return 0; - } + len = (pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) ? pItemSSID->len : ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; + if ((pDevice->bLinkPass == true) && + (memcmp(pItemSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, len) == 0)) + return 0; + + //mike:need clear desiredBSSID + if (pItemSSID->len == 0) { + memset(pMgmt->abyDesireBSSID, 0xFF, 6); + return 0; + } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Wext wil order another command of siwap to link with desired AP, - //so here need not associate?? - if(pDevice->bWPASuppWextEnabled == true) { - /*******search if in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned int ii , uSameBssidNum=0; - - memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); - pCurr = BSSpSearchBSSList(pDevice, - NULL, - abyTmpDesireSSID, - pMgmt->eConfigPHYMode - ); - - if (pCurr == NULL){ - PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } - else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) { - uSameBssidNum++; - } - } - if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! - printk("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *) pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } - } - } - return 0; - } - #endif + //Wext wil order another command of siwap to link with desired AP, + //so here need not associate?? + if (pDevice->bWPASuppWextEnabled == true) { + /*******search if in hidden ssid mode ****/ + { + PKnownBSS pCurr = NULL; + unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned int ii, uSameBssidNum = 0; + + memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID)); + pCurr = BSSpSearchBSSList(pDevice, + NULL, + abyTmpDesireSSID, + pMgmt->eConfigPHYMode +); + + if (pCurr == NULL) { + PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); + vResetCommandTimer((void *)pDevice); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + } + else { //mike:to find out if that desired SSID is a hidden-ssid AP , + // by means of judging if there are two same BSSID exist in list ? + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive && + !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) { + uSameBssidNum++; + } + } + if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + printk("SIOCSIWESSID:hidden ssid directly associate.......\n"); + vResetCommandTimer((void *)pDevice); + pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + } + } + } + return 0; + } +#endif - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); } - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - pDevice->bCommit = true; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + pDevice->bCommit = true; } @@ -910,28 +910,28 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { */ int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); // Note : if wrq->u.data.flags != 0, we should // get the relevant SSID from the SSID list... // Get the current SSID - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; memcpy(extra, pItemSSID->abySSID , pItemSSID->len); extra[pItemSSID->len] = '\0'; wrq->length = pItemSSID->len + 1; - //2008-0409-03, by Einsn Liu - wrq->length = pItemSSID->len; + //2008-0409-03, by Einsn Liu + wrq->length = pItemSSID->len; wrq->flags = 1; // active @@ -943,28 +943,28 @@ int iwctl_giwessid(struct net_device *dev, */ int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; + int rc = 0; u8 brate = 0; int i; - unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { + rc = -EINVAL; + return rc; + } // First : get a valid bit rate value // Which type of value - if((wrq->value < 13) && - (wrq->value >= 0)) { + if ((wrq->value < 13) && + (wrq->value >= 0)) { // Setting by rate index // Find value in the magic rate table brate = wrq->value; @@ -973,51 +973,51 @@ int iwctl_siwrate(struct net_device *dev, u8 normvalue = (u8) (wrq->value/500000); // Check if rate is valid - for(i = 0 ; i < 13 ; i++) { - if(normvalue == abySupportedRates[i]) { + for (i = 0; i < 13; i++) { + if (normvalue == abySupportedRates[i]) { brate = i; break; } } } // -1 designed the max rate (mostly auto mode) - if(wrq->value == -1) { + if (wrq->value == -1) { // Get the highest available rate - for(i = 0 ; i < 13 ; i++) { - if(abySupportedRates[i] == 0) + for (i = 0; i < 13; i++) { + if (abySupportedRates[i] == 0) break; } - if(i != 0) + if (i != 0) brate = i - 1; } // Check that it is valid // brate is index of abySupportedRates[] - if(brate > 13 ) { + if (brate > 13) { rc = -EINVAL; return rc; } // Now, check if we want a fixed or auto value - if(wrq->fixed != 0) { + if (wrq->fixed != 0) { // Fixed mode // One rate, fixed - printk("Rate Fix\n"); + printk("Rate Fix\n"); pDevice->bFixRate = true; - if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) { - pDevice->uConnectionRate = 3; - } - else { - pDevice->uConnectionRate = brate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); - } + if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { + pDevice->uConnectionRate = 3; + } + else { + pDevice->uConnectionRate = brate; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); + } } else { - pDevice->bFixRate = false; - pDevice->uConnectionRate = 13; - printk("auto rate:connection_rate is 13\n"); - } + pDevice->bFixRate = false; + pDevice->uConnectionRate = 13; + printk("auto rate:connection_rate is 13\n"); + } return rc; } @@ -1027,60 +1027,60 @@ int iwctl_siwrate(struct net_device *dev, */ int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); //2007-0118-05, by EinsnLiu //Mark the unnecessary sentences. // PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); - { - unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - int brate = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); + { + unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; + int brate = 0; //2008-5-8 by chester -if(pDevice->bLinkPass){ -if(pDevice->bFixRate == true){ - if (pDevice->uConnectionRate < 13) { - brate = abySupportedRates[pDevice->uConnectionRate]; - }else { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } -} -else -{ + if (pDevice->bLinkPass) { + if (pDevice->bFixRate == true) { + if (pDevice->uConnectionRate < 13) { + brate = abySupportedRates[pDevice->uConnectionRate]; + } else { + if (pDevice->byBBType == BB_TYPE_11B) + brate = 0x16; + if (pDevice->byBBType == BB_TYPE_11G) + brate = 0x6C; + if (pDevice->byBBType == BB_TYPE_11A) + brate = 0x6C; + } + } + else + { - brate = abySupportedRates[TxRate_iwconfig]; -} -} -else brate =0; + brate = abySupportedRates[TxRate_iwconfig]; + } + } + else brate = 0; //2007-0118-05, by EinsnLiu //Mark the unnecessary sentences. /* - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (pDevice->byBBType == BB_TYPE_11B) + brate = 0x16; + if (pDevice->byBBType == BB_TYPE_11G) + brate = 0x6C; + if (pDevice->byBBType == BB_TYPE_11A) + brate = 0x6C; + } */ -// if (pDevice->uConnectionRate == 13) +// if (pDevice->uConnectionRate == 13) // brate = abySupportedRates[pDevice->wCurrentRate]; - wrq->value = brate * 500000; - // If more than one rate, set auto - if (pDevice->bFixRate == true) - wrq->fixed = true; - } + wrq->value = brate * 500000; + // If more than one rate, set auto + if (pDevice->bFixRate == true) + wrq->fixed = true; + } return 0; @@ -1093,25 +1093,25 @@ else brate =0; */ int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n"); { - int rthr = wrq->value; - if(wrq->disabled) + int rthr = wrq->value; + if (wrq->disabled) rthr = 2312; - if((rthr < 0) || (rthr > 2312)) { + if ((rthr < 0) || (rthr > 2312)) { rc = -EINVAL; - }else { - pDevice->wRTSThreshold = rthr; - } - } + } else { + pDevice->wRTSThreshold = rthr; + } + } return 0; } @@ -1121,13 +1121,13 @@ int iwctl_siwrts(struct net_device *dev, */ int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); wrq->value = pDevice->wRTSThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -1140,26 +1140,26 @@ int iwctl_giwrts(struct net_device *dev, */ int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; - int fthr = wrq->value; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + int rc = 0; + int fthr = wrq->value; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); - if (wrq->disabled) + if (wrq->disabled) fthr = 2312; - if((fthr < 256) || (fthr > 2312)) { + if ((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; - }else { - fthr &= ~0x1; // Get an even value - pDevice->wFragmentationThreshold = (u16)fthr; - } + } else { + fthr &= ~0x1; // Get an even value + pDevice->wFragmentationThreshold = (u16)fthr; + } return rc; } @@ -1169,13 +1169,13 @@ int iwctl_siwfrag(struct net_device *dev, */ int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); wrq->value = pDevice->wFragmentationThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -1189,15 +1189,15 @@ int iwctl_giwfrag(struct net_device *dev, * Wireless Handler : set retry threshold */ int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); if (wrq->disabled) { rc = -EINVAL; @@ -1205,7 +1205,7 @@ int iwctl_siwretry(struct net_device *dev, } if (wrq->flags & IW_RETRY_LIMIT) { - if(wrq->flags & IW_RETRY_MAX) + if (wrq->flags & IW_RETRY_MAX) pDevice->byLongRetryLimit = wrq->value; else if (wrq->flags & IW_RETRY_MIN) pDevice->byShortRetryLimit = wrq->value; @@ -1227,25 +1227,25 @@ int iwctl_siwretry(struct net_device *dev, * Wireless Handler : get retry threshold */ int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); wrq->disabled = 0; // Can't be disabled // Note : by default, display the min retry number - if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { wrq->flags = IW_RETRY_LIFETIME; wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms - } else if((wrq->flags & IW_RETRY_MAX)) { + } else if ((wrq->flags & IW_RETRY_MAX)) { wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrq->value = (int)pDevice->byLongRetryLimit; } else { wrq->flags = IW_RETRY_LIMIT; wrq->value = (int)pDevice->byShortRetryLimit; - if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) + if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) wrq->flags |= IW_RETRY_MIN; } @@ -1258,14 +1258,14 @@ int iwctl_giwretry(struct net_device *dev, * Wireless Handler : set encode mode */ int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); unsigned long dwKeyIndex = (unsigned long)(wrq->flags & IW_ENCODE_INDEX); - int ii,uu, rc = 0; + int ii, uu, rc = 0; int index = (wrq->flags & IW_ENCODE_INDEX); //2007-0207-07, by EinsnLiu @@ -1281,192 +1281,192 @@ int iwctl_siwencode(struct net_device *dev, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); -if((wrq->flags & IW_ENCODE_DISABLED)==0){ - //Not disable encryption + if ((wrq->flags & IW_ENCODE_DISABLED) == 0) { + //Not disable encryption - if (dwKeyIndex > WLAN_WEP_NKEYS) { - rc = -EINVAL; - return rc; - } + if (dwKeyIndex > WLAN_WEP_NKEYS) { + rc = -EINVAL; + return rc; + } - if(dwKeyIndex<1&&((wrq->flags&IW_ENCODE_NOKEY)==0)){//set default key - if(pDevice->byKeyIndexbyKeyIndex; + if (dwKeyIndex < 1 && ((wrq->flags & IW_ENCODE_NOKEY) == 0)) {//set default key + if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) { + dwKeyIndex = pDevice->byKeyIndex; } - else dwKeyIndex=0; - }else dwKeyIndex--; + else dwKeyIndex = 0; + } else dwKeyIndex--; - // Check the size of the key - if (wrq->length > WLAN_WEP232_KEYLEN) { - rc = -EINVAL; - return rc; - } - - if(wrq->length>0){//have key - - if (wrq->length == WLAN_WEP232_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP104_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP40_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); - }else {//no support length - rc = -EINVAL; - return rc; - } - memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); - memcpy(pDevice->abyKey, extra, wrq->length); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); - for (ii = 0; ii < wrq->length; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(dwKeyIndex | (1 << 31)), - wrq->length, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID - ); - spin_unlock_irq(&pDevice->lock); - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->uKeyLength = wrq->length; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - - }else if(index>0){ - //when the length is 0 the request only changes the default transmit key index - //check the new key if it has a non zero length - if(pDevice->bEncryptionEnable==false) - { - rc = -EINVAL; - return rc; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n"); - pkeytab=&(pDevice->sKey.KeyTable[MAX_KEY_TABLE-1]); - if(pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength==0){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n"); - rc = -EINVAL; - return rc; + // Check the size of the key + if (wrq->length > WLAN_WEP232_KEYLEN) { + rc = -EINVAL; + return rc; } - pDevice->byKeyIndex =(unsigned char)dwKeyIndex; - pkeytab->dwGTKeyIndex =dwKeyIndex | (1 << 31); - pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex=dwKeyIndex | (1 << 31); - } -}else {//disable the key - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); - if(pDevice->bEncryptionEnable==false) - return 0; - pMgmt->bShareKeyAlgorithm = false; - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - for(uu=0;uuPortOffset, uu); - spin_unlock_irq(&pDevice->lock); - } -} -//End Modify,Einsn + if (wrq->length > 0) {//have key -/* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); + if (wrq->length == WLAN_WEP232_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP104_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP40_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); + } else {//no support length + rc = -EINVAL; + return rc; + } + memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); + memcpy(pDevice->abyKey, extra, wrq->length); - // Check the size of the key - if (wrq->length > WLAN_WEP232_KEYLEN) { - rc = -EINVAL; - return rc; - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyKey: "); + for (ii = 0; ii < wrq->length; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); + } - if (dwKeyIndex > WLAN_WEP_NKEYS) { - rc = -EINVAL; - return rc; - } - - if (dwKeyIndex > 0) - dwKeyIndex--; - - // Send the key to the card - if (wrq->length > 0) { - - if (wrq->length == WLAN_WEP232_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP104_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); - } - else if (wrq->length == WLAN_WEP40_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); - } - memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); - memcpy(pDevice->abyKey, extra, wrq->length); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); - for (ii = 0; ii < wrq->length; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(pDevice->byKeyIndex | (1 << 31)), - pDevice->uKeyLength, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID - ); - spin_unlock_irq(&pDevice->lock); - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->uKeyLength = wrq->length; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - - // Do we want to just set the transmit key index ? - if ( index < 4 ) { - pDevice->byKeyIndex = index; - } - else if(!(wrq->flags & IW_ENCODE_MODE)) { + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + KeybSetDefaultKey(&(pDevice->sKey), + (unsigned long)(dwKeyIndex | (1 << 31)), + wrq->length, + NULL, + pDevice->abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID +); + spin_unlock_irq(&pDevice->lock); + } + pDevice->byKeyIndex = (unsigned char)dwKeyIndex; + pDevice->uKeyLength = wrq->length; + pDevice->bTransmitKey = true; + pDevice->bEncryptionEnable = true; + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + + } else if (index > 0) { + //when the length is 0 the request only changes the default transmit key index + //check the new key if it has a non zero length + if (pDevice->bEncryptionEnable == false) + { rc = -EINVAL; return rc; - } - } - // Read the flags - if(wrq->flags & IW_ENCODE_DISABLED){ + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n"); + pkeytab = &(pDevice->sKey.KeyTable[MAX_KEY_TABLE - 1]); + if (pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength == 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n"); + rc = -EINVAL; + return rc; + } + pDevice->byKeyIndex = (unsigned char)dwKeyIndex; + pkeytab->dwGTKeyIndex = dwKeyIndex | (1 << 31); + pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex = dwKeyIndex | (1 << 31); + } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); + } else {//disable the key + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); + if (pDevice->bEncryptionEnable == false) + return 0; pMgmt->bShareKeyAlgorithm = false; - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - for(uu=0;uuPortOffset, uu); - spin_unlock_irq(&pDevice->lock); - } + pDevice->bEncryptionEnable = false; + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + for (uu = 0; uu < MAX_KEY_TABLE; uu++) + MACvDisableKeyEntry(pDevice->PortOffset, uu); + spin_unlock_irq(&pDevice->lock); + } } +//End Modify,Einsn + +/* + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); + + // Check the size of the key + if (wrq->length > WLAN_WEP232_KEYLEN) { + rc = -EINVAL; + return rc; + } + + if (dwKeyIndex > WLAN_WEP_NKEYS) { + rc = -EINVAL; + return rc; + } + + if (dwKeyIndex > 0) + dwKeyIndex--; + + // Send the key to the card + if (wrq->length > 0) { + + if (wrq->length == WLAN_WEP232_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP104_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); + } + else if (wrq->length == WLAN_WEP40_KEYLEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); + } + memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); + memcpy(pDevice->abyKey, extra, wrq->length); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyKey: "); + for (ii = 0; ii < wrq->length; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); + } + + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + KeybSetDefaultKey(&(pDevice->sKey), + (unsigned long)(pDevice->byKeyIndex | (1 << 31)), + pDevice->uKeyLength, + NULL, + pDevice->abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID +); + spin_unlock_irq(&pDevice->lock); + } + pDevice->byKeyIndex = (unsigned char)dwKeyIndex; + pDevice->uKeyLength = wrq->length; + pDevice->bTransmitKey = true; + pDevice->bEncryptionEnable = true; + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + + // Do we want to just set the transmit key index ? + if (index < 4) { + pDevice->byKeyIndex = index; + } + else if (!(wrq->flags & IW_ENCODE_MODE)) { + rc = -EINVAL; + return rc; + } + } + // Read the flags + if (wrq->flags & IW_ENCODE_DISABLED) { + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); + pMgmt->bShareKeyAlgorithm = false; + pDevice->bEncryptionEnable = false; + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + if (pDevice->flags & DEVICE_FLAGS_OPENED) { + spin_lock_irq(&pDevice->lock); + for (uu=0; uuPortOffset, uu); + spin_unlock_irq(&pDevice->lock); + } + } */ - if(wrq->flags & IW_ENCODE_RESTRICTED) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); + if (wrq->flags & IW_ENCODE_RESTRICTED) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); pMgmt->bShareKeyAlgorithm = true; } - if(wrq->flags & IW_ENCODE_OPEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); + if (wrq->flags & IW_ENCODE_OPEN) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); pMgmt->bShareKeyAlgorithm = false; } return rc; @@ -1475,80 +1475,80 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){ /* * Wireless Handler : get encode mode */ - /* -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - char abyKey[WLAN_WEP232_KEYLEN]; - unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); - PSKeyItem pKey = NULL; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); +/* + int iwctl_giwencode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) + { + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; + char abyKey[WLAN_WEP232_KEYLEN]; + unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); + PSKeyItem pKey = NULL; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); //2007-0207-06, by EinsnLiu //the key index in iwconfig is 1-4 when our driver is 0-3 //so it can't be used directly. //if the index is 0,we should used the index set by driver. - if (index > WLAN_WEP_NKEYS) { - rc = -EINVAL; - return rc; - } - if(index<1){//set default key - if(pDevice->byKeyIndexbyKeyIndex; - } - else index=0; - }else index--; +if (index > WLAN_WEP_NKEYS) { +rc = -EINVAL; +return rc; +} +if (index<1) {//set default key +if (pDevice->byKeyIndexbyKeyIndex; +} +else index=0; +} else index--; //End Add,Einsn - memset(abyKey, 0, sizeof(abyKey)); - // Check encryption mode - wrq->flags = IW_ENCODE_NOKEY; - // Is WEP enabled ??? - if (pDevice->bEncryptionEnable) - wrq->flags |= IW_ENCODE_ENABLED; - else - wrq->flags |= IW_ENCODE_DISABLED; +memset(abyKey, 0, sizeof(abyKey)); +// Check encryption mode +wrq->flags = IW_ENCODE_NOKEY; +// Is WEP enabled ??? +if (pDevice->bEncryptionEnable) +wrq->flags |= IW_ENCODE_ENABLED; +else +wrq->flags |= IW_ENCODE_DISABLED; - if (pMgmt->bShareKeyAlgorithm) - wrq->flags |= IW_ENCODE_RESTRICTED; - else - wrq->flags |= IW_ENCODE_OPEN; +if (pMgmt->bShareKeyAlgorithm) +wrq->flags |= IW_ENCODE_RESTRICTED; +else +wrq->flags |= IW_ENCODE_OPEN; - if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){ - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); +if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)) { +wrq->length = pKey->uKeyLength; +memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); //2007-0207-06, by EinsnLiu //only get key success need to copy data //index should +1. //there is not necessary to return -EINVAL when get key failed //if return -EINVAL,the encryption item can't be display by the command "iwconfig". - wrq->flags |= index+1; - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } +wrq->flags |= index+1; +memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); +} - //else { - // rc = -EINVAL; - // return rc; - // } +//else { +// rc = -EINVAL; +// return rc; +// } //End Modify,Einsn - return 0; +return 0; } */ //2008-0409-06, by Einsn Liu int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1562,13 +1562,13 @@ int iwctl_giwencode(struct net_device *dev, if (index > WLAN_WEP_NKEYS) { return -EINVAL; } - if(index<1){//get default key - if(pDevice->byKeyIndexbyKeyIndex; - } else - index=0; - }else - index--; + if (index < 1) {//get default key + if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) { + index = pDevice->byKeyIndex; + } else + index = 0; + } else + index--; memset(abyKey, 0, WLAN_WEP232_KEYLEN); // Check encryption mode @@ -1583,18 +1583,18 @@ int iwctl_giwencode(struct net_device *dev, wrq->flags |= IW_ENCODE_RESTRICTED; else wrq->flags |= IW_ENCODE_OPEN; - wrq->length=0; - - if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key - if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){ + wrq->length = 0; + + if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled || + pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) {//get wpa pairwise key + if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) { wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); + memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); + memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); + } + } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)) { + wrq->length = pKey->uKeyLength; + memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); } @@ -1608,19 +1608,19 @@ int iwctl_giwencode(struct net_device *dev, * Wireless Handler : set power mode */ int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; + if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { + rc = -EINVAL; + return rc; } if (wrq->disabled) { @@ -1629,23 +1629,23 @@ int iwctl_siwpower(struct net_device *dev, return rc; } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); + pDevice->ePSMode = WMAC_POWER_FAST; + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); + pDevice->ePSMode = WMAC_POWER_FAST; + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); rc = -EINVAL; break; case IW_POWER_ALL_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n"); rc = -EINVAL; case IW_POWER_ON: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n"); break; default: rc = -EINVAL; @@ -1658,21 +1658,21 @@ int iwctl_siwpower(struct net_device *dev, * Wireless Handler : get power mode */ int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int mode = pDevice->ePSMode; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + int mode = pDevice->ePSMode; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); wrq->disabled = (mode == WMAC_POWER_CAM); if (wrq->disabled) - return 0; + return 0; if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); @@ -1691,21 +1691,21 @@ int iwctl_giwpower(struct net_device *dev, * Wireless Handler : get Sensitivity */ int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - long ldBm; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + long ldBm; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); - if (pDevice->bLinkPass == true) { - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - wrq->value = ldBm; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); + if (pDevice->bLinkPass == true) { + RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); + wrq->value = ldBm; } else { - wrq->value = 0; - }; + wrq->value = 0; + }; wrq->disabled = (wrq->value == 0); wrq->fixed = 1; @@ -1717,66 +1717,66 @@ int iwctl_giwsens(struct net_device *dev, #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; - static int wpa_version=0; //must be static to save the last value,einsn liu - static int pairwise=0; + int ret = 0; + static int wpa_version = 0; //must be static to save the last value,einsn liu + static int pairwise = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); switch (wrq->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: wpa_version = wrq->value; - if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { - PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); + if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { + PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); //pDevice->bWPADevEnable = false; } - else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) { - PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); + else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) { + PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); } else { - PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); + PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); } //pDevice->bWPASuppWextEnabled =true; break; case IW_AUTH_CIPHER_PAIRWISE: pairwise = wrq->value; - if(pairwise == IW_AUTH_CIPHER_CCMP){ + if (pairwise == IW_AUTH_CIPHER_CCMP) { pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - }else if(pairwise == IW_AUTH_CIPHER_TKIP){ + } else if (pairwise == IW_AUTH_CIPHER_TKIP) { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - }else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){ + } else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) { pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - }else if(pairwise == IW_AUTH_CIPHER_NONE){ + } else if (pairwise == IW_AUTH_CIPHER_NONE) { //do nothing,einsn liu - }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + } else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; break; case IW_AUTH_CIPHER_GROUP: - if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED) + if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) break; - if(pairwise == IW_AUTH_CIPHER_NONE){ - if(wrq->value == IW_AUTH_CIPHER_CCMP){ + if (pairwise == IW_AUTH_CIPHER_NONE) { + if (wrq->value == IW_AUTH_CIPHER_CCMP) { pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - }else { + } else { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; } } break; case IW_AUTH_KEY_MGMT: - if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){ - if(wrq->value == IW_AUTH_KEY_MGMT_PSK) + if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) { + if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){ - if(wrq->value == 0){ + } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) { + if (wrq->value == 0) { pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK) + } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; else pMgmt->eAuthenMode = WMAC_AUTH_WPA; } @@ -1787,10 +1787,10 @@ int iwctl_siwauth(struct net_device *dev, case IW_AUTH_DROP_UNENCRYPTED: break; case IW_AUTH_80211_AUTH_ALG: - if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ - pMgmt->bShareKeyAlgorithm=false; - }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){ - pMgmt->bShareKeyAlgorithm=true; + if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM) { + pMgmt->bShareKeyAlgorithm = false; + } else if (wrq->value == IW_AUTH_ALG_SHARED_KEY) { + pMgmt->bShareKeyAlgorithm = true; } break; case IW_AUTH_WPA_ENABLED: @@ -1803,7 +1803,7 @@ int iwctl_siwauth(struct net_device *dev, break; case IW_AUTH_PRIVACY_INVOKED: pDevice->bEncryptionEnable = !!wrq->value; - if(pDevice->bEncryptionEnable == false){ + if (pDevice->bEncryptionEnable == false) { wpa_version = 0; pairwise = 0; pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; @@ -1818,22 +1818,22 @@ int iwctl_siwauth(struct net_device *dev, break; } /* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode = %d\n",pMgmt->eAuthenMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"true":"false"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"true":"false"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"true":"false"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode = %d\n",pMgmt->eAuthenMode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"true":"false"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"true":"false"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"true":"false"); */ - return ret; + return ret; } int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_request_info *info, + struct iw_param *wrq, + char *extra) { return -EOPNOTSUPP; } @@ -1841,56 +1841,56 @@ int iwctl_giwauth(struct net_device *dev, int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; + int ret = 0; - if(wrq->length){ + if (wrq->length) { if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) { ret = -EINVAL; goto out; } - if(wrq->length > MAX_WPA_IE_LEN){ + if (wrq->length > MAX_WPA_IE_LEN) { ret = -ENOMEM; goto out; } memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){ + if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)) { ret = -EFAULT; goto out; } pMgmt->wWPAIELen = wrq->length; - }else { + } else { memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); pMgmt->wWPAIELen = 0; } - out://not completely ...not necessary in wpa_supplicant 0.5.8 +out://not completely ...not necessary in wpa_supplicant 0.5.8 return ret; } int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret=0; + int ret = 0; int space = wrq->length; wrq->length = 0; - if(pMgmt->wWPAIELen > 0){ + if (pMgmt->wWPAIELen > 0) { wrq->length = pMgmt->wWPAIELen; - if(pMgmt->wWPAIELen <= space){ - if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){ + if (pMgmt->wWPAIELen <= space) { + if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) { ret = -EFAULT; } - }else + } else ret = -E2BIG; } @@ -1899,139 +1899,139 @@ int iwctl_giwgenie(struct net_device *dev, int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; - struct viawget_wpa_param *param=NULL; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct viawget_wpa_param *param = NULL; //original member - wpa_alg alg_name; - u8 addr[6]; - int key_idx, set_tx=0; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 key[64]; - size_t seq_len=0,key_len=0; + wpa_alg alg_name; + u8 addr[6]; + int key_idx, set_tx = 0; + u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; + u8 key[64]; + size_t seq_len = 0, key_len = 0; // - // int ii; - u8 *buf; - size_t blen; - u8 key_array[64]; - int ret=0; + // int ii; + u8 *buf; + size_t blen; + u8 key_array[64]; + int ret = 0; -PRINT_K("SIOCSIWENCODEEXT...... \n"); + PRINT_K("SIOCSIWENCODEEXT...... \n"); -blen = sizeof(*param); -buf = kmalloc((int)blen, (int)GFP_KERNEL); -if (buf == NULL) - return -ENOMEM; -memset(buf, 0, blen); -param = (struct viawget_wpa_param *) buf; + blen = sizeof(*param); + buf = kmalloc((int)blen, (int)GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memset(buf, 0, blen); + param = (struct viawget_wpa_param *)buf; //recover alg_name -switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = WPA_ALG_NONE; + switch (ext->alg) { + case IW_ENCODE_ALG_NONE: + alg_name = WPA_ALG_NONE; break; - case IW_ENCODE_ALG_WEP: - alg_name = WPA_ALG_WEP; + case IW_ENCODE_ALG_WEP: + alg_name = WPA_ALG_WEP; break; - case IW_ENCODE_ALG_TKIP: - alg_name = WPA_ALG_TKIP; + case IW_ENCODE_ALG_TKIP: + alg_name = WPA_ALG_TKIP; break; - case IW_ENCODE_ALG_CCMP: - alg_name = WPA_ALG_CCMP; + case IW_ENCODE_ALG_CCMP: + alg_name = WPA_ALG_CCMP; break; - default: - PRINT_K("Unknown alg = %d\n",ext->alg); - ret= -ENOMEM; + default: + PRINT_K("Unknown alg = %d\n", ext->alg); + ret = -ENOMEM; goto error; - } + } //recover addr - memcpy(addr, ext->addr.sa_data, ETH_ALEN); + memcpy(addr, ext->addr.sa_data, ETH_ALEN); //recover key_idx - key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; + key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; //recover set_tx -if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - set_tx = 1; + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + set_tx = 1; //recover seq,seq_len - if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - seq_len=IW_ENCODE_SEQ_MAX_SIZE; - memcpy(seq, ext->rx_seq, seq_len); - } + if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + seq_len = IW_ENCODE_SEQ_MAX_SIZE; + memcpy(seq, ext->rx_seq, seq_len); + } //recover key,key_len -if(ext->key_len) { - key_len=ext->key_len; - memcpy(key, &ext->key[0], key_len); + if (ext->key_len) { + key_len = ext->key_len; + memcpy(key, &ext->key[0], key_len); } -memset(key_array, 0, 64); -if ( key_len > 0) { - memcpy(key_array, key, key_len); - if (key_len == 32) { - // notice ! the oder - memcpy(&key_array[16], &key[24], 8); - memcpy(&key_array[24], &key[16], 8); - } + memset(key_array, 0, 64); + if (key_len > 0) { + memcpy(key_array, key, key_len); + if (key_len == 32) { + // notice ! the oder + memcpy(&key_array[16], &key[24], 8); + memcpy(&key_array[24], &key[16], 8); + } } /**************Translate iw_encode_ext to viawget_wpa_param****************/ -memcpy(param->addr, addr, ETH_ALEN); -param->u.wpa_key.alg_name = (int)alg_name; -param->u.wpa_key.set_tx = set_tx; -param->u.wpa_key.key_index = key_idx; -param->u.wpa_key.key_len = key_len; -param->u.wpa_key.key = (u8 *)key_array; -param->u.wpa_key.seq = (u8 *)seq; -param->u.wpa_key.seq_len = seq_len; + memcpy(param->addr, addr, ETH_ALEN); + param->u.wpa_key.alg_name = (int)alg_name; + param->u.wpa_key.set_tx = set_tx; + param->u.wpa_key.key_index = key_idx; + param->u.wpa_key.key_len = key_len; + param->u.wpa_key.key = (u8 *)key_array; + param->u.wpa_key.seq = (u8 *)seq; + param->u.wpa_key.seq_len = seq_len; //****set if current action is Network Manager count?? //****this method is so foolish,but there is no other way??? -if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { - if(param->u.wpa_key.key_index ==0) { - pDevice->bwextcount++; - } - if((pDevice->bwextcount == 1)&&(param->u.wpa_key.key_index ==1)) { - pDevice->bwextcount++; - } - if((pDevice->bwextcount ==2)&&(param->u.wpa_key.key_index ==2)) { - pDevice->bwextcount++; + if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { + if (param->u.wpa_key.key_index == 0) { + pDevice->bwextcount++; + } + if ((pDevice->bwextcount == 1) && (param->u.wpa_key.key_index == 1)) { + pDevice->bwextcount++; + } + if ((pDevice->bwextcount == 2) && (param->u.wpa_key.key_index == 2)) { + pDevice->bwextcount++; + } + if ((pDevice->bwextcount == 3) && (param->u.wpa_key.key_index == 3)) { + pDevice->bwextcount++; + } + } + if (pDevice->bwextcount == 4) { + printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); + pDevice->bwextcount = 0; + pDevice->bWPASuppWextEnabled = true; } - if((pDevice->bwextcount ==3)&&(param->u.wpa_key.key_index ==3)) { - pDevice->bwextcount++; - } - } -if( pDevice->bwextcount == 4) { - printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); - pDevice->bwextcount=0; - pDevice->bWPASuppWextEnabled = true; - } //****** - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, true); - spin_unlock_irq(&pDevice->lock); + spin_lock_irq(&pDevice->lock); + ret = wpa_set_keys(pDevice, param, true); + spin_unlock_irq(&pDevice->lock); error: -kfree(param); + kfree(param); return ret; } int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { - return -EOPNOTSUPP; + return -EOPNOTSUPP; } int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info * info, - struct iw_point *wrq, - char *extra) + struct iw_request_info *info, + struct iw_point *wrq, + char *extra) { PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -2039,21 +2039,21 @@ int iwctl_siwmlme(struct net_device *dev, //u16 reason = cpu_to_le16(mlme->reason_code); int ret = 0; - if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ + if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) { ret = -EINVAL; return ret; } - switch(mlme->cmd){ + switch (mlme->cmd) { case IW_MLME_DEAUTH: //this command seems to be not complete,please test it --einsnliu //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); break; case IW_MLME_DISASSOC: - if(pDevice->bLinkPass == true){ - printk("iwctl_siwmlme--->send DISASSOCIATE\n"); - //clear related flags - memset(pMgmt->abyDesireBSSID, 0xFF,6); - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); + if (pDevice->bLinkPass == true) { + printk("iwctl_siwmlme--->send DISASSOCIATE\n"); + //clear related flags + memset(pMgmt->abyDesireBSSID, 0xFF, 6); + KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); } break; @@ -2075,96 +2075,96 @@ int iwctl_siwmlme(struct net_device *dev, /* -static const iw_handler iwctl_handler[] = -{ - (iw_handler) iwctl_commit, // SIOCSIWCOMMIT - (iw_handler) iwctl_giwname, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (iw_handler) NULL, // SIOCGIWNWID - (iw_handler) iwctl_siwfreq, // SIOCSIWFREQ - (iw_handler) iwctl_giwfreq, // SIOCGIWFREQ - (iw_handler) iwctl_siwmode, // SIOCSIWMODE - (iw_handler) iwctl_giwmode, // SIOCGIWMODE - (iw_handler) NULL, // SIOCSIWSENS - (iw_handler) iwctl_giwsens, // SIOCGIWSENS - (iw_handler) NULL, // SIOCSIWRANGE - (iw_handler) iwctl_giwrange, // SIOCGIWRANGE - (iw_handler) NULL, // SIOCSIWPRIV - (iw_handler) NULL, // SIOCGIWPRIV - (iw_handler) NULL, // SIOCSIWSTATS - (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY - (iw_handler) NULL, // SIOCGIWSPY - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) iwctl_siwap, // SIOCSIWAP - (iw_handler) iwctl_giwap, // SIOCGIWAP - (iw_handler) NULL, // -- hole -- 0x16 - (iw_handler) iwctl_giwaplist, // SIOCGIWAPLIST - (iw_handler) iwctl_siwscan, // SIOCSIWSCAN - (iw_handler) iwctl_giwscan, // SIOCGIWSCAN - (iw_handler) iwctl_siwessid, // SIOCSIWESSID - (iw_handler) iwctl_giwessid, // SIOCGIWESSID - (iw_handler) NULL, // SIOCSIWNICKN - (iw_handler) NULL, // SIOCGIWNICKN - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) iwctl_siwrate, // SIOCSIWRATE 0x20 - (iw_handler) iwctl_giwrate, // SIOCGIWRATE - (iw_handler) iwctl_siwrts, // SIOCSIWRTS - (iw_handler) iwctl_giwrts, // SIOCGIWRTS - (iw_handler) iwctl_siwfrag, // SIOCSIWFRAG - (iw_handler) iwctl_giwfrag, // SIOCGIWFRAG - (iw_handler) NULL, // SIOCSIWTXPOW - (iw_handler) NULL, // SIOCGIWTXPOW - (iw_handler) iwctl_siwretry, // SIOCSIWRETRY - (iw_handler) iwctl_giwretry, // SIOCGIWRETRY - (iw_handler) iwctl_siwencode, // SIOCSIWENCODE - (iw_handler) iwctl_giwencode, // SIOCGIWENCODE - (iw_handler) iwctl_siwpower, // SIOCSIWPOWER - (iw_handler) iwctl_giwpower, // SIOCGIWPOWER - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) iwctl_siwgenie, // SIOCSIWGENIE - (iw_handler) iwctl_giwgenie, // SIOCGIWGENIE - (iw_handler) iwctl_siwauth, // SIOCSIWAUTH - (iw_handler) iwctl_giwauth, // SIOCGIWAUTH - (iw_handler) iwctl_siwencodeext, // SIOCSIWENCODEEXT - (iw_handler) iwctl_giwencodeext, // SIOCGIWENCODEEXT - (iw_handler) NULL, // SIOCSIWPMKSA - (iw_handler) NULL, // -- hole -- - -}; + static const iw_handler iwctl_handler[] = + { + (iw_handler) iwctl_commit, // SIOCSIWCOMMIT + (iw_handler) iwctl_giwname, // SIOCGIWNAME + (iw_handler) NULL, // SIOCSIWNWID + (iw_handler) NULL, // SIOCGIWNWID + (iw_handler) iwctl_siwfreq, // SIOCSIWFREQ + (iw_handler) iwctl_giwfreq, // SIOCGIWFREQ + (iw_handler) iwctl_siwmode, // SIOCSIWMODE + (iw_handler) iwctl_giwmode, // SIOCGIWMODE + (iw_handler) NULL, // SIOCSIWSENS + (iw_handler) iwctl_giwsens, // SIOCGIWSENS + (iw_handler) NULL, // SIOCSIWRANGE + (iw_handler) iwctl_giwrange, // SIOCGIWRANGE + (iw_handler) NULL, // SIOCSIWPRIV + (iw_handler) NULL, // SIOCGIWPRIV + (iw_handler) NULL, // SIOCSIWSTATS + (iw_handler) NULL, // SIOCGIWSTATS + (iw_handler) NULL, // SIOCSIWSPY + (iw_handler) NULL, // SIOCGIWSPY + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // -- hole -- + (iw_handler) iwctl_siwap, // SIOCSIWAP + (iw_handler) iwctl_giwap, // SIOCGIWAP + (iw_handler) NULL, // -- hole -- 0x16 + (iw_handler) iwctl_giwaplist, // SIOCGIWAPLIST + (iw_handler) iwctl_siwscan, // SIOCSIWSCAN + (iw_handler) iwctl_giwscan, // SIOCGIWSCAN + (iw_handler) iwctl_siwessid, // SIOCSIWESSID + (iw_handler) iwctl_giwessid, // SIOCGIWESSID + (iw_handler) NULL, // SIOCSIWNICKN + (iw_handler) NULL, // SIOCGIWNICKN + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // -- hole -- + (iw_handler) iwctl_siwrate, // SIOCSIWRATE 0x20 + (iw_handler) iwctl_giwrate, // SIOCGIWRATE + (iw_handler) iwctl_siwrts, // SIOCSIWRTS + (iw_handler) iwctl_giwrts, // SIOCGIWRTS + (iw_handler) iwctl_siwfrag, // SIOCSIWFRAG + (iw_handler) iwctl_giwfrag, // SIOCGIWFRAG + (iw_handler) NULL, // SIOCSIWTXPOW + (iw_handler) NULL, // SIOCGIWTXPOW + (iw_handler) iwctl_siwretry, // SIOCSIWRETRY + (iw_handler) iwctl_giwretry, // SIOCGIWRETRY + (iw_handler) iwctl_siwencode, // SIOCSIWENCODE + (iw_handler) iwctl_giwencode, // SIOCGIWENCODE + (iw_handler) iwctl_siwpower, // SIOCSIWPOWER + (iw_handler) iwctl_giwpower, // SIOCGIWPOWER + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // -- hole -- + (iw_handler) iwctl_siwgenie, // SIOCSIWGENIE + (iw_handler) iwctl_giwgenie, // SIOCGIWGENIE + (iw_handler) iwctl_siwauth, // SIOCSIWAUTH + (iw_handler) iwctl_giwauth, // SIOCGIWAUTH + (iw_handler) iwctl_siwencodeext, // SIOCSIWENCODEEXT + (iw_handler) iwctl_giwencodeext, // SIOCGIWENCODEEXT + (iw_handler) NULL, // SIOCSIWPMKSA + (iw_handler) NULL, // -- hole -- + + }; */ static const iw_handler iwctl_handler[] = { (iw_handler) iwctl_commit, // SIOCSIWCOMMIT - (iw_handler) NULL, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (iw_handler) NULL, // SIOCGIWNWID + (iw_handler) NULL, // SIOCGIWNAME + (iw_handler) NULL, // SIOCSIWNWID + (iw_handler) NULL, // SIOCGIWNWID (iw_handler) NULL, // SIOCSIWFREQ (iw_handler) NULL, // SIOCGIWFREQ (iw_handler) NULL, // SIOCSIWMODE (iw_handler) NULL, // SIOCGIWMODE - (iw_handler) NULL, // SIOCSIWSENS - (iw_handler) NULL, // SIOCGIWSENS - (iw_handler) NULL, // SIOCSIWRANGE - (iw_handler) iwctl_giwrange, // SIOCGIWRANGE - (iw_handler) NULL, // SIOCSIWPRIV - (iw_handler) NULL, // SIOCGIWPRIV - (iw_handler) NULL, // SIOCSIWSTATS - (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY - (iw_handler) NULL, // SIOCGIWSPY - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWAP - (iw_handler) NULL, // SIOCGIWAP - (iw_handler) NULL, // -- hole -- 0x16 - (iw_handler) NULL, // SIOCGIWAPLIST - (iw_handler) iwctl_siwscan, // SIOCSIWSCAN - (iw_handler) iwctl_giwscan, // SIOCGIWSCAN + (iw_handler) NULL, // SIOCSIWSENS + (iw_handler) NULL, // SIOCGIWSENS + (iw_handler) NULL, // SIOCSIWRANGE + (iw_handler) iwctl_giwrange, // SIOCGIWRANGE + (iw_handler) NULL, // SIOCSIWPRIV + (iw_handler) NULL, // SIOCGIWPRIV + (iw_handler) NULL, // SIOCSIWSTATS + (iw_handler) NULL, // SIOCGIWSTATS + (iw_handler) NULL, // SIOCSIWSPY + (iw_handler) NULL, // SIOCGIWSPY + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // SIOCSIWAP + (iw_handler) NULL, // SIOCGIWAP + (iw_handler) NULL, // -- hole -- 0x16 + (iw_handler) NULL, // SIOCGIWAPLIST + (iw_handler) iwctl_siwscan, // SIOCSIWSCAN + (iw_handler) iwctl_giwscan, // SIOCGIWSCAN (iw_handler) NULL, // SIOCSIWESSID (iw_handler) NULL, // SIOCGIWESSID (iw_handler) NULL, // SIOCSIWNICKN @@ -2187,16 +2187,16 @@ static const iw_handler iwctl_handler[] = (iw_handler) NULL, // SIOCGIWPOWER //2008-0409-07, by Einsn Liu - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWGENIE - (iw_handler) NULL, // SIOCGIWGENIE + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // SIOCSIWGENIE + (iw_handler) NULL, // SIOCGIWGENIE (iw_handler) NULL, // SIOCSIWAUTH (iw_handler) NULL, // SIOCGIWAUTH (iw_handler) NULL, // SIOCSIWENCODEEXT (iw_handler) NULL, // SIOCGIWENCODEEXT - (iw_handler) NULL, // SIOCSIWPMKSA - (iw_handler) NULL, // -- hole -- + (iw_handler) NULL, // SIOCSIWPMKSA + (iw_handler) NULL, // -- hole -- }; @@ -2207,9 +2207,9 @@ static const iw_handler iwctl_private_handler[] = struct iw_priv_args iwctl_private_args[] = { -{ IOCTL_CMD_SET, - IW_PRIV_TYPE_CHAR | 1024, 0, - "set"}, + { IOCTL_CMD_SET, + IW_PRIV_TYPE_CHAR | 1024, 0, + "set"}, }; @@ -2222,7 +2222,7 @@ const struct iw_handler_def iwctl_handler_def = // .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args), .num_private = 0, .num_private_args = 0, - .standard = (iw_handler *) iwctl_handler, + .standard = (iw_handler *)iwctl_handler, // .private = (iw_handler *) iwctl_private_handler, // .private_args = (struct iw_priv_args *)iwctl_private_args, .private = NULL, diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h index d224f913a624..c36dd748f521 100644 --- a/drivers/staging/vt6655/iwctl.h +++ b/drivers/staging/vt6655/iwctl.h @@ -40,177 +40,177 @@ /*--------------------- Export Functions --------------------------*/ -struct iw_statistics *iwctl_get_wireless_stats (struct net_device *dev); +struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev); int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); + struct iw_request_info *info, + struct sockaddr *wrq, + char *extra); int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); + struct iw_request_info *info, + __u32 *wmode, + char *extra); int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); + struct iw_request_info *info, + __u32 *wmode, + char *extra); int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); + struct iw_request_info *info, + struct iw_freq *wrq, + char *extra); int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); + struct iw_request_info *info, + struct iw_freq *wrq, + char *extra); int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra); + struct iw_request_info *info, + char *wrq, + char *extra); int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); + struct iw_request_info *info, + struct sockaddr *wrq, + char *extra); int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); //2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); + struct iw_request_info *info, + struct iw_param *wrq, + char *extra); int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info * info, - struct iw_point *wrq, - char *extra); + struct iw_request_info *info, + struct iw_point *wrq, + char *extra); #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //End Add -- //2008-0409-07, by Einsn Liu -- cgit From d82adcabc603ce1d2c2ef86e33fb50214dfcf4d8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:54 -0700 Subject: staging:vt6655:key: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/key.c | 1160 +++++++++++++++++++++--------------------- drivers/staging/vt6655/key.h | 168 +++--- 2 files changed, 664 insertions(+), 664 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 194fedc715fa..63ef58f0ad60 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -45,7 +45,7 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Functions --------------------------*/ @@ -59,25 +59,25 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ static void -s_vCheckKeyTableValid (PSKeyManagement pTable, unsigned long dwIoBase) +s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase) { - int i; - - for (i=0;iKeyTable[i].bInUse == true) && - (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[3].bKeyValid == false) - ) { - - pTable->KeyTable[i].bInUse = false; - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } - } + int i; + + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) && + (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) && + (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) && + (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) && + (pTable->KeyTable[i].GroupKey[3].bKeyValid == false) +) { + + pTable->KeyTable[i].bInUse = false; + pTable->KeyTable[i].wKeyCtl = 0; + pTable->KeyTable[i].bSoftWEP = false; + MACvDisableKeyEntry(dwIoBase, i); + } + } } @@ -96,24 +96,24 @@ s_vCheckKeyTableValid (PSKeyManagement pTable, unsigned long dwIoBase) * Return Value: none * */ -void KeyvInitTable (PSKeyManagement pTable, unsigned long dwIoBase) +void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase) { - int i; - int jj; - - for (i=0;iKeyTable[i].bInUse = false; - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i]; - for (jj=0; jj < MAX_GROUP_KEY; jj++) { - pTable->KeyTable[i].GroupKey[jj].bKeyValid = false; - pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i]; - } - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].dwGTKeyIndex = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } + int i; + int jj; + + for (i = 0; i < MAX_KEY_TABLE; i++) { + pTable->KeyTable[i].bInUse = false; + pTable->KeyTable[i].PairwiseKey.bKeyValid = false; + pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i]; + for (jj = 0; jj < MAX_GROUP_KEY; jj++) { + pTable->KeyTable[i].GroupKey[jj].bKeyValid = false; + pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i]; + } + pTable->KeyTable[i].wKeyCtl = 0; + pTable->KeyTable[i].dwGTKeyIndex = 0; + pTable->KeyTable[i].bSoftWEP = false; + MACvDisableKeyEntry(dwIoBase, i); + } } @@ -131,44 +131,44 @@ void KeyvInitTable (PSKeyManagement pTable, unsigned long dwIoBase) * Return Value: true if found otherwise false * */ -bool KeybGetKey ( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey - ) +bool KeybGetKey( + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + PSKeyItem *pKey +) { - int i; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n"); - - *pKey = NULL; - for (i=0;iKeyTable[i].bInUse == true) && - !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if (dwKeyIndex == 0xFFFFFFFF) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return (true); - } - else { - return (false); - } - } else if (dwKeyIndex < MAX_GROUP_KEY) { - if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) { - *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]); - return (true); - } - else { - return (false); - } - } - else { - return (false); - } - } - } - return (false); + int i; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetKey() \n"); + + *pKey = NULL; + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { + if (dwKeyIndex == 0xFFFFFFFF) { + if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { + *pKey = &(pTable->KeyTable[i].PairwiseKey); + return (true); + } + else { + return (false); + } + } else if (dwKeyIndex < MAX_GROUP_KEY) { + if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) { + *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]); + return (true); + } + else { + return (false); + } + } + else { + return (false); + } + } + } + return (false); } @@ -189,162 +189,162 @@ bool KeybGetKey ( * Return Value: true if success otherwise false * */ -bool KeybSetKey ( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ) +bool KeybSetKey( + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +) { - int i,j; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex); - - j = (MAX_KEY_TABLE-1); - for (i=0;i<(MAX_KEY_TABLE-1);i++) { - if ((pTable->KeyTable[i].bInUse == false) && - (j == (MAX_KEY_TABLE-1))) { - // found empty table - j = i; - } - if ((pTable->KeyTable[i].bInUse == true) && - !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - // found table already exist - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[i].PairwiseKey); - pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[i].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return (false); - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); - } - else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return (true); - } - } - if (j < (MAX_KEY_TABLE-1)) { - memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,ETH_ALEN); - pTable->KeyTable[j].bInUse = true; - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[j].PairwiseKey); - pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[j].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return (false); - pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j); - } - pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); - } - else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return (true); - } - return (false); + int i, j; + unsigned int ii; + PSKeyItem pKey; + unsigned int uKeyIdx; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetKey: %lX\n", dwKeyIndex); + + j = (MAX_KEY_TABLE-1); + for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { + if ((pTable->KeyTable[i].bInUse == false) && + (j == (MAX_KEY_TABLE-1))) { + // found empty table + j = i; + } + if ((pTable->KeyTable[i].bInUse == true) && + !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { + // found table already exist + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { + // Pairwise key + pKey = &(pTable->KeyTable[i].PairwiseKey); + pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed + pTable->KeyTable[i].wKeyCtl |= byKeyDecMode; + uKeyIdx = 4; // use HW key entry 4 for pairwise key + } else { + // Group key + if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) + return (false); + pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); + if ((dwKeyIndex & TRANSMIT_KEY) != 0) { + // Group transmit key + pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + } + pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed + pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); + pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address + uKeyIdx = (dwKeyIndex & 0x000000FF); + } + pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly + + pKey->bKeyValid = true; + pKey->uKeyLength = uKeyLength; + pKey->dwKeyIndex = dwKeyIndex; + pKey->byCipherSuite = byKeyDecMode; + memcpy(pKey->abyKey, pbyKey, uKeyLength); + if (byKeyDecMode == KEY_CTL_WEP) { + if (uKeyLength == WLAN_WEP40_KEYLEN) + pKey->abyKey[15] &= 0x7F; + if (uKeyLength == WLAN_WEP104_KEYLEN) + pKey->abyKey[15] |= 0x80; + } + MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID); + + if ((dwKeyIndex & USE_KEYRSC) == 0) { + // RSC set by NIC + memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + } + else { + memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + } + pKey->dwTSC47_16 = 0; + pKey->wTSC15_0 = 0; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", pKey->uKeyLength); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + for (ii = 0; ii < pKey->uKeyLength; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + + return (true); + } + } + if (j < (MAX_KEY_TABLE-1)) { + memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN); + pTable->KeyTable[j].bInUse = true; + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { + // Pairwise key + pKey = &(pTable->KeyTable[j].PairwiseKey); + pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed + pTable->KeyTable[j].wKeyCtl |= byKeyDecMode; + uKeyIdx = 4; // use HW key entry 4 for pairwise key + } else { + // Group key + if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) + return (false); + pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]); + if ((dwKeyIndex & TRANSMIT_KEY) != 0) { + // Group transmit key + pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j); + } + pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed + pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); + pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address + uKeyIdx = (dwKeyIndex & 0x000000FF); + } + pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly + + pKey->bKeyValid = true; + pKey->uKeyLength = uKeyLength; + pKey->dwKeyIndex = dwKeyIndex; + pKey->byCipherSuite = byKeyDecMode; + memcpy(pKey->abyKey, pbyKey, uKeyLength); + if (byKeyDecMode == KEY_CTL_WEP) { + if (uKeyLength == WLAN_WEP40_KEYLEN) + pKey->abyKey[15] &= 0x7F; + if (uKeyLength == WLAN_WEP104_KEYLEN) + pKey->abyKey[15] |= 0x80; + } + MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID); + + if ((dwKeyIndex & USE_KEYRSC) == 0) { + // RSC set by NIC + memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + } + else { + memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + } + pKey->dwTSC47_16 = 0; + pKey->wTSC15_0 = 0; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(N): \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + for (ii = 0; ii < pKey->uKeyLength; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + + return (true); + } + return (false); } @@ -362,63 +362,63 @@ bool KeybSetKey ( * Return Value: true if success otherwise false * */ -bool KeybRemoveKey ( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long dwIoBase - ) +bool KeybRemoveKey( + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + unsigned long dwIoBase +) { - int i; - - if (is_broadcast_ether_addr(pbyBSSID)) { - // delete all keys - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - for (i=0;iKeyTable[i].PairwiseKey.bKeyValid = false; - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - for (i=0;iKeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - else { - return false; - } - } - - for (i=0;iKeyTable[i].bInUse == true) && - !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - s_vCheckKeyTableValid(pTable, dwIoBase); - return (true); - } - else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return (true); - } - else { - return (false); - } - } - } - return (false); + int i; + + if (is_broadcast_ether_addr(pbyBSSID)) { + // delete all keys + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { + for (i = 0; i < MAX_KEY_TABLE; i++) { + pTable->KeyTable[i].PairwiseKey.bKeyValid = false; + } + s_vCheckKeyTableValid(pTable, dwIoBase); + return true; + } + else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { + for (i = 0; i < MAX_KEY_TABLE; i++) { + pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; + if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { + // remove Group transmit key + pTable->KeyTable[i].dwGTKeyIndex = 0; + } + } + s_vCheckKeyTableValid(pTable, dwIoBase); + return true; + } + else { + return false; + } + } + + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { + pTable->KeyTable[i].PairwiseKey.bKeyValid = false; + s_vCheckKeyTableValid(pTable, dwIoBase); + return (true); + } + else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { + pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; + if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { + // remove Group transmit key + pTable->KeyTable[i].dwGTKeyIndex = 0; + } + s_vCheckKeyTableValid(pTable, dwIoBase); + return (true); + } + else { + return (false); + } + } + } + return (false); } @@ -435,27 +435,27 @@ bool KeybRemoveKey ( * Return Value: true if success otherwise false * */ -bool KeybRemoveAllKey ( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwIoBase - ) +bool KeybRemoveAllKey( + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwIoBase +) { - int i,u; - - for (i=0;iKeyTable[i].bInUse == true) && - !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - for(u=0;uKeyTable[i].GroupKey[u].bKeyValid = false; - } - pTable->KeyTable[i].dwGTKeyIndex = 0; - s_vCheckKeyTableValid(pTable, dwIoBase); - return (true); - } - } - return (false); + int i, u; + + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { + pTable->KeyTable[i].PairwiseKey.bKeyValid = false; + for (u = 0; u < MAX_GROUP_KEY; u++) { + pTable->KeyTable[i].GroupKey[u].bKeyValid = false; + } + pTable->KeyTable[i].dwGTKeyIndex = 0; + s_vCheckKeyTableValid(pTable, dwIoBase); + return (true); + } + } + return (false); } /* @@ -470,38 +470,38 @@ bool KeybRemoveAllKey ( * Return Value: true if success otherwise false * */ -void KeyvRemoveWEPKey ( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long dwIoBase - ) +void KeyvRemoveWEPKey( + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long dwIoBase +) { - if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) { - pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0; - } - } - } - s_vCheckKeyTableValid(pTable, dwIoBase); - } - return; + if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { + if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) { + if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) { + pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; + if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) { + // remove Group transmit key + pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0; + } + } + } + s_vCheckKeyTableValid(pTable, dwIoBase); + } + return; } -void KeyvRemoveAllWEPKey ( - PSKeyManagement pTable, - unsigned long dwIoBase - ) +void KeyvRemoveAllWEPKey( + PSKeyManagement pTable, + unsigned long dwIoBase +) { - int i; + int i; - for(i=0;iKeyTable[i].bInUse == true) && - !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - - if (dwKeyType == PAIRWISE_KEY) { - - if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: "); - for (ii = 0; ii < 6; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - - return (true); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n"); - return (false); - } - } // End of Type == PAIRWISE - else { - if (pTable->KeyTable[i].dwGTKeyIndex == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n"); - return false; - } - if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) { - *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n"); - for (ii = 0; ii < 6; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex); - - return (true); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n"); - return (false); - } - } // End of Type = GROUP - } // BSSID match - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! "); - for (ii = 0; ii < 6; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii)); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - return (false); + int i, ii; + + *pKey = NULL; + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { + + if (dwKeyType == PAIRWISE_KEY) { + + if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { + *pKey = &(pTable->KeyTable[i].PairwiseKey); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PAIRWISE_KEY: KeyTable.abyBSSID: "); + for (ii = 0; ii < 6; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + + return (true); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PairwiseKey.bKeyValid == false\n"); + return (false); + } + } // End of Type == PAIRWISE + else { + if (pTable->KeyTable[i].dwGTKeyIndex == 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: dwGTKeyIndex == 0 !!!\n"); + return false; + } + if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) { + *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP_KEY: KeyTable.abyBSSID\n"); + for (ii = 0; ii < 6; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex); + + return (true); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GroupKey.bKeyValid == false\n"); + return (false); + } + } // End of Type = GROUP + } // BSSID match + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: NO Match BSSID !!! "); + for (ii = 0; ii < 6; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *(pbyBSSID+ii)); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + return (false); } @@ -597,22 +597,22 @@ bool KeybGetTransmitKey ( * Return Value: true if found otherwise false * */ -bool KeybCheckPairewiseKey ( - PSKeyManagement pTable, - PSKeyItem *pKey - ) +bool KeybCheckPairewiseKey( + PSKeyManagement pTable, + PSKeyItem *pKey +) { - int i; - - *pKey = NULL; - for (i=0;iKeyTable[i].bInUse == true) && - (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return (true); - } - } - return (false); + int i; + + *pKey = NULL; + for (i = 0; i < MAX_KEY_TABLE; i++) { + if ((pTable->KeyTable[i].bInUse == true) && + (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) { + *pKey = &(pTable->KeyTable[i].PairwiseKey); + return (true); + } + } + return (false); } /* @@ -631,97 +631,97 @@ bool KeybCheckPairewiseKey ( * Return Value: true if success otherwise false * */ -bool KeybSetDefaultKey ( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ) +bool KeybSetDefaultKey( + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +) { - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength); - - - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key - return (false); - } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) { - return (false); - } - - if (uKeyLength > MAX_KEY_LEN) - return false; - - pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true; - for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; - - // Group key - pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1); - - } - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address - uKeyIdx = (dwKeyIndex & 0x000000FF); - - if ((uKeyLength == WLAN_WEP232_KEYLEN) && - (byKeyDecMode == KEY_CTL_WEP)) { - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match - pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true; - } else { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false) - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match - } - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); - } else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n"); - for (ii = 0; ii < pKey->uKeyLength; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); - - return (true); + unsigned int ii; + PSKeyItem pKey; + unsigned int uKeyIdx; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength); + + + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key + return (false); + } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) { + return (false); + } + + if (uKeyLength > MAX_KEY_LEN) + return false; + + pTable->KeyTable[MAX_KEY_TABLE - 1].bInUse = true; + for (ii = 0; ii < ETH_ALEN; ii++) + pTable->KeyTable[MAX_KEY_TABLE - 1].abyBSSID[ii] = 0xFF; + + // Group key + pKey = &(pTable->KeyTable[MAX_KEY_TABLE - 1].GroupKey[dwKeyIndex & 0x000000FF]); + if ((dwKeyIndex & TRANSMIT_KEY) != 0) { + // Group transmit key + pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1); + + } + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4); + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode); + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address + uKeyIdx = (dwKeyIndex & 0x000000FF); + + if ((uKeyLength == WLAN_WEP232_KEYLEN) && + (byKeyDecMode == KEY_CTL_WEP)) { + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match + pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true; + } else { + if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false) + pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match + } + + pKey->bKeyValid = true; + pKey->uKeyLength = uKeyLength; + pKey->dwKeyIndex = dwKeyIndex; + pKey->byCipherSuite = byKeyDecMode; + memcpy(pKey->abyKey, pbyKey, uKeyLength); + if (byKeyDecMode == KEY_CTL_WEP) { + if (uKeyLength == WLAN_WEP40_KEYLEN) + pKey->abyKey[15] &= 0x7F; + if (uKeyLength == WLAN_WEP104_KEYLEN) + pKey->abyKey[15] |= 0x80; + } + MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID); + + if ((dwKeyIndex & USE_KEYRSC) == 0) { + // RSC set by NIC + memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + } else { + memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + } + pKey->dwTSC47_16 = 0; + pKey->wTSC15_0 = 0; + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n", pKey->bKeyValid); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n", (int)pKey->uKeyLength); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: \n"); + for (ii = 0; ii < pKey->uKeyLength; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x", pKey->abyKey[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n", pKey->wTSC15_0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); + + return (true); } @@ -741,86 +741,86 @@ bool KeybSetDefaultKey ( * Return Value: true if success otherwise false * */ -bool KeybSetAllGroupKey ( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ) +bool KeybSetAllGroupKey( + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +) { - int i; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); - - - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key - return (false); - } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) { - return (false); - } - - for (i=0; i < MAX_KEY_TABLE-1; i++) { - if (pTable->KeyTable[i].bInUse == true) { - // found table already exist - // Group key - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); - - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); - } - else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - - //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16)); - //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0)); - //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex)); - - } // (pTable->KeyTable[i].bInUse == true) - } - return (true); + int i; + unsigned int ii; + PSKeyItem pKey; + unsigned int uKeyIdx; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); + + + if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key + return (false); + } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) { + return (false); + } + + for (i = 0; i < MAX_KEY_TABLE - 1; i++) { + if (pTable->KeyTable[i].bInUse == true) { + // found table already exist + // Group key + pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); + if ((dwKeyIndex & TRANSMIT_KEY) != 0) { + // Group transmit key + pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + + } + pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed + pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); + pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address + uKeyIdx = (dwKeyIndex & 0x000000FF); + + pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly + + pKey->bKeyValid = true; + pKey->uKeyLength = uKeyLength; + pKey->dwKeyIndex = dwKeyIndex; + pKey->byCipherSuite = byKeyDecMode; + memcpy(pKey->abyKey, pbyKey, uKeyLength); + if (byKeyDecMode == KEY_CTL_WEP) { + if (uKeyLength == WLAN_WEP40_KEYLEN) + pKey->abyKey[15] &= 0x7F; + if (uKeyLength == WLAN_WEP104_KEYLEN) + pKey->abyKey[15] |= 0x80; + } + MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID); + + if ((dwKeyIndex & USE_KEYRSC) == 0) { + // RSC set by NIC + memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + } + else { + memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + } + pKey->dwTSC47_16 = 0; + pKey->wTSC15_0 = 0; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + for (ii = 0; ii < pKey->uKeyLength; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + + //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16)); + //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0)); + //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex)); + + } // (pTable->KeyTable[i].bInUse == true) + } + return (true); } diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 6b2dad331a5b..f09cdb1885fb 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -57,39 +57,39 @@ typedef struct tagSKeyItem { - bool bKeyValid; - unsigned long uKeyLength; - unsigned char abyKey[MAX_KEY_LEN]; - QWORD KeyRSC; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned char byCipherSuite; - unsigned char byReserved0; - unsigned long dwKeyIndex; - void *pvKeyTable; + bool bKeyValid; + unsigned long uKeyLength; + unsigned char abyKey[MAX_KEY_LEN]; + QWORD KeyRSC; + unsigned long dwTSC47_16; + unsigned short wTSC15_0; + unsigned char byCipherSuite; + unsigned char byReserved0; + unsigned long dwKeyIndex; + void *pvKeyTable; } SKeyItem, *PSKeyItem; //64 typedef struct tagSKeyTable { - unsigned char abyBSSID[ETH_ALEN]; //6 - unsigned char byReserved0[2]; //8 - SKeyItem PairwiseKey; - SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 - unsigned long dwGTKeyIndex; // GroupTransmitKey Index - bool bInUse; - //2006-1116-01, by NomadZhao - //unsigned short wKeyCtl; - //bool bSoftWEP; - bool bSoftWEP; - unsigned short wKeyCtl; // for address of wKeyCtl at align 4 - - unsigned char byReserved1[6]; + unsigned char abyBSSID[ETH_ALEN]; //6 + unsigned char byReserved0[2]; //8 + SKeyItem PairwiseKey; + SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 + unsigned long dwGTKeyIndex; // GroupTransmitKey Index + bool bInUse; + //2006-1116-01, by NomadZhao + //unsigned short wKeyCtl; + //bool bSoftWEP; + bool bSoftWEP; + unsigned short wKeyCtl; // for address of wKeyCtl at align 4 + + unsigned char byReserved1[6]; } SKeyTable, *PSKeyTable; //348 typedef struct tagSKeyManagement { - SKeyTable KeyTable[MAX_KEY_TABLE]; -} SKeyManagement, * PSKeyManagement; + SKeyTable KeyTable[MAX_KEY_TABLE]; +} SKeyManagement, *PSKeyManagement; /*--------------------- Export Types ------------------------------*/ @@ -104,81 +104,81 @@ typedef struct tagSKeyManagement void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase); bool KeybGetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey - ); + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + PSKeyItem *pKey +); bool KeybSetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ); + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +); bool KeybSetDefaultKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ); + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +); bool KeybRemoveKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long dwIoBase - ); + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyIndex, + unsigned long dwIoBase +); bool KeybGetTransmitKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyType, - PSKeyItem *pKey - ); + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwKeyType, + PSKeyItem *pKey +); bool KeybCheckPairewiseKey( - PSKeyManagement pTable, - PSKeyItem *pKey - ); + PSKeyManagement pTable, + PSKeyItem *pKey +); bool KeybRemoveAllKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwIoBase - ); + PSKeyManagement pTable, + unsigned char *pbyBSSID, + unsigned long dwIoBase +); void KeyvRemoveWEPKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long dwIoBase - ); + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long dwIoBase +); void KeyvRemoveAllWEPKey( - PSKeyManagement pTable, - unsigned long dwIoBase - ); - -bool KeybSetAllGroupKey ( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - PQWORD pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - unsigned long dwIoBase, - unsigned char byLocalID - ); + PSKeyManagement pTable, + unsigned long dwIoBase +); + +bool KeybSetAllGroupKey( + PSKeyManagement pTable, + unsigned long dwKeyIndex, + unsigned long uKeyLength, + PQWORD pKeyRSC, + unsigned char *pbyKey, + unsigned char byKeyDecMode, + unsigned long dwIoBase, + unsigned char byLocalID +); #endif // __KEY_H__ -- cgit From c3504bfd11f084636a7a6a1dfce318c6ce8ddbcc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:55 -0700 Subject: staging:vt6655:mac: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mac.c | 1632 +++++++++++++++++++++--------------------- drivers/staging/vt6655/mac.h | 836 +++++++++++----------- 2 files changed, 1234 insertions(+), 1234 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 30c261579412..33e89f0319d6 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -75,7 +75,7 @@ unsigned short TxRate_iwconfig;//2008-5-8 by chester /*--------------------- Static Definitions -------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -103,25 +103,25 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: none * */ -void MACvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyMacRegs) +void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs) { - int ii; + int ii; - // read page0 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { - VNSvInPortB(dwIoBase + ii, pbyMacRegs); - pbyMacRegs++; - } + // read page0 register + for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { + VNSvInPortB(dwIoBase + ii, pbyMacRegs); + pbyMacRegs++; + } - MACvSelectPage1(dwIoBase); + MACvSelectPage1(dwIoBase); - // read page1 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { - VNSvInPortB(dwIoBase + ii, pbyMacRegs); - pbyMacRegs++; - } + // read page1 register + for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { + VNSvInPortB(dwIoBase + ii, pbyMacRegs); + pbyMacRegs++; + } - MACvSelectPage0(dwIoBase); + MACvSelectPage0(dwIoBase); } @@ -140,12 +140,12 @@ void MACvReadAllRegs (unsigned long dwIoBase, unsigned char *pbyMacRegs) * Return Value: true if all test bits On; otherwise false * */ -bool MACbIsRegBitsOn (unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) +bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) { - unsigned char byData; + unsigned char byData; - VNSvInPortB(dwIoBase + byRegOfs, &byData); - return (byData & byTestBits) == byTestBits; + VNSvInPortB(dwIoBase + byRegOfs, &byData); + return (byData & byTestBits) == byTestBits; } /* @@ -163,12 +163,12 @@ bool MACbIsRegBitsOn (unsigned long dwIoBase, unsigned char byRegOfs, unsigned c * Return Value: true if all test bits Off; otherwise false * */ -bool MACbIsRegBitsOff (unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) +bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) { - unsigned char byData; + unsigned char byData; - VNSvInPortB(dwIoBase + byRegOfs, &byData); - return !(byData & byTestBits); + VNSvInPortB(dwIoBase + byRegOfs, &byData); + return !(byData & byTestBits); } /* @@ -184,15 +184,15 @@ bool MACbIsRegBitsOff (unsigned long dwIoBase, unsigned char byRegOfs, unsigned * Return Value: true if interrupt is disable; otherwise false * */ -bool MACbIsIntDisable (unsigned long dwIoBase) +bool MACbIsIntDisable(unsigned long dwIoBase) { - unsigned long dwData; + unsigned long dwData; - VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData); - if (dwData != 0) - return false; + VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData); + if (dwData != 0) + return false; - return true; + return true; } /* @@ -209,14 +209,14 @@ bool MACbIsIntDisable (unsigned long dwIoBase) * Return Value: Mask Value read * */ -unsigned char MACbyReadMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx) +unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx) { - unsigned char byData; + unsigned char byData; - MACvSelectPage1(dwIoBase); - VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData); - MACvSelectPage0(dwIoBase); - return byData; + MACvSelectPage1(dwIoBase); + VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData); + MACvSelectPage0(dwIoBase); + return byData; } /* @@ -234,11 +234,11 @@ unsigned char MACbyReadMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx) * Return Value: none * */ -void MACvWriteMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData) +void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData) { - MACvSelectPage1(dwIoBase); - VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData); - MACvSelectPage0(dwIoBase); + MACvSelectPage1(dwIoBase); + VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData); + MACvSelectPage0(dwIoBase); } /* @@ -255,21 +255,21 @@ void MACvWriteMultiAddr (unsigned long dwIoBase, unsigned int uByteIdx, unsigned * Return Value: none * */ -void MACvSetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx) +void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx) { - unsigned int uByteIdx; - unsigned char byBitMask; - unsigned char byOrgValue; - - // calculate byte position - uByteIdx = byHashIdx / 8; - ASSERT(uByteIdx < 8); - // calculate bit position - byBitMask = 1; - byBitMask <<= (byHashIdx % 8); - // turn on the bit - byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); - MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask)); + unsigned int uByteIdx; + unsigned char byBitMask; + unsigned char byOrgValue; + + // calculate byte position + uByteIdx = byHashIdx / 8; + ASSERT(uByteIdx < 8); + // calculate bit position + byBitMask = 1; + byBitMask <<= (byHashIdx % 8); + // turn on the bit + byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); + MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask)); } /* @@ -286,21 +286,21 @@ void MACvSetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx) * Return Value: none * */ -void MACvResetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx) +void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx) { - unsigned int uByteIdx; - unsigned char byBitMask; - unsigned char byOrgValue; - - // calculate byte position - uByteIdx = byHashIdx / 8; - ASSERT(uByteIdx < 8); - // calculate bit position - byBitMask = 1; - byBitMask <<= (byHashIdx % 8); - // turn off the bit - byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); - MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask))); + unsigned int uByteIdx; + unsigned char byBitMask; + unsigned char byOrgValue; + + // calculate byte position + uByteIdx = byHashIdx / 8; + ASSERT(uByteIdx < 8); + // calculate bit position + byBitMask = 1; + byBitMask <<= (byHashIdx % 8); + // turn off the bit + byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); + MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask))); } /* @@ -317,16 +317,16 @@ void MACvResetMultiAddrByHash (unsigned long dwIoBase, unsigned char byHashIdx) * Return Value: none * */ -void MACvSetRxThreshold (unsigned long dwIoBase, unsigned char byThreshold) +void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold) { - unsigned char byOrgValue; + unsigned char byOrgValue; - ASSERT(byThreshold < 4); + ASSERT(byThreshold < 4); - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4); - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); + // set FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); + byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4); + VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); } /* @@ -342,11 +342,11 @@ void MACvSetRxThreshold (unsigned long dwIoBase, unsigned char byThreshold) * Return Value: none * */ -void MACvGetRxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold) +void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold) { - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); - *pbyThreshold = (*pbyThreshold >> 4) & 0x03; + // get FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); + *pbyThreshold = (*pbyThreshold >> 4) & 0x03; } /* @@ -363,16 +363,16 @@ void MACvGetRxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold) * Return Value: none * */ -void MACvSetTxThreshold (unsigned long dwIoBase, unsigned char byThreshold) +void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold) { - unsigned char byOrgValue; + unsigned char byOrgValue; - ASSERT(byThreshold < 4); + ASSERT(byThreshold < 4); - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2); - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); + // set FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); + byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2); + VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); } /* @@ -388,11 +388,11 @@ void MACvSetTxThreshold (unsigned long dwIoBase, unsigned char byThreshold) * Return Value: none * */ -void MACvGetTxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold) +void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold) { - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); - *pbyThreshold = (*pbyThreshold >> 2) & 0x03; + // get FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); + *pbyThreshold = (*pbyThreshold >> 2) & 0x03; } /* @@ -409,16 +409,16 @@ void MACvGetTxThreshold (unsigned long dwIoBase, unsigned char *pbyThreshold) * Return Value: none * */ -void MACvSetDmaLength (unsigned long dwIoBase, unsigned char byDmaLength) +void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength) { - unsigned char byOrgValue; + unsigned char byOrgValue; - ASSERT(byDmaLength < 4); + ASSERT(byDmaLength < 4); - // set FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); - byOrgValue = (byOrgValue & 0xFC) | byDmaLength; - VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); + // set FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); + byOrgValue = (byOrgValue & 0xFC) | byDmaLength; + VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); } /* @@ -434,11 +434,11 @@ void MACvSetDmaLength (unsigned long dwIoBase, unsigned char byDmaLength) * Return Value: none * */ -void MACvGetDmaLength (unsigned long dwIoBase, unsigned char *pbyDmaLength) +void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength) { - // get FCR0 - VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength); - *pbyDmaLength &= 0x03; + // get FCR0 + VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength); + *pbyDmaLength &= 0x03; } /* @@ -455,10 +455,10 @@ void MACvGetDmaLength (unsigned long dwIoBase, unsigned char *pbyDmaLength) * Return Value: none * */ -void MACvSetShortRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit) +void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit) { - // set SRT - VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit); + // set SRT + VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit); } /* @@ -474,10 +474,10 @@ void MACvSetShortRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit) * Return Value: none * */ -void MACvGetShortRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimit) +void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit) { - // get SRT - VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit); + // get SRT + VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit); } /* @@ -494,10 +494,10 @@ void MACvGetShortRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimi * Return Value: none * */ -void MACvSetLongRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit) +void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit) { - // set LRT - VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit); + // set LRT + VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit); } /* @@ -513,10 +513,10 @@ void MACvSetLongRetryLimit (unsigned long dwIoBase, unsigned char byRetryLimit) * Return Value: none * */ -void MACvGetLongRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimit) +void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit) { - // get LRT - VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit); + // get LRT + VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit); } /* @@ -533,17 +533,17 @@ void MACvGetLongRetryLimit (unsigned long dwIoBase, unsigned char *pbyRetryLimit * Return Value: none * */ -void MACvSetLoopbackMode (unsigned long dwIoBase, unsigned char byLoopbackMode) +void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode) { - unsigned char byOrgValue; - - ASSERT(byLoopbackMode < 3); - byLoopbackMode <<= 6; - // set TCR - VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); - byOrgValue = byOrgValue & 0x3F; - byOrgValue = byOrgValue | byLoopbackMode; - VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue); + unsigned char byOrgValue; + + ASSERT(byLoopbackMode < 3); + byLoopbackMode <<= 6; + // set TCR + VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); + byOrgValue = byOrgValue & 0x3F; + byOrgValue = byOrgValue | byLoopbackMode; + VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue); } /* @@ -559,14 +559,14 @@ void MACvSetLoopbackMode (unsigned long dwIoBase, unsigned char byLoopbackMode) * Return Value: true if in Loopback mode; otherwise false * */ -bool MACbIsInLoopbackMode (unsigned long dwIoBase) +bool MACbIsInLoopbackMode(unsigned long dwIoBase) { - unsigned char byOrgValue; + unsigned char byOrgValue; - VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); - if (byOrgValue & (TEST_LBINT | TEST_LBEXT)) - return true; - return false; + VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); + if (byOrgValue & (TEST_LBINT | TEST_LBEXT)) + return true; + return false; } /* @@ -583,51 +583,51 @@ bool MACbIsInLoopbackMode (unsigned long dwIoBase) * Return Value: none * */ -void MACvSetPacketFilter (unsigned long dwIoBase, unsigned short wFilterType) +void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType) { - unsigned char byOldRCR; - unsigned char byNewRCR = 0; - - // if only in DIRECTED mode, multicast-address will set to zero, - // but if other mode exist (e.g. PROMISCUOUS), multicast-address - // will be open - if (wFilterType & PKT_TYPE_DIRECTED) { - // set multicast address to accept none - MACvSelectPage1(dwIoBase); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L); - MACvSelectPage0(dwIoBase); - } - - if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) { - // set multicast address to accept all - MACvSelectPage1(dwIoBase); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL); - VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL); - MACvSelectPage0(dwIoBase); - } - - if (wFilterType & PKT_TYPE_PROMISCUOUS) { - - byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST); - - byNewRCR &= ~RCR_BSSID; - } - - if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)) - byNewRCR |= RCR_MULTICAST; - - if (wFilterType & PKT_TYPE_BROADCAST) - byNewRCR |= RCR_BROADCAST; - - if (wFilterType & PKT_TYPE_ERROR_CRC) - byNewRCR |= RCR_ERRCRC; - - VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR); - if (byNewRCR != byOldRCR) { - // Modify the Receive Command Register - VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR); - } + unsigned char byOldRCR; + unsigned char byNewRCR = 0; + + // if only in DIRECTED mode, multicast-address will set to zero, + // but if other mode exist (e.g. PROMISCUOUS), multicast-address + // will be open + if (wFilterType & PKT_TYPE_DIRECTED) { + // set multicast address to accept none + MACvSelectPage1(dwIoBase); + VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L); + VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L); + MACvSelectPage0(dwIoBase); + } + + if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) { + // set multicast address to accept all + MACvSelectPage1(dwIoBase); + VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL); + VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL); + MACvSelectPage0(dwIoBase); + } + + if (wFilterType & PKT_TYPE_PROMISCUOUS) { + + byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST); + + byNewRCR &= ~RCR_BSSID; + } + + if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)) + byNewRCR |= RCR_MULTICAST; + + if (wFilterType & PKT_TYPE_BROADCAST) + byNewRCR |= RCR_BROADCAST; + + if (wFilterType & PKT_TYPE_ERROR_CRC) + byNewRCR |= RCR_ERRCRC; + + VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR); + if (byNewRCR != byOldRCR) { + // Modify the Receive Command Register + VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR); + } } /* @@ -643,23 +643,23 @@ void MACvSetPacketFilter (unsigned long dwIoBase, unsigned short wFilterType) * Return Value: none * */ -void MACvSaveContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) +void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf) { - int ii; + int ii; - // read page0 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { - VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii)); - } + // read page0 register + for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { + VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii)); + } - MACvSelectPage1(dwIoBase); + MACvSelectPage1(dwIoBase); - // read page1 register - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { - VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); - } + // read page1 register + for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { + VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); + } - MACvSelectPage0(dwIoBase); + MACvSelectPage0(dwIoBase); } /* @@ -676,41 +676,41 @@ void MACvSaveContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) * Return Value: none * */ -void MACvRestoreContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) +void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf) { - int ii; + int ii; - MACvSelectPage1(dwIoBase); - // restore page1 - for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { - VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); - } - MACvSelectPage0(dwIoBase); + MACvSelectPage1(dwIoBase); + // restore page1 + for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { + VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); + } + MACvSelectPage0(dwIoBase); - // restore RCR,TCR,IMR... - for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) { - VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); - } - // restore MAC Config. - for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) { - VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); - } - VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG)); + // restore RCR,TCR,IMR... + for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) { + VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); + } + // restore MAC Config. + for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) { + VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); + } + VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG)); - // restore PS Config. - for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) { - VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); - } + // restore PS Config. + for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) { + VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); + } - // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR - VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)); - VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)); - VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR)); + // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR + VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)); + VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)); + VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR)); - VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)); + VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)); - VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)); + VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)); } @@ -728,36 +728,36 @@ void MACvRestoreContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) * Return Value: true if all values are the same; otherwise false * */ -bool MACbCompareContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) +bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf) { - unsigned long dwData; + unsigned long dwData; - // compare MAC context to determine if this is a power lost init, - // return true for power remaining init, return false for power lost init + // compare MAC context to determine if this is a power lost init, + // return true for power remaining init, return false for power lost init - // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR - VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) { - return false; - } + // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR + VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData); + if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) { + return false; + } - VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) { - return false; - } + VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData); + if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) { + return false; + } - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) { - return false; - } + VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData); + if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) { + return false; + } - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData); - if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) { - return false; - } + VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData); + if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) { + return false; + } - return true; + return true; } /* @@ -773,23 +773,23 @@ bool MACbCompareContext (unsigned long dwIoBase, unsigned char *pbyCxtBuf) * Return Value: true if Reset Success; otherwise false * */ -bool MACbSoftwareReset (unsigned long dwIoBase) +bool MACbSoftwareReset(unsigned long dwIoBase) { - unsigned char byData; - unsigned short ww; - - // turn on HOSTCR_SOFTRST, just write 0x01 to reset - //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST); - VNSvOutPortB(dwIoBase+ MAC_REG_HOSTCR, 0x01); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); - if ( !(byData & HOSTCR_SOFTRST)) - break; - } - if (ww == W_MAX_TIMEOUT) - return false; - return true; + unsigned char byData; + unsigned short ww; + + // turn on HOSTCR_SOFTRST, just write 0x01 to reset + //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST); + VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01); + + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); + if (!(byData & HOSTCR_SOFTRST)) + break; + } + if (ww == W_MAX_TIMEOUT) + return false; + return true; } @@ -806,24 +806,24 @@ bool MACbSoftwareReset (unsigned long dwIoBase) * Return Value: true if success; otherwise false * */ -bool MACbSafeSoftwareReset (unsigned long dwIoBase) +bool MACbSafeSoftwareReset(unsigned long dwIoBase) { - unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1]; - bool bRetVal; - - // PATCH.... - // save some important register's value, then do - // reset, then restore register's value - - // save MAC context - MACvSaveContext(dwIoBase, abyTmpRegData); - // do reset - bRetVal = MACbSoftwareReset(dwIoBase); - //BBvSoftwareReset(pDevice->PortOffset); - // restore MAC context, except CR0 - MACvRestoreContext(dwIoBase, abyTmpRegData); - - return bRetVal; + unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1]; + bool bRetVal; + + // PATCH.... + // save some important register's value, then do + // reset, then restore register's value + + // save MAC context + MACvSaveContext(dwIoBase, abyTmpRegData); + // do reset + bRetVal = MACbSoftwareReset(dwIoBase); + //BBvSoftwareReset(pDevice->PortOffset); + // restore MAC context, except CR0 + MACvRestoreContext(dwIoBase, abyTmpRegData); + + return bRetVal; } /* @@ -839,52 +839,52 @@ bool MACbSafeSoftwareReset (unsigned long dwIoBase) * Return Value: true if success; otherwise false * */ -bool MACbSafeRxOff (unsigned long dwIoBase) +bool MACbSafeRxOff(unsigned long dwIoBase) { - unsigned short ww; - unsigned long dwData; - unsigned char byData; - - // turn off wow temp for turn off Rx safely - - // Clear RX DMA0,1 - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN); - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData); - if (!(dwData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x10); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x10)\n"); - return(false); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData); - if ( !(dwData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x11); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x11)\n"); - return(false); - } - - // try to safe shutdown RX - MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); - // W_MAX_TIMEOUT is the timeout period - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); - if ( !(byData & HOSTCR_RXONST)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x12); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x12)\n"); - return(false); - } - return true; + unsigned short ww; + unsigned long dwData; + unsigned char byData; + + // turn off wow temp for turn off Rx safely + + // Clear RX DMA0,1 + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN); + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData); + if (!(dwData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x10); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x10)\n"); + return(false); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData); + if (!(dwData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x11); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x11)\n"); + return(false); + } + + // try to safe shutdown RX + MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); + // W_MAX_TIMEOUT is the timeout period + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); + if (!(byData & HOSTCR_RXONST)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x12); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x12)\n"); + return(false); + } + return true; } /* @@ -900,55 +900,55 @@ bool MACbSafeRxOff (unsigned long dwIoBase) * Return Value: true if success; otherwise false * */ -bool MACbSafeTxOff (unsigned long dwIoBase) +bool MACbSafeTxOff(unsigned long dwIoBase) { - unsigned short ww; - unsigned long dwData; - unsigned char byData; - - // Clear TX DMA - //Tx0 - VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN); - //AC0 - VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN); - - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData); - if ( !(dwData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x20); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x20)\n"); - return(false); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData); - if ( !(dwData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x21); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x21)\n"); - return(false); - } - - // try to safe shutdown TX - MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); - - // W_MAX_TIMEOUT is the timeout period - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); - if ( !(byData & HOSTCR_TXONST)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x24); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x24)\n"); - return(false); - } - return true; + unsigned short ww; + unsigned long dwData; + unsigned char byData; + + // Clear TX DMA + //Tx0 + VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN); + //AC0 + VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN); + + + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData); + if (!(dwData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x20); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x20)\n"); + return(false); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData); + if (!(dwData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x21); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x21)\n"); + return(false); + } + + // try to safe shutdown TX + MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); + + // W_MAX_TIMEOUT is the timeout period + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); + if (!(byData & HOSTCR_TXONST)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x24); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x24)\n"); + return(false); + } + return true; } /* @@ -964,26 +964,26 @@ bool MACbSafeTxOff (unsigned long dwIoBase) * Return Value: true if success; otherwise false * */ -bool MACbSafeStop (unsigned long dwIoBase) +bool MACbSafeStop(unsigned long dwIoBase) { - MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX); - - if (MACbSafeRxOff(dwIoBase) == false) { - DBG_PORT80(0xA1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == false)\n"); - MACbSafeSoftwareReset(dwIoBase); - return false; - } - if (MACbSafeTxOff(dwIoBase) == false) { - DBG_PORT80(0xA2); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == false)\n"); - MACbSafeSoftwareReset(dwIoBase); - return false; - } - - MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN); - - return true; + MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX); + + if (MACbSafeRxOff(dwIoBase) == false) { + DBG_PORT80(0xA1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n"); + MACbSafeSoftwareReset(dwIoBase); + return false; + } + if (MACbSafeTxOff(dwIoBase) == false) { + DBG_PORT80(0xA2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n"); + MACbSafeSoftwareReset(dwIoBase); + return false; + } + + MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN); + + return true; } /* @@ -999,18 +999,18 @@ bool MACbSafeStop (unsigned long dwIoBase) * Return Value: true if success; otherwise false * */ -bool MACbShutdown (unsigned long dwIoBase) +bool MACbShutdown(unsigned long dwIoBase) { - // disable MAC IMR - MACvIntDisable(dwIoBase); - MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL); - // stop the adapter - if (!MACbSafeStop(dwIoBase)) { - MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); - return false; - } - MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); - return true; + // disable MAC IMR + MACvIntDisable(dwIoBase); + MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL); + // stop the adapter + if (!MACbSafeStop(dwIoBase)) { + MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); + return false; + } + MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); + return true; } /* @@ -1026,42 +1026,42 @@ bool MACbShutdown (unsigned long dwIoBase) * Return Value: none * */ -void MACvInitialize (unsigned long dwIoBase) +void MACvInitialize(unsigned long dwIoBase) { - // clear sticky bits - MACvClearStckDS(dwIoBase); - // disable force PME-enable - VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR); - // only 3253 A - /* - MACvPwrEvntDisable(dwIoBase); - // clear power status - VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPSR0, 0x0F0F); - */ - - // do reset - MACbSoftwareReset(dwIoBase); - - // issue AUTOLD in EECSR to reload eeprom - //MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); - // wait until EEPROM loading complete - //while (true) { - // u8 u8Data; - // VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &u8Data); - // if ( !(u8Data & I2MCSR_AUTOLD)) - // break; - //} - - // reset TSF counter - VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter - VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - - // set packet filter - // receive directed and broadcast address - - MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST); + // clear sticky bits + MACvClearStckDS(dwIoBase); + // disable force PME-enable + VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR); + // only 3253 A + /* + MACvPwrEvntDisable(dwIoBase); + // clear power status + VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPSR0, 0x0F0F); + */ + + // do reset + MACbSoftwareReset(dwIoBase); + + // issue AUTOLD in EECSR to reload eeprom + //MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); + // wait until EEPROM loading complete + //while (true) { + // u8 u8Data; + // VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &u8Data); + // if (!(u8Data & I2MCSR_AUTOLD)) + // break; + //} + + // reset TSF counter + VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); + // enable TSF counter + VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + + + // set packet filter + // receive directed and broadcast address + + MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST); } @@ -1079,28 +1079,28 @@ void MACvInitialize (unsigned long dwIoBase) * Return Value: none * */ -void MACvSetCurrRx0DescAddr (unsigned long dwIoBase, unsigned long dwCurrDescAddr) +void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr) { -unsigned short ww; -unsigned char byData; -unsigned char byOrgDMACtl; - - VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData); - if ( !(byData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x13); - } - VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); - } + unsigned short ww; + unsigned char byData; + unsigned char byOrgDMACtl; + + VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x13); + } + VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); + } } /* @@ -1117,28 +1117,28 @@ unsigned char byOrgDMACtl; * Return Value: none * */ -void MACvSetCurrRx1DescAddr (unsigned long dwIoBase, unsigned long dwCurrDescAddr) +void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr) { -unsigned short ww; -unsigned char byData; -unsigned char byOrgDMACtl; - - VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData); - if ( !(byData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x14); - } - VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); - } + unsigned short ww; + unsigned char byData; + unsigned char byOrgDMACtl; + + VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x14); + } + VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); + } } /* @@ -1155,28 +1155,28 @@ unsigned char byOrgDMACtl; * Return Value: none * */ -void MACvSetCurrTx0DescAddrEx (unsigned long dwIoBase, unsigned long dwCurrDescAddr) +void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr) { -unsigned short ww; -unsigned char byData; -unsigned char byOrgDMACtl; - - VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); - if ( !(byData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x25); - } - VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); - } + unsigned short ww; + unsigned char byData; + unsigned char byOrgDMACtl; + + VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x25); + } + VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); + } } /* @@ -1193,41 +1193,41 @@ unsigned char byOrgDMACtl; * Return Value: none * */ - //TxDMA1 = AC0DMA -void MACvSetCurrAC0DescAddrEx (unsigned long dwIoBase, unsigned long dwCurrDescAddr) +//TxDMA1 = AC0DMA +void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr) { -unsigned short ww; -unsigned char byData; -unsigned char byOrgDMACtl; - - VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); - if (!(byData & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x26); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x26)\n"); - } - VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr); - if (byOrgDMACtl & DMACTL_RUN) { - VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); - } + unsigned short ww; + unsigned char byData; + unsigned char byOrgDMACtl; + + VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); + } + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x26); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x26)\n"); + } + VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr); + if (byOrgDMACtl & DMACTL_RUN) { + VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); + } } -void MACvSetCurrTXDescAddr (int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr) +void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr) { - if(iTxType == TYPE_AC0DMA){ - MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr); - }else if(iTxType == TYPE_TXDMA0){ - MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr); - } + if (iTxType == TYPE_AC0DMA) { + MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr); + } else if (iTxType == TYPE_TXDMA0) { + MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr); + } } /* @@ -1244,25 +1244,25 @@ void MACvSetCurrTXDescAddr (int iTxType, unsigned long dwIoBase, unsigned long d * Return Value: none * */ -void MACvTimer0MicroSDelay (unsigned long dwIoBase, unsigned int uDelay) +void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay) { -unsigned char byValue; -unsigned int uu,ii; - - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); - VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay); - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); - for(ii=0;ii<66;ii++) { // assume max PCI clock is 66Mhz - for (uu = 0; uu < uDelay; uu++) { - VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue); - if ((byValue == 0) || - (byValue & TMCTL_TSUSP)) { - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); - return; - } - } - } - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); + unsigned char byValue; + unsigned int uu, ii; + + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); + VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay); + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); + for (ii = 0; ii < 66; ii++) { // assume max PCI clock is 66Mhz + for (uu = 0; uu < uDelay; uu++) { + VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue); + if ((byValue == 0) || + (byValue & TMCTL_TSUSP)) { + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); + return; + } + } + } + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); } @@ -1280,11 +1280,11 @@ unsigned int uu,ii; * Return Value: none * */ -void MACvOneShotTimer0MicroSec (unsigned long dwIoBase, unsigned int uDelayTime) +void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime) { - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); - VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime); - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); + VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime); + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); } /* @@ -1301,143 +1301,143 @@ void MACvOneShotTimer0MicroSec (unsigned long dwIoBase, unsigned int uDelayTime) * Return Value: none * */ -void MACvOneShotTimer1MicroSec (unsigned long dwIoBase, unsigned int uDelayTime) +void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime) { - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0); - VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime); - VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE)); + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0); + VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime); + VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE)); } -void MACvSetMISCFifo (unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData) +void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData) { - if (wOffset > 273) - return; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + if (wOffset > 273) + return; + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } -bool MACbTxDMAOff (unsigned long dwIoBase, unsigned int idx) +bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx) { -unsigned char byData; -unsigned int ww = 0; - - if (idx == TYPE_TXDMA0) { - VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); - if ( !(byData & DMACTL_RUN)) - break; - } - } else if (idx == TYPE_AC0DMA) { - VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); - if ( !(byData & DMACTL_RUN)) - break; - } - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x29); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x29)\n"); - return false; - } - return true; + unsigned char byData; + unsigned int ww = 0; + + if (idx == TYPE_TXDMA0) { + VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + } else if (idx == TYPE_AC0DMA) { + VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); + if (!(byData & DMACTL_RUN)) + break; + } + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x29); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x29)\n"); + return false; + } + return true; } -void MACvClearBusSusInd (unsigned long dwIoBase) +void MACvClearBusSusInd(unsigned long dwIoBase) { - unsigned long dwOrgValue; - unsigned int ww; - // check if BcnSusInd enabled - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if( !(dwOrgValue & EnCFG_BcnSusInd)) - return; - //Set BcnSusClr - dwOrgValue = dwOrgValue | EnCFG_BcnSusClr; - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if( !(dwOrgValue & EnCFG_BcnSusInd)) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x33); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n"); - } + unsigned long dwOrgValue; + unsigned int ww; + // check if BcnSusInd enabled + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); + if (!(dwOrgValue & EnCFG_BcnSusInd)) + return; + //Set BcnSusClr + dwOrgValue = dwOrgValue | EnCFG_BcnSusClr; + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); + if (!(dwOrgValue & EnCFG_BcnSusInd)) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x33); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + } } -void MACvEnableBusSusEn (unsigned long dwIoBase) +void MACvEnableBusSusEn(unsigned long dwIoBase) { - unsigned char byOrgValue; - unsigned long dwOrgValue; - unsigned int ww; - // check if BcnSusInd enabled - VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue); - - //Set BcnSusEn - byOrgValue = byOrgValue | CFG_BCNSUSEN; - VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); - if(dwOrgValue & EnCFG_BcnSusInd) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x34); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x34)\n"); - } + unsigned char byOrgValue; + unsigned long dwOrgValue; + unsigned int ww; + // check if BcnSusInd enabled + VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue); + + //Set BcnSusEn + byOrgValue = byOrgValue | CFG_BCNSUSEN; + VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue); + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); + if (dwOrgValue & EnCFG_BcnSusInd) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x34); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x34)\n"); + } } -bool MACbFlushSYNCFifo (unsigned long dwIoBase) +bool MACbFlushSYNCFifo(unsigned long dwIoBase) { - unsigned char byOrgValue; - unsigned int ww; - // Read MACCR - VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); - - // Set SYNCFLUSH - byOrgValue = byOrgValue | MACCR_SYNCFLUSH; - VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue); - - // Check if SyncFlushOK - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); - if(byOrgValue & MACCR_SYNCFLUSHOK) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x35); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n"); - } - return true; + unsigned char byOrgValue; + unsigned int ww; + // Read MACCR + VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); + + // Set SYNCFLUSH + byOrgValue = byOrgValue | MACCR_SYNCFLUSH; + VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue); + + // Check if SyncFlushOK + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); + if (byOrgValue & MACCR_SYNCFLUSHOK) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x35); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + } + return true; } -bool MACbPSWakeup (unsigned long dwIoBase) +bool MACbPSWakeup(unsigned long dwIoBase) { - unsigned char byOrgValue; - unsigned int ww; - // Read PSCTL - if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) { - return true; - } - // Disable PS - MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN); - - // Check if SyncFlushOK - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue); - if(byOrgValue & PSCTL_WAKEDONE) - break; - } - if (ww == W_MAX_TIMEOUT) { - DBG_PORT80(0x36); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n"); - return false; - } - return true; + unsigned char byOrgValue; + unsigned int ww; + // Read PSCTL + if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) { + return true; + } + // Disable PS + MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN); + + // Check if SyncFlushOK + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue); + if (byOrgValue & PSCTL_WAKEDONE) + break; + } + if (ww == W_MAX_TIMEOUT) { + DBG_PORT80(0x36); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + return false; + } + return true; } /* @@ -1455,55 +1455,55 @@ bool MACbPSWakeup (unsigned long dwIoBase) * */ -void MACvSetKeyEntry (unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, - unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID) +void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, + unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID) { -unsigned short wOffset; -unsigned long dwData; -int ii; - - if (byLocalID <= 1) - return; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - - dwData = 0; - dwData |= wKeyCtl; - dwData <<= 16; - dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); - - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - dwData = 0; - dwData |= *(pbyAddr+3); - dwData <<= 8; - dwData |= *(pbyAddr+2); - dwData <<= 8; - dwData |= *(pbyAddr+1); - dwData <<= 8; - dwData |= *(pbyAddr+0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData); - - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - wOffset += (uKeyIdx * 4); - for (ii=0;ii<4;ii++) { - // always push 128 bits - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - } + unsigned short wOffset; + unsigned long dwData; + int ii; + + if (byLocalID <= 1) + return; + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); + + dwData = 0; + dwData |= wKeyCtl; + dwData <<= 16; + dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); + + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + wOffset++; + + dwData = 0; + dwData |= *(pbyAddr+3); + dwData <<= 8; + dwData |= *(pbyAddr+2); + dwData <<= 8; + dwData |= *(pbyAddr+1); + dwData <<= 8; + dwData |= *(pbyAddr+0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2. wOffset: %d, Data: %lX\n", wOffset, dwData); + + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + wOffset++; + + wOffset += (uKeyIdx * 4); + for (ii = 0; ii < 4; ii++) { + // always push 128 bits + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + } } @@ -1522,16 +1522,16 @@ int ii; * Return Value: none * */ -void MACvDisableKeyEntry (unsigned long dwIoBase, unsigned int uEntryIdx) +void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx) { -unsigned short wOffset; + unsigned short wOffset; - wOffset = MISCFIFO_KEYETRY0; - wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } @@ -1550,38 +1550,38 @@ unsigned short wOffset; * */ -void MACvSetDefaultKeyEntry (unsigned long dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) +void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, + unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) { -unsigned short wOffset; -unsigned long dwData; -int ii; - - if (byLocalID <= 1) - return; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - wOffset++; - wOffset++; - wOffset += (uKeyIdx * 4); - // always push 128 bits - for (ii=0; ii<3; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - } - dwData = *pdwKey; - if (uKeyLen == WLAN_WEP104_KEYLEN) { - dwData |= 0x80000000; - } - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); + unsigned short wOffset; + unsigned long dwData; + int ii; + + if (byLocalID <= 1) + return; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultKeyEntry\n"); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (10 * MISCFIFO_KEYENTRYSIZE); + + wOffset++; + wOffset++; + wOffset += (uKeyIdx * 4); + // always push 128 bits + for (ii = 0; ii < 3; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + } + dwData = *pdwKey; + if (uKeyLen == WLAN_WEP104_KEYLEN) { + dwData |= 0x80000000; + } + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); } @@ -1601,25 +1601,25 @@ int ii; * */ /* -void MACvEnableDefaultKey (unsigned long dwIoBase, unsigned char byLocalID) -{ -unsigned short wOffset; -unsigned long dwData; + void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID) + { + unsigned short wOffset; + unsigned long dwData; - if (byLocalID <= 1) - return; + if (byLocalID <= 1) + return; - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - dwData = 0xC0440000; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); + dwData = 0xC0440000; + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); -} + } */ /* @@ -1636,20 +1636,20 @@ unsigned long dwData; * Return Value: none * */ -void MACvDisableDefaultKey (unsigned long dwIoBase) +void MACvDisableDefaultKey(unsigned long dwIoBase) { -unsigned short wOffset; -unsigned long dwData; + unsigned short wOffset; + unsigned long dwData; - wOffset = MISCFIFO_KEYETRY0; - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - dwData = 0x0; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); + dwData = 0x0; + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); } /* @@ -1666,43 +1666,43 @@ unsigned long dwData; * Return Value: none * */ -void MACvSetDefaultTKIPKeyEntry (unsigned long dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) +void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, + unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) { -unsigned short wOffset; -unsigned long dwData; -int ii; - - if (byLocalID <= 1) - return; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultTKIPKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - // Kyle test : change offset from 10 -> 0 - wOffset += (10 * MISCFIFO_KEYENTRYSIZE); - - dwData = 0xC0660000; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - dwData = 0; - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - wOffset++; - - wOffset += (uKeyIdx * 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx); - // always push 128 bits - for (ii=0; ii<4; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - } + unsigned short wOffset; + unsigned long dwData; + int ii; + + if (byLocalID <= 1) + return; + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultTKIPKeyEntry\n"); + wOffset = MISCFIFO_KEYETRY0; + // Kyle test : change offset from 10 -> 0 + wOffset += (10 * MISCFIFO_KEYENTRYSIZE); + + dwData = 0xC0660000; + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + wOffset++; + + dwData = 0; + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + wOffset++; + + wOffset += (uKeyIdx * 4); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx); + // always push 128 bits + for (ii = 0; ii < 4; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + } } @@ -1723,28 +1723,28 @@ int ii; * */ -void MACvSetDefaultKeyCtl (unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID) +void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID) { -unsigned short wOffset; -unsigned long dwData; + unsigned short wOffset; + unsigned long dwData; - if (byLocalID <= 1) - return; + if (byLocalID <= 1) + return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n"); - wOffset = MISCFIFO_KEYETRY0; - wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); + wOffset = MISCFIFO_KEYETRY0; + wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - dwData = 0; - dwData |= wKeyCtl; - dwData <<= 16; - dwData |= 0xffff; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); + dwData = 0; + dwData |= wKeyCtl; + dwData <<= 16; + dwData |= 0xffff; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); - VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); + VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index adfb366f4901..7612dbf29d69 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -604,20 +604,20 @@ #define MISCFIFO_SYNDATASIZE 21 // enabled mask value of irq -#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \ - IMR_RXDMA1 | \ - IMR_RXNOBUF | \ - IMR_MIBNEARFULL | \ - IMR_SOFTINT | \ - IMR_FETALERR | \ - IMR_WATCHDOG | \ - IMR_SOFTTIMER | \ - IMR_GPIO | \ - IMR_TBTT | \ - IMR_RXDMA0 | \ - IMR_BNTX | \ - IMR_AC0DMA | \ - IMR_TXDMA0) +#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \ + IMR_RXDMA1 | \ + IMR_RXNOBUF | \ + IMR_MIBNEARFULL | \ + IMR_SOFTINT | \ + IMR_FETALERR | \ + IMR_WATCHDOG | \ + IMR_SOFTTIMER | \ + IMR_GPIO | \ + IMR_TBTT | \ + IMR_RXDMA0 | \ + IMR_BNTX | \ + IMR_AC0DMA | \ + IMR_TXDMA0) // max time out delay time #define W_MAX_TIMEOUT 0xFFF0U // @@ -637,412 +637,412 @@ /*--------------------- Export Macros ------------------------------*/ -#define MACvRegBitsOn(dwIoBase, byRegOfs, byBits) \ -{ \ - unsigned char byData; \ - VNSvInPortB(dwIoBase + byRegOfs, &byData); \ - VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits)); \ -} - -#define MACvWordRegBitsOn(dwIoBase, byRegOfs, wBits) \ -{ \ - unsigned short wData; \ - VNSvInPortW(dwIoBase + byRegOfs, &wData); \ - VNSvOutPortW(dwIoBase + byRegOfs, wData | (wBits)); \ -} - -#define MACvDWordRegBitsOn(dwIoBase, byRegOfs, dwBits) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + byRegOfs, &dwData); \ - VNSvOutPortD(dwIoBase + byRegOfs, dwData | (dwBits)); \ -} - -#define MACvRegBitsOnEx(dwIoBase, byRegOfs, byMask, byBits) \ -{ \ - unsigned char byData; \ - VNSvInPortB(dwIoBase + byRegOfs, &byData); \ - byData &= byMask; \ - VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits)); \ -} - -#define MACvRegBitsOff(dwIoBase, byRegOfs, byBits) \ -{ \ - unsigned char byData; \ - VNSvInPortB(dwIoBase + byRegOfs, &byData); \ - VNSvOutPortB(dwIoBase + byRegOfs, byData & ~(byBits)); \ -} - -#define MACvWordRegBitsOff(dwIoBase, byRegOfs, wBits) \ -{ \ - unsigned short wData; \ - VNSvInPortW(dwIoBase + byRegOfs, &wData); \ - VNSvOutPortW(dwIoBase + byRegOfs, wData & ~(wBits)); \ -} - -#define MACvDWordRegBitsOff(dwIoBase, byRegOfs, dwBits) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + byRegOfs, &dwData); \ - VNSvOutPortD(dwIoBase + byRegOfs, dwData & ~(dwBits)); \ -} - -#define MACvGetCurrRx0DescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, \ - (unsigned long *)pdwCurrDescAddr); \ -} - -#define MACvGetCurrRx1DescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, \ - (unsigned long *)pdwCurrDescAddr); \ -} - -#define MACvGetCurrTx0DescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, \ - (unsigned long *)pdwCurrDescAddr); \ -} - -#define MACvGetCurrAC0DescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, \ - (unsigned long *)pdwCurrDescAddr); \ -} - -#define MACvGetCurrSyncDescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_SYNCDMAPTR, \ - (unsigned long *)pdwCurrDescAddr); \ -} - -#define MACvGetCurrATIMDescAddr(dwIoBase, pdwCurrDescAddr) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR, \ - (unsigned long *)pdwCurrDescAddr); \ -} \ +#define MACvRegBitsOn(dwIoBase, byRegOfs, byBits) \ + { \ + unsigned char byData; \ + VNSvInPortB(dwIoBase + byRegOfs, &byData); \ + VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits)); \ + } + +#define MACvWordRegBitsOn(dwIoBase, byRegOfs, wBits) \ + { \ + unsigned short wData; \ + VNSvInPortW(dwIoBase + byRegOfs, &wData); \ + VNSvOutPortW(dwIoBase + byRegOfs, wData | (wBits)); \ + } + +#define MACvDWordRegBitsOn(dwIoBase, byRegOfs, dwBits) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + byRegOfs, &dwData); \ + VNSvOutPortD(dwIoBase + byRegOfs, dwData | (dwBits)); \ + } + +#define MACvRegBitsOnEx(dwIoBase, byRegOfs, byMask, byBits) \ + { \ + unsigned char byData; \ + VNSvInPortB(dwIoBase + byRegOfs, &byData); \ + byData &= byMask; \ + VNSvOutPortB(dwIoBase + byRegOfs, byData | (byBits)); \ + } + +#define MACvRegBitsOff(dwIoBase, byRegOfs, byBits) \ + { \ + unsigned char byData; \ + VNSvInPortB(dwIoBase + byRegOfs, &byData); \ + VNSvOutPortB(dwIoBase + byRegOfs, byData & ~(byBits)); \ + } + +#define MACvWordRegBitsOff(dwIoBase, byRegOfs, wBits) \ + { \ + unsigned short wData; \ + VNSvInPortW(dwIoBase + byRegOfs, &wData); \ + VNSvOutPortW(dwIoBase + byRegOfs, wData & ~(wBits)); \ + } + +#define MACvDWordRegBitsOff(dwIoBase, byRegOfs, dwBits) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + byRegOfs, &dwData); \ + VNSvOutPortD(dwIoBase + byRegOfs, dwData & ~(dwBits)); \ + } + +#define MACvGetCurrRx0DescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, \ + (unsigned long *)pdwCurrDescAddr); \ + } + +#define MACvGetCurrRx1DescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, \ + (unsigned long *)pdwCurrDescAddr); \ + } + +#define MACvGetCurrTx0DescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, \ + (unsigned long *)pdwCurrDescAddr); \ + } + +#define MACvGetCurrAC0DescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, \ + (unsigned long *)pdwCurrDescAddr); \ + } + +#define MACvGetCurrSyncDescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_SYNCDMAPTR, \ + (unsigned long *)pdwCurrDescAddr); \ + } + +#define MACvGetCurrATIMDescAddr(dwIoBase, pdwCurrDescAddr) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR, \ + (unsigned long *)pdwCurrDescAddr); \ + } \ // set the chip with current BCN tx descriptor address -#define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, \ - dwCurrDescAddr); \ -} +#define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, \ + dwCurrDescAddr); \ + } // set the chip with current BCN length -#define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength) \ -{ \ - VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2, \ - wCurrBCNLength); \ -} - -#define MACvReadBSSIDAddress(dwIoBase, pbyEtherAddr) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0, \ - (unsigned char *)pbyEtherAddr); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 1, \ - pbyEtherAddr + 1); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 2, \ - pbyEtherAddr + 2); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 3, \ - pbyEtherAddr + 3); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 4, \ - pbyEtherAddr + 4); \ - VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 5, \ - pbyEtherAddr + 5); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} - -#define MACvWriteBSSIDAddress(dwIoBase, pbyEtherAddr) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0, \ - *(pbyEtherAddr)); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 1, \ - *(pbyEtherAddr + 1)); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 2, \ - *(pbyEtherAddr + 2)); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 3, \ - *(pbyEtherAddr + 3)); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 4, \ - *(pbyEtherAddr + 4)); \ - VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 5, \ - *(pbyEtherAddr + 5)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} - -#define MACvReadEtherAddress(dwIoBase, pbyEtherAddr) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0, \ - (unsigned char *)pbyEtherAddr); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 1, \ - pbyEtherAddr + 1); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 2, \ - pbyEtherAddr + 2); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 3, \ - pbyEtherAddr + 3); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 4, \ - pbyEtherAddr + 4); \ - VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 5, \ - pbyEtherAddr + 5); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} - - -#define MACvWriteEtherAddress(dwIoBase, pbyEtherAddr) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0, \ - *pbyEtherAddr); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 1, \ - *(pbyEtherAddr + 1)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 2, \ - *(pbyEtherAddr + 2)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 3, \ - *(pbyEtherAddr + 3)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 4, \ - *(pbyEtherAddr + 4)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 5, \ - *(pbyEtherAddr + 5)); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} - - -#define MACvClearISR(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_ISR, IMR_MASK_VALUE); \ -} - -#define MACvStart(dwIoBase) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, \ - (HOSTCR_MACEN | HOSTCR_RXON | HOSTCR_TXON)); \ -} - -#define MACvRx0PerPktMode(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKT); \ -} - -#define MACvRx0BufferFillMode(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKTCLR); \ -} - -#define MACvRx1PerPktMode(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKT); \ -} - -#define MACvRx1BufferFillMode(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKTCLR); \ -} - -#define MACvRxOn(dwIoBase) \ -{ \ - MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); \ -} - -#define MACvReceive0(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); \ - } \ -} - -#define MACvReceive1(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); \ - } \ -} - -#define MACvTxOn(dwIoBase) \ -{ \ - MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); \ -} - -#define MACvTransmit0(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); \ - } \ -} - -#define MACvTransmitAC0(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); \ - } \ -} - -#define MACvTransmitSYNC(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_SYNCDMACTL, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_RUN); \ - } \ -} - -#define MACvTransmitATIM(dwIoBase) \ -{ \ - unsigned long dwData; \ - VNSvInPortD(dwIoBase + MAC_REG_ATIMDMACTL, &dwData); \ - if (dwData & DMACTL_RUN) { \ - VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_WAKE);\ - } \ - else { \ - VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_RUN); \ - } \ -} - -#define MACvTransmitBCN(dwIoBase) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_BCNDMACTL, BEACON_READY); \ -} - -#define MACvClearStckDS(dwIoBase) \ -{ \ - unsigned char byOrgValue; \ - VNSvInPortB(dwIoBase + MAC_REG_STICKHW, &byOrgValue); \ - byOrgValue = byOrgValue & 0xFC; \ - VNSvOutPortB(dwIoBase + MAC_REG_STICKHW, byOrgValue); \ -} - -#define MACvReadISR(dwIoBase, pdwValue) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_ISR, pdwValue); \ -} - -#define MACvWriteISR(dwIoBase, dwValue) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_ISR, dwValue); \ -} - -#define MACvIntEnable(dwIoBase, dwMask) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_IMR, dwMask); \ -} - -#define MACvIntDisable(dwIoBase) \ -{ \ - VNSvOutPortD(dwIoBase + MAC_REG_IMR, 0); \ -} - -#define MACvSelectPage0(dwIoBase) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} -#define MACvSelectPage1(dwIoBase) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ -} - -#define MACvReadMIBCounter(dwIoBase, pdwCounter) \ -{ \ - VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR , pdwCounter); \ -} - -#define MACvPwrEvntDisable(dwIoBase) \ -{ \ - VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000); \ -} - -#define MACvEnableProtectMD(dwIoBase) \ -{ \ - unsigned long dwOrgValue; \ - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ - dwOrgValue = dwOrgValue | EnCFG_ProtectMd; \ - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ -} - -#define MACvDisableProtectMD(dwIoBase) \ -{ \ - unsigned long dwOrgValue; \ - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ - dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd; \ - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ -} - -#define MACvEnableBarkerPreambleMd(dwIoBase) \ -{ \ - unsigned long dwOrgValue; \ - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ - dwOrgValue = dwOrgValue | EnCFG_BarkerPream; \ - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ -} - -#define MACvDisableBarkerPreambleMd(dwIoBase) \ -{ \ - unsigned long dwOrgValue; \ - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ - dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream; \ - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ -} - -#define MACvSetBBType(dwIoBase, byTyp) \ -{ \ - unsigned long dwOrgValue; \ - VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ - dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK; \ - dwOrgValue = dwOrgValue | (unsigned long) byTyp; \ - VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ -} - -#define MACvReadATIMW(dwIoBase, pwCounter) \ -{ \ - VNSvInPortW(dwIoBase + MAC_REG_AIDATIM , pwCounter); \ -} - -#define MACvWriteATIMW(dwIoBase, wCounter) \ -{ \ - VNSvOutPortW(dwIoBase + MAC_REG_AIDATIM , wCounter); \ -} - -#define MACvWriteCRC16_128(dwIoBase, byRegOfs, wCRC) \ -{ \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ - VNSvOutPortW(dwIoBase + byRegOfs, wCRC); \ - VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ -} - -#define MACvGPIOIn(dwIoBase, pbyValue) \ -{ \ - VNSvInPortB(dwIoBase + MAC_REG_GPIOCTL1, pbyValue); \ -} +#define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength) \ + { \ + VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2, \ + wCurrBCNLength); \ + } + +#define MACvReadBSSIDAddress(dwIoBase, pbyEtherAddr) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0, \ + (unsigned char *)pbyEtherAddr); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 1, \ + pbyEtherAddr + 1); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 2, \ + pbyEtherAddr + 2); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 3, \ + pbyEtherAddr + 3); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 4, \ + pbyEtherAddr + 4); \ + VNSvInPortB(dwIoBase + MAC_REG_BSSID0 + 5, \ + pbyEtherAddr + 5); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } + +#define MACvWriteBSSIDAddress(dwIoBase, pbyEtherAddr) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0, \ + *(pbyEtherAddr)); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 1, \ + *(pbyEtherAddr + 1)); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 2, \ + *(pbyEtherAddr + 2)); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 3, \ + *(pbyEtherAddr + 3)); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 4, \ + *(pbyEtherAddr + 4)); \ + VNSvOutPortB(dwIoBase + MAC_REG_BSSID0 + 5, \ + *(pbyEtherAddr + 5)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } + +#define MACvReadEtherAddress(dwIoBase, pbyEtherAddr) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0, \ + (unsigned char *)pbyEtherAddr); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 1, \ + pbyEtherAddr + 1); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 2, \ + pbyEtherAddr + 2); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 3, \ + pbyEtherAddr + 3); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 4, \ + pbyEtherAddr + 4); \ + VNSvInPortB(dwIoBase + MAC_REG_PAR0 + 5, \ + pbyEtherAddr + 5); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } + + +#define MACvWriteEtherAddress(dwIoBase, pbyEtherAddr) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0, \ + *pbyEtherAddr); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 1, \ + *(pbyEtherAddr + 1)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 2, \ + *(pbyEtherAddr + 2)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 3, \ + *(pbyEtherAddr + 3)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 4, \ + *(pbyEtherAddr + 4)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAR0 + 5, \ + *(pbyEtherAddr + 5)); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } + + +#define MACvClearISR(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_ISR, IMR_MASK_VALUE); \ + } + +#define MACvStart(dwIoBase) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, \ + (HOSTCR_MACEN | HOSTCR_RXON | HOSTCR_TXON)); \ + } + +#define MACvRx0PerPktMode(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKT); \ + } + +#define MACvRx0BufferFillMode(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, RX_PERPKTCLR); \ + } + +#define MACvRx1PerPktMode(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKT); \ + } + +#define MACvRx1BufferFillMode(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, RX_PERPKTCLR); \ + } + +#define MACvRxOn(dwIoBase) \ + { \ + MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); \ + } + +#define MACvReceive0(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); \ + } \ + } + +#define MACvReceive1(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); \ + } \ + } + +#define MACvTxOn(dwIoBase) \ + { \ + MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); \ + } + +#define MACvTransmit0(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); \ + } \ + } + +#define MACvTransmitAC0(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); \ + } \ + } + +#define MACvTransmitSYNC(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_SYNCDMACTL, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_SYNCDMACTL, DMACTL_RUN); \ + } \ + } + +#define MACvTransmitATIM(dwIoBase) \ + { \ + unsigned long dwData; \ + VNSvInPortD(dwIoBase + MAC_REG_ATIMDMACTL, &dwData); \ + if (dwData & DMACTL_RUN) { \ + VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_WAKE); \ + } \ + else { \ + VNSvOutPortD(dwIoBase + MAC_REG_ATIMDMACTL, DMACTL_RUN); \ + } \ + } + +#define MACvTransmitBCN(dwIoBase) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_BCNDMACTL, BEACON_READY); \ + } + +#define MACvClearStckDS(dwIoBase) \ + { \ + unsigned char byOrgValue; \ + VNSvInPortB(dwIoBase + MAC_REG_STICKHW, &byOrgValue); \ + byOrgValue = byOrgValue & 0xFC; \ + VNSvOutPortB(dwIoBase + MAC_REG_STICKHW, byOrgValue); \ + } + +#define MACvReadISR(dwIoBase, pdwValue) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_ISR, pdwValue); \ + } + +#define MACvWriteISR(dwIoBase, dwValue) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_ISR, dwValue); \ + } + +#define MACvIntEnable(dwIoBase, dwMask) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_IMR, dwMask); \ + } + +#define MACvIntDisable(dwIoBase) \ + { \ + VNSvOutPortD(dwIoBase + MAC_REG_IMR, 0); \ + } + +#define MACvSelectPage0(dwIoBase) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } +#define MACvSelectPage1(dwIoBase) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + } + +#define MACvReadMIBCounter(dwIoBase, pdwCounter) \ + { \ + VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR , pdwCounter); \ + } + +#define MACvPwrEvntDisable(dwIoBase) \ + { \ + VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000); \ + } + +#define MACvEnableProtectMD(dwIoBase) \ + { \ + unsigned long dwOrgValue; \ + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ + dwOrgValue = dwOrgValue | EnCFG_ProtectMd; \ + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ + } + +#define MACvDisableProtectMD(dwIoBase) \ + { \ + unsigned long dwOrgValue; \ + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ + dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd; \ + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ + } + +#define MACvEnableBarkerPreambleMd(dwIoBase) \ + { \ + unsigned long dwOrgValue; \ + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ + dwOrgValue = dwOrgValue | EnCFG_BarkerPream; \ + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ + } + +#define MACvDisableBarkerPreambleMd(dwIoBase) \ + { \ + unsigned long dwOrgValue; \ + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ + dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream; \ + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ + } + +#define MACvSetBBType(dwIoBase, byTyp) \ + { \ + unsigned long dwOrgValue; \ + VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); \ + dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK; \ + dwOrgValue = dwOrgValue | (unsigned long) byTyp; \ + VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); \ + } + +#define MACvReadATIMW(dwIoBase, pwCounter) \ + { \ + VNSvInPortW(dwIoBase + MAC_REG_AIDATIM , pwCounter); \ + } + +#define MACvWriteATIMW(dwIoBase, wCounter) \ + { \ + VNSvOutPortW(dwIoBase + MAC_REG_AIDATIM , wCounter); \ + } + +#define MACvWriteCRC16_128(dwIoBase, byRegOfs, wCRC) \ + { \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1); \ + VNSvOutPortW(dwIoBase + byRegOfs, wCRC); \ + VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 0); \ + } + +#define MACvGPIOIn(dwIoBase, pbyValue) \ + { \ + VNSvInPortB(dwIoBase + MAC_REG_GPIOCTL1, pbyValue); \ + } #define MACvSetRFLE_LatchBase(dwIoBase) \ -{ \ - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT); \ -} + { \ + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT); \ + } /*--------------------- Export Classes ----------------------------*/ @@ -1107,7 +1107,7 @@ void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime); void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData); -bool MACbTxDMAOff (unsigned long dwIoBase, unsigned int idx); +bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx); void MACvClearBusSusInd(unsigned long dwIoBase); void MACvEnableBusSusEn(unsigned long dwIoBase); @@ -1116,14 +1116,14 @@ bool MACbFlushSYNCFifo(unsigned long dwIoBase); bool MACbPSWakeup(unsigned long dwIoBase); void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, - unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID); + unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID); void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx); void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); + unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); //void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID); void MACvDisableDefaultKey(unsigned long dwIoBase); void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, - unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); + unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID); void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID); #endif // __MAC_H__ -- cgit From fd0badb8edd3d59d226248d9f8aceca8b0aadb81 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:56 -0700 Subject: staging:vt6655:mib: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mib.c | 698 +++++++++++++++++++++---------------------- drivers/staging/vt6655/mib.h | 502 +++++++++++++++---------------- 2 files changed, 600 insertions(+), 600 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index 63ae4adddf2f..a1b99990b569 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -45,7 +45,7 @@ #include "baseband.h" /*--------------------- Static Definitions -------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -70,9 +70,9 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: none * */ -void STAvClearAllCounter (PSStatCounter pStatistic) +void STAvClearAllCounter(PSStatCounter pStatistic) { - // set memory to zero + // set memory to zero memset(pStatistic, 0, sizeof(SStatCounter)); } @@ -90,54 +90,54 @@ void STAvClearAllCounter (PSStatCounter pStatistic) * Return Value: none * */ -void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, unsigned long dwIsr) +void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr) { - /**********************/ - /* ABNORMAL interrupt */ - /**********************/ - // not any IMR bit invoke irq + /**********************/ + /* ABNORMAL interrupt */ + /**********************/ + // not any IMR bit invoke irq - if (dwIsr == 0) { - pStatistic->ISRStat.dwIsrUnknown++; - return; - } + if (dwIsr == 0) { + pStatistic->ISRStat.dwIsrUnknown++; + return; + } //Added by Kyle - if (dwIsr & ISR_TXDMA0) // ISR, bit0 - pStatistic->ISRStat.dwIsrTx0OK++; // TXDMA0 successful + if (dwIsr & ISR_TXDMA0) // ISR, bit0 + pStatistic->ISRStat.dwIsrTx0OK++; // TXDMA0 successful - if (dwIsr & ISR_AC0DMA) // ISR, bit1 - pStatistic->ISRStat.dwIsrAC0TxOK++; // AC0DMA successful + if (dwIsr & ISR_AC0DMA) // ISR, bit1 + pStatistic->ISRStat.dwIsrAC0TxOK++; // AC0DMA successful - if (dwIsr & ISR_BNTX) // ISR, bit2 - pStatistic->ISRStat.dwIsrBeaconTxOK++; // BeaconTx successful + if (dwIsr & ISR_BNTX) // ISR, bit2 + pStatistic->ISRStat.dwIsrBeaconTxOK++; // BeaconTx successful - if (dwIsr & ISR_RXDMA0) // ISR, bit3 - pStatistic->ISRStat.dwIsrRx0OK++; // Rx0 successful + if (dwIsr & ISR_RXDMA0) // ISR, bit3 + pStatistic->ISRStat.dwIsrRx0OK++; // Rx0 successful - if (dwIsr & ISR_TBTT) // ISR, bit4 - pStatistic->ISRStat.dwIsrTBTTInt++; // TBTT successful + if (dwIsr & ISR_TBTT) // ISR, bit4 + pStatistic->ISRStat.dwIsrTBTTInt++; // TBTT successful - if (dwIsr & ISR_SOFTTIMER) // ISR, bit6 - pStatistic->ISRStat.dwIsrSTIMERInt++; + if (dwIsr & ISR_SOFTTIMER) // ISR, bit6 + pStatistic->ISRStat.dwIsrSTIMERInt++; - if (dwIsr & ISR_WATCHDOG) // ISR, bit7 - pStatistic->ISRStat.dwIsrWatchDog++; + if (dwIsr & ISR_WATCHDOG) // ISR, bit7 + pStatistic->ISRStat.dwIsrWatchDog++; - if (dwIsr & ISR_FETALERR) // ISR, bit8 - pStatistic->ISRStat.dwIsrUnrecoverableError++; + if (dwIsr & ISR_FETALERR) // ISR, bit8 + pStatistic->ISRStat.dwIsrUnrecoverableError++; - if (dwIsr & ISR_SOFTINT) // ISR, bit9 - pStatistic->ISRStat.dwIsrSoftInterrupt++; // software interrupt + if (dwIsr & ISR_SOFTINT) // ISR, bit9 + pStatistic->ISRStat.dwIsrSoftInterrupt++; // software interrupt - if (dwIsr & ISR_MIBNEARFULL) // ISR, bit10 - pStatistic->ISRStat.dwIsrMIBNearfull++; + if (dwIsr & ISR_MIBNEARFULL) // ISR, bit10 + pStatistic->ISRStat.dwIsrMIBNearfull++; - if (dwIsr & ISR_RXNOBUF) // ISR, bit11 - pStatistic->ISRStat.dwIsrRxNoBuf++; // Rx No Buff + if (dwIsr & ISR_RXNOBUF) // ISR, bit11 + pStatistic->ISRStat.dwIsrRxNoBuf++; // Rx No Buff - if (dwIsr & ISR_RXDMA1) // ISR, bit12 - pStatistic->ISRStat.dwIsrRx1OK++; // Rx1 successful + if (dwIsr & ISR_RXDMA1) // ISR, bit12 + pStatistic->ISRStat.dwIsrRx1OK++; // Rx1 successful // if (dwIsr & ISR_ATIMTX) // ISR, bit13 // pStatistic->ISRStat.dwIsrATIMTxOK++; // ATIMTX successful @@ -154,8 +154,8 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, unsigned long dwIsr) // if (dwIsr & ISR_SYNCFLUSHOK) // ISR, bit20 // pStatistic->ISRStat.dwIsrSYNCFlushOK++; - if (dwIsr & ISR_SOFTTIMER1) // ISR, bit21 - pStatistic->ISRStat.dwIsrSTIMER1Int++; + if (dwIsr & ISR_SOFTTIMER1) // ISR, bit21 + pStatistic->ISRStat.dwIsrSTIMER1Int++; } @@ -176,194 +176,194 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, unsigned long dwIsr) * Return Value: none * */ -void STAvUpdateRDStatCounter (PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength) +void STAvUpdateRDStatCounter(PSStatCounter pStatistic, + unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, + unsigned char *pbyBuffer, unsigned int cbFrameLength) { - //need change - PS802_11Header pHeader = (PS802_11Header)pbyBuffer; - - if (byRSR & RSR_ADDROK) - pStatistic->dwRsrADDROk++; - if (byRSR & RSR_CRCOK) { - pStatistic->dwRsrCRCOk++; - - pStatistic->ullRsrOK++; - - if (cbFrameLength >= ETH_ALEN) { - // update counters in case of successful transmit - if (byRSR & RSR_ADDRBROAD) { - pStatistic->ullRxBroadcastFrames++; - pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength; - } - else if (byRSR & RSR_ADDRMULTI) { - pStatistic->ullRxMulticastFrames++; - pStatistic->ullRxMulticastBytes += (unsigned long long) cbFrameLength; - } - else { - pStatistic->ullRxDirectedFrames++; - pStatistic->ullRxDirectedBytes += (unsigned long long) cbFrameLength; - } - } - } - - if(byRxRate==22) { - pStatistic->CustomStat.ullRsr11M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr11MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr11M, (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); - } - else if(byRxRate==11) { - pStatistic->CustomStat.ullRsr5M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr5MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr5M, (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); - } - else if(byRxRate==4) { - pStatistic->CustomStat.ullRsr2M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr2MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr2M, (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); - } - else if(byRxRate==2){ - pStatistic->CustomStat.ullRsr1M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr1MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr1M, (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); - } - else if(byRxRate==12){ - pStatistic->CustomStat.ullRsr6M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr6MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr6M, (int)pStatistic->CustomStat.ullRsr6MCRCOk); - } - else if(byRxRate==18){ - pStatistic->CustomStat.ullRsr9M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr9MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr9M, (int)pStatistic->CustomStat.ullRsr9MCRCOk); - } - else if(byRxRate==24){ - pStatistic->CustomStat.ullRsr12M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr12MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr12M, (int)pStatistic->CustomStat.ullRsr12MCRCOk); - } - else if(byRxRate==36){ - pStatistic->CustomStat.ullRsr18M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr18MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr18M, (int)pStatistic->CustomStat.ullRsr18MCRCOk); - } - else if(byRxRate==48){ - pStatistic->CustomStat.ullRsr24M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr24MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr24M, (int)pStatistic->CustomStat.ullRsr24MCRCOk); - } - else if(byRxRate==72){ - pStatistic->CustomStat.ullRsr36M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr36MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr36M, (int)pStatistic->CustomStat.ullRsr36MCRCOk); - } - else if(byRxRate==96){ - pStatistic->CustomStat.ullRsr48M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr48MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr48M, (int)pStatistic->CustomStat.ullRsr48MCRCOk); - } - else if(byRxRate==108){ - pStatistic->CustomStat.ullRsr54M++; - if(byRSR & RSR_CRCOK) { - pStatistic->CustomStat.ullRsr54MCRCOk++; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr54M, (int)pStatistic->CustomStat.ullRsr54MCRCOk); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (int)pStatistic->dwRsrRxPacket+1, (int)pStatistic->dwRsrCRCOk); - } - - if (byRSR & RSR_BSSIDOK) - pStatistic->dwRsrBSSIDOk++; - - if (byRSR & RSR_BCNSSIDOK) - pStatistic->dwRsrBCNSSIDOk++; - if (byRSR & RSR_IVLDLEN) //invalid len (> 2312 byte) - pStatistic->dwRsrLENErr++; - if (byRSR & RSR_IVLDTYP) //invalid packet type - pStatistic->dwRsrTYPErr++; - if (byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) - pStatistic->dwRsrErr++; - - if (byNewRSR & NEWRSR_DECRYPTOK) - pStatistic->dwNewRsrDECRYPTOK++; - if (byNewRSR & NEWRSR_CFPIND) - pStatistic->dwNewRsrCFP++; - if (byNewRSR & NEWRSR_HWUTSF) - pStatistic->dwNewRsrUTSF++; - if (byNewRSR & NEWRSR_BCNHITAID) - pStatistic->dwNewRsrHITAID++; - if (byNewRSR & NEWRSR_BCNHITAID0) - pStatistic->dwNewRsrHITAID0++; - - // increase rx packet count - pStatistic->dwRsrRxPacket++; - pStatistic->dwRsrRxOctet += cbFrameLength; - - - if (IS_TYPE_DATA(pbyBuffer)) { - pStatistic->dwRsrRxData++; - } else if (IS_TYPE_MGMT(pbyBuffer)){ - pStatistic->dwRsrRxManage++; - } else if (IS_TYPE_CONTROL(pbyBuffer)){ - pStatistic->dwRsrRxControl++; - } - - if (byRSR & RSR_ADDRBROAD) - pStatistic->dwRsrBroadcast++; - else if (byRSR & RSR_ADDRMULTI) - pStatistic->dwRsrMulticast++; - else - pStatistic->dwRsrDirected++; - - if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl)) - pStatistic->dwRsrRxFragment++; - - if (cbFrameLength < ETH_ZLEN + 4) { - pStatistic->dwRsrRunt++; - } - else if (cbFrameLength == ETH_ZLEN + 4) { - pStatistic->dwRsrRxFrmLen64++; - } - else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) { - pStatistic->dwRsrRxFrmLen65_127++; - } - else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) { - pStatistic->dwRsrRxFrmLen128_255++; - } - else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) { - pStatistic->dwRsrRxFrmLen256_511++; - } - else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) { - pStatistic->dwRsrRxFrmLen512_1023++; - } - else if ((1024 <= cbFrameLength) && (cbFrameLength <= ETH_FRAME_LEN + 4)) { - pStatistic->dwRsrRxFrmLen1024_1518++; - } else if (cbFrameLength > ETH_FRAME_LEN + 4) { - pStatistic->dwRsrLong++; - } + //need change + PS802_11Header pHeader = (PS802_11Header)pbyBuffer; + + if (byRSR & RSR_ADDROK) + pStatistic->dwRsrADDROk++; + if (byRSR & RSR_CRCOK) { + pStatistic->dwRsrCRCOk++; + + pStatistic->ullRsrOK++; + + if (cbFrameLength >= ETH_ALEN) { + // update counters in case of successful transmit + if (byRSR & RSR_ADDRBROAD) { + pStatistic->ullRxBroadcastFrames++; + pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength; + } + else if (byRSR & RSR_ADDRMULTI) { + pStatistic->ullRxMulticastFrames++; + pStatistic->ullRxMulticastBytes += (unsigned long long) cbFrameLength; + } + else { + pStatistic->ullRxDirectedFrames++; + pStatistic->ullRxDirectedBytes += (unsigned long long) cbFrameLength; + } + } + } + + if (byRxRate == 22) { + pStatistic->CustomStat.ullRsr11M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr11MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "11M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr11M, (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); + } + else if (byRxRate == 11) { + pStatistic->CustomStat.ullRsr5M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr5MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 5M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr5M, (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); + } + else if (byRxRate == 4) { + pStatistic->CustomStat.ullRsr2M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr2MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 2M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr2M, (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); + } + else if (byRxRate == 2) { + pStatistic->CustomStat.ullRsr1M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr1MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 1M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr1M, (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); + } + else if (byRxRate == 12) { + pStatistic->CustomStat.ullRsr6M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr6MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 6M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr6M, (int)pStatistic->CustomStat.ullRsr6MCRCOk); + } + else if (byRxRate == 18) { + pStatistic->CustomStat.ullRsr9M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr9MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 9M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr9M, (int)pStatistic->CustomStat.ullRsr9MCRCOk); + } + else if (byRxRate == 24) { + pStatistic->CustomStat.ullRsr12M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr12MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "12M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr12M, (int)pStatistic->CustomStat.ullRsr12MCRCOk); + } + else if (byRxRate == 36) { + pStatistic->CustomStat.ullRsr18M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr18MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "18M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr18M, (int)pStatistic->CustomStat.ullRsr18MCRCOk); + } + else if (byRxRate == 48) { + pStatistic->CustomStat.ullRsr24M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr24MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "24M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr24M, (int)pStatistic->CustomStat.ullRsr24MCRCOk); + } + else if (byRxRate == 72) { + pStatistic->CustomStat.ullRsr36M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr36MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "36M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr36M, (int)pStatistic->CustomStat.ullRsr36MCRCOk); + } + else if (byRxRate == 96) { + pStatistic->CustomStat.ullRsr48M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr48MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "48M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr48M, (int)pStatistic->CustomStat.ullRsr48MCRCOk); + } + else if (byRxRate == 108) { + pStatistic->CustomStat.ullRsr54M++; + if (byRSR & RSR_CRCOK) { + pStatistic->CustomStat.ullRsr54MCRCOk++; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "54M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr54M, (int)pStatistic->CustomStat.ullRsr54MCRCOk); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown: Total[%d], CRCOK[%d]\n", (int)pStatistic->dwRsrRxPacket+1, (int)pStatistic->dwRsrCRCOk); + } + + if (byRSR & RSR_BSSIDOK) + pStatistic->dwRsrBSSIDOk++; + + if (byRSR & RSR_BCNSSIDOK) + pStatistic->dwRsrBCNSSIDOk++; + if (byRSR & RSR_IVLDLEN) //invalid len (> 2312 byte) + pStatistic->dwRsrLENErr++; + if (byRSR & RSR_IVLDTYP) //invalid packet type + pStatistic->dwRsrTYPErr++; + if (byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) + pStatistic->dwRsrErr++; + + if (byNewRSR & NEWRSR_DECRYPTOK) + pStatistic->dwNewRsrDECRYPTOK++; + if (byNewRSR & NEWRSR_CFPIND) + pStatistic->dwNewRsrCFP++; + if (byNewRSR & NEWRSR_HWUTSF) + pStatistic->dwNewRsrUTSF++; + if (byNewRSR & NEWRSR_BCNHITAID) + pStatistic->dwNewRsrHITAID++; + if (byNewRSR & NEWRSR_BCNHITAID0) + pStatistic->dwNewRsrHITAID0++; + + // increase rx packet count + pStatistic->dwRsrRxPacket++; + pStatistic->dwRsrRxOctet += cbFrameLength; + + + if (IS_TYPE_DATA(pbyBuffer)) { + pStatistic->dwRsrRxData++; + } else if (IS_TYPE_MGMT(pbyBuffer)) { + pStatistic->dwRsrRxManage++; + } else if (IS_TYPE_CONTROL(pbyBuffer)) { + pStatistic->dwRsrRxControl++; + } + + if (byRSR & RSR_ADDRBROAD) + pStatistic->dwRsrBroadcast++; + else if (byRSR & RSR_ADDRMULTI) + pStatistic->dwRsrMulticast++; + else + pStatistic->dwRsrDirected++; + + if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl)) + pStatistic->dwRsrRxFragment++; + + if (cbFrameLength < ETH_ZLEN + 4) { + pStatistic->dwRsrRunt++; + } + else if (cbFrameLength == ETH_ZLEN + 4) { + pStatistic->dwRsrRxFrmLen64++; + } + else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) { + pStatistic->dwRsrRxFrmLen65_127++; + } + else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) { + pStatistic->dwRsrRxFrmLen128_255++; + } + else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) { + pStatistic->dwRsrRxFrmLen256_511++; + } + else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) { + pStatistic->dwRsrRxFrmLen512_1023++; + } + else if ((1024 <= cbFrameLength) && (cbFrameLength <= ETH_FRAME_LEN + 4)) { + pStatistic->dwRsrRxFrmLen1024_1518++; + } else if (cbFrameLength > ETH_FRAME_LEN + 4) { + pStatistic->dwRsrLong++; + } } @@ -387,28 +387,28 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, */ void -STAvUpdateRDStatCounterEx ( - PSStatCounter pStatistic, - unsigned char byRSR, - unsigned char byNewRSR, - unsigned char byRxRate, - unsigned char *pbyBuffer, - unsigned int cbFrameLength - ) +STAvUpdateRDStatCounterEx( + PSStatCounter pStatistic, + unsigned char byRSR, + unsigned char byNewRSR, + unsigned char byRxRate, + unsigned char *pbyBuffer, + unsigned int cbFrameLength +) { - STAvUpdateRDStatCounter( - pStatistic, - byRSR, - byNewRSR, - byRxRate, - pbyBuffer, - cbFrameLength - ); - - // rx length - pStatistic->dwCntRxFrmLength = cbFrameLength; - // rx pattern, we just see 10 bytes for sample - memcpy(pStatistic->abyCntRxPattern, (unsigned char *)pbyBuffer, 10); + STAvUpdateRDStatCounter( + pStatistic, + byRSR, + byNewRSR, + byRxRate, + pbyBuffer, + cbFrameLength +); + + // rx length + pStatistic->dwCntRxFrmLength = cbFrameLength; + // rx pattern, we just see 10 bytes for sample + memcpy(pStatistic->abyCntRxPattern, (unsigned char *)pbyBuffer, 10); } @@ -430,77 +430,77 @@ STAvUpdateRDStatCounterEx ( * */ void -STAvUpdateTDStatCounter ( - PSStatCounter pStatistic, - unsigned char byTSR0, - unsigned char byTSR1, - unsigned char *pbyBuffer, - unsigned int cbFrameLength, - unsigned int uIdx - ) +STAvUpdateTDStatCounter( + PSStatCounter pStatistic, + unsigned char byTSR0, + unsigned char byTSR1, + unsigned char *pbyBuffer, + unsigned int cbFrameLength, + unsigned int uIdx +) { - PWLAN_80211HDR_A4 pHeader; - unsigned char *pbyDestAddr; - unsigned char byTSR0_NCR = byTSR0 & TSR0_NCR; - - - - pHeader = (PWLAN_80211HDR_A4) pbyBuffer; - if (WLAN_GET_FC_TODS(pHeader->wFrameCtl) == 0) { - pbyDestAddr = &(pHeader->abyAddr1[0]); - } - else { - pbyDestAddr = &(pHeader->abyAddr3[0]); - } - // increase tx packet count - pStatistic->dwTsrTxPacket[uIdx]++; - pStatistic->dwTsrTxOctet[uIdx] += cbFrameLength; - - if (byTSR0_NCR != 0) { - pStatistic->dwTsrRetry[uIdx]++; - pStatistic->dwTsrTotalRetry[uIdx] += byTSR0_NCR; - - if (byTSR0_NCR == 1) - pStatistic->dwTsrOnceRetry[uIdx]++; - else - pStatistic->dwTsrMoreThanOnceRetry[uIdx]++; - } - - if ((byTSR1&(TSR1_TERR|TSR1_RETRYTMO|TSR1_TMO|ACK_DATA)) == 0) { - pStatistic->ullTsrOK[uIdx]++; - pStatistic->CustomStat.ullTsrAllOK = - (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]); - // update counters in case that successful transmit - if (is_broadcast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxBroadcastFrames[uIdx]++; - pStatistic->ullTxBroadcastBytes[uIdx] += (unsigned long long) cbFrameLength; - } - else if (is_multicast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxMulticastFrames[uIdx]++; - pStatistic->ullTxMulticastBytes[uIdx] += (unsigned long long) cbFrameLength; - } - else { - pStatistic->ullTxDirectedFrames[uIdx]++; - pStatistic->ullTxDirectedBytes[uIdx] += (unsigned long long) cbFrameLength; - } - } - else { - if (byTSR1 & TSR1_TERR) - pStatistic->dwTsrErr[uIdx]++; - if (byTSR1 & TSR1_RETRYTMO) - pStatistic->dwTsrRetryTimeout[uIdx]++; - if (byTSR1 & TSR1_TMO) - pStatistic->dwTsrTransmitTimeout[uIdx]++; - if (byTSR1 & ACK_DATA) - pStatistic->dwTsrACKData[uIdx]++; - } - - if (is_broadcast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrBroadcast[uIdx]++; - else if (is_multicast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrMulticast[uIdx]++; - else - pStatistic->dwTsrDirected[uIdx]++; + PWLAN_80211HDR_A4 pHeader; + unsigned char *pbyDestAddr; + unsigned char byTSR0_NCR = byTSR0 & TSR0_NCR; + + + + pHeader = (PWLAN_80211HDR_A4) pbyBuffer; + if (WLAN_GET_FC_TODS(pHeader->wFrameCtl) == 0) { + pbyDestAddr = &(pHeader->abyAddr1[0]); + } + else { + pbyDestAddr = &(pHeader->abyAddr3[0]); + } + // increase tx packet count + pStatistic->dwTsrTxPacket[uIdx]++; + pStatistic->dwTsrTxOctet[uIdx] += cbFrameLength; + + if (byTSR0_NCR != 0) { + pStatistic->dwTsrRetry[uIdx]++; + pStatistic->dwTsrTotalRetry[uIdx] += byTSR0_NCR; + + if (byTSR0_NCR == 1) + pStatistic->dwTsrOnceRetry[uIdx]++; + else + pStatistic->dwTsrMoreThanOnceRetry[uIdx]++; + } + + if ((byTSR1&(TSR1_TERR|TSR1_RETRYTMO|TSR1_TMO|ACK_DATA)) == 0) { + pStatistic->ullTsrOK[uIdx]++; + pStatistic->CustomStat.ullTsrAllOK = + (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]); + // update counters in case that successful transmit + if (is_broadcast_ether_addr(pbyDestAddr)) { + pStatistic->ullTxBroadcastFrames[uIdx]++; + pStatistic->ullTxBroadcastBytes[uIdx] += (unsigned long long) cbFrameLength; + } + else if (is_multicast_ether_addr(pbyDestAddr)) { + pStatistic->ullTxMulticastFrames[uIdx]++; + pStatistic->ullTxMulticastBytes[uIdx] += (unsigned long long) cbFrameLength; + } + else { + pStatistic->ullTxDirectedFrames[uIdx]++; + pStatistic->ullTxDirectedBytes[uIdx] += (unsigned long long) cbFrameLength; + } + } + else { + if (byTSR1 & TSR1_TERR) + pStatistic->dwTsrErr[uIdx]++; + if (byTSR1 & TSR1_RETRYTMO) + pStatistic->dwTsrRetryTimeout[uIdx]++; + if (byTSR1 & TSR1_TMO) + pStatistic->dwTsrTransmitTimeout[uIdx]++; + if (byTSR1 & ACK_DATA) + pStatistic->dwTsrACKData[uIdx]++; + } + + if (is_broadcast_ether_addr(pbyDestAddr)) + pStatistic->dwTsrBroadcast[uIdx]++; + else if (is_multicast_ether_addr(pbyDestAddr)) + pStatistic->dwTsrMulticast[uIdx]++; + else + pStatistic->dwTsrDirected[uIdx]++; } @@ -520,20 +520,20 @@ STAvUpdateTDStatCounter ( * */ void -STAvUpdateTDStatCounterEx ( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength - ) +STAvUpdateTDStatCounterEx( + PSStatCounter pStatistic, + unsigned char *pbyBuffer, + unsigned long cbFrameLength +) { - unsigned int uPktLength; + unsigned int uPktLength; - uPktLength = (unsigned int)cbFrameLength; + uPktLength = (unsigned int)cbFrameLength; - // tx length - pStatistic->dwCntTxBufLength = uPktLength; - // tx pattern, we just see 16 bytes for sample - memcpy(pStatistic->abyCntTxPattern, pbyBuffer, 16); + // tx length + pStatistic->dwCntTxBufLength = uPktLength; + // tx pattern, we just see 16 bytes for sample + memcpy(pStatistic->abyCntTxPattern, pbyBuffer, 16); } @@ -553,28 +553,28 @@ STAvUpdateTDStatCounterEx ( */ void STAvUpdate802_11Counter( - PSDot11Counters p802_11Counter, - PSStatCounter pStatistic, - unsigned long dwCounter - ) + PSDot11Counters p802_11Counter, + PSStatCounter pStatistic, + unsigned long dwCounter +) { - //p802_11Counter->TransmittedFragmentCount - p802_11Counter->MulticastTransmittedFrameCount = (unsigned long long) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] + - pStatistic->dwTsrBroadcast[TYPE_TXDMA0] + - pStatistic->dwTsrMulticast[TYPE_AC0DMA] + - pStatistic->dwTsrMulticast[TYPE_TXDMA0]); - p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]); - p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]); - p802_11Counter->MultipleRetryCount = (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] + - pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]); - //p802_11Counter->FrameDuplicateCount - p802_11Counter->RTSSuccessCount += (unsigned long long) (dwCounter & 0x000000ff); - p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8); - p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16); - p802_11Counter->FCSErrorCount += (unsigned long long) ((dwCounter & 0xff000000) >> 24); - //p802_11Counter->ReceivedFragmentCount - p802_11Counter->MulticastReceivedFrameCount = (unsigned long long) (pStatistic->dwRsrBroadcast + - pStatistic->dwRsrMulticast); + //p802_11Counter->TransmittedFragmentCount + p802_11Counter->MulticastTransmittedFrameCount = (unsigned long long) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] + + pStatistic->dwTsrBroadcast[TYPE_TXDMA0] + + pStatistic->dwTsrMulticast[TYPE_AC0DMA] + + pStatistic->dwTsrMulticast[TYPE_TXDMA0]); + p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]); + p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]); + p802_11Counter->MultipleRetryCount = (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] + + pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]); + //p802_11Counter->FrameDuplicateCount + p802_11Counter->RTSSuccessCount += (unsigned long long) (dwCounter & 0x000000ff); + p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8); + p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16); + p802_11Counter->FCSErrorCount += (unsigned long long) ((dwCounter & 0xff000000) >> 24); + //p802_11Counter->ReceivedFragmentCount + p802_11Counter->MulticastReceivedFrameCount = (unsigned long long) (pStatistic->dwRsrBroadcast + + pStatistic->dwRsrMulticast); } /* @@ -592,6 +592,6 @@ STAvUpdate802_11Counter( void STAvClear802_11Counter(PSDot11Counters p802_11Counter) { - // set memory to zero + // set memory to zero memset(p802_11Counter, 0, sizeof(SDot11Counters)); } diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index 5cd697a2bc77..c2740e0bb059 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -39,28 +39,28 @@ // typedef struct tagSDot11Counters { - unsigned long Length; // Length of structure - unsigned long long TransmittedFragmentCount; - unsigned long long MulticastTransmittedFrameCount; - unsigned long long FailedCount; - unsigned long long RetryCount; - unsigned long long MultipleRetryCount; - unsigned long long RTSSuccessCount; - unsigned long long RTSFailureCount; - unsigned long long ACKFailureCount; - unsigned long long FrameDuplicateCount; - unsigned long long ReceivedFragmentCount; - unsigned long long MulticastReceivedFrameCount; - unsigned long long FCSErrorCount; - unsigned long long TKIPLocalMICFailures; - unsigned long long TKIPRemoteMICFailures; - unsigned long long TKIPICVErrors; - unsigned long long TKIPCounterMeasuresInvoked; - unsigned long long TKIPReplays; - unsigned long long CCMPFormatErrors; - unsigned long long CCMPReplays; - unsigned long long CCMPDecryptErrors; - unsigned long long FourWayHandshakeFailures; + unsigned long Length; // Length of structure + unsigned long long TransmittedFragmentCount; + unsigned long long MulticastTransmittedFrameCount; + unsigned long long FailedCount; + unsigned long long RetryCount; + unsigned long long MultipleRetryCount; + unsigned long long RTSSuccessCount; + unsigned long long RTSFailureCount; + unsigned long long ACKFailureCount; + unsigned long long FrameDuplicateCount; + unsigned long long ReceivedFragmentCount; + unsigned long long MulticastReceivedFrameCount; + unsigned long long FCSErrorCount; + unsigned long long TKIPLocalMICFailures; + unsigned long long TKIPRemoteMICFailures; + unsigned long long TKIPICVErrors; + unsigned long long TKIPCounterMeasuresInvoked; + unsigned long long TKIPReplays; + unsigned long long CCMPFormatErrors; + unsigned long long CCMPReplays; + unsigned long long CCMPDecryptErrors; + unsigned long long FourWayHandshakeFailures; // unsigned long long WEPUndecryptableCount; // unsigned long long WEPICVErrorCount; // unsigned long long DecryptSuccessCount; @@ -72,29 +72,29 @@ typedef struct tagSDot11Counters { // MIB2 counter // typedef struct tagSMib2Counter { - long ifIndex; - char ifDescr[256]; // max size 255 plus zero ending - // e.g. "interface 1" - long ifType; - long ifMtu; - unsigned long ifSpeed; - unsigned char ifPhysAddress[ETH_ALEN]; - long ifAdminStatus; - long ifOperStatus; - unsigned long ifLastChange; - unsigned long ifInOctets; - unsigned long ifInUcastPkts; - unsigned long ifInNUcastPkts; - unsigned long ifInDiscards; - unsigned long ifInErrors; - unsigned long ifInUnknownProtos; - unsigned long ifOutOctets; - unsigned long ifOutUcastPkts; - unsigned long ifOutNUcastPkts; - unsigned long ifOutDiscards; - unsigned long ifOutErrors; - unsigned long ifOutQLen; - unsigned long ifSpecific; + long ifIndex; + char ifDescr[256]; // max size 255 plus zero ending + // e.g. "interface 1" + long ifType; + long ifMtu; + unsigned long ifSpeed; + unsigned char ifPhysAddress[ETH_ALEN]; + long ifAdminStatus; + long ifOperStatus; + unsigned long ifLastChange; + unsigned long ifInOctets; + unsigned long ifInUcastPkts; + unsigned long ifInNUcastPkts; + unsigned long ifInDiscards; + unsigned long ifInErrors; + unsigned long ifInUnknownProtos; + unsigned long ifOutOctets; + unsigned long ifOutUcastPkts; + unsigned long ifOutNUcastPkts; + unsigned long ifOutDiscards; + unsigned long ifOutErrors; + unsigned long ifOutQLen; + unsigned long ifSpecific; } SMib2Counter, *PSMib2Counter; // Value in the ifType entry @@ -110,64 +110,64 @@ typedef struct tagSMib2Counter { // RMON counter // typedef struct tagSRmonCounter { - long etherStatsIndex; - unsigned long etherStatsDataSource; - unsigned long etherStatsDropEvents; - unsigned long etherStatsOctets; - unsigned long etherStatsPkts; - unsigned long etherStatsBroadcastPkts; - unsigned long etherStatsMulticastPkts; - unsigned long etherStatsCRCAlignErrors; - unsigned long etherStatsUndersizePkts; - unsigned long etherStatsOversizePkts; - unsigned long etherStatsFragments; - unsigned long etherStatsJabbers; - unsigned long etherStatsCollisions; - unsigned long etherStatsPkt64Octets; - unsigned long etherStatsPkt65to127Octets; - unsigned long etherStatsPkt128to255Octets; - unsigned long etherStatsPkt256to511Octets; - unsigned long etherStatsPkt512to1023Octets; - unsigned long etherStatsPkt1024to1518Octets; - unsigned long etherStatsOwners; - unsigned long etherStatsStatus; + long etherStatsIndex; + unsigned long etherStatsDataSource; + unsigned long etherStatsDropEvents; + unsigned long etherStatsOctets; + unsigned long etherStatsPkts; + unsigned long etherStatsBroadcastPkts; + unsigned long etherStatsMulticastPkts; + unsigned long etherStatsCRCAlignErrors; + unsigned long etherStatsUndersizePkts; + unsigned long etherStatsOversizePkts; + unsigned long etherStatsFragments; + unsigned long etherStatsJabbers; + unsigned long etherStatsCollisions; + unsigned long etherStatsPkt64Octets; + unsigned long etherStatsPkt65to127Octets; + unsigned long etherStatsPkt128to255Octets; + unsigned long etherStatsPkt256to511Octets; + unsigned long etherStatsPkt512to1023Octets; + unsigned long etherStatsPkt1024to1518Octets; + unsigned long etherStatsOwners; + unsigned long etherStatsStatus; } SRmonCounter, *PSRmonCounter; // // Custom counter // typedef struct tagSCustomCounters { - unsigned long Length; - - unsigned long long ullTsrAllOK; - - unsigned long long ullRsr11M; - unsigned long long ullRsr5M; - unsigned long long ullRsr2M; - unsigned long long ullRsr1M; - - unsigned long long ullRsr11MCRCOk; - unsigned long long ullRsr5MCRCOk; - unsigned long long ullRsr2MCRCOk; - unsigned long long ullRsr1MCRCOk; - - unsigned long long ullRsr54M; - unsigned long long ullRsr48M; - unsigned long long ullRsr36M; - unsigned long long ullRsr24M; - unsigned long long ullRsr18M; - unsigned long long ullRsr12M; - unsigned long long ullRsr9M; - unsigned long long ullRsr6M; - - unsigned long long ullRsr54MCRCOk; - unsigned long long ullRsr48MCRCOk; - unsigned long long ullRsr36MCRCOk; - unsigned long long ullRsr24MCRCOk; - unsigned long long ullRsr18MCRCOk; - unsigned long long ullRsr12MCRCOk; - unsigned long long ullRsr9MCRCOk; - unsigned long long ullRsr6MCRCOk; + unsigned long Length; + + unsigned long long ullTsrAllOK; + + unsigned long long ullRsr11M; + unsigned long long ullRsr5M; + unsigned long long ullRsr2M; + unsigned long long ullRsr1M; + + unsigned long long ullRsr11MCRCOk; + unsigned long long ullRsr5MCRCOk; + unsigned long long ullRsr2MCRCOk; + unsigned long long ullRsr1MCRCOk; + + unsigned long long ullRsr54M; + unsigned long long ullRsr48M; + unsigned long long ullRsr36M; + unsigned long long ullRsr24M; + unsigned long long ullRsr18M; + unsigned long long ullRsr12M; + unsigned long long ullRsr9M; + unsigned long long ullRsr6M; + + unsigned long long ullRsr54MCRCOk; + unsigned long long ullRsr48MCRCOk; + unsigned long long ullRsr36MCRCOk; + unsigned long long ullRsr24MCRCOk; + unsigned long long ullRsr18MCRCOk; + unsigned long long ullRsr12MCRCOk; + unsigned long long ullRsr9MCRCOk; + unsigned long long ullRsr6MCRCOk; } SCustomCounters, *PSCustomCounters; @@ -176,30 +176,30 @@ typedef struct tagSCustomCounters { // Custom counter // typedef struct tagSISRCounters { - unsigned long Length; - - unsigned long dwIsrTx0OK; - unsigned long dwIsrAC0TxOK; - unsigned long dwIsrBeaconTxOK; - unsigned long dwIsrRx0OK; - unsigned long dwIsrTBTTInt; - unsigned long dwIsrSTIMERInt; - unsigned long dwIsrWatchDog; - unsigned long dwIsrUnrecoverableError; - unsigned long dwIsrSoftInterrupt; - unsigned long dwIsrMIBNearfull; - unsigned long dwIsrRxNoBuf; - - unsigned long dwIsrUnknown; // unknown interrupt count - - unsigned long dwIsrRx1OK; - unsigned long dwIsrATIMTxOK; - unsigned long dwIsrSYNCTxOK; - unsigned long dwIsrCFPEnd; - unsigned long dwIsrATIMEnd; - unsigned long dwIsrSYNCFlushOK; - unsigned long dwIsrSTIMER1Int; - ///////////////////////////////////// + unsigned long Length; + + unsigned long dwIsrTx0OK; + unsigned long dwIsrAC0TxOK; + unsigned long dwIsrBeaconTxOK; + unsigned long dwIsrRx0OK; + unsigned long dwIsrTBTTInt; + unsigned long dwIsrSTIMERInt; + unsigned long dwIsrWatchDog; + unsigned long dwIsrUnrecoverableError; + unsigned long dwIsrSoftInterrupt; + unsigned long dwIsrMIBNearfull; + unsigned long dwIsrRxNoBuf; + + unsigned long dwIsrUnknown; // unknown interrupt count + + unsigned long dwIsrRx1OK; + unsigned long dwIsrATIMTxOK; + unsigned long dwIsrSYNCTxOK; + unsigned long dwIsrCFPEnd; + unsigned long dwIsrATIMEnd; + unsigned long dwIsrSYNCFlushOK; + unsigned long dwIsrSTIMER1Int; + ///////////////////////////////////// } SISRCounters, *PSISRCounters; @@ -213,125 +213,125 @@ typedef struct tagSISRCounters { // statistic counter // typedef struct tagSStatCounter { - // - // ISR status count - // - - - // RSR status count - // - unsigned long dwRsrFrmAlgnErr; - unsigned long dwRsrErr; - unsigned long dwRsrCRCErr; - unsigned long dwRsrCRCOk; - unsigned long dwRsrBSSIDOk; - unsigned long dwRsrADDROk; - unsigned long dwRsrBCNSSIDOk; - unsigned long dwRsrLENErr; - unsigned long dwRsrTYPErr; - - unsigned long dwNewRsrDECRYPTOK; - unsigned long dwNewRsrCFP; - unsigned long dwNewRsrUTSF; - unsigned long dwNewRsrHITAID; - unsigned long dwNewRsrHITAID0; - - unsigned long dwRsrLong; - unsigned long dwRsrRunt; - - unsigned long dwRsrRxControl; - unsigned long dwRsrRxData; - unsigned long dwRsrRxManage; - - unsigned long dwRsrRxPacket; - unsigned long dwRsrRxOctet; - unsigned long dwRsrBroadcast; - unsigned long dwRsrMulticast; - unsigned long dwRsrDirected; - // 64-bit OID - unsigned long long ullRsrOK; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullRxBroadcastBytes; - unsigned long long ullRxMulticastBytes; - unsigned long long ullRxDirectedBytes; - unsigned long long ullRxBroadcastFrames; - unsigned long long ullRxMulticastFrames; - unsigned long long ullRxDirectedFrames; - - unsigned long dwRsrRxFragment; - unsigned long dwRsrRxFrmLen64; - unsigned long dwRsrRxFrmLen65_127; - unsigned long dwRsrRxFrmLen128_255; - unsigned long dwRsrRxFrmLen256_511; - unsigned long dwRsrRxFrmLen512_1023; - unsigned long dwRsrRxFrmLen1024_1518; - - // TSR status count - // - unsigned long dwTsrTotalRetry[TYPE_MAXTD]; // total collision retry count - unsigned long dwTsrOnceRetry[TYPE_MAXTD]; // this packet only occur one collision - unsigned long dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision - unsigned long dwTsrRetry[TYPE_MAXTD]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - unsigned long dwTsrACKData[TYPE_MAXTD]; - unsigned long dwTsrErr[TYPE_MAXTD]; - unsigned long dwAllTsrOK[TYPE_MAXTD]; - unsigned long dwTsrRetryTimeout[TYPE_MAXTD]; - unsigned long dwTsrTransmitTimeout[TYPE_MAXTD]; - - unsigned long dwTsrTxPacket[TYPE_MAXTD]; - unsigned long dwTsrTxOctet[TYPE_MAXTD]; - unsigned long dwTsrBroadcast[TYPE_MAXTD]; - unsigned long dwTsrMulticast[TYPE_MAXTD]; - unsigned long dwTsrDirected[TYPE_MAXTD]; - - // RD/TD count - unsigned long dwCntRxFrmLength; - unsigned long dwCntTxBufLength; - - unsigned char abyCntRxPattern[16]; - unsigned char abyCntTxPattern[16]; - - - - // Software check.... - unsigned long dwCntRxDataErr; // rx buffer data software compare CRC err count - unsigned long dwCntDecryptErr; // rx buffer data software compare CRC err count - unsigned long dwCntRxICVErr; // rx buffer data software compare CRC err count - unsigned int idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD - - // 64-bit OID - unsigned long long ullTsrOK[TYPE_MAXTD]; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullTxBroadcastFrames[TYPE_MAXTD]; - unsigned long long ullTxMulticastFrames[TYPE_MAXTD]; - unsigned long long ullTxDirectedFrames[TYPE_MAXTD]; - unsigned long long ullTxBroadcastBytes[TYPE_MAXTD]; - unsigned long long ullTxMulticastBytes[TYPE_MAXTD]; - unsigned long long ullTxDirectedBytes[TYPE_MAXTD]; + // + // ISR status count + // + + + // RSR status count + // + unsigned long dwRsrFrmAlgnErr; + unsigned long dwRsrErr; + unsigned long dwRsrCRCErr; + unsigned long dwRsrCRCOk; + unsigned long dwRsrBSSIDOk; + unsigned long dwRsrADDROk; + unsigned long dwRsrBCNSSIDOk; + unsigned long dwRsrLENErr; + unsigned long dwRsrTYPErr; + + unsigned long dwNewRsrDECRYPTOK; + unsigned long dwNewRsrCFP; + unsigned long dwNewRsrUTSF; + unsigned long dwNewRsrHITAID; + unsigned long dwNewRsrHITAID0; + + unsigned long dwRsrLong; + unsigned long dwRsrRunt; + + unsigned long dwRsrRxControl; + unsigned long dwRsrRxData; + unsigned long dwRsrRxManage; + + unsigned long dwRsrRxPacket; + unsigned long dwRsrRxOctet; + unsigned long dwRsrBroadcast; + unsigned long dwRsrMulticast; + unsigned long dwRsrDirected; + // 64-bit OID + unsigned long long ullRsrOK; + + // for some optional OIDs (64 bits) and DMI support + unsigned long long ullRxBroadcastBytes; + unsigned long long ullRxMulticastBytes; + unsigned long long ullRxDirectedBytes; + unsigned long long ullRxBroadcastFrames; + unsigned long long ullRxMulticastFrames; + unsigned long long ullRxDirectedFrames; + + unsigned long dwRsrRxFragment; + unsigned long dwRsrRxFrmLen64; + unsigned long dwRsrRxFrmLen65_127; + unsigned long dwRsrRxFrmLen128_255; + unsigned long dwRsrRxFrmLen256_511; + unsigned long dwRsrRxFrmLen512_1023; + unsigned long dwRsrRxFrmLen1024_1518; + + // TSR status count + // + unsigned long dwTsrTotalRetry[TYPE_MAXTD]; // total collision retry count + unsigned long dwTsrOnceRetry[TYPE_MAXTD]; // this packet only occur one collision + unsigned long dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision + unsigned long dwTsrRetry[TYPE_MAXTD]; // this packet has ever occur collision, + // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) + unsigned long dwTsrACKData[TYPE_MAXTD]; + unsigned long dwTsrErr[TYPE_MAXTD]; + unsigned long dwAllTsrOK[TYPE_MAXTD]; + unsigned long dwTsrRetryTimeout[TYPE_MAXTD]; + unsigned long dwTsrTransmitTimeout[TYPE_MAXTD]; + + unsigned long dwTsrTxPacket[TYPE_MAXTD]; + unsigned long dwTsrTxOctet[TYPE_MAXTD]; + unsigned long dwTsrBroadcast[TYPE_MAXTD]; + unsigned long dwTsrMulticast[TYPE_MAXTD]; + unsigned long dwTsrDirected[TYPE_MAXTD]; + + // RD/TD count + unsigned long dwCntRxFrmLength; + unsigned long dwCntTxBufLength; + + unsigned char abyCntRxPattern[16]; + unsigned char abyCntTxPattern[16]; + + + + // Software check.... + unsigned long dwCntRxDataErr; // rx buffer data software compare CRC err count + unsigned long dwCntDecryptErr; // rx buffer data software compare CRC err count + unsigned long dwCntRxICVErr; // rx buffer data software compare CRC err count + unsigned int idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD + + // 64-bit OID + unsigned long long ullTsrOK[TYPE_MAXTD]; + + // for some optional OIDs (64 bits) and DMI support + unsigned long long ullTxBroadcastFrames[TYPE_MAXTD]; + unsigned long long ullTxMulticastFrames[TYPE_MAXTD]; + unsigned long long ullTxDirectedFrames[TYPE_MAXTD]; + unsigned long long ullTxBroadcastBytes[TYPE_MAXTD]; + unsigned long long ullTxMulticastBytes[TYPE_MAXTD]; + unsigned long long ullTxDirectedBytes[TYPE_MAXTD]; // unsigned long dwTxRetryCount[8]; - // - // ISR status count - // - SISRCounters ISRStat; - - SCustomCounters CustomStat; - - #ifdef Calcu_LinkQual - //Tx count: - unsigned long TxNoRetryOkCount; //success tx no retry ! - unsigned long TxRetryOkCount; //success tx but retry ! - unsigned long TxFailCount; //fail tx ? - //Rx count: - unsigned long RxOkCnt; //success rx ! - unsigned long RxFcsErrCnt; //fail rx ? - //statistic - unsigned long SignalStren; - unsigned long LinkQuality; - #endif + // + // ISR status count + // + SISRCounters ISRStat; + + SCustomCounters CustomStat; + +#ifdef Calcu_LinkQual + //Tx count: + unsigned long TxNoRetryOkCount; //success tx no retry ! + unsigned long TxRetryOkCount; //success tx but retry ! + unsigned long TxFailCount; //fail tx ? + //Rx count: + unsigned long RxOkCnt; //success rx ! + unsigned long RxFcsErrCnt; //fail rx ? + //statistic + unsigned long SignalStren; + unsigned long LinkQuality; +#endif } SStatCounter, *PSStatCounter; /*--------------------- Export Classes ----------------------------*/ @@ -345,27 +345,27 @@ void STAvClearAllCounter(PSStatCounter pStatistic); void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr); void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); + unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, + unsigned char *pbyBuffer, unsigned int cbFrameLength); void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRsr, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); + unsigned char byRSR, unsigned char byNewRsr, unsigned char byRxRate, + unsigned char *pbyBuffer, unsigned int cbFrameLength); void STAvUpdateTDStatCounter(PSStatCounter pStatistic, unsigned char byTSR0, unsigned char byTSR1, - unsigned char *pbyBuffer, unsigned int cbFrameLength, unsigned int uIdx); + unsigned char *pbyBuffer, unsigned int cbFrameLength, unsigned int uIdx); void STAvUpdateTDStatCounterEx( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength - ); + PSStatCounter pStatistic, + unsigned char *pbyBuffer, + unsigned long cbFrameLength +); void STAvUpdate802_11Counter( - PSDot11Counters p802_11Counter, - PSStatCounter pStatistic, - unsigned long dwCounter - ); + PSDot11Counters p802_11Counter, + PSStatCounter pStatistic, + unsigned long dwCounter +); void STAvClear802_11Counter(PSDot11Counters p802_11Counter); -- cgit From a51ff9058ca08a97b2e69dc70748a53eb144c3f8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:57 -0700 Subject: staging:vt6655:michael: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/michael.c | 166 +++++++++++++++++++-------------------- drivers/staging/vt6655/michael.h | 6 +- 2 files changed, 86 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c index 67618f069d0d..cd39dc0ee8a7 100644 --- a/drivers/staging/vt6655/michael.c +++ b/drivers/staging/vt6655/michael.c @@ -48,11 +48,11 @@ /*--------------------- Static Functions --------------------------*/ /* -static unsigned long s_dwGetUINT32(unsigned char *p); // Get unsigned long from 4 bytes LSByte first -static void s_vPutUINT32(unsigned char *p, unsigned long val); // Put unsigned long into 4 bytes LSByte first + static unsigned long s_dwGetUINT32(unsigned char *p); // Get unsigned long from 4 bytes LSByte first + static void s_vPutUINT32(unsigned char *p, unsigned long val); // Put unsigned long into 4 bytes LSByte first */ static void s_vClear(void); // Clear the internal message, - // resets the object to the state just after construction. +// resets the object to the state just after construction. static void s_vSetKey(unsigned long dwK0, unsigned long dwK1); static void s_vAppendByte(unsigned char b); // Add a single byte to the internal message @@ -66,116 +66,116 @@ static unsigned int nBytesInM; // # bytes in M /*--------------------- Export Functions --------------------------*/ /* -static unsigned long s_dwGetUINT32 (unsigned char *p) + static unsigned long s_dwGetUINT32 (unsigned char *p) // Convert from unsigned char [] to unsigned long in a portable way { - unsigned long res = 0; - unsigned int i; - for(i=0; i<4; i++ ) - { - res |= (*p++) << (8*i); - } - return res; +unsigned long res = 0; +unsigned int i; +for (i=0; i<4; i++) +{ + res |= (*p++) << (8 * i); +} +return res; } static void s_vPutUINT32 (unsigned char *p, unsigned long val) // Convert from unsigned long to unsigned char [] in a portable way { - unsigned int i; - for(i=0; i<4; i++ ) - { - *p++ = (unsigned char) (val & 0xff); - val >>= 8; - } + unsigned int i; + for (i=0; i<4; i++) + { + *p++ = (unsigned char) (val & 0xff); + val >>= 8; + } } */ -static void s_vClear (void) +static void s_vClear(void) { - // Reset the state to the empty message. - L = K0; - R = K1; - nBytesInM = 0; - M = 0; + // Reset the state to the empty message. + L = K0; + R = K1; + nBytesInM = 0; + M = 0; } -static void s_vSetKey (unsigned long dwK0, unsigned long dwK1) +static void s_vSetKey(unsigned long dwK0, unsigned long dwK1) { - // Set the key - K0 = dwK0; - K1 = dwK1; - // and reset the message - s_vClear(); + // Set the key + K0 = dwK0; + K1 = dwK1; + // and reset the message + s_vClear(); } -static void s_vAppendByte (unsigned char b) +static void s_vAppendByte(unsigned char b) { - // Append the byte to our word-sized buffer - M |= b << (8*nBytesInM); - nBytesInM++; - // Process the word if it is full. - if( nBytesInM >= 4 ) - { - L ^= M; - R ^= ROL32( L, 17 ); - L += R; - R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); - L += R; - R ^= ROL32( L, 3 ); - L += R; - R ^= ROR32( L, 2 ); - L += R; - // Clear the buffer - M = 0; - nBytesInM = 0; - } + // Append the byte to our word-sized buffer + M |= b << (8*nBytesInM); + nBytesInM++; + // Process the word if it is full. + if (nBytesInM >= 4) + { + L ^= M; + R ^= ROL32(L, 17); + L += R; + R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); + L += R; + R ^= ROL32(L, 3); + L += R; + R ^= ROR32(L, 2); + L += R; + // Clear the buffer + M = 0; + nBytesInM = 0; + } } -void MIC_vInit (unsigned long dwK0, unsigned long dwK1) +void MIC_vInit(unsigned long dwK0, unsigned long dwK1) { - // Set the key - s_vSetKey(dwK0, dwK1); + // Set the key + s_vSetKey(dwK0, dwK1); } -void MIC_vUnInit (void) +void MIC_vUnInit(void) { - // Wipe the key material - K0 = 0; - K1 = 0; + // Wipe the key material + K0 = 0; + K1 = 0; - // And the other fields as well. - //Note that this sets (L,R) to (K0,K1) which is just fine. - s_vClear(); + // And the other fields as well. + //Note that this sets (L,R) to (K0,K1) which is just fine. + s_vClear(); } -void MIC_vAppend (unsigned char *src, unsigned int nBytes) +void MIC_vAppend(unsigned char *src, unsigned int nBytes) { - // This is simple - while (nBytes > 0) - { - s_vAppendByte(*src++); - nBytes--; - } + // This is simple + while (nBytes > 0) + { + s_vAppendByte(*src++); + nBytes--; + } } -void MIC_vGetMIC (unsigned long *pdwL, unsigned long *pdwR) +void MIC_vGetMIC(unsigned long *pdwL, unsigned long *pdwR) { - // Append the minimum padding - s_vAppendByte(0x5a); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - // and then zeroes until the length is a multiple of 4 - while( nBytesInM != 0 ) - { - s_vAppendByte(0); - } - // The s_vAppendByte function has already computed the result. - *pdwL = L; - *pdwR = R; - // Reset to the empty message. - s_vClear(); + // Append the minimum padding + s_vAppendByte(0x5a); + s_vAppendByte(0); + s_vAppendByte(0); + s_vAppendByte(0); + s_vAppendByte(0); + // and then zeroes until the length is a multiple of 4 + while (nBytesInM != 0) + { + s_vAppendByte(0); + } + // The s_vAppendByte function has already computed the result. + *pdwL = L; + *pdwR = R; + // Reset to the empty message. + s_vClear(); } diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h index 3131b161d6a9..03936eec72ff 100644 --- a/drivers/staging/vt6655/michael.h +++ b/drivers/staging/vt6655/michael.h @@ -49,9 +49,9 @@ void MIC_vGetMIC(unsigned long *pdwL, unsigned long *pdwR); /*--------------------- Export Macros ------------------------------*/ // Rotation functions on 32 bit values -#define ROL32( A, n ) \ - ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) -#define ROR32( A, n ) ROL32( (A), 32-(n) ) +#define ROL32(A, n) \ + (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) +#define ROR32(A, n) ROL32((A), 32-(n)) #endif //__MICHAEL_H__ -- cgit From 474f0f89ef01f3b628fa84c488e9e029a081ce9b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:58 -0700 Subject: staging:vt6655:power: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/power.c | 468 ++++++++++++++++++++--------------------- drivers/staging/vt6655/power.h | 30 +-- 2 files changed, 249 insertions(+), 249 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 661d534304cc..3be79c7f79ba 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -54,7 +54,7 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ @@ -71,62 +71,62 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: * None. * --*/ + -*/ void PSvEnablePowerSaving( - void *hDeviceContext, - unsigned short wListenInterval - ) + void *hDeviceContext, + unsigned short wListenInterval +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15; - - // set period of power up before TBTT - VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); - if (pDevice->eOPMode != OP_MODE_ADHOC) { - // set AID - VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); - } else { - // set ATIM Window - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - } - // Set AutoSleep - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - // Set HWUTSF - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); - - if (wListenInterval >= 2) { - // clear always listen beacon - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); - //pDevice->wCFG &= ~CFG_ALB; - // first time set listen next beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - pMgmt->wCountToWakeUp = wListenInterval; - } - else { - // always listen beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); - //pDevice->wCFG |= CFG_ALB; - pMgmt->wCountToWakeUp = 0; - } - - // enable power saving hw function - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - pDevice->bEnablePSMode = true; - - if (pDevice->eOPMode == OP_MODE_ADHOC) { + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15; + + // set period of power up before TBTT + VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); + if (pDevice->eOPMode != OP_MODE_ADHOC) { + // set AID + VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); + } else { + // set ATIM Window + MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); + } + // Set AutoSleep + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); + // Set HWUTSF + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); + + if (wListenInterval >= 2) { + // clear always listen beacon + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); + //pDevice->wCFG &= ~CFG_ALB; + // first time set listen next beacon + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); + pMgmt->wCountToWakeUp = wListenInterval; + } + else { + // always listen beacon + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); + //pDevice->wCFG |= CFG_ALB; + pMgmt->wCountToWakeUp = 0; + } + + // enable power saving hw function + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); + pDevice->bEnablePSMode = true; + + if (pDevice->eOPMode == OP_MODE_ADHOC) { // bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } - // We don't send null pkt in ad hoc mode since beacon will handle this. - else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { - PSbSendNullPacket(pDevice); - } - pDevice->bPWBitOn = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); - return; + } + // We don't send null pkt in ad hoc mode since beacon will handle this. + else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + PSbSendNullPacket(pDevice); + } + pDevice->bPWBitOn = true; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); + return; } @@ -142,32 +142,32 @@ PSvEnablePowerSaving( * Return Value: * None. * --*/ + -*/ void PSvDisablePowerSaving( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; // PSMgmtObject pMgmt = pDevice->pMgmt; - // disable power saving hw function - MACbPSWakeup(pDevice->PortOffset); - //clear AutoSleep - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - //clear HWUTSF - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); - // set always listen beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); - - pDevice->bEnablePSMode = false; - - if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { - PSbSendNullPacket(pDevice); - } - pDevice->bPWBitOn = false; - return; + // disable power saving hw function + MACbPSWakeup(pDevice->PortOffset); + //clear AutoSleep + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); + //clear HWUTSF + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); + // set always listen beacon + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); + + pDevice->bEnablePSMode = false; + + if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + PSbSendNullPacket(pDevice); + } + pDevice->bPWBitOn = false; + return; } @@ -179,61 +179,61 @@ PSvDisablePowerSaving( * Return Value: * true, if power down success * false, if fail --*/ + -*/ bool PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp - ) + void *hDeviceContext, + bool bCheckRxDMA, + bool bCheckCountToWakeUp +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - // check if already in Doze mode - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - // check if in TIM wake period - if (pMgmt->bInTIMWake) - return false; - } - - // check scan state - if (pDevice->bCmdRunning) - return false; - - // Force PSEN on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - - // check if all TD are empty, - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - - // check if rx isr is clear - if (bCheckRxDMA && - ((pDevice->dwIsr& ISR_RXDMA0) != 0) && - ((pDevice->dwIsr & ISR_RXDMA1) != 0)){ - return false; - } - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - if (bCheckCountToWakeUp && - (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) { - return false; - } - } - - // no Tx, no Rx isr, now go to Doze - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int uIdx; + + // check if already in Doze mode + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) + return true; + + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + // check if in TIM wake period + if (pMgmt->bInTIMWake) + return false; + } + + // check scan state + if (pDevice->bCmdRunning) + return false; + + // Force PSEN on + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); + + // check if all TD are empty, + for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { + if (pDevice->iTDUsed[uIdx] != 0) + return false; + } + + // check if rx isr is clear + if (bCheckRxDMA && + ((pDevice->dwIsr & ISR_RXDMA0) != 0) && + ((pDevice->dwIsr & ISR_RXDMA1) != 0)) { + return false; + } + + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + if (bCheckCountToWakeUp && + (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) { + return false; + } + } + + // no Tx, no Rx isr, now go to Doze + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); + return true; } @@ -246,43 +246,43 @@ PSbConsiderPowerDown( * Return Value: * None. * --*/ + -*/ void PSvSendPSPOLL( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxMgmtPacket pTxPacket = NULL; - - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | - WLAN_SET_FC_PWRMGT(0) - )); - pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; - memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); - } - else { + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSTxMgmtPacket pTxPacket = NULL; + + + memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | + WLAN_SET_FC_PWRMGT(0) +)); + pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; + memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; + pTxPacket->cbPayloadLen = 0; + // send the frame + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); + } + else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); - }; + }; - return; + return; } @@ -295,81 +295,81 @@ PSvSendPSPOLL( * Return Value: * None. * --*/ + -*/ bool PSbSendNullPacket( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - - if (pDevice->bLinkPass == false) { - return false; - } - #ifdef TxInSleep - if ((pDevice->bEnablePSMode == false) && - (pDevice->fTxDataInSleep == false)){ - return false; - } + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket = NULL; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int uIdx; + + + if (pDevice->bLinkPass == false) { + return false; + } +#ifdef TxInSleep + if ((pDevice->bEnablePSMode == false) && + (pDevice->fTxDataInSleep == false)) { + return false; + } #else - if (pDevice->bEnablePSMode == false) { - return false; - } + if (pDevice->bEnablePSMode == false) { + return false; + } #endif - if (pDevice->bEnablePSMode) { - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx ++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - } - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - if (pDevice->bEnablePSMode) { - - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(1) - )); - } - else { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(0) - )); - } - - if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1)); - } - - memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); - return false; - } - else { + if (pDevice->bEnablePSMode) { + for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { + if (pDevice->iTDUsed[uIdx] != 0) + return false; + } + } + + memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + + if (pDevice->bEnablePSMode) { + + pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | + WLAN_SET_FC_PWRMGT(1) +)); + } + else { + pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | + WLAN_SET_FC_PWRMGT(0) +)); + } + + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1)); + } + + memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; + pTxPacket->cbPayloadLen = 0; + // send the frame + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); + return false; + } + else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); - } + } - return true ; + return true; } /*+ @@ -380,33 +380,33 @@ PSbSendNullPacket( * Return Value: * None. * --*/ + -*/ bool PSbIsNextTBTTWakeUp( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - bool bWakeUp = false; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + bool bWakeUp = false; - if (pMgmt->wListenInterval >= 2) { - if (pMgmt->wCountToWakeUp == 0) { - pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - } + if (pMgmt->wListenInterval >= 2) { + if (pMgmt->wCountToWakeUp == 0) { + pMgmt->wCountToWakeUp = pMgmt->wListenInterval; + } - pMgmt->wCountToWakeUp --; + pMgmt->wCountToWakeUp--; - if (pMgmt->wCountToWakeUp == 1) { - // Turn on wake up to listen next beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - bWakeUp = true; - } + if (pMgmt->wCountToWakeUp == 1) { + // Turn on wake up to listen next beacon + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); + bWakeUp = true; + } - } + } - return bWakeUp; + return bWakeUp; } diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index 01013b592285..0d1d372b1c48 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -50,35 +50,35 @@ bool PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp - ); + void *hDeviceContext, + bool bCheckRxDMA, + bool bCheckCountToWakeUp +); void PSvDisablePowerSaving( - void *hDeviceContext - ); + void *hDeviceContext +); void PSvEnablePowerSaving( - void *hDeviceContext, - unsigned short wListenInterval - ); + void *hDeviceContext, + unsigned short wListenInterval +); void PSvSendPSPOLL( - void *hDeviceContext - ); + void *hDeviceContext +); bool PSbSendNullPacket( - void *hDeviceContext - ); + void *hDeviceContext +); bool PSbIsNextTBTTWakeUp( - void *hDeviceContext - ); + void *hDeviceContext +); #endif //__POWER_H__ -- cgit From 7e58568f13f325233687aa288d412848fef0d8e8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:44:59 -0700 Subject: staging:vt6655:rc4: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rc4.c | 78 ++++++++++++++++++++++---------------------- drivers/staging/vt6655/rc4.h | 6 ++-- 2 files changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c index 9856c08b3d77..343b815c0a9e 100644 --- a/drivers/staging/vt6655/rc4.c +++ b/drivers/staging/vt6655/rc4.c @@ -34,54 +34,54 @@ void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len) { - unsigned int ust1, ust2; - unsigned int keyindex; - unsigned int stateindex; - unsigned char *pbyst; - unsigned int idx; + unsigned int ust1, ust2; + unsigned int keyindex; + unsigned int stateindex; + unsigned char *pbyst; + unsigned int idx; - pbyst = pRC4->abystate; - pRC4->ux = 0; - pRC4->uy = 0; - for (idx = 0; idx < 256; idx++) - pbyst[idx] = (unsigned char)idx; - keyindex = 0; - stateindex = 0; - for (idx = 0; idx < 256; idx++) { - ust1 = pbyst[idx]; - stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; - ust2 = pbyst[stateindex]; - pbyst[stateindex] = (unsigned char)ust1; - pbyst[idx] = (unsigned char)ust2; - if (++keyindex >= cbKey_len) - keyindex = 0; - } + pbyst = pRC4->abystate; + pRC4->ux = 0; + pRC4->uy = 0; + for (idx = 0; idx < 256; idx++) + pbyst[idx] = (unsigned char)idx; + keyindex = 0; + stateindex = 0; + for (idx = 0; idx < 256; idx++) { + ust1 = pbyst[idx]; + stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; + ust2 = pbyst[stateindex]; + pbyst[stateindex] = (unsigned char)ust1; + pbyst[idx] = (unsigned char)ust2; + if (++keyindex >= cbKey_len) + keyindex = 0; + } } unsigned int rc4_byte(PRC4Ext pRC4) { - unsigned int ux; - unsigned int uy; - unsigned int ustx, usty; - unsigned char *pbyst; + unsigned int ux; + unsigned int uy; + unsigned int ustx, usty; + unsigned char *pbyst; - pbyst = pRC4->abystate; - ux = (pRC4->ux + 1) & 0xff; - ustx = pbyst[ux]; - uy = (ustx + pRC4->uy) & 0xff; - usty = pbyst[uy]; - pRC4->ux = ux; - pRC4->uy = uy; - pbyst[uy] = (unsigned char)ustx; - pbyst[ux] = (unsigned char)usty; + pbyst = pRC4->abystate; + ux = (pRC4->ux + 1) & 0xff; + ustx = pbyst[ux]; + uy = (ustx + pRC4->uy) & 0xff; + usty = pbyst[uy]; + pRC4->ux = ux; + pRC4->uy = uy; + pbyst[uy] = (unsigned char)ustx; + pbyst[ux] = (unsigned char)usty; - return pbyst[(ustx + usty) & 0xff]; + return pbyst[(ustx + usty) & 0xff]; } void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, - unsigned char *pbySrc, unsigned int cbData_len) + unsigned char *pbySrc, unsigned int cbData_len) { - unsigned int ii; - for (ii = 0; ii < cbData_len; ii++) - pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4)); + unsigned int ii; + for (ii = 0; ii < cbData_len; ii++) + pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4)); } diff --git a/drivers/staging/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h index ad04e351365e..74b2eed9bce3 100644 --- a/drivers/staging/vt6655/rc4.h +++ b/drivers/staging/vt6655/rc4.h @@ -35,9 +35,9 @@ /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Types ------------------------------*/ typedef struct { - unsigned int ux; - unsigned int uy; - unsigned char abystate[256]; + unsigned int ux; + unsigned int uy; + unsigned char abystate[256]; } RC4Ext, *PRC4Ext; void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len); -- cgit From 3bd1996e3a7ebbf166080a4a76a01140ad1a1a8f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:00 -0700 Subject: staging:vt6655:rf: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rf.c | 1456 +++++++++++++++++++++---------------------- drivers/staging/vt6655/rf.h | 22 +- 2 files changed, 739 insertions(+), 739 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index aaa231aaf4e9..df38abf508fd 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -59,363 +59,363 @@ const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = { - 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x00FFF300+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0F4DC500+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0805B600+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0146C700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x00068800+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0403B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x00DBBA00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // - 0x0BDFFC00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x00000D00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW - }; + 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x00FFF300+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0F4DC500+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0805B600+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0146C700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x00068800+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0403B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x00DBBA00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // + 0x0BDFFC00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x00000D00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW +}; const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = { - 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz - 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz - 0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz - 0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz - 0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz - 0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz - 0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz - 0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz - 0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz - 0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz - 0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz - 0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz - 0x03F7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz - 0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2412M - }; + 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz + 0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz + 0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz + 0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz + 0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz + 0x03F7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz + 0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz + 0x03E7A000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz + 0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz + 0x03F7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz + 0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz + 0x03E7B000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz + 0x03F7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz + 0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2412M +}; const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = { - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz - 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz - 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz - 0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2412M - }; + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz + 0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz + 0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz + 0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2412M +}; unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = { - 0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04043900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04044900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04045900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04046900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04047900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04048900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04049900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0404F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04050900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04051900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04052900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04053900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04054900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04055900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04056900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04057900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04058900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04059900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0405F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04060900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04061900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04062900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04063900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04064900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04065900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04066900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04067900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04068900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04069900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0406F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04070900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04071900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04072900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04073900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04074900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04075900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04076900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04077900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04078900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x04079900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, - 0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW - }; + 0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04043900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04044900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04045900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04046900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04047900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04048900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04049900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0404F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04050900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04051900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04052900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04053900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04054900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04055900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04056900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04057900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04058900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04059900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0405F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04060900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04061900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04062900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04063900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04064900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04065900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04066900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04067900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04068900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04069900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0406F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04070900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04071900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04072900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04073900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04074900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04075900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04076900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04077900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04078900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x04079900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, + 0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW +}; //{{ RobertYu:20050104 // 40MHz reference frequency // Need to Pull PLLON(PE3) low when writing channel registers through 3-wire. const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = { - 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a - 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a - 0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2 - 0x3FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 5FDFA3 - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 11b/g // Need modify for 11a - //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45 - // RoberYu:20050113, Rev0.47 Regsiter Setting Guide - 0x802B5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B55 - 0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 860207 - 0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0xE0000A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: E0600A - 0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10) - //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C - // RoberYu:20050113, Rev0.47 Regsiter Setting Guide - 0x000A3C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C - 0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // Need modify for 11a: 12BACF - }; + 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a + 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a + 0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2 + 0x3FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 5FDFA3 + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 11b/g // Need modify for 11a + //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45 + // RoberYu:20050113, Rev0.47 Regsiter Setting Guide + 0x802B5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B55 + 0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 860207 + 0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0xE0000A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: E0600A + 0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10) + //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C + // RoberYu:20050113, Rev0.47 Regsiter Setting Guide + 0x000A3C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C + 0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // Need modify for 11a: 12BACF +}; const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = { - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g - 0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g - 0x5FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g - 0x67F78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 11a // Need modify for 11b/g - 0x853F5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g, RoberYu:20050113 - 0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g - 0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0xE0600A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g - 0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10) - 0x00147C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g - 0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, - 0x12BACF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // Need modify for 11b/g - }; + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g + 0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g + 0x5FDFA300+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g + 0x67F78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // 11a // Need modify for 11b/g + 0x853F5500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g, RoberYu:20050113 + 0x56AF3600+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0xCE020700+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g + 0x6EBC0800+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0xE0600A00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g + 0x08031B00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10) + 0x00147C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g + 0xFFFFFD00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x00000E00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, + 0x12BACF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // Need modify for 11b/g +}; const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = { - 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz - 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz - 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz - 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz - 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz - 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz - 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz - 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49 - 0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz - - // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) - 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) - 0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) - 0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) - - // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, - // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) - - 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) - 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) - 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) - 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) - 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) - 0x0FF55000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) - 0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) - 0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49 - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) - 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) - 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) - 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) - 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) - 0x0FF59000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) - - 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) - 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) - 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) - 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) - 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) - 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) - 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) - 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) - 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) - 0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) - 0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) - 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) - 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) - 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) - 0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) - 0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) - }; + 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz + 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz + 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz + 0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz + 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz + 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz + 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz + 0x0037A000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037B000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49 + 0x0037C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz + + // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) + 0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) + 0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) + 0x0FF53000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) + + // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, + // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) + + 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) + 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) + 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) + 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) + 0x0FF54000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) + 0x0FF55000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) + 0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) + 0x0FF56000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49 + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) + 0x0FF57000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) + 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) + 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) + 0x0FF58000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) + 0x0FF59000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) + + 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) + 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) + 0x0FF5C000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) + 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) + 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) + 0x0FF5D000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) + 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) + 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) + 0x0FF5E000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) + 0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) + 0x0FF5F000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) + 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) + 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) + 0x0FF60000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) + 0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) + 0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) +}; const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = { - 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz - 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz - 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz - 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz - 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz - 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz - 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz - 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz - 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz - 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz - 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz - 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz - 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz - 0x06666100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz - - // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) - 0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) - 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) - 0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) - 0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) - - // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, - // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) - 0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) - 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) - 0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) - 0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) - 0x10000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) - 0x1AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) - 0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) - 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) - 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) - 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) - 0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) - 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) - 0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) - 0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) - 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) - }; + 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz + 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz + 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz + 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz + 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz + 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz + 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz + 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz + 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz + 0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz + 0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz + 0x0B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz + 0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz + 0x06666100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz + + // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) + 0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) + 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) + 0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) + 0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) + + // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, + // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) + 0x1D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) + 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) + 0x08000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) + 0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) + 0x10000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) + 0x1AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) + 0x05555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) + 0x0AAAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) + 0x15555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) + 0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) + 0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) + 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) + 0x0D555100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) + 0x18000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) + 0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) +}; const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = { - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz - 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz - - // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) - - // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, - // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) - 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) - 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) - }; + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz + 0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 14, Tf = 2484MHz + + // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 183, Tf = 4915MHz (15) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 184, Tf = 4920MHz (16) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 185, Tf = 4925MHz (17) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 187, Tf = 4935MHz (18) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 188, Tf = 4940MHz (19) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 189, Tf = 4945MHz (20) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 192, Tf = 4960MHz (21) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 196, Tf = 4980MHz (22) + + // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, + // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 5035MHz (23) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 5040MHz (24) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 5045MHz (25) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 5055MHz (26) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 5060MHz (27) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 16, Tf = 5080MHz (28) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 34, Tf = 5170MHz (29) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 36, Tf = 5180MHz (30) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 38, Tf = 5190MHz (31) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 40, Tf = 5200MHz (32) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 42, Tf = 5210MHz (33) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 44, Tf = 5220MHz (34) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 46, Tf = 5230MHz (35) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 48, Tf = 5240MHz (36) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 52, Tf = 5260MHz (37) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 56, Tf = 5280MHz (38) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 60, Tf = 5300MHz (39) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 64, Tf = 5320MHz (40) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 100, Tf = 5500MHz (41) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 104, Tf = 5520MHz (42) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 108, Tf = 5540MHz (43) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 112, Tf = 5560MHz (44) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 116, Tf = 5580MHz (45) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 120, Tf = 5600MHz (46) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 124, Tf = 5620MHz (47) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 128, Tf = 5640MHz (48) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 132, Tf = 5660MHz (49) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 136, Tf = 5680MHz (50) + 0x67D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 140, Tf = 5700MHz (51) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 149, Tf = 5745MHz (52) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 153, Tf = 5765MHz (53) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 157, Tf = 5785MHz (54) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 161, Tf = 5805MHz (55) + 0x77D78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW // channel = 165, Tf = 5825MHz (56) +}; //}} RobertYu @@ -438,72 +438,72 @@ const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = { * Return Value: true if succeeded; false if failed. * */ -bool s_bAL7230Init (unsigned long dwIoBase) +bool s_bAL7230Init(unsigned long dwIoBase) { - int ii; - bool bResult; + int ii; + bool bResult; - bResult = true; + bResult = true; - //3-wire control for normal mode - VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); + //3-wire control for normal mode + VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | - SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | + SOFTPWRCTL_TXPEINV)); + BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration - for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[ii]); + for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[ii]); - // PLL On - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + // PLL On + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - //Calibration - MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable - MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active - MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable + //Calibration + MACvTimer0MicroSDelay(dwIoBase, 150);//150us + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x9ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:active, RCK:disable + MACvTimer0MicroSDelay(dwIoBase, 30);//30us + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x3ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW)); //TXDCOC:disable, RCK:active + MACvTimer0MicroSDelay(dwIoBase, 30);//30us + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); //TXDCOC:disable, RCK:disable - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | - SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPECTI | - SOFTPWRCTL_TXPEINV)); + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | + SOFTPWRCTL_SWPE2 | + SOFTPWRCTL_SWPECTI | + SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeON(dwIoBase); // RobertYu:20050106 + BBvPowerSaveModeON(dwIoBase); // RobertYu:20050106 - // PE1: TX_ON, PE2: RX_ON, PE3: PLLON - //3-wire control for power saving mode - VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 + // PE1: TX_ON, PE2: RX_ON, PE3: PLLON + //3-wire control for power saving mode + VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 - return bResult; + return bResult; } // Need to Pull PLLON low when writing channel registers through 3-wire interface -bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) +bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel) { - bool bResult; + bool bResult; - bResult = true; + bResult = true; - // PLLON Off - MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + // PLLON Off + MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable0[byChannel-1]); //Reg0 - bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable1[byChannel-1]); //Reg1 - bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL7230ChannelTable2[byChannel-1]); //Reg4 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable0[byChannel - 1]); //Reg0 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable1[byChannel - 1]); //Reg1 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230ChannelTable2[byChannel - 1]); //Reg4 - // PLLOn On - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + // PLLOn On + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - // Set Channel[7] = 0 to tell H/W channel is changing now. - VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); - MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL7230); - // Set Channel[7] = 1 to tell H/W channel change is done. - VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); + // Set Channel[7] = 0 to tell H/W channel is changing now. + VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); + MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL7230); + // Set Channel[7] = 1 to tell H/W channel change is done. + VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); - return bResult; + return bResult; } /* @@ -586,25 +586,25 @@ bool s_bAL7230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) * Return Value: true if succeeded; false if failed. * */ -bool IFRFbWriteEmbedded (unsigned long dwIoBase, unsigned long dwData) +bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData) { - unsigned short ww; - unsigned long dwValue; + unsigned short ww; + unsigned long dwValue; - VNSvOutPortD(dwIoBase + MAC_REG_IFREGCTL, dwData); + VNSvOutPortD(dwIoBase + MAC_REG_IFREGCTL, dwData); - // W_MAX_TIMEOUT is the timeout period - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - VNSvInPortD(dwIoBase + MAC_REG_IFREGCTL, &dwValue); - if (dwValue & IFREGCTL_DONE) - break; - } + // W_MAX_TIMEOUT is the timeout period + for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { + VNSvInPortD(dwIoBase + MAC_REG_IFREGCTL, &dwValue); + if (dwValue & IFREGCTL_DONE) + break; + } - if (ww == W_MAX_TIMEOUT) { + if (ww == W_MAX_TIMEOUT) { // DBG_PORT80_ALWAYS(0x32); - return false; - } - return true; + return false; + } + return true; } @@ -648,72 +648,72 @@ bool IFRFbWriteEmbedded (unsigned long dwIoBase, unsigned long dwData) * Return Value: true if succeeded; false if failed. * */ -bool RFbAL2230Init (unsigned long dwIoBase) +bool RFbAL2230Init(unsigned long dwIoBase) { - int ii; - bool bResult; + int ii; + bool bResult; - bResult = true; + bResult = true; - //3-wire control for normal mode - VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); + //3-wire control for normal mode + VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | - SOFTPWRCTL_TXPEINV)); + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | + SOFTPWRCTL_TXPEINV)); //2008-8-21 chester - // PLL Off + // PLL Off - MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - //patch abnormal AL2230 frequency output + //patch abnormal AL2230 frequency output //2008-8-21 chester - IFRFbWriteEmbedded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + IFRFbWriteEmbedded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); - for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[ii]); + for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[ii]); //2008-8-21 chester -MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us + MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us - // PLL On - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); + // PLL On + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - MACvTimer0MicroSDelay(dwIoBase, 150);//150us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); - MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); - MACvTimer0MicroSDelay(dwIoBase, 30);//30us - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); + MACvTimer0MicroSDelay(dwIoBase, 150);//150us + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + MACvTimer0MicroSDelay(dwIoBase, 30);//30us + bResult &= IFRFbWriteEmbedded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); + MACvTimer0MicroSDelay(dwIoBase, 30);//30us + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); - MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | - SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPECTI | - SOFTPWRCTL_TXPEINV)); + MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | + SOFTPWRCTL_SWPE2 | + SOFTPWRCTL_SWPECTI | + SOFTPWRCTL_TXPEINV)); - //3-wire control for power saving mode - VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 + //3-wire control for power saving mode + VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 - return bResult; + return bResult; } -bool RFbAL2230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) +bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel) { - bool bResult; + bool bResult; - bResult = true; + bResult = true; - bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]); - bResult &= IFRFbWriteEmbedded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]); + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230ChannelTable0[byChannel - 1]); + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL2230ChannelTable1[byChannel - 1]); - // Set Channel[7] = 0 to tell H/W channel is changing now. - VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); - MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230); - // Set Channel[7] = 1 to tell H/W channel change is done. - VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); + // Set Channel[7] = 0 to tell H/W channel is changing now. + VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); + MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230); + // Set Channel[7] = 1 to tell H/W channel change is done. + VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); - return bResult; + return bResult; } /* @@ -771,29 +771,29 @@ bool RFbAL2230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) * Return Value: true if succeeded; false if failed. * */ -bool RFbInit ( - PSDevice pDevice - ) +bool RFbInit( + PSDevice pDevice +) { -bool bResult = true; - switch (pDevice->byRFType) { - case RF_AIROHA : - case RF_AL2230S: - pDevice->byMaxPwrLevel = AL2230_PWR_IDX_LEN; - bResult = RFbAL2230Init(pDevice->PortOffset); - break; - case RF_AIROHA7230 : - pDevice->byMaxPwrLevel = AL7230_PWR_IDX_LEN; - bResult = s_bAL7230Init(pDevice->PortOffset); - break; - case RF_NOTHING : - bResult = true; - break; - default : - bResult = false; - break; - } - return bResult; + bool bResult = true; + switch (pDevice->byRFType) { + case RF_AIROHA: + case RF_AL2230S: + pDevice->byMaxPwrLevel = AL2230_PWR_IDX_LEN; + bResult = RFbAL2230Init(pDevice->PortOffset); + break; + case RF_AIROHA7230: + pDevice->byMaxPwrLevel = AL7230_PWR_IDX_LEN; + bResult = s_bAL7230Init(pDevice->PortOffset); + break; + case RF_NOTHING: + bResult = true; + break; + default: + bResult = false; + break; + } + return bResult; } /* @@ -809,21 +809,21 @@ bool bResult = true; * Return Value: true if succeeded; false if failed. * */ -bool RFbShutDown ( - PSDevice pDevice - ) +bool RFbShutDown( + PSDevice pDevice +) { -bool bResult = true; - - switch (pDevice->byRFType) { - case RF_AIROHA7230 : - bResult = IFRFbWriteEmbedded (pDevice->PortOffset, 0x1ABAEF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW); - break; - default : - bResult = true; - break; - } - return bResult; + bool bResult = true; + + switch (pDevice->byRFType) { + case RF_AIROHA7230: + bResult = IFRFbWriteEmbedded(pDevice->PortOffset, 0x1ABAEF00 + (BY_AL7230_REG_LEN << 3) + IFREGCTL_REGW); + break; + default: + bResult = true; + break; + } + return bResult; } /* @@ -839,28 +839,28 @@ bool bResult = true; * Return Value: true if succeeded; false if failed. * */ -bool RFbSelectChannel (unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel) +bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel) { -bool bResult = true; - switch (byRFType) { - - case RF_AIROHA : - case RF_AL2230S: - bResult = RFbAL2230SelectChannel(dwIoBase, byChannel); - break; - //{{ RobertYu: 20050104 - case RF_AIROHA7230 : - bResult = s_bAL7230SelectChannel(dwIoBase, byChannel); - break; - //}} RobertYu - case RF_NOTHING : - bResult = true; - break; - default: - bResult = false; - break; - } - return bResult; + bool bResult = true; + switch (byRFType) { + + case RF_AIROHA: + case RF_AL2230S: + bResult = RFbAL2230SelectChannel(dwIoBase, byChannel); + break; + //{{ RobertYu: 20050104 + case RF_AIROHA7230: + bResult = s_bAL7230SelectChannel(dwIoBase, byChannel); + break; + //}} RobertYu + case RF_NOTHING: + bResult = true; + break; + default: + bResult = false; + break; + } + return bResult; } /* @@ -875,76 +875,76 @@ bool bResult = true; * Return Value: None. * */ -bool RFvWriteWakeProgSyn (unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel) +bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel) { - int ii; - unsigned char byInitCount = 0; - unsigned char bySleepCount = 0; - - VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, 0); - switch (byRFType) { - case RF_AIROHA: - case RF_AL2230S: - - if (uChannel > CB_MAX_CHANNEL_24G) - return false; - - byInitCount = CB_AL2230_INIT_SEQ + 2; // Init Reg + Channel Reg (2) - bySleepCount = 0; - if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) { - return false; - } - - for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++ ) { - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230InitTable[ii]); - } - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable0[uChannel-1]); - ii ++; - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]); - break; - - //{{ RobertYu: 20050104 - // Need to check, PLLON need to be low for channel setting - case RF_AIROHA7230: - byInitCount = CB_AL7230_INIT_SEQ + 3; // Init Reg + Channel Reg (3) - bySleepCount = 0; - if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) { - return false; - } - - if (uChannel <= CB_MAX_CHANNEL_24G) - { - for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) { - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTable[ii]); - } - } - else - { - for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++ ) { - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTableAMode[ii]); - } - } - - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable0[uChannel-1]); - ii ++; - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable1[uChannel-1]); - ii ++; - MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]); - break; - //}} RobertYu - - case RF_NOTHING : - return true; - break; - - default: - return false; - break; - } - - MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (unsigned long )MAKEWORD(bySleepCount, byInitCount)); - - return true; + int ii; + unsigned char byInitCount = 0; + unsigned char bySleepCount = 0; + + VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, 0); + switch (byRFType) { + case RF_AIROHA: + case RF_AL2230S: + + if (uChannel > CB_MAX_CHANNEL_24G) + return false; + + byInitCount = CB_AL2230_INIT_SEQ + 2; // Init Reg + Channel Reg (2) + bySleepCount = 0; + if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) { + return false; + } + + for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) { + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230InitTable[ii]); + } + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable0[uChannel-1]); + ii++; + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL2230ChannelTable1[uChannel-1]); + break; + + //{{ RobertYu: 20050104 + // Need to check, PLLON need to be low for channel setting + case RF_AIROHA7230: + byInitCount = CB_AL7230_INIT_SEQ + 3; // Init Reg + Channel Reg (3) + bySleepCount = 0; + if (byInitCount > (MISCFIFO_SYNDATASIZE - bySleepCount)) { + return false; + } + + if (uChannel <= CB_MAX_CHANNEL_24G) + { + for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) { + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTable[ii]); + } + } + else + { + for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) { + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230InitTableAMode[ii]); + } + } + + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable0[uChannel-1]); + ii++; + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable1[uChannel-1]); + ii++; + MACvSetMISCFifo(dwIoBase, (unsigned short)(MISCFIFO_SYNDATA_IDX + ii), dwAL7230ChannelTable2[uChannel-1]); + break; + //}} RobertYu + + case RF_NOTHING: + return true; + break; + + default: + return false; + break; + } + + MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (unsigned long)MAKEWORD(bySleepCount, byInitCount)); + + return true; } /* @@ -960,87 +960,87 @@ bool RFvWriteWakeProgSyn (unsigned long dwIoBase, unsigned char byRFType, unsign * Return Value: true if succeeded; false if failed. * */ -bool RFbSetPower ( - PSDevice pDevice, - unsigned int uRATE, - unsigned int uCH - ) +bool RFbSetPower( + PSDevice pDevice, + unsigned int uRATE, + unsigned int uCH +) { -bool bResult = true; -unsigned char byPwr = 0; -unsigned char byDec = 0; -unsigned char byPwrdBm = 0; - - if (pDevice->dwDiagRefCount != 0) { - return true; - } - if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) { - return false; - } - - switch (uRATE) { - case RATE_1M: - case RATE_2M: - case RATE_5M: - case RATE_11M: - byPwr = pDevice->abyCCKPwrTbl[uCH]; - byPwrdBm = pDevice->abyCCKDefaultPwr[uCH]; + bool bResult = true; + unsigned char byPwr = 0; + unsigned char byDec = 0; + unsigned char byPwrdBm = 0; + + if (pDevice->dwDiagRefCount != 0) { + return true; + } + if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) { + return false; + } + + switch (uRATE) { + case RATE_1M: + case RATE_2M: + case RATE_5M: + case RATE_11M: + byPwr = pDevice->abyCCKPwrTbl[uCH]; + byPwrdBm = pDevice->abyCCKDefaultPwr[uCH]; //PLICE_DEBUG-> - //byPwr+=5; + //byPwr+=5; //PLICE_DEBUG <- //printk("Rate <11:byPwr is %d\n",byPwr); break; - case RATE_6M: - case RATE_9M: - case RATE_18M: - byPwr = pDevice->abyOFDMPwrTbl[uCH]; - if (pDevice->byRFType == RF_UW2452) { - byDec = byPwr + 14; - } else { - byDec = byPwr + 10; - } - if (byDec >= pDevice->byMaxPwrLevel) { - byDec = pDevice->byMaxPwrLevel-1; - } - if (pDevice->byRFType == RF_UW2452) { - byPwrdBm = byDec - byPwr; - byPwrdBm /= 3; - } else { - byPwrdBm = byDec - byPwr; - byPwrdBm >>= 1; - } - byPwrdBm += pDevice->abyOFDMDefaultPwr[uCH]; - byPwr = byDec; + case RATE_6M: + case RATE_9M: + case RATE_18M: + byPwr = pDevice->abyOFDMPwrTbl[uCH]; + if (pDevice->byRFType == RF_UW2452) { + byDec = byPwr + 14; + } else { + byDec = byPwr + 10; + } + if (byDec >= pDevice->byMaxPwrLevel) { + byDec = pDevice->byMaxPwrLevel-1; + } + if (pDevice->byRFType == RF_UW2452) { + byPwrdBm = byDec - byPwr; + byPwrdBm /= 3; + } else { + byPwrdBm = byDec - byPwr; + byPwrdBm >>= 1; + } + byPwrdBm += pDevice->abyOFDMDefaultPwr[uCH]; + byPwr = byDec; //PLICE_DEBUG-> - //byPwr+=5; + //byPwr+=5; //PLICE_DEBUG<- //printk("Rate <24:byPwr is %d\n",byPwr); break; - case RATE_24M: - case RATE_36M: - case RATE_48M: - case RATE_54M: - byPwr = pDevice->abyOFDMPwrTbl[uCH]; - byPwrdBm = pDevice->abyOFDMDefaultPwr[uCH]; + case RATE_24M: + case RATE_36M: + case RATE_48M: + case RATE_54M: + byPwr = pDevice->abyOFDMPwrTbl[uCH]; + byPwrdBm = pDevice->abyOFDMDefaultPwr[uCH]; //PLICE_DEBUG-> - //byPwr+=5; + //byPwr+=5; //PLICE_DEBUG<- //printk("Rate < 54:byPwr is %d\n",byPwr); break; - } + } // if (pDevice->byLocalID <= REV_ID_VT3253_B1) { - if (pDevice->byCurPwr == byPwr) { - return true; - } - bResult = RFbRawSetPower(pDevice, byPwr, uRATE); + if (pDevice->byCurPwr == byPwr) { + return true; + } + bResult = RFbRawSetPower(pDevice, byPwr, uRATE); // } - if (bResult == true) { - pDevice->byCurPwr = byPwr; - } - return bResult; + if (bResult == true) { + pDevice->byCurPwr = byPwr; + } + return bResult; } /* @@ -1057,55 +1057,55 @@ unsigned char byPwrdBm = 0; * */ -bool RFbRawSetPower ( - PSDevice pDevice, - unsigned char byPwr, - unsigned int uRATE - ) +bool RFbRawSetPower( + PSDevice pDevice, + unsigned char byPwr, + unsigned int uRATE +) { -bool bResult = true; -unsigned long dwMax7230Pwr = 0; - - if (byPwr >= pDevice->byMaxPwrLevel) { - return (false); - } - switch (pDevice->byRFType) { - - case RF_AIROHA : - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); - if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - } else { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - } - break; - - - case RF_AL2230S : - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); - if (uRATE <= RATE_11M) { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - }else { - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); - } - - break; - - case RF_AIROHA7230: - // 0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value - dwMax7230Pwr = 0x080C0B00 | ( (byPwr) << 12 ) | - (BY_AL7230_REG_LEN << 3 ) | IFREGCTL_REGW; - - bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwMax7230Pwr); - break; - - - default : - break; - } - return bResult; + bool bResult = true; + unsigned long dwMax7230Pwr = 0; + + if (byPwr >= pDevice->byMaxPwrLevel) { + return (false); + } + switch (pDevice->byRFType) { + + case RF_AIROHA: + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + if (uRATE <= RATE_11M) { + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + } else { + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + } + break; + + + case RF_AL2230S: + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwAL2230PowerTable[byPwr]); + if (uRATE <= RATE_11M) { + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + } else { + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW); + } + + break; + + case RF_AIROHA7230: + // 0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value + dwMax7230Pwr = 0x080C0B00 | ((byPwr) << 12) | + (BY_AL7230_REG_LEN << 3) | IFREGCTL_REGW; + + bResult &= IFRFbWriteEmbedded(pDevice->PortOffset, dwMax7230Pwr); + break; + + + default: + break; + } + return bResult; } /*+ @@ -1122,30 +1122,30 @@ unsigned long dwMax7230Pwr = 0; * * Return Value: none * --*/ + -*/ void -RFvRSSITodBm ( - PSDevice pDevice, - unsigned char byCurrRSSI, - long * pldBm - ) +RFvRSSITodBm( + PSDevice pDevice, + unsigned char byCurrRSSI, + long *pldBm + ) { - unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03); - long b = (byCurrRSSI & 0x3F); - long a = 0; - unsigned char abyAIROHARF[4] = {0, 18, 0, 40}; - - switch (pDevice->byRFType) { - case RF_AIROHA: - case RF_AL2230S: - case RF_AIROHA7230: //RobertYu: 20040104 - a = abyAIROHARF[byIdx]; - break; - default: - break; - } - - *pldBm = -1 * (a + b * 2); + unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03); + long b = (byCurrRSSI & 0x3F); + long a = 0; + unsigned char abyAIROHARF[4] = {0, 18, 0, 40}; + + switch (pDevice->byRFType) { + case RF_AIROHA: + case RF_AL2230S: + case RF_AIROHA7230: //RobertYu: 20040104 + a = abyAIROHARF[byIdx]; + break; + default: + break; + } + + *pldBm = -1 * (a + b * 2); } //////////////////////////////////////////////////////////////////////////////// @@ -1154,39 +1154,39 @@ RFvRSSITodBm ( // Post processing for the 11b/g and 11a. // for save time on changing Reg2,3,5,7,10,12,15 -bool RFbAL7230SelectChannelPostProcess (unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel) +bool RFbAL7230SelectChannelPostProcess(unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel) { - bool bResult; - - bResult = true; - - // if change between 11 b/g and 11a need to update the following register - // Channel Index 1~14 - - if( (byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G) ) - { - // Change from 2.4G to 5G - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15 - } - else if( (byOldChannel > CB_MAX_CHANNEL_24G) && (byNewChannel <= CB_MAX_CHANNEL_24G) ) - { - // change from 5G to 2.4G - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[2]); //Reg2 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[3]); //Reg3 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[5]); //Reg5 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[7]); //Reg7 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[10]);//Reg10 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[12]);//Reg12 - bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[15]);//Reg15 - } - - return bResult; + bool bResult; + + bResult = true; + + // if change between 11 b/g and 11a need to update the following register + // Channel Index 1~14 + + if ((byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G)) + { + // Change from 2.4G to 5G + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[2]); //Reg2 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[3]); //Reg3 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[5]); //Reg5 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[7]); //Reg7 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[10]);//Reg10 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[12]);//Reg12 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTableAMode[15]);//Reg15 + } + else if ((byOldChannel > CB_MAX_CHANNEL_24G) && (byNewChannel <= CB_MAX_CHANNEL_24G)) + { + // change from 5G to 2.4G + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[2]); //Reg2 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[3]); //Reg3 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[5]); //Reg5 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[7]); //Reg7 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[10]);//Reg10 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[12]);//Reg12 + bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[15]);//Reg15 + } + + return bResult; } diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index 1da0fdeb2e1c..e671ab0b64fa 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -77,23 +77,23 @@ bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData); bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel); -bool RFbInit ( - PSDevice pDevice - ); +bool RFbInit( + PSDevice pDevice +); bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel); bool RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH); bool RFbRawSetPower( - PSDevice pDevice, - unsigned char byPwr, - unsigned int uRATE - ); + PSDevice pDevice, + unsigned char byPwr, + unsigned int uRATE +); void RFvRSSITodBm( - PSDevice pDevice, - unsigned char byCurrRSSI, - long *pldBm - ); + PSDevice pDevice, + unsigned char byCurrRSSI, + long *pldBm +); //{{ RobertYu: 20050104 bool RFbAL7230SelectChannelPostProcess(unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel); -- cgit From 547f1cffdc77e2d1316022f9fec9a0af5fff1a6a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:01 -0700 Subject: staging:vt6655:rxtx: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 5652 ++++++++++++++++++++--------------------- drivers/staging/vt6655/rxtx.h | 52 +- 2 files changed, 2852 insertions(+), 2852 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index d66854f5b304..ed33e96d0208 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -69,7 +69,7 @@ /*--------------------- Static Variables --------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; #define PLICE_DEBUG @@ -81,18 +81,18 @@ static int msglevel =MSG_LEVEL_INFO; // packet size >= 256 -> direct send const unsigned short wTimeStampOff[2][MAX_RATE] = { - {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble - {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble - }; + {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble + {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble +}; const unsigned short wFB_Opt0[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 - {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 - }; + {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 + {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 +}; const unsigned short wFB_Opt1[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 - {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 - }; + {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 + {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 +}; #define RTSDUR_BB 0 @@ -117,81 +117,81 @@ const unsigned short wFB_Opt1[2][5] = { static void s_vFillTxKey( - PSDevice pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR - ); + PSDevice pDevice, + unsigned char *pbyBuf, + unsigned char *pbyIVHead, + PSKeyItem pTransmitKey, + unsigned char *pbyHdrBuf, + unsigned short wPayloadLen, + unsigned char *pMICHDR +); static void s_vFillRTSHead( - PSDevice pDevice, - unsigned char byPktType, - void * pvRTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - PSEthernetHeader psEthHeader, - unsigned short wCurrentRate, - unsigned char byFBOption - ); + PSDevice pDevice, + unsigned char byPktType, + void *pvRTS, + unsigned int cbFrameLength, + bool bNeedAck, + bool bDisCRC, + PSEthernetHeader psEthHeader, + unsigned short wCurrentRate, + unsigned char byFBOption +); static void s_vGenerateTxParameter( - PSDevice pDevice, - unsigned char byPktType, - void * pTxBufHead, - void * pvRrvTime, - void * pvRTS, - void * pvCTS, - unsigned int cbFrameSize, - bool bNeedACK, - unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, - unsigned short wCurrentRate - ); + PSDevice pDevice, + unsigned char byPktType, + void *pTxBufHead, + void *pvRrvTime, + void *pvRTS, + void *pvCTS, + unsigned int cbFrameSize, + bool bNeedACK, + unsigned int uDMAIdx, + PSEthernetHeader psEthHeader, + unsigned short wCurrentRate +); static void s_vFillFragParameter( - PSDevice pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void * pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount - ); + PSDevice pDevice, + unsigned char *pbyBuffer, + unsigned int uTxType, + void *pvtdCurr, + unsigned short wFragType, + unsigned int cbReqCount +); static unsigned int s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, - unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum); + unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt, + PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum); static unsigned int -s_uFillDataHead ( - PSDevice pDevice, - unsigned char byPktType, - void * pTxDataHead, - unsigned int cbFrameLength, - unsigned int uDMAIdx, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption, - unsigned short wCurrentRate - ); +s_uFillDataHead( + PSDevice pDevice, + unsigned char byPktType, + void *pTxDataHead, + unsigned int cbFrameLength, + unsigned int uDMAIdx, + bool bNeedAck, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, + unsigned char byFBOption, + unsigned short wCurrentRate +); /*--------------------- Export Variables --------------------------*/ @@ -200,408 +200,408 @@ s_uFillDataHead ( static void -s_vFillTxKey ( - PSDevice pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR - ) +s_vFillTxKey( + PSDevice pDevice, + unsigned char *pbyBuf, + unsigned char *pbyIVHead, + PSKeyItem pTransmitKey, + unsigned char *pbyHdrBuf, + unsigned short wPayloadLen, + unsigned char *pMICHDR +) { - unsigned long *pdwIV = (unsigned long *) pbyIVHead; - unsigned long *pdwExtIV = (unsigned long *) ((unsigned char *)pbyIVHead+4); - unsigned short wValue; - PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; - unsigned long dwRevIVCounter; - unsigned char byKeyIndex = 0; - - - - //Fill TXKEY - if (pTransmitKey == NULL) - return; - - dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter); - *pdwIV = pDevice->dwIVCounter; - byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){ - memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } else { - memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } - memcpy(pDevice->abyPRNG, pbyBuf, 16); - } - // Append IV after Mac Header - *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (unsigned long)byKeyIndex << 30; - *pdwIV = cpu_to_le32(*pdwIV); - pDevice->dwIVCounter++; - if (pDevice->dwIVCounter > WEP_IV_MASK) { - pDevice->dwIVCounter = 0; - } - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) { - pTransmitKey->dwTSC47_16++; - } - TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - memcpy(pbyBuf, pDevice->abyPRNG, 16); - // Make IV - memcpy(pdwIV, pDevice->abyPRNG, 3); - - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - // Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); - - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) { - pTransmitKey->dwTSC47_16++; - } - memcpy(pbyBuf, pTransmitKey->abyKey, 16); - - // Make IV - *pdwIV = 0; - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0)); - //Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - //Fill MICHDR0 - *pMICHDR = 0x59; - *((unsigned char *)(pMICHDR+1)) = 0; // TxPriority - memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6); - *((unsigned char *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); - *((unsigned char *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); - *((unsigned char *)(pMICHDR+14)) = HIBYTE(wPayloadLen); - *((unsigned char *)(pMICHDR+15)) = LOBYTE(wPayloadLen); - - //Fill MICHDR1 - *((unsigned char *)(pMICHDR+16)) = 0; // HLEN[15:8] - if (pDevice->bLongHeader) { - *((unsigned char *)(pMICHDR+17)) = 28; // HLEN[7:0] - } else { - *((unsigned char *)(pMICHDR+17)) = 22; // HLEN[7:0] - } - wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F); - memcpy(pMICHDR+18, (unsigned char *)&wValue, 2); // MSKFRACTL - memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6); - memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6); - - //Fill MICHDR2 - memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6); - wValue = pMACHeader->wSeqCtl; - wValue &= 0x000F; - wValue = cpu_to_le16(wValue); - memcpy(pMICHDR+38, (unsigned char *)&wValue, 2); // MSKSEQCTL - if (pDevice->bLongHeader) { - memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6); - } - } + unsigned long *pdwIV = (unsigned long *)pbyIVHead; + unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4); + unsigned short wValue; + PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; + unsigned long dwRevIVCounter; + unsigned char byKeyIndex = 0; + + + + //Fill TXKEY + if (pTransmitKey == NULL) + return; + + dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter); + *pdwIV = pDevice->dwIVCounter; + byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; + + if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { + if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { + memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3); + memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); + } else { + memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3); + memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); + if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { + memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3); + memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); + } + memcpy(pDevice->abyPRNG, pbyBuf, 16); + } + // Append IV after Mac Header + *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 + *pdwIV |= (unsigned long)byKeyIndex << 30; + *pdwIV = cpu_to_le32(*pdwIV); + pDevice->dwIVCounter++; + if (pDevice->dwIVCounter > WEP_IV_MASK) { + pDevice->dwIVCounter = 0; + } + } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { + pTransmitKey->wTSC15_0++; + if (pTransmitKey->wTSC15_0 == 0) { + pTransmitKey->dwTSC47_16++; + } + TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, + pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); + memcpy(pbyBuf, pDevice->abyPRNG, 16); + // Make IV + memcpy(pdwIV, pDevice->abyPRNG, 3); + + *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV + // Append IV&ExtIV after Mac Header + *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); + + } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { + pTransmitKey->wTSC15_0++; + if (pTransmitKey->wTSC15_0 == 0) { + pTransmitKey->dwTSC47_16++; + } + memcpy(pbyBuf, pTransmitKey->abyKey, 16); + + // Make IV + *pdwIV = 0; + *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV + *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0)); + //Append IV&ExtIV after Mac Header + *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); + + //Fill MICHDR0 + *pMICHDR = 0x59; + *((unsigned char *)(pMICHDR+1)) = 0; // TxPriority + memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6); + *((unsigned char *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); + *((unsigned char *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); + *((unsigned char *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); + *((unsigned char *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); + *((unsigned char *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); + *((unsigned char *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); + *((unsigned char *)(pMICHDR+14)) = HIBYTE(wPayloadLen); + *((unsigned char *)(pMICHDR+15)) = LOBYTE(wPayloadLen); + + //Fill MICHDR1 + *((unsigned char *)(pMICHDR+16)) = 0; // HLEN[15:8] + if (pDevice->bLongHeader) { + *((unsigned char *)(pMICHDR+17)) = 28; // HLEN[7:0] + } else { + *((unsigned char *)(pMICHDR+17)) = 22; // HLEN[7:0] + } + wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F); + memcpy(pMICHDR+18, (unsigned char *)&wValue, 2); // MSKFRACTL + memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6); + memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6); + + //Fill MICHDR2 + memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6); + wValue = pMACHeader->wSeqCtl; + wValue &= 0x000F; + wValue = cpu_to_le16(wValue); + memcpy(pMICHDR+38, (unsigned char *)&wValue, 2); // MSKSEQCTL + if (pDevice->bLongHeader) { + memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6); + } + } } static void -s_vSWencryption ( - PSDevice pDevice, - PSKeyItem pTransmitKey, - unsigned char *pbyPayloadHead, - unsigned short wPayloadSize - ) +s_vSWencryption( + PSDevice pDevice, + PSKeyItem pTransmitKey, + unsigned char *pbyPayloadHead, + unsigned short wPayloadSize +) { - unsigned int cbICVlen = 4; - unsigned long dwICV = 0xFFFFFFFFL; - unsigned long *pdwICV; - - if (pTransmitKey == NULL) - return; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - //======================================================================= - // Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - //======================================================================= - //Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } + unsigned int cbICVlen = 4; + unsigned long dwICV = 0xFFFFFFFFL; + unsigned long *pdwICV; + + if (pTransmitKey == NULL) + return; + + if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { + //======================================================================= + // Append ICV after payload + dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) + pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); + // finally, we must invert dwCRC to get the correct answer + *pdwICV = cpu_to_le32(~dwICV); + // RC4 encryption + rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); + rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); + //======================================================================= + } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { + //======================================================================= + //Append ICV after payload + dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) + pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); + // finally, we must invert dwCRC to get the correct answer + *pdwICV = cpu_to_le32(~dwICV); + // RC4 encryption + rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); + rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); + //======================================================================= + } } /*byPktType : PK_TYPE_11A 0 - PK_TYPE_11B 1 - PK_TYPE_11GB 2 - PK_TYPE_11GA 3 + PK_TYPE_11B 1 + PK_TYPE_11GB 2 + PK_TYPE_11GA 3 */ static unsigned int -s_uGetTxRsvTime ( - PSDevice pDevice, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate, - bool bNeedAck - ) +s_uGetTxRsvTime( + PSDevice pDevice, + unsigned char byPktType, + unsigned int cbFrameLength, + unsigned short wRate, + bool bNeedAck +) { - unsigned int uDataTime, uAckTime; + unsigned int uDataTime, uAckTime; - uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate); + uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate); #ifdef PLICE_DEBUG //printk("s_uGetTxRsvTime is %d\n",uDataTime); #endif - if (byPktType == PK_TYPE_11B) {//llb,CCK mode - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate); - } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate); - } - - if (bNeedAck) { - return (uDataTime + pDevice->uSIFS + uAckTime); - } - else { - return uDataTime; - } + if (byPktType == PK_TYPE_11B) {//llb,CCK mode + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate); + } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate); + } + + if (bNeedAck) { + return (uDataTime + pDevice->uSIFS + uAckTime); + } + else { + return uDataTime; + } } //byFreqType: 0=>5GHZ 1=>2.4GHZ static unsigned int -s_uGetRTSCTSRsvTime ( - PSDevice pDevice, - unsigned char byRTSRsvType, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wCurrentRate - ) +s_uGetRTSCTSRsvTime( + PSDevice pDevice, + unsigned char byRTSRsvType, + unsigned char byPktType, + unsigned int cbFrameLength, + unsigned short wCurrentRate +) { - unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; - - uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0; - - - uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate); - if (byRTSRsvType == 0) { //RTSTxRrvTime_bb - uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); - uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - } - else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ - uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - } - else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa - uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate); - uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - } - else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS; - return uRrvTime; - } - - //RTSRrvTime - uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS; - return uRrvTime; + unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; + + uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0; + + + uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate); + if (byRTSRsvType == 0) { //RTSTxRrvTime_bb + uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); + uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + } + else if (byRTSRsvType == 1) { //RTSTxRrvTime_ba, only in 2.4GHZ + uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate); + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + } + else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa + uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate); + uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + } + else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS; + return uRrvTime; + } + + //RTSRrvTime + uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS; + return uRrvTime; } //byFreqType 0: 5GHz, 1:2.4Ghz static unsigned int -s_uGetDataDuration ( - PSDevice pDevice, - unsigned char byDurType, - unsigned int cbFrameLength, - unsigned char byPktType, - unsigned short wRate, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption - ) +s_uGetDataDuration( + PSDevice pDevice, + unsigned char byDurType, + unsigned int cbFrameLength, + unsigned char byPktType, + unsigned short wRate, + bool bNeedAck, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, + unsigned char byFBOption +) { - bool bLastFrag = 0; - unsigned int uAckTime =0, uNextPktTime = 0; - - - - if (uFragIdx == (uMACfragNum-1)) { - bLastFrag = 1; - } - - - switch (byDurType) { - - case DATADUR_B: //DATADUR_B - if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag - if (bNeedAck) { - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - return (pDevice->uSIFS + uAckTime); - } else { - return 0; - } - } - else {//First Frag or Mid Frag - if (uFragIdx == (uMACfragNum-2)) { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - } - if (bNeedAck) { - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - return (pDevice->uSIFS + uAckTime + uNextPktTime); - } else { - return (pDevice->uSIFS + uNextPktTime); - } - } - break; - - case DATADUR_A: //DATADUR_A - if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime); - } else { - return 0; - } - } - else {//First Frag or Mid Frag - if(uFragIdx == (uMACfragNum-2)){ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - } - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime + uNextPktTime); - } else { - return (pDevice->uSIFS + uNextPktTime); - } - } - break; - - case DATADUR_A_F0: //DATADUR_A_F0 - if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime); - } else { - return 0; - } - } - else { //First Frag or Mid Frag - if (byFBOption == AUTO_FB_0) { - if (wRate < RATE_18M) - wRate = RATE_18M; - else if (wRate > RATE_54M) - wRate = RATE_54M; - - if(uFragIdx == (uMACfragNum-2)){ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); - } - } else { // (byFBOption == AUTO_FB_1) - if (wRate < RATE_18M) - wRate = RATE_18M; - else if (wRate > RATE_54M) - wRate = RATE_54M; - - if(uFragIdx == (uMACfragNum-2)){ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); - } - } - - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime + uNextPktTime); - } else { - return (pDevice->uSIFS + uNextPktTime); - } - } - break; - - case DATADUR_A_F1: //DATADUR_A_F1 - if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime); - } else { - return 0; - } - } - else { //First Frag or Mid Frag - if (byFBOption == AUTO_FB_0) { - if (wRate < RATE_18M) - wRate = RATE_18M; - else if (wRate > RATE_54M) - wRate = RATE_54M; - - if(uFragIdx == (uMACfragNum-2)){ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); - } - - } else { // (byFBOption == AUTO_FB_1) - if (wRate < RATE_18M) - wRate = RATE_18M; - else if (wRate > RATE_54M) - wRate = RATE_54M; - - if(uFragIdx == (uMACfragNum-2)){ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); - } else { - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); - } - } - if(bNeedAck){ - uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - return (pDevice->uSIFS + uAckTime + uNextPktTime); - } else { - return (pDevice->uSIFS + uNextPktTime); - } - } - break; - - default: - break; - } + bool bLastFrag = 0; + unsigned int uAckTime = 0, uNextPktTime = 0; + + + + if (uFragIdx == (uMACfragNum-1)) { + bLastFrag = 1; + } + + + switch (byDurType) { + + case DATADUR_B: //DATADUR_B + if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + return (pDevice->uSIFS + uAckTime); + } else { + return 0; + } + } + else {//First Frag or Mid Frag + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + } + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + return (pDevice->uSIFS + uAckTime + uNextPktTime); + } else { + return (pDevice->uSIFS + uNextPktTime); + } + } + break; + + case DATADUR_A: //DATADUR_A + if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime); + } else { + return 0; + } + } + else {//First Frag or Mid Frag + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + } + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime + uNextPktTime); + } else { + return (pDevice->uSIFS + uNextPktTime); + } + } + break; + + case DATADUR_A_F0: //DATADUR_A_F0 + if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime); + } else { + return 0; + } + } + else { //First Frag or Mid Frag + if (byFBOption == AUTO_FB_0) { + if (wRate < RATE_18M) + wRate = RATE_18M; + else if (wRate > RATE_54M) + wRate = RATE_54M; + + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + } + } else { // (byFBOption == AUTO_FB_1) + if (wRate < RATE_18M) + wRate = RATE_18M; + else if (wRate > RATE_54M) + wRate = RATE_54M; + + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + } + } + + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime + uNextPktTime); + } else { + return (pDevice->uSIFS + uNextPktTime); + } + } + break; + + case DATADUR_A_F1: //DATADUR_A_F1 + if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime); + } else { + return 0; + } + } + else { //First Frag or Mid Frag + if (byFBOption == AUTO_FB_0) { + if (wRate < RATE_18M) + wRate = RATE_18M; + else if (wRate > RATE_54M) + wRate = RATE_54M; + + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + } + + } else { // (byFBOption == AUTO_FB_1) + if (wRate < RATE_18M) + wRate = RATE_18M; + else if (wRate > RATE_54M) + wRate = RATE_54M; + + if (uFragIdx == (uMACfragNum-2)) { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + } else { + uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + } + } + if (bNeedAck) { + uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + return (pDevice->uSIFS + uAckTime + uNextPktTime); + } else { + return (pDevice->uSIFS + uNextPktTime); + } + } + break; + + default: + break; + } ASSERT(false); return 0; @@ -611,97 +611,97 @@ s_uGetDataDuration ( //byFreqType: 0=>5GHZ 1=>2.4GHZ static unsigned int -s_uGetRTSCTSDuration ( - PSDevice pDevice, - unsigned char byDurType, - unsigned int cbFrameLength, - unsigned char byPktType, - unsigned short wRate, - bool bNeedAck, - unsigned char byFBOption - ) +s_uGetRTSCTSDuration( + PSDevice pDevice, + unsigned char byDurType, + unsigned int cbFrameLength, + unsigned char byPktType, + unsigned short wRate, + bool bNeedAck, + unsigned char byFBOption +) { - unsigned int uCTSTime = 0, uDurTime = 0; - - - switch (byDurType) { - - case RTSDUR_BB: //RTSDuration_bb - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_BA: //RTSDuration_ba - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_AA: //RTSDuration_aa - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case CTSDUR_BA: //CTSDuration_ba - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_BA_F0: //RTSDuration_ba_f0 - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); - } - break; - - case RTSDUR_AA_F0: //RTSDuration_aa_f0 - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); - } - break; - - case RTSDUR_BA_F1: //RTSDuration_ba_f1 - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); - } - break; - - case RTSDUR_AA_F1: //RTSDuration_aa_f1 - uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); - } - break; - - case CTSDUR_BA_F0: //CTSDuration_ba_f0 - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); - } - break; - - case CTSDUR_BA_F1: //CTSDuration_ba_f1 - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); - } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) { - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); - } - break; - - default: - break; - } - - return uDurTime; + unsigned int uCTSTime = 0, uDurTime = 0; + + + switch (byDurType) { + + case RTSDUR_BB: //RTSDuration_bb + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + break; + + case RTSDUR_BA: //RTSDuration_ba + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + break; + + case RTSDUR_AA: //RTSDuration_aa + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + break; + + case CTSDUR_BA: //CTSDuration_ba + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); + break; + + case RTSDUR_BA_F0: //RTSDuration_ba_f0 + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + } + break; + + case RTSDUR_AA_F0: //RTSDuration_aa_f0 + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + } + break; + + case RTSDUR_BA_F1: //RTSDuration_ba_f1 + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + } + break; + + case RTSDUR_AA_F1: //RTSDuration_aa_f1 + uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + } + break; + + case CTSDUR_BA_F0: //CTSDuration_ba_f0 + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck); + } + break; + + case CTSDUR_BA_F1: //CTSDuration_ba_f1 + if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck); + } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) { + uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck); + } + break; + + default: + break; + } + + return uDurTime; } @@ -709,405 +709,405 @@ s_uGetRTSCTSDuration ( static unsigned int -s_uFillDataHead ( - PSDevice pDevice, - unsigned char byPktType, - void * pTxDataHead, - unsigned int cbFrameLength, - unsigned int uDMAIdx, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption, - unsigned short wCurrentRate - ) +s_uFillDataHead( + PSDevice pDevice, + unsigned char byPktType, + void *pTxDataHead, + unsigned int cbFrameLength, + unsigned int uDMAIdx, + bool bNeedAck, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, + unsigned char byFBOption, + unsigned short wCurrentRate +) { - unsigned short wLen = 0x0000; - - if (pTxDataHead == NULL) { - return 0; - } - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (byFBOption == AUTO_FB_NONE) { - PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) - ); - pBuf->wTransmitLength_a = cpu_to_le16(wLen); - BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - //Get Duration and TimeStamp - pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); //1: 2.4GHz - pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, - PK_TYPE_11B, pDevice->byTopCCKBasicRate, - bNeedAck, uFragIdx, cbLastFragmentSize, - uMACfragNum, byFBOption)); //1: 2.4 - - pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]); - - return (pBuf->wDuration_a); - } else { - // Auto Fallback - PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) - ); - pBuf->wTransmitLength_a = cpu_to_le16(wLen); - BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - //Get Duration and TimeStamp - pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz - pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, - pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz - pBuf->wDuration_a_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz - pBuf->wDuration_a_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz - - pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]); - - return (pBuf->wDuration_a); - } //if (byFBOption == AUTO_FB_NONE) - } - else if (byPktType == PK_TYPE_11A) { - if ((byFBOption != AUTO_FB_NONE)) { - // Auto Fallback - PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration and TimeStampOff - - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz - pBuf->wDuration_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz - pBuf->wDuration_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz - pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - return (pBuf->wDuration); - } else { - PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration and TimeStampOff - - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - - pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - return (pBuf->wDuration); - } - } - else { - PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration and TimeStampOff - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - return (pBuf->wDuration); - } - return 0; + unsigned short wLen = 0x0000; + + if (pTxDataHead == NULL) { + return 0; + } + + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + if (byFBOption == AUTO_FB_NONE) { + PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) +); + pBuf->wTransmitLength_a = cpu_to_le16(wLen); + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + //Get Duration and TimeStamp + pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, + byPktType, wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); //1: 2.4GHz + pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, + PK_TYPE_11B, pDevice->byTopCCKBasicRate, + bNeedAck, uFragIdx, cbLastFragmentSize, + uMACfragNum, byFBOption)); //1: 2.4 + + pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]); + + return (pBuf->wDuration_a); + } else { + // Auto Fallback + PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) +); + pBuf->wTransmitLength_a = cpu_to_le16(wLen); + BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + //Get Duration and TimeStamp + pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz + pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, + pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz + pBuf->wDuration_a_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz + pBuf->wDuration_a_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz + + pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]); + + return (pBuf->wDuration_a); + } //if (byFBOption == AUTO_FB_NONE) + } + else if (byPktType == PK_TYPE_11A) { + if ((byFBOption != AUTO_FB_NONE)) { + // Auto Fallback + PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration and TimeStampOff + + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz + pBuf->wDuration_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz + pBuf->wDuration_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz + pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + return (pBuf->wDuration); + } else { + PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration and TimeStampOff + + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); + + pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + return (pBuf->wDuration); + } + } + else { + PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration and TimeStampOff + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, + wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); + pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + return (pBuf->wDuration); + } + return 0; } static void -s_vFillRTSHead ( - PSDevice pDevice, - unsigned char byPktType, - void * pvRTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - PSEthernetHeader psEthHeader, - unsigned short wCurrentRate, - unsigned char byFBOption - ) +s_vFillRTSHead( + PSDevice pDevice, + unsigned char byPktType, + void *pvRTS, + unsigned int cbFrameLength, + bool bNeedAck, + bool bDisCRC, + PSEthernetHeader psEthHeader, + unsigned short wCurrentRate, + unsigned char byFBOption +) { - unsigned int uRTSFrameLen = 20; - unsigned short wLen = 0x0000; - - if (pvRTS == NULL) - return; - - if (bDisCRC) { - // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame, - // in this case we need to decrease its length by 4. - uRTSFrameLen -= 4; - } - - // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account. - // Otherwise, we need to modify codes for them. - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (byFBOption == AUTO_FB_NONE) { - PSRTS_g pBuf = (PSRTS_g)pvRTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) - ); - pBuf->wTransmitLength_a = cpu_to_le16(wLen); - //Get Duration - pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData - pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData - pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data - - pBuf->Data.wDurationID = pBuf->wDuration_aa; - //Get RTS Frame body - pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - } - } - else { - PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) - ); - pBuf->wTransmitLength_a = cpu_to_le16(wLen); - - //Get Duration - pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData - pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData - pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData - pBuf->wRTSDuration_ba_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_aa_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_ba_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData - pBuf->wRTSDuration_aa_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData - pBuf->Data.wDurationID = pBuf->wDuration_aa; - //Get RTS Frame body - pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - } - - } // if (byFBOption == AUTO_FB_NONE) - } - else if (byPktType == PK_TYPE_11A) { - if (byFBOption == AUTO_FB_NONE) { - PSRTS_ab pBuf = (PSRTS_ab)pvRTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData - pBuf->Data.wDurationID = pBuf->wDuration; - //Get RTS Frame body - pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - } - - } - else { - PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData - pBuf->wRTSDuration_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData - pBuf->wRTSDuration_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0: - pBuf->Data.wDurationID = pBuf->wDuration; - //Get RTS Frame body - pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - } - } - } - else if (byPktType == PK_TYPE_11B) { - PSRTS_ab pBuf = (PSRTS_ab)pvRTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) - ); - pBuf->wTransmitLength = cpu_to_le16(wLen); - //Get Duration - pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData - pBuf->Data.wDurationID = pBuf->wDuration; - //Get RTS Frame body - pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - } - } + unsigned int uRTSFrameLen = 20; + unsigned short wLen = 0x0000; + + if (pvRTS == NULL) + return; + + if (bDisCRC) { + // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame, + // in this case we need to decrease its length by 4. + uRTSFrameLen -= 4; + } + + // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account. + // Otherwise, we need to modify codes for them. + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + if (byFBOption == AUTO_FB_NONE) { + PSRTS_g pBuf = (PSRTS_g)pvRTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) +); + pBuf->wTransmitLength_a = cpu_to_le16(wLen); + //Get Duration + pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData + pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + + pBuf->Data.wDurationID = pBuf->wDuration_aa; + //Get RTS Frame body + pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + } + } + else { + PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a) +); + pBuf->wTransmitLength_a = cpu_to_le16(wLen); + + //Get Duration + pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData + pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData + pBuf->wRTSDuration_ba_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_aa_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_ba_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData + pBuf->wRTSDuration_aa_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData + pBuf->Data.wDurationID = pBuf->wDuration_aa; + //Get RTS Frame body + pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + } + + } // if (byFBOption == AUTO_FB_NONE) + } + else if (byPktType == PK_TYPE_11A) { + if (byFBOption == AUTO_FB_NONE) { + PSRTS_ab pBuf = (PSRTS_ab)pvRTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData + pBuf->Data.wDurationID = pBuf->wDuration; + //Get RTS Frame body + pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + } + + } + else { + PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData + pBuf->wRTSDuration_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData + pBuf->wRTSDuration_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0: + pBuf->Data.wDurationID = pBuf->wDuration; + //Get RTS Frame body + pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + } + } + } + else if (byPktType == PK_TYPE_11B) { + PSRTS_ab pBuf = (PSRTS_ab)pvRTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField) +); + pBuf->wTransmitLength = cpu_to_le16(wLen); + //Get Duration + pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData + pBuf->Data.wDurationID = pBuf->wDuration; + //Get RTS Frame body + pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 + + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + } + } } static void -s_vFillCTSHead ( - PSDevice pDevice, - unsigned int uDMAIdx, - unsigned char byPktType, - void * pvCTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - unsigned short wCurrentRate, - unsigned char byFBOption - ) +s_vFillCTSHead( + PSDevice pDevice, + unsigned int uDMAIdx, + unsigned char byPktType, + void *pvCTS, + unsigned int cbFrameLength, + bool bNeedAck, + bool bDisCRC, + unsigned short wCurrentRate, + unsigned char byFBOption +) { - unsigned int uCTSFrameLen = 14; - unsigned short wLen = 0x0000; - - if (pvCTS == NULL) { - return; - } - - if (bDisCRC) { - // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame, - // in this case we need to decrease its length by 4. - uCTSFrameLen -= 4; - } - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) { - // Auto Fall back - PSCTS_FB pBuf = (PSCTS_FB)pvCTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - - - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - - pBuf->wDuration_ba = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data - pBuf->wDuration_ba += pDevice->wCTSDuration; - pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); - //Get CTSDuration_ba_f0 - pBuf->wCTSDuration_ba_f0 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data - pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration; - pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0); - //Get CTSDuration_ba_f1 - pBuf->wCTSDuration_ba_f1 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data - pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration; - pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1); - //Get CTS Frame body - pBuf->Data.wDurationID = pBuf->wDuration_ba; - pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 - pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); - - } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) - PSCTS pBuf = (PSCTS)pvCTS; - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, - (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) - ); - pBuf->wTransmitLength_b = cpu_to_le16(wLen); - //Get CTSDuration_ba - pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data - pBuf->wDuration_ba += pDevice->wCTSDuration; - pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); - - //Get CTS Frame body - pBuf->Data.wDurationID = pBuf->wDuration_ba; - pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 - pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); - } - } + unsigned int uCTSFrameLen = 14; + unsigned short wLen = 0x0000; + + if (pvCTS == NULL) { + return; + } + + if (bDisCRC) { + // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame, + // in this case we need to decrease its length by 4. + uCTSFrameLen -= 4; + } + + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) { + // Auto Fall back + PSCTS_FB pBuf = (PSCTS_FB)pvCTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + + + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + + pBuf->wDuration_ba = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wDuration_ba += pDevice->wCTSDuration; + pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); + //Get CTSDuration_ba_f0 + pBuf->wCTSDuration_ba_f0 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration; + pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0); + //Get CTSDuration_ba_f1 + pBuf->wCTSDuration_ba_f1 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration; + pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1); + //Get CTS Frame body + pBuf->Data.wDurationID = pBuf->wDuration_ba; + pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 + pBuf->Data.wReserved = 0x0000; + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); + + } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) + PSCTS pBuf = (PSCTS)pvCTS; + //Get SignalField,ServiceField,Length + BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, + (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b) +); + pBuf->wTransmitLength_b = cpu_to_le16(wLen); + //Get CTSDuration_ba + pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data + pBuf->wDuration_ba += pDevice->wCTSDuration; + pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba); + + //Get CTS Frame body + pBuf->Data.wDurationID = pBuf->wDuration_ba; + pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 + pBuf->Data.wReserved = 0x0000; + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); + } + } } @@ -1136,1046 +1136,1046 @@ s_vFillCTSHead ( * * Return Value: none * --*/ + -*/ // unsigned int cbFrameSize,//Hdr+Payload+FCS static void -s_vGenerateTxParameter ( - PSDevice pDevice, - unsigned char byPktType, - void * pTxBufHead, - void * pvRrvTime, - void * pvRTS, - void * pvCTS, - unsigned int cbFrameSize, - bool bNeedACK, - unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, - unsigned short wCurrentRate - ) +s_vGenerateTxParameter( + PSDevice pDevice, + unsigned char byPktType, + void *pTxBufHead, + void *pvRrvTime, + void *pvRTS, + void *pvCTS, + unsigned int cbFrameSize, + bool bNeedACK, + unsigned int uDMAIdx, + PSEthernetHeader psEthHeader, + unsigned short wCurrentRate +) { - unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 - unsigned short wFifoCtl; - bool bDisCRC = false; - unsigned char byFBOption = AUTO_FB_NONE; + unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 + unsigned short wFifoCtl; + bool bDisCRC = false; + unsigned char byFBOption = AUTO_FB_NONE; // unsigned short wCurrentRate = pDevice->wCurrentRate; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n"); - PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead; - pFifoHead->wReserved = wCurrentRate; - wFifoCtl = pFifoHead->wFIFOCtl; - - if (wFifoCtl & FIFOCTL_CRCDIS) { - bDisCRC = true; - } - - if (wFifoCtl & FIFOCTL_AUTO_FB_0) { - byFBOption = AUTO_FB_0; - } - else if (wFifoCtl & FIFOCTL_AUTO_FB_1) { - byFBOption = AUTO_FB_1; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - - if (pvRTS != NULL) { //RTS_need - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime; - pBuf->wRTSTxRrvTime_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz - pBuf->wRTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz - pBuf->wRTSTxRrvTime_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz - pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM - pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK - } - //Fill RTS - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } - else {//RTS_needless, PCF mode - - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime; - pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM - pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK - pBuf->wCTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz - } - - - //Fill CTS - s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption); - } - } - else if (byPktType == PK_TYPE_11A) { - - if (pvRTS != NULL) {//RTS_need, non PCF mode - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz - pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM - } - //Fill RTS - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } - else if (pvRTS == NULL) {//RTS_needless, non PCF mode - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM - } - } - } - else if (byPktType == PK_TYPE_11B) { - - if ((pvRTS != NULL)) {//RTS_need, non PCF mode - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz - pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK - } - //Fill RTS - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } - else { //RTS_needless, non PCF mode - //Fill RsvTime - if (pvRrvTime) { - PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; - pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK - } - } - } - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n"); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vGenerateTxParameter...\n"); + PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead; + pFifoHead->wReserved = wCurrentRate; + wFifoCtl = pFifoHead->wFIFOCtl; + + if (wFifoCtl & FIFOCTL_CRCDIS) { + bDisCRC = true; + } + + if (wFifoCtl & FIFOCTL_AUTO_FB_0) { + byFBOption = AUTO_FB_0; + } + else if (wFifoCtl & FIFOCTL_AUTO_FB_1) { + byFBOption = AUTO_FB_1; + } + + if (pDevice->bLongHeader) + cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; + + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + + if (pvRTS != NULL) { //RTS_need + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime; + pBuf->wRTSTxRrvTime_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz + pBuf->wRTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz + pBuf->wRTSTxRrvTime_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz + pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM + pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK + } + //Fill RTS + s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); + } + else {//RTS_needless, PCF mode + + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime; + pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM + pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK + pBuf->wCTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz + } + + + //Fill CTS + s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption); + } + } + else if (byPktType == PK_TYPE_11A) { + + if (pvRTS != NULL) {//RTS_need, non PCF mode + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; + pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz + pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM + } + //Fill RTS + s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); + } + else if (pvRTS == NULL) {//RTS_needless, non PCF mode + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; + pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM + } + } + } + else if (byPktType == PK_TYPE_11B) { + + if ((pvRTS != NULL)) {//RTS_need, non PCF mode + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; + pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz + pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK + } + //Fill RTS + s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); + } + else { //RTS_needless, non PCF mode + //Fill RsvTime + if (pvRrvTime) { + PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime; + pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK + } + } + } + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vGenerateTxParameter END.\n"); } /* - unsigned char *pbyBuffer,//point to pTxBufHead - unsigned short wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last - unsigned int cbFragmentSize,//Hdr+payoad+FCS + unsigned char *pbyBuffer,//point to pTxBufHead + unsigned short wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last + unsigned int cbFragmentSize,//Hdr+payoad+FCS */ static void s_vFillFragParameter( - PSDevice pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void * pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount - ) + PSDevice pDevice, + unsigned char *pbyBuffer, + unsigned int uTxType, + void *pvtdCurr, + unsigned short wFragType, + unsigned int cbReqCount +) { - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter...\n"); - - if (uTxType == TYPE_SYNCDMA) { - //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); - PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr; - - //Set FIFOCtl & TimeStamp in TxSyncDesc - ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl; - ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - } - else { - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } - } - else { - //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); - PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - } - else { - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } - } - - pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001 - - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n"); + PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vFillFragParameter...\n"); + + if (uTxType == TYPE_SYNCDMA) { + //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); + PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr; + + //Set FIFOCtl & TimeStamp in TxSyncDesc + ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl; + ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp; + //Set TSR1 & ReqCount in TxDescHead + ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + } + else { + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); + } + } + else { + //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx); + PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr; + //Set TSR1 & ReqCount in TxDescHead + ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + } + else { + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); + } + } + + pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001 + + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vFillFragParameter END\n"); } static unsigned int s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, - unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum) + unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt, + PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum) { - unsigned int cbMACHdLen; - unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbLastFragPayloadSize; - unsigned int uFragIdx; - unsigned char *pbyPayloadHead; - unsigned char *pbyIVHead; - unsigned char *pbyMacHdr; - unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last - unsigned int uDuration; - unsigned char *pbyBuffer; + unsigned int cbMACHdLen; + unsigned int cbFrameSize; + unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS + unsigned int cbFragPayloadSize; + unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS + unsigned int cbLastFragPayloadSize; + unsigned int uFragIdx; + unsigned char *pbyPayloadHead; + unsigned char *pbyIVHead; + unsigned char *pbyMacHdr; + unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last + unsigned int uDuration; + unsigned char *pbyBuffer; // unsigned int uKeyEntryIdx = NUM_KEY_ENTRY+1; // unsigned char byKeySel = 0xFF; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int cb802_1_H_len = 0; - unsigned int uLength = 0; - unsigned int uTmpLen = 0; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int cb802_1_H_len = 0; + unsigned int uLength = 0; + unsigned int uTmpLen = 0; // unsigned char abyTmp[8]; // unsigned long dwCRC; - unsigned int cbMICHDR = 0; - unsigned long dwMICKey0, dwMICKey1; - unsigned long dwMIC_Priority; - unsigned long *pdwMIC_L; - unsigned long *pdwMIC_R; - unsigned long dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length". - bool bMIC2Frag = false; - unsigned int uMICFragLen = 0; - unsigned int uMACfragNum = 1; - unsigned int uPadding = 0; - unsigned int cbReqCount = 0; - - bool bNeedACK; - bool bRTS; - bool bIsAdhoc; - unsigned char *pbyType; - PSTxDesc ptdCurr; - PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; + unsigned int cbMICHDR = 0; + unsigned long dwMICKey0, dwMICKey1; + unsigned long dwMIC_Priority; + unsigned long *pdwMIC_L; + unsigned long *pdwMIC_R; + unsigned long dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length". + bool bMIC2Frag = false; + unsigned int uMICFragLen = 0; + unsigned int uMACfragNum = 1; + unsigned int uPadding = 0; + unsigned int cbReqCount = 0; + + bool bNeedACK; + bool bRTS; + bool bIsAdhoc; + unsigned char *pbyType; + PSTxDesc ptdCurr; + PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; // unsigned int tmpDescIdx; - unsigned int cbHeaderLength = 0; - void * pvRrvTime; - PSMICHDRHead pMICHDR; - void * pvRTS; - void * pvCTS; - void * pvTxDataHd; - unsigned short wTxBufSize; // FFinfo size - unsigned int uTotalCopyLength = 0; - unsigned char byFBOption = AUTO_FB_NONE; - bool bIsWEP256 = false; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_cbFillTxBufHead...\n"); - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - bIsAdhoc = true; - } - else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - bIsAdhoc = false; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) { - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { - bIsWEP256 = true; - } - } - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(SMICHDRHead); - } - if (pDevice->byLocalID > REV_ID_VT3253_A1) { - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMACHdLen%4); - uPadding %= 4; - } - } - - - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((bNeedACK == false) || - (cbFrameSize < pDevice->wRTSThreshold) || - ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold)) - ) { - bRTS = false; - } - else { - bRTS = true; - psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); - } - // - // Use for AUTO FALL BACK - // - if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) { - byFBOption = AUTO_FB_0; - } - else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) { - byFBOption = AUTO_FB_1; - } - - ////////////////////////////////////////////////////// - //Set RrvTime/RTS/CTS Buffer - wTxBufSize = sizeof(STxBufHead); - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - - if (byFBOption == AUTO_FB_NONE) { - if (bRTS == true) {//RTS_need - pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); - pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g)); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g); - } - else { //RTS_needless - pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); - pvRTS = NULL; - pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); - pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); - } - } else { - // Auto Fall Back - if (bRTS == true) {//RTS_need - pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); - pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB)); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB); - } - else { //RTS_needless - pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); - pvRTS = NULL; - pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); - pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB)); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB); - } - } // Auto Fall Back - } - else {//802.11a/b packet - - if (byFBOption == AUTO_FB_NONE) { - if (bRTS == true) { - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab)); - cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab); - } - else { //RTS_needless, need MICHDR - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); - } - } else { - // Auto Fall Back - if (bRTS == true) {//RTS_need - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB)); - cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB); - } - else { //RTS_needless - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); - cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB); - } - } // Auto Fall Back - } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); + unsigned int cbHeaderLength = 0; + void *pvRrvTime; + PSMICHDRHead pMICHDR; + void *pvRTS; + void *pvCTS; + void *pvTxDataHd; + unsigned short wTxBufSize; // FFinfo size + unsigned int uTotalCopyLength = 0; + unsigned char byFBOption = AUTO_FB_NONE; + bool bIsWEP256 = false; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; + + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_cbFillTxBufHead...\n"); + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + + if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) + bNeedACK = false; + else + bNeedACK = true; + bIsAdhoc = true; + } + else { + // MSDUs in Infra mode always need ACK + bNeedACK = true; + bIsAdhoc = false; + } + + if (pDevice->bLongHeader) + cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; + else + cbMACHdLen = WLAN_HDR_ADDR3_LEN; + + + if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) { + if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { + cbIVlen = 4; + cbICVlen = 4; + if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { + bIsWEP256 = true; + } + } + if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { + cbIVlen = 8;//IV+ExtIV + cbMIClen = 8; + cbICVlen = 4; + } + if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { + cbIVlen = 8;//RSN Header + cbICVlen = 8;//MIC + cbMICHDR = sizeof(SMICHDRHead); + } + if (pDevice->byLocalID > REV_ID_VT3253_A1) { + //MAC Header should be padding 0 to DW alignment. + uPadding = 4 - (cbMACHdLen%4); + uPadding %= 4; + } + } + + + cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; + + if ((bNeedACK == false) || + (cbFrameSize < pDevice->wRTSThreshold) || + ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold)) +) { + bRTS = false; + } + else { + bRTS = true; + psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); + } + // + // Use for AUTO FALL BACK + // + if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) { + byFBOption = AUTO_FB_0; + } + else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) { + byFBOption = AUTO_FB_1; + } + + ////////////////////////////////////////////////////// + //Set RrvTime/RTS/CTS Buffer + wTxBufSize = sizeof(STxBufHead); + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet + + if (byFBOption == AUTO_FB_NONE) { + if (bRTS == true) {//RTS_need + pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); + pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g)); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g); + } + else { //RTS_needless + pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pvRTS = NULL; + pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); + pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); + } + } else { + // Auto Fall Back + if (bRTS == true) {//RTS_need + pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); + pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB)); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB); + } + else { //RTS_needless + pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pvRTS = NULL; + pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); + pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB)); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB); + } + } // Auto Fall Back + } + else {//802.11a/b packet + + if (byFBOption == AUTO_FB_NONE) { + if (bRTS == true) { + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab)); + cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab); + } + else { //RTS_needless, need MICHDR + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pvRTS = NULL; + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); + } + } else { + // Auto Fall Back + if (bRTS == true) {//RTS_need + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB)); + cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB); + } + else { //RTS_needless + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pvRTS = NULL; + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); + cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB); + } + } // Auto Fall Back + } + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); ////////////////////////////////////////////////////////////////// - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); - } - else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); - } - else { - dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[28]); - } - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); - } + if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); + dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); + } + else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { + dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); + dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); + } + else { + dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[24]); + dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[28]); + } + // DO Software Michael + MIC_vInit(dwMICKey0, dwMICKey1); + MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); + dwMIC_Priority = 0; + MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); + } /////////////////////////////////////////////////////////////////// - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding); - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) { - // Fragmentation - // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS) - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS))) - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) { - cbLastFragPayloadSize = cbFragPayloadSize; - } else { - uMACfragNum++; - } - //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS] - cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen; - - for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx ++) { - if (uFragIdx == 0) { - //========================= - // Start Fragmentation - //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start Fragmentation...\n"); - wFragType = FRAGCTL_STAFRAG; - - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - //Fill IV(ExtIV,RSNHDR) - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } - else { - memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *) (pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - //Fill MICHDR - //if (pDevice->bAES) { - // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize); - //} - //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, - // pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx); - - - - //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); - - - uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize); - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); - - } - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } - else if (uFragIdx == (uMACfragNum-1)) { - //========================= - // Last Fragmentation - //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last Fragmentation...\n"); - //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; - - wFragType = FRAGCTL_ENDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - } - - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - - - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - if (bMIC2Frag == false) { - - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - (cbLastFragPayloadSize - cbMIClen) - ); - //TODO check uTmpLen ! - uTmpLen = cbLastFragPayloadSize - cbMIClen; - - } - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, cbLastFragPayloadSize, uTmpLen); - - if (bMIC2Frag == false) { - if (uTmpLen != 0) - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); - } else { - if (uMICFragLen >= 4) { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - - } else { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen), - (4 - uMICFragLen)); - memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4), - (cbMIClen - uMICFragLen)); - } - /* - for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii - 8 - 24))); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n"); - */ - } - MIC_vUnInit(); - } else { - ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen)); - } - - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - - } - else { - //========================= - // Middle Fragmentation - //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle Fragmentation...\n"); - //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; - - wFragType = FRAGCTL_MIDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - //Fill MICHDR - //if (pDevice->bAES) { - // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize); - //} - //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, - // pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx); - - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; - - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - cbFragPayloadSize - ); - uTmpLen = cbFragPayloadSize; - - uTotalCopyLength += uTmpLen; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - - if (uTmpLen < cbFragPayloadSize) { - bMIC2Frag = true; - uMICFragLen = cbFragPayloadSize - uTmpLen; - ASSERT(uMICFragLen < cbMIClen); - - pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - dwSafeMIC_L = *pdwMIC_L; - dwSafeMIC_R = *pdwMIC_R; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, cbFragPayloadSize, uTmpLen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen); - /* - for (ii = 0; ii < uMICFragLen; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength + uTmpLen) + ii))); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - */ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen); - /* - for (ii = 0; ii < uTmpLen; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii))); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n"); - */ - - } else { - ASSERT(uTmpLen == (cbFragPayloadSize)); - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } - } // for (uMACfragNum) - } - else { - //========================= - // No Fragmentation - //========================= - //DBG_PRTGRP03(("No Fragmentation...\n")); - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n"); - wFragType = FRAGCTL_NONFRAG; - - //Set FragCtl in TxBufferHead - psTxBufHd->wFragCtl |= (unsigned short)wFragType; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, - 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, 0); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } - else { - memcpy((unsigned char *) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *) (pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - //Fill MICHDR - //if (pDevice->bAES) { - // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n"); - // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFrameBodySize); - //} - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14), - cbFrameBodySize - cb802_1_H_len - ); - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){ - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength); - /* - for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii))); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - */ - - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); - - pdwMIC_L = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); - pdwMIC_R = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); + pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength); + pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); + pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding); + + if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) { + // Fragmentation + // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS) + cbFragmentSize = pDevice->wFragmentationThreshold; + cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; + //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS))) + uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); + cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; + if (cbLastFragPayloadSize == 0) { + cbLastFragPayloadSize = cbFragPayloadSize; + } else { + uMACfragNum++; + } + //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS] + cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen; + + for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) { + if (uFragIdx == 0) { + //========================= + // Start Fragmentation + //========================= + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start Fragmentation...\n"); + wFragType = FRAGCTL_STAFRAG; + + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, + uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); + // Generate TX MAC Header + vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, + wFragType, uDMAIdx, uFragIdx); + + if (bNeedEncrypt == true) { + //Fill TXKEY + s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); + //Fill IV(ExtIV,RSNHDR) + if (pDevice->bEnableHostWEP) { + pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; + pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; + } + } + + + // 802.1H + if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { + if ((psEthHeader->wType == TYPE_PKT_IPX) || + (psEthHeader->wType == cpu_to_le16(0xF380))) { + memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); + } + else { + memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); + } + pbyType = (unsigned char *)(pbyPayloadHead + 6); + memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); + cb802_1_H_len = 8; + } + + cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; + //--------------------------- + // S/W or H/W Encryption + //--------------------------- + //Fill MICHDR + //if (pDevice->bAES) { + // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize); + //} + //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, + // pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx); + + + + //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + + uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; + //copy TxBufferHeader + MacHeader to desc + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + + // Copy the Packet into a tx Buffer + memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); + + + uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; + + if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start MIC: %d\n", cbFragPayloadSize); + MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); + + } + + //--------------------------- + // S/W Encryption + //--------------------------- + if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { + if (bNeedEncrypt) { + s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize); + cbReqCount += cbICVlen; + } + } + + ptdCurr = (PSTxDesc)pHeadTD; + //-------------------- + //1.Set TSR1 & ReqCount in TxDescHead + //2.Set FragCtl in TxBufferHead + //3.Set Frame Control + //4.Set Sequence Control + //5.Get S/W generate FCS + //-------------------- + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); + + ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); + pDevice->iTDUsed[uDMAIdx]++; + pHeadTD = ptdCurr->next; + } + else if (uFragIdx == (uMACfragNum-1)) { + //========================= + // Last Fragmentation + //========================= + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last Fragmentation...\n"); + //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; + + wFragType = FRAGCTL_ENDFRAG; + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, + uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); + + // Generate TX MAC Header + vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, + wFragType, uDMAIdx, uFragIdx); + + if (bNeedEncrypt == true) { + //Fill TXKEY + s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR); + + if (pDevice->bEnableHostWEP) { + pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; + pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; + } + + } + + + cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize; + //--------------------------- + // S/W or H/W Encryption + //--------------------------- + + + + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; + + uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; + + //copy TxBufferHeader + MacHeader to desc + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + + // Copy the Packet into a tx Buffer + if (bMIC2Frag == false) { + + memcpy((pbyBuffer + uLength), + (pPacket + 14 + uTotalCopyLength), + (cbLastFragPayloadSize - cbMIClen) +); + //TODO check uTmpLen ! + uTmpLen = cbLastFragPayloadSize - cbMIClen; + + } + if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", + uMICFragLen, cbLastFragPayloadSize, uTmpLen); + + if (bMIC2Frag == false) { + if (uTmpLen != 0) + MIC_vAppend((pbyBuffer + uLength), uTmpLen); + pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen); + pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4); + MIC_vGetMIC(pdwMIC_L, pdwMIC_R); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); + } else { + if (uMICFragLen >= 4) { + memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), + (cbMIClen - uMICFragLen)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen >= 4: %X, %d\n", + *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), + (cbMIClen - uMICFragLen)); + + } else { + memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen), + (4 - uMICFragLen)); + memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen < 4: %X, %d\n", + *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4), + (cbMIClen - uMICFragLen)); + } + /* + for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii - 8 - 24))); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n\n"); + */ + } + MIC_vUnInit(); + } else { + ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen)); + } + + + //--------------------------- + // S/W Encryption + //--------------------------- + if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { + if (bNeedEncrypt) { + s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize); + cbReqCount += cbICVlen; + } + } + + ptdCurr = (PSTxDesc)pHeadTD; + + //-------------------- + //1.Set TSR1 & ReqCount in TxDescHead + //2.Set FragCtl in TxBufferHead + //3.Set Frame Control + //4.Set Sequence Control + //5.Get S/W generate FCS + //-------------------- + + + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); + + ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); + pDevice->iTDUsed[uDMAIdx]++; + pHeadTD = ptdCurr->next; + + } + else { + //========================= + // Middle Fragmentation + //========================= + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle Fragmentation...\n"); + //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx]; + + wFragType = FRAGCTL_MIDFRAG; + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, + uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); + + // Generate TX MAC Header + vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, + wFragType, uDMAIdx, uFragIdx); + + + if (bNeedEncrypt == true) { + //Fill TXKEY + s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); + + if (pDevice->bEnableHostWEP) { + pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; + pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; + } + } + + cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; + //--------------------------- + // S/W or H/W Encryption + //--------------------------- + //Fill MICHDR + //if (pDevice->bAES) { + // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFragPayloadSize); + //} + //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, + // pbyPayloadHead, (unsigned short)cbFragPayloadSize, uDMAIdx); + + + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr; + + + uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; + + //copy TxBufferHeader + MacHeader to desc + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + + // Copy the Packet into a tx Buffer + memcpy((pbyBuffer + uLength), + (pPacket + 14 + uTotalCopyLength), + cbFragPayloadSize +); + uTmpLen = cbFragPayloadSize; + + uTotalCopyLength += uTmpLen; + + if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + + MIC_vAppend((pbyBuffer + uLength), uTmpLen); + + if (uTmpLen < cbFragPayloadSize) { + bMIC2Frag = true; + uMICFragLen = cbFragPayloadSize - uTmpLen; + ASSERT(uMICFragLen < cbMIClen); + + pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen); + pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4); + MIC_vGetMIC(pdwMIC_L, pdwMIC_R); + dwSafeMIC_L = *pdwMIC_L; + dwSafeMIC_R = *pdwMIC_R; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", + uMICFragLen, cbFragPayloadSize, uTmpLen); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fill MIC in Middle frag [%d]\n", uMICFragLen); + /* + for (ii = 0; ii < uMICFragLen; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength + uTmpLen) + ii))); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + */ + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle frag len: %d\n", uTmpLen); + /* + for (ii = 0; ii < uTmpLen; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii))); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n\n"); + */ + + } else { + ASSERT(uTmpLen == (cbFragPayloadSize)); + } + + if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { + if (bNeedEncrypt) { + s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize); + cbReqCount += cbICVlen; + } + } + + ptdCurr = (PSTxDesc)pHeadTD; + + //-------------------- + //1.Set TSR1 & ReqCount in TxDescHead + //2.Set FragCtl in TxBufferHead + //3.Set Frame Control + //4.Set Sequence Control + //5.Get S/W generate FCS + //-------------------- + + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); + + ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); + pDevice->iTDUsed[uDMAIdx]++; + pHeadTD = ptdCurr->next; + } + } // for (uMACfragNum) + } + else { + //========================= + // No Fragmentation + //========================= + //DBG_PRTGRP03(("No Fragmentation...\n")); + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No Fragmentation...\n"); + wFragType = FRAGCTL_NONFRAG; + + //Set FragCtl in TxBufferHead + psTxBufHd->wFragCtl |= (unsigned short)wFragType; + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, + 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); + + // Generate TX MAC Header + vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt, + wFragType, uDMAIdx, 0); + + if (bNeedEncrypt == true) { + //Fill TXKEY + s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); + + if (pDevice->bEnableHostWEP) { + pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; + pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; + } + } + + // 802.1H + if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { + if ((psEthHeader->wType == TYPE_PKT_IPX) || + (psEthHeader->wType == cpu_to_le16(0xF380))) { + memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); + } + else { + memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); + } + pbyType = (unsigned char *)(pbyPayloadHead + 6); + memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); + cb802_1_H_len = 8; + } + + cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); + //--------------------------- + // S/W or H/W Encryption + //--------------------------- + //Fill MICHDR + //if (pDevice->bAES) { + // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fill MICHDR...\n"); + // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, pbyMacHdr, (unsigned short)cbFrameBodySize); + //} + + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][uDescIdx].pbyVAddr; + + uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; + + //copy TxBufferHeader + MacHeader to desc + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); + + // Copy the Packet into a tx Buffer + memcpy((pbyBuffer + uLength), + (pPacket + 14), + cbFrameBodySize - cb802_1_H_len +); + + if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength); + /* + for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii))); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + */ + + MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); + + pdwMIC_L = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); + pdwMIC_R = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4); + + MIC_vGetMIC(pdwMIC_L, pdwMIC_R); + MIC_vUnInit(); + + + if (pDevice->bTxMICFail == true) { + *pdwMIC_L = 0; + *pdwMIC_R = 0; + pDevice->bTxMICFail = false; + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); /* - for (ii = 0; ii < 8; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((unsigned char *)(pdwMIC_L) + ii))); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); + for (ii = 0; ii < 8; ii++) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *(((unsigned char *)(pdwMIC_L) + ii))); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); */ - } + } - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)){ - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), - (unsigned short)(cbFrameBodySize + cbMIClen)); - cbReqCount += cbICVlen; - } - } + if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { + if (bNeedEncrypt) { + s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), + (unsigned short)(cbFrameBodySize + cbMIClen)); + cbReqCount += cbICVlen; + } + } - ptdCurr = (PSTxDesc)pHeadTD; + ptdCurr = (PSTxDesc)pHeadTD; - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); + //Set TSR1 & ReqCount in TxDescHead + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - pDevice->iTDUsed[uDMAIdx]++; + pDevice->iTDUsed[uDMAIdx]++; -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength); -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cbHeaderLength[%d]\n", cbHeaderLength); +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength); +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cbHeaderLength[%d]\n", cbHeaderLength); - } - *puMACfragNum = uMACfragNum; - //DBG_PRTGRP03(("s_cbFillTxBufHead END\n")); - return cbHeaderLength; + } + *puMACfragNum = uMACfragNum; + //DBG_PRTGRP03(("s_cbFillTxBufHead END\n")); + return cbHeaderLength; } void vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, - bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize) + bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, + PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, + PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum, + unsigned int *pcbHeaderSize) { - unsigned int wTxBufSize; // FFinfo size - bool bNeedACK; - bool bIsAdhoc; - unsigned short cbMacHdLen; - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - - wTxBufSize = sizeof(STxBufHead); - - memset(pTxBufHead, 0, wTxBufSize); - //Set FIFOCTL_NEEDACK - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - bIsAdhoc = true; - } - else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - bIsAdhoc = false; - } - - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); - - //Set FIFOCTL_LHEAD - if (pDevice->bLongHeader) - pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; - - //Set FIFOCTL_GENINT - - pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; - - - //Set FIFOCTL_ISDMA0 - if (TYPE_TXDMA0 == uDMAIdx) { - pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0; - } - - //Set FRAGCTL_MACHDCNT - if (pDevice->bLongHeader) { - cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - ; - } - else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } - else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } - else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - } - - //Set Auto Fallback Ctl - if (pDevice->wCurrentRate >= RATE_18M) { - if (pDevice->byAutoFBCtrl == AUTO_FB_0) { - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; - } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) { - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; - } - } - - //Set FRAGCTL_WEPTYP - pDevice->bAES = false; - - //Set FRAGCTL_WEPTYP - if (pDevice->byLocalID > REV_ID_VT3253_A1) { - if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - } - else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 - if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN) - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } - else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP - pTxBufHead->wFragCtl |= FRAGCTL_AES; - } - } - } + unsigned int wTxBufSize; // FFinfo size + bool bNeedACK; + bool bIsAdhoc; + unsigned short cbMacHdLen; + PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; + + wTxBufSize = sizeof(STxBufHead); + + memset(pTxBufHead, 0, wTxBufSize); + //Set FIFOCTL_NEEDACK + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) { + bNeedACK = false; + pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); + } + else { + bNeedACK = true; + pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + } + bIsAdhoc = true; + } + else { + // MSDUs in Infra mode always need ACK + bNeedACK = true; + pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + bIsAdhoc = false; + } + + + pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; + pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); + + //Set FIFOCTL_LHEAD + if (pDevice->bLongHeader) + pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; + + //Set FIFOCTL_GENINT + + pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; + + + //Set FIFOCTL_ISDMA0 + if (TYPE_TXDMA0 == uDMAIdx) { + pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0; + } + + //Set FRAGCTL_MACHDCNT + if (pDevice->bLongHeader) { + cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6; + } else { + cbMacHdLen = WLAN_HDR_ADDR3_LEN; + } + pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); + + //Set packet type + if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 + ; + } + else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11B; + } + else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; + } + else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; + } + //Set FIFOCTL_GrpAckPolicy + if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; + } + + //Set Auto Fallback Ctl + if (pDevice->wCurrentRate >= RATE_18M) { + if (pDevice->byAutoFBCtrl == AUTO_FB_0) { + pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; + } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) { + pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; + } + } + + //Set FRAGCTL_WEPTYP + pDevice->bAES = false; + + //Set FRAGCTL_WEPTYP + if (pDevice->byLocalID > REV_ID_VT3253_A1) { + if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled + if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { + pTxBufHead->wFragCtl |= FRAGCTL_TKIP; + } + else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 + if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN) + pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; + } + else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP + pTxBufHead->wFragCtl |= FRAGCTL_AES; + } + } + } #ifdef PLICE_DEBUG //printk("Func:vGenerateFIFOHeader:TxDataRate is %d,TxPower is %d\n",pDevice->wCurrentRate,pDevice->byCurPwr); @@ -2188,22 +2188,22 @@ vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pb RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh); #endif - //if (pDevice->wCurrentRate == 3) - //pDevice->byCurPwr = 46; - pTxBufHead->byTxPower = pDevice->byCurPwr; + //if (pDevice->wCurrentRate == 3) + //pDevice->byCurPwr = 46; + pTxBufHead->byTxPower = pDevice->byCurPwr; /* - if(pDevice->bEnableHostWEP) - pTxBufHead->wFragCtl &= ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES); + if (pDevice->bEnableHostWEP) + pTxBufHead->wFragCtl &= ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES); */ - *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, - uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, - pTransmitKey, uNodeIndex, puMACfragNum); + *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, + uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, + pTransmitKey, uNodeIndex, puMACfragNum); - return; + return; } @@ -2226,74 +2226,74 @@ vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pb * * Return Value: none * --*/ + -*/ void -vGenerateMACHeader ( - PSDevice pDevice, - unsigned char *pbyBufferAddr, - unsigned short wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx - ) +vGenerateMACHeader( + PSDevice pDevice, + unsigned char *pbyBufferAddr, + unsigned short wDuration, + PSEthernetHeader psEthHeader, + bool bNeedEncrypt, + unsigned short wFragType, + unsigned int uDMAIdx, + unsigned int uFragIdx +) { - PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; - - memset(pMACHeader, 0, (sizeof(S802_11Header))); //- sizeof(pMACHeader->dwIV))); - - if (uDMAIdx == TYPE_ATIMDMA) { - pMACHeader->wFrameCtl = TYPE_802_11_ATIM; - } else { - pMACHeader->wFrameCtl = TYPE_802_11_DATA; - } - - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_FROMDS; - } - else { - if (pDevice->eOPMode == OP_MODE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - } - else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - pMACHeader->wFrameCtl |= FC_TODS; - } - } - - if (bNeedEncrypt) - pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1)); - - pMACHeader->wDurationID = cpu_to_le16(wDuration); - - if (pDevice->bLongHeader) { - PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; - pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); - memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); - } - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - - //Set FragNumber in Sequence Control - pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx); - - if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - } - - if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag - pMACHeader->wFrameCtl |= FC_MOREFRAG; - } + PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; + + memset(pMACHeader, 0, (sizeof(S802_11Header))); //- sizeof(pMACHeader->dwIV))); + + if (uDMAIdx == TYPE_ATIMDMA) { + pMACHeader->wFrameCtl = TYPE_802_11_ATIM; + } else { + pMACHeader->wFrameCtl = TYPE_802_11_DATA; + } + + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + pMACHeader->wFrameCtl |= FC_FROMDS; + } + else { + if (pDevice->eOPMode == OP_MODE_ADHOC) { + memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + } + else { + memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + pMACHeader->wFrameCtl |= FC_TODS; + } + } + + if (bNeedEncrypt) + pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1)); + + pMACHeader->wDurationID = cpu_to_le16(wDuration); + + if (pDevice->bLongHeader) { + PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; + pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); + memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); + } + pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + + //Set FragNumber in Sequence Control + pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx); + + if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { + pDevice->wSeqCounter++; + if (pDevice->wSeqCounter > 0x0fff) + pDevice->wSeqCounter = 0; + } + + if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag + pMACHeader->wFrameCtl |= FC_MOREFRAG; + } } @@ -2303,887 +2303,887 @@ vGenerateMACHeader ( CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void * pvRTS; - PSCTS pCTS; - void * pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void * pvRrvTime; - void * pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - return CMD_STATUS_RESOURCES; - } - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - cbFrameBodySize = pPacket->cbPayloadLen; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; - } - - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { + PSTxDesc pFrstTD; + unsigned char byPktType; + unsigned char *pbyTxBufferAddr; + void *pvRTS; + PSCTS pCTS; + void *pvTxDataHd; + unsigned int uDuration; + unsigned int cbReqCount; + PS802_11Header pMACHeader; + unsigned int cbHeaderSize; + unsigned int cbFrameBodySize; + bool bNeedACK; + bool bIsPSPOLL = false; + PSTxBufHead pTxBufHead; + unsigned int cbFrameSize; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int uPadding = 0; + unsigned short wTxBufSize; + unsigned int cbMacHdLen; + SEthernetHeader sEthHeader; + void *pvRrvTime; + void *pMICHDR; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned short wCurrentRate = RATE_1M; + + + if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { + return CMD_STATUS_RESOURCES; + } + + pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; + pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; + cbFrameBodySize = pPacket->cbPayloadLen; + pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; + wTxBufSize = sizeof(STxBufHead); + memset(pTxBufHead, 0, wTxBufSize); + + if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + wCurrentRate = RATE_6M; + byPktType = PK_TYPE_11A; + } else { + wCurrentRate = RATE_1M; + byPktType = PK_TYPE_11B; + } + + // SetPower will cause error power TX state for OFDM Date packet in TX buffer. + // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. + // And cmd timer will wait data pkt TX finish before scanning so it's OK + // to set power here. + if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); - } else { - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - } - pTxBufHead->byTxPower = pDevice->byCurPwr; - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } - else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } - else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } - else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - - if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0]))) - bNeedACK = false; - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - }; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) { - - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - //Set Preamble type always long - //pDevice->byPreambleType = PREAMBLE_LONG; - // probe-response don't retry - //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { - // bNeedACK = false; - // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK); - //} - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; - } - - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - } - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() - - //Set RrvTime/RTS/CTS Buffer - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - - pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); - pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS)); - cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g); - } - else { // 802.11a/b packet - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = NULL; - pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab); - } - - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); - - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); - - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyBSSID; - PSKeyItem pTransmitKey = NULL; - - pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); - - //Fill TXKEY - //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet. - //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL); - - //Fill IV(ExtIV,RSNHDR) - //s_vFillPrePayload(pDevice, pbyIVHead, NULL); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - //Fill MICHDR - //if (pDevice->bAES) { - // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize); - //} - do { - if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && - (pDevice->bLinkPass == true)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); - break; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n"); - break; - } - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n"); - } - } while(false); - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL); - - memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen), - cbFrameBodySize); - } - else { - // Copy the Packet into a tx Buffer - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - } - - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++ ; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } else { - ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } - } - - - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); - } - - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; + } else { + RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); + } + pTxBufHead->byTxPower = pDevice->byCurPwr; + //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ + if (pDevice->byFOETuning) { + if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { + wCurrentRate = RATE_24M; + byPktType = PK_TYPE_11GA; + } + } + + //Set packet type + if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 + pTxBufHead->wFIFOCtl = 0; + } + else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11B; + } + else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; + } + else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; + } + + pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; + pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + + + if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0]))) + bNeedACK = false; + else { + bNeedACK = true; + pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + }; + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || + (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { + + pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; + //Set Preamble type always long + //pDevice->byPreambleType = PREAMBLE_LONG; + // probe-response don't retry + //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { + // bNeedACK = false; + // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK); + //} + } + + pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); + + if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { + bIsPSPOLL = true; + cbMacHdLen = WLAN_HDR_ADDR2_LEN; + } else { + cbMacHdLen = WLAN_HDR_ADDR3_LEN; + } + + //Set FRAGCTL_MACHDCNT + pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); + + // Notes: + // Although spec says MMPDU can be fragmented; In most cases, + // no one will send a MMPDU under fragmentation. With RTS may occur. + pDevice->bAES = false; //Set FRAGCTL_WEPTYP + + if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { + if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { + cbIVlen = 4; + cbICVlen = 4; + pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; + } + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + cbIVlen = 8;//IV+ExtIV + cbMIClen = 8; + cbICVlen = 4; + pTxBufHead->wFragCtl |= FRAGCTL_TKIP; + //We need to get seed here for filling TxKey entry. + //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, + // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); + } + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + cbIVlen = 8;//RSN Header + cbICVlen = 8;//MIC + pTxBufHead->wFragCtl |= FRAGCTL_AES; + pDevice->bAES = true; + } + //MAC Header should be padding 0 to DW alignment. + uPadding = 4 - (cbMacHdLen%4); + uPadding %= 4; + } + + cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; + + //Set FIFOCTL_GrpAckPolicy + if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; + } + //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() + + //Set RrvTime/RTS/CTS Buffer + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet + + pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = NULL; + pvRTS = NULL; + pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS)); + cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g); + } + else { // 802.11a/b packet + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = NULL; + pvRTS = NULL; + pCTS = NULL; + pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab); + } + + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + + memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); + //========================= + // No Fragmentation + //========================= + pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; + + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS, + cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); + + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, + 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + + pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); + + cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; + + if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { + unsigned char *pbyIVHead; + unsigned char *pbyPayloadHead; + unsigned char *pbyBSSID; + PSKeyItem pTransmitKey = NULL; + + pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); + pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); + + //Fill TXKEY + //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet. + //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL); + + //Fill IV(ExtIV,RSNHDR) + //s_vFillPrePayload(pDevice, pbyIVHead, NULL); + //--------------------------- + // S/W or H/W Encryption + //--------------------------- + //Fill MICHDR + //if (pDevice->bAES) { + // s_vFillMICHDR(pDevice, (unsigned char *)pMICHDR, (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize); + //} + do { + if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && + (pDevice->bLinkPass == true)) { + pbyBSSID = pDevice->abyBSSID; + // get pairwise key + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { + // get group key + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n"); + break; + } + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get PTK.\n"); + break; + } + } + // get group key + pbyBSSID = pDevice->abyBroadcastAddr; + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { + pTransmitKey = NULL; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n"); + } + } while (false); + //Fill TXKEY + s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, + (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL); + + memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); + memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen), + cbFrameBodySize); + } + else { + // Copy the Packet into a tx Buffer + memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); + } + + pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + pDevice->wSeqCounter++; + if (pDevice->wSeqCounter > 0x0fff) + pDevice->wSeqCounter = 0; + + if (bIsPSPOLL) { + // The MAC will automatically replace the Duration-field of MAC header by Duration-field + // of FIFO control header. + // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is + // in the same place of other packet's Duration-field). + // And it will cause Cisco-AP to issue Disassociation-packet + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); + ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); + } else { + ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); + } + } + + + // first TD is the only TD + //Set TSR1 & ReqCount in TxDescHead + pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); + pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; + pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); + pFrstTD->pTDInfo->byFlags = 0; + + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { + // Disable PS + MACbPSWakeup(pDevice->PortOffset); + } + pDevice->bPWBitOn = false; + + wmb(); + pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); + + pDevice->iTDUsed[TYPE_TXDMA0]++; + + if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); + } + + pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; #ifdef PLICE_DEBUG - //printk("SCAN:CurrentRate is %d,TxPower is %d\n",wCurrentRate,pTxBufHead->byTxPower); + //printk("SCAN:CurrentRate is %d,TxPower is %d\n",wCurrentRate,pTxBufHead->byTxPower); #endif #ifdef TxInSleep - pDevice->nTxDataTimeCout=0; //2008-8-21 chester for send null packet - #endif + pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet +#endif - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); + // Poll Transmit the adapter + MACvTransmit0(pDevice->PortOffset); - return CMD_STATUS_PENDING; + return CMD_STATUS_PENDING; } CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { - unsigned char byPktType; - unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; - unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - unsigned int cbHeaderSize = 0; - unsigned short wTxBufSize = sizeof(STxShortBufHead); - PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer; - PSTxDataHead_ab pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize); - PS802_11Header pMACHeader; - unsigned short wCurrentRate; - unsigned short wLen = 0x0000; - - - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_2M; - byPktType = PK_TYPE_11B; - } - - //Set Preamble type always long - pDevice->byPreambleType = PREAMBLE_LONG; - - //Set FIFOCTL_GENINT - - pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; - - - //Set packet type & Get Duration - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType, - wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); - } - else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType, - wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); - } - - BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType, - (unsigned short *)&(wLen), (unsigned char *)&(pTxDataHead->byServiceField), (unsigned char *)&(pTxDataHead->bySignalField) - ); - pTxDataHead->wTransmitLength = cpu_to_le16(wLen); - //Get TimeStampOff - pTxDataHead->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); - cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab); - - //Generate Beacon Header - pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize); - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - - pMACHeader->wDurationID = 0; - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++ ; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - // Set Beacon buffer length - pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize; - - MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); - - MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen); - // Set auto Transmit on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - // Poll Transmit the adapter - MACvTransmitBCN(pDevice->PortOffset); - - return CMD_STATUS_PENDING; + unsigned char byPktType; + unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; + unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; + unsigned int cbHeaderSize = 0; + unsigned short wTxBufSize = sizeof(STxShortBufHead); + PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer; + PSTxDataHead_ab pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize); + PS802_11Header pMACHeader; + unsigned short wCurrentRate; + unsigned short wLen = 0x0000; + + + memset(pTxBufHead, 0, wTxBufSize); + + if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + wCurrentRate = RATE_6M; + byPktType = PK_TYPE_11A; + } else { + wCurrentRate = RATE_2M; + byPktType = PK_TYPE_11B; + } + + //Set Preamble type always long + pDevice->byPreambleType = PREAMBLE_LONG; + + //Set FIFOCTL_GENINT + + pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; + + + //Set packet type & Get Duration + if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 + pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType, + wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); + } + else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11B; + pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType, + wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE)); + } + + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType, + (unsigned short *)&(wLen), (unsigned char *)&(pTxDataHead->byServiceField), (unsigned char *)&(pTxDataHead->bySignalField) +); + pTxDataHead->wTransmitLength = cpu_to_le16(wLen); + //Get TimeStampOff + pTxDataHead->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]); + cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab); + + //Generate Beacon Header + pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize); + memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); + + pMACHeader->wDurationID = 0; + pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + pDevice->wSeqCounter++; + if (pDevice->wSeqCounter > 0x0fff) + pDevice->wSeqCounter = 0; + + // Set Beacon buffer length + pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize; + + MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); + + MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen); + // Set auto Transmit on + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + // Poll Transmit the adapter + MACvTransmitBCN(pDevice->PortOffset); + + return CMD_STATUS_PENDING; } unsigned int -cbGetFragCount ( - PSDevice pDevice, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader - ) +cbGetFragCount( + PSDevice pDevice, + PSKeyItem pTransmitKey, + unsigned int cbFrameBodySize, + PSEthernetHeader psEthHeader +) { - unsigned int cbMACHdLen; - unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragPayloadSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uMACfragNum = 1; - bool bNeedACK; - - - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - } - else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - - - if (pDevice->bEncryptionEnable == true) { - - if (pTransmitKey == NULL) { - if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) || - (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } - - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) { - // Fragmentation - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) { - cbLastFragPayloadSize = cbFragPayloadSize; - } else { - uMACfragNum++; - } - } - return uMACfragNum; + unsigned int cbMACHdLen; + unsigned int cbFrameSize; + unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS + unsigned int cbFragPayloadSize; + unsigned int cbLastFragPayloadSize; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int uMACfragNum = 1; + bool bNeedACK; + + + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) + bNeedACK = false; + else + bNeedACK = true; + } + else { + // MSDUs in Infra mode always need ACK + bNeedACK = true; + } + + if (pDevice->bLongHeader) + cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; + else + cbMACHdLen = WLAN_HDR_ADDR3_LEN; + + + if (pDevice->bEncryptionEnable == true) { + + if (pTransmitKey == NULL) { + if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) || + (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) { + cbIVlen = 4; + cbICVlen = 4; + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + cbIVlen = 8;//IV+ExtIV + cbMIClen = 8; + cbICVlen = 4; + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + cbIVlen = 8;//RSN Header + cbICVlen = 8;//MIC + } + } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { + cbIVlen = 4; + cbICVlen = 4; + } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { + cbIVlen = 8;//IV+ExtIV + cbMIClen = 8; + cbICVlen = 4; + } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { + cbIVlen = 8;//RSN Header + cbICVlen = 8;//MIC + } + } + + cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; + + if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) { + // Fragmentation + cbFragmentSize = pDevice->wFragmentationThreshold; + cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; + uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); + cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; + if (cbLastFragPayloadSize == 0) { + cbLastFragPayloadSize = cbFragPayloadSize; + } else { + uMACfragNum++; + } + } + return uMACfragNum; } void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen) { - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void * pvRTS; - void * pvCTS; - void * pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned int cbMICHDR = 0; - unsigned int uLength = 0; - unsigned long dwMICKey0, dwMICKey1; - unsigned long dwMIC_Priority; - unsigned long *pdwMIC_L; - unsigned long *pdwMIC_R; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void * pvRrvTime; - void * pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - PUWLAN_80211HDR p80211Header; - unsigned int uNodeIndex = 0; - bool bNodeExist = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyMacHdr; - - unsigned int cbExtSuppRate = 0; + PSTxDesc pFrstTD; + unsigned char byPktType; + unsigned char *pbyTxBufferAddr; + void *pvRTS; + void *pvCTS; + void *pvTxDataHd; + unsigned int uDuration; + unsigned int cbReqCount; + PS802_11Header pMACHeader; + unsigned int cbHeaderSize; + unsigned int cbFrameBodySize; + bool bNeedACK; + bool bIsPSPOLL = false; + PSTxBufHead pTxBufHead; + unsigned int cbFrameSize; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int uPadding = 0; + unsigned int cbMICHDR = 0; + unsigned int uLength = 0; + unsigned long dwMICKey0, dwMICKey1; + unsigned long dwMIC_Priority; + unsigned long *pdwMIC_L; + unsigned long *pdwMIC_R; + unsigned short wTxBufSize; + unsigned int cbMacHdLen; + SEthernetHeader sEthHeader; + void *pvRrvTime; + void *pMICHDR; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned short wCurrentRate = RATE_1M; + PUWLAN_80211HDR p80211Header; + unsigned int uNodeIndex = 0; + bool bNodeExist = false; + SKeyItem STempKey; + PSKeyItem pTransmitKey = NULL; + unsigned char *pbyIVHead; + unsigned char *pbyPayloadHead; + unsigned char *pbyMacHdr; + + unsigned int cbExtSuppRate = 0; // PWLAN_IE pItem; - pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - - if(cbMPDULen <= WLAN_HDR_ADDR3_LEN) { - cbFrameBodySize = 0; - } - else { - cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN; - } - p80211Header = (PUWLAN_80211HDR)pbMPDU; - - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; - } - - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX to finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { - RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); - } else { - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - } - pTxBufHead->byTxPower = pDevice->byCurPwr; - - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl); - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } - else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } - else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } - else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - - if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) { - bNeedACK = false; - if (pDevice->bEnableHostWEP) { - uNodeIndex = 0; - bNodeExist = true; - } - } - else { - if (pDevice->bEnableHostWEP) { - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex)) - bNodeExist = true; - } - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - }; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) { - - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - //Set Preamble type always long - //pDevice->byPreambleType = PREAMBLE_LONG; - - // probe-response don't retry - //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { - // bNeedACK = false; - // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK); - //} - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - // hostapd deamon ext support rate patch - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) { - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN; - } - - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) { - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - } - - if (cbExtSuppRate >0) { - cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; - } - } - - - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - } - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(SMICHDRHead); - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; - } - - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - } - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() - - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - - pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); - pvRTS = NULL; - pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); - pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); - cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); - - } - else {//802.11a/b packet - - pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); - cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); - - } - - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); - - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); - - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; - - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding); - - // Copy the Packet into a tx Buffer - memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); - - // version set to 0, patch for hostapd deamon - pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); - memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); - - // replace support rate, patch for hostapd deamon( only support 11M) - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - if (cbExtSuppRate != 0) { - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize), - pMgmt->abyCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN - ); - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN, - pMgmt->abyCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN - ); - } - } - - // Set wep - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - - if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - - dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); - - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); - - uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; - - MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); - - pdwMIC_L = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize); - pdwMIC_R = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); - - } - - - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen)); - } - } - - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++ ; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID); - ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID); - } else { - ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID); - } - } - - - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->pTDInfo->skb = skb; - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); - } + pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; + + if (cbMPDULen <= WLAN_HDR_ADDR3_LEN) { + cbFrameBodySize = 0; + } + else { + cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN; + } + p80211Header = (PUWLAN_80211HDR)pbMPDU; + + + pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; + pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; + pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; + wTxBufSize = sizeof(STxBufHead); + memset(pTxBufHead, 0, wTxBufSize); + + if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + wCurrentRate = RATE_6M; + byPktType = PK_TYPE_11A; + } else { + wCurrentRate = RATE_1M; + byPktType = PK_TYPE_11B; + } + + // SetPower will cause error power TX state for OFDM Date packet in TX buffer. + // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. + // And cmd timer will wait data pkt TX to finish before scanning so it's OK + // to set power here. + if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) { + RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); + } else { + RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); + } + pTxBufHead->byTxPower = pDevice->byCurPwr; + + //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ + if (pDevice->byFOETuning) { + if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { + wCurrentRate = RATE_24M; + byPktType = PK_TYPE_11GA; + } + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl); + + //Set packet type + if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 + pTxBufHead->wFIFOCtl = 0; + } + else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11B; + } + else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; + } + else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; + } + + pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; + pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + + + if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) { + bNeedACK = false; + if (pDevice->bEnableHostWEP) { + uNodeIndex = 0; + bNodeExist = true; + } + } + else { + if (pDevice->bEnableHostWEP) { + if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex)) + bNodeExist = true; + } + bNeedACK = true; + pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + }; + + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || + (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { + + pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; + //Set Preamble type always long + //pDevice->byPreambleType = PREAMBLE_LONG; + + // probe-response don't retry + //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) { + // bNeedACK = false; + // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK); + //} + } + + pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); + + if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { + bIsPSPOLL = true; + cbMacHdLen = WLAN_HDR_ADDR2_LEN; + } else { + cbMacHdLen = WLAN_HDR_ADDR3_LEN; + } + + // hostapd deamon ext support rate patch + if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { + + if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) { + cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN; + } + + if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) { + cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + } + + if (cbExtSuppRate > 0) { + cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; + } + } + + + //Set FRAGCTL_MACHDCNT + pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); + + // Notes: + // Although spec says MMPDU can be fragmented; In most cases, + // no one will send a MMPDU under fragmentation. With RTS may occur. + pDevice->bAES = false; //Set FRAGCTL_WEPTYP + + + if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { + if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { + cbIVlen = 4; + cbICVlen = 4; + pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; + } + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + cbIVlen = 8;//IV+ExtIV + cbMIClen = 8; + cbICVlen = 4; + pTxBufHead->wFragCtl |= FRAGCTL_TKIP; + //We need to get seed here for filling TxKey entry. + //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, + // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); + } + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + cbIVlen = 8;//RSN Header + cbICVlen = 8;//MIC + cbMICHDR = sizeof(SMICHDRHead); + pTxBufHead->wFragCtl |= FRAGCTL_AES; + pDevice->bAES = true; + } + //MAC Header should be padding 0 to DW alignment. + uPadding = 4 - (cbMacHdLen%4); + uPadding %= 4; + } + + cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate; + + //Set FIFOCTL_GrpAckPolicy + if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000 + pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; + } + //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() + + + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet + + pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pvRTS = NULL; + pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); + pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); + cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g); + + } + else {//802.11a/b packet + + pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); + pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pvRTS = NULL; + pvCTS = NULL; + pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); + cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); + + } + + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); + //========================= + // No Fragmentation + //========================= + pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; + + + //Fill FIFO,RrvTime,RTS,and CTS + s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, + cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); + + //Fill DataHead + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, + 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + + pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); + + cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; + + pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize); + pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); + pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding); + + // Copy the Packet into a tx Buffer + memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); + + // version set to 0, patch for hostapd deamon + pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); + memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); + + // replace support rate, patch for hostapd deamon(only support 11M) + if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { + if (cbExtSuppRate != 0) { + if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) + memcpy((pbyPayloadHead + cbFrameBodySize), + pMgmt->abyCurrSuppRates, + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN +); + if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) + memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN, + pMgmt->abyCurrExtSuppRates, + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN +); + } + } + + // Set wep + if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { + + if (pDevice->bEnableHostWEP) { + pTransmitKey = &STempKey; + pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; + pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; + pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; + pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; + pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; + memcpy(pTransmitKey->abyKey, + &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], + pTransmitKey->uKeyLength +); + } + + if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { + + dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]); + dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]); + + // DO Software Michael + MIC_vInit(dwMICKey0, dwMICKey1); + MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); + dwMIC_Priority = 0; + MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); + + uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; + + MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); + + pdwMIC_L = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize); + pdwMIC_R = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); + + MIC_vGetMIC(pdwMIC_L, pdwMIC_R); + MIC_vUnInit(); + + if (pDevice->bTxMICFail == true) { + *pdwMIC_L = 0; + *pdwMIC_R = 0; + pDevice->bTxMICFail = false; + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); + + } + + + s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, + pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); + + if (pDevice->bEnableHostWEP) { + pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; + pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; + } + + if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { + s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen)); + } + } + + pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); + pDevice->wSeqCounter++; + if (pDevice->wSeqCounter > 0x0fff) + pDevice->wSeqCounter = 0; + + + if (bIsPSPOLL) { + // The MAC will automatically replace the Duration-field of MAC header by Duration-field + // of FIFO control header. + // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is + // in the same place of other packet's Duration-field). + // And it will cause Cisco-AP to issue Disassociation-packet + if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { + ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID); + ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID); + } else { + ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID); + } + } + + + // first TD is the only TD + //Set TSR1 & ReqCount in TxDescHead + pFrstTD->pTDInfo->skb = skb; + pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); + pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; + pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount); + pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); + pFrstTD->pTDInfo->byFlags = 0; + pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB; + + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { + // Disable PS + MACbPSWakeup(pDevice->PortOffset); + } + pDevice->bPWBitOn = false; + + wmb(); + pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); + + pDevice->iTDUsed[TYPE_TXDMA0]++; + + if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); + } - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; + pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); + // Poll Transmit the adapter + MACvTransmit0(pDevice->PortOffset); - return; + return; } diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index fa827b828a30..b5f0f56216cb 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -40,44 +40,44 @@ /*--------------------- Export Functions --------------------------*/ /* -void -vGenerateMACHeader(PSDevice pDevice, unsigned long dwTxBufferAddr, unsigned char *pbySkbData, - unsigned int cbPacketSize, bool bDMA0Used, unsigned int *pcbHeadSize, - unsigned int *pcbAppendPayload); - -void -vProcessRxMACHeader(PSDevice pDevice, unsigned long dwRxBufferAddr, unsigned int cbPacketSize, - bool bIsWEP, unsigned int *pcbHeadSize); + void + vGenerateMACHeader(PSDevice pDevice, unsigned long dwTxBufferAddr, unsigned char *pbySkbData, + unsigned int cbPacketSize, bool bDMA0Used, unsigned int *pcbHeadSize, + unsigned int *pcbAppendPayload); + + void + vProcessRxMACHeader(PSDevice pDevice, unsigned long dwRxBufferAddr, unsigned int cbPacketSize, + bool bIsWEP, unsigned int *pcbHeadSize); */ void -vGenerateMACHeader ( - PSDevice pDevice, - unsigned char *pbyBufferAddr, - unsigned short wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx - ); +vGenerateMACHeader( + PSDevice pDevice, + unsigned char *pbyBufferAddr, + unsigned short wDuration, + PSEthernetHeader psEthHeader, + bool bNeedEncrypt, + unsigned short wFragType, + unsigned int uDMAIdx, + unsigned int uFragIdx +); unsigned int cbGetFragCount( - PSDevice pDevice, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader - ); + PSDevice pDevice, + PSKeyItem pTransmitKey, + unsigned int cbFrameBodySize, + PSEthernetHeader psEthHeader +); void vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktTyp, unsigned char *pbyTxBufferAddr, - bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum, unsigned int *pcbHeaderSize); + bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, unsigned char *pPacket, PSKeyItem pTransmitKey, + unsigned int uNodeIndex, unsigned int *puMACfragNum, unsigned int *pcbHeaderSize); void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen); -- cgit From 0c979148d2967848713117961a87bfa4b24e8b08 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:02 -0700 Subject: staging:vt6655:srom: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/srom.c | 254 +++++++++++++++++++++--------------------- drivers/staging/vt6655/srom.h | 58 +++++----- 2 files changed, 156 insertions(+), 156 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 6a0a232d1a0c..8c95d1b35967 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -78,36 +78,36 @@ */ unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset) { - unsigned short wDelay, wNoACK; - unsigned char byWait; - unsigned char byData; - unsigned char byOrg; - - byData = 0xFF; - VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - /* turn off hardware retry for getting NACK */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); - for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); - - /* issue read command */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR); - /* wait DONE be set */ - for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { - VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); - if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) - break; - PCAvDelayByIO(CB_DELAY_LOOP_WAIT); - } - if ((wDelay < W_MAX_TIMEOUT) && - ( !(byWait & I2MCSR_NACK))) { - break; - } - } - VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData); - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - return byData; + unsigned short wDelay, wNoACK; + unsigned char byWait; + unsigned char byData; + unsigned char byOrg; + + byData = 0xFF; + VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); + /* turn off hardware retry for getting NACK */ + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); + for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { + VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); + VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); + + /* issue read command */ + VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR); + /* wait DONE be set */ + for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { + VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); + if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) + break; + PCAvDelayByIO(CB_DELAY_LOOP_WAIT); + } + if ((wDelay < W_MAX_TIMEOUT) && + (!(byWait & I2MCSR_NACK))) { + break; + } + } + VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData); + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); + return byData; } @@ -127,40 +127,40 @@ unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntO */ bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byData) { - unsigned short wDelay, wNoACK; - unsigned char byWait; - - unsigned char byOrg; - - VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - /* turn off hardware retry for getting NACK */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); - for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); - VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); - VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData); - - /* issue write command */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW); - /* wait DONE be set */ - for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { - VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); - if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) - break; - PCAvDelayByIO(CB_DELAY_LOOP_WAIT); - } - - if ((wDelay < W_MAX_TIMEOUT) && - ( !(byWait & I2MCSR_NACK))) { - break; - } - } - if (wNoACK == W_MAX_I2CRETRY) { - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - return false; - } - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - return true; + unsigned short wDelay, wNoACK; + unsigned char byWait; + + unsigned char byOrg; + + VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); + /* turn off hardware retry for getting NACK */ + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); + for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { + VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); + VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); + VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData); + + /* issue write command */ + VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW); + /* wait DONE be set */ + for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { + VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); + if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) + break; + PCAvDelayByIO(CB_DELAY_LOOP_WAIT); + } + + if ((wDelay < W_MAX_TIMEOUT) && + (!(byWait & I2MCSR_NACK))) { + break; + } + } + if (wNoACK == W_MAX_I2CRETRY) { + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); + return false; + } + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); + return true; } @@ -180,10 +180,10 @@ bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, un */ void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits) { - unsigned char byOrgData; + unsigned char byOrgData; - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - SROMbWriteEmbedded(dwIoBase, byContntOffset,(unsigned char)(byOrgData | byBits)); + byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); + SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData | byBits)); } @@ -201,10 +201,10 @@ void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsign */ void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits) { - unsigned char byOrgData; + unsigned char byOrgData; - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - SROMbWriteEmbedded(dwIoBase, byContntOffset,(unsigned char)(byOrgData & (~byBits))); + byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); + SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData & (~byBits))); } @@ -224,10 +224,10 @@ void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsig */ bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits) { - unsigned char byOrgData; + unsigned char byOrgData; - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - return (byOrgData & byTestBits) == byTestBits; + byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); + return (byOrgData & byTestBits) == byTestBits; } @@ -247,10 +247,10 @@ bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsi */ bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits) { - unsigned char byOrgData; + unsigned char byOrgData; - byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); - return !(byOrgData & byTestBits); + byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset); + return !(byOrgData & byTestBits); } @@ -268,13 +268,13 @@ bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, uns */ void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs) { - int ii; + int ii; - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase,(unsigned char) ii); - pbyEepromRegs++; - } + /* ii = Rom Address */ + for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { + *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase, (unsigned char)ii); + pbyEepromRegs++; + } } @@ -293,13 +293,13 @@ void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs) */ void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs) { - int ii; + int ii; - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - SROMbWriteEmbedded(dwIoBase,(unsigned char) ii, *pbyEepromRegs); - pbyEepromRegs++; - } + /* ii = Rom Address */ + for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { + SROMbWriteEmbedded(dwIoBase, (unsigned char)ii, *pbyEepromRegs); + pbyEepromRegs++; + } } @@ -317,13 +317,13 @@ void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs) */ void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress) { - unsigned char ii; + unsigned char ii; - /* ii = Rom Address */ - for (ii = 0; ii < ETH_ALEN; ii++) { - *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii); - pbyEtherAddress++; - } + /* ii = Rom Address */ + for (ii = 0; ii < ETH_ALEN; ii++) { + *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii); + pbyEtherAddress++; + } } @@ -342,13 +342,13 @@ void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddres */ void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress) { - unsigned char ii; + unsigned char ii; - /* ii = Rom Address */ - for (ii = 0; ii < ETH_ALEN; ii++) { - SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress); - pbyEtherAddress++; - } + /* ii = Rom Address */ + for (ii = 0; ii < ETH_ALEN; ii++) { + SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress); + pbyEtherAddress++; + } } @@ -366,15 +366,15 @@ void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddre */ void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId) { - unsigned char *pbyData; - - pbyData = (unsigned char *)pdwSubSysVenId; - /* sub vendor */ - *pbyData = SROMbyReadEmbedded(dwIoBase, 6); - *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7); - /* sub system */ - *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8); - *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9); + unsigned char *pbyData; + + pbyData = (unsigned char *)pdwSubSysVenId; + /* sub vendor */ + *pbyData = SROMbyReadEmbedded(dwIoBase, 6); + *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7); + /* sub system */ + *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8); + *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9); } /* @@ -391,30 +391,30 @@ void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId) */ bool SROMbAutoLoad(unsigned long dwIoBase) { - unsigned char byWait; - int ii; + unsigned char byWait; + int ii; - unsigned char byOrg; + unsigned char byOrg; - VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - /* turn on hardware retry */ - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); + VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); + /* turn on hardware retry */ + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); - MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); + MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); - VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); - if ( !(byWait & I2MCSR_AUTOLD)) - break; - } + /* ii = Rom Address */ + for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { + MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); + VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); + if (!(byWait & I2MCSR_AUTOLD)) + break; + } - VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); + VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); - if (ii == EEP_MAX_CONTEXT_SIZE) - return false; - return true; + if (ii == EEP_MAX_CONTEXT_SIZE) + return false; + return true; } diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h index 4c261dac01b5..32cf1093f4f7 100644 --- a/drivers/staging/vt6655/srom.h +++ b/drivers/staging/vt6655/srom.h @@ -97,34 +97,34 @@ // 2048 bits = 256 bytes = 128 words // typedef struct tagSSromReg { - unsigned char abyPAR[6]; // 0x00 (unsigned short) - - unsigned short wSUB_VID; // 0x03 (unsigned short) - unsigned short wSUB_SID; - - unsigned char byBCFG0; // 0x05 (unsigned short) - unsigned char byBCFG1; - - unsigned char byFCR0; // 0x06 (unsigned short) - unsigned char byFCR1; - unsigned char byPMC0; // 0x07 (unsigned short) - unsigned char byPMC1; - unsigned char byMAXLAT; // 0x08 (unsigned short) - unsigned char byMINGNT; - unsigned char byCFG0; // 0x09 (unsigned short) - unsigned char byCFG1; - unsigned short wCISPTR; // 0x0A (unsigned short) - unsigned short wRsv0; // 0x0B (unsigned short) - unsigned short wRsv1; // 0x0C (unsigned short) - unsigned char byBBPAIR; // 0x0D (unsigned short) - unsigned char byRFTYPE; - unsigned char byMinChannel; // 0x0E (unsigned short) - unsigned char byMaxChannel; - unsigned char bySignature; // 0x0F (unsigned short) - unsigned char byCheckSum; - - unsigned char abyReserved0[96]; // 0x10 (unsigned short) - unsigned char abyCIS[128]; // 0x80 (unsigned short) + unsigned char abyPAR[6]; // 0x00 (unsigned short) + + unsigned short wSUB_VID; // 0x03 (unsigned short) + unsigned short wSUB_SID; + + unsigned char byBCFG0; // 0x05 (unsigned short) + unsigned char byBCFG1; + + unsigned char byFCR0; // 0x06 (unsigned short) + unsigned char byFCR1; + unsigned char byPMC0; // 0x07 (unsigned short) + unsigned char byPMC1; + unsigned char byMAXLAT; // 0x08 (unsigned short) + unsigned char byMINGNT; + unsigned char byCFG0; // 0x09 (unsigned short) + unsigned char byCFG1; + unsigned short wCISPTR; // 0x0A (unsigned short) + unsigned short wRsv0; // 0x0B (unsigned short) + unsigned short wRsv1; // 0x0C (unsigned short) + unsigned char byBBPAIR; // 0x0D (unsigned short) + unsigned char byRFTYPE; + unsigned char byMinChannel; // 0x0E (unsigned short) + unsigned char byMaxChannel; + unsigned char bySignature; // 0x0F (unsigned short) + unsigned char byCheckSum; + + unsigned char abyReserved0[96]; // 0x10 (unsigned short) + unsigned char abyCIS[128]; // 0x80 (unsigned short) } SSromReg, *PSSromReg; /*--------------------- Export Macros ------------------------------*/ @@ -152,6 +152,6 @@ void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddre void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId); -bool SROMbAutoLoad (unsigned long dwIoBase); +bool SROMbAutoLoad(unsigned long dwIoBase); #endif // __EEPROM_H__ -- cgit From 9eb6c753363a2b366dc79a137daa8bd2e050df10 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:03 -0700 Subject: staging:vt6655:tcrc: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/tcrc.c | 156 +++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c index 1313c4cd0860..ec14033b0116 100644 --- a/drivers/staging/vt6655/tcrc.c +++ b/drivers/staging/vt6655/tcrc.c @@ -43,70 +43,70 @@ // 32-bit CRC table static const unsigned long s_adwCrc32Table[256] = { - 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, - 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, - 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, - 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, - 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, - 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, - 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, - 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, - 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, - 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, - 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, - 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, - 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, - 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, - 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, - 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, - 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, - 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, - 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, - 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, - 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, - 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, - 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, - 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, - 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, - 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, - 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, - 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, - 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, - 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, - 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, - 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, - 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, - 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, - 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, - 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, - 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, - 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, - 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, - 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, - 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, - 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, - 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, - 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, - 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, - 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, - 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, - 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, - 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, - 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, - 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, - 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, - 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, - 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, - 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, - 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, - 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, - 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, - 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, - 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, - 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, - 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, - 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, - 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL }; /*--------------------- Static Functions --------------------------*/ @@ -131,18 +131,18 @@ static const unsigned long s_adwCrc32Table[256] = { * * Return Value: CRC-32 * --*/ -unsigned long CRCdwCrc32 (unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed) + -*/ +unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed) { - unsigned long dwCrc; + unsigned long dwCrc; - dwCrc = dwCrcSeed; - while (cbByte--) { - dwCrc = s_adwCrc32Table[(unsigned char)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); - pbyData++; - } + dwCrc = dwCrcSeed; + while (cbByte--) { + dwCrc = s_adwCrc32Table[(unsigned char)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); + pbyData++; + } - return dwCrc; + return dwCrc; } @@ -163,10 +163,10 @@ unsigned long CRCdwCrc32 (unsigned char *pbyData, unsigned int cbByte, unsigned * * Return Value: CRC-32 * --*/ -unsigned long CRCdwGetCrc32 (unsigned char *pbyData, unsigned int cbByte) + -*/ +unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte) { - return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); + return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); } @@ -189,10 +189,10 @@ unsigned long CRCdwGetCrc32 (unsigned char *pbyData, unsigned int cbByte) * * Return Value: CRC-32 * --*/ + -*/ unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC) { - return CRCdwCrc32(pbyData, cbByte, dwPreCRC); + return CRCdwCrc32(pbyData, cbByte, dwPreCRC); } -- cgit From 947f9a0273425473a9b86bcb23d04f15a5823cf5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:04 -0700 Subject: staging:vt6655:tether: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/tether.c | 46 ++++++++++++++++++++--------------------- drivers/staging/vt6655/tether.h | 34 +++++++++++++++--------------- 2 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c index 28554bf75549..26dc89aa1a7b 100644 --- a/drivers/staging/vt6655/tether.c +++ b/drivers/staging/vt6655/tether.c @@ -61,25 +61,25 @@ * Return Value: Hash value * */ -unsigned char ETHbyGetHashIndexByCrc32 (unsigned char *pbyMultiAddr) +unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr) { - int ii; - unsigned char byTmpHash; - unsigned char byHash = 0; + int ii; + unsigned char byTmpHash; + unsigned char byHash = 0; - // get the least 6-bits from CRC generator - byTmpHash = (unsigned char)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, - 0xFFFFFFFFL) & 0x3F); - // reverse most bit to least bit - for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { - byHash <<= 1; - if (byTmpHash & 0x01) - byHash |= 1; - byTmpHash >>= 1; - } + // get the least 6-bits from CRC generator + byTmpHash = (unsigned char)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, + 0xFFFFFFFFL) & 0x3F); + // reverse most bit to least bit + for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { + byHash <<= 1; + if (byTmpHash & 0x01) + byHash |= 1; + byTmpHash >>= 1; + } - // adjust 6-bits to the right most - return (byHash >> 2); + // adjust 6-bits to the right most + return (byHash >> 2); } @@ -96,14 +96,14 @@ unsigned char ETHbyGetHashIndexByCrc32 (unsigned char *pbyMultiAddr) * Return Value: true if ok; false if error. * */ -bool ETHbIsBufferCrc32Ok (unsigned char *pbyBuffer, unsigned int cbFrameLength) +bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength) { - unsigned long dwCRC; + unsigned long dwCRC; - dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); - if (cpu_to_le32(*((unsigned long *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) { - return false; - } - return true; + dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); + if (cpu_to_le32(*((unsigned long *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) { + return false; + } + return true; } diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index 6a68f97d9a32..0c0a625e9c80 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -37,7 +37,7 @@ // constants // #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) - // Ethernet address string length +// Ethernet address string length #define MAX_LOOKAHEAD_SIZE ETH_FRAME_LEN @@ -151,10 +151,10 @@ // Ethernet packet // typedef struct tagSEthernetHeader { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wType; -}__attribute__ ((__packed__)) + unsigned char abyDstAddr[ETH_ALEN]; + unsigned char abySrcAddr[ETH_ALEN]; + unsigned short wType; +} __attribute__ ((__packed__)) SEthernetHeader, *PSEthernetHeader; @@ -162,24 +162,24 @@ SEthernetHeader, *PSEthernetHeader; // 802_3 packet // typedef struct tagS802_3Header { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wLen; -}__attribute__ ((__packed__)) + unsigned char abyDstAddr[ETH_ALEN]; + unsigned char abySrcAddr[ETH_ALEN]; + unsigned short wLen; +} __attribute__ ((__packed__)) S802_3Header, *PS802_3Header; // // 802_11 packet // typedef struct tagS802_11Header { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[ETH_ALEN]; - unsigned char abyAddr2[ETH_ALEN]; - unsigned char abyAddr3[ETH_ALEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[ETH_ALEN]; -}__attribute__ ((__packed__)) + unsigned short wFrameCtl; + unsigned short wDurationID; + unsigned char abyAddr1[ETH_ALEN]; + unsigned char abyAddr2[ETH_ALEN]; + unsigned char abyAddr3[ETH_ALEN]; + unsigned short wSeqCtl; + unsigned char abyAddr4[ETH_ALEN]; +} __attribute__ ((__packed__)) S802_11Header, *PS802_11Header; /*--------------------- Export Macros ------------------------------*/ -- cgit From 5fd36ba5f577b7828aa0ce04cd1372aeec62cdf7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:05 -0700 Subject: staging:vt6655:tkip: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/tkip.c | 328 +++++++++++++++++++++--------------------- drivers/staging/vt6655/tkip.h | 12 +- 2 files changed, 170 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c index f141ba1cbb9b..ccdcdf5731c9 100644 --- a/drivers/staging/vt6655/tkip.c +++ b/drivers/staging/vt6655/tkip.c @@ -56,73 +56,73 @@ /* bytes swapped. To allow an endian tolerant implementation, the byte */ /* halves have been expressed independently here. */ const unsigned char TKIP_Sbox_Lower[256] = { - 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, - 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, - 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, - 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, - 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, - 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, - 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, - 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, - 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, - 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, - 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, - 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, - 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, - 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, - 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, - 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, - 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, - 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, - 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, - 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, - 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, - 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, - 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, - 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, - 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, - 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, - 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, - 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, - 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, - 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, - 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, - 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A + 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54, + 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A, + 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B, + 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B, + 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F, + 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F, + 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5, + 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F, + 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB, + 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97, + 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED, + 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A, + 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94, + 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3, + 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04, + 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D, + 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39, + 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95, + 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83, + 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76, + 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4, + 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B, + 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0, + 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18, + 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51, + 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85, + 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12, + 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9, + 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7, + 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A, + 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8, + 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A }; const unsigned char TKIP_Sbox_Upper[256] = { - 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, - 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, - 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, - 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, - 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, - 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, - 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, - 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, - 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, - 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, - 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, - 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, - 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, - 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, - 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, - 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, - 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, - 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, - 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, - 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, - 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, - 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, - 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, - 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, - 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, - 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, - 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, - 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, - 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, - 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, - 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, - 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C + 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91, + 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC, + 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB, + 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B, + 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83, + 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A, + 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F, + 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA, + 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B, + 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13, + 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6, + 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85, + 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11, + 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B, + 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1, + 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF, + 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E, + 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6, + 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B, + 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD, + 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8, + 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2, + 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49, + 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10, + 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97, + 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F, + 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C, + 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27, + 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33, + 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5, + 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0, + 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C }; @@ -141,31 +141,31 @@ unsigned int rotr1(unsigned int a); /************************************************************/ unsigned int tkip_sbox(unsigned int index) { - unsigned int index_low; - unsigned int index_high; - unsigned int left, right; + unsigned int index_low; + unsigned int index_high; + unsigned int left, right; - index_low = (index % 256); - index_high = ((index >> 8) % 256); + index_low = (index % 256); + index_high = ((index >> 8) % 256); - left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256); - right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256); + left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256); + right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256); - return (left ^ right); + return (left ^ right); }; unsigned int rotr1(unsigned int a) { - unsigned int b; - - if ((a & 0x01) == 0x01) { - b = (a >> 1) | 0x8000; - } else { - b = (a >> 1) & 0x7fff; - } - b = b % 65536; - return b; + unsigned int b; + + if ((a & 0x01) == 0x01) { + b = (a >> 1) | 0x8000; + } else { + b = (a >> 1) & 0x7fff; + } + b = b % 65536; + return b; } @@ -184,89 +184,89 @@ unsigned int rotr1(unsigned int a) * */ void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key - ) + unsigned char *pbyTKey, + unsigned char *pbyTA, + unsigned short wTSC15_0, + unsigned long dwTSC47_16, + unsigned char *pbyRC4Key +) { - unsigned int p1k[5]; + unsigned int p1k[5]; // unsigned int ttak0, ttak1, ttak2, ttak3, ttak4; - unsigned int tsc0, tsc1, tsc2; - unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; - unsigned long int pnl,pnh; - - int i, j; - - pnl = wTSC15_0; - pnh = dwTSC47_16; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256)); - p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256)); - p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256)); - - /* Phase 1, step 2 */ - for (i=0; i<8; i++) { - j = 2*(i & 1); - p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536 )) % 65536; - p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536 )) % 65536; - p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536 )) % 65536; - p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536 )) % 65536; - p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536 )) % 65536; - p1k[4] = (p1k[4] + i) % 65536; - } - /* Phase 2, Step 1 */ - ppk0 = p1k[0]; - ppk1 = p1k[1]; - ppk2 = p1k[2]; - ppk3 = p1k[3]; - ppk4 = p1k[4]; - ppk5 = (p1k[4] + tsc2) % 65536; - - /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); - ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); - ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); - ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); - ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); - ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); - - /* Phase 2, Step 3 */ - pbyRC4Key[0] = (tsc2 >> 8) % 256; - pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; - pbyRC4Key[2] = tsc2 % 256; - pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256; - - pbyRC4Key[4] = ppk0 % 256; - pbyRC4Key[5] = (ppk0 >> 8) % 256; - - pbyRC4Key[6] = ppk1 % 256; - pbyRC4Key[7] = (ppk1 >> 8) % 256; - - pbyRC4Key[8] = ppk2 % 256; - pbyRC4Key[9] = (ppk2 >> 8) % 256; - - pbyRC4Key[10] = ppk3 % 256; - pbyRC4Key[11] = (ppk3 >> 8) % 256; - - pbyRC4Key[12] = ppk4 % 256; - pbyRC4Key[13] = (ppk4 >> 8) % 256; - - pbyRC4Key[14] = ppk5 % 256; - pbyRC4Key[15] = (ppk5 >> 8) % 256; + unsigned int tsc0, tsc1, tsc2; + unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; + unsigned long int pnl, pnh; + + int i, j; + + pnl = wTSC15_0; + pnh = dwTSC47_16; + + tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ + tsc1 = (unsigned int)(pnh % 65536); + tsc2 = (unsigned int)(pnl % 65536); /* lsb */ + + /* Phase 1, step 1 */ + p1k[0] = tsc1; + p1k[1] = tsc0; + p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256)); + p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256)); + p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256)); + + /* Phase 1, step 2 */ + for (i = 0; i < 8; i++) { + j = 2 * (i & 1); + p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536; + p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536; + p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536; + p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536; + p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536; + p1k[4] = (p1k[4] + i) % 65536; + } + /* Phase 2, Step 1 */ + ppk0 = p1k[0]; + ppk1 = p1k[1]; + ppk2 = p1k[2]; + ppk3 = p1k[3]; + ppk4 = p1k[4]; + ppk5 = (p1k[4] + tsc2) % 65536; + + /* Phase2, Step 2 */ + ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); + ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); + ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); + ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); + ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); + ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); + + ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); + ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); + ppk2 = ppk2 + rotr1(ppk1); + ppk3 = ppk3 + rotr1(ppk2); + ppk4 = ppk4 + rotr1(ppk3); + ppk5 = ppk5 + rotr1(ppk4); + + /* Phase 2, Step 3 */ + pbyRC4Key[0] = (tsc2 >> 8) % 256; + pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; + pbyRC4Key[2] = tsc2 % 256; + pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256; + + pbyRC4Key[4] = ppk0 % 256; + pbyRC4Key[5] = (ppk0 >> 8) % 256; + + pbyRC4Key[6] = ppk1 % 256; + pbyRC4Key[7] = (ppk1 >> 8) % 256; + + pbyRC4Key[8] = ppk2 % 256; + pbyRC4Key[9] = (ppk2 >> 8) % 256; + + pbyRC4Key[10] = ppk3 % 256; + pbyRC4Key[11] = (ppk3 >> 8) % 256; + + pbyRC4Key[12] = ppk4 % 256; + pbyRC4Key[13] = (ppk4 >> 8) % 256; + + pbyRC4Key[14] = ppk5 % 256; + pbyRC4Key[15] = (ppk5 >> 8) % 256; } diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h index eb5951d726e0..b7191fac753d 100644 --- a/drivers/staging/vt6655/tkip.h +++ b/drivers/staging/vt6655/tkip.h @@ -47,12 +47,12 @@ /*--------------------- Export Functions --------------------------*/ void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key - ); + unsigned char *pbyTKey, + unsigned char *pbyTA, + unsigned short wTSC15_0, + unsigned long dwTSC47_16, + unsigned char *pbyRC4Key +); #endif // __TKIP_H__ -- cgit From 76dffe6435efee37e57efefb264a6a3b481e77fc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:06 -0700 Subject: staging:vt6655:ttype: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ttype.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index be223bd25d2c..114ac3024e4e 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -56,16 +56,16 @@ // an 8-byte-aligned 8 byte long structure // which is NOT really a floating point number. typedef union tagUQuadWord { - struct { - unsigned int dwLowDword; - unsigned int dwHighDword; - } u; - double DoNotUseThisField; + struct { + unsigned int dwLowDword; + unsigned int dwHighDword; + } u; + double DoNotUseThisField; } UQuadWord; typedef UQuadWord QWORD; // 64-bit /****** Common pointer types ***********************************************/ -typedef QWORD * PQWORD; +typedef QWORD *PQWORD; #endif // __TTYPE_H__ -- cgit From 031d3996ec3d33d100f272cd4dd0311a95e347e2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:07 -0700 Subject: staging:vt6655:upc: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/upc.h | 136 +++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index 9596fdef0e3c..af6413694302 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -41,32 +41,32 @@ #ifdef IO_MAP -#define VNSvInPortB(dwIOAddress, pbyData) { \ - *(pbyData) = inb(dwIOAddress); \ -} +#define VNSvInPortB(dwIOAddress, pbyData) { \ + *(pbyData) = inb(dwIOAddress); \ + } -#define VNSvInPortW(dwIOAddress, pwData) { \ - *(pwData) = inw(dwIOAddress); \ -} +#define VNSvInPortW(dwIOAddress, pwData) { \ + *(pwData) = inw(dwIOAddress); \ + } -#define VNSvInPortD(dwIOAddress, pdwData) { \ - *(pdwData) = inl(dwIOAddress); \ -} +#define VNSvInPortD(dwIOAddress, pdwData) { \ + *(pdwData) = inl(dwIOAddress); \ + } -#define VNSvOutPortB(dwIOAddress, byData) { \ - outb(byData, dwIOAddress); \ -} +#define VNSvOutPortB(dwIOAddress, byData) { \ + outb(byData, dwIOAddress); \ + } -#define VNSvOutPortW(dwIOAddress, wData) { \ - outw(wData, dwIOAddress); \ -} +#define VNSvOutPortW(dwIOAddress, wData) { \ + outw(wData, dwIOAddress); \ + } -#define VNSvOutPortD(dwIOAddress, dwData) { \ - outl(dwData, dwIOAddress); \ -} +#define VNSvOutPortD(dwIOAddress, dwData) { \ + outl(dwData, dwIOAddress); \ + } #else @@ -75,38 +75,38 @@ // -#define VNSvInPortB(dwIOAddress, pbyData) { \ - volatile unsigned char * pbyAddr = ((unsigned char *)(dwIOAddress)); \ - *(pbyData) = readb(pbyAddr); \ -} +#define VNSvInPortB(dwIOAddress, pbyData) { \ + volatile unsigned char *pbyAddr = ((unsigned char *)(dwIOAddress)); \ + *(pbyData) = readb(pbyAddr); \ + } -#define VNSvInPortW(dwIOAddress, pwData) { \ - volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress)); \ - *(pwData) = readw(pwAddr); \ -} +#define VNSvInPortW(dwIOAddress, pwData) { \ + volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress)); \ + *(pwData) = readw(pwAddr); \ + } -#define VNSvInPortD(dwIOAddress, pdwData) { \ - volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress)); \ - *(pdwData) = readl(pdwAddr); \ -} +#define VNSvInPortD(dwIOAddress, pdwData) { \ + volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress)); \ + *(pdwData) = readl(pdwAddr); \ + } -#define VNSvOutPortB(dwIOAddress, byData) { \ - volatile unsigned char * pbyAddr = ((unsigned char *)(dwIOAddress)); \ - writeb((unsigned char)byData, pbyAddr); \ -} +#define VNSvOutPortB(dwIOAddress, byData) { \ + volatile unsigned char *pbyAddr = ((unsigned char *)(dwIOAddress)); \ + writeb((unsigned char)byData, pbyAddr); \ + } -#define VNSvOutPortW(dwIOAddress, wData) { \ - volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress)); \ - writew((unsigned short)wData, pwAddr); \ -} +#define VNSvOutPortW(dwIOAddress, wData) { \ + volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress)); \ + writew((unsigned short)wData, pwAddr); \ + } -#define VNSvOutPortD(dwIOAddress, dwData) { \ - volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress)); \ - writel((unsigned long)dwData, pdwAddr); \ -} +#define VNSvOutPortD(dwIOAddress, dwData) { \ + volatile unsigned long *pdwAddr = ((unsigned long *)(dwIOAddress)); \ + writel((unsigned long)dwData, pdwAddr); \ + } #endif @@ -115,42 +115,42 @@ // ALWAYS IO-Mapped IO when in 16-bit/32-bit environment // #define PCBvInPortB(dwIOAddress, pbyData) { \ - *(pbyData) = inb(dwIOAddress); \ -} + *(pbyData) = inb(dwIOAddress); \ + } #define PCBvInPortW(dwIOAddress, pwData) { \ - *(pwData) = inw(dwIOAddress); \ -} + *(pwData) = inw(dwIOAddress); \ + } #define PCBvInPortD(dwIOAddress, pdwData) { \ - *(pdwData) = inl(dwIOAddress); \ -} + *(pdwData) = inl(dwIOAddress); \ + } #define PCBvOutPortB(dwIOAddress, byData) { \ - outb(byData, dwIOAddress); \ -} + outb(byData, dwIOAddress); \ + } #define PCBvOutPortW(dwIOAddress, wData) { \ - outw(wData, dwIOAddress); \ -} + outw(wData, dwIOAddress); \ + } #define PCBvOutPortD(dwIOAddress, dwData) { \ - outl(dwData, dwIOAddress); \ -} - - -#define PCAvDelayByIO(uDelayUnit) { \ - unsigned char byData; \ - unsigned long ii; \ - \ - if (uDelayUnit <= 50) { \ - udelay(uDelayUnit); \ - } \ - else { \ - for (ii = 0; ii < (uDelayUnit); ii++) \ - byData = inb(0x61); \ - } \ -} + outl(dwData, dwIOAddress); \ + } + + +#define PCAvDelayByIO(uDelayUnit) { \ + unsigned char byData; \ + unsigned long ii; \ + \ + if (uDelayUnit <= 50) { \ + udelay(uDelayUnit); \ + } \ + else { \ + for (ii = 0; ii < (uDelayUnit); ii++) \ + byData = inb(0x61); \ + } \ + } /*--------------------- Export Classes ----------------------------*/ -- cgit From d9d644edc358b854a63a28bc4601c4268d5c8344 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:08 -0700 Subject: staging:vt6655:vntwifi: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/vntwifi.c | 906 +++++++++++++++++++-------------------- drivers/staging/vt6655/vntwifi.h | 258 +++++------ 2 files changed, 582 insertions(+), 582 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 62c44b87d310..221c89053786 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -66,16 +66,16 @@ * * Return Value: none * --*/ + -*/ void -VNTWIFIvSetOPMode ( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode - ) +VNTWIFIvSetOPMode( + void *pMgmtHandle, + WMAC_CONFIG_MODE eOPMode +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - pMgmt->eConfigMode = eOPMode; + pMgmt->eConfigMode = eOPMode; } @@ -95,20 +95,20 @@ VNTWIFIvSetOPMode ( * * Return Value: none * --*/ + -*/ void -VNTWIFIvSetIBSSParameter ( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel - ) +VNTWIFIvSetIBSSParameter( + void *pMgmtHandle, + unsigned short wBeaconPeriod, + unsigned short wATIMWindow, + unsigned int uChannel +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - pMgmt->wIBSSBeaconPeriod = wBeaconPeriod; - pMgmt->wIBSSATIMWindow = wATIMWindow; - pMgmt->uIBSSChannel = uChannel; + pMgmt->wIBSSBeaconPeriod = wBeaconPeriod; + pMgmt->wIBSSATIMWindow = wATIMWindow; + pMgmt->uIBSSChannel = uChannel; } /*+ @@ -124,14 +124,14 @@ VNTWIFIvSetIBSSParameter ( * * Return Value: current SSID pointer. * --*/ + -*/ PWLAN_IE_SSID -VNTWIFIpGetCurrentSSID ( - void *pMgmtHandle - ) +VNTWIFIpGetCurrentSSID( + void *pMgmtHandle +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - return((PWLAN_IE_SSID) pMgmt->abyCurrSSID); + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + return((PWLAN_IE_SSID) pMgmt->abyCurrSSID); } /*+ @@ -147,17 +147,17 @@ VNTWIFIpGetCurrentSSID ( * * Return Value: current Channel. * --*/ + -*/ unsigned int -VNTWIFIpGetCurrentChannel ( - void *pMgmtHandle - ) +VNTWIFIpGetCurrentChannel( + void *pMgmtHandle +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - if (pMgmtHandle != NULL) { - return (pMgmt->uCurrChannel); - } - return 0; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + if (pMgmtHandle != NULL) { + return (pMgmt->uCurrChannel); + } + return 0; } /*+ @@ -173,14 +173,14 @@ VNTWIFIpGetCurrentChannel ( * * Return Value: current Assoc ID * --*/ + -*/ unsigned short -VNTWIFIwGetAssocID ( - void *pMgmtHandle - ) +VNTWIFIwGetAssocID( + void *pMgmtHandle +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - return(pMgmt->wCurrAID); + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + return(pMgmt->wCurrAID); } @@ -199,35 +199,35 @@ VNTWIFIwGetAssocID ( * * Return Value: max support rate * --*/ + -*/ unsigned char -VNTWIFIbyGetMaxSupportRate ( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs - ) +VNTWIFIbyGetMaxSupportRate( + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs +) { - unsigned char byMaxSupportRate = RATE_1M; - unsigned char bySupportRate = RATE_1M; - unsigned int ii = 0; - - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); - if (bySupportRate > byMaxSupportRate) { - byMaxSupportRate = bySupportRate; - } - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); - if (bySupportRate > byMaxSupportRate) { - byMaxSupportRate = bySupportRate; - } - } - } - - return byMaxSupportRate; + unsigned char byMaxSupportRate = RATE_1M; + unsigned char bySupportRate = RATE_1M; + unsigned int ii = 0; + + if (pSupportRateIEs) { + for (ii = 0; ii < pSupportRateIEs->len; ii++) { + bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); + if (bySupportRate > byMaxSupportRate) { + byMaxSupportRate = bySupportRate; + } + } + } + if (pExtSupportRateIEs) { + for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { + bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); + if (bySupportRate > byMaxSupportRate) { + byMaxSupportRate = bySupportRate; + } + } + } + + return byMaxSupportRate; } /*+ @@ -245,48 +245,48 @@ VNTWIFIbyGetMaxSupportRate ( * * Return Value: max support rate * --*/ + -*/ unsigned char -VNTWIFIbyGetACKTxRate ( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs - ) +VNTWIFIbyGetACKTxRate( + unsigned char byRxDataRate, + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs +) { - unsigned char byMaxAckRate; - unsigned char byBasicRate; - unsigned int ii; - - if (byRxDataRate <= RATE_11M) { - byMaxAckRate = RATE_1M; - } else { - // 24M is mandatory for 802.11a and 802.11g - byMaxAckRate = RATE_24M; - } - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - if (pSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } - } - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - if (pExtSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } - } - } - } - - return byMaxAckRate; + unsigned char byMaxAckRate; + unsigned char byBasicRate; + unsigned int ii; + + if (byRxDataRate <= RATE_11M) { + byMaxAckRate = RATE_1M; + } else { + // 24M is mandatory for 802.11a and 802.11g + byMaxAckRate = RATE_24M; + } + if (pSupportRateIEs) { + for (ii = 0; ii < pSupportRateIEs->len; ii++) { + if (pSupportRateIEs->abyRates[ii] & 0x80) { + byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); + if ((byBasicRate <= byRxDataRate) && + (byBasicRate > byMaxAckRate)) { + byMaxAckRate = byBasicRate; + } + } + } + } + if (pExtSupportRateIEs) { + for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { + if (pExtSupportRateIEs->abyRates[ii] & 0x80) { + byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); + if ((byBasicRate <= byRxDataRate) && + (byBasicRate > byMaxAckRate)) { + byMaxAckRate = byBasicRate; + } + } + } + } + + return byMaxAckRate; } /*+ @@ -303,22 +303,22 @@ VNTWIFIbyGetACKTxRate ( * * Return Value: none * --*/ + -*/ void -VNTWIFIvSetAuthenticationMode ( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode - ) +VNTWIFIvSetAuthenticationMode( + void *pMgmtHandle, + WMAC_AUTHENTICATION_MODE eAuthMode +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eAuthenMode = eAuthMode; - if ((eAuthMode == WMAC_AUTH_SHAREKEY) || - (eAuthMode == WMAC_AUTH_AUTO)) { - pMgmt->bShareKeyAlgorithm = true; - } else { - pMgmt->bShareKeyAlgorithm = false; - } + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + + pMgmt->eAuthenMode = eAuthMode; + if ((eAuthMode == WMAC_AUTH_SHAREKEY) || + (eAuthMode == WMAC_AUTH_AUTO)) { + pMgmt->bShareKeyAlgorithm = true; + } else { + pMgmt->bShareKeyAlgorithm = false; + } } /*+ @@ -335,59 +335,59 @@ VNTWIFIvSetAuthenticationMode ( * * Return Value: none * --*/ + -*/ void -VNTWIFIvSetEncryptionMode ( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode - ) +VNTWIFIvSetEncryptionMode( + void *pMgmtHandle, + WMAC_ENCRYPTION_MODE eEncryptionMode +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eEncryptionMode = eEncryptionMode; - if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled) ) { - pMgmt->bPrivacyInvoked = true; - } else { - pMgmt->bPrivacyInvoked = false; - } + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + + pMgmt->eEncryptionMode = eEncryptionMode; + if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) || + (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) || + (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled)) { + pMgmt->bPrivacyInvoked = true; + } else { + pMgmt->bPrivacyInvoked = false; + } } bool -VNTWIFIbConfigPhyMode ( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType - ) +VNTWIFIbConfigPhyMode( + void *pMgmtHandle, + CARD_PHY_TYPE ePhyType +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if ((ePhyType != PHY_TYPE_AUTO) && - (ePhyType != pMgmt->eCurrentPHYMode)) { - if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL)==true) { - pMgmt->eCurrentPHYMode = ePhyType; - } else { - return(false); - } - } - pMgmt->eConfigPHYMode = ePhyType; - return(true); + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + + if ((ePhyType != PHY_TYPE_AUTO) && + (ePhyType != pMgmt->eCurrentPHYMode)) { + if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL) == true) { + pMgmt->eCurrentPHYMode = ePhyType; + } else { + return(false); + } + } + pMgmt->eConfigPHYMode = ePhyType; + return(true); } void -VNTWIFIbGetConfigPhyMode ( - void *pMgmtHandle, - void *pePhyType - ) +VNTWIFIbGetConfigPhyMode( + void *pMgmtHandle, + void *pePhyType +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - if ((pMgmt != NULL) && (pePhyType != NULL)) { - *(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode; - } + if ((pMgmt != NULL) && (pePhyType != NULL)) { + *(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode; + } } /*+ @@ -403,7 +403,7 @@ VNTWIFIbGetConfigPhyMode ( * * Return Value: None. * --*/ + -*/ /*+ @@ -420,56 +420,56 @@ VNTWIFIbGetConfigPhyMode ( * * Return Value: None. * --*/ + -*/ void VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, void **pvFirstBSS) { - unsigned int ii = 0; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - PKnownBSS pBSS = NULL; - unsigned int uCount = 0; - - *pvFirstBSS = NULL; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) { - continue; - } - if (*pvFirstBSS == NULL) { - *pvFirstBSS = &(pMgmt->sBSSList[ii]); - } - uCount++; - } - *puBSSCount = uCount; + unsigned int ii = 0; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + PKnownBSS pBSS = NULL; + unsigned int uCount = 0; + + *pvFirstBSS = NULL; + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pBSS = &(pMgmt->sBSSList[ii]); + if (!pBSS->bActive) { + continue; + } + if (*pvFirstBSS == NULL) { + *pvFirstBSS = &(pMgmt->sBSSList[ii]); + } + uCount++; + } + *puBSSCount = uCount; } void -VNTWIFIvGetNextBSS ( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS - ) +VNTWIFIvGetNextBSS( + void *pMgmtHandle, + void *pvCurrentBSS, + void **pvNextBSS +) { - PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - *pvNextBSS = NULL; - - while (*pvNextBSS == NULL) { - pBSS++; - if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) { - return; - } - if (pBSS->bActive == true) { - *pvNextBSS = pBSS; - return; - } - } + PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + + *pvNextBSS = NULL; + + while (*pvNextBSS == NULL) { + pBSS++; + if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) { + return; + } + if (pBSS->bActive == true) { + *pvNextBSS = pBSS; + return; + } + } } @@ -487,319 +487,319 @@ VNTWIFIvGetNextBSS ( * * Return Value: none * --*/ + -*/ void VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount - ) + void *pMgmtHandle, + unsigned char *pbyDestAddress, + bool bTxOk, + unsigned short wRate, + unsigned char *pbyTxFailCount +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; - unsigned int ii; - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) { - return; - } - } - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; - if (bTxOk == true) { - // transmit success, TxAttempts at least plus one - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; - for(ii=0;iisNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; - } - return; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + unsigned int uNodeIndex = 0; + unsigned int ii; + + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || + (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { + if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) { + return; + } + } + pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; + if (bTxOk == true) { + // transmit success, TxAttempts at least plus one + pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; + pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; + } else { + pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; + } + pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; + for (ii = 0; ii < MAX_RATE; ii++) { + pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; + } + return; } void VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate - ) + void *pMgmtHandle, + unsigned char *pbyDestAddress, + unsigned short *pwTxDataRate, + unsigned char *pbyACKRate, + unsigned char *pbyCCKBasicRate, + unsigned char *pbyOFDMBasicRate +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; - unsigned short wTxDataRate = RATE_1M; - unsigned char byACKRate = RATE_1M; - unsigned char byCCKBasicRate = RATE_1M; - unsigned char byOFDMBasicRate = RATE_24M; - PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL; - PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL; - - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - // Adhoc Tx rate decided from node DB - if(BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) { - wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates); - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates); - } else { - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { - wTxDataRate = RATE_2M; - } else { - wTxDataRate = RATE_24M; - } - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } - } else { // Infrastructure: rate decided from AP Node, index = 0 + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + unsigned int uNodeIndex = 0; + unsigned short wTxDataRate = RATE_1M; + unsigned char byACKRate = RATE_1M; + unsigned char byCCKBasicRate = RATE_1M; + unsigned char byOFDMBasicRate = RATE_24M; + PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL; + PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL; + + + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || + (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { + // Adhoc Tx rate decided from node DB + if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) { + wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); + pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates); + pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates); + } else { + if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { + wTxDataRate = RATE_2M; + } else { + wTxDataRate = RATE_24M; + } + pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; + pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; + } + } else { // Infrastructure: rate decided from AP Node, index = 0 wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate); #ifdef PLICE_DEBUG printk(KERN_DEBUG "GetTxRate:AP MAC is %pM,TxRate is %d\n", - pMgmt->sNodeDBTable[0].abyMACAddr, wTxDataRate); + pMgmt->sNodeDBTable[0].abyMACAddr, wTxDataRate); #endif - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } - byACKRate = VNTWIFIbyGetACKTxRate( (unsigned char) wTxDataRate, - pSupportRateIEs, - pExtSupportRateIEs - ); - if (byACKRate > (unsigned char) wTxDataRate) { - byACKRate = (unsigned char) wTxDataRate; - } - byCCKBasicRate = VNTWIFIbyGetACKTxRate( RATE_11M, - pSupportRateIEs, - pExtSupportRateIEs - ); - byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M, - pSupportRateIEs, - pExtSupportRateIEs - ); - *pwTxDataRate = wTxDataRate; - *pbyACKRate = byACKRate; - *pbyCCKBasicRate = byCCKBasicRate; - *pbyOFDMBasicRate = byOFDMBasicRate; - return; + pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; + pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; + } + byACKRate = VNTWIFIbyGetACKTxRate((unsigned char) wTxDataRate, + pSupportRateIEs, + pExtSupportRateIEs +); + if (byACKRate > (unsigned char) wTxDataRate) { + byACKRate = (unsigned char) wTxDataRate; + } + byCCKBasicRate = VNTWIFIbyGetACKTxRate(RATE_11M, + pSupportRateIEs, + pExtSupportRateIEs +); + byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M, + pSupportRateIEs, + pExtSupportRateIEs +); + *pwTxDataRate = wTxDataRate; + *pbyACKRate = byACKRate; + *pbyCCKBasicRate = byCCKBasicRate; + *pbyOFDMBasicRate = byOFDMBasicRate; + return; } unsigned char VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey - ) + void *pMgmtHandle, + bool bGroupKey +) { - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; + PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - if (bGroupKey == true) { - return (pMgmt->byCSSGK); - } else { - return (pMgmt->byCSSPK); - } + if (bGroupKey == true) { + return (pMgmt->byCSSGK); + } else { + return (pMgmt->byCSSPK); + } } /* -bool -VNTWIFIbInit( - void *pAdapterHandler, - void **pMgmtHandler - ) -{ - - PSMgmtObject pMgmt = NULL; - unsigned int ii; - - - pMgmt = (PSMgmtObject)kmalloc(sizeof(SMgmtObject), (int)GFP_ATOMIC); - if (pMgmt == NULL) { - *pMgmtHandler = NULL; - return false; - } - - memset(pMgmt, 0, sizeof(SMgmtObject)); - pMgmt->pAdapter = (void *) pAdapterHandler; - - // should initial MAC address abyMACAddr - for(ii=0;iiabyDesireBSSID[ii] = 0xFF; - } - pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; - pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_NONE; - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - - pMgmt->cbFreeCmdQueue = CMD_Q_SIZE; - pMgmt->uCmdDequeueIdx = 0; - pMgmt->uCmdEnqueueIdx = 0; - pMgmt->eCommandState = WLAN_CMD_STATE_IDLE; - pMgmt->bCmdStop = false; - pMgmt->bCmdRunning = false; - - *pMgmtHandler = pMgmt; - return true; -} + bool + VNTWIFIbInit( + void *pAdapterHandler, + void **pMgmtHandler +) + { + + PSMgmtObject pMgmt = NULL; + unsigned int ii; + + + pMgmt = (PSMgmtObject)kmalloc(sizeof(SMgmtObject), (int)GFP_ATOMIC); + if (pMgmt == NULL) { + *pMgmtHandler = NULL; + return false; + } + + memset(pMgmt, 0, sizeof(SMgmtObject)); + pMgmt->pAdapter = (void *) pAdapterHandler; + + // should initial MAC address abyMACAddr + for (ii=0; iiabyDesireBSSID[ii] = 0xFF; + } + pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; + pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; + pMgmt->byCSSPK = KEY_CTL_NONE; + pMgmt->byCSSGK = KEY_CTL_NONE; + pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; + + pMgmt->cbFreeCmdQueue = CMD_Q_SIZE; + pMgmt->uCmdDequeueIdx = 0; + pMgmt->uCmdEnqueueIdx = 0; + pMgmt->eCommandState = WLAN_CMD_STATE_IDLE; + pMgmt->bCmdStop = false; + pMgmt->bCmdRunning = false; + + *pMgmtHandler = pMgmt; + return true; + } */ bool -VNTWIFIbSetPMKIDCache ( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo - ) +VNTWIFIbSetPMKIDCache( + void *pMgmtObject, + unsigned long ulCount, + void *pPMKIDInfo +) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - if (ulCount > MAX_PMKID_CACHE) { - return (false); - } - pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount; - memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo))); - return (true); + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + + if (ulCount > MAX_PMKID_CACHE) { + return (false); + } + pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount; + memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo))); + return (true); } unsigned short VNTWIFIwGetMaxSupportRate( - void *pMgmtObject - ) + void *pMgmtObject +) { - unsigned short wRate = RATE_54M; - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - for(wRate = RATE_54M; wRate > RATE_1M; wRate--) { - if (pMgmt->sNodeDBTable[0].wSuppRate & (1<eCurrentPHYMode == PHY_TYPE_11A) { - return (RATE_6M); - } else { - return (RATE_1M); - } + unsigned short wRate = RATE_54M; + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + + for (wRate = RATE_54M; wRate > RATE_1M; wRate--) { + if (pMgmt->sNodeDBTable[0].wSuppRate & (1<eCurrentPHYMode == PHY_TYPE_11A) { + return (RATE_6M); + } else { + return (RATE_1M); + } } void -VNTWIFIvSet11h ( - void *pMgmtObject, - bool b11hEnable - ) +VNTWIFIvSet11h( + void *pMgmtObject, + bool b11hEnable +) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - pMgmt->b11hEnable = b11hEnable; + pMgmt->b11hEnable = b11hEnable; } bool VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs - ) + void *pMgmtObject, + bool bEndOfReport, + void *pvMeasureEID, + unsigned char byReportMode, + unsigned char byBasicMap, + unsigned char byCCAFraction, + unsigned char *pbyRPIs +) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned char *pbyCurrentEID = (unsigned char *) (pMgmt->pCurrMeasureEIDRep); - - //spin_lock_irq(&pDevice->lock); - if ((pvMeasureEID != NULL) && - (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3)) - ) { - pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP; - pMgmt->pCurrMeasureEIDRep->len = 3; - pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byToken; - pMgmt->pCurrMeasureEIDRep->byMode = byReportMode; - pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType; - switch (pMgmt->pCurrMeasureEIDRep->byType) { - case MEASURE_TYPE_BASIC : - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC); - memcpy( &(pMgmt->pCurrMeasureEIDRep->sRep.sBasic), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap; - break; - case MEASURE_TYPE_CCA : - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA); - memcpy( &(pMgmt->pCurrMeasureEIDRep->sRep.sCCA), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction; - break; - case MEASURE_TYPE_RPI : - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI); - memcpy( &(pMgmt->pCurrMeasureEIDRep->sRep.sRPI), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8); - break; - default : - break; - } - pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; - } - if (bEndOfReport == true) { - IEEE11hbMSRRepTx(pMgmt); - } - //spin_unlock_irq(&pDevice->lock); - return (true); + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + unsigned char *pbyCurrentEID = (unsigned char *)(pMgmt->pCurrMeasureEIDRep); + + //spin_lock_irq(&pDevice->lock); + if ((pvMeasureEID != NULL) && + (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3)) +) { + pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP; + pMgmt->pCurrMeasureEIDRep->len = 3; + pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ)pvMeasureEID)->byToken; + pMgmt->pCurrMeasureEIDRep->byMode = byReportMode; + pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType; + switch (pMgmt->pCurrMeasureEIDRep->byType) { + case MEASURE_TYPE_BASIC: + pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC); + memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sBasic), + &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), + sizeof(MEASEURE_REQ)); + pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap; + break; + case MEASURE_TYPE_CCA: + pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA); + memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sCCA), + &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), + sizeof(MEASEURE_REQ)); + pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction; + break; + case MEASURE_TYPE_RPI: + pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI); + memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sRPI), + &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), + sizeof(MEASEURE_REQ)); + memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8); + break; + default: + break; + } + pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len); + pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); + pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; + } + if (bEndOfReport == true) { + IEEE11hbMSRRepTx(pMgmt); + } + //spin_unlock_irq(&pDevice->lock); + return (true); } bool VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel - ) + void *pMgmtObject, + unsigned char byNewChannel +) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - //spin_lock_irq(&pDevice->lock); - pMgmt->uCurrChannel = byNewChannel; - pMgmt->bSwitchChannel = false; - //spin_unlock_irq(&pDevice->lock); - return true; + //spin_lock_irq(&pDevice->lock); + pMgmt->uCurrChannel = byNewChannel; + pMgmt->bSwitchChannel = false; + //spin_unlock_irq(&pDevice->lock); + return true; } /* -bool -VNTWIFIbRadarPresent( - void *pMgmtObject, - unsigned char byChannel - ) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (byChannel == (unsigned char) pMgmt->uCurrChannel) && - (pMgmt->bSwitchChannel != true) && - (pMgmt->b11hEnable == true)) { - if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) { - pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel); - pMgmt->bSwitchChannel = true; - } - BEACONbSendBeacon(pMgmt); - CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10); - } - return true; -} + bool + VNTWIFIbRadarPresent( + void *pMgmtObject, + unsigned char byChannel +) + { + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (byChannel == (unsigned char) pMgmt->uCurrChannel) && + (pMgmt->bSwitchChannel != true) && + (pMgmt->b11hEnable == true)) { + if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) { + pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel); + pMgmt->bSwitchChannel = true; + } + BEACONbSendBeacon(pMgmt); + CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10); + } + return true; + } */ diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index f4327abaa773..49a0a02fe14c 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -65,28 +65,28 @@ // Pre-configured Authenticaiton Mode (from XP) typedef enum tagWMAC_AUTHENTICATION_MODE { - WMAC_AUTH_OPEN, - WMAC_AUTH_SHAREKEY, - WMAC_AUTH_AUTO, - WMAC_AUTH_WPA, - WMAC_AUTH_WPAPSK, - WMAC_AUTH_WPANONE, - WMAC_AUTH_WPA2, - WMAC_AUTH_WPA2PSK, - WMAC_AUTH_MAX // Not a real mode, defined as upper bound + WMAC_AUTH_OPEN, + WMAC_AUTH_SHAREKEY, + WMAC_AUTH_AUTO, + WMAC_AUTH_WPA, + WMAC_AUTH_WPAPSK, + WMAC_AUTH_WPANONE, + WMAC_AUTH_WPA2, + WMAC_AUTH_WPA2PSK, + WMAC_AUTH_MAX // Not a real mode, defined as upper bound } WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE; typedef enum tagWMAC_ENCRYPTION_MODE { - WMAC_ENCRYPTION_WEPEnabled, - WMAC_ENCRYPTION_WEPDisabled, - WMAC_ENCRYPTION_WEPKeyAbsent, - WMAC_ENCRYPTION_WEPNotSupported, - WMAC_ENCRYPTION_TKIPEnabled, - WMAC_ENCRYPTION_TKIPKeyAbsent, - WMAC_ENCRYPTION_AESEnabled, - WMAC_ENCRYPTION_AESKeyAbsent + WMAC_ENCRYPTION_WEPEnabled, + WMAC_ENCRYPTION_WEPDisabled, + WMAC_ENCRYPTION_WEPKeyAbsent, + WMAC_ENCRYPTION_WEPNotSupported, + WMAC_ENCRYPTION_TKIPEnabled, + WMAC_ENCRYPTION_TKIPKeyAbsent, + WMAC_ENCRYPTION_AESEnabled, + WMAC_ENCRYPTION_AESKeyAbsent } WMAC_ENCRYPTION_MODE, *PWMAC_ENCRYPTION_MODE; @@ -94,10 +94,10 @@ typedef enum tagWMAC_ENCRYPTION_MODE { typedef enum tagWMAC_CONFIG_MODE { - WMAC_CONFIG_ESS_STA = 0, - WMAC_CONFIG_IBSS_STA, - WMAC_CONFIG_AUTO, - WMAC_CONFIG_AP + WMAC_CONFIG_ESS_STA = 0, + WMAC_CONFIG_IBSS_STA, + WMAC_CONFIG_AUTO, + WMAC_CONFIG_AP } WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE; @@ -105,29 +105,29 @@ typedef enum tagWMAC_CONFIG_MODE { typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX + WMAC_POWER_CAM, + WMAC_POWER_FAST, + WMAC_POWER_MAX } WMAC_POWER_MODE, *PWMAC_POWER_MODE; #define VNTWIFIbIsShortSlotTime(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTSLOTTIME(wCapInfo) \ + WLAN_GET_CAP_INFO_SHORTSLOTTIME(wCapInfo) \ #define VNTWIFIbIsProtectMode(byERP) \ - ((byERP & WLAN_EID_ERP_USE_PROTECTION) != 0) \ + ((byERP & WLAN_EID_ERP_USE_PROTECTION) != 0) \ #define VNTWIFIbIsBarkerMode(byERP) \ - ((byERP & WLAN_EID_ERP_BARKER_MODE) != 0) \ + ((byERP & WLAN_EID_ERP_BARKER_MODE) != 0) \ #define VNTWIFIbIsShortPreamble(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTPREAMBLE(wCapInfo) \ + WLAN_GET_CAP_INFO_SHORTPREAMBLE(wCapInfo) \ -#define VNTWIFIbIsEncryption(wCapInfo) \ - WLAN_GET_CAP_INFO_PRIVACY(wCapInfo) \ +#define VNTWIFIbIsEncryption(wCapInfo) \ + WLAN_GET_CAP_INFO_PRIVACY(wCapInfo) \ -#define VNTWIFIbIsESS(wCapInfo) \ - WLAN_GET_CAP_INFO_ESS(wCapInfo) \ +#define VNTWIFIbIsESS(wCapInfo) \ + WLAN_GET_CAP_INFO_ESS(wCapInfo) \ /*--------------------- Export Classes ----------------------------*/ @@ -141,167 +141,167 @@ typedef enum tagWMAC_POWER_MODE { /*--------------------- Export Functions --------------------------*/ void -VNTWIFIvSetIBSSParameter ( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel - ); +VNTWIFIvSetIBSSParameter( + void *pMgmtHandle, + unsigned short wBeaconPeriod, + unsigned short wATIMWindow, + unsigned int uChannel +); void -VNTWIFIvSetOPMode ( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode - ); +VNTWIFIvSetOPMode( + void *pMgmtHandle, + WMAC_CONFIG_MODE eOPMode +); PWLAN_IE_SSID VNTWIFIpGetCurrentSSID( - void *pMgmtHandle - ); + void *pMgmtHandle +); unsigned int VNTWIFIpGetCurrentChannel( - void *pMgmtHandle - ); + void *pMgmtHandle +); unsigned short -VNTWIFIwGetAssocID ( - void *pMgmtHandle - ); +VNTWIFIwGetAssocID( + void *pMgmtHandle +); unsigned char -VNTWIFIbyGetMaxSupportRate ( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs - ); +VNTWIFIbyGetMaxSupportRate( + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs +); unsigned char -VNTWIFIbyGetACKTxRate ( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs - ); +VNTWIFIbyGetACKTxRate( + unsigned char byRxDataRate, + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs +); void -VNTWIFIvSetAuthenticationMode ( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode - ); +VNTWIFIvSetAuthenticationMode( + void *pMgmtHandle, + WMAC_AUTHENTICATION_MODE eAuthMode +); void -VNTWIFIvSetEncryptionMode ( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode - ); +VNTWIFIvSetEncryptionMode( + void *pMgmtHandle, + WMAC_ENCRYPTION_MODE eEncryptionMode +); bool VNTWIFIbConfigPhyMode( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType - ); + void *pMgmtHandle, + CARD_PHY_TYPE ePhyType +); void VNTWIFIbGetConfigPhyMode( - void *pMgmtHandle, - void *pePhyType - ); + void *pMgmtHandle, + void *pePhyType +); void VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, - void **pvFirstBSS); + void **pvFirstBSS); void -VNTWIFIvGetNextBSS ( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS - ); +VNTWIFIvGetNextBSS( + void *pMgmtHandle, + void *pvCurrentBSS, + void **pvNextBSS +); void VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount - ); + void *pMgmtHandle, + unsigned char *pbyDestAddress, + bool bTxOk, + unsigned short wRate, + unsigned char *pbyTxFailCount +); void VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate - ); + void *pMgmtHandle, + unsigned char *pbyDestAddress, + unsigned short *pwTxDataRate, + unsigned char *pbyACKRate, + unsigned char *pbyCCKBasicRate, + unsigned char *pbyOFDMBasicRate +); /* -bool -VNTWIFIbInit( - void *pAdapterHandler, - void **pMgmtHandler - ); + bool + VNTWIFIbInit( + void *pAdapterHandler, + void **pMgmtHandler +); */ unsigned char VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey - ); + void *pMgmtHandle, + bool bGroupKey +); bool -VNTWIFIbSetPMKIDCache ( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo - ); +VNTWIFIbSetPMKIDCache( + void *pMgmtObject, + unsigned long ulCount, + void *pPMKIDInfo +); bool -VNTWIFIbCommandRunning ( - void *pMgmtObject - ); +VNTWIFIbCommandRunning( + void *pMgmtObject +); unsigned short VNTWIFIwGetMaxSupportRate( - void *pMgmtObject - ); + void *pMgmtObject +); // for 802.11h void -VNTWIFIvSet11h ( - void *pMgmtObject, - bool b11hEnable - ); +VNTWIFIvSet11h( + void *pMgmtObject, + bool b11hEnable +); bool VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs - ); + void *pMgmtObject, + bool bEndOfReport, + void *pvMeasureEID, + unsigned char byReportMode, + unsigned char byBasicMap, + unsigned char byCCAFraction, + unsigned char *pbyRPIs +); bool VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel - ); + void *pMgmtObject, + unsigned char byNewChannel +); /* -bool -VNTWIFIbRadarPresent( - void *pMgmtObject, - unsigned char byChannel - ); + bool + VNTWIFIbRadarPresent( + void *pMgmtObject, + unsigned char byChannel +); */ #endif //__VNTWIFI_H__ -- cgit From 3bd1a38ba8bf190d560d65bfbce5343d1262678a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:09 -0700 Subject: staging:vt6655:wcmd: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wcmd.c | 1734 ++++++++++++++++++++--------------------- drivers/staging/vt6655/wcmd.h | 108 +-- 2 files changed, 921 insertions(+), 921 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 101c7359f414..ec3f1421582c 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -62,34 +62,34 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Functions --------------------------*/ static void s_vProbeChannel( - PSDevice pDevice - ); + PSDevice pDevice +); static PSTxMgmtPacket s_MgrMakeProbeRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); static bool -s_bCommandComplete ( - PSDevice pDevice - ); +s_bCommandComplete( + PSDevice pDevice +); /*--------------------- Export Variables --------------------------*/ @@ -116,39 +116,39 @@ void vAdHocBeaconStop(PSDevice pDevice) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - bool bStop; - - /* - * temporarily stop Beacon packet for AdHoc Server - * if all of the following conditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - * (3) One of the following conditions is met - * (3.1) AdHoc channel is in B/G band and the - * current scan channel is in A band - * or - * (3.2) AdHoc channel is in A mode - */ - bStop = false; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) - { - if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && - (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) - { - bStop = true; - } - if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) - { - bStop = true; - } - } - - if (bStop) - { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + bool bStop; + + /* + * temporarily stop Beacon packet for AdHoc Server + * if all of the following conditions are met: + * (1) STA is in AdHoc mode + * (2) VT3253 is programmed as automatic Beacon Transmitting + * (3) One of the following conditions is met + * (3.1) AdHoc channel is in B/G band and the + * current scan channel is in A band + * or + * (3.2) AdHoc channel is in A mode + */ + bStop = false; + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (pMgmt->eCurrState >= WMAC_STATE_STARTED)) + { + if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && + (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) + { + bStop = true; + } + if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) + { + bStop = true; + } + } + + if (bStop) + { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + } } /* vAdHocBeaconStop */ @@ -170,19 +170,19 @@ static void vAdHocBeaconRestart(PSDevice pDevice) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - /* - * Restart Beacon packet for AdHoc Server - * if all of the following coditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - */ - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) - { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + + /* + * Restart Beacon packet for AdHoc Server + * if all of the following coditions are met: + * (1) STA is in AdHoc mode + * (2) VT3253 is programmed as automatic Beacon Transmitting + */ + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (pMgmt->eCurrState >= WMAC_STATE_STARTED)) + { + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + } } @@ -200,54 +200,54 @@ vAdHocBeaconRestart(PSDevice pDevice) * Return Value: * none. * --*/ + -*/ static void s_vProbeChannel( - PSDevice pDevice - ) + PSDevice pDevice +) { - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - unsigned char *pbyRate; - PSTxMgmtPacket pTxPacket; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - pbyRate = &abyCurrSuppRatesA[0]; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - pbyRate = &abyCurrSuppRatesB[0]; - } else { - pbyRate = &abyCurrSuppRatesG[0]; - } - // build an assocreq frame and send it - pTxPacket = s_MgrMakeProbeRequest - ( - pDevice, - pMgmt, - pMgmt->abyScanBSSID, - (PWLAN_IE_SSID)pMgmt->abyScanSSID, - (PWLAN_IE_SUPP_RATES)pbyRate, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG - ); - - if (pTxPacket != NULL ){ - for (ii = 0; ii < 2 ; ii++) { - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n"); - } - } - } + //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M + unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; + unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; + //6M, 9M, 12M, 48M + unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; + unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; + unsigned char *pbyRate; + PSTxMgmtPacket pTxPacket; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned int ii; + + + if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { + pbyRate = &abyCurrSuppRatesA[0]; + } else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + pbyRate = &abyCurrSuppRatesB[0]; + } else { + pbyRate = &abyCurrSuppRatesG[0]; + } + // build an assocreq frame and send it + pTxPacket = s_MgrMakeProbeRequest + ( + pDevice, + pMgmt, + pMgmt->abyScanBSSID, + (PWLAN_IE_SSID)pMgmt->abyScanSSID, + (PWLAN_IE_SUPP_RATES)pbyRate, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG + ); + + if (pTxPacket != NULL) { + for (ii = 0; ii < 2; ii++) { + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n"); + } + } + } } @@ -263,55 +263,55 @@ s_vProbeChannel( * Return Value: * A ptr to Tx frame or NULL on allocation failue * --*/ + -*/ PSTxMgmtPacket s_MgrMakeProbeRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates + +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBEREQ sFrame; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; - vMgrEncodeProbeRequest(&sFrame); - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); - // Copy the SSID, pSSID->len=0 indicate broadcast SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - // Copy the extension rate set - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_PROBEREQ sFrame; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; + vMgrEncodeProbeRequest(&sFrame); + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); + // Copy the SSID, pSSID->len=0 indicate broadcast SSID + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += pSSID->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + // Copy the extension rate set + if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); + } + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -320,707 +320,707 @@ s_MgrMakeProbeRequest( void vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond - ) + void *hDeviceContext, + unsigned int MSecond +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - // RUN_AT :1 msec ~= (HZ/1024) - pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); - add_timer(&pDevice->sTimerCommand); - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + + init_timer(&pDevice->sTimerCommand); + pDevice->sTimerCommand.data = (unsigned long) pDevice; + pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; + // RUN_AT :1 msec ~= (HZ/1024) + pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); + add_timer(&pDevice->sTimerCommand); + return; } void -vCommandTimer ( - void *hDeviceContext - ) +vCommandTimer( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SSID pItemSSIDCurr; - CMD_STATUS Status; - unsigned int ii; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; - - - if (pDevice->dwDiagRefCount != 0) - return; - if (pDevice->bCmdRunning != true) - return; - - spin_lock_irq(&pDevice->lock); - - switch ( pDevice->eCommandState ) { - - case WLAN_CMD_SCAN_START: - - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - s_bCommandComplete(pDevice); - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP); - spin_unlock_irq(&pDevice->lock); - return; - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SCAN_START\n"); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; - // wait all Data TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){ - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, 10); - return; - } - - if (pMgmt->uScanChannel == 0 ) { - pMgmt->uScanChannel = pDevice->byMinChannel; - // Set Baseband to be more sensitive. - - } - if (pMgmt->uScanChannel > pDevice->byMaxChannel) { - pMgmt->eScanState = WMAC_NO_SCANNING; - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); - } - vAdHocBeaconRestart(pDevice); - s_bCommandComplete(pDevice); - - } else { + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PWLAN_IE_SSID pItemSSID; + PWLAN_IE_SSID pItemSSIDCurr; + CMD_STATUS Status; + unsigned int ii; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + struct sk_buff *skb; + + + if (pDevice->dwDiagRefCount != 0) + return; + if (pDevice->bCmdRunning != true) + return; + + spin_lock_irq(&pDevice->lock); + + switch (pDevice->eCommandState) { + + case WLAN_CMD_SCAN_START: + + pDevice->byReAssocCount = 0; + if (pDevice->bRadioOff == true) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + s_bCommandComplete(pDevice); + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP); + spin_unlock_irq(&pDevice->lock); + return; + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SCAN_START\n"); + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; + // wait all Data TD complete + if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *)pDevice, 10); + return; + } + + if (pMgmt->uScanChannel == 0) { + pMgmt->uScanChannel = pDevice->byMinChannel; + // Set Baseband to be more sensitive. + + } + if (pMgmt->uScanChannel > pDevice->byMaxChannel) { + pMgmt->eScanState = WMAC_NO_SCANNING; + + // Set Baseband's sensitivity back. + // Set channel back + set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); + } else { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); + } + vAdHocBeaconRestart(pDevice); + s_bCommandComplete(pDevice); + + } else { //2008-8-4 by chester - if (!is_channel_valid(pMgmt->uScanChannel)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel); - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } + if (!is_channel_valid(pMgmt->uScanChannel)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n", pMgmt->uScanChannel); + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } //printk("chester-pMgmt->uScanChannel=%d,pDevice->byMaxChannel=%d\n",pMgmt->uScanChannel,pDevice->byMaxChannel); - if (pMgmt->uScanChannel == pDevice->byMinChannel) { - //pMgmt->eScanType = WMAC_SCAN_ACTIVE; - pMgmt->abyScanBSSID[0] = 0xFF; - pMgmt->abyScanBSSID[1] = 0xFF; - pMgmt->abyScanBSSID[2] = 0xFF; - pMgmt->abyScanBSSID[3] = 0xFF; - pMgmt->abyScanBSSID[4] = 0xFF; - pMgmt->abyScanBSSID[5] = 0xFF; - pItemSSID->byElementID = WLAN_EID_SSID; - // clear bssid list - // BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - pMgmt->eScanState = WMAC_IS_SCANNING; - - } - - vAdHocBeaconStop(pDevice); - - if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SCAN Channel: %d\n", pMgmt->uScanChannel); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel); - } - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN); + if (pMgmt->uScanChannel == pDevice->byMinChannel) { + //pMgmt->eScanType = WMAC_SCAN_ACTIVE; + pMgmt->abyScanBSSID[0] = 0xFF; + pMgmt->abyScanBSSID[1] = 0xFF; + pMgmt->abyScanBSSID[2] = 0xFF; + pMgmt->abyScanBSSID[3] = 0xFF; + pMgmt->abyScanBSSID[4] = 0xFF; + pMgmt->abyScanBSSID[5] = 0xFF; + pItemSSID->byElementID = WLAN_EID_SSID; + // clear bssid list + // BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + pMgmt->eScanState = WMAC_IS_SCANNING; + + } + + vAdHocBeaconStop(pDevice); + + if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel); + } + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN); // printk("chester-mxch=%d\n",pDevice->byMaxChannel); - // printk("chester-ch=%d\n",pMgmt->uScanChannel); - pMgmt->uScanChannel++; + // printk("chester-ch=%d\n",pMgmt->uScanChannel); + pMgmt->uScanChannel++; //2008-8-4 by chester - if (!is_channel_valid(pMgmt->uScanChannel) && - pMgmt->uScanChannel <= pDevice->byMaxChannel ){ - pMgmt->uScanChannel=pDevice->byMaxChannel+1; - pMgmt->eCommandState = WLAN_CMD_SCAN_END; - - } - - - if ((pMgmt->b11hEnable == false) || - (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { - s_vProbeChannel(pDevice); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); - return; - } else { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); - return; - } - - } - - break; - - case WLAN_CMD_SCAN_END: - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); - } - - pMgmt->eScanState = WMAC_NO_SCANNING; - vAdHocBeaconRestart(pDevice); + if (!is_channel_valid(pMgmt->uScanChannel) && + pMgmt->uScanChannel <= pDevice->byMaxChannel) { + pMgmt->uScanChannel = pDevice->byMaxChannel + 1; + pMgmt->eCommandState = WLAN_CMD_SCAN_END; + + } + + + if ((pMgmt->b11hEnable == false) || + (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { + s_vProbeChannel(pDevice); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); + return; + } else { + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); + return; + } + + } + + break; + + case WLAN_CMD_SCAN_END: + + // Set Baseband's sensitivity back. + // Set channel back + set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); + } else { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_INFRASTRUCTURE); + } + + pMgmt->eScanState = WMAC_NO_SCANNING; + vAdHocBeaconRestart(pDevice); //2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - if(pMgmt->eScanType == WMAC_SCAN_PASSIVE) - {//send scan event to wpa_Supplicant - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - } + if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) + {//send scan event to wpa_Supplicant + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); + } #endif - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_DISASSOCIATE_START : - pDevice->byReAssocCount = 0; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); - // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); - pDevice->bLinkPass = false; - // unlock command busy - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->sNodeDBTable[0].bActive = false; + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_DISASSOCIATE_START: + pDevice->byReAssocCount = 0; + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Disassociation Packet..\n"); + // reason = 8 : disassoc because sta has left + vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); + pDevice->bLinkPass = false; + // unlock command busy + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID->len = 0; + memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->sNodeDBTable[0].bActive = false; // pDevice->bBeaconBufReady = false; - } - netif_stop_queue(pDevice->dev); - pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" CARDbRadioPowerOff\n"); - //2008-09-02 by chester - // CARDbRadioPowerOff(pDevice); - s_bCommandComplete(pDevice); - break; - - case WLAN_DISASSOCIATE_WAIT : - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } + } + netif_stop_queue(pDevice->dev); + pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; + // wait all Control TD complete + if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { + vCommandTimerWait((void *)pDevice, 10); + spin_unlock_irq(&pDevice->lock); + return; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " CARDbRadioPowerOff\n"); + //2008-09-02 by chester + // CARDbRadioPowerOff(pDevice); + s_bCommandComplete(pDevice); + break; + + case WLAN_DISASSOCIATE_WAIT: + // wait all Control TD complete + if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { + vCommandTimerWait((void *)pDevice, 10); + spin_unlock_irq(&pDevice->lock); + return; + } //2008-09-02 by chester - // CARDbRadioPowerOff(pDevice); - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_SSID_START: - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } + // CARDbRadioPowerOff(pDevice); + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_SSID_START: + pDevice->byReAssocCount = 0; + if (pDevice->bRadioOff == true) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } //printk("chester-currmode=%d\n",pMgmt->eCurrMode); -printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); - //memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID, - //((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID); - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)&& (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - - if (pItemSSID->len == pItemSSIDCurr->len) { - if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - } - - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - // set initial state - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((void *)pDevice); - BSSvClearNodeDBTable(pDevice, 0); - - vMgrJoinBSSBegin((void *)pDevice, &Status); - // if Infra mode - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { - - // Call mgr to begin the deauthentication - // reason = (3) because sta has left ESS - if (pMgmt->eCurrState>= WMAC_STATE_AUTH) { - vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); - } - // Call mgr to begin the authentication - vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { + printk("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); + //memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID, + //((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN); + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: desire ssid = %s\n", pItemSSID->abySSID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); + + if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSID->len =%d\n", pItemSSID->len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " desire ssid = %s\n", pItemSSID->abySSID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " curr ssid = %s\n", pItemSSIDCurr->abySSID); + } + + if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || + ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { + + if (pItemSSID->len == pItemSSIDCurr->len) { + if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + } + + netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + } + // set initial state + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + PSvDisablePowerSaving((void *)pDevice); + BSSvClearNodeDBTable(pDevice, 0); + + vMgrJoinBSSBegin((void *)pDevice, &Status); + // if Infra mode + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { + + // Call mgr to begin the deauthentication + // reason = (3) because sta has left ESS + if (pMgmt->eCurrState >= WMAC_STATE_AUTH) { + vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); + } + // Call mgr to begin the authentication + vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); + if (Status == CMD_STATUS_SUCCESS) { + pDevice->byLinkWaitCount = 0; + pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; + vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); + spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); + return; + } + } + // if Adhoc mode + else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { + if (netif_queue_stopped(pDevice->dev)) { + netif_wake_queue(pDevice->dev); + } + pDevice->bLinkPass = true; + + pMgmt->sNodeDBTable[0].bActive = true; + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + bClearBSSID_SCAN(pDevice); + } + else { + // start own IBSS + vMgrCreateOwnIBSS((void *)pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n"); + } + BSSvAddMulticastNode(pDevice); + } + } + // if SSID not found + else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { + if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || + pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { + // start own IBSS + vMgrCreateOwnIBSS((void *)pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n"); + } + BSSvAddMulticastNode(pDevice); + if (netif_queue_stopped(pDevice->dev)) { + netif_wake_queue(pDevice->dev); + } + pDevice->bLinkPass = true; + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + // if (pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif + + } + } + s_bCommandComplete(pDevice); + break; + + case WLAN_AUTHENTICATE_WAIT: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_AUTHENTICATE_WAIT\n"); + if (pMgmt->eCurrState == WMAC_STATE_AUTH) { + // Call mgr to begin the association + pDevice->byLinkWaitCount = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_AUTH\n"); + vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); + if (Status == CMD_STATUS_SUCCESS) { + pDevice->byLinkWaitCount = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState = WLAN_ASSOCIATE_WAIT\n"); + pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; + vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); + spin_unlock_irq(&pDevice->lock); + return; + } + } + + else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { + printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); + } + else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if authenticated_frame delay! + pDevice->byLinkWaitCount++; + printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); + return; + } pDevice->byLinkWaitCount = 0; - pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); - return; - } - } - // if Adhoc mode - else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pDevice->bLinkPass = true; - - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - bClearBSSID_SCAN(pDevice); - } - else { - // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n"); - } - BSSvAddMulticastNode(pDevice); - } - } - // if SSID not found - else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || - pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { - // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n"); - } - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pDevice->bLinkPass = true; - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - #endif - - } - } - s_bCommandComplete(pDevice); - break; - - case WLAN_AUTHENTICATE_WAIT : - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n"); - if (pMgmt->eCurrState == WMAC_STATE_AUTH) { - // Call mgr to begin the association - pDevice->byLinkWaitCount = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { + s_bCommandComplete(pDevice); + break; + + case WLAN_ASSOCIATE_WAIT: + if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_ASSOC\n"); + if (pDevice->ePSMode != WMAC_POWER_CAM) { + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); + } + if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { + KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); + } + pDevice->bLinkPass = true; + pDevice->byLinkWaitCount = 0; + pDevice->byReAssocCount = 0; + bClearBSSID_SCAN(pDevice); + if (pDevice->byFOETuning) { + BBvSetFOE(pDevice->PortOffset); + PSbSendNullPacket(pDevice); + } + if (netif_queue_stopped(pDevice->dev)) { + netif_wake_queue(pDevice->dev); + } +#ifdef TxInSleep + if (pDevice->IsTxDataTrigger != false) { //TxDataTimer is not triggered at the first time + // printk("Re-initial TxDataTimer****\n"); + del_timer(&pDevice->sTimerTxData); + init_timer(&pDevice->sTimerTxData); + pDevice->sTimerTxData.data = (unsigned long) pDevice; + pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; + pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback + pDevice->fTxDataInSleep = false; + pDevice->nTxDataTimeCout = 0; + } + else { + // printk("mike:-->First time trigger TimerTxData InSleep\n"); + } + pDevice->IsTxDataTrigger = true; + add_timer(&pDevice->sTimerTxData); +#endif + } + else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { + printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); + } + else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! + pDevice->byLinkWaitCount++; + printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); + return; + } pDevice->byLinkWaitCount = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n"); - pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - return; - } - } - - else if(pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { - printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); - } - else if(pDevice->byLinkWaitCount <= 4){ //mike add:wait another 2 sec if authenticated_frame delay! - pDevice->byLinkWaitCount ++; - printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - s_bCommandComplete(pDevice); - break; - - case WLAN_ASSOCIATE_WAIT : - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n"); - if (pDevice->ePSMode != WMAC_POWER_CAM) { - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - } - if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { - KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); - } - pDevice->bLinkPass = true; - pDevice->byLinkWaitCount = 0; - pDevice->byReAssocCount = 0; - bClearBSSID_SCAN(pDevice); - if (pDevice->byFOETuning) { - BBvSetFOE(pDevice->PortOffset); - PSbSendNullPacket(pDevice); - } - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - #ifdef TxInSleep - if(pDevice->IsTxDataTrigger != false) { //TxDataTimer is not triggered at the first time - // printk("Re-initial TxDataTimer****\n"); - del_timer(&pDevice->sTimerTxData); - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->nTxDataTimeCout = 0; - } - else { - // printk("mike:-->First time trigger TimerTxData InSleep\n"); - } - pDevice->IsTxDataTrigger = true; - add_timer(&pDevice->sTimerTxData); - #endif - } - else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { - printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); - } - else if(pDevice->byLinkWaitCount <= 4){ //mike add:wait another 2 sec if associated_frame delay! - pDevice->byLinkWaitCount ++; - printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_AP_MODE_START : - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - del_timer(&pMgmt->sTimerSecondCallback); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pDevice->bLinkPass = false; - if (pDevice->bEnableHostWEP == true) - BSSvClearNodeDBTable(pDevice, 1); - else - BSSvClearNodeDBTable(pDevice, 0); - pDevice->uAssocCount = 0; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bFixRate = false; - - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n"); - } - // alway turn off unicast bit - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); - pDevice->byRxMode &= ~RCR_UNICAST; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode ); - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pDevice->bLinkPass = true; - add_timer(&pMgmt->sTimerSecondCallback); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_TX_PSPACKET_START : - // DTIM Multicast tx - if (pMgmt->sNodeDBTable[0].bRxPSPoll) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { - pMgmt->abyPSTxMap[0] &= ~byMask[0]; - pDevice->bMoreData = false; - } - else { - pDevice->bMoreData = true; - } - if (!device_dma0_xmit(pDevice, skb, 0)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n"); - } - pMgmt->sNodeDBTable[0].wEnQueueCnt--; - } - } - - // PS nodes tx - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive && - pMgmt->sNodeDBTable[ii].bRxPSPoll) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", - ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pDevice->bMoreData = false; - } - else { - pDevice->bMoreData = true; - } - if (!device_dma0_xmit(pDevice, skb, ii)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n"); - } - pMgmt->sNodeDBTable[ii].wEnQueueCnt--; - // check if sta ps enabled, and wait next pspoll. - // if sta ps disable, then send all pending buffers. - if (pMgmt->sNodeDBTable[ii].bPSEnable) - break; - } - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii); - } - pMgmt->sNodeDBTable[ii].bRxPSPoll = false; - } - } - - s_bCommandComplete(pDevice); - break; - - - case WLAN_CMD_RADIO_START : - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n"); - if (pDevice->bRadioCmd == true) - CARDbRadioPowerOn(pDevice); - else - CARDbRadioPowerOff(pDevice); - - s_bCommandComplete(pDevice); - break; - - - case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE : - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n"); - // wait all TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){ - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - pDevice->byBBVGACurrent = pDevice->byBBVGANew; - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); - s_bCommandComplete(pDevice); - break; - - default : - s_bCommandComplete(pDevice); - break; - - } //switch - spin_unlock_irq(&pDevice->lock); - return; + + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_AP_MODE_START: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_AP_MODE_START\n"); + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + del_timer(&pMgmt->sTimerSecondCallback); + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pDevice->bLinkPass = false; + if (pDevice->bEnableHostWEP == true) + BSSvClearNodeDBTable(pDevice, 1); + else + BSSvClearNodeDBTable(pDevice, 0); + pDevice->uAssocCount = 0; + pMgmt->eCurrState = WMAC_STATE_IDLE; + pDevice->bFixRate = false; + + vMgrCreateOwnIBSS((void *)pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n"); + } + // alway turn off unicast bit + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); + pDevice->byRxMode &= ~RCR_UNICAST; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); + BSSvAddMulticastNode(pDevice); + if (netif_queue_stopped(pDevice->dev)) { + netif_wake_queue(pDevice->dev); + } + pDevice->bLinkPass = true; + add_timer(&pMgmt->sTimerSecondCallback); + } + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_TX_PSPACKET_START: + // DTIM Multicast tx + if (pMgmt->sNodeDBTable[0].bRxPSPoll) { + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { + if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { + pMgmt->abyPSTxMap[0] &= ~byMask[0]; + pDevice->bMoreData = false; + } + else { + pDevice->bMoreData = true; + } + if (!device_dma0_xmit(pDevice, skb, 0)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n"); + } + pMgmt->sNodeDBTable[0].wEnQueueCnt--; + } + } + + // PS nodes tx + for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { + if (pMgmt->sNodeDBTable[ii].bActive && + pMgmt->sNodeDBTable[ii].bRxPSPoll) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", + ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { + if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { + // clear tx map + pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= + ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; + pDevice->bMoreData = false; + } + else { + pDevice->bMoreData = true; + } + if (!device_dma0_xmit(pDevice, skb, ii)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n"); + } + pMgmt->sNodeDBTable[ii].wEnQueueCnt--; + // check if sta ps enabled, and wait next pspoll. + // if sta ps disable, then send all pending buffers. + if (pMgmt->sNodeDBTable[ii].bPSEnable) + break; + } + if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { + // clear tx map + pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= + ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii); + } + pMgmt->sNodeDBTable[ii].bRxPSPoll = false; + } + } + + s_bCommandComplete(pDevice); + break; + + + case WLAN_CMD_RADIO_START: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n"); + if (pDevice->bRadioCmd == true) + CARDbRadioPowerOn(pDevice); + else + CARDbRadioPowerOff(pDevice); + + s_bCommandComplete(pDevice); + break; + + + case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE: + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n"); + // wait all TD complete + if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { + vCommandTimerWait((void *)pDevice, 10); + spin_unlock_irq(&pDevice->lock); + return; + } + if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { + vCommandTimerWait((void *)pDevice, 10); + spin_unlock_irq(&pDevice->lock); + return; + } + pDevice->byBBVGACurrent = pDevice->byBBVGANew; + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); + s_bCommandComplete(pDevice); + break; + + default: + s_bCommandComplete(pDevice); + break; + + } //switch + spin_unlock_irq(&pDevice->lock); + return; } static bool -s_bCommandComplete ( - PSDevice pDevice - ) +s_bCommandComplete( + PSDevice pDevice +) { - PWLAN_IE_SSID pSSID; - bool bRadioCmd = false; - //unsigned short wDeAuthenReason = 0; - bool bForceSCAN = true; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - pDevice->eCommandState = WLAN_CMD_IDLE; - if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { - //Command Queue Empty - pDevice->bCmdRunning = false; - return true; - } - else { - pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; - pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; - bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; - bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue++; - pDevice->bCmdRunning = true; - switch ( pDevice->eCommand ) { - case WLAN_CMD_BSSID_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n"); - pDevice->eCommandState = WLAN_CMD_SCAN_START; - pMgmt->uScanChannel = 0; - if (pSSID->len != 0) { - memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - } else { - memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - } + PWLAN_IE_SSID pSSID; + bool bRadioCmd = false; + //unsigned short wDeAuthenReason = 0; + bool bForceSCAN = true; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + pDevice->eCommandState = WLAN_CMD_IDLE; + if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { + //Command Queue Empty + pDevice->bCmdRunning = false; + return true; + } + else { + pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; + pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; + bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; + bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; + ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); + pDevice->cbFreeCmdQueue++; + pDevice->bCmdRunning = true; + switch (pDevice->eCommand) { + case WLAN_CMD_BSSID_SCAN: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_BSSID_SCAN\n"); + pDevice->eCommandState = WLAN_CMD_SCAN_START; + pMgmt->uScanChannel = 0; + if (pSSID->len != 0) { + memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + } else { + memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + } /* - if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) { - if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) && - ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) { - pDevice->eCommandState = WLAN_CMD_IDLE; - } - } + if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) { + if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) && + (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) { + pDevice->eCommandState = WLAN_CMD_IDLE; + } + } */ - break; - case WLAN_CMD_SSID: - pDevice->eCommandState = WLAN_CMD_SSID_START; - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - if (pSSID->len != 0) - memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n"); - break; - case WLAN_CMD_DISASSOCIATE: - pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; - break; - case WLAN_CMD_RX_PSPOLL: - pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; - break; - case WLAN_CMD_RUN_AP: - pDevice->eCommandState = WLAN_CMD_AP_MODE_START; - break; - case WLAN_CMD_RADIO: - pDevice->eCommandState = WLAN_CMD_RADIO_START; - pDevice->bRadioCmd = bRadioCmd; - break; - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; - - default: - break; - - } - - vCommandTimerWait((void *)pDevice, 0); - } - - return true; + break; + case WLAN_CMD_SSID: + pDevice->eCommandState = WLAN_CMD_SSID_START; + if (pSSID->len > WLAN_SSID_MAXLEN) + pSSID->len = WLAN_SSID_MAXLEN; + if (pSSID->len != 0) + memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SSID_START\n"); + break; + case WLAN_CMD_DISASSOCIATE: + pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; + break; + case WLAN_CMD_RX_PSPOLL: + pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; + break; + case WLAN_CMD_RUN_AP: + pDevice->eCommandState = WLAN_CMD_AP_MODE_START; + break; + case WLAN_CMD_RADIO: + pDevice->eCommandState = WLAN_CMD_RADIO_START; + pDevice->bRadioCmd = bRadioCmd; + break; + case WLAN_CMD_CHANGE_BBSENSITIVITY: + pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; + break; + + default: + break; + + } + + vCommandTimerWait((void *)pDevice, 0); + } + + return true; } -bool bScheduleCommand ( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 - ) +bool bScheduleCommand( + void *hDeviceContext, + CMD_CODE eCommand, + unsigned char *pbyItem0 +) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; - if (pDevice->cbFreeCmdQueue == 0) { - return (false); - } - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; - memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + if (pDevice->cbFreeCmdQueue == 0) { + return (false); + } + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; + memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - if (pbyItem0 != NULL) { - switch (eCommand) { + if (pbyItem0 != NULL) { + switch (eCommand) { - case WLAN_CMD_BSSID_SCAN: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; - break; + case WLAN_CMD_BSSID_SCAN: + memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, + pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; + break; - case WLAN_CMD_SSID: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - break; + case WLAN_CMD_SSID: + memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, + pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + break; - case WLAN_CMD_DISASSOCIATE: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); - break; + case WLAN_CMD_DISASSOCIATE: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); + break; /* - case WLAN_CMD_DEAUTH: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((unsigned short *)pbyItem0); - break; + case WLAN_CMD_DEAUTH: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((unsigned short *)pbyItem0); + break; */ - case WLAN_CMD_RX_PSPOLL: - break; + case WLAN_CMD_RX_PSPOLL: + break; - case WLAN_CMD_RADIO: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); - break; + case WLAN_CMD_RADIO: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); + break; - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; + case WLAN_CMD_CHANGE_BBSENSITIVITY: + pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; + break; - default: - break; - } - } + default: + break; + } + } - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue--; + ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); + pDevice->cbFreeCmdQueue--; - if (pDevice->bCmdRunning == false) { - s_bCommandComplete(pDevice); - } - else { - } - return (true); + if (pDevice->bCmdRunning == false) { + s_bCommandComplete(pDevice); + } + else { + } + return (true); } @@ -1038,87 +1038,87 @@ bool bScheduleCommand ( * Return Value: true if success; otherwise false * */ -bool bClearBSSID_SCAN ( - void *hDeviceContext - ) +bool bClearBSSID_SCAN( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; - unsigned int ii; - - if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { - for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) { - if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) - pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; - ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); - if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) - break; - } - } - return true; + PSDevice pDevice = (PSDevice)hDeviceContext; + unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; + unsigned int ii; + + if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { + for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) { + if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) + pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; + ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); + if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) + break; + } + } + return true; } //mike add:reset command timer void vResetCommandTimer( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - - //delete timer - del_timer(&pDevice->sTimerCommand); - //init timer - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->eCommandState = WLAN_CMD_IDLE; - pDevice->bCmdRunning = false; - pDevice->bCmdClear = false; + PSDevice pDevice = (PSDevice)hDeviceContext; + + //delete timer + del_timer(&pDevice->sTimerCommand); + //init timer + init_timer(&pDevice->sTimerCommand); + pDevice->sTimerCommand.data = (unsigned long) pDevice; + pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; + pDevice->sTimerCommand.expires = RUN_AT(HZ); + pDevice->cbFreeCmdQueue = CMD_Q_SIZE; + pDevice->uCmdDequeueIdx = 0; + pDevice->uCmdEnqueueIdx = 0; + pDevice->eCommandState = WLAN_CMD_IDLE; + pDevice->bCmdRunning = false; + pDevice->bCmdClear = false; } #ifdef TxInSleep void BSSvSecondTxData( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - pDevice->nTxDataTimeCout++; - - if(pDevice->nTxDataTimeCout<4) //don't tx data if timer less than 40s - { - // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__, - // (int)pDevice->nTxDataTimeCout); - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - add_timer(&pDevice->sTimerTxData); - return; - } - - spin_lock_irq(&pDevice->lock); - #if 1 - if(((pDevice->bLinkPass ==true)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking - (pDevice->fWPA_Authened == true)) { //wpa linking - #else - if(pDevice->bLinkPass ==true) { - #endif - - // printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__); - pDevice->fTxDataInSleep = true; - PSbSendNullPacket(pDevice); //send null packet - pDevice->fTxDataInSleep = false; - } - spin_unlock_irq(&pDevice->lock); - - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - add_timer(&pDevice->sTimerTxData); - return; -} + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + pDevice->nTxDataTimeCout++; + + if (pDevice->nTxDataTimeCout < 4) //don't tx data if timer less than 40s + { + // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__, + // (int)pDevice->nTxDataTimeCout); + pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback + add_timer(&pDevice->sTimerTxData); + return; + } + + spin_lock_irq(&pDevice->lock); +#if 1 + if (((pDevice->bLinkPass == true) && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking + (pDevice->fWPA_Authened == true)) { //wpa linking +#else + if (pDevice->bLinkPass == true) { +#endif + + // printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__); + pDevice->fTxDataInSleep = true; + PSbSendNullPacket(pDevice); //send null packet + pDevice->fTxDataInSleep = false; + } + spin_unlock_irq(&pDevice->lock); + + pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback + add_timer(&pDevice->sTimerTxData); + return; + } #endif diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index 69d4fc55b843..4dc943531c93 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -43,59 +43,59 @@ // Command code typedef enum tagCMD_CODE { - WLAN_CMD_BSSID_SCAN, - WLAN_CMD_SSID, - WLAN_CMD_DISASSOCIATE, - WLAN_CMD_DEAUTH, - WLAN_CMD_RX_PSPOLL, - WLAN_CMD_RADIO, - WLAN_CMD_CHANGE_BBSENSITIVITY, - WLAN_CMD_SETPOWER, - WLAN_CMD_TBTT_WAKEUP, - WLAN_CMD_BECON_SEND, - WLAN_CMD_CHANGE_ANTENNA, - WLAN_CMD_REMOVE_ALLKEY, - WLAN_CMD_MAC_DISPOWERSAVING, - WLAN_CMD_11H_CHSW, - WLAN_CMD_RUN_AP + WLAN_CMD_BSSID_SCAN, + WLAN_CMD_SSID, + WLAN_CMD_DISASSOCIATE, + WLAN_CMD_DEAUTH, + WLAN_CMD_RX_PSPOLL, + WLAN_CMD_RADIO, + WLAN_CMD_CHANGE_BBSENSITIVITY, + WLAN_CMD_SETPOWER, + WLAN_CMD_TBTT_WAKEUP, + WLAN_CMD_BECON_SEND, + WLAN_CMD_CHANGE_ANTENNA, + WLAN_CMD_REMOVE_ALLKEY, + WLAN_CMD_MAC_DISPOWERSAVING, + WLAN_CMD_11H_CHSW, + WLAN_CMD_RUN_AP } CMD_CODE, *PCMD_CODE; #define CMD_Q_SIZE 32 typedef enum tagCMD_STATUS { - CMD_STATUS_SUCCESS = 0, - CMD_STATUS_FAILURE, - CMD_STATUS_RESOURCES, - CMD_STATUS_TIMEOUT, - CMD_STATUS_PENDING + CMD_STATUS_SUCCESS = 0, + CMD_STATUS_FAILURE, + CMD_STATUS_RESOURCES, + CMD_STATUS_TIMEOUT, + CMD_STATUS_PENDING } CMD_STATUS, *PCMD_STATUS; typedef struct tagCMD_ITEM { - CMD_CODE eCmd; - unsigned char abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - bool bNeedRadioOFF; - unsigned short wDeAuthenReason; - bool bRadioCmd; - bool bForceSCAN; + CMD_CODE eCmd; + unsigned char abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + bool bNeedRadioOFF; + unsigned short wDeAuthenReason; + bool bRadioCmd; + bool bForceSCAN; } CMD_ITEM, *PCMD_ITEM; // Command state typedef enum tagCMD_STATE { - WLAN_CMD_SCAN_START, - WLAN_CMD_SCAN_END, - WLAN_CMD_DISASSOCIATE_START, - WLAN_CMD_SSID_START, - WLAN_AUTHENTICATE_WAIT, - WLAN_ASSOCIATE_WAIT, - WLAN_DISASSOCIATE_WAIT, - WLAN_CMD_TX_PSPACKET_START, - WLAN_CMD_AP_MODE_START, - WLAN_CMD_RADIO_START, - WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE, - WLAN_CMD_IDLE + WLAN_CMD_SCAN_START, + WLAN_CMD_SCAN_END, + WLAN_CMD_DISASSOCIATE_START, + WLAN_CMD_SSID_START, + WLAN_AUTHENTICATE_WAIT, + WLAN_ASSOCIATE_WAIT, + WLAN_DISASSOCIATE_WAIT, + WLAN_CMD_TX_PSPACKET_START, + WLAN_CMD_AP_MODE_START, + WLAN_CMD_RADIO_START, + WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE, + WLAN_CMD_IDLE } CMD_STATE, *PCMD_STATE; @@ -111,35 +111,35 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ void vResetCommandTimer( - void *hDeviceContext - ); + void *hDeviceContext +); void -vCommandTimer ( - void *hDeviceContext - ); +vCommandTimer( + void *hDeviceContext +); bool bClearBSSID_SCAN( - void *hDeviceContext - ); + void *hDeviceContext +); bool bScheduleCommand( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 - ); + void *hDeviceContext, + CMD_CODE eCommand, + unsigned char *pbyItem0 +); void vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond - ); + void *hDeviceContext, + unsigned int MSecond +); #ifdef TxInSleep void BSSvSecondTxData( - void *hDeviceContext - ); + void *hDeviceContext +); #endif #endif //__WCMD_H__ -- cgit From e2b8c6d3a5dbc9e3ba270bdf73bd78b6d0c81b01 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:10 -0700 Subject: staging:vt6655:wctl: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wctl.c | 246 +++++++++++++++++++++--------------------- drivers/staging/vt6655/wctl.h | 70 ++++++------ 2 files changed, 158 insertions(+), 158 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c index c096583a7726..6bd009ee9129 100644 --- a/drivers/staging/vt6655/wctl.c +++ b/drivers/staging/vt6655/wctl.c @@ -66,32 +66,32 @@ * */ -bool WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) +bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader) { - unsigned int uIndex; - unsigned int ii; - PSCacheEntry pCacheEntry; - - if (IS_FC_RETRY(pMACHeader)) { - - uIndex = pCache->uInPtr; - for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) { - pCacheEntry = &(pCache->asCacheEntry[uIndex]); - if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) && - (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) - ) { - /* Duplicate match */ - return true; - } - ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); - } - } - /* Not fount in cache - insert */ - pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; - pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; - memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); - return false; + unsigned int uIndex; + unsigned int ii; + PSCacheEntry pCacheEntry; + + if (IS_FC_RETRY(pMACHeader)) { + + uIndex = pCache->uInPtr; + for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) { + pCacheEntry = &(pCache->asCacheEntry[uIndex]); + if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) && + (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) +) { + /* Duplicate match */ + return true; + } + ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); + } + } + /* Not fount in cache - insert */ + pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; + pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; + memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); + ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); + return false; } /* @@ -108,19 +108,19 @@ bool WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) * Return Value: index number in Defragment Database * */ -unsigned int WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader) { -unsigned int ii; - - for(ii=0;iicbDFCB;ii++) { - if ((pDevice->sRxDFCB[ii].bInUse == true) && - (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) - ) { - // - return(ii); - } - } - return(pDevice->cbDFCB); + unsigned int ii; + + for (ii = 0; ii < pDevice->cbDFCB; ii++) { + if ((pDevice->sRxDFCB[ii].bInUse == true) && + (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) +) { + // + return(ii); + } + } + return(pDevice->cbDFCB); } @@ -138,24 +138,24 @@ unsigned int ii; * Return Value: index number in Defragment Database * */ -unsigned int WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader) { -unsigned int ii; - - if (pDevice->cbFreeDFCB == 0) - return(pDevice->cbDFCB); - for(ii=0;iicbDFCB;ii++) { - if (pDevice->sRxDFCB[ii].bInUse == false) { - pDevice->cbFreeDFCB--; - pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[ii].bInUse = true; - pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - return(ii); - } - } - return(pDevice->cbDFCB); + unsigned int ii; + + if (pDevice->cbFreeDFCB == 0) + return(pDevice->cbDFCB); + for (ii = 0; ii < pDevice->cbDFCB; ii++) { + if (pDevice->sRxDFCB[ii].bInUse == false) { + pDevice->cbFreeDFCB--; + pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; + pDevice->sRxDFCB[ii].bInUse = true; + pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); + pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); + memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); + return(ii); + } + } + return(pDevice->cbDFCB); } @@ -175,76 +175,76 @@ unsigned int ii; * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false * */ -bool WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV) +bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV) { -unsigned int uHeaderSize; - - - if (bWEP == true) { - uHeaderSize = 28; - if (bExtIV) - // ExtIV - uHeaderSize +=4; - } - else { - uHeaderSize = 24; - } - - if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) { - // duplicate, we must flush previous DCB - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - } - else { - pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) { - return(false); - } - } - // reserve 4 byte to match MAC RX Buffer - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (unsigned char *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); - return(false); - } - else { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) { - if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) && - (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) && - ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { - - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((unsigned char *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); - } - else { - // seq error or frag # error flush DFCB - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - return(false); - } - } - else { - return(false); - } - if (IS_LAST_FRAGMENT_PKT(pMACHeader)) { - //enq defragcontrolblock - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); - return(true); - } - return(false); - } + unsigned int uHeaderSize; + + + if (bWEP == true) { + uHeaderSize = 28; + if (bExtIV) + // ExtIV + uHeaderSize += 4; + } + else { + uHeaderSize = 24; + } + + if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) { + pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); + if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) { + // duplicate, we must flush previous DCB + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime; + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F); + } + else { + pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader); + if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) { + return(false); + } + } + // reserve 4 byte to match MAC RX Buffer + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (unsigned char *)(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); + memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); + return(false); + } + else { + pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); + if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) { + if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) && + (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) && + ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { + + memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((unsigned char *)(pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); + } + else { + // seq error or frag # error flush DFCB + pDevice->cbFreeDFCB++; + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; + return(false); + } + } + else { + return(false); + } + if (IS_LAST_FRAGMENT_PKT(pMACHeader)) { + //enq defragcontrolblock + pDevice->cbFreeDFCB++; + pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); + return(true); + } + return(false); + } } diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h index a92bb6d2b3f0..998fef979f27 100644 --- a/drivers/staging/vt6655/wctl.h +++ b/drivers/staging/vt6655/wctl.h @@ -35,60 +35,60 @@ /*--------------------- Export Definitions -------------------------*/ -#define IS_TYPE_DATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA) +#define IS_TYPE_DATA(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA) -#define IS_TYPE_MGMT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT) +#define IS_TYPE_MGMT(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT) -#define IS_TYPE_CONTROL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL) +#define IS_TYPE_CONTROL(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL) -#define IS_FC_MOREDATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA) +#define IS_FC_MOREDATA(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA) -#define IS_FC_POWERMGT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT) +#define IS_FC_POWERMGT(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT) -#define IS_FC_RETRY(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY) +#define IS_FC_RETRY(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY) -#define IS_FC_WEP(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP) +#define IS_FC_WEP(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP) #ifdef __BIG_ENDIAN -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0)) +#define IS_FRAGMENT_PKT(pMACHeader) \ + (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ + ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0)) -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0) +#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0) #else -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0)) +#define IS_FRAGMENT_PKT(pMACHeader) \ + (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ + ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0)) -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0) +#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0) #endif//#ifdef __BIG_ENDIAN -#define IS_LAST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0) +#define IS_LAST_FRAGMENT_PKT(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0) -#define IS_CTL_PSPOLL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) +#define IS_CTL_PSPOLL(pMACHeader) \ + ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) -#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \ - if ((uVar) >= ((uModulo) - 1)) \ - (uVar) = 0; \ - else \ - (uVar)++; \ -} +#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \ + if ((uVar) >= ((uModulo) - 1)) \ + (uVar) = 0; \ + else \ + (uVar)++; \ + } /*--------------------- Export Classes ----------------------------*/ @@ -99,7 +99,7 @@ bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader); bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, - unsigned int cbFrameLength, bool bWEP, bool bExtIV); + unsigned int cbFrameLength, bool bWEP, bool bExtIV); unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader); unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader); -- cgit From cb850a64d1396bfda67d9b2ba93b933db8f99f50 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:11 -0700 Subject: staging:vt6655:wmgr: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wmgr.c | 8154 ++++++++++++++++++++--------------------- drivers/staging/vt6655/wmgr.h | 514 +-- 2 files changed, 4334 insertions(+), 4334 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index b08a611a184a..2cc3514b5a39 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -89,246 +89,246 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Functions --------------------------*/ //2008-8-4 by chester static bool ChannelExceedZoneType( - PSDevice pDevice, - unsigned char byCurrChannel - ); + PSDevice pDevice, + unsigned char byCurrChannel +); // Association/diassociation functions static PSTxMgmtPacket s_MgrMakeAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pDAddr, + unsigned short wCurrCapInfo, + unsigned short wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); static void s_vMgrRxAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + unsigned int uNodeIndex +); static PSTxMgmtPacket s_MgrMakeReAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pDAddr, + unsigned short wCurrCapInfo, + unsigned short wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); static void s_vMgrRxAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + bool bReAssocType +); static void s_vMgrRxDisassociation( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); // Authentication/deauthen functions static void s_vMgrRxAuthenSequence_1( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +); static void s_vMgrRxAuthenSequence_2( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +); static void s_vMgrRxAuthenSequence_3( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +); static void s_vMgrRxAuthenSequence_4( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +); static void s_vMgrRxAuthentication( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); static void s_vMgrRxDeauthentication( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); // Scan functions // probe request/response functions static void s_vMgrRxProbeRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); static void s_vMgrRxProbeResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); // beacon functions static void s_vMgrRxBeacon( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + bool bInScan +); static void s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM - ); + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM +); static PSTxMgmtPacket s_MgrMakeBeacon( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wCurrBeaconPeriod, + unsigned int uCurrChannel, + unsigned short wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + unsigned char *pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); // Association response static PSTxMgmtPacket s_MgrMakeAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wAssocStatus, + unsigned short wAssocAID, + unsigned char *pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); // ReAssociation response static PSTxMgmtPacket s_MgrMakeReAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wAssocStatus, + unsigned short wAssocAID, + unsigned char *pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +); // Probe response static PSTxMgmtPacket s_MgrMakeProbeResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType - ); + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wCurrBeaconPeriod, + unsigned int uCurrChannel, + unsigned short wCurrATIMWinodw, + unsigned char *pDstAddr, + PWLAN_IE_SSID pCurrSSID, + unsigned char *pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + unsigned char byPHYType +); // received status static void s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus - ); + PSMgmtObject pMgmt, + unsigned short wStatus +); static void -s_vMgrSynchBSS ( - PSDevice pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus - ); +s_vMgrSynchBSS( + PSDevice pDevice, + unsigned int uBSSMode, + PKnownBSS pCurr, + PCMD_STATUS pStatus +); static bool -s_bCipherMatch ( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK - ); +s_bCipherMatch( + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, + unsigned char *pbyCCSPK, + unsigned char *pbyCCSGK +); - static void Encyption_Rebuild( - PSDevice pDevice, - PKnownBSS pCurr - ); +static void Encyption_Rebuild( + PSDevice pDevice, + PKnownBSS pCurr +); @@ -346,32 +346,32 @@ s_bCipherMatch ( * Return Value: * Ndis_staus. * --*/ + -*/ void vMgrObjectInit( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - - pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; - pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; - pMgmt->uCurrChannel = pDevice->uChannel; - for(ii=0;iiabyDesireBSSID[ii] = 0xFF; - } - pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1); - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_NONE; - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - BSSvClearBSSList((void *)pDevice, false); - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + int ii; + + + pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; + pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; + pMgmt->uCurrChannel = pDevice->uChannel; + for (ii = 0; ii < WLAN_BSSID_LEN; ii++) { + pMgmt->abyDesireBSSID[ii] = 0xFF; + } + pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1); + pMgmt->byCSSPK = KEY_CTL_NONE; + pMgmt->byCSSGK = KEY_CTL_NONE; + pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; + BSSvClearBSSList((void *)pDevice, false); + + return; } /*+ @@ -382,42 +382,42 @@ vMgrObjectInit( * Return Value: * Ndis_staus. * --*/ + -*/ void vMgrTimerInit( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - - init_timer(&pMgmt->sTimerSecondCallback); - pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice; - pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack; - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - - #ifdef TxInSleep - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->IsTxDataTrigger = false; - pDevice->nTxDataTimeCout = 0; - #endif - - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + + + init_timer(&pMgmt->sTimerSecondCallback); + pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice; + pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack; + pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); + + init_timer(&pDevice->sTimerCommand); + pDevice->sTimerCommand.data = (unsigned long) pDevice; + pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; + pDevice->sTimerCommand.expires = RUN_AT(HZ); + +#ifdef TxInSleep + init_timer(&pDevice->sTimerTxData); + pDevice->sTimerTxData.data = (unsigned long) pDevice; + pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; + pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback + pDevice->fTxDataInSleep = false; + pDevice->IsTxDataTrigger = false; + pDevice->nTxDataTimeCout = 0; +#endif + + pDevice->cbFreeCmdQueue = CMD_Q_SIZE; + pDevice->uCmdDequeueIdx = 0; + pDevice->uCmdEnqueueIdx = 0; + + return; } @@ -430,22 +430,22 @@ vMgrTimerInit( * Return Value: * None. * --*/ + -*/ void vMgrObjectReset( - void *hDeviceContext - ) + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bEnablePSMode = false; - // TODO: timer + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + pDevice->bEnablePSMode = false; + // TODO: timer - return; + return; } @@ -458,72 +458,72 @@ vMgrObjectReset( * Return Value: * None. * --*/ + -*/ void vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket; - - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - } - // always allow receive short preamble - //if (pDevice->byPreambleType == 1) { - // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - //} - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - } - if (pMgmt->b11hEnable == true) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - /* build an assocreq frame and send it */ - pTxPacket = s_MgrMakeAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if (pTxPacket != NULL ){ - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } - } - else - *pStatus = CMD_STATUS_RESOURCES; - - return ; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket; + + + pMgmt->wCurrCapInfo = 0; + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); + if (pDevice->bEncryptionEnable) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); + } + // always allow receive short preamble + //if (pDevice->byPreambleType == 1) { + // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + //} + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + if (pMgmt->wListenInterval == 0) + pMgmt->wListenInterval = 1; // at least one. + + // ERP Phy (802.11g) should support short preamble. + if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); + } + } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { + if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + } + } + if (pMgmt->b11hEnable == true) + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); + + /* build an assocreq frame and send it */ + pTxPacket = s_MgrMakeAssocRequest + ( + pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + pMgmt->wCurrCapInfo, + pMgmt->wListenInterval, + (PWLAN_IE_SSID)pMgmt->abyCurrSSID, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates +); + + if (pTxPacket != NULL) { + /* send the frame */ + *pStatus = csMgmt_xmit(pDevice, pTxPacket); + if (*pStatus == CMD_STATUS_PENDING) { + pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING; + *pStatus = CMD_STATUS_SUCCESS; + } + } + else + *pStatus = CMD_STATUS_RESOURCES; + + return; } @@ -535,75 +535,75 @@ vMgrAssocBeginSta( * Return Value: * None. * --*/ + -*/ void vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket; - - - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - } - - //if (pDevice->byPreambleType == 1) { - // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - //} - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - } - if (pMgmt->b11hEnable == true) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - - pTxPacket = s_MgrMakeReAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if (pTxPacket != NULL ){ - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n"); - } - } - - - return ; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket; + + + + pMgmt->wCurrCapInfo = 0; + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); + if (pDevice->bEncryptionEnable) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); + } + + //if (pDevice->byPreambleType == 1) { + // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + //} + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + + if (pMgmt->wListenInterval == 0) + pMgmt->wListenInterval = 1; // at least one. + + + // ERP Phy (802.11g) should support short preamble. + if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); + } + } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { + if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + } + } + if (pMgmt->b11hEnable == true) + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); + + + pTxPacket = s_MgrMakeReAssocRequest + ( + pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + pMgmt->wCurrCapInfo, + pMgmt->wListenInterval, + (PWLAN_IE_SSID)pMgmt->abyCurrSSID, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates +); + + if (pTxPacket != NULL) { + /* send the frame */ + *pStatus = csMgmt_xmit(pDevice, pTxPacket); + if (*pStatus != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n"); + } + } + + + return; } /*+ @@ -614,56 +614,56 @@ vMgrReAssocBeginSta( * Return Value: * None. * --*/ + -*/ void vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + unsigned char *abyDestAddress, + unsigned short wReason, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_DISASSOC sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DISASSOC_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeDisassociation(&sFrame); - - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC) - )); - - memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set reason code - *(sFrame.pwReason) = cpu_to_le16(wReason); - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - // send the frame - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - *pStatus = CMD_STATUS_SUCCESS; - } - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_DISASSOC sFrame; + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + + // Setup the sFrame structure + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_DISASSOC_FR_MAXLEN; + + // format fixed field frame structure + vMgrEncodeDisassociation(&sFrame); + + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC) +)); + + memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + // Set reason code + *(sFrame.pwReason) = cpu_to_le16(wReason); + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + // send the frame + *pStatus = csMgmt_xmit(pDevice, pTxPacket); + if (*pStatus == CMD_STATUS_PENDING) { + pMgmt->eCurrState = WMAC_STATE_IDLE; + *pStatus = CMD_STATUS_SUCCESS; + } + + return; } @@ -676,151 +676,151 @@ vMgrDisassocBeginSta( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + unsigned int uNodeIndex +) { - WLAN_FR_ASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ)); - memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - vMgrDecodeAssocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - uRateLen = WLAN_RATES_MAXLEN_11B; - } - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - } else { - abyCurrExtSuppRates[1] = 0; - } - - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; + WLAN_FR_ASSOCREQ sFrame; + CMD_STATUS Status; + PSTxMgmtPacket pTxPacket; + unsigned short wAssocStatus = 0; + unsigned short wAssocAID = 0; + unsigned int uRateLen = WLAN_RATES_MAXLEN; + unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + + + if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) + return; + // node index not found + if (!uNodeIndex) + return; + + //check if node is authenticated + //decode the frame + memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ)); + memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + + vMgrDecodeAssocRequest(&sFrame); + + if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; + pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); + pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = + WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; + // Todo: check sta basic rate, if ap can't support, set status code + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + uRateLen = WLAN_RATES_MAXLEN_11B; + } + abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; + abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, + uRateLen); + abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; + if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { + abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, + uRateLen); + } else { + abyCurrExtSuppRates[1] = 0; + } + + + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, + false, // do not change our basic rate + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) +); + + // set max tx rate + pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; #ifdef PLICE_DEBUG - printk("RxAssocRequest:wTxDataRate is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); + printk("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); #endif // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - // check if ERP support - if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { - pDevice->bBarkerPreambleMd = true; - } - - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ) ; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - }//else { TODO: received STA under state1 handle } - else { - return; - } - - - // assoc response reply.. - pTxPacket = s_MgrMakeAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - if (pTxPacket != NULL ){ - - if (pDevice->bEnableHostapd) { - return; - } - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n"); - } - - } - - return; + pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = + WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = + WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; + wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; + wAssocAID = (unsigned short)uNodeIndex; + // check if ERP support + if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) + pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; + + if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { + // B only STA join + pDevice->bProtectMode = true; + pDevice->bNonERPPresent = true; + } + if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { + pDevice->bBarkerPreambleMd = true; + } + + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", + sFrame.pHdr->sA3.abyAddr2[0], + sFrame.pHdr->sA3.abyAddr2[1], + sFrame.pHdr->sA3.abyAddr2[2], + sFrame.pHdr->sA3.abyAddr2[3], + sFrame.pHdr->sA3.abyAddr2[4], + sFrame.pHdr->sA3.abyAddr2[5] + ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n", + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); + }//else { TODO: received STA under state1 handle } + else { + return; + } + + + // assoc response reply.. + pTxPacket = s_MgrMakeAssocResponse + ( + pDevice, + pMgmt, + pMgmt->wCurrCapInfo, + wAssocStatus, + wAssocAID, + sFrame.pHdr->sA3.abyAddr2, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates +); + if (pTxPacket != NULL) { + + if (pDevice->bEnableHostapd) { + return; + } + /* send the frame */ + Status = csMgmt_xmit(pDevice, pTxPacket); + if (Status != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n"); + } + + } + + return; } @@ -838,145 +838,145 @@ s_vMgrRxAssocRequest( * * Return Value: None. * --*/ + -*/ static void s_vMgrRxReAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + unsigned int uNodeIndex +) { - WLAN_FR_REASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeReassocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - uRateLen = WLAN_RATES_MAXLEN_11B; - } - - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - } else { - abyCurrExtSuppRates[1] = 0; - } - - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; + WLAN_FR_REASSOCREQ sFrame; + CMD_STATUS Status; + PSTxMgmtPacket pTxPacket; + unsigned short wAssocStatus = 0; + unsigned short wAssocAID = 0; + unsigned int uRateLen = WLAN_RATES_MAXLEN; + unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + + if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) + return; + // node index not found + if (!uNodeIndex) + return; + //check if node is authenticated + //decode the frame + memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ)); + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeReassocRequest(&sFrame); + + if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; + pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); + pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = + WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; + // Todo: check sta basic rate, if ap can't support, set status code + + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + uRateLen = WLAN_RATES_MAXLEN_11B; + } + + abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; + abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, + uRateLen); + abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; + if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { + abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, + uRateLen); + } else { + abyCurrExtSuppRates[1] = 0; + } + + + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, + false, // do not change our basic rate + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) +); + + // set max tx rate + pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; #ifdef PLICE_DEBUG - printk("RxReAssocRequest:TxDataRate is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); + printk("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); #endif // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - - // if suppurt ERP - if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { - pDevice->bBarkerPreambleMd = true; - } - - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ) ; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - - } - - - // assoc response reply.. - pTxPacket = s_MgrMakeReAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if (pTxPacket != NULL ){ - /* send the frame */ - if (pDevice->bEnableHostapd) { - return; - } - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n"); - } - } - return; + pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = + WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = + WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; + wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; + wAssocAID = (unsigned short)uNodeIndex; + + // if suppurt ERP + if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) + pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; + + if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { + // B only STA join + pDevice->bProtectMode = true; + pDevice->bNonERPPresent = true; + } + if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { + pDevice->bBarkerPreambleMd = true; + } + + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", + sFrame.pHdr->sA3.abyAddr2[0], + sFrame.pHdr->sA3.abyAddr2[1], + sFrame.pHdr->sA3.abyAddr2[2], + sFrame.pHdr->sA3.abyAddr2[3], + sFrame.pHdr->sA3.abyAddr2[4], + sFrame.pHdr->sA3.abyAddr2[5] + ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n", + pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); + + } + + + // assoc response reply.. + pTxPacket = s_MgrMakeReAssocResponse + ( + pDevice, + pMgmt, + pMgmt->wCurrCapInfo, + wAssocStatus, + wAssocAID, + sFrame.pHdr->sA3.abyAddr2, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates + ); + + if (pTxPacket != NULL) { + /* send the frame */ + if (pDevice->bEnableHostapd) { + return; + } + Status = csMgmt_xmit(pDevice, pTxPacket); + if (Status != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n"); + } + } + return; } @@ -988,154 +988,154 @@ s_vMgrRxReAssocRequest( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + bool bReAssocType +) { - WLAN_FR_ASSOCRESP sFrame; - PWLAN_IE_SSID pItemSSID; - unsigned char *pbyIEs; - viawget_wpa_header *wpahdr; - - - - if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING || - pMgmt->eCurrState == WMAC_STATE_ASSOC) { - - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - // decode the frame - vMgrDecodeAssocResponse(&sFrame); - if ((sFrame.pwCapInfo == 0) || - (sFrame.pwStatus == 0) || - (sFrame.pwAid == 0) || - (sFrame.pSuppRates == 0)){ - DBG_PORT80(0xCC); - return; - } - - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid); - pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07; - - pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6; - pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength; - pbyIEs = pMgmt->sAssocInfo.abyIEs; - pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pbyIEs, (sFrame.pBuf + 24 +6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength); - - // save values and set current BSS state - if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){ - // set AID - pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid))); - if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) ) - { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n"); - } - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15)); - pMgmt->eCurrState = WMAC_STATE_ASSOC; - BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID); - pDevice->bLinkPass = true; - pDevice->uBBVGADiffCount = 0; - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - if(skb_tailroom(pDevice->skb) <(sizeof(viawget_wpa_header)+pMgmt->sAssocInfo.AssocInfo.ResponseIELength+ - pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough - dev_kfree_skb(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_ASSOC_MSG; - wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len); - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len, - pbyIEs, - wpahdr->resp_ie_len - ); - skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } + WLAN_FR_ASSOCRESP sFrame; + PWLAN_IE_SSID pItemSSID; + unsigned char *pbyIEs; + viawget_wpa_header *wpahdr; + + + + if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING || + pMgmt->eCurrState == WMAC_STATE_ASSOC) { + + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + // decode the frame + vMgrDecodeAssocResponse(&sFrame); + if ((sFrame.pwCapInfo == 0) || + (sFrame.pwStatus == 0) || + (sFrame.pwAid == 0) || + (sFrame.pSuppRates == 0)) { + DBG_PORT80(0xCC); + return; + } + + pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo); + pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus); + pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid); + pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07; + + pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6; + pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength; + pbyIEs = pMgmt->sAssocInfo.abyIEs; + pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength; + memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength); + + // save values and set current BSS state + if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { + // set AID + pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid))); + if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1)) + { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n"); + } + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14 | BIT15)); + pMgmt->eCurrState = WMAC_STATE_ASSOC; + BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID); + pDevice->bLinkPass = true; + pDevice->uBBVGADiffCount = 0; + if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { + if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength + + pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough + dev_kfree_skb(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + wpahdr->type = VIAWGET_ASSOC_MSG; + wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; + wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; + memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len); + memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len, + pbyIEs, + wpahdr->resp_ie_len +); + skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } //2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //if(pDevice->bWPADevEnable == true) - { - unsigned char buf[512]; - size_t len; - union iwreq_data wrqu; - int we_event; - - memset(buf, 0, 512); - - len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - if(len) { - memcpy(buf, pMgmt->sAssocInfo.abyIEs, len); - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCREQIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); + //if (pDevice->bWPADevEnable == true) + { + unsigned char buf[512]; + size_t len; + union iwreq_data wrqu; + int we_event; + + memset(buf, 0, 512); + + len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; + if (len) { + memcpy(buf, pMgmt->sAssocInfo.abyIEs, len); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = len; + we_event = IWEVASSOCREQIE; + wireless_send_event(pDevice->dev, we_event, &wrqu, buf); + } + + memset(buf, 0, 512); + len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; + + if (len) { + memcpy(buf, pbyIEs, len); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = len; + we_event = IWEVASSOCRESPIE; + wireless_send_event(pDevice->dev, we_event, &wrqu, buf); + } + + + memset(&wrqu, 0, sizeof(wrqu)); + memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT +//End Add -- //2008-0409-07, by Einsn Liu } - - memset(buf, 0, 512); - len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - - if(len) { - memcpy(buf, pbyIEs, len); - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCRESPIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); + else { + if (bReAssocType) { + pMgmt->eCurrState = WMAC_STATE_IDLE; + } + else { + // jump back to the auth state and indicate the error + pMgmt->eCurrState = WMAC_STATE_AUTH; + } + s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus)))); } - - memset(&wrqu, 0, sizeof (wrqu)); - memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } -#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, by Einsn Liu - } - else { - if (bReAssocType) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - else { - // jump back to the auth state and indicate the error - pMgmt->eCurrState = WMAC_STATE_AUTH; - } - s_vMgrLogStatus(pMgmt,cpu_to_le16((*(sFrame.pwStatus)))); - } - - } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //need clear flags related to Networkmanager - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = false; + pDevice->bwextcount = 0; + pDevice->bWPASuppWextEnabled = false; #endif -if(pMgmt->eCurrState == WMAC_STATE_ASSOC) - timer_expire(pDevice->sTimerCommand, 0); - return; + if (pMgmt->eCurrState == WMAC_STATE_ASSOC) + timer_expire(pDevice->sTimerCommand, 0); + return; } @@ -1149,51 +1149,51 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) * Return Value: * None. * --*/ + -*/ void vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY); - else - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM); - - *(sFrame.pwAuthSequence) = cpu_to_le16(1); - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING){ - pMgmt->eCurrState = WMAC_STATE_AUTHPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } - - return ; + PSDevice pDevice = (PSDevice)hDeviceContext; + WLAN_FR_AUTHEN sFrame; + PSTxMgmtPacket pTxPacket = NULL; + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_AUTHEN_FR_MAXLEN; + vMgrEncodeAuthen(&sFrame); + /* insert values */ + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + if (pMgmt->bShareKeyAlgorithm) + *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY); + else + *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM); + + *(sFrame.pwAuthSequence) = cpu_to_le16(1); + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + *pStatus = csMgmt_xmit(pDevice, pTxPacket); + if (*pStatus == CMD_STATUS_PENDING) { + pMgmt->eCurrState = WMAC_STATE_AUTHPENDING; + *pStatus = CMD_STATUS_SUCCESS; + } + + return; } @@ -1207,51 +1207,51 @@ vMgrAuthenBeginSta( * Return Value: * None. * --*/ + -*/ void vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + unsigned char *abyDestAddress, + unsigned short wReason, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - WLAN_FR_DEAUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN; - vMgrEncodeDeauthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN) - )); - - memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING){ - *pStatus = CMD_STATUS_SUCCESS; - } - - - return ; + PSDevice pDevice = (PSDevice)hDeviceContext; + WLAN_FR_DEAUTHEN sFrame; + PSTxMgmtPacket pTxPacket = NULL; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN; + vMgrEncodeDeauthen(&sFrame); + /* insert values */ + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN) +)); + + memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + *pStatus = csMgmt_xmit(pDevice, pTxPacket); + if (*pStatus == CMD_STATUS_PENDING) { + *pStatus = CMD_STATUS_SUCCESS; + } + + + return; } @@ -1263,49 +1263,49 @@ vMgrDeAuthenBeginSta( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAuthentication( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - WLAN_FR_AUTHEN sFrame; - - // we better be an AP or a STA in AUTHPENDING otherwise ignore - if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP || - pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) { - return; - } - - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeAuthen(&sFrame); - switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){ - case 1: - //AP function - s_vMgrRxAuthenSequence_1(pDevice,pMgmt, &sFrame); - break; - case 2: - s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame); - break; - case 3: - //AP function - s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame); - break; - case 4: - s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame); - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n", - cpu_to_le16((*(sFrame.pwAuthSequence)))); - break; - } - return; + WLAN_FR_AUTHEN sFrame; + + // we better be an AP or a STA in AUTHPENDING otherwise ignore + if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP || + pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) { + return; + } + + // decode the frame + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeAuthen(&sFrame); + switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) { + case 1: + //AP function + s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame); + break; + case 2: + s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame); + break; + case 3: + //AP function + s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame); + break; + case 4: + s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame); + break; + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n", + cpu_to_le16((*(sFrame.pwAuthSequence)))); + break; + } + return; } @@ -1320,99 +1320,99 @@ s_vMgrRxAuthentication( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAuthenSequence_1( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +) { - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uNodeIndex; - WLAN_FR_AUTHEN sFrame; - PSKeyItem pTransmitKey; - - // Insert a Node entry - if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2, - WLAN_ADDR_LEN); - } - - if (pMgmt->bShareKeyAlgorithm) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1; - } - else { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - } - - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(2); - - if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - } - else { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - } - - if (pMgmt->bShareKeyAlgorithm && - (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) { - - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN); - // get group key - if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) { - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3); - rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN); - } - memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN); - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) { - return; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n"); - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n"); - } - return; + PSTxMgmtPacket pTxPacket = NULL; + unsigned int uNodeIndex; + WLAN_FR_AUTHEN sFrame; + PSKeyItem pTransmitKey; + + // Insert a Node entry + if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { + BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); + memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2, + WLAN_ADDR_LEN); + } + + if (pMgmt->bShareKeyAlgorithm) { + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN; + pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1; + } + else { + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; + } + + // send auth reply + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_AUTHEN_FR_MAXLEN; + // format buffer structure + vMgrEncodeAuthen(&sFrame); + // insert values + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| + WLAN_SET_FC_ISWEP(0) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); + *(sFrame.pwAuthSequence) = cpu_to_le16(2); + + if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) { + if (pMgmt->bShareKeyAlgorithm) + *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); + else + *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); + } + else { + if (pMgmt->bShareKeyAlgorithm) + *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); + else + *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); + } + + if (pMgmt->bShareKeyAlgorithm && + (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) { + + sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); + sFrame.len += WLAN_CHALLENGE_IE_LEN; + sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; + sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; + memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN); + // get group key + if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) { + rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3); + rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN); + } + memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN); + } + + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + // send the frame + if (pDevice->bEnableHostapd) { + return; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n"); + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n"); + } + return; } @@ -1427,93 +1427,93 @@ s_vMgrRxAuthenSequence_1( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAuthenSequence_2( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +) { - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - - switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) - { - case WLAN_AUTH_ALG_OPENSYSTEM: - if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){ - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } - else { - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { + WLAN_FR_AUTHEN sFrame; + PSTxMgmtPacket pTxPacket = NULL; + + + switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) + { + case WLAN_AUTH_ALG_OPENSYSTEM: + if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n"); + pMgmt->eCurrState = WMAC_STATE_AUTH; + timer_expire(pDevice->sTimerCommand, 0); + } + else { + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n"); + s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); + pMgmt->eCurrState = WMAC_STATE_IDLE; + } + if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { // spin_unlock_irq(&pDevice->lock); // vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); - } - - break; - - case WLAN_AUTH_ALG_SHAREDKEY: - - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(1) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(3); - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memcpy( sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN); - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n"); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n"); - if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { + } + + break; + + case WLAN_AUTH_ALG_SHAREDKEY: + + if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_AUTHEN_FR_MAXLEN; + // format buffer structure + vMgrEncodeAuthen(&sFrame); + // insert values + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| + WLAN_SET_FC_ISWEP(1) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); + *(sFrame.pwAuthSequence) = cpu_to_le16(3); + *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); + sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); + sFrame.len += WLAN_CHALLENGE_IE_LEN; + sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; + sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; + memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN); + // Adjust the length fields + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + // send the frame + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n"); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n"); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n"); + if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { // spin_unlock_irq(&pDevice->lock); // vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); - } - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - } - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); - break; - } - return; + } + s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); + } + break; + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); + break; + } + return; } @@ -1529,81 +1529,81 @@ s_vMgrRxAuthenSequence_2( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAuthenSequence_3( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +) { - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uStatusCode = 0 ; - unsigned int uNodeIndex = 0; - WLAN_FR_AUTHEN sFrame; - - if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) { - uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ; - goto reply; - } - if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - } - else { - uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE; - goto reply; - } - - if (uNodeIndex) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0; - } - uStatusCode = WLAN_MGMT_STATUS_SUCCESS; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n"); + PSTxMgmtPacket pTxPacket = NULL; + unsigned int uStatusCode = 0; + unsigned int uNodeIndex = 0; + WLAN_FR_AUTHEN sFrame; + + if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) { + uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; + goto reply; + } + if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { + if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) { + uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ; + goto reply; + } + if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) { + uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; + goto reply; + } + } + else { + uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE; + goto reply; + } + + if (uNodeIndex) { + pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; + pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0; + } + uStatusCode = WLAN_MGMT_STATUS_SUCCESS; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n"); reply: - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(4); - *(sFrame.pwStatus) = cpu_to_le16(uStatusCode); - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) { - return; - } - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n"); - } - return; + // send auth reply + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_AUTHEN_FR_MAXLEN; + // format buffer structure + vMgrEncodeAuthen(&sFrame); + /* insert values */ + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| + WLAN_SET_FC_ISWEP(0) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); + *(sFrame.pwAuthSequence) = cpu_to_le16(4); + *(sFrame.pwStatus) = cpu_to_le16(uStatusCode); + + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + // send the frame + if (pDevice->bEnableHostapd) { + return; + } + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n"); + } + return; } @@ -1618,32 +1618,32 @@ reply: * Return Value: * None. * --*/ + -*/ static void s_vMgrRxAuthenSequence_4( - PSDevice pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame +) { - if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){ - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } - else{ - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))) ); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - - if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { + if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n"); + pMgmt->eCurrState = WMAC_STATE_AUTH; + timer_expire(pDevice->sTimerCommand, 0); + } + else{ + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n"); + s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); + pMgmt->eCurrState = WMAC_STATE_IDLE; + } + + if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { // spin_unlock_irq(&pDevice->lock); // vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); - } + } } @@ -1656,73 +1656,73 @@ s_vMgrRxAuthenSequence_4( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxDisassociation( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - WLAN_FR_DISASSOC sFrame; - unsigned int uNodeIndex = 0; + WLAN_FR_DISASSOC sFrame; + unsigned int uNodeIndex = 0; // CMD_STATUS CmdStatus; - viawget_wpa_header *wpahdr; - - if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){ - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { - BSSvRemoveOneNode(pDevice, uNodeIndex); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n"); - } - } - else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){ - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDisassociation(&sFrame); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason))); - //TODO: do something let upper layer know or - //try to send associate packet again because of inactivity timeout - // if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - // vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus); - // } - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - printk("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - #endif - } - /* else, ignore it */ - - return; + viawget_wpa_header *wpahdr; + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + // if is acting an AP.. + // a STA is leaving this BSS.. + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { + BSSvRemoveOneNode(pDevice, uNodeIndex); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n"); + } + } + else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeDisassociation(&sFrame); + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason))); + //TODO: do something let upper layer know or + //try to send associate packet again because of inactivity timeout + // if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { + // vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus); + // } + if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + wpahdr->type = VIAWGET_DISASSOC_MSG; + wpahdr->resp_ie_len = 0; + wpahdr->req_ie_len = 0; + skb_put(pDevice->skb, sizeof(viawget_wpa_header)); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } + +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + // if (pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + printk("wireless_send_event--->SIOCGIWAP(disassociated)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif + } + /* else, ignore it */ + + return; } @@ -1735,82 +1735,82 @@ s_vMgrRxDisassociation( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxDeauthentication( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - WLAN_FR_DEAUTHEN sFrame; - unsigned int uNodeIndex = 0; - viawget_wpa_header *wpahdr; - - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){ - //Todo: - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { - BSSvRemoveOneNode(pDevice, uNodeIndex); - } - else { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n"); - } - } - else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDeauthen(&sFrame); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason)))); - // TODO: update BSS list for specific BSSID if pre-authentication case - if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) { - if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - #endif - - } - /* else, ignore it. TODO: IBSS authentication service - would be implemented here */ - }; - return; + WLAN_FR_DEAUTHEN sFrame; + unsigned int uNodeIndex = 0; + viawget_wpa_header *wpahdr; + + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + //Todo: + // if is acting an AP.. + // a STA is leaving this BSS.. + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) { + BSSvRemoveOneNode(pDevice, uNodeIndex); + } + else { + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n"); + } + } + else { + if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeDeauthen(&sFrame); + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason)))); + // TODO: update BSS list for specific BSSID if pre-authentication case + if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) { + if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) { + pMgmt->sNodeDBTable[0].bActive = false; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pMgmt->eCurrState = WMAC_STATE_IDLE; + netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + } + } + + if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { + wpahdr = (viawget_wpa_header *)pDevice->skb->data; + wpahdr->type = VIAWGET_DISASSOC_MSG; + wpahdr->resp_ie_len = 0; + wpahdr->req_ie_len = 0; + skb_put(pDevice->skb, sizeof(viawget_wpa_header)); + pDevice->skb->dev = pDevice->wpadev; + skb_reset_mac_header(pDevice->skb); + pDevice->skb->pkt_type = PACKET_HOST; + pDevice->skb->protocol = htons(ETH_P_802_2); + memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); + netif_rx(pDevice->skb); + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + } + +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + // if (pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } +#endif + + } + /* else, ignore it. TODO: IBSS authentication service + would be implemented here */ + }; + return; } @@ -1825,30 +1825,30 @@ s_vMgrRxDeauthentication( * Return Value: * True:exceed; * False:normal case --*/ + -*/ static bool ChannelExceedZoneType( - PSDevice pDevice, - unsigned char byCurrChannel - ) + PSDevice pDevice, + unsigned char byCurrChannel +) { - bool exceed=false; + bool exceed = false; - switch(pDevice->byZoneType) { - case 0x00: //USA:1~11 - if((byCurrChannel<1) ||(byCurrChannel>11)) - exceed = true; - break; + switch (pDevice->byZoneType) { + case 0x00: //USA:1~11 + if ((byCurrChannel < 1) || (byCurrChannel > 11)) + exceed = true; + break; case 0x01: //Japan:1~13 case 0x02: //Europe:1~13 - if((byCurrChannel<1) ||(byCurrChannel>13)) - exceed = true; - break; + if ((byCurrChannel < 1) || (byCurrChannel > 13)) + exceed = true; + break; default: //reserve for other zonetype break; - } + } - return exceed; + return exceed; } @@ -1861,514 +1861,514 @@ ChannelExceedZoneType( * Return Value: * None. * --*/ + -*/ static void s_vMgrRxBeacon( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + bool bInScan +) { - PKnownBSS pBSSList; - WLAN_FR_BEACON sFrame; - QWORD qwTSFOffset; - bool bIsBSSIDEqual = false; - bool bIsSSIDEqual = false; - bool bTSFLargeDiff = false; - bool bTSFOffsetPostive = false; - bool bUpdateTSF = false; - bool bIsAPBeacon = false; - bool bIsChannelEqual = false; - unsigned int uLocateByteIndex; - unsigned char byTIMBitOn = 0; - unsigned short wAIDNumber = 0; - unsigned int uNodeIndex; - QWORD qwTimestamp, qwLocalTSF; - QWORD qwCurrTSF; - unsigned short wStartIndex = 0; - unsigned short wAIDIndex = 0; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - bool bChannelHit = false; - bool bUpdatePhyParameter = false; - unsigned char byIEChannel = 0; - - - memset(&sFrame, 0, sizeof(WLAN_FR_BEACON)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - // decode the beacon frame - vMgrDecodeBeacon(&sFrame); - - if ((sFrame.pwBeaconInterval == 0) || - (sFrame.pwCapInfo == 0) || - (sFrame.pSSID == 0) || - (sFrame.pSuppRates == 0) ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n"); - return; - } - - - if (sFrame.pDSParms != NULL) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } + PKnownBSS pBSSList; + WLAN_FR_BEACON sFrame; + QWORD qwTSFOffset; + bool bIsBSSIDEqual = false; + bool bIsSSIDEqual = false; + bool bTSFLargeDiff = false; + bool bTSFOffsetPostive = false; + bool bUpdateTSF = false; + bool bIsAPBeacon = false; + bool bIsChannelEqual = false; + unsigned int uLocateByteIndex; + unsigned char byTIMBitOn = 0; + unsigned short wAIDNumber = 0; + unsigned int uNodeIndex; + QWORD qwTimestamp, qwLocalTSF; + QWORD qwCurrTSF; + unsigned short wStartIndex = 0; + unsigned short wAIDIndex = 0; + unsigned char byCurrChannel = pRxPacket->byRxChannel; + ERPObject sERP; + unsigned int uRateLen = WLAN_RATES_MAXLEN; + bool bChannelHit = false; + bool bUpdatePhyParameter = false; + unsigned char byIEChannel = 0; + + + memset(&sFrame, 0, sizeof(WLAN_FR_BEACON)); + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + + // decode the beacon frame + vMgrDecodeBeacon(&sFrame); + + if ((sFrame.pwBeaconInterval == 0) || + (sFrame.pwCapInfo == 0) || + (sFrame.pSSID == 0) || + (sFrame.pSuppRates == 0)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n"); + return; + } + + + if (sFrame.pDSParms != NULL) { + if (byCurrChannel > CB_MAX_CHANNEL_24G) { + // channel remapping to + byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); + } else { + byIEChannel = sFrame.pDSParms->byCurrChannel; + } + if (byCurrChannel != byIEChannel) { + // adjust channel info. bcs we rcv adjacent channel packets + bChannelHit = false; + byCurrChannel = byIEChannel; + } + } else { + // no DS channel info + bChannelHit = true; + } //2008-0730-01by MikeLiu -if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket - ); - } - else { -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel); - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket - ); - - } - - if (bInScan) { - return; - } - - if(byCurrChannel == (unsigned char)pMgmt->uCurrChannel) - bIsChannelEqual = true; - - if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - - // if rx beacon without ERP field - if (sERP.bERPExist) { - if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)){ - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - } - else { - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if(!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - if(!sERP.bERPExist) - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - } - - // set to MAC&BBP - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)){ - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } - } - - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) - return; - - // check if BSSID the same - if (memcmp(sFrame.pHdr->sA3.abyAddr3, - pMgmt->abyCurrBSSID, - WLAN_BSSID_LEN) == 0) { - - bIsBSSIDEqual = true; + if (ChannelExceedZoneType(pDevice, byCurrChannel) == true) + return; + + if (sFrame.pERP != NULL) { + sERP.byERP = sFrame.pERP->byContext; + sERP.bERPExist = true; + + } else { + sERP.bERPExist = false; + sERP.byERP = 0; + } + + pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + if (pBSSList == NULL) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon/insert: RxChannel = : %d\n", byCurrChannel); + BSSbInsertToBSSList((void *)pDevice, + sFrame.pHdr->sA3.abyAddr3, + *sFrame.pqwTimestamp, + *sFrame.pwBeaconInterval, + *sFrame.pwCapInfo, + byCurrChannel, + sFrame.pSSID, + sFrame.pSuppRates, + sFrame.pExtSuppRates, + &sERP, + sFrame.pRSN, + sFrame.pRSNWPA, + sFrame.pIE_Country, + sFrame.pIE_Quiet, + sFrame.len - WLAN_HDR_ADDR3_LEN, + sFrame.pHdr->sA4.abyAddr4, // payload of beacon + (void *)pRxPacket +); + } + else { +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "update bcn: RxChannel = : %d\n", byCurrChannel); + BSSbUpdateToBSSList((void *)pDevice, + *sFrame.pqwTimestamp, + *sFrame.pwBeaconInterval, + *sFrame.pwCapInfo, + byCurrChannel, + bChannelHit, + sFrame.pSSID, + sFrame.pSuppRates, + sFrame.pExtSuppRates, + &sERP, + sFrame.pRSN, + sFrame.pRSNWPA, + sFrame.pIE_Country, + sFrame.pIE_Quiet, + pBSSList, + sFrame.len - WLAN_HDR_ADDR3_LEN, + sFrame.pHdr->sA4.abyAddr4, // payload of probresponse + (void *)pRxPacket +); + + } + + if (bInScan) { + return; + } + + if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel) + bIsChannelEqual = true; + + if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { + + // if rx beacon without ERP field + if (sERP.bERPExist) { + if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) { + pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); + pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; + } + } + else { + pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); + pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; + } + + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) + pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); + if (!sERP.bERPExist) + pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); + } + + // set to MAC&BBP + if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { + if (!pDevice->bProtectMode) { + MACvEnableProtectMD(pDevice->PortOffset); + pDevice->bProtectMode = true; + } + } + } + + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) + return; + + // check if BSSID the same + if (memcmp(sFrame.pHdr->sA3.abyAddr3, + pMgmt->abyCurrBSSID, + WLAN_BSSID_LEN) == 0) { + + bIsBSSIDEqual = true; // 2008-05-21 by Richardtai - pDevice->uCurrRSSI = pRxPacket->uRSSI; - pDevice->byCurrSQ = pRxPacket->bySQ; - - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) { - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp); - } - } - // check if SSID the same - if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) { - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - sFrame.pSSID->len - ) == 0) { - bIsSSIDEqual = true; - } - } - - if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== true) && - (bIsBSSIDEqual == true) && - (bIsSSIDEqual == true) && - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // add state check to prevent reconnect fail since we'll receive Beacon - - bIsAPBeacon = true; - - if (pBSSList != NULL) { - - // Compare PHY parameter setting - if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) { - bUpdatePhyParameter = true; - pMgmt->wCurrCapInfo = pBSSList->wCapInfo; - } - if (sFrame.pERP != NULL) { - if ((sFrame.pERP->byElementID == WLAN_EID_ERP) && - (pMgmt->byERPContext != sFrame.pERP->byContext)) { - bUpdatePhyParameter = true; - pMgmt->byERPContext = sFrame.pERP->byContext; - } - } - // - // Basic Rate Set may change dynamically - // - if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) { - uRateLen = WLAN_RATES_MAXLEN_11B; - } - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate( (void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) - ); + pDevice->uCurrRSSI = pRxPacket->uRSSI; + pDevice->byCurrSQ = pRxPacket->bySQ; + + if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) { + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp); + } + } + // check if SSID the same + if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) { + if (memcmp(sFrame.pSSID->abySSID, + ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, + sFrame.pSSID->len +) == 0) { + bIsSSIDEqual = true; + } + } + + if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) == true) && + (bIsBSSIDEqual == true) && + (bIsSSIDEqual == true) && + (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + // add state check to prevent reconnect fail since we'll receive Beacon + + bIsAPBeacon = true; + + if (pBSSList != NULL) { + + // Compare PHY parameter setting + if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) { + bUpdatePhyParameter = true; + pMgmt->wCurrCapInfo = pBSSList->wCapInfo; + } + if (sFrame.pERP != NULL) { + if ((sFrame.pERP->byElementID == WLAN_EID_ERP) && + (pMgmt->byERPContext != sFrame.pERP->byContext)) { + bUpdatePhyParameter = true; + pMgmt->byERPContext = sFrame.pERP->byContext; + } + } + // + // Basic Rate Set may change dynamically + // + if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) { + uRateLen = WLAN_RATES_MAXLEN_11B; + } + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + uRateLen); + pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + uRateLen); + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + true, + &(pMgmt->sNodeDBTable[0].wMaxBasicRate), + &(pMgmt->sNodeDBTable[0].wMaxSuppRate), + &(pMgmt->sNodeDBTable[0].wSuppRate), + &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) + ); #ifdef PLICE_DEBUG - //printk("RxBeacon:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate); + //printk("RxBeacon:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate); #endif if (bUpdatePhyParameter == true) { - CARDbSetPhyParameter( pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - } - if (sFrame.pIE_PowerConstraint != NULL) { - CARDvSetPowerConstraint(pMgmt->pAdapter, - (unsigned char) pBSSList->uChannel, - sFrame.pIE_PowerConstraint->byPower - ); - } - if (sFrame.pIE_CHSW != NULL) { - CARDbChannelSwitch( pMgmt->pAdapter, - sFrame.pIE_CHSW->byMode, - get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode), - sFrame.pIE_CHSW->byCount - ); - - } else if (bIsChannelEqual == false) { - set_channel(pMgmt->pAdapter, pBSSList->uChannel); - } - } - } - -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n"); - // check if CF field exists - if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { - if (sFrame.pCFParms->wCFPDurRemaining > 0) { - // TODO: deal with CFP period to set NAV - } - } - - HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp)); - LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp)); - HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF); - LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF); - - // check if beacon TSF larger or small than our local TSF - if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) { - if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) { - bTSFOffsetPostive = true; - } - else { - bTSFOffsetPostive = false; - } - } - else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) { - bTSFOffsetPostive = true; - } - else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) { - bTSFOffsetPostive = false; - } - - if (bTSFOffsetPostive) { - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF)); - } - else { - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp)); - } - - if (HIDWORD(qwTSFOffset) != 0 || - (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE )) { - bTSFLargeDiff = true; - } - - - // if infra mode - if (bIsAPBeacon == true) { - - // Infra mode: Local TSF always follow AP's TSF if Difference huge. - if (bTSFLargeDiff) - bUpdateTSF = true; - - if ((pDevice->bEnablePSMode == true) &&(sFrame.pTIM != 0)) { - - // deal with DTIM, analysis TIM - pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false ; - pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; - pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod; - wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15); - - // check if AID in TIM field bit on - // wStartIndex = N1 - wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1; - // AIDIndex = N2 - wAIDIndex = (wAIDNumber >> 3); - if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) { - uLocateByteIndex = wAIDIndex - wStartIndex; - // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250] - if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) { - byTIMBitOn = (0x01) << ((wAIDNumber) % 8); - pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false; - } - else { - pMgmt->bInTIM = false; - }; - } - else { - pMgmt->bInTIM = false; - }; - - if (pMgmt->bInTIM || - (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) { - pMgmt->bInTIMWake = true; - // send out ps-poll packet + CARDbSetPhyParameter(pMgmt->pAdapter, + pMgmt->eCurrentPHYMode, + pMgmt->wCurrCapInfo, + pMgmt->byERPContext, + pMgmt->abyCurrSuppRates, + pMgmt->abyCurrExtSuppRates + ); + } + if (sFrame.pIE_PowerConstraint != NULL) { + CARDvSetPowerConstraint(pMgmt->pAdapter, + (unsigned char) pBSSList->uChannel, + sFrame.pIE_PowerConstraint->byPower +); + } + if (sFrame.pIE_CHSW != NULL) { + CARDbChannelSwitch(pMgmt->pAdapter, + sFrame.pIE_CHSW->byMode, + get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode), + sFrame.pIE_CHSW->byCount + ); + + } else if (bIsChannelEqual == false) { + set_channel(pMgmt->pAdapter, pBSSList->uChannel); + } + } + } + +// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2 \n"); + // check if CF field exists + if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { + if (sFrame.pCFParms->wCFPDurRemaining > 0) { + // TODO: deal with CFP period to set NAV + } + } + + HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp)); + LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp)); + HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF); + LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF); + + // check if beacon TSF larger or small than our local TSF + if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) { + if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) { + bTSFOffsetPostive = true; + } + else { + bTSFOffsetPostive = false; + } + } + else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) { + bTSFOffsetPostive = true; + } + else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) { + bTSFOffsetPostive = false; + } + + if (bTSFOffsetPostive) { + qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF)); + } + else { + qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp)); + } + + if (HIDWORD(qwTSFOffset) != 0 || + (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE)) { + bTSFLargeDiff = true; + } + + + // if infra mode + if (bIsAPBeacon == true) { + + // Infra mode: Local TSF always follow AP's TSF if Difference huge. + if (bTSFLargeDiff) + bUpdateTSF = true; + + if ((pDevice->bEnablePSMode == true) && (sFrame.pTIM != 0)) { + + // deal with DTIM, analysis TIM + pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false; + pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; + pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod; + wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15); + + // check if AID in TIM field bit on + // wStartIndex = N1 + wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1; + // AIDIndex = N2 + wAIDIndex = (wAIDNumber >> 3); + if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) { + uLocateByteIndex = wAIDIndex - wStartIndex; + // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250] + if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) { + byTIMBitOn = (0x01) << ((wAIDNumber) % 8); + pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false; + } + else { + pMgmt->bInTIM = false; + }; + } + else { + pMgmt->bInTIM = false; + }; + + if (pMgmt->bInTIM || + (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) { + pMgmt->bInTIMWake = true; + // send out ps-poll packet // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n"); - if (pMgmt->bInTIM) { - PSvSendPSPOLL((PSDevice)pDevice); + if (pMgmt->bInTIM) { + PSvSendPSPOLL((PSDevice)pDevice); // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n"); - } - - } - else { - pMgmt->bInTIMWake = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n"); - if (pDevice->bPWBitOn == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n"); - if (PSbSendNullPacket(pDevice)) - pDevice->bPWBitOn = true; - } - if(PSbConsiderPowerDown(pDevice, false, false)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n"); - } - } - - } - - } - // if adhoc mode - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) { - if (bIsBSSIDEqual) { - // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count. - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - // adhoc mode:TSF updated only when beacon larger than local TSF - if (bTSFLargeDiff && bTSFOffsetPostive && - (pMgmt->eCurrState == WMAC_STATE_JOINTED)) - bUpdateTSF = true; - - // During dpc, already in spinlocked. - if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { - - // Update the STA, (Technically the Beacons of all the IBSS nodes - // should be identical, but that's not happening in practice. - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0; - } - else { - // Todo, initial Node content - BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); - - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; -#ifdef PLICE_DEBUG - //if (uNodeIndex == 0) - { - printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n",pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate,uNodeIndex); + } + + } + else { + pMgmt->bInTIMWake = false; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n"); + if (pDevice->bPWBitOn == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n"); + if (PSbSendNullPacket(pDevice)) + pDevice->bPWBitOn = true; + } + if (PSbConsiderPowerDown(pDevice, false, false)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n"); + } + } + } + + } + // if adhoc mode + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) { + if (bIsBSSIDEqual) { + // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count. + if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + + // adhoc mode:TSF updated only when beacon larger than local TSF + if (bTSFLargeDiff && bTSFOffsetPostive && + (pMgmt->eCurrState == WMAC_STATE_JOINTED)) + bUpdateTSF = true; + + // During dpc, already in spinlocked. + if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { + + // Update the STA, (Technically the Beacons of all the IBSS nodes + // should be identical, but that's not happening in practice. + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + WLAN_RATES_MAXLEN_11B); + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + NULL, + true, + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) + ); + pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0; + } + else { + // Todo, initial Node content + BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); + + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + WLAN_RATES_MAXLEN_11B); + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + NULL, + true, + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), + &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) + ); + + memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); + pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); + pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; +#ifdef PLICE_DEBUG + //if (uNodeIndex == 0) + { + printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex); + } #endif /* - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; + pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); + if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) + pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; */ - } - - // if other stations joined, indicate connection to upper layer.. - if (pMgmt->eCurrState == WMAC_STATE_STARTED) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n"); - pMgmt->eCurrState = WMAC_STATE_JOINTED; - pDevice->bLinkPass = true; - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - } - } - else if (bIsSSIDEqual) { - - // See other adhoc sta with the same SSID but BSSID is different. - // adpot this vars only when TSF larger then us. - if (bTSFLargeDiff && bTSFOffsetPostive) { - // we don't support ATIM under adhoc mode - // if ( sFrame.pIBSSParms->wATIMWindow == 0) { - // adpot this vars - // TODO: check sFrame cap if privacy on, and support rate syn - memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN); - memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow); - pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval); - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set HW beacon interval and re-synchronizing.... - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n"); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - // Turn off bssid filter to avoid filter others adhoc station which bssid is different. - MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - - CARDbSetPhyParameter ( pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates); - - - // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - // set highest basic rate - // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates); - // Prepare beacon frame - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - // } - } - } - } - // endian issue ??? - // Update TSF - if (bUpdateTSF) { - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF); - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - } - - return; + } + + // if other stations joined, indicate connection to upper layer.. + if (pMgmt->eCurrState == WMAC_STATE_STARTED) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n"); + pMgmt->eCurrState = WMAC_STATE_JOINTED; + pDevice->bLinkPass = true; + if (netif_queue_stopped(pDevice->dev)) { + netif_wake_queue(pDevice->dev); + } + pMgmt->sNodeDBTable[0].bActive = true; + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + + } + } + else if (bIsSSIDEqual) { + + // See other adhoc sta with the same SSID but BSSID is different. + // adpot this vars only when TSF larger then us. + if (bTSFLargeDiff && bTSFOffsetPostive) { + // we don't support ATIM under adhoc mode + // if (sFrame.pIBSSParms->wATIMWindow == 0) { + // adpot this vars + // TODO: check sFrame cap if privacy on, and support rate syn + memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN); + memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow); + pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval); + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + WLAN_RATES_MAXLEN_11B); + // set HW beacon interval and re-synchronizing.... + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n"); + VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod); + CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF); + CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); + // Turn off bssid filter to avoid filter others adhoc station which bssid is different. + MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); + + CARDbSetPhyParameter(pMgmt->pAdapter, + pMgmt->eCurrentPHYMode, + pMgmt->wCurrCapInfo, + pMgmt->byERPContext, + pMgmt->abyCurrSuppRates, + pMgmt->abyCurrExtSuppRates); + + + // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); + // set highest basic rate + // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates); + // Prepare beacon frame + bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); + // } + } + } + } + // endian issue ??? + // Update TSF + if (bUpdateTSF) { + CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); + CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF); + CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); + CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); + } + + return; } @@ -2384,731 +2384,731 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) * Return Value: * CMD_STATUS * --*/ + -*/ void vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus - ) + void *hDeviceContext, + PCMD_STATUS pStatus +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wMaxBasicRate; - unsigned short wMaxSuppRate; - unsigned char byTopCCKBasicRate; - unsigned char byTopOFDMBasicRate; - QWORD qwCurrTSF; - unsigned int ii; - unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60}; - unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96}; - unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned short wSuppRate; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) { - // encryption mode error - *pStatus = CMD_STATUS_FAILURE; - return; - } - } - - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - pMgmt->eCurrentPHYMode = pMgmt->byAPBBType; - } else { - if (pDevice->byBBType == BB_TYPE_11G) - pMgmt->eCurrentPHYMode = PHY_TYPE_11G; - if (pDevice->byBBType == BB_TYPE_11B) - pMgmt->eCurrentPHYMode = PHY_TYPE_11B; - if (pDevice->byBBType == BB_TYPE_11A) - pMgmt->eCurrentPHYMode = PHY_TYPE_11A; - } - - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { - pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } else { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } - - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 4; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii]; - for (ii = 4; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4]; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4]; - } - - - // Disable Protect Mode - pDevice->bProtectMode = 0; - MACvDisableProtectMD(pDevice->PortOffset); - - pDevice->bBarkerPreambleMd = 0; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - - // Kyle Test 2003.11.04 - - // set HW beacon interval - if (pMgmt->wIBSSBeaconPeriod == 0) - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - - - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - // clear TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - // set Next TBTT - CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod); - - pMgmt->uIBSSChannel = pDevice->uChannel; - - if (pMgmt->uIBSSChannel == 0) - pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL; - - - // set basic rate - - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - pMgmt->eCurrMode = WMAC_MODE_ESS_AP; - } - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6); - pMgmt->byIBSSDFSRecovery = 10; - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; - } - - // Adopt pre-configured IBSS vars to current vars - pMgmt->eCurrState = WMAC_STATE_STARTED; - pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod; - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow; - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pDevice->uCurrRSSI = 0; - pDevice->byCurrSQ = 0; - //memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID, - // ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN); - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrSSID, - pMgmt->abyDesireSSID, - ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN - ); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - // AP mode BSSID = MAC addr - memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%pM\n", - pMgmt->abyCurrBSSID); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - - // BSSID selected must be randomized as spec 11.1.3 - pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF)& 0x000000ff); - pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8); - pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16); - pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4); - pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12); - pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20); - pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0]; - pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1]; - pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2]; - pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3]; - pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4]; - pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5]; - pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP; - pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - - - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%pM\n", - pMgmt->abyCurrBSSID); - } - - // Set Capability Info - pMgmt->wCurrCapInfo = 0; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD; - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1); - } - - if (pDevice->bEncryptionEnable) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; - } else { - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } else { - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } - - pMgmt->byERPContext = 0; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned short wMaxBasicRate; + unsigned short wMaxSuppRate; + unsigned char byTopCCKBasicRate; + unsigned char byTopOFDMBasicRate; + QWORD qwCurrTSF; + unsigned int ii; + unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60}; + unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96}; + unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; + unsigned short wSuppRate; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n"); + + if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) && + (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) && + (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) { + // encryption mode error + *pStatus = CMD_STATUS_FAILURE; + return; + } + } -// memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; + pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + pMgmt->eCurrentPHYMode = pMgmt->byAPBBType; + } else { + if (pDevice->byBBType == BB_TYPE_11G) + pMgmt->eCurrentPHYMode = PHY_TYPE_11G; + if (pDevice->byBBType == BB_TYPE_11B) + pMgmt->eCurrentPHYMode = PHY_TYPE_11B; + if (pDevice->byBBType == BB_TYPE_11A) + pMgmt->eCurrentPHYMode = PHY_TYPE_11A; + } - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); - } - - CARDbSetPhyParameter( pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - - CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod); - // set channel and clear NAV - set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel); - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - - if (CARDbIsShortPreamble(pMgmt->pAdapter)) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } else { - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1)); - } - - if ((pMgmt->b11hEnable == true) && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - } else { - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1)); - } - - pMgmt->eCurrState = WMAC_STATE_STARTED; - // Prepare beacon to send - if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) { - *pStatus = CMD_STATUS_SUCCESS; - } - - return ; -} + if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { + pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B; + pMgmt->abyCurrExtSuppRates[1] = 0; + for (ii = 0; ii < 4; ii++) + pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; + } else { + pMgmt->abyCurrSuppRates[1] = 8; + pMgmt->abyCurrExtSuppRates[1] = 0; + for (ii = 0; ii < 8; ii++) + pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; + } + if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { + pMgmt->abyCurrSuppRates[1] = 8; + pMgmt->abyCurrExtSuppRates[1] = 4; + for (ii = 0; ii < 4; ii++) + pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii]; + for (ii = 4; ii < 8; ii++) + pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4]; + for (ii = 0; ii < 4; ii++) + pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4]; + } -/*+ - * - * Routine Description: - * Instructs wmac to join a bss using the supplied attributes. - * The arguments may the BSSID or SSID and the rest of the - * attributes are obtained from the scan result of known bss list. - * - * - * Return Value: - * None. - * --*/ -void -vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus - ) -{ + // Disable Protect Mode + pDevice->bProtectMode = 0; + MACvDisableProtectMD(pDevice->PortOffset); - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pCurr = NULL; - unsigned int ii, uu; - PWLAN_IE_SUPP_RATES pItemRates = NULL; - PWLAN_IE_SUPP_RATES pItemExtRates = NULL; - PWLAN_IE_SSID pItemSSID; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned short wMaxBasicRate = RATE_1M; - unsigned short wMaxSuppRate = RATE_1M; - unsigned short wSuppRate; - unsigned char byTopCCKBasicRate = RATE_1M; - unsigned char byTopOFDMBasicRate = RATE_1M; - - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive == true) - break; - } - - if (ii == MAX_BSS_NUM) { - *pStatus = CMD_STATUS_RESOURCES; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n"); - return; - } - - // memset(pMgmt->abyDesireBSSID, 0, WLAN_BSSID_LEN); - // Search known BSS list for prefer BSSID or SSID - - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode - ); - - if (pCurr == NULL){ - *pStatus = CMD_STATUS_RESOURCES; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID); - return; - } - - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n"); - if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){ - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA)||(pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { - - // patch for CISCO migration mode -/* - if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } -*/ - } + pDevice->bBarkerPreambleMd = 0; + MACvDisableBarkerPreambleMd(pDevice->PortOffset); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //if(pDevice->bWPASuppWextEnabled == true) - Encyption_Rebuild(pDevice, pCurr); -#endif - // Infrastructure BSS - s_vMgrSynchBSS(pDevice, - WMAC_MODE_ESS_STA, - pCurr, - pStatus - ); - - if (*pStatus == CMD_STATUS_SUCCESS){ - - // Adopt this BSS state vars in Mgmt Object - pMgmt->uCurrChannel = pCurr->uChannel; - - memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { - uRateLen = WLAN_RATES_MAXLEN_11B; - } - - pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates; - pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates; - - // Parse Support Rate IE - pItemRates->byElementID = WLAN_EID_SUPP_RATES; - pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - pItemRates, - uRateLen); - - // Parse Extension Support Rate IE - pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES; - pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates, - pItemExtRates, - uRateLen); - // Stuffing Rate IE - if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) { - for (ii = 0; ii < (unsigned int)(8 - pItemRates->len); ) { - pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii]; - ii ++; - if (pItemExtRates->len <= ii) - break; - } - pItemRates->len += (unsigned char)ii; - if (pItemExtRates->len - ii > 0) { - pItemExtRates->len -= (unsigned char)ii; - for (uu = 0; uu < pItemExtRates->len; uu ++) { - pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii]; - } - } else { - pItemExtRates->len = 0; - } - } - - RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - // TODO: deal with if wCapInfo the privacy is on, but station WEP is off - // TODO: deal with if wCapInfo the PS-Pollable is on. - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - pMgmt->eCurrMode = WMAC_MODE_ESS_STA; - - pMgmt->eCurrState = WMAC_STATE_JOINTED; - // Adopt BSS state in Adapter Device Object - //pDevice->byOpMode = OP_MODE_INFRASTRUCTURE; -// memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); + // Kyle Test 2003.11.04 - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult); - if (bResult == false) { - vFlush_PMKID_Candidate((void *)pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n"); - bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - } - } - - // Preamble type auto-switch: if AP can receive short-preamble cap, - // we can turn on too. - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n"); - - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n"); - } - else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - }; - - - } - else { - // ad-hoc mode BSS - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - - if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } - - s_vMgrSynchBSS(pDevice, - WMAC_MODE_IBSS_STA, - pCurr, - pStatus - ); - - if (*pStatus == CMD_STATUS_SUCCESS){ - // Adopt this BSS state vars in Mgmt Object - // TODO: check if CapInfo privacy on, but we don't.. - pMgmt->uCurrChannel = pCurr->uChannel; - - - // Parse Support Rate IE - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set basic rate - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - pMgmt->wCurrCapInfo = pCurr->wCapInfo; - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); -// pMgmt->wCurrATIMWindow = pCurr->wATIMWindow; - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; + // set HW beacon interval + if (pMgmt->wIBSSBeaconPeriod == 0) + pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - pMgmt->eCurrState = WMAC_STATE_STARTED; - // Adopt BSS state in Adapter Device Object - //pDevice->byOpMode = OP_MODE_ADHOC; -// pDevice->bLinkPass = true; -// memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%pM\n", - pMgmt->abyCurrBSSID); - // Preamble type auto-switch: if AP can receive short-preamble cap, - // and if registry setting is short preamble we can turn on too. - - // Prepare beacon - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } - else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - }; - }; - return; -} + CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); + // clear TSF counter + VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); + // enable TSF counter + VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + // set Next TBTT + CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod); + pMgmt->uIBSSChannel = pDevice->uChannel; -/*+ - * - * Routine Description: - * Set HW to synchronize a specific BSS from known BSS list. - * - * - * Return Value: - * PCM_STATUS + if (pMgmt->uIBSSChannel == 0) + pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL; + + + // set basic rate + + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true, + &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, + &byTopCCKBasicRate, &byTopOFDMBasicRate); + + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + pMgmt->eCurrMode = WMAC_MODE_ESS_AP; + } + + if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { + memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6); + pMgmt->byIBSSDFSRecovery = 10; + pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; + } + + // Adopt pre-configured IBSS vars to current vars + pMgmt->eCurrState = WMAC_STATE_STARTED; + pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod; + pMgmt->uCurrChannel = pMgmt->uIBSSChannel; + pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow; + MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); + pDevice->uCurrRSSI = 0; + pDevice->byCurrSQ = 0; + //memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID, + // ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN); + memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + memcpy(pMgmt->abyCurrSSID, + pMgmt->abyDesireSSID, + ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN +); + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + // AP mode BSSID = MAC addr + memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "AP beacon created BSSID:%pM\n", + pMgmt->abyCurrBSSID); + } + + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + + // BSSID selected must be randomized as spec 11.1.3 + pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF) & 0x000000ff); + pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0000ff00) >> 8); + pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00ff0000) >> 16); + pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00000ff0) >> 4); + pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF) & 0x000ff000) >> 12); + pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0ff00000) >> 20); + pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0]; + pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1]; + pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2]; + pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3]; + pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4]; + pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5]; + pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP; + pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; + + + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Adhoc beacon created bssid:%pM\n", + pMgmt->abyCurrBSSID); + } + + // Set Capability Info + pMgmt->wCurrCapInfo = 0; + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); + pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD; + pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; + } + + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1); + } + + if (pDevice->bEncryptionEnable) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); + if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + pMgmt->byCSSPK = KEY_CTL_CCMP; + pMgmt->byCSSGK = KEY_CTL_CCMP; + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + pMgmt->byCSSPK = KEY_CTL_TKIP; + pMgmt->byCSSGK = KEY_CTL_TKIP; + } else { + pMgmt->byCSSPK = KEY_CTL_NONE; + pMgmt->byCSSGK = KEY_CTL_WEP; + } + } else { + pMgmt->byCSSPK = KEY_CTL_WEP; + pMgmt->byCSSGK = KEY_CTL_WEP; + } + } + + pMgmt->byERPContext = 0; + +// memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP); + } else { + CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC); + } + + CARDbSetPhyParameter(pMgmt->pAdapter, + pMgmt->eCurrentPHYMode, + pMgmt->wCurrCapInfo, + pMgmt->byERPContext, + pMgmt->abyCurrSuppRates, + pMgmt->abyCurrExtSuppRates + ); + + CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod); + // set channel and clear NAV + set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel); + pMgmt->uCurrChannel = pMgmt->uIBSSChannel; + + if (CARDbIsShortPreamble(pMgmt->pAdapter)) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); + } else { + pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1)); + } + + if ((pMgmt->b11hEnable == true) && + (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); + } else { + pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1)); + } + + pMgmt->eCurrState = WMAC_STATE_STARTED; + // Prepare beacon to send + if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) { + *pStatus = CMD_STATUS_SUCCESS; + } + + return; +} + + + +/*+ + * + * Routine Description: + * Instructs wmac to join a bss using the supplied attributes. + * The arguments may the BSSID or SSID and the rest of the + * attributes are obtained from the scan result of known bss list. + * + * + * Return Value: + * None. + * + -*/ + +void +vMgrJoinBSSBegin( + void *hDeviceContext, + PCMD_STATUS pStatus +) +{ + + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = pDevice->pMgmt; + PKnownBSS pCurr = NULL; + unsigned int ii, uu; + PWLAN_IE_SUPP_RATES pItemRates = NULL; + PWLAN_IE_SUPP_RATES pItemExtRates = NULL; + PWLAN_IE_SSID pItemSSID; + unsigned int uRateLen = WLAN_RATES_MAXLEN; + unsigned short wMaxBasicRate = RATE_1M; + unsigned short wMaxSuppRate = RATE_1M; + unsigned short wSuppRate; + unsigned char byTopCCKBasicRate = RATE_1M; + unsigned char byTopOFDMBasicRate = RATE_1M; + + + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + if (pMgmt->sBSSList[ii].bActive == true) + break; + } + + if (ii == MAX_BSS_NUM) { + *pStatus = CMD_STATUS_RESOURCES; + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n"); + return; + } + + // memset(pMgmt->abyDesireBSSID, 0, WLAN_BSSID_LEN); + // Search known BSS list for prefer BSSID or SSID + + pCurr = BSSpSearchBSSList(pDevice, + pMgmt->abyDesireBSSID, + pMgmt->abyDesireSSID, + pMgmt->eConfigPHYMode +); + + if (pCurr == NULL) { + *pStatus = CMD_STATUS_RESOURCES; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID); + return; + } + + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n"); + if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) { + + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { + + // patch for CISCO migration mode +/* + if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + // encryption mode error + pMgmt->eCurrState = WMAC_STATE_IDLE; + return; + } + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + // encryption mode error + pMgmt->eCurrState = WMAC_STATE_IDLE; + return; + } + } +*/ + } + +#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT + //if (pDevice->bWPASuppWextEnabled == true) + Encyption_Rebuild(pDevice, pCurr); +#endif + // Infrastructure BSS + s_vMgrSynchBSS(pDevice, + WMAC_MODE_ESS_STA, + pCurr, + pStatus +); + + if (*pStatus == CMD_STATUS_SUCCESS) { + + // Adopt this BSS state vars in Mgmt Object + pMgmt->uCurrChannel = pCurr->uChannel; + + memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); + + if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { + uRateLen = WLAN_RATES_MAXLEN_11B; + } + + pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates; + pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates; + + // Parse Support Rate IE + pItemRates->byElementID = WLAN_EID_SUPP_RATES; + pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, + pItemRates, + uRateLen); + + // Parse Extension Support Rate IE + pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES; + pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates, + pItemExtRates, + uRateLen); + // Stuffing Rate IE + if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) { + for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) { + pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii]; + ii++; + if (pItemExtRates->len <= ii) + break; + } + pItemRates->len += (unsigned char)ii; + if (pItemExtRates->len - ii > 0) { + pItemExtRates->len -= (unsigned char)ii; + for (uu = 0; uu < pItemExtRates->len; uu++) { + pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii]; + } + } else { + pItemExtRates->len = 0; + } + } + + RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true, + &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, + &byTopCCKBasicRate, &byTopOFDMBasicRate); + + // TODO: deal with if wCapInfo the privacy is on, but station WEP is off + // TODO: deal with if wCapInfo the PS-Pollable is on. + pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; + memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); + memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + + pMgmt->eCurrMode = WMAC_MODE_ESS_STA; + + pMgmt->eCurrState = WMAC_STATE_JOINTED; + // Adopt BSS state in Adapter Device Object + //pDevice->byOpMode = OP_MODE_INFRASTRUCTURE; +// memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); + + // Add current BSS to Candidate list + // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. + if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { + bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult); + if (bResult == false) { + vFlush_PMKID_Candidate((void *)pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n"); + bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + } + } + + // Preamble type auto-switch: if AP can receive short-preamble cap, + // we can turn on too. + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join ESS\n"); + + + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n"); + } + else { + pMgmt->eCurrState = WMAC_STATE_IDLE; + }; + + + } + else { + // ad-hoc mode BSS + if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + + if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) { + // encryption mode error + pMgmt->eCurrState = WMAC_STATE_IDLE; + return; + } + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) { + // encryption mode error + pMgmt->eCurrState = WMAC_STATE_IDLE; + return; + } + } else { + // encryption mode error + pMgmt->eCurrState = WMAC_STATE_IDLE; + return; + } + } + + s_vMgrSynchBSS(pDevice, + WMAC_MODE_IBSS_STA, + pCurr, + pStatus +); + + if (*pStatus == CMD_STATUS_SUCCESS) { + // Adopt this BSS state vars in Mgmt Object + // TODO: check if CapInfo privacy on, but we don't.. + pMgmt->uCurrChannel = pCurr->uChannel; + + + // Parse Support Rate IE + pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; + pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + WLAN_RATES_MAXLEN_11B); + // set basic rate + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, + &byTopCCKBasicRate, &byTopOFDMBasicRate); + + pMgmt->wCurrCapInfo = pCurr->wCapInfo; + pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; + memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); + memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); + memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); +// pMgmt->wCurrATIMWindow = pCurr->wATIMWindow; + MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); + pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; + + pMgmt->eCurrState = WMAC_STATE_STARTED; + // Adopt BSS state in Adapter Device Object + //pDevice->byOpMode = OP_MODE_ADHOC; +// pDevice->bLinkPass = true; +// memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join IBSS ok:%pM\n", + pMgmt->abyCurrBSSID); + // Preamble type auto-switch: if AP can receive short-preamble cap, + // and if registry setting is short preamble we can turn on too. + + // Prepare beacon + bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); + } + else { + pMgmt->eCurrState = WMAC_STATE_IDLE; + }; + }; + return; +} + + + +/*+ * --*/ + * Routine Description: + * Set HW to synchronize a specific BSS from known BSS list. + * + * + * Return Value: + * PCM_STATUS + * + -*/ static void -s_vMgrSynchBSS ( - PSDevice pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus - ) +s_vMgrSynchBSS( + PSDevice pDevice, + unsigned int uBSSMode, + PKnownBSS pCurr, + PCMD_STATUS pStatus +) { - CARD_PHY_TYPE ePhyType = PHY_TYPE_11B; - PSMgmtObject pMgmt = pDevice->pMgmt; + CARD_PHY_TYPE ePhyType = PHY_TYPE_11B; + PSMgmtObject pMgmt = pDevice->pMgmt; // int ii; - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - - - *pStatus = CMD_STATUS_FAILURE; - - if (s_bCipherMatch(pCurr, - pDevice->eEncryptionStatus, - &(pMgmt->byCSSPK), - &(pMgmt->byCSSGK)) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n"); - return; - } - - pMgmt->pCurrBSS = pCurr; - - // if previous mode is IBSS. - if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY); - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - // Init the BSS informations - pDevice->bCCK = true; - pDevice->bProtectMode = false; - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bNonERPPresent = false; - pDevice->byPreambleType = 0; - pDevice->wBasicRate = 0; - // Set Basic Rate - CARDbAddBasicRate((void *)pDevice, RATE_1M); - // calculate TSF offset - // TSF Offset = Received Timestamp TSF - Marked Local's TSF - CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF); - - CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval); - - // set Next TBTT - // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval - CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval); - - // set BSSID - MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID); - - MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); + //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M + unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; + unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; + //6M, 9M, 12M, 48M + unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; + unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; + + + *pStatus = CMD_STATUS_FAILURE; + + if (s_bCipherMatch(pCurr, + pDevice->eEncryptionStatus, + &(pMgmt->byCSSPK), + &(pMgmt->byCSSGK)) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n"); + return; + } + + pMgmt->pCurrBSS = pCurr; + + // if previous mode is IBSS. + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY); + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + } + + // Init the BSS informations + pDevice->bCCK = true; + pDevice->bProtectMode = false; + MACvDisableProtectMD(pDevice->PortOffset); + pDevice->bBarkerPreambleMd = false; + MACvDisableBarkerPreambleMd(pDevice->PortOffset); + pDevice->bNonERPPresent = false; + pDevice->byPreambleType = 0; + pDevice->wBasicRate = 0; + // Set Basic Rate + CARDbAddBasicRate((void *)pDevice, RATE_1M); + // calculate TSF offset + // TSF Offset = Received Timestamp TSF - Marked Local's TSF + CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF); + + CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval); + + // set Next TBTT + // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval + CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval); + + // set BSSID + MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID); + + MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = " "%pM\n", pMgmt->abyCurrBSSID); - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11A; - } else { - return; - } - } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) || - (pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } else { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11G; - } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } - - if (ePhyType == PHY_TYPE_11A) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else if (ePhyType == PHY_TYPE_11B) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG)); - memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG)); - } - - - if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE); - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap); - } - } else { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC); - } - - if (CARDbSetPhyParameter( pMgmt->pAdapter, - ePhyType, - pCurr->wCapInfo, - pCurr->sERP.byERP, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ) != true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); - return; - } - // set channel and clear NAV - if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel); - return; - } + if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { + if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || + (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { + ePhyType = PHY_TYPE_11A; + } else { + return; + } + } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { + if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) || + (pMgmt->eConfigPHYMode == PHY_TYPE_11G) || + (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { + ePhyType = PHY_TYPE_11B; + } else { + return; + } + } else { + if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) || + (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { + ePhyType = PHY_TYPE_11G; + } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) { + ePhyType = PHY_TYPE_11B; + } else { + return; + } + } + + if (ePhyType == PHY_TYPE_11A) { + memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA)); + pMgmt->abyCurrExtSuppRates[1] = 0; + } else if (ePhyType == PHY_TYPE_11B) { + memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB)); + pMgmt->abyCurrExtSuppRates[1] = 0; + } else { + memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG)); + memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG)); + } + + + if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) { + CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE); + // Add current BSS to Candidate list + // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. + if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { + CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap); + } + } else { + CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC); + } + + if (CARDbSetPhyParameter(pMgmt->pAdapter, + ePhyType, + pCurr->wCapInfo, + pCurr->sERP.byERP, + pMgmt->abyCurrSuppRates, + pMgmt->abyCurrExtSuppRates + ) != true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); + return; + } + // set channel and clear NAV + if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel); + return; + } /* - for (ii=0;iildBmMAX< pDevice->ldBmThreshold[ii]) { - pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; - break; - } - } - - if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] \n", - (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); - printk("RSSI[%d] NewGain[%d] OldGain[%d] \n", - (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); - } - printk("ldBmMAX[%d] NewGain[%d] OldGain[%d] \n", - (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); + for (ii=0; iildBmMAX< pDevice->ldBmThreshold[ii]) { + pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; + break; + } + } + + if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] \n", + (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); + printk("RSSI[%d] NewGain[%d] OldGain[%d] \n", + (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); + } + printk("ldBmMAX[%d] NewGain[%d] OldGain[%d] \n", + (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent); */ - pMgmt->uCurrChannel = pCurr->uChannel; - pMgmt->eCurrentPHYMode = ePhyType; - pMgmt->byERPContext = pCurr->sERP.byERP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); + pMgmt->uCurrChannel = pCurr->uChannel; + pMgmt->eCurrentPHYMode = ePhyType; + pMgmt->byERPContext = pCurr->sERP.byERP; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); - *pStatus = CMD_STATUS_SUCCESS; + *pStatus = CMD_STATUS_SUCCESS; - return; + return; }; //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus - static void Encyption_Rebuild( - PSDevice pDevice, - PKnownBSS pCurr - ) - { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - // unsigned int ii , uSameBssidNum=0; - - // for (ii = 0; ii < MAX_BSS_NUM; ii++) { - // if (pMgmt->sBSSList[ii].bActive && - // !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) { - // uSameBssidNum++; - // } - // } - // if( uSameBssidNum>=2) { //we only check AP in hidden sssid mode - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. - if(pCurr->bWPAValid == true) { //WPA-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - if(pCurr->abyPKType[0] == WPA_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n"); - } - else if(pCurr->abyPKType[0] == WPA_AESCCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n"); - } - } - else if(pCurr->bWPA2Valid == true) { //WPA2-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n"); - } - else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n"); - } - } - } - // } - return; - } +static void Encyption_Rebuild( + PSDevice pDevice, + PKnownBSS pCurr +) +{ + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + // unsigned int ii , uSameBssidNum=0; + + // for (ii = 0; ii < MAX_BSS_NUM; ii++) { + // if (pMgmt->sBSSList[ii].bActive && + // !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) { + // uSameBssidNum++; + // } + // } + // if (uSameBssidNum>=2) { //we only check AP in hidden sssid mode + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. + if (pCurr->bWPAValid == true) { //WPA-PSK + pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; + if (pCurr->abyPKType[0] == WPA_TKIP) { + pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP + PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n"); + } + else if (pCurr->abyPKType[0] == WPA_AESCCMP) { + pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES + PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n"); + } + } + else if (pCurr->bWPA2Valid == true) { //WPA2-PSK + pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; + if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) { + pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP + PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n"); + } + else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) { + pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES + PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n"); + } + } + } + // } + return; +} /*+ @@ -3120,293 +3120,293 @@ s_vMgrSynchBSS ( * Return Value: * void * --*/ + -*/ static void s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM - ) + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM +) { - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned char byMap; - unsigned int ii, jj; - bool bStartFound = false; - bool bMulticast = false; - unsigned short wStartIndex = 0; - unsigned short wEndIndex = 0; - - - // Find size of partial virtual bitmap - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - byMap = pMgmt->abyPSTxMap[ii]; - if (!ii) { - // Mask out the broadcast bit which is indicated separately. - bMulticast = (byMap & byMask[0]) != 0; - if(bMulticast) { - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - } - byMap = 0; - } - if (byMap) { - if (!bStartFound) { - bStartFound = true; - wStartIndex = ii; - } - wEndIndex = ii; - } - } - - - // Round start index down to nearest even number - wStartIndex &= ~BIT0; - - // Round end index up to nearest even number - wEndIndex = ((wEndIndex + 1) & ~BIT0); - - // Size of element payload - - pTIM->len = 3 + (wEndIndex - wStartIndex) + 1; - - // Fill in the Fixed parts of the TIM - pTIM->byDTIMCount = pMgmt->byDTIMCount; - pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod; - pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) | - (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK); - - // Append variable part of TIM - - for (ii = wStartIndex, jj =0 ; ii <= wEndIndex; ii++, jj++) { - pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii]; - } - - // Aid = 0 don't used. - pTIM->byVirtBitMap[0] &= ~BIT0; + unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + unsigned char byMap; + unsigned int ii, jj; + bool bStartFound = false; + bool bMulticast = false; + unsigned short wStartIndex = 0; + unsigned short wEndIndex = 0; + + + // Find size of partial virtual bitmap + for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { + byMap = pMgmt->abyPSTxMap[ii]; + if (!ii) { + // Mask out the broadcast bit which is indicated separately. + bMulticast = (byMap & byMask[0]) != 0; + if (bMulticast) { + pMgmt->sNodeDBTable[0].bRxPSPoll = true; + } + byMap = 0; + } + if (byMap) { + if (!bStartFound) { + bStartFound = true; + wStartIndex = ii; + } + wEndIndex = ii; + } + } + + + // Round start index down to nearest even number + wStartIndex &= ~BIT0; + + // Round end index up to nearest even number + wEndIndex = ((wEndIndex + 1) & ~BIT0); + + // Size of element payload + + pTIM->len = 3 + (wEndIndex - wStartIndex) + 1; + + // Fill in the Fixed parts of the TIM + pTIM->byDTIMCount = pMgmt->byDTIMCount; + pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod; + pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) | + (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK); + + // Append variable part of TIM + + for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++) { + pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii]; + } + + // Aid = 0 don't used. + pTIM->byVirtBitMap[0] &= ~BIT0; } /*+ * * Routine Description: - * Constructs an Beacon frame( Ad-hoc mode) + * Constructs an Beacon frame(Ad-hoc mode) * * * Return Value: * PTR to frame; or NULL on allocation failure * --*/ + -*/ static PSTxMgmtPacket s_MgrMakeBeacon( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wCurrBeaconPeriod, + unsigned int uCurrChannel, + unsigned short wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + unsigned char *pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_BEACON sFrame; - unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - // prepare beacon frame - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_BEACON_FR_MAXLEN; - vMgrEncodeBeacon(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON) - )); - - if (pDevice->bEnablePSMode) { - sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1)); - } - - memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN - ); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN - ); - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - // TIM field - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len); - sFrame.pTIM->byElementID = WLAN_EID_TIM; - s_vMgrFormatTIM(pMgmt, sFrame.pTIM); - sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - /* RSN parameter */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 12; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40 - else - sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 0; - // Auth Key Management Suite - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; - sFrame.pRSNWPA->len +=2; - - // RSN Capabilities - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0; - sFrame.pRSNWPA->len +=2; - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - } - } - - if ((pMgmt->b11hEnable == true) && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel == true) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy( pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN - ); - } - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_BEACON sFrame; + unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + unsigned char *pbyBuffer; + unsigned int uLength = 0; + PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; + unsigned int ii; + + // prepare beacon frame + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + // Setup the sFrame structure. + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_BEACON_FR_MAXLEN; + vMgrEncodeBeacon(&sFrame); + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON) +)); + + if (pDevice->bEnablePSMode) { + sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1)); + } + + memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); + *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); + *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); + // Copy SSID + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, + pCurrSSID, + ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN +); + // Copy the rate set + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, + pCurrSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN +); + // DS parameter + if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { + sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); + sFrame.len += (1) + WLAN_IEHDR_LEN; + sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; + sFrame.pDSParms->len = 1; + sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; + } + // TIM field + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len); + sFrame.pTIM->byElementID = WLAN_EID_TIM; + s_vMgrFormatTIM(pMgmt, sFrame.pTIM); + sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len); + } + + if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + + // IBSS parameter + sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); + sFrame.len += (2) + WLAN_IEHDR_LEN; + sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; + sFrame.pIBSSParms->len = 2; + sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + /* RSN parameter */ + sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); + sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; + sFrame.pRSNWPA->len = 12; + sFrame.pRSNWPA->abyOUI[0] = 0x00; + sFrame.pRSNWPA->abyOUI[1] = 0x50; + sFrame.pRSNWPA->abyOUI[2] = 0xf2; + sFrame.pRSNWPA->abyOUI[3] = 0x01; + sFrame.pRSNWPA->wVersion = 1; + sFrame.pRSNWPA->abyMulticast[0] = 0x00; + sFrame.pRSNWPA->abyMulticast[1] = 0x50; + sFrame.pRSNWPA->abyMulticast[2] = 0xf2; + if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) + sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) + sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) + sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40 + else + sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE + + // Pairwise Key Cipher Suite + sFrame.pRSNWPA->wPKCount = 0; + // Auth Key Management Suite + *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; + sFrame.pRSNWPA->len += 2; + + // RSN Capabilities + *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; + sFrame.pRSNWPA->len += 2; + sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + } + } + + if ((pMgmt->b11hEnable == true) && + (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { + // Country IE + pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); + set_country_IE(pMgmt->pAdapter, pbyBuffer); + set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); + uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; + pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); + // Power Constrain IE + ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; + ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; + ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; + pbyBuffer += (1) + WLAN_IEHDR_LEN; + uLength += (1) + WLAN_IEHDR_LEN; + if (pMgmt->bSwitchChannel == true) { + // Channel Switch IE + ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; + ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; + ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; + ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); + ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; + pbyBuffer += (3) + WLAN_IEHDR_LEN; + uLength += (3) + WLAN_IEHDR_LEN; + } + // TPC report + ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; + ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; + ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); + ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; + pbyBuffer += (2) + WLAN_IEHDR_LEN; + uLength += (2) + WLAN_IEHDR_LEN; + // IBSS DFS + if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { + pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; + pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; + pIBSSDFS->len = 7; + memcpy(pIBSSDFS->abyDFSOwner, + pMgmt->abyIBSSDFSOwner, + 6); + pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; + pbyBuffer += (7) + WLAN_IEHDR_LEN; + uLength += (7) + WLAN_IEHDR_LEN; + for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) { + if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { + pbyBuffer += 2; + uLength += 2; + pIBSSDFS->len += 2; + } + } + } + sFrame.len += uLength; + } + + if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { + sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); + sFrame.len += 1 + WLAN_IEHDR_LEN; + sFrame.pERP->byElementID = WLAN_EID_ERP; + sFrame.pERP->len = 1; + sFrame.pERP->byContext = 0; + if (pDevice->bProtectMode == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; + if (pDevice->bNonERPPresent == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; + if (pDevice->bBarkerPreambleMd == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; + } + if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, + pCurrExtSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN +); + } + // hostapd wpa/wpa2 IE + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { + if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + if (pMgmt->wWPAIELen != 0) { + sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); + memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); + sFrame.len += pMgmt->wWPAIELen; + } + } + } + + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -3422,184 +3422,184 @@ s_MgrMakeBeacon( * Return Value: * PTR to frame; or NULL on allocation failure * --*/ + -*/ PSTxMgmtPacket s_MgrMakeProbeResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wCurrBeaconPeriod, + unsigned int uCurrChannel, + unsigned short wCurrATIMWinodw, + unsigned char *pDstAddr, + PWLAN_IE_SSID pCurrSSID, + unsigned char *pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + unsigned char byPHYType +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBERESP_FR_MAXLEN; - vMgrEncodeProbeResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - - if (byPHYType == BB_TYPE_11B) { - *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); - } - - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN - ); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN - ); - - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = 0; - } - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd == true) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - - if ((pMgmt->b11hEnable == true) && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel == true) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy( pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for(ii=CB_MAX_CHANNEL_24G+1; ii<=CB_MAX_CHANNEL; ii++ ) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN - ); - } - - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_PROBERESP sFrame; + unsigned char *pbyBuffer; + unsigned int uLength = 0; + PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; + unsigned int ii; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + // Setup the sFrame structure. + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_PROBERESP_FR_MAXLEN; + vMgrEncodeProbeResponse(&sFrame); + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); + *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); + *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); + + if (byPHYType == BB_TYPE_11B) { + *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); + } + + // Copy SSID + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, + pCurrSSID, + ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN +); + // Copy the rate set + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, + pCurrSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN +); + + // DS parameter + if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { + sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); + sFrame.len += (1) + WLAN_IEHDR_LEN; + sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; + sFrame.pDSParms->len = 1; + sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; + } + + if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { + // IBSS parameter + sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); + sFrame.len += (2) + WLAN_IEHDR_LEN; + sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; + sFrame.pIBSSParms->len = 2; + sFrame.pIBSSParms->wATIMWindow = 0; + } + if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { + sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); + sFrame.len += 1 + WLAN_IEHDR_LEN; + sFrame.pERP->byElementID = WLAN_EID_ERP; + sFrame.pERP->len = 1; + sFrame.pERP->byContext = 0; + if (pDevice->bProtectMode == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; + if (pDevice->bNonERPPresent == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; + if (pDevice->bBarkerPreambleMd == true) + sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; + } + + if ((pMgmt->b11hEnable == true) && + (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { + // Country IE + pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); + set_country_IE(pMgmt->pAdapter, pbyBuffer); + set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); + uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; + pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); + // Power Constrain IE + ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; + ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; + ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; + pbyBuffer += (1) + WLAN_IEHDR_LEN; + uLength += (1) + WLAN_IEHDR_LEN; + if (pMgmt->bSwitchChannel == true) { + // Channel Switch IE + ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; + ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; + ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; + ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); + ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; + pbyBuffer += (3) + WLAN_IEHDR_LEN; + uLength += (3) + WLAN_IEHDR_LEN; + } + // TPC report + ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; + ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; + ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); + ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; + pbyBuffer += (2) + WLAN_IEHDR_LEN; + uLength += (2) + WLAN_IEHDR_LEN; + // IBSS DFS + if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { + pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; + pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; + pIBSSDFS->len = 7; + memcpy(pIBSSDFS->abyDFSOwner, + pMgmt->abyIBSSDFSOwner, + 6); + pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; + pbyBuffer += (7) + WLAN_IEHDR_LEN; + uLength += (7) + WLAN_IEHDR_LEN; + for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { + if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { + pbyBuffer += 2; + uLength += 2; + pIBSSDFS->len += 2; + } + } + } + sFrame.len += uLength; + } + + + if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, + pCurrExtSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN +); + } + + // hostapd wpa/wpa2 IE + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { + if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { + if (pMgmt->wWPAIELen != 0) { + sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); + memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); + sFrame.len += pMgmt->wWPAIELen; + } + } + } + + // Adjust the length fields + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -3613,263 +3613,263 @@ s_MgrMakeProbeResponse( * Return Value: * A ptr to frame or NULL on allocation failure * --*/ + -*/ PSTxMgmtPacket s_MgrMakeAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pDAddr, + unsigned short wCurrCapInfo, + unsigned short wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN; - // format fixed field frame structure - vMgrEncodeAssocRequest(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set the capability and listen interval - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - // sFrame.len point to end of fixed field - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4)) - sFrame.len += 4 + WLAN_IEHDR_LEN; - else - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - // for 802.11h - if (pMgmt->b11hEnable == true) { - if (sFrame.pCurrPowerCap == NULL) { - sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len); - sFrame.len += (2 + WLAN_IEHDR_LEN); - sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY; - sFrame.pCurrPowerCap->len = 2; - CARDvGetPowerCapability(pMgmt->pAdapter, - &(sFrame.pCurrPowerCap->byMinPower), - &(sFrame.pCurrPowerCap->byMaxPower) - ); - } - if (sFrame.pCurrSuppCh == NULL) { - sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len); - sFrame.len += set_support_channels(pMgmt->pAdapter,(unsigned char *)sFrame.pCurrSuppCh); - } - } - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) { - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - } else { - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - } - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - } else { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - } - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++=0x01; - *pbyRSN++=0x00; - *pbyRSN++=0x00; - - *pbyRSN++=0x50; - *pbyRSN++=0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) { - *pbyRSN++=WPA_AUTH_PSK; - } - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) { - *pbyRSN++=WPA_AUTH_IEEE802_1X; - } - else { - *pbyRSN++=WPA_NONE; - } - - sFrame.pRSNWPA->len +=6; - - // RSN Capabilities - - *pbyRSN++=0x00; - *pbyRSN++=0x00; - sFrame.pRSNWPA->len +=2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - // WPA IE - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) { - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - } else { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - } - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - } else { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - } - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - } else { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - } - sFrame.pRSN->len +=6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len +=2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID) ++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - if (*pwPMKID != 0) { - sFrame.pRSN->len += (2 + (*pwPMKID)*16); - } - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_ASSOCREQ sFrame; + unsigned char *pbyIEs; + unsigned char *pbyRSN; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + // Setup the sFrame structure. + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN; + // format fixed field frame structure + vMgrEncodeAssocRequest(&sFrame); + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + // Set the capability and listen interval + *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); + *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); + + // sFrame.len point to end of fixed field + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); + + pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; + pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + pbyIEs = pMgmt->sAssocInfo.abyIEs; + memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); + pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; + + // Copy the rate set + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4)) + sFrame.len += 4 + WLAN_IEHDR_LEN; + else + sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + + // Copy the extension rate set + if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); + } + + pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; + + // for 802.11h + if (pMgmt->b11hEnable == true) { + if (sFrame.pCurrPowerCap == NULL) { + sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len); + sFrame.len += (2 + WLAN_IEHDR_LEN); + sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY; + sFrame.pCurrPowerCap->len = 2; + CARDvGetPowerCapability(pMgmt->pAdapter, + &(sFrame.pCurrPowerCap->byMinPower), + &(sFrame.pCurrPowerCap->byMaxPower) +); + } + if (sFrame.pCurrSuppCh == NULL) { + sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len); + sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh); + } + } + + if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && + (pMgmt->pCurrBSS != NULL)) { + /* WPA IE */ + sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); + sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; + sFrame.pRSNWPA->len = 16; + sFrame.pRSNWPA->abyOUI[0] = 0x00; + sFrame.pRSNWPA->abyOUI[1] = 0x50; + sFrame.pRSNWPA->abyOUI[2] = 0xf2; + sFrame.pRSNWPA->abyOUI[3] = 0x01; + sFrame.pRSNWPA->wVersion = 1; + //Group Key Cipher Suite + sFrame.pRSNWPA->abyMulticast[0] = 0x00; + sFrame.pRSNWPA->abyMulticast[1] = 0x50; + sFrame.pRSNWPA->abyMulticast[2] = 0xf2; + if (pMgmt->byCSSGK == KEY_CTL_WEP) { + sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; + } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { + sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; + } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { + sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; + } else { + sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; + } + // Pairwise Key Cipher Suite + sFrame.pRSNWPA->wPKCount = 1; + sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; + sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; + sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; + if (pMgmt->byCSSPK == KEY_CTL_TKIP) { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; + } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; + } else { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; + } + // Auth Key Management Suite + pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); + *pbyRSN++ = 0x01; + *pbyRSN++ = 0x00; + *pbyRSN++ = 0x00; + + *pbyRSN++ = 0x50; + *pbyRSN++ = 0xf2; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) { + *pbyRSN++ = WPA_AUTH_PSK; + } + else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) { + *pbyRSN++ = WPA_AUTH_IEEE802_1X; + } + else { + *pbyRSN++ = WPA_NONE; + } + + sFrame.pRSNWPA->len += 6; + + // RSN Capabilities + + *pbyRSN++ = 0x00; + *pbyRSN++ = 0x00; + sFrame.pRSNWPA->len += 2; + + sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION + pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); + pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + + } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && + (pMgmt->pCurrBSS != NULL)) { + unsigned int ii; + unsigned short *pwPMKID; + + // WPA IE + sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); + sFrame.pRSN->byElementID = WLAN_EID_RSN; + sFrame.pRSN->len = 6; //Version(2)+GK(4) + sFrame.pRSN->wVersion = 1; + //Group Key Cipher Suite + sFrame.pRSN->abyRSN[0] = 0x00; + sFrame.pRSN->abyRSN[1] = 0x0F; + sFrame.pRSN->abyRSN[2] = 0xAC; + if (pMgmt->byCSSGK == KEY_CTL_WEP) { + sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; + } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; + } else { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; + } + + // Pairwise Key Cipher Suite + sFrame.pRSN->abyRSN[4] = 1; + sFrame.pRSN->abyRSN[5] = 0; + sFrame.pRSN->abyRSN[6] = 0x00; + sFrame.pRSN->abyRSN[7] = 0x0F; + sFrame.pRSN->abyRSN[8] = 0xAC; + if (pMgmt->byCSSPK == KEY_CTL_TKIP) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; + } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; + } else { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; + } + sFrame.pRSN->len += 6; + + // Auth Key Management Suite + sFrame.pRSN->abyRSN[10] = 1; + sFrame.pRSN->abyRSN[11] = 0; + sFrame.pRSN->abyRSN[12] = 0x00; + sFrame.pRSN->abyRSN[13] = 0x0F; + sFrame.pRSN->abyRSN[14] = 0xAC; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; + } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; + } else { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; + } + sFrame.pRSN->len += 6; + + // RSN Capabilities + if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { + memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); + } else { + sFrame.pRSN->abyRSN[16] = 0; + sFrame.pRSN->abyRSN[17] = 0; + } + sFrame.pRSN->len += 2; + + if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { + // RSN PMKID + pbyRSN = &sFrame.pRSN->abyRSN[18]; + pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count + *pwPMKID = 0; // Initialize PMKID count + pbyRSN += 2; // Point to PMKID list + for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { + if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); + pbyRSN += 16; + } + } + if (*pwPMKID != 0) { + sFrame.pRSN->len += (2 + (*pwPMKID)*16); + } + } + + sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; + // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION + pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); + pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; + } + + + // Adjust the length fields + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + return pTxPacket; } @@ -3888,245 +3888,245 @@ s_MgrMakeAssocRequest( * Return Value: * A ptr to frame or NULL on allocation failure * --*/ + -*/ PSTxMgmtPacket s_MgrMakeReAssocRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned char *pDAddr, + unsigned short wCurrCapInfo, + unsigned short wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset( pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - /* Setup the sFrame structure. */ - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeReassocRequest(&sFrame); - - /* Setup the header */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - /* Set the capability and listen interval */ - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - /* Copy the SSID */ - /* sFrame.len point to end of fixed field */ - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - /* Copy the rate set */ - /* sFrame.len point to end of SSID */ - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) { - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - } else { - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - } - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - } else { - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - } - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++=0x01; - *pbyRSN++=0x00; - *pbyRSN++=0x00; - - *pbyRSN++=0x50; - *pbyRSN++=0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) { - *pbyRSN++=WPA_AUTH_PSK; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) { - *pbyRSN++=WPA_AUTH_IEEE802_1X; - } else { - *pbyRSN++=WPA_NONE; - } - - sFrame.pRSNWPA->len +=6; - - // RSN Capabilities - *pbyRSN++=0x00; - *pbyRSN++=0x00; - sFrame.pRSNWPA->len +=2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - /* WPA IE */ - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) { - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - } else { - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - } - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - } else { - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - } - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - } else { - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - } - sFrame.pRSN->len +=6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len +=2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID) ++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - if (*pwPMKID != 0) { - sFrame.pRSN->len += (2 + (*pwPMKID)*16); - } - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_REASSOCREQ sFrame; + unsigned char *pbyIEs; + unsigned char *pbyRSN; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + /* Setup the sFrame structure. */ + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN; + + // format fixed field frame structure + vMgrEncodeReassocRequest(&sFrame); + + /* Setup the header */ + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + /* Set the capability and listen interval */ + *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); + *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); + + memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + /* Copy the SSID */ + /* sFrame.len point to end of fixed field */ + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); + + pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; + pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + pbyIEs = pMgmt->sAssocInfo.abyIEs; + memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); + pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; + + /* Copy the rate set */ + /* sFrame.len point to end of SSID */ + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + + // Copy the extension rate set + if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); + } + + pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; + + if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && + (pMgmt->pCurrBSS != NULL)) { + /* WPA IE */ + sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); + sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; + sFrame.pRSNWPA->len = 16; + sFrame.pRSNWPA->abyOUI[0] = 0x00; + sFrame.pRSNWPA->abyOUI[1] = 0x50; + sFrame.pRSNWPA->abyOUI[2] = 0xf2; + sFrame.pRSNWPA->abyOUI[3] = 0x01; + sFrame.pRSNWPA->wVersion = 1; + //Group Key Cipher Suite + sFrame.pRSNWPA->abyMulticast[0] = 0x00; + sFrame.pRSNWPA->abyMulticast[1] = 0x50; + sFrame.pRSNWPA->abyMulticast[2] = 0xf2; + if (pMgmt->byCSSGK == KEY_CTL_WEP) { + sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; + } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { + sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; + } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { + sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; + } else { + sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; + } + // Pairwise Key Cipher Suite + sFrame.pRSNWPA->wPKCount = 1; + sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; + sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; + sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; + if (pMgmt->byCSSPK == KEY_CTL_TKIP) { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; + } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; + } else { + sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; + } + // Auth Key Management Suite + pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); + *pbyRSN++ = 0x01; + *pbyRSN++ = 0x00; + *pbyRSN++ = 0x00; + + *pbyRSN++ = 0x50; + *pbyRSN++ = 0xf2; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) { + *pbyRSN++ = WPA_AUTH_PSK; + } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) { + *pbyRSN++ = WPA_AUTH_IEEE802_1X; + } else { + *pbyRSN++ = WPA_NONE; + } + + sFrame.pRSNWPA->len += 6; + + // RSN Capabilities + *pbyRSN++ = 0x00; + *pbyRSN++ = 0x00; + sFrame.pRSNWPA->len += 2; + + sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION + pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); + pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; + + } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && + (pMgmt->pCurrBSS != NULL)) { + unsigned int ii; + unsigned short *pwPMKID; + + /* WPA IE */ + sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); + sFrame.pRSN->byElementID = WLAN_EID_RSN; + sFrame.pRSN->len = 6; //Version(2)+GK(4) + sFrame.pRSN->wVersion = 1; + //Group Key Cipher Suite + sFrame.pRSN->abyRSN[0] = 0x00; + sFrame.pRSN->abyRSN[1] = 0x0F; + sFrame.pRSN->abyRSN[2] = 0xAC; + if (pMgmt->byCSSGK == KEY_CTL_WEP) { + sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; + } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; + } else { + sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; + } + + // Pairwise Key Cipher Suite + sFrame.pRSN->abyRSN[4] = 1; + sFrame.pRSN->abyRSN[5] = 0; + sFrame.pRSN->abyRSN[6] = 0x00; + sFrame.pRSN->abyRSN[7] = 0x0F; + sFrame.pRSN->abyRSN[8] = 0xAC; + if (pMgmt->byCSSPK == KEY_CTL_TKIP) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; + } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; + } else { + sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; + } + sFrame.pRSN->len += 6; + + // Auth Key Management Suite + sFrame.pRSN->abyRSN[10] = 1; + sFrame.pRSN->abyRSN[11] = 0; + sFrame.pRSN->abyRSN[12] = 0x00; + sFrame.pRSN->abyRSN[13] = 0x0F; + sFrame.pRSN->abyRSN[14] = 0xAC; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; + } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; + } else { + sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; + } + sFrame.pRSN->len += 6; + + // RSN Capabilities + if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { + memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); + } else { + sFrame.pRSN->abyRSN[16] = 0; + sFrame.pRSN->abyRSN[17] = 0; + } + sFrame.pRSN->len += 2; + + if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { + // RSN PMKID + pbyRSN = &sFrame.pRSN->abyRSN[18]; + pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count + *pwPMKID = 0; // Initialize PMKID count + pbyRSN += 2; // Point to PMKID list + for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { + if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); + pbyRSN += 16; + } + } + if (*pwPMKID != 0) { + sFrame.pRSN->len += (2 + (*pwPMKID) * 16); + } + } + + sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; + // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION + pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; + memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); + pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; + } + + + /* Adjust the length fields */ + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -4140,68 +4140,68 @@ s_MgrMakeReAssocRequest( * Return Value: * PTR to frame; or NULL on allocation failure * --*/ + -*/ PSTxMgmtPacket s_MgrMakeAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wAssocStatus, + unsigned short wAssocAID, + unsigned char *pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCRESP sFrame; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeAssocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN - ); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN - ); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_ASSOCRESP sFrame; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + // Setup the sFrame structure + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; + vMgrEncodeAssocResponse(&sFrame); + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); + *sFrame.pwStatus = cpu_to_le16(wAssocStatus); + *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); + + // Copy the rate set + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, + pCurrSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN +); + + if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, + pCurrExtSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN +); + } + + // Adjust the length fields + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -4214,68 +4214,68 @@ s_MgrMakeAssocResponse( * Return Value: * PTR to frame; or NULL on allocation failure * --*/ + -*/ PSTxMgmtPacket s_MgrMakeReAssocResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + unsigned short wCurrCapInfo, + unsigned short wAssocStatus, + unsigned short wAssocAID, + unsigned char *pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates +) { - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCRESP sFrame; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeReassocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN - ); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN - ); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + PSTxMgmtPacket pTxPacket = NULL; + WLAN_FR_REASSOCRESP sFrame; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); + // Setup the sFrame structure + sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; + sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; + vMgrEncodeReassocResponse(&sFrame); + // Setup the header + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP) +)); + memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); + *sFrame.pwStatus = cpu_to_le16(wAssocStatus); + *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); + + // Copy the rate set + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, + pCurrSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN +); + + if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, + pCurrExtSuppRates, + ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN +); + } + + // Adjust the length fields + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } @@ -4288,118 +4288,118 @@ s_MgrMakeReAssocResponse( * Return Value: * none. * --*/ + -*/ static void s_vMgrRxProbeResponse( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - PKnownBSS pBSSList = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned char byIEChannel = 0; - bool bChannelHit = true; - - - memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeResponse(&sFrame); - - if ((sFrame.pqwTimestamp == 0) || - (sFrame.pwBeaconInterval == 0) || - (sFrame.pwCapInfo == 0) || - (sFrame.pSSID == 0) || - (sFrame.pSuppRates == 0)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header); - DBG_PORT80(0xCC); - return; - } - - if(sFrame.pSSID->len == 0) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n"); - - if (sFrame.pDSParms != 0) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } + PKnownBSS pBSSList = NULL; + WLAN_FR_PROBERESP sFrame; + unsigned char byCurrChannel = pRxPacket->byRxChannel; + ERPObject sERP; + unsigned char byIEChannel = 0; + bool bChannelHit = true; + + + memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP)); + // decode the frame + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeProbeResponse(&sFrame); + + if ((sFrame.pqwTimestamp == 0) || + (sFrame.pwBeaconInterval == 0) || + (sFrame.pwCapInfo == 0) || + (sFrame.pSSID == 0) || + (sFrame.pSuppRates == 0)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header); + DBG_PORT80(0xCC); + return; + } + + if (sFrame.pSSID->len == 0) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n"); + + if (sFrame.pDSParms != 0) { + if (byCurrChannel > CB_MAX_CHANNEL_24G) { + // channel remapping to + byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); + } else { + byIEChannel = sFrame.pDSParms->byCurrChannel; + } + if (byCurrChannel != byIEChannel) { + // adjust channel info. bcs we rcv adjacent channel packets + bChannelHit = false; + byCurrChannel = byIEChannel; + } + } else { + // no DS channel info + bChannelHit = true; + } //2008-0730-01by MikeLiu -if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - - // update or insert the bss - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList) { - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket - ); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket - ); - } - return; + if (ChannelExceedZoneType(pDevice, byCurrChannel) == true) + return; + + if (sFrame.pERP != NULL) { + sERP.byERP = sFrame.pERP->byContext; + sERP.bERPExist = true; + } else { + sERP.bERPExist = false; + sERP.byERP = 0; + } + + + // update or insert the bss + pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + if (pBSSList) { + BSSbUpdateToBSSList((void *)pDevice, + *sFrame.pqwTimestamp, + *sFrame.pwBeaconInterval, + *sFrame.pwCapInfo, + byCurrChannel, + bChannelHit, + sFrame.pSSID, + sFrame.pSuppRates, + sFrame.pExtSuppRates, + &sERP, + sFrame.pRSN, + sFrame.pRSNWPA, + sFrame.pIE_Country, + sFrame.pIE_Quiet, + pBSSList, + sFrame.len - WLAN_HDR_ADDR3_LEN, + sFrame.pHdr->sA4.abyAddr4, // payload of probresponse + (void *)pRxPacket +); + } + else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp/insert: RxChannel = : %d\n", byCurrChannel); + BSSbInsertToBSSList((void *)pDevice, + sFrame.pHdr->sA3.abyAddr3, + *sFrame.pqwTimestamp, + *sFrame.pwBeaconInterval, + *sFrame.pwCapInfo, + byCurrChannel, + sFrame.pSSID, + sFrame.pSuppRates, + sFrame.pExtSuppRates, + &sERP, + sFrame.pRSN, + sFrame.pRSNWPA, + sFrame.pIE_Country, + sFrame.pIE_Quiet, + sFrame.len - WLAN_HDR_ADDR3_LEN, + sFrame.pHdr->sA4.abyAddr4, // payload of beacon + (void *)pRxPacket +); + } + return; } @@ -4412,79 +4412,79 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==true) * Return Value: * none. * --*/ + -*/ static void s_vMgrRxProbeRequest( - PSDevice pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - WLAN_FR_PROBEREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned char byPHYType = BB_TYPE_11B; - - // STA in Ad-hoc mode: when latest TBTT beacon transmit success, - // STA have to response this request. - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) { - - memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeRequest(&sFrame); + WLAN_FR_PROBEREQ sFrame; + CMD_STATUS Status; + PSTxMgmtPacket pTxPacket; + unsigned char byPHYType = BB_TYPE_11B; + + // STA in Ad-hoc mode: when latest TBTT beacon transmit success, + // STA have to response this request. + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || + ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) { + + memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ)); + // decode the frame + sFrame.len = pRxPacket->cbMPDULen; + sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; + vMgrDecodeProbeRequest(&sFrame); /* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n", - sFrame.pHdr->sA3.abyAddr2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n", + sFrame.pHdr->sA3.abyAddr2); */ - if (sFrame.pSSID->len != 0) { - if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) - return; - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) { - return; - } - } - - if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) { - byPHYType = BB_TYPE_11G; - } - - // Probe response reply.. - pTxPacket = s_MgrMakeProbeResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - 0, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - byPHYType - ); - if (pTxPacket != NULL ){ - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n"); - } - else { + if (sFrame.pSSID->len != 0) { + if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) + return; + if (memcmp(sFrame.pSSID->abySSID, + ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, + ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) { + return; + } + } + + if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) { + byPHYType = BB_TYPE_11G; + } + + // Probe response reply.. + pTxPacket = s_MgrMakeProbeResponse + ( + pDevice, + pMgmt, + pMgmt->wCurrCapInfo, + pMgmt->wCurrBeaconPeriod, + pMgmt->uCurrChannel, + 0, + sFrame.pHdr->sA3.abyAddr2, + (PWLAN_IE_SSID)pMgmt->abyCurrSSID, + (unsigned char *)pMgmt->abyCurrBSSID, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, + byPHYType +); + if (pTxPacket != NULL) { + /* send the frame */ + Status = csMgmt_xmit(pDevice, pTxPacket); + if (Status != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n"); + } + else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n"); - } - } - } + } + } + } - return; + return; } @@ -4503,142 +4503,142 @@ s_vMgrRxProbeRequest( * Return Value: * none. * --*/ + -*/ void vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) + void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - bool bInScan = false; - unsigned int uNodeIndex = 0; - NODE_STATE eNodeState = 0; - CMD_STATUS Status; - - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState; - } - - switch( WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) ){ - - case WLAN_FSTYPE_ASSOCREQ: - // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n"); - } - else { - s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - } - break; - - case WLAN_FSTYPE_ASSOCRESP: - // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n"); - break; - - case WLAN_FSTYPE_REASSOCREQ: - // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n"); - // Todo: reassoc - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n"); - - } - s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - break; - - case WLAN_FSTYPE_REASSOCRESP: - // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true); - break; - - case WLAN_FSTYPE_PROBEREQ: - // Frame Clase = 0 - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n"); - s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_PROBERESP: - // Frame Clase = 0 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n"); - - s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_BEACON: - // Frame Clase = 0 - //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n"); - if (pMgmt->eScanState != WMAC_NO_SCANNING) { - bInScan = true; - } - s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan); - break; - - case WLAN_FSTYPE_ATIM: - // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n"); - break; - - case WLAN_FSTYPE_DISASSOC: - // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n"); - } - s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_AUTHEN: - // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n"); - s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_DEAUTHEN: - // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n"); - s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket); - break; - - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n"); - } - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + bool bInScan = false; + unsigned int uNodeIndex = 0; + NODE_STATE eNodeState = 0; + CMD_STATUS Status; + + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) + eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState; + } + + switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) { + + case WLAN_FSTYPE_ASSOCREQ: + // Frame Clase = 2 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n"); + if (eNodeState < NODE_AUTH) { + // send deauth notification + // reason = (6) class 2 received from nonauth sta + vMgrDeAuthenBeginSta(pDevice, + pMgmt, + pRxPacket->p80211Header->sA3.abyAddr2, + (6), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n"); + } + else { + s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); + } + break; + + case WLAN_FSTYPE_ASSOCRESP: + // Frame Clase = 2 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n"); + s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n"); + break; + + case WLAN_FSTYPE_REASSOCREQ: + // Frame Clase = 2 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n"); + // Todo: reassoc + if (eNodeState < NODE_AUTH) { + // send deauth notification + // reason = (6) class 2 received from nonauth sta + vMgrDeAuthenBeginSta(pDevice, + pMgmt, + pRxPacket->p80211Header->sA3.abyAddr2, + (6), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n"); + + } + s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); + break; + + case WLAN_FSTYPE_REASSOCRESP: + // Frame Clase = 2 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n"); + s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true); + break; + + case WLAN_FSTYPE_PROBEREQ: + // Frame Clase = 0 + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n"); + s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket); + break; + + case WLAN_FSTYPE_PROBERESP: + // Frame Clase = 0 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n"); + + s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket); + break; + + case WLAN_FSTYPE_BEACON: + // Frame Clase = 0 + //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n"); + if (pMgmt->eScanState != WMAC_NO_SCANNING) { + bInScan = true; + } + s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan); + break; + + case WLAN_FSTYPE_ATIM: + // Frame Clase = 1 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n"); + break; + + case WLAN_FSTYPE_DISASSOC: + // Frame Clase = 2 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n"); + if (eNodeState < NODE_AUTH) { + // send deauth notification + // reason = (6) class 2 received from nonauth sta + vMgrDeAuthenBeginSta(pDevice, + pMgmt, + pRxPacket->p80211Header->sA3.abyAddr2, + (6), + &Status +); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n"); + } + s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket); + break; + + case WLAN_FSTYPE_AUTHEN: + // Frame Clase = 1 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n"); + s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket); + break; + + case WLAN_FSTYPE_DEAUTHEN: + // Frame Clase = 1 + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n"); + s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket); + break; + + default: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n"); + } + + return; } @@ -4654,44 +4654,44 @@ vMgrRxManagePacket( * Return Value: * true if success; false if failed. * --*/ + -*/ bool bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt - ) + void *hDeviceContext, + PSMgmtObject pMgmt +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket; // pDevice->bBeaconBufReady = false; - if (pDevice->bEncryptionEnable || pDevice->bEnable8021x){ - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - } - else { - pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1); - } - pTxPacket = s_MgrMakeBeacon - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - pMgmt->wCurrATIMWindow, //0, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->abyCurrBSSID[0] == 0)) - return false; - - csBeacon_xmit(pDevice, pTxPacket); - - return true; + if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) { + pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); + } + else { + pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1); + } + pTxPacket = s_MgrMakeBeacon + ( + pDevice, + pMgmt, + pMgmt->wCurrCapInfo, + pMgmt->wCurrBeaconPeriod, + pMgmt->uCurrChannel, + pMgmt->wCurrATIMWindow, //0, + (PWLAN_IE_SSID)pMgmt->abyCurrSSID, + (unsigned char *)pMgmt->abyCurrBSSID, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates +); + + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (pMgmt->abyCurrBSSID[0] == 0)) + return false; + + csBeacon_xmit(pDevice, pTxPacket); + + return true; } @@ -4708,58 +4708,58 @@ bMgrPrepareBeaconToSend( * Return Value: * none. * --*/ + -*/ static void s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus - ) + PSMgmtObject pMgmt, + unsigned short wStatus +) { - switch( wStatus ){ - case WLAN_MGMT_STATUS_UNSPEC_FAILURE: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n"); - break; - case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n"); - break; - case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n"); - break; - case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n"); - break; - case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n"); - break; - case WLAN_MGMT_STATUS_CHALLENGE_FAIL: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n"); - break; - case WLAN_MGMT_STATUS_AUTH_TIMEOUT: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n"); - break; - default: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus); - break; - } + switch (wStatus) { + case WLAN_MGMT_STATUS_UNSPEC_FAILURE: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n"); + break; + case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n"); + break; + case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n"); + break; + case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n"); + break; + case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n"); + break; + case WLAN_MGMT_STATUS_CHALLENGE_FAIL: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n"); + break; + case WLAN_MGMT_STATUS_AUTH_TIMEOUT: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n"); + break; + case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n"); + break; + default: + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus); + break; + } } @@ -4778,52 +4778,52 @@ s_vMgrLogStatus( * * Return Value: none. * --*/ + -*/ bool -bAdd_PMKID_Candidate ( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj - ) +bAdd_PMKID_Candidate( + void *hDeviceContext, + unsigned char *pbyBSSID, + PSRSNCapObject psRSNCapObj +) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PPMKID_CANDIDATE pCandidateList; - unsigned int ii = 0; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL)) - return false; - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) - return false; - - - - // Update Old Candidate - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - } else { - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - } - return true; - } - } - - // New Candidate - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - } else { - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - } - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); - pDevice->gsPMKIDCandidate.NumCandidates++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; + PSDevice pDevice = (PSDevice)hDeviceContext; + PPMKID_CANDIDATE pCandidateList; + unsigned int ii = 0; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + + if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL)) + return false; + + if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) + return false; + + + + // Update Old Candidate + for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { + pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; + if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { + if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { + pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; + } else { + pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); + } + return true; + } + } + + // New Candidate + pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; + if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { + pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; + } else { + pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); + } + memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); + pDevice->gsPMKIDCandidate.NumCandidates++; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + return true; } /* @@ -4839,166 +4839,166 @@ bAdd_PMKID_Candidate ( * * Return Value: none. * --*/ + -*/ void -vFlush_PMKID_Candidate ( - void *hDeviceContext - ) +vFlush_PMKID_Candidate( + void *hDeviceContext +) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; - if (pDevice == NULL) - return; + if (pDevice == NULL) + return; - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); + memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); } static bool -s_bCipherMatch ( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK - ) +s_bCipherMatch( + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, + unsigned char *pbyCCSPK, + unsigned char *pbyCCSGK +) { - unsigned char byMulticastCipher = KEY_CTL_INVALID; - unsigned char byCipherMask = 0x00; - int i; - - if (pBSSNode == NULL) - return false; - - // check cap. of BSS - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (EncStatus == Ndis802_11Encryption1Enabled)) { - // default is WEP only - byMulticastCipher = KEY_CTL_WEP; - } - - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (pBSSNode->bWPA2Valid == true) && - //20080123-01, by Einsn Liu - ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA2 - // check Group Key Cipher - if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) || - (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for(i=0;iwCSSPKCount;i++) { - if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) || - (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) { - // this should not happen as defined 802.11i - byCipherMask |= 0x01; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wCSSPKCount; - } - } - - } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (pBSSNode->bWPAValid == true) && - ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA - // check Group Key Cipher - if ((pBSSNode->byGKType == WPA_WEP40) || - (pBSSNode->byGKType == WPA_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byGKType == WPA_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byGKType == WPA_AESCCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for(i=0;iwPKCount;i++) { - if (pBSSNode->abyPKType[i] == WPA_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyPKType[i] == WPA_NONE) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wPKCount; - } - } - } - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n", - byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus); - - // mask our cap. with BSS - if (EncStatus == Ndis802_11Encryption1Enabled) { - - // For supporting Cisco migration mode, don't care pairwise key cipher - if ((byMulticastCipher == KEY_CTL_WEP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else { - return false; - } - - } else if (EncStatus == Ndis802_11Encryption2Enabled) { - if ((byMulticastCipher == KEY_CTL_TKIP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else { - return false; - } - } else if (EncStatus == Ndis802_11Encryption3Enabled) { - if ((byMulticastCipher == KEY_CTL_CCMP) && - (byCipherMask == 0)) { - // When CCMP is enable, "Use group cipher suite" shall not be a valid option. - return false; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_CCMP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_CCMP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else { - return false; - } - } - return true; + unsigned char byMulticastCipher = KEY_CTL_INVALID; + unsigned char byCipherMask = 0x00; + int i; + + if (pBSSNode == NULL) + return false; + + // check cap. of BSS + if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && + (EncStatus == Ndis802_11Encryption1Enabled)) { + // default is WEP only + byMulticastCipher = KEY_CTL_WEP; + } + + if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && + (pBSSNode->bWPA2Valid == true) && + //20080123-01, by Einsn Liu + ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { + //WPA2 + // check Group Key Cipher + if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) || + (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) { + byMulticastCipher = KEY_CTL_WEP; + } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) { + byMulticastCipher = KEY_CTL_TKIP; + } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { + byMulticastCipher = KEY_CTL_CCMP; + } else { + byMulticastCipher = KEY_CTL_INVALID; + } + + // check Pairwise Key Cipher + for (i = 0; i < pBSSNode->wCSSPKCount; i++) { + if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) || + (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) { + // this should not happen as defined 802.11i + byCipherMask |= 0x01; + } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) { + byCipherMask |= 0x02; + } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) { + byCipherMask |= 0x04; + } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) { + // use group key only ignore all others + byCipherMask = 0; + i = pBSSNode->wCSSPKCount; + } + } + + } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && + (pBSSNode->bWPAValid == true) && + ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { + //WPA + // check Group Key Cipher + if ((pBSSNode->byGKType == WPA_WEP40) || + (pBSSNode->byGKType == WPA_WEP104)) { + byMulticastCipher = KEY_CTL_WEP; + } else if (pBSSNode->byGKType == WPA_TKIP) { + byMulticastCipher = KEY_CTL_TKIP; + } else if (pBSSNode->byGKType == WPA_AESCCMP) { + byMulticastCipher = KEY_CTL_CCMP; + } else { + byMulticastCipher = KEY_CTL_INVALID; + } + + // check Pairwise Key Cipher + for (i = 0; i < pBSSNode->wPKCount; i++) { + if (pBSSNode->abyPKType[i] == WPA_TKIP) { + byCipherMask |= 0x02; + } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) { + byCipherMask |= 0x04; + } else if (pBSSNode->abyPKType[i] == WPA_NONE) { + // use group key only ignore all others + byCipherMask = 0; + i = pBSSNode->wPKCount; + } + } + } + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%d, %d, %d, %d, EncStatus:%d\n", + byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus); + + // mask our cap. with BSS + if (EncStatus == Ndis802_11Encryption1Enabled) { + + // For supporting Cisco migration mode, don't care pairwise key cipher + if ((byMulticastCipher == KEY_CTL_WEP) && + (byCipherMask == 0)) { + *pbyCCSGK = KEY_CTL_WEP; + *pbyCCSPK = KEY_CTL_NONE; + return true; + } else { + return false; + } + + } else if (EncStatus == Ndis802_11Encryption2Enabled) { + if ((byMulticastCipher == KEY_CTL_TKIP) && + (byCipherMask == 0)) { + *pbyCCSGK = KEY_CTL_TKIP; + *pbyCCSPK = KEY_CTL_NONE; + return true; + } else if ((byMulticastCipher == KEY_CTL_WEP) && + ((byCipherMask & 0x02) != 0)) { + *pbyCCSGK = KEY_CTL_WEP; + *pbyCCSPK = KEY_CTL_TKIP; + return true; + } else if ((byMulticastCipher == KEY_CTL_TKIP) && + ((byCipherMask & 0x02) != 0)) { + *pbyCCSGK = KEY_CTL_TKIP; + *pbyCCSPK = KEY_CTL_TKIP; + return true; + } else { + return false; + } + } else if (EncStatus == Ndis802_11Encryption3Enabled) { + if ((byMulticastCipher == KEY_CTL_CCMP) && + (byCipherMask == 0)) { + // When CCMP is enable, "Use group cipher suite" shall not be a valid option. + return false; + } else if ((byMulticastCipher == KEY_CTL_WEP) && + ((byCipherMask & 0x04) != 0)) { + *pbyCCSGK = KEY_CTL_WEP; + *pbyCCSPK = KEY_CTL_CCMP; + return true; + } else if ((byMulticastCipher == KEY_CTL_TKIP) && + ((byCipherMask & 0x04) != 0)) { + *pbyCCSGK = KEY_CTL_TKIP; + *pbyCCSPK = KEY_CTL_CCMP; + return true; + } else if ((byMulticastCipher == KEY_CTL_CCMP) && + ((byCipherMask & 0x04) != 0)) { + *pbyCCSGK = KEY_CTL_CCMP; + *pbyCCSPK = KEY_CTL_CCMP; + return true; + } else { + return false; + } + } + return true; } diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index bfa67ae5d40a..d50f80d7669c 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -82,7 +82,7 @@ /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Types ------------------------------*/ -#define timer_expire(timer,next_tick) mod_timer(&timer, RUN_AT(next_tick)) +#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick)) typedef void (*TimerFunction)(unsigned long); @@ -91,87 +91,87 @@ typedef void (*TimerFunction)(unsigned long); typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; typedef struct _NDIS_802_11_AI_REQFI { - unsigned short Capabilities; - unsigned short ListenInterval; - NDIS_802_11_MAC_ADDRESS CurrentAPAddress; + unsigned short Capabilities; + unsigned short ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; } NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; typedef struct _NDIS_802_11_AI_RESFI { - unsigned short Capabilities; - unsigned short StatusCode; - unsigned short AssociationId; + unsigned short Capabilities; + unsigned short StatusCode; + unsigned short AssociationId; } NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION { - unsigned long Length; - unsigned short AvailableRequestFixedIEs; - NDIS_802_11_AI_REQFI RequestFixedIEs; - unsigned long RequestIELength; - unsigned long OffsetRequestIEs; - unsigned short AvailableResponseFixedIEs; - NDIS_802_11_AI_RESFI ResponseFixedIEs; - unsigned long ResponseIELength; - unsigned long OffsetResponseIEs; + unsigned long Length; + unsigned short AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + unsigned long RequestIELength; + unsigned long OffsetRequestIEs; + unsigned short AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + unsigned long ResponseIELength; + unsigned long OffsetResponseIEs; } NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; typedef struct tagSAssocInfo { - NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; - unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; - // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION - unsigned long RequestIELength; - unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN]; + NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; + unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; + // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION + unsigned long RequestIELength; + unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN]; } SAssocInfo, *PSAssocInfo; //--- /* -typedef enum tagWMAC_AUTHENTICATION_MODE { + typedef enum tagWMAC_AUTHENTICATION_MODE { - WMAC_AUTH_OPEN, - WMAC_AUTH_SHAREKEY, - WMAC_AUTH_AUTO, - WMAC_AUTH_WPA, - WMAC_AUTH_WPAPSK, - WMAC_AUTH_WPANONE, - WMAC_AUTH_WPA2, - WMAC_AUTH_WPA2PSK, - WMAC_AUTH_MAX // Not a real mode, defined as upper bound + WMAC_AUTH_OPEN, + WMAC_AUTH_SHAREKEY, + WMAC_AUTH_AUTO, + WMAC_AUTH_WPA, + WMAC_AUTH_WPAPSK, + WMAC_AUTH_WPANONE, + WMAC_AUTH_WPA2, + WMAC_AUTH_WPA2PSK, + WMAC_AUTH_MAX // Not a real mode, defined as upper bound -} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE; + } WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE; */ // Pre-configured Mode (from XP) /* -typedef enum tagWMAC_CONFIG_MODE { - WMAC_CONFIG_ESS_STA, - WMAC_CONFIG_IBSS_STA, - WMAC_CONFIG_AUTO, - WMAC_CONFIG_AP + typedef enum tagWMAC_CONFIG_MODE { + WMAC_CONFIG_ESS_STA, + WMAC_CONFIG_IBSS_STA, + WMAC_CONFIG_AUTO, + WMAC_CONFIG_AP -} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE; + } WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE; */ typedef enum tagWMAC_SCAN_TYPE { - WMAC_SCAN_ACTIVE, - WMAC_SCAN_PASSIVE, - WMAC_SCAN_HYBRID + WMAC_SCAN_ACTIVE, + WMAC_SCAN_PASSIVE, + WMAC_SCAN_HYBRID } WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE; typedef enum tagWMAC_SCAN_STATE { - WMAC_NO_SCANNING, - WMAC_IS_SCANNING, - WMAC_IS_PROBEPENDING + WMAC_NO_SCANNING, + WMAC_IS_SCANNING, + WMAC_IS_PROBEPENDING } WMAC_SCAN_STATE, *PWMAC_SCAN_STATE; @@ -189,43 +189,43 @@ typedef enum tagWMAC_SCAN_STATE { typedef enum tagWMAC_BSS_STATE { - WMAC_STATE_IDLE, - WMAC_STATE_STARTED, - WMAC_STATE_JOINTED, - WMAC_STATE_AUTHPENDING, - WMAC_STATE_AUTH, - WMAC_STATE_ASSOCPENDING, - WMAC_STATE_ASSOC + WMAC_STATE_IDLE, + WMAC_STATE_STARTED, + WMAC_STATE_JOINTED, + WMAC_STATE_AUTHPENDING, + WMAC_STATE_AUTH, + WMAC_STATE_ASSOCPENDING, + WMAC_STATE_ASSOC } WMAC_BSS_STATE, *PWMAC_BSS_STATE; // WMAC selected running mode typedef enum tagWMAC_CURRENT_MODE { - WMAC_MODE_STANDBY, - WMAC_MODE_ESS_STA, - WMAC_MODE_IBSS_STA, - WMAC_MODE_ESS_AP + WMAC_MODE_STANDBY, + WMAC_MODE_ESS_STA, + WMAC_MODE_IBSS_STA, + WMAC_MODE_ESS_AP } WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE; /* -typedef enum tagWMAC_POWER_MODE { + typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX + WMAC_POWER_CAM, + WMAC_POWER_FAST, + WMAC_POWER_MAX -} WMAC_POWER_MODE, *PWMAC_POWER_MODE; + } WMAC_POWER_MODE, *PWMAC_POWER_MODE; */ // Tx Management Packet descriptor typedef struct tagSTxMgmtPacket { - PUWLAN_80211HDR p80211Header; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; + PUWLAN_80211HDR p80211Header; + unsigned int cbMPDULen; + unsigned int cbPayloadLen; } STxMgmtPacket, *PSTxMgmtPacket; @@ -233,14 +233,14 @@ typedef struct tagSTxMgmtPacket { // Rx Management Packet descriptor typedef struct tagSRxMgmtPacket { - PUWLAN_80211HDR p80211Header; - QWORD qwLocalTSF; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; - unsigned int uRSSI; - unsigned char bySQ; - unsigned char byRxRate; - unsigned char byRxChannel; + PUWLAN_80211HDR p80211Header; + QWORD qwLocalTSF; + unsigned int cbMPDULen; + unsigned int cbPayloadLen; + unsigned int uRSSI; + unsigned char bySQ; + unsigned char byRxRate; + unsigned char byRxChannel; } SRxMgmtPacket, *PSRxMgmtPacket; @@ -249,146 +249,146 @@ typedef struct tagSRxMgmtPacket { typedef struct tagSMgmtObject { - void * pAdapter; - // MAC address - unsigned char abyMACAddr[WLAN_ADDR_LEN]; + void *pAdapter; + // MAC address + unsigned char abyMACAddr[WLAN_ADDR_LEN]; - // Configuration Mode - WMAC_CONFIG_MODE eConfigMode; // MAC pre-configed mode - CARD_PHY_TYPE eCurrentPHYMode; - CARD_PHY_TYPE eConfigPHYMode; + // Configuration Mode + WMAC_CONFIG_MODE eConfigMode; // MAC pre-configed mode + CARD_PHY_TYPE eCurrentPHYMode; + CARD_PHY_TYPE eConfigPHYMode; - // Operation state variables - WMAC_CURRENT_MODE eCurrMode; // MAC current connection mode - WMAC_BSS_STATE eCurrState; // MAC current BSS state + // Operation state variables + WMAC_CURRENT_MODE eCurrMode; // MAC current connection mode + WMAC_BSS_STATE eCurrState; // MAC current BSS state - PKnownBSS pCurrBSS; - unsigned char byCSSGK; - unsigned char byCSSPK; + PKnownBSS pCurrBSS; + unsigned char byCSSGK; + unsigned char byCSSPK; // unsigned char abyNewSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; // unsigned char abyNewExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - // Current state vars - unsigned int uCurrChannel; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; - unsigned short wCurrCapInfo; - unsigned short wCurrAID; - unsigned short wCurrATIMWindow; - unsigned short wCurrBeaconPeriod; - bool bIsDS; - unsigned char byERPContext; - - CMD_STATE eCommandState; - unsigned int uScanChannel; - - // Desire joining BSS vars - unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyDesireBSSID[WLAN_BSSID_LEN]; - - // Adhoc or AP configuration vars - //unsigned char abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned short wIBSSBeaconPeriod; - unsigned short wIBSSATIMWindow; - unsigned int uIBSSChannel; - unsigned char abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char byAPBBType; - unsigned char abyWPAIE[MAX_WPA_IE_LEN]; - unsigned short wWPAIELen; - - unsigned int uAssocCount; - bool bMoreData; - - // Scan state vars - WMAC_SCAN_STATE eScanState; - WMAC_SCAN_TYPE eScanType; - unsigned int uScanStartCh; - unsigned int uScanEndCh; - unsigned short wScanSteps; - unsigned int uScanBSSType; - // Desire scanning vars - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyScanBSSID[WLAN_BSSID_LEN]; - - // Privacy - WMAC_AUTHENTICATION_MODE eAuthenMode; - WMAC_ENCRYPTION_MODE eEncryptionMode; - bool bShareKeyAlgorithm; - unsigned char abyChallenge[WLAN_CHALLENGE_LEN]; - bool bPrivacyInvoked; - - // Received beacon state vars - bool bInTIM; - bool bMulticastTIM; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - - // Power saving state vars - WMAC_POWER_MODE ePSMode; - unsigned short wListenInterval; - unsigned short wCountToWakeUp; - bool bInTIMWake; - unsigned char *pbyPSPacketPool; - unsigned char byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN]; - bool bRxBeaconInTBTTWake; - unsigned char abyPSTxMap[MAX_NODE_NUM + 1]; - - // management command related - unsigned int uCmdBusy; - unsigned int uCmdHostAPBusy; - - // management packet pool - unsigned char *pbyMgmtPacketPool; - unsigned char byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - - - // One second callback timer - struct timer_list sTimerSecondCallback; - - // Temporarily Rx Mgmt Packet Descriptor - SRxMgmtPacket sRxPacket; - - // link list of known bss's (scan results) - KnownBSS sBSSList[MAX_BSS_NUM]; - - - - // table list of known node - // sNodeDBList[0] is reserved for AP under Infra mode - // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode - KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1]; - - - - // WPA2 PMKID Cache - SPMKIDCache gsPMKIDCache; - bool bRoaming; - - // rate fall back vars - - - - // associate info - SAssocInfo sAssocInfo; - + // Current state vars + unsigned int uCurrChannel; + unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; + unsigned short wCurrCapInfo; + unsigned short wCurrAID; + unsigned short wCurrATIMWindow; + unsigned short wCurrBeaconPeriod; + bool bIsDS; + unsigned char byERPContext; + + CMD_STATE eCommandState; + unsigned int uScanChannel; + + // Desire joining BSS vars + unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned char abyDesireBSSID[WLAN_BSSID_LEN]; + + // Adhoc or AP configuration vars + //unsigned char abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned short wIBSSBeaconPeriod; + unsigned short wIBSSATIMWindow; + unsigned int uIBSSChannel; + unsigned char abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; + unsigned char byAPBBType; + unsigned char abyWPAIE[MAX_WPA_IE_LEN]; + unsigned short wWPAIELen; + + unsigned int uAssocCount; + bool bMoreData; + + // Scan state vars + WMAC_SCAN_STATE eScanState; + WMAC_SCAN_TYPE eScanType; + unsigned int uScanStartCh; + unsigned int uScanEndCh; + unsigned short wScanSteps; + unsigned int uScanBSSType; + // Desire scanning vars + unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; + unsigned char abyScanBSSID[WLAN_BSSID_LEN]; + + // Privacy + WMAC_AUTHENTICATION_MODE eAuthenMode; + WMAC_ENCRYPTION_MODE eEncryptionMode; + bool bShareKeyAlgorithm; + unsigned char abyChallenge[WLAN_CHALLENGE_LEN]; + bool bPrivacyInvoked; + + // Received beacon state vars + bool bInTIM; + bool bMulticastTIM; + unsigned char byDTIMCount; + unsigned char byDTIMPeriod; + + // Power saving state vars + WMAC_POWER_MODE ePSMode; + unsigned short wListenInterval; + unsigned short wCountToWakeUp; + bool bInTIMWake; + unsigned char *pbyPSPacketPool; + unsigned char byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN]; + bool bRxBeaconInTBTTWake; + unsigned char abyPSTxMap[MAX_NODE_NUM + 1]; + + // management command related + unsigned int uCmdBusy; + unsigned int uCmdHostAPBusy; + + // management packet pool + unsigned char *pbyMgmtPacketPool; + unsigned char byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; + + + // One second callback timer + struct timer_list sTimerSecondCallback; + + // Temporarily Rx Mgmt Packet Descriptor + SRxMgmtPacket sRxPacket; + + // link list of known bss's (scan results) + KnownBSS sBSSList[MAX_BSS_NUM]; + + + + // table list of known node + // sNodeDBList[0] is reserved for AP under Infra mode + // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode + KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1]; + + + + // WPA2 PMKID Cache + SPMKIDCache gsPMKIDCache; + bool bRoaming; + + // rate fall back vars + + + + // associate info + SAssocInfo sAssocInfo; + - // for 802.11h - bool b11hEnable; - bool bSwitchChannel; - unsigned char byNewChannel; - PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; - unsigned int uLengthOfRepEIDs; - unsigned char abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyIECountry[WLAN_A3FR_MAXLEN]; - unsigned char abyIBSSDFSOwner[6]; - unsigned char byIBSSDFSRecovery; + // for 802.11h + bool b11hEnable; + bool bSwitchChannel; + unsigned char byNewChannel; + PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; + unsigned int uLengthOfRepEIDs; + unsigned char abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; + unsigned char abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; + unsigned char abyIECountry[WLAN_A3FR_MAXLEN]; + unsigned char abyIBSSDFSOwner[6]; + unsigned char byIBSSDFSRecovery; - struct sk_buff skb; + struct sk_buff skb; } SMgmtObject, *PSMgmtObject; @@ -401,102 +401,102 @@ typedef struct tagSMgmtObject void vMgrObjectInit( - void *hDeviceContext - ); + void *hDeviceContext +); void vMgrTimerInit( - void *hDeviceContext - ); + void *hDeviceContext +); void vMgrObjectReset( - void *hDeviceContext - ); + void *hDeviceContext +); void vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +); void vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +); void vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + unsigned char *abyDestAddress, + unsigned short wReason, + PCMD_STATUS pStatus +); void vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus +); void vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PCMD_STATUS pStatus +); void vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PCMD_STATUS pStatus +); void vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket +); /* -void -vMgrScanBegin( - void *hDeviceContext, - PCMD_STATUS pStatus - ); + void + vMgrScanBegin( + void *hDeviceContext, + PCMD_STATUS pStatus +); */ void vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus - ); + void *hDeviceContext, + PSMgmtObject pMgmt, + unsigned char *abyDestAddress, + unsigned short wReason, + PCMD_STATUS pStatus +); bool bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt - ); + void *hDeviceContext, + PSMgmtObject pMgmt +); bool -bAdd_PMKID_Candidate ( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj - ); +bAdd_PMKID_Candidate( + void *hDeviceContext, + unsigned char *pbyBSSID, + PSRSNCapObject psRSNCapObj +); void -vFlush_PMKID_Candidate ( - void *hDeviceContext - ); +vFlush_PMKID_Candidate( + void *hDeviceContext +); #endif // __WMGR_H__ -- cgit From f0c35239af054af27ab764b9553d82866777febb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:12 -0700 Subject: staging:vt6655:wpa: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wpa.c | 334 +++++++++++++++++++++---------------------- drivers/staging/vt6655/wpa.h | 22 +-- 2 files changed, 178 insertions(+), 178 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 4412fe9396a4..b501a3665c34 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -43,7 +43,7 @@ #include "80211mgr.h" /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; @@ -66,26 +66,26 @@ const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; * * Return Value: none. * --*/ + -*/ void -WPA_ClearRSN ( - PKnownBSS pBSSList - ) +WPA_ClearRSN( + PKnownBSS pBSSList +) { - int ii; - pBSSList->byGKType = WPA_TKIP; - for (ii=0; ii < 4; ii ++) - pBSSList->abyPKType[ii] = WPA_TKIP; - pBSSList->wPKCount = 0; - for (ii=0; ii < 4; ii ++) - pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X; - pBSSList->wAuthCount = 0; - pBSSList->byDefaultK_as_PK = 0; - pBSSList->byReplayIdx = 0; - pBSSList->sRSNCapObj.bRSNCapExist = false; - pBSSList->sRSNCapObj.wRSNCap = 0; - pBSSList->bWPAValid = false; + int ii; + pBSSList->byGKType = WPA_TKIP; + for (ii = 0; ii < 4; ii++) + pBSSList->abyPKType[ii] = WPA_TKIP; + pBSSList->wPKCount = 0; + for (ii = 0; ii < 4; ii++) + pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X; + pBSSList->wAuthCount = 0; + pBSSList->byDefaultK_as_PK = 0; + pBSSList->byReplayIdx = 0; + pBSSList->sRSNCapObj.bRSNCapExist = false; + pBSSList->sRSNCapObj.wRSNCap = 0; + pBSSList->bWPAValid = false; } @@ -103,122 +103,122 @@ WPA_ClearRSN ( * * Return Value: none. * --*/ + -*/ void -WPA_ParseRSN ( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN - ) +WPA_ParseRSN( + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN +) { - PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; - int i, j, m, n = 0; - unsigned char *pbyCaps; + PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; + int i, j, m, n = 0; + unsigned char *pbyCaps; - WPA_ClearRSN(pBSSList); + WPA_ClearRSN(pBSSList); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WPA_ParseRSN: [%d]\n", pRSN->len); - // information element header makes sense - if ((pRSN->len >= 6) // oui1(4)+ver(2) - && (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) - && (pRSN->wVersion == 1)) { + // information element header makes sense + if ((pRSN->len >= 6) // oui1(4)+ver(2) + && (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) + && (pRSN->wVersion == 1)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n"); - // update each variable if pRSN is long enough to contain the variable - if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4) - { - if ( !memcmp(pRSN->abyMulticast, abyOUI01, 4)) - pBSSList->byGKType = WPA_WEP40; - else if ( !memcmp(pRSN->abyMulticast, abyOUI02, 4)) - pBSSList->byGKType = WPA_TKIP; - else if ( !memcmp(pRSN->abyMulticast, abyOUI03, 4)) - pBSSList->byGKType = WPA_AESWRAP; - else if ( !memcmp(pRSN->abyMulticast, abyOUI04, 4)) - pBSSList->byGKType = WPA_AESCCMP; - else if ( !memcmp(pRSN->abyMulticast, abyOUI05, 4)) - pBSSList->byGKType = WPA_WEP104; - else - // any vendor checks here - pBSSList->byGKType = WPA_NONE; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Legal RSN\n"); + // update each variable if pRSN is long enough to contain the variable + if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4) + { + if (!memcmp(pRSN->abyMulticast, abyOUI01, 4)) + pBSSList->byGKType = WPA_WEP40; + else if (!memcmp(pRSN->abyMulticast, abyOUI02, 4)) + pBSSList->byGKType = WPA_TKIP; + else if (!memcmp(pRSN->abyMulticast, abyOUI03, 4)) + pBSSList->byGKType = WPA_AESWRAP; + else if (!memcmp(pRSN->abyMulticast, abyOUI04, 4)) + pBSSList->byGKType = WPA_AESCCMP; + else if (!memcmp(pRSN->abyMulticast, abyOUI05, 4)) + pBSSList->byGKType = WPA_WEP104; + else + // any vendor checks here + pBSSList->byGKType = WPA_NONE; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType); - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byGKType: %x\n", pBSSList->byGKType); + } - if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2) - { - j = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); - for(i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { - if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) - if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) - pBSSList->abyPKType[j++] = WPA_NONE; - else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyPKType[j++] = WPA_TKIP; - else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4)) - pBSSList->abyPKType[j++] = WPA_AESWRAP; - else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4)) - pBSSList->abyPKType[j++] = WPA_AESCCMP; - else - // any vendor checks here - ; - } - else - break; - //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1])); - } //for - pBSSList->wPKCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount); - } + if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2) + { + j = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); + for (i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { + if (pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) + if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) + pBSSList->abyPKType[j++] = WPA_NONE; + else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4)) + pBSSList->abyPKType[j++] = WPA_TKIP; + else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4)) + pBSSList->abyPKType[j++] = WPA_AESWRAP; + else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4)) + pBSSList->abyPKType[j++] = WPA_AESCCMP; + else + // any vendor checks here + ; + } + else + break; + //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1])); + } //for + pBSSList->wPKCount = (unsigned short)j; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wPKCount: %d\n", pBSSList->wPKCount); + } - m = pRSN->wPKCount; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4); + m = pRSN->wPKCount; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "m: %d\n", m); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "14+m*4: %d\n", 14+m*4); - if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2) - // overlay IE_RSN_Auth structure into correct place - pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI; - j = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", - pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); - for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { - if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) - if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; - else if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_PSK; - else - // any vendor checks here - ; - } - else - break; - //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1])); - } - if(j > 0) - pBSSList->wAuthCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount); - } + if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2) + // overlay IE_RSN_Auth structure into correct place + pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI; + j = 0; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", + pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); + for (i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { + if (pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) + if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) + pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; + else if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4)) + pBSSList->abyAuthType[j++] = WPA_AUTH_PSK; + else + // any vendor checks here + ; + } + else + break; + //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1])); + } + if (j > 0) + pBSSList->wAuthCount = (unsigned short)j; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAuthCount: %d\n", pBSSList->wAuthCount); + } - if (pIE_RSN_Auth != NULL) { + if (pIE_RSN_Auth != NULL) { - n = pIE_RSN_Auth->wAuthCount; + n = pIE_RSN_Auth->wAuthCount; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "n: %d\n", n); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); - if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2) - pbyCaps = (unsigned char *)pIE_RSN_Auth->AuthKSList[n].abyOUI; - pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; - pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); - pBSSList->sRSNCapObj.bRSNCapExist = true; - pBSSList->sRSNCapObj.wRSNCap = *(unsigned short *)pbyCaps; - //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps)); - //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK)); - //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx)); - } - } - pBSSList->bWPAValid = true; - } + if (pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2) + pbyCaps = (unsigned char *)pIE_RSN_Auth->AuthKSList[n].abyOUI; + pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; + pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); + pBSSList->sRSNCapObj.bRSNCapExist = true; + pBSSList->sRSNCapObj.wRSNCap = *(unsigned short *)pbyCaps; + //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps)); + //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK)); + //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx)); + } + } + pBSSList->bWPAValid = true; + } } /*+ @@ -236,51 +236,51 @@ WPA_ParseRSN ( * * Return Value: none. * --*/ + -*/ bool -WPA_SearchRSN ( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList - ) +WPA_SearchRSN( + unsigned char byCmd, + unsigned char byEncrypt, + PKnownBSS pBSSList +) { - int ii; - unsigned char byPKType = WPA_NONE; + int ii; + unsigned char byPKType = WPA_NONE; - if (pBSSList->bWPAValid == false) - return false; + if (pBSSList->bWPAValid == false) + return false; - switch(byCmd) { - case 0: + switch (byCmd) { + case 0: - if (byEncrypt != pBSSList->byGKType) - return false; + if (byEncrypt != pBSSList->byGKType) + return false; - if (pBSSList->wPKCount > 0) { - for (ii = 0; ii < pBSSList->wPKCount; ii ++) { - if (pBSSList->abyPKType[ii] == WPA_AESCCMP) - byPKType = WPA_AESCCMP; - else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP)) - byPKType = WPA_TKIP; - else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP40; - else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP104; - } - if (byEncrypt != byPKType) - return false; - } - return true; + if (pBSSList->wPKCount > 0) { + for (ii = 0; ii < pBSSList->wPKCount; ii++) { + if (pBSSList->abyPKType[ii] == WPA_AESCCMP) + byPKType = WPA_AESCCMP; + else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP)) + byPKType = WPA_TKIP; + else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) + byPKType = WPA_WEP40; + else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) + byPKType = WPA_WEP104; + } + if (byEncrypt != byPKType) + return false; + } + return true; // if (pBSSList->wAuthCount > 0) // for (ii=0; ii < pBSSList->wAuthCount; ii ++) // if (byAuth == pBSSList->abyAuthType[ii]) // break; - break; + break; - default: - break; - } - return false; + default: + break; + } + return false; } /*+ @@ -296,21 +296,21 @@ WPA_SearchRSN ( * * Return Value: none. * --*/ + -*/ bool -WPAb_Is_RSN ( - PWLAN_IE_RSN_EXT pRSN - ) +WPAb_Is_RSN( + PWLAN_IE_RSN_EXT pRSN +) { - if (pRSN == NULL) - return false; + if (pRSN == NULL) + return false; - if ((pRSN->len >= 6) && // oui1(4)+ver(2) - (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) && - (pRSN->wVersion == 1)) { - return true; - } - else - return false; + if ((pRSN->len >= 6) && // oui1(4)+ver(2) + (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) && + (pRSN->wVersion == 1)) { + return true; + } + else + return false; } diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h index 921fd7ae9d38..48a66704e214 100644 --- a/drivers/staging/vt6655/wpa.h +++ b/drivers/staging/vt6655/wpa.h @@ -60,25 +60,25 @@ void WPA_ClearRSN( - PKnownBSS pBSSList - ); + PKnownBSS pBSSList +); void WPA_ParseRSN( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN - ); + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN +); bool WPA_SearchRSN( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList - ); + unsigned char byCmd, + unsigned char byEncrypt, + PKnownBSS pBSSList +); bool WPAb_Is_RSN( - PWLAN_IE_RSN_EXT pRSN - ); + PWLAN_IE_RSN_EXT pRSN +); #endif // __WPA_H__ -- cgit From 3e28383f2dbda0947fb9f870bfddbb1ba302435a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:13 -0700 Subject: staging:vt6655:wpa2: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wpa2.c | 504 +++++++++++++++++++++--------------------- drivers/staging/vt6655/wpa2.h | 28 +-- 2 files changed, 266 insertions(+), 266 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 884db1abe123..0b33feabcd16 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -36,7 +36,7 @@ #include "wmgr.h" /*--------------------- Static Definitions -------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Classes ----------------------------*/ @@ -71,25 +71,25 @@ const unsigned char abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; * * Return Value: none. * --*/ + -*/ void -WPA2_ClearRSN ( - PKnownBSS pBSSNode - ) +WPA2_ClearRSN( + PKnownBSS pBSSNode +) { - int ii; - - pBSSNode->bWPA2Valid = false; - - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - for (ii=0; ii < 4; ii ++) - pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP; - pBSSNode->wCSSPKCount = 1; - for (ii=0; ii < 4; ii ++) - pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X; - pBSSNode->wAKMSSAuthCount = 1; - pBSSNode->sRSNCapObj.bRSNCapExist = false; - pBSSNode->sRSNCapObj.wRSNCap = 0; + int ii; + + pBSSNode->bWPA2Valid = false; + + pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; + for (ii = 0; ii < 4; ii++) + pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP; + pBSSNode->wCSSPKCount = 1; + for (ii = 0; ii < 4; ii++) + pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X; + pBSSNode->wAKMSSAuthCount = 1; + pBSSNode->sRSNCapObj.bRSNCapExist = false; + pBSSNode->sRSNCapObj.wRSNCap = 0; } /*+ @@ -106,144 +106,144 @@ WPA2_ClearRSN ( * * Return Value: none. * --*/ + -*/ void -WPA2vParseRSN ( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN - ) +WPA2vParseRSN( + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN +) { - int i, j; - unsigned short m = 0, n = 0; - unsigned char *pbyOUI; - bool bUseGK = false; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len); - - WPA2_ClearRSN(pBSSNode); - - if (pRSN->len == 2) { // ver(2) - if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) { - pBSSNode->bWPA2Valid = true; - } - return; - } - - if (pRSN->len < 6) { // ver(2) + GK(4) - // invalid CSS, P802.11i/D10.0, p31 - return; - } - - // information element header makes sense - if ((pRSN->byElementID == WLAN_EID_RSN) && - (pRSN->wVersion == 1)) { - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n"); - - pbyOUI = &(pRSN->abyRSN[0]); - if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40; - else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP; - else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104; - else if ( !memcmp(pbyOUI, abyOUIGK, 4)) { - // invalid CSS, P802.11i/D10.0, p32 - return; - } else - // any vendor checks here - pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK); - - if (pRSN->len == 6) { - pBSSNode->bWPA2Valid = true; - return; - } - - if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2) - pBSSNode->wCSSPKCount = *((unsigned short *) &(pRSN->abyRSN[4])); - j = 0; - pbyOUI = &(pRSN->abyRSN[6]); - - for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(unsigned char)); i++) { - - if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i) - if ( !memcmp(pbyOUI, abyOUIGK, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; - bUseGK = true; - } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) { - // Invalid CSS, continue to parsing - } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) { - if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; - else - ; // Invalid CSS, continue to parsing - } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; - } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) { - // Invalid CSS, continue to parsing - } else { - // any vendor checks here - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; - } - pbyOUI += 4; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]); - } else - break; - } //for - - if (bUseGK == true) { - if (j != 1) { - // invalid CSS, This should be only PK CSS. - return; - } - if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - // invalid CSS, If CCMP is enable , PK can't be CSSGK. - return; - } - } - if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) { - // invalid CSS, No valid PK. - return; - } - pBSSNode->wCSSPKCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); - } - - m = *((unsigned short *) &(pRSN->abyRSN[4])); - - if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((unsigned short *) &(pRSN->abyRSN[6+4*m])); - j = 0; - pbyOUI = &(pRSN->abyRSN[8+4*m]); - for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) { - if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i) - if ( !memcmp(pbyOUI, abyOUI8021X, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X; - else if ( !memcmp(pbyOUI, abyOUIPSK, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK; - else - // any vendor checks here - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]); - } else - break; - } - pBSSNode->wAKMSSAuthCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); - - n = *((unsigned short *) &(pRSN->abyRSN[6+4*m])); - if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) - pBSSNode->sRSNCapObj.bRSNCapExist = true; - pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *) &(pRSN->abyRSN[8+4*m+4*n])); - } - } - //ignore PMKID lists bcs only (Re)Assocrequest has this field - pBSSNode->bWPA2Valid = true; - } + int i, j; + unsigned short m = 0, n = 0; + unsigned char *pbyOUI; + bool bUseGK = false; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WPA2_ParseRSN: [%d]\n", pRSN->len); + + WPA2_ClearRSN(pBSSNode); + + if (pRSN->len == 2) { // ver(2) + if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) { + pBSSNode->bWPA2Valid = true; + } + return; + } + + if (pRSN->len < 6) { // ver(2) + GK(4) + // invalid CSS, P802.11i/D10.0, p31 + return; + } + + // information element header makes sense + if ((pRSN->byElementID == WLAN_EID_RSN) && + (pRSN->wVersion == 1)) { + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Legal 802.11i RSN\n"); + + pbyOUI = &(pRSN->abyRSN[0]); + if (!memcmp(pbyOUI, abyOUIWEP40, 4)) + pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40; + else if (!memcmp(pbyOUI, abyOUITKIP, 4)) + pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP; + else if (!memcmp(pbyOUI, abyOUICCMP, 4)) + pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; + else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) + pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104; + else if (!memcmp(pbyOUI, abyOUIGK, 4)) { + // invalid CSS, P802.11i/D10.0, p32 + return; + } else + // any vendor checks here + pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "802.11i CSS: %X\n", pBSSNode->byCSSGK); + + if (pRSN->len == 6) { + pBSSNode->bWPA2Valid = true; + return; + } + + if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2) + pBSSNode->wCSSPKCount = *((unsigned short *)&(pRSN->abyRSN[4])); + j = 0; + pbyOUI = &(pRSN->abyRSN[6]); + + for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(unsigned char)); i++) { + + if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i) + if (!memcmp(pbyOUI, abyOUIGK, 4)) { + pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; + bUseGK = true; + } else if (!memcmp(pbyOUI, abyOUIWEP40, 4)) { + // Invalid CSS, continue to parsing + } else if (!memcmp(pbyOUI, abyOUITKIP, 4)) { + if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) + pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; + else + ; // Invalid CSS, continue to parsing + } else if (!memcmp(pbyOUI, abyOUICCMP, 4)) { + pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; + } else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) { + // Invalid CSS, continue to parsing + } else { + // any vendor checks here + pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; + } + pbyOUI += 4; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]); + } else + break; + } //for + + if (bUseGK == true) { + if (j != 1) { + // invalid CSS, This should be only PK CSS. + return; + } + if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { + // invalid CSS, If CCMP is enable , PK can't be CSSGK. + return; + } + } + if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) { + // invalid CSS, No valid PK. + return; + } + pBSSNode->wCSSPKCount = (unsigned short)j; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); + } + + m = *((unsigned short *)&(pRSN->abyRSN[4])); + + if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) + pBSSNode->wAKMSSAuthCount = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); + j = 0; + pbyOUI = &(pRSN->abyRSN[8+4*m]); + for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) { + if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i) + if (!memcmp(pbyOUI, abyOUI8021X, 4)) + pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X; + else if (!memcmp(pbyOUI, abyOUIPSK, 4)) + pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK; + else + // any vendor checks here + pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]); + } else + break; + } + pBSSNode->wAKMSSAuthCount = (unsigned short)j; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); + + n = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); + if (pRSN->len >= 12 + 4 * m + 4 * n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) + pBSSNode->sRSNCapObj.bRSNCapExist = true; + pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *)&(pRSN->abyRSN[8+4*m+4*n])); + } + } + //ignore PMKID lists bcs only (Re)Assocrequest has this field + pBSSNode->bWPA2Valid = true; + } } @@ -260,105 +260,105 @@ WPA2vParseRSN ( * * Return Value: length of IEs. * --*/ + -*/ unsigned int WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs - ) + void *pMgmtHandle, + PWLAN_IE_RSN pRSNIEs +) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - unsigned char *pbyBuffer = NULL; - unsigned int ii = 0; - unsigned short *pwPMKID = NULL; - - if (pRSNIEs == NULL) { - return(0); - } - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA2 IE */ - pbyBuffer = (unsigned char *) pRSNIEs; - pRSNIEs->byElementID = WLAN_EID_RSN; - pRSNIEs->len = 6; //Version(2)+GK(4) - pRSNIEs->wVersion = 1; - //Group Key Cipher Suite - pRSNIEs->abyRSN[0] = 0x00; - pRSNIEs->abyRSN[1] = 0x0F; - pRSNIEs->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) { - pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP; - } else { - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - } - - // Pairwise Key Cipher Suite - pRSNIEs->abyRSN[4] = 1; - pRSNIEs->abyRSN[5] = 0; - pRSNIEs->abyRSN[6] = 0x00; - pRSNIEs->abyRSN[7] = 0x0F; - pRSNIEs->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) { - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP; - } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP; - } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - } else { - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - } - pRSNIEs->len += 6; - - // Auth Key Management Suite - pRSNIEs->abyRSN[10] = 1; - pRSNIEs->abyRSN[11] = 0; - pRSNIEs->abyRSN[12] = 0x00; - pRSNIEs->abyRSN[13] = 0x0F; - pRSNIEs->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - } else { - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - } - pRSNIEs->len +=6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { - memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - pRSNIEs->abyRSN[16] = 0; - pRSNIEs->abyRSN[17] = 0; - } - pRSNIEs->len +=2; - - if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && - (pMgmt->bRoaming == true) && - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]); // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list - for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { - if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID) ++; - memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); - pbyBuffer += 16; - } - } - if (*pwPMKID != 0) { - pRSNIEs->len += (2 + (*pwPMKID)*16); - } else { - pbyBuffer = &pRSNIEs->abyRSN[18]; - } - } - return(pRSNIEs->len + WLAN_IEHDR_LEN); - } - return(0); + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; + unsigned char *pbyBuffer = NULL; + unsigned int ii = 0; + unsigned short *pwPMKID = NULL; + + if (pRSNIEs == NULL) { + return(0); + } + if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && + (pMgmt->pCurrBSS != NULL)) { + /* WPA2 IE */ + pbyBuffer = (unsigned char *)pRSNIEs; + pRSNIEs->byElementID = WLAN_EID_RSN; + pRSNIEs->len = 6; //Version(2)+GK(4) + pRSNIEs->wVersion = 1; + //Group Key Cipher Suite + pRSNIEs->abyRSN[0] = 0x00; + pRSNIEs->abyRSN[1] = 0x0F; + pRSNIEs->abyRSN[2] = 0xAC; + if (pMgmt->byCSSGK == KEY_CTL_WEP) { + pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; + } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) { + pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) { + pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP; + } else { + pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; + } + + // Pairwise Key Cipher Suite + pRSNIEs->abyRSN[4] = 1; + pRSNIEs->abyRSN[5] = 0; + pRSNIEs->abyRSN[6] = 0x00; + pRSNIEs->abyRSN[7] = 0x0F; + pRSNIEs->abyRSN[8] = 0xAC; + if (pMgmt->byCSSPK == KEY_CTL_TKIP) { + pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP; + } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) { + pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP; + } else if (pMgmt->byCSSPK == KEY_CTL_NONE) { + pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; + } else { + pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; + } + pRSNIEs->len += 6; + + // Auth Key Management Suite + pRSNIEs->abyRSN[10] = 1; + pRSNIEs->abyRSN[11] = 0; + pRSNIEs->abyRSN[12] = 0x00; + pRSNIEs->abyRSN[13] = 0x0F; + pRSNIEs->abyRSN[14] = 0xAC; + if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) { + pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK; + } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { + pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X; + } else { + pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; + } + pRSNIEs->len += 6; + + // RSN Capabilities + if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { + memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); + } else { + pRSNIEs->abyRSN[16] = 0; + pRSNIEs->abyRSN[17] = 0; + } + pRSNIEs->len += 2; + + if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && + (pMgmt->bRoaming == true) && + (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { + // RSN PMKID + pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]); // Point to PMKID count + *pwPMKID = 0; // Initialize PMKID count + pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list + for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { + if (!memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); + pbyBuffer += 16; + } + } + if (*pwPMKID != 0) { + pRSNIEs->len += (2 + (*pwPMKID)*16); + } else { + pbyBuffer = &pRSNIEs->abyRSN[18]; + } + } + return(pRSNIEs->len + WLAN_IEHDR_LEN); + } + return(0); } diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h index 718208beb72f..34c92f46d6f0 100644 --- a/drivers/staging/vt6655/wpa2.h +++ b/drivers/staging/vt6655/wpa2.h @@ -40,13 +40,13 @@ #define MAX_PMKID_CACHE 16 typedef struct tagsPMKIDInfo { - unsigned char abyBSSID[6]; - unsigned char abyPMKID[16]; + unsigned char abyBSSID[6]; + unsigned char abyPMKID[16]; } PMKIDInfo, *PPMKIDInfo; typedef struct tagSPMKIDCache { - unsigned long BSSIDInfoCount; - PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; + unsigned long BSSIDInfoCount; + PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; } SPMKIDCache, *PSPMKIDCache; @@ -59,20 +59,20 @@ typedef struct tagSPMKIDCache { /*--------------------- Export Functions --------------------------*/ void -WPA2_ClearRSN ( - PKnownBSS pBSSNode - ); +WPA2_ClearRSN( + PKnownBSS pBSSNode +); void -WPA2vParseRSN ( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN - ); +WPA2vParseRSN( + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN +); unsigned int WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs - ); + void *pMgmtHandle, + PWLAN_IE_RSN pRSNIEs +); #endif // __WPA2_H__ -- cgit From f9cf92bfc67023091d6b9dbaab7de15ce0184686 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:14 -0700 Subject: staging:vt6655:wpactl: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wpactl.c | 868 ++++++++++++++++++++-------------------- drivers/staging/vt6655/wpactl.h | 2 +- 2 files changed, 435 insertions(+), 435 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 2b6ae1e403bf..eda17051297d 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -54,7 +54,7 @@ static const int frequency_list[] = { /*--------------------- Static Variables --------------------------*/ //static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ @@ -70,7 +70,7 @@ static void wpadev_setup(struct net_device *dev) dev->addr_len = ETH_ALEN; dev->tx_queue_len = 1000; - memset(dev->broadcast,0xFF, ETH_ALEN); + memset(dev->broadcast, 0xFF, ETH_ALEN); dev->flags = IFF_BROADCAST|IFF_MULTICAST; } @@ -91,37 +91,37 @@ static void wpadev_setup(struct net_device *dev) static int wpa_init_wpadev(PSDevice pDevice) { - PSDevice wpadev_priv; + PSDevice wpadev_priv; struct net_device *dev = pDevice->dev; - int ret=0; + int ret = 0; pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup); if (pDevice->wpadev == NULL) return -ENOMEM; - wpadev_priv = netdev_priv(pDevice->wpadev); - *wpadev_priv = *pDevice; + wpadev_priv = netdev_priv(pDevice->wpadev); + *wpadev_priv = *pDevice; memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN); - pDevice->wpadev->base_addr = dev->base_addr; + pDevice->wpadev->base_addr = dev->base_addr; pDevice->wpadev->irq = dev->irq; pDevice->wpadev->mem_start = dev->mem_start; pDevice->wpadev->mem_end = dev->mem_end; ret = register_netdev(pDevice->wpadev); if (ret) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n", - dev->name); + dev->name); free_netdev(pDevice->wpadev); return -1; } if (pDevice->skb == NULL) { - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - if (pDevice->skb == NULL) - return -ENOMEM; - } + pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + if (pDevice->skb == NULL) + return -ENOMEM; + } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n", - dev->name, pDevice->wpadev->name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n", + dev->name, pDevice->wpadev->name); return 0; } @@ -142,18 +142,18 @@ static int wpa_init_wpadev(PSDevice pDevice) static int wpa_release_wpadev(PSDevice pDevice) { - if (pDevice->skb) { - dev_kfree_skb(pDevice->skb); - pDevice->skb = NULL; - } - - if (pDevice->wpadev) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->wpadev->name); - unregister_netdev(pDevice->wpadev); - free_netdev(pDevice->wpadev); - pDevice->wpadev = NULL; - } + if (pDevice->skb) { + dev_kfree_skb(pDevice->skb); + pDevice->skb = NULL; + } + + if (pDevice->wpadev) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", + pDevice->dev->name, pDevice->wpadev->name); + unregister_netdev(pDevice->wpadev); + free_netdev(pDevice->wpadev); + pDevice->wpadev = NULL; + } return 0; } @@ -199,245 +199,245 @@ int wpa_set_wpadev(PSDevice pDevice, int val) * */ - int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel) +int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel) { - struct viawget_wpa_param *param=ctx; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - QWORD KeyRSC; + struct viawget_wpa_param *param = ctx; + PSMgmtObject pMgmt = pDevice->pMgmt; + unsigned long dwKeyIndex = 0; + unsigned char abyKey[MAX_KEY_LEN]; + unsigned char abySeq[MAX_KEY_LEN]; + QWORD KeyRSC; // NDIS_802_11_KEY_RSC KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; + unsigned char byKeyDecMode = KEY_CTL_WEP; int ret = 0; int uu, ii; if (param->u.wpa_key.alg_name > WPA_ALG_CCMP || - param->u.wpa_key.key_len >= MAX_KEY_LEN || - param->u.wpa_key.seq_len >= MAX_KEY_LEN) + param->u.wpa_key.key_len >= MAX_KEY_LEN || + param->u.wpa_key.seq_len >= MAX_KEY_LEN) return -EINVAL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name); if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - pDevice->bEncryptionEnable = false; - pDevice->byKeyIndex = 0; - pDevice->bTransmitKey = false; - KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset); - for (uu=0; uuPortOffset, uu); - } - return ret; - } - - //spin_unlock_irq(&pDevice->lock); - if(param->u.wpa_key.key && fcpfkernel) { - memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); - } - else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.key && - copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } -spin_lock_irq(&pDevice->lock); - } + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + pDevice->bEncryptionEnable = false; + pDevice->byKeyIndex = 0; + pDevice->bTransmitKey = false; + KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset); + for (uu = 0; uu < MAX_KEY_TABLE; uu++) { + MACvDisableKeyEntry(pDevice->PortOffset, uu); + } + return ret; + } - dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index); + //spin_unlock_irq(&pDevice->lock); + if (param->u.wpa_key.key && fcpfkernel) { + memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); + } + else { + spin_unlock_irq(&pDevice->lock); + if (param->u.wpa_key.key && + copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) { + spin_lock_irq(&pDevice->lock); + return -EINVAL; + } + spin_lock_irq(&pDevice->lock); + } + + dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index); if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { - if (dwKeyIndex > 3) { - return -EINVAL; - } - else { - if (param->u.wpa_key.set_tx) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.wpa_key.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - return ret; - } - - //spin_unlock_irq(&pDevice->lock); - if(param->u.wpa_key.seq && fcpfkernel) { - memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); - } - else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.seq && - copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } -spin_lock_irq(&pDevice->lock); -} + if (dwKeyIndex > 3) { + return -EINVAL; + } + else { + if (param->u.wpa_key.set_tx) { + pDevice->byKeyIndex = (unsigned char)dwKeyIndex; + pDevice->bTransmitKey = true; + dwKeyIndex |= (1 << 31); + } + KeybSetDefaultKey(&(pDevice->sKey), + dwKeyIndex & ~(BIT30 | USE_KEYRSC), + param->u.wpa_key.key_len, + NULL, + abyKey, + KEY_CTL_WEP, + pDevice->PortOffset, + pDevice->byLocalID); + + } + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + pDevice->bEncryptionEnable = true; + return ret; + } + + //spin_unlock_irq(&pDevice->lock); + if (param->u.wpa_key.seq && fcpfkernel) { + memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); + } + else { + spin_unlock_irq(&pDevice->lock); + if (param->u.wpa_key.seq && + copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) { + spin_lock_irq(&pDevice->lock); + return -EINVAL; + } + spin_lock_irq(&pDevice->lock); + } if (param->u.wpa_key.seq_len > 0) { - for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) { - if (ii < 4) - LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); - else - HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8)); - //KeyRSC |= (abySeq[ii] << (ii * 8)); + for (ii = 0; ii < param->u.wpa_key.seq_len; ii++) { + if (ii < 4) + LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); + else + HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8)); + //KeyRSC |= (abySeq[ii] << (ii * 8)); } dwKeyIndex |= 1 << 29; } - if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); - return -EINVAL; - } + if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); + return -EINVAL; + } if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - } + pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; + } if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - } + pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; + } if (param->u.wpa_key.set_tx) dwKeyIndex |= (1 << 31); - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - byKeyDecMode = KEY_CTL_CCMP; - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - byKeyDecMode = KEY_CTL_TKIP; - else - byKeyDecMode = KEY_CTL_WEP; - - // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (param->u.wpa_key.key_len == MAX_KEY_LEN) - byKeyDecMode = KEY_CTL_TKIP; - else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } - - // Check TKIP key length - if ((byKeyDecMode == KEY_CTL_TKIP) && - (param->u.wpa_key.key_len != MAX_KEY_LEN)) { - // TKIP Key must be 256 bits - //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n")); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); - return -EINVAL; - } - // Check AES key length - if ((byKeyDecMode == KEY_CTL_CCMP) && - (param->u.wpa_key.key_len != AES_KEY_LEN)) { - // AES Key must be 128 bits - //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n")); - return -EINVAL; - } - - // spin_lock_irq(&pDevice->lock); - if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { - // If is_broadcast_ether_addr, set the key as every key entry's group key. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); - - if ((KeybSetAllGroupKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) == true) && - (KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) == true) ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); - - } else { - //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n")); - // spin_unlock_irq(&pDevice->lock); - return -EINVAL; - } - - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); - // BSSID not 0xffffffffffff - // Pairwise Key can't be WEP - if (byKeyDecMode == KEY_CTL_WEP) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); - //spin_unlock_irq(&pDevice->lock); - return -EINVAL; - } - - dwKeyIndex |= (1 << 30); // set pairwise key - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n")); - //spin_unlock_irq(&pDevice->lock); - return -EINVAL; - } - if (KeybSetKey(&(pDevice->sKey), - ¶m->addr[0], - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); - - } else { - // Key Table Full - if (!compare_ether_addr(¶m->addr[0], pDevice->abyBSSID)) { - //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n")); - //spin_unlock_irq(&pDevice->lock); - return -EINVAL; - - } else { - // Save Key and configure just before associate/reassociate to BSSID - // we do not implement now - //spin_unlock_irq(&pDevice->lock); - return -EINVAL; - } - } - } // BSSID not 0xffffffffffff - if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { - pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index; - pDevice->bTransmitKey = true; - } - pDevice->bEncryptionEnable = true; - //spin_unlock_irq(&pDevice->lock); + if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) + byKeyDecMode = KEY_CTL_CCMP; + else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) + byKeyDecMode = KEY_CTL_TKIP; + else + byKeyDecMode = KEY_CTL_WEP; + + // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled + if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { + if (param->u.wpa_key.key_len == MAX_KEY_LEN) + byKeyDecMode = KEY_CTL_TKIP; + else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) + byKeyDecMode = KEY_CTL_WEP; + else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) + byKeyDecMode = KEY_CTL_WEP; + } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { + if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) + byKeyDecMode = KEY_CTL_WEP; + else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) + byKeyDecMode = KEY_CTL_WEP; + } + + // Check TKIP key length + if ((byKeyDecMode == KEY_CTL_TKIP) && + (param->u.wpa_key.key_len != MAX_KEY_LEN)) { + // TKIP Key must be 256 bits + //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n")); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); + return -EINVAL; + } + // Check AES key length + if ((byKeyDecMode == KEY_CTL_CCMP) && + (param->u.wpa_key.key_len != AES_KEY_LEN)) { + // AES Key must be 128 bits + //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n")); + return -EINVAL; + } + + // spin_lock_irq(&pDevice->lock); + if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { + // If is_broadcast_ether_addr, set the key as every key entry's group key. + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); + + if ((KeybSetAllGroupKey(&(pDevice->sKey), + dwKeyIndex, + param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), + (unsigned char *)abyKey, + byKeyDecMode, + pDevice->PortOffset, + pDevice->byLocalID) == true) && + (KeybSetDefaultKey(&(pDevice->sKey), + dwKeyIndex, + param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), + (unsigned char *)abyKey, + byKeyDecMode, + pDevice->PortOffset, + pDevice->byLocalID) == true)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); + + } else { + //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n")); + // spin_unlock_irq(&pDevice->lock); + return -EINVAL; + } + + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); + // BSSID not 0xffffffffffff + // Pairwise Key can't be WEP + if (byKeyDecMode == KEY_CTL_WEP) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); + //spin_unlock_irq(&pDevice->lock); + return -EINVAL; + } + + dwKeyIndex |= (1 << 30); // set pairwise key + if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { + //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n")); + //spin_unlock_irq(&pDevice->lock); + return -EINVAL; + } + if (KeybSetKey(&(pDevice->sKey), + ¶m->addr[0], + dwKeyIndex, + param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), + (unsigned char *)abyKey, + byKeyDecMode, + pDevice->PortOffset, + pDevice->byLocalID) == true) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); + + } else { + // Key Table Full + if (!compare_ether_addr(¶m->addr[0], pDevice->abyBSSID)) { + //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n")); + //spin_unlock_irq(&pDevice->lock); + return -EINVAL; + + } else { + // Save Key and configure just before associate/reassociate to BSSID + // we do not implement now + //spin_unlock_irq(&pDevice->lock); + return -EINVAL; + } + } + } // BSSID not 0xffffffffffff + if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { + pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index; + pDevice->bTransmitKey = true; + } + pDevice->bEncryptionEnable = true; + //spin_unlock_irq(&pDevice->lock); /* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3], + pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4] +); */ return ret; @@ -460,22 +460,22 @@ spin_lock_irq(&pDevice->lock); */ static int wpa_set_wpa(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; int ret = 0; - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - pMgmt->bShareKeyAlgorithm = false; + pMgmt->eAuthenMode = WMAC_AUTH_OPEN; + pMgmt->bShareKeyAlgorithm = false; - return ret; + return ret; } - /* +/* * Description: * set disassociate * @@ -490,19 +490,19 @@ static int wpa_set_wpa(PSDevice pDevice, */ static int wpa_set_disassociate(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; int ret = 0; - spin_lock_irq(&pDevice->lock); - if (pDevice->bLinkPass) { - if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - } - spin_unlock_irq(&pDevice->lock); + spin_lock_irq(&pDevice->lock); + if (pDevice->bLinkPass) { + if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + } + spin_unlock_irq(&pDevice->lock); - return ret; + return ret; } @@ -522,16 +522,16 @@ static int wpa_set_disassociate(PSDevice pDevice, */ static int wpa_set_scan(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { int ret = 0; - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); + spin_lock_irq(&pDevice->lock); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); + spin_unlock_irq(&pDevice->lock); - return ret; + return ret; } @@ -551,14 +551,14 @@ static int wpa_set_scan(PSDevice pDevice, */ static int wpa_get_bssid(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; int ret = 0; memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6); - return ret; + return ret; } @@ -578,18 +578,18 @@ static int wpa_get_bssid(PSDevice pDevice, */ static int wpa_get_ssid(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; + PSMgmtObject pMgmt = pDevice->pMgmt; PWLAN_IE_SSID pItemSSID; int ret = 0; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len); param->u.wpa_associate.ssid_len = pItemSSID->len; - return ret; + return ret; } @@ -609,65 +609,65 @@ static int wpa_get_ssid(PSDevice pDevice, */ static int wpa_get_scan(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { struct viawget_scan_result *scan_buf; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PKnownBSS pBSS; + PSMgmtObject pMgmt = pDevice->pMgmt; + PWLAN_IE_SSID pItemSSID; + PKnownBSS pBSS; unsigned char *pBuf; int ret = 0; u16 count = 0; u16 ii, jj; #if 1 - unsigned char *ptempBSS; + unsigned char *ptempBSS; - ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC); + ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC); - if (ptempBSS == NULL) { + if (ptempBSS == NULL) { - printk("bubble sort kmalloc memory fail@@@\n"); + printk("bubble sort kmalloc memory fail@@@\n"); - ret = -ENOMEM; + ret = -ENOMEM; - return ret; + return ret; - } + } - for (ii = 0; ii < MAX_BSS_NUM; ii++) { + for (ii = 0; ii < MAX_BSS_NUM; ii++) { - for(jj=0;jjsBSSList[jj].bActive!=true) || + if ((pMgmt->sBSSList[jj].bActive != true) || - ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) { + ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI) && (pMgmt->sBSSList[jj + 1].bActive != false))) { - memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS)); + memcpy(ptempBSS, &pMgmt->sBSSList[jj], sizeof(KnownBSS)); - memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS)); + memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1], sizeof(KnownBSS)); - memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS)); + memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS)); - } + } - } + } - } + } - kfree(ptempBSS); + kfree(ptempBSS); - // printk("bubble sort result:\n"); + // printk("bubble sort result:\n"); - //for (ii = 0; ii < MAX_BSS_NUM; ii++) + //for (ii = 0; ii < MAX_BSS_NUM; ii++) - // printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID, + // printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID, - // pMgmt->sBSSList[ii].uRSSI); + // pMgmt->sBSSList[ii].uRSSI); - #endif +#endif //******mike:bubble sort by stronger RSSI*****// @@ -676,61 +676,61 @@ static int wpa_get_scan(PSDevice pDevice, count = 0; pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - count++; - } - - pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); - - if (pBuf == NULL) { - ret = -ENOMEM; - return ret; - } - scan_buf = (struct viawget_scan_result *)pBuf; + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + pBSS = &(pMgmt->sBSSList[ii]); + if (!pBSS->bActive) + continue; + count++; + } + + pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); + + if (pBuf == NULL) { + ret = -ENOMEM; + return ret; + } + scan_buf = (struct viawget_scan_result *)pBuf; pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (pBSS->bActive) { - if (jj >= count) - break; - memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); - scan_buf->ssid_len = pItemSSID->len; - scan_buf->freq = frequency_list[pBSS->uChannel-1]; - scan_buf->caps = pBSS->wCapInfo; - //scan_buf->caps = pBSS->wCapInfo; - //scan_buf->qual = - //scan_buf->noise = - //scan_buf->level = - //scan_buf->maxrate = - if (pBSS->wWPALen != 0) { - scan_buf->wpa_ie_len = pBSS->wWPALen; - memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); - } - if (pBSS->wRSNLen != 0) { - scan_buf->rsn_ie_len = pBSS->wRSNLen; - memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); - } - scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result)); - jj ++; - } - } - - if (jj < count) - count = jj; - - if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) { + for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { + pBSS = &(pMgmt->sBSSList[ii]); + if (pBSS->bActive) { + if (jj >= count) + break; + memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); + pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; + memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); + scan_buf->ssid_len = pItemSSID->len; + scan_buf->freq = frequency_list[pBSS->uChannel-1]; + scan_buf->caps = pBSS->wCapInfo; + //scan_buf->caps = pBSS->wCapInfo; + //scan_buf->qual = + //scan_buf->noise = + //scan_buf->level = + //scan_buf->maxrate = + if (pBSS->wWPALen != 0) { + scan_buf->wpa_ie_len = pBSS->wWPALen; + memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); + } + if (pBSS->wRSNLen != 0) { + scan_buf->rsn_ie_len = pBSS->wRSNLen; + memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); + } + scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result)); + jj++; + } + } + + if (jj < count) + count = jj; + + if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) { ret = -EFAULT; } param->u.scan_results.scan_count = count; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count) - kfree(pBuf); - return ret; + kfree(pBuf); + return ret; } @@ -750,22 +750,22 @@ static int wpa_get_scan(PSDevice pDevice, */ static int wpa_set_associate(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char abyWPAIE[64]; - int ret = 0; - bool bWepEnabled=false; + PSMgmtObject pMgmt = pDevice->pMgmt; + PWLAN_IE_SSID pItemSSID; + unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char abyWPAIE[64]; + int ret = 0; + bool bWepEnabled = false; // set key type & algorithm - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); if (param->u.wpa_associate.wpa_ie_len) { @@ -778,28 +778,28 @@ static int wpa_set_associate(PSDevice pDevice, } if (param->u.wpa_associate.mode == 1) - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; + pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; else - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - // set ssid + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; + // set ssid memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSID->byElementID = WLAN_EID_SSID; pItemSSID->len = param->u.wpa_associate.ssid_len; memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len); // set bssid - if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) - memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); -else -{ - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); -} + if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) + memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); + else + { + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); + } - if (param->u.wpa_associate.wpa_ie_len == 0) { - if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY) - pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; - else - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; + if (param->u.wpa_associate.wpa_ie_len == 0) { + if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY) + pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; + else + pMgmt->eAuthenMode = WMAC_AUTH_OPEN; } else if (abyWPAIE[0] == RSN_INFO_ELEM) { if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; @@ -809,9 +809,9 @@ else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE) pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; + pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; else - pMgmt->eAuthenMode = WMAC_AUTH_WPA; + pMgmt->eAuthenMode = WMAC_AUTH_WPA; } switch (param->u.wpa_associate.pairwise_suite) { @@ -824,7 +824,7 @@ else case CIPHER_WEP40: case CIPHER_WEP104: pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - bWepEnabled=true; + bWepEnabled = true; break; case CIPHER_NONE: if (param->u.wpa_associate.group_suite == CIPHER_CCMP) @@ -838,52 +838,52 @@ else //DavidWang add for WPA_supplicant support open/share mode - if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; - pMgmt->bShareKeyAlgorithm = true; - } - else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { - if(!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - //pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - //pMgmt->bShareKeyAlgorithm = false; //20080717-06, by chester//Fix Open mode, WEP encryption - } + if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; + pMgmt->bShareKeyAlgorithm = true; + } + else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { + if (!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + //pMgmt->eAuthenMode = WMAC_AUTH_OPEN; + //pMgmt->bShareKeyAlgorithm = false; //20080717-06, by chester//Fix Open mode, WEP encryption + } //mike save old encryption status pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus; - if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) - pDevice->bEncryptionEnable = true; - else - pDevice->bEncryptionEnable = false; -if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || - ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==true))) ) //DavidWang //20080717-06, by chester//Not to initial WEP - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); + if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) + pDevice->bEncryptionEnable = true; + else + pDevice->bEncryptionEnable = false; + if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || + ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled == true)))) //DavidWang //20080717-06, by chester//Not to initial WEP + KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); + spin_lock_irq(&pDevice->lock); + pDevice->bLinkPass = false; + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + netif_stop_queue(pDevice->dev); //20080701-02, by Mike Liu /*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/ -{ - PKnownBSS pCurr = NULL; - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode - ); - - if (pCurr == NULL){ - printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - } -} + { + PKnownBSS pCurr = NULL; + pCurr = BSSpSearchBSSList(pDevice, + pMgmt->abyDesireBSSID, + pMgmt->abyDesireSSID, + pMgmt->eConfigPHYMode +); + + if (pCurr == NULL) { + printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + } + } /****************************************************************/ - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); + spin_unlock_irq(&pDevice->lock); - return ret; + return ret; } @@ -922,61 +922,61 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) switch (param->cmd) { case VIAWGET_SET_WPA: - ret = wpa_set_wpa(pDevice, param); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n"); + ret = wpa_set_wpa(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n"); break; case VIAWGET_SET_KEY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n"); - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, false); - spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n"); + spin_lock_irq(&pDevice->lock); + ret = wpa_set_keys(pDevice, param, false); + spin_unlock_irq(&pDevice->lock); break; case VIAWGET_SET_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n"); - ret = wpa_set_scan(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n"); + ret = wpa_set_scan(pDevice, param); break; case VIAWGET_GET_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n"); - ret = wpa_get_scan(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n"); + ret = wpa_get_scan(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_SSID: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n"); - ret = wpa_get_ssid(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n"); + ret = wpa_get_ssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_BSSID: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n"); - ret = wpa_get_bssid(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n"); + ret = wpa_get_bssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_SET_ASSOCIATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n"); - ret = wpa_set_associate(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n"); + ret = wpa_set_associate(pDevice, param); break; case VIAWGET_SET_DISASSOCIATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n"); - ret = wpa_set_disassociate(pDevice, param); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n"); + ret = wpa_set_disassociate(pDevice, param); break; case VIAWGET_SET_DROP_UNENCRYPT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n"); break; - case VIAWGET_SET_DEAUTHENTICATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n"); + case VIAWGET_SET_DEAUTHENTICATE: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n"); break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", - param->cmd); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", + param->cmd); return -EOPNOTSUPP; break; } diff --git a/drivers/staging/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h index dbe8e861d991..2b7a05a2902e 100644 --- a/drivers/staging/vt6655/wpactl.h +++ b/drivers/staging/vt6655/wpactl.h @@ -42,7 +42,7 @@ typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 } wpa_cipher; -typedef enum { KEY_MGMT_802_1X, KEY_MGMT_CCKM,KEY_MGMT_PSK, KEY_MGMT_NONE, +typedef enum { KEY_MGMT_802_1X, KEY_MGMT_CCKM, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt; #define AUTH_ALG_OPEN_SYSTEM 0x01 -- cgit From 180071a1c3b145fcd3a12356ed1d3c9c1be72cf0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 18 Mar 2013 10:45:15 -0700 Subject: staging:vt6655:wroute: Whitespace cleanups Neatening only. git diff -w shows no differences. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wroute.c | 256 ++++++++++++++++++++-------------------- drivers/staging/vt6655/wroute.h | 2 +- 2 files changed, 129 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 82e93cb82053..0f9ff2e1462b 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -43,7 +43,7 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; /*--------------------- Static Functions --------------------------*/ @@ -65,134 +65,134 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: true if packet duplicate; otherwise false * */ -bool ROUTEbRelay (PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex) +bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex) { - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum; - unsigned char byPktType; - bool bNeedEncryption = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; - unsigned int ii; - unsigned char *pbyBSSID; - - - - - if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n"); - return false; - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)pbySkbData, ETH_HLEN); - - cbFrameBodySize = uDataLen - ETH_HLEN; - - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { - cbFrameBodySize += 8; - } - - if (pDevice->bEncryptionEnable == true) { - bNeedEncryption = true; - - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); - } - } - - if (pDevice->bEnableHostWEP) { - if (uNodeIndex < MAX_NODE_NUM + 1) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - } - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) { - return false; - } - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) { - pDevice->wCurrentRate = RATE_11M; - } else { - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } - } - else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - if (pDevice->wCurrentRate <= RATE_11M) - byPktType = PK_TYPE_11B; - - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_AC0DMA, pHeadTD, - &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - pLastTD->pTDInfo->skb = 0; - pLastTD->pTDInfo->byFlags = 0; - - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; - - MACvTransmitAC0(pDevice->PortOffset); - - return true; + PSMgmtObject pMgmt = pDevice->pMgmt; + PSTxDesc pHeadTD, pLastTD; + unsigned int cbFrameBodySize; + unsigned int uMACfragNum; + unsigned char byPktType; + bool bNeedEncryption = false; + SKeyItem STempKey; + PSKeyItem pTransmitKey = NULL; + unsigned int cbHeaderSize; + unsigned int ii; + unsigned char *pbyBSSID; + + + + + if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n"); + return false; + } + + pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; + + pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP); + + memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)pbySkbData, ETH_HLEN); + + cbFrameBodySize = uDataLen - ETH_HLEN; + + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { + cbFrameBodySize += 8; + } + + if (pDevice->bEncryptionEnable == true) { + bNeedEncryption = true; + + // get group key + pbyBSSID = pDevice->abyBroadcastAddr; + if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { + pTransmitKey = NULL; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + } + } + + if (pDevice->bEnableHostWEP) { + if (uNodeIndex < MAX_NODE_NUM + 1) { + pTransmitKey = &STempKey; + pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; + pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; + pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; + pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; + pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; + memcpy(pTransmitKey->abyKey, + &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], + pTransmitKey->uKeyLength +); + } + } + + uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); + + if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { + return false; + } + byPktType = (unsigned char)pDevice->byPacketType; + + if (pDevice->bFixRate) { + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + if (pDevice->uConnectionRate >= RATE_11M) { + pDevice->wCurrentRate = RATE_11M; + } else { + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } + } else { + if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && + (pDevice->uConnectionRate <= RATE_6M)) { + pDevice->wCurrentRate = RATE_6M; + } else { + if (pDevice->uConnectionRate >= RATE_54M) + pDevice->wCurrentRate = RATE_54M; + else + pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; + } + } + } + else { + pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; + } + + if (pDevice->wCurrentRate <= RATE_11M) + byPktType = PK_TYPE_11B; + + vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, + cbFrameBodySize, TYPE_AC0DMA, pHeadTD, + &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex, + &uMACfragNum, + &cbHeaderSize +); + + if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { + // Disable PS + MACbPSWakeup(pDevice->PortOffset); + } + + pDevice->bPWBitOn = false; + + pLastTD = pHeadTD; + for (ii = 0; ii < uMACfragNum; ii++) { + // Poll Transmit the adapter + wmb(); + pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; + wmb(); + if (ii == (uMACfragNum - 1)) + pLastTD = pHeadTD; + pHeadTD = pHeadTD->next; + } + + pLastTD->pTDInfo->skb = 0; + pLastTD->pTDInfo->byFlags = 0; + + pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; + + MACvTransmitAC0(pDevice->PortOffset); + + return true; } diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h index 34f9e43a6cc4..ddaec1f58e32 100644 --- a/drivers/staging/vt6655/wroute.h +++ b/drivers/staging/vt6655/wroute.h @@ -39,7 +39,7 @@ /*--------------------- Export Functions --------------------------*/ -bool ROUTEbRelay (PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex); +bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex); #endif // __WROUTE_H__ -- cgit From ad3c025b35832f9634523651d27dbf1233570976 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Sat, 16 Mar 2013 09:31:10 -0400 Subject: zcache/TODO: Update on two items. Two of them (zcache DebugFS cleanup) and the module loading capability are now in linux-next for v3.10. Also Bob Liu is full-time going to help on knocking these items off the list. CC: bob.liu@oracle.com Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/TODO | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/TODO b/drivers/staging/zcache/TODO index c1e26d4973dc..ec9aa11653b9 100644 --- a/drivers/staging/zcache/TODO +++ b/drivers/staging/zcache/TODO @@ -41,14 +41,10 @@ STATUS/OWNERSHIP for 3.9, see https://lkml.org/lkml/2013/2/6/437; 7. PROTOTYPED as part of "new" zcache; in staging/zcache for 3.9; needs more review (plan to discuss at LSF/MM 2013) -8. IN PROGRESS; owned by Konrad Wilk; v2 recently posted - http://lkml.org/lkml/2013/2/1/542 9. IN PROGRESS; owned by Konrad Wilk; Mel Gorman provided great feedback in August 2012 (unfortunately of "old" zcache) -10. Konrad posted series of fixes (that now need rebasing) - https://lkml.org/lkml/2013/2/1/566 -11. NOT DONE; owned by Konrad Wilk +11. NOT DONE; owned by Konrad Wilk and Bob Liu 12. TBD (depends on quantity of feedback) 13. PROPOSED; one suggestion proposed by Dan; needs more ideas/feedback 14. TBD (depends on feedback) -- cgit From dcb4e2d9bb4e3b6ad05bc513a237a87e46952341 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Fri, 15 Mar 2013 10:34:16 +0800 Subject: staging: zcache: introduce zero filled pages handler Introduce zero-filled pages handler to capture and handle zero pages. Acked-by: Dan Magenheimer Signed-off-by: Wanpeng Li Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 7a6dd966931b..86ead8d96796 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -277,6 +277,32 @@ static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) kmem_cache_free(zcache_obj_cache, obj); } +static bool page_is_zero_filled(void *ptr) +{ + unsigned int pos; + unsigned long *page; + + page = (unsigned long *)ptr; + + for (pos = 0; pos < PAGE_SIZE / sizeof(*page); pos++) { + if (page[pos]) + return false; + } + + return true; +} + +static void handle_zero_filled_page(void *page) +{ + void *user_mem; + + user_mem = kmap_atomic(page); + memset(user_mem, 0, PAGE_SIZE); + kunmap_atomic(user_mem); + + flush_dcache_page(page); +} + static struct tmem_hostops zcache_hostops = { .obj_alloc = zcache_obj_alloc, .obj_free = zcache_obj_free, -- cgit From 25eeb667599b192ea850a062d69383ee864c06ab Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Wed, 13 Mar 2013 15:06:16 +0800 Subject: zram: fix zram_bvec_read duplicate dump failure message and stat accumulation When zram decompress fails, the code unnecessarily dumps failure messages and does stat accumulation in function zram_decompress_page(), this work is already done in function zram_decompress_page, the patch skips the redundant work. Signed-off-by: Wanpeng Li Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 5918fd7d7e36..e34e3fe0ae2e 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -207,11 +207,8 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, ret = zram_decompress_page(zram, uncmem, index); /* 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); + if (unlikely(ret != LZO_E_OK)) goto out_cleanup; - } if (is_partial_io(bvec)) memcpy(user_mem + bvec->bv_offset, uncmem + offset, -- cgit From 501ad1c49b3d8c7b7495ef044c698c22710fc27d Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Mon, 18 Mar 2013 09:58:03 +0100 Subject: FIX: softingcs conversion to module_pcmcia_driver macro Reported-by: Stephen Rothwell Signed-off-by: Kurt Van Dijck Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/softing/softing_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c index 738355c12744..498605f833dd 100644 --- a/drivers/net/can/softing/softing_cs.c +++ b/drivers/net/can/softing/softing_cs.c @@ -340,7 +340,7 @@ static struct pcmcia_driver softingcs_driver = { .remove = softingcs_remove, }; -module_pcmcia_driver(&softingcs_driver); +module_pcmcia_driver(softingcs_driver); MODULE_DESCRIPTION("softing CANcard driver" ", links PCMCIA card to softing driver"); -- cgit From 6f8da5df8c451103e0043f73a00c90676da6be9e Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Tue, 12 Mar 2013 18:08:09 -0400 Subject: power_supply: Add support for tps65090-charger This patch adds support for the tps65090 charger driver. This driver is responsible for controlling the charger aspect of the tps65090 mfd. Currently, this mainly consists of turning on and off the charger, but some features of the charger can be supported through this driver including: - Enable Auto Recharge based on Battery voltage - Fast Charge Safety Timer - Maximum battery discharge current - Maximum battery adapter current - Enable External Charge - Disable charging termination based on low charger current (supported) Once the driver is accepted, later patches can add support for the features above which are not yet supported. Based on work by: Syed Rafiuddin Laxman Dewangan Signed-off-by: Rhyland Klein Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 7 + drivers/power/Makefile | 1 + drivers/power/tps65090-charger.c | 315 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/tps65090.h | 5 + 4 files changed, 328 insertions(+) create mode 100644 drivers/power/tps65090-charger.c (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 07e1a8f8d03e..339f802b91c1 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -340,6 +340,13 @@ config CHARGER_SMB347 Say Y to include support for Summit Microelectronics SMB347 Battery Charger. +config CHARGER_TPS65090 + tristate "TPS65090 battery charger driver" + depends on MFD_TPS65090 + help + Say Y here to enable support for battery charging with TPS65090 + PMIC chips. + config AB8500_BM bool "AB8500 Battery Management Driver" depends on AB8500_CORE && AB8500_GPADC diff --git a/drivers/power/Makefile b/drivers/power/Makefile index eb520ea74970..653bf6ceff30 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -52,4 +52,5 @@ obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o obj-$(CONFIG_POWER_AVS) += avs/ obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o +obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o obj-$(CONFIG_POWER_RESET) += reset/ diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c new file mode 100644 index 000000000000..0c66c6656b13 --- /dev/null +++ b/drivers/power/tps65090-charger.c @@ -0,0 +1,315 @@ +/* + * Battery charger driver for TI's tps65090 + * + * Copyright (c) 2013, NVIDIA 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, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS65090_REG_INTR_STS 0x00 +#define TPS65090_REG_CG_CTRL0 0x04 +#define TPS65090_REG_CG_CTRL1 0x05 +#define TPS65090_REG_CG_CTRL2 0x06 +#define TPS65090_REG_CG_CTRL3 0x07 +#define TPS65090_REG_CG_CTRL4 0x08 +#define TPS65090_REG_CG_CTRL5 0x09 +#define TPS65090_REG_CG_STATUS1 0x0a +#define TPS65090_REG_CG_STATUS2 0x0b + +#define TPS65090_CHARGER_ENABLE BIT(0) +#define TPS65090_VACG BIT(1) +#define TPS65090_NOITERM BIT(5) + +struct tps65090_charger { + struct device *dev; + int ac_online; + int prev_ac_online; + int irq; + struct power_supply ac; + struct tps65090_platform_data *pdata; +}; + +static enum power_supply_property tps65090_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static int tps65090_low_chrg_current(struct tps65090_charger *charger) +{ + int ret; + + ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL5, + TPS65090_NOITERM); + if (ret < 0) { + dev_err(charger->dev, "%s(): error reading in register 0x%x\n", + __func__, TPS65090_REG_CG_CTRL5); + return ret; + } + return 0; +} + +static int tps65090_enable_charging(struct tps65090_charger *charger, + uint8_t enable) +{ + int ret; + uint8_t ctrl0 = 0; + + ret = tps65090_read(charger->dev->parent, TPS65090_REG_CG_CTRL0, + &ctrl0); + if (ret < 0) { + dev_err(charger->dev, "%s(): error reading in register 0x%x\n", + __func__, TPS65090_REG_CG_CTRL0); + return ret; + } + + ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL0, + (ctrl0 | TPS65090_CHARGER_ENABLE)); + if (ret < 0) { + dev_err(charger->dev, "%s(): error reading in register 0x%x\n", + __func__, TPS65090_REG_CG_CTRL0); + return ret; + } + return 0; +} + +static int tps65090_config_charger(struct tps65090_charger *charger) +{ + int ret; + + if (charger->pdata->enable_low_current_chrg) { + ret = tps65090_low_chrg_current(charger); + if (ret < 0) { + dev_err(charger->dev, + "error configuring low charge current\n"); + return ret; + } + } + + return 0; +} + +static int tps65090_ac_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct tps65090_charger *charger = container_of(psy, + struct tps65090_charger, ac); + + if (psp == POWER_SUPPLY_PROP_ONLINE) { + val->intval = charger->ac_online; + charger->prev_ac_online = charger->ac_online; + return 0; + } + return -EINVAL; +} + +static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) +{ + struct tps65090_charger *charger = dev_id; + int ret; + uint8_t status1 = 0; + uint8_t intrsts = 0; + + ret = tps65090_read(charger->dev->parent, TPS65090_REG_CG_STATUS1, + &status1); + if (ret < 0) { + dev_err(charger->dev, "%s(): Error in reading reg 0x%x\n", + __func__, TPS65090_REG_CG_STATUS1); + return IRQ_HANDLED; + } + msleep(75); + ret = tps65090_read(charger->dev->parent, TPS65090_REG_INTR_STS, + &intrsts); + if (ret < 0) { + dev_err(charger->dev, "%s(): Error in reading reg 0x%x\n", + __func__, TPS65090_REG_INTR_STS); + return IRQ_HANDLED; + } + + if (intrsts & TPS65090_VACG) { + ret = tps65090_enable_charging(charger, 1); + if (ret < 0) + return IRQ_HANDLED; + charger->ac_online = 1; + } else { + charger->ac_online = 0; + } + + if (charger->prev_ac_online != charger->ac_online) + power_supply_changed(&charger->ac); + + return IRQ_HANDLED; +} + +#if defined(CONFIG_OF) + +#include + +static struct tps65090_platform_data * + tps65090_parse_dt_charger_data(struct platform_device *pdev) +{ + struct tps65090_platform_data *pdata; + struct device_node *np = pdev->dev.parent->of_node; + unsigned int prop; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(&pdev->dev, "Memory alloc for tps65090_pdata failed\n"); + return NULL; + } + + prop = of_property_read_bool(np, "ti,enable-low-current-chrg"); + pdata->enable_low_current_chrg = prop; + + pdata->irq_base = -1; + + return pdata; + +} +#else +static struct tps65090_platform_data * + tps65090_parse_dt_charger_data(struct platform_device *pdev) +{ + return NULL; +} +#endif + +static int tps65090_charger_probe(struct platform_device *pdev) +{ + struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); + struct tps65090_charger *cdata; + struct tps65090_platform_data *pdata; + uint8_t status1 = 0; + int ret; + int irq; + + pdata = dev_get_platdata(pdev->dev.parent); + + if (!pdata && tps65090_mfd->dev->of_node) + pdata = tps65090_parse_dt_charger_data(pdev); + + if (!pdata) { + dev_err(&pdev->dev, "%s():no platform data available\n", + __func__); + return -ENODEV; + } + + cdata = devm_kzalloc(&pdev->dev, sizeof(*cdata), GFP_KERNEL); + if (!cdata) { + dev_err(&pdev->dev, "failed to allocate memory status\n"); + return -ENOMEM; + } + + dev_set_drvdata(&pdev->dev, cdata); + + cdata->dev = &pdev->dev; + cdata->pdata = pdata; + + cdata->ac.name = "tps65090-ac"; + cdata->ac.type = POWER_SUPPLY_TYPE_MAINS; + cdata->ac.get_property = tps65090_ac_get_property; + cdata->ac.properties = tps65090_ac_props; + cdata->ac.num_properties = ARRAY_SIZE(tps65090_ac_props); + cdata->ac.supplied_to = pdata->supplied_to; + cdata->ac.num_supplicants = pdata->num_supplicants; + + ret = power_supply_register(&pdev->dev, &cdata->ac); + if (ret) { + dev_err(&pdev->dev, "failed: power supply register\n"); + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_warn(&pdev->dev, "Unable to get charger irq = %d\n", irq); + ret = irq; + goto fail_unregister_supply; + } + + cdata->irq = irq; + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + tps65090_charger_isr, 0, "tps65090-charger", cdata); + if (ret) { + dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq, + ret); + goto fail_free_irq; + } + + ret = tps65090_config_charger(cdata); + if (ret < 0) { + dev_err(&pdev->dev, "charger config failed, err %d\n", ret); + goto fail_free_irq; + } + + /* Check for charger presence */ + ret = tps65090_read(cdata->dev->parent, TPS65090_REG_CG_STATUS1, + &status1); + if (ret < 0) { + dev_err(cdata->dev, "%s(): Error in reading reg 0x%x", __func__, + TPS65090_REG_CG_STATUS1); + goto fail_free_irq; + } + + if (status1 != 0) { + ret = tps65090_enable_charging(cdata, 1); + if (ret < 0) { + dev_err(cdata->dev, "error enabling charger\n"); + goto fail_free_irq; + } + cdata->ac_online = 1; + power_supply_changed(&cdata->ac); + } + + return 0; + +fail_free_irq: + devm_free_irq(cdata->dev, irq, cdata); +fail_unregister_supply: + power_supply_unregister(&cdata->ac); + + return ret; +} + +static int tps65090_charger_remove(struct platform_device *pdev) +{ + struct tps65090_charger *cdata = dev_get_drvdata(&pdev->dev); + + devm_free_irq(cdata->dev, cdata->irq, cdata); + power_supply_unregister(&cdata->ac); + + return 0; +} + +static struct platform_driver tps65090_charger_driver = { + .driver = { + .name = "tps65090-charger", + .owner = THIS_MODULE, + }, + .probe = tps65090_charger_probe, + .remove = tps65090_charger_remove, +}; +module_platform_driver(tps65090_charger_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Syed Rafiuddin "); +MODULE_DESCRIPTION("tps65090 battery charger driver"); diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 6694cf43e8b8..998628a2b08b 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -86,6 +86,11 @@ struct tps65090_regulator_plat_data { struct tps65090_platform_data { int irq_base; + + char **supplied_to; + size_t num_supplicants; + int enable_low_current_chrg; + struct tps65090_regulator_plat_data *reg_pdata[TPS65090_REGULATOR_MAX]; }; -- cgit From 9239ebcffb9301eab75c638dcb702688884cc5d6 Mon Sep 17 00:00:00 2001 From: Andrey Gelman Date: Sun, 27 Jan 2013 22:16:33 +0200 Subject: test_power: Fix a bug in setting module parameter values When the kernel loads a module, module params are processed prior to calling module_init. As a result, setting module param value should not have side effects, at least as long as the module has not been initialized. Signed-off-by: Andrey Gelman Signed-off-by: Anton Vorontsov --- drivers/power/test_power.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/power/test_power.c b/drivers/power/test_power.c index b99a452a4fda..0152f35dca5c 100644 --- a/drivers/power/test_power.c +++ b/drivers/power/test_power.c @@ -30,6 +30,8 @@ static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; static int battery_capacity = 50; static int battery_voltage = 3300; +static bool module_initialized; + static int test_power_get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -185,6 +187,7 @@ static int __init test_power_init(void) } } + module_initialized = true; return 0; failed: while (--i >= 0) @@ -209,6 +212,8 @@ static void __exit test_power_exit(void) for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) power_supply_unregister(&test_power_supplies[i]); + + module_initialized = false; } module_exit(test_power_exit); @@ -221,8 +226,8 @@ struct battery_property_map { }; static struct battery_property_map map_ac_online[] = { - { 0, "on" }, - { 1, "off" }, + { 0, "off" }, + { 1, "on" }, { -1, NULL }, }; @@ -295,10 +300,16 @@ static const char *map_get_key(struct battery_property_map *map, int value, return def_key; } +static inline void signal_power_supply_changed(struct power_supply *psy) +{ + if (module_initialized) + power_supply_changed(psy); +} + static int param_set_ac_online(const char *key, const struct kernel_param *kp) { ac_online = map_get_value(map_ac_online, key, ac_online); - power_supply_changed(&test_power_supplies[0]); + signal_power_supply_changed(&test_power_supplies[0]); return 0; } @@ -311,7 +322,7 @@ static int param_get_ac_online(char *buffer, const struct kernel_param *kp) static int param_set_usb_online(const char *key, const struct kernel_param *kp) { usb_online = map_get_value(map_ac_online, key, usb_online); - power_supply_changed(&test_power_supplies[2]); + signal_power_supply_changed(&test_power_supplies[2]); return 0; } @@ -325,7 +336,7 @@ static int param_set_battery_status(const char *key, const struct kernel_param *kp) { battery_status = map_get_value(map_status, key, battery_status); - power_supply_changed(&test_power_supplies[1]); + signal_power_supply_changed(&test_power_supplies[1]); return 0; } @@ -339,7 +350,7 @@ static int param_set_battery_health(const char *key, const struct kernel_param *kp) { battery_health = map_get_value(map_health, key, battery_health); - power_supply_changed(&test_power_supplies[1]); + signal_power_supply_changed(&test_power_supplies[1]); return 0; } @@ -353,7 +364,7 @@ static int param_set_battery_present(const char *key, const struct kernel_param *kp) { battery_present = map_get_value(map_present, key, battery_present); - power_supply_changed(&test_power_supplies[0]); + signal_power_supply_changed(&test_power_supplies[0]); return 0; } @@ -369,7 +380,7 @@ static int param_set_battery_technology(const char *key, { battery_technology = map_get_value(map_technology, key, battery_technology); - power_supply_changed(&test_power_supplies[1]); + signal_power_supply_changed(&test_power_supplies[1]); return 0; } @@ -390,7 +401,7 @@ static int param_set_battery_capacity(const char *key, return -EINVAL; battery_capacity = tmp; - power_supply_changed(&test_power_supplies[1]); + signal_power_supply_changed(&test_power_supplies[1]); return 0; } @@ -405,7 +416,7 @@ static int param_set_battery_voltage(const char *key, return -EINVAL; battery_voltage = tmp; - power_supply_changed(&test_power_supplies[1]); + signal_power_supply_changed(&test_power_supplies[1]); return 0; } -- cgit From c6cc9fc9d42ec82da2c770f0bef1488dc467f29c Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 04:33:25 +0530 Subject: s3c-adc-battery: Fix possible NULL pointer dereference Check for (bat == NULL) has to be done before accessing bat Signed-off-by: Syam Sidhardhan Signed-off-by: Anton Vorontsov --- drivers/power/s3c_adc_battery.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index d2ca989dcbdc..5948ce058bdd 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c @@ -145,14 +145,17 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, int new_level; int full_volt; - const struct s3c_adc_bat_thresh *lut = bat->pdata->lut_noac; - unsigned int lut_size = bat->pdata->lut_noac_cnt; + const struct s3c_adc_bat_thresh *lut; + unsigned int lut_size; if (!bat) { dev_err(psy->dev, "no battery infos ?!\n"); return -EINVAL; } + lut = bat->pdata->lut_noac; + lut_size = bat->pdata->lut_noac_cnt; + if (bat->volt_value < 0 || bat->cur_value < 0 || jiffies_to_msecs(jiffies - bat->timestamp) > BAT_POLL_INTERVAL) { -- cgit From b64a15930c35c3c1046533aadcfe4f3233e70c20 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 19 Mar 2013 10:14:35 +0200 Subject: usb: phy: samsung: fix sparse warning Fix the following sparse warning: drivers/usb/phy/phy-samsung-usb2.c:50:26: sparse: incorrect type in argument 1 (different address spaces) drivers/usb/phy/phy-samsung-usb2.c:50:26: expected void const volatile [noderef] *addr drivers/usb/phy/phy-samsung-usb2.c:50:26: got void * Cc: Vivek Gautam Cc: Kukjin Kim Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-samsung-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c index dce968151505..45ffe036dacc 100644 --- a/drivers/usb/phy/phy-samsung-usb2.c +++ b/drivers/usb/phy/phy-samsung-usb2.c @@ -43,7 +43,7 @@ static int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } -static bool exynos5_phyhost_is_on(void *regs) +static bool exynos5_phyhost_is_on(void __iomem *regs) { u32 reg; -- cgit From eed456f93d01e9476a1e777d22ae8a8382546ab7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 19 Mar 2013 10:45:04 +0000 Subject: regmap: irq: Clarify error message when we fail to request primary IRQ Display the name for the chip rather than just the primary IRQ so it is clearer what exactly has failed. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 020ea2b9fd2f..1643e889bafc 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -460,7 +460,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, chip->name, d); if (ret != 0) { - dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); + dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n", + irq, chip->name, ret); goto err_domain; } -- cgit From 50861c7effcad107826e49e6077e64b666c2dc3f Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 18 Mar 2013 12:06:40 +0000 Subject: mrf24j40: pinctrl support Activate pinctrl settings when used with a DT system. Signed-off-by: Alan Ott Signed-off-by: David S. Miller --- drivers/net/ieee802154/mrf24j40.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 3f2c7aaf28c4..3106895e8b91 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -623,6 +624,7 @@ static int mrf24j40_probe(struct spi_device *spi) int ret = -ENOMEM; u8 val; struct mrf24j40 *devrec; + struct pinctrl *pinctrl; printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq); @@ -633,6 +635,11 @@ static int mrf24j40_probe(struct spi_device *spi) if (!devrec->buf) goto err_buf; + pinctrl = devm_pinctrl_get_select_default(&spi->dev); + if (IS_ERR(pinctrl)) + dev_warn(&spi->dev, + "pinctrl pins are not configured from the driver"); + spi->mode = SPI_MODE_0; /* TODO: Is this appropriate for right here? */ if (spi->max_speed_hz > MAX_SPI_SPEED_HZ) spi->max_speed_hz = MAX_SPI_SPEED_HZ; -- cgit From 7a1c2318868615a522610c05192dbc9dd423647d Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 18 Mar 2013 12:06:41 +0000 Subject: mrf24j40: Warn if transmit interrupts timeout Issue a warning if a transmit complete interrupt doesn't happen in time. Signed-off-by: Alan Ott Signed-off-by: David S. Miller --- drivers/net/ieee802154/mrf24j40.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 3106895e8b91..582c0a3d5773 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -362,6 +362,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) if (ret == -ERESTARTSYS) goto err; if (ret == 0) { + dev_warn(printdev(devrec), "Timeout waiting for TX interrupt\n"); ret = -ETIMEDOUT; goto err; } -- cgit From cf82dabd29168b19c4ac651a11010ded34785142 Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 18 Mar 2013 12:06:42 +0000 Subject: mrf24j40: Increase max SPI speed to 10MHz Upon consulting the datasheet further, it does indicates a maximum speed for SCK at 10MHz. Signed-off-by: Alan Ott Signed-off-by: David S. Miller --- drivers/net/ieee802154/mrf24j40.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 582c0a3d5773..b4f9b67b0877 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -92,9 +92,8 @@ struct mrf24j40 { #define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5) #define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4) -/* Maximum speed to run the device at. TODO: Get the real max value from - * someone at Microchip since it isn't in the datasheet. */ -#define MAX_SPI_SPEED_HZ 1000000 +/* The datasheet indicates the theoretical maximum for SCK to be 10MHz */ +#define MAX_SPI_SPEED_HZ 10000000 #define printdev(X) (&X->spi->dev) -- cgit From 119c331f166ab1c55ac40c9840d180dac91f0cff Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 18 Mar 2013 12:06:43 +0000 Subject: mrf24j40: Fix byte-order of IEEE address Load the 64-bit Extended (IEEE) address into the hardware in the proper byte order. Signed-off-by: Alan Ott Signed-off-by: David S. Miller --- drivers/net/ieee802154/mrf24j40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index b4f9b67b0877..0ca8f88ac538 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -478,7 +478,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, int i; for (i = 0; i < 8; i++) write_short_reg(devrec, REG_EADR0+i, - filt->ieee_addr[i]); + filt->ieee_addr[7-i]); #ifdef DEBUG printk(KERN_DEBUG "Set long addr to: "); -- cgit From 6fed9592de7bd9c904ab476c3e264a18d1cf3598 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Mar 2013 21:01:38 +0000 Subject: net/smsc911x: Use NULL instead of integer for pointer Silences the following sparse warning: drivers/net/ethernet/smsc/smsc911x.c:2145:30: warning: Using plain integer as NULL pointer Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index da5cc9a3b34c..48e2b99bec51 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2115,7 +2115,7 @@ static int smsc911x_init(struct net_device *dev) spin_lock_init(&pdata->dev_lock); spin_lock_init(&pdata->mac_lock); - if (pdata->ioaddr == 0) { + if (pdata->ioaddr == NULL) { SMSC_WARN(pdata, probe, "pdata->ioaddr: 0x00000000"); return -ENODEV; } -- cgit From 0aacd23ff29a846c7eebbd9db8752fa360f34ad1 Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Mon, 11 Mar 2013 14:44:11 -0600 Subject: mmc: tegra: use mmc_of_parse to get the support of standard MMC DT bindings Updating the sdhci-tegra driver to use mmc_of_parse to support standard MMC DT bindings. Then we can remove the redundant code that already support in generic MMC core. Signed-off-by: Joseph Lo Tested-by: Thierry Reding Signed-off-by: Stephen Warren Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-tegra.c | 92 +++++------------------------------------- 1 file changed, 10 insertions(+), 82 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index ff99b632808d..c665d1d26320 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -44,10 +45,7 @@ struct sdhci_tegra_soc_data { struct sdhci_tegra { const struct sdhci_tegra_soc_data *soc_data; - int cd_gpio; - int wp_gpio; int power_gpio; - int is_8bit; }; static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) @@ -107,23 +105,9 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg) static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host) { - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_tegra *tegra_host = pltfm_host->priv; - - if (!gpio_is_valid(tegra_host->wp_gpio)) - return -1; - - return gpio_get_value(tegra_host->wp_gpio); + return mmc_gpio_get_ro(host->mmc); } -static irqreturn_t carddetect_irq(int irq, void *data) -{ - struct sdhci_host *sdhost = (struct sdhci_host *)data; - - tasklet_schedule(&sdhost->card_tasklet); - return IRQ_HANDLED; -}; - static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -145,12 +129,11 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width) { - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_tegra *tegra_host = pltfm_host->priv; u32 ctrl; ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - if (tegra_host->is_8bit && bus_width == MMC_BUS_WIDTH_8) { + if ((host->mmc->caps & MMC_CAP_8_BIT_DATA) && + (bus_width == MMC_BUS_WIDTH_8)) { ctrl &= ~SDHCI_CTRL_4BITBUS; ctrl |= SDHCI_CTRL_8BITBUS; } else { @@ -222,19 +205,15 @@ static const struct of_device_id sdhci_tegra_dt_match[] = { }; MODULE_DEVICE_TABLE(of, sdhci_dt_ids); -static void sdhci_tegra_parse_dt(struct device *dev, - struct sdhci_tegra *tegra_host) +static void sdhci_tegra_parse_dt(struct device *dev) { struct device_node *np = dev->of_node; - u32 bus_width; + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_tegra *tegra_host = pltfm_host->priv; - tegra_host->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); - tegra_host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0); - - if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && - bus_width == 8) - tegra_host->is_8bit = 1; + mmc_of_parse(host->mmc); } static int sdhci_tegra_probe(struct platform_device *pdev) @@ -266,7 +245,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev) tegra_host->soc_data = soc_data; pltfm_host->priv = tegra_host; - sdhci_tegra_parse_dt(&pdev->dev, tegra_host); + sdhci_tegra_parse_dt(&pdev->dev); if (gpio_is_valid(tegra_host->power_gpio)) { rc = gpio_request(tegra_host->power_gpio, "sdhci_power"); @@ -278,37 +257,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev) gpio_direction_output(tegra_host->power_gpio, 1); } - if (gpio_is_valid(tegra_host->cd_gpio)) { - rc = gpio_request(tegra_host->cd_gpio, "sdhci_cd"); - if (rc) { - dev_err(mmc_dev(host->mmc), - "failed to allocate cd gpio\n"); - goto err_cd_req; - } - gpio_direction_input(tegra_host->cd_gpio); - - rc = request_irq(gpio_to_irq(tegra_host->cd_gpio), - carddetect_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - mmc_hostname(host->mmc), host); - - if (rc) { - dev_err(mmc_dev(host->mmc), "request irq error\n"); - goto err_cd_irq_req; - } - - } - - if (gpio_is_valid(tegra_host->wp_gpio)) { - rc = gpio_request(tegra_host->wp_gpio, "sdhci_wp"); - if (rc) { - dev_err(mmc_dev(host->mmc), - "failed to allocate wp gpio\n"); - goto err_wp_req; - } - gpio_direction_input(tegra_host->wp_gpio); - } - clk = clk_get(mmc_dev(host->mmc), NULL); if (IS_ERR(clk)) { dev_err(mmc_dev(host->mmc), "clk err\n"); @@ -318,9 +266,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev) clk_prepare_enable(clk); pltfm_host->clk = clk; - if (tegra_host->is_8bit) - host->mmc->caps |= MMC_CAP_8_BIT_DATA; - rc = sdhci_add_host(host); if (rc) goto err_add_host; @@ -331,15 +276,6 @@ err_add_host: clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); err_clk_get: - if (gpio_is_valid(tegra_host->wp_gpio)) - gpio_free(tegra_host->wp_gpio); -err_wp_req: - if (gpio_is_valid(tegra_host->cd_gpio)) - free_irq(gpio_to_irq(tegra_host->cd_gpio), host); -err_cd_irq_req: - if (gpio_is_valid(tegra_host->cd_gpio)) - gpio_free(tegra_host->cd_gpio); -err_cd_req: if (gpio_is_valid(tegra_host->power_gpio)) gpio_free(tegra_host->power_gpio); err_power_req: @@ -357,14 +293,6 @@ static int sdhci_tegra_remove(struct platform_device *pdev) sdhci_remove_host(host, dead); - if (gpio_is_valid(tegra_host->wp_gpio)) - gpio_free(tegra_host->wp_gpio); - - if (gpio_is_valid(tegra_host->cd_gpio)) { - free_irq(gpio_to_irq(tegra_host->cd_gpio), host); - gpio_free(tegra_host->cd_gpio); - } - if (gpio_is_valid(tegra_host->power_gpio)) gpio_free(tegra_host->power_gpio); -- cgit From 401f6a2729988c7229c3a78bba0d2f73851e3f51 Mon Sep 17 00:00:00 2001 From: John Sheu Date: Wed, 6 Feb 2013 20:03:01 -0300 Subject: [media] v4l2-mem2mem: drop rdy_queue on STREAMOFF When a v4l2-mem2mem context gets a STREAMOFF call on either its CAPTURE or OUTPUT queues, we should: * Drop the corresponding rdy_queue, since a subsequent STREAMON expects an empty queue. * Deschedule the context, as it now has at least one empty queue and cannot run. Signed-off-by: John Sheu Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 27ddb3d15251..66f599fcb829 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -408,10 +408,35 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamon); int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) { - struct vb2_queue *vq; + struct v4l2_m2m_dev *m2m_dev; + struct v4l2_m2m_queue_ctx *q_ctx; + unsigned long flags_job, flags; + int ret; - vq = v4l2_m2m_get_vq(m2m_ctx, type); - return vb2_streamoff(vq, type); + q_ctx = get_queue_ctx(m2m_ctx, type); + ret = vb2_streamoff(&q_ctx->q, type); + if (ret) + return ret; + + m2m_dev = m2m_ctx->m2m_dev; + spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); + /* We should not be scheduled anymore, since we're dropping a queue. */ + INIT_LIST_HEAD(&m2m_ctx->queue); + m2m_ctx->job_flags = 0; + + spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); + /* Drop queue, since streamoff returns device to the same state as after + * calling reqbufs. */ + INIT_LIST_HEAD(&q_ctx->rdy_queue); + spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags); + + if (m2m_dev->curr_ctx == m2m_ctx) { + m2m_dev->curr_ctx = NULL; + wake_up(&m2m_ctx->finished); + } + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); + + return 0; } EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); -- cgit From 4159d01bea38ee82f6e49383b7e73e328c118755 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 28 Feb 2013 10:35:56 -0300 Subject: [media] em28xx: Add ISDB support for c3tech Digital duo This is an hybrid board. However, for analog, it requires a new driver for saa7136. So, for now, let's just add support for Digital TV. Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/usb/em28xx/Kconfig | 1 + drivers/media/usb/em28xx/em28xx-cards.c | 24 ++++++++++++++++++++++++ drivers/media/usb/em28xx/em28xx-dvb.c | 26 ++++++++++++++++++++++++++ drivers/media/usb/em28xx/em28xx.h | 1 + 5 files changed, 53 insertions(+) (limited to 'drivers') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 3f12865b2a88..c59181431df5 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -85,3 +85,4 @@ 85 -> PCTV QuatroStick (510e) (em2884) [2304:0242] 86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251] 87 -> Terratec Cinergy HTC USB XS (em2884) [0ccd:008e,0ccd:00ac] + 88 -> C3 Tech Digital Duo HDTV/SDTV USB (em2884) [1b80:e755] diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index c754a80a8d8b..ca5ee6aceb62 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig @@ -46,6 +46,7 @@ config VIDEO_EM28XX_DVB select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT + select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT ---help--- diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 6e62b72376b0..46fff5c3335b 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -345,6 +345,18 @@ static struct em28xx_reg_seq pctv_460e[] = { { -1, -1, -1, -1}, }; +static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { + {EM2874_R80_GPIO, 0xff, 0xff, 10}, + {EM2874_R80_GPIO, 0xfd, 0xff, 10}, /* xc5000 reset */ + {EM2874_R80_GPIO, 0xf9, 0xff, 35}, + {EM2874_R80_GPIO, 0xfd, 0xff, 10}, + {EM2874_R80_GPIO, 0xff, 0xff, 10}, + {EM2874_R80_GPIO, 0xfe, 0xff, 10}, + {EM2874_R80_GPIO, 0xbe, 0xff, 10}, + {EM2874_R80_GPIO, 0xfe, 0xff, 20}, + { -1, -1, -1, -1}, +}; + #if 0 static struct em28xx_reg_seq hauppauge_930c_gpio[] = { {EM2874_R80_GPIO, 0x6f, 0xff, 10}, @@ -978,6 +990,16 @@ struct em28xx_board em28xx_boards[] = { .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, + [EM2884_BOARD_C3TECH_DIGITAL_DUO] = { + .name = "C3 Tech Digital Duo HDTV/SDTV USB", + .has_dvb = 1, + /* FIXME: Add analog support - need a saa7136 driver */ + .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ + .ir_codes = RC_MAP_EMPTY, + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, + .dvb_gpio = c3tech_digital_duo_digital, + }, [EM2884_BOARD_CINERGY_HTC_STICK] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, @@ -2144,6 +2166,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28174_BOARD_PCTV_460E }, { USB_DEVICE(0x2040, 0x1605), .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, + { USB_DEVICE(0x1b80, 0xe755), + .driver_info = EM2884_BOARD_C3TECH_DIGITAL_DUO }, { USB_DEVICE(0xeb1a, 0x5006), .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 }, { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */ diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 98b95be3be6e..42a6a2696224 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -50,6 +50,7 @@ #include "tda10071.h" #include "a8293.h" #include "qt1010.h" +#include "mb86a20s.h" MODULE_DESCRIPTION("driver for em28xx based DVB cards"); MODULE_AUTHOR("Mauro Carvalho Chehab "); @@ -766,9 +767,25 @@ static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = { }; static struct qt1010_config em28xx_qt1010_config = { .i2c_address = 0x62 +}; + +static const struct mb86a20s_config c3tech_duo_mb86a20s_config = { + .demod_address = 0x10, + .is_serial = true, +}; + +static struct tda18271_std_map mb86a20s_tda18271_config = { + .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4, + .if_lvl = 1, .rfagc_top = 0x37, }, +}; +static struct tda18271_config c3tech_duo_tda18271_config = { + .std_map = &mb86a20s_tda18271_config, + .gate = TDA18271_GATE_DIGITAL, + .small_i2c = TDA18271_03_BYTE_CHUNK_INIT, }; + /* ------------------------------------------------------------------ */ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) @@ -1177,6 +1194,15 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); break; + case EM2884_BOARD_C3TECH_DIGITAL_DUO: + dvb->fe[0] = dvb_attach(mb86a20s_attach, + &c3tech_duo_mb86a20s_config, + &dev->i2c_adap[dev->def_i2c_bus]); + if (dvb->fe[0] != NULL) + dvb_attach(tda18271_attach, dvb->fe[0], 0x60, + &dev->i2c_adap[dev->def_i2c_bus], + &c3tech_duo_tda18271_config); + break; case EM28174_BOARD_PCTV_460E: /* attach demod */ dvb->fe[0] = dvb_attach(tda10071_attach, diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index f6ac1df83816..4c667fd1661d 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -129,6 +129,7 @@ #define EM2884_BOARD_PCTV_510E 85 #define EM2884_BOARD_PCTV_520E 86 #define EM2884_BOARD_TERRATEC_HTC_USB_XS 87 +#define EM2884_BOARD_C3TECH_DIGITAL_DUO 88 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit From 801b69f2570e2556c6d5a060df85ce9bd0d38119 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 16 Feb 2013 17:25:43 -0300 Subject: [media] redrat3: limit periods to hardware limits The redrat hardware cannot handle periods of larger than 32767us, limit appropriately. Also fix memory leak in redrat3_get_timeout. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 53 +++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 1b37fe2779f8..842bdcded27c 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -209,9 +209,6 @@ struct redrat3_dev { u16 pktlen; u16 pkttype; u16 bytes_read; - /* indicate whether we are going to reprocess - * the USB callback with a bigger buffer */ - int buftoosmall; char *datap; u32 carrier; @@ -396,7 +393,6 @@ static u32 redrat3_us_to_len(u32 microsec) /* don't allow zero lengths to go back, breaks lirc */ return result ? result : 1; - } /* timer callback to send reset event */ @@ -515,8 +511,6 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) rr3_dbg(dev, "calling ir_raw_event_handle\n"); ir_raw_event_handle(rr3->rc); - - return; } /* Util fn to send rr3 cmds */ @@ -613,7 +607,7 @@ static inline void redrat3_delete(struct redrat3_dev *rr3, static u32 redrat3_get_timeout(struct redrat3_dev *rr3) { - u32 *tmp; + __be32 *tmp; u32 timeout = MS_TO_US(150); /* a sane default, if things go haywire */ int len, ret, pipe; @@ -628,14 +622,16 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3) ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); - if (ret != len) { + if (ret != len) dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); - return timeout; + else { + timeout = redrat3_len_to_us(be32_to_cpup(tmp)); + + rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000); } - timeout = redrat3_len_to_us(be32_to_cpu(*tmp)); + kfree(tmp); - rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000); return timeout; } @@ -755,7 +751,6 @@ static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len) static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) { - rr3_ftr(rr3->dev, "Entering %s\n", __func__); memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len); @@ -815,7 +810,7 @@ out: } /* callback function from USB when async USB request has completed */ -static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) +static void redrat3_handle_async(struct urb *urb) { struct redrat3_dev *rr3; int ret; @@ -857,7 +852,7 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) } } -static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +static void redrat3_write_bulk_callback(struct urb *urb) { struct redrat3_dev *rr3; int len; @@ -901,7 +896,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; struct redrat3_signal_header header; - int i, j, ret, ret_len, offset; + int i, ret, ret_len, offset; int lencheck, cur_sample_len, pipe; char *buffer = NULL, *sigdata = NULL; int *sample_lens = NULL; @@ -931,8 +926,19 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, goto out; } + sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); + if (!sigdata) { + ret = -ENOMEM; + goto out; + } + for (i = 0; i < count; i++) { cur_sample_len = redrat3_us_to_len(txbuf[i]); + if (cur_sample_len > 0xffff) { + dev_warn(dev, "transmit period of %uus truncated to %uus\n", + txbuf[i], redrat3_len_to_us(0xffff)); + cur_sample_len = 0xffff; + } for (lencheck = 0; lencheck < curlencheck; lencheck++) { if (sample_lens[lencheck] == cur_sample_len) break; @@ -950,22 +956,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, break; } } - } - - sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); - if (!sigdata) { - ret = -ENOMEM; - goto out; + sigdata[i] = lencheck; } sigdata[count] = RR3_END_OF_SIGNAL; sigdata[count + 1] = RR3_END_OF_SIGNAL; - for (i = 0; i < count; i++) { - for (j = 0; j < curlencheck; j++) { - if (sample_lens[j] == redrat3_us_to_len(txbuf[i])) - sigdata[i] = j; - } - } offset = RR3_TX_HEADER_OFFSET; sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS) @@ -1175,7 +1170,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, ep_in->wMaxPacketSize, - (usb_complete_t)redrat3_handle_async, rr3); + redrat3_handle_async, rr3); /* set up bulk-out endpoint*/ rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL); @@ -1195,7 +1190,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress); usb_fill_bulk_urb(rr3->write_urb, udev, pipe, rr3->bulk_out_buf, ep_out->wMaxPacketSize, - (usb_complete_t)redrat3_write_bulk_callback, rr3); + redrat3_write_bulk_callback, rr3); rr3->udev = udev; -- cgit From 4c055a5ae94c76b1139d6e071812d39eed3b67cd Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 16 Feb 2013 17:25:44 -0300 Subject: [media] redrat3: remove memcpys and fix unaligned memory access In stead of doing a memcpy from #defined offset, declare structs which describe the incoming and outgoing data accurately. Tested on first generation RedRat. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 351 +++++++++++++-------------------------------- 1 file changed, 103 insertions(+), 248 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 842bdcded27c..ec655b8ef4d3 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -45,6 +45,7 @@ * */ +#include #include #include #include @@ -129,25 +130,11 @@ static int debug; /* USB bulk-in IR data endpoint address */ #define RR3_BULK_IN_EP_ADDR 0x82 -/* Raw Modulated signal data value offsets */ -#define RR3_PAUSE_OFFSET 0 -#define RR3_FREQ_COUNT_OFFSET 4 -#define RR3_NUM_PERIOD_OFFSET 6 -#define RR3_MAX_LENGTHS_OFFSET 8 -#define RR3_NUM_LENGTHS_OFFSET 9 -#define RR3_MAX_SIGS_OFFSET 10 -#define RR3_NUM_SIGS_OFFSET 12 -#define RR3_REPEATS_OFFSET 14 - /* Size of the fixed-length portion of the signal */ -#define RR3_HEADER_LENGTH 15 #define RR3_DRIVER_MAXLENS 128 #define RR3_MAX_SIG_SIZE 512 -#define RR3_MAX_BUF_SIZE \ - ((2 * RR3_HEADER_LENGTH) + RR3_DRIVER_MAXLENS + RR3_MAX_SIG_SIZE) #define RR3_TIME_UNIT 50 #define RR3_END_OF_SIGNAL 0x7f -#define RR3_TX_HEADER_OFFSET 4 #define RR3_TX_TRAILER_LEN 2 #define RR3_RX_MIN_TIMEOUT 5 #define RR3_RX_MAX_TIMEOUT 2000 @@ -159,6 +146,32 @@ static int debug; #define USB_RR3USB_PRODUCT_ID 0x0001 #define USB_RR3IIUSB_PRODUCT_ID 0x0005 +struct redrat3_header { + __be16 length; + __be16 transfer_type; +} __packed; + +/* sending and receiving irdata */ +struct redrat3_irdata { + struct redrat3_header header; + __be32 pause; + __be16 mod_freq_count; + __be16 num_periods; + __u8 max_lengths; + __u8 no_lengths; + __be16 max_sig_size; + __be16 sig_size; + __u8 no_repeats; + __be16 lens[RR3_DRIVER_MAXLENS]; /* not aligned */ + __u8 sigdata[RR3_MAX_SIG_SIZE]; +} __packed; + +/* firmware errors */ +struct redrat3_error { + struct redrat3_header header; + __be16 fw_error; +} __packed; + /* table of devices that work with this driver */ static struct usb_device_id redrat3_dev_table[] = { /* Original version of the RedRat3 */ @@ -180,7 +193,7 @@ struct redrat3_dev { /* the receive endpoint */ struct usb_endpoint_descriptor *ep_in; /* the buffer to receive data */ - unsigned char *bulk_in_buf; + void *bulk_in_buf; /* urb used to read ir data */ struct urb *read_urb; @@ -205,69 +218,15 @@ struct redrat3_dev { bool transmitting; /* store for current packet */ - char pbuf[RR3_MAX_BUF_SIZE]; - u16 pktlen; - u16 pkttype; + struct redrat3_irdata irdata; u16 bytes_read; - char *datap; u32 carrier; - char name[128]; + char name[64]; char phys[64]; }; -/* All incoming data buffers adhere to a very specific data format */ -struct redrat3_signal_header { - u16 length; /* Length of data being transferred */ - u16 transfer_type; /* Type of data transferred */ - u32 pause; /* Pause between main and repeat signals */ - u16 mod_freq_count; /* Value of timer on mod. freq. measurement */ - u16 no_periods; /* No. of periods over which mod. freq. is measured */ - u8 max_lengths; /* Max no. of lengths (i.e. size of array) */ - u8 no_lengths; /* Actual no. of elements in lengths array */ - u16 max_sig_size; /* Max no. of values in signal data array */ - u16 sig_size; /* Acuto no. of values in signal data array */ - u8 no_repeats; /* No. of repeats of repeat signal section */ - /* Here forward is the lengths and signal data */ -}; - -static void redrat3_dump_signal_header(struct redrat3_signal_header *header) -{ - pr_info("%s:\n", __func__); - pr_info(" * length: %u, transfer_type: 0x%02x\n", - header->length, header->transfer_type); - pr_info(" * pause: %u, freq_count: %u, no_periods: %u\n", - header->pause, header->mod_freq_count, header->no_periods); - pr_info(" * lengths: %u (max: %u)\n", - header->no_lengths, header->max_lengths); - pr_info(" * sig_size: %u (max: %u)\n", - header->sig_size, header->max_sig_size); - pr_info(" * repeats: %u\n", header->no_repeats); -} - -static void redrat3_dump_signal_data(char *buffer, u16 len) -{ - int offset, i; - char *data_vals; - - pr_info("%s:", __func__); - - offset = RR3_TX_HEADER_OFFSET + RR3_HEADER_LENGTH - + (RR3_DRIVER_MAXLENS * sizeof(u16)); - - /* read RR3_DRIVER_MAXLENS from ctrl msg */ - data_vals = buffer + offset; - - for (i = 0; i < len; i++) { - if (i % 10 == 0) - pr_cont("\n * "); - pr_cont("%02x ", *data_vals++); - } - - pr_cont("\n"); -} - /* * redrat3_issue_async * @@ -349,13 +308,14 @@ static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code) } } -static u32 redrat3_val_to_mod_freq(struct redrat3_signal_header *ph) +static u32 redrat3_val_to_mod_freq(struct redrat3_irdata *irdata) { u32 mod_freq = 0; + u16 mod_freq_count = be16_to_cpu(irdata->mod_freq_count); - if (ph->mod_freq_count != 0) - mod_freq = (RR3_CLK * ph->no_periods) / - (ph->mod_freq_count * RR3_CLK_PER_COUNT); + if (mod_freq_count != 0) + mod_freq = (RR3_CLK * be16_to_cpu(irdata->num_periods)) / + (mod_freq_count * RR3_CLK_PER_COUNT); return mod_freq; } @@ -407,16 +367,11 @@ static void redrat3_rx_timeout(unsigned long data) static void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); - struct redrat3_signal_header header; struct device *dev; int i, trailer = 0; + unsigned sig_size, single_len, offset, val; unsigned long delay; - u32 mod_freq, single_len; - u16 *len_vals; - u8 *data_vals; - u32 tmp32; - u16 tmp16; - char *sig_data; + u32 mod_freq; if (!rr3) { pr_err("%s called with no context!\n", __func__); @@ -426,57 +381,20 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) rr3_ftr(rr3->dev, "Entered %s\n", __func__); dev = rr3->dev; - sig_data = rr3->pbuf; - - header.length = rr3->pktlen; - header.transfer_type = rr3->pkttype; - - /* Sanity check */ - if (!(header.length >= RR3_HEADER_LENGTH)) - dev_warn(dev, "read returned less than rr3 header len\n"); /* Make sure we reset the IR kfifo after a bit of inactivity */ delay = usecs_to_jiffies(rr3->hw_timeout); mod_timer(&rr3->rx_timeout, jiffies + delay); - memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32)); - header.pause = be32_to_cpu(tmp32); - - memcpy(&tmp16, sig_data + RR3_FREQ_COUNT_OFFSET, sizeof(tmp16)); - header.mod_freq_count = be16_to_cpu(tmp16); - - memcpy(&tmp16, sig_data + RR3_NUM_PERIOD_OFFSET, sizeof(tmp16)); - header.no_periods = be16_to_cpu(tmp16); - - header.max_lengths = sig_data[RR3_MAX_LENGTHS_OFFSET]; - header.no_lengths = sig_data[RR3_NUM_LENGTHS_OFFSET]; - - memcpy(&tmp16, sig_data + RR3_MAX_SIGS_OFFSET, sizeof(tmp16)); - header.max_sig_size = be16_to_cpu(tmp16); - - memcpy(&tmp16, sig_data + RR3_NUM_SIGS_OFFSET, sizeof(tmp16)); - header.sig_size = be16_to_cpu(tmp16); - - header.no_repeats= sig_data[RR3_REPEATS_OFFSET]; - - if (debug) { - redrat3_dump_signal_header(&header); - redrat3_dump_signal_data(sig_data, header.sig_size); - } - - mod_freq = redrat3_val_to_mod_freq(&header); + mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); rr3_dbg(dev, "Got mod_freq of %u\n", mod_freq); - /* Here we pull out the 'length' values from the signal */ - len_vals = (u16 *)(sig_data + RR3_HEADER_LENGTH); - - data_vals = sig_data + RR3_HEADER_LENGTH + - (header.max_lengths * sizeof(u16)); - /* process each rr3 encoded byte into an int */ - for (i = 0; i < header.sig_size; i++) { - u16 val = len_vals[data_vals[i]]; - single_len = redrat3_len_to_us((u32)be16_to_cpu(val)); + sig_size = be16_to_cpu(rr3->irdata.sig_size); + for (i = 0; i < sig_size; i++) { + offset = rr3->irdata.sigdata[i]; + val = get_unaligned_be16(&rr3->irdata.lens[offset]); + single_len = redrat3_len_to_us(val); /* we should always get pulse/space/pulse/space samples */ if (i % 2) @@ -534,7 +452,7 @@ static u8 redrat3_send_cmd(int cmd, struct redrat3_dev *rr3) __func__, res, *data); res = -EIO; } else - res = (u8)data[0]; + res = data[0]; kfree(data); @@ -704,79 +622,72 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len) { - u16 tx_error; - u16 hdrlen; + struct redrat3_header *header = rr3->bulk_in_buf; + unsigned pktlen, pkttype; rr3_ftr(rr3->dev, "Entering %s\n", __func__); /* grab the Length and type of transfer */ - memcpy(&(rr3->pktlen), (unsigned char *) rr3->bulk_in_buf, - sizeof(rr3->pktlen)); - memcpy(&(rr3->pkttype), ((unsigned char *) rr3->bulk_in_buf + - sizeof(rr3->pktlen)), - sizeof(rr3->pkttype)); + pktlen = be16_to_cpu(header->length); + pkttype = be16_to_cpu(header->transfer_type); - /*data needs conversion to know what its real values are*/ - rr3->pktlen = be16_to_cpu(rr3->pktlen); - rr3->pkttype = be16_to_cpu(rr3->pkttype); + if (pktlen > sizeof(rr3->irdata)) { + dev_warn(rr3->dev, "packet length %u too large\n", pktlen); + return; + } - switch (rr3->pkttype) { + switch (pkttype) { case RR3_ERROR: - memcpy(&tx_error, ((unsigned char *)rr3->bulk_in_buf - + (sizeof(rr3->pktlen) + sizeof(rr3->pkttype))), - sizeof(tx_error)); - tx_error = be16_to_cpu(tx_error); - redrat3_dump_fw_error(rr3, tx_error); + if (len >= sizeof(struct redrat3_error)) { + struct redrat3_error *error = rr3->bulk_in_buf; + unsigned fw_error = be16_to_cpu(error->fw_error); + redrat3_dump_fw_error(rr3, fw_error); + } break; case RR3_MOD_SIGNAL_IN: - hdrlen = sizeof(rr3->pktlen) + sizeof(rr3->pkttype); + memcpy(&rr3->irdata, rr3->bulk_in_buf, len); rr3->bytes_read = len; - rr3->bytes_read -= hdrlen; - rr3->datap = &(rr3->pbuf[0]); - - memcpy(rr3->datap, ((unsigned char *)rr3->bulk_in_buf + hdrlen), - rr3->bytes_read); - rr3->datap += rr3->bytes_read; rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n", - rr3->bytes_read, rr3->pktlen); + rr3->bytes_read, pktlen); break; default: - rr3_dbg(rr3->dev, "ignoring packet with type 0x%02x, " - "len of %d, 0x%02x\n", rr3->pkttype, len, rr3->pktlen); + rr3_dbg(rr3->dev, "ignoring packet with type 0x%02x, len of %d, 0x%02x\n", + pkttype, len, pktlen); break; } } static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) { + void *irdata = &rr3->irdata; + rr3_ftr(rr3->dev, "Entering %s\n", __func__); - memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len); - rr3->datap += len; + if (len + rr3->bytes_read > sizeof(rr3->irdata)) { + dev_warn(rr3->dev, "too much data for packet\n"); + rr3->bytes_read = 0; + return; + } + + memcpy(irdata + rr3->bytes_read, rr3->bulk_in_buf, len); rr3->bytes_read += len; - rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n", - rr3->bytes_read, rr3->pktlen); + rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n", rr3->bytes_read, + be16_to_cpu(rr3->irdata.header.length)); } /* gather IR data from incoming urb, process it when we have enough */ static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len) { struct device *dev = rr3->dev; + unsigned pkttype; int ret = 0; rr3_ftr(dev, "Entering %s\n", __func__); - if (rr3->pktlen > RR3_MAX_BUF_SIZE) { - dev_err(rr3->dev, "error: packet larger than buffer\n"); - ret = -EINVAL; - goto out; - } - - if ((rr3->bytes_read == 0) && - (len >= (sizeof(rr3->pkttype) + sizeof(rr3->pktlen)))) { + if (rr3->bytes_read == 0 && len >= sizeof(struct redrat3_header)) { redrat3_read_packet_start(rr3, len); } else if (rr3->bytes_read != 0) { redrat3_read_packet_continue(rr3, len); @@ -786,26 +697,20 @@ static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len) goto out; } - if (rr3->bytes_read > rr3->pktlen) { - dev_err(dev, "bytes_read (%d) greater than pktlen (%d)\n", - rr3->bytes_read, rr3->pktlen); - ret = -EINVAL; - goto out; - } else if (rr3->bytes_read < rr3->pktlen) + if (rr3->bytes_read < be16_to_cpu(rr3->irdata.header.length)) /* we're still accumulating data */ return 0; /* if we get here, we've got IR data to decode */ - if (rr3->pkttype == RR3_MOD_SIGNAL_IN) + pkttype = be16_to_cpu(rr3->irdata.header.transfer_type); + if (pkttype == RR3_MOD_SIGNAL_IN) redrat3_process_ir_data(rr3); else - rr3_dbg(dev, "discarding non-signal data packet " - "(type 0x%02x)\n", rr3->pkttype); + rr3_dbg(dev, "discarding non-signal data packet (type 0x%02x)\n", + pkttype); out: rr3->bytes_read = 0; - rr3->pktlen = 0; - rr3->pkttype = 0; return ret; } @@ -846,8 +751,6 @@ static void redrat3_handle_async(struct urb *urb) default: dev_warn(rr3->dev, "Error: urb status = %d\n", urb->status); rr3->bytes_read = 0; - rr3->pktlen = 0; - rr3->pkttype = 0; break; } } @@ -873,7 +776,7 @@ static u16 mod_freq_to_val(unsigned int mod_freq) int mult = 6000000; /* Clk used in mod. freq. generation is CLK24/4. */ - return (u16)(65536 - (mult / mod_freq)); + return 65536 - (mult / mod_freq); } static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier) @@ -895,16 +798,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, { struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; - struct redrat3_signal_header header; - int i, ret, ret_len, offset; + struct redrat3_irdata *irdata = NULL; + int i, ret, ret_len; int lencheck, cur_sample_len, pipe; - char *buffer = NULL, *sigdata = NULL; int *sample_lens = NULL; - u32 tmpi; - u16 tmps; - u8 *datap; u8 curlencheck = 0; - u16 *lengths_ptr; int sendbuf_len; rr3_ftr(dev, "Entering %s\n", __func__); @@ -926,8 +824,8 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, goto out; } - sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); - if (!sigdata) { + irdata = kzalloc(sizeof(*irdata), GFP_KERNEL); + if (!irdata) { ret = -ENOMEM; goto out; } @@ -950,83 +848,41 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, /* now convert the value to a proper * rr3 value.. */ sample_lens[curlencheck] = cur_sample_len; + put_unaligned_be16(cur_sample_len, + &irdata->lens[curlencheck]); curlencheck++; } else { count = i - 1; break; } } - sigdata[i] = lencheck; + irdata->sigdata[i] = lencheck; } - sigdata[count] = RR3_END_OF_SIGNAL; - sigdata[count + 1] = RR3_END_OF_SIGNAL; - - offset = RR3_TX_HEADER_OFFSET; - sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS) - + count + RR3_TX_TRAILER_LEN + offset; - - buffer = kzalloc(sendbuf_len, GFP_KERNEL); - if (!buffer) { - ret = -ENOMEM; - goto out; - } + irdata->sigdata[count] = RR3_END_OF_SIGNAL; + irdata->sigdata[count + 1] = RR3_END_OF_SIGNAL; + sendbuf_len = offsetof(struct redrat3_irdata, + sigdata[count + RR3_TX_TRAILER_LEN]); /* fill in our packet header */ - header.length = sendbuf_len - offset; - header.transfer_type = RR3_MOD_SIGNAL_OUT; - header.pause = redrat3_len_to_us(100); - header.mod_freq_count = mod_freq_to_val(rr3->carrier); - header.no_periods = 0; /* n/a to transmit */ - header.max_lengths = RR3_DRIVER_MAXLENS; - header.no_lengths = curlencheck; - header.max_sig_size = RR3_MAX_SIG_SIZE; - header.sig_size = count + RR3_TX_TRAILER_LEN; - /* we currently rely on repeat handling in the IR encoding source */ - header.no_repeats = 0; - - tmps = cpu_to_be16(header.length); - memcpy(buffer, &tmps, 2); - - tmps = cpu_to_be16(header.transfer_type); - memcpy(buffer + 2, &tmps, 2); - - tmpi = cpu_to_be32(header.pause); - memcpy(buffer + offset, &tmpi, sizeof(tmpi)); - - tmps = cpu_to_be16(header.mod_freq_count); - memcpy(buffer + offset + RR3_FREQ_COUNT_OFFSET, &tmps, 2); - - buffer[offset + RR3_NUM_LENGTHS_OFFSET] = header.no_lengths; - - tmps = cpu_to_be16(header.sig_size); - memcpy(buffer + offset + RR3_NUM_SIGS_OFFSET, &tmps, 2); - - buffer[offset + RR3_REPEATS_OFFSET] = header.no_repeats; - - lengths_ptr = (u16 *)(buffer + offset + RR3_HEADER_LENGTH); - for (i = 0; i < curlencheck; ++i) - lengths_ptr[i] = cpu_to_be16(sample_lens[i]); - - datap = (u8 *)(buffer + offset + RR3_HEADER_LENGTH + - (sizeof(u16) * RR3_DRIVER_MAXLENS)); - memcpy(datap, sigdata, (count + RR3_TX_TRAILER_LEN)); - - if (debug) { - redrat3_dump_signal_header(&header); - redrat3_dump_signal_data(buffer, header.sig_size); - } + irdata->header.length = cpu_to_be16(sendbuf_len - + sizeof(struct redrat3_header)); + irdata->header.transfer_type = cpu_to_be16(RR3_MOD_SIGNAL_OUT); + irdata->pause = cpu_to_be32(redrat3_len_to_us(100)); + irdata->mod_freq_count = cpu_to_be16(mod_freq_to_val(rr3->carrier)); + irdata->no_lengths = curlencheck; + irdata->sig_size = cpu_to_be16(count + RR3_TX_TRAILER_LEN); pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); - tmps = usb_bulk_msg(rr3->udev, pipe, buffer, + ret = usb_bulk_msg(rr3->udev, pipe, irdata, sendbuf_len, &ret_len, 10 * HZ); - rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, tmps); + rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret); /* now tell the hardware to transmit what we sent it */ pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, 0, buffer, 2, HZ * 10); + 0, 0, irdata, 2, HZ * 10); if (ret < 0) dev_err(dev, "Error: control msg send failed, rc %d\n", ret); @@ -1035,8 +891,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, out: kfree(sample_lens); - kfree(buffer); - kfree(sigdata); + kfree(irdata); rr3->transmitting = false; /* rr3 re-enables rc detector because it was enabled before */ -- cgit From fa7b9ac2e25e149fa9972fced79196c0c971a218 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 16 Feb 2013 17:25:45 -0300 Subject: [media] redrat3: missing endian conversions and warnings Spotted by sparse. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 71 ++++++++-------------------------------------- 1 file changed, 12 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index ec655b8ef4d3..12167a6b5472 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -54,7 +54,6 @@ #include /* Driver Information */ -#define DRIVER_VERSION "0.70" #define DRIVER_AUTHOR "Jarod Wilson " #define DRIVER_AUTHOR2 "The Dweller, Stephen Cox" #define DRIVER_DESC "RedRat3 USB IR Transceiver Driver" @@ -199,14 +198,9 @@ struct redrat3_dev { /* the send endpoint */ struct usb_endpoint_descriptor *ep_out; - /* the buffer to send data */ - unsigned char *bulk_out_buf; - /* the urb used to send data */ - struct urb *write_urb; /* usb dma */ dma_addr_t dma_in; - dma_addr_t dma_out; /* rx signal timeout timer */ struct timer_list rx_timeout; @@ -239,7 +233,6 @@ static void redrat3_issue_async(struct redrat3_dev *rr3) rr3_ftr(rr3->dev, "Entering %s\n", __func__); - memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize); res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); if (res) rr3_dbg(rr3->dev, "%s: receive request FAILED! " @@ -368,7 +361,7 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) { DEFINE_IR_RAW_EVENT(rawir); struct device *dev; - int i, trailer = 0; + unsigned i, trailer = 0; unsigned sig_size, single_len, offset, val; unsigned long delay; u32 mod_freq; @@ -510,15 +503,11 @@ static inline void redrat3_delete(struct redrat3_dev *rr3, { rr3_ftr(rr3->dev, "%s cleaning up\n", __func__); usb_kill_urb(rr3->read_urb); - usb_kill_urb(rr3->write_urb); usb_free_urb(rr3->read_urb); - usb_free_urb(rr3->write_urb); - usb_free_coherent(udev, rr3->ep_in->wMaxPacketSize, + usb_free_coherent(udev, le16_to_cpu(rr3->ep_in->wMaxPacketSize), rr3->bulk_in_buf, rr3->dma_in); - usb_free_coherent(udev, rr3->ep_out->wMaxPacketSize, - rr3->bulk_out_buf, rr3->dma_out); kfree(rr3); } @@ -566,7 +555,7 @@ static void redrat3_reset(struct redrat3_dev *rr3) rxpipe = usb_rcvctrlpipe(udev, 0); txpipe = usb_sndctrlpipe(udev, 0); - val = kzalloc(len, GFP_KERNEL); + val = kmalloc(len, GFP_KERNEL); if (!val) { dev_err(dev, "Memory allocation failure\n"); return; @@ -620,7 +609,7 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) rr3_ftr(rr3->dev, "Exiting %s\n", __func__); } -static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len) +static void redrat3_read_packet_start(struct redrat3_dev *rr3, unsigned len) { struct redrat3_header *header = rr3->bulk_in_buf; unsigned pktlen, pkttype; @@ -659,7 +648,7 @@ static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len) } } -static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) +static void redrat3_read_packet_continue(struct redrat3_dev *rr3, unsigned len) { void *irdata = &rr3->irdata; @@ -679,7 +668,7 @@ static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) } /* gather IR data from incoming urb, process it when we have enough */ -static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len) +static int redrat3_get_ir_data(struct redrat3_dev *rr3, unsigned len) { struct device *dev = rr3->dev; unsigned pkttype; @@ -755,22 +744,6 @@ static void redrat3_handle_async(struct urb *urb) } } -static void redrat3_write_bulk_callback(struct urb *urb) -{ - struct redrat3_dev *rr3; - int len; - - if (!urb) - return; - - rr3 = urb->context; - if (rr3) { - len = urb->actual_length; - rr3_ftr(rr3->dev, "%s: called (status=%d len=%d)\n", - __func__, urb->status, len); - } -} - static u16 mod_freq_to_val(unsigned int mod_freq) { int mult = 6000000; @@ -799,11 +772,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; struct redrat3_irdata *irdata = NULL; - int i, ret, ret_len; + int ret, ret_len; int lencheck, cur_sample_len, pipe; int *sample_lens = NULL; u8 curlencheck = 0; - int sendbuf_len; + unsigned i, sendbuf_len; rr3_ftr(dev, "Entering %s\n", __func__); @@ -1015,38 +988,18 @@ static int redrat3_dev_probe(struct usb_interface *intf, } rr3->ep_in = ep_in; - rr3->bulk_in_buf = usb_alloc_coherent(udev, ep_in->wMaxPacketSize, - GFP_ATOMIC, &rr3->dma_in); + rr3->bulk_in_buf = usb_alloc_coherent(udev, + le16_to_cpu(ep_in->wMaxPacketSize), GFP_ATOMIC, &rr3->dma_in); if (!rr3->bulk_in_buf) { dev_err(dev, "Read buffer allocation failure\n"); goto error; } pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); - usb_fill_bulk_urb(rr3->read_urb, udev, pipe, - rr3->bulk_in_buf, ep_in->wMaxPacketSize, - redrat3_handle_async, rr3); - - /* set up bulk-out endpoint*/ - rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rr3->write_urb) { - dev_err(dev, "Write urb allocation failure\n"); - goto error; - } + usb_fill_bulk_urb(rr3->read_urb, udev, pipe, rr3->bulk_in_buf, + le16_to_cpu(ep_in->wMaxPacketSize), redrat3_handle_async, rr3); rr3->ep_out = ep_out; - rr3->bulk_out_buf = usb_alloc_coherent(udev, ep_out->wMaxPacketSize, - GFP_ATOMIC, &rr3->dma_out); - if (!rr3->bulk_out_buf) { - dev_err(dev, "Write buffer allocation failure\n"); - goto error; - } - - pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress); - usb_fill_bulk_urb(rr3->write_urb, udev, pipe, - rr3->bulk_out_buf, ep_out->wMaxPacketSize, - redrat3_write_bulk_callback, rr3); - rr3->udev = udev; redrat3_reset(rr3); -- cgit From 5144f5b76028dbfdbbf2f10721b73a553451c83a Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 5 Mar 2013 18:02:43 -0300 Subject: [media] dvb_demux: Transport stream continuity check fix This patch avoids incrementing continuity counter demux->cnt_storage[pid] for TS packets without payload in accordance with ISO /IEC 13818-1. [mchehab@redhat.com: unmangle whitespacing and fix CodingStyle. Also checked ISO/IEC spec: patch is according with it] Reviewed-by: Mauro Carvalho Chehab Signed-off-by: John Smith Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_demux.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index d319717eb535..71641b2dde6b 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -440,20 +440,22 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) if (!dvb_demux_feed_err_pkts) return; } else /* if TEI bit is set, pid may be wrong- skip pkt counter */ - if (demux->cnt_storage && dvb_demux_tscheck) { - /* check pkt counter */ - if (pid < MAX_PID) { - if ((buf[3] & 0xf) != demux->cnt_storage[pid]) - dprintk_tscheck("TS packet counter mismatch. " - "PID=0x%x expected 0x%x " - "got 0x%x\n", + if (demux->cnt_storage && dvb_demux_tscheck) { + /* check pkt counter */ + if (pid < MAX_PID) { + if (buf[3] & 0x10) + demux->cnt_storage[pid] = + (demux->cnt_storage[pid] + 1) & 0xf; + + if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { + dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", pid, demux->cnt_storage[pid], buf[3] & 0xf); - - demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf; + demux->cnt_storage[pid] = buf[3] & 0xf; + } + } + /* end check */ } - /* end check */ - } list_for_each_entry(feed, &demux->feed_list, list_head) { if ((feed->pid != pid) && (feed->pid != 0x2000)) -- cgit From 72873e51c578ae29463a5d146f68881fcd0924c0 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Wed, 6 Mar 2013 16:44:46 -0300 Subject: [media] lmedm04: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 96804be0fffe..b3fd0ffa3c3f 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -1302,8 +1302,7 @@ static void lme2510_exit(struct dvb_usb_device *d) if (d != NULL) { usb_buffer = lme2510_exit_int(d); - if (usb_buffer != NULL) - kfree(usb_buffer); + kfree(usb_buffer); } } -- cgit From e76d4ce49f574b6d94324239f8b7d655774d062c Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Wed, 6 Mar 2013 16:52:15 -0300 Subject: [media] rc-core: initialize rc-core earlier if built-in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rc-core is a subsystem so it should be registered earlier if built into the kernel. Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 759a40a42eaa..a92b8c536c89 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1207,7 +1207,7 @@ static void __exit rc_core_exit(void) rc_map_unregister(&empty_map); } -module_init(rc_core_init); +subsys_initcall(rc_core_init); module_exit(rc_core_exit); int rc_core_debug; /* ir_debug level (0,1,2) */ -- cgit From 40fc5325e1b6764754116cc36dd34adfb964ef65 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Wed, 6 Mar 2013 16:52:10 -0300 Subject: [media] rc-core: rename ir_input_class to rc_class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The name is already misleading and will be more so in the future as the connection to the input subsystem is obscured away further. Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a92b8c536c89..f3047920b8c0 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -715,14 +715,14 @@ static void ir_close(struct input_dev *idev) } /* class for /sys/class/rc */ -static char *ir_devnode(struct device *dev, umode_t *mode) +static char *rc_devnode(struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); } -static struct class ir_input_class = { +static struct class rc_class = { .name = "rc", - .devnode = ir_devnode, + .devnode = rc_devnode, }; /* @@ -1016,7 +1016,7 @@ struct rc_dev *rc_allocate_device(void) setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = &rc_dev_type; - dev->dev.class = &ir_input_class; + dev->dev.class = &rc_class; device_initialize(&dev->dev); __module_get(THIS_MODULE); @@ -1190,7 +1190,7 @@ EXPORT_SYMBOL_GPL(rc_unregister_device); static int __init rc_core_init(void) { - int rc = class_register(&ir_input_class); + int rc = class_register(&rc_class); if (rc) { printk(KERN_ERR "rc_core: unable to register rc class\n"); return rc; @@ -1203,7 +1203,7 @@ static int __init rc_core_init(void) static void __exit rc_core_exit(void) { - class_unregister(&ir_input_class); + class_unregister(&rc_class); rc_map_unregister(&empty_map); } -- cgit From f08e9f0d5c138fcf8b0a1a952011cd044ae4e859 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Thu, 7 Mar 2013 09:36:22 -0300 Subject: [media] [1/1,dvb-usb] GOTVIEW SatelliteHD card support Added support for the GOTVIEW SatelliteHD card which is based on Montage M88DS3000 and works very well with this driver. Signed-off-by: Andrey Pavlenko Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 24cfd4bbbc8a..d5957b0299d3 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -79,6 +79,10 @@ #define USB_PID_TEVII_S632 0xd632 #endif +#ifndef USB_PID_GOTVIEW_SAT_HD +#define USB_PID_GOTVIEW_SAT_HD 0x5456 +#endif + #define DW210X_READ_MSG 0 #define DW210X_WRITE_MSG 1 @@ -1549,6 +1553,7 @@ enum dw2102_table_entry { TEVII_S421, TEVII_S632, TERRATEC_CINERGY_S2_R2, + GOTVIEW_SAT_HD, }; static struct usb_device_id dw2102_table[] = { @@ -1570,6 +1575,7 @@ static struct usb_device_id dw2102_table[] = { [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)}, [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, + [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, { } }; @@ -1970,7 +1976,7 @@ static struct dvb_usb_device_properties su3000_properties = { }}, } }, - .num_device_descs = 4, + .num_device_descs = 5, .devices = { { "SU3000HD DVB-S USB2.0", { &dw2102_table[GENIATECH_SU3000], NULL }, @@ -1988,6 +1994,10 @@ static struct dvb_usb_device_properties su3000_properties = { { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL }, { NULL }, }, + { "GOTVIEW Satellite HD", + { &dw2102_table[GOTVIEW_SAT_HD], NULL }, + { NULL }, + }, } }; -- cgit From f0cd015e31d3818c96a9b436357b39929c2a361b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 14:33:51 -0300 Subject: [media] tvp7002: replace 'preset' by 'timings' in various structs/variables This is the first step towards removing the deprecated preset support of this driver. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp7002.c | 90 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 537f6b4d4918..7995eeb8f847 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -326,8 +326,8 @@ static const struct i2c_reg_value tvp7002_parms_720P50[] = { { TVP7002_EOR, 0xff, TVP7002_RESERVED } }; -/* Preset definition for handling device operation */ -struct tvp7002_preset_definition { +/* Timings definition for handling device operation */ +struct tvp7002_timings_definition { u32 preset; struct v4l2_dv_timings timings; const struct i2c_reg_value *p_settings; @@ -339,8 +339,8 @@ struct tvp7002_preset_definition { u16 cpl_max; }; -/* Struct list for digital video presets */ -static const struct tvp7002_preset_definition tvp7002_presets[] = { +/* Struct list for digital video timings */ +static const struct tvp7002_timings_definition tvp7002_timings[] = { { V4L2_DV_720P60, V4L2_DV_BT_CEA_1280X720P60, @@ -420,7 +420,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = { } }; -#define NUM_PRESETS ARRAY_SIZE(tvp7002_presets) +#define NUM_TIMINGS ARRAY_SIZE(tvp7002_timings) /* Device definition */ struct tvp7002 { @@ -431,7 +431,7 @@ struct tvp7002 { int ver; int streaming; - const struct tvp7002_preset_definition *current_preset; + const struct tvp7002_timings_definition *current_timings; }; /* @@ -603,11 +603,11 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd, u32 preset; int i; - for (i = 0; i < NUM_PRESETS; i++) { - preset = tvp7002_presets[i].preset; + for (i = 0; i < NUM_TIMINGS; i++) { + preset = tvp7002_timings[i].preset; if (preset == dv_preset->preset) { - device->current_preset = &tvp7002_presets[i]; - return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings); + device->current_timings = &tvp7002_timings[i]; + return tvp7002_write_inittab(sd, tvp7002_timings[i].p_settings); } } @@ -623,12 +623,12 @@ static int tvp7002_s_dv_timings(struct v4l2_subdev *sd, if (dv_timings->type != V4L2_DV_BT_656_1120) return -EINVAL; - for (i = 0; i < NUM_PRESETS; i++) { - const struct v4l2_bt_timings *t = &tvp7002_presets[i].timings.bt; + for (i = 0; i < NUM_TIMINGS; i++) { + const struct v4l2_bt_timings *t = &tvp7002_timings[i].timings.bt; if (!memcmp(bt, t, &bt->standards - &bt->width)) { - device->current_preset = &tvp7002_presets[i]; - return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings); + device->current_timings = &tvp7002_timings[i]; + return tvp7002_write_inittab(sd, tvp7002_timings[i].p_settings); } } return -EINVAL; @@ -639,7 +639,7 @@ static int tvp7002_g_dv_timings(struct v4l2_subdev *sd, { struct tvp7002 *device = to_tvp7002(sd); - *dv_timings = device->current_preset->timings; + *dv_timings = device->current_timings->timings; return 0; } @@ -681,15 +681,15 @@ static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f int error; /* Calculate height and width based on current standard */ - error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset); + error = v4l_fill_dv_preset_info(device->current_timings->preset, &e_preset); if (error) return error; f->width = e_preset.width; f->height = e_preset.height; f->code = V4L2_MBUS_FMT_YUYV10_1X20; - f->field = device->current_preset->scanmode; - f->colorspace = device->current_preset->color_space; + f->field = device->current_timings->scanmode; + f->colorspace = device->current_timings->color_space; v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d", f->width, f->height); @@ -697,16 +697,16 @@ static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f } /* - * tvp7002_query_dv_preset() - query DV preset + * tvp7002_query_dv() - query DV timings * @sd: pointer to standard V4L2 sub-device structure - * @qpreset: standard V4L2 v4l2_dv_preset structure + * @index: index into the tvp7002_timings array * - * Returns the current DV preset by TVP7002. If no active input is + * Returns the current DV timings detected by TVP7002. If no active input is * detected, returns -EINVAL */ static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index) { - const struct tvp7002_preset_definition *presets = tvp7002_presets; + const struct tvp7002_timings_definition *timings = tvp7002_timings; u8 progressive; u32 lpfr; u32 cpln; @@ -717,7 +717,7 @@ static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index) u8 cpl_msb; /* Return invalid index if no active input is detected */ - *index = NUM_PRESETS; + *index = NUM_TIMINGS; /* Read standards from device registers */ tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error); @@ -738,23 +738,23 @@ static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index) progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT; /* Do checking of video modes */ - for (*index = 0; *index < NUM_PRESETS; (*index)++, presets++) - if (lpfr == presets->lines_per_frame && - progressive == presets->progressive) { - if (presets->cpl_min == 0xffff) + for (*index = 0; *index < NUM_TIMINGS; (*index)++, timings++) + if (lpfr == timings->lines_per_frame && + progressive == timings->progressive) { + if (timings->cpl_min == 0xffff) break; - if (cpln >= presets->cpl_min && cpln <= presets->cpl_max) + if (cpln >= timings->cpl_min && cpln <= timings->cpl_max) break; } - if (*index == NUM_PRESETS) { + if (*index == NUM_TIMINGS) { v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n", lpfr, cpln); return -ENOLINK; } /* Update lines per frame and clocks per line info */ - v4l2_dbg(1, debug, sd, "detected preset: %d\n", *index); + v4l2_dbg(1, debug, sd, "detected timings: %d\n", *index); return 0; } @@ -764,13 +764,13 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd, int index; int err = tvp7002_query_dv(sd, &index); - if (err || index == NUM_PRESETS) { + if (err || index == NUM_TIMINGS) { qpreset->preset = V4L2_DV_INVALID; if (err == -ENOLINK) err = 0; return err; } - qpreset->preset = tvp7002_presets[index].preset; + qpreset->preset = tvp7002_timings[index].preset; return 0; } @@ -782,7 +782,7 @@ static int tvp7002_query_dv_timings(struct v4l2_subdev *sd, if (err) return err; - *timings = tvp7002_presets[index].timings; + *timings = tvp7002_timings[index].timings; return 0; } @@ -896,7 +896,7 @@ static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable) */ static int tvp7002_log_status(struct v4l2_subdev *sd) { - const struct tvp7002_preset_definition *presets = tvp7002_presets; + const struct tvp7002_timings_definition *timings = tvp7002_timings; struct tvp7002 *device = to_tvp7002(sd); struct v4l2_dv_enum_preset e_preset; struct v4l2_dv_preset detected; @@ -907,20 +907,20 @@ static int tvp7002_log_status(struct v4l2_subdev *sd) tvp7002_query_dv_preset(sd, &detected); /* Print standard related code values */ - for (i = 0; i < NUM_PRESETS; i++, presets++) - if (presets->preset == detected.preset) + for (i = 0; i < NUM_TIMINGS; i++, timings++) + if (timings->preset == detected.preset) break; - if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset)) + if (v4l_fill_dv_preset_info(device->current_timings->preset, &e_preset)) return -EINVAL; v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name); v4l2_info(sd, " Pixels per line: %u\n", e_preset.width); v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height); - if (i == NUM_PRESETS) { + if (i == NUM_TIMINGS) { v4l2_info(sd, "Detected DV Preset: None\n"); } else { - if (v4l_fill_dv_preset_info(presets->preset, &e_preset)) + if (v4l_fill_dv_preset_info(timings->preset, &e_preset)) return -EINVAL; v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name); v4l2_info(sd, " Pixels per line: %u\n", e_preset.width); @@ -946,20 +946,20 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd, struct v4l2_dv_enum_preset *preset) { /* Check requested format index is within range */ - if (preset->index >= NUM_PRESETS) + if (preset->index >= NUM_TIMINGS) return -EINVAL; - return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset); + return v4l_fill_dv_preset_info(tvp7002_timings[preset->index].preset, preset); } static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd, struct v4l2_enum_dv_timings *timings) { /* Check requested format index is within range */ - if (timings->index >= NUM_PRESETS) + if (timings->index >= NUM_TIMINGS) return -EINVAL; - timings->timings = tvp7002_presets[timings->index].timings; + timings->timings = tvp7002_timings[timings->index].timings; return 0; } @@ -1043,7 +1043,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) sd = &device->sd; device->pdata = c->dev.platform_data; - device->current_preset = tvp7002_presets; + device->current_timings = tvp7002_timings; /* Tell v4l2 the device is ready */ v4l2_i2c_subdev_init(sd, c, &tvp7002_ops); @@ -1080,7 +1080,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) return error; /* Set registers according to default video mode */ - preset.preset = device->current_preset->preset; + preset.preset = device->current_timings->preset; error = tvp7002_s_dv_preset(sd, &preset); v4l2_ctrl_handler_init(&device->hdl, 1); -- cgit From f96067af1f2313fd0e29c131368f33364f0ad98c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 14:46:40 -0300 Subject: [media] tvp7002: use dv_timings structs instead of presets In the functions tvp7002_mbus_fmt(), tvp7002_log_status and tvp7002_probe() we should use the dv_timings data structures instead of dv_preset data structures and functions. This is the second step towards removing the deprecated preset support of this driver. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp7002.c | 54 ++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 7995eeb8f847..d7a08bc49622 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -677,16 +677,10 @@ static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl) static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) { struct tvp7002 *device = to_tvp7002(sd); - struct v4l2_dv_enum_preset e_preset; - int error; - - /* Calculate height and width based on current standard */ - error = v4l_fill_dv_preset_info(device->current_timings->preset, &e_preset); - if (error) - return error; + const struct v4l2_bt_timings *bt = &device->current_timings->timings.bt; - f->width = e_preset.width; - f->height = e_preset.height; + f->width = bt->width; + f->height = bt->height; f->code = V4L2_MBUS_FMT_YUYV10_1X20; f->field = device->current_timings->scanmode; f->colorspace = device->current_timings->color_space; @@ -896,35 +890,21 @@ static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable) */ static int tvp7002_log_status(struct v4l2_subdev *sd) { - const struct tvp7002_timings_definition *timings = tvp7002_timings; struct tvp7002 *device = to_tvp7002(sd); - struct v4l2_dv_enum_preset e_preset; - struct v4l2_dv_preset detected; - int i; + const struct v4l2_bt_timings *bt; + int detected; - detected.preset = V4L2_DV_INVALID; - /* Find my current standard*/ - tvp7002_query_dv_preset(sd, &detected); + /* Find my current timings */ + tvp7002_query_dv(sd, &detected); - /* Print standard related code values */ - for (i = 0; i < NUM_TIMINGS; i++, timings++) - if (timings->preset == detected.preset) - break; - - if (v4l_fill_dv_preset_info(device->current_timings->preset, &e_preset)) - return -EINVAL; - - v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name); - v4l2_info(sd, " Pixels per line: %u\n", e_preset.width); - v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height); - if (i == NUM_TIMINGS) { - v4l2_info(sd, "Detected DV Preset: None\n"); + bt = &device->current_timings->timings.bt; + v4l2_info(sd, "Selected DV Timings: %ux%u\n", bt->width, bt->height); + if (detected == NUM_TIMINGS) { + v4l2_info(sd, "Detected DV Timings: None\n"); } else { - if (v4l_fill_dv_preset_info(timings->preset, &e_preset)) - return -EINVAL; - v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name); - v4l2_info(sd, " Pixels per line: %u\n", e_preset.width); - v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height); + bt = &tvp7002_timings[detected].timings.bt; + v4l2_info(sd, "Detected DV Timings: %ux%u\n", + bt->width, bt->height); } v4l2_info(sd, "Streaming enabled: %s\n", device->streaming ? "yes" : "no"); @@ -1019,7 +999,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) { struct v4l2_subdev *sd; struct tvp7002 *device; - struct v4l2_dv_preset preset; + struct v4l2_dv_timings timings; int polarity_a; int polarity_b; u8 revision; @@ -1080,8 +1060,8 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) return error; /* Set registers according to default video mode */ - preset.preset = device->current_timings->preset; - error = tvp7002_s_dv_preset(sd, &preset); + timings = device->current_timings->timings; + error = tvp7002_s_dv_timings(sd, &timings); v4l2_ctrl_handler_init(&device->hdl, 1); v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops, -- cgit From 416d307651ffa035a1e9f5ccc9f915cb2235d415 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 14:49:15 -0300 Subject: [media] tvp7002: remove dv_preset support Finally remove the dv_preset support from this driver. Note that dv_preset support was already removed from any bridge drivers that use this i2c driver, so the dv_preset ops were no longer called and can be removed safely. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp7002.c | 70 --------------------------------------------- 1 file changed, 70 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index d7a08bc49622..7406de9b45db 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -328,7 +328,6 @@ static const struct i2c_reg_value tvp7002_parms_720P50[] = { /* Timings definition for handling device operation */ struct tvp7002_timings_definition { - u32 preset; struct v4l2_dv_timings timings; const struct i2c_reg_value *p_settings; enum v4l2_colorspace color_space; @@ -342,7 +341,6 @@ struct tvp7002_timings_definition { /* Struct list for digital video timings */ static const struct tvp7002_timings_definition tvp7002_timings[] = { { - V4L2_DV_720P60, V4L2_DV_BT_CEA_1280X720P60, tvp7002_parms_720P60, V4L2_COLORSPACE_REC709, @@ -353,7 +351,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 153 }, { - V4L2_DV_1080I60, V4L2_DV_BT_CEA_1920X1080I60, tvp7002_parms_1080I60, V4L2_COLORSPACE_REC709, @@ -364,7 +361,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 205 }, { - V4L2_DV_1080I50, V4L2_DV_BT_CEA_1920X1080I50, tvp7002_parms_1080I50, V4L2_COLORSPACE_REC709, @@ -375,7 +371,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 245 }, { - V4L2_DV_720P50, V4L2_DV_BT_CEA_1280X720P50, tvp7002_parms_720P50, V4L2_COLORSPACE_REC709, @@ -386,7 +381,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 183 }, { - V4L2_DV_1080P60, V4L2_DV_BT_CEA_1920X1080P60, tvp7002_parms_1080P60, V4L2_COLORSPACE_REC709, @@ -397,7 +391,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 102 }, { - V4L2_DV_480P59_94, V4L2_DV_BT_CEA_720X480P59_94, tvp7002_parms_480P, V4L2_COLORSPACE_SMPTE170M, @@ -408,7 +401,6 @@ static const struct tvp7002_timings_definition tvp7002_timings[] = { 0xffff }, { - V4L2_DV_576P50, V4L2_DV_BT_CEA_720X576P50, tvp7002_parms_576P, V4L2_COLORSPACE_SMPTE170M, @@ -588,32 +580,6 @@ static int tvp7002_write_inittab(struct v4l2_subdev *sd, return error; } -/* - * tvp7002_s_dv_preset() - Set digital video preset - * @sd: ptr to v4l2_subdev struct - * @dv_preset: ptr to v4l2_dv_preset struct - * - * Set the digital video preset for a TVP7002 decoder device. - * Returns zero when successful or -EINVAL if register access fails. - */ -static int tvp7002_s_dv_preset(struct v4l2_subdev *sd, - struct v4l2_dv_preset *dv_preset) -{ - struct tvp7002 *device = to_tvp7002(sd); - u32 preset; - int i; - - for (i = 0; i < NUM_TIMINGS; i++) { - preset = tvp7002_timings[i].preset; - if (preset == dv_preset->preset) { - device->current_timings = &tvp7002_timings[i]; - return tvp7002_write_inittab(sd, tvp7002_timings[i].p_settings); - } - } - - return -EINVAL; -} - static int tvp7002_s_dv_timings(struct v4l2_subdev *sd, struct v4l2_dv_timings *dv_timings) { @@ -752,22 +718,6 @@ static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index) return 0; } -static int tvp7002_query_dv_preset(struct v4l2_subdev *sd, - struct v4l2_dv_preset *qpreset) -{ - int index; - int err = tvp7002_query_dv(sd, &index); - - if (err || index == NUM_TIMINGS) { - qpreset->preset = V4L2_DV_INVALID; - if (err == -ENOLINK) - err = 0; - return err; - } - qpreset->preset = tvp7002_timings[index].preset; - return 0; -} - static int tvp7002_query_dv_timings(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings) { @@ -915,23 +865,6 @@ static int tvp7002_log_status(struct v4l2_subdev *sd) return 0; } -/* - * tvp7002_enum_dv_presets() - Enum supported digital video formats - * @sd: pointer to standard V4L2 sub-device structure - * @preset: pointer to format struct - * - * Enumerate supported digital video formats. - */ -static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd, - struct v4l2_dv_enum_preset *preset) -{ - /* Check requested format index is within range */ - if (preset->index >= NUM_TIMINGS) - return -EINVAL; - - return v4l_fill_dv_preset_info(tvp7002_timings[preset->index].preset, preset); -} - static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd, struct v4l2_enum_dv_timings *timings) { @@ -966,9 +899,6 @@ static const struct v4l2_subdev_core_ops tvp7002_core_ops = { /* Specific video subsystem operation handlers */ static const struct v4l2_subdev_video_ops tvp7002_video_ops = { - .enum_dv_presets = tvp7002_enum_dv_presets, - .s_dv_preset = tvp7002_s_dv_preset, - .query_dv_preset = tvp7002_query_dv_preset, .g_dv_timings = tvp7002_g_dv_timings, .s_dv_timings = tvp7002_s_dv_timings, .enum_dv_timings = tvp7002_enum_dv_timings, -- cgit From 4bd3bb7129ac9a0ee3ba4b587c228f5f43b841cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 14:51:23 -0300 Subject: [media] davinci_vpfe: fix copy-paste errors in several comments This removes some incorrect dv_preset references left over from copy-and-paste errors. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 99ccbebea598..19dc5b062d07 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1016,12 +1016,12 @@ vpfe_query_dv_timings(struct file *file, void *fh, } /* - * vpfe_s_dv_timings() - set dv_preset on external subdev + * vpfe_s_dv_timings() - set dv_timings on external subdev * @file: file pointer * @priv: void pointer * @timings: pointer to v4l2_dv_timings structure * - * set dv_timings pointed by preset on external subdev through + * set dv_timings pointed by timings on external subdev through * v4l2_device_call_until_err, this configures amplifier also * * Return 0 on success, error code otherwise @@ -1042,12 +1042,12 @@ vpfe_s_dv_timings(struct file *file, void *fh, } /* - * vpfe_g_dv_timings() - get dv_preset which is set on external subdev + * vpfe_g_dv_timings() - get dv_timings which is set on external subdev * @file: file pointer * @priv: void pointer * @timings: pointer to v4l2_dv_timings structure * - * get dv_preset which is set on external subdev through + * get dv_timings which is set on external subdev through * v4l2_subdev_call * * Return 0 on success, error code otherwise @@ -1423,7 +1423,7 @@ static int vpfe_dqbuf(struct file *file, void *priv, } /* - * vpfe_streamon() - get dv_preset which is set on external subdev + * vpfe_streamon() - start streaming * @file: file pointer * @priv: void pointer * @buf_type: enum v4l2_buf_type @@ -1472,7 +1472,7 @@ static int vpfe_streamon(struct file *file, void *priv, } /* - * vpfe_streamoff() - get dv_preset which is set on external subdev + * vpfe_streamoff() - stop streaming * @file: file pointer * @priv: void pointer * @buf_type: enum v4l2_buf_type -- cgit From ef2d41b19b8100ce63eabba9ee87953aa685921a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 15:06:28 -0300 Subject: [media] davinci: remove VPBE_ENC_DV_PRESET and rename VPBE_ENC_CUSTOM_TIMINGS Remove VPBE_ENC_DV_PRESET (the DV_PRESET API is no longer supported) and VPBE_ENC_CUSTOM_TIMINGS is renamed to VPBE_ENC_DV_TIMINGS since the old "CUSTOM_TIMINGS" name is deprecated in favor of "DV_TIMINGS". Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Acked-by: Sekhar Nori Signed-off-by: Mauro Carvalho Chehab --- arch/arm/mach-davinci/board-dm644x-evm.c | 4 ++-- arch/arm/mach-davinci/dm644x.c | 2 +- drivers/media/platform/davinci/vpbe.c | 8 ++++---- drivers/media/platform/davinci/vpbe_display.c | 2 +- drivers/media/platform/davinci/vpbe_venc.c | 8 ++++---- include/media/davinci/vpbe_types.h | 3 +-- 6 files changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 71735e7797cc..a02180052a76 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -649,7 +649,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = { static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = { { .name = "480p59_94", - .timings_type = VPBE_ENC_CUSTOM_TIMINGS, + .timings_type = VPBE_ENC_DV_TIMINGS, .dv_timings = V4L2_DV_BT_CEA_720X480P59_94, .interlaced = 0, .xres = 720, @@ -661,7 +661,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = { }, { .name = "576p50", - .timings_type = VPBE_ENC_CUSTOM_TIMINGS, + .timings_type = VPBE_ENC_DV_TIMINGS, .dv_timings = V4L2_DV_BT_CEA_720X576P50, .interlaced = 0, .xres = 720, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index db1dd92e00af..ee0e994748e0 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -706,7 +706,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, v |= DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); break; - case VPBE_ENC_CUSTOM_TIMINGS: + case VPBE_ENC_DV_TIMINGS: if (pclock <= 27000000) { v |= DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 4ca0f9a2ad8a..2a49f00c4543 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -344,7 +344,7 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev, return -EINVAL; for (i = 0; i < output->num_modes; i++) { - if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS && + if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS && !memcmp(&output->modes[i].dv_timings, dv_timings, sizeof(*dv_timings))) break; @@ -385,7 +385,7 @@ static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev, struct v4l2_dv_timings *dv_timings) { if (vpbe_dev->current_timings.timings_type & - VPBE_ENC_CUSTOM_TIMINGS) { + VPBE_ENC_DV_TIMINGS) { *dv_timings = vpbe_dev->current_timings.dv_timings; return 0; } @@ -412,7 +412,7 @@ static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev, return -EINVAL; for (i = 0; i < output->num_modes; i++) { - if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS) { + if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) { if (j == timings->index) break; j++; @@ -515,7 +515,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, return vpbe_s_std(vpbe_dev, &preset_mode->std_id); if (preset_mode->timings_type & - VPBE_ENC_CUSTOM_TIMINGS) { + VPBE_ENC_DV_TIMINGS) { dv_timings = preset_mode->dv_timings; return vpbe_s_dv_timings(vpbe_dev, &dv_timings); diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 9f9f2c1a073f..8290fddbd47d 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1202,7 +1202,7 @@ vpbe_display_g_dv_timings(struct file *file, void *priv, /* Get the given standard in the encoder */ if (vpbe_dev->current_timings.timings_type & - VPBE_ENC_CUSTOM_TIMINGS) { + VPBE_ENC_DV_TIMINGS) { *dv_timings = vpbe_dev->current_timings.dv_timings; } else { return -EINVAL; diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index bdbebd59df98..9546d268e2db 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -313,7 +313,7 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd) return -EINVAL; /* Setup clock at VPSS & VENC for SD */ - if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0) + if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); @@ -360,7 +360,7 @@ static int venc_set_576p50(struct v4l2_subdev *sd) venc->venc_type != VPBE_VERSION_2) return -EINVAL; /* Setup clock at VPSS & VENC for SD */ - if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0) + if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); @@ -400,7 +400,7 @@ static int venc_set_720p60_internal(struct v4l2_subdev *sd) struct venc_state *venc = to_state(sd); struct venc_platform_data *pdata = venc->pdata; - if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0) + if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); @@ -428,7 +428,7 @@ static int venc_set_1080i30_internal(struct v4l2_subdev *sd) struct venc_state *venc = to_state(sd); struct venc_platform_data *pdata = venc->pdata; - if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0) + if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); diff --git a/include/media/davinci/vpbe_types.h b/include/media/davinci/vpbe_types.h index 9b85396514be..05dbe0ba514c 100644 --- a/include/media/davinci/vpbe_types.h +++ b/include/media/davinci/vpbe_types.h @@ -26,8 +26,7 @@ enum vpbe_version { /* vpbe_timing_type - Timing types used in vpbe device */ enum vpbe_enc_timings_type { VPBE_ENC_STD = 0x1, - VPBE_ENC_DV_PRESET = 0x2, - VPBE_ENC_CUSTOM_TIMINGS = 0x4, + VPBE_ENC_DV_TIMINGS = 0x4, /* Used when set timings through FB device interface */ VPBE_ENC_TIMINGS_INVALID = 0x8, }; -- cgit From 6f55dbaea5381831770025a98c04b5fc2f7e18ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Mar 2013 05:48:43 -0300 Subject: [media] davinci/vpfe_capture: convert to the control framework Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 47 ++++----------------------- 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 28d019da4c01..70facc03e6e0 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1107,6 +1107,7 @@ static int vpfe_g_input(struct file *file, void *priv, unsigned int *index) static int vpfe_s_input(struct file *file, void *priv, unsigned int index) { struct vpfe_device *vpfe_dev = video_drvdata(file); + struct v4l2_subdev *sd; struct vpfe_subdev_info *sdinfo; int subdev_index, inp_index; struct vpfe_route *route; @@ -1138,14 +1139,15 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) } sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index]; + sd = vpfe_dev->sd[subdev_index]; route = &sdinfo->routes[inp_index]; if (route && sdinfo->can_route) { input = route->input; output = route->output; } - ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, - video, s_routing, input, output, 0); + if (sd) + ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0); if (ret) { v4l2_err(&vpfe_dev->v4l2_dev, @@ -1154,6 +1156,8 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) goto unlock_out; } vpfe_dev->current_subdev = sdinfo; + if (sd) + vpfe_dev->v4l2_dev.ctrl_handler = sd->ctrl_handler; vpfe_dev->current_input = index; vpfe_dev->std_index = 0; @@ -1439,41 +1443,6 @@ static int vpfe_dqbuf(struct file *file, void *priv, buf, file->f_flags & O_NONBLOCK); } -static int vpfe_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qctrl) -{ - struct vpfe_device *vpfe_dev = video_drvdata(file); - struct vpfe_subdev_info *sdinfo; - - sdinfo = vpfe_dev->current_subdev; - - return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, - core, queryctrl, qctrl); - -} - -static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) -{ - struct vpfe_device *vpfe_dev = video_drvdata(file); - struct vpfe_subdev_info *sdinfo; - - sdinfo = vpfe_dev->current_subdev; - - return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, - core, g_ctrl, ctrl); -} - -static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) -{ - struct vpfe_device *vpfe_dev = video_drvdata(file); - struct vpfe_subdev_info *sdinfo; - - sdinfo = vpfe_dev->current_subdev; - - return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, - core, s_ctrl, ctrl); -} - /* * vpfe_calculate_offsets : This function calculates buffers offset * for top and bottom field @@ -1781,9 +1750,6 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = { .vidioc_querystd = vpfe_querystd, .vidioc_s_std = vpfe_s_std, .vidioc_g_std = vpfe_g_std, - .vidioc_queryctrl = vpfe_queryctrl, - .vidioc_g_ctrl = vpfe_g_ctrl, - .vidioc_s_ctrl = vpfe_s_ctrl, .vidioc_reqbufs = vpfe_reqbufs, .vidioc_querybuf = vpfe_querybuf, .vidioc_qbuf = vpfe_qbuf, @@ -2007,6 +1973,7 @@ static int vpfe_probe(struct platform_device *pdev) /* set first sub device as current one */ vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0]; + vpfe_dev->v4l2_dev.ctrl_handler = vpfe_dev->sd[0]->ctrl_handler; /* We have at least one sub device to work with */ mutex_unlock(&ccdc_lock); -- cgit From 142b66e82c39ad7e8e7e80c738718aa653bcad1b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 19 Feb 2013 13:33:34 -0300 Subject: [media] davinci/vpbe_display: remove deprecated current_norm Since vpbe_display already provides a g_std op setting current_norm didn't do anything. Remove that code. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 8290fddbd47d..30976dc9f346 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1176,10 +1176,6 @@ vpbe_display_s_dv_timings(struct file *file, void *priv, "Failed to set the dv timings info\n"); return -EINVAL; } - /* set the current norm to zero to be consistent. If STD is used - * v4l2 layer will set the norm properly on successful s_std call - */ - layer->video_dev.current_norm = 0; return 0; } @@ -1694,12 +1690,8 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev, vbd->vfl_dir = VFL_DIR_TX; if (disp_dev->vpbe_dev->current_timings.timings_type & - VPBE_ENC_STD) { + VPBE_ENC_STD) vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50); - vbd->current_norm = - disp_dev->vpbe_dev->current_timings.std_id; - } else - vbd->current_norm = 0; snprintf(vbd->name, sizeof(vbd->name), "DaVinci_VPBE Display_DRIVER_V%d.%d.%d", -- cgit From b12aed0ec518eb348ae0f6d196fd726c57670823 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 19 Feb 2013 13:34:52 -0300 Subject: [media] davinci/vpfe_capture: remove current_norm Since vpfe_capture already provided a g_std op setting current_norm does not actually do anything. Remove it. Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 70facc03e6e0..3d1af6704822 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1884,7 +1884,6 @@ static int vpfe_probe(struct platform_device *pdev) vfd->fops = &vpfe_fops; vfd->ioctl_ops = &vpfe_ioctl_ops; vfd->tvnorms = 0; - vfd->current_norm = V4L2_STD_PAL; vfd->v4l2_dev = &vpfe_dev->v4l2_dev; snprintf(vfd->name, sizeof(vfd->name), "%s_V%d.%d.%d", -- cgit From 1de1951930d4450d1645a0a907b710f268af42c3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Mar 2013 07:18:38 -0300 Subject: [media] davinci/dm644x_ccdc: fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/platform/davinci/dm644x_ccdc.c: In function ‘validate_ccdc_param’: drivers/media/platform/davinci/dm644x_ccdc.c:233:32: warning: comparison between ‘enum ccdc_gama_width’ and ‘enum ccdc_data_size’ [-Wenum-compare] It took a bit of work, see this thread of an earlier attempt to fix this: https://patchwork.kernel.org/patch/1923091/ I've chosen not to follow the suggestions in that thread since gamma_width is really a different property from data_size. What you really want is to know if gamma_width fits inside data_size and for that you need to translate each enum into a maximum bit number so you can safely compare the two. So I put in two static inline translation functions instead, keeping the rest of the code the same (except for fixing the 'gama' typo). Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/dm644x_ccdc.c | 13 +++++++----- drivers/media/platform/davinci/dm644x_ccdc_regs.h | 2 +- include/media/davinci/dm644x_ccdc.h | 24 +++++++++++++++++------ 3 files changed, 27 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 318e80512998..971d639b6674 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -228,9 +228,12 @@ static void ccdc_readregs(void) static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) { if (ccdcparam->alaw.enable) { - if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) || - (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) || - (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) { + u8 max_gamma = ccdc_gamma_width_max_bit(ccdcparam->alaw.gamma_wd); + u8 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz); + + if ((ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) || + (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_15_6) || + (max_gamma > max_data)) { dev_dbg(ccdc_cfg.dev, "\nInvalid data line select"); return -1; } @@ -560,8 +563,8 @@ void ccdc_config_raw(void) /* Enable and configure aLaw register if needed */ if (config_params->alaw.enable) { - val = ((config_params->alaw.gama_wd & - CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE); + val = ((config_params->alaw.gamma_wd & + CCDC_ALAW_GAMMA_WD_MASK) | CCDC_ALAW_ENABLE); regw(val, CCDC_ALAW); dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val); } diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h index 90370e414e2c..2b0aca5383f0 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h +++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h @@ -84,7 +84,7 @@ #define CCDC_VDHDEN_ENABLE (1 << 16) #define CCDC_LPF_ENABLE (1 << 14) #define CCDC_ALAW_ENABLE (1 << 3) -#define CCDC_ALAW_GAMA_WD_MASK 7 +#define CCDC_ALAW_GAMMA_WD_MASK 7 #define CCDC_BLK_CLAMP_ENABLE (1 << 31) #define CCDC_BLK_SGAIN_MASK 0x1F #define CCDC_BLK_ST_PXL_MASK 0x7FFF diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h index 3e178eb52fb3..852e96c4bb46 100644 --- a/include/media/davinci/dm644x_ccdc.h +++ b/include/media/davinci/dm644x_ccdc.h @@ -38,17 +38,23 @@ enum ccdc_sample_line { CCDC_SAMPLE_16LINES }; -/* enum for Alaw gama width */ -enum ccdc_gama_width { - CCDC_GAMMA_BITS_15_6, +/* enum for Alaw gamma width */ +enum ccdc_gamma_width { + CCDC_GAMMA_BITS_15_6, /* use bits 15-6 for gamma */ CCDC_GAMMA_BITS_14_5, CCDC_GAMMA_BITS_13_4, CCDC_GAMMA_BITS_12_3, CCDC_GAMMA_BITS_11_2, CCDC_GAMMA_BITS_10_1, - CCDC_GAMMA_BITS_09_0 + CCDC_GAMMA_BITS_09_0 /* use bits 9-0 for gamma */ }; +/* returns the highest bit used for the gamma */ +static inline u8 ccdc_gamma_width_max_bit(enum ccdc_gamma_width width) +{ + return 15 - width; +} + enum ccdc_data_size { CCDC_DATA_16BITS, CCDC_DATA_15BITS, @@ -60,12 +66,18 @@ enum ccdc_data_size { CCDC_DATA_8BITS }; +/* returns the highest bit used for this data size */ +static inline u8 ccdc_data_size_max_bit(enum ccdc_data_size sz) +{ + return sz == CCDC_DATA_8BITS ? 7 : 15 - sz; +} + /* structure for ALaw */ struct ccdc_a_law { /* Enable/disable A-Law */ unsigned char enable; - /* Gama Width Input */ - enum ccdc_gama_width gama_wd; + /* Gamma Width Input */ + enum ccdc_gamma_width gamma_wd; }; /* structure for Black Clamping */ -- cgit From db242f62bd18f6c689c0e04f3df14be2deb89462 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Mar 2013 07:24:07 -0300 Subject: [media] davinci: more gama -> gamma typo fixes Signed-off-by: Hans Verkuil Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/dm355_ccdc.c | 10 +++++----- drivers/media/platform/davinci/dm355_ccdc_regs.h | 2 +- drivers/media/platform/davinci/isif.c | 2 +- drivers/media/platform/davinci/isif_regs.h | 4 ++-- include/media/davinci/dm355_ccdc.h | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 4277e4ad810c..2364dbab8046 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -85,7 +85,7 @@ static struct ccdc_oper_config { .mfilt1 = CCDC_NO_MEDIAN_FILTER1, .mfilt2 = CCDC_NO_MEDIAN_FILTER2, .alaw = { - .gama_wd = 2, + .gamma_wd = 2, }, .blk_clamp = { .sample_pixel = 1, @@ -303,8 +303,8 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) } if (ccdcparam->alaw.enable) { - if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 || - ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) { + if (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_13_4 || + ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) { dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n"); return -EINVAL; } @@ -680,8 +680,8 @@ static int ccdc_config_raw(void) /* Enable and configure aLaw register if needed */ if (config_params->alaw.enable) { val |= (CCDC_ALAW_ENABLE | - ((config_params->alaw.gama_wd & - CCDC_ALAW_GAMA_WD_MASK) << + ((config_params->alaw.gamma_wd & + CCDC_ALAW_GAMMA_WD_MASK) << CCDC_GAMMAWD_INPUT_SHIFT)); } diff --git a/drivers/media/platform/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h index d6d2ef0533b5..2e1946e0b99f 100644 --- a/drivers/media/platform/davinci/dm355_ccdc_regs.h +++ b/drivers/media/platform/davinci/dm355_ccdc_regs.h @@ -153,7 +153,7 @@ #define CCDC_VDHDEN_ENABLE (1 << 16) #define CCDC_LPF_ENABLE (1 << 14) #define CCDC_ALAW_ENABLE 1 -#define CCDC_ALAW_GAMA_WD_MASK 7 +#define CCDC_ALAW_GAMMA_WD_MASK 7 #define CCDC_REC656IF_BT656_EN 3 #define CCDC_FMTCFG_FMTMODE_MASK 3 diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index 5050f9265f48..abc3ae36645c 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -604,7 +604,7 @@ static int isif_config_raw(void) if (module_params->compress.alg == ISIF_ALAW) val |= ISIF_ALAW_ENABLE; - val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT); + val |= (params->data_msb << ISIF_ALAW_GAMMA_WD_SHIFT); regw(val, CGAMMAWD); /* Configure DPCM compression settings */ diff --git a/drivers/media/platform/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h index aa69a463c122..3993aece821b 100644 --- a/drivers/media/platform/davinci/isif_regs.h +++ b/drivers/media/platform/davinci/isif_regs.h @@ -203,8 +203,8 @@ #define ISIF_LPF_MASK 1 /* GAMMAWD registers */ -#define ISIF_ALAW_GAMA_WD_MASK 0xF -#define ISIF_ALAW_GAMA_WD_SHIFT 1 +#define ISIF_ALAW_GAMMA_WD_MASK 0xF +#define ISIF_ALAW_GAMMA_WD_SHIFT 1 #define ISIF_ALAW_ENABLE 1 #define ISIF_GAMMAWD_CFA_SHIFT 5 diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h index adf2fe4bf0bb..c669a9fb75e5 100644 --- a/include/media/davinci/dm355_ccdc.h +++ b/include/media/davinci/dm355_ccdc.h @@ -38,7 +38,7 @@ enum ccdc_sample_line { CCDC_SAMPLE_16LINES }; -/* enum for Alaw gama width */ +/* enum for Alaw gamma width */ enum ccdc_gamma_width { CCDC_GAMMA_BITS_13_4, CCDC_GAMMA_BITS_12_3, @@ -97,8 +97,8 @@ enum ccdc_mfilt2 { struct ccdc_a_law { /* Enable/disable A-Law */ unsigned char enable; - /* Gama Width Input */ - enum ccdc_gamma_width gama_wd; + /* Gamma Width Input */ + enum ccdc_gamma_width gamma_wd; }; /* structure for Black Clamping */ -- cgit From a8451ed205774398084de4a71e6794b86c94b5e5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Feb 2013 15:12:01 -0300 Subject: [media] blackfin: replace V4L2_IN/OUT_CAP_CUSTOM_TIMINGS by DV_TIMINGS The use of V4L2_IN/OUT_CAP_CUSTOM_TIMINGS is obsolete, use DV_TIMINGS instead. Note that V4L2_IN/OUT_CAP_CUSTOM_TIMINGS is just a #define for V4L2_IN/OUT_CAP_DV_TIMINGS. At some point in the future these CUSTOM_TIMINGS defines might be removed. Signed-off-by: Hans Verkuil Acked-by: Scott Jiang Signed-off-by: Mauro Carvalho Chehab --- arch/blackfin/mach-bf609/boards/ezkit.c | 8 ++++---- drivers/media/platform/blackfin/bfin_capture.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c index 61c1f47a4bf2..97d701639585 100644 --- a/arch/blackfin/mach-bf609/boards/ezkit.c +++ b/arch/blackfin/mach-bf609/boards/ezkit.c @@ -936,19 +936,19 @@ static struct v4l2_input adv7842_inputs[] = { .index = 2, .name = "Component", .type = V4L2_INPUT_TYPE_CAMERA, - .capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS, + .capabilities = V4L2_IN_CAP_DV_TIMINGS, }, { .index = 3, .name = "VGA", .type = V4L2_INPUT_TYPE_CAMERA, - .capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS, + .capabilities = V4L2_IN_CAP_DV_TIMINGS, }, { .index = 4, .name = "HDMI", .type = V4L2_INPUT_TYPE_CAMERA, - .capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS, + .capabilities = V4L2_IN_CAP_DV_TIMINGS, }, }; @@ -1074,7 +1074,7 @@ static struct v4l2_output adv7511_outputs[] = { .index = 0, .name = "HDMI", .type = V4L2_INPUT_TYPE_CAMERA, - .capabilities = V4L2_OUT_CAP_CUSTOM_TIMINGS, + .capabilities = V4L2_OUT_CAP_DV_TIMINGS, }, }; diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 8ffe42aabd85..476cfc88d144 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -384,7 +384,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) params.ppi_control = bcap_dev->cfg->ppi_control; params.int_mask = bcap_dev->cfg->int_mask; if (bcap_dev->cfg->inputs[bcap_dev->cur_input].capabilities - & V4L2_IN_CAP_CUSTOM_TIMINGS) { + & V4L2_IN_CAP_DV_TIMINGS) { struct v4l2_bt_timings *bt = &bcap_dev->dv_timings.bt; params.hdelay = bt->hsync + bt->hbackporch; @@ -1111,7 +1111,7 @@ static int bcap_probe(struct platform_device *pdev) } bcap_dev->std = std; } - if (config->inputs[0].capabilities & V4L2_IN_CAP_CUSTOM_TIMINGS) { + if (config->inputs[0].capabilities & V4L2_IN_CAP_DV_TIMINGS) { struct v4l2_dv_timings dv_timings; ret = v4l2_subdev_call(bcap_dev->sd, video, g_dv_timings, &dv_timings); -- cgit From 30ee400614385ac49f4c9b4bc03d77ff8f07a61e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Feb 2013 12:07:16 -0200 Subject: clk: mxs: Fix sparse warnings Fix the following sparse warnings: drivers/clk/mxs/clk.c:17:1: warning: symbol 'mxs_lock' was not declared. Should it be static? drivers/clk/mxs/clk.c:19:5: warning: symbol 'mxs_clk_wait' was not declared. Should it be static? Signed-off-by: Fabio Estevam Acked-by: Shawn Guo Signed-off-by: Mike Turquette --- drivers/clk/mxs/clk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c index b24d56067c80..5301bce8957b 100644 --- a/drivers/clk/mxs/clk.c +++ b/drivers/clk/mxs/clk.c @@ -13,6 +13,7 @@ #include #include #include +#include "clk.h" DEFINE_SPINLOCK(mxs_lock); -- cgit From 3d6ee287a3e341c88eafd0b4620b12d640b3736b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 12 Mar 2013 20:26:02 +0100 Subject: clk: Introduce optional is_prepared callback To reflect whether a clk_hw is prepared the clk_hw may implement the optional is_prepared callback. If not implemented we fall back to use the software prepare counter. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 21 +++++++++++++++++++++ include/linux/clk-provider.h | 6 ++++++ 2 files changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index ed87b2405806..7571b5054f3c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -451,6 +451,27 @@ unsigned long __clk_get_flags(struct clk *clk) return !clk ? 0 : clk->flags; } +bool __clk_is_prepared(struct clk *clk) +{ + int ret; + + if (!clk) + return false; + + /* + * .is_prepared is optional for clocks that can prepare + * fall back to software usage counter if it is missing + */ + if (!clk->ops->is_prepared) { + ret = clk->prepare_count ? 1 : 0; + goto out; + } + + ret = clk->ops->is_prepared(clk->hw); +out: + return !!ret; +} + bool __clk_is_enabled(struct clk *clk) { int ret; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7f197d7addb0..ee946862e058 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -45,6 +45,10 @@ struct clk_hw; * undo any work done in the @prepare callback. Called with * prepare_lock held. * + * @is_prepared: Queries the hardware to determine if the clock is prepared. + * This function is allowed to sleep. Optional, if this op is not + * set then the prepare count will be used. + * * @enable: Enable the clock atomically. This must not return until the * clock is generating a valid clock signal, usable by consumer * devices. Called with enable_lock held. This function must not @@ -108,6 +112,7 @@ struct clk_hw; struct clk_ops { int (*prepare)(struct clk_hw *hw); void (*unprepare)(struct clk_hw *hw); + int (*is_prepared)(struct clk_hw *hw); int (*enable)(struct clk_hw *hw); void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); @@ -351,6 +356,7 @@ unsigned int __clk_get_enable_count(struct clk *clk); unsigned int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); +bool __clk_is_prepared(struct clk *clk); bool __clk_is_enabled(struct clk *clk); struct clk *__clk_lookup(const char *name); -- cgit From 1c155b3dfe08351f5fc811062648969f1ba7af53 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 12 Mar 2013 20:26:03 +0100 Subject: clk: Unprepare the unused prepared slow clocks at late init The unused ungated fast clocks are already being disabled from clk_disable_unused at late init. This patch extend this sequence to the slow unused prepared clocks to be unprepared. Unless the optional .is_prepared callback is implemented by a clk_hw the clk_disable_unused sequence will not unprepare any unused clocks, since it will fall back to use the software prepare counter. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette [mturquette@linaro.org: fixed hlist accessors per b67bfe0d] --- drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 7571b5054f3c..c0141f3e1109 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -335,6 +335,28 @@ late_initcall(clk_debug_init); static inline int clk_debug_register(struct clk *clk) { return 0; } #endif +/* caller must hold prepare_lock */ +static void clk_unprepare_unused_subtree(struct clk *clk) +{ + struct clk *child; + + if (!clk) + return; + + hlist_for_each_entry(child, &clk->children, child_node) + clk_unprepare_unused_subtree(child); + + if (clk->prepare_count) + return; + + if (clk->flags & CLK_IGNORE_UNUSED) + return; + + if (__clk_is_prepared(clk)) + if (clk->ops->unprepare) + clk->ops->unprepare(clk->hw); +} + /* caller must hold prepare_lock */ static void clk_disable_unused_subtree(struct clk *clk) { @@ -386,6 +408,12 @@ static int clk_disable_unused(void) hlist_for_each_entry(clk, &clk_orphan_list, child_node) clk_disable_unused_subtree(clk); + hlist_for_each_entry(clk, &clk_root_list, child_node) + clk_unprepare_unused_subtree(clk); + + hlist_for_each_entry(clk, &clk_orphan_list, child_node) + clk_unprepare_unused_subtree(clk); + mutex_unlock(&prepare_lock); return 0; -- cgit From 3cc8247f1dce79511de8bf0f69ab02a46cc315b7 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 12 Mar 2013 20:26:04 +0100 Subject: clk: Introduce optional unprepare_unused callback An unprepare_unused callback is introduced due to the same reasons to why the disable_unused callback was added. During the clk_disable_unused sequence, those clk_hw that needs specific treatment with regards to being unprepared, shall implement the unprepare_unused callback. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 7 +++++-- include/linux/clk-provider.h | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c0141f3e1109..253792a46c08 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -352,9 +352,12 @@ static void clk_unprepare_unused_subtree(struct clk *clk) if (clk->flags & CLK_IGNORE_UNUSED) return; - if (__clk_is_prepared(clk)) - if (clk->ops->unprepare) + if (__clk_is_prepared(clk)) { + if (clk->ops->unprepare_unused) + clk->ops->unprepare_unused(clk->hw); + else if (clk->ops->unprepare) clk->ops->unprepare(clk->hw); + } } /* caller must hold prepare_lock */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index ee946862e058..56e6cc12c796 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -49,6 +49,10 @@ struct clk_hw; * This function is allowed to sleep. Optional, if this op is not * set then the prepare count will be used. * + * @unprepare_unused: Unprepare the clock atomically. Only called from + * clk_disable_unused for prepare clocks with special needs. + * Called with prepare mutex held. This function may sleep. + * * @enable: Enable the clock atomically. This must not return until the * clock is generating a valid clock signal, usable by consumer * devices. Called with enable_lock held. This function must not @@ -113,6 +117,7 @@ struct clk_ops { int (*prepare)(struct clk_hw *hw); void (*unprepare)(struct clk_hw *hw); int (*is_prepared)(struct clk_hw *hw); + void (*unprepare_unused)(struct clk_hw *hw); int (*enable)(struct clk_hw *hw); void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); -- cgit From 2850985f7749abca7fc374a438bc0126ca28c9c4 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 12 Mar 2013 20:26:05 +0100 Subject: clk: ux500: Support is_prepared callback for clk-prcmu To be able to gate unused prcmu clocks from the clk_disable_unused sequence, clk-prcmu now implements the is_prepared callback. Signed-off-by: Ulf Hansson Signed-off-by: Mike Turquette --- drivers/clk/ux500/clk-prcmu.c | 134 +++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 74faa7e3cf59..9d832567c6be 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -20,15 +20,23 @@ struct clk_prcmu { struct clk_hw hw; u8 cg_sel; + int is_prepared; int is_enabled; + int opp_requested; }; /* PRCMU clock operations. */ static int clk_prcmu_prepare(struct clk_hw *hw) { + int ret; struct clk_prcmu *clk = to_clk_prcmu(hw); - return prcmu_request_clock(clk->cg_sel, true); + + ret = prcmu_request_clock(clk->cg_sel, true); + if (!ret) + clk->is_prepared = 1; + + return ret;; } static void clk_prcmu_unprepare(struct clk_hw *hw) @@ -37,6 +45,14 @@ static void clk_prcmu_unprepare(struct clk_hw *hw) if (prcmu_request_clock(clk->cg_sel, false)) pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, hw->init->name); + else + clk->is_prepared = 0; +} + +static int clk_prcmu_is_prepared(struct clk_hw *hw) +{ + struct clk_prcmu *clk = to_clk_prcmu(hw); + return clk->is_prepared; } static int clk_prcmu_enable(struct clk_hw *hw) @@ -79,58 +95,52 @@ static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate, return prcmu_set_clock_rate(clk->cg_sel, rate); } -static int request_ape_opp100(bool enable) -{ - static int reqs; - int err = 0; - - if (enable) { - if (!reqs) - err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, - "clock", 100); - if (!err) - reqs++; - } else { - reqs--; - if (!reqs) - prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, - "clock"); - } - return err; -} - static int clk_prcmu_opp_prepare(struct clk_hw *hw) { int err; struct clk_prcmu *clk = to_clk_prcmu(hw); - err = request_ape_opp100(true); - if (err) { - pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n", - __func__, hw->init->name); - return err; + if (!clk->opp_requested) { + err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, + (char *)__clk_get_name(hw->clk), + 100); + if (err) { + pr_err("clk_prcmu: %s fail req APE OPP for %s.\n", + __func__, hw->init->name); + return err; + } + clk->opp_requested = 1; } err = prcmu_request_clock(clk->cg_sel, true); - if (err) - request_ape_opp100(false); + if (err) { + prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, + (char *)__clk_get_name(hw->clk)); + clk->opp_requested = 0; + return err; + } - return err; + clk->is_prepared = 1; + return 0; } static void clk_prcmu_opp_unprepare(struct clk_hw *hw) { struct clk_prcmu *clk = to_clk_prcmu(hw); - if (prcmu_request_clock(clk->cg_sel, false)) - goto out_error; - if (request_ape_opp100(false)) - goto out_error; - return; - -out_error: - pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, - hw->init->name); + if (prcmu_request_clock(clk->cg_sel, false)) { + pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, + hw->init->name); + return; + } + + if (clk->opp_requested) { + prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, + (char *)__clk_get_name(hw->clk)); + clk->opp_requested = 0; + } + + clk->is_prepared = 0; } static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) @@ -138,38 +148,49 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) int err; struct clk_prcmu *clk = to_clk_prcmu(hw); - err = prcmu_request_ape_opp_100_voltage(true); - if (err) { - pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n", - __func__, hw->init->name); - return err; + if (!clk->opp_requested) { + err = prcmu_request_ape_opp_100_voltage(true); + if (err) { + pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n", + __func__, hw->init->name); + return err; + } + clk->opp_requested = 1; } err = prcmu_request_clock(clk->cg_sel, true); - if (err) + if (err) { prcmu_request_ape_opp_100_voltage(false); + clk->opp_requested = 0; + return err; + } - return err; + clk->is_prepared = 1; + return 0; } static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) { struct clk_prcmu *clk = to_clk_prcmu(hw); - if (prcmu_request_clock(clk->cg_sel, false)) - goto out_error; - if (prcmu_request_ape_opp_100_voltage(false)) - goto out_error; - return; - -out_error: - pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, - hw->init->name); + if (prcmu_request_clock(clk->cg_sel, false)) { + pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, + hw->init->name); + return; + } + + if (clk->opp_requested) { + prcmu_request_ape_opp_100_voltage(false); + clk->opp_requested = 0; + } + + clk->is_prepared = 0; } static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare, + .is_prepared = clk_prcmu_is_prepared, .enable = clk_prcmu_enable, .disable = clk_prcmu_disable, .is_enabled = clk_prcmu_is_enabled, @@ -181,6 +202,7 @@ static struct clk_ops clk_prcmu_scalable_ops = { static struct clk_ops clk_prcmu_gate_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare, + .is_prepared = clk_prcmu_is_prepared, .enable = clk_prcmu_enable, .disable = clk_prcmu_disable, .is_enabled = clk_prcmu_is_enabled, @@ -202,6 +224,7 @@ static struct clk_ops clk_prcmu_rate_ops = { static struct clk_ops clk_prcmu_opp_gate_ops = { .prepare = clk_prcmu_opp_prepare, .unprepare = clk_prcmu_opp_unprepare, + .is_prepared = clk_prcmu_is_prepared, .enable = clk_prcmu_enable, .disable = clk_prcmu_disable, .is_enabled = clk_prcmu_is_enabled, @@ -211,6 +234,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { .prepare = clk_prcmu_opp_volt_prepare, .unprepare = clk_prcmu_opp_volt_unprepare, + .is_prepared = clk_prcmu_is_prepared, .enable = clk_prcmu_enable, .disable = clk_prcmu_disable, .is_enabled = clk_prcmu_is_enabled, @@ -242,7 +266,9 @@ static struct clk *clk_reg_prcmu(const char *name, } clk->cg_sel = cg_sel; + clk->is_prepared = 1; clk->is_enabled = 1; + clk->opp_requested = 0; /* "rate" can be used for changing the initial frequency */ if (rate) prcmu_set_clock_rate(cg_sel, rate); -- cgit From 0ea21a524070f17f0bc06aafd43a2efaa0940d8f Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Fri, 8 Mar 2013 06:22:10 -0300 Subject: [media] davinci: vpbe: fix module build add a null entry in platform_device_id {}. This patch fixes following error: drivers/media/platform/davinci/vpbe_venc: struct platform_device_id is 24 bytes. The last of 3 is: 0x64 0x6d 0x33 0x35 0x35 0x2c 0x76 0x70 0x62 0x65 0x2d 0x76 0x65 0x6e 0x63 0x00 0x00 0x00 0x00 0x00 0x03 0x00 0x00 0x00 FATAL: drivers/media/platform/davinci/vpbe_venc: struct platform_device_id is not terminated with a NULL entry! make[1]: *** [__modpost] Error 1 Reported-by: Sekhar Nori Signed-off-by: Lad, Prabhakar Tested-by: Sekhar Nori Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_osd.c | 3 +++ drivers/media/platform/davinci/vpbe_venc.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c index 12ad17c52ef3..396a51cbede7 100644 --- a/drivers/media/platform/davinci/vpbe_osd.c +++ b/drivers/media/platform/davinci/vpbe_osd.c @@ -52,6 +52,9 @@ static struct platform_device_id vpbe_osd_devtype[] = { .name = DM355_VPBE_OSD_SUBDEV_NAME, .driver_data = VPBE_VERSION_3, }, + { + /* sentinel */ + } }; MODULE_DEVICE_TABLE(platform, vpbe_osd_devtype); diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 9546d268e2db..f15f211a5508 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -51,6 +51,9 @@ static struct platform_device_id vpbe_venc_devtype[] = { .name = DM355_VPBE_VENC_SUBDEV_NAME, .driver_data = VPBE_VERSION_3, }, + { + /* sentinel */ + } }; MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype); -- cgit From 4d10f054f7df600ec8a388091c93b2d976920de0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 19 Mar 2013 15:38:50 +0100 Subject: clocksource: make CLOCKSOURCE_OF_DECLARE type safe This ensures that a function pointer passed into CLOCKSOURCE_OF_DECLARE takes the same arguments that we use for calling that function later. Also fix the extraneous semicolon at end of the CLOCKSOURCE_OF_DECLARE definition. Signed-off-by: Arnd Bergmann Acked-by: Rob Herring --- drivers/clocksource/clksrc-of.c | 3 ++- drivers/clocksource/vt8500_timer.c | 2 +- include/linux/clocksource.h | 11 +++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 3ef11fba781c..37f5325bec95 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c @@ -16,6 +16,7 @@ #include #include +#include extern struct of_device_id __clksrc_of_table[]; @@ -26,7 +27,7 @@ void __init clocksource_of_init(void) { struct device_node *np; const struct of_device_id *match; - void (*init_func)(struct device_node *); + clocksource_of_init_fn init_func; for_each_matching_node_and_match(np, __clksrc_of_table, &match) { init_func = match->data; diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index 242255285597..64f553f04fa4 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c @@ -165,4 +165,4 @@ static void __init vt8500_timer_init(struct device_node *np) 4, 0xf0000000); } -CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init) +CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 08ed5e19d8c6..ac33184b14fd 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -332,16 +332,23 @@ extern int clocksource_mmio_init(void __iomem *, const char *, extern int clocksource_i8253_init(void); +struct device_node; +typedef void(*clocksource_of_init_fn)(struct device_node *); #ifdef CONFIG_CLKSRC_OF extern void clocksource_of_init(void); #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ static const struct of_device_id __clksrc_of_table_##name \ __used __section(__clksrc_of_table) \ - = { .compatible = compat, .data = fn }; + = { .compatible = compat, \ + .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } #else static inline void clocksource_of_init(void) {} -#define CLOCKSOURCE_OF_DECLARE(name, compat, fn) +#define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ + static const struct of_device_id __clksrc_of_table_##name \ + __unused __section(__clksrc_of_table) \ + = { .compatible = compat, \ + .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } #endif #endif /* _LINUX_CLOCKSOURCE_H */ -- cgit From 0e646c52cf0ee186ec50b41c4db8cf81500c8dd1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 11 Mar 2013 16:22:29 +0100 Subject: clk: Add axi-clkgen driver This driver adds support for the AXI clkgen pcore to the common clock framework. The AXI clkgen pcore is a AXI front-end to the MMCM_ADV frequency synthesizer commonly found in Xilinx FPGAs. The AXI clkgen pcore is used in Analog Devices' reference designs targeting Xilinx FPGAs. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mike Turquette --- .../devicetree/bindings/clock/axi-clkgen.txt | 22 ++ drivers/clk/Kconfig | 8 + drivers/clk/Makefile | 1 + drivers/clk/clk-axi-clkgen.c | 331 +++++++++++++++++++++ 4 files changed, 362 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/axi-clkgen.txt create mode 100644 drivers/clk/clk-axi-clkgen.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt new file mode 100644 index 000000000000..028b493e97ff --- /dev/null +++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt @@ -0,0 +1,22 @@ +Binding for the axi-clkgen clock generator + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "adi,axi-clkgen". +- #clock-cells : from common clock binding; Should always be set to 0. +- reg : Address and length of the axi-clkgen register set. +- clocks : Phandle and clock specifier for the parent clock. + +Optional properties: +- clock-output-names : From common clock binding. + +Example: + clock@0xff000000 { + compatible = "adi,axi-clkgen"; + #clock-cells = <0>; + reg = <0xff000000 0x1000>; + clocks = <&osc 1>; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a47e6ee98b8c..a64caefdba12 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -63,6 +63,14 @@ config CLK_TWL6040 McPDM. McPDM module is using the external bit clock on the McPDM bus as functional clock. +config COMMON_CLK_AXI_CLKGEN + tristate "AXI clkgen driver" + depends on ARCH_ZYNQ || MICROBLAZE + help + ---help--- + Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx + FPGAs. It is commonly used in Analog Devices' reference designs. + endmenu source "drivers/clk/mvebu/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 300d4775d926..1c22f9dc721d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_X86) += x86/ # Chip specific +obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c new file mode 100644 index 000000000000..8137327847c3 --- /dev/null +++ b/drivers/clk/clk-axi-clkgen.c @@ -0,0 +1,331 @@ +/* + * AXI clkgen driver + * + * Copyright 2012-2013 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04 +#define AXI_CLKGEN_REG_CLK_OUT1 0x08 +#define AXI_CLKGEN_REG_CLK_OUT2 0x0c +#define AXI_CLKGEN_REG_CLK_DIV 0x10 +#define AXI_CLKGEN_REG_CLK_FB1 0x14 +#define AXI_CLKGEN_REG_CLK_FB2 0x18 +#define AXI_CLKGEN_REG_LOCK1 0x1c +#define AXI_CLKGEN_REG_LOCK2 0x20 +#define AXI_CLKGEN_REG_LOCK3 0x24 +#define AXI_CLKGEN_REG_FILTER1 0x28 +#define AXI_CLKGEN_REG_FILTER2 0x2c + +struct axi_clkgen { + void __iomem *base; + struct clk_hw clk_hw; +}; + +static uint32_t axi_clkgen_lookup_filter(unsigned int m) +{ + switch (m) { + case 0: + return 0x01001990; + case 1: + return 0x01001190; + case 2: + return 0x01009890; + case 3: + return 0x01001890; + case 4: + return 0x01008890; + case 5 ... 8: + return 0x01009090; + case 9 ... 11: + return 0x01000890; + case 12: + return 0x08009090; + case 13 ... 22: + return 0x01001090; + case 23 ... 36: + return 0x01008090; + case 37 ... 46: + return 0x08001090; + default: + return 0x08008090; + } +} + +static const uint32_t axi_clkgen_lock_table[] = { + 0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8, + 0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8, + 0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339, + 0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271, + 0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4, + 0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190, + 0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e, + 0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c, + 0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113, +}; + +static uint32_t axi_clkgen_lookup_lock(unsigned int m) +{ + if (m < ARRAY_SIZE(axi_clkgen_lock_table)) + return axi_clkgen_lock_table[m]; + return 0x1f1f00fa; +} + +static const unsigned int fpfd_min = 10000; +static const unsigned int fpfd_max = 300000; +static const unsigned int fvco_min = 600000; +static const unsigned int fvco_max = 1200000; + +static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout, + unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout) +{ + unsigned long d, d_min, d_max, _d_min, _d_max; + unsigned long m, m_min, m_max; + unsigned long f, dout, best_f, fvco; + + fin /= 1000; + fout /= 1000; + + best_f = ULONG_MAX; + *best_d = 0; + *best_m = 0; + *best_dout = 0; + + d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1); + d_max = min_t(unsigned long, fin / fpfd_min, 80); + + m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1); + m_max = min_t(unsigned long, fvco_max * d_max / fin, 64); + + for (m = m_min; m <= m_max; m++) { + _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max)); + _d_max = min(d_max, fin * m / fvco_min); + + for (d = _d_min; d <= _d_max; d++) { + fvco = fin * m / d; + + dout = DIV_ROUND_CLOSEST(fvco, fout); + dout = clamp_t(unsigned long, dout, 1, 128); + f = fvco / dout; + if (abs(f - fout) < abs(best_f - fout)) { + best_f = f; + *best_d = d; + *best_m = m; + *best_dout = dout; + if (best_f == fout) + return; + } + } + } +} + +static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low, + unsigned int *high, unsigned int *edge, unsigned int *nocount) +{ + if (divider == 1) + *nocount = 1; + else + *nocount = 0; + + *high = divider / 2; + *edge = divider % 2; + *low = divider - *high; +} + +static void axi_clkgen_write(struct axi_clkgen *axi_clkgen, + unsigned int reg, unsigned int val) +{ + writel(val, axi_clkgen->base + reg); +} + +static void axi_clkgen_read(struct axi_clkgen *axi_clkgen, + unsigned int reg, unsigned int *val) +{ + *val = readl(axi_clkgen->base + reg); +} + +static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) +{ + return container_of(clk_hw, struct axi_clkgen, clk_hw); +} + +static int axi_clkgen_set_rate(struct clk_hw *clk_hw, + unsigned long rate, unsigned long parent_rate) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + unsigned int d, m, dout; + unsigned int nocount; + unsigned int high; + unsigned int edge; + unsigned int low; + uint32_t filter; + uint32_t lock; + + if (parent_rate == 0 || rate == 0) + return -EINVAL; + + axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout); + + if (d == 0 || dout == 0 || m == 0) + return -EINVAL; + + filter = axi_clkgen_lookup_filter(m - 1); + lock = axi_clkgen_lookup_lock(m - 1); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0); + + axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, + (high << 6) | low); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2, + (edge << 7) | (nocount << 6)); + + axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, + (edge << 13) | (nocount << 12) | (high << 6) | low); + + axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, + (high << 6) | low); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2, + (edge << 7) | (nocount << 6)); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2, + (((lock >> 16) & 0x1f) << 10) | 0x1); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3, + (((lock >> 24) & 0x1f) << 10) | 0x3e9); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16); + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1); + + return 0; +} + +static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + unsigned int d, m, dout; + + axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout); + + if (d == 0 || dout == 0 || m == 0) + return -EINVAL; + + return *parent_rate / d * m / dout; +} + +static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, + unsigned long parent_rate) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + unsigned int d, m, dout; + unsigned int reg; + unsigned long long tmp; + + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, ®); + dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, ®); + d = (reg & 0x3f) + ((reg >> 6) & 0x3f); + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, ®); + m = (reg & 0x3f) + ((reg >> 6) & 0x3f); + + if (d == 0 || dout == 0) + return 0; + + tmp = (unsigned long long)(parent_rate / d) * m; + do_div(tmp, dout); + + if (tmp > ULONG_MAX) + return ULONG_MAX; + + return tmp; +} + +static const struct clk_ops axi_clkgen_ops = { + .recalc_rate = axi_clkgen_recalc_rate, + .round_rate = axi_clkgen_round_rate, + .set_rate = axi_clkgen_set_rate, +}; + +static int axi_clkgen_probe(struct platform_device *pdev) +{ + struct axi_clkgen *axi_clkgen; + struct clk_init_data init; + const char *parent_name; + const char *clk_name; + struct resource *mem; + struct clk *clk; + + axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL); + if (!axi_clkgen) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(axi_clkgen->base)) + return PTR_ERR(axi_clkgen->base); + + parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); + if (!parent_name) + return -EINVAL; + + clk_name = pdev->dev.of_node->name; + of_property_read_string(pdev->dev.of_node, "clock-output-names", + &clk_name); + + init.name = clk_name; + init.ops = &axi_clkgen_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + axi_clkgen->clk_hw.init = &init; + clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, + clk); +} + +static int axi_clkgen_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + + return 0; +} + +static const struct of_device_id axi_clkgen_ids[] = { + { .compatible = "adi,axi-clkgen-1.00.a" }, + { }, +}; +MODULE_DEVICE_TABLE(of, axi_clkgen_ids); + +static struct platform_driver axi_clkgen_driver = { + .driver = { + .name = "adi-axi-clkgen", + .owner = THIS_MODULE, + .of_match_table = axi_clkgen_ids, + }, + .probe = axi_clkgen_probe, + .remove = axi_clkgen_remove, +}; +module_platform_driver(axi_clkgen_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator"); -- cgit From b7d44d9487a11e835de10908f4ab30b4290c0b7f Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Wed, 20 Mar 2013 11:28:51 +1030 Subject: hw_random: free rng_buffer at module exit rng-core module allocates rng_buffer by kmalloc() since commit f7f154f1246ccc5a0a7e9ce50932627d60a0c878. But this buffer won't be freed and there is a memory leak possibility at module exit. Signed-off-by: Satoru Takeuchi Signed-off-by: Rusty Russell --- drivers/char/hw_random/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 69ae5972713c..a0f7724852eb 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -380,6 +380,15 @@ void hwrng_unregister(struct hwrng *rng) } EXPORT_SYMBOL_GPL(hwrng_unregister); +static void __exit hwrng_exit(void) +{ + mutex_lock(&rng_mutex); + BUG_ON(current_rng); + kfree(rng_buffer); + mutex_unlock(&rng_mutex); +} + +module_exit(hwrng_exit); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); -- cgit From 73640c991e2f2804939af70567b23e4c54b7c266 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 18 Mar 2013 13:22:18 +1030 Subject: tools/virtio: fix build for 3.8 Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/vhost/test.c | 4 +++- tools/virtio/Makefile | 2 +- tools/virtio/linux/virtio.h | 7 ++++++- tools/virtio/virtio_test.c | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 91d6f060aade..329d3021d059 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -275,7 +275,9 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl, return vhost_test_reset_owner(n); default: mutex_lock(&n->dev.mutex); - r = vhost_dev_ioctl(&n->dev, ioctl, arg); + r = vhost_dev_ioctl(&n->dev, ioctl, argp); + if (r == -ENOIOCTLCMD) + r = vhost_vring_ioctl(&n->dev, ioctl, argp); vhost_test_flush(n); mutex_unlock(&n->dev.mutex); return r; diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile index d1d442ed106a..b48c4329e644 100644 --- a/tools/virtio/Makefile +++ b/tools/virtio/Makefile @@ -1,7 +1,7 @@ all: test mod test: virtio_test virtio_test: virtio_ring.o virtio_test.o -CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -MMD +CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD vpath %.c ../../drivers/virtio mod: ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index 81847dd08bd0..390c4cb3b018 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -85,6 +85,8 @@ typedef __u16 u16; typedef enum { GFP_KERNEL, GFP_ATOMIC, + __GFP_HIGHMEM, + __GFP_HIGH } gfp_t; typedef enum { IRQ_NONE, @@ -163,6 +165,8 @@ struct virtqueue { void (*callback)(struct virtqueue *vq); const char *name; struct virtio_device *vdev; + unsigned int index; + unsigned int num_free; void *priv; }; @@ -206,7 +210,8 @@ bool virtqueue_enable_cb(struct virtqueue *vq); bool virtqueue_enable_cb_delayed(struct virtqueue *vq); void *virtqueue_detach_unused_buf(struct virtqueue *vq); -struct virtqueue *vring_new_virtqueue(unsigned int num, +struct virtqueue *vring_new_virtqueue(unsigned int index, + unsigned int num, unsigned int vring_align, struct virtio_device *vdev, bool weak_barriers, diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index fcc9aa25fd08..faf3f0c9d71f 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -92,7 +92,8 @@ static void vq_info_add(struct vdev_info *dev, int num) assert(r >= 0); memset(info->ring, 0, vring_size(num, 4096)); vring_init(&info->vring, num, info->ring, 4096); - info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev, + info->vq = vring_new_virtqueue(info->idx, + info->vring.num, 4096, &dev->vdev, true, info->ring, vq_notify, vq_callback, "test"); assert(info->vq); -- cgit From a9a0fef779074838230e04a322fd2bdc921f4f4f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 18 Mar 2013 13:22:19 +1030 Subject: virtio_ring: expose virtio barriers for use in vringh. The host side of ring needs this logic too. Signed-off-by: Rusty Russell --- drivers/virtio/virtio_ring.c | 33 +++++-------------------- include/linux/virtio_ring.h | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index ffd7e7da5d3b..245177c286ae 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -24,27 +24,6 @@ #include #include -/* virtio guest is communicating with a virtual "device" that actually runs on - * a host processor. Memory barriers are used to control SMP effects. */ -#ifdef CONFIG_SMP -/* Where possible, use SMP barriers which are more lightweight than mandatory - * barriers, because mandatory barriers control MMIO effects on accesses - * through relaxed memory I/O windows (which virtio-pci does not use). */ -#define virtio_mb(vq) \ - do { if ((vq)->weak_barriers) smp_mb(); else mb(); } while(0) -#define virtio_rmb(vq) \ - do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0) -#define virtio_wmb(vq) \ - do { if ((vq)->weak_barriers) smp_wmb(); else wmb(); } while(0) -#else -/* We must force memory ordering even if guest is UP since host could be - * running on another CPU, but SMP barriers are defined to barrier() in that - * configuration. So fall back to mandatory barriers instead. */ -#define virtio_mb(vq) mb() -#define virtio_rmb(vq) rmb() -#define virtio_wmb(vq) wmb() -#endif - #ifdef DEBUG /* For development, we want to crash whenever the ring is screwed. */ #define BAD_RING(_vq, fmt, args...) \ @@ -276,7 +255,7 @@ add_head: /* Descriptors and available array need to be set before we expose the * new available array entries. */ - virtio_wmb(vq); + virtio_wmb(vq->weak_barriers); vq->vring.avail->idx++; vq->num_added++; @@ -312,7 +291,7 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq) START_USE(vq); /* We need to expose available array entries before checking avail * event. */ - virtio_mb(vq); + virtio_mb(vq->weak_barriers); old = vq->vring.avail->idx - vq->num_added; new = vq->vring.avail->idx; @@ -436,7 +415,7 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) } /* Only get used array entries after they have been exposed by host. */ - virtio_rmb(vq); + virtio_rmb(vq->weak_barriers); last_used = (vq->last_used_idx & (vq->vring.num - 1)); i = vq->vring.used->ring[last_used].id; @@ -460,7 +439,7 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) * the read in the next get_buf call. */ if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { vring_used_event(&vq->vring) = vq->last_used_idx; - virtio_mb(vq); + virtio_mb(vq->weak_barriers); } #ifdef DEBUG @@ -513,7 +492,7 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) * entry. Always do both to keep code simple. */ vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; vring_used_event(&vq->vring) = vq->last_used_idx; - virtio_mb(vq); + virtio_mb(vq->weak_barriers); if (unlikely(more_used(vq))) { END_USE(vq); return false; @@ -553,7 +532,7 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) /* TODO: tune this threshold */ bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4; vring_used_event(&vq->vring) = vq->last_used_idx + bufs; - virtio_mb(vq); + virtio_mb(vq->weak_barriers); if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) { END_USE(vq); return false; diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index 63c6ea199519..ca3ad41c2c82 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -4,6 +4,63 @@ #include #include +/* + * Barriers in virtio are tricky. Non-SMP virtio guests can't assume + * they're not on an SMP host system, so they need to assume real + * barriers. Non-SMP virtio hosts could skip the barriers, but does + * anyone care? + * + * For virtio_pci on SMP, we don't need to order with respect to MMIO + * accesses through relaxed memory I/O windows, so smp_mb() et al are + * sufficient. + * + * For using virtio to talk to real devices (eg. other heterogeneous + * CPUs) we do need real barriers. In theory, we could be using both + * kinds of virtio, so it's a runtime decision, and the branch is + * actually quite cheap. + */ + +#ifdef CONFIG_SMP +static inline void virtio_mb(bool weak_barriers) +{ + if (weak_barriers) + smp_mb(); + else + mb(); +} + +static inline void virtio_rmb(bool weak_barriers) +{ + if (weak_barriers) + smp_rmb(); + else + rmb(); +} + +static inline void virtio_wmb(bool weak_barriers) +{ + if (weak_barriers) + smp_wmb(); + else + wmb(); +} +#else +static inline void virtio_mb(bool weak_barriers) +{ + mb(); +} + +static inline void virtio_rmb(bool weak_barriers) +{ + rmb(); +} + +static inline void virtio_wmb(bool weak_barriers) +{ + wmb(); +} +#endif + struct virtio_device; struct virtqueue; -- cgit From f87d0fbb579818fed3eeb0923cc253163ab93039 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 13:50:14 +1030 Subject: vringh: host-side implementation of virtio rings. Getting use of virtio rings correct is tricky, and a recent patch saw an implementation of in-kernel rings (as separate from userspace). This abstracts the business of dealing with the virtio ring layout from the access (userspace or direct); to do this, we use function pointers, which gcc inlines correctly. Signed-off-by: Rusty Russell Acked-by: Michael S. Tsirkin --- drivers/Makefile | 2 +- drivers/vhost/Kconfig | 8 + drivers/vhost/Kconfig.tcm | 1 + drivers/vhost/Makefile | 2 + drivers/vhost/vringh.c | 1007 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/vringh.h | 196 +++++++++ 6 files changed, 1215 insertions(+), 1 deletion(-) create mode 100644 drivers/vhost/vringh.c create mode 100644 include/linux/vringh.h (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index dce39a95fa71..72d28d34ee24 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -123,7 +123,7 @@ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_BCMA) += bcma/ -obj-$(CONFIG_VHOST_NET) += vhost/ +obj-$(CONFIG_VHOST_RING) += vhost/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index bf243177ffe1..85b773a93a5d 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig @@ -1,6 +1,7 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net" depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) + select VHOST_RING ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net @@ -12,3 +13,10 @@ config VHOST_NET if STAGING source "drivers/vhost/Kconfig.tcm" endif + +config VHOST_RING + tristate + ---help--- + This option is selected by any driver which needs to access + the host side of a virtio ring. + diff --git a/drivers/vhost/Kconfig.tcm b/drivers/vhost/Kconfig.tcm index 7e3aa28d999e..c3a8cfa1de72 100644 --- a/drivers/vhost/Kconfig.tcm +++ b/drivers/vhost/Kconfig.tcm @@ -1,6 +1,7 @@ config TCM_VHOST tristate "TCM_VHOST fabric module" depends on TARGET_CORE && EVENTFD && m + select VHOST_RING default n ---help--- Say M here to enable the TCM_VHOST fabric module for use with virtio-scsi guests diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile index a27b053bc9ab..1d37f5e12be6 100644 --- a/drivers/vhost/Makefile +++ b/drivers/vhost/Makefile @@ -2,3 +2,5 @@ obj-$(CONFIG_VHOST_NET) += vhost_net.o vhost_net-y := vhost.o net.o obj-$(CONFIG_TCM_VHOST) += tcm_vhost.o + +obj-$(CONFIG_VHOST_RING) += vringh.o diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c new file mode 100644 index 000000000000..bff0775e258c --- /dev/null +++ b/drivers/vhost/vringh.c @@ -0,0 +1,1007 @@ +/* + * Helpers for the host side of a virtio ring. + * + * Since these may be in userspace, we use (inline) accessors. + */ +#include +#include +#include +#include +#include +#include +#include + +static __printf(1,2) __cold void vringh_bad(const char *fmt, ...) +{ + static DEFINE_RATELIMIT_STATE(vringh_rs, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + if (__ratelimit(&vringh_rs)) { + va_list ap; + va_start(ap, fmt); + printk(KERN_NOTICE "vringh:"); + vprintk(fmt, ap); + va_end(ap); + } +} + +/* Returns vring->num if empty, -ve on error. */ +static inline int __vringh_get_head(const struct vringh *vrh, + int (*getu16)(u16 *val, const u16 *p), + u16 *last_avail_idx) +{ + u16 avail_idx, i, head; + int err; + + err = getu16(&avail_idx, &vrh->vring.avail->idx); + if (err) { + vringh_bad("Failed to access avail idx at %p", + &vrh->vring.avail->idx); + return err; + } + + if (*last_avail_idx == avail_idx) + return vrh->vring.num; + + /* Only get avail ring entries after they have been exposed by guest. */ + virtio_rmb(vrh->weak_barriers); + + i = *last_avail_idx & (vrh->vring.num - 1); + + err = getu16(&head, &vrh->vring.avail->ring[i]); + if (err) { + vringh_bad("Failed to read head: idx %d address %p", + *last_avail_idx, &vrh->vring.avail->ring[i]); + return err; + } + + if (head >= vrh->vring.num) { + vringh_bad("Guest says index %u > %u is available", + head, vrh->vring.num); + return -EINVAL; + } + + (*last_avail_idx)++; + return head; +} + +/* Copy some bytes to/from the iovec. Returns num copied. */ +static inline ssize_t vringh_iov_xfer(struct vringh_kiov *iov, + void *ptr, size_t len, + int (*xfer)(void *addr, void *ptr, + size_t len)) +{ + int err, done = 0; + + while (len && iov->i < iov->used) { + size_t partlen; + + partlen = min(iov->iov[iov->i].iov_len, len); + err = xfer(iov->iov[iov->i].iov_base, ptr, partlen); + if (err) + return err; + done += partlen; + len -= partlen; + ptr += partlen; + iov->consumed += partlen; + iov->iov[iov->i].iov_len -= partlen; + iov->iov[iov->i].iov_base += partlen; + + if (!iov->iov[iov->i].iov_len) { + /* Fix up old iov element then increment. */ + iov->iov[iov->i].iov_len = iov->consumed; + iov->iov[iov->i].iov_base -= iov->consumed; + + iov->consumed = 0; + iov->i++; + } + } + return done; +} + +/* May reduce *len if range is shorter. */ +static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len, + struct vringh_range *range, + bool (*getrange)(struct vringh *, + u64, struct vringh_range *)) +{ + if (addr < range->start || addr > range->end_incl) { + if (!getrange(vrh, addr, range)) + return false; + } + BUG_ON(addr < range->start || addr > range->end_incl); + + /* To end of memory? */ + if (unlikely(addr + *len == 0)) { + if (range->end_incl == -1ULL) + return true; + goto truncate; + } + + /* Otherwise, don't wrap. */ + if (addr + *len < addr) { + vringh_bad("Wrapping descriptor %zu@0x%llx", + *len, (unsigned long long)addr); + return false; + } + + if (unlikely(addr + *len - 1 > range->end_incl)) + goto truncate; + return true; + +truncate: + *len = range->end_incl + 1 - addr; + return true; +} + +static inline bool no_range_check(struct vringh *vrh, u64 addr, size_t *len, + struct vringh_range *range, + bool (*getrange)(struct vringh *, + u64, struct vringh_range *)) +{ + return true; +} + +/* No reason for this code to be inline. */ +static int move_to_indirect(int *up_next, u16 *i, void *addr, + const struct vring_desc *desc, + struct vring_desc **descs, int *desc_max) +{ + /* Indirect tables can't have indirect. */ + if (*up_next != -1) { + vringh_bad("Multilevel indirect %u->%u", *up_next, *i); + return -EINVAL; + } + + if (unlikely(desc->len % sizeof(struct vring_desc))) { + vringh_bad("Strange indirect len %u", desc->len); + return -EINVAL; + } + + /* We will check this when we follow it! */ + if (desc->flags & VRING_DESC_F_NEXT) + *up_next = desc->next; + else + *up_next = -2; + *descs = addr; + *desc_max = desc->len / sizeof(struct vring_desc); + + /* Now, start at the first indirect. */ + *i = 0; + return 0; +} + +static int resize_iovec(struct vringh_kiov *iov, gfp_t gfp) +{ + struct kvec *new; + unsigned int flag, new_num = (iov->max_num & ~VRINGH_IOV_ALLOCATED) * 2; + + if (new_num < 8) + new_num = 8; + + flag = (iov->max_num & VRINGH_IOV_ALLOCATED); + if (flag) + new = krealloc(iov->iov, new_num * sizeof(struct iovec), gfp); + else { + new = kmalloc(new_num * sizeof(struct iovec), gfp); + if (new) { + memcpy(new, iov->iov, + iov->max_num * sizeof(struct iovec)); + flag = VRINGH_IOV_ALLOCATED; + } + } + if (!new) + return -ENOMEM; + iov->iov = new; + iov->max_num = (new_num | flag); + return 0; +} + +static u16 __cold return_from_indirect(const struct vringh *vrh, int *up_next, + struct vring_desc **descs, int *desc_max) +{ + u16 i = *up_next; + + *up_next = -1; + *descs = vrh->vring.desc; + *desc_max = vrh->vring.num; + return i; +} + +static int slow_copy(struct vringh *vrh, void *dst, const void *src, + bool (*rcheck)(struct vringh *vrh, u64 addr, size_t *len, + struct vringh_range *range, + bool (*getrange)(struct vringh *vrh, + u64, + struct vringh_range *)), + bool (*getrange)(struct vringh *vrh, + u64 addr, + struct vringh_range *r), + struct vringh_range *range, + int (*copy)(void *dst, const void *src, size_t len)) +{ + size_t part, len = sizeof(struct vring_desc); + + do { + u64 addr; + int err; + + part = len; + addr = (u64)(unsigned long)src - range->offset; + + if (!rcheck(vrh, addr, &part, range, getrange)) + return -EINVAL; + + err = copy(dst, src, part); + if (err) + return err; + + dst += part; + src += part; + len -= part; + } while (len); + return 0; +} + +static inline int +__vringh_iov(struct vringh *vrh, u16 i, + struct vringh_kiov *riov, + struct vringh_kiov *wiov, + bool (*rcheck)(struct vringh *vrh, u64 addr, size_t *len, + struct vringh_range *range, + bool (*getrange)(struct vringh *, u64, + struct vringh_range *)), + bool (*getrange)(struct vringh *, u64, struct vringh_range *), + gfp_t gfp, + int (*copy)(void *dst, const void *src, size_t len)) +{ + int err, count = 0, up_next, desc_max; + struct vring_desc desc, *descs; + struct vringh_range range = { -1ULL, 0 }, slowrange; + bool slow = false; + + /* We start traversing vring's descriptor table. */ + descs = vrh->vring.desc; + desc_max = vrh->vring.num; + up_next = -1; + + if (riov) + riov->i = riov->used = 0; + else if (wiov) + wiov->i = wiov->used = 0; + else + /* You must want something! */ + BUG(); + + for (;;) { + void *addr; + struct vringh_kiov *iov; + size_t len; + + if (unlikely(slow)) + err = slow_copy(vrh, &desc, &descs[i], rcheck, getrange, + &slowrange, copy); + else + err = copy(&desc, &descs[i], sizeof(desc)); + if (unlikely(err)) + goto fail; + + if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) { + /* Make sure it's OK, and get offset. */ + len = desc.len; + if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { + err = -EINVAL; + goto fail; + } + + if (unlikely(len != desc.len)) { + slow = true; + /* We need to save this range to use offset */ + slowrange = range; + } + + addr = (void *)(long)(desc.addr + range.offset); + err = move_to_indirect(&up_next, &i, addr, &desc, + &descs, &desc_max); + if (err) + goto fail; + continue; + } + + if (count++ == vrh->vring.num) { + vringh_bad("Descriptor loop in %p", descs); + err = -ELOOP; + goto fail; + } + + if (desc.flags & VRING_DESC_F_WRITE) + iov = wiov; + else { + iov = riov; + if (unlikely(wiov && wiov->i)) { + vringh_bad("Readable desc %p after writable", + &descs[i]); + err = -EINVAL; + goto fail; + } + } + + if (!iov) { + vringh_bad("Unexpected %s desc", + !wiov ? "writable" : "readable"); + err = -EPROTO; + goto fail; + } + + again: + /* Make sure it's OK, and get offset. */ + len = desc.len; + if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { + err = -EINVAL; + goto fail; + } + addr = (void *)(unsigned long)(desc.addr + range.offset); + + if (unlikely(iov->used == (iov->max_num & ~VRINGH_IOV_ALLOCATED))) { + err = resize_iovec(iov, gfp); + if (err) + goto fail; + } + + iov->iov[iov->used].iov_base = addr; + iov->iov[iov->used].iov_len = len; + iov->used++; + + if (unlikely(len != desc.len)) { + desc.len -= len; + desc.addr += len; + goto again; + } + + if (desc.flags & VRING_DESC_F_NEXT) { + i = desc.next; + } else { + /* Just in case we need to finish traversing above. */ + if (unlikely(up_next > 0)) { + i = return_from_indirect(vrh, &up_next, + &descs, &desc_max); + slow = false; + } else + break; + } + + if (i >= desc_max) { + vringh_bad("Chained index %u > %u", i, desc_max); + err = -EINVAL; + goto fail; + } + } + + return 0; + +fail: + return err; +} + +static inline int __vringh_complete(struct vringh *vrh, + const struct vring_used_elem *used, + unsigned int num_used, + int (*putu16)(u16 *p, u16 val), + int (*putused)(struct vring_used_elem *dst, + const struct vring_used_elem + *src, unsigned num)) +{ + struct vring_used *used_ring; + int err; + u16 used_idx, off; + + used_ring = vrh->vring.used; + used_idx = vrh->last_used_idx + vrh->completed; + + off = used_idx % vrh->vring.num; + + /* Compiler knows num_used == 1 sometimes, hence extra check */ + if (num_used > 1 && unlikely(off + num_used >= vrh->vring.num)) { + u16 part = vrh->vring.num - off; + err = putused(&used_ring->ring[off], used, part); + if (!err) + err = putused(&used_ring->ring[0], used + part, + num_used - part); + } else + err = putused(&used_ring->ring[off], used, num_used); + + if (err) { + vringh_bad("Failed to write %u used entries %u at %p", + num_used, off, &used_ring->ring[off]); + return err; + } + + /* Make sure buffer is written before we update index. */ + virtio_wmb(vrh->weak_barriers); + + err = putu16(&vrh->vring.used->idx, used_idx + num_used); + if (err) { + vringh_bad("Failed to update used index at %p", + &vrh->vring.used->idx); + return err; + } + + vrh->completed += num_used; + return 0; +} + + +static inline int __vringh_need_notify(struct vringh *vrh, + int (*getu16)(u16 *val, const u16 *p)) +{ + bool notify; + u16 used_event; + int err; + + /* Flush out used index update. This is paired with the + * barrier that the Guest executes when enabling + * interrupts. */ + virtio_mb(vrh->weak_barriers); + + /* Old-style, without event indices. */ + if (!vrh->event_indices) { + u16 flags; + err = getu16(&flags, &vrh->vring.avail->flags); + if (err) { + vringh_bad("Failed to get flags at %p", + &vrh->vring.avail->flags); + return err; + } + return (!(flags & VRING_AVAIL_F_NO_INTERRUPT)); + } + + /* Modern: we know when other side wants to know. */ + err = getu16(&used_event, &vring_used_event(&vrh->vring)); + if (err) { + vringh_bad("Failed to get used event idx at %p", + &vring_used_event(&vrh->vring)); + return err; + } + + /* Just in case we added so many that we wrap. */ + if (unlikely(vrh->completed > 0xffff)) + notify = true; + else + notify = vring_need_event(used_event, + vrh->last_used_idx + vrh->completed, + vrh->last_used_idx); + + vrh->last_used_idx += vrh->completed; + vrh->completed = 0; + return notify; +} + +static inline bool __vringh_notify_enable(struct vringh *vrh, + int (*getu16)(u16 *val, const u16 *p), + int (*putu16)(u16 *p, u16 val)) +{ + u16 avail; + + if (!vrh->event_indices) { + /* Old-school; update flags. */ + if (putu16(&vrh->vring.used->flags, 0) != 0) { + vringh_bad("Clearing used flags %p", + &vrh->vring.used->flags); + return true; + } + } else { + if (putu16(&vring_avail_event(&vrh->vring), + vrh->last_avail_idx) != 0) { + vringh_bad("Updating avail event index %p", + &vring_avail_event(&vrh->vring)); + return true; + } + } + + /* They could have slipped one in as we were doing that: make + * sure it's written, then check again. */ + virtio_mb(vrh->weak_barriers); + + if (getu16(&avail, &vrh->vring.avail->idx) != 0) { + vringh_bad("Failed to check avail idx at %p", + &vrh->vring.avail->idx); + return true; + } + + /* This is unlikely, so we just leave notifications enabled + * (if we're using event_indices, we'll only get one + * notification anyway). */ + return avail == vrh->last_avail_idx; +} + +static inline void __vringh_notify_disable(struct vringh *vrh, + int (*putu16)(u16 *p, u16 val)) +{ + if (!vrh->event_indices) { + /* Old-school; update flags. */ + if (putu16(&vrh->vring.used->flags, VRING_USED_F_NO_NOTIFY)) { + vringh_bad("Setting used flags %p", + &vrh->vring.used->flags); + } + } +} + +/* Userspace access helpers: in this case, addresses are really userspace. */ +static inline int getu16_user(u16 *val, const u16 *p) +{ + return get_user(*val, (__force u16 __user *)p); +} + +static inline int putu16_user(u16 *p, u16 val) +{ + return put_user(val, (__force u16 __user *)p); +} + +static inline int copydesc_user(void *dst, const void *src, size_t len) +{ + return copy_from_user(dst, (__force void __user *)src, len) ? + -EFAULT : 0; +} + +static inline int putused_user(struct vring_used_elem *dst, + const struct vring_used_elem *src, + unsigned int num) +{ + return copy_to_user((__force void __user *)dst, src, + sizeof(*dst) * num) ? -EFAULT : 0; +} + +static inline int xfer_from_user(void *src, void *dst, size_t len) +{ + return copy_from_user(dst, (__force void __user *)src, len) ? + -EFAULT : 0; +} + +static inline int xfer_to_user(void *dst, void *src, size_t len) +{ + return copy_to_user((__force void __user *)dst, src, len) ? + -EFAULT : 0; +} + +/** + * vringh_init_user - initialize a vringh for a userspace vring. + * @vrh: the vringh to initialize. + * @features: the feature bits for this ring. + * @num: the number of elements. + * @weak_barriers: true if we only need memory barriers, not I/O. + * @desc: the userpace descriptor pointer. + * @avail: the userpace avail pointer. + * @used: the userpace used pointer. + * + * Returns an error if num is invalid: you should check pointers + * yourself! + */ +int vringh_init_user(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc __user *desc, + struct vring_avail __user *avail, + struct vring_used __user *used) +{ + /* Sane power of 2 please! */ + if (!num || num > 0xffff || (num & (num - 1))) { + vringh_bad("Bad ring size %u", num); + return -EINVAL; + } + + vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); + vrh->weak_barriers = weak_barriers; + vrh->completed = 0; + vrh->last_avail_idx = 0; + vrh->last_used_idx = 0; + vrh->vring.num = num; + /* vring expects kernel addresses, but only used via accessors. */ + vrh->vring.desc = (__force struct vring_desc *)desc; + vrh->vring.avail = (__force struct vring_avail *)avail; + vrh->vring.used = (__force struct vring_used *)used; + return 0; +} +EXPORT_SYMBOL(vringh_init_user); + +/** + * vringh_getdesc_user - get next available descriptor from userspace ring. + * @vrh: the userspace vring. + * @riov: where to put the readable descriptors (or NULL) + * @wiov: where to put the writable descriptors (or NULL) + * @getrange: function to call to check ranges. + * @head: head index we received, for passing to vringh_complete_user(). + * + * Returns 0 if there was no descriptor, 1 if there was, or -errno. + * + * Note that on error return, you can tell the difference between an + * invalid ring and a single invalid descriptor: in the former case, + * *head will be vrh->vring.num. You may be able to ignore an invalid + * descriptor, but there's not much you can do with an invalid ring. + * + * Note that you may need to clean up riov and wiov, even on error! + */ +int vringh_getdesc_user(struct vringh *vrh, + struct vringh_iov *riov, + struct vringh_iov *wiov, + bool (*getrange)(struct vringh *vrh, + u64 addr, struct vringh_range *r), + u16 *head) +{ + int err; + + *head = vrh->vring.num; + err = __vringh_get_head(vrh, getu16_user, &vrh->last_avail_idx); + if (err < 0) + return err; + + /* Empty... */ + if (err == vrh->vring.num) + return 0; + + /* We need the layouts to be the identical for this to work */ + BUILD_BUG_ON(sizeof(struct vringh_kiov) != sizeof(struct vringh_iov)); + BUILD_BUG_ON(offsetof(struct vringh_kiov, iov) != + offsetof(struct vringh_iov, iov)); + BUILD_BUG_ON(offsetof(struct vringh_kiov, i) != + offsetof(struct vringh_iov, i)); + BUILD_BUG_ON(offsetof(struct vringh_kiov, used) != + offsetof(struct vringh_iov, used)); + BUILD_BUG_ON(offsetof(struct vringh_kiov, max_num) != + offsetof(struct vringh_iov, max_num)); + BUILD_BUG_ON(sizeof(struct iovec) != sizeof(struct kvec)); + BUILD_BUG_ON(offsetof(struct iovec, iov_base) != + offsetof(struct kvec, iov_base)); + BUILD_BUG_ON(offsetof(struct iovec, iov_len) != + offsetof(struct kvec, iov_len)); + BUILD_BUG_ON(sizeof(((struct iovec *)NULL)->iov_base) + != sizeof(((struct kvec *)NULL)->iov_base)); + BUILD_BUG_ON(sizeof(((struct iovec *)NULL)->iov_len) + != sizeof(((struct kvec *)NULL)->iov_len)); + + *head = err; + err = __vringh_iov(vrh, *head, (struct vringh_kiov *)riov, + (struct vringh_kiov *)wiov, + range_check, getrange, GFP_KERNEL, copydesc_user); + if (err) + return err; + + return 1; +} +EXPORT_SYMBOL(vringh_getdesc_user); + +/** + * vringh_iov_pull_user - copy bytes from vring_iov. + * @riov: the riov as passed to vringh_getdesc_user() (updated as we consume) + * @dst: the place to copy. + * @len: the maximum length to copy. + * + * Returns the bytes copied <= len or a negative errno. + */ +ssize_t vringh_iov_pull_user(struct vringh_iov *riov, void *dst, size_t len) +{ + return vringh_iov_xfer((struct vringh_kiov *)riov, + dst, len, xfer_from_user); +} +EXPORT_SYMBOL(vringh_iov_pull_user); + +/** + * vringh_iov_push_user - copy bytes into vring_iov. + * @wiov: the wiov as passed to vringh_getdesc_user() (updated as we consume) + * @dst: the place to copy. + * @len: the maximum length to copy. + * + * Returns the bytes copied <= len or a negative errno. + */ +ssize_t vringh_iov_push_user(struct vringh_iov *wiov, + const void *src, size_t len) +{ + return vringh_iov_xfer((struct vringh_kiov *)wiov, + (void *)src, len, xfer_to_user); +} +EXPORT_SYMBOL(vringh_iov_push_user); + +/** + * vringh_abandon_user - we've decided not to handle the descriptor(s). + * @vrh: the vring. + * @num: the number of descriptors to put back (ie. num + * vringh_get_user() to undo). + * + * The next vringh_get_user() will return the old descriptor(s) again. + */ +void vringh_abandon_user(struct vringh *vrh, unsigned int num) +{ + /* We only update vring_avail_event(vr) when we want to be notified, + * so we haven't changed that yet. */ + vrh->last_avail_idx -= num; +} +EXPORT_SYMBOL(vringh_abandon_user); + +/** + * vringh_complete_user - we've finished with descriptor, publish it. + * @vrh: the vring. + * @head: the head as filled in by vringh_getdesc_user. + * @len: the length of data we have written. + * + * You should check vringh_need_notify_user() after one or more calls + * to this function. + */ +int vringh_complete_user(struct vringh *vrh, u16 head, u32 len) +{ + struct vring_used_elem used; + + used.id = head; + used.len = len; + return __vringh_complete(vrh, &used, 1, putu16_user, putused_user); +} +EXPORT_SYMBOL(vringh_complete_user); + +/** + * vringh_complete_multi_user - we've finished with many descriptors. + * @vrh: the vring. + * @used: the head, length pairs. + * @num_used: the number of used elements. + * + * You should check vringh_need_notify_user() after one or more calls + * to this function. + */ +int vringh_complete_multi_user(struct vringh *vrh, + const struct vring_used_elem used[], + unsigned num_used) +{ + return __vringh_complete(vrh, used, num_used, + putu16_user, putused_user); +} +EXPORT_SYMBOL(vringh_complete_multi_user); + +/** + * vringh_notify_enable_user - we want to know if something changes. + * @vrh: the vring. + * + * This always enables notifications, but returns false if there are + * now more buffers available in the vring. + */ +bool vringh_notify_enable_user(struct vringh *vrh) +{ + return __vringh_notify_enable(vrh, getu16_user, putu16_user); +} +EXPORT_SYMBOL(vringh_notify_enable_user); + +/** + * vringh_notify_disable_user - don't tell us if something changes. + * @vrh: the vring. + * + * This is our normal running state: we disable and then only enable when + * we're going to sleep. + */ +void vringh_notify_disable_user(struct vringh *vrh) +{ + __vringh_notify_disable(vrh, putu16_user); +} +EXPORT_SYMBOL(vringh_notify_disable_user); + +/** + * vringh_need_notify_user - must we tell the other side about used buffers? + * @vrh: the vring we've called vringh_complete_user() on. + * + * Returns -errno or 0 if we don't need to tell the other side, 1 if we do. + */ +int vringh_need_notify_user(struct vringh *vrh) +{ + return __vringh_need_notify(vrh, getu16_user); +} +EXPORT_SYMBOL(vringh_need_notify_user); + +/* Kernelspace access helpers. */ +static inline int getu16_kern(u16 *val, const u16 *p) +{ + *val = ACCESS_ONCE(*p); + return 0; +} + +static inline int putu16_kern(u16 *p, u16 val) +{ + ACCESS_ONCE(*p) = val; + return 0; +} + +static inline int copydesc_kern(void *dst, const void *src, size_t len) +{ + memcpy(dst, src, len); + return 0; +} + +static inline int putused_kern(struct vring_used_elem *dst, + const struct vring_used_elem *src, + unsigned int num) +{ + memcpy(dst, src, num * sizeof(*dst)); + return 0; +} + +static inline int xfer_kern(void *src, void *dst, size_t len) +{ + memcpy(dst, src, len); + return 0; +} + +/** + * vringh_init_kern - initialize a vringh for a kernelspace vring. + * @vrh: the vringh to initialize. + * @features: the feature bits for this ring. + * @num: the number of elements. + * @weak_barriers: true if we only need memory barriers, not I/O. + * @desc: the userpace descriptor pointer. + * @avail: the userpace avail pointer. + * @used: the userpace used pointer. + * + * Returns an error if num is invalid. + */ +int vringh_init_kern(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc *desc, + struct vring_avail *avail, + struct vring_used *used) +{ + /* Sane power of 2 please! */ + if (!num || num > 0xffff || (num & (num - 1))) { + vringh_bad("Bad ring size %u", num); + return -EINVAL; + } + + vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); + vrh->weak_barriers = weak_barriers; + vrh->completed = 0; + vrh->last_avail_idx = 0; + vrh->last_used_idx = 0; + vrh->vring.num = num; + vrh->vring.desc = desc; + vrh->vring.avail = avail; + vrh->vring.used = used; + return 0; +} +EXPORT_SYMBOL(vringh_init_kern); + +/** + * vringh_getdesc_kern - get next available descriptor from kernelspace ring. + * @vrh: the kernelspace vring. + * @riov: where to put the readable descriptors (or NULL) + * @wiov: where to put the writable descriptors (or NULL) + * @head: head index we received, for passing to vringh_complete_kern(). + * @gfp: flags for allocating larger riov/wiov. + * + * Returns 0 if there was no descriptor, 1 if there was, or -errno. + * + * Note that on error return, you can tell the difference between an + * invalid ring and a single invalid descriptor: in the former case, + * *head will be vrh->vring.num. You may be able to ignore an invalid + * descriptor, but there's not much you can do with an invalid ring. + * + * Note that you may need to clean up riov and wiov, even on error! + */ +int vringh_getdesc_kern(struct vringh *vrh, + struct vringh_kiov *riov, + struct vringh_kiov *wiov, + u16 *head, + gfp_t gfp) +{ + int err; + + err = __vringh_get_head(vrh, getu16_kern, &vrh->last_avail_idx); + if (err < 0) + return err; + + /* Empty... */ + if (err == vrh->vring.num) + return 0; + + *head = err; + err = __vringh_iov(vrh, *head, riov, wiov, no_range_check, NULL, + gfp, copydesc_kern); + if (err) + return err; + + return 1; +} +EXPORT_SYMBOL(vringh_getdesc_kern); + +/** + * vringh_iov_pull_kern - copy bytes from vring_iov. + * @riov: the riov as passed to vringh_getdesc_kern() (updated as we consume) + * @dst: the place to copy. + * @len: the maximum length to copy. + * + * Returns the bytes copied <= len or a negative errno. + */ +ssize_t vringh_iov_pull_kern(struct vringh_kiov *riov, void *dst, size_t len) +{ + return vringh_iov_xfer(riov, dst, len, xfer_kern); +} +EXPORT_SYMBOL(vringh_iov_pull_kern); + +/** + * vringh_iov_push_kern - copy bytes into vring_iov. + * @wiov: the wiov as passed to vringh_getdesc_kern() (updated as we consume) + * @dst: the place to copy. + * @len: the maximum length to copy. + * + * Returns the bytes copied <= len or a negative errno. + */ +ssize_t vringh_iov_push_kern(struct vringh_kiov *wiov, + const void *src, size_t len) +{ + return vringh_iov_xfer(wiov, (void *)src, len, xfer_kern); +} +EXPORT_SYMBOL(vringh_iov_push_kern); + +/** + * vringh_abandon_kern - we've decided not to handle the descriptor(s). + * @vrh: the vring. + * @num: the number of descriptors to put back (ie. num + * vringh_get_kern() to undo). + * + * The next vringh_get_kern() will return the old descriptor(s) again. + */ +void vringh_abandon_kern(struct vringh *vrh, unsigned int num) +{ + /* We only update vring_avail_event(vr) when we want to be notified, + * so we haven't changed that yet. */ + vrh->last_avail_idx -= num; +} +EXPORT_SYMBOL(vringh_abandon_kern); + +/** + * vringh_complete_kern - we've finished with descriptor, publish it. + * @vrh: the vring. + * @head: the head as filled in by vringh_getdesc_kern. + * @len: the length of data we have written. + * + * You should check vringh_need_notify_kern() after one or more calls + * to this function. + */ +int vringh_complete_kern(struct vringh *vrh, u16 head, u32 len) +{ + struct vring_used_elem used; + + used.id = head; + used.len = len; + + return __vringh_complete(vrh, &used, 1, putu16_kern, putused_kern); +} +EXPORT_SYMBOL(vringh_complete_kern); + +/** + * vringh_notify_enable_kern - we want to know if something changes. + * @vrh: the vring. + * + * This always enables notifications, but returns false if there are + * now more buffers available in the vring. + */ +bool vringh_notify_enable_kern(struct vringh *vrh) +{ + return __vringh_notify_enable(vrh, getu16_kern, putu16_kern); +} +EXPORT_SYMBOL(vringh_notify_enable_kern); + +/** + * vringh_notify_disable_kern - don't tell us if something changes. + * @vrh: the vring. + * + * This is our normal running state: we disable and then only enable when + * we're going to sleep. + */ +void vringh_notify_disable_kern(struct vringh *vrh) +{ + __vringh_notify_disable(vrh, putu16_kern); +} +EXPORT_SYMBOL(vringh_notify_disable_kern); + +/** + * vringh_need_notify_kern - must we tell the other side about used buffers? + * @vrh: the vring we've called vringh_complete_kern() on. + * + * Returns -errno or 0 if we don't need to tell the other side, 1 if we do. + */ +int vringh_need_notify_kern(struct vringh *vrh) +{ + return __vringh_need_notify(vrh, getu16_kern); +} +EXPORT_SYMBOL(vringh_need_notify_kern); diff --git a/include/linux/vringh.h b/include/linux/vringh.h new file mode 100644 index 000000000000..b8f086625c49 --- /dev/null +++ b/include/linux/vringh.h @@ -0,0 +1,196 @@ +/* + * Linux host-side vring helpers; for when the kernel needs to access + * someone else's vring. + * + * Copyright IBM Corporation, 2013. + * Parts taken from drivers/vhost/vhost.c Copyright 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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. + * + * Written by: Rusty Russell + */ +#ifndef _LINUX_VRINGH_H +#define _LINUX_VRINGH_H +#include +#include +#include +#include + +/* virtio_ring with information needed for host access. */ +struct vringh { + /* Guest publishes used event idx (note: we always do). */ + bool event_indices; + + /* Can we get away with weak barriers? */ + bool weak_barriers; + + /* Last available index we saw (ie. where we're up to). */ + u16 last_avail_idx; + + /* Last index we used. */ + u16 last_used_idx; + + /* How many descriptors we've completed since last need_notify(). */ + u32 completed; + + /* The vring (note: it may contain user pointers!) */ + struct vring vring; +}; + +/* The memory the vring can access, and what offset to apply. */ +struct vringh_range { + u64 start, end_incl; + u64 offset; +}; + +/** + * struct vringh_iov - iovec mangler. + * + * Mangles iovec in place, and restores it. + * Remaining data is iov + i, of used - i elements. + */ +struct vringh_iov { + struct iovec *iov; + size_t consumed; /* Within iov[i] */ + unsigned i, used, max_num; +}; + +/** + * struct vringh_iov - kvec mangler. + * + * Mangles kvec in place, and restores it. + * Remaining data is iov + i, of used - i elements. + */ +struct vringh_kiov { + struct kvec *iov; + size_t consumed; /* Within iov[i] */ + unsigned i, used, max_num; +}; + +/* Flag on max_num to indicate we're kmalloced. */ +#define VRINGH_IOV_ALLOCATED 0x8000000 + +/* Helpers for userspace vrings. */ +int vringh_init_user(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc __user *desc, + struct vring_avail __user *avail, + struct vring_used __user *used); + +static inline void vringh_iov_init(struct vringh_iov *iov, + struct iovec *iovec, unsigned num) +{ + iov->used = iov->i = 0; + iov->consumed = 0; + iov->max_num = num; + iov->iov = iovec; +} + +static inline void vringh_iov_reset(struct vringh_iov *iov) +{ + iov->iov[iov->i].iov_len += iov->consumed; + iov->iov[iov->i].iov_base -= iov->consumed; + iov->consumed = 0; + iov->i = 0; +} + +static inline void vringh_iov_cleanup(struct vringh_iov *iov) +{ + if (iov->max_num & VRINGH_IOV_ALLOCATED) + kfree(iov->iov); + iov->max_num = iov->used = iov->i = iov->consumed = 0; + iov->iov = NULL; +} + +/* Convert a descriptor into iovecs. */ +int vringh_getdesc_user(struct vringh *vrh, + struct vringh_iov *riov, + struct vringh_iov *wiov, + bool (*getrange)(struct vringh *vrh, + u64 addr, struct vringh_range *r), + u16 *head); + +/* Copy bytes from readable vsg, consuming it (and incrementing wiov->i). */ +ssize_t vringh_iov_pull_user(struct vringh_iov *riov, void *dst, size_t len); + +/* Copy bytes into writable vsg, consuming it (and incrementing wiov->i). */ +ssize_t vringh_iov_push_user(struct vringh_iov *wiov, + const void *src, size_t len); + +/* Mark a descriptor as used. */ +int vringh_complete_user(struct vringh *vrh, u16 head, u32 len); +int vringh_complete_multi_user(struct vringh *vrh, + const struct vring_used_elem used[], + unsigned num_used); + +/* Pretend we've never seen descriptor (for easy error handling). */ +void vringh_abandon_user(struct vringh *vrh, unsigned int num); + +/* Do we need to fire the eventfd to notify the other side? */ +int vringh_need_notify_user(struct vringh *vrh); + +bool vringh_notify_enable_user(struct vringh *vrh); +void vringh_notify_disable_user(struct vringh *vrh); + +/* Helpers for kernelspace vrings. */ +int vringh_init_kern(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc *desc, + struct vring_avail *avail, + struct vring_used *used); + +static inline void vringh_kiov_init(struct vringh_kiov *kiov, + struct kvec *kvec, unsigned num) +{ + kiov->used = kiov->i = 0; + kiov->consumed = 0; + kiov->max_num = num; + kiov->iov = kvec; +} + +static inline void vringh_kiov_reset(struct vringh_kiov *kiov) +{ + kiov->iov[kiov->i].iov_len += kiov->consumed; + kiov->iov[kiov->i].iov_base -= kiov->consumed; + kiov->consumed = 0; + kiov->i = 0; +} + +static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov) +{ + if (kiov->max_num & VRINGH_IOV_ALLOCATED) + kfree(kiov->iov); + kiov->max_num = kiov->used = kiov->i = kiov->consumed = 0; + kiov->iov = NULL; +} + +int vringh_getdesc_kern(struct vringh *vrh, + struct vringh_kiov *riov, + struct vringh_kiov *wiov, + u16 *head, + gfp_t gfp); + +ssize_t vringh_iov_pull_kern(struct vringh_kiov *riov, void *dst, size_t len); +ssize_t vringh_iov_push_kern(struct vringh_kiov *wiov, + const void *src, size_t len); +void vringh_abandon_kern(struct vringh *vrh, unsigned int num); +int vringh_complete_kern(struct vringh *vrh, u16 head, u32 len); + +bool vringh_notify_enable_kern(struct vringh *vrh); +void vringh_notify_disable_kern(struct vringh *vrh); + +int vringh_need_notify_kern(struct vringh *vrh); + +#endif /* _LINUX_VRINGH_H */ -- cgit From 0d2e1a2926b1839a4b74519e660739b2566c9386 Mon Sep 17 00:00:00 2001 From: Erwan Yvin Date: Wed, 20 Mar 2013 13:52:24 +1030 Subject: caif_virtio: Introduce caif over virtio Add the CAIF Virtio shared memory driver for talking to a modem. This CAIF Link layer communicates to the modem over shared memory. It is implemented as a virtio_driver. The underlying virtio device is managed by the remoteproc framework. The Virtio queue is used for transmitting data to the modem, and the new vringh is used for receiving data. Genalloc is used for managing the shared memory used for TX data. The default dma-alloc-coherent allocator can only allocate whole pages, and this wastes too much shared memory. Flow control is implemented by stopping the TX-queues if the virtio queues go full or we run out of memory. Queued are reopened when queues are below the watermark. NAPI is used in RX path, and a dedicated tasklet is used for releasing TX buffers. Signed-off-by: Erwan Yvin Acked-by: David S. Miller Signed-off-by: Rusty Russell (minor fixes) --- drivers/net/caif/Kconfig | 14 + drivers/net/caif/Makefile | 3 + drivers/net/caif/caif_virtio.c | 785 ++++++++++++++++++++++++++++++++++++++++ include/linux/virtio_caif.h | 24 ++ include/uapi/linux/virtio_ids.h | 1 + 5 files changed, 827 insertions(+) create mode 100644 drivers/net/caif/caif_virtio.c create mode 100644 include/linux/virtio_caif.h (limited to 'drivers') diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 60c2142373c9..893f9154011e 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig @@ -47,3 +47,17 @@ config CAIF_HSI The caif low level driver for CAIF over HSI. Be aware that if you enable this then you also need to enable a low-level HSI driver. + +config CAIF_VIRTIO + tristate "CAIF virtio transport driver" + depends on CAIF + select VHOST_RING + select VIRTIO + select GENERIC_ALLOCATOR + default n + ---help--- + The caif driver for CAIF over Virtio. + +if CAIF_VIRTIO +source "drivers/vhost/Kconfig" +endif diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile index 91dff861560f..d9ee26a96c6e 100644 --- a/drivers/net/caif/Makefile +++ b/drivers/net/caif/Makefile @@ -13,3 +13,6 @@ obj-$(CONFIG_CAIF_SHM) += caif_shm.o # HSI interface obj-$(CONFIG_CAIF_HSI) += caif_hsi.o + +# Virtio interface +obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c new file mode 100644 index 000000000000..b1e1205e4e28 --- /dev/null +++ b/drivers/net/caif/caif_virtio.c @@ -0,0 +1,785 @@ +/* + * Copyright (C) ST-Ericsson AB 2013 + * Authors: Vicram Arv / vikram.arv@stericsson.com, + * Dmitry Tarnyagin / dmitry.tarnyagin@stericsson.com + * Sjur Brendeland / sjur.brandeland@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Vicram Arv "); +MODULE_AUTHOR("Sjur Brendeland "); +MODULE_DESCRIPTION("Virtio CAIF Driver"); + +/* NAPI schedule quota */ +#define CFV_DEFAULT_QUOTA 32 + +/* Defaults used if virtio config space is unavailable */ +#define CFV_DEF_MTU_SIZE 4096 +#define CFV_DEF_HEADROOM 32 +#define CFV_DEF_TAILROOM 32 + +/* Required IP header alignment */ +#define IP_HDR_ALIGN 4 + +/* struct cfv_napi_contxt - NAPI context info + * @riov: IOV holding data read from the ring. Note that riov may + * still hold data when cfv_rx_poll() returns. + * @head: Last descriptor ID we received from vringh_getdesc_kern. + * We use this to put descriptor back on the used ring. USHRT_MAX is + * used to indicate invalid head-id. + */ +struct cfv_napi_context { + struct vringh_kiov riov; + unsigned short head; +}; + +/* struct cfv_stats - statistics for debugfs + * @rx_napi_complete: Number of NAPI completions (RX) + * @rx_napi_resched: Number of calls where the full quota was used (RX) + * @rx_nomem: Number of SKB alloc failures (RX) + * @rx_kicks: Number of RX kicks + * @tx_full_ring: Number times TX ring was full + * @tx_no_mem: Number of times TX went out of memory + * @tx_flow_on: Number of flow on (TX) + * @tx_kicks: Number of TX kicks + */ +struct cfv_stats { + u32 rx_napi_complete; + u32 rx_napi_resched; + u32 rx_nomem; + u32 rx_kicks; + u32 tx_full_ring; + u32 tx_no_mem; + u32 tx_flow_on; + u32 tx_kicks; +}; + +/* struct cfv_info - Caif Virtio control structure + * @cfdev: caif common header + * @vdev: Associated virtio device + * @vr_rx: rx/downlink host vring + * @vq_tx: tx/uplink virtqueue + * @ndev: CAIF link layer device + * @watermark_tx: indicates number of free descriptors we need + * to reopen the tx-queues after overload. + * @tx_lock: protects vq_tx from concurrent use + * @tx_release_tasklet: Tasklet for freeing consumed TX buffers + * @napi: Napi context used in cfv_rx_poll() + * @ctx: Context data used in cfv_rx_poll() + * @tx_hr: transmit headroom + * @rx_hr: receive headroom + * @tx_tr: transmit tail room + * @rx_tr: receive tail room + * @mtu: transmit max size + * @mru: receive max size + * @allocsz: size of dma memory reserved for TX buffers + * @alloc_addr: virtual address to dma memory for TX buffers + * @alloc_dma: dma address to dma memory for TX buffers + * @genpool: Gen Pool used for allocating TX buffers + * @reserved_mem: Pointer to memory reserve allocated from genpool + * @reserved_size: Size of memory reserve allocated from genpool + * @stats: Statistics exposed in sysfs + * @debugfs: Debugfs dentry for statistic counters + */ +struct cfv_info { + struct caif_dev_common cfdev; + struct virtio_device *vdev; + struct vringh *vr_rx; + struct virtqueue *vq_tx; + struct net_device *ndev; + unsigned int watermark_tx; + /* Protect access to vq_tx */ + spinlock_t tx_lock; + struct tasklet_struct tx_release_tasklet; + struct napi_struct napi; + struct cfv_napi_context ctx; + u16 tx_hr; + u16 rx_hr; + u16 tx_tr; + u16 rx_tr; + u32 mtu; + u32 mru; + size_t allocsz; + void *alloc_addr; + dma_addr_t alloc_dma; + struct gen_pool *genpool; + unsigned long reserved_mem; + size_t reserved_size; + struct cfv_stats stats; + struct dentry *debugfs; +}; + +/* struct buf_info - maintains transmit buffer data handle + * @size: size of transmit buffer + * @dma_handle: handle to allocated dma device memory area + * @vaddr: virtual address mapping to allocated memory area + */ +struct buf_info { + size_t size; + u8 *vaddr; +}; + +/* Called from virtio device, in IRQ context */ +static void cfv_release_cb(struct virtqueue *vq_tx) +{ + struct cfv_info *cfv = vq_tx->vdev->priv; + + ++cfv->stats.tx_kicks; + tasklet_schedule(&cfv->tx_release_tasklet); +} + +static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info) +{ + if (!buf_info) + return; + gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr, + buf_info->size); + kfree(buf_info); +} + +/* This is invoked whenever the remote processor completed processing + * a TX msg we just sent, and the buffer is put back to the used ring. + */ +static void cfv_release_used_buf(struct virtqueue *vq_tx) +{ + struct cfv_info *cfv = vq_tx->vdev->priv; + unsigned long flags; + + BUG_ON(vq_tx != cfv->vq_tx); + + for (;;) { + unsigned int len; + struct buf_info *buf_info; + + /* Get used buffer from used ring to recycle used descriptors */ + spin_lock_irqsave(&cfv->tx_lock, flags); + buf_info = virtqueue_get_buf(vq_tx, &len); + spin_unlock_irqrestore(&cfv->tx_lock, flags); + + /* Stop looping if there are no more buffers to free */ + if (!buf_info) + break; + + free_buf_info(cfv, buf_info); + + /* watermark_tx indicates if we previously stopped the tx + * queues. If we have enough free stots in the virtio ring, + * re-establish memory reserved and open up tx queues. + */ + if (cfv->vq_tx->num_free <= cfv->watermark_tx) + continue; + + /* Re-establish memory reserve */ + if (cfv->reserved_mem == 0 && cfv->genpool) + cfv->reserved_mem = + gen_pool_alloc(cfv->genpool, + cfv->reserved_size); + + /* Open up the tx queues */ + if (cfv->reserved_mem) { + cfv->watermark_tx = + virtqueue_get_vring_size(cfv->vq_tx); + netif_tx_wake_all_queues(cfv->ndev); + /* Buffers are recycled in cfv_netdev_tx, so + * disable notifications when queues are opened. + */ + virtqueue_disable_cb(cfv->vq_tx); + ++cfv->stats.tx_flow_on; + } else { + /* if no memory reserve, wait for more free slots */ + WARN_ON(cfv->watermark_tx > + virtqueue_get_vring_size(cfv->vq_tx)); + cfv->watermark_tx += + virtqueue_get_vring_size(cfv->vq_tx) / 4; + } + } +} + +/* Allocate a SKB and copy packet data to it */ +static struct sk_buff *cfv_alloc_and_copy_skb(int *err, + struct cfv_info *cfv, + u8 *frm, u32 frm_len) +{ + struct sk_buff *skb; + u32 cfpkt_len, pad_len; + + *err = 0; + /* Verify that packet size with down-link header and mtu size */ + if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) { + netdev_err(cfv->ndev, + "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n", + frm_len, cfv->mru, cfv->rx_hr, + cfv->rx_tr); + *err = -EPROTO; + return NULL; + } + + cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr); + pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1); + + skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len); + if (!skb) { + *err = -ENOMEM; + return NULL; + } + + skb_reserve(skb, cfv->rx_hr + pad_len); + + memcpy(skb_put(skb, cfpkt_len), frm + cfv->rx_hr, cfpkt_len); + return skb; +} + +/* Get packets from the host vring */ +static int cfv_rx_poll(struct napi_struct *napi, int quota) +{ + struct cfv_info *cfv = container_of(napi, struct cfv_info, napi); + int rxcnt = 0; + int err = 0; + void *buf; + struct sk_buff *skb; + struct vringh_kiov *riov = &cfv->ctx.riov; + unsigned int skb_len; + +again: + do { + skb = NULL; + + /* Put the previous iovec back on the used ring and + * fetch a new iovec if we have processed all elements. + */ + if (riov->i == riov->used) { + if (cfv->ctx.head != USHRT_MAX) { + vringh_complete_kern(cfv->vr_rx, + cfv->ctx.head, + 0); + cfv->ctx.head = USHRT_MAX; + } + + err = vringh_getdesc_kern( + cfv->vr_rx, + riov, + NULL, + &cfv->ctx.head, + GFP_ATOMIC); + + if (err <= 0) + goto exit; + } + + buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base); + /* TODO: Add check on valid buffer address */ + + skb = cfv_alloc_and_copy_skb(&err, cfv, buf, + riov->iov[riov->i].iov_len); + if (unlikely(err)) + goto exit; + + /* Push received packet up the stack. */ + skb_len = skb->len; + skb->protocol = htons(ETH_P_CAIF); + skb_reset_mac_header(skb); + skb->dev = cfv->ndev; + err = netif_receive_skb(skb); + if (unlikely(err)) { + ++cfv->ndev->stats.rx_dropped; + } else { + ++cfv->ndev->stats.rx_packets; + cfv->ndev->stats.rx_bytes += skb_len; + } + + ++riov->i; + ++rxcnt; + } while (rxcnt < quota); + + ++cfv->stats.rx_napi_resched; + goto out; + +exit: + switch (err) { + case 0: + ++cfv->stats.rx_napi_complete; + + /* Really out of patckets? (stolen from virtio_net)*/ + napi_complete(napi); + if (unlikely(vringh_notify_enable_kern(cfv->vr_rx)) && + napi_schedule_prep(napi)) { + vringh_notify_disable_kern(cfv->vr_rx); + __napi_schedule(napi); + goto again; + } + break; + + case -ENOMEM: + ++cfv->stats.rx_nomem; + dev_kfree_skb(skb); + /* Stop NAPI poll on OOM, we hope to be polled later */ + napi_complete(napi); + vringh_notify_enable_kern(cfv->vr_rx); + break; + + default: + /* We're doomed, any modem fault is fatal */ + netdev_warn(cfv->ndev, "Bad ring, disable device\n"); + cfv->ndev->stats.rx_dropped = riov->used - riov->i; + napi_complete(napi); + vringh_notify_disable_kern(cfv->vr_rx); + netif_carrier_off(cfv->ndev); + break; + } +out: + if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0) + vringh_notify(cfv->vr_rx); + return rxcnt; +} + +static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx) +{ + struct cfv_info *cfv = vdev->priv; + + ++cfv->stats.rx_kicks; + vringh_notify_disable_kern(cfv->vr_rx); + napi_schedule(&cfv->napi); +} + +static void cfv_destroy_genpool(struct cfv_info *cfv) +{ + if (cfv->alloc_addr) + dma_free_coherent(cfv->vdev->dev.parent->parent, + cfv->allocsz, cfv->alloc_addr, + cfv->alloc_dma); + + if (!cfv->genpool) + return; + gen_pool_free(cfv->genpool, cfv->reserved_mem, + cfv->reserved_size); + gen_pool_destroy(cfv->genpool); + cfv->genpool = NULL; +} + +static int cfv_create_genpool(struct cfv_info *cfv) +{ + int err; + + /* dma_alloc can only allocate whole pages, and we need a more + * fine graned allocation so we use genpool. We ask for space needed + * by IP and a full ring. If the dma allcoation fails we retry with a + * smaller allocation size. + */ + err = -ENOMEM; + cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) * + (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10; + if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu) + return -EINVAL; + + for (;;) { + if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) { + netdev_info(cfv->ndev, "Not enough device memory\n"); + return -ENOMEM; + } + + cfv->alloc_addr = dma_alloc_coherent( + cfv->vdev->dev.parent->parent, + cfv->allocsz, &cfv->alloc_dma, + GFP_ATOMIC); + if (cfv->alloc_addr) + break; + + cfv->allocsz = (cfv->allocsz * 3) >> 2; + } + + netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n", + cfv->allocsz); + + /* Allocate on 128 bytes boundaries (1 << 7)*/ + cfv->genpool = gen_pool_create(7, -1); + if (!cfv->genpool) + goto err; + + err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr, + (phys_addr_t)virt_to_phys(cfv->alloc_addr), + cfv->allocsz, -1); + if (err) + goto err; + + /* Reserve some memory for low memory situations. If we hit the roof + * in the memory pool, we stop TX flow and release the reserve. + */ + cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu; + cfv->reserved_mem = gen_pool_alloc(cfv->genpool, + cfv->reserved_size); + if (!cfv->reserved_mem) + goto err; + + cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx); + return 0; +err: + cfv_destroy_genpool(cfv); + return err; +} + +/* Enable the CAIF interface and allocate the memory-pool */ +static int cfv_netdev_open(struct net_device *netdev) +{ + struct cfv_info *cfv = netdev_priv(netdev); + + if (cfv_create_genpool(cfv)) + return -ENOMEM; + + netif_carrier_on(netdev); + napi_enable(&cfv->napi); + + /* Schedule NAPI to read any pending packets */ + napi_schedule(&cfv->napi); + return 0; +} + +/* Disable the CAIF interface and free the memory-pool */ +static int cfv_netdev_close(struct net_device *netdev) +{ + struct cfv_info *cfv = netdev_priv(netdev); + unsigned long flags; + struct buf_info *buf_info; + + /* Disable interrupts, queues and NAPI polling */ + netif_carrier_off(netdev); + virtqueue_disable_cb(cfv->vq_tx); + vringh_notify_disable_kern(cfv->vr_rx); + napi_disable(&cfv->napi); + + /* Release any TX buffers on both used and avilable rings */ + cfv_release_used_buf(cfv->vq_tx); + spin_lock_irqsave(&cfv->tx_lock, flags); + while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx))) + free_buf_info(cfv, buf_info); + spin_unlock_irqrestore(&cfv->tx_lock, flags); + + /* Release all dma allocated memory and destroy the pool */ + cfv_destroy_genpool(cfv); + return 0; +} + +/* Allocate a buffer in dma-memory and copy skb to it */ +static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv, + struct sk_buff *skb, + struct scatterlist *sg) +{ + struct caif_payload_info *info = (void *)&skb->cb; + struct buf_info *buf_info = NULL; + u8 pad_len, hdr_ofs; + + if (!cfv->genpool) + goto err; + + if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) { + netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n", + cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu); + goto err; + } + + buf_info = kmalloc(sizeof(struct buf_info), GFP_ATOMIC); + if (unlikely(!buf_info)) + goto err; + + /* Make the IP header aligned in tbe buffer */ + hdr_ofs = cfv->tx_hr + info->hdr_len; + pad_len = hdr_ofs & (IP_HDR_ALIGN - 1); + buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len; + + /* allocate dma memory buffer */ + buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size); + if (unlikely(!buf_info->vaddr)) + goto err; + + /* copy skbuf contents to send buffer */ + skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len); + sg_init_one(sg, buf_info->vaddr + pad_len, + skb->len + cfv->tx_hr + cfv->rx_hr); + + return buf_info; +err: + kfree(buf_info); + return NULL; +} + +/* Put the CAIF packet on the virtio ring and kick the receiver */ +static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev) +{ + struct cfv_info *cfv = netdev_priv(netdev); + struct buf_info *buf_info; + struct scatterlist sg; + unsigned long flags; + bool flow_off = false; + int ret; + + /* garbage collect released buffers */ + cfv_release_used_buf(cfv->vq_tx); + spin_lock_irqsave(&cfv->tx_lock, flags); + + /* Flow-off check takes into account number of cpus to make sure + * virtqueue will not be overfilled in any possible smp conditions. + * + * Flow-on is triggered when sufficient buffers are freed + */ + if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) { + flow_off = true; + cfv->stats.tx_full_ring++; + } + + /* If we run out of memory, we release the memory reserve and retry + * allocation. + */ + buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg); + if (unlikely(!buf_info)) { + cfv->stats.tx_no_mem++; + flow_off = true; + + if (cfv->reserved_mem && cfv->genpool) { + gen_pool_free(cfv->genpool, cfv->reserved_mem, + cfv->reserved_size); + cfv->reserved_mem = 0; + buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg); + } + } + + if (unlikely(flow_off)) { + /* Turn flow on when a 1/4 of the descriptors are released */ + cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4; + /* Enable notifications of recycled TX buffers */ + virtqueue_enable_cb(cfv->vq_tx); + netif_tx_stop_all_queues(netdev); + } + + if (unlikely(!buf_info)) { + /* If the memory reserve does it's job, this shouldn't happen */ + netdev_warn(cfv->ndev, "Out of gen_pool memory\n"); + goto err; + } + + ret = virtqueue_add_buf(cfv->vq_tx, &sg, 1, 0, + buf_info, GFP_ATOMIC); + if (unlikely((ret < 0))) { + /* If flow control works, this shouldn't happen */ + netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n", + ret); + goto err; + } + + /* update netdev statistics */ + cfv->ndev->stats.tx_packets++; + cfv->ndev->stats.tx_bytes += skb->len; + spin_unlock_irqrestore(&cfv->tx_lock, flags); + + /* tell the remote processor it has a pending message to read */ + virtqueue_kick(cfv->vq_tx); + + dev_kfree_skb(skb); + return NETDEV_TX_OK; +err: + spin_unlock_irqrestore(&cfv->tx_lock, flags); + cfv->ndev->stats.tx_dropped++; + free_buf_info(cfv, buf_info); + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +static void cfv_tx_release_tasklet(unsigned long drv) +{ + struct cfv_info *cfv = (struct cfv_info *)drv; + cfv_release_used_buf(cfv->vq_tx); +} + +static const struct net_device_ops cfv_netdev_ops = { + .ndo_open = cfv_netdev_open, + .ndo_stop = cfv_netdev_close, + .ndo_start_xmit = cfv_netdev_tx, +}; + +static void cfv_netdev_setup(struct net_device *netdev) +{ + netdev->netdev_ops = &cfv_netdev_ops; + netdev->type = ARPHRD_CAIF; + netdev->tx_queue_len = 100; + netdev->flags = IFF_POINTOPOINT | IFF_NOARP; + netdev->mtu = CFV_DEF_MTU_SIZE; + netdev->destructor = free_netdev; +} + +/* Create debugfs counters for the device */ +static inline void debugfs_init(struct cfv_info *cfv) +{ + cfv->debugfs = + debugfs_create_dir(netdev_name(cfv->ndev), NULL); + + if (IS_ERR(cfv->debugfs)) + return; + + debugfs_create_u32("rx-napi-complete", S_IRUSR, cfv->debugfs, + &cfv->stats.rx_napi_complete); + debugfs_create_u32("rx-napi-resched", S_IRUSR, cfv->debugfs, + &cfv->stats.rx_napi_resched); + debugfs_create_u32("rx-nomem", S_IRUSR, cfv->debugfs, + &cfv->stats.rx_nomem); + debugfs_create_u32("rx-kicks", S_IRUSR, cfv->debugfs, + &cfv->stats.rx_kicks); + debugfs_create_u32("tx-full-ring", S_IRUSR, cfv->debugfs, + &cfv->stats.tx_full_ring); + debugfs_create_u32("tx-no-mem", S_IRUSR, cfv->debugfs, + &cfv->stats.tx_no_mem); + debugfs_create_u32("tx-kicks", S_IRUSR, cfv->debugfs, + &cfv->stats.tx_kicks); + debugfs_create_u32("tx-flow-on", S_IRUSR, cfv->debugfs, + &cfv->stats.tx_flow_on); +} + +/* Setup CAIF for the a virtio device */ +static int cfv_probe(struct virtio_device *vdev) +{ + vq_callback_t *vq_cbs = cfv_release_cb; + vrh_callback_t *vrh_cbs = cfv_recv; + const char *names = "output"; + const char *cfv_netdev_name = "cfvrt"; + struct net_device *netdev; + struct cfv_info *cfv; + int err = -EINVAL; + + netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name, + cfv_netdev_setup); + if (!netdev) + return -ENOMEM; + + cfv = netdev_priv(netdev); + cfv->vdev = vdev; + cfv->ndev = netdev; + + spin_lock_init(&cfv->tx_lock); + + /* Get the RX virtio ring. This is a "host side vring". */ + err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs); + if (err) + goto err; + + /* Get the TX virtio ring. This is a "guest side vring". */ + err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names); + if (err) + goto err; + + /* Get the CAIF configuration from virtio config space, if available */ +#define GET_VIRTIO_CONFIG_OPS(_v, _var, _f) \ + ((_v)->config->get(_v, offsetof(struct virtio_caif_transf_config, _f), \ + &_var, \ + FIELD_SIZEOF(struct virtio_caif_transf_config, _f))) + + if (vdev->config->get) { + GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_hr, headroom); + GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_hr, headroom); + GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_tr, tailroom); + GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_tr, tailroom); + GET_VIRTIO_CONFIG_OPS(vdev, cfv->mtu, mtu); + GET_VIRTIO_CONFIG_OPS(vdev, cfv->mru, mtu); + } else { + cfv->tx_hr = CFV_DEF_HEADROOM; + cfv->rx_hr = CFV_DEF_HEADROOM; + cfv->tx_tr = CFV_DEF_TAILROOM; + cfv->rx_tr = CFV_DEF_TAILROOM; + cfv->mtu = CFV_DEF_MTU_SIZE; + cfv->mru = CFV_DEF_MTU_SIZE; + } + + netdev->needed_headroom = cfv->tx_hr; + netdev->needed_tailroom = cfv->tx_tr; + + /* Disable buffer release interrupts unless we have stopped TX queues */ + virtqueue_disable_cb(cfv->vq_tx); + + netdev->mtu = cfv->mtu - cfv->tx_tr; + vdev->priv = cfv; + + /* Initialize NAPI poll context data */ + vringh_kiov_init(&cfv->ctx.riov, NULL, 0); + cfv->ctx.head = USHRT_MAX; + netif_napi_add(netdev, &cfv->napi, cfv_rx_poll, CFV_DEFAULT_QUOTA); + + tasklet_init(&cfv->tx_release_tasklet, + cfv_tx_release_tasklet, + (unsigned long)cfv); + + /* Carrier is off until netdevice is opened */ + netif_carrier_off(netdev); + + /* register Netdev */ + err = register_netdev(netdev); + if (err) { + dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err); + goto err; + } + + debugfs_init(cfv); + + return 0; +err: + netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err); + + if (cfv->vr_rx) + vdev->vringh_config->del_vrhs(cfv->vdev); + if (cfv->vdev) + vdev->config->del_vqs(cfv->vdev); + free_netdev(netdev); + return err; +} + +static void cfv_remove(struct virtio_device *vdev) +{ + struct cfv_info *cfv = vdev->priv; + + rtnl_lock(); + dev_close(cfv->ndev); + rtnl_unlock(); + + tasklet_kill(&cfv->tx_release_tasklet); + debugfs_remove_recursive(cfv->debugfs); + + vringh_kiov_cleanup(&cfv->ctx.riov); + vdev->config->reset(vdev); + vdev->vringh_config->del_vrhs(cfv->vdev); + cfv->vr_rx = NULL; + vdev->config->del_vqs(cfv->vdev); + unregister_netdev(cfv->ndev); +} + +static struct virtio_device_id id_table[] = { + { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static unsigned int features[] = { +}; + +static struct virtio_driver caif_virtio_driver = { + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = cfv_probe, + .remove = cfv_remove, +}; + +module_virtio_driver(caif_virtio_driver); +MODULE_DEVICE_TABLE(virtio, id_table); diff --git a/include/linux/virtio_caif.h b/include/linux/virtio_caif.h new file mode 100644 index 000000000000..5d2d3124ca3d --- /dev/null +++ b/include/linux/virtio_caif.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) ST-Ericsson AB 2012 + * Author: Sjur Brændeland + * + * This header is BSD licensed so + * anyone can use the definitions to implement compatible remote processors + */ + +#ifndef VIRTIO_CAIF_H +#define VIRTIO_CAIF_H + +#include +struct virtio_caif_transf_config { + u16 headroom; + u16 tailroom; + u32 mtu; + u8 reserved[4]; +}; + +struct virtio_caif_config { + struct virtio_caif_transf_config uplink, downlink; + u8 reserved[8]; +}; +#endif diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index a7630d04029f..284fc3a05f7b 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -38,5 +38,6 @@ #define VIRTIO_ID_SCSI 8 /* virtio scsi */ #define VIRTIO_ID_9P 9 /* 9p virtio console */ #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ +#define VIRTIO_ID_CAIF 12 /* Virtio caif */ #endif /* _LINUX_VIRTIO_IDS_H */ -- cgit From 13816c768d46586e925b22736992258d6105ad2c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:37:09 +1030 Subject: virtio_ring: virtqueue_add_sgs, to add multiple sgs. virtio_scsi can really use this, to avoid the current hack of copying the whole sg array. Some other things get slightly neater, too. This causes a slowdown in virtqueue_add_buf(), which is implemented as a wrapper. This is addressed in the next patches. for i in `seq 50`; do /usr/bin/time -f 'Wall time:%e' ./vringh_test --indirect --eventidx --parallel --fast-vringh; done 2>&1 | stats --trim-outliers: Before: Using CPUS 0 and 3 Guest: notified 0, pinged 39009-39063(39062) Host: notified 39009-39063(39062), pinged 0 Wall time:1.700000-1.950000(1.723542) After: Using CPUS 0 and 3 Guest: notified 0, pinged 39062-39063(39063) Host: notified 39062-39063(39063), pinged 0 Wall time:1.760000-2.220000(1.789167) Signed-off-by: Rusty Russell Reviewed-by: Wanlong Gao Reviewed-by: Asias He --- drivers/virtio/virtio_ring.c | 220 ++++++++++++++++++++++++++++----------- include/linux/virtio.h | 7 ++ tools/virtio/linux/scatterlist.h | 16 +++ tools/virtio/linux/virtio.h | 7 ++ 4 files changed, 187 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 245177c286ae..a78ad459cc85 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -98,16 +98,36 @@ struct vring_virtqueue #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) +static inline struct scatterlist *sg_next_chained(struct scatterlist *sg, + unsigned int *count) +{ + return sg_next(sg); +} + +static inline struct scatterlist *sg_next_arr(struct scatterlist *sg, + unsigned int *count) +{ + if (--(*count) == 0) + return NULL; + return sg + 1; +} + /* Set up an indirect table of descriptors and add it to the queue. */ -static int vring_add_indirect(struct vring_virtqueue *vq, - struct scatterlist sg[], - unsigned int out, - unsigned int in, - gfp_t gfp) +static inline int vring_add_indirect(struct vring_virtqueue *vq, + struct scatterlist *sgs[], + struct scatterlist *(*next) + (struct scatterlist *, unsigned int *), + unsigned int total_sg, + unsigned int total_out, + unsigned int total_in, + unsigned int out_sgs, + unsigned int in_sgs, + gfp_t gfp) { struct vring_desc *desc; unsigned head; - int i; + struct scatterlist *sg; + int i, n; /* * We require lowmem mappings for the descriptors because @@ -116,25 +136,31 @@ static int vring_add_indirect(struct vring_virtqueue *vq, */ gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH); - desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); + desc = kmalloc(total_sg * sizeof(struct vring_desc), gfp); if (!desc) return -ENOMEM; - /* Transfer entries from the sg list into the indirect page */ - for (i = 0; i < out; i++) { - desc[i].flags = VRING_DESC_F_NEXT; - desc[i].addr = sg_phys(sg); - desc[i].len = sg->length; - desc[i].next = i+1; - sg++; + /* Transfer entries from the sg lists into the indirect page */ + i = 0; + for (n = 0; n < out_sgs; n++) { + for (sg = sgs[n]; sg; sg = next(sg, &total_out)) { + desc[i].flags = VRING_DESC_F_NEXT; + desc[i].addr = sg_phys(sg); + desc[i].len = sg->length; + desc[i].next = i+1; + i++; + } } - for (; i < (out + in); i++) { - desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE; - desc[i].addr = sg_phys(sg); - desc[i].len = sg->length; - desc[i].next = i+1; - sg++; + for (; n < (out_sgs + in_sgs); n++) { + for (sg = sgs[n]; sg; sg = next(sg, &total_in)) { + desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE; + desc[i].addr = sg_phys(sg); + desc[i].len = sg->length; + desc[i].next = i+1; + i++; + } } + BUG_ON(i != total_sg); /* Last one doesn't continue. */ desc[i-1].flags &= ~VRING_DESC_F_NEXT; @@ -155,29 +181,20 @@ static int vring_add_indirect(struct vring_virtqueue *vq, return head; } -/** - * virtqueue_add_buf - expose buffer to other end - * @vq: the struct virtqueue we're talking about. - * @sg: the description of the buffer(s). - * @out_num: the number of sg readable by other side - * @in_num: the number of sg which are writable (after readable ones) - * @data: the token identifying the buffer. - * @gfp: how to do memory allocations (if necessary). - * - * Caller must ensure we don't call this with other virtqueue operations - * at the same time (except where noted). - * - * Returns zero or a negative error (ie. ENOSPC, ENOMEM). - */ -int virtqueue_add_buf(struct virtqueue *_vq, - struct scatterlist sg[], - unsigned int out, - unsigned int in, - void *data, - gfp_t gfp) +static inline int virtqueue_add(struct virtqueue *_vq, + struct scatterlist *sgs[], + struct scatterlist *(*next) + (struct scatterlist *, unsigned int *), + unsigned int total_out, + unsigned int total_in, + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp) { struct vring_virtqueue *vq = to_vvq(_vq); - unsigned int i, avail, uninitialized_var(prev); + struct scatterlist *sg; + unsigned int i, n, avail, uninitialized_var(prev), total_sg; int head; START_USE(vq); @@ -197,46 +214,54 @@ int virtqueue_add_buf(struct virtqueue *_vq, } #endif + total_sg = total_in + total_out; + /* If the host supports indirect descriptor tables, and we have multiple * buffers, then go indirect. FIXME: tune this threshold */ - if (vq->indirect && (out + in) > 1 && vq->vq.num_free) { - head = vring_add_indirect(vq, sg, out, in, gfp); + if (vq->indirect && total_sg > 1 && vq->vq.num_free) { + head = vring_add_indirect(vq, sgs, next, total_sg, total_out, + total_in, + out_sgs, in_sgs, gfp); if (likely(head >= 0)) goto add_head; } - BUG_ON(out + in > vq->vring.num); - BUG_ON(out + in == 0); + BUG_ON(total_sg > vq->vring.num); + BUG_ON(total_sg == 0); - if (vq->vq.num_free < out + in) { + if (vq->vq.num_free < total_sg) { pr_debug("Can't add buf len %i - avail = %i\n", - out + in, vq->vq.num_free); + total_sg, vq->vq.num_free); /* FIXME: for historical reasons, we force a notify here if * there are outgoing parts to the buffer. Presumably the * host should service the ring ASAP. */ - if (out) + if (out_sgs) vq->notify(&vq->vq); END_USE(vq); return -ENOSPC; } /* We're about to use some buffers from the free list. */ - vq->vq.num_free -= out + in; - - head = vq->free_head; - for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { - vq->vring.desc[i].flags = VRING_DESC_F_NEXT; - vq->vring.desc[i].addr = sg_phys(sg); - vq->vring.desc[i].len = sg->length; - prev = i; - sg++; + vq->vq.num_free -= total_sg; + + head = i = vq->free_head; + for (n = 0; n < out_sgs; n++) { + for (sg = sgs[n]; sg; sg = next(sg, &total_out)) { + vq->vring.desc[i].flags = VRING_DESC_F_NEXT; + vq->vring.desc[i].addr = sg_phys(sg); + vq->vring.desc[i].len = sg->length; + prev = i; + i = vq->vring.desc[i].next; + } } - for (; in; i = vq->vring.desc[i].next, in--) { - vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE; - vq->vring.desc[i].addr = sg_phys(sg); - vq->vring.desc[i].len = sg->length; - prev = i; - sg++; + for (; n < (out_sgs + in_sgs); n++) { + for (sg = sgs[n]; sg; sg = next(sg, &total_in)) { + vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE; + vq->vring.desc[i].addr = sg_phys(sg); + vq->vring.desc[i].len = sg->length; + prev = i; + i = vq->vring.desc[i].next; + } } /* Last one doesn't continue. */ vq->vring.desc[prev].flags &= ~VRING_DESC_F_NEXT; @@ -269,8 +294,77 @@ add_head: return 0; } + +/** + * virtqueue_add_buf - expose buffer to other end + * @vq: the struct virtqueue we're talking about. + * @sg: the description of the buffer(s). + * @out_num: the number of sg readable by other side + * @in_num: the number of sg which are writable (after readable ones) + * @data: the token identifying the buffer. + * @gfp: how to do memory allocations (if necessary). + * + * Caller must ensure we don't call this with other virtqueue operations + * at the same time (except where noted). + * + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). + */ +int virtqueue_add_buf(struct virtqueue *_vq, + struct scatterlist sg[], + unsigned int out, + unsigned int in, + void *data, + gfp_t gfp) +{ + struct scatterlist *sgs[2]; + + sgs[0] = sg; + sgs[1] = sg + out; + + return virtqueue_add(_vq, sgs, sg_next_arr, + out, in, out ? 1 : 0, in ? 1 : 0, data, gfp); +} EXPORT_SYMBOL_GPL(virtqueue_add_buf); +/** + * virtqueue_add_sgs - expose buffers to other end + * @vq: the struct virtqueue we're talking about. + * @sgs: array of terminated scatterlists. + * @out_num: the number of scatterlists readable by other side + * @in_num: the number of scatterlists which are writable (after readable ones) + * @data: the token identifying the buffer. + * @gfp: how to do memory allocations (if necessary). + * + * Caller must ensure we don't call this with other virtqueue operations + * at the same time (except where noted). + * + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). + */ +int virtqueue_add_sgs(struct virtqueue *_vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp) +{ + unsigned int i, total_out, total_in; + + /* Count them first. */ + for (i = total_out = total_in = 0; i < out_sgs; i++) { + struct scatterlist *sg; + for (sg = sgs[i]; sg; sg = sg_next(sg)) + total_out++; + } + for (; i < out_sgs + in_sgs; i++) { + struct scatterlist *sg; + for (sg = sgs[i]; sg; sg = sg_next(sg)) + total_in++; + } + return virtqueue_add(_vq, sgs, sg_next_chained, + total_out, total_in, out_sgs, in_sgs, data, gfp); +} +EXPORT_SYMBOL_GPL(virtqueue_add_sgs); + /** * virtqueue_kick_prepare - first half of split virtqueue_kick call. * @vq: the struct virtqueue diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 5d5b3abc283d..ac80288b2920 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -41,6 +41,13 @@ int virtqueue_add_buf(struct virtqueue *vq, void *data, gfp_t gfp); +int virtqueue_add_sgs(struct virtqueue *vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp); + void virtqueue_kick(struct virtqueue *vq); bool virtqueue_kick_prepare(struct virtqueue *vq); diff --git a/tools/virtio/linux/scatterlist.h b/tools/virtio/linux/scatterlist.h index b2cf7d0f6133..68c9e2adc996 100644 --- a/tools/virtio/linux/scatterlist.h +++ b/tools/virtio/linux/scatterlist.h @@ -125,6 +125,22 @@ static inline void sg_mark_end(struct scatterlist *sg) sg->page_link &= ~0x01; } +/** + * sg_unmark_end - Undo setting the end of the scatterlist + * @sg: SG entryScatterlist + * + * Description: + * Removes the termination marker from the given entry of the scatterlist. + * + **/ +static inline void sg_unmark_end(struct scatterlist *sg) +{ +#ifdef CONFIG_DEBUG_SG + BUG_ON(sg->sg_magic != SG_MAGIC); +#endif + sg->page_link &= ~0x02; +} + static inline struct scatterlist *sg_next(struct scatterlist *sg) { #ifdef CONFIG_DEBUG_SG diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index e4af6591f5ff..5fa612ad932c 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -56,6 +56,13 @@ int virtqueue_add_buf(struct virtqueue *vq, void *data, gfp_t gfp); +int virtqueue_add_sgs(struct virtqueue *vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, + void *data, + gfp_t gfp); + void virtqueue_kick(struct virtqueue *vq); void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); -- cgit From 282edb36499042a92b71f052f51754ae7ed936e4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:26 +1030 Subject: virtio_ring: virtqueue_add_outbuf / virtqueue_add_inbuf. These are specialized versions of virtqueue_add_buf(), which cover over 80% of cases and are far clearer. In particular, the scatterlists passed to these functions don't have to be clean (ie. we ignore end markers). Signed-off-by: Rusty Russell --- drivers/virtio/virtio_ring.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++++++ 2 files changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index a78ad459cc85..5217baf5528c 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -365,6 +365,50 @@ int virtqueue_add_sgs(struct virtqueue *_vq, } EXPORT_SYMBOL_GPL(virtqueue_add_sgs); +/** + * virtqueue_add_outbuf - expose output buffers to other end + * @vq: the struct virtqueue we're talking about. + * @sgs: array of scatterlists (need not be terminated!) + * @num: the number of scatterlists readable by other side + * @data: the token identifying the buffer. + * @gfp: how to do memory allocations (if necessary). + * + * Caller must ensure we don't call this with other virtqueue operations + * at the same time (except where noted). + * + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). + */ +int virtqueue_add_outbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp) +{ + return virtqueue_add(vq, &sg, sg_next_arr, num, 0, 1, 0, data, gfp); +} +EXPORT_SYMBOL_GPL(virtqueue_add_outbuf); + +/** + * virtqueue_add_inbuf - expose input buffers to other end + * @vq: the struct virtqueue we're talking about. + * @sgs: array of scatterlists (need not be terminated!) + * @num: the number of scatterlists writable by other side + * @data: the token identifying the buffer. + * @gfp: how to do memory allocations (if necessary). + * + * Caller must ensure we don't call this with other virtqueue operations + * at the same time (except where noted). + * + * Returns zero or a negative error (ie. ENOSPC, ENOMEM). + */ +int virtqueue_add_inbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp) +{ + return virtqueue_add(vq, &sg, sg_next_arr, 0, num, 0, 1, data, gfp); +} +EXPORT_SYMBOL_GPL(virtqueue_add_inbuf); + /** * virtqueue_kick_prepare - first half of split virtqueue_kick call. * @vq: the struct virtqueue diff --git a/include/linux/virtio.h b/include/linux/virtio.h index ac80288b2920..833f17b6a743 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -41,6 +41,16 @@ int virtqueue_add_buf(struct virtqueue *vq, void *data, gfp_t gfp); +int virtqueue_add_outbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp); + +int virtqueue_add_inbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp); + int virtqueue_add_sgs(struct virtqueue *vq, struct scatterlist *sgs[], unsigned int out_sgs, -- cgit From 5ee21a52c05b5670ceeaa502c15cf306e379f714 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Mar 2013 15:44:27 +1030 Subject: virtio-blk: reorganize virtblk_add_req Right now, both virtblk_add_req and virtblk_add_req_wait call virtqueue_add_buf. To prepare for the next patches, abstract the call to virtqueue_add_buf into a new function __virtblk_add_req, and include the waiting logic directly in virtblk_add_req. Signed-off-by: Paolo Bonzini Reviewed-by: Asias He Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 55 +++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 922bcb97e23a..b271650032fa 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -100,50 +100,39 @@ static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk, return vbr; } -static void virtblk_add_buf_wait(struct virtio_blk *vblk, - struct virtblk_req *vbr, - unsigned long out, - unsigned long in) +static inline int __virtblk_add_req(struct virtqueue *vq, + struct virtblk_req *vbr, + unsigned long out, + unsigned long in) { + return virtqueue_add_buf(vq, vbr->sg, out, in, vbr, GFP_ATOMIC); +} + +static void virtblk_add_req(struct virtblk_req *vbr, + unsigned int out, unsigned int in) +{ + struct virtio_blk *vblk = vbr->vblk; DEFINE_WAIT(wait); + int ret; - for (;;) { + spin_lock_irq(vblk->disk->queue->queue_lock); + while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr, + out, in)) < 0)) { prepare_to_wait_exclusive(&vblk->queue_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(vblk->disk->queue->queue_lock); + io_schedule(); spin_lock_irq(vblk->disk->queue->queue_lock); - if (virtqueue_add_buf(vblk->vq, vbr->sg, out, in, vbr, - GFP_ATOMIC) < 0) { - spin_unlock_irq(vblk->disk->queue->queue_lock); - io_schedule(); - } else { - virtqueue_kick(vblk->vq); - spin_unlock_irq(vblk->disk->queue->queue_lock); - break; - } + finish_wait(&vblk->queue_wait, &wait); } - finish_wait(&vblk->queue_wait, &wait); -} - -static inline void virtblk_add_req(struct virtblk_req *vbr, - unsigned int out, unsigned int in) -{ - struct virtio_blk *vblk = vbr->vblk; - - spin_lock_irq(vblk->disk->queue->queue_lock); - if (unlikely(virtqueue_add_buf(vblk->vq, vbr->sg, out, in, vbr, - GFP_ATOMIC) < 0)) { - spin_unlock_irq(vblk->disk->queue->queue_lock); - virtblk_add_buf_wait(vblk, vbr, out, in); - return; - } virtqueue_kick(vblk->vq); spin_unlock_irq(vblk->disk->queue->queue_lock); } -static int virtblk_bio_send_flush(struct virtblk_req *vbr) +static void virtblk_bio_send_flush(struct virtblk_req *vbr) { unsigned int out = 0, in = 0; @@ -155,11 +144,9 @@ static int virtblk_bio_send_flush(struct virtblk_req *vbr) sg_set_buf(&vbr->sg[out + in++], &vbr->status, sizeof(vbr->status)); virtblk_add_req(vbr, out, in); - - return 0; } -static int virtblk_bio_send_data(struct virtblk_req *vbr) +static void virtblk_bio_send_data(struct virtblk_req *vbr) { struct virtio_blk *vblk = vbr->vblk; unsigned int num, out = 0, in = 0; @@ -188,8 +175,6 @@ static int virtblk_bio_send_data(struct virtblk_req *vbr) } virtblk_add_req(vbr, out, in); - - return 0; } static void virtblk_bio_send_data_work(struct work_struct *work) -- cgit From 8f39db9d3709afe944710f124111ec87467d25c7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Mar 2013 15:44:27 +1030 Subject: virtio-blk: use virtqueue_add_sgs on bio path (This is a respin of Paolo Bonzini's patch, but it calls virtqueue_add_sgs() instead of his multi-part API). Move the creation of the request header and response footer to __virtblk_add_req. vbr->sg only contains the data scatterlist, the header/footer are added separately using virtqueue_add_sgs(). With this change, virtio-blk (with use_bio) is not relying anymore on the virtio functions ignoring the end markers in a scatterlist. The next patch will do the same for the other path. Signed-off-by: Paolo Bonzini Signed-off-by: Rusty Russell Reviewed-by: Asias He --- drivers/block/virtio_blk.c | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b271650032fa..cfbe39d35277 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -62,6 +62,7 @@ struct virtblk_req struct virtio_blk *vblk; int flags; u8 status; + int nents; struct scatterlist sg[]; }; @@ -100,24 +101,36 @@ static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk, return vbr; } -static inline int __virtblk_add_req(struct virtqueue *vq, - struct virtblk_req *vbr, - unsigned long out, - unsigned long in) +static int __virtblk_add_req(struct virtqueue *vq, + struct virtblk_req *vbr) { - return virtqueue_add_buf(vq, vbr->sg, out, in, vbr, GFP_ATOMIC); + struct scatterlist hdr, status, *sgs[3]; + unsigned int num_out = 0, num_in = 0; + + sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr)); + sgs[num_out++] = &hdr; + + if (vbr->nents) { + if (vbr->out_hdr.type & VIRTIO_BLK_T_OUT) + sgs[num_out++] = vbr->sg; + else + sgs[num_out + num_in++] = vbr->sg; + } + + sg_init_one(&status, &vbr->status, sizeof(vbr->status)); + sgs[num_out + num_in++] = &status; + + return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); } -static void virtblk_add_req(struct virtblk_req *vbr, - unsigned int out, unsigned int in) +static void virtblk_add_req(struct virtblk_req *vbr) { struct virtio_blk *vblk = vbr->vblk; DEFINE_WAIT(wait); int ret; spin_lock_irq(vblk->disk->queue->queue_lock); - while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr, - out, in)) < 0)) { + while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr)) < 0)) { prepare_to_wait_exclusive(&vblk->queue_wait, &wait, TASK_UNINTERRUPTIBLE); @@ -134,22 +147,18 @@ static void virtblk_add_req(struct virtblk_req *vbr, static void virtblk_bio_send_flush(struct virtblk_req *vbr) { - unsigned int out = 0, in = 0; - vbr->flags |= VBLK_IS_FLUSH; vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = 0; - sg_set_buf(&vbr->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); - sg_set_buf(&vbr->sg[out + in++], &vbr->status, sizeof(vbr->status)); + vbr->nents = 0; - virtblk_add_req(vbr, out, in); + virtblk_add_req(vbr); } static void virtblk_bio_send_data(struct virtblk_req *vbr) { struct virtio_blk *vblk = vbr->vblk; - unsigned int num, out = 0, in = 0; struct bio *bio = vbr->bio; vbr->flags &= ~VBLK_IS_FLUSH; @@ -157,24 +166,15 @@ static void virtblk_bio_send_data(struct virtblk_req *vbr) vbr->out_hdr.sector = bio->bi_sector; vbr->out_hdr.ioprio = bio_prio(bio); - sg_set_buf(&vbr->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); - - num = blk_bio_map_sg(vblk->disk->queue, bio, vbr->sg + out); - - sg_set_buf(&vbr->sg[num + out + in++], &vbr->status, - sizeof(vbr->status)); - - if (num) { - if (bio->bi_rw & REQ_WRITE) { + vbr->nents = blk_bio_map_sg(vblk->disk->queue, bio, vbr->sg); + if (vbr->nents) { + if (bio->bi_rw & REQ_WRITE) vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; - out += num; - } else { + else vbr->out_hdr.type |= VIRTIO_BLK_T_IN; - in += num; - } } - virtblk_add_req(vbr, out, in); + virtblk_add_req(vbr); } static void virtblk_bio_send_data_work(struct work_struct *work) -- cgit From 20af3cfd20145fece208ada7cb10e1fd7f21f128 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Mar 2013 15:44:27 +1030 Subject: virtio-blk: use virtqueue_add_sgs on req path (This is a respin of Paolo Bonzini's patch, but it calls virtqueue_add_sgs() instead of his multi-part API). This is similar to the previous patch, but a bit more radical because the bio and req paths now share the buffer construction code. Because the req path doesn't use vbr->sg, however, we need to add a couple of arguments to __virtblk_add_req. We also need to teach __virtblk_add_req how to build SCSI command requests. Signed-off-by: Paolo Bonzini Signed-off-by: Rusty Russell Reviewed-by: Asias He --- drivers/block/virtio_blk.c | 69 ++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index cfbe39d35277..cc88b29c6393 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -102,19 +102,40 @@ static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk, } static int __virtblk_add_req(struct virtqueue *vq, - struct virtblk_req *vbr) + struct virtblk_req *vbr, + struct scatterlist *data_sg, + unsigned data_nents) { - struct scatterlist hdr, status, *sgs[3]; + struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6]; unsigned int num_out = 0, num_in = 0; + int type = vbr->out_hdr.type & ~VIRTIO_BLK_T_OUT; sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr)); sgs[num_out++] = &hdr; - if (vbr->nents) { + /* + * If this is a packet command we need a couple of additional headers. + * Behind the normal outhdr we put a segment with the scsi command + * block, and before the normal inhdr we put the sense data and the + * inhdr with additional status information. + */ + if (type == VIRTIO_BLK_T_SCSI_CMD) { + sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len); + sgs[num_out++] = &cmd; + } + + if (data_nents) { if (vbr->out_hdr.type & VIRTIO_BLK_T_OUT) - sgs[num_out++] = vbr->sg; + sgs[num_out++] = data_sg; else - sgs[num_out + num_in++] = vbr->sg; + sgs[num_out + num_in++] = data_sg; + } + + if (type == VIRTIO_BLK_T_SCSI_CMD) { + sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE); + sgs[num_out + num_in++] = &sense; + sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr)); + sgs[num_out + num_in++] = &inhdr; } sg_init_one(&status, &vbr->status, sizeof(vbr->status)); @@ -130,7 +151,8 @@ static void virtblk_add_req(struct virtblk_req *vbr) int ret; spin_lock_irq(vblk->disk->queue->queue_lock); - while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr)) < 0)) { + while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr, vbr->sg, + vbr->nents)) < 0)) { prepare_to_wait_exclusive(&vblk->queue_wait, &wait, TASK_UNINTERRUPTIBLE); @@ -283,7 +305,7 @@ static void virtblk_done(struct virtqueue *vq) static bool do_req(struct request_queue *q, struct virtio_blk *vblk, struct request *req) { - unsigned long num, out = 0, in = 0; + unsigned int num; struct virtblk_req *vbr; vbr = virtblk_alloc_req(vblk, GFP_ATOMIC); @@ -320,40 +342,15 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, } } - sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); - - /* - * If this is a packet command we need a couple of additional headers. - * Behind the normal outhdr we put a segment with the scsi command - * block, and before the normal inhdr we put the sense data and the - * inhdr with additional status information before the normal inhdr. - */ - if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) - sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len); - - num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); - - if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { - sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE); - sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, - sizeof(vbr->in_hdr)); - } - - sg_set_buf(&vblk->sg[num + out + in++], &vbr->status, - sizeof(vbr->status)); - + num = blk_rq_map_sg(q, vbr->req, vblk->sg); if (num) { - if (rq_data_dir(vbr->req) == WRITE) { + if (rq_data_dir(vbr->req) == WRITE) vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; - out += num; - } else { + else vbr->out_hdr.type |= VIRTIO_BLK_T_IN; - in += num; - } } - if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr, - GFP_ATOMIC) < 0) { + if (__virtblk_add_req(vblk->vq, vbr, vblk->sg, num) < 0) { mempool_free(vbr, vblk->pool); return false; } -- cgit From 0a11cc36f7b33fa2de0ad95199d2f2ab896fbd93 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:27 +1030 Subject: virtio_blk: remove nents member. It's simply a flag as to whether we have data now, so make it an explicit function parameter rather than a member of struct virtblk_req. Signed-off-by: Rusty Russell Reviewed-by: Asias He --- drivers/block/virtio_blk.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index cc88b29c6393..64723953e1c9 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -62,7 +62,6 @@ struct virtblk_req struct virtio_blk *vblk; int flags; u8 status; - int nents; struct scatterlist sg[]; }; @@ -104,7 +103,7 @@ static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk, static int __virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr, struct scatterlist *data_sg, - unsigned data_nents) + bool have_data) { struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6]; unsigned int num_out = 0, num_in = 0; @@ -124,7 +123,7 @@ static int __virtblk_add_req(struct virtqueue *vq, sgs[num_out++] = &cmd; } - if (data_nents) { + if (have_data) { if (vbr->out_hdr.type & VIRTIO_BLK_T_OUT) sgs[num_out++] = data_sg; else @@ -144,7 +143,7 @@ static int __virtblk_add_req(struct virtqueue *vq, return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); } -static void virtblk_add_req(struct virtblk_req *vbr) +static void virtblk_add_req(struct virtblk_req *vbr, bool have_data) { struct virtio_blk *vblk = vbr->vblk; DEFINE_WAIT(wait); @@ -152,7 +151,7 @@ static void virtblk_add_req(struct virtblk_req *vbr) spin_lock_irq(vblk->disk->queue->queue_lock); while (unlikely((ret = __virtblk_add_req(vblk->vq, vbr, vbr->sg, - vbr->nents)) < 0)) { + have_data)) < 0)) { prepare_to_wait_exclusive(&vblk->queue_wait, &wait, TASK_UNINTERRUPTIBLE); @@ -173,30 +172,31 @@ static void virtblk_bio_send_flush(struct virtblk_req *vbr) vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = 0; - vbr->nents = 0; - virtblk_add_req(vbr); + virtblk_add_req(vbr, false); } static void virtblk_bio_send_data(struct virtblk_req *vbr) { struct virtio_blk *vblk = vbr->vblk; struct bio *bio = vbr->bio; + bool have_data; vbr->flags &= ~VBLK_IS_FLUSH; vbr->out_hdr.type = 0; vbr->out_hdr.sector = bio->bi_sector; vbr->out_hdr.ioprio = bio_prio(bio); - vbr->nents = blk_bio_map_sg(vblk->disk->queue, bio, vbr->sg); - if (vbr->nents) { + if (blk_bio_map_sg(vblk->disk->queue, bio, vbr->sg)) { + have_data = true; if (bio->bi_rw & REQ_WRITE) vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; else vbr->out_hdr.type |= VIRTIO_BLK_T_IN; - } + } else + have_data = false; - virtblk_add_req(vbr); + virtblk_add_req(vbr, have_data); } static void virtblk_bio_send_data_work(struct work_struct *work) -- cgit From 682993b4e445bdfe9935d5e6e298565b7e11d7ee Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Wed, 20 Mar 2013 15:44:28 +1030 Subject: virtio-scsi: use virtqueue_add_sgs for command buffers Using the new virtqueue_add_sgs function lets us simplify the queueing path. In particular, all data protected by the tgt_lock is just gone (multiqueue will find a new use for the lock). Signed-off-by: Wanlong Gao Acked-by: Paolo Bonzini Reviewed-by: Asias He Signed-off-by: Rusty Russell --- drivers/scsi/virtio_scsi.c | 100 +++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 0f5dd2804ae5..77206d0eb6a9 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -61,11 +61,8 @@ struct virtio_scsi_vq { /* Per-target queue state */ struct virtio_scsi_target_state { - /* Protects sg. Lock hierarchy is tgt_lock -> vq_lock. */ + /* Never held at the same time as vq_lock. */ spinlock_t tgt_lock; - - /* For sglist construction when adding commands to the virtqueue. */ - struct scatterlist sg[]; }; /* Driver instance state */ @@ -353,75 +350,61 @@ static void virtscsi_event_done(struct virtqueue *vq) spin_unlock_irqrestore(&vscsi->event_vq.vq_lock, flags); }; -static void virtscsi_map_sgl(struct scatterlist *sg, unsigned int *p_idx, - struct scsi_data_buffer *sdb) -{ - struct sg_table *table = &sdb->table; - struct scatterlist *sg_elem; - unsigned int idx = *p_idx; - int i; - - for_each_sg(table->sgl, sg_elem, table->nents, i) - sg[idx++] = *sg_elem; - - *p_idx = idx; -} - /** - * virtscsi_map_cmd - map a scsi_cmd to a virtqueue scatterlist - * @vscsi : virtio_scsi state + * virtscsi_add_cmd - add a virtio_scsi_cmd to a virtqueue + * @vq : the struct virtqueue we're talking about * @cmd : command structure - * @out_num : number of read-only elements - * @in_num : number of write-only elements * @req_size : size of the request buffer * @resp_size : size of the response buffer - * - * Called with tgt_lock held. + * @gfp : flags to use for memory allocations */ -static void virtscsi_map_cmd(struct virtio_scsi_target_state *tgt, - struct virtio_scsi_cmd *cmd, - unsigned *out_num, unsigned *in_num, - size_t req_size, size_t resp_size) +static int virtscsi_add_cmd(struct virtqueue *vq, + struct virtio_scsi_cmd *cmd, + size_t req_size, size_t resp_size, gfp_t gfp) { struct scsi_cmnd *sc = cmd->sc; - struct scatterlist *sg = tgt->sg; - unsigned int idx = 0; + struct scatterlist *sgs[4], req, resp; + struct sg_table *out, *in; + unsigned out_num = 0, in_num = 0; + + out = in = NULL; + + if (sc && sc->sc_data_direction != DMA_NONE) { + if (sc->sc_data_direction != DMA_FROM_DEVICE) + out = &scsi_out(sc)->table; + if (sc->sc_data_direction != DMA_TO_DEVICE) + in = &scsi_in(sc)->table; + } /* Request header. */ - sg_set_buf(&sg[idx++], &cmd->req, req_size); + sg_init_one(&req, &cmd->req, req_size); + sgs[out_num++] = &req; /* Data-out buffer. */ - if (sc && sc->sc_data_direction != DMA_FROM_DEVICE) - virtscsi_map_sgl(sg, &idx, scsi_out(sc)); - - *out_num = idx; + if (out) + sgs[out_num++] = out->sgl; /* Response header. */ - sg_set_buf(&sg[idx++], &cmd->resp, resp_size); + sg_init_one(&resp, &cmd->resp, resp_size); + sgs[out_num + in_num++] = &resp; /* Data-in buffer */ - if (sc && sc->sc_data_direction != DMA_TO_DEVICE) - virtscsi_map_sgl(sg, &idx, scsi_in(sc)); + if (in) + sgs[out_num + in_num++] = in->sgl; - *in_num = idx - *out_num; + return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, gfp); } -static int virtscsi_kick_cmd(struct virtio_scsi_target_state *tgt, - struct virtio_scsi_vq *vq, +static int virtscsi_kick_cmd(struct virtio_scsi_vq *vq, struct virtio_scsi_cmd *cmd, size_t req_size, size_t resp_size, gfp_t gfp) { - unsigned int out_num, in_num; unsigned long flags; int err; bool needs_kick = false; - spin_lock_irqsave(&tgt->tgt_lock, flags); - virtscsi_map_cmd(tgt, cmd, &out_num, &in_num, req_size, resp_size); - - spin_lock(&vq->vq_lock); - err = virtqueue_add_buf(vq->vq, tgt->sg, out_num, in_num, cmd, gfp); - spin_unlock(&tgt->tgt_lock); + spin_lock_irqsave(&vq->vq_lock, flags); + err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size, gfp); if (!err) needs_kick = virtqueue_kick_prepare(vq->vq); @@ -435,7 +418,6 @@ static int virtscsi_kick_cmd(struct virtio_scsi_target_state *tgt, static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) { struct virtio_scsi *vscsi = shost_priv(sh); - struct virtio_scsi_target_state *tgt = vscsi->tgt[sc->device->id]; struct virtio_scsi_cmd *cmd; int ret; @@ -469,7 +451,7 @@ static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) BUG_ON(sc->cmd_len > VIRTIO_SCSI_CDB_SIZE); memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len); - if (virtscsi_kick_cmd(tgt, &vscsi->req_vq, cmd, + if (virtscsi_kick_cmd(&vscsi->req_vq, cmd, sizeof cmd->req.cmd, sizeof cmd->resp.cmd, GFP_ATOMIC) == 0) ret = 0; @@ -483,11 +465,10 @@ out: static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) { DECLARE_COMPLETION_ONSTACK(comp); - struct virtio_scsi_target_state *tgt = vscsi->tgt[cmd->sc->device->id]; int ret = FAILED; cmd->comp = ∁ - if (virtscsi_kick_cmd(tgt, &vscsi->ctrl_vq, cmd, + if (virtscsi_kick_cmd(&vscsi->ctrl_vq, cmd, sizeof cmd->req.tmf, sizeof cmd->resp.tmf, GFP_NOIO) < 0) goto out; @@ -588,20 +569,16 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, } static struct virtio_scsi_target_state *virtscsi_alloc_tgt( - struct virtio_device *vdev, int sg_elems) + struct virtio_device *vdev) { struct virtio_scsi_target_state *tgt; gfp_t gfp_mask = GFP_KERNEL; - /* We need extra sg elements at head and tail. */ - tgt = kmalloc(sizeof(*tgt) + sizeof(tgt->sg[0]) * (sg_elems + 2), - gfp_mask); - + tgt = kmalloc(sizeof(*tgt), gfp_mask); if (!tgt) return NULL; spin_lock_init(&tgt->tgt_lock); - sg_init_table(tgt->sg, sg_elems + 2); return tgt; } @@ -635,7 +612,7 @@ static int virtscsi_init(struct virtio_device *vdev, { int err; struct virtqueue *vqs[3]; - u32 i, sg_elems; + u32 i; vq_callback_t *callbacks[] = { virtscsi_ctrl_done, @@ -663,11 +640,8 @@ static int virtscsi_init(struct virtio_device *vdev, if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) virtscsi_kick_event_all(vscsi); - /* We need to know how many segments before we allocate. */ - sg_elems = virtscsi_config_get(vdev, seg_max) ?: 1; - for (i = 0; i < num_targets; i++) { - vscsi->tgt[i] = virtscsi_alloc_tgt(vdev, sg_elems); + vscsi->tgt[i] = virtscsi_alloc_tgt(vdev); if (!vscsi->tgt[i]) { err = -ENOMEM; goto out; -- cgit From bf9582910b26525d4eeaa9840b07e7bf820f04fb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:28 +1030 Subject: virtio_scsi: use virtqueue_add_inbuf() for virtscsi_kick_event. It's a bit clearer, and add_buf is going away. Signed-off-by: Rusty Russell Reviewed-by: Asias He --- drivers/scsi/virtio_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 77206d0eb6a9..b53ba9e18f47 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -222,8 +222,8 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); - err = virtqueue_add_buf(vscsi->event_vq.vq, &sg, 0, 1, event_node, - GFP_ATOMIC); + err = virtqueue_add_inbuf(vscsi->event_vq.vq, &sg, 1, event_node, + GFP_ATOMIC); if (!err) virtqueue_kick(vscsi->event_vq.vq); -- cgit From f7bc9594513d8f5a6e88e1486d48687ce5831834 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:28 +1030 Subject: virtio_net: use virtqueue_add_sgs[] for command buffers. It's a bit cleaner to hand multiple sgs, rather than one big one. Cc: "Michael S. Tsirkin" Tested-by: Wanlong Gao Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 57ac4b0294bc..be704876af8a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -39,7 +39,6 @@ module_param(gso, bool, 0444); #define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) #define GOOD_COPY_LEN 128 -#define VIRTNET_SEND_COMMAND_SG_MAX 2 #define VIRTNET_DRIVER_VERSION "1.0.0" struct virtnet_stats { @@ -767,32 +766,35 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) * never fail unless improperly formated. */ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, - struct scatterlist *data, int out, int in) + struct scatterlist *out, + struct scatterlist *in) { - struct scatterlist *s, sg[VIRTNET_SEND_COMMAND_SG_MAX + 2]; + struct scatterlist *sgs[4], hdr, stat; struct virtio_net_ctrl_hdr ctrl; virtio_net_ctrl_ack status = ~0; - unsigned int tmp; - int i; + unsigned out_num = 0, in_num = 0, tmp; /* Caller should know better */ - BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) || - (out + in > VIRTNET_SEND_COMMAND_SG_MAX)); - - out++; /* Add header */ - in++; /* Add return status */ + BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)); ctrl.class = class; ctrl.cmd = cmd; + /* Add header */ + sg_init_one(&hdr, &ctrl, sizeof(ctrl)); + sgs[out_num++] = &hdr; - sg_init_table(sg, out + in); + if (out) + sgs[out_num++] = out; + if (in) + sgs[out_num + in_num++] = in; - sg_set_buf(&sg[0], &ctrl, sizeof(ctrl)); - for_each_sg(data, s, out + in - 2, i) - sg_set_buf(&sg[i + 1], sg_virt(s), s->length); - sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); + /* Add return status. */ + sg_init_one(&stat, &status, sizeof(status)); + sgs[out_num + in_num++] = &stat; - BUG_ON(virtqueue_add_buf(vi->cvq, sg, out, in, vi, GFP_ATOMIC) < 0); + BUG_ON(out_num + in_num > ARRAY_SIZE(sgs)); + BUG_ON(virtqueue_add_sgs(vi->cvq, sgs, out_num, in_num, vi, GFP_ATOMIC) + < 0); virtqueue_kick(vi->cvq); @@ -821,7 +823,7 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) sg_init_one(&sg, addr->sa_data, dev->addr_len); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_ADDR_SET, - &sg, 1, 0)) { + &sg, NULL)) { dev_warn(&vdev->dev, "Failed to set mac address by vq command.\n"); return -EINVAL; @@ -889,8 +891,7 @@ static void virtnet_ack_link_announce(struct virtnet_info *vi) { rtnl_lock(); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_ANNOUNCE, - VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL, - 0, 0)) + VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL, NULL)) dev_warn(&vi->dev->dev, "Failed to ack link announce.\n"); rtnl_unlock(); } @@ -908,7 +909,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs) sg_init_one(&sg, &s, sizeof(s)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, - VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg, 1, 0)){ + VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg, NULL)) { dev_warn(&dev->dev, "Fail to set num of queue pairs to %d\n", queue_pairs); return -EINVAL; @@ -955,7 +956,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, VIRTIO_NET_CTRL_RX_PROMISC, - sg, 1, 0)) + sg, NULL)) dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", promisc ? "en" : "dis"); @@ -963,7 +964,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, VIRTIO_NET_CTRL_RX_ALLMULTI, - sg, 1, 0)) + sg, NULL)) dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n", allmulti ? "en" : "dis"); @@ -1000,7 +1001,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_TABLE_SET, - sg, 2, 0)) + sg, NULL)) dev_warn(&dev->dev, "Failed to set MAC fitler table.\n"); kfree(buf); @@ -1014,7 +1015,7 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) sg_init_one(&sg, &vid, sizeof(vid)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, - VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0)) + VIRTIO_NET_CTRL_VLAN_ADD, &sg, NULL)) dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); return 0; } @@ -1027,7 +1028,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) sg_init_one(&sg, &vid, sizeof(vid)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, - VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) + VIRTIO_NET_CTRL_VLAN_DEL, &sg, NULL)) dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid); return 0; } -- cgit From 9dc7b9e4d0a6daac5b1f29a338911d63d34533cd Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:28 +1030 Subject: virtio_net: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Cc: "Michael S. Tsirkin" Reviewed-by: Asias He Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index be704876af8a..d88d4366d9ac 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -443,7 +443,7 @@ static int add_recvbuf_small(struct receive_queue *rq, gfp_t gfp) skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); - err = virtqueue_add_buf(rq->vq, rq->sg, 0, 2, skb, gfp); + err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp); if (err < 0) dev_kfree_skb(skb); @@ -488,8 +488,8 @@ static int add_recvbuf_big(struct receive_queue *rq, gfp_t gfp) /* chain first in list head */ first->private = (unsigned long)list; - err = virtqueue_add_buf(rq->vq, rq->sg, 0, MAX_SKB_FRAGS + 2, - first, gfp); + err = virtqueue_add_inbuf(rq->vq, rq->sg, MAX_SKB_FRAGS + 2, + first, gfp); if (err < 0) give_pages(rq, first); @@ -507,7 +507,7 @@ static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp) sg_init_one(rq->sg, page_address(page), PAGE_SIZE); - err = virtqueue_add_buf(rq->vq, rq->sg, 0, 1, page, gfp); + err = virtqueue_add_inbuf(rq->vq, rq->sg, 1, page, gfp); if (err < 0) give_pages(rq, page); @@ -710,8 +710,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) sg_set_buf(sq->sg, &hdr->hdr, sizeof hdr->hdr); num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1; - return virtqueue_add_buf(sq->vq, sq->sg, num_sg, - 0, skb, GFP_ATOMIC); + return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC); } static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) -- cgit From fb6aa6fcfec29932122cb0fb2d5d1f7700a9883b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:29 +1030 Subject: virtio_rng: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Signed-off-by: Rusty Russell Reviewed-by: Asias He --- drivers/char/hw_random/virtio-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 10fd71ccf587..842e2d55d335 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -47,7 +47,7 @@ static void register_buffer(u8 *buf, size_t size) sg_init_one(&sg, buf, size); /* There should always be room for one buffer. */ - if (virtqueue_add_buf(vq, &sg, 0, 1, buf, GFP_KERNEL) < 0) + if (virtqueue_add_inbuf(vq, &sg, 1, buf, GFP_KERNEL) < 0) BUG(); virtqueue_kick(vq); -- cgit From 6797999d99587e7b4189cf24c8f1053e02444703 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:29 +1030 Subject: virtio_console: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Acked-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e905d5f53051..6d59f166e0e9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -502,7 +502,7 @@ static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf) sg_init_one(sg, buf->buf, buf->size); - ret = virtqueue_add_buf(vq, sg, 0, 1, buf, GFP_ATOMIC); + ret = virtqueue_add_inbuf(vq, sg, 1, buf, GFP_ATOMIC); virtqueue_kick(vq); if (!ret) ret = vq->num_free; @@ -569,7 +569,7 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, vq = portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); - if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { + if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { virtqueue_kick(vq); while (!virtqueue_get_buf(vq, &len)) cpu_relax(); @@ -618,7 +618,7 @@ static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, reclaim_consumed_buffers(port); - err = virtqueue_add_buf(out_vq, sg, nents, 0, data, GFP_ATOMIC); + err = virtqueue_add_outbuf(out_vq, sg, nents, data, GFP_ATOMIC); /* Tell Host to go! */ virtqueue_kick(out_vq); -- cgit From 71bcbecc89a6b24f2c60d3e4271e76013fa46860 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:29 +1030 Subject: caif_virtio: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Cc: Sjur Brendeland Signed-off-by: Rusty Russell --- drivers/net/caif/caif_virtio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index b1e1205e4e28..f6caa1eb4cd6 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c @@ -572,8 +572,7 @@ static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev) goto err; } - ret = virtqueue_add_buf(cfv->vq_tx, &sg, 1, 0, - buf_info, GFP_ATOMIC); + ret = virtqueue_add_outbuf(cfv->vq_tx, &sg, 1, buf_info, GFP_ATOMIC); if (unlikely((ret < 0))) { /* If flow control works, this shouldn't happen */ netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n", -- cgit From cee51d69a45b6ce202d1d17551165fb3c76dfdb9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:29 +1030 Subject: virtio_rpmsg_bus: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Cc: Ohad Ben-Cohen Signed-off-by: Rusty Russell --- drivers/rpmsg/virtio_rpmsg_bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index a59684b5fc68..33d827b30e95 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -757,14 +757,14 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, mutex_lock(&vrp->tx_lock); /* add message to the remote processor's virtqueue */ - err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL); + err = virtqueue_add_outbuf(vrp->svq, &sg, 1, msg, GFP_KERNEL); if (err) { /* * need to reclaim the buffer here, otherwise it's lost * (memory won't leak, but rpmsg won't use it again for TX). * this will wait for a buffer management overhaul. */ - dev_err(dev, "virtqueue_add_buf failed: %d\n", err); + dev_err(dev, "virtqueue_add_outbuf failed: %d\n", err); goto out; } @@ -839,7 +839,7 @@ static void rpmsg_recv_done(struct virtqueue *rvq) sg_init_one(&sg, msg, RPMSG_BUF_SIZE); /* add the buffer back to the remote processor's virtqueue */ - err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL); + err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, msg, GFP_KERNEL); if (err < 0) { dev_err(dev, "failed to add a virtqueue buffer: %d\n", err); return; @@ -970,7 +970,7 @@ static int rpmsg_probe(struct virtio_device *vdev) sg_init_one(&sg, cpu_addr, RPMSG_BUF_SIZE); - err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr, + err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, cpu_addr, GFP_KERNEL); WARN_ON(err); /* sanity check; this can't really happen */ } -- cgit From 92549abc6a6573294fc1bb9330db8b52dedfea5f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 Mar 2013 15:44:30 +1030 Subject: virtio_balloon: use simplified virtqueue accessors. We never add buffers with input and output parts, so use the new accessors. Signed-off-by: Rusty Russell --- drivers/virtio/virtio_balloon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 8dab163c5ef0..bd3ae324a1a2 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -108,7 +108,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) sg_init_one(&sg, vb->pfns, sizeof(vb->pfns[0]) * vb->num_pfns); /* We should always be able to add one buffer to an empty queue. */ - if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0) + if (virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL) < 0) BUG(); virtqueue_kick(vq); @@ -256,7 +256,7 @@ static void stats_handle_request(struct virtio_balloon *vb) if (!virtqueue_get_buf(vq, &len)) return; sg_init_one(&sg, vb->stats, sizeof(vb->stats)); - if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0) + if (virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL) < 0) BUG(); virtqueue_kick(vq); } @@ -341,7 +341,7 @@ static int init_vqs(struct virtio_balloon *vb) * use it to signal us later. */ sg_init_one(&sg, vb->stats, sizeof vb->stats); - if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb, GFP_KERNEL) + if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL) < 0) BUG(); virtqueue_kick(vb->stats_vq); -- cgit From e8d891fb7b8fe4ee7311820594323d46dbc31d45 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 20 Mar 2013 08:01:53 +0200 Subject: usb: phy: gpio-vbus: don't ignore regulator APIs return value Due to recent changes to regulator API, all users which don't check regulator_{en,dis}able()'s return value will generate compile warnings. Add such checks to gpio-vbus. Cc: Mark Brown Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-gpio-vbus-usb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index a7d4ac591982..4c76074e518d 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -61,6 +61,7 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) { struct regulator *vbus_draw = gpio_vbus->vbus_draw; int enabled; + int ret; if (!vbus_draw) return; @@ -69,12 +70,16 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) if (mA) { regulator_set_current_limit(vbus_draw, 0, 1000 * mA); if (!enabled) { - regulator_enable(vbus_draw); + ret = regulator_enable(vbus_draw); + if (ret < 0) + return; gpio_vbus->vbus_draw_enabled = 1; } } else { if (enabled) { - regulator_disable(vbus_draw); + ret = regulator_disable(vbus_draw); + if (ret < 0) + return; gpio_vbus->vbus_draw_enabled = 0; } } -- cgit From b9545b48ff4c725ea71f1d9fd9b78da08ddd6551 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Mar 2013 11:34:44 +0200 Subject: iwlwifi: mvm: MVM op_mode is supported on 7000 only The code removed in this patch was used for bring up on older NICs. No MVM capable fw will ever be released for older NICs, so remove that code. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 37 +------- drivers/net/wireless/iwlwifi/mvm/fw.c | 10 +-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 5 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 136 +++++++----------------------- drivers/net/wireless/iwlwifi/mvm/ops.c | 12 --- 5 files changed, 38 insertions(+), 162 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index f8d7e88234e4..0e94d8b91956 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -278,38 +278,7 @@ enum { NVM_ACCESS_TARGET_EEPROM = 2, }; -/** - * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM. - * @op_code: 0 - read, 1 - write. - * @target: NVM_ACCESS_TARGET_*. should be 0 for read. - * @cache_refresh: 0 - None, 1- NVM. - * @offset: offset in the nvm data. - * @length: of the chunk. - * @data: empty on read, the NVM chunk on write - */ -struct iwl_nvm_access_cmd_ver1 { - u8 op_code; - u8 target; - u8 cache_refresh; - u8 reserved; - __le16 offset; - __le16 length; - u8 data[]; -} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */ - -/** - * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD - * @offset: the offset in the nvm data - * @length: of the chunk - * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write - */ -struct iwl_nvm_access_resp_ver1 { - __le16 offset; - __le16 length; - u8 data[]; -} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */ - -/* Section types for NVM_ACCESS_CMD version 2 */ +/* Section types for NVM_ACCESS_CMD */ enum { NVM_SECTION_TYPE_HW = 0, NVM_SECTION_TYPE_SW, @@ -330,7 +299,7 @@ enum { * @length: in bytes, to read/write * @data: if write operation, the data to write. On read its empty */ -struct iwl_nvm_access_cmd_ver2 { +struct iwl_nvm_access_cmd { u8 op_code; u8 target; __le16 type; @@ -347,7 +316,7 @@ struct iwl_nvm_access_cmd_ver2 { * @status: 0 for success, fail otherwise * @data: if read operation, the data returned. Empty on write. */ -struct iwl_nvm_access_resp_ver2 { +struct iwl_nvm_access_resp { __le16 offset; __le16 length; __le16 type; diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 1006b3204e7b..d43e2a57d354 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -330,12 +330,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) if (ret) goto error; - /* WkP doesn't have all calibrations, need to set default values */ - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - ret = iwl_set_default_calibrations(mvm); - if (ret) - goto error; - } + /* need to set default values */ + ret = iwl_set_default_calibrations(mvm); + if (ret) + goto error; /* * Send phy configurations command to init uCode diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 203eb85e03d3..d022e44e83a1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -281,10 +281,7 @@ struct iwl_mvm { atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; struct iwl_nvm_data *nvm_data; - /* eeprom blob for debugfs/testmode */ - u8 *eeprom_blob; - size_t eeprom_blob_size; - /* NVM sections for 7000 family */ + /* NVM sections */ struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS]; /* EEPROM MAC addresses */ diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 93e3d0f174cc..b8ec02f89acc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -77,26 +77,8 @@ static const int nvm_to_read[] = { /* Default NVM size to read */ #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); -/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ -union iwl_nvm_access_cmd { - struct iwl_nvm_access_cmd_ver1 ver1; - struct iwl_nvm_access_cmd_ver2 ver2; -}; -union iwl_nvm_access_resp { - struct iwl_nvm_access_resp_ver1 ver1; - struct iwl_nvm_access_resp_ver2 ver2; -}; - -static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd, - u16 offset, u16 length) -{ - cmd->offset = cpu_to_le16(offset); - cmd->length = cpu_to_le16(length); - cmd->cache_refresh = 1; -} - -static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd, - u16 offset, u16 length, u16 section) +static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd, + u16 offset, u16 length, u16 section) { cmd->offset = cpu_to_le16(offset); cmd->length = cpu_to_le16(length); @@ -106,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd, static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, u16 offset, u16 length, u8 *data) { - union iwl_nvm_access_cmd nvm_access_cmd; - union iwl_nvm_access_resp *nvm_resp; + struct iwl_nvm_access_cmd nvm_access_cmd = {}; + struct iwl_nvm_access_resp *nvm_resp; struct iwl_rx_packet *pkt; struct iwl_host_cmd cmd = { .id = NVM_ACCESS_CMD, @@ -117,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, int ret, bytes_read, offset_read; u8 *resp_data; - memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd)); - - /* TODO: not sure family should be the decider, maybe FW version? */ - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2), - offset, length, section); - cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2); - } else { - iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1), - offset, length); - cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1); - } + iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section); + cmd.len[0] = sizeof(struct iwl_nvm_access_cmd); ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret) @@ -144,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, /* Extract NVM response */ nvm_resp = (void *)pkt->data; - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - ret = le16_to_cpu(nvm_resp->ver2.status); - bytes_read = le16_to_cpu(nvm_resp->ver2.length); - offset_read = le16_to_cpu(nvm_resp->ver2.offset); - resp_data = nvm_resp->ver2.data; - } else { - ret = le16_to_cpu(nvm_resp->ver1.length) <= 0; - bytes_read = le16_to_cpu(nvm_resp->ver1.length); - offset_read = le16_to_cpu(nvm_resp->ver1.offset); - resp_data = nvm_resp->ver1.data; - } + ret = le16_to_cpu(nvm_resp->status); + bytes_read = le16_to_cpu(nvm_resp->length); + offset_read = le16_to_cpu(nvm_resp->offset); + resp_data = nvm_resp->data; if (ret) { IWL_ERR(mvm, "NVM access command failed with status %d (device: %s)\n", @@ -194,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, { u16 length, offset = 0; int ret; - bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; /* Set nvm section read length */ length = IWL_NVM_DEFAULT_CHUNK_SIZE; - /* - * if length is greater than EEPROM size, truncate it because uCode - * doesn't check it by itself, and exit the loop when reached. - */ - if (old_eeprom && length > mvm->cfg->base_params->eeprom_size) - length = mvm->cfg->base_params->eeprom_size; ret = length; /* Read the NVM until exhausted (reading less than requested) */ @@ -217,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, return ret; } offset += ret; - if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size) - break; } IWL_INFO(mvm, "NVM section %d read completed\n", section); @@ -252,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm) int ret, i, section; u8 *nvm_buffer, *temp; - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - /* TODO: find correct NVM max size for a section */ - nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, - GFP_KERNEL); - if (!nvm_buffer) - return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { - section = nvm_to_read[i]; - /* we override the constness for initial read */ - ret = iwl_nvm_read_section(mvm, section, nvm_buffer); - if (ret < 0) - break; - temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); - if (!temp) { - ret = -ENOMEM; - break; - } - mvm->nvm_sections[section].data = temp; - mvm->nvm_sections[section].length = ret; - } - kfree(nvm_buffer); + /* TODO: find correct NVM max size for a section */ + nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, + GFP_KERNEL); + if (!nvm_buffer) + return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { + section = nvm_to_read[i]; + /* we override the constness for initial read */ + ret = iwl_nvm_read_section(mvm, section, nvm_buffer); if (ret < 0) - return ret; - } else { - /* allocate eeprom */ - mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size; - IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n", - mvm->eeprom_blob_size); - mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL); - if (!mvm->eeprom_blob) - return -ENOMEM; - - ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob); - if (ret != mvm->eeprom_blob_size) { - IWL_ERR(mvm, "Read partial NVM %d/%zd\n", - ret, mvm->eeprom_blob_size); - kfree(mvm->eeprom_blob); - mvm->eeprom_blob = NULL; - return -EINVAL; + break; + temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); + if (!temp) { + ret = -ENOMEM; + break; } + mvm->nvm_sections[section].data = temp; + mvm->nvm_sections[section].length = ret; } + kfree(nvm_buffer); + if (ret < 0) + return ret; ret = 0; - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) - mvm->nvm_data = iwl_parse_nvm_sections(mvm); - else - mvm->nvm_data = - iwl_parse_eeprom_data(mvm->trans->dev, - mvm->cfg, - mvm->eeprom_blob, - mvm->eeprom_blob_size); - - if (!mvm->nvm_data) { - kfree(mvm->eeprom_blob); - mvm->eeprom_blob = NULL; - ret = -ENOMEM; - } + mvm->nvm_data = iwl_parse_nvm_sections(mvm); return ret; } diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 828bdddd07e9..b490426294cc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -319,16 +319,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, }; int err, scan_size; - switch (cfg->device_family) { - case IWL_DEVICE_FAMILY_6030: - case IWL_DEVICE_FAMILY_6005: - case IWL_DEVICE_FAMILY_7000: - break; - default: - IWL_ERR(trans, "Trying to load mvm on an unsupported device\n"); - return NULL; - } - /******************************** * 1. Allocating and configuring HW data ********************************/ @@ -444,7 +434,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, out_free: iwl_phy_db_free(mvm->phy_db); kfree(mvm->scan_cmd); - kfree(mvm->eeprom_blob); iwl_trans_stop_hw(trans, true); ieee80211_free_hw(mvm->hw); return NULL; @@ -466,7 +455,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) iwl_phy_db_free(mvm->phy_db); mvm->phy_db = NULL; - kfree(mvm->eeprom_blob); iwl_free_nvm_data(mvm->nvm_data); for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) kfree(mvm->nvm_sections[i].data); -- cgit From 6caffd4f9d11cbd9651d93a511ac385ce84aab83 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Mar 2013 13:15:21 +0100 Subject: iwlwifi: mvm: suppress key error messages in AP mode In AP mode, don't attempt to program GTKs into the device, they're used for TX only so not needed and programming them causes error messages. Also, in this case and if key programming fails, avoid trying to remove the key that isn't present later. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index ed2d8754c82b..f64bca5da450 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1087,6 +1087,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: + if (vif->type == NL80211_IFTYPE_AP && !sta) { + /* GTK on AP interface is a TX-only key, return 0 */ + ret = 0; + key->hw_key_idx = STA_KEY_IDX_INVALID; + break; + } + IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false); if (ret) { @@ -1095,11 +1102,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, * can't add key for RX, but we don't need it * in the device for TX so still return 0 */ + key->hw_key_idx = STA_KEY_IDX_INVALID; ret = 0; } break; case DISABLE_KEY: + if (key->hw_key_idx == STA_KEY_IDX_INVALID) { + ret = 0; + break; + } + IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n"); ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key); break; -- cgit From 571765c8598a86c81b658e55285643506770fb2d Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Tue, 5 Mar 2013 15:26:03 +0200 Subject: iwlwifi: mvm: Add beacon notification handler Mostly for debugging purposes Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | 6 ++++++ drivers/net/wireless/iwlwifi/mvm/fw-api.h | 1 + drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 19 +++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 ++ 5 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h index 6d53850c5448..007a93b25bd7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h @@ -537,6 +537,12 @@ struct iwl_mac_beacon_cmd { struct ieee80211_hdr frame[0]; } __packed; +struct iwl_beacon_notif { + struct iwl_mvm_tx_resp beacon_notify_hdr; + __le64 tsf; + __le32 ibss_mgr_status; +} __packed; + /** * enum iwl_dump_control - dump (flush) control flags * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 0e94d8b91956..1073f2682221 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -151,6 +151,7 @@ enum { SET_CALIB_DEFAULT_CMD = 0x8e, + BEACON_NOTIFICATION = 0x90, BEACON_TEMPLATE_CMD = 0x91, TX_ANT_CONFIGURATION_CMD = 0x98, BT_CONFIG = 0x9b, diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 2779235daa35..a00fb730386f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -1013,3 +1013,22 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) mvmvif->uploaded = false; return 0; } + +int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_beacon_notif *beacon = (void *)pkt->data; + u16 status __maybe_unused = + le16_to_cpu(beacon->beacon_notify_hdr.status.status); + u32 rate __maybe_unused = + le32_to_cpu(beacon->beacon_notify_hdr.initial_rate); + + IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n", + status & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le64_to_cpu(beacon->tsf), + rate); + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d022e44e83a1..ea1fafd616e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -448,6 +448,9 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); /* Bindings */ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index b490426294cc..81ff28361dc2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -231,6 +231,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), + RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), @@ -276,6 +277,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(WEP_KEY), CMD(REPLY_RX_PHY_CMD), CMD(REPLY_RX_MPDU_CMD), + CMD(BEACON_NOTIFICATION), CMD(BEACON_TEMPLATE_CMD), CMD(STATISTICS_NOTIFICATION), CMD(TX_ANT_CONFIGURATION_CMD), -- cgit From cc904c7188c29847817f35e6966fec3014c7479b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 14 Mar 2013 08:35:06 +0200 Subject: iwlwifi: fix length check in multi-TB HCMD As reported by Ben Hutchings, there was a harmless issue in the checks being done on the lengths of the TBs while building the TFD for a multi-TB host command. Cc: stable@vger@kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8595c16f74de..cb5c6792e3a8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1264,7 +1264,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { int copy = 0; - if (!cmd->len) + if (!cmd->len[i]) continue; /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ -- cgit From 4620020b5d7ca34d1c03fa98b0ca457320cb7d71 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Mar 2013 16:38:32 +0200 Subject: iwlwifi: set rfkill in internal state of the transport We didn't update the internal of the PCIe transport when we read the RFkill state directly. Fix that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 17bedc50e753..12c4f31ca8fb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -475,6 +475,10 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill && !run_in_rfkill) return -ERFKILL; @@ -641,6 +645,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; int err; @@ -656,6 +661,10 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_enable_rfkill_int(trans); hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; @@ -694,6 +703,10 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, * op_mode. */ hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); } } -- cgit From 2d5d50ee596361566f7f84300117cba7d7672bc5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 31 Jan 2013 15:03:55 +0200 Subject: iwlwifi: dvm: don't send HCMD in restart flow There is a race between the restart flow and the workers. The workers are cancelled after the fw is already killed and might send HCMD when there is fw to handle them. Simply check that there is a fw to which the HCMD can be sent before actually sending it. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/lib.c | 9 +++++++++ drivers/net/wireless/iwlwifi/dvm/ucode.c | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 86ea5f4c3939..44ca0e57f9f7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -1261,6 +1261,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + /* + * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag + * in iwl_down but cancel the workers only later. + */ + if (!priv->ucode_loaded) { + IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id); + return -EIO; + } + /* * Synchronous commands from this op-mode must hold * the mutex, this ensures we don't try to send two diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 736fe9bb140e..1a4ac9236a44 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -367,6 +367,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } + priv->ucode_loaded = true; + if (ucode_type != IWL_UCODE_WOWLAN) { /* delay a bit to give rfkill time to run */ msleep(5); @@ -380,8 +382,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } - priv->ucode_loaded = true; - return 0; } -- cgit From bbcf50b1d6b38e34958a1572f4077fa12d3dc24d Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 18 Mar 2013 14:59:49 +0530 Subject: regulator: palmas: rename probe/remove callback functions When palmas regulator probe creates stack dump during initialization due to some crash, it prints the call trace as follows: [3.166321] [] (_regmap_read+0x5c/0xa8) from [] (regmap_read+0x44/0x5c) [3.174669] [] (regmap_read+0x44/0x5c) from [] (palmas_probe+0x240/0x7d0) [3.183193] [] (palmas_probe+0x240/0x7d0) from [] (platform_drv_probe+0x14/0x18) [3.192322] [] (platform_drv_probe+0x14/0x18) from [] (driver_probe_device+0x104/0x214) [3.202055] [] (driver_probe_device+0x104/0x214) from [] (bus_for_each_drv+0x5c/0x88) The palmas_probe is current name but it helps on debugging if the function name is more appropriate to the sub-module name. Renaming the palmas_probe() to palmas_regulator_probe() and palmas_remove() to palams_regulator_remove(). Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 122fea432d38..aec2d76096dd 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -581,7 +581,7 @@ static void palmas_dt_to_pdata(struct device *dev, } -static int palmas_probe(struct platform_device *pdev) +static int palmas_regulators_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; @@ -790,7 +790,7 @@ err_unregister_regulator: return ret; } -static int palmas_remove(struct platform_device *pdev) +static int palmas_regulators_remove(struct platform_device *pdev) { struct palmas_pmic *pmic = platform_get_drvdata(pdev); int id; @@ -818,8 +818,8 @@ static struct platform_driver palmas_driver = { .of_match_table = of_palmas_match_tbl, .owner = THIS_MODULE, }, - .probe = palmas_probe, - .remove = palmas_remove, + .probe = palmas_regulators_probe, + .remove = palmas_regulators_remove, }; static int __init palmas_init(void) -- cgit From 0d4e67174b03e3dcfe75ce7ec488770a5d443bf4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 19 Mar 2013 15:25:20 +0200 Subject: ath6kl: fix size_t printf warnings My new tracing code for ath6kl introduced these warnings on 64-bit: trace.h:38:1: warning: format '%d' expects argument of type 'int', but argument 4 has type 'size_t' [-Wformat] trace.h:61:1: warning: format '%d' expects argument of type 'int', but argument 4 has type 'size_t' [-Wformat] trace.h:84:1: warning: format '%d' expects argument of type 'int', but argument 6 has type 'size_t' [-Wformat] trace.h:119:1: warning: format '%d' expects argument of type 'int', but argument 7 has type 'size_t' [-Wformat] trace.h:173:1: warning: format '%d' expects argument of type 'int', but argument 3 has type 'size_t' [-Wformat] trace.h:193:1: warning: format '%d' expects argument of type 'int', but argument 5 has type 'size_t' [-Wformat] trace.h:221:1: warning: format '%d' expects argument of type 'int', but argument 5 has type 'size_t' [-Wformat] Fix them by using %zd. Reported-by: John W. Linville Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath6kl/trace.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h index 6af6fa038312..1a1ea7881b4d 100644 --- a/drivers/net/wireless/ath/ath6kl/trace.h +++ b/drivers/net/wireless/ath/ath6kl/trace.h @@ -53,7 +53,7 @@ TRACE_EVENT(ath6kl_wmi_cmd, ), TP_printk( - "id %d len %d", + "id %d len %zd", __entry->id, __entry->buf_len ) ); @@ -76,7 +76,7 @@ TRACE_EVENT(ath6kl_wmi_event, ), TP_printk( - "id %d len %d", + "id %d len %zd", __entry->id, __entry->buf_len ) ); @@ -108,7 +108,7 @@ TRACE_EVENT(ath6kl_sdio, ), TP_printk( - "%s addr 0x%x flags 0x%x len %d\n", + "%s addr 0x%x flags 0x%x len %zd\n", __entry->tx ? "tx" : "rx", __entry->addr, __entry->flags, @@ -161,7 +161,7 @@ TRACE_EVENT(ath6kl_sdio_scat, ), TP_printk( - "%s addr 0x%x flags 0x%x entries %d total_len %d\n", + "%s addr 0x%x flags 0x%x entries %d total_len %zd\n", __entry->tx ? "tx" : "rx", __entry->addr, __entry->flags, @@ -186,7 +186,7 @@ TRACE_EVENT(ath6kl_sdio_irq, ), TP_printk( - "irq len %d\n", __entry->buf_len + "irq len %zd\n", __entry->buf_len ) ); @@ -211,7 +211,7 @@ TRACE_EVENT(ath6kl_htc_rx, ), TP_printk( - "status %d endpoint %d len %d\n", + "status %d endpoint %d len %zd\n", __entry->status, __entry->endpoint, __entry->buf_len @@ -239,7 +239,7 @@ TRACE_EVENT(ath6kl_htc_tx, ), TP_printk( - "status %d endpoint %d len %d\n", + "status %d endpoint %d len %zd\n", __entry->status, __entry->endpoint, __entry->buf_len -- cgit From 5b7e662ba7e39211034d00088e538f40251f01a4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Mar 2013 20:15:24 +0200 Subject: iwlwifi: mvm: fix the {ack,cts}_kill_msk The masks were wrong. They should be 0xffffffff when SCO, HID or SNIFF profiles are used. They should be 0xffff0000 in any other case (default) to get a bit more throughput when the BT profile allows for it. Fix a debug print on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 47954deb6493..99f78737f8ff 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -125,15 +125,15 @@ enum iwl_bt_kill_msk { }; static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { - 0xffffffff, - 0xfffffc00, - 0, + [BT_KILL_MSK_DEFAULT] = 0xffff0000, + [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, + [BT_KILL_MSK_REDUCED_TXPOW] = 0, }; static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { - 0xffffffff, - 0xfffffc00, - 0, + [BT_KILL_MSK_DEFAULT] = 0xffff0000, + [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, + [BT_KILL_MSK_REDUCED_TXPOW] = 0, }; #define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) @@ -327,7 +327,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, return 0; IWL_DEBUG_COEX(mvm, - "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n", + "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", bt_kill_msk, BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", -- cgit From a77feb5d460778368abf2c6f84d238e31a1fa049 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Mar 2013 12:06:12 +0200 Subject: iwlwifi: mvm: don't support multi-channel inhibition This feature is not implemented yet in firmware. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 99f78737f8ff..19e4cb602d76 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -201,8 +201,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) cmd.flags = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE; - cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? - BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0; + cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0; cmd.flags |= BT_SYNC_2_BT_DISABLE; cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | -- cgit From 398e8c6c4eea39853a80cc1513f80026c1a62519 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 13 Mar 2013 15:20:35 +0200 Subject: iwlwifi: mvm: Remove obsolete queue definitions Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 6 +++--- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ---- drivers/net/wireless/iwlwifi/mvm/time-event.c | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 10 +++++----- 5 files changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index a00fb730386f..76156d16e658 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -196,7 +196,7 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, u32 qmask, ac; if (vif->type == NL80211_IFTYPE_P2P_DEVICE) - return BIT(IWL_OFFCHANNEL_QUEUE); + return BIT(IWL_MVM_OFFCHANNEL_QUEUE); qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ? BIT(vif->cab_queue) : 0; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index f64bca5da450..3492d6092b2d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -143,8 +143,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_TIMING_BEACON_ONLY; - hw->queues = IWL_FIRST_AMPDU_QUEUE; - hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE; + hw->queues = IWL_MVM_FIRST_AGG_QUEUE; + hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; hw->rate_control_algorithm = "iwl-mvm-rs"; /* @@ -257,7 +257,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, goto drop; } - if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE && + if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) goto drop; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index ea1fafd616e9..43a1d297ec1e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -90,10 +90,6 @@ enum iwl_mvm_tx_fifo { IWL_MVM_TX_FIFO_VO, }; -/* Placeholder */ -#define IWL_OFFCHANNEL_QUEUE 8 -#define IWL_FIRST_AMPDU_QUEUE 11 - extern struct ieee80211_ops iwl_mvm_hw_ops; /** * struct iwl_mvm_mod_params - module parameters for iwlmvm diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index c2c7f5176027..989f6c8b75d2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -116,7 +116,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) * issue as it will have to complete before the next command is * executed, and a new time event means a new command. */ - iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false); + iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false); } static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index a65acf09f913..ccff2e5f71a6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, spin_unlock(&mvmsta->lock); if (mvmsta->vif->type == NL80211_IFTYPE_AP && - txq_id < IWL_FIRST_AMPDU_QUEUE) + txq_id < IWL_MVM_FIRST_AGG_QUEUE) atomic_inc(&mvmsta->pending_frames); return 0; @@ -606,7 +606,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, info); /* Single frame failure in an AMPDU queue => send BAR */ - if (txq_id >= IWL_FIRST_AMPDU_QUEUE && + if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE && !(info->flags & IEEE80211_TX_STAT_ACK)) info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; @@ -619,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ieee80211_tx_status_ni(mvm->hw, skb); } - if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { + if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) { /* If this is an aggregation queue, we use the ssn since: * ssn = wifi seq_num % 256. * The seq_ctl is the sequence control of the packet to which @@ -681,7 +681,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, * If there are no pending frames for this STA, notify mac80211 that * this station can go to sleep in its STA table. */ - if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta && + if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta && !WARN_ON(skb_freed > 1) && mvmsta->vif->type == NL80211_IFTYPE_AP && atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { @@ -750,7 +750,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, u16 sequence = le16_to_cpu(pkt->hdr.sequence); struct ieee80211_sta *sta; - if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE)) + if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE)) return; if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) -- cgit From 5649ce429e81b77919c0029a02edf44df3be7797 Mon Sep 17 00:00:00 2001 From: Andrei Epure Date: Sun, 10 Mar 2013 15:22:33 +0200 Subject: iwlwifi: use kmemdup instead of kmalloc+memcpy Signed-off-by: Andrei Epure Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-test.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index efff2986b5b4..5cfd55b86ed3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -272,7 +272,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb) reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; skb = iwl_test_alloc_reply(tst, reply_len + 20); - reply_buf = kmalloc(reply_len, GFP_KERNEL); + reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL); if (!skb || !reply_buf) { kfree_skb(skb); kfree(reply_buf); @@ -280,7 +280,6 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb) } /* The reply is in a page, that we cannot send to user space. */ - memcpy(reply_buf, &(pkt->hdr), reply_len); iwl_free_resp(&cmd); if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, -- cgit From 1e1391ca43994b697b0145384797a078ce1e0ce7 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 13 Mar 2013 14:52:04 +0200 Subject: iwlwifi: mvm: Fix quota handling for monitor interface 1. Quota for the monitor interface should be added only if there is a channel context assigned to the interface. 2. In the unassign channel context flow, need to remove the quota for the monitor interface binding, before unbinding. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 6 ++++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/iwlwifi/mvm/quota.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3492d6092b2d..064eaefdff72 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1264,6 +1264,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, * will handle quota settings. */ if (vif->type == NL80211_IFTYPE_MONITOR) { + mvmvif->monitor_active = true; ret = iwl_mvm_update_quotas(mvm, vif); if (ret) goto out_remove_binding; @@ -1294,15 +1295,16 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP) goto out_unlock; - iwl_mvm_binding_remove_vif(mvm, vif); switch (vif->type) { case NL80211_IFTYPE_MONITOR: - iwl_mvm_update_quotas(mvm, vif); + mvmvif->monitor_active = false; + iwl_mvm_update_quotas(mvm, NULL); break; default: break; } + iwl_mvm_binding_remove_vif(mvm, vif); out_unlock: mvmvif->phy_ctxt = NULL; mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 43a1d297ec1e..53d58968e30a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -157,6 +157,8 @@ enum iwl_power_scheme { * @uploaded: indicates the MAC context has been added to the device * @ap_active: indicates that ap context is configured, and that the interface * should get quota etc. + * @monitor_active: indicates that monitor context is configured, and that the + * interface should get quota etc. * @queue_params: QoS params for this MAC * @bcast_sta: station used for broadcast packets. Used by the following * vifs: P2P_DEVICE, GO and AP. @@ -169,6 +171,7 @@ struct iwl_mvm_vif { bool uploaded; bool ap_active; + bool monitor_active; u32 ap_beacon_time; diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index df85c49dc599..a1e3e923ea3e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c @@ -114,7 +114,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, data->n_interfaces[id]++; break; case NL80211_IFTYPE_MONITOR: - data->n_interfaces[id]++; + if (mvmvif->monitor_active) + data->n_interfaces[id]++; break; case NL80211_IFTYPE_P2P_DEVICE: break; -- cgit From 4103d8485090cd4bf4d05b96fcf55409eec664ad Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 12 Mar 2013 17:35:58 +0100 Subject: iwlwifi: remove 5ghz_disable option 5ghz_disable has no effect any longer, that was changed during refactoring of EEPROM reading/parsing. Remove it, wpa_supplicant allow now to specify frequencies, on which device will operate. Signed-off-by: Stanislaw Gruszka Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 -- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 3ce4e9d5082d..498300577ac0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1266,7 +1266,3 @@ module_param_named(auto_agg, iwlwifi_mod_params.auto_agg, bool, S_IRUGO); MODULE_PARM_DESC(auto_agg, "enable agg w/o check traffic load (default: enable)"); - -module_param_named(5ghz_disable, iwlwifi_mod_params.disable_5ghz, - bool, S_IRUGO); -MODULE_PARM_DESC(5ghz_disable, "disable 5GHz band (default: 0 [enabled])"); diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 3cc39ffe8ba5..d6f6c37c09fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -103,7 +103,6 @@ enum iwl_power_level { * @ant_coupling: antenna coupling in dB, default = 0 * @bt_ch_announce: BT channel inhibition, default = enable * @auto_agg: enable agg. without check, default = true - * @disable_5ghz: disable 5GHz capability, default = false */ struct iwl_mod_params { int sw_crypto; @@ -120,7 +119,6 @@ struct iwl_mod_params { int ant_coupling; bool bt_ch_announce; bool auto_agg; - bool disable_5ghz; }; #endif /* #__iwl_modparams_h__ */ -- cgit From 1b53f218e2960525861cff7e75ef29a9c9522be2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Mar 2013 17:02:41 +0200 Subject: iwlwifi: mvm: print the flags in ALIVE notification This has valuable data about RFkill state seen from the fw side. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d43e2a57d354..b497647bf34b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -134,9 +134,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK; - IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n", + IWL_DEBUG_FW(mvm, + "Alive ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", le16_to_cpu(palive->status), palive->ver_type, - palive->ver_subtype); + palive->ver_subtype, palive->flags); return true; } -- cgit From 754d7d9eb4db044c2fcd96e442b5b18f503050bc Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Mar 2013 22:16:20 +0200 Subject: iwlwifi: add debug message when a CMD is dropped in RFKILL Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8595c16f74de..b29034d9c963 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1566,8 +1566,11 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) return -EIO; - if (test_bit(STATUS_RFKILL, &trans_pcie->status)) + if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { + IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", + cmd->id); return -ERFKILL; + } if (cmd->flags & CMD_ASYNC) return iwl_pcie_send_hcmd_async(trans, cmd); -- cgit From 5358549575aab8ed98c55100650510bdfb6ef5ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Mar 2013 13:04:50 +0100 Subject: iwlwifi: mvm: specify filter flags in monitor mode In firmware "listener" (monitor) mode, we still need to open up the filters with the filter flags to receive all frames. Reviewed-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 76156d16e658..c45822fb937d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -692,7 +692,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); - /* No other data to be filled */ + + cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | + MAC_FILTER_IN_CONTROL_AND_MGMT | + MAC_FILTER_IN_BEACON | + MAC_FILTER_IN_PROBE_REQUEST); + return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } -- cgit From d110cb51cf109a6dff0e801d945ea98d2883bd01 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 7 Mar 2013 17:27:40 +0200 Subject: iwlwifi: mvm: take the radio type / step / dash from TLVs This data should taken from TLVs and not from the NVM. This is true for the value written in CSR_HW_IF_CONFIG_REG too. Also, no need to set the CSR_HW_IF_CONFIG_REG_BIT_MAC_SI bit for 7000 devices which are the only devices currently supported. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-fw.h | 13 +++++++++++++ drivers/net/wireless/iwlwifi/mvm/ops.c | 22 ++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 435618574240..4e932e04d87e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -154,6 +154,19 @@ struct iwl_tlv_calib_ctrl { __le32 event_trigger; } __packed; +enum iwl_fw_phy_cfg { + FW_PHY_CFG_RADIO_TYPE_POS = 0, + FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS, + FW_PHY_CFG_RADIO_STEP_POS = 2, + FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS, + FW_PHY_CFG_RADIO_DASH_POS = 4, + FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS, + FW_PHY_CFG_TX_CHAIN_POS = 16, + FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS, + FW_PHY_CFG_RX_CHAIN_POS = 20, + FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS, +}; + /** * struct iwl_fw - variables associated with the firmware * diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 81ff28361dc2..fe031d304d1e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -143,21 +143,12 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; u32 reg_val = 0; - /* - * We can't upload the correct value to the INIT image - * as we don't have nvm_data by that time. - * - * TODO: Figure out what we should do here - */ - if (mvm->nvm_data) { - radio_cfg_type = mvm->nvm_data->radio_cfg_type; - radio_cfg_step = mvm->nvm_data->radio_cfg_step; - radio_cfg_dash = mvm->nvm_data->radio_cfg_dash; - } else { - radio_cfg_type = 0; - radio_cfg_step = 0; - radio_cfg_dash = 0; - } + radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >> + FW_PHY_CFG_RADIO_TYPE_POS; + radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >> + FW_PHY_CFG_RADIO_STEP_POS; + radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >> + FW_PHY_CFG_RADIO_DASH_POS; /* SKU control */ reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << @@ -175,7 +166,6 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) /* silicon bits */ reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; - reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI; iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | -- cgit From 332235427a566d8be04b9676a7ac380c8853aa9b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 9 Mar 2013 20:38:19 +0200 Subject: iwlwifi: mvm: take the valid_{rx,tx}_ant from the TLV This is the right source of information for the valid Tx antennas, not the NVM. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-fw.h | 12 ++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw.c | 8 ++++---- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 7 +++---- drivers/net/wireless/iwlwifi/mvm/scan.c | 4 ++-- 5 files changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 4e932e04d87e..c4c446d41eb0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -203,4 +203,16 @@ struct iwl_fw { bool mvm_fw; }; +static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw) +{ + return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >> + FW_PHY_CFG_TX_CHAIN_POS; +} + +static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw) +{ + return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >> + FW_PHY_CFG_RX_CHAIN_POS; +} + #endif /* __iwl_fw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index b497647bf34b..e18c92dd60ec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -114,7 +114,7 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant) .valid = cpu_to_le32(valid_tx_ant), }; - IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant); + IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant); return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, sizeof(tx_ant_cmd), &tx_ant_cmd); } @@ -327,7 +327,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) WARN_ON(ret); /* Send TX valid antennas before triggering calibrations */ - ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); + ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); if (ret) goto error; @@ -413,7 +413,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; } - ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); + ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); if (ret) goto error; @@ -467,7 +467,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm) goto error; } - ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); + ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); if (ret) goto error; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index c45822fb937d..86e312a4f629 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -803,7 +803,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, TX_CMD_FLG_TSF); mvm->mgmt_last_antenna_idx = - iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, + iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), mvm->mgmt_last_antenna_idx); beacon_cmd.tx.rate_n_flags = diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 0d537e035ef0..0f0b44eabd93 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -142,7 +142,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm, struct cfg80211_chan_def *chandef, u8 chains_static, u8 chains_dynamic) { - u8 valid_rx_chains, active_cnt, idle_cnt; + u8 active_cnt, idle_cnt; /* Set the channel info data */ cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ? @@ -158,17 +158,16 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm, * Need to add on chain noise calibration limitations, and * BT coex considerations. */ - valid_rx_chains = mvm->nvm_data->valid_rx_ant; idle_cnt = chains_static; active_cnt = chains_dynamic; - cmd->rxchain_info = cpu_to_le32(valid_rx_chains << + cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) << PHY_RX_CHAIN_VALID_POS); cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); cmd->rxchain_info |= cpu_to_le32(active_cnt << PHY_RX_CHAIN_MIMO_CNT_POS); - cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant); + cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw)); } /* diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 0d3c76b29242..2157b0f8ced5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -74,7 +74,7 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) { u16 rx_chain; - u8 rx_ant = mvm->nvm_data->valid_rx_ant; + u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw); rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; @@ -115,7 +115,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band, u32 tx_ant; mvm->scan_last_antenna_idx = - iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, + iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), mvm->scan_last_antenna_idx); tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; -- cgit From b9269262342817533a73958ff3f9b1553e9c9b7c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Mar 2013 14:40:38 +0200 Subject: iwlwifi: mvm: tune the move to static SMPS due to BT load We should disable MIMO only if bt_traffic_load goes up to 3. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 19e4cb602d76..1700232aa166 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -188,6 +188,8 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { /* BT Antenna Coupling Threshold (dB) */ #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) +#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) + int iwl_send_bt_init_conf(struct iwl_mvm *mvm) { @@ -274,7 +276,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, if (data->notif->bt_status) smps_mode = IEEE80211_SMPS_DYNAMIC; - if (data->notif->bt_traffic_load) + if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD) smps_mode = IEEE80211_SMPS_STATIC; IWL_DEBUG_COEX(data->mvm, -- cgit From 6039f3e196721a4bb08d85af5367e50201052145 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Mar 2013 10:40:05 +0100 Subject: iwlwifi: mvm: fix WoWLAN RF-kill bug The RF-kill wakeup trigger flag is set in the wrong command, which means it won't work. Also fix the comment in the TCP wakeup trigger code -- the firmware was changed to look at all the different trigger flags. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/d3.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index d4578cefe445..bf087abe39f3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -866,17 +866,13 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); if (wowlan->rfkill_release) - d3_cfg_cmd.wakeup_flags |= + wowlan_config_cmd.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); if (wowlan->tcp) { /* - * The firmware currently doesn't really look at these, only - * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that - * reason bit since losing the connection to the AP implies - * losing the TCP connection. - * Set the flags anyway as long as they exist, in case this - * will be changed in the firmware. + * Set the "link change" (really "link lost") flag as well + * since that implies losing the TCP connection. */ wowlan_config_cmd.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | -- cgit From c451e6d4bd290db5290cfa7f9c4079386373645b Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 20 Feb 2013 08:41:54 +0200 Subject: iwlwifi: mvm: Increase the max remain on channel time Increase the maximal remain on channel time as longer remain on channel requests are handled by the FW using fragmented time events. This reduces the number of user/kernel space iterations during flows such as p2p_listen. In addition it is currently required for flows which require longer duration such as p2p_sd. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 064eaefdff72..ccbeaed60943 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -174,7 +174,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->n_iface_combinations = ARRAY_SIZE(iwl_mvm_iface_combinations); - hw->wiphy->max_remain_on_channel_duration = 500; + hw->wiphy->max_remain_on_channel_duration = 10000; hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; /* Extract MAC address */ -- cgit From eb8ad609912cd468b23467892a1c80ff2d610716 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghiu Date: Mon, 18 Mar 2013 23:35:31 +0200 Subject: regulator: fan53555: Use PTR_RET function Used PTR_RET function instead of IS_ERR and PTR_ERR. Patch found using coccinelle. Signed-off-by: Alexandru Gheorghiu Signed-off-by: Mark Brown --- drivers/regulator/fan53555.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 9165b0c40ed3..f0e1ae52bb05 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -219,9 +219,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, rdesc->owner = THIS_MODULE; di->rdev = regulator_register(&di->desc, config); - if (IS_ERR(di->rdev)) - return PTR_ERR(di->rdev); - return 0; + return PTR_RET(di->rdev); } -- cgit From e635c797b3b18ffbe4ef5db27971f48b661f03bd Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 13 Feb 2013 11:05:18 +0200 Subject: iwlwifi: mvm: Add support for different ROC types Schedule different time event based on the ROC type Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.c | 36 ++++++++++++++++----------- drivers/net/wireless/iwlwifi/mvm/time-event.h | 3 ++- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index de4e0e476f4e..3d193f8c33b6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1161,7 +1161,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, &chandef, 1, 1); /* Schedule the time events */ - ret = iwl_mvm_start_p2p_roc(mvm, vif, duration); + ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); mutex_unlock(&mvm->mutex); IWL_DEBUG_MAC80211(mvm, "leave\n"); diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 989f6c8b75d2..4dc934bed055 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -76,14 +76,12 @@ #define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) #define MSEC_TO_TU(_msec) (_msec*1000/1024) -/* For ROC use a TE type which has priority high enough to be scheduled when - * there is a concurrent BSS or GO/AP. Currently, use a TE type that has - * priority similar to the TE priority used for action scans by the FW. - * TODO: This needs to be changed, based on the reason for the ROC, i.e., use - * TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use - * TE_P2P_DEVICE_ACTION_SCAN +/* + * For the high priority TE use a time event type that has similar priority to + * the FW's action scan priority. */ -#define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN +#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE +#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, struct iwl_mvm_time_event_data *te_data) @@ -438,7 +436,7 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm, } int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - int duration) + int duration, enum ieee80211_roc_type type) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; @@ -459,21 +457,29 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); time_cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); - time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE); + + switch (type) { + case IEEE80211_ROC_TYPE_NORMAL: + time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL); + break; + case IEEE80211_ROC_TYPE_MGMT_TX: + time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX); + break; + default: + WARN_ONCE(1, "Got an invalid ROC type\n"); + return -EINVAL; + } time_cmd.apply_time = cpu_to_le32(0); time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); time_cmd.is_present = cpu_to_le32(1); - time_cmd.interval = cpu_to_le32(1); /* - * IWL_MVM_ROC_TE_TYPE can have lower priority than other events + * The P2P Device TEs can have lower priority than other events * that are being scheduled by the driver/fw, and thus it might not be - * scheduled. To improve the chances of it being scheduled, allow it to - * be fragmented. - * In addition, for the same reasons, allow to delay the scheduling of - * the time event. + * scheduled. To improve the chances of it being scheduled, allow them + * to be fragmented, and in addition allow them to be delayed. */ time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20); time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index b36424eda361..f86c51065ed3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -162,6 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm, * that the vif type is NL80211_IFTYPE_P2P_DEVICE * @duration: the requested duration in millisecond for the fw to be on the * channel that is bound to the vif. + * @type: the remain on channel request type * * This function can be used to issue a remain on channel session, * which means that the fw will stay in the channel for the request %duration @@ -172,7 +173,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm, * another notification to the driver. */ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - int duration); + int duration, enum ieee80211_roc_type type); /** * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity -- cgit From 07f42258893d3768deb9a24165d23f1355bc1949 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 20 Mar 2013 11:00:34 +0900 Subject: treewide: Fix typos in printk Correct spelling typo in various drivers. Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/ata/sata_fsl.c | 2 +- drivers/clk/mvebu/clk-core.c | 4 ++-- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/media/usb/dvb-usb/opera1.c | 2 +- drivers/net/ethernet/ti/cpts.c | 2 +- drivers/power/pm2301_charger.c | 2 +- drivers/scsi/mpt3sas/mpt3sas_config.c | 2 +- drivers/video/goldfishfb.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 124b2c1d9c0b..b0fd7cd40e7b 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -311,7 +311,7 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host, intr_coalescing_ticks = ticks; spin_unlock(&host->lock); - DPRINTK("intrrupt coalescing, count = 0x%x, ticks = %x\n", + DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n", intr_coalescing_count, intr_coalescing_ticks); DPRINTK("ICC register status: (hcr base: 0x%x) = 0x%x\n", hcr_base, ioread32(hcr_base + ICC)); diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c index 69056a7479e8..1b4e3332ac17 100644 --- a/drivers/clk/mvebu/clk-core.c +++ b/drivers/clk/mvebu/clk-core.c @@ -157,7 +157,7 @@ static u32 __init armada_370_get_cpu_freq(void __iomem *sar) cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) & SARL_A370_PCLK_FREQ_OPT_MASK); if (cpu_freq_select > ARRAY_SIZE(armada_370_cpu_frequencies)) { - pr_err("CPU freq select unsuported %d\n", cpu_freq_select); + pr_err("CPU freq select unsupported %d\n", cpu_freq_select); cpu_freq = 0; } else cpu_freq = armada_370_cpu_frequencies[cpu_freq_select]; @@ -279,7 +279,7 @@ static u32 __init armada_xp_get_cpu_freq(void __iomem *sar) SARH_AXP_PCLK_FREQ_OPT_MASK) << SARH_AXP_PCLK_FREQ_OPT_SHIFT); if (cpu_freq_select > ARRAY_SIZE(armada_xp_cpu_frequencies)) { - pr_err("CPU freq select unsuported: %d\n", cpu_freq_select); + pr_err("CPU freq select unsupported: %d\n", cpu_freq_select); cpu_freq = 0; } else cpu_freq = armada_xp_cpu_frequencies[cpu_freq_select]; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f61cb7998c72..6d8219e59bde 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2017,7 +2017,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) } if (channel_eq) - DRM_DEBUG_KMS("Channel EQ done. DP Training successfull\n"); + DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE); } diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c index c8a95042dfbc..16ba90acf539 100644 --- a/drivers/media/usb/dvb-usb/opera1.c +++ b/drivers/media/usb/dvb-usb/opera1.c @@ -151,7 +151,7 @@ static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], break; } if (dvb_usb_opera1_debug & 0x10) - info("sending i2c mesage %d %d", tmp, msg[i].len); + info("sending i2c message %d %d", tmp, msg[i].len); } mutex_unlock(&d->i2c_mutex); return num; diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index 463597f919f1..8c351f100aca 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -94,7 +94,7 @@ static int cpts_fifo_read(struct cpts *cpts, int match) case CPTS_EV_HW: break; default: - pr_err("cpts: unkown event type\n"); + pr_err("cpts: unknown event type\n"); break; } if (type == match) diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index ed48d75bb786..ee346d443571 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -235,7 +235,7 @@ out: static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) { - dev_dbg(pm2->dev , "20 minutes watchdog occured\n"); + dev_dbg(pm2->dev , "20 minutes watchdog expired\n"); pm2->ac.wd_expired = true; power_supply_changed(&pm2->ac_chg.psy); diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 1df9ed4f371d..4db0c7a18bd8 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -148,7 +148,7 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, desc = "raid_config"; break; case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: - desc = "driver_mappping"; + desc = "driver_mapping"; break; } break; diff --git a/drivers/video/goldfishfb.c b/drivers/video/goldfishfb.c index 489abb32fc04..7f6c9e6cfc6c 100644 --- a/drivers/video/goldfishfb.c +++ b/drivers/video/goldfishfb.c @@ -148,7 +148,7 @@ static int goldfish_fb_pan_display(struct fb_var_screeninfo *var, wait_event_timeout(fb->wait, fb->base_update_count != base_update_count, HZ / 15); if (fb->base_update_count == base_update_count) - pr_err("goldfish_fb_pan_display: timeout wating for base update\n"); + pr_err("goldfish_fb_pan_display: timeout waiting for base update\n"); return 0; } -- cgit From c233cf4074e50933edd5e82c3c5826923f0c1b10 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 19 Mar 2013 07:40:02 +0000 Subject: gianfar: Fix tx napi polling There are 2 issues with the current napi poll routine, with regards to tx ring cleanup: 1) for multi-queue devices (MQ_MG_MODE), should tx_bit_map != rx_bit_map, which is possible (and supported in h/w) if the DT property "fsl,tx-bit-map" holds a different value than rx_bit_map, the current polling routine will service the wrong Tx queues in this case (i.e. the interrupt group will receive interrupts from tx queues that it will not service) 2) Tx cleanup completion consumes napi budget, whereas the napi budget should be reserved for Rx work only. The patch fixes these issues and provides a clean napi polling routine. Napi poll completion is reached when all the Rx queues have been serviced and there is no Tx work to do. Signed-off-by: Claudiu Manoil Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 82 ++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 1b468a82a68f..1e555a70b821 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -132,7 +132,7 @@ static int gfar_poll(struct napi_struct *napi, int budget); static void gfar_netpoll(struct net_device *dev); #endif int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); -static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); +static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int amount_pull, struct napi_struct *napi); void gfar_halt(struct net_device *dev); @@ -2468,7 +2468,7 @@ static void gfar_align_skb(struct sk_buff *skb) } /* Interrupt Handler for Transmit complete */ -static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) +static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) { struct net_device *dev = tx_queue->dev; struct netdev_queue *txq; @@ -2570,8 +2570,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) tx_queue->dirty_tx = bdp; netdev_tx_completed_queue(txq, howmany, bytes_sent); - - return howmany; } static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp) @@ -2834,62 +2832,72 @@ static int gfar_poll(struct napi_struct *napi, int budget) struct gfar __iomem *regs = gfargrp->regs; struct gfar_priv_tx_q *tx_queue = NULL; struct gfar_priv_rx_q *rx_queue = NULL; - int rx_cleaned = 0, budget_per_queue = 0, rx_cleaned_per_queue = 0; - int tx_cleaned = 0, i, left_over_budget = budget; + int work_done = 0, work_done_per_q = 0; + int i, budget_per_q; + int has_tx_work; unsigned long serviced_queues = 0; - int num_queues = 0; - - num_queues = gfargrp->num_rx_queues; - budget_per_queue = budget/num_queues; + int num_queues = gfargrp->num_rx_queues; + budget_per_q = budget/num_queues; /* Clear IEVENT, so interrupts aren't called again * because of the packets that have already arrived */ gfar_write(®s->ievent, IEVENT_RTX_MASK); - while (num_queues && left_over_budget) { - budget_per_queue = left_over_budget/num_queues; - left_over_budget = 0; + while (1) { + has_tx_work = 0; + for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { + tx_queue = priv->tx_queue[i]; + /* run Tx cleanup to completion */ + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) { + gfar_clean_tx_ring(tx_queue); + has_tx_work = 1; + } + } for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { if (test_bit(i, &serviced_queues)) continue; + rx_queue = priv->rx_queue[i]; - tx_queue = priv->tx_queue[rx_queue->qindex]; - - tx_cleaned += gfar_clean_tx_ring(tx_queue); - rx_cleaned_per_queue = - gfar_clean_rx_ring(rx_queue, budget_per_queue); - rx_cleaned += rx_cleaned_per_queue; - if (rx_cleaned_per_queue < budget_per_queue) { - left_over_budget = left_over_budget + - (budget_per_queue - - rx_cleaned_per_queue); + work_done_per_q = + gfar_clean_rx_ring(rx_queue, budget_per_q); + work_done += work_done_per_q; + + /* finished processing this queue */ + if (work_done_per_q < budget_per_q) { set_bit(i, &serviced_queues); num_queues--; + if (!num_queues) + break; + /* recompute budget per Rx queue */ + budget_per_q = + (budget - work_done) / num_queues; } } - } - if (tx_cleaned) - return budget; + if (work_done >= budget) + break; - if (rx_cleaned < budget) { - napi_complete(napi); + if (!num_queues && !has_tx_work) { - /* Clear the halt bit in RSTAT */ - gfar_write(®s->rstat, gfargrp->rstat); + napi_complete(napi); - gfar_write(®s->imask, IMASK_DEFAULT); + /* Clear the halt bit in RSTAT */ + gfar_write(®s->rstat, gfargrp->rstat); - /* If we are coalescing interrupts, update the timer - * Otherwise, clear it - */ - gfar_configure_coalescing(priv, gfargrp->rx_bit_map, - gfargrp->tx_bit_map); + gfar_write(®s->imask, IMASK_DEFAULT); + + /* If we are coalescing interrupts, update the timer + * Otherwise, clear it + */ + gfar_configure_coalescing(priv, gfargrp->rx_bit_map, + gfargrp->tx_bit_map); + break; + } } - return rx_cleaned; + return work_done; } #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit From 6be5ed3fef568ad79f9519db4a336c725a089d51 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 19 Mar 2013 07:40:03 +0000 Subject: gianfar: Poll only active Rx queues Split the napi budget fairly among the active queues only, instead of dividing it by the total number of Rx queues assigned to the given interrupt group. Use the h/w indication field RXFi in rstat (receive status register) to identify the active rx queues from the current interrupt group (i.e. receive event occured on ring i, if ring i is part of the current interrupt group). This indication field in rstat, RXFi i=0..7, allows us to find out on which queues of the same interrupt group do we have incomming traffic once we entered the polling routine for the given interrupt group. After servicing the ring i, the corresponding bit RXFi will be written with 1 to clear the active queue indication for that ring. Signed-off-by: Claudiu Manoil Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 28 +++++++++++++++++++--------- drivers/net/ethernet/freescale/gianfar.h | 4 +++- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 1e555a70b821..3f07dbd01980 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2835,15 +2835,20 @@ static int gfar_poll(struct napi_struct *napi, int budget) int work_done = 0, work_done_per_q = 0; int i, budget_per_q; int has_tx_work; - unsigned long serviced_queues = 0; - int num_queues = gfargrp->num_rx_queues; + unsigned long rstat_rxf; + int num_act_queues; - budget_per_q = budget/num_queues; /* Clear IEVENT, so interrupts aren't called again * because of the packets that have already arrived */ gfar_write(®s->ievent, IEVENT_RTX_MASK); + rstat_rxf = gfar_read(®s->rstat) & RSTAT_RXF_MASK; + + num_act_queues = bitmap_weight(&rstat_rxf, MAX_RX_QS); + if (num_act_queues) + budget_per_q = budget/num_act_queues; + while (1) { has_tx_work = 0; for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { @@ -2856,7 +2861,8 @@ static int gfar_poll(struct napi_struct *napi, int budget) } for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { - if (test_bit(i, &serviced_queues)) + /* skip queue if not active */ + if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) continue; rx_queue = priv->rx_queue[i]; @@ -2866,20 +2872,24 @@ static int gfar_poll(struct napi_struct *napi, int budget) /* finished processing this queue */ if (work_done_per_q < budget_per_q) { - set_bit(i, &serviced_queues); - num_queues--; - if (!num_queues) + /* clear active queue hw indication */ + gfar_write(®s->rstat, + RSTAT_CLEAR_RXF0 >> i); + rstat_rxf &= ~(RSTAT_CLEAR_RXF0 >> i); + num_act_queues--; + + if (!num_act_queues) break; /* recompute budget per Rx queue */ budget_per_q = - (budget - work_done) / num_queues; + (budget - work_done) / num_act_queues; } } if (work_done >= budget) break; - if (!num_queues && !has_tx_work) { + if (!num_act_queues && !has_tx_work) { napi_complete(napi); diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 63a28d294e20..b1d0c1c77139 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -291,7 +291,9 @@ extern const char gfar_driver_version[]; #define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) -#define RSTAT_CLEAR_RHALT 0x00800000 +#define RSTAT_CLEAR_RHALT 0x00800000 +#define RSTAT_CLEAR_RXF0 0x00000080 +#define RSTAT_RXF_MASK 0x000000ff #define TCTRL_IPCSEN 0x00004000 #define TCTRL_TUCSEN 0x00002000 -- cgit From 5d9657d83a1cfecfbe41add0d94863d3fe714df0 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 19 Mar 2013 07:40:04 +0000 Subject: gianfar: Remove redundant programming of [rt]xic registers For Multi Q Multi Group (MQ_MG_MODE) mode, the Rx/Tx colescing registers [rt]xic are aliased with the [rt]xic0 registers (coalescing setting regs for Q0). This avoids programming twice in a row the coalescing registers for the Rx/Tx hw Q0. Signed-off-by: Claudiu Manoil Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 3f07dbd01980..e28b3e6b12d9 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1821,20 +1821,9 @@ void gfar_configure_coalescing(struct gfar_private *priv, { struct gfar __iomem *regs = priv->gfargrp[0].regs; u32 __iomem *baddr; - int i = 0; - - /* Backward compatible case ---- even if we enable - * multiple queues, there's only single reg to program - */ - gfar_write(®s->txic, 0); - if (likely(priv->tx_queue[0]->txcoalescing)) - gfar_write(®s->txic, priv->tx_queue[0]->txic); - - gfar_write(®s->rxic, 0); - if (unlikely(priv->rx_queue[0]->rxcoalescing)) - gfar_write(®s->rxic, priv->rx_queue[0]->rxic); if (priv->mode == MQ_MG_MODE) { + int i = 0; baddr = ®s->txic0; for_each_set_bit(i, &tx_mask, priv->num_tx_queues) { gfar_write(baddr + i, 0); @@ -1848,6 +1837,17 @@ void gfar_configure_coalescing(struct gfar_private *priv, if (likely(priv->rx_queue[i]->rxcoalescing)) gfar_write(baddr + i, priv->rx_queue[i]->rxic); } + } else { + /* Backward compatible case ---- even if we enable + * multiple queues, there's only single reg to program + */ + gfar_write(®s->txic, 0); + if (likely(priv->tx_queue[0]->txcoalescing)) + gfar_write(®s->txic, priv->tx_queue[0]->txic); + + gfar_write(®s->rxic, 0); + if (unlikely(priv->rx_queue[0]->rxcoalescing)) + gfar_write(®s->rxic, priv->rx_queue[0]->rxic); } } -- cgit From 800c644bcd0f2b29020c0dd6b661596c14c0f34f Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 19 Mar 2013 07:40:05 +0000 Subject: gianfar: Refactor config coalescing calls for all queues The only place where gfar_configure_coalescing is called with an actual bitmask (other than 0xff) is in gfar_poll (on the hot path). So make gfar_configure_coalescing() static for the buffer processing path, and export gfar_configure_coalescing_all() for the remaining cases that require to set coalescing for all the queues at once (on the slow path). Signed-off-by: Claudiu Manoil Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 11 ++++++++--- drivers/net/ethernet/freescale/gianfar.h | 3 +-- drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index e28b3e6b12d9..49ce83b1088f 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -341,7 +341,7 @@ static void gfar_init_mac(struct net_device *ndev) gfar_init_tx_rx_base(priv); /* Configure the coalescing support */ - gfar_configure_coalescing(priv, 0xFF, 0xFF); + gfar_configure_coalescing_all(priv); /* set this when rx hw offload (TOE) functions are being used */ priv->uses_rxfcb = 0; @@ -1816,7 +1816,7 @@ void gfar_start(struct net_device *dev) dev->trans_start = jiffies; /* prevent tx timeout */ } -void gfar_configure_coalescing(struct gfar_private *priv, +static void gfar_configure_coalescing(struct gfar_private *priv, unsigned long tx_mask, unsigned long rx_mask) { struct gfar __iomem *regs = priv->gfargrp[0].regs; @@ -1851,6 +1851,11 @@ void gfar_configure_coalescing(struct gfar_private *priv, } } +void gfar_configure_coalescing_all(struct gfar_private *priv) +{ + gfar_configure_coalescing(priv, 0xFF, 0xFF); +} + static int register_grp_irqs(struct gfar_priv_grp *grp) { struct gfar_private *priv = grp->priv; @@ -1940,7 +1945,7 @@ int startup_gfar(struct net_device *ndev) phy_start(priv->phydev); - gfar_configure_coalescing(priv, 0xFF, 0xFF); + gfar_configure_coalescing_all(priv); return 0; diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index b1d0c1c77139..eec87eaaae92 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1182,8 +1182,7 @@ extern void stop_gfar(struct net_device *dev); extern void gfar_halt(struct net_device *dev); extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable, u32 regnum, u32 read); -extern void gfar_configure_coalescing(struct gfar_private *priv, - unsigned long tx_mask, unsigned long rx_mask); +extern void gfar_configure_coalescing_all(struct gfar_private *priv); void gfar_init_sysfs(struct net_device *dev); int gfar_set_features(struct net_device *dev, netdev_features_t features); extern void gfar_check_rx_parser_mode(struct gfar_private *priv); diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 75e89acf4912..8248df760aad 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -436,7 +436,7 @@ static int gfar_scoalesce(struct net_device *dev, gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs)); } - gfar_configure_coalescing(priv, 0xFF, 0xFF); + gfar_configure_coalescing_all(priv); return 0; } -- cgit From 2b5faa4c553f90ee2dde1d976b220b1ca9741ef0 Mon Sep 17 00:00:00 2001 From: Jesper Derehag Date: Tue, 19 Mar 2013 20:50:05 +0000 Subject: connector: Added coredumping event to the process connector Process connector can now also detect coredumping events. Main aim of patch is get notified at start of coredumping, instead of having to wait for it to finish and then being notified through EXIT event. Could be used for instance by process-managers that want to get notified as soon as possible about process failures, and not necessarily beeing notified after coredump, which could be in the order of minutes depending on size of coredump, piping and so on. Signed-off-by: Jesper Derehag Signed-off-by: David S. Miller --- drivers/connector/cn_proc.c | 25 +++++++++++++++++++++++++ include/linux/cn_proc.h | 4 ++++ include/uapi/linux/cn_proc.h | 10 +++++++++- kernel/signal.c | 2 ++ 4 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 1110478dd0fd..08ae128cce9b 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -232,6 +232,31 @@ void proc_comm_connector(struct task_struct *task) cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); } +void proc_coredump_connector(struct task_struct *task) +{ + struct cn_msg *msg; + struct proc_event *ev; + __u8 buffer[CN_PROC_MSG_SIZE]; + struct timespec ts; + + if (atomic_read(&proc_event_num_listeners) < 1) + return; + + msg = (struct cn_msg *)buffer; + ev = (struct proc_event *)msg->data; + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + ev->what = PROC_EVENT_COREDUMP; + ev->event_data.coredump.process_pid = task->pid; + ev->event_data.coredump.process_tgid = task->tgid; + + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ + msg->len = sizeof(*ev); + cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); +} + void proc_exit_connector(struct task_struct *task) { struct cn_msg *msg; diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 2c1bc1ea04ee..1d5b02a96c46 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -26,6 +26,7 @@ void proc_id_connector(struct task_struct *task, int which_id); void proc_sid_connector(struct task_struct *task); void proc_ptrace_connector(struct task_struct *task, int which_id); void proc_comm_connector(struct task_struct *task); +void proc_coredump_connector(struct task_struct *task); void proc_exit_connector(struct task_struct *task); #else static inline void proc_fork_connector(struct task_struct *task) @@ -48,6 +49,9 @@ static inline void proc_ptrace_connector(struct task_struct *task, int ptrace_id) {} +static inline void proc_coredump_connector(struct task_struct *task) +{} + static inline void proc_exit_connector(struct task_struct *task) {} #endif /* CONFIG_PROC_EVENTS */ diff --git a/include/uapi/linux/cn_proc.h b/include/uapi/linux/cn_proc.h index 0d7b49973bb3..f6c271035bbd 100644 --- a/include/uapi/linux/cn_proc.h +++ b/include/uapi/linux/cn_proc.h @@ -56,7 +56,9 @@ struct proc_event { PROC_EVENT_PTRACE = 0x00000100, PROC_EVENT_COMM = 0x00000200, /* "next" should be 0x00000400 */ - /* "last" is the last process event: exit */ + /* "last" is the last process event: exit, + * while "next to last" is coredumping event */ + PROC_EVENT_COREDUMP = 0x40000000, PROC_EVENT_EXIT = 0x80000000 } what; __u32 cpu; @@ -110,11 +112,17 @@ struct proc_event { char comm[16]; } comm; + struct coredump_proc_event { + __kernel_pid_t process_pid; + __kernel_pid_t process_tgid; + } coredump; + struct exit_proc_event { __kernel_pid_t process_pid; __kernel_pid_t process_tgid; __u32 exit_code, exit_signal; } exit; + } event_data; }; diff --git a/kernel/signal.c b/kernel/signal.c index dd72567767d9..497330ec2ae9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -32,6 +32,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -2350,6 +2351,7 @@ relock: if (sig_kernel_coredump(signr)) { if (print_fatal_signals) print_fatal_signal(info->si_signo); + proc_coredump_connector(current); /* * If it was able to dump core, this kills all * other threads in the group and synchronizes with -- cgit From 18e4a7374c3307c76e4675ff9382a0ce58be0b25 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Mar 2013 01:41:28 +0000 Subject: net: ks8695net: Use module_platform_driver() module_platform_driver macro removes some boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8695net.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index 07a6ebc47c92..b6c60fdef4ff 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -1622,25 +1622,7 @@ static struct platform_driver ks8695_driver = { .resume = ks8695_drv_resume, }; -/* Module interface */ - -static int __init -ks8695_init(void) -{ - printk(KERN_INFO "%s Ethernet driver, V%s\n", - MODULENAME, MODULEVERSION); - - return platform_driver_register(&ks8695_driver); -} - -static void __exit -ks8695_cleanup(void) -{ - platform_driver_unregister(&ks8695_driver); -} - -module_init(ks8695_init); -module_exit(ks8695_cleanup); +module_platform_driver(ks8695_driver); MODULE_AUTHOR("Simtec Electronics"); MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); -- cgit From 6d7496836d10591746e0cf342377d0390c339783 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Mar 2013 01:41:29 +0000 Subject: net: s6gmac: Use module_platform_driver() module_platform_driver macro removes some boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/ethernet/s6gmac.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index 21683e2b1ff4..cd5f4e21cede 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c @@ -1053,20 +1053,7 @@ static struct platform_driver s6gmac_driver = { }, }; -static int __init s6gmac_init(void) -{ - printk(KERN_INFO DRV_PRMT "S6 GMAC ethernet driver\n"); - return platform_driver_register(&s6gmac_driver); -} - - -static void __exit s6gmac_exit(void) -{ - platform_driver_unregister(&s6gmac_driver); -} - -module_init(s6gmac_init); -module_exit(s6gmac_exit); +module_platform_driver(s6gmac_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("S6105 on chip Ethernet driver"); -- cgit From 95d158df4459016c98e8dae2229d12be09d79324 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Mar 2013 01:41:30 +0000 Subject: net: au1k_ir: Use module_platform_driver() module_platform_driver macro removes some boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Cc: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/au1k_ir.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 56f1e6d6e4eb..7a1f684edcb5 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -953,18 +953,7 @@ static struct platform_driver au1k_irda_driver = { .remove = au1k_irda_remove, }; -static int __init au1k_irda_load(void) -{ - return platform_driver_register(&au1k_irda_driver); -} - -static void __exit au1k_irda_unload(void) -{ - return platform_driver_unregister(&au1k_irda_driver); -} +module_platform_driver(au1k_irda_driver); MODULE_AUTHOR("Pete Popov "); MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); - -module_init(au1k_irda_load); -module_exit(au1k_irda_unload); -- cgit From f8e5fc8c203fd7fe9fe17e1376464ece0bc64829 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Mar 2013 01:41:31 +0000 Subject: net: mdio-gpio: Use module_platform_driver() module_platform_driver macro removes some boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Signed-off-by: David S. Miller --- drivers/net/phy/mdio-gpio.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 27274986ab56..a47f9236d966 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -235,17 +235,7 @@ static struct platform_driver mdio_gpio_driver = { }, }; -static int __init mdio_gpio_init(void) -{ - return platform_driver_register(&mdio_gpio_driver); -} -module_init(mdio_gpio_init); - -static void __exit mdio_gpio_exit(void) -{ - platform_driver_unregister(&mdio_gpio_driver); -} -module_exit(mdio_gpio_exit); +module_platform_driver(mdio_gpio_driver); MODULE_ALIAS("platform:mdio-gpio"); MODULE_AUTHOR("Laurent Pinchart, Paulius Zaleckas"); -- cgit From 9fad0c941a4f72becedd52db043506bf3968dae2 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 20 Mar 2013 01:41:32 +0000 Subject: net: mdio-octeon: Use module_platform_driver() module_platform_driver macro removes some boilerplate and simplifies the code. Signed-off-by: Sachin Kamat Cc: David Daney Acked-by: David Daney Signed-off-by: David S. Miller --- drivers/net/phy/mdio-octeon.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index 09297fe05ae5..c2c878d496ad 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -197,18 +197,7 @@ void octeon_mdiobus_force_mod_depencency(void) } EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency); -static int __init octeon_mdiobus_mod_init(void) -{ - return platform_driver_register(&octeon_mdiobus_driver); -} - -static void __exit octeon_mdiobus_mod_exit(void) -{ - platform_driver_unregister(&octeon_mdiobus_driver); -} - -module_init(octeon_mdiobus_mod_init); -module_exit(octeon_mdiobus_mod_exit); +module_platform_driver(octeon_mdiobus_driver); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); -- cgit From e052a5893b78d43bd183c6cc33bc346efe6bc6e5 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 20 Mar 2013 05:01:45 +0000 Subject: net: ethernet: davinci_emac: make local function emac_poll_controller() static emac_poll_controller() was not declared. It should be static. Signed-off-by: Wei Yongjun Acked-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ae1b77aa199f..e38e3d8f81eb 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1438,7 +1438,7 @@ static int emac_poll(struct napi_struct *napi, int budget) * Polled functionality used by netconsole and others in non interrupt mode * */ -void emac_poll_controller(struct net_device *ndev) +static void emac_poll_controller(struct net_device *ndev) { struct emac_priv *priv = netdev_priv(ndev); -- cgit From 47a5247fddf30a1c0d1f5a1afb3bd17e8715075e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 20 Mar 2013 05:06:11 +0000 Subject: net: fec: make local function fec_poll_controller() static fec_poll_controller() was not declared. It should be static. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 186222ef1012..3eb608f5d0c7 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1556,7 +1556,7 @@ fec_set_mac_address(struct net_device *ndev, void *p) * Polled functionality used by netconsole and others in non interrupt mode * */ -void fec_poll_controller(struct net_device *dev) +static void fec_poll_controller(struct net_device *dev) { int i; struct fec_enet_private *fep = netdev_priv(dev); -- cgit From 7fa6f34081f168975af72be51715bdc6601931f7 Mon Sep 17 00:00:00 2001 From: Yuval Mintz Date: Wed, 20 Mar 2013 05:21:28 +0000 Subject: bnx2x: AER revised Revised bnx2x implementation of PCI Express Advanced Error Recovery - stop and free driver resources according to the AER flow (instead of the currently implemented `hope-for-the-best' release approach), and do not make any assumptions on the HW state after slot reset. Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 3 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 149 +++++++++++++++++++---- 4 files changed, 130 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index a4729c73ab80..c59da2d7b065 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1226,10 +1226,11 @@ enum { struct bnx2x_prev_path_list { + struct list_head list; u8 bus; u8 slot; u8 path; - struct list_head list; + u8 aer; u8 undi; }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index db6912b09997..3f5cd7c9f103 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2010,7 +2010,7 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) * Cleans the object that have internal lists without sending * ramrods. Should be run when interrutps are disabled. */ -static void bnx2x_squeeze_objects(struct bnx2x *bp) +void bnx2x_squeeze_objects(struct bnx2x *bp) { int rc; unsigned long ramrod_flags = 0, vlan_mac_flags = 0; @@ -2775,7 +2775,7 @@ load_error0: #endif /* ! BNX2X_STOP_ON_ERROR */ } -static int bnx2x_drain_tx_queues(struct bnx2x *bp) +int bnx2x_drain_tx_queues(struct bnx2x *bp) { u8 rc = 0, cos, i; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index f9098d8fc25b..54e1b149acb3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1402,4 +1402,8 @@ static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr) * */ void bnx2x_fill_fw_str(struct bnx2x *bp, char *buf, size_t buf_len); + +int bnx2x_drain_tx_queues(struct bnx2x *bp); +void bnx2x_squeeze_objects(struct bnx2x *bp); + #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 4902d1eb3d1e..10b0748a2d72 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9718,6 +9718,31 @@ static struct bnx2x_prev_path_list * return NULL; } +static int bnx2x_prev_path_mark_eeh(struct bnx2x *bp) +{ + struct bnx2x_prev_path_list *tmp_list; + int rc; + + rc = down_interruptible(&bnx2x_prev_sem); + if (rc) { + BNX2X_ERR("Received %d when tried to take lock\n", rc); + return rc; + } + + tmp_list = bnx2x_prev_path_get_entry(bp); + if (tmp_list) { + tmp_list->aer = 1; + rc = 0; + } else { + BNX2X_ERR("path %d: Entry does not exist for eeh; Flow occurs before initial insmod is over ?\n", + BP_PATH(bp)); + } + + up(&bnx2x_prev_sem); + + return rc; +} + static bool bnx2x_prev_is_path_marked(struct bnx2x *bp) { struct bnx2x_prev_path_list *tmp_list; @@ -9726,14 +9751,15 @@ static bool bnx2x_prev_is_path_marked(struct bnx2x *bp) if (down_trylock(&bnx2x_prev_sem)) return false; - list_for_each_entry(tmp_list, &bnx2x_prev_list, list) { - if (PCI_SLOT(bp->pdev->devfn) == tmp_list->slot && - bp->pdev->bus->number == tmp_list->bus && - BP_PATH(bp) == tmp_list->path) { + tmp_list = bnx2x_prev_path_get_entry(bp); + if (tmp_list) { + if (tmp_list->aer) { + DP(NETIF_MSG_HW, "Path %d was marked by AER\n", + BP_PATH(bp)); + } else { rc = true; BNX2X_DEV_INFO("Path %d was already cleaned from previous drivers\n", BP_PATH(bp)); - break; } } @@ -9747,6 +9773,28 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi) struct bnx2x_prev_path_list *tmp_list; int rc; + rc = down_interruptible(&bnx2x_prev_sem); + if (rc) { + BNX2X_ERR("Received %d when tried to take lock\n", rc); + return rc; + } + + /* Check whether the entry for this path already exists */ + tmp_list = bnx2x_prev_path_get_entry(bp); + if (tmp_list) { + if (!tmp_list->aer) { + BNX2X_ERR("Re-Marking the path.\n"); + } else { + DP(NETIF_MSG_HW, "Removing AER indication from path %d\n", + BP_PATH(bp)); + tmp_list->aer = 0; + } + up(&bnx2x_prev_sem); + return 0; + } + up(&bnx2x_prev_sem); + + /* Create an entry for this path and add it */ tmp_list = kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL); if (!tmp_list) { BNX2X_ERR("Failed to allocate 'bnx2x_prev_path_list'\n"); @@ -9756,6 +9804,7 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi) tmp_list->bus = bp->pdev->bus->number; tmp_list->slot = PCI_SLOT(bp->pdev->devfn); tmp_list->path = BP_PATH(bp); + tmp_list->aer = 0; tmp_list->undi = after_undi ? (1 << BP_PORT(bp)) : 0; rc = down_interruptible(&bnx2x_prev_sem); @@ -9763,8 +9812,8 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi) BNX2X_ERR("Received %d when tried to take lock\n", rc); kfree(tmp_list); } else { - BNX2X_DEV_INFO("Marked path [%d] - finished previous unload\n", - BP_PATH(bp)); + DP(NETIF_MSG_HW, "Marked path [%d] - finished previous unload\n", + BP_PATH(bp)); list_add(&tmp_list->list, &bnx2x_prev_list); up(&bnx2x_prev_sem); } @@ -10003,6 +10052,7 @@ static int bnx2x_prev_unload(struct bnx2x *bp) } do { + int aer = 0; /* Lock MCP using an unload request */ fw = bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS, 0); if (!fw) { @@ -10011,7 +10061,18 @@ static int bnx2x_prev_unload(struct bnx2x *bp) break; } - if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON) { + rc = down_interruptible(&bnx2x_prev_sem); + if (rc) { + BNX2X_ERR("Cannot check for AER; Received %d when tried to take lock\n", + rc); + } else { + /* If Path is marked by EEH, ignore unload status */ + aer = !!(bnx2x_prev_path_get_entry(bp) && + bnx2x_prev_path_get_entry(bp)->aer); + } + up(&bnx2x_prev_sem); + + if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON || aer) { rc = bnx2x_prev_unload_common(bp); break; } @@ -12632,9 +12693,7 @@ static void bnx2x_remove_one(struct pci_dev *pdev) static int bnx2x_eeh_nic_unload(struct bnx2x *bp) { - int i; - - bp->state = BNX2X_STATE_ERROR; + bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; bp->rx_mode = BNX2X_RX_MODE_NONE; @@ -12643,29 +12702,21 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) /* Stop Tx */ bnx2x_tx_disable(bp); - - bnx2x_netif_stop(bp, 0); /* Delete all NAPI objects */ bnx2x_del_all_napi(bp); if (CNIC_LOADED(bp)) bnx2x_del_all_napi_cnic(bp); + netdev_reset_tc(bp->dev); del_timer_sync(&bp->timer); + cancel_delayed_work(&bp->sp_task); + cancel_delayed_work(&bp->period_task); - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - - /* Release IRQs */ - bnx2x_free_irq(bp); - - /* Free SKBs, SGEs, TPA pool and driver internals */ - bnx2x_free_skbs(bp); - - for_each_rx_queue(bp, i) - bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - - bnx2x_free_mem(bp); + spin_lock_bh(&bp->stats_lock); + bp->stats_state = STATS_STATE_DISABLED; + spin_unlock_bh(&bp->stats_lock); - bp->state = BNX2X_STATE_CLOSED; + bnx2x_save_statistics(bp); netif_carrier_off(bp->dev); @@ -12701,6 +12752,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev, rtnl_lock(); + BNX2X_ERR("IO error detected\n"); + netif_device_detach(dev); if (state == pci_channel_io_perm_failure) { @@ -12711,6 +12764,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev, if (netif_running(dev)) bnx2x_eeh_nic_unload(bp); + bnx2x_prev_path_mark_eeh(bp); + pci_disable_device(pdev); rtnl_unlock(); @@ -12729,9 +12784,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct bnx2x *bp = netdev_priv(dev); + int i; rtnl_lock(); - + BNX2X_ERR("IO slot reset initializing...\n"); if (pci_enable_device(pdev)) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset\n"); @@ -12745,6 +12801,42 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) if (netif_running(dev)) bnx2x_set_power_state(bp, PCI_D0); + if (netif_running(dev)) { + BNX2X_ERR("IO slot reset --> driver unload\n"); + if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { + u32 v; + + v = SHMEM2_RD(bp, + drv_capabilities_flag[BP_FW_MB_IDX(bp)]); + SHMEM2_WR(bp, drv_capabilities_flag[BP_FW_MB_IDX(bp)], + v & ~DRV_FLAGS_CAPABILITIES_LOADED_L2); + } + bnx2x_drain_tx_queues(bp); + bnx2x_send_unload_req(bp, UNLOAD_RECOVERY); + bnx2x_netif_stop(bp, 1); + bnx2x_free_irq(bp); + + /* Report UNLOAD_DONE to MCP */ + bnx2x_send_unload_done(bp, true); + + bp->sp_state = 0; + bp->port.pmf = 0; + + bnx2x_prev_unload(bp); + + /* We should have resetted the engine, so It's fair to + * assume the FW will no longer write to the bnx2x driver. + */ + bnx2x_squeeze_objects(bp); + bnx2x_free_skbs(bp); + for_each_rx_queue(bp, i) + bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); + bnx2x_free_fp_mem(bp); + bnx2x_free_mem(bp); + + bp->state = BNX2X_STATE_CLOSED; + } + rtnl_unlock(); return PCI_ERS_RESULT_RECOVERED; @@ -12771,6 +12863,9 @@ static void bnx2x_io_resume(struct pci_dev *pdev) bnx2x_eeh_recover(bp); + bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK; + if (netif_running(dev)) bnx2x_nic_load(bp, LOAD_NORMAL); -- cgit From 70386d40e19eeff8696f2593755e78f6f7fa9e6d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Mar 2013 09:33:19 -0700 Subject: chelsio: add headroom in RX path Drivers should reserve some headroom in skb used in receive path, to avoid future head reallocation. One possible way to do that is to use dev_alloc_skb() instead of alloc_skb(), so that NET_SKB_PAD bytes are reserved. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb/sge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c index 482976925154..89bef504d9dc 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c @@ -835,7 +835,7 @@ static void refill_free_list(struct sge *sge, struct freelQ *q) struct sk_buff *skb; dma_addr_t mapping; - skb = alloc_skb(q->rx_buffer_size, GFP_ATOMIC); + skb = dev_alloc_skb(q->rx_buffer_size); if (!skb) break; -- cgit From 75f32ec1de7a4c905ba2007972d981f96c977eb2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 20 Mar 2013 14:18:28 +0200 Subject: arm: tegra: fix Kconfig select clauses USB_ULPI and USB_ULPI_VIEWPORT shouldn't really be selected directly by anyone, but since Tegra still needs some time before turning ulpi viewport into a proper PHY driver, we need to keep the selects in place. This patch just fixes the conditional select so that it will continue to build after merging the latest PHY layer changes. Acked-by: Stephen Warren Tested-by: Stephen Warren Signed-off-by: Felipe Balbi --- arch/arm/mach-tegra/Kconfig | 8 ++++---- drivers/usb/host/Kconfig | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index d1c4893894ce..dbc653ea851c 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -18,8 +18,8 @@ config ARCH_TEGRA_2x_SOC select PL310_ERRATA_727915 if CACHE_L2X0 select PL310_ERRATA_769419 if CACHE_L2X0 select USB_ARCH_HAS_EHCI if USB_SUPPORT - select USB_ULPI if USB - select USB_ULPI_VIEWPORT if USB_SUPPORT + select USB_ULPI if USB_PHY + select USB_ULPI_VIEWPORT if USB_PHY help Support for NVIDIA Tegra AP20 and T20 processors, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller @@ -37,8 +37,8 @@ config ARCH_TEGRA_3x_SOC select PINCTRL_TEGRA30 select PL310_ERRATA_769419 if CACHE_L2X0 select USB_ARCH_HAS_EHCI if USB_SUPPORT - select USB_ULPI if USB - select USB_ULPI_VIEWPORT if USB_SUPPORT + select USB_ULPI if USB_PHY + select USB_ULPI_VIEWPORT if USB_PHY help Support for NVIDIA Tegra T30 processor family, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ba1347ccb9dd..1b58587b7be9 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -179,6 +179,7 @@ config USB_EHCI_TEGRA boolean "NVIDIA Tegra HCD support" depends on USB_EHCI_HCD && ARCH_TEGRA select USB_EHCI_ROOT_HUB_TT + select USB_PHY help This driver enables support for the internal USB Host Controllers found in NVIDIA Tegra SoCs. The controllers are EHCI compliant. -- cgit From e76d120b68d2e0f159ba999b1210920a5a0ed53d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 20 Mar 2013 09:02:41 +0000 Subject: chelsio: use netdev_alloc_skb_ip_align Use netdev_alloc_sk_ip_align in the case where packet is copied. This handles case where NET_IP_ALIGN == 0 as well as adding required header padding. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb/sge.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c index 89bef504d9dc..55fe8c9f0484 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c @@ -1046,11 +1046,10 @@ static inline struct sk_buff *get_packet(struct pci_dev *pdev, const struct freelQ_ce *ce = &fl->centries[fl->cidx]; if (len < copybreak) { - skb = alloc_skb(len + 2, GFP_ATOMIC); + skb = netdev_alloc_skb_ip_align(NULL, len); if (!skb) goto use_orig_buf; - skb_reserve(skb, 2); /* align IP header */ skb_put(skb, len); pci_dma_sync_single_for_cpu(pdev, dma_unmap_addr(ce, dma_addr), -- cgit From 3465a22488a47d5f4791876a22fde2bb1720f4cf Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 20 Mar 2013 15:52:00 +0000 Subject: staging/iio: iio_hwmon: Use device tree node name for hwmon name attribute So far, all instances of iio_hwmon set their hwmon name attribute to "iio_hwmon", which is not very descriptive. Set it to the device tree node name if available, and only revert to iio_hwmon otherwise. Signed-off-by: Guenter Roeck Signed-off-by: Jonathan Cameron --- drivers/staging/iio/iio_hwmon.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 93af756ba48c..aafa4531b961 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -58,7 +59,12 @@ static ssize_t iio_hwmon_read_val(struct device *dev, static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "iio_hwmon\n"); + const char *name = "iio_hwmon"; + + if (dev->of_node && dev->of_node->name) + name = dev->of_node->name; + + return sprintf(buf, "%s\n", name); } static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -- cgit From 29727f3bc2e691d59c521ff09b4d59a743b5d9a3 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 20 Mar 2013 11:46:10 -0400 Subject: Revert "USB: quatech2: only write to the tty if the port is open." This reverts commit 27b351c5546008c640b3e65152f60ca74b3706f1. Calling tty_flip_buffer_push on an unopened tty is legal, so the driver doesn't need track if port has been opened. Reverting this allows the entire is_open logic to be removed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/quatech2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index d643a4d4d770..00e6c9bac8a3 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -661,9 +661,7 @@ void qt2_process_read_urb(struct urb *urb) __func__); break; } - - if (port_priv->is_open) - tty_flip_buffer_push(&port->port); + tty_flip_buffer_push(&port->port); newport = *(ch + 3); @@ -706,8 +704,7 @@ void qt2_process_read_urb(struct urb *urb) tty_insert_flip_string(&port->port, ch, 1); } - if (port_priv->is_open) - tty_flip_buffer_push(&port->port); + tty_flip_buffer_push(&port->port); } static void qt2_write_bulk_callback(struct urb *urb) -- cgit From 5de8875281e1db024d67cbd5c792264194bfca2a Mon Sep 17 00:00:00 2001 From: Javier Martin Date: Fri, 1 Mar 2013 12:37:53 +0100 Subject: crypto: sahara - Add driver for SAHARA2 accelerator. SAHARA2 HW module is included in the i.MX27 SoC from Freescale. It is capable of performing cipher algorithms such as AES, 3DES..., hashing and RNG too. This driver provides support for AES-CBC and AES-ECB by now. Reviewed-by: Arnd Bergmann Signed-off-by: Javier Martin Signed-off-by: Herbert Xu --- .../devicetree/bindings/crypto/fsl-imx-sahara.txt | 15 + drivers/crypto/Kconfig | 10 + drivers/crypto/Makefile | 1 + drivers/crypto/sahara.c | 1070 ++++++++++++++++++++ 4 files changed, 1096 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt create mode 100644 drivers/crypto/sahara.c (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt b/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt new file mode 100644 index 000000000000..5c65eccd0e56 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt @@ -0,0 +1,15 @@ +Freescale SAHARA Cryptographic Accelerator included in some i.MX chips. +Currently only i.MX27 is supported. + +Required properties: +- compatible : Should be "fsl,-sahara" +- reg : Should contain SAHARA registers location and length +- interrupts : Should contain SAHARA interrupt number + +Example: + +sah@10025000 { + compatible = "fsl,imx27-sahara"; + reg = < 0x10025000 0x800>; + interrupts = <75>; +}; diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e66fb0a332d4..dffb85525368 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -276,6 +276,16 @@ config CRYPTO_DEV_PICOXCELL Saying m here will build a module named pipcoxcell_crypto. +config CRYPTO_DEV_SAHARA + tristate "Support for SAHARA crypto accelerator" + depends on ARCH_MXC && EXPERIMENTAL && OF + select CRYPTO_BLKCIPHER + select CRYPTO_AES + select CRYPTO_ECB + help + This option enables support for the SAHARA HW crypto accelerator + found in some Freescale i.MX chips. + config CRYPTO_DEV_S5P tristate "Support for Samsung S5PV210 crypto accelerator" depends on ARCH_S5PV210 diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 880a47b0b023..38ce13d3b79b 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o +obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/ diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c new file mode 100644 index 000000000000..a97bb6c1596c --- /dev/null +++ b/drivers/crypto/sahara.c @@ -0,0 +1,1070 @@ +/* + * Cryptographic API. + * + * Support for SAHARA cryptographic accelerator. + * + * Copyright (c) 2013 Vista Silicon S.L. + * Author: Javier Martin + * + * 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. + * + * Based on omap-aes.c and tegra-aes.c + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SAHARA_NAME "sahara" +#define SAHARA_VERSION_3 3 +#define SAHARA_TIMEOUT_MS 1000 +#define SAHARA_MAX_HW_DESC 2 +#define SAHARA_MAX_HW_LINK 20 + +#define FLAGS_MODE_MASK 0x000f +#define FLAGS_ENCRYPT BIT(0) +#define FLAGS_CBC BIT(1) +#define FLAGS_NEW_KEY BIT(3) +#define FLAGS_BUSY 4 + +#define SAHARA_HDR_BASE 0x00800000 +#define SAHARA_HDR_SKHA_ALG_AES 0 +#define SAHARA_HDR_SKHA_OP_ENC (1 << 2) +#define SAHARA_HDR_SKHA_MODE_ECB (0 << 3) +#define SAHARA_HDR_SKHA_MODE_CBC (1 << 3) +#define SAHARA_HDR_FORM_DATA (5 << 16) +#define SAHARA_HDR_FORM_KEY (8 << 16) +#define SAHARA_HDR_LLO (1 << 24) +#define SAHARA_HDR_CHA_SKHA (1 << 28) +#define SAHARA_HDR_CHA_MDHA (2 << 28) +#define SAHARA_HDR_PARITY_BIT (1 << 31) + +/* SAHARA can only process one request at a time */ +#define SAHARA_QUEUE_LENGTH 1 + +#define SAHARA_REG_VERSION 0x00 +#define SAHARA_REG_DAR 0x04 +#define SAHARA_REG_CONTROL 0x08 +#define SAHARA_CONTROL_SET_THROTTLE(x) (((x) & 0xff) << 24) +#define SAHARA_CONTROL_SET_MAXBURST(x) (((x) & 0xff) << 16) +#define SAHARA_CONTROL_RNG_AUTORSD (1 << 7) +#define SAHARA_CONTROL_ENABLE_INT (1 << 4) +#define SAHARA_REG_CMD 0x0C +#define SAHARA_CMD_RESET (1 << 0) +#define SAHARA_CMD_CLEAR_INT (1 << 8) +#define SAHARA_CMD_CLEAR_ERR (1 << 9) +#define SAHARA_CMD_SINGLE_STEP (1 << 10) +#define SAHARA_CMD_MODE_BATCH (1 << 16) +#define SAHARA_CMD_MODE_DEBUG (1 << 18) +#define SAHARA_REG_STATUS 0x10 +#define SAHARA_STATUS_GET_STATE(x) ((x) & 0x7) +#define SAHARA_STATE_IDLE 0 +#define SAHARA_STATE_BUSY 1 +#define SAHARA_STATE_ERR 2 +#define SAHARA_STATE_FAULT 3 +#define SAHARA_STATE_COMPLETE 4 +#define SAHARA_STATE_COMP_FLAG (1 << 2) +#define SAHARA_STATUS_DAR_FULL (1 << 3) +#define SAHARA_STATUS_ERROR (1 << 4) +#define SAHARA_STATUS_SECURE (1 << 5) +#define SAHARA_STATUS_FAIL (1 << 6) +#define SAHARA_STATUS_INIT (1 << 7) +#define SAHARA_STATUS_RNG_RESEED (1 << 8) +#define SAHARA_STATUS_ACTIVE_RNG (1 << 9) +#define SAHARA_STATUS_ACTIVE_MDHA (1 << 10) +#define SAHARA_STATUS_ACTIVE_SKHA (1 << 11) +#define SAHARA_STATUS_MODE_BATCH (1 << 16) +#define SAHARA_STATUS_MODE_DEDICATED (1 << 17) +#define SAHARA_STATUS_MODE_DEBUG (1 << 18) +#define SAHARA_STATUS_GET_ISTATE(x) (((x) >> 24) & 0xff) +#define SAHARA_REG_ERRSTATUS 0x14 +#define SAHARA_ERRSTATUS_GET_SOURCE(x) ((x) & 0xf) +#define SAHARA_ERRSOURCE_CHA 14 +#define SAHARA_ERRSOURCE_DMA 15 +#define SAHARA_ERRSTATUS_DMA_DIR (1 << 8) +#define SAHARA_ERRSTATUS_GET_DMASZ(x)(((x) >> 9) & 0x3) +#define SAHARA_ERRSTATUS_GET_DMASRC(x) (((x) >> 13) & 0x7) +#define SAHARA_ERRSTATUS_GET_CHASRC(x) (((x) >> 16) & 0xfff) +#define SAHARA_ERRSTATUS_GET_CHAERR(x) (((x) >> 28) & 0x3) +#define SAHARA_REG_FADDR 0x18 +#define SAHARA_REG_CDAR 0x1C +#define SAHARA_REG_IDAR 0x20 + +struct sahara_hw_desc { + u32 hdr; + u32 len1; + dma_addr_t p1; + u32 len2; + dma_addr_t p2; + dma_addr_t next; +}; + +struct sahara_hw_link { + u32 len; + dma_addr_t p; + dma_addr_t next; +}; + +struct sahara_ctx { + struct sahara_dev *dev; + unsigned long flags; + int keylen; + u8 key[AES_KEYSIZE_128]; + struct crypto_ablkcipher *fallback; +}; + +struct sahara_aes_reqctx { + unsigned long mode; +}; + +struct sahara_dev { + struct device *device; + void __iomem *regs_base; + struct clk *clk_ipg; + struct clk *clk_ahb; + + struct sahara_ctx *ctx; + spinlock_t lock; + struct crypto_queue queue; + unsigned long flags; + + struct tasklet_struct done_task; + struct tasklet_struct queue_task; + + struct sahara_hw_desc *hw_desc[SAHARA_MAX_HW_DESC]; + dma_addr_t hw_phys_desc[SAHARA_MAX_HW_DESC]; + + u8 *key_base; + dma_addr_t key_phys_base; + + u8 *iv_base; + dma_addr_t iv_phys_base; + + struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK]; + dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK]; + + struct ablkcipher_request *req; + size_t total; + struct scatterlist *in_sg; + unsigned int nb_in_sg; + struct scatterlist *out_sg; + unsigned int nb_out_sg; + + u32 error; + struct timer_list watchdog; +}; + +static struct sahara_dev *dev_ptr; + +static inline void sahara_write(struct sahara_dev *dev, u32 data, u32 reg) +{ + writel(data, dev->regs_base + reg); +} + +static inline unsigned int sahara_read(struct sahara_dev *dev, u32 reg) +{ + return readl(dev->regs_base + reg); +} + +static u32 sahara_aes_key_hdr(struct sahara_dev *dev) +{ + u32 hdr = SAHARA_HDR_BASE | SAHARA_HDR_SKHA_ALG_AES | + SAHARA_HDR_FORM_KEY | SAHARA_HDR_LLO | + SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT; + + if (dev->flags & FLAGS_CBC) { + hdr |= SAHARA_HDR_SKHA_MODE_CBC; + hdr ^= SAHARA_HDR_PARITY_BIT; + } + + if (dev->flags & FLAGS_ENCRYPT) { + hdr |= SAHARA_HDR_SKHA_OP_ENC; + hdr ^= SAHARA_HDR_PARITY_BIT; + } + + return hdr; +} + +static u32 sahara_aes_data_link_hdr(struct sahara_dev *dev) +{ + return SAHARA_HDR_BASE | SAHARA_HDR_FORM_DATA | + SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT; +} + +static int sahara_sg_length(struct scatterlist *sg, + unsigned int total) +{ + int sg_nb; + unsigned int len; + struct scatterlist *sg_list; + + sg_nb = 0; + sg_list = sg; + + while (total) { + len = min(sg_list->length, total); + + sg_nb++; + total -= len; + + sg_list = sg_next(sg_list); + if (!sg_list) + total = 0; + } + + return sg_nb; +} + +static char *sahara_err_src[16] = { + "No error", + "Header error", + "Descriptor length error", + "Descriptor length or pointer error", + "Link length error", + "Link pointer error", + "Input buffer error", + "Output buffer error", + "Output buffer starvation", + "Internal state fault", + "General descriptor problem", + "Reserved", + "Descriptor address error", + "Link address error", + "CHA error", + "DMA error" +}; + +static char *sahara_err_dmasize[4] = { + "Byte transfer", + "Half-word transfer", + "Word transfer", + "Reserved" +}; + +static char *sahara_err_dmasrc[8] = { + "No error", + "AHB bus error", + "Internal IP bus error", + "Parity error", + "DMA crosses 256 byte boundary", + "DMA is busy", + "Reserved", + "DMA HW error" +}; + +static char *sahara_cha_errsrc[12] = { + "Input buffer non-empty", + "Illegal address", + "Illegal mode", + "Illegal data size", + "Illegal key size", + "Write during processing", + "CTX read during processing", + "HW error", + "Input buffer disabled/underflow", + "Output buffer disabled/overflow", + "DES key parity error", + "Reserved" +}; + +static char *sahara_cha_err[4] = { "No error", "SKHA", "MDHA", "RNG" }; + +static void sahara_decode_error(struct sahara_dev *dev, unsigned int error) +{ + u8 source = SAHARA_ERRSTATUS_GET_SOURCE(error); + u16 chasrc = ffs(SAHARA_ERRSTATUS_GET_CHASRC(error)); + + dev_err(dev->device, "%s: Error Register = 0x%08x\n", __func__, error); + + dev_err(dev->device, " - %s.\n", sahara_err_src[source]); + + if (source == SAHARA_ERRSOURCE_DMA) { + if (error & SAHARA_ERRSTATUS_DMA_DIR) + dev_err(dev->device, " * DMA read.\n"); + else + dev_err(dev->device, " * DMA write.\n"); + + dev_err(dev->device, " * %s.\n", + sahara_err_dmasize[SAHARA_ERRSTATUS_GET_DMASZ(error)]); + dev_err(dev->device, " * %s.\n", + sahara_err_dmasrc[SAHARA_ERRSTATUS_GET_DMASRC(error)]); + } else if (source == SAHARA_ERRSOURCE_CHA) { + dev_err(dev->device, " * %s.\n", + sahara_cha_errsrc[chasrc]); + dev_err(dev->device, " * %s.\n", + sahara_cha_err[SAHARA_ERRSTATUS_GET_CHAERR(error)]); + } + dev_err(dev->device, "\n"); +} + +static char *sahara_state[4] = { "Idle", "Busy", "Error", "HW Fault" }; + +static void sahara_decode_status(struct sahara_dev *dev, unsigned int status) +{ + u8 state; + + if (!IS_ENABLED(DEBUG)) + return; + + state = SAHARA_STATUS_GET_STATE(status); + + dev_dbg(dev->device, "%s: Status Register = 0x%08x\n", + __func__, status); + + dev_dbg(dev->device, " - State = %d:\n", state); + if (state & SAHARA_STATE_COMP_FLAG) + dev_dbg(dev->device, " * Descriptor completed. IRQ pending.\n"); + + dev_dbg(dev->device, " * %s.\n", + sahara_state[state & ~SAHARA_STATE_COMP_FLAG]); + + if (status & SAHARA_STATUS_DAR_FULL) + dev_dbg(dev->device, " - DAR Full.\n"); + if (status & SAHARA_STATUS_ERROR) + dev_dbg(dev->device, " - Error.\n"); + if (status & SAHARA_STATUS_SECURE) + dev_dbg(dev->device, " - Secure.\n"); + if (status & SAHARA_STATUS_FAIL) + dev_dbg(dev->device, " - Fail.\n"); + if (status & SAHARA_STATUS_RNG_RESEED) + dev_dbg(dev->device, " - RNG Reseed Request.\n"); + if (status & SAHARA_STATUS_ACTIVE_RNG) + dev_dbg(dev->device, " - RNG Active.\n"); + if (status & SAHARA_STATUS_ACTIVE_MDHA) + dev_dbg(dev->device, " - MDHA Active.\n"); + if (status & SAHARA_STATUS_ACTIVE_SKHA) + dev_dbg(dev->device, " - SKHA Active.\n"); + + if (status & SAHARA_STATUS_MODE_BATCH) + dev_dbg(dev->device, " - Batch Mode.\n"); + else if (status & SAHARA_STATUS_MODE_DEDICATED) + dev_dbg(dev->device, " - Decidated Mode.\n"); + else if (status & SAHARA_STATUS_MODE_DEBUG) + dev_dbg(dev->device, " - Debug Mode.\n"); + + dev_dbg(dev->device, " - Internal state = 0x%02x\n", + SAHARA_STATUS_GET_ISTATE(status)); + + dev_dbg(dev->device, "Current DAR: 0x%08x\n", + sahara_read(dev, SAHARA_REG_CDAR)); + dev_dbg(dev->device, "Initial DAR: 0x%08x\n\n", + sahara_read(dev, SAHARA_REG_IDAR)); +} + +static void sahara_dump_descriptors(struct sahara_dev *dev) +{ + int i; + + if (!IS_ENABLED(DEBUG)) + return; + + for (i = 0; i < SAHARA_MAX_HW_DESC; i++) { + dev_dbg(dev->device, "Descriptor (%d) (0x%08x):\n", + i, dev->hw_phys_desc[i]); + dev_dbg(dev->device, "\thdr = 0x%08x\n", dev->hw_desc[i]->hdr); + dev_dbg(dev->device, "\tlen1 = %u\n", dev->hw_desc[i]->len1); + dev_dbg(dev->device, "\tp1 = 0x%08x\n", dev->hw_desc[i]->p1); + dev_dbg(dev->device, "\tlen2 = %u\n", dev->hw_desc[i]->len2); + dev_dbg(dev->device, "\tp2 = 0x%08x\n", dev->hw_desc[i]->p2); + dev_dbg(dev->device, "\tnext = 0x%08x\n", + dev->hw_desc[i]->next); + } + dev_dbg(dev->device, "\n"); +} + +static void sahara_dump_links(struct sahara_dev *dev) +{ + int i; + + if (!IS_ENABLED(DEBUG)) + return; + + for (i = 0; i < SAHARA_MAX_HW_LINK; i++) { + dev_dbg(dev->device, "Link (%d) (0x%08x):\n", + i, dev->hw_phys_link[i]); + dev_dbg(dev->device, "\tlen = %u\n", dev->hw_link[i]->len); + dev_dbg(dev->device, "\tp = 0x%08x\n", dev->hw_link[i]->p); + dev_dbg(dev->device, "\tnext = 0x%08x\n", + dev->hw_link[i]->next); + } + dev_dbg(dev->device, "\n"); +} + +static void sahara_aes_done_task(unsigned long data) +{ + struct sahara_dev *dev = (struct sahara_dev *)data; + + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_TO_DEVICE); + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_FROM_DEVICE); + + spin_lock(&dev->lock); + clear_bit(FLAGS_BUSY, &dev->flags); + spin_unlock(&dev->lock); + + dev->req->base.complete(&dev->req->base, dev->error); +} + +void sahara_watchdog(unsigned long data) +{ + struct sahara_dev *dev = (struct sahara_dev *)data; + unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS); + unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS); + + sahara_decode_status(dev, stat); + sahara_decode_error(dev, err); + dev->error = -ETIMEDOUT; + sahara_aes_done_task(data); +} + +static int sahara_hw_descriptor_create(struct sahara_dev *dev) +{ + struct sahara_ctx *ctx = dev->ctx; + struct scatterlist *sg; + int ret; + int i, j; + + /* Copy new key if necessary */ + if (ctx->flags & FLAGS_NEW_KEY) { + memcpy(dev->key_base, ctx->key, ctx->keylen); + ctx->flags &= ~FLAGS_NEW_KEY; + + if (dev->flags & FLAGS_CBC) { + dev->hw_desc[0]->len1 = AES_BLOCK_SIZE; + dev->hw_desc[0]->p1 = dev->iv_phys_base; + } else { + dev->hw_desc[0]->len1 = 0; + dev->hw_desc[0]->p1 = 0; + } + dev->hw_desc[0]->len2 = ctx->keylen; + dev->hw_desc[0]->p2 = dev->key_phys_base; + dev->hw_desc[0]->next = dev->hw_phys_desc[1]; + } + dev->hw_desc[0]->hdr = sahara_aes_key_hdr(dev); + + dev->nb_in_sg = sahara_sg_length(dev->in_sg, dev->total); + dev->nb_out_sg = sahara_sg_length(dev->out_sg, dev->total); + if ((dev->nb_in_sg + dev->nb_out_sg) > SAHARA_MAX_HW_LINK) { + dev_err(dev->device, "not enough hw links (%d)\n", + dev->nb_in_sg + dev->nb_out_sg); + return -EINVAL; + } + + ret = dma_map_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); + if (ret != dev->nb_in_sg) { + dev_err(dev->device, "couldn't map in sg\n"); + goto unmap_in; + } + ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_FROM_DEVICE); + if (ret != dev->nb_out_sg) { + dev_err(dev->device, "couldn't map out sg\n"); + goto unmap_out; + } + + /* Create input links */ + dev->hw_desc[1]->p1 = dev->hw_phys_link[0]; + sg = dev->in_sg; + for (i = 0; i < dev->nb_in_sg; i++) { + dev->hw_link[i]->len = sg->length; + dev->hw_link[i]->p = sg->dma_address; + if (i == (dev->nb_in_sg - 1)) { + dev->hw_link[i]->next = 0; + } else { + dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; + sg = sg_next(sg); + } + } + + /* Create output links */ + dev->hw_desc[1]->p2 = dev->hw_phys_link[i]; + sg = dev->out_sg; + for (j = i; j < dev->nb_out_sg + i; j++) { + dev->hw_link[j]->len = sg->length; + dev->hw_link[j]->p = sg->dma_address; + if (j == (dev->nb_out_sg + i - 1)) { + dev->hw_link[j]->next = 0; + } else { + dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; + sg = sg_next(sg); + } + } + + /* Fill remaining fields of hw_desc[1] */ + dev->hw_desc[1]->hdr = sahara_aes_data_link_hdr(dev); + dev->hw_desc[1]->len1 = dev->total; + dev->hw_desc[1]->len2 = dev->total; + dev->hw_desc[1]->next = 0; + + sahara_dump_descriptors(dev); + sahara_dump_links(dev); + + /* Start processing descriptor chain. */ + mod_timer(&dev->watchdog, + jiffies + msecs_to_jiffies(SAHARA_TIMEOUT_MS)); + sahara_write(dev, dev->hw_phys_desc[0], SAHARA_REG_DAR); + + return 0; + +unmap_out: + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_TO_DEVICE); +unmap_in: + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_FROM_DEVICE); + + return -EINVAL; +} + +static void sahara_aes_queue_task(unsigned long data) +{ + struct sahara_dev *dev = (struct sahara_dev *)data; + struct crypto_async_request *async_req, *backlog; + struct sahara_ctx *ctx; + struct sahara_aes_reqctx *rctx; + struct ablkcipher_request *req; + int ret; + + spin_lock(&dev->lock); + backlog = crypto_get_backlog(&dev->queue); + async_req = crypto_dequeue_request(&dev->queue); + if (!async_req) + clear_bit(FLAGS_BUSY, &dev->flags); + spin_unlock(&dev->lock); + + if (!async_req) + return; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + req = ablkcipher_request_cast(async_req); + + /* Request is ready to be dispatched by the device */ + dev_dbg(dev->device, + "dispatch request (nbytes=%d, src=%p, dst=%p)\n", + req->nbytes, req->src, req->dst); + + /* assign new request to device */ + dev->req = req; + dev->total = req->nbytes; + dev->in_sg = req->src; + dev->out_sg = req->dst; + + rctx = ablkcipher_request_ctx(req); + ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); + rctx->mode &= FLAGS_MODE_MASK; + dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode; + + if ((dev->flags & FLAGS_CBC) && req->info) + memcpy(dev->iv_base, req->info, AES_KEYSIZE_128); + + /* assign new context to device */ + ctx->dev = dev; + dev->ctx = ctx; + + ret = sahara_hw_descriptor_create(dev); + if (ret < 0) { + spin_lock(&dev->lock); + clear_bit(FLAGS_BUSY, &dev->flags); + spin_unlock(&dev->lock); + dev->req->base.complete(&dev->req->base, ret); + } +} + +static int sahara_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct sahara_ctx *ctx = crypto_ablkcipher_ctx(tfm); + int ret; + + ctx->keylen = keylen; + + /* SAHARA only supports 128bit keys */ + if (keylen == AES_KEYSIZE_128) { + memcpy(ctx->key, key, keylen); + ctx->flags |= FLAGS_NEW_KEY; + return 0; + } + + if (keylen != AES_KEYSIZE_128 && + keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256) + return -EINVAL; + + /* + * The requested key size is not supported by HW, do a fallback. + */ + ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + ctx->fallback->base.crt_flags |= + (tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK); + + ret = crypto_ablkcipher_setkey(ctx->fallback, key, keylen); + if (ret) { + struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm); + + tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK; + tfm_aux->crt_flags |= + (ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK); + } + return ret; +} + +static int sahara_aes_crypt(struct ablkcipher_request *req, unsigned long mode) +{ + struct sahara_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + struct sahara_aes_reqctx *rctx = ablkcipher_request_ctx(req); + struct sahara_dev *dev = dev_ptr; + int err = 0; + int busy; + + dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n", + req->nbytes, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); + + if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { + dev_err(dev->device, + "request size is not exact amount of AES blocks\n"); + return -EINVAL; + } + + ctx->dev = dev; + + rctx->mode = mode; + spin_lock_bh(&dev->lock); + err = ablkcipher_enqueue_request(&dev->queue, req); + busy = test_and_set_bit(FLAGS_BUSY, &dev->flags); + spin_unlock_bh(&dev->lock); + + if (!busy) + tasklet_schedule(&dev->queue_task); + + return err; +} + +static int sahara_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + struct crypto_tfm *tfm = + crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req)); + struct sahara_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + int err; + + if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { + ablkcipher_request_set_tfm(req, ctx->fallback); + err = crypto_ablkcipher_encrypt(req); + ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); + return err; + } + + return sahara_aes_crypt(req, FLAGS_ENCRYPT); +} + +static int sahara_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + struct crypto_tfm *tfm = + crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req)); + struct sahara_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + int err; + + if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { + ablkcipher_request_set_tfm(req, ctx->fallback); + err = crypto_ablkcipher_decrypt(req); + ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); + return err; + } + + return sahara_aes_crypt(req, 0); +} + +static int sahara_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + struct crypto_tfm *tfm = + crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req)); + struct sahara_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + int err; + + if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { + ablkcipher_request_set_tfm(req, ctx->fallback); + err = crypto_ablkcipher_encrypt(req); + ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); + return err; + } + + return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); +} + +static int sahara_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + struct crypto_tfm *tfm = + crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req)); + struct sahara_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + int err; + + if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { + ablkcipher_request_set_tfm(req, ctx->fallback); + err = crypto_ablkcipher_decrypt(req); + ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm)); + return err; + } + + return sahara_aes_crypt(req, FLAGS_CBC); +} + +static int sahara_aes_cra_init(struct crypto_tfm *tfm) +{ + const char *name = tfm->__crt_alg->cra_name; + struct sahara_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->fallback = crypto_alloc_ablkcipher(name, 0, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback)) { + pr_err("Error allocating fallback algo %s\n", name); + return PTR_ERR(ctx->fallback); + } + + tfm->crt_ablkcipher.reqsize = sizeof(struct sahara_aes_reqctx); + + return 0; +} + +static void sahara_aes_cra_exit(struct crypto_tfm *tfm) +{ + struct sahara_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->fallback) + crypto_free_ablkcipher(ctx->fallback); + ctx->fallback = NULL; +} + +static struct crypto_alg aes_algs[] = { +{ + .cra_name = "ecb(aes)", + .cra_driver_name = "sahara-ecb-aes", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sahara_ctx), + .cra_alignmask = 0x0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sahara_aes_cra_init, + .cra_exit = sahara_aes_cra_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE , + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = sahara_aes_setkey, + .encrypt = sahara_aes_ecb_encrypt, + .decrypt = sahara_aes_ecb_decrypt, + } +}, { + .cra_name = "cbc(aes)", + .cra_driver_name = "sahara-cbc-aes", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sahara_ctx), + .cra_alignmask = 0x0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sahara_aes_cra_init, + .cra_exit = sahara_aes_cra_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE , + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = sahara_aes_setkey, + .encrypt = sahara_aes_cbc_encrypt, + .decrypt = sahara_aes_cbc_decrypt, + } +} +}; + +static irqreturn_t sahara_irq_handler(int irq, void *data) +{ + struct sahara_dev *dev = (struct sahara_dev *)data; + unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS); + unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS); + + del_timer(&dev->watchdog); + + sahara_write(dev, SAHARA_CMD_CLEAR_INT | SAHARA_CMD_CLEAR_ERR, + SAHARA_REG_CMD); + + sahara_decode_status(dev, stat); + + if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_BUSY) { + return IRQ_NONE; + } else if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_COMPLETE) { + dev->error = 0; + } else { + sahara_decode_error(dev, err); + dev->error = -EINVAL; + } + + tasklet_schedule(&dev->done_task); + + return IRQ_HANDLED; +} + + +static int sahara_register_algs(struct sahara_dev *dev) +{ + int err, i, j; + + for (i = 0; i < ARRAY_SIZE(aes_algs); i++) { + INIT_LIST_HEAD(&aes_algs[i].cra_list); + err = crypto_register_alg(&aes_algs[i]); + if (err) + goto err_aes_algs; + } + + return 0; + +err_aes_algs: + for (j = 0; j < i; j++) + crypto_unregister_alg(&aes_algs[j]); + + return err; +} + +static void sahara_unregister_algs(struct sahara_dev *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(aes_algs); i++) + crypto_unregister_alg(&aes_algs[i]); +} + +static struct platform_device_id sahara_platform_ids[] = { + { .name = "sahara-imx27" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, sahara_platform_ids); + +static struct of_device_id sahara_dt_ids[] = { + { .compatible = "fsl,imx27-sahara" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, sahara_dt_ids); + +static int sahara_probe(struct platform_device *pdev) +{ + struct sahara_dev *dev; + struct resource *res; + u32 version; + int irq; + int err; + int i; + + dev = devm_kzalloc(&pdev->dev, sizeof(struct sahara_dev), GFP_KERNEL); + if (dev == NULL) { + dev_err(&pdev->dev, "unable to alloc data struct.\n"); + return -ENOMEM; + } + + dev->device = &pdev->dev; + platform_set_drvdata(pdev, dev); + + /* Get the base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get memory region resource\n"); + return -ENODEV; + } + + if (devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), SAHARA_NAME) == NULL) { + dev_err(&pdev->dev, "failed to request memory region\n"); + return -ENOENT; + } + dev->regs_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!dev->regs_base) { + dev_err(&pdev->dev, "failed to ioremap address region\n"); + return -ENOENT; + } + + /* Get the IRQ */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "failed to get irq resource\n"); + return irq; + } + + if (devm_request_irq(&pdev->dev, irq, sahara_irq_handler, + 0, SAHARA_NAME, dev) < 0) { + dev_err(&pdev->dev, "failed to request irq\n"); + return -ENOENT; + } + + /* clocks */ + dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(dev->clk_ipg)) { + dev_err(&pdev->dev, "Could not get ipg clock\n"); + return PTR_ERR(dev->clk_ipg); + } + + dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); + if (IS_ERR(dev->clk_ahb)) { + dev_err(&pdev->dev, "Could not get ahb clock\n"); + return PTR_ERR(dev->clk_ahb); + } + + /* Allocate HW descriptors */ + dev->hw_desc[0] = dma_alloc_coherent(&pdev->dev, + SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc), + &dev->hw_phys_desc[0], GFP_KERNEL); + if (!dev->hw_desc[0]) { + dev_err(&pdev->dev, "Could not allocate hw descriptors\n"); + return -ENOMEM; + } + dev->hw_desc[1] = dev->hw_desc[0] + 1; + dev->hw_phys_desc[1] = dev->hw_phys_desc[0] + + sizeof(struct sahara_hw_desc); + + /* Allocate space for iv and key */ + dev->key_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, + &dev->key_phys_base, GFP_KERNEL); + if (!dev->key_base) { + dev_err(&pdev->dev, "Could not allocate memory for key\n"); + err = -ENOMEM; + goto err_key; + } + dev->iv_base = dev->key_base + AES_KEYSIZE_128; + dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128; + + /* Allocate space for HW links */ + dev->hw_link[0] = dma_alloc_coherent(&pdev->dev, + SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link), + &dev->hw_phys_link[0], GFP_KERNEL); + if (!dev->hw_link) { + dev_err(&pdev->dev, "Could not allocate hw links\n"); + err = -ENOMEM; + goto err_link; + } + for (i = 1; i < SAHARA_MAX_HW_LINK; i++) { + dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] + + sizeof(struct sahara_hw_link); + dev->hw_link[i] = dev->hw_link[i - 1] + 1; + } + + crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH); + + dev_ptr = dev; + + tasklet_init(&dev->queue_task, sahara_aes_queue_task, + (unsigned long)dev); + tasklet_init(&dev->done_task, sahara_aes_done_task, + (unsigned long)dev); + + init_timer(&dev->watchdog); + dev->watchdog.function = &sahara_watchdog; + dev->watchdog.data = (unsigned long)dev; + + clk_prepare_enable(dev->clk_ipg); + clk_prepare_enable(dev->clk_ahb); + + version = sahara_read(dev, SAHARA_REG_VERSION); + if (version != SAHARA_VERSION_3) { + dev_err(&pdev->dev, "SAHARA version %d not supported\n", + version); + err = -ENODEV; + goto err_algs; + } + + sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH, + SAHARA_REG_CMD); + sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) | + SAHARA_CONTROL_SET_MAXBURST(8) | + SAHARA_CONTROL_RNG_AUTORSD | + SAHARA_CONTROL_ENABLE_INT, + SAHARA_REG_CONTROL); + + err = sahara_register_algs(dev); + if (err) + goto err_algs; + + dev_info(&pdev->dev, "SAHARA version %d initialized\n", version); + + return 0; + +err_algs: + dma_free_coherent(&pdev->dev, + SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link), + dev->hw_link[0], dev->hw_phys_link[0]); + clk_disable_unprepare(dev->clk_ipg); + clk_disable_unprepare(dev->clk_ahb); + dev_ptr = NULL; +err_link: + dma_free_coherent(&pdev->dev, + 2 * AES_KEYSIZE_128, + dev->key_base, dev->key_phys_base); +err_key: + dma_free_coherent(&pdev->dev, + SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc), + dev->hw_desc[0], dev->hw_phys_desc[0]); + + return err; +} + +static int sahara_remove(struct platform_device *pdev) +{ + struct sahara_dev *dev = platform_get_drvdata(pdev); + + dma_free_coherent(&pdev->dev, + SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link), + dev->hw_link[0], dev->hw_phys_link[0]); + dma_free_coherent(&pdev->dev, + 2 * AES_KEYSIZE_128, + dev->key_base, dev->key_phys_base); + dma_free_coherent(&pdev->dev, + SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc), + dev->hw_desc[0], dev->hw_phys_desc[0]); + + tasklet_kill(&dev->done_task); + tasklet_kill(&dev->queue_task); + + sahara_unregister_algs(dev); + + clk_disable_unprepare(dev->clk_ipg); + clk_disable_unprepare(dev->clk_ahb); + + dev_ptr = NULL; + + return 0; +} + +static struct platform_driver sahara_driver = { + .probe = sahara_probe, + .remove = sahara_remove, + .driver = { + .name = SAHARA_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(sahara_dt_ids), + }, + .id_table = sahara_platform_ids, +}; + +module_platform_driver(sahara_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Javier Martin "); +MODULE_DESCRIPTION("SAHARA2 HW crypto accelerator"); -- cgit From 1643a35fea3300c7df63c91596d3246c05b43a76 Mon Sep 17 00:00:00 2001 From: Mihnea Dobrescu-Balaur Date: Mon, 11 Mar 2013 12:48:10 +0200 Subject: crypto: ux500 - replace kmalloc and then memcpy with kmemdup Signed-off-by: Mihnea Dobrescu-Balaur Signed-off-by: Herbert Xu --- drivers/crypto/ux500/hash/hash_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 632c3339895f..8d16d3aa7650 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1368,14 +1368,12 @@ static int hash_setkey(struct crypto_ahash *tfm, /** * Freed in final. */ - ctx->key = kmalloc(keylen, GFP_KERNEL); + ctx->key = kmemdup(key, keylen, GFP_KERNEL); if (!ctx->key) { pr_err(DEV_DBG_NAME " [%s] Failed to allocate ctx->key " "for %d\n", __func__, alg); return -ENOMEM; } - - memcpy(ctx->key, key, keylen); ctx->keylen = keylen; return ret; -- cgit From f82757d912b916348976c464ddc80539d89c851d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 07:09:54 -0300 Subject: [media] siano: Change GPIO voltage setting names Siano changed the namespace on more recent API, and re-used some of the old names. In order to be able to update the API to support newer chips, the better is to follow this change. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.c | 2 +- drivers/media/common/siano/smscoreapi.c | 8 ++++---- drivers/media/common/siano/smscoreapi.h | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index 680c781c8dd6..8ee2e92b9b1a 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c @@ -183,7 +183,7 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST, - .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA, + .outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA, }; if (pin == 0) diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 9565dcc8381f..3b2fc872ca0b 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1305,16 +1305,16 @@ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0; switch (pinconfig->outputdriving) { - case SMS_GPIO_OUTPUTDRIVING_16mA: + case SMS_GPIO_OUTPUTDRIVING_S_16mA: msg.data[3] = 7; /* Nova - 16mA */ break; - case SMS_GPIO_OUTPUTDRIVING_12mA: + case SMS_GPIO_OUTPUTDRIVING_S_12mA: msg.data[3] = 5; /* Nova - 11mA */ break; - case SMS_GPIO_OUTPUTDRIVING_8mA: + case SMS_GPIO_OUTPUTDRIVING_S_8mA: msg.data[3] = 3; /* Nova - 7mA */ break; - case SMS_GPIO_OUTPUTDRIVING_4mA: + case SMS_GPIO_OUTPUTDRIVING_S_4mA: default: msg.data[3] = 2; /* Nova - 4mA */ break; diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index c592ae090397..a6d29a2426a1 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -642,10 +642,10 @@ struct smscore_config_gpio { #define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 u8 outputslewrate; -#define SMS_GPIO_OUTPUTDRIVING_4mA 0 -#define SMS_GPIO_OUTPUTDRIVING_8mA 1 -#define SMS_GPIO_OUTPUTDRIVING_12mA 2 -#define SMS_GPIO_OUTPUTDRIVING_16mA 3 +#define SMS_GPIO_OUTPUTDRIVING_S_4mA 0 +#define SMS_GPIO_OUTPUTDRIVING_S_8mA 1 +#define SMS_GPIO_OUTPUTDRIVING_S_12mA 2 +#define SMS_GPIO_OUTPUTDRIVING_S_16mA 3 u8 outputdriving; }; -- cgit From 739a8c91a39cd2bc3fce23ab4368816150fcf27a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 07:14:51 -0300 Subject: [media] siano: Add the new voltage definitions for GPIO Those new definitions came from this patch, from Doron Cohen: http://patchwork.linuxtv.org/patch/7882/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index a6d29a2426a1..62f05e89da0e 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -642,10 +642,22 @@ struct smscore_config_gpio { #define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 u8 outputslewrate; + /* 10xx */ #define SMS_GPIO_OUTPUTDRIVING_S_4mA 0 #define SMS_GPIO_OUTPUTDRIVING_S_8mA 1 #define SMS_GPIO_OUTPUTDRIVING_S_12mA 2 #define SMS_GPIO_OUTPUTDRIVING_S_16mA 3 + + /* 11xx*/ +#define SMS_GPIO_OUTPUTDRIVING_1_5mA 0 +#define SMS_GPIO_OUTPUTDRIVING_2_8mA 1 +#define SMS_GPIO_OUTPUTDRIVING_4mA 2 +#define SMS_GPIO_OUTPUTDRIVING_7mA 3 +#define SMS_GPIO_OUTPUTDRIVING_10mA 4 +#define SMS_GPIO_OUTPUTDRIVING_11mA 5 +#define SMS_GPIO_OUTPUTDRIVING_14mA 6 +#define SMS_GPIO_OUTPUTDRIVING_16mA 7 + u8 outputdriving; }; -- cgit From c31b9fb26069d0beedb3125a4ff3c1d0f8051d26 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 08:30:08 -0300 Subject: [media] siano: remove a duplicated structure definition The same GPIO config struct was declared twice at the driver, with different names and different macros: struct smscore_config_gpio struct smscore_config_gpio Remove the one that uses CamelCase and fix the references to its attributes/macros. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.c | 18 +++++------ drivers/media/common/siano/smscoreapi.c | 20 ++++++------ drivers/media/common/siano/smscoreapi.h | 55 +++++++-------------------------- 3 files changed, 30 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index 8ee2e92b9b1a..b22b61dbc0e2 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c @@ -109,18 +109,18 @@ struct sms_board *sms_get_board(unsigned id) } EXPORT_SYMBOL_GPL(sms_get_board); static inline void sms_gpio_assign_11xx_default_led_config( - struct smscore_gpio_config *pGpioConfig) { - pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT; - pGpioConfig->InputCharacteristics = - SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL; - pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA; - pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; - pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE; + struct smscore_config_gpio *pGpioConfig) { + pGpioConfig->direction = SMS_GPIO_DIRECTION_OUTPUT; + pGpioConfig->inputcharacteristics = + SMS_GPIO_INPUTCHARACTERISTICS_NORMAL; + pGpioConfig->outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA; + pGpioConfig->outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; + pGpioConfig->pullupdown = SMS_GPIO_PULLUPDOWN_NONE; } int sms_board_event(struct smscore_device_t *coredev, enum SMS_BOARD_EVENTS gevent) { - struct smscore_gpio_config MyGpioConfig; + struct smscore_config_gpio MyGpioConfig; sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); @@ -182,7 +182,7 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) .direction = SMS_GPIO_DIRECTION_OUTPUT, .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, - .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST, + .outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_FAST, .outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA, }; diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 3b2fc872ca0b..804eb32fd8cc 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1405,7 +1405,7 @@ static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, } int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, - struct smscore_gpio_config *pGpioConfig) { + struct smscore_config_gpio *pGpioConfig) { u32 totalLen; u32 TranslatedPinNum = 0; @@ -1452,19 +1452,19 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, pMsg->msgData[1] = TranslatedPinNum; pMsg->msgData[2] = GroupNum; - ElectricChar = (pGpioConfig->PullUpDown) - | (pGpioConfig->InputCharacteristics << 2) - | (pGpioConfig->OutputSlewRate << 3) - | (pGpioConfig->OutputDriving << 4); + ElectricChar = (pGpioConfig->pullupdown) + | (pGpioConfig->inputcharacteristics << 2) + | (pGpioConfig->outputslewrate << 3) + | (pGpioConfig->outputdriving << 4); pMsg->msgData[3] = ElectricChar; - pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[4] = pGpioConfig->direction; pMsg->msgData[5] = groupCfg; } else { pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; - pMsg->msgData[1] = pGpioConfig->PullUpDown; - pMsg->msgData[2] = pGpioConfig->OutputSlewRate; - pMsg->msgData[3] = pGpioConfig->OutputDriving; - pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[1] = pGpioConfig->pullupdown; + pMsg->msgData[2] = pGpioConfig->outputslewrate; + pMsg->msgData[3] = pGpioConfig->outputdriving; + pMsg->msgData[4] = pGpioConfig->direction; pMsg->msgData[5] = 0; } diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 62f05e89da0e..f2510f50d1fe 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -638,8 +638,16 @@ struct smscore_config_gpio { #define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1 u8 inputcharacteristics; -#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0 -#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 + /* 10xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 +#define SMS_GPIO_OUTPUT_SLEW_WRATE_SLOW 1 + + /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 +#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 +#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 + u8 outputslewrate; /* 10xx */ @@ -661,47 +669,6 @@ struct smscore_config_gpio { u8 outputdriving; }; -struct smscore_gpio_config { -#define SMS_GPIO_DIRECTION_INPUT 0 -#define SMS_GPIO_DIRECTION_OUTPUT 1 - u8 Direction; - -#define SMS_GPIO_PULL_UP_DOWN_NONE 0 -#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 -#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 -#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 - u8 PullUpDown; - -#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 -#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 - u8 InputCharacteristics; - -#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ - - -#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ -#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ - u8 OutputSlewRate; - -#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ -#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ - -#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ -#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ - u8 OutputDriving; -}; - extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -750,7 +717,7 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); /* new GPIO management */ extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, - struct smscore_gpio_config *pGpioConfig); + struct smscore_config_gpio *pGpioConfig); extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, u8 NewLevel); extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, -- cgit From f251001c8086c8388aa7635b9fcd908b444e139c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 07:16:19 -0300 Subject: [media] siano: update message macros Convert from #define into an enum and add the newer message macros as found on this patch from Doron Cohen: http://patchwork.linuxtv.org/patch/7882/ No messages got supressed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.h | 374 +++++++++++++++++++++++++++----- 1 file changed, 321 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index f2510f50d1fe..4a0a7639319d 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -194,59 +194,327 @@ struct smscore_device_t { #define SMS_MAX_PAYLOAD_SIZE 240 #define SMS_TUNE_TIMEOUT 500 -#define MSG_SMS_GPIO_CONFIG_REQ 507 -#define MSG_SMS_GPIO_CONFIG_RES 508 -#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 -#define MSG_SMS_GPIO_SET_LEVEL_RES 510 -#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 -#define MSG_SMS_GPIO_GET_LEVEL_RES 512 -#define MSG_SMS_RF_TUNE_REQ 561 -#define MSG_SMS_RF_TUNE_RES 562 -#define MSG_SMS_INIT_DEVICE_REQ 578 -#define MSG_SMS_INIT_DEVICE_RES 579 -#define MSG_SMS_ADD_PID_FILTER_REQ 601 -#define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_RES 616 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_HO_PER_SLICES_IND 630 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 -#define MSG_SMS_DATA_DOWNLOAD_REQ 660 -#define MSG_SMS_DATA_DOWNLOAD_RES 661 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 -#define MSG_SMS_GET_VERSION_EX_REQ 668 -#define MSG_SMS_GET_VERSION_EX_RES 669 -#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 -#define MSG_SMS_I2C_SET_FREQ_REQ 685 -#define MSG_SMS_GENERIC_I2C_REQ 687 -#define MSG_SMS_GENERIC_I2C_RES 688 -#define MSG_SMS_DVBT_BDA_DATA 693 -#define MSG_SW_RELOAD_REQ 697 -#define MSG_SMS_DATA_MSG 699 -#define MSG_SW_RELOAD_START_REQ 702 -#define MSG_SW_RELOAD_START_RES 703 -#define MSG_SW_RELOAD_EXEC_REQ 704 -#define MSG_SW_RELOAD_EXEC_RES 705 -#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 -#define MSG_SMS_GPIO_CONFIG_EX_REQ 712 -#define MSG_SMS_GPIO_CONFIG_EX_RES 713 -#define MSG_SMS_ISDBT_TUNE_REQ 776 -#define MSG_SMS_ISDBT_TUNE_RES 777 -#define MSG_SMS_TRANSMISSION_IND 782 -#define MSG_SMS_START_IR_REQ 800 -#define MSG_SMS_START_IR_RES 801 -#define MSG_SMS_IR_SAMPLES_IND 802 -#define MSG_SMS_SIGNAL_DETECTED_IND 827 -#define MSG_SMS_NO_SIGNAL_IND 828 +enum msg_types { + MSG_TYPE_BASE_VAL = 500, + MSG_SMS_GET_VERSION_REQ = 503, + MSG_SMS_GET_VERSION_RES = 504, + MSG_SMS_MULTI_BRIDGE_CFG = 505, + MSG_SMS_GPIO_CONFIG_REQ = 507, + MSG_SMS_GPIO_CONFIG_RES = 508, + MSG_SMS_GPIO_SET_LEVEL_REQ = 509, + MSG_SMS_GPIO_SET_LEVEL_RES = 510, + MSG_SMS_GPIO_GET_LEVEL_REQ = 511, + MSG_SMS_GPIO_GET_LEVEL_RES = 512, + MSG_SMS_EEPROM_BURN_IND = 513, + MSG_SMS_LOG_ENABLE_CHANGE_REQ = 514, + MSG_SMS_LOG_ENABLE_CHANGE_RES = 515, + MSG_SMS_SET_MAX_TX_MSG_LEN_REQ = 516, + MSG_SMS_SET_MAX_TX_MSG_LEN_RES = 517, + MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE = 518, + MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST = 519, + MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ = 520, + MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES = 521, + MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND = 522, + MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND = 523, + MSG_SMS_CONFIGURE_RF_SWITCH_REQ = 524, + MSG_SMS_CONFIGURE_RF_SWITCH_RES = 525, + MSG_SMS_MRC_PATH_DISCONNECT_REQ = 526, + MSG_SMS_MRC_PATH_DISCONNECT_RES = 527, + MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ = 528, + MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES = 529, + MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ = 530, + MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES = 531, + MSG_WR_REG_RFT_REQ = 533, + MSG_WR_REG_RFT_RES = 534, + MSG_RD_REG_RFT_REQ = 535, + MSG_RD_REG_RFT_RES = 536, + MSG_RD_REG_ALL_RFT_REQ = 537, + MSG_RD_REG_ALL_RFT_RES = 538, + MSG_HELP_INT = 539, + MSG_RUN_SCRIPT_INT = 540, + MSG_SMS_EWS_INBAND_REQ = 541, + MSG_SMS_EWS_INBAND_RES = 542, + MSG_SMS_RFS_SELECT_REQ = 543, + MSG_SMS_RFS_SELECT_RES = 544, + MSG_SMS_MB_GET_VER_REQ = 545, + MSG_SMS_MB_GET_VER_RES = 546, + MSG_SMS_MB_WRITE_CFGFILE_REQ = 547, + MSG_SMS_MB_WRITE_CFGFILE_RES = 548, + MSG_SMS_MB_READ_CFGFILE_REQ = 549, + MSG_SMS_MB_READ_CFGFILE_RES = 550, + MSG_SMS_RD_MEM_REQ = 552, + MSG_SMS_RD_MEM_RES = 553, + MSG_SMS_WR_MEM_REQ = 554, + MSG_SMS_WR_MEM_RES = 555, + MSG_SMS_UPDATE_MEM_REQ = 556, + MSG_SMS_UPDATE_MEM_RES = 557, + MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ = 558, + MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES = 559, + MSG_SMS_RF_TUNE_REQ = 561, + MSG_SMS_RF_TUNE_RES = 562, + MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ = 563, + MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES = 564, + MSG_SMS_ISDBT_SB_RECEPTION_REQ = 565, + MSG_SMS_ISDBT_SB_RECEPTION_RES = 566, + MSG_SMS_GENERIC_EPROM_WRITE_REQ = 567, + MSG_SMS_GENERIC_EPROM_WRITE_RES = 568, + MSG_SMS_GENERIC_EPROM_READ_REQ = 569, + MSG_SMS_GENERIC_EPROM_READ_RES = 570, + MSG_SMS_EEPROM_WRITE_REQ = 571, + MSG_SMS_EEPROM_WRITE_RES = 572, + MSG_SMS_CUSTOM_READ_REQ = 574, + MSG_SMS_CUSTOM_READ_RES = 575, + MSG_SMS_CUSTOM_WRITE_REQ = 576, + MSG_SMS_CUSTOM_WRITE_RES = 577, + MSG_SMS_INIT_DEVICE_REQ = 578, + MSG_SMS_INIT_DEVICE_RES = 579, + MSG_SMS_ATSC_SET_ALL_IP_REQ = 580, + MSG_SMS_ATSC_SET_ALL_IP_RES = 581, + MSG_SMS_ATSC_START_ENSEMBLE_REQ = 582, + MSG_SMS_ATSC_START_ENSEMBLE_RES = 583, + MSG_SMS_SET_OUTPUT_MODE_REQ = 584, + MSG_SMS_SET_OUTPUT_MODE_RES = 585, + MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ = 586, + MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES = 587, + MSG_SMS_SUB_CHANNEL_START_REQ = 589, + MSG_SMS_SUB_CHANNEL_START_RES = 590, + MSG_SMS_SUB_CHANNEL_STOP_REQ = 591, + MSG_SMS_SUB_CHANNEL_STOP_RES = 592, + MSG_SMS_ATSC_IP_FILTER_ADD_REQ = 593, + MSG_SMS_ATSC_IP_FILTER_ADD_RES = 594, + MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ = 595, + MSG_SMS_ATSC_IP_FILTER_REMOVE_RES = 596, + MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ = 597, + MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES = 598, + MSG_SMS_WAIT_CMD = 599, + MSG_SMS_ADD_PID_FILTER_REQ = 601, + MSG_SMS_ADD_PID_FILTER_RES = 602, + MSG_SMS_REMOVE_PID_FILTER_REQ = 603, + MSG_SMS_REMOVE_PID_FILTER_RES = 604, + MSG_SMS_FAST_INFORMATION_CHANNEL_REQ = 605, + MSG_SMS_FAST_INFORMATION_CHANNEL_RES = 606, + MSG_SMS_DAB_CHANNEL = 607, + MSG_SMS_GET_PID_FILTER_LIST_REQ = 608, + MSG_SMS_GET_PID_FILTER_LIST_RES = 609, + MSG_SMS_POWER_DOWN_REQ = 610, + MSG_SMS_POWER_DOWN_RES = 611, + MSG_SMS_ATSC_SLT_EXIST_IND = 612, + MSG_SMS_ATSC_NO_SLT_IND = 613, + MSG_SMS_GET_STATISTICS_REQ = 615, + MSG_SMS_GET_STATISTICS_RES = 616, + MSG_SMS_SEND_DUMP = 617, + MSG_SMS_SCAN_START_REQ = 618, + MSG_SMS_SCAN_START_RES = 619, + MSG_SMS_SCAN_STOP_REQ = 620, + MSG_SMS_SCAN_STOP_RES = 621, + MSG_SMS_SCAN_PROGRESS_IND = 622, + MSG_SMS_SCAN_COMPLETE_IND = 623, + MSG_SMS_LOG_ITEM = 624, + MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ = 628, + MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES = 629, + MSG_SMS_HO_PER_SLICES_IND = 630, + MSG_SMS_HO_INBAND_POWER_IND = 631, + MSG_SMS_MANUAL_DEMOD_REQ = 632, + MSG_SMS_HO_TUNE_ON_REQ = 636, + MSG_SMS_HO_TUNE_ON_RES = 637, + MSG_SMS_HO_TUNE_OFF_REQ = 638, + MSG_SMS_HO_TUNE_OFF_RES = 639, + MSG_SMS_HO_PEEK_FREQ_REQ = 640, + MSG_SMS_HO_PEEK_FREQ_RES = 641, + MSG_SMS_HO_PEEK_FREQ_IND = 642, + MSG_SMS_MB_ATTEN_SET_REQ = 643, + MSG_SMS_MB_ATTEN_SET_RES = 644, + MSG_SMS_ENABLE_STAT_IN_I2C_REQ = 649, + MSG_SMS_ENABLE_STAT_IN_I2C_RES = 650, + MSG_SMS_SET_ANTENNA_CONFIG_REQ = 651, + MSG_SMS_SET_ANTENNA_CONFIG_RES = 652, + MSG_SMS_GET_STATISTICS_EX_REQ = 653, + MSG_SMS_GET_STATISTICS_EX_RES = 654, + MSG_SMS_SLEEP_RESUME_COMP_IND = 655, + MSG_SMS_SWITCH_HOST_INTERFACE_REQ = 656, + MSG_SMS_SWITCH_HOST_INTERFACE_RES = 657, + MSG_SMS_DATA_DOWNLOAD_REQ = 660, + MSG_SMS_DATA_DOWNLOAD_RES = 661, + MSG_SMS_DATA_VALIDITY_REQ = 662, + MSG_SMS_DATA_VALIDITY_RES = 663, + MSG_SMS_SWDOWNLOAD_TRIGGER_REQ = 664, + MSG_SMS_SWDOWNLOAD_TRIGGER_RES = 665, + MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ = 666, + MSG_SMS_SWDOWNLOAD_BACKDOOR_RES = 667, + MSG_SMS_GET_VERSION_EX_REQ = 668, + MSG_SMS_GET_VERSION_EX_RES = 669, + MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ = 670, + MSG_SMS_CLOCK_OUTPUT_CONFIG_RES = 671, + MSG_SMS_I2C_SET_FREQ_REQ = 685, + MSG_SMS_I2C_SET_FREQ_RES = 686, + MSG_SMS_GENERIC_I2C_REQ = 687, + MSG_SMS_GENERIC_I2C_RES = 688, + MSG_SMS_DVBT_BDA_DATA = 693, + MSG_SW_RELOAD_REQ = 697, + MSG_SMS_DATA_MSG = 699, + MSG_TABLE_UPLOAD_REQ = 700, + MSG_TABLE_UPLOAD_RES = 701, + MSG_SW_RELOAD_START_REQ = 702, + MSG_SW_RELOAD_START_RES = 703, + MSG_SW_RELOAD_EXEC_REQ = 704, + MSG_SW_RELOAD_EXEC_RES = 705, + MSG_SMS_SPI_INT_LINE_SET_REQ = 710, + MSG_SMS_SPI_INT_LINE_SET_RES = 711, + MSG_SMS_GPIO_CONFIG_EX_REQ = 712, + MSG_SMS_GPIO_CONFIG_EX_RES = 713, + MSG_SMS_WATCHDOG_ACT_REQ = 716, + MSG_SMS_WATCHDOG_ACT_RES = 717, + MSG_SMS_LOOPBACK_REQ = 718, + MSG_SMS_LOOPBACK_RES = 719, + MSG_SMS_RAW_CAPTURE_START_REQ = 720, + MSG_SMS_RAW_CAPTURE_START_RES = 721, + MSG_SMS_RAW_CAPTURE_ABORT_REQ = 722, + MSG_SMS_RAW_CAPTURE_ABORT_RES = 723, + MSG_SMS_RAW_CAPTURE_COMPLETE_IND = 728, + MSG_SMS_DATA_PUMP_IND = 729, + MSG_SMS_DATA_PUMP_REQ = 730, + MSG_SMS_DATA_PUMP_RES = 731, + MSG_SMS_FLASH_DL_REQ = 732, + MSG_SMS_EXEC_TEST_1_REQ = 734, + MSG_SMS_EXEC_TEST_1_RES = 735, + MSG_SMS_ENBALE_TS_INTERFACE_REQ = 736, + MSG_SMS_ENBALE_TS_INTERFACE_RES = 737, + MSG_SMS_SPI_SET_BUS_WIDTH_REQ = 738, + MSG_SMS_SPI_SET_BUS_WIDTH_RES = 739, + MSG_SMS_SEND_EMM_REQ = 740, + MSG_SMS_SEND_EMM_RES = 741, + MSG_SMS_DISABLE_TS_INTERFACE_REQ = 742, + MSG_SMS_DISABLE_TS_INTERFACE_RES = 743, + MSG_SMS_IS_BUF_FREE_REQ = 744, + MSG_SMS_IS_BUF_FREE_RES = 745, + MSG_SMS_EXT_ANTENNA_REQ = 746, + MSG_SMS_EXT_ANTENNA_RES = 747, + MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE = 748, + MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE = 749, + MSG_SMS_BATTERY_LEVEL_REQ = 750, + MSG_SMS_BATTERY_LEVEL_RES = 751, + MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE = 752, + MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE = 753, + MSG_SMS_FM_RADIO_BLOCK_IND = 754, + MSG_SMS_HOST_NOTIFICATION_IND = 755, + MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE = 756, + MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE = 757, + MSG_SMS_CMMB_GET_NETWORKS_REQ = 760, + MSG_SMS_CMMB_GET_NETWORKS_RES = 761, + MSG_SMS_CMMB_START_SERVICE_REQ = 762, + MSG_SMS_CMMB_START_SERVICE_RES = 763, + MSG_SMS_CMMB_STOP_SERVICE_REQ = 764, + MSG_SMS_CMMB_STOP_SERVICE_RES = 765, + MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ = 768, + MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES = 769, + MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ = 770, + MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES = 771, + MSG_SMS_CMMB_START_CONTROL_INFO_REQ = 772, + MSG_SMS_CMMB_START_CONTROL_INFO_RES = 773, + MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ = 774, + MSG_SMS_CMMB_STOP_CONTROL_INFO_RES = 775, + MSG_SMS_ISDBT_TUNE_REQ = 776, + MSG_SMS_ISDBT_TUNE_RES = 777, + MSG_SMS_TRANSMISSION_IND = 782, + MSG_SMS_PID_STATISTICS_IND = 783, + MSG_SMS_POWER_DOWN_IND = 784, + MSG_SMS_POWER_DOWN_CONF = 785, + MSG_SMS_POWER_UP_IND = 786, + MSG_SMS_POWER_UP_CONF = 787, + MSG_SMS_POWER_MODE_SET_REQ = 790, + MSG_SMS_POWER_MODE_SET_RES = 791, + MSG_SMS_DEBUG_HOST_EVENT_REQ = 792, + MSG_SMS_DEBUG_HOST_EVENT_RES = 793, + MSG_SMS_NEW_CRYSTAL_REQ = 794, + MSG_SMS_NEW_CRYSTAL_RES = 795, + MSG_SMS_CONFIG_SPI_REQ = 796, + MSG_SMS_CONFIG_SPI_RES = 797, + MSG_SMS_I2C_SHORT_STAT_IND = 798, + MSG_SMS_START_IR_REQ = 800, + MSG_SMS_START_IR_RES = 801, + MSG_SMS_IR_SAMPLES_IND = 802, + MSG_SMS_CMMB_CA_SERVICE_IND = 803, + MSG_SMS_SLAVE_DEVICE_DETECTED = 804, + MSG_SMS_INTERFACE_LOCK_IND = 805, + MSG_SMS_INTERFACE_UNLOCK_IND = 806, + MSG_SMS_SEND_ROSUM_BUFF_REQ = 810, + MSG_SMS_SEND_ROSUM_BUFF_RES = 811, + MSG_SMS_ROSUM_BUFF = 812, + MSG_SMS_SET_AES128_KEY_REQ = 815, + MSG_SMS_SET_AES128_KEY_RES = 816, + MSG_SMS_MBBMS_WRITE_REQ = 817, + MSG_SMS_MBBMS_WRITE_RES = 818, + MSG_SMS_MBBMS_READ_IND = 819, + MSG_SMS_IQ_STREAM_START_REQ = 820, + MSG_SMS_IQ_STREAM_START_RES = 821, + MSG_SMS_IQ_STREAM_STOP_REQ = 822, + MSG_SMS_IQ_STREAM_STOP_RES = 823, + MSG_SMS_IQ_STREAM_DATA_BLOCK = 824, + MSG_SMS_GET_EEPROM_VERSION_REQ = 825, + MSG_SMS_GET_EEPROM_VERSION_RES = 826, + MSG_SMS_SIGNAL_DETECTED_IND = 827, + MSG_SMS_NO_SIGNAL_IND = 828, + MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ = 830, + MSG_SMS_MRC_SHUTDOWN_SLAVE_RES = 831, + MSG_SMS_MRC_BRINGUP_SLAVE_REQ = 832, + MSG_SMS_MRC_BRINGUP_SLAVE_RES = 833, + MSG_SMS_EXTERNAL_LNA_CTRL_REQ = 834, + MSG_SMS_EXTERNAL_LNA_CTRL_RES = 835, + MSG_SMS_SET_PERIODIC_STATISTICS_REQ = 836, + MSG_SMS_SET_PERIODIC_STATISTICS_RES = 837, + MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ = 838, + MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES = 839, + LOCAL_TUNE = 850, + LOCAL_IFFT_H_ICI = 851, + MSG_RESYNC_REQ = 852, + MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ = 853, + MSG_SMS_CMMB_GET_MRC_STATISTICS_RES = 854, + MSG_SMS_LOG_EX_ITEM = 855, + MSG_SMS_DEVICE_DATA_LOSS_IND = 856, + MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND = 857, + MSG_SMS_USER_MSG_REQ = 858, + MSG_SMS_USER_MSG_RES = 859, + MSG_SMS_SMART_CARD_INIT_REQ = 860, + MSG_SMS_SMART_CARD_INIT_RES = 861, + MSG_SMS_SMART_CARD_WRITE_REQ = 862, + MSG_SMS_SMART_CARD_WRITE_RES = 863, + MSG_SMS_SMART_CARD_READ_IND = 864, + MSG_SMS_TSE_ENABLE_REQ = 866, + MSG_SMS_TSE_ENABLE_RES = 867, + MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ = 868, + MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES = 869, + MSG_SMS_LED_CONFIG_REQ = 870, + MSG_SMS_LED_CONFIG_RES = 871, + MSG_PWM_ANTENNA_REQ = 872, + MSG_PWM_ANTENNA_RES = 873, + MSG_SMS_CMMB_SMD_SN_REQ = 874, + MSG_SMS_CMMB_SMD_SN_RES = 875, + MSG_SMS_CMMB_SET_CA_CW_REQ = 876, + MSG_SMS_CMMB_SET_CA_CW_RES = 877, + MSG_SMS_CMMB_SET_CA_SALT_REQ = 878, + MSG_SMS_CMMB_SET_CA_SALT_RES = 879, + MSG_SMS_NSCD_INIT_REQ = 880, + MSG_SMS_NSCD_INIT_RES = 881, + MSG_SMS_NSCD_PROCESS_SECTION_REQ = 882, + MSG_SMS_NSCD_PROCESS_SECTION_RES = 883, + MSG_SMS_DBD_CREATE_OBJECT_REQ = 884, + MSG_SMS_DBD_CREATE_OBJECT_RES = 885, + MSG_SMS_DBD_CONFIGURE_REQ = 886, + MSG_SMS_DBD_CONFIGURE_RES = 887, + MSG_SMS_DBD_SET_KEYS_REQ = 888, + MSG_SMS_DBD_SET_KEYS_RES = 889, + MSG_SMS_DBD_PROCESS_HEADER_REQ = 890, + MSG_SMS_DBD_PROCESS_HEADER_RES = 891, + MSG_SMS_DBD_PROCESS_DATA_REQ = 892, + MSG_SMS_DBD_PROCESS_DATA_RES = 893, + MSG_SMS_DBD_PROCESS_GET_DATA_REQ = 894, + MSG_SMS_DBD_PROCESS_GET_DATA_RES = 895, + MSG_SMS_NSCD_OPEN_SESSION_REQ = 896, + MSG_SMS_NSCD_OPEN_SESSION_RES = 897, + MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ = 898, + MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES = 899, + MSG_LAST_MSG_TYPE = 900, +}; #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ -- cgit From 4c3bdb5e2f5612ceb99ac17dbbe673b59a94d105 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 09:27:39 -0300 Subject: [media] siano: better debug send/receive messages Instead of printing a message for some random messages, print it for all sent/received ones. That helps a lot to debug what's going on. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 351 +++++++++++++++++++++++++++++++- drivers/media/common/siano/smscoreapi.h | 2 + drivers/media/common/siano/smsdvb.c | 10 +- drivers/media/usb/siano/smsusb.c | 9 + 4 files changed, 354 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 804eb32fd8cc..bc15dcecb25d 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -63,6 +63,345 @@ struct smscore_client_t { onremove_t onremove_handler; }; +static char *siano_msgs[] = { + [MSG_TYPE_BASE_VAL - MSG_TYPE_BASE_VAL] = "MSG_TYPE_BASE_VAL", + [MSG_SMS_GET_VERSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_REQ", + [MSG_SMS_GET_VERSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_RES", + [MSG_SMS_MULTI_BRIDGE_CFG - MSG_TYPE_BASE_VAL] = "MSG_SMS_MULTI_BRIDGE_CFG", + [MSG_SMS_GPIO_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_REQ", + [MSG_SMS_GPIO_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_RES", + [MSG_SMS_GPIO_SET_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_REQ", + [MSG_SMS_GPIO_SET_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_RES", + [MSG_SMS_GPIO_GET_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_REQ", + [MSG_SMS_GPIO_GET_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_RES", + [MSG_SMS_EEPROM_BURN_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_BURN_IND", + [MSG_SMS_LOG_ENABLE_CHANGE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_REQ", + [MSG_SMS_LOG_ENABLE_CHANGE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_RES", + [MSG_SMS_SET_MAX_TX_MSG_LEN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_REQ", + [MSG_SMS_SET_MAX_TX_MSG_LEN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_RES", + [MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE", + [MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST", + [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ", + [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES", + [MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND", + [MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND", + [MSG_SMS_CONFIGURE_RF_SWITCH_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_REQ", + [MSG_SMS_CONFIGURE_RF_SWITCH_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_RES", + [MSG_SMS_MRC_PATH_DISCONNECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_REQ", + [MSG_SMS_MRC_PATH_DISCONNECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_RES", + [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ", + [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES", + [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ", + [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES", + [MSG_WR_REG_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_REQ", + [MSG_WR_REG_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_RES", + [MSG_RD_REG_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_REQ", + [MSG_RD_REG_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_RES", + [MSG_RD_REG_ALL_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_REQ", + [MSG_RD_REG_ALL_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_RES", + [MSG_HELP_INT - MSG_TYPE_BASE_VAL] = "MSG_HELP_INT", + [MSG_RUN_SCRIPT_INT - MSG_TYPE_BASE_VAL] = "MSG_RUN_SCRIPT_INT", + [MSG_SMS_EWS_INBAND_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_REQ", + [MSG_SMS_EWS_INBAND_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_RES", + [MSG_SMS_RFS_SELECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_REQ", + [MSG_SMS_RFS_SELECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_RES", + [MSG_SMS_MB_GET_VER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_REQ", + [MSG_SMS_MB_GET_VER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_RES", + [MSG_SMS_MB_WRITE_CFGFILE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_REQ", + [MSG_SMS_MB_WRITE_CFGFILE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_RES", + [MSG_SMS_MB_READ_CFGFILE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_REQ", + [MSG_SMS_MB_READ_CFGFILE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_RES", + [MSG_SMS_RD_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_REQ", + [MSG_SMS_RD_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_RES", + [MSG_SMS_WR_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_REQ", + [MSG_SMS_WR_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_RES", + [MSG_SMS_UPDATE_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_REQ", + [MSG_SMS_UPDATE_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_RES", + [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ", + [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES", + [MSG_SMS_RF_TUNE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_REQ", + [MSG_SMS_RF_TUNE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_RES", + [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ", + [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES", + [MSG_SMS_ISDBT_SB_RECEPTION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_REQ", + [MSG_SMS_ISDBT_SB_RECEPTION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_RES", + [MSG_SMS_GENERIC_EPROM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_REQ", + [MSG_SMS_GENERIC_EPROM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_RES", + [MSG_SMS_GENERIC_EPROM_READ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_REQ", + [MSG_SMS_GENERIC_EPROM_READ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_RES", + [MSG_SMS_EEPROM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_REQ", + [MSG_SMS_EEPROM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_RES", + [MSG_SMS_CUSTOM_READ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_REQ", + [MSG_SMS_CUSTOM_READ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_RES", + [MSG_SMS_CUSTOM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_REQ", + [MSG_SMS_CUSTOM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_RES", + [MSG_SMS_INIT_DEVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_REQ", + [MSG_SMS_INIT_DEVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_RES", + [MSG_SMS_ATSC_SET_ALL_IP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_REQ", + [MSG_SMS_ATSC_SET_ALL_IP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_RES", + [MSG_SMS_ATSC_START_ENSEMBLE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_REQ", + [MSG_SMS_ATSC_START_ENSEMBLE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_RES", + [MSG_SMS_SET_OUTPUT_MODE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_REQ", + [MSG_SMS_SET_OUTPUT_MODE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_RES", + [MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ", + [MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES", + [MSG_SMS_SUB_CHANNEL_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_REQ", + [MSG_SMS_SUB_CHANNEL_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_RES", + [MSG_SMS_SUB_CHANNEL_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_REQ", + [MSG_SMS_SUB_CHANNEL_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_RES", + [MSG_SMS_ATSC_IP_FILTER_ADD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_REQ", + [MSG_SMS_ATSC_IP_FILTER_ADD_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_RES", + [MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ", + [MSG_SMS_ATSC_IP_FILTER_REMOVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_RES", + [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ", + [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES", + [MSG_SMS_WAIT_CMD - MSG_TYPE_BASE_VAL] = "MSG_SMS_WAIT_CMD", + [MSG_SMS_ADD_PID_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_REQ", + [MSG_SMS_ADD_PID_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_RES", + [MSG_SMS_REMOVE_PID_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_REQ", + [MSG_SMS_REMOVE_PID_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_RES", + [MSG_SMS_FAST_INFORMATION_CHANNEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_REQ", + [MSG_SMS_FAST_INFORMATION_CHANNEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_RES", + [MSG_SMS_DAB_CHANNEL - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_CHANNEL", + [MSG_SMS_GET_PID_FILTER_LIST_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_REQ", + [MSG_SMS_GET_PID_FILTER_LIST_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_RES", + [MSG_SMS_POWER_DOWN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_REQ", + [MSG_SMS_POWER_DOWN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_RES", + [MSG_SMS_ATSC_SLT_EXIST_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SLT_EXIST_IND", + [MSG_SMS_ATSC_NO_SLT_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_NO_SLT_IND", + [MSG_SMS_GET_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_REQ", + [MSG_SMS_GET_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_RES", + [MSG_SMS_SEND_DUMP - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_DUMP", + [MSG_SMS_SCAN_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_REQ", + [MSG_SMS_SCAN_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_RES", + [MSG_SMS_SCAN_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_REQ", + [MSG_SMS_SCAN_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_RES", + [MSG_SMS_SCAN_PROGRESS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_PROGRESS_IND", + [MSG_SMS_SCAN_COMPLETE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_COMPLETE_IND", + [MSG_SMS_LOG_ITEM - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ITEM", + [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ", + [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES", + [MSG_SMS_HO_PER_SLICES_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PER_SLICES_IND", + [MSG_SMS_HO_INBAND_POWER_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_INBAND_POWER_IND", + [MSG_SMS_MANUAL_DEMOD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MANUAL_DEMOD_REQ", + [MSG_SMS_HO_TUNE_ON_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_REQ", + [MSG_SMS_HO_TUNE_ON_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_RES", + [MSG_SMS_HO_TUNE_OFF_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_REQ", + [MSG_SMS_HO_TUNE_OFF_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_RES", + [MSG_SMS_HO_PEEK_FREQ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_REQ", + [MSG_SMS_HO_PEEK_FREQ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_RES", + [MSG_SMS_HO_PEEK_FREQ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_IND", + [MSG_SMS_MB_ATTEN_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_REQ", + [MSG_SMS_MB_ATTEN_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_RES", + [MSG_SMS_ENABLE_STAT_IN_I2C_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_REQ", + [MSG_SMS_ENABLE_STAT_IN_I2C_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_RES", + [MSG_SMS_SET_ANTENNA_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_REQ", + [MSG_SMS_SET_ANTENNA_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_RES", + [MSG_SMS_GET_STATISTICS_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_REQ", + [MSG_SMS_GET_STATISTICS_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_RES", + [MSG_SMS_SLEEP_RESUME_COMP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLEEP_RESUME_COMP_IND", + [MSG_SMS_SWITCH_HOST_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_REQ", + [MSG_SMS_SWITCH_HOST_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_RES", + [MSG_SMS_DATA_DOWNLOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_REQ", + [MSG_SMS_DATA_DOWNLOAD_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_RES", + [MSG_SMS_DATA_VALIDITY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_REQ", + [MSG_SMS_DATA_VALIDITY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_RES", + [MSG_SMS_SWDOWNLOAD_TRIGGER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_REQ", + [MSG_SMS_SWDOWNLOAD_TRIGGER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_RES", + [MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ", + [MSG_SMS_SWDOWNLOAD_BACKDOOR_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_RES", + [MSG_SMS_GET_VERSION_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_REQ", + [MSG_SMS_GET_VERSION_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_RES", + [MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ", + [MSG_SMS_CLOCK_OUTPUT_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_RES", + [MSG_SMS_I2C_SET_FREQ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_REQ", + [MSG_SMS_I2C_SET_FREQ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_RES", + [MSG_SMS_GENERIC_I2C_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_REQ", + [MSG_SMS_GENERIC_I2C_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_RES", + [MSG_SMS_DVBT_BDA_DATA - MSG_TYPE_BASE_VAL] = "MSG_SMS_DVBT_BDA_DATA", + [MSG_SW_RELOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_REQ", + [MSG_SMS_DATA_MSG - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_MSG", + [MSG_TABLE_UPLOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_REQ", + [MSG_TABLE_UPLOAD_RES - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_RES", + [MSG_SW_RELOAD_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_REQ", + [MSG_SW_RELOAD_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_RES", + [MSG_SW_RELOAD_EXEC_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_REQ", + [MSG_SW_RELOAD_EXEC_RES - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_RES", + [MSG_SMS_SPI_INT_LINE_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_REQ", + [MSG_SMS_SPI_INT_LINE_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_RES", + [MSG_SMS_GPIO_CONFIG_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_REQ", + [MSG_SMS_GPIO_CONFIG_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_RES", + [MSG_SMS_WATCHDOG_ACT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_REQ", + [MSG_SMS_WATCHDOG_ACT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_RES", + [MSG_SMS_LOOPBACK_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_REQ", + [MSG_SMS_LOOPBACK_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_RES", + [MSG_SMS_RAW_CAPTURE_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_REQ", + [MSG_SMS_RAW_CAPTURE_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_RES", + [MSG_SMS_RAW_CAPTURE_ABORT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_REQ", + [MSG_SMS_RAW_CAPTURE_ABORT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_RES", + [MSG_SMS_RAW_CAPTURE_COMPLETE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_COMPLETE_IND", + [MSG_SMS_DATA_PUMP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_IND", + [MSG_SMS_DATA_PUMP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_REQ", + [MSG_SMS_DATA_PUMP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_RES", + [MSG_SMS_FLASH_DL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_FLASH_DL_REQ", + [MSG_SMS_EXEC_TEST_1_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_REQ", + [MSG_SMS_EXEC_TEST_1_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_RES", + [MSG_SMS_ENBALE_TS_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENBALE_TS_INTERFACE_REQ", + [MSG_SMS_ENBALE_TS_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENBALE_TS_INTERFACE_RES", + [MSG_SMS_SPI_SET_BUS_WIDTH_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_REQ", + [MSG_SMS_SPI_SET_BUS_WIDTH_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_RES", + [MSG_SMS_SEND_EMM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_REQ", + [MSG_SMS_SEND_EMM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_RES", + [MSG_SMS_DISABLE_TS_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_REQ", + [MSG_SMS_DISABLE_TS_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_RES", + [MSG_SMS_IS_BUF_FREE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_REQ", + [MSG_SMS_IS_BUF_FREE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_RES", + [MSG_SMS_EXT_ANTENNA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_REQ", + [MSG_SMS_EXT_ANTENNA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_RES", + [MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE", + [MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE", + [MSG_SMS_BATTERY_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_REQ", + [MSG_SMS_BATTERY_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_RES", + [MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE", + [MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE", + [MSG_SMS_FM_RADIO_BLOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_FM_RADIO_BLOCK_IND", + [MSG_SMS_HOST_NOTIFICATION_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HOST_NOTIFICATION_IND", + [MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE", + [MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE", + [MSG_SMS_CMMB_GET_NETWORKS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_REQ", + [MSG_SMS_CMMB_GET_NETWORKS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_RES", + [MSG_SMS_CMMB_START_SERVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_REQ", + [MSG_SMS_CMMB_START_SERVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_RES", + [MSG_SMS_CMMB_STOP_SERVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_REQ", + [MSG_SMS_CMMB_STOP_SERVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_RES", + [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ", + [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES", + [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ", + [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES", + [MSG_SMS_CMMB_START_CONTROL_INFO_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_REQ", + [MSG_SMS_CMMB_START_CONTROL_INFO_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_RES", + [MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ", + [MSG_SMS_CMMB_STOP_CONTROL_INFO_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_RES", + [MSG_SMS_ISDBT_TUNE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_REQ", + [MSG_SMS_ISDBT_TUNE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_RES", + [MSG_SMS_TRANSMISSION_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_TRANSMISSION_IND", + [MSG_SMS_PID_STATISTICS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_PID_STATISTICS_IND", + [MSG_SMS_POWER_DOWN_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_IND", + [MSG_SMS_POWER_DOWN_CONF - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_CONF", + [MSG_SMS_POWER_UP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_IND", + [MSG_SMS_POWER_UP_CONF - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_CONF", + [MSG_SMS_POWER_MODE_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_REQ", + [MSG_SMS_POWER_MODE_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_RES", + [MSG_SMS_DEBUG_HOST_EVENT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_REQ", + [MSG_SMS_DEBUG_HOST_EVENT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_RES", + [MSG_SMS_NEW_CRYSTAL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_REQ", + [MSG_SMS_NEW_CRYSTAL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_RES", + [MSG_SMS_CONFIG_SPI_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_REQ", + [MSG_SMS_CONFIG_SPI_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_RES", + [MSG_SMS_I2C_SHORT_STAT_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SHORT_STAT_IND", + [MSG_SMS_START_IR_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_REQ", + [MSG_SMS_START_IR_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_RES", + [MSG_SMS_IR_SAMPLES_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_IR_SAMPLES_IND", + [MSG_SMS_CMMB_CA_SERVICE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_CA_SERVICE_IND", + [MSG_SMS_SLAVE_DEVICE_DETECTED - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLAVE_DEVICE_DETECTED", + [MSG_SMS_INTERFACE_LOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_LOCK_IND", + [MSG_SMS_INTERFACE_UNLOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_UNLOCK_IND", + [MSG_SMS_SEND_ROSUM_BUFF_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_REQ", + [MSG_SMS_SEND_ROSUM_BUFF_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_RES", + [MSG_SMS_ROSUM_BUFF - MSG_TYPE_BASE_VAL] = "MSG_SMS_ROSUM_BUFF", + [MSG_SMS_SET_AES128_KEY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_REQ", + [MSG_SMS_SET_AES128_KEY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_RES", + [MSG_SMS_MBBMS_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_REQ", + [MSG_SMS_MBBMS_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_RES", + [MSG_SMS_MBBMS_READ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_READ_IND", + [MSG_SMS_IQ_STREAM_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_REQ", + [MSG_SMS_IQ_STREAM_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_RES", + [MSG_SMS_IQ_STREAM_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_REQ", + [MSG_SMS_IQ_STREAM_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_RES", + [MSG_SMS_IQ_STREAM_DATA_BLOCK - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_DATA_BLOCK", + [MSG_SMS_GET_EEPROM_VERSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_REQ", + [MSG_SMS_GET_EEPROM_VERSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_RES", + [MSG_SMS_SIGNAL_DETECTED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SIGNAL_DETECTED_IND", + [MSG_SMS_NO_SIGNAL_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_NO_SIGNAL_IND", + [MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ", + [MSG_SMS_MRC_SHUTDOWN_SLAVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_RES", + [MSG_SMS_MRC_BRINGUP_SLAVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_REQ", + [MSG_SMS_MRC_BRINGUP_SLAVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_RES", + [MSG_SMS_EXTERNAL_LNA_CTRL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_REQ", + [MSG_SMS_EXTERNAL_LNA_CTRL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_RES", + [MSG_SMS_SET_PERIODIC_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_REQ", + [MSG_SMS_SET_PERIODIC_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_RES", + [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ", + [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES", + [LOCAL_TUNE - MSG_TYPE_BASE_VAL] = "LOCAL_TUNE", + [LOCAL_IFFT_H_ICI - MSG_TYPE_BASE_VAL] = "LOCAL_IFFT_H_ICI", + [MSG_RESYNC_REQ - MSG_TYPE_BASE_VAL] = "MSG_RESYNC_REQ", + [MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ", + [MSG_SMS_CMMB_GET_MRC_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_RES", + [MSG_SMS_LOG_EX_ITEM - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_EX_ITEM", + [MSG_SMS_DEVICE_DATA_LOSS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEVICE_DATA_LOSS_IND", + [MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND", + [MSG_SMS_USER_MSG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_REQ", + [MSG_SMS_USER_MSG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_RES", + [MSG_SMS_SMART_CARD_INIT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_REQ", + [MSG_SMS_SMART_CARD_INIT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_RES", + [MSG_SMS_SMART_CARD_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_REQ", + [MSG_SMS_SMART_CARD_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_RES", + [MSG_SMS_SMART_CARD_READ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_READ_IND", + [MSG_SMS_TSE_ENABLE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_REQ", + [MSG_SMS_TSE_ENABLE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_RES", + [MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ", + [MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES", + [MSG_SMS_LED_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_REQ", + [MSG_SMS_LED_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_RES", + [MSG_PWM_ANTENNA_REQ - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_REQ", + [MSG_PWM_ANTENNA_RES - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_RES", + [MSG_SMS_CMMB_SMD_SN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_REQ", + [MSG_SMS_CMMB_SMD_SN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_RES", + [MSG_SMS_CMMB_SET_CA_CW_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_REQ", + [MSG_SMS_CMMB_SET_CA_CW_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_RES", + [MSG_SMS_CMMB_SET_CA_SALT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_REQ", + [MSG_SMS_CMMB_SET_CA_SALT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_RES", + [MSG_SMS_NSCD_INIT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_REQ", + [MSG_SMS_NSCD_INIT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_RES", + [MSG_SMS_NSCD_PROCESS_SECTION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_REQ", + [MSG_SMS_NSCD_PROCESS_SECTION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_RES", + [MSG_SMS_DBD_CREATE_OBJECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_REQ", + [MSG_SMS_DBD_CREATE_OBJECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_RES", + [MSG_SMS_DBD_CONFIGURE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_REQ", + [MSG_SMS_DBD_CONFIGURE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_RES", + [MSG_SMS_DBD_SET_KEYS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_REQ", + [MSG_SMS_DBD_SET_KEYS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_RES", + [MSG_SMS_DBD_PROCESS_HEADER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_REQ", + [MSG_SMS_DBD_PROCESS_HEADER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_RES", + [MSG_SMS_DBD_PROCESS_DATA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_REQ", + [MSG_SMS_DBD_PROCESS_DATA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_RES", + [MSG_SMS_DBD_PROCESS_GET_DATA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_REQ", + [MSG_SMS_DBD_PROCESS_GET_DATA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_RES", + [MSG_SMS_NSCD_OPEN_SESSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_REQ", + [MSG_SMS_NSCD_OPEN_SESSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_RES", + [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ", + [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES", + [MSG_LAST_MSG_TYPE - MSG_TYPE_BASE_VAL] = "MSG_LAST_MSG_TYPE", +}; + +char *smscore_translate_msg(enum msg_types msgtype) +{ + int i = msgtype - MSG_TYPE_BASE_VAL; + char *msg; + + if (i < 0 || i > ARRAY_SIZE(siano_msgs)) + return "Unknown msg type"; + + msg = siano_msgs[i]; + + if (!*msg) + return "Unknown msg type"; + + return msg; +} +EXPORT_SYMBOL_GPL(smscore_translate_msg); + void smscore_set_board_id(struct smscore_device_t *core, int id) { core->board_id = id; @@ -1012,8 +1351,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, { struct SmsVersionRes_ST *ver = (struct SmsVersionRes_ST *) phdr; - sms_debug("MSG_SMS_GET_VERSION_EX_RES " - "id %d prots 0x%x ver %d.%d", + sms_debug("Firmware id %d prots 0x%x ver %d.%d", ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); @@ -1025,39 +1363,33 @@ void smscore_onresponse(struct smscore_device_t *coredev, break; } case MSG_SMS_INIT_DEVICE_RES: - sms_debug("MSG_SMS_INIT_DEVICE_RES"); complete(&coredev->init_device_done); break; case MSG_SW_RELOAD_START_RES: - sms_debug("MSG_SW_RELOAD_START_RES"); complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; case MSG_SW_RELOAD_EXEC_RES: - sms_debug("MSG_SW_RELOAD_EXEC_RES"); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); complete(&coredev->trigger_done); break; case MSG_SMS_SLEEP_RESUME_COMP_IND: complete(&coredev->resume_done); break; case MSG_SMS_GPIO_CONFIG_EX_RES: - sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); complete(&coredev->gpio_configuration_done); break; case MSG_SMS_GPIO_SET_LEVEL_RES: - sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); complete(&coredev->gpio_set_level_done); break; case MSG_SMS_GPIO_GET_LEVEL_RES: { u32 *msgdata = (u32 *) phdr; coredev->gpio_get_res = msgdata[1]; - sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", + sms_debug("gpio level %d", coredev->gpio_get_res); complete(&coredev->gpio_get_level_done); break; @@ -1075,6 +1407,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, break; default: + sms_debug("message not handled.\n"); break; } smscore_putbuffer(coredev, cb); diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 4a0a7639319d..0078fef095a7 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -937,6 +937,8 @@ struct smscore_config_gpio { u8 outputdriving; }; +char *smscore_translate_msg(enum msg_types msgtype); + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index aa77e54a8fae..57f3560514ab 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -249,20 +249,16 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) break; case MSG_SMS_SIGNAL_DETECTED_IND: - sms_info("MSG_SMS_SIGNAL_DETECTED_IND"); client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; is_status_update = true; break; case MSG_SMS_NO_SIGNAL_IND: - sms_info("MSG_SMS_NO_SIGNAL_IND"); client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; is_status_update = true; break; case MSG_SMS_TRANSMISSION_IND: { - sms_info("MSG_SMS_TRANSMISSION_IND"); - pMsgData++; memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, sizeof(struct TRANSMISSION_STATISTICS_S)); @@ -281,7 +277,6 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) &client->sms_stat_dvb.ReceptionData; struct SRVM_SIGNAL_STATUS_S SignalStatusData; - /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/ pMsgData++; SignalStatusData.result = pMsgData[0]; SignalStatusData.snr = pMsgData[1]; @@ -336,8 +331,6 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) struct RECEPTION_STATISTICS_S *pReceptionData = &client->sms_stat_dvb.ReceptionData; - sms_info("MSG_SMS_GET_STATISTICS_RES"); - is_status_update = true; switch (smscore_get_device_mode(client->coredev)) { @@ -360,8 +353,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) break; } default: - sms_info("Unhandled message %d", phdr->msgType); - + sms_info("message not handled"); } smscore_putbuffer(client->coredev, cb); diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index de2c10289eec..2050e4c415b1 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -106,6 +106,10 @@ static void smsusb_onresponse(struct urb *urb) } else surb->cb->offset = 0; + sms_debug("received %s(%d) size: %d", + smscore_translate_msg(phdr->msgType), + phdr->msgType, phdr->msgLength); + smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; } else { @@ -181,8 +185,13 @@ static int smsusb_start_streaming(struct smsusb_device_t *dev) static int smsusb_sendrequest(void *context, void *buffer, size_t size) { struct smsusb_device_t *dev = (struct smsusb_device_t *) context; + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; int dummy; + sms_debug("sending %s(%d) size: %d", + smscore_translate_msg(phdr->msgType), phdr->msgType, + phdr->msgLength); + smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); -- cgit From ab2b599ebfbdd4e311e796643d487722256418b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 07:37:47 -0300 Subject: [media] siano: add the remaining new defines from new driver Add the remaining new defines/enums from Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7882/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.h | 39 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 0078fef095a7..fc451e206436 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -50,18 +50,31 @@ along with this program. If not, see . #define SMS_ALIGN_ADDRESS(addr) \ ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) +#define SMS_DEVICE_FAMILY1 0 #define SMS_DEVICE_FAMILY2 1 #define SMS_ROM_NO_RESPONSE 2 #define SMS_DEVICE_NOT_READY 0x8000000 enum sms_device_type_st { + SMS_UNKNOWN_TYPE = -1, SMS_STELLAR = 0, SMS_NOVA_A0, SMS_NOVA_B0, SMS_VEGA, + SMS_VENICE, + SMS_MING, + SMS_PELE, + SMS_RIO, + SMS_DENVER_1530, + SMS_DENVER_2160, SMS_NUM_OF_DEVICE_TYPES }; +enum sms_power_mode_st { + SMS_POWER_MODE_ACTIVE, + SMS_POWER_MODE_SUSPENDED +}; + struct smscore_device_t; struct smscore_client_t; struct smscore_buffer_t; @@ -176,18 +189,29 @@ struct smscore_device_t { #define SMS_ANTENNA_GPIO_0 1 #define SMS_ANTENNA_GPIO_1 0 -#define BW_8_MHZ 0 -#define BW_7_MHZ 1 -#define BW_6_MHZ 2 -#define BW_5_MHZ 3 -#define BW_ISDBT_1SEG 4 -#define BW_ISDBT_3SEG 5 +enum sms_bandwidth_mode { + BW_8_MHZ = 0, + BW_7_MHZ = 1, + BW_6_MHZ = 2, + BW_5_MHZ = 3, + BW_ISDBT_1SEG = 4, + BW_ISDBT_3SEG = 5, + BW_2_MHZ = 6, + BW_FM_RADIO = 7, + BW_ISDBT_13SEG = 8, + BW_1_5_MHZ = 15, + BW_UNKNOWN = 0xffff +}; + #define MSG_HDR_FLAG_SPLIT_MSG 4 #define MAX_GPIO_PIN_NUMBER 31 #define HIF_TASK 11 +#define HIF_TASK_SLAVE 22 +#define HIF_TASK_SLAVE2 33 +#define HIF_TASK_SLAVE3 44 #define SMS_HOST_LIB 150 #define DVBT_BDA_CONTROL_MSG_ID 201 @@ -545,6 +569,9 @@ enum SMS_DEVICE_MODE { DEVICE_MODE_ISDBT_BDA, DEVICE_MODE_CMMB, DEVICE_MODE_RAW_TUNER, + DEVICE_MODE_FM_RADIO, + DEVICE_MODE_FM_RADIO_BDA, + DEVICE_MODE_ATSC, DEVICE_MODE_MAX, }; -- cgit From 3ba92d0b58c909d68c316b5f7989abbc7b62b3ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 08:42:47 -0300 Subject: [media] siano: Properly initialize board information Board #0 is an existing one. Instead of initializing the driver with it, use a different value to detect if board is unknown. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index bc15dcecb25d..1dab4b64d395 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -723,6 +723,7 @@ int smscore_register_device(struct smsdevice_params_t *params, sms_info("allocated %d buffers", dev->num_buffers); dev->mode = DEVICE_MODE_NONE; + dev->board_id = SMS_BOARD_UNKNOWN; dev->context = params->context; dev->device = params->device; dev->setmode_handler = params->setmode_handler; -- cgit From db30567a63db0094e03338462939031edf558cc8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 08:33:44 -0300 Subject: [media] siano: add additional attributes to cards entries Those attributes will be used by the newer sms2xxx cards. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h index d8cdf756f7cf..9f1861aa71c9 100644 --- a/drivers/media/common/siano/sms-cards.h +++ b/drivers/media/common/siano/sms-cards.h @@ -79,6 +79,12 @@ struct sms_board { /* gpios */ int led_power, led_hi, led_lo, lna_ctrl, rf_switch; + + char intf_num; + int default_mode; + unsigned int mtu; + unsigned int crystal; + struct sms_antenna_config_ST *antenna_config; }; struct sms_board *sms_get_board(unsigned id); -- cgit From 05f0ffbc487517a529c00119d0bfde33df509b52 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 09:53:50 -0300 Subject: [media] siano: use USB endpoint descriptors for in/out endp Instead of using hardcoded descriptors, detect them from the USB descriptors. This patch is rebased form Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7883/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/siano/smsusb.c | 99 +++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 2050e4c415b1..a31bf74a5957 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -35,16 +35,23 @@ module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); #define USB1_BUFFER_SIZE 0x1000 -#define USB2_BUFFER_SIZE 0x4000 +#define USB2_BUFFER_SIZE 0x2000 #define MAX_BUFFERS 50 #define MAX_URBS 10 struct smsusb_device_t; +enum smsusb_state { + SMSUSB_DISCONNECTED, + SMSUSB_SUSPENDED, + SMSUSB_ACTIVE +}; + struct smsusb_urb_t { + struct list_head entry; struct smscore_buffer_t *cb; - struct smsusb_device_t *dev; + struct smsusb_device_t *dev; struct urb urb; }; @@ -57,11 +64,23 @@ struct smsusb_device_t { int response_alignment; int buffer_size; + + unsigned char in_ep; + unsigned char out_ep; + enum smsusb_state state; }; static int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb); +/** + * Completing URB's callback handler - top half (interrupt context) + * adds completing sms urb to the global surbs list and activtes the worker + * thread the surb + * IMPORTANT - blocking functions must not be called from here !!! + + * @param urb pointer to a completing urb object + */ static void smsusb_onresponse(struct urb *urb) { struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; @@ -140,7 +159,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, usb_fill_bulk_urb( &surb->urb, dev->udev, - usb_rcvbulkpipe(dev->udev, 0x81), + usb_rcvbulkpipe(dev->udev, dev->in_ep), surb->cb->p, dev->buffer_size, smsusb_onresponse, @@ -192,6 +211,9 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) smscore_translate_msg(phdr->msgType), phdr->msgType, phdr->msgLength); + if (dev->state != SMSUSB_ACTIVE) + return -ENOENT; + smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); @@ -301,13 +323,15 @@ static void smsusb_term_device(struct usb_interface *intf) struct smsusb_device_t *dev = usb_get_intfdata(intf); if (dev) { + dev->state = SMSUSB_DISCONNECTED; + smsusb_stop_streaming(dev); /* unregister from smscore */ if (dev->coredev) smscore_unregister_device(dev->coredev); - sms_info("device %p destroyed", dev); + sms_info("device 0x%p destroyed", dev); kfree(dev); } @@ -330,6 +354,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) memset(¶ms, 0, sizeof(params)); usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); + dev->state = SMSUSB_DISCONNECTED; params.device_type = sms_get_board(board_id)->type; @@ -346,6 +371,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) case SMS_NOVA_A0: case SMS_NOVA_B0: case SMS_VEGA: + case SMS_VENICE: + case SMS_DENVER_1530: dev->buffer_size = USB2_BUFFER_SIZE; dev->response_alignment = le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - @@ -355,6 +382,16 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) break; } + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN) + dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; + else + dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; + } + + sms_info("in_ep = %02x, out_ep = %02x", + dev->in_ep, dev->out_ep); + params.device = &dev->udev->dev; params.buffer_size = dev->buffer_size; params.num_buffers = MAX_BUFFERS; @@ -386,6 +423,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) return rc; } + dev->state = SMSUSB_ACTIVE; + rc = smscore_start_device(dev->coredev); if (rc < 0) { sms_err("smscore_start_device(...) failed"); @@ -393,7 +432,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) return rc; } - sms_info("device %p created", dev); + sms_info("device 0x%p created", dev); return rc; } @@ -402,15 +441,23 @@ static int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); - char devpath[32]; int i, rc; - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); + sms_info("interface number %d", + intf->cur_altsetting->desc.bInterfaceNumber); - if (intf->num_altsetting > 0) { - rc = usb_set_interface( - udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); + if (sms_get_board(id->driver_info)->intf_num != + intf->cur_altsetting->desc.bInterfaceNumber) { + sms_err("interface number is %d expecting %d", + sms_get_board(id->driver_info)->intf_num, + intf->cur_altsetting->desc.bInterfaceNumber); + return -ENODEV; + } + + if (intf->num_altsetting > 1) { + rc = usb_set_interface(udev, + intf->cur_altsetting->desc.bInterfaceNumber, + 0); if (rc < 0) { sms_err("usb_set_interface failed, rc %d", rc); return rc; @@ -419,27 +466,25 @@ static int smsusb_probe(struct usb_interface *intf, sms_info("smsusb_probe %d", intf->cur_altsetting->desc.bInterfaceNumber); - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { sms_info("endpoint %d %02x %02x %d", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - + if (intf->cur_altsetting->endpoint[i].desc.bEndpointAddress & + USB_DIR_IN) + rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, + intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); + else + rc = usb_clear_halt(udev, usb_sndbulkpipe(udev, + intf->cur_altsetting->endpoint[i].desc.bEndpointAddress)); + } if ((udev->actconfig->desc.bNumInterfaces == 2) && (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { sms_err("rom interface 0 is not used"); return -ENODEV; } - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { - snprintf(devpath, sizeof(devpath), "usb\\%d-%s", - udev->bus->busnum, udev->devpath); - sms_info("stellar device was found."); - return smsusb1_load_firmware( - udev, smscore_registry_getmode(devpath), - id->driver_info); - } - rc = smsusb_init_device(intf, id->driver_info); sms_info("rc %d", rc); sms_board_load_modules(id->driver_info); @@ -454,7 +499,9 @@ static void smsusb_disconnect(struct usb_interface *intf) static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) { struct smsusb_device_t *dev = usb_get_intfdata(intf); - printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); + printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); + dev->state = SMSUSB_SUSPENDED; + /*smscore_set_power_mode(dev, SMS_POWER_MODE_SUSPENDED);*/ smsusb_stop_streaming(dev); return 0; } @@ -465,9 +512,9 @@ static int smsusb_resume(struct usb_interface *intf) struct smsusb_device_t *dev = usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); - printk(KERN_INFO "%s: Entering.\n", __func__); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); + printk(KERN_INFO "%s Entering.\n", __func__); + usb_clear_halt(udev, usb_rcvbulkpipe(udev, dev->in_ep)); + usb_clear_halt(udev, usb_sndbulkpipe(udev, dev->out_ep)); for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, -- cgit From 7333839505d568e0e69a6d02a3ee0f455b6c37a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 09:56:27 -0300 Subject: [media] siano: store firmware version As there are some changes that seem to be firmware-dependent, we need to store the firmware version, as we don't want to break support for existing cards that use a legacy (and sometimes custom) firmware. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 2 ++ drivers/media/common/siano/smscoreapi.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 1dab4b64d395..7b5d81a30cdf 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1359,6 +1359,8 @@ void smscore_onresponse(struct smscore_device_t *coredev, coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; coredev->modes_supported = ver->SupportedProtocols; + coredev->fw_version = ver->RomVersionMajor << 8 | + ver->RomVersionMinor; complete(&coredev->version_ex_done); break; diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index fc451e206436..f1440a55cb4d 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -178,6 +178,7 @@ struct smscore_device_t { /* Firmware */ u8 *fw_buf; u32 fw_buf_size; + u16 fw_version; /* Infrared (IR) */ struct ir_t ir; -- cgit From 018b0c6f8acb5819591f3b43b51fc342af548c82 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Mar 2013 12:15:08 -0300 Subject: [media] siano: make load firmware logic to work with newer firmwares There are new firmwares for sms2xxx devices. Change the firmware load logic to handle those newer firmwares and devices. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 348 ++++++++++++++++++++------------ drivers/media/common/siano/smscoreapi.h | 8 +- 2 files changed, 220 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 7b5d81a30cdf..d489701c3842 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -683,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params, /* init completion events */ init_completion(&dev->version_ex_done); init_completion(&dev->data_download_done); + init_completion(&dev->data_validity_done); init_completion(&dev->trigger_done); init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); @@ -753,7 +754,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, struct completion *completion) { - int rc = coredev->sendrequest_handler(coredev->context, buffer, size); + int rc; + + if (completion == NULL) + return -EINVAL; + init_completion(completion); + + rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { sms_info("sendrequest returned error %d", rc); return rc; @@ -850,8 +857,9 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) { struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; - struct SmsMsgHdr_ST *msg; - u32 mem_address; + struct SmsMsgData_ST4 *msg; + u32 mem_address, calc_checksum = 0; + u32 i, *ptr; u8 *payload = firmware->Payload; int rc = 0; firmware->StartAddress = le32_to_cpu(firmware->StartAddress); @@ -874,34 +882,35 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, if (coredev->mode != DEVICE_MODE_NONE) { sms_debug("sending reload command."); - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_START_REQ, sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, - msg->msgLength, + msg->xMsgHeader.msgLength, &coredev->reload_start_done); + if (rc < 0) { + sms_err("device reload failed, rc %d", rc); + goto exit_fw_download; + } mem_address = *(u32 *) &payload[20]; } + for (i = 0, ptr = (u32 *)firmware->Payload; i < firmware->Length/4 ; + i++, ptr++) + calc_checksum += *ptr; + while (size && rc >= 0) { struct SmsDataDownload_ST *DataMsg = (struct SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_DOWNLOAD_REQ, (u16)(sizeof(struct SmsMsgHdr_ST) + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); - if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && - (coredev->mode == DEVICE_MODE_NONE)) - rc = coredev->sendrequest_handler( - coredev->context, DataMsg, - DataMsg->xMsgHeader.msgLength); - else - rc = smscore_sendrequest_and_wait( - coredev, DataMsg, + rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); @@ -910,44 +919,65 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, mem_address += payload_size; } - if (rc >= 0) { - if (coredev->mode == DEVICE_MODE_NONE) { - struct SmsMsgData_ST *TriggerMsg = - (struct SmsMsgData_ST *) msg; - - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct SmsMsgHdr_ST) + - sizeof(u32) * 5); - - TriggerMsg->msgData[0] = firmware->StartAddress; - /* Entry point */ - TriggerMsg->msgData[1] = 5; /* Priority */ - TriggerMsg->msgData[2] = 0x200; /* Stack size */ - TriggerMsg->msgData[3] = 0; /* Parameter */ - TriggerMsg->msgData[4] = 4; /* Task ID */ - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { - rc = coredev->sendrequest_handler( - coredev->context, TriggerMsg, - TriggerMsg->xMsgHeader.msgLength); - msleep(100); - } else - rc = smscore_sendrequest_and_wait( - coredev, TriggerMsg, + if (rc < 0) + goto exit_fw_download; + + sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", + calc_checksum); + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_VALIDITY_REQ, + sizeof(msg->xMsgHeader) + + sizeof(u32) * 3); + msg->msgData[0] = firmware->StartAddress; + /* Entry point */ + msg->msgData[1] = firmware->Length; + msg->msgData[2] = 0; /* Regular checksum*/ + smsendian_handle_tx_message(msg); + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->xMsgHeader.msgLength, + &coredev->data_validity_done); + if (rc < 0) + goto exit_fw_download; + + if (coredev->mode == DEVICE_MODE_NONE) { + struct SmsMsgData_ST *TriggerMsg = + (struct SmsMsgData_ST *) msg; + + sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ"); + SMS_INIT_MSG(&msg->xMsgHeader, + MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, + sizeof(struct SmsMsgHdr_ST) + + sizeof(u32) * 5); + + TriggerMsg->msgData[0] = firmware->StartAddress; + /* Entry point */ + TriggerMsg->msgData[1] = 6; /* Priority */ + TriggerMsg->msgData[2] = 0x200; /* Stack size */ + TriggerMsg->msgData[3] = 0; /* Parameter */ + TriggerMsg->msgData[4] = 4; /* Task ID */ + + smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); + rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); - } else { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, - sizeof(struct SmsMsgHdr_ST)); - - rc = coredev->sendrequest_handler(coredev->context, - msg, msg->msgLength); - } - msleep(500); + } else { + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ, + sizeof(struct SmsMsgHdr_ST)); + smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); + rc = coredev->sendrequest_handler(coredev->context, msg, + msg->xMsgHeader.msgLength); } - sms_debug("rc=%d, postload=%p ", rc, - coredev->postload_handler); + if (rc < 0) + goto exit_fw_download; + + /* + * backward compatibility - wait to device_ready_done for + * not more than 400 ms + */ + msleep(400); + +exit_fw_download: + sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler); kfree(msg); @@ -956,6 +986,10 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, rc; } + +static char *smscore_get_fw_filename(struct smscore_device_t *coredev, + int mode, int lookup); + /** * loads specified firmware into a buffer and calls device loadfirmware_handler * @@ -967,41 +1001,43 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, * @return 0 on success, <0 on error. */ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, - char *filename, + int mode, int lookup, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; + u8 *fw_buf; + u32 fw_buf_size; const struct firmware *fw; - u8 *fw_buffer; - if (loadfirmware_handler == NULL && !(coredev->device_flags & - SMS_DEVICE_FAMILY2)) + char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); + if (!strcmp(fw_filename, "none")) + return -ENOENT; + + if (loadfirmware_handler == NULL && !(coredev->device_flags + & SMS_DEVICE_FAMILY2)) return -EINVAL; - rc = request_firmware(&fw, filename, coredev->device); + rc = request_firmware(&fw, fw_filename, coredev->device); if (rc < 0) { - sms_info("failed to open \"%s\"", filename); + sms_info("failed to open \"%s\"", fw_filename); return rc; } - sms_info("read FW %s, size=%zd", filename, fw->size); - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), - GFP_KERNEL | GFP_DMA); - if (fw_buffer) { - memcpy(fw_buffer, fw->data, fw->size); - - rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, - fw_buffer, - fw->size) : - loadfirmware_handler(coredev->context, - fw_buffer, fw->size); - - kfree(fw_buffer); - } else { + sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size); + fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), + GFP_KERNEL | GFP_DMA); + if (!fw_buf) { sms_info("failed to allocate firmware buffer"); - rc = -ENOMEM; + return -ENOMEM; } + memcpy(fw_buf, fw->data, fw->size); + fw_buf_size = fw->size; + + rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? + smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size) + : loadfirmware_handler(coredev->context, fw_buf, + fw_buf_size); + kfree(fw_buf); release_firmware(fw); return rc; @@ -1050,7 +1086,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("waiting for %d buffer(s)", coredev->num_buffers - num_buffers); + kmutex_unlock(&g_smscore_deviceslock); msleep(100); + kmutex_lock(&g_smscore_deviceslock); } sms_info("freed %d buffers", num_buffers); @@ -1107,30 +1145,73 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) } static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - /*Stellar NOVA A0 Nova B0 VEGA*/ - /*DVBT*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*DVBH*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, - /*DABIP*/ - {"none", "none", "none", "none"}, - /*BDA*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*ISDBT*/ - {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*ISDBTBDA*/ - {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*CMMB*/ - {"none", "none", "none", "cmmb_vega_12mhz.inp"} + /*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */ + /*DVBT*/ + { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, + /*DVBH*/ + { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" }, + /*TDMB*/ + { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" }, + /*DABIP*/ + { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, + /*DVBT_BDA*/ + { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, + /*ISDBT*/ + { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, + /*ISDBT_BDA*/ + { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, + /*CMMB*/ + { "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" }, + /*RAW - not supported*/ + { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, + /*FM*/ + { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, + /*FM_BDA*/ + { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, + /*ATSC*/ + { "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" } }; -static inline char *sms_get_fw_name(struct smscore_device_t *coredev, - int mode, enum sms_device_type_st type) +/** + * get firmware file name from one of the two mechanisms : sms_boards or + * smscore_fw_lkup. + * @param coredev pointer to a coredev object returned by + * smscore_register_device + * @param mode requested mode of operation + * @param lookup if 1, always get the fw filename from smscore_fw_lkup + * table. if 0, try first to get from sms_boards + * + * @return 0 on success, <0 on error. + */ +static char *smscore_get_fw_filename(struct smscore_device_t *coredev, + int mode, int lookup) { - char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; - return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; + char **fw; + int board_id = smscore_get_board_id(coredev); + enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath); + + if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { + sms_debug("trying to get fw name from lookup table mode %d type %d", + mode, type); + return smscore_fw_lkup[mode][type]; + } + + sms_debug("trying to get fw name from sms_boards board_id %d mode %d", + board_id, mode); + fw = sms_get_board(board_id)->fw; + if (fw == NULL) { + sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", + mode, type); + return smscore_fw_lkup[mode][type]; + } + + if (fw[mode] == NULL) { + sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", + mode, type); + return smscore_fw_lkup[mode][type]; + } + + return fw[mode]; } /** @@ -1145,9 +1226,7 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev, */ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) { - void *buffer; int rc = 0; - enum sms_device_type_st type; sms_debug("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { @@ -1172,55 +1251,30 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (!(coredev->modes_supported & (1 << mode))) { - char *fw_filename; - - type = smscore_registry_gettype(coredev->devpath); - fw_filename = sms_get_fw_name(coredev, mode, type); - rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - if (rc < 0) { - sms_warn("error %d loading firmware: %s, " - "trying again with default firmware", - rc, fw_filename); + mode, 0, NULL); - /* try again with the default firmware */ - fw_filename = smscore_fw_lkup[mode][type]; + /* + * try again with the default firmware - + * get the fw filename from look-up table + */ + if (rc < 0) { + sms_debug("error %d loading firmware, trying again with default firmware", + rc); rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - + mode, 1, + NULL); if (rc < 0) { - sms_warn("error %d loading " - "firmware: %s", rc, - fw_filename); + sms_debug("error %d loading firmware", + rc); return rc; } } - sms_log("firmware download success: %s", fw_filename); - } else - sms_info("mode %d supported by running " - "firmware", mode); - - buffer = kmalloc(sizeof(struct SmsMsgData_ST) + - SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) { - struct SmsMsgData_ST *msg = - (struct SmsMsgData_ST *) - SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, - sizeof(struct SmsMsgData_ST)); - msg->msgData[0] = mode; - - rc = smscore_sendrequest_and_wait( - coredev, msg, msg->xMsgHeader.msgLength, - &coredev->init_device_done); - - kfree(buffer); + if (rc >= 0) + sms_info("firmware download success"); } else { - sms_err("Could not allocate buffer for " - "init device message."); - rc = -ENOMEM; + sms_info("mode %d is already supported by running firmware", + mode); } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { @@ -1239,8 +1293,25 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc >= 0) { + char *buffer; coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; + + buffer = kmalloc(sizeof(struct SmsMsgData_ST) + + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (buffer) { + struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); + + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, + sizeof(struct SmsMsgData_ST)); + msg->msgData[0] = mode; + + rc = smscore_sendrequest_and_wait( + coredev, msg, msg->xMsgHeader.msgLength, + &coredev->init_device_done); + + kfree(buffer); + } } if (rc < 0) @@ -1371,6 +1442,15 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SW_RELOAD_START_RES: complete(&coredev->reload_start_done); break; + case MSG_SMS_DATA_VALIDITY_RES: + { + struct SmsMsgData_ST *validity = (struct SmsMsgData_ST *) phdr; + + sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", + validity->msgData[0]); + complete(&coredev->data_validity_done); + break; + } case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index f1440a55cb4d..91db8536c2b0 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -162,6 +162,7 @@ struct smscore_device_t { /* host <--> device messages */ struct completion version_ex_done, data_download_done, trigger_done; + struct completion data_validity_done, device_ready_done; struct completion init_device_done, reload_start_done, resume_done; struct completion gpio_configuration_done, gpio_set_level_done; struct completion gpio_get_level_done, ir_init_done; @@ -594,6 +595,11 @@ struct SmsMsgData_ST2 { u32 msgData[2]; }; +struct SmsMsgData_ST4 { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[4]; +}; + struct SmsDataDownload_ST { struct SmsMsgHdr_ST xMsgHeader; u32 MemAddr; @@ -998,8 +1004,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); -extern int smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode, char *filename); extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf, int size); -- cgit From ab7bdb12984732e5ebac00d6a180431cbd4e0ce1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 06:54:14 -0300 Subject: [media] siano: report the choosed firmware in debug Don't keep in the dark: report the firmware file name after lookup. That helps to debug what's happening when a firmware is not found. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index d489701c3842..5034153ed09c 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1010,6 +1010,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, const struct firmware *fw; char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); + sms_debug("Firmware name: %s\n", fw_filename); if (!strcmp(fw_filename, "none")) return -ENOENT; -- cgit From 1e19c21ec7b5e66228602f4d88d894e23db1e004 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 07:32:47 -0300 Subject: [media] siano: fix the debug message Instead of displaying this: [ 61.869415] smscore_load_firmware_family2: rc=0, postload=0x (null) Display, instead: [ 1348.441160] smscore_load_firmware_family2: rc=0 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 5034153ed09c..7302f950c6bd 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -977,13 +977,16 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, msleep(400); exit_fw_download: - sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler); - kfree(msg); - return ((rc >= 0) && coredev->postload_handler) ? - coredev->postload_handler(coredev->context) : - rc; + if (coredev->postload_handler) { + sms_debug("rc=%d, postload=0x%p", rc, coredev->postload_handler); + if (rc >= 0) + return coredev->postload_handler(coredev->context); + } + + sms_debug("rc=%d", rc); + return rc; } -- cgit From 9e915e5bc8dfa3380c376a5e10f1abe8c17f324a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 11:35:00 -0300 Subject: [media] siano: always load smsdvb Without smsdvb, the driver actually does nothing, as it lacks the userspace API. While I wrote it independently, in order to make a sms2270 board I have here to work, this patch is functionally identical to this patch from Doron Cohen: http://patchwork.linuxtv.org/patch/7894/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index b22b61dbc0e2..04bb04ca414f 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c @@ -293,19 +293,7 @@ EXPORT_SYMBOL_GPL(sms_board_lna_control); int sms_board_load_modules(int id) { - switch (id) { - case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - request_module("smsdvb"); - break; - default: - /* do nothing */ - break; - } + request_module("smsdvb"); return 0; } EXPORT_SYMBOL_GPL(sms_board_load_modules); -- cgit From e5d218ee75787bbe5bbe6c570797443c877cd4e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 11:38:57 -0300 Subject: [media] siano: cleanups at smscoreapi.c Some cleanups at smscoreapi. Most are just CodingStyle. Also, use kzalloc when allocating a new buffer, as it initializes the allocated space with zero. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 25 ++++++++++++++++--------- drivers/media/common/siano/smscoreapi.h | 1 - 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 7302f950c6bd..ba73293cf7d3 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -490,10 +490,10 @@ static enum sms_device_type_st smscore_registry_gettype(char *devpath) else sms_err("No registry found."); - return -1; + return -EINVAL; } -void smscore_registry_setmode(char *devpath, int mode) +static void smscore_registry_setmode(char *devpath, int mode) { struct smscore_registry_entry_t *entry; @@ -633,10 +633,11 @@ static struct smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, dma_addr_t common_buffer_phys) { - struct smscore_buffer_t *cb = - kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); + struct smscore_buffer_t *cb; + + cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); if (!cb) { - sms_info("kmalloc(...) failed"); + sms_info("kzalloc(...) failed"); return NULL; } @@ -710,9 +711,10 @@ int smscore_register_device(struct smsdevice_params_t *params, for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers++, buffer += params->buffer_size) { - struct smscore_buffer_t *cb = - smscore_createbuffer(buffer, dev->common_buffer, - dev->common_buffer_phys); + struct smscore_buffer_t *cb; + + cb = smscore_createbuffer(buffer, dev->common_buffer, + dev->common_buffer_phys); if (!cb) { smscore_unregister_device(dev); return -ENOMEM; @@ -1192,7 +1194,9 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, { char **fw; int board_id = smscore_get_board_id(coredev); - enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath); + enum sms_device_type_st type; + + type = smscore_registry_gettype(coredev->devpath); if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { sms_debug("trying to get fw name from lookup table mode %d type %d", @@ -1320,6 +1324,9 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) if (rc < 0) sms_err("return error code %d.", rc); + else + sms_debug("Success setting device mode."); + return rc; } diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 91db8536c2b0..8af94c434352 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -973,7 +973,6 @@ struct smscore_config_gpio { char *smscore_translate_msg(enum msg_types msgtype); -extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); extern int smscore_register_hotplug(hotplug_t hotplug); -- cgit From faab6820b3c11ca62fd2284d2e5174ccb0650b05 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 11:53:46 -0300 Subject: [media] siano: add some new messages to the smscoreapi Based on Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7887/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index ba73293cf7d3..67d0319dc013 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1429,7 +1429,23 @@ void smscore_onresponse(struct smscore_device_t *coredev, rc = client->onresponse_handler(client->context, cb); if (rc < 0) { + smsendian_handle_rx_message((struct SmsMsgData_ST *)phdr); + switch (phdr->msgType) { + case MSG_SMS_ISDBT_TUNE_RES: + break; + case MSG_SMS_RF_TUNE_RES: + break; + case MSG_SMS_SIGNAL_DETECTED_IND: + break; + case MSG_SMS_NO_SIGNAL_IND: + break; + case MSG_SMS_SPI_INT_LINE_SET_RES: + break; + case MSG_SMS_INTERFACE_LOCK_IND: + break; + case MSG_SMS_INTERFACE_UNLOCK_IND: + break; case MSG_SMS_GET_VERSION_EX_RES: { struct SmsVersionRes_ST *ver = -- cgit From 76e41a655ae68b3e0468a3ef497a57415a77b54b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 16:32:33 -0300 Subject: [media] siano: use a separate completion for stats Instead of re-use tune_done also for stats, the better is to use a different completion. Also, it was noticed that sometimes, the driver answers with MSG_SMS_SIGNAL_DETECTED_IND for status request. Fix the code to also handle those other signal indicators. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 57f3560514ab..f4fd6703c49e 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -48,6 +48,7 @@ struct smsdvb_client_t { fe_status_t fe_status; struct completion tune_done; + struct completion stats_done; struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; int event_fe_state; @@ -349,7 +350,6 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) pReceptionData->ErrorTSPackets = 0; } - complete(&client->tune_done); break; } default: @@ -376,6 +376,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) client->fe_status = 0; sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); } + complete(&client->stats_done); } return 0; @@ -471,7 +472,7 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) sizeof(struct SmsMsgHdr_ST), 0 }; rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); + &client->stats_done); return rc; } @@ -1002,6 +1003,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, client->coredev = coredev; init_completion(&client->tune_done); + init_completion(&client->stats_done); kmutex_lock(&g_smsdvb_clientslock); -- cgit From a51fea4fdbf1c8151f55029c82f850cbd335ff29 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 16:34:06 -0300 Subject: [media] siano: add support for ISDB-T full-seg Fix the DVBv5 API handling for ISDB-T and add support for 13 segments. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 46 ++++++++++++++----------------------- 1 file changed, 17 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index f4fd6703c49e..4900aa9e8b7a 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -652,6 +652,9 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); + int board_id = smscore_get_board_id(client->coredev); + struct sms_board *board = sms_get_board(board_id); + enum sms_device_type_st type = board->type; struct { struct SmsMsgHdr_ST Msg; @@ -669,40 +672,25 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) if (c->isdbt_sb_segment_idx == -1) c->isdbt_sb_segment_idx = 0; - switch (c->isdbt_sb_segment_count) { - case 3: - Msg.Data[1] = BW_ISDBT_3SEG; - break; - case 1: - Msg.Data[1] = BW_ISDBT_1SEG; - break; - case 0: /* AUTO */ - switch (c->bandwidth_hz / 1000000) { - case 8: - case 7: - c->isdbt_sb_segment_count = 3; - Msg.Data[1] = BW_ISDBT_3SEG; - break; - case 6: - c->isdbt_sb_segment_count = 1; - Msg.Data[1] = BW_ISDBT_1SEG; - break; - default: /* Assumes 6 MHZ bw */ - c->isdbt_sb_segment_count = 1; - c->bandwidth_hz = 6000; - Msg.Data[1] = BW_ISDBT_1SEG; - break; - } - break; - default: - sms_info("Segment count %d not supported", c->isdbt_sb_segment_count); - return -EINVAL; - } + if (!c->isdbt_layer_enabled) + c->isdbt_layer_enabled = 7; Msg.Data[0] = c->frequency; + Msg.Data[1] = BW_ISDBT_1SEG; Msg.Data[2] = 12000000; Msg.Data[3] = c->isdbt_sb_segment_idx; + if (c->isdbt_partial_reception) { + if ((type == SMS_PELE || type == SMS_RIO) && + c->isdbt_sb_segment_count > 3) + Msg.Data[1] = BW_ISDBT_13SEG; + else if (c->isdbt_sb_segment_count > 1) + Msg.Data[1] = BW_ISDBT_3SEG; + } else if (type == SMS_PELE || type == SMS_RIO) + Msg.Data[1] = BW_ISDBT_13SEG; + + c->bandwidth_hz = 6000000; + sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, c->frequency, c->isdbt_sb_segment_count, c->isdbt_sb_segment_idx); -- cgit From 0c189fa69ed3d9c08d6f1db845c6fd174c92c429 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 16:34:53 -0300 Subject: [media] siano: add support for LNA on ISDB-T The very same code also exists for DVB-T. Add it for ISDB-T. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 4900aa9e8b7a..864f53e7ca63 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -655,7 +655,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) int board_id = smscore_get_board_id(client->coredev); struct sms_board *board = sms_get_board(board_id); enum sms_device_type_st type = board->type; - + int ret; struct { struct SmsMsgHdr_ST Msg; u32 Data[4]; @@ -695,6 +695,23 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) c->frequency, c->isdbt_sb_segment_count, c->isdbt_sb_segment_idx); + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didn't lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); } -- cgit From b4059095ab281b940b52a6a0e826de25eb50e3c7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 21:58:47 -0300 Subject: [media] siano: use the newer stats message for recent firmwares The old statistics request don't work with newer firmwares. Add a logic to use the newer stats if firmware major is 8. Note that I have only 2 devices here, one with firmware 2.1 (Hauppauge model 55009 Rev B1F7) and another one with firmware 8.1. We may need to adjust the firmware minimal version for the *_EX message variants, as we start finding firmware versions between 2.x and 8.x. This patch was based on Doron Cohen patch: http://patchwork.linuxtv.org/patch/7886/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.h | 103 +++++++++++++++++++ drivers/media/common/siano/smsdvb.c | 177 ++++++++++++++++++++++++++++---- 2 files changed, 260 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 8af94c434352..7925c04e3edc 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -800,6 +800,66 @@ struct SMSHOSTLIB_STATISTICS_ISDBT_ST { u32 SmsToHostTxErrors; /* Total number of transmission errors. */ }; +struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST { + u32 StatisticsType; /* Enumerator identifying the type of the + * structure. Values are the same as + * SMSHOSTLIB_DEVICE_MODES_E + * + * This field MUST always be first in any + * statistics structure */ + + u32 FullSize; /* Total size of the structure returned by the modem. + * If the size requested by the host is smaller than + * FullSize, the struct will be truncated */ + + /* Common parameters */ + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + /* Reception quality */ + s32 SNR; /* dB */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in Hz */ + + /* Transmission parameters */ + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz */ + u32 TransmissionMode; /* ISDB-T transmission mode */ + u32 ModemState; /* 0 - Acquisition, 1 - Locked */ + u32 GuardInterval; /* Guard Interval, 1 divided by value */ + u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ + u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ + u32 NumOfLayers; /* Number of ISDB-T layers in the network */ + + u32 SegmentNumber; /* Segment number for ISDB-Tsb */ + u32 TuneBW; /* Tuned bandwidth - BW_ISDBT_1SEG / BW_ISDBT_3SEG */ + + /* Per-layer information */ + /* Layers A, B and C */ + struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; + /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ + + /* Interface information */ + u32 Reserved1; /* Was SmsToHostTxErrors - obsolete . */ + /* Proprietary information */ + u32 ExtAntenna; /* Obsolete field. */ + u32 ReceptionQuality; + u32 EwsAlertActive; /* Signals if EWS alert is currently on */ + u32 LNAOnOff; /* Internal LNA state: 0: OFF, 1: ON */ + + u32 RfAgcLevel; /* RF AGC Level [linear units], full gain = 65535 (20dB) */ + u32 BbAgcLevel; /* Baseband AGC level [linear units], full gain = 65535 (71.5dB) */ + u32 FwErrorsCounter; /* Application errors - should be always zero */ + u8 FwErrorsHistoryArr[8]; /* Last FW errors IDs - first is most recent, last is oldest */ + + s32 MRC_SNR; /* dB */ + u32 SNRFullRes; /* dB x 65536 */ + u32 Reserved4[4]; +}; + + struct PID_STATISTICS_DATA_S { struct PID_BURST_S { u32 size; @@ -880,6 +940,35 @@ struct RECEPTION_STATISTICS_S { s32 MRC_InBandPwr; /* In band power in dBM */ }; +struct RECEPTION_STATISTICS_EX_S { + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + s32 SNR; /* dB */ + u32 BER; /* Post Viterbi BER [1E-5] */ + u32 BERErrorCount; /* Number of erronous SYNC bits. */ + u32 BERBitCount; /* Total number of SYNC bits. */ + u32 TS_PER; /* Transport stream PER, + 0xFFFFFFFF indicate N/A */ + u32 MFER; /* DVB-H frame error rate in percentage, + 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ + u32 ErrorTSPackets; /* Number of erroneous + transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + + s32 RefDevPPM; + s32 FreqDevHz; + + s32 MRC_SNR; /* dB */ + s32 MRC_RSSI; /* dBm */ + s32 MRC_InBandPwr; /* In band power in dBM */ +}; + /* Statistics information returned as response for * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ @@ -895,6 +984,20 @@ struct SMSHOSTLIB_STATISTICS_DVB_S { struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; }; +/* Statistics information returned as response for + * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ +struct SMSHOSTLIB_STATISTICS_DVB_EX_S { + /* Reception */ + struct RECEPTION_STATISTICS_EX_S ReceptionData; + + /* Transmission parameters */ + struct TRANSMISSION_STATISTICS_S TransmissionData; + + /* Burst parameters, valid only for DVB-H */ +#define SRVM_MAX_PID_FILTERS 8 + struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; +}; + struct SRVM_SIGNAL_STATUS_S { u32 result; u32 snr; diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 864f53e7ca63..dbb807e3a212 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -50,7 +50,7 @@ struct smsdvb_client_t { struct completion tune_done; struct completion stats_done; - struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; + struct SMSHOSTLIB_STATISTICS_DVB_EX_S sms_stat_dvb; int event_fe_state; int event_unc_state; }; @@ -115,12 +115,10 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, } } - -static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData, +static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, struct SMSHOSTLIB_STATISTICS_ST *p) { if (sms_dbg & 2) { - printk(KERN_DEBUG "Reserved = %d", p->Reserved); printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); @@ -132,6 +130,7 @@ static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionDat printk(KERN_DEBUG "RSSI = %d", p->RSSI); printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); printk(KERN_DEBUG "Frequency = %d", p->Frequency); printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); @@ -163,17 +162,24 @@ static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionDat printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); } + /* update reception data */ + pReceptionData->IsRfLocked = p->IsRfLocked; pReceptionData->IsDemodLocked = p->IsDemodLocked; - + pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; + pReceptionData->ModemState = p->ModemState; pReceptionData->SNR = p->SNR; pReceptionData->BER = p->BER; pReceptionData->BERErrorCount = p->BERErrorCount; + pReceptionData->BERBitCount = p->BERBitCount; + pReceptionData->RSSI = p->RSSI; + CORRECT_STAT_RSSI(*pReceptionData); pReceptionData->InBandPwr = p->InBandPwr; + pReceptionData->CarrierOffset = p->CarrierOffset; pReceptionData->ErrorTSPackets = p->ErrorTSPackets; + pReceptionData->TotalTSPackets = p->TotalTSPackets; }; - -static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData, +static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) { int i; @@ -212,18 +218,100 @@ static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionD } } + /* update reception data */ + pReceptionData->IsRfLocked = p->IsRfLocked; pReceptionData->IsDemodLocked = p->IsDemodLocked; + pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; + pReceptionData->ModemState = p->ModemState; + pReceptionData->SNR = p->SNR; + pReceptionData->BER = p->LayerInfo[0].BER; + pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; + pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; + pReceptionData->RSSI = p->RSSI; + CORRECT_STAT_RSSI(*pReceptionData); + pReceptionData->InBandPwr = p->InBandPwr; + pReceptionData->CarrierOffset = p->CarrierOffset; + pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; + pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; + pReceptionData->MFER = 0; + + /* TS PER */ + if ((p->LayerInfo[0].TotalTSPackets + + p->LayerInfo[0].ErrorTSPackets) > 0) { + pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets + * 100) / (p->LayerInfo[0].TotalTSPackets + + p->LayerInfo[0].ErrorTSPackets); + } else { + pReceptionData->TS_PER = 0; + } +} + +static void smsdvb_update_isdbt_stats_ex(struct RECEPTION_STATISTICS_EX_S *pReceptionData, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +{ + int i; + + if (sms_dbg & 2) { + printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); + printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); + printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); + printk(KERN_DEBUG "SNR = %d", p->SNR); + printk(KERN_DEBUG "RSSI = %d", p->RSSI); + printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); + printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); + printk(KERN_DEBUG "Frequency = %d", p->Frequency); + printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); + printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); + printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); + printk(KERN_DEBUG "SystemType = %d", p->SystemType); + printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); + printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); + printk(KERN_DEBUG "SegmentNumber = %d", p->SegmentNumber); + printk(KERN_DEBUG "TuneBW = %d", p->TuneBW); + for (i = 0; i < 3; i++) { + printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); + printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); + printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); + printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); + printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); + printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); + printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); + printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); + printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); + printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); + printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); + printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); + } + } + + /* update reception data */ + pReceptionData->IsRfLocked = p->IsRfLocked; + pReceptionData->IsDemodLocked = p->IsDemodLocked; + pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; + pReceptionData->ModemState = p->ModemState; pReceptionData->SNR = p->SNR; + pReceptionData->BER = p->LayerInfo[0].BER; + pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; + pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; + pReceptionData->RSSI = p->RSSI; + CORRECT_STAT_RSSI(*pReceptionData); pReceptionData->InBandPwr = p->InBandPwr; - pReceptionData->ErrorTSPackets = 0; - pReceptionData->BER = 0; - pReceptionData->BERErrorCount = 0; - for (i = 0; i < 3; i++) { - pReceptionData->BER += p->LayerInfo[i].BER; - pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount; - pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets; + pReceptionData->CarrierOffset = p->CarrierOffset; + pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; + pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; + pReceptionData->MFER = 0; + + /* TS PER */ + if ((p->LayerInfo[0].TotalTSPackets + + p->LayerInfo[0].ErrorTSPackets) > 0) { + pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets + * 100) / (p->LayerInfo[0].TotalTSPackets + + p->LayerInfo[0].ErrorTSPackets); + } else { + pReceptionData->TS_PER = 0; } } @@ -260,21 +348,29 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) break; case MSG_SMS_TRANSMISSION_IND: { + pMsgData++; memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, sizeof(struct TRANSMISSION_STATISTICS_S)); +#if 1 + /* + * FIXME: newer driver doesn't have those fixes + * Are those firmware-specific stuff? + */ + /* Mo need to correct guard interval * (as opposed to old statistics message). */ CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); CORRECT_STAT_TRANSMISSON_MODE( client->sms_stat_dvb.TransmissionData); +#endif is_status_update = true; break; } case MSG_SMS_HO_PER_SLICES_IND: { - struct RECEPTION_STATISTICS_S *pReceptionData = + struct RECEPTION_STATISTICS_EX_S *pReceptionData = &client->sms_stat_dvb.ReceptionData; struct SRVM_SIGNAL_STATUS_S SignalStatusData; @@ -329,7 +425,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt; struct SmsMsgStatisticsInfo_ST dvb; } *p = (void *) (phdr + 1); - struct RECEPTION_STATISTICS_S *pReceptionData = + struct RECEPTION_STATISTICS_EX_S *pReceptionData = &client->sms_stat_dvb.ReceptionData; is_status_update = true; @@ -352,6 +448,34 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) break; } + case MSG_SMS_GET_STATISTICS_EX_RES: { + union { + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST isdbt; + struct SMSHOSTLIB_STATISTICS_ST dvb; + } *p = (void *) (phdr + 1); + struct RECEPTION_STATISTICS_EX_S *pReceptionData = + &client->sms_stat_dvb.ReceptionData; + + is_status_update = true; + + switch (smscore_get_device_mode(client->coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + smsdvb_update_isdbt_stats_ex(pReceptionData, &p->isdbt); + break; + default: + smsdvb_update_dvb_stats(pReceptionData, &p->dvb); + } + if (!pReceptionData->IsDemodLocked) { + pReceptionData->SNR = 0; + pReceptionData->BER = 0; + pReceptionData->BERErrorCount = 0; + pReceptionData->InBandPwr = 0; + pReceptionData->ErrorTSPackets = 0; + } + + break; + } default: sms_info("message not handled"); } @@ -466,10 +590,23 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) { int rc; - struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, - DVBT_BDA_CONTROL_MSG_ID, - HIF_TASK, - sizeof(struct SmsMsgHdr_ST), 0 }; + struct SmsMsgHdr_ST Msg; + + + Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.msgDstId = HIF_TASK; + Msg.msgFlags = 0; + Msg.msgLength = sizeof(Msg); + + /* + * Check for firmware version, to avoid breaking for old cards + */ + if (client->coredev->fw_version >= 0x800) + Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; + else + Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; + + smsendian_handle_tx_message((struct SmsMsgHdr_S *)&Msg); rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stats_done); -- cgit From 347d8f1fa69f4dd021f1ca3d69e1527d95f185e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Mar 2013 22:35:44 -0300 Subject: [media] siano: add new devices to the Siano Driver This patch is based on Doron Cohen's patches: http://patchwork.linuxtv.org/patch/7881/ http://patchwork.linuxtv.org/patch/7888/ http://patchwork.linuxtv.org/patch/7883/ It basically merges the above patches, rebasing them to the macro definitions used upstream, with are different than the ones used by them internally. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.c | 65 ++++++++++++++++++++++++++++++++-- drivers/media/common/siano/sms-cards.h | 8 +++++ drivers/media/mmc/siano/smssdio.c | 10 ++++++ drivers/media/usb/siano/smsusb.c | 31 ++++++++++++++++ 4 files changed, 111 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index 04bb04ca414f..bb6e558b8120 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c @@ -28,43 +28,53 @@ MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))"); static struct sms_board sms_boards[] = { [SMS_BOARD_UNKNOWN] = { .name = "Unknown board", + .type = SMS_UNKNOWN_TYPE, + .default_mode = DEVICE_MODE_NONE, }, [SMS1XXX_BOARD_SIANO_STELLAR] = { .name = "Siano Stellar Digital Receiver", .type = SMS_STELLAR, + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_SIANO_NOVA_A] = { .name = "Siano Nova A Digital Receiver", .type = SMS_NOVA_A0, + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_SIANO_NOVA_B] = { .name = "Siano Nova B Digital Receiver", .type = SMS_NOVA_B0, + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_SIANO_VEGA] = { .name = "Siano Vega Digital Receiver", .type = SMS_VEGA, + .default_mode = DEVICE_MODE_CMMB, }, [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = { .name = "Hauppauge Catamount", .type = SMS_STELLAR, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = { .name = "Hauppauge Okemo-A", .type = SMS_NOVA_A0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = { .name = "Hauppauge Okemo-B", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { .name = "Hauppauge WinTV MiniStick", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, .rc_codes = RC_MAP_HAUPPAUGE, .board_cfg.leds_power = 26, .board_cfg.led0 = 27, @@ -78,6 +88,7 @@ static struct sms_board sms_boards[] = { .name = "Hauppauge WinTV MiniCard", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, .lna_ctrl = 29, .board_cfg.foreign_lna0_ctrl = 29, .rf_switch = 17, @@ -87,17 +98,64 @@ static struct sms_board sms_boards[] = { .name = "Hauppauge WinTV MiniCard", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .default_mode = DEVICE_MODE_DVBT_BDA, .lna_ctrl = -1, }, [SMS1XXX_BOARD_SIANO_NICE] = { - /* 11 */ .name = "Siano Nice Digital Receiver", .type = SMS_NOVA_B0, + .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_SIANO_VENICE] = { - /* 12 */ .name = "Siano Venice Digital Receiver", .type = SMS_VEGA, + .default_mode = DEVICE_MODE_CMMB, + }, + [SMS1XXX_BOARD_SIANO_STELLAR_ROM] = { + .name = "Siano Stellar Digital Receiver ROM", + .type = SMS_STELLAR, + .default_mode = DEVICE_MODE_DVBT_BDA, + .intf_num = 1, + }, + [SMS1XXX_BOARD_ZTE_DVB_DATA_CARD] = { + .name = "ZTE Data Card Digital Receiver", + .type = SMS_NOVA_B0, + .default_mode = DEVICE_MODE_DVBT_BDA, + .intf_num = 5, + .mtu = 15792, + }, + [SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD] = { + .name = "ONDA Data Card Digital Receiver", + .type = SMS_NOVA_B0, + .default_mode = DEVICE_MODE_DVBT_BDA, + .intf_num = 6, + .mtu = 15792, + }, + [SMS1XXX_BOARD_SIANO_MING] = { + .name = "Siano Ming Digital Receiver", + .type = SMS_MING, + .default_mode = DEVICE_MODE_CMMB, + }, + [SMS1XXX_BOARD_SIANO_PELE] = { + .name = "Siano Pele Digital Receiver", + .type = SMS_PELE, + .default_mode = DEVICE_MODE_ISDBT_BDA, + }, + [SMS1XXX_BOARD_SIANO_RIO] = { + .name = "Siano Rio Digital Receiver", + .type = SMS_RIO, + .default_mode = DEVICE_MODE_ISDBT_BDA, + }, + [SMS1XXX_BOARD_SIANO_DENVER_1530] = { + .name = "Siano Denver (ATSC-M/H) Digital Receiver", + .type = SMS_DENVER_1530, + .default_mode = DEVICE_MODE_ATSC, + .crystal = 2400, + }, + [SMS1XXX_BOARD_SIANO_DENVER_2160] = { + .name = "Siano Denver (TDMB) Digital Receiver", + .type = SMS_DENVER_2160, + .default_mode = DEVICE_MODE_DAB_TDMB, }, }; @@ -119,7 +177,8 @@ static inline void sms_gpio_assign_11xx_default_led_config( } int sms_board_event(struct smscore_device_t *coredev, - enum SMS_BOARD_EVENTS gevent) { + enum SMS_BOARD_EVENTS gevent) +{ struct smscore_config_gpio MyGpioConfig; sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h index 9f1861aa71c9..c63b544c49c5 100644 --- a/drivers/media/common/siano/sms-cards.h +++ b/drivers/media/common/siano/sms-cards.h @@ -37,6 +37,14 @@ #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 #define SMS1XXX_BOARD_SIANO_NICE 11 #define SMS1XXX_BOARD_SIANO_VENICE 12 +#define SMS1XXX_BOARD_SIANO_STELLAR_ROM 13 +#define SMS1XXX_BOARD_ZTE_DVB_DATA_CARD 14 +#define SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD 15 +#define SMS1XXX_BOARD_SIANO_MING 16 +#define SMS1XXX_BOARD_SIANO_PELE 17 +#define SMS1XXX_BOARD_SIANO_RIO 18 +#define SMS1XXX_BOARD_SIANO_DENVER_1530 19 +#define SMS1XXX_BOARD_SIANO_DENVER_2160 20 struct sms_board_gpio_cfg { int lna_vhf_exist; diff --git a/drivers/media/mmc/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c index 15d34935e00b..c96da47bece5 100644 --- a/drivers/media/mmc/siano/smssdio.c +++ b/drivers/media/mmc/siano/smssdio.c @@ -61,6 +61,16 @@ static const struct sdio_device_id smssdio_ids[] = { .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE), .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, 0x302), + .driver_data = SMS1XXX_BOARD_SIANO_MING}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, 0x500), + .driver_data = SMS1XXX_BOARD_SIANO_PELE}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, 0x600), + .driver_data = SMS1XXX_BOARD_SIANO_RIO}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, 0x700), + .driver_data = SMS1XXX_BOARD_SIANO_DENVER_2160}, + {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, 0x800), + .driver_data = SMS1XXX_BOARD_SIANO_DENVER_1530}, { /* end: all zeroes */ }, }; diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index a31bf74a5957..751c0d6d98b8 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -441,6 +441,7 @@ static int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); + char devpath[32]; int i, rc; sms_info("interface number %d", @@ -485,6 +486,16 @@ static int smsusb_probe(struct usb_interface *intf, return -ENODEV; } + if (id->driver_info == SMS1XXX_BOARD_SIANO_STELLAR_ROM) { + sms_info("stellar device was found."); + snprintf(devpath, sizeof(devpath), "usb\\%d-%s", + udev->bus->busnum, udev->devpath); + sms_info("stellar device was found."); + return smsusb1_load_firmware( + udev, smscore_registry_getmode(devpath), + id->driver_info); + } + rc = smsusb_init_device(intf, id->driver_info); sms_info("rc %d", rc); sms_board_load_modules(id->driver_info); @@ -602,6 +613,26 @@ static const struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xf5a0), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x187f, 0x0202), + .driver_info = SMS1XXX_BOARD_SIANO_NICE }, + { USB_DEVICE(0x187f, 0x0301), + .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, + { USB_DEVICE(0x187f, 0x0302), + .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, + { USB_DEVICE(0x187f, 0x0310), + .driver_info = SMS1XXX_BOARD_SIANO_MING }, + { USB_DEVICE(0x187f, 0x0500), + .driver_info = SMS1XXX_BOARD_SIANO_PELE }, + { USB_DEVICE(0x187f, 0x0600), + .driver_info = SMS1XXX_BOARD_SIANO_RIO }, + { USB_DEVICE(0x187f, 0x0700), + .driver_info = SMS1XXX_BOARD_SIANO_DENVER_2160 }, + { USB_DEVICE(0x187f, 0x0800), + .driver_info = SMS1XXX_BOARD_SIANO_DENVER_1530 }, + { USB_DEVICE(0x19D2, 0x0086), + .driver_info = SMS1XXX_BOARD_ZTE_DVB_DATA_CARD }, + { USB_DEVICE(0x19D2, 0x0078), + .driver_info = SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD }, { } /* Terminating entry */ }; -- cgit From dfbf021c9e6c9de2296eae7b4e89148e7f68b28e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Mar 2013 20:48:42 -0300 Subject: [media] siano: Configure board's mtu and xtal Backported from Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7889/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 67d0319dc013..6b53367f74dc 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -824,6 +824,57 @@ static int smscore_init_ir(struct smscore_device_t *coredev) return 0; } +/** + * configures device features according to board configuration structure. + * + * @param coredev pointer to a coredev object returned by + * smscore_register_device + * + * @return 0 on success, <0 on error. + */ +int smscore_configure_board(struct smscore_device_t *coredev) +{ + struct sms_board *board; + + board = sms_get_board(coredev->board_id); + if (!board) { + sms_err("no board configuration exist."); + return -EINVAL; + } + + if (board->mtu) { + struct SmsMsgData_ST MtuMsg; + sms_debug("set max transmit unit %d", board->mtu); + + MtuMsg.xMsgHeader.msgSrcId = 0; + MtuMsg.xMsgHeader.msgDstId = HIF_TASK; + MtuMsg.xMsgHeader.msgFlags = 0; + MtuMsg.xMsgHeader.msgType = MSG_SMS_SET_MAX_TX_MSG_LEN_REQ; + MtuMsg.xMsgHeader.msgLength = sizeof(MtuMsg); + MtuMsg.msgData[0] = board->mtu; + + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&MtuMsg); + coredev->sendrequest_handler(coredev->context, &MtuMsg, + sizeof(MtuMsg)); + } + + if (board->crystal) { + struct SmsMsgData_ST CrysMsg; + sms_debug("set crystal value %d", board->crystal); + + SMS_INIT_MSG(&CrysMsg.xMsgHeader, + MSG_SMS_NEW_CRYSTAL_REQ, + sizeof(CrysMsg)); + CrysMsg.msgData[0] = board->crystal; + + smsendian_handle_tx_message((struct SmsMsgHdr_S *)&CrysMsg); + coredev->sendrequest_handler(coredev->context, &CrysMsg, + sizeof(CrysMsg)); + } + + return 0; +} + /** * sets initial device mode and notifies client hotplugs that device is ready * @@ -840,6 +891,11 @@ int smscore_start_device(struct smscore_device_t *coredev) sms_info("set device mode faile , rc %d", rc); return rc; } + rc = smscore_configure_board(coredev); + if (rc < 0) { + sms_info("configure board failed , rc %d", rc); + return rc; + } kmutex_lock(&g_smscore_deviceslock); -- cgit From fe802fd92d6abd1fce2ae8d03a073807d25e9453 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 10:24:38 -0300 Subject: [media] siano: call MSG_SMS_INIT_DEVICE_REQ Newer firmwares seem to require an init device message. Apply such change from Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7889/ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 43 ++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 6b53367f74dc..9379ea7f8152 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1278,6 +1278,42 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, return fw[mode]; } +/** + * send init device request and wait for response + * + * @param coredev pointer to a coredev object returned by + * smscore_register_device + * @param mode requested mode of operation + * + * @return 0 on success, <0 on error. + */ +int smscore_init_device(struct smscore_device_t *coredev, int mode) +{ + void *buffer; + struct SmsMsgData_ST *msg; + int rc = 0; + + buffer = kmalloc(sizeof(struct SmsMsgData_ST) + + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (!buffer) { + sms_err("Could not allocate buffer for init device message."); + return -ENOMEM; + } + + msg = (struct SmsMsgData_ST *)SMS_ALIGN_ADDRESS(buffer); + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, + sizeof(struct SmsMsgData_ST)); + msg->msgData[0] = mode; + + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg); + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->xMsgHeader. msgLength, + &coredev->init_device_done); + + kfree(buffer); + return rc; +} + /** * calls device handler to change mode of operation * NOTE: stellar/usb may disconnect when changing mode @@ -1340,8 +1376,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) sms_info("mode %d is already supported by running firmware", mode); } + if (coredev->fw_version >= 0x800) { + rc = smscore_init_device(coredev, mode); + if (rc < 0) + sms_err("device init failed, rc %d.", rc); + } } else { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_MAX) { sms_err("invalid mode specified %d", mode); return -EINVAL; } -- cgit From 80ccb51a0f970ab0935a8be70b677ecbcdf74e3e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 11:34:56 -0300 Subject: [media] siano: simplify message endianness logic Currently, every time a message is sent or received, the endiannes need to be fixed on big endian machines. This is currently done on every call to the send API, and on every msg reception logic. Instead of doing that, move it to the send/receive functions. That simplifies the logic and avoids the risk of forgetting to fix it somewhere. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 14 -------------- drivers/media/common/siano/smsdvb.c | 8 -------- drivers/media/mmc/siano/smssdio.c | 3 +++ drivers/media/usb/siano/smsusb.c | 9 ++++++--- 4 files changed, 9 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 9379ea7f8152..8c576a6e3829 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -37,7 +37,6 @@ #include "smscoreapi.h" #include "sms-cards.h" #include "smsir.h" -#include "smsendian.h" static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); @@ -807,8 +806,6 @@ static int smscore_init_ir(struct smscore_device_t *coredev) msg->msgData[0] = coredev->ir.controller; msg->msgData[1] = coredev->ir.timeout; - smsendian_handle_tx_message( - (struct SmsMsgHdr_ST2 *)msg); rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader. msgLength, &coredev->ir_init_done); @@ -853,7 +850,6 @@ int smscore_configure_board(struct smscore_device_t *coredev) MtuMsg.xMsgHeader.msgLength = sizeof(MtuMsg); MtuMsg.msgData[0] = board->mtu; - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&MtuMsg); coredev->sendrequest_handler(coredev->context, &MtuMsg, sizeof(MtuMsg)); } @@ -867,7 +863,6 @@ int smscore_configure_board(struct smscore_device_t *coredev) sizeof(CrysMsg)); CrysMsg.msgData[0] = board->crystal; - smsendian_handle_tx_message((struct SmsMsgHdr_S *)&CrysMsg); coredev->sendrequest_handler(coredev->context, &CrysMsg, sizeof(CrysMsg)); } @@ -989,7 +984,6 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, /* Entry point */ msg->msgData[1] = firmware->Length; msg->msgData[2] = 0; /* Regular checksum*/ - smsendian_handle_tx_message(msg); rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->data_validity_done); @@ -1013,14 +1007,12 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, TriggerMsg->msgData[3] = 0; /* Parameter */ TriggerMsg->msgData[4] = 4; /* Task ID */ - smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); } else { SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ, sizeof(struct SmsMsgHdr_ST)); - smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = coredev->sendrequest_handler(coredev->context, msg, msg->xMsgHeader.msgLength); } @@ -1305,7 +1297,6 @@ int smscore_init_device(struct smscore_device_t *coredev, int mode) sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg); rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader. msgLength, &coredev->init_device_done); @@ -1526,8 +1517,6 @@ void smscore_onresponse(struct smscore_device_t *coredev, rc = client->onresponse_handler(client->context, cb); if (rc < 0) { - smsendian_handle_rx_message((struct SmsMsgData_ST *)phdr); - switch (phdr->msgType) { case MSG_SMS_ISDBT_TUNE_RES: break; @@ -2008,7 +1997,6 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, pMsg->msgData[5] = 0; } - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, &coredev->gpio_configuration_done); @@ -2058,7 +2046,6 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, pMsg->msgData[1] = NewLevel; /* Send message to SMS */ - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, &coredev->gpio_set_level_done); @@ -2107,7 +2094,6 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, pMsg->msgData[1] = 0; /* Send message to SMS */ - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, &coredev->gpio_get_level_done); diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index dbb807e3a212..6335574e9342 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -29,7 +29,6 @@ along with this program. If not, see . #include "dvb_frontend.h" #include "smscoreapi.h" -#include "smsendian.h" #include "sms-cards.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -324,8 +323,6 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ bool is_status_update = false; - smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); - switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), @@ -545,7 +542,6 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); } @@ -566,7 +562,6 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); } @@ -577,7 +572,6 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, { int rc; - smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer); rc = smsclient_sendrequest(client->smsclient, buffer, size); if (rc < 0) return rc; @@ -606,8 +600,6 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) else Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; - smsendian_handle_tx_message((struct SmsMsgHdr_S *)&Msg); - rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stats_done); diff --git a/drivers/media/mmc/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c index c96da47bece5..8834c435acae 100644 --- a/drivers/media/mmc/siano/smssdio.c +++ b/drivers/media/mmc/siano/smssdio.c @@ -43,6 +43,7 @@ #include "smscoreapi.h" #include "sms-cards.h" +#include "smsendian.h" /* Registers */ @@ -97,6 +98,7 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size) sdio_claim_host(smsdev->func); + smsendian_handle_tx_message((struct SmsMsgData_ST *) buffer); while (size >= smsdev->func->cur_blksize) { ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, buffer, smsdev->func->cur_blksize); @@ -231,6 +233,7 @@ static void smssdio_interrupt(struct sdio_func *func) cb->size = hdr->msgLength; cb->offset = 0; + smsendian_handle_rx_message((struct SmsMsgData_ST *) cb->p); smscore_onresponse(smsdev->coredev, cb); } diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 751c0d6d98b8..acd3d1e82e03 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -129,6 +129,8 @@ static void smsusb_onresponse(struct urb *urb) smscore_translate_msg(phdr->msgType), phdr->msgType, phdr->msgLength); + smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); + smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; } else { @@ -207,13 +209,14 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; int dummy; + if (dev->state != SMSUSB_ACTIVE) + return -ENOENT; + sms_debug("sending %s(%d) size: %d", smscore_translate_msg(phdr->msgType), phdr->msgType, phdr->msgLength); - if (dev->state != SMSUSB_ACTIVE) - return -ENOENT; - + smsendian_handle_tx_message((struct SmsMsgData_ST *) phdr); smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); -- cgit From eab0fa0f04317c7bb50f87d6b410d8ad6e2c2888 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 12:05:58 -0300 Subject: [media] siano: split get_frontend into per-std functions Instead of handling both DVB-T and ISDB-T at the same get_frontend function, break it intow one function per-delivery system. That makes the code clearer as we start to add support for DVBv5 statistics, and for ISDB-T get frontend stuff. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 229 +++++++++++++++++++----------------- 1 file changed, 124 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 6335574e9342..1d6b8dfa0808 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -863,131 +863,150 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) } } -static int smsdvb_get_frontend(struct dvb_frontend *fe) +static int smsdvb_get_frontend_dvb(struct dvb_frontend *fe) { struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; struct TRANSMISSION_STATISTICS_S *td = &client->sms_stat_dvb.TransmissionData; - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - fep->frequency = td->Frequency; - - switch (td->Bandwidth) { - case 6: - fep->bandwidth_hz = 6000000; - break; - case 7: - fep->bandwidth_hz = 7000000; - break; - case 8: - fep->bandwidth_hz = 8000000; - break; - } + fep->frequency = td->Frequency; - switch (td->TransmissionMode) { - case 2: - fep->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 8: - fep->transmission_mode = TRANSMISSION_MODE_8K; - } + switch (td->Bandwidth) { + case 6: + fep->bandwidth_hz = 6000000; + break; + case 7: + fep->bandwidth_hz = 7000000; + break; + case 8: + fep->bandwidth_hz = 8000000; + break; + } - switch (td->GuardInterval) { - case 0: - fep->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - fep->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - fep->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - fep->guard_interval = GUARD_INTERVAL_1_4; - break; - } + switch (td->TransmissionMode) { + case 2: + fep->transmission_mode = TRANSMISSION_MODE_2K; + break; + case 8: + fep->transmission_mode = TRANSMISSION_MODE_8K; + } - switch (td->CodeRate) { - case 0: - fep->code_rate_HP = FEC_1_2; - break; - case 1: - fep->code_rate_HP = FEC_2_3; - break; - case 2: - fep->code_rate_HP = FEC_3_4; - break; - case 3: - fep->code_rate_HP = FEC_5_6; - break; - case 4: - fep->code_rate_HP = FEC_7_8; - break; - } + switch (td->GuardInterval) { + case 0: + fep->guard_interval = GUARD_INTERVAL_1_32; + break; + case 1: + fep->guard_interval = GUARD_INTERVAL_1_16; + break; + case 2: + fep->guard_interval = GUARD_INTERVAL_1_8; + break; + case 3: + fep->guard_interval = GUARD_INTERVAL_1_4; + break; + } - switch (td->LPCodeRate) { - case 0: - fep->code_rate_LP = FEC_1_2; - break; - case 1: - fep->code_rate_LP = FEC_2_3; - break; - case 2: - fep->code_rate_LP = FEC_3_4; - break; - case 3: - fep->code_rate_LP = FEC_5_6; - break; - case 4: - fep->code_rate_LP = FEC_7_8; - break; - } + switch (td->CodeRate) { + case 0: + fep->code_rate_HP = FEC_1_2; + break; + case 1: + fep->code_rate_HP = FEC_2_3; + break; + case 2: + fep->code_rate_HP = FEC_3_4; + break; + case 3: + fep->code_rate_HP = FEC_5_6; + break; + case 4: + fep->code_rate_HP = FEC_7_8; + break; + } - switch (td->Constellation) { - case 0: - fep->modulation = QPSK; - break; - case 1: - fep->modulation = QAM_16; - break; - case 2: - fep->modulation = QAM_64; - break; - } + switch (td->LPCodeRate) { + case 0: + fep->code_rate_LP = FEC_1_2; + break; + case 1: + fep->code_rate_LP = FEC_2_3; + break; + case 2: + fep->code_rate_LP = FEC_3_4; + break; + case 3: + fep->code_rate_LP = FEC_5_6; + break; + case 4: + fep->code_rate_LP = FEC_7_8; + break; + } - switch (td->Hierarchy) { - case 0: - fep->hierarchy = HIERARCHY_NONE; - break; - case 1: - fep->hierarchy = HIERARCHY_1; - break; - case 2: - fep->hierarchy = HIERARCHY_2; - break; - case 3: - fep->hierarchy = HIERARCHY_4; - break; - } + switch (td->Constellation) { + case 0: + fep->modulation = QPSK; + break; + case 1: + fep->modulation = QAM_16; + break; + case 2: + fep->modulation = QAM_64; + break; + } - fep->inversion = INVERSION_AUTO; + switch (td->Hierarchy) { + case 0: + fep->hierarchy = HIERARCHY_NONE; break; + case 1: + fep->hierarchy = HIERARCHY_1; + break; + case 2: + fep->hierarchy = HIERARCHY_2; + break; + case 3: + fep->hierarchy = HIERARCHY_4; + break; + } + + fep->inversion = INVERSION_AUTO; + + return 0; +} + +static int smsdvb_get_frontend_isdb(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + struct TRANSMISSION_STATISTICS_S *td = + &client->sms_stat_dvb.TransmissionData; + + fep->frequency = td->Frequency; + fep->bandwidth_hz = 6000000; + /* todo: retrive the other parameters */ + + return 0; +} + +static int smsdvb_get_frontend(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + struct smscore_device_t *coredev = client->coredev; + + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_DVBT: + case DEVICE_MODE_DVBT_BDA: + return smsdvb_get_frontend_dvb(fe); case DEVICE_MODE_ISDBT: case DEVICE_MODE_ISDBT_BDA: - fep->frequency = td->Frequency; - fep->bandwidth_hz = 6000000; - /* todo: retrive the other parameters */ - break; + return smsdvb_get_frontend_isdb(fe); default: return -EINVAL; } - - return 0; } static int smsdvb_init(struct dvb_frontend *fe) -- cgit From ff702eb8d9c8ca293e7f0343dd38b718d58815b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 15:54:46 -0300 Subject: [media] siano: split debug logic from the status update routine It is confusing to merge both status updates with debug stuff. Also, it is a better idea to move those status updates to debugfs, instead of doing a large amount of printk's like that. So, break them into a separate block of routines. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 250 +++++++++++++++++++----------------- 1 file changed, 135 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 1d6b8dfa0808..04544f591df5 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -61,6 +61,136 @@ static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); +static void smsdvb_print_dvb_stats(struct SMSHOSTLIB_STATISTICS_ST *p) +{ + if (!(sms_dbg & 2)) + return; + + printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); + printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); + printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); + printk(KERN_DEBUG "SNR = %d", p->SNR); + printk(KERN_DEBUG "BER = %d", p->BER); + printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC); + printk(KERN_DEBUG "TS_PER = %d", p->TS_PER); + printk(KERN_DEBUG "MFER = %d", p->MFER); + printk(KERN_DEBUG "RSSI = %d", p->RSSI); + printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); + printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); + printk(KERN_DEBUG "Frequency = %d", p->Frequency); + printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); + printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); + printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); + printk(KERN_DEBUG "CodeRate = %d", p->CodeRate); + printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate); + printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy); + printk(KERN_DEBUG "Constellation = %d", p->Constellation); + printk(KERN_DEBUG "BurstSize = %d", p->BurstSize); + printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration); + printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime); + printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime); + printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows); + printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols); + printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols); + printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets); + printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets); + printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs); + printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs); + printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs); + printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount); + printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount); + printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); + printk(KERN_DEBUG "PreBER = %d", p->PreBER); + printk(KERN_DEBUG "CellId = %d", p->CellId); + printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP); + printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP); + printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); +} + +static void smsdvb_print_isdb_stats(struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) +{ + int i; + + if (!(sms_dbg & 2)) + return; + + printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); + printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); + printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); + printk(KERN_DEBUG "SNR = %d", p->SNR); + printk(KERN_DEBUG "RSSI = %d", p->RSSI); + printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); + printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); + printk(KERN_DEBUG "Frequency = %d", p->Frequency); + printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); + printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); + printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); + printk(KERN_DEBUG "SystemType = %d", p->SystemType); + printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); + printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); + printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); + + for (i = 0; i < 3; i++) { + printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); + printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); + printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); + printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); + printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); + printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); + printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); + printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); + printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); + printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); + printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); + printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); + } +} + +static void +smsdvb_print_isdb_stats_ex(struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +{ + int i; + + if (!(sms_dbg & 2)) + return; + + printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); + printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); + printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); + printk(KERN_DEBUG "SNR = %d", p->SNR); + printk(KERN_DEBUG "RSSI = %d", p->RSSI); + printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); + printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); + printk(KERN_DEBUG "Frequency = %d", p->Frequency); + printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); + printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); + printk(KERN_DEBUG "ModemState = %d", p->ModemState); + printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); + printk(KERN_DEBUG "SystemType = %d", p->SystemType); + printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); + printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); + printk(KERN_DEBUG "SegmentNumber = %d", p->SegmentNumber); + printk(KERN_DEBUG "TuneBW = %d", p->TuneBW); + + for (i = 0; i < 3; i++) { + printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); + printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); + printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); + printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); + printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); + printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); + printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); + printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); + printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); + printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); + printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); + printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); + } +} + /* Events that may come from DVB v3 adapter */ static void sms_board_dvb3_event(struct smsdvb_client_t *client, enum SMS_DVB3_EVENTS event) { @@ -115,51 +245,9 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, } static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, - struct SMSHOSTLIB_STATISTICS_ST *p) + struct SMSHOSTLIB_STATISTICS_ST *p) { - if (sms_dbg & 2) { - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "BER = %d", p->BER); - printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC); - printk(KERN_DEBUG "TS_PER = %d", p->TS_PER); - printk(KERN_DEBUG "MFER = %d", p->MFER); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "CodeRate = %d", p->CodeRate); - printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate); - printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy); - printk(KERN_DEBUG "Constellation = %d", p->Constellation); - printk(KERN_DEBUG "BurstSize = %d", p->BurstSize); - printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration); - printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime); - printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime); - printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows); - printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols); - printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols); - printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets); - printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets); - printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs); - printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs); - printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs); - printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount); - printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); - printk(KERN_DEBUG "PreBER = %d", p->PreBER); - printk(KERN_DEBUG "CellId = %d", p->CellId); - printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP); - printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP); - printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); - } + smsdvb_print_dvb_stats(p); /* update reception data */ pReceptionData->IsRfLocked = p->IsRfLocked; @@ -179,43 +267,9 @@ static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_EX_S *pReception }; static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, - struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) + struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) { - int i; - - if (sms_dbg & 2) { - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "SystemType = %d", p->SystemType); - printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); - printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); - - for (i = 0; i < 3; i++) { - printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); - printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); - printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); - printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); - printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); - printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); - printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); - printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); - printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); - printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); - printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); - printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); - } - } + smsdvb_print_isdb_stats(p); /* update reception data */ pReceptionData->IsRfLocked = p->IsRfLocked; @@ -249,41 +303,7 @@ static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_EX_S *pRecepti static void smsdvb_update_isdbt_stats_ex(struct RECEPTION_STATISTICS_EX_S *pReceptionData, struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) { - int i; - - if (sms_dbg & 2) { - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "SystemType = %d", p->SystemType); - printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); - printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); - printk(KERN_DEBUG "SegmentNumber = %d", p->SegmentNumber); - printk(KERN_DEBUG "TuneBW = %d", p->TuneBW); - for (i = 0; i < 3; i++) { - printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); - printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); - printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); - printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); - printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); - printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); - printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); - printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); - printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); - printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); - printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); - printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); - } - } + smsdvb_print_isdb_stats_ex(p); /* update reception data */ pReceptionData->IsRfLocked = p->IsRfLocked; -- cgit From d42f1cb25334bbcddf213a00bb67083414027933 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 19:26:28 -0300 Subject: [media] siano: Convert it to report DVBv5 stats While this frontend provides a nice set of statistics, the way it is currently reported to userspace is poor. Worse than that, instead of using quality indicators that range from 0 to 65535, as expected by userspace, most indicators range from 0 to 100. Improve it by using DVBv5 statistics API. The legacy indicators are still reported using the very same old way, but they're now using a proper range (0 to 65535 for quality indicadors; 0.1 dB for SNR). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 826 ++++++++++++++++++++---------------- 1 file changed, 468 insertions(+), 358 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 04544f591df5..a5f52721154c 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -49,7 +49,10 @@ struct smsdvb_client_t { struct completion tune_done; struct completion stats_done; - struct SMSHOSTLIB_STATISTICS_DVB_EX_S sms_stat_dvb; + int last_per; + + int legacy_ber, legacy_per; + int event_fe_state; int event_unc_state; }; @@ -61,6 +64,82 @@ static int sms_dbg; module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); +/* + * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S. + * It was obtained by comparing the way it was filled by the original code + */ +struct RECEPTION_STATISTICS_PER_SLICES_S { + u32 result; + u32 snr; + s32 inBandPower; + u32 tsPackets; + u32 etsPackets; + u32 constellation; + u32 hpCode; + u32 tpsSrvIndLP; + u32 tpsSrvIndHP; + u32 cellId; + u32 reason; + u32 requestId; + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + + u32 BER; /* Post Viterbi BER [1E-5] */ + s32 RSSI; /* dBm */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ + + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + + u32 BERBitCount; /* Total number of SYNC bits. */ + u32 BERErrorCount; /* Number of erronous SYNC bits. */ + + s32 MRC_SNR; /* dB */ + s32 MRC_InBandPwr; /* In band power in dBM */ + s32 MRC_RSSI; /* dBm */ +}; + +u32 sms_to_bw_table[] = { + [BW_8_MHZ] = 8000000, + [BW_7_MHZ] = 7000000, + [BW_6_MHZ] = 6000000, + [BW_5_MHZ] = 5000000, + [BW_2_MHZ] = 2000000, + [BW_1_5_MHZ] = 1500000, + [BW_ISDBT_1SEG] = 6000000, + [BW_ISDBT_3SEG] = 6000000, + [BW_ISDBT_13SEG] = 6000000, +}; + +u32 sms_to_guard_interval_table[] = { + [0] = GUARD_INTERVAL_1_32, + [1] = GUARD_INTERVAL_1_16, + [2] = GUARD_INTERVAL_1_8, + [3] = GUARD_INTERVAL_1_4, +}; + +u32 sms_to_code_rate_table[] = { + [0] = FEC_1_2, + [1] = FEC_2_3, + [2] = FEC_3_4, + [3] = FEC_5_6, + [4] = FEC_7_8, +}; + + +u32 sms_to_hierarchy_table[] = { + [0] = HIERARCHY_NONE, + [1] = HIERARCHY_1, + [2] = HIERARCHY_2, + [3] = HIERARCHY_4, +}; + +u32 sms_to_modulation_table[] = { + [0] = QPSK, + [1] = QAM_16, + [2] = QAM_64, + [3] = DQPSK, +}; + static void smsdvb_print_dvb_stats(struct SMSHOSTLIB_STATISTICS_ST *p) { if (!(sms_dbg & 2)) @@ -244,93 +323,350 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, } } -static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, +static void smsdvb_stats_not_ready(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + struct smscore_device_t *coredev = client->coredev; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int i, n_layers; + + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + n_layers = 4; + default: + n_layers = 1; + } + + /* Fill the length of each status counter */ + + /* Only global stats */ + c->strength.len = 1; + c->cnr.len = 1; + + /* Per-layer stats */ + c->post_bit_error.len = n_layers; + c->post_bit_count.len = n_layers; + c->block_error.len = n_layers; + c->block_count.len = n_layers; + + /* Signal is always available */ + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = 0; + + /* Put all of them at FE_SCALE_NOT_AVAILABLE */ + for (i = 0; i < n_layers; i++) { + c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + } +} + +static inline int sms_to_mode(u32 mode) +{ + switch (mode) { + case 2: + return TRANSMISSION_MODE_2K; + case 4: + return TRANSMISSION_MODE_4K; + case 8: + return TRANSMISSION_MODE_8K; + } + return TRANSMISSION_MODE_AUTO; +} + +static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) +{ + if (is_demod_locked) + return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + + if (is_rf_locked) + return FE_HAS_SIGNAL | FE_HAS_CARRIER; + + return 0; +} + + +#define convert_from_table(value, table, defval) ({ \ + u32 __ret; \ + if (value < ARRAY_SIZE(table)) \ + __ret = table[value]; \ + else \ + __ret = defval; \ + __ret; \ +}) + +#define sms_to_bw(value) \ + convert_from_table(value, sms_to_bw_table, 0); + +#define sms_to_guard_interval(value) \ + convert_from_table(value, sms_to_guard_interval_table, \ + GUARD_INTERVAL_AUTO); + +#define sms_to_code_rate(value) \ + convert_from_table(value, sms_to_code_rate_table, \ + FEC_NONE); + +#define sms_to_hierarchy(value) \ + convert_from_table(value, sms_to_hierarchy_table, \ + FEC_NONE); + +#define sms_to_modulation(value) \ + convert_from_table(value, sms_to_modulation_table, \ + FEC_NONE); + +static void smsdvb_update_tx_params(struct smsdvb_client_t *client, + struct TRANSMISSION_STATISTICS_S *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->code_rate_HP = sms_to_code_rate(p->CodeRate); + c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); + c->hierarchy = sms_to_hierarchy(p->Hierarchy); + c->modulation = sms_to_modulation(p->Constellation); +} + +static void smsdvb_update_per_slices(struct smsdvb_client_t *client, + struct RECEPTION_STATISTICS_PER_SLICES_S *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); + c->modulation = sms_to_modulation(p->constellation); + + /* TS PER */ + client->last_per = c->block_error.stat[0].uvalue; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += p->etsPackets; + c->block_count.stat[0].uvalue += p->etsPackets + p->tsPackets; + + /* BER */ + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += p->BERErrorCount; + c->post_bit_count.stat[0].uvalue += p->BERBitCount; + + /* Legacy PER/BER */ + client->legacy_per = (p->etsPackets * 65535) / + (p->tsPackets + p->etsPackets); + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->snr * 1000; +} + +static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, struct SMSHOSTLIB_STATISTICS_ST *p) { + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + smsdvb_print_dvb_stats(p); + client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); + + /* Update DVB modulation parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->code_rate_HP = sms_to_code_rate(p->CodeRate); + c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); + c->hierarchy = sms_to_hierarchy(p->Hierarchy); + c->modulation = sms_to_modulation(p->Constellation); + /* update reception data */ - pReceptionData->IsRfLocked = p->IsRfLocked; - pReceptionData->IsDemodLocked = p->IsDemodLocked; - pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; - pReceptionData->ModemState = p->ModemState; - pReceptionData->SNR = p->SNR; - pReceptionData->BER = p->BER; - pReceptionData->BERErrorCount = p->BERErrorCount; - pReceptionData->BERBitCount = p->BERBitCount; - pReceptionData->RSSI = p->RSSI; - CORRECT_STAT_RSSI(*pReceptionData); - pReceptionData->InBandPwr = p->InBandPwr; - pReceptionData->CarrierOffset = p->CarrierOffset; - pReceptionData->ErrorTSPackets = p->ErrorTSPackets; - pReceptionData->TotalTSPackets = p->TotalTSPackets; + c->lna = p->IsExternalLNAOn ? 1 : 0; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + /* TS PER */ + client->last_per = c->block_error.stat[0].uvalue; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += p->ErrorTSPackets; + c->block_count.stat[0].uvalue += p->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += p->BERErrorCount; + c->post_bit_count.stat[0].uvalue += p->BERBitCount; + + /* Legacy PER/BER */ + client->legacy_ber = p->BER; }; -static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, +static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) { + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; + int i, n_layers; + smsdvb_print_isdb_stats(p); + /* Update ISDB-T transmission parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->isdbt_partial_reception = p->PartialReception ? 1 : 0; + n_layers = p->NumOfLayers; + if (n_layers < 1) + n_layers = 1; + if (n_layers > 3) + n_layers = 3; + c->isdbt_layer_enabled = 0; + /* update reception data */ - pReceptionData->IsRfLocked = p->IsRfLocked; - pReceptionData->IsDemodLocked = p->IsDemodLocked; - pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; - pReceptionData->ModemState = p->ModemState; - pReceptionData->SNR = p->SNR; - pReceptionData->BER = p->LayerInfo[0].BER; - pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; - pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; - pReceptionData->RSSI = p->RSSI; - CORRECT_STAT_RSSI(*pReceptionData); - pReceptionData->InBandPwr = p->InBandPwr; - - pReceptionData->CarrierOffset = p->CarrierOffset; - pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; - pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; - pReceptionData->MFER = 0; + c->lna = p->IsExternalLNAOn ? 1 : 0; - /* TS PER */ - if ((p->LayerInfo[0].TotalTSPackets + - p->LayerInfo[0].ErrorTSPackets) > 0) { - pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets - * 100) / (p->LayerInfo[0].TotalTSPackets - + p->LayerInfo[0].ErrorTSPackets); - } else { - pReceptionData->TS_PER = 0; + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + client->last_per = c->block_error.stat[0].uvalue; + + /* Clears global counters, as the code below will sum it again */ + c->block_error.stat[0].uvalue = 0; + c->block_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].uvalue = 0; + c->post_bit_count.stat[0].uvalue = 0; + + for (i = 0; i < n_layers; i++) { + lr = &p->LayerInfo[i]; + + /* Update per-layer transmission parameters */ + if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { + c->isdbt_layer_enabled |= 1 << i; + c->layer[i].segment_count = lr->NumberOfSegments; + } else { + continue; + } + c->layer[i].modulation = sms_to_modulation(lr->Constellation); + + /* TS PER */ + c->block_error.stat[i].scale = FE_SCALE_COUNTER; + c->block_count.stat[i].scale = FE_SCALE_COUNTER; + c->block_error.stat[i].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i].uvalue += lr->TotalTSPackets; + + /* Update global PER counter */ + c->block_error.stat[0].uvalue += lr->ErrorTSPackets; + c->block_count.stat[0].uvalue += lr->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + + /* Update global BER counter */ + c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[0].uvalue += lr->BERBitCount; } } -static void smsdvb_update_isdbt_stats_ex(struct RECEPTION_STATISTICS_EX_S *pReceptionData, - struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) { + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; + int i, n_layers; + smsdvb_print_isdb_stats_ex(p); + /* Update ISDB-T transmission parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->isdbt_partial_reception = p->PartialReception ? 1 : 0; + n_layers = p->NumOfLayers; + if (n_layers < 1) + n_layers = 1; + if (n_layers > 3) + n_layers = 3; + c->isdbt_layer_enabled = 0; + /* update reception data */ - pReceptionData->IsRfLocked = p->IsRfLocked; - pReceptionData->IsDemodLocked = p->IsDemodLocked; - pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; - pReceptionData->ModemState = p->ModemState; - pReceptionData->SNR = p->SNR; - pReceptionData->BER = p->LayerInfo[0].BER; - pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; - pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; - pReceptionData->RSSI = p->RSSI; - CORRECT_STAT_RSSI(*pReceptionData); - pReceptionData->InBandPwr = p->InBandPwr; - - pReceptionData->CarrierOffset = p->CarrierOffset; - pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; - pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; - pReceptionData->MFER = 0; + c->lna = p->IsExternalLNAOn ? 1 : 0; - /* TS PER */ - if ((p->LayerInfo[0].TotalTSPackets + - p->LayerInfo[0].ErrorTSPackets) > 0) { - pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets - * 100) / (p->LayerInfo[0].TotalTSPackets - + p->LayerInfo[0].ErrorTSPackets); - } else { - pReceptionData->TS_PER = 0; + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + client->last_per = c->block_error.stat[0].uvalue; + + /* Clears global counters, as the code below will sum it again */ + c->block_error.stat[0].uvalue = 0; + c->block_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].uvalue = 0; + c->post_bit_count.stat[0].uvalue = 0; + + for (i = 0; i < n_layers; i++) { + lr = &p->LayerInfo[i]; + + /* Update per-layer transmission parameters */ + if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { + c->isdbt_layer_enabled |= 1 << i; + c->layer[i].segment_count = lr->NumberOfSegments; + } else { + continue; + } + c->layer[i].modulation = sms_to_modulation(lr->Constellation); + + /* TS PER */ + c->block_error.stat[i].scale = FE_SCALE_COUNTER; + c->block_count.stat[i].scale = FE_SCALE_COUNTER; + c->block_error.stat[i].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i].uvalue += lr->TotalTSPackets; + + /* Update global PER counter */ + c->block_error.stat[0].uvalue += lr->ErrorTSPackets; + c->block_count.stat[0].uvalue += lr->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + + /* Update global BER counter */ + c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[0].uvalue += lr->BERBitCount; } } @@ -339,13 +675,14 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) + cb->offset); - u32 *pMsgData = (u32 *) phdr + 1; - /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ + void *p = phdr + 1; + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; bool is_status_update = false; switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), + dvb_dmx_swfilter(&client->demux, p, cb->size - sizeof(struct SmsMsgHdr_ST)); break; @@ -355,166 +692,64 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) break; case MSG_SMS_SIGNAL_DETECTED_IND: - client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; + client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + is_status_update = true; break; case MSG_SMS_NO_SIGNAL_IND: - client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; + client->fe_status = 0; + is_status_update = true; break; - case MSG_SMS_TRANSMISSION_IND: { - - pMsgData++; - memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, - sizeof(struct TRANSMISSION_STATISTICS_S)); + case MSG_SMS_TRANSMISSION_IND: + smsdvb_update_tx_params(client, p); -#if 1 - /* - * FIXME: newer driver doesn't have those fixes - * Are those firmware-specific stuff? - */ - - /* Mo need to correct guard interval - * (as opposed to old statistics message). - */ - CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); - CORRECT_STAT_TRANSMISSON_MODE( - client->sms_stat_dvb.TransmissionData); -#endif is_status_update = true; break; - } - case MSG_SMS_HO_PER_SLICES_IND: { - struct RECEPTION_STATISTICS_EX_S *pReceptionData = - &client->sms_stat_dvb.ReceptionData; - struct SRVM_SIGNAL_STATUS_S SignalStatusData; - - pMsgData++; - SignalStatusData.result = pMsgData[0]; - SignalStatusData.snr = pMsgData[1]; - SignalStatusData.inBandPower = (s32) pMsgData[2]; - SignalStatusData.tsPackets = pMsgData[3]; - SignalStatusData.etsPackets = pMsgData[4]; - SignalStatusData.constellation = pMsgData[5]; - SignalStatusData.hpCode = pMsgData[6]; - SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; - SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; - SignalStatusData.cellId = pMsgData[9] & 0xFFFF; - SignalStatusData.reason = pMsgData[10]; - SignalStatusData.requestId = pMsgData[11]; - pReceptionData->IsRfLocked = pMsgData[16]; - pReceptionData->IsDemodLocked = pMsgData[17]; - pReceptionData->ModemState = pMsgData[12]; - pReceptionData->SNR = pMsgData[1]; - pReceptionData->BER = pMsgData[13]; - pReceptionData->RSSI = pMsgData[14]; - CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); - - pReceptionData->InBandPwr = (s32) pMsgData[2]; - pReceptionData->CarrierOffset = (s32) pMsgData[15]; - pReceptionData->TotalTSPackets = pMsgData[3]; - pReceptionData->ErrorTSPackets = pMsgData[4]; - /* TS PER */ - if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) - > 0) { - pReceptionData->TS_PER = (SignalStatusData.etsPackets - * 100) / (SignalStatusData.tsPackets - + SignalStatusData.etsPackets); - } else { - pReceptionData->TS_PER = 0; - } - - pReceptionData->BERBitCount = pMsgData[18]; - pReceptionData->BERErrorCount = pMsgData[19]; - - pReceptionData->MRC_SNR = pMsgData[20]; - pReceptionData->MRC_InBandPwr = pMsgData[21]; - pReceptionData->MRC_RSSI = pMsgData[22]; + case MSG_SMS_HO_PER_SLICES_IND: + smsdvb_update_per_slices(client, p); is_status_update = true; break; - } - case MSG_SMS_GET_STATISTICS_RES: { - union { - struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt; - struct SmsMsgStatisticsInfo_ST dvb; - } *p = (void *) (phdr + 1); - struct RECEPTION_STATISTICS_EX_S *pReceptionData = - &client->sms_stat_dvb.ReceptionData; - - is_status_update = true; + case MSG_SMS_GET_STATISTICS_RES: switch (smscore_get_device_mode(client->coredev)) { case DEVICE_MODE_ISDBT: case DEVICE_MODE_ISDBT_BDA: - smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt); + smsdvb_update_isdbt_stats(client, p); break; default: - smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat); - } - if (!pReceptionData->IsDemodLocked) { - pReceptionData->SNR = 0; - pReceptionData->BER = 0; - pReceptionData->BERErrorCount = 0; - pReceptionData->InBandPwr = 0; - pReceptionData->ErrorTSPackets = 0; + smsdvb_update_dvb_stats(client, p); } + is_status_update = true; break; - } - case MSG_SMS_GET_STATISTICS_EX_RES: { - union { - struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST isdbt; - struct SMSHOSTLIB_STATISTICS_ST dvb; - } *p = (void *) (phdr + 1); - struct RECEPTION_STATISTICS_EX_S *pReceptionData = - &client->sms_stat_dvb.ReceptionData; + /* Only for ISDB-T */ + case MSG_SMS_GET_STATISTICS_EX_RES: + smsdvb_update_isdbt_stats_ex(client, p); is_status_update = true; - - switch (smscore_get_device_mode(client->coredev)) { - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - smsdvb_update_isdbt_stats_ex(pReceptionData, &p->isdbt); - break; - default: - smsdvb_update_dvb_stats(pReceptionData, &p->dvb); - } - if (!pReceptionData->IsDemodLocked) { - pReceptionData->SNR = 0; - pReceptionData->BER = 0; - pReceptionData->BERErrorCount = 0; - pReceptionData->InBandPwr = 0; - pReceptionData->ErrorTSPackets = 0; - } - break; - } default: sms_info("message not handled"); } smscore_putbuffer(client->coredev, cb); if (is_status_update) { - if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER - | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + if (client->fe_status == FE_HAS_LOCK) { sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); - if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets - == 0) + if (client->last_per == c->block_error.stat[0].uvalue) sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); else - sms_board_dvb3_event(client, - DVB3_EVENT_UNC_ERR); - + sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); } else { - if (client->sms_stat_dvb.ReceptionData.IsRfLocked) - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER; - else - client->fe_status = 0; + smsdvb_stats_not_ready(fe); + sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); } complete(&client->stats_done); @@ -612,13 +847,20 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) Msg.msgFlags = 0; Msg.msgLength = sizeof(Msg); - /* - * Check for firmware version, to avoid breaking for old cards - */ - if (client->coredev->fw_version >= 0x800) - Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; - else + switch (smscore_get_device_mode(client->coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + /* + * Check for firmware version, to avoid breaking for old cards + */ + if (client->coredev->fw_version >= 0x800) + Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; + else + Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; + break; + default: Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; + } rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stats_done); @@ -628,12 +870,12 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) static inline int led_feedback(struct smsdvb_client_t *client) { - if (client->fe_status & FE_HAS_LOCK) - return sms_board_led_feedback(client->coredev, - (client->sms_stat_dvb.ReceptionData.BER - == 0) ? SMS_LED_HI : SMS_LED_LO); - else + if (!(client->fe_status & FE_HAS_LOCK)) return sms_board_led_feedback(client->coredev, SMS_LED_OFF); + + return sms_board_led_feedback(client->coredev, + (client->legacy_ber == 0) ? + SMS_LED_HI : SMS_LED_LO); } static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) @@ -655,11 +897,12 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) { int rc; struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); rc = smsdvb_send_statistics_request(client); - *ber = client->sms_stat_dvb.ReceptionData.BER; + *ber = client->legacy_ber; led_feedback(client); @@ -668,21 +911,21 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int rc; - + s32 power = (s32) c->strength.stat[0].uvalue; struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); rc = smsdvb_send_statistics_request(client); - if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) + if (power < -95) *strength = 0; - else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) - *strength = 100; + else if (power > -29) + *strength = 65535; else - *strength = - (client->sms_stat_dvb.ReceptionData.InBandPwr - + 95) * 3 / 2; + *strength = (power + 95) * 65535 / 66; led_feedback(client); @@ -691,13 +934,16 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int rc; struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); rc = smsdvb_send_statistics_request(client); - *snr = client->sms_stat_dvb.ReceptionData.SNR; + /* Preferred scale for SNR with legacy API: 0.1 dB */ + *snr = c->cnr.stat[0].svalue / 100; led_feedback(client); @@ -707,12 +953,14 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { int rc; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); rc = smsdvb_send_statistics_request(client); - *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; + *ucblocks = c->block_error.stat[0].uvalue; led_feedback(client); @@ -743,7 +991,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) int ret; - client->fe_status = FE_HAS_SIGNAL; + client->fe_status = 0; client->event_fe_state = -1; client->event_unc_state = -1; fe->dtv_property_cache.delivery_system = SYS_DVBT; @@ -871,6 +1119,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) container_of(fe, struct smsdvb_client_t, frontend); struct smscore_device_t *coredev = client->coredev; + smsdvb_stats_not_ready(fe); + switch (smscore_get_device_mode(coredev)) { case DEVICE_MODE_DVBT: case DEVICE_MODE_DVBT_BDA: @@ -883,150 +1133,10 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) } } -static int smsdvb_get_frontend_dvb(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *fep = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct TRANSMISSION_STATISTICS_S *td = - &client->sms_stat_dvb.TransmissionData; - - fep->frequency = td->Frequency; - - switch (td->Bandwidth) { - case 6: - fep->bandwidth_hz = 6000000; - break; - case 7: - fep->bandwidth_hz = 7000000; - break; - case 8: - fep->bandwidth_hz = 8000000; - break; - } - - switch (td->TransmissionMode) { - case 2: - fep->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 8: - fep->transmission_mode = TRANSMISSION_MODE_8K; - } - - switch (td->GuardInterval) { - case 0: - fep->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - fep->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - fep->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - fep->guard_interval = GUARD_INTERVAL_1_4; - break; - } - - switch (td->CodeRate) { - case 0: - fep->code_rate_HP = FEC_1_2; - break; - case 1: - fep->code_rate_HP = FEC_2_3; - break; - case 2: - fep->code_rate_HP = FEC_3_4; - break; - case 3: - fep->code_rate_HP = FEC_5_6; - break; - case 4: - fep->code_rate_HP = FEC_7_8; - break; - } - - switch (td->LPCodeRate) { - case 0: - fep->code_rate_LP = FEC_1_2; - break; - case 1: - fep->code_rate_LP = FEC_2_3; - break; - case 2: - fep->code_rate_LP = FEC_3_4; - break; - case 3: - fep->code_rate_LP = FEC_5_6; - break; - case 4: - fep->code_rate_LP = FEC_7_8; - break; - } - - switch (td->Constellation) { - case 0: - fep->modulation = QPSK; - break; - case 1: - fep->modulation = QAM_16; - break; - case 2: - fep->modulation = QAM_64; - break; - } - - switch (td->Hierarchy) { - case 0: - fep->hierarchy = HIERARCHY_NONE; - break; - case 1: - fep->hierarchy = HIERARCHY_1; - break; - case 2: - fep->hierarchy = HIERARCHY_2; - break; - case 3: - fep->hierarchy = HIERARCHY_4; - break; - } - - fep->inversion = INVERSION_AUTO; - - return 0; -} - -static int smsdvb_get_frontend_isdb(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *fep = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct TRANSMISSION_STATISTICS_S *td = - &client->sms_stat_dvb.TransmissionData; - - fep->frequency = td->Frequency; - fep->bandwidth_hz = 6000000; - /* todo: retrive the other parameters */ - - return 0; -} - +/* Nothing to do here, as stats are automatically updated */ static int smsdvb_get_frontend(struct dvb_frontend *fe) { - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - return smsdvb_get_frontend_dvb(fe); - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - return smsdvb_get_frontend_isdb(fe); - default: - return -EINVAL; - } + return 0; } static int smsdvb_init(struct dvb_frontend *fe) -- cgit From c02272f9b9c71c5fe6c0cb3874ec153ff2e842ef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 23:01:48 -0300 Subject: [media] siano: fix start of statistics It seems that the first u32 after the header for some stats are used by something not documented. The stats struct starts after it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index a5f52721154c..70ea3e9b4ac6 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -724,7 +724,8 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) smsdvb_update_isdbt_stats(client, p); break; default: - smsdvb_update_dvb_stats(client, p); + /* Skip SmsMsgStatisticsInfo_ST:RequestResult field */ + smsdvb_update_dvb_stats(client, p + sizeof(u32)); } is_status_update = true; @@ -732,7 +733,8 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) /* Only for ISDB-T */ case MSG_SMS_GET_STATISTICS_EX_RES: - smsdvb_update_isdbt_stats_ex(client, p); + /* Skip SmsMsgStatisticsInfo_ST:RequestResult field? */ + smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); is_status_update = true; break; default: -- cgit From 3f6b87cff66bb8507aefd62559c516dd7c8f822a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Mar 2013 22:33:06 -0300 Subject: [media] siano: allow showing the complete statistics via debugfs Outputs the result of the statistics responses via debugfs. That can help to track bugs at the stats filling. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb.c | 464 +++++++++++++++++++++++++++--------- 1 file changed, 355 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 70ea3e9b4ac6..aeadd8a42775 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c @@ -22,6 +22,7 @@ along with this program. If not, see . #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" @@ -55,6 +56,13 @@ struct smsdvb_client_t { int event_fe_state; int event_unc_state; + + /* Stats debugfs data */ + struct dentry *debugfs; + char *stats_data; + atomic_t stats_count; + bool stats_was_read; + wait_queue_head_t stats_queue; }; static struct list_head g_smsdvb_clients; @@ -140,134 +148,358 @@ u32 sms_to_modulation_table[] = { [3] = DQPSK, }; -static void smsdvb_print_dvb_stats(struct SMSHOSTLIB_STATISTICS_ST *p) +static struct dentry *smsdvb_debugfs; + +static void smsdvb_print_dvb_stats(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ST *p) { - if (!(sms_dbg & 2)) + int n = 0; + char *buf; + + if (!client->stats_data || atomic_read(&client->stats_count)) return; - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "BER = %d", p->BER); - printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC); - printk(KERN_DEBUG "TS_PER = %d", p->TS_PER); - printk(KERN_DEBUG "MFER = %d", p->MFER); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "CodeRate = %d", p->CodeRate); - printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate); - printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy); - printk(KERN_DEBUG "Constellation = %d", p->Constellation); - printk(KERN_DEBUG "BurstSize = %d", p->BurstSize); - printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration); - printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime); - printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime); - printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows); - printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols); - printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols); - printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets); - printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets); - printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs); - printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs); - printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs); - printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount); - printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); - printk(KERN_DEBUG "PreBER = %d", p->PreBER); - printk(KERN_DEBUG "CellId = %d", p->CellId); - printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP); - printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP); - printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); + buf = client->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\n", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\n", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d\n", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BER = %d\n", p->BER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "FIB_CRC = %d\n", p->FIB_CRC); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TS_PER = %d\n", p->TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "MFER = %d\n", p->MFER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d\n", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\n", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\n", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\n", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\n", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\n", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CodeRate = %d\n", p->CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, + "LPCodeRate = %d\n", p->LPCodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Hierarchy = %d\n", p->Hierarchy); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Constellation = %d\n", p->Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstSize = %d\n", p->BurstSize); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstDuration = %d\n", p->BurstDuration); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstCycleTime = %d\n", p->BurstCycleTime); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CalculatedBurstCycleTime = %d\n", + p->CalculatedBurstCycleTime); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfRows = %d\n", p->NumOfRows); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfPaddCols = %d\n", p->NumOfPaddCols); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfPunctCols = %d\n", p->NumOfPunctCols); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ErrorTSPackets = %d\n", p->ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TotalTSPackets = %d\n", p->TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfValidMpeTlbs = %d\n", p->NumOfValidMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfInvalidMpeTlbs = %d\n", p->NumOfInvalidMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfCorrectedMpeTlbs = %d\n", p->NumOfCorrectedMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BERErrorCount = %d\n", p->BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BERBitCount = %d\n", p->BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PreBER = %d\n", p->PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CellId = %d\n", p->CellId); + n += snprintf(&buf[n], PAGE_SIZE - n, + "DvbhSrvIndHP = %d\n", p->DvbhSrvIndHP); + n += snprintf(&buf[n], PAGE_SIZE - n, + "DvbhSrvIndLP = %d\n", p->DvbhSrvIndLP); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumMPEReceived = %d\n", p->NumMPEReceived); + + atomic_set(&client->stats_count, n); + wake_up(&client->stats_queue); } -static void smsdvb_print_isdb_stats(struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) +static void smsdvb_print_isdb_stats(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) { - int i; + int i, n = 0; + char *buf; - if (!(sms_dbg & 2)) + if (!client->stats_data || atomic_read(&client->stats_count)) return; - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "SystemType = %d", p->SystemType); - printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); - printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); - printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); + buf = client->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\t\t", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\t", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d dB\t\t", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d dBm\t\t", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d dBm\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\t", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\t\t", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d Hz\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\t", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\t\t", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SystemType = %d\t\t", p->SystemType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PartialReception = %d\t", p->PartialReception); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfLayers = %d\n", p->NumOfLayers); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); for (i = 0; i < 3; i++) { - printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); - printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); - printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); - printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); - printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); - printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); - printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); - printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); - printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); - printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); - printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); - printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); + if (p->LayerInfo[i].NumberOfSegments < 1 || + p->LayerInfo[i].NumberOfSegments > 13) + continue; + + n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", + p->LayerInfo[i].CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", + p->LayerInfo[i].Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", + p->LayerInfo[i].BER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", + p->LayerInfo[i].BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", + p->LayerInfo[i].BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", + p->LayerInfo[i].PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", + p->LayerInfo[i].TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", + p->LayerInfo[i].ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", + p->LayerInfo[i].TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", + p->LayerInfo[i].TILdepthI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "\tNumberOfSegments = %d\t", + p->LayerInfo[i].NumberOfSegments); + n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", + p->LayerInfo[i].TMCCErrors); } + + atomic_set(&client->stats_count, n); + wake_up(&client->stats_queue); } static void -smsdvb_print_isdb_stats_ex(struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +smsdvb_print_isdb_stats_ex(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) { - int i; + int i, n = 0; + char *buf; - if (!(sms_dbg & 2)) + if (!client->stats_data || atomic_read(&client->stats_count)) return; - printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); - printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); - printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); - printk(KERN_DEBUG "SNR = %d", p->SNR); - printk(KERN_DEBUG "RSSI = %d", p->RSSI); - printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); - printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); - printk(KERN_DEBUG "Frequency = %d", p->Frequency); - printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); - printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); - printk(KERN_DEBUG "ModemState = %d", p->ModemState); - printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); - printk(KERN_DEBUG "SystemType = %d", p->SystemType); - printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); - printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); - printk(KERN_DEBUG "SegmentNumber = %d", p->SegmentNumber); - printk(KERN_DEBUG "TuneBW = %d", p->TuneBW); + buf = client->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\t\t", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\t", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d dB\t\t", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d dBm\t\t", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d dBm\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\t", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\t\t", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d Hz\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\t", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\t\t", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SystemType = %d\t\t", p->SystemType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PartialReception = %d\t", p->PartialReception); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfLayers = %d\n", p->NumOfLayers); + n += snprintf(&buf[n], PAGE_SIZE - n, "SegmentNumber = %d\t", + p->SegmentNumber); + n += snprintf(&buf[n], PAGE_SIZE - n, "TuneBW = %d\n", + p->TuneBW); for (i = 0; i < 3; i++) { - printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); - printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); - printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); - printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); - printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); - printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); - printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); - printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); - printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); - printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); - printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); - printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); + if (p->LayerInfo[i].NumberOfSegments < 1 || + p->LayerInfo[i].NumberOfSegments > 13) + continue; + + n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", + p->LayerInfo[i].CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", + p->LayerInfo[i].Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", + p->LayerInfo[i].BER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", + p->LayerInfo[i].BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", + p->LayerInfo[i].BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", + p->LayerInfo[i].PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", + p->LayerInfo[i].TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", + p->LayerInfo[i].ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", + p->LayerInfo[i].TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", + p->LayerInfo[i].TILdepthI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "\tNumberOfSegments = %d\t", + p->LayerInfo[i].NumberOfSegments); + n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", + p->LayerInfo[i].TMCCErrors); + } + + atomic_set(&client->stats_count, n); + wake_up(&client->stats_queue); +} + +static int smsdvb_stats_open(struct inode *inode, struct file *file) +{ + struct smsdvb_client_t *client = inode->i_private; + + atomic_set(&client->stats_count, 0); + client->stats_was_read = false; + + init_waitqueue_head(&client->stats_queue); + + client->stats_data = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (client->stats_data == NULL) + return -ENOMEM; + + file->private_data = client; + + return 0; +} + +static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, + size_t nbytes, loff_t *ppos) +{ + struct smsdvb_client_t *client = file->private_data; + + if (!client->stats_data || client->stats_was_read) + return 0; + + wait_event_interruptible(client->stats_queue, + atomic_read(&client->stats_count)); + + return simple_read_from_buffer(user_buf, nbytes, ppos, + client->stats_data, + atomic_read(&client->stats_count)); + + client->stats_was_read = true; +} + +static int smsdvb_stats_release(struct inode *inode, struct file *file) +{ + struct smsdvb_client_t *client = file->private_data; + + kfree(client->stats_data); + client->stats_data = NULL; + + return 0; +} + +static const struct file_operations debugfs_stats_ops = { + .open = smsdvb_stats_open, + .read = smsdvb_stats_read, + .release = smsdvb_stats_release, + .llseek = generic_file_llseek, +}; + +static int create_stats_debugfs(struct smsdvb_client_t *client) +{ + struct smscore_device_t *coredev = client->coredev; + struct dentry *d; + + if (!smsdvb_debugfs) + return -ENODEV; + + client->debugfs = debugfs_create_dir(coredev->devpath, smsdvb_debugfs); + if (IS_ERR_OR_NULL(client->debugfs)) { + sms_info("Unable to create debugfs %s directory.\n", + coredev->devpath); + return -ENODEV; } + + d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs, + client, &debugfs_stats_ops); + if (!d) { + debugfs_remove(client->debugfs); + return -ENOMEM; + } + + return 0; +} + +static void release_stats_debugfs(struct smsdvb_client_t *client) +{ + if (!client->debugfs) + return; + + debugfs_remove_recursive(client->debugfs); + + client->debugfs = NULL; } /* Events that may come from DVB v3 adapter */ @@ -476,7 +708,7 @@ static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, struct dvb_frontend *fe = &client->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - smsdvb_print_dvb_stats(p); + smsdvb_print_dvb_stats(client, p); client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); @@ -526,7 +758,7 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; int i, n_layers; - smsdvb_print_isdb_stats(p); + smsdvb_print_isdb_stats(client, p); /* Update ISDB-T transmission parameters */ c->frequency = p->Frequency; @@ -602,7 +834,7 @@ static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; int i, n_layers; - smsdvb_print_isdb_stats_ex(p); + smsdvb_print_isdb_stats_ex(client, p); /* Update ISDB-T transmission parameters */ c->frequency = p->Frequency; @@ -766,6 +998,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client) list_del(&client->entry); + release_stats_debugfs(client); smscore_unregister_client(client->smsclient); dvb_unregister_frontend(&client->frontend); dvb_dmxdev_release(&client->dmxdev); @@ -1303,6 +1536,9 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, sms_info("success"); sms_board_setup(coredev); + if (create_stats_debugfs(client) < 0) + sms_info("failed to create debugfs node"); + return 0; client_error: @@ -1325,10 +1561,17 @@ adapter_error: static int __init smsdvb_module_init(void) { int rc; + struct dentry *d; INIT_LIST_HEAD(&g_smsdvb_clients); kmutex_init(&g_smsdvb_clientslock); + d = debugfs_create_dir("smsdvb", usb_debug_root); + if (IS_ERR_OR_NULL(d)) + sms_err("Couldn't create sysfs node for smsdvb"); + else + smsdvb_debugfs = d; + rc = smscore_register_hotplug(smsdvb_hotplug); sms_debug(""); @@ -1346,6 +1589,9 @@ static void __exit smsdvb_module_exit(void) smsdvb_unregister_client( (struct smsdvb_client_t *) g_smsdvb_clients.next); + if (smsdvb_debugfs) + debugfs_remove_recursive(smsdvb_debugfs); + kmutex_unlock(&g_smsdvb_clientslock); } -- cgit From 503efe5cfc9fb9f67a6659c4ab39174b442876f3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Mar 2013 09:04:44 -0300 Subject: [media] siano: split debugfs code into a separate file To avoid mixing two different things at the same place, move the debugfs code into a separate file. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/Kconfig | 12 + drivers/media/common/siano/Makefile | 5 + drivers/media/common/siano/smscoreapi.h | 6 + drivers/media/common/siano/smsdvb-debugfs.c | 503 +++++++++ drivers/media/common/siano/smsdvb-main.c | 1184 ++++++++++++++++++++ drivers/media/common/siano/smsdvb.c | 1603 --------------------------- drivers/media/common/siano/smsdvb.h | 124 +++ drivers/media/usb/siano/smsusb.c | 2 + 8 files changed, 1836 insertions(+), 1603 deletions(-) create mode 100644 drivers/media/common/siano/smsdvb-debugfs.c create mode 100644 drivers/media/common/siano/smsdvb-main.c delete mode 100644 drivers/media/common/siano/smsdvb.c create mode 100644 drivers/media/common/siano/smsdvb.h (limited to 'drivers') diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig index 68f0f604678e..f3f5ec44e685 100644 --- a/drivers/media/common/siano/Kconfig +++ b/drivers/media/common/siano/Kconfig @@ -17,3 +17,15 @@ config SMS_SIANO_RC default y ---help--- Choose Y to select Remote Controller support for Siano driver. + +config SMS_SIANO_DEBUGFS + bool "Enable debugfs for smsdvb" + depends on SMS_SIANO_MDTV + depends on DEBUG_FS + depends on SMS_USB_DRV + ---help--- + Choose Y to enable visualizing a dump of the frontend + statistics response packets via debugfs. Currently, works + only with Siano USB devices. + + Useful only for developers. In doubt, say N. diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile index 81b1e985bea5..4c0567f106b2 100644 --- a/drivers/media/common/siano/Makefile +++ b/drivers/media/common/siano/Makefile @@ -1,4 +1,5 @@ smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o +smsdvb-objs := smsdvb-main.o obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o @@ -6,6 +7,10 @@ ifeq ($(CONFIG_SMS_SIANO_RC),y) smsmdtv-objs += smsir.o endif +ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y) + smsdvb-objs += smsdvb-debugfs.o +endif + ccflags-y += -Idrivers/media/dvb-core ccflags-y += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 7925c04e3edc..53b81cbc1bda 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -184,6 +184,12 @@ struct smscore_device_t { /* Infrared (IR) */ struct ir_t ir; + /* + * Identify if device is USB or not. + * Used by smsdvb-sysfs to know the root node for debugfs + */ + bool is_usb_device; + int led_state; }; diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c new file mode 100644 index 000000000000..4d5dd471e2e1 --- /dev/null +++ b/drivers/media/common/siano/smsdvb-debugfs.c @@ -0,0 +1,503 @@ +/*********************************************************************** + * + * Copyright(c) 2013 Mauro Carvalho Chehab + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 . + * + ***********************************************************************/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + +#include "smscoreapi.h" + +#include "smsdvb.h" + +static struct dentry *smsdvb_debugfs_usb_root; + +struct smsdvb_debugfs { + struct kref refcount; + spinlock_t lock; + + char stats_data[PAGE_SIZE]; + unsigned stats_count; + bool stats_was_read; + + wait_queue_head_t stats_queue; +}; + +void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ST *p) +{ + int n = 0; + char *buf; + + spin_lock(&debug_data->lock); + if (debug_data->stats_count) { + spin_unlock(&debug_data->lock); + return; + } + + buf = debug_data->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\n", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\n", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d\n", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BER = %d\n", p->BER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "FIB_CRC = %d\n", p->FIB_CRC); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TS_PER = %d\n", p->TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "MFER = %d\n", p->MFER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d\n", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\n", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\n", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\n", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\n", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\n", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CodeRate = %d\n", p->CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, + "LPCodeRate = %d\n", p->LPCodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Hierarchy = %d\n", p->Hierarchy); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Constellation = %d\n", p->Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstSize = %d\n", p->BurstSize); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstDuration = %d\n", p->BurstDuration); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BurstCycleTime = %d\n", p->BurstCycleTime); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CalculatedBurstCycleTime = %d\n", + p->CalculatedBurstCycleTime); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfRows = %d\n", p->NumOfRows); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfPaddCols = %d\n", p->NumOfPaddCols); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfPunctCols = %d\n", p->NumOfPunctCols); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ErrorTSPackets = %d\n", p->ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TotalTSPackets = %d\n", p->TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfValidMpeTlbs = %d\n", p->NumOfValidMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfInvalidMpeTlbs = %d\n", p->NumOfInvalidMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfCorrectedMpeTlbs = %d\n", p->NumOfCorrectedMpeTlbs); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BERErrorCount = %d\n", p->BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, + "BERBitCount = %d\n", p->BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PreBER = %d\n", p->PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CellId = %d\n", p->CellId); + n += snprintf(&buf[n], PAGE_SIZE - n, + "DvbhSrvIndHP = %d\n", p->DvbhSrvIndHP); + n += snprintf(&buf[n], PAGE_SIZE - n, + "DvbhSrvIndLP = %d\n", p->DvbhSrvIndLP); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumMPEReceived = %d\n", p->NumMPEReceived); + + debug_data->stats_count = n; + spin_unlock(&debug_data->lock); + wake_up(&debug_data->stats_queue); +} + +void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) +{ + int i, n = 0; + char *buf; + + spin_lock(&debug_data->lock); + if (debug_data->stats_count) { + spin_unlock(&debug_data->lock); + return; + } + + buf = debug_data->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\t\t", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\t", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d dB\t\t", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d dBm\t\t", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d dBm\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\t", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\t\t", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d Hz\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\t", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\t\t", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SystemType = %d\t\t", p->SystemType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PartialReception = %d\t", p->PartialReception); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfLayers = %d\n", p->NumOfLayers); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); + + for (i = 0; i < 3; i++) { + if (p->LayerInfo[i].NumberOfSegments < 1 || + p->LayerInfo[i].NumberOfSegments > 13) + continue; + + n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", + p->LayerInfo[i].CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", + p->LayerInfo[i].Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", + p->LayerInfo[i].BER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", + p->LayerInfo[i].BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", + p->LayerInfo[i].BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", + p->LayerInfo[i].PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", + p->LayerInfo[i].TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", + p->LayerInfo[i].ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", + p->LayerInfo[i].TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", + p->LayerInfo[i].TILdepthI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "\tNumberOfSegments = %d\t", + p->LayerInfo[i].NumberOfSegments); + n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", + p->LayerInfo[i].TMCCErrors); + } + + debug_data->stats_count = n; + spin_unlock(&debug_data->lock); + wake_up(&debug_data->stats_queue); +} + +void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +{ + int i, n = 0; + char *buf; + + spin_lock(&debug_data->lock); + if (debug_data->stats_count) { + spin_unlock(&debug_data->lock); + return; + } + + buf = debug_data->stats_data; + + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsRfLocked = %d\t\t", p->IsRfLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsDemodLocked = %d\t", p->IsDemodLocked); + n += snprintf(&buf[n], PAGE_SIZE - n, + "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SNR = %d dB\t\t", p->SNR); + n += snprintf(&buf[n], PAGE_SIZE - n, + "RSSI = %d dBm\t\t", p->RSSI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "InBandPwr = %d dBm\n", p->InBandPwr); + n += snprintf(&buf[n], PAGE_SIZE - n, + "CarrierOffset = %d\t", p->CarrierOffset); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Bandwidth = %d\t\t", p->Bandwidth); + n += snprintf(&buf[n], PAGE_SIZE - n, + "Frequency = %d Hz\n", p->Frequency); + n += snprintf(&buf[n], PAGE_SIZE - n, + "TransmissionMode = %d\t", p->TransmissionMode); + n += snprintf(&buf[n], PAGE_SIZE - n, + "ModemState = %d\t\t", p->ModemState); + n += snprintf(&buf[n], PAGE_SIZE - n, + "GuardInterval = %d\n", p->GuardInterval); + n += snprintf(&buf[n], PAGE_SIZE - n, + "SystemType = %d\t\t", p->SystemType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "PartialReception = %d\t", p->PartialReception); + n += snprintf(&buf[n], PAGE_SIZE - n, + "NumOfLayers = %d\n", p->NumOfLayers); + n += snprintf(&buf[n], PAGE_SIZE - n, "SegmentNumber = %d\t", + p->SegmentNumber); + n += snprintf(&buf[n], PAGE_SIZE - n, "TuneBW = %d\n", + p->TuneBW); + + for (i = 0; i < 3; i++) { + if (p->LayerInfo[i].NumberOfSegments < 1 || + p->LayerInfo[i].NumberOfSegments > 13) + continue; + + n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", + p->LayerInfo[i].CodeRate); + n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", + p->LayerInfo[i].Constellation); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", + p->LayerInfo[i].BER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", + p->LayerInfo[i].BERErrorCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", + p->LayerInfo[i].BERBitCount); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", + p->LayerInfo[i].PreBER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", + p->LayerInfo[i].TS_PER); + n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", + p->LayerInfo[i].ErrorTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", + p->LayerInfo[i].TotalTSPackets); + n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", + p->LayerInfo[i].TILdepthI); + n += snprintf(&buf[n], PAGE_SIZE - n, + "\tNumberOfSegments = %d\t", + p->LayerInfo[i].NumberOfSegments); + n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", + p->LayerInfo[i].TMCCErrors); + } + + + debug_data->stats_count = n; + spin_unlock(&debug_data->lock); + + wake_up(&debug_data->stats_queue); +} + +static int smsdvb_stats_open(struct inode *inode, struct file *file) +{ + struct smsdvb_client_t *client = inode->i_private; + struct smsdvb_debugfs *debug_data = client->debug_data; + + kref_get(&debug_data->refcount); + + spin_lock(&debug_data->lock); + debug_data->stats_count = 0; + debug_data->stats_was_read = false; + spin_unlock(&debug_data->lock); + + file->private_data = debug_data; + + return 0; +} + +static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data) +{ + int rc = 1; + + spin_lock(&debug_data->lock); + + if (debug_data->stats_was_read) + goto exit; + + rc = debug_data->stats_count; + +exit: + spin_unlock(&debug_data->lock); + return rc; +} + +static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, + size_t nbytes, loff_t *ppos) +{ + int rc = 0; + struct smsdvb_debugfs *debug_data = file->private_data; + + rc = wait_event_interruptible(debug_data->stats_queue, + smsdvb_stats_wait_read(debug_data)); + if (rc < 0) + return rc; + + rc = simple_read_from_buffer(user_buf, nbytes, ppos, + debug_data->stats_data, + debug_data->stats_count); + spin_lock(&debug_data->lock); + debug_data->stats_was_read = true; + spin_unlock(&debug_data->lock); + + return rc; +} + +static void smsdvb_debugfs_data_release(struct kref *ref) +{ + struct smsdvb_debugfs *debug_data; + + debug_data = container_of(ref, struct smsdvb_debugfs, refcount); + kfree(debug_data); +} + +static int smsdvb_stats_release(struct inode *inode, struct file *file) +{ + struct smsdvb_debugfs *debug_data = file->private_data; + + spin_lock(&debug_data->lock); + debug_data->stats_was_read = true; + spin_unlock(&debug_data->lock); + wake_up_interruptible_sync(&debug_data->stats_queue); + + kref_put(&debug_data->refcount, smsdvb_debugfs_data_release); + file->private_data = NULL; + + return 0; +} + +static const struct file_operations debugfs_stats_ops = { + .open = smsdvb_stats_open, + .read = smsdvb_stats_read, + .release = smsdvb_stats_release, + .llseek = generic_file_llseek, +}; + +/* + * Functions used by smsdvb, in order to create the interfaces + */ + +int smsdvb_debugfs_create(struct smsdvb_client_t *client) +{ + struct smscore_device_t *coredev = client->coredev; + struct dentry *d; + struct smsdvb_debugfs *debug_data; + + if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device) + return -ENODEV; + + client->debugfs = debugfs_create_dir(coredev->devpath, + smsdvb_debugfs_usb_root); + if (IS_ERR_OR_NULL(client->debugfs)) { + pr_info("Unable to create debugfs %s directory.\n", + coredev->devpath); + return -ENODEV; + } + + d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs, + client, &debugfs_stats_ops); + if (!d) { + debugfs_remove(client->debugfs); + return -ENOMEM; + } + + debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL); + if (!debug_data) + return -ENOMEM; + + client->debug_data = debug_data; + client->prt_dvb_stats = smsdvb_print_dvb_stats; + client->prt_isdb_stats = smsdvb_print_isdb_stats; + client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex; + + init_waitqueue_head(&debug_data->stats_queue); + spin_lock_init(&debug_data->lock); + kref_init(&debug_data->refcount); + + return 0; +} + +void smsdvb_debugfs_release(struct smsdvb_client_t *client) +{ + if (!client->debugfs) + return; + +printk("%s\n", __func__); + + client->prt_dvb_stats = NULL; + client->prt_isdb_stats = NULL; + client->prt_isdb_stats_ex = NULL; + + debugfs_remove_recursive(client->debugfs); + kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release); + + client->debug_data = NULL; + client->debugfs = NULL; +} + +int smsdvb_debugfs_register(void) +{ + struct dentry *d; + + /* + * FIXME: This was written to debug Siano USB devices. So, it creates + * the debugfs node under /usb. + * A similar logic would be needed for Siano sdio devices, but, in that + * case, usb_debug_root is not a good choice. + * + * Perhaps the right fix here would be to create another sysfs root + * node for sdio-based boards, but this may need some logic at sdio + * subsystem. + */ + d = debugfs_create_dir("smsdvb", usb_debug_root); + if (IS_ERR_OR_NULL(d)) { + sms_err("Couldn't create sysfs node for smsdvb"); + return PTR_ERR(d); + } else { + smsdvb_debugfs_usb_root = d; + } + return 0; +} + +void smsdvb_debugfs_unregister(void) +{ + if (smsdvb_debugfs_usb_root) + debugfs_remove_recursive(smsdvb_debugfs_usb_root); + smsdvb_debugfs_usb_root = NULL; +} diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c new file mode 100644 index 000000000000..c14f10d5d6c0 --- /dev/null +++ b/drivers/media/common/siano/smsdvb-main.c @@ -0,0 +1,1184 @@ +/**************************************************************** + +Siano Mobile Silicon, Inc. +MDTV receiver kernel modules. +Copyright (C) 2006-2008, Uri Shkolnik + +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 "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + +#include "smscoreapi.h" +#include "sms-cards.h" + +#include "smsdvb.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static struct list_head g_smsdvb_clients; +static struct mutex g_smsdvb_clientslock; + +static int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + + +u32 sms_to_bw_table[] = { + [BW_8_MHZ] = 8000000, + [BW_7_MHZ] = 7000000, + [BW_6_MHZ] = 6000000, + [BW_5_MHZ] = 5000000, + [BW_2_MHZ] = 2000000, + [BW_1_5_MHZ] = 1500000, + [BW_ISDBT_1SEG] = 6000000, + [BW_ISDBT_3SEG] = 6000000, + [BW_ISDBT_13SEG] = 6000000, +}; + +u32 sms_to_guard_interval_table[] = { + [0] = GUARD_INTERVAL_1_32, + [1] = GUARD_INTERVAL_1_16, + [2] = GUARD_INTERVAL_1_8, + [3] = GUARD_INTERVAL_1_4, +}; + +u32 sms_to_code_rate_table[] = { + [0] = FEC_1_2, + [1] = FEC_2_3, + [2] = FEC_3_4, + [3] = FEC_5_6, + [4] = FEC_7_8, +}; + + +u32 sms_to_hierarchy_table[] = { + [0] = HIERARCHY_NONE, + [1] = HIERARCHY_1, + [2] = HIERARCHY_2, + [3] = HIERARCHY_4, +}; + +u32 sms_to_modulation_table[] = { + [0] = QPSK, + [1] = QAM_16, + [2] = QAM_64, + [3] = DQPSK, +}; + + +/* Events that may come from DVB v3 adapter */ +static void sms_board_dvb3_event(struct smsdvb_client_t *client, + enum SMS_DVB3_EVENTS event) { + + struct smscore_device_t *coredev = client->coredev; + switch (event) { + case DVB3_EVENT_INIT: + sms_debug("DVB3_EVENT_INIT"); + sms_board_event(coredev, BOARD_EVENT_BIND); + break; + case DVB3_EVENT_SLEEP: + sms_debug("DVB3_EVENT_SLEEP"); + sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); + break; + case DVB3_EVENT_HOTPLUG: + sms_debug("DVB3_EVENT_HOTPLUG"); + sms_board_event(coredev, BOARD_EVENT_POWER_INIT); + break; + case DVB3_EVENT_FE_LOCK: + if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { + client->event_fe_state = DVB3_EVENT_FE_LOCK; + sms_debug("DVB3_EVENT_FE_LOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_LOCK); + } + break; + case DVB3_EVENT_FE_UNLOCK: + if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { + client->event_fe_state = DVB3_EVENT_FE_UNLOCK; + sms_debug("DVB3_EVENT_FE_UNLOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); + } + break; + case DVB3_EVENT_UNC_OK: + if (client->event_unc_state != DVB3_EVENT_UNC_OK) { + client->event_unc_state = DVB3_EVENT_UNC_OK; + sms_debug("DVB3_EVENT_UNC_OK"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); + } + break; + case DVB3_EVENT_UNC_ERR: + if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { + client->event_unc_state = DVB3_EVENT_UNC_ERR; + sms_debug("DVB3_EVENT_UNC_ERR"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); + } + break; + + default: + sms_err("Unknown dvb3 api event"); + break; + } +} + +static void smsdvb_stats_not_ready(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + struct smscore_device_t *coredev = client->coredev; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int i, n_layers; + + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + n_layers = 4; + default: + n_layers = 1; + } + + /* Fill the length of each status counter */ + + /* Only global stats */ + c->strength.len = 1; + c->cnr.len = 1; + + /* Per-layer stats */ + c->post_bit_error.len = n_layers; + c->post_bit_count.len = n_layers; + c->block_error.len = n_layers; + c->block_count.len = n_layers; + + /* Signal is always available */ + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = 0; + + /* Put all of them at FE_SCALE_NOT_AVAILABLE */ + for (i = 0; i < n_layers; i++) { + c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; + } +} + +static inline int sms_to_mode(u32 mode) +{ + switch (mode) { + case 2: + return TRANSMISSION_MODE_2K; + case 4: + return TRANSMISSION_MODE_4K; + case 8: + return TRANSMISSION_MODE_8K; + } + return TRANSMISSION_MODE_AUTO; +} + +static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) +{ + if (is_demod_locked) + return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + + if (is_rf_locked) + return FE_HAS_SIGNAL | FE_HAS_CARRIER; + + return 0; +} + + +#define convert_from_table(value, table, defval) ({ \ + u32 __ret; \ + if (value < ARRAY_SIZE(table)) \ + __ret = table[value]; \ + else \ + __ret = defval; \ + __ret; \ +}) + +#define sms_to_bw(value) \ + convert_from_table(value, sms_to_bw_table, 0); + +#define sms_to_guard_interval(value) \ + convert_from_table(value, sms_to_guard_interval_table, \ + GUARD_INTERVAL_AUTO); + +#define sms_to_code_rate(value) \ + convert_from_table(value, sms_to_code_rate_table, \ + FEC_NONE); + +#define sms_to_hierarchy(value) \ + convert_from_table(value, sms_to_hierarchy_table, \ + FEC_NONE); + +#define sms_to_modulation(value) \ + convert_from_table(value, sms_to_modulation_table, \ + FEC_NONE); + +static void smsdvb_update_tx_params(struct smsdvb_client_t *client, + struct TRANSMISSION_STATISTICS_S *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->code_rate_HP = sms_to_code_rate(p->CodeRate); + c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); + c->hierarchy = sms_to_hierarchy(p->Hierarchy); + c->modulation = sms_to_modulation(p->Constellation); +} + +static void smsdvb_update_per_slices(struct smsdvb_client_t *client, + struct RECEPTION_STATISTICS_PER_SLICES_S *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); + c->modulation = sms_to_modulation(p->constellation); + + /* TS PER */ + client->last_per = c->block_error.stat[0].uvalue; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += p->etsPackets; + c->block_count.stat[0].uvalue += p->etsPackets + p->tsPackets; + + /* BER */ + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += p->BERErrorCount; + c->post_bit_count.stat[0].uvalue += p->BERBitCount; + + /* Legacy PER/BER */ + client->legacy_per = (p->etsPackets * 65535) / + (p->tsPackets + p->etsPackets); + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->snr * 1000; +} + +static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ST *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (client->prt_dvb_stats) + client->prt_dvb_stats(client->debug_data, p); + + client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); + + /* Update DVB modulation parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->code_rate_HP = sms_to_code_rate(p->CodeRate); + c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); + c->hierarchy = sms_to_hierarchy(p->Hierarchy); + c->modulation = sms_to_modulation(p->Constellation); + + /* update reception data */ + c->lna = p->IsExternalLNAOn ? 1 : 0; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + /* TS PER */ + client->last_per = c->block_error.stat[0].uvalue; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += p->ErrorTSPackets; + c->block_count.stat[0].uvalue += p->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += p->BERErrorCount; + c->post_bit_count.stat[0].uvalue += p->BERBitCount; + + /* Legacy PER/BER */ + client->legacy_ber = p->BER; +}; + +static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; + int i, n_layers; + + if (client->prt_isdb_stats) + client->prt_isdb_stats(client->debug_data, p); + + /* Update ISDB-T transmission parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->isdbt_partial_reception = p->PartialReception ? 1 : 0; + n_layers = p->NumOfLayers; + if (n_layers < 1) + n_layers = 1; + if (n_layers > 3) + n_layers = 3; + c->isdbt_layer_enabled = 0; + + /* update reception data */ + c->lna = p->IsExternalLNAOn ? 1 : 0; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + client->last_per = c->block_error.stat[0].uvalue; + + /* Clears global counters, as the code below will sum it again */ + c->block_error.stat[0].uvalue = 0; + c->block_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].uvalue = 0; + c->post_bit_count.stat[0].uvalue = 0; + + for (i = 0; i < n_layers; i++) { + lr = &p->LayerInfo[i]; + + /* Update per-layer transmission parameters */ + if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { + c->isdbt_layer_enabled |= 1 << i; + c->layer[i].segment_count = lr->NumberOfSegments; + } else { + continue; + } + c->layer[i].modulation = sms_to_modulation(lr->Constellation); + + /* TS PER */ + c->block_error.stat[i].scale = FE_SCALE_COUNTER; + c->block_count.stat[i].scale = FE_SCALE_COUNTER; + c->block_error.stat[i].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i].uvalue += lr->TotalTSPackets; + + /* Update global PER counter */ + c->block_error.stat[0].uvalue += lr->ErrorTSPackets; + c->block_count.stat[0].uvalue += lr->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + + /* Update global BER counter */ + c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[0].uvalue += lr->BERBitCount; + } +} + +static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) +{ + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; + int i, n_layers; + + if (client->prt_isdb_stats_ex) + client->prt_isdb_stats_ex(client->debug_data, p); + + /* Update ISDB-T transmission parameters */ + c->frequency = p->Frequency; + client->fe_status = sms_to_status(p->IsDemodLocked, 0); + c->bandwidth_hz = sms_to_bw(p->Bandwidth); + c->transmission_mode = sms_to_mode(p->TransmissionMode); + c->guard_interval = sms_to_guard_interval(p->GuardInterval); + c->isdbt_partial_reception = p->PartialReception ? 1 : 0; + n_layers = p->NumOfLayers; + if (n_layers < 1) + n_layers = 1; + if (n_layers > 3) + n_layers = 3; + c->isdbt_layer_enabled = 0; + + /* update reception data */ + c->lna = p->IsExternalLNAOn ? 1 : 0; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = p->SNR * 1000; + + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->RSSI * 1000; + + client->last_per = c->block_error.stat[0].uvalue; + + /* Clears global counters, as the code below will sum it again */ + c->block_error.stat[0].uvalue = 0; + c->block_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].uvalue = 0; + c->post_bit_count.stat[0].uvalue = 0; + + for (i = 0; i < n_layers; i++) { + lr = &p->LayerInfo[i]; + + /* Update per-layer transmission parameters */ + if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { + c->isdbt_layer_enabled |= 1 << i; + c->layer[i].segment_count = lr->NumberOfSegments; + } else { + continue; + } + c->layer[i].modulation = sms_to_modulation(lr->Constellation); + + /* TS PER */ + c->block_error.stat[i].scale = FE_SCALE_COUNTER; + c->block_count.stat[i].scale = FE_SCALE_COUNTER; + c->block_error.stat[i].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i].uvalue += lr->TotalTSPackets; + + /* Update global PER counter */ + c->block_error.stat[0].uvalue += lr->ErrorTSPackets; + c->block_count.stat[0].uvalue += lr->TotalTSPackets; + + /* BER */ + c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + + /* Update global BER counter */ + c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[0].uvalue += lr->BERBitCount; + } +} + +static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) +{ + struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) + + cb->offset); + void *p = phdr + 1; + struct dvb_frontend *fe = &client->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + bool is_status_update = false; + + switch (phdr->msgType) { + case MSG_SMS_DVBT_BDA_DATA: + dvb_dmx_swfilter(&client->demux, p, + cb->size - sizeof(struct SmsMsgHdr_ST)); + break; + + case MSG_SMS_RF_TUNE_RES: + case MSG_SMS_ISDBT_TUNE_RES: + complete(&client->tune_done); + break; + + case MSG_SMS_SIGNAL_DETECTED_IND: + client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_LOCK; + + is_status_update = true; + break; + + case MSG_SMS_NO_SIGNAL_IND: + client->fe_status = 0; + + is_status_update = true; + break; + + case MSG_SMS_TRANSMISSION_IND: + smsdvb_update_tx_params(client, p); + + is_status_update = true; + break; + + case MSG_SMS_HO_PER_SLICES_IND: + smsdvb_update_per_slices(client, p); + + is_status_update = true; + break; + + case MSG_SMS_GET_STATISTICS_RES: + switch (smscore_get_device_mode(client->coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + smsdvb_update_isdbt_stats(client, p); + break; + default: + /* Skip SmsMsgStatisticsInfo_ST:RequestResult field */ + smsdvb_update_dvb_stats(client, p + sizeof(u32)); + } + + is_status_update = true; + break; + + /* Only for ISDB-T */ + case MSG_SMS_GET_STATISTICS_EX_RES: + /* Skip SmsMsgStatisticsInfo_ST:RequestResult field? */ + smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); + is_status_update = true; + break; + default: + sms_info("message not handled"); + } + smscore_putbuffer(client->coredev, cb); + + if (is_status_update) { + if (client->fe_status == FE_HAS_LOCK) { + sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); + if (client->last_per == c->block_error.stat[0].uvalue) + sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); + else + sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); + } else { + smsdvb_stats_not_ready(fe); + + sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); + } + complete(&client->stats_done); + } + + return 0; +} + +static void smsdvb_unregister_client(struct smsdvb_client_t *client) +{ + /* must be called under clientslock */ + + list_del(&client->entry); + + smsdvb_debugfs_release(client); + smscore_unregister_client(client->smsclient); + dvb_unregister_frontend(&client->frontend); + dvb_dmxdev_release(&client->dmxdev); + dvb_dmx_release(&client->demux); + dvb_unregister_adapter(&client->adapter); + kfree(client); +} + +static void smsdvb_onremove(void *context) +{ + kmutex_lock(&g_smsdvb_clientslock); + + smsdvb_unregister_client((struct smsdvb_client_t *) context); + + kmutex_unlock(&g_smsdvb_clientslock); +} + +static int smsdvb_start_feed(struct dvb_demux_feed *feed) +{ + struct smsdvb_client_t *client = + container_of(feed->demux, struct smsdvb_client_t, demux); + struct SmsMsgData_ST PidMsg; + + sms_debug("add pid %d(%x)", + feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, + &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_stop_feed(struct dvb_demux_feed *feed) +{ + struct smsdvb_client_t *client = + container_of(feed->demux, struct smsdvb_client_t, demux); + struct SmsMsgData_ST PidMsg; + + sms_debug("remove pid %d(%x)", + feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, + &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, + void *buffer, size_t size, + struct completion *completion) +{ + int rc; + + rc = smsclient_sendrequest(client->smsclient, buffer, size); + if (rc < 0) + return rc; + + return wait_for_completion_timeout(completion, + msecs_to_jiffies(2000)) ? + 0 : -ETIME; +} + +static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) +{ + int rc; + struct SmsMsgHdr_ST Msg; + + + Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.msgDstId = HIF_TASK; + Msg.msgFlags = 0; + Msg.msgLength = sizeof(Msg); + + switch (smscore_get_device_mode(client->coredev)) { + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + /* + * Check for firmware version, to avoid breaking for old cards + */ + if (client->coredev->fw_version >= 0x800) + Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; + else + Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; + break; + default: + Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; + } + + rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->stats_done); + + return rc; +} + +static inline int led_feedback(struct smsdvb_client_t *client) +{ + if (!(client->fe_status & FE_HAS_LOCK)) + return sms_board_led_feedback(client->coredev, SMS_LED_OFF); + + return sms_board_led_feedback(client->coredev, + (client->legacy_ber == 0) ? + SMS_LED_HI : SMS_LED_LO); +} + +static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) +{ + int rc; + struct smsdvb_client_t *client; + client = container_of(fe, struct smsdvb_client_t, frontend); + + rc = smsdvb_send_statistics_request(client); + + *stat = client->fe_status; + + led_feedback(client); + + return rc; +} + +static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + int rc; + struct smsdvb_client_t *client; + + client = container_of(fe, struct smsdvb_client_t, frontend); + + rc = smsdvb_send_statistics_request(client); + + *ber = client->legacy_ber; + + led_feedback(client); + + return rc; +} + +static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int rc; + s32 power = (s32) c->strength.stat[0].uvalue; + struct smsdvb_client_t *client; + + client = container_of(fe, struct smsdvb_client_t, frontend); + + rc = smsdvb_send_statistics_request(client); + + if (power < -95) + *strength = 0; + else if (power > -29) + *strength = 65535; + else + *strength = (power + 95) * 65535 / 66; + + led_feedback(client); + + return rc; +} + +static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int rc; + struct smsdvb_client_t *client; + + client = container_of(fe, struct smsdvb_client_t, frontend); + + rc = smsdvb_send_statistics_request(client); + + /* Preferred scale for SNR with legacy API: 0.1 dB */ + *snr = c->cnr.stat[0].svalue / 100; + + led_feedback(client); + + return rc; +} + +static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + int rc; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct smsdvb_client_t *client; + + client = container_of(fe, struct smsdvb_client_t, frontend); + + rc = smsdvb_send_statistics_request(client); + + *ucblocks = c->block_error.stat[0].uvalue; + + led_feedback(client); + + return rc; +} + +static int smsdvb_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + sms_debug(""); + + tune->min_delay_ms = 400; + tune->step_size = 250000; + tune->max_drift = 0; + return 0; +} + +static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + + struct { + struct SmsMsgHdr_ST Msg; + u32 Data[3]; + } Msg; + + int ret; + + client->fe_status = 0; + client->event_fe_state = -1; + client->event_unc_state = -1; + fe->dtv_property_cache.delivery_system = SYS_DVBT; + + Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.Msg.msgDstId = HIF_TASK; + Msg.Msg.msgFlags = 0; + Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; + Msg.Msg.msgLength = sizeof(Msg); + Msg.Data[0] = c->frequency; + Msg.Data[2] = 12000000; + + sms_info("%s: freq %d band %d", __func__, c->frequency, + c->bandwidth_hz); + + switch (c->bandwidth_hz / 1000000) { + case 8: + Msg.Data[1] = BW_8_MHZ; + break; + case 7: + Msg.Data[1] = BW_7_MHZ; + break; + case 6: + Msg.Data[1] = BW_6_MHZ; + break; + case 0: + return -EOPNOTSUPP; + default: + return -EINVAL; + } + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didn't lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } + + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); +} + +static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + int board_id = smscore_get_board_id(client->coredev); + struct sms_board *board = sms_get_board(board_id); + enum sms_device_type_st type = board->type; + int ret; + + struct { + struct SmsMsgHdr_ST Msg; + u32 Data[4]; + } Msg; + + fe->dtv_property_cache.delivery_system = SYS_ISDBT; + + Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.Msg.msgDstId = HIF_TASK; + Msg.Msg.msgFlags = 0; + Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ; + Msg.Msg.msgLength = sizeof(Msg); + + if (c->isdbt_sb_segment_idx == -1) + c->isdbt_sb_segment_idx = 0; + + if (!c->isdbt_layer_enabled) + c->isdbt_layer_enabled = 7; + + Msg.Data[0] = c->frequency; + Msg.Data[1] = BW_ISDBT_1SEG; + Msg.Data[2] = 12000000; + Msg.Data[3] = c->isdbt_sb_segment_idx; + + if (c->isdbt_partial_reception) { + if ((type == SMS_PELE || type == SMS_RIO) && + c->isdbt_sb_segment_count > 3) + Msg.Data[1] = BW_ISDBT_13SEG; + else if (c->isdbt_sb_segment_count > 1) + Msg.Data[1] = BW_ISDBT_3SEG; + } else if (type == SMS_PELE || type == SMS_RIO) + Msg.Data[1] = BW_ISDBT_13SEG; + + c->bandwidth_hz = 6000000; + + sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, + c->frequency, c->isdbt_sb_segment_count, + c->isdbt_sb_segment_idx); + + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didn't lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); +} + +static int smsdvb_set_frontend(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + struct smscore_device_t *coredev = client->coredev; + + smsdvb_stats_not_ready(fe); + + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_DVBT: + case DEVICE_MODE_DVBT_BDA: + return smsdvb_dvbt_set_frontend(fe); + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + return smsdvb_isdbt_set_frontend(fe); + default: + return -EINVAL; + } +} + +/* Nothing to do here, as stats are automatically updated */ +static int smsdvb_get_frontend(struct dvb_frontend *fe) +{ + return 0; +} + +static int smsdvb_init(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + + sms_board_power(client->coredev, 1); + + sms_board_dvb3_event(client, DVB3_EVENT_INIT); + return 0; +} + +static int smsdvb_sleep(struct dvb_frontend *fe) +{ + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); + + sms_board_led_feedback(client->coredev, SMS_LED_OFF); + sms_board_power(client->coredev, 0); + + sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); + + return 0; +} + +static void smsdvb_release(struct dvb_frontend *fe) +{ + /* do nothing */ +} + +static struct dvb_frontend_ops smsdvb_fe_ops = { + .info = { + .name = "Siano Mobile Digital MDTV Receiver", + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 250000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = smsdvb_release, + + .set_frontend = smsdvb_set_frontend, + .get_frontend = smsdvb_get_frontend, + .get_tune_settings = smsdvb_get_tune_settings, + + .read_status = smsdvb_read_status, + .read_ber = smsdvb_read_ber, + .read_signal_strength = smsdvb_read_signal_strength, + .read_snr = smsdvb_read_snr, + .read_ucblocks = smsdvb_read_ucblocks, + + .init = smsdvb_init, + .sleep = smsdvb_sleep, +}; + +static int smsdvb_hotplug(struct smscore_device_t *coredev, + struct device *device, int arrival) +{ + struct smsclient_params_t params; + struct smsdvb_client_t *client; + int rc; + + /* device removal handled by onremove callback */ + if (!arrival) + return 0; + client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); + if (!client) { + sms_err("kmalloc() failed"); + return -ENOMEM; + } + + /* register dvb adapter */ + rc = dvb_register_adapter(&client->adapter, + sms_get_board( + smscore_get_board_id(coredev))->name, + THIS_MODULE, device, adapter_nr); + if (rc < 0) { + sms_err("dvb_register_adapter() failed %d", rc); + goto adapter_error; + } + + /* init dvb demux */ + client->demux.dmx.capabilities = DMX_TS_FILTERING; + client->demux.filternum = 32; /* todo: nova ??? */ + client->demux.feednum = 32; + client->demux.start_feed = smsdvb_start_feed; + client->demux.stop_feed = smsdvb_stop_feed; + + rc = dvb_dmx_init(&client->demux); + if (rc < 0) { + sms_err("dvb_dmx_init failed %d", rc); + goto dvbdmx_error; + } + + /* init dmxdev */ + client->dmxdev.filternum = 32; + client->dmxdev.demux = &client->demux.dmx; + client->dmxdev.capabilities = 0; + + rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); + if (rc < 0) { + sms_err("dvb_dmxdev_init failed %d", rc); + goto dmxdev_error; + } + + /* init and register frontend */ + memcpy(&client->frontend.ops, &smsdvb_fe_ops, + sizeof(struct dvb_frontend_ops)); + + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_DVBT: + case DEVICE_MODE_DVBT_BDA: + client->frontend.ops.delsys[0] = SYS_DVBT; + break; + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + client->frontend.ops.delsys[0] = SYS_ISDBT; + break; + } + + rc = dvb_register_frontend(&client->adapter, &client->frontend); + if (rc < 0) { + sms_err("frontend registration failed %d", rc); + goto frontend_error; + } + + params.initial_id = 1; + params.data_type = MSG_SMS_DVBT_BDA_DATA; + params.onresponse_handler = smsdvb_onresponse; + params.onremove_handler = smsdvb_onremove; + params.context = client; + + rc = smscore_register_client(coredev, ¶ms, &client->smsclient); + if (rc < 0) { + sms_err("smscore_register_client() failed %d", rc); + goto client_error; + } + + client->coredev = coredev; + + init_completion(&client->tune_done); + init_completion(&client->stats_done); + + kmutex_lock(&g_smsdvb_clientslock); + + list_add(&client->entry, &g_smsdvb_clients); + + kmutex_unlock(&g_smsdvb_clientslock); + + client->event_fe_state = -1; + client->event_unc_state = -1; + sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); + + sms_info("success"); + sms_board_setup(coredev); + + if (smsdvb_debugfs_create(client) < 0) + sms_info("failed to create debugfs node"); + + return 0; + +client_error: + dvb_unregister_frontend(&client->frontend); + +frontend_error: + dvb_dmxdev_release(&client->dmxdev); + +dmxdev_error: + dvb_dmx_release(&client->demux); + +dvbdmx_error: + dvb_unregister_adapter(&client->adapter); + +adapter_error: + kfree(client); + return rc; +} + +static int __init smsdvb_module_init(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smsdvb_clients); + kmutex_init(&g_smsdvb_clientslock); + + smsdvb_debugfs_register(); + + rc = smscore_register_hotplug(smsdvb_hotplug); + + sms_debug(""); + + return rc; +} + +static void __exit smsdvb_module_exit(void) +{ + smscore_unregister_hotplug(smsdvb_hotplug); + + kmutex_lock(&g_smsdvb_clientslock); + + while (!list_empty(&g_smsdvb_clients)) + smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next); + + smsdvb_debugfs_unregister(); + + kmutex_unlock(&g_smsdvb_clientslock); +} + +module_init(smsdvb_module_init); +module_exit(smsdvb_module_exit); + +MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); +MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c deleted file mode 100644 index aeadd8a42775..000000000000 --- a/drivers/media/common/siano/smsdvb.c +++ /dev/null @@ -1,1603 +0,0 @@ -/**************************************************************** - -Siano Mobile Silicon, Inc. -MDTV receiver kernel modules. -Copyright (C) 2006-2008, Uri Shkolnik - -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 "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - -#include "smscoreapi.h" -#include "sms-cards.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - - struct completion tune_done; - struct completion stats_done; - - int last_per; - - int legacy_ber, legacy_per; - - int event_fe_state; - int event_unc_state; - - /* Stats debugfs data */ - struct dentry *debugfs; - char *stats_data; - atomic_t stats_count; - bool stats_was_read; - wait_queue_head_t stats_queue; -}; - -static struct list_head g_smsdvb_clients; -static struct mutex g_smsdvb_clientslock; - -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - -/* - * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S. - * It was obtained by comparing the way it was filled by the original code - */ -struct RECEPTION_STATISTICS_PER_SLICES_S { - u32 result; - u32 snr; - s32 inBandPower; - u32 tsPackets; - u32 etsPackets; - u32 constellation; - u32 hpCode; - u32 tpsSrvIndLP; - u32 tpsSrvIndHP; - u32 cellId; - u32 reason; - u32 requestId; - u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ - - u32 BER; /* Post Viterbi BER [1E-5] */ - s32 RSSI; /* dBm */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - - u32 BERBitCount; /* Total number of SYNC bits. */ - u32 BERErrorCount; /* Number of erronous SYNC bits. */ - - s32 MRC_SNR; /* dB */ - s32 MRC_InBandPwr; /* In band power in dBM */ - s32 MRC_RSSI; /* dBm */ -}; - -u32 sms_to_bw_table[] = { - [BW_8_MHZ] = 8000000, - [BW_7_MHZ] = 7000000, - [BW_6_MHZ] = 6000000, - [BW_5_MHZ] = 5000000, - [BW_2_MHZ] = 2000000, - [BW_1_5_MHZ] = 1500000, - [BW_ISDBT_1SEG] = 6000000, - [BW_ISDBT_3SEG] = 6000000, - [BW_ISDBT_13SEG] = 6000000, -}; - -u32 sms_to_guard_interval_table[] = { - [0] = GUARD_INTERVAL_1_32, - [1] = GUARD_INTERVAL_1_16, - [2] = GUARD_INTERVAL_1_8, - [3] = GUARD_INTERVAL_1_4, -}; - -u32 sms_to_code_rate_table[] = { - [0] = FEC_1_2, - [1] = FEC_2_3, - [2] = FEC_3_4, - [3] = FEC_5_6, - [4] = FEC_7_8, -}; - - -u32 sms_to_hierarchy_table[] = { - [0] = HIERARCHY_NONE, - [1] = HIERARCHY_1, - [2] = HIERARCHY_2, - [3] = HIERARCHY_4, -}; - -u32 sms_to_modulation_table[] = { - [0] = QPSK, - [1] = QAM_16, - [2] = QAM_64, - [3] = DQPSK, -}; - -static struct dentry *smsdvb_debugfs; - -static void smsdvb_print_dvb_stats(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ST *p) -{ - int n = 0; - char *buf; - - if (!client->stats_data || atomic_read(&client->stats_count)) - return; - - buf = client->stats_data; - - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsRfLocked = %d\n", p->IsRfLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsDemodLocked = %d\n", p->IsDemodLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SNR = %d\n", p->SNR); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BER = %d\n", p->BER); - n += snprintf(&buf[n], PAGE_SIZE - n, - "FIB_CRC = %d\n", p->FIB_CRC); - n += snprintf(&buf[n], PAGE_SIZE - n, - "TS_PER = %d\n", p->TS_PER); - n += snprintf(&buf[n], PAGE_SIZE - n, - "MFER = %d\n", p->MFER); - n += snprintf(&buf[n], PAGE_SIZE - n, - "RSSI = %d\n", p->RSSI); - n += snprintf(&buf[n], PAGE_SIZE - n, - "InBandPwr = %d\n", p->InBandPwr); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CarrierOffset = %d\n", p->CarrierOffset); - n += snprintf(&buf[n], PAGE_SIZE - n, - "ModemState = %d\n", p->ModemState); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Frequency = %d\n", p->Frequency); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Bandwidth = %d\n", p->Bandwidth); - n += snprintf(&buf[n], PAGE_SIZE - n, - "TransmissionMode = %d\n", p->TransmissionMode); - n += snprintf(&buf[n], PAGE_SIZE - n, - "ModemState = %d\n", p->ModemState); - n += snprintf(&buf[n], PAGE_SIZE - n, - "GuardInterval = %d\n", p->GuardInterval); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CodeRate = %d\n", p->CodeRate); - n += snprintf(&buf[n], PAGE_SIZE - n, - "LPCodeRate = %d\n", p->LPCodeRate); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Hierarchy = %d\n", p->Hierarchy); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Constellation = %d\n", p->Constellation); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BurstSize = %d\n", p->BurstSize); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BurstDuration = %d\n", p->BurstDuration); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BurstCycleTime = %d\n", p->BurstCycleTime); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CalculatedBurstCycleTime = %d\n", - p->CalculatedBurstCycleTime); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfRows = %d\n", p->NumOfRows); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfPaddCols = %d\n", p->NumOfPaddCols); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfPunctCols = %d\n", p->NumOfPunctCols); - n += snprintf(&buf[n], PAGE_SIZE - n, - "ErrorTSPackets = %d\n", p->ErrorTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, - "TotalTSPackets = %d\n", p->TotalTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfValidMpeTlbs = %d\n", p->NumOfValidMpeTlbs); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfInvalidMpeTlbs = %d\n", p->NumOfInvalidMpeTlbs); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfCorrectedMpeTlbs = %d\n", p->NumOfCorrectedMpeTlbs); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BERErrorCount = %d\n", p->BERErrorCount); - n += snprintf(&buf[n], PAGE_SIZE - n, - "BERBitCount = %d\n", p->BERBitCount); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); - n += snprintf(&buf[n], PAGE_SIZE - n, - "PreBER = %d\n", p->PreBER); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CellId = %d\n", p->CellId); - n += snprintf(&buf[n], PAGE_SIZE - n, - "DvbhSrvIndHP = %d\n", p->DvbhSrvIndHP); - n += snprintf(&buf[n], PAGE_SIZE - n, - "DvbhSrvIndLP = %d\n", p->DvbhSrvIndLP); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumMPEReceived = %d\n", p->NumMPEReceived); - - atomic_set(&client->stats_count, n); - wake_up(&client->stats_queue); -} - -static void smsdvb_print_isdb_stats(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) -{ - int i, n = 0; - char *buf; - - if (!client->stats_data || atomic_read(&client->stats_count)) - return; - - buf = client->stats_data; - - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsRfLocked = %d\t\t", p->IsRfLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsDemodLocked = %d\t", p->IsDemodLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SNR = %d dB\t\t", p->SNR); - n += snprintf(&buf[n], PAGE_SIZE - n, - "RSSI = %d dBm\t\t", p->RSSI); - n += snprintf(&buf[n], PAGE_SIZE - n, - "InBandPwr = %d dBm\n", p->InBandPwr); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CarrierOffset = %d\t", p->CarrierOffset); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Bandwidth = %d\t\t", p->Bandwidth); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Frequency = %d Hz\n", p->Frequency); - n += snprintf(&buf[n], PAGE_SIZE - n, - "TransmissionMode = %d\t", p->TransmissionMode); - n += snprintf(&buf[n], PAGE_SIZE - n, - "ModemState = %d\t\t", p->ModemState); - n += snprintf(&buf[n], PAGE_SIZE - n, - "GuardInterval = %d\n", p->GuardInterval); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SystemType = %d\t\t", p->SystemType); - n += snprintf(&buf[n], PAGE_SIZE - n, - "PartialReception = %d\t", p->PartialReception); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfLayers = %d\n", p->NumOfLayers); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SmsToHostTxErrors = %d\n", p->SmsToHostTxErrors); - - for (i = 0; i < 3; i++) { - if (p->LayerInfo[i].NumberOfSegments < 1 || - p->LayerInfo[i].NumberOfSegments > 13) - continue; - - n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", - p->LayerInfo[i].CodeRate); - n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", - p->LayerInfo[i].Constellation); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", - p->LayerInfo[i].BER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", - p->LayerInfo[i].BERErrorCount); - n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", - p->LayerInfo[i].BERBitCount); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", - p->LayerInfo[i].PreBER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", - p->LayerInfo[i].TS_PER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", - p->LayerInfo[i].ErrorTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", - p->LayerInfo[i].TotalTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", - p->LayerInfo[i].TILdepthI); - n += snprintf(&buf[n], PAGE_SIZE - n, - "\tNumberOfSegments = %d\t", - p->LayerInfo[i].NumberOfSegments); - n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", - p->LayerInfo[i].TMCCErrors); - } - - atomic_set(&client->stats_count, n); - wake_up(&client->stats_queue); -} - -static void -smsdvb_print_isdb_stats_ex(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) -{ - int i, n = 0; - char *buf; - - if (!client->stats_data || atomic_read(&client->stats_count)) - return; - - buf = client->stats_data; - - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsRfLocked = %d\t\t", p->IsRfLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsDemodLocked = %d\t", p->IsDemodLocked); - n += snprintf(&buf[n], PAGE_SIZE - n, - "IsExternalLNAOn = %d\n", p->IsExternalLNAOn); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SNR = %d dB\t\t", p->SNR); - n += snprintf(&buf[n], PAGE_SIZE - n, - "RSSI = %d dBm\t\t", p->RSSI); - n += snprintf(&buf[n], PAGE_SIZE - n, - "InBandPwr = %d dBm\n", p->InBandPwr); - n += snprintf(&buf[n], PAGE_SIZE - n, - "CarrierOffset = %d\t", p->CarrierOffset); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Bandwidth = %d\t\t", p->Bandwidth); - n += snprintf(&buf[n], PAGE_SIZE - n, - "Frequency = %d Hz\n", p->Frequency); - n += snprintf(&buf[n], PAGE_SIZE - n, - "TransmissionMode = %d\t", p->TransmissionMode); - n += snprintf(&buf[n], PAGE_SIZE - n, - "ModemState = %d\t\t", p->ModemState); - n += snprintf(&buf[n], PAGE_SIZE - n, - "GuardInterval = %d\n", p->GuardInterval); - n += snprintf(&buf[n], PAGE_SIZE - n, - "SystemType = %d\t\t", p->SystemType); - n += snprintf(&buf[n], PAGE_SIZE - n, - "PartialReception = %d\t", p->PartialReception); - n += snprintf(&buf[n], PAGE_SIZE - n, - "NumOfLayers = %d\n", p->NumOfLayers); - n += snprintf(&buf[n], PAGE_SIZE - n, "SegmentNumber = %d\t", - p->SegmentNumber); - n += snprintf(&buf[n], PAGE_SIZE - n, "TuneBW = %d\n", - p->TuneBW); - - for (i = 0; i < 3; i++) { - if (p->LayerInfo[i].NumberOfSegments < 1 || - p->LayerInfo[i].NumberOfSegments > 13) - continue; - - n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tCodeRate = %d\t", - p->LayerInfo[i].CodeRate); - n += snprintf(&buf[n], PAGE_SIZE - n, "Constellation = %d\n", - p->LayerInfo[i].Constellation); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tBER = %-5d\t", - p->LayerInfo[i].BER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tBERErrorCount = %-5d\t", - p->LayerInfo[i].BERErrorCount); - n += snprintf(&buf[n], PAGE_SIZE - n, "BERBitCount = %-5d\n", - p->LayerInfo[i].BERBitCount); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tPreBER = %-5d\t", - p->LayerInfo[i].PreBER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tTS_PER = %-5d\n", - p->LayerInfo[i].TS_PER); - n += snprintf(&buf[n], PAGE_SIZE - n, "\tErrorTSPackets = %-5d\t", - p->LayerInfo[i].ErrorTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, "TotalTSPackets = %-5d\t", - p->LayerInfo[i].TotalTSPackets); - n += snprintf(&buf[n], PAGE_SIZE - n, "TILdepthI = %d\n", - p->LayerInfo[i].TILdepthI); - n += snprintf(&buf[n], PAGE_SIZE - n, - "\tNumberOfSegments = %d\t", - p->LayerInfo[i].NumberOfSegments); - n += snprintf(&buf[n], PAGE_SIZE - n, "TMCCErrors = %d\n", - p->LayerInfo[i].TMCCErrors); - } - - atomic_set(&client->stats_count, n); - wake_up(&client->stats_queue); -} - -static int smsdvb_stats_open(struct inode *inode, struct file *file) -{ - struct smsdvb_client_t *client = inode->i_private; - - atomic_set(&client->stats_count, 0); - client->stats_was_read = false; - - init_waitqueue_head(&client->stats_queue); - - client->stats_data = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (client->stats_data == NULL) - return -ENOMEM; - - file->private_data = client; - - return 0; -} - -static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, - size_t nbytes, loff_t *ppos) -{ - struct smsdvb_client_t *client = file->private_data; - - if (!client->stats_data || client->stats_was_read) - return 0; - - wait_event_interruptible(client->stats_queue, - atomic_read(&client->stats_count)); - - return simple_read_from_buffer(user_buf, nbytes, ppos, - client->stats_data, - atomic_read(&client->stats_count)); - - client->stats_was_read = true; -} - -static int smsdvb_stats_release(struct inode *inode, struct file *file) -{ - struct smsdvb_client_t *client = file->private_data; - - kfree(client->stats_data); - client->stats_data = NULL; - - return 0; -} - -static const struct file_operations debugfs_stats_ops = { - .open = smsdvb_stats_open, - .read = smsdvb_stats_read, - .release = smsdvb_stats_release, - .llseek = generic_file_llseek, -}; - -static int create_stats_debugfs(struct smsdvb_client_t *client) -{ - struct smscore_device_t *coredev = client->coredev; - struct dentry *d; - - if (!smsdvb_debugfs) - return -ENODEV; - - client->debugfs = debugfs_create_dir(coredev->devpath, smsdvb_debugfs); - if (IS_ERR_OR_NULL(client->debugfs)) { - sms_info("Unable to create debugfs %s directory.\n", - coredev->devpath); - return -ENODEV; - } - - d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs, - client, &debugfs_stats_ops); - if (!d) { - debugfs_remove(client->debugfs); - return -ENOMEM; - } - - return 0; -} - -static void release_stats_debugfs(struct smsdvb_client_t *client) -{ - if (!client->debugfs) - return; - - debugfs_remove_recursive(client->debugfs); - - client->debugfs = NULL; -} - -/* Events that may come from DVB v3 adapter */ -static void sms_board_dvb3_event(struct smsdvb_client_t *client, - enum SMS_DVB3_EVENTS event) { - - struct smscore_device_t *coredev = client->coredev; - switch (event) { - case DVB3_EVENT_INIT: - sms_debug("DVB3_EVENT_INIT"); - sms_board_event(coredev, BOARD_EVENT_BIND); - break; - case DVB3_EVENT_SLEEP: - sms_debug("DVB3_EVENT_SLEEP"); - sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); - break; - case DVB3_EVENT_HOTPLUG: - sms_debug("DVB3_EVENT_HOTPLUG"); - sms_board_event(coredev, BOARD_EVENT_POWER_INIT); - break; - case DVB3_EVENT_FE_LOCK: - if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { - client->event_fe_state = DVB3_EVENT_FE_LOCK; - sms_debug("DVB3_EVENT_FE_LOCK"); - sms_board_event(coredev, BOARD_EVENT_FE_LOCK); - } - break; - case DVB3_EVENT_FE_UNLOCK: - if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { - client->event_fe_state = DVB3_EVENT_FE_UNLOCK; - sms_debug("DVB3_EVENT_FE_UNLOCK"); - sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); - } - break; - case DVB3_EVENT_UNC_OK: - if (client->event_unc_state != DVB3_EVENT_UNC_OK) { - client->event_unc_state = DVB3_EVENT_UNC_OK; - sms_debug("DVB3_EVENT_UNC_OK"); - sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); - } - break; - case DVB3_EVENT_UNC_ERR: - if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { - client->event_unc_state = DVB3_EVENT_UNC_ERR; - sms_debug("DVB3_EVENT_UNC_ERR"); - sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); - } - break; - - default: - sms_err("Unknown dvb3 api event"); - break; - } -} - -static void smsdvb_stats_not_ready(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int i, n_layers; - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - n_layers = 4; - default: - n_layers = 1; - } - - /* Fill the length of each status counter */ - - /* Only global stats */ - c->strength.len = 1; - c->cnr.len = 1; - - /* Per-layer stats */ - c->post_bit_error.len = n_layers; - c->post_bit_count.len = n_layers; - c->block_error.len = n_layers; - c->block_count.len = n_layers; - - /* Signal is always available */ - c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = 0; - - /* Put all of them at FE_SCALE_NOT_AVAILABLE */ - for (i = 0; i < n_layers; i++) { - c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; - c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; - c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; - c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; - c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; - } -} - -static inline int sms_to_mode(u32 mode) -{ - switch (mode) { - case 2: - return TRANSMISSION_MODE_2K; - case 4: - return TRANSMISSION_MODE_4K; - case 8: - return TRANSMISSION_MODE_8K; - } - return TRANSMISSION_MODE_AUTO; -} - -static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) -{ - if (is_demod_locked) - return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_LOCK; - - if (is_rf_locked) - return FE_HAS_SIGNAL | FE_HAS_CARRIER; - - return 0; -} - - -#define convert_from_table(value, table, defval) ({ \ - u32 __ret; \ - if (value < ARRAY_SIZE(table)) \ - __ret = table[value]; \ - else \ - __ret = defval; \ - __ret; \ -}) - -#define sms_to_bw(value) \ - convert_from_table(value, sms_to_bw_table, 0); - -#define sms_to_guard_interval(value) \ - convert_from_table(value, sms_to_guard_interval_table, \ - GUARD_INTERVAL_AUTO); - -#define sms_to_code_rate(value) \ - convert_from_table(value, sms_to_code_rate_table, \ - FEC_NONE); - -#define sms_to_hierarchy(value) \ - convert_from_table(value, sms_to_hierarchy_table, \ - FEC_NONE); - -#define sms_to_modulation(value) \ - convert_from_table(value, sms_to_modulation_table, \ - FEC_NONE); - -static void smsdvb_update_tx_params(struct smsdvb_client_t *client, - struct TRANSMISSION_STATISTICS_S *p) -{ - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - c->frequency = p->Frequency; - client->fe_status = sms_to_status(p->IsDemodLocked, 0); - c->bandwidth_hz = sms_to_bw(p->Bandwidth); - c->transmission_mode = sms_to_mode(p->TransmissionMode); - c->guard_interval = sms_to_guard_interval(p->GuardInterval); - c->code_rate_HP = sms_to_code_rate(p->CodeRate); - c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); - c->hierarchy = sms_to_hierarchy(p->Hierarchy); - c->modulation = sms_to_modulation(p->Constellation); -} - -static void smsdvb_update_per_slices(struct smsdvb_client_t *client, - struct RECEPTION_STATISTICS_PER_SLICES_S *p) -{ - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); - c->modulation = sms_to_modulation(p->constellation); - - /* TS PER */ - client->last_per = c->block_error.stat[0].uvalue; - c->block_error.stat[0].scale = FE_SCALE_COUNTER; - c->block_count.stat[0].scale = FE_SCALE_COUNTER; - c->block_error.stat[0].uvalue += p->etsPackets; - c->block_count.stat[0].uvalue += p->etsPackets + p->tsPackets; - - /* BER */ - c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[0].uvalue += p->BERErrorCount; - c->post_bit_count.stat[0].uvalue += p->BERBitCount; - - /* Legacy PER/BER */ - client->legacy_per = (p->etsPackets * 65535) / - (p->tsPackets + p->etsPackets); - - /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; - - /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - c->cnr.stat[0].svalue = p->snr * 1000; -} - -static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ST *p) -{ - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - smsdvb_print_dvb_stats(client, p); - - client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); - - /* Update DVB modulation parameters */ - c->frequency = p->Frequency; - client->fe_status = sms_to_status(p->IsDemodLocked, 0); - c->bandwidth_hz = sms_to_bw(p->Bandwidth); - c->transmission_mode = sms_to_mode(p->TransmissionMode); - c->guard_interval = sms_to_guard_interval(p->GuardInterval); - c->code_rate_HP = sms_to_code_rate(p->CodeRate); - c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); - c->hierarchy = sms_to_hierarchy(p->Hierarchy); - c->modulation = sms_to_modulation(p->Constellation); - - /* update reception data */ - c->lna = p->IsExternalLNAOn ? 1 : 0; - - /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - c->cnr.stat[0].svalue = p->SNR * 1000; - - /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; - - /* TS PER */ - client->last_per = c->block_error.stat[0].uvalue; - c->block_error.stat[0].scale = FE_SCALE_COUNTER; - c->block_count.stat[0].scale = FE_SCALE_COUNTER; - c->block_error.stat[0].uvalue += p->ErrorTSPackets; - c->block_count.stat[0].uvalue += p->TotalTSPackets; - - /* BER */ - c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[0].uvalue += p->BERErrorCount; - c->post_bit_count.stat[0].uvalue += p->BERBitCount; - - /* Legacy PER/BER */ - client->legacy_ber = p->BER; -}; - -static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) -{ - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; - int i, n_layers; - - smsdvb_print_isdb_stats(client, p); - - /* Update ISDB-T transmission parameters */ - c->frequency = p->Frequency; - client->fe_status = sms_to_status(p->IsDemodLocked, 0); - c->bandwidth_hz = sms_to_bw(p->Bandwidth); - c->transmission_mode = sms_to_mode(p->TransmissionMode); - c->guard_interval = sms_to_guard_interval(p->GuardInterval); - c->isdbt_partial_reception = p->PartialReception ? 1 : 0; - n_layers = p->NumOfLayers; - if (n_layers < 1) - n_layers = 1; - if (n_layers > 3) - n_layers = 3; - c->isdbt_layer_enabled = 0; - - /* update reception data */ - c->lna = p->IsExternalLNAOn ? 1 : 0; - - /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - c->cnr.stat[0].svalue = p->SNR * 1000; - - /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; - - client->last_per = c->block_error.stat[0].uvalue; - - /* Clears global counters, as the code below will sum it again */ - c->block_error.stat[0].uvalue = 0; - c->block_count.stat[0].uvalue = 0; - c->post_bit_error.stat[0].uvalue = 0; - c->post_bit_count.stat[0].uvalue = 0; - - for (i = 0; i < n_layers; i++) { - lr = &p->LayerInfo[i]; - - /* Update per-layer transmission parameters */ - if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { - c->isdbt_layer_enabled |= 1 << i; - c->layer[i].segment_count = lr->NumberOfSegments; - } else { - continue; - } - c->layer[i].modulation = sms_to_modulation(lr->Constellation); - - /* TS PER */ - c->block_error.stat[i].scale = FE_SCALE_COUNTER; - c->block_count.stat[i].scale = FE_SCALE_COUNTER; - c->block_error.stat[i].uvalue += lr->ErrorTSPackets; - c->block_count.stat[i].uvalue += lr->TotalTSPackets; - - /* Update global PER counter */ - c->block_error.stat[0].uvalue += lr->ErrorTSPackets; - c->block_count.stat[0].uvalue += lr->TotalTSPackets; - - /* BER */ - c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[i].uvalue += lr->BERBitCount; - - /* Update global BER counter */ - c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[0].uvalue += lr->BERBitCount; - } -} - -static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, - struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) -{ - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; - int i, n_layers; - - smsdvb_print_isdb_stats_ex(client, p); - - /* Update ISDB-T transmission parameters */ - c->frequency = p->Frequency; - client->fe_status = sms_to_status(p->IsDemodLocked, 0); - c->bandwidth_hz = sms_to_bw(p->Bandwidth); - c->transmission_mode = sms_to_mode(p->TransmissionMode); - c->guard_interval = sms_to_guard_interval(p->GuardInterval); - c->isdbt_partial_reception = p->PartialReception ? 1 : 0; - n_layers = p->NumOfLayers; - if (n_layers < 1) - n_layers = 1; - if (n_layers > 3) - n_layers = 3; - c->isdbt_layer_enabled = 0; - - /* update reception data */ - c->lna = p->IsExternalLNAOn ? 1 : 0; - - /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - c->cnr.stat[0].svalue = p->SNR * 1000; - - /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; - - client->last_per = c->block_error.stat[0].uvalue; - - /* Clears global counters, as the code below will sum it again */ - c->block_error.stat[0].uvalue = 0; - c->block_count.stat[0].uvalue = 0; - c->post_bit_error.stat[0].uvalue = 0; - c->post_bit_count.stat[0].uvalue = 0; - - for (i = 0; i < n_layers; i++) { - lr = &p->LayerInfo[i]; - - /* Update per-layer transmission parameters */ - if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { - c->isdbt_layer_enabled |= 1 << i; - c->layer[i].segment_count = lr->NumberOfSegments; - } else { - continue; - } - c->layer[i].modulation = sms_to_modulation(lr->Constellation); - - /* TS PER */ - c->block_error.stat[i].scale = FE_SCALE_COUNTER; - c->block_count.stat[i].scale = FE_SCALE_COUNTER; - c->block_error.stat[i].uvalue += lr->ErrorTSPackets; - c->block_count.stat[i].uvalue += lr->TotalTSPackets; - - /* Update global PER counter */ - c->block_error.stat[0].uvalue += lr->ErrorTSPackets; - c->block_count.stat[0].uvalue += lr->TotalTSPackets; - - /* BER */ - c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[i].uvalue += lr->BERBitCount; - - /* Update global BER counter */ - c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[0].uvalue += lr->BERBitCount; - } -} - -static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) -{ - struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) - + cb->offset); - void *p = phdr + 1; - struct dvb_frontend *fe = &client->frontend; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - bool is_status_update = false; - - switch (phdr->msgType) { - case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, p, - cb->size - sizeof(struct SmsMsgHdr_ST)); - break; - - case MSG_SMS_RF_TUNE_RES: - case MSG_SMS_ISDBT_TUNE_RES: - complete(&client->tune_done); - break; - - case MSG_SMS_SIGNAL_DETECTED_IND: - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - - is_status_update = true; - break; - - case MSG_SMS_NO_SIGNAL_IND: - client->fe_status = 0; - - is_status_update = true; - break; - - case MSG_SMS_TRANSMISSION_IND: - smsdvb_update_tx_params(client, p); - - is_status_update = true; - break; - - case MSG_SMS_HO_PER_SLICES_IND: - smsdvb_update_per_slices(client, p); - - is_status_update = true; - break; - - case MSG_SMS_GET_STATISTICS_RES: - switch (smscore_get_device_mode(client->coredev)) { - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - smsdvb_update_isdbt_stats(client, p); - break; - default: - /* Skip SmsMsgStatisticsInfo_ST:RequestResult field */ - smsdvb_update_dvb_stats(client, p + sizeof(u32)); - } - - is_status_update = true; - break; - - /* Only for ISDB-T */ - case MSG_SMS_GET_STATISTICS_EX_RES: - /* Skip SmsMsgStatisticsInfo_ST:RequestResult field? */ - smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); - is_status_update = true; - break; - default: - sms_info("message not handled"); - } - smscore_putbuffer(client->coredev, cb); - - if (is_status_update) { - if (client->fe_status == FE_HAS_LOCK) { - sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); - if (client->last_per == c->block_error.stat[0].uvalue) - sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); - else - sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); - } else { - smsdvb_stats_not_ready(fe); - - sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); - } - complete(&client->stats_done); - } - - return 0; -} - -static void smsdvb_unregister_client(struct smsdvb_client_t *client) -{ - /* must be called under clientslock */ - - list_del(&client->entry); - - release_stats_debugfs(client); - smscore_unregister_client(client->smsclient); - dvb_unregister_frontend(&client->frontend); - dvb_dmxdev_release(&client->dmxdev); - dvb_dmx_release(&client->demux); - dvb_unregister_adapter(&client->adapter); - kfree(client); -} - -static void smsdvb_onremove(void *context) -{ - kmutex_lock(&g_smsdvb_clientslock); - - smsdvb_unregister_client((struct smsdvb_client_t *) context); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -static int smsdvb_start_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("add pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("remove pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, - void *buffer, size_t size, - struct completion *completion) -{ - int rc; - - rc = smsclient_sendrequest(client->smsclient, buffer, size); - if (rc < 0) - return rc; - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(2000)) ? - 0 : -ETIME; -} - -static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) -{ - int rc; - struct SmsMsgHdr_ST Msg; - - - Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.msgDstId = HIF_TASK; - Msg.msgFlags = 0; - Msg.msgLength = sizeof(Msg); - - switch (smscore_get_device_mode(client->coredev)) { - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - /* - * Check for firmware version, to avoid breaking for old cards - */ - if (client->coredev->fw_version >= 0x800) - Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; - else - Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; - break; - default: - Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; - } - - rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->stats_done); - - return rc; -} - -static inline int led_feedback(struct smsdvb_client_t *client) -{ - if (!(client->fe_status & FE_HAS_LOCK)) - return sms_board_led_feedback(client->coredev, SMS_LED_OFF); - - return sms_board_led_feedback(client->coredev, - (client->legacy_ber == 0) ? - SMS_LED_HI : SMS_LED_LO); -} - -static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - int rc; - struct smsdvb_client_t *client; - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *stat = client->fe_status; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - int rc; - struct smsdvb_client_t *client; - - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *ber = client->legacy_ber; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int rc; - s32 power = (s32) c->strength.stat[0].uvalue; - struct smsdvb_client_t *client; - - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - if (power < -95) - *strength = 0; - else if (power > -29) - *strength = 65535; - else - *strength = (power + 95) * 65535 / 66; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int rc; - struct smsdvb_client_t *client; - - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - /* Preferred scale for SNR with legacy API: 0.1 dB */ - *snr = c->cnr.stat[0].svalue / 100; - - led_feedback(client); - - return rc; -} - -static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - int rc; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct smsdvb_client_t *client; - - client = container_of(fe, struct smsdvb_client_t, frontend); - - rc = smsdvb_send_statistics_request(client); - - *ucblocks = c->block_error.stat[0].uvalue; - - led_feedback(client); - - return rc; -} - -static int smsdvb_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - sms_debug(""); - - tune->min_delay_ms = 400; - tune->step_size = 250000; - tune->max_drift = 0; - return 0; -} - -static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - struct { - struct SmsMsgHdr_ST Msg; - u32 Data[3]; - } Msg; - - int ret; - - client->fe_status = 0; - client->event_fe_state = -1; - client->event_unc_state = -1; - fe->dtv_property_cache.delivery_system = SYS_DVBT; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - Msg.Data[0] = c->frequency; - Msg.Data[2] = 12000000; - - sms_info("%s: freq %d band %d", __func__, c->frequency, - c->bandwidth_hz); - - switch (c->bandwidth_hz / 1000000) { - case 8: - Msg.Data[1] = BW_8_MHZ; - break; - case 7: - Msg.Data[1] = BW_7_MHZ; - break; - case 6: - Msg.Data[1] = BW_6_MHZ; - break; - case 0: - return -EOPNOTSUPP; - default: - return -EINVAL; - } - /* Disable LNA, if any. An error is returned if no LNA is present */ - ret = sms_board_lna_control(client->coredev, 0); - if (ret == 0) { - fe_status_t status; - - /* tune with LNA off at first */ - ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - smsdvb_read_status(fe, &status); - - if (status & FE_HAS_LOCK) - return ret; - - /* previous tune didn't lock - enable LNA and tune again */ - sms_board_lna_control(client->coredev, 1); - } - - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); -} - -static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int board_id = smscore_get_board_id(client->coredev); - struct sms_board *board = sms_get_board(board_id); - enum sms_device_type_st type = board->type; - int ret; - struct { - struct SmsMsgHdr_ST Msg; - u32 Data[4]; - } Msg; - - fe->dtv_property_cache.delivery_system = SYS_ISDBT; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - - if (c->isdbt_sb_segment_idx == -1) - c->isdbt_sb_segment_idx = 0; - - if (!c->isdbt_layer_enabled) - c->isdbt_layer_enabled = 7; - - Msg.Data[0] = c->frequency; - Msg.Data[1] = BW_ISDBT_1SEG; - Msg.Data[2] = 12000000; - Msg.Data[3] = c->isdbt_sb_segment_idx; - - if (c->isdbt_partial_reception) { - if ((type == SMS_PELE || type == SMS_RIO) && - c->isdbt_sb_segment_count > 3) - Msg.Data[1] = BW_ISDBT_13SEG; - else if (c->isdbt_sb_segment_count > 1) - Msg.Data[1] = BW_ISDBT_3SEG; - } else if (type == SMS_PELE || type == SMS_RIO) - Msg.Data[1] = BW_ISDBT_13SEG; - - c->bandwidth_hz = 6000000; - - sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, - c->frequency, c->isdbt_sb_segment_count, - c->isdbt_sb_segment_idx); - - /* Disable LNA, if any. An error is returned if no LNA is present */ - ret = sms_board_lna_control(client->coredev, 0); - if (ret == 0) { - fe_status_t status; - - /* tune with LNA off at first */ - ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - smsdvb_read_status(fe, &status); - - if (status & FE_HAS_LOCK) - return ret; - - /* previous tune didn't lock - enable LNA and tune again */ - sms_board_lna_control(client->coredev, 1); - } - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); -} - -static int smsdvb_set_frontend(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - struct smscore_device_t *coredev = client->coredev; - - smsdvb_stats_not_ready(fe); - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - return smsdvb_dvbt_set_frontend(fe); - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - return smsdvb_isdbt_set_frontend(fe); - default: - return -EINVAL; - } -} - -/* Nothing to do here, as stats are automatically updated */ -static int smsdvb_get_frontend(struct dvb_frontend *fe) -{ - return 0; -} - -static int smsdvb_init(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_power(client->coredev, 1); - - sms_board_dvb3_event(client, DVB3_EVENT_INIT); - return 0; -} - -static int smsdvb_sleep(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - sms_board_power(client->coredev, 0); - - sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); - - return 0; -} - -static void smsdvb_release(struct dvb_frontend *fe) -{ - /* do nothing */ -} - -static struct dvb_frontend_ops smsdvb_fe_ops = { - .info = { - .name = "Siano Mobile Digital MDTV Receiver", - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = smsdvb_release, - - .set_frontend = smsdvb_set_frontend, - .get_frontend = smsdvb_get_frontend, - .get_tune_settings = smsdvb_get_tune_settings, - - .read_status = smsdvb_read_status, - .read_ber = smsdvb_read_ber, - .read_signal_strength = smsdvb_read_signal_strength, - .read_snr = smsdvb_read_snr, - .read_ucblocks = smsdvb_read_ucblocks, - - .init = smsdvb_init, - .sleep = smsdvb_sleep, -}; - -static int smsdvb_hotplug(struct smscore_device_t *coredev, - struct device *device, int arrival) -{ - struct smsclient_params_t params; - struct smsdvb_client_t *client; - int rc; - - /* device removal handled by onremove callback */ - if (!arrival) - return 0; - client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); - if (!client) { - sms_err("kmalloc() failed"); - return -ENOMEM; - } - - /* register dvb adapter */ - rc = dvb_register_adapter(&client->adapter, - sms_get_board( - smscore_get_board_id(coredev))->name, - THIS_MODULE, device, adapter_nr); - if (rc < 0) { - sms_err("dvb_register_adapter() failed %d", rc); - goto adapter_error; - } - - /* init dvb demux */ - client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; /* todo: nova ??? */ - client->demux.feednum = 32; - client->demux.start_feed = smsdvb_start_feed; - client->demux.stop_feed = smsdvb_stop_feed; - - rc = dvb_dmx_init(&client->demux); - if (rc < 0) { - sms_err("dvb_dmx_init failed %d", rc); - goto dvbdmx_error; - } - - /* init dmxdev */ - client->dmxdev.filternum = 32; - client->dmxdev.demux = &client->demux.dmx; - client->dmxdev.capabilities = 0; - - rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); - if (rc < 0) { - sms_err("dvb_dmxdev_init failed %d", rc); - goto dmxdev_error; - } - - /* init and register frontend */ - memcpy(&client->frontend.ops, &smsdvb_fe_ops, - sizeof(struct dvb_frontend_ops)); - - switch (smscore_get_device_mode(coredev)) { - case DEVICE_MODE_DVBT: - case DEVICE_MODE_DVBT_BDA: - client->frontend.ops.delsys[0] = SYS_DVBT; - break; - case DEVICE_MODE_ISDBT: - case DEVICE_MODE_ISDBT_BDA: - client->frontend.ops.delsys[0] = SYS_ISDBT; - break; - } - - rc = dvb_register_frontend(&client->adapter, &client->frontend); - if (rc < 0) { - sms_err("frontend registration failed %d", rc); - goto frontend_error; - } - - params.initial_id = 1; - params.data_type = MSG_SMS_DVBT_BDA_DATA; - params.onresponse_handler = smsdvb_onresponse; - params.onremove_handler = smsdvb_onremove; - params.context = client; - - rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) { - sms_err("smscore_register_client() failed %d", rc); - goto client_error; - } - - client->coredev = coredev; - - init_completion(&client->tune_done); - init_completion(&client->stats_done); - - kmutex_lock(&g_smsdvb_clientslock); - - list_add(&client->entry, &g_smsdvb_clients); - - kmutex_unlock(&g_smsdvb_clientslock); - - client->event_fe_state = -1; - client->event_unc_state = -1; - sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); - - sms_info("success"); - sms_board_setup(coredev); - - if (create_stats_debugfs(client) < 0) - sms_info("failed to create debugfs node"); - - return 0; - -client_error: - dvb_unregister_frontend(&client->frontend); - -frontend_error: - dvb_dmxdev_release(&client->dmxdev); - -dmxdev_error: - dvb_dmx_release(&client->demux); - -dvbdmx_error: - dvb_unregister_adapter(&client->adapter); - -adapter_error: - kfree(client); - return rc; -} - -static int __init smsdvb_module_init(void) -{ - int rc; - struct dentry *d; - - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - d = debugfs_create_dir("smsdvb", usb_debug_root); - if (IS_ERR_OR_NULL(d)) - sms_err("Couldn't create sysfs node for smsdvb"); - else - smsdvb_debugfs = d; - - rc = smscore_register_hotplug(smsdvb_hotplug); - - sms_debug(""); - - return rc; -} - -static void __exit smsdvb_module_exit(void) -{ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client( - (struct smsdvb_client_t *) g_smsdvb_clients.next); - - if (smsdvb_debugfs) - debugfs_remove_recursive(smsdvb_debugfs); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -module_init(smsdvb_module_init); -module_exit(smsdvb_module_exit); - -MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); -MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h new file mode 100644 index 000000000000..09982bcf2535 --- /dev/null +++ b/drivers/media/common/siano/smsdvb.h @@ -0,0 +1,124 @@ +/*********************************************************************** + * + * 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 . + * + ***********************************************************************/ + +struct smsdvb_debugfs; +struct smsdvb_client_t; + +typedef void (*sms_prt_dvb_stats_t)(struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ST *p); + +typedef void (*sms_prt_isdb_stats_t)(struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p); + +typedef void (*sms_prt_isdb_stats_ex_t) + (struct smsdvb_debugfs *debug_data, + struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p); + + +struct smsdvb_client_t { + struct list_head entry; + + struct smscore_device_t *coredev; + struct smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + + struct completion tune_done; + struct completion stats_done; + + int last_per; + + int legacy_ber, legacy_per; + + int event_fe_state; + int event_unc_state; + + /* Stats debugfs data */ + struct dentry *debugfs; + + struct smsdvb_debugfs *debug_data; + + sms_prt_dvb_stats_t prt_dvb_stats; + sms_prt_isdb_stats_t prt_isdb_stats; + sms_prt_isdb_stats_ex_t prt_isdb_stats_ex; +}; + +/* + * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S. + * It was obtained by comparing the way it was filled by the original code + */ +struct RECEPTION_STATISTICS_PER_SLICES_S { + u32 result; + u32 snr; + s32 inBandPower; + u32 tsPackets; + u32 etsPackets; + u32 constellation; + u32 hpCode; + u32 tpsSrvIndLP; + u32 tpsSrvIndHP; + u32 cellId; + u32 reason; + u32 requestId; + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + + u32 BER; /* Post Viterbi BER [1E-5] */ + s32 RSSI; /* dBm */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ + + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + + u32 BERBitCount; /* Total number of SYNC bits. */ + u32 BERErrorCount; /* Number of erronous SYNC bits. */ + + s32 MRC_SNR; /* dB */ + s32 MRC_InBandPwr; /* In band power in dBM */ + s32 MRC_RSSI; /* dBm */ +}; + +/* From smsdvb-debugfs.c */ +#ifdef CONFIG_SMS_SIANO_DEBUGFS + +int smsdvb_debugfs_create(struct smsdvb_client_t *client); +void smsdvb_debugfs_release(struct smsdvb_client_t *client); +int smsdvb_debugfs_register(void); +void smsdvb_debugfs_unregister(void); + +#else + +static inline int smsdvb_debugfs_create(struct smsdvb_client_t *client) +{ + return 0; +} + +static inline void smsdvb_debugfs_release(struct smsdvb_client_t *client) {} + +static inline int smsdvb_debugfs_register(void) +{ + return 0; +}; + +static inline void smsdvb_debugfs_unregister(void) {}; + +#endif + diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index acd3d1e82e03..def5e41405a4 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -412,6 +412,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) smscore_set_board_id(dev->coredev, board_id); + dev->coredev->is_usb_device = true; + /* initialize urbs */ for (i = 0; i < MAX_URBS; i++) { dev->surbs[i].dev = dev; -- cgit From 4cce1f4eb29765def538e7c975dac73346a0d306 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 16 Mar 2013 14:32:25 -0300 Subject: [media] siano: add two missing fields to ISDB-T stats debugfs Those fields help to identify the version of the ISDB stats. Useful while debuging the driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-debugfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c index 4d5dd471e2e1..59c7323f98d4 100644 --- a/drivers/media/common/siano/smsdvb-debugfs.c +++ b/drivers/media/common/siano/smsdvb-debugfs.c @@ -165,6 +165,11 @@ void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data, buf = debug_data->stats_data; + n += snprintf(&buf[n], PAGE_SIZE - n, + "StatisticsType = %d\t", p->StatisticsType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "FullSize = %d\n", p->FullSize); + n += snprintf(&buf[n], PAGE_SIZE - n, "IsRfLocked = %d\t\t", p->IsRfLocked); n += snprintf(&buf[n], PAGE_SIZE - n, @@ -250,6 +255,11 @@ void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data, buf = debug_data->stats_data; + n += snprintf(&buf[n], PAGE_SIZE - n, + "StatisticsType = %d\t", p->StatisticsType); + n += snprintf(&buf[n], PAGE_SIZE - n, + "FullSize = %d\n", p->FullSize); + n += snprintf(&buf[n], PAGE_SIZE - n, "IsRfLocked = %d\t\t", p->IsRfLocked); n += snprintf(&buf[n], PAGE_SIZE - n, -- cgit From a9b9fbdf0a6a65359cd97254a282526822de5257 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Mar 2013 10:51:25 -0300 Subject: [media] siano: don't request statistics too fast As each DVBv3 call may generate an stats overhead, prevent doing it too fast. This is specially useful if a burst of get stats DVBv3 call is sent. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 5 +++++ drivers/media/common/siano/smsdvb.h | 2 ++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index c14f10d5d6c0..4242005082ed 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -663,6 +663,11 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) int rc; struct SmsMsgHdr_ST Msg; + /* Don't request stats too fast */ + if (client->get_stats_jiffies && + (!time_after(jiffies, client->get_stats_jiffies))) + return 0; + client->get_stats_jiffies = jiffies + msecs_to_jiffies(100); Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; Msg.msgDstId = HIF_TASK; diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h index 09982bcf2535..34220696d87d 100644 --- a/drivers/media/common/siano/smsdvb.h +++ b/drivers/media/common/siano/smsdvb.h @@ -52,6 +52,8 @@ struct smsdvb_client_t { int event_fe_state; int event_unc_state; + unsigned long get_stats_jiffies; + /* Stats debugfs data */ struct dentry *debugfs; -- cgit From f5de95e2467b7b6b968e6c67489425265dd2a1c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Mar 2013 12:06:30 -0300 Subject: [media] siano: fix signal strength and CNR stats measurements There are a number of small issues with the stats refactoring: - InBandPwr better represents the signal strength; - Don't zero signal strength /cnr if no lock; - Fix signal strength/cnr scale; - Don't need to fill PER/BER if not locked, as the code will disable those stats anyway. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 57 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 4242005082ed..90f6e894e593 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -155,11 +155,11 @@ static void smsdvb_stats_not_ready(struct dvb_frontend *fe) n_layers = 1; } - /* Fill the length of each status counter */ - - /* Only global stats */ + /* Global stats */ c->strength.len = 1; c->cnr.len = 1; + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; /* Per-layer stats */ c->post_bit_error.len = n_layers; @@ -167,13 +167,11 @@ static void smsdvb_stats_not_ready(struct dvb_frontend *fe) c->block_error.len = n_layers; c->block_count.len = n_layers; - /* Signal is always available */ - c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = 0; - - /* Put all of them at FE_SCALE_NOT_AVAILABLE */ + /* + * Put all of them at FE_SCALE_NOT_AVAILABLE. They're dynamically + * changed when the stats become available. + */ for (i = 0; i < n_layers; i++) { - c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; @@ -261,6 +259,16 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client, client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); c->modulation = sms_to_modulation(p->constellation); + /* Signal Strength, in DBm */ + c->strength.stat[0].uvalue = p->inBandPower * 1000; + + /* Carrier to Noise ratio, in DB */ + c->cnr.stat[0].svalue = p->snr * 1000; + + /* PER/BER requires demod lock */ + if (!p->IsDemodLocked) + return; + /* TS PER */ client->last_per = c->block_error.stat[0].uvalue; c->block_error.stat[0].scale = FE_SCALE_COUNTER; @@ -277,13 +285,6 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client, /* Legacy PER/BER */ client->legacy_per = (p->etsPackets * 65535) / (p->tsPackets + p->etsPackets); - - /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; - - /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - c->cnr.stat[0].svalue = p->snr * 1000; } static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, @@ -312,11 +313,14 @@ static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, c->lna = p->IsExternalLNAOn ? 1 : 0; /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; c->cnr.stat[0].svalue = p->SNR * 1000; /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; + c->strength.stat[0].uvalue = p->InBandPwr * 1000; + + /* PER/BER requires demod lock */ + if (!p->IsDemodLocked) + return; /* TS PER */ client->last_per = c->block_error.stat[0].uvalue; @@ -364,11 +368,14 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, c->lna = p->IsExternalLNAOn ? 1 : 0; /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; c->cnr.stat[0].svalue = p->SNR * 1000; /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; + c->strength.stat[0].uvalue = p->InBandPwr * 1000; + + /* PER/BER and per-layer stats require demod lock */ + if (!p->IsDemodLocked) + return; client->last_per = c->block_error.stat[0].uvalue; @@ -441,11 +448,14 @@ static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, c->lna = p->IsExternalLNAOn ? 1 : 0; /* Carrier to Noise ratio, in DB */ - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; c->cnr.stat[0].svalue = p->SNR * 1000; /* Signal Strength, in DBm */ - c->strength.stat[0].uvalue = p->RSSI * 1000; + c->strength.stat[0].uvalue = p->InBandPwr * 1000; + + /* PER/BER and per-layer stats require demod lock */ + if (!p->IsDemodLocked) + return; client->last_per = c->block_error.stat[0].uvalue; @@ -943,11 +953,14 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) static int smsdvb_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); struct smscore_device_t *coredev = client->coredev; smsdvb_stats_not_ready(fe); + c->strength.stat[0].uvalue = 0; + c->cnr.stat[0].uvalue = 0; switch (smscore_get_device_mode(coredev)) { case DEVICE_MODE_DVBT: -- cgit From 9671045f4ce7a9e5eedc669a6921aeec26bd095e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Mar 2013 13:38:41 -0300 Subject: [media] siano: fix PER/BER report on DVBv5 The check for lock logic is broken. Due to that, no PER/BER stats will ever be showed, and the DVBV3 events will be wrong. Also, the per-layer PER/BER stats for ISDB-T are filled with the wrong index. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 46 ++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 90f6e894e593..632a250a42cf 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -382,8 +382,12 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, /* Clears global counters, as the code below will sum it again */ c->block_error.stat[0].uvalue = 0; c->block_count.stat[0].uvalue = 0; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; c->post_bit_error.stat[0].uvalue = 0; c->post_bit_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; for (i = 0; i < n_layers; i++) { lr = &p->LayerInfo[i]; @@ -398,20 +402,20 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, c->layer[i].modulation = sms_to_modulation(lr->Constellation); /* TS PER */ - c->block_error.stat[i].scale = FE_SCALE_COUNTER; - c->block_count.stat[i].scale = FE_SCALE_COUNTER; - c->block_error.stat[i].uvalue += lr->ErrorTSPackets; - c->block_count.stat[i].uvalue += lr->TotalTSPackets; + c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; + c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; + c->block_error.stat[i + 1].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i + 1].uvalue += lr->TotalTSPackets; /* Update global PER counter */ c->block_error.stat[0].uvalue += lr->ErrorTSPackets; c->block_count.stat[0].uvalue += lr->TotalTSPackets; /* BER */ - c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i + 1].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i + 1].uvalue += lr->BERBitCount; /* Update global BER counter */ c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; @@ -462,9 +466,17 @@ static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, /* Clears global counters, as the code below will sum it again */ c->block_error.stat[0].uvalue = 0; c->block_count.stat[0].uvalue = 0; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; c->post_bit_error.stat[0].uvalue = 0; c->post_bit_count.stat[0].uvalue = 0; + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.len = n_layers + 1; + c->post_bit_count.len = n_layers + 1; + c->block_error.len = n_layers + 1; + c->block_count.len = n_layers + 1; for (i = 0; i < n_layers; i++) { lr = &p->LayerInfo[i]; @@ -478,20 +490,20 @@ static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, c->layer[i].modulation = sms_to_modulation(lr->Constellation); /* TS PER */ - c->block_error.stat[i].scale = FE_SCALE_COUNTER; - c->block_count.stat[i].scale = FE_SCALE_COUNTER; - c->block_error.stat[i].uvalue += lr->ErrorTSPackets; - c->block_count.stat[i].uvalue += lr->TotalTSPackets; + c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER; + c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER; + c->block_error.stat[i + 1].uvalue += lr->ErrorTSPackets; + c->block_count.stat[i + 1].uvalue += lr->TotalTSPackets; /* Update global PER counter */ c->block_error.stat[0].uvalue += lr->ErrorTSPackets; c->block_count.stat[0].uvalue += lr->TotalTSPackets; /* BER */ - c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; - c->post_bit_count.stat[i].uvalue += lr->BERBitCount; + c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[i + 1].uvalue += lr->BERErrorCount; + c->post_bit_count.stat[i + 1].uvalue += lr->BERBitCount; /* Update global BER counter */ c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; @@ -572,7 +584,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) smscore_putbuffer(client->coredev, cb); if (is_status_update) { - if (client->fe_status == FE_HAS_LOCK) { + if (client->fe_status & FE_HAS_LOCK) { sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); if (client->last_per == c->block_error.stat[0].uvalue) sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); -- cgit From 5c3b87435b291efb260aec37fdbe397859e550c5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Mar 2013 19:21:13 -0300 Subject: [media] siano: Fix bandwidth report It was expected that the bandwidth would be following the defines at smscoreapi.h. However, this doesn't work. Instead, this field brings just the bandwidth in MHz. Convert it to Hertz. It should be noticed that, on ISDB, using the _EX request, the field TuneBW seems to show the value that matches the bandwidth code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 632a250a42cf..d83896bb98fd 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -43,18 +43,6 @@ module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); -u32 sms_to_bw_table[] = { - [BW_8_MHZ] = 8000000, - [BW_7_MHZ] = 7000000, - [BW_6_MHZ] = 6000000, - [BW_5_MHZ] = 5000000, - [BW_2_MHZ] = 2000000, - [BW_1_5_MHZ] = 1500000, - [BW_ISDBT_1SEG] = 6000000, - [BW_ISDBT_3SEG] = 6000000, - [BW_ISDBT_13SEG] = 6000000, -}; - u32 sms_to_guard_interval_table[] = { [0] = GUARD_INTERVAL_1_32, [1] = GUARD_INTERVAL_1_16, @@ -204,6 +192,10 @@ static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) return 0; } +static inline u32 sms_to_bw(u32 value) +{ + return value * 1000000; +} #define convert_from_table(value, table, defval) ({ \ u32 __ret; \ @@ -214,9 +206,6 @@ static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) __ret; \ }) -#define sms_to_bw(value) \ - convert_from_table(value, sms_to_bw_table, 0); - #define sms_to_guard_interval(value) \ convert_from_table(value, sms_to_guard_interval_table, \ GUARD_INTERVAL_AUTO); -- cgit From e1b2ac4d1e6bb214823c42bb807a6cc5f21aa223 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Mar 2013 07:22:08 -0300 Subject: [media] siano: Only feed DVB data when there's a feed Right now, the driver sends DVB data even before tunning. It was noticed that this may lead into some mistakes at DVB decode, as the PIDs from wrong channels may be associated with another frequency, as they may already be inside the PID buffers. So, prevent it by not feeding DVB demux with data while there's no feed or while the device is not tuned. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 18 +++++++++++++++--- drivers/media/common/siano/smsdvb.h | 3 +++ 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index d83896bb98fd..4393c688d0ad 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -512,8 +512,13 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, p, - cb->size - sizeof(struct SmsMsgHdr_ST)); + /* + * Only feed data to dvb demux if are there any feed listening + * to it and if the device has tuned + */ + if (client->feed_users && client->has_tuned) + dvb_dmx_swfilter(&client->demux, p, + cb->size - sizeof(struct SmsMsgHdr_ST)); break; case MSG_SMS_RF_TUNE_RES: @@ -579,9 +584,10 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); else sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); + client->has_tuned = true; } else { smsdvb_stats_not_ready(fe); - + client->has_tuned = false; sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); } complete(&client->stats_done); @@ -623,6 +629,8 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) sms_debug("add pid %d(%x)", feed->pid, feed->pid); + client->feed_users++; + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; PidMsg.xMsgHeader.msgFlags = 0; @@ -643,6 +651,8 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) sms_debug("remove pid %d(%x)", feed->pid, feed->pid); + client->feed_users--; + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; PidMsg.xMsgHeader.msgFlags = 0; @@ -963,6 +973,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) c->strength.stat[0].uvalue = 0; c->cnr.stat[0].uvalue = 0; + client->has_tuned = false; + switch (smscore_get_device_mode(coredev)) { case DEVICE_MODE_DVBT: case DEVICE_MODE_DVBT_BDA: diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h index 34220696d87d..63cdd755521e 100644 --- a/drivers/media/common/siano/smsdvb.h +++ b/drivers/media/common/siano/smsdvb.h @@ -54,6 +54,9 @@ struct smsdvb_client_t { unsigned long get_stats_jiffies; + int feed_users; + bool has_tuned; + /* Stats debugfs data */ struct dentry *debugfs; -- cgit From 773adad14135999380a4652b4ba01c5694827870 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 16 Mar 2013 21:05:30 -0300 Subject: [media] siano: fix status report with old firmware and ISDB-T This seems to be ever broken. That's the status report with Firmware 2.1, before adding support for sms2270 is: [22273.787218] smsdvb_onresponse: MSG_SMS_GET_STATISTICS_RES [22273.792592] IsRfLocked = 1 [22273.792592] IsDemodLocked = 1 ... [22273.792598] TransmissionMode = -64 ... (all unshown fields are filled with zeros) Of course, transmission mode being a negative number is wrong. So, we need to take a deeper look on it. With the debugfs patches applied, it is possible to see that, instead of filling StatisticsType with 5, and FullSize with the size of the payload (this is what happens with sms2270 and firmware 8.1), those fields are also initialized with zero: StatisticsType = 0 FullSize = 0 IsRfLocked = 1 IsDemodLocked = 1 IsExternalLNAOn = 0 SNR = 0 dB RSSI = 0 dBm InBandPwr = 0 dBm CarrierOffset = 0 Bandwidth = 0 Frequency = 0 Hz TransmissionMode = -64 ModemState = 0 GuardInterval = 0 SystemType = 0 PartialReception = 0 NumOfLayers = 0 SmsToHostTxErrors = 0 The data under "TransmissionMode" varies according with the signal, and it is negative. It also matches the value for InBandPwr when the tuner is on DVB-T (ok, signal doesn't lock, but the power level should be about the same with the antena fixed, and measured at about the same time). So, there's a very high chance that, when StatisticsType is zero, the signal strength is at the same position as Transmission Mode. So, discard all other parameters, and provide only signal/rf lock and signal strength if StatisticsType is 0, for ISDB-T. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 4393c688d0ad..c53cb4e8d0c6 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -339,9 +339,21 @@ static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, if (client->prt_isdb_stats) client->prt_isdb_stats(client->debug_data, p); + client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); + + /* + * Firmware 2.1 seems to report only lock status and + * Signal strength. The signal strength indicator is at the + * wrong field. + */ + if (p->StatisticsType == 0) { + c->strength.stat[0].uvalue = ((s32)p->TransmissionMode) * 1000; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return; + } + /* Update ISDB-T transmission parameters */ c->frequency = p->Frequency; - client->fe_status = sms_to_status(p->IsDemodLocked, 0); c->bandwidth_hz = sms_to_bw(p->Bandwidth); c->transmission_mode = sms_to_mode(p->TransmissionMode); c->guard_interval = sms_to_guard_interval(p->GuardInterval); -- cgit From 6a28bd94f4d068b6de65517e52f52b6840603d0a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 17 Mar 2013 10:27:44 -0300 Subject: [media] siano: add support for .poll on debugfs Implement poll() method for debugfs and be sure that the debug_data won't be freed on ir or on read(). With this change, poll() will return POLLIN if either data was filled or if data was read. That allows read() to return 0 to indicate EOF in the latter case. As poll() is now provided, fix support for non-block mode. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-debugfs.c | 77 ++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c index 59c7323f98d4..0219be36c289 100644 --- a/drivers/media/common/siano/smsdvb-debugfs.c +++ b/drivers/media/common/siano/smsdvb-debugfs.c @@ -352,6 +352,14 @@ static int smsdvb_stats_open(struct inode *inode, struct file *file) return 0; } +static void smsdvb_debugfs_data_release(struct kref *ref) +{ + struct smsdvb_debugfs *debug_data; + + debug_data = container_of(ref, struct smsdvb_debugfs, refcount); + kfree(debug_data); +} + static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data) { int rc = 1; @@ -368,33 +376,65 @@ exit: return rc; } -static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, - size_t nbytes, loff_t *ppos) +static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait) { - int rc = 0; struct smsdvb_debugfs *debug_data = file->private_data; + int rc; - rc = wait_event_interruptible(debug_data->stats_queue, - smsdvb_stats_wait_read(debug_data)); - if (rc < 0) - return rc; + kref_get(&debug_data->refcount); - rc = simple_read_from_buffer(user_buf, nbytes, ppos, - debug_data->stats_data, - debug_data->stats_count); - spin_lock(&debug_data->lock); - debug_data->stats_was_read = true; - spin_unlock(&debug_data->lock); + poll_wait(file, &debug_data->stats_queue, wait); + + rc = smsdvb_stats_wait_read(debug_data); + if (rc > 0) + rc = POLLIN | POLLRDNORM; + + kref_put(&debug_data->refcount, smsdvb_debugfs_data_release); return rc; } -static void smsdvb_debugfs_data_release(struct kref *ref) +static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, + size_t nbytes, loff_t *ppos) { - struct smsdvb_debugfs *debug_data; + int rc = 0, len; + struct smsdvb_debugfs *debug_data = file->private_data; - debug_data = container_of(ref, struct smsdvb_debugfs, refcount); - kfree(debug_data); + kref_get(&debug_data->refcount); + + if (file->f_flags & O_NONBLOCK) { + rc = smsdvb_stats_wait_read(debug_data); + if (!rc) { + rc = -EWOULDBLOCK; + goto ret; + } + } else { + rc = wait_event_interruptible(debug_data->stats_queue, + smsdvb_stats_wait_read(debug_data)); + if (rc < 0) + goto ret; + } + + if (debug_data->stats_was_read) { + rc = 0; /* EOF */ + goto ret; + } + + len = debug_data->stats_count - *ppos; + if (len >= 0) + rc = simple_read_from_buffer(user_buf, nbytes, ppos, + debug_data->stats_data, len); + else + rc = 0; + + if (*ppos >= debug_data->stats_count) { + spin_lock(&debug_data->lock); + debug_data->stats_was_read = true; + spin_unlock(&debug_data->lock); + } +ret: + kref_put(&debug_data->refcount, smsdvb_debugfs_data_release); + return rc; } static int smsdvb_stats_release(struct inode *inode, struct file *file) @@ -402,7 +442,7 @@ static int smsdvb_stats_release(struct inode *inode, struct file *file) struct smsdvb_debugfs *debug_data = file->private_data; spin_lock(&debug_data->lock); - debug_data->stats_was_read = true; + debug_data->stats_was_read = true; /* return EOF to read() */ spin_unlock(&debug_data->lock); wake_up_interruptible_sync(&debug_data->stats_queue); @@ -414,6 +454,7 @@ static int smsdvb_stats_release(struct inode *inode, struct file *file) static const struct file_operations debugfs_stats_ops = { .open = smsdvb_stats_open, + .poll = smsdvb_stats_poll, .read = smsdvb_stats_read, .release = smsdvb_stats_release, .llseek = generic_file_llseek, -- cgit From 5ac14b60118071631bb0e2e50527c7528675648c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 09:50:17 -0300 Subject: [media] siano: simplify firmware lookup logic There are two ways to specify firmware for siano devices: a per-device ID and a per-device type. The per-device type logic is currently made by a 11x9 string table, sparsely filled. It is very hard to read the table at the source code, as there are too much "none" filling there ("none" there is a way to tell NULL). Instead of using such problematic table, convert it into an easy to read table, where the unused values will be defaulted to NULL. While here, also simplifies a little bit the logic and print a message if an user-selected mode doesn't exist. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 91 +++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 8c576a6e3829..9b2f2b42bfbb 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1063,9 +1063,11 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, const struct firmware *fw; char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); - sms_debug("Firmware name: %s\n", fw_filename); - if (!strcmp(fw_filename, "none")) + if (!fw_filename) { + sms_info("mode %d not supported on this device", mode); return -ENOENT; + } + sms_debug("Firmware name: %s", fw_filename); if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) @@ -1198,32 +1200,53 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) return rc; } -static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - /*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */ - /*DVBT*/ - { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, - /*DVBH*/ - { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" }, - /*TDMB*/ - { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" }, - /*DABIP*/ - { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, - /*DVBT_BDA*/ - { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, - /*ISDBT*/ - { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, - /*ISDBT_BDA*/ - { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, - /*CMMB*/ - { "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" }, - /*RAW - not supported*/ - { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, - /*FM*/ - { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, - /*FM_BDA*/ - { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, - /*ATSC*/ - { "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" } +static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = { + [SMS_NOVA_A0] = { + [DEVICE_MODE_DVBT] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_DVBH] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz.inp", + }, + [SMS_NOVA_B0] = { + [DEVICE_MODE_DVBT] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_DVBH] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz_b0.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz_b0.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz_b0.inp", + [DEVICE_MODE_FM_RADIO] = "fm_radio.inp", + [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio.inp", + }, + [SMS_VEGA] = { + [DEVICE_MODE_CMMB] = "cmmb_vega_12mhz.inp", + }, + [SMS_VENICE] = { + [DEVICE_MODE_CMMB] = "cmmb_venice_12mhz.inp", + }, + [SMS_MING] = { + [DEVICE_MODE_CMMB] = "cmmb_ming_app.inp", + }, + [SMS_PELE] = { + [DEVICE_MODE_ISDBT] = "isdbt_pele.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_pele.inp", + }, + [SMS_RIO] = { + [DEVICE_MODE_DVBT] = "dvb_rio.inp", + [DEVICE_MODE_DVBH] = "dvbh_rio.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_rio.inp", + [DEVICE_MODE_ISDBT] = "isdbt_rio.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_rio.inp", + [DEVICE_MODE_FM_RADIO] = "fm_radio_rio.inp", + [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio_rio.inp", + }, + [SMS_DENVER_1530] = { + [DEVICE_MODE_ATSC] = "atsc_denver.inp", + }, + [SMS_DENVER_2160] = { + [DEVICE_MODE_DAB_TDMB] = "tdmb_denver.inp", + }, }; /** @@ -1249,22 +1272,16 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { sms_debug("trying to get fw name from lookup table mode %d type %d", mode, type); - return smscore_fw_lkup[mode][type]; + return smscore_fw_lkup[type][mode]; } sms_debug("trying to get fw name from sms_boards board_id %d mode %d", board_id, mode); fw = sms_get_board(board_id)->fw; - if (fw == NULL) { - sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", - mode, type); - return smscore_fw_lkup[mode][type]; - } - - if (fw[mode] == NULL) { + if (!fw || !fw[mode]) { sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", mode, type); - return smscore_fw_lkup[mode][type]; + return smscore_fw_lkup[type][mode]; } return fw[mode]; -- cgit From 9711a8a600a12d2895c18f31be1fc5b3c4d9b209 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 Mar 2013 11:40:45 -0300 Subject: [media] siano: honour per-card default mode Instead of using a global default_mode, passed via modprobe parameter, use the one defined inside the cards struct. That will prevent the need of manually specify it for each board, except, of course, if the user wants to do something different, on boards that accept multiple types. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 9b2f2b42bfbb..44040a60cd77 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -434,7 +434,7 @@ static struct mutex g_smscore_deviceslock; static struct list_head g_smscore_registry; static struct mutex g_smscore_registrylock; -static int default_mode = 4; +static int default_mode = DEVICE_MODE_NONE; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); @@ -880,8 +880,15 @@ int smscore_configure_board(struct smscore_device_t *coredev) */ int smscore_start_device(struct smscore_device_t *coredev) { - int rc = smscore_set_device_mode( - coredev, smscore_registry_getmode(coredev->devpath)); + int rc; + int board_id = smscore_get_board_id(coredev); + int mode = smscore_registry_getmode(coredev->devpath); + + /* Device is initialized as DEVICE_MODE_NONE */ + if (board_id != SMS_BOARD_UNKNOWN && mode == DEVICE_MODE_NONE) + mode = sms_get_board(board_id)->default_mode; + + rc = smscore_set_device_mode(coredev, mode); if (rc < 0) { sms_info("set device mode faile , rc %d", rc); return rc; @@ -1269,6 +1276,12 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, type = smscore_registry_gettype(coredev->devpath); + /* Prevent looking outside the smscore_fw_lkup table */ + if (type <= SMS_UNKNOWN_TYPE || type >= SMS_NUM_OF_DEVICE_TYPES) + return NULL; + if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) + return NULL; + if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { sms_debug("trying to get fw name from lookup table mode %d type %d", mode, type); @@ -1338,7 +1351,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) sms_debug("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { - if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) { + if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { sms_err("invalid mode specified %d", mode); return -EINVAL; } @@ -1390,7 +1403,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) sms_err("device init failed, rc %d.", rc); } } else { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_MAX) { + if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { sms_err("invalid mode specified %d", mode); return -EINVAL; } -- cgit From e584f9d61ea0aefa81ddd3faf53100536ba4057e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 12:00:23 -0300 Subject: [media] siano: remove the bogus firmware lookup code There is an special lookup code that is called when SMS_BOARD_UNKNOWN. The logic there is bogus and will cause an oops, as .type is SMS_UNKNOWN_TYPE (-1). As the code would do: return smscore_fw_lkup[type][mode]; That would mean that it would try to go past the smscore_fw_lkup table. So, just remove that bogus code, simplifying the logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 44040a60cd77..d57df9170ae1 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1048,7 +1048,7 @@ exit_fw_download: static char *smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode, int lookup); + int mode); /** * loads specified firmware into a buffer and calls device loadfirmware_handler @@ -1061,7 +1061,7 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, * @return 0 on success, <0 on error. */ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, - int mode, int lookup, + int mode, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; @@ -1069,7 +1069,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, u32 fw_buf_size; const struct firmware *fw; - char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); + char *fw_filename = smscore_get_fw_filename(coredev, mode); if (!fw_filename) { sms_info("mode %d not supported on this device", mode); return -ENOENT; @@ -1268,7 +1268,7 @@ static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = { * @return 0 on success, <0 on error. */ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode, int lookup) + int mode) { char **fw; int board_id = smscore_get_board_id(coredev); @@ -1282,12 +1282,6 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) return NULL; - if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { - sms_debug("trying to get fw name from lookup table mode %d type %d", - mode, type); - return smscore_fw_lkup[type][mode]; - } - sms_debug("trying to get fw name from sms_boards board_id %d mode %d", board_id, mode); fw = sms_get_board(board_id)->fw; @@ -1373,24 +1367,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) if (!(coredev->modes_supported & (1 << mode))) { rc = smscore_load_firmware_from_file(coredev, - mode, 0, NULL); - - /* - * try again with the default firmware - - * get the fw filename from look-up table - */ - if (rc < 0) { - sms_debug("error %d loading firmware, trying again with default firmware", - rc); - rc = smscore_load_firmware_from_file(coredev, - mode, 1, - NULL); - if (rc < 0) { - sms_debug("error %d loading firmware", - rc); - return rc; - } - } + mode, NULL); if (rc >= 0) sms_info("firmware download success"); } else { -- cgit From 2a7643159d0faf839529f5001737b996d53760d9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 12:06:08 -0300 Subject: [media] siano: reorder smscore_get_fw_filename() function Put this function earlier in the code, to avoid the need of defining a function stub. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 172 ++++++++++++++++---------------- 1 file changed, 84 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index d57df9170ae1..c04d8267adba 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1046,9 +1046,92 @@ exit_fw_download: return rc; } +static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = { + [SMS_NOVA_A0] = { + [DEVICE_MODE_DVBT] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_DVBH] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz.inp", + [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz.inp", + }, + [SMS_NOVA_B0] = { + [DEVICE_MODE_DVBT] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_DVBH] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz_b0.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz_b0.inp", + [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz_b0.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz_b0.inp", + [DEVICE_MODE_FM_RADIO] = "fm_radio.inp", + [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio.inp", + }, + [SMS_VEGA] = { + [DEVICE_MODE_CMMB] = "cmmb_vega_12mhz.inp", + }, + [SMS_VENICE] = { + [DEVICE_MODE_CMMB] = "cmmb_venice_12mhz.inp", + }, + [SMS_MING] = { + [DEVICE_MODE_CMMB] = "cmmb_ming_app.inp", + }, + [SMS_PELE] = { + [DEVICE_MODE_ISDBT] = "isdbt_pele.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_pele.inp", + }, + [SMS_RIO] = { + [DEVICE_MODE_DVBT] = "dvb_rio.inp", + [DEVICE_MODE_DVBH] = "dvbh_rio.inp", + [DEVICE_MODE_DVBT_BDA] = "dvb_rio.inp", + [DEVICE_MODE_ISDBT] = "isdbt_rio.inp", + [DEVICE_MODE_ISDBT_BDA] = "isdbt_rio.inp", + [DEVICE_MODE_FM_RADIO] = "fm_radio_rio.inp", + [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio_rio.inp", + }, + [SMS_DENVER_1530] = { + [DEVICE_MODE_ATSC] = "atsc_denver.inp", + }, + [SMS_DENVER_2160] = { + [DEVICE_MODE_DAB_TDMB] = "tdmb_denver.inp", + }, +}; +/** + * get firmware file name from one of the two mechanisms : sms_boards or + * smscore_fw_lkup. + * @param coredev pointer to a coredev object returned by + * smscore_register_device + * @param mode requested mode of operation + * @param lookup if 1, always get the fw filename from smscore_fw_lkup + * table. if 0, try first to get from sms_boards + * + * @return 0 on success, <0 on error. + */ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode); + int mode) +{ + char **fw; + int board_id = smscore_get_board_id(coredev); + enum sms_device_type_st type; + + type = smscore_registry_gettype(coredev->devpath); + + /* Prevent looking outside the smscore_fw_lkup table */ + if (type <= SMS_UNKNOWN_TYPE || type >= SMS_NUM_OF_DEVICE_TYPES) + return NULL; + if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) + return NULL; + + sms_debug("trying to get fw name from sms_boards board_id %d mode %d", + board_id, mode); + fw = sms_get_board(board_id)->fw; + if (!fw || !fw[mode]) { + sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", + mode, type); + return smscore_fw_lkup[type][mode]; + } + + return fw[mode]; +} /** * loads specified firmware into a buffer and calls device loadfirmware_handler @@ -1207,93 +1290,6 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) return rc; } -static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = { - [SMS_NOVA_A0] = { - [DEVICE_MODE_DVBT] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_DVBH] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz.inp", - }, - [SMS_NOVA_B0] = { - [DEVICE_MODE_DVBT] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_DVBH] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz_b0.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz_b0.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz_b0.inp", - [DEVICE_MODE_FM_RADIO] = "fm_radio.inp", - [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio.inp", - }, - [SMS_VEGA] = { - [DEVICE_MODE_CMMB] = "cmmb_vega_12mhz.inp", - }, - [SMS_VENICE] = { - [DEVICE_MODE_CMMB] = "cmmb_venice_12mhz.inp", - }, - [SMS_MING] = { - [DEVICE_MODE_CMMB] = "cmmb_ming_app.inp", - }, - [SMS_PELE] = { - [DEVICE_MODE_ISDBT] = "isdbt_pele.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_pele.inp", - }, - [SMS_RIO] = { - [DEVICE_MODE_DVBT] = "dvb_rio.inp", - [DEVICE_MODE_DVBH] = "dvbh_rio.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_rio.inp", - [DEVICE_MODE_ISDBT] = "isdbt_rio.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_rio.inp", - [DEVICE_MODE_FM_RADIO] = "fm_radio_rio.inp", - [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio_rio.inp", - }, - [SMS_DENVER_1530] = { - [DEVICE_MODE_ATSC] = "atsc_denver.inp", - }, - [SMS_DENVER_2160] = { - [DEVICE_MODE_DAB_TDMB] = "tdmb_denver.inp", - }, -}; - -/** - * get firmware file name from one of the two mechanisms : sms_boards or - * smscore_fw_lkup. - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param mode requested mode of operation - * @param lookup if 1, always get the fw filename from smscore_fw_lkup - * table. if 0, try first to get from sms_boards - * - * @return 0 on success, <0 on error. - */ -static char *smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode) -{ - char **fw; - int board_id = smscore_get_board_id(coredev); - enum sms_device_type_st type; - - type = smscore_registry_gettype(coredev->devpath); - - /* Prevent looking outside the smscore_fw_lkup table */ - if (type <= SMS_UNKNOWN_TYPE || type >= SMS_NUM_OF_DEVICE_TYPES) - return NULL; - if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) - return NULL; - - sms_debug("trying to get fw name from sms_boards board_id %d mode %d", - board_id, mode); - fw = sms_get_board(board_id)->fw; - if (!fw || !fw[mode]) { - sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", - mode, type); - return smscore_fw_lkup[type][mode]; - } - - return fw[mode]; -} - /** * send init device request and wait for response * -- cgit From 07bb6bdddfa09f01024e5caeb2bab8836b8de13e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 12:59:50 -0300 Subject: [media] siano: remove a bogus printk line The logic that detects the types of sms devices is bogus. It returns [ 4645.187790] smsusb_init_device: line: 372: Unspecified sms device type! For several devices, including the one I have (SMS_RIO). In a matter of fact, the right thing to do there is to print an error only if the device is really unknown (SMS_UNKNOWN_TYPE). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/siano/smsusb.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index def5e41405a4..01a0f39a7cec 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -368,14 +368,10 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) params.setmode_handler = smsusb1_setmode; params.detectmode_handler = smsusb1_detectmode; break; - default: + case SMS_UNKNOWN_TYPE: sms_err("Unspecified sms device type!"); /* fall-thru */ - case SMS_NOVA_A0: - case SMS_NOVA_B0: - case SMS_VEGA: - case SMS_VENICE: - case SMS_DENVER_1530: + default: dev->buffer_size = USB2_BUFFER_SIZE; dev->response_alignment = le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - -- cgit From 98c3f94e6db3b4df21336b41c646366ea417527c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 13:06:28 -0300 Subject: [media] siano: remove doubled new line sms_debug() and sms_info() already adds a '\n' at the printed strings. No need to add more. That helps to cleanup stuff like: [ 4868.205648] smscore_onresponse: message not handled. [ 4868.205898] smscore_onresponse: message not handled. and: [ 5467.959769] smscore_onresponse: data rate 143069 bytes/secs While here, provides the message name, when the message is not handled by the smsmdtv core. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 6 ++++-- drivers/media/common/siano/smsdvb-main.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index c04d8267adba..92eea545ed4e 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1495,7 +1495,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, last_sample_time = time_now; if (time_now - last_sample_time > 10000) { - sms_debug("\ndata rate %d bytes/secs", + sms_debug("data rate %d bytes/secs", (int)((data_total * 1000) / (time_now - last_sample_time))); @@ -1606,7 +1606,9 @@ void smscore_onresponse(struct smscore_device_t *coredev, break; default: - sms_debug("message not handled.\n"); + sms_debug("message %s(%d) not handled.", + smscore_translate_msg(phdr->msgType), + phdr->msgType); break; } smscore_putbuffer(coredev, cb); diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index c53cb4e8d0c6..a2882f5cfdd0 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -949,7 +949,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) c->bandwidth_hz = 6000000; - sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, + sms_info("%s: freq %d segwidth %d segindex %d", __func__, c->frequency, c->isdbt_sb_segment_count, c->isdbt_sb_segment_idx); -- cgit From d8a18e88c952f155b953d4b164818940ae8686a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 13:12:29 -0300 Subject: [media] siano: Remove bogus complain about MSG_SMS_DVBT_BDA_DATA When the driver is tuned into chanel, and it is removed/reinserted, the message stream data may be arriving during device probe: [ 5680.162004] smscore_set_device_mode: set device mode to 6 [ 5680.162267] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.162391] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.162641] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.162891] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.163016] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.163266] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.163516] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.163640] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.163891] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.164016] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.164265] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.164515] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.164519] smscore_onresponse: Firmware id 6 prots 0x40 ver 8.1 [ 5680.164766] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.166018] smscore_onresponse: message MSG_SMS_DVBT_BDA_DATA(693) not handled. [ 5680.166438] DVB: registering new adapter (Siano Rio Digital Receiver) Instead of complaining, just silently discard those messages, instead of complaining. A proper fix is to put the device on suspend/power down mode when the module is removed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 92eea545ed4e..b5e40aa9651a 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1605,6 +1605,15 @@ void smscore_onresponse(struct smscore_device_t *coredev, - sizeof(struct SmsMsgHdr_ST)); break; + case MSG_SMS_DVBT_BDA_DATA: + /* + * It can be received here, if the frontend is + * tuned into a valid channel and the proper firmware + * is loaded. That happens when the module got removed + * and re-inserted, without powering the device off + */ + break; + default: sms_debug("message %s(%d) not handled.", smscore_translate_msg(phdr->msgType), -- cgit From 11ad03a5630fbf109615ce17da1a031b9950f3f9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 17:02:54 -0300 Subject: [media] siano: use defines for firmware names There are too many firmwares there. As we need to add MODULE_FIMWARE() macros, the better is to define their names on just one place and use the macros for both cards/device type tables and MODULE_FIRMWARE(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/sms-cards.c | 14 ++++----- drivers/media/common/siano/smscoreapi.c | 56 ++++++++++++++++----------------- drivers/media/common/siano/smscoreapi.h | 24 ++++++++++++++ 3 files changed, 59 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index bb6e558b8120..6680134d2336 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c @@ -54,26 +54,26 @@ static struct sms_board sms_boards[] = { [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = { .name = "Hauppauge Catamount", .type = SMS_STELLAR, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_STELLAR, .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = { .name = "Hauppauge Okemo-A", .type = SMS_NOVA_A0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_A, .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = { .name = "Hauppauge Okemo-B", .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_B, .default_mode = DEVICE_MODE_DVBT_BDA, }, [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { .name = "Hauppauge WinTV MiniStick", .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .fw[DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_HCW_55XXX, + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX, .default_mode = DEVICE_MODE_DVBT_BDA, .rc_codes = RC_MAP_HAUPPAUGE, .board_cfg.leds_power = 26, @@ -87,7 +87,7 @@ static struct sms_board sms_boards[] = { [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = { .name = "Hauppauge WinTV MiniCard", .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX, .default_mode = DEVICE_MODE_DVBT_BDA, .lna_ctrl = 29, .board_cfg.foreign_lna0_ctrl = 29, @@ -97,7 +97,7 @@ static struct sms_board sms_boards[] = { [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { .name = "Hauppauge WinTV MiniCard", .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", + .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX, .default_mode = DEVICE_MODE_DVBT_BDA, .lna_ctrl = -1, }, diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index b5e40aa9651a..b7aa63f9d9f6 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -1048,50 +1048,50 @@ exit_fw_download: static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = { [SMS_NOVA_A0] = { - [DEVICE_MODE_DVBT] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_DVBH] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz.inp", - [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz.inp", + [DEVICE_MODE_DVBT] = SMS_FW_DVB_NOVA_12MHZ, + [DEVICE_MODE_DVBH] = SMS_FW_DVB_NOVA_12MHZ, + [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_NOVA_12MHZ, + [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ, + [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_NOVA_12MHZ, + [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_NOVA_12MHZ, }, [SMS_NOVA_B0] = { - [DEVICE_MODE_DVBT] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_DVBH] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_DAB_TDMB] = "tdmb_nova_12mhz_b0.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_nova_12mhz_b0.inp", - [DEVICE_MODE_ISDBT] = "isdbt_nova_12mhz_b0.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_nova_12mhz_b0.inp", - [DEVICE_MODE_FM_RADIO] = "fm_radio.inp", - [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio.inp", + [DEVICE_MODE_DVBT] = SMS_FW_DVB_NOVA_12MHZ_B0, + [DEVICE_MODE_DVBH] = SMS_FW_DVB_NOVA_12MHZ_B0, + [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_NOVA_12MHZ_B0, + [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0, + [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_NOVA_12MHZ_B0, + [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_NOVA_12MHZ_B0, + [DEVICE_MODE_FM_RADIO] = SMS_FW_FM_RADIO, + [DEVICE_MODE_FM_RADIO_BDA] = SMS_FW_FM_RADIO, }, [SMS_VEGA] = { - [DEVICE_MODE_CMMB] = "cmmb_vega_12mhz.inp", + [DEVICE_MODE_CMMB] = SMS_FW_CMMB_VEGA_12MHZ, }, [SMS_VENICE] = { - [DEVICE_MODE_CMMB] = "cmmb_venice_12mhz.inp", + [DEVICE_MODE_CMMB] = SMS_FW_CMMB_VENICE_12MHZ, }, [SMS_MING] = { - [DEVICE_MODE_CMMB] = "cmmb_ming_app.inp", + [DEVICE_MODE_CMMB] = SMS_FW_CMMB_MING_APP, }, [SMS_PELE] = { - [DEVICE_MODE_ISDBT] = "isdbt_pele.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_pele.inp", + [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_PELE, + [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_PELE, }, [SMS_RIO] = { - [DEVICE_MODE_DVBT] = "dvb_rio.inp", - [DEVICE_MODE_DVBH] = "dvbh_rio.inp", - [DEVICE_MODE_DVBT_BDA] = "dvb_rio.inp", - [DEVICE_MODE_ISDBT] = "isdbt_rio.inp", - [DEVICE_MODE_ISDBT_BDA] = "isdbt_rio.inp", - [DEVICE_MODE_FM_RADIO] = "fm_radio_rio.inp", - [DEVICE_MODE_FM_RADIO_BDA] = "fm_radio_rio.inp", + [DEVICE_MODE_DVBT] = SMS_FW_DVB_RIO, + [DEVICE_MODE_DVBH] = SMS_FW_DVBH_RIO, + [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_RIO, + [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_RIO, + [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_RIO, + [DEVICE_MODE_FM_RADIO] = SMS_FW_FM_RADIO_RIO, + [DEVICE_MODE_FM_RADIO_BDA] = SMS_FW_FM_RADIO_RIO, }, [SMS_DENVER_1530] = { - [DEVICE_MODE_ATSC] = "atsc_denver.inp", + [DEVICE_MODE_ATSC] = SMS_FW_ATSC_DENVER, }, [SMS_DENVER_2160] = { - [DEVICE_MODE_DAB_TDMB] = "tdmb_denver.inp", + [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_DENVER, }, }; diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 53b81cbc1bda..a9672e04c64f 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -44,6 +44,30 @@ along with this program. If not, see . #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif +/* Define the firmware names used by the driver */ +#define SMS_FW_ATSC_DENVER "atsc_denver.inp" +#define SMS_FW_CMMB_MING_APP "cmmb_ming_app.inp" +#define SMS_FW_CMMB_VEGA_12MHZ "cmmb_vega_12mhz.inp" +#define SMS_FW_CMMB_VENICE_12MHZ "cmmb_venice_12mhz.inp" +#define SMS_FW_DVBH_RIO "dvbh_rio.inp" +#define SMS_FW_DVB_NOVA_12MHZ_B0 "dvb_nova_12mhz_b0.inp" +#define SMS_FW_DVB_NOVA_12MHZ "dvb_nova_12mhz.inp" +#define SMS_FW_DVB_RIO "dvb_rio.inp" +#define SMS_FW_FM_RADIO "fm_radio.inp" +#define SMS_FW_FM_RADIO_RIO "fm_radio_rio.inp" +#define SMS_FW_DVBT_HCW_55XXX "sms1xxx-hcw-55xxx-dvbt-02.fw" +#define SMS_FW_ISDBT_HCW_55XXX "sms1xxx-hcw-55xxx-isdbt-02.fw" +#define SMS_FW_ISDBT_NOVA_12MHZ_B0 "isdbt_nova_12mhz_b0.inp" +#define SMS_FW_ISDBT_NOVA_12MHZ "isdbt_nova_12mhz.inp" +#define SMS_FW_ISDBT_PELE "isdbt_pele.inp" +#define SMS_FW_ISDBT_RIO "isdbt_rio.inp" +#define SMS_FW_DVBT_NOVA_A "sms1xxx-nova-a-dvbt-01.fw" +#define SMS_FW_DVBT_NOVA_B "sms1xxx-nova-b-dvbt-01.fw" +#define SMS_FW_DVBT_STELLAR "sms1xxx-stellar-dvbt-01.fw" +#define SMS_FW_TDMB_DENVER "tdmb_denver.inp" +#define SMS_FW_TDMB_NOVA_12MHZ_B0 "tdmb_nova_12mhz_b0.inp" +#define SMS_FW_TDMB_NOVA_12MHZ "tdmb_nova_12mhz.inp" + #define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) #define SMS_ALLOC_ALIGNMENT 128 #define SMS_DMA_ALIGNMENT 16 -- cgit From c8b8fdb39dabef67307df884212401c20877d9d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Mar 2013 17:46:53 -0300 Subject: [media] siano: add MODULE_FIRMWARE() macros This driver can use several firmwares. Provide such info at module firmware metadata. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.c | 24 ++++++++++++++++++++++++ drivers/media/common/siano/smscoreapi.h | 6 +++++- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index b7aa63f9d9f6..5006d1ce2806 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -2174,3 +2174,27 @@ module_exit(smscore_module_exit); MODULE_DESCRIPTION("Siano MDTV Core module"); MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); MODULE_LICENSE("GPL"); + +/* This should match what's defined at smscoreapi.h */ +MODULE_FIRMWARE(SMS_FW_ATSC_DENVER); +MODULE_FIRMWARE(SMS_FW_CMMB_MING_APP); +MODULE_FIRMWARE(SMS_FW_CMMB_VEGA_12MHZ); +MODULE_FIRMWARE(SMS_FW_CMMB_VENICE_12MHZ); +MODULE_FIRMWARE(SMS_FW_DVBH_RIO); +MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ_B0); +MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ); +MODULE_FIRMWARE(SMS_FW_DVB_RIO); +MODULE_FIRMWARE(SMS_FW_FM_RADIO); +MODULE_FIRMWARE(SMS_FW_FM_RADIO_RIO); +MODULE_FIRMWARE(SMS_FW_DVBT_HCW_55XXX); +MODULE_FIRMWARE(SMS_FW_ISDBT_HCW_55XXX); +MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ_B0); +MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ); +MODULE_FIRMWARE(SMS_FW_ISDBT_PELE); +MODULE_FIRMWARE(SMS_FW_ISDBT_RIO); +MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_A); +MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_B); +MODULE_FIRMWARE(SMS_FW_DVBT_STELLAR); +MODULE_FIRMWARE(SMS_FW_TDMB_DENVER); +MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ_B0); +MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ); diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index a9672e04c64f..bb742469d40a 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -44,7 +44,11 @@ along with this program. If not, see . #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif -/* Define the firmware names used by the driver */ +/* + * Define the firmware names used by the driver. + * Those should match what's used at smscoreapi.c and sms-cards.c + * including the MODULE_FIRMWARE() macros at the end of smscoreapi.c + */ #define SMS_FW_ATSC_DENVER "atsc_denver.inp" #define SMS_FW_CMMB_MING_APP "cmmb_ming_app.inp" #define SMS_FW_CMMB_VEGA_12MHZ "cmmb_vega_12mhz.inp" -- cgit From 44a50d088aad18a1a2709091bf25a108f967f8c9 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 17 Mar 2013 20:23:21 +0200 Subject: usb: phy: twl4030-usb: don't enable PHY during init There is no need to do it, otg.set_suspend(false) (which itself comes from runtime_pm OMAP glue calls) will enable it later anyway. This used to be the place where things were enabled if booted with cable connected before runtime_pm conversion, but now can be dropped. Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index 1986c782346f..4ad234cc6c9e 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -515,19 +515,17 @@ static int twl4030_usb_phy_init(struct usb_phy *phy) struct twl4030_usb *twl = phy_to_twl(phy); enum omap_musb_vbus_id_status status; - status = twl4030_usb_linkstat(twl); - if (status > 0) { - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) { - __twl4030_phy_power(twl, 0); - twl->asleep = 1; - } else { - __twl4030_phy_resume(twl); - twl->asleep = 0; - } + /* + * Start in sleep state, we'll get called through set_suspend() + * callback when musb is runtime resumed and it's time to start. + */ + __twl4030_phy_power(twl, 0); + twl->asleep = 1; + status = twl4030_usb_linkstat(twl); + if (status > 0) omap_musb_mailbox(twl->linkstat); - } + sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return 0; } -- cgit From ca4f70ce78de9a2fa09741f80cf7bda2f4256ecc Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 17 Mar 2013 20:23:22 +0200 Subject: usb: phy: twl4030-usb: ignore duplicate events In some rare cases we may get multiple interrupts that will generate duplicate omap_musb_mailbox() calls. This is a problem because each VBUS/ID event generates runtime_pm call in OMAP glue code, causing unbalanced gets or puts and breaking PM. The same goes for initial state, glue already defaults to "no cable" state, so only bother it if we have VBUS or ID. Signed-off-by: Grazvydas Ignotas Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index 4ad234cc6c9e..7ff67ce373dc 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -483,9 +483,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; enum omap_musb_vbus_id_status status; + enum omap_musb_vbus_id_status status_prev = twl->linkstat; status = twl4030_usb_linkstat(twl); - if (status > 0) { + if (status > 0 && status != status_prev) { /* FIXME add a set_power() method so that B-devices can * configure the charger appropriately. It's not always * correct to consume VBUS power, and how much current to @@ -523,7 +524,7 @@ static int twl4030_usb_phy_init(struct usb_phy *phy) twl->asleep = 1; status = twl4030_usb_linkstat(twl); - if (status > 0) + if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) omap_musb_mailbox(twl->linkstat); sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -- cgit From 15460de7f3d9cf0846af1cfdb4a3995d2f270ce7 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 17 Mar 2013 20:23:23 +0200 Subject: usb: phy: twl4030-usb: don't switch the phy on/off needlessly With runtime_pm in place there is no longer need to turn the phy on/off in OTG layer on cable connect/disconnect, OMAP glue does this through otg.set_suspend() callback after it's called through omap_musb_mailbox() on VBUS/ID interrupt. Not doing this will save power when cable is connected but no gadget driver is loaded. This will also have side effect of automatic USB charging no longer working without twl4030_charger driver, because a regulator needed for charging will no longer be enabled, so be sure to enable charger driver if charging is needed. Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index 7ff67ce373dc..f4ec53a58103 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -498,12 +498,6 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) * USB_LINK_VBUS state. musb_hdrc won't care until it * starts to handle softconnect right. */ - if (status == OMAP_MUSB_VBUS_OFF || - status == OMAP_MUSB_ID_FLOAT) - twl4030_phy_suspend(twl, 0); - else - twl4030_phy_resume(twl); - omap_musb_mailbox(twl->linkstat); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -- cgit From 249751f22380386042056cce6a73c934f5b942a3 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 17 Mar 2013 20:23:24 +0200 Subject: usb: phy: twl4030-usb: poll for ID disconnect On pandora, STS_USB interrupt doesn't arrive on USB host cable disconnect for some reason while VBUS is driven by twl itself, but STS_HW_CONDITIONS is updated correctly. It does work fine when PHY is powered down though. To work around that we have to poll. This patch also moves twl->linkstat update code to callers so that changes can be handled in thread safe way (as polling work can trigger at the same time as real irq now). TI PSP kernels have similar workarounds, so (many?) more boards are likely affected. Signed-off-by: Grazvydas Ignotas Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-twl4030-usb.c | 64 ++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index f4ec53a58103..61fe7e29c9c3 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -163,6 +163,8 @@ struct twl4030_usb { bool vbus_supplied; u8 asleep; bool irq_enabled; + + struct delayed_work id_workaround_work; }; /* internal define on top of container_of */ @@ -287,10 +289,6 @@ static enum omap_musb_vbus_id_status * are registered, and that both are active... */ - spin_lock_irq(&twl->lock); - twl->linkstat = linkstat; - spin_unlock_irq(&twl->lock); - return linkstat; } @@ -412,6 +410,16 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) __twl4030_phy_resume(twl); twl->asleep = 0; dev_dbg(twl->dev, "%s\n", __func__); + + /* + * XXX When VBUS gets driven after musb goes to A mode, + * ID_PRES related interrupts no longer arrive, why? + * Register itself is updated fine though, so we must poll. + */ + if (twl->linkstat == OMAP_MUSB_ID_GROUND) { + cancel_delayed_work(&twl->id_workaround_work); + schedule_delayed_work(&twl->id_workaround_work, HZ); + } } static int twl4030_usb_ldo_init(struct twl4030_usb *twl) @@ -483,10 +491,18 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; enum omap_musb_vbus_id_status status; - enum omap_musb_vbus_id_status status_prev = twl->linkstat; + bool status_changed = false; status = twl4030_usb_linkstat(twl); - if (status > 0 && status != status_prev) { + + spin_lock_irq(&twl->lock); + if (status >= 0 && status != twl->linkstat) { + twl->linkstat = status; + status_changed = true; + } + spin_unlock_irq(&twl->lock); + + if (status_changed) { /* FIXME add a set_power() method so that B-devices can * configure the charger appropriately. It's not always * correct to consume VBUS power, and how much current to @@ -498,13 +514,42 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) * USB_LINK_VBUS state. musb_hdrc won't care until it * starts to handle softconnect right. */ - omap_musb_mailbox(twl->linkstat); + omap_musb_mailbox(status); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; } +static void twl4030_id_workaround_work(struct work_struct *work) +{ + struct twl4030_usb *twl = container_of(work, struct twl4030_usb, + id_workaround_work.work); + enum omap_musb_vbus_id_status status; + bool status_changed = false; + + status = twl4030_usb_linkstat(twl); + + spin_lock_irq(&twl->lock); + if (status >= 0 && status != twl->linkstat) { + twl->linkstat = status; + status_changed = true; + } + spin_unlock_irq(&twl->lock); + + if (status_changed) { + dev_dbg(twl->dev, "handle missing status change to %d\n", + status); + omap_musb_mailbox(status); + } + + /* don't schedule during sleep - irq works right then */ + if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { + cancel_delayed_work(&twl->id_workaround_work); + schedule_delayed_work(&twl->id_workaround_work, HZ); + } +} + static int twl4030_usb_phy_init(struct usb_phy *phy) { struct twl4030_usb *twl = phy_to_twl(phy); @@ -518,6 +563,8 @@ static int twl4030_usb_phy_init(struct usb_phy *phy) twl->asleep = 1; status = twl4030_usb_linkstat(twl); + twl->linkstat = status; + if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) omap_musb_mailbox(twl->linkstat); @@ -608,6 +655,8 @@ static int twl4030_usb_probe(struct platform_device *pdev) /* init spinlock for workqueue */ spin_lock_init(&twl->lock); + INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); + err = twl4030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); @@ -646,6 +695,7 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; + cancel_delayed_work(&twl->id_workaround_work); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ -- cgit From 6cd2c7db41eab204b6474534df4ca68a7dc53d86 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 21 Mar 2013 14:20:12 +0200 Subject: videomode: videomode_from_timing work We currently have videomode_from_timing(), which takes one display_timing entry from display_timings. To make it easier to use display_timing without display_timings, this patch renames videomode_from_timing() to videomode_from_timings(), and adds a new videomode_from_timing() which just converts a given display_timing to videomode. Signed-off-by: Tomi Valkeinen Cc: Steffen Trumtrar --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +- drivers/video/of_videomode.c | 2 +- drivers/video/videomode.c | 25 ++++++++++++++++--------- include/video/videomode.h | 15 +++++++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 580b74e2022b..90ee49786372 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -173,7 +173,7 @@ static int panel_connector_get_modes(struct drm_connector *connector) struct drm_display_mode *mode = drm_mode_create(dev); struct videomode vm; - if (videomode_from_timing(timings, &vm, i)) + if (videomode_from_timings(timings, &vm, i)) break; drm_display_mode_from_videomode(&vm, mode); diff --git a/drivers/video/of_videomode.c b/drivers/video/of_videomode.c index 5b8066cd397f..111c2d1911d3 100644 --- a/drivers/video/of_videomode.c +++ b/drivers/video/of_videomode.c @@ -43,7 +43,7 @@ int of_get_videomode(struct device_node *np, struct videomode *vm, if (index == OF_USE_NATIVE_MODE) index = disp->native_mode; - ret = videomode_from_timing(disp, vm, index); + ret = videomode_from_timings(disp, vm, index); if (ret) return ret; diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c index a3d95f263cd5..df375c96c5d3 100644 --- a/drivers/video/videomode.c +++ b/drivers/video/videomode.c @@ -11,15 +11,9 @@ #include